973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
b311480e |
13 | |
7fd59977 |
14 | |
42cf5bc1 |
15 | #include <Aspect_GradientBackground.hxx> |
16 | #include <Aspect_Grid.hxx> |
17 | #include <Aspect_RectangularGrid.hxx> |
18 | #include <Aspect_Window.hxx> |
19 | #include <Bnd_Box.hxx> |
20 | #include <gp_Ax3.hxx> |
21 | #include <gp_Dir.hxx> |
7fd59977 |
22 | #include <gp_Dir2d.hxx> |
42cf5bc1 |
23 | #include <Graphic3d_Group.hxx> |
24 | #include <Graphic3d_Structure.hxx> |
25 | #include <Graphic3d_TextureEnv.hxx> |
26 | #include <Graphic3d_Vector.hxx> |
27 | #include <Quantity_Color.hxx> |
28 | #include <Standard_MultiplyDefined.hxx> |
29 | #include <Standard_TypeMismatch.hxx> |
30 | #include <TColStd_Array2OfReal.hxx> |
31 | #include <V3d_BadValue.hxx> |
7fd59977 |
32 | #include <V3d_CircularGrid.hxx> |
42cf5bc1 |
33 | #include <V3d_Light.hxx> |
34 | #include <V3d_RectangularGrid.hxx> |
35 | #include <V3d_UnMapped.hxx> |
36 | #include <V3d_View.hxx> |
37 | #include <V3d_Viewer.hxx> |
92efcf78 |
38 | #include <Aspect_CircularGrid.hxx> |
7fd59977 |
39 | |
81bba717 |
40 | #define MYEPSILON1 0.0001 // Comparison with 0.0 |
c6541a0c |
41 | #define MYEPSILON2 M_PI / 180. // Delta between 2 angles |
7fd59977 |
42 | |
c357e426 |
43 | //============================================================================= |
44 | //function : SetGrid |
45 | //purpose : |
46 | //============================================================================= |
b8ddfc2f |
47 | void V3d_View::SetGrid (const gp_Ax3& aPlane, const Handle(Aspect_Grid)& aGrid) |
48 | { |
b5ac8292 |
49 | MyPlane = aPlane; |
50 | MyGrid = aGrid; |
51 | |
52 | Standard_Real xl, yl, zl; |
53 | Standard_Real xdx, xdy, xdz; |
54 | Standard_Real ydx, ydy, ydz; |
55 | Standard_Real dx, dy, dz; |
56 | aPlane.Location ().Coord (xl, yl, zl); |
57 | aPlane.XDirection ().Coord (xdx, xdy, xdz); |
58 | aPlane.YDirection ().Coord (ydx, ydy, ydz); |
59 | aPlane.Direction ().Coord (dx, dy, dz); |
60 | |
61 | Standard_Real CosAlpha = Cos (MyGrid->RotationAngle ()); |
62 | Standard_Real SinAlpha = Sin (MyGrid->RotationAngle ()); |
63 | |
64 | TColStd_Array2OfReal Trsf1 (1, 4, 1, 4); |
65 | Trsf1 (4, 4) = 1.0; |
66 | Trsf1 (4, 1) = Trsf1 (4, 2) = Trsf1 (4, 3) = 0.0; |
67 | // Translation |
68 | Trsf1 (1, 4) = xl, |
69 | Trsf1 (2, 4) = yl, |
70 | Trsf1 (3, 4) = zl; |
71 | // Transformation change of marker |
72 | Trsf1 (1, 1) = xdx, |
73 | Trsf1 (2, 1) = xdy, |
74 | Trsf1 (3, 1) = xdz, |
75 | Trsf1 (1, 2) = ydx, |
76 | Trsf1 (2, 2) = ydy, |
77 | Trsf1 (3, 2) = ydz, |
78 | Trsf1 (1, 3) = dx, |
79 | Trsf1 (2, 3) = dy, |
80 | Trsf1 (3, 3) = dz; |
81 | |
82 | TColStd_Array2OfReal Trsf2 (1, 4, 1, 4); |
83 | Trsf2 (4, 4) = 1.0; |
84 | Trsf2 (4, 1) = Trsf2 (4, 2) = Trsf2 (4, 3) = 0.0; |
85 | // Translation of the origin |
86 | Trsf2 (1, 4) = -MyGrid->XOrigin (), |
87 | Trsf2 (2, 4) = -MyGrid->YOrigin (), |
88 | Trsf2 (3, 4) = 0.0; |
89 | // Rotation Alpha around axis -Z |
90 | Trsf2 (1, 1) = CosAlpha, |
91 | Trsf2 (2, 1) = -SinAlpha, |
92 | Trsf2 (3, 1) = 0.0, |
93 | Trsf2 (1, 2) = SinAlpha, |
94 | Trsf2 (2, 2) = CosAlpha, |
95 | Trsf2 (3, 2) = 0.0, |
96 | Trsf2 (1, 3) = 0.0, |
97 | Trsf2 (2, 3) = 0.0, |
98 | Trsf2 (3, 3) = 1.0; |
99 | |
100 | Standard_Real valuetrsf; |
101 | Standard_Real valueoldtrsf; |
102 | Standard_Real valuenewtrsf; |
103 | Standard_Integer i, j, k; |
104 | // Calculation of the product of matrices |
105 | for (i=1; i<=4; i++) |
106 | for (j=1; j<=4; j++) { |
107 | MyTrsf (i, j) = 0.0; |
108 | for (k=1; k<=4; k++) { |
109 | valueoldtrsf = Trsf1 (i, k); |
110 | valuetrsf = Trsf2 (k, j); |
111 | valuenewtrsf = MyTrsf (i, j) + valueoldtrsf * valuetrsf; |
112 | MyTrsf (i, j) = valuenewtrsf; |
113 | } |
114 | } |
7fd59977 |
115 | } |
116 | |
c357e426 |
117 | //============================================================================= |
118 | //function : SetGridActivity |
119 | //purpose : |
120 | //============================================================================= |
b8ddfc2f |
121 | void V3d_View::SetGridActivity (const Standard_Boolean AFlag) |
122 | { |
b5ac8292 |
123 | if (AFlag) MyGrid->Activate (); |
124 | else MyGrid->Deactivate (); |
7fd59977 |
125 | } |
126 | |
c357e426 |
127 | //============================================================================= |
128 | //function : toPolarCoords |
129 | //purpose : |
130 | //============================================================================= |
b5ac8292 |
131 | void toPolarCoords (const Standard_Real theX, const Standard_Real theY, |
132 | Standard_Real& theR, Standard_Real& thePhi) |
133 | { |
134 | theR = Sqrt (theX * theX + theY * theY); |
135 | thePhi = ATan2 (theY, theX); |
136 | } |
137 | |
c357e426 |
138 | //============================================================================= |
139 | //function : toCartesianCoords |
140 | //purpose : |
141 | //============================================================================= |
b5ac8292 |
142 | void toCartesianCoords (const Standard_Real theR, const Standard_Real thePhi, |
143 | Standard_Real& theX, Standard_Real& theY) |
144 | { |
145 | theX = theR * Cos (thePhi); |
146 | theY = theR * Sin (thePhi); |
147 | } |
148 | |
c357e426 |
149 | //============================================================================= |
150 | //function : Compute |
151 | //purpose : |
152 | //============================================================================= |
b8ddfc2f |
153 | Graphic3d_Vertex V3d_View::Compute (const Graphic3d_Vertex & AVertex) const |
154 | { |
b5ac8292 |
155 | Graphic3d_Vertex CurPoint, NewPoint; |
156 | Standard_Real X1, Y1, Z1, X2, Y2, Z2; |
157 | Standard_Real XPp, YPp; |
c357e426 |
158 | Handle(Graphic3d_Camera) aCamera = Camera(); |
7fd59977 |
159 | |
c357e426 |
160 | gp_Dir aRefPlane = aCamera->Direction().Reversed(); |
b5ac8292 |
161 | X1 = aRefPlane.X(); Y1 = aRefPlane.Y(); Z1 = aRefPlane.Z(); |
162 | MyPlane.Direction ().Coord (X2, Y2, Z2); |
7fd59977 |
163 | |
b5ac8292 |
164 | gp_Dir VPN (X1, Y1, Z1); |
165 | gp_Dir GPN (X2, Y2, Z2); |
7fd59977 |
166 | |
b5ac8292 |
167 | AVertex.Coord (X1, Y1, Z1); |
168 | Project (X1, Y1, Z1, XPp, YPp); |
7fd59977 |
169 | |
b5ac8292 |
170 | // Casw when the plane of the grid and the plane of the view |
171 | // are perpendicular to MYEPSILON2 close radians |
172 | if (Abs (VPN.Angle (GPN) - M_PI / 2.) < MYEPSILON2) { |
173 | NewPoint.SetCoord (X1, Y1, Z1); |
b5ac8292 |
174 | return NewPoint; |
175 | } |
176 | |
177 | Standard_Boolean IsRectangular = |
178 | MyGrid->IsKind (STANDARD_TYPE (Aspect_RectangularGrid)); |
179 | |
180 | Graphic3d_Vertex P1; |
181 | |
182 | Standard_Real x0, y0, z0, x1, y1, z1, x2, y2, z2; |
183 | |
184 | P1.SetCoord (0.0, 0.0, 0.0); |
185 | CurPoint = V3d_View::TrsPoint (P1, MyTrsf); |
186 | CurPoint.Coord (x0, y0, z0); |
187 | |
188 | // get grid axes in world space |
189 | P1.SetCoord (1.0, 0.0, 0.0); |
190 | CurPoint = V3d_View::TrsPoint (P1, MyTrsf); |
191 | CurPoint.Coord (x1, y1, z1); |
192 | gp_Vec aGridX (gp_Pnt (x0, y0, z0), gp_Pnt (x1, y1, z1)); |
193 | aGridX.Normalize(); |
194 | |
195 | P1.SetCoord (0.0, 1.0, 0.0); |
196 | CurPoint = V3d_View::TrsPoint (P1, MyTrsf); |
197 | CurPoint.Coord (x2, y2, z2); |
198 | gp_Vec aGridY (gp_Pnt (x0, y0, z0), gp_Pnt (x2, y2, z2)); |
199 | aGridY.Normalize(); |
200 | |
201 | // get grid normal |
202 | MyPlane.Direction().Coord (x2, y2, z2); |
203 | gp_Vec aPlaneNormal (x2, y2, z2); |
204 | |
205 | gp_Vec aPointOnPlane = gp_Vec (0.0, 0.0, 0.0); |
206 | |
207 | AVertex.Coord (x1, y1, z1); |
208 | |
209 | // project ray from camera onto grid plane |
c357e426 |
210 | gp_Vec aProjection = aCamera->IsOrthographic() |
211 | ? gp_Vec (aCamera->Direction()) |
212 | : gp_Vec (aCamera->Eye(), gp_Pnt (x1, y1, z1)).Normalized(); |
aacbabe1 |
213 | gp_Vec aPointOrigin = gp_Vec (gp_Pnt (x1, y1, z1), gp_Pnt (x0, y0, z0)); |
214 | Standard_Real aT = aPointOrigin.Dot (aPlaneNormal) / aProjection.Dot (aPlaneNormal); |
215 | aPointOnPlane = gp_Vec (x1, y1, z1) + aProjection * aT; |
b5ac8292 |
216 | |
217 | if (IsRectangular) { |
218 | Standard_Real XS, YS; |
219 | Handle(Aspect_RectangularGrid) theGrid = |
c5f3a425 |
220 | Handle(Aspect_RectangularGrid)::DownCast (MyGrid); |
b5ac8292 |
221 | XS = theGrid->XStep (), YS = theGrid->YStep (); |
222 | |
223 | // project point on plane to grid local space |
224 | gp_Vec aToPoint (gp_Pnt (x0, y0, z0), |
225 | gp_Pnt (aPointOnPlane.X(), aPointOnPlane.Y(), aPointOnPlane.Z())); |
226 | Standard_Real anXSteps = Round (aGridX.Dot (aToPoint) / XS); |
227 | Standard_Real anYSteps = Round (aGridY.Dot (aToPoint) / YS); |
228 | |
229 | // clamp point to grid |
230 | gp_Vec aResult = aGridX * anXSteps * XS + aGridY * anYSteps * YS + gp_Vec (x0, y0, z0); |
231 | NewPoint.SetCoord (aResult.X(), aResult.Y(), aResult.Z()); |
232 | |
233 | } |
234 | else // IsCircular |
235 | { |
236 | Standard_Real RS; |
237 | Standard_Integer DN; |
238 | Standard_Real Alpha; |
239 | Handle(Aspect_CircularGrid) theGrid = |
c5f3a425 |
240 | Handle(Aspect_CircularGrid)::DownCast (MyGrid); |
b5ac8292 |
241 | RS = theGrid->RadiusStep (); |
242 | DN = theGrid->DivisionNumber (); |
243 | Alpha = M_PI / Standard_Real (DN); |
244 | |
245 | // project point on plane to grid local space |
246 | gp_Vec aToPoint (gp_Pnt (x0, y0, z0), |
247 | gp_Pnt (aPointOnPlane.X(), aPointOnPlane.Y(), aPointOnPlane.Z())); |
248 | |
249 | Standard_Real anR = 0.0, aPhi = 0.0; |
250 | Standard_Real aLocalX = aGridX.Dot (aToPoint); |
251 | Standard_Real aLocalY = aGridY.Dot (aToPoint); |
252 | toPolarCoords (aLocalX, aLocalY, anR, aPhi); |
253 | |
254 | // clamp point to grid |
255 | Standard_Real anRSteps = Round (anR / RS); |
256 | Standard_Real aPhiSteps = Round (aPhi / Alpha); |
257 | toCartesianCoords (anRSteps * RS, aPhiSteps * Alpha, aLocalX, aLocalY); |
258 | |
259 | gp_Vec aResult = aGridX * aLocalX + aGridY * aLocalY + gp_Vec (x0, y0, z0); |
260 | NewPoint.SetCoord (aResult.X(), aResult.Y(), aResult.Z()); |
261 | } |
7fd59977 |
262 | |
b5ac8292 |
263 | return NewPoint; |
7fd59977 |
264 | } |
265 | |
c357e426 |
266 | //============================================================================= |
267 | //function : ZBufferTriedronSetup |
268 | //purpose : |
269 | //============================================================================= |
270 | void V3d_View::ZBufferTriedronSetup(const Quantity_NameOfColor theXColor, |
271 | const Quantity_NameOfColor theYColor, |
272 | const Quantity_NameOfColor theZColor, |
273 | const Standard_Real theSizeRatio, |
274 | const Standard_Real theAxisDiametr, |
275 | const Standard_Integer theNbFacettes) |
7fd59977 |
276 | { |
caf231b0 |
277 | myTrihedron->SetArrowsColor (theXColor, theYColor, theZColor); |
278 | myTrihedron->SetSizeRatio (theSizeRatio); |
279 | myTrihedron->SetNbFacets (theNbFacettes); |
280 | myTrihedron->SetArrowDiameter (theAxisDiametr); |
7fd59977 |
281 | } |
282 | |
c357e426 |
283 | //============================================================================= |
284 | //function : TriedronDisplay |
285 | //purpose : |
286 | //============================================================================= |
287 | void V3d_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition thePosition, |
288 | const Quantity_NameOfColor theColor, |
289 | const Standard_Real theScale, |
290 | const V3d_TypeOfVisualization theMode) |
b8ddfc2f |
291 | { |
caf231b0 |
292 | myTrihedron->SetLabelsColor (theColor); |
293 | myTrihedron->SetScale (theScale); |
294 | myTrihedron->SetPosition (thePosition); |
295 | myTrihedron->SetWireframe (theMode == V3d_WIREFRAME); |
296 | |
297 | myTrihedron->Display (*this); |
7fd59977 |
298 | } |
299 | |
c357e426 |
300 | //============================================================================= |
301 | //function : TriedronErase |
302 | //purpose : |
303 | //============================================================================= |
304 | void V3d_View::TriedronErase() |
b8ddfc2f |
305 | { |
caf231b0 |
306 | myTrihedron->Erase(); |
7fd59977 |
307 | } |
308 | |
c357e426 |
309 | //============================================================================= |
310 | //function : GetGraduatedTrihedron |
311 | //purpose : |
312 | //============================================================================= |
536d98e2 |
313 | const Graphic3d_GraduatedTrihedron& V3d_View::GetGraduatedTrihedron() const |
7fd59977 |
314 | { |
c357e426 |
315 | return myView->GetGraduatedTrihedron(); |
7fd59977 |
316 | } |
317 | |
c357e426 |
318 | //============================================================================= |
319 | //function : GraduatedTrihedronDisplay |
320 | //purpose : |
321 | //============================================================================= |
a79f67f8 |
322 | void V3d_View::GraduatedTrihedronDisplay(const Graphic3d_GraduatedTrihedron& theTrihedronData) |
7fd59977 |
323 | { |
c357e426 |
324 | myView->GraduatedTrihedronDisplay (theTrihedronData); |
7fd59977 |
325 | } |
326 | |
c357e426 |
327 | //============================================================================= |
328 | //function : GraduatedTrihedronErase |
329 | //purpose : |
330 | //============================================================================= |
7fd59977 |
331 | void V3d_View::GraduatedTrihedronErase() |
332 | { |
c357e426 |
333 | myView->GraduatedTrihedronErase(); |
7fd59977 |
334 | } |