1 // Created on: 2017-07-25
2 // Created by: Anastasia BOBYLEVA
3 // Copyright (c) 2017-2019 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_ViewCube.hxx>
17
18 #include <AIS_AnimationCamera.hxx>
19 #include <AIS_InteractiveContext.hxx>
20 #include <gp_Ax2.hxx>
21 #include <Graphic3d_ViewAffinity.hxx>
22 #include <Graphic3d_Text.hxx>
23 #include <NCollection_Lerp.hxx>
24 #include <Prs3d.hxx>
25 #include <Prs3d_Arrow.hxx>
26 #include <Prs3d_DatumAspect.hxx>
27 #include <Prs3d_Text.hxx>
28 #include <Prs3d_ToolDisk.hxx>
29 #include <Prs3d_ToolSphere.hxx>
30 #include <SelectMgr_SequenceOfOwner.hxx>
31 #include <V3d.hxx>
32 #include <V3d_View.hxx>
33
34 IMPLEMENT_STANDARD_RTTIEXT(AIS_ViewCube, AIS_InteractiveObject)
35 IMPLEMENT_STANDARD_RTTIEXT(AIS_ViewCubeOwner, SelectMgr_EntityOwner)
36 IMPLEMENT_STANDARD_RTTIEXT(AIS_ViewCubeSensitive, Select3D_SensitivePrimitiveArray)
37
38 namespace
39 {
40 static const Standard_Integer THE_NB_ROUND_SPLITS = 8;
41 static const Standard_Integer THE_NB_DISK_SLICES = 20;
42 static const Standard_Integer THE_NB_ARROW_FACETTES = 20;
43
44 //! Return the number of non-zero components.
nbDirectionComponents(const gp_Dir & theDir)45 static Standard_Integer nbDirectionComponents (const gp_Dir& theDir)
46 {
47 Standard_Integer aNbComps = 0;
48 for (Standard_Integer aCompIter = 1; aCompIter <= 3; ++aCompIter)
49 {
50 if (Abs (theDir.Coord (aCompIter)) > gp::Resolution())
51 {
52 ++aNbComps;
53 }
54 }
55 return aNbComps;
56 }
57 }
58
59 //=======================================================================
60 //function : AIS_ViewCubeSensitive
61 //purpose :
62 //=======================================================================
AIS_ViewCubeSensitive(const Handle (SelectMgr_EntityOwner)& theOwner,const Handle (Graphic3d_ArrayOfTriangles)& theTris)63 AIS_ViewCubeSensitive::AIS_ViewCubeSensitive (const Handle(SelectMgr_EntityOwner)& theOwner,
64 const Handle(Graphic3d_ArrayOfTriangles)& theTris)
65 : Select3D_SensitivePrimitiveArray (theOwner)
66 {
67 InitTriangulation (theTris->Attributes(), theTris->Indices(), TopLoc_Location());
68 }
69
70 //=======================================================================
71 //function : Matches
72 //purpose :
73 //=======================================================================
Matches(SelectBasics_SelectingVolumeManager & theMgr,SelectBasics_PickResult & thePickResult)74 Standard_Boolean AIS_ViewCubeSensitive::Matches (SelectBasics_SelectingVolumeManager& theMgr,
75 SelectBasics_PickResult& thePickResult)
76 {
77 return isValidRay (theMgr) && Select3D_SensitivePrimitiveArray::Matches (theMgr, thePickResult);
78 }
79
80 //=======================================================================
81 //function : isValidRay
82 //purpose :
83 //=======================================================================
isValidRay(const SelectBasics_SelectingVolumeManager & theMgr) const84 bool AIS_ViewCubeSensitive::isValidRay (const SelectBasics_SelectingVolumeManager& theMgr) const
85 {
86 if (theMgr.GetActiveSelectionType() != SelectMgr_SelectionType_Point)
87 {
88 // disallow rectangular selection
89 return false;
90 }
91
92 if (AIS_ViewCubeOwner* anOwner = dynamic_cast<AIS_ViewCubeOwner* >(myOwnerId.get()))
93 {
94 const Standard_Real anAngleToler = 10.0 * M_PI / 180.0;
95 const gp_Dir aRay = theMgr.GetViewRayDirection();
96 const gp_Dir aDir = V3d::GetProjAxis (anOwner->MainOrientation());
97 return !aRay.IsNormal (aDir, anAngleToler);
98 }
99 return true;
100 }
101
102 //=======================================================================
103 //function : IsBoxSide
104 //purpose :
105 //=======================================================================
IsBoxSide(V3d_TypeOfOrientation theOrient)106 bool AIS_ViewCube::IsBoxSide (V3d_TypeOfOrientation theOrient)
107 {
108 return nbDirectionComponents (V3d::GetProjAxis (theOrient)) == 1;
109 }
110
111 //=======================================================================
112 //function : IsBoxEdge
113 //purpose :
114 //=======================================================================
IsBoxEdge(V3d_TypeOfOrientation theOrient)115 bool AIS_ViewCube::IsBoxEdge (V3d_TypeOfOrientation theOrient)
116 {
117 return nbDirectionComponents (V3d::GetProjAxis (theOrient)) == 2;
118 }
119
120 //=======================================================================
121 //function : IsBoxCorner
122 //purpose :
123 //=======================================================================
IsBoxCorner(V3d_TypeOfOrientation theOrient)124 bool AIS_ViewCube::IsBoxCorner (V3d_TypeOfOrientation theOrient)
125 {
126 return nbDirectionComponents (V3d::GetProjAxis (theOrient)) == 3;
127 }
128
129 //=======================================================================
130 //function : AIS_ViewCube
131 //purpose :
132 //=======================================================================
AIS_ViewCube()133 AIS_ViewCube::AIS_ViewCube()
134 : myBoxEdgeAspect (new Prs3d_ShadingAspect()),
135 myBoxCornerAspect (new Prs3d_ShadingAspect()),
136 mySize (1.0),
137 myBoxEdgeMinSize (2.0),
138 myBoxEdgeGap (0.0),
139 myBoxFacetExtension (1.0),
140 myAxesPadding (1.0),
141 myAxesRadius (1.0),
142 myAxesConeRadius (3.0),
143 myAxesSphereRadius (4.0),
144 myCornerMinSize (2.0),
145 myRoundRadius (0.0),
146 myToDisplayAxes (true),
147 myToDisplayEdges (true),
148 myToDisplayVertices (true),
149 myIsYup (false),
150 myViewAnimation (new AIS_AnimationCamera ("AIS_ViewCube", Handle(V3d_View)())),
151 myStartState(new Graphic3d_Camera()),
152 myEndState (new Graphic3d_Camera()),
153 myToAutoStartAnim (true),
154 myIsFixedAnimation (true),
155 myToFitSelected (true),
156 myToResetCameraUp (false)
157 {
158 myViewAnimation->SetOwnDuration (0.5);
159 myInfiniteState = true;
160 myIsMutable = true;
161 myDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
162 myTransformPersistence = new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_LOWER, Graphic3d_Vec2i (100, 100));
163
164 myDrawer->SetTextAspect (new Prs3d_TextAspect());
165 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
166
167 myDynHilightDrawer = new Prs3d_Drawer();
168 myDynHilightDrawer->SetLink (myDrawer);
169 myDynHilightDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
170
171 setDefaultAttributes();
172 setDefaultHighlightAttributes();
173
174 // setup default labels
175 myBoxSideLabels.Bind (V3d_TypeOfOrientation_Zup_Front, "FRONT");
176 myBoxSideLabels.Bind (V3d_TypeOfOrientation_Zup_Back, "BACK");
177 myBoxSideLabels.Bind (V3d_TypeOfOrientation_Zup_Top, "TOP");
178 myBoxSideLabels.Bind (V3d_TypeOfOrientation_Zup_Bottom, "BOTTOM");
179 myBoxSideLabels.Bind (V3d_TypeOfOrientation_Zup_Left, "LEFT");
180 myBoxSideLabels.Bind (V3d_TypeOfOrientation_Zup_Right, "RIGHT");
181
182 myAxesLabels.Bind (Prs3d_DatumParts_XAxis, "X");
183 myAxesLabels.Bind (Prs3d_DatumParts_YAxis, "Y");
184 myAxesLabels.Bind (Prs3d_DatumParts_ZAxis, "Z");
185
186 // define default size
187 SetSize (70.0);
188 }
189
190 //=======================================================================
191 //function : setDefaultAttributes
192 //purpose :
193 //=======================================================================
setDefaultAttributes()194 void AIS_ViewCube::setDefaultAttributes()
195 {
196 myDrawer->TextAspect()->SetHorizontalJustification(Graphic3d_HTA_CENTER);
197 myDrawer->TextAspect()->SetVerticalJustification (Graphic3d_VTA_CENTER);
198 myDrawer->TextAspect()->SetColor (Quantity_NOC_BLACK);
199 myDrawer->TextAspect()->SetFont (Font_NOF_SANS_SERIF);
200 myDrawer->TextAspect()->SetHeight (16.0);
201 myDrawer->TextAspect()->Aspect()->SetTextZoomable (true); // the whole object is drawn within transformation-persistence
202 // this should be forced back-face culling regardless Closed flag
203 myDrawer->TextAspect()->Aspect()->SetFaceCulling (Graphic3d_TypeOfBackfacingModel_BackCulled);
204
205 Graphic3d_MaterialAspect aMat (Graphic3d_NameOfMaterial_UserDefined);
206 aMat.SetColor (Quantity_NOC_WHITE);
207 aMat.SetAmbientColor (Quantity_NOC_GRAY60);
208
209 const Handle(Graphic3d_AspectFillArea3d)& aShading = myDrawer->ShadingAspect()->Aspect();
210 aShading->SetInteriorStyle (Aspect_IS_SOLID);
211 // this should be forced back-face culling regardless Closed flag
212 aShading->SetFaceCulling (Graphic3d_TypeOfBackfacingModel_BackCulled);
213 aShading->SetInteriorColor (aMat.Color());
214 aShading->SetFrontMaterial (aMat);
215 myDrawer->SetFaceBoundaryDraw (false);
216
217 *myBoxEdgeAspect ->Aspect() = *aShading;
218 myBoxEdgeAspect->SetColor (Quantity_NOC_GRAY30);
219 *myBoxCornerAspect->Aspect() = *aShading;
220 myBoxCornerAspect->SetColor (Quantity_NOC_GRAY30);
221 }
222
223 //=======================================================================
224 //function : setDefaultHighlightAttributes
225 //purpose :
226 //=======================================================================
setDefaultHighlightAttributes()227 void AIS_ViewCube::setDefaultHighlightAttributes()
228 {
229 Graphic3d_MaterialAspect aHighlightMaterial;
230 aHighlightMaterial.SetAmbientColor (Quantity_NOC_BLACK);
231 aHighlightMaterial.SetDiffuseColor (Quantity_NOC_BLACK);
232 aHighlightMaterial.SetSpecularColor(Quantity_NOC_BLACK);
233 aHighlightMaterial.SetEmissiveColor(Quantity_NOC_BLACK);
234 aHighlightMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
235 myDynHilightDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
236 myDynHilightDrawer->ShadingAspect()->SetMaterial (aHighlightMaterial);
237 myDynHilightDrawer->ShadingAspect()->SetColor (Quantity_NOC_CYAN1);
238 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
239 myDynHilightDrawer->SetColor (Quantity_NOC_CYAN1);
240 }
241
242 //=======================================================================
243 //function : SetYup
244 //purpose :
245 //=======================================================================
SetYup(Standard_Boolean theIsYup,Standard_Boolean theToUpdateLabels)246 void AIS_ViewCube::SetYup (Standard_Boolean theIsYup,
247 Standard_Boolean theToUpdateLabels)
248 {
249 if (myIsYup == theIsYup)
250 {
251 return;
252 }
253
254 myIsYup = theIsYup;
255
256 static const V3d_TypeOfOrientation THE_ZUP_ORI_LIST[6] =
257 {
258 V3d_TypeOfOrientation_Zup_Front, V3d_TypeOfOrientation_Zup_Back,
259 V3d_TypeOfOrientation_Zup_Top, V3d_TypeOfOrientation_Zup_Bottom,
260 V3d_TypeOfOrientation_Zup_Left, V3d_TypeOfOrientation_Zup_Right
261 };
262 static const V3d_TypeOfOrientation THE_YUP_ORI_LIST[6] =
263 {
264 V3d_TypeOfOrientation_Yup_Front, V3d_TypeOfOrientation_Yup_Back,
265 V3d_TypeOfOrientation_Yup_Top, V3d_TypeOfOrientation_Yup_Bottom,
266 V3d_TypeOfOrientation_Yup_Left, V3d_TypeOfOrientation_Yup_Right
267 };
268 if (theToUpdateLabels)
269 {
270 NCollection_Array1<TCollection_AsciiString> aLabels (0, 5);
271 for (Standard_Integer aLabelIter = 0; aLabelIter < 6; ++aLabelIter)
272 {
273 myBoxSideLabels.Find (!myIsYup ? THE_YUP_ORI_LIST[aLabelIter] : THE_ZUP_ORI_LIST[aLabelIter],
274 aLabels.ChangeValue (aLabelIter));
275 }
276 for (Standard_Integer aLabelIter = 0; aLabelIter < 6; ++aLabelIter)
277 {
278 myBoxSideLabels.Bind (myIsYup ? THE_YUP_ORI_LIST[aLabelIter] : THE_ZUP_ORI_LIST[aLabelIter],
279 aLabels.Value (aLabelIter));
280 }
281 }
282
283 SetToUpdate();
284 }
285
286 //=======================================================================
287 //function : ResetStyles
288 //purpose :
289 //=======================================================================
ResetStyles()290 void AIS_ViewCube::ResetStyles()
291 {
292 UnsetAttributes();
293 UnsetHilightAttributes();
294
295 myBoxEdgeMinSize = 2.0;
296 myCornerMinSize = 2.0;
297 myBoxEdgeGap = 0.0;
298 myRoundRadius = 0.0;
299
300 myToDisplayAxes = true;
301 myToDisplayEdges = true;
302 myToDisplayVertices = true;
303
304 myBoxFacetExtension = 1.0;
305 myAxesPadding = 1.0;
306 SetSize (70.0);
307 }
308
309 //=======================================================================
310 //function : SetSize
311 //purpose :
312 //=======================================================================
SetSize(Standard_Real theValue,Standard_Boolean theToAdaptAnother)313 void AIS_ViewCube::SetSize (Standard_Real theValue,
314 Standard_Boolean theToAdaptAnother)
315 {
316 const bool isNewSize = Abs (mySize - theValue) > Precision::Confusion();
317 mySize = theValue;
318 if (theToAdaptAnother)
319 {
320 if (myBoxFacetExtension > 0.0)
321 {
322 SetBoxFacetExtension (mySize * 0.15);
323 }
324 if (myAxesPadding > 0.0)
325 {
326 SetAxesPadding (mySize * 0.1);
327 }
328 SetFontHeight (mySize * 0.16);
329 }
330 if (isNewSize)
331 {
332 SetToUpdate();
333 }
334 }
335
336 //=======================================================================
337 //function : SetRoundRadius
338 //purpose :
339 //=======================================================================
SetRoundRadius(const Standard_Real theValue)340 void AIS_ViewCube::SetRoundRadius (const Standard_Real theValue)
341 {
342 Standard_OutOfRange_Raise_if (theValue < 0.0 || theValue > 0.5,
343 "AIS_ViewCube::SetRoundRadius(): theValue should be in [0; 0.5]");
344 if (Abs (myRoundRadius - theValue) > Precision::Confusion())
345 {
346 myRoundRadius = theValue;
347 SetToUpdate();
348 }
349 }
350
351 //=======================================================================
352 //function : createRoundRectangleTriangles
353 //purpose :
354 //=======================================================================
createRoundRectangleTriangles(const Handle (Graphic3d_ArrayOfTriangles)& theTris,Standard_Integer & theNbNodes,Standard_Integer & theNbTris,const gp_XY & theSize,Standard_Real theRadius,const gp_Trsf & theTrsf)355 void AIS_ViewCube::createRoundRectangleTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
356 Standard_Integer& theNbNodes,
357 Standard_Integer& theNbTris,
358 const gp_XY& theSize,
359 Standard_Real theRadius,
360 const gp_Trsf& theTrsf)
361 {
362 const Standard_Real aRadius = Min (theRadius, Min (theSize.X(), theSize.Y()) * 0.5);
363 const gp_XY aHSize (theSize.X() * 0.5 - aRadius, theSize.Y() * 0.5 - aRadius);
364 const gp_Dir aNorm = gp::DZ().Transformed (theTrsf);
365 const Standard_Integer aVertFirst = !theTris.IsNull() ? theTris->VertexNumber() : 0;
366 if (aRadius > 0.0)
367 {
368 const Standard_Integer aNbNodes = (THE_NB_ROUND_SPLITS + 1) * 4 + 1;
369 theNbNodes += aNbNodes;
370 theNbTris += aNbNodes;
371 if (theTris.IsNull())
372 {
373 return;
374 }
375
376 theTris->AddVertex (gp_Pnt (0.0, 0.0, 0.0).Transformed (theTrsf));
377 for (Standard_Integer aNodeIter = 0; aNodeIter <= THE_NB_ROUND_SPLITS; ++aNodeIter)
378 {
379 const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (M_PI * 0.5, 0.0, Standard_Real(aNodeIter) / Standard_Real(THE_NB_ROUND_SPLITS));
380 theTris->AddVertex (gp_Pnt (aHSize.X() + aRadius * Cos (anAngle), aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
381 }
382 for (Standard_Integer aNodeIter = 0; aNodeIter <= THE_NB_ROUND_SPLITS; ++aNodeIter)
383 {
384 const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (0.0, -M_PI * 0.5, Standard_Real(aNodeIter) / Standard_Real(THE_NB_ROUND_SPLITS));
385 theTris->AddVertex (gp_Pnt (aHSize.X() + aRadius * Cos (anAngle), -aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
386 }
387 for (Standard_Integer aNodeIter = 0; aNodeIter <= THE_NB_ROUND_SPLITS; ++aNodeIter)
388 {
389 const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (-M_PI * 0.5, -M_PI, Standard_Real(aNodeIter) / Standard_Real(THE_NB_ROUND_SPLITS));
390 theTris->AddVertex (gp_Pnt (-aHSize.X() + aRadius * Cos (anAngle), -aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
391 }
392 for (Standard_Integer aNodeIter = 0; aNodeIter <= THE_NB_ROUND_SPLITS; ++aNodeIter)
393 {
394 const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (-M_PI, -M_PI * 1.5, Standard_Real(aNodeIter) / Standard_Real(THE_NB_ROUND_SPLITS));
395 theTris->AddVertex (gp_Pnt (-aHSize.X() + aRadius * Cos (anAngle), aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
396 }
397
398 // split triangle fan
399 theTris->AddTriangleFanEdges (aVertFirst + 1, theTris->VertexNumber(), true);
400 }
401 else
402 {
403 theNbNodes += 4;
404 theNbTris += 2;
405 if (theTris.IsNull())
406 {
407 return;
408 }
409
410 theTris->AddVertex (gp_Pnt (-aHSize.X(), -aHSize.Y(), 0.0).Transformed (theTrsf));
411 theTris->AddVertex (gp_Pnt (-aHSize.X(), aHSize.Y(), 0.0).Transformed (theTrsf));
412 theTris->AddVertex (gp_Pnt ( aHSize.X(), aHSize.Y(), 0.0).Transformed (theTrsf));
413 theTris->AddVertex (gp_Pnt ( aHSize.X(), -aHSize.Y(), 0.0).Transformed (theTrsf));
414 theTris->AddQuadTriangleEdges (aVertFirst + 1, aVertFirst + 2, aVertFirst + 3, aVertFirst + 4);
415 }
416
417 for (Standard_Integer aVertIter = aVertFirst + 1; aVertIter <= theTris->VertexNumber(); ++aVertIter)
418 {
419 theTris->SetVertexNormal (aVertIter, -aNorm);
420 }
421 }
422
423 //=======================================================================
424 //function : createBoxPartTriangles
425 //purpose :
426 //=======================================================================
createBoxPartTriangles(const Handle (Graphic3d_ArrayOfTriangles)& theTris,Standard_Integer & theNbNodes,Standard_Integer & theNbTris,V3d_TypeOfOrientation theDir) const427 void AIS_ViewCube::createBoxPartTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
428 Standard_Integer& theNbNodes,
429 Standard_Integer& theNbTris,
430 V3d_TypeOfOrientation theDir) const
431 {
432 if (IsBoxSide (theDir))
433 {
434 createBoxSideTriangles (theTris, theNbNodes, theNbTris, theDir);
435 }
436 else if (IsBoxEdge (theDir)
437 && myToDisplayEdges)
438 {
439 createBoxEdgeTriangles (theTris, theNbNodes, theNbTris, theDir);
440 }
441 else if (IsBoxCorner (theDir)
442 && myToDisplayVertices)
443 {
444 createBoxCornerTriangles (theTris, theNbNodes, theNbTris, theDir);
445 }
446 }
447
448 //=======================================================================
449 //function : createBoxSideTriangles
450 //purpose :
451 //=======================================================================
createBoxSideTriangles(const Handle (Graphic3d_ArrayOfTriangles)& theTris,Standard_Integer & theNbNodes,Standard_Integer & theNbTris,V3d_TypeOfOrientation theDirection) const452 void AIS_ViewCube::createBoxSideTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
453 Standard_Integer& theNbNodes,
454 Standard_Integer& theNbTris,
455 V3d_TypeOfOrientation theDirection) const
456 {
457 const gp_Dir aDir = V3d::GetProjAxis (theDirection);
458 const gp_Pnt aPos = aDir.XYZ() * (mySize * 0.5 + myBoxFacetExtension);
459 const gp_Ax2 aPosition (aPos, aDir.Reversed());
460
461 gp_Ax3 aSystem (aPosition);
462 gp_Trsf aTrsf;
463 aTrsf.SetTransformation (aSystem, gp_Ax3());
464
465 createRoundRectangleTriangles (theTris, theNbNodes, theNbTris,
466 gp_XY (mySize, mySize), myRoundRadius * mySize, aTrsf);
467 }
468
469 //=======================================================================
470 //function : createBoxEdgeTriangles
471 //purpose :
472 //=======================================================================
createBoxEdgeTriangles(const Handle (Graphic3d_ArrayOfTriangles)& theTris,Standard_Integer & theNbNodes,Standard_Integer & theNbTris,V3d_TypeOfOrientation theDirection) const473 void AIS_ViewCube::createBoxEdgeTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
474 Standard_Integer& theNbNodes,
475 Standard_Integer& theNbTris,
476 V3d_TypeOfOrientation theDirection) const
477 {
478 const Standard_Real aThickness = Max (myBoxFacetExtension * gp_XY (1.0, 1.0).Modulus() - myBoxEdgeGap, myBoxEdgeMinSize);
479
480 const gp_Dir aDir = V3d::GetProjAxis (theDirection);
481 const gp_Pnt aPos = aDir.XYZ() * (mySize * 0.5 * gp_XY (1.0, 1.0).Modulus() + myBoxFacetExtension * Cos (M_PI_4));
482 const gp_Ax2 aPosition (aPos, aDir.Reversed());
483
484 gp_Ax3 aSystem (aPosition);
485 gp_Trsf aTrsf;
486 aTrsf.SetTransformation (aSystem, gp_Ax3());
487
488 createRoundRectangleTriangles (theTris, theNbNodes, theNbTris,
489 gp_XY (aThickness, mySize), myRoundRadius * mySize, aTrsf);
490 }
491
492 //=======================================================================
493 //function : createBoxCornerTriangles
494 //purpose :
495 //=======================================================================
createBoxCornerTriangles(const Handle (Graphic3d_ArrayOfTriangles)& theTris,Standard_Integer & theNbNodes,Standard_Integer & theNbTris,V3d_TypeOfOrientation theDir) const496 void AIS_ViewCube::createBoxCornerTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
497 Standard_Integer& theNbNodes,
498 Standard_Integer& theNbTris,
499 V3d_TypeOfOrientation theDir) const
500 {
501 const Standard_Real aHSize = mySize * 0.5;
502 const gp_Dir aDir = V3d::GetProjAxis (theDir);
503 const gp_XYZ aHSizeDir = aDir.XYZ() * (aHSize * gp_Vec (1.0, 1.0, 1.0).Magnitude());
504 const Standard_Integer aVertFirst = !theTris.IsNull() ? theTris->VertexNumber() : 0;
505 if (myRoundRadius > 0.0)
506 {
507 theNbNodes += THE_NB_DISK_SLICES + 1;
508 theNbTris += THE_NB_DISK_SLICES + 1;
509 if (theTris.IsNull())
510 {
511 return;
512 }
513
514 const Standard_Real anEdgeHWidth = myBoxFacetExtension * gp_XY (1.0, 1.0).Modulus() * 0.5;
515 const Standard_Real aHeight = anEdgeHWidth * Sqrt (2.0 / 3.0); // tetrahedron height
516 const gp_Pnt aPos = aDir.XYZ() * (aHSize * gp_Vec (1.0, 1.0, 1.0).Magnitude() + aHeight);
517 const gp_Ax2 aPosition (aPos, aDir.Reversed());
518 gp_Ax3 aSystem (aPosition);
519 gp_Trsf aTrsf;
520 aTrsf.SetTransformation (aSystem, gp_Ax3());
521 const Standard_Real aRadius = Max (myBoxFacetExtension * 0.5 / Cos (M_PI_4), myCornerMinSize);
522
523 theTris->AddVertex (gp_Pnt (0.0, 0.0, 0.0).Transformed (aTrsf));
524 for (Standard_Integer aNodeIter = 0; aNodeIter < THE_NB_DISK_SLICES; ++aNodeIter)
525 {
526 const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (2.0 * M_PI, 0.0, Standard_Real(aNodeIter) / Standard_Real(THE_NB_DISK_SLICES));
527 theTris->AddVertex (gp_Pnt (aRadius * Cos (anAngle), aRadius * Sin (anAngle), 0.0).Transformed (aTrsf));
528 }
529 theTris->AddTriangleFanEdges (aVertFirst + 1, theTris->VertexNumber(), true);
530 }
531 else
532 {
533 theNbNodes += 3;
534 theNbTris += 1;
535 if (theTris.IsNull())
536 {
537 return;
538 }
539
540 theTris->AddVertex (aHSizeDir + myBoxFacetExtension * gp_Dir (aDir.X(), 0.0, 0.0).XYZ());
541 theTris->AddVertex (aHSizeDir + myBoxFacetExtension * gp_Dir (0.0, aDir.Y(), 0.0).XYZ());
542 theTris->AddVertex (aHSizeDir + myBoxFacetExtension * gp_Dir (0.0, 0.0, aDir.Z()).XYZ());
543
544 const gp_XYZ aNode1 = theTris->Vertice (aVertFirst + 1).XYZ();
545 const gp_XYZ aNode2 = theTris->Vertice (aVertFirst + 2).XYZ();
546 const gp_XYZ aNode3 = theTris->Vertice (aVertFirst + 3).XYZ();
547 const gp_XYZ aNormTri = ((aNode2 - aNode1).Crossed (aNode3 - aNode1));
548 if (aNormTri.Dot (aDir.XYZ()) < 0.0)
549 {
550 theTris->AddTriangleEdges (aVertFirst + 1, aVertFirst + 3, aVertFirst + 2);
551 }
552 else
553 {
554 theTris->AddTriangleEdges (aVertFirst + 1, aVertFirst + 2, aVertFirst + 3);
555 }
556 }
557
558 for (Standard_Integer aVertIter = aVertFirst + 1; aVertIter <= theTris->VertexNumber(); ++aVertIter)
559 {
560 theTris->SetVertexNormal (aVertIter, aDir);
561 }
562 }
563
564 //=======================================================================
565 //function : Compute
566 //purpose :
567 //=======================================================================
Compute(const Handle (PrsMgr_PresentationManager)&,const Handle (Prs3d_Presentation)& thePrs,const Standard_Integer theMode)568 void AIS_ViewCube::Compute (const Handle(PrsMgr_PresentationManager)& ,
569 const Handle(Prs3d_Presentation)& thePrs,
570 const Standard_Integer theMode)
571 {
572 thePrs->SetInfiniteState (true);
573 if (theMode != 0)
574 {
575 return;
576 }
577
578 const gp_Pnt aLocation = (mySize * 0.5 + myBoxFacetExtension + myAxesPadding) * gp_XYZ (-1.0, -1.0, -1.0);
579
580 // Display axes
581 if (myToDisplayAxes)
582 {
583 const Standard_Real anAxisSize = mySize + 2.0 * myBoxFacetExtension + myAxesPadding;
584 const Handle(Prs3d_DatumAspect)& aDatumAspect = myDrawer->DatumAspect();
585 for (Standard_Integer anAxisIter = Prs3d_DatumParts_XAxis; anAxisIter <= Prs3d_DatumParts_ZAxis; ++anAxisIter)
586 {
587 const Prs3d_DatumParts aPart = (Prs3d_DatumParts )anAxisIter;
588 if (!aDatumAspect->DrawDatumPart (aPart))
589 {
590 continue;
591 }
592
593 gp_Ax1 anAx1;
594 switch (aPart)
595 {
596 case Prs3d_DatumParts_XAxis: anAx1 = gp_Ax1 (aLocation, gp::DX()); break;
597 case Prs3d_DatumParts_YAxis: anAx1 = gp_Ax1 (aLocation, gp::DY()); break;
598 case Prs3d_DatumParts_ZAxis: anAx1 = gp_Ax1 (aLocation, gp::DZ()); break;
599 default: break;
600 }
601
602 Handle(Graphic3d_Group) anAxisGroup = thePrs->NewGroup();
603 anAxisGroup->SetClosed (true);
604 anAxisGroup->SetGroupPrimitivesAspect (aDatumAspect->ShadingAspect (aPart)->Aspect());
605
606 const Standard_Real anArrowLength = 0.2 * anAxisSize;
607 Handle(Graphic3d_ArrayOfTriangles) aTriangleArray = Prs3d_Arrow::DrawShaded (anAx1, myAxesRadius, anAxisSize, myAxesConeRadius, anArrowLength, THE_NB_ARROW_FACETTES);
608 anAxisGroup->AddPrimitiveArray (aTriangleArray);
609
610 TCollection_AsciiString anAxisLabel;
611 if (aDatumAspect->ToDrawLabels()
612 && myAxesLabels.Find (aPart, anAxisLabel)
613 && !anAxisLabel.IsEmpty())
614 {
615 Handle(Graphic3d_Group) anAxisLabelGroup = thePrs->NewGroup();
616 gp_Pnt aTextOrigin = anAx1.Location().Translated (gp_Vec (anAx1.Direction().X() * (anAxisSize + anArrowLength),
617 anAx1.Direction().Y() * (anAxisSize + anArrowLength),
618 anAx1.Direction().Z() * (anAxisSize + anArrowLength)));
619 Prs3d_Text::Draw (anAxisLabelGroup, aDatumAspect->TextAspect (aPart), TCollection_ExtendedString (anAxisLabel), aTextOrigin);
620 }
621 }
622
623 // Display center
624 {
625 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
626 aGroup->SetClosed (true);
627 Handle(Prs3d_ShadingAspect) anAspectCen = new Prs3d_ShadingAspect();
628 anAspectCen->SetColor (Quantity_NOC_WHITE);
629 aGroup->SetGroupPrimitivesAspect (anAspectCen->Aspect());
630 Prs3d_ToolSphere aTool (myAxesSphereRadius, THE_NB_DISK_SLICES, THE_NB_DISK_SLICES);
631 gp_Trsf aTrsf;
632 aTrsf.SetTranslation (gp_Vec (gp::Origin(), aLocation));
633 Handle(Graphic3d_ArrayOfTriangles) aCenterArray;
634 aTool.FillArray (aCenterArray, aTrsf);
635 aGroup->AddPrimitiveArray (aCenterArray);
636 }
637 }
638
639 // Display box sides
640 {
641 Standard_Integer aNbNodes = 0, aNbTris = 0;
642 for (Standard_Integer aPartIter = V3d_Xpos; aPartIter <= Standard_Integer(V3d_Zneg); ++aPartIter)
643 {
644 createBoxPartTriangles (Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris, (V3d_TypeOfOrientation )aPartIter);
645 }
646 if (aNbNodes > 0)
647 {
648 Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_VertexNormal);
649 Handle(Graphic3d_ArrayOfSegments) aSegs;
650 if (myDrawer->FaceBoundaryDraw())
651 {
652 aSegs = new Graphic3d_ArrayOfSegments (aNbNodes, aNbNodes * 2, Graphic3d_ArrayFlags_None);
653 }
654 aNbNodes = aNbTris = 0;
655 for (Standard_Integer aPartIter = V3d_Xpos; aPartIter <= Standard_Integer(V3d_Zneg); ++aPartIter)
656 {
657 Standard_Integer aTriNodesFrom = aTris->VertexNumber();
658 const Standard_Integer aTriFrom = aNbTris;
659 createBoxPartTriangles (aTris, aNbNodes, aNbTris, (V3d_TypeOfOrientation )aPartIter);
660 if (aSegs.IsNull())
661 {
662 continue;
663 }
664
665 const Standard_Integer aFirstNode = aSegs->VertexNumber();
666 for (Standard_Integer aVertIter = (aNbTris - aTriFrom) > 2 ? aTriNodesFrom + 2 : aTriNodesFrom + 1; // skip triangle fan center
667 aVertIter <= aTris->VertexNumber(); ++aVertIter)
668 {
669 aSegs->AddVertex (aTris->Vertice (aVertIter));
670 }
671 aSegs->AddPolylineEdges (aFirstNode + 1, aSegs->VertexNumber(), true);
672 }
673
674 {
675 Handle(Graphic3d_Group) aGroupSides = thePrs->NewGroup();
676 aGroupSides->SetClosed (true);
677 aGroupSides->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
678 aGroupSides->AddPrimitiveArray (aTris);
679 }
680
681 if (!aSegs.IsNull())
682 {
683 Handle(Graphic3d_Group) aGroupSegs = thePrs->NewGroup();
684 aGroupSegs->SetGroupPrimitivesAspect (myDrawer->FaceBoundaryAspect()->Aspect());
685 aGroupSegs->AddPrimitiveArray (aSegs);
686 }
687 }
688
689 // Display box sides labels
690 Handle(Graphic3d_Group) aTextGroup = thePrs->NewGroup();
691 aTextGroup->SetGroupPrimitivesAspect (myDrawer->TextAspect()->Aspect());
692 for (Standard_Integer aPartIter = V3d_Xpos; aPartIter <= Standard_Integer(V3d_Zneg); ++aPartIter)
693 {
694 const V3d_TypeOfOrientation anOrient = (V3d_TypeOfOrientation )aPartIter;
695
696 TCollection_AsciiString aLabel;
697 if (!myBoxSideLabels.Find (anOrient, aLabel)
698 || aLabel.IsEmpty())
699 {
700 continue;
701 }
702
703 const gp_Dir aDir = V3d::GetProjAxis (anOrient);
704 gp_Dir anUp = myIsYup ? gp::DY() : gp::DZ();
705 if (myIsYup)
706 {
707 if (anOrient == V3d_Ypos
708 || anOrient == V3d_Yneg)
709 {
710 anUp = -gp::DZ();
711 }
712 }
713 else
714 {
715 if (anOrient == V3d_Zpos)
716 {
717 anUp = gp::DY();
718 }
719 else if (anOrient == V3d_Zneg)
720 {
721 anUp = -gp::DY();
722 }
723 }
724
725 const Standard_Real anOffset = 2.0; // extra offset to avoid overlapping with triangulation
726 const gp_Pnt aPos = aDir.XYZ() * (mySize * 0.5 + myBoxFacetExtension + anOffset);
727 const gp_Ax2 aPosition (aPos, aDir, anUp.Crossed (aDir));
728
729 Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)myDrawer->TextAspect()->Height());
730 aText->SetText (aLabel);
731 aText->SetOrientation (aPosition);
732 aText->SetOwnAnchorPoint (false);
733 aText->SetHorizontalAlignment(myDrawer->TextAspect()->HorizontalJustification());
734 aText->SetVerticalAlignment (myDrawer->TextAspect()->VerticalJustification());
735 aTextGroup->AddText (aText);
736 }
737 }
738
739 // Display box edges
740 {
741 Standard_Integer aNbNodes = 0, aNbTris = 0;
742 for (Standard_Integer aPartIter = V3d_XposYpos; aPartIter <= Standard_Integer(V3d_YposZneg); ++aPartIter)
743 {
744 createBoxPartTriangles (Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris, (V3d_TypeOfOrientation )aPartIter);
745 }
746 if (aNbNodes > 0)
747 {
748 Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_VertexNormal);
749 aNbNodes = aNbTris = 0;
750 for (Standard_Integer aPartIter = V3d_XposYpos; aPartIter <= Standard_Integer(V3d_YposZneg); ++aPartIter)
751 {
752 const V3d_TypeOfOrientation anOrient = (V3d_TypeOfOrientation )aPartIter;
753 createBoxPartTriangles (aTris, aNbNodes, aNbTris, anOrient);
754 }
755
756 Handle(Graphic3d_Group) aGroupEdges = thePrs->NewGroup();
757 aGroupEdges->SetClosed (true);
758 aGroupEdges->SetGroupPrimitivesAspect (myBoxEdgeAspect->Aspect());
759 aGroupEdges->AddPrimitiveArray (aTris);
760 }
761 }
762
763 // Display box corners
764 {
765 Standard_Integer aNbNodes = 0, aNbTris = 0;
766 for (Standard_Integer aPartIter = V3d_XposYposZpos; aPartIter <= Standard_Integer(V3d_XnegYnegZneg); ++aPartIter)
767 {
768 createBoxPartTriangles (Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris, (V3d_TypeOfOrientation )aPartIter);
769 }
770 if (aNbNodes > 0)
771 {
772 Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_VertexNormal);
773 aNbNodes = aNbTris = 0;
774 for (Standard_Integer aPartIter = V3d_XposYposZpos; aPartIter <= Standard_Integer(V3d_XnegYnegZneg); ++aPartIter)
775 {
776 const V3d_TypeOfOrientation anOrient = (V3d_TypeOfOrientation )aPartIter;
777 createBoxPartTriangles (aTris, aNbNodes, aNbTris, anOrient);
778 }
779
780 Handle(Graphic3d_Group) aGroupCorners = thePrs->NewGroup();
781 aGroupCorners->SetClosed (true);
782 aGroupCorners->SetGroupPrimitivesAspect (myBoxCornerAspect->Aspect());
783 aGroupCorners->AddPrimitiveArray (aTris);
784 }
785 }
786 }
787
788 //=======================================================================
789 //function : ComputeSelection
790 //purpose :
791 //=======================================================================
ComputeSelection(const Handle (SelectMgr_Selection)& theSelection,const Standard_Integer theMode)792 void AIS_ViewCube::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
793 const Standard_Integer theMode)
794 {
795 if (theMode != 0)
796 {
797 return;
798 }
799
800 for (Standard_Integer aPartIter = 0; aPartIter <= Standard_Integer(V3d_XnegYnegZneg); ++aPartIter)
801 {
802 const V3d_TypeOfOrientation anOri = (V3d_TypeOfOrientation )aPartIter;
803 Standard_Integer aNbNodes = 0, aNbTris = 0;
804 createBoxPartTriangles (Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris, anOri);
805 if (aNbNodes <= 0)
806 {
807 continue;
808 }
809
810 Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_None);
811 aNbNodes = aNbTris = 0;
812 createBoxPartTriangles (aTris, aNbNodes, aNbTris, anOri);
813
814 Standard_Integer aSensitivity = 2;
815 if (IsBoxCorner (anOri))
816 {
817 aSensitivity = 8;
818 }
819 else if (IsBoxEdge (anOri))
820 {
821 aSensitivity = 4;
822 }
823 Handle(AIS_ViewCubeOwner) anOwner = new AIS_ViewCubeOwner (this, anOri);
824 Handle(AIS_ViewCubeSensitive) aTriSens = new AIS_ViewCubeSensitive (anOwner, aTris);
825 aTriSens->SetSensitivityFactor (aSensitivity);
826 theSelection->Add (aTriSens);
827 }
828 }
829
830 //=======================================================================
831 //function : Duration
832 //purpose :
833 //=======================================================================
Duration() const834 Standard_Real AIS_ViewCube::Duration() const
835 {
836 return myViewAnimation->OwnDuration();
837 }
838
839 //=======================================================================
840 //function : SetDuration
841 //purpose :
842 //=======================================================================
SetDuration(Standard_Real theDurationSec)843 void AIS_ViewCube::SetDuration (Standard_Real theDurationSec)
844 {
845 myViewAnimation->SetOwnDuration (theDurationSec);
846 }
847
848 //=======================================================================
849 //function : HasAnimation
850 //purpose :
851 //=======================================================================
HasAnimation() const852 Standard_Boolean AIS_ViewCube::HasAnimation() const
853 {
854 return !myViewAnimation->IsStopped();
855 }
856
857 //=======================================================================
858 //function : viewFitAll
859 //purpose :
860 //=======================================================================
viewFitAll(const Handle (V3d_View)& theView,const Handle (Graphic3d_Camera)& theCamera)861 void AIS_ViewCube::viewFitAll (const Handle(V3d_View)& theView,
862 const Handle(Graphic3d_Camera)& theCamera)
863 {
864 Bnd_Box aBndBox = myToFitSelected ? GetContext()->BoundingBoxOfSelection() : theView->View()->MinMaxValues();
865 if (aBndBox.IsVoid()
866 && myToFitSelected)
867 {
868 aBndBox = theView->View()->MinMaxValues();
869 }
870 if (!aBndBox.IsVoid())
871 {
872 theView->FitMinMax (theCamera, aBndBox, 0.01, 10.0 * Precision::Confusion());
873 }
874 }
875
876 //=======================================================================
877 //function : StartAnimation
878 //purpose :
879 //=======================================================================
StartAnimation(const Handle (AIS_ViewCubeOwner)& theOwner)880 void AIS_ViewCube::StartAnimation (const Handle(AIS_ViewCubeOwner)& theOwner)
881 {
882 Handle(V3d_View) aView = GetContext()->LastActiveView();
883 if (theOwner.IsNull()
884 || aView.IsNull())
885 {
886 return;
887 }
888
889 myStartState->Copy (aView->Camera());
890 myEndState ->Copy (aView->Camera());
891
892 {
893 {
894 Handle(Graphic3d_Camera) aBackupCamera = aView->Camera();
895 const bool wasImmediateUpdate = aView->SetImmediateUpdate (false);
896 aView->SetCamera (myEndState);
897 aView->SetProj (theOwner->MainOrientation(), myIsYup);
898 aView->SetCamera (aBackupCamera);
899 aView->SetImmediateUpdate (wasImmediateUpdate);
900 }
901
902 const gp_Dir aNewDir = myEndState->Direction();
903 if (!myToResetCameraUp
904 && !aNewDir.IsEqual (myStartState->Direction(), Precision::Angular()))
905 {
906 // find the Up direction closest to current instead of default one
907 const gp_Ax1 aNewDirAx1 (gp::Origin(), aNewDir);
908 const gp_Dir anOldUp = myStartState->Up();
909 const gp_Dir anUpList[4] =
910 {
911 myEndState->Up(),
912 myEndState->Up().Rotated (aNewDirAx1, M_PI_2),
913 myEndState->Up().Rotated (aNewDirAx1, M_PI),
914 myEndState->Up().Rotated (aNewDirAx1, M_PI * 1.5),
915 };
916
917 Standard_Real aBestAngle = Precision::Infinite();
918 gp_Dir anUpBest;
919 for (Standard_Integer anUpIter = 0; anUpIter < 4; ++anUpIter)
920 {
921 Standard_Real anAngle = anUpList[anUpIter].Angle (anOldUp);
922 if (aBestAngle > anAngle)
923 {
924 aBestAngle = anAngle;
925 anUpBest = anUpList[anUpIter];
926 }
927 }
928 myEndState->SetUp (anUpBest);
929 }
930
931 viewFitAll (aView, myEndState);
932 }
933
934 myViewAnimation->SetView (aView);
935 myViewAnimation->SetCameraStart (myStartState);
936 myViewAnimation->SetCameraEnd (myEndState);
937 myViewAnimation->StartTimer (0.0, 1.0, true, false);
938 }
939
940 //=======================================================================
941 //function : updateAnimation
942 //purpose :
943 //=======================================================================
updateAnimation()944 Standard_Boolean AIS_ViewCube::updateAnimation()
945 {
946 const Standard_Real aPts = myViewAnimation->UpdateTimer();
947 if (aPts >= myViewAnimation->OwnDuration())
948 {
949 myViewAnimation->Stop();
950 onAnimationFinished();
951 myViewAnimation->SetView (Handle(V3d_View)());
952 return Standard_False;
953 }
954 return Standard_True;
955 }
956
957 //=======================================================================
958 //function : UpdateAnimation
959 //purpose :
960 //=======================================================================
UpdateAnimation(const Standard_Boolean theToUpdate)961 Standard_Boolean AIS_ViewCube::UpdateAnimation (const Standard_Boolean theToUpdate)
962 {
963 Handle(V3d_View) aView = myViewAnimation->View();
964 if (!HasAnimation()
965 || !updateAnimation())
966 {
967 return Standard_False;
968 }
969
970 if (theToUpdate
971 && !aView.IsNull())
972 {
973 aView->IsInvalidated() ? aView->Redraw() : aView->RedrawImmediate();
974 }
975
976 onAfterAnimation();
977 return Standard_True;
978 }
979
980 //=======================================================================
981 //function : HandleClick
982 //purpose :
983 //=======================================================================
HandleClick(const Handle (AIS_ViewCubeOwner)& theOwner)984 void AIS_ViewCube::HandleClick (const Handle(AIS_ViewCubeOwner)& theOwner)
985 {
986 if (!myToAutoStartAnim)
987 {
988 return;
989 }
990
991 StartAnimation (theOwner);
992 if (!myIsFixedAnimation)
993 {
994 return;
995 }
996 for (; HasAnimation(); )
997 {
998 UpdateAnimation (true);
999 }
1000 }
1001
1002 //=======================================================================
1003 //function : HilightOwnerWithColor
1004 //purpose :
1005 //=======================================================================
HilightOwnerWithColor(const Handle (PrsMgr_PresentationManager)& thePrsMgr,const Handle (Prs3d_Drawer)& theStyle,const Handle (SelectMgr_EntityOwner)& theOwner)1006 void AIS_ViewCube::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
1007 const Handle(Prs3d_Drawer)& theStyle,
1008 const Handle(SelectMgr_EntityOwner)& theOwner)
1009 {
1010 if (theOwner.IsNull()
1011 || !thePrsMgr->IsImmediateModeOn())
1012 {
1013 return;
1014 }
1015
1016 const Graphic3d_ZLayerId aLayer = theStyle->ZLayer() != Graphic3d_ZLayerId_UNKNOWN ? theStyle->ZLayer() : myDrawer->ZLayer();
1017 const AIS_ViewCubeOwner* aCubeOwner = dynamic_cast<AIS_ViewCubeOwner* >(theOwner.get());
1018
1019 Handle(Prs3d_Presentation) aHiPrs = GetHilightPresentation (thePrsMgr);
1020 aHiPrs->Clear();
1021 aHiPrs->CStructure()->ViewAffinity = thePrsMgr->StructureManager()->ObjectAffinity (Handle(Standard_Transient)(this));
1022 aHiPrs->SetTransformPersistence (TransformPersistence());
1023 aHiPrs->SetZLayer (aLayer);
1024
1025 {
1026 Handle(Graphic3d_Group) aGroup = aHiPrs->NewGroup();
1027 aGroup->SetGroupPrimitivesAspect (theStyle->ShadingAspect()->Aspect());
1028 Standard_Integer aNbNodes = 0, aNbTris = 0;
1029 createBoxPartTriangles (Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris, aCubeOwner->MainOrientation());
1030 if (aNbNodes > 0)
1031 {
1032 Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_None);
1033 aNbNodes = aNbTris = 0;
1034 createBoxPartTriangles (aTris, aNbNodes, aNbTris, aCubeOwner->MainOrientation());
1035 aGroup->AddPrimitiveArray (aTris);
1036 }
1037 }
1038
1039 if (thePrsMgr->IsImmediateModeOn())
1040 {
1041 thePrsMgr->AddToImmediateList (aHiPrs);
1042 }
1043 }
1044
1045 //=======================================================================
1046 //function : HilightSelected
1047 //purpose :
1048 //=======================================================================
HilightSelected(const Handle (PrsMgr_PresentationManager)&,const SelectMgr_SequenceOfOwner & theSeq)1049 void AIS_ViewCube::HilightSelected (const Handle(PrsMgr_PresentationManager)& ,
1050 const SelectMgr_SequenceOfOwner& theSeq)
1051 {
1052 // this method should never be called since AIS_InteractiveObject::HandleClick() has been overridden
1053 if (theSeq.Size() == 1)
1054 {
1055 //HandleClick (Handle(AIS_ViewCubeOwner)::DownCast (theSeq.First()));
1056 }
1057 }
1058