1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-24 13:50:49 +03:00

Update BRepMesh package

This commit is contained in:
bugmaster
2018-07-13 14:26:00 +03:00
parent 813ba25267
commit 9b87a2de25
19 changed files with 0 additions and 5268 deletions

View File

@@ -1,147 +0,0 @@
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_HeaderFile
#define _BRepMesh_HeaderFile
#include <gp_Pnt.hxx>
#include <gp_XYZ.hxx>
#include <gp_XY.hxx>
#include <Bnd_B2d.hxx>
#include <Bnd_Box2d.hxx>
#include <Standard.hxx>
#include <NCollection_List.hxx>
#include <NCollection_Map.hxx>
#include <NCollection_Vector.hxx>
#include <NCollection_Handle.hxx>
#include <NCollection_DataMap.hxx>
#include <NCollection_IndexedMap.hxx>
#include <NCollection_IndexedDataMap.hxx>
#include <NCollection_Array1.hxx>
#include <NCollection_Sequence.hxx>
#include <NCollection_CellFilter.hxx>
#include <NCollection_IncAllocator.hxx>
#include <NCollection_EBTree.hxx>
#include <NCollection_UBTreeFiller.hxx>
#include <BRepMesh_Edge.hxx>
#include <BRepMesh_Triangle.hxx>
#include <BRepMesh_PairOfPolygon.hxx>
#include <BRepMesh_PairOfIndex.hxx>
#include <BRepMesh_Circle.hxx>
#include <TopTools_ShapeMapHasher.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <vector>
class BRepMesh_Vertex;
class TopoDS_Edge;
class TopoDS_Vertex;
class BRepMesh_FaceAttribute;
class BRepMesh_VertexInspector;
class BRepMesh_CircleInspector;
class BRepMesh_Classifier;
class Poly_Triangulation;
class BRepMesh_VertexTool;
namespace BRepMesh
{
//! Default size for memory block allocated by IncAllocator.
/**
* The idea here is that blocks of the given size are returned to the system
* rather than retained in the malloc heap, at least on WIN32 and WIN64 platforms.
*/
#ifdef _WIN64
const size_t MEMORY_BLOCK_SIZE_HUGE = 1024 * 1024;
#else
const size_t MEMORY_BLOCK_SIZE_HUGE = 512 * 1024;
#endif
//! Structure keeping parameters of segment.
struct Segment
{
gp_XY StartPnt;
gp_XY EndPnt;
};
//! Sequences
typedef NCollection_Sequence<Bnd_B2d> SequenceOfBndB2d;
typedef NCollection_Sequence<Standard_Integer> SequenceOfInteger;
typedef NCollection_Sequence<Standard_Real> SequenceOfReal;
//! Vectors
typedef NCollection_Vector<BRepMesh_Vertex> VectorOfVertex;
typedef NCollection_Vector<Standard_Integer> VectorOfInteger;
typedef NCollection_Vector<BRepMesh_Circle> VectorOfCircle;
//! Trees
typedef NCollection_EBTree<Standard_Integer, Bnd_Box2d> BndBox2dTree;
typedef NCollection_UBTreeFiller<Standard_Integer, Bnd_Box2d> BndBox2dTreeFiller;
//! Arrays
typedef NCollection_Array1<BRepMesh_Vertex> Array1OfVertexOfDelaun;
typedef NCollection_Array1<Standard_Integer> Array1OfInteger;
typedef NCollection_Array1<Standard_Real> Array1OfReal;
typedef NCollection_Array1<Segment> Array1OfSegments;
//! Lists
typedef NCollection_List<gp_XY> ListOfXY;
typedef NCollection_List<BRepMesh_Vertex> ListOfVertex;
typedef NCollection_List<Standard_Integer> ListOfInteger;
//! Maps
typedef NCollection_Map<Standard_Real> MapOfReal;
typedef NCollection_Map<Standard_Integer> MapOfInteger;
typedef NCollection_DataMap<Handle(Poly_Triangulation), Standard_Boolean> DMapOfTriangulationBool;
typedef NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> MapOfShape;
typedef NCollection_DataMap<Standard_Integer, Standard_Integer> MapOfIntegerInteger;
typedef NCollection_DataMap<TopoDS_Vertex, Standard_Integer, TopTools_ShapeMapHasher> DMapOfVertexInteger;
typedef NCollection_DataMap<TopoDS_Face, Handle(BRepMesh_FaceAttribute), TopTools_ShapeMapHasher> DMapOfFaceAttribute;
typedef NCollection_DataMap<TopoDS_Shape, BRepMesh_PairOfPolygon, TopTools_ShapeMapHasher> DMapOfShapePairOfPolygon;
typedef NCollection_DataMap<Standard_Integer, gp_Pnt> DMapOfIntegerPnt;
typedef NCollection_DataMap<Standard_Integer, ListOfXY> DMapOfIntegerListOfXY;
typedef NCollection_DataMap<Standard_Integer, ListOfInteger> DMapOfIntegerListOfInteger;
typedef NCollection_DataMap<TopoDS_Edge, DMapOfTriangulationBool, TopTools_ShapeMapHasher> DMapOfEdgeListOfTriangulationBool;
typedef NCollection_IndexedMap<Standard_Integer> IMapOfInteger;
typedef NCollection_IndexedMap<Standard_Real> IMapOfReal;
typedef NCollection_IndexedMap<BRepMesh_Triangle> IMapOfElement;
typedef NCollection_IndexedDataMap<BRepMesh_Edge, BRepMesh_PairOfIndex> IDMapOfLink;
//! CellFilters
typedef NCollection_CellFilter<BRepMesh_CircleInspector> CircleCellFilter;
typedef NCollection_CellFilter<BRepMesh_VertexInspector> VertexCellFilter;
//! Handles
typedef NCollection_Handle<VectorOfVertex> HVectorOfVertex;
typedef NCollection_Handle<MapOfInteger> HMapOfInteger;
typedef NCollection_Handle<IMapOfInteger> HIMapOfInteger;
typedef NCollection_Handle<DMapOfShapePairOfPolygon> HDMapOfShapePairOfPolygon;
typedef NCollection_Handle<DMapOfIntegerPnt> HDMapOfIntegerPnt;
typedef NCollection_Handle<BRepMesh_Classifier> HClassifier;
typedef NCollection_Handle<BndBox2dTree> HBndBox2dTree;
typedef NCollection_Handle<Array1OfSegments> HArray1OfSegments;
typedef NCollection_Handle<DMapOfVertexInteger> HDMapOfVertexInteger;
typedef NCollection_Handle<DMapOfIntegerListOfXY> HDMapOfIntegerListOfXY;
typedef NCollection_Handle<BRepMesh_VertexTool> HVertexTool;
typedef NCollection_Handle<SequenceOfBndB2d> HSequenceOfBndB2d;
typedef NCollection_Handle<SequenceOfInteger> HSequenceOfInteger;
//! Other data structures
typedef std::pair<HArray1OfSegments, HBndBox2dTree> SegmentsTree;
typedef NCollection_Array1<SegmentsTree> Array1OfSegmentsTree;
} // namespace BRepMesh
#endif

View File

@@ -1,89 +0,0 @@
// Created on: 2014-08-13
// Created by: Oleg AGASHIN
// Copyright (c) 2011-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRepMesh_EdgeParameterProvider.hxx>
#include <gp_Pnt.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <Precision.hxx>
//=======================================================================
//function : Constructor
//purpose :
//=======================================================================
BRepMesh_EdgeParameterProvider::BRepMesh_EdgeParameterProvider(
const TopoDS_Edge& theEdge,
const TopoDS_Face& theFace,
const Handle(TColStd_HArray1OfReal)& theParameters)
: myParameters(theParameters),
myIsSameParam(BRep_Tool::SameParameter(theEdge)),
myScale(1.),
myCurveAdaptor(theEdge, theFace)
{
if (myIsSameParam)
return;
// Extract actual parametric values
Standard_Real aLastParam;
BRep_Tool::Range(theEdge, theFace, myFirstParam, aLastParam);
myFoundParam = myCurParam = myFirstParam;
// Extract parameters stored in polygon
myOldFirstParam =
myParameters->Value(myParameters->Lower());
const Standard_Real aOldLastParam =
myParameters->Value(myParameters->Upper());
// Calculate scale factor between actual and stored parameters
if ((myOldFirstParam != myFirstParam || aOldLastParam != aLastParam) &&
myOldFirstParam != aOldLastParam)
{
myScale = (aLastParam - myFirstParam) /
(aOldLastParam - myOldFirstParam);
}
myProjector.Initialize(myCurveAdaptor, myCurveAdaptor.FirstParameter(),
myCurveAdaptor.LastParameter(), Precision::PConfusion());
}
//=======================================================================
//function : Parameter
//purpose :
//=======================================================================
Standard_Real BRepMesh_EdgeParameterProvider::Parameter(
const Standard_Integer theIndex,
const gp_Pnt& thePoint3d)
{
if (myIsSameParam)
return myParameters->Value(theIndex);
// Use scaled
Standard_Real aPrevParam = myCurParam;
myCurParam = myFirstParam + myScale *
(myParameters->Value(theIndex) - myOldFirstParam);
myFoundParam += (myCurParam - aPrevParam);
myProjector.Perform(thePoint3d, myFoundParam);
if (myProjector.IsDone())
myFoundParam = myProjector.Point().Parameter();
return myFoundParam;
}

View File

@@ -1,264 +0,0 @@
// Created on: 2014-08-13
// Created by: Oleg AGASHIN
// Copyright (c) 2011-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRepMesh_EdgeTessellator.hxx>
#include <Geom_Surface.hxx>
#include <Geom_Plane.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <BRepAdaptor_HSurface.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopLoc_Location.hxx>
#include <BRep_Tool.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TColStd_Array1OfReal.hxx>
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_EdgeTessellator,BRepMesh_IEdgeTool)
//=======================================================================
//function : Constructor
//purpose :
//=======================================================================
BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator(
const TopoDS_Edge& theEdge,
const Handle(BRepMesh_FaceAttribute)& theFaceAttribute,
const TopTools_IndexedDataMapOfShapeListOfShape& theMapOfSharedFaces,
const Standard_Real theLinDeflection,
const Standard_Real theAngDeflection,
const Standard_Real theMinSize)
: mySurface(theFaceAttribute->Surface())
{
Standard_Real aPreciseAngDef = 0.5 * theAngDeflection;
Standard_Real aPreciseLinDef = 0.5 * theLinDeflection;
if (theEdge.Orientation() == TopAbs_INTERNAL)
aPreciseLinDef *= 0.5;
mySquareEdgeDef = aPreciseLinDef * aPreciseLinDef;
mySquareMinSize = Max(mySquareEdgeDef, theMinSize * theMinSize);
myEdgeSqTol = BRep_Tool::Tolerance (theEdge);
myEdgeSqTol *= myEdgeSqTol;
Standard_Boolean isSameParam = BRep_Tool::SameParameter(theEdge);
if (isSameParam)
myCOnS.Initialize(theEdge);
else
myCOnS.Initialize(theEdge, theFaceAttribute->Face());
const GeomAbs_CurveType aCurveType = myCOnS.GetType();
Standard_Integer aMinPntNb = (aCurveType == GeomAbs_Circle) ? 4 : 2; //OCC287
// Get 2d curve and init geom tool
Standard_Real aFirstParam, aLastParam;
Handle(Geom2d_Curve) aCurve2d =
BRep_Tool::CurveOnSurface(theEdge, theFaceAttribute->Face(), aFirstParam, aLastParam);
myCurve2d.Load(aCurve2d, aFirstParam, aLastParam);
myTool = new BRepMesh_GeomTool(myCOnS, aFirstParam, aLastParam,
aPreciseLinDef, aPreciseAngDef, aMinPntNb, theMinSize);
if (aCurveType == GeomAbs_BSplineCurve)
{
// bug24220
const Standard_Integer aNbInt = myCOnS.NbIntervals(GeomAbs_C1);
if ( aNbInt > 1 )
{
TColStd_Array1OfReal anIntervals( 1, aNbInt + 1 );
myCOnS.Intervals(anIntervals, GeomAbs_C1);
for (Standard_Integer aIntIt = 1; aIntIt <= aNbInt; ++aIntIt)
{
const Standard_Real& aStartInt = anIntervals.Value( aIntIt );
const Standard_Real& anEndInt = anIntervals.Value( aIntIt + 1 );
BRepMesh_GeomTool aDetalizator(myCOnS, aStartInt, anEndInt,
aPreciseLinDef, aPreciseAngDef, aMinPntNb, theMinSize);
Standard_Integer aNbAddNodes = aDetalizator.NbPoints();
for ( Standard_Integer aNodeIt = 1; aNodeIt <= aNbAddNodes; ++aNodeIt )
{
Standard_Real aParam;
gp_Pnt aPoint3d;
gp_Pnt2d aPoint2d;
aDetalizator.Value( aNodeIt, aParam, aPoint3d);
myCurve2d.D0(aParam, aPoint2d);
myTool->AddPoint( aPoint3d, aParam, Standard_False );
}
}
}
}
// PTv, chl/922/G9, Take into account internal vertices
// it is necessary for internal edges, which do not split other edges, by their vertex
TopExp_Explorer aVertexIt(theEdge, TopAbs_VERTEX);
for (; aVertexIt.More(); aVertexIt.Next())
{
const TopoDS_Vertex& aVertex = TopoDS::Vertex(aVertexIt.Current());
if (aVertex.Orientation() != TopAbs_INTERNAL)
continue;
myTool->AddPoint(BRep_Tool::Pnt(aVertex),
BRep_Tool::Parameter(aVertex, theEdge), Standard_True);
}
Standard_Integer aNodesNb = myTool->NbPoints();
//Check deflection in 2d space for improvement of edge tesselation.
if( isSameParam && aNodesNb > 1)
{
const TopTools_ListOfShape& aSharedFaces = theMapOfSharedFaces.FindFromKey(theEdge);
TopTools_ListIteratorOfListOfShape aFaceIt(aSharedFaces);
for (; aFaceIt.More(); aFaceIt.Next())
{
const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Value());
BRepAdaptor_Surface aSurf(aFace, Standard_False);
if (aSurf.GetType() == GeomAbs_Plane)
continue;
Standard_Real aF, aL;
aCurve2d = BRep_Tool::CurveOnSurface(theEdge, aFace, aF, aL);
if ( Abs(aF - aFirstParam) > Precision::PConfusion() ||
Abs(aL - aLastParam ) > Precision::PConfusion() )
{
continue;
}
Geom2dAdaptor_Curve aGACurve(aCurve2d, aF, aL);
aNodesNb = myTool->NbPoints();
TColStd_Array1OfReal aParamArray(1, aNodesNb);
for (Standard_Integer i = 1; i <= aNodesNb; ++i)
{
gp_Pnt aTmpPnt;
Standard_Real aParam;
myTool->Value(i, aParam, aTmpPnt);
aParamArray.SetValue(i, aParam);
}
for (Standard_Integer i = 1; i < aNodesNb; ++i)
splitSegment(aSurf, aGACurve, aParamArray(i), aParamArray(i + 1), 1);
}
}
const Standard_Real aTol = Precision::Confusion();
const Standard_Real aDu = mySurface->UResolution (aTol);
const Standard_Real aDv = mySurface->VResolution (aTol);
myFaceRangeU[0] = mySurface->FirstUParameter() - aDu;
myFaceRangeU[1] = mySurface->LastUParameter() + aDu;
myFaceRangeV[0] = mySurface->FirstVParameter() - aDv;
myFaceRangeV[1] = mySurface->LastVParameter() + aDv;
}
//=======================================================================
//function : Value
//purpose :
//=======================================================================
Standard_Boolean BRepMesh_EdgeTessellator::Value(
const Standard_Integer theIndex,
Standard_Real& theParameter,
gp_Pnt& thePoint,
gp_Pnt2d& theUV)
{
myTool->Value(theIndex, theParameter, thePoint);
myCurve2d.D0(theParameter, theUV);
// If point coordinates are out of surface range,
// it is necessary to re-project point.
if (mySurface->GetType() != GeomAbs_BSplineSurface &&
mySurface->GetType() != GeomAbs_BezierSurface &&
mySurface->GetType() != GeomAbs_OtherSurface)
{
return Standard_True;
}
// Let skip periodic case.
if (mySurface->IsUPeriodic() || mySurface->IsVPeriodic())
return Standard_True;
// Point lies within the surface range - nothing to do.
if (theUV.X() > myFaceRangeU[0] && theUV.X() < myFaceRangeU[1] &&
theUV.Y() > myFaceRangeV[0] && theUV.Y() < myFaceRangeV[1])
{
return Standard_True;
}
gp_Pnt aPntOnSurf;
mySurface->D0 (theUV.X (), theUV.Y (), aPntOnSurf);
return (thePoint.SquareDistance (aPntOnSurf) < myEdgeSqTol);
}
//=======================================================================
//function : splitSegment
//purpose :
//=======================================================================
void BRepMesh_EdgeTessellator::splitSegment(
const Adaptor3d_Surface& theSurf,
const Geom2dAdaptor_Curve& theCurve2d,
const Standard_Real theFirst,
const Standard_Real theLast,
const Standard_Integer theNbIter)
{
// limit iteration depth
if(theNbIter > 10)
return;
gp_Pnt2d uvf, uvl, uvm;
gp_Pnt P3dF, P3dL, midP3d, midP3dFromSurf;
Standard_Real midpar;
if(Abs(theLast - theFirst) < 2 * Precision::PConfusion())
return;
theCurve2d.D0(theFirst, uvf);
theCurve2d.D0(theLast, uvl);
P3dF = theSurf.Value(uvf.X(), uvf.Y());
P3dL = theSurf.Value(uvl.X(), uvl.Y());
if(P3dF.SquareDistance(P3dL) < mySquareMinSize)
return;
uvm = gp_Pnt2d((uvf.XY() + uvl.XY())*0.5);
midP3dFromSurf = theSurf.Value(uvm.X(), uvm.Y());
gp_XYZ Vec1 = midP3dFromSurf.XYZ() - P3dF.XYZ();
if(Vec1.SquareModulus() < mySquareMinSize)
return;
gp_XYZ aVec = P3dL.XYZ() - P3dF.XYZ();
aVec.Normalize();
Standard_Real aModulus = Vec1.Dot(aVec);
gp_XYZ aProj = aVec * aModulus;
gp_XYZ aDist = Vec1 - aProj;
if(aDist.SquareModulus() < mySquareEdgeDef)
return;
midpar = (theFirst + theLast) * 0.5;
myCOnS.D0(midpar, midP3d);
myTool->AddPoint(midP3d, midpar, Standard_False);
splitSegment(theSurf, theCurve2d, theFirst, midpar, theNbIter + 1);
splitSegment(theSurf, theCurve2d, midpar, theLast, theNbIter + 1);
}

