1 // Created on: 2014-10-14
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <StdPrs_WFShape.hxx>
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>
28 #include <Prs3d_NListOfSequenceOfPnt.hxx>
29 #include <Prs3d_NListIteratorOfListOfSequenceOfPnt.hxx>
31 #include <Poly_Connect.hxx>
32 #include <Poly_PolygonOnTriangulation.hxx>
33 #include <Poly_Polygon3D.hxx>
34 #include <Poly_Triangulation.hxx>
35 #include <Graphic3d_AspectLine3d.hxx>
36 #include <Graphic3d_ArrayOfPolylines.hxx>
37 #include <Graphic3d_ArrayOfSegments.hxx>
38 #include <Graphic3d_ArrayOfPoints.hxx>
40 #include <TColgp_HSequenceOfPnt.hxx>
41 #include <TColStd_Array1OfInteger.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Face.hxx>
45 #include <TopTools_ListIteratorOfListOfShape.hxx>
46 #include <NCollection_List.hxx>
50 typedef NCollection_List<Handle(TColgp_HSequenceOfPnt)> ListOfSequenceOfPnt;
53 // =========================================================================
56 // =========================================================================
57 void StdPrs_WFShape::Add (const Handle (Prs3d_Presentation)& thePresentation,
58 const TopoDS_Shape& theShape,
59 const Handle (Prs3d_Drawer)& theDrawer)
61 if (theShape.IsNull())
66 Prs3d_ShapeTool aTool (theShape, theDrawer->VertexDrawMode() == Prs3d_VDM_All);
68 // Explore shape elements.
69 TopTools_ListOfShape aLFree, aLUnFree, aLWire;
70 for (aTool.InitCurve(); aTool.MoreCurve(); aTool.NextCurve())
72 const TopoDS_Edge& anEdge = aTool.GetCurve();
73 switch (aTool.Neighbours())
75 case 0: aLWire.Append (anEdge); break;
76 case 1: aLFree.Append (anEdge); break;
77 default: aLUnFree.Append (anEdge); break;
81 TColgp_SequenceOfPnt aShapeVertices;
82 for (aTool.InitVertex(); aTool.MoreVertex(); aTool.NextVertex())
84 aShapeVertices.Append (BRep_Tool::Pnt (aTool.GetVertex()));
87 Standard_Real aShapeDeflection = Prs3d::GetDeflection (theShape, theDrawer);
89 // Draw shape elements.
90 TopTools_ListOfShape aDiscreteFaces;
91 for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace())
93 if (!aTool.HasSurface())
95 aDiscreteFaces.Append (aTool.GetFace());
98 addEdgesOnTriangulation (thePresentation, aDiscreteFaces, theDrawer->FreeBoundaryAspect());
100 if (!aLWire.IsEmpty() && theDrawer->WireDraw())
102 addEdges (thePresentation, aLWire, theDrawer->WireAspect(), theDrawer, aShapeDeflection);
105 if (!aLFree.IsEmpty() && theDrawer->FreeBoundaryDraw())
107 addEdges (thePresentation, aLFree, theDrawer->FreeBoundaryAspect(), theDrawer, aShapeDeflection);
110 if (!aLUnFree.IsEmpty() && theDrawer->UnFreeBoundaryDraw())
112 addEdges (thePresentation, aLUnFree, theDrawer->UnFreeBoundaryAspect(), theDrawer, aShapeDeflection);
115 if (!aShapeVertices.IsEmpty())
117 addVertices (thePresentation, aShapeVertices, theDrawer->PointAspect());
121 for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace())
123 if (aTool.IsPlanarFace() && !theDrawer->IsoOnPlane())
128 StdPrs_Isolines::Add (thePresentation, aTool.GetFace(), theDrawer, aShapeDeflection);
132 // =========================================================================
133 // function : AddEdges
135 // =========================================================================
136 void StdPrs_WFShape::addEdges (const Handle (Prs3d_Presentation)& thePresentation,
137 const TopTools_ListOfShape& theEdges,
138 const Handle (Prs3d_LineAspect)& theAspect,
139 const Handle (Prs3d_Drawer)& theDrawer,
140 const Standard_Real theShapeDeflection)
142 ListOfSequenceOfPnt aPointsOfEdges;
144 TopTools_ListIteratorOfListOfShape anEdgesIter;
145 for (anEdgesIter.Initialize (theEdges); anEdgesIter.More(); anEdgesIter.Next())
147 const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgesIter.Value());
148 if (BRep_Tool::Degenerated (anEdge))
153 Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt;
155 TopLoc_Location aLocation;
156 Handle(Poly_Triangulation) aTriangulation;
157 Handle(Poly_PolygonOnTriangulation) anEdgeIndicies;
158 BRep_Tool::PolygonOnTriangulation (anEdge, anEdgeIndicies, aTriangulation, aLocation);
159 Handle(Poly_Polygon3D) aPolygon;
161 if (!anEdgeIndicies.IsNull())
163 // Presentation based on triangulation of a face.
164 const TColStd_Array1OfInteger& anIndices = anEdgeIndicies->Nodes();
165 const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
167 Standard_Integer anIndex = anIndices.Lower();
168 if (aLocation.IsIdentity())
170 for (; anIndex <= anIndices.Upper(); ++anIndex)
172 aPoints->Append (aNodes (anIndices (anIndex)));
177 for (; anIndex <= anIndices.Upper(); ++anIndex)
179 aPoints->Append (aNodes (anIndices (anIndex)).Transformed (aLocation));
183 else if (!(aPolygon = BRep_Tool::Polygon3D (anEdge, aLocation)).IsNull())
185 // Presentation based on triangulation of the free edge on a surface.
186 const TColgp_Array1OfPnt& aNodes = aPolygon->Nodes();
187 Standard_Integer anIndex = aNodes.Lower();
188 if (aLocation.IsIdentity())
190 for (; anIndex <= aNodes.Upper(); ++anIndex)
192 aPoints->Append (aNodes.Value (anIndex));
197 for (; anIndex <= aNodes.Upper(); ++anIndex)
199 aPoints->Append (aNodes.Value (anIndex).Transformed (aLocation));
203 else if (BRep_Tool::IsGeometric (anEdge))
205 // Default presentation for edges without triangulation.
206 BRepAdaptor_Curve aCurve (anEdge);
207 StdPrs_DeflectionCurve::Add (thePresentation,
211 aPoints->ChangeSequence(),
215 if (!aPoints->IsEmpty())
217 aPointsOfEdges.Append (aPoints);
221 Standard_Integer aNbBounds = aPointsOfEdges.Size();
222 Standard_Integer aNbVertices = 0;
224 ListOfSequenceOfPnt::Iterator aPolylineIter;
225 for (aPolylineIter.Initialize (aPointsOfEdges); aPolylineIter.More(); aPolylineIter.Next())
227 aNbVertices += aPolylineIter.Value()->Length();
230 if (aNbBounds < 1 || aNbVertices < 2)
235 // Construct array of primitives.
236 Handle(Graphic3d_ArrayOfPolylines) aPrimitiveArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds);
237 for (aPolylineIter.Initialize (aPointsOfEdges); aPolylineIter.More(); aPolylineIter.Next())
239 const Handle(TColgp_HSequenceOfPnt)& aPoints = aPolylineIter.Value();
240 aPrimitiveArray->AddBound (aPoints->Length());
241 for (Standard_Integer anI = 1; anI <= aPoints->Length(); ++anI)
243 aPrimitiveArray->AddVertex (aPoints->Value (anI));
247 // Add array of primitives to presentation.
248 Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
249 aGroup->SetPrimitivesAspect (theAspect->Aspect());
250 aGroup->AddPrimitiveArray (aPrimitiveArray);
253 // =========================================================================
254 // function : AddEdgesOnTriangulation
256 // =========================================================================
257 void StdPrs_WFShape::addEdgesOnTriangulation (const Handle(Prs3d_Presentation)& thePresentation,
258 const TopTools_ListOfShape& theFaces,
259 const Handle (Prs3d_LineAspect)& theAspect)
261 TColgp_SequenceOfPnt aSurfPoints;
263 TopLoc_Location aLocation;
264 TopTools_ListIteratorOfListOfShape aFaceIter;
265 for (aFaceIter.Initialize (theFaces); aFaceIter.More(); aFaceIter.Next())
267 const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Value());
269 Handle(Poly_Triangulation) T = BRep_Tool::Triangulation (aFace, aLocation);
275 const TColgp_Array1OfPnt& aNodes = T->Nodes();
277 // Build the connect tool.
278 Poly_Connect aPolyConnect (T);
280 Standard_Integer aNbTriangles = T->NbTriangles();
281 Standard_Integer aT[3];
282 Standard_Integer aN[3];
284 // Count the free edges.
285 Standard_Integer aNbFree = 0;
286 for (Standard_Integer anI = 1; anI <= aNbTriangles; ++anI)
288 aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]);
289 for (Standard_Integer aJ = 0; aJ < 3; ++aJ)
298 // Allocate the arrays.
299 TColStd_Array1OfInteger aFree (1, 2 * aNbFree);
300 Standard_Integer aNbInternal = (3 * aNbTriangles - aNbFree) / 2;
301 TColStd_Array1OfInteger anInternal (0, 2 * aNbInternal);
303 Standard_Integer aFreeIndex = 1, anIntIndex = 1;
304 const Poly_Array1OfTriangle& aTriangles = T->Triangles();
305 for (Standard_Integer anI = 1; anI <= aNbTriangles; ++anI)
307 aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]);
308 aTriangles (anI).Get (aN[0], aN[1], aN[2]);
309 for (Standard_Integer aJ = 0; aJ < 3; aJ++)
311 Standard_Integer k = (aJ + 1) % 3;
314 aFree (aFreeIndex) = aN[aJ];
315 aFree (aFreeIndex + 1) = aN[k];
318 // internal edge if this triangle has a lower index than the adjacent.
319 else if (anI < aT[aJ])
321 anInternal (anIntIndex) = aN[aJ];
322 anInternal (anIntIndex + 1) = aN[k];
329 Standard_Integer aFreeHalfNb = aFree.Length() / 2;
330 for (Standard_Integer anI = 1; anI <= aFreeHalfNb; ++anI)
332 gp_Pnt aPoint1 = aNodes (aFree (2 * anI - 1)).Transformed (aLocation);
333 gp_Pnt aPoint2 = aNodes (aFree (2 * anI )).Transformed (aLocation);
334 aSurfPoints.Append (aPoint1);
335 aSurfPoints.Append (aPoint2);
339 if (aSurfPoints.Length() < 2)
344 Standard_Integer aNbVertices = aSurfPoints.Length();
345 Standard_Integer aNbBounds = aNbVertices / 2;
346 Handle(Graphic3d_ArrayOfSegments) aSurfArray = new Graphic3d_ArrayOfSegments (aNbVertices, aNbBounds);
347 for (Standard_Integer anI = 1; anI <= aNbVertices; anI += 2)
349 aSurfArray->AddBound (2);
350 aSurfArray->AddVertex (aSurfPoints.Value (anI));
351 aSurfArray->AddVertex (aSurfPoints.Value (anI + 1));
353 Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
354 aGroup->SetPrimitivesAspect (theAspect->Aspect());
355 aGroup->AddPrimitiveArray (aSurfArray);
358 // =========================================================================
359 // function : AddPoints
361 // =========================================================================
362 void StdPrs_WFShape::addVertices (const Handle (Prs3d_Presentation)& thePresentation,
363 const TColgp_SequenceOfPnt& theVertices,
364 const Handle (Prs3d_PointAspect)& theAspect)
366 Standard_Integer aNbVertices = theVertices.Length();
372 Handle(Graphic3d_ArrayOfPoints) aVertexArray = new Graphic3d_ArrayOfPoints (aNbVertices);
373 for (Standard_Integer anI = 1; anI <= aNbVertices; ++anI)
375 aVertexArray->AddVertex (theVertices.Value (anI));
378 Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
379 aGroup->SetPrimitivesAspect (theAspect->Aspect());
380 aGroup->AddPrimitiveArray (aVertexArray);