1 // Created on: 2018-12-12
2 // Created by: Olga SURYANINOVA
3 // Copyright (c) 2018 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <AIS_CameraFrustum.hxx>
18 #include <AIS_DisplayMode.hxx>
19 #include <Graphic3d_ArrayOfTriangles.hxx>
20 #include <Graphic3d_ArrayOfSegments.hxx>
21 #include <Prs3d_LineAspect.hxx>
22 #include <Prs3d_ShadingAspect.hxx>
23 #include <Select3D_SensitiveGroup.hxx>
24 #include <Select3D_SensitivePrimitiveArray.hxx>
25 #include <Select3D_SensitiveSegment.hxx>
26 #include <SelectMgr_EntityOwner.hxx>
28 IMPLEMENT_STANDARD_RTTIEXT(AIS_CameraFrustum, AIS_InteractiveObject)
32 static const Standard_ShortReal THE_DEFAULT_TRANSPARENCY = 0.7f;
33 static const Quantity_Color THE_DEFAULT_COLOR = Quantity_NOC_WHITE;
36 //=======================================================================
37 //function : Constructor
39 //=======================================================================
40 AIS_CameraFrustum::AIS_CameraFrustum()
41 : myPoints (0, Graphic3d_Camera::FrustumVerticesNB)
43 myDrawer->SetLineAspect (new Prs3d_LineAspect (THE_DEFAULT_COLOR, Aspect_TOL_SOLID, 1.0));
45 Handle(Prs3d_ShadingAspect) aShadingAspect = new Prs3d_ShadingAspect();
46 aShadingAspect->SetMaterial (Graphic3d_NOM_PLASTIC);
47 aShadingAspect->Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Blend);
48 aShadingAspect->SetTransparency (THE_DEFAULT_TRANSPARENCY);
49 aShadingAspect->SetColor (THE_DEFAULT_COLOR);
50 myDrawer->SetShadingAspect (aShadingAspect);
52 myDrawer->SetTransparency (THE_DEFAULT_TRANSPARENCY);
53 SetDisplayMode (AIS_Shaded);
56 //=======================================================================
57 //function : AcceptDisplayMode
59 //=======================================================================
60 Standard_Boolean AIS_CameraFrustum::AcceptDisplayMode (const Standard_Integer theMode) const
62 return theMode == AIS_Shaded || theMode == AIS_WireFrame;
65 //=======================================================================
66 //function : SetCameraFrustum
68 //=======================================================================
69 void AIS_CameraFrustum::SetCameraFrustum (const Handle(Graphic3d_Camera)& theCamera)
71 if (theCamera.IsNull())
76 theCamera->FrustumPoints (myPoints);
84 //=======================================================================
87 //=======================================================================
88 void AIS_CameraFrustum::SetColor (const Quantity_Color& theColor)
90 AIS_InteractiveObject::SetColor (theColor);
91 myDrawer->ShadingAspect()->SetColor (theColor);
92 myDrawer->LineAspect()->SetColor (theColor);
95 //=======================================================================
96 //function : UnsetColor
98 //=======================================================================
99 void AIS_CameraFrustum::UnsetColor()
106 AIS_InteractiveObject::UnsetColor();
108 myDrawer->ShadingAspect()->SetColor (THE_DEFAULT_COLOR);
109 myDrawer->LineAspect()->SetColor (THE_DEFAULT_COLOR);
112 //=======================================================================
113 //function : UnsetColor
115 //=======================================================================
116 void AIS_CameraFrustum::UnsetTransparency()
118 myDrawer->ShadingAspect()->SetTransparency (0.0f);
119 myDrawer->SetTransparency (0.0f);
122 //=======================================================================
123 //function : fillTriangles
125 //=======================================================================
126 void AIS_CameraFrustum::fillTriangles()
128 if (myTriangles.IsNull())
130 const Standard_Integer aPlaneTriangleVertsNb = 2 * 3;
131 const Standard_Integer aPlanesNb = 3 * 2;
133 myTriangles = new Graphic3d_ArrayOfTriangles (Graphic3d_Camera::FrustumVerticesNB, aPlaneTriangleVertsNb * aPlanesNb);
134 myTriangles->SetVertice (Graphic3d_Camera::FrustumVerticesNB, gp_Pnt (0.0, 0.0, 0.0));
136 // Triangles go in order (clockwise vertices traversing for correct normal):
137 // (0, 2, 1), (3, 1, 2)
138 const Standard_Integer aLookup1_clockwise[] = { 0, 1, 0, 1, 0, 1 };
139 const Standard_Integer aLookup2_clockwise[] = { 0, 0, 1, 1, 1, 0 };
140 // Triangles go in order (counterclockwise vertices traversing for correct normal):
141 // (1, 2, 0), (2, 1, 3)
142 const Standard_Integer aLookup1_anticlockwise[] = { 0, 1, 0, 1, 0, 1 };
143 const Standard_Integer aLookup2_anticlockwise[] = { 1, 0, 0, 0, 1, 1 };
144 Standard_Integer aShifts[] = { 0, 0, 0 };
146 // Planes go in order:
147 // LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
148 for (Standard_Integer aFaceIdx = 0; aFaceIdx < 3; ++aFaceIdx)
150 for (Standard_Integer i = 0; i < 2; ++i)
152 for (Standard_Integer aPntIter = 0; aPntIter < aPlaneTriangleVertsNb; ++aPntIter)
154 aShifts[aFaceIdx] = i;
157 aShifts[(aFaceIdx + 1) % 3] = aLookup1_clockwise[aPntIter];
158 aShifts[(aFaceIdx + 2) % 3] = aLookup2_clockwise[aPntIter];
162 aShifts[(aFaceIdx + 1) % 3] = aLookup1_anticlockwise[aPntIter];
163 aShifts[(aFaceIdx + 2) % 3] = aLookup2_anticlockwise[aPntIter];
166 Standard_Integer anIndex = aShifts[0] * 2 * 2 + aShifts[1] * 2 + aShifts[2];
167 myTriangles->AddEdge (anIndex + 1);
173 for (Standard_Integer aPointIter = 0; aPointIter < Graphic3d_Camera::FrustumVerticesNB; ++aPointIter)
175 const Graphic3d_Vec3d aPnt = myPoints[aPointIter];
176 myTriangles->SetVertice (aPointIter + 1, gp_Pnt (aPnt.x(), aPnt.y(), aPnt.z()));
180 //=======================================================================
181 //function : fillBorders
183 //=======================================================================
184 void AIS_CameraFrustum::fillBorders()
186 if (myBorders.IsNull())
188 const Standard_Integer aPlaneSegmVertsNb = 2 * 4;
189 const Standard_Integer aPlanesNb = 3 * 2;
190 myBorders = new Graphic3d_ArrayOfSegments (Graphic3d_Camera::FrustumVerticesNB, aPlaneSegmVertsNb * aPlanesNb);
191 myBorders->SetVertice (Graphic3d_Camera::FrustumVerticesNB, gp_Pnt (0.0, 0.0, 0.0));
193 // Segments go in order:
194 // (0, 2), (2, 3), (3, 1), (1, 0)
195 const Standard_Integer aLookup1[] = { 0, 1, 1, 1, 1, 0, 0, 0 };
196 const Standard_Integer aLookup2[] = { 0, 0, 0, 1, 1, 1, 1, 0 };
197 Standard_Integer aShifts[] = { 0, 0, 0 };
199 // Planes go in order:
200 // LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
201 for (Standard_Integer aFaceIdx = 0; aFaceIdx < 3; ++aFaceIdx)
203 for (Standard_Integer i = 0; i < 2; ++i)
205 for (Standard_Integer aSegmVertIter = 0; aSegmVertIter < aPlaneSegmVertsNb; ++aSegmVertIter)
207 aShifts[aFaceIdx] = i;
208 aShifts[(aFaceIdx + 1) % 3] = aLookup1[aSegmVertIter];
209 aShifts[(aFaceIdx + 2) % 3] = aLookup2[aSegmVertIter];
211 Standard_Integer anIndex = aShifts[0] * 2 * 2 + aShifts[1] * 2 + aShifts[2];
212 myBorders->AddEdge (anIndex + 1);
218 for (Standard_Integer aPointIter = 0; aPointIter < Graphic3d_Camera::FrustumVerticesNB; ++aPointIter)
220 const Graphic3d_Vec3d aPnt = myPoints[aPointIter];
221 myBorders->SetVertice (aPointIter + 1, gp_Pnt (aPnt.x(), aPnt.y(), aPnt.z()));
225 //=======================================================================
228 //=======================================================================
229 void AIS_CameraFrustum::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
230 const Handle(Prs3d_Presentation)& thePrs,
231 const Standard_Integer theMode)
233 thePrs->SetInfiniteState (true);
234 if (myTriangles.IsNull())
239 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
244 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
245 aGroup->AddPrimitiveArray (myTriangles);
250 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
251 aGroup->AddPrimitiveArray (myBorders);
257 //=======================================================================
258 //function : ComputeSelection
260 //=======================================================================
261 void AIS_CameraFrustum::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
262 const Standard_Integer theMode)
264 Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
267 case SelectionMode_Edges:
269 Handle(Select3D_SensitiveGroup) aSensitiveEntity = new Select3D_SensitiveGroup (anOwner);
270 for (Standard_Integer anIter = 1; anIter <= myBorders->EdgeNumber(); anIter += 2)
272 aSensitiveEntity->Add (new Select3D_SensitiveSegment (anOwner, myBorders->Vertice (myBorders->Edge (anIter)), myBorders->Vertice(myBorders->Edge (anIter + 1))));
274 theSelection->Add (aSensitiveEntity);
277 case SelectionMode_Volume:
279 Handle(Select3D_SensitivePrimitiveArray) aSelArray = new Select3D_SensitivePrimitiveArray (anOwner);
280 aSelArray->InitTriangulation (myTriangles->Attributes(), myTriangles->Indices(), TopLoc_Location());
281 theSelection->Add (aSelArray);