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