1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // GEOM GEOMGUI : GUI for Geometry component
20 // File : EntityGUI_3DSketcherDlg.cxx
25 #include <boost/lexical_cast.hpp>
27 #include "EntityGUI_3DSketcherDlg.h"
28 #include "EntityGUI_Widgets.h"
30 #include <Basics_OCCTVersion.hxx>
33 #include <GeometryGUI.h>
34 #include <Precision.hxx>
37 #include <SUIT_Session.h>
38 #include <SUIT_Desktop.h>
39 #include <SUIT_MessageBox.h>
40 #include <SUIT_ResourceMgr.h>
41 #include <SUIT_ViewWindow.h>
42 #include <SUIT_ViewManager.h>
44 #include <SOCC_ViewModel.h>
45 #include <SalomeApp_Application.h>
46 #include <SalomeApp_DoubleSpinBox.h>
47 #include <LightApp_Application.h>
48 #include <LightApp_SelectionMgr.h>
50 #include <SalomeApp_Tools.h>
54 #include <TColStd_IndexedMapOfInteger.hxx>
55 #include <BRepBuilderAPI_MakeVertex.hxx>
56 #include <BRepBuilderAPI_MakePolygon.hxx>
57 #include <BRepBuilderAPI_MakeEdge.hxx>
59 #include <AIS_Trihedron.hxx>
60 #include <AIS_AngleDimension.hxx>
61 #include <AIS_LengthDimension.hxx>
62 #include <AIS_Drawer.hxx>
63 #include <Geom_Axis2Placement.hxx>
64 #include <Geom_Plane.hxx>
65 #include <SelectMgr_Selection.hxx>
66 #include <gce_MakePln.hxx>
67 #include <Prs3d_AngleAspect.hxx>
68 #include <Prs3d_LineAspect.hxx>
69 #include <Prs3d_LengthAspect.hxx>
70 #if OCC_VERSION_LARGE > 0x06050300
71 #include <Prs3d_TextAspect.hxx>
72 #include <Prs3d_Presentation.hxx>
73 #include <Prs3d_Text.hxx>
74 #include <Graphic3d_VerticalTextAlignment.hxx>
75 #include <Graphic3d_HorizontalTextAlignment.hxx>
76 #include <Graphic3d_AspectText3d.hxx>
77 #include <Font_FontAspect.hxx>
78 #endif // OCC_VERSION_LARGE > 0x06050300
80 // This include must be *AFTER* SOCC_ViewModel.h because
81 // of the constant ROTATE which is a #define in
82 // GEOMImpl_Types.hxx and an enum in SOCC_ViewModel.h
83 #include <GEOMImpl_Types.hxx>
87 // Avoid duplication of angle coordinates in cylindrical mode
88 // Check spherical mode in absolute
100 Locker(bool& l) : myLock(l) { myLock = true; }
101 ~Locker() { myLock = false; }
106 #if OCC_VERSION_LARGE > 0x06050300
107 DEFINE_STANDARD_HANDLE(AIS_Text, AIS_InteractiveObject)
109 class AIS_Text:public AIS_InteractiveObject
113 DEFINE_STANDARD_RTTI(AIS_Text );
119 const TCollection_ExtendedString& , const gp_Pnt& ,
120 Quantity_Color color,
121 Standard_Integer aHJust,
122 Standard_Integer aVJust ,
123 Standard_Real Angle ,
124 Standard_Boolean Zoom ,
125 Standard_Real Height,
126 Font_FontAspect FontAspect,
127 Standard_CString Font
132 void Compute ( const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
133 const Handle(Prs3d_Presentation)& aPresentation,
134 const Standard_Integer aMode);
136 void ComputeSelection ( const Handle(SelectMgr_Selection)& aSelection,
137 const Standard_Integer aMode){} ;
140 TCollection_ExtendedString aText;
145 Standard_Real aAngle;
146 Standard_Real aHeight;
147 Standard_Boolean aZoomable;
148 Quantity_Color aColor;
149 Standard_CString aFont;
150 Font_FontAspect aFontAspect;
151 Graphic3d_HorizontalTextAlignment aHJustification;
152 Graphic3d_VerticalTextAlignment aVJustification;
155 IMPLEMENT_STANDARD_HANDLE(AIS_Text, AIS_InteractiveObject)
156 IMPLEMENT_STANDARD_RTTIEXT(AIS_Text, AIS_InteractiveObject)
158 AIS_Text::AIS_Text( const TCollection_ExtendedString& text, const gp_Pnt& position,
159 Quantity_Color color = Quantity_NOC_YELLOW,
160 Standard_Integer aHJust = Graphic3d_HTA_LEFT,
161 Standard_Integer aVJust = Graphic3d_VTA_BOTTOM,
162 Standard_Real angle = 0.0 ,
163 Standard_Boolean zoomable = Standard_False,
164 Standard_Real height = 16.,
165 Font_FontAspect fontAspect = Font_FA_Regular,
166 Standard_CString font = "Courier")
169 aPosition = position;
170 aHJustification = Graphic3d_HorizontalTextAlignment(aHJust);
171 aVJustification = Graphic3d_VerticalTextAlignment(aVJust);
173 aZoomable = zoomable;
176 aFontAspect = fontAspect;
180 void AIS_Text::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
181 const Handle(Prs3d_Presentation)& aPresentation,
182 const Standard_Integer aMode)
185 aPresentation->Clear();
187 Handle_Prs3d_TextAspect asp = myDrawer->TextAspect();
190 asp->SetColor(aColor);
191 asp->SetHeight(aHeight); // I am changing the myHeight value
193 asp->SetHorizontalJustification(aHJustification);
194 asp->SetVerticalJustification(aVJustification);
195 asp->Aspect()->SetTextZoomable(aZoomable);
196 asp->Aspect()->SetTextAngle(aAngle);
197 asp->Aspect()->SetTextFontAspect(aFontAspect);
198 Prs3d_Text::Draw(aPresentation, asp, aText, aPosition);
200 #endif // OCC_VERSION_LARGE > 0x06050300
202 bool isSame (double d1, double d2)
204 return Abs(d1 - d2) <= Precision::Confusion();
207 //=================================================================================
208 // class : EntityGUI_3DSketcherDlg()
209 // purpose : Constructs a EntityGUI_3DSketcherDlg which is a child of 'parent', with the
210 // name 'name' and widget flags set to 'f'.
211 // The dialog will by default be modeless, unless you set 'modal' to
212 // TRUE to construct a modal dialog.
213 //=================================================================================
214 EntityGUI_3DSketcherDlg::EntityGUI_3DSketcherDlg (GeometryGUI* theGeometryGUI, QWidget* parent,
215 bool modal, Qt::WindowFlags fl,
216 const double lineWidth)
217 : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl),
220 myLineWidth(lineWidth),
221 myGeometryGUI(theGeometryGUI),
224 QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
225 QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_UNDO")));
226 QPixmap image2(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_REDO")));
227 QPixmap image3(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICO_3DSKETCH")));
229 setWindowTitle(tr("GEOM_3DSKETCHER_TITLE"));
231 /***************************************************************/
233 mainFrame()->GroupConstructors->setTitle(tr("GEOM_3DSKETCHER"));
234 mainFrame()->RadioButton1->setIcon(image3);;
235 mainFrame()->RadioButton2->close();
236 mainFrame()->RadioButton3->close();
238 GroupType = new EntityGUI_Type(centralWidget());
239 GroupType->GroupType2->setTitle(tr("GEOM_COORDINATES_TYPE"));
240 GroupType->GroupType1->setTitle(tr("GEOM_MODE"));
241 GroupType->RadioButton1->setText(tr("GEOM_SKETCHER_ABS"));
242 GroupType->RadioButton2->setText(tr("GEOM_SKETCHER_REL"));
243 GroupType->RadioButton3->setText(tr("(X,Y,Z)"));
244 GroupType->RadioButton4->setText(tr("GEOM_ANGLES"));
246 myTypeGroup1 = new QButtonGroup(this);
247 myTypeGroup1->setExclusive(true);
248 myTypeGroup1->addButton(GroupType->RadioButton1, 0);
249 myTypeGroup1->addButton(GroupType->RadioButton2, 1);
251 myTypeGroup2 = new QButtonGroup(this);
252 myTypeGroup2->setExclusive(true);
253 myTypeGroup2->addButton(GroupType->RadioButton3, 0);
254 myTypeGroup2->addButton(GroupType->RadioButton4, 1);
256 Group3Spin = new EntityGUI_3Spin(centralWidget());
257 Group3Spin->GroupBox1->setTitle(tr("GEOM_SKETCHER_VALUES"));
258 Group3Spin->buttonApply->setText(tr("GEOM_SKETCHER_APPLY"));
259 Group3Spin->buttonUndo->setIcon(image1);
260 Group3Spin->buttonRedo->setIcon(image2);
261 Group3Spin->TextLabel1->setText(tr("GEOM_SKETCHER_X2"));
262 Group3Spin->TextLabel2->setText(tr("GEOM_SKETCHER_Y2"));
263 Group3Spin->TextLabel3->setText(tr("GEOM_SKETCHER_Z2"));
265 GroupAngles = new EntityGUI_Angles(centralWidget());
266 GroupAngles->buttonApply->setText(tr("GEOM_SKETCHER_APPLY"));
267 GroupAngles->buttonUndo->setIcon(image1);
268 GroupAngles->buttonRedo->setIcon(image2);
269 GroupAngles->TextLabel1->setText(tr("GEOM_LENGTH"));
270 GroupAngles->TextLabel2->setText(tr("GEOM_ANGLE"));
271 GroupAngles->checkBox ->setText(tr("GEOM_ANGLE_2"));
272 GroupAngles->checkBox_2->setText(tr("GEOM_HEIGHT"));
274 GroupControls = new EntityGUI_Controls(centralWidget());
275 GroupControls->GroupBox1->setTitle(tr("GEOM_CONTROLS"));
276 GroupControls->CheckBox1->setText(tr("GEOM_SHOW_LENGTH"));
277 GroupControls->CheckBox2->setText(tr("GEOM_SHOW_ANGLE"));
278 GroupControls->CheckBox3->setText(tr("GEOM_SHOW_POINTS_COORD"));
279 GroupControls->lineEdit_1->setReadOnly(true);
280 GroupControls->lineEdit_2->setReadOnly(true);
281 GroupControls->lineEdit_3->setReadOnly(true);
282 GroupControls->lineEdit_4->setReadOnly(true);
283 GroupControls->lineEdit_5->setReadOnly(true);
284 GroupControls->lineEdit_6->setReadOnly(true);
285 GroupControls->label_1->setText(tr("X:"));
286 GroupControls->label_2->setText(tr("Y:"));
287 GroupControls->label_3->setText(tr("Z:"));
288 GroupControls->label_4->setText(tr("X:"));
289 GroupControls->label_5->setText(tr("Y:"));
290 GroupControls->label_6->setText(tr("Z:"));
291 GroupControls->label_7->setText(tr("GEOM_START"));
292 GroupControls->label_8->setText(tr("GEOM_END"));
294 buttonOk()->setText(tr("GEOM_BUT_END_SKETCH"));
295 buttonApply()->setText(tr("GEOM_BUT_CLOSE_SKETCH"));
297 QVBoxLayout* layout = new QVBoxLayout(centralWidget());
298 layout->setMargin(0); layout->setSpacing(6);
299 layout->addWidget(GroupType);
300 layout->addWidget(Group3Spin);
301 layout->addWidget(GroupAngles);
302 layout->addWidget(GroupControls);
304 setHelpFileName("create_3dsketcher_page.html");
310 //=================================================================================
311 // function : ~EntityGUI_3DSketcherDlg()
312 // purpose : Destroys the object and frees any allocated resources
313 //=================================================================================
314 EntityGUI_3DSketcherDlg::~EntityGUI_3DSketcherDlg()
316 myGeomGUI->SetActiveDialogBox(0);
319 //=================================================================================
322 //=================================================================================
323 void EntityGUI_3DSketcherDlg::Init()
327 myPrsType = prsType();
329 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
330 myAnglePrs = dynamic_cast<SOCC_Prs*>(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
331 myLengthPrs = dynamic_cast<SOCC_Prs*>(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
332 #if OCC_VERSION_LARGE > 0x06050300
333 myTextPrs = dynamic_cast<SOCC_Prs*>(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
334 #endif // OCC_VERSION_LARGE > 0x06050300
336 localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX);
338 /* Get setting of step value from file configuration */
339 double step = SUIT_Session::session()->resourceMgr()->doubleValue("Geometry", "SettingsGeomStep", 100.0);
341 /* min, max, step and decimals for spin boxes */
342 initSpinBox(Group3Spin->SpinBox_DX, COORD_MIN, COORD_MAX, step, "length_precision");
343 initSpinBox(Group3Spin->SpinBox_DY, COORD_MIN, COORD_MAX, step, "length_precision");
344 initSpinBox(Group3Spin->SpinBox_DZ, COORD_MIN, COORD_MAX, step, "length_precision");
346 initSpinBox(GroupAngles->SpinBox_DA , -360.0, 360.0, step, "angular_precision");
347 initSpinBox(GroupAngles->SpinBox_DA2, -90.0, 90.0, step, "angular_precision");
348 initSpinBox(GroupAngles->SpinBox_DL , COORD_MIN, COORD_MAX, step, "length_precision");
349 initSpinBox(GroupAngles->SpinBox_DH , COORD_MIN, COORD_MAX, step, "length_precision");
351 Group3Spin->SpinBox_DX->setValue(0.0);
352 Group3Spin->SpinBox_DY->setValue(0.0);
353 Group3Spin->SpinBox_DZ->setValue(0.0);
355 GroupAngles->SpinBox_DA->setValue(0.0);
356 GroupAngles->SpinBox_DA2->setValue(0.0);
357 GroupAngles->SpinBox_DL->setValue(0.0);
358 GroupAngles->SpinBox_DH->setValue(0.0);
360 GroupAngles->radioButton_1->setChecked(true);
361 GroupAngles->checkBox->setChecked(false);
362 GroupAngles->checkBox_2->setChecked(false);
363 GroupAngles->SpinBox_DA2->setEnabled(false);
364 GroupAngles->SpinBox_DH->setEnabled(false);
366 GroupControls->CheckBox1->setChecked(true);
367 GroupControls->CheckBox2->setChecked(true);
368 GroupControls->CheckBox3->setChecked(true);
370 isLengthVisible = true;
371 isAngleVisible = true;
375 /* signals and slots connections */
376 connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
377 connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
379 connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
381 connect(Group3Spin->buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnAddPoint()));
382 connect(Group3Spin->buttonUndo, SIGNAL(clicked()), this, SLOT(ClickOnUndo()));
383 connect(Group3Spin->buttonRedo, SIGNAL(clicked()), this, SLOT(ClickOnRedo())) ;
385 connect(GroupAngles->buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnAddPoint()));
386 connect(GroupAngles->buttonUndo, SIGNAL(clicked()), this, SLOT(ClickOnUndo()));
387 connect(GroupAngles->buttonRedo, SIGNAL(clicked()), this, SLOT(ClickOnRedo())) ;
389 connect(myTypeGroup1, SIGNAL(buttonClicked(int)), this, SLOT(TypeClicked(int)));
390 connect(myTypeGroup2, SIGNAL(buttonClicked(int)), this, SLOT(TypeClicked(int)));
392 connect(Group3Spin->SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
393 connect(Group3Spin->SpinBox_DY, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
394 connect(Group3Spin->SpinBox_DZ, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
396 connect(GroupAngles->SpinBox_DA, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
397 connect(GroupAngles->SpinBox_DA2, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
398 connect(GroupAngles->SpinBox_DL, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
399 connect(GroupAngles->SpinBox_DH, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
401 connect(GroupAngles->radioButton_1, SIGNAL(clicked (bool)), this, SLOT(ButtonClicked(bool))) ;
402 connect(GroupAngles->radioButton_2, SIGNAL(clicked (bool)), this, SLOT(ButtonClicked(bool))) ;
403 connect(GroupAngles->radioButton_3, SIGNAL(clicked (bool)), this, SLOT(ButtonClicked(bool))) ;
405 connect(GroupAngles->checkBox, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
406 connect(GroupAngles->checkBox_2, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
407 connect(GroupControls->CheckBox1, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
408 connect(GroupControls->CheckBox2, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
409 connect(GroupControls->CheckBox3, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
411 connect(myGeomGUI, SIGNAL(SignalDefaultStepValueChanged(double)), this, SLOT(SetDoubleSpinBoxStep(double)));
413 connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
414 connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
416 initName(tr("GEOM_3DSKETCHER"));
418 GroupControls->CheckBox3->click();
420 UpdateButtonsState();
425 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
428 //=================================================================================
429 // function : TypeClicked()
430 // purpose : Radio button management
431 //=================================================================================
432 void EntityGUI_3DSketcherDlg::TypeClicked (int id)
434 QButtonGroup* send = (QButtonGroup*) sender();
436 int coordType = myCoordType;
439 if (send == myTypeGroup1)
441 if(id == myMode) return;
444 else if (send == myTypeGroup2)
446 if (id == myCoordType) return;
453 bool blocked = Group3Spin->SpinBox_DX->signalsBlocked();
454 Group3Spin->SpinBox_DX->blockSignals(true);
455 Group3Spin->SpinBox_DY->blockSignals(true);
456 Group3Spin->SpinBox_DZ->blockSignals(true);
458 // Get setting of step value from file configuration
459 XYZ xyz = getLastPoint();
461 Group3Spin->SpinBox_DX->text().toDouble(&okx);
462 Group3Spin->SpinBox_DY->text().toDouble(&oky);
463 Group3Spin->SpinBox_DZ->text().toDouble(&okz);
465 if (coordType == 0) // Cartesian coordinates
467 if (mode == 0) { // XYZ
468 Group3Spin->TextLabel1->setText(tr("GEOM_SKETCHER_X2"));
469 Group3Spin->TextLabel2->setText(tr("GEOM_SKETCHER_Y2"));
470 Group3Spin->TextLabel3->setText(tr("GEOM_SKETCHER_Z2"));
471 if (myCoordType == 0 && myMode == 1)
473 if (okx) Group3Spin->SpinBox_DX->setValue(xyz.x + Group3Spin->SpinBox_DX->value());
474 if (oky) Group3Spin->SpinBox_DY->setValue(xyz.y + Group3Spin->SpinBox_DY->value());
475 if (okz) Group3Spin->SpinBox_DZ->setValue(xyz.z + Group3Spin->SpinBox_DZ->value());
477 Group3Spin->buttonApply->setFocus();
479 else if (mode == 1) { // DXDYDZ
480 Group3Spin->TextLabel1->setText(tr("GEOM_SKETCHER_DX2"));
481 Group3Spin->TextLabel2->setText(tr("GEOM_SKETCHER_DY2"));
482 Group3Spin->TextLabel3->setText(tr("GEOM_SKETCHER_DZ2"));
483 if (myCoordType == 0 && myMode == 0)
485 if (okx) Group3Spin->SpinBox_DX->setValue(Group3Spin->SpinBox_DX->value() - xyz.x);
486 if (oky) Group3Spin->SpinBox_DY->setValue(Group3Spin->SpinBox_DY->value() - xyz.y);
487 if (okz) Group3Spin->SpinBox_DZ->setValue(Group3Spin->SpinBox_DZ->value() - xyz.z);
489 Group3Spin->buttonApply->setFocus();
492 else if (coordType == 1) // Angles and Length
496 GroupAngles->buttonApply->setFocus();
499 Group3Spin->SpinBox_DX->blockSignals(blocked);
500 Group3Spin->SpinBox_DY->blockSignals(blocked);
501 Group3Spin->SpinBox_DZ->blockSignals(blocked);
504 myCoordType = coordType;
507 resize(minimumSizeHint());
509 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
512 //=================================================================================
513 // function : ClickOnAddPoint()
514 // purpose : called when the point coordinates is Applyed
515 //=================================================================================
516 void EntityGUI_3DSketcherDlg::ClickOnAddPoint()
524 myPrsType = prsType();
527 displayDimensions( /*store = */true);
529 myPointsList.append(getCurrentPoint());
531 myLengthIORedoList.Clear();
532 myAngleIORedoList.Clear();
534 if (myCoordType == 0 && myMode == 1) // RELATIVE CARTESIAN COORDINATES
536 Group3Spin->SpinBox_DX->setValue(0.0);
537 Group3Spin->SpinBox_DY->setValue(0.0);
538 Group3Spin->SpinBox_DZ->setValue(0.0);
540 else if (myCoordType == 1 && myMode == 1) // RELATIVE ANGULAR COORDINATES
542 GroupAngles->SpinBox_DA->setValue(0.0);
543 GroupAngles->SpinBox_DL->setValue(0.0);
544 GroupAngles->SpinBox_DA2->setValue(0.0);
547 UpdatePointCoordinates();
549 UpdateButtonsState();
550 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
553 //=================================================================================
554 // function : UpdateButtonsState()
556 //=================================================================================
557 void EntityGUI_3DSketcherDlg::UpdateButtonsState()
559 if (myPointsList.count() == 0)
561 GroupType->RadioButton1->click();
562 GroupType->RadioButton3->click();
564 GroupType->RadioButton2->setEnabled(myPointsList.count() > 0);
565 // GroupType->RadioButton3->setEnabled(myPointsList.count() > 0);
566 // GroupType->RadioButton4->setEnabled(myPointsList.count() > 0);
567 Group3Spin->buttonUndo->setEnabled(myPointsList.count() > 0);
568 Group3Spin->buttonRedo->setEnabled(myRedoList.count() > 0);
569 GroupAngles->buttonUndo->setEnabled(myPointsList.count() > 0);
570 GroupAngles->buttonRedo->setEnabled(myRedoList.count() > 0);
573 //=================================================================================
574 // function : UpdatePointCoordinates()
575 // purpose :Update point coordinates in the control groupbox
576 //=================================================================================
577 void EntityGUI_3DSketcherDlg::UpdatePointCoordinates()
579 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
580 int aPrecision = resMgr->integerValue("Geometry", "length_precision", 6);
582 if (myPointsList.count() == 0)
584 GroupControls->lineEdit_1->setText("");
585 GroupControls->lineEdit_2->setText("");
586 GroupControls->lineEdit_3->setText("");
588 GroupControls->lineEdit_4->setText("");
589 GroupControls->lineEdit_5->setText("");
590 GroupControls->lineEdit_6->setText("");
592 else if (myPointsList.count() == 1)
594 GroupControls->lineEdit_1->setText(DlgRef::PrintDoubleValue(getLastPoint().x, aPrecision));
595 GroupControls->lineEdit_2->setText(DlgRef::PrintDoubleValue(getLastPoint().y, aPrecision));
596 GroupControls->lineEdit_3->setText(DlgRef::PrintDoubleValue(getLastPoint().z, aPrecision));
598 GroupControls->lineEdit_4->setText("");
599 GroupControls->lineEdit_5->setText("");
600 GroupControls->lineEdit_6->setText("");
604 GroupControls->lineEdit_4->setText(DlgRef::PrintDoubleValue(getLastPoint().x, aPrecision));
605 GroupControls->lineEdit_5->setText(DlgRef::PrintDoubleValue(getLastPoint().y, aPrecision));
606 GroupControls->lineEdit_6->setText(DlgRef::PrintDoubleValue(getLastPoint().z, aPrecision));
611 //=================================================================================
612 // function : ClickOnUndo()
614 //=================================================================================
615 void EntityGUI_3DSketcherDlg::ClickOnUndo()
617 if (myPointsList.count() > 0) {
619 myRedoList.append(myPointsList.last());
621 // Erase dimensions presentations
622 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
623 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
624 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
626 removeLastIOFromPrs();
628 // Display modified presentation
630 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
632 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
634 // Remove last point from list
635 myPointsList.removeLast();
636 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
637 UpdateButtonsState();
639 // Update of point coordinates in the control groupbox
640 UpdatePointCoordinates();
646 //=================================================================================
647 // function : ClickOnRedo()
649 //=================================================================================
650 void EntityGUI_3DSketcherDlg::ClickOnRedo()
652 if (myRedoList.count() > 0) {
654 myPointsList.append(myRedoList.last());
656 // Erase dimensions presentations
657 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
658 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
659 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
661 restoreLastIOToPrs();
663 // Display modified presentation
665 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
667 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
669 // Remove last point from redo list
670 myRedoList.removeLast();
671 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
672 UpdateButtonsState();
674 // Update of point coordinates in the control groupbox
675 UpdatePointCoordinates();
681 //=================================================================================
682 // function : removeLastIO()
684 //=================================================================================
685 void EntityGUI_3DSketcherDlg::removeLastIOFromPrs ()
687 AIS_ListOfInteractive anIOList;
688 XYZ Last = getLastPoint();
690 for (int l = 0; l<Last.L; l++)
692 myLengthPrs->GetObjects(anIOList);
693 myLengthIORedoList.Prepend(anIOList.First()); // Store last prepended Length IO in redo list
694 myLengthPrs->RemoveFirst(); // Remove it from myLengthPrs
696 for (int a = 0; a<Last.A; a++)
698 myAnglePrs->GetObjects(anIOList);
699 myAngleIORedoList.Prepend(anIOList.First()); // Store last prepended Angle IO in redo list
700 myAnglePrs->RemoveFirst(); // Remove it from myAnglePrs
704 //=================================================================================
705 // function : restoreLastIO()
707 //=================================================================================
708 void EntityGUI_3DSketcherDlg::restoreLastIOToPrs ()
710 XYZ LastDeleted = myRedoList.last();
712 for (int l = 0; l<LastDeleted.L; l++)
714 myLengthPrs->PrependObject(myLengthIORedoList.First()); // Restore last removed IO
715 myLengthIORedoList.RemoveFirst(); // Remove it from redo list
717 for (int a = 0; a<LastDeleted.A; a++)
719 myAnglePrs->PrependObject(myAngleIORedoList.First()); // Restore last removed IO
720 myAngleIORedoList.RemoveFirst(); // Remove it from redo list
724 //=================================================================================
725 // function : SelectionIntoArgument()
726 // purpose : Called when selection as changed
727 //=================================================================================
728 void EntityGUI_3DSketcherDlg::SelectionIntoArgument()
730 LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
731 SALOME_ListIO aSelList;
732 aSelMgr->selectedObjects(aSelList);
734 int nbSel = aSelList.Extent();
736 GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject(aSelList.First());
737 if (!CORBA::is_nil(aSelectedObject)) {
739 if (GEOMBase::GetShape(aSelectedObject, aShape, TopAbs_SHAPE)) {
740 // Explore the shape if its a local selection
741 TColStd_IndexedMapOfInteger aMap;
742 aSelMgr->GetIndexes(aSelList.First(), aMap);
743 if (aMap.Extent() == 1) {
744 int anIndex = aMap(1);
745 GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations(getStudyId());
746 aSelectedObject = aShapesOp->GetSubShape(aSelectedObject, anIndex);
750 if (aShape.ShapeType() != TopAbs_VERTEX)
751 isOk = GEOMBase::GetShape(aSelectedObject, aShape, TopAbs_VERTEX);
754 if (GEOMBase::VertexToPoint(aShape, aPnt)) {
755 // set coordinates to the Spin Boxes
760 bool blocked = Group3Spin->SpinBox_DX->signalsBlocked();
761 Group3Spin->SpinBox_DX->blockSignals(true);
762 Group3Spin->SpinBox_DY->blockSignals(true);
763 Group3Spin->SpinBox_DZ->blockSignals(true);
764 if (GroupType->RadioButton1->isChecked()) {
765 Group3Spin->SpinBox_DX->setValue(aX);
766 Group3Spin->SpinBox_DY->setValue(aY);
767 Group3Spin->SpinBox_DZ->setValue(aZ);
769 else if (GroupType->RadioButton2->isChecked()) {
770 XYZ xyz = getLastPoint();
771 Group3Spin->SpinBox_DX->setValue(aX - xyz.x);
772 Group3Spin->SpinBox_DY->setValue(aY - xyz.y);
773 Group3Spin->SpinBox_DZ->setValue(aZ - xyz.z);
775 Group3Spin->SpinBox_DX->blockSignals(blocked);
776 Group3Spin->SpinBox_DY->blockSignals(blocked);
777 Group3Spin->SpinBox_DZ->blockSignals(blocked);
782 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
785 //=================================================================================
786 // function : DeactivateActiveDialog()
788 //=================================================================================
789 void EntityGUI_3DSketcherDlg::DeactivateActiveDialog()
793 disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
794 myGeomGUI->SetActiveDialogBox(0);
797 //=================================================================================
798 // function : ActivateThisDialog()
800 //=================================================================================
801 void EntityGUI_3DSketcherDlg::ActivateThisDialog()
803 myGeomGUI->EmitSignalDeactivateDialog();
805 myGeomGUI->SetActiveDialogBox(this);
807 connect(myGeomGUI->getApp()->selectionMgr(),
808 SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
810 localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX);
811 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
814 //=================================================================================
815 // function : ValueChangedInSpinBox()
817 //=================================================================================
818 void EntityGUI_3DSketcherDlg::ValueChangedInSpinBox (double newValue)
820 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
823 //=================================================================================
824 // function : BoxChecked()
825 // purpose : ChecBoxes management
826 //=================================================================================
827 void EntityGUI_3DSketcherDlg::BoxChecked (bool checked)
829 QCheckBox* send = (QCheckBox*) sender();
830 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
832 if (send == GroupAngles->checkBox)
834 GroupAngles->SpinBox_DA2->setEnabled(checked);
837 GroupAngles->SpinBox_DH->setEnabled(false);
838 GroupAngles->checkBox_2->setChecked(false);
841 else if (send == GroupAngles->checkBox_2)
843 GroupAngles->SpinBox_DH->setEnabled(checked);
846 GroupAngles->SpinBox_DA2->setEnabled(false);
847 GroupAngles->checkBox->setChecked(false);
851 else if (send == GroupControls->CheckBox1)
853 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
855 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
856 isLengthVisible=true;
859 isLengthVisible=false;
861 else if (send == GroupControls->CheckBox2)
863 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
866 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
870 isAngleVisible=false;
872 else if (send == GroupControls->CheckBox3)
874 GroupControls->lineEdit_1->setVisible(checked);
875 GroupControls->lineEdit_2->setVisible(checked);
876 GroupControls->lineEdit_3->setVisible(checked);
877 GroupControls->lineEdit_4->setVisible(checked);
878 GroupControls->lineEdit_5->setVisible(checked);
879 GroupControls->lineEdit_6->setVisible(checked);
881 GroupControls->label_1->setVisible(checked);
882 GroupControls->label_2->setVisible(checked);
883 GroupControls->label_3->setVisible(checked);
884 GroupControls->label_4->setVisible(checked);
885 GroupControls->label_5->setVisible(checked);
886 GroupControls->label_6->setVisible(checked);
887 GroupControls->label_7->setVisible(checked);
888 GroupControls->label_8->setVisible(checked);
890 GroupControls->updateGeometry();
891 GroupControls->resize(minimumSizeHint());
895 resize(minimumSizeHint());
897 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
900 //=================================================================================
901 // function : ButtonClicked()
903 //=================================================================================
904 void EntityGUI_3DSketcherDlg::ButtonClicked (bool checked)
906 if (GroupAngles->radioButton_1->isChecked())
908 else if (GroupAngles->radioButton_2->isChecked())
913 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
916 //=================================================================================
917 // function : enterEvent()
919 //=================================================================================
920 void EntityGUI_3DSketcherDlg::enterEvent (QEvent*)
922 if (!mainFrame()->GroupConstructors->isEnabled())
923 ActivateThisDialog();
926 //=================================================================================
927 // function : createOperation
929 //=================================================================================
930 GEOM::GEOM_IOperations_ptr EntityGUI_3DSketcherDlg::createOperation()
932 return getGeomEngine()->GetICurvesOperations(getStudyId());
935 //=================================================================================
936 // function : isValid
938 //=================================================================================
939 bool EntityGUI_3DSketcherDlg::isValid (QString& msg)
942 ok = Group3Spin->SpinBox_DX->isValid(msg, !IsPreview()) && ok;
943 ok = Group3Spin->SpinBox_DY->isValid(msg, !IsPreview()) && ok;
944 ok = Group3Spin->SpinBox_DZ->isValid(msg, !IsPreview()) && ok;
948 //=================================================================================
949 // function : execute
951 //=================================================================================
952 bool EntityGUI_3DSketcherDlg::execute (ObjectList& objects)
954 //GEOM::ListOfDouble_var aCoordsArray = new GEOM::ListOfDouble;
955 //if (!myOK || myPointsList.size() == 0)
956 // aCoordsArray->length((myPointsList.size()+1)*3);
958 // aCoordsArray->length(myPointsList.size()*3);
960 QStringList aCommands;
961 aCommands << "3DSketcher";
962 QStringList aParameters;
965 QList<XYZ>::const_iterator it;
966 for (it = myPointsList.begin(); it != myPointsList.end(); ++it) {
967 //aCoordsArray[i++] = (*it).x;
968 //aCoordsArray[i++] = (*it).y;
969 //aCoordsArray[i++] = (*it).z;
970 aCommands << (*it).command;
971 aParameters << (*it).params;
974 if (!myOK || myPointsList.size() == 0) {
975 XYZ xyz = getCurrentPoint();
976 //aCoordsArray[i++] = xyz.x;
977 //aCoordsArray[i++] = xyz.y;
978 //aCoordsArray[i++] = xyz.z;
979 aCommands << xyz.command;
980 aParameters << xyz.params;
983 // MESSAGE("aCommands.last() = "<< aCommands.last().toStdString());
984 GEOM::GEOM_ICurvesOperations_var anOper = GEOM::GEOM_ICurvesOperations::_narrow(getOperation());
985 //GEOM::GEOM_Object_var anObj = anOper->Make3DSketcher(aCoordsArray);
986 GEOM::GEOM_Object_var anObj = anOper->Make3DSketcherCommand(aCommands.join(":").toLatin1().constData());
988 if (!anObj->_is_nil()) {
989 if (!IsPreview()) anObj->SetParameters(aParameters.join(":").toLatin1().constData());
990 objects.push_back(anObj._retn());
996 //=================================================================================
997 // function : SetDoubleSpinBoxStep()
998 // purpose : Double spin box management
999 //=================================================================================
1000 void EntityGUI_3DSketcherDlg::SetDoubleSpinBoxStep (double step)
1002 Group3Spin->SpinBox_DX->setSingleStep(step);
1003 Group3Spin->SpinBox_DY->setSingleStep(step);
1004 Group3Spin->SpinBox_DZ->setSingleStep(step);
1005 GroupAngles->SpinBox_DA ->setSingleStep(step);
1006 GroupAngles->SpinBox_DA2->setSingleStep(step);
1007 GroupAngles->SpinBox_DL->setSingleStep(step);
1008 GroupAngles->SpinBox_DH->setSingleStep(step);
1011 //=================================================================================
1012 // function : ClickOnOk()
1014 //=================================================================================
1015 void EntityGUI_3DSketcherDlg::ClickOnOk()
1025 //=================================================================================
1026 // function : ClickOnApply()
1028 //=================================================================================
1029 bool EntityGUI_3DSketcherDlg::ClickOnApply()
1032 if (!isValid(msg)) {
1037 if (myPointsList.count() > 0)
1038 myPointsList.append(myPointsList[0]);
1049 //=================================================================================
1050 // function : getLastPoint()
1051 // purpose : return last points from list
1052 //=================================================================================
1053 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getLastPoint() const
1055 return myPointsList.count() > 0 ? myPointsList.last() : XYZ();
1058 //=================================================================================
1059 // function : getPenultimatePoint()
1060 // purpose : return penultimate point from list
1061 //=================================================================================
1062 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getPenultimatePoint() const
1064 double size = myPointsList.count();
1065 return size > 1 ? myPointsList.at(size - 2) : XYZ();
1068 //=================================================================================
1069 // function : getCurrentPoint()
1070 // purpose : returns current point
1071 //=================================================================================
1072 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getCurrentPoint() const
1076 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1077 int aPrecision = resMgr->integerValue("Geometry", "length_precision", 7);
1079 bool spherical = GroupAngles->checkBox->isChecked();
1080 bool cylindrical = GroupAngles->checkBox_2->isChecked();
1082 if (myCoordType == 1)
1084 if (GroupAngles->radioButton_1->isChecked())
1085 xyz.command = "OXY";
1086 else if (GroupAngles->radioButton_2->isChecked())
1087 xyz.command = "OYZ";
1089 xyz.command = "OXZ";
1091 if (cylindrical) // Cylindrical coordinates (radius, angle, height)
1094 xyz.command += "S"; // Spherical coordinates (radius, angle1, angle2) --> polar if angle2 = 0
1096 if (myMode == 0) // Absolute coordinates
1097 xyz.command += "A ";
1098 else if (myMode == 1) // Relative coordinates
1099 xyz.command += "R ";
1102 double anAngle = GroupAngles->SpinBox_DA->value();
1103 double aLength = GroupAngles->SpinBox_DL->value();
1105 double anAngle2 = 0.0;
1107 if (spherical) { // Spherical coordinates (radius, angle1, angle2)
1108 anAngle2 = GroupAngles->SpinBox_DA2->value();
1109 da2 = GroupAngles->SpinBox_DA2->text();
1112 double aHeight = 0.0;
1115 aHeight = GroupAngles->SpinBox_DH->value();
1116 dh = GroupAngles->SpinBox_DH->text();
1120 QString::number(anAngle, 'g', aPrecision) + " ";
1122 GroupAngles->SpinBox_DA->text() + ":";
1127 QString::number(aHeight, 'g', aPrecision) + " ";
1131 else // Spherical or polar coordinates
1134 QString::number(anAngle2, 'g', aPrecision) + " ";
1140 QString::number(aLength, 'g', aPrecision);
1142 GroupAngles->SpinBox_DL->text();
1145 // Calculate point coordinates for preview
1146 anAngle = anAngle * M_PI/180.0;
1147 anAngle2 = anAngle2 * M_PI/180.0;
1148 double aProjectedLength = aLength * cos(anAngle2);
1150 XYZ xyzP = getLastPoint();
1152 xyzP.x=xyzP.y=xyzP.z=0.0;
1153 if (GroupAngles->radioButton_1->isChecked()) // OXY
1155 xyz.x = xyzP.x + aProjectedLength * cos(anAngle);
1156 xyz.y = xyzP.y + aProjectedLength * sin(anAngle);
1158 xyz.z = xyzP.z + aHeight;
1160 xyz.z = xyzP.z + aLength * sin(anAngle2);
1162 else if (GroupAngles->radioButton_2->isChecked()) // OYZ
1164 xyz.y = xyzP.y + aProjectedLength * cos(anAngle);
1165 xyz.z = xyzP.z + aProjectedLength * sin(anAngle);
1167 xyz.x = xyzP.x + aHeight;
1169 xyz.x = xyzP.x + aLength * sin(anAngle2);
1173 xyz.z = xyzP.z + aProjectedLength * sin(anAngle);
1174 xyz.x = xyzP.x + aProjectedLength * cos(anAngle);
1176 xyz.y = xyzP.y + aHeight;
1178 xyz.y = xyzP.y + aLength * sin(anAngle2);
1181 else if(myCoordType == 0) {
1182 if (myMode == 0) { // XYZ
1183 xyz.x = Group3Spin->SpinBox_DX->value();
1184 xyz.y = Group3Spin->SpinBox_DY->value();
1185 xyz.z = Group3Spin->SpinBox_DZ->value();
1186 xyz.command = "TT ";
1189 xyz = getLastPoint();
1190 xyz.x += Group3Spin->SpinBox_DX->value();
1191 xyz.y += Group3Spin->SpinBox_DY->value();
1192 xyz.z += Group3Spin->SpinBox_DZ->value();
1196 double aX = Group3Spin->SpinBox_DX->value();
1197 double aY = Group3Spin->SpinBox_DY->value();
1198 double aZ = Group3Spin->SpinBox_DZ->value();
1201 QString::number(aX, 'g', aPrecision) + " " +
1202 QString::number(aY, 'g', aPrecision) + " " +
1203 QString::number(aZ, 'g', aPrecision);
1205 Group3Spin->SpinBox_DX->text() + ":" +
1206 Group3Spin->SpinBox_DY->text() + ":" +
1207 Group3Spin->SpinBox_DZ->text();
1209 // Update point presentation type
1210 xyz.A = myPrsType.A; // Number of angle diomensions
1211 xyz.L = myPrsType.L; // Number of length dimensions
1217 //=================================================================================
1218 // function : getPresentationPlane()
1219 // purpose : returns the suitable plane for right
1220 // relative positioning of dimension presentations
1221 //=================================================================================
1222 gp_Dir EntityGUI_3DSketcherDlg::getPresentationPlane() const
1224 bool withAngle = (myCoordType == 1);
1225 bool twoAngles = GroupAngles->checkBox->isChecked();
1227 XYZ Last = getLastPoint();
1228 XYZ Current = getCurrentPoint();
1229 XYZ Penultimate = getPenultimatePoint();
1231 gp_Pnt P1 = gp_Pnt(Last.x,Last.y,Last.z);
1232 if (myMode == 0) // Absolute coordinates
1235 gp_Pnt P2 = gp_Pnt(Current.x,Current.y,Current.z);
1236 gp_Pnt P3 = gp_Pnt(Penultimate.x,Penultimate.y,Penultimate.z);
1241 gp_Dir aNormal; // Normal defining the plane of the presentation
1243 if (withAngle) // If one angle
1245 // Transformation from the current coordinate system
1246 // to the reference coordinate system
1247 gp_Trsf aTransform = toReferenceSystem (P1);
1248 gp_Dir N1 = gp::DZ();
1249 gp_Dir N2 = gp::DY();
1250 N1.Transform(aTransform);
1251 N2.Transform(aTransform);
1253 if (Vec1.CrossMagnitude(N1) > Precision::Confusion())
1255 // The plane is orthogonal to the angle presentation plane
1256 // and contains the current edge
1257 aNormal = N1.Crossed(gp_Dir(Vec1));
1264 gp_Vec V = Vec1.Transformed(aTransform.Inverted());
1265 gp_Vec Vec3(V.X(),V.Y(),0.0);
1267 // Express the coordinates in the refernce coordinate system (OXY)
1268 Vec3.Transform(aTransform);
1269 if(Abs(Vec1.CrossMagnitude(Vec3)) > Precision::Confusion())
1271 // set the normal as the cross product of the current edge with its projection
1272 // it ensures that the dimension changes side when the angle becomes negative
1273 aNormal = gp_Dir(Vec1.Crossed(Vec3));
1279 // Check colinearity
1280 if (Abs(Vec1.CrossMagnitude(Vec2)) < Precision::Confusion())
1282 Vec2 = gp_Vec(gp::DX());
1283 if (Abs(Vec1.CrossMagnitude(Vec2)) < Precision::Confusion())
1285 Vec2 = gp_Vec(gp::DY());
1288 // If no angles, the plane is the one formed by the last edge and the current one
1289 aNormal = gp_Dir(Vec1.Crossed(Vec2));
1294 //================================================================
1295 // Function : displayPreview
1296 // Purpose : Method for displaying preview of resulting shape
1297 // Redefined from GEOMBase_Helper.
1298 //================================================================
1299 void EntityGUI_3DSketcherDlg::displayPreview (GEOM::GEOM_Object_ptr object,
1301 const bool activate,
1303 const double lineWidth,
1304 const int displayMode,
1307 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1309 QColor aColor = resMgr->colorValue("Geometry","line_color",QColor(255,0,0));
1310 Quantity_NameOfColor line_color = SalomeApp_Tools::color(aColor).Name();
1312 // set width of displayed shape
1315 lw = resMgr->integerValue("Geometry", "preview_edge_width", -1);
1317 getDisplayer()->SetWidth(lw);
1319 // Disable activation of selection
1320 getDisplayer()->SetToActivate(activate);
1322 // Make a reference to GEOM_Object
1323 CORBA::String_var objStr = myGeometryGUI->getApp()->orb()->object_to_string(object);
1324 getDisplayer()->SetName(objStr.in());
1326 // Create wire from applied object
1327 TopoDS_Shape anApplyedWire, aLastSegment;
1328 if (!createShapes(object, anApplyedWire, aLastSegment))
1331 // Set color for preview shape
1332 getDisplayer()->SetColor(line_color);
1335 SALOME_Prs* aPrs = getDisplayer()->BuildPrs(anApplyedWire);
1336 if (aPrs != 0 && !aPrs->IsNull())
1337 GEOMBase_Helper::displayPreview(aPrs, append, update);
1339 getDisplayer()->SetColor(Quantity_NOC_VIOLET);
1340 aPrs = getDisplayer()->BuildPrs(aLastSegment);
1342 if (aPrs != 0 && !aPrs->IsNull())
1343 GEOMBase_Helper::displayPreview(aPrs, append, update);
1345 getDisplayer()->SetColor(line_color);
1347 // Display local trihedron if the mode is relative
1349 displayTrihedron(2);
1351 // Display preview of suitable dimension presentations
1352 displayDimensions(false);
1354 getDisplayer()->UnsetName();
1356 // Enable activation of displayed objects
1357 getDisplayer()->SetToActivate(true);
1360 //================================================================
1361 // Function : displayTrihedron()
1362 // Purpose : Method for displaying trihedron
1363 //================================================================
1364 void EntityGUI_3DSketcherDlg::displayTrihedron (int selMode)
1366 // Add trihedron to preview
1367 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1369 gp_Pnt P(getLastPoint().x,getLastPoint().y,getLastPoint().z);
1370 Handle(Geom_Axis2Placement) anAxis = new Geom_Axis2Placement(P,gp::DZ(),gp::DX());
1371 Handle(AIS_Trihedron) anIO = new AIS_Trihedron(anAxis);
1372 anIO->SetSelectionMode(selMode);
1374 SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1375 (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1378 aSPrs->PrependObject(anIO);
1379 GEOMBase_Helper::displayPreview(aSPrs, true, true);
1383 //================================================================
1384 // Function : displayDimensions( bool store )
1385 // Purpose : Method for displaying dimensions. If store = true
1386 // the presentation is stored in a list
1387 //================================================================
1388 void EntityGUI_3DSketcherDlg::displayDimensions (bool store)
1390 myPrsType = prsType();
1391 XYZ Last = getLastPoint();
1392 XYZ Current = getCurrentPoint();
1394 gp_Pnt Last_Pnt(Last.x,Last.y,Last.z);
1396 gp_Pnt P0 = Last_Pnt;
1397 gp_Pnt Origin = gp::Origin();
1398 if (myMode == 0) // Absolute coordinates
1401 gp_Pnt Current_Pnt(Current.x,Current.y,Current.z);
1404 // Check if last end current point are coincident
1405 if (Last_Pnt.IsEqual(Current_Pnt, 1e-7))
1408 gp_Dir aNormal = getPresentationPlane();
1410 if (myCoordType == 0)
1412 bool oneDimensionalMove = (isSame(Last_Pnt.X(), Current_Pnt.X()) &&
1413 isSame(Last_Pnt.Y(), Current_Pnt.Y()) ) ||
1414 (isSame(Last_Pnt.Y(), Current_Pnt.Y()) &&
1415 isSame(Last_Pnt.Z(), Current_Pnt.Z()) ) ||
1416 (isSame(Last_Pnt.X(), Current_Pnt.X()) &&
1417 isSame(Last_Pnt.Z(), Current_Pnt.Z()) );
1421 std::string aCoordText = "( " + doubleToString(Current_Pnt.X()) +
1422 ", " + doubleToString(Current_Pnt.Y()) +
1423 ", " + doubleToString(Current_Pnt.Z()) + " )";
1424 displayText(aCoordText, Current_Pnt, store);
1428 if (oneDimensionalMove)
1430 // For better colocation of dimensions if only one coordinate changes (aNormal is a better choice)
1431 displayLength(P0, Current_Pnt, aNormal, store);
1435 displayLength(gp_Pnt(P0.X(),Current.y,P0.Z()), gp_Pnt(Current.x,Current.y,P0.Z()), gp::DZ().Reversed(), store);
1436 displayLength(gp_Pnt(Current.x,P0.Y(),P0.Z()), gp_Pnt(Current.x,Current.y,P0.Z()), gp::DZ(), store);
1437 displayLength(gp_Pnt(Current.x,Current.y,P0.Z()), Current_Pnt, gp::DX(), store);
1441 else if (myCoordType == 1) // ANGLES
1443 bool spherical = GroupAngles->checkBox->isChecked();
1444 bool cylindrical = GroupAngles->checkBox_2->isChecked();
1446 double anAngle1 = GroupAngles->SpinBox_DA->value();
1447 double aLength = GroupAngles->SpinBox_DL->value();
1449 // Set the coordinates in the current coordinate system
1450 P1.SetCoord( aLength, 0.0, 0.0); // X direction
1451 P2.SetCoord( aLength * cos(anAngle1 * M_PI / 180. ),
1452 aLength * sin(anAngle1 * M_PI / 180. ),
1455 // Express the coordinates in the refernce coordinate system (OXY)
1456 gp_Trsf aTranform = toReferenceSystem(P0);
1457 P1.Transform(aTranform);
1458 P2.Transform(aTranform);
1459 P1.Translate(Origin, P0);
1460 P2.Translate(Origin, P0);
1462 if(myMode !=0 || !store)
1463 displayAngle(anAngle1, P0, P1, P2, store);
1466 std::string anAngleText = doubleToString(anAngle1) + "deg";
1467 displayText(anAngleText, Current_Pnt, store);
1472 double anAngle2 = GroupAngles->SpinBox_DA2->value();
1473 displayAngle(anAngle2, P0, P2, Current_Pnt, store);
1474 displayLength(P0, Current_Pnt, aNormal, store);
1478 bool sameRadius = isSame ( radius(Last_Pnt), radius(Current_Pnt) );
1479 bool sameHeight = isSame ( height(Last_Pnt), height(Current_Pnt) );
1481 gp_Vec aVec(P2, Current_Pnt);
1483 if (myMode == 0 && !sameRadius)
1485 displayLength(P0.Translated(aVec), P2.Translated(aVec), aNormal, store); // Radius
1487 else if (myMode == 1)
1488 displayLength(P0, P2, aNormal, store);
1491 (myMode == 1 || !sameHeight) )
1492 displayLength(P2, Current_Pnt, aNormal.Reversed(), store); // Height
1497 //================================================================
1498 // Function : displayAngle()
1499 // Purpose : Method for displaying angle dimensions
1500 //================================================================
1501 void EntityGUI_3DSketcherDlg::displayAngle (double theAngle,
1507 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1509 // Creation of the AIS object
1510 Handle(AIS_AngleDimension) anAngleIO = createAISAngleDimension(theAngle,
1514 if (anAngleIO == NULL)
1519 // Erase dimensions presentations
1520 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
1521 myAnglePrs->PrependObject(anAngleIO);
1523 // Display modified presentation
1525 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
1527 // Update dimension presentation angle count for later undo / redo
1530 else if ( isAngleVisible)
1532 SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1533 (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1537 aSPrs->AddObject(anAngleIO);
1538 GEOMBase_Helper::displayPreview(aSPrs, true, true);
1544 //================================================================
1545 // Function : displayLength()
1546 // Purpose : Method for displaying length dimensions for a segment
1548 //================================================================
1549 void EntityGUI_3DSketcherDlg::displayLength (gp_Pnt P1,
1554 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1556 double aLength = P1.Distance(P2);
1558 if (aLength < Precision::Confusion())
1561 Handle(AIS_LengthDimension) anIO = createAISLengthDimension(aLength, P1, P2, theNormal);
1565 // Erase length dimensions presentation
1566 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
1567 myLengthPrs->PrependObject(anIO);
1569 // Display modified presentation
1570 if (isLengthVisible)
1571 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
1573 // Update dimension presentation length count for later undo / redo
1576 else if (isLengthVisible)
1578 SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1579 (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1582 aSPrs->PrependObject(anIO);
1583 GEOMBase_Helper::displayPreview(aSPrs, true, true);
1588 //================================================================
1589 // Function : displayText()
1590 // Purpose : Method for displaying length dimensions for a segment
1592 //================================================================
1593 void EntityGUI_3DSketcherDlg::displayText ( std::string theText,
1597 #if OCC_VERSION_LARGE > 0x06050300
1598 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1600 Handle(AIS_Text) anIO = new AIS_Text(TCollection_ExtendedString(theText.c_str()), P);
1604 // Erase length dimensions presentation
1605 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myTextPrs, true);
1606 myTextPrs->PrependObject(anIO);
1608 // Display modified presentation
1609 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myTextPrs);
1613 SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1614 (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1617 aSPrs->PrependObject(anIO);
1618 GEOMBase_Helper::displayPreview(aSPrs, true, true);
1621 #endif // OCC_VERSION_LARGE > 0x06050300
1624 //================================================================
1625 // Function : createAISLengthDimension()
1626 // Purpose : Method for creation of a length dimension object
1627 // Returns an Handle on the AIS_LengthDimension obect
1628 //================================================================
1629 Handle(AIS_LengthDimension) EntityGUI_3DSketcherDlg::createAISLengthDimension(double theLength,
1634 // Convert length to string
1635 std::string aLength_str = doubleToString(theLength);
1637 // Plane construction
1638 gce_MakePln gce_MP(P1, theNormal);
1639 Handle(Geom_Plane) aPlane = new Geom_Plane(gce_MP.Value());
1641 TopoDS_Vertex aVert1 = BRepBuilderAPI_MakeVertex(P1);
1642 TopoDS_Vertex aVert2 = BRepBuilderAPI_MakeVertex(P2);
1644 Handle(AIS_LengthDimension) anIO =
1645 new AIS_LengthDimension(aVert1,
1649 TCollection_ExtendedString(aLength_str.c_str()));
1650 anIO->SetArrowSize(theLength/20);
1652 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1653 int w = resMgr->integerValue("Geometry", "measures_line_width", 1);
1654 Handle(Prs3d_LengthAspect) asp = new Prs3d_LengthAspect();
1655 asp->LineAspect()->SetWidth(w);
1656 anIO->Attributes()->SetLengthAspect(asp);
1661 //================================================================
1662 // Function : createAISAngleDimension()
1663 // Purpose : Method for creation of an angle dimension object
1664 // Returns an Handle on the AIS_AngleDimension obect
1665 //================================================================
1666 Handle(AIS_AngleDimension) EntityGUI_3DSketcherDlg::createAISAngleDimension(double theAngle,
1671 // Length of the built segment
1672 double aLength = P0.Distance(P1);
1675 if (Abs(theAngle) < Precision::Angular() ||
1676 aLength < Precision::Confusion())
1679 // Convert angles to string
1680 std::string Angle_str = doubleToString(theAngle);
1682 // Construction of the plane
1683 gce_MakePln gce_MP2(P0, P1, P2);
1684 Handle(Geom_Plane) aPlane = new Geom_Plane(gce_MP2.Value());
1686 TopoDS_Vertex V0 = BRepBuilderAPI_MakeVertex(P0);
1687 TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(P1);
1688 TopoDS_Vertex V2 = BRepBuilderAPI_MakeVertex(P2);
1690 TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge(V0, V1);
1691 TopoDS_Edge anEdge2 = BRepBuilderAPI_MakeEdge(V0, V2);
1693 Handle(AIS_AngleDimension) anIO =
1694 new AIS_AngleDimension(anEdge1, anEdge2, aPlane, theAngle * M_PI / 180.,
1695 TCollection_ExtendedString(Angle_str.c_str()));
1697 anIO->SetArrowSize((theAngle * M_PI / 180) * (aLength/20));
1699 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1700 int w = resMgr->integerValue("Geometry", "measures_line_width", 1);
1701 Handle(Prs3d_AngleAspect) asp = new Prs3d_AngleAspect();
1702 asp->LineAspect()->SetWidth(w);
1703 anIO->Attributes()->SetAngleAspect(asp);
1708 //================================================================
1709 // Function : createShapes
1710 // Purpose : Create applyed wire, and last segment from entry object
1711 //================================================================
1712 bool EntityGUI_3DSketcherDlg::createShapes (GEOM::GEOM_Object_ptr /*theObject*/,
1713 TopoDS_Shape& theApplyedWire,
1714 TopoDS_Shape& theLastSegment)
1716 QList<gp_Pnt> points;
1717 foreach (XYZ xyz, myPointsList) {
1718 gp_Pnt p(xyz.x, xyz.y, xyz.z);
1719 if (points.isEmpty() || points.last().Distance(p) > gp::Resolution())
1723 if (points.count() == 1) {
1724 // only one point is created
1725 BRepBuilderAPI_MakeVertex mkVertex (points.last());
1726 theApplyedWire = mkVertex.Shape();
1728 else if (points.count() > 1) {
1730 BRepBuilderAPI_MakePolygon mkWire;
1731 foreach(gp_Pnt p, points)
1733 theApplyedWire = mkWire.Shape();
1736 XYZ curxyz = getCurrentPoint();
1737 gp_Pnt curpnt(curxyz.x, curxyz.y, curxyz.z);
1739 if (points.isEmpty() || points.last().Distance(curpnt) <= gp::Resolution()) {
1740 BRepBuilderAPI_MakeVertex mkVertex (curpnt);
1741 theLastSegment = mkVertex.Shape();
1744 BRepBuilderAPI_MakeEdge mkEdge(points.last(), curpnt);
1745 theLastSegment = mkEdge.Shape();
1748 /* VSR: old algorithm does not work properly, see bug 0020899
1749 TopoDS_Shape aShape;
1750 if (!GEOMBase::GetShape(theObject, aShape))
1753 if (aShape.ShapeType() != TopAbs_WIRE && aShape.ShapeType() != TopAbs_VERTEX)
1756 theApplyedWire = aShape;
1760 BRepBuilderAPI_MakeWire aBuilder;
1761 TopExp_Explorer edgeExp(aShape, TopAbs_EDGE);
1763 TopoDS_Shape anEdge = edgeExp.Current();
1765 if (edgeExp.More()) // i.e. non-last edge
1766 aBuilder.Add(TopoDS::Edge(anEdge));
1768 theLastSegment = anEdge;
1773 if (aBuilder.IsDone()) {
1774 theApplyedWire = aBuilder.Shape();
1776 else if (!theLastSegment.IsNull()) {
1777 TopExp_Explorer vertexExp(theLastSegment, TopAbs_VERTEX);
1778 theApplyedWire = vertexExp.Current();
1785 //================================================================
1786 // Function : doubleToString
1787 // Purpose : converts double to string
1788 //================================================================
1789 std::string EntityGUI_3DSketcherDlg::doubleToString (double num)
1793 char format = 'g'; // truncated to a number of significant digits
1795 return QString::number(num, format, digNum).toStdString();
1798 //================================================================
1799 // Function : toReferenceSystem ()
1801 //================================================================
1802 gp_Trsf EntityGUI_3DSketcherDlg::toReferenceSystem(gp_Pnt origin) const
1804 gp_Trsf T; // Identity transformation
1805 gp_Ax3 reference_system; // OXY
1806 reference_system.SetLocation(origin);
1808 gp_Ax3 current_system = reference_system;
1809 switch (myOrientation)
1813 current_system = gp_Ax3(origin, gp::DX(), gp::DY());
1818 current_system = gp_Ax3(origin, gp::DY().Reversed(), gp::DX());
1823 T.SetTransformation( current_system, reference_system );
1828 //================================================================
1829 // Function : toCurrentSystem ()
1831 //================================================================
1832 gp_Trsf EntityGUI_3DSketcherDlg::toCurrentSystem(gp_Pnt origin) const
1834 return toReferenceSystem(origin).Inverted();
1837 //================================================================
1838 // Function : radius (gp_Pnt) const
1840 //================================================================
1841 double EntityGUI_3DSketcherDlg::radius (gp_Pnt thePnt) const
1843 // Get the point coordinates in the current coordinates system
1844 gp_Trsf aTrsf = toCurrentSystem(gp::Origin());
1845 gp_Pnt aPnt = thePnt.Transformed(aTrsf);
1847 double radius = sqrt(aPnt.X()*aPnt.X() + aPnt.Y()*aPnt.Y());
1851 //================================================================
1852 // Function : height (gp_Pnt) const
1854 //================================================================
1855 double EntityGUI_3DSketcherDlg::height (gp_Pnt thePnt) const
1857 // Get the point coordinates in the current coordinates system
1858 gp_Trsf aTrsf = toCurrentSystem(gp::Origin());
1859 gp_Pnt aPnt = thePnt.Transformed(aTrsf);