View File

@@ -1,93 +0,0 @@
// Created on: 2014-08-13
// Created by: Oleg AGASHIN
// Copyright (c) 2011-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_EdgeTessellator_HeaderFile
#define _BRepMesh_EdgeTessellator_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <BRepMesh.hxx>
#include <BRepMesh_IEdgeTool.hxx>
#include <BRepMesh_GeomTool.hxx>
#include <BRepMesh_FaceAttribute.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
class Adaptor3d_Surface;
class TopoDS_Edge;
class BRepAdaptor_HSurface;
//! Auxiliary class implements functionality producing tessellated
//! representation of an edge based on edge geometry.
class BRepMesh_EdgeTessellator : public BRepMesh_IEdgeTool
{
public:
//! Constructor.
//! Automatically performs tessellation of the edge according to the
//! given parameters.
BRepMesh_EdgeTessellator(
const TopoDS_Edge& theEdge,
const Handle(BRepMesh_FaceAttribute)& theFaceAttribute,
const TopTools_IndexedDataMapOfShapeListOfShape& theMapOfSharedFaces,
const Standard_Real theLinDeflection,
const Standard_Real theAngDeflection,
const Standard_Real theMinSize);
//! Returns number of dicretization points.
virtual Standard_Integer NbPoints() const Standard_OVERRIDE
{
return myTool->NbPoints();
}
//! Returns parameters of solution with the given index.
//! @param theIndex index of tessellation point.
//! @param theParameter parameters on PCurve corresponded to the solution.
//! @param thePoint tessellation point.
//! @param theUV coordinates of tessellation point in parametric space of face.
//! @return True in case of valid result, false elewhere.
virtual Standard_Boolean Value(
const Standard_Integer theIndex,
Standard_Real& theParameter,
gp_Pnt& thePoint,
gp_Pnt2d& theUV) Standard_OVERRIDE;
DEFINE_STANDARD_RTTIEXT(BRepMesh_EdgeTessellator,BRepMesh_IEdgeTool)
private:
//!
void splitSegment(const Adaptor3d_Surface& theSurf,
const Geom2dAdaptor_Curve& theCurve2d,
const Standard_Real theFirst,
const Standard_Real theLast,
const Standard_Integer theNbIter);
private:
NCollection_Handle<BRepMesh_GeomTool> myTool;
Handle(BRepAdaptor_HSurface) mySurface;
BRepAdaptor_Curve myCOnS;
Geom2dAdaptor_Curve myCurve2d;
Standard_Real mySquareEdgeDef;
Standard_Real mySquareMinSize;
Standard_Real myEdgeSqTol;
Standard_Real myFaceRangeU[2];
Standard_Real myFaceRangeV[2];
};
DEFINE_STANDARD_HANDLE(BRepMesh_EdgeTessellator, BRepMesh_IEdgeTool)
#endif

View File

@@ -1,257 +0,0 @@
// Created by: Ekaterina SMIRNOVA
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRepMesh_FaceAttribute.hxx>
#include <TopoDS_Vertex.hxx>
#include <BRepAdaptor_HSurface.hxx>
#include <BRepMesh_ShapeTool.hxx>
#include <BRepMesh_Classifier.hxx>
#include <BRepTools.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Iterator.hxx>
#include <BRep_Tool.hxx>
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FaceAttribute,Standard_Transient)
//=======================================================================
//function : Constructor
//purpose :
//=======================================================================
BRepMesh_FaceAttribute::BRepMesh_FaceAttribute()
: myDefFace (0.),
myUMin (0.),
myUMax (0.),
myVMin (0.),
myVMax (0.),
myDeltaX (1.),
myDeltaY (1.),
myMinStep (-1.),
myStatus (BRepMesh_NoError),
myAdaptiveMin (Standard_False)
{
init();
}
//=======================================================================
//function : Constructor
//purpose :
//=======================================================================
BRepMesh_FaceAttribute::BRepMesh_FaceAttribute(
const BRepMesh::HDMapOfVertexInteger& theBoundaryVertices,
const BRepMesh::HDMapOfIntegerPnt& theBoundaryPoints)
: myDefFace (0.),
myUMin (0.),
myUMax (0.),
myVMin (0.),
myVMax (0.),
myDeltaX (1.),
myDeltaY (1.),
myMinStep (-1.),
myStatus (BRepMesh_NoError),
myAdaptiveMin (Standard_False),
myBoundaryVertices(theBoundaryVertices),
myBoundaryPoints (theBoundaryPoints)
{
}
//=======================================================================
//function : Constructor
//purpose :
//=======================================================================
BRepMesh_FaceAttribute::BRepMesh_FaceAttribute(
const TopoDS_Face& theFace,
const BRepMesh::HDMapOfVertexInteger& theBoundaryVertices,
const BRepMesh::HDMapOfIntegerPnt& theBoundaryPoints,
const Standard_Boolean theAdaptiveMin)
: myDefFace (0.),
myUMin (0.),
myUMax (0.),
myVMin (0.),
myVMax (0.),
myDeltaX (1.),
myDeltaY (1.),
myMinStep (-1.),
myStatus (BRepMesh_NoError),
myAdaptiveMin (theAdaptiveMin),
myBoundaryVertices(theBoundaryVertices),
myBoundaryPoints (theBoundaryPoints),
myFace (theFace)
{
init();
}
//=======================================================================
//function : Destructor
//purpose :
//=======================================================================
BRepMesh_FaceAttribute::~BRepMesh_FaceAttribute()
{
}
//=======================================================================
//function : SetFace
//purpose :
//=======================================================================
void BRepMesh_FaceAttribute::SetFace (
const TopoDS_Face& theFace,
const Standard_Boolean theAdaptiveMin)
{
myFace = theFace;
myAdaptiveMin = theAdaptiveMin;
init ();
}
//=======================================================================
//function : init
//purpose :
//=======================================================================
void BRepMesh_FaceAttribute::init()
{
myVertexEdgeMap = new BRepMesh::IMapOfInteger;
myInternalEdges = new BRepMesh::DMapOfShapePairOfPolygon;
myLocation2D = new BRepMesh::DMapOfIntegerListOfXY;
myClassifier = new BRepMesh_Classifier;
if (myFace.IsNull())
return;
BRepTools::Update(myFace);
myFace.Orientation(TopAbs_FORWARD);
BRepTools::UVBounds(myFace, myUMin, myUMax, myVMin, myVMax);
if (myAdaptiveMin)
{
// compute minimal UV distance
// between vertices
myMinStep = RealLast();
for (TopoDS_Iterator aFaceIt(myFace); aFaceIt.More(); aFaceIt.Next())
{
for (TopoDS_Iterator aWireIt(aFaceIt.Value()); aWireIt.More(); aWireIt.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(aWireIt.Value());
if (anEdge.IsNull() || BRep_Tool::IsClosed(anEdge))
continue;
// Get end points on 2d curve
gp_Pnt2d aFirst2d, aLast2d;
BRep_Tool::UVPoints(anEdge, myFace, aFirst2d, aLast2d);
Standard_Real aDist =aFirst2d.Distance(aLast2d);
if (aDist < myMinStep)
myMinStep = aDist;
}
}
}
BRepAdaptor_Surface aSurfAdaptor(myFace, Standard_False);
mySurface = new BRepAdaptor_HSurface(aSurfAdaptor);
}
//=======================================================================
//function : Clear
//purpose :
//=======================================================================
void BRepMesh_FaceAttribute::Clear()
{
myStructure.Nullify();
myLocation2D->Clear();
myInternalEdges->Clear();
myVertexEdgeMap->Clear();
}
//=======================================================================
//function : computeParametricTolerance
//purpose :
//=======================================================================
Standard_Real BRepMesh_FaceAttribute::computeParametricTolerance(
const Standard_Real theFirstParam,
const Standard_Real theLastParam) const
{
const Standard_Real aDeflectionUV = 1.e-05;
Standard_Real aPreci = (theLastParam - theFirstParam) * aDeflectionUV;
if(myAdaptiveMin && myMinStep < aPreci)
aPreci = myMinStep;
return Max(Precision::PConfusion(), aPreci);
}
//=======================================================================
//function : getVertexIndex
//purpose :
//=======================================================================
Standard_Boolean BRepMesh_FaceAttribute::getVertexIndex(
const TopoDS_Vertex& theVertex,
Standard_Integer& theVertexIndex) const
{
if (!myBoundaryVertices.IsNull() && myBoundaryVertices->IsBound(theVertex))
theVertexIndex = myBoundaryVertices->Find(theVertex);
else if (!mySurfaceVertices.IsNull() && mySurfaceVertices->IsBound(theVertex))
theVertexIndex = mySurfaceVertices->Find(theVertex);
else
return Standard_False;
return Standard_True;
}
//=======================================================================
//function : AddNode
//purpose :
//=======================================================================
void BRepMesh_FaceAttribute::AddNode(
const Standard_Integer theIndex,
const gp_XY& theUV,
const BRepMesh_DegreeOfFreedom theMovability,
Standard_Integer& theNodeIndex,
Standard_Integer& theNodeOnEdgeIndex)
{
BRepMesh_Vertex aNode(theUV, theIndex, theMovability);
theNodeIndex = myStructure->AddNode(aNode);
theNodeOnEdgeIndex = myVertexEdgeMap->FindIndex(theNodeIndex);
if (theNodeOnEdgeIndex == 0)
theNodeOnEdgeIndex = myVertexEdgeMap->Add(theNodeIndex);
}
//=======================================================================
//function : Scale
//purpose :
//=======================================================================
gp_XY BRepMesh_FaceAttribute::Scale(const gp_XY& thePoint2d,
const Standard_Boolean isToFaceBasis)
{
return isToFaceBasis ?
gp_XY((thePoint2d.X() - myUMin) / myDeltaX, (thePoint2d.Y() - myVMin) / myDeltaY) :
gp_XY(thePoint2d.X() * myDeltaX + myUMin, thePoint2d.Y() * myDeltaY + myVMin);
}
//=======================================================================
//function : ToleranceU
//purpose :
//=======================================================================
Standard_Real BRepMesh_FaceAttribute::ToleranceU() const
{
return computeParametricTolerance(myUMin, myUMax);
}
//=======================================================================
//function : ToleranceV
//purpose :
//=======================================================================
Standard_Real BRepMesh_FaceAttribute::ToleranceV() const
{
return computeParametricTolerance(myVMin, myVMax);
}

View File

