0031765: Coding Rules - eliminate GCC compiler warnings -Wcatch-value in IVtk
[occt.git] / src / IVtkOCC / IVtkOCC_ShapeMesher.cxx
CommitLineData
913a4c4a 1// Created on: 2011-10-14
2// Created by: Roman KOZLOV
3// Copyright (c) 2011-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
9df04979 16#include <IVtkOCC_ShapeMesher.hxx>
17
913a4c4a 18#include <Adaptor3d_IsoCurve.hxx>
19#include <Bnd_Box.hxx>
20#include <BRep_Tool.hxx>
913a4c4a 21#include <BRepBndLib.hxx>
22#include <BRepMesh_DiscretFactory.hxx>
23#include <BRepMesh_DiscretRoot.hxx>
913a4c4a 24#include <BRepTools.hxx>
25#include <Hatch_Hatcher.hxx>
26#include <GCPnts_QuasiUniformDeflection.hxx>
27#include <GCPnts_TangentialDeflection.hxx>
c04c30b3 28#include <Geom_BezierSurface.hxx>
29#include <Geom_BSplineSurface.hxx>
913a4c4a 30#include <Geom2dAdaptor_Curve.hxx>
31#include <GeomAdaptor_Curve.hxx>
32#include <gp_Dir2d.hxx>
33#include <gp_Pnt2d.hxx>
9df04979 34#include <Message.hxx>
913a4c4a 35#include <NCollection_Array1.hxx>
36#include <Poly_Polygon3D.hxx>
37#include <Poly_PolygonOnTriangulation.hxx>
38#include <Poly_Triangulation.hxx>
39#include <Precision.hxx>
40#include <Prs3d.hxx>
41#include <Prs3d_Drawer.hxx>
98eb4489 42#include <Prs3d_IsoAspect.hxx>
913a4c4a 43#include <Standard_ErrorHandler.hxx>
98eb4489 44#include <StdPrs_Isolines.hxx>
7f24b768 45#include <StdPrs_ToolTriangulatedShape.hxx>
913a4c4a 46#include <TColgp_SequenceOfPnt2d.hxx>
47#include <TColStd_Array1OfReal.hxx>
48#include <TopExp.hxx>
49#include <TopExp_Explorer.hxx>
50
92efcf78 51IMPLEMENT_STANDARD_RTTIEXT(IVtkOCC_ShapeMesher,IVtk_IShapeMesher)
52
913a4c4a 53// Handle implementation
ec357c5c 54
913a4c4a 55
56//================================================================
57// Function : internalBuild
58// Purpose :
59//================================================================
60void IVtkOCC_ShapeMesher::internalBuild()
61{
62 // TODO: do we need any protection here so as not to triangualte
63 // the shape twice??? This can be done e.g. by checking if
64 // triangulation exists for TopoDS_Shape..
65 meshShape();
66
67 // Free vertices and free edges should always be shown.
68 // Shared edges are needed in WF representation only.
69 // TODO: how to filter free edges at visualization level????
70 addFreeVertices();
71 addEdges();
72
73 // Build wireframe points and cells (lines for isolines)
74 addWireFrameFaces();
75
76 // Build shaded representation (based on Poly_Triangulation)
77 addShadedFaces();
78}
79
80//================================================================
81// Function : GetShapeObj
82// Purpose :
83//================================================================
84const IVtkOCC_Shape::Handle IVtkOCC_ShapeMesher::GetShapeObj() const
85{
86 return (IVtkOCC_Shape::Handle::DownCast(myShapeObj));
87}
88
89//================================================================
90// Function : GetDeflection
91// Purpose : Returns absolute deflection used by this algorithm.
92//================================================================
93Standard_Real IVtkOCC_ShapeMesher::GetDeflection() const
94{
95 if (myDeflection < Precision::Confusion()) // if not yet initialized
96 {
97 Handle(Prs3d_Drawer) aDefDrawer = new Prs3d_Drawer();
98 aDefDrawer->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
99 aDefDrawer->SetDeviationCoefficient (GetDeviationCoeff());
7f24b768 100 myDeflection = StdPrs_ToolTriangulatedShape::GetDeflection (GetShapeObj()->GetShape(), aDefDrawer);
913a4c4a 101 }
102
103 return myDeflection;
104}
105
106//================================================================
107// Function : meshShape
108// Purpose :
109//================================================================
110void IVtkOCC_ShapeMesher::meshShape()
111{
a2f76b15 112 const TopoDS_Shape& anOcctShape = GetShapeObj()->GetShape();
913a4c4a 113 if (anOcctShape.IsNull())
114 {
115 return;
116 }
117
118 //Clean triangulation before compute incremental mesh
119 BRepTools::Clean (anOcctShape);
120
121 //Compute triangulation
122 Standard_Real aDeflection = GetDeflection();
123 if (aDeflection < Precision::Confusion())
124 {
125 return;
126 }
127
128 try
129 {
130 OCC_CATCH_SIGNALS
131
132 Handle(BRepMesh_DiscretRoot) anAlgo;
133 anAlgo = BRepMesh_DiscretFactory::Get().Discret (anOcctShape,
134 aDeflection,
135 GetDeviationAngle());
136 if (!anAlgo.IsNull())
137 {
138 anAlgo->Perform();
139 }
140 }
9df04979 141 catch (const Standard_Failure& anException)
142 {
143 Message::SendFail (TCollection_AsciiString("Error: IVtkOCC_ShapeMesher::meshShape() triangulation builder has failed (")
144 + anException.GetMessageString() + ")");
145 }
913a4c4a 146}
147
148//================================================================
149// Function : addFreeVertices
150// Purpose :
151//================================================================
152void IVtkOCC_ShapeMesher::addFreeVertices()
153{
154 TopTools_IndexedDataMapOfShapeListOfShape aVertexMap;
155 TopExp::MapShapesAndAncestors (GetShapeObj()->GetShape(),
156 TopAbs_VERTEX,
157 TopAbs_EDGE,
158 aVertexMap);
159
160 Standard_Integer aVertNum = aVertexMap.Extent();
161 IVtk_MeshType aType;
162 for (Standard_Integer anIt = 1; anIt <= aVertNum; anIt++)
163 {
164 if (aVertexMap.FindFromIndex(anIt).IsEmpty())
165 {
166 aType = MT_FreeVertex;
167 }
168 else
169 {
170 aType = MT_SharedVertex;
171 }
a2f76b15 172 const TopoDS_Vertex& aVertex = TopoDS::Vertex (aVertexMap.FindKey (anIt));
913a4c4a 173 addVertex (aVertex, GetShapeObj()->GetSubShapeId (aVertex), aType);
174 }
175}
176
177//================================================================
178// Function : addEdges
179// Purpose :
180//================================================================
181void IVtkOCC_ShapeMesher::addEdges()
182{
183 TopTools_IndexedDataMapOfShapeListOfShape anEdgesMap;
184 TopExp::MapShapesAndAncestors (GetShapeObj()->GetShape(),
185 TopAbs_EDGE,
186 TopAbs_FACE,
187 anEdgesMap);
913a4c4a 188 int aNbFaces;
189 IVtk_MeshType aType;
190 myEdgesTypes.Clear();
191
2ba1172b 192 TopTools_IndexedDataMapOfShapeListOfShape::Iterator aEdgeIt(anEdgesMap);
193 for (; aEdgeIt.More(); aEdgeIt.Next())
913a4c4a 194 {
2ba1172b 195 const TopoDS_Edge& anOcctEdge = TopoDS::Edge (aEdgeIt.Key());
196 const TopTools_ListOfShape& aFaceList = aEdgeIt.Value();
197 aNbFaces = aFaceList.Extent();
913a4c4a 198 if (aNbFaces == 0)
199 {
200 aType = MT_FreeEdge;
201 }
202 else if (aNbFaces == 1)
203 {
204 aType = MT_BoundaryEdge;
205 }
206 else
207 {
2ba1172b 208 aType = (aNbFaces >= 2) && (BRep_Tool::MaxContinuity(anOcctEdge) > GeomAbs_G2) ?
209 MT_SeamEdge : MT_SharedEdge;
913a4c4a 210 }
211 addEdge (anOcctEdge, GetShapeObj()->GetSubShapeId (anOcctEdge), aType);
212 myEdgesTypes.Bind (anOcctEdge, aType);
213 }
214}
215
216//================================================================
217// Function : addWireFrameFaces
218// Purpose :
219//================================================================
220void IVtkOCC_ShapeMesher::addWireFrameFaces()
221{
222 // Check the deflection value once for all faces
223 if (GetDeflection() < Precision::Confusion())
224 {
225 return;
226 }
227
228 TopExp_Explorer aFaceIter (GetShapeObj()->GetShape(), TopAbs_FACE);
229 for (; aFaceIter.More(); aFaceIter.Next())
230 {
a2f76b15 231 const TopoDS_Face& anOcctFace = TopoDS::Face (aFaceIter.Current());
913a4c4a 232 try
233 {
234 OCC_CATCH_SIGNALS
235 addWFFace (anOcctFace,
236 GetShapeObj()->GetSubShapeId (anOcctFace));
237 }
9df04979 238 catch (const Standard_Failure& anException)
239 {
240 Message::SendFail (TCollection_AsciiString("Error: addWireFrameFaces() wireframe presentation builder has failed (")
241 + anException.GetMessageString() + ")");
242 }
913a4c4a 243 }
244}
245
246//================================================================
247// Function : addShadedFaces
248// Purpose :
249//================================================================
250void IVtkOCC_ShapeMesher::addShadedFaces()
251{
252 TopExp_Explorer aFaceIter (GetShapeObj()->GetShape(), TopAbs_FACE);
253 for (; aFaceIter.More(); aFaceIter.Next())
254 {
a2f76b15 255 const TopoDS_Face& anOcctFace = TopoDS::Face (aFaceIter.Current());
913a4c4a 256 addShadedFace (anOcctFace,
257 GetShapeObj()->GetSubShapeId (anOcctFace));
258 }
259}
260
261//================================================================
262// Function : addVertex
263// Purpose :
264//================================================================
265void IVtkOCC_ShapeMesher::addVertex (const TopoDS_Vertex& theVertex,
266 const IVtk_IdType theShapeId,
267 const IVtk_MeshType theMeshType)
268{
269 if (theVertex.IsNull())
270 {
271 return;
272 }
273
274 gp_Pnt aPnt3d = BRep_Tool::Pnt (theVertex);
275
276 IVtk_PointId anId =
277 myShapeData->InsertCoordinate (aPnt3d.X(), aPnt3d.Y(), aPnt3d.Z());
278 myShapeData->InsertVertex (theShapeId, anId, theMeshType);
279
280}
281
282//================================================================
283// Function : processPolyline
284// Purpose :
285//================================================================
286void IVtkOCC_ShapeMesher::processPolyline (Standard_Integer theNbNodes,
287 const TColgp_Array1OfPnt& thePoints,
288 const TColStd_Array1OfInteger& thePointIds,
289 const IVtk_IdType theOcctId,
290 bool theNoTransform,
291 gp_Trsf theTransformation,
292 const IVtk_MeshType theMeshType)
293{
294 if (theNbNodes < 2)
295 {
296 return;
297 }
298
a2f76b15 299 IVtk_PointIdList aPolyPointIds;
913a4c4a 300
301 IVtk_PointId anId;
302 for (Standard_Integer aJ = 0; aJ < theNbNodes; aJ++)
303 {
304 Standard_Integer aPntId = thePointIds (aJ + 1);
305 gp_Pnt point = thePoints (aPntId);
306
307 if (!theNoTransform)
308 {
309 // Apply the transformation to points
310 point.Transform (theTransformation);
311 }
312
313 anId = myShapeData->InsertCoordinate (point.X(), point.Y(), point.Z());
a2f76b15 314 aPolyPointIds.Append (anId);
913a4c4a 315 }
316
a2f76b15 317 myShapeData->InsertLine (theOcctId, &aPolyPointIds, theMeshType);
913a4c4a 318}
319
320//================================================================
321// Function : addEdge
322// Purpose :
323//================================================================
324void IVtkOCC_ShapeMesher::addEdge (const TopoDS_Edge& theEdge,
325 const IVtk_IdType theShapeId,
326 const IVtk_MeshType theMeshType)
327{
328 if (theEdge.IsNull() || BRep_Tool::Degenerated (theEdge))
329 {
330 return;
331 }
332
333 // Two discrete representations of an OCCT edge are possible:
334 // 1. Polygon on trinagulation - holds Ids of points
335 // contained in Poly_Triangulation object
336 Handle(Poly_PolygonOnTriangulation) aPolyOnTriangulation;
337 Handle(Poly_Triangulation) aTriangulation;
338 TopLoc_Location aLocation;
339 BRep_Tool::PolygonOnTriangulation (theEdge,
340 aPolyOnTriangulation,
341 aTriangulation,
342 aLocation,
343 1);
344
345 // 2. 3D polygon - holds 3D points
346 Handle(Poly_Polygon3D) aPoly3d;
347 if (aPolyOnTriangulation.IsNull())
348 {
349 aPoly3d = BRep_Tool::Polygon3D (theEdge, aLocation);
350 }
351
352 if (aPoly3d.IsNull() && aPolyOnTriangulation.IsNull())
353 {
354 return;
355 }
356
357 // Handle a non-identity transofmation applied to the edge
358 gp_Trsf anEdgeTransf;
359 bool noTransform = true;
360 if (!aLocation.IsIdentity())
361 {
362 noTransform = false;
363 anEdgeTransf = aLocation.Transformation();
364 }
365
366 if (!aPoly3d.IsNull())
367 {
368 Standard_Integer aNbNodes = aPoly3d->NbNodes();
369 const TColgp_Array1OfPnt& aPoints = aPoly3d->Nodes();
370 TColStd_Array1OfInteger aPointIds (1, aNbNodes);
371
372 for (Standard_Integer anI = 1; anI <= aNbNodes; anI++)
373 {
374 aPointIds.SetValue (anI, anI);
375 }
376
377 processPolyline (aNbNodes,
378 aPoints,
379 aPointIds,
380 theShapeId,
381 noTransform,
382 anEdgeTransf,
383 theMeshType);
384 }
385 else
386 {
387 Standard_Integer aNbNodes = aPolyOnTriangulation->NbNodes();
388 const TColStd_Array1OfInteger& aPointIds = aPolyOnTriangulation->Nodes();
389 const TColgp_Array1OfPnt& aPoints = aTriangulation->Nodes();
390
391 processPolyline (aNbNodes,
392 aPoints,
393 aPointIds,
394 theShapeId,
395 noTransform,
396 anEdgeTransf,
397 theMeshType);
398 }
399}
400
913a4c4a 401//================================================================
402// Function : addWFFace
403// Purpose :
404//================================================================
405void IVtkOCC_ShapeMesher::addWFFace (const TopoDS_Face& theFace,
406 const IVtk_IdType theShapeId)
407{
408 if (theFace.IsNull())
409 {
410 return;
411 }
412
413 TopoDS_Face aFaceToMesh = theFace;
414 aFaceToMesh.Orientation (TopAbs_FORWARD);
415
416 // The code that builds wireframe representation for a TopoDS_Face
417 // has been adapted from some OCCT 6.5.1 methods:
418 // - Prs3d_WFShape::Add()
419 // - StdPrs_WFDeflectionRestrictedFace::Add()
420 // - StdPrs_DeflectionCurve::Add()
421
422 // Add face's edges here but with the face ID
98eb4489 423 for (TopExp_Explorer anEdgeIter (aFaceToMesh, TopAbs_EDGE); anEdgeIter.More(); anEdgeIter.Next())
913a4c4a 424 {
a2f76b15 425 const TopoDS_Edge& anOcctEdge = TopoDS::Edge (anEdgeIter.Current());
913a4c4a 426 addEdge (anOcctEdge, theShapeId, myEdgesTypes (anOcctEdge));
427 }
428
429 TopLoc_Location aLoc;
430 const Handle(Geom_Surface)& aGeomSurf = BRep_Tool::Surface (aFaceToMesh, aLoc);
431 if (aGeomSurf.IsNull())
432 {
433 return;
434 }
435
98eb4489 436 const Standard_Real aDeflection = GetDeflection();
437 Handle(Prs3d_Drawer) aDrawer = new Prs3d_Drawer();
438 aDrawer->SetUIsoAspect (new Prs3d_IsoAspect (Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0f, myNbIsos[0]));
439 aDrawer->SetVIsoAspect (new Prs3d_IsoAspect (Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0f, myNbIsos[1]));
440 aDrawer->SetDeviationAngle (myDevAngle);
441 aDrawer->SetDeviationCoefficient (myDevCoeff);
442 aDrawer->SetMaximalChordialDeviation (aDeflection);
913a4c4a 443
98eb4489 444 Prs3d_NListOfSequenceOfPnt aPolylines;
445 StdPrs_Isolines::Add (theFace, aDrawer, aDeflection, aPolylines, aPolylines);
446 for (Prs3d_NListOfSequenceOfPnt::Iterator aPolyIter (aPolylines); aPolyIter.More(); aPolyIter.Next())
913a4c4a 447 {
98eb4489 448 const Handle(TColgp_HSequenceOfPnt)& aPoints = aPolyIter.Value();
449 const Standard_Integer theNbNodes = aPoints->Length();
450 if (theNbNodes < 2)
913a4c4a 451 {
98eb4489 452 continue;
913a4c4a 453 }
913a4c4a 454
98eb4489 455 IVtk_PointIdList aPolyPointIds;
456 for (TColgp_HSequenceOfPnt::Iterator aNodeIter (*aPoints); aNodeIter.More(); aNodeIter.Next())
913a4c4a 457 {
98eb4489 458 const gp_Pnt& aPnt = aNodeIter.Value();
459 const IVtk_PointId anId = myShapeData->InsertCoordinate (aPnt.X(), aPnt.Y(), aPnt.Z());
460 aPolyPointIds.Append (anId);
913a4c4a 461 }
98eb4489 462
463 myShapeData->InsertLine (theShapeId, &aPolyPointIds, MT_IsoLine);
913a4c4a 464 }
465}
466
467//================================================================
468// Function : addShadedFace
469// Purpose :
470//================================================================
471void IVtkOCC_ShapeMesher::addShadedFace (const TopoDS_Face& theFace,
472 const IVtk_IdType theShapeId)
473{
474 if (theFace.IsNull())
475 {
476 return;
477 }
478
479 // Build triangulation of the face.
480 TopLoc_Location aLoc;
481 Handle(Poly_Triangulation) anOcctTriangulation = BRep_Tool::Triangulation (theFace, aLoc);
482 if (anOcctTriangulation.IsNull())
483 {
484 return;
485 }
486
487 gp_Trsf aPntTransform;
488 Standard_Boolean noTransform = Standard_True;
489 if (!aLoc.IsIdentity())
490 {
491 noTransform = Standard_False;
492 aPntTransform = aLoc.Transformation();
493 }
494
495 // Get triangulation points.
496 const TColgp_Array1OfPnt& aPoints = anOcctTriangulation->Nodes();
497 Standard_Integer aNbPoints = anOcctTriangulation->NbNodes();
498
499 // Keep inserted points id's of triangulation in an array.
500 NCollection_Array1<IVtk_PointId> aPointIds (1, aNbPoints);
501 IVtk_PointId anId;
502
503 Standard_Integer anI;
504 for (anI = 1; anI <= aNbPoints; anI++)
505 {
506 gp_Pnt aPoint = aPoints (anI);
507
508 if (!noTransform)
509 {
510 aPoint.Transform (aPntTransform);
511 }
512
513 // Add a point into output shape data and keep its id in the array.
514 anId = myShapeData->InsertCoordinate (aPoint.X(), aPoint.Y(), aPoint.Z());
515 aPointIds.SetValue (anI, anId);
516 }
517
518 // Create triangles on the created triangulation points.
519 const Poly_Array1OfTriangle& aTriangles = anOcctTriangulation->Triangles();
520 Standard_Integer aNbTriangles = anOcctTriangulation->NbTriangles();
521 Standard_Integer aN1, aN2, aN3;
522 for (anI = 1; anI <= aNbTriangles; anI++)
523 {
524 aTriangles(anI).Get (aN1, aN2, aN3); // get indexes of triangle's points
525 // Insert new triangle on these points into output shape data.
526 myShapeData->InsertTriangle (
527 theShapeId, aPointIds(aN1), aPointIds(aN2), aPointIds(aN3), MT_ShadedFace);
528 }
529}