// Created on: 1995-06-20
// Created by: Stagiaire Alain JOURDAIN
// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+#include <BRepMesh_IncrementalMesh.hxx>
+#include <OSD_Parallel.hxx>
+#include <Precision.hxx>
+#include <Standard_ErrorHandler.hxx>
-#include <BRepMesh_IncrementalMesh.ixx>
-
-#include <BRepMesh.hxx>
+#include <BRepMesh_ShapeTool.hxx>
#include <BRepMesh_Edge.hxx>
-#include <BRepMesh_Triangle.hxx>
-#include <BRepMesh_FastDiscretFace.hxx>
#include <BRepMesh_PluginMacro.hxx>
#include <Bnd_Box.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
+#include <BRepTools.hxx>
#include <BRepLib.hxx>
#include <BRepBndLib.hxx>
#include <BRepAdaptor_Curve.hxx>
-#include <GCPnts_TangentialDeflection.hxx>
-#include <Precision.hxx>
+
+#include <Poly_Triangulation.hxx>
+#include <Poly_Polygon3D.hxx>
+#include <Poly_PolygonOnTriangulation.hxx>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopAbs.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
-#include <TopAbs.hxx>
+
#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopTools_MutexForShapeProvider.hxx>
#include <TColgp_Array1OfPnt.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
#include <TColStd_Array1OfReal.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS.hxx>
+#include <TColStd_MapOfTransient.hxx>
#include <TopTools_HArray1OfShape.hxx>
-#include <Poly_Triangulation.hxx>
-#include <Poly_Polygon3D.hxx>
-#include <Poly_PolygonOnTriangulation.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-#include <vector>
+#include <GCPnts_TangentialDeflection.hxx>
-#ifdef HAVE_TBB
- // paralleling using Intel TBB
- #include <tbb/parallel_for_each.h>
-#endif
+IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_IncrementalMesh,BRepMesh_DiscretRoot)
namespace
{
//! Default flag to control parallelization for BRepMesh_IncrementalMesh
//! tool returned for Mesh Factory
static Standard_Boolean IS_IN_PARALLEL = Standard_False;
-};
+}
+
//=======================================================================
-//function : BRepMesh_IncrementalMesh
+//function : Default constructor
//purpose :
//=======================================================================
-BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh()
-: myRelative (Standard_False),
- myInParallel (Standard_False),
- myModified (Standard_False),
- myStatus (0)
+BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh()
+: myMaxShapeSize(0.),
+ myModified(Standard_False),
+ myStatus(0)
{
- mymapedge.Clear();
- myancestors.Clear();
}
//=======================================================================
-//function : BRepMesh_IncrementalMesh
+//function : Constructor
//purpose :
//=======================================================================
-BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh (const TopoDS_Shape& theShape,
- const Standard_Real theDeflection,
- const Standard_Boolean theRelative,
- const Standard_Real theAngle,
- const Standard_Boolean theInParallel)
-: myRelative (theRelative),
- myInParallel (theInParallel),
- myModified (Standard_False),
- myStatus (0)
+BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh( const TopoDS_Shape& theShape,
+ const Standard_Real theLinDeflection,
+ const Standard_Boolean isRelative,
+ const Standard_Real theAngDeflection,
+ const Standard_Boolean isInParallel,
+ const Standard_Boolean adaptiveMin)
+: myMaxShapeSize(0.),
+ myModified(Standard_False),
+ myStatus(0)
{
- mymapedge.Clear();
- myancestors.Clear();
- myDeflection = theDeflection;
- myAngle = theAngle;
- myShape = theShape;
+ myParameters.Deflection = theLinDeflection;
+ myParameters.Relative = isRelative;
+ myParameters.Angle = theAngDeflection;
+ myParameters.InParallel = isInParallel;
+ myParameters.AdaptiveMin = adaptiveMin;
- //
+ myShape = theShape;
Perform();
}
//=======================================================================
-//function : ~
+//function : Constructor
//purpose :
//=======================================================================
-BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
+BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh(const TopoDS_Shape& theShape,
+ const BRepMesh_FastDiscret::Parameters& theParameters)
+ : myParameters(theParameters)
{
+ myShape = theShape;
+
+ Perform();
}
//=======================================================================
-//function : SetParallel
-//purpose :
+//function : Destructor
+//purpose :
//=======================================================================
-void BRepMesh_IncrementalMesh::SetParallel (const Standard_Boolean theInParallel)
+BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
{
- myInParallel = theInParallel;
}
//=======================================================================
-//function : IsParallel
-//purpose :
+//function : clear
+//purpose :
//=======================================================================
-Standard_Boolean BRepMesh_IncrementalMesh::IsParallel() const
+void BRepMesh_IncrementalMesh::clear()
{
- return myInParallel;
+ // the allocator will be alive while the structures are alive
+ Handle(NCollection_BaseAllocator) anAlloc =
+ new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
+ myEdges.Clear(anAlloc);
+ myEdgeDeflection.Clear(anAlloc);
+ myFaces.Clear();
+ myMesh.Nullify();
}
//=======================================================================
-//function : Init
+//function : init
//purpose :
//=======================================================================
-void BRepMesh_IncrementalMesh::Init()
+void BRepMesh_IncrementalMesh::init()
{
- myModified=Standard_False;
- mymapedge.Clear();
- myancestors.Clear();
+ myStatus = 0;
+ myModified = Standard_False;
+
+ setDone();
+ clear();
+
+ collectFaces();
+
+ Bnd_Box aBox;
+ if ( myParameters.Relative )
+ {
+ BRepBndLib::Add(myShape, aBox, Standard_False);
+
+ if (aBox.IsVoid())
+ {
+ // Nothing to mesh.
+ return;
+ }
+
+ BRepMesh_ShapeTool::BoxMaxDimension(aBox, myMaxShapeSize);
+ }
+
+ myMesh = new BRepMesh_FastDiscret (aBox, myParameters);
+
+ myMesh->InitSharedFaces(myShape);
}
//=======================================================================
-//function : SetRelative
+//function : collectFaces
//purpose :
//=======================================================================
-void BRepMesh_IncrementalMesh::SetRelative(const Standard_Boolean theFlag)
+void BRepMesh_IncrementalMesh::collectFaces()
{
- myRelative=theFlag;
+ Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
+ TopTools_ListOfShape aFaceList(anAlloc);
+ BRepLib::ReverseSortFaces(myShape, aFaceList);
+ TColStd_MapOfTransient aTFaceMap(1, anAlloc);
+
+ // make array of faces suitable for processing (excluding faces without surface)
+ TopLoc_Location aDummyLoc;
+ TopTools_ListIteratorOfListOfShape aFaceIter(aFaceList);
+ for (; aFaceIter.More(); aFaceIter.Next())
+ {
+ const TopoDS_Face& aFace = TopoDS::Face(aFaceIter.Value());
+ const Handle(TopoDS_TShape)& aTFace = aFace.TShape();
+ if (!aTFaceMap.Add (aTFace))
+ continue; // already processed
+
+ const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aDummyLoc);
+ if (aSurf.IsNull())
+ continue;
+
+ myFaces.Append(aFace);
+ }
}
//=======================================================================
-//function : Relative
+//function : Perform
//purpose :
//=======================================================================
-Standard_Boolean BRepMesh_IncrementalMesh::Relative()const
+void BRepMesh_IncrementalMesh::Perform()
{
- return myRelative;
+ init();
+
+ if (myMesh.IsNull())
+ return;
+
+ update();
}
//=======================================================================
-//function : IsModified
+//function : update()
//purpose :
//=======================================================================
-Standard_Boolean BRepMesh_IncrementalMesh::IsModified() const
+void BRepMesh_IncrementalMesh::update()
{
- return myModified;
+ // Update edges data
+ TopExp_Explorer aExplorer(myShape, TopAbs_EDGE);
+ for (; aExplorer.More(); aExplorer.Next())
+ {
+ const TopoDS_Edge& aEdge = TopoDS::Edge(aExplorer.Current());
+ if(!BRep_Tool::IsGeometric(aEdge))
+ continue;
+
+ update(aEdge);
+ }
+
+ // Update faces data
+ NCollection_Vector<TopoDS_Face>::Iterator aFaceIt(myFaces);
+ for (; aFaceIt.More(); aFaceIt.Next())
+ update(aFaceIt.Value());
+
+ // Mesh faces
+ OSD_Parallel::ForEach(myFaces.begin(), myFaces.end(), *myMesh, !myParameters.InParallel);
+
+ commit();
+ clear();
}
//=======================================================================
-//function : Perform
+//function : discretizeFreeEdges
//purpose :
//=======================================================================
-void BRepMesh_IncrementalMesh::Perform()
+void BRepMesh_IncrementalMesh::discretizeFreeEdges()
{
- Bnd_Box aBox;
- //
- SetDone();
- //
- Init();
- //
- BRepBndLib::Add(myShape, aBox);
- myBox = aBox;
- //
- if (!myMesh.IsNull()) {
- myMesh.Nullify();
+ TopExp_Explorer aExplorer(myShape ,TopAbs_EDGE, TopAbs_FACE);
+ for (; aExplorer.More(); aExplorer.Next())
+ {
+ const TopoDS_Edge& aEdge = TopoDS::Edge(aExplorer.Current());
+ if(!BRep_Tool::IsGeometric(aEdge))
+ continue;
+
+ TopLoc_Location aLoc;
+ Standard_Real aEdgeDeflection = edgeDeflection(aEdge);
+ Handle(Poly_Polygon3D) aPoly3D = BRep_Tool::Polygon3D(aEdge, aLoc);
+ if (!aPoly3D.IsNull() && aPoly3D->Deflection() < 1.1 * aEdgeDeflection)
+ continue;
+
+ BRepAdaptor_Curve aCurve(aEdge);
+ GCPnts_TangentialDeflection aDiscret(aCurve, aCurve.FirstParameter(),
+ aCurve.LastParameter(), myParameters.Angle, aEdgeDeflection, 2,
+ Precision::PConfusion(), myParameters.MinSize);
+
+ Standard_Integer aNodesNb = aDiscret.NbPoints();
+ TColgp_Array1OfPnt aNodes (1, aNodesNb);
+ TColStd_Array1OfReal aUVNodes(1, aNodesNb);
+ for (Standard_Integer i = 1; i <= aNodesNb; ++i)
+ {
+ aNodes (i) = aDiscret.Value(i);
+ aUVNodes(i) = aDiscret.Parameter(i);
+ }
+
+ aPoly3D = new Poly_Polygon3D(aNodes, aUVNodes);
+ aPoly3D->Deflection(myParameters.Deflection);
+
+ BRep_Builder aBuilder;
+ aBuilder.UpdateEdge(aEdge, aPoly3D);
}
- //
- myMesh = new BRepMesh_FastDiscret(myDeflection,
- myAngle,
- aBox,
- Standard_True,
- Standard_True,
- myRelative,
- Standard_True);
- //
- Update(myShape);
}
//=======================================================================
-//function : GetStatus
+//function : edgeDeflection
//purpose :
//=======================================================================
-Standard_Integer BRepMesh_IncrementalMesh::GetStatusFlags() const
+Standard_Real BRepMesh_IncrementalMesh::edgeDeflection(
+ const TopoDS_Edge& theEdge)
{
- return myStatus;
+ const Standard_Real* pDef = myEdgeDeflection.Seek(theEdge);
+ if (pDef)
+ return *pDef;
+
+ Standard_Real aEdgeDeflection;
+ if ( myParameters.Relative )
+ {
+ Standard_Real aScale;
+ aEdgeDeflection = BRepMesh_ShapeTool::RelativeEdgeDeflection(theEdge,
+ myParameters.Deflection, myMaxShapeSize, aScale);
+ }
+ else
+ aEdgeDeflection = myParameters.Deflection;
+
+ myEdgeDeflection.Bind(theEdge, aEdgeDeflection);
+ return aEdgeDeflection;
}
//=======================================================================
-//function : Update(shape)
-//purpose : Builds the incremental mesh of the shape
+//function : faceDeflection
+//purpose :
//=======================================================================
-void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S)
+Standard_Real BRepMesh_IncrementalMesh::faceDeflection(
+ const TopoDS_Face& theFace)
{
- myModified = Standard_False;
- TopExp_Explorer ex;
+ if ( !myParameters.Relative )
+ return myParameters.Deflection;
- //AGV 080407: Since version 6.2.0 there would be exception without this check
- if (myBox.IsVoid())
- return;
+ Standard_Integer aEdgesNb = 0;
+ Standard_Real aFaceDeflection = 0.;
- TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, myancestors);
-
- BRepMesh_FastDiscret::BoxMaxDimension(myBox, mydtotale);
-
- for (ex.Init(S, TopAbs_EDGE); ex.More(); ex.Next()) {
- if(BRep_Tool::IsGeometric(TopoDS::Edge(ex.Current()))) {
- Update(TopoDS::Edge(ex.Current()));
- }
+ TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
+ for (; aEdgeIt.More(); aEdgeIt.Next(), ++aEdgesNb)
+ {
+ const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
+ aFaceDeflection += edgeDeflection(aEdge);
}
- // get list of faces
- std::vector<TopoDS_Face> aFaces;
+ return (aEdgesNb == 0) ? myParameters.Deflection : (aFaceDeflection / aEdgesNb);
+}
+
+//=======================================================================
+//function : update(edge)
+//purpose :
+//=======================================================================
+void BRepMesh_IncrementalMesh::update(const TopoDS_Edge& theEdge)
+{
+ if (!myEdges.IsBound(theEdge))
+ myEdges.Bind(theEdge, BRepMesh::DMapOfTriangulationBool(3, myEdges.Allocator()));
+
+ Standard_Real aEdgeDeflection = edgeDeflection(theEdge);
+ // Check that triangulation relies to face of the given shape.
+ const TopTools_IndexedDataMapOfShapeListOfShape& aMapOfSharedFaces =
+ myMesh->SharedFaces();
+
+ const TopTools_ListOfShape& aSharedFaces =
+ aMapOfSharedFaces.FindFromKey(theEdge);
+
+ TopTools_ListIteratorOfListOfShape aSharedFaceIt(aSharedFaces);
+ for (; aSharedFaceIt.More(); aSharedFaceIt.Next())
{
- TopTools_ListOfShape aFaceList;
- BRepLib::ReverseSortFaces (S, aFaceList);
- TopTools_MapOfShape aFaceMap;
- aFaces.reserve (aFaceList.Extent());
-
- // make array of faces suitable for processing (excluding faces without surface)
- TopLoc_Location aDummyLoc;
- const TopLoc_Location anEmptyLoc;
- for (TopTools_ListIteratorOfListOfShape aFaceIter (aFaceList); aFaceIter.More(); aFaceIter.Next())
+ TopLoc_Location aLoc;
+ const TopoDS_Face& aFace = TopoDS::Face(aSharedFaceIt.Value());
+ const Handle(Poly_Triangulation)& aFaceTriangulation =
+ BRep_Tool::Triangulation(aFace, aLoc);
+
+ if (aFaceTriangulation.IsNull())
+ continue;
+
+ Standard_Boolean isConsistent = Standard_False;
+ const Handle(Poly_PolygonOnTriangulation)& aPolygon =
+ BRep_Tool::PolygonOnTriangulation(theEdge, aFaceTriangulation, aLoc);
+
+ if (!aPolygon.IsNull())
{
- TopoDS_Shape aFaceNoLoc = aFaceIter.Value();
- aFaceNoLoc.Location (anEmptyLoc);
- if (!aFaceMap.Add (aFaceNoLoc))
- continue; // already processed
-
- TopoDS_Face aFace = TopoDS::Face (aFaceIter.Value());
- const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aDummyLoc);
- if (aSurf.IsNull())
- continue;
+ isConsistent = aPolygon->Deflection() < 1.1 * aEdgeDeflection &&
+ aPolygon->HasParameters();
- Update (aFace);
- aFaces.push_back (aFace);
+ if (!isConsistent)
+ {
+ myModified = Standard_True;
+ BRepMesh_ShapeTool::NullifyEdge(theEdge, aFaceTriangulation, aLoc);
+ }
}
+
+ myEdges(theEdge).Bind(aFaceTriangulation, isConsistent);
}
+}
+
+//=======================================================================
+//function : isToBeMeshed
+//purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_IncrementalMesh::toBeMeshed(
+ const TopoDS_Face& theFace,
+ const Standard_Boolean isWithCheck)
+{
+ TopLoc_Location aLoc;
+ const Handle(Poly_Triangulation)& aTriangulation =
+ BRep_Tool::Triangulation(theFace, aLoc);
- if (myInParallel)
+ if (aTriangulation.IsNull())
+ return Standard_True;
+
+ if (isWithCheck)
{
- #ifdef HAVE_TBB
- myMesh->CreateMutexesForSubShapes(S, TopAbs_EDGE);
- // mesh faces in parallel threads using TBB
- tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *myMesh.operator->());
- #else
- // alternative parallelization not yet available
- for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
- myMesh->Process (*it);
- #endif
- myMesh->RemoveAllMutexes();
+ Standard_Real aFaceDeflection = faceDeflection(theFace);
+ if (aTriangulation->Deflection() < 1.1 * aFaceDeflection)
+ {
+ Standard_Boolean isEdgesConsistent = Standard_True;
+ TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
+ for (; aEdgeIt.More() && isEdgesConsistent; aEdgeIt.Next())
+ {
+ const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
+ if (!myEdges.IsBound(aEdge))
+ continue;
+
+ BRepMesh::DMapOfTriangulationBool& aTriMap = myEdges(aEdge);
+ isEdgesConsistent &= aTriMap.IsBound(aTriangulation) &&
+ aTriMap(aTriangulation);
+ }
+
+ if (isEdgesConsistent)
+ {
+ // #25080: check that indices of links forming triangles are in range.
+ Standard_Boolean isTriangulationConsistent = Standard_True;
+ const Standard_Integer aNodesNb = aTriangulation->NbNodes();
+ const Poly_Array1OfTriangle& aTriangles = aTriangulation->Triangles();
+ Standard_Integer i = aTriangles.Lower();
+ for (; i <= aTriangles.Upper() && isTriangulationConsistent; ++i)
+ {
+ const Poly_Triangle& aTriangle = aTriangles(i);
+ Standard_Integer n[3];
+ aTriangle.Get(n[0], n[1], n[2]);
+ for (Standard_Integer j = 0; j < 3 && isTriangulationConsistent; ++j)
+ isTriangulationConsistent = (n[j] >= 1 && n[j] <= aNodesNb);
+ }
+
+ if (isTriangulationConsistent)
+ return Standard_False;
+ }
+ }
}
- else
+
+ // Nullify edges
+ TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
+ for (; aEdgeIt.More(); aEdgeIt.Next())
{
- for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
- myMesh->Process (*it);
+ const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
+ BRepMesh_ShapeTool::NullifyEdge(aEdge, aTriangulation, aLoc);
}
- // maillage des edges non contenues dans les faces :
- Standard_Real f, l, defedge;
- Standard_Integer i, nbNodes;
- TopLoc_Location L;
- Standard_Real cdef = 1.;
- ex.Init(S ,TopAbs_EDGE, TopAbs_FACE);
+ BRepMesh_ShapeTool::NullifyFace(theFace);
+ return Standard_True;
+}
+
+//=======================================================================
+//function : update(face)
+//purpose :
+//=======================================================================
+void BRepMesh_IncrementalMesh::update(const TopoDS_Face& theFace)
+{
+ if (!toBeMeshed(theFace, Standard_True))
+ return;
+
+ myModified = Standard_True;
+ Standard_Integer aStatus = myMesh->Add(theFace);
+
+ myStatus |= aStatus;
+ if (aStatus != BRepMesh_ReMesh)
+ return;
- while (ex.More()) {
- const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
+ BRepMesh::MapOfShape aUsedFaces;
+ aUsedFaces.Add(theFace);
- if(!BRep_Tool::IsGeometric(E)) {
- ex.Next();
+ const TopTools_IndexedDataMapOfShapeListOfShape& aMapOfSharedFaces =
+ myMesh->SharedFaces();
+
+ TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
+ for (; aEdgeIt.More(); aEdgeIt.Next())
+ {
+ const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
+ if (aMapOfSharedFaces.FindIndex(aEdge) == 0)
continue;
- }
+
+ const TopTools_ListOfShape& aSharedFaces = aMapOfSharedFaces.FindFromKey(aEdge);
+ TopTools_ListIteratorOfListOfShape aSharedFaceIt(aSharedFaces);
+ for (; aSharedFaceIt.More(); aSharedFaceIt.Next())
+ {
+ const TopoDS_Face& aFace = TopoDS::Face(aSharedFaceIt.Value());
+ if (aUsedFaces.Contains(aFace))
+ continue;
- if (myRelative)
- defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection,
- mydtotale, cdef);
- else
- defedge = myDeflection;
-
- Handle(Poly_Polygon3D) P3D = BRep_Tool::Polygon3D(E, L);
- Standard_Boolean maill = Standard_False;
- if (P3D.IsNull()) {
- maill = Standard_True;
- }
- else if (P3D->Deflection() > 1.1*defedge) {
- maill = Standard_True;
- }
- if (maill) {
- BRepAdaptor_Curve C(E);
- f = C.FirstParameter();
- l = C.LastParameter();
-
- GCPnts_TangentialDeflection TD(C, f, l, myAngle, defedge, 2);
- nbNodes = TD.NbPoints();
-
- TColgp_Array1OfPnt Nodes(1, nbNodes);
- TColStd_Array1OfReal UVNodes(1, nbNodes);
- for ( i = 1; i <= nbNodes; i++) {
- Nodes(i) = TD.Value(i);
- UVNodes(i) = TD.Parameter(i);
- }
-
- BRep_Builder B;
- Handle(Poly_Polygon3D) P = new Poly_Polygon3D(Nodes, UVNodes);
- P->Deflection(myDeflection);
- B.UpdateEdge(E, P);
- }
+ aUsedFaces.Add(aFace);
+ toBeMeshed(aFace, Standard_False);
- ex.Next();
+ myStatus |= myMesh->Add(aFace);
+ }
}
}
//=======================================================================
-//function : Update(edge)
-//purpose : Locate a correct discretisation if it exists
-// Set no one otherwise
+//function : commit
+//purpose :
//=======================================================================
-void BRepMesh_IncrementalMesh::Update(const TopoDS_Edge& E)
+void BRepMesh_IncrementalMesh::commit()
{
- TopLoc_Location l;
- Standard_Integer i = 1;
- Handle(Poly_Triangulation) T, TNull;
- Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
- Standard_Boolean found = Standard_False;
- Standard_Real defedge = Precision::Confusion();
- Standard_Real cdef = 1.;
- BRep_Builder B;
- Standard_Boolean defined = Standard_False;
-
- do {
- BRep_Tool::PolygonOnTriangulation(E, Poly, T, l, i);
- i++;
- if (!T.IsNull() && !Poly.IsNull()) {
- if (!defined) {
- if (myRelative)
- defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection,
- mydtotale, cdef);
- else
- defedge = myDeflection;
- mymapedge.Bind(E, defedge);
- defined = Standard_True;
- }
- if ((!myRelative && Poly->Deflection() <= 1.1*defedge) ||
- (myRelative && Poly->Deflection() <= 1.1*defedge))
- found = Standard_True;
- else {
- myModified = Standard_True;
- B.UpdateEdge(E, NullPoly, T, l);
- }
- }
- } while (!Poly.IsNull());
+ NCollection_Vector<TopoDS_Face>::Iterator aFaceIt(myFaces);
+ for (; aFaceIt.More(); aFaceIt.Next())
+ commitEdges(aFaceIt.Value());
- if (!found) myMap.Add(E);
+ discretizeFreeEdges();
}
-
//=======================================================================
-//function : Update(face)
-//purpose : If the face is not correctly triangulated, or if one of its
-// edges is to be discretisated correctly, the triangulation
-// of this face is built.
+//function : commitEdges
+//purpose :
//=======================================================================
-void BRepMesh_IncrementalMesh::Update(const TopoDS_Face& F)
+void BRepMesh_IncrementalMesh::commitEdges(const TopoDS_Face& theFace)
{
- TopLoc_Location l;
- Handle(Geom_Surface) SS = BRep_Tool::Surface(F, l);
- if (SS.IsNull()) return;
-
- //Standard_Integer i;
- Standard_Boolean WillBeTriangulated = Standard_False;
- Handle(Poly_Triangulation) T, TNull;
- T = BRep_Tool::Triangulation(F, l);
- Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
-
- BRep_Builder B;
- TopExp_Explorer ex;
-
- Standard_Real defedge, defface, cdef = 1.;
- Standard_Integer nbEdge = 0;
- if (myRelative) {
- defface = 0.;
-
- for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
- const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
- nbEdge++;
- if (mymapedge.IsBound(edge)) {
- defedge = mymapedge(edge);
- }
- else
- defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(edge, myDeflection, mydtotale, cdef);
- defface = defface + defedge;
- }
- if (nbEdge != 0) defface = defface / nbEdge;
- else defface = myDeflection;
- }
- else
- defface = myDeflection;
-
- if (!T.IsNull()) {
- if ((!myRelative && T->Deflection() <= 1.1*defface) ||
- (myRelative && T->Deflection() <= 1.1*defface)) {
- for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
- const TopoDS_Shape& E = ex.Current();
- Poly = BRep_Tool::PolygonOnTriangulation(TopoDS::Edge(E), T, l);
- if (Poly.IsNull() || myMap.Contains(E)) {
- WillBeTriangulated = Standard_True;
- // cas un peu special. la triangulation est bonne, mais
- // l'edge n'a pas de representation polygonalisee sur celle-ci.
- break;
- }
- }
- }
- else WillBeTriangulated = Standard_True;
+ TopoDS_Face aFace = theFace;
+ aFace.Orientation(TopAbs_FORWARD);
+
+ Handle(BRepMesh_FaceAttribute) aFaceAttribute;
+ if (!myMesh->GetFaceAttribute(aFace, aFaceAttribute))
+ return;
+
+ if (!aFaceAttribute->IsValid())
+ {
+ myStatus |= aFaceAttribute->GetStatus();
+ return;
}
- if (WillBeTriangulated || T.IsNull()) {
- myModified = Standard_True;
- if (!T.IsNull()) {
- for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
- B.UpdateEdge(TopoDS::Edge(ex.Current()), NullPoly, T, l);
- myMap.Remove(ex.Current());
- }
- B.UpdateFace(F, TNull);
- }
- myMesh->Add(F, myancestors);
- myStatus |= (Standard_Integer)(myMesh->CurrentFaceStatus());
- if (myMesh->CurrentFaceStatus() == BRepMesh_ReMesh) {
-#ifdef DEB_MESH
- cout << " face remaillee + finement que prevu."<< endl;
-#endif
-
- Standard_Integer index;
-
- TopTools_MapOfShape MShape;
- MShape.Add(F);
-
- TopoDS_Iterator ex(F),ex2;
- for (; ex.More(); ex.Next()) {
- const TopoDS_Shape& aWire = ex.Value();
- if (aWire.ShapeType() != TopAbs_WIRE)
- continue;
- TopoDS_Iterator exW(aWire);
- for(; exW.More(); exW.Next()) {
- const TopoDS_Edge& edge = TopoDS::Edge(exW.Value());
- index = myancestors.FindIndex(edge);
- if (index != 0) {
- const TopTools_ListOfShape& L = myancestors.FindFromKey(edge);
-
- TopTools_ListIteratorOfListOfShape it(L);
-
- for (; it.More(); it.Next()) {
- TopoDS_Face F2 = TopoDS::Face(it.Value());
- if (!MShape.Contains(F2)) {
- MShape.Add(F2);
- T = BRep_Tool::Triangulation(F2, l);
- if (!T.IsNull()) {
-#ifdef DEB_MESH
- cout <<"triangulation a refaire" <<endl;
-#endif
- for (ex2.Initialize(F2); ex2.More(); ex2.Next()) {
- const TopoDS_Shape& aWire2 = ex2.Value();
- if (aWire2.ShapeType() != TopAbs_WIRE)
- continue;
- TopoDS_Iterator exW2(aWire2);
- for(; exW2.More(); exW2.Next()) {
- TopoDS_Edge E2 = TopoDS::Edge(exW2.Value());
- B.UpdateEdge(E2, NullPoly, T, l);
- }
- }
- B.UpdateFace(F2, TNull);
- myMesh->Add(F2, myancestors);
- }
- }
- }
- }
- }
- }
+ TopLoc_Location aLoc;
+ Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, aLoc);
+
+ if (aTriangulation.IsNull())
+ return;
+
+ try
+ {
+ OCC_CATCH_SIGNALS
+
+ // Store discretization of edges
+ BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = aFaceAttribute->ChangeInternalEdges();
+ BRepMesh::DMapOfShapePairOfPolygon::Iterator aEdgeIt(*aInternalEdges);
+ for (; aEdgeIt.More(); aEdgeIt.Next())
+ {
+ const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Key());
+ const BRepMesh_PairOfPolygon& aPolyPair = aEdgeIt.Value();
+ const Handle(Poly_PolygonOnTriangulation)& aPolygon1 = aPolyPair.First();
+ const Handle(Poly_PolygonOnTriangulation)& aPolygon2 = aPolyPair.Last();
+
+ if (aPolygon1 == aPolygon2)
+ BRepMesh_ShapeTool::UpdateEdge(aEdge, aPolygon1, aTriangulation, aLoc);
+ else
+ BRepMesh_ShapeTool::UpdateEdge(aEdge, aPolygon1, aPolygon2, aTriangulation, aLoc);
}
}
+ catch (Standard_Failure)
+ {
+ myStatus |= BRepMesh_Failure;
+ }
}
//=======================================================================
//function : Discret
//purpose :
//=======================================================================
-Standard_Integer BRepMesh_IncrementalMesh::Discret (const TopoDS_Shape& theShape,
- const Standard_Real theDeflection,
- const Standard_Real theAngle,
- BRepMesh_PDiscretRoot& theAlgo)
+Standard_Integer BRepMesh_IncrementalMesh::Discret(
+ const TopoDS_Shape& theShape,
+ const Standard_Real theDeflection,
+ const Standard_Real theAngle,
+ BRepMesh_DiscretRoot* &theAlgo)
{
BRepMesh_IncrementalMesh* anAlgo = new BRepMesh_IncrementalMesh();
- anAlgo->SetDeflection (theDeflection);
- anAlgo->SetAngle (theAngle);
- anAlgo->SetShape (theShape);
- anAlgo->SetParallel (IS_IN_PARALLEL);
+ anAlgo->ChangeParameters().Deflection = theDeflection;
+ anAlgo->ChangeParameters().Angle = theAngle;
+ anAlgo->ChangeParameters().InParallel = IS_IN_PARALLEL;
+ anAlgo->SetShape (theShape);
theAlgo = anAlgo;
return 0; // no error
}
//=======================================================================
Standard_Boolean BRepMesh_IncrementalMesh::IsParallelDefault()
{
-#ifdef HAVE_TBB
return IS_IN_PARALLEL;
-#else
- // no alternative parallelization yet - flag has no meaning
- return Standard_False;
-#endif
}
//=======================================================================
//function : Discret
//purpose :
//=======================================================================
-void BRepMesh_IncrementalMesh::SetParallelDefault (const Standard_Boolean theInParallel)
+void BRepMesh_IncrementalMesh::SetParallelDefault(
+ const Standard_Boolean theInParallel)
{
IS_IN_PARALLEL = theInParallel;
}