@@ -1,405 +0,0 @@
// Copyright (c) 2013 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_FaceAttribute_HeaderFile
#define _BRepMesh_FaceAttribute_HeaderFile
#include <Standard.hxx>
#include <Standard_Transient.hxx>
#include <Standard_Type.hxx>
#include <BRepMesh_Status.hxx>
#include <BRepMesh.hxx>
#include <BRepMesh_DataStructureOfDelaun.hxx>
class BRepAdaptor_HSurface;
//! Auxiliary class for FastDiscret and FastDiscretFace classes.
class BRepMesh_FaceAttribute : public Standard_Transient
{
public:
//! Constructor. Initializes empty attribute.
//! @param theBoundaryVertices shared map of shape vertices.
//! @param theBoundaryPoints shared discretization points of shape boundaries.
Standard_EXPORT BRepMesh_FaceAttribute(
const BRepMesh::HDMapOfVertexInteger& theBoundaryVertices,
const BRepMesh::HDMapOfIntegerPnt& theBoundaryPoints);
//! Constructor.
//! @param theFace face the attribute is created for.
//! Used for default initialization. Attribute keeps reference
//! to the source face with forward orientation.
//! @param theBoundaryVertices shared map of shape vertices.
//! @param theBoundaryPoints shared discretization points of shape boundaries.
//! @param theAdaptiveMin switches on adaptive computation of minimal parametric
//! tolerance (if true).
Standard_EXPORT BRepMesh_FaceAttribute(
const TopoDS_Face& theFace,
const BRepMesh::HDMapOfVertexInteger& theBoundaryVertices,
const BRepMesh::HDMapOfIntegerPnt& theBoundaryPoints,
const Standard_Boolean theAdaptiveMin);
//! Destructor.
Standard_EXPORT virtual ~BRepMesh_FaceAttribute();
public: //! @name main geometrical properties.
//! Returns face's surface.
inline const Handle(BRepAdaptor_HSurface)& Surface() const
{
return mySurface;
}
//! Returns True in case if this attribute has already been intialized.
inline Standard_Boolean IsInitialized () const
{
return !myFace.IsNull ();
}
//! Initializes this attribute by the given face.
Standard_EXPORT void SetFace (
const TopoDS_Face& theFace,
const Standard_Boolean theAdaptiveMin);
//! Returns forward oriented face to be used for calculations.
inline const TopoDS_Face& Face() const
{
return myFace;
}
//! Sets boundary vertices map.
inline void SetBoundaryVertices(const BRepMesh::HDMapOfVertexInteger& theVertices)
{
myBoundaryVertices = theVertices;
}
//! Sets boundary points map.
inline void SetBoundaryPoints(const BRepMesh::HDMapOfIntegerPnt& theBoundaryPoints)
{
myBoundaryPoints = theBoundaryPoints;
}
//! Returns U tolerance of face calculated regarding its parameters.
Standard_EXPORT Standard_Real ToleranceU() const;
//! Returns V tolerance of face calculated regarding its parameters.
Standard_EXPORT Standard_Real ToleranceV() const;
//! Gives face deflection parameter.
inline Standard_Real GetDefFace() const
{
return myDefFace;
}
//! Sets face deflection.
inline void SetDefFace(const Standard_Real theDefFace)
{
myDefFace = theDefFace;
}
//! Gives minimal value in U domain.
inline Standard_Real GetUMin() const
{
return myUMin;
}
//! Sets minimal value in U domain.
inline void SetUMin(const Standard_Real theUMin)
{
myUMin = theUMin;
}
//! Gives minimal value in V domain.
inline Standard_Real GetVMin() const
{
return myVMin;
}
//! Sets minimal value in V domain.
inline void SetVMin(const Standard_Real theVMin)
{
myVMin = theVMin;
}
//! Gives maximal value in U domain.
inline Standard_Real GetUMax() const
{
return myUMax;
}
//! Sets maximal value in U domain.
inline void SetUMax(const Standard_Real theUMax)
{
myUMax = theUMax;
}
//! Gives maximal value in V domain.
inline Standard_Real GetVMax() const
{
return myVMax;
}
//! Sets maximal value in V domain.
inline void SetVMax(const Standard_Real theVMax)
{
myVMax = theVMax;
}
//! Gives value of step in U domain.
inline Standard_Real GetDeltaX() const
{
return myDeltaX;
}
//! Sets value of step in U domain.
inline void SetDeltaX(const Standard_Real theDeltaX)
{
myDeltaX = theDeltaX;
}
//! Gives value of step in V domain.
inline Standard_Real GetDeltaY() const
{
return myDeltaY;
}
//! Sets value of step in V domain.
inline void SetDeltaY(const Standard_Real theDeltaY)
{
myDeltaY = theDeltaY;
}
//! Sets set of status flags for this face.
inline Standard_Integer GetStatus() const
{
return myStatus;
}
//! Sets status flag for this face.
inline void SetStatus(const BRepMesh_Status theStatus)
{
myStatus |= theStatus;
}
//! Returns TRUE in case if computed data is valid.
inline Standard_Boolean IsValid() const
{
return (myStatus == BRepMesh_NoError || myStatus == BRepMesh_ReMesh);
}
public: //! @name auxiliary structures
//! Clear face attribute.
Standard_EXPORT void Clear();
//! Gives reference to map of internal edges of face.
inline BRepMesh::HDMapOfShapePairOfPolygon& ChangeInternalEdges()
{
return myInternalEdges;
}
//! Gives reference to map of 2D points of discretization.
inline BRepMesh::HDMapOfIntegerListOfXY& ChangeLocation2D()
{
return myLocation2D;
}
//! Gives reference to map of 3D points of discretization.
inline BRepMesh::HDMapOfIntegerPnt& ChangeSurfacePoints()
{
return mySurfacePoints;
}
//! Gives reference to map of vertices of discretization.
inline BRepMesh::HDMapOfVertexInteger& ChangeSurfaceVertices()
{
return mySurfaceVertices;
}
//! Gives reference on map of (vertex, edge) pairs of face.
inline BRepMesh::HIMapOfInteger& ChangeVertexEdgeMap()
{
return myVertexEdgeMap;
}
//! Gives Delaunay data structure.
inline Handle(BRepMesh_DataStructureOfDelaun)& ChangeStructure()
{
return myStructure;
}
//! Returns classifier.
inline BRepMesh::HClassifier& ChangeClassifier()
{
return myClassifier;
}
//! Returns mesh nodes calculated for boundaries.
inline BRepMesh::HVectorOfVertex& ChangeMeshNodes()
{
return myMeshNodes;
}
public: //! @name Point/Vertex/Node manipulators
//! Gives the number of different locations in 3D space.
inline Standard_Integer LastPointId() const
{
return (myBoundaryPoints.IsNull() ? 0 : myBoundaryPoints->Extent()) +
(mySurfacePoints.IsNull() ? 0 : mySurfacePoints->Extent());
}
//! Gives the 3D location of the vertex.
inline const gp_Pnt& GetPoint(const BRepMesh_Vertex& theVertex) const
{
return GetPoint(theVertex.Location3d());
}
//! Gives the 3D location of the vertex.
inline const gp_Pnt& GetPoint(const Standard_Integer theIndex) const
{
if (!mySurfacePoints.IsNull() && theIndex > myBoundaryPoints->Extent())
return mySurfacePoints->Find(theIndex);
return myBoundaryPoints->Find(theIndex);
}
//! Returns index of the given vertex if it exists in cache,
//! elsewhere adds it to cache and returns cached index.
//! @param theVertexExplorer template parameter intended to transfer
//! parameters of vertex to method. Explorer class can implement different
//! approaches of extraction of target parameters.
//! @param isFillEdgeVertices if TRUE adds vertex to shared map of
//! edges vertices, elsewhere adds it map of face vertices.
template<class HVertexExplorer>
Standard_Integer GetVertexIndex(
const HVertexExplorer& theVertexExplorer,
const Standard_Boolean isFillEdgeVertices = Standard_False)
{
const TopoDS_Vertex& aVertex = theVertexExplorer->Vertex();
Standard_Integer aNewVertexIndex = 0;
if (getVertexIndex(aVertex, aNewVertexIndex))
return aNewVertexIndex;
if (!theVertexExplorer->IsSameUV() ||
!getVertexIndex(theVertexExplorer->SameVertex(), aNewVertexIndex))
{
aNewVertexIndex = LastPointId() + 1;
BRepMesh::DMapOfIntegerPnt& aPointsMap = isFillEdgeVertices ?
*myBoundaryPoints : *mySurfacePoints;
aPointsMap.Bind(aNewVertexIndex, theVertexExplorer->Point());
}
BRepMesh::DMapOfVertexInteger& aVertexMap = isFillEdgeVertices ?
*myBoundaryVertices : *mySurfaceVertices;
aVertexMap.Bind(aVertex, aNewVertexIndex);
return aNewVertexIndex;
}
//! Adds node with the given parameters to mesh.
//! @param theIndex index of 3D point corresponded to the node.
//! @param theUV node position.
//! @param theMovability movability of a node.
//! @param theNodeIndex index of vertex in mesh structure.
//! @param theNodeOnEdgeIndex ordered index of node on the boundary.
Standard_EXPORT void AddNode(const Standard_Integer theIndex,
const gp_XY& theUV,
const BRepMesh_DegreeOfFreedom theMovability,
Standard_Integer& theNodeIndex,
Standard_Integer& theNodeOnEdgeIndex);
public: //! @name Auxiliary methods
//! Scales the given point from real parametric space
//! to face basis and otherwise.
//! @param thePoint2d point to be scaled.
//! @param isToFaceBasis if TRUE converts point to face basis,
//! otherwise performs reverse conversion.
//! @return scaled point.
Standard_EXPORT gp_XY Scale(const gp_XY& thePoint2d,
const Standard_Boolean isToFaceBasis);
DEFINE_STANDARD_RTTIEXT(BRepMesh_FaceAttribute,Standard_Transient)
private:
//! Default constructor.
BRepMesh_FaceAttribute();
//! Assignment operator.
void operator =(const BRepMesh_FaceAttribute& /*theOther*/)
{
}
//! Initializes internal data structures.
void init();
//! Computes parametric tolerance of a face regarding the given limits.
Standard_Real computeParametricTolerance(
const Standard_Real theFirstParam,
const Standard_Real theLastParam) const;
//! Clears internal data structures local to face.
void clearLocal(
const Standard_Boolean isClearSurfaceDataOnly = Standard_False);
//! Returns index of the given vertex if it exists in cache.
//! @param theVertex vertex which index should be retrieved.
//! @param theVertexIndex index of the given vertex.
//! @return TRUE if cached value is found, FALSE elsewhere.
Standard_EXPORT Standard_Boolean getVertexIndex(
const TopoDS_Vertex& theVertex,
Standard_Integer& theVertexIndex) const;
private:
Standard_Real myDefFace; //!< Restore face deflection
Standard_Real myUMin; //!< Describes minimal value in U domain
Standard_Real myUMax; //!< Describes maximal value in U domain
Standard_Real myVMin; //!< Describes minimal value in V domain
Standard_Real myVMax; //!< Describes maximal value in V domain
Standard_Real myDeltaX;
Standard_Real myDeltaY;
Standard_Real myMinStep;
Standard_Integer myStatus;
Standard_Boolean myAdaptiveMin;
BRepMesh::HDMapOfVertexInteger myBoundaryVertices;
BRepMesh::HDMapOfIntegerPnt myBoundaryPoints;
TopoDS_Face myFace;
Handle(BRepAdaptor_HSurface) mySurface;
BRepMesh::HClassifier myClassifier;
BRepMesh::HDMapOfShapePairOfPolygon myInternalEdges;
BRepMesh::HDMapOfIntegerListOfXY myLocation2D;
BRepMesh::HIMapOfInteger myVertexEdgeMap;
// This field is intended to keep calculated mesh nodes to prevent
// extremely high memory consumption in case if the whole structure is kept.
BRepMesh::HVectorOfVertex myMeshNodes;
BRepMesh::HDMapOfVertexInteger mySurfaceVertices;
BRepMesh::HDMapOfIntegerPnt mySurfacePoints;
Handle(BRepMesh_DataStructureOfDelaun) myStructure;
};
DEFINE_STANDARD_HANDLE(BRepMesh_FaceAttribute, Standard_Transient)
#endif

View File

