1 // Copyright (C) 2007-2016 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, or (at your option) any later version.
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
20 // GEOM GEOMGUI : GUI for Geometry component
21 // File : EntityGUI_3DSketcherDlg.cxx
26 #include <boost/lexical_cast.hpp>
28 #include "EntityGUI_3DSketcherDlg.h"
29 #include "EntityGUI_Widgets.h"
31 #include <Basics_OCCTVersion.hxx>
34 #include <GeometryGUI.h>
35 #include <Precision.hxx>
38 #include <SUIT_Session.h>
39 #include <SUIT_Desktop.h>
40 #include <SUIT_MessageBox.h>
41 #include <SUIT_ResourceMgr.h>
42 #include <SUIT_ViewWindow.h>
43 #include <SUIT_ViewManager.h>
45 #include <SOCC_ViewModel.h>
46 #include <SalomeApp_Application.h>
47 #include <SalomeApp_DoubleSpinBox.h>
48 #include <LightApp_Application.h>
49 #include <LightApp_SelectionMgr.h>
51 #include <SalomeApp_Tools.h>
55 #include <TColStd_IndexedMapOfInteger.hxx>
56 #include <BRepBuilderAPI_MakeVertex.hxx>
57 #include <BRepBuilderAPI_MakePolygon.hxx>
58 #include <BRepBuilderAPI_MakeEdge.hxx>
60 #include <AIS_Trihedron.hxx>
61 #include <AIS_AngleDimension.hxx>
62 #include <AIS_LengthDimension.hxx>
63 #include <Geom_Axis2Placement.hxx>
64 #include <Geom_Plane.hxx>
65 #include <SelectMgr_Selection.hxx>
66 #include <gce_MakePln.hxx>
67 #include <Prs3d_LineAspect.hxx>
68 #include <Prs3d_DimensionAspect.hxx>
69 #include <Prs3d_TextAspect.hxx>
70 #include <Prs3d_Presentation.hxx>
71 #include <Prs3d_Text.hxx>
72 #include <Graphic3d_VerticalTextAlignment.hxx>
73 #include <Graphic3d_HorizontalTextAlignment.hxx>
74 #include <Graphic3d_AspectText3d.hxx>
75 #include <Font_FontAspect.hxx>
77 // This include must be *AFTER* SOCC_ViewModel.h because
78 // of the constant ROTATE which is a #define in
79 // GEOMImpl_Types.hxx and an enum in SOCC_ViewModel.h
80 #include <GEOMImpl_Types.hxx>
84 // Avoid duplication of angle coordinates in cylindrical mode
85 // Check spherical mode in absolute
97 Locker(bool& l) : myLock(l) { myLock = true; }
98 ~Locker() { myLock = false; }
103 DEFINE_STANDARD_HANDLE(AIS_Text, AIS_InteractiveObject)
105 class AIS_Text:public AIS_InteractiveObject
108 OCCT_DEFINE_STANDARD_RTTIEXT(AIS_Text,AIS_InteractiveObject)
114 const TCollection_ExtendedString& , const gp_Pnt& ,
115 Quantity_Color color,
116 Standard_Integer aHJust,
117 Standard_Integer aVJust ,
118 Standard_Real Angle ,
119 Standard_Boolean Zoom ,
120 Standard_Real Height,
121 Font_FontAspect FontAspect,
122 Standard_CString Font
127 void Compute ( const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
128 const Handle(Prs3d_Presentation)& aPresentation,
129 const Standard_Integer aMode);
131 void ComputeSelection ( const Handle(SelectMgr_Selection)& aSelection,
132 const Standard_Integer aMode){} ;
135 TCollection_ExtendedString aText;
140 Standard_Real aAngle;
141 Standard_Real aHeight;
142 Standard_Boolean aZoomable;
143 Quantity_Color aColor;
144 Standard_CString aFont;
145 Font_FontAspect aFontAspect;
146 Graphic3d_HorizontalTextAlignment aHJustification;
147 Graphic3d_VerticalTextAlignment aVJustification;
150 OCCT_IMPLEMENT_STANDARD_RTTIEXT(AIS_Text, AIS_InteractiveObject)
152 AIS_Text::AIS_Text( const TCollection_ExtendedString& text, const gp_Pnt& position,
153 Quantity_Color color = Quantity_NOC_YELLOW,
154 Standard_Integer aHJust = Graphic3d_HTA_LEFT,
155 Standard_Integer aVJust = Graphic3d_VTA_BOTTOM,
156 Standard_Real angle = 0.0 ,
157 Standard_Boolean zoomable = Standard_False,
158 Standard_Real height = 16.,
159 Font_FontAspect fontAspect = Font_FA_Regular,
160 Standard_CString font = "Courier")
163 aPosition = position;
164 aHJustification = Graphic3d_HorizontalTextAlignment(aHJust);
165 aVJustification = Graphic3d_VerticalTextAlignment(aVJust);
167 aZoomable = zoomable;
170 aFontAspect = fontAspect;
174 void AIS_Text::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
175 const Handle(Prs3d_Presentation)& aPresentation,
176 const Standard_Integer aMode)
179 aPresentation->Clear();
181 Handle(Prs3d_TextAspect) asp = myDrawer->TextAspect();
184 asp->SetColor(aColor);
185 asp->SetHeight(aHeight); // I am changing the myHeight value
187 asp->SetHorizontalJustification(aHJustification);
188 asp->SetVerticalJustification(aVJustification);
189 asp->Aspect()->SetTextZoomable(aZoomable);
190 asp->Aspect()->SetTextAngle(aAngle);
191 asp->Aspect()->SetTextFontAspect(aFontAspect);
192 Prs3d_Text::Draw(aPresentation, asp, aText, aPosition);
195 bool isSame (double d1, double d2)
197 return Abs(d1 - d2) <= Precision::Confusion();
200 //=================================================================================
201 // class : EntityGUI_3DSketcherDlg()
202 // purpose : Constructs a EntityGUI_3DSketcherDlg which is a child of 'parent', with the
203 // name 'name' and widget flags set to 'f'.
204 // The dialog will by default be modeless, unless you set 'modal' to
205 // TRUE to construct a modal dialog.
206 //=================================================================================
207 EntityGUI_3DSketcherDlg::EntityGUI_3DSketcherDlg (GeometryGUI* theGeometryGUI, QWidget* parent,
208 bool modal, Qt::WindowFlags fl,
209 const double lineWidth)
210 : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl),
213 myLineWidth(lineWidth),
214 myGeometryGUI(theGeometryGUI),
215 myLengthIORedoList(),
218 QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
219 QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_UNDO")));
220 QPixmap image2(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_REDO")));
221 QPixmap image3(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICO_3DSKETCH")));
223 setWindowTitle(tr("GEOM_3DSKETCHER_TITLE"));
225 /***************************************************************/
227 mainFrame()->GroupConstructors->setTitle(tr("GEOM_3DSKETCHER"));
228 mainFrame()->RadioButton1->setIcon(image3);;
229 mainFrame()->RadioButton2->close();
230 mainFrame()->RadioButton3->close();
232 GroupType = new EntityGUI_Type(centralWidget());
233 GroupType->GroupType2->setTitle(tr("GEOM_COORDINATES_TYPE"));
234 GroupType->GroupType1->setTitle(tr("GEOM_MODE"));
235 GroupType->RadioButton1->setText(tr("GEOM_SKETCHER_ABS"));
236 GroupType->RadioButton2->setText(tr("GEOM_SKETCHER_REL"));
237 GroupType->RadioButton3->setText(tr("(X,Y,Z)"));
238 GroupType->RadioButton4->setText(tr("GEOM_ANGLES"));
240 myTypeGroup1 = new QButtonGroup(this);
241 myTypeGroup1->setExclusive(true);
242 myTypeGroup1->addButton(GroupType->RadioButton1, 0);
243 myTypeGroup1->addButton(GroupType->RadioButton2, 1);
245 myTypeGroup2 = new QButtonGroup(this);
246 myTypeGroup2->setExclusive(true);
247 myTypeGroup2->addButton(GroupType->RadioButton3, 0);
248 myTypeGroup2->addButton(GroupType->RadioButton4, 1);
250 Group3Spin = new EntityGUI_3Spin(centralWidget());
251 Group3Spin->GroupBox1->setTitle(tr("GEOM_SKETCHER_VALUES"));
252 Group3Spin->buttonApply->setText(tr("GEOM_SKETCHER_APPLY"));
253 Group3Spin->buttonUndo->setIcon(image1);
254 Group3Spin->buttonRedo->setIcon(image2);
255 Group3Spin->TextLabel1->setText(tr("GEOM_SKETCHER_X2"));
256 Group3Spin->TextLabel2->setText(tr("GEOM_SKETCHER_Y2"));
257 Group3Spin->TextLabel3->setText(tr("GEOM_SKETCHER_Z2"));
259 GroupAngles = new EntityGUI_Angles(centralWidget());
260 GroupAngles->buttonApply->setText(tr("GEOM_SKETCHER_APPLY"));
261 GroupAngles->buttonUndo->setIcon(image1);
262 GroupAngles->buttonRedo->setIcon(image2);
263 GroupAngles->TextLabel1->setText(tr("GEOM_LENGTH"));
264 GroupAngles->TextLabel2->setText(tr("GEOM_ANGLE"));
265 GroupAngles->checkBox ->setText(tr("GEOM_ANGLE_2"));
266 GroupAngles->checkBox_2->setText(tr("GEOM_HEIGHT"));
268 GroupControls = new EntityGUI_Controls(centralWidget());
269 GroupControls->GroupBox1->setTitle(tr("GEOM_CONTROLS"));
270 GroupControls->CheckBox1->setText(tr("GEOM_SHOW_LENGTH"));
271 GroupControls->CheckBox2->setText(tr("GEOM_SHOW_ANGLE"));
272 GroupControls->CheckBox3->setText(tr("GEOM_SHOW_POINTS_COORD"));
273 GroupControls->lineEdit_1->setReadOnly(true);
274 GroupControls->lineEdit_2->setReadOnly(true);
275 GroupControls->lineEdit_3->setReadOnly(true);
276 GroupControls->lineEdit_4->setReadOnly(true);
277 GroupControls->lineEdit_5->setReadOnly(true);
278 GroupControls->lineEdit_6->setReadOnly(true);
279 GroupControls->label_1->setText(tr("X:"));
280 GroupControls->label_2->setText(tr("Y:"));
281 GroupControls->label_3->setText(tr("Z:"));
282 GroupControls->label_4->setText(tr("X:"));
283 GroupControls->label_5->setText(tr("Y:"));
284 GroupControls->label_6->setText(tr("Z:"));
285 GroupControls->label_7->setText(tr("GEOM_START"));
286 GroupControls->label_8->setText(tr("GEOM_END"));
288 buttonOk()->setText(tr("GEOM_BUT_END_SKETCH"));
289 buttonApply()->setText(tr("GEOM_BUT_CLOSE_SKETCH"));
291 QVBoxLayout* layout = new QVBoxLayout(centralWidget());
292 layout->setMargin(0); layout->setSpacing(6);
293 layout->addWidget(GroupType);
294 layout->addWidget(Group3Spin);
295 layout->addWidget(GroupAngles);
296 layout->addWidget(GroupControls);
298 setHelpFileName("create_3dsketcher_page.html");
304 //=================================================================================
305 // function : ~EntityGUI_3DSketcherDlg()
306 // purpose : Destroys the object and frees any allocated resources
307 //=================================================================================
308 EntityGUI_3DSketcherDlg::~EntityGUI_3DSketcherDlg()
310 myGeomGUI->SetActiveDialogBox(0);
313 //=================================================================================
316 //=================================================================================
317 void EntityGUI_3DSketcherDlg::Init()
321 myPrsType = prsType();
323 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
324 myAnglePrs = dynamic_cast<SOCC_Prs*>(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
325 myLengthPrs = dynamic_cast<SOCC_Prs*>(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
326 myTextPrs = dynamic_cast<SOCC_Prs*>(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
328 localSelection(TopAbs_VERTEX);
330 /* Get setting of step value from file configuration */
331 double step = SUIT_Session::session()->resourceMgr()->doubleValue("Geometry", "SettingsGeomStep", 100.0);
333 /* min, max, step and decimals for spin boxes */
334 initSpinBox(Group3Spin->SpinBox_DX, COORD_MIN, COORD_MAX, step, "length_precision");
335 initSpinBox(Group3Spin->SpinBox_DY, COORD_MIN, COORD_MAX, step, "length_precision");
336 initSpinBox(Group3Spin->SpinBox_DZ, COORD_MIN, COORD_MAX, step, "length_precision");
338 initSpinBox(GroupAngles->SpinBox_DA , -360.0, 360.0, step, "angular_precision");
339 initSpinBox(GroupAngles->SpinBox_DA2, -90.0, 90.0, step, "angular_precision");
340 initSpinBox(GroupAngles->SpinBox_DL , COORD_MIN, COORD_MAX, step, "length_precision");
341 initSpinBox(GroupAngles->SpinBox_DH , COORD_MIN, COORD_MAX, step, "length_precision");
343 Group3Spin->SpinBox_DX->setValue(0.0);
344 Group3Spin->SpinBox_DY->setValue(0.0);
345 Group3Spin->SpinBox_DZ->setValue(0.0);
347 GroupAngles->SpinBox_DA->setValue(0.0);
348 GroupAngles->SpinBox_DA2->setValue(0.0);
349 GroupAngles->SpinBox_DL->setValue(0.0);
350 GroupAngles->SpinBox_DH->setValue(0.0);
352 GroupAngles->radioButton_1->setChecked(true);
353 GroupAngles->checkBox->setChecked(false);
354 GroupAngles->checkBox_2->setChecked(false);
355 GroupAngles->SpinBox_DA2->setEnabled(false);
356 GroupAngles->SpinBox_DH->setEnabled(false);
358 GroupControls->CheckBox1->setChecked(true);
359 GroupControls->CheckBox2->setChecked(true);
360 GroupControls->CheckBox3->setChecked(true);
362 isLengthVisible = true;
363 isAngleVisible = true;
367 /* signals and slots connections */
368 connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
369 connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
371 connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
373 connect(Group3Spin->buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnAddPoint()));
374 connect(Group3Spin->buttonUndo, SIGNAL(clicked()), this, SLOT(ClickOnUndo()));
375 connect(Group3Spin->buttonRedo, SIGNAL(clicked()), this, SLOT(ClickOnRedo())) ;
377 connect(GroupAngles->buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnAddPoint()));
378 connect(GroupAngles->buttonUndo, SIGNAL(clicked()), this, SLOT(ClickOnUndo()));
379 connect(GroupAngles->buttonRedo, SIGNAL(clicked()), this, SLOT(ClickOnRedo())) ;
381 connect(myTypeGroup1, SIGNAL(buttonClicked(int)), this, SLOT(TypeClicked(int)));
382 connect(myTypeGroup2, SIGNAL(buttonClicked(int)), this, SLOT(TypeClicked(int)));
384 connect(Group3Spin->SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
385 connect(Group3Spin->SpinBox_DY, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
386 connect(Group3Spin->SpinBox_DZ, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
388 connect(GroupAngles->SpinBox_DA, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
389 connect(GroupAngles->SpinBox_DA2, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
390 connect(GroupAngles->SpinBox_DL, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
391 connect(GroupAngles->SpinBox_DH, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
393 connect(GroupAngles->radioButton_1, SIGNAL(clicked (bool)), this, SLOT(ButtonClicked(bool))) ;
394 connect(GroupAngles->radioButton_2, SIGNAL(clicked (bool)), this, SLOT(ButtonClicked(bool))) ;
395 connect(GroupAngles->radioButton_3, SIGNAL(clicked (bool)), this, SLOT(ButtonClicked(bool))) ;
397 connect(GroupAngles->checkBox, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
398 connect(GroupAngles->checkBox_2, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
399 connect(GroupControls->CheckBox1, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
400 connect(GroupControls->CheckBox2, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
401 connect(GroupControls->CheckBox3, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
403 connect(myGeomGUI, SIGNAL(SignalDefaultStepValueChanged(double)), this, SLOT(SetDoubleSpinBoxStep(double)));
405 connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
406 connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
408 initName(tr("GEOM_3DSKETCHER"));
410 GroupControls->CheckBox3->click();
412 UpdateButtonsState();
417 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
420 //=================================================================================
421 // function : TypeClicked()
422 // purpose : Radio button management
423 //=================================================================================
424 void EntityGUI_3DSketcherDlg::TypeClicked (int id)
426 QButtonGroup* send = (QButtonGroup*) sender();
428 int coordType = myCoordType;
431 if (send == myTypeGroup1)
433 if(id == myMode) return;
436 else if (send == myTypeGroup2)
438 if (id == myCoordType) return;
445 bool blocked = Group3Spin->SpinBox_DX->signalsBlocked();
446 Group3Spin->SpinBox_DX->blockSignals(true);
447 Group3Spin->SpinBox_DY->blockSignals(true);
448 Group3Spin->SpinBox_DZ->blockSignals(true);
450 // Get setting of step value from file configuration
451 XYZ xyz = getLastPoint();
453 Group3Spin->SpinBox_DX->text().toDouble(&okx);
454 Group3Spin->SpinBox_DY->text().toDouble(&oky);
455 Group3Spin->SpinBox_DZ->text().toDouble(&okz);
457 if (coordType == 0) // Cartesian coordinates
459 if (mode == 0) { // XYZ
460 Group3Spin->TextLabel1->setText(tr("GEOM_SKETCHER_X2"));
461 Group3Spin->TextLabel2->setText(tr("GEOM_SKETCHER_Y2"));
462 Group3Spin->TextLabel3->setText(tr("GEOM_SKETCHER_Z2"));
463 if (myCoordType == 0 && myMode == 1)
465 if (okx) Group3Spin->SpinBox_DX->setValue(xyz.x + Group3Spin->SpinBox_DX->value());
466 if (oky) Group3Spin->SpinBox_DY->setValue(xyz.y + Group3Spin->SpinBox_DY->value());
467 if (okz) Group3Spin->SpinBox_DZ->setValue(xyz.z + Group3Spin->SpinBox_DZ->value());
469 Group3Spin->buttonApply->setFocus();
471 else if (mode == 1) { // DXDYDZ
472 Group3Spin->TextLabel1->setText(tr("GEOM_SKETCHER_DX2"));
473 Group3Spin->TextLabel2->setText(tr("GEOM_SKETCHER_DY2"));
474 Group3Spin->TextLabel3->setText(tr("GEOM_SKETCHER_DZ2"));
475 if (myCoordType == 0 && myMode == 0)
477 if (okx) Group3Spin->SpinBox_DX->setValue(Group3Spin->SpinBox_DX->value() - xyz.x);
478 if (oky) Group3Spin->SpinBox_DY->setValue(Group3Spin->SpinBox_DY->value() - xyz.y);
479 if (okz) Group3Spin->SpinBox_DZ->setValue(Group3Spin->SpinBox_DZ->value() - xyz.z);
481 Group3Spin->buttonApply->setFocus();
484 else if (coordType == 1) // Angles and Length
488 GroupAngles->buttonApply->setFocus();
491 Group3Spin->SpinBox_DX->blockSignals(blocked);
492 Group3Spin->SpinBox_DY->blockSignals(blocked);
493 Group3Spin->SpinBox_DZ->blockSignals(blocked);
496 myCoordType = coordType;
499 resize(minimumSizeHint());
501 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
504 //=================================================================================
505 // function : ClickOnAddPoint()
506 // purpose : called when the point coordinates is Applyed
507 //=================================================================================
508 void EntityGUI_3DSketcherDlg::ClickOnAddPoint()
516 myPrsType = prsType();
519 displayDimensions( /*store = */true);
521 myPointsList.append(getCurrentPoint());
523 myLengthIORedoList.Clear();
524 myAngleIORedoList.Clear();
525 myTextIORedoList.Clear();
527 if (myCoordType == 0 && myMode == 1) // RELATIVE CARTESIAN COORDINATES
529 Group3Spin->SpinBox_DX->setValue(0.0);
530 Group3Spin->SpinBox_DY->setValue(0.0);
531 Group3Spin->SpinBox_DZ->setValue(0.0);
533 else if (myCoordType == 1 && myMode == 1) // RELATIVE ANGULAR COORDINATES
535 GroupAngles->SpinBox_DA->setValue(0.0);
536 GroupAngles->SpinBox_DL->setValue(0.0);
537 GroupAngles->SpinBox_DA2->setValue(0.0);
540 UpdatePointCoordinates();
542 UpdateButtonsState();
543 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
546 //=================================================================================
547 // function : UpdateButtonsState()
549 //=================================================================================
550 void EntityGUI_3DSketcherDlg::UpdateButtonsState()
552 if (myPointsList.count() == 0)
554 GroupType->RadioButton1->click();
555 GroupType->RadioButton3->click();
557 GroupType->RadioButton2->setEnabled(myPointsList.count() > 0);
558 // GroupType->RadioButton3->setEnabled(myPointsList.count() > 0);
559 // GroupType->RadioButton4->setEnabled(myPointsList.count() > 0);
560 Group3Spin->buttonUndo->setEnabled(myPointsList.count() > 0);
561 Group3Spin->buttonRedo->setEnabled(myRedoList.count() > 0);
562 GroupAngles->buttonUndo->setEnabled(myPointsList.count() > 0);
563 GroupAngles->buttonRedo->setEnabled(myRedoList.count() > 0);
566 //=================================================================================
567 // function : UpdatePointCoordinates()
568 // purpose :Update point coordinates in the control groupbox
569 //=================================================================================
570 void EntityGUI_3DSketcherDlg::UpdatePointCoordinates()
572 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
573 int aPrecision = resMgr->integerValue("Geometry", "length_precision", 6);
575 if (myPointsList.count() == 0)
577 GroupControls->lineEdit_1->setText("");
578 GroupControls->lineEdit_2->setText("");
579 GroupControls->lineEdit_3->setText("");
581 GroupControls->lineEdit_4->setText("");
582 GroupControls->lineEdit_5->setText("");
583 GroupControls->lineEdit_6->setText("");
585 else if (myPointsList.count() == 1)
587 GroupControls->lineEdit_1->setText(DlgRef::PrintDoubleValue(getLastPoint().x, aPrecision));
588 GroupControls->lineEdit_2->setText(DlgRef::PrintDoubleValue(getLastPoint().y, aPrecision));
589 GroupControls->lineEdit_3->setText(DlgRef::PrintDoubleValue(getLastPoint().z, aPrecision));
591 GroupControls->lineEdit_4->setText("");
592 GroupControls->lineEdit_5->setText("");
593 GroupControls->lineEdit_6->setText("");
597 GroupControls->lineEdit_4->setText(DlgRef::PrintDoubleValue(getLastPoint().x, aPrecision));
598 GroupControls->lineEdit_5->setText(DlgRef::PrintDoubleValue(getLastPoint().y, aPrecision));
599 GroupControls->lineEdit_6->setText(DlgRef::PrintDoubleValue(getLastPoint().z, aPrecision));
604 //=================================================================================
605 // function : ClickOnUndo()
607 //=================================================================================
608 void EntityGUI_3DSketcherDlg::ClickOnUndo()
611 if (myPointsList.count() > 0) {
613 myRedoList.append(myPointsList.last());
615 // Erase dimensions presentations
616 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
617 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
618 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
619 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myTextPrs, true);
621 removeLastIOFromPrs();
623 // Display modified presentation
625 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
627 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
628 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myTextPrs);
630 // Remove last point from list
631 myWorkPoint = myPointsList.last();
632 myPointsList.removeLast();
633 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
634 UpdateButtonsState();
636 // Update of point coordinates in the control groupbox
637 UpdatePointCoordinates();
641 myIsUndoRedo = false;
644 //=================================================================================
645 // function : ClickOnRedo()
647 //=================================================================================
648 void EntityGUI_3DSketcherDlg::ClickOnRedo()
651 if (myRedoList.count() > 0) {
653 myPointsList.append(myRedoList.last());
655 // Erase dimensions presentations
656 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
657 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
658 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
659 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myTextPrs, true);
661 restoreLastIOToPrs();
663 // Display modified presentation
665 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
667 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
668 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myTextPrs);
670 // Remove last point from redo list
671 myWorkPoint = myRedoList.last();
672 myRedoList.removeLast();
673 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
674 UpdateButtonsState();
676 // Update of point coordinates in the control groupbox
677 UpdatePointCoordinates();
681 myIsUndoRedo = false;
684 //=================================================================================
685 // function : removeLastIO()
687 //=================================================================================
688 void EntityGUI_3DSketcherDlg::removeLastIOFromPrs ()
690 AIS_ListOfInteractive anIOList;
691 XYZ Last = getLastPoint();
693 for (int l = 0; l<Last.L; l++)
695 myLengthPrs->GetObjects(anIOList);
696 myLengthIORedoList.Prepend(anIOList.First()); // Store last prepended Length IO in redo list
697 myLengthPrs->RemoveFirst(); // Remove it from myLengthPrs
699 for (int a = 0; a<Last.A; a++)
701 myAnglePrs->GetObjects(anIOList);
702 myAngleIORedoList.Prepend(anIOList.First()); // Store last prepended Angle IO in redo list
703 myAnglePrs->RemoveFirst(); // Remove it from myAnglePrs
705 for (int t = 0; t<Last.T; t++)
707 myTextPrs->GetObjects(anIOList);
708 myTextIORedoList.Prepend(anIOList.First()); // Store last prepended Text IO in redo list
709 myTextPrs->RemoveFirst(); // Remove it from myTextPrs
713 //=================================================================================
714 // function : restoreLastIO()
716 //=================================================================================
717 void EntityGUI_3DSketcherDlg::restoreLastIOToPrs ()
719 XYZ LastDeleted = myRedoList.last();
721 for (int l = 0; l<LastDeleted.L; l++)
723 myLengthPrs->PrependObject(myLengthIORedoList.First()); // Restore last removed IO
724 myLengthIORedoList.RemoveFirst(); // Remove it from redo list
726 for (int a = 0; a<LastDeleted.A; a++)
728 myAnglePrs->PrependObject(myAngleIORedoList.First()); // Restore last removed IO
729 myAngleIORedoList.RemoveFirst(); // Remove it from redo list
731 for (int t = 0; t<LastDeleted.T; t++)
733 myTextPrs->PrependObject(myTextIORedoList.First()); // Restore last removed IO
734 myTextIORedoList.RemoveFirst(); // Remove it from redo list
738 //=================================================================================
739 // function : SelectionIntoArgument()
740 // purpose : Called when selection as changed
741 //=================================================================================
742 void EntityGUI_3DSketcherDlg::SelectionIntoArgument()
744 LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
745 SALOME_ListIO aSelList;
746 aSelMgr->selectedObjects(aSelList);
748 int nbSel = aSelList.Extent();
750 GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject(aSelList.First());
751 if (!CORBA::is_nil(aSelectedObject)) {
753 if (GEOMBase::GetShape(aSelectedObject, aShape, TopAbs_SHAPE)) {
754 // Explore the shape if its a local selection
755 TColStd_IndexedMapOfInteger aMap;
756 aSelMgr->GetIndexes(aSelList.First(), aMap);
757 if (aMap.Extent() == 1) {
758 int anIndex = aMap(1);
759 GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations(getStudyId());
760 aSelectedObject = aShapesOp->GetSubShape(aSelectedObject, anIndex);
764 if (aShape.ShapeType() != TopAbs_VERTEX)
765 isOk = GEOMBase::GetShape(aSelectedObject, aShape, TopAbs_VERTEX);
768 if (GEOMBase::VertexToPoint(aShape, aPnt)) {
769 // set coordinates to the Spin Boxes
774 bool blocked = Group3Spin->SpinBox_DX->signalsBlocked();
775 Group3Spin->SpinBox_DX->blockSignals(true);
776 Group3Spin->SpinBox_DY->blockSignals(true);
777 Group3Spin->SpinBox_DZ->blockSignals(true);
778 if (GroupType->RadioButton1->isChecked()) {
779 Group3Spin->SpinBox_DX->setValue(aX);
780 Group3Spin->SpinBox_DY->setValue(aY);
781 Group3Spin->SpinBox_DZ->setValue(aZ);
783 else if (GroupType->RadioButton2->isChecked()) {
784 XYZ xyz = getLastPoint();
785 Group3Spin->SpinBox_DX->setValue(aX - xyz.x);
786 Group3Spin->SpinBox_DY->setValue(aY - xyz.y);
787 Group3Spin->SpinBox_DZ->setValue(aZ - xyz.z);
789 Group3Spin->SpinBox_DX->blockSignals(blocked);
790 Group3Spin->SpinBox_DY->blockSignals(blocked);
791 Group3Spin->SpinBox_DZ->blockSignals(blocked);
796 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
799 //=================================================================================
800 // function : DeactivateActiveDialog()
802 //=================================================================================
803 void EntityGUI_3DSketcherDlg::DeactivateActiveDialog()
807 disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
808 myGeomGUI->SetActiveDialogBox(0);
811 //=================================================================================
812 // function : ActivateThisDialog()
814 //=================================================================================
815 void EntityGUI_3DSketcherDlg::ActivateThisDialog()
817 myGeomGUI->EmitSignalDeactivateDialog();
819 myGeomGUI->SetActiveDialogBox(this);
821 connect(myGeomGUI->getApp()->selectionMgr(),
822 SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
824 localSelection(TopAbs_VERTEX);
825 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
828 //=================================================================================
829 // function : ValueChangedInSpinBox()
831 //=================================================================================
832 void EntityGUI_3DSketcherDlg::ValueChangedInSpinBox (double newValue)
834 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
837 //=================================================================================
838 // function : BoxChecked()
839 // purpose : ChecBoxes management
840 //=================================================================================
841 void EntityGUI_3DSketcherDlg::BoxChecked (bool checked)
843 QCheckBox* send = (QCheckBox*) sender();
844 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
846 if (send == GroupAngles->checkBox)
848 GroupAngles->SpinBox_DA2->setEnabled(checked);
851 GroupAngles->SpinBox_DH->setEnabled(false);
852 GroupAngles->checkBox_2->setChecked(false);
855 else if (send == GroupAngles->checkBox_2)
857 GroupAngles->SpinBox_DH->setEnabled(checked);
860 GroupAngles->SpinBox_DA2->setEnabled(false);
861 GroupAngles->checkBox->setChecked(false);
865 else if (send == GroupControls->CheckBox1)
867 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
869 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
870 isLengthVisible=true;
873 isLengthVisible=false;
875 else if (send == GroupControls->CheckBox2)
877 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
880 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
884 isAngleVisible=false;
886 else if (send == GroupControls->CheckBox3)
888 GroupControls->lineEdit_1->setVisible(checked);
889 GroupControls->lineEdit_2->setVisible(checked);
890 GroupControls->lineEdit_3->setVisible(checked);
891 GroupControls->lineEdit_4->setVisible(checked);
892 GroupControls->lineEdit_5->setVisible(checked);
893 GroupControls->lineEdit_6->setVisible(checked);
895 GroupControls->label_1->setVisible(checked);
896 GroupControls->label_2->setVisible(checked);
897 GroupControls->label_3->setVisible(checked);
898 GroupControls->label_4->setVisible(checked);
899 GroupControls->label_5->setVisible(checked);
900 GroupControls->label_6->setVisible(checked);
901 GroupControls->label_7->setVisible(checked);
902 GroupControls->label_8->setVisible(checked);
904 GroupControls->updateGeometry();
905 GroupControls->resize(minimumSizeHint());
909 resize(minimumSizeHint());
911 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
914 //=================================================================================
915 // function : ButtonClicked()
917 //=================================================================================
918 void EntityGUI_3DSketcherDlg::ButtonClicked (bool checked)
920 if (GroupAngles->radioButton_1->isChecked())
922 else if (GroupAngles->radioButton_2->isChecked())
927 GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
930 //=================================================================================
931 // function : enterEvent()
933 //=================================================================================
934 void EntityGUI_3DSketcherDlg::enterEvent (QEvent*)
936 if (!mainFrame()->GroupConstructors->isEnabled())
937 ActivateThisDialog();
940 //=================================================================================
941 // function : createOperation
943 //=================================================================================
944 GEOM::GEOM_IOperations_ptr EntityGUI_3DSketcherDlg::createOperation()
946 return getGeomEngine()->GetICurvesOperations(getStudyId());
949 //=================================================================================
950 // function : isValid
952 //=================================================================================
953 bool EntityGUI_3DSketcherDlg::isValid (QString& msg)
956 ok = Group3Spin->SpinBox_DX->isValid(msg, !IsPreview()) && ok;
957 ok = Group3Spin->SpinBox_DY->isValid(msg, !IsPreview()) && ok;
958 ok = Group3Spin->SpinBox_DZ->isValid(msg, !IsPreview()) && ok;
962 //=================================================================================
963 // function : execute
965 //=================================================================================
966 bool EntityGUI_3DSketcherDlg::execute (ObjectList& objects)
968 //GEOM::ListOfDouble_var aCoordsArray = new GEOM::ListOfDouble;
969 //if (!myOK || myPointsList.size() == 0)
970 // aCoordsArray->length((myPointsList.size()+1)*3);
972 // aCoordsArray->length(myPointsList.size()*3);
974 QStringList aCommands;
975 aCommands << "3DSketcher";
976 QStringList aParameters;
979 QList<XYZ>::const_iterator it;
980 for (it = myPointsList.begin(); it != myPointsList.end(); ++it) {
981 //aCoordsArray[i++] = (*it).x;
982 //aCoordsArray[i++] = (*it).y;
983 //aCoordsArray[i++] = (*it).z;
984 aCommands << (*it).command;
985 aParameters << (*it).params;
988 if (!myOK || myPointsList.size() == 0) {
989 XYZ xyz = getCurrentPoint();
990 //aCoordsArray[i++] = xyz.x;
991 //aCoordsArray[i++] = xyz.y;
992 //aCoordsArray[i++] = xyz.z;
993 aCommands << xyz.command;
994 aParameters << xyz.params;
997 // MESSAGE("aCommands.last() = "<< aCommands.last().toStdString());
998 GEOM::GEOM_ICurvesOperations_var anOper = GEOM::GEOM_ICurvesOperations::_narrow(getOperation());
999 //GEOM::GEOM_Object_var anObj = anOper->Make3DSketcher(aCoordsArray);
1000 GEOM::GEOM_Object_var anObj = anOper->Make3DSketcherCommand(aCommands.join(":").toLatin1().constData());
1002 if (!anObj->_is_nil()) {
1003 if (!IsPreview()) anObj->SetParameters(aParameters.join(":").toLatin1().constData());
1004 objects.push_back(anObj._retn());
1010 //=================================================================================
1011 // function : SetDoubleSpinBoxStep()
1012 // purpose : Double spin box management
1013 //=================================================================================
1014 void EntityGUI_3DSketcherDlg::SetDoubleSpinBoxStep (double step)
1016 Group3Spin->SpinBox_DX->setSingleStep(step);
1017 Group3Spin->SpinBox_DY->setSingleStep(step);
1018 Group3Spin->SpinBox_DZ->setSingleStep(step);
1019 GroupAngles->SpinBox_DA ->setSingleStep(step);
1020 GroupAngles->SpinBox_DA2->setSingleStep(step);
1021 GroupAngles->SpinBox_DL->setSingleStep(step);
1022 GroupAngles->SpinBox_DH->setSingleStep(step);
1025 //=================================================================================
1026 // function : ClickOnOk()
1028 //=================================================================================
1029 void EntityGUI_3DSketcherDlg::ClickOnOk()
1039 //=================================================================================
1040 // function : ClickOnApply()
1042 //=================================================================================
1043 bool EntityGUI_3DSketcherDlg::ClickOnApply()
1046 if (!isValid(msg)) {
1051 if (myPointsList.count() > 0)
1052 myPointsList.append(myPointsList[0]);
1063 //=================================================================================
1064 // function : getLastPoint()
1065 // purpose : return last points from list
1066 //=================================================================================
1067 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getLastPoint() const
1069 return myPointsList.count() > 0 ? myPointsList.last() : XYZ();
1072 //=================================================================================
1073 // function : getPenultimatePoint()
1074 // purpose : return penultimate point from list
1075 //=================================================================================
1076 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getPenultimatePoint() const
1078 double size = myPointsList.count();
1079 return size > 1 ? myPointsList.at(size - 2) : XYZ();
1082 //=================================================================================
1083 // function : getCurrentPoint()
1084 // purpose : returns current point
1085 //=================================================================================
1086 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getCurrentPoint() const
1090 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1091 int aPrecision = resMgr->integerValue("Geometry", "length_precision", 7);
1093 bool spherical = GroupAngles->checkBox->isChecked();
1094 bool cylindrical = GroupAngles->checkBox_2->isChecked();
1096 if (myCoordType == 1)
1098 if (GroupAngles->radioButton_1->isChecked())
1099 xyz.command = "OXY";
1100 else if (GroupAngles->radioButton_2->isChecked())
1101 xyz.command = "OYZ";
1103 xyz.command = "OXZ";
1105 if (cylindrical) // Cylindrical coordinates (radius, angle, height)
1108 xyz.command += "S"; // Spherical coordinates (radius, angle1, angle2) --> polar if angle2 = 0
1110 if (myMode == 0) // Absolute coordinates
1111 xyz.command += "A ";
1112 else if (myMode == 1) // Relative coordinates
1113 xyz.command += "R ";
1116 double anAngle = GroupAngles->SpinBox_DA->value();
1117 double aLength = GroupAngles->SpinBox_DL->value();
1119 double anAngle2 = 0.0;
1121 if (spherical) { // Spherical coordinates (radius, angle1, angle2)
1122 anAngle2 = GroupAngles->SpinBox_DA2->value();
1123 da2 = GroupAngles->SpinBox_DA2->text();
1126 double aHeight = 0.0;
1129 aHeight = GroupAngles->SpinBox_DH->value();
1130 dh = GroupAngles->SpinBox_DH->text();
1134 QString::number(anAngle, 'g', aPrecision) + " ";
1136 GroupAngles->SpinBox_DA->text() + ":";
1141 QString::number(aHeight, 'g', aPrecision) + " ";
1145 else // Spherical or polar coordinates
1148 QString::number(anAngle2, 'g', aPrecision) + " ";
1154 QString::number(aLength, 'g', aPrecision);
1156 GroupAngles->SpinBox_DL->text();
1159 // Calculate point coordinates for preview
1160 anAngle = anAngle * M_PI/180.0;
1161 anAngle2 = anAngle2 * M_PI/180.0;
1162 double aProjectedLength = aLength * cos(anAngle2);
1164 XYZ xyzP = getLastPoint();
1166 xyzP.x=xyzP.y=xyzP.z=0.0;
1167 if (GroupAngles->radioButton_1->isChecked()) // OXY
1169 xyz.x = xyzP.x + aProjectedLength * cos(anAngle);
1170 xyz.y = xyzP.y + aProjectedLength * sin(anAngle);
1172 xyz.z = xyzP.z + aHeight;
1174 xyz.z = xyzP.z + aLength * sin(anAngle2);
1176 else if (GroupAngles->radioButton_2->isChecked()) // OYZ
1178 xyz.y = xyzP.y + aProjectedLength * cos(anAngle);
1179 xyz.z = xyzP.z + aProjectedLength * sin(anAngle);
1181 xyz.x = xyzP.x + aHeight;
1183 xyz.x = xyzP.x + aLength * sin(anAngle2);
1187 xyz.z = xyzP.z + aProjectedLength * sin(anAngle);
1188 xyz.x = xyzP.x + aProjectedLength * cos(anAngle);
1190 xyz.y = xyzP.y + aHeight;
1192 xyz.y = xyzP.y + aLength * sin(anAngle2);
1195 else if(myCoordType == 0) {
1196 if (myMode == 0) { // XYZ
1197 xyz.x = Group3Spin->SpinBox_DX->value();
1198 xyz.y = Group3Spin->SpinBox_DY->value();
1199 xyz.z = Group3Spin->SpinBox_DZ->value();
1200 xyz.command = "TT ";
1203 xyz = getLastPoint();
1204 xyz.x += Group3Spin->SpinBox_DX->value();
1205 xyz.y += Group3Spin->SpinBox_DY->value();
1206 xyz.z += Group3Spin->SpinBox_DZ->value();
1210 double aX = Group3Spin->SpinBox_DX->value();
1211 double aY = Group3Spin->SpinBox_DY->value();
1212 double aZ = Group3Spin->SpinBox_DZ->value();
1215 QString::number(aX, 'g', aPrecision) + " " +
1216 QString::number(aY, 'g', aPrecision) + " " +
1217 QString::number(aZ, 'g', aPrecision);
1219 Group3Spin->SpinBox_DX->text() + ":" +
1220 Group3Spin->SpinBox_DY->text() + ":" +
1221 Group3Spin->SpinBox_DZ->text();
1223 // Update point presentation type
1224 xyz.A = myPrsType.A; // Number of angle diomensions
1225 xyz.L = myPrsType.L; // Number of length dimensions
1226 xyz.T = myPrsType.T; // Number of text objects
1232 //=================================================================================
1233 // function : getPresentationPlane()
1234 // purpose : returns the suitable plane for right
1235 // relative positioning of dimension presentations
1236 //=================================================================================
1237 gp_Dir EntityGUI_3DSketcherDlg::getPresentationPlane() const
1239 bool withAngle = (myCoordType == 1);
1240 bool twoAngles = GroupAngles->checkBox->isChecked();
1242 XYZ Last = getLastPoint();
1244 if( myIsUndoRedo ) {
1245 Current = myWorkPoint;
1247 Current = getCurrentPoint();
1250 XYZ Penultimate = getPenultimatePoint();
1252 gp_Pnt P1 = gp_Pnt(Last.x,Last.y,Last.z);
1253 if (myMode == 0) // Absolute coordinates
1256 gp_Pnt P2 = gp_Pnt(Current.x,Current.y,Current.z);
1257 gp_Pnt P3 = gp_Pnt(Penultimate.x,Penultimate.y,Penultimate.z);
1262 gp_Dir aNormal; // Normal defining the plane of the presentation
1264 if (withAngle) // If one angle
1266 // Transformation from the current coordinate system
1267 // to the reference coordinate system
1268 gp_Trsf aTransform = toReferenceSystem (P1);
1269 gp_Dir N1 = gp::DZ();
1270 gp_Dir N2 = gp::DY();
1271 N1.Transform(aTransform);
1272 N2.Transform(aTransform);
1274 if (Vec1.CrossMagnitude(N1) > Precision::Confusion())
1276 // The plane is orthogonal to the angle presentation plane
1277 // and contains the current edge
1278 aNormal = N1.Crossed(gp_Dir(Vec1));
1285 gp_Vec V = Vec1.Transformed(aTransform.Inverted());
1286 gp_Vec Vec3(V.X(),V.Y(),0.0);
1288 // Express the coordinates in the refernce coordinate system (OXY)
1289 Vec3.Transform(aTransform);
1290 if(Abs(Vec1.CrossMagnitude(Vec3)) > Precision::Confusion())
1292 // set the normal as the cross product of the current edge with its projection
1293 // it ensures that the dimension changes side when the angle becomes negative
1294 aNormal = gp_Dir(Vec1.Crossed(Vec3));
1300 // Check colinearity
1301 if (Abs(Vec1.CrossMagnitude(Vec2)) < Precision::Confusion())
1303 Vec2 = gp_Vec(gp::DX());
1304 if (Abs(Vec1.CrossMagnitude(Vec2)) < Precision::Confusion())
1306 Vec2 = gp_Vec(gp::DY());
1309 // If no angles, the plane is the one formed by the last edge and the current one
1310 if(Abs(Vec1.CrossMagnitude(Vec2)) > Precision::Confusion()) {
1311 aNormal = gp_Dir(Vec1.Crossed(Vec2));
1317 //================================================================
1318 // Function : displayPreview
1319 // Purpose : Method for displaying preview of resulting shape
1320 // Redefined from GEOMBase_Helper.
1321 //================================================================
1322 void EntityGUI_3DSketcherDlg::displayPreview (GEOM::GEOM_Object_ptr object,
1324 const bool activate,
1326 const double lineWidth,
1327 const int displayMode,
1330 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1332 QColor aColor = resMgr->colorValue("Geometry","line_color",QColor(255,0,0));
1333 Quantity_NameOfColor line_color = SalomeApp_Tools::color(aColor).Name();
1335 // set width of displayed shape
1338 lw = resMgr->integerValue("Geometry", "preview_edge_width", -1);
1340 getDisplayer()->SetWidth(lw);
1342 // Disable activation of selection
1343 getDisplayer()->SetToActivate(activate);
1345 // Make a reference to GEOM_Object
1346 CORBA::String_var objStr = myGeometryGUI->getApp()->orb()->object_to_string(object);
1347 getDisplayer()->SetName(objStr.in());
1349 // Create wire from applied object
1350 TopoDS_Shape anApplyedWire, aLastSegment;
1351 if (!createShapes(object, anApplyedWire, aLastSegment))
1354 // Set color for preview shape
1355 getDisplayer()->SetColor(line_color);
1358 SALOME_Prs* aPrs = getDisplayer()->BuildPrs(anApplyedWire);
1359 if (aPrs != 0 && !aPrs->IsNull())
1360 GEOMBase_Helper::displayPreview(aPrs, append, update);
1362 getDisplayer()->SetColor(Quantity_NOC_VIOLET);
1363 aPrs = getDisplayer()->BuildPrs(aLastSegment);
1365 if (aPrs != 0 && !aPrs->IsNull())
1366 GEOMBase_Helper::displayPreview(aPrs, append, update);
1368 getDisplayer()->SetColor(line_color);
1370 // Display local trihedron if the mode is relative
1372 displayTrihedron(2);
1374 // Display preview of suitable dimension presentations
1375 displayDimensions(false);
1377 getDisplayer()->UnsetName();
1379 // Enable activation of displayed objects
1380 getDisplayer()->SetToActivate(true);
1383 //================================================================
1384 // Function : displayTrihedron()
1385 // Purpose : Method for displaying trihedron
1386 //================================================================
1387 void EntityGUI_3DSketcherDlg::displayTrihedron (int selMode)
1389 // Add trihedron to preview
1390 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1392 SOCC_Viewer* anOCCViewer = dynamic_cast<SOCC_Viewer*>( vw->getViewManager()->getViewModel() );
1396 Handle(AIS_InteractiveContext) anAISContext = anOCCViewer->getAISContext();
1400 gp_Pnt P(getLastPoint().x,getLastPoint().y,getLastPoint().z);
1401 Handle(Geom_Axis2Placement) anAxis = new Geom_Axis2Placement(P,gp::DZ(),gp::DX());
1402 Handle(AIS_Trihedron) anIO = new AIS_Trihedron(anAxis);
1404 SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>( anOCCViewer->CreatePrs(0) );
1407 aSPrs->PrependObject(anIO);
1408 GEOMBase_Helper::displayPreview(aSPrs, true, true);
1410 anAISContext->Activate(anIO, selMode);
1413 //================================================================
1414 // Function : displayDimensions( bool store )
1415 // Purpose : Method for displaying dimensions. If store = true
1416 // the presentation is stored in a list
1417 //================================================================
1418 void EntityGUI_3DSketcherDlg::displayDimensions (bool store)
1420 myPrsType = prsType();
1421 XYZ Last = getLastPoint();
1422 XYZ Current = getCurrentPoint();
1424 gp_Pnt Last_Pnt(Last.x,Last.y,Last.z);
1426 gp_Pnt P0 = Last_Pnt;
1427 gp_Pnt Origin = gp::Origin();
1428 if (myMode == 0) // Absolute coordinates
1431 gp_Pnt Current_Pnt(Current.x,Current.y,Current.z);
1434 // Check if last end current point are coincident
1435 if (Last_Pnt.IsEqual(Current_Pnt, 1e-7))
1438 gp_Dir aNormal = getPresentationPlane();
1440 if (myCoordType == 0)
1442 bool oneDimensionalMove = (isSame(Last_Pnt.X(), Current_Pnt.X()) &&
1443 isSame(Last_Pnt.Y(), Current_Pnt.Y()) ) ||
1444 (isSame(Last_Pnt.Y(), Current_Pnt.Y()) &&
1445 isSame(Last_Pnt.Z(), Current_Pnt.Z()) ) ||
1446 (isSame(Last_Pnt.X(), Current_Pnt.X()) &&
1447 isSame(Last_Pnt.Z(), Current_Pnt.Z()) );
1451 std::string aCoordText = "( " + doubleToString(Current_Pnt.X()) +
1452 ", " + doubleToString(Current_Pnt.Y()) +
1453 ", " + doubleToString(Current_Pnt.Z()) + " )";
1454 displayText(aCoordText, Current_Pnt, store);
1458 if (oneDimensionalMove)
1460 // For better colocation of dimensions if only one coordinate changes (aNormal is a better choice)
1461 displayLength(P0, Current_Pnt, aNormal, store);
1465 displayLength(gp_Pnt(P0.X(),Current.y,P0.Z()), gp_Pnt(Current.x,Current.y,P0.Z()), gp::DZ().Reversed(), store);
1466 displayLength(gp_Pnt(Current.x,P0.Y(),P0.Z()), gp_Pnt(Current.x,Current.y,P0.Z()), gp::DZ(), store);
1467 displayLength(gp_Pnt(Current.x,Current.y,P0.Z()), Current_Pnt, gp::DX(), store);
1471 else if (myCoordType == 1) // ANGLES
1473 bool spherical = GroupAngles->checkBox->isChecked();
1474 bool cylindrical = GroupAngles->checkBox_2->isChecked();
1476 double anAngle1 = GroupAngles->SpinBox_DA->value();
1477 double aLength = GroupAngles->SpinBox_DL->value();
1479 // Set the coordinates in the current coordinate system
1480 P1.SetCoord( aLength, 0.0, 0.0); // X direction
1481 P2.SetCoord( aLength * cos(anAngle1 * M_PI / 180. ),
1482 aLength * sin(anAngle1 * M_PI / 180. ),
1485 // Express the coordinates in the refernce coordinate system (OXY)
1486 gp_Trsf aTranform = toReferenceSystem(P0);
1487 P1.Transform(aTranform);
1488 P2.Transform(aTranform);
1489 P1.Translate(Origin, P0);
1490 P2.Translate(Origin, P0);
1492 if(myMode !=0 || !store)
1493 displayAngle(anAngle1, P0, P1, P2, store);
1496 std::string anAngleText = doubleToString(anAngle1) + " deg.";
1497 displayText(anAngleText, Current_Pnt, store);
1502 double anAngle2 = GroupAngles->SpinBox_DA2->value();
1503 displayAngle(anAngle2, P0, P2, Current_Pnt, store);
1504 displayLength(P0, Current_Pnt, aNormal, store);
1508 bool sameRadius = isSame ( radius(Last_Pnt), radius(Current_Pnt) );
1509 bool sameHeight = isSame ( height(Last_Pnt), height(Current_Pnt) );
1511 gp_Vec aVec(P2, Current_Pnt);
1513 if (myMode == 0 && !sameRadius)
1515 displayLength(P0.Translated(aVec), P2.Translated(aVec), aNormal, store); // Radius
1517 else if (myMode == 1)
1518 displayLength(P0, P2, aNormal, store);
1521 (myMode == 1 || !sameHeight) )
1522 displayLength(P2, Current_Pnt, aNormal.Reversed(), store); // Height
1527 //================================================================
1528 // Function : displayAngle()
1529 // Purpose : Method for displaying angle dimensions
1530 //================================================================
1531 void EntityGUI_3DSketcherDlg::displayAngle (double theAngle,
1537 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1539 // Creation of the AIS object
1540 Handle(AIS_AngleDimension) anAngleIO = createAISAngleDimension(theAngle,
1544 if (anAngleIO.IsNull())
1549 // Erase dimensions presentations
1550 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
1551 myAnglePrs->PrependObject(anAngleIO);
1553 // Display modified presentation
1555 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
1557 // Update dimension presentation angle count for later undo / redo
1560 else if ( isAngleVisible)
1562 SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1563 (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1567 aSPrs->AddObject(anAngleIO);
1568 GEOMBase_Helper::displayPreview(aSPrs, true, true);
1574 //================================================================
1575 // Function : displayLength()
1576 // Purpose : Method for displaying length dimensions for a segment
1578 //================================================================
1579 void EntityGUI_3DSketcherDlg::displayLength (gp_Pnt P1,
1584 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1586 double aLength = P1.Distance(P2);
1588 if (aLength < Precision::Confusion())
1591 Handle(AIS_LengthDimension) anIO = createAISLengthDimension(aLength, P1, P2, theNormal);
1595 // Erase length dimensions presentation
1596 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
1597 myLengthPrs->PrependObject(anIO);
1599 // Display modified presentation
1600 if (isLengthVisible)
1601 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
1603 // Update dimension presentation length count for later undo / redo
1606 else if (isLengthVisible)
1608 SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1609 (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1612 aSPrs->PrependObject(anIO);
1613 GEOMBase_Helper::displayPreview(aSPrs, true, true);
1618 //================================================================
1619 // Function : displayText()
1620 // Purpose : Method for displaying length dimensions for a segment
1622 //================================================================
1623 void EntityGUI_3DSketcherDlg::displayText ( std::string theText,
1627 SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1629 Handle(AIS_Text) anIO = new AIS_Text(TCollection_ExtendedString(theText.c_str()), P);
1633 // Erase length dimensions presentation
1634 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myTextPrs, true);
1635 myTextPrs->PrependObject(anIO);
1637 // Display modified presentation
1638 ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myTextPrs);
1640 // Update dimension presentation text count for later undo / redo
1645 SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1646 (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1649 aSPrs->PrependObject(anIO);
1650 GEOMBase_Helper::displayPreview(aSPrs, true, true);
1656 //================================================================
1657 // Function : createAISLengthDimension()
1658 // Purpose : Method for creation of a length dimension object
1659 // Returns an Handle on the AIS_LengthDimension obect
1660 //================================================================
1661 Handle(AIS_LengthDimension) EntityGUI_3DSketcherDlg::createAISLengthDimension(double theLength,
1666 // Plane construction
1667 gce_MakePln gce_MP(P1, theNormal);
1668 Handle(Geom_Plane) aPlane = new Geom_Plane(gce_MP.Value());
1670 TopoDS_Vertex aVert1 = BRepBuilderAPI_MakeVertex(P1);
1671 TopoDS_Vertex aVert2 = BRepBuilderAPI_MakeVertex(P2);
1673 Handle(AIS_LengthDimension) anIO = new AIS_LengthDimension( aVert1, aVert2, aPlane->Pln() );
1675 anIO->SetCustomValue( theLength );
1677 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1678 int w = resMgr->integerValue( "Geometry", "measures_line_width", 1 );
1680 Handle(Prs3d_DimensionAspect) aDimensionStyle = new Prs3d_DimensionAspect;
1682 aDimensionStyle->ArrowAspect()->SetLength( theLength / 20.0 );
1683 aDimensionStyle->LineAspect()->SetWidth( w );
1684 aDimensionStyle->MakeText3d( Standard_False );
1685 aDimensionStyle->SetTextHorizontalPosition( Prs3d_DTHP_Center );
1686 aDimensionStyle->SetTextVerticalPosition( Prs3d_DTVP_Center );
1687 aDimensionStyle->MakeArrows3d( Standard_True );
1688 anIO->SetFlyout( 0.0 );
1689 anIO->SetDimensionAspect( aDimensionStyle );
1694 //================================================================
1695 // Function : createAISAngleDimension()
1696 // Purpose : Method for creation of an angle dimension object
1697 // Returns an Handle on the AIS_AngleDimension obect
1698 //================================================================
1699 Handle(AIS_AngleDimension) EntityGUI_3DSketcherDlg::createAISAngleDimension(double theAngle,
1704 // Length of the built segment
1705 double aLength = P0.Distance(P1);
1708 if (Abs(theAngle) < Precision::Angular() ||
1709 aLength < Precision::Confusion())
1712 Handle(AIS_AngleDimension) anIO = new AIS_AngleDimension( P1, P0, P2 );
1714 //anIO->SetCustomValue( theAngle );
1716 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1717 int w = resMgr->integerValue( "Geometry", "measures_line_width", 1 );
1719 Handle(Prs3d_DimensionAspect) aDimensionStyle = new Prs3d_DimensionAspect;
1721 aDimensionStyle->ArrowAspect()->SetLength( (theAngle * M_PI / 180.0) * (aLength / 20.0) );
1722 aDimensionStyle->LineAspect()->SetWidth( w );
1723 aDimensionStyle->SetTextHorizontalPosition( Prs3d_DTHP_Center );
1724 aDimensionStyle->SetTextVerticalPosition( Prs3d_DTVP_Center );
1725 aDimensionStyle->MakeText3d( Standard_False );
1726 aDimensionStyle->MakeArrows3d( Standard_True );
1728 anIO->SetDimensionAspect( aDimensionStyle );
1733 //================================================================
1734 // Function : createShapes
1735 // Purpose : Create applyed wire, and last segment from entry object
1736 //================================================================
1737 bool EntityGUI_3DSketcherDlg::createShapes (GEOM::GEOM_Object_ptr /*theObject*/,
1738 TopoDS_Shape& theApplyedWire,
1739 TopoDS_Shape& theLastSegment)
1741 QList<gp_Pnt> points;
1742 foreach (XYZ xyz, myPointsList) {
1743 gp_Pnt p(xyz.x, xyz.y, xyz.z);
1744 if (points.isEmpty() || points.last().Distance(p) > gp::Resolution())
1748 if (points.count() == 1) {
1749 // only one point is created
1750 BRepBuilderAPI_MakeVertex mkVertex (points.last());
1751 theApplyedWire = mkVertex.Shape();
1753 else if (points.count() > 1) {
1755 BRepBuilderAPI_MakePolygon mkWire;
1756 foreach(gp_Pnt p, points)
1758 theApplyedWire = mkWire.Shape();
1761 XYZ curxyz = getCurrentPoint();
1762 gp_Pnt curpnt(curxyz.x, curxyz.y, curxyz.z);
1764 if (points.isEmpty() || points.last().Distance(curpnt) <= gp::Resolution()) {
1765 BRepBuilderAPI_MakeVertex mkVertex (curpnt);
1766 theLastSegment = mkVertex.Shape();
1769 BRepBuilderAPI_MakeEdge mkEdge(points.last(), curpnt);
1770 theLastSegment = mkEdge.Shape();
1773 /* VSR: old algorithm does not work properly, see bug 0020899
1774 TopoDS_Shape aShape;
1775 if (!GEOMBase::GetShape(theObject, aShape))
1778 if (aShape.ShapeType() != TopAbs_WIRE && aShape.ShapeType() != TopAbs_VERTEX)
1781 theApplyedWire = aShape;
1785 BRepBuilderAPI_MakeWire aBuilder;
1786 TopExp_Explorer edgeExp(aShape, TopAbs_EDGE);
1788 TopoDS_Shape anEdge = edgeExp.Current();
1790 if (edgeExp.More()) // i.e. non-last edge
1791 aBuilder.Add(TopoDS::Edge(anEdge));
1793 theLastSegment = anEdge;
1798 if (aBuilder.IsDone()) {
1799 theApplyedWire = aBuilder.Shape();
1801 else if (!theLastSegment.IsNull()) {
1802 TopExp_Explorer vertexExp(theLastSegment, TopAbs_VERTEX);
1803 theApplyedWire = vertexExp.Current();
1810 //================================================================
1811 // Function : doubleToString
1812 // Purpose : converts double to string
1813 //================================================================
1814 std::string EntityGUI_3DSketcherDlg::doubleToString (double num)
1818 char format = 'g'; // truncated to a number of significant digits
1820 return QString::number(num, format, digNum).toStdString();
1823 //================================================================
1824 // Function : toReferenceSystem ()
1826 //================================================================
1827 gp_Trsf EntityGUI_3DSketcherDlg::toReferenceSystem(gp_Pnt origin) const
1829 gp_Trsf T; // Identity transformation
1830 gp_Ax3 reference_system; // OXY
1831 reference_system.SetLocation(origin);
1833 gp_Ax3 current_system = reference_system;
1834 switch (myOrientation)
1838 current_system = gp_Ax3(origin, gp::DX(), gp::DY());
1843 current_system = gp_Ax3(origin, gp::DY().Reversed(), gp::DX());
1848 T.SetTransformation( current_system, reference_system );
1853 //================================================================
1854 // Function : toCurrentSystem ()
1856 //================================================================
1857 gp_Trsf EntityGUI_3DSketcherDlg::toCurrentSystem(gp_Pnt origin) const
1859 return toReferenceSystem(origin).Inverted();
1862 //================================================================
1863 // Function : radius (gp_Pnt) const
1865 //================================================================
1866 double EntityGUI_3DSketcherDlg::radius (gp_Pnt thePnt) const
1868 // Get the point coordinates in the current coordinates system
1869 gp_Trsf aTrsf = toCurrentSystem(gp::Origin());
1870 gp_Pnt aPnt = thePnt.Transformed(aTrsf);
1872 double radius = sqrt(aPnt.X()*aPnt.X() + aPnt.Y()*aPnt.Y());
1876 //================================================================
1877 // Function : height (gp_Pnt) const
1879 //================================================================
1880 double EntityGUI_3DSketcherDlg::height (gp_Pnt thePnt) const
1882 // Get the point coordinates in the current coordinates system
1883 gp_Trsf aTrsf = toCurrentSystem(gp::Origin());
1884 gp_Pnt aPnt = thePnt.Transformed(aTrsf);