0029570: Visualization, Graphic3d_Aspect - merge Graphic3d_Group aspects
[occt.git] / src / StdPrs / StdPrs_WFShape.cxx
CommitLineData
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>
24#include <StdPrs_ToolTriangulatedShape.hxx>
25#include <StdPrs_Isolines.hxx>
26#include <Standard_ErrorHandler.hxx>
27#include <Prs3d_ShapeTool.hxx>
28#include <Prs3d_IsoAspect.hxx>
5ad8c033 29#include <Prs3d.hxx>
30#include <Poly_Connect.hxx>
31#include <Poly_PolygonOnTriangulation.hxx>
32#include <Poly_Polygon3D.hxx>
33#include <Poly_Triangulation.hxx>
34#include <Graphic3d_AspectLine3d.hxx>
5ad8c033 35#include <Graphic3d_ArrayOfSegments.hxx>
36#include <Graphic3d_ArrayOfPoints.hxx>
37#include <gp_Pnt.hxx>
38#include <TColgp_HSequenceOfPnt.hxx>
39#include <TColStd_Array1OfInteger.hxx>
40#include <TopoDS_Edge.hxx>
41#include <TopoDS_Face.hxx>
42#include <TopoDS.hxx>
bf5f0ca2 43#include <TopExp.hxx>
5ad8c033 44#include <TopTools_ListIteratorOfListOfShape.hxx>
00af0ebb 45#include <Standard_Mutex.hxx>
5ad8c033 46
884cafd8 47//! Functor for executing StdPrs_Isolines in parallel threads.
48class StdPrs_WFShape_IsoFunctor
49{
50public:
51 StdPrs_WFShape_IsoFunctor (Prs3d_NListOfSequenceOfPnt& thePolylinesU,
52 Prs3d_NListOfSequenceOfPnt& thePolylinesV,
53 const std::vector<TopoDS_Face>& theFaces,
54 const Handle(Prs3d_Drawer)& theDrawer,
55 Standard_Real theShapeDeflection)
56 : myPolylinesU (thePolylinesU),
57 myPolylinesV (thePolylinesV),
58 myFaces (theFaces),
59 myDrawer (theDrawer),
60 myShapeDeflection (theShapeDeflection)
61 {
62 //
63 }
64
65 void operator()(const Standard_Integer& theIndex) const
66 {
67 Prs3d_NListOfSequenceOfPnt aPolylinesU, aPolylinesV;
68 const TopoDS_Face& aFace = myFaces[theIndex];
69 StdPrs_Isolines::Add (aFace, myDrawer, myShapeDeflection, aPolylinesU, aPolylinesV);
70 {
71 Standard_Mutex::Sentry aLock (myMutex);
72 myPolylinesU.Append (aPolylinesU);
73 myPolylinesV.Append (aPolylinesV);
74 }
75 }
76
77private:
78 StdPrs_WFShape_IsoFunctor operator= (StdPrs_WFShape_IsoFunctor& );
79private:
80 Prs3d_NListOfSequenceOfPnt& myPolylinesU;
81 Prs3d_NListOfSequenceOfPnt& myPolylinesV;
82 const std::vector<TopoDS_Face>& myFaces;
83 const Handle(Prs3d_Drawer)& myDrawer;
84 mutable Standard_Mutex myMutex;
85 const Standard_Real myShapeDeflection;
86};
87
88
5ad8c033 89// =========================================================================
90// function : Add
91// purpose :
92// =========================================================================
884cafd8 93void StdPrs_WFShape::Add (const Handle(Prs3d_Presentation)& thePresentation,
94 const TopoDS_Shape& theShape,
95 const Handle(Prs3d_Drawer)& theDrawer,
96 Standard_Boolean theIsParallel)
5ad8c033 97{
98 if (theShape.IsNull())
99 {
100 return;
101 }
102
bf5f0ca2 103 // draw triangulation-only edges
104 if (Handle(Graphic3d_ArrayOfPrimitives) aTriFreeEdges = AddEdgesOnTriangulation (theShape, Standard_True))
5ad8c033 105 {
bf5f0ca2 106 Handle(Graphic3d_Group) aGroup = thePresentation->NewGroup();
107 aGroup->SetPrimitivesAspect (theDrawer->FreeBoundaryAspect()->Aspect());
108 aGroup->AddPrimitiveArray (aTriFreeEdges);
5ad8c033 109 }
5ad8c033 110
1b9f5d95 111 Prs3d_NListOfSequenceOfPnt aCommonPolylines;
112 const Handle(Prs3d_LineAspect)& aWireAspect = theDrawer->WireAspect();
bf5f0ca2 113 const Standard_Real aShapeDeflection = Prs3d::GetDeflection (theShape, theDrawer);
1b9f5d95 114
115 // Draw isolines
5ad8c033 116 {
1b9f5d95 117 Prs3d_NListOfSequenceOfPnt aUPolylines, aVPolylines;
118 Prs3d_NListOfSequenceOfPnt* aUPolylinesPtr = &aUPolylines;
119 Prs3d_NListOfSequenceOfPnt* aVPolylinesPtr = &aVPolylines;
120
121 const Handle(Prs3d_LineAspect)& anIsoAspectU = theDrawer->UIsoAspect();
122 const Handle(Prs3d_LineAspect)& anIsoAspectV = theDrawer->VIsoAspect();
123 if (anIsoAspectV->Aspect()->IsEqual (*anIsoAspectU->Aspect()))
124 {
bf5f0ca2 125 aVPolylinesPtr = aUPolylinesPtr; // put both U and V isolines into single group
1b9f5d95 126 }
127 if (anIsoAspectU->Aspect()->IsEqual (*aWireAspect->Aspect()))
128 {
bf5f0ca2 129 aUPolylinesPtr = &aCommonPolylines; // put U isolines into single group with common edges
1b9f5d95 130 }
131 if (anIsoAspectV->Aspect()->IsEqual (*aWireAspect->Aspect()))
132 {
bf5f0ca2 133 aVPolylinesPtr = &aCommonPolylines; // put V isolines into single group with common edges
1b9f5d95 134 }
135
884cafd8 136 bool isParallelIso = false;
137 if (theIsParallel)
1b9f5d95 138 {
884cafd8 139 Standard_Integer aNbFaces = 0;
140 for (TopExp_Explorer aFaceExplorer (theShape, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next())
1b9f5d95 141 {
884cafd8 142 ++aNbFaces;
1b9f5d95 143 }
884cafd8 144 if (aNbFaces > 1)
145 {
146 isParallelIso = true;
147 std::vector<TopoDS_Face> aFaces (aNbFaces);
148 aNbFaces = 0;
149 for (TopExp_Explorer aFaceExplorer (theShape, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next())
150 {
151 const TopoDS_Face& aFace = TopoDS::Face (aFaceExplorer.Current());
152 if (theDrawer->IsoOnPlane() || !Prs3d_ShapeTool::IsPlanarFace (aFace))
153 {
154 aFaces[aNbFaces++] = aFace;
155 }
156 }
1b9f5d95 157
884cafd8 158 StdPrs_WFShape_IsoFunctor anIsoFunctor (*aUPolylinesPtr, *aVPolylinesPtr, aFaces, theDrawer, aShapeDeflection);
5e3047fd 159 OSD_Parallel::For (0, aNbFaces, anIsoFunctor, aNbFaces < 2);
884cafd8 160 }
161 }
162
163 if (!isParallelIso)
164 {
165 for (TopExp_Explorer aFaceExplorer (theShape, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next())
166 {
167 const TopoDS_Face& aFace = TopoDS::Face (aFaceExplorer.Current());
168 if (theDrawer->IsoOnPlane() || !Prs3d_ShapeTool::IsPlanarFace (aFace))
169 {
170 StdPrs_Isolines::Add (aFace, theDrawer, aShapeDeflection, *aUPolylinesPtr, *aVPolylinesPtr);
171 }
172 }
1b9f5d95 173 }
174
175 Prs3d::AddPrimitivesGroup (thePresentation, anIsoAspectU, aUPolylines);
176 Prs3d::AddPrimitivesGroup (thePresentation, anIsoAspectV, aVPolylines);
5ad8c033 177 }
178
5ad8c033 179 {
bf5f0ca2 180 Prs3d_NListOfSequenceOfPnt anUnfree, aFree;
181 Prs3d_NListOfSequenceOfPnt* anUnfreePtr = &anUnfree;
182 Prs3d_NListOfSequenceOfPnt* aFreePtr = &aFree;
183 if (!theDrawer->UnFreeBoundaryDraw())
1b9f5d95 184 {
bf5f0ca2 185 anUnfreePtr = NULL;
1b9f5d95 186 }
bf5f0ca2 187 else if (theDrawer->UnFreeBoundaryAspect()->Aspect()->IsEqual (*aWireAspect->Aspect()))
1b9f5d95 188 {
bf5f0ca2 189 anUnfreePtr = &aCommonPolylines; // put unfree edges into single group with common edges
1b9f5d95 190 }
5ad8c033 191
bf5f0ca2 192 if (!theDrawer->FreeBoundaryDraw())
1b9f5d95 193 {
bf5f0ca2 194 aFreePtr = NULL;
1b9f5d95 195 }
bf5f0ca2 196 else if (theDrawer->FreeBoundaryAspect()->Aspect()->IsEqual (*aWireAspect->Aspect()))
1b9f5d95 197 {
bf5f0ca2 198 aFreePtr = &aCommonPolylines; // put free edges into single group with common edges
1b9f5d95 199 }
bf5f0ca2 200
201 addEdges (theShape,
202 theDrawer,
203 aShapeDeflection,
204 theDrawer->WireDraw() ? &aCommonPolylines : NULL,
205 aFreePtr,
206 anUnfreePtr);
207 Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->UnFreeBoundaryAspect(), anUnfree);
208 Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->FreeBoundaryAspect(), aFree);
5ad8c033 209 }
210
1b9f5d95 211 Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->WireAspect(), aCommonPolylines);
212
bf5f0ca2 213 if (Handle(Graphic3d_ArrayOfPoints) aVertexArray = AddVertexes (theShape, theDrawer->VertexDrawMode()))
5ad8c033 214 {
bf5f0ca2 215 Handle(Graphic3d_Group) aGroup = thePresentation->NewGroup();
216 aGroup->SetPrimitivesAspect (theDrawer->PointAspect()->Aspect());
217 aGroup->AddPrimitiveArray (aVertexArray);
218 }
219}
220
221// =========================================================================
222// function : AddAllEdges
223// purpose :
224// =========================================================================
225Handle(Graphic3d_ArrayOfPrimitives) StdPrs_WFShape::AddAllEdges (const TopoDS_Shape& theShape,
226 const Handle(Prs3d_Drawer)& theDrawer)
227{
228 const Standard_Real aShapeDeflection = Prs3d::GetDeflection (theShape, theDrawer);
229 Prs3d_NListOfSequenceOfPnt aPolylines;
230 addEdges (theShape, theDrawer, aShapeDeflection,
231 &aPolylines, &aPolylines, &aPolylines);
232 return Prs3d::PrimitivesFromPolylines (aPolylines);
233}
234
235// =========================================================================
236// function : addEdges
237// purpose :
238// =========================================================================
239void StdPrs_WFShape::addEdges (const TopoDS_Shape& theShape,
240 const Handle(Prs3d_Drawer)& theDrawer,
241 Standard_Real theShapeDeflection,
242 Prs3d_NListOfSequenceOfPnt* theWire,
243 Prs3d_NListOfSequenceOfPnt* theFree,
244 Prs3d_NListOfSequenceOfPnt* theUnFree)
245{
246 if (theShape.IsNull())
247 {
248 return;
249 }
250
251 TopTools_ListOfShape aLWire, aLFree, aLUnFree;
252 TopTools_IndexedDataMapOfShapeListOfShape anEdgeMap;
253 TopExp::MapShapesAndAncestors (theShape, TopAbs_EDGE, TopAbs_FACE, anEdgeMap);
254 for (TopTools_IndexedDataMapOfShapeListOfShape::Iterator anEdgeIter (anEdgeMap); anEdgeIter.More(); anEdgeIter.Next())
255 {
256 const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key());
257 const Standard_Integer aNbNeighbours = anEdgeIter.Value().Extent();
258 switch (aNbNeighbours)
1b9f5d95 259 {
bf5f0ca2 260 case 0:
261 {
262 if (theWire != NULL)
263 {
264 aLWire.Append (anEdge);
265 }
266 break;
267 }
268 case 1:
269 {
270 if (theFree != NULL)
271 {
272 aLFree.Append (anEdge);
273 }
274 break;
275 }
276 default:
277 {
278 if (theUnFree)
279 {
280 aLUnFree.Append (anEdge);
281 }
282 break;
283 }
5ad8c033 284 }
5ad8c033 285 }
bf5f0ca2 286
287 if (!aLWire.IsEmpty())
288 {
289 addEdges (aLWire, theDrawer, theShapeDeflection, *theWire);
290 }
291 if (!aLFree.IsEmpty())
292 {
293 addEdges (aLFree, theDrawer, theShapeDeflection, *theFree);
294 }
295 if (!aLUnFree.IsEmpty())
296 {
297 addEdges (aLUnFree, theDrawer, theShapeDeflection, *theUnFree);
298 }
5ad8c033 299}
300
301// =========================================================================
302// function : AddEdges
303// purpose :
304// =========================================================================
1b9f5d95 305void StdPrs_WFShape::addEdges (const TopTools_ListOfShape& theEdges,
306 const Handle (Prs3d_Drawer)& theDrawer,
307 const Standard_Real theShapeDeflection,
308 Prs3d_NListOfSequenceOfPnt& thePolylines)
5ad8c033 309{
5ad8c033 310 TopTools_ListIteratorOfListOfShape anEdgesIter;
311 for (anEdgesIter.Initialize (theEdges); anEdgesIter.More(); anEdgesIter.Next())
312 {
313 const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgesIter.Value());
314 if (BRep_Tool::Degenerated (anEdge))
315 {
316 continue;
317 }
318
319 Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt;
320
321 TopLoc_Location aLocation;
322 Handle(Poly_Triangulation) aTriangulation;
323 Handle(Poly_PolygonOnTriangulation) anEdgeIndicies;
324 BRep_Tool::PolygonOnTriangulation (anEdge, anEdgeIndicies, aTriangulation, aLocation);
325 Handle(Poly_Polygon3D) aPolygon;
326
327 if (!anEdgeIndicies.IsNull())
328 {
329 // Presentation based on triangulation of a face.
330 const TColStd_Array1OfInteger& anIndices = anEdgeIndicies->Nodes();
331 const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
332
333 Standard_Integer anIndex = anIndices.Lower();
334 if (aLocation.IsIdentity())
335 {
336 for (; anIndex <= anIndices.Upper(); ++anIndex)
337 {
338 aPoints->Append (aNodes (anIndices (anIndex)));
339 }
340 }
341 else
342 {
343 for (; anIndex <= anIndices.Upper(); ++anIndex)
344 {
345 aPoints->Append (aNodes (anIndices (anIndex)).Transformed (aLocation));
346 }
347 }
348 }
349 else if (!(aPolygon = BRep_Tool::Polygon3D (anEdge, aLocation)).IsNull())
350 {
351 // Presentation based on triangulation of the free edge on a surface.
352 const TColgp_Array1OfPnt& aNodes = aPolygon->Nodes();
353 Standard_Integer anIndex = aNodes.Lower();
354 if (aLocation.IsIdentity())
355 {
356 for (; anIndex <= aNodes.Upper(); ++anIndex)
357 {
358 aPoints->Append (aNodes.Value (anIndex));
359 }
360 }
361 else
362 {
363 for (; anIndex <= aNodes.Upper(); ++anIndex)
364 {
365 aPoints->Append (aNodes.Value (anIndex).Transformed (aLocation));
366 }
367 }
368 }
369 else if (BRep_Tool::IsGeometric (anEdge))
370 {
371 // Default presentation for edges without triangulation.
372 BRepAdaptor_Curve aCurve (anEdge);
1b9f5d95 373 StdPrs_DeflectionCurve::Add (Handle(Prs3d_Presentation)(),
5ad8c033 374 aCurve,
375 theShapeDeflection,
376 theDrawer,
377 aPoints->ChangeSequence(),
378 Standard_False);
379 }
380
381 if (!aPoints->IsEmpty())
382 {
1b9f5d95 383 thePolylines.Append (aPoints);
5ad8c033 384 }
385 }
5ad8c033 386}
387
388// =========================================================================
389// function : AddEdgesOnTriangulation
390// purpose :
391// =========================================================================
0a863061 392Handle(Graphic3d_ArrayOfPrimitives) StdPrs_WFShape::AddEdgesOnTriangulation (const TopoDS_Shape& theShape,
393 const Standard_Boolean theToExcludeGeometric)
5ad8c033 394{
0a863061 395 TColgp_SequenceOfPnt aSeqPnts;
396 AddEdgesOnTriangulation (aSeqPnts, theShape, theToExcludeGeometric);
397 if (aSeqPnts.Size() < 2)
398 {
399 return Handle(Graphic3d_ArrayOfSegments)();
400 }
5ad8c033 401
0a863061 402 Standard_Integer aNbVertices = aSeqPnts.Size();
403 Handle(Graphic3d_ArrayOfSegments) aSurfArray = new Graphic3d_ArrayOfSegments (aNbVertices);
404 for (Standard_Integer anI = 1; anI <= aNbVertices; anI += 2)
5ad8c033 405 {
0a863061 406 aSurfArray->AddVertex (aSeqPnts.Value (anI));
407 aSurfArray->AddVertex (aSeqPnts.Value (anI + 1));
408 }
409 return aSurfArray;
410}
5ad8c033 411
0a863061 412// =========================================================================
413// function : AddEdgesOnTriangulation
414// purpose :
415// =========================================================================
416void StdPrs_WFShape::AddEdgesOnTriangulation (TColgp_SequenceOfPnt& theSegments,
417 const TopoDS_Shape& theShape,
418 const Standard_Boolean theToExcludeGeometric)
419{
420 TopLoc_Location aLocation, aDummyLoc;
421 for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
422 {
423 const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Current());
424 if (theToExcludeGeometric)
425 {
426 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aDummyLoc);
427 if (!aSurf.IsNull())
428 {
429 continue;
430 }
431 }
432 const Handle(Poly_Triangulation)& T = BRep_Tool::Triangulation (aFace, aLocation);
5ad8c033 433 if (T.IsNull())
434 {
435 continue;
436 }
437
438 const TColgp_Array1OfPnt& aNodes = T->Nodes();
439
440 // Build the connect tool.
441 Poly_Connect aPolyConnect (T);
442
443 Standard_Integer aNbTriangles = T->NbTriangles();
444 Standard_Integer aT[3];
445 Standard_Integer aN[3];
446
447 // Count the free edges.
448 Standard_Integer aNbFree = 0;
449 for (Standard_Integer anI = 1; anI <= aNbTriangles; ++anI)
450 {
451 aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]);
452 for (Standard_Integer aJ = 0; aJ < 3; ++aJ)
453 {
454 if (aT[aJ] == 0)
455 {
456 ++aNbFree;
457 }
458 }
459 }
460
413b1c1a 461 if (aNbFree == 0)
462 {
463 continue;
464 }
465
5ad8c033 466 // Allocate the arrays.
467 TColStd_Array1OfInteger aFree (1, 2 * aNbFree);
468 Standard_Integer aNbInternal = (3 * aNbTriangles - aNbFree) / 2;
469 TColStd_Array1OfInteger anInternal (0, 2 * aNbInternal);
470
471 Standard_Integer aFreeIndex = 1, anIntIndex = 1;
472 const Poly_Array1OfTriangle& aTriangles = T->Triangles();
473 for (Standard_Integer anI = 1; anI <= aNbTriangles; ++anI)
474 {
475 aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]);
476 aTriangles (anI).Get (aN[0], aN[1], aN[2]);
477 for (Standard_Integer aJ = 0; aJ < 3; aJ++)
478 {
479 Standard_Integer k = (aJ + 1) % 3;
480 if (aT[aJ] == 0)
481 {
482 aFree (aFreeIndex) = aN[aJ];
483 aFree (aFreeIndex + 1) = aN[k];
484 aFreeIndex += 2;
485 }
486 // internal edge if this triangle has a lower index than the adjacent.
487 else if (anI < aT[aJ])
488 {
489 anInternal (anIntIndex) = aN[aJ];
490 anInternal (anIntIndex + 1) = aN[k];
491 anIntIndex += 2;
492 }
493 }
494 }
495
496 // free edges
497 Standard_Integer aFreeHalfNb = aFree.Length() / 2;
498 for (Standard_Integer anI = 1; anI <= aFreeHalfNb; ++anI)
499 {
500 gp_Pnt aPoint1 = aNodes (aFree (2 * anI - 1)).Transformed (aLocation);
501 gp_Pnt aPoint2 = aNodes (aFree (2 * anI )).Transformed (aLocation);
0a863061 502 theSegments.Append (aPoint1);
503 theSegments.Append (aPoint2);
5ad8c033 504 }
505 }
5ad8c033 506}
507
508// =========================================================================
bf5f0ca2 509// function : AddVertexes
5ad8c033 510// purpose :
511// =========================================================================
bf5f0ca2 512Handle(Graphic3d_ArrayOfPoints) StdPrs_WFShape::AddVertexes (const TopoDS_Shape& theShape,
513 Prs3d_VertexDrawMode theVertexMode)
5ad8c033 514{
bf5f0ca2 515 TColgp_SequenceOfPnt aShapeVertices;
516 if (theVertexMode == Prs3d_VDM_All)
5ad8c033 517 {
bf5f0ca2 518 for (TopExp_Explorer aVertIter (theShape, TopAbs_VERTEX); aVertIter.More(); aVertIter.Next())
519 {
520 const TopoDS_Vertex& aVert = TopoDS::Vertex (aVertIter.Current());
521 aShapeVertices.Append (BRep_Tool::Pnt (aVert));
522 }
5ad8c033 523 }
bf5f0ca2 524 else
525 {
526 // isolated vertices
527 for (TopExp_Explorer aVertIter (theShape, TopAbs_VERTEX, TopAbs_EDGE); aVertIter.More(); aVertIter.Next())
528 {
529 const TopoDS_Vertex& aVert = TopoDS::Vertex (aVertIter.Current());
530 aShapeVertices.Append (BRep_Tool::Pnt (aVert));
531 }
5ad8c033 532
bf5f0ca2 533 // internal vertices
534 for (TopExp_Explorer anEdgeIter (theShape, TopAbs_EDGE); anEdgeIter.More(); anEdgeIter.Next())
535 {
536 for (TopoDS_Iterator aVertIter (anEdgeIter.Current(), Standard_False, Standard_True); aVertIter.More(); aVertIter.Next())
537 {
538 const TopoDS_Shape& aVertSh = aVertIter.Value();
539 if (aVertSh.Orientation() == TopAbs_INTERNAL
540 && aVertSh.ShapeType() == TopAbs_VERTEX)
541 {
542 const TopoDS_Vertex& aVert = TopoDS::Vertex (aVertSh);
543 aShapeVertices.Append (BRep_Tool::Pnt (aVert));
544 }
545 }
546 }
547 }
548
549 if (aShapeVertices.IsEmpty())
5ad8c033 550 {
bf5f0ca2 551 return Handle(Graphic3d_ArrayOfPoints)();
5ad8c033 552 }
553
bf5f0ca2 554 const Standard_Integer aNbVertices = aShapeVertices.Length();
555 Handle(Graphic3d_ArrayOfPoints) aVertexArray = new Graphic3d_ArrayOfPoints (aNbVertices);
556 for (Standard_Integer aVertIter = 1; aVertIter <= aNbVertices; ++aVertIter)
557 {
558 aVertexArray->AddVertex (aShapeVertices.Value (aVertIter));
559 }
560 return aVertexArray;
5ad8c033 561}