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