Salome HOME
Copyrights update 2015.
[modules/geom.git] / src / EntityGUI / EntityGUI_3DSketcherDlg.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // GEOM GEOMGUI : GUI for Geometry component
21 // File   : EntityGUI_3DSketcherDlg.cxx
22 // Author : DMV, OCN
23
24 #include <cmath>
25 #include <string>
26 #include <boost/lexical_cast.hpp>
27
28 #include "EntityGUI_3DSketcherDlg.h"
29 #include "EntityGUI_Widgets.h"
30
31 #include <Basics_OCCTVersion.hxx>
32
33 #include <GEOMBase.h>
34 #include <GeometryGUI.h>
35 #include <Precision.hxx>
36
37 #include <DlgRef.h>
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>
44 #include <SOCC_Prs.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>
50
51 #include <SalomeApp_Tools.h>
52
53 //OCCT includes
54 #include <TopoDS.hxx>
55 #include <TColStd_IndexedMapOfInteger.hxx>
56 #include <BRepBuilderAPI_MakeVertex.hxx>
57 #include <BRepBuilderAPI_MakePolygon.hxx>
58 #include <BRepBuilderAPI_MakeEdge.hxx>
59
60 #include <AIS_Trihedron.hxx>
61 #include <AIS_AngleDimension.hxx>
62 #include <AIS_LengthDimension.hxx>
63 #include <AIS_Drawer.hxx>
64 #include <Geom_Axis2Placement.hxx>
65 #include <Geom_Plane.hxx>
66 #include <SelectMgr_Selection.hxx>
67 #include <gce_MakePln.hxx>
68 #include <Prs3d_LineAspect.hxx>
69 #include <Prs3d_DimensionAspect.hxx>
70 #include <Prs3d_TextAspect.hxx>
71 #include <Prs3d_Presentation.hxx>
72 #include <Prs3d_Text.hxx>
73 #include <Graphic3d_VerticalTextAlignment.hxx>
74 #include <Graphic3d_HorizontalTextAlignment.hxx>
75 #include <Graphic3d_AspectText3d.hxx>
76 #include <Font_FontAspect.hxx>
77
78 // This include must be *AFTER* SOCC_ViewModel.h because
79 // of the constant ROTATE which is a #define in
80 // GEOMImpl_Types.hxx and an enum in SOCC_ViewModel.h
81 #include <GEOMImpl_Types.hxx>
82
83 // TODO
84 //
85 // Avoid duplication of angle coordinates in cylindrical mode
86 // Check spherical mode in absolute
87
88 enum
89 {
90   OXY,
91   OYZ,
92   OXZ
93 };
94
95 class Locker
96 {
97 public:
98   Locker(bool& l) : myLock(l) { myLock = true;  }
99   ~Locker()                   { myLock = false; }
100 private:
101   bool& myLock;
102 };
103
104 DEFINE_STANDARD_HANDLE(AIS_Text, AIS_InteractiveObject)
105
106 class AIS_Text:public AIS_InteractiveObject
107 {
108 public:
109   // CASCADE RTTI
110   DEFINE_STANDARD_RTTI(AIS_Text );
111
112   AIS_Text(){};
113
114   AIS_Text
115     (
116       const TCollection_ExtendedString& , const gp_Pnt& ,
117       Quantity_Color color,
118       Standard_Integer aHJust,
119       Standard_Integer aVJust ,
120       Standard_Real Angle ,
121       Standard_Boolean Zoom ,
122       Standard_Real  Height,
123       Font_FontAspect FontAspect,
124       Standard_CString Font
125     );
126
127 private:
128
129   void Compute (  const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
130                   const Handle(Prs3d_Presentation)& aPresentation,
131                   const Standard_Integer aMode);
132
133   void ComputeSelection (  const Handle(SelectMgr_Selection)& aSelection,
134                            const Standard_Integer aMode){} ;
135
136 protected:
137   TCollection_ExtendedString          aText;
138   gp_Pnt                              aPosition;
139   Standard_Real                       Red;
140   Standard_Real                       Green;
141   Standard_Real                       Blue;
142   Standard_Real                       aAngle;
143   Standard_Real                       aHeight;
144   Standard_Boolean                    aZoomable;
145   Quantity_Color                      aColor;
146   Standard_CString                    aFont;
147   Font_FontAspect                      aFontAspect;
148   Graphic3d_HorizontalTextAlignment   aHJustification;
149   Graphic3d_VerticalTextAlignment     aVJustification;
150 };
151
152 IMPLEMENT_STANDARD_HANDLE(AIS_Text, AIS_InteractiveObject)
153 IMPLEMENT_STANDARD_RTTIEXT(AIS_Text, AIS_InteractiveObject)
154
155 AIS_Text::AIS_Text( const TCollection_ExtendedString& text, const gp_Pnt& position,
156                           Quantity_Color    color       = Quantity_NOC_YELLOW,
157                           Standard_Integer  aHJust      = Graphic3d_HTA_LEFT,
158                           Standard_Integer  aVJust      = Graphic3d_VTA_BOTTOM,
159                           Standard_Real     angle       = 0.0 ,
160                           Standard_Boolean  zoomable    = Standard_False,
161                           Standard_Real     height      = 16.,
162                           Font_FontAspect    fontAspect  = Font_FA_Regular,
163                           Standard_CString  font        = "Courier")
164 {
165   aText           = text;
166   aPosition       = position;
167   aHJustification = Graphic3d_HorizontalTextAlignment(aHJust);
168   aVJustification = Graphic3d_VerticalTextAlignment(aVJust);
169   aAngle          = angle;
170   aZoomable       = zoomable;
171   aHeight         = height;
172   aColor          = color;
173   aFontAspect     = fontAspect;
174   aFont           = font;
175 };
176
177 void AIS_Text::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
178                           const Handle(Prs3d_Presentation)& aPresentation,
179                           const Standard_Integer aMode)
180 {
181
182   aPresentation->Clear();
183
184   Handle_Prs3d_TextAspect asp = myDrawer->TextAspect();
185
186   asp->SetFont(aFont);
187   asp->SetColor(aColor);
188   asp->SetHeight(aHeight); // I am changing the myHeight value
189
190   asp->SetHorizontalJustification(aHJustification);
191   asp->SetVerticalJustification(aVJustification);
192   asp->Aspect()->SetTextZoomable(aZoomable);
193   asp->Aspect()->SetTextAngle(aAngle);
194   asp->Aspect()->SetTextFontAspect(aFontAspect);
195   Prs3d_Text::Draw(aPresentation, asp, aText, aPosition);
196 };
197
198 bool isSame (double d1, double d2)
199
200   return Abs(d1 - d2) <= Precision::Confusion();
201 }
202
203 //=================================================================================
204 // class    : EntityGUI_3DSketcherDlg()
205 // purpose  : Constructs a EntityGUI_3DSketcherDlg which is a child of 'parent', with the
206 //            name 'name' and widget flags set to 'f'.
207 //            The dialog will by default be modeless, unless you set 'modal' to
208 //            TRUE to construct a modal dialog.
209 //=================================================================================
210 EntityGUI_3DSketcherDlg::EntityGUI_3DSketcherDlg (GeometryGUI* theGeometryGUI, QWidget* parent,
211                                                   bool modal, Qt::WindowFlags fl,
212                                                   const double lineWidth)
213   : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl),
214     myMode(-1),
215     myOK(false),
216     myLineWidth(lineWidth),
217     myGeometryGUI(theGeometryGUI),
218     myLengthIORedoList(),
219     myIsUndoRedo(false)
220 {
221   QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
222   QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_UNDO")));
223   QPixmap image2(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_REDO")));
224   QPixmap image3(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICO_3DSKETCH")));
225
226   setWindowTitle(tr("GEOM_3DSKETCHER_TITLE"));
227
228   /***************************************************************/
229
230   mainFrame()->GroupConstructors->setTitle(tr("GEOM_3DSKETCHER"));
231   mainFrame()->RadioButton1->setIcon(image3);;
232   mainFrame()->RadioButton2->close();
233   mainFrame()->RadioButton3->close();
234
235   GroupType = new EntityGUI_Type(centralWidget());
236   GroupType->GroupType2->setTitle(tr("GEOM_COORDINATES_TYPE"));
237   GroupType->GroupType1->setTitle(tr("GEOM_MODE"));
238   GroupType->RadioButton1->setText(tr("GEOM_SKETCHER_ABS"));
239   GroupType->RadioButton2->setText(tr("GEOM_SKETCHER_REL"));
240   GroupType->RadioButton3->setText(tr("(X,Y,Z)"));
241   GroupType->RadioButton4->setText(tr("GEOM_ANGLES"));
242  
243   myTypeGroup1 = new QButtonGroup(this);
244   myTypeGroup1->setExclusive(true);
245   myTypeGroup1->addButton(GroupType->RadioButton1, 0);
246   myTypeGroup1->addButton(GroupType->RadioButton2, 1);
247   
248   myTypeGroup2 = new QButtonGroup(this);
249   myTypeGroup2->setExclusive(true);
250   myTypeGroup2->addButton(GroupType->RadioButton3, 0);
251   myTypeGroup2->addButton(GroupType->RadioButton4, 1);
252
253   Group3Spin = new EntityGUI_3Spin(centralWidget());
254   Group3Spin->GroupBox1->setTitle(tr("GEOM_SKETCHER_VALUES"));
255   Group3Spin->buttonApply->setText(tr("GEOM_SKETCHER_APPLY"));
256   Group3Spin->buttonUndo->setIcon(image1);
257   Group3Spin->buttonRedo->setIcon(image2);
258   Group3Spin->TextLabel1->setText(tr("GEOM_SKETCHER_X2"));
259   Group3Spin->TextLabel2->setText(tr("GEOM_SKETCHER_Y2"));
260   Group3Spin->TextLabel3->setText(tr("GEOM_SKETCHER_Z2"));
261
262   GroupAngles = new EntityGUI_Angles(centralWidget());
263   GroupAngles->buttonApply->setText(tr("GEOM_SKETCHER_APPLY"));
264   GroupAngles->buttonUndo->setIcon(image1);
265   GroupAngles->buttonRedo->setIcon(image2);
266   GroupAngles->TextLabel1->setText(tr("GEOM_LENGTH"));
267   GroupAngles->TextLabel2->setText(tr("GEOM_ANGLE")); 
268   GroupAngles->checkBox  ->setText(tr("GEOM_ANGLE_2"));
269   GroupAngles->checkBox_2->setText(tr("GEOM_HEIGHT"));
270
271   GroupControls = new EntityGUI_Controls(centralWidget());
272   GroupControls->GroupBox1->setTitle(tr("GEOM_CONTROLS"));
273   GroupControls->CheckBox1->setText(tr("GEOM_SHOW_LENGTH")); 
274   GroupControls->CheckBox2->setText(tr("GEOM_SHOW_ANGLE"));
275   GroupControls->CheckBox3->setText(tr("GEOM_SHOW_POINTS_COORD"));
276   GroupControls->lineEdit_1->setReadOnly(true);
277   GroupControls->lineEdit_2->setReadOnly(true);
278   GroupControls->lineEdit_3->setReadOnly(true);
279   GroupControls->lineEdit_4->setReadOnly(true);
280   GroupControls->lineEdit_5->setReadOnly(true);
281   GroupControls->lineEdit_6->setReadOnly(true);
282   GroupControls->label_1->setText(tr("X:"));
283   GroupControls->label_2->setText(tr("Y:"));
284   GroupControls->label_3->setText(tr("Z:"));
285   GroupControls->label_4->setText(tr("X:"));
286   GroupControls->label_5->setText(tr("Y:"));
287   GroupControls->label_6->setText(tr("Z:"));
288   GroupControls->label_7->setText(tr("GEOM_START"));
289   GroupControls->label_8->setText(tr("GEOM_END"));
290
291   buttonOk()->setText(tr("GEOM_BUT_END_SKETCH"));
292   buttonApply()->setText(tr("GEOM_BUT_CLOSE_SKETCH"));
293
294   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
295   layout->setMargin(0); layout->setSpacing(6);
296   layout->addWidget(GroupType);
297   layout->addWidget(Group3Spin);
298   layout->addWidget(GroupAngles);
299   layout->addWidget(GroupControls);
300
301   setHelpFileName("create_3dsketcher_page.html");
302
303   resize(100,100);
304   Init();
305 }
306
307 //=================================================================================
308 // function : ~EntityGUI_3DSketcherDlg()
309 // purpose  : Destroys the object and frees any allocated resources
310 //=================================================================================
311 EntityGUI_3DSketcherDlg::~EntityGUI_3DSketcherDlg()
312 {
313   myGeomGUI->SetActiveDialogBox(0);
314 }
315
316 //=================================================================================
317 // function : Init()
318 // purpose  :
319 //=================================================================================
320 void EntityGUI_3DSketcherDlg::Init()
321 {
322   myOK = false;
323   myOrientation = OXY;
324   myPrsType = prsType();
325
326   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
327   myAnglePrs = dynamic_cast<SOCC_Prs*>(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
328   myLengthPrs = dynamic_cast<SOCC_Prs*>(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
329   myTextPrs = dynamic_cast<SOCC_Prs*>(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
330
331   localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX);
332
333   /* Get setting of step value from file configuration */
334   double step = SUIT_Session::session()->resourceMgr()->doubleValue("Geometry", "SettingsGeomStep", 100.0);
335
336   /* min, max, step and decimals for spin boxes */
337   initSpinBox(Group3Spin->SpinBox_DX, COORD_MIN, COORD_MAX, step, "length_precision");
338   initSpinBox(Group3Spin->SpinBox_DY, COORD_MIN, COORD_MAX, step, "length_precision");
339   initSpinBox(Group3Spin->SpinBox_DZ, COORD_MIN, COORD_MAX, step, "length_precision");
340
341   initSpinBox(GroupAngles->SpinBox_DA , -360.0, 360.0, step, "angular_precision");
342   initSpinBox(GroupAngles->SpinBox_DA2,  -90.0,  90.0, step, "angular_precision");
343   initSpinBox(GroupAngles->SpinBox_DL , COORD_MIN, COORD_MAX, step, "length_precision");
344   initSpinBox(GroupAngles->SpinBox_DH , COORD_MIN, COORD_MAX, step, "length_precision");
345
346   Group3Spin->SpinBox_DX->setValue(0.0);
347   Group3Spin->SpinBox_DY->setValue(0.0);
348   Group3Spin->SpinBox_DZ->setValue(0.0);
349
350   GroupAngles->SpinBox_DA->setValue(0.0);
351   GroupAngles->SpinBox_DA2->setValue(0.0);
352   GroupAngles->SpinBox_DL->setValue(0.0);
353   GroupAngles->SpinBox_DH->setValue(0.0);
354
355   GroupAngles->radioButton_1->setChecked(true);
356   GroupAngles->checkBox->setChecked(false);
357   GroupAngles->checkBox_2->setChecked(false);
358   GroupAngles->SpinBox_DA2->setEnabled(false);
359   GroupAngles->SpinBox_DH->setEnabled(false);
360
361   GroupControls->CheckBox1->setChecked(true);
362   GroupControls->CheckBox2->setChecked(true);
363   GroupControls->CheckBox3->setChecked(true);
364   
365   isLengthVisible = true;
366   isAngleVisible = true;
367
368   GroupAngles->hide();
369
370   /* signals and slots connections */
371   connect(buttonOk(),     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
372   connect(buttonApply(),  SIGNAL(clicked()), this, SLOT(ClickOnApply()));
373
374   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
375
376   connect(Group3Spin->buttonApply,   SIGNAL(clicked()), this, SLOT(ClickOnAddPoint()));
377   connect(Group3Spin->buttonUndo,    SIGNAL(clicked()), this, SLOT(ClickOnUndo()));
378   connect(Group3Spin->buttonRedo,    SIGNAL(clicked()), this, SLOT(ClickOnRedo())) ;
379
380   connect(GroupAngles->buttonApply,  SIGNAL(clicked()), this, SLOT(ClickOnAddPoint()));
381   connect(GroupAngles->buttonUndo,   SIGNAL(clicked()), this, SLOT(ClickOnUndo()));
382   connect(GroupAngles->buttonRedo,   SIGNAL(clicked()), this, SLOT(ClickOnRedo())) ;
383
384   connect(myTypeGroup1, SIGNAL(buttonClicked(int)),  this, SLOT(TypeClicked(int)));
385   connect(myTypeGroup2, SIGNAL(buttonClicked(int)),  this, SLOT(TypeClicked(int)));
386
387   connect(Group3Spin->SpinBox_DX,       SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
388   connect(Group3Spin->SpinBox_DY,       SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
389   connect(Group3Spin->SpinBox_DZ,       SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
390
391   connect(GroupAngles->SpinBox_DA,      SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
392   connect(GroupAngles->SpinBox_DA2,     SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
393   connect(GroupAngles->SpinBox_DL,      SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
394   connect(GroupAngles->SpinBox_DH,      SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
395
396   connect(GroupAngles->radioButton_1,   SIGNAL(clicked (bool)), this, SLOT(ButtonClicked(bool))) ;
397   connect(GroupAngles->radioButton_2,   SIGNAL(clicked (bool)), this, SLOT(ButtonClicked(bool))) ;
398   connect(GroupAngles->radioButton_3,   SIGNAL(clicked (bool)), this, SLOT(ButtonClicked(bool))) ;
399
400   connect(GroupAngles->checkBox,        SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
401   connect(GroupAngles->checkBox_2,      SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
402   connect(GroupControls->CheckBox1,     SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
403   connect(GroupControls->CheckBox2,     SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
404   connect(GroupControls->CheckBox3,     SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ;
405
406   connect(myGeomGUI, SIGNAL(SignalDefaultStepValueChanged(double)), this, SLOT(SetDoubleSpinBoxStep(double)));
407
408   connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
409   connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()),        this, SLOT(ClickOnCancel()));
410
411   initName(tr("GEOM_3DSKETCHER"));
412   
413   GroupControls->CheckBox3->click();
414
415   UpdateButtonsState();
416   
417   myMode      = 0;
418   myCoordType = 0;
419   
420   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
421 }
422
423 //=================================================================================
424 // function : TypeClicked()
425 // purpose  : Radio button management
426 //=================================================================================
427 void EntityGUI_3DSketcherDlg::TypeClicked (int id)
428 {
429   QButtonGroup* send = (QButtonGroup*) sender();
430   
431   int coordType = myCoordType;
432   int mode      = myMode;
433   
434   if (send == myTypeGroup1)
435   {
436     if(id == myMode) return;
437     mode = id;   
438   }
439   else if (send == myTypeGroup2)
440   {
441     if (id == myCoordType) return;
442     coordType = id;  
443   }
444   
445   GroupAngles->hide();
446   Group3Spin->show();
447
448   bool blocked = Group3Spin->SpinBox_DX->signalsBlocked();
449   Group3Spin->SpinBox_DX->blockSignals(true);
450   Group3Spin->SpinBox_DY->blockSignals(true);
451   Group3Spin->SpinBox_DZ->blockSignals(true);
452
453   // Get setting of step value from file configuration
454   XYZ xyz = getLastPoint();
455   bool okx, oky, okz;
456   Group3Spin->SpinBox_DX->text().toDouble(&okx);
457   Group3Spin->SpinBox_DY->text().toDouble(&oky);
458   Group3Spin->SpinBox_DZ->text().toDouble(&okz);
459
460   if (coordType == 0)  // Cartesian coordinates
461   {
462     if (mode == 0) {   // XYZ
463       Group3Spin->TextLabel1->setText(tr("GEOM_SKETCHER_X2"));
464       Group3Spin->TextLabel2->setText(tr("GEOM_SKETCHER_Y2"));
465       Group3Spin->TextLabel3->setText(tr("GEOM_SKETCHER_Z2"));
466       if (myCoordType == 0 && myMode == 1)
467       {
468         if (okx) Group3Spin->SpinBox_DX->setValue(xyz.x + Group3Spin->SpinBox_DX->value());
469         if (oky) Group3Spin->SpinBox_DY->setValue(xyz.y + Group3Spin->SpinBox_DY->value());
470         if (okz) Group3Spin->SpinBox_DZ->setValue(xyz.z + Group3Spin->SpinBox_DZ->value());
471       }
472       Group3Spin->buttonApply->setFocus();
473     }
474     else if (mode == 1) { // DXDYDZ
475       Group3Spin->TextLabel1->setText(tr("GEOM_SKETCHER_DX2"));
476       Group3Spin->TextLabel2->setText(tr("GEOM_SKETCHER_DY2"));
477       Group3Spin->TextLabel3->setText(tr("GEOM_SKETCHER_DZ2"));
478       if (myCoordType == 0 && myMode == 0)
479       {
480         if (okx) Group3Spin->SpinBox_DX->setValue(Group3Spin->SpinBox_DX->value() - xyz.x);
481         if (oky) Group3Spin->SpinBox_DY->setValue(Group3Spin->SpinBox_DY->value() - xyz.y);
482         if (okz) Group3Spin->SpinBox_DZ->setValue(Group3Spin->SpinBox_DZ->value() - xyz.z);
483       }
484       Group3Spin->buttonApply->setFocus();
485     }
486   }
487   else if (coordType == 1) // Angles and Length
488   {
489     Group3Spin->hide();
490     GroupAngles->show();
491     GroupAngles->buttonApply->setFocus();
492   }
493
494   Group3Spin->SpinBox_DX->blockSignals(blocked);
495   Group3Spin->SpinBox_DY->blockSignals(blocked);
496   Group3Spin->SpinBox_DZ->blockSignals(blocked);
497
498   myMode = mode;
499   myCoordType = coordType;
500
501   updateGeometry();
502   resize(minimumSizeHint());
503
504   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
505 }
506
507 //=================================================================================
508 // function : ClickOnAddPoint()
509 // purpose  : called when the point coordinates is Applyed
510 //=================================================================================
511 void EntityGUI_3DSketcherDlg::ClickOnAddPoint()
512
513   QString msg;
514   if (!isValid(msg)) {
515     showError(msg);
516     return;
517   }
518   
519   myPrsType   = prsType();
520   
521 //   if(myMode == 1)
522     displayDimensions( /*store = */true);
523
524   myPointsList.append(getCurrentPoint());
525   myRedoList.clear();
526   myLengthIORedoList.Clear();
527   myAngleIORedoList.Clear();
528   myTextIORedoList.Clear();
529
530   if (myCoordType == 0 && myMode == 1)     // RELATIVE CARTESIAN COORDINATES
531   {
532     Group3Spin->SpinBox_DX->setValue(0.0);
533     Group3Spin->SpinBox_DY->setValue(0.0);
534     Group3Spin->SpinBox_DZ->setValue(0.0);
535   }
536   else if (myCoordType == 1 && myMode == 1) // RELATIVE ANGULAR COORDINATES
537   {
538     GroupAngles->SpinBox_DA->setValue(0.0);
539     GroupAngles->SpinBox_DL->setValue(0.0);
540     GroupAngles->SpinBox_DA2->setValue(0.0);
541   }
542   
543   UpdatePointCoordinates();
544     
545   UpdateButtonsState();
546   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
547 }
548
549 //=================================================================================
550 // function : UpdateButtonsState()
551 // purpose  :
552 //=================================================================================
553 void EntityGUI_3DSketcherDlg::UpdateButtonsState()
554 {
555   if (myPointsList.count() == 0) 
556   {
557     GroupType->RadioButton1->click();
558     GroupType->RadioButton3->click();
559   }
560   GroupType->RadioButton2->setEnabled(myPointsList.count() > 0);
561 //   GroupType->RadioButton3->setEnabled(myPointsList.count() > 0);
562 //   GroupType->RadioButton4->setEnabled(myPointsList.count() > 0);
563   Group3Spin->buttonUndo->setEnabled(myPointsList.count() > 0);
564   Group3Spin->buttonRedo->setEnabled(myRedoList.count() > 0);
565   GroupAngles->buttonUndo->setEnabled(myPointsList.count() > 0);
566   GroupAngles->buttonRedo->setEnabled(myRedoList.count() > 0);
567 }
568
569 //=================================================================================
570 // function : UpdatePointCoordinates()
571 // purpose  :Update point coordinates in the control groupbox
572 //=================================================================================
573 void EntityGUI_3DSketcherDlg::UpdatePointCoordinates()
574 {
575   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
576   int aPrecision = resMgr->integerValue("Geometry", "length_precision", 6);
577   
578   if (myPointsList.count() == 0)
579   {
580     GroupControls->lineEdit_1->setText("");
581     GroupControls->lineEdit_2->setText("");
582     GroupControls->lineEdit_3->setText("");
583     
584     GroupControls->lineEdit_4->setText("");
585     GroupControls->lineEdit_5->setText("");
586     GroupControls->lineEdit_6->setText("");
587   }
588   else if (myPointsList.count() == 1)
589   {
590     GroupControls->lineEdit_1->setText(DlgRef::PrintDoubleValue(getLastPoint().x, aPrecision));
591     GroupControls->lineEdit_2->setText(DlgRef::PrintDoubleValue(getLastPoint().y, aPrecision));
592     GroupControls->lineEdit_3->setText(DlgRef::PrintDoubleValue(getLastPoint().z, aPrecision));
593     
594     GroupControls->lineEdit_4->setText("");
595     GroupControls->lineEdit_5->setText("");
596     GroupControls->lineEdit_6->setText("");
597   }
598   else
599   {
600     GroupControls->lineEdit_4->setText(DlgRef::PrintDoubleValue(getLastPoint().x, aPrecision));
601     GroupControls->lineEdit_5->setText(DlgRef::PrintDoubleValue(getLastPoint().y, aPrecision));
602     GroupControls->lineEdit_6->setText(DlgRef::PrintDoubleValue(getLastPoint().z, aPrecision));
603   }
604   
605 }
606
607 //=================================================================================
608 // function : ClickOnUndo()
609 // purpose  :
610 //=================================================================================
611 void EntityGUI_3DSketcherDlg::ClickOnUndo()
612 {
613   myIsUndoRedo = true;
614   if (myPointsList.count() > 0) {
615     
616     myRedoList.append(myPointsList.last());
617
618     // Erase dimensions presentations
619     SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
620     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
621     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
622     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myTextPrs, true);
623     
624     removeLastIOFromPrs();
625
626     // Display modified presentation
627     if (isLengthVisible)
628       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
629     if (isAngleVisible)
630       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
631     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myTextPrs);
632     
633     // Remove last point from list
634     myWorkPoint = myPointsList.last();
635     myPointsList.removeLast();
636     GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
637     UpdateButtonsState();
638     
639     // Update of point coordinates in the control groupbox
640     UpdatePointCoordinates();
641
642     updateViewer();
643   }
644   myIsUndoRedo = false;
645 }
646
647 //=================================================================================
648 // function : ClickOnRedo()
649 // purpose  :
650 //=================================================================================
651 void EntityGUI_3DSketcherDlg::ClickOnRedo()
652 {
653   myIsUndoRedo = true;
654   if (myRedoList.count() > 0) {
655     
656     myPointsList.append(myRedoList.last());
657
658     // Erase dimensions presentations
659     SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
660     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
661     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
662     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myTextPrs, true);
663     
664     restoreLastIOToPrs();
665
666     // Display modified presentation
667     if (isLengthVisible)
668       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
669     if (isAngleVisible)
670       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
671     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myTextPrs);
672     
673     // Remove last point from redo list
674     myWorkPoint = myRedoList.last();
675     myRedoList.removeLast();
676     GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
677     UpdateButtonsState();
678     
679     // Update of point coordinates in the control groupbox
680     UpdatePointCoordinates();
681
682     updateViewer();
683   }
684   myIsUndoRedo = false;
685 }
686
687 //=================================================================================
688 // function : removeLastIO()
689 // purpose  :
690 //=================================================================================
691 void EntityGUI_3DSketcherDlg::removeLastIOFromPrs ()
692 {
693   AIS_ListOfInteractive anIOList;
694   XYZ Last = getLastPoint();
695   
696   for (int l = 0; l<Last.L; l++)
697   {
698     myLengthPrs->GetObjects(anIOList);
699     myLengthIORedoList.Prepend(anIOList.First());  // Store last prepended Length IO in redo list
700     myLengthPrs->RemoveFirst();                    // Remove it from myLengthPrs
701   }
702   for (int a = 0; a<Last.A; a++)
703   {
704     myAnglePrs->GetObjects(anIOList);
705     myAngleIORedoList.Prepend(anIOList.First());  // Store last prepended Angle IO in redo list
706     myAnglePrs->RemoveFirst();                    // Remove it from myAnglePrs
707   }
708   for (int t = 0; t<Last.T; t++)
709   {
710     myTextPrs->GetObjects(anIOList);
711     myTextIORedoList.Prepend(anIOList.First());  // Store last prepended Text IO in redo list
712     myTextPrs->RemoveFirst();                    // Remove it from myTextPrs
713   }
714 }
715
716 //=================================================================================
717 // function : restoreLastIO()
718 // purpose  :
719 //=================================================================================
720 void EntityGUI_3DSketcherDlg::restoreLastIOToPrs ()
721 {
722   XYZ LastDeleted = myRedoList.last();
723   
724   for (int l = 0; l<LastDeleted.L; l++)
725   {
726     myLengthPrs->PrependObject(myLengthIORedoList.First()); // Restore last removed IO
727     myLengthIORedoList.RemoveFirst();                       // Remove it from redo list
728   } 
729   for (int a = 0; a<LastDeleted.A; a++)
730   {
731     myAnglePrs->PrependObject(myAngleIORedoList.First());  // Restore last removed IO
732     myAngleIORedoList.RemoveFirst();                       // Remove it from redo list
733   }
734   for (int t = 0; t<LastDeleted.T; t++)
735   {
736     myTextPrs->PrependObject(myTextIORedoList.First());  // Restore last removed IO
737     myTextIORedoList.RemoveFirst();                       // Remove it from redo list
738   }
739 }
740
741 //=================================================================================
742 // function : SelectionIntoArgument()
743 // purpose  : Called when selection as changed
744 //=================================================================================
745 void EntityGUI_3DSketcherDlg::SelectionIntoArgument()
746 {
747   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
748   SALOME_ListIO aSelList;
749   aSelMgr->selectedObjects(aSelList);
750
751   int nbSel = aSelList.Extent();
752   if (nbSel == 1) {
753     GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject(aSelList.First());
754     if (!CORBA::is_nil(aSelectedObject)) {
755       TopoDS_Shape aShape;
756       if (GEOMBase::GetShape(aSelectedObject, aShape, TopAbs_SHAPE)) {
757         // Explore the shape if its a local selection
758         TColStd_IndexedMapOfInteger aMap;
759         aSelMgr->GetIndexes(aSelList.First(), aMap);
760         if (aMap.Extent() == 1) {
761           int anIndex = aMap(1);
762           GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations(getStudyId());
763           aSelectedObject = aShapesOp->GetSubShape(aSelectedObject, anIndex);
764         }
765       }
766       bool isOk = true;
767       if (aShape.ShapeType() != TopAbs_VERTEX)
768         isOk = GEOMBase::GetShape(aSelectedObject, aShape, TopAbs_VERTEX);
769       if (isOk) {
770         gp_Pnt aPnt;
771         if (GEOMBase::VertexToPoint(aShape, aPnt)) {
772           // set coordinates to the Spin Boxes
773           double aX, aY, aZ;
774           aX = aPnt.X();
775           aY = aPnt.Y();
776           aZ = aPnt.Z();
777           bool blocked = Group3Spin->SpinBox_DX->signalsBlocked();
778           Group3Spin->SpinBox_DX->blockSignals(true);
779           Group3Spin->SpinBox_DY->blockSignals(true);
780           Group3Spin->SpinBox_DZ->blockSignals(true);
781           if (GroupType->RadioButton1->isChecked()) {
782             Group3Spin->SpinBox_DX->setValue(aX);
783             Group3Spin->SpinBox_DY->setValue(aY);
784             Group3Spin->SpinBox_DZ->setValue(aZ);
785           }
786           else if (GroupType->RadioButton2->isChecked()) {
787             XYZ xyz = getLastPoint();
788             Group3Spin->SpinBox_DX->setValue(aX - xyz.x);
789             Group3Spin->SpinBox_DY->setValue(aY - xyz.y);
790             Group3Spin->SpinBox_DZ->setValue(aZ - xyz.z);
791           }
792           Group3Spin->SpinBox_DX->blockSignals(blocked);
793           Group3Spin->SpinBox_DY->blockSignals(blocked);
794           Group3Spin->SpinBox_DZ->blockSignals(blocked);
795         }
796       }
797     }
798   }
799   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
800 }
801
802 //=================================================================================
803 // function : DeactivateActiveDialog()
804 // purpose  :
805 //=================================================================================
806 void EntityGUI_3DSketcherDlg::DeactivateActiveDialog()
807 {
808   setEnabled(false);
809   globalSelection();
810   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
811   myGeomGUI->SetActiveDialogBox(0);
812 }
813
814 //=================================================================================
815 // function : ActivateThisDialog()
816 // purpose  :
817 //=================================================================================
818 void EntityGUI_3DSketcherDlg::ActivateThisDialog()
819 {
820   myGeomGUI->EmitSignalDeactivateDialog();
821   setEnabled(true);
822   myGeomGUI->SetActiveDialogBox(this);
823
824   connect(myGeomGUI->getApp()->selectionMgr(),
825           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
826
827   localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX);
828   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
829 }
830
831 //=================================================================================
832 // function : ValueChangedInSpinBox()
833 // purpose  :
834 //=================================================================================
835 void EntityGUI_3DSketcherDlg::ValueChangedInSpinBox (double newValue)
836 {
837   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
838 }
839
840 //=================================================================================
841 // function : BoxChecked()
842 // purpose  : ChecBoxes management
843 //=================================================================================
844 void EntityGUI_3DSketcherDlg::BoxChecked (bool checked)
845 {
846   QCheckBox* send = (QCheckBox*) sender();
847   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
848
849   if (send == GroupAngles->checkBox)
850   {
851     GroupAngles->SpinBox_DA2->setEnabled(checked);
852     if(checked)
853     {
854       GroupAngles->SpinBox_DH->setEnabled(false);
855       GroupAngles->checkBox_2->setChecked(false);
856     }
857   }
858   else if (send == GroupAngles->checkBox_2)
859   {
860     GroupAngles->SpinBox_DH->setEnabled(checked);
861     if(checked)
862     {
863       GroupAngles->SpinBox_DA2->setEnabled(false);
864       GroupAngles->checkBox->setChecked(false);
865     }
866   }
867
868   else if (send == GroupControls->CheckBox1)
869   {
870     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
871     if (checked){
872       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
873       isLengthVisible=true;
874     }
875     else
876       isLengthVisible=false;
877   }
878   else if (send == GroupControls->CheckBox2)
879   {
880     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
881     if (checked)
882     {
883       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
884       isAngleVisible=true;
885     }
886     else
887       isAngleVisible=false;
888   }
889   else if (send == GroupControls->CheckBox3)
890   {
891     GroupControls->lineEdit_1->setVisible(checked);
892     GroupControls->lineEdit_2->setVisible(checked);
893     GroupControls->lineEdit_3->setVisible(checked);
894     GroupControls->lineEdit_4->setVisible(checked);
895     GroupControls->lineEdit_5->setVisible(checked);
896     GroupControls->lineEdit_6->setVisible(checked);
897     
898     GroupControls->label_1->setVisible(checked);
899     GroupControls->label_2->setVisible(checked);
900     GroupControls->label_3->setVisible(checked);
901     GroupControls->label_4->setVisible(checked);
902     GroupControls->label_5->setVisible(checked);
903     GroupControls->label_6->setVisible(checked);
904     GroupControls->label_7->setVisible(checked);
905     GroupControls->label_8->setVisible(checked);
906     
907     GroupControls->updateGeometry();
908     GroupControls->resize(minimumSizeHint());
909   } 
910
911   updateGeometry();
912   resize(minimumSizeHint());
913   
914   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
915 }
916
917 //=================================================================================
918 // function : ButtonClicked()
919 // purpose  :
920 //=================================================================================
921 void EntityGUI_3DSketcherDlg::ButtonClicked (bool checked)
922 {
923   if (GroupAngles->radioButton_1->isChecked())
924     myOrientation = OXY;
925   else if (GroupAngles->radioButton_2->isChecked())
926     myOrientation = OYZ;
927   else
928     myOrientation = OXZ;
929
930   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
931 }
932
933 //=================================================================================
934 // function : enterEvent()
935 // purpose  :
936 //=================================================================================
937 void EntityGUI_3DSketcherDlg::enterEvent (QEvent*)
938 {
939   if (!mainFrame()->GroupConstructors->isEnabled())
940     ActivateThisDialog();
941 }
942
943 //=================================================================================
944 // function : createOperation
945 // purpose  :
946 //=================================================================================
947 GEOM::GEOM_IOperations_ptr EntityGUI_3DSketcherDlg::createOperation()
948 {
949   return getGeomEngine()->GetICurvesOperations(getStudyId());
950 }
951
952 //=================================================================================
953 // function : isValid
954 // purpose  :
955 //=================================================================================
956 bool EntityGUI_3DSketcherDlg::isValid (QString& msg)
957 {
958   bool ok = true;
959   ok = Group3Spin->SpinBox_DX->isValid(msg, !IsPreview()) && ok;
960   ok = Group3Spin->SpinBox_DY->isValid(msg, !IsPreview()) && ok;
961   ok = Group3Spin->SpinBox_DZ->isValid(msg, !IsPreview()) && ok;
962   return ok;
963 }
964
965 //=================================================================================
966 // function : execute
967 // purpose  :
968 //=================================================================================
969 bool EntityGUI_3DSketcherDlg::execute (ObjectList& objects)
970 {
971   //GEOM::ListOfDouble_var aCoordsArray = new GEOM::ListOfDouble;
972   //if (!myOK || myPointsList.size() == 0)
973   //  aCoordsArray->length((myPointsList.size()+1)*3);
974   //else
975   //  aCoordsArray->length(myPointsList.size()*3);
976
977   QStringList aCommands;
978   aCommands << "3DSketcher";
979   QStringList aParameters;
980
981   //int i = 0;
982   QList<XYZ>::const_iterator it;
983   for (it = myPointsList.begin(); it != myPointsList.end(); ++it) {
984     //aCoordsArray[i++] = (*it).x;
985     //aCoordsArray[i++] = (*it).y;
986     //aCoordsArray[i++] = (*it).z;
987     aCommands << (*it).command;
988     aParameters << (*it).params;
989   }
990
991   if (!myOK || myPointsList.size() == 0) {
992     XYZ xyz = getCurrentPoint();
993     //aCoordsArray[i++] = xyz.x;
994     //aCoordsArray[i++] = xyz.y;
995     //aCoordsArray[i++] = xyz.z;
996     aCommands << xyz.command;
997     aParameters << xyz.params;
998   }
999
1000 //   MESSAGE("aCommands.last() = "<< aCommands.last().toStdString());
1001   GEOM::GEOM_ICurvesOperations_var anOper = GEOM::GEOM_ICurvesOperations::_narrow(getOperation());
1002   //GEOM::GEOM_Object_var anObj = anOper->Make3DSketcher(aCoordsArray);
1003   GEOM::GEOM_Object_var anObj = anOper->Make3DSketcherCommand(aCommands.join(":").toLatin1().constData());
1004
1005   if (!anObj->_is_nil()) {
1006     if (!IsPreview()) anObj->SetParameters(aParameters.join(":").toLatin1().constData());
1007     objects.push_back(anObj._retn());
1008   }
1009
1010   return true;
1011 }
1012
1013 //=================================================================================
1014 // function : SetDoubleSpinBoxStep()
1015 // purpose  : Double spin box management
1016 //=================================================================================
1017 void EntityGUI_3DSketcherDlg::SetDoubleSpinBoxStep (double step)
1018 {
1019   Group3Spin->SpinBox_DX->setSingleStep(step);
1020   Group3Spin->SpinBox_DY->setSingleStep(step);
1021   Group3Spin->SpinBox_DZ->setSingleStep(step);
1022   GroupAngles->SpinBox_DA ->setSingleStep(step);
1023   GroupAngles->SpinBox_DA2->setSingleStep(step);
1024   GroupAngles->SpinBox_DL->setSingleStep(step);
1025   GroupAngles->SpinBox_DH->setSingleStep(step);
1026 }
1027
1028 //=================================================================================
1029 // function : ClickOnOk()
1030 // purpose  :
1031 //=================================================================================
1032 void EntityGUI_3DSketcherDlg::ClickOnOk()
1033 {
1034   Locker lock(myOK);
1035
1036   if (!onAccept())
1037     return;
1038
1039   ClickOnCancel();
1040 }
1041
1042 //=================================================================================
1043 // function : ClickOnApply()
1044 // purpose  :
1045 //=================================================================================
1046 bool EntityGUI_3DSketcherDlg::ClickOnApply()
1047 {
1048   QString msg;
1049   if (!isValid(msg)) {
1050     showError(msg);
1051     return false;
1052   }
1053
1054   if (myPointsList.count() > 0)
1055     myPointsList.append(myPointsList[0]);
1056
1057   Locker lock(myOK);
1058
1059   if (!onAccept())
1060     return false;
1061
1062   ClickOnCancel();
1063   return true;
1064 }
1065
1066 //=================================================================================
1067 // function : getLastPoint()
1068 // purpose  : return last points from list
1069 //=================================================================================
1070 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getLastPoint() const
1071 {
1072   return myPointsList.count() > 0 ? myPointsList.last() : XYZ();
1073 }
1074
1075 //=================================================================================
1076 // function : getPenultimatePoint()
1077 // purpose  : return penultimate point from list
1078 //=================================================================================
1079 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getPenultimatePoint() const
1080 {
1081   double size = myPointsList.count();
1082   return size > 1 ? myPointsList.at(size - 2) : XYZ();
1083 }
1084
1085 //=================================================================================
1086 // function : getCurrentPoint()
1087 // purpose  : returns current point
1088 //=================================================================================
1089 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getCurrentPoint() const
1090 {
1091   XYZ xyz;
1092
1093   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1094   int aPrecision = resMgr->integerValue("Geometry", "length_precision", 7);
1095   
1096   bool spherical   = GroupAngles->checkBox->isChecked();
1097   bool cylindrical = GroupAngles->checkBox_2->isChecked();
1098
1099   if (myCoordType == 1) 
1100   {
1101     if (GroupAngles->radioButton_1->isChecked())
1102       xyz.command = "OXY";
1103     else if (GroupAngles->radioButton_2->isChecked())
1104       xyz.command = "OYZ";
1105     else
1106       xyz.command = "OXZ";
1107     
1108     if (cylindrical)       // Cylindrical coordinates (radius, angle, height)
1109       xyz.command += "C";
1110     else
1111       xyz.command += "S";  // Spherical coordinates (radius, angle1, angle2) --> polar if angle2 = 0
1112     
1113     if (myMode == 0)       // Absolute coordinates
1114       xyz.command += "A ";
1115     else if (myMode == 1)  // Relative coordinates
1116       xyz.command += "R ";
1117       
1118
1119     double anAngle  = GroupAngles->SpinBox_DA->value();
1120     double aLength  = GroupAngles->SpinBox_DL->value();
1121
1122     double anAngle2 = 0.0;
1123     QString da2 = "0";
1124     if (spherical) {       // Spherical coordinates (radius, angle1, angle2)
1125       anAngle2 = GroupAngles->SpinBox_DA2->value();
1126       da2 = GroupAngles->SpinBox_DA2->text();
1127     }
1128     
1129     double aHeight = 0.0;
1130     QString dh = "0";
1131     if (cylindrical) {
1132       aHeight = GroupAngles->SpinBox_DH->value();
1133       dh = GroupAngles->SpinBox_DH->text();
1134     }
1135
1136     xyz.command +=
1137       QString::number(anAngle, 'g', aPrecision) + " ";
1138     xyz.params =
1139       GroupAngles->SpinBox_DA->text() + ":"; 
1140     
1141     if(cylindrical)
1142     {
1143       xyz.command +=
1144         QString::number(aHeight, 'g', aPrecision) + " ";
1145       xyz.params +=
1146         dh + ":";
1147     }
1148     else                  // Spherical or polar coordinates
1149     {
1150       xyz.command +=
1151         QString::number(anAngle2, 'g', aPrecision) + " ";
1152       xyz.params +=
1153         dh + ":";
1154     }
1155     
1156     xyz.command +=
1157       QString::number(aLength, 'g', aPrecision);
1158     xyz.params +=
1159       GroupAngles->SpinBox_DL->text();
1160
1161       
1162     // Calculate point coordinates for preview
1163     anAngle  = anAngle * M_PI/180.0;
1164     anAngle2 = anAngle2 * M_PI/180.0;
1165     double aProjectedLength = aLength * cos(anAngle2);
1166     
1167     XYZ xyzP = getLastPoint();
1168     if (myMode == 0)
1169       xyzP.x=xyzP.y=xyzP.z=0.0; 
1170     if (GroupAngles->radioButton_1->isChecked()) // OXY
1171     {
1172       xyz.x = xyzP.x + aProjectedLength * cos(anAngle);
1173       xyz.y = xyzP.y + aProjectedLength * sin(anAngle);
1174       if (cylindrical)
1175         xyz.z = xyzP.z + aHeight;
1176       else
1177         xyz.z = xyzP.z + aLength * sin(anAngle2);
1178     }
1179     else if (GroupAngles->radioButton_2->isChecked()) // OYZ
1180     {
1181       xyz.y = xyzP.y + aProjectedLength * cos(anAngle);
1182       xyz.z = xyzP.z + aProjectedLength * sin(anAngle);
1183       if (cylindrical)
1184         xyz.x = xyzP.x + aHeight;
1185       else
1186         xyz.x = xyzP.x + aLength * sin(anAngle2);
1187     }
1188     else // OXZ
1189     {
1190       xyz.z = xyzP.z + aProjectedLength * sin(anAngle);
1191       xyz.x = xyzP.x + aProjectedLength * cos(anAngle);
1192       if (cylindrical)
1193         xyz.y = xyzP.y + aHeight;
1194       else
1195         xyz.y = xyzP.y + aLength * sin(anAngle2);
1196     }
1197   }
1198   else if(myCoordType == 0) {
1199     if (myMode == 0) { // XYZ
1200       xyz.x = Group3Spin->SpinBox_DX->value();
1201       xyz.y = Group3Spin->SpinBox_DY->value();
1202       xyz.z = Group3Spin->SpinBox_DZ->value();
1203       xyz.command = "TT ";
1204     }
1205     else { // DXDYDZ
1206       xyz = getLastPoint();
1207       xyz.x += Group3Spin->SpinBox_DX->value();
1208       xyz.y += Group3Spin->SpinBox_DY->value();
1209       xyz.z += Group3Spin->SpinBox_DZ->value();
1210       xyz.command = "T ";
1211     }
1212
1213     double aX  = Group3Spin->SpinBox_DX->value();
1214     double aY  = Group3Spin->SpinBox_DY->value();
1215     double aZ  = Group3Spin->SpinBox_DZ->value();
1216
1217     xyz.command +=
1218       QString::number(aX, 'g', aPrecision) + " " +
1219       QString::number(aY, 'g', aPrecision) + " " +
1220       QString::number(aZ, 'g', aPrecision);
1221     xyz.params =
1222       Group3Spin->SpinBox_DX->text() + ":" +
1223       Group3Spin->SpinBox_DY->text() + ":" +
1224       Group3Spin->SpinBox_DZ->text();
1225   }
1226   // Update point presentation type
1227   xyz.A = myPrsType.A;  // Number of angle diomensions
1228   xyz.L = myPrsType.L;  // Number of length dimensions
1229   xyz.T = myPrsType.T;  // Number of text objects
1230   
1231   return xyz;
1232 }
1233
1234
1235 //=================================================================================
1236 // function : getPresentationPlane()
1237 // purpose  : returns the suitable plane for right
1238 //            relative positioning of dimension presentations
1239 //=================================================================================
1240 gp_Dir EntityGUI_3DSketcherDlg::getPresentationPlane() const
1241
1242   bool withAngle = (myCoordType == 1);
1243   bool twoAngles = GroupAngles->checkBox->isChecked();
1244   
1245   XYZ Last    = getLastPoint();
1246   XYZ Current;
1247   if( myIsUndoRedo ) {
1248       Current = myWorkPoint;
1249   } else {
1250     Current = getCurrentPoint();
1251   }
1252   
1253   XYZ Penultimate = getPenultimatePoint();
1254   
1255   gp_Pnt P1 = gp_Pnt(Last.x,Last.y,Last.z);
1256   if (myMode == 0) // Absolute coordinates
1257     P1 = gp::Origin();
1258   
1259   gp_Pnt P2 = gp_Pnt(Current.x,Current.y,Current.z);
1260   gp_Pnt P3 = gp_Pnt(Penultimate.x,Penultimate.y,Penultimate.z);
1261   
1262   gp_Vec Vec1(P1,P2);
1263   gp_Vec Vec2(P1,P3);
1264   
1265   gp_Dir aNormal;                  // Normal defining the plane of the presentation 
1266   
1267   if (withAngle)                   // If one angle
1268   {
1269     // Transformation from the current coordinate system 
1270     // to the reference coordinate system
1271     gp_Trsf aTransform = toReferenceSystem (P1);
1272     gp_Dir N1 = gp::DZ();
1273     gp_Dir N2 = gp::DY();
1274     N1.Transform(aTransform);
1275     N2.Transform(aTransform);
1276     
1277     if (Vec1.CrossMagnitude(N1) > Precision::Confusion())
1278     {
1279       // The plane is orthogonal to the angle presentation plane 
1280       // and contains the current edge
1281       aNormal = N1.Crossed(gp_Dir(Vec1));
1282     }
1283     else
1284       aNormal = N2;
1285
1286     if (twoAngles)
1287     { 
1288       gp_Vec V = Vec1.Transformed(aTransform.Inverted());
1289       gp_Vec Vec3(V.X(),V.Y(),0.0);
1290       
1291       // Express the coordinates in the refernce coordinate system (OXY)
1292       Vec3.Transform(aTransform);   
1293       if(Abs(Vec1.CrossMagnitude(Vec3)) > Precision::Confusion())                                  
1294       { 
1295         //  set the normal as the cross product of the current edge with its projection
1296         //  it ensures that the dimension changes side when the angle becomes negative
1297         aNormal = gp_Dir(Vec1.Crossed(Vec3));  
1298       } 
1299     }         
1300   }
1301   else
1302   {
1303     // Check colinearity
1304     if (Abs(Vec1.CrossMagnitude(Vec2)) < Precision::Confusion())
1305     {
1306       Vec2 = gp_Vec(gp::DX());
1307       if (Abs(Vec1.CrossMagnitude(Vec2)) < Precision::Confusion())
1308       {
1309         Vec2 = gp_Vec(gp::DY());
1310       }
1311     }
1312     // If no angles, the plane is the one formed by the last edge and the current one
1313     if(Abs(Vec1.CrossMagnitude(Vec2)) > Precision::Confusion()) {
1314       aNormal = gp_Dir(Vec1.Crossed(Vec2)); 
1315     }
1316   }
1317   return aNormal;
1318 }
1319
1320 //================================================================
1321 // Function : displayPreview
1322 // Purpose  : Method for displaying preview of resulting shape
1323 //            Redefined from GEOMBase_Helper.
1324 //================================================================
1325 void EntityGUI_3DSketcherDlg::displayPreview (GEOM::GEOM_Object_ptr object,
1326                                               const bool            append,
1327                                               const bool            activate,
1328                                               const bool            update,
1329                                               const double          lineWidth,
1330                                               const int             displayMode,
1331                                               const int             color)
1332 {
1333   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1334
1335   QColor aColor = resMgr->colorValue("Geometry","line_color",QColor(255,0,0));
1336   Quantity_NameOfColor line_color = SalomeApp_Tools::color(aColor).Name();
1337
1338   // set width of displayed shape
1339   int lw = lineWidth;
1340   if (lw == -1) {
1341     lw = resMgr->integerValue("Geometry", "preview_edge_width", -1);
1342   }
1343   getDisplayer()->SetWidth(lw);
1344
1345   // Disable activation of selection
1346   getDisplayer()->SetToActivate(activate);
1347
1348   // Make a reference to GEOM_Object
1349   CORBA::String_var objStr = myGeometryGUI->getApp()->orb()->object_to_string(object);
1350   getDisplayer()->SetName(objStr.in());
1351
1352   // Create wire from applied object
1353   TopoDS_Shape anApplyedWire, aLastSegment;
1354   if (!createShapes(object, anApplyedWire, aLastSegment))
1355     return;
1356
1357   // Set color for preview shape
1358   getDisplayer()->SetColor(line_color);
1359
1360   // Build prs
1361   SALOME_Prs* aPrs = getDisplayer()->BuildPrs(anApplyedWire);
1362   if (aPrs != 0 && !aPrs->IsNull())
1363     GEOMBase_Helper::displayPreview(aPrs, append, update);
1364
1365   getDisplayer()->SetColor(Quantity_NOC_VIOLET);
1366   aPrs = getDisplayer()->BuildPrs(aLastSegment);
1367
1368   if (aPrs != 0 && !aPrs->IsNull())
1369     GEOMBase_Helper::displayPreview(aPrs, append, update);
1370
1371   getDisplayer()->SetColor(line_color);
1372
1373   // Display local trihedron if the mode is relative
1374   if (myMode == 1)
1375     displayTrihedron(2);
1376
1377   // Display preview of suitable dimension presentations
1378   displayDimensions(false);
1379
1380   getDisplayer()->UnsetName();
1381
1382   // Enable activation of displayed objects
1383   getDisplayer()->SetToActivate(true);
1384 }
1385
1386 //================================================================
1387 // Function : displayTrihedron()
1388 // Purpose  : Method for displaying trihedron
1389 //================================================================
1390 void EntityGUI_3DSketcherDlg::displayTrihedron (int selMode)
1391 {
1392   // Add trihedron to preview
1393   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1394
1395   gp_Pnt P(getLastPoint().x,getLastPoint().y,getLastPoint().z);
1396   Handle(Geom_Axis2Placement) anAxis = new Geom_Axis2Placement(P,gp::DZ(),gp::DX());
1397   Handle(AIS_Trihedron) anIO = new AIS_Trihedron(anAxis);
1398   anIO->SetSelectionMode(selMode);
1399
1400   SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1401     (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1402
1403   if (aSPrs) {
1404     aSPrs->PrependObject(anIO);
1405     GEOMBase_Helper::displayPreview(aSPrs, true, true);
1406   }
1407 }
1408
1409 //================================================================
1410 // Function : displayDimensions( bool store )
1411 // Purpose  : Method for displaying dimensions. If store = true
1412 //            the presentation is stored in a list
1413 //================================================================
1414 void EntityGUI_3DSketcherDlg::displayDimensions (bool store)
1415 {
1416   myPrsType   = prsType();
1417   XYZ Last    = getLastPoint();
1418   XYZ Current = getCurrentPoint();
1419
1420   gp_Pnt Last_Pnt(Last.x,Last.y,Last.z);
1421   
1422   gp_Pnt P0 = Last_Pnt;
1423   gp_Pnt Origin = gp::Origin();
1424   if (myMode == 0)                 // Absolute coordinates
1425     P0 = Origin;
1426   
1427   gp_Pnt Current_Pnt(Current.x,Current.y,Current.z);
1428   gp_Pnt P1, P2;
1429   
1430   // Check if last end current point are coincident
1431   if (Last_Pnt.IsEqual(Current_Pnt, 1e-7))
1432     return;
1433   
1434   gp_Dir aNormal = getPresentationPlane();
1435   
1436   if (myCoordType == 0)
1437   {
1438     bool oneDimensionalMove =  (isSame(Last_Pnt.X(), Current_Pnt.X()) && 
1439                                 isSame(Last_Pnt.Y(), Current_Pnt.Y()) ) ||
1440                                (isSame(Last_Pnt.Y(), Current_Pnt.Y()) && 
1441                                 isSame(Last_Pnt.Z(), Current_Pnt.Z()) ) ||
1442                                (isSame(Last_Pnt.X(), Current_Pnt.X()) && 
1443                                 isSame(Last_Pnt.Z(), Current_Pnt.Z()) );
1444      
1445     if (myMode == 0)
1446     {
1447       std::string aCoordText = "( " + doubleToString(Current_Pnt.X()) + 
1448                                ", " + doubleToString(Current_Pnt.Y()) +
1449                                ", " + doubleToString(Current_Pnt.Z()) + " )";
1450       displayText(aCoordText, Current_Pnt, store);
1451     }
1452     else 
1453     { 
1454       if (oneDimensionalMove)
1455       {
1456         // For better colocation of dimensions if only one coordinate changes (aNormal is a better choice)
1457         displayLength(P0, Current_Pnt, aNormal, store);
1458       }
1459       else
1460       {
1461         displayLength(gp_Pnt(P0.X(),Current.y,P0.Z()), gp_Pnt(Current.x,Current.y,P0.Z()), gp::DZ().Reversed(), store);
1462         displayLength(gp_Pnt(Current.x,P0.Y(),P0.Z()), gp_Pnt(Current.x,Current.y,P0.Z()), gp::DZ(), store);
1463         displayLength(gp_Pnt(Current.x,Current.y,P0.Z()), Current_Pnt, gp::DX(), store);
1464       }
1465     }
1466   }
1467   else if (myCoordType == 1)             // ANGLES
1468   {
1469     bool spherical   = GroupAngles->checkBox->isChecked(); 
1470     bool cylindrical = GroupAngles->checkBox_2->isChecked();
1471     
1472     double anAngle1 = GroupAngles->SpinBox_DA->value();
1473     double aLength  = GroupAngles->SpinBox_DL->value();
1474     
1475     // Set the coordinates in the current coordinate system
1476     P1.SetCoord( aLength, 0.0, 0.0);    // X direction
1477     P2.SetCoord( aLength * cos(anAngle1 * M_PI / 180. ),
1478                  aLength * sin(anAngle1 * M_PI / 180. ),
1479                  0.0); 
1480     
1481     // Express the coordinates in the refernce coordinate system (OXY)
1482     gp_Trsf aTranform = toReferenceSystem(P0);
1483     P1.Transform(aTranform);    
1484     P2.Transform(aTranform);
1485     P1.Translate(Origin, P0);
1486     P2.Translate(Origin, P0);
1487     
1488     if(myMode !=0  || !store)
1489       displayAngle(anAngle1, P0, P1, P2, store);
1490     else
1491     {
1492       std::string anAngleText = doubleToString(anAngle1) + " deg.";
1493       displayText(anAngleText, Current_Pnt, store);
1494     }
1495     
1496     if(spherical)
1497     {
1498       double anAngle2 = GroupAngles->SpinBox_DA2->value();
1499       displayAngle(anAngle2, P0, P2, Current_Pnt, store);
1500       displayLength(P0, Current_Pnt, aNormal, store);
1501     }
1502     else
1503     {
1504       bool sameRadius = isSame ( radius(Last_Pnt), radius(Current_Pnt) );
1505       bool sameHeight = isSame ( height(Last_Pnt), height(Current_Pnt) );
1506                             
1507       gp_Vec aVec(P2, Current_Pnt);
1508       
1509       if (myMode == 0 && !sameRadius)
1510       {
1511         displayLength(P0.Translated(aVec), P2.Translated(aVec), aNormal, store);  // Radius  
1512       }
1513       else if (myMode == 1)
1514         displayLength(P0, P2, aNormal, store);
1515       
1516       if ( cylindrical && 
1517           (myMode == 1 || !sameHeight) )
1518         displayLength(P2, Current_Pnt, aNormal.Reversed(), store); // Height
1519     }
1520   }
1521 }
1522
1523 //================================================================
1524 // Function : displayAngle()
1525 // Purpose  : Method for displaying angle dimensions
1526 //================================================================
1527 void EntityGUI_3DSketcherDlg::displayAngle (double theAngle,
1528                                             gp_Pnt P0, 
1529                                             gp_Pnt P1, 
1530                                             gp_Pnt P2,
1531                                             bool store)
1532 {
1533   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1534   
1535   // Creation of the AIS object
1536   Handle(AIS_AngleDimension) anAngleIO = createAISAngleDimension(theAngle, 
1537                                                                  P0, 
1538                                                                  P1, 
1539                                                                  P2);
1540   if (anAngleIO == NULL)
1541     return;
1542   
1543   if (store)
1544   {
1545     // Erase dimensions presentations
1546     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
1547     myAnglePrs->PrependObject(anAngleIO);
1548     
1549     // Display modified presentation
1550     if (isAngleVisible)
1551       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
1552     
1553     // Update dimension presentation angle count for later undo / redo
1554     myPrsType.A += 1;
1555   }
1556   else if ( isAngleVisible)
1557   {
1558     SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1559         (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1560         
1561     if (aSPrs)
1562     {
1563       aSPrs->AddObject(anAngleIO);
1564       GEOMBase_Helper::displayPreview(aSPrs, true, true); 
1565     }
1566   }
1567 }
1568
1569
1570 //================================================================
1571 // Function : displayLength()
1572 // Purpose  : Method for displaying length dimensions for a segment
1573 //            creation step
1574 //================================================================
1575 void EntityGUI_3DSketcherDlg::displayLength (gp_Pnt P1,
1576                                              gp_Pnt P2,
1577                                              gp_Dir theNormal,
1578                                              bool store)
1579 {
1580   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1581   
1582   double aLength = P1.Distance(P2);
1583   
1584   if (aLength < Precision::Confusion())
1585     return;
1586     
1587   Handle(AIS_LengthDimension) anIO = createAISLengthDimension(aLength, P1, P2, theNormal);
1588
1589   if (store)
1590   {
1591     // Erase length dimensions presentation
1592     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
1593     myLengthPrs->PrependObject(anIO);
1594
1595     // Display modified presentation
1596     if (isLengthVisible)
1597       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
1598     
1599     // Update dimension presentation length count for later undo / redo
1600     myPrsType.L += 1;
1601   }
1602   else if (isLengthVisible)
1603   {
1604     SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1605       (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1606     if (aSPrs)
1607     {
1608       aSPrs->PrependObject(anIO);
1609       GEOMBase_Helper::displayPreview(aSPrs, true, true);
1610     }
1611   }
1612 }
1613
1614 //================================================================
1615 // Function : displayText()
1616 // Purpose  : Method for displaying length dimensions for a segment
1617 //            creation step
1618 //================================================================
1619 void EntityGUI_3DSketcherDlg::displayText ( std::string theText,
1620                                             gp_Pnt P,
1621                                             bool store )
1622 {
1623   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1624     
1625   Handle(AIS_Text) anIO = new AIS_Text(TCollection_ExtendedString(theText.c_str()), P);
1626
1627   if (store)
1628   {
1629     // Erase length dimensions presentation
1630     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myTextPrs, true);
1631     myTextPrs->PrependObject(anIO);
1632
1633     // Display modified presentation
1634     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myTextPrs);
1635     
1636     // Update dimension presentation text count for later undo / redo
1637     myPrsType.T += 1;
1638   }
1639   else
1640   {
1641     SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1642       (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1643     if (aSPrs)
1644     {
1645       aSPrs->PrependObject(anIO);
1646       GEOMBase_Helper::displayPreview(aSPrs, true, true);
1647     }
1648   }
1649
1650 }
1651
1652 //================================================================
1653 // Function : createAISLengthDimension()
1654 // Purpose  : Method for creation of a length dimension object
1655 //            Returns an Handle on the AIS_LengthDimension obect
1656 //================================================================
1657 Handle(AIS_LengthDimension) EntityGUI_3DSketcherDlg::createAISLengthDimension(double theLength, 
1658                                                                               gp_Pnt P1, 
1659                                                                               gp_Pnt P2, 
1660                                                                               gp_Dir theNormal)
1661 {
1662   // Plane construction
1663   gce_MakePln gce_MP(P1, theNormal);
1664   Handle(Geom_Plane) aPlane = new Geom_Plane(gce_MP.Value());
1665   
1666   TopoDS_Vertex aVert1 = BRepBuilderAPI_MakeVertex(P1);
1667   TopoDS_Vertex aVert2 = BRepBuilderAPI_MakeVertex(P2);
1668
1669   Handle(AIS_LengthDimension) anIO = new AIS_LengthDimension( aVert1, aVert2, aPlane->Pln() );
1670
1671   anIO->SetCustomValue( theLength );
1672
1673   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1674   int w = resMgr->integerValue( "Geometry", "measures_line_width", 1 );
1675
1676   Handle(Prs3d_DimensionAspect) aDimensionStyle = new Prs3d_DimensionAspect;
1677
1678   aDimensionStyle->ArrowAspect()->SetLength( theLength / 20.0 );
1679   aDimensionStyle->LineAspect()->SetWidth( w );
1680   aDimensionStyle->MakeText3d( Standard_False );
1681   aDimensionStyle->SetTextHorizontalPosition( Prs3d_DTHP_Center );
1682   aDimensionStyle->SetTextVerticalPosition( Prs3d_DTVP_Center );
1683   aDimensionStyle->MakeArrows3d( Standard_True );
1684   anIO->SetFlyout( 0.0 );
1685   anIO->SetDimensionAspect( aDimensionStyle );
1686
1687   return anIO;
1688 }
1689
1690 //================================================================
1691 // Function : createAISAngleDimension()
1692 // Purpose  : Method for creation of an angle dimension object
1693 //            Returns an Handle on the AIS_AngleDimension obect
1694 //================================================================
1695 Handle(AIS_AngleDimension) EntityGUI_3DSketcherDlg::createAISAngleDimension(double theAngle, 
1696                                                                             gp_Pnt P0, 
1697                                                                             gp_Pnt P1, 
1698                                                                             gp_Pnt P2)
1699 {
1700   // Length of the built segment
1701   double aLength = P0.Distance(P1);
1702   
1703   // Check input data
1704   if (Abs(theAngle) < Precision::Angular() ||
1705       aLength < Precision::Confusion())
1706     return NULL;
1707
1708   Handle(AIS_AngleDimension) anIO = new AIS_AngleDimension( P1, P0, P2 );
1709
1710   //anIO->SetCustomValue( theAngle );
1711
1712   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1713   int w = resMgr->integerValue( "Geometry", "measures_line_width", 1 );
1714
1715   Handle(Prs3d_DimensionAspect) aDimensionStyle = new Prs3d_DimensionAspect;
1716
1717   aDimensionStyle->ArrowAspect()->SetLength( (theAngle * M_PI / 180.0) * (aLength / 20.0) );
1718   aDimensionStyle->LineAspect()->SetWidth( w );
1719   aDimensionStyle->SetTextHorizontalPosition( Prs3d_DTHP_Center );
1720   aDimensionStyle->SetTextVerticalPosition( Prs3d_DTVP_Center );
1721   aDimensionStyle->MakeText3d( Standard_False );
1722   aDimensionStyle->MakeArrows3d( Standard_True );
1723
1724   anIO->SetDimensionAspect( aDimensionStyle );
1725
1726   return anIO;
1727 }
1728
1729 //================================================================
1730 // Function : createShapes
1731 // Purpose  : Create applyed wire, and last segment from entry object
1732 //================================================================
1733 bool EntityGUI_3DSketcherDlg::createShapes (GEOM::GEOM_Object_ptr /*theObject*/,
1734                                             TopoDS_Shape&         theApplyedWire,
1735                                             TopoDS_Shape&         theLastSegment)
1736 {
1737   QList<gp_Pnt> points;
1738   foreach (XYZ xyz, myPointsList) {
1739     gp_Pnt p(xyz.x, xyz.y, xyz.z);
1740     if (points.isEmpty() || points.last().Distance(p) > gp::Resolution())
1741       points << p;
1742   }
1743
1744   if (points.count() == 1) {
1745     // only one point is created
1746     BRepBuilderAPI_MakeVertex mkVertex (points.last());
1747     theApplyedWire = mkVertex.Shape();
1748   }
1749   else if (points.count() > 1) {
1750     // wire is created
1751     BRepBuilderAPI_MakePolygon mkWire;
1752     foreach(gp_Pnt p, points)
1753       mkWire.Add(p);
1754     theApplyedWire = mkWire.Shape();
1755   }
1756
1757   XYZ curxyz = getCurrentPoint();
1758   gp_Pnt curpnt(curxyz.x, curxyz.y, curxyz.z);
1759
1760   if (points.isEmpty() || points.last().Distance(curpnt) <= gp::Resolution()) {
1761     BRepBuilderAPI_MakeVertex mkVertex (curpnt);
1762     theLastSegment = mkVertex.Shape();
1763   }
1764   else {
1765     BRepBuilderAPI_MakeEdge mkEdge(points.last(), curpnt);
1766     theLastSegment = mkEdge.Shape();
1767   }
1768
1769   /* VSR: old algorithm does not work properly, see bug 0020899
1770   TopoDS_Shape aShape;
1771   if (!GEOMBase::GetShape(theObject, aShape))
1772     return false;
1773
1774   if (aShape.ShapeType() != TopAbs_WIRE && aShape.ShapeType() != TopAbs_VERTEX)
1775     return false;
1776
1777   theApplyedWire = aShape;
1778   if (myOK)
1779      return true;
1780
1781   BRepBuilderAPI_MakeWire aBuilder;
1782   TopExp_Explorer edgeExp(aShape, TopAbs_EDGE);
1783   while (1) {
1784     TopoDS_Shape anEdge = edgeExp.Current();
1785     edgeExp.Next();
1786     if (edgeExp.More()) // i.e. non-last edge
1787       aBuilder.Add(TopoDS::Edge(anEdge));
1788     else {
1789       theLastSegment = anEdge;
1790       break;
1791     }
1792   }
1793
1794   if (aBuilder.IsDone()) {
1795     theApplyedWire = aBuilder.Shape();
1796   }
1797   else if (!theLastSegment.IsNull()) {
1798     TopExp_Explorer vertexExp(theLastSegment, TopAbs_VERTEX);
1799     theApplyedWire = vertexExp.Current();
1800     }
1801   */
1802
1803   return true;
1804 }
1805
1806 //================================================================
1807 // Function : doubleToString
1808 // Purpose  : converts double to string
1809 //================================================================
1810 std::string EntityGUI_3DSketcherDlg::doubleToString (double num)
1811 {
1812   // truncate num
1813   int digNum = 5;
1814   char format = 'g'; // truncated to a number of significant digits
1815
1816   return QString::number(num, format, digNum).toStdString();
1817 }
1818
1819 //================================================================
1820 // Function : toReferenceSystem ()
1821 // Purpose  :
1822 //================================================================
1823 gp_Trsf EntityGUI_3DSketcherDlg::toReferenceSystem(gp_Pnt origin) const
1824
1825   gp_Trsf T;                        // Identity transformation
1826   gp_Ax3 reference_system;          // OXY
1827   reference_system.SetLocation(origin);
1828   
1829   gp_Ax3 current_system = reference_system;
1830   switch (myOrientation)
1831   {
1832     case OYZ:
1833     {
1834       current_system = gp_Ax3(origin, gp::DX(), gp::DY());
1835       break;
1836     }
1837     case OXZ:
1838     {
1839       current_system = gp_Ax3(origin, gp::DY().Reversed(), gp::DX());
1840       break;
1841     }
1842   }
1843   
1844   T.SetTransformation( current_system, reference_system );
1845   
1846   return T;
1847 }
1848
1849 //================================================================
1850 // Function : toCurrentSystem ()
1851 // Purpose  :
1852 //================================================================
1853 gp_Trsf EntityGUI_3DSketcherDlg::toCurrentSystem(gp_Pnt origin) const
1854 {
1855   return toReferenceSystem(origin).Inverted();
1856 }
1857
1858 //================================================================
1859 // Function : radius (gp_Pnt) const
1860 // Purpose  :
1861 //================================================================
1862 double EntityGUI_3DSketcherDlg::radius (gp_Pnt thePnt) const
1863 {
1864   // Get the point coordinates in the current coordinates system
1865   gp_Trsf aTrsf = toCurrentSystem(gp::Origin());
1866   gp_Pnt aPnt = thePnt.Transformed(aTrsf);
1867   
1868   double radius = sqrt(aPnt.X()*aPnt.X() + aPnt.Y()*aPnt.Y());
1869   return radius;
1870 }
1871
1872 //================================================================
1873 // Function : height (gp_Pnt) const
1874 // Purpose  :
1875 //================================================================
1876 double EntityGUI_3DSketcherDlg::height (gp_Pnt thePnt) const
1877 {
1878   // Get the point coordinates in the current coordinates system
1879   gp_Trsf aTrsf = toCurrentSystem(gp::Origin());
1880   gp_Pnt aPnt = thePnt.Transformed(aTrsf);
1881   
1882   return aPnt.Z();
1883 }