]> SALOME platform Git repositories - modules/geom.git/blob - src/EntityGUI/EntityGUI_3DSketcherDlg.cxx
Salome HOME
EDF 2281 : Add 2 primitives for hexa mesh
[modules/geom.git] / src / EntityGUI / EntityGUI_3DSketcherDlg.cxx
1 // Copyright (C) 2007-2012  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 // GEOM GEOMGUI : GUI for Geometry component
20 // File   : EntityGUI_3DSketcherDlg.cxx
21 // Author : DMV, OCN
22
23 #include <cmath>
24 #include <string>
25 #include <boost/lexical_cast.hpp>
26
27 #include "EntityGUI_3DSketcherDlg.h"
28 #include "EntityGUI_Widgets.h"
29
30 #include <Basics_OCCTVersion.hxx>
31
32 #include <GEOMBase.h>
33 #include <GeometryGUI.h>
34 #include <Precision.hxx>
35
36 #include <DlgRef.h>
37 #include <SUIT_Session.h>
38 #include <SUIT_Desktop.h>
39 #include <SUIT_MessageBox.h>
40 #include <SUIT_ResourceMgr.h>
41 #include <SUIT_ViewWindow.h>
42 #include <SUIT_ViewManager.h>
43 #include <SOCC_Prs.h>
44 #include <SOCC_ViewModel.h>
45 #include <SalomeApp_Application.h>
46 #include <SalomeApp_DoubleSpinBox.h>
47 #include <LightApp_Application.h>
48 #include <LightApp_SelectionMgr.h>
49
50 #include <SalomeApp_Tools.h>
51
52 //OCCT includes
53 #include <TopoDS.hxx>
54 #include <TColStd_IndexedMapOfInteger.hxx>
55 #include <BRepBuilderAPI_MakeVertex.hxx>
56 #include <BRepBuilderAPI_MakePolygon.hxx>
57 #include <BRepBuilderAPI_MakeEdge.hxx>
58
59 #include <AIS_Trihedron.hxx>
60 #include <AIS_AngleDimension.hxx>
61 #include <AIS_LengthDimension.hxx>
62 #include <AIS_Drawer.hxx>
63 #include <Geom_Axis2Placement.hxx>
64 #include <Geom_Plane.hxx>
65 #include <SelectMgr_Selection.hxx>
66 #include <gce_MakePln.hxx>
67 #include <Prs3d_AngleAspect.hxx>
68 #include <Prs3d_LineAspect.hxx>
69 #include <Prs3d_LengthAspect.hxx>
70 #if OCC_VERSION_LARGE > 0x06050300
71 #include <Prs3d_TextAspect.hxx>
72 #include <Prs3d_Presentation.hxx>
73 #include <Prs3d_Text.hxx>
74 #include <Graphic3d_VerticalTextAlignment.hxx>
75 #include <Graphic3d_HorizontalTextAlignment.hxx>
76 #include <Graphic3d_AspectText3d.hxx>
77 #include <Font_FontAspect.hxx>
78 #endif // OCC_VERSION_LARGE > 0x06050300
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
534   if (myCoordType == 0 && myMode == 1)     // RELATIVE CARTESIAN COORDINATES
535   {
536     Group3Spin->SpinBox_DX->setValue(0.0);
537     Group3Spin->SpinBox_DY->setValue(0.0);
538     Group3Spin->SpinBox_DZ->setValue(0.0);
539   }
540   else if (myCoordType == 1 && myMode == 1) // RELATIVE ANGULAR COORDINATES
541   {
542     GroupAngles->SpinBox_DA->setValue(0.0);
543     GroupAngles->SpinBox_DL->setValue(0.0);
544     GroupAngles->SpinBox_DA2->setValue(0.0);
545   }
546   
547   UpdatePointCoordinates();
548     
549   UpdateButtonsState();
550   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
551 }
552
553 //=================================================================================
554 // function : UpdateButtonsState()
555 // purpose  :
556 //=================================================================================
557 void EntityGUI_3DSketcherDlg::UpdateButtonsState()
558 {
559   if (myPointsList.count() == 0) 
560   {
561     GroupType->RadioButton1->click();
562     GroupType->RadioButton3->click();
563   }
564   GroupType->RadioButton2->setEnabled(myPointsList.count() > 0);
565 //   GroupType->RadioButton3->setEnabled(myPointsList.count() > 0);
566 //   GroupType->RadioButton4->setEnabled(myPointsList.count() > 0);
567   Group3Spin->buttonUndo->setEnabled(myPointsList.count() > 0);
568   Group3Spin->buttonRedo->setEnabled(myRedoList.count() > 0);
569   GroupAngles->buttonUndo->setEnabled(myPointsList.count() > 0);
570   GroupAngles->buttonRedo->setEnabled(myRedoList.count() > 0);
571 }
572
573 //=================================================================================
574 // function : UpdatePointCoordinates()
575 // purpose  :Update point coordinates in the control groupbox
576 //=================================================================================
577 void EntityGUI_3DSketcherDlg::UpdatePointCoordinates()
578 {
579   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
580   int aPrecision = resMgr->integerValue("Geometry", "length_precision", 6);
581   
582   if (myPointsList.count() == 0)
583   {
584     GroupControls->lineEdit_1->setText("");
585     GroupControls->lineEdit_2->setText("");
586     GroupControls->lineEdit_3->setText("");
587     
588     GroupControls->lineEdit_4->setText("");
589     GroupControls->lineEdit_5->setText("");
590     GroupControls->lineEdit_6->setText("");
591   }
592   else if (myPointsList.count() == 1)
593   {
594     GroupControls->lineEdit_1->setText(DlgRef::PrintDoubleValue(getLastPoint().x, aPrecision));
595     GroupControls->lineEdit_2->setText(DlgRef::PrintDoubleValue(getLastPoint().y, aPrecision));
596     GroupControls->lineEdit_3->setText(DlgRef::PrintDoubleValue(getLastPoint().z, aPrecision));
597     
598     GroupControls->lineEdit_4->setText("");
599     GroupControls->lineEdit_5->setText("");
600     GroupControls->lineEdit_6->setText("");
601   }
602   else
603   {
604     GroupControls->lineEdit_4->setText(DlgRef::PrintDoubleValue(getLastPoint().x, aPrecision));
605     GroupControls->lineEdit_5->setText(DlgRef::PrintDoubleValue(getLastPoint().y, aPrecision));
606     GroupControls->lineEdit_6->setText(DlgRef::PrintDoubleValue(getLastPoint().z, aPrecision));
607   }
608   
609 }
610
611 //=================================================================================
612 // function : ClickOnUndo()
613 // purpose  :
614 //=================================================================================
615 void EntityGUI_3DSketcherDlg::ClickOnUndo()
616 {
617   if (myPointsList.count() > 0) {
618     
619     myRedoList.append(myPointsList.last());
620
621     // Erase dimensions presentations
622     SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
623     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
624     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
625     
626     removeLastIOFromPrs();
627
628     // Display modified presentation
629     if (isLengthVisible)
630       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
631     if (isAngleVisible)
632       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
633     
634     // Remove last point from list
635     myPointsList.removeLast();
636     GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
637     UpdateButtonsState();
638     
639     // Update of point coordinates in the control groupbox
640     UpdatePointCoordinates();
641
642     updateViewer();
643   }
644 }
645
646 //=================================================================================
647 // function : ClickOnRedo()
648 // purpose  :
649 //=================================================================================
650 void EntityGUI_3DSketcherDlg::ClickOnRedo()
651 {
652   if (myRedoList.count() > 0) {
653     
654     myPointsList.append(myRedoList.last());
655
656     // Erase dimensions presentations
657     SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
658     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
659     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
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     
669     // Remove last point from redo list
670     myRedoList.removeLast();
671     GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
672     UpdateButtonsState();
673     
674     // Update of point coordinates in the control groupbox
675     UpdatePointCoordinates();
676
677     updateViewer();
678   }
679 }
680
681 //=================================================================================
682 // function : removeLastIO()
683 // purpose  :
684 //=================================================================================
685 void EntityGUI_3DSketcherDlg::removeLastIOFromPrs ()
686 {
687   AIS_ListOfInteractive anIOList;
688   XYZ Last = getLastPoint();
689   
690   for (int l = 0; l<Last.L; l++)
691   {
692     myLengthPrs->GetObjects(anIOList);
693     myLengthIORedoList.Prepend(anIOList.First());  // Store last prepended Length IO in redo list
694     myLengthPrs->RemoveFirst();                    // Remove it from myLengthPrs
695   }
696   for (int a = 0; a<Last.A; a++)
697   {
698     myAnglePrs->GetObjects(anIOList);
699     myAngleIORedoList.Prepend(anIOList.First());  // Store last prepended Angle IO in redo list
700     myAnglePrs->RemoveFirst();                    // Remove it from myAnglePrs
701   }
702 }
703
704 //=================================================================================
705 // function : restoreLastIO()
706 // purpose  :
707 //=================================================================================
708 void EntityGUI_3DSketcherDlg::restoreLastIOToPrs ()
709 {
710   XYZ LastDeleted = myRedoList.last();
711   
712   for (int l = 0; l<LastDeleted.L; l++)
713   {
714     myLengthPrs->PrependObject(myLengthIORedoList.First()); // Restore last removed IO
715     myLengthIORedoList.RemoveFirst();                       // Remove it from redo list
716   } 
717   for (int a = 0; a<LastDeleted.A; a++)
718   {
719     myAnglePrs->PrependObject(myAngleIORedoList.First());  // Restore last removed IO
720     myAngleIORedoList.RemoveFirst();                       // Remove it from redo list
721   }
722 }
723
724 //=================================================================================
725 // function : SelectionIntoArgument()
726 // purpose  : Called when selection as changed
727 //=================================================================================
728 void EntityGUI_3DSketcherDlg::SelectionIntoArgument()
729 {
730   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
731   SALOME_ListIO aSelList;
732   aSelMgr->selectedObjects(aSelList);
733
734   int nbSel = aSelList.Extent();
735   if (nbSel == 1) {
736     GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject(aSelList.First());
737     if (!CORBA::is_nil(aSelectedObject)) {
738       TopoDS_Shape aShape;
739       if (GEOMBase::GetShape(aSelectedObject, aShape, TopAbs_SHAPE)) {
740         // Explore the shape if its a local selection
741         TColStd_IndexedMapOfInteger aMap;
742         aSelMgr->GetIndexes(aSelList.First(), aMap);
743         if (aMap.Extent() == 1) {
744           int anIndex = aMap(1);
745           GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations(getStudyId());
746           aSelectedObject = aShapesOp->GetSubShape(aSelectedObject, anIndex);
747         }
748       }
749       bool isOk = true;
750       if (aShape.ShapeType() != TopAbs_VERTEX)
751         isOk = GEOMBase::GetShape(aSelectedObject, aShape, TopAbs_VERTEX);
752       if (isOk) {
753         gp_Pnt aPnt;
754         if (GEOMBase::VertexToPoint(aShape, aPnt)) {
755           // set coordinates to the Spin Boxes
756           double aX, aY, aZ;
757           aX = aPnt.X();
758           aY = aPnt.Y();
759           aZ = aPnt.Z();
760           bool blocked = Group3Spin->SpinBox_DX->signalsBlocked();
761           Group3Spin->SpinBox_DX->blockSignals(true);
762           Group3Spin->SpinBox_DY->blockSignals(true);
763           Group3Spin->SpinBox_DZ->blockSignals(true);
764           if (GroupType->RadioButton1->isChecked()) {
765             Group3Spin->SpinBox_DX->setValue(aX);
766             Group3Spin->SpinBox_DY->setValue(aY);
767             Group3Spin->SpinBox_DZ->setValue(aZ);
768           }
769           else if (GroupType->RadioButton2->isChecked()) {
770             XYZ xyz = getLastPoint();
771             Group3Spin->SpinBox_DX->setValue(aX - xyz.x);
772             Group3Spin->SpinBox_DY->setValue(aY - xyz.y);
773             Group3Spin->SpinBox_DZ->setValue(aZ - xyz.z);
774           }
775           Group3Spin->SpinBox_DX->blockSignals(blocked);
776           Group3Spin->SpinBox_DY->blockSignals(blocked);
777           Group3Spin->SpinBox_DZ->blockSignals(blocked);
778         }
779       }
780     }
781   }
782   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
783 }
784
785 //=================================================================================
786 // function : DeactivateActiveDialog()
787 // purpose  :
788 //=================================================================================
789 void EntityGUI_3DSketcherDlg::DeactivateActiveDialog()
790 {
791   setEnabled(false);
792   globalSelection();
793   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
794   myGeomGUI->SetActiveDialogBox(0);
795 }
796
797 //=================================================================================
798 // function : ActivateThisDialog()
799 // purpose  :
800 //=================================================================================
801 void EntityGUI_3DSketcherDlg::ActivateThisDialog()
802 {
803   myGeomGUI->EmitSignalDeactivateDialog();
804   setEnabled(true);
805   myGeomGUI->SetActiveDialogBox(this);
806
807   connect(myGeomGUI->getApp()->selectionMgr(),
808           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
809
810   localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX);
811   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
812 }
813
814 //=================================================================================
815 // function : ValueChangedInSpinBox()
816 // purpose  :
817 //=================================================================================
818 void EntityGUI_3DSketcherDlg::ValueChangedInSpinBox (double newValue)
819 {
820   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
821 }
822
823 //=================================================================================
824 // function : BoxChecked()
825 // purpose  : ChecBoxes management
826 //=================================================================================
827 void EntityGUI_3DSketcherDlg::BoxChecked (bool checked)
828 {
829   QCheckBox* send = (QCheckBox*) sender();
830   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
831
832   if (send == GroupAngles->checkBox)
833   {
834     GroupAngles->SpinBox_DA2->setEnabled(checked);
835     if(checked)
836     {
837       GroupAngles->SpinBox_DH->setEnabled(false);
838       GroupAngles->checkBox_2->setChecked(false);
839     }
840   }
841   else if (send == GroupAngles->checkBox_2)
842   {
843     GroupAngles->SpinBox_DH->setEnabled(checked);
844     if(checked)
845     {
846       GroupAngles->SpinBox_DA2->setEnabled(false);
847       GroupAngles->checkBox->setChecked(false);
848     }
849   }
850
851   else if (send == GroupControls->CheckBox1)
852   {
853     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
854     if (checked){
855       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
856       isLengthVisible=true;
857     }
858     else
859       isLengthVisible=false;
860   }
861   else if (send == GroupControls->CheckBox2)
862   {
863     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
864     if (checked)
865     {
866       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
867       isAngleVisible=true;
868     }
869     else
870       isAngleVisible=false;
871   }
872   else if (send == GroupControls->CheckBox3)
873   {
874     GroupControls->lineEdit_1->setVisible(checked);
875     GroupControls->lineEdit_2->setVisible(checked);
876     GroupControls->lineEdit_3->setVisible(checked);
877     GroupControls->lineEdit_4->setVisible(checked);
878     GroupControls->lineEdit_5->setVisible(checked);
879     GroupControls->lineEdit_6->setVisible(checked);
880     
881     GroupControls->label_1->setVisible(checked);
882     GroupControls->label_2->setVisible(checked);
883     GroupControls->label_3->setVisible(checked);
884     GroupControls->label_4->setVisible(checked);
885     GroupControls->label_5->setVisible(checked);
886     GroupControls->label_6->setVisible(checked);
887     GroupControls->label_7->setVisible(checked);
888     GroupControls->label_8->setVisible(checked);
889     
890     GroupControls->updateGeometry();
891     GroupControls->resize(minimumSizeHint());
892   } 
893
894   updateGeometry();
895   resize(minimumSizeHint());
896   
897   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
898 }
899
900 //=================================================================================
901 // function : ButtonClicked()
902 // purpose  :
903 //=================================================================================
904 void EntityGUI_3DSketcherDlg::ButtonClicked (bool checked)
905 {
906   if (GroupAngles->radioButton_1->isChecked())
907     myOrientation = OXY;
908   else if (GroupAngles->radioButton_2->isChecked())
909     myOrientation = OYZ;
910   else
911     myOrientation = OXZ;
912
913   GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth);
914 }
915
916 //=================================================================================
917 // function : enterEvent()
918 // purpose  :
919 //=================================================================================
920 void EntityGUI_3DSketcherDlg::enterEvent (QEvent*)
921 {
922   if (!mainFrame()->GroupConstructors->isEnabled())
923     ActivateThisDialog();
924 }
925
926 //=================================================================================
927 // function : createOperation
928 // purpose  :
929 //=================================================================================
930 GEOM::GEOM_IOperations_ptr EntityGUI_3DSketcherDlg::createOperation()
931 {
932   return getGeomEngine()->GetICurvesOperations(getStudyId());
933 }
934
935 //=================================================================================
936 // function : isValid
937 // purpose  :
938 //=================================================================================
939 bool EntityGUI_3DSketcherDlg::isValid (QString& msg)
940 {
941   bool ok = true;
942   ok = Group3Spin->SpinBox_DX->isValid(msg, !IsPreview()) && ok;
943   ok = Group3Spin->SpinBox_DY->isValid(msg, !IsPreview()) && ok;
944   ok = Group3Spin->SpinBox_DZ->isValid(msg, !IsPreview()) && ok;
945   return ok;
946 }
947
948 //=================================================================================
949 // function : execute
950 // purpose  :
951 //=================================================================================
952 bool EntityGUI_3DSketcherDlg::execute (ObjectList& objects)
953 {
954   //GEOM::ListOfDouble_var aCoordsArray = new GEOM::ListOfDouble;
955   //if (!myOK || myPointsList.size() == 0)
956   //  aCoordsArray->length((myPointsList.size()+1)*3);
957   //else
958   //  aCoordsArray->length(myPointsList.size()*3);
959
960   QStringList aCommands;
961   aCommands << "3DSketcher";
962   QStringList aParameters;
963
964   //int i = 0;
965   QList<XYZ>::const_iterator it;
966   for (it = myPointsList.begin(); it != myPointsList.end(); ++it) {
967     //aCoordsArray[i++] = (*it).x;
968     //aCoordsArray[i++] = (*it).y;
969     //aCoordsArray[i++] = (*it).z;
970     aCommands << (*it).command;
971     aParameters << (*it).params;
972   }
973
974   if (!myOK || myPointsList.size() == 0) {
975     XYZ xyz = getCurrentPoint();
976     //aCoordsArray[i++] = xyz.x;
977     //aCoordsArray[i++] = xyz.y;
978     //aCoordsArray[i++] = xyz.z;
979     aCommands << xyz.command;
980     aParameters << xyz.params;
981   }
982
983 //   MESSAGE("aCommands.last() = "<< aCommands.last().toStdString());
984   GEOM::GEOM_ICurvesOperations_var anOper = GEOM::GEOM_ICurvesOperations::_narrow(getOperation());
985   //GEOM::GEOM_Object_var anObj = anOper->Make3DSketcher(aCoordsArray);
986   GEOM::GEOM_Object_var anObj = anOper->Make3DSketcherCommand(aCommands.join(":").toLatin1().constData());
987
988   if (!anObj->_is_nil()) {
989     if (!IsPreview()) anObj->SetParameters(aParameters.join(":").toLatin1().constData());
990     objects.push_back(anObj._retn());
991   }
992
993   return true;
994 }
995
996 //=================================================================================
997 // function : SetDoubleSpinBoxStep()
998 // purpose  : Double spin box management
999 //=================================================================================
1000 void EntityGUI_3DSketcherDlg::SetDoubleSpinBoxStep (double step)
1001 {
1002   Group3Spin->SpinBox_DX->setSingleStep(step);
1003   Group3Spin->SpinBox_DY->setSingleStep(step);
1004   Group3Spin->SpinBox_DZ->setSingleStep(step);
1005   GroupAngles->SpinBox_DA ->setSingleStep(step);
1006   GroupAngles->SpinBox_DA2->setSingleStep(step);
1007   GroupAngles->SpinBox_DL->setSingleStep(step);
1008   GroupAngles->SpinBox_DH->setSingleStep(step);
1009 }
1010
1011 //=================================================================================
1012 // function : ClickOnOk()
1013 // purpose  :
1014 //=================================================================================
1015 void EntityGUI_3DSketcherDlg::ClickOnOk()
1016 {
1017   Locker lock(myOK);
1018
1019   if (!onAccept())
1020     return;
1021
1022   ClickOnCancel();
1023 }
1024
1025 //=================================================================================
1026 // function : ClickOnApply()
1027 // purpose  :
1028 //=================================================================================
1029 bool EntityGUI_3DSketcherDlg::ClickOnApply()
1030 {
1031   QString msg;
1032   if (!isValid(msg)) {
1033     showError(msg);
1034     return false;
1035   }
1036
1037   if (myPointsList.count() > 0)
1038     myPointsList.append(myPointsList[0]);
1039
1040   Locker lock(myOK);
1041
1042   if (!onAccept())
1043     return false;
1044
1045   ClickOnCancel();
1046   return true;
1047 }
1048
1049 //=================================================================================
1050 // function : getLastPoint()
1051 // purpose  : return last points from list
1052 //=================================================================================
1053 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getLastPoint() const
1054 {
1055   return myPointsList.count() > 0 ? myPointsList.last() : XYZ();
1056 }
1057
1058 //=================================================================================
1059 // function : getPenultimatePoint()
1060 // purpose  : return penultimate point from list
1061 //=================================================================================
1062 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getPenultimatePoint() const
1063 {
1064   double size = myPointsList.count();
1065   return size > 1 ? myPointsList.at(size - 2) : XYZ();
1066 }
1067
1068 //=================================================================================
1069 // function : getCurrentPoint()
1070 // purpose  : returns current point
1071 //=================================================================================
1072 EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getCurrentPoint() const
1073 {
1074   XYZ xyz;
1075
1076   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1077   int aPrecision = resMgr->integerValue("Geometry", "length_precision", 7);
1078   
1079   bool spherical   = GroupAngles->checkBox->isChecked();
1080   bool cylindrical = GroupAngles->checkBox_2->isChecked();
1081
1082   if (myCoordType == 1) 
1083   {
1084     if (GroupAngles->radioButton_1->isChecked())
1085       xyz.command = "OXY";
1086     else if (GroupAngles->radioButton_2->isChecked())
1087       xyz.command = "OYZ";
1088     else
1089       xyz.command = "OXZ";
1090     
1091     if (cylindrical)       // Cylindrical coordinates (radius, angle, height)
1092       xyz.command += "C";
1093     else
1094       xyz.command += "S";  // Spherical coordinates (radius, angle1, angle2) --> polar if angle2 = 0
1095     
1096     if (myMode == 0)       // Absolute coordinates
1097       xyz.command += "A ";
1098     else if (myMode == 1)  // Relative coordinates
1099       xyz.command += "R ";
1100       
1101
1102     double anAngle  = GroupAngles->SpinBox_DA->value();
1103     double aLength  = GroupAngles->SpinBox_DL->value();
1104
1105     double anAngle2 = 0.0;
1106     QString da2 = "0";
1107     if (spherical) {       // Spherical coordinates (radius, angle1, angle2)
1108       anAngle2 = GroupAngles->SpinBox_DA2->value();
1109       da2 = GroupAngles->SpinBox_DA2->text();
1110     }
1111     
1112     double aHeight = 0.0;
1113     QString dh = "0";
1114     if (cylindrical) {
1115       aHeight = GroupAngles->SpinBox_DH->value();
1116       dh = GroupAngles->SpinBox_DH->text();
1117     }
1118
1119     xyz.command +=
1120       QString::number(anAngle, 'g', aPrecision) + " ";
1121     xyz.params =
1122       GroupAngles->SpinBox_DA->text() + ":"; 
1123     
1124     if(cylindrical)
1125     {
1126       xyz.command +=
1127         QString::number(aHeight, 'g', aPrecision) + " ";
1128       xyz.params +=
1129         dh + ":";
1130     }
1131     else                  // Spherical or polar coordinates
1132     {
1133       xyz.command +=
1134         QString::number(anAngle2, 'g', aPrecision) + " ";
1135       xyz.params +=
1136         dh + ":";
1137     }
1138     
1139     xyz.command +=
1140       QString::number(aLength, 'g', aPrecision);
1141     xyz.params +=
1142       GroupAngles->SpinBox_DL->text();
1143
1144       
1145     // Calculate point coordinates for preview
1146     anAngle  = anAngle * M_PI/180.0;
1147     anAngle2 = anAngle2 * M_PI/180.0;
1148     double aProjectedLength = aLength * cos(anAngle2);
1149     
1150     XYZ xyzP = getLastPoint();
1151     if (myMode == 0)
1152       xyzP.x=xyzP.y=xyzP.z=0.0; 
1153     if (GroupAngles->radioButton_1->isChecked()) // OXY
1154     {
1155       xyz.x = xyzP.x + aProjectedLength * cos(anAngle);
1156       xyz.y = xyzP.y + aProjectedLength * sin(anAngle);
1157       if (cylindrical)
1158         xyz.z = xyzP.z + aHeight;
1159       else
1160         xyz.z = xyzP.z + aLength * sin(anAngle2);
1161     }
1162     else if (GroupAngles->radioButton_2->isChecked()) // OYZ
1163     {
1164       xyz.y = xyzP.y + aProjectedLength * cos(anAngle);
1165       xyz.z = xyzP.z + aProjectedLength * sin(anAngle);
1166       if (cylindrical)
1167         xyz.x = xyzP.x + aHeight;
1168       else
1169         xyz.x = xyzP.x + aLength * sin(anAngle2);
1170     }
1171     else // OXZ
1172     {
1173       xyz.z = xyzP.z + aProjectedLength * sin(anAngle);
1174       xyz.x = xyzP.x + aProjectedLength * cos(anAngle);
1175       if (cylindrical)
1176         xyz.y = xyzP.y + aHeight;
1177       else
1178         xyz.y = xyzP.y + aLength * sin(anAngle2);
1179     }
1180   }
1181   else if(myCoordType == 0) {
1182     if (myMode == 0) { // XYZ
1183       xyz.x = Group3Spin->SpinBox_DX->value();
1184       xyz.y = Group3Spin->SpinBox_DY->value();
1185       xyz.z = Group3Spin->SpinBox_DZ->value();
1186       xyz.command = "TT ";
1187     }
1188     else { // DXDYDZ
1189       xyz = getLastPoint();
1190       xyz.x += Group3Spin->SpinBox_DX->value();
1191       xyz.y += Group3Spin->SpinBox_DY->value();
1192       xyz.z += Group3Spin->SpinBox_DZ->value();
1193       xyz.command = "T ";
1194     }
1195
1196     double aX  = Group3Spin->SpinBox_DX->value();
1197     double aY  = Group3Spin->SpinBox_DY->value();
1198     double aZ  = Group3Spin->SpinBox_DZ->value();
1199
1200     xyz.command +=
1201       QString::number(aX, 'g', aPrecision) + " " +
1202       QString::number(aY, 'g', aPrecision) + " " +
1203       QString::number(aZ, 'g', aPrecision);
1204     xyz.params =
1205       Group3Spin->SpinBox_DX->text() + ":" +
1206       Group3Spin->SpinBox_DY->text() + ":" +
1207       Group3Spin->SpinBox_DZ->text();
1208   }
1209   // Update point presentation type
1210   xyz.A = myPrsType.A;  // Number of angle diomensions
1211   xyz.L = myPrsType.L;  // Number of length dimensions
1212   
1213   return xyz;
1214 }
1215
1216
1217 //=================================================================================
1218 // function : getPresentationPlane()
1219 // purpose  : returns the suitable plane for right
1220 //            relative positioning of dimension presentations
1221 //=================================================================================
1222 gp_Dir EntityGUI_3DSketcherDlg::getPresentationPlane() const
1223
1224   bool withAngle = (myCoordType == 1);
1225   bool twoAngles = GroupAngles->checkBox->isChecked();
1226   
1227   XYZ Last    = getLastPoint();
1228   XYZ Current = getCurrentPoint();
1229   XYZ Penultimate = getPenultimatePoint();
1230   
1231   gp_Pnt P1 = gp_Pnt(Last.x,Last.y,Last.z);
1232   if (myMode == 0) // Absolute coordinates
1233     P1 = gp::Origin();
1234   
1235   gp_Pnt P2 = gp_Pnt(Current.x,Current.y,Current.z);
1236   gp_Pnt P3 = gp_Pnt(Penultimate.x,Penultimate.y,Penultimate.z);
1237   
1238   gp_Vec Vec1(P1,P2);
1239   gp_Vec Vec2(P1,P3);
1240   
1241   gp_Dir aNormal;                  // Normal defining the plane of the presentation 
1242   
1243   if (withAngle)                   // If one angle
1244   {
1245     // Transformation from the current coordinate system 
1246     // to the reference coordinate system
1247     gp_Trsf aTransform = toReferenceSystem (P1);
1248     gp_Dir N1 = gp::DZ();
1249     gp_Dir N2 = gp::DY();
1250     N1.Transform(aTransform);
1251     N2.Transform(aTransform);
1252     
1253     if (Vec1.CrossMagnitude(N1) > Precision::Confusion())
1254     {
1255       // The plane is orthogonal to the angle presentation plane 
1256       // and contains the current edge
1257       aNormal = N1.Crossed(gp_Dir(Vec1));
1258     }
1259     else
1260       aNormal = N2;
1261
1262     if (twoAngles)
1263     { 
1264       gp_Vec V = Vec1.Transformed(aTransform.Inverted());
1265       gp_Vec Vec3(V.X(),V.Y(),0.0);
1266       
1267       // Express the coordinates in the refernce coordinate system (OXY)
1268       Vec3.Transform(aTransform);   
1269       if(Abs(Vec1.CrossMagnitude(Vec3)) > Precision::Confusion())                                  
1270       { 
1271         //  set the normal as the cross product of the current edge with its projection
1272         //  it ensures that the dimension changes side when the angle becomes negative
1273         aNormal = gp_Dir(Vec1.Crossed(Vec3));  
1274       } 
1275     }         
1276   }
1277   else
1278   {
1279     // Check colinearity
1280     if (Abs(Vec1.CrossMagnitude(Vec2)) < Precision::Confusion())
1281     {
1282       Vec2 = gp_Vec(gp::DX());
1283       if (Abs(Vec1.CrossMagnitude(Vec2)) < Precision::Confusion())
1284       {
1285         Vec2 = gp_Vec(gp::DY());
1286       }
1287     }
1288     // If no angles, the plane is the one formed by the last edge and the current one
1289     aNormal = gp_Dir(Vec1.Crossed(Vec2)); 
1290   }
1291   return aNormal;
1292 }
1293
1294 //================================================================
1295 // Function : displayPreview
1296 // Purpose  : Method for displaying preview of resulting shape
1297 //            Redefined from GEOMBase_Helper.
1298 //================================================================
1299 void EntityGUI_3DSketcherDlg::displayPreview (GEOM::GEOM_Object_ptr object,
1300                                               const bool            append,
1301                                               const bool            activate,
1302                                               const bool            update,
1303                                               const double          lineWidth,
1304                                               const int             displayMode,
1305                                               const int             color)
1306 {
1307   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1308
1309   QColor aColor = resMgr->colorValue("Geometry","line_color",QColor(255,0,0));
1310   Quantity_NameOfColor line_color = SalomeApp_Tools::color(aColor).Name();
1311
1312   // set width of displayed shape
1313   int lw = lineWidth;
1314   if (lw == -1) {
1315     lw = resMgr->integerValue("Geometry", "preview_edge_width", -1);
1316   }
1317   getDisplayer()->SetWidth(lw);
1318
1319   // Disable activation of selection
1320   getDisplayer()->SetToActivate(activate);
1321
1322   // Make a reference to GEOM_Object
1323   CORBA::String_var objStr = myGeometryGUI->getApp()->orb()->object_to_string(object);
1324   getDisplayer()->SetName(objStr.in());
1325
1326   // Create wire from applied object
1327   TopoDS_Shape anApplyedWire, aLastSegment;
1328   if (!createShapes(object, anApplyedWire, aLastSegment))
1329     return;
1330
1331   // Set color for preview shape
1332   getDisplayer()->SetColor(line_color);
1333
1334   // Build prs
1335   SALOME_Prs* aPrs = getDisplayer()->BuildPrs(anApplyedWire);
1336   if (aPrs != 0 && !aPrs->IsNull())
1337     GEOMBase_Helper::displayPreview(aPrs, append, update);
1338
1339   getDisplayer()->SetColor(Quantity_NOC_VIOLET);
1340   aPrs = getDisplayer()->BuildPrs(aLastSegment);
1341
1342   if (aPrs != 0 && !aPrs->IsNull())
1343     GEOMBase_Helper::displayPreview(aPrs, append, update);
1344
1345   getDisplayer()->SetColor(line_color);
1346
1347   // Display local trihedron if the mode is relative
1348   if (myMode == 1)
1349     displayTrihedron(2);
1350
1351   // Display preview of suitable dimension presentations
1352   displayDimensions(false);
1353
1354   getDisplayer()->UnsetName();
1355
1356   // Enable activation of displayed objects
1357   getDisplayer()->SetToActivate(true);
1358 }
1359
1360 //================================================================
1361 // Function : displayTrihedron()
1362 // Purpose  : Method for displaying trihedron
1363 //================================================================
1364 void EntityGUI_3DSketcherDlg::displayTrihedron (int selMode)
1365 {
1366   // Add trihedron to preview
1367   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1368
1369   gp_Pnt P(getLastPoint().x,getLastPoint().y,getLastPoint().z);
1370   Handle(Geom_Axis2Placement) anAxis = new Geom_Axis2Placement(P,gp::DZ(),gp::DX());
1371   Handle(AIS_Trihedron) anIO = new AIS_Trihedron(anAxis);
1372   anIO->SetSelectionMode(selMode);
1373
1374   SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1375     (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1376
1377   if (aSPrs) {
1378     aSPrs->PrependObject(anIO);
1379     GEOMBase_Helper::displayPreview(aSPrs, true, true);
1380   }
1381 }
1382
1383 //================================================================
1384 // Function : displayDimensions( bool store )
1385 // Purpose  : Method for displaying dimensions. If store = true
1386 //            the presentation is stored in a list
1387 //================================================================
1388 void EntityGUI_3DSketcherDlg::displayDimensions (bool store)
1389 {
1390   myPrsType   = prsType();
1391   XYZ Last    = getLastPoint();
1392   XYZ Current = getCurrentPoint();
1393
1394   gp_Pnt Last_Pnt(Last.x,Last.y,Last.z);
1395   
1396   gp_Pnt P0 = Last_Pnt;
1397   gp_Pnt Origin = gp::Origin();
1398   if (myMode == 0)                 // Absolute coordinates
1399     P0 = Origin;
1400   
1401   gp_Pnt Current_Pnt(Current.x,Current.y,Current.z);
1402   gp_Pnt P1, P2;
1403   
1404   // Check if last end current point are coincident
1405   if (Last_Pnt.IsEqual(Current_Pnt, 1e-7))
1406     return;
1407   
1408   gp_Dir aNormal = getPresentationPlane();
1409   
1410   if (myCoordType == 0)
1411   {
1412     bool oneDimensionalMove =  (isSame(Last_Pnt.X(), Current_Pnt.X()) && 
1413                                 isSame(Last_Pnt.Y(), Current_Pnt.Y()) ) ||
1414                                (isSame(Last_Pnt.Y(), Current_Pnt.Y()) && 
1415                                 isSame(Last_Pnt.Z(), Current_Pnt.Z()) ) ||
1416                                (isSame(Last_Pnt.X(), Current_Pnt.X()) && 
1417                                 isSame(Last_Pnt.Z(), Current_Pnt.Z()) );
1418      
1419     if (myMode == 0)
1420     {
1421       std::string aCoordText = "( " + doubleToString(Current_Pnt.X()) + 
1422                                ", " + doubleToString(Current_Pnt.Y()) +
1423                                ", " + doubleToString(Current_Pnt.Z()) + " )";
1424       displayText(aCoordText, Current_Pnt, store);
1425     }
1426     else 
1427     { 
1428       if (oneDimensionalMove)
1429       {
1430         // For better colocation of dimensions if only one coordinate changes (aNormal is a better choice)
1431         displayLength(P0, Current_Pnt, aNormal, store);
1432       }
1433       else
1434       {
1435         displayLength(gp_Pnt(P0.X(),Current.y,P0.Z()), gp_Pnt(Current.x,Current.y,P0.Z()), gp::DZ().Reversed(), store);
1436         displayLength(gp_Pnt(Current.x,P0.Y(),P0.Z()), gp_Pnt(Current.x,Current.y,P0.Z()), gp::DZ(), store);
1437         displayLength(gp_Pnt(Current.x,Current.y,P0.Z()), Current_Pnt, gp::DX(), store);
1438       }
1439     }
1440   }
1441   else if (myCoordType == 1)             // ANGLES
1442   {
1443     bool spherical   = GroupAngles->checkBox->isChecked(); 
1444     bool cylindrical = GroupAngles->checkBox_2->isChecked();
1445     
1446     double anAngle1 = GroupAngles->SpinBox_DA->value();
1447     double aLength  = GroupAngles->SpinBox_DL->value();
1448     
1449     // Set the coordinates in the current coordinate system
1450     P1.SetCoord( aLength, 0.0, 0.0);    // X direction
1451     P2.SetCoord( aLength * cos(anAngle1 * M_PI / 180. ),
1452                  aLength * sin(anAngle1 * M_PI / 180. ),
1453                  0.0); 
1454     
1455     // Express the coordinates in the refernce coordinate system (OXY)
1456     gp_Trsf aTranform = toReferenceSystem(P0);
1457     P1.Transform(aTranform);    
1458     P2.Transform(aTranform);
1459     P1.Translate(Origin, P0);
1460     P2.Translate(Origin, P0);
1461     
1462     if(myMode !=0  || !store)
1463       displayAngle(anAngle1, P0, P1, P2, store);
1464     else
1465     {
1466       std::string anAngleText = doubleToString(anAngle1) + "deg";
1467       displayText(anAngleText, Current_Pnt, store);
1468     }
1469     
1470     if(spherical)
1471     {
1472       double anAngle2 = GroupAngles->SpinBox_DA2->value();
1473       displayAngle(anAngle2, P0, P2, Current_Pnt, store);
1474       displayLength(P0, Current_Pnt, aNormal, store);
1475     }
1476     else
1477     {
1478       bool sameRadius = isSame ( radius(Last_Pnt), radius(Current_Pnt) );
1479       bool sameHeight = isSame ( height(Last_Pnt), height(Current_Pnt) );
1480                             
1481       gp_Vec aVec(P2, Current_Pnt);
1482       
1483       if (myMode == 0 && !sameRadius)
1484       {
1485         displayLength(P0.Translated(aVec), P2.Translated(aVec), aNormal, store);  // Radius  
1486       }
1487       else if (myMode == 1)
1488         displayLength(P0, P2, aNormal, store);
1489       
1490       if ( cylindrical && 
1491           (myMode == 1 || !sameHeight) )
1492         displayLength(P2, Current_Pnt, aNormal.Reversed(), store); // Height
1493     }
1494   }
1495 }
1496
1497 //================================================================
1498 // Function : displayAngle()
1499 // Purpose  : Method for displaying angle dimensions
1500 //================================================================
1501 void EntityGUI_3DSketcherDlg::displayAngle (double theAngle,
1502                                             gp_Pnt P0, 
1503                                             gp_Pnt P1, 
1504                                             gp_Pnt P2,
1505                                             bool store)
1506 {
1507   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1508   
1509   // Creation of the AIS object
1510   Handle(AIS_AngleDimension) anAngleIO = createAISAngleDimension(theAngle, 
1511                                                                  P0, 
1512                                                                  P1, 
1513                                                                  P2);
1514   if (anAngleIO == NULL)
1515     return;
1516   
1517   if (store)
1518   {
1519     // Erase dimensions presentations
1520     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true);
1521     myAnglePrs->PrependObject(anAngleIO);
1522     
1523     // Display modified presentation
1524     if (isAngleVisible)
1525       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs);
1526     
1527     // Update dimension presentation angle count for later undo / redo
1528     myPrsType.A += 1;
1529   }
1530   else if ( isAngleVisible)
1531   {
1532     SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1533         (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1534         
1535     if (aSPrs)
1536     {
1537       aSPrs->AddObject(anAngleIO);
1538       GEOMBase_Helper::displayPreview(aSPrs, true, true); 
1539     }
1540   }
1541 }
1542
1543
1544 //================================================================
1545 // Function : displayLength()
1546 // Purpose  : Method for displaying length dimensions for a segment
1547 //            creation step
1548 //================================================================
1549 void EntityGUI_3DSketcherDlg::displayLength (gp_Pnt P1,
1550                                              gp_Pnt P2,
1551                                              gp_Dir theNormal,
1552                                              bool store)
1553 {
1554   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1555   
1556   double aLength = P1.Distance(P2);
1557   
1558   if (aLength < Precision::Confusion())
1559     return;
1560     
1561   Handle(AIS_LengthDimension) anIO = createAISLengthDimension(aLength, P1, P2, theNormal);
1562
1563   if (store)
1564   {
1565     // Erase length dimensions presentation
1566     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true);
1567     myLengthPrs->PrependObject(anIO);
1568
1569     // Display modified presentation
1570     if (isLengthVisible)
1571       ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs);
1572     
1573     // Update dimension presentation length count for later undo / redo
1574     myPrsType.L += 1;
1575   }
1576   else if (isLengthVisible)
1577   {
1578     SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1579       (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1580     if (aSPrs)
1581     {
1582       aSPrs->PrependObject(anIO);
1583       GEOMBase_Helper::displayPreview(aSPrs, true, true);
1584     }
1585   }
1586 }
1587
1588 //================================================================
1589 // Function : displayText()
1590 // Purpose  : Method for displaying length dimensions for a segment
1591 //            creation step
1592 //================================================================
1593 void EntityGUI_3DSketcherDlg::displayText ( std::string theText,
1594                                             gp_Pnt P,
1595                                             bool store )
1596 {
1597 #if OCC_VERSION_LARGE > 0x06050300
1598   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1599     
1600   Handle(AIS_Text) anIO = new AIS_Text(TCollection_ExtendedString(theText.c_str()), P);
1601
1602   if (store)
1603   {
1604     // Erase length dimensions presentation
1605     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myTextPrs, true);
1606     myTextPrs->PrependObject(anIO);
1607
1608     // Display modified presentation
1609     ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myTextPrs);
1610   }
1611   else
1612   {
1613     SOCC_Prs* aSPrs = dynamic_cast<SOCC_Prs*>
1614       (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
1615     if (aSPrs)
1616     {
1617       aSPrs->PrependObject(anIO);
1618       GEOMBase_Helper::displayPreview(aSPrs, true, true);
1619     }
1620   }
1621 #endif // OCC_VERSION_LARGE > 0x06050300
1622 }
1623
1624 //================================================================
1625 // Function : createAISLengthDimension()
1626 // Purpose  : Method for creation of a length dimension object
1627 //            Returns an Handle on the AIS_LengthDimension obect
1628 //================================================================
1629 Handle(AIS_LengthDimension) EntityGUI_3DSketcherDlg::createAISLengthDimension(double theLength, 
1630                                                                               gp_Pnt P1, 
1631                                                                               gp_Pnt P2, 
1632                                                                               gp_Dir theNormal)
1633 {
1634   // Convert length to string
1635   std::string aLength_str = doubleToString(theLength);
1636   
1637   // Plane construction
1638   gce_MakePln gce_MP(P1, theNormal);
1639   Handle(Geom_Plane) aPlane = new Geom_Plane(gce_MP.Value());
1640   
1641   TopoDS_Vertex aVert1 = BRepBuilderAPI_MakeVertex(P1);
1642   TopoDS_Vertex aVert2 = BRepBuilderAPI_MakeVertex(P2);
1643
1644   Handle(AIS_LengthDimension) anIO =
1645     new AIS_LengthDimension(aVert1,
1646                             aVert2,
1647                             aPlane,
1648                             theLength,
1649                             TCollection_ExtendedString(aLength_str.c_str()));
1650   anIO->SetArrowSize(theLength/20);
1651
1652   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1653   int w = resMgr->integerValue("Geometry", "measures_line_width", 1);
1654   Handle(Prs3d_LengthAspect) asp = new Prs3d_LengthAspect();
1655   asp->LineAspect()->SetWidth(w);
1656   anIO->Attributes()->SetLengthAspect(asp);
1657   
1658   return anIO;
1659 }
1660
1661 //================================================================
1662 // Function : createAISAngleDimension()
1663 // Purpose  : Method for creation of an angle dimension object
1664 //            Returns an Handle on the AIS_AngleDimension obect
1665 //================================================================
1666 Handle(AIS_AngleDimension) EntityGUI_3DSketcherDlg::createAISAngleDimension(double theAngle, 
1667                                                                             gp_Pnt P0, 
1668                                                                             gp_Pnt P1, 
1669                                                                             gp_Pnt P2)
1670 {
1671   // Length of the built segment
1672   double aLength = P0.Distance(P1);
1673   
1674   // Check input data
1675   if (Abs(theAngle) < Precision::Angular() ||
1676       aLength < Precision::Confusion())
1677     return NULL;
1678   
1679   // Convert angles to string
1680   std::string Angle_str = doubleToString(theAngle);
1681   
1682   // Construction of the plane
1683   gce_MakePln gce_MP2(P0, P1, P2);
1684   Handle(Geom_Plane) aPlane = new Geom_Plane(gce_MP2.Value());
1685   
1686   TopoDS_Vertex V0 = BRepBuilderAPI_MakeVertex(P0);
1687   TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(P1);
1688   TopoDS_Vertex V2 = BRepBuilderAPI_MakeVertex(P2);
1689   
1690   TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge(V0, V1);
1691   TopoDS_Edge anEdge2 = BRepBuilderAPI_MakeEdge(V0, V2);
1692
1693   Handle(AIS_AngleDimension) anIO =
1694     new AIS_AngleDimension(anEdge1, anEdge2, aPlane, theAngle * M_PI / 180.,
1695                            TCollection_ExtendedString(Angle_str.c_str()));
1696     
1697   anIO->SetArrowSize((theAngle * M_PI / 180) * (aLength/20));
1698   
1699   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1700   int w = resMgr->integerValue("Geometry", "measures_line_width", 1);
1701   Handle(Prs3d_AngleAspect) asp = new Prs3d_AngleAspect();
1702   asp->LineAspect()->SetWidth(w);
1703   anIO->Attributes()->SetAngleAspect(asp);
1704   
1705   return anIO;
1706 }
1707
1708 //================================================================
1709 // Function : createShapes
1710 // Purpose  : Create applyed wire, and last segment from entry object
1711 //================================================================
1712 bool EntityGUI_3DSketcherDlg::createShapes (GEOM::GEOM_Object_ptr /*theObject*/,
1713                                             TopoDS_Shape&         theApplyedWire,
1714                                             TopoDS_Shape&         theLastSegment)
1715 {
1716   QList<gp_Pnt> points;
1717   foreach (XYZ xyz, myPointsList) {
1718     gp_Pnt p(xyz.x, xyz.y, xyz.z);
1719     if (points.isEmpty() || points.last().Distance(p) > gp::Resolution())
1720       points << p;
1721   }
1722
1723   if (points.count() == 1) {
1724     // only one point is created
1725     BRepBuilderAPI_MakeVertex mkVertex (points.last());
1726     theApplyedWire = mkVertex.Shape();
1727   }
1728   else if (points.count() > 1) {
1729     // wire is created
1730     BRepBuilderAPI_MakePolygon mkWire;
1731     foreach(gp_Pnt p, points)
1732       mkWire.Add(p);
1733     theApplyedWire = mkWire.Shape();
1734   }
1735
1736   XYZ curxyz = getCurrentPoint();
1737   gp_Pnt curpnt(curxyz.x, curxyz.y, curxyz.z);
1738
1739   if (points.isEmpty() || points.last().Distance(curpnt) <= gp::Resolution()) {
1740     BRepBuilderAPI_MakeVertex mkVertex (curpnt);
1741     theLastSegment = mkVertex.Shape();
1742   }
1743   else {
1744     BRepBuilderAPI_MakeEdge mkEdge(points.last(), curpnt);
1745     theLastSegment = mkEdge.Shape();
1746   }
1747
1748   /* VSR: old algorithm does not work properly, see bug 0020899
1749   TopoDS_Shape aShape;
1750   if (!GEOMBase::GetShape(theObject, aShape))
1751     return false;
1752
1753   if (aShape.ShapeType() != TopAbs_WIRE && aShape.ShapeType() != TopAbs_VERTEX)
1754     return false;
1755
1756   theApplyedWire = aShape;
1757   if (myOK)
1758      return true;
1759
1760   BRepBuilderAPI_MakeWire aBuilder;
1761   TopExp_Explorer edgeExp(aShape, TopAbs_EDGE);
1762   while (1) {
1763     TopoDS_Shape anEdge = edgeExp.Current();
1764     edgeExp.Next();
1765     if (edgeExp.More()) // i.e. non-last edge
1766       aBuilder.Add(TopoDS::Edge(anEdge));
1767     else {
1768       theLastSegment = anEdge;
1769       break;
1770     }
1771   }
1772
1773   if (aBuilder.IsDone()) {
1774     theApplyedWire = aBuilder.Shape();
1775   }
1776   else if (!theLastSegment.IsNull()) {
1777     TopExp_Explorer vertexExp(theLastSegment, TopAbs_VERTEX);
1778     theApplyedWire = vertexExp.Current();
1779     }
1780   */
1781
1782   return true;
1783 }
1784
1785 //================================================================
1786 // Function : doubleToString
1787 // Purpose  : converts double to string
1788 //================================================================
1789 std::string EntityGUI_3DSketcherDlg::doubleToString (double num)
1790 {
1791   // truncate num
1792   int digNum = 5;
1793   char format = 'g'; // truncated to a number of significant digits
1794
1795   return QString::number(num, format, digNum).toStdString();
1796 }
1797
1798 //================================================================
1799 // Function : toReferenceSystem ()
1800 // Purpose  :
1801 //================================================================
1802 gp_Trsf EntityGUI_3DSketcherDlg::toReferenceSystem(gp_Pnt origin) const
1803
1804   gp_Trsf T;                        // Identity transformation
1805   gp_Ax3 reference_system;          // OXY
1806   reference_system.SetLocation(origin);
1807   
1808   gp_Ax3 current_system = reference_system;
1809   switch (myOrientation)
1810   {
1811     case OYZ:
1812     {
1813       current_system = gp_Ax3(origin, gp::DX(), gp::DY());
1814       break;
1815     }
1816     case OXZ:
1817     {
1818       current_system = gp_Ax3(origin, gp::DY().Reversed(), gp::DX());
1819       break;
1820     }
1821   }
1822   
1823   T.SetTransformation( current_system, reference_system );
1824   
1825   return T;
1826 }
1827
1828 //================================================================
1829 // Function : toCurrentSystem ()
1830 // Purpose  :
1831 //================================================================
1832 gp_Trsf EntityGUI_3DSketcherDlg::toCurrentSystem(gp_Pnt origin) const
1833 {
1834   return toReferenceSystem(origin).Inverted();
1835 }
1836
1837 //================================================================
1838 // Function : radius (gp_Pnt) const
1839 // Purpose  :
1840 //================================================================
1841 double EntityGUI_3DSketcherDlg::radius (gp_Pnt thePnt) const
1842 {
1843   // Get the point coordinates in the current coordinates system
1844   gp_Trsf aTrsf = toCurrentSystem(gp::Origin());
1845   gp_Pnt aPnt = thePnt.Transformed(aTrsf);
1846   
1847   double radius = sqrt(aPnt.X()*aPnt.X() + aPnt.Y()*aPnt.Y());
1848   return radius;
1849 }
1850
1851 //================================================================
1852 // Function : height (gp_Pnt) const
1853 // Purpose  :
1854 //================================================================
1855 double EntityGUI_3DSketcherDlg::height (gp_Pnt thePnt) const
1856 {
1857   // Get the point coordinates in the current coordinates system
1858   gp_Trsf aTrsf = toCurrentSystem(gp::Origin());
1859   gp_Pnt aPnt = thePnt.Transformed(aTrsf);
1860   
1861   return aPnt.Z();
1862 }