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