0026885: Visualization - drop redundant aspects from structure level
[occt.git] / src / AIS / AIS_Manipulator.cxx
1 // Created on: 2015-12-23
2 // Created by: Anastasia BORISOVA
3 // Copyright (c) 2015 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <AIS_Manipulator.hxx>
17
18 #include <AIS_InteractiveContext.hxx>
19 #include <AIS_ManipulatorOwner.hxx>
20 #include <gce_MakeDir.hxx>
21 #include <GeomAPI_ExtremaCurveCurve.hxx>
22 #include <GeomAPI_IntCS.hxx>
23 #include <Geom_Circle.hxx>
24 #include <Geom_Line.hxx>
25 #include <Geom_Plane.hxx>
26 #include <Geom_Transformation.hxx>
27 #include <Prs3d_Root.hxx>
28 #include <Prs3d_ShadingAspect.hxx>
29 #include <Select3D_SensitiveCircle.hxx>
30 #include <Select3D_SensitivePoint.hxx>
31 #include <Select3D_SensitiveSegment.hxx>
32 #include <Select3D_SensitiveTriangulation.hxx>
33 #include <SelectMgr_SequenceOfOwner.hxx>
34 #include <StdPrs_ToolDisk.hxx>
35 #include <StdPrs_ToolCylinder.hxx>
36 #include <StdPrs_ToolSphere.hxx>
37 #include <TColgp_Array1OfPnt.hxx>
38 #include <V3d_View.hxx>
39
40 IMPLEMENT_STANDARD_HANDLE (AIS_Manipulator, AIS_InteractiveObject)
41 IMPLEMENT_STANDARD_RTTIEXT(AIS_Manipulator, AIS_InteractiveObject)
42
43 IMPLEMENT_HSEQUENCE(AIS_ManipulatorObjectSequence)
44
45 //=======================================================================
46 //function : init
47 //purpose  : 
48 //=======================================================================
49 void AIS_Manipulator::init()
50 {
51   // Create axis in the default coordinate system. The custom position is applied in local transformation.
52   myAxes[0] = Axis (gp::OX(), Quantity_NOC_RED);
53   myAxes[1] = Axis (gp::OY(), Quantity_NOC_GREEN);
54   myAxes[2] = Axis (gp::OZ(), Quantity_NOC_BLUE1);
55
56   Graphic3d_MaterialAspect aShadingMaterial;
57   aShadingMaterial.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
58   aShadingMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
59
60   myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
61   myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
62   myDrawer->ShadingAspect()->SetColor (Quantity_NOC_WHITE);
63   myDrawer->ShadingAspect()->SetMaterial (aShadingMaterial);
64
65   Graphic3d_MaterialAspect aHilightMaterial;
66   aHilightMaterial.SetColor (Quantity_NOC_AZURE);
67   aHilightMaterial.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
68   aHilightMaterial.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
69   aHilightMaterial.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
70   aHilightMaterial.SetReflectionModeOff (Graphic3d_TOR_EMISSION);
71   aHilightMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
72
73   myHighlightAspect = new Prs3d_ShadingAspect();
74   myHighlightAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
75   myHighlightAspect->SetMaterial (aHilightMaterial);
76
77   SetSize (100);
78   SetZLayer (Graphic3d_ZLayerId_Topmost);
79 }
80
81 //=======================================================================
82 //function : getHighlightPresentation
83 //purpose  : 
84 //=======================================================================
85 Handle(Prs3d_Presentation) AIS_Manipulator::getHighlightPresentation (const Handle(SelectMgr_EntityOwner)& theOwner) const
86 {
87   Handle(Prs3d_Presentation) aDummyPrs;
88   Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theOwner);
89   if (anOwner.IsNull())
90   {
91     return aDummyPrs;
92   }
93
94   switch (anOwner->Mode())
95   {
96     case AIS_MM_Translation: return myAxes[anOwner->Index()].TranslatorHighlightPrs();
97     case AIS_MM_Rotation   : return myAxes[anOwner->Index()].RotatorHighlightPrs();
98     case AIS_MM_Scaling    : return myAxes[anOwner->Index()].ScalerHighlightPrs();
99     case AIS_MM_None       : break;
100   }
101
102   return aDummyPrs;
103 }
104
105 //=======================================================================
106 //function : getGroup
107 //purpose  : 
108 //=======================================================================
109 Handle(Graphic3d_Group) AIS_Manipulator::getGroup (const Standard_Integer theIndex, const AIS_ManipulatorMode theMode) const
110 {
111   Handle(Graphic3d_Group) aDummyGroup;
112
113   if (theIndex < 0 || theIndex > 2)
114   {
115     return aDummyGroup;
116   }
117
118   switch (theMode)
119   {
120     case AIS_MM_Translation: return myAxes[theIndex].TranslatorGroup();
121     case AIS_MM_Rotation   : return myAxes[theIndex].RotatorGroup();
122     case AIS_MM_Scaling    : return myAxes[theIndex].ScalerGroup();
123     case AIS_MM_None       : break;
124   }
125
126   return aDummyGroup;
127 }
128
129 //=======================================================================
130 //function : Constructor
131 //purpose  : 
132 //=======================================================================
133 AIS_Manipulator::AIS_Manipulator()
134 : myPosition (gp::XOY()),
135   myCurrentIndex (-1),
136   myCurrentMode (AIS_MM_None),
137   myIsActivationOnDetection (Standard_False),
138   myIsZoomPersistentMode (Standard_True),
139   myHasStartedTransformation (Standard_False),
140   myStartPosition (gp::XOY()),
141   myStartPick (0.0, 0.0, 0.0),
142   myPrevState (0.0)
143 {
144   SetInfiniteState();
145   SetMutable (Standard_True);
146   SetDisplayMode (AIS_Shaded);
147   init();
148 }
149
150 //=======================================================================
151 //function : Constructor
152 //purpose  : 
153 //=======================================================================
154 AIS_Manipulator::AIS_Manipulator (const gp_Ax2& thePosition)
155 : myPosition (thePosition),
156   myCurrentIndex (-1),
157   myCurrentMode (AIS_MM_None),
158   myIsActivationOnDetection (Standard_False),
159   myIsZoomPersistentMode (Standard_True),
160   myHasStartedTransformation (Standard_False),
161   myStartPosition (gp::XOY()),
162   myStartPick (0.0, 0.0, 0.0),
163   myPrevState (0.0)
164 {
165   SetInfiniteState();
166   SetMutable (Standard_True);
167   SetDisplayMode (AIS_Shaded);
168   init();
169 }
170
171 //=======================================================================
172 //function : SetPart
173 //purpose  : 
174 //=======================================================================
175 void AIS_Manipulator::SetPart (const Standard_Integer theAxisIndex, const AIS_ManipulatorMode theMode, const Standard_Boolean theIsEnabled)
176 {
177   Standard_ProgramError_Raise_if (theAxisIndex < 0 || theAxisIndex > 2, "AIS_Manipulator::SetMode(): axis index should be between 0 and 2");
178   switch (theMode)
179   {
180     case AIS_MM_Translation:
181       myAxes[theAxisIndex].SetTranslation (theIsEnabled);
182       break;
183
184     case AIS_MM_Rotation:
185       myAxes[theAxisIndex].SetRotation (theIsEnabled);
186       break;
187
188     case AIS_MM_Scaling:
189       myAxes[theAxisIndex].SetScaling (theIsEnabled);
190       break;
191
192     case AIS_MM_None:
193       break;
194   }
195 }
196
197 //=======================================================================
198 //function : EnableMode
199 //purpose  : 
200 //=======================================================================
201 void AIS_Manipulator::EnableMode (const AIS_ManipulatorMode theMode)
202 {
203   if (!IsAttached())
204   {
205     return;
206   }
207
208   const Handle(AIS_InteractiveContext)& aContext = GetContext();
209   if (aContext.IsNull())
210   {
211     return;
212   }
213
214   aContext->Activate (this, theMode);
215 }
216
217 //=======================================================================
218 //function : attachToBox
219 //purpose  : 
220 //=======================================================================
221 void AIS_Manipulator::attachToBox (const Bnd_Box& theBox)
222 {
223   if (theBox.IsVoid())
224   {
225     return;
226   }
227
228   Standard_Real anXmin = 0.0, anYmin = 0.0, aZmin = 0.0, anXmax = 0.0, anYmax = 0.0, aZmax = 0.0;
229   theBox.Get (anXmin, anYmin, aZmin, anXmax, anYmax, aZmax);
230
231   gp_Ax2 aPosition = gp::XOY();
232   aPosition.SetLocation (gp_Pnt ((anXmin + anXmax) * 0.5, (anYmin + anYmax) * 0.5, (aZmin + aZmax) * 0.5));
233   SetPosition (aPosition);
234 }
235
236 //=======================================================================
237 //function : adjustSize
238 //purpose  : 
239 //=======================================================================
240 void AIS_Manipulator::adjustSize (const Bnd_Box& theBox)
241 {
242   Standard_Real aXmin = 0., aYmin = 0., aZmin = 0., aXmax = 0., aYmax = 0., aZmax = 0.0;
243   theBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
244   Standard_Real aXSize = aXmax - aXmin;
245   Standard_Real aYSize = aYmax - aYmin;
246   Standard_Real aZSize  = aZmax  - aZmin;
247
248   SetSize ((Standard_ShortReal) (Max (aXSize, Max (aYSize, aZSize)) * 0.5));
249 }
250
251 //=======================================================================
252 //function : Attach
253 //purpose  : 
254 //=======================================================================
255 void AIS_Manipulator::Attach (const Handle(AIS_InteractiveObject)& theObject, const OptionsForAttach& theOptions)
256 {
257   if (theObject->IsKind (STANDARD_TYPE(AIS_Manipulator)))
258   {
259     return;
260   }
261
262   Handle(AIS_ManipulatorObjectSequence) aSeq = new AIS_ManipulatorObjectSequence();
263   aSeq->Append (theObject);
264   Attach (aSeq, theOptions);
265 }
266
267 //=======================================================================
268 //function : Attach
269 //purpose  : 
270 //=======================================================================
271 void AIS_Manipulator::Attach (const Handle(AIS_ManipulatorObjectSequence)& theObjects, const OptionsForAttach& theOptions)
272 {
273   if (theObjects->Size() < 1)
274   {
275     return;
276   }
277
278   SetOwner (theObjects);
279   Bnd_Box aBox;
280   const Handle(AIS_InteractiveObject)& aCurObject = theObjects->Value (theObjects->Lower());
281   aCurObject->BoundingBox (aBox);
282
283   if (theOptions.AdjustPosition)
284   {
285     attachToBox (aBox);
286   }
287
288   if (theOptions.AdjustSize)
289   {
290     adjustSize (aBox);
291   }
292
293   const Handle(AIS_InteractiveContext)& aContext = Object()->GetContext();
294   if (!aContext.IsNull())
295   {
296     if (!aContext->IsDisplayed (this))
297     {
298       aContext->Display (this, Standard_False);
299     }
300     else
301     {
302       aContext->Update (this, Standard_False);
303       aContext->RecomputeSelectionOnly (this);
304     }
305
306     aContext->Load (this);
307     aContext->CurrentViewer()->RedrawImmediate();
308   }
309
310   if (theOptions.EnableModes)
311   {
312     EnableMode (AIS_MM_Rotation);
313     EnableMode (AIS_MM_Translation);
314     EnableMode (AIS_MM_Scaling);
315   }
316 }
317
318 //=======================================================================
319 //function : Detach
320 //purpose  : 
321 //=======================================================================
322 void AIS_Manipulator::Detach()
323 {
324   DeactivateCurrentMode();
325
326   if (!IsAttached())
327   {
328     return;
329   }
330
331   Handle(AIS_InteractiveObject) anObject = Object();
332   const Handle(AIS_InteractiveContext)& aContext = anObject->GetContext();
333   if (!aContext.IsNull())
334   {
335     aContext->Remove (this, Standard_False);
336   }
337
338   SetOwner (NULL);
339 }
340
341 //=======================================================================
342 //function : Objects
343 //purpose  : 
344 //=======================================================================
345 Handle(AIS_ManipulatorObjectSequence) AIS_Manipulator::Objects() const
346 {
347   return Handle(AIS_ManipulatorObjectSequence)::DownCast (GetOwner());
348 }
349
350 //=======================================================================
351 //function : Object
352 //purpose  : 
353 //=======================================================================
354 Handle(AIS_InteractiveObject) AIS_Manipulator::Object (const Standard_Integer theIndex) const
355 {
356   Handle(AIS_ManipulatorObjectSequence) anOwner = Handle(AIS_ManipulatorObjectSequence)::DownCast (GetOwner());
357
358   Standard_ProgramError_Raise_if (theIndex < anOwner->Lower() || theIndex > anOwner->Upper(), "AIS_Manipulator::Object(): wrong index value");
359
360   if (anOwner.IsNull() || anOwner->IsEmpty())
361   {
362     return NULL;
363   }
364
365   return anOwner->Value (theIndex);
366 }
367
368 //=======================================================================
369 //function : Object
370 //purpose  : 
371 //=======================================================================
372 Handle(AIS_InteractiveObject) AIS_Manipulator::Object() const
373 {
374   return Object (1);
375 }
376
377 //=======================================================================
378 //function : ObjectTransformation
379 //purpose  : 
380 //=======================================================================
381 Standard_Boolean AIS_Manipulator::ObjectTransformation (const Standard_Integer theMaxX, const Standard_Integer theMaxY,
382                                                         const Handle(V3d_View)& theView, gp_Trsf& theTrsf)
383 {
384   // Initialize start reference data
385   if (!myHasStartedTransformation)
386   {
387     Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
388     myStartTrsfs.Clear();
389     for (Standard_Integer anIt = anObjects->Lower(); anIt <= anObjects->Upper(); ++anIt)
390     {
391       myStartTrsfs.Append (anObjects->Value (anIt)->LocalTransformation());
392     }
393     myStartPosition = myPosition;
394   }
395
396   // Get 3d point with projection vector
397   Graphic3d_Vec3d anInputPoint;
398   Graphic3d_Vec3d aProj;
399   theView->ConvertWithProj (theMaxX, theMaxY, anInputPoint.x(), anInputPoint.y(), anInputPoint.z(), aProj.x(), aProj.y(), aProj.z());
400   gp_Lin anInputLine (gp_Pnt (anInputPoint.x(), anInputPoint.y(), anInputPoint.z()), gp_Dir (aProj.x(), aProj.y(), aProj.z()));
401   gp_Pnt aNewPosition = gp::Origin();
402
403   switch (myCurrentMode)
404   {
405     case AIS_MM_Translation:
406     {
407       gp_Lin aLine (myStartPick, myAxes[myCurrentIndex].Position().Direction());
408       Handle(Geom_Curve) anInputCurve = new Geom_Line (anInputLine);
409       Handle(Geom_Curve) aCurve = new Geom_Line (aLine);
410       GeomAPI_ExtremaCurveCurve anExtrema (anInputCurve, aCurve);
411       gp_Pnt aP1, aP2;
412       anExtrema.NearestPoints (aP1, aP2);
413       aNewPosition = aP2;
414
415       if (!myHasStartedTransformation)
416       {
417         myStartPick = aNewPosition;
418         myHasStartedTransformation = Standard_True;
419         return Standard_True;
420       }
421
422       if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
423       {
424         return Standard_False;
425       }
426
427       gp_Trsf aNewTrsf;
428       aNewTrsf.SetTranslation (gp_Vec(myStartPick, aNewPosition));
429       theTrsf *= aNewTrsf;
430       break;
431     }
432     case AIS_MM_Rotation:
433     {
434       Handle(Geom_Curve) anInputCurve = new Geom_Line (anInputLine);
435       Handle(Geom_Surface) aSurface = new Geom_Plane (myPosition.Location(), myAxes[myCurrentIndex].Position().Direction());
436       GeomAPI_IntCS aIntersector (anInputCurve, aSurface);
437       if (!aIntersector.IsDone() || aIntersector.NbPoints() < 1)
438       {
439         return Standard_False;
440       }
441
442       aNewPosition = aIntersector.Point (1);
443
444       if (!myHasStartedTransformation)
445       {
446         myStartPick = aNewPosition;
447         myHasStartedTransformation = Standard_True;
448         gp_Dir aStartAxis = gce_MakeDir (myPosition.Location(), myStartPick);
449         myPrevState = aStartAxis.AngleWithRef (gce_MakeDir(myPosition.Location(), aNewPosition), myAxes[myCurrentIndex].Position().Direction());
450         return Standard_True;
451       }
452
453       if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
454       {
455         return Standard_False;
456       }
457
458       gp_Dir aStartAxis = myPosition.Location().IsEqual (myStartPick, Precision::Confusion())
459         ? myAxes[(myCurrentIndex + 1) % 3].Position().Direction()
460         : gce_MakeDir (myPosition.Location(), myStartPick);
461
462       gp_Dir aCurrentAxis = gce_MakeDir (myPosition.Location(), aNewPosition);
463       Standard_Real anAngle = aStartAxis.AngleWithRef (aCurrentAxis, myAxes[myCurrentIndex].Position().Direction());
464
465       // Change value of an angle if it should have different sign.
466       if (anAngle * myPrevState < 0 && Abs (anAngle) < M_PI_2)
467       {
468         Standard_ShortReal aSign = myPrevState > 0 ? -1.0f : 1.0f;
469         anAngle = aSign * (M_PI * 2 - anAngle);
470       }
471
472       if (Abs (anAngle) < Precision::Confusion())
473       {
474         return Standard_False;
475       }
476
477       gp_Trsf aNewTrsf;
478       aNewTrsf.SetRotation (myAxes[myCurrentIndex].Position(), anAngle);
479       theTrsf *= aNewTrsf;
480       myPrevState = anAngle;
481       break;
482     }
483     case AIS_MM_Scaling:
484     {
485       gp_Lin aLine (myStartPosition.Location(), myAxes[myCurrentIndex].Position().Direction());
486       Handle(Geom_Curve) anInputCurve = new Geom_Line (anInputLine);
487       Handle(Geom_Curve) aCurve = new Geom_Line (aLine);
488       GeomAPI_ExtremaCurveCurve anExtrema (anInputCurve, aCurve);
489       gp_Pnt aTmp;
490       anExtrema.NearestPoints (aTmp, aNewPosition);
491
492       if (!myHasStartedTransformation)
493       {
494         myStartPick = aNewPosition;
495         myHasStartedTransformation = Standard_True;
496         return Standard_True;
497       }
498
499       if (aNewPosition.Distance (myStartPick) < Precision::Confusion() 
500        || aNewPosition.Distance (myStartPosition.Location()) < Precision::Confusion())
501       {
502         return Standard_False;
503       }
504
505       Standard_Real aCoeff = myStartPosition.Location().Distance (aNewPosition)
506                            / myStartPosition.Location().Distance (myStartPick);
507       gp_Trsf aNewTrsf;
508       aNewTrsf.SetScale (myPosition.Location(), aCoeff);
509
510       theTrsf = aNewTrsf;
511       break;
512     }
513     case AIS_MM_None:
514       return Standard_False;
515   }
516
517   return Standard_True;
518 }
519
520 //=======================================================================
521 //function : StartTransform
522 //purpose  : 
523 //=======================================================================
524 void AIS_Manipulator::StartTransform (const Standard_Integer theX, const Standard_Integer theY, const Handle(V3d_View)& theView)
525 {
526   if (myHasStartedTransformation)
527   {
528     return;
529   }
530
531   gp_Trsf aTrsf;
532   ObjectTransformation (theX, theY, theView, aTrsf);
533 }
534
535 //=======================================================================
536 //function : StopTransform
537 //purpose  : 
538 //=======================================================================
539 void AIS_Manipulator::StopTransform (const Standard_Boolean theToApply)
540 {
541   if (!IsAttached() || !myHasStartedTransformation)
542   {
543     return;
544   }
545
546   myHasStartedTransformation = Standard_False;
547
548   if (!theToApply)
549   {
550     Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
551
552     for (Standard_Integer anIt = anObjects->Lower(); anIt <= anObjects->Upper(); ++anIt)
553     {
554       anObjects->Value (anIt)->SetLocalTransformation (myStartTrsfs(anIt));
555     }
556
557     SetPosition (myStartPosition);
558   }
559 }
560
561 //=======================================================================
562 //function : Transform
563 //purpose  : 
564 //=======================================================================
565 void AIS_Manipulator::Transform (const gp_Trsf& theTrsf)
566 {
567   if (!IsAttached() || !myHasStartedTransformation)
568   {
569     return;
570   }
571
572   Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
573
574   for (Standard_Integer anIt = anObjects->Lower(); anIt <= anObjects->Upper(); ++anIt)
575   {
576     anObjects->Value (anIt)->SetLocalTransformation (theTrsf * myStartTrsfs(anIt));
577   }
578
579   if ((myCurrentMode == AIS_MM_Translation && myBehaviorOnTransform.FollowTranslation)
580    || (myCurrentMode == AIS_MM_Rotation    && myBehaviorOnTransform.FollowRotation))
581   {
582     gp_Pnt aPos  = myStartPosition.Location().Transformed (theTrsf);
583     gp_Dir aVDir = myStartPosition.Direction().Transformed (theTrsf);
584     gp_Dir aXDir = myStartPosition.XDirection().Transformed (theTrsf);
585     SetPosition (gp_Ax2 (aPos, aVDir, aXDir));
586   }
587 }
588
589 //=======================================================================
590 //function : Transform
591 //purpose  : 
592 //=======================================================================
593 gp_Trsf AIS_Manipulator::Transform (const Standard_Integer thePX, const Standard_Integer thePY,
594                                     const Handle(V3d_View)& theView)
595 {
596   gp_Trsf aTrsf;
597   if (ObjectTransformation (thePX, thePY, theView, aTrsf))
598   {
599     Transform (aTrsf);
600   }
601
602   return aTrsf;
603 }
604
605 //=======================================================================
606 //function : SetPosition
607 //purpose  : 
608 //=======================================================================
609 void AIS_Manipulator::SetPosition (const gp_Ax2& thePosition)
610 {
611   if (!myPosition.Location().IsEqual (thePosition.Location(), Precision::Confusion())
612    || !myPosition.Direction().IsEqual (thePosition.Direction(), Precision::Angular())
613    || !myPosition.XDirection().IsEqual (thePosition.XDirection(), Precision::Angular()))
614   {
615     myPosition = thePosition;
616     myAxes[0].SetPosition (gp_Ax1 (myPosition.Location(), myPosition.XDirection()));
617     myAxes[1].SetPosition (gp_Ax1 (myPosition.Location(), myPosition.YDirection()));
618     myAxes[2].SetPosition (gp_Ax1 (myPosition.Location(), myPosition.Direction()));
619
620     updateTransformation();
621   }
622 }
623
624 //=======================================================================
625 //function : updateTransformation
626 //purpose  : set local transformation to avoid graphics recomputation
627 //=======================================================================
628 void AIS_Manipulator::updateTransformation()
629 {
630   gp_Trsf aTrsf;
631
632   if (!myIsZoomPersistentMode)
633   {
634     aTrsf.SetTransformation (myPosition, gp::XOY());
635   }
636   else
637   {
638     const gp_Dir& aVDir = myPosition.Direction();
639     const gp_Dir& aXDir = myPosition.XDirection();
640     aTrsf.SetTransformation (gp_Ax2 (gp::Origin(), aVDir, aXDir), gp::XOY());
641   }
642
643   AIS_InteractiveObject::SetLocalTransformation (aTrsf);
644
645   Handle(Geom_Transformation) aGeomTrsf = new Geom_Transformation (this->Transformation());
646
647   for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
648   {
649     myAxes[anIt].Transform (aGeomTrsf);
650   }
651
652   if (myIsZoomPersistentMode)
653   {
654     if (!(GetTransformPersistenceMode () == Graphic3d_TMF_ZoomPers
655        && GetTransformPersistencePoint().IsEqual (myPosition.Location(), 0.)))
656     {
657       setTransformPersistence (Graphic3d_TMF_ZoomPers, myPosition.Location());
658     }
659   }
660 }
661
662 //=======================================================================
663 //function : SetSize
664 //purpose  : 
665 //=======================================================================
666 void AIS_Manipulator::SetSize (const Standard_ShortReal theSideLength)
667 {
668   for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
669   {
670     myAxes[anIt].SetSize (theSideLength);
671   }
672
673   SetToUpdate();
674 }
675
676 //=======================================================================
677 //function : SetGap
678 //purpose  : 
679 //=======================================================================
680 void AIS_Manipulator::SetGap (const Standard_ShortReal theValue)
681 {
682   for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
683   {
684     myAxes[anIt].SetIndent (theValue);
685   }
686
687   SetToUpdate();
688 }
689
690 //=======================================================================
691 //function : DeactivateCurrentMode
692 //purpose  : 
693 //=======================================================================
694 void AIS_Manipulator::DeactivateCurrentMode()
695 {
696   if (!myIsActivationOnDetection)
697   {
698     Handle(Graphic3d_Group) aGroup = getGroup (myCurrentIndex, myCurrentMode);
699     if (aGroup.IsNull())
700     {
701       return;
702     }
703
704     Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
705     anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
706     anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
707     anAspect->SetTransparency (myDrawer->ShadingAspect()->Transparency());
708     anAspect->SetColor (myAxes[myCurrentIndex].Color());
709
710     aGroup->SetGroupPrimitivesAspect (anAspect->Aspect());
711   }
712
713   myCurrentIndex = -1;
714   myCurrentMode = AIS_MM_None;
715
716   if (myHasStartedTransformation)
717   {
718     myHasStartedTransformation = Standard_False;
719   }
720 }
721
722 //=======================================================================
723 //function : SetZoomPersistence
724 //purpose  : 
725 //=======================================================================
726 void AIS_Manipulator::SetZoomPersistence (const Standard_Boolean theToEnable)
727 {
728   if (myIsZoomPersistentMode != theToEnable)
729   {
730     SetToUpdate();
731   }
732
733   myIsZoomPersistentMode = theToEnable;
734
735   if (!theToEnable)
736   {
737     setTransformPersistence (Graphic3d_TMF_None, gp::Origin());
738   }
739
740   updateTransformation();
741 }
742
743 //=======================================================================
744 //function : SetTransformPersistence
745 //purpose  : 
746 //=======================================================================
747 void AIS_Manipulator::SetTransformPersistence (const Graphic3d_TransModeFlags& theFlag, const gp_Pnt& thePoint)
748 {
749   Standard_ASSERT_RETURN (!myIsZoomPersistentMode,
750     "AIS_Manipulator::SetTransformPersistence: "
751     "Custom settings are not supported by this class in ZoomPersistence mode",);
752
753   setTransformPersistence (theFlag, thePoint);
754 }
755
756 //=======================================================================
757 //function : setTransformPersistence
758 //purpose  : 
759 //=======================================================================
760 void AIS_Manipulator::setTransformPersistence (const Graphic3d_TransModeFlags& theFlag, const gp_Pnt& thePoint)
761 {
762   AIS_InteractiveObject::SetTransformPersistence (theFlag, thePoint);
763
764   for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
765   {
766     myAxes[anIt].SetTransformPersistence (theFlag, thePoint);
767   }
768 }
769
770 //=======================================================================
771 //function : SetLocalTransformation
772 //purpose  : 
773 //=======================================================================
774 void AIS_Manipulator::SetLocalTransformation (const gp_Trsf& /*theTransformation*/)
775 {
776   Standard_ASSERT_INVOKE (
777     "AIS_Manipulator::SetLocalTransformation: "
778     "Custom transformation is not supported by this class");
779 }
780
781 //=======================================================================
782 //function : Compute
783 //purpose  : 
784 //=======================================================================
785 void AIS_Manipulator::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
786                                const Handle(Prs3d_Presentation)& thePrs,
787                                const Standard_Integer theMode)
788 {
789   if (theMode != AIS_Shaded)
790   {
791     return;
792   }
793
794   thePrs->SetInfiniteState (Standard_True);
795   thePrs->SetMutable (Standard_True);
796   Handle(Graphic3d_Group) aGroup;
797   Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
798   anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
799   anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
800   anAspect->SetTransparency (myDrawer->ShadingAspect()->Transparency());
801
802   // Display center
803   myCenter.Init (myAxes[0].AxisRadius() * 2.0f, gp::Origin());
804   aGroup = Prs3d_Root::NewGroup (thePrs);
805   aGroup->SetPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
806   aGroup->AddPrimitiveArray (myCenter.Array());
807
808   for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
809   {
810     // Display axes
811     aGroup = Prs3d_Root::NewGroup (thePrs);
812     anAspect->SetColor (myAxes[anIt].Color());
813     aGroup->SetGroupPrimitivesAspect (anAspect->Aspect());
814     myAxes[anIt].Compute (thePrsMgr, thePrs, anAspect);
815     myAxes[anIt].SetTransformPersistence (GetTransformPersistenceMode(),
816                                           GetTransformPersistencePoint());
817   }
818
819   updateTransformation();
820 }
821
822 //=======================================================================
823 //function : HilightSelected
824 //purpose  : 
825 //=======================================================================
826 void AIS_Manipulator::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
827                                        const SelectMgr_SequenceOfOwner& theSeq)
828 {
829   if (theSeq.IsEmpty())
830   {
831     return;
832   }
833
834   if (myIsActivationOnDetection)
835   {
836     return;
837   }
838
839   if (!theSeq (1)->IsKind (STANDARD_TYPE (AIS_ManipulatorOwner)))
840   {
841     thePM->Color (this, GetContext()->HilightColor(), 0);
842     return;
843   }
844
845   Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theSeq (1));
846   myHighlightAspect->Aspect()->SetInteriorColor (GetContext()->HilightColor());
847   Handle(Graphic3d_Group) aGroup = getGroup (anOwner->Index(), anOwner->Mode());
848   if (aGroup.IsNull())
849   {
850     return;
851   }
852
853   aGroup->SetGroupPrimitivesAspect (myHighlightAspect->Aspect());
854
855   myCurrentIndex = anOwner->Index();
856   myCurrentMode = anOwner->Mode();
857 }
858
859 //=======================================================================
860 //function : ClearSelected
861 //purpose  :
862 //=======================================================================
863 void AIS_Manipulator::ClearSelected()
864 {
865   DeactivateCurrentMode();
866 }
867
868 //=======================================================================
869 //function : HilightOwnerWithColor
870 //purpose  : 
871 //=======================================================================
872 void AIS_Manipulator::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM, const Quantity_NameOfColor theColor, const Handle(SelectMgr_EntityOwner)& theOwner)
873 {
874   Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theOwner);
875   Handle(Prs3d_Presentation) aPresentation = getHighlightPresentation (anOwner);
876   if (aPresentation.IsNull())
877   {
878     return;
879   }
880   aPresentation->Highlight (Aspect_TOHM_COLOR, theColor);
881   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPresentation->Groups());
882        aGroupIter.More(); aGroupIter.Next())
883   {
884     Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
885     if (!aGrp.IsNull()
886      && aGrp->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
887     {
888       aGrp->SetGroupPrimitivesAspect (myHighlightAspect->Aspect());
889     }
890   }
891   aPresentation->SetZLayer (Graphic3d_ZLayerId_Topmost);
892   thePM->AddToImmediateList (aPresentation);
893
894   if (myIsActivationOnDetection)
895   {
896     if (HasActiveMode())
897     {
898       DeactivateCurrentMode();
899     }
900
901     myCurrentIndex = anOwner->Index();
902     myCurrentMode = anOwner->Mode();
903   }
904 }
905
906 //=======================================================================
907 //function : ComputeSelection
908 //purpose  : 
909 //=======================================================================
910 void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
911                                         const Standard_Integer theMode)
912 {
913   //Check mode
914   AIS_ManipulatorMode aMode = (AIS_ManipulatorMode) theMode;
915   if (aMode == AIS_MM_None)
916   {
917     return;
918   }
919   Handle(SelectMgr_EntityOwner) anOwner;
920   if (aMode == AIS_MM_None)
921   {
922     anOwner = new SelectMgr_EntityOwner (this, 5);
923   }
924   Handle(Select3D_SensitiveTriangulation) aTri;
925   if (aMode == AIS_MM_Translation || aMode == AIS_MM_None)
926   {
927     for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
928     {
929       const Axis& anAxis = myAxes[anIt];
930       if (aMode != AIS_MM_None)
931       {
932         anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_Translation, 9);
933       }
934       // define sensitivity by line
935       Handle(Select3D_SensitiveSegment) aLine = new Select3D_SensitiveSegment (anOwner, gp::Origin(), anAxis.TranslatorTipPosition());
936       aLine->SetSensitivityFactor (15);
937       theSelection->Add (aLine);
938       // enlarge sensitivity by triangulation
939       aTri = new Select3D_SensitiveTriangulation (anOwner, anAxis.TranslatorCylinder().Triangulation(), TopLoc_Location(), Standard_True);
940       theSelection->Add (aTri);
941       aTri = new Select3D_SensitiveTriangulation (anOwner, anAxis.TranslatorArrow().Triangulation(), TopLoc_Location(), Standard_True);
942       theSelection->Add (aTri);
943       aTri = new Select3D_SensitiveTriangulation (anOwner, anAxis.TranslatorArrowBottom().Triangulation(), TopLoc_Location(), Standard_True);
944       theSelection->Add (aTri);
945     }
946   }
947
948   if (aMode == AIS_MM_Rotation || aMode == AIS_MM_None)
949   {
950     for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
951     {
952       const Axis& anAxis = myAxes[anIt];
953       if (aMode != AIS_MM_None)
954       {
955         anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Rotation, 9);
956       }
957       // define sensitivity by circle
958       Handle(Geom_Circle) aGeomCircle = new Geom_Circle (gp_Ax2 (gp::Origin(), anAxis.ReferenceAxis().Direction()), anAxis.RotatorDiskRadius());
959       Handle(Select3D_SensitiveCircle) aCircle = new Select3D_SensitiveCircle (anOwner, aGeomCircle, Standard_False, anAxis.FacettesNumber());
960       aCircle->SetSensitivityFactor (15);
961       theSelection->Add (aCircle);
962       // enlarge sensitivity by triangulation
963       aTri = new Select3D_SensitiveTriangulation (anOwner, myAxes[anIt].RotatorDisk().Triangulation(), TopLoc_Location(), Standard_True);
964       theSelection->Add (aTri);
965     }
966   }
967
968   if (aMode == AIS_MM_Scaling || aMode == AIS_MM_None)
969   {
970     for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
971     {
972       if (aMode != AIS_MM_None)
973       {
974         anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Scaling, 9);
975       }
976       // define sensitivity by point
977       Handle(Select3D_SensitivePoint) aPnt = new Select3D_SensitivePoint (anOwner, myAxes[anIt].ScalerCubePosition());
978       aPnt->SetSensitivityFactor (15);
979       theSelection->Add (aPnt);
980       // enlarge sensitivity by triangulation
981       aTri = new Select3D_SensitiveTriangulation (anOwner, myAxes[anIt].ScalerCube().Triangulation(), TopLoc_Location(), Standard_True);
982       theSelection->Add (aTri);
983     }
984   }
985 }
986
987 //=======================================================================
988 //class    : Cylinder
989 //function : Init
990 //purpose  : 
991 //=======================================================================
992 void AIS_Manipulator::Cylinder::Init (const Standard_ShortReal theBotRad, const Standard_ShortReal theTopRad,
993                                       const Standard_ShortReal theHeight,
994                                       const Standard_Integer theSlicesNb, const Standard_Integer theStacksNb,
995                                       const gp_Ax1& thePosition)
996 {
997   myPosition = thePosition;
998   myBottomRad = theBotRad;
999   myTopRad = theTopRad;
1000   myHeight = theHeight;
1001
1002   StdPrs_ToolCylinder aTool (myBottomRad, myTopRad, myHeight, theSlicesNb, theStacksNb);
1003   gp_Ax3 aSystem (myPosition.Location(), myPosition.Direction());
1004   gp_Trsf aTrsf;
1005   aTrsf.SetTransformation (aSystem, gp_Ax3());
1006
1007   aTool.FillArray (myArray, myTriangulation, aTrsf);
1008 }
1009
1010 //=======================================================================
1011 //class    : Disk
1012 //function : Init
1013 //purpose  : 
1014 //=======================================================================
1015 void AIS_Manipulator::Disk::Init (const Standard_ShortReal theInnerRadius,
1016                                   const Standard_ShortReal theOuterRadius,
1017                                   const gp_Ax1& thePosition,
1018                                   const Standard_Integer theSlicesNb,
1019                                   const Standard_Integer theStacksNb)
1020 {
1021   myPosition = thePosition;
1022   myInnerRad = theInnerRadius;
1023   myOuterRad = theOuterRadius;
1024
1025   StdPrs_ToolDisk aTool (theInnerRadius, theOuterRadius, theSlicesNb, theStacksNb);
1026   gp_Ax3 aSystem (myPosition.Location(), myPosition.Direction());
1027   gp_Trsf aTrsf;
1028   aTrsf.SetTransformation (aSystem, gp_Ax3());
1029   aTool.FillArray (myArray, myTriangulation, aTrsf);
1030 }
1031
1032 //=======================================================================
1033 //class    : Sphere
1034 //function : Init
1035 //purpose  : 
1036 //=======================================================================
1037 void AIS_Manipulator::Sphere::Init (const Standard_ShortReal theRadius,
1038                                     const gp_Pnt& thePosition,
1039                                     const Standard_Integer theSlicesNb,
1040                                     const Standard_Integer theStacksNb)
1041 {
1042   myPosition = thePosition;
1043   myRadius = theRadius;
1044
1045   StdPrs_ToolSphere aTool (theRadius, theSlicesNb, theStacksNb);
1046   gp_Trsf aTrsf;
1047   aTrsf.SetTranslation (gp_Vec(gp::Origin(), thePosition));
1048   aTool.FillArray (myArray, myTriangulation, aTrsf);
1049 }
1050
1051 //=======================================================================
1052 //class    : Cube
1053 //function : Init
1054 //purpose  : 
1055 //=======================================================================
1056 void AIS_Manipulator::Cube::Init (const gp_Ax1& thePosition, const Standard_ShortReal theSize)
1057 {
1058   myArray = new Graphic3d_ArrayOfTriangles (12 * 3, 0, Standard_True);
1059
1060   Poly_Array1OfTriangle aPolyTriangles (1, 12);
1061   TColgp_Array1OfPnt aPoints (1, 36);
1062   NCollection_Array1<gp_Dir> aNormals (1, 12);
1063   myTriangulation = new Poly_Triangulation (aPoints, aPolyTriangles);
1064
1065   gp_Ax2 aPln (thePosition.Location(), thePosition.Direction());
1066   gp_Pnt aBottomLeft = thePosition.Location().XYZ() - aPln.XDirection().XYZ() * theSize * 0.5 - aPln.YDirection().XYZ() * theSize * 0.5;
1067   gp_Pnt aV2 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize;
1068   gp_Pnt aV3 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize + aPln.XDirection().XYZ() * theSize;
1069   gp_Pnt aV4 = aBottomLeft.XYZ() + aPln.XDirection().XYZ() * theSize;
1070   gp_Pnt aTopRight = thePosition.Location().XYZ() + thePosition.Direction().XYZ() * theSize
1071     + aPln.XDirection().XYZ() * theSize * 0.5 + aPln.YDirection().XYZ() * theSize * 0.5;
1072   gp_Pnt aV5 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize;
1073   gp_Pnt aV6 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize - aPln.XDirection().XYZ() * theSize;
1074   gp_Pnt aV7 = aTopRight.XYZ() - aPln.XDirection().XYZ() * theSize;
1075
1076   gp_Dir aRight ((gp_Vec(aTopRight, aV7) ^ gp_Vec(aTopRight, aV2)).XYZ());
1077   gp_Dir aFront ((gp_Vec(aV3, aV4) ^ gp_Vec(aV3, aV5)).XYZ());
1078
1079   // Bottom
1080   addTriangle (0, aBottomLeft, aV2, aV3, -thePosition.Direction());
1081   addTriangle (1, aBottomLeft, aV3, aV4, -thePosition.Direction());
1082
1083   // Front
1084   addTriangle (2, aV3, aV4, aV5, aFront);
1085   addTriangle (3, aV3, aV5, aTopRight, aFront);
1086
1087   // Back
1088   addTriangle (4, aBottomLeft, aV2, aV7, -aFront);
1089   addTriangle (5, aBottomLeft, aV7, aV6, -aFront);
1090
1091   // aTop
1092   addTriangle (6, aV7, aV6, aV5, thePosition.Direction());
1093   addTriangle (7, aTopRight, aV7, aV5, thePosition.Direction());
1094
1095   //Left
1096   addTriangle (8, aV6, aV5, aV4, -aRight);
1097   addTriangle (9, aBottomLeft, aV6, aV4, -aRight);
1098
1099   // Right
1100   addTriangle (10, aV3, aTopRight, aV7, aRight);
1101   addTriangle (11, aV3, aV7, aV2, aRight);
1102 }
1103
1104 //=======================================================================
1105 //class    : Cube
1106 //function : addTriangle
1107 //purpose  : 
1108 //=======================================================================
1109 void AIS_Manipulator::Cube::addTriangle (const Standard_Integer theIndex,
1110                                          const gp_Pnt& theP1, const gp_Pnt& theP2, const gp_Pnt& theP3,
1111                                          const gp_Dir& theNormal)
1112 {
1113   myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 1, theP1);
1114   myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 2, theP2);
1115   myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 3, theP3);
1116
1117   myTriangulation->ChangeTriangles().SetValue (theIndex + 1, Poly_Triangle (theIndex * 3 + 1, theIndex * 3 + 2, theIndex * 3 + 3));
1118   myArray->AddVertex (theP1, theNormal);
1119   myArray->AddVertex (theP2, theNormal);
1120   myArray->AddVertex (theP3, theNormal);
1121 }
1122
1123 //=======================================================================
1124 //class    : Axis
1125 //function : Constructor
1126 //purpose  : 
1127 //=======================================================================
1128 AIS_Manipulator::Axis::Axis (const gp_Ax1& theAxis,
1129                              const Quantity_Color& theColor,
1130                              const Standard_ShortReal theLength)
1131 : myReferenceAxis (theAxis),
1132   myPosition (theAxis),
1133   myColor (theColor),
1134   myHasTranslation (Standard_True),
1135   myLength (theLength),
1136   myAxisRadius (0.5f),
1137   myHasScaling (Standard_True),
1138   myBoxSize (2.0f),
1139   myHasRotation (Standard_True),
1140   myInnerRadius (myLength + myBoxSize),
1141   myDiskThickness (myBoxSize * 0.5f),
1142   myIndent (0.2f),
1143   myFacettesNumber (20),
1144   myCircleRadius (myLength + myBoxSize + myBoxSize * 0.5f * 0.5f)
1145 {
1146   //
1147 }
1148
1149 //=======================================================================
1150 //class    : Axis
1151 //function : Compute
1152 //purpose  : 
1153 //=======================================================================
1154 void AIS_Manipulator::Axis::Compute (const Handle_PrsMgr_PresentationManager3d& thePrsMgr,
1155                                      const Handle(Prs3d_Presentation)& thePrs,
1156                                      const Handle(Prs3d_ShadingAspect)& theAspect)
1157 {
1158   Handle(Graphic3d_Group) aGroup;
1159
1160   if (myHasTranslation)
1161   {
1162     const Standard_ShortReal anArrowLength = 0.25f * myLength;
1163     const Standard_ShortReal aCylinderLength = myLength - anArrowLength;
1164
1165     myCylinder.Init (myAxisRadius, myAxisRadius, aCylinderLength, myFacettesNumber, 2, gp_Ax1 (gp::Origin(), myReferenceAxis.Direction()));
1166
1167     gp_Pnt anArrowBottom (0.0, 0.0, 0.0);
1168     anArrowBottom.Translate (myReferenceAxis.Direction().XYZ() * aCylinderLength);
1169
1170     myArrow.Init (myAxisRadius * 1.5f, 0.0f, anArrowLength, myFacettesNumber, 2, gp_Ax1 (anArrowBottom, myReferenceAxis.Direction()));
1171     myArrowBottom.Init (myAxisRadius, myAxisRadius * 1.5f, gp_Ax1 (anArrowBottom, myReferenceAxis.Direction()), myFacettesNumber);
1172     myArrowTipPos = anArrowBottom;
1173
1174     myTranslatorGroup = Prs3d_Root::NewGroup (thePrs);
1175     myTranslatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1176     myTranslatorGroup->AddPrimitiveArray (myCylinder.Array());
1177     myTranslatorGroup->AddPrimitiveArray (myArrow.Array());
1178     myTranslatorGroup->AddPrimitiveArray (myArrowBottom.Array());
1179
1180     if (myHighlightTranslator.IsNull())
1181     {
1182       myHighlightTranslator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1183     }
1184
1185     myHighlightTranslator->Clear();
1186     aGroup = Prs3d_Root::CurrentGroup (myHighlightTranslator);
1187     aGroup->AddPrimitiveArray (myCylinder.Array());
1188     aGroup->AddPrimitiveArray (myArrow.Array());
1189     aGroup->AddPrimitiveArray (myArrowBottom.Array());
1190   }
1191
1192   if (myHasScaling)
1193   {
1194     myCubePos = myReferenceAxis.Direction().XYZ() * (myLength + myIndent);
1195     myCube.Init (gp_Ax1 (myCubePos, myReferenceAxis.Direction()), myBoxSize);
1196
1197     myScalerGroup = Prs3d_Root::NewGroup (thePrs);
1198     myScalerGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1199     myScalerGroup->AddPrimitiveArray (myCube.Array());
1200
1201     if (myHighlightScaler.IsNull())
1202     {
1203       myHighlightScaler = new Prs3d_Presentation (thePrsMgr->StructureManager());
1204     }
1205
1206     myHighlightScaler->Clear();
1207     aGroup = Prs3d_Root::CurrentGroup (myHighlightScaler);
1208     aGroup->AddPrimitiveArray (myCube.Array());
1209   }
1210
1211   if (myHasRotation)
1212   {
1213     myCircleRadius = myInnerRadius + myIndent * 2 + myDiskThickness * 0.5f;
1214     myCircle.Init (myInnerRadius + myIndent * 2, myInnerRadius + myDiskThickness + myIndent * 2, gp_Ax1(gp::Origin(), myReferenceAxis.Direction()), myFacettesNumber * 2);
1215     myRotatorGroup = Prs3d_Root::NewGroup (thePrs);
1216     myRotatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1217     myRotatorGroup->AddPrimitiveArray (myCircle.Array());
1218
1219     if (myHighlightRotator.IsNull())
1220     {
1221       myHighlightRotator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1222     }
1223
1224     myHighlightRotator->Clear();
1225     aGroup = Prs3d_Root::CurrentGroup (myHighlightRotator);
1226     Prs3d_Root::CurrentGroup (myHighlightRotator)->AddPrimitiveArray (myCircle.Array());
1227   }
1228 }