Salome HOME
fd7b8688942cac1e6390adb2249e2156e106103e
[modules/geom.git] / src / EntityGUI / EntityGUI_3DSketcherDlg.cxx
1 // Copyright (C) 2007-2016  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 <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>
76
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>
81
82 // TODO
83 //
84 // Avoid duplication of angle coordinates in cylindrical mode
85 // Check spherical mode in absolute
86
87 enum
88 {
89   OXY,
90   OYZ,
91   OXZ
92 };
93
94 class Locker
95 {
96 public:
97   Locker(bool& l) : myLock(l) { myLock = true;  }
98   ~Locker()                   { myLock = false; }
99 private:
100   bool& myLock;
101 };
102
103 DEFINE_STANDARD_HANDLE(AIS_Text, AIS_InteractiveObject)
104
105 class AIS_Text:public AIS_InteractiveObject
106 {
107 public:
108   OCCT_DEFINE_STANDARD_RTTIEXT(AIS_Text,AIS_InteractiveObject)
109
110   AIS_Text(){};
111
112   AIS_Text
113     (
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
123     );
124
125 private:
126
127   void Compute (  const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
128                   const Handle(Prs3d_Presentation)& aPresentation,
129                   const Standard_Integer aMode);
130
131   void ComputeSelection (  const Handle(SelectMgr_Selection)& aSelection,
132                            const Standard_Integer aMode){} ;
133
134 protected:
135   TCollection_ExtendedString          aText;
136   gp_Pnt                              aPosition;
137   Standard_Real                       Red;
138   Standard_Real                       Green;
139   Standard_Real                       Blue;
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;
148 };
149
150 OCCT_IMPLEMENT_STANDARD_RTTIEXT(AIS_Text, AIS_InteractiveObject)
151
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")
161 {
162   aText           = text;
163   aPosition       = position;
164   aHJustification = Graphic3d_HorizontalTextAlignment(aHJust);
165   aVJustification = Graphic3d_VerticalTextAlignment(aVJust);
166   aAngle          = angle;
167   aZoomable       = zoomable;
168   aHeight         = height;
169   aColor          = color;
170   aFontAspect     = fontAspect;
171   aFont           = font;
172 };
173
174 void AIS_Text::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
175                           const Handle(Prs3d_Presentation)& aPresentation,
176                           const Standard_Integer aMode)
177 {
178
179   aPresentation->Clear();
180
181   Handle(Prs3d_TextAspect) asp = myDrawer->TextAspect();
182
183   asp->SetFont(aFont);
184   asp->SetColor(aColor);
185   asp->SetHeight(aHeight); // I am changing the myHeight value
186
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);
193 };
194
195 bool isSame (double d1, double d2)
196
197   return Abs(d1 - d2) <= Precision::Confusion();
198 }
199
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),
211     myMode(-1),
212     myOK(false),
213     myLineWidth(lineWidth),
214     myGeometryGUI(theGeometryGUI),
215     myLengthIORedoList(),
216     myIsUndoRedo(false)
217 {
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")));
222
223   setWindowTitle(tr("GEOM_3DSKETCHER_TITLE"));
224
225   /***************************************************************/
226
227   mainFrame()->GroupConstructors->setTitle(tr("GEOM_3DSKETCHER"));
228   mainFrame()->RadioButton1->setIcon(image3);;
229   mainFrame()->RadioButton2->close();
230   mainFrame()->RadioButton3->close();
231
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"));
239  
240   myTypeGroup1 = new QButtonGroup(this);
241   myTypeGroup1->setExclusive(true);
242   myTypeGroup1->addButton(GroupType->RadioButton1, 0);
243   myTypeGroup1->addButton(GroupType->RadioButton2, 1);
244   
245   myTypeGroup2 = new QButtonGroup(this);
246   myTypeGroup2->setExclusive(true);
247   myTypeGroup2->addButton(GroupType->RadioButton3, 0);
248   myTypeGroup2->addButton(GroupType->RadioButton4, 1);
249
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"));
258
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"));
267
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"));
287
288   buttonOk()->setText(tr("GEOM_BUT_END_SKETCH"));
289   buttonApply()->setText(tr("GEOM_BUT_CLOSE_SKETCH"));
290
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);
297
298   setHelpFileName("create_3dsketcher_page.html");
299
300   resize(100,100);
301   Init();
302 }
303
304 //=================================================================================
305 // function : ~EntityGUI_3DSketcherDlg()
306 // purpose  : Destroys the object and frees any allocated resources
307 //=================================================================================
308 EntityGUI_3DSketcherDlg::~EntityGUI_3DSketcherDlg()
309 {
310   myGeomGUI->SetActiveDialogBox(0);
311 }
312
313 //=================================================================================
314 // function : Init()
315 // purpose  :
316 //=================================================================================
317 void EntityGUI_3DSketcherDlg::Init()
318 {
319   myOK = false;
320   myOrientation = OXY;
321   myPrsType = prsType();
322
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));
327
328   localSelection(TopAbs_VERTEX);
329
330   /* Get setting of step value from file configuration */
331   double step = SUIT_Session::session()->resourceMgr()->doubleValue("Geometry", "SettingsGeomStep", 100.0);
332
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");
337
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");
342
343   Group3Spin->SpinBox_DX->setValue(0.0);
344   Group3Spin->SpinBox_DY->setValue(0.0);
345   Group3Spin->SpinBox_DZ->setValue(0.0);
346
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);
351
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);
357
358   GroupControls->CheckBox1->setChecked(true);
359   GroupControls->CheckBox2->setChecked(true);
360   GroupControls->CheckBox3->setChecked(true);
361   
362   isLengthVisible = true;
363   isAngleVisible = true;
364
365   GroupAngles->hide();
366
367   /* signals and slots connections */
368   connect(buttonOk(),     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
369   connect(buttonApply(),  SIGNAL(clicked()), this, SLOT(ClickOnApply()));
370
371   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
372
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())) ;
376
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())) ;
380
381   connect(myTypeGroup1, SIGNAL(buttonClicked(int)),  this, SLOT(TypeClicked(int)));
382   connect(myTypeGroup2, SIGNAL(buttonClicked(int)),  this, SLOT(TypeClicked(int)));
383
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)));
387
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)));
392
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))) ;
396
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))) ;
402
403   connect(myGeomGUI, SIGNAL(SignalDefaultStepValueChanged(double)), this, SLOT(SetDoubleSpinBoxStep(double)));
404
405   connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
406   connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()),        this, SLOT(ClickOnCancel()));
407
408   initName(tr("GEOM_3DSKETCHER"));
409   
410   GroupControls->CheckBox3->click();
411
412   UpdateButtonsState();
413   
414   myMode      = 0;
415   myCoordType = 0;
416   
417   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
418 }
419
420 //=================================================================================
421 // function : TypeClicked()
422 // purpose  : Radio button management
423 //=================================================================================
424 void EntityGUI_3DSketcherDlg::TypeClicked (int id)
425 {
426   QButtonGroup* send = (QButtonGroup*) sender();
427   
428   int coordType = myCoordType;
429   int mode      = myMode;
430   
431   if (send == myTypeGroup1)
432   {
433     if(id == myMode) return;
434     mode = id;   
435   }
436   else if (send == myTypeGroup2)
437   {
438     if (id == myCoordType) return;
439     coordType = id;  
440   }
441   
442   GroupAngles->hide();
443   Group3Spin->show();
444
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);
449
450   // Get setting of step value from file configuration
451   XYZ xyz = getLastPoint();
452   bool okx, oky, okz;
453   Group3Spin->SpinBox_DX->text().toDouble(&okx);
454   Group3Spin->SpinBox_DY->text().toDouble(&oky);
455   Group3Spin->SpinBox_DZ->text().toDouble(&okz);
456
457   if (coordType == 0)  // Cartesian coordinates
458   {
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)
464       {
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());
468       }
469       Group3Spin->buttonApply->setFocus();
470     }
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)
476       {
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);
480       }
481       Group3Spin->buttonApply->setFocus();
482     }
483   }
484   else if (coordType == 1) // Angles and Length
485   {
486     Group3Spin->hide();
487     GroupAngles->show();
488     GroupAngles->buttonApply->setFocus();
489   }
490
491   Group3Spin->SpinBox_DX->blockSignals(blocked);
492   Group3Spin->SpinBox_DY->blockSignals(blocked);
493   Group3Spin->SpinBox_DZ->blockSignals(blocked);
494
495   myMode = mode;
496   myCoordType = coordType;
497
498   updateGeometry();
499   resize(minimumSizeHint());
500
501   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
502 }
503
504 //=================================================================================
505 // function : ClickOnAddPoint()
506 // purpose  : called when the point coordinates is Applyed
507 //=================================================================================
508 void EntityGUI_3DSketcherDlg::ClickOnAddPoint()
509
510   QString msg;
511   if (!isValid(msg)) {
512     showError(msg);
513     return;
514   }
515   
516   myPrsType   = prsType();
517   
518 //   if(myMode == 1)
519     displayDimensions( /*store = */true);
520
521   myPointsList.append(getCurrentPoint());
522   myRedoList.clear();
523   myLengthIORedoList.Clear();
524   myAngleIORedoList.Clear();
525   myTextIORedoList.Clear();
526
527   if (myCoordType == 0 && myMode == 1)     // RELATIVE CARTESIAN COORDINATES
528   {
529     Group3Spin->SpinBox_DX->setValue(0.0);
530     Group3Spin->SpinBox_DY->setValue(0.0);
531     Group3Spin->SpinBox_DZ->setValue(0.0);
532   }
533   else if (myCoordType == 1 && myMode == 1) // RELATIVE ANGULAR COORDINATES
534   {
535     GroupAngles->SpinBox_DA->setValue(0.0);
536     GroupAngles->SpinBox_DL->setValue(0.0);
537     GroupAngles->SpinBox_DA2->setValue(0.0);
538   }
539   
540   UpdatePointCoordinates();
541     
542   UpdateButtonsState();
543   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
544 }
545
546 //=================================================================================
547 // function : UpdateButtonsState()
548 // purpose  :
549 //=================================================================================
550 void EntityGUI_3DSketcherDlg::UpdateButtonsState()
551 {
552   if (myPointsList.count() == 0) 
553   {
554     GroupType->RadioButton1->click();
555     GroupType->RadioButton3->click();
556   }
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);
564 }
565
566 //=================================================================================
567 // function : UpdatePointCoordinates()
568 // purpose  :Update point coordinates in the control groupbox
569 //=================================================================================
570 void EntityGUI_3DSketcherDlg::UpdatePointCoordinates()
571 {
572   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
573   int aPrecision = resMgr->integerValue("Geometry", "length_precision", 6);
574   
575   if (myPointsList.count() == 0)
576   {
577     GroupControls->lineEdit_1->setText("");
578     GroupControls->lineEdit_2->setText("");
579     GroupControls->lineEdit_3->setText("");
580     
581     GroupControls->lineEdit_4->setText("");
582     GroupControls->lineEdit_5->setText("");
583     GroupControls->lineEdit_6->setText("");
584   }
585   else if (myPointsList.count() == 1)
586   {
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));
590     
591     GroupControls->lineEdit_4->setText("");
592     GroupControls->lineEdit_5->setText("");
593     GroupControls->lineEdit_6->setText("");
594   }
595   else
596   {
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));
600   }
601   
602 }
603
604 //=================================================================================
605 // function : ClickOnUndo()
606 // purpose  :
607 //=================================================================================
608 void EntityGUI_3DSketcherDlg::ClickOnUndo()
609 {
610   myIsUndoRedo = true;
611   if (myPointsList.count() > 0) {
612     
613     myRedoList.append(myPointsList.last());
614
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);
620     
621     removeLastIOFromPrs();
622
623     // Display modified presentation
624     if (isLengthVisible)
625       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
626     if (isAngleVisible)
627       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
628     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myTextPrs);
629     
630     // Remove last point from list
631     myWorkPoint = myPointsList.last();
632     myPointsList.removeLast();
633     GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
634     UpdateButtonsState();
635     
636     // Update of point coordinates in the control groupbox
637     UpdatePointCoordinates();
638
639     updateViewer();
640   }
641   myIsUndoRedo = false;
642 }
643
644 //=================================================================================
645 // function : ClickOnRedo()
646 // purpose  :
647 //=================================================================================
648 void EntityGUI_3DSketcherDlg::ClickOnRedo()
649 {
650   myIsUndoRedo = true;
651   if (myRedoList.count() > 0) {
652     
653     myPointsList.append(myRedoList.last());
654
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);
660     
661     restoreLastIOToPrs();
662
663     // Display modified presentation
664     if (isLengthVisible)
665       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
666     if (isAngleVisible)
667       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
668     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myTextPrs);
669     
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();
675     
676     // Update of point coordinates in the control groupbox
677     UpdatePointCoordinates();
678
679     updateViewer();
680   }
681   myIsUndoRedo = false;
682 }
683
684 //=================================================================================
685 // function : removeLastIO()
686 // purpose  :
687 //=================================================================================
688 void EntityGUI_3DSketcherDlg::removeLastIOFromPrs ()
689 {
690   AIS_ListOfInteractive anIOList;
691   XYZ Last = getLastPoint();
692   
693   for (int l = 0; l<Last.L; l++)
694   {
695     myLengthPrs->GetObjects(anIOList);
696     myLengthIORedoList.Prepend(anIOList.First());  // Store last prepended Length IO in redo list
697     myLengthPrs->RemoveFirst();                    // Remove it from myLengthPrs
698   }
699   for (int a = 0; a<Last.A; a++)
700   {
701     myAnglePrs->GetObjects(anIOList);
702     myAngleIORedoList.Prepend(anIOList.First());  // Store last prepended Angle IO in redo list
703     myAnglePrs->RemoveFirst();                    // Remove it from myAnglePrs
704   }
705   for (int t = 0; t<Last.T; t++)
706   {
707     myTextPrs->GetObjects(anIOList);
708     myTextIORedoList.Prepend(anIOList.First());  // Store last prepended Text IO in redo list
709     myTextPrs->RemoveFirst();                    // Remove it from myTextPrs
710   }
711 }
712
713 //=================================================================================
714 // function : restoreLastIO()
715 // purpose  :
716 //=================================================================================
717 void EntityGUI_3DSketcherDlg::restoreLastIOToPrs ()
718 {
719   XYZ LastDeleted = myRedoList.last();
720   
721   for (int l = 0; l<LastDeleted.L; l++)
722   {
723     myLengthPrs->PrependObject(myLengthIORedoList.First()); // Restore last removed IO
724     myLengthIORedoList.RemoveFirst();                       // Remove it from redo list
725   } 
726   for (int a = 0; a<LastDeleted.A; a++)
727   {
728     myAnglePrs->PrependObject(myAngleIORedoList.First());  // Restore last removed IO
729     myAngleIORedoList.RemoveFirst();                       // Remove it from redo list
730   }
731   for (int t = 0; t<LastDeleted.T; t++)
732   {
733     myTextPrs->PrependObject(myTextIORedoList.First());  // Restore last removed IO
734     myTextIORedoList.RemoveFirst();                       // Remove it from redo list
735   }
736 }
737
738 //=================================================================================
739 // function : SelectionIntoArgument()
740 // purpose  : Called when selection as changed
741 //=================================================================================
742 void EntityGUI_3DSketcherDlg::SelectionIntoArgument()
743 {
744   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
745   SALOME_ListIO aSelList;
746   aSelMgr->selectedObjects(aSelList);
747
748   int nbSel = aSelList.Extent();
749   if (nbSel == 1) {
750     GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject(aSelList.First());
751     if (!CORBA::is_nil(aSelectedObject)) {
752       TopoDS_Shape aShape;
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);
761         }
762       }
763       bool isOk = true;
764       if (aShape.ShapeType() != TopAbs_VERTEX)
765         isOk = GEOMBase::GetShape(aSelectedObject, aShape, TopAbs_VERTEX);
766       if (isOk) {
767         gp_Pnt aPnt;
768         if (GEOMBase::VertexToPoint(aShape, aPnt)) {
769           // set coordinates to the Spin Boxes
770           double aX, aY, aZ;
771           aX = aPnt.X();
772           aY = aPnt.Y();
773           aZ = aPnt.Z();
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);
782           }
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);
788           }
789           Group3Spin->SpinBox_DX->blockSignals(blocked);
790           Group3Spin->SpinBox_DY->blockSignals(blocked);
791           Group3Spin->SpinBox_DZ->blockSignals(blocked);
792         }
793       }
794     }
795   }
796   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
797 }
798
799 //=================================================================================
800 // function : DeactivateActiveDialog()
801 // purpose  :
802 //=================================================================================
803 void EntityGUI_3DSketcherDlg::DeactivateActiveDialog()
804 {
805   setEnabled(false);
806   globalSelection();
807   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
808   myGeomGUI->SetActiveDialogBox(0);
809 }
810
811 //=================================================================================
812 // function : ActivateThisDialog()
813 // purpose  :
814 //=================================================================================
815 void EntityGUI_3DSketcherDlg::ActivateThisDialog()
816 {
817   myGeomGUI->EmitSignalDeactivateDialog();
818   setEnabled(true);
819   myGeomGUI->SetActiveDialogBox(this);
820
821   connect(myGeomGUI->getApp()->selectionMgr(),
822           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
823
824   localSelection(TopAbs_VERTEX);
825   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
826 }
827
828 //=================================================================================
829 // function : ValueChangedInSpinBox()
830 // purpose  :
831 //=================================================================================
832 void EntityGUI_3DSketcherDlg::ValueChangedInSpinBox (double newValue)
833 {
834   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
835 }
836
837 //=================================================================================
838 // function : BoxChecked()
839 // purpose  : ChecBoxes management
840 //=================================================================================
841 void EntityGUI_3DSketcherDlg::BoxChecked (bool checked)
842 {
843   QCheckBox* send = (QCheckBox*) sender();
844   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
845
846   if (send == GroupAngles->checkBox)
847   {
848     GroupAngles->SpinBox_DA2->setEnabled(checked);
849     if(checked)
850     {
851       GroupAngles->SpinBox_DH->setEnabled(false);
852       GroupAngles->checkBox_2->setChecked(false);
853     }
854   }
855   else if (send == GroupAngles->checkBox_2)
856   {
857     GroupAngles->SpinBox_DH->setEnabled(checked);
858     if(checked)
859     {
860       GroupAngles->SpinBox_DA2->setEnabled(false);
861       GroupAngles->checkBox->setChecked(false);
862     }
863   }
864
865   else if (send == GroupControls->CheckBox1)
866   {
867     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
868     if (checked){
869       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
870       isLengthVisible=true;
871     }
872     else
873       isLengthVisible=false;
874   }
875   else if (send == GroupControls->CheckBox2)
876   {
877     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
878     if (checked)
879     {
880       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
881       isAngleVisible=true;
882     }
883     else
884       isAngleVisible=false;
885   }
886   else if (send == GroupControls->CheckBox3)
887   {
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);
894     
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);
903     
904     GroupControls->updateGeometry();
905     GroupControls->resize(minimumSizeHint());
906   } 
907
908   updateGeometry();
909   resize(minimumSizeHint());
910   
911   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
912 }
913
914 //=================================================================================
915 // function : ButtonClicked()
916 // purpose  :
917 //=================================================================================
918 void EntityGUI_3DSketcherDlg::ButtonClicked (bool checked)
919 {
920   if (GroupAngles->radioButton_1->isChecked())
921     myOrientation = OXY;
922   else if (GroupAngles->radioButton_2->isChecked())
923     myOrientation = OYZ;
924   else
925     myOrientation = OXZ;
926
927   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
928 }
929
930 //=================================================================================
931 // function : enterEvent()
932 // purpose  :
933 //=================================================================================
934 void EntityGUI_3DSketcherDlg::enterEvent (QEvent*)
935 {
936   if (!mainFrame()->GroupConstructors->isEnabled())
937     ActivateThisDialog();
938 }
939
940 //=================================================================================
941 // function : createOperation
942 // purpose  :
943 //=================================================================================
944 GEOM::GEOM_IOperations_ptr EntityGUI_3DSketcherDlg::createOperation()
945 {
946   return getGeomEngine()->GetICurvesOperations(getStudyId());
947 }
948
949 //=================================================================================
950 // function : isValid
951 // purpose  :
952 //=================================================================================
953 bool EntityGUI_3DSketcherDlg::isValid (QString& msg)
954 {
955   bool ok = true;
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;
959   return ok;
960 }
961
962 //=================================================================================
963 // function : execute
964 // purpose  :
965 //=================================================================================
966 bool EntityGUI_3DSketcherDlg::execute (ObjectList& objects)
967 {
968   //GEOM::ListOfDouble_var aCoordsArray = new GEOM::ListOfDouble;
969   //if (!myOK || myPointsList.size() == 0)
970   //  aCoordsArray->length((myPointsList.size()+1)*3);
971   //else
972   //  aCoordsArray->length(myPointsList.size()*3);
973
974   QStringList aCommands;
975   aCommands << "3DSketcher";
976   QStringList aParameters;
977
978   //int i = 0;
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;
986   }
987
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;
995   }
996
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());
1001
1002   if (!anObj->_is_nil()) {
1003     if (!IsPreview()) anObj->SetParameters(aParameters.join(":").toLatin1().constData());
1004     objects.push_back(anObj._retn());
1005   }
1006
1007   return true;
1008 }
1009
1010 //=================================================================================
1011 // function : SetDoubleSpinBoxStep()
1012 // purpose  : Double spin box management
1013 //=================================================================================
1014 void EntityGUI_3DSketcherDlg::SetDoubleSpinBoxStep (double step)
1015 {
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);
1023 }
1024
1025 //=================================================================================
1026 // function : ClickOnOk()
1027 // purpose  :
1028 //=================================================================================
1029 void EntityGUI_3DSketcherDlg::ClickOnOk()
1030 {
1031   Locker lock(myOK);
1032
1033   if (!onAccept())
1034     return;
1035
1036   ClickOnCancel();
1037 }
1038
1039 //=================================================================================
1040 // function : ClickOnApply()
1041 // purpose  :
1042 //=================================================================================
1043 bool EntityGUI_3DSketcherDlg::ClickOnApply()
1044 {
1045   QString msg;
1046   if (!isValid(msg)) {
1047     showError(msg);
1048     return false;
1049   }
1050
1051   if (myPointsList.count() > 0)
1052     myPointsList.append(myPointsList[0]);
1053
1054   Locker lock(myOK);
1055
1056   if (!onAccept())
1057     return false;
1058
1059   ClickOnCancel();
1060   return true;
1061 }
1062
1063 //=================================================================================
1064 // function : getLastPoint()
1065 // purpose  : return last points from list
1066 //=================================================================================
1067 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getLastPoint() const
1068 {
1069   return myPointsList.count() > 0 ? myPointsList.last() : XYZ();
1070 }
1071
1072 //=================================================================================
1073 // function : getPenultimatePoint()
1074 // purpose  : return penultimate point from list
1075 //=================================================================================
1076 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getPenultimatePoint() const
1077 {
1078   double size = myPointsList.count();
1079   return size > 1 ? myPointsList.at(size - 2) : XYZ();
1080 }
1081
1082 //=================================================================================
1083 // function : getCurrentPoint()
1084 // purpose  : returns current point
1085 //=================================================================================
1086 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getCurrentPoint() const
1087 {
1088   XYZ xyz;
1089
1090   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1091   int aPrecision = resMgr->integerValue("Geometry", "length_precision", 7);
1092   
1093   bool spherical   = GroupAngles->checkBox->isChecked();
1094   bool cylindrical = GroupAngles->checkBox_2->isChecked();
1095
1096   if (myCoordType == 1) 
1097   {
1098     if (GroupAngles->radioButton_1->isChecked())
1099       xyz.command = "OXY";
1100     else if (GroupAngles->radioButton_2->isChecked())
1101       xyz.command = "OYZ";
1102     else
1103       xyz.command = "OXZ";
1104     
1105     if (cylindrical)       // Cylindrical coordinates (radius, angle, height)
1106       xyz.command += "C";
1107     else
1108       xyz.command += "S";  // Spherical coordinates (radius, angle1, angle2) --> polar if angle2 = 0
1109     
1110     if (myMode == 0)       // Absolute coordinates
1111       xyz.command += "A ";
1112     else if (myMode == 1)  // Relative coordinates
1113       xyz.command += "R ";
1114       
1115
1116     double anAngle  = GroupAngles->SpinBox_DA->value();
1117     double aLength  = GroupAngles->SpinBox_DL->value();
1118
1119     double anAngle2 = 0.0;
1120     QString da2 = "0";
1121     if (spherical) {       // Spherical coordinates (radius, angle1, angle2)
1122       anAngle2 = GroupAngles->SpinBox_DA2->value();
1123       da2 = GroupAngles->SpinBox_DA2->text();
1124     }
1125     
1126     double aHeight = 0.0;
1127     QString dh = "0";
1128     if (cylindrical) {
1129       aHeight = GroupAngles->SpinBox_DH->value();
1130       dh = GroupAngles->SpinBox_DH->text();
1131     }
1132
1133     xyz.command +=
1134       QString::number(anAngle, 'g', aPrecision) + " ";
1135     xyz.params =
1136       GroupAngles->SpinBox_DA->text() + ":"; 
1137     
1138     if(cylindrical)
1139     {
1140       xyz.command +=
1141         QString::number(aHeight, 'g', aPrecision) + " ";
1142       xyz.params +=
1143         dh + ":";
1144     }
1145     else                  // Spherical or polar coordinates
1146     {
1147       xyz.command +=
1148         QString::number(anAngle2, 'g', aPrecision) + " ";
1149       xyz.params +=
1150         dh + ":";
1151     }
1152     
1153     xyz.command +=
1154       QString::number(aLength, 'g', aPrecision);
1155     xyz.params +=
1156       GroupAngles->SpinBox_DL->text();
1157
1158       
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);
1163     
1164     XYZ xyzP = getLastPoint();
1165     if (myMode == 0)
1166       xyzP.x=xyzP.y=xyzP.z=0.0; 
1167     if (GroupAngles->radioButton_1->isChecked()) // OXY
1168     {
1169       xyz.x = xyzP.x + aProjectedLength * cos(anAngle);
1170       xyz.y = xyzP.y + aProjectedLength * sin(anAngle);
1171       if (cylindrical)
1172         xyz.z = xyzP.z + aHeight;
1173       else
1174         xyz.z = xyzP.z + aLength * sin(anAngle2);
1175     }
1176     else if (GroupAngles->radioButton_2->isChecked()) // OYZ
1177     {
1178       xyz.y = xyzP.y + aProjectedLength * cos(anAngle);
1179       xyz.z = xyzP.z + aProjectedLength * sin(anAngle);
1180       if (cylindrical)
1181         xyz.x = xyzP.x + aHeight;
1182       else
1183         xyz.x = xyzP.x + aLength * sin(anAngle2);
1184     }
1185     else // OXZ
1186     {
1187       xyz.z = xyzP.z + aProjectedLength * sin(anAngle);
1188       xyz.x = xyzP.x + aProjectedLength * cos(anAngle);
1189       if (cylindrical)
1190         xyz.y = xyzP.y + aHeight;
1191       else
1192         xyz.y = xyzP.y + aLength * sin(anAngle2);
1193     }
1194   }
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 ";
1201     }
1202     else { // DXDYDZ
1203       xyz = getLastPoint();
1204       xyz.x += Group3Spin->SpinBox_DX->value();
1205       xyz.y += Group3Spin->SpinBox_DY->value();
1206       xyz.z += Group3Spin->SpinBox_DZ->value();
1207       xyz.command = "T ";
1208     }
1209
1210     double aX  = Group3Spin->SpinBox_DX->value();
1211     double aY  = Group3Spin->SpinBox_DY->value();
1212     double aZ  = Group3Spin->SpinBox_DZ->value();
1213
1214     xyz.command +=
1215       QString::number(aX, 'g', aPrecision) + " " +
1216       QString::number(aY, 'g', aPrecision) + " " +
1217       QString::number(aZ, 'g', aPrecision);
1218     xyz.params =
1219       Group3Spin->SpinBox_DX->text() + ":" +
1220       Group3Spin->SpinBox_DY->text() + ":" +
1221       Group3Spin->SpinBox_DZ->text();
1222   }
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
1227   
1228   return xyz;
1229 }
1230
1231
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
1238
1239   bool withAngle = (myCoordType == 1);
1240   bool twoAngles = GroupAngles->checkBox->isChecked();
1241   
1242   XYZ Last    = getLastPoint();
1243   XYZ Current;
1244   if( myIsUndoRedo ) {
1245       Current = myWorkPoint;
1246   } else {
1247     Current = getCurrentPoint();
1248   }
1249   
1250   XYZ Penultimate = getPenultimatePoint();
1251   
1252   gp_Pnt P1 = gp_Pnt(Last.x,Last.y,Last.z);
1253   if (myMode == 0) // Absolute coordinates
1254     P1 = gp::Origin();
1255   
1256   gp_Pnt P2 = gp_Pnt(Current.x,Current.y,Current.z);
1257   gp_Pnt P3 = gp_Pnt(Penultimate.x,Penultimate.y,Penultimate.z);
1258   
1259   gp_Vec Vec1(P1,P2);
1260   gp_Vec Vec2(P1,P3);
1261   
1262   gp_Dir aNormal;                  // Normal defining the plane of the presentation 
1263   
1264   if (withAngle)                   // If one angle
1265   {
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);
1273     
1274     if (Vec1.CrossMagnitude(N1) > Precision::Confusion())
1275     {
1276       // The plane is orthogonal to the angle presentation plane 
1277       // and contains the current edge
1278       aNormal = N1.Crossed(gp_Dir(Vec1));
1279     }
1280     else
1281       aNormal = N2;
1282
1283     if (twoAngles)
1284     { 
1285       gp_Vec V = Vec1.Transformed(aTransform.Inverted());
1286       gp_Vec Vec3(V.X(),V.Y(),0.0);
1287       
1288       // Express the coordinates in the refernce coordinate system (OXY)
1289       Vec3.Transform(aTransform);   
1290       if(Abs(Vec1.CrossMagnitude(Vec3)) > Precision::Confusion())                                  
1291       { 
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));  
1295       } 
1296     }         
1297   }
1298   else
1299   {
1300     // Check colinearity
1301     if (Abs(Vec1.CrossMagnitude(Vec2)) < Precision::Confusion())
1302     {
1303       Vec2 = gp_Vec(gp::DX());
1304       if (Abs(Vec1.CrossMagnitude(Vec2)) < Precision::Confusion())
1305       {
1306         Vec2 = gp_Vec(gp::DY());
1307       }
1308     }
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)); 
1312     }
1313   }
1314   return aNormal;
1315 }
1316
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,
1323                                               const bool            append,
1324                                               const bool            activate,
1325                                               const bool            update,
1326                                               const double          lineWidth,
1327                                               const int             displayMode,
1328                                               const int             color)
1329 {
1330   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1331
1332   QColor aColor = resMgr->colorValue("Geometry","line_color",QColor(255,0,0));
1333   Quantity_NameOfColor line_color = SalomeApp_Tools::color(aColor).Name();
1334
1335   // set width of displayed shape
1336   int lw = lineWidth;
1337   if (lw == -1) {
1338     lw = resMgr->integerValue("Geometry", "preview_edge_width", -1);
1339   }
1340   getDisplayer()->SetWidth(lw);
1341
1342   // Disable activation of selection
1343   getDisplayer()->SetToActivate(activate);
1344
1345   // Make a reference to GEOM_Object
1346   CORBA::String_var objStr = myGeometryGUI->getApp()->orb()->object_to_string(object);
1347   getDisplayer()->SetName(objStr.in());
1348
1349   // Create wire from applied object
1350   TopoDS_Shape anApplyedWire, aLastSegment;
1351   if (!createShapes(object, anApplyedWire, aLastSegment))
1352     return;
1353
1354   // Set color for preview shape
1355   getDisplayer()->SetColor(line_color);
1356
1357   // Build prs
1358   SALOME_Prs* aPrs = getDisplayer()->BuildPrs(anApplyedWire);
1359   if (aPrs != 0 && !aPrs->IsNull())
1360     GEOMBase_Helper::displayPreview(aPrs, append, update);
1361
1362   getDisplayer()->SetColor(Quantity_NOC_VIOLET);
1363   aPrs = getDisplayer()->BuildPrs(aLastSegment);
1364
1365   if (aPrs != 0 && !aPrs->IsNull())
1366     GEOMBase_Helper::displayPreview(aPrs, append, update);
1367
1368   getDisplayer()->SetColor(line_color);
1369
1370   // Display local trihedron if the mode is relative
1371   if (myMode == 1)
1372     displayTrihedron(2);
1373
1374   // Display preview of suitable dimension presentations
1375   displayDimensions(false);
1376
1377   getDisplayer()->UnsetName();
1378
1379   // Enable activation of displayed objects
1380   getDisplayer()->SetToActivate(true);
1381 }
1382
1383 //================================================================
1384 // Function : displayTrihedron()
1385 // Purpose  : Method for displaying trihedron
1386 //================================================================
1387 void EntityGUI_3DSketcherDlg::displayTrihedron (int selMode)
1388 {
1389   // Add trihedron to preview
1390   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1391   
1392   SOCC_Viewer* anOCCViewer = dynamic_cast<SOCC_Viewer*>( vw->getViewManager()->getViewModel() );
1393   if( !anOCCViewer )
1394     return;
1395   
1396   Handle(AIS_InteractiveContext) anAISContext = anOCCViewer->getAISContext();
1397   if( !anAISContext )
1398     return;
1399   
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);
1403
1404   SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>( anOCCViewer->CreatePrs(0) );
1405
1406   if (aSPrs) {
1407     aSPrs->PrependObject(anIO);
1408     GEOMBase_Helper::displayPreview(aSPrs, true, true);
1409   }
1410   anAISContext->Activate(anIO, selMode);
1411 }
1412
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)
1419 {
1420   myPrsType   = prsType();
1421   XYZ Last    = getLastPoint();
1422   XYZ Current = getCurrentPoint();
1423
1424   gp_Pnt Last_Pnt(Last.x,Last.y,Last.z);
1425   
1426   gp_Pnt P0 = Last_Pnt;
1427   gp_Pnt Origin = gp::Origin();
1428   if (myMode == 0)                 // Absolute coordinates
1429     P0 = Origin;
1430   
1431   gp_Pnt Current_Pnt(Current.x,Current.y,Current.z);
1432   gp_Pnt P1, P2;
1433   
1434   // Check if last end current point are coincident
1435   if (Last_Pnt.IsEqual(Current_Pnt, 1e-7))
1436     return;
1437   
1438   gp_Dir aNormal = getPresentationPlane();
1439   
1440   if (myCoordType == 0)
1441   {
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()) );
1448      
1449     if (myMode == 0)
1450     {
1451       std::string aCoordText = "( " + doubleToString(Current_Pnt.X()) + 
1452                                ", " + doubleToString(Current_Pnt.Y()) +
1453                                ", " + doubleToString(Current_Pnt.Z()) + " )";
1454       displayText(aCoordText, Current_Pnt, store);
1455     }
1456     else 
1457     { 
1458       if (oneDimensionalMove)
1459       {
1460         // For better colocation of dimensions if only one coordinate changes (aNormal is a better choice)
1461         displayLength(P0, Current_Pnt, aNormal, store);
1462       }
1463       else
1464       {
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);
1468       }
1469     }
1470   }
1471   else if (myCoordType == 1)             // ANGLES
1472   {
1473     bool spherical   = GroupAngles->checkBox->isChecked(); 
1474     bool cylindrical = GroupAngles->checkBox_2->isChecked();
1475     
1476     double anAngle1 = GroupAngles->SpinBox_DA->value();
1477     double aLength  = GroupAngles->SpinBox_DL->value();
1478     
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. ),
1483                  0.0); 
1484     
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);
1491     
1492     if(myMode !=0  || !store)
1493       displayAngle(anAngle1, P0, P1, P2, store);
1494     else
1495     {
1496       std::string anAngleText = doubleToString(anAngle1) + " deg.";
1497       displayText(anAngleText, Current_Pnt, store);
1498     }
1499     
1500     if(spherical)
1501     {
1502       double anAngle2 = GroupAngles->SpinBox_DA2->value();
1503       displayAngle(anAngle2, P0, P2, Current_Pnt, store);
1504       displayLength(P0, Current_Pnt, aNormal, store);
1505     }
1506     else
1507     {
1508       bool sameRadius = isSame ( radius(Last_Pnt), radius(Current_Pnt) );
1509       bool sameHeight = isSame ( height(Last_Pnt), height(Current_Pnt) );
1510                             
1511       gp_Vec aVec(P2, Current_Pnt);
1512       
1513       if (myMode == 0 && !sameRadius)
1514       {
1515         displayLength(P0.Translated(aVec), P2.Translated(aVec), aNormal, store);  // Radius  
1516       }
1517       else if (myMode == 1)
1518         displayLength(P0, P2, aNormal, store);
1519       
1520       if ( cylindrical && 
1521           (myMode == 1 || !sameHeight) )
1522         displayLength(P2, Current_Pnt, aNormal.Reversed(), store); // Height
1523     }
1524   }
1525 }
1526
1527 //================================================================
1528 // Function : displayAngle()
1529 // Purpose  : Method for displaying angle dimensions
1530 //================================================================
1531 void EntityGUI_3DSketcherDlg::displayAngle (double theAngle,
1532                                             gp_Pnt P0, 
1533                                             gp_Pnt P1, 
1534                                             gp_Pnt P2,
1535                                             bool store)
1536 {
1537   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1538   
1539   // Creation of the AIS object
1540   Handle(AIS_AngleDimension) anAngleIO = createAISAngleDimension(theAngle, 
1541                                                                  P0, 
1542                                                                  P1, 
1543                                                                  P2);
1544   if (anAngleIO.IsNull())
1545     return;
1546   
1547   if (store)
1548   {
1549     // Erase dimensions presentations
1550     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
1551     myAnglePrs->PrependObject(anAngleIO);
1552     
1553     // Display modified presentation
1554     if (isAngleVisible)
1555       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
1556     
1557     // Update dimension presentation angle count for later undo / redo
1558     myPrsType.A += 1;
1559   }
1560   else if ( isAngleVisible)
1561   {
1562     SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1563         (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1564         
1565     if (aSPrs)
1566     {
1567       aSPrs->AddObject(anAngleIO);
1568       GEOMBase_Helper::displayPreview(aSPrs, true, true); 
1569     }
1570   }
1571 }
1572
1573
1574 //================================================================
1575 // Function : displayLength()
1576 // Purpose  : Method for displaying length dimensions for a segment
1577 //            creation step
1578 //================================================================
1579 void EntityGUI_3DSketcherDlg::displayLength (gp_Pnt P1,
1580                                              gp_Pnt P2,
1581                                              gp_Dir theNormal,
1582                                              bool store)
1583 {
1584   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1585   
1586   double aLength = P1.Distance(P2);
1587   
1588   if (aLength < Precision::Confusion())
1589     return;
1590     
1591   Handle(AIS_LengthDimension) anIO = createAISLengthDimension(aLength, P1, P2, theNormal);
1592
1593   if (store)
1594   {
1595     // Erase length dimensions presentation
1596     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
1597     myLengthPrs->PrependObject(anIO);
1598
1599     // Display modified presentation
1600     if (isLengthVisible)
1601       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
1602     
1603     // Update dimension presentation length count for later undo / redo
1604     myPrsType.L += 1;
1605   }
1606   else if (isLengthVisible)
1607   {
1608     SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1609       (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1610     if (aSPrs)
1611     {
1612       aSPrs->PrependObject(anIO);
1613       GEOMBase_Helper::displayPreview(aSPrs, true, true);
1614     }
1615   }
1616 }
1617
1618 //================================================================
1619 // Function : displayText()
1620 // Purpose  : Method for displaying length dimensions for a segment
1621 //            creation step
1622 //================================================================
1623 void EntityGUI_3DSketcherDlg::displayText ( std::string theText,
1624                                             gp_Pnt P,
1625                                             bool store )
1626 {
1627   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1628     
1629   Handle(AIS_Text) anIO = new AIS_Text(TCollection_ExtendedString(theText.c_str()), P);
1630
1631   if (store)
1632   {
1633     // Erase length dimensions presentation
1634     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myTextPrs, true);
1635     myTextPrs->PrependObject(anIO);
1636
1637     // Display modified presentation
1638     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myTextPrs);
1639     
1640     // Update dimension presentation text count for later undo / redo
1641     myPrsType.T += 1;
1642   }
1643   else
1644   {
1645     SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1646       (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1647     if (aSPrs)
1648     {
1649       aSPrs->PrependObject(anIO);
1650       GEOMBase_Helper::displayPreview(aSPrs, true, true);
1651     }
1652   }
1653
1654 }
1655
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, 
1662                                                                               gp_Pnt P1, 
1663                                                                               gp_Pnt P2, 
1664                                                                               gp_Dir theNormal)
1665 {
1666   // Plane construction
1667   gce_MakePln gce_MP(P1, theNormal);
1668   Handle(Geom_Plane) aPlane = new Geom_Plane(gce_MP.Value());
1669   
1670   TopoDS_Vertex aVert1 = BRepBuilderAPI_MakeVertex(P1);
1671   TopoDS_Vertex aVert2 = BRepBuilderAPI_MakeVertex(P2);
1672
1673   Handle(AIS_LengthDimension) anIO = new AIS_LengthDimension( aVert1, aVert2, aPlane->Pln() );
1674
1675   anIO->SetCustomValue( theLength );
1676
1677   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1678   int w = resMgr->integerValue( "Geometry", "measures_line_width", 1 );
1679
1680   Handle(Prs3d_DimensionAspect) aDimensionStyle = new Prs3d_DimensionAspect;
1681
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 );
1690
1691   return anIO;
1692 }
1693
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, 
1700                                                                             gp_Pnt P0, 
1701                                                                             gp_Pnt P1, 
1702                                                                             gp_Pnt P2)
1703 {
1704   // Length of the built segment
1705   double aLength = P0.Distance(P1);
1706   
1707   // Check input data
1708   if (Abs(theAngle) < Precision::Angular() ||
1709       aLength < Precision::Confusion())
1710     return NULL;
1711
1712   Handle(AIS_AngleDimension) anIO = new AIS_AngleDimension( P1, P0, P2 );
1713
1714   //anIO->SetCustomValue( theAngle );
1715
1716   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1717   int w = resMgr->integerValue( "Geometry", "measures_line_width", 1 );
1718
1719   Handle(Prs3d_DimensionAspect) aDimensionStyle = new Prs3d_DimensionAspect;
1720
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 );
1727
1728   anIO->SetDimensionAspect( aDimensionStyle );
1729
1730   return anIO;
1731 }
1732
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)
1740 {
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())
1745       points << p;
1746   }
1747
1748   if (points.count() == 1) {
1749     // only one point is created
1750     BRepBuilderAPI_MakeVertex mkVertex (points.last());
1751     theApplyedWire = mkVertex.Shape();
1752   }
1753   else if (points.count() > 1) {
1754     // wire is created
1755     BRepBuilderAPI_MakePolygon mkWire;
1756     foreach(gp_Pnt p, points)
1757       mkWire.Add(p);
1758     theApplyedWire = mkWire.Shape();
1759   }
1760
1761   XYZ curxyz = getCurrentPoint();
1762   gp_Pnt curpnt(curxyz.x, curxyz.y, curxyz.z);
1763
1764   if (points.isEmpty() || points.last().Distance(curpnt) <= gp::Resolution()) {
1765     BRepBuilderAPI_MakeVertex mkVertex (curpnt);
1766     theLastSegment = mkVertex.Shape();
1767   }
1768   else {
1769     BRepBuilderAPI_MakeEdge mkEdge(points.last(), curpnt);
1770     theLastSegment = mkEdge.Shape();
1771   }
1772
1773   /* VSR: old algorithm does not work properly, see bug 0020899
1774   TopoDS_Shape aShape;
1775   if (!GEOMBase::GetShape(theObject, aShape))
1776     return false;
1777
1778   if (aShape.ShapeType() != TopAbs_WIRE && aShape.ShapeType() != TopAbs_VERTEX)
1779     return false;
1780
1781   theApplyedWire = aShape;
1782   if (myOK)
1783      return true;
1784
1785   BRepBuilderAPI_MakeWire aBuilder;
1786   TopExp_Explorer edgeExp(aShape, TopAbs_EDGE);
1787   while (1) {
1788     TopoDS_Shape anEdge = edgeExp.Current();
1789     edgeExp.Next();
1790     if (edgeExp.More()) // i.e. non-last edge
1791       aBuilder.Add(TopoDS::Edge(anEdge));
1792     else {
1793       theLastSegment = anEdge;
1794       break;
1795     }
1796   }
1797
1798   if (aBuilder.IsDone()) {
1799     theApplyedWire = aBuilder.Shape();
1800   }
1801   else if (!theLastSegment.IsNull()) {
1802     TopExp_Explorer vertexExp(theLastSegment, TopAbs_VERTEX);
1803     theApplyedWire = vertexExp.Current();
1804     }
1805   */
1806
1807   return true;
1808 }
1809
1810 //================================================================
1811 // Function : doubleToString
1812 // Purpose  : converts double to string
1813 //================================================================
1814 std::string EntityGUI_3DSketcherDlg::doubleToString (double num)
1815 {
1816   // truncate num
1817   int digNum = 5;
1818   char format = 'g'; // truncated to a number of significant digits
1819
1820   return QString::number(num, format, digNum).toStdString();
1821 }
1822
1823 //================================================================
1824 // Function : toReferenceSystem ()
1825 // Purpose  :
1826 //================================================================
1827 gp_Trsf EntityGUI_3DSketcherDlg::toReferenceSystem(gp_Pnt origin) const
1828
1829   gp_Trsf T;                        // Identity transformation
1830   gp_Ax3 reference_system;          // OXY
1831   reference_system.SetLocation(origin);
1832   
1833   gp_Ax3 current_system = reference_system;
1834   switch (myOrientation)
1835   {
1836     case OYZ:
1837     {
1838       current_system = gp_Ax3(origin, gp::DX(), gp::DY());
1839       break;
1840     }
1841     case OXZ:
1842     {
1843       current_system = gp_Ax3(origin, gp::DY().Reversed(), gp::DX());
1844       break;
1845     }
1846   }
1847   
1848   T.SetTransformation( current_system, reference_system );
1849   
1850   return T;
1851 }
1852
1853 //================================================================
1854 // Function : toCurrentSystem ()
1855 // Purpose  :
1856 //================================================================
1857 gp_Trsf EntityGUI_3DSketcherDlg::toCurrentSystem(gp_Pnt origin) const
1858 {
1859   return toReferenceSystem(origin).Inverted();
1860 }
1861
1862 //================================================================
1863 // Function : radius (gp_Pnt) const
1864 // Purpose  :
1865 //================================================================
1866 double EntityGUI_3DSketcherDlg::radius (gp_Pnt thePnt) const
1867 {
1868   // Get the point coordinates in the current coordinates system
1869   gp_Trsf aTrsf = toCurrentSystem(gp::Origin());
1870   gp_Pnt aPnt = thePnt.Transformed(aTrsf);
1871   
1872   double radius = sqrt(aPnt.X()*aPnt.X() + aPnt.Y()*aPnt.Y());
1873   return radius;
1874 }
1875
1876 //================================================================
1877 // Function : height (gp_Pnt) const
1878 // Purpose  :
1879 //================================================================
1880 double EntityGUI_3DSketcherDlg::height (gp_Pnt thePnt) const
1881 {
1882   // Get the point coordinates in the current coordinates system
1883   gp_Trsf aTrsf = toCurrentSystem(gp::Origin());
1884   gp_Pnt aPnt = thePnt.Transformed(aTrsf);
1885   
1886   return aPnt.Z();
1887 }