0031458: Visualization - refine classes across Prs3d and StdPrs packages
[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()),
152 myDuration (0.5),
153 myToAutoStartAnim (true),
154 myIsFixedAnimation (true),
155 myToFitSelected (true),
156 myToResetCameraUp (false)
157{
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//=======================================================================
828//function : HasAnimation
829//purpose :
830//=======================================================================
831Standard_Boolean AIS_ViewCube::HasAnimation() const
832{
833 return !myViewAnimation->IsStopped();
834}
835
caa309aa 836//=======================================================================
837//function : viewFitAll
838//purpose :
839//=======================================================================
840void AIS_ViewCube::viewFitAll (const Handle(V3d_View)& theView,
841 const Handle(Graphic3d_Camera)& theCamera)
842{
843 Bnd_Box aBndBox = myToFitSelected ? GetContext()->BoundingBoxOfSelection() : theView->View()->MinMaxValues();
844 if (aBndBox.IsVoid()
845 && myToFitSelected)
846 {
847 aBndBox = theView->View()->MinMaxValues();
848 }
849 if (!aBndBox.IsVoid())
850 {
851 theView->FitMinMax (theCamera, aBndBox, 0.01, 10.0 * Precision::Confusion());
852 }
853}
854
2108d9a2 855//=======================================================================
856//function : StartAnimation
857//purpose :
858//=======================================================================
859void AIS_ViewCube::StartAnimation (const Handle(AIS_ViewCubeOwner)& theOwner)
860{
861 Handle(V3d_View) aView = GetContext()->LastActiveView();
862 if (theOwner.IsNull()
863 || aView.IsNull())
864 {
865 return;
866 }
867
868 myStartState->Copy (aView->Camera());
869 myEndState ->Copy (aView->Camera());
870
871 {
caa309aa 872 {
873 Handle(Graphic3d_Camera) aBackupCamera = aView->Camera();
874 const bool wasImmediateUpdate = aView->SetImmediateUpdate (false);
875 aView->SetCamera (myEndState);
876 aView->SetProj (theOwner->MainOrientation(), myIsYup);
877 aView->SetCamera (aBackupCamera);
878 aView->SetImmediateUpdate (wasImmediateUpdate);
879 }
2108d9a2 880
caa309aa 881 const gp_Dir aNewDir = myEndState->Direction();
2108d9a2 882 if (!myToResetCameraUp
caa309aa 883 && !aNewDir.IsEqual (myStartState->Direction(), Precision::Angular()))
2108d9a2 884 {
885 // find the Up direction closest to current instead of default one
886 const gp_Ax1 aNewDirAx1 (gp::Origin(), aNewDir);
caa309aa 887 const gp_Dir anOldUp = myStartState->Up();
2108d9a2 888 const gp_Dir anUpList[4] =
889 {
caa309aa 890 myEndState->Up(),
891 myEndState->Up().Rotated (aNewDirAx1, M_PI_2),
892 myEndState->Up().Rotated (aNewDirAx1, M_PI),
893 myEndState->Up().Rotated (aNewDirAx1, M_PI * 1.5),
2108d9a2 894 };
895
896 Standard_Real aBestAngle = Precision::Infinite();
897 gp_Dir anUpBest;
898 for (Standard_Integer anUpIter = 0; anUpIter < 4; ++anUpIter)
899 {
900 Standard_Real anAngle = anUpList[anUpIter].Angle (anOldUp);
901 if (aBestAngle > anAngle)
902 {
903 aBestAngle = anAngle;
904 anUpBest = anUpList[anUpIter];
905 }
906 }
caa309aa 907 myEndState->SetUp (anUpBest);
2108d9a2 908 }
909
caa309aa 910 viewFitAll (aView, myEndState);
2108d9a2 911 }
912
913 myViewAnimation->SetView (aView);
914 myViewAnimation->SetCameraStart (myStartState);
915 myViewAnimation->SetCameraEnd (myEndState);
916 myViewAnimation->SetOwnDuration (myDuration);
917 myViewAnimation->StartTimer (0.0, 1.0, true, false);
918}
919
920//=======================================================================
921//function : updateAnimation
922//purpose :
923//=======================================================================
924Standard_Boolean AIS_ViewCube::updateAnimation()
925{
926 const Standard_Real aPts = myViewAnimation->UpdateTimer();
927 if (aPts >= myDuration)
928 {
929 myViewAnimation->Stop();
930 onAnimationFinished();
931 myViewAnimation->SetView (Handle(V3d_View)());
932 return Standard_False;
933 }
934 return Standard_True;
935}
936
937//=======================================================================
938//function : UpdateAnimation
939//purpose :
940//=======================================================================
941Standard_Boolean AIS_ViewCube::UpdateAnimation (const Standard_Boolean theToUpdate)
942{
943 Handle(V3d_View) aView = myViewAnimation->View();
944 if (!HasAnimation()
945 || !updateAnimation())
946 {
947 return Standard_False;
948 }
949
950 if (theToUpdate
951 && !aView.IsNull())
952 {
953 aView->IsInvalidated() ? aView->Redraw() : aView->RedrawImmediate();
954 }
955
956 onAfterAnimation();
957 return Standard_True;
958}
959
960//=======================================================================
961//function : HandleClick
962//purpose :
963//=======================================================================
964void AIS_ViewCube::HandleClick (const Handle(AIS_ViewCubeOwner)& theOwner)
965{
966 if (!myToAutoStartAnim)
967 {
968 return;
969 }
970
971 StartAnimation (theOwner);
972 if (!myIsFixedAnimation)
973 {
974 return;
975 }
976 for (; HasAnimation(); )
977 {
978 UpdateAnimation (true);
979 }
980}
981
982//=======================================================================
983//function : HilightOwnerWithColor
984//purpose :
985//=======================================================================
986void AIS_ViewCube::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
987 const Handle(Prs3d_Drawer)& theStyle,
988 const Handle(SelectMgr_EntityOwner)& theOwner)
989{
990 if (theOwner.IsNull()
991 || !thePrsMgr->IsImmediateModeOn())
992 {
993 return;
994 }
995
996 const Graphic3d_ZLayerId aLayer = theStyle->ZLayer() != Graphic3d_ZLayerId_UNKNOWN ? theStyle->ZLayer() : myDrawer->ZLayer();
997 const AIS_ViewCubeOwner* aCubeOwner = dynamic_cast<AIS_ViewCubeOwner* >(theOwner.get());
998
999 Handle(Prs3d_Presentation) aHiPrs = GetHilightPresentation (thePrsMgr);
1000 aHiPrs->Clear();
1001 aHiPrs->CStructure()->ViewAffinity = thePrsMgr->StructureManager()->ObjectAffinity (Handle(Standard_Transient)(this));
1002 aHiPrs->SetTransformPersistence (TransformPersistence());
1003 aHiPrs->SetZLayer (aLayer);
1004
1005 {
1006 Handle(Graphic3d_Group) aGroup = aHiPrs->NewGroup();
1007 aGroup->SetGroupPrimitivesAspect (theStyle->ShadingAspect()->Aspect());
caa309aa 1008 Standard_Integer aNbNodes = 0, aNbTris = 0;
1009 createBoxPartTriangles (Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris, aCubeOwner->MainOrientation());
1010 if (aNbNodes > 0)
2108d9a2 1011 {
caa309aa 1012 Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_None);
1013 aNbNodes = aNbTris = 0;
1014 createBoxPartTriangles (aTris, aNbNodes, aNbTris, aCubeOwner->MainOrientation());
2108d9a2 1015 aGroup->AddPrimitiveArray (aTris);
1016 }
1017 }
1018
1019 if (thePrsMgr->IsImmediateModeOn())
1020 {
1021 thePrsMgr->AddToImmediateList (aHiPrs);
1022 }
1023}
1024
1025//=======================================================================
1026//function : HilightSelected
1027//purpose :
1028//=======================================================================
1029void AIS_ViewCube::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& ,
1030 const SelectMgr_SequenceOfOwner& theSeq)
1031{
1032 // this method should never be called since AIS_InteractiveObject::HandleClick() has been overridden
1033 if (theSeq.Size() == 1)
1034 {
1035 //HandleClick (Handle(AIS_ViewCubeOwner)::DownCast (theSeq.First()));
1036 }
1037}