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 <Extrema_ExtElC.hxx>
21 #include <gce_MakeDir.hxx>
22 #include <Geom_Circle.hxx>
23 #include <Geom_Transformation.hxx>
24 #include <IntAna_IntConicQuad.hxx>
25 #include <Prs3d_Arrow.hxx>
26 #include <Prs3d_Root.hxx>
27 #include <Prs3d_ShadingAspect.hxx>
28 #include <Prs3d_ToolDisk.hxx>
29 #include <Prs3d_ToolSphere.hxx>
30 #include <Select3D_SensitiveCircle.hxx>
31 #include <Select3D_SensitivePoint.hxx>
32 #include <Select3D_SensitiveSegment.hxx>
33 #include <Select3D_SensitiveTriangulation.hxx>
34 #include <Select3D_SensitivePrimitiveArray.hxx>
35 #include <SelectMgr_SequenceOfOwner.hxx>
36 #include <TColgp_Array1OfPnt.hxx>
37 #include <V3d_View.hxx>
39 IMPLEMENT_STANDARD_HANDLE (AIS_Manipulator, AIS_InteractiveObject)
40 IMPLEMENT_STANDARD_RTTIEXT(AIS_Manipulator, AIS_InteractiveObject)
42 IMPLEMENT_HSEQUENCE(AIS_ManipulatorObjectSequence)
46 //! Return Ax1 for specified direction of Ax2.
47 static gp_Ax1 getAx1FromAx2Dir (const gp_Ax2& theAx2,
52 case 0: return gp_Ax1 (theAx2.Location(), theAx2.XDirection());
53 case 1: return gp_Ax1 (theAx2.Location(), theAx2.YDirection());
54 case 2: return theAx2.Axis();
56 throw Standard_ProgramError ("AIS_Manipulator - Invalid axis index");
60 //=======================================================================
63 //=======================================================================
64 void AIS_Manipulator::init()
66 // Create axis in the default coordinate system. The custom position is applied in local transformation.
67 myAxes[0] = Axis (gp::OX(), Quantity_NOC_RED);
68 myAxes[1] = Axis (gp::OY(), Quantity_NOC_GREEN);
69 myAxes[2] = Axis (gp::OZ(), Quantity_NOC_BLUE1);
71 Graphic3d_MaterialAspect aShadingMaterial;
72 aShadingMaterial.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
73 aShadingMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
75 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
76 myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
77 myDrawer->ShadingAspect()->SetColor (Quantity_NOC_WHITE);
78 myDrawer->ShadingAspect()->SetMaterial (aShadingMaterial);
80 Graphic3d_MaterialAspect aHilightMaterial;
81 aHilightMaterial.SetColor (Quantity_NOC_AZURE);
82 aHilightMaterial.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
83 aHilightMaterial.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
84 aHilightMaterial.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
85 aHilightMaterial.SetReflectionModeOff (Graphic3d_TOR_EMISSION);
86 aHilightMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
88 myHighlightAspect = new Prs3d_ShadingAspect();
89 myHighlightAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
90 myHighlightAspect->SetMaterial (aHilightMaterial);
93 SetZLayer (Graphic3d_ZLayerId_Topmost);
96 //=======================================================================
97 //function : getHighlightPresentation
99 //=======================================================================
100 Handle(Prs3d_Presentation) AIS_Manipulator::getHighlightPresentation (const Handle(SelectMgr_EntityOwner)& theOwner) const
102 Handle(Prs3d_Presentation) aDummyPrs;
103 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theOwner);
104 if (anOwner.IsNull())
109 switch (anOwner->Mode())
111 case AIS_MM_Translation: return myAxes[anOwner->Index()].TranslatorHighlightPrs();
112 case AIS_MM_Rotation : return myAxes[anOwner->Index()].RotatorHighlightPrs();
113 case AIS_MM_Scaling : return myAxes[anOwner->Index()].ScalerHighlightPrs();
114 case AIS_MM_None : break;
120 //=======================================================================
121 //function : getGroup
123 //=======================================================================
124 Handle(Graphic3d_Group) AIS_Manipulator::getGroup (const Standard_Integer theIndex, const AIS_ManipulatorMode theMode) const
126 Handle(Graphic3d_Group) aDummyGroup;
128 if (theIndex < 0 || theIndex > 2)
135 case AIS_MM_Translation: return myAxes[theIndex].TranslatorGroup();
136 case AIS_MM_Rotation : return myAxes[theIndex].RotatorGroup();
137 case AIS_MM_Scaling : return myAxes[theIndex].ScalerGroup();
138 case AIS_MM_None : break;
144 //=======================================================================
145 //function : Constructor
147 //=======================================================================
148 AIS_Manipulator::AIS_Manipulator()
149 : myPosition (gp::XOY()),
151 myCurrentMode (AIS_MM_None),
152 myIsActivationOnDetection (Standard_False),
153 myIsZoomPersistentMode (Standard_True),
154 myHasStartedTransformation (Standard_False),
155 myStartPosition (gp::XOY()),
156 myStartPick (0.0, 0.0, 0.0),
160 SetMutable (Standard_True);
161 SetDisplayMode (AIS_Shaded);
165 //=======================================================================
166 //function : Constructor
168 //=======================================================================
169 AIS_Manipulator::AIS_Manipulator (const gp_Ax2& thePosition)
170 : myPosition (thePosition),
172 myCurrentMode (AIS_MM_None),
173 myIsActivationOnDetection (Standard_False),
174 myIsZoomPersistentMode (Standard_True),
175 myHasStartedTransformation (Standard_False),
176 myStartPosition (gp::XOY()),
177 myStartPick (0.0, 0.0, 0.0),
181 SetMutable (Standard_True);
182 SetDisplayMode (AIS_Shaded);
186 //=======================================================================
189 //=======================================================================
190 void AIS_Manipulator::SetPart (const Standard_Integer theAxisIndex, const AIS_ManipulatorMode theMode, const Standard_Boolean theIsEnabled)
192 Standard_ProgramError_Raise_if (theAxisIndex < 0 || theAxisIndex > 2, "AIS_Manipulator::SetMode(): axis index should be between 0 and 2");
195 case AIS_MM_Translation:
196 myAxes[theAxisIndex].SetTranslation (theIsEnabled);
199 case AIS_MM_Rotation:
200 myAxes[theAxisIndex].SetRotation (theIsEnabled);
204 myAxes[theAxisIndex].SetScaling (theIsEnabled);
212 //=======================================================================
213 //function : EnableMode
215 //=======================================================================
216 void AIS_Manipulator::EnableMode (const AIS_ManipulatorMode theMode)
223 const Handle(AIS_InteractiveContext)& aContext = GetContext();
224 if (aContext.IsNull())
229 aContext->Activate (this, theMode);
232 //=======================================================================
233 //function : attachToBox
235 //=======================================================================
236 void AIS_Manipulator::attachToBox (const Bnd_Box& theBox)
243 Standard_Real anXmin = 0.0, anYmin = 0.0, aZmin = 0.0, anXmax = 0.0, anYmax = 0.0, aZmax = 0.0;
244 theBox.Get (anXmin, anYmin, aZmin, anXmax, anYmax, aZmax);
246 gp_Ax2 aPosition = gp::XOY();
247 aPosition.SetLocation (gp_Pnt ((anXmin + anXmax) * 0.5, (anYmin + anYmax) * 0.5, (aZmin + aZmax) * 0.5));
248 SetPosition (aPosition);
251 //=======================================================================
252 //function : adjustSize
254 //=======================================================================
255 void AIS_Manipulator::adjustSize (const Bnd_Box& theBox)
257 Standard_Real aXmin = 0., aYmin = 0., aZmin = 0., aXmax = 0., aYmax = 0., aZmax = 0.0;
258 theBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
259 Standard_Real aXSize = aXmax - aXmin;
260 Standard_Real aYSize = aYmax - aYmin;
261 Standard_Real aZSize = aZmax - aZmin;
263 SetSize ((Standard_ShortReal) (Max (aXSize, Max (aYSize, aZSize)) * 0.5));
266 //=======================================================================
269 //=======================================================================
270 void AIS_Manipulator::Attach (const Handle(AIS_InteractiveObject)& theObject, const OptionsForAttach& theOptions)
272 if (theObject->IsKind (STANDARD_TYPE(AIS_Manipulator)))
277 Handle(AIS_ManipulatorObjectSequence) aSeq = new AIS_ManipulatorObjectSequence();
278 aSeq->Append (theObject);
279 Attach (aSeq, theOptions);
282 //=======================================================================
285 //=======================================================================
286 void AIS_Manipulator::Attach (const Handle(AIS_ManipulatorObjectSequence)& theObjects, const OptionsForAttach& theOptions)
288 if (theObjects->Size() < 1)
293 SetOwner (theObjects);
295 const Handle(AIS_InteractiveObject)& aCurObject = theObjects->Value (theObjects->Lower());
296 aCurObject->BoundingBox (aBox);
298 if (theOptions.AdjustPosition)
303 if (theOptions.AdjustSize)
308 const Handle(AIS_InteractiveContext)& aContext = Object()->GetContext();
309 if (!aContext.IsNull())
311 if (!aContext->IsDisplayed (this))
313 aContext->Display (this, Standard_False);
317 aContext->Update (this, Standard_False);
318 aContext->RecomputeSelectionOnly (this);
321 aContext->Load (this);
324 if (theOptions.EnableModes)
326 EnableMode (AIS_MM_Rotation);
327 EnableMode (AIS_MM_Translation);
328 EnableMode (AIS_MM_Scaling);
332 //=======================================================================
335 //=======================================================================
336 void AIS_Manipulator::Detach()
338 DeactivateCurrentMode();
345 Handle(AIS_InteractiveObject) anObject = Object();
346 const Handle(AIS_InteractiveContext)& aContext = anObject->GetContext();
347 if (!aContext.IsNull())
349 aContext->Remove (this, Standard_False);
355 //=======================================================================
358 //=======================================================================
359 Handle(AIS_ManipulatorObjectSequence) AIS_Manipulator::Objects() const
361 return Handle(AIS_ManipulatorObjectSequence)::DownCast (GetOwner());
364 //=======================================================================
367 //=======================================================================
368 Handle(AIS_InteractiveObject) AIS_Manipulator::Object (const Standard_Integer theIndex) const
370 Handle(AIS_ManipulatorObjectSequence) anOwner = Handle(AIS_ManipulatorObjectSequence)::DownCast (GetOwner());
372 Standard_ProgramError_Raise_if (theIndex < anOwner->Lower() || theIndex > anOwner->Upper(), "AIS_Manipulator::Object(): wrong index value");
374 if (anOwner.IsNull() || anOwner->IsEmpty())
379 return anOwner->Value (theIndex);
382 //=======================================================================
385 //=======================================================================
386 Handle(AIS_InteractiveObject) AIS_Manipulator::Object() const
391 //=======================================================================
392 //function : ObjectTransformation
394 //=======================================================================
395 Standard_Boolean AIS_Manipulator::ObjectTransformation (const Standard_Integer theMaxX, const Standard_Integer theMaxY,
396 const Handle(V3d_View)& theView, gp_Trsf& theTrsf)
398 // Initialize start reference data
399 if (!myHasStartedTransformation)
401 myStartTrsfs.Clear();
402 Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
403 for (AIS_ManipulatorObjectSequence::Iterator anObjIter (*anObjects); anObjIter.More(); anObjIter.Next())
405 myStartTrsfs.Append (anObjIter.Value()->LocalTransformation());
407 myStartPosition = myPosition;
410 // Get 3d point with projection vector
411 Graphic3d_Vec3d anInputPoint, aProj;
412 theView->ConvertWithProj (theMaxX, theMaxY, anInputPoint.x(), anInputPoint.y(), anInputPoint.z(), aProj.x(), aProj.y(), aProj.z());
413 const gp_Lin anInputLine (gp_Pnt (anInputPoint.x(), anInputPoint.y(), anInputPoint.z()), gp_Dir (aProj.x(), aProj.y(), aProj.z()));
414 switch (myCurrentMode)
416 case AIS_MM_Translation:
419 const gp_Lin aLine (myStartPosition.Location(), myAxes[myCurrentIndex].Position().Direction());
420 Extrema_ExtElC anExtrema (anInputLine, aLine, Precision::Angular());
421 if (!anExtrema.IsDone()
422 || anExtrema.NbExt() != 1)
424 // translation cannot be done co-directed with camera
425 return Standard_False;
428 Extrema_POnCurv anExPnts[2];
429 anExtrema.Points (1, anExPnts[0], anExPnts[1]);
430 const gp_Pnt aNewPosition = anExPnts[1].Value();
431 if (!myHasStartedTransformation)
433 myStartPick = aNewPosition;
434 myHasStartedTransformation = Standard_True;
435 return Standard_True;
437 else if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
439 return Standard_False;
443 if (myCurrentMode == AIS_MM_Translation)
445 aNewTrsf.SetTranslation (gp_Vec(myStartPick, aNewPosition));
448 else if (myCurrentMode == AIS_MM_Scaling)
450 if (aNewPosition.Distance (myStartPosition.Location()) < Precision::Confusion())
452 return Standard_False;
455 Standard_Real aCoeff = myStartPosition.Location().Distance (aNewPosition)
456 / myStartPosition.Location().Distance (myStartPick);
457 aNewTrsf.SetScale (myPosition.Location(), aCoeff);
460 return Standard_True;
462 case AIS_MM_Rotation:
464 const gp_Pnt aPosLoc = myStartPosition.Location();
465 const gp_Ax1 aCurrAxis = getAx1FromAx2Dir (myStartPosition, myCurrentIndex);
466 IntAna_IntConicQuad aIntersector (anInputLine, gp_Pln (aPosLoc, aCurrAxis.Direction()), Precision::Angular(), Precision::Intersection());
467 if (!aIntersector.IsDone() || aIntersector.NbPoints() < 1)
469 return Standard_False;
472 const gp_Pnt aNewPosition = aIntersector.Point (1);
473 if (!myHasStartedTransformation)
475 myStartPick = aNewPosition;
476 myHasStartedTransformation = Standard_True;
477 gp_Dir aStartAxis = gce_MakeDir (aPosLoc, myStartPick);
478 myPrevState = aStartAxis.AngleWithRef (gce_MakeDir(aPosLoc, aNewPosition), aCurrAxis.Direction());
479 return Standard_True;
482 if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
484 return Standard_False;
487 gp_Dir aStartAxis = aPosLoc.IsEqual (myStartPick, Precision::Confusion())
488 ? getAx1FromAx2Dir (myStartPosition, (myCurrentIndex + 1) % 3).Direction()
489 : gce_MakeDir (aPosLoc, myStartPick);
491 gp_Dir aCurrentAxis = gce_MakeDir (aPosLoc, aNewPosition);
492 Standard_Real anAngle = aStartAxis.AngleWithRef (aCurrentAxis, aCurrAxis.Direction());
494 // Change value of an angle if it should have different sign.
495 if (anAngle * myPrevState < 0 && Abs (anAngle) < M_PI_2)
497 Standard_Real aSign = myPrevState > 0 ? -1.0 : 1.0;
498 anAngle = aSign * (M_PI * 2 - anAngle);
501 if (Abs (anAngle) < Precision::Confusion())
503 return Standard_False;
507 aNewTrsf.SetRotation (aCurrAxis, anAngle);
509 myPrevState = anAngle;
510 return Standard_True;
514 return Standard_False;
517 return Standard_False;
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;
552 Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
553 AIS_ManipulatorObjectSequence::Iterator anObjIter (*anObjects);
554 NCollection_Sequence<gp_Trsf>::Iterator aTrsfIter (myStartTrsfs);
555 for (; anObjIter.More(); anObjIter.Next(), aTrsfIter.Next())
557 anObjIter.ChangeValue()->SetLocalTransformation (aTrsfIter.Value());
559 SetPosition (myStartPosition);
562 //=======================================================================
563 //function : Transform
565 //=======================================================================
566 void AIS_Manipulator::Transform (const gp_Trsf& theTrsf)
568 if (!IsAttached() || !myHasStartedTransformation)
574 Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
575 AIS_ManipulatorObjectSequence::Iterator anObjIter (*anObjects);
576 NCollection_Sequence<gp_Trsf>::Iterator aTrsfIter (myStartTrsfs);
577 for (; anObjIter.More(); anObjIter.Next(), aTrsfIter.Next())
579 anObjIter.ChangeValue()->SetLocalTransformation (theTrsf * aTrsfIter.Value());
583 if ((myCurrentMode == AIS_MM_Translation && myBehaviorOnTransform.FollowTranslation)
584 || (myCurrentMode == AIS_MM_Rotation && myBehaviorOnTransform.FollowRotation))
586 gp_Pnt aPos = myStartPosition.Location().Transformed (theTrsf);
587 gp_Dir aVDir = myStartPosition.Direction().Transformed (theTrsf);
588 gp_Dir aXDir = myStartPosition.XDirection().Transformed (theTrsf);
589 SetPosition (gp_Ax2 (aPos, aVDir, aXDir));
593 //=======================================================================
594 //function : Transform
596 //=======================================================================
597 gp_Trsf AIS_Manipulator::Transform (const Standard_Integer thePX, const Standard_Integer thePY,
598 const Handle(V3d_View)& theView)
601 if (ObjectTransformation (thePX, thePY, theView, aTrsf))
609 //=======================================================================
610 //function : SetPosition
612 //=======================================================================
613 void AIS_Manipulator::SetPosition (const gp_Ax2& thePosition)
615 if (!myPosition.Location().IsEqual (thePosition.Location(), Precision::Confusion())
616 || !myPosition.Direction().IsEqual (thePosition.Direction(), Precision::Angular())
617 || !myPosition.XDirection().IsEqual (thePosition.XDirection(), Precision::Angular()))
619 myPosition = thePosition;
620 myAxes[0].SetPosition (getAx1FromAx2Dir (thePosition, 0));
621 myAxes[1].SetPosition (getAx1FromAx2Dir (thePosition, 1));
622 myAxes[2].SetPosition (getAx1FromAx2Dir (thePosition, 2));
623 updateTransformation();
627 //=======================================================================
628 //function : updateTransformation
629 //purpose : set local transformation to avoid graphics recomputation
630 //=======================================================================
631 void AIS_Manipulator::updateTransformation()
635 if (!myIsZoomPersistentMode)
637 aTrsf.SetTransformation (myPosition, gp::XOY());
641 const gp_Dir& aVDir = myPosition.Direction();
642 const gp_Dir& aXDir = myPosition.XDirection();
643 aTrsf.SetTransformation (gp_Ax2 (gp::Origin(), aVDir, aXDir), gp::XOY());
646 Handle(Geom_Transformation) aGeomTrsf = new Geom_Transformation (aTrsf);
647 // we explicitly call here setLocalTransformation() of the base class
648 // since AIS_Manipulator::setLocalTransformation() implementation throws exception
649 // as protection from external calls
650 AIS_InteractiveObject::setLocalTransformation (aGeomTrsf);
651 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
653 myAxes[anIt].Transform (aGeomTrsf);
656 if (myIsZoomPersistentMode)
658 if (TransformPersistence().IsNull()
659 || TransformPersistence()->Mode() != Graphic3d_TMF_ZoomPers
660 || !TransformPersistence()->AnchorPoint().IsEqual (myPosition.Location(), 0.0))
662 setTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, myPosition.Location()));
667 //=======================================================================
670 //=======================================================================
671 void AIS_Manipulator::SetSize (const Standard_ShortReal theSideLength)
673 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
675 myAxes[anIt].SetSize (theSideLength);
681 //=======================================================================
684 //=======================================================================
685 void AIS_Manipulator::SetGap (const Standard_ShortReal theValue)
687 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
689 myAxes[anIt].SetIndent (theValue);
695 //=======================================================================
696 //function : DeactivateCurrentMode
698 //=======================================================================
699 void AIS_Manipulator::DeactivateCurrentMode()
701 if (!myIsActivationOnDetection)
703 Handle(Graphic3d_Group) aGroup = getGroup (myCurrentIndex, myCurrentMode);
709 Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
710 anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
711 anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
712 anAspect->SetTransparency (myDrawer->ShadingAspect()->Transparency());
713 anAspect->SetColor (myAxes[myCurrentIndex].Color());
715 aGroup->SetGroupPrimitivesAspect (anAspect->Aspect());
719 myCurrentMode = AIS_MM_None;
721 if (myHasStartedTransformation)
723 myHasStartedTransformation = Standard_False;
727 //=======================================================================
728 //function : SetZoomPersistence
730 //=======================================================================
731 void AIS_Manipulator::SetZoomPersistence (const Standard_Boolean theToEnable)
733 if (myIsZoomPersistentMode != theToEnable)
738 myIsZoomPersistentMode = theToEnable;
742 setTransformPersistence (Handle(Graphic3d_TransformPers)());
745 updateTransformation();
748 //=======================================================================
749 //function : SetTransformPersistence
751 //=======================================================================
752 void AIS_Manipulator::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
754 Standard_ASSERT_RETURN (!myIsZoomPersistentMode,
755 "AIS_Manipulator::SetTransformPersistence: "
756 "Custom settings are not allowed by this class in ZoomPersistence mode",);
758 setTransformPersistence (theTrsfPers);
761 //=======================================================================
762 //function : setTransformPersistence
764 //=======================================================================
765 void AIS_Manipulator::setTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
767 AIS_InteractiveObject::SetTransformPersistence (theTrsfPers);
769 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
771 myAxes[anIt].SetTransformPersistence (theTrsfPers);
775 //=======================================================================
776 //function : setLocalTransformation
778 //=======================================================================
779 void AIS_Manipulator::setLocalTransformation (const Handle(Geom_Transformation)& /*theTrsf*/)
781 Standard_ASSERT_INVOKE ("AIS_Manipulator::setLocalTransformation: "
782 "Custom transformation is not supported by this class");
785 //=======================================================================
788 //=======================================================================
789 void AIS_Manipulator::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
790 const Handle(Prs3d_Presentation)& thePrs,
791 const Standard_Integer theMode)
793 if (theMode != AIS_Shaded)
798 thePrs->SetInfiniteState (Standard_True);
799 thePrs->SetMutable (Standard_True);
800 Handle(Graphic3d_Group) aGroup;
801 Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
802 anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
803 anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
804 anAspect->SetTransparency (myDrawer->ShadingAspect()->Transparency());
807 myCenter.Init (myAxes[0].AxisRadius() * 2.0f, gp::Origin());
808 aGroup = Prs3d_Root::NewGroup (thePrs);
809 aGroup->SetPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
810 aGroup->AddPrimitiveArray (myCenter.Array());
812 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
815 aGroup = Prs3d_Root::NewGroup (thePrs);
817 Handle(Prs3d_ShadingAspect) anAspectAx = new Prs3d_ShadingAspect (new Graphic3d_AspectFillArea3d(*anAspect->Aspect()));
818 anAspectAx->SetColor (myAxes[anIt].Color());
819 aGroup->SetGroupPrimitivesAspect (anAspectAx->Aspect());
820 myAxes[anIt].Compute (thePrsMgr, thePrs, anAspectAx);
821 myAxes[anIt].SetTransformPersistence (TransformPersistence());
824 updateTransformation();
827 //=======================================================================
828 //function : HilightSelected
830 //=======================================================================
831 void AIS_Manipulator::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
832 const SelectMgr_SequenceOfOwner& theSeq)
834 if (theSeq.IsEmpty())
839 if (myIsActivationOnDetection)
844 if (!theSeq (1)->IsKind (STANDARD_TYPE (AIS_ManipulatorOwner)))
846 thePM->Color (this, GetContext()->HighlightStyle(), 0);
850 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theSeq (1));
851 myHighlightAspect->Aspect()->SetInteriorColor (GetContext()->HighlightStyle()->Color());
852 Handle(Graphic3d_Group) aGroup = getGroup (anOwner->Index(), anOwner->Mode());
858 aGroup->SetGroupPrimitivesAspect (myHighlightAspect->Aspect());
860 myCurrentIndex = anOwner->Index();
861 myCurrentMode = anOwner->Mode();
864 //=======================================================================
865 //function : ClearSelected
867 //=======================================================================
868 void AIS_Manipulator::ClearSelected()
870 DeactivateCurrentMode();
873 //=======================================================================
874 //function : HilightOwnerWithColor
876 //=======================================================================
877 void AIS_Manipulator::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM,
878 const Handle(Prs3d_Drawer)& theStyle,
879 const Handle(SelectMgr_EntityOwner)& theOwner)
881 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theOwner);
882 Handle(Prs3d_Presentation) aPresentation = getHighlightPresentation (anOwner);
883 if (aPresentation.IsNull())
887 aPresentation->Highlight (theStyle);
888 for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPresentation->Groups());
889 aGroupIter.More(); aGroupIter.Next())
891 Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
893 && aGrp->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
895 aGrp->SetGroupPrimitivesAspect (myHighlightAspect->Aspect());
898 aPresentation->SetZLayer (Graphic3d_ZLayerId_Topmost);
899 thePM->AddToImmediateList (aPresentation);
901 if (myIsActivationOnDetection)
905 DeactivateCurrentMode();
908 myCurrentIndex = anOwner->Index();
909 myCurrentMode = anOwner->Mode();
913 //=======================================================================
914 //function : ComputeSelection
916 //=======================================================================
917 void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
918 const Standard_Integer theMode)
921 AIS_ManipulatorMode aMode = (AIS_ManipulatorMode) theMode;
922 if (aMode == AIS_MM_None)
926 Handle(SelectMgr_EntityOwner) anOwner;
927 if (aMode == AIS_MM_None)
929 anOwner = new SelectMgr_EntityOwner (this, 5);
932 if (aMode == AIS_MM_Translation || aMode == AIS_MM_None)
934 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
936 const Axis& anAxis = myAxes[anIt];
937 if (aMode != AIS_MM_None)
939 anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_Translation, 9);
941 // define sensitivity by line
942 Handle(Select3D_SensitiveSegment) aLine = new Select3D_SensitiveSegment (anOwner, gp::Origin(), anAxis.TranslatorTipPosition());
943 aLine->SetSensitivityFactor (15);
944 theSelection->Add (aLine);
946 // enlarge sensitivity by triangulation
947 Handle(Select3D_SensitivePrimitiveArray) aTri = new Select3D_SensitivePrimitiveArray (anOwner);
948 aTri->InitTriangulation (anAxis.TriangleArray()->Attributes(), anAxis.TriangleArray()->Indices(), TopLoc_Location());
949 theSelection->Add (aTri);
953 if (aMode == AIS_MM_Rotation || aMode == AIS_MM_None)
955 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
957 const Axis& anAxis = myAxes[anIt];
958 if (aMode != AIS_MM_None)
960 anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Rotation, 9);
962 // define sensitivity by circle
963 Handle(Geom_Circle) aGeomCircle = new Geom_Circle (gp_Ax2 (gp::Origin(), anAxis.ReferenceAxis().Direction()), anAxis.RotatorDiskRadius());
964 Handle(Select3D_SensitiveCircle) aCircle = new Select3D_SensitiveCircle (anOwner, aGeomCircle, Standard_False, anAxis.FacettesNumber());
965 aCircle->SetSensitivityFactor (15);
966 theSelection->Add (aCircle);
967 // enlarge sensitivity by triangulation
968 Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation (anOwner, myAxes[anIt].RotatorDisk().Triangulation(), TopLoc_Location(), Standard_True);
969 theSelection->Add (aTri);
973 if (aMode == AIS_MM_Scaling || aMode == AIS_MM_None)
975 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
977 if (aMode != AIS_MM_None)
979 anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Scaling, 9);
981 // define sensitivity by point
982 Handle(Select3D_SensitivePoint) aPnt = new Select3D_SensitivePoint (anOwner, myAxes[anIt].ScalerCubePosition());
983 aPnt->SetSensitivityFactor (15);
984 theSelection->Add (aPnt);
985 // enlarge sensitivity by triangulation
986 Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation (anOwner, myAxes[anIt].ScalerCube().Triangulation(), TopLoc_Location(), Standard_True);
987 theSelection->Add (aTri);
992 //=======================================================================
996 //=======================================================================
997 void AIS_Manipulator::Disk::Init (const Standard_ShortReal theInnerRadius,
998 const Standard_ShortReal theOuterRadius,
999 const gp_Ax1& thePosition,
1000 const Standard_Integer theSlicesNb,
1001 const Standard_Integer theStacksNb)
1003 myPosition = thePosition;
1004 myInnerRad = theInnerRadius;
1005 myOuterRad = theOuterRadius;
1007 Prs3d_ToolDisk aTool (theInnerRadius, theOuterRadius, theSlicesNb, theStacksNb);
1008 gp_Ax3 aSystem (myPosition.Location(), myPosition.Direction());
1010 aTrsf.SetTransformation (aSystem, gp_Ax3());
1011 aTool.FillArray (myArray, myTriangulation, aTrsf);
1014 //=======================================================================
1018 //=======================================================================
1019 void AIS_Manipulator::Sphere::Init (const Standard_ShortReal theRadius,
1020 const gp_Pnt& thePosition,
1021 const Standard_Integer theSlicesNb,
1022 const Standard_Integer theStacksNb)
1024 myPosition = thePosition;
1025 myRadius = theRadius;
1027 Prs3d_ToolSphere aTool (theRadius, theSlicesNb, theStacksNb);
1029 aTrsf.SetTranslation (gp_Vec(gp::Origin(), thePosition));
1030 aTool.FillArray (myArray, myTriangulation, aTrsf);
1033 //=======================================================================
1037 //=======================================================================
1038 void AIS_Manipulator::Cube::Init (const gp_Ax1& thePosition, const Standard_ShortReal theSize)
1040 myArray = new Graphic3d_ArrayOfTriangles (12 * 3, 0, Standard_True);
1042 Poly_Array1OfTriangle aPolyTriangles (1, 12);
1043 TColgp_Array1OfPnt aPoints (1, 36);
1044 NCollection_Array1<gp_Dir> aNormals (1, 12);
1045 myTriangulation = new Poly_Triangulation (aPoints, aPolyTriangles);
1047 gp_Ax2 aPln (thePosition.Location(), thePosition.Direction());
1048 gp_Pnt aBottomLeft = thePosition.Location().XYZ() - aPln.XDirection().XYZ() * theSize * 0.5 - aPln.YDirection().XYZ() * theSize * 0.5;
1049 gp_Pnt aV2 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize;
1050 gp_Pnt aV3 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize + aPln.XDirection().XYZ() * theSize;
1051 gp_Pnt aV4 = aBottomLeft.XYZ() + aPln.XDirection().XYZ() * theSize;
1052 gp_Pnt aTopRight = thePosition.Location().XYZ() + thePosition.Direction().XYZ() * theSize
1053 + aPln.XDirection().XYZ() * theSize * 0.5 + aPln.YDirection().XYZ() * theSize * 0.5;
1054 gp_Pnt aV5 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize;
1055 gp_Pnt aV6 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize - aPln.XDirection().XYZ() * theSize;
1056 gp_Pnt aV7 = aTopRight.XYZ() - aPln.XDirection().XYZ() * theSize;
1058 gp_Dir aRight ((gp_Vec(aTopRight, aV7) ^ gp_Vec(aTopRight, aV2)).XYZ());
1059 gp_Dir aFront ((gp_Vec(aV3, aV4) ^ gp_Vec(aV3, aV5)).XYZ());
1062 addTriangle (0, aBottomLeft, aV2, aV3, -thePosition.Direction());
1063 addTriangle (1, aBottomLeft, aV3, aV4, -thePosition.Direction());
1066 addTriangle (2, aV3, aV4, aV5, aFront);
1067 addTriangle (3, aV3, aV5, aTopRight, aFront);
1070 addTriangle (4, aBottomLeft, aV2, aV7, -aFront);
1071 addTriangle (5, aBottomLeft, aV7, aV6, -aFront);
1074 addTriangle (6, aV7, aV6, aV5, thePosition.Direction());
1075 addTriangle (7, aTopRight, aV7, aV5, thePosition.Direction());
1078 addTriangle (8, aV6, aV5, aV4, -aRight);
1079 addTriangle (9, aBottomLeft, aV6, aV4, -aRight);
1082 addTriangle (10, aV3, aTopRight, aV7, aRight);
1083 addTriangle (11, aV3, aV7, aV2, aRight);
1086 //=======================================================================
1088 //function : addTriangle
1090 //=======================================================================
1091 void AIS_Manipulator::Cube::addTriangle (const Standard_Integer theIndex,
1092 const gp_Pnt& theP1, const gp_Pnt& theP2, const gp_Pnt& theP3,
1093 const gp_Dir& theNormal)
1095 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 1, theP1);
1096 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 2, theP2);
1097 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 3, theP3);
1099 myTriangulation->ChangeTriangles().SetValue (theIndex + 1, Poly_Triangle (theIndex * 3 + 1, theIndex * 3 + 2, theIndex * 3 + 3));
1100 myArray->AddVertex (theP1, theNormal);
1101 myArray->AddVertex (theP2, theNormal);
1102 myArray->AddVertex (theP3, theNormal);
1105 //=======================================================================
1107 //function : Constructor
1109 //=======================================================================
1110 AIS_Manipulator::Axis::Axis (const gp_Ax1& theAxis,
1111 const Quantity_Color& theColor,
1112 const Standard_ShortReal theLength)
1113 : myReferenceAxis (theAxis),
1114 myPosition (theAxis),
1116 myHasTranslation (Standard_True),
1117 myLength (theLength),
1118 myAxisRadius (0.5f),
1119 myHasScaling (Standard_True),
1121 myHasRotation (Standard_True),
1122 myInnerRadius (myLength + myBoxSize),
1123 myDiskThickness (myBoxSize * 0.5f),
1125 myFacettesNumber (20),
1126 myCircleRadius (myLength + myBoxSize + myBoxSize * 0.5f * 0.5f)
1131 //=======================================================================
1133 //function : Compute
1135 //=======================================================================
1137 void AIS_Manipulator::Axis::Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
1138 const Handle(Prs3d_Presentation)& thePrs,
1139 const Handle(Prs3d_ShadingAspect)& theAspect)
1141 if (myHasTranslation)
1143 const Standard_Real anArrowLength = 0.25 * myLength;
1144 const Standard_Real aCylinderLength = myLength - anArrowLength;
1145 myArrowTipPos = gp_Pnt (0.0, 0.0, 0.0).Translated (myReferenceAxis.Direction().XYZ() * aCylinderLength);
1147 myTriangleArray = Prs3d_Arrow::DrawShaded (gp_Ax1(gp::Origin(), myReferenceAxis.Direction()),
1153 myTranslatorGroup = Prs3d_Root::NewGroup (thePrs);
1154 myTranslatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1155 myTranslatorGroup->AddPrimitiveArray (myTriangleArray);
1157 if (myHighlightTranslator.IsNull())
1159 myHighlightTranslator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1163 myHighlightTranslator->Clear();
1166 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightTranslator);
1167 aGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1168 aGroup->AddPrimitiveArray (myTriangleArray);
1174 myCubePos = myReferenceAxis.Direction().XYZ() * (myLength + myIndent);
1175 myCube.Init (gp_Ax1 (myCubePos, myReferenceAxis.Direction()), myBoxSize);
1177 myScalerGroup = Prs3d_Root::NewGroup (thePrs);
1178 myScalerGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1179 myScalerGroup->AddPrimitiveArray (myCube.Array());
1181 if (myHighlightScaler.IsNull())
1183 myHighlightScaler = new Prs3d_Presentation (thePrsMgr->StructureManager());
1187 myHighlightScaler->Clear();
1190 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightScaler);
1191 aGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1192 aGroup->AddPrimitiveArray (myCube.Array());
1198 myCircleRadius = myInnerRadius + myIndent * 2 + myDiskThickness * 0.5f;
1199 myCircle.Init (myInnerRadius + myIndent * 2, myInnerRadius + myDiskThickness + myIndent * 2, gp_Ax1(gp::Origin(), myReferenceAxis.Direction()), myFacettesNumber * 2);
1200 myRotatorGroup = Prs3d_Root::NewGroup (thePrs);
1201 myRotatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1202 myRotatorGroup->AddPrimitiveArray (myCircle.Array());
1204 if (myHighlightRotator.IsNull())
1206 myHighlightRotator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1210 myHighlightRotator->Clear();
1213 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightRotator);
1214 aGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1215 aGroup->AddPrimitiveArray (myCircle.Array());