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