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> |
22 | #include <StdPrs_DeflectionCurve.hxx> |
23 | #include <StdPrs_ToolTriangulatedShape.hxx> |
24 | #include <StdPrs_Isolines.hxx> |
25 | #include <Standard_ErrorHandler.hxx> |
26 | #include <Prs3d_ShapeTool.hxx> |
27 | #include <Prs3d_IsoAspect.hxx> |
5ad8c033 |
28 | #include <Prs3d.hxx> |
29 | #include <Poly_Connect.hxx> |
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> |
42 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
5ad8c033 |
43 | |
44 | // ========================================================================= |
45 | // function : Add |
46 | // purpose : |
47 | // ========================================================================= |
48 | void StdPrs_WFShape::Add (const Handle (Prs3d_Presentation)& thePresentation, |
49 | const TopoDS_Shape& theShape, |
50 | const Handle (Prs3d_Drawer)& theDrawer) |
51 | { |
52 | if (theShape.IsNull()) |
53 | { |
54 | return; |
55 | } |
56 | |
57 | Prs3d_ShapeTool aTool (theShape, theDrawer->VertexDrawMode() == Prs3d_VDM_All); |
58 | |
59 | // Explore shape elements. |
60 | TopTools_ListOfShape aLFree, aLUnFree, aLWire; |
61 | for (aTool.InitCurve(); aTool.MoreCurve(); aTool.NextCurve()) |
62 | { |
63 | const TopoDS_Edge& anEdge = aTool.GetCurve(); |
64 | switch (aTool.Neighbours()) |
65 | { |
66 | case 0: aLWire.Append (anEdge); break; |
67 | case 1: aLFree.Append (anEdge); break; |
68 | default: aLUnFree.Append (anEdge); break; |
69 | } |
70 | } |
71 | |
5ad8c033 |
72 | Standard_Real aShapeDeflection = Prs3d::GetDeflection (theShape, theDrawer); |
73 | |
1b9f5d95 |
74 | // Draw shape elements |
5ad8c033 |
75 | { |
1b9f5d95 |
76 | TopTools_ListOfShape aDiscreteFaces; |
77 | for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace()) |
5ad8c033 |
78 | { |
1b9f5d95 |
79 | if (!aTool.HasSurface()) |
80 | { |
81 | aDiscreteFaces.Append (aTool.GetFace()); |
82 | } |
5ad8c033 |
83 | } |
1b9f5d95 |
84 | addEdgesOnTriangulation (thePresentation, aDiscreteFaces, theDrawer->FreeBoundaryAspect()); |
5ad8c033 |
85 | } |
5ad8c033 |
86 | |
1b9f5d95 |
87 | Prs3d_NListOfSequenceOfPnt aCommonPolylines; |
88 | const Handle(Prs3d_LineAspect)& aWireAspect = theDrawer->WireAspect(); |
89 | |
90 | // Draw isolines |
5ad8c033 |
91 | { |
1b9f5d95 |
92 | Prs3d_NListOfSequenceOfPnt aUPolylines, aVPolylines; |
93 | Prs3d_NListOfSequenceOfPnt* aUPolylinesPtr = &aUPolylines; |
94 | Prs3d_NListOfSequenceOfPnt* aVPolylinesPtr = &aVPolylines; |
95 | |
96 | const Handle(Prs3d_LineAspect)& anIsoAspectU = theDrawer->UIsoAspect(); |
97 | const Handle(Prs3d_LineAspect)& anIsoAspectV = theDrawer->VIsoAspect(); |
98 | if (anIsoAspectV->Aspect()->IsEqual (*anIsoAspectU->Aspect())) |
99 | { |
100 | aVPolylinesPtr = aUPolylinesPtr; |
101 | } |
102 | if (anIsoAspectU->Aspect()->IsEqual (*aWireAspect->Aspect())) |
103 | { |
104 | aUPolylinesPtr = &aCommonPolylines; |
105 | } |
106 | if (anIsoAspectV->Aspect()->IsEqual (*aWireAspect->Aspect())) |
107 | { |
108 | aVPolylinesPtr = &aCommonPolylines; |
109 | } |
110 | |
111 | for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace()) |
112 | { |
113 | if (aTool.IsPlanarFace() && !theDrawer->IsoOnPlane()) |
114 | { |
115 | continue; |
116 | } |
117 | |
118 | StdPrs_Isolines::Add (aTool.GetFace(), theDrawer, aShapeDeflection, *aUPolylinesPtr, *aVPolylinesPtr); |
119 | } |
120 | |
121 | Prs3d::AddPrimitivesGroup (thePresentation, anIsoAspectU, aUPolylines); |
122 | Prs3d::AddPrimitivesGroup (thePresentation, anIsoAspectV, aVPolylines); |
5ad8c033 |
123 | } |
124 | |
1b9f5d95 |
125 | if (!aLWire.IsEmpty() && theDrawer->WireDraw()) |
5ad8c033 |
126 | { |
1b9f5d95 |
127 | addEdges (aLWire, theDrawer, aShapeDeflection, aCommonPolylines); |
5ad8c033 |
128 | } |
129 | |
130 | if (!aLUnFree.IsEmpty() && theDrawer->UnFreeBoundaryDraw()) |
131 | { |
1b9f5d95 |
132 | const Handle(Prs3d_LineAspect)& aLineAspect = theDrawer->UnFreeBoundaryAspect(); |
133 | if (!aLineAspect->Aspect()->IsEqual (*aWireAspect->Aspect())) |
134 | { |
135 | Prs3d_NListOfSequenceOfPnt aPolylines; |
136 | addEdges (aLUnFree, theDrawer, aShapeDeflection, aPolylines); |
137 | Prs3d::AddPrimitivesGroup (thePresentation, aLineAspect, aPolylines); |
138 | } |
139 | else |
140 | { |
141 | addEdges (aLUnFree, theDrawer, aShapeDeflection, aCommonPolylines); |
142 | } |
5ad8c033 |
143 | } |
144 | |
1b9f5d95 |
145 | if (!aLFree.IsEmpty() && theDrawer->FreeBoundaryDraw()) |
5ad8c033 |
146 | { |
1b9f5d95 |
147 | const Handle(Prs3d_LineAspect)& aLineAspect = theDrawer->FreeBoundaryAspect(); |
148 | if (!aLineAspect->Aspect()->IsEqual (*aWireAspect->Aspect())) |
149 | { |
150 | Prs3d_NListOfSequenceOfPnt aPolylines; |
151 | addEdges (aLFree, theDrawer, aShapeDeflection, aPolylines); |
152 | Prs3d::AddPrimitivesGroup (thePresentation, aLineAspect, aPolylines); |
153 | } |
154 | else |
155 | { |
156 | addEdges (aLFree, theDrawer, aShapeDeflection, aCommonPolylines); |
157 | } |
5ad8c033 |
158 | } |
159 | |
1b9f5d95 |
160 | Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->WireAspect(), aCommonPolylines); |
161 | |
5ad8c033 |
162 | { |
1b9f5d95 |
163 | TColgp_SequenceOfPnt aShapeVertices; |
164 | for (aTool.InitVertex(); aTool.MoreVertex(); aTool.NextVertex()) |
5ad8c033 |
165 | { |
1b9f5d95 |
166 | aShapeVertices.Append (BRep_Tool::Pnt (aTool.GetVertex())); |
167 | } |
168 | if (!aShapeVertices.IsEmpty()) |
169 | { |
170 | addVertices (thePresentation, aShapeVertices, theDrawer->PointAspect()); |
5ad8c033 |
171 | } |
5ad8c033 |
172 | } |
173 | } |
174 | |
175 | // ========================================================================= |
176 | // function : AddEdges |
177 | // purpose : |
178 | // ========================================================================= |
1b9f5d95 |
179 | void StdPrs_WFShape::addEdges (const TopTools_ListOfShape& theEdges, |
180 | const Handle (Prs3d_Drawer)& theDrawer, |
181 | const Standard_Real theShapeDeflection, |
182 | Prs3d_NListOfSequenceOfPnt& thePolylines) |
5ad8c033 |
183 | { |
5ad8c033 |
184 | TopTools_ListIteratorOfListOfShape anEdgesIter; |
185 | for (anEdgesIter.Initialize (theEdges); anEdgesIter.More(); anEdgesIter.Next()) |
186 | { |
187 | const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgesIter.Value()); |
188 | if (BRep_Tool::Degenerated (anEdge)) |
189 | { |
190 | continue; |
191 | } |
192 | |
193 | Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt; |
194 | |
195 | TopLoc_Location aLocation; |
196 | Handle(Poly_Triangulation) aTriangulation; |
197 | Handle(Poly_PolygonOnTriangulation) anEdgeIndicies; |
198 | BRep_Tool::PolygonOnTriangulation (anEdge, anEdgeIndicies, aTriangulation, aLocation); |
199 | Handle(Poly_Polygon3D) aPolygon; |
200 | |
201 | if (!anEdgeIndicies.IsNull()) |
202 | { |
203 | // Presentation based on triangulation of a face. |
204 | const TColStd_Array1OfInteger& anIndices = anEdgeIndicies->Nodes(); |
205 | const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes(); |
206 | |
207 | Standard_Integer anIndex = anIndices.Lower(); |
208 | if (aLocation.IsIdentity()) |
209 | { |
210 | for (; anIndex <= anIndices.Upper(); ++anIndex) |
211 | { |
212 | aPoints->Append (aNodes (anIndices (anIndex))); |
213 | } |
214 | } |
215 | else |
216 | { |
217 | for (; anIndex <= anIndices.Upper(); ++anIndex) |
218 | { |
219 | aPoints->Append (aNodes (anIndices (anIndex)).Transformed (aLocation)); |
220 | } |
221 | } |
222 | } |
223 | else if (!(aPolygon = BRep_Tool::Polygon3D (anEdge, aLocation)).IsNull()) |
224 | { |
225 | // Presentation based on triangulation of the free edge on a surface. |
226 | const TColgp_Array1OfPnt& aNodes = aPolygon->Nodes(); |
227 | Standard_Integer anIndex = aNodes.Lower(); |
228 | if (aLocation.IsIdentity()) |
229 | { |
230 | for (; anIndex <= aNodes.Upper(); ++anIndex) |
231 | { |
232 | aPoints->Append (aNodes.Value (anIndex)); |
233 | } |
234 | } |
235 | else |
236 | { |
237 | for (; anIndex <= aNodes.Upper(); ++anIndex) |
238 | { |
239 | aPoints->Append (aNodes.Value (anIndex).Transformed (aLocation)); |
240 | } |
241 | } |
242 | } |
243 | else if (BRep_Tool::IsGeometric (anEdge)) |
244 | { |
245 | // Default presentation for edges without triangulation. |
246 | BRepAdaptor_Curve aCurve (anEdge); |
1b9f5d95 |
247 | StdPrs_DeflectionCurve::Add (Handle(Prs3d_Presentation)(), |
5ad8c033 |
248 | aCurve, |
249 | theShapeDeflection, |
250 | theDrawer, |
251 | aPoints->ChangeSequence(), |
252 | Standard_False); |
253 | } |
254 | |
255 | if (!aPoints->IsEmpty()) |
256 | { |
1b9f5d95 |
257 | thePolylines.Append (aPoints); |
5ad8c033 |
258 | } |
259 | } |
5ad8c033 |
260 | } |
261 | |
262 | // ========================================================================= |
263 | // function : AddEdgesOnTriangulation |
264 | // purpose : |
265 | // ========================================================================= |
266 | void StdPrs_WFShape::addEdgesOnTriangulation (const Handle(Prs3d_Presentation)& thePresentation, |
267 | const TopTools_ListOfShape& theFaces, |
268 | const Handle (Prs3d_LineAspect)& theAspect) |
269 | { |
270 | TColgp_SequenceOfPnt aSurfPoints; |
271 | |
272 | TopLoc_Location aLocation; |
273 | TopTools_ListIteratorOfListOfShape aFaceIter; |
274 | for (aFaceIter.Initialize (theFaces); aFaceIter.More(); aFaceIter.Next()) |
275 | { |
276 | const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Value()); |
277 | |
278 | Handle(Poly_Triangulation) T = BRep_Tool::Triangulation (aFace, aLocation); |
279 | if (T.IsNull()) |
280 | { |
281 | continue; |
282 | } |
283 | |
284 | const TColgp_Array1OfPnt& aNodes = T->Nodes(); |
285 | |
286 | // Build the connect tool. |
287 | Poly_Connect aPolyConnect (T); |
288 | |
289 | Standard_Integer aNbTriangles = T->NbTriangles(); |
290 | Standard_Integer aT[3]; |
291 | Standard_Integer aN[3]; |
292 | |
293 | // Count the free edges. |
294 | Standard_Integer aNbFree = 0; |
295 | for (Standard_Integer anI = 1; anI <= aNbTriangles; ++anI) |
296 | { |
297 | aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]); |
298 | for (Standard_Integer aJ = 0; aJ < 3; ++aJ) |
299 | { |
300 | if (aT[aJ] == 0) |
301 | { |
302 | ++aNbFree; |
303 | } |
304 | } |
305 | } |
306 | |
413b1c1a |
307 | if (aNbFree == 0) |
308 | { |
309 | continue; |
310 | } |
311 | |
5ad8c033 |
312 | // Allocate the arrays. |
313 | TColStd_Array1OfInteger aFree (1, 2 * aNbFree); |
314 | Standard_Integer aNbInternal = (3 * aNbTriangles - aNbFree) / 2; |
315 | TColStd_Array1OfInteger anInternal (0, 2 * aNbInternal); |
316 | |
317 | Standard_Integer aFreeIndex = 1, anIntIndex = 1; |
318 | const Poly_Array1OfTriangle& aTriangles = T->Triangles(); |
319 | for (Standard_Integer anI = 1; anI <= aNbTriangles; ++anI) |
320 | { |
321 | aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]); |
322 | aTriangles (anI).Get (aN[0], aN[1], aN[2]); |
323 | for (Standard_Integer aJ = 0; aJ < 3; aJ++) |
324 | { |
325 | Standard_Integer k = (aJ + 1) % 3; |
326 | if (aT[aJ] == 0) |
327 | { |
328 | aFree (aFreeIndex) = aN[aJ]; |
329 | aFree (aFreeIndex + 1) = aN[k]; |
330 | aFreeIndex += 2; |
331 | } |
332 | // internal edge if this triangle has a lower index than the adjacent. |
333 | else if (anI < aT[aJ]) |
334 | { |
335 | anInternal (anIntIndex) = aN[aJ]; |
336 | anInternal (anIntIndex + 1) = aN[k]; |
337 | anIntIndex += 2; |
338 | } |
339 | } |
340 | } |
341 | |
342 | // free edges |
343 | Standard_Integer aFreeHalfNb = aFree.Length() / 2; |
344 | for (Standard_Integer anI = 1; anI <= aFreeHalfNb; ++anI) |
345 | { |
346 | gp_Pnt aPoint1 = aNodes (aFree (2 * anI - 1)).Transformed (aLocation); |
347 | gp_Pnt aPoint2 = aNodes (aFree (2 * anI )).Transformed (aLocation); |
348 | aSurfPoints.Append (aPoint1); |
349 | aSurfPoints.Append (aPoint2); |
350 | } |
351 | } |
352 | |
353 | if (aSurfPoints.Length() < 2) |
354 | { |
355 | return; |
356 | } |
357 | |
358 | Standard_Integer aNbVertices = aSurfPoints.Length(); |
1b9f5d95 |
359 | Handle(Graphic3d_ArrayOfSegments) aSurfArray = new Graphic3d_ArrayOfSegments (aNbVertices); |
5ad8c033 |
360 | for (Standard_Integer anI = 1; anI <= aNbVertices; anI += 2) |
361 | { |
5ad8c033 |
362 | aSurfArray->AddVertex (aSurfPoints.Value (anI)); |
363 | aSurfArray->AddVertex (aSurfPoints.Value (anI + 1)); |
364 | } |
365 | Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); |
366 | aGroup->SetPrimitivesAspect (theAspect->Aspect()); |
367 | aGroup->AddPrimitiveArray (aSurfArray); |
368 | } |
369 | |
370 | // ========================================================================= |
371 | // function : AddPoints |
372 | // purpose : |
373 | // ========================================================================= |
374 | void StdPrs_WFShape::addVertices (const Handle (Prs3d_Presentation)& thePresentation, |
375 | const TColgp_SequenceOfPnt& theVertices, |
376 | const Handle (Prs3d_PointAspect)& theAspect) |
377 | { |
378 | Standard_Integer aNbVertices = theVertices.Length(); |
379 | if (aNbVertices < 1) |
380 | { |
381 | return; |
382 | } |
383 | |
384 | Handle(Graphic3d_ArrayOfPoints) aVertexArray = new Graphic3d_ArrayOfPoints (aNbVertices); |
385 | for (Standard_Integer anI = 1; anI <= aNbVertices; ++anI) |
386 | { |
387 | aVertexArray->AddVertex (theVertices.Value (anI)); |
388 | } |
389 | |
390 | Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); |
391 | aGroup->SetPrimitivesAspect (theAspect->Aspect()); |
392 | aGroup->AddPrimitiveArray (aVertexArray); |
393 | } |