0030477: Visualization - crash in AIS_Manipulator::ObjectTransformation after using...
[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()
5ac0f989 496 || anExtrema.IsParallel()
12280e4b 497 || anExtrema.NbExt() != 1)
498 {
499 // translation cannot be done co-directed with camera
500 return Standard_False;
501 }
625e1958 502
12280e4b 503 Extrema_POnCurv anExPnts[2];
504 anExtrema.Points (1, anExPnts[0], anExPnts[1]);
505 const gp_Pnt aNewPosition = anExPnts[1].Value();
625e1958 506 if (!myHasStartedTransformation)
507 {
508 myStartPick = aNewPosition;
509 myHasStartedTransformation = Standard_True;
510 return Standard_True;
511 }
12280e4b 512 else if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
625e1958 513 {
514 return Standard_False;
515 }
516
517 gp_Trsf aNewTrsf;
12280e4b 518 if (myCurrentMode == AIS_MM_Translation)
519 {
520 aNewTrsf.SetTranslation (gp_Vec(myStartPick, aNewPosition));
521 theTrsf *= aNewTrsf;
522 }
523 else if (myCurrentMode == AIS_MM_Scaling)
524 {
525 if (aNewPosition.Distance (myStartPosition.Location()) < Precision::Confusion())
526 {
527 return Standard_False;
528 }
529
530 Standard_Real aCoeff = myStartPosition.Location().Distance (aNewPosition)
531 / myStartPosition.Location().Distance (myStartPick);
532 aNewTrsf.SetScale (myPosition.Location(), aCoeff);
533 theTrsf = aNewTrsf;
534 }
3ed88fac 535 return Standard_True;
625e1958 536 }
537 case AIS_MM_Rotation:
538 {
3ed88fac 539 const gp_Pnt aPosLoc = myStartPosition.Location();
540 const gp_Ax1 aCurrAxis = getAx1FromAx2Dir (myStartPosition, myCurrentIndex);
12280e4b 541 IntAna_IntConicQuad aIntersector (anInputLine, gp_Pln (aPosLoc, aCurrAxis.Direction()), Precision::Angular(), Precision::Intersection());
5ac0f989 542 if (!aIntersector.IsDone()
543 || aIntersector.IsParallel()
544 || aIntersector.NbPoints() < 1)
625e1958 545 {
546 return Standard_False;
547 }
548
3ed88fac 549 const gp_Pnt aNewPosition = aIntersector.Point (1);
625e1958 550 if (!myHasStartedTransformation)
551 {
552 myStartPick = aNewPosition;
553 myHasStartedTransformation = Standard_True;
3ed88fac 554 gp_Dir aStartAxis = gce_MakeDir (aPosLoc, myStartPick);
555 myPrevState = aStartAxis.AngleWithRef (gce_MakeDir(aPosLoc, aNewPosition), aCurrAxis.Direction());
625e1958 556 return Standard_True;
557 }
558
559 if (aNewPosition.Distance (myStartPick) < Precision::Confusion())
560 {
561 return Standard_False;
562 }
563
3ed88fac 564 gp_Dir aStartAxis = aPosLoc.IsEqual (myStartPick, Precision::Confusion())
565 ? getAx1FromAx2Dir (myStartPosition, (myCurrentIndex + 1) % 3).Direction()
566 : gce_MakeDir (aPosLoc, myStartPick);
625e1958 567
3ed88fac 568 gp_Dir aCurrentAxis = gce_MakeDir (aPosLoc, aNewPosition);
569 Standard_Real anAngle = aStartAxis.AngleWithRef (aCurrentAxis, aCurrAxis.Direction());
625e1958 570
571 // Change value of an angle if it should have different sign.
572 if (anAngle * myPrevState < 0 && Abs (anAngle) < M_PI_2)
573 {
3ed88fac 574 Standard_Real aSign = myPrevState > 0 ? -1.0 : 1.0;
625e1958 575 anAngle = aSign * (M_PI * 2 - anAngle);
576 }
577
578 if (Abs (anAngle) < Precision::Confusion())
579 {
580 return Standard_False;
581 }
582
583 gp_Trsf aNewTrsf;
3ed88fac 584 aNewTrsf.SetRotation (aCurrAxis, anAngle);
625e1958 585 theTrsf *= aNewTrsf;
586 myPrevState = anAngle;
3ed88fac 587 return Standard_True;
625e1958 588 }
625e1958 589 case AIS_MM_None:
3ed88fac 590 {
625e1958 591 return Standard_False;
3ed88fac 592 }
625e1958 593 }
3ed88fac 594 return Standard_False;
625e1958 595}
596
597//=======================================================================
598//function : StartTransform
599//purpose :
600//=======================================================================
601void AIS_Manipulator::StartTransform (const Standard_Integer theX, const Standard_Integer theY, const Handle(V3d_View)& theView)
602{
603 if (myHasStartedTransformation)
604 {
605 return;
606 }
607
608 gp_Trsf aTrsf;
609 ObjectTransformation (theX, theY, theView, aTrsf);
610}
611
612//=======================================================================
613//function : StopTransform
614//purpose :
615//=======================================================================
616void AIS_Manipulator::StopTransform (const Standard_Boolean theToApply)
617{
618 if (!IsAttached() || !myHasStartedTransformation)
619 {
620 return;
621 }
622
623 myHasStartedTransformation = Standard_False;
3ed88fac 624 if (theToApply)
625e1958 625 {
3ed88fac 626 return;
627 }
625e1958 628
3ed88fac 629 Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
630 AIS_ManipulatorObjectSequence::Iterator anObjIter (*anObjects);
631 NCollection_Sequence<gp_Trsf>::Iterator aTrsfIter (myStartTrsfs);
632 for (; anObjIter.More(); anObjIter.Next(), aTrsfIter.Next())
633 {
634 anObjIter.ChangeValue()->SetLocalTransformation (aTrsfIter.Value());
625e1958 635 }
3ed88fac 636 SetPosition (myStartPosition);
625e1958 637}
638
639//=======================================================================
640//function : Transform
641//purpose :
642//=======================================================================
643void AIS_Manipulator::Transform (const gp_Trsf& theTrsf)
644{
645 if (!IsAttached() || !myHasStartedTransformation)
646 {
647 return;
648 }
649
625e1958 650 {
3ed88fac 651 Handle(AIS_ManipulatorObjectSequence) anObjects = Objects();
652 AIS_ManipulatorObjectSequence::Iterator anObjIter (*anObjects);
653 NCollection_Sequence<gp_Trsf>::Iterator aTrsfIter (myStartTrsfs);
654 for (; anObjIter.More(); anObjIter.Next(), aTrsfIter.Next())
655 {
656 anObjIter.ChangeValue()->SetLocalTransformation (theTrsf * aTrsfIter.Value());
657 }
625e1958 658 }
659
660 if ((myCurrentMode == AIS_MM_Translation && myBehaviorOnTransform.FollowTranslation)
661 || (myCurrentMode == AIS_MM_Rotation && myBehaviorOnTransform.FollowRotation))
662 {
663 gp_Pnt aPos = myStartPosition.Location().Transformed (theTrsf);
664 gp_Dir aVDir = myStartPosition.Direction().Transformed (theTrsf);
665 gp_Dir aXDir = myStartPosition.XDirection().Transformed (theTrsf);
666 SetPosition (gp_Ax2 (aPos, aVDir, aXDir));
667 }
668}
669
670//=======================================================================
671//function : Transform
672//purpose :
673//=======================================================================
674gp_Trsf AIS_Manipulator::Transform (const Standard_Integer thePX, const Standard_Integer thePY,
675 const Handle(V3d_View)& theView)
676{
677 gp_Trsf aTrsf;
678 if (ObjectTransformation (thePX, thePY, theView, aTrsf))
679 {
680 Transform (aTrsf);
681 }
682
683 return aTrsf;
684}
685
686//=======================================================================
687//function : SetPosition
688//purpose :
689//=======================================================================
690void AIS_Manipulator::SetPosition (const gp_Ax2& thePosition)
691{
692 if (!myPosition.Location().IsEqual (thePosition.Location(), Precision::Confusion())
693 || !myPosition.Direction().IsEqual (thePosition.Direction(), Precision::Angular())
694 || !myPosition.XDirection().IsEqual (thePosition.XDirection(), Precision::Angular()))
695 {
696 myPosition = thePosition;
3ed88fac 697 myAxes[0].SetPosition (getAx1FromAx2Dir (thePosition, 0));
698 myAxes[1].SetPosition (getAx1FromAx2Dir (thePosition, 1));
699 myAxes[2].SetPosition (getAx1FromAx2Dir (thePosition, 2));
625e1958 700 updateTransformation();
701 }
702}
703
704//=======================================================================
705//function : updateTransformation
706//purpose : set local transformation to avoid graphics recomputation
707//=======================================================================
708void AIS_Manipulator::updateTransformation()
709{
710 gp_Trsf aTrsf;
711
712 if (!myIsZoomPersistentMode)
713 {
714 aTrsf.SetTransformation (myPosition, gp::XOY());
715 }
716 else
717 {
718 const gp_Dir& aVDir = myPosition.Direction();
719 const gp_Dir& aXDir = myPosition.XDirection();
720 aTrsf.SetTransformation (gp_Ax2 (gp::Origin(), aVDir, aXDir), gp::XOY());
721 }
722
1f7f5a90 723 Handle(Geom_Transformation) aGeomTrsf = new Geom_Transformation (aTrsf);
724 // we explicitly call here setLocalTransformation() of the base class
725 // since AIS_Manipulator::setLocalTransformation() implementation throws exception
726 // as protection from external calls
727 AIS_InteractiveObject::setLocalTransformation (aGeomTrsf);
625e1958 728 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
729 {
730 myAxes[anIt].Transform (aGeomTrsf);
731 }
732
733 if (myIsZoomPersistentMode)
734 {
778cd667 735 if (TransformPersistence().IsNull()
736 || TransformPersistence()->Mode() != Graphic3d_TMF_ZoomPers
737 || !TransformPersistence()->AnchorPoint().IsEqual (myPosition.Location(), 0.0))
625e1958 738 {
778cd667 739 setTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, myPosition.Location()));
625e1958 740 }
741 }
742}
743
744//=======================================================================
745//function : SetSize
746//purpose :
747//=======================================================================
748void AIS_Manipulator::SetSize (const Standard_ShortReal theSideLength)
749{
750 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
751 {
752 myAxes[anIt].SetSize (theSideLength);
753 }
754
755 SetToUpdate();
756}
757
758//=======================================================================
759//function : SetGap
760//purpose :
761//=======================================================================
762void AIS_Manipulator::SetGap (const Standard_ShortReal theValue)
763{
764 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
765 {
766 myAxes[anIt].SetIndent (theValue);
767 }
768
769 SetToUpdate();
770}
771
772//=======================================================================
773//function : DeactivateCurrentMode
774//purpose :
775//=======================================================================
776void AIS_Manipulator::DeactivateCurrentMode()
777{
778 if (!myIsActivationOnDetection)
779 {
780 Handle(Graphic3d_Group) aGroup = getGroup (myCurrentIndex, myCurrentMode);
781 if (aGroup.IsNull())
782 {
783 return;
784 }
785
786 Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
787 anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
788 anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
789 anAspect->SetTransparency (myDrawer->ShadingAspect()->Transparency());
790 anAspect->SetColor (myAxes[myCurrentIndex].Color());
791
792 aGroup->SetGroupPrimitivesAspect (anAspect->Aspect());
793 }
794
795 myCurrentIndex = -1;
796 myCurrentMode = AIS_MM_None;
797
798 if (myHasStartedTransformation)
799 {
800 myHasStartedTransformation = Standard_False;
801 }
802}
803
804//=======================================================================
805//function : SetZoomPersistence
806//purpose :
807//=======================================================================
808void AIS_Manipulator::SetZoomPersistence (const Standard_Boolean theToEnable)
809{
810 if (myIsZoomPersistentMode != theToEnable)
811 {
812 SetToUpdate();
813 }
814
815 myIsZoomPersistentMode = theToEnable;
816
817 if (!theToEnable)
818 {
778cd667 819 setTransformPersistence (Handle(Graphic3d_TransformPers)());
625e1958 820 }
821
822 updateTransformation();
823}
824
825//=======================================================================
826//function : SetTransformPersistence
778cd667 827//purpose :
625e1958 828//=======================================================================
778cd667 829void AIS_Manipulator::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
625e1958 830{
831 Standard_ASSERT_RETURN (!myIsZoomPersistentMode,
832 "AIS_Manipulator::SetTransformPersistence: "
778cd667 833 "Custom settings are not allowed by this class in ZoomPersistence mode",);
625e1958 834
778cd667 835 setTransformPersistence (theTrsfPers);
625e1958 836}
837
838//=======================================================================
839//function : setTransformPersistence
840//purpose :
841//=======================================================================
778cd667 842void AIS_Manipulator::setTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
625e1958 843{
778cd667 844 AIS_InteractiveObject::SetTransformPersistence (theTrsfPers);
625e1958 845
846 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
847 {
778cd667 848 myAxes[anIt].SetTransformPersistence (theTrsfPers);
625e1958 849 }
850}
851
852//=======================================================================
1f7f5a90 853//function : setLocalTransformation
854//purpose :
625e1958 855//=======================================================================
1f7f5a90 856void AIS_Manipulator::setLocalTransformation (const Handle(Geom_Transformation)& /*theTrsf*/)
625e1958 857{
1f7f5a90 858 Standard_ASSERT_INVOKE ("AIS_Manipulator::setLocalTransformation: "
859 "Custom transformation is not supported by this class");
625e1958 860}
861
862//=======================================================================
863//function : Compute
864//purpose :
865//=======================================================================
866void AIS_Manipulator::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
867 const Handle(Prs3d_Presentation)& thePrs,
868 const Standard_Integer theMode)
869{
870 if (theMode != AIS_Shaded)
871 {
872 return;
873 }
874
875 thePrs->SetInfiniteState (Standard_True);
876 thePrs->SetMutable (Standard_True);
877 Handle(Graphic3d_Group) aGroup;
878 Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
879 anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
880 anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
881 anAspect->SetTransparency (myDrawer->ShadingAspect()->Transparency());
882
883 // Display center
884 myCenter.Init (myAxes[0].AxisRadius() * 2.0f, gp::Origin());
885 aGroup = Prs3d_Root::NewGroup (thePrs);
886 aGroup->SetPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
887 aGroup->AddPrimitiveArray (myCenter.Array());
888
889 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
890 {
891 // Display axes
892 aGroup = Prs3d_Root::NewGroup (thePrs);
b6472664 893
894 Handle(Prs3d_ShadingAspect) anAspectAx = new Prs3d_ShadingAspect (new Graphic3d_AspectFillArea3d(*anAspect->Aspect()));
895 anAspectAx->SetColor (myAxes[anIt].Color());
896 aGroup->SetGroupPrimitivesAspect (anAspectAx->Aspect());
897 myAxes[anIt].Compute (thePrsMgr, thePrs, anAspectAx);
778cd667 898 myAxes[anIt].SetTransformPersistence (TransformPersistence());
625e1958 899 }
900
901 updateTransformation();
902}
903
904//=======================================================================
905//function : HilightSelected
906//purpose :
907//=======================================================================
908void AIS_Manipulator::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
909 const SelectMgr_SequenceOfOwner& theSeq)
910{
911 if (theSeq.IsEmpty())
912 {
913 return;
914 }
915
916 if (myIsActivationOnDetection)
917 {
918 return;
919 }
920
921 if (!theSeq (1)->IsKind (STANDARD_TYPE (AIS_ManipulatorOwner)))
922 {
8e5fb5ea 923 thePM->Color (this, GetContext()->HighlightStyle(), 0);
625e1958 924 return;
925 }
926
927 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theSeq (1));
8e5fb5ea 928 myHighlightAspect->Aspect()->SetInteriorColor (GetContext()->HighlightStyle()->Color());
625e1958 929 Handle(Graphic3d_Group) aGroup = getGroup (anOwner->Index(), anOwner->Mode());
930 if (aGroup.IsNull())
931 {
932 return;
933 }
934
935 aGroup->SetGroupPrimitivesAspect (myHighlightAspect->Aspect());
936
937 myCurrentIndex = anOwner->Index();
938 myCurrentMode = anOwner->Mode();
939}
940
941//=======================================================================
942//function : ClearSelected
943//purpose :
944//=======================================================================
945void AIS_Manipulator::ClearSelected()
946{
947 DeactivateCurrentMode();
948}
949
950//=======================================================================
951//function : HilightOwnerWithColor
952//purpose :
953//=======================================================================
8e5fb5ea 954void AIS_Manipulator::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM,
f838dac4 955 const Handle(Prs3d_Drawer)& theStyle,
8e5fb5ea 956 const Handle(SelectMgr_EntityOwner)& theOwner)
625e1958 957{
958 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theOwner);
959 Handle(Prs3d_Presentation) aPresentation = getHighlightPresentation (anOwner);
960 if (aPresentation.IsNull())
961 {
962 return;
963 }
8e5fb5ea 964 aPresentation->Highlight (theStyle);
2831708b 965 for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPresentation->Groups());
966 aGroupIter.More(); aGroupIter.Next())
967 {
968 Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
969 if (!aGrp.IsNull()
970 && aGrp->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
971 {
972 aGrp->SetGroupPrimitivesAspect (myHighlightAspect->Aspect());
973 }
974 }
625e1958 975 aPresentation->SetZLayer (Graphic3d_ZLayerId_Topmost);
976 thePM->AddToImmediateList (aPresentation);
977
978 if (myIsActivationOnDetection)
979 {
980 if (HasActiveMode())
981 {
982 DeactivateCurrentMode();
983 }
984
985 myCurrentIndex = anOwner->Index();
986 myCurrentMode = anOwner->Mode();
987 }
988}
989
990//=======================================================================
991//function : ComputeSelection
992//purpose :
993//=======================================================================
994void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
995 const Standard_Integer theMode)
996{
997 //Check mode
998 AIS_ManipulatorMode aMode = (AIS_ManipulatorMode) theMode;
999 if (aMode == AIS_MM_None)
1000 {
1001 return;
1002 }
1003 Handle(SelectMgr_EntityOwner) anOwner;
1004 if (aMode == AIS_MM_None)
1005 {
1006 anOwner = new SelectMgr_EntityOwner (this, 5);
1007 }
62ef08df 1008
625e1958 1009 if (aMode == AIS_MM_Translation || aMode == AIS_MM_None)
1010 {
1011 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
1012 {
f15c5f90 1013 if (!myAxes[anIt].HasTranslation())
1014 {
1015 continue;
1016 }
625e1958 1017 const Axis& anAxis = myAxes[anIt];
1018 if (aMode != AIS_MM_None)
1019 {
f15c5f90 1020 anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Translation, 9);
625e1958 1021 }
1022 // define sensitivity by line
1023 Handle(Select3D_SensitiveSegment) aLine = new Select3D_SensitiveSegment (anOwner, gp::Origin(), anAxis.TranslatorTipPosition());
1024 aLine->SetSensitivityFactor (15);
1025 theSelection->Add (aLine);
62ef08df 1026
625e1958 1027 // enlarge sensitivity by triangulation
62ef08df 1028 Handle(Select3D_SensitivePrimitiveArray) aTri = new Select3D_SensitivePrimitiveArray (anOwner);
1029 aTri->InitTriangulation (anAxis.TriangleArray()->Attributes(), anAxis.TriangleArray()->Indices(), TopLoc_Location());
625e1958 1030 theSelection->Add (aTri);
1031 }
1032 }
1033
1034 if (aMode == AIS_MM_Rotation || aMode == AIS_MM_None)
1035 {
1036 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
1037 {
f15c5f90 1038 if (!myAxes[anIt].HasRotation())
1039 {
1040 continue;
1041 }
625e1958 1042 const Axis& anAxis = myAxes[anIt];
1043 if (aMode != AIS_MM_None)
1044 {
1045 anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Rotation, 9);
1046 }
1047 // define sensitivity by circle
1048 Handle(Geom_Circle) aGeomCircle = new Geom_Circle (gp_Ax2 (gp::Origin(), anAxis.ReferenceAxis().Direction()), anAxis.RotatorDiskRadius());
b11aef43 1049 Handle(Select3D_SensitiveCircle) aCircle = new ManipSensCircle (anOwner, aGeomCircle, anAxis.FacettesNumber());
625e1958 1050 aCircle->SetSensitivityFactor (15);
1051 theSelection->Add (aCircle);
1052 // enlarge sensitivity by triangulation
b11aef43 1053 Handle(Select3D_SensitiveTriangulation) aTri = new ManipSensTriangulation (anOwner, myAxes[anIt].RotatorDisk().Triangulation(), anAxis.ReferenceAxis().Direction());
625e1958 1054 theSelection->Add (aTri);
1055 }
1056 }
1057
1058 if (aMode == AIS_MM_Scaling || aMode == AIS_MM_None)
1059 {
1060 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
1061 {
f15c5f90 1062 if (!myAxes[anIt].HasScaling())
1063 {
1064 continue;
1065 }
625e1958 1066 if (aMode != AIS_MM_None)
1067 {
1068 anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Scaling, 9);
1069 }
1070 // define sensitivity by point
1071 Handle(Select3D_SensitivePoint) aPnt = new Select3D_SensitivePoint (anOwner, myAxes[anIt].ScalerCubePosition());
1072 aPnt->SetSensitivityFactor (15);
1073 theSelection->Add (aPnt);
1074 // enlarge sensitivity by triangulation
62ef08df 1075 Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation (anOwner, myAxes[anIt].ScalerCube().Triangulation(), TopLoc_Location(), Standard_True);
625e1958 1076 theSelection->Add (aTri);
1077 }
1078 }
1079}
1080
1081//=======================================================================
625e1958 1082//class : Disk
1083//function : Init
1084//purpose :
1085//=======================================================================
1086void AIS_Manipulator::Disk::Init (const Standard_ShortReal theInnerRadius,
1087 const Standard_ShortReal theOuterRadius,
1088 const gp_Ax1& thePosition,
1089 const Standard_Integer theSlicesNb,
1090 const Standard_Integer theStacksNb)
1091{
1092 myPosition = thePosition;
1093 myInnerRad = theInnerRadius;
1094 myOuterRad = theOuterRadius;
1095
62ef08df 1096 Prs3d_ToolDisk aTool (theInnerRadius, theOuterRadius, theSlicesNb, theStacksNb);
625e1958 1097 gp_Ax3 aSystem (myPosition.Location(), myPosition.Direction());
1098 gp_Trsf aTrsf;
1099 aTrsf.SetTransformation (aSystem, gp_Ax3());
1100 aTool.FillArray (myArray, myTriangulation, aTrsf);
1101}
1102
1103//=======================================================================
1104//class : Sphere
1105//function : Init
1106//purpose :
1107//=======================================================================
1108void AIS_Manipulator::Sphere::Init (const Standard_ShortReal theRadius,
1109 const gp_Pnt& thePosition,
1110 const Standard_Integer theSlicesNb,
1111 const Standard_Integer theStacksNb)
1112{
1113 myPosition = thePosition;
1114 myRadius = theRadius;
1115
62ef08df 1116 Prs3d_ToolSphere aTool (theRadius, theSlicesNb, theStacksNb);
625e1958 1117 gp_Trsf aTrsf;
1118 aTrsf.SetTranslation (gp_Vec(gp::Origin(), thePosition));
1119 aTool.FillArray (myArray, myTriangulation, aTrsf);
1120}
1121
1122//=======================================================================
1123//class : Cube
1124//function : Init
1125//purpose :
1126//=======================================================================
1127void AIS_Manipulator::Cube::Init (const gp_Ax1& thePosition, const Standard_ShortReal theSize)
1128{
1129 myArray = new Graphic3d_ArrayOfTriangles (12 * 3, 0, Standard_True);
1130
1131 Poly_Array1OfTriangle aPolyTriangles (1, 12);
1132 TColgp_Array1OfPnt aPoints (1, 36);
1133 NCollection_Array1<gp_Dir> aNormals (1, 12);
1134 myTriangulation = new Poly_Triangulation (aPoints, aPolyTriangles);
1135
1136 gp_Ax2 aPln (thePosition.Location(), thePosition.Direction());
1137 gp_Pnt aBottomLeft = thePosition.Location().XYZ() - aPln.XDirection().XYZ() * theSize * 0.5 - aPln.YDirection().XYZ() * theSize * 0.5;
1138 gp_Pnt aV2 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize;
1139 gp_Pnt aV3 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize + aPln.XDirection().XYZ() * theSize;
1140 gp_Pnt aV4 = aBottomLeft.XYZ() + aPln.XDirection().XYZ() * theSize;
1141 gp_Pnt aTopRight = thePosition.Location().XYZ() + thePosition.Direction().XYZ() * theSize
1142 + aPln.XDirection().XYZ() * theSize * 0.5 + aPln.YDirection().XYZ() * theSize * 0.5;
1143 gp_Pnt aV5 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize;
1144 gp_Pnt aV6 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize - aPln.XDirection().XYZ() * theSize;
1145 gp_Pnt aV7 = aTopRight.XYZ() - aPln.XDirection().XYZ() * theSize;
1146
1147 gp_Dir aRight ((gp_Vec(aTopRight, aV7) ^ gp_Vec(aTopRight, aV2)).XYZ());
1148 gp_Dir aFront ((gp_Vec(aV3, aV4) ^ gp_Vec(aV3, aV5)).XYZ());
1149
1150 // Bottom
1151 addTriangle (0, aBottomLeft, aV2, aV3, -thePosition.Direction());
1152 addTriangle (1, aBottomLeft, aV3, aV4, -thePosition.Direction());
1153
1154 // Front
1155 addTriangle (2, aV3, aV4, aV5, aFront);
1156 addTriangle (3, aV3, aV5, aTopRight, aFront);
1157
1158 // Back
1159 addTriangle (4, aBottomLeft, aV2, aV7, -aFront);
1160 addTriangle (5, aBottomLeft, aV7, aV6, -aFront);
1161
1162 // aTop
1163 addTriangle (6, aV7, aV6, aV5, thePosition.Direction());
1164 addTriangle (7, aTopRight, aV7, aV5, thePosition.Direction());
1165
1166 //Left
1167 addTriangle (8, aV6, aV5, aV4, -aRight);
1168 addTriangle (9, aBottomLeft, aV6, aV4, -aRight);
1169
1170 // Right
1171 addTriangle (10, aV3, aTopRight, aV7, aRight);
1172 addTriangle (11, aV3, aV7, aV2, aRight);
1173}
1174
1175//=======================================================================
1176//class : Cube
1177//function : addTriangle
1178//purpose :
1179//=======================================================================
1180void AIS_Manipulator::Cube::addTriangle (const Standard_Integer theIndex,
1181 const gp_Pnt& theP1, const gp_Pnt& theP2, const gp_Pnt& theP3,
1182 const gp_Dir& theNormal)
1183{
1184 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 1, theP1);
1185 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 2, theP2);
1186 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 3, theP3);
1187
1188 myTriangulation->ChangeTriangles().SetValue (theIndex + 1, Poly_Triangle (theIndex * 3 + 1, theIndex * 3 + 2, theIndex * 3 + 3));
1189 myArray->AddVertex (theP1, theNormal);
1190 myArray->AddVertex (theP2, theNormal);
1191 myArray->AddVertex (theP3, theNormal);
1192}
1193
1194//=======================================================================
1195//class : Axis
1196//function : Constructor
1197//purpose :
1198//=======================================================================
1199AIS_Manipulator::Axis::Axis (const gp_Ax1& theAxis,
1200 const Quantity_Color& theColor,
1201 const Standard_ShortReal theLength)
1202: myReferenceAxis (theAxis),
1203 myPosition (theAxis),
1204 myColor (theColor),
1205 myHasTranslation (Standard_True),
1206 myLength (theLength),
1207 myAxisRadius (0.5f),
1208 myHasScaling (Standard_True),
1209 myBoxSize (2.0f),
1210 myHasRotation (Standard_True),
1211 myInnerRadius (myLength + myBoxSize),
1212 myDiskThickness (myBoxSize * 0.5f),
1213 myIndent (0.2f),
1214 myFacettesNumber (20),
1215 myCircleRadius (myLength + myBoxSize + myBoxSize * 0.5f * 0.5f)
1216{
1217 //
1218}
1219
1220//=======================================================================
1221//class : Axis
1222//function : Compute
62ef08df 1223//purpose :
625e1958 1224//=======================================================================
62ef08df 1225
1226void AIS_Manipulator::Axis::Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
625e1958 1227 const Handle(Prs3d_Presentation)& thePrs,
1228 const Handle(Prs3d_ShadingAspect)& theAspect)
1229{
625e1958 1230 if (myHasTranslation)
1231 {
62ef08df 1232 const Standard_Real anArrowLength = 0.25 * myLength;
1233 const Standard_Real aCylinderLength = myLength - anArrowLength;
1234 myArrowTipPos = gp_Pnt (0.0, 0.0, 0.0).Translated (myReferenceAxis.Direction().XYZ() * aCylinderLength);
1235
1236 myTriangleArray = Prs3d_Arrow::DrawShaded (gp_Ax1(gp::Origin(), myReferenceAxis.Direction()),
1237 myAxisRadius,
1238 myLength,
1239 myAxisRadius * 1.5,
1240 anArrowLength,
1241 myFacettesNumber);
625e1958 1242 myTranslatorGroup = Prs3d_Root::NewGroup (thePrs);
1243 myTranslatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
62ef08df 1244 myTranslatorGroup->AddPrimitiveArray (myTriangleArray);
625e1958 1245
1246 if (myHighlightTranslator.IsNull())
1247 {
1248 myHighlightTranslator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1249 }
62ef08df 1250 else
1251 {
1252 myHighlightTranslator->Clear();
1253 }
dc89236f 1254 {
1255 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightTranslator);
1256 aGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1257 aGroup->AddPrimitiveArray (myTriangleArray);
1258 }
625e1958 1259 }
1260
1261 if (myHasScaling)
1262 {
1263 myCubePos = myReferenceAxis.Direction().XYZ() * (myLength + myIndent);
1264 myCube.Init (gp_Ax1 (myCubePos, myReferenceAxis.Direction()), myBoxSize);
1265
1266 myScalerGroup = Prs3d_Root::NewGroup (thePrs);
1267 myScalerGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1268 myScalerGroup->AddPrimitiveArray (myCube.Array());
1269
1270 if (myHighlightScaler.IsNull())
1271 {
1272 myHighlightScaler = new Prs3d_Presentation (thePrsMgr->StructureManager());
1273 }
62ef08df 1274 else
1275 {
1276 myHighlightScaler->Clear();
1277 }
dc89236f 1278 {
1279 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightScaler);
1280 aGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1281 aGroup->AddPrimitiveArray (myCube.Array());
1282 }
625e1958 1283 }
1284
1285 if (myHasRotation)
1286 {
1287 myCircleRadius = myInnerRadius + myIndent * 2 + myDiskThickness * 0.5f;
1288 myCircle.Init (myInnerRadius + myIndent * 2, myInnerRadius + myDiskThickness + myIndent * 2, gp_Ax1(gp::Origin(), myReferenceAxis.Direction()), myFacettesNumber * 2);
1289 myRotatorGroup = Prs3d_Root::NewGroup (thePrs);
1290 myRotatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1291 myRotatorGroup->AddPrimitiveArray (myCircle.Array());
1292
1293 if (myHighlightRotator.IsNull())
1294 {
1295 myHighlightRotator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1296 }
62ef08df 1297 else
1298 {
1299 myHighlightRotator->Clear();
1300 }
dc89236f 1301 {
1302 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightRotator);
1303 aGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1304 aGroup->AddPrimitiveArray (myCircle.Array());
1305 }
625e1958 1306 }
1307}