1 // File: NIS_SurfaceDrawer.cpp
2 // Created: 20.03.08 09:09
3 // Author: Alexander GRIGORIEV
4 // Copyright: Open Cascade S.A. 2008
6 #include <NIS_SurfaceDrawer.hxx>
7 #include <NIS_Surface.hxx>
8 #include <NIS_InteractiveObject.hxx>
9 #include <Standard_ProgramError.hxx>
16 static void setColor(GLenum theFace,
17 Quantity_Parameter * theAmbient,
18 const Standard_Real theSpecularity,
21 IMPLEMENT_STANDARD_HANDLE (NIS_SurfaceDrawer, NIS_Drawer)
22 IMPLEMENT_STANDARD_RTTIEXT (NIS_SurfaceDrawer, NIS_Drawer)
24 //=======================================================================
25 //function : NIS_SurfaceDrawer()
26 //purpose : Constructor
27 //=======================================================================
29 NIS_SurfaceDrawer::NIS_SurfaceDrawer
30 (const Quantity_Color &theNormal,
31 const Quantity_Color &theHilight,
32 const Quantity_Color &theDynHilight)
33 : myBackColor (theNormal),
34 myPolygonOffset (0.f),
35 myIsWireframe (Standard_False)
37 myColor[Draw_Normal] = theNormal;
38 myColor[Draw_Top] = theNormal;
39 myColor[Draw_Transparent] = theNormal;
40 myColor[Draw_Hilighted] = theHilight;
41 myColor[Draw_DynHilighted] = theDynHilight;
44 //=======================================================================
47 //=======================================================================
49 void NIS_SurfaceDrawer::SetColor(const Quantity_Color &theColor)
51 myColor[Draw_Normal] = theColor;
52 myColor[Draw_Top] = theColor;
53 myColor[Draw_Transparent] = theColor;
56 //=======================================================================
59 //=======================================================================
61 void NIS_SurfaceDrawer::Assign (const Handle_NIS_Drawer& theOther)
63 if (theOther.IsNull() == Standard_False) {
64 NIS_Drawer::Assign (theOther);
65 const Handle(NIS_SurfaceDrawer)& anOther =
66 static_cast <const Handle(NIS_SurfaceDrawer)&> (theOther);
67 myColor[Draw_Normal] = anOther->myColor[Draw_Normal];
68 myColor[Draw_Top] = anOther->myColor[Draw_Top];
69 myColor[Draw_Transparent] = anOther->myColor[Draw_Transparent];
70 myColor[Draw_Hilighted] = anOther->myColor[Draw_Hilighted];
71 myColor[Draw_DynHilighted] = anOther->myColor[Draw_DynHilighted];
72 myBackColor = anOther->myBackColor;
73 myPolygonOffset = anOther->myPolygonOffset;
74 myIsWireframe = anOther->myIsWireframe;
78 //=======================================================================
80 //purpose : Comparison of two Drawers (for Map impementation)
81 //=======================================================================
83 Standard_Boolean NIS_SurfaceDrawer::IsEqual
84 (const Handle_NIS_Drawer& theOther)const
86 static const Standard_Real anEpsilon2 (1e-7);
87 Standard_Boolean aResult (Standard_False);
88 const Handle(NIS_SurfaceDrawer) anOther =
89 Handle(NIS_SurfaceDrawer)::DownCast (theOther);
90 if (NIS_Drawer::IsEqual(theOther))
91 aResult = (anOther->myColor[Draw_Normal]
92 .SquareDistance (myColor[Draw_Normal]) < anEpsilon2 &&
93 anOther->myColor[Draw_Hilighted]
94 .SquareDistance (myColor[Draw_Hilighted]) < anEpsilon2 &&
95 anOther->myColor[Draw_DynHilighted]
96 .SquareDistance (myColor[Draw_DynHilighted]) < anEpsilon2 &&
97 anOther->myBackColor.SquareDistance(myBackColor) < anEpsilon2 &&
98 fabs(anOther->myPolygonOffset - myPolygonOffset) < 0.999 &&
99 myIsWireframe == anOther->myIsWireframe);
101 // Arbitrary point for test
103 gp_XYZ(113., -31.3, 29.19),
104 gp_XYZ(113., -31.3, 29.19)
106 anOther->myTrsf.Transforms(aPnt[0]);
107 myTrsf.Transforms(aPnt[1]);
108 if ((aPnt[0] - aPnt[1]).SquareModulus() > anEpsilon2)
109 aResult = Standard_False;
114 //=======================================================================
117 //=======================================================================
119 void NIS_SurfaceDrawer::redraw (const DrawType theType,
120 const Handle_NIS_View& theView)
122 glMatrixMode( GL_MODELVIEW );
125 GLdouble aMatrix[16] = {
126 myTrsf.Value(1,1), myTrsf.Value(2,1), myTrsf.Value(3,1), 0.,
127 myTrsf.Value(1,2), myTrsf.Value(2,2), myTrsf.Value(3,2), 0.,
128 myTrsf.Value(1,3), myTrsf.Value(2,3), myTrsf.Value(3,3), 0.,
129 myTrsf.Value(1,4), myTrsf.Value(2,4), myTrsf.Value(3,4), 1.
132 glMultMatrixd( aMatrix );
134 NIS_Drawer::redraw(theType, theView);
139 //=======================================================================
140 //function : BeforeDraw
142 //=======================================================================
144 void NIS_SurfaceDrawer::BeforeDraw (const DrawType theType,
147 glEnable(GL_LIGHTING);
148 // glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
149 glEnableClientState (GL_VERTEX_ARRAY);
150 if (myIsWireframe == Standard_False) {
151 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
152 glEnable(GL_POLYGON_OFFSET_FILL);
153 glShadeModel(GL_SMOOTH);
156 Quantity_Parameter aValueCol[4] = {0., 0., 0., 1.};
157 Quantity_TypeOfColor bidTC (Quantity_TOC_RGB);
158 GLfloat aLineWidth (1.f);
159 GLfloat anOffset = myPolygonOffset;
160 static const GLfloat gColorN[4] = {0.f, 0.f, 0.f, 1.f};
163 case Draw_DynHilighted:
165 myColor[theType].Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC);
166 setColor(GL_FRONT_AND_BACK, &aValueCol[0], 0.1, 5);
167 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &gColorN[0]);
168 glLineWidth (aLineWidth);
169 if (myIsWireframe == Standard_False)
170 glPolygonOffset(1.f, -(anOffset + 11.f));
176 case Draw_Transparent:
177 if (myIsWireframe == Standard_False) {
178 glPolygonOffset(1.f, -anOffset);
179 glEnableClientState (GL_NORMAL_ARRAY);
181 myColor[theType].Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC);
182 aValueCol[3] = 1. - myTransparency;
183 if (theType == Draw_Transparent) {
185 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
186 // don't write triangles into depth test
187 glDepthMask(GL_FALSE);
193 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
194 if (theType == Draw_Hilighted ||
195 myBackColor.SquareDistance(myColor[Draw_Normal]) < 1.e-7)
197 setColor(GL_FRONT_AND_BACK, &aValueCol[0], 0.5, 10);
199 setColor(GL_FRONT, &aValueCol[0], 0.4, 10);
200 myBackColor.Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC);
201 setColor(GL_BACK, &aValueCol[0], 0.8, 5);
203 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &gColorN[0]);
204 glLineWidth (aLineWidth);
207 //=======================================================================
208 //function : AfterDraw
210 //=======================================================================
212 void NIS_SurfaceDrawer::AfterDraw (const DrawType theType,
215 glDisable(GL_LIGHTING);
216 glDisableClientState(GL_VERTEX_ARRAY);
218 case Draw_Transparent:
220 glDepthMask(GL_TRUE);
224 if (myIsWireframe == Standard_False)
225 glDisableClientState(GL_NORMAL_ARRAY);
228 if (myIsWireframe == Standard_False)
229 glDisable(GL_POLYGON_OFFSET_FILL);
232 //=======================================================================
235 //=======================================================================
237 void NIS_SurfaceDrawer::Draw (const Handle_NIS_InteractiveObject& theObj,
238 const DrawType theType,
241 // Assertion for the type of the drawn object
243 static const Handle(Standard_Type) ThisType = STANDARD_TYPE(NIS_Surface);
244 Standard_ProgramError_Raise_if (theObj->IsKind(ThisType) == Standard_False,
245 "NIS_Surface::Draw: irrelevant object type");
247 const NIS_Surface * pObject =
248 static_cast <const NIS_Surface *> (theObj.operator->());
249 glVertexPointer (3, GL_FLOAT, 0, pObject->Node(0));
251 // In Highlited mode the shape must be shown as wireframe
252 Standard_Boolean isWireframe(myIsWireframe);
253 if (isWireframe == Standard_False && theType == Draw_DynHilighted)
254 if (pObject->NEdges() > 0)
255 isWireframe = Standard_True;
259 for (Standard_Integer i = 0; i < pObject->NEdges(); i++) {
260 const GLint * pEdge = static_cast<const GLint *> (pObject->Edge(i));
261 glDrawElements (GL_LINE_STRIP, pEdge[0], GL_UNSIGNED_INT, &pEdge[1]);
264 if (pObject->NTriangles()) {
265 if (theType != Draw_DynHilighted)
266 glNormalPointer (GL_FLOAT, 0, pObject->Normal(0));
267 glDrawElements (GL_TRIANGLES, pObject->NTriangles()*3,
268 GL_UNSIGNED_INT, pObject->Triangle(0));
273 //=======================================================================
274 //function : setColor
276 //=======================================================================
278 void setColor(GLenum theFace,
279 Quantity_Parameter * theAmbient,
280 const Standard_Real theSpecularity,
283 GLfloat aSpec = static_cast<GLfloat>(theSpecularity);
284 GLfloat aValueCol[4] = {
285 GLfloat(theAmbient[0]),
286 GLfloat(theAmbient[1]),
287 GLfloat(theAmbient[2]),
288 GLfloat(theAmbient[3])
290 glMaterialfv(theFace, GL_AMBIENT_AND_DIFFUSE, &aValueCol[0]);
291 aValueCol[0] = aSpec * (aValueCol[0] - 1.f) + 1.f;
292 aValueCol[1] = aSpec * (aValueCol[1] - 1.f) + 1.f;
293 aValueCol[2] = aSpec * (aValueCol[2] - 1.f) + 1.f;
295 glMaterialfv(theFace, GL_SPECULAR, &aValueCol[0]);
296 glMateriali(theFace, GL_SHININESS, theShininess);