0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / AIS / AIS_CameraFrustum.cxx
CommitLineData
30a1b24e 1// Created on: 2018-12-12
2// Created by: Olga SURYANINOVA
3// Copyright (c) 2018 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_CameraFrustum.hxx>
17
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>
27
28IMPLEMENT_STANDARD_RTTIEXT(AIS_CameraFrustum, AIS_InteractiveObject)
29
30namespace
31{
32 static const Standard_ShortReal THE_DEFAULT_TRANSPARENCY = 0.7f;
33 static const Quantity_Color THE_DEFAULT_COLOR = Quantity_NOC_WHITE;
34}
35
36//=======================================================================
37//function : Constructor
38//purpose :
39//=======================================================================
40AIS_CameraFrustum::AIS_CameraFrustum()
41: myPoints (0, Graphic3d_Camera::FrustumVerticesNB)
42{
43 myDrawer->SetLineAspect (new Prs3d_LineAspect (THE_DEFAULT_COLOR, Aspect_TOL_SOLID, 1.0));
44
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);
51
52 myDrawer->SetTransparency (THE_DEFAULT_TRANSPARENCY);
53 SetDisplayMode (AIS_Shaded);
54}
55
56//=======================================================================
57//function : AcceptDisplayMode
58//purpose :
59//=======================================================================
60Standard_Boolean AIS_CameraFrustum::AcceptDisplayMode (const Standard_Integer theMode) const
61{
62 return theMode == AIS_Shaded || theMode == AIS_WireFrame;
63}
64
65//=======================================================================
66//function : SetCameraFrustum
67//purpose :
68//=======================================================================
69void AIS_CameraFrustum::SetCameraFrustum (const Handle(Graphic3d_Camera)& theCamera)
70{
71 if (theCamera.IsNull())
72 {
73 return;
74 }
75
76 theCamera->FrustumPoints (myPoints);
77
78 fillTriangles();
79 fillBorders();
80
81 SetToUpdate();
82}
83
84//=======================================================================
85//function : SetColor
86//purpose :
87//=======================================================================
88void AIS_CameraFrustum::SetColor (const Quantity_Color& theColor)
89{
90 AIS_InteractiveObject::SetColor (theColor);
91 myDrawer->ShadingAspect()->SetColor (theColor);
92 myDrawer->LineAspect()->SetColor (theColor);
226fce20 93 SynchronizeAspects();
30a1b24e 94}
95
96//=======================================================================
97//function : UnsetColor
98//purpose :
99//=======================================================================
100void AIS_CameraFrustum::UnsetColor()
101{
102 if (!HasColor())
103 {
104 return;
105 }
106
107 AIS_InteractiveObject::UnsetColor();
108
109 myDrawer->ShadingAspect()->SetColor (THE_DEFAULT_COLOR);
110 myDrawer->LineAspect()->SetColor (THE_DEFAULT_COLOR);
226fce20 111 SynchronizeAspects();
30a1b24e 112}
113
114//=======================================================================
115//function : UnsetColor
116//purpose :
117//=======================================================================
118void AIS_CameraFrustum::UnsetTransparency()
119{
120 myDrawer->ShadingAspect()->SetTransparency (0.0f);
121 myDrawer->SetTransparency (0.0f);
226fce20 122 SynchronizeAspects();
30a1b24e 123}
124
125//=======================================================================
126//function : fillTriangles
127//purpose :
128//=======================================================================
129void AIS_CameraFrustum::fillTriangles()
130{
131 if (myTriangles.IsNull())
132 {
133 const Standard_Integer aPlaneTriangleVertsNb = 2 * 3;
134 const Standard_Integer aPlanesNb = 3 * 2;
135
136 myTriangles = new Graphic3d_ArrayOfTriangles (Graphic3d_Camera::FrustumVerticesNB, aPlaneTriangleVertsNb * aPlanesNb);
137 myTriangles->SetVertice (Graphic3d_Camera::FrustumVerticesNB, gp_Pnt (0.0, 0.0, 0.0));
138
139 // Triangles go in order (clockwise vertices traversing for correct normal):
140 // (0, 2, 1), (3, 1, 2)
141 const Standard_Integer aLookup1_clockwise[] = { 0, 1, 0, 1, 0, 1 };
142 const Standard_Integer aLookup2_clockwise[] = { 0, 0, 1, 1, 1, 0 };
143 // Triangles go in order (counterclockwise vertices traversing for correct normal):
144 // (1, 2, 0), (2, 1, 3)
145 const Standard_Integer aLookup1_anticlockwise[] = { 0, 1, 0, 1, 0, 1 };
146 const Standard_Integer aLookup2_anticlockwise[] = { 1, 0, 0, 0, 1, 1 };
147 Standard_Integer aShifts[] = { 0, 0, 0 };
148
149 // Planes go in order:
150 // LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
151 for (Standard_Integer aFaceIdx = 0; aFaceIdx < 3; ++aFaceIdx)
152 {
153 for (Standard_Integer i = 0; i < 2; ++i)
154 {
155 for (Standard_Integer aPntIter = 0; aPntIter < aPlaneTriangleVertsNb; ++aPntIter)
156 {
157 aShifts[aFaceIdx] = i;
158 if (i == 0)
159 {
160 aShifts[(aFaceIdx + 1) % 3] = aLookup1_clockwise[aPntIter];
161 aShifts[(aFaceIdx + 2) % 3] = aLookup2_clockwise[aPntIter];
162 }
163 else
164 {
165 aShifts[(aFaceIdx + 1) % 3] = aLookup1_anticlockwise[aPntIter];
166 aShifts[(aFaceIdx + 2) % 3] = aLookup2_anticlockwise[aPntIter];
167 }
168
169 Standard_Integer anIndex = aShifts[0] * 2 * 2 + aShifts[1] * 2 + aShifts[2];
170 myTriangles->AddEdge (anIndex + 1);
171 }
172 }
173 }
174 }
175
176 for (Standard_Integer aPointIter = 0; aPointIter < Graphic3d_Camera::FrustumVerticesNB; ++aPointIter)
177 {
178 const Graphic3d_Vec3d aPnt = myPoints[aPointIter];
179 myTriangles->SetVertice (aPointIter + 1, gp_Pnt (aPnt.x(), aPnt.y(), aPnt.z()));
180 }
181}
182
183//=======================================================================
184//function : fillBorders
185//purpose :
186//=======================================================================
187void AIS_CameraFrustum::fillBorders()
188{
189 if (myBorders.IsNull())
190 {
191 const Standard_Integer aPlaneSegmVertsNb = 2 * 4;
192 const Standard_Integer aPlanesNb = 3 * 2;
193 myBorders = new Graphic3d_ArrayOfSegments (Graphic3d_Camera::FrustumVerticesNB, aPlaneSegmVertsNb * aPlanesNb);
194 myBorders->SetVertice (Graphic3d_Camera::FrustumVerticesNB, gp_Pnt (0.0, 0.0, 0.0));
195
196 // Segments go in order:
197 // (0, 2), (2, 3), (3, 1), (1, 0)
198 const Standard_Integer aLookup1[] = { 0, 1, 1, 1, 1, 0, 0, 0 };
199 const Standard_Integer aLookup2[] = { 0, 0, 0, 1, 1, 1, 1, 0 };
200 Standard_Integer aShifts[] = { 0, 0, 0 };
201
202 // Planes go in order:
203 // LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
204 for (Standard_Integer aFaceIdx = 0; aFaceIdx < 3; ++aFaceIdx)
205 {
206 for (Standard_Integer i = 0; i < 2; ++i)
207 {
208 for (Standard_Integer aSegmVertIter = 0; aSegmVertIter < aPlaneSegmVertsNb; ++aSegmVertIter)
209 {
210 aShifts[aFaceIdx] = i;
211 aShifts[(aFaceIdx + 1) % 3] = aLookup1[aSegmVertIter];
212 aShifts[(aFaceIdx + 2) % 3] = aLookup2[aSegmVertIter];
213
214 Standard_Integer anIndex = aShifts[0] * 2 * 2 + aShifts[1] * 2 + aShifts[2];
215 myBorders->AddEdge (anIndex + 1);
216 }
217 }
218 }
219 }
220
221 for (Standard_Integer aPointIter = 0; aPointIter < Graphic3d_Camera::FrustumVerticesNB; ++aPointIter)
222 {
223 const Graphic3d_Vec3d aPnt = myPoints[aPointIter];
224 myBorders->SetVertice (aPointIter + 1, gp_Pnt (aPnt.x(), aPnt.y(), aPnt.z()));
225 }
226}
227
228//=======================================================================
229//function : Compute
230//purpose :
231//=======================================================================
232void AIS_CameraFrustum::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
233 const Handle(Prs3d_Presentation)& thePrs,
234 const Standard_Integer theMode)
235{
236 thePrs->SetInfiniteState (true);
237 if (myTriangles.IsNull())
238 {
239 return;
240 }
241
30a1b24e 242 switch (theMode)
243 {
244 case AIS_Shaded:
245 {
bf5f0ca2 246 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
30a1b24e 247 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
248 aGroup->AddPrimitiveArray (myTriangles);
249 }
250 Standard_FALLTHROUGH
251 case AIS_WireFrame:
252 {
bf5f0ca2 253 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
30a1b24e 254 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
255 aGroup->AddPrimitiveArray (myBorders);
256 break;
257 }
258 }
259}
260
261//=======================================================================
262//function : ComputeSelection
263//purpose :
264//=======================================================================
265void AIS_CameraFrustum::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
266 const Standard_Integer theMode)
267{
268 Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
269 switch (theMode)
270 {
271 case SelectionMode_Edges:
272 {
273 Handle(Select3D_SensitiveGroup) aSensitiveEntity = new Select3D_SensitiveGroup (anOwner);
274 for (Standard_Integer anIter = 1; anIter <= myBorders->EdgeNumber(); anIter += 2)
275 {
276 aSensitiveEntity->Add (new Select3D_SensitiveSegment (anOwner, myBorders->Vertice (myBorders->Edge (anIter)), myBorders->Vertice(myBorders->Edge (anIter + 1))));
277 }
278 theSelection->Add (aSensitiveEntity);
279 break;
280 }
281 case SelectionMode_Volume:
282 {
283 Handle(Select3D_SensitivePrimitiveArray) aSelArray = new Select3D_SensitivePrimitiveArray (anOwner);
284 aSelArray->InitTriangulation (myTriangles->Attributes(), myTriangles->Indices(), TopLoc_Location());
285 theSelection->Add (aSelArray);
286 break;
287 }
288 }
289}