Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2007-08-04 |
2 | // Created by: Alexander GRIGORIEV | |
3 | // Copyright (c) 2007-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 | ||
22 | #include <VrmlData_ShapeConvert.hxx> | |
23 | #include <VrmlData_Scene.hxx> | |
24 | #include <VrmlData_Group.hxx> | |
25 | #include <VrmlData_Coordinate.hxx> | |
26 | #include <VrmlData_IndexedFaceSet.hxx> | |
27 | #include <VrmlData_IndexedLineSet.hxx> | |
28 | #include <VrmlData_ShapeNode.hxx> | |
29 | #include <BRepMesh_IncrementalMesh.hxx> | |
30 | #include <BRep_Builder.hxx> | |
31 | #include <BRep_Tool.hxx> | |
32 | #include <Geom_Surface.hxx> | |
33 | #include <NCollection_DataMap.hxx> | |
34 | #include <Poly_Triangulation.hxx> | |
35 | #include <Poly_Connect.hxx> | |
36 | #include <Poly_PolygonOnTriangulation.hxx> | |
37 | #include <Poly_Polygon3D.hxx> | |
38 | #include <Precision.hxx> | |
39 | #include <TColgp_Array1OfPnt2d.hxx> | |
40 | #include <TopExp_Explorer.hxx> | |
41 | #include <TopoDS.hxx> | |
42 | #include <TopoDS_Edge.hxx> | |
43 | #include <TopoDS_Face.hxx> | |
44 | #include <TopoDS_Shape.hxx> | |
45 | #include <TopoDS_Wire.hxx> | |
46 | #include <GCPnts_TangentialDeflection.hxx> | |
47 | #include <BRepAdaptor_Curve.hxx> | |
48 | #include <TColStd_Array1OfReal.hxx> | |
49 | #include <TColStd_HArray1OfReal.hxx> | |
50 | #include <TShort_Array1OfShortReal.hxx> | |
51 | #include <GeomLib.hxx> | |
52 | #include <TShort_HArray1OfShortReal.hxx> | |
53 | ||
54 | //======================================================================= | |
55 | //function : IsEqual | |
56 | //purpose : for NCollection_DataMap interface | |
57 | //======================================================================= | |
58 | ||
59 | inline Standard_Boolean IsEqual (const TopoDS_Shape& one, | |
60 | const TopoDS_Shape& two) | |
61 | { | |
62 | return one == two; | |
63 | } | |
64 | ||
65 | //======================================================================= | |
66 | //function : AddShape | |
67 | //purpose : | |
68 | //======================================================================= | |
69 | ||
70 | void VrmlData_ShapeConvert::AddShape (const TopoDS_Shape& theShape, | |
71 | const char * theName) | |
72 | { | |
73 | ShapeData aData;/* = { - compilation problem on SUN | |
74 | TCollection_AsciiString(), | |
75 | theShape, | |
76 | NULL | |
77 | };*/ | |
78 | aData.Shape = theShape; | |
79 | aData.Node = NULL; | |
80 | ||
81 | if (theName) { | |
82 | char buf[2048], * optr = &buf[0]; | |
83 | char * eptr = &buf[sizeof(buf)-1]; | |
84 | for (const char * ptr = theName;; ptr++) { | |
8263fcd3 | 85 | char sym = *ptr; |
7fd59977 | 86 | if (sym == '\0' || sym == '\n' || sym == '\r') { |
87 | * optr = '\0'; | |
88 | break; | |
89 | } | |
90 | if (sym == '\"' || sym == '\\') | |
91 | * optr = '/'; | |
92 | else if (sym == '.') | |
93 | * optr = '_'; | |
94 | else | |
95 | * optr = sym; | |
96 | if (++optr >= eptr) { | |
97 | *optr = '\0'; | |
98 | break; | |
99 | } | |
100 | } | |
101 | aData.Name = buf; | |
102 | } | |
103 | myShapes.Append (aData); | |
104 | } | |
105 | ||
106 | //======================================================================= | |
107 | //function : Convert | |
108 | //purpose : | |
109 | //======================================================================= | |
110 | ||
111 | void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, | |
112 | const Standard_Boolean theExtractEdges, | |
113 | const Standard_Real theDeflection, | |
114 | const Standard_Real theDeflAngle) | |
115 | { | |
116 | const Standard_Real aDeflection = | |
117 | theDeflection < 0.0001 ? 0.0001 : theDeflection; | |
118 | ||
119 | Standard_Boolean Extract[2] = {theExtractFaces, theExtractEdges}; | |
120 | TopAbs_ShapeEnum ShapeType[2] = {TopAbs_FACE, TopAbs_EDGE}; | |
121 | Standard_Integer i; | |
122 | ||
123 | const Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator; | |
124 | ||
125 | // Relocation map for converted shapes. We should distinguish both TShape | |
126 | // and Orientation in this map. | |
127 | NCollection_DataMap <TopoDS_Shape,Handle(VrmlData_Geometry)> | |
128 | aRelMap (100, anAlloc); | |
129 | ||
130 | ||
131 | NCollection_List<ShapeData>::Iterator anIter (myShapes); | |
132 | for (; anIter.More(); anIter.Next()) { | |
133 | ||
134 | ShapeData& aData = anIter.ChangeValue(); | |
135 | Handle(VrmlData_Group) aGroup = | |
136 | new VrmlData_Group (myScene, aData.Name.ToCString()); | |
137 | myScene.AddNode (aGroup); | |
138 | ||
139 | for(i = 0; i < 2; ++i) { | |
140 | ||
141 | if(!Extract[i]) continue; | |
142 | ||
143 | TopExp_Explorer anExp (aData.Shape, ShapeType[i]); | |
144 | for (; anExp.More(); anExp.Next()) { | |
145 | const TopoDS_Shape& aShape = anExp.Current(); | |
146 | TopLoc_Location aLoc; | |
147 | Handle(VrmlData_Geometry) aTShapeNode; | |
148 | const Standard_Boolean isReverse=(aShape.Orientation()==TopAbs_REVERSED); | |
149 | ||
150 | TopoDS_Shape aTestedShape; | |
151 | aTestedShape.TShape (aShape.TShape()); | |
152 | aTestedShape.Orientation (isReverse ? TopAbs_REVERSED : TopAbs_FORWARD); | |
153 | Standard_Boolean isTessellate (Standard_False); | |
154 | switch (ShapeType[i]) { | |
155 | case TopAbs_FACE: | |
156 | { | |
157 | const TopoDS_Face& aFace = TopoDS::Face (aShape); | |
158 | if (aFace.IsNull() == Standard_False) { | |
159 | Handle(Poly_Triangulation) aTri = | |
160 | BRep_Tool::Triangulation (aFace, aLoc); | |
161 | ||
162 | if (aRelMap.IsBound (aTestedShape)) { | |
163 | aTShapeNode = aRelMap(aTestedShape); | |
164 | break; | |
165 | } | |
166 | ||
167 | if (aTri.IsNull()) | |
168 | isTessellate = Standard_True; | |
169 | // Check the existing deflection | |
170 | else if (aTri->Deflection() > aDeflection+ Precision::Confusion()) | |
171 | isTessellate = Standard_True; | |
172 | if (isTessellate) { | |
173 | // Triangulate the face by the standard OCC mesher | |
174 | BRepMesh_IncrementalMesh IM (aFace, aDeflection, Standard_False, theDeflAngle); | |
175 | aTri = BRep_Tool::Triangulation (aFace, aLoc); | |
176 | } | |
177 | if (aTri.IsNull() == Standard_False) { | |
178 | TopoDS_Shape aTestedShapeRev = aTestedShape; | |
179 | aTestedShapeRev.Orientation (isReverse ? | |
180 | TopAbs_FORWARD : TopAbs_REVERSED); | |
181 | Handle(VrmlData_IndexedFaceSet) aFaceSetToReuse; | |
182 | if (aRelMap.IsBound (aTestedShapeRev)) | |
183 | aFaceSetToReuse = Handle(VrmlData_IndexedFaceSet)::DownCast | |
184 | (aRelMap(aTestedShapeRev)); | |
185 | ||
186 | Handle(VrmlData_Coordinate) aCoordToReuse; | |
187 | if (aFaceSetToReuse.IsNull() == Standard_False) | |
188 | aCoordToReuse = aFaceSetToReuse->Coordinates(); | |
189 | ||
190 | aTShapeNode = triToIndexedFaceSet (aTri, aFace, aCoordToReuse); | |
191 | myScene.AddNode (aTShapeNode, Standard_False); | |
192 | // Bind the converted face | |
193 | aRelMap.Bind (aTestedShape, aTShapeNode); | |
194 | } | |
195 | } | |
196 | } | |
197 | break; | |
198 | case TopAbs_WIRE: | |
199 | { | |
200 | const TopoDS_Wire& aWire = TopoDS::Wire (aShape); | |
201 | if (aWire.IsNull() == Standard_False) { | |
202 | } | |
203 | } | |
204 | break; | |
205 | case TopAbs_EDGE: | |
206 | { | |
207 | const TopoDS_Edge& aEdge = TopoDS::Edge (aShape); | |
208 | if (aEdge.IsNull() == Standard_False) { | |
209 | Handle(Poly_Polygon3D) aPol = BRep_Tool::Polygon3D (aEdge, aLoc); | |
210 | ||
211 | if (aRelMap.IsBound (aTestedShape)) { | |
212 | aTShapeNode = aRelMap(aTestedShape); | |
213 | break; | |
214 | } | |
215 | // Check the presence of reversly oriented Edge. It can also be used | |
216 | // because we do not distinguish the orientation for edges. | |
217 | aTestedShape.Orientation (isReverse ? | |
218 | TopAbs_FORWARD : TopAbs_REVERSED); | |
219 | if (aRelMap.IsBound (aTestedShape)) { | |
220 | aTShapeNode = aRelMap(aTestedShape); | |
221 | break; | |
222 | } | |
223 | ||
224 | if (aPol.IsNull()) | |
225 | isTessellate = Standard_True; | |
226 | // Check the existing deflection | |
227 | else if (aPol->Deflection() > aDeflection+ Precision::Confusion() | |
228 | && BRep_Tool::IsGeometric(aEdge)) | |
229 | isTessellate = Standard_True; | |
230 | ||
231 | if (isTessellate && BRep_Tool::IsGeometric(aEdge)) { | |
232 | //try to find PolygonOnTriangulation | |
233 | Handle(Poly_PolygonOnTriangulation) aPT; | |
234 | Handle(Poly_Triangulation) aT; | |
235 | TopLoc_Location aL; | |
236 | ||
237 | Standard_Boolean found = Standard_False; | |
302f96fb | 238 | for(i = 1; ; i++) { |
7fd59977 | 239 | |
240 | BRep_Tool::PolygonOnTriangulation(aEdge, aPT, aT, aL, i); | |
241 | ||
242 | if(aPT.IsNull() || aT.IsNull()) break; | |
243 | ||
244 | if(aPT->Deflection() <= aDeflection + Precision::Confusion() && | |
245 | aPT->HasParameters()) { | |
246 | found = Standard_True; | |
247 | break; | |
248 | } | |
249 | ||
250 | } | |
251 | ||
252 | if(found) { | |
253 | ||
254 | BRepAdaptor_Curve aCurve(aEdge); | |
255 | Handle(TColStd_HArray1OfReal) aPrs = aPT->Parameters(); | |
256 | Standard_Integer nbNodes = aPT->NbNodes(); | |
257 | TColgp_Array1OfPnt arrNodes(1, nbNodes); | |
258 | TColStd_Array1OfReal arrUVNodes(1, nbNodes); | |
259 | ||
d497b314 P |
260 | for(Standard_Integer j = 1; j <= nbNodes; j++) { |
261 | arrUVNodes(j) = aPrs->Value(aPrs->Lower() + j - 1); | |
262 | arrNodes(j) = aCurve.Value(arrUVNodes(j)); | |
7fd59977 | 263 | } |
264 | aPol = new Poly_Polygon3D(arrNodes, arrUVNodes); | |
265 | aPol->Deflection (aPT->Deflection()); | |
266 | } | |
267 | else{ | |
268 | ||
269 | BRepAdaptor_Curve aCurve(aEdge); | |
270 | const Standard_Real aFirst = aCurve.FirstParameter(); | |
271 | const Standard_Real aLast = aCurve.LastParameter(); | |
272 | ||
273 | GCPnts_TangentialDeflection TD (aCurve, aFirst, aLast, | |
274 | theDeflAngle, aDeflection, 2); | |
275 | const Standard_Integer nbNodes = TD.NbPoints(); | |
276 | ||
277 | TColgp_Array1OfPnt arrNodes(1, nbNodes); | |
278 | TColStd_Array1OfReal arrUVNodes(1, nbNodes); | |
d497b314 P |
279 | for (Standard_Integer j = 1; j <= nbNodes; j++) { |
280 | arrNodes(j) = TD.Value(j); | |
281 | arrUVNodes(j) = TD.Parameter(j); | |
7fd59977 | 282 | } |
283 | aPol = new Poly_Polygon3D(arrNodes, arrUVNodes); | |
284 | aPol->Deflection (aDeflection); | |
285 | } | |
286 | ||
287 | BRep_Builder aBld; | |
288 | aBld.UpdateEdge (aEdge, aPol); | |
289 | } | |
290 | aTShapeNode = polToIndexedLineSet (aPol); | |
291 | myScene.AddNode (aTShapeNode, Standard_False); | |
292 | // Bind the converted face | |
293 | aRelMap.Bind (aTestedShape, aTShapeNode); | |
294 | } | |
295 | } | |
296 | break; | |
566f8441 | 297 | default: |
298 | break; | |
7fd59977 | 299 | } |
300 | ||
301 | if (aTShapeNode.IsNull() == Standard_False) { | |
302 | const Handle(VrmlData_ShapeNode) aShapeNode = | |
303 | new VrmlData_ShapeNode (myScene, 0L); | |
304 | aShapeNode->SetAppearance (ShapeType[i] == TopAbs_FACE ? | |
305 | defaultMaterialFace():defaultMaterialEdge()); | |
306 | myScene.AddNode (aShapeNode, Standard_False); | |
307 | aShapeNode->SetGeometry (aTShapeNode); | |
308 | if (aLoc.IsIdentity()) | |
309 | // Store the shape node directly into the main Group. | |
310 | aGroup->AddNode (aShapeNode); | |
311 | else { | |
312 | // Create a Transform grouping node | |
313 | Handle(VrmlData_Group) aTrans = new VrmlData_Group (myScene, 0L, | |
314 | Standard_True); | |
315 | gp_Trsf aTrsf (aLoc); | |
316 | if (fabs(myScale - 1.) > Precision::Confusion()) { | |
317 | const gp_XYZ aTransl = aTrsf.TranslationPart() * myScale; | |
318 | aTrsf.SetTranslationPart (aTransl); | |
319 | } | |
320 | aTrans->SetTransform (aTrsf); | |
321 | myScene.AddNode (aTrans, Standard_False); | |
322 | aGroup->AddNode (aTrans); | |
323 | ||
324 | // Store the shape node under the transform. | |
325 | aTrans->AddNode (aShapeNode); | |
326 | } | |
327 | } | |
328 | } | |
329 | } | |
330 | } | |
331 | myShapes.Clear(); | |
332 | } | |
333 | ||
334 | //======================================================================= | |
335 | //function : triToIndexedFaceSet | |
336 | //purpose : | |
337 | //======================================================================= | |
338 | ||
339 | Handle_VrmlData_Geometry VrmlData_ShapeConvert::triToIndexedFaceSet | |
340 | (const Handle_Poly_Triangulation& theTri, | |
341 | const TopoDS_Face& theFace, | |
342 | const Handle_VrmlData_Coordinate& theCoord) | |
343 | { | |
344 | Standard_Integer i; | |
345 | const Standard_Integer nNodes (theTri->NbNodes()); | |
346 | const Standard_Integer nTriangles (theTri->NbTriangles()); | |
347 | const TColgp_Array1OfPnt& arrPolyNodes = theTri->Nodes(); | |
348 | const Poly_Array1OfTriangle& arrTriangles = theTri->Triangles(); | |
349 | ||
350 | const Handle(VrmlData_IndexedFaceSet) aFaceSet = | |
351 | new VrmlData_IndexedFaceSet (myScene, | |
352 | 0L, // no name | |
353 | Standard_True, // IsCCW | |
354 | Standard_False, // IsSolid | |
355 | Standard_False); // IsConvex | |
356 | const Handle(NCollection_IncAllocator)& anAlloc = myScene.Allocator(); | |
357 | const Standard_Boolean isReverse = (theFace.Orientation() == TopAbs_REVERSED); | |
358 | ||
359 | // Create the array of triangles | |
360 | const Standard_Integer ** arrPolygons = static_cast<const Standard_Integer **> | |
361 | (anAlloc->Allocate (nTriangles * sizeof(const Standard_Integer *))); | |
362 | aFaceSet->SetPolygons (nTriangles, arrPolygons); | |
363 | ||
364 | // Store the triangles | |
365 | for (i = 0; i < nTriangles; i++) { | |
366 | Standard_Integer * aPolygon = static_cast<Standard_Integer *> | |
367 | (anAlloc->Allocate (4*sizeof(Standard_Integer))); | |
368 | aPolygon[0] = 3; | |
369 | arrTriangles(i+1).Get (aPolygon[1],aPolygon[2],aPolygon[3]); | |
370 | aPolygon[1]--; | |
371 | if (isReverse) { | |
372 | const Standard_Integer aTmp = aPolygon[2]-1; | |
373 | aPolygon[2] = aPolygon[3]-1; | |
374 | aPolygon[3] = aTmp; | |
375 | } else { | |
376 | aPolygon[2]--; | |
377 | aPolygon[3]--; | |
378 | } | |
379 | arrPolygons[i] = aPolygon; | |
380 | } | |
381 | ||
382 | // Create the Coordinates node | |
383 | if (theCoord.IsNull() == Standard_False) | |
384 | aFaceSet->SetCoordinates (theCoord); | |
385 | else { | |
386 | gp_XYZ * arrNodes = static_cast <gp_XYZ *> | |
387 | (anAlloc->Allocate (nNodes * sizeof(gp_XYZ))); | |
388 | for (i = 0; i < nNodes; i++) | |
389 | arrNodes[i] = arrPolyNodes(i+1).XYZ() * myScale; | |
390 | ||
391 | const Handle(VrmlData_Coordinate) aCoordNode = | |
392 | new VrmlData_Coordinate (myScene, 0L, nNodes, arrNodes); | |
393 | myScene.AddNode (aCoordNode, Standard_False); | |
394 | aFaceSet->SetCoordinates (aCoordNode); | |
395 | } | |
396 | ||
397 | // Create the Normals node if theTri has normals | |
398 | if(theTri->HasNormals()) { | |
399 | gp_XYZ * arrVec = static_cast <gp_XYZ *> | |
400 | (anAlloc->Allocate (nNodes * sizeof(gp_XYZ))); | |
401 | const TShort_Array1OfShortReal& Norm = theTri->Normals(); | |
402 | Standard_Integer j; | |
403 | for (i = 0, j = 1; i < nNodes; i++, j += 3) { | |
404 | ||
405 | gp_XYZ aNormal(Norm(j), Norm(j+1), Norm(j+2)); | |
406 | arrVec[i] = aNormal; | |
407 | ||
408 | } | |
409 | const Handle(VrmlData_Normal) aNormalNode = | |
410 | new VrmlData_Normal (myScene, 0L, nNodes, arrVec); | |
411 | myScene.AddNode (aNormalNode, Standard_False); | |
412 | aFaceSet->SetNormals (aNormalNode); | |
413 | return aFaceSet; | |
414 | } | |
415 | ||
416 | Poly_Connect PC(theTri); | |
417 | // Create the Normals node (if UV- values are available) | |
418 | TopLoc_Location aLoc; | |
08cd2f6b | 419 | const Standard_Real aConf2 = Precision::SquareConfusion(); |
7fd59977 | 420 | const Handle(Geom_Surface) aSurface = BRep_Tool::Surface (theFace, aLoc); |
421 | if (theTri->HasUVNodes() && aSurface.IsNull() == Standard_False) { | |
422 | if (aSurface->IsCNu(1) && aSurface->IsCNv(1)) | |
423 | { | |
424 | Standard_Integer nbNormVal = nNodes * 3; | |
425 | Handle(TShort_HArray1OfShortReal) Normals = | |
426 | new TShort_HArray1OfShortReal(1, nbNormVal); | |
427 | ||
428 | const TColgp_Array1OfPnt2d& arrUV = theTri->UVNodes(); | |
429 | gp_XYZ * arrVec = static_cast <gp_XYZ *> | |
430 | (anAlloc->Allocate (nNodes * sizeof(gp_XYZ))); | |
431 | ||
432 | // Compute the normal vectors | |
433 | Standard_Real Tol = Sqrt(aConf2); | |
434 | for (i = 0; i < nNodes; i++) { | |
435 | const gp_Pnt2d& aUV = arrUV(i+1); | |
436 | ||
437 | gp_Dir aNormal; | |
438 | ||
439 | if (GeomLib::NormEstim(aSurface, aUV, Tol, aNormal) > 1) { | |
440 | //Try to estimate as middle normal of adjacent triangles | |
441 | Standard_Integer n[3]; | |
442 | ||
443 | gp_XYZ eqPlan(0., 0., 0.); | |
444 | for (PC.Initialize(i+1); PC.More(); PC.Next()) { | |
445 | arrTriangles(PC.Value()).Get(n[0], n[1], n[2]); | |
446 | gp_XYZ v1(arrPolyNodes(n[1]).Coord()-arrPolyNodes(n[0]).Coord()); | |
447 | gp_XYZ v2(arrPolyNodes(n[2]).Coord()-arrPolyNodes(n[1]).Coord()); | |
448 | gp_XYZ vv = v1^v2; | |
449 | ||
450 | Standard_Real mod = vv.Modulus(); | |
451 | if (mod < Tol) | |
452 | continue; | |
453 | ||
454 | eqPlan += vv/mod; | |
455 | } | |
456 | ||
457 | if (eqPlan.SquareModulus() > gp::Resolution()) | |
458 | aNormal = gp_Dir(eqPlan); | |
459 | } | |
460 | if (isReverse) | |
461 | aNormal.Reverse(); | |
462 | ||
463 | if (aNormal.X()*aNormal.X() < aConf2) | |
464 | aNormal.SetX(0.); | |
465 | if (aNormal.Y()*aNormal.Y() < aConf2) | |
466 | aNormal.SetY(0.); | |
467 | if (aNormal.Z()*aNormal.Z() < aConf2) | |
468 | aNormal.SetZ(0.); | |
469 | arrVec[i] = aNormal.XYZ(); | |
470 | ||
471 | Standard_Integer j = i * 3; | |
7f4c4756 | 472 | Normals->SetValue(j + 1, (Standard_ShortReal)aNormal.X()); |
473 | Normals->SetValue(j + 2, (Standard_ShortReal)aNormal.Y()); | |
474 | Normals->SetValue(j + 3, (Standard_ShortReal)aNormal.Z()); | |
7fd59977 | 475 | |
476 | } | |
477 | ||
478 | theTri->SetNormals(Normals); | |
479 | ||
480 | const Handle(VrmlData_Normal) aNormalNode = | |
481 | new VrmlData_Normal (myScene, 0L, nNodes, arrVec); | |
482 | myScene.AddNode (aNormalNode, Standard_False); | |
483 | aFaceSet->SetNormals (aNormalNode); | |
484 | } | |
485 | } | |
486 | ||
487 | return aFaceSet; | |
488 | } | |
489 | ||
490 | //======================================================================= | |
491 | //function : polToIndexedLineSet | |
492 | //purpose : single polygon3D => IndexedLineSet | |
493 | //======================================================================= | |
494 | ||
495 | Handle_VrmlData_Geometry VrmlData_ShapeConvert::polToIndexedLineSet | |
496 | (const Handle_Poly_Polygon3D& thePol) | |
497 | { | |
498 | Standard_Integer i; | |
499 | const Standard_Integer nNodes (thePol->NbNodes()); | |
500 | const TColgp_Array1OfPnt& arrPolyNodes = thePol->Nodes(); | |
501 | const Handle(NCollection_IncAllocator)& anAlloc = myScene.Allocator(); | |
502 | ||
503 | const Handle(VrmlData_IndexedLineSet) aLineSet = | |
504 | new VrmlData_IndexedLineSet (myScene, 0L); | |
505 | ||
506 | // Create the array of polygons (1 member) | |
507 | const Standard_Integer ** arrPolygons = static_cast<const Standard_Integer **> | |
508 | (anAlloc->Allocate (sizeof(const Standard_Integer *))); | |
509 | aLineSet->SetPolygons (1, arrPolygons); | |
510 | ||
511 | // Store the polygon | |
512 | Standard_Integer * aPolygon = static_cast<Standard_Integer *> | |
513 | (anAlloc->Allocate ((nNodes+1)*sizeof(Standard_Integer))); | |
514 | aPolygon[0] = nNodes; | |
515 | for (i = 1; i <= nNodes; i++) | |
516 | aPolygon[i] = i-1; | |
517 | arrPolygons[0] = aPolygon; | |
518 | ||
519 | // Create the Coordinates node | |
520 | gp_XYZ * arrNodes = static_cast <gp_XYZ *> | |
521 | (anAlloc->Allocate (nNodes * sizeof(gp_XYZ))); | |
522 | for (i = 0; i < nNodes; i++) | |
523 | arrNodes[i] = arrPolyNodes(i+1).XYZ() * myScale; | |
524 | ||
525 | const Handle(VrmlData_Coordinate) aCoordNode = | |
526 | new VrmlData_Coordinate (myScene, 0L, nNodes, arrNodes); | |
527 | myScene.AddNode (aCoordNode, Standard_False); | |
528 | aLineSet->SetCoordinates (aCoordNode); | |
529 | ||
530 | return aLineSet; | |
531 | } | |
532 | ||
533 | //======================================================================= | |
534 | //function : defaultMaterialFace | |
535 | //purpose : | |
536 | //======================================================================= | |
537 | ||
538 | Handle(VrmlData_Appearance) VrmlData_ShapeConvert::defaultMaterialFace () const | |
539 | { | |
540 | static char aNodeName[] = "__defaultMaterialFace"; | |
541 | Handle(VrmlData_Appearance) anAppearance = | |
542 | Handle(VrmlData_Appearance)::DownCast(myScene.FindNode(aNodeName)); | |
543 | if (anAppearance.IsNull()) { | |
544 | const Handle(VrmlData_Material) aMaterial = | |
545 | new VrmlData_Material (myScene, 0L, 1.0, 0.022, 0.); | |
546 | aMaterial->SetDiffuseColor (Quantity_Color(0.780392, 0.568627, 0.113725, | |
547 | Quantity_TOC_RGB)); | |
548 | aMaterial->SetEmissiveColor(Quantity_Color(0.329412, 0.223529, 0.027451, | |
549 | Quantity_TOC_RGB)); | |
550 | aMaterial->SetSpecularColor(Quantity_Color(0.992157, 0.941176, 0.807843, | |
551 | Quantity_TOC_RGB)); | |
552 | myScene.AddNode (aMaterial, Standard_False); | |
553 | anAppearance = new VrmlData_Appearance (myScene, aNodeName); | |
554 | anAppearance->SetMaterial (aMaterial); | |
555 | myScene.AddNode (anAppearance, Standard_False); | |
556 | } | |
557 | return anAppearance; | |
558 | } | |
559 | ||
560 | //======================================================================= | |
561 | //function : defaultMaterialEdge | |
562 | //purpose : | |
563 | //======================================================================= | |
564 | ||
565 | Handle(VrmlData_Appearance) VrmlData_ShapeConvert::defaultMaterialEdge () const | |
566 | { | |
567 | static char aNodeName[] = "__defaultMaterialEdge"; | |
568 | Handle(VrmlData_Appearance) anAppearance = | |
569 | Handle(VrmlData_Appearance)::DownCast(myScene.FindNode(aNodeName)); | |
570 | if (anAppearance.IsNull()) { | |
571 | const Handle(VrmlData_Material) aMaterial = | |
572 | new VrmlData_Material (myScene, 0L, 0.2, 0.2, 0.2); | |
573 | aMaterial->SetDiffuseColor (Quantity_Color(0.2, 0.7, 0.2, | |
574 | Quantity_TOC_RGB)); | |
575 | aMaterial->SetEmissiveColor(Quantity_Color(0.2, 0.7, 0.2, | |
576 | Quantity_TOC_RGB)); | |
577 | aMaterial->SetSpecularColor(Quantity_Color(0.2, 0.7, 0.2, | |
578 | Quantity_TOC_RGB)); | |
579 | myScene.AddNode (aMaterial, Standard_False); | |
580 | anAppearance = new VrmlData_Appearance (myScene, aNodeName); | |
581 | anAppearance->SetMaterial (aMaterial); | |
582 | myScene.AddNode (anAppearance, Standard_False); | |
583 | } | |
584 | return anAppearance; | |
585 | } |