0025180: Visualization - Homogeneous transformation API in TKV3d
[occt.git] / src / AIS / AIS_Manipulator.cxx
CommitLineData
625e1958 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
40IMPLEMENT_STANDARD_HANDLE (AIS_Manipulator, AIS_InteractiveObject)
41IMPLEMENT_STANDARD_RTTIEXT(AIS_Manipulator, AIS_InteractiveObject)
42
43IMPLEMENT_HSEQUENCE(AIS_ManipulatorObjectSequence)
44
45//=======================================================================
46//function : init
47//purpose :
48//=======================================================================
49void 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//=======================================================================
85Handle(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//=======================================================================
109Handle(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//=======================================================================
133AIS_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//=======================================================================
154AIS_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//=======================================================================
175void 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//=======================================================================
201void 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//=======================================================================
221void 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//=======================================================================
240void 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//=======================================================================
255void 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//=======================================================================
271void 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//=======================================================================
322void 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//=======================================================================
345Handle(AIS_ManipulatorObjectSequence) AIS_Manipulator::Objects() const
346{
347 return Handle(AIS_ManipulatorObjectSequence)::DownCast (GetOwner());
348}
349
350//=======================================================================
351//function : Object
352//purpose :
353//=======================================================================
354Handle(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//=======================================================================
372Handle(AIS_InteractiveObject) AIS_Manipulator::Object() const
373{
374 return Object (1);
375}
376
377//=======================================================================
378//function : ObjectTransformation
379//purpose :
380//=======================================================================
381Standard_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//=======================================================================
524void 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//=======================================================================
539void 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//=======================================================================
565void 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//=======================================================================
593gp_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//=======================================================================
609void 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//=======================================================================
628void 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
1f7f5a90 643 Handle(Geom_Transformation) aGeomTrsf = new Geom_Transformation (aTrsf);
644 // we explicitly call here setLocalTransformation() of the base class
645 // since AIS_Manipulator::setLocalTransformation() implementation throws exception
646 // as protection from external calls
647 AIS_InteractiveObject::setLocalTransformation (aGeomTrsf);
625e1958 648 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
649 {
650 myAxes[anIt].Transform (aGeomTrsf);
651 }
652
653 if (myIsZoomPersistentMode)
654 {
778cd667 655 if (TransformPersistence().IsNull()
656 || TransformPersistence()->Mode() != Graphic3d_TMF_ZoomPers
657 || !TransformPersistence()->AnchorPoint().IsEqual (myPosition.Location(), 0.0))
625e1958 658 {
778cd667 659 setTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, myPosition.Location()));
625e1958 660 }
661 }
662}
663
664//=======================================================================
665//function : SetSize
666//purpose :
667//=======================================================================
668void AIS_Manipulator::SetSize (const Standard_ShortReal theSideLength)
669{
670 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
671 {
672 myAxes[anIt].SetSize (theSideLength);
673 }
674
675 SetToUpdate();
676}
677
678//=======================================================================
679//function : SetGap
680//purpose :
681//=======================================================================
682void AIS_Manipulator::SetGap (const Standard_ShortReal theValue)
683{
684 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
685 {
686 myAxes[anIt].SetIndent (theValue);
687 }
688
689 SetToUpdate();
690}
691
692//=======================================================================
693//function : DeactivateCurrentMode
694//purpose :
695//=======================================================================
696void AIS_Manipulator::DeactivateCurrentMode()
697{
698 if (!myIsActivationOnDetection)
699 {
700 Handle(Graphic3d_Group) aGroup = getGroup (myCurrentIndex, myCurrentMode);
701 if (aGroup.IsNull())
702 {
703 return;
704 }
705
706 Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
707 anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
708 anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
709 anAspect->SetTransparency (myDrawer->ShadingAspect()->Transparency());
710 anAspect->SetColor (myAxes[myCurrentIndex].Color());
711
712 aGroup->SetGroupPrimitivesAspect (anAspect->Aspect());
713 }
714
715 myCurrentIndex = -1;
716 myCurrentMode = AIS_MM_None;
717
718 if (myHasStartedTransformation)
719 {
720 myHasStartedTransformation = Standard_False;
721 }
722}
723
724//=======================================================================
725//function : SetZoomPersistence
726//purpose :
727//=======================================================================
728void AIS_Manipulator::SetZoomPersistence (const Standard_Boolean theToEnable)
729{
730 if (myIsZoomPersistentMode != theToEnable)
731 {
732 SetToUpdate();
733 }
734
735 myIsZoomPersistentMode = theToEnable;
736
737 if (!theToEnable)
738 {
778cd667 739 setTransformPersistence (Handle(Graphic3d_TransformPers)());
625e1958 740 }
741
742 updateTransformation();
743}
744
745//=======================================================================
746//function : SetTransformPersistence
778cd667 747//purpose :
625e1958 748//=======================================================================
778cd667 749void AIS_Manipulator::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
625e1958 750{
751 Standard_ASSERT_RETURN (!myIsZoomPersistentMode,
752 "AIS_Manipulator::SetTransformPersistence: "
778cd667 753 "Custom settings are not allowed by this class in ZoomPersistence mode",);
625e1958 754
778cd667 755 setTransformPersistence (theTrsfPers);
625e1958 756}
757
758//=======================================================================
759//function : setTransformPersistence
760//purpose :
761//=======================================================================
778cd667 762void AIS_Manipulator::setTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
625e1958 763{
778cd667 764 AIS_InteractiveObject::SetTransformPersistence (theTrsfPers);
625e1958 765
766 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
767 {
778cd667 768 myAxes[anIt].SetTransformPersistence (theTrsfPers);
625e1958 769 }
770}
771
772//=======================================================================
1f7f5a90 773//function : setLocalTransformation
774//purpose :
625e1958 775//=======================================================================
1f7f5a90 776void AIS_Manipulator::setLocalTransformation (const Handle(Geom_Transformation)& /*theTrsf*/)
625e1958 777{
1f7f5a90 778 Standard_ASSERT_INVOKE ("AIS_Manipulator::setLocalTransformation: "
779 "Custom transformation is not supported by this class");
625e1958 780}
781
782//=======================================================================
783//function : Compute
784//purpose :
785//=======================================================================
786void AIS_Manipulator::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
787 const Handle(Prs3d_Presentation)& thePrs,
788 const Standard_Integer theMode)
789{
790 if (theMode != AIS_Shaded)
791 {
792 return;
793 }
794
795 thePrs->SetInfiniteState (Standard_True);
796 thePrs->SetMutable (Standard_True);
797 Handle(Graphic3d_Group) aGroup;
798 Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
799 anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
800 anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
801 anAspect->SetTransparency (myDrawer->ShadingAspect()->Transparency());
802
803 // Display center
804 myCenter.Init (myAxes[0].AxisRadius() * 2.0f, gp::Origin());
805 aGroup = Prs3d_Root::NewGroup (thePrs);
806 aGroup->SetPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
807 aGroup->AddPrimitiveArray (myCenter.Array());
808
809 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
810 {
811 // Display axes
812 aGroup = Prs3d_Root::NewGroup (thePrs);
b6472664 813
814 Handle(Prs3d_ShadingAspect) anAspectAx = new Prs3d_ShadingAspect (new Graphic3d_AspectFillArea3d(*anAspect->Aspect()));
815 anAspectAx->SetColor (myAxes[anIt].Color());
816 aGroup->SetGroupPrimitivesAspect (anAspectAx->Aspect());
817 myAxes[anIt].Compute (thePrsMgr, thePrs, anAspectAx);
778cd667 818 myAxes[anIt].SetTransformPersistence (TransformPersistence());
625e1958 819 }
820
821 updateTransformation();
822}
823
824//=======================================================================
825//function : HilightSelected
826//purpose :
827//=======================================================================
828void AIS_Manipulator::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
829 const SelectMgr_SequenceOfOwner& theSeq)
830{
831 if (theSeq.IsEmpty())
832 {
833 return;
834 }
835
836 if (myIsActivationOnDetection)
837 {
838 return;
839 }
840
841 if (!theSeq (1)->IsKind (STANDARD_TYPE (AIS_ManipulatorOwner)))
842 {
843 thePM->Color (this, GetContext()->HilightColor(), 0);
844 return;
845 }
846
847 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theSeq (1));
848 myHighlightAspect->Aspect()->SetInteriorColor (GetContext()->HilightColor());
849 Handle(Graphic3d_Group) aGroup = getGroup (anOwner->Index(), anOwner->Mode());
850 if (aGroup.IsNull())
851 {
852 return;
853 }
854
855 aGroup->SetGroupPrimitivesAspect (myHighlightAspect->Aspect());
856
857 myCurrentIndex = anOwner->Index();
858 myCurrentMode = anOwner->Mode();
859}
860
861//=======================================================================
862//function : ClearSelected
863//purpose :
864//=======================================================================
865void AIS_Manipulator::ClearSelected()
866{
867 DeactivateCurrentMode();
868}
869
870//=======================================================================
871//function : HilightOwnerWithColor
872//purpose :
873//=======================================================================
874void AIS_Manipulator::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM, const Quantity_NameOfColor theColor, const Handle(SelectMgr_EntityOwner)& theOwner)
875{
876 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theOwner);
877 Handle(Prs3d_Presentation) aPresentation = getHighlightPresentation (anOwner);
878 if (aPresentation.IsNull())
879 {
880 return;
881 }
882 aPresentation->Highlight (Aspect_TOHM_COLOR, theColor);
2831708b 883 for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPresentation->Groups());
884 aGroupIter.More(); aGroupIter.Next())
885 {
886 Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
887 if (!aGrp.IsNull()
888 && aGrp->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
889 {
890 aGrp->SetGroupPrimitivesAspect (myHighlightAspect->Aspect());
891 }
892 }
625e1958 893 aPresentation->SetZLayer (Graphic3d_ZLayerId_Topmost);
894 thePM->AddToImmediateList (aPresentation);
895
896 if (myIsActivationOnDetection)
897 {
898 if (HasActiveMode())
899 {
900 DeactivateCurrentMode();
901 }
902
903 myCurrentIndex = anOwner->Index();
904 myCurrentMode = anOwner->Mode();
905 }
906}
907
908//=======================================================================
909//function : ComputeSelection
910//purpose :
911//=======================================================================
912void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
913 const Standard_Integer theMode)
914{
915 //Check mode
916 AIS_ManipulatorMode aMode = (AIS_ManipulatorMode) theMode;
917 if (aMode == AIS_MM_None)
918 {
919 return;
920 }
921 Handle(SelectMgr_EntityOwner) anOwner;
922 if (aMode == AIS_MM_None)
923 {
924 anOwner = new SelectMgr_EntityOwner (this, 5);
925 }
926 Handle(Select3D_SensitiveTriangulation) aTri;
927 if (aMode == AIS_MM_Translation || aMode == AIS_MM_None)
928 {
929 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
930 {
931 const Axis& anAxis = myAxes[anIt];
932 if (aMode != AIS_MM_None)
933 {
934 anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_Translation, 9);
935 }
936 // define sensitivity by line
937 Handle(Select3D_SensitiveSegment) aLine = new Select3D_SensitiveSegment (anOwner, gp::Origin(), anAxis.TranslatorTipPosition());
938 aLine->SetSensitivityFactor (15);
939 theSelection->Add (aLine);
940 // enlarge sensitivity by triangulation
941 aTri = new Select3D_SensitiveTriangulation (anOwner, anAxis.TranslatorCylinder().Triangulation(), TopLoc_Location(), Standard_True);
942 theSelection->Add (aTri);
943 aTri = new Select3D_SensitiveTriangulation (anOwner, anAxis.TranslatorArrow().Triangulation(), TopLoc_Location(), Standard_True);
944 theSelection->Add (aTri);
945 aTri = new Select3D_SensitiveTriangulation (anOwner, anAxis.TranslatorArrowBottom().Triangulation(), TopLoc_Location(), Standard_True);
946 theSelection->Add (aTri);
947 }
948 }
949
950 if (aMode == AIS_MM_Rotation || aMode == AIS_MM_None)
951 {
952 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
953 {
954 const Axis& anAxis = myAxes[anIt];
955 if (aMode != AIS_MM_None)
956 {
957 anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Rotation, 9);
958 }
959 // define sensitivity by circle
960 Handle(Geom_Circle) aGeomCircle = new Geom_Circle (gp_Ax2 (gp::Origin(), anAxis.ReferenceAxis().Direction()), anAxis.RotatorDiskRadius());
961 Handle(Select3D_SensitiveCircle) aCircle = new Select3D_SensitiveCircle (anOwner, aGeomCircle, Standard_False, anAxis.FacettesNumber());
962 aCircle->SetSensitivityFactor (15);
963 theSelection->Add (aCircle);
964 // enlarge sensitivity by triangulation
965 aTri = new Select3D_SensitiveTriangulation (anOwner, myAxes[anIt].RotatorDisk().Triangulation(), TopLoc_Location(), Standard_True);
966 theSelection->Add (aTri);
967 }
968 }
969
970 if (aMode == AIS_MM_Scaling || aMode == AIS_MM_None)
971 {
972 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
973 {
974 if (aMode != AIS_MM_None)
975 {
976 anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Scaling, 9);
977 }
978 // define sensitivity by point
979 Handle(Select3D_SensitivePoint) aPnt = new Select3D_SensitivePoint (anOwner, myAxes[anIt].ScalerCubePosition());
980 aPnt->SetSensitivityFactor (15);
981 theSelection->Add (aPnt);
982 // enlarge sensitivity by triangulation
983 aTri = new Select3D_SensitiveTriangulation (anOwner, myAxes[anIt].ScalerCube().Triangulation(), TopLoc_Location(), Standard_True);
984 theSelection->Add (aTri);
985 }
986 }
987}
988
989//=======================================================================
990//class : Cylinder
991//function : Init
992//purpose :
993//=======================================================================
994void AIS_Manipulator::Cylinder::Init (const Standard_ShortReal theBotRad, const Standard_ShortReal theTopRad,
995 const Standard_ShortReal theHeight,
996 const Standard_Integer theSlicesNb, const Standard_Integer theStacksNb,
997 const gp_Ax1& thePosition)
998{
999 myPosition = thePosition;
1000 myBottomRad = theBotRad;
1001 myTopRad = theTopRad;
1002 myHeight = theHeight;
1003
1004 StdPrs_ToolCylinder aTool (myBottomRad, myTopRad, myHeight, theSlicesNb, theStacksNb);
1005 gp_Ax3 aSystem (myPosition.Location(), myPosition.Direction());
1006 gp_Trsf aTrsf;
1007 aTrsf.SetTransformation (aSystem, gp_Ax3());
1008
1009 aTool.FillArray (myArray, myTriangulation, aTrsf);
1010}
1011
1012//=======================================================================
1013//class : Disk
1014//function : Init
1015//purpose :
1016//=======================================================================
1017void AIS_Manipulator::Disk::Init (const Standard_ShortReal theInnerRadius,
1018 const Standard_ShortReal theOuterRadius,
1019 const gp_Ax1& thePosition,
1020 const Standard_Integer theSlicesNb,
1021 const Standard_Integer theStacksNb)
1022{
1023 myPosition = thePosition;
1024 myInnerRad = theInnerRadius;
1025 myOuterRad = theOuterRadius;
1026
1027 StdPrs_ToolDisk aTool (theInnerRadius, theOuterRadius, theSlicesNb, theStacksNb);
1028 gp_Ax3 aSystem (myPosition.Location(), myPosition.Direction());
1029 gp_Trsf aTrsf;
1030 aTrsf.SetTransformation (aSystem, gp_Ax3());
1031 aTool.FillArray (myArray, myTriangulation, aTrsf);
1032}
1033
1034//=======================================================================
1035//class : Sphere
1036//function : Init
1037//purpose :
1038//=======================================================================
1039void AIS_Manipulator::Sphere::Init (const Standard_ShortReal theRadius,
1040 const gp_Pnt& thePosition,
1041 const Standard_Integer theSlicesNb,
1042 const Standard_Integer theStacksNb)
1043{
1044 myPosition = thePosition;
1045 myRadius = theRadius;
1046
1047 StdPrs_ToolSphere aTool (theRadius, theSlicesNb, theStacksNb);
1048 gp_Trsf aTrsf;
1049 aTrsf.SetTranslation (gp_Vec(gp::Origin(), thePosition));
1050 aTool.FillArray (myArray, myTriangulation, aTrsf);
1051}
1052
1053//=======================================================================
1054//class : Cube
1055//function : Init
1056//purpose :
1057//=======================================================================
1058void AIS_Manipulator::Cube::Init (const gp_Ax1& thePosition, const Standard_ShortReal theSize)
1059{
1060 myArray = new Graphic3d_ArrayOfTriangles (12 * 3, 0, Standard_True);
1061
1062 Poly_Array1OfTriangle aPolyTriangles (1, 12);
1063 TColgp_Array1OfPnt aPoints (1, 36);
1064 NCollection_Array1<gp_Dir> aNormals (1, 12);
1065 myTriangulation = new Poly_Triangulation (aPoints, aPolyTriangles);
1066
1067 gp_Ax2 aPln (thePosition.Location(), thePosition.Direction());
1068 gp_Pnt aBottomLeft = thePosition.Location().XYZ() - aPln.XDirection().XYZ() * theSize * 0.5 - aPln.YDirection().XYZ() * theSize * 0.5;
1069 gp_Pnt aV2 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize;
1070 gp_Pnt aV3 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize + aPln.XDirection().XYZ() * theSize;
1071 gp_Pnt aV4 = aBottomLeft.XYZ() + aPln.XDirection().XYZ() * theSize;
1072 gp_Pnt aTopRight = thePosition.Location().XYZ() + thePosition.Direction().XYZ() * theSize
1073 + aPln.XDirection().XYZ() * theSize * 0.5 + aPln.YDirection().XYZ() * theSize * 0.5;
1074 gp_Pnt aV5 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize;
1075 gp_Pnt aV6 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize - aPln.XDirection().XYZ() * theSize;
1076 gp_Pnt aV7 = aTopRight.XYZ() - aPln.XDirection().XYZ() * theSize;
1077
1078 gp_Dir aRight ((gp_Vec(aTopRight, aV7) ^ gp_Vec(aTopRight, aV2)).XYZ());
1079 gp_Dir aFront ((gp_Vec(aV3, aV4) ^ gp_Vec(aV3, aV5)).XYZ());
1080
1081 // Bottom
1082 addTriangle (0, aBottomLeft, aV2, aV3, -thePosition.Direction());
1083 addTriangle (1, aBottomLeft, aV3, aV4, -thePosition.Direction());
1084
1085 // Front
1086 addTriangle (2, aV3, aV4, aV5, aFront);
1087 addTriangle (3, aV3, aV5, aTopRight, aFront);
1088
1089 // Back
1090 addTriangle (4, aBottomLeft, aV2, aV7, -aFront);
1091 addTriangle (5, aBottomLeft, aV7, aV6, -aFront);
1092
1093 // aTop
1094 addTriangle (6, aV7, aV6, aV5, thePosition.Direction());
1095 addTriangle (7, aTopRight, aV7, aV5, thePosition.Direction());
1096
1097 //Left
1098 addTriangle (8, aV6, aV5, aV4, -aRight);
1099 addTriangle (9, aBottomLeft, aV6, aV4, -aRight);
1100
1101 // Right
1102 addTriangle (10, aV3, aTopRight, aV7, aRight);
1103 addTriangle (11, aV3, aV7, aV2, aRight);
1104}
1105
1106//=======================================================================
1107//class : Cube
1108//function : addTriangle
1109//purpose :
1110//=======================================================================
1111void AIS_Manipulator::Cube::addTriangle (const Standard_Integer theIndex,
1112 const gp_Pnt& theP1, const gp_Pnt& theP2, const gp_Pnt& theP3,
1113 const gp_Dir& theNormal)
1114{
1115 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 1, theP1);
1116 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 2, theP2);
1117 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 3, theP3);
1118
1119 myTriangulation->ChangeTriangles().SetValue (theIndex + 1, Poly_Triangle (theIndex * 3 + 1, theIndex * 3 + 2, theIndex * 3 + 3));
1120 myArray->AddVertex (theP1, theNormal);
1121 myArray->AddVertex (theP2, theNormal);
1122 myArray->AddVertex (theP3, theNormal);
1123}
1124
1125//=======================================================================
1126//class : Axis
1127//function : Constructor
1128//purpose :
1129//=======================================================================
1130AIS_Manipulator::Axis::Axis (const gp_Ax1& theAxis,
1131 const Quantity_Color& theColor,
1132 const Standard_ShortReal theLength)
1133: myReferenceAxis (theAxis),
1134 myPosition (theAxis),
1135 myColor (theColor),
1136 myHasTranslation (Standard_True),
1137 myLength (theLength),
1138 myAxisRadius (0.5f),
1139 myHasScaling (Standard_True),
1140 myBoxSize (2.0f),
1141 myHasRotation (Standard_True),
1142 myInnerRadius (myLength + myBoxSize),
1143 myDiskThickness (myBoxSize * 0.5f),
1144 myIndent (0.2f),
1145 myFacettesNumber (20),
1146 myCircleRadius (myLength + myBoxSize + myBoxSize * 0.5f * 0.5f)
1147{
1148 //
1149}
1150
1151//=======================================================================
1152//class : Axis
1153//function : Compute
1154//purpose :
1155//=======================================================================
1156void AIS_Manipulator::Axis::Compute (const Handle_PrsMgr_PresentationManager3d& thePrsMgr,
1157 const Handle(Prs3d_Presentation)& thePrs,
1158 const Handle(Prs3d_ShadingAspect)& theAspect)
1159{
1160 Handle(Graphic3d_Group) aGroup;
1161
1162 if (myHasTranslation)
1163 {
1164 const Standard_ShortReal anArrowLength = 0.25f * myLength;
1165 const Standard_ShortReal aCylinderLength = myLength - anArrowLength;
1166
1167 myCylinder.Init (myAxisRadius, myAxisRadius, aCylinderLength, myFacettesNumber, 2, gp_Ax1 (gp::Origin(), myReferenceAxis.Direction()));
1168
1169 gp_Pnt anArrowBottom (0.0, 0.0, 0.0);
1170 anArrowBottom.Translate (myReferenceAxis.Direction().XYZ() * aCylinderLength);
1171
1172 myArrow.Init (myAxisRadius * 1.5f, 0.0f, anArrowLength, myFacettesNumber, 2, gp_Ax1 (anArrowBottom, myReferenceAxis.Direction()));
1173 myArrowBottom.Init (myAxisRadius, myAxisRadius * 1.5f, gp_Ax1 (anArrowBottom, myReferenceAxis.Direction()), myFacettesNumber);
1174 myArrowTipPos = anArrowBottom;
1175
1176 myTranslatorGroup = Prs3d_Root::NewGroup (thePrs);
1177 myTranslatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1178 myTranslatorGroup->AddPrimitiveArray (myCylinder.Array());
1179 myTranslatorGroup->AddPrimitiveArray (myArrow.Array());
1180 myTranslatorGroup->AddPrimitiveArray (myArrowBottom.Array());
1181
1182 if (myHighlightTranslator.IsNull())
1183 {
1184 myHighlightTranslator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1185 }
1186
1187 myHighlightTranslator->Clear();
1188 aGroup = Prs3d_Root::CurrentGroup (myHighlightTranslator);
1189 aGroup->AddPrimitiveArray (myCylinder.Array());
1190 aGroup->AddPrimitiveArray (myArrow.Array());
1191 aGroup->AddPrimitiveArray (myArrowBottom.Array());
1192 }
1193
1194 if (myHasScaling)
1195 {
1196 myCubePos = myReferenceAxis.Direction().XYZ() * (myLength + myIndent);
1197 myCube.Init (gp_Ax1 (myCubePos, myReferenceAxis.Direction()), myBoxSize);
1198
1199 myScalerGroup = Prs3d_Root::NewGroup (thePrs);
1200 myScalerGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1201 myScalerGroup->AddPrimitiveArray (myCube.Array());
1202
1203 if (myHighlightScaler.IsNull())
1204 {
1205 myHighlightScaler = new Prs3d_Presentation (thePrsMgr->StructureManager());
1206 }
1207
1208 myHighlightScaler->Clear();
1209 aGroup = Prs3d_Root::CurrentGroup (myHighlightScaler);
1210 aGroup->AddPrimitiveArray (myCube.Array());
1211 }
1212
1213 if (myHasRotation)
1214 {
1215 myCircleRadius = myInnerRadius + myIndent * 2 + myDiskThickness * 0.5f;
1216 myCircle.Init (myInnerRadius + myIndent * 2, myInnerRadius + myDiskThickness + myIndent * 2, gp_Ax1(gp::Origin(), myReferenceAxis.Direction()), myFacettesNumber * 2);
1217 myRotatorGroup = Prs3d_Root::NewGroup (thePrs);
1218 myRotatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1219 myRotatorGroup->AddPrimitiveArray (myCircle.Array());
1220
1221 if (myHighlightRotator.IsNull())
1222 {
1223 myHighlightRotator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1224 }
1225
1226 myHighlightRotator->Clear();
1227 aGroup = Prs3d_Root::CurrentGroup (myHighlightRotator);
1228 Prs3d_Root::CurrentGroup (myHighlightRotator)->AddPrimitiveArray (myCircle.Array());
1229 }
1230}