@@ -1,978 +0,0 @@
// Created on: 1996-02-27
// Created by: Ekaterina SMIRNOVA
// Copyright (c) 1996-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRepMesh_FastDiscret.hxx>
#include <BRepMesh_WireChecker.hxx>
#include <BRepMesh_FastDiscretFace.hxx>
#include <BRepMesh_FaceAttribute.hxx>
#include <BRepMesh_DataStructureOfDelaun.hxx>
#include <BRepMesh_GeomTool.hxx>
#include <BRepMesh_PairOfPolygon.hxx>
#include <BRepMesh_Classifier.hxx>
#include <BRepMesh_EdgeParameterProvider.hxx>
#include <BRepMesh_IEdgeTool.hxx>
#include <BRepMesh_EdgeTessellator.hxx>
#include <BRepMesh_EdgeTessellationExtractor.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepAdaptor_HSurface.hxx>
#include <Bnd_Box.hxx>
#include <BRepTools.hxx>
#include <BRepBndLib.hxx>
#include <BndLib_Add3dCurve.hxx>
#include <Poly_Triangulation.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <Precision.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2dAdaptor_HCurve.hxx>
#include <Geom_Surface.hxx>
#include <Geom_Plane.hxx>
#include <GeomAbs_SurfaceType.hxx>
#include <Extrema_LocateExtPC.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_Array1OfCharacter.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColGeom2d_SequenceOfCurve.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopAbs.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <OSD_Parallel.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
#include <NCollection_IncAllocator.hxx>
#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
#include <BRep_PointRepresentation.hxx>
#include <vector>
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FastDiscret,Standard_Transient)
#define UVDEFLECTION 1.e-05
//=======================================================================
//function : BRepMesh_FastDiscret
//purpose :
//=======================================================================
BRepMesh_FastDiscret::BRepMesh_FastDiscret( const Bnd_Box& theBox,
const BRepMesh_FastDiscret::Parameters& theParams)
:
myMapdefle(1000, new NCollection_IncAllocator()),
myBoundaryVertices(new BRepMesh::DMapOfVertexInteger),
myBoundaryPoints(new BRepMesh::DMapOfIntegerPnt),
myParameters(theParams),
myDtotale(0.)
{
if ( myParameters.Relative )
BRepMesh_ShapeTool::BoxMaxDimension(theBox, myDtotale);
}
//=======================================================================
//function : InitSharedFaces
//purpose :
//=======================================================================
void BRepMesh_FastDiscret::InitSharedFaces(const TopoDS_Shape& theShape)
{
TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, mySharedFaces);
}
//=======================================================================
//function : Perform(shape)
//purpose :
//=======================================================================
void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
{
InitSharedFaces(theShape);
std::vector<TopoDS_Face> aFaces;
TopExp_Explorer anExplorer(theShape, TopAbs_FACE);
for (; anExplorer.More(); anExplorer.Next())
{
const TopoDS_Face& aFace = TopoDS::Face(anExplorer.Current());
Add(aFace);
aFaces.push_back(aFace);
}
OSD_Parallel::ForEach(aFaces.begin(), aFaces.end(), *this, !myParameters.InParallel);
}
//=======================================================================
//function : Process
//purpose :
//=======================================================================
void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
{
Handle(BRepMesh_FaceAttribute) anAttribute;
if (GetFaceAttribute(theFace, anAttribute))
{
try
{
OCC_CATCH_SIGNALS
BRepMesh_FastDiscretFace aTool(myParameters.Angle, myParameters.MinSize,
myParameters.InternalVerticesMode, myParameters.ControlSurfaceDeflection);
aTool.Perform(anAttribute);
}
catch (Standard_Failure)
{
anAttribute->SetStatus(BRepMesh_Failure);
}
}
}
//=======================================================================
//function : resetDataStructure
//purpose :
//=======================================================================
void BRepMesh_FastDiscret::resetDataStructure()
{
Handle(NCollection_IncAllocator) aAllocator;
if (myAttribute->ChangeStructure().IsNull())
aAllocator = new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
else
aAllocator = myAttribute->ChangeStructure()->Allocator();
myAttribute->Clear();
aAllocator->Reset(Standard_False);
Handle(BRepMesh_DataStructureOfDelaun) aStructure =
new BRepMesh_DataStructureOfDelaun(aAllocator);
const Standard_Real aTolU = myAttribute->ToleranceU();
const Standard_Real aTolV = myAttribute->ToleranceV();
const Standard_Real uCellSize = 14.0 * aTolU;
const Standard_Real vCellSize = 14.0 * aTolV;
aStructure->Data()->SetCellSize ( uCellSize, vCellSize);
aStructure->Data()->SetTolerance( aTolU , aTolV );
myAttribute->ChangeStructure() = aStructure;
}
//=======================================================================
//function : Add(face)
//purpose :
//=======================================================================
Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
{
myAttribute.Nullify();
GetFaceAttribute(theFace, myAttribute, Standard_True);
try
{
OCC_CATCH_SIGNALS
// Initialize face attributes
if (!myAttribute->IsInitialized ())
myAttribute->SetFace (theFace, myParameters.AdaptiveMin);
BRepMesh::HIMapOfInteger& aVertexEdgeMap = myAttribute->ChangeVertexEdgeMap();
BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges();
resetDataStructure();
Standard_Real defedge = myParameters.Deflection;
Standard_Integer nbEdge = 0;
Standard_Real savangle = myParameters.Angle;
Standard_Real cdef;
Standard_Real maxdef = 2.* BRepMesh_ShapeTool::MaxFaceTolerance(theFace);
Standard_Real defface = 0.;
if (!myParameters.Relative)
{
defedge = Max(UVDEFLECTION, defedge);
defface = Max(myParameters.Deflection, maxdef);
}
const TopoDS_Face& aFace = myAttribute->Face();
for (TopoDS_Iterator aWireIt(aFace); aWireIt.More(); aWireIt.Next())
{
for (TopoDS_Iterator aEdgeIt(aWireIt.Value()); aEdgeIt.More(); aEdgeIt.Next(), ++nbEdge)
{
const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Value());
if (aEdge.IsNull())
continue;
if (myParameters.Relative)
{
if (!myMapdefle.IsBound(aEdge))
{
if (myEdges.IsBound(aEdge))
{
const BRepMesh_PairOfPolygon& aPair = myEdges.Find(aEdge);
const Handle(Poly_PolygonOnTriangulation)& aPolygon = aPair.First();
defedge = aPolygon->Deflection();
}
else
{
defedge = BRepMesh_ShapeTool::RelativeEdgeDeflection(
aEdge, myParameters.Deflection, myDtotale, cdef);
myParameters.Angle = savangle * cdef;
}
}
else
{
defedge = myMapdefle(aEdge);
}
defface += defedge;
defface = Max(maxdef, defface);
if (!myMapdefle.IsBound(aEdge))
{
defedge = Max(UVDEFLECTION, defedge);
myMapdefle.Bind(aEdge, defedge);
}
}
else
{
if (!myMapdefle.IsBound(aEdge))
{
myMapdefle.Bind(aEdge, defedge);
}
}
Standard_Real aFirstParam, aLastParam;
Handle(Geom2d_Curve) aCurve2d =
BRep_Tool::CurveOnSurface(aEdge, aFace, aFirstParam, aLastParam);
if (aCurve2d.IsNull())
continue;
Handle(Geom2dAdaptor_HCurve) aPCurve =
new Geom2dAdaptor_HCurve(aCurve2d, aFirstParam, aLastParam);
add(aEdge, aPCurve, defedge);
myParameters.Angle = savangle;
}
}
if ( nbEdge == 0 || aVertexEdgeMap->Extent() < 3 )
{
myAttribute->ChangeStructure().Nullify();
myAttribute->SetStatus(BRepMesh_Failure);
return myAttribute->GetStatus();
}
if ( myParameters.Relative )
{
defface = defface / nbEdge;
}
else
{
defface = myParameters.Deflection;
}
defface = Max(maxdef, defface);
TopLoc_Location aLoc;
Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, aLoc);
const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
if ( aTriangulation.IsNull() )
{
Standard_Real xCur, yCur;
Standard_Real maxX, minX, maxY, minY;
minX = minY = 1.e100;
maxX = maxY =-1.e100;
Standard_Integer ipn = 0;
Standard_Integer i1 = 1;
for ( i1 = 1; i1 <= aVertexEdgeMap->Extent(); ++i1 )
{
const BRepMesh_Vertex& aVertex =
myAttribute->ChangeStructure()->GetNode(aVertexEdgeMap->FindKey(i1));
++ipn;
xCur = aVertex.Coord().X();
yCur = aVertex.Coord().Y();
minX = Min(xCur, minX);
maxX = Max(xCur, maxX);
minY = Min(yCur, minY);
maxY = Max(yCur, maxY);
}
Standard_Real myumin = minX;
Standard_Real myumax = maxX;
Standard_Real myvmin = minY;
Standard_Real myvmax = maxY;
const Standard_Real umin = gFace->FirstUParameter();
const Standard_Real umax = gFace->LastUParameter();
const Standard_Real vmin = gFace->FirstVParameter();
const Standard_Real vmax = gFace->LastVParameter();
if (myumin < umin || myumax > umax)
{
if (gFace->IsUPeriodic())
{
if ((myumax - myumin) > (umax - umin))
myumax = myumin + (umax - umin);
}
else
{
if (umin > myumin)
myumin = umin;
if (umax < myumax)
myumax = umax;
}
}
if (myvmin < vmin || myvmax > vmax)
{
if (gFace->IsVPeriodic())
{
if ((myvmax - myvmin) > (vmax - vmin))
myvmax = myvmin + (vmax - vmin);
}
else
{
if ( vmin > myvmin )
myvmin = vmin;
if (vmax < myvmax)
myvmax = vmax;
}
}
GeomAbs_SurfaceType aSurfType = gFace->GetType();
// Fast verification of the validity of calculated limits.
// If wrong, sure a problem of pcurve.
if (aSurfType == GeomAbs_BezierSurface &&
(myumin < -0.5 || myumax > 1.5 || myvmin < -0.5 || myvmax > 1.5) )
{
myAttribute->ChangeStructure().Nullify();
myAttribute->SetStatus(BRepMesh_Failure);
return myAttribute->GetStatus();
}
//define parameters for correct parametrics
Standard_Real deltaX = 1.0;
Standard_Real deltaY = 1.0;
{
Standard_Real aTolU, aTolV;
myAttribute->ChangeStructure()->Data()->GetTolerance(aTolU, aTolV);
const Standard_Real aTol = Sqrt(aTolU * aTolU + aTolV * aTolV);
BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier();
BRepMesh_WireChecker aDFaceChecker(aFace, aTol, aInternalEdges,
aVertexEdgeMap, myAttribute->ChangeStructure(),
myumin, myumax, myvmin, myvmax, myParameters.InParallel );
aDFaceChecker.ReCompute(aClassifier);
BRepMesh_Status aCheckStatus = aDFaceChecker.Status();
if (aCheckStatus == BRepMesh_SelfIntersectingWire)
{
Standard_Integer nbmaill = 0;
Standard_Real eps = Precision::Confusion();
while (nbmaill < 5 && aCheckStatus != BRepMesh_ReMesh)
{
++nbmaill;
resetDataStructure();
for (TopoDS_Iterator aWireIt(aFace); aWireIt.More(); aWireIt.Next())
{
for (TopoDS_Iterator aEdgeIt(aWireIt.Value()); aEdgeIt.More(); aEdgeIt.Next(), ++nbEdge)
{
const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt.Value());
if (anEdge.IsNull())
continue;
if (myEdges.IsBound(anEdge))
myEdges.UnBind(anEdge);
defedge = Max(myMapdefle(anEdge) / 3.0, eps);
myMapdefle.Bind(anEdge, defedge);
Standard_Real aFirstParam, aLastParam;
Handle(Geom2d_Curve) aCurve2d =
BRep_Tool::CurveOnSurface(anEdge, aFace, aFirstParam, aLastParam);
if (aCurve2d.IsNull())
continue;
Handle(Geom2dAdaptor_HCurve) aPCurve =
new Geom2dAdaptor_HCurve(aCurve2d, aFirstParam, aLastParam);
add(anEdge, aPCurve, defedge);
}
}
aDFaceChecker.ReCompute(aClassifier);
if (aDFaceChecker.Status() == BRepMesh_NoError)
aCheckStatus = BRepMesh_ReMesh;
}
}
myAttribute->SetStatus(aCheckStatus);
if (!myAttribute->IsValid())
{
myAttribute->ChangeStructure().Nullify();
return myAttribute->GetStatus();
}
}
// try to find the real length:
// akm (bug OCC16) : We must calculate these measures in non-singular
// parts of face. Let's try to compute average value of three
// (umin, (umin+umax)/2, umax), and respectively for v.
// vvvvv
Standard_Real longu = 0.0, longv = 0.0; //, last , first;
gp_Pnt P11, P12, P21, P22, P31, P32;
Standard_Real du = 0.05 * ( myumax - myumin );
Standard_Real dv = 0.05 * ( myvmax - myvmin );
Standard_Real dfuave = 0.5 * ( myumin + myumax );
Standard_Real dfvave = 0.5 * ( myvmin + myvmax );
Standard_Real dfucur, dfvcur;
// U loop
gFace->D0(myumin, myvmin, P11);
gFace->D0(myumin, dfvave, P21);
gFace->D0(myumin, myvmax, P31);
for (i1=1, dfucur=myumin+du; i1 <= 20; i1++, dfucur+=du)
{
gFace->D0(dfucur, myvmin, P12);
gFace->D0(dfucur, dfvave, P22);
gFace->D0(dfucur, myvmax, P32);
longu += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
P11 = P12;
P21 = P22;
P31 = P32;
}
// V loop
gFace->D0(myumin, myvmin, P11);
gFace->D0(dfuave, myvmin, P21);
gFace->D0(myumax, myvmin, P31);
for (i1=1, dfvcur=myvmin+dv; i1 <= 20; i1++, dfvcur+=dv)
{
gFace->D0(myumin, dfvcur, P12);
gFace->D0(dfuave, dfvcur, P22);
gFace->D0(myumax, dfvcur, P32);
longv += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
P11 = P12;
P21 = P22;
P31 = P32;
}
longu /= 3.;
longv /= 3.;
// akm (bug OCC16) ^^^^^
if (longu <= 1.e-16 || longv <= 1.e-16)
{
//yes, it is seen!!
myAttribute->ChangeStructure().Nullify();
myAttribute->SetStatus(BRepMesh_Failure);
return myAttribute->GetStatus();
}
if (aSurfType == GeomAbs_Torus)
{
gp_Torus Tor = gFace->Torus();
Standard_Real r = Tor.MinorRadius(), R = Tor.MajorRadius();
Standard_Real Du, Dv;//, pasu, pasv;
Dv = Max(1.0e0 - (defface/r),0.0e0) ;
Standard_Real oldDv = 2.0 * ACos (Dv);
oldDv = Min(oldDv, myParameters.Angle);
Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
Dv = oldDv;
Standard_Integer nbV = Max((Standard_Integer)((myvmax-myvmin)/Dv), 2);
Dv = (myvmax-myvmin)/(nbV+1);
Standard_Real ru = R + r;
if ( ru > 1.e-16 )
{
Du = Max(1.0e0 - (defface/ru),0.0e0);
Du = (2.0 * ACos (Du));
Du = Min(Du, myParameters.Angle);
Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
if (aa < gp::Resolution())
{
myAttribute->ChangeStructure().Nullify();
return myAttribute->GetStatus();
}
Du = Du * Min(oldDv, Du) / aa;
}
else
{
Du = Dv;
}
Standard_Integer nbU = Max((Standard_Integer)((myumax-myumin)/Du), 2);
nbU = Max(nbU, (Standard_Integer)(nbV*(myumax-myumin)*R/((myvmax-myvmin)*r)/5.));
Du = (myumax-myumin)/(nbU+1);
//-- DeltaX and DeltaY are chosen so that to avoid "jumping"
//-- of points on the grid
deltaX = Du;
deltaY = Dv;
}
else if (aSurfType == GeomAbs_Cylinder)
{
gp_Cylinder Cyl = gFace->Cylinder();
Standard_Real R = Cyl.Radius();
// Calculate parameters for iteration in U direction
Standard_Real Du = 1.0 - (defface/R);
if (Du < 0.0)
Du = 0.0;
Du = 2.0 * ACos (Du);
if (Du > myParameters.Angle)
Du = myParameters.Angle;
deltaX = Du / longv;
deltaY = 1.;
}
else
{
deltaX = (myumax-myumin)/longu;
deltaY = (myvmax-myvmin)/longv;
}
// Restore face attribute
myAttribute->SetDefFace(defface);
myAttribute->SetUMax(myumax);
myAttribute->SetVMax(myvmax);
myAttribute->SetUMin(myumin);
myAttribute->SetVMin(myvmin);
myAttribute->SetDeltaX(deltaX);
myAttribute->SetDeltaY(deltaY);
}
myAttribute->ChangeMeshNodes() =
myAttribute->ChangeStructure()->Data()->Vertices();
}
catch(Standard_Failure)
{
myAttribute->SetStatus(BRepMesh_Failure);
}
myAttribute->ChangeStructure().Nullify();
return myAttribute->GetStatus();
}
//=======================================================================
//function : getEdgeAttributes
//purpose :
//=======================================================================
Standard_Boolean BRepMesh_FastDiscret::getEdgeAttributes(
const TopoDS_Edge& theEdge,
const Handle(Geom2dAdaptor_HCurve)& thePCurve,
const Standard_Real theDefEdge,
BRepMesh_FastDiscret::EdgeAttributes& theAttributes) const
{
EdgeAttributes& aEAttr = theAttributes;
// Get vertices
TopExp::Vertices(theEdge, aEAttr.FirstVertex, aEAttr.LastVertex);
if (aEAttr.FirstVertex.IsNull() || aEAttr.LastVertex.IsNull())
return Standard_False;
// Get range on 2d curve
const TopoDS_Face& aFace = myAttribute->Face();
BRep_Tool::Range(theEdge, aFace, aEAttr.FirstParam, aEAttr.LastParam);
// Get end points on 2d curve
BRep_Tool::UVPoints(theEdge, aFace, aEAttr.FirstUV, aEAttr.LastUV);
aEAttr.IsSameUV =
aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion());
if (aEAttr.IsSameUV)
{
// 1. is it really sameUV without being degenerated
gp_Pnt2d uvF, uvL;
thePCurve->D0(thePCurve->FirstParameter(), uvF);
thePCurve->D0(thePCurve->LastParameter(), uvL);
if (!aEAttr.FirstUV.IsEqual(uvF, Precision::PConfusion()))
aEAttr.FirstUV = uvF;
if (!aEAttr.LastUV.IsEqual(uvL, Precision::PConfusion()))
aEAttr.LastUV = uvL;
aEAttr.IsSameUV =
aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion());
}
//Control tolerance of vertices
const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
gp_Pnt pFirst = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y());
gp_Pnt pLast = gFace->Value(aEAttr.LastUV.X(), aEAttr.LastUV.Y());
Standard_Real aSqDist = pFirst.SquareDistance(BRep_Tool::Pnt(aEAttr.FirstVertex));
aSqDist = Max(aSqDist, pLast.SquareDistance(BRep_Tool::Pnt(aEAttr.LastVertex)));
aEAttr.Deflection = Max(theDefEdge, BRep_Tool::Tolerance(theEdge));
aEAttr.Deflection = Max(aEAttr.Deflection, sqrt(aSqDist));
return Standard_True;
}
//=======================================================================
//function : registerEdgeVertices
//purpose :
//=======================================================================
void BRepMesh_FastDiscret::registerEdgeVertices(
BRepMesh_FastDiscret::EdgeAttributes& theAttributes,
Standard_Integer& ipf,
Standard_Integer& ivf,
Standard_Integer& isvf,
Standard_Integer& ipl,
Standard_Integer& ivl,
Standard_Integer& isvl)
{
EdgeAttributes& aEAttr = theAttributes;
if (aEAttr.FirstVExtractor.IsNull())
{
// Use edge geometry to produce tesselation.
aEAttr.FirstVExtractor =
new TopoDSVExplorer(aEAttr.FirstVertex, aEAttr.IsSameUV, aEAttr.LastVertex);
}
if (aEAttr.LastVExtractor.IsNull())
{
// Use edge geometry to produce tesselation.
aEAttr.LastVExtractor =
new TopoDSVExplorer(aEAttr.LastVertex, aEAttr.IsSameUV, aEAttr.FirstVertex);
}
// Process first vertex
ipf = myAttribute->GetVertexIndex(aEAttr.FirstVExtractor, Standard_True);
Standard_Real aMinDist = 2. * BRep_Tool::Tolerance(aEAttr.FirstVertex);
gp_XY aTmpUV1 = BRepMesh_ShapeTool::FindUV(ipf, aEAttr.FirstUV, aMinDist, myAttribute);
myAttribute->AddNode(ipf, aTmpUV1, BRepMesh_Frontier, ivf, isvf);
// Process last vertex
ipl = aEAttr.LastVertex.IsSame(aEAttr.FirstVertex) ? ipf :
myAttribute->GetVertexIndex(aEAttr.LastVExtractor, Standard_True);
aMinDist = 2. * BRep_Tool::Tolerance(aEAttr.LastVertex);
gp_XY aTmpUV2 = BRepMesh_ShapeTool::FindUV(ipl, aEAttr.LastUV, aMinDist, myAttribute);
myAttribute->AddNode(ipl, aTmpUV2, BRepMesh_Frontier, ivl, isvl);
// Update edge deflection
const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
gp_Pnt aPntE1 = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y());
gp_Pnt aPntFound1 = gFace->Value(aTmpUV1.X(), aTmpUV1.Y());
Standard_Real aSqDist = aPntE1.SquareDistance(aPntFound1);
gp_Pnt aPntE2 = gFace->Value(aEAttr.LastUV.X(), aEAttr.LastUV.Y());
gp_Pnt aPntFound2 = gFace->Value(aTmpUV2.X(), aTmpUV2.Y());
aSqDist = Max(aSqDist, aPntE2.SquareDistance(aPntFound2));
aEAttr.Deflection = Max(aEAttr.Deflection, sqrt(aSqDist));
}
//=======================================================================
//function : add
//purpose :
//=======================================================================
void BRepMesh_FastDiscret::add(
const TopoDS_Edge& theEdge,
const Handle(Geom2dAdaptor_HCurve)& thePCurve,
const Standard_Real theDefEdge)
{
const TopAbs_Orientation orEdge = theEdge.Orientation();
if (orEdge == TopAbs_EXTERNAL)
return;
EdgeAttributes aEAttr;
if (!getEdgeAttributes(theEdge, thePCurve, theDefEdge, aEAttr))
return;
if (!myEdges.IsBound(theEdge))
{
update(theEdge, thePCurve, theDefEdge, aEAttr);
return;
}
Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
// If this Edge has been already checked and it is not degenerated,
// the points of the polygon calculated at the first check are retrieved :
// retrieve the polygone:
const BRepMesh_PairOfPolygon& aPair = myEdges.Find(theEdge);
const Handle(Poly_PolygonOnTriangulation)& aPolygon = aPair.First();
const TColStd_Array1OfInteger& aNodes = aPolygon->Nodes();
Handle(TColStd_HArray1OfReal) aParams = aPolygon->Parameters();
// creation anew:
const Standard_Integer aNodesNb = aNodes.Length();
TColStd_Array1OfInteger aNewNodes (1, aNodesNb);
TColStd_Array1OfReal aNewParams(1, aNodesNb);
aNewNodes (1) = isvf;
aNewParams(1) = aEAttr.FirstParam;
aNewNodes (aNodesNb) = isvl;
aNewParams(aNodesNb) = aEAttr.LastParam;
const TopoDS_Face& aFace = myAttribute->Face();
if (!BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
{
BRepMesh_EdgeParameterProvider aProvider(theEdge, aFace, aParams);
for (Standard_Integer i = 2; i < aNodesNb; ++i)
{
const Standard_Integer aPointId = aNodes(i);
const gp_Pnt& aPnt = myBoundaryPoints->Find(aPointId);
const Standard_Real aParam = aProvider.Parameter(i, aPnt);
gp_Pnt2d aUV = thePCurve->Value(aParam);
Standard_Integer iv2, isv;
myAttribute->AddNode(aPointId, aUV.Coord(), BRepMesh_OnCurve, iv2, isv);
aNewNodes (i) = isv;
aNewParams(i) = aParam;
}
}
Handle(Poly_PolygonOnTriangulation) P1 =
new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
storePolygon(theEdge, P1, aEAttr.Deflection);
}
//=======================================================================
//function : update(edge)
//purpose :
//=======================================================================
void BRepMesh_FastDiscret::update(
const TopoDS_Edge& theEdge,
const Handle(Geom2dAdaptor_HCurve)& theC2d,
const Standard_Real theDefEdge,
BRepMesh_FastDiscret::EdgeAttributes& theAttributes)
{
EdgeAttributes& aEAttr = theAttributes;
const TopoDS_Face& aFace = myAttribute->Face();
Handle(BRepMesh_IEdgeTool) aEdgeTool;
// Try to find existing tessellation.
for (Standard_Integer i = 1; aEdgeTool.IsNull(); ++i)
{
TopLoc_Location aLoc;
Handle(Poly_Triangulation) aTriangulation;
Handle(Poly_PolygonOnTriangulation) aPolygon;
BRep_Tool::PolygonOnTriangulation(theEdge, aPolygon, aTriangulation, aLoc, i);
if (aPolygon.IsNull())
break;
if (aTriangulation.IsNull() || !aPolygon->HasParameters())
continue;
if (aPolygon->Deflection() > 1.1 * theDefEdge)
continue;
const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
const TColStd_Array1OfInteger& aIndices = aPolygon->Nodes();
Handle(TColStd_HArray1OfReal) aParams = aPolygon->Parameters();
aEAttr.FirstVExtractor = new PolyVExplorer(aEAttr.FirstVertex,
aEAttr.IsSameUV, aEAttr.LastVertex, aIndices(1), aNodes, aLoc);
aEAttr.LastVExtractor = new PolyVExplorer(aEAttr.LastVertex,
aEAttr.IsSameUV, aEAttr.FirstVertex, aIndices(aIndices.Length()), aNodes, aLoc);
aEdgeTool = new BRepMesh_EdgeTessellationExtractor(theEdge, theC2d,
aFace, aTriangulation, aPolygon, aLoc);
}
if (aEdgeTool.IsNull())
{
aEdgeTool = new BRepMesh_EdgeTessellator(theEdge, myAttribute,
mySharedFaces, theDefEdge, myParameters.Angle, myParameters.MinSize);
}
Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
Handle(Poly_PolygonOnTriangulation) P1, P2;
if (BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
{
// two nodes
Standard_Integer aNewNodesArr[] = {isvf, isvl};
Standard_Integer aNewNodInStructArr[] = {ipf, ipl};
Standard_Real aNewParamsArr[] = {aEAttr.FirstParam, aEAttr.LastParam};
TColStd_Array1OfInteger aNewNodes (aNewNodesArr[0], 1, 2);
TColStd_Array1OfInteger aNewNodInStruct(aNewNodInStructArr[0], 1, 2);
TColStd_Array1OfReal aNewParams (aNewParamsArr[0], 1, 2);
P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
}
else
{
const Standard_Integer aNodesNb = aEdgeTool->NbPoints();
// Allocate the memory for arrays aNewNodesVec, aNewNodesInStructVec, aNewParamsVec
// only once using the buffer aBuf.
TColStd_Array1OfCharacter aBuf(1, aNodesNb * (2*sizeof(Standard_Integer) + sizeof(Standard_Real)));
TColStd_Array1OfInteger aNewNodesVec(*reinterpret_cast<const Standard_Integer*>
(&aBuf(1)), 1, aNodesNb);
TColStd_Array1OfInteger aNewNodesInStructVec(*reinterpret_cast<const Standard_Integer*>
(&aBuf(1 + aNodesNb*sizeof(Standard_Integer))), 1, aNodesNb);
TColStd_Array1OfReal aNewParamsVec(*reinterpret_cast<const Standard_Real*>
(&aBuf(1 + aNodesNb*2*sizeof(Standard_Integer))), 1, aNodesNb);
Standard_Integer aNodesCount = 1;
aNewNodesInStructVec(aNodesCount) = ipf;
aNewNodesVec (aNodesCount) = isvf;
aNewParamsVec (aNodesCount) = aEAttr.FirstParam;
++aNodesCount;
Standard_Integer aPrevNodeId = ivf;
Standard_Integer aLastPointId = myAttribute->LastPointId();
for (Standard_Integer i = 2; i < aNodesNb; ++i)
{
gp_Pnt aPnt;
gp_Pnt2d aUV;
Standard_Real aParam;
if (!aEdgeTool->Value(i, aParam, aPnt, aUV))
continue;
// Imitate index of 3d point in order to not to add points to map without necessity.
Standard_Integer iv2, isv;
myAttribute->AddNode(aLastPointId + 1, aUV.Coord(), BRepMesh_Frontier, iv2, isv);
if (aPrevNodeId == iv2)
continue;
// Ok, now we can add point to the map.
myBoundaryPoints->Bind (++aLastPointId, aPnt);
aNewNodesInStructVec(aNodesCount) = aLastPointId;
aNewNodesVec (aNodesCount) = isv;
aNewParamsVec (aNodesCount) = aParam;
++aNodesCount;
aPrevNodeId = iv2;
}
aNewNodesInStructVec(aNodesCount) = ipl;
aNewNodesVec (aNodesCount) = isvl;
aNewParamsVec (aNodesCount) = aEAttr.LastParam;
TColStd_Array1OfInteger aNewNodes (aNewNodesVec.First (), 1, aNodesCount);
TColStd_Array1OfInteger aNewNodInStruct(aNewNodesInStructVec.First(), 1, aNodesCount);
TColStd_Array1OfReal aNewParams (aNewParamsVec.First(), 1, aNodesCount);
P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
}
storePolygon(theEdge, P1, aEAttr.Deflection);
storePolygonSharedData(theEdge, P2, aEAttr.Deflection);
}
//=======================================================================
//function : storeInternalPolygon
//purpose :
//=======================================================================
void BRepMesh_FastDiscret::storePolygon(
const TopoDS_Edge& theEdge,
Handle(Poly_PolygonOnTriangulation)& thePolygon,
const Standard_Real theDeflection)
{
thePolygon->Deflection(theDeflection);
BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges();
if (aInternalEdges->IsBound(theEdge))
{
BRepMesh_PairOfPolygon& aPair = aInternalEdges->ChangeFind(theEdge);
if (theEdge.Orientation() == TopAbs_REVERSED)
aPair.Append(thePolygon);
else
aPair.Prepend(thePolygon);
return;
}
BRepMesh_PairOfPolygon aPair;
aPair.Append(thePolygon);
aInternalEdges->Bind(theEdge, aPair);
}
//=======================================================================
//function : storePolygonSharedData
//purpose :
//=======================================================================
void BRepMesh_FastDiscret::storePolygonSharedData(
const TopoDS_Edge& theEdge,
Handle(Poly_PolygonOnTriangulation)& thePolygon,
const Standard_Real theDeflection)
{
thePolygon->Deflection(theDeflection);
BRepMesh_PairOfPolygon aPair;
aPair.Append(thePolygon);
myEdges.Bind(theEdge, aPair);
}
//=======================================================================
//function : GetFaceAttribute
//purpose :
//=======================================================================
Standard_Boolean BRepMesh_FastDiscret::GetFaceAttribute(
const TopoDS_Face& theFace,
Handle(BRepMesh_FaceAttribute)& theAttribute,
const Standard_Boolean isForceCreate) const
{
if (myAttributes.IsBound(theFace))
{
theAttribute = myAttributes(theFace);
return Standard_True;
}
else if (isForceCreate)
{
theAttribute = new BRepMesh_FaceAttribute(myBoundaryVertices, myBoundaryPoints);
myAttributes.Bind(theFace, theAttribute);
}
return Standard_False;
}
//=======================================================================
//function : RemoveFaceAttribute
//purpose :
//=======================================================================
void BRepMesh_FastDiscret::RemoveFaceAttribute(const TopoDS_Face& theFace)
{
if (myAttributes.IsBound(theFace))
myAttributes.UnBind(theFace);
}

View File

@@ -1,364 +0,0 @@
// Copyright (c) 2013 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_FastDiscret_HeaderFile
#define _BRepMesh_FastDiscret_HeaderFile
#include <Standard.hxx>
#include <Standard_Type.hxx>
#include <BRepMesh_FastDiscret.hxx>
#include <BRepMesh_DataStructureOfDelaun.hxx>
#include <TColStd_IndexedMapOfInteger.hxx>
#include <BRepMesh_Status.hxx>
#include <TopTools_DataMapOfShapeReal.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MutexForShapeProvider.hxx>
#include <Standard_Transient.hxx>
#include <BRepMesh_Delaun.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <BRepMesh_Triangle.hxx>
#include <BRepMesh_FaceAttribute.hxx>
#include <BRepMesh.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <BRep_Tool.hxx>
#include <BRepMesh_ShapeTool.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
class BRepMesh_DataStructureOfDelaun;
class Bnd_Box;
class TopoDS_Shape;
class TopoDS_Face;
class TopoDS_Edge;
class Geom2dAdaptor_HCurve;
class BRepAdaptor_HSurface;
class BRepMesh_Edge;
class BRepMesh_Vertex;
class gp_Pnt;
class BRepMesh_FaceAttribute;
//! Algorithm to mesh a shape with respect of the <br>
//! frontier the deflection and by option the shared <br>
//! components. <br>
class BRepMesh_FastDiscret : public Standard_Transient
{
public:
//! Structure storing meshing parameters
struct Parameters {
//! Default constructor
Parameters()
:
Angle(0.1),
Deflection(0.001),
MinSize(Precision::Confusion()),
InParallel(Standard_False),
Relative(Standard_False),
AdaptiveMin(Standard_False),
InternalVerticesMode(Standard_True),
ControlSurfaceDeflection(Standard_True)
{
}
//! Angular deflection
Standard_Real Angle;
//! Deflection
Standard_Real Deflection;
//! Minimal allowed size of mesh element
Standard_Real MinSize;
//! Switches on/off multy thread computation
Standard_Boolean InParallel;
//! Switches on/off relative computation of edge tolerance<br>
//! If trur, deflection used for the polygonalisation of each edge will be
//! <defle> * Size of Edge. The deflection used for the faces will be the
//! maximum deflection of their edges.
Standard_Boolean Relative;
//! Adaptive parametric tolerance flag. <br>
//! If this flag is set to true the minimal parametric tolerance
//! is computed taking minimal parametric distance between vertices
//! into account
Standard_Boolean AdaptiveMin;
//! Mode to take or ont to take internal face vertices into account
//! in triangulation process
Standard_Boolean InternalVerticesMode;
//! Prameter to check the deviation of triangulation and interior of
//! the face
Standard_Boolean ControlSurfaceDeflection;
};
public:
//! Constructor.
//! Sets the meshing parameters and updates
//! relative defletion according to bounding box
//! @param B - bounding box encompasing shape
//! @param theParams - meshing algo parameters
Standard_EXPORT BRepMesh_FastDiscret (const Bnd_Box& B,
const Parameters& theParams);
//! Build triangulation on the whole shape.
Standard_EXPORT void Perform(const TopoDS_Shape& shape);
//! Record a face for further processing.
//! @return status flags collected during discretization
//! of boundaries of the given face.
Standard_EXPORT Standard_Integer Add(const TopoDS_Face& face);
//! Triangulate a face previously recorded for
//! processing by call to Add(). Can be executed in
//! parallel threads.
Standard_EXPORT void Process(const TopoDS_Face& face) const;
void operator () (const TopoDS_Face& face) const
{
Process(face);
}
//! Returns parameters of meshing
inline const Parameters& MeshParameters() const
{
return myParameters;
}
//! Returns modificable mesh parameters
inline Parameters& ChangeMeshParameters()
{
return myParameters;
}
Standard_EXPORT void InitSharedFaces(const TopoDS_Shape& theShape);
inline const TopTools_IndexedDataMapOfShapeListOfShape& SharedFaces() const
{
return mySharedFaces;
}
//! Returns attribute descriptor for the given face.
//! @param theFace face the attribute should be returned for.
//! @param[out] theAttribute attribute found for the specified face.
//! @param isForceCreate if True creates new attribute in case if there
//! is no data for the given face.
Standard_EXPORT Standard_Boolean GetFaceAttribute (
const TopoDS_Face& theFace,
Handle(BRepMesh_FaceAttribute)& theAttribute,
const Standard_Boolean isForceCreate = Standard_False) const;
//! Remove face attribute as useless to free locate memory.
Standard_EXPORT void RemoveFaceAttribute( const TopoDS_Face& theFace );
//! Returns number of boundary 3d points.
inline Standard_Integer NbBoundaryPoints() const
{
return myBoundaryPoints->Extent();
}
DEFINE_STANDARD_RTTIEXT(BRepMesh_FastDiscret,Standard_Transient)
private:
//! Auxiliary class used to extract geometrical parameters of TopoDS_Vertex.
class TopoDSVExplorer
{
public:
TopoDSVExplorer(
const TopoDS_Vertex& theVertex,
const Standard_Boolean isSameUV,
const TopoDS_Vertex& theSameVertex)
: myVertex(theVertex),
myIsSameUV(isSameUV),
mySameVertex(theSameVertex)
{
}
virtual ~TopoDSVExplorer() {
}
const TopoDS_Vertex& Vertex() const
{
return myVertex;
}
Standard_Boolean IsSameUV() const
{
return myIsSameUV;
}
const TopoDS_Vertex& SameVertex() const
{
return mySameVertex;
}
virtual gp_Pnt Point() const
{
return BRep_Tool::Pnt(myVertex);
}
private:
void operator =(const TopoDSVExplorer& /*theOther*/)
{
}
private:
const TopoDS_Vertex& myVertex;
Standard_Boolean myIsSameUV;
const TopoDS_Vertex& mySameVertex;
};
//! Auxiliary class used to extract polygonal parameters of TopoDS_Vertex.
class PolyVExplorer : public TopoDSVExplorer
{
public:
PolyVExplorer(
const TopoDS_Vertex& theVertex,
const Standard_Boolean isSameUV,
const TopoDS_Vertex& theSameVertex,
const Standard_Integer theVertexIndex,
const TColgp_Array1OfPnt& thePolygon,
const TopLoc_Location& theLoc)
: TopoDSVExplorer(theVertex, isSameUV, theSameVertex),
myVertexIndex(theVertexIndex),
myPolygon(thePolygon),
myLoc(theLoc)
{
}
virtual gp_Pnt Point() const
{
return BRepMesh_ShapeTool::UseLocation(myPolygon(myVertexIndex), myLoc);
}
private:
void operator =(const PolyVExplorer& /*theOther*/)
{
}
private:
Standard_Integer myVertexIndex;
const TColgp_Array1OfPnt& myPolygon;
const TopLoc_Location myLoc;
};
//! Structure keeps common parameters of edge
//! used for tessellation.
struct EdgeAttributes
{
TopoDS_Vertex FirstVertex;
TopoDS_Vertex LastVertex;
Standard_Real FirstParam;
Standard_Real LastParam;
gp_Pnt2d FirstUV;
gp_Pnt2d LastUV;
Standard_Real Deflection;
Standard_Boolean IsSameUV;
NCollection_Handle<TopoDSVExplorer> FirstVExtractor;
NCollection_Handle<TopoDSVExplorer> LastVExtractor;
};
//! Fills structure of by attributes of the given edge.
//! @return TRUE on success, FALSE elsewhere.
Standard_Boolean getEdgeAttributes(
const TopoDS_Edge& theEdge,
const Handle(Geom2dAdaptor_HCurve)& thePCurve,
const Standard_Real theDefEdge,
EdgeAttributes& theAttributes) const;
//! Registers end vertices of the edge in mesh data
//! structure of currently processed face.
void registerEdgeVertices(
EdgeAttributes& theAttributes,
Standard_Integer& ipf,
Standard_Integer& ivf,
Standard_Integer& isvf,
Standard_Integer& ipl,
Standard_Integer& ivl,
Standard_Integer& isvl);
//! Adds tessellated representation of the given edge to
//! mesh data structure of currently processed face.
void add(const TopoDS_Edge& theEdge,
const Handle(Geom2dAdaptor_HCurve)& theCurve2D,
const Standard_Real theEdgeDeflection);
//! Updates tessellated representation of the given edge.
//! If edge already has a polygon which deflection satisfies
//! the given value, retrieves tessellation from polygon.
//! Computes tessellation using edge's geometry elsewhere.
void update(
const TopoDS_Edge& theEdge,
const Handle(Geom2dAdaptor_HCurve)& theCurve2D,
const Standard_Real theEdgeDeflection,
EdgeAttributes& theAttributes);
//! Stores polygonal model of the given edge.
//! @param theEdge edge which polygonal model is stored.
//! @param thePolygon polygonal model of the edge.
//! @param theDeflection deflection with which polygonalization is performed.
//! This value is stored inside the polygon.
void storePolygon(
const TopoDS_Edge& theEdge,
Handle(Poly_PolygonOnTriangulation)& thePolygon,
const Standard_Real theDeflection);
//! Caches polygonal model of the given edge to be used in further.
//! @param theEdge edge which polygonal data is stored.
//! @param thePolygon shared polygonal data of the edge.
//! @param theDeflection deflection with which polygonalization is performed.
//! This value is stored inside the polygon.
void storePolygonSharedData(
const TopoDS_Edge& theEdge,
Handle(Poly_PolygonOnTriangulation)& thePolygon,
const Standard_Real theDeflection);
//! Resets temporary data structure used to collect unique nodes.
void resetDataStructure();
private:
TopoDS_Face myFace;
BRepMesh::DMapOfShapePairOfPolygon myEdges;
mutable BRepMesh::DMapOfFaceAttribute myAttributes;
TopTools_DataMapOfShapeReal myMapdefle;
// Data shared for whole shape
BRepMesh::HDMapOfVertexInteger myBoundaryVertices;
BRepMesh::HDMapOfIntegerPnt myBoundaryPoints;
// Fast access to attributes of current face
Handle(BRepMesh_FaceAttribute) myAttribute;
TopTools_IndexedDataMapOfShapeListOfShape mySharedFaces;
Parameters myParameters;
Standard_Real myDtotale;
};
DEFINE_STANDARD_HANDLE(BRepMesh_FastDiscret, Standard_Transient)
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,194 +0,0 @@
// Copyright (c) 2013 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_FastDiscretFace_HeaderFile
#define _BRepMesh_FastDiscretFace_HeaderFile
#include <Standard.hxx>
#include <Standard_Type.hxx>
#include <BRepMesh_FastDiscretFace.hxx>
#include <BRepMesh_DataStructureOfDelaun.hxx>
#include <BRepMesh.hxx>
#include <BRepMesh_FaceAttribute.hxx>
#include <Standard_Transient.hxx>
#include <TopTools_MutexForShapeProvider.hxx>
#include <TopTools_DataMapOfShapeReal.hxx>
#include <BRepMesh_Delaun.hxx>
#include <BRepMesh_Triangle.hxx>
#include <BRepMesh_Classifier.hxx>
#include <ElSLib.hxx>
class BRepMesh_DataStructureOfDelaun;
class BRepMesh_FaceAttribute;
class TopoDS_Face;
class TopoDS_Vertex;
class BRepAdaptor_HSurface;
class TopoDS_Edge;
class Poly_Triangulation;
class TopLoc_Location;
class gp_XY;
class gp_Pnt2d;
class BRepMesh_Edge;
class BRepMesh_Vertex;
class gp_Pnt;
//! Algorithm to mesh a face with respect of the frontier
//! the deflection and by option the shared components.
class BRepMesh_FastDiscretFace : public Standard_Transient
{
public:
//! Constructor.
//! @param theAngle deviation angle to be used for surface tessellation.
//! @param isInternalVerticesMode flag enabling/disabling internal
//! vertices mode.
//! @param isControlSurfaceDeflection enables/disables adaptive
//! reconfiguration of mesh.
Standard_EXPORT BRepMesh_FastDiscretFace(
const Standard_Real theAngle,
const Standard_Real theMinSize,
const Standard_Boolean isInternalVerticesMode,
const Standard_Boolean isControlSurfaceDeflection);
Standard_EXPORT void Perform(const Handle(BRepMesh_FaceAttribute)& theAttribute);
DEFINE_STANDARD_RTTIEXT(BRepMesh_FastDiscretFace,Standard_Transient)
private:
void add(const Handle(BRepMesh_FaceAttribute)& theAttribute);
void add(const TopoDS_Vertex& theVertex);
Standard_Real control(BRepMesh_Delaun& theMeshBuilder,
const Standard_Boolean theIsFirst);
//! Registers the given nodes in mesh data structure and
//! performs refinement of existing mesh.
//! @param theVertices nodes to be inserted.
//! @param theMeshBuilder initialized tool refining mesh
//! in respect to inserting nodes.
//! @return TRUE if vertices were been inserted, FALSE elewhere.
Standard_Boolean addVerticesToMesh(
const BRepMesh::ListOfVertex& theVertices,
BRepMesh_Delaun& theMeshBuilder);
//! Calculates nodes lying on face's surface and inserts them to a mesh.
//! @param theMeshBuilder initialized tool refining mesh
//! in respect to inserting nodes.
void insertInternalVertices(BRepMesh_Delaun& theMeshBuilder);
//! Calculates nodes lying on spherical surface.
//! @param theNewVertices list of vertices to be extended and added to mesh.
void insertInternalVerticesSphere(BRepMesh::ListOfVertex& theNewVertices);
//! Calculates nodes lying on cylindrical surface.
//! @param theNewVertices list of vertices to be extended and added to mesh.
void insertInternalVerticesCylinder(BRepMesh::ListOfVertex& theNewVertices);
//! Calculates nodes lying on conical surface.
//! @param theNewVertices list of vertices to be extended and added to mesh.
void insertInternalVerticesCone(BRepMesh::ListOfVertex& theNewVertices);
//! Calculates nodes lying on toroidal surface.
//! @param theNewVertices list of vertices to be extended and added to mesh.
void insertInternalVerticesTorus(BRepMesh::ListOfVertex& theNewVertices);
//! Calculates nodes lying on custom-type surface.
//! @param theNewVertices list of vertices to be extended and added to mesh.
void insertInternalVerticesOther(BRepMesh::ListOfVertex& theNewVertices);
//! Template method trying to insert new internal vertex corresponded to
//! the given 2d point. Calculates 3d position analytically using the given
//! surface.
//! @param thePnt2d 2d point to be inserted to the list.
//! @param theAnalyticSurface analytic surface to calculate 3d point.
//! @param[out] theVertices list of vertices to be updated.
template<class AnalyticSurface>
void tryToInsertAnalyticVertex(const gp_Pnt2d& thePnt2d,
const AnalyticSurface& theAnalyticSurface,
BRepMesh::ListOfVertex& theVertices)
{
const BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier();
if (aClassifier->Perform(thePnt2d) != TopAbs_IN)
return;
gp_Pnt aPnt;
ElSLib::D0(thePnt2d.X(), thePnt2d.Y(), theAnalyticSurface, aPnt);
insertVertex(aPnt, thePnt2d.Coord(), theVertices);
}
//! Creates new vertex with the given parameters.
//! @param thePnt3d 3d point corresponded to the vertex.
//! @param theUV UV point corresponded to the vertex.
//! @param[out] theVertices list of vertices to be updated.
void insertVertex(const gp_Pnt& thePnt3d,
const gp_XY& theUV,
BRepMesh::ListOfVertex& theVertices);
//! Stores mesh into the face (without internal edges).
void commitSurfaceTriangulation();
//! Performs initialization of data structure using existing data.
void initDataStructure();
//! Adds new link to the mesh data structure.
//! Movability of the link and order of nodes depend on orientation parameter.
void addLinkToMesh(const Standard_Integer theFirstNodeId,
const Standard_Integer theLastNodeId,
const TopAbs_Orientation theOrientation);
//! Inserts new node into a mesh in case if smoothed region build
//! using the given node has better deflection metrics than source state.
//! @param thePnt3d 3d point corresponded to the vertex.
//! @param theUV UV point corresponded to the vertex.
//! @param isDeflectionCheckOnly if TRUE new node will not be added to a mesh
//! even if deflection parameter is better.
//! @param theTriangleDeflection deflection of a triangle from real geometry.
//! @param theFaceDeflection deflection to be achieved.
//! @param theCircleTool tool used for fast extraction of triangles
//! touched by the given point.
//! @param[out] theVertices list of vertices to be updated.
//! @param[in out] theMaxTriangleDeflection maximal deflection of a mesh.
//! @return TRUE in case if the given deflection of triangle is fine and
//! there is no necessity to insert new node or new node was being inserted
//! successfully, FALSE in case if new configuration is better but
//! isDeflectionCheckOnly flag is set.
Standard_Boolean checkDeflectionAndInsert(
const gp_Pnt& thePnt3d,
const gp_XY& theUV,
const Standard_Boolean isDeflectionCheckOnly,
const Standard_Real theTriangleDeflection,
const Standard_Real theFaceDeflection,
const BRepMesh_CircleTool& theCircleTool,
BRepMesh::ListOfVertex& theVertices,
Standard_Real& theMaxTriangleDeflection,
const Handle(NCollection_IncAllocator)& theTempAlloc);
private:
Standard_Real myAngle;
Standard_Boolean myInternalVerticesMode;
BRepMesh::IMapOfReal myUParam;
BRepMesh::IMapOfReal myVParam;
// Fast access to attributes of current face
Handle(BRepMesh_FaceAttribute) myAttribute;
Handle(BRepMesh_DataStructureOfDelaun) myStructure;
Standard_Real myMinSize;
Standard_Boolean myIsControlSurfaceDeflection;
};
DEFINE_STANDARD_HANDLE (BRepMesh_FastDiscretFace, Standard_Transient)
#endif

View File

@@ -1,20 +0,0 @@
// Created on: 2014-08-13
// Created by: Oleg AGASHIN
// Copyright (c) 2011-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRepMesh_IEdgeTool.hxx>
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_IEdgeTool,Standard_Transient)

View File

@@ -1,48 +0,0 @@
// Created on: 2014-08-13
// Created by: Oleg AGASHIN
// Copyright (c) 2011-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_IEdgeTool_HeaderFile
#define _BRepMesh_IEdgeTool_HeaderFile
#include <Standard.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <Standard_Transient.hxx>
//! Interface class providing API for edge tessellation tools.
class BRepMesh_IEdgeTool : public Standard_Transient
{
public:
//! Returns number of tessellation points.
virtual Standard_Integer NbPoints() const = 0;
//! Returns parameters of solution with the given index.
//! @param theIndex index of tessellation point.
//! @param theParameter parameters on PCurve corresponded to the solution.
//! @param thePoint tessellation point.
//! @param theUV coordinates of tessellation point in parametric space of face.
//! @return True in case of valid result, false elewhere.
virtual Standard_Boolean Value(
const Standard_Integer theIndex,
Standard_Real& theParameter,
gp_Pnt& thePoint,
gp_Pnt2d& theUV) = 0;
DEFINE_STANDARD_RTTIEXT(BRepMesh_IEdgeTool,Standard_Transient)
};
DEFINE_STANDARD_HANDLE(BRepMesh_IEdgeTool, Standard_Transient)
#endif

View File

@@ -1,81 +0,0 @@
// Copyright (c) 2013 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_PairOfPolygon_HeaderFile
#define _BRepMesh_PairOfPolygon_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Macro.hxx>
class Poly_PolygonOnTriangulation;
class BRepMesh_PairOfPolygon
{
public:
DEFINE_STANDARD_ALLOC
//! Constructor. Creates empty pair with null fileds.
BRepMesh_PairOfPolygon()
{
}
//! Clears pair handles.
inline void Clear()
{
myFirst.Nullify();
myLast.Nullify();
}
//! Sets the first element of the pair.
//! If last element is empty, also assignes the given polygon to it.
//! @param thePolygon plygon to be set.
inline void Prepend(const Handle(Poly_PolygonOnTriangulation)& thePolygon)
{
myFirst = thePolygon;
if (myLast.IsNull())
myLast = thePolygon;
}
//! Sets the last element of the pair.
//! If first element is empty, also assignes the given polygon to it.
//! @param thePolygon plygon to be set.
inline void Append(const Handle(Poly_PolygonOnTriangulation)& thePolygon)
{
if (myFirst.IsNull())
myFirst = thePolygon;
myLast = thePolygon;
}
//! Returns first polygon on triangulation.
inline const Handle(Poly_PolygonOnTriangulation)& First() const
{
return myFirst;
}
//! Returns last polygon on triangulation.
inline const Handle(Poly_PolygonOnTriangulation)& Last() const
{
return myLast;
}
private:
Handle(Poly_PolygonOnTriangulation) myFirst;
Handle(Poly_PolygonOnTriangulation) myLast;
};
#endif

View File

@@ -1,29 +0,0 @@
// Created on: 2011-05-17
// Created by: Oleg AGASHIN
// Copyright (c) 2011-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_Status_HeaderFile
#define _BRepMesh_Status_HeaderFile
//! Discribes the wires discretisation.
enum BRepMesh_Status
{
BRepMesh_NoError = 0x0,
BRepMesh_OpenWire = 0x1,
BRepMesh_SelfIntersectingWire = 0x2,
BRepMesh_Failure = 0x4,
BRepMesh_ReMesh = 0x8
};
#endif

View File

@@ -1,410 +0,0 @@
// Created on: 2014-06-03
// Created by: Oleg AGASHIN
// Copyright (c) 1997-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRepMesh_WireChecker.hxx>
#include <Precision.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <gp_Pnt2d.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <TopAbs_Orientation.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Iterator.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <BRepMesh_PairOfPolygon.hxx>
#include <TColStd_SequenceOfInteger.hxx>
#include <TColStd_IndexedMapOfInteger.hxx>
#include <BRepMesh_DataStructureOfDelaun.hxx>
#include <BRepMesh_Classifier.hxx>
#include <BRepMesh_WireInterferenceChecker.hxx>
#include <OSD_Parallel.hxx>
//=======================================================================
//function : Selector::Constructor
//purpose :
//=======================================================================
BRepMesh_WireChecker::BndBox2dTreeSelector::BndBox2dTreeSelector(
const Standard_Integer theReservedSize)
: mySkippedIndex(-1),
myIndices(0, theReservedSize - 1),
myIndicesNb(0)
{
}
//=======================================================================
//function : Reject
//purpose :
//=======================================================================
Standard_Boolean BRepMesh_WireChecker::BndBox2dTreeSelector::Reject(
const Bnd_Box2d& theBox2D) const
{
return myBox2D.IsOut(theBox2D);
}
//=======================================================================
//function : Accept
//purpose :
//=======================================================================
Standard_Boolean BRepMesh_WireChecker::BndBox2dTreeSelector::Accept(
const Standard_Integer& theIndex)
{
if (theIndex <= mySkippedIndex)
return Standard_False;
myIndices(myIndicesNb++) = theIndex;
return Standard_True;
}
//=======================================================================
//function : Clear
//purpose :
//=======================================================================
void BRepMesh_WireChecker::BndBox2dTreeSelector::Clear()
{
mySkippedIndex = -1;
myIndicesNb = 0;
}
//=======================================================================
//function : SetBox
//purpose :
//=======================================================================
void BRepMesh_WireChecker::BndBox2dTreeSelector::SetBox(
const Bnd_Box2d& theBox2D)
{
myBox2D = theBox2D;
}
//=======================================================================
//function : Clear
//purpose :
//=======================================================================
void BRepMesh_WireChecker::BndBox2dTreeSelector::SetSkippedIndex(
const Standard_Integer theIndex)
{
mySkippedIndex = theIndex;
}
//=======================================================================
//function : Indices
//purpose :
//=======================================================================
const BRepMesh::Array1OfInteger&
BRepMesh_WireChecker::BndBox2dTreeSelector::Indices() const
{
return myIndices;
}
//=======================================================================
//function : IndicesNb
//purpose :
//=======================================================================
Standard_Integer BRepMesh_WireChecker::BndBox2dTreeSelector::IndicesNb() const
{
return myIndicesNb;
}
//=======================================================================
//function : Constructor
//purpose :
//=======================================================================
BRepMesh_WireChecker::BRepMesh_WireChecker(
const TopoDS_Face& theFace,
const Standard_Real theTolUV,
const BRepMesh::HDMapOfShapePairOfPolygon& theEdges,
const BRepMesh::HIMapOfInteger& theVertexMap,
const Handle(BRepMesh_DataStructureOfDelaun)& theStructure,
const Standard_Real theUmin,
const Standard_Real theUmax,
const Standard_Real theVmin,
const Standard_Real theVmax,
const Standard_Boolean isInParallel)
: myTolUV(theTolUV),
myEdges(theEdges),
myVertexMap(theVertexMap),
myStructure(theStructure),
myUmin(theUmin),
myUmax(theUmax),
myVmin(theVmin),
myVmax(theVmax),
myStatus(BRepMesh_NoError),
myIsInParallel(isInParallel)
{
TopoDS_Face aFace = theFace;
aFace.Orientation(TopAbs_FORWARD);
for (TopoDS_Iterator aFaceIt(aFace); aFaceIt.More(); aFaceIt.Next())
{
if (aFaceIt.Value().IsNull() || aFaceIt.Value().ShapeType() != TopAbs_WIRE) // may be inner vertex
continue;
const TopoDS_Wire& aWire = TopoDS::Wire(aFaceIt.Value());
myWiresEdges.Append(ListOfEdges());
ListOfEdges& aEdges = myWiresEdges.ChangeLast();
// Start traversing the wires
BRepTools_WireExplorer aWireExplorer(aWire, aFace);
for (; aWireExplorer.More(); aWireExplorer.Next())
{
const TopoDS_Edge& aEdge = aWireExplorer.Current();
TopAbs_Orientation aOrient = aEdge.Orientation();
if (aOrient != TopAbs_FORWARD && aOrient != TopAbs_REVERSED)
continue;
aEdges.Append(aEdge);
}
if (aEdges.IsEmpty())
myWiresEdges.Remove(myWiresEdges.Size());
}
}
//=======================================================================
//function : ReCompute
//purpose :
//=======================================================================
void BRepMesh_WireChecker::ReCompute(BRepMesh::HClassifier& theClassifier)
{
if (theClassifier.IsNull())
return;
theClassifier->Destroy();
myStatus = BRepMesh_NoError;
SeqOfDWires aDWires;
if (!collectDiscretizedWires(aDWires))
return;
const Standard_Integer aNbWires = aDWires.Size();
BRepMesh::Array1OfSegmentsTree aWiresBiPoints(1, aNbWires);
fillSegmentsTree(aDWires, aWiresBiPoints);
if (myIsInParallel && aNbWires > 1)
{
// Check wires in parallel threads.
Standard_Mutex aWireMutex;
BRepMesh_WireInterferenceChecker aIntChecker(aWiresBiPoints, &myStatus, &aWireMutex);
OSD_Parallel::For(1, aNbWires + 1, aIntChecker);
}
else
{
BRepMesh_WireInterferenceChecker aIntChecker(aWiresBiPoints, &myStatus);
OSD_Parallel::For(1, aNbWires + 1, aIntChecker, Standard_True);
}
if (myStatus == BRepMesh_SelfIntersectingWire)
return;
// Find holes
SeqOfDWires::Iterator aDWiresIt(aDWires);
for (; aDWiresIt.More(); aDWiresIt.Next())
{
const SeqOfPnt2d& aDWire = aDWiresIt.Value();
theClassifier->RegisterWire(aDWire, myTolUV, myUmin, myUmax, myVmin, myVmax);
}
}
//=======================================================================
//function : collectDiscretizedWires
//purpose :
//=======================================================================
Standard_Boolean BRepMesh_WireChecker::collectDiscretizedWires(
SeqOfDWires& theDWires)
{
SeqOfWireEdges::Iterator aWireIt(myWiresEdges);
for(; aWireIt.More(); aWireIt.Next())
{
const ListOfEdges& aEdges = aWireIt.Value();
// For each wire we create a data map, linking vertices (only
// the ends of edges) with their positions in the sequence of
// all 2d points from this wire.
// When we meet some vertex for the second time - the piece
// of sequence is treated for a HOLE and quits the sequence.
// Actually, we must unbind the vertices belonging to the
// loop from the map, but since they can't appear twice on the
// valid wire, leave them for a little speed up.
SeqOfPnt2d aSeqPnt2d;
BRepMesh::MapOfIntegerInteger aNodeInSeq;
Standard_Integer aFirstIndex = 0, aLastIndex = 0;
// Start traversing the wire
ListOfEdges::Iterator aEdgeIt(aEdges);
for (; aEdgeIt.More(); aEdgeIt.Next())
{
const TopoDS_Edge& aEdge = aEdgeIt.Value();
TopAbs_Orientation aOrient = aEdge.Orientation();
if (!myEdges->IsBound(aEdge))
continue;
// Retrieve polygon
// Define the direction for adding points to aSeqPnt2d
Standard_Integer aStartId, aEndId, aIncrement;
const BRepMesh_PairOfPolygon& aPair = myEdges->Find(aEdge);
Handle(Poly_PolygonOnTriangulation) aNOD;
if (aOrient == TopAbs_FORWARD)
{
aNOD = aPair.First();
aStartId = 1;
aEndId = aNOD->NbNodes();
aIncrement = 1;
}
else
{
aNOD = aPair.Last();
aStartId = aNOD->NbNodes();
aEndId = 1;
aIncrement = -1;
}
const TColStd_Array1OfInteger& aIndices = aNOD->Nodes();
const Standard_Integer aFirstVertexId = myVertexMap->FindKey(aIndices(aStartId));
const Standard_Integer aLastVertexId = myVertexMap->FindKey(aIndices(aEndId) );
if (aFirstVertexId == aLastVertexId && (aEndId - aStartId) == aIncrement)
{
// case of continuous set of degenerated edges
aLastIndex = aLastVertexId;
continue;
}
if (aFirstIndex != 0)
{
if (aFirstVertexId != aLastIndex)
{
// there's a gap between edges
myStatus = BRepMesh_OpenWire;
return Standard_False;
}
}
else
aFirstIndex = aFirstVertexId;
aLastIndex = aLastVertexId;
// Record first vertex (to detect loops)
aNodeInSeq.Bind(aFirstVertexId, (aSeqPnt2d.Length() + 1));
// Add vertices in sequence
for (Standard_Integer i = aStartId; i != aEndId; i += aIncrement)
{
Standard_Integer aIndex = ((i == aStartId) ?
aFirstVertexId :
myVertexMap->FindKey(aIndices(i)));
aSeqPnt2d.Append(gp_Pnt2d(myStructure->GetNode(aIndex).Coord()));
}
// Now, is there a loop?
if (aNodeInSeq.IsBound(aLastVertexId))
{
// Yes, treat it separately as a hole
// Divide points into main wire and a loop
const Standard_Integer aIdxWireStart = aNodeInSeq(aLastVertexId);
if(aIdxWireStart < aSeqPnt2d.Length())
{
theDWires.Append(SeqOfPnt2d());
SeqOfPnt2d& aWire = theDWires.ChangeLast();
aSeqPnt2d.Split(aIdxWireStart, aWire);
}
}
}
if (aFirstIndex == 0)
continue;
// Isn't wire open?
if (aFirstIndex != aLastIndex || aSeqPnt2d.Length() > 1)
{
myStatus = BRepMesh_OpenWire;
return Standard_False;
}
}
return Standard_True;
}
//=======================================================================
//function : fillSegmentsTree
//purpose :
//=======================================================================
void BRepMesh_WireChecker::fillSegmentsTree(
const SeqOfDWires& theDWires,
BRepMesh::Array1OfSegmentsTree& theWiresSegmentsTree)
{
const Standard_Integer aNbWires = theDWires.Size();
for (Standard_Integer aWireIt = 1; aWireIt <= aNbWires; ++aWireIt)
{
const SeqOfPnt2d& aWire = theDWires(aWireIt);
const Standard_Integer aWireLen = aWire.Size();
BRepMesh::HArray1OfSegments aWireSegments =
new BRepMesh::Array1OfSegments(1, aWireLen);
BRepMesh::HBndBox2dTree aBndBoxTree =
new BRepMesh::BndBox2dTree;
BRepMesh::BndBox2dTreeFiller aBndBoxTreeFiller(*aBndBoxTree);
Standard_Real x1 = 0., y1 = 0., aXstart = 0., aYstart = 0.;
for (Standard_Integer aPntIt = 0; aPntIt <= aWireLen; ++aPntIt)
{
Standard_Real x2, y2;
// Obtain last point of the segment
if (aPntIt == aWireLen)
{
x2 = aXstart;
y2 = aYstart;
}
else
{
const gp_Pnt2d& aPnt = aWire(aPntIt + 1);
x2 = aPnt.X();
y2 = aPnt.Y();
}
// Build segment (bi-point)
if (aPntIt == 0)
{
aXstart = x2;
aYstart = y2;
}
else
{
gp_Pnt2d aStartPnt(x1, y1);
gp_Pnt2d aEndPnt(x2, y2);
BRepMesh::Segment& aSegment = aWireSegments->ChangeValue(aPntIt);
aSegment.StartPnt = aStartPnt.XY();
aSegment.EndPnt = aEndPnt.XY();
Bnd_Box2d aBox;
aBox.Add(aStartPnt);
aBox.Add( aEndPnt);
aBndBoxTreeFiller.Add(aPntIt, aBox);
}
x1 = x2;
y1 = y2;
}
aBndBoxTreeFiller.Fill();
BRepMesh::SegmentsTree& aSegmentsTree = theWiresSegmentsTree(aWireIt);
aSegmentsTree.first = aWireSegments;
aSegmentsTree.second = aBndBoxTree;
}
}

View File

@@ -1,142 +0,0 @@
// Created on: 2014-06-03
// Created by: Oleg AGASHIN
// Copyright (c) 1997-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_WireChecker_HeaderFile
#define _BRepMesh_WireChecker_HeaderFile
#include <Standard.hxx>
#include <TopoDS_Face.hxx>
#include <BRepMesh_Status.hxx>
#include <BRepMesh_DataStructureOfDelaun.hxx>
#include <BRepMesh.hxx>
#include <TColStd_IndexedMapOfInteger.hxx>
#include <TopoDS_Edge.hxx>
#include <Bnd_Box2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_XY.hxx>
#include <vector>
//! Auxilary class intended to check correctness of discretized face.
//! In particular, checks boundaries of discretized face for self
//! intersections and gaps.
class BRepMesh_WireChecker
{
public:
//! Selector.
//! Used to identify segments with overlapped bounding boxes.
//! Note that instance of selector can be used only once due to
//! unextentable array of indices.
class BndBox2dTreeSelector : public BRepMesh::BndBox2dTree::Selector
{
public:
Standard_EXPORT BndBox2dTreeSelector(const Standard_Integer theReservedSize);
Standard_EXPORT virtual Standard_Boolean Reject(const Bnd_Box2d& theBox2D) const;
Standard_EXPORT virtual Standard_Boolean Accept(const Standard_Integer& theIndex);
Standard_EXPORT void Clear();
Standard_EXPORT void SetBox(const Bnd_Box2d& theBox2D);
Standard_EXPORT void SetSkippedIndex(const Standard_Integer theIndex);
Standard_EXPORT const BRepMesh::Array1OfInteger& Indices() const;
Standard_EXPORT Standard_Integer IndicesNb() const;
protected:
Bnd_Box2d myBox2D;
Standard_Integer mySkippedIndex;
BRepMesh::Array1OfInteger myIndices;
Standard_Integer myIndicesNb;
};
private:
typedef NCollection_List<TopoDS_Edge> ListOfEdges;
typedef NCollection_Sequence<ListOfEdges> SeqOfWireEdges;
typedef NCollection_Sequence<gp_Pnt2d> SeqOfPnt2d;
typedef NCollection_Sequence<SeqOfPnt2d> SeqOfDWires;
public:
//! Constructor.
//! @param theFace Face to be checked.
//! @param theTolUV Tolerance to be used for calculations in parametric space.
//! @param theEdges Map of edges with associated polygon on triangulation.
//! @param theVertexMap Map of face vertices.
//! @param theStructure Discretized representation of face in parametric space.
//! @param theUmin Lower U boundary of the face in parametric space.
//! @param theUmax Upper U boundary of the face in parametric space.
//! @param theVmin Lower V boundary of the face in parametric space.
//! @param theVmax Upper V boundary of the face in parametric space.
Standard_EXPORT BRepMesh_WireChecker(
const TopoDS_Face& theFace,
const Standard_Real theTolUV,
const BRepMesh::HDMapOfShapePairOfPolygon& theEdges,
const BRepMesh::HIMapOfInteger& theVertexMap,
const Handle(BRepMesh_DataStructureOfDelaun)& theStructure,
const Standard_Real theUmin,
const Standard_Real theUmax,
const Standard_Real theVmin,
const Standard_Real theVmax,
const Standard_Boolean isInParallel);
//! Recompute data using parameters passed in constructor.
//! @param[out] theClassifier Classifier to be updated using calculated data.
Standard_EXPORT void ReCompute(BRepMesh::HClassifier& theClassifier);
//! Returns status of the check.
inline BRepMesh_Status Status() const
{
return myStatus;
}
private:
//! Collects discrete wires.
//! @param[out] theDWires sequence of discretized wires to be filled.
//! @return TRUE on success, FALSE in case of open wire.
Standard_Boolean collectDiscretizedWires(SeqOfDWires& theDWires);
//! Fills array of BiPoints for corresponding wire.
//! @param theDWires Sequence of wires to be processed.
//! @param theWiresSegmentsTree Array of segments with corresponding
//! bounding boxes trees to be filled.
void fillSegmentsTree(
const SeqOfDWires& theDWires,
BRepMesh::Array1OfSegmentsTree& theWiresSegmentsTree);
//! Assignment operator.
void operator =(BRepMesh_WireChecker& /*theOther*/)
{
}
private:
const Standard_Real myTolUV;
const BRepMesh::HDMapOfShapePairOfPolygon& myEdges;
const BRepMesh::HIMapOfInteger& myVertexMap;
const Handle(BRepMesh_DataStructureOfDelaun)& myStructure;
const Standard_Real myUmin;
const Standard_Real myUmax;
const Standard_Real myVmin;
const Standard_Real myVmax;
BRepMesh_Status myStatus;
SeqOfWireEdges myWiresEdges;
Standard_Boolean myIsInParallel;
};
#endif

View File

@@ -1,134 +0,0 @@
// Created on: 2014-06-18
// Created by: Oleg AGASHIN
// Copyright (c) 2011-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRepMesh_WireInterferenceChecker.hxx>
#include <BRepMesh_GeomTool.hxx>
#include <Precision.hxx>
// TODO: remove this variable after implementation of LoopChecker2d.
static const Standard_Real MIN_LOOP_S = 2 * M_PI * 2.E-5;
//=======================================================================
//function : Constructor
//purpose :
//=======================================================================
BRepMesh_WireInterferenceChecker::BRepMesh_WireInterferenceChecker(
const BRepMesh::Array1OfSegmentsTree& theWires,
BRepMesh_Status* theStatus,
Standard_Mutex* theMutex)
: myWires (theWires),
myStatus(theStatus),
myMutex (theMutex)
{
}
//=======================================================================
//function : Checker's body
//purpose :
//=======================================================================
void BRepMesh_WireInterferenceChecker::operator ()(
const Standard_Integer& theWireId) const
{
if (*myStatus == BRepMesh_SelfIntersectingWire)
return;
const BRepMesh::SegmentsTree& aWireSegTree1 = myWires(theWireId);
const BRepMesh::HArray1OfSegments& aWireSegments1 = aWireSegTree1.first;
const BRepMesh::HBndBox2dTree& aWireBoxTree1 = aWireSegTree1.second;
for (Standard_Integer aWireIt = theWireId; aWireIt <= myWires.Upper(); ++aWireIt)
{
// Break execution in case if flag was raised by another thread.
if (*myStatus == BRepMesh_SelfIntersectingWire)
return;
const Standard_Boolean isSelfIntCheck = (aWireIt == theWireId);
const BRepMesh::SegmentsTree& aWireSegTree2 =
isSelfIntCheck ? aWireSegTree1 : myWires(aWireIt);
const BRepMesh::HArray1OfSegments& aWireSegments2 = aWireSegTree2.first;
const BRepMesh::HBndBox2dTree& aWireBoxTree2 = aWireSegTree2.second;
BRepMesh_WireChecker::BndBox2dTreeSelector aSelector (aWireSegments2->Size());
Standard_Integer aSegmentId1 = aWireSegments1->Lower();
for (; aSegmentId1 <= aWireSegments1->Upper(); ++aSegmentId1)
{
// Break execution in case if flag was raised by another thread
if (*myStatus == BRepMesh_SelfIntersectingWire)
return;
aSelector.Clear();
aSelector.SetBox(aWireBoxTree1->FindNode(aSegmentId1).Bnd());
if (isSelfIntCheck)
aSelector.SetSkippedIndex(aSegmentId1);
if (aWireBoxTree2->Select(aSelector) == 0)
continue;
const BRepMesh::Segment& aSegment1 = aWireSegments1->Value(aSegmentId1);
const BRepMesh::Array1OfInteger& aSelected = aSelector.Indices();
const Standard_Integer aSelectedNb = aSelector.IndicesNb();
for (Standard_Integer aBndIt = 0; aBndIt < aSelectedNb; ++aBndIt)
{
// Break execution in case if flag was raised by another thread
if (*myStatus == BRepMesh_SelfIntersectingWire)
return;
const Standard_Integer aSegmentId2 = aSelected(aBndIt);
const BRepMesh::Segment& aSegment2 = aWireSegments2->Value(aSegmentId2);
gp_Pnt2d aIntPnt;
BRepMesh_GeomTool::IntFlag aIntStatus = BRepMesh_GeomTool::IntSegSeg(
aSegment1.StartPnt, aSegment1.EndPnt,
aSegment2.StartPnt, aSegment2.EndPnt,
Standard_False, Standard_False,
aIntPnt);
if (aIntStatus == BRepMesh_GeomTool::Cross)
{
// TODO: remove this block after implementation of LoopChecker2d.
if (isSelfIntCheck)
{
gp_XY aPrevVec;
Standard_Real aSumS = 0.;
const gp_XY& aRefPnt = aIntPnt.Coord();
for (Standard_Integer i = aSegmentId1; i < aSegmentId2; ++i)
{
const BRepMesh::Segment& aSeg = aWireSegments1->Value(i);
gp_XY aCurVec = aSeg.EndPnt - aRefPnt;
if (aCurVec.SquareModulus() < gp::Resolution())
continue;
if (aPrevVec.SquareModulus() > gp::Resolution())
aSumS += aPrevVec ^ aCurVec;
aPrevVec = aCurVec;
}
if (Abs(aSumS / 2.) < MIN_LOOP_S)
continue;
}
Standard_Mutex::Sentry aSentry(myMutex);
*myStatus = BRepMesh_SelfIntersectingWire;
return;
}
}
}
}
}

View File

@@ -1,67 +0,0 @@
// Created on: 2014-06-18
// Created by: Oleg AGASHIN
// Copyright (c) 2011-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// 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.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_WireInterferenceChecker_HeaderFile
#define _BRepMesh_WireInterferenceChecker_HeaderFile
#include <Standard.hxx>
#include <Standard_Mutex.hxx>
#include <BRepMesh_WireChecker.hxx>
#include <BRepMesh_Status.hxx>
//! Auxilary class implementing functionality for
//! checking interference between two discretized wires.
class BRepMesh_WireInterferenceChecker
{
public:
//! Enumerates states of segments intersection check.
enum IntFlag
{
NoIntersection,
Cross,
EndPointTouch,
PointOnSegment,
Glued,
Same
};
//! Constructor
//! @param theWires wires that should be checked.
//! @param theStatus shared flag to set status of the check.
//! @param theMutex shared mutex for parallel processing.
BRepMesh_WireInterferenceChecker(
const BRepMesh::Array1OfSegmentsTree& theWires,
BRepMesh_Status* theStatus,
Standard_Mutex* theMutex = NULL);
//! Checker's body.
//! @param theWireId Id of discretized wire to be checked.
void operator ()(const Standard_Integer& theWireId) const;
private:
//! Assignment operator.
void operator =(const BRepMesh_WireInterferenceChecker& /*theOther*/)
{
}
private:
const BRepMesh::Array1OfSegmentsTree& myWires;
BRepMesh_Status* myStatus;
Standard_Mutex* myMutex;
};
#endif

View File

@@ -82,17 +82,3 @@ BRepMesh_VertexInspector.hxx
BRepMesh_VertexTool.cxx
BRepMesh_VertexTool.hxx
BRepMesh_Triangle.hxx
BRepMesh.hxx
BRepMesh_EdgeParameterProvider.cxx
BRepMesh_EdgeTessellator.cxx
BRepMesh_EdgeTessellator.hxx
BRepMesh_FaceAttribute.cxx
BRepMesh_FaceAttribute.hxx
BRepMesh_FastDiscret.cxx
BRepMesh_FastDiscret.hxx
BRepMesh_FastDiscretFace.cxx
BRepMesh_FastDiscretFace.hxx
BRepMesh_IEdgeTool.cxx
BRepMesh_IEdgeTool.hxx
BRepMesh_PairOfPolygon.hxx
BRepMesh_Status.hxx