1 // Created on: 2008-03-20
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2008-2012 OPEN CASCADE SAS
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.
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.
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.
21 #include <NIS_SurfaceDrawer.hxx>
22 #include <NIS_Surface.hxx>
23 #include <NIS_InteractiveObject.hxx>
24 #include <Standard_ProgramError.hxx>
26 #include <OpenGl_GlCore11.hxx>
28 static void setColor(GLenum theFace,
29 Quantity_Parameter * theAmbient,
30 const Standard_Real theSpecularity,
33 IMPLEMENT_STANDARD_HANDLE (NIS_SurfaceDrawer, NIS_Drawer)
34 IMPLEMENT_STANDARD_RTTIEXT (NIS_SurfaceDrawer, NIS_Drawer)
36 //=======================================================================
37 //function : NIS_SurfaceDrawer()
38 //purpose : Constructor
39 //=======================================================================
41 NIS_SurfaceDrawer::NIS_SurfaceDrawer
42 (const Quantity_Color &theNormal,
43 const Quantity_Color &theHilight,
44 const Quantity_Color &theDynHilight)
45 : myBackColor (theNormal),
46 myPolygonOffset (0.f),
47 myIsWireframe (Standard_False)
49 myColor[Draw_Normal] = theNormal;
50 myColor[Draw_Top] = theNormal;
51 myColor[Draw_Transparent] = theNormal;
52 myColor[Draw_Hilighted] = theHilight;
53 myColor[Draw_DynHilighted] = theDynHilight;
56 //=======================================================================
59 //=======================================================================
61 void NIS_SurfaceDrawer::SetColor(const Quantity_Color &theColor)
63 myColor[Draw_Normal] = theColor;
64 myColor[Draw_Top] = theColor;
65 myColor[Draw_Transparent] = theColor;
68 //=======================================================================
71 //=======================================================================
73 void NIS_SurfaceDrawer::Assign (const Handle_NIS_Drawer& theOther)
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];
80 myColor[Draw_Top] = anOther->myColor[Draw_Top];
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;
85 myPolygonOffset = anOther->myPolygonOffset;
86 myIsWireframe = anOther->myIsWireframe;
90 //=======================================================================
92 //purpose : Comparison of two Drawers (for Map impementation)
93 //=======================================================================
95 Standard_Boolean NIS_SurfaceDrawer::IsEqual
96 (const Handle_NIS_Drawer& theOther)const
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 &&
111 myIsWireframe == anOther->myIsWireframe);
113 // Arbitrary point for test
115 gp_XYZ(113., -31.3, 29.19),
116 gp_XYZ(113., -31.3, 29.19)
118 anOther->myTrsf.Transforms(aPnt[0]);
119 myTrsf.Transforms(aPnt[1]);
120 if ((aPnt[0] - aPnt[1]).SquareModulus() > anEpsilon2)
121 aResult = Standard_False;
126 //=======================================================================
129 //=======================================================================
131 void NIS_SurfaceDrawer::redraw (const DrawType theType,
132 const Handle_NIS_View& theView)
134 glMatrixMode( GL_MODELVIEW );
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.
144 glMultMatrixd( aMatrix );
146 NIS_Drawer::redraw(theType, theView);
151 //=======================================================================
152 //function : BeforeDraw
154 //=======================================================================
156 void NIS_SurfaceDrawer::BeforeDraw (const DrawType theType,
159 glEnable(GL_LIGHTING);
160 // glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
161 glEnableClientState (GL_VERTEX_ARRAY);
162 if (myIsWireframe == Standard_False) {
163 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
164 glEnable(GL_POLYGON_OFFSET_FILL);
165 glShadeModel(GL_SMOOTH);
168 Quantity_Parameter aValueCol[4] = {0., 0., 0., 1.};
169 Quantity_TypeOfColor bidTC (Quantity_TOC_RGB);
170 GLfloat aLineWidth (1.f);
171 GLfloat anOffset = myPolygonOffset;
172 static const GLfloat gColorN[4] = {0.f, 0.f, 0.f, 1.f};
175 case Draw_DynHilighted:
177 myColor[theType].Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC);
178 setColor(GL_FRONT_AND_BACK, &aValueCol[0], 0.1, 5);
179 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &gColorN[0]);
180 glLineWidth (aLineWidth);
181 if (myIsWireframe == Standard_False)
182 glPolygonOffset(1.f, -(anOffset + 11.f));
188 case Draw_Transparent:
189 if (myIsWireframe == Standard_False) {
190 glPolygonOffset(1.f, -anOffset);
191 glEnableClientState (GL_NORMAL_ARRAY);
193 myColor[theType].Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC);
194 aValueCol[3] = 1. - myTransparency;
195 if (theType == Draw_Transparent) {
197 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
198 // don't write triangles into depth test
199 glDepthMask(GL_FALSE);
205 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
206 if (theType == Draw_Hilighted ||
207 myBackColor.SquareDistance(myColor[Draw_Normal]) < 1.e-7)
209 setColor(GL_FRONT_AND_BACK, &aValueCol[0], 0.5, 10);
211 setColor(GL_FRONT, &aValueCol[0], 0.4, 10);
212 myBackColor.Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC);
213 setColor(GL_BACK, &aValueCol[0], 0.8, 5);
215 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &gColorN[0]);
216 glLineWidth (aLineWidth);
219 //=======================================================================
220 //function : AfterDraw
222 //=======================================================================
224 void NIS_SurfaceDrawer::AfterDraw (const DrawType theType,
227 glDisable(GL_LIGHTING);
228 glDisableClientState(GL_VERTEX_ARRAY);
230 case Draw_Transparent:
232 glDepthMask(GL_TRUE);
236 if (myIsWireframe == Standard_False)
237 glDisableClientState(GL_NORMAL_ARRAY);
240 if (myIsWireframe == Standard_False)
241 glDisable(GL_POLYGON_OFFSET_FILL);
244 //=======================================================================
247 //=======================================================================
249 void NIS_SurfaceDrawer::Draw (const Handle_NIS_InteractiveObject& theObj,
250 const DrawType theType,
253 // Assertion for the type of the drawn object
255 static const Handle(Standard_Type) ThisType = STANDARD_TYPE(NIS_Surface);
256 Standard_ProgramError_Raise_if (theObj->IsKind(ThisType) == Standard_False,
257 "NIS_Surface::Draw: irrelevant object type");
259 const NIS_Surface * pObject =
260 static_cast <const NIS_Surface *> (theObj.operator->());
261 glVertexPointer (3, GL_FLOAT, 0, pObject->Node(0));
263 // In Highlited mode the shape must be shown as wireframe
264 Standard_Boolean isWireframe(myIsWireframe);
265 if (isWireframe == Standard_False && theType == Draw_DynHilighted)
266 if (pObject->NEdges() > 0)
267 isWireframe = Standard_True;
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]);
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));
285 //=======================================================================
286 //function : setColor
288 //=======================================================================
290 void setColor(GLenum theFace,
291 Quantity_Parameter * theAmbient,
292 const Standard_Real theSpecularity,
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])
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;
307 glMaterialfv(theFace, GL_SPECULAR, &aValueCol[0]);
308 glMateriali(theFace, GL_SHININESS, theShininess);