Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2008-03-20 |
2 | // Created by: Alexander GRIGORIEV | |
3 | // Copyright (c) 2008-2012 OPEN CASCADE SAS | |
4 | // | |
5 | // The content of this file is subject to the Open CASCADE Technology Public | |
6 | // License Version 6.5 (the "License"). You may not use the content of this file | |
7 | // except in compliance with the License. Please obtain a copy of the License | |
8 | // at http://www.opencascade.org and read it completely before using this file. | |
9 | // | |
10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
12 | // | |
13 | // The Original Code and all software distributed under the License is | |
14 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
15 | // Initial Developer hereby disclaims all such warranties, including without | |
16 | // limitation, any warranties of merchantability, fitness for a particular | |
17 | // purpose or non-infringement. Please see the License for the specific terms | |
18 | // and conditions governing the rights and limitations under the License. | |
19 | ||
7fd59977 | 20 | |
21 | #include <NIS_SurfaceDrawer.hxx> | |
22 | #include <NIS_Surface.hxx> | |
23 | #include <NIS_InteractiveObject.hxx> | |
24 | #include <Standard_ProgramError.hxx> | |
25 | ||
cfd5fa01 | 26 | #include <OpenGl_GlCore11.hxx> |
7fd59977 | 27 | |
ffe2bea7 A |
28 | static void setColor(GLenum theFace, |
29 | Quantity_Parameter * theAmbient, | |
30 | const Standard_Real theSpecularity, | |
31 | GLint theShininess); | |
32 | ||
7fd59977 | 33 | IMPLEMENT_STANDARD_HANDLE (NIS_SurfaceDrawer, NIS_Drawer) |
34 | IMPLEMENT_STANDARD_RTTIEXT (NIS_SurfaceDrawer, NIS_Drawer) | |
35 | ||
36 | //======================================================================= | |
37 | //function : NIS_SurfaceDrawer() | |
38 | //purpose : Constructor | |
39 | //======================================================================= | |
40 | ||
41 | NIS_SurfaceDrawer::NIS_SurfaceDrawer | |
42 | (const Quantity_Color &theNormal, | |
43 | const Quantity_Color &theHilight, | |
44 | const Quantity_Color &theDynHilight) | |
45 | : myBackColor (theNormal), | |
ffe2bea7 A |
46 | myPolygonOffset (0.f), |
47 | myIsWireframe (Standard_False) | |
7fd59977 | 48 | { |
49 | myColor[Draw_Normal] = theNormal; | |
ffe2bea7 | 50 | myColor[Draw_Top] = theNormal; |
7fd59977 | 51 | myColor[Draw_Transparent] = theNormal; |
52 | myColor[Draw_Hilighted] = theHilight; | |
53 | myColor[Draw_DynHilighted] = theDynHilight; | |
54 | } | |
55 | ||
56 | //======================================================================= | |
57 | //function : SetColor | |
cfd5fa01 | 58 | //purpose : |
7fd59977 | 59 | //======================================================================= |
60 | ||
ffe2bea7 | 61 | void NIS_SurfaceDrawer::SetColor(const Quantity_Color &theColor) |
7fd59977 | 62 | { |
63 | myColor[Draw_Normal] = theColor; | |
ffe2bea7 | 64 | myColor[Draw_Top] = theColor; |
7fd59977 | 65 | myColor[Draw_Transparent] = theColor; |
7fd59977 | 66 | } |
67 | ||
68 | //======================================================================= | |
69 | //function : Assign | |
cfd5fa01 | 70 | //purpose : |
7fd59977 | 71 | //======================================================================= |
72 | ||
73 | void NIS_SurfaceDrawer::Assign (const Handle_NIS_Drawer& theOther) | |
74 | { | |
75 | if (theOther.IsNull() == Standard_False) { | |
76 | NIS_Drawer::Assign (theOther); | |
77 | const Handle(NIS_SurfaceDrawer)& anOther = | |
78 | static_cast <const Handle(NIS_SurfaceDrawer)&> (theOther); | |
79 | myColor[Draw_Normal] = anOther->myColor[Draw_Normal]; | |
ffe2bea7 | 80 | myColor[Draw_Top] = anOther->myColor[Draw_Top]; |
7fd59977 | 81 | myColor[Draw_Transparent] = anOther->myColor[Draw_Transparent]; |
82 | myColor[Draw_Hilighted] = anOther->myColor[Draw_Hilighted]; | |
83 | myColor[Draw_DynHilighted] = anOther->myColor[Draw_DynHilighted]; | |
84 | myBackColor = anOther->myBackColor; | |
ffe2bea7 A |
85 | myPolygonOffset = anOther->myPolygonOffset; |
86 | myIsWireframe = anOther->myIsWireframe; | |
7fd59977 | 87 | } |
88 | } | |
89 | ||
90 | //======================================================================= | |
91 | //function : IsEqual | |
92 | //purpose : Comparison of two Drawers (for Map impementation) | |
93 | //======================================================================= | |
94 | ||
95 | Standard_Boolean NIS_SurfaceDrawer::IsEqual | |
96 | (const Handle_NIS_Drawer& theOther)const | |
97 | { | |
98 | static const Standard_Real anEpsilon2 (1e-7); | |
99 | Standard_Boolean aResult (Standard_False); | |
100 | const Handle(NIS_SurfaceDrawer) anOther = | |
101 | Handle(NIS_SurfaceDrawer)::DownCast (theOther); | |
102 | if (NIS_Drawer::IsEqual(theOther)) | |
103 | aResult = (anOther->myColor[Draw_Normal] | |
104 | .SquareDistance (myColor[Draw_Normal]) < anEpsilon2 && | |
105 | anOther->myColor[Draw_Hilighted] | |
106 | .SquareDistance (myColor[Draw_Hilighted]) < anEpsilon2 && | |
107 | anOther->myColor[Draw_DynHilighted] | |
108 | .SquareDistance (myColor[Draw_DynHilighted]) < anEpsilon2 && | |
109 | anOther->myBackColor.SquareDistance(myBackColor) < anEpsilon2 && | |
110 | fabs(anOther->myPolygonOffset - myPolygonOffset) < 0.999 && | |
ffe2bea7 | 111 | myIsWireframe == anOther->myIsWireframe); |
7fd59977 | 112 | if (aResult) { |
113 | // Arbitrary point for test | |
114 | gp_XYZ aPnt[2] = { | |
115 | gp_XYZ(113., -31.3, 29.19), | |
116 | gp_XYZ(113., -31.3, 29.19) | |
117 | }; | |
118 | anOther->myTrsf.Transforms(aPnt[0]); | |
119 | myTrsf.Transforms(aPnt[1]); | |
120 | if ((aPnt[0] - aPnt[1]).SquareModulus() > anEpsilon2) | |
121 | aResult = Standard_False; | |
122 | } | |
123 | return aResult; | |
124 | } | |
125 | ||
126 | //======================================================================= | |
127 | //function : redraw | |
cfd5fa01 | 128 | //purpose : |
7fd59977 | 129 | //======================================================================= |
130 | ||
131 | void NIS_SurfaceDrawer::redraw (const DrawType theType, | |
ffe2bea7 | 132 | const Handle_NIS_View& theView) |
7fd59977 | 133 | { |
134 | glMatrixMode( GL_MODELVIEW ); | |
135 | glPushMatrix(); | |
136 | ||
137 | GLdouble aMatrix[16] = { | |
138 | myTrsf.Value(1,1), myTrsf.Value(2,1), myTrsf.Value(3,1), 0., | |
139 | myTrsf.Value(1,2), myTrsf.Value(2,2), myTrsf.Value(3,2), 0., | |
140 | myTrsf.Value(1,3), myTrsf.Value(2,3), myTrsf.Value(3,3), 0., | |
141 | myTrsf.Value(1,4), myTrsf.Value(2,4), myTrsf.Value(3,4), 1. | |
142 | }; | |
143 | ||
144 | glMultMatrixd( aMatrix ); | |
145 | ||
146 | NIS_Drawer::redraw(theType, theView); | |
147 | ||
148 | glPopMatrix(); | |
149 | } | |
150 | ||
151 | //======================================================================= | |
152 | //function : BeforeDraw | |
cfd5fa01 | 153 | //purpose : |
7fd59977 | 154 | //======================================================================= |
155 | ||
156 | void NIS_SurfaceDrawer::BeforeDraw (const DrawType theType, | |
ffe2bea7 | 157 | const NIS_DrawList&) |
7fd59977 | 158 | { |
159 | glEnable(GL_LIGHTING); | |
ffe2bea7 | 160 | // glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); |
7fd59977 | 161 | glEnableClientState (GL_VERTEX_ARRAY); |
ffe2bea7 A |
162 | if (myIsWireframe == Standard_False) { |
163 | glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); | |
164 | glEnable(GL_POLYGON_OFFSET_FILL); | |
165 | glShadeModel(GL_SMOOTH); | |
166 | } | |
7fd59977 | 167 | |
ffe2bea7 | 168 | Quantity_Parameter aValueCol[4] = {0., 0., 0., 1.}; |
7fd59977 | 169 | Quantity_TypeOfColor bidTC (Quantity_TOC_RGB); |
170 | GLfloat aLineWidth (1.f); | |
171 | GLfloat anOffset = myPolygonOffset; | |
ffe2bea7 A |
172 | static const GLfloat gColorN[4] = {0.f, 0.f, 0.f, 1.f}; |
173 | ||
7fd59977 | 174 | switch (theType) { |
175 | case Draw_DynHilighted: | |
176 | aLineWidth = 3.f; | |
177 | myColor[theType].Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC); | |
ffe2bea7 A |
178 | setColor(GL_FRONT_AND_BACK, &aValueCol[0], 0.1, 5); |
179 | glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &gColorN[0]); | |
7fd59977 | 180 | glLineWidth (aLineWidth); |
ffe2bea7 A |
181 | if (myIsWireframe == Standard_False) |
182 | glPolygonOffset(1.f, -(anOffset + 11.f)); | |
7fd59977 | 183 | return; |
184 | case Draw_Hilighted: | |
185 | anOffset += 10.f; | |
186 | case Draw_Normal: | |
ffe2bea7 | 187 | case Draw_Top: |
7fd59977 | 188 | case Draw_Transparent: |
ffe2bea7 A |
189 | if (myIsWireframe == Standard_False) { |
190 | glPolygonOffset(1.f, -anOffset); | |
191 | glEnableClientState (GL_NORMAL_ARRAY); | |
192 | } | |
7fd59977 | 193 | myColor[theType].Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC); |
194 | aValueCol[3] = 1. - myTransparency; | |
ffe2bea7 A |
195 | if (theType == Draw_Transparent) { |
196 | glEnable(GL_BLEND); | |
197 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
198 | // don't write triangles into depth test | |
199 | glDepthMask(GL_FALSE); | |
200 | } | |
7fd59977 | 201 | break; |
202 | default: | |
203 | return; | |
204 | } | |
ffe2bea7 | 205 | // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0); |
7fd59977 | 206 | if (theType == Draw_Hilighted || |
207 | myBackColor.SquareDistance(myColor[Draw_Normal]) < 1.e-7) | |
208 | { | |
ffe2bea7 | 209 | setColor(GL_FRONT_AND_BACK, &aValueCol[0], 0.5, 10); |
7fd59977 | 210 | } else { |
ffe2bea7 | 211 | setColor(GL_FRONT, &aValueCol[0], 0.4, 10); |
7fd59977 | 212 | myBackColor.Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC); |
ffe2bea7 | 213 | setColor(GL_BACK, &aValueCol[0], 0.8, 5); |
7fd59977 | 214 | } |
215 | glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &gColorN[0]); | |
7fd59977 | 216 | glLineWidth (aLineWidth); |
7fd59977 | 217 | } |
218 | ||
219 | //======================================================================= | |
220 | //function : AfterDraw | |
cfd5fa01 | 221 | //purpose : |
7fd59977 | 222 | //======================================================================= |
223 | ||
224 | void NIS_SurfaceDrawer::AfterDraw (const DrawType theType, | |
ffe2bea7 | 225 | const NIS_DrawList&) |
7fd59977 | 226 | { |
7fd59977 | 227 | glDisable(GL_LIGHTING); |
228 | glDisableClientState(GL_VERTEX_ARRAY); | |
229 | switch (theType) { | |
ffe2bea7 A |
230 | case Draw_Transparent: |
231 | glDisable(GL_BLEND); | |
232 | glDepthMask(GL_TRUE); | |
7fd59977 | 233 | case Draw_Hilighted: |
234 | case Draw_Normal: | |
ffe2bea7 A |
235 | case Draw_Top: |
236 | if (myIsWireframe == Standard_False) | |
237 | glDisableClientState(GL_NORMAL_ARRAY); | |
7fd59977 | 238 | default:; |
239 | } | |
ffe2bea7 A |
240 | if (myIsWireframe == Standard_False) |
241 | glDisable(GL_POLYGON_OFFSET_FILL); | |
7fd59977 | 242 | } |
243 | ||
244 | //======================================================================= | |
245 | //function : Draw | |
cfd5fa01 | 246 | //purpose : |
7fd59977 | 247 | //======================================================================= |
248 | ||
249 | void NIS_SurfaceDrawer::Draw (const Handle_NIS_InteractiveObject& theObj, | |
ffe2bea7 A |
250 | const DrawType theType, |
251 | const NIS_DrawList&) | |
7fd59977 | 252 | { |
253 | // Assertion for the type of the drawn object | |
254 | #ifdef _DEBUG | |
255 | static const Handle(Standard_Type) ThisType = STANDARD_TYPE(NIS_Surface); | |
256 | Standard_ProgramError_Raise_if (theObj->IsKind(ThisType) == Standard_False, | |
ffe2bea7 | 257 | "NIS_Surface::Draw: irrelevant object type"); |
7fd59977 | 258 | #endif |
259 | const NIS_Surface * pObject = | |
260 | static_cast <const NIS_Surface *> (theObj.operator->()); | |
ffe2bea7 A |
261 | glVertexPointer (3, GL_FLOAT, 0, pObject->Node(0)); |
262 | ||
cfd5fa01 | 263 | // In Highlited mode the shape must be shown as wireframe |
ffe2bea7 A |
264 | Standard_Boolean isWireframe(myIsWireframe); |
265 | if (isWireframe == Standard_False && theType == Draw_DynHilighted) | |
266 | if (pObject->NEdges() > 0) | |
267 | isWireframe = Standard_True; | |
268 | ||
269 | if (isWireframe) | |
7fd59977 | 270 | { |
ffe2bea7 A |
271 | for (Standard_Integer i = 0; i < pObject->NEdges(); i++) { |
272 | const GLint * pEdge = static_cast<const GLint *> (pObject->Edge(i)); | |
273 | glDrawElements (GL_LINE_STRIP, pEdge[0], GL_UNSIGNED_INT, &pEdge[1]); | |
274 | } | |
275 | } else { | |
276 | if (pObject->NTriangles()) { | |
277 | if (theType != Draw_DynHilighted) | |
278 | glNormalPointer (GL_FLOAT, 0, pObject->Normal(0)); | |
279 | glDrawElements (GL_TRIANGLES, pObject->NTriangles()*3, | |
280 | GL_UNSIGNED_INT, pObject->Triangle(0)); | |
281 | } | |
7fd59977 | 282 | } |
283 | } | |
ffe2bea7 A |
284 | |
285 | //======================================================================= | |
286 | //function : setColor | |
cfd5fa01 | 287 | //purpose : |
ffe2bea7 A |
288 | //======================================================================= |
289 | ||
290 | void setColor(GLenum theFace, | |
291 | Quantity_Parameter * theAmbient, | |
292 | const Standard_Real theSpecularity, | |
293 | GLint theShininess) | |
294 | { | |
295 | GLfloat aSpec = static_cast<GLfloat>(theSpecularity); | |
296 | GLfloat aValueCol[4] = { | |
297 | GLfloat(theAmbient[0]), | |
298 | GLfloat(theAmbient[1]), | |
299 | GLfloat(theAmbient[2]), | |
300 | GLfloat(theAmbient[3]) | |
301 | }; | |
302 | glMaterialfv(theFace, GL_AMBIENT_AND_DIFFUSE, &aValueCol[0]); | |
303 | aValueCol[0] = aSpec * (aValueCol[0] - 1.f) + 1.f; | |
304 | aValueCol[1] = aSpec * (aValueCol[1] - 1.f) + 1.f; | |
305 | aValueCol[2] = aSpec * (aValueCol[2] - 1.f) + 1.f; | |
306 | aValueCol[3] = 1.f; | |
307 | glMaterialfv(theFace, GL_SPECULAR, &aValueCol[0]); | |
308 | glMateriali(theFace, GL_SHININESS, theShininess); | |
309 | } | |
310 |