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