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. |
48 | class StdPrs_WFShape_IsoFunctor |
49 | { |
50 | public: |
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 | |
77 | private: |
78 | StdPrs_WFShape_IsoFunctor operator= (StdPrs_WFShape_IsoFunctor& ); |
79 | private: |
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 |
93 | void 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 | // ========================================================================= |
225 | Handle(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 | // ========================================================================= |
239 | void 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 |
305 | void 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 |
392 | Handle(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 | // ========================================================================= |
416 | void 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 |
512 | Handle(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 | } |