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 "utilities.h"
33 #include <OCCViewer_ViewManager.h>
34 #include <LightApp_SelectionMgr.h>
35 #include <SalomeApp_Application.h>
36 #include <SUIT_ResourceMgr.h>
37 #include <SUIT_Session.h>
39 #include <BRep_Tool.hxx>
40 #include <Geom_Surface.hxx>
41 #include <GeomLib_IsPlanarSurface.hxx>
45 #include <QVBoxLayout>
49 //=================================================================================
50 // function : Constructor
52 //=================================================================================
53 EntityGUI_PolylineDlg::EntityGUI_PolylineDlg
54 (GeometryGUI* theGeometryGUI, QWidget* parent, bool modal, Qt::WindowFlags fl)
55 : GEOMBase_Skeleton( theGeometryGUI, parent, modal, fl ),
63 myPolylineSelButton (0),
65 myEditCurrentArgument (0)
67 QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_CC_POLYLINE")));
68 QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
70 setWindowTitle(tr("POLYLINE_DLG_TITLE"));
72 /***************************************************************/
73 mainFrame()->GroupConstructors->setTitle(tr("POLYLINE_TITLE"));
74 mainFrame()->RadioButton1->setIcon(image0);
75 mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose );
76 mainFrame()->RadioButton2->close();
77 mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
78 mainFrame()->RadioButton3->close();
80 QGroupBox *aGroupBox1 = new QGroupBox(tr("GEOM_CS"), this);
81 QGridLayout *aPlaneLayout = new QGridLayout(aGroupBox1);
83 aPlaneLayout->setSpacing(6);
84 aPlaneLayout->setMargin(11);
86 myPlnComboBox = new QComboBox(aGroupBox1);
87 aPlaneLayout->addWidget(myPlnComboBox, 0, 0, 1, 3);
89 myPlnButton = new QPushButton (aGroupBox1);
90 myPlnButton->setText( tr( "GEOM_SKETCHER_RESTORE" ) );
91 aPlaneLayout->addWidget(myPlnButton, 0, 3);
94 QLabel *aPlaneLbl = new QLabel(tr("GEOM_PLANE"), aGroupBox1);
96 myPlnSelButton = new QPushButton (aGroupBox1);
97 myPlnSelButton->setIcon(image1);
98 myWPlaneLineEdit = new QLineEdit (aGroupBox1);
99 myWPlaneLineEdit->setReadOnly(true);
102 QLabel *aPolylineLbl = new QLabel(tr("POLYLINE_IMPORT"), aGroupBox1);
104 myPolylineSelButton = new QPushButton (aGroupBox1);
105 myPolylineSelButton->setIcon(image1);
106 myPolylineEdit = new QLineEdit (aGroupBox1);
107 myPolylineEdit->setReadOnly(true);
110 aPlaneLayout->addWidget(aPlaneLbl, 1, 0);
111 aPlaneLayout->addWidget(myPlnSelButton, 1, 1);
112 aPlaneLayout->addWidget(myWPlaneLineEdit, 1, 2, 1, 2);
114 aPlaneLayout->addWidget(aPolylineLbl, 2, 0);
115 aPlaneLayout->addWidget(myPolylineSelButton, 2, 1);
116 aPlaneLayout->addWidget(myPolylineEdit, 2, 2, 1, 2);
118 aPlaneLayout->setColumnStretch(2, 1);
120 myCurve = new CurveCreator_Curve( CurveCreator::Dim2d );
121 myEditorWidget = new CurveCreator_Widget (centralWidget(), myCurve);
122 myAddElementBox = new QGroupBox (tr("POLYLINE_ADD_SECTION"), centralWidget());
124 QBoxLayout* anAddElementLayout = new QVBoxLayout( myAddElementBox );
126 anAddElementLayout->setMargin( 0 );
127 anAddElementLayout->setSpacing( 6 );
129 QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
131 layout->setMargin( 0 );
132 layout->setSpacing( 6 );
133 layout->addWidget( aGroupBox1 );
134 layout->addWidget( myEditorWidget );
135 layout->addWidget( myAddElementBox );
137 /***************************************************************/
139 setHelpFileName( "create_polyline_page.html" );
141 /* Initialisations */
145 //=================================================================================
146 // function : Destructor
148 //=================================================================================
149 EntityGUI_PolylineDlg::~EntityGUI_PolylineDlg()
154 //=================================================================================
157 //=================================================================================
158 void EntityGUI_PolylineDlg::Init()
160 initName(tr("POLYLINE_NAME"));
162 SalomeApp_Application *anApp = myGeomGUI->getApp();
163 OCCViewer_ViewManager *aViewManager = dynamic_cast<OCCViewer_ViewManager*>
164 (anApp->getViewManager(OCCViewer_Viewer::Type(), true));
165 LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr();
167 myEditorWidget->setOCCViewer(aViewManager ? aViewManager->getOCCViewer() : 0);
169 // Init the list of local coordinate system
170 gp_Pnt aPnt(0., 0., 0.);
171 gp_Dir aDirN(0., 0., 1.);
172 gp_Dir aDirX(1., 0., 0.);
173 gp_Ax3 aLCS(aPnt, aDirN, aDirX);
176 myPlnComboBox->addItem(tr("GEOM_GCS"), false);
177 myWPlaneList.push_back(GEOM::GeomObjPtr());
178 myLCSList.push_back(aLCS);
180 connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
181 connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
184 connect(myPlnSelButton, SIGNAL(clicked()),
185 this, SLOT(SetEditCurrentArgument()));
187 connect(myPolylineSelButton, SIGNAL(clicked()),
188 this, SLOT(SetEditCurrentArgument()));
189 connect(aSelMgr, SIGNAL(currentSelectionChanged()),
190 this, SLOT(SelectionIntoArgument()));
191 connect(myEditorWidget, SIGNAL(subOperationStarted(QWidget*, bool)),
192 this, SLOT(processStartedSubOperation(QWidget*, bool)));
193 connect(myEditorWidget, SIGNAL(subOperationFinished(QWidget*)),
194 this, SLOT(processFinishedSubOperation(QWidget*)));
195 connect(myEditorWidget, SIGNAL(curveModified()),
196 this, SLOT(onUpdatePreview()));
198 connect(myPlnComboBox, SIGNAL(activated(int)),
199 this, SLOT(ActivateLocalCS()));
200 connect(myPlnButton, SIGNAL(clicked()),
201 this, SLOT(ActivateLocalCS()));
203 connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
204 connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
206 myAddElementBox->hide();
207 myPolylineSelButton->click();
208 SelectionIntoArgument();
211 //=================================================================================
214 //=================================================================================
215 void EntityGUI_PolylineDlg::Clear()
219 myCurve = new CurveCreator_Curve( CurveCreator::Dim2d );
220 myEditorWidget->setCurve(myCurve);
223 //=================================================================================
224 // function : GetCurveParams
226 //=================================================================================
227 void EntityGUI_PolylineDlg::GetCurveParams(GEOM::ListOfListOfDouble &theCoords,
228 GEOM::string_array &theNames,
229 GEOM::short_array &theTypes,
230 GEOM::ListOfBool &theCloseds)
232 const int aNbSec = myCurve->getNbSections();
236 theCoords.length(aNbSec);
237 theNames.length(aNbSec);
238 theTypes.length(aNbSec);
239 theCloseds.length(aNbSec);
241 for (i = 0; i < aNbSec; ++i) {
243 CurveCreator::Coordinates aCoords = myCurve->getPoints(i);
244 const int aNbPoints = aCoords.size();
246 theCoords[i].length(aNbPoints);
248 for (j = 0; j < aNbPoints; ++j) {
249 theCoords[i][j] = aCoords[j];
253 const CurveCreator::SectionType aType = myCurve->getSectionType(i);
256 case CurveCreator::Spline:
257 theTypes[i] = GEOM::Interpolation;
259 case CurveCreator::Polyline:
261 theTypes[i] = GEOM::Polyline;
265 // Set section names and closed flags.
266 theNames[i] = CORBA::string_dup(myCurve->getSectionName(i).c_str());
267 theCloseds[i] = myCurve->isClosed(i);
271 //=================================================================================
272 // function : createOperation
274 //=================================================================================
275 GEOM::GEOM_IOperations_ptr EntityGUI_PolylineDlg::createOperation()
277 return getGeomEngine()->GetICurvesOperations( getStudyId() );
280 //=================================================================================
281 // function : isValid
283 //=================================================================================
284 bool EntityGUI_PolylineDlg::isValid( QString& msg )
289 //=================================================================================
290 // function : execute
292 //=================================================================================
293 bool EntityGUI_PolylineDlg::execute( ObjectList& objects )
295 GEOM::GEOM_ICurvesOperations_var anOper =
296 GEOM::GEOM_ICurvesOperations::_narrow(getOperation());
298 // Get the polyline creation parameters.
299 GEOM::ListOfListOfDouble aCoords;
300 GEOM::string_array aNames;
301 GEOM::short_array aTypes;
302 GEOM::ListOfBool aCloseds;
304 GetCurveParams(aCoords, aNames, aTypes, aCloseds);
306 // Get Working Plane.
307 int ind = myPlnComboBox->currentIndex();
310 bool isPlane = myPlnComboBox->itemData(ind).toBool();
311 GEOM::GEOM_Object_var anObj;
315 anObj = anOper->MakePolyline2DOnPlane
316 (aCoords, aNames, aTypes, aCloseds, myWPlaneList.at(ind).get());
318 gp_Ax3 anAxis = myLCSList.at(ind);
319 GEOM::ListOfDouble aPlane;
322 aPlane[0] = anAxis.Location().X();
323 aPlane[1] = anAxis.Location().Y();
324 aPlane[2] = anAxis.Location().Z();
325 aPlane[3] = anAxis.Direction().X();
326 aPlane[4] = anAxis.Direction().Y();
327 aPlane[5] = anAxis.Direction().Z();
328 aPlane[6] = anAxis.XDirection().X();
329 aPlane[7] = anAxis.XDirection().Y();
330 aPlane[8] = anAxis.XDirection().Z();
332 anObj = anOper->MakePolyline2D
333 (aCoords, aNames, aTypes, aCloseds, aPlane);
336 if (!anObj->_is_nil()) {
337 objects.push_back(anObj._retn());
344 //=================================================================================
345 // function : ClickOnOk()
347 //=================================================================================
348 void EntityGUI_PolylineDlg::ClickOnOk()
350 setIsApplyAndClose( true );
356 //=================================================================================
357 // function : ClickOnApply()
359 //=================================================================================
360 bool EntityGUI_PolylineDlg::ClickOnApply()
370 //=================================================================================
371 // function : ClickOnCancel()
373 //=================================================================================
374 void EntityGUI_PolylineDlg::ClickOnCancel()
376 myEditorWidget->SetViewer2DMode(false);
377 GEOMBase_Skeleton::ClickOnCancel();
380 //=================================================================================
381 // function : processStartedSubOperation
383 //=================================================================================
384 void EntityGUI_PolylineDlg::processStartedSubOperation( QWidget* theWidget, bool theIsEdit )
386 myEditorWidget->setEnabled( false );
388 myAddElementBox->setTitle( theIsEdit ? tr( "POLYLINE_EDIT_SECTION" ) : tr( "POLYLINE_ADD_SECTION" ) );
389 QBoxLayout* anAddElementLayout = dynamic_cast<QBoxLayout*>( myAddElementBox->layout() );
390 anAddElementLayout->addWidget( theWidget );
393 myAddElementBox->show();
397 //=================================================================================
398 // function : processFinishedSubOperation
400 //=================================================================================
401 void EntityGUI_PolylineDlg::processFinishedSubOperation( QWidget* theWidget )
403 myEditorWidget->setEnabled( true );
405 QBoxLayout* anAddElementLayout = dynamic_cast<QBoxLayout*>( myAddElementBox->layout() );
406 anAddElementLayout->removeWidget( theWidget );
409 myAddElementBox->hide();
412 //=================================================================================
413 // function : deleteSelected
414 // purpose : Redirect the delete action to editor widget
415 //=================================================================================
416 void EntityGUI_PolylineDlg::deleteSelected()
418 myEditorWidget->removeSelected();
421 //=================================================================================
422 // function : deleteEnabled
423 // purpose : Checks whether there are some to delete
424 //=================================================================================
425 bool EntityGUI_PolylineDlg::deleteEnabled()
427 return myEditorWidget->removeEnabled();
430 //=================================================================================
431 // function : SelectionIntoArgument
432 // purpose : Called when selection is changed
433 //=================================================================================
434 void EntityGUI_PolylineDlg::SelectionIntoArgument()
436 bool isModified = false;
437 GEOM::GeomObjPtr aSelectedObject = getSelected(TopAbs_SHAPE);
440 if (aSelectedObject && GEOMBase::GetShape(aSelectedObject.get(), aShape) &&
442 QString aName = GEOMBase::GetName(aSelectedObject.get());
444 if (myEditCurrentArgument == myPolylineEdit) {
446 CurveCreator_Curve *aNewCurve =
447 new CurveCreator_Curve(CurveCreator::Dim2d);
450 if (CurveCreator_Utils::constructCurve(aShape, aNewCurve, aLocalCS)) {
451 // Change the current curve be the new one.
452 myEditorWidget->setCurve(aNewCurve);
456 myPolylineEdit->setText(aName);
458 AddLocalCS(aSelectedObject.get(), false, aLocalCS);
459 myWPlaneLineEdit->clear();
460 myPlnSelButton->setDown(false);
462 myPolylineSelButton->setDown(true);
464 // Does nothing, just clears selection.
468 } else if (myEditCurrentArgument == myWPlaneLineEdit) {
469 // Import planar face.
470 if (aShape.ShapeType() == TopAbs_FACE) {
471 // Check if the face is planar
472 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aShape));
473 GeomLib_IsPlanarSurface aPlanarCheck(aSurf, Precision::Confusion());
475 if (aPlanarCheck.IsPlanar()) {
476 myWPlaneLineEdit->setText(aName);
477 myPolylineEdit->clear();
478 AddLocalCS(aSelectedObject.get(), true,
479 WPlaneToLCS(aSelectedObject.get()));
481 myPlnSelButton->setDown(true);
482 myPolylineSelButton->setDown(false);
487 myEditCurrentArgument->setText(tr("GEOM_SKETCHER_WPLANE"));
494 // Does nothing, just clears selection.
495 disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
496 myGeomGUI->getApp()->selectionMgr()->clearSelected();
497 connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
498 this, SLOT(SelectionIntoArgument()));
502 //=================================================================================
503 // function : SetEditCurrentArgument()
505 //=================================================================================
506 void EntityGUI_PolylineDlg::SetEditCurrentArgument()
508 if (sender() == myPlnSelButton) {
510 myEditCurrentArgument = myWPlaneLineEdit;
511 myEditCurrentArgument->setFocus();
512 myPlnSelButton->setDown(true);
513 myPolylineSelButton->setDown(false);
515 } else if (sender() == myPolylineSelButton) {
516 myEditCurrentArgument = myPolylineEdit;
517 myEditCurrentArgument->setFocus();
519 myPlnSelButton->setDown(false);
521 myPolylineSelButton->setDown(true);
525 //=================================================================================
526 // function : ActivateThisDialog
528 //=================================================================================
529 void EntityGUI_PolylineDlg::ActivateThisDialog()
531 GEOMBase_Skeleton::ActivateThisDialog();
533 connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
534 this, SLOT(SelectionIntoArgument()));
537 //=================================================================================
538 // function : enterEvent()
540 //=================================================================================
541 void EntityGUI_PolylineDlg::enterEvent (QEvent*)
543 if (!mainFrame()->GroupConstructors->isEnabled())
544 ActivateThisDialog();
547 //=================================================================================
548 // function : onUpdatePreview
550 //=================================================================================
551 void EntityGUI_PolylineDlg::onUpdatePreview()
553 displayPreview(true);
556 //=================================================================================
557 // function : ActivateLocalCS
558 // purpose : Activate & Fit Working plane
559 //=================================================================================
560 void EntityGUI_PolylineDlg::ActivateLocalCS()
562 const int ind = myPlnComboBox->currentIndex();
567 myWPlaneLineEdit->clear();
569 myPolylineEdit->clear();
570 } else if (ind > 0) { // Skip 0 as it is default
571 // Update text on line edits.
572 QString aName = GEOMBase::GetName(GetActiveWPlane().get());
573 bool isPlane = myPlnComboBox->itemData(ind).toBool();
577 myWPlaneLineEdit->setText(aName);
579 myPolylineEdit->clear();
581 myPolylineEdit->setText(aName);
583 myWPlaneLineEdit->clear();
588 gp_Ax3 anAxis = GetActiveLocalCS();
590 myGeomGUI->SetWorkingPlane(anAxis);
591 myGeomGUI->ActiveWorkingPlane();
594 //=================================================================================
595 // function : GetActiveLocalCS
596 // purpose : Get Working plane
597 //=================================================================================
598 gp_Ax3 EntityGUI_PolylineDlg::GetActiveLocalCS()
600 const int ind = myPlnComboBox->currentIndex();
602 return ind >= 0 ? myLCSList.at(ind) : myGeomGUI->GetWorkingPlane();
605 //=================================================================================
606 // function : GetActiveWPlane
607 // purpose : Get Working plane
608 //=================================================================================
609 GEOM::GeomObjPtr EntityGUI_PolylineDlg::GetActiveWPlane()
611 const int ind = myPlnComboBox->currentIndex();
613 return ind >= 0 ? myWPlaneList.at(ind) : GEOM::GeomObjPtr();
616 //=================================================================================
617 // function : AddLocalCS()
618 // purpose : Add All Coordinates systems in study
619 //=================================================================================
620 void EntityGUI_PolylineDlg::AddLocalCS(GEOM::GeomObjPtr theSelectedObject,
622 const gp_Ax3 &theLCS)
624 QString aName = GEOMBase::GetName(theSelectedObject.get());
626 int index = myPlnComboBox->findText(aName, Qt::MatchExactly);
628 if (index == -1) { // If the working plane hasn't been added yet
629 myWPlaneList.push_back(theSelectedObject);
630 myLCSList.push_back(theLCS);
631 myPlnComboBox->addItem(aName, QVariant(IsPlane));
632 index = myPlnComboBox->count();
633 myPlnComboBox->setCurrentIndex(index - 1);
635 myPlnComboBox->setCurrentIndex(index);
640 //=================================================================================
641 // function : WPlaneToLCS ( aWPlane )
643 //=================================================================================
644 gp_Ax3 EntityGUI_PolylineDlg::WPlaneToLCS(GEOM::GeomObjPtr theGeomObj)
646 TopoDS_Shape aShape =
647 GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), theGeomObj.get());
650 if (theGeomObj || aShape.IsNull()) {
651 MESSAGE("CORBA::is_nil(theGeomObj) || aShape.IsNull()")
654 aLCS.Transform(aShape.Location().Transformation());
656 if (aShape.ShapeType() == TopAbs_FACE) {
657 GEOM::GEOM_IMeasureOperations_ptr aMeasureOp =
658 myGeomGUI->GetGeomGen()->GetIMeasureOperations(getStudyId());
659 double Ox, Oy, Oz, Zx, Zy, Zz, Xx, Xy, Xz;
661 aMeasureOp->GetPosition(theGeomObj.get(), Ox, Oy, Oz, Zx, Zy, Zz, Xx, Xy, Xz);
663 if (aMeasureOp->IsDone()) {
664 gp_Pnt aPnt (Ox, Oy, Oz);
665 gp_Dir aDirN (Zx, Zy, Zz);
666 gp_Dir aDirX (Xx, Xy, Xz);
667 aLCS = gp_Ax3(aPnt, aDirN, aDirX);