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