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