5ad8c033 |
1 | // Created on: 2014-10-14 |
2 | // Created by: Anton POLETAEV |
3 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
4 | // |
5 | // This file is part of Open CASCADE Technology software library. |
6 | // |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
12 | // |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
15 | |
16 | #include <StdPrs_WFShape.hxx> |
17 | |
18 | #include <BRep_Tool.hxx> |
19 | #include <BRepAdaptor_Curve.hxx> |
20 | #include <BRepAdaptor_Surface.hxx> |
21 | #include <BRepAdaptor_HSurface.hxx> |
884cafd8 |
22 | #include <OSD_Parallel.hxx> |
5ad8c033 |
23 | #include <StdPrs_DeflectionCurve.hxx> |
5ad8c033 |
24 | #include <StdPrs_Isolines.hxx> |
7f24b768 |
25 | #include <StdPrs_ShapeTool.hxx> |
26 | #include <StdPrs_ToolTriangulatedShape.hxx> |
5ad8c033 |
27 | #include <Standard_ErrorHandler.hxx> |
5ad8c033 |
28 | #include <Prs3d_IsoAspect.hxx> |
5ad8c033 |
29 | #include <Prs3d.hxx> |
5ad8c033 |
30 | #include <Poly_PolygonOnTriangulation.hxx> |
31 | #include <Poly_Polygon3D.hxx> |
32 | #include <Poly_Triangulation.hxx> |
33 | #include <Graphic3d_AspectLine3d.hxx> |
5ad8c033 |
34 | #include <Graphic3d_ArrayOfSegments.hxx> |
35 | #include <Graphic3d_ArrayOfPoints.hxx> |
36 | #include <gp_Pnt.hxx> |
37 | #include <TColgp_HSequenceOfPnt.hxx> |
38 | #include <TColStd_Array1OfInteger.hxx> |
39 | #include <TopoDS_Edge.hxx> |
40 | #include <TopoDS_Face.hxx> |
41 | #include <TopoDS.hxx> |
bf5f0ca2 |
42 | #include <TopExp.hxx> |
5ad8c033 |
43 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
00af0ebb |
44 | #include <Standard_Mutex.hxx> |
5ad8c033 |
45 | |
884cafd8 |
46 | //! Functor for executing StdPrs_Isolines in parallel threads. |
47 | class StdPrs_WFShape_IsoFunctor |
48 | { |
49 | public: |
50 | StdPrs_WFShape_IsoFunctor (Prs3d_NListOfSequenceOfPnt& thePolylinesU, |
51 | Prs3d_NListOfSequenceOfPnt& thePolylinesV, |
52 | const std::vector<TopoDS_Face>& theFaces, |
53 | const Handle(Prs3d_Drawer)& theDrawer, |
54 | Standard_Real theShapeDeflection) |
55 | : myPolylinesU (thePolylinesU), |
56 | myPolylinesV (thePolylinesV), |
57 | myFaces (theFaces), |
58 | myDrawer (theDrawer), |
59 | myShapeDeflection (theShapeDeflection) |
60 | { |
61 | // |
62 | } |
63 | |
64 | void operator()(const Standard_Integer& theIndex) const |
65 | { |
66 | Prs3d_NListOfSequenceOfPnt aPolylinesU, aPolylinesV; |
67 | const TopoDS_Face& aFace = myFaces[theIndex]; |
68 | StdPrs_Isolines::Add (aFace, myDrawer, myShapeDeflection, aPolylinesU, aPolylinesV); |
69 | { |
70 | Standard_Mutex::Sentry aLock (myMutex); |
71 | myPolylinesU.Append (aPolylinesU); |
72 | myPolylinesV.Append (aPolylinesV); |
73 | } |
74 | } |
75 | |
76 | private: |
77 | StdPrs_WFShape_IsoFunctor operator= (StdPrs_WFShape_IsoFunctor& ); |
78 | private: |
79 | Prs3d_NListOfSequenceOfPnt& myPolylinesU; |
80 | Prs3d_NListOfSequenceOfPnt& myPolylinesV; |
81 | const std::vector<TopoDS_Face>& myFaces; |
82 | const Handle(Prs3d_Drawer)& myDrawer; |
83 | mutable Standard_Mutex myMutex; |
84 | const Standard_Real myShapeDeflection; |
85 | }; |
86 | |
87 | |
5ad8c033 |
88 | // ========================================================================= |
89 | // function : Add |
90 | // purpose : |
91 | // ========================================================================= |
884cafd8 |
92 | void StdPrs_WFShape::Add (const Handle(Prs3d_Presentation)& thePresentation, |
93 | const TopoDS_Shape& theShape, |
94 | const Handle(Prs3d_Drawer)& theDrawer, |
95 | Standard_Boolean theIsParallel) |
5ad8c033 |
96 | { |
97 | if (theShape.IsNull()) |
98 | { |
99 | return; |
100 | } |
101 | |
29263c94 |
102 | if (theDrawer->IsAutoTriangulation()) |
103 | { |
104 | StdPrs_ToolTriangulatedShape::Tessellate (theShape, theDrawer); |
105 | } |
106 | |
bf5f0ca2 |
107 | // draw triangulation-only edges |
108 | if (Handle(Graphic3d_ArrayOfPrimitives) aTriFreeEdges = AddEdgesOnTriangulation (theShape, Standard_True)) |
5ad8c033 |
109 | { |
bf5f0ca2 |
110 | Handle(Graphic3d_Group) aGroup = thePresentation->NewGroup(); |
111 | aGroup->SetPrimitivesAspect (theDrawer->FreeBoundaryAspect()->Aspect()); |
112 | aGroup->AddPrimitiveArray (aTriFreeEdges); |
5ad8c033 |
113 | } |
5ad8c033 |
114 | |
1b9f5d95 |
115 | Prs3d_NListOfSequenceOfPnt aCommonPolylines; |
116 | const Handle(Prs3d_LineAspect)& aWireAspect = theDrawer->WireAspect(); |
7f24b768 |
117 | const Standard_Real aShapeDeflection = StdPrs_ToolTriangulatedShape::GetDeflection (theShape, theDrawer); |
1b9f5d95 |
118 | |
119 | // Draw isolines |
5ad8c033 |
120 | { |
1b9f5d95 |
121 | Prs3d_NListOfSequenceOfPnt aUPolylines, aVPolylines; |
122 | Prs3d_NListOfSequenceOfPnt* aUPolylinesPtr = &aUPolylines; |
123 | Prs3d_NListOfSequenceOfPnt* aVPolylinesPtr = &aVPolylines; |
124 | |
125 | const Handle(Prs3d_LineAspect)& anIsoAspectU = theDrawer->UIsoAspect(); |
126 | const Handle(Prs3d_LineAspect)& anIsoAspectV = theDrawer->VIsoAspect(); |
127 | if (anIsoAspectV->Aspect()->IsEqual (*anIsoAspectU->Aspect())) |
128 | { |
bf5f0ca2 |
129 | aVPolylinesPtr = aUPolylinesPtr; // put both U and V isolines into single group |
1b9f5d95 |
130 | } |
131 | if (anIsoAspectU->Aspect()->IsEqual (*aWireAspect->Aspect())) |
132 | { |
bf5f0ca2 |
133 | aUPolylinesPtr = &aCommonPolylines; // put U isolines into single group with common edges |
1b9f5d95 |
134 | } |
135 | if (anIsoAspectV->Aspect()->IsEqual (*aWireAspect->Aspect())) |
136 | { |
bf5f0ca2 |
137 | aVPolylinesPtr = &aCommonPolylines; // put V isolines into single group with common edges |
1b9f5d95 |
138 | } |
139 | |
884cafd8 |
140 | bool isParallelIso = false; |
141 | if (theIsParallel) |
1b9f5d95 |
142 | { |
884cafd8 |
143 | Standard_Integer aNbFaces = 0; |
144 | for (TopExp_Explorer aFaceExplorer (theShape, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next()) |
1b9f5d95 |
145 | { |
884cafd8 |
146 | ++aNbFaces; |
1b9f5d95 |
147 | } |
884cafd8 |
148 | if (aNbFaces > 1) |
149 | { |
150 | isParallelIso = true; |
151 | std::vector<TopoDS_Face> aFaces (aNbFaces); |
152 | aNbFaces = 0; |
153 | for (TopExp_Explorer aFaceExplorer (theShape, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next()) |
154 | { |
155 | const TopoDS_Face& aFace = TopoDS::Face (aFaceExplorer.Current()); |
7f24b768 |
156 | if (theDrawer->IsoOnPlane() || !StdPrs_ShapeTool::IsPlanarFace (aFace)) |
884cafd8 |
157 | { |
158 | aFaces[aNbFaces++] = aFace; |
159 | } |
160 | } |
1b9f5d95 |
161 | |
884cafd8 |
162 | StdPrs_WFShape_IsoFunctor anIsoFunctor (*aUPolylinesPtr, *aVPolylinesPtr, aFaces, theDrawer, aShapeDeflection); |
5e3047fd |
163 | OSD_Parallel::For (0, aNbFaces, anIsoFunctor, aNbFaces < 2); |
884cafd8 |
164 | } |
165 | } |
166 | |
167 | if (!isParallelIso) |
168 | { |
169 | for (TopExp_Explorer aFaceExplorer (theShape, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next()) |
170 | { |
171 | const TopoDS_Face& aFace = TopoDS::Face (aFaceExplorer.Current()); |
7f24b768 |
172 | if (theDrawer->IsoOnPlane() || !StdPrs_ShapeTool::IsPlanarFace (aFace)) |
884cafd8 |
173 | { |
174 | StdPrs_Isolines::Add (aFace, theDrawer, aShapeDeflection, *aUPolylinesPtr, *aVPolylinesPtr); |
175 | } |
176 | } |
1b9f5d95 |
177 | } |
178 | |
179 | Prs3d::AddPrimitivesGroup (thePresentation, anIsoAspectU, aUPolylines); |
180 | Prs3d::AddPrimitivesGroup (thePresentation, anIsoAspectV, aVPolylines); |
5ad8c033 |
181 | } |
182 | |
5ad8c033 |
183 | { |
bf5f0ca2 |
184 | Prs3d_NListOfSequenceOfPnt anUnfree, aFree; |
185 | Prs3d_NListOfSequenceOfPnt* anUnfreePtr = &anUnfree; |
186 | Prs3d_NListOfSequenceOfPnt* aFreePtr = &aFree; |
187 | if (!theDrawer->UnFreeBoundaryDraw()) |
1b9f5d95 |
188 | { |
bf5f0ca2 |
189 | anUnfreePtr = NULL; |
1b9f5d95 |
190 | } |
bf5f0ca2 |
191 | else if (theDrawer->UnFreeBoundaryAspect()->Aspect()->IsEqual (*aWireAspect->Aspect())) |
1b9f5d95 |
192 | { |
bf5f0ca2 |
193 | anUnfreePtr = &aCommonPolylines; // put unfree edges into single group with common edges |
1b9f5d95 |
194 | } |
5ad8c033 |
195 | |
bf5f0ca2 |
196 | if (!theDrawer->FreeBoundaryDraw()) |
1b9f5d95 |
197 | { |
bf5f0ca2 |
198 | aFreePtr = NULL; |
1b9f5d95 |
199 | } |
bf5f0ca2 |
200 | else if (theDrawer->FreeBoundaryAspect()->Aspect()->IsEqual (*aWireAspect->Aspect())) |
1b9f5d95 |
201 | { |
bf5f0ca2 |
202 | aFreePtr = &aCommonPolylines; // put free edges into single group with common edges |
1b9f5d95 |
203 | } |
bf5f0ca2 |
204 | |
205 | addEdges (theShape, |
206 | theDrawer, |
207 | aShapeDeflection, |
208 | theDrawer->WireDraw() ? &aCommonPolylines : NULL, |
209 | aFreePtr, |
210 | anUnfreePtr); |
211 | Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->UnFreeBoundaryAspect(), anUnfree); |
212 | Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->FreeBoundaryAspect(), aFree); |
5ad8c033 |
213 | } |
214 | |
1b9f5d95 |
215 | Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->WireAspect(), aCommonPolylines); |
216 | |
bf5f0ca2 |
217 | if (Handle(Graphic3d_ArrayOfPoints) aVertexArray = AddVertexes (theShape, theDrawer->VertexDrawMode())) |
5ad8c033 |
218 | { |
bf5f0ca2 |
219 | Handle(Graphic3d_Group) aGroup = thePresentation->NewGroup(); |
220 | aGroup->SetPrimitivesAspect (theDrawer->PointAspect()->Aspect()); |
221 | aGroup->AddPrimitiveArray (aVertexArray); |
222 | } |
223 | } |
224 | |
225 | // ========================================================================= |
226 | // function : AddAllEdges |
227 | // purpose : |
228 | // ========================================================================= |
229 | Handle(Graphic3d_ArrayOfPrimitives) StdPrs_WFShape::AddAllEdges (const TopoDS_Shape& theShape, |
230 | const Handle(Prs3d_Drawer)& theDrawer) |
231 | { |
7f24b768 |
232 | const Standard_Real aShapeDeflection = StdPrs_ToolTriangulatedShape::GetDeflection (theShape, theDrawer); |
bf5f0ca2 |
233 | Prs3d_NListOfSequenceOfPnt aPolylines; |
234 | addEdges (theShape, theDrawer, aShapeDeflection, |
235 | &aPolylines, &aPolylines, &aPolylines); |
236 | return Prs3d::PrimitivesFromPolylines (aPolylines); |
237 | } |
238 | |
239 | // ========================================================================= |
240 | // function : addEdges |
241 | // purpose : |
242 | // ========================================================================= |
243 | void StdPrs_WFShape::addEdges (const TopoDS_Shape& theShape, |
244 | const Handle(Prs3d_Drawer)& theDrawer, |
245 | Standard_Real theShapeDeflection, |
246 | Prs3d_NListOfSequenceOfPnt* theWire, |
247 | Prs3d_NListOfSequenceOfPnt* theFree, |
248 | Prs3d_NListOfSequenceOfPnt* theUnFree) |
249 | { |
250 | if (theShape.IsNull()) |
251 | { |
252 | return; |
253 | } |
254 | |
255 | TopTools_ListOfShape aLWire, aLFree, aLUnFree; |
256 | TopTools_IndexedDataMapOfShapeListOfShape anEdgeMap; |
257 | TopExp::MapShapesAndAncestors (theShape, TopAbs_EDGE, TopAbs_FACE, anEdgeMap); |
258 | for (TopTools_IndexedDataMapOfShapeListOfShape::Iterator anEdgeIter (anEdgeMap); anEdgeIter.More(); anEdgeIter.Next()) |
259 | { |
260 | const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key()); |
261 | const Standard_Integer aNbNeighbours = anEdgeIter.Value().Extent(); |
262 | switch (aNbNeighbours) |
1b9f5d95 |
263 | { |
bf5f0ca2 |
264 | case 0: |
265 | { |
266 | if (theWire != NULL) |
267 | { |
268 | aLWire.Append (anEdge); |
269 | } |
270 | break; |
271 | } |
272 | case 1: |
273 | { |
274 | if (theFree != NULL) |
275 | { |
276 | aLFree.Append (anEdge); |
277 | } |
278 | break; |
279 | } |
280 | default: |
281 | { |
282 | if (theUnFree) |
283 | { |
284 | aLUnFree.Append (anEdge); |
285 | } |
286 | break; |
287 | } |
5ad8c033 |
288 | } |
5ad8c033 |
289 | } |
bf5f0ca2 |
290 | |
291 | if (!aLWire.IsEmpty()) |
292 | { |
293 | addEdges (aLWire, theDrawer, theShapeDeflection, *theWire); |
294 | } |
295 | if (!aLFree.IsEmpty()) |
296 | { |
297 | addEdges (aLFree, theDrawer, theShapeDeflection, *theFree); |
298 | } |
299 | if (!aLUnFree.IsEmpty()) |
300 | { |
301 | addEdges (aLUnFree, theDrawer, theShapeDeflection, *theUnFree); |
302 | } |
5ad8c033 |
303 | } |
304 | |
305 | // ========================================================================= |
306 | // function : AddEdges |
307 | // purpose : |
308 | // ========================================================================= |
1b9f5d95 |
309 | void StdPrs_WFShape::addEdges (const TopTools_ListOfShape& theEdges, |
310 | const Handle (Prs3d_Drawer)& theDrawer, |
311 | const Standard_Real theShapeDeflection, |
312 | Prs3d_NListOfSequenceOfPnt& thePolylines) |
5ad8c033 |
313 | { |
5ad8c033 |
314 | TopTools_ListIteratorOfListOfShape anEdgesIter; |
315 | for (anEdgesIter.Initialize (theEdges); anEdgesIter.More(); anEdgesIter.Next()) |
316 | { |
317 | const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgesIter.Value()); |
318 | if (BRep_Tool::Degenerated (anEdge)) |
319 | { |
320 | continue; |
321 | } |
322 | |
323 | Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt; |
324 | |
325 | TopLoc_Location aLocation; |
326 | Handle(Poly_Triangulation) aTriangulation; |
327 | Handle(Poly_PolygonOnTriangulation) anEdgeIndicies; |
328 | BRep_Tool::PolygonOnTriangulation (anEdge, anEdgeIndicies, aTriangulation, aLocation); |
329 | Handle(Poly_Polygon3D) aPolygon; |
330 | |
331 | if (!anEdgeIndicies.IsNull()) |
332 | { |
333 | // Presentation based on triangulation of a face. |
334 | const TColStd_Array1OfInteger& anIndices = anEdgeIndicies->Nodes(); |
335 | const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes(); |
336 | |
337 | Standard_Integer anIndex = anIndices.Lower(); |
338 | if (aLocation.IsIdentity()) |
339 | { |
340 | for (; anIndex <= anIndices.Upper(); ++anIndex) |
341 | { |
342 | aPoints->Append (aNodes (anIndices (anIndex))); |
343 | } |
344 | } |
345 | else |
346 | { |
347 | for (; anIndex <= anIndices.Upper(); ++anIndex) |
348 | { |
349 | aPoints->Append (aNodes (anIndices (anIndex)).Transformed (aLocation)); |
350 | } |
351 | } |
352 | } |
353 | else if (!(aPolygon = BRep_Tool::Polygon3D (anEdge, aLocation)).IsNull()) |
354 | { |
355 | // Presentation based on triangulation of the free edge on a surface. |
356 | const TColgp_Array1OfPnt& aNodes = aPolygon->Nodes(); |
357 | Standard_Integer anIndex = aNodes.Lower(); |
358 | if (aLocation.IsIdentity()) |
359 | { |
360 | for (; anIndex <= aNodes.Upper(); ++anIndex) |
361 | { |
362 | aPoints->Append (aNodes.Value (anIndex)); |
363 | } |
364 | } |
365 | else |
366 | { |
367 | for (; anIndex <= aNodes.Upper(); ++anIndex) |
368 | { |
369 | aPoints->Append (aNodes.Value (anIndex).Transformed (aLocation)); |
370 | } |
371 | } |
372 | } |
373 | else if (BRep_Tool::IsGeometric (anEdge)) |
374 | { |
375 | // Default presentation for edges without triangulation. |
376 | BRepAdaptor_Curve aCurve (anEdge); |
1b9f5d95 |
377 | StdPrs_DeflectionCurve::Add (Handle(Prs3d_Presentation)(), |
5ad8c033 |
378 | aCurve, |
379 | theShapeDeflection, |
380 | theDrawer, |
381 | aPoints->ChangeSequence(), |
382 | Standard_False); |
383 | } |
384 | |
385 | if (!aPoints->IsEmpty()) |
386 | { |
1b9f5d95 |
387 | thePolylines.Append (aPoints); |
5ad8c033 |
388 | } |
389 | } |
5ad8c033 |
390 | } |
391 | |
392 | // ========================================================================= |
393 | // function : AddEdgesOnTriangulation |
394 | // purpose : |
395 | // ========================================================================= |
0a863061 |
396 | Handle(Graphic3d_ArrayOfPrimitives) StdPrs_WFShape::AddEdgesOnTriangulation (const TopoDS_Shape& theShape, |
397 | const Standard_Boolean theToExcludeGeometric) |
5ad8c033 |
398 | { |
0a863061 |
399 | TColgp_SequenceOfPnt aSeqPnts; |
400 | AddEdgesOnTriangulation (aSeqPnts, theShape, theToExcludeGeometric); |
401 | if (aSeqPnts.Size() < 2) |
402 | { |
403 | return Handle(Graphic3d_ArrayOfSegments)(); |
404 | } |
5ad8c033 |
405 | |
0a863061 |
406 | Standard_Integer aNbVertices = aSeqPnts.Size(); |
407 | Handle(Graphic3d_ArrayOfSegments) aSurfArray = new Graphic3d_ArrayOfSegments (aNbVertices); |
408 | for (Standard_Integer anI = 1; anI <= aNbVertices; anI += 2) |
5ad8c033 |
409 | { |
0a863061 |
410 | aSurfArray->AddVertex (aSeqPnts.Value (anI)); |
411 | aSurfArray->AddVertex (aSeqPnts.Value (anI + 1)); |
412 | } |
413 | return aSurfArray; |
414 | } |
5ad8c033 |
415 | |
0a863061 |
416 | // ========================================================================= |
417 | // function : AddEdgesOnTriangulation |
418 | // purpose : |
419 | // ========================================================================= |
420 | void StdPrs_WFShape::AddEdgesOnTriangulation (TColgp_SequenceOfPnt& theSegments, |
421 | const TopoDS_Shape& theShape, |
422 | const Standard_Boolean theToExcludeGeometric) |
423 | { |
424 | TopLoc_Location aLocation, aDummyLoc; |
425 | for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next()) |
426 | { |
427 | const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Current()); |
428 | if (theToExcludeGeometric) |
429 | { |
430 | const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aDummyLoc); |
431 | if (!aSurf.IsNull()) |
432 | { |
433 | continue; |
434 | } |
435 | } |
7f24b768 |
436 | if (const Handle(Poly_Triangulation)& aPolyTri = BRep_Tool::Triangulation (aFace, aLocation)) |
5ad8c033 |
437 | { |
7f24b768 |
438 | Prs3d::AddFreeEdges (theSegments, aPolyTri, aLocation); |
5ad8c033 |
439 | } |
440 | } |
5ad8c033 |
441 | } |
442 | |
443 | // ========================================================================= |
bf5f0ca2 |
444 | // function : AddVertexes |
5ad8c033 |
445 | // purpose : |
446 | // ========================================================================= |
bf5f0ca2 |
447 | Handle(Graphic3d_ArrayOfPoints) StdPrs_WFShape::AddVertexes (const TopoDS_Shape& theShape, |
448 | Prs3d_VertexDrawMode theVertexMode) |
5ad8c033 |
449 | { |
bf5f0ca2 |
450 | TColgp_SequenceOfPnt aShapeVertices; |
451 | if (theVertexMode == Prs3d_VDM_All) |
5ad8c033 |
452 | { |
bf5f0ca2 |
453 | for (TopExp_Explorer aVertIter (theShape, TopAbs_VERTEX); aVertIter.More(); aVertIter.Next()) |
454 | { |
455 | const TopoDS_Vertex& aVert = TopoDS::Vertex (aVertIter.Current()); |
456 | aShapeVertices.Append (BRep_Tool::Pnt (aVert)); |
457 | } |
5ad8c033 |
458 | } |
bf5f0ca2 |
459 | else |
460 | { |
461 | // isolated vertices |
462 | for (TopExp_Explorer aVertIter (theShape, TopAbs_VERTEX, TopAbs_EDGE); aVertIter.More(); aVertIter.Next()) |
463 | { |
464 | const TopoDS_Vertex& aVert = TopoDS::Vertex (aVertIter.Current()); |
465 | aShapeVertices.Append (BRep_Tool::Pnt (aVert)); |
466 | } |
5ad8c033 |
467 | |
bf5f0ca2 |
468 | // internal vertices |
469 | for (TopExp_Explorer anEdgeIter (theShape, TopAbs_EDGE); anEdgeIter.More(); anEdgeIter.Next()) |
470 | { |
471 | for (TopoDS_Iterator aVertIter (anEdgeIter.Current(), Standard_False, Standard_True); aVertIter.More(); aVertIter.Next()) |
472 | { |
473 | const TopoDS_Shape& aVertSh = aVertIter.Value(); |
474 | if (aVertSh.Orientation() == TopAbs_INTERNAL |
475 | && aVertSh.ShapeType() == TopAbs_VERTEX) |
476 | { |
477 | const TopoDS_Vertex& aVert = TopoDS::Vertex (aVertSh); |
478 | aShapeVertices.Append (BRep_Tool::Pnt (aVert)); |
479 | } |
480 | } |
481 | } |
482 | } |
483 | |
484 | if (aShapeVertices.IsEmpty()) |
5ad8c033 |
485 | { |
bf5f0ca2 |
486 | return Handle(Graphic3d_ArrayOfPoints)(); |
5ad8c033 |
487 | } |
488 | |
bf5f0ca2 |
489 | const Standard_Integer aNbVertices = aShapeVertices.Length(); |
490 | Handle(Graphic3d_ArrayOfPoints) aVertexArray = new Graphic3d_ArrayOfPoints (aNbVertices); |
491 | for (Standard_Integer aVertIter = 1; aVertIter <= aNbVertices; ++aVertIter) |
492 | { |
493 | aVertexArray->AddVertex (aShapeVertices.Value (aVertIter)); |
494 | } |
495 | return aVertexArray; |
5ad8c033 |
496 | } |