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