1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "EntityGUI_PolylineDlg.h"
24 #include <CurveCreator_Curve.hxx>
25 #include <CurveCreator_Utils.hxx>
26 #include <CurveCreator_Widget.h>
28 #include <GeometryGUI.h>
31 #include <OCCViewer_ViewManager.h>
32 #include <LightApp_SelectionMgr.h>
33 #include <SalomeApp_Application.h>
34 #include <SUIT_ResourceMgr.h>
35 #include <SUIT_Session.h>
36 #include "utilities.h"
38 #include <BRep_Tool.hxx>
39 #include <Geom_Surface.hxx>
40 #include <GeomLib_IsPlanarSurface.hxx>
44 #include <QVBoxLayout>
48 //=================================================================================
49 // function : Constructor
51 //=================================================================================
52 EntityGUI_PolylineDlg::EntityGUI_PolylineDlg
53 (GeometryGUI* theGeometryGUI, QWidget* parent, bool modal, Qt::WindowFlags fl)
54 : GEOMBase_Skeleton( theGeometryGUI, parent, modal, fl ),
62 myPolylineSelButton (0),
64 myEditCurrentArgument (0)
66 QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_CC_POLYLINE")));
67 QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
69 setWindowTitle(tr("POLYLINE_DLG_TITLE"));
71 /***************************************************************/
72 mainFrame()->GroupConstructors->setTitle(tr("POLYLINE_TITLE"));
73 mainFrame()->RadioButton1->setIcon(image0);
74 mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose );
75 mainFrame()->RadioButton2->close();
76 mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
77 mainFrame()->RadioButton3->close();
79 QGroupBox *aGroupBox1 = new QGroupBox(tr("GEOM_CS"), this);
80 QGridLayout *aPlaneLayout = new QGridLayout(aGroupBox1);
82 aPlaneLayout->setSpacing(6);
83 aPlaneLayout->setMargin(11);
85 myPlnComboBox = new QComboBox(aGroupBox1);
86 aPlaneLayout->addWidget(myPlnComboBox, 0, 0, 1, 3);
88 myPlnButton = new QPushButton (aGroupBox1);
89 myPlnButton->setText( tr( "GEOM_SKETCHER_RESTORE" ) );
90 aPlaneLayout->addWidget(myPlnButton, 0, 3);
93 QLabel *aPlaneLbl = new QLabel(tr("GEOM_PLANE"), aGroupBox1);
95 myPlnSelButton = new QPushButton (aGroupBox1);
96 myPlnSelButton->setIcon(image1);
97 myWPlaneLineEdit = new QLineEdit (aGroupBox1);
98 myWPlaneLineEdit->setReadOnly(true);
101 QLabel *aPolylineLbl = new QLabel(tr("POLYLINE_IMPORT"), aGroupBox1);
103 myPolylineSelButton = new QPushButton (aGroupBox1);
104 myPolylineSelButton->setIcon(image1);
105 myPolylineEdit = new QLineEdit (aGroupBox1);
106 myPolylineEdit->setReadOnly(true);
109 aPlaneLayout->addWidget(aPlaneLbl, 1, 0);
110 aPlaneLayout->addWidget(myPlnSelButton, 1, 1);
111 aPlaneLayout->addWidget(myWPlaneLineEdit, 1, 2, 1, 2);
113 aPlaneLayout->addWidget(aPolylineLbl, 2, 0);
114 aPlaneLayout->addWidget(myPolylineSelButton, 2, 1);
115 aPlaneLayout->addWidget(myPolylineEdit, 2, 2, 1, 2);
117 aPlaneLayout->setColumnStretch(2, 1);
119 myCurve = new CurveCreator_Curve( CurveCreator::Dim2d );
120 myEditorWidget = new CurveCreator_Widget (centralWidget(), myCurve);
121 myAddElementBox = new QGroupBox (tr("POLYLINE_ADD_SECTION"), centralWidget());
123 QBoxLayout* anAddElementLayout = new QVBoxLayout( myAddElementBox );
125 anAddElementLayout->setMargin( 0 );
126 anAddElementLayout->setSpacing( 6 );
128 QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
130 layout->setMargin( 0 );
131 layout->setSpacing( 6 );
132 layout->addWidget( aGroupBox1 );
133 layout->addWidget( myEditorWidget );
134 layout->addWidget( myAddElementBox );
136 /***************************************************************/
138 setHelpFileName( "create_polyline_page.html" );
140 /* Initialisations */
144 //=================================================================================
145 // function : Destructor
147 //=================================================================================
148 EntityGUI_PolylineDlg::~EntityGUI_PolylineDlg()
153 //=================================================================================
156 //=================================================================================
157 void EntityGUI_PolylineDlg::Init()
159 initName(tr("POLYLINE_NAME"));
161 SalomeApp_Application *anApp = myGeomGUI->getApp();
162 OCCViewer_ViewManager *aViewManager = dynamic_cast<OCCViewer_ViewManager*>
163 (anApp->getViewManager(OCCViewer_Viewer::Type(), true));
164 LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr();
166 myEditorWidget->setOCCViewer(aViewManager ? aViewManager->getOCCViewer() : 0);
168 // Init the list of local coordinate system
169 gp_Pnt aPnt(0., 0., 0.);
170 gp_Dir aDirN(0., 0., 1.);
171 gp_Dir aDirX(1., 0., 0.);
172 gp_Ax3 aLCS(aPnt, aDirN, aDirX);
175 myPlnComboBox->addItem(tr("GEOM_GCS"), false);
176 myWPlaneList.push_back(GEOM::GeomObjPtr());
177 myLCSList.push_back(aLCS);
179 connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
180 connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
183 connect(myPlnSelButton, SIGNAL(clicked()),
184 this, SLOT(SetEditCurrentArgument()));
186 connect(myPolylineSelButton, SIGNAL(clicked()),
187 this, SLOT(SetEditCurrentArgument()));
188 connect(aSelMgr, SIGNAL(currentSelectionChanged()),
189 this, SLOT(SelectionIntoArgument()));
190 connect(myEditorWidget, SIGNAL(subOperationStarted(QWidget*, bool)),
191 this, SLOT(processStartedSubOperation(QWidget*, bool)));
192 connect(myEditorWidget, SIGNAL(subOperationFinished(QWidget*)),
193 this, SLOT(processFinishedSubOperation(QWidget*)));
194 connect(myEditorWidget, SIGNAL(curveModified()),
195 this, SLOT(onUpdatePreview()));
197 connect(myPlnComboBox, SIGNAL(activated(int)),
198 this, SLOT(ActivateLocalCS()));
199 connect(myPlnButton, SIGNAL(clicked()),
200 this, SLOT(ActivateLocalCS()));
202 connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
203 connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
205 myAddElementBox->hide();
206 myPolylineSelButton->click();
207 SelectionIntoArgument();
210 //=================================================================================
213 //=================================================================================
214 void EntityGUI_PolylineDlg::Clear()
218 myCurve = new CurveCreator_Curve( CurveCreator::Dim2d );
219 myEditorWidget->setCurve(myCurve);
222 //=================================================================================
223 // function : GetCurveParams
225 //=================================================================================
226 void EntityGUI_PolylineDlg::GetCurveParams(GEOM::ListOfListOfDouble &theCoords,
227 GEOM::string_array &theNames,
228 GEOM::short_array &theTypes,
229 GEOM::ListOfBool &theCloseds)
231 const int aNbSec = myCurve->getNbSections();
235 theCoords.length(aNbSec);
236 theNames.length(aNbSec);
237 theTypes.length(aNbSec);
238 theCloseds.length(aNbSec);
240 for (i = 0; i < aNbSec; ++i) {
242 CurveCreator::Coordinates aCoords = myCurve->getPoints(i);
243 const int aNbPoints = aCoords.size();
245 theCoords[i].length(aNbPoints);
247 for (j = 0; j < aNbPoints; ++j) {
248 theCoords[i][j] = aCoords[j];
252 const CurveCreator::SectionType aType = myCurve->getSectionType(i);
255 case CurveCreator::Spline:
256 theTypes[i] = GEOM::Interpolation;
258 case CurveCreator::Polyline:
260 theTypes[i] = GEOM::Polyline;
264 // Set section names and closed flags.
265 theNames[i] = CORBA::string_dup(myCurve->getSectionName(i).c_str());
266 theCloseds[i] = myCurve->isClosed(i);
270 //=================================================================================
271 // function : createOperation
273 //=================================================================================
274 GEOM::GEOM_IOperations_ptr EntityGUI_PolylineDlg::createOperation()
276 return getGeomEngine()->GetICurvesOperations( getStudyId() );
279 //=================================================================================
280 // function : isValid
282 //=================================================================================
283 bool EntityGUI_PolylineDlg::isValid( QString& msg )
288 //=================================================================================
289 // function : execute
291 //=================================================================================
292 bool EntityGUI_PolylineDlg::execute( ObjectList& objects )
294 GEOM::GEOM_ICurvesOperations_var anOper =
295 GEOM::GEOM_ICurvesOperations::_narrow(getOperation());
297 // Get the polyline creation parameters.
298 GEOM::ListOfListOfDouble aCoords;
299 GEOM::string_array aNames;
300 GEOM::short_array aTypes;
301 GEOM::ListOfBool aCloseds;
303 GetCurveParams(aCoords, aNames, aTypes, aCloseds);
305 // Get Working Plane.
306 int ind = myPlnComboBox->currentIndex();
309 bool isPlane = myPlnComboBox->itemData(ind).toBool();
310 GEOM::GEOM_Object_var anObj;
314 anObj = anOper->MakePolyline2DOnPlane
315 (aCoords, aNames, aTypes, aCloseds, myWPlaneList.at(ind).get());
317 gp_Ax3 anAxis = myLCSList.at(ind);
318 GEOM::ListOfDouble aPlane;
321 aPlane[0] = anAxis.Location().X();
322 aPlane[1] = anAxis.Location().Y();
323 aPlane[2] = anAxis.Location().Z();
324 aPlane[3] = anAxis.Direction().X();
325 aPlane[4] = anAxis.Direction().Y();
326 aPlane[5] = anAxis.Direction().Z();
327 aPlane[6] = anAxis.XDirection().X();
328 aPlane[7] = anAxis.XDirection().Y();
329 aPlane[8] = anAxis.XDirection().Z();
331 anObj = anOper->MakePolyline2D
332 (aCoords, aNames, aTypes, aCloseds, aPlane);
335 if (!anObj->_is_nil()) {
336 objects.push_back(anObj._retn());
343 //=================================================================================
344 // function : ClickOnOk()
346 //=================================================================================
347 void EntityGUI_PolylineDlg::ClickOnOk()
349 setIsApplyAndClose( true );
355 //=================================================================================
356 // function : ClickOnApply()
358 //=================================================================================
359 bool EntityGUI_PolylineDlg::ClickOnApply()
369 //=================================================================================
370 // function : ClickOnCancel()
372 //=================================================================================
373 void EntityGUI_PolylineDlg::ClickOnCancel()
375 myEditorWidget->SetViewer2DMode(false);
376 GEOMBase_Skeleton::ClickOnCancel();
379 //=================================================================================
380 // function : processStartedSubOperation
382 //=================================================================================
383 void EntityGUI_PolylineDlg::processStartedSubOperation( QWidget* theWidget, bool theIsEdit )
385 myEditorWidget->setEnabled( false );
387 myAddElementBox->setTitle( theIsEdit ? tr( "POLYLINE_EDIT_SECTION" ) : tr( "POLYLINE_ADD_SECTION" ) );
388 QBoxLayout* anAddElementLayout = dynamic_cast<QBoxLayout*>( myAddElementBox->layout() );
389 anAddElementLayout->addWidget( theWidget );
392 myAddElementBox->show();
396 //=================================================================================
397 // function : processFinishedSubOperation
399 //=================================================================================
400 void EntityGUI_PolylineDlg::processFinishedSubOperation( QWidget* theWidget )
402 myEditorWidget->setEnabled( true );
404 QBoxLayout* anAddElementLayout = dynamic_cast<QBoxLayout*>( myAddElementBox->layout() );
405 anAddElementLayout->removeWidget( theWidget );
408 myAddElementBox->hide();
411 //=================================================================================
412 // function : deleteSelected
413 // purpose : Redirect the delete action to editor widget
414 //=================================================================================
415 void EntityGUI_PolylineDlg::deleteSelected()
417 myEditorWidget->removeSelected();
420 //=================================================================================
421 // function : deleteEnabled
422 // purpose : Checks whether there are some to delete
423 //=================================================================================
424 bool EntityGUI_PolylineDlg::deleteEnabled()
426 return myEditorWidget->removeEnabled();
429 //=================================================================================
430 // function : SelectionIntoArgument
431 // purpose : Called when selection is changed
432 //=================================================================================
433 void EntityGUI_PolylineDlg::SelectionIntoArgument()
435 bool isModified = false;
436 GEOM::GeomObjPtr aSelectedObject = getSelected(TopAbs_SHAPE);
439 if (aSelectedObject && GEOMBase::GetShape(aSelectedObject.get(), aShape) &&
441 QString aName = GEOMBase::GetName(aSelectedObject.get());
443 if (myEditCurrentArgument == myPolylineEdit) {
445 CurveCreator_Curve *aNewCurve =
446 new CurveCreator_Curve(CurveCreator::Dim2d);
449 if (CurveCreator_Utils::constructCurve(aShape, aNewCurve, aLocalCS)) {
450 // Change the current curve be the new one.
451 myEditorWidget->setCurve(aNewCurve);
455 myPolylineEdit->setText(aName);
457 AddLocalCS(aSelectedObject.get(), false, aLocalCS);
458 myWPlaneLineEdit->clear();
459 myPlnSelButton->setDown(false);
461 myPolylineSelButton->setDown(true);
463 // Does nothing, just clears selection.
467 } else if (myEditCurrentArgument == myWPlaneLineEdit) {
468 // Import planar face.
469 if (aShape.ShapeType() == TopAbs_FACE) {
470 // Check if the face is planar
471 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aShape));
472 GeomLib_IsPlanarSurface aPlanarCheck(aSurf, Precision::Confusion());
474 if (aPlanarCheck.IsPlanar()) {
475 myWPlaneLineEdit->setText(aName);
476 myPolylineEdit->clear();
477 AddLocalCS(aSelectedObject.get(), true,
478 WPlaneToLCS(aSelectedObject.get()));
480 myPlnSelButton->setDown(true);
481 myPolylineSelButton->setDown(false);
486 myEditCurrentArgument->setText(tr("GEOM_SKETCHER_WPLANE"));
493 // Does nothing, just clears selection.
494 disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
495 myGeomGUI->getApp()->selectionMgr()->clearSelected();
496 connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
497 this, SLOT(SelectionIntoArgument()));
501 //=================================================================================
502 // function : SetEditCurrentArgument()
504 //=================================================================================
505 void EntityGUI_PolylineDlg::SetEditCurrentArgument()
507 if (sender() == myPlnSelButton) {
509 myEditCurrentArgument = myWPlaneLineEdit;
510 myEditCurrentArgument->setFocus();
511 myPlnSelButton->setDown(true);
512 myPolylineSelButton->setDown(false);
514 } else if (sender() == myPolylineSelButton) {
515 myEditCurrentArgument = myPolylineEdit;
516 myEditCurrentArgument->setFocus();
518 myPlnSelButton->setDown(false);
520 myPolylineSelButton->setDown(true);
524 //=================================================================================
525 // function : ActivateThisDialog
527 //=================================================================================
528 void EntityGUI_PolylineDlg::ActivateThisDialog()
530 GEOMBase_Skeleton::ActivateThisDialog();
532 connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
533 this, SLOT(SelectionIntoArgument()));
536 //=================================================================================
537 // function : enterEvent()
539 //=================================================================================
540 void EntityGUI_PolylineDlg::enterEvent (QEvent*)
542 if (!mainFrame()->GroupConstructors->isEnabled())
543 ActivateThisDialog();
546 //=================================================================================
547 // function : onUpdatePreview
549 //=================================================================================
550 void EntityGUI_PolylineDlg::onUpdatePreview()
552 displayPreview(true);
555 //=================================================================================
556 // function : ActivateLocalCS
557 // purpose : Activate & Fit Working plane
558 //=================================================================================
559 void EntityGUI_PolylineDlg::ActivateLocalCS()
561 const int ind = myPlnComboBox->currentIndex();
566 myWPlaneLineEdit->clear();
568 myPolylineEdit->clear();
569 } else if (ind > 0) { // Skip 0 as it is default
570 // Update text on line edits.
571 QString aName = GEOMBase::GetName(GetActiveWPlane().get());
572 bool isPlane = myPlnComboBox->itemData(ind).toBool();
576 myWPlaneLineEdit->setText(aName);
578 myPolylineEdit->clear();
580 myPolylineEdit->setText(aName);
582 myWPlaneLineEdit->clear();
587 gp_Ax3 anAxis = GetActiveLocalCS();
589 myGeomGUI->SetWorkingPlane(anAxis);
590 myGeomGUI->ActiveWorkingPlane();
593 //=================================================================================
594 // function : GetActiveLocalCS
595 // purpose : Get Working plane
596 //=================================================================================
597 gp_Ax3 EntityGUI_PolylineDlg::GetActiveLocalCS()
599 const int ind = myPlnComboBox->currentIndex();
601 return ind >= 0 ? myLCSList.at(ind) : myGeomGUI->GetWorkingPlane();
604 //=================================================================================
605 // function : GetActiveWPlane
606 // purpose : Get Working plane
607 //=================================================================================
608 GEOM::GeomObjPtr EntityGUI_PolylineDlg::GetActiveWPlane()
610 const int ind = myPlnComboBox->currentIndex();
612 return ind >= 0 ? myWPlaneList.at(ind) : GEOM::GeomObjPtr();
615 //=================================================================================
616 // function : AddLocalCS()
617 // purpose : Add All Coordinates systems in study
618 //=================================================================================
619 void EntityGUI_PolylineDlg::AddLocalCS(GEOM::GeomObjPtr theSelectedObject,
621 const gp_Ax3 &theLCS)
623 QString aName = GEOMBase::GetName(theSelectedObject.get());
625 int index = myPlnComboBox->findText(aName, Qt::MatchExactly);
627 if (index == -1) { // If the working plane hasn't been added yet
628 myWPlaneList.push_back(theSelectedObject);
629 myLCSList.push_back(theLCS);
630 myPlnComboBox->addItem(aName, QVariant(IsPlane));
631 index = myPlnComboBox->count();
632 myPlnComboBox->setCurrentIndex(index - 1);
634 myPlnComboBox->setCurrentIndex(index);
639 //=================================================================================
640 // function : WPlaneToLCS ( aWPlane )
642 //=================================================================================
643 gp_Ax3 EntityGUI_PolylineDlg::WPlaneToLCS(GEOM::GeomObjPtr theGeomObj)
645 TopoDS_Shape aShape =
646 GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), theGeomObj.get());
649 if (theGeomObj || aShape.IsNull()) {
650 MESSAGE("CORBA::is_nil(theGeomObj) || aShape.IsNull()")
653 aLCS.Transform(aShape.Location().Transformation());
655 if (aShape.ShapeType() == TopAbs_FACE) {
656 GEOM::GEOM_IMeasureOperations_ptr aMeasureOp =
657 myGeomGUI->GetGeomGen()->GetIMeasureOperations(getStudyId());
658 double Ox, Oy, Oz, Zx, Zy, Zz, Xx, Xy, Xz;
660 aMeasureOp->GetPosition(theGeomObj.get(), Ox, Oy, Oz, Zx, Zy, Zz, Xx, Xy, Xz);
662 if (aMeasureOp->IsDone()) {
663 gp_Pnt aPnt (Ox, Oy, Oz);
664 gp_Dir aDirN (Zx, Zy, Zz);
665 gp_Dir aDirX (Xx, Xy, Xz);
666 aLCS = gp_Ax3(aPnt, aDirN, aDirX);