1 // Created on: 2015-12-23
2 // Created by: Anastasia BORISOVA
3 // Copyright (c) 2015 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <AIS_Manipulator.hxx>
18 #include <AIS_DisplayMode.hxx>
19 #include <AIS_InteractiveContext.hxx>
20 #include <AIS_ManipulatorOwner.hxx>
21 #include <Extrema_ExtElC.hxx>
22 #include <gce_MakeDir.hxx>
23 #include <IntAna_IntConicQuad.hxx>
24 #include <Prs3d_Arrow.hxx>
25 #include <Prs3d_ShadingAspect.hxx>
26 #include <Prs3d_ToolDisk.hxx>
27 #include <Prs3d_ToolSector.hxx>
28 #include <Prs3d_ToolSphere.hxx>
29 #include <Select3D_SensitiveCircle.hxx>
30 #include <Select3D_SensitivePoint.hxx>
31 #include <Select3D_SensitiveSegment.hxx>
32 #include <Select3D_SensitiveTriangulation.hxx>
33 #include <Select3D_SensitivePrimitiveArray.hxx>
34 #include <SelectMgr_SequenceOfOwner.hxx>
35 #include <TColgp_Array1OfPnt.hxx>
36 #include <V3d_View.hxx>
38 IMPLEMENT_STANDARD_HANDLE (AIS_Manipulator, AIS_InteractiveObject)
39 IMPLEMENT_STANDARD_RTTIEXT(AIS_Manipulator, AIS_InteractiveObject)
41 IMPLEMENT_HSEQUENCE(AIS_ManipulatorObjectSequence)
45 //! Return Ax1 for specified direction of Ax2.
46 static gp_Ax1 getAx1FromAx2Dir (const gp_Ax2& theAx2,
51 case 0: return gp_Ax1 (theAx2.Location(), theAx2.XDirection());
52 case 1: return gp_Ax1 (theAx2.Location(), theAx2.YDirection());
53 case 2: return theAx2.Axis();
55 throw Standard_ProgramError ("AIS_Manipulator - Invalid axis index");
58 //! Auxiliary tool for filtering picking ray.
59 class ManipSensRotation
63 ManipSensRotation (const gp_Dir& thePlaneNormal) : myPlaneNormal (thePlaneNormal), myAngleTol (10.0 * M_PI / 180.0) {}
65 //! Checks if picking ray can be used for detection.
66 Standard_Boolean isValidRay (const SelectBasics_SelectingVolumeManager& theMgr) const
68 if (theMgr.GetActiveSelectionType() != SelectMgr_SelectionType_Point)
70 return Standard_False;
73 const gp_Dir aRay = theMgr.GetViewRayDirection();
74 return !aRay.IsNormal (myPlaneNormal, myAngleTol);
78 Standard_Real myAngleTol;
81 //! Sensitive circle with filtering picking ray.
82 class ManipSensCircle : public Select3D_SensitiveCircle, public ManipSensRotation
86 ManipSensCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
87 const gp_Circ& theCircle)
88 : Select3D_SensitiveCircle (theOwnerId, theCircle, Standard_False),
89 ManipSensRotation (theCircle.Position().Direction()) {}
91 //! Checks whether the circle overlaps current selecting volume
92 virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
93 SelectBasics_PickResult& thePickResult) Standard_OVERRIDE
95 return isValidRay (theMgr)
96 && Select3D_SensitiveCircle::Matches (theMgr, thePickResult);
100 //! Sensitive triangulation with filtering picking ray.
101 class ManipSensTriangulation : public Select3D_SensitiveTriangulation, public ManipSensRotation
104 ManipSensTriangulation (const Handle(SelectMgr_EntityOwner)& theOwnerId,
105 const Handle(Poly_Triangulation)& theTrg,
106 const gp_Dir& thePlaneNormal)
107 : Select3D_SensitiveTriangulation (theOwnerId, theTrg, TopLoc_Location(), Standard_True),
108 ManipSensRotation (thePlaneNormal) {}
110 //! Checks whether the circle overlaps current selecting volume
111 virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
112 SelectBasics_PickResult& thePickResult) Standard_OVERRIDE
114 return isValidRay (theMgr)
115 && Select3D_SensitiveTriangulation::Matches (theMgr, thePickResult);
120 //=======================================================================
123 //=======================================================================
124 void AIS_Manipulator::init()
126 // Create axis in the default coordinate system. The custom position is applied in local transformation.
127 myAxes[0] = Axis (gp::OX(), Quantity_NOC_RED);
128 myAxes[1] = Axis (gp::OY(), Quantity_NOC_GREEN);
129 myAxes[2] = Axis (gp::OZ(), Quantity_NOC_BLUE1);
131 Graphic3d_MaterialAspect aShadingMaterial;
132 aShadingMaterial.SetSpecularColor(Quantity_NOC_BLACK);
133 aShadingMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
135 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
136 myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
137 myDrawer->ShadingAspect()->SetColor (Quantity_NOC_WHITE);
138 myDrawer->ShadingAspect()->SetMaterial (aShadingMaterial);
140 Graphic3d_MaterialAspect aHilightMaterial;
141 aHilightMaterial.SetColor (Quantity_NOC_AZURE);
142 aHilightMaterial.SetAmbientColor (Quantity_NOC_BLACK);
143 aHilightMaterial.SetDiffuseColor (Quantity_NOC_BLACK);
144 aHilightMaterial.SetSpecularColor(Quantity_NOC_BLACK);
145 aHilightMaterial.SetEmissiveColor(Quantity_NOC_BLACK);
146 aHilightMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
148 myHighlightAspect = new Prs3d_ShadingAspect();
149 myHighlightAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
150 myHighlightAspect->SetMaterial (aHilightMaterial);
152 Graphic3d_MaterialAspect aDraggerMaterial;
153 aDraggerMaterial.SetAmbientColor (Quantity_NOC_BLACK);
154 aDraggerMaterial.SetDiffuseColor (Quantity_NOC_BLACK);
155 aDraggerMaterial.SetSpecularColor(Quantity_NOC_BLACK);
156 aDraggerMaterial.SetMaterialType(Graphic3d_MATERIAL_ASPECT);
158 myDraggerHighlight = new Prs3d_ShadingAspect();
159 myDraggerHighlight->Aspect()->SetInteriorStyle(Aspect_IS_SOLID);
160 myDraggerHighlight->SetMaterial(aDraggerMaterial);
162 myDraggerHighlight->SetTransparency(0.5);
165 SetZLayer (Graphic3d_ZLayerId_Topmost);
168 //=======================================================================
169 //function : getHighlightPresentation
171 //=======================================================================
172 Handle(Prs3d_Presentation) AIS_Manipulator::getHighlightPresentation (const Handle(SelectMgr_EntityOwner)& theOwner) const
174 Handle(Prs3d_Presentation) aDummyPrs;
175 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theOwner);
176 if (anOwner.IsNull())
181 switch (anOwner->Mode())
183 case AIS_MM_Translation : return myAxes[anOwner->Index()].TranslatorHighlightPrs();
184 case AIS_MM_Rotation : return myAxes[anOwner->Index()].RotatorHighlightPrs();
185 case AIS_MM_Scaling : return myAxes[anOwner->Index()].ScalerHighlightPrs();
186 case AIS_MM_TranslationPlane: return myAxes[anOwner->Index()].DraggerHighlightPrs();
187 case AIS_MM_None : break;
193 //=======================================================================
194 //function : getGroup
196 //=======================================================================
197 Handle(Graphic3d_Group) AIS_Manipulator::getGroup (const Standard_Integer theIndex, const AIS_ManipulatorMode theMode) const
199 Handle(Graphic3d_Group) aDummyGroup;
201 if (theIndex < 0 || theIndex > 2)
208 case AIS_MM_Translation : return myAxes[theIndex].TranslatorGroup();
209 case AIS_MM_Rotation : return myAxes[theIndex].RotatorGroup();
210 case AIS_MM_Scaling : return myAxes[theIndex].ScalerGroup();
211 case AIS_MM_TranslationPlane: return myAxes[theIndex].DraggerGroup();
212 case AIS_MM_None : break;
218 //=======================================================================
219 //function : Constructor
221 //=======================================================================
222 AIS_Manipulator::AIS_Manipulator()
223 : myPosition (gp::XOY()),
225 myCurrentMode (AIS_MM_None),
226 myIsActivationOnDetection (Standard_False),
227 myIsZoomPersistentMode (Standard_True),
228 myHasStartedTransformation (Standard_False),
229 myStartPosition (gp::XOY()),
230 myStartPick (0.0, 0.0, 0.0),
234 SetMutable (Standard_True);
235 SetDisplayMode (AIS_Shaded);
239 //=======================================================================
240 //function : Constructor
242 //=======================================================================
243 AIS_Manipulator::AIS_Manipulator (const gp_Ax2& thePosition)
244 : myPosition (thePosition),
246 myCurrentMode (AIS_MM_None),
247 myIsActivationOnDetection (Standard_False),
248 myIsZoomPersistentMode (Standard_True),
249 myHasStartedTransformation (Standard_False),
250 myStartPosition (gp::XOY()),
251 myStartPick (0.0, 0.0, 0.0),
255 SetMutable (Standard_True);
256 SetDisplayMode (AIS_Shaded);
260 //=======================================================================
263 //=======================================================================
264 void AIS_Manipulator::SetPart (const Standard_Integer theAxisIndex, const AIS_ManipulatorMode theMode, const Standard_Boolean theIsEnabled)
266 Standard_ProgramError_Raise_if (theAxisIndex < 0 || theAxisIndex > 2, "AIS_Manipulator::SetMode(): axis index should be between 0 and 2");
269 case AIS_MM_Translation:
270 myAxes[theAxisIndex].SetTranslation (theIsEnabled);
273 case AIS_MM_Rotation:
274 myAxes[theAxisIndex].SetRotation (theIsEnabled);
278 myAxes[theAxisIndex].SetScaling (theIsEnabled);
281 case AIS_MM_TranslationPlane:
282 myAxes[theAxisIndex].SetDragging(theIsEnabled);
290 //=======================================================================
293 //=======================================================================
294 void AIS_Manipulator::SetPart (const AIS_ManipulatorMode theMode, const Standard_Boolean theIsEnabled)
296 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
298 SetPart (anIt, theMode, theIsEnabled);
302 //=======================================================================
303 //function : EnableMode
305 //=======================================================================
306 void AIS_Manipulator::EnableMode (const AIS_ManipulatorMode theMode)
313 const Handle(AIS_InteractiveContext)& aContext = GetContext();
314 if (aContext.IsNull())
319 aContext->Activate (this, theMode);
322 //=======================================================================
323 //function : attachToBox
325 //=======================================================================
326 void AIS_Manipulator::attachToBox (const Bnd_Box& theBox)
333 Standard_Real anXmin = 0.0, anYmin = 0.0, aZmin = 0.0, anXmax = 0.0, anYmax = 0.0, aZmax = 0.0;
334 theBox.Get (anXmin, anYmin, aZmin, anXmax, anYmax, aZmax);
336 gp_Ax2 aPosition = gp::XOY();
337 aPosition.SetLocation (gp_Pnt ((anXmin + anXmax) * 0.5, (anYmin + anYmax) * 0.5, (aZmin + aZmax) * 0.5));
338 SetPosition (aPosition);
341 //=======================================================================
342 //function : adjustSize
344 //=======================================================================
345 void AIS_Manipulator::adjustSize (const Bnd_Box& theBox)
347 Standard_Real aXmin = 0., aYmin = 0., aZmin = 0., aXmax = 0., aYmax = 0., aZmax = 0.0;
348 theBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
349 Standard_Real aXSize = aXmax - aXmin;
350 Standard_Real aYSize = aYmax - aYmin;
351 Standard_Real aZSize = aZmax - aZmin;
353 SetSize ((Standard_ShortReal) (Max (aXSize, Max (aYSize, aZSize)) * 0.5));
356 //=======================================================================
359 //=======================================================================
360 void AIS_Manipulator::Attach (const Handle(AIS_InteractiveObject)& theObject, const OptionsForAttach& theOptions)
362 if (theObject->IsKind (STANDARD_TYPE(AIS_Manipulator)))
367 Handle(AIS_ManipulatorObjectSequence) aSeq = new AIS_ManipulatorObjectSequence();
368 aSeq->Append (theObject);
369 Attach (aSeq, theOptions);
372 //=======================================================================
375 //=======================================================================
376 void AIS_Manipulator::Attach (const Handle(AIS_ManipulatorObjectSequence)& theObjects, const OptionsForAttach& theOptions)
378 if (theObjects->Size() < 1)
383 SetOwner (theObjects);
385 const Handle(AIS_InteractiveObject)& aCurObject = theObjects->Value (theObjects->Lower());
386 aCurObject->BoundingBox (aBox);
388 if (theOptions.AdjustPosition)
393 if (theOptions.AdjustSize)
398 const Handle(AIS_InteractiveContext)& aContext = Object()->GetContext();
399 if (!aContext.IsNull())
401 if (!aContext->IsDisplayed (this))
403 aContext->Display (this, Standard_False);
407 aContext->Update (this, Standard_False);
408 aContext->RecomputeSelectionOnly (this);
411 aContext->Load (this);
414 if (theOptions.EnableModes)
416 EnableMode (AIS_MM_Rotation);
417 EnableMode (AIS_MM_Translation);
418 EnableMode (AIS_MM_Scaling);
419 EnableMode (AIS_MM_TranslationPlane);
423 //=======================================================================
426 //=======================================================================
427 void AIS_Manipulator::Detach()
429 DeactivateCurrentMode();
436 Handle(AIS_InteractiveObject) anObject = Object();
437 const Handle(AIS_InteractiveContext)& aContext = anObject->GetContext();
438 if (!aContext.IsNull())
440 aContext->Remove (this, Standard_False);
446 //=======================================================================
449 //=======================================================================
450 Handle(AIS_ManipulatorObjectSequence) AIS_Manipulator::Objects() const
452 return Handle(AIS_ManipulatorObjectSequence)::DownCast (GetOwner());
455 //=======================================================================
458 //=======================================================================
459 Handle(AIS_InteractiveObject) AIS_Manipulator::Object (const Standard_Integer theIndex) const
461 Handle(AIS_ManipulatorObjectSequence) anOwner = Handle(AIS_ManipulatorObjectSequence)::DownCast (GetOwner());
463 Standard_ProgramError_Raise_if (theIndex < anOwner->Lower() || theIndex > anOwner->Upper(), "AIS_Manipulator::Object(): wrong index value");
465 if (anOwner.IsNull() || anOwner->IsEmpty())
470 return anOwner->Value (theIndex);
473 //=======================================================================
476 //=======================================================================
477 Handle(AIS_InteractiveObject) AIS_Manipulator::Object() const
482 //=======================================================================
483 //function : ObjectTransformation
485 //=======================================================================
486 Standard_Boolean AIS_Manipulator::ObjectTransformation (const Standard_Integer theMaxX, const Standard_Integer theMaxY,
487 const Handle(V3d_View)& theView, gp_Trsf& theTrsf)
489 // Initialize start reference data
490 if (!myHasStartedTransformation)
492 myStartTrsfs.Clear();
493 Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
494 for (AIS_ManipulatorObjectSequence::Iterator anObjIter (*anObjects); anObjIter.More(); anObjIter.Next())
496 myStartTrsfs.Append (anObjIter.Value()->LocalTransformation());
498 myStartPosition = myPosition;
501 // Get 3d point with projection vector
502 Graphic3d_Vec3d anInputPoint, aProj;
503 theView->ConvertWithProj (theMaxX, theMaxY, anInputPoint.x(), anInputPoint.y(), anInputPoint.z(), aProj.x(), aProj.y(), aProj.z());
504 const gp_Lin anInputLine (gp_Pnt (anInputPoint.x(), anInputPoint.y(), anInputPoint.z()), gp_Dir (aProj.x(), aProj.y(), aProj.z()));
505 switch (myCurrentMode)
507 case AIS_MM_Translation:
510 const gp_Lin aLine (myStartPosition.Location(), myAxes[myCurrentIndex].Position().Direction());
511 Extrema_ExtElC anExtrema (anInputLine, aLine, Precision::Angular());
512 if (!anExtrema.IsDone()
513 || anExtrema.IsParallel()
514 || anExtrema.NbExt() != 1)
516 // translation cannot be done co-directed with camera
517 return Standard_False;
520 Extrema_POnCurv anExPnts[2];
521 anExtrema.Points (1, anExPnts[0], anExPnts[1]);
522 const gp_Pnt aNewPosition = anExPnts[1].Value();
523 if (!myHasStartedTransformation)
525 myStartPick = aNewPosition;
526 myHasStartedTransformation = Standard_True;
527 return Standard_True;
529 else if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
531 return Standard_False;
535 if (myCurrentMode == AIS_MM_Translation)
537 aNewTrsf.SetTranslation (gp_Vec(myStartPick, aNewPosition));
540 else if (myCurrentMode == AIS_MM_Scaling)
542 if (aNewPosition.Distance (myStartPosition.Location()) < Precision::Confusion())
544 return Standard_False;
547 Standard_Real aCoeff = myStartPosition.Location().Distance (aNewPosition)
548 / myStartPosition.Location().Distance (myStartPick);
549 aNewTrsf.SetScale (myPosition.Location(), aCoeff);
552 return Standard_True;
554 case AIS_MM_Rotation:
556 const gp_Pnt aPosLoc = myStartPosition.Location();
557 const gp_Ax1 aCurrAxis = getAx1FromAx2Dir (myStartPosition, myCurrentIndex);
558 IntAna_IntConicQuad aIntersector (anInputLine, gp_Pln (aPosLoc, aCurrAxis.Direction()), Precision::Angular(), Precision::Intersection());
559 if (!aIntersector.IsDone()
560 || aIntersector.IsParallel()
561 || aIntersector.NbPoints() < 1)
563 return Standard_False;
566 const gp_Pnt aNewPosition = aIntersector.Point (1);
567 if (!myHasStartedTransformation)
569 myStartPick = aNewPosition;
570 myHasStartedTransformation = Standard_True;
571 gp_Dir aStartAxis = gce_MakeDir (aPosLoc, myStartPick);
572 myPrevState = aStartAxis.AngleWithRef (gce_MakeDir(aPosLoc, aNewPosition), aCurrAxis.Direction());
573 return Standard_True;
576 if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
578 return Standard_False;
581 gp_Dir aStartAxis = aPosLoc.IsEqual (myStartPick, Precision::Confusion())
582 ? getAx1FromAx2Dir (myStartPosition, (myCurrentIndex + 1) % 3).Direction()
583 : gce_MakeDir (aPosLoc, myStartPick);
585 gp_Dir aCurrentAxis = gce_MakeDir (aPosLoc, aNewPosition);
586 Standard_Real anAngle = aStartAxis.AngleWithRef (aCurrentAxis, aCurrAxis.Direction());
588 // Change value of an angle if it should have different sign.
589 if (anAngle * myPrevState < 0 && Abs (anAngle) < M_PI_2)
591 Standard_Real aSign = myPrevState > 0 ? -1.0 : 1.0;
592 anAngle = aSign * (M_PI * 2 - anAngle);
595 if (Abs (anAngle) < Precision::Confusion())
597 return Standard_False;
601 aNewTrsf.SetRotation (aCurrAxis, anAngle);
603 myPrevState = anAngle;
604 return Standard_True;
606 case AIS_MM_TranslationPlane:
608 const gp_Pnt aPosLoc = myStartPosition.Location();
609 const gp_Ax1 aCurrAxis = getAx1FromAx2Dir(myStartPosition, myCurrentIndex);
610 IntAna_IntConicQuad aIntersector(anInputLine, gp_Pln(aPosLoc, aCurrAxis.Direction()), Precision::Angular(), Precision::Intersection());
611 if (!aIntersector.IsDone() || aIntersector.NbPoints() < 1)
613 return Standard_False;
616 const gp_Pnt aNewPosition = aIntersector.Point(1);
617 if (!myHasStartedTransformation)
619 myStartPick = aNewPosition;
620 myHasStartedTransformation = Standard_True;
621 return Standard_True;
624 if (aNewPosition.Distance(myStartPick) < Precision::Confusion())
626 return Standard_False;
630 aNewTrsf.SetTranslation(gp_Vec(myStartPick, aNewPosition));
632 return Standard_True;
636 return Standard_False;
639 return Standard_False;
642 //=======================================================================
643 //function : ProcessDragging
645 //=======================================================================
646 Standard_Boolean AIS_Manipulator::ProcessDragging (const Handle(AIS_InteractiveContext)&,
647 const Handle(V3d_View)& theView,
648 const Handle(SelectMgr_EntityOwner)&,
649 const Graphic3d_Vec2i& theDragFrom,
650 const Graphic3d_Vec2i& theDragTo,
651 const AIS_DragAction theAction)
655 case AIS_DragAction_Start:
659 StartTransform (theDragFrom.x(), theDragFrom.y(), theView);
660 return Standard_True;
664 case AIS_DragAction_Confirmed:
666 return Standard_True;
668 case AIS_DragAction_Update:
670 Transform (theDragTo.x(), theDragTo.y(), theView);
671 return Standard_True;
673 case AIS_DragAction_Abort:
675 StopTransform (false);
676 return Standard_True;
678 case AIS_DragAction_Stop:
681 return Standard_False;
684 //=======================================================================
685 //function : StartTransform
687 //=======================================================================
688 void AIS_Manipulator::StartTransform (const Standard_Integer theX, const Standard_Integer theY, const Handle(V3d_View)& theView)
690 if (myHasStartedTransformation)
696 ObjectTransformation (theX, theY, theView, aTrsf);
699 //=======================================================================
700 //function : StopTransform
702 //=======================================================================
703 void AIS_Manipulator::StopTransform (const Standard_Boolean theToApply)
705 if (!IsAttached() || !myHasStartedTransformation)
710 myHasStartedTransformation = Standard_False;
716 Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
717 AIS_ManipulatorObjectSequence::Iterator anObjIter (*anObjects);
718 NCollection_Sequence<gp_Trsf>::Iterator aTrsfIter (myStartTrsfs);
719 for (; anObjIter.More(); anObjIter.Next(), aTrsfIter.Next())
721 anObjIter.ChangeValue()->SetLocalTransformation (aTrsfIter.Value());
723 SetPosition (myStartPosition);
726 //=======================================================================
727 //function : Transform
729 //=======================================================================
730 void AIS_Manipulator::Transform (const gp_Trsf& theTrsf)
732 if (!IsAttached() || !myHasStartedTransformation)
738 Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
739 AIS_ManipulatorObjectSequence::Iterator anObjIter (*anObjects);
740 NCollection_Sequence<gp_Trsf>::Iterator aTrsfIter (myStartTrsfs);
741 for (; anObjIter.More(); anObjIter.Next(), aTrsfIter.Next())
743 const Handle(AIS_InteractiveObject)& anObj = anObjIter.ChangeValue();
744 const gp_Trsf& anOldTrsf = aTrsfIter.Value();
745 const Handle(TopLoc_Datum3D)& aParentTrsf = anObj->CombinedParentTransformation();
746 if (!aParentTrsf.IsNull()
747 && aParentTrsf->Form() != gp_Identity)
749 // recompute local transformation relative to parent transformation
750 const gp_Trsf aNewLocalTrsf = aParentTrsf->Trsf().Inverted() * theTrsf * aParentTrsf->Trsf() * anOldTrsf;
751 anObj->SetLocalTransformation (aNewLocalTrsf);
755 anObj->SetLocalTransformation (theTrsf * anOldTrsf);
760 if ((myCurrentMode == AIS_MM_Translation && myBehaviorOnTransform.FollowTranslation)
761 || (myCurrentMode == AIS_MM_Rotation && myBehaviorOnTransform.FollowRotation)
762 || (myCurrentMode == AIS_MM_TranslationPlane && myBehaviorOnTransform.FollowDragging))
764 gp_Pnt aPos = myStartPosition.Location().Transformed (theTrsf);
765 gp_Dir aVDir = myStartPosition.Direction().Transformed (theTrsf);
766 gp_Dir aXDir = myStartPosition.XDirection().Transformed (theTrsf);
767 SetPosition (gp_Ax2 (aPos, aVDir, aXDir));
771 //=======================================================================
772 //function : Transform
774 //=======================================================================
775 gp_Trsf AIS_Manipulator::Transform (const Standard_Integer thePX, const Standard_Integer thePY,
776 const Handle(V3d_View)& theView)
779 if (ObjectTransformation (thePX, thePY, theView, aTrsf))
787 //=======================================================================
788 //function : SetPosition
790 //=======================================================================
791 void AIS_Manipulator::SetPosition (const gp_Ax2& thePosition)
793 if (!myPosition.Location().IsEqual (thePosition.Location(), Precision::Confusion())
794 || !myPosition.Direction().IsEqual (thePosition.Direction(), Precision::Angular())
795 || !myPosition.XDirection().IsEqual (thePosition.XDirection(), Precision::Angular()))
797 myPosition = thePosition;
798 myAxes[0].SetPosition (getAx1FromAx2Dir (thePosition, 0));
799 myAxes[1].SetPosition (getAx1FromAx2Dir (thePosition, 1));
800 myAxes[2].SetPosition (getAx1FromAx2Dir (thePosition, 2));
801 updateTransformation();
805 //=======================================================================
806 //function : updateTransformation
807 //purpose : set local transformation to avoid graphics recomputation
808 //=======================================================================
809 void AIS_Manipulator::updateTransformation()
813 if (!myIsZoomPersistentMode)
815 aTrsf.SetTransformation (myPosition, gp::XOY());
819 const gp_Dir& aVDir = myPosition.Direction();
820 const gp_Dir& aXDir = myPosition.XDirection();
821 aTrsf.SetTransformation (gp_Ax2 (gp::Origin(), aVDir, aXDir), gp::XOY());
824 Handle(TopLoc_Datum3D) aGeomTrsf = new TopLoc_Datum3D (aTrsf);
825 // we explicitly call here setLocalTransformation() of the base class
826 // since AIS_Manipulator::setLocalTransformation() implementation throws exception
827 // as protection from external calls
828 AIS_InteractiveObject::setLocalTransformation (aGeomTrsf);
829 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
831 myAxes[anIt].Transform (aGeomTrsf);
834 if (myIsZoomPersistentMode)
836 if (TransformPersistence().IsNull()
837 || TransformPersistence()->Mode() != Graphic3d_TMF_ZoomPers
838 || !TransformPersistence()->AnchorPoint().IsEqual (myPosition.Location(), 0.0))
840 setTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, myPosition.Location()));
845 //=======================================================================
848 //=======================================================================
849 void AIS_Manipulator::SetSize (const Standard_ShortReal theSideLength)
851 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
853 myAxes[anIt].SetSize (theSideLength);
859 //=======================================================================
862 //=======================================================================
863 void AIS_Manipulator::SetGap (const Standard_ShortReal theValue)
865 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
867 myAxes[anIt].SetIndent (theValue);
873 //=======================================================================
874 //function : DeactivateCurrentMode
876 //=======================================================================
877 void AIS_Manipulator::DeactivateCurrentMode()
879 if (!myIsActivationOnDetection)
881 Handle(Graphic3d_Group) aGroup = getGroup (myCurrentIndex, myCurrentMode);
887 Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
888 anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
889 anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
890 if (myCurrentMode == AIS_MM_TranslationPlane)
891 anAspect->SetTransparency(1.0);
894 anAspect->SetTransparency(myDrawer->ShadingAspect()->Transparency());
895 anAspect->SetColor(myAxes[myCurrentIndex].Color());
898 aGroup->SetGroupPrimitivesAspect (anAspect->Aspect());
902 myCurrentMode = AIS_MM_None;
904 if (myHasStartedTransformation)
906 myHasStartedTransformation = Standard_False;
910 //=======================================================================
911 //function : SetZoomPersistence
913 //=======================================================================
914 void AIS_Manipulator::SetZoomPersistence (const Standard_Boolean theToEnable)
916 if (myIsZoomPersistentMode != theToEnable)
921 myIsZoomPersistentMode = theToEnable;
925 setTransformPersistence (Handle(Graphic3d_TransformPers)());
928 updateTransformation();
931 //=======================================================================
932 //function : SetTransformPersistence
934 //=======================================================================
935 void AIS_Manipulator::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
937 Standard_ASSERT_RETURN (!myIsZoomPersistentMode,
938 "AIS_Manipulator::SetTransformPersistence: "
939 "Custom settings are not allowed by this class in ZoomPersistence mode",);
941 setTransformPersistence (theTrsfPers);
944 //=======================================================================
945 //function : setTransformPersistence
947 //=======================================================================
948 void AIS_Manipulator::setTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
950 AIS_InteractiveObject::SetTransformPersistence (theTrsfPers);
952 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
954 myAxes[anIt].SetTransformPersistence (theTrsfPers);
958 //=======================================================================
959 //function : setLocalTransformation
961 //=======================================================================
962 void AIS_Manipulator::setLocalTransformation (const Handle(TopLoc_Datum3D)& /*theTrsf*/)
964 Standard_ASSERT_INVOKE ("AIS_Manipulator::setLocalTransformation: "
965 "Custom transformation is not supported by this class");
968 //=======================================================================
971 //=======================================================================
972 void AIS_Manipulator::Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
973 const Handle(Prs3d_Presentation)& thePrs,
974 const Standard_Integer theMode)
976 if (theMode != AIS_Shaded)
981 thePrs->SetInfiniteState (Standard_True);
982 thePrs->SetMutable (Standard_True);
983 Handle(Graphic3d_Group) aGroup;
984 Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
985 anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
986 anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
987 anAspect->SetTransparency (myDrawer->ShadingAspect()->Transparency());
990 myCenter.Init (myAxes[0].AxisRadius() * 2.0f, gp::Origin());
991 aGroup = thePrs->NewGroup ();
992 aGroup->SetPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
993 aGroup->AddPrimitiveArray (myCenter.Array());
995 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
998 aGroup = thePrs->NewGroup ();
1000 Handle(Prs3d_ShadingAspect) anAspectAx = new Prs3d_ShadingAspect (new Graphic3d_AspectFillArea3d(*anAspect->Aspect()));
1001 anAspectAx->SetColor (myAxes[anIt].Color());
1002 aGroup->SetGroupPrimitivesAspect (anAspectAx->Aspect());
1003 myAxes[anIt].Compute (thePrsMgr, thePrs, anAspectAx);
1004 myAxes[anIt].SetTransformPersistence (TransformPersistence());
1007 updateTransformation();
1010 //=======================================================================
1011 //function : HilightSelected
1013 //=======================================================================
1014 void AIS_Manipulator::HilightSelected (const Handle(PrsMgr_PresentationManager)& thePM,
1015 const SelectMgr_SequenceOfOwner& theSeq)
1017 if (theSeq.IsEmpty())
1022 if (myIsActivationOnDetection)
1027 if (!theSeq (1)->IsKind (STANDARD_TYPE (AIS_ManipulatorOwner)))
1029 thePM->Color (this, GetContext()->HighlightStyle(), 0);
1033 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theSeq (1));
1034 myHighlightAspect->Aspect()->SetInteriorColor (GetContext()->HighlightStyle()->Color());
1035 Handle(Graphic3d_Group) aGroup = getGroup (anOwner->Index(), anOwner->Mode());
1036 if (aGroup.IsNull())
1041 if (anOwner->Mode() == AIS_MM_TranslationPlane)
1043 myDraggerHighlight->SetColor(myAxes[anOwner->Index()].Color());
1044 aGroup->SetGroupPrimitivesAspect(myDraggerHighlight->Aspect());
1047 aGroup->SetGroupPrimitivesAspect(myHighlightAspect->Aspect());
1049 myCurrentIndex = anOwner->Index();
1050 myCurrentMode = anOwner->Mode();
1053 //=======================================================================
1054 //function : ClearSelected
1056 //=======================================================================
1057 void AIS_Manipulator::ClearSelected()
1059 DeactivateCurrentMode();
1062 //=======================================================================
1063 //function : HilightOwnerWithColor
1065 //=======================================================================
1066 void AIS_Manipulator::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager)& thePM,
1067 const Handle(Prs3d_Drawer)& theStyle,
1068 const Handle(SelectMgr_EntityOwner)& theOwner)
1070 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theOwner);
1071 Handle(Prs3d_Presentation) aPresentation = getHighlightPresentation (anOwner);
1072 if (aPresentation.IsNull())
1077 aPresentation->CStructure()->ViewAffinity = myViewAffinity;
1079 if (anOwner->Mode() == AIS_MM_TranslationPlane)
1081 Handle(Prs3d_Drawer) aStyle = new Prs3d_Drawer();
1082 aStyle->SetColor (myAxes[anOwner->Index()].Color());
1083 aStyle->SetTransparency (0.5);
1084 aPresentation->Highlight (aStyle);
1088 aPresentation->Highlight (theStyle);
1091 for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPresentation->Groups());
1092 aGroupIter.More(); aGroupIter.Next())
1094 Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
1097 aGrp->SetGroupPrimitivesAspect (myHighlightAspect->Aspect());
1100 aPresentation->SetZLayer (Graphic3d_ZLayerId_Topmost);
1101 thePM->AddToImmediateList (aPresentation);
1103 if (myIsActivationOnDetection)
1105 if (HasActiveMode())
1107 DeactivateCurrentMode();
1110 myCurrentIndex = anOwner->Index();
1111 myCurrentMode = anOwner->Mode();
1115 //=======================================================================
1116 //function : ComputeSelection
1118 //=======================================================================
1119 void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
1120 const Standard_Integer theMode)
1123 const AIS_ManipulatorMode aMode = (AIS_ManipulatorMode) theMode;
1124 if (aMode == AIS_MM_None)
1128 Handle(SelectMgr_EntityOwner) anOwner;
1130 // Sensitivity calculation for manipulator parts allows to avoid
1131 // overlapping of sensitive areas when size of manipulator is small.
1132 // Sensitivity is calculated relative to the default size of the manipulator (100.0f).
1133 const Standard_ShortReal aSensitivityCoef = myAxes[0].Size() / 100.0f;
1134 const Standard_Integer aHighSensitivity = Max (Min (RealToInt (aSensitivityCoef * 15), 15), 3); // clamp sensitivity within range [3, 15]
1135 const Standard_Integer aLowSensitivity = Max (Min (RealToInt (aSensitivityCoef * 10), 10), 2); // clamp sensitivity within range [2, 10]
1139 case AIS_MM_Translation:
1141 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
1143 if (!myAxes[anIt].HasTranslation())
1147 const Axis& anAxis = myAxes[anIt];
1148 anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_Translation, 9);
1150 // define sensitivity by line
1151 Handle(Select3D_SensitiveSegment) aLine = new Select3D_SensitiveSegment(anOwner, gp::Origin(), anAxis.TranslatorTipPosition());
1152 aLine->SetSensitivityFactor (aHighSensitivity);
1153 theSelection->Add (aLine);
1155 // enlarge sensitivity by triangulation
1156 Handle(Select3D_SensitivePrimitiveArray) aTri = new Select3D_SensitivePrimitiveArray(anOwner);
1157 aTri->InitTriangulation (anAxis.TriangleArray()->Attributes(), anAxis.TriangleArray()->Indices(), TopLoc_Location());
1158 theSelection->Add (aTri);
1162 case AIS_MM_Rotation:
1164 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
1166 if (!myAxes[anIt].HasRotation())
1170 const Axis& anAxis = myAxes[anIt];
1171 anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_Rotation, 9);
1173 // define sensitivity by circle
1174 const gp_Circ aGeomCircle (gp_Ax2(gp::Origin(), anAxis.ReferenceAxis().Direction()), anAxis.RotatorDiskRadius());
1175 Handle(Select3D_SensitiveCircle) aCircle = new ManipSensCircle(anOwner, aGeomCircle);
1176 aCircle->SetSensitivityFactor (aLowSensitivity);
1177 theSelection->Add(aCircle);
1178 // enlarge sensitivity by triangulation
1179 Handle(Select3D_SensitiveTriangulation) aTri = new ManipSensTriangulation(anOwner, myAxes[anIt].RotatorDisk().Triangulation(), anAxis.ReferenceAxis().Direction());
1180 theSelection->Add (aTri);
1184 case AIS_MM_Scaling:
1186 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
1188 if (!myAxes[anIt].HasScaling())
1192 anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_Scaling, 9);
1194 // define sensitivity by point
1195 Handle(Select3D_SensitivePoint) aPnt = new Select3D_SensitivePoint(anOwner, myAxes[anIt].ScalerCubePosition());
1196 aPnt->SetSensitivityFactor (aHighSensitivity);
1197 theSelection->Add (aPnt);
1198 // enlarge sensitivity by triangulation
1199 Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation(anOwner, myAxes[anIt].ScalerCube().Triangulation(), TopLoc_Location(), Standard_True);
1200 theSelection->Add (aTri);
1204 case AIS_MM_TranslationPlane:
1206 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
1208 if (!myAxes[anIt].HasDragging())
1212 anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_TranslationPlane, 9);
1214 // define sensitivity by two crossed lines
1215 Standard_Real aSensitivityOffset = ZoomPersistence() ? aHighSensitivity * (0.5 + M_SQRT2) : 0.0;
1216 gp_Pnt aP1 = myAxes[((anIt + 1) % 3)].TranslatorTipPosition().Translated (myAxes[((anIt + 2) % 3)].ReferenceAxis().Direction().XYZ() * aSensitivityOffset);
1217 gp_Pnt aP2 = myAxes[((anIt + 2) % 3)].TranslatorTipPosition().Translated (myAxes[((anIt + 1) % 3)].ReferenceAxis().Direction().XYZ() * aSensitivityOffset);
1218 gp_XYZ aMidP = (aP1.XYZ() + aP2.XYZ()) / 2.0;
1219 gp_XYZ anOrig = aMidP.Normalized().Multiplied (aSensitivityOffset);
1221 Handle(Select3D_SensitiveSegment) aLine1 = new Select3D_SensitiveSegment(anOwner, aP1, aP2);
1222 aLine1->SetSensitivityFactor(aLowSensitivity);
1223 theSelection->Add (aLine1);
1224 Handle(Select3D_SensitiveSegment) aLine2 = new Select3D_SensitiveSegment(anOwner, anOrig, aMidP);
1225 aLine2->SetSensitivityFactor (aLowSensitivity);
1226 theSelection->Add (aLine2);
1228 // enlarge sensitivity by triangulation
1229 Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation(anOwner, myAxes[anIt].DraggerSector().Triangulation(), TopLoc_Location(), Standard_True);
1230 theSelection->Add (aTri);
1236 anOwner = new SelectMgr_EntityOwner(this, 5);
1242 //=======================================================================
1246 //=======================================================================
1247 void AIS_Manipulator::Disk::Init (const Standard_ShortReal theInnerRadius,
1248 const Standard_ShortReal theOuterRadius,
1249 const gp_Ax1& thePosition,
1250 const Standard_Integer theSlicesNb,
1251 const Standard_Integer theStacksNb)
1253 myPosition = thePosition;
1254 myInnerRad = theInnerRadius;
1255 myOuterRad = theOuterRadius;
1257 Prs3d_ToolDisk aTool (theInnerRadius, theOuterRadius, theSlicesNb, theStacksNb);
1258 gp_Ax3 aSystem (myPosition.Location(), myPosition.Direction());
1260 aTrsf.SetTransformation (aSystem, gp_Ax3());
1261 myArray = aTool.CreateTriangulation (aTrsf);
1262 myTriangulation = aTool.CreatePolyTriangulation (aTrsf);
1265 //=======================================================================
1269 //=======================================================================
1270 void AIS_Manipulator::Sphere::Init (const Standard_ShortReal theRadius,
1271 const gp_Pnt& thePosition,
1272 const Standard_Integer theSlicesNb,
1273 const Standard_Integer theStacksNb)
1275 myPosition = thePosition;
1276 myRadius = theRadius;
1278 Prs3d_ToolSphere aTool (theRadius, theSlicesNb, theStacksNb);
1280 aTrsf.SetTranslation (gp_Vec(gp::Origin(), thePosition));
1281 myArray = aTool.CreateTriangulation (aTrsf);
1282 myTriangulation = aTool.CreatePolyTriangulation (aTrsf);
1285 //=======================================================================
1289 //=======================================================================
1290 void AIS_Manipulator::Cube::Init (const gp_Ax1& thePosition, const Standard_ShortReal theSize)
1292 myArray = new Graphic3d_ArrayOfTriangles (12 * 3, 0, Standard_True);
1294 Poly_Array1OfTriangle aPolyTriangles (1, 12);
1295 TColgp_Array1OfPnt aPoints (1, 36);
1296 NCollection_Array1<gp_Dir> aNormals (1, 12);
1297 myTriangulation = new Poly_Triangulation (aPoints, aPolyTriangles);
1299 gp_Ax2 aPln (thePosition.Location(), thePosition.Direction());
1300 gp_Pnt aBottomLeft = thePosition.Location().XYZ() - aPln.XDirection().XYZ() * theSize * 0.5 - aPln.YDirection().XYZ() * theSize * 0.5;
1301 gp_Pnt aV2 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize;
1302 gp_Pnt aV3 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize + aPln.XDirection().XYZ() * theSize;
1303 gp_Pnt aV4 = aBottomLeft.XYZ() + aPln.XDirection().XYZ() * theSize;
1304 gp_Pnt aTopRight = thePosition.Location().XYZ() + thePosition.Direction().XYZ() * theSize
1305 + aPln.XDirection().XYZ() * theSize * 0.5 + aPln.YDirection().XYZ() * theSize * 0.5;
1306 gp_Pnt aV5 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize;
1307 gp_Pnt aV6 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize - aPln.XDirection().XYZ() * theSize;
1308 gp_Pnt aV7 = aTopRight.XYZ() - aPln.XDirection().XYZ() * theSize;
1310 gp_Dir aRight ((gp_Vec(aTopRight, aV7) ^ gp_Vec(aTopRight, aV2)).XYZ());
1311 gp_Dir aFront ((gp_Vec(aV3, aV4) ^ gp_Vec(aV3, aV5)).XYZ());
1314 addTriangle (0, aBottomLeft, aV2, aV3, -thePosition.Direction());
1315 addTriangle (1, aBottomLeft, aV3, aV4, -thePosition.Direction());
1318 addTriangle (2, aV3, aV5, aV4, -aFront);
1319 addTriangle (3, aV3, aTopRight, aV5, -aFront);
1322 addTriangle (4, aBottomLeft, aV7, aV2, aFront);
1323 addTriangle (5, aBottomLeft, aV6, aV7, aFront);
1326 addTriangle (6, aV7, aV6, aV5, thePosition.Direction());
1327 addTriangle (7, aTopRight, aV7, aV5, thePosition.Direction());
1330 addTriangle (8, aV6, aV4, aV5, aRight);
1331 addTriangle (9, aBottomLeft, aV4, aV6, aRight);
1334 addTriangle (10, aV3, aV7, aTopRight, -aRight);
1335 addTriangle (11, aV3, aV2, aV7, -aRight);
1338 //=======================================================================
1340 //function : addTriangle
1342 //=======================================================================
1343 void AIS_Manipulator::Cube::addTriangle (const Standard_Integer theIndex,
1344 const gp_Pnt& theP1, const gp_Pnt& theP2, const gp_Pnt& theP3,
1345 const gp_Dir& theNormal)
1347 myTriangulation->SetNode (theIndex * 3 + 1, theP1);
1348 myTriangulation->SetNode (theIndex * 3 + 2, theP2);
1349 myTriangulation->SetNode (theIndex * 3 + 3, theP3);
1351 myTriangulation->SetTriangle (theIndex + 1, Poly_Triangle (theIndex * 3 + 1, theIndex * 3 + 2, theIndex * 3 + 3));
1352 myArray->AddVertex (theP1, theNormal);
1353 myArray->AddVertex (theP2, theNormal);
1354 myArray->AddVertex (theP3, theNormal);
1357 //=======================================================================
1361 //=======================================================================
1362 void AIS_Manipulator::Sector::Init (const Standard_ShortReal theRadius,
1363 const gp_Ax1& thePosition,
1364 const gp_Dir& theXDirection,
1365 const Standard_Integer theSlicesNb,
1366 const Standard_Integer theStacksNb)
1368 Prs3d_ToolSector aTool(theRadius, theSlicesNb, theStacksNb);
1369 gp_Ax3 aSystem(thePosition.Location(), thePosition.Direction(), theXDirection);
1371 aTrsf.SetTransformation(aSystem, gp_Ax3());
1372 myArray = aTool.CreateTriangulation (aTrsf);
1373 myTriangulation = aTool.CreatePolyTriangulation (aTrsf);
1376 //=======================================================================
1378 //function : Constructor
1380 //=======================================================================
1381 AIS_Manipulator::Axis::Axis (const gp_Ax1& theAxis,
1382 const Quantity_Color& theColor,
1383 const Standard_ShortReal theLength)
1384 : myReferenceAxis (theAxis),
1385 myPosition (theAxis),
1387 myHasTranslation (Standard_True),
1388 myLength (theLength),
1389 myAxisRadius (0.5f),
1390 myHasScaling (Standard_True),
1392 myHasRotation (Standard_True),
1393 myInnerRadius (myLength + myBoxSize),
1394 myDiskThickness (myBoxSize * 0.5f),
1396 myHasDragging(Standard_True),
1397 myFacettesNumber (20),
1398 myCircleRadius (myLength + myBoxSize + myBoxSize * 0.5f * 0.5f)
1403 //=======================================================================
1405 //function : Compute
1407 //=======================================================================
1409 void AIS_Manipulator::Axis::Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
1410 const Handle(Prs3d_Presentation)& thePrs,
1411 const Handle(Prs3d_ShadingAspect)& theAspect)
1413 if (myHasTranslation)
1415 const Standard_Real anArrowLength = 0.25 * myLength;
1416 const Standard_Real aCylinderLength = myLength - anArrowLength;
1417 myArrowTipPos = gp_Pnt (0.0, 0.0, 0.0).Translated (myReferenceAxis.Direction().XYZ() * aCylinderLength);
1419 myTriangleArray = Prs3d_Arrow::DrawShaded (gp_Ax1(gp::Origin(), myReferenceAxis.Direction()),
1425 myTranslatorGroup = thePrs->NewGroup();
1426 myTranslatorGroup->SetClosed (true);
1427 myTranslatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1428 myTranslatorGroup->AddPrimitiveArray (myTriangleArray);
1430 if (myHighlightTranslator.IsNull())
1432 myHighlightTranslator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1436 myHighlightTranslator->Clear();
1439 Handle(Graphic3d_Group) aGroup = myHighlightTranslator->CurrentGroup();
1440 aGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1441 aGroup->AddPrimitiveArray (myTriangleArray);
1447 myCubePos = myReferenceAxis.Direction().XYZ() * (myLength + myIndent);
1448 myCube.Init (gp_Ax1 (myCubePos, myReferenceAxis.Direction()), myBoxSize);
1450 myScalerGroup = thePrs->NewGroup();
1451 myScalerGroup->SetClosed (true);
1452 myScalerGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1453 myScalerGroup->AddPrimitiveArray (myCube.Array());
1455 if (myHighlightScaler.IsNull())
1457 myHighlightScaler = new Prs3d_Presentation (thePrsMgr->StructureManager());
1461 myHighlightScaler->Clear();
1464 Handle(Graphic3d_Group) aGroup = myHighlightScaler->CurrentGroup();
1465 aGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1466 aGroup->AddPrimitiveArray (myCube.Array());
1472 myCircleRadius = myInnerRadius + myIndent * 2 + myDiskThickness * 0.5f;
1473 myCircle.Init (myInnerRadius + myIndent * 2, myInnerRadius + myDiskThickness + myIndent * 2, gp_Ax1(gp::Origin(), myReferenceAxis.Direction()), myFacettesNumber * 2);
1474 myRotatorGroup = thePrs->NewGroup ();
1475 myRotatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1476 myRotatorGroup->AddPrimitiveArray (myCircle.Array());
1478 if (myHighlightRotator.IsNull())
1480 myHighlightRotator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1484 myHighlightRotator->Clear();
1487 Handle(Graphic3d_Group) aGroup = myHighlightRotator->CurrentGroup();
1488 aGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1489 aGroup->AddPrimitiveArray (myCircle.Array());
1496 if (myReferenceAxis.Direction().X() > 0)
1497 aXDirection = gp::DY();
1498 else if (myReferenceAxis.Direction().Y() > 0)
1499 aXDirection = gp::DZ();
1501 aXDirection = gp::DX();
1503 mySector.Init(myInnerRadius + myIndent * 2, gp_Ax1(gp::Origin(), myReferenceAxis.Direction()), aXDirection, myFacettesNumber * 2);
1504 myDraggerGroup = thePrs->NewGroup();
1506 Handle(Graphic3d_AspectFillArea3d) aFillArea = new Graphic3d_AspectFillArea3d();
1507 myDraggerGroup->SetGroupPrimitivesAspect(aFillArea);
1508 myDraggerGroup->AddPrimitiveArray(mySector.Array());
1510 if (myHighlightDragger.IsNull())
1512 myHighlightDragger = new Prs3d_Presentation(thePrsMgr->StructureManager());
1516 myHighlightDragger->Clear();
1519 Handle(Graphic3d_Group) aGroup = myHighlightDragger->CurrentGroup();
1520 aGroup->SetGroupPrimitivesAspect(aFillArea);
1521 aGroup->AddPrimitiveArray(mySector.Array());