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