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_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>
40 IMPLEMENT_STANDARD_HANDLE (AIS_Manipulator, AIS_InteractiveObject)
41 IMPLEMENT_STANDARD_RTTIEXT(AIS_Manipulator, AIS_InteractiveObject)
43 IMPLEMENT_HSEQUENCE(AIS_ManipulatorObjectSequence)
45 //=======================================================================
48 //=======================================================================
49 void AIS_Manipulator::init()
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);
56 Graphic3d_MaterialAspect aShadingMaterial;
57 aShadingMaterial.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
58 aShadingMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
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);
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);
73 myHighlightAspect = new Prs3d_ShadingAspect();
74 myHighlightAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
75 myHighlightAspect->SetMaterial (aHilightMaterial);
78 SetZLayer (Graphic3d_ZLayerId_Topmost);
81 //=======================================================================
82 //function : getHighlightPresentation
84 //=======================================================================
85 Handle(Prs3d_Presentation) AIS_Manipulator::getHighlightPresentation (const Handle(SelectMgr_EntityOwner)& theOwner) const
87 Handle(Prs3d_Presentation) aDummyPrs;
88 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theOwner);
94 switch (anOwner->Mode())
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;
105 //=======================================================================
106 //function : getGroup
108 //=======================================================================
109 Handle(Graphic3d_Group) AIS_Manipulator::getGroup (const Standard_Integer theIndex, const AIS_ManipulatorMode theMode) const
111 Handle(Graphic3d_Group) aDummyGroup;
113 if (theIndex < 0 || theIndex > 2)
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;
129 //=======================================================================
130 //function : Constructor
132 //=======================================================================
133 AIS_Manipulator::AIS_Manipulator()
134 : myPosition (gp::XOY()),
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),
145 SetMutable (Standard_True);
146 SetDisplayMode (AIS_Shaded);
150 //=======================================================================
151 //function : Constructor
153 //=======================================================================
154 AIS_Manipulator::AIS_Manipulator (const gp_Ax2& thePosition)
155 : myPosition (thePosition),
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),
166 SetMutable (Standard_True);
167 SetDisplayMode (AIS_Shaded);
171 //=======================================================================
174 //=======================================================================
175 void AIS_Manipulator::SetPart (const Standard_Integer theAxisIndex, const AIS_ManipulatorMode theMode, const Standard_Boolean theIsEnabled)
177 Standard_ProgramError_Raise_if (theAxisIndex < 0 || theAxisIndex > 2, "AIS_Manipulator::SetMode(): axis index should be between 0 and 2");
180 case AIS_MM_Translation:
181 myAxes[theAxisIndex].SetTranslation (theIsEnabled);
184 case AIS_MM_Rotation:
185 myAxes[theAxisIndex].SetRotation (theIsEnabled);
189 myAxes[theAxisIndex].SetScaling (theIsEnabled);
197 //=======================================================================
198 //function : EnableMode
200 //=======================================================================
201 void AIS_Manipulator::EnableMode (const AIS_ManipulatorMode theMode)
208 const Handle(AIS_InteractiveContext)& aContext = GetContext();
209 if (aContext.IsNull())
214 aContext->Activate (this, theMode);
217 //=======================================================================
218 //function : attachToBox
220 //=======================================================================
221 void AIS_Manipulator::attachToBox (const Bnd_Box& theBox)
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);
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);
236 //=======================================================================
237 //function : adjustSize
239 //=======================================================================
240 void AIS_Manipulator::adjustSize (const Bnd_Box& theBox)
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;
248 SetSize ((Standard_ShortReal) (Max (aXSize, Max (aYSize, aZSize)) * 0.5));
251 //=======================================================================
254 //=======================================================================
255 void AIS_Manipulator::Attach (const Handle(AIS_InteractiveObject)& theObject, const OptionsForAttach& theOptions)
257 if (theObject->IsKind (STANDARD_TYPE(AIS_Manipulator)))
262 Handle(AIS_ManipulatorObjectSequence) aSeq = new AIS_ManipulatorObjectSequence();
263 aSeq->Append (theObject);
264 Attach (aSeq, theOptions);
267 //=======================================================================
270 //=======================================================================
271 void AIS_Manipulator::Attach (const Handle(AIS_ManipulatorObjectSequence)& theObjects, const OptionsForAttach& theOptions)
273 if (theObjects->Size() < 1)
278 SetOwner (theObjects);
280 const Handle(AIS_InteractiveObject)& aCurObject = theObjects->Value (theObjects->Lower());
281 aCurObject->BoundingBox (aBox);
283 if (theOptions.AdjustPosition)
288 if (theOptions.AdjustSize)
293 const Handle(AIS_InteractiveContext)& aContext = Object()->GetContext();
294 if (!aContext.IsNull())
296 if (!aContext->IsDisplayed (this))
298 aContext->Display (this, Standard_False);
302 aContext->Update (this, Standard_False);
303 aContext->RecomputeSelectionOnly (this);
306 aContext->Load (this);
307 aContext->CurrentViewer()->RedrawImmediate();
310 if (theOptions.EnableModes)
312 EnableMode (AIS_MM_Rotation);
313 EnableMode (AIS_MM_Translation);
314 EnableMode (AIS_MM_Scaling);
318 //=======================================================================
321 //=======================================================================
322 void AIS_Manipulator::Detach()
324 DeactivateCurrentMode();
331 Handle(AIS_InteractiveObject) anObject = Object();
332 const Handle(AIS_InteractiveContext)& aContext = anObject->GetContext();
333 if (!aContext.IsNull())
335 aContext->Remove (this, Standard_False);
341 //=======================================================================
344 //=======================================================================
345 Handle(AIS_ManipulatorObjectSequence) AIS_Manipulator::Objects() const
347 return Handle(AIS_ManipulatorObjectSequence)::DownCast (GetOwner());
350 //=======================================================================
353 //=======================================================================
354 Handle(AIS_InteractiveObject) AIS_Manipulator::Object (const Standard_Integer theIndex) const
356 Handle(AIS_ManipulatorObjectSequence) anOwner = Handle(AIS_ManipulatorObjectSequence)::DownCast (GetOwner());
358 Standard_ProgramError_Raise_if (theIndex < anOwner->Lower() || theIndex > anOwner->Upper(), "AIS_Manipulator::Object(): wrong index value");
360 if (anOwner.IsNull() || anOwner->IsEmpty())
365 return anOwner->Value (theIndex);
368 //=======================================================================
371 //=======================================================================
372 Handle(AIS_InteractiveObject) AIS_Manipulator::Object() const
377 //=======================================================================
378 //function : ObjectTransformation
380 //=======================================================================
381 Standard_Boolean AIS_Manipulator::ObjectTransformation (const Standard_Integer theMaxX, const Standard_Integer theMaxY,
382 const Handle(V3d_View)& theView, gp_Trsf& theTrsf)
384 // Initialize start reference data
385 if (!myHasStartedTransformation)
387 Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
388 myStartTrsfs.Clear();
389 for (Standard_Integer anIt = anObjects->Lower(); anIt <= anObjects->Upper(); ++anIt)
391 myStartTrsfs.Append (anObjects->Value (anIt)->LocalTransformation());
393 myStartPosition = myPosition;
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();
403 switch (myCurrentMode)
405 case AIS_MM_Translation:
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);
412 anExtrema.NearestPoints (aP1, aP2);
415 if (!myHasStartedTransformation)
417 myStartPick = aNewPosition;
418 myHasStartedTransformation = Standard_True;
419 return Standard_True;
422 if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
424 return Standard_False;
428 aNewTrsf.SetTranslation (gp_Vec(myStartPick, aNewPosition));
432 case AIS_MM_Rotation:
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)
439 return Standard_False;
442 aNewPosition = aIntersector.Point (1);
444 if (!myHasStartedTransformation)
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;
453 if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
455 return Standard_False;
458 gp_Dir aStartAxis = myPosition.Location().IsEqual (myStartPick, Precision::Confusion())
459 ? myAxes[(myCurrentIndex + 1) % 3].Position().Direction()
460 : gce_MakeDir (myPosition.Location(), myStartPick);
462 gp_Dir aCurrentAxis = gce_MakeDir (myPosition.Location(), aNewPosition);
463 Standard_Real anAngle = aStartAxis.AngleWithRef (aCurrentAxis, myAxes[myCurrentIndex].Position().Direction());
465 // Change value of an angle if it should have different sign.
466 if (anAngle * myPrevState < 0 && Abs (anAngle) < M_PI_2)
468 Standard_ShortReal aSign = myPrevState > 0 ? -1.0f : 1.0f;
469 anAngle = aSign * (M_PI * 2 - anAngle);
472 if (Abs (anAngle) < Precision::Confusion())
474 return Standard_False;
478 aNewTrsf.SetRotation (myAxes[myCurrentIndex].Position(), anAngle);
480 myPrevState = anAngle;
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);
490 anExtrema.NearestPoints (aTmp, aNewPosition);
492 if (!myHasStartedTransformation)
494 myStartPick = aNewPosition;
495 myHasStartedTransformation = Standard_True;
496 return Standard_True;
499 if (aNewPosition.Distance (myStartPick) < Precision::Confusion()
500 || aNewPosition.Distance (myStartPosition.Location()) < Precision::Confusion())
502 return Standard_False;
505 Standard_Real aCoeff = myStartPosition.Location().Distance (aNewPosition)
506 / myStartPosition.Location().Distance (myStartPick);
508 aNewTrsf.SetScale (myPosition.Location(), aCoeff);
514 return Standard_False;
517 return Standard_True;
520 //=======================================================================
521 //function : StartTransform
523 //=======================================================================
524 void AIS_Manipulator::StartTransform (const Standard_Integer theX, const Standard_Integer theY, const Handle(V3d_View)& theView)
526 if (myHasStartedTransformation)
532 ObjectTransformation (theX, theY, theView, aTrsf);
535 //=======================================================================
536 //function : StopTransform
538 //=======================================================================
539 void AIS_Manipulator::StopTransform (const Standard_Boolean theToApply)
541 if (!IsAttached() || !myHasStartedTransformation)
546 myHasStartedTransformation = Standard_False;
550 Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
552 for (Standard_Integer anIt = anObjects->Lower(); anIt <= anObjects->Upper(); ++anIt)
554 anObjects->Value (anIt)->SetLocalTransformation (myStartTrsfs(anIt));
557 SetPosition (myStartPosition);
561 //=======================================================================
562 //function : Transform
564 //=======================================================================
565 void AIS_Manipulator::Transform (const gp_Trsf& theTrsf)
567 if (!IsAttached() || !myHasStartedTransformation)
572 Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
574 for (Standard_Integer anIt = anObjects->Lower(); anIt <= anObjects->Upper(); ++anIt)
576 anObjects->Value (anIt)->SetLocalTransformation (theTrsf * myStartTrsfs(anIt));
579 if ((myCurrentMode == AIS_MM_Translation && myBehaviorOnTransform.FollowTranslation)
580 || (myCurrentMode == AIS_MM_Rotation && myBehaviorOnTransform.FollowRotation))
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));
589 //=======================================================================
590 //function : Transform
592 //=======================================================================
593 gp_Trsf AIS_Manipulator::Transform (const Standard_Integer thePX, const Standard_Integer thePY,
594 const Handle(V3d_View)& theView)
597 if (ObjectTransformation (thePX, thePY, theView, aTrsf))
605 //=======================================================================
606 //function : SetPosition
608 //=======================================================================
609 void AIS_Manipulator::SetPosition (const gp_Ax2& thePosition)
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()))
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()));
620 updateTransformation();
624 //=======================================================================
625 //function : updateTransformation
626 //purpose : set local transformation to avoid graphics recomputation
627 //=======================================================================
628 void AIS_Manipulator::updateTransformation()
632 if (!myIsZoomPersistentMode)
634 aTrsf.SetTransformation (myPosition, gp::XOY());
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());
643 AIS_InteractiveObject::SetLocalTransformation (aTrsf);
645 Handle(Geom_Transformation) aGeomTrsf = new Geom_Transformation (this->Transformation());
647 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
649 myAxes[anIt].Transform (aGeomTrsf);
652 if (myIsZoomPersistentMode)
654 if (!(GetTransformPersistenceMode () == Graphic3d_TMF_ZoomPers
655 && GetTransformPersistencePoint().IsEqual (myPosition.Location(), 0.)))
657 setTransformPersistence (Graphic3d_TMF_ZoomPers, myPosition.Location());
662 //=======================================================================
665 //=======================================================================
666 void AIS_Manipulator::SetSize (const Standard_ShortReal theSideLength)
668 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
670 myAxes[anIt].SetSize (theSideLength);
676 //=======================================================================
679 //=======================================================================
680 void AIS_Manipulator::SetGap (const Standard_ShortReal theValue)
682 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
684 myAxes[anIt].SetIndent (theValue);
690 //=======================================================================
691 //function : DeactivateCurrentMode
693 //=======================================================================
694 void AIS_Manipulator::DeactivateCurrentMode()
696 if (!myIsActivationOnDetection)
698 Handle(Graphic3d_Group) aGroup = getGroup (myCurrentIndex, myCurrentMode);
704 Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
705 anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
706 anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
707 anAspect->SetTransparency (myDrawer->ShadingAspect()->Transparency());
708 anAspect->SetColor (myAxes[myCurrentIndex].Color());
710 aGroup->SetGroupPrimitivesAspect (anAspect->Aspect());
714 myCurrentMode = AIS_MM_None;
716 if (myHasStartedTransformation)
718 myHasStartedTransformation = Standard_False;
722 //=======================================================================
723 //function : SetZoomPersistence
725 //=======================================================================
726 void AIS_Manipulator::SetZoomPersistence (const Standard_Boolean theToEnable)
728 if (myIsZoomPersistentMode != theToEnable)
733 myIsZoomPersistentMode = theToEnable;
737 setTransformPersistence (Graphic3d_TMF_None, gp::Origin());
740 updateTransformation();
743 //=======================================================================
744 //function : SetTransformPersistence
746 //=======================================================================
747 void AIS_Manipulator::SetTransformPersistence (const Graphic3d_TransModeFlags& theFlag, const gp_Pnt& thePoint)
749 Standard_ASSERT_RETURN (!myIsZoomPersistentMode,
750 "AIS_Manipulator::SetTransformPersistence: "
751 "Custom settings are not supported by this class in ZoomPersistence mode",);
753 setTransformPersistence (theFlag, thePoint);
756 //=======================================================================
757 //function : setTransformPersistence
759 //=======================================================================
760 void AIS_Manipulator::setTransformPersistence (const Graphic3d_TransModeFlags& theFlag, const gp_Pnt& thePoint)
762 AIS_InteractiveObject::SetTransformPersistence (theFlag, thePoint);
764 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
766 myAxes[anIt].SetTransformPersistence (theFlag, thePoint);
770 //=======================================================================
771 //function : SetLocalTransformation
773 //=======================================================================
774 void AIS_Manipulator::SetLocalTransformation (const gp_Trsf& /*theTransformation*/)
776 Standard_ASSERT_INVOKE (
777 "AIS_Manipulator::SetLocalTransformation: "
778 "Custom transformation is not supported by this class");
781 //=======================================================================
784 //=======================================================================
785 void AIS_Manipulator::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
786 const Handle(Prs3d_Presentation)& thePrs,
787 const Standard_Integer theMode)
789 if (theMode != AIS_Shaded)
794 thePrs->SetInfiniteState (Standard_True);
795 thePrs->SetMutable (Standard_True);
796 Handle(Graphic3d_Group) aGroup;
797 Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
798 anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
799 anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
800 anAspect->SetTransparency (myDrawer->ShadingAspect()->Transparency());
803 myCenter.Init (myAxes[0].AxisRadius() * 2.0f, gp::Origin());
804 aGroup = Prs3d_Root::NewGroup (thePrs);
805 aGroup->SetPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
806 aGroup->AddPrimitiveArray (myCenter.Array());
808 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
811 aGroup = Prs3d_Root::NewGroup (thePrs);
812 anAspect->SetColor (myAxes[anIt].Color());
813 aGroup->SetGroupPrimitivesAspect (anAspect->Aspect());
814 myAxes[anIt].Compute (thePrsMgr, thePrs, anAspect);
815 myAxes[anIt].SetTransformPersistence (GetTransformPersistenceMode(),
816 GetTransformPersistencePoint());
819 updateTransformation();
822 //=======================================================================
823 //function : HilightSelected
825 //=======================================================================
826 void AIS_Manipulator::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
827 const SelectMgr_SequenceOfOwner& theSeq)
829 if (theSeq.IsEmpty())
834 if (myIsActivationOnDetection)
839 if (!theSeq (1)->IsKind (STANDARD_TYPE (AIS_ManipulatorOwner)))
841 thePM->Color (this, GetContext()->HilightColor(), 0);
845 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theSeq (1));
846 myHighlightAspect->Aspect()->SetInteriorColor (GetContext()->HilightColor());
847 Handle(Graphic3d_Group) aGroup = getGroup (anOwner->Index(), anOwner->Mode());
853 aGroup->SetGroupPrimitivesAspect (myHighlightAspect->Aspect());
855 myCurrentIndex = anOwner->Index();
856 myCurrentMode = anOwner->Mode();
859 //=======================================================================
860 //function : ClearSelected
862 //=======================================================================
863 void AIS_Manipulator::ClearSelected()
865 DeactivateCurrentMode();
868 //=======================================================================
869 //function : HilightOwnerWithColor
871 //=======================================================================
872 void AIS_Manipulator::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM, const Quantity_NameOfColor theColor, const Handle(SelectMgr_EntityOwner)& theOwner)
874 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theOwner);
875 Handle(Prs3d_Presentation) aPresentation = getHighlightPresentation (anOwner);
876 if (aPresentation.IsNull())
880 aPresentation->Highlight (Aspect_TOHM_COLOR, theColor);
881 aPresentation->SetShadingAspect (myHighlightAspect);
882 aPresentation->SetZLayer (Graphic3d_ZLayerId_Topmost);
883 thePM->AddToImmediateList (aPresentation);
885 if (myIsActivationOnDetection)
889 DeactivateCurrentMode();
892 myCurrentIndex = anOwner->Index();
893 myCurrentMode = anOwner->Mode();
897 //=======================================================================
898 //function : ComputeSelection
900 //=======================================================================
901 void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
902 const Standard_Integer theMode)
905 AIS_ManipulatorMode aMode = (AIS_ManipulatorMode) theMode;
906 if (aMode == AIS_MM_None)
910 Handle(SelectMgr_EntityOwner) anOwner;
911 if (aMode == AIS_MM_None)
913 anOwner = new SelectMgr_EntityOwner (this, 5);
915 Handle(Select3D_SensitiveTriangulation) aTri;
916 if (aMode == AIS_MM_Translation || aMode == AIS_MM_None)
918 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
920 const Axis& anAxis = myAxes[anIt];
921 if (aMode != AIS_MM_None)
923 anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_Translation, 9);
925 // define sensitivity by line
926 Handle(Select3D_SensitiveSegment) aLine = new Select3D_SensitiveSegment (anOwner, gp::Origin(), anAxis.TranslatorTipPosition());
927 aLine->SetSensitivityFactor (15);
928 theSelection->Add (aLine);
929 // enlarge sensitivity by triangulation
930 aTri = new Select3D_SensitiveTriangulation (anOwner, anAxis.TranslatorCylinder().Triangulation(), TopLoc_Location(), Standard_True);
931 theSelection->Add (aTri);
932 aTri = new Select3D_SensitiveTriangulation (anOwner, anAxis.TranslatorArrow().Triangulation(), TopLoc_Location(), Standard_True);
933 theSelection->Add (aTri);
934 aTri = new Select3D_SensitiveTriangulation (anOwner, anAxis.TranslatorArrowBottom().Triangulation(), TopLoc_Location(), Standard_True);
935 theSelection->Add (aTri);
939 if (aMode == AIS_MM_Rotation || aMode == AIS_MM_None)
941 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
943 const Axis& anAxis = myAxes[anIt];
944 if (aMode != AIS_MM_None)
946 anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Rotation, 9);
948 // define sensitivity by circle
949 Handle(Geom_Circle) aGeomCircle = new Geom_Circle (gp_Ax2 (gp::Origin(), anAxis.ReferenceAxis().Direction()), anAxis.RotatorDiskRadius());
950 Handle(Select3D_SensitiveCircle) aCircle = new Select3D_SensitiveCircle (anOwner, aGeomCircle, Standard_False, anAxis.FacettesNumber());
951 aCircle->SetSensitivityFactor (15);
952 theSelection->Add (aCircle);
953 // enlarge sensitivity by triangulation
954 aTri = new Select3D_SensitiveTriangulation (anOwner, myAxes[anIt].RotatorDisk().Triangulation(), TopLoc_Location(), Standard_True);
955 theSelection->Add (aTri);
959 if (aMode == AIS_MM_Scaling || aMode == AIS_MM_None)
961 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
963 if (aMode != AIS_MM_None)
965 anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Scaling, 9);
967 // define sensitivity by point
968 Handle(Select3D_SensitivePoint) aPnt = new Select3D_SensitivePoint (anOwner, myAxes[anIt].ScalerCubePosition());
969 aPnt->SetSensitivityFactor (15);
970 theSelection->Add (aPnt);
971 // enlarge sensitivity by triangulation
972 aTri = new Select3D_SensitiveTriangulation (anOwner, myAxes[anIt].ScalerCube().Triangulation(), TopLoc_Location(), Standard_True);
973 theSelection->Add (aTri);
978 //=======================================================================
982 //=======================================================================
983 void AIS_Manipulator::Cylinder::Init (const Standard_ShortReal theBotRad, const Standard_ShortReal theTopRad,
984 const Standard_ShortReal theHeight,
985 const Standard_Integer theSlicesNb, const Standard_Integer theStacksNb,
986 const gp_Ax1& thePosition)
988 myPosition = thePosition;
989 myBottomRad = theBotRad;
990 myTopRad = theTopRad;
991 myHeight = theHeight;
993 StdPrs_ToolCylinder aTool (myBottomRad, myTopRad, myHeight, theSlicesNb, theStacksNb);
994 gp_Ax3 aSystem (myPosition.Location(), myPosition.Direction());
996 aTrsf.SetTransformation (aSystem, gp_Ax3());
998 aTool.FillArray (myArray, myTriangulation, aTrsf);
1001 //=======================================================================
1005 //=======================================================================
1006 void AIS_Manipulator::Disk::Init (const Standard_ShortReal theInnerRadius,
1007 const Standard_ShortReal theOuterRadius,
1008 const gp_Ax1& thePosition,
1009 const Standard_Integer theSlicesNb,
1010 const Standard_Integer theStacksNb)
1012 myPosition = thePosition;
1013 myInnerRad = theInnerRadius;
1014 myOuterRad = theOuterRadius;
1016 StdPrs_ToolDisk aTool (theInnerRadius, theOuterRadius, theSlicesNb, theStacksNb);
1017 gp_Ax3 aSystem (myPosition.Location(), myPosition.Direction());
1019 aTrsf.SetTransformation (aSystem, gp_Ax3());
1020 aTool.FillArray (myArray, myTriangulation, aTrsf);
1023 //=======================================================================
1027 //=======================================================================
1028 void AIS_Manipulator::Sphere::Init (const Standard_ShortReal theRadius,
1029 const gp_Pnt& thePosition,
1030 const Standard_Integer theSlicesNb,
1031 const Standard_Integer theStacksNb)
1033 myPosition = thePosition;
1034 myRadius = theRadius;
1036 StdPrs_ToolSphere aTool (theRadius, theSlicesNb, theStacksNb);
1038 aTrsf.SetTranslation (gp_Vec(gp::Origin(), thePosition));
1039 aTool.FillArray (myArray, myTriangulation, aTrsf);
1042 //=======================================================================
1046 //=======================================================================
1047 void AIS_Manipulator::Cube::Init (const gp_Ax1& thePosition, const Standard_ShortReal theSize)
1049 myArray = new Graphic3d_ArrayOfTriangles (12 * 3, 0, Standard_True);
1051 Poly_Array1OfTriangle aPolyTriangles (1, 12);
1052 TColgp_Array1OfPnt aPoints (1, 36);
1053 NCollection_Array1<gp_Dir> aNormals (1, 12);
1054 myTriangulation = new Poly_Triangulation (aPoints, aPolyTriangles);
1056 gp_Ax2 aPln (thePosition.Location(), thePosition.Direction());
1057 gp_Pnt aBottomLeft = thePosition.Location().XYZ() - aPln.XDirection().XYZ() * theSize * 0.5 - aPln.YDirection().XYZ() * theSize * 0.5;
1058 gp_Pnt aV2 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize;
1059 gp_Pnt aV3 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize + aPln.XDirection().XYZ() * theSize;
1060 gp_Pnt aV4 = aBottomLeft.XYZ() + aPln.XDirection().XYZ() * theSize;
1061 gp_Pnt aTopRight = thePosition.Location().XYZ() + thePosition.Direction().XYZ() * theSize
1062 + aPln.XDirection().XYZ() * theSize * 0.5 + aPln.YDirection().XYZ() * theSize * 0.5;
1063 gp_Pnt aV5 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize;
1064 gp_Pnt aV6 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize - aPln.XDirection().XYZ() * theSize;
1065 gp_Pnt aV7 = aTopRight.XYZ() - aPln.XDirection().XYZ() * theSize;
1067 gp_Dir aRight ((gp_Vec(aTopRight, aV7) ^ gp_Vec(aTopRight, aV2)).XYZ());
1068 gp_Dir aFront ((gp_Vec(aV3, aV4) ^ gp_Vec(aV3, aV5)).XYZ());
1071 addTriangle (0, aBottomLeft, aV2, aV3, -thePosition.Direction());
1072 addTriangle (1, aBottomLeft, aV3, aV4, -thePosition.Direction());
1075 addTriangle (2, aV3, aV4, aV5, aFront);
1076 addTriangle (3, aV3, aV5, aTopRight, aFront);
1079 addTriangle (4, aBottomLeft, aV2, aV7, -aFront);
1080 addTriangle (5, aBottomLeft, aV7, aV6, -aFront);
1083 addTriangle (6, aV7, aV6, aV5, thePosition.Direction());
1084 addTriangle (7, aTopRight, aV7, aV5, thePosition.Direction());
1087 addTriangle (8, aV6, aV5, aV4, -aRight);
1088 addTriangle (9, aBottomLeft, aV6, aV4, -aRight);
1091 addTriangle (10, aV3, aTopRight, aV7, aRight);
1092 addTriangle (11, aV3, aV7, aV2, aRight);
1095 //=======================================================================
1097 //function : addTriangle
1099 //=======================================================================
1100 void AIS_Manipulator::Cube::addTriangle (const Standard_Integer theIndex,
1101 const gp_Pnt& theP1, const gp_Pnt& theP2, const gp_Pnt& theP3,
1102 const gp_Dir& theNormal)
1104 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 1, theP1);
1105 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 2, theP2);
1106 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 3, theP3);
1108 myTriangulation->ChangeTriangles().SetValue (theIndex + 1, Poly_Triangle (theIndex * 3 + 1, theIndex * 3 + 2, theIndex * 3 + 3));
1109 myArray->AddVertex (theP1, theNormal);
1110 myArray->AddVertex (theP2, theNormal);
1111 myArray->AddVertex (theP3, theNormal);
1114 //=======================================================================
1116 //function : Constructor
1118 //=======================================================================
1119 AIS_Manipulator::Axis::Axis (const gp_Ax1& theAxis,
1120 const Quantity_Color& theColor,
1121 const Standard_ShortReal theLength)
1122 : myReferenceAxis (theAxis),
1123 myPosition (theAxis),
1125 myHasTranslation (Standard_True),
1126 myLength (theLength),
1127 myAxisRadius (0.5f),
1128 myHasScaling (Standard_True),
1130 myHasRotation (Standard_True),
1131 myInnerRadius (myLength + myBoxSize),
1132 myDiskThickness (myBoxSize * 0.5f),
1134 myFacettesNumber (20),
1135 myCircleRadius (myLength + myBoxSize + myBoxSize * 0.5f * 0.5f)
1140 //=======================================================================
1142 //function : Compute
1144 //=======================================================================
1145 void AIS_Manipulator::Axis::Compute (const Handle_PrsMgr_PresentationManager3d& thePrsMgr,
1146 const Handle(Prs3d_Presentation)& thePrs,
1147 const Handle(Prs3d_ShadingAspect)& theAspect)
1149 Handle(Graphic3d_Group) aGroup;
1151 if (myHasTranslation)
1153 const Standard_ShortReal anArrowLength = 0.25f * myLength;
1154 const Standard_ShortReal aCylinderLength = myLength - anArrowLength;
1156 myCylinder.Init (myAxisRadius, myAxisRadius, aCylinderLength, myFacettesNumber, 2, gp_Ax1 (gp::Origin(), myReferenceAxis.Direction()));
1158 gp_Pnt anArrowBottom (0.0, 0.0, 0.0);
1159 anArrowBottom.Translate (myReferenceAxis.Direction().XYZ() * aCylinderLength);
1161 myArrow.Init (myAxisRadius * 1.5f, 0.0f, anArrowLength, myFacettesNumber, 2, gp_Ax1 (anArrowBottom, myReferenceAxis.Direction()));
1162 myArrowBottom.Init (myAxisRadius, myAxisRadius * 1.5f, gp_Ax1 (anArrowBottom, myReferenceAxis.Direction()), myFacettesNumber);
1163 myArrowTipPos = anArrowBottom;
1165 myTranslatorGroup = Prs3d_Root::NewGroup (thePrs);
1166 myTranslatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1167 myTranslatorGroup->AddPrimitiveArray (myCylinder.Array());
1168 myTranslatorGroup->AddPrimitiveArray (myArrow.Array());
1169 myTranslatorGroup->AddPrimitiveArray (myArrowBottom.Array());
1171 if (myHighlightTranslator.IsNull())
1173 myHighlightTranslator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1176 myHighlightTranslator->Clear();
1177 aGroup = Prs3d_Root::CurrentGroup (myHighlightTranslator);
1178 aGroup->AddPrimitiveArray (myCylinder.Array());
1179 aGroup->AddPrimitiveArray (myArrow.Array());
1180 aGroup->AddPrimitiveArray (myArrowBottom.Array());
1185 myCubePos = myReferenceAxis.Direction().XYZ() * (myLength + myIndent);
1186 myCube.Init (gp_Ax1 (myCubePos, myReferenceAxis.Direction()), myBoxSize);
1188 myScalerGroup = Prs3d_Root::NewGroup (thePrs);
1189 myScalerGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1190 myScalerGroup->AddPrimitiveArray (myCube.Array());
1192 if (myHighlightScaler.IsNull())
1194 myHighlightScaler = new Prs3d_Presentation (thePrsMgr->StructureManager());
1197 myHighlightScaler->Clear();
1198 aGroup = Prs3d_Root::CurrentGroup (myHighlightScaler);
1199 aGroup->AddPrimitiveArray (myCube.Array());
1204 myCircleRadius = myInnerRadius + myIndent * 2 + myDiskThickness * 0.5f;
1205 myCircle.Init (myInnerRadius + myIndent * 2, myInnerRadius + myDiskThickness + myIndent * 2, gp_Ax1(gp::Origin(), myReferenceAxis.Direction()), myFacettesNumber * 2);
1206 myRotatorGroup = Prs3d_Root::NewGroup (thePrs);
1207 myRotatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1208 myRotatorGroup->AddPrimitiveArray (myCircle.Array());
1210 if (myHighlightRotator.IsNull())
1212 myHighlightRotator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1215 myHighlightRotator->Clear();
1216 aGroup = Prs3d_Root::CurrentGroup (myHighlightRotator);
1217 Prs3d_Root::CurrentGroup (myHighlightRotator)->AddPrimitiveArray (myCircle.Array());