0030679: Attached model hangs most of OCCT common functionality
[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
294//=======================================================================
f15c5f90 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
306//=======================================================================
625e1958 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 {
245cbf94 705 const Handle(AIS_InteractiveObject)& anObj = anObjIter.ChangeValue();
706 const gp_Trsf& anOldTrsf = aTrsfIter.Value();
707 const Handle(Geom_Transformation)& aParentTrsf = anObj->CombinedParentTransformation();
708 if (!aParentTrsf.IsNull()
709 && aParentTrsf->Form() != gp_Identity)
710 {
711 // recompute local transformation relative to parent transformation
712 const gp_Trsf aNewLocalTrsf = aParentTrsf->Trsf().Inverted() * theTrsf * aParentTrsf->Trsf() * anOldTrsf;
713 anObj->SetLocalTransformation (aNewLocalTrsf);
714 }
715 else
716 {
717 anObj->SetLocalTransformation (theTrsf * anOldTrsf);
718 }
3ed88fac 719 }
625e1958 720 }
721
f522ce50 722 if ((myCurrentMode == AIS_MM_Translation && myBehaviorOnTransform.FollowTranslation)
723 || (myCurrentMode == AIS_MM_Rotation && myBehaviorOnTransform.FollowRotation)
724 || (myCurrentMode == AIS_MM_TranslationPlane && myBehaviorOnTransform.FollowDragging))
625e1958 725 {
726 gp_Pnt aPos = myStartPosition.Location().Transformed (theTrsf);
727 gp_Dir aVDir = myStartPosition.Direction().Transformed (theTrsf);
728 gp_Dir aXDir = myStartPosition.XDirection().Transformed (theTrsf);
729 SetPosition (gp_Ax2 (aPos, aVDir, aXDir));
730 }
731}
732
733//=======================================================================
734//function : Transform
735//purpose :
736//=======================================================================
737gp_Trsf AIS_Manipulator::Transform (const Standard_Integer thePX, const Standard_Integer thePY,
738 const Handle(V3d_View)& theView)
739{
740 gp_Trsf aTrsf;
741 if (ObjectTransformation (thePX, thePY, theView, aTrsf))
742 {
743 Transform (aTrsf);
744 }
745
746 return aTrsf;
747}
748
749//=======================================================================
750//function : SetPosition
751//purpose :
752//=======================================================================
753void AIS_Manipulator::SetPosition (const gp_Ax2& thePosition)
754{
755 if (!myPosition.Location().IsEqual (thePosition.Location(), Precision::Confusion())
756 || !myPosition.Direction().IsEqual (thePosition.Direction(), Precision::Angular())
757 || !myPosition.XDirection().IsEqual (thePosition.XDirection(), Precision::Angular()))
758 {
759 myPosition = thePosition;
3ed88fac 760 myAxes[0].SetPosition (getAx1FromAx2Dir (thePosition, 0));
761 myAxes[1].SetPosition (getAx1FromAx2Dir (thePosition, 1));
762 myAxes[2].SetPosition (getAx1FromAx2Dir (thePosition, 2));
625e1958 763 updateTransformation();
764 }
765}
766
767//=======================================================================
768//function : updateTransformation
769//purpose : set local transformation to avoid graphics recomputation
770//=======================================================================
771void AIS_Manipulator::updateTransformation()
772{
773 gp_Trsf aTrsf;
774
775 if (!myIsZoomPersistentMode)
776 {
777 aTrsf.SetTransformation (myPosition, gp::XOY());
778 }
779 else
780 {
781 const gp_Dir& aVDir = myPosition.Direction();
782 const gp_Dir& aXDir = myPosition.XDirection();
783 aTrsf.SetTransformation (gp_Ax2 (gp::Origin(), aVDir, aXDir), gp::XOY());
784 }
785
1f7f5a90 786 Handle(Geom_Transformation) aGeomTrsf = new Geom_Transformation (aTrsf);
787 // we explicitly call here setLocalTransformation() of the base class
788 // since AIS_Manipulator::setLocalTransformation() implementation throws exception
789 // as protection from external calls
790 AIS_InteractiveObject::setLocalTransformation (aGeomTrsf);
625e1958 791 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
792 {
793 myAxes[anIt].Transform (aGeomTrsf);
794 }
795
796 if (myIsZoomPersistentMode)
797 {
778cd667 798 if (TransformPersistence().IsNull()
799 || TransformPersistence()->Mode() != Graphic3d_TMF_ZoomPers
800 || !TransformPersistence()->AnchorPoint().IsEqual (myPosition.Location(), 0.0))
625e1958 801 {
778cd667 802 setTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, myPosition.Location()));
625e1958 803 }
804 }
805}
806
807//=======================================================================
808//function : SetSize
809//purpose :
810//=======================================================================
811void AIS_Manipulator::SetSize (const Standard_ShortReal theSideLength)
812{
813 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
814 {
815 myAxes[anIt].SetSize (theSideLength);
816 }
817
818 SetToUpdate();
819}
820
821//=======================================================================
822//function : SetGap
823//purpose :
824//=======================================================================
825void AIS_Manipulator::SetGap (const Standard_ShortReal theValue)
826{
827 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
828 {
829 myAxes[anIt].SetIndent (theValue);
830 }
831
832 SetToUpdate();
833}
834
835//=======================================================================
836//function : DeactivateCurrentMode
837//purpose :
838//=======================================================================
839void AIS_Manipulator::DeactivateCurrentMode()
840{
841 if (!myIsActivationOnDetection)
842 {
843 Handle(Graphic3d_Group) aGroup = getGroup (myCurrentIndex, myCurrentMode);
844 if (aGroup.IsNull())
845 {
846 return;
847 }
848
849 Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
850 anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
851 anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
f522ce50 852 if (myCurrentMode == AIS_MM_TranslationPlane)
853 anAspect->SetTransparency(1.0);
854 else
855 {
856 anAspect->SetTransparency(myDrawer->ShadingAspect()->Transparency());
857 anAspect->SetColor(myAxes[myCurrentIndex].Color());
858 }
625e1958 859
860 aGroup->SetGroupPrimitivesAspect (anAspect->Aspect());
861 }
862
863 myCurrentIndex = -1;
864 myCurrentMode = AIS_MM_None;
865
866 if (myHasStartedTransformation)
867 {
868 myHasStartedTransformation = Standard_False;
869 }
870}
871
872//=======================================================================
873//function : SetZoomPersistence
874//purpose :
875//=======================================================================
876void AIS_Manipulator::SetZoomPersistence (const Standard_Boolean theToEnable)
877{
878 if (myIsZoomPersistentMode != theToEnable)
879 {
880 SetToUpdate();
881 }
882
883 myIsZoomPersistentMode = theToEnable;
884
885 if (!theToEnable)
886 {
778cd667 887 setTransformPersistence (Handle(Graphic3d_TransformPers)());
625e1958 888 }
889
890 updateTransformation();
891}
892
893//=======================================================================
894//function : SetTransformPersistence
778cd667 895//purpose :
625e1958 896//=======================================================================
778cd667 897void AIS_Manipulator::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
625e1958 898{
899 Standard_ASSERT_RETURN (!myIsZoomPersistentMode,
900 "AIS_Manipulator::SetTransformPersistence: "
778cd667 901 "Custom settings are not allowed by this class in ZoomPersistence mode",);
625e1958 902
778cd667 903 setTransformPersistence (theTrsfPers);
625e1958 904}
905
906//=======================================================================
907//function : setTransformPersistence
908//purpose :
909//=======================================================================
778cd667 910void AIS_Manipulator::setTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
625e1958 911{
778cd667 912 AIS_InteractiveObject::SetTransformPersistence (theTrsfPers);
625e1958 913
914 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
915 {
778cd667 916 myAxes[anIt].SetTransformPersistence (theTrsfPers);
625e1958 917 }
918}
919
920//=======================================================================
1f7f5a90 921//function : setLocalTransformation
922//purpose :
625e1958 923//=======================================================================
1f7f5a90 924void AIS_Manipulator::setLocalTransformation (const Handle(Geom_Transformation)& /*theTrsf*/)
625e1958 925{
1f7f5a90 926 Standard_ASSERT_INVOKE ("AIS_Manipulator::setLocalTransformation: "
927 "Custom transformation is not supported by this class");
625e1958 928}
929
930//=======================================================================
931//function : Compute
932//purpose :
933//=======================================================================
934void AIS_Manipulator::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
935 const Handle(Prs3d_Presentation)& thePrs,
936 const Standard_Integer theMode)
937{
938 if (theMode != AIS_Shaded)
939 {
940 return;
941 }
942
943 thePrs->SetInfiniteState (Standard_True);
944 thePrs->SetMutable (Standard_True);
945 Handle(Graphic3d_Group) aGroup;
946 Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
947 anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
948 anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
949 anAspect->SetTransparency (myDrawer->ShadingAspect()->Transparency());
950
951 // Display center
952 myCenter.Init (myAxes[0].AxisRadius() * 2.0f, gp::Origin());
f522ce50 953 aGroup = thePrs->NewGroup ();
625e1958 954 aGroup->SetPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
955 aGroup->AddPrimitiveArray (myCenter.Array());
956
957 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
958 {
959 // Display axes
f522ce50 960 aGroup = thePrs->NewGroup ();
b6472664 961
962 Handle(Prs3d_ShadingAspect) anAspectAx = new Prs3d_ShadingAspect (new Graphic3d_AspectFillArea3d(*anAspect->Aspect()));
963 anAspectAx->SetColor (myAxes[anIt].Color());
964 aGroup->SetGroupPrimitivesAspect (anAspectAx->Aspect());
965 myAxes[anIt].Compute (thePrsMgr, thePrs, anAspectAx);
778cd667 966 myAxes[anIt].SetTransformPersistence (TransformPersistence());
625e1958 967 }
968
969 updateTransformation();
970}
971
972//=======================================================================
973//function : HilightSelected
974//purpose :
975//=======================================================================
976void AIS_Manipulator::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
977 const SelectMgr_SequenceOfOwner& theSeq)
978{
979 if (theSeq.IsEmpty())
980 {
981 return;
982 }
983
984 if (myIsActivationOnDetection)
985 {
986 return;
987 }
988
989 if (!theSeq (1)->IsKind (STANDARD_TYPE (AIS_ManipulatorOwner)))
990 {
8e5fb5ea 991 thePM->Color (this, GetContext()->HighlightStyle(), 0);
625e1958 992 return;
993 }
994
995 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theSeq (1));
8e5fb5ea 996 myHighlightAspect->Aspect()->SetInteriorColor (GetContext()->HighlightStyle()->Color());
625e1958 997 Handle(Graphic3d_Group) aGroup = getGroup (anOwner->Index(), anOwner->Mode());
998 if (aGroup.IsNull())
999 {
1000 return;
1001 }
1002
f522ce50 1003 if (anOwner->Mode() == AIS_MM_TranslationPlane)
1004 {
1005 myDraggerHighlight->SetColor(myAxes[anOwner->Index()].Color());
1006 aGroup->SetGroupPrimitivesAspect(myDraggerHighlight->Aspect());
1007 }
1008 else
1009 aGroup->SetGroupPrimitivesAspect(myHighlightAspect->Aspect());
625e1958 1010
1011 myCurrentIndex = anOwner->Index();
1012 myCurrentMode = anOwner->Mode();
1013}
1014
1015//=======================================================================
1016//function : ClearSelected
1017//purpose :
1018//=======================================================================
1019void AIS_Manipulator::ClearSelected()
1020{
1021 DeactivateCurrentMode();
1022}
1023
1024//=======================================================================
1025//function : HilightOwnerWithColor
1026//purpose :
1027//=======================================================================
8e5fb5ea 1028void AIS_Manipulator::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM,
f838dac4 1029 const Handle(Prs3d_Drawer)& theStyle,
8e5fb5ea 1030 const Handle(SelectMgr_EntityOwner)& theOwner)
625e1958 1031{
1032 Handle(AIS_ManipulatorOwner) anOwner = Handle(AIS_ManipulatorOwner)::DownCast (theOwner);
1033 Handle(Prs3d_Presentation) aPresentation = getHighlightPresentation (anOwner);
1034 if (aPresentation.IsNull())
1035 {
1036 return;
1037 }
f522ce50 1038 if (anOwner->Mode() == AIS_MM_TranslationPlane)
1039 {
1040 Handle(Prs3d_Drawer) aStyle = new Prs3d_Drawer();
1041 aStyle->SetColor(myAxes[anOwner->Index()].Color());
1042 aStyle->SetTransparency(0.5);
1043 aPresentation->Highlight(aStyle);
1044 }
1045 else
1046 aPresentation->Highlight(theStyle);
2831708b 1047 for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPresentation->Groups());
1048 aGroupIter.More(); aGroupIter.Next())
1049 {
1050 Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
bf5f0ca2 1051 if (!aGrp.IsNull())
2831708b 1052 {
1053 aGrp->SetGroupPrimitivesAspect (myHighlightAspect->Aspect());
1054 }
1055 }
625e1958 1056 aPresentation->SetZLayer (Graphic3d_ZLayerId_Topmost);
1057 thePM->AddToImmediateList (aPresentation);
1058
1059 if (myIsActivationOnDetection)
1060 {
1061 if (HasActiveMode())
1062 {
1063 DeactivateCurrentMode();
1064 }
1065
1066 myCurrentIndex = anOwner->Index();
1067 myCurrentMode = anOwner->Mode();
1068 }
1069}
1070
1071//=======================================================================
1072//function : ComputeSelection
1073//purpose :
1074//=======================================================================
1075void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
1076 const Standard_Integer theMode)
1077{
1078 //Check mode
1079 AIS_ManipulatorMode aMode = (AIS_ManipulatorMode) theMode;
1080 if (aMode == AIS_MM_None)
1081 {
1082 return;
1083 }
1084 Handle(SelectMgr_EntityOwner) anOwner;
1085 if (aMode == AIS_MM_None)
1086 {
1087 anOwner = new SelectMgr_EntityOwner (this, 5);
1088 }
62ef08df 1089
625e1958 1090 if (aMode == AIS_MM_Translation || aMode == AIS_MM_None)
1091 {
1092 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
1093 {
f15c5f90 1094 if (!myAxes[anIt].HasTranslation())
1095 {
1096 continue;
1097 }
625e1958 1098 const Axis& anAxis = myAxes[anIt];
1099 if (aMode != AIS_MM_None)
1100 {
f15c5f90 1101 anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Translation, 9);
625e1958 1102 }
1103 // define sensitivity by line
1104 Handle(Select3D_SensitiveSegment) aLine = new Select3D_SensitiveSegment (anOwner, gp::Origin(), anAxis.TranslatorTipPosition());
1105 aLine->SetSensitivityFactor (15);
1106 theSelection->Add (aLine);
62ef08df 1107
625e1958 1108 // enlarge sensitivity by triangulation
62ef08df 1109 Handle(Select3D_SensitivePrimitiveArray) aTri = new Select3D_SensitivePrimitiveArray (anOwner);
1110 aTri->InitTriangulation (anAxis.TriangleArray()->Attributes(), anAxis.TriangleArray()->Indices(), TopLoc_Location());
625e1958 1111 theSelection->Add (aTri);
1112 }
1113 }
1114
1115 if (aMode == AIS_MM_Rotation || aMode == AIS_MM_None)
1116 {
1117 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
1118 {
f15c5f90 1119 if (!myAxes[anIt].HasRotation())
1120 {
1121 continue;
1122 }
625e1958 1123 const Axis& anAxis = myAxes[anIt];
1124 if (aMode != AIS_MM_None)
1125 {
1126 anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Rotation, 9);
1127 }
1128 // define sensitivity by circle
1129 Handle(Geom_Circle) aGeomCircle = new Geom_Circle (gp_Ax2 (gp::Origin(), anAxis.ReferenceAxis().Direction()), anAxis.RotatorDiskRadius());
b11aef43 1130 Handle(Select3D_SensitiveCircle) aCircle = new ManipSensCircle (anOwner, aGeomCircle, anAxis.FacettesNumber());
625e1958 1131 aCircle->SetSensitivityFactor (15);
1132 theSelection->Add (aCircle);
1133 // enlarge sensitivity by triangulation
b11aef43 1134 Handle(Select3D_SensitiveTriangulation) aTri = new ManipSensTriangulation (anOwner, myAxes[anIt].RotatorDisk().Triangulation(), anAxis.ReferenceAxis().Direction());
625e1958 1135 theSelection->Add (aTri);
1136 }
1137 }
1138
1139 if (aMode == AIS_MM_Scaling || aMode == AIS_MM_None)
1140 {
1141 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
1142 {
f15c5f90 1143 if (!myAxes[anIt].HasScaling())
1144 {
1145 continue;
1146 }
625e1958 1147 if (aMode != AIS_MM_None)
1148 {
1149 anOwner = new AIS_ManipulatorOwner (this, anIt, AIS_MM_Scaling, 9);
1150 }
1151 // define sensitivity by point
1152 Handle(Select3D_SensitivePoint) aPnt = new Select3D_SensitivePoint (anOwner, myAxes[anIt].ScalerCubePosition());
1153 aPnt->SetSensitivityFactor (15);
1154 theSelection->Add (aPnt);
1155 // enlarge sensitivity by triangulation
62ef08df 1156 Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation (anOwner, myAxes[anIt].ScalerCube().Triangulation(), TopLoc_Location(), Standard_True);
625e1958 1157 theSelection->Add (aTri);
1158 }
1159 }
f522ce50 1160
1161 if (aMode == AIS_MM_TranslationPlane || aMode == AIS_MM_None)
1162 {
1163 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
1164 {
1165 if (!myAxes[anIt].HasDragging())
1166 {
1167 continue;
1168 }
1169 if (aMode != AIS_MM_None)
1170 {
1171 anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_TranslationPlane, 9);
1172 }
1173
1174 // define sensitivity by two crossed lines
1175 gp_Pnt aP1, aP2;
1176 aP1 = myAxes[((anIt + 1) % 3)].TranslatorTipPosition();
1177 aP2 = myAxes[((anIt + 2) % 3)].TranslatorTipPosition();
1178 gp_XYZ aMidP = (aP1.XYZ() + aP2.XYZ()) / 2.0;
1179
1180 Handle(Select3D_SensitiveSegment) aLine1 = new Select3D_SensitiveSegment(anOwner, aP1, aP2);
1181 aLine1->SetSensitivityFactor(10);
1182 theSelection->Add(aLine1);
1183 Handle(Select3D_SensitiveSegment) aLine2 = new Select3D_SensitiveSegment(anOwner, gp::Origin(), aMidP);
1184 aLine2->SetSensitivityFactor(10);
1185 theSelection->Add(aLine2);
1186
1187 // enlarge sensitivity by triangulation
1188 Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation(anOwner, myAxes[anIt].DraggerSector().Triangulation(), TopLoc_Location(), Standard_True);
1189 theSelection->Add(aTri);
1190 }
1191 }
625e1958 1192}
1193
1194//=======================================================================
625e1958 1195//class : Disk
1196//function : Init
1197//purpose :
1198//=======================================================================
1199void AIS_Manipulator::Disk::Init (const Standard_ShortReal theInnerRadius,
1200 const Standard_ShortReal theOuterRadius,
1201 const gp_Ax1& thePosition,
1202 const Standard_Integer theSlicesNb,
1203 const Standard_Integer theStacksNb)
1204{
1205 myPosition = thePosition;
1206 myInnerRad = theInnerRadius;
1207 myOuterRad = theOuterRadius;
1208
62ef08df 1209 Prs3d_ToolDisk aTool (theInnerRadius, theOuterRadius, theSlicesNb, theStacksNb);
625e1958 1210 gp_Ax3 aSystem (myPosition.Location(), myPosition.Direction());
1211 gp_Trsf aTrsf;
1212 aTrsf.SetTransformation (aSystem, gp_Ax3());
1213 aTool.FillArray (myArray, myTriangulation, aTrsf);
1214}
1215
1216//=======================================================================
1217//class : Sphere
1218//function : Init
1219//purpose :
1220//=======================================================================
1221void AIS_Manipulator::Sphere::Init (const Standard_ShortReal theRadius,
1222 const gp_Pnt& thePosition,
1223 const Standard_Integer theSlicesNb,
1224 const Standard_Integer theStacksNb)
1225{
1226 myPosition = thePosition;
1227 myRadius = theRadius;
1228
62ef08df 1229 Prs3d_ToolSphere aTool (theRadius, theSlicesNb, theStacksNb);
625e1958 1230 gp_Trsf aTrsf;
1231 aTrsf.SetTranslation (gp_Vec(gp::Origin(), thePosition));
1232 aTool.FillArray (myArray, myTriangulation, aTrsf);
1233}
1234
1235//=======================================================================
1236//class : Cube
1237//function : Init
1238//purpose :
1239//=======================================================================
1240void AIS_Manipulator::Cube::Init (const gp_Ax1& thePosition, const Standard_ShortReal theSize)
1241{
1242 myArray = new Graphic3d_ArrayOfTriangles (12 * 3, 0, Standard_True);
1243
1244 Poly_Array1OfTriangle aPolyTriangles (1, 12);
1245 TColgp_Array1OfPnt aPoints (1, 36);
1246 NCollection_Array1<gp_Dir> aNormals (1, 12);
1247 myTriangulation = new Poly_Triangulation (aPoints, aPolyTriangles);
1248
1249 gp_Ax2 aPln (thePosition.Location(), thePosition.Direction());
1250 gp_Pnt aBottomLeft = thePosition.Location().XYZ() - aPln.XDirection().XYZ() * theSize * 0.5 - aPln.YDirection().XYZ() * theSize * 0.5;
1251 gp_Pnt aV2 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize;
1252 gp_Pnt aV3 = aBottomLeft.XYZ() + aPln.YDirection().XYZ() * theSize + aPln.XDirection().XYZ() * theSize;
1253 gp_Pnt aV4 = aBottomLeft.XYZ() + aPln.XDirection().XYZ() * theSize;
1254 gp_Pnt aTopRight = thePosition.Location().XYZ() + thePosition.Direction().XYZ() * theSize
1255 + aPln.XDirection().XYZ() * theSize * 0.5 + aPln.YDirection().XYZ() * theSize * 0.5;
1256 gp_Pnt aV5 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize;
1257 gp_Pnt aV6 = aTopRight.XYZ() - aPln.YDirection().XYZ() * theSize - aPln.XDirection().XYZ() * theSize;
1258 gp_Pnt aV7 = aTopRight.XYZ() - aPln.XDirection().XYZ() * theSize;
1259
1260 gp_Dir aRight ((gp_Vec(aTopRight, aV7) ^ gp_Vec(aTopRight, aV2)).XYZ());
1261 gp_Dir aFront ((gp_Vec(aV3, aV4) ^ gp_Vec(aV3, aV5)).XYZ());
1262
1263 // Bottom
1264 addTriangle (0, aBottomLeft, aV2, aV3, -thePosition.Direction());
1265 addTriangle (1, aBottomLeft, aV3, aV4, -thePosition.Direction());
1266
1267 // Front
1268 addTriangle (2, aV3, aV4, aV5, aFront);
1269 addTriangle (3, aV3, aV5, aTopRight, aFront);
1270
1271 // Back
1272 addTriangle (4, aBottomLeft, aV2, aV7, -aFront);
1273 addTriangle (5, aBottomLeft, aV7, aV6, -aFront);
1274
1275 // aTop
1276 addTriangle (6, aV7, aV6, aV5, thePosition.Direction());
1277 addTriangle (7, aTopRight, aV7, aV5, thePosition.Direction());
1278
1279 //Left
1280 addTriangle (8, aV6, aV5, aV4, -aRight);
1281 addTriangle (9, aBottomLeft, aV6, aV4, -aRight);
1282
1283 // Right
1284 addTriangle (10, aV3, aTopRight, aV7, aRight);
1285 addTriangle (11, aV3, aV7, aV2, aRight);
1286}
1287
1288//=======================================================================
1289//class : Cube
1290//function : addTriangle
1291//purpose :
1292//=======================================================================
1293void AIS_Manipulator::Cube::addTriangle (const Standard_Integer theIndex,
1294 const gp_Pnt& theP1, const gp_Pnt& theP2, const gp_Pnt& theP3,
1295 const gp_Dir& theNormal)
1296{
1297 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 1, theP1);
1298 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 2, theP2);
1299 myTriangulation->ChangeNodes().SetValue (theIndex * 3 + 3, theP3);
1300
1301 myTriangulation->ChangeTriangles().SetValue (theIndex + 1, Poly_Triangle (theIndex * 3 + 1, theIndex * 3 + 2, theIndex * 3 + 3));
1302 myArray->AddVertex (theP1, theNormal);
1303 myArray->AddVertex (theP2, theNormal);
1304 myArray->AddVertex (theP3, theNormal);
1305}
1306
1307//=======================================================================
f522ce50 1308//class : Sector
1309//function : Init
1310//purpose :
1311//=======================================================================
1312void AIS_Manipulator::Sector::Init (const Standard_ShortReal theRadius,
1313 const gp_Ax1& thePosition,
1314 const gp_Dir& theXDirection,
1315 const Standard_Integer theSlicesNb,
1316 const Standard_Integer theStacksNb)
1317{
1318 Prs3d_ToolSector aTool(theRadius, theSlicesNb, theStacksNb);
1319 gp_Ax3 aSystem(thePosition.Location(), thePosition.Direction(), theXDirection);
1320 gp_Trsf aTrsf;
1321 aTrsf.SetTransformation(aSystem, gp_Ax3());
1322 aTool.FillArray(myArray, myTriangulation, aTrsf);
1323}
1324
1325//=======================================================================
625e1958 1326//class : Axis
1327//function : Constructor
1328//purpose :
1329//=======================================================================
1330AIS_Manipulator::Axis::Axis (const gp_Ax1& theAxis,
1331 const Quantity_Color& theColor,
1332 const Standard_ShortReal theLength)
1333: myReferenceAxis (theAxis),
1334 myPosition (theAxis),
1335 myColor (theColor),
1336 myHasTranslation (Standard_True),
1337 myLength (theLength),
1338 myAxisRadius (0.5f),
1339 myHasScaling (Standard_True),
1340 myBoxSize (2.0f),
1341 myHasRotation (Standard_True),
1342 myInnerRadius (myLength + myBoxSize),
1343 myDiskThickness (myBoxSize * 0.5f),
1344 myIndent (0.2f),
f522ce50 1345 myHasDragging(Standard_True),
625e1958 1346 myFacettesNumber (20),
1347 myCircleRadius (myLength + myBoxSize + myBoxSize * 0.5f * 0.5f)
1348{
1349 //
1350}
1351
1352//=======================================================================
1353//class : Axis
1354//function : Compute
62ef08df 1355//purpose :
625e1958 1356//=======================================================================
62ef08df 1357
1358void AIS_Manipulator::Axis::Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
625e1958 1359 const Handle(Prs3d_Presentation)& thePrs,
1360 const Handle(Prs3d_ShadingAspect)& theAspect)
1361{
625e1958 1362 if (myHasTranslation)
1363 {
62ef08df 1364 const Standard_Real anArrowLength = 0.25 * myLength;
1365 const Standard_Real aCylinderLength = myLength - anArrowLength;
1366 myArrowTipPos = gp_Pnt (0.0, 0.0, 0.0).Translated (myReferenceAxis.Direction().XYZ() * aCylinderLength);
1367
1368 myTriangleArray = Prs3d_Arrow::DrawShaded (gp_Ax1(gp::Origin(), myReferenceAxis.Direction()),
1369 myAxisRadius,
1370 myLength,
1371 myAxisRadius * 1.5,
1372 anArrowLength,
1373 myFacettesNumber);
f522ce50 1374 myTranslatorGroup = thePrs->NewGroup ();
625e1958 1375 myTranslatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
62ef08df 1376 myTranslatorGroup->AddPrimitiveArray (myTriangleArray);
625e1958 1377
1378 if (myHighlightTranslator.IsNull())
1379 {
1380 myHighlightTranslator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1381 }
62ef08df 1382 else
1383 {
1384 myHighlightTranslator->Clear();
1385 }
dc89236f 1386 {
1387 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightTranslator);
1388 aGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1389 aGroup->AddPrimitiveArray (myTriangleArray);
1390 }
625e1958 1391 }
1392
1393 if (myHasScaling)
1394 {
1395 myCubePos = myReferenceAxis.Direction().XYZ() * (myLength + myIndent);
1396 myCube.Init (gp_Ax1 (myCubePos, myReferenceAxis.Direction()), myBoxSize);
1397
f522ce50 1398 myScalerGroup = thePrs->NewGroup ();
625e1958 1399 myScalerGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1400 myScalerGroup->AddPrimitiveArray (myCube.Array());
1401
1402 if (myHighlightScaler.IsNull())
1403 {
1404 myHighlightScaler = new Prs3d_Presentation (thePrsMgr->StructureManager());
1405 }
62ef08df 1406 else
1407 {
1408 myHighlightScaler->Clear();
1409 }
dc89236f 1410 {
1411 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightScaler);
1412 aGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1413 aGroup->AddPrimitiveArray (myCube.Array());
1414 }
625e1958 1415 }
1416
1417 if (myHasRotation)
1418 {
1419 myCircleRadius = myInnerRadius + myIndent * 2 + myDiskThickness * 0.5f;
1420 myCircle.Init (myInnerRadius + myIndent * 2, myInnerRadius + myDiskThickness + myIndent * 2, gp_Ax1(gp::Origin(), myReferenceAxis.Direction()), myFacettesNumber * 2);
f522ce50 1421 myRotatorGroup = thePrs->NewGroup ();
625e1958 1422 myRotatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1423 myRotatorGroup->AddPrimitiveArray (myCircle.Array());
1424
1425 if (myHighlightRotator.IsNull())
1426 {
1427 myHighlightRotator = new Prs3d_Presentation (thePrsMgr->StructureManager());
1428 }
62ef08df 1429 else
1430 {
1431 myHighlightRotator->Clear();
1432 }
dc89236f 1433 {
1434 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightRotator);
1435 aGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
1436 aGroup->AddPrimitiveArray (myCircle.Array());
1437 }
625e1958 1438 }
f522ce50 1439
1440 if (myHasDragging)
1441 {
1442 gp_Dir aXDirection;
1443 if (myReferenceAxis.Direction().X() > 0)
1444 aXDirection = gp::DY();
1445 else if (myReferenceAxis.Direction().Y() > 0)
1446 aXDirection = gp::DZ();
1447 else
1448 aXDirection = gp::DX();
1449
1450 mySector.Init(myInnerRadius + myIndent * 2, gp_Ax1(gp::Origin(), myReferenceAxis.Direction()), aXDirection, myFacettesNumber * 2);
1451 myDraggerGroup = thePrs->NewGroup();
1452
1453 Handle(Graphic3d_AspectFillArea3d) aFillArea = new Graphic3d_AspectFillArea3d();
1454 myDraggerGroup->SetGroupPrimitivesAspect(aFillArea);
1455 myDraggerGroup->AddPrimitiveArray(mySector.Array());
1456
1457 if (myHighlightDragger.IsNull())
1458 {
1459 myHighlightDragger = new Prs3d_Presentation(thePrsMgr->StructureManager());
1460 }
1461 else
1462 {
1463 myHighlightDragger->Clear();
1464 }
1465 {
1466 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup(myHighlightDragger);
1467 aGroup->SetGroupPrimitivesAspect(aFillArea);
1468 aGroup->AddPrimitiveArray(mySector.Array());
1469 }
1470 }
625e1958 1471}