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