caf231b0 |
1 | // Created on: 2016-10-11 |
2 | // Created by: Ilya SEVRIKOV |
3 | // Copyright (c) 2016 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 <V3d_Trihedron.hxx> |
17 | |
18 | #include <gp_Ax3.hxx> |
19 | #include <Graphic3d_ArrayOfPolylines.hxx> |
20 | #include <Graphic3d_ArrayOfSegments.hxx> |
21 | #include <Graphic3d_ArrayOfTriangles.hxx> |
22 | #include <Graphic3d_Camera.hxx> |
23 | #include <Graphic3d_TransformPers.hxx> |
24 | #include <Prs3d.hxx> |
62ef08df |
25 | #include <Prs3d_Arrow.hxx> |
caf231b0 |
26 | #include <Prs3d_LineAspect.hxx> |
27 | #include <Prs3d_ShadingAspect.hxx> |
28 | #include <Prs3d_Text.hxx> |
29 | #include <Prs3d_TextAspect.hxx> |
62ef08df |
30 | #include <Prs3d_ToolSphere.hxx> |
caf231b0 |
31 | #include <V3d_View.hxx> |
32 | |
33 | IMPLEMENT_STANDARD_RTTIEXT (V3d_Trihedron, Standard_Transient) |
34 | |
35 | namespace |
36 | { |
37 | //! Compensates difference between old implementation (without transform persistence) and current implementation. |
38 | static const Standard_Real THE_INTERNAL_SCALE_FACTOR = 500.0; |
39 | |
40 | static const Standard_ShortReal THE_CYLINDER_LENGTH = 0.75f; |
41 | static const Standard_Integer THE_CIRCLE_SERMENTS_NB = 24; |
42 | static const Standard_Real THE_CIRCLE_SEGMENT_ANGLE = 2.0 * M_PI / THE_CIRCLE_SERMENTS_NB; |
43 | } |
44 | |
45 | //! Dummy implementation of Graphic3d_Structure overriding ::Compute() method for handling Device Lost. |
46 | class V3d_Trihedron::TrihedronStructure : public Graphic3d_Structure |
47 | { |
48 | public: |
49 | //! Main constructor. |
50 | TrihedronStructure (const Handle(Graphic3d_StructureManager)& theManager, V3d_Trihedron* theTrihedron) |
51 | : Graphic3d_Structure (theManager), myTrihedron (theTrihedron) {} |
52 | |
53 | //! Override method to redirect to V3d_Trihedron. |
54 | virtual void Compute() Standard_OVERRIDE { myTrihedron->compute(); } |
55 | |
56 | private: |
57 | V3d_Trihedron* myTrihedron; |
58 | }; |
59 | |
60 | // ============================================================================ |
61 | // function : V3d_Trihedron |
62 | // purpose : |
63 | // ============================================================================ |
64 | V3d_Trihedron::V3d_Trihedron() |
65 | : myScale (1.0), |
66 | myRatio (0.8), |
67 | myDiameter (0.05), |
68 | myNbFacettes (12), |
69 | myIsWireframe(Standard_False), |
70 | myToCompute (Standard_True) |
71 | { |
72 | myTransformPers = new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_LOWER); |
73 | SetPosition (Aspect_TOTP_LEFT_LOWER); |
74 | |
75 | // Set material. |
76 | Graphic3d_MaterialAspect aShadingMaterial; |
77 | aShadingMaterial.SetReflectionModeOff (Graphic3d_TOR_SPECULAR); |
78 | aShadingMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT); |
79 | |
80 | for (Standard_Integer anIt = 0; anIt < 3; ++anIt) |
81 | { |
82 | myArrowShadingAspects[anIt] = new Prs3d_ShadingAspect(); |
83 | myArrowLineAspects[anIt] = new Prs3d_LineAspect (Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0); |
84 | |
85 | // mark texture map ON to actually disable environment map |
86 | myArrowShadingAspects[anIt]->Aspect()->SetTextureMapOn(); |
87 | myArrowShadingAspects[anIt]->Aspect()->SetInteriorStyle (Aspect_IS_SOLID); |
88 | myArrowShadingAspects[anIt]->SetMaterial (aShadingMaterial); |
89 | } |
90 | myArrowShadingAspects[0]->SetColor (Quantity_NOC_RED); |
91 | myArrowLineAspects [0]->SetColor (Quantity_NOC_RED); |
92 | myArrowShadingAspects[1]->SetColor (Quantity_NOC_GREEN); |
93 | myArrowLineAspects [1]->SetColor (Quantity_NOC_GREEN); |
94 | myArrowShadingAspects[2]->SetColor (Quantity_NOC_BLUE1); |
95 | myArrowLineAspects [2]->SetColor (Quantity_NOC_BLUE1); |
96 | |
97 | mySphereShadingAspect = new Prs3d_ShadingAspect(); |
98 | mySphereLineAspect = new Prs3d_LineAspect (Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0); |
99 | |
100 | // mark texture map ON to actually disable environment map |
101 | mySphereShadingAspect->Aspect()->SetTextureMapOn(); |
102 | mySphereShadingAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID); |
103 | mySphereShadingAspect->SetMaterial (aShadingMaterial); |
104 | mySphereShadingAspect->SetColor (Quantity_NOC_WHITE); |
105 | |
106 | myTextAspect = new Prs3d_TextAspect(); |
107 | myTextAspect->SetFont ("Courier"); |
108 | myTextAspect->SetHeight (16); |
109 | myTextAspect->SetHorizontalJustification (Graphic3d_HTA_LEFT); |
110 | myTextAspect->SetVerticalJustification (Graphic3d_VTA_BOTTOM); |
111 | } |
112 | |
113 | // ============================================================================ |
114 | // function : SetLabelsColor |
115 | // purpose : |
116 | // ============================================================================ |
117 | void V3d_Trihedron::SetLabelsColor (const Quantity_Color& theColor) |
118 | { |
119 | myTextAspect->SetColor (theColor); |
120 | } |
121 | |
122 | // ============================================================================ |
123 | // function : SetArrowsColor |
124 | // purpose : |
125 | // ============================================================================ |
126 | void V3d_Trihedron::SetArrowsColor (const Quantity_Color& theXColor, |
127 | const Quantity_Color& theYColor, |
128 | const Quantity_Color& theZColor) |
129 | { |
130 | const Quantity_Color aColors[3] = { theXColor, theYColor, theZColor }; |
131 | for (Standard_Integer anIt = 0; anIt < 3; ++anIt) |
132 | { |
133 | myArrowShadingAspects[anIt]->SetColor (aColors[anIt]); |
134 | myArrowLineAspects [anIt]->SetColor (aColors[anIt]); |
135 | } |
136 | } |
137 | |
138 | // ============================================================================ |
139 | // function : SetScale |
140 | // purpose : |
141 | // ============================================================================ |
142 | void V3d_Trihedron::SetScale (const Standard_Real theScale) |
143 | { |
144 | if (Abs (myScale - theScale) > Precision::Confusion()) |
145 | { |
146 | invalidate(); |
147 | } |
148 | myScale = theScale; |
149 | } |
150 | |
151 | // ======================================================================= |
152 | // function : SetSizeRatio |
153 | // purpose : |
154 | // ======================================================================= |
155 | void V3d_Trihedron::SetSizeRatio (const Standard_Real theRatio) |
156 | { |
157 | if (Abs (myRatio - theRatio) > Precision::Confusion()) |
158 | { |
159 | invalidate(); |
160 | } |
161 | myRatio = theRatio; |
162 | } |
163 | |
164 | // ======================================================================= |
165 | // function : SetArrowDiameter |
166 | // purpose : |
167 | // ======================================================================= |
168 | void V3d_Trihedron::SetArrowDiameter (const Standard_Real theDiam) |
169 | { |
170 | if (Abs (myDiameter - theDiam) > Precision::Confusion()) |
171 | { |
172 | invalidate(); |
173 | } |
174 | myDiameter = theDiam; |
175 | } |
176 | |
177 | // ======================================================================= |
178 | // function : SetNbFacets |
179 | // purpose : |
180 | // ======================================================================= |
181 | void V3d_Trihedron::SetNbFacets (const Standard_Integer theNbFacets) |
182 | { |
183 | if (Abs (myNbFacettes - theNbFacets) > 0) |
184 | { |
185 | invalidate(); |
186 | } |
187 | myNbFacettes = theNbFacets; |
188 | } |
189 | |
190 | // ============================================================================ |
191 | // function : Display |
192 | // purpose : |
193 | // ============================================================================ |
194 | void V3d_Trihedron::Display (const V3d_View& theView) |
195 | { |
196 | if (myStructure.IsNull()) |
197 | { |
198 | myStructure = new TrihedronStructure (theView.Viewer()->StructureManager(), this); |
199 | myStructure->SetTransformPersistence (myTransformPers); |
200 | myStructure->SetZLayer (Graphic3d_ZLayerId_Topmost); |
201 | myStructure->SetDisplayPriority (9); |
202 | myStructure->SetInfiniteState (Standard_True); |
203 | myStructure->CStructure()->ViewAffinity = new Graphic3d_ViewAffinity(); |
204 | myStructure->CStructure()->ViewAffinity->SetVisible (Standard_False); |
205 | myStructure->CStructure()->ViewAffinity->SetVisible (theView.View()->Identification(), true); |
206 | } |
207 | if (myToCompute) |
208 | { |
209 | compute(); |
210 | } |
211 | |
212 | myStructure->Display(); |
213 | } |
214 | |
215 | // ============================================================================ |
216 | // function : Erase |
217 | // purpose : |
218 | // ============================================================================ |
219 | void V3d_Trihedron::Erase() |
220 | { |
221 | if (!myStructure.IsNull()) |
222 | { |
223 | myStructure->Erase(); |
224 | myStructure.Nullify(); |
225 | } |
226 | } |
227 | |
228 | // ============================================================================ |
229 | // function : SetPosition |
230 | // purpose : |
231 | // ============================================================================ |
232 | void V3d_Trihedron::SetPosition (const Aspect_TypeOfTriedronPosition thePosition) |
233 | { |
234 | Graphic3d_Vec2i anOffset (0, 0); |
235 | if ((thePosition & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0) |
236 | { |
237 | anOffset.x() = static_cast<Standard_Integer> (myScale * THE_INTERNAL_SCALE_FACTOR); |
238 | } |
239 | if ((thePosition & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0) |
240 | { |
241 | anOffset.y() = static_cast<Standard_Integer> (myScale * THE_INTERNAL_SCALE_FACTOR); |
242 | } |
243 | |
244 | myTransformPers->SetCorner2d (thePosition); |
245 | myTransformPers->SetOffset2d (anOffset); |
246 | } |
247 | |
248 | // ============================================================================ |
249 | // function : compute |
250 | // purpose : |
251 | // ============================================================================ |
252 | void V3d_Trihedron::compute() |
253 | { |
254 | myStructure->GraphicClear (Standard_False); |
255 | |
256 | // Create trihedron. |
62ef08df |
257 | const Standard_Real aScale = myScale * myRatio * THE_INTERNAL_SCALE_FACTOR; |
258 | const Standard_Real aCylinderLength = aScale * THE_CYLINDER_LENGTH; |
259 | const Standard_Real aCylinderRadius = aScale * myDiameter; |
260 | const Standard_Real aConeRadius = myIsWireframe ? aCylinderRadius : (aCylinderRadius * 2.0); |
261 | const Standard_Real aConeLength = aScale * (1.0 - THE_CYLINDER_LENGTH); |
262 | const Standard_Real aSphereRadius = aCylinderRadius * 2.0; |
263 | const Standard_Real aRayon = aScale / 30.0; |
caf231b0 |
264 | { |
265 | Handle(Graphic3d_Group) aSphereGroup = myStructure->NewGroup(); |
266 | |
267 | // Display origin. |
268 | if (myIsWireframe) |
269 | { |
270 | Handle(Graphic3d_ArrayOfPolylines) anCircleArray = new Graphic3d_ArrayOfPolylines (THE_CIRCLE_SERMENTS_NB + 2); |
271 | for (Standard_Integer anIt = THE_CIRCLE_SERMENTS_NB; anIt >= 0; --anIt) |
272 | { |
273 | anCircleArray->AddVertex (aRayon * Sin (anIt * THE_CIRCLE_SEGMENT_ANGLE), |
274 | aRayon * Cos (anIt * THE_CIRCLE_SEGMENT_ANGLE), 0.0); |
275 | } |
276 | anCircleArray->AddVertex (aRayon * Sin (THE_CIRCLE_SERMENTS_NB * THE_CIRCLE_SEGMENT_ANGLE), |
277 | aRayon * Cos (THE_CIRCLE_SERMENTS_NB * THE_CIRCLE_SEGMENT_ANGLE), 0.0); |
278 | |
279 | aSphereGroup->SetGroupPrimitivesAspect (mySphereLineAspect->Aspect()); |
280 | aSphereGroup->AddPrimitiveArray (anCircleArray); |
281 | } |
282 | else |
283 | { |
284 | gp_Trsf aSphereTransform; |
285 | aSphereGroup->SetGroupPrimitivesAspect (mySphereShadingAspect->Aspect()); |
62ef08df |
286 | aSphereGroup->AddPrimitiveArray (Prs3d_ToolSphere::Create (aSphereRadius, myNbFacettes, myNbFacettes, aSphereTransform)); |
caf231b0 |
287 | } |
288 | } |
289 | |
290 | // Display axes. |
291 | { |
292 | const gp_Ax1 anAxes[3] = { gp::OX(), gp::OY(), gp::OZ() }; |
293 | for (Standard_Integer anIter = 0; anIter < 3; ++anIter) |
294 | { |
295 | Handle(Graphic3d_Group) anAxisGroup = myStructure->NewGroup(); |
caf231b0 |
296 | if (myIsWireframe) |
297 | { |
62ef08df |
298 | // create a tube |
caf231b0 |
299 | Handle(Graphic3d_ArrayOfPrimitives) anArray = new Graphic3d_ArrayOfSegments (2); |
300 | anArray->AddVertex (0.0f, 0.0f, 0.0f); |
301 | anArray->AddVertex (anAxes[anIter].Direction().XYZ() * aCylinderLength); |
302 | |
303 | anAxisGroup->SetGroupPrimitivesAspect (myArrowLineAspects[anIter]->Aspect()); |
304 | anAxisGroup->AddPrimitiveArray (anArray); |
305 | } |
caf231b0 |
306 | |
62ef08df |
307 | Handle(Graphic3d_ArrayOfTriangles) aTriangles = Prs3d_Arrow::DrawShaded (anAxes[anIter], |
308 | myIsWireframe ? 0.0 : aCylinderRadius, |
309 | aCylinderLength + aConeLength, |
310 | aConeRadius, |
311 | aConeLength, |
312 | myNbFacettes); |
313 | anAxisGroup->SetGroupPrimitivesAspect (myArrowShadingAspects[anIter]->Aspect()); |
314 | anAxisGroup->AddPrimitiveArray (aTriangles); |
caf231b0 |
315 | } |
316 | } |
317 | |
318 | // Display labels. |
319 | { |
320 | Handle(Graphic3d_Group) aLabelGroup = myStructure->NewGroup(); |
321 | const TCollection_ExtendedString aLabels[3] = { "X", "Y", "Z" }; |
322 | const gp_Pnt aPoints[3] = { gp_Pnt (aScale + 2.0 * aRayon, 0.0, -aRayon), |
323 | gp_Pnt ( aRayon, aScale + 3.0 * aRayon, 2.0 * aRayon), |
324 | gp_Pnt ( -2.0 * aRayon, 0.5 * aRayon, aScale + 3.0 * aRayon) }; |
325 | for (Standard_Integer anAxisIter = 0; anAxisIter < 3; ++anAxisIter) |
326 | { |
327 | Prs3d_Text::Draw (aLabelGroup, myTextAspect, aLabels[anAxisIter], aPoints[anAxisIter]); |
328 | } |
329 | } |
330 | } |