/* * Copyright (C) 2008,2009,2010 Thorsten Liebig (Thorsten.Liebig@gmx.de) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "QCSGridEditor.h" #include "CSRectGrid.h" #include "QCSXCAD_Global.h" QCSGridEditor::QCSGridEditor(CSRectGrid* grid, QWidget* parent) : QWidget(parent) { clGrid=grid; QGridLayout* lay = new QGridLayout(); setLayout(lay); //lay->addWidget(new QLabel(tr("Direction")),0,0); lay->addWidget(new QLabel(tr("Min")),0,1); lay->addWidget(new QLabel(tr("Max")),0,2); lay->addWidget(new QLabel(tr("Lines")),0,3); for (int n=0;n<3;++n) { m_DirNames[n] = new QLabel(GetDirName(n)); lay->addWidget(m_DirNames[n],n+1,0); } QLabel* label=NULL; for (unsigned int i=0;i<6;++i) { label=new QLabel("0"); lay->addWidget(label,i/2+1,i%2+1); lay->setAlignment(label,Qt::AlignCenter); SimBox.append(label); } for (unsigned int i=0;i<3;++i) { label=new QLabel("0"); lay->addWidget(label,i+1,3); lay->setAlignment(label,Qt::AlignCenter); NodeQty.append(label); } QString EditText = tr("Edit"); if (QCSX_Settings.GetEdit()==false) EditText = tr("View"); QPushButton* PB = new QPushButton(QIcon(":/images/edit.png"),EditText); QObject::connect(PB,SIGNAL(clicked()),this,SLOT(EditX())); lay->addWidget(PB,1,4); PB = new QPushButton(QIcon(":/images/edit.png"),EditText); QObject::connect(PB,SIGNAL(clicked()),this,SLOT(EditY())); lay->addWidget(PB,2,4); PB = new QPushButton(QIcon(":/images/edit.png"),EditText); QObject::connect(PB,SIGNAL(clicked()),this,SLOT(EditZ())); lay->addWidget(PB,3,4); lay->addWidget(new QLabel(tr("Drawing unit [m]:")),4,0,1,2); UnitLength = new QLineEdit("1"); UnitLength->setEnabled(QCSX_Settings.GetEdit()); QObject::connect(UnitLength,SIGNAL(textEdited(QString)),this,SLOT(SetDeltaUnit(QString))); lay->addWidget(UnitLength,4,2,1,3); OpacitySlider = new QSlider(Qt::Horizontal); OpacitySlider->setRange(0,255); QObject::connect(OpacitySlider,SIGNAL(valueChanged(int)),this,SIGNAL(OpacityChange(int))); lay->addWidget(new QLabel(tr("Grid opacity")),5,0,1,3); lay->addWidget(OpacitySlider,5,2,1,3); lay->setRowStretch(6,1); lay->setColumnStretch(5,1); } QCSGridEditor::~QCSGridEditor() { } QToolBar* QCSGridEditor::BuildToolbar() { QToolBar *TB = new QToolBar(tr("Discretisation")); TB->setObjectName("Discretisation_ToolBar"); TB->addAction(tr("homo\nDisc"),this,SLOT(BuildHomogenDisc())); TB->addAction(tr("inhomo\nDisc"),this,SLOT(BuildInHomogenDisc())); TB->addAction(tr("increase \nDisc"),this,SLOT(IncreaseResolution())); TB->addAction(tr("detect \nedges"),this,SLOT(DetectEdges())); return TB; } QWidget* QCSGridEditor::BuildPlanePosWidget() { QWidget* PPWid = new QWidget(); QGridLayout* lay = new QGridLayout(); for (int n=0;n<3;++n) { m_NormNames[n] = new QLabel(GetNormName(n)+ tr(" plane:")); lay->addWidget( m_NormNames[n] ,n,0); m_PlanePos[n] = new QSlider(); m_PlanePos[n]->setOrientation(Qt::Horizontal); lay->addWidget(m_PlanePos[n],n,1); m_PlanePosValue[n] = new QLabel(); lay->addWidget(m_PlanePosValue[n],n,2); } QObject::connect(m_PlanePos[0],SIGNAL(valueChanged(int)),this,SIGNAL(GridPlaneXChanged(int))); QObject::connect(m_PlanePos[1],SIGNAL(valueChanged(int)),this,SIGNAL(GridPlaneYChanged(int))); QObject::connect(m_PlanePos[2],SIGNAL(valueChanged(int)),this,SIGNAL(GridPlaneZChanged(int))); QObject::connect(m_PlanePos[0],SIGNAL(valueChanged(int)),this,SLOT(SetGridPlaneX(int))); QObject::connect(m_PlanePos[1],SIGNAL(valueChanged(int)),this,SLOT(SetGridPlaneY(int))); QObject::connect(m_PlanePos[2],SIGNAL(valueChanged(int)),this,SLOT(SetGridPlaneZ(int))); PPWid->setLayout(lay); return PPWid; } void QCSGridEditor::SetGridPlaneX(int pos) { m_PlanePosValue[0]->setText(QString("%1 = %2").arg(GetDirName(0)).arg(clGrid->GetLine(0,pos))); } void QCSGridEditor::SetGridPlaneY(int pos) { m_PlanePosValue[1]->setText(QString("%1 = %2").arg(GetDirName(1)).arg(clGrid->GetLine(1,pos))); } void QCSGridEditor::SetGridPlaneZ(int pos) { m_PlanePosValue[2]->setText(QString("%1 = %2").arg(GetDirName(2)).arg(clGrid->GetLine(2,pos))); } void QCSGridEditor::BuildInHomogenDisc() { QDialog* HomogenDisc = new QDialog(); QGridLayout* lay = new QGridLayout(); lay->addWidget(new QLabel(tr("Create inhomogenous discretisation:")),0,0,1,3); QCheckBox* DelOldGrid = new QCheckBox(tr("Clear old mesh")); DelOldGrid->setChecked(true); lay->addWidget(DelOldGrid,0,5); lay->addWidget(new QLabel(tr("min")),1,1); lay->addWidget(new QLabel(tr("max")),1,2); lay->addWidget(new QLabel(tr("lines")),1,3); lay->addWidget(new QLabel(tr("grid distribution function:")),1,4,1,2); // lay->addWidget(new QLabel(tr("X")),2,0); // lay->addWidget(new QLabel(tr("Y")),3,0); // lay->addWidget(new QLabel(tr("Z")),4,0); QLineEdit* function[3]; function[0] = new QLineEdit(GetDirName(0)); function[1] = new QLineEdit(GetDirName(1)); function[2] = new QLineEdit(GetDirName(2)); lay->addWidget(new QLabel("X:"),2,0); lay->addWidget(new QLabel("f(x)="),2,4); lay->addWidget(function[0],2,5); lay->addWidget(new QLabel("Y:"),3,0); lay->addWidget(new QLabel("f(y)="),3,4); lay->addWidget(function[1],3,5); lay->addWidget(new QLabel("Z:"),4,0); lay->addWidget(new QLabel("f(z)="),4,4); lay->addWidget(function[2],4,5); QLineEdit* BoxLine[6]; QSpinBox* Nodes[3]; for (int i=0;i<3;++i) { BoxLine[2*i]= new QLineEdit(QString("0")); lay->addWidget(BoxLine[2*i],i+2,1); BoxLine[2*i+1]= new QLineEdit(QString("1")); lay->addWidget(BoxLine[2*i+1],i+2,2); Nodes[i] = new QSpinBox(); Nodes[i]->setRange(0,9999); Nodes[i]->setValue(0); lay->addWidget(Nodes[i],i+2,3); } QPushButton* PB = new QPushButton(tr("Ok")); QObject::connect(PB,SIGNAL(clicked()),HomogenDisc,SLOT(accept())); QPushButton* PBcancel = new QPushButton(tr("Cancel")); QObject::connect(PBcancel,SIGNAL(clicked()),HomogenDisc,SLOT(reject())); QHBoxLayout* hLay = new QHBoxLayout(); hLay->addStretch(1); hLay->addWidget(PB); hLay->addWidget(PBcancel); hLay->addStretch(1); lay->addLayout(hLay,5,0,1,6); HomogenDisc->setLayout(lay); if (HomogenDisc->exec()==QDialog::Accepted) { double dSimBox[6]; for (int i=0;i<6;++i) dSimBox[i]=BoxLine[i]->text().toDouble(); for (int i=0;i<3;++i) { // if ((Check[i]->checkState()==Qt::Checked))// && (dSimBox[2*i+1]>dSimBox[2*i])) // { // FunctionParser fParse; // fParse.AddConstant("pi", 3.1415926535897932); // fParse.Parse(function[i]->text().toStdString(),coordVars.at(i).toStdString()); // if (fParse.GetParseErrorType()!=FunctionParser::FP_NO_ERROR) // QMessageBox::warning(HomogenDisc,tr("Error reading grid function!"),QString(tr("fparser error message:\n%1").arg(fParse.ErrorMsg()))); // else // { // double dStep=0; // if (Nodes[i]->value()>1) dStep=(dSimBox[2*i+1]-dSimBox[2*i])/(Nodes[i]->value()-1); // if (DelOldGrid->isChecked()) clGrid->ClearLines(i); // double dValue=0; // double dPos=0; // bool error=false; // for (int n=0;nvalue();++n) // { // dPos=dSimBox[2*i]+n*dStep; // dValue=fParse.Eval(&dPos); // if (fParse.EvalError()!=0) error=true; // clGrid->AddDiscLine(i,dValue); // } // if (error) QMessageBox::warning(HomogenDisc,tr("Error evaluation grid function!"),QString(tr("An error occurred evaluation the grid function f(%1)!").arg(coordVars.at(i)))); // } // clGrid->Sort(i); // } if (Nodes[i]->value()>0)// && (dSimBox[2*i+1]>dSimBox[2*i])) { double dStep=0; if (Nodes[i]->value()>1) dStep=(dSimBox[2*i+1]-dSimBox[2*i])/(Nodes[i]->value()-1); if (DelOldGrid->isChecked()) clGrid->ClearLines(i); double* dValue=new double[Nodes[i]->value()]; for (int n=0;nvalue();++n) dValue[n]=dSimBox[2*i]+n*dStep; std::string error = clGrid->AddDiscLines(i,Nodes[i]->value(),dValue,function[i]->text().toStdString()); delete[] dValue; if (error.empty()==false) QMessageBox::warning(HomogenDisc,tr("Error evaluation grid function!"),QString(error.c_str())); } clGrid->Sort(i); } } delete HomogenDisc; Update(); } void QCSGridEditor::BuildHomogenDisc() { QDialog* HomogenDisc = new QDialog(); QGridLayout* lay = new QGridLayout(); lay->addWidget(new QLabel(tr("Create homogenous discretisation:")),0,0,1,3); QCheckBox* DelOldGrid = new QCheckBox(tr("Clear old mesh")); DelOldGrid->setChecked(true); lay->addWidget(DelOldGrid,0,3); lay->addWidget(new QLabel(tr("Min")),1,1); lay->addWidget(new QLabel(tr("Max")),1,2); lay->addWidget(new QLabel(tr("Lines")),1,3); // lay->addWidget(new QLabel(tr("X")),2,0); // lay->addWidget(new QLabel(tr("Y")),3,0); // lay->addWidget(new QLabel(tr("Z")),4,0); QCheckBox* Check[3]; Check[0] = new QCheckBox(GetDirName(0)); lay->addWidget(Check[0],2,0); Check[1] = new QCheckBox(GetDirName(1)); lay->addWidget(Check[1],3,0); Check[2] = new QCheckBox(GetDirName(2)); lay->addWidget(Check[2],4,0); QLineEdit* BoxLine[6]; QSpinBox* Nodes[3]; for (int i=0;i<3;++i) { BoxLine[2*i]= new QLineEdit(QString("%1").arg(clGrid->GetLine(i,0))); lay->addWidget(BoxLine[2*i],i+2,1); BoxLine[2*i+1]= new QLineEdit(QString("%1").arg(clGrid->GetLine(i,clGrid->GetQtyLines(i)-1))); lay->addWidget(BoxLine[2*i+1],i+2,2); Nodes[i] = new QSpinBox(); Nodes[i]->setRange(1,9999); Nodes[i]->setValue(clGrid->GetQtyLines(i)); lay->addWidget(Nodes[i],i+2,3); Check[i]->setChecked(true); } QPushButton* PB = new QPushButton(tr("Ok")); QObject::connect(PB,SIGNAL(clicked()),HomogenDisc,SLOT(accept())); QPushButton* PBcancel = new QPushButton(tr("Cancel")); QObject::connect(PBcancel,SIGNAL(clicked()),HomogenDisc,SLOT(reject())); QHBoxLayout* hLay = new QHBoxLayout(); hLay->addStretch(1); hLay->addWidget(PB); hLay->addWidget(PBcancel); hLay->addStretch(1); lay->addLayout(hLay,5,0,1,4); HomogenDisc->setLayout(lay); if (HomogenDisc->exec()==QDialog::Accepted) { double dSimBox[6]; for (int i=0;i<6;++i) dSimBox[i]=BoxLine[i]->text().toDouble(); for (int i=0;i<3;++i) { if ((Check[i]->checkState()==Qt::Checked))// && (dSimBox[2*i+1]>dSimBox[2*i])) { double dStep=0; if (Nodes[i]->value()>1) dStep=(dSimBox[2*i+1]-dSimBox[2*i])/(Nodes[i]->value()-1); if (DelOldGrid->isChecked()) clGrid->ClearLines(i); for (int n=0;nvalue();++n) clGrid->AddDiscLine(i,dSimBox[2*i]+n*dStep); clGrid->Sort(i); } // else if (Check[i]->checkState()==Qt::Checked) // { // clGrid->ClearLines(i); // if (Nodes[i]->value()>0) clGrid->AddDiscLine(i,dSimBox[2*i]); // } } } delete HomogenDisc; Update(); } void QCSGridEditor::IncreaseResolution() { QDialog* DiscInc = new QDialog(); QGridLayout* lay = new QGridLayout(); lay->addWidget(new QLabel(tr("Increase Resolution of Discretisation:")),0,0,1,2); QCheckBox* Check[3]; QSpinBox* Spin[3]; Check[0] = new QCheckBox(tr("X - Factor: ")); Check[0]->setChecked(true); Spin[0]=new QSpinBox();Spin[0]->setRange(2,9); lay->addWidget(Check[0],2,0); lay->addWidget(Spin[0],2,1); Check[1] = new QCheckBox(tr("Y - Factor: ")); Check[1]->setChecked(true); Spin[1]=new QSpinBox();Spin[1]->setRange(2,9); lay->addWidget(Check[1],3,0); lay->addWidget(Spin[1],3,1); Check[2] = new QCheckBox(tr("Z - Factor: ")); Check[2]->setChecked(true); Spin[2]=new QSpinBox();Spin[2]->setRange(2,9); lay->addWidget(Check[2],4,0); lay->addWidget(Spin[2],4,1); QPushButton* PB = new QPushButton(tr("Ok")); QObject::connect(PB,SIGNAL(clicked()),DiscInc,SLOT(accept())); QPushButton* PBcancel = new QPushButton(tr("Cancel")); QObject::connect(PBcancel,SIGNAL(clicked()),DiscInc,SLOT(reject())); QHBoxLayout* hLay = new QHBoxLayout(); hLay->addStretch(1); hLay->addWidget(PB); hLay->addWidget(PBcancel); hLay->addStretch(1); lay->addLayout(hLay,5,0,1,2); DiscInc->setLayout(lay); if (DiscInc->exec()==QDialog::Accepted) { for (int i=0;i<3;++i) if (Check[i]->checkState()==Qt::Checked) { clGrid->IncreaseResolution(i,Spin[i]->value()); } } Update(); } void QCSGridEditor::EditX() { Edit(0); } void QCSGridEditor::EditY() { Edit(1); } void QCSGridEditor::EditZ() { Edit(2); } double* QCSGridEditor::GetDoubleArrayFromString(int *count, QString qsValue) { double* values=NULL; *count = 0; QStringList seq = qsValue.split(":"); if (seq.size()==3) { double start,step,stop; bool ok; start = seq.at(0).toDouble(&ok); if (ok) step = seq.at(1).toDouble(&ok); if (ok) stop = seq.at(2).toDouble(&ok); if (ok) { int NrSteps = (int)((stop-start)/step); if ((NrSteps>=0) && (NrSteps<1000)) { values = new double[NrSteps+1]; *count = NrSteps+1; for (int n=0;n<=NrSteps;++n) values[n]=start+n*step; } } } return values; } void QCSGridEditor::Edit(int direct) { QTextEdit *Line = new QTextEdit(clGrid->GetLinesAsString(direct).c_str()); Line->setReadOnly(QCSX_Settings.GetEdit()==false); QDialog* EditDisc = new QDialog(this); if (QCSX_Settings.GetEdit()) EditDisc->setWindowTitle(tr("Edit Discratisation")); else EditDisc->setWindowTitle(tr("View Discratisation")); QGridLayout* lay = new QGridLayout(); lay->addWidget(Line,0,0,1,4); if (QCSX_Settings.GetEdit()) lay->addWidget(new QLabel(tr("Allowed syntax example: 0,10, 20, 30:1.5e1:100, 50 , sqrt(1000:-10:200)")),1,0,1,4); QPushButton* PB = new QPushButton(tr("Ok")); QObject::connect(PB,SIGNAL(clicked()),EditDisc,SLOT(accept())); lay->addWidget(PB,2,1); if (QCSX_Settings.GetEdit()) { PB = new QPushButton(tr("Cancel")); QObject::connect(PB,SIGNAL(clicked()),EditDisc,SLOT(reject())); lay->addWidget(PB,2,2); } lay->setRowStretch(0,1); lay->setColumnStretch(0,1); lay->setColumnStretch(3,1); EditDisc->setLayout(lay); if (EditDisc->exec()==QDialog::Accepted && QCSX_Settings.GetEdit()) { clGrid->ClearLines(direct); QStringList gridValues = Line->toPlainText().split(","); for (int n=0;nAddDiscLine(direct,val); else { QString FloatExp("-?\\d+(.\\d+)?(e-?\\d+)?"); QRegExp qre(FloatExp + ":" + FloatExp + ":" + FloatExp); if (qre.exactMatch(qsValue)) { int count=0; double* values = GetDoubleArrayFromString(&count,qsValue); if (values) clGrid->AddDiscLines(direct,count,values); } else if (qsValue.contains(QRegExp(FloatExp + ":" + FloatExp + ":" + FloatExp))) { qre.indexIn(qsValue); QString seq = qre.cap(); // cerr << "found-->" << seq.toStdString() << endl; QString function = qsValue.replace(QRegExp(FloatExp + ":" + FloatExp + ":" + FloatExp),GetDirName(direct)); // cerr << function.toStdString() << endl; int count=0; double* values = GetDoubleArrayFromString(&count,seq); if (values) clGrid->AddDiscLines(direct,count,values,function.toStdString()); } } } } Update(); } void QCSGridEditor::DetectEdges() { QDialog* Edges = new QDialog(); QGridLayout* lay = new QGridLayout(); lay->addWidget(new QLabel(tr("Detect Edges for Discretisation:")),0,0,1,1); QCheckBox* Check[3]; Check[0] = new QCheckBox(tr("X - Active ")); Check[0]->setChecked(true); lay->addWidget(Check[0],2,0); Check[1] = new QCheckBox(tr("Y - Active ")); Check[1]->setChecked(true); lay->addWidget(Check[1],3,0); Check[2] = new QCheckBox(tr("Z - Active ")); Check[2]->setChecked(true); lay->addWidget(Check[2],4,0); QPushButton* PB = new QPushButton(tr("Ok")); QObject::connect(PB,SIGNAL(clicked()),Edges,SLOT(accept())); QPushButton* PBcancel = new QPushButton(tr("Cancel")); QObject::connect(PBcancel,SIGNAL(clicked()),Edges,SLOT(reject())); QHBoxLayout* hLay = new QHBoxLayout(); hLay->addStretch(1); hLay->addWidget(PB); hLay->addWidget(PBcancel); hLay->addStretch(1); lay->addLayout(hLay,5,0,1,1); Edges->setLayout(lay); if (Edges->exec()==QDialog::Accepted) { for (int i=0;i<3;++i) if (Check[i]->checkState()==Qt::Checked) { emit signalDetectEdges(i); } } Update(); } void QCSGridEditor::SetDeltaUnit(QString val) { bool succ=false; double dDal=val.toDouble(&succ); if ((val>0) && succ) clGrid->SetDeltaUnit(dDal); } void QCSGridEditor::Update() { clGrid->Sort(0); clGrid->Sort(1); clGrid->Sort(2); for (size_t i=0;i<3;++i) { SimBox.at(2*i)->setText(QString("%1").arg(clGrid->GetLine(i,0))); SimBox.at(2*i+1)->setText(QString("%1").arg(clGrid->GetLine(i,clGrid->GetQtyLines(i)-1))); NodeQty.at(i)->setText(QString("%1").arg(clGrid->GetQtyLines(i))); m_DirNames[i]->setText(GetDirName(i)); m_PlanePos[i]->setRange(0,clGrid->GetQtyLines(i)-1); m_NormNames[i]->setText(GetNormName(i)+ tr(" plane: ")); } SetGridPlaneX(m_PlanePos[0]->value()); SetGridPlaneY(m_PlanePos[0]->value()); SetGridPlaneZ(m_PlanePos[0]->value()); UnitLength->setText(QString("%1").arg(clGrid->GetDeltaUnit())); emit GridChanged(); } void QCSGridEditor::SetOpacity(int val) { OpacitySlider->setValue(val); } int QCSGridEditor::GetOpacity() { return OpacitySlider->value(); } QString QCSGridEditor::GetDirName(int ny) { if (clGrid->GetMeshType()==0) { switch (ny) { case 0: return "x"; case 1: return "y"; case 2: return "z"; } } if (clGrid->GetMeshType()==1) { switch (ny) { case 0: return "r"; case 1: return QChar(0xb1, 0x03); case 2: return "z"; } } return ""; } QString QCSGridEditor::GetNormName(int ny) { if (clGrid->GetMeshType()==0) { switch (ny) { case 0: return "yz"; case 1: return "zx"; case 2: return "xy"; } } if (clGrid->GetMeshType()==1) { switch (ny) { case 0: return QString(QChar(0xb1, 0x03)) + "z"; case 1: return "zr"; case 2: return "r" + QString(QChar(0xb1, 0x03)); } } return ""; }