p TopOpeBRepDS
p TopOpeBRepTool
p TopTrans
-p XBRepMesh
+n XBRepMesh
t TKBO
t TKBool
t TKFeat
imported Circle from BRepMesh;
imported DiscretRoot from BRepMesh;
imported DiscretFactory from BRepMesh;
- --
- pointer PDiscretRoot to DiscretRoot from BRepMesh;
imported ShapeTool from BRepMesh;
imported Collections from BRepMesh;
imported WireInterferenceChecker from BRepMesh;
imported EdgeChecker from BRepMesh;
imported FaceChecker from BRepMesh;
+ imported EdgeParameterProvider from BRepMesh;
+ imported IEdgeTool from BRepMesh;
+ imported EdgeTessellationExtractor from BRepMesh;
+ imported EdgeTessellator from BRepMesh;
primitive PluginEntryType;
#include <BRepMesh_Circle.hxx>
#include <TopTools_ShapeMapHasher.hxx>
#include <Handle_Poly_Triangulation.hxx>
+#include <TopoDS_Face.hxx>
#include <vector>
class TopoDS_Face;
class TopoDS_Edge;
class TopoDS_Vertex;
-class BRepMesh_FaceAttribute;
class Handle_BRepMesh_FaceAttribute;
class BRepMesh_VertexInspector;
class BRepMesh_CircleInspector;
//! Handles
typedef N_HANDLE<MapOfInteger> HMapOfInteger;
+ typedef N_HANDLE<IMapOfInteger> HIMapOfInteger;
+ typedef N_HANDLE<DMapOfShapePairOfPolygon> HDMapOfShapePairOfPolygon;
+ typedef N_HANDLE<DMapOfIntegerPnt> HDMapOfIntegerPnt;
typedef N_HANDLE<BRepMesh_Classifier> HClassifier;
typedef N_HANDLE<BndBox2dTree> HBndBox2dTree;
typedef N_HANDLE<Array1OfSegments> HArray1OfSegments;
//function : BRepMesh_Delaun
//purpose : Creates the triangulation with an empty Mesh data structure
//=======================================================================
-BRepMesh_Delaun::BRepMesh_Delaun( BRepMeshCol::Array1OfVertexOfDelaun& theVertices,
- const Standard_Boolean isPositive )
-: myIsPositiveOrientation( isPositive ),
- myCircles( theVertices.Length(), new NCollection_IncAllocator() )
+BRepMesh_Delaun::BRepMesh_Delaun(
+ BRepMeshCol::Array1OfVertexOfDelaun& theVertices)
+: myCircles( theVertices.Length(), new NCollection_IncAllocator() )
{
if ( theVertices.Length() > 2 )
{
//function : BRepMesh_Delaun
//purpose : Creates the triangulation with and existent Mesh data structure
//=======================================================================
-BRepMesh_Delaun::BRepMesh_Delaun( const Handle( BRepMesh_DataStructureOfDelaun )& theOldMesh,
- BRepMeshCol::Array1OfVertexOfDelaun& theVertices,
- const Standard_Boolean isPositive )
- : myIsPositiveOrientation( isPositive ),
- myCircles( theVertices.Length(), theOldMesh->Allocator() )
+BRepMesh_Delaun::BRepMesh_Delaun(
+ const Handle( BRepMesh_DataStructureOfDelaun )& theOldMesh,
+ BRepMeshCol::Array1OfVertexOfDelaun& theVertices)
+ : myCircles( theVertices.Length(), theOldMesh->Allocator() )
{
myMeshData = theOldMesh;
if ( theVertices.Length() > 2 )
//function : BRepMesh_Delaun
//purpose : Creates the triangulation with and existent Mesh data structure
//=======================================================================
-BRepMesh_Delaun::BRepMesh_Delaun( const Handle( BRepMesh_DataStructureOfDelaun )& theOldMesh,
- BRepMeshCol::Array1OfInteger& theVertexIndices,
- const Standard_Boolean isPositive )
- : myIsPositiveOrientation( isPositive ),
- myCircles( theVertexIndices.Length(), theOldMesh->Allocator() )
+BRepMesh_Delaun::BRepMesh_Delaun(
+ const Handle( BRepMesh_DataStructureOfDelaun )& theOldMesh,
+ BRepMeshCol::Array1OfInteger& theVertexIndices)
+ : myCircles( theVertexIndices.Length(), theOldMesh->Allocator() )
{
myMeshData = theOldMesh;
if ( theVertexIndices.Length() > 2 )
mySupVert[2] = myMeshData->AddNode(
BRepMesh_Vertex( aMaxX + aDelta, aMinY - aDeltaMin, BRepMesh_Free ) );
- if ( !myIsPositiveOrientation )
- {
- Standard_Integer aTmp;
- aTmp = mySupVert[1];
- mySupVert[1] = mySupVert[2];
- mySupVert[2] = aTmp;
- }
-
Standard_Integer e[3];
Standard_Boolean o[3];
for (Standard_Integer aNodeId = 0; aNodeId < 3; ++aNodeId)
continue;
}
- Standard_Boolean isSensOK;
- if ( myIsPositiveOrientation )
- isSensOK = ( aDist12 > 0. && aDist23 > 0.);
- else
- isSensOK = ( aDist12 < 0. && aDist23 < 0.);
-
-
BRepMesh_Edge aFirstLink( aNodes[1], aNodes[0], BRepMesh_Free );
BRepMesh_Edge aLastLink ( aNodes[2], aNodes[1], BRepMesh_Free );
isPositive ? anEdgeId : -anEdgeId,
myMeshData->AddLink( aLastLink ) };
- if ( isSensOK )
+ Standard_Boolean isSensOK = (aDist12 > 0. && aDist23 > 0.);
+ if (isSensOK)
{
Standard_Integer anEdges[3];
Standard_Boolean anEdgesOri[3];
{
// Find the next link having the greatest angle
// respect to a direction of a reference one
- Standard_Real aMaxAngle = myIsPositiveOrientation ?
- RealFirst() : RealLast();
+ Standard_Real aMaxAngle = RealFirst();
Standard_Integer aNextLinkId = 0;
BRepMeshCol::ListOfInteger::Iterator aLinkIt( myMeshData->LinksConnectedTo( thePivotNode ) );
}
}
- if ( ( myIsPositiveOrientation && anAngle <= aMaxAngle ) ||
- (!myIsPositiveOrientation && anAngle >= aMaxAngle ) )
- {
+ if (anAngle <= aMaxAngle)
continue;
- }
Standard_Boolean isCheckEndPoints = ( anOtherNode != theFirstNode );
Standard_Real aDist = aRefEdgeDir ^ aDistanceDir;
Standard_Real aAngle = Abs( aRefEdgeDir.Angle(aDistanceDir) );
Standard_Real anAbsDist = Abs( aDist );
- if ( ( anAbsDist < Precision ) ||
- ( myIsPositiveOrientation && aDist < 0. ) ||
- (!myIsPositiveOrientation && aDist > 0. ) )
- {
+ if (anAbsDist < Precision || aDist < 0.)
continue;
- }
if ( ( anAbsDist >= aMinDist ) &&
( aAngle <= aOptAngle || aAngle > AngDeviation90Deg ) )
DEFINE_STANDARD_ALLOC
//! Creates the triangulation with an empty Mesh data structure.
- Standard_EXPORT BRepMesh_Delaun (BRepMeshCol::Array1OfVertexOfDelaun& theVertices,
- const Standard_Boolean isPositive = Standard_True);
+ Standard_EXPORT BRepMesh_Delaun (BRepMeshCol::Array1OfVertexOfDelaun& theVertices);
//! Creates the triangulation with an existent Mesh data structure.
Standard_EXPORT BRepMesh_Delaun (const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
- BRepMeshCol::Array1OfVertexOfDelaun& theVertices,
- const Standard_Boolean isPositive = Standard_True);
+ BRepMeshCol::Array1OfVertexOfDelaun& theVertices);
//! Creates the triangulation with an existant Mesh data structure.
Standard_EXPORT BRepMesh_Delaun (const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
- BRepMeshCol::Array1OfInteger& theVertexIndices,
- const Standard_Boolean isPositive = Standard_True);
+ BRepMeshCol::Array1OfInteger& theVertexIndices);
//! Initializes the triangulation with an array of vertices.
Standard_EXPORT void Init (BRepMeshCol::Array1OfVertexOfDelaun& theVertices);
private:
Handle(BRepMesh_DataStructureOfDelaun) myMeshData;
- Standard_Boolean myIsPositiveOrientation;
BRepMesh_CircleTool myCircles;
Standard_Integer mySupVert[3];
BRepMesh_Triangle mySupTrian;
#include <OSD_SharedLibrary.hxx>
#include <OSD_Function.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
-#include <BRepMesh_PDiscretRoot.hxx>
+#include <BRepMesh_DiscretRoot.hxx>
namespace
{
}
// try to create dummy tool
- BRepMesh_PDiscretRoot anInstancePtr = NULL;
+ BRepMesh_DiscretRoot* anInstancePtr = NULL;
Standard_Integer anErr = aFunc (TopoDS_Shape(), 0.001, 0.1, anInstancePtr);
if (anErr != 0 || anInstancePtr == NULL)
{
const Standard_Real theAngle)
{
Handle(BRepMesh_DiscretRoot) aDiscretRoot;
- BRepMesh_PDiscretRoot anInstancePtr = NULL;
+ BRepMesh_DiscretRoot* anInstancePtr = NULL;
if (myPluginEntry != NULL)
{
// use plugin
#include <Standard_Macro.hxx>
#include <BRepMesh_DegreeOfFreedom.hxx>
-//! Light weighted structure representing link of the mesh.
-class BRepMesh_Edge
+//! Light weighted structure representing simple link.
+class BRepMesh_OrientedEdge
{
public:
DEFINE_STANDARD_ALLOC
-
+
//! Default constructor.
- Standard_EXPORT BRepMesh_Edge()
- : myFirstNode (-1),
- myLastNode (-1),
- myMovability(BRepMesh_Deleted)
+ Standard_EXPORT BRepMesh_OrientedEdge()
+ : myFirstNode(-1),
+ myLastNode(-1)
{
}
- //! Contructs a link beetween two vertices.
- Standard_EXPORT BRepMesh_Edge(const Standard_Integer theFirstNode,
- const Standard_Integer theLastNode,
- const BRepMesh_DegreeOfFreedom theMovability)
- : myFirstNode (theFirstNode),
- myLastNode (theLastNode),
- myMovability(theMovability)
+ //! Constructs a link between two vertices.
+ Standard_EXPORT BRepMesh_OrientedEdge(
+ const Standard_Integer theFirstNode,
+ const Standard_Integer theLastNode)
+ : myFirstNode(theFirstNode),
+ myLastNode(theLastNode)
{
}
{
return myLastNode;
}
-
+
+ //! Returns hash code for this edge.
+ //! @param theUpper upper index in the container.
+ //! @return hash code.
+ Standard_EXPORT Standard_Integer HashCode(const Standard_Integer theUpper) const
+ {
+ return ::HashCode(myFirstNode + myLastNode, theUpper);
+ }
+
+ //! Checks this and other edge for equality.
+ //! @param theOther edge to be checked against this one.
+ //! @retrun TRUE if edges have the same orientation, FALSE if not.
+ inline Standard_Boolean IsEqual(const BRepMesh_OrientedEdge& theOther) const
+ {
+ return (myFirstNode == theOther.myFirstNode && myLastNode == theOther.myLastNode);
+ }
+
+ //! Alias for IsEqual.
+ Standard_Boolean operator ==(const BRepMesh_OrientedEdge& Other) const
+ {
+ return IsEqual(Other);
+ }
+
+private:
+
+ Standard_Integer myFirstNode;
+ Standard_Integer myLastNode;
+};
+
+//! Light weighted structure representing link of the mesh.
+class BRepMesh_Edge : public BRepMesh_OrientedEdge
+{
+public:
+
+ //! Default constructor.
+ Standard_EXPORT BRepMesh_Edge()
+ : BRepMesh_OrientedEdge(),
+ myMovability(BRepMesh_Deleted)
+ {
+ }
+
+ //! Constructs a link between two vertices.
+ Standard_EXPORT BRepMesh_Edge(
+ const Standard_Integer theFirstNode,
+ const Standard_Integer theLastNode,
+ const BRepMesh_DegreeOfFreedom theMovability)
+ : BRepMesh_OrientedEdge(theFirstNode, theLastNode),
+ myMovability(theMovability)
+ {
+ }
+
//! Returns movability flag of the Link.
inline BRepMesh_DegreeOfFreedom Movability() const
{
return myMovability;
}
-
+
//! Sets movability flag of the Link.
//! \param theMovability flag to be set.
inline void SetMovability(const BRepMesh_DegreeOfFreedom theMovability)
{
myMovability = theMovability;
}
-
- //! Returns hash code for this edge.
- //! \param theUpper upper index in the container.
- //! \return hash code.
- Standard_EXPORT Standard_Integer HashCode(const Standard_Integer theUpper) const
- {
- return ::HashCode(myFirstNode + myLastNode, theUpper);
- }
-
+
//! Checks if the given edge and this one have the same orientation.
//! \param theOther edge to be checked against this one.
//! \retrun TRUE if edges have the same orientation, FALSE if not.
inline Standard_Boolean IsSameOrientation(const BRepMesh_Edge& theOther) const
{
- return (myFirstNode == theOther.myFirstNode && myLastNode == theOther.myLastNode);
+ return BRepMesh_OrientedEdge::IsEqual(theOther);
}
-
+
//! Checks for equality with another edge.
//! \param theOther edge to be checked against this one.
//! \return TRUE if equal, FALSE if not.
inline Standard_Boolean IsEqual(const BRepMesh_Edge& theOther) const
{
- if (myMovability == BRepMesh_Deleted ||
- theOther.myMovability == BRepMesh_Deleted)
- {
+ if (myMovability == BRepMesh_Deleted || theOther.myMovability == BRepMesh_Deleted)
return Standard_False;
- }
- return IsSameOrientation(theOther) ||
- (myFirstNode == theOther.myLastNode && myLastNode == theOther.myFirstNode);
+ return IsSameOrientation(theOther) ||
+ (FirstNode() == theOther.LastNode() && LastNode() == theOther.FirstNode());
}
//! Alias for IsEqual.
private:
- Standard_Integer myFirstNode;
- Standard_Integer myLastNode;
BRepMesh_DegreeOfFreedom myMovability;
};
+inline Standard_Integer HashCode(const BRepMesh_OrientedEdge& theEdge,
+ const Standard_Integer theUpper)
+{
+ return theEdge.HashCode(theUpper);
+}
+
inline Standard_Integer HashCode(const BRepMesh_Edge& theEdge,
const Standard_Integer theUpper)
{
--- /dev/null
+// 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.)
+{
+ 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);
+ }
+
+ BRepAdaptor_Curve aCOnS(theEdge, theFace);
+ myProjector.Initialize(aCOnS, aCOnS.FirstParameter(),
+ aCOnS.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;
+}
--- /dev/null
+// 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_EdgeParameterProvider_HeaderFile
+#define _BRepMesh_EdgeParameterProvider_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Extrema_LocateExtPC.hxx>
+#include <Handle_TColStd_HArray1OfReal.hxx>
+
+class gp_Pnt;
+class TopoDS_Edge;
+class TopoDS_Face;
+class TColStd_HArray1OfReal;
+
+//! Auxiliary class provides correct parameters
+//! on curve regarding SameParameter flag.
+class BRepMesh_EdgeParameterProvider
+{
+public:
+
+ DEFINE_STANDARD_ALLOC
+
+ //! Constructor.
+ //! @param theEdge edge which parameters should be processed.
+ //! @param theFace face the parametric values are defined for.
+ //! @param theParameters parameters corresponded to discretization points.
+ BRepMesh_EdgeParameterProvider(
+ const TopoDS_Edge& theEdge,
+ const TopoDS_Face& theFace,
+ const Handle(TColStd_HArray1OfReal)& theParameters);
+
+ //! Returns parameter according to SameParameter flag of the edge.
+ //! If SameParameter is TRUE returns value from parameters w/o changes,
+ //! elsewhere scales initial parameter and tries to determine resulting
+ //! value using projection of the corresponded 3D point on PCurve.
+ Standard_Real Parameter(const Standard_Integer theIndex,
+ const gp_Pnt& thePoint3d);
+
+private:
+
+ Handle(TColStd_HArray1OfReal) myParameters;
+
+ Standard_Boolean myIsSameParam;
+ Standard_Real myFirstParam;
+
+ Standard_Real myOldFirstParam;
+ Standard_Real myScale;
+
+ Standard_Real myCurParam;
+ Standard_Real myFoundParam;
+
+ Extrema_LocateExtPC myProjector;
+};
+
+#endif
--- /dev/null
+// 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_EdgeTessellationExtractor.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Poly_PolygonOnTriangulation.hxx>
+#include <Poly_Triangulation.hxx>
+#include <BRepMesh_ShapeTool.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (BRepMesh_EdgeTessellationExtractor, BRepMesh_IEdgeTool)
+IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_EdgeTessellationExtractor, BRepMesh_IEdgeTool)
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+BRepMesh_EdgeTessellationExtractor::BRepMesh_EdgeTessellationExtractor(
+ const TopoDS_Edge& theEdge,
+ const Handle(Geom2d_Curve)& thePCurve,
+ const TopoDS_Face& theFace,
+ const Handle(Poly_Triangulation)& theTriangulation,
+ const Handle(Poly_PolygonOnTriangulation)& thePolygon,
+ const TopLoc_Location& theLocation)
+ : myProvider(theEdge, theFace, thePolygon->Parameters()),
+ myPCurve(thePCurve),
+ myNodes(theTriangulation->Nodes()),
+ myIndices(thePolygon->Nodes()),
+ myLoc(theLocation)
+{
+}
+
+//=======================================================================
+//function : Value
+//purpose :
+//=======================================================================
+void BRepMesh_EdgeTessellationExtractor::Value(
+ const Standard_Integer theIndex,
+ Standard_Real& theParameter,
+ gp_Pnt& thePoint,
+ gp_Pnt2d& theUV)
+{
+ const gp_Pnt& theRefPnt = myNodes(myIndices(theIndex));
+ thePoint = BRepMesh_ShapeTool::UseLocation(theRefPnt, myLoc);
+
+ theParameter = myProvider.Parameter(theIndex, thePoint);
+ theUV = myPCurve->Value(theParameter);
+}
--- /dev/null
+// 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_EdgeTessellationExtractor_HeaderFile
+#define _BRepMesh_EdgeTessellationExtractor_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <BRepMesh_IEdgeTool.hxx>
+#include <BRepMesh_EdgeParameterProvider.hxx>
+#include <Handle_Geom2d_Curve.hxx>
+#include <Handle_Poly_PolygonOnTriangulation.hxx>
+#include <Handle_Poly_Triangulation.hxx>
+#include <TopLoc_Location.hxx>
+#include <TColgp_Array1OfPnt.hxx>
+#include <TColStd_Array1OfInteger.hxx>
+
+class Poly_Triangulation;
+class Poly_PolygonOnTriangulation;
+class TopoDS_Edge;
+class TopoDS_Face;
+
+//! Auxiliary class implements functionality retrieving tessellated
+//! representation of an edge stored in polygon.
+class BRepMesh_EdgeTessellationExtractor : public BRepMesh_IEdgeTool
+{
+public:
+
+ //! Constructor.
+ //! Initializes extractor.
+ BRepMesh_EdgeTessellationExtractor(
+ const TopoDS_Edge& theEdge,
+ const Handle(Geom2d_Curve)& thePCurve,
+ const TopoDS_Face& theFace,
+ const Handle(Poly_Triangulation)& theTriangulation,
+ const Handle(Poly_PolygonOnTriangulation)& thePolygon,
+ const TopLoc_Location& theLocation);
+
+ //! Returns number of dicretization points.
+ virtual Standard_Integer NbPoints() const
+ {
+ return myIndices.Length();
+ }
+
+ //! 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.
+ virtual void Value(const Standard_Integer theIndex,
+ Standard_Real& theParameter,
+ gp_Pnt& thePoint,
+ gp_Pnt2d& theUV);
+
+ DEFINE_STANDARD_RTTI(BRepMesh_EdgeTessellationExtractor)
+
+private:
+
+ //! Assignment operator.
+ void operator =(const BRepMesh_EdgeTessellationExtractor& /*theOther*/)
+ {
+ }
+
+private:
+
+ BRepMesh_EdgeParameterProvider myProvider;
+ const Handle(Geom2d_Curve)& myPCurve;
+ const TColgp_Array1OfPnt& myNodes;
+ const TColStd_Array1OfInteger& myIndices;
+ const TopLoc_Location myLoc;
+};
+
+DEFINE_STANDARD_HANDLE(BRepMesh_EdgeTessellationExtractor, BRepMesh_IEdgeTool)
+
+#endif
--- /dev/null
+// 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 <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_HANDLE (BRepMesh_EdgeTessellator, BRepMesh_IEdgeTool)
+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)
+ : 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;
+
+ Standard_Boolean isSameParam = BRep_Tool::SameParameter(theEdge);
+ if (isSameParam)
+ myCOnS.Initialize(theEdge);
+ else
+ myCOnS.Initialize(theEdge, theFaceAttribute->Face());
+
+ TopLoc_Location aLoc;
+ const GeomAbs_CurveType aCurveType = myCOnS.GetType();
+ Standard_Integer aMinPntNb = (aCurveType == GeomAbs_Circle) ? 4 : 2; //OCC287
+
+ // Get range on 2d curve
+ Standard_Real aFirstParam, aLastParam;
+ BRep_Tool::Range(theEdge, theFaceAttribute->Face(), aFirstParam, aLastParam);
+ myTool = new BRepMesh_GeomTool(myCOnS, aFirstParam, aLastParam,
+ aPreciseLinDef, aPreciseAngDef, aMinPntNb);
+
+ if (aCurveType == GeomAbs_BSplineCurve)
+ {
+ // TODO: remove this code block when #24959 is fixed
+ const Standard_Integer aNbInt = myCOnS.NbIntervals(GeomAbs_C1);
+ if ( aNbInt > 0 )
+ {
+ 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);
+
+ 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, mySurface, aParam, aPoint3d, 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())
+ {
+ TopLoc_Location aLoc;
+ const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Value());
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
+
+ if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
+ continue;
+
+ Standard_Real aF, aL;
+ Handle(Geom2d_Curve) aCurve2d = BRep_Tool::CurveOnSurface(theEdge, aFace, aF, aL);
+ if ( Abs(aF - aFirstParam) > Precision::PConfusion() ||
+ Abs(aL - aLastParam ) > Precision::PConfusion() )
+ {
+ continue;
+ }
+
+ aNodesNb = myTool->NbPoints();
+ TColStd_Array1OfReal aParamArray(1, aNodesNb);
+ for (Standard_Integer i = 1; i <= aNodesNb; ++i)
+ {
+ gp_Pnt2d aTmpUV;
+ gp_Pnt aTmpPnt;
+ Standard_Real aParam;
+ myTool->Value(i, mySurface, aParam, aTmpPnt, aTmpUV);
+ aParamArray.SetValue(i, aParam);
+ }
+
+ for (Standard_Integer i = 1; i < aNodesNb; ++i)
+ splitSegment(aSurf, aCurve2d, aParamArray(i), aParamArray(i + 1), 1);
+ }
+ }
+}
+
+//=======================================================================
+//function : Value
+//purpose :
+//=======================================================================
+void BRepMesh_EdgeTessellator::Value(const Standard_Integer theIndex,
+ Standard_Real& theParameter,
+ gp_Pnt& thePoint,
+ gp_Pnt2d& theUV)
+{
+ myTool->Value(theIndex, mySurface, theParameter, thePoint, theUV);
+}
+
+//=======================================================================
+//function : splitSegment
+//purpose :
+//=======================================================================
+void BRepMesh_EdgeTessellator::splitSegment(
+ const Handle(Geom_Surface)& theSurf,
+ const Handle(Geom2d_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) < mySquareEdgeDef)
+ return;
+
+ uvm = gp_Pnt2d((uvf.XY() + uvl.XY())*0.5);
+ midP3dFromSurf = theSurf->Value(uvm.X(), uvm.Y());
+
+ gp_XYZ aVec = P3dL.XYZ() - P3dF.XYZ();
+ aVec.Normalize();
+
+ gp_XYZ Vec1 = midP3dFromSurf.XYZ() - P3dF.XYZ();
+ 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);
+}
--- /dev/null
+// 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_Collections.hxx>
+#include <BRepMesh_IEdgeTool.hxx>
+#include <BRepMesh_GeomTool.hxx>
+#include <BRepMesh_FaceAttribute.hxx>
+#include <Handle_Geom_Surface.hxx>
+#include <Handle_Geom2d_Curve.hxx>
+#include <Handle_BRepAdaptor_HSurface.hxx>
+#include <BRepAdaptor_Curve.hxx>
+
+class Geom_Surface;
+class Geom2d_Curve;
+class TopoDS_Edge;
+class BRepAdaptor_HSurface;
+class TopTools_IndexedDataMapOfShapeListOfShape;
+
+//! 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);
+
+ //! Returns number of dicretization points.
+ virtual Standard_Integer NbPoints() const
+ {
+ 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.
+ virtual void Value(const Standard_Integer theIndex,
+ Standard_Real& theParameter,
+ gp_Pnt& thePoint,
+ gp_Pnt2d& theUV);
+
+ DEFINE_STANDARD_RTTI(BRepMesh_EdgeTessellator)
+
+private:
+
+ //!
+ void splitSegment(const Handle(Geom_Surface)& theSurf,
+ const Handle(Geom2d_Curve)& theCurve2d,
+ const Standard_Real theFirst,
+ const Standard_Real theLast,
+ const Standard_Integer theNbIter);
+
+private:
+ N_HANDLE<BRepMesh_GeomTool> myTool;
+ Handle(BRepAdaptor_HSurface) mySurface;
+ BRepAdaptor_Curve myCOnS;
+ Standard_Real mySquareEdgeDef;
+};
+
+DEFINE_STANDARD_HANDLE(BRepMesh_EdgeTessellator, BRepMesh_IEdgeTool)
+
+#endif
// 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>
IMPLEMENT_STANDARD_HANDLE (BRepMesh_FaceAttribute, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FaceAttribute, Standard_Transient)
//=======================================================================
-//function : BRepMesh_FaceAttribute
+//function : Constructor
//purpose :
//=======================================================================
-BRepMesh_FaceAttribute::BRepMesh_FaceAttribute():
- mydefface(0.), myumin(0.), myumax(0.), myvmin(0.), myvmax(0.),
- mydeltaX(1.), mydeltaY(1.), myminX(0.), myminY(0.)
+BRepMesh_FaceAttribute::BRepMesh_FaceAttribute(
+ const TopoDS_Face& theFace,
+ BRepMeshCol::DMapOfVertexInteger& theBoundaryVertices,
+ BRepMeshCol::DMapOfIntegerPnt& theBoundaryPoints)
+ : myDefFace (0.),
+ myUMin (0.),
+ myUMax (0.),
+ myVMin (0.),
+ myVMax (0.),
+ myDeltaX (1.),
+ myDeltaY (1.),
+ myStatus (BRepMesh_NoError),
+ myBoundaryVertices(theBoundaryVertices),
+ myBoundaryPoints (theBoundaryPoints),
+ myAllocator (new NCollection_IncAllocator(64000))
{
+ myVertexEdgeMap = new BRepMeshCol::IMapOfInteger;
+ myInternalEdges = new BRepMeshCol::DMapOfShapePairOfPolygon;
+ mySurfacePoints = new BRepMeshCol::DMapOfIntegerPnt;
+ myClassifier = new BRepMesh_Classifier;
+
+ myFace = theFace;
+ BRepTools::Update(myFace);
+ myFace.Orientation(TopAbs_FORWARD);
+
+ BRepAdaptor_Surface aSurfAdaptor(myFace, Standard_False);
+ mySurface = new BRepAdaptor_HSurface(aSurfAdaptor);
+
+ ResetStructure();
+}
+
+//=======================================================================
+//function : Destructor
+//purpose :
+//=======================================================================
+BRepMesh_FaceAttribute::~BRepMesh_FaceAttribute()
+{
+ clearLocal();
+
+ mySurfaceVertices.Clear();
+ mySurfacePoints->Clear();
+
+ myClassifier.Nullify();
+ myAllocator.Nullify();
+}
+
+//=======================================================================
+//function : clearLocal
+//purpose :
+//=======================================================================
+void BRepMesh_FaceAttribute::clearLocal()
+{
+ myStructure.Nullify();
+
+ myLocation2D.Clear();
+ myVertexEdgeMap->Clear();
+ myInternalEdges->Clear();
+
+ myAllocator->Reset(Standard_False);
+}
+
+//=======================================================================
+//function : ResetStructure
+//purpose :
+//=======================================================================
+Handle(BRepMesh_DataStructureOfDelaun)& BRepMesh_FaceAttribute::ResetStructure()
+{
+ clearLocal();
+ myStructure = new BRepMesh_DataStructureOfDelaun(myAllocator);
+
+ BRepTools::UVBounds(myFace, myUMin, myUMax, myVMin, myVMax);
+ Standard_Real aTolU = ToleranceU();
+ Standard_Real aTolV = ToleranceV();
+
+ myStructure->Data().SetCellSize(14.0 * aTolU, 14.0 * aTolV);
+ myStructure->Data().SetTolerance(aTolU, aTolV);
+ return myStructure;
+}
+
+//=======================================================================
+//function : computeParametricTolerance
+//purpose :
+//=======================================================================
+Standard_Real BRepMesh_FaceAttribute::computeParametricTolerance(
+ const Standard_Real theFirstParam,
+ const Standard_Real theLastParam) const
+{
+ const Standard_Real aDeflectionUV = 1.e-05;
+ return Max(Precision::PConfusion(), (theLastParam - theFirstParam) * aDeflectionUV);
+}
+
+//=======================================================================
+//function : getVertexIndex
+//purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_FaceAttribute::getVertexIndex(
+ const TopoDS_Vertex& theVertex,
+ Standard_Integer& theVertexIndex) const
+{
+ if (myBoundaryVertices.IsBound(theVertex))
+ theVertexIndex = myBoundaryVertices.Find(theVertex);
+ else if (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);
}
#define _BRepMesh_FaceAttribute_HeaderFile
#include <Standard.hxx>
+#include <Standard_Transient.hxx>
#include <Standard_DefineHandle.hxx>
+
+#include <BRepMesh_Status.hxx>
#include <BRepMesh_Collections.hxx>
-#include <Standard_Transient.hxx>
+#include <BRepMesh_DataStructureOfDelaun.hxx>
+#include <Handle_BRepAdaptor_HSurface.hxx>
+class BRepAdaptor_HSurface;
-//! auxiliary class for FastDiscret and FastDiscretFace classes <br>
+//! Auxiliary class for FastDiscret and FastDiscretFace classes.
class BRepMesh_FaceAttribute : public Standard_Transient
{
public:
- Standard_EXPORT BRepMesh_FaceAttribute();
-
- inline Standard_Real& GetDefFace()
+ //! 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.
+ Standard_EXPORT BRepMesh_FaceAttribute(
+ const TopoDS_Face& theFace,
+ BRepMeshCol::DMapOfVertexInteger& theBoundaryVertices,
+ BRepMeshCol::DMapOfIntegerPnt& theBoundaryPoints);
+
+ //! Destructor.
+ virtual ~BRepMesh_FaceAttribute();
+
+public: //! @name main geometrical properties.
+
+ //! Returns face's surface.
+ inline const Handle(BRepAdaptor_HSurface)& Surface() const
+ {
+ return mySurface;
+ }
+
+ //! Returns forward oriented face to be used for calculations.
+ inline const TopoDS_Face& Face() const
+ {
+ return myFace;
+ }
+
+ //! Returns U tolerance of face calculated regarding its parameters.
+ inline Standard_Real ToleranceU() const
+ {
+ return computeParametricTolerance(myUMin, myUMax);
+ }
+
+ //! Returns V tolerance of face calculated regarding its parameters.
+ inline Standard_Real ToleranceV() const
+ {
+ return computeParametricTolerance(myVMin, myVMax);
+ }
+
+ //! 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 mydefface;
+ return myVMax;
}
- inline Standard_Real& GetUMin()
+ //! Sets maximal value in V domain.
+ inline void SetVMax(const Standard_Real theVMax)
{
- return myumin;
+ myVMax = theVMax;
}
- inline Standard_Real& GetVMin()
+ //! Gives value of step in U domain.
+ inline Standard_Real GetDeltaX() const
{
- return myvmin;
+ return myDeltaX;
}
- inline Standard_Real& GetUMax()
+ //! Sets value of step in U domain.
+ inline void SetDeltaX(const Standard_Real theDeltaX)
{
- return myumax;
+ myDeltaX = theDeltaX;
}
- inline Standard_Real& GetVMax()
+ //! Gives value of step in V domain.
+ inline Standard_Real GetDeltaY() const
{
- return myvmax;
+ return myDeltaY;
}
- inline Standard_Real& GetDeltaX()
+ //! Sets value of step in V domain.
+ inline void SetDeltaY(const Standard_Real theDeltaY)
{
- return mydeltaX;
+ myDeltaY = theDeltaY;
}
- inline Standard_Real& GetDeltaY()
+ //! Sets set of status flags for this face.
+ inline Standard_Integer GetStatus() const
{
- return mydeltaY;
+ return myStatus;
}
- inline Standard_Real& GetMinX()
+ //! Sets status flag for this face.
+ inline void SetStatus(const BRepMesh_Status theStatus)
{
- return myminX;
+ myStatus |= theStatus;
}
- inline Standard_Real& GetMinY()
+ //! Returns TRUE in case if computed data is valid.
+ inline Standard_Boolean IsValid() const
{
- return myminY;
+ return (myStatus == BRepMesh_NoError || myStatus == BRepMesh_ReMesh);
}
- inline BRepMeshCol::HClassifier& GetClassifier()
+public: //! @name auxiliary structures
+
+ //! Clear all face attribute.
+ Standard_EXPORT void Clear();
+
+ //! Resets mesh data structure.
+ //! @returns reset data structure.
+ Standard_EXPORT Handle(BRepMesh_DataStructureOfDelaun)& ResetStructure();
+
+ //! Gives reference to map of internal edges of face.
+ inline BRepMeshCol::HDMapOfShapePairOfPolygon& ChangeInternalEdges()
{
- return myclassifier;
+ return myInternalEdges;
}
+ //! Gives reference to map of 2D points of discretization.
+ inline BRepMeshCol::DMapOfIntegerListOfXY& ChangeLocation2D()
+ {
+ return myLocation2D;
+ }
+
+ //! Gives reference to map of 3D points of discretization.
+ inline BRepMeshCol::HDMapOfIntegerPnt& ChangeSurfacePoints()
+ {
+ return mySurfacePoints;
+ }
+
+ //! Gives reference on map of (vertex, edge) pairs of face.
+ inline BRepMeshCol::HIMapOfInteger& ChangeVertexEdgeMap()
+ {
+ return myVertexEdgeMap;
+ }
+
+ //! Gives Delaunay data structure.
+ inline Handle(BRepMesh_DataStructureOfDelaun)& ChangeStructure()
+ {
+ return myStructure;
+ }
+
+ //! Returns classifier.
+ inline BRepMeshCol::HClassifier& ChangeClassifier()
+ {
+ return myClassifier;
+ }
+
+public: //! @name Point/Vertex/Node manipulators
+
+ //! Gives the number of different locations in 3D space.
+ inline Standard_Integer LastPointId() const
+ {
+ return myBoundaryPoints.Extent() + 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 (theIndex > myBoundaryPoints.Extent())
+ return mySurfacePoints->Find(theIndex);
+
+ return myBoundaryPoints(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;
+
+ BRepMeshCol::DMapOfIntegerPnt& aPointsMap = isFillEdgeVertices ?
+ myBoundaryPoints : *mySurfacePoints;
+
+ aPointsMap.Bind(aNewVertexIndex, theVertexExplorer->Point());
+ }
+
+ BRepMeshCol::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_RTTI(BRepMesh_FaceAttribute)
-private:
-
- Standard_Real mydefface;
- Standard_Real myumin;
- Standard_Real myumax;
- Standard_Real myvmin;
- Standard_Real myvmax;
- Standard_Real mydeltaX;
- Standard_Real mydeltaY;
- Standard_Real myminX;
- Standard_Real myminY;
- BRepMeshCol::HClassifier myclassifier;
+private:
+
+ //! Assignment operator.
+ void operator =(const BRepMesh_FaceAttribute& /*theOther*/)
+ {
+ }
+
+ //! 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();
+
+ //! 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_Integer myStatus;
+
+ BRepMeshCol::DMapOfVertexInteger& myBoundaryVertices;
+ BRepMeshCol::DMapOfIntegerPnt& myBoundaryPoints;
+
+ TopoDS_Face myFace;
+ Handle(BRepAdaptor_HSurface) mySurface;
+ BRepMeshCol::DMapOfVertexInteger mySurfaceVertices;
+ BRepMeshCol::HDMapOfIntegerPnt mySurfacePoints;
+
+ BRepMeshCol::DMapOfIntegerListOfXY myLocation2D;
+ BRepMeshCol::HIMapOfInteger myVertexEdgeMap;
+ BRepMeshCol::HDMapOfShapePairOfPolygon myInternalEdges;
+
+ Handle(BRepMesh_DataStructureOfDelaun) myStructure;
+ BRepMeshCol::HClassifier myClassifier;
+ BRepMeshCol::Allocator myAllocator;
};
DEFINE_STANDARD_HANDLE(BRepMesh_FaceAttribute, Standard_Transient)
#include <BRepMesh_GeomTool.hxx>
#include <BRepMesh_PairOfPolygon.hxx>
#include <BRepMesh_Classifier.hxx>
-#include <BRepMesh_ShapeTool.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 <BRepTools.hxx>
#include <BRepBndLib.hxx>
#include <BndLib_Add3dCurve.hxx>
-#include <BRep_Tool.hxx>
#include <Poly_Triangulation.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_HArray1OfReal.hxx>
-#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColGeom2d_SequenceOfCurve.hxx>
#include <SortTools_ShellSortOfReal.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopAbs.hxx>
#include <TopoDS.hxx>
//function : BRepMesh_FastDiscret
//purpose :
//=======================================================================
-BRepMesh_FastDiscret::BRepMesh_FastDiscret(const Standard_Real theDefle,
- const Standard_Real theAngl,
- const Bnd_Box& theBox,
- const Standard_Boolean theWithShare,
- const Standard_Boolean theInshape,
- const Standard_Boolean theRelative,
- const Standard_Boolean theShapetrigu,
- const Standard_Boolean isInParallel)
+BRepMesh_FastDiscret::BRepMesh_FastDiscret(
+ const Standard_Real theDefle,
+ const Standard_Real theAngl,
+ const Bnd_Box& theBox,
+ const Standard_Boolean theWithShare,
+ const Standard_Boolean theInshape,
+ const Standard_Boolean theRelative,
+ const Standard_Boolean theShapetrigu,
+ const Standard_Boolean isInParallel)
: myAngle (theAngl),
myDeflection (theDefle),
myWithShare (theWithShare),
myInParallel (isInParallel),
- myNbLocat (0),
myRelative (theRelative),
myShapetrigu (theShapetrigu),
myInshape (theInshape)
{
- myAllocator = new NCollection_IncAllocator(64000);
- if(myRelative)
+ if ( myRelative )
BRepMesh_ShapeTool::BoxMaxDimension(theBox, myDtotale);
}
//function : BRepMesh_FastDiscret
//purpose :
//=======================================================================
-
BRepMesh_FastDiscret::BRepMesh_FastDiscret(const TopoDS_Shape& theShape,
const Standard_Real theDefle,
const Standard_Real theAngl,
myDeflection (theDefle),
myWithShare (theWithShare),
myInParallel (isInParallel),
- myNbLocat (0),
myRelative (theRelative),
myShapetrigu (theShapetrigu),
myInshape (theInshape)
{
- myAllocator = new NCollection_IncAllocator(64000);
- if(myRelative)
+ if ( myRelative )
BRepMesh_ShapeTool::BoxMaxDimension(theBox, myDtotale);
- Perform(theShape);
-}
-//=======================================================================
-//function : SetParallel
-//purpose :
-//=======================================================================
-void BRepMesh_FastDiscret::SetParallel (const Standard_Boolean theInParallel)
-{
- myInParallel = theInParallel;
+ Perform(theShape);
}
//=======================================================================
-//function : IsParallel
-//purpose :
+//function : InitSharedFaces
+//purpose :
//=======================================================================
-Standard_Boolean BRepMesh_FastDiscret::IsParallel() const
+void BRepMesh_FastDiscret::InitSharedFaces(const TopoDS_Shape& theShape)
{
- return myInParallel;
+ TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, mySharedFaces);
}
//=======================================================================
//function : Perform(shape)
//purpose :
//=======================================================================
-
void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
{
- TopTools_IndexedDataMapOfShapeListOfShape anAncestors;
- TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, anAncestors);
+ InitSharedFaces(theShape);
+
std::vector<TopoDS_Face> aFaces;
- for (TopExp_Explorer ex(theShape, TopAbs_FACE); ex.More(); ex.Next()) {
- TopoDS_Face aF = TopoDS::Face(ex.Current());
- Add(aF, anAncestors);
- aFaces.push_back(aF);
+ 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);
}
#ifdef HAVE_TBB
- if (myInParallel)
+ if ( myInParallel )
{
- CreateMutexesForSubShapes(theShape, TopAbs_EDGE);
- // mesh faces in parallel threads using TBB
- tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *this);
- RemoveAllMutexes();
+ tbb::parallel_for_each(aFaces.begin(), aFaces.end(), *this);
}
else
{
#endif
- for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
- Process (*it);
+ std::vector<TopoDS_Face>::const_iterator anIt(aFaces.begin());
+ for (; anIt != aFaces.end(); anIt++)
+ Process(*anIt);
#ifdef HAVE_TBB
}
#endif
//function : Process
//purpose :
//=======================================================================
-
void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
{
- //cout << "START face " << theFace.TShape().operator->() << endl << flush;
- Handle(BRepMesh_FaceAttribute) fattribute;
- if ( GetFaceAttribute (theFace, fattribute) )
+ Handle(BRepMesh_FaceAttribute) anAttribute;
+ if (GetFaceAttribute(theFace, anAttribute))
{
- BRepMesh_FastDiscretFace aTool (GetAngle(), WithShare());
- aTool.Add (theFace, fattribute, GetMapOfDefEdge(), myMutexProvider);
+ try
+ {
+ OCC_CATCH_SIGNALS
+
+ BRepMesh_FastDiscretFace aTool(GetAngle(), WithShare());
+ aTool.Add(anAttribute);
+ }
+ catch (Standard_Failure)
+ {
+ anAttribute->SetStatus(BRepMesh_Failure);
+ }
}
- //cout << "END face " << theFace.TShape().operator->() << endl << flush;
}
//=======================================================================
//function : Add(face)
//purpose :
//=======================================================================
-
-#define MESH_FAILURE(theface) \
-{ \
- myFacestate = BRepMesh_Failure; \
- myNottriangulated.Append(theface); \
- return; \
-}
-
-void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface,
- const TopTools_IndexedDataMapOfShapeListOfShape& theAncestors)
+Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
{
-#ifndef DEB_MESH
try
{
OCC_CATCH_SIGNALS
-#endif
- TopoDS_Face face = theface;
- BRepTools::Update(face);
- face.Orientation(TopAbs_FORWARD);
- myStructure.Nullify();
- Handle(NCollection_IncAllocator) anAlloc = Handle(NCollection_IncAllocator)::DownCast(myAllocator);
- anAlloc->Reset(Standard_False);
- myStructure=new BRepMesh_DataStructureOfDelaun(anAlloc);
-
- Standard_Real aUmin, aVmin, aUmax, aVmax;
- BRepTools::UVBounds (theface, aUmin, aUmax, aVmin, aVmax);
- Standard_Real aTolU = Max( Precision::PConfusion(), (aUmax - aUmin) * UVDEFLECTION );
- Standard_Real aTolV = Max( Precision::PConfusion(), (aVmax - aVmin) * UVDEFLECTION );
- myStructure->Data().SetCellSize ( 14 * aTolU, 14 * aTolV );
- myStructure->Data().SetTolerance( aTolU, aTolV );
-
- BRepAdaptor_Surface BS(face, Standard_False);
- Handle(BRepAdaptor_HSurface) gFace = new BRepAdaptor_HSurface(BS);
-
- GeomAbs_SurfaceType thetype;
- thetype = BS.GetType();
-
- gp_Pnt2d uvFirst, uvLast;
-
- Handle(Poly_Triangulation) T;
- TopLoc_Location loc;
-
- if (!myWithShare) {
- myVertices.Clear();
- myEdges.Clear();
- }
- myVemap.Clear();
- myLocation2d.Clear();
- myInternaledges.Clear();
+ // Initialize face attributes
+ myAttribute.Nullify();
+ GetFaceAttribute(theFace, myAttribute);
+ if (myAttribute.IsNull())
+ {
+ myAttribute = new BRepMesh_FaceAttribute(theFace,
+ myBoundaryVertices, myBoundaryPoints);
- Standard_Integer i;
- i = 1;
+ myAttributes.Bind(theFace, myAttribute);
+ }
- Standard_Real defedge, defface;
- Standard_Integer nbEdge = 0;
- Standard_Real savangle = myAngle;
- Standard_Real cdef;
- Standard_Real maxdef = 2.* BRepMesh_ShapeTool::MaxFaceTolerance(theface);
- defface = 0.;
+ myStructure = myAttribute->ResetStructure();
+ myVertexEdgeMap = myAttribute->ChangeVertexEdgeMap();
+ myInternalEdges = myAttribute->ChangeInternalEdges();
- if (!myRelative) defface = Max(myDeflection, maxdef);
+ if (!myWithShare)
+ {
+ myEdges.Clear();
+ myBoundaryVertices.Clear();
+ myBoundaryPoints.Clear();
+ }
- BRepMeshCol::SequenceOfReal aFSeq, aLSeq;
- TColGeom2d_SequenceOfCurve aCSeq;
- TopTools_SequenceOfShape aShSeq;
+ Standard_Real defedge;
+ Standard_Integer nbEdge = 0;
+ Standard_Real savangle = myAngle;
+ Standard_Real cdef;
+ Standard_Real maxdef = 2.* BRepMesh_ShapeTool::MaxFaceTolerance(theFace);
- TopoDS_Iterator exW(face);
+ Standard_Real defface = 0.;
+ if (!myRelative)
+ defface = Max(myDeflection, maxdef);
- for (; exW.More(); exW.Next()) {
- const TopoDS_Shape& aWire = exW.Value();
- if (aWire.ShapeType() != TopAbs_WIRE)
- continue;
- TopoDS_Iterator ex(aWire);
- for(; ex.More(); ex.Next()) {
- const TopoDS_Edge& edge = TopoDS::Edge(ex.Value());
- nbEdge++;
- if (!myMapdefle.IsBound(edge)) {
- if (myRelative) {
- if (myEdges.IsBound(edge)) {
- const BRepMesh_PairOfPolygon& pair = myEdges.Find(edge);
- const Handle(Poly_PolygonOnTriangulation)& P = pair.First();
- defedge = P->Deflection();
+ N_SEQUENCE<EdgePCurve> aPCurves;
+ N_SEQUENCE<TopoDS_Edge> aFaceEdges;
+
+ const TopoDS_Face& aFace = myAttribute->Face();
+ const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
+ TopExp_Explorer aWireIt(aFace, TopAbs_WIRE);
+ for (; aWireIt.More(); aWireIt.Next())
+ {
+ TopExp_Explorer aEdgeIt(aWireIt.Current(), TopAbs_EDGE);
+ for (; aEdgeIt.More(); aEdgeIt.Next(), ++nbEdge)
+ {
+ const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
+ if (!myMapdefle.IsBound(aEdge))
+ {
+ if (myRelative)
+ {
+ 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, myDeflection, myDtotale, cdef);
+
+ myAngle = savangle * cdef;
+ }
+
+ defface += defedge;
+ defface = Max(maxdef, defface);
+ }
+ else
+ {
+ defedge = myDeflection;
}
- else {
- defedge = BRepMesh_ShapeTool::RelativeEdgeDeflection(edge,
- myDeflection, myDtotale, cdef);
- myAngle = savangle * cdef;
+ defedge = Max(maxdef, defedge);
+ defedge = Max(UVDEFLECTION, defedge);
+ myMapdefle.Bind(aEdge, defedge);
+ }
+ else
+ {
+ defedge = myMapdefle(aEdge);
+ if ( myRelative )
+ {
+ defface += defedge;
+ defface = Max(maxdef, defface);
}
- defface = defface + defedge;
- defface = Max(maxdef, defface);
}
- else defedge = myDeflection;
-
- defedge = Max(maxdef, defedge);
- defedge = Max(UVDEFLECTION , defedge);
- myMapdefle.Bind(edge, defedge);
- }
- else{
- defedge = myMapdefle(edge);
- if (myRelative) {defface = defface + defedge; defface = Max(maxdef, defface);}
+
+ Standard_Real aFirstParam, aLastParam;
+ Handle(Geom2d_Curve) aCurve2d =
+ BRep_Tool::CurveOnSurface(aEdge, aFace, aFirstParam, aLastParam);
+
+ if (aCurve2d.IsNull())
+ continue;
+
+ EdgePCurve aPCurve = { aCurve2d, aFirstParam, aLastParam };
+ aPCurves.Append(aPCurve);
+ aFaceEdges.Append(aEdge);
+
+ add(aEdge, aPCurve, defedge);
+ myAngle = savangle;
}
- Standard_Real f1,l1;
- Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(edge, face, f1, l1);
- if (C.IsNull()) continue;
-
- aFSeq.Append(f1);
- aLSeq.Append(l1);
- aCSeq.Append(C);
- aShSeq.Append(edge);
- Add(edge, face, gFace, C, theAncestors, defedge, f1, l1);
- myAngle = savangle;
}
- }
- if (nbEdge == 0 || myVemap.Extent() < 3)
- {
- MESH_FAILURE(theface);
- }
+ if ( nbEdge == 0 || myVertexEdgeMap->Extent() < 3 )
+ {
+ myAttribute->SetStatus(BRepMesh_Failure);
+ return myAttribute->GetStatus();
+ }
- if (myRelative ) defface = defface / nbEdge;
- else defface = myDeflection;
-
- if (myWithShare) defface = Max(maxdef, defface);
-
- T = BRep_Tool::Triangulation(face, loc);
-
- if (!myShapetrigu || T.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 <= myVemap.Extent(); i1++) {
- const BRepMesh_Vertex& aV = myStructure->GetNode(myVemap.FindKey(i1));
- ipn++;
- xCur=aV.Coord().X();
- yCur=aV.Coord().Y();
- minX=Min(xCur, minX);
- maxX=Max(xCur, maxX);
- minY=Min(yCur, minY);
- maxY=Max(yCur, maxY);
+ if ( myRelative )
+ {
+ defface = defface / nbEdge;
}
- Standard_Real myumin = minX;
- Standard_Real myumax = maxX;
- Standard_Real myvmin = minY;
- Standard_Real myvmax = maxY;
-
- const Standard_Real umin = BS.FirstUParameter();
- const Standard_Real umax = BS.LastUParameter();
- const Standard_Real vmin = BS.FirstVParameter();
- const Standard_Real vmax = BS.LastVParameter();
-
- if (myumin < umin || myumax > umax)
+ else
+ {
+ defface = myDeflection;
+ }
+
+ if ( myWithShare )
+ defface = Max(maxdef, defface);
+
+ TopLoc_Location aLoc;
+ Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, aLoc);
+
+ if (!myShapetrigu || aTriangulation.IsNull())
{
- if (BS.IsUPeriodic())
+ 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 <= myVertexEdgeMap->Extent(); ++i1 )
{
- if ((myumax - myumin) > (umax - umin))
- {
- myumax = myumin + (umax - umin);
- }
+ const BRepMesh_Vertex& aVertex = myStructure->GetNode(myVertexEdgeMap->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);
}
- else
+
+ 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 (umin > myumin) myumin = umin;
- if (umax < myumax) 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 (BS.IsVPeriodic())
+ if (myvmin < vmin || myvmax > vmax)
{
- if ((myvmax - myvmin) > (vmax - vmin))
+ if (gFace->IsVPeriodic())
+ {
+ if ((myvmax - myvmin) > (vmax - vmin))
+ myvmax = myvmin + (vmax - vmin);
+ }
+ else
{
- myvmax = myvmin + (vmax - vmin);
+ if ( vmin > myvmin )
+ myvmin = vmin;
+
+ if (vmax < myvmax)
+ myvmax = vmax;
}
}
- else
+
+ 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) )
{
- if (vmin > myvmin) myvmin = vmin;
- if (vmax < myvmax) myvmax = vmax;
+ myAttribute->SetStatus(BRepMesh_Failure);
+ return myAttribute->GetStatus();
}
- }
- // fast verification of the validity of calculated limits. If wrong,
- // sure a problem of pcurve.
- if (thetype == GeomAbs_BezierSurface &&
- (myumin < -0.5 || myumax > 1.5 || myvmin < -0.5 || myvmax > 1.5))
- {
- MESH_FAILURE(theface);
- }
-
- //define parameters for correct parametrics
-
- Standard_Real deltaX = 1.0;
- Standard_Real deltaY = 1.0;
- Standard_Integer nbVertices = myVemap.Extent();
- const Standard_Real tolclass = Precision::PConfusion(); //0.03*Max(myumax-myumin, myvmax-myvmin);
-
- BRepMeshCol::HClassifier classifier = new BRepMesh_Classifier;
- {
- BRepMesh_WireChecker aDFaceChecker(face,
- tolclass, myInternaledges, myVemap, myStructure,
- myumin, myumax, myvmin, myvmax, myInParallel);
- aDFaceChecker.ReCompute(classifier);
-
- myFacestate = aDFaceChecker.Status();
- if (myFacestate == BRepMesh_SelfIntersectingWire)
+ //define parameters for correct parametrics
+ Standard_Real deltaX = 1.0;
+ Standard_Real deltaY = 1.0;
+
{
- Standard_Integer nbmaill = 0;
- Standard_Real eps = Precision::Confusion();
- while (nbmaill < 5 && myFacestate != BRepMesh_ReMesh)
+ BRepMeshCol::HClassifier& aClassifier = myAttribute->ChangeClassifier();
+ BRepMesh_WireChecker aDFaceChecker(aFace, Precision::PConfusion(),
+ myInternalEdges, myVertexEdgeMap, myStructure,
+ myumin, myumax, myvmin, myvmax, myInParallel );
+
+ aDFaceChecker.ReCompute(aClassifier);
+ BRepMesh_Status aCheckStatus = aDFaceChecker.Status();
+
+ if (aCheckStatus == BRepMesh_SelfIntersectingWire)
{
- nbmaill++;
-
- //clear the structure of links
- myStructure.Nullify();
- myStructure = new BRepMesh_DataStructureOfDelaun(anAlloc);
-
- myVemap.Clear();
- myLocation2d.Clear();
- myInternaledges.Clear();
-
- Standard_Integer j1;
- for(j1 = 1; j1 <= aShSeq.Length(); j1++)
+ Standard_Integer nbmaill = 0;
+ Standard_Real eps = Precision::Confusion();
+ while (nbmaill < 5 && aCheckStatus != BRepMesh_ReMesh)
{
- const TopoDS_Edge& edge = TopoDS::Edge(aShSeq.Value(j1));
- if (myEdges.IsBound(edge))
+ ++nbmaill;
+
+ // Clear the structure of links
+ myStructure = myAttribute->ResetStructure();
+
+
+ for (Standard_Integer j = 1; j <= aFaceEdges.Length(); ++j)
{
- myEdges.UnBind(edge);
- myInternaledges.UnBind(edge);
+ const TopoDS_Edge& anEdge = aFaceEdges(j);
+ if (myEdges.IsBound(anEdge))
+ myEdges.UnBind(anEdge);
+
+ defedge = Max(myMapdefle(anEdge) / 3.0, eps);
+ myMapdefle.Bind(anEdge, defedge);
+
+ add(anEdge, aPCurves(j), defedge);
}
- }
-
-
- for( j1 = 1; j1 <= aShSeq.Length(); j1++)
- {
- const TopoDS_Edge& edge = TopoDS::Edge(aShSeq.Value(j1));
- defedge = myMapdefle(edge) / 3.;
- defedge = Max(defedge, eps);
- myMapdefle.Bind(edge, defedge);
- const Handle(Geom2d_Curve)& C = aCSeq.Value(j1);
- Add(edge, face, gFace, C, theAncestors, defedge, aFSeq.Value(j1), aLSeq.Value(j1));
- }
- aDFaceChecker.ReCompute(classifier);
- if (aDFaceChecker.Status() == BRepMesh_NoError)
- {
- myFacestate = BRepMesh_ReMesh;
+ aDFaceChecker.ReCompute(aClassifier);
+ if (aDFaceChecker.Status() == BRepMesh_NoError)
+ aCheckStatus = BRepMesh_ReMesh;
}
- nbVertices = myVemap.Extent();
}
+
+ myAttribute->SetStatus(aCheckStatus);
+ if (!myAttribute->IsValid())
+ //RemoveFaceAttribute(theFace);
+ return myAttribute->GetStatus();
}
- }
-
- if (myFacestate != BRepMesh_NoError && myFacestate != BRepMesh_ReMesh)
- {
- myNottriangulated.Append(face);
- classifier.Nullify();
- return;
- }
-
- // 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 = (myumax-myumin)/20;
- Standard_Real dv = (myvmax-myvmin)/20;
- Standard_Real dfuave=(myumin+myumax)/2, dfucur;
- Standard_Real dfvave=(myvmin+myvmax)/2, dfvcur;
- // U loop
- BS.D0 (myumin, myvmin, P11);
- BS.D0 (myumin, dfvave, P21);
- BS.D0 (myumin, myvmax, P31);
- for (i1=1, dfucur=myumin+du; i1 <= 20; i1++, dfucur+=du) {
- BS.D0 (dfucur, myvmin, P12);
- BS.D0 (dfucur, dfvave, P22);
- BS.D0 (dfucur, myvmax, P32);
- longu += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
- P11 = P12;
- P21 = P22;
- P31 = P32;
- }
- // V loop
- BS.D0(myumin, myvmin, P11);
- BS.D0(dfuave, myvmin, P21);
- BS.D0(myumax, myvmin, P31);
- for (i1=1, dfvcur=myvmin+dv; i1 <= 20; i1++, dfvcur+=dv) {
- BS.D0 (myumin, dfvcur, P12);
- BS.D0 (dfuave, dfvcur, P22);
- BS.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!!
-#ifdef DEB_MESH_CHRONO
- chMaillEdges.Stop();
- MESH_CHRONO_TSTOP(thetype);
-#endif
- MESH_FAILURE(theface);
- }
+ // 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;
+ }
- if (thetype == GeomAbs_Torus) {
- gp_Torus Tor = BS.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, myAngle);
- 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, myAngle);
- Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
- if(aa < gp::Resolution())
- return;
-
- Du = Du * Min(oldDv, Du) / aa;
+ // 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;
}
- 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.));
+
+ longu /= 3.;
+ longv /= 3.;
+ // akm (bug OCC16) ^^^^^
+
+ if (longu <= 1.e-16 || longv <= 1.e-16)
+ {
+ //yes, it is seen!!
+ 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, myAngle);
+ 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, myAngle);
+ Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
+
+ if (aa < gp::Resolution())
+ 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 (thetype == GeomAbs_Cylinder) {
- /*Standard_Real aMax = Max(myumax,myvmax);
- deltaX = 0.01; //1./aMax; //0.01;
- deltaY = 1.0;*/
- gp_Cylinder Cyl = BS.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 > GetAngle()) Du = GetAngle();
- deltaX = Du/longv;
- deltaY = 1.;
- }
- else {
- deltaX = (myumax-myumin)/longu;
- deltaY = (myvmax-myvmin)/longv;
- }
+ 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();
- if(!myMapattrib.IsBound(theface))
- {
- Handle(BRepMesh_FaceAttribute) aFA = new BRepMesh_FaceAttribute();
- aFA->GetDefFace() = defface;
- aFA->GetUMax() = myumax;
- aFA->GetVMax() = myvmax;
- aFA->GetUMin() = myumin;
- aFA->GetVMin() = myvmin;
- aFA->GetDeltaX() = deltaX;
- aFA->GetDeltaY() = deltaY;
- aFA->GetMinX() = minX;
- aFA->GetMinY() = minY;
- aFA->GetClassifier() = classifier;
- myMapattrib.Bind(theface, aFA);
- }
+ // Calculate parameters for iteration in U direction
+ Standard_Real Du = 1.0 - (defface/R);
+ if (Du < 0.0)
+ Du = 0.0;
- //Standard_Integer nbVertices = myVemap.Extent();
- T = new Poly_Triangulation(nbVertices, 1, Standard_True);
- TColgp_Array1OfPnt& Nodes = T->ChangeNodes();
- TColgp_Array1OfPnt2d& Nodes2d = T->ChangeUVNodes();
-
- Standard_Integer index;
- for (i = 1; i <= nbVertices; i++) {
- index = myVemap.FindKey(i);
- Nodes(i) = Pnt(index);
- Nodes2d(i).SetXY(Vertex(index).Coord());
- }
- BRepMesh_ShapeTool::AddInFace(face, T);
+ Du = 2.0 * ACos (Du);
+ if (Du > GetAngle())
+ Du = GetAngle();
- BRepMeshCol::DMapOfShapePairOfPolygon::Iterator It(myInternaledges);
- for (; It.More(); It.Next())
- {
- const TopoDS_Edge& aEdge = TopoDS::Edge(It.Key());
- const BRepMesh_PairOfPolygon& pair = It.Value();
- const Handle(Poly_PolygonOnTriangulation)& NOD1 = pair.First();
- const Handle(Poly_PolygonOnTriangulation)& NOD2 = pair.Last();
- if ( NOD1 == NOD2 )
- BRepMesh_ShapeTool::UpdateEdge(aEdge, NOD1, T, loc);
+ deltaX = Du / longv;
+ deltaY = 1.;
+ }
else
- BRepMesh_ShapeTool::UpdateEdge(aEdge, NOD1, NOD2, T, loc);
- }
- }
+ {
+ deltaX = (myumax-myumin)/longu;
+ deltaY = (myvmax-myvmin)/longv;
+ }
-#ifndef DEB_MESH
+ // Restore face attribute
+ myAttribute->SetDefFace(defface);
+ myAttribute->SetUMax(myumax);
+ myAttribute->SetVMax(myvmax);
+ myAttribute->SetUMin(myumin);
+ myAttribute->SetVMin(myvmin);
+ myAttribute->SetDeltaX(deltaX);
+ myAttribute->SetDeltaY(deltaY);
+ }
}
catch(Standard_Failure)
{
- MESH_FAILURE(theface);
+ myAttribute->SetStatus(BRepMesh_Failure);
}
-#endif // DEB_MESH
- myStructure.Nullify();
+
+ return myAttribute->GetStatus();
}
//=======================================================================
-//function : splitSegment
+//function : addLinkToMesh
//purpose :
//=======================================================================
-static void splitSegment( BRepMesh_GeomTool& theGT,
- const Handle(Geom_Surface)& theSurf,
- const Handle(Geom2d_Curve)& theCurve2d,
- const BRepAdaptor_Curve& theBAC,
- const Standard_Real theSquareEDef,
- const Standard_Real theFirst,
- const Standard_Real theLast,
- const Standard_Integer theNbIter)
+void BRepMesh_FastDiscret::addLinkToMesh(
+ const Standard_Integer theFirstNodeId,
+ const Standard_Integer theLastNodeId,
+ const TopAbs_Orientation theOrientation)
{
- //limit ineration 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) < theSquareEDef)
- return;
-
- uvm = gp_Pnt2d((uvf.XY() + uvl.XY())*0.5);
- midP3dFromSurf = theSurf->Value(uvm.X(), uvm.Y());
-
- gp_XYZ aVec = P3dL.XYZ()-P3dF.XYZ();
- aVec.Normalize();
-
- gp_XYZ Vec1 = midP3dFromSurf.XYZ() - P3dF.XYZ();
- Standard_Real aModulus = Vec1.Dot(aVec);
- gp_XYZ aProj = aVec*aModulus;
- gp_XYZ aDist = Vec1 - aProj;
-
- if(aDist.SquareModulus() < theSquareEDef)
- return;
-
- midpar = (theFirst + theLast) * 0.5;
- theBAC.D0(midpar, midP3d);
- theGT.AddPoint(midP3d, midpar, Standard_False);
-
- splitSegment(theGT, theSurf, theCurve2d, theBAC, theSquareEDef, theFirst, midpar, theNbIter+1);
- splitSegment(theGT, theSurf, theCurve2d, theBAC, theSquareEDef, midpar, theLast, theNbIter+1);
+ if (theOrientation == TopAbs_FORWARD)
+ myStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Frontier));
+ else if (theOrientation == TopAbs_REVERSED)
+ myStructure->AddLink(BRepMesh_Edge(theLastNodeId, theFirstNodeId, BRepMesh_Frontier));
+ else if (theOrientation == TopAbs_INTERNAL)
+ myStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Fixed));
}
//=======================================================================
-//function : Add
-//purpose :
+//function : getEdgeAttributes
+//purpose :
//=======================================================================
-void BRepMesh_FastDiscret::Add( const TopoDS_Edge& theEdge,
- const TopoDS_Face& theFace,
- const Handle(BRepAdaptor_HSurface)& theGFace,
- const Handle(Geom2d_Curve)& theC2d,
- const TopTools_IndexedDataMapOfShapeListOfShape& theAncestors,
- const Standard_Real theDefEdge,
- const Standard_Real theFirst,
- const Standard_Real theLast)
+Standard_Boolean BRepMesh_FastDiscret::getEdgeAttributes(
+ const TopoDS_Edge& theEdge,
+ const BRepMesh_FastDiscret::EdgePCurve& thePCurve,
+ const Standard_Real theDefEdge,
+ BRepMesh_FastDiscret::EdgeAttributes& theAttributes) const
{
- const TopAbs_Orientation orEdge = theEdge.Orientation();
- if (orEdge == TopAbs_EXTERNAL) return;
-
- const Standard_Boolean isEdgeBound = myEdges.IsBound(theEdge);
-
- if (!isEdgeBound)
- {
- if (Update(theEdge, theFace, theC2d, theDefEdge, theFirst, theLast))
- {
- return;
- }
- }
-
- TopoDS_Vertex pBegin, pEnd;
- TopExp::Vertices(theEdge, pBegin, pEnd);
- if (pBegin.IsNull() || pEnd.IsNull())
- {
- return;
- }
-
- Standard_Real wFirst, wLast;
- BRep_Tool::Range(theEdge, theFace, wFirst, wLast);
+ EdgeAttributes& aEAttr = theAttributes;
- gp_Pnt2d uvFirst, uvLast;
- BRep_Tool::UVPoints(theEdge, theFace, uvFirst, uvLast);
+ // Get vertices
+ TopExp::Vertices(theEdge, aEAttr.FirstVertex, aEAttr.LastVertex);
+ if (aEAttr.FirstVertex.IsNull() || aEAttr.LastVertex.IsNull())
+ return Standard_False;
- const Standard_Boolean sameUV = uvFirst.IsEqual(uvLast, Precision::PConfusion());
+ // Get range on 2d curve
+ const TopoDS_Face& aFace = myAttribute->Face();
+ BRep_Tool::Range(theEdge, aFace, aEAttr.FirstParam, aEAttr.LastParam);
- //Control vertexes tolerances
- gp_Pnt pFirst = theGFace->Value(uvFirst.X(), uvFirst.Y());
- gp_Pnt pLast = theGFace->Value(uvLast.X(), uvLast.Y());
+ // Get end points on 2d curve
+ BRep_Tool::UVPoints(theEdge, aFace, aEAttr.FirstUV, aEAttr.LastUV);
- Standard_Real mindist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(pBegin)),
- pLast.Distance(BRep_Tool::Pnt(pEnd)));
+ aEAttr.IsSameUV =
+ aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion());
- if(mindist < BRep_Tool::Tolerance(pBegin) ||
- mindist < BRep_Tool::Tolerance(pEnd) ) mindist = theDefEdge;
+ //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());
- // control of degenerated non-coded edges.
+ aEAttr.MinDist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(aEAttr.FirstVertex)),
+ pLast .Distance(BRep_Tool::Pnt(aEAttr.LastVertex)));
- Standard_Boolean degener = BRep_Tool::Degenerated(theEdge);
-
- if (!degener)
+ if (aEAttr.MinDist < BRep_Tool::Tolerance(aEAttr.FirstVertex) ||
+ aEAttr.MinDist < BRep_Tool::Tolerance(aEAttr.LastVertex))
{
- if (pBegin.IsSame(pEnd))
- {
- // calculation of the length of the edge in 3D
- Standard_Real longueur = 0.0;
- Standard_Real du = (wLast-wFirst)/20;
- gp_Pnt P1, P2;
- BRepAdaptor_Curve BC(theEdge);
- BC.D0(wFirst, P1);
- Standard_Real tolV = BRep_Tool::Tolerance(pBegin);
- Standard_Real tolV2 = 1.2*tolV;
- for (Standard_Integer l = 1; l <= 20; l++) {
- BC.D0(wFirst + l*du, P2);
- longueur += P1.Distance(P2);
- if (longueur > tolV2) break;
- P1 = P2;
- }
-
- if (longueur < tolV2)
- {
- degener = Standard_True;
- }
- }
+ aEAttr.MinDist = theDefEdge;
}
- // Correct UV points
- if (sameUV)
+ if (aEAttr.IsSameUV)
{
// 1. is it really sameUV without being degenerated
gp_Pnt2d uvF, uvL;
- theC2d->D0(theFirst, uvF);
- theC2d->D0(theLast, uvL);
- if (!uvFirst.IsEqual(uvF, Precision::PConfusion()))
- {
- uvFirst = uvF;
- }
- if (!uvLast.IsEqual(uvL, Precision::PConfusion()))
- {
- uvLast = uvL;
- }
+ thePCurve.Curve2d->D0(thePCurve.FirstParam, uvF);
+ thePCurve.Curve2d->D0(thePCurve.LastParam, uvL);
+
+ if (!aEAttr.FirstUV.IsEqual(uvF, Precision::PConfusion()))
+ aEAttr.FirstUV = uvF;
+
+ if (!aEAttr.LastUV.IsEqual(uvL, Precision::PConfusion()))
+ aEAttr.LastUV = uvL;
}
- gp_XY theUV;
+ return Standard_True;
+}
- // Process first vertex
- Standard_Integer ipf;
- if (myVertices.IsBound(pBegin))
+//=======================================================================
+//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())
{
- ipf = myVertices.Find(pBegin);
+ // Use edge geometry to produce tesselation.
+ aEAttr.FirstVExtractor =
+ new TopoDSVExplorer(aEAttr.FirstVertex, aEAttr.IsSameUV, aEAttr.LastVertex);
}
- else
+
+ if (aEAttr.LastVExtractor.IsNull())
{
- if (sameUV && myVertices.IsBound(pEnd))
- {
- ipf = myVertices.Find(pEnd);
- }
- else
- {
- myNbLocat++;
- ipf = myNbLocat;
- myLocation3d.Bind(ipf, BRep_Tool::Pnt(pBegin));
- }
- myVertices.Bind(pBegin, ipf);
+ // Use edge geometry to produce tesselation.
+ aEAttr.LastVExtractor =
+ new TopoDSVExplorer(aEAttr.LastVertex, aEAttr.IsSameUV, aEAttr.FirstVertex);
}
- Handle(BRepMesh_FaceAttribute) aFaceAttribute;
- GetFaceAttribute ( theFace, aFaceAttribute );
- theUV = BRepMesh_ShapeTool::FindUV(ipf, uvFirst,
- pBegin, mindist, aFaceAttribute, theGFace, myLocation2d);
+ gp_XY aTmpUV;
+ // Process first vertex
+ ipf = myAttribute->GetVertexIndex(aEAttr.FirstVExtractor, Standard_True);
+ aTmpUV = BRepMesh_ShapeTool::FindUV(ipf, aEAttr.FirstUV, aEAttr.FirstVertex,
+ aEAttr.MinDist, myAttribute);
- BRepMesh_Vertex vf(theUV, ipf, BRepMesh_Frontier);
- Standard_Integer ivf = myStructure->AddNode(vf);
+ myAttribute->AddNode(ipf, aTmpUV, BRepMesh_Frontier, ivf, isvf);
// Process last vertex
- Standard_Integer ipl;
- if (pEnd.IsSame(pBegin))
- {
- ipl = ipf;
- }
- else
+ ipl = aEAttr.LastVertex.IsSame(aEAttr.FirstVertex) ? ipf :
+ myAttribute->GetVertexIndex(aEAttr.LastVExtractor, Standard_True);
+ aTmpUV = BRepMesh_ShapeTool::FindUV(ipl, aEAttr.LastUV, aEAttr.LastVertex,
+ aEAttr.MinDist, myAttribute);
+
+ myAttribute->AddNode(ipl, aTmpUV, BRepMesh_Frontier, ivl, isvl);
+}
+
+//=======================================================================
+//function : add
+//purpose :
+//=======================================================================
+void BRepMesh_FastDiscret::add(
+ const TopoDS_Edge& theEdge,
+ const BRepMesh_FastDiscret::EdgePCurve& 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))
{
- if (myVertices.IsBound(pEnd))
- {
- ipl = myVertices.Find(pEnd);
- }
- else
- {
- if (sameUV)
- {
- ipl = ipf;
- }
- else
- {
- myNbLocat++;
- ipl = myNbLocat;
- myLocation3d.Bind(ipl, BRep_Tool::Pnt(pEnd));
- }
- myVertices.Bind(pEnd,ipl);
- }
+ update(theEdge, thePCurve.Curve2d, theDefEdge, aEAttr);
+ return;
}
- theUV = BRepMesh_ShapeTool::FindUV(ipl, uvLast,
- pEnd, mindist, aFaceAttribute, theGFace, myLocation2d);
+ Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
+ registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
- BRepMesh_Vertex vl(theUV, ipl, BRepMesh_Frontier);
- Standard_Integer ivl= myStructure->AddNode(vl);
+ // If this Edge has been already checked and it is not degenerated,
+ // the points of the polygon calculated at the first check are retrieved :
- Standard_Integer isvf = myVemap.FindIndex(ivf);
- if (isvf == 0) isvf = myVemap.Add(ivf);
- Standard_Integer isvl = myVemap.FindIndex(ivl);
- if (isvl == 0) isvl = myVemap.Add(ivl);
-
- Standard_Real otherdefedge = 0.5*theDefEdge;
- gp_Pnt2d uv;
- BRepMesh_Vertex v2;
- gp_Pnt P3d;
+ // 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();
- Handle(Poly_PolygonOnTriangulation) P1;
+ // creation anew:
+ const Standard_Integer aNodesNb = aNodes.Length();
+ TColStd_Array1OfInteger aNewNodes (1, aNodesNb);
+ TColStd_Array1OfReal aNewParams(1, aNodesNb);
- if (!isEdgeBound)
- {
- Handle(Poly_PolygonOnTriangulation) P2;
+ aNewNodes (1) = isvf;
+ aNewParams(1) = aEAttr.FirstParam;
- if (degener)
- {
- // creation anew:
- TColStd_Array1OfInteger Nodes(1, 2), NodInStruct(1, 2);
- TColStd_Array1OfReal Param(1, 2);
-
- NodInStruct(1) = ipf;
- Nodes(1) = isvf;
- Param(1) = wFirst;
-
- NodInStruct(2) = ipl;
- Nodes(2) = isvl;
- Param(2) = wLast;
+ aNewNodes (aNodesNb) = isvl;
+ aNewParams(aNodesNb) = aEAttr.LastParam;
- P1 = new Poly_PolygonOnTriangulation(Nodes, Param);
- P2 = new Poly_PolygonOnTriangulation(NodInStruct, Param);
- }
- else
+ 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)
{
- if (orEdge == TopAbs_INTERNAL) otherdefedge *= 0.5;
-
- BRepAdaptor_Curve cons;
- Standard_Boolean isSameParam = BRep_Tool::SameParameter(theEdge);
- if (isSameParam)
- {
- cons.Initialize(theEdge);
- }
- else
- {
- cons.Initialize(theEdge, theFace);
- }
+ const Standard_Integer aPointId = aNodes(i);
+ gp_Pnt& aPnt = myBoundaryPoints(aPointId);
- TopLoc_Location L;
- Standard_Integer nbpmin = 2;
- const GeomAbs_CurveType aCurveType = cons.GetType();
- if ( aCurveType == GeomAbs_Circle )
- nbpmin = 4; //OCC287
+ const Standard_Real aParam = aProvider.Parameter(i, aPnt);
+ gp_Pnt2d aUV = thePCurve.Curve2d->Value(aParam);
- BRepMesh_GeomTool GT(cons, wFirst, wLast, otherdefedge, 0.5 * myAngle, nbpmin);
+ Standard_Integer iv2, isv;
+ myAttribute->AddNode(aPointId, aUV.Coord(), BRepMesh_OnCurve, iv2, isv);
- if ( aCurveType == GeomAbs_BSplineCurve )
- {
- const Standard_Integer aNbInt = cons.NbIntervals( GeomAbs_C1 );
- if ( aNbInt > 0 )
- {
- TColStd_Array1OfReal anIntervals( 1, aNbInt + 1 );
- cons.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 );
+ aNewNodes (i) = isv;
+ aNewParams(i) = aParam;
- BRepMesh_GeomTool aDetalizator( cons, aStartInt, anEndInt,
- otherdefedge, 0.5 * myAngle, nbpmin );
+ addLinkToMesh(ivf, iv2, orEdge);
+ ivf = iv2;
+ }
- 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, theGFace, aParam, aPoint3d, aPoint2d );
- GT.AddPoint( aPoint3d, aParam, Standard_False );
- }
- }
- }
- }
+ // last point
+ if (ivf != ivl)
+ addLinkToMesh(ivf, ivl, orEdge);
+ }
- // PTv, chl/922/G9, Take into account internal vertices
- // it is necessary for internal edges, which do not split other edges, by their vertex
- TopoDS_Iterator exV(theEdge);
- for ( ; exV.More(); exV.Next() )
- {
- TopoDS_Vertex aIntV = TopoDS::Vertex(exV.Value());
- if ( aIntV.Orientation() == TopAbs_INTERNAL )
- GT.AddPoint(BRep_Tool::Pnt(aIntV),
- BRep_Tool::Parameter(aIntV, theEdge),
- Standard_True);
- }
+ Handle(Poly_PolygonOnTriangulation) P1 =
+ new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
- Standard_Integer i;
- Standard_Integer nbnodes = GT.NbPoints();
- //Check deflection in 2d space for improvement of edge tesselation.
- if( isSameParam && nbnodes > 1)
- {
- Standard_Real aSquareEdgeDef = otherdefedge * otherdefedge;
- const TopTools_ListOfShape& lf = theAncestors.FindFromKey(theEdge);
- TopTools_ListIteratorOfListOfShape itl(lf);
- for (; itl.More(); itl.Next()) {
- const TopoDS_Face& aFace = TopoDS::Face (itl.Value());
-
- TopLoc_Location aLoc;
- Standard_Real aF, aL;
- Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
- const Handle(Standard_Type)& aType = aSurf->DynamicType();
- if(aType == STANDARD_TYPE(Geom_Plane))
- continue;
- Handle(Geom2d_Curve) aCurve2d = BRep_Tool::CurveOnSurface(theEdge, aFace, aF, aL);
- if(Abs(aF-wFirst)>Precision::PConfusion()||Abs(aL-wLast)>Precision::PConfusion())
- continue;
-
- gp_Pnt2d uvf;
- Standard_Real parf;
- nbnodes = GT.NbPoints();
- TColStd_Array1OfReal aParamArray(1, nbnodes);
- for (i = 1; i <= nbnodes; i++)
- {
- GT.Value(i, theGFace, parf, P3d, uvf);
- aParamArray.SetValue(i, parf);
- }
- for (i = 1; i < nbnodes; i++)
- {
- splitSegment(GT, aSurf, aCurve2d, cons, aSquareEdgeDef, aParamArray(i), aParamArray(i+1), 1);
- }
- }
- }
+ storePolygon(theEdge, P1, theDefEdge);
+}
- // Creation of polygons on triangulation:
- Standard_Real puv;
- nbnodes = GT.NbPoints();
+//=======================================================================
+//function : update(edge)
+//purpose :
+//=======================================================================
+void BRepMesh_FastDiscret::update(
+ const TopoDS_Edge& theEdge,
+ const Handle(Geom2d_Curve)& theC2d,
+ const Standard_Real theDefEdge,
+ BRepMesh_FastDiscret::EdgeAttributes& theAttributes)
+{
+ EdgeAttributes& aEAttr = theAttributes;
- TColStd_Array1OfInteger Nodes(1, nbnodes);
- TColStd_Array1OfInteger NodInStruct(1, nbnodes);
- TColStd_Array1OfReal Param(1, nbnodes);
-
- // processing of the 1st point:
- Nodes(1) = isvf;
- NodInStruct(1) = ipf;
- Param(1) = wFirst;
-
- // last point:
- Nodes(nbnodes) = isvl;
- NodInStruct(nbnodes) = ipl;
- Param(nbnodes) = wLast;
+ 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(nbnodes > 2)
- {
- Standard_Integer iv2;
- for (i = 2; i < GT.NbPoints(); i++)
- {
- // Record 3d point
- GT.Value(i, theGFace, puv, P3d, uv);
- myNbLocat++;
- myLocation3d.Bind(myNbLocat, P3d);
- NodInStruct(i) = myNbLocat;
- // Record 2d point
- v2.Initialize(uv.Coord(), myNbLocat, BRepMesh_OnCurve);
- iv2=myStructure->AddNode(v2);
-
- Standard_Integer isv = myVemap.FindIndex(iv2);
- if (isv == 0) isv = myVemap.Add(iv2);
- Nodes(i) = isv;
- NodInStruct(i) = myNbLocat;
- Param(i) = puv;
-
- if (orEdge == TopAbs_FORWARD)
- myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Frontier));
- else if (orEdge == TopAbs_REVERSED)
- myStructure->AddLink(BRepMesh_Edge(iv2, ivf, BRepMesh_Frontier));
- else if (orEdge == TopAbs_INTERNAL)
- myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Fixed));
- ivf = iv2;
- }
- }
+ if (aPolygon.IsNull())
+ break;
- P1 = new Poly_PolygonOnTriangulation(Nodes, Param);
- P2 = new Poly_PolygonOnTriangulation(NodInStruct, Param);
- }
+ if (aTriangulation.IsNull() || !aPolygon->HasParameters())
+ continue;
- P2->Deflection(otherdefedge);
- BRepMesh_PairOfPolygon pair;
- pair.Append(P2);
- myEdges.Bind(theEdge, pair);
-
- if (ivf != ivl) {
- if (orEdge == TopAbs_FORWARD)
- myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Frontier));
- else if (orEdge == TopAbs_REVERSED)
- myStructure->AddLink(BRepMesh_Edge(ivl, ivf, BRepMesh_Frontier));
- else if (orEdge == TopAbs_INTERNAL)
- myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Fixed));
- }
-
+ if (aPolygon->Deflection() > 1.1 * theDefEdge)
+ continue;
- }
- // If this Edge has been already checked and it is not degenerated,
- // the points of the polygon calculated at the first check are retrieved :
- else
- {
- if (degener)
- {
- // Create 2d polygon for degenerated edge
- TColStd_Array1OfInteger Nodes(1, 2);
- TColStd_Array1OfReal PPar(1, 2);
-
- Nodes(1) = isvf;
- PPar(1) = wFirst;
-
- Nodes(2) = isvl;
- PPar(2) = wLast;
-
- P1 = new Poly_PolygonOnTriangulation(Nodes, PPar);
- }
- else
- {
- // retrieve the polygone:
- const BRepMesh_PairOfPolygon& pair = myEdges.Find(theEdge);
- const Handle(Poly_PolygonOnTriangulation)& P = pair.First();
- const TColStd_Array1OfInteger& NOD = P->Nodes();
- Handle(TColStd_HArray1OfReal) Par = P->Parameters();
-
- // creation anew:
- const Standard_Integer nbnodes = NOD.Length();
- TColStd_Array1OfInteger Nodes(1, nbnodes);
- TColStd_Array1OfReal PPar(1, nbnodes);
- Standard_Integer iv2;
-
- Nodes(1) = isvf;
- PPar(1) = wFirst;
-
- Nodes(nbnodes) = isvl;
- PPar(nbnodes) = wLast;
-
- if (nbnodes > 2)
- {
- Standard_Integer i;
- if (BRep_Tool::SameParameter(theEdge))
- {
- for (i = 2; i < nbnodes; i++)
- {
- const Standard_Real puv = Par->Value(i);
- theC2d->D0(puv, uv);
- v2.Initialize(uv.Coord(), NOD(i), BRepMesh_OnCurve);
- iv2 = myStructure->AddNode(v2);
-
- Standard_Integer isv = myVemap.FindIndex(iv2);
- if (isv == 0) isv = myVemap.Add(iv2);
- Nodes(i) = isv;
- PPar(i) = puv;
-
- if (orEdge==TopAbs_FORWARD)
- myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Frontier));
- else if (orEdge == TopAbs_REVERSED)
- myStructure->AddLink(BRepMesh_Edge(iv2, ivf, BRepMesh_Frontier));
- else if (orEdge == TopAbs_INTERNAL)
- myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Fixed));
-
- ivf = iv2;
- }
- }
- else
- {
- const Standard_Real wFold = Par->Value(Par->Lower());
- const Standard_Real wLold = Par->Value(Par->Upper());
+ const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
+ const TColStd_Array1OfInteger& aIndices = aPolygon->Nodes();
+ Handle(TColStd_HArray1OfReal) aParams = aPolygon->Parameters();
- Standard_Real wKoef = 1.;
- if ((wFold != wFirst || wLold != wLast) && wLold != wFold)
- {
- wKoef = (wLast - wFirst) / (wLold - wFold);
- }
-
- BRepAdaptor_Curve cons(theEdge, theFace);
- Extrema_LocateExtPC pcos;
- pcos.Initialize(cons, cons.FirstParameter(),
- cons.LastParameter(), Precision::PConfusion());
-
- Standard_Real wPrev;
- Standard_Real wCur = wFirst;
- Standard_Real wCurFound = wFirst;
- for (i = 2; i < nbnodes; i++)
- {
- P3d = myLocation3d(NOD(i));
- // Record 2d point
- wPrev = wCur;
- wCur = wFirst + wKoef*(Par->Value(i) - wFold);
- wCurFound += (wCur - wPrev);
- pcos.Perform(P3d, wCurFound);
- if (pcos.IsDone()) wCurFound = pcos.Point().Parameter();
- theC2d->D0(wCurFound, uv);
- v2.Initialize(uv.Coord(), NOD(i), BRepMesh_OnCurve);
- iv2 = myStructure->AddNode(v2);
-
- Standard_Integer isv = myVemap.FindIndex(iv2);
- if (isv == 0) isv = myVemap.Add(iv2);
- Nodes(i) = isv;
- PPar(i) = wCurFound;
-
- if (orEdge==TopAbs_FORWARD)
- myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Frontier));
- else if (orEdge == TopAbs_REVERSED)
- myStructure->AddLink(BRepMesh_Edge(iv2, ivf, BRepMesh_Frontier));
- else if (orEdge == TopAbs_INTERNAL)
- myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Fixed));
-
- ivf = iv2;
- }
- }
- }
+ aEAttr.FirstVExtractor = new PolyVExplorer(aEAttr.FirstVertex,
+ aEAttr.IsSameUV, aEAttr.LastVertex, aIndices(1), aNodes, aLoc);
- P1 = new Poly_PolygonOnTriangulation(Nodes, PPar);
-
- if (ivf != ivl) {
- if (orEdge == TopAbs_FORWARD)
- myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Frontier));
- else if (orEdge == TopAbs_REVERSED)
- myStructure->AddLink(BRepMesh_Edge(ivl, ivf, BRepMesh_Frontier));
- else if (orEdge == TopAbs_INTERNAL)
- myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Fixed));
- }
- }
- }
+ aEAttr.LastVExtractor = new PolyVExplorer(aEAttr.LastVertex,
+ aEAttr.IsSameUV, aEAttr.FirstVertex, aIndices(aIndices.Length()), aNodes, aLoc);
- P1->Deflection(theDefEdge);
- if (myInternaledges.IsBound(theEdge))
- {
- BRepMesh_PairOfPolygon& pair = myInternaledges.ChangeFind(theEdge);
- if (orEdge == TopAbs_REVERSED)
- pair.Append(P1);
- else
- pair.Prepend(P1);
+ aEdgeTool = new BRepMesh_EdgeTessellationExtractor(theEdge, theC2d,
+ aFace, aTriangulation, aPolygon, aLoc);
}
- else
+
+ if (aEdgeTool.IsNull())
{
- BRepMesh_PairOfPolygon pair1;
- pair1.Append(P1);
- myInternaledges.Bind(theEdge, pair1);
+ aEdgeTool = new BRepMesh_EdgeTessellator(theEdge, myAttribute,
+ mySharedFaces, theDefEdge, myAngle);
}
-}
+ Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
+ registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
-//=======================================================================
-//function : Update(edge)
-//purpose :
-//=======================================================================
-Standard_Boolean BRepMesh_FastDiscret::Update(const TopoDS_Edge& theEdge,
- const TopoDS_Face& theFace,
- const Handle(Geom2d_Curve)& theC2d,
- const Standard_Real theDefEdge,
- const Standard_Real theFirst,
- const Standard_Real theLast)
-{
- TopLoc_Location Loc;
- Handle(Poly_Triangulation) T;
- Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
-
- Standard_Integer i = 1;
- Standard_Boolean found = Standard_False;
- do
+ TopAbs_Orientation orEdge = theEdge.Orientation();
+ Handle(Poly_PolygonOnTriangulation) P1, P2;
+ if (BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
{
- BRep_Tool::PolygonOnTriangulation(theEdge,Poly,T,Loc,i);
- i++;
- if (!found && !T.IsNull() && T->HasUVNodes() &&
- !Poly.IsNull() && Poly->HasParameters())
- {
- if (Poly->Deflection() <= 1.1*theDefEdge)
- {
- // 2d vertex indices
- TopAbs_Orientation orEdge = theEdge.Orientation();
- Standard_Integer iv1, iv2, ivl;
- Standard_Integer isv1, isv, isvl;
-
- // Get range on 2d curve
- Standard_Real wFirst, wLast;
- BRep_Tool::Range(theEdge, theFace, wFirst, wLast);
-
- // Get end points on 2d curve
- gp_Pnt2d uvFirst, uvLast;
- BRep_Tool::UVPoints(theEdge, theFace, uvFirst, uvLast);
-
- // Get vertices
- TopoDS_Vertex pBegin, pEnd;
- TopExp::Vertices(theEdge,pBegin,pEnd);
-
- const Standard_Boolean sameUV =
- uvFirst.IsEqual(uvLast, Precision::PConfusion());
-
- //Controle vertice tolerances
- BRepAdaptor_Surface BS(theFace, Standard_False);
- Handle(BRepAdaptor_HSurface) gFace = new BRepAdaptor_HSurface(BS);
-
-
- gp_Pnt pFirst = gFace->Value(uvFirst.X(), uvFirst.Y());
- gp_Pnt pLast = gFace->Value(uvLast.X(), uvLast.Y());
-
- Standard_Real mindist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(pBegin)),
- pLast.Distance(BRep_Tool::Pnt(pEnd)));
-
- if (mindist < BRep_Tool::Tolerance(pBegin) ||
- mindist < BRep_Tool::Tolerance(pEnd) ) mindist = theDefEdge;
-
- if (sameUV)
- {
- // 1. is it really sameUV without being degenerated
- gp_Pnt2d uvF, uvL;
- theC2d->D0(theFirst, uvF);
- theC2d->D0(theLast, uvL);
- if (!uvFirst.IsEqual(uvF, Precision::PConfusion())) {
- uvFirst = uvF;
- }
- if (!uvLast.IsEqual(uvL, Precision::PConfusion())) {
- uvLast = uvL;
- }
- }
+ const Standard_Integer aNodesNb = 2;
+ TColStd_Array1OfInteger aNewNodes (1, aNodesNb);
+ TColStd_Array1OfInteger aNewNodInStruct(1, aNodesNb);
+ TColStd_Array1OfReal aNewParams (1, aNodesNb);
- const TColgp_Array1OfPnt& Nodes = T->Nodes();
- const TColStd_Array1OfInteger& Indices = Poly->Nodes();
- Handle(TColStd_HArray1OfReal) Param = Poly->Parameters();
-
- const Standard_Integer nbnodes = Indices.Length();
- TColStd_Array1OfInteger NewNodes(1, nbnodes);
- TColStd_Array1OfInteger NewNodInStruct(1, nbnodes);
-
- gp_Pnt P3d;
- gp_XY theUV;
-
- // Process first vertex
- Standard_Integer ipf;
- if (myVertices.IsBound(pBegin))
- {
- ipf = myVertices.Find(pBegin);
- }
- else
- {
- if (sameUV && myVertices.IsBound(pEnd))
- {
- ipf = myVertices.Find(pEnd);
- }
- else
- {
- P3d = Nodes(Indices(1));
- if (!Loc.IsIdentity())
- P3d.Transform(Loc.Transformation());
- myNbLocat++;
- myLocation3d.Bind(myNbLocat,P3d);
- ipf = myNbLocat;
- }
- myVertices.Bind(pBegin,ipf);
- }
- NewNodInStruct(1) = ipf;
-
- Handle(BRepMesh_FaceAttribute) aFaceAttribute;
- GetFaceAttribute ( theFace, aFaceAttribute );
- theUV = BRepMesh_ShapeTool::FindUV(ipf, uvFirst,
- pBegin, mindist, aFaceAttribute, gFace, myLocation2d);
-
- BRepMesh_Vertex vf(theUV,ipf,BRepMesh_Frontier);
- iv1 = myStructure->AddNode(vf);
- isv1 = myVemap.FindIndex(iv1);
- if (isv1 == 0) isv1 = myVemap.Add(iv1);
- NewNodes(1) = isv1;
-
- // Process last vertex
- Standard_Integer ipl;
- if (pEnd.IsSame(pBegin))
- {
- ipl = ipf;
- }
- else
- {
- if (myVertices.IsBound(pEnd))
- {
- ipl = myVertices.Find(pEnd);
- }
- else
- {
- if (sameUV)
- {
- ipl = ipf;
- ivl = iv1;
- }
- else
- {
- myNbLocat++;
- myLocation3d.Bind(myNbLocat,Nodes(Indices(nbnodes)).Transformed(Loc.Transformation()));
- ipl = myNbLocat;
- }
- myVertices.Bind(pEnd,ipl);
- }
- }
- NewNodInStruct(nbnodes) = ipl;
- theUV = BRepMesh_ShapeTool::FindUV(ipl, uvLast,
- pEnd, mindist, aFaceAttribute, gFace, myLocation2d);
-
- BRepMesh_Vertex vl(theUV,ipl,BRepMesh_Frontier);
-
- ivl = myStructure->AddNode(vl);
- isvl = myVemap.FindIndex(ivl);
- if (isvl == 0) isvl = myVemap.Add(ivl);
-
- NewNodes(nbnodes) = isvl;
-
- gp_Pnt2d uv;
- BRepMesh_Vertex v;
-
- if (BRep_Tool::SameParameter(theEdge))
- {
- for (i = 2; i < Indices.Length(); i++)
- {
- // Record 3d point
- P3d = Nodes(Indices(i));
- if (!Loc.IsIdentity())
- P3d.Transform(Loc.Transformation());
- myNbLocat++;
- myLocation3d.Bind(myNbLocat, P3d);
- NewNodInStruct(i) = myNbLocat;
- // Record 2d point
- uv = theC2d->Value(Param->Value(i));
- v.Initialize(uv.Coord(), myNbLocat, BRepMesh_Frontier);
- iv2 = myStructure->AddNode(v);
- isv = myVemap.FindIndex(iv2);
- if (isv == 0) isv = myVemap.Add(iv2);
- NewNodes(i) = isv;
-
- //add links
- if (orEdge == TopAbs_FORWARD)
- myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Frontier));
- else if (orEdge == TopAbs_REVERSED)
- myStructure->AddLink(BRepMesh_Edge(iv2,iv1,BRepMesh_Frontier));
- else if (orEdge == TopAbs_INTERNAL)
- myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Fixed));
- iv1 = iv2;
- }
-
- // last point
- if (iv1 != ivl) {
- if (orEdge == TopAbs_FORWARD)
- myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Frontier));
- else if (orEdge == TopAbs_REVERSED)
- myStructure->AddLink(BRepMesh_Edge(ivl,iv1,BRepMesh_Frontier));
- else if (orEdge == TopAbs_INTERNAL)
- myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Fixed));
- }
-
-
- }
- else
- {
- const Standard_Real wFold = Param->Value(Param->Lower());
- const Standard_Real wLold = Param->Value(Param->Upper());
-
- Standard_Real wKoef = 1.;
- if ((wFold != wFirst || wLold != wLast) && wLold != wFold)
- {
- wKoef = (wLast - wFirst) / (wLold - wFold);
- }
-
- BRepAdaptor_Curve cons(theEdge, theFace);
- Extrema_LocateExtPC pcos;
- pcos.Initialize(cons, cons.FirstParameter(),
- cons.LastParameter(), Precision::PConfusion());
-
- Standard_Real wPrev;
- Standard_Real wCur = wFirst;
- Standard_Real wCurFound = wFirst;
- for (i = 2; i < Indices.Length(); i++)
- {
- // Record 3d point
- P3d = Nodes(Indices(i));
- if (!Loc.IsIdentity())
- P3d.Transform(Loc.Transformation());
- myNbLocat++;
- myLocation3d.Bind(myNbLocat, P3d);
- NewNodInStruct(i) = myNbLocat;
- // Record 2d point
- wPrev = wCur;
- wCur = wFirst + wKoef*(Param->Value(i) - wFold);
- wCurFound += (wCur - wPrev);
- pcos.Perform(P3d, wCurFound);
- if (pcos.IsDone()) wCurFound = pcos.Point().Parameter();
- theC2d->D0(wCurFound, uv);
- v.Initialize(uv.Coord(), myNbLocat, BRepMesh_Frontier);
- iv2 = myStructure->AddNode(v);
- isv = myVemap.FindIndex(iv2);
- if (isv == 0) isv = myVemap.Add(iv2);
- NewNodes(i) = isv;
+ aNewNodInStruct(1) = ipf;
+ aNewNodes (1) = isvf;
+ aNewParams (1) = aEAttr.FirstParam;
-
- //add links
- if (orEdge == TopAbs_FORWARD)
- myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Frontier));
- else if (orEdge == TopAbs_REVERSED)
- myStructure->AddLink(BRepMesh_Edge(iv2,iv1,BRepMesh_Frontier));
- else if (orEdge == TopAbs_INTERNAL)
- myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Fixed));
- iv1 = iv2;
- }
-
- // last point
- if (iv1 != ivl) {
- if (orEdge == TopAbs_FORWARD)
- myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Frontier));
- else if (orEdge == TopAbs_REVERSED)
- myStructure->AddLink(BRepMesh_Edge(ivl,iv1,BRepMesh_Frontier));
- else if (orEdge == TopAbs_INTERNAL)
- myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Fixed));
- }
- }
-
- Handle(Poly_PolygonOnTriangulation) P1 =
- new Poly_PolygonOnTriangulation(NewNodes, Param->Array1());
- P1->Deflection(theDefEdge);
- if (myInternaledges.IsBound(theEdge))
- {
- BRepMesh_PairOfPolygon& pair = myInternaledges.ChangeFind(theEdge);
- if (theEdge.Orientation() == TopAbs_REVERSED)
- pair.Append(P1);
- else
- pair.Prepend(P1);
- }
- else
- {
- BRepMesh_PairOfPolygon pair1;
- pair1.Append(P1);
- myInternaledges.Bind(theEdge, pair1);
- }
-
- Handle(Poly_PolygonOnTriangulation) P2 =
- new Poly_PolygonOnTriangulation(NewNodInStruct, Param->Array1());
- P2->Deflection(theDefEdge);
- BRepMesh_PairOfPolygon pair;
- pair.Append(P2);
- myEdges.Bind(theEdge, pair);
-
- found = Standard_True;
- }
- else
- {
- BRepMesh_ShapeTool::NullifyEdge(theEdge, T, Loc);
- BRepMesh_ShapeTool::NullifyFace(theFace);
- }
- }
- else if (!T.IsNull() && !T->HasUVNodes())
- {
- BRepMesh_ShapeTool::NullifyEdge(theEdge, T, Loc);
- BRepMesh_ShapeTool::NullifyFace(theFace);
- }
- }
- while (!Poly.IsNull());
+ aNewNodInStruct(aNodesNb) = ipl;
+ aNewNodes (aNodesNb) = isvl;
+ aNewParams (aNodesNb) = aEAttr.LastParam;
- return found;
-}
+ P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
+ P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
+ }
+ else
+ {
+ const Standard_Integer aNodesNb = aEdgeTool->NbPoints();
+ TColStd_Array1OfInteger aNewNodes (1, aNodesNb);
+ TColStd_Array1OfInteger aNewNodInStruct(1, aNodesNb);
+ TColStd_Array1OfReal aNewParams (1, aNodesNb);
-//=======================================================================
-//function : output
-//purpose :
-//=======================================================================
-Standard_Integer BRepMesh_FastDiscret::NbTriangles() const
-{
- return myStructure->NbElements();
-}
+ aNewNodInStruct(1) = ipf;
+ aNewNodes (1) = isvf;
+ aNewParams (1) = aEAttr.FirstParam;
-//=======================================================================
-//function : Triangle
-//purpose :
-//=======================================================================
+ aNewNodInStruct(aNodesNb) = ipl;
+ aNewNodes (aNodesNb) = isvl;
+ aNewParams (aNodesNb) = aEAttr.LastParam;
-const BRepMesh_Triangle& BRepMesh_FastDiscret::Triangle
- (const Standard_Integer Index) const
-{
- return myStructure->GetElement(Index);
-}
+ Standard_Integer aLastPointId = myAttribute->LastPointId();
+ for (Standard_Integer i = 2; i < aNodesNb; ++i)
+ {
+ gp_Pnt aPnt;
+ gp_Pnt2d aUV;
+ Standard_Real aParam;
+ aEdgeTool->Value(i, aParam, aPnt, aUV);
+ myBoundaryPoints.Bind(++aLastPointId, aPnt);
-//=======================================================================
-//function : NbEdges
-//purpose :
-//=======================================================================
+ Standard_Integer iv2, isv;
+ myAttribute->AddNode(aLastPointId, aUV.Coord(), BRepMesh_Frontier, iv2, isv);
-Standard_Integer BRepMesh_FastDiscret::NbEdges() const
-{
- return myStructure->NbLinks();
-}
+ aNewNodInStruct(i) = aLastPointId;
+ aNewNodes (i) = isv;
+ aNewParams (i) = aParam;
-//=======================================================================
-//function : Edge
-//purpose :
-//=======================================================================
+ addLinkToMesh(ivf, iv2, orEdge);
+ ivf = iv2;
+ }
-const BRepMesh_Edge& BRepMesh_FastDiscret::Edge(const Standard_Integer Index) const
-{
- return myStructure->GetLink(Index);
-}
+ P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
+ P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
+ }
-//=======================================================================
-//function : NbVertices
-//purpose :
-//=======================================================================
+ // last point
+ if (ivf != ivl)
+ addLinkToMesh(ivf, ivl, orEdge);
-Standard_Integer BRepMesh_FastDiscret::NbVertices() const
-{
- return myStructure->NbNodes();
+ storePolygon(theEdge, P1, theDefEdge);
+ storePolygonSharedData(theEdge, P2, theDefEdge);
}
//=======================================================================
-//function : Vertex
+//function : storeInternalPolygon
//purpose :
//=======================================================================
-
-const BRepMesh_Vertex& BRepMesh_FastDiscret::Vertex
- (const Standard_Integer Index) const
+void BRepMesh_FastDiscret::storePolygon(
+ const TopoDS_Edge& theEdge,
+ Handle(Poly_PolygonOnTriangulation)& thePolygon,
+ const Standard_Real theDeflection)
{
- return myStructure->GetNode(Index);
-}
+ thePolygon->Deflection(theDeflection);
+ if (myInternalEdges->IsBound(theEdge))
+ {
+ BRepMesh_PairOfPolygon& aPair = myInternalEdges->ChangeFind(theEdge);
+ if (theEdge.Orientation() == TopAbs_REVERSED)
+ aPair.Append(thePolygon);
+ else
+ aPair.Prepend(thePolygon);
-//=======================================================================
-//function : Pnt
-//purpose :
-//=======================================================================
+ return;
+ }
-const gp_Pnt& BRepMesh_FastDiscret::Pnt(const Standard_Integer Index) const
-{
- return myLocation3d(myStructure->GetNode(Index).Location3d());
+ BRepMesh_PairOfPolygon aPair;
+ aPair.Append(thePolygon);
+ myInternalEdges->Bind(theEdge, aPair);
}
//=======================================================================
-//function : VerticesOfDomain
+//function : storePolygonSharedData
//purpose :
//=======================================================================
-
-void BRepMesh_FastDiscret::VerticesOfDomain(BRepMeshCol::MapOfInteger& Indices) const
-{
- Indices.Clear();
-
- // recuperate from the map of edges.
- const BRepMeshCol::MapOfInteger& edmap = myStructure->LinksOfDomain();
-
- // iterator on edges.
- BRepMeshCol::MapOfInteger::Iterator iter(edmap);
-
- Standard_Integer ind_edge;
- for (iter.Reset(); iter.More(); iter.Next()) {
- ind_edge = iter.Key();
- const BRepMesh_Edge& Ed = Edge(ind_edge);
- Indices.Add(Ed.FirstNode());
- Indices.Add(Ed.LastNode());
- }
-}
-
-BRepMesh_Status BRepMesh_FastDiscret::CurrentFaceStatus() const
+void BRepMesh_FastDiscret::storePolygonSharedData(
+ const TopoDS_Edge& theEdge,
+ Handle(Poly_PolygonOnTriangulation)& thePolygon,
+ const Standard_Real theDeflection)
{
- return myFacestate;
+ 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)& theFattrib) const
+Standard_Boolean BRepMesh_FastDiscret::GetFaceAttribute(
+ const TopoDS_Face& theFace,
+ Handle(BRepMesh_FaceAttribute)& theAttribute ) const
{
- if(myMapattrib.IsBound(theFace))
+ if (myAttributes.IsBound(theFace))
{
- theFattrib = myMapattrib(theFace);
+ theAttribute = myAttributes(theFace);
return Standard_True;
}
+
return Standard_False;
}
//function : RemoveFaceAttribute
//purpose :
//=======================================================================
-
void BRepMesh_FastDiscret::RemoveFaceAttribute(const TopoDS_Face& theFace)
{
- if(myMapattrib.IsBound(theFace))
- myMapattrib.UnBind(theFace);
-}
-
-//=======================================================================
-//function : CreateMutexesForSubShapes
-//purpose :
-//=======================================================================
-void BRepMesh_FastDiscret::CreateMutexesForSubShapes(const TopoDS_Shape& theShape,
- const TopAbs_ShapeEnum theType)
-{
- myMutexProvider.CreateMutexesForSubShapes(theShape, theType);
-}
-
-//=======================================================================
-//function : RemoveAllMutexes
-//purpose :
-//=======================================================================
-void BRepMesh_FastDiscret::RemoveAllMutexes()
-{
- myMutexProvider.RemoveAllMutexes();
+ if (myAttributes.IsBound(theFace))
+ myAttributes.UnBind(theFace);
}
#include <BRepMesh_Triangle.hxx>
#include <BRepMesh_FaceAttribute.hxx>
#include <BRepMesh_Collections.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 TopTools_IndexedDataMapOfShapeListOfShape;
class TopoDS_Edge;
class BRepAdaptor_HSurface;
class Geom2d_Curve;
-class TopoDS_Vertex;
class BRepMesh_Edge;
class BRepMesh_Vertex;
class gp_Pnt;
const Standard_Boolean shapetrigu = Standard_False,
const Standard_Boolean isInParallel = Standard_False);
- //! Build triangulation on the whole shape <br>
+ //! Build triangulation on the whole shape.
Standard_EXPORT void Perform(const TopoDS_Shape& shape);
- //! Record a face for further processing. <br>
- Standard_EXPORT void Add(const TopoDS_Face& face,
- const TopTools_IndexedDataMapOfShapeListOfShape& ancestor) ;
+ //! 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 <br>
- //! processing by call to Add(). Can be executed in <br>
- //! parallel threads. <br>
+ //! 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);
}
- Standard_EXPORT BRepMesh_Status CurrentFaceStatus() const;
-
//! Request algorithm to launch in multiple threads <br>
//! to improve performance (should be supported by plugin). <br>
- Standard_EXPORT void SetParallel(const Standard_Boolean theInParallel);
+ inline void SetParallel(const Standard_Boolean theInParallel)
+ {
+ myInParallel = theInParallel;
+ }
//! Returns the multi-threading usage flag. <br>
- Standard_EXPORT Standard_Boolean IsParallel() const;
-
- //! Creates mutexes for each sub-shape of type theType in theShape. <br>
- //! Used to avoid data races. <br>
- Standard_EXPORT void CreateMutexesForSubShapes(const TopoDS_Shape& theShape,
- const TopAbs_ShapeEnum theType);
-
- //! Removes all created mutexes <br>
- Standard_EXPORT void RemoveAllMutexes();
-
- //! Gives the number of built triangles. <br>
- Standard_EXPORT Standard_Integer NbTriangles() const;
-
- //! Gives the triangle of <Index>. <br>
- Standard_EXPORT const BRepMesh_Triangle& Triangle(const Standard_Integer Index) const;
-
- //! Gives the number of built Edges <br>
- Standard_EXPORT Standard_Integer NbEdges() const;
-
- //! Gives the edge of index <Index>. <br>
- Standard_EXPORT const BRepMesh_Edge& Edge(const Standard_Integer Index) const;
-
- //! Gives the number of built Vertices. <br>
- Standard_EXPORT Standard_Integer NbVertices() const;
-
- //! Gives the vertex of <Index>. <br>
- Standard_EXPORT const BRepMesh_Vertex& Vertex(const Standard_Integer Index) const;
-
- //! Gives the nodes of triangle with the given index.
- Standard_EXPORT void TriangleNodes(const Standard_Integer theIndex,
- Standard_Integer (&theNodes)[3]) const
+ inline Standard_Boolean IsParallel() const
{
- myStructure->ElementNodes(Triangle(theIndex), theNodes);
+ return myInParallel;
}
-
- //! Gives the location3d of the vertex of <Index>. <br>
- Standard_EXPORT const gp_Pnt& Pnt(const Standard_Integer Index) const;
-
+
//! Gives the list of indices of the vertices <br>
Standard_EXPORT void VerticesOfDomain(BRepMeshCol::MapOfInteger& Indices) const;
- //! Gives the list of indices of the edges <br>
- inline void EdgesOfDomain(BRepMeshCol::MapOfInteger& Indices) const
- {
- Indices = myStructure->LinksOfDomain();
- }
-
- //! Gives the list of indices of the triangles <br>
- inline void TrianglesOfDomain(BRepMeshCol::MapOfInteger& Indices) const
- {
- Indices = myStructure->ElementsOfDomain();
- }
-
- //! Gives the number of different location in 3d space.
- //! It is different of the number of vertices if there
- //! is more than one surface. <br>
- //! Even for one surface, the number can be different
- //! if an edge is shared. <br>
- inline Standard_Integer NbPoint3d() const
- {
- return myNbLocat;
- }
-
- //! Gives the 3d space location of the vertex <Index>. <br>
- inline const gp_Pnt& Point3d(const Standard_Integer Index) const
- {
- return myLocation3d(Index);
- }
-
//! returns the deflection value. <br>
inline Standard_Real GetDeflection() const
{
return myShapetrigu;
}
- //! returns the face deflection value. <br>
- Standard_EXPORT Standard_Boolean GetFaceAttribute(const TopoDS_Face& face,Handle(BRepMesh_FaceAttribute)& fattrib) const;
+ Standard_EXPORT void InitSharedFaces(const TopoDS_Shape& theShape);
- //! remove face attribute as useless to free locate memory <br>
- Standard_EXPORT void RemoveFaceAttribute(const TopoDS_Face& face);
-
- inline const TopTools_DataMapOfShapeReal& GetMapOfDefEdge() const
+ inline const TopTools_IndexedDataMapOfShapeListOfShape& SharedFaces() const
{
- return myMapdefle;
+ return mySharedFaces;
}
+ //! Gives face attribute.
+ Standard_EXPORT Standard_Boolean GetFaceAttribute
+ ( const TopoDS_Face& theFace, Handle(BRepMesh_FaceAttribute)& theAttribute ) 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_RTTI(BRepMesh_FastDiscret)
-private:
-
- void Add(const TopoDS_Edge& edge,
- const TopoDS_Face& face,
- const Handle(BRepAdaptor_HSurface)& S,
- const Handle(Geom2d_Curve)& C,
- const TopTools_IndexedDataMapOfShapeListOfShape& ancestor,
- const Standard_Real defedge,
- const Standard_Real first,
- const Standard_Real last);
-
- void Add(const TopoDS_Vertex& theVert,
- const TopoDS_Face& face,
- const Handle(BRepAdaptor_HSurface)& S);
-
- Standard_Boolean Update(const TopoDS_Edge& Edge,
- const TopoDS_Face& Face,
- const Handle(Geom2d_Curve)& C,
- const Standard_Real defedge,
- const Standard_Real first,
- const Standard_Real last);
-
- void InternalVertices(const Handle(BRepAdaptor_HSurface)& caro,
- BRepMeshCol::ListOfVertex& inter,
- const Standard_Real defedge,
- const BRepMeshCol::HClassifier& classifier);
-
- Standard_Real Control(const Handle(BRepAdaptor_HSurface)& caro,
- const Standard_Real defface,
- BRepMeshCol::ListOfVertex& inter,
- BRepMeshCol::ListOfInteger& badTri,
- BRepMeshCol::ListOfInteger& nulTri,
- BRepMesh_Delaun& trigu,
- const Standard_Boolean isfirst);
-
- void AddInShape(const TopoDS_Face& face,
- const Standard_Real defedge);
+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)
+ {
+ }
+
+ 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_Boolean IsSameUV;
+ Standard_Real MinDist;
+
+ N_HANDLE<TopoDSVExplorer> FirstVExtractor;
+ N_HANDLE<TopoDSVExplorer> LastVExtractor;
+ };
+
+ //! Structure keeps geometrical parameters of edge's PCurve.
+ //! Used for caching.
+ struct EdgePCurve
+ {
+ Handle(Geom2d_Curve) Curve2d;
+ Standard_Real FirstParam;
+ Standard_Real LastParam;
+ };
+
+ //! Fills structure of by attributes of the given edge.
+ //! @return TRUE on success, FALSE elsewhere.
+ Standard_Boolean getEdgeAttributes(
+ const TopoDS_Edge& theEdge,
+ const EdgePCurve& 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 EdgePCurve& 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(Geom2d_Curve)& theCurve2D,
+ const Standard_Real theEdgeDeflection,
+ EdgeAttributes& theAttributes);
+
+ //! 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);
+
+ //! 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);
private:
- Standard_Real myAngle;
- Standard_Real myDeflection;
- Standard_Real myDtotale;
- Standard_Boolean myWithShare;
- Standard_Boolean myInParallel;
- BRepMeshCol::DMapOfVertexInteger myVertices;
- BRepMeshCol::DMapOfShapePairOfPolygon myEdges;
- BRepMeshCol::DMapOfShapePairOfPolygon myInternaledges;
- Standard_Integer myNbLocat;
- BRepMeshCol::DMapOfIntegerPnt myLocation3d;
- Handle_BRepMesh_DataStructureOfDelaun myStructure;
- BRepMeshCol::DMapOfFaceAttribute myMapattrib;
- TColStd_IndexedMapOfInteger myVemap;
- BRepMeshCol::DMapOfIntegerListOfXY myLocation2d;
- Standard_Boolean myRelative;
- Standard_Boolean myShapetrigu;
- Standard_Boolean myInshape;
- BRepMesh_Status myFacestate;
- TopTools_DataMapOfShapeReal myMapdefle;
- TopTools_ListOfShape myNottriangulated;
- BRepMeshCol::Allocator myAllocator;
- TopTools_MutexForShapeProvider myMutexProvider;
+ TopoDS_Face myFace;
+ Standard_Real myAngle;
+ Standard_Real myDeflection;
+ Standard_Real myDtotale;
+ Standard_Boolean myWithShare;
+ Standard_Boolean myInParallel;
+ BRepMeshCol::DMapOfShapePairOfPolygon myEdges;
+ BRepMeshCol::DMapOfFaceAttribute myAttributes;
+ Standard_Boolean myRelative;
+ Standard_Boolean myShapetrigu;
+ Standard_Boolean myInshape;
+ TopTools_DataMapOfShapeReal myMapdefle;
+
+ // Data shared for whole shape
+ BRepMeshCol::DMapOfVertexInteger myBoundaryVertices;
+ BRepMeshCol::DMapOfIntegerPnt myBoundaryPoints;
+
+ // Fast access to attributes of current face
+ Handle(BRepMesh_FaceAttribute) myAttribute;
+ Handle(BRepMesh_DataStructureOfDelaun) myStructure;
+ BRepMeshCol::HIMapOfInteger myVertexEdgeMap;
+ BRepMeshCol::HDMapOfShapePairOfPolygon myInternalEdges;
+ TopTools_IndexedDataMapOfShapeListOfShape mySharedFaces;
};
DEFINE_STANDARD_HANDLE(BRepMesh_FastDiscret, Standard_Transient)
#include <BRepMesh_FastDiscretFace.hxx>
#include <BRepMesh_PairOfPolygon.hxx>
-#include <BRepMesh_Classifier.hxx>
#include <BRepMesh_ShapeTool.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <Poly_Triangulation.hxx>
#include <BRep_TVertex.hxx>
#include <BRep_Tool.hxx>
-#include <ElSLib.hxx>
#include <GeomLib.hxx>
#include <Geom_Surface.hxx>
#include <Geom_BSplineSurface.hxx>
#include <NCollection_Map.hxx>
#include <Bnd_Box2d.hxx>
-#define UVDEFLECTION 1.e-05
+#include <algorithm>
IMPLEMENT_STANDARD_HANDLE (BRepMesh_FastDiscretFace, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FastDiscretFace, Standard_Transient)
return (n? (result / (Standard_Real) n) : -1.);
}
+namespace {
+
+ //! Auxiliary class used to extract geometrical parameters of fixed TopoDS_Vertex.
+ class FixedVExplorer
+ {
+ public:
+
+ DEFINE_STANDARD_ALLOC
+
+ FixedVExplorer(const TopoDS_Vertex& theVertex)
+ : myVertex(theVertex)
+ {
+ }
+
+ const TopoDS_Vertex& Vertex() const
+ {
+ return myVertex;
+ }
+
+ Standard_Boolean IsSameUV() const
+ {
+ return Standard_False;
+ }
+
+ TopoDS_Vertex SameVertex() const
+ {
+ return TopoDS_Vertex();
+ }
+
+ virtual gp_Pnt Point() const
+ {
+ return BRep_Tool::Pnt(myVertex);
+ }
+
+ private:
+
+ void operator =(const FixedVExplorer& /*theOther*/)
+ {
+ }
+
+ private:
+ const TopoDS_Vertex& myVertex;
+ };
+}
+
+
//=======================================================================
//function : BRepMesh_FastDiscretFace
//purpose :
BRepMesh_FastDiscretFace::BRepMesh_FastDiscretFace
(const Standard_Real theAngle,
const Standard_Boolean theWithShare) :
- myAngle(theAngle), myWithShare(theWithShare), myNbLocat(0),
+ myAngle(theAngle), myWithShare(theWithShare),
myInternalVerticesMode(Standard_True)
{
myAllocator = new NCollection_IncAllocator(64000);
//function : Add(face)
//purpose :
//=======================================================================
-
-void BRepMesh_FastDiscretFace::Add(const TopoDS_Face& theFace,
- const Handle(BRepMesh_FaceAttribute)& theAttrib,
- const TopTools_DataMapOfShapeReal& theMapDefle,
- const TopTools_MutexForShapeProvider& theMutexProvider)
+void BRepMesh_FastDiscretFace::Add(const Handle(BRepMesh_FaceAttribute)& theAttribute)
{
-#ifndef DEB_MESH
- try
- {
- OCC_CATCH_SIGNALS
-#endif
- TopoDS_Face face = theFace;
- TopLoc_Location loc;
-
- const Handle(Poly_Triangulation)& aFaceTrigu = BRep_Tool::Triangulation(face, loc);
- if ( aFaceTrigu.IsNull() )
- return;
+ if (!theAttribute->IsValid())
+ return;
- myAttrib = theAttrib;
- face.Orientation(TopAbs_FORWARD);
- myStructure.Nullify();
- Handle(NCollection_IncAllocator) anAlloc = Handle(NCollection_IncAllocator)::DownCast(myAllocator);
- anAlloc->Reset(Standard_False);
- myStructure=new BRepMesh_DataStructureOfDelaun(anAlloc);
-
- Standard_Real umax = myAttrib->GetUMax();
- Standard_Real umin = myAttrib->GetUMin();
- Standard_Real vmax = myAttrib->GetVMax();
- Standard_Real vmin = myAttrib->GetVMin();
+ myAttribute = theAttribute;
+ myStructure = myAttribute->ChangeStructure();
+ myVertexEdgeMap = myAttribute->ChangeVertexEdgeMap();
+ myClassifier = myAttribute->ChangeClassifier();
+ mySurfacePoints = myAttribute->ChangeSurfacePoints();
- Standard_Real aTolU = Max( Precision::PConfusion(), (umax - umin) * UVDEFLECTION );
- Standard_Real aTolV = Max( Precision::PConfusion(), (vmax - vmin) * UVDEFLECTION );
- Standard_Real uCellSize = 14 * aTolU;
- Standard_Real vCellSize = 14 * aTolV;
+ Standard_Real aTolU = myAttribute->ToleranceU();
+ Standard_Real aTolV = myAttribute->ToleranceV();
+ Standard_Real uCellSize = 14.0 * aTolU;
+ Standard_Real vCellSize = 14.0 * aTolV;
- myStructure->Data().SetCellSize ( uCellSize, vCellSize );
- myStructure->Data().SetTolerance( aTolU, aTolV );
+ const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
+ GeomAbs_SurfaceType thetype = gFace->GetType();
+ Standard_Integer i = 1;
- BRepAdaptor_Surface BS(face, Standard_False);
- Handle(BRepAdaptor_HSurface) gFace = new BRepAdaptor_HSurface(BS);
-
- GeomAbs_SurfaceType thetype;
- thetype = BS.GetType();
-
- TopAbs_Orientation orFace = face.Orientation();
-
- if (!myWithShare)
- myVertices.Clear();
-
- myListver.Clear();
- myVemap.Clear();
- myLocation2d.Clear();
- myInternaledges.Clear();
-
- Standard_Integer i = 1;
- Standard_Integer ipn = 0;
-
- TopoDS_Iterator exW(face);
- for (; exW.More(); exW.Next()) {
- const TopoDS_Shape& aWire = exW.Value();
- if (aWire.ShapeType() != TopAbs_WIRE)
- continue;
- TopoDS_Iterator ex(aWire);
- for(; ex.More(); ex.Next()) {
- const TopoDS_Edge& edge = TopoDS::Edge(ex.Value());
- if(edge.IsNull())
- continue;
- RestoreStructureFromTriangulation(edge, face, gFace, aFaceTrigu,
- theMapDefle(edge), loc, theMutexProvider);
- }
- }
-
- ////////////////////////////////////////////////////////////
- //add internal vertices after self-intersection check
- Standard_Integer nbVertices = 0;
- if(myInternalVerticesMode) {
- for(TopExp_Explorer ex(face,TopAbs_VERTEX ,TopAbs_EDGE); ex.More(); ex.Next()) {
- const TopoDS_Vertex& aVert = TopoDS::Vertex(ex.Current());
- Add(aVert,face,gFace);
- }
- nbVertices = myVemap.Extent();
- }
-
- // essai de determination de la longueur vraie:
- // 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 deltaX = myAttrib->GetDeltaX();
- Standard_Real deltaY = myAttrib->GetDeltaY();
-
- BRepMeshCol::Array1OfInteger tabvert_corr(1, nbVertices);
- gp_Pnt2d p2d;
-
- // Check the necessity to fill the map of parameters
- const Standard_Boolean useUVParam = (thetype == GeomAbs_Torus ||
- thetype == GeomAbs_BezierSurface ||
- thetype == GeomAbs_BSplineSurface);
- myUParam.Clear();
- myVParam.Clear();
-
- BRepMesh_VertexTool aMoveNodes(myVemap.Extent(), myAllocator);
-
- aMoveNodes.SetCellSize ( uCellSize / deltaX, vCellSize / deltaY);
- aMoveNodes.SetTolerance( aTolU / deltaX, aTolV / deltaY);
+ ////////////////////////////////////////////////////////////
+ //add internal vertices after self-intersection check
+ Standard_Integer nbVertices = 0;
+ if ( myInternalVerticesMode )
+ {
+ TopExp_Explorer anExplorer(myAttribute->Face(), TopAbs_VERTEX, TopAbs_EDGE);
+ for ( ; anExplorer.More(); anExplorer.Next() )
+ add(TopoDS::Vertex(anExplorer.Current()));
+ nbVertices = myVertexEdgeMap->Extent();
+ }
- for (i = 1; i <= myStructure->NbNodes(); i++)
- {
- const BRepMesh_Vertex& v = myStructure->GetNode(i);
- p2d = v.Coord();
- if (useUVParam) {
- myUParam.Add(p2d.X());
- myVParam.Add(p2d.Y());
- }
- gp_XY res;
- res.SetCoord((p2d.X() - umin ) / deltaX,
- (p2d.Y() - vmin ) / deltaY);
- BRepMesh_Vertex v_new(res,v.Location3d(),v.Movability());
- const BRepMeshCol::ListOfInteger& alist = myStructure->LinksConnectedTo(i);
- aMoveNodes.Add(v_new, alist);
- tabvert_corr(i) = i;
- }
- myStructure->ReplaceNodes(aMoveNodes);
-
- Standard_Boolean rajout;
-
- BRepMeshCol::HClassifier& classifier = theAttrib->GetClassifier();
+ // essai de determination de la longueur vraie:
+ // 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;
- switch (thetype)
- {
- case GeomAbs_Sphere:
- case GeomAbs_Torus:
- rajout = Standard_True;
- break;
- default:
- rajout = Standard_False;
- }
+ const Standard_Real deltaX = myAttribute->GetDeltaX();
+ const Standard_Real deltaY = myAttribute->GetDeltaY();
- BRepMesh_Delaun trigu(myStructure, tabvert_corr, orFace==TopAbs_FORWARD);
-
- //removed all free edges from triangulation
- Standard_Integer nbLinks = myStructure->NbLinks();
- for( i = 1; i <= nbLinks; i++ )
- {
- if( myStructure->ElementsConnectedTo(i).Extent() < 1 )
- {
- BRepMesh_Edge& anEdge = (BRepMesh_Edge&)trigu.GetEdge(i);
- if ( anEdge.Movability() == BRepMesh_Deleted )
- continue;
+ BRepMeshCol::Array1OfInteger tabvert_corr(1, nbVertices);
- anEdge.SetMovability(BRepMesh_Free);
- myStructure->RemoveLink(i);
- }
- }
+ // Check the necessity to fill the map of parameters
+ const Standard_Boolean useUVParam = (thetype == GeomAbs_Torus ||
+ thetype == GeomAbs_BezierSurface ||
+ thetype == GeomAbs_BSplineSurface);
+ myUParam.Clear();
+ myVParam.Clear();
- Standard_Boolean isaline;
- isaline = ((umax-umin) < UVDEFLECTION) || ((vmax-vmin) < UVDEFLECTION);
-
- Standard_Real aDef = -1;
- if (!isaline && myStructure->ElementsOfDomain().Extent() > 0) {
- BRepMeshCol::ListOfInteger badTri, nulTri;
-
- if(!rajout)
- {
- aDef = Control(gFace, theAttrib->GetDefFace(), myListver, badTri, nulTri, trigu, Standard_True);
- if( aDef > theAttrib->GetDefFace() || aDef < 0.)
- rajout = Standard_True;
- }
+ BRepMesh_VertexTool aMoveNodes(nbVertices, myAllocator);
- if(!rajout) {
- if(useUVParam) {
- if(BS.IsUClosed()) {
- if(myVParam.Extent() > 2) {
- rajout = Standard_True;
- }
- }
- if(BS.IsVClosed()) {
- if(myUParam.Extent() > 2) {
- rajout = Standard_True;
- }
- }
- }
- }
+ aMoveNodes.SetCellSize ( uCellSize / deltaX, vCellSize / deltaY);
+ aMoveNodes.SetTolerance( aTolU / deltaX, aTolV / deltaY);
- if(rajout){
- InternalVertices(gFace, myListver, theAttrib->GetDefFace(), classifier);
-
- if (myListver.Extent() > 0) {
- BRepMeshCol::Array1OfVertexOfDelaun verttab(1, myListver.Extent());
- BRepMeshCol::ListOfVertex::Iterator itVer(myListver);
- ipn = 1;
- for (; itVer.More(); itVer.Next())
- verttab(ipn++) = itVer.Value();
- trigu.AddVertices(verttab);
- }
- //control internal points
- BRepMeshCol::ListOfVertex vvlist;
- aDef = Control(gFace, theAttrib->GetDefFace(), vvlist, badTri, nulTri, trigu, Standard_False);
- myListver.Append(vvlist);
- }
- }
+ for ( i = 1; i <= myStructure->NbNodes(); ++i )
+ {
+ const BRepMesh_Vertex& v = myStructure->GetNode(i);
+ gp_XY aPnt2d = v.Coord();
- //modify myStructure back
- aMoveNodes.SetCellSize ( uCellSize, vCellSize );
- aMoveNodes.SetTolerance( aTolU , aTolV );
- for (i = 1; i <= myStructure->NbNodes(); i++)
+ if (useUVParam)
{
- const BRepMesh_Vertex& v = myStructure->GetNode(i);
- p2d = v.Coord();
- gp_XY res;
- res.SetCoord(p2d.X() * deltaX + umin, p2d.Y() * deltaY + vmin);
- BRepMesh_Vertex v_new(res,v.Location3d(),v.Movability());
- const BRepMeshCol::ListOfInteger& alist = myStructure->LinksConnectedTo(i);
- aMoveNodes.Add(v_new, alist);
+ myUParam.Add(aPnt2d.X());
+ myVParam.Add(aPnt2d.Y());
}
- myStructure->ReplaceNodes(aMoveNodes);
-
- AddInShape(face, (aDef < 0.0)? theAttrib->GetDefFace() : aDef, theMutexProvider);
-#ifndef DEB_MESH
- }
- catch(Standard_Failure)
- {
- BRepMesh_ShapeTool::NullifyFace(theFace);
+
+ aPnt2d = myAttribute->Scale(aPnt2d, Standard_True);
+ BRepMesh_Vertex v_new(aPnt2d, v.Location3d(), v.Movability());
+ const BRepMeshCol::ListOfInteger& alist = myStructure->LinksConnectedTo(i);
+ aMoveNodes.Add(v_new, alist);
+ tabvert_corr(i) = i;
}
-#endif // DEB_MESH
- myStructure.Nullify();
- myAttrib.Nullify();
-}
+ myStructure->ReplaceNodes(aMoveNodes);
-//=======================================================================
-//function : RestoreStructureFromTriangulation(edge)
-//purpose : Restore structure of Delaun from triangulation on face
-//=======================================================================
-Standard_Boolean BRepMesh_FastDiscretFace::RestoreStructureFromTriangulation
- (const TopoDS_Edge& theEdge,
- const TopoDS_Face& theFace,
- const Handle(BRepAdaptor_HSurface)& theSurf,
- const Handle(Poly_Triangulation)& theTrigu,
- const Standard_Real theDefEdge,
- const TopLoc_Location& theLoc,
- const TopTools_MutexForShapeProvider& theMutexProvider)
-{
- // 2d vertex indices
- TopAbs_Orientation orEdge = theEdge.Orientation();
- // Get end points on 2d curve
- gp_Pnt2d uvFirst, uvLast;
- // oan: changes for right restoring of triangulation data from face & edges
- Handle(Poly_PolygonOnTriangulation) Poly;
+ Standard_Boolean rajout =
+ (thetype == GeomAbs_Sphere || thetype == GeomAbs_Torus);
- {
- // lock mutex during querying data from edge curves to prevent parallel change of the same data
- Standard_Mutex* aMutex = theMutexProvider.GetMutex(theEdge);
- Standard_Mutex::Sentry aSentry (aMutex);
+ BRepMesh_Delaun trigu(myStructure, tabvert_corr);
- Poly = BRep_Tool::PolygonOnTriangulation(theEdge, theTrigu, theLoc);
- if (Poly.IsNull() || !Poly->HasParameters())
- return Standard_False;
+ //removed all free edges from triangulation
+ const Standard_Integer nbLinks = myStructure->NbLinks();
+ for( i = 1; i <= nbLinks; i++ )
+ {
+ if( myStructure->ElementsConnectedTo(i).Extent() < 1 )
+ {
+ BRepMesh_Edge& anEdge = (BRepMesh_Edge&)trigu.GetEdge(i);
+ if ( anEdge.Movability() == BRepMesh_Deleted )
+ continue;
- BRep_Tool::UVPoints(theEdge, theFace, uvFirst, uvLast);
+ anEdge.SetMovability(BRepMesh_Free);
+ myStructure->RemoveLink(i);
+ }
}
- // Get vertices
- TopoDS_Vertex pBegin, pEnd;
- TopExp::Vertices(theEdge,pBegin,pEnd);
-
- const Standard_Boolean sameUV =
- uvFirst.IsEqual(uvLast, Precision::PConfusion());
+ const Standard_Real umax = myAttribute->GetUMax();
+ const Standard_Real umin = myAttribute->GetUMin();
+ const Standard_Real vmax = myAttribute->GetVMax();
+ const Standard_Real vmin = myAttribute->GetVMin();
- const TColgp_Array1OfPnt2d& UVNodes = theTrigu->UVNodes();
- const TColgp_Array1OfPnt& Nodes = theTrigu->Nodes();
- const TColStd_Array1OfInteger& Indices = Poly->Nodes();
-
- const Standard_Integer nbnodes = Indices.Length();
- TColStd_Array1OfInteger NewNodes(1, nbnodes);
-
- gp_Pnt P3d;
- gp_XY anUV;
+ Standard_Boolean isaline =
+ ((umax - umin) < Precision::PConfusion() ||
+ (vmax - vmin) < Precision::PConfusion());
- // Process first vertex
- Standard_Integer ipf;
- if (myVertices.IsBound(pBegin))
+ Standard_Real aDef = -1;
+ if ( !isaline && myStructure->ElementsOfDomain().Extent() > 0 )
{
- ipf = myVertices.Find(pBegin);
- }
- else
- {
- if (sameUV && myVertices.IsBound(pEnd))
+ BRepMeshCol::ListOfVertex aNewVertices;
+ if ( !rajout )
{
- ipf = myVertices.Find(pEnd);
- }
- else
- {
- P3d = Nodes(Indices(1));
- if (!theLoc.IsIdentity())
- P3d.Transform(theLoc.Transformation());
- myNbLocat++;
- myLocation3d.Bind(myNbLocat, P3d);
- ipf = myNbLocat;
- }
- myVertices.Bind(pBegin,ipf);
- }
-
- //Controle vertice tolerances
- gp_Pnt pFirst = theSurf->Value(uvFirst.X(), uvFirst.Y());
- gp_Pnt pLast = theSurf->Value(uvLast.X(), uvLast.Y());
-
- Standard_Real mindist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(pBegin)),
- pLast.Distance(BRep_Tool::Pnt(pEnd)));
+ aDef = control(aNewVertices, trigu, Standard_True);
- if (mindist < BRep_Tool::Tolerance(pBegin) ||
- mindist < BRep_Tool::Tolerance(pEnd) ) mindist = theDefEdge;
-
- anUV = BRepMesh_ShapeTool::FindUV(ipf, uvFirst,
- pBegin, mindist, myAttrib, theSurf, myLocation2d);
-
- Standard_Integer iv1, isv1;
- BRepMesh_Vertex vf(anUV, ipf, BRepMesh_Frontier);
- iv1 = myStructure->AddNode(vf);
- isv1 = myVemap.FindIndex(iv1);
- if (isv1 == 0)
- isv1 = myVemap.Add(iv1);
- NewNodes(1) = isv1;
-
- // Process last vertex
- Standard_Integer ipl, ivl;
- if (pEnd.IsSame(pBegin))
- {
- ipl = ipf;
- }
- else
- {
- if (myVertices.IsBound(pEnd))
- {
- ipl = myVertices.Find(pEnd);
+ if( aDef > myAttribute->GetDefFace() || aDef < 0.)
+ rajout = Standard_True;
}
- else
+
+ if ( !rajout && useUVParam )
{
- if (sameUV)
- {
- ipl = ipf;
- ivl = iv1;
- }
- else
+ if ( myVParam.Extent() > 2 &&
+ (gFace->IsUClosed() ||
+ gFace->IsVClosed()))
{
- P3d = Nodes(Indices(nbnodes));
- if (!theLoc.IsIdentity())
- P3d.Transform(theLoc.Transformation());
- myNbLocat++;
- myLocation3d.Bind(myNbLocat, P3d);
- ipl = myNbLocat;
+ rajout = Standard_True;
}
- myVertices.Bind(pEnd,ipl);
}
- }
- anUV = BRepMesh_ShapeTool::FindUV(ipl, uvLast,
- pEnd, mindist, myAttrib, theSurf, myLocation2d);
+ if ( rajout )
+ {
+ insertInternalVertices(aNewVertices, trigu);
- BRepMesh_Vertex vl(anUV, ipl, BRepMesh_Frontier);
-
- Standard_Integer isvl;
- ivl = myStructure->AddNode(vl);
- isvl = myVemap.FindIndex(ivl);
- if (isvl == 0)
- isvl = myVemap.Add(ivl);
- NewNodes(nbnodes) = isvl;
-
- BRepMesh_Vertex v;
-
- Standard_Integer i;
- for (i = 2; i < nbnodes; i++)
- {
- // Record 3d point
- P3d = Nodes(Indices(i));
- if (!theLoc.IsIdentity())
- P3d.Transform(theLoc.Transformation());
- myNbLocat++;
- myLocation3d.Bind(myNbLocat, P3d);
-
- // Record 2d point
- anUV = UVNodes(Indices(i)).Coord();
-
- Standard_Integer iv2, isv;
- v.Initialize(anUV, myNbLocat, BRepMesh_Frontier);
- iv2 = myStructure->AddNode(v);
- isv = myVemap.FindIndex(iv2);
- if (isv == 0)
- isv = myVemap.Add(iv2);
- NewNodes(i) = isv;
-
- //add links
- if (orEdge == TopAbs_FORWARD)
- myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Frontier));
- else if (orEdge == TopAbs_REVERSED)
- myStructure->AddLink(BRepMesh_Edge(iv2,iv1,BRepMesh_Frontier));
- else if (orEdge == TopAbs_INTERNAL)
- myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Fixed));
- iv1 = iv2;
- }
-
- // last point
- if (iv1 != ivl) {
- if (orEdge == TopAbs_FORWARD)
- myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Frontier));
- else if (orEdge == TopAbs_REVERSED)
- myStructure->AddLink(BRepMesh_Edge(ivl,iv1,BRepMesh_Frontier));
- else if (orEdge == TopAbs_INTERNAL)
- myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Fixed));
- }
-
- Handle(Poly_PolygonOnTriangulation) P1 =
- new Poly_PolygonOnTriangulation(NewNodes, Poly->Parameters()->Array1());
- P1->Deflection(theDefEdge);
- if (myInternaledges.IsBound(theEdge))
- {
- BRepMesh_PairOfPolygon& pair = myInternaledges.ChangeFind(theEdge);
- if (theEdge.Orientation() == TopAbs_REVERSED)
- pair.Append(P1);
- else
- pair.Prepend(P1);
+ //control internal points
+ aDef = control(aNewVertices, trigu, Standard_False);
+ }
}
- else
+
+ //modify myStructure back
+ aMoveNodes.SetCellSize ( uCellSize, vCellSize );
+ aMoveNodes.SetTolerance( aTolU , aTolV );
+
+ for ( i = 1; i <= myStructure->NbNodes(); ++i )
{
- BRepMesh_PairOfPolygon pair1;
- pair1.Append(P1);
- myInternaledges.Bind(theEdge, pair1);
+ const BRepMesh_Vertex& v = myStructure->GetNode(i);
+ gp_XY aPnt2d = myAttribute->Scale(v.Coord(), Standard_False);
+ BRepMesh_Vertex v_new(aPnt2d, v.Location3d(), v.Movability());
+ const BRepMeshCol::ListOfInteger& alist = myStructure->LinksConnectedTo(i);
+ aMoveNodes.Add(v_new, alist);
+
+ // Register internal nodes used in triangulation
+ if (!alist.IsEmpty() && myVertexEdgeMap->FindIndex(i) == 0)
+ myVertexEdgeMap->Add(i);
}
+ myStructure->ReplaceNodes(aMoveNodes);
- return Standard_True;
+ if (!(aDef < 0.))
+ myAttribute->SetDefFace(aDef);
}
//=======================================================================
-//function : InternalVertices
+//function : addVerticesToMesh
//purpose :
//=======================================================================
+Standard_Boolean BRepMesh_FastDiscretFace::addVerticesToMesh(
+ const BRepMeshCol::ListOfVertex& theVertices,
+ BRepMesh_Delaun& theMeshBuilder)
+{
+ if (theVertices.IsEmpty())
+ return Standard_False;
+
+ BRepMeshCol::Array1OfVertexOfDelaun aArrayOfNewVertices(1, theVertices.Extent());
+ BRepMeshCol::ListOfVertex::Iterator aVertexIt(theVertices);
+ for (Standard_Integer aVertexId = 0; aVertexIt.More(); aVertexIt.Next())
+ aArrayOfNewVertices(++aVertexId) = aVertexIt.Value();
+
+ theMeshBuilder.AddVertices(aArrayOfNewVertices);
+ return Standard_True;
+}
+//=======================================================================
+//function : insertInternalVertices
+//purpose :
+//=======================================================================
static void filterParameters(const BRepMeshCol::IMapOfReal& theParams,
const Standard_Real theMinDist,
const Standard_Real theFilterDist,
//add last point if required
if(aParamArray(anInitLen)-theParams(aParamLength) > theMinDist)
{
- aParamTmp.Append(aParamArray(anInitLen));
+ aParamTmp.Append(aParamArray(anInitLen));
aParamLength++;
}
}
}
-void BRepMesh_FastDiscretFace::InternalVertices(const Handle(BRepAdaptor_HSurface)& theCaro,
- BRepMeshCol::ListOfVertex& theInternalV,
- const Standard_Real theDefFace,
- const BRepMeshCol::HClassifier& theClassifier)
+void BRepMesh_FastDiscretFace::insertInternalVertices(
+ BRepMeshCol::ListOfVertex& theNewVertices,
+ BRepMesh_Delaun& theMeshBuilder)
{
- BRepMesh_Vertex newV;
- gp_Pnt2d p2d;
- gp_Pnt p3d;
+ const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
+ switch (gFace->GetType())
+ {
+ case GeomAbs_Sphere:
+ insertInternalVerticesSphere(theNewVertices);
+ break;
+
+ case GeomAbs_Cylinder:
+ insertInternalVerticesCylinder(theNewVertices);
+ break;
+
+ case GeomAbs_Cone:
+ insertInternalVerticesCone(theNewVertices);
+ break;
+
+ case GeomAbs_Torus:
+ insertInternalVerticesTorus(theNewVertices);
+ break;
+
+ case GeomAbs_BezierSurface:
+ case GeomAbs_BSplineSurface:
+ insertInternalVerticesBSpline(theNewVertices);
+ break;
+
+ default:
+ insertInternalVerticesOther(theNewVertices);
+ break;
+ }
- // work following the type of surface
- const BRepAdaptor_Surface& BS = *(BRepAdaptor_Surface*)&(theCaro->Surface());
- GeomAbs_SurfaceType thetype = theCaro->GetType();
-
- Standard_Real umax = myAttrib->GetUMax();
- Standard_Real umin = myAttrib->GetUMin();
- Standard_Real vmax = myAttrib->GetVMax();
- Standard_Real vmin = myAttrib->GetVMin();
- Standard_Real deltaX = myAttrib->GetDeltaX();
- Standard_Real deltaY = myAttrib->GetDeltaY();
-
- if (thetype == GeomAbs_Sphere)
- {
- gp_Sphere S = BS.Sphere();
- const Standard_Real R = S.Radius();
-
- // Calculate parameters for iteration in V direction
- Standard_Real Dv = 1.0 - (theDefFace/R);
- if (Dv < 0.0) Dv = 0.0;
- Standard_Real oldDv = 2.0 * ACos (Dv);
- Dv = .7 * oldDv; //.7 ~= sqrt(2.) - Dv is hypotenuse of triangle when oldDv is legs
- const Standard_Real sv = vmax - vmin;
- Dv = sv/((Standard_Integer)(sv/Dv) + 1);
- const Standard_Real pasvmax = vmax-Dv*0.5;
-
- //Du can be defined from relation: 2*r*Sin(Du/2) = 2*R*Sin(Dv/2), r = R*Cos(v)
- //here approximate relation r*Du = R*Dv is used
-
- Standard_Real Du, pasu, pasv; //, ru;
- const Standard_Real su = umax-umin;
- Standard_Boolean Shift = Standard_False;
- for (pasv = vmin + Dv; pasv < pasvmax; pasv += Dv)
+ addVerticesToMesh(theNewVertices, theMeshBuilder);
+}
+
+//=======================================================================
+//function : insertInternalVerticesSphere
+//purpose :
+//=======================================================================
+void BRepMesh_FastDiscretFace::insertInternalVerticesSphere(
+ BRepMeshCol::ListOfVertex& theNewVertices)
+{
+ const Standard_Real umax = myAttribute->GetUMax();
+ const Standard_Real umin = myAttribute->GetUMin();
+ const Standard_Real vmax = myAttribute->GetVMax();
+ const Standard_Real vmin = myAttribute->GetVMin();
+
+ gp_Sphere S = myAttribute->Surface()->Sphere();
+ const Standard_Real R = S.Radius();
+
+ // Calculate parameters for iteration in V direction
+ Standard_Real Dv = 1.0 - (myAttribute->GetDefFace() / R);
+ if (Dv < 0.0) Dv = 0.0;
+ Standard_Real oldDv = 2.0 * ACos(Dv);
+ Dv = .7 * oldDv; //.7 ~= sqrt(2.) - Dv is hypotenuse of triangle when oldDv is legs
+ const Standard_Real sv = vmax - vmin;
+ Dv = sv / ((Standard_Integer)(sv / Dv) + 1);
+ const Standard_Real pasvmax = vmax - Dv*0.5;
+
+ //Du can be defined from relation: 2*r*Sin(Du/2) = 2*R*Sin(Dv/2), r = R*Cos(v)
+ //here approximate relation r*Du = R*Dv is used
+
+ Standard_Real Du, pasu, pasv; //, ru;
+ const Standard_Real su = umax - umin;
+ Standard_Boolean Shift = Standard_False;
+ for (pasv = vmin + Dv; pasv < pasvmax; pasv += Dv)
+ {
+ // Calculate parameters for iteration in U direction
+ // 1.-.365*pasv*pasv is simple approximation of Cos(pasv)
+ // with condition that it gives ~.1 when pasv = pi/2
+ Du = Dv / (1. - .365*pasv*pasv);
+ Du = su / ((Standard_Integer)(su / Du) + 1);
+ Shift = !Shift;
+ const Standard_Real d = (Shift) ? Du*.5 : 0.;
+ const Standard_Real pasumax = umax - Du*0.5 + d;
+ for (pasu = umin + Du - d; pasu < pasumax; pasu += Du)
{
- // Calculate parameters for iteration in U direction
- // 1.-.365*pasv*pasv is simple approximation of Cos(pasv)
- // with condition that it gives ~.1 when pasv = pi/2
- Du = Dv/(1.-.365*pasv*pasv);
- Du = su/((Standard_Integer)(su/Du) + 1);
- Shift = !Shift;
- const Standard_Real d = (Shift)? Du*.5 : 0.;
- const Standard_Real pasumax = umax-Du*0.5 + d;
- for (pasu = umin + Du - d; pasu < pasumax; pasu += Du)
- {
- if (theClassifier->Perform(gp_Pnt2d(pasu, pasv)) == TopAbs_IN)
- {
- // Record 3d point
-#ifdef DEB_MESH_CHRONO
- D0Internal++;
-#endif
- ElSLib::D0(pasu, pasv, S, p3d);
- myNbLocat++;
- myLocation3d.Bind(myNbLocat, p3d);
- // Record 2d point
- p2d.SetCoord((pasu-umin)/deltaX, (pasv-vmin)/deltaY);
- newV.Initialize(p2d.XY(), myNbLocat, BRepMesh_Free);
- theInternalV.Append(newV);
- }
- }
+ tryToInsertAnalyticVertex(gp_Pnt2d(pasu, pasv), S, theNewVertices);
}
}
- else if (thetype == GeomAbs_Cylinder)
- {
- gp_Cylinder S = BS.Cylinder();
- const Standard_Real R = S.Radius();
+}
- // Calculate parameters for iteration in U direction
- Standard_Real Du = 1.0 - (theDefFace/R);
- if (Du < 0.0) Du = 0.0;
- Du = 2.0 * ACos (Du);
- if (Du > myAngle) Du = myAngle;
- const Standard_Real su = umax - umin;
- const Standard_Integer nbU = (Standard_Integer)(su/Du);
- Du = su/(nbU+1);
-
- // Calculate parameters for iteration in V direction
- const Standard_Real sv = vmax - vmin;
- Standard_Integer nbV = (Standard_Integer)( nbU*sv/(su*R) );
- nbV = Min(nbV, 100*nbU);
- Standard_Real Dv = sv/(nbV+1);
-
- Standard_Real pasu, pasv, pasvmax = vmax-Dv*0.5, pasumax = umax-Du*0.5;
- for (pasv = vmin + Dv; pasv < pasvmax; pasv += Dv) {
- for (pasu = umin + Du; pasu < pasumax; pasu += Du) {
- if (theClassifier->Perform(gp_Pnt2d(pasu, pasv)) == TopAbs_IN)
- {
- // Record 3d point
- ElSLib::D0(pasu, pasv, S, p3d);
- myNbLocat++;
- myLocation3d.Bind(myNbLocat, p3d);
- // Record 2d point
- p2d.SetCoord((pasu-umin)/deltaX, (pasv-vmin)/deltaY);
- newV.Initialize(p2d.XY(), myNbLocat, BRepMesh_Free);
- theInternalV.Append(newV);
- }
- }
+//=======================================================================
+//function : insertInternalVerticesCylinder
+//purpose :
+//=======================================================================
+void BRepMesh_FastDiscretFace::insertInternalVerticesCylinder(
+ BRepMeshCol::ListOfVertex& theNewVertices)
+{
+ const Standard_Real umax = myAttribute->GetUMax();
+ const Standard_Real umin = myAttribute->GetUMin();
+ const Standard_Real vmax = myAttribute->GetVMax();
+ const Standard_Real vmin = myAttribute->GetVMin();
+
+ gp_Cylinder S = myAttribute->Surface()->Cylinder();
+ const Standard_Real R = S.Radius();
+
+ // Calculate parameters for iteration in U direction
+ Standard_Real Du = 1.0 - (myAttribute->GetDefFace() / R);
+ if (Du < 0.0) Du = 0.0;
+ Du = 2.0 * ACos(Du);
+ if (Du > myAngle) Du = myAngle;
+ const Standard_Real su = umax - umin;
+ const Standard_Integer nbU = (Standard_Integer)(su / Du);
+ Du = su / (nbU + 1);
+
+ // Calculate parameters for iteration in V direction
+ const Standard_Real sv = vmax - vmin;
+ Standard_Integer nbV = (Standard_Integer)(nbU*sv / (su*R));
+ nbV = Min(nbV, 100 * nbU);
+ Standard_Real Dv = sv / (nbV + 1);
+
+ Standard_Real pasu, pasv, pasvmax = vmax - Dv*0.5, pasumax = umax - Du*0.5;
+ for (pasv = vmin + Dv; pasv < pasvmax; pasv += Dv)
+ {
+ for (pasu = umin + Du; pasu < pasumax; pasu += Du)
+ {
+ tryToInsertAnalyticVertex(gp_Pnt2d(pasu, pasv), S, theNewVertices);
}
}
- else if (thetype == GeomAbs_Cone)
+}
+
+//=======================================================================
+//function : insertInternalVerticesCone
+//purpose :
+//=======================================================================
+void BRepMesh_FastDiscretFace::insertInternalVerticesCone(
+ BRepMeshCol::ListOfVertex& theNewVertices)
+{
+ const Standard_Real umax = myAttribute->GetUMax();
+ const Standard_Real umin = myAttribute->GetUMin();
+ const Standard_Real vmax = myAttribute->GetVMax();
+ const Standard_Real vmin = myAttribute->GetVMin();
+
+ Standard_Real R, RefR, SAng;
+ gp_Cone C = myAttribute->Surface()->Cone();
+ RefR = C.RefRadius();
+ SAng = C.SemiAngle();
+ R = Max(Abs(RefR + vmin*Sin(SAng)), Abs(RefR + vmax*Sin(SAng)));
+ Standard_Real Du, Dv, pasu, pasv;
+ Du = Max(1.0e0 - (myAttribute->GetDefFace() / R), 0.0e0);
+ Du = (2.0 * ACos(Du));
+ Standard_Integer nbU = (Standard_Integer)((umax - umin) / Du);
+ Standard_Integer nbV = (Standard_Integer)(nbU*(vmax - vmin) / ((umax - umin)*R));
+ Du = (umax - umin) / (nbU + 1);
+ Dv = (vmax - vmin) / (nbV + 1);
+
+ Standard_Real pasvmax = vmax - Dv*0.5, pasumax = umax - Du*0.5;
+ for (pasv = vmin + Dv; pasv < pasvmax; pasv += Dv)
{
- Standard_Real R, RefR, SAng;
- gp_Cone C = BS.Cone();
- RefR = C.RefRadius();
- SAng = C.SemiAngle();
- R = Max(Abs(RefR+vmin*Sin(SAng)), Abs(RefR+vmax*Sin(SAng)));
- Standard_Real Du, Dv, pasu, pasv;
- Du = Max(1.0e0 - (theDefFace/R),0.0e0);
- Du = (2.0 * ACos (Du));
- Standard_Integer nbU = (Standard_Integer) ( (umax-umin)/Du );
- Standard_Integer nbV = (Standard_Integer) ( nbU*(vmax-vmin)/((umax-umin)*R) );
- Du = (umax-umin)/(nbU+1);
- Dv = (vmax-vmin)/(nbV+1);
-
- Standard_Real pasvmax = vmax-Dv*0.5, pasumax = umax-Du*0.5;
- for (pasv = vmin + Dv; pasv < pasvmax; pasv += Dv) {
- for (pasu = umin + Du; pasu < pasumax; pasu += Du) {
- if (theClassifier->Perform(gp_Pnt2d(pasu, pasv)) == TopAbs_IN)
- {
- // Record 3d point
- ElSLib::D0(pasu, pasv, C, p3d);
- myNbLocat++;
- myLocation3d.Bind(myNbLocat, p3d);
- // Record 2d point
- p2d.SetCoord((pasu-umin)/deltaX, (pasv-vmin)/deltaY);
- newV.Initialize(p2d.XY(), myNbLocat, BRepMesh_Free);
- theInternalV.Append(newV);
- }
- }
+ for (pasu = umin + Du; pasu < pasumax; pasu += Du)
+ {
+ tryToInsertAnalyticVertex(gp_Pnt2d(pasu, pasv), C, theNewVertices);
}
}
- else if (thetype == GeomAbs_Torus)
+}
+
+//=======================================================================
+//function : insertInternalVerticesTorus
+//purpose :
+//=======================================================================
+void BRepMesh_FastDiscretFace::insertInternalVerticesTorus(
+ BRepMeshCol::ListOfVertex& theNewVertices)
+{
+ const Standard_Real umax = myAttribute->GetUMax();
+ const Standard_Real umin = myAttribute->GetUMin();
+ const Standard_Real vmax = myAttribute->GetVMax();
+ const Standard_Real vmin = myAttribute->GetVMin();
+ const Standard_Real deltaX = myAttribute->GetDeltaX();
+ const Standard_Real deltaY = myAttribute->GetDeltaY();
+ const Standard_Real aDefFace = myAttribute->GetDefFace();
+
+ gp_Torus T = myAttribute->Surface()->Torus();
+
+ Standard_Boolean insert;
+ Standard_Integer i, j, ParamULength, ParamVLength;
+ Standard_Real pp, pasu, pasv;
+ Standard_Real r = T.MinorRadius(), R = T.MajorRadius();
+
+ BRepMeshCol::SequenceOfReal ParamU, ParamV;
+
+ Standard_Real Du, Dv;//, pasu, pasv;
+ Dv = Max(1.0e0 - (aDefFace / r), 0.0e0);
+ Standard_Real oldDv = 2.0 * ACos(Dv);
+ oldDv = Min(oldDv, myAngle);
+ Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
+ Dv = oldDv;
+
+ Standard_Integer nbV = Max((Standard_Integer)((vmax - vmin) / Dv), 2);
+ Dv = (vmax - vmin) / (nbV + 1);
+ Standard_Real ru = R + r;
+ if (ru > 1.e-16)
{
- gp_Torus T = BS.Torus();
+ Du = 2.0 * ACos(Max(1.0 - (aDefFace / ru), 0.0));
+ if (myAngle < Du) Du = myAngle;
+ Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
+ if (aa < gp::Resolution())
+ return;
+ Du *= Min(oldDv, Du) / aa;
+ }
+ else Du = Dv;
- Standard_Boolean insert;
- Standard_Integer i, j, ParamULength, ParamVLength;
- Standard_Real pp, pasu, pasv;
- Standard_Real r = T.MinorRadius(), R = T.MajorRadius();
+ Standard_Integer nbU = Max((Standard_Integer)((umax - umin) / Du), 2);
+ nbU = Max(nbU, (int)(nbV*(umax - umin)*R / ((vmax - vmin)*r) / 5.));
+ Du = (umax - umin) / (nbU + 1);
- BRepMeshCol::SequenceOfReal ParamU, ParamV;
+ if (R < r)
+ {
+ // As the points of edges are returned.
+ // in this case, the points are not representative.
- Standard_Real Du, Dv;//, pasu, pasv;
- Dv = Max(1.0e0 - (theDefFace/r),0.0e0) ;
- Standard_Real oldDv = 2.0 * ACos (Dv);
- oldDv = Min(oldDv, myAngle);
- Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
- Dv = oldDv;
-
- Standard_Integer nbV = Max((Standard_Integer)((vmax-vmin)/Dv), 2);
- Dv = (vmax-vmin)/(nbV+1);
- Standard_Real ru = R + r;
- if (ru > 1.e-16)
- {
- Du = 2.0 * ACos(Max(1.0 - (theDefFace/ru),0.0));
- if (myAngle < Du) Du = myAngle;
- Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
- if(aa < gp::Resolution())
- return;
- Du *= Min(oldDv, Du) / aa;
- }
- else Du = Dv;
-
- Standard_Integer nbU = Max((Standard_Integer)((umax-umin)/Du), 2);
- nbU = Max(nbU , (int)(nbV*(umax-umin)*R/((vmax-vmin)*r)/5.));
- Du = (umax-umin)/(nbU+1);
-
- if (R < r)
- {
- // As the points of edges are returned.
- // in this case, the points are not representative.
-
- //-- Choose DeltaX and DeltaY so that to avoid skipping points on the grid
- for (i = 0; i <= nbU; i++) ParamU.Append(umin + i* Du);
- }//R<r
- else //U if R > r
- {
- //--ofv: U
- // Number of mapped U parameters
- const Standard_Integer LenU = myUParam.Extent();
- // Fill array of U parameters
- TColStd_Array1OfReal Up(1,LenU);
- for (j = 1; j <= LenU; j++) Up(j) = myUParam(j);
-
- // Calculate DU, leave array of parameters
- Standard_Real aDU = FUN_CalcAverageDUV(Up,LenU);
- aDU = Max(aDU, Abs(umax - umin) / (Standard_Real) nbU / 2.);
- Standard_Real dUstd = Abs(umax - umin) / (Standard_Real) LenU;
- if (aDU > dUstd) dUstd = aDU;
- // Add U parameters
- for (j = 1; j <= LenU; j++)
- {
- pp = Up(j);
- insert = Standard_True;
- ParamULength = ParamU.Length();
- for (i = 1; i <= ParamULength && insert; i++)
- {
- insert = (Abs(ParamU.Value(i)-pp) > (0.5*dUstd));
- }
- if (insert) ParamU.Append(pp);
- }
- }
-
- //--ofv: V
- // Number of mapped V parameters
- const Standard_Integer LenV = myVParam.Extent();
- // Fill array of V parameters
- TColStd_Array1OfReal Vp(1,LenV);
- for (j = 1; j <= LenV; j++) Vp(j) = myVParam(j);
- // Calculate DV, sort array of parameters
- Standard_Real aDV = FUN_CalcAverageDUV(Vp,LenV);
- aDV = Max(aDV, Abs(vmax - vmin) / (Standard_Real) nbV / 2.);
-
- Standard_Real dVstd = Abs(vmax - vmin) / (Standard_Real) LenV;
- if (aDV > dVstd) dVstd = aDV;
- // Add V parameters
- for (j = 1; j <= LenV; j++)
+ //-- Choose DeltaX and DeltaY so that to avoid skipping points on the grid
+ for (i = 0; i <= nbU; i++) ParamU.Append(umin + i* Du);
+ }//R<r
+ else //U if R > r
+ {
+ //--ofv: U
+ // Number of mapped U parameters
+ const Standard_Integer LenU = myUParam.Extent();
+ // Fill array of U parameters
+ TColStd_Array1OfReal Up(1, LenU);
+ for (j = 1; j <= LenU; j++) Up(j) = myUParam(j);
+
+ // Calculate DU, leave array of parameters
+ Standard_Real aDU = FUN_CalcAverageDUV(Up, LenU);
+ aDU = Max(aDU, Abs(umax - umin) / (Standard_Real)nbU / 2.);
+ Standard_Real dUstd = Abs(umax - umin) / (Standard_Real)LenU;
+ if (aDU > dUstd) dUstd = aDU;
+ // Add U parameters
+ for (j = 1; j <= LenU; j++)
{
- pp = Vp(j);
-
+ pp = Up(j);
insert = Standard_True;
- ParamVLength = ParamV.Length();
- for (i = 1; i <= ParamVLength && insert; i++)
+ ParamULength = ParamU.Length();
+ for (i = 1; i <= ParamULength && insert; i++)
{
- insert = (Abs(ParamV.Value(i)-pp) > (dVstd*2./3.));
+ insert = (Abs(ParamU.Value(i) - pp) > (0.5*dUstd));
}
- if (insert) ParamV.Append(pp);
+ if (insert) ParamU.Append(pp);
}
+ }
- Standard_Integer Lu = ParamU.Length(), Lv = ParamV.Length();
- Standard_Real uminnew = umin+deltaY*0.1;
- Standard_Real vminnew = vmin+deltaX*0.1;
- Standard_Real umaxnew = umax-deltaY*0.1;
- Standard_Real vmaxnew = vmax-deltaX*0.1;
+ //--ofv: V
+ // Number of mapped V parameters
+ const Standard_Integer LenV = myVParam.Extent();
+ // Fill array of V parameters
+ TColStd_Array1OfReal Vp(1, LenV);
+ for (j = 1; j <= LenV; j++) Vp(j) = myVParam(j);
+ // Calculate DV, sort array of parameters
+ Standard_Real aDV = FUN_CalcAverageDUV(Vp, LenV);
+ aDV = Max(aDV, Abs(vmax - vmin) / (Standard_Real)nbV / 2.);
+
+ Standard_Real dVstd = Abs(vmax - vmin) / (Standard_Real)LenV;
+ if (aDV > dVstd) dVstd = aDV;
+ // Add V parameters
+ for (j = 1; j <= LenV; j++)
+ {
+ pp = Vp(j);
- for (i = 1; i <= Lu; i++)
+ insert = Standard_True;
+ ParamVLength = ParamV.Length();
+ for (i = 1; i <= ParamVLength && insert; i++)
{
- pasu = ParamU.Value(i);
- if (pasu >= uminnew && pasu < umaxnew)
+ insert = (Abs(ParamV.Value(i) - pp) > (dVstd*2. / 3.));
+ }
+ if (insert) ParamV.Append(pp);
+ }
+
+ Standard_Integer Lu = ParamU.Length(), Lv = ParamV.Length();
+ Standard_Real uminnew = umin + deltaY*0.1;
+ Standard_Real vminnew = vmin + deltaX*0.1;
+ Standard_Real umaxnew = umax - deltaY*0.1;
+ Standard_Real vmaxnew = vmax - deltaX*0.1;
+
+ for (i = 1; i <= Lu; i++)
+ {
+ pasu = ParamU.Value(i);
+ if (pasu >= uminnew && pasu < umaxnew)
+ {
+ for (j = 1; j <= Lv; j++)
{
- for (j = 1; j <= Lv; j++)
+ pasv = ParamV.Value(j);
+ if (pasv >= vminnew && pasv < vmaxnew)
{
- pasv = ParamV.Value(j);
- if (pasv >= vminnew && pasv < vmaxnew)
- {
- if (theClassifier->Perform(gp_Pnt2d(pasu, pasv)) == TopAbs_IN)
- {
- // Record 3d point
- ElSLib::D0(pasu, pasv, T, p3d);
- myNbLocat++;
- myLocation3d.Bind(myNbLocat, p3d);
- // Record 2d point
- p2d.SetCoord((pasu-umin)/deltaX, (pasv-vmin)/deltaY);
- newV.Initialize(p2d.XY(), myNbLocat, BRepMesh_Free);
- theInternalV.Append(newV);
- }
- }
+ tryToInsertAnalyticVertex(gp_Pnt2d(pasu, pasv), T, theNewVertices);
}
}
}
}
- else if (thetype == GeomAbs_BezierSurface || thetype == GeomAbs_BSplineSurface)
+}
+
+//=======================================================================
+//function : insertInternalVerticesBSpline
+//purpose :
+//=======================================================================
+void BRepMesh_FastDiscretFace::insertInternalVerticesBSpline(
+ BRepMeshCol::ListOfVertex& theNewVertices)
+{
+ const Standard_Real aRange[2][2] = {
+ { myAttribute->GetUMax(), myAttribute->GetUMin() },
+ { myAttribute->GetVMax(), myAttribute->GetVMin() }
+ };
+
+ const Standard_Real aDelta[2] = {
+ myAttribute->GetDeltaX(),
+ myAttribute->GetDeltaY()
+ };
+
+ const Standard_Real aDefFace = myAttribute->GetDefFace();
+ const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
+
+ BRepMeshCol::SequenceOfReal aParams[2];
+ for (Standard_Integer i = 0; i < 2; ++i)
{
- //define resolutions
- Standard_Real uRes = BS.UResolution(theDefFace);
- Standard_Real vRes = BS.VResolution(theDefFace);
+ Standard_Boolean isU = (i == 0);
+ Standard_Real aRes = isU ?
+ gFace->UResolution(aDefFace) :
+ gFace->VResolution(aDefFace);
// Sort and filter sequence of parameters
- Standard_Real aMinDu = Precision::PConfusion();
- if(deltaX < 1.)
- aMinDu/=deltaX;
-
- Standard_Real aDuMaxLim = 0.1*(umax-umin);
- Standard_Real ddu = Min(aDuMaxLim,Max(0.005*(umax-umin),2.*uRes));
- BRepMeshCol::SequenceOfReal ParamU;
- filterParameters(myUParam,aMinDu,ddu,ParamU);
- Standard_Integer ParamULength = ParamU.Length();
-
- Standard_Real aMinDv = Precision::PConfusion();
- if(deltaY < 1)
- aMinDv/=deltaY;
-
- Standard_Real aDvMaxLim = 0.1*(vmax-vmin);
- Standard_Real ddv = Min(aDvMaxLim,Max(0.005*(vmax-vmin),2.*vRes));
- BRepMeshCol::SequenceOfReal ParamV;
- filterParameters(myVParam,aMinDv,ddv,ParamV);
- Standard_Integer ParamVLength = ParamV.Length();
-
- // check intermediate isolines
- Handle(Geom_Surface) B;
- if (thetype == GeomAbs_BezierSurface) {
- B = BS.Bezier();
+ Standard_Real aMinDiff = Precision::PConfusion();
+ if (aDelta[i] < 1.)
+ aMinDiff /= aDelta[i];
+
+ Standard_Real aRangeDiff = aRange[i][0] - aRange[i][1];
+ Standard_Real aDiffMaxLim = 0.1 * aRangeDiff;
+ Standard_Real aDiff = Min(aDiffMaxLim, Max(0.005 * aRangeDiff, 2. * aRes));
+ filterParameters(isU ? myUParam : myVParam, aMinDiff, aDiff, aParams[i]);
+ }
+
+ // check intermediate isolines
+ Handle(Geom_Surface) aBSpline;
+ GeomAbs_SurfaceType aSurfType = gFace->GetType();
+ if (aSurfType == GeomAbs_BezierSurface)
+ aBSpline = gFace->Bezier();
+ else if (aSurfType == GeomAbs_BSplineSurface)
+ aBSpline = gFace->BSpline();
+
+ // precision for compare square distances
+ const Standard_Real aPrecision = Precision::Confusion();
+ const Standard_Real aSqPrecision = aPrecision * aPrecision;
+ for (Standard_Integer k = 0; k < 2; ++k)
+ {
+ BRepMeshCol::SequenceOfReal& aParams1 = aParams[k];
+ BRepMeshCol::SequenceOfReal& aParams2 = aParams[(k + 1) % 2];
+ const Standard_Boolean isU = (k == 0);
+ Standard_Integer aStartIndex, aEndIndex;
+ if (isU)
+ {
+ aStartIndex = 1;
+ aEndIndex = aParams1.Length();
}
- else {
- B = BS.BSpline();
+ else
+ {
+ aStartIndex = 2;
+ aEndIndex = aParams1.Length() - 1;
}
- gp_Pnt P1, P2, PControl;
- Standard_Real u, v, dist;
-
- // precision for compare square distances
- double dPreci = Precision::SquareConfusion();
-
- // Insert V parameters by deflection criterion
- Standard_Integer i,j;
- Standard_Real V1, V2, U1, U2;
- for (i = 1; i <= ParamULength; i++) {
- Handle(Geom_Curve) IsoU = B->UIso(ParamU.Value(i));
- V1 = ParamV.Value(1);
- P1 = IsoU->Value(V1);
- for (j = 2; j <= ParamVLength;) {
- V2 = ParamV.Value(j);
- P2 = IsoU->Value(V2);
- v = 0.5*(V1+V2);
- PControl = IsoU->Value(v);
+ for (Standard_Integer i = aStartIndex; i <= aEndIndex; ++i)
+ {
+ const Standard_Real aParam1 = aParams1(i);
+ Handle(Geom_Curve) aIso = isU ?
+ aBSpline->UIso(aParam1) : aBSpline->VIso(aParam1);
+
+ Standard_Real aPrevParam2 = aParams2(1);
+ gp_Pnt aPrevPnt2 = aIso->Value(aPrevParam2);
+ for (Standard_Integer j = 2; j <= aParams2.Length();)
+ {
+ Standard_Real aParam2 = aParams2(j);
+ gp_Pnt aPnt2 = aIso->Value(aParam2);
+ Standard_Real aMidParam = 0.5 * (aPrevParam2 + aParam2);
+ gp_Pnt aMidPnt = aIso->Value(aMidParam);
+
// 23.03.2010 skl for OCC21645 - change precision for comparison
- if( P1.SquareDistance(P2) > dPreci ) {
- gp_Lin L (P1, gp_Dir(gp_Vec(P1, P2)));
- dist = L.Distance(PControl);
- }
- else {
- dist = P1.Distance(PControl);
+ Standard_Real aDist;
+ if (aPrevPnt2.SquareDistance(aPnt2) > aSqPrecision)
+ {
+ gp_Lin aLin(aPrevPnt2, gp_Dir(gp_Vec(aPrevPnt2, aPnt2)));
+ aDist = aLin.Distance(aMidPnt);
}
- if (dist > theDefFace) {
+ else
+ aDist = aPrevPnt2.Distance(aMidPnt);
+
+ if (aDist > aDefFace)
+ {
// insertion
- ParamV.InsertBefore(j, v);
- ParamVLength++;
+ aParams2.InsertBefore(j, aMidParam);
}
- else {
+ else
+ {
//put regular grig for normals
- gp_Dir N1(0,0,1),N2(0,0,1);
- Standard_Boolean aSt1 = GeomLib::NormEstim(B, gp_Pnt2d(ParamU.Value(i),V1), Precision::Confusion(), N1);
- Standard_Boolean aSt2 = GeomLib::NormEstim(B, gp_Pnt2d(ParamU.Value(i),v), Precision::Confusion(), N2);
-
- Standard_Real anAngle1 = N2.Angle(N1);
- if(aSt1 < 1 && aSt2 < 1 && anAngle1 > myAngle ) {
- // insertion
- ParamV.InsertBefore(j, v);
- ParamVLength++;
+ gp_Pnt2d aStPnt1, aStPnt2;
+ if (isU)
+ {
+ aStPnt1 = gp_Pnt2d(aParam1, aPrevParam2);
+ aStPnt2 = gp_Pnt2d(aParam1, aMidParam);
}
- else {
- V1 = V2;
- P1 = P2;
- j++;
+ else
+ {
+ aStPnt1 = gp_Pnt2d(aPrevParam2, aParam1);
+ aStPnt2 = gp_Pnt2d(aMidParam, aParam1);
}
- }
- }
- }
- for (i = 2; i < ParamVLength; i++) {
- v = ParamV.Value(i);
- Handle(Geom_Curve) IsoV = B->VIso(v);
- U1 = ParamU.Value(1);
- P1 = IsoV->Value(U1);
- for (j = 2; j <= ParamULength;) {
- U2 = ParamU.Value(j);
- P2 = IsoV->Value(U2);
- u = 0.5*(U1+U2);
- PControl = IsoV->Value(u);
- // 23.03.2010 skl for OCC21645 - change precision for comparison
- if( P1.SquareDistance(P2) > dPreci ) {
- gp_Lin L (P1, gp_Dir(gp_Vec(P1, P2)));
- dist = L.Distance(PControl);
- }
- else {
- dist = P1.Distance(PControl);
- }
- if (dist > theDefFace) {
- // insertion
- ParamU.InsertBefore(j, u);
- ParamULength++;
- }
- else {
- //check normal
- //put regular grig for normals
- gp_Dir N1(0,0,1),N2(0,0,1);
- Standard_Boolean aSt1 = GeomLib::NormEstim(B, gp_Pnt2d(U1,v), Precision::Confusion(), N1);
- Standard_Boolean aSt2 = GeomLib::NormEstim(B, gp_Pnt2d(u,v), Precision::Confusion(), N2);
-
- Standard_Real anAngle1 = N2.Angle(N1);
- if(aSt1 < 1 && aSt2 < 1 && anAngle1 > myAngle) {
+ gp_Dir N1(0, 0, 1), N2(0, 0, 1);
+ Standard_Boolean aSt1 = GeomLib::NormEstim(aBSpline, aStPnt1, aPrecision, N1);
+ Standard_Boolean aSt2 = GeomLib::NormEstim(aBSpline, aStPnt2, aPrecision, N2);
+
+ Standard_Real aAngle = N2.Angle(N1);
+ if (aSt1 < 1 && aSt2 < 1 && aAngle > myAngle)
+ {
// insertion
- ParamU.InsertBefore(j, u);
- ParamULength++;
+ aParams2.InsertBefore(j, aMidParam);
}
- else {
- U1 = U2;
- P1 = P2;
- if (j < ParamULength) {
+ else
+ {
+ aPrevParam2 = aParam2;
+ aPrevPnt2 = aPnt2;
+
+ if (!isU && j < aParams2.Length())
+ {
+ // Update point parameter.
+ aStPnt1.SetX(aPrevParam2);
+
// Classify intersection point
- if (theClassifier->Perform(gp_Pnt2d(U1, v)) == TopAbs_IN)
+ if (myClassifier->Perform(aStPnt1) == TopAbs_IN)
{
- // Record 3d point
- myNbLocat++;
- myLocation3d.Bind(myNbLocat, P1);
- // Record 2d point
- p2d.SetCoord((U1-umin)/deltaX, (v-vmin)/deltaY);
- newV.Initialize(p2d.XY(), myNbLocat, BRepMesh_Free);
- theInternalV.Append(newV);
+ insertVertex(aPrevPnt2, aStPnt1.Coord(), theNewVertices);
}
}
- j++;
+
+ ++j;
}
}
}
}
}
- else {
- const Standard_Real anAngle = 0.35;
-
- Standard_Integer i, j, nbpointsU = 10, nbpointsV = 10;
- Adaptor3d_IsoCurve tabu[11], tabv[11];
-
- BRepMeshCol::SequenceOfReal ParamU, ParamV;
- Standard_Real u, v, du, dv;
- Standard_Integer iu, iv;
- Standard_Real f, l;
-
- du = (umax-umin) / (nbpointsU+1); dv = (vmax-vmin) / (nbpointsV+1);
-
- for (iu = 0; iu <= nbpointsU; iu++) {
- u = umin + iu*du;
- tabu[iu].Load(theCaro);
- tabu[iu].Load(GeomAbs_IsoU, u);
- }
-
- for (iv = 0; iv <= nbpointsV; iv++) {
- v = vmin + iv*dv;
- tabv[iv].Load(theCaro);
- tabv[iv].Load(GeomAbs_IsoV, v);
- }
+}
- Standard_Integer imax = 1, MaxV = 0;
-
- GCPnts_TangentialDeflection* tabGU = new GCPnts_TangentialDeflection[nbpointsU+1];
-
- for (i = 0; i <= nbpointsU; i++) {
- f = Max(vmin, tabu[i].FirstParameter());
- l = Min(vmax, tabu[i].LastParameter());
- GCPnts_TangentialDeflection theDeflection(tabu[i], f, l, anAngle, 0.7*theDefFace, 2);
- tabGU[i] = theDeflection;
- if (tabGU[i].NbPoints() > MaxV) {
- MaxV = tabGU[i].NbPoints();
- imax = i;
- }
- }
-
- // return table of parameters V:
- Standard_Integer NV = tabGU[imax].NbPoints();
- for (i = 1; i <= NV; i++) {
- ParamV.Append(tabGU[imax].Parameter(i));
- }
- delete [] tabGU;
+//=======================================================================
+//function : insertInternalVerticesOther
+//purpose :
+//=======================================================================
+void BRepMesh_FastDiscretFace::insertInternalVerticesOther(
+ BRepMeshCol::ListOfVertex& theNewVertices)
+{
+ const Standard_Real aAngle = 0.35;
+ const Standard_Real aRange[2][2] = {
+ { myAttribute->GetUMax(), myAttribute->GetUMin() },
+ { myAttribute->GetVMax(), myAttribute->GetVMin() }
+ };
+
+ const Standard_Real aDefFace = myAttribute->GetDefFace();
+ const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
+
+ BRepMeshCol::SequenceOfReal aParams[2];
+ const Standard_Integer aIsoPointsNb = 11;
+ for (Standard_Integer k = 0; k < 2; ++k)
+ {
+ const Standard_Boolean isU = (k == 0);
+ const GeomAbs_IsoType aIsoType = isU ? GeomAbs_IsoU : GeomAbs_IsoV;
+ const Standard_Integer aOtherParamsIndex = (k + 1) % 2;
+ const Standard_Real (&aRange1)[2] = aRange[k];
+ const Standard_Real (&aRange2)[2] = aRange[aOtherParamsIndex];
+
+ GCPnts_TangentialDeflection aDiscretIso[aIsoPointsNb];
+ const Standard_Real aStepWidth = (aRange1[0] - aRange1[1]) / aIsoPointsNb;
+
+ // Find the most curved Iso.
+ Standard_Integer aMaxIndex = 1, aMaxPointsNb = 0;
+ for (Standard_Integer aIsoIt = 0; aIsoIt < aIsoPointsNb; ++aIsoIt)
+ {
+ Standard_Real aParam = aRange1[1] + aIsoIt * aStepWidth;
+ Adaptor3d_IsoCurve aIso(gFace, aIsoType, aParam);
- imax = 1;
- Standard_Integer MaxU = 0;
+ Standard_Real aFirstParam = Max(aRange2[1], aIso.FirstParameter());
+ Standard_Real aLastParam = Min(aRange2[0], aIso.LastParameter());
- GCPnts_TangentialDeflection* tabGV = new GCPnts_TangentialDeflection[nbpointsV+1];
+ aDiscretIso[aIsoIt].Initialize(aIso, aFirstParam, aLastParam,
+ aAngle, 0.7 * aDefFace, 2);
- for (i = 0; i <= nbpointsV; i++) {
- f = Max(umin, tabv[i].FirstParameter());
- l = Min(umax, tabv[i].LastParameter());
- GCPnts_TangentialDeflection thedeflection2(tabv[i], f, l, anAngle, 0.7*theDefFace, 2);
- tabGV[i] = thedeflection2;
- if (tabGV[i].NbPoints() > MaxU) {
- MaxU = tabGV[i].NbPoints();
- imax = i;
+ const Standard_Integer aPointsNb = aDiscretIso[aIsoIt].NbPoints();
+ if (aPointsNb > aMaxPointsNb)
+ {
+ aMaxPointsNb = aPointsNb;
+ aMaxIndex = aIsoIt;
}
}
-
- // return table of parameters U:
- Standard_Integer NU = tabGV[imax].NbPoints();
- for (i = 1; i <= NU; i++) {
- ParamU.Append(tabGV[imax].Parameter(i));
- }
- delete [] tabGV;
-
- if (ParamU.Length() == 2) {
- ParamU.InsertAfter(1, (umax+umin)*0.5);
- }
- if (ParamV.Length() == 2) {
- ParamV.InsertAfter(1, (vmax+vmin)*0.5);
- }
-
- BRepMeshCol::SequenceOfReal InsertV, InsertU;
- gp_Pnt P1;
- Adaptor3d_IsoCurve IsoV;
- IsoV.Load(theCaro);
+ BRepMeshCol::SequenceOfReal& aParams2 = aParams[aOtherParamsIndex];
+ GCPnts_TangentialDeflection& aDIso = aDiscretIso[aMaxIndex];
+ for (Standard_Integer i = 1; i <= aMaxPointsNb; ++i)
+ aParams2.Append(aDIso.Parameter(i));
- Standard_Integer Lu = ParamU.Length(), Lv = ParamV.Length();
-
- for (i = 2; i < Lv; i++) {
- v = ParamV.Value(i);
- IsoV.Load(GeomAbs_IsoV, v);
- for (j = 2; j < Lu; j++) {
- u = ParamU.Value(j);
- if (theClassifier->Perform(gp_Pnt2d(u, v)) == TopAbs_IN)
- {
- // Record 3d point
- P1 = IsoV.Value(u);
- myNbLocat++;
- myLocation3d.Bind(myNbLocat, P1);
- // Record 2d point
- p2d.SetCoord((u-umin)/deltaX, (v-vmin)/deltaY);
- newV.Initialize(p2d.XY(), myNbLocat, BRepMesh_Free);
- theInternalV.Append(newV);
- }
- }
- }
+ if (aParams2.Length() == 2)
+ aParams2.InsertAfter(1, 0.5 * (aRange2[1] + aRange2[0]));
}
-#ifdef DEB_MESH_CHRONO
- chInternal.Stop();
-#endif
-}
-/**
-* Internal class Couple, moved from MeshData package
-*/
+ Adaptor3d_IsoCurve aIsoV;
+ aIsoV.Load(gFace);
-class BRepMesh_Couple
-{
- public:
- BRepMesh_Couple() { myI1 = myI2 = 0; }
- BRepMesh_Couple(const Standard_Integer I1,
- const Standard_Integer I2)
- { myI1 = I1; myI2 = I2; }
-
- Standard_Integer myI1;
- Standard_Integer myI2;
-};
-
-inline Standard_Boolean IsEqual(const BRepMesh_Couple& one,
- const BRepMesh_Couple& other)
-{
- if (one.myI1 == other.myI1 &&
- one.myI2 == other.myI2) return Standard_True;
- else return Standard_False;
-}
+ const Standard_Integer aUPointsNb = aParams[0].Length();
+ const Standard_Integer aVPointsNb = aParams[1].Length();
+ for (Standard_Integer i = 2; i < aVPointsNb; ++i)
+ {
+ const Standard_Real aV = aParams[1].Value(i);
+ aIsoV.Load(GeomAbs_IsoV, aV);
-inline Standard_Integer HashCode(const BRepMesh_Couple& one,
- const Standard_Integer Upper)
-{
- return ::HashCode((one.myI1+one.myI2), Upper);
-}
+ for (Standard_Integer j = 2; j < aUPointsNb; ++j)
+ {
+ const Standard_Real aU = aParams[0].Value(j);
-typedef NCollection_Map<BRepMesh_Couple> BRepMesh_MapOfCouple;
+ const gp_Pnt2d aNewPoint(aU, aV);
+ if (myClassifier->Perform(aNewPoint) == TopAbs_IN)
+ insertVertex(aIsoV.Value(aU), aNewPoint.Coord(), theNewVertices);
+ }
+ }
+}
//=======================================================================
-//function : Control
+//function : control
//purpose :
//=======================================================================
-Standard_Real BRepMesh_FastDiscretFace::Control(const Handle(BRepAdaptor_HSurface)& theCaro,
- const Standard_Real theDefFace,
- BRepMeshCol::ListOfVertex& theInternalV,
- BRepMeshCol::ListOfInteger& theBadTriangles,
- BRepMeshCol::ListOfInteger& theNulTriangles,
- BRepMesh_Delaun& theTrigu,
- const Standard_Boolean theIsFirst)
+Standard_Real BRepMesh_FastDiscretFace::control(
+ BRepMeshCol::ListOfVertex& theNewVertices,
+ BRepMesh_Delaun& theTrigu,
+ const Standard_Boolean theIsFirst)
+
+#define CHECK_DEF_AND_INSERT_CURRENT(isSkipped) \
+if (aSqDef > aMaxSqDef) \
+ aMaxSqDef = aSqDef; \
+ \
+(isSkipped) = Standard_False; \
+if (aSqDef > aSqDefFace) \
+{ \
+ (isSkipped) = theIsFirst; \
+ if (!(isSkipped)) \
+ insertVertex(pDef, mi2d, theNewVertices); \
+} \
+
{
+ Standard_Integer aTrianglesNb = myStructure->ElementsOfDomain().Extent();
+ if (aTrianglesNb < 1)
+ return -1.0;
+
//IMPORTANT: Constants used in calculations
- const Standard_Real MinimalArea2d = 1.e-9;
+ const Standard_Real MinimalArea2d = 1.e-9;
const Standard_Real MinimalSqLength3d = 1.e-12;
+ const Standard_Real aSqDefFace = myAttribute->GetDefFace() * myAttribute->GetDefFace();
- // Define the number of iterations
- Standard_Integer myNbIterations = 11;
- const Standard_Integer nbPasses = (theIsFirst? 1 : myNbIterations);
+ const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
- // Initialize stop condition
- Standard_Boolean allDegenerated = Standard_False;
- Standard_Integer nbInserted = 1;
-
- // Create map of links to skip already processed
- Standard_Integer nbtriangles;
-
- nbtriangles = myStructure->ElementsOfDomain().Extent();
- if (nbtriangles <= 0) return -1.0;
- BRepMesh_MapOfCouple theCouples(3*nbtriangles);
-
- gp_XY mi2d;
- gp_XYZ vecEd1, vecEd2, vecEd3;
- gp_Pnt pDef;
- Standard_Real dv = 0, defl = 0, maxdef = -1;
- Standard_Integer pass = 1, nf = 0, nl = 0;
- BRepMesh_Vertex InsVertex;
- Standard_Boolean caninsert;
-
- Standard_Real sqdefface = theDefFace * theDefFace;
-
- GeomAbs_SurfaceType thetype = theCaro->GetType();
- Handle(Geom_Surface) BSpl;
- Standard_Boolean isSpline = Standard_False;
- if (thetype == GeomAbs_BezierSurface || thetype == GeomAbs_BSplineSurface)
- {
- isSpline = Standard_True;
- if (thetype == GeomAbs_BezierSurface)
- BSpl = theCaro->Bezier();
- else
- BSpl = theCaro->BSpline();
- }
+ Handle(Geom_Surface) aBSpline;
+ GeomAbs_SurfaceType aSurfType = gFace->GetType();
+ if (aSurfType == GeomAbs_BezierSurface)
+ aBSpline = gFace->Bezier();
+ else if (aSurfType == GeomAbs_BSplineSurface)
+ aBSpline = gFace->BSpline();
- NCollection_DataMap<Standard_Integer,gp_Dir> aNorMap;
- BRepMeshCol::MapOfIntegerInteger aStatMap;
+ NCollection_DataMap<Standard_Integer, gp_Dir> aNorMap;
+ BRepMeshCol::MapOfIntegerInteger aStatMap;
+ NCollection_Map<BRepMesh_OrientedEdge> aCouples(3 * aTrianglesNb);
// Perform refinement passes
- for (; pass <= nbPasses && nbInserted && !allDegenerated; pass++)
+ // Define the number of iterations
+ Standard_Integer aIterationsNb = 11;
+ const Standard_Integer aPassesNb = (theIsFirst ? 1 : aIterationsNb);
+ // Initialize stop condition
+ Standard_Real aMaxSqDef = -1.;
+ Standard_Integer aPass = 1, aInsertedNb = 1;
+ Standard_Boolean isAllDegenerated = Standard_False;
+ for (; aPass <= aPassesNb && aInsertedNb && !isAllDegenerated; ++aPass)
{
- theInternalV.Clear();
- theBadTriangles.Clear();
-
- // Reset stop condition
- allDegenerated = Standard_True;
- nbInserted = 0;
- maxdef = -1.0;
+ theNewVertices.Clear();
- // Do not insert nodes in last pass in non-SharedMode
- caninsert = (myWithShare || pass < nbPasses);
+ // Reset stop condition
+ aInsertedNb = 0;
+ aMaxSqDef = -1.;
+ isAllDegenerated = Standard_True;
- // Read mesh size
- nbtriangles = myStructure->ElementsOfDomain().Extent();
- if (nbtriangles <= 0) break;
+ aTrianglesNb = myStructure->ElementsOfDomain().Extent();
+ if (aTrianglesNb < 1)
+ break;
// Iterate on current triangles
- BRepMeshCol::MapOfInteger::Iterator triDom;
- const BRepMeshCol::MapOfInteger& TriMap = myStructure->ElementsOfDomain();
- triDom.Initialize(TriMap);
- Standard_Integer aNbPnt = 0;
- Standard_Real umin = myAttrib->GetUMin();
- Standard_Real vmin = myAttrib->GetVMin();
- Standard_Real deltaX = myAttrib->GetDeltaX();
- Standard_Real deltaY = myAttrib->GetDeltaY();
- for (; triDom.More(); triDom.Next())
+ const BRepMeshCol::MapOfInteger& aTriangles = myStructure->ElementsOfDomain();
+ BRepMeshCol::MapOfInteger::Iterator aTriangleIt(aTriangles);
+ for (; aTriangleIt.More(); aTriangleIt.Next())
{
- Standard_Integer TriId = triDom.Key();
- const BRepMesh_Triangle& curTri=Triangle(TriId);
- if (curTri.Movability()==BRepMesh_Deleted) continue;
-
+ const Standard_Integer aTriangleId = aTriangleIt.Key();
+ const BRepMesh_Triangle& aCurrentTriangle = myStructure->GetElement(aTriangleId);
+
+ if (aCurrentTriangle.Movability() == BRepMesh_Deleted)
+ continue;
+
Standard_Integer v[3];
- myStructure->ElementNodes(curTri, v);
+ myStructure->ElementNodes(aCurrentTriangle, v);
Standard_Integer e[3];
Standard_Boolean o[3];
- curTri.Edges(e, o);
-
- Standard_Boolean m1 = (Edge(e[0]).Movability() == BRepMesh_Frontier);
- Standard_Boolean m2 = (Edge(e[1]).Movability() == BRepMesh_Frontier);
- Standard_Boolean m3 = (Edge(e[2]).Movability() == BRepMesh_Frontier);
-
- const BRepMesh_Vertex& vert1=Vertex(v[0]);
- const BRepMesh_Vertex& vert2=Vertex(v[1]);
- const BRepMesh_Vertex& vert3=Vertex(v[2]);
-
- const gp_XYZ& p1=myLocation3d(vert1.Location3d()).Coord();
- const gp_XYZ& p2=myLocation3d(vert2.Location3d()).Coord();
- const gp_XYZ& p3=myLocation3d(vert3.Location3d()).Coord();
-
- vecEd1 = p2 - p1;
- vecEd2 = p3 - p2;
- vecEd3 = p1 - p3;
-
- // Check for degenerated triangle
- if (vecEd1.SquareModulus() < MinimalSqLength3d ||
- vecEd2.SquareModulus() < MinimalSqLength3d ||
- vecEd3.SquareModulus() < MinimalSqLength3d)
+ aCurrentTriangle.Edges(e, o);
+
+ gp_XY xy[3];
+ gp_XYZ p[3];
+ Standard_Boolean m[3];
+ for (Standard_Integer i = 0; i < 3; ++i)
{
- theNulTriangles.Append(TriId);
- continue;
+ m[i] = (myStructure->GetLink(e[i]).Movability() == BRepMesh_Frontier);
+
+ const BRepMesh_Vertex& aVertex = myStructure->GetNode(v[i]);
+ xy[i] = myAttribute->Scale(aVertex.Coord(), Standard_False);
+ p [i] = myAttribute->GetPoint(aVertex).Coord();
}
- allDegenerated = Standard_False;
+ gp_XYZ aLinkVec[3];
+ Standard_Boolean isDegeneratedTri = Standard_False;
+ for (Standard_Integer i = 0; i < 3 && !isDegeneratedTri; ++i)
+ {
+ aLinkVec[i] = p[(i + 1) % 3] - p[i];
+ isDegeneratedTri = (aLinkVec[i].SquareModulus() < MinimalSqLength3d);
+ }
+
+ if (isDegeneratedTri)
+ continue;
- gp_XY xy1(vert1.Coord().X()*deltaX+umin,vert1.Coord().Y()*deltaY+vmin);
- gp_XY xy2(vert2.Coord().X()*deltaX+umin,vert2.Coord().Y()*deltaY+vmin);
- gp_XY xy3(vert3.Coord().X()*deltaX+umin,vert3.Coord().Y()*deltaY+vmin);
+ isAllDegenerated = Standard_False;
// Check triangle area in 2d
- if (Abs((xy2-xy1)^(xy3-xy1)) < MinimalArea2d)
- {
- theNulTriangles.Append(TriId);
+ if (Abs((xy[1]-xy[0])^(xy[2]-xy[1])) < MinimalArea2d)
continue;
- }
// Check triangle normal
- gp_XYZ normal(vecEd1^vecEd2);
- dv = normal.Modulus();
- if (dv < Precision::Confusion())
+ gp_Pnt pDef;
+ Standard_Real aSqDef = -1.;
+ Standard_Boolean isSkipped = Standard_False;
+ gp_XYZ normal(aLinkVec[0] ^ aLinkVec[1]);
+ try
{
- theNulTriangles.Append(TriId);
- continue;
+ OCC_CATCH_SIGNALS
+
+ normal.Normalize();
+
+ // Check deflection on triangle
+ gp_XY mi2d = (xy[0] + xy[1] + xy[2]) / 3.0;
+ gFace->D0(mi2d.X(), mi2d.Y(), pDef);
+ aSqDef = Abs(normal * (pDef.XYZ() - p[0]));
+ aSqDef *= aSqDef;
+
+ CHECK_DEF_AND_INSERT_CURRENT(isSkipped);
+ if (isSkipped)
+ break;
}
- normal /= dv;
-
- // Check deflection on triangle
- mi2d = (xy1+xy2+xy3)/3.0;
- theCaro->D0(mi2d.X(), mi2d.Y(), pDef);
- defl = Abs(normal*(pDef.XYZ()-p1));
- defl = defl*defl;
- /*mi2d = (xy1+xy2+xy3)/3.0;
- theCaro->D0(mi2d.X(), mi2d.Y(), pDef);
- defl = pDef.SquareDistance((p1+p2+p3)/3.);*/
- if (defl > maxdef) maxdef = defl;
- if (defl > sqdefface)
+ catch (Standard_Failure)
{
- if (theIsFirst) break;
- if (caninsert)
- {
- // Record new vertex
- aNbPnt++;
- myNbLocat++;
- myLocation3d.Bind(myNbLocat,pDef);
- mi2d.SetCoord((mi2d.X()-umin)/deltaX,(mi2d.Y()-vmin)/deltaY);
- InsVertex.Initialize(mi2d,myNbLocat,BRepMesh_Free);
- theInternalV.Append(InsVertex);
- }
- theBadTriangles.Append(TriId);
+ continue;
}
-
- if (!m2) // Not a boundary
+
+ for (Standard_Integer i = 0; i < 3 && !isSkipped; ++i)
{
+ if (m[i]) // is a boundary
+ continue;
+
+ Standard_Integer j = (i + 1) % 3;
// Check if this link was already processed
- if (v[1] < v[2]) { nf = v[1]; nl = v[2]; } else { nf = v[2]; nl = v[1]; }
- if (theCouples.Add(BRepMesh_Couple(nf,nl)))
+ Standard_Integer aFirstVertex, aLastVertex;
+ if (v[i] < v[j])
+ {
+ aFirstVertex = v[i];
+ aLastVertex = v[j];
+ }
+ else
{
- // Check deflection on edge 1
- mi2d = (xy2+xy3)*0.5;
- theCaro->D0(mi2d.X(), mi2d.Y(), pDef);
- gp_Lin L (p2, gp_Vec(p2, p3));
- defl = L.SquareDistance(pDef);
- if (defl > maxdef) maxdef = defl;
- if (defl > sqdefface)
- {
- if (theIsFirst) break;
- if (caninsert)
- {
- // Record new vertex
- aNbPnt++;
- myNbLocat++;
- myLocation3d.Bind(myNbLocat,pDef);
- mi2d.SetCoord((mi2d.X()-umin)/deltaX,(mi2d.Y()-vmin)/deltaY);
- InsVertex.Initialize(mi2d,myNbLocat,BRepMesh_Free);
- theInternalV.Append(InsVertex);
- }
- theBadTriangles.Append(TriId);
- }
+ aFirstVertex = v[j];
+ aLastVertex = v[i];
}
- }
- if (!m3) // Not a boundary
- {
- // Check if this link was already processed
- if (v[0] < v[2]) { nf = v[0]; nl = v[2]; } else { nf = v[2]; nl = v[0]; }
- if (theCouples.Add(BRepMesh_Couple(nf,nl)))
+ if (aCouples.Add(BRepMesh_OrientedEdge(aFirstVertex, aLastVertex)))
{
- // Check deflection on edge 2
- mi2d = (xy3+xy1)*0.5;
- theCaro->D0(mi2d.X(), mi2d.Y(), pDef);
- gp_Lin L (p1, gp_Vec(p1, p3));
- defl = L.SquareDistance(pDef);
- if (defl > maxdef) maxdef = defl;
- if (defl > sqdefface)
- {
- if (theIsFirst) break;
- if (caninsert)
- {
- // Record new vertex
- aNbPnt++;
- myNbLocat++;
- myLocation3d.Bind(myNbLocat,pDef);
- mi2d.SetCoord((mi2d.X()-umin)/deltaX,(mi2d.Y()-vmin)/deltaY);
- InsVertex.Initialize(mi2d,myNbLocat,BRepMesh_Free);
- theInternalV.Append(InsVertex);
- }
- theBadTriangles.Append(TriId);
- }
+ // Check deflection on edge 1
+ gp_XY mi2d = (xy[i] + xy[j]) * 0.5;
+ gFace->D0(mi2d.X(), mi2d.Y(), pDef);
+ gp_Lin aLin(p[i], gp_Vec(p[i], p[j]));
+ aSqDef = aLin.SquareDistance(pDef);
+
+ CHECK_DEF_AND_INSERT_CURRENT(isSkipped);
}
}
- if (!m1) // Not a boundary
+ if (isSkipped)
+ break;
+
+ //check normal on bsplines
+ if (theIsFirst && !aBSpline.IsNull())
{
- // Check if this link was already processed
- if (v[0] < v[1]) { nf = v[0]; nl = v[1]; } else { nf = v[1]; nl = v[0]; }
- if (theCouples.Add(BRepMesh_Couple(nf,nl)))
+ gp_Dir N[3] = { gp::DZ(), gp::DZ(), gp::DZ() };
+ Standard_Integer aSt[3];
+
+ for (Standard_Integer i = 0; i < 3; ++i)
{
- // Check deflection on edge 3
- mi2d = (xy1+xy2)*0.5;
- theCaro->D0(mi2d.X(), mi2d.Y(), pDef);
- gp_Lin L (p1, gp_Vec(p1, p2));
- defl = L.SquareDistance(pDef);
- if (defl > maxdef) maxdef = defl;
- if (defl > sqdefface)
+ if (aNorMap.IsBound(v[i]))
{
- if (theIsFirst) break;
- if (caninsert)
- {
- // Record new vertex
- aNbPnt++;
- myNbLocat++;
- myLocation3d.Bind(myNbLocat,pDef);
- mi2d.SetCoord((mi2d.X()-umin)/deltaX,(mi2d.Y()-vmin)/deltaY);
- InsVertex.Initialize(mi2d,myNbLocat,BRepMesh_Free);
- theInternalV.Append(InsVertex);
- }
- theBadTriangles.Append(TriId);
+ aSt[i] = aStatMap.Find(v[i]);
+ N[i] = aNorMap.Find(v[i]);
+ }
+ else
+ {
+ aSt[i] = GeomLib::NormEstim(aBSpline, gp_Pnt2d(xy[i]), Precision::Confusion(), N[i]);
+ aStatMap.Bind(v[i], aSt[i]);
+ aNorMap.Bind(v[i], N[i]);
}
- }
- }
-
- //check normal on bsplines
- if(theIsFirst && isSpline && !BSpl.IsNull() )
- {
- gp_Dir N1(0,0,1), N2(0,0,1), N3(0,0,1);
- Standard_Integer aSt1, aSt2, aSt3;
- if(aNorMap.IsBound(v[0])) {
- aSt1 = aStatMap.Find(v[0]);
- N1 =aNorMap.Find(v[0]);
- }
- else {
- aSt1 = GeomLib::NormEstim(BSpl, gp_Pnt2d(xy1), Precision::Confusion(), N1);
- aStatMap.Bind(v[0],aSt1);
- aNorMap.Bind(v[0],N1);
}
- if(aNorMap.IsBound(v[1])) {
- aSt2 = aStatMap.Find(v[1]);
- N2 = aNorMap.Find(v[1]);
- }
- else {
- aSt2 = GeomLib::NormEstim(BSpl, gp_Pnt2d(xy2), Precision::Confusion(), N2);
- aStatMap.Bind(v[1],aSt2);
- aNorMap.Bind(v[1],N2);
- }
+ Standard_Real aAngle[3];
+ for (Standard_Integer i = 0; i < 3; ++i)
+ aAngle[i] = N[(i + 1) % 3].Angle(N[i]);
- if(aNorMap.IsBound(v[2])) {
- aSt3 = aStatMap.Find(v[2]);
- N3 = aNorMap.Find(v[2]);
- }
- else {
- aSt3 = GeomLib::NormEstim(BSpl, gp_Pnt2d(xy3), Precision::Confusion(), N3);
- aStatMap.Bind(v[2],aSt3);
- aNorMap.Bind(v[2],N3.XYZ());
- }
-
- Standard_Real anAngle1 = N2.Angle(N1);
- Standard_Real anAngle2 = N3.Angle(N2);
- Standard_Real anAngle3 = N1.Angle(N3);
- if(aSt1 < 1 && aSt2 < 1 && aSt3 < 1 &&
- (anAngle1 > myAngle || anAngle2 > myAngle || anAngle3 > myAngle)) {
-
- maxdef = -1;
+ if (aSt[0] < 1 && aSt[1] < 1 && aSt[2] < 1)
+ {
+ if (aAngle[0] > myAngle || aAngle[1] > myAngle || aAngle[2] > myAngle)
+ {
+ aMaxSqDef = -1.;
break;
+ }
}
}
}
-
- if (!theIsFirst && theInternalV.Extent() > 0)
- {
- BRepMeshCol::Array1OfVertexOfDelaun verttab(1, theInternalV.Extent());
- BRepMeshCol::ListOfVertex::Iterator itVer(theInternalV);
- Standard_Integer ipn = 1;
- for (; itVer.More(); itVer.Next())
- verttab(ipn++) = itVer.Value();
-
- theTrigu.AddVertices(verttab);
- nbInserted++;
- }
- }
-
- if (maxdef < 0)
- return maxdef;
- return Sqrt(maxdef);
-}
-
-//=======================================================================
-//function : AddInShape
-//purpose :
-//=======================================================================
-void BRepMesh_FastDiscretFace::AddInShape(const TopoDS_Face& theFace,
- const Standard_Real theDefFace,
- const TopTools_MutexForShapeProvider& theMutexProvider)
-{
- TopLoc_Location loc = theFace.Location();
- Handle(Poly_Triangulation) TOld = BRep_Tool::Triangulation(theFace, loc);
- Handle(Poly_PolygonOnTriangulation) NullPoly;
-
- BRepMesh_ShapeTool::NullifyFace(theFace);
-
- try{
- BRepMeshCol::MapOfInteger::Iterator it;
-
- Standard_Integer i, index;
- TopAbs_Orientation orFace = theFace.Orientation();
-
- const BRepMeshCol::MapOfInteger& TriMap = myStructure->ElementsOfDomain();
- it.Initialize(TriMap);
-
- Standard_Integer nTri = TriMap.Extent();
- if (nTri != 0) {
-
- Poly_Array1OfTriangle Tri(1, nTri);
-
- i = 1;
-
- for (; it.More(); it.Next())
- {
- const BRepMesh_Triangle& aCurElem = myStructure->GetElement(it.Key());
-
- Standard_Integer v[3];
- myStructure->ElementNodes(aCurElem, v);
-
- Standard_Integer iv1, iv2, iv3;
- iv1 = myVemap.FindIndex(v[0]);
- if (iv1 == 0) iv1 = myVemap.Add(v[0]);
- iv2 = myVemap.FindIndex(v[1]);
- if (iv2 == 0) iv2 = myVemap.Add(v[1]);
- iv3 = myVemap.FindIndex(v[2]);
- if (iv3 == 0) iv3 = myVemap.Add(v[2]);
-
- if (orFace == TopAbs_REVERSED) Tri(i++).Set(iv1, iv3, iv2);
- else Tri(i++).Set(iv1, iv2, iv3);
- }
-
- Standard_Integer nbVertices = myVemap.Extent();
- Handle(Poly_Triangulation) T = new Poly_Triangulation(nbVertices, nTri, Standard_True);
- Poly_Array1OfTriangle& Trian = T->ChangeTriangles();
- Trian = Tri;
- TColgp_Array1OfPnt& Nodes = T->ChangeNodes();
- TColgp_Array1OfPnt2d& Nodes2d = T->ChangeUVNodes();
-
- for (i = 1; i <= nbVertices; i++) {
- index = myVemap.FindKey(i);
- Nodes(i) = Pnt(index);
- Nodes2d(i).SetXY(Vertex(index).Coord());
- }
-
- T->Deflection(theDefFace);
- BRepMesh_ShapeTool::AddInFace(theFace, T);
-
- // implement polygons on triangulation in the face:
- BRepMeshCol::DMapOfShapePairOfPolygon::Iterator It(myInternaledges);
-
- for (; It.More(); It.Next()) {
- const TopoDS_Edge& aEdge = TopoDS::Edge(It.Key());
- const BRepMesh_PairOfPolygon& pair = It.Value();
- const Handle(Poly_PolygonOnTriangulation)& NOD1 = pair.First();
- const Handle(Poly_PolygonOnTriangulation)& NOD2 = pair.Last();
- // lock mutex to prevent parallel change of the same data
- Standard_Mutex* aMutex = theMutexProvider.GetMutex(It.Key());
- Standard_Mutex::Sentry aSentry (aMutex);
+ if (theIsFirst)
+ continue;
- if ( NOD1 == NOD2 ) {
- BRepMesh_ShapeTool::NullifyEdge(aEdge, TOld, loc);
- BRepMesh_ShapeTool::UpdateEdge(aEdge, NOD1, T, loc);
- }
- else {
- BRepMesh_ShapeTool::NullifyEdge(aEdge, TOld, loc);
- BRepMesh_ShapeTool::UpdateEdge(aEdge, NOD1, NOD2, T, loc);
- }
- }
+ if (addVerticesToMesh(theNewVertices, theTrigu))
+ ++aInsertedNb;
}
- }
-
- catch(Standard_Failure)
- {
- // MESH_FAILURE(theFace);
- }
-}
-
-
-//=======================================================================
-//function : Triangle
-//purpose :
-//=======================================================================
-const BRepMesh_Triangle& BRepMesh_FastDiscretFace::Triangle(const Standard_Integer Index) const
-{
- return myStructure->GetElement(Index);
+ return (aMaxSqDef < 0) ? aMaxSqDef : Sqrt(aMaxSqDef);
}
//=======================================================================
-//function : NbEdges
+//function : add
//purpose :
//=======================================================================
-
-/*Standard_Integer BRepMesh_FastDiscretFace::NbEdges() const
+void BRepMesh_FastDiscretFace::add(const TopoDS_Vertex& theVertex)
{
- return myStructure->NbLinks();
-}*/
-
-//=======================================================================
-//function : Edge
-//purpose :
-//=======================================================================
+ if (theVertex.Orientation() != TopAbs_INTERNAL)
+ return;
-const BRepMesh_Edge& BRepMesh_FastDiscretFace::Edge(const Standard_Integer Index) const
-{
- return myStructure->GetLink(Index);
-}
+ try
+ {
+ OCC_CATCH_SIGNALS
+ gp_Pnt2d aPnt2d = BRep_Tool::Parameters(theVertex, myAttribute->Face());
-//=======================================================================
-//function : Vertex
-//purpose :
-//=======================================================================
+ N_HANDLE<FixedVExplorer> aFixedVExplorer = new FixedVExplorer(theVertex);
+ Standard_Integer aIndex = myAttribute->GetVertexIndex(aFixedVExplorer);
+ gp_XY anUV = BRepMesh_ShapeTool::FindUV(aIndex, aPnt2d,
+ theVertex, BRep_Tool::Tolerance(theVertex), myAttribute);
-const BRepMesh_Vertex& BRepMesh_FastDiscretFace::Vertex(const Standard_Integer Index) const
-{
- return myStructure->GetNode(Index);
+ Standard_Integer aTmpId1, aTmpId2;
+ myAttribute->AddNode(aIndex, anUV, BRepMesh_Fixed, aTmpId1, aTmpId2);
+ }
+ catch (Standard_Failure)
+ {
+ }
}
//=======================================================================
-//function : Pnt
+//function : insertVertex
//purpose :
//=======================================================================
-
-const gp_Pnt& BRepMesh_FastDiscretFace::Pnt(const Standard_Integer Index) const
+void BRepMesh_FastDiscretFace::insertVertex(
+ const gp_Pnt& thePnt3d,
+ const gp_XY& theUV,
+ BRepMeshCol::ListOfVertex& theVertices)
{
- return myLocation3d(myStructure->GetNode(Index).Location3d());
-}
+ Standard_Integer aNbLocat = myAttribute->LastPointId();
+ mySurfacePoints->Bind(++aNbLocat, thePnt3d);
-static Standard_Boolean GetVertexParameters(const TopoDS_Vertex& theVert,
- const TopoDS_Face& theFace,
- gp_Pnt2d& thePoint)
-{
- TopLoc_Location L;
- const Handle(Geom_Surface)& S = BRep_Tool::Surface(theFace,L);
- L = L.Predivided(theVert.Location());
- BRep_ListIteratorOfListOfPointRepresentation itpr =
- ((*((Handle(BRep_TVertex)*) &theVert.TShape()))->Points());
- // Check first if there are PointRepresentation (case non Manifold)
-
- while (itpr.More()) {
- if (itpr.Value()->IsPointOnSurface(S,L)) {
- thePoint.SetCoord(itpr.Value()->Parameter(),
- itpr.Value()->Parameter2());
- return Standard_True;
- }
- itpr.Next();
- }
- return Standard_False;
-}
-
-//=======================================================================
-//function : Add
-//purpose : method intended to add internal myVertices in triangulation.
-//=======================================================================
-void BRepMesh_FastDiscretFace::Add(const TopoDS_Vertex& theVert,
- const TopoDS_Face& theFace,
- const Handle(BRepAdaptor_HSurface)& thegFace)
-{
- const TopAbs_Orientation anOrient = theVert.Orientation();
- gp_Pnt2d uvXY;
- if( anOrient != TopAbs_INTERNAL || !GetVertexParameters(theVert,theFace,uvXY))
- return;
- Standard_Integer indVert =0;
- if (myVertices.IsBound(theVert))
- indVert = myVertices.Find(theVert);
- else
- {
- myNbLocat++;
- myLocation3d.Bind(myNbLocat, BRep_Tool::Pnt(theVert));
- indVert = myNbLocat;
- myVertices.Bind(theVert, indVert);
- }
- Standard_Real mindist = BRep_Tool::Tolerance(theVert);
- // gp_Pnt2d uvXY = BRep_Tool::Parameters(theVert,theFace);
- gp_XY anUV = BRepMesh_ShapeTool::FindUV(indVert, uvXY,
- theVert, mindist, myAttrib, thegFace, myLocation2d);
-
- BRepMesh_Vertex vf(anUV, indVert, BRepMesh_Fixed);
- Standard_Integer ivff = myStructure->AddNode(vf);
- Standard_Integer isvf = myVemap.FindIndex(ivff);
- if (isvf == 0) isvf = myVemap.Add(ivff);
-}
+ gp_XY aPnt2d = myAttribute->Scale(theUV, Standard_True);
+ BRepMesh_Vertex aVertex(aPnt2d, aNbLocat, BRepMesh_Free);
+ theVertices.Append(aVertex);
+}
\ No newline at end of file
#include <Handle_Poly_Triangulation.hxx>
#include <BRepMesh_Delaun.hxx>
#include <BRepMesh_Triangle.hxx>
+#include <BRepMesh_Classifier.hxx>
+#include <ElSLib.hxx>
class BRepMesh_DataStructureOfDelaun;
class BRepMesh_FaceAttribute;
class gp_Pnt;
//! Algorithm to mesh a face with respect of the frontier
-//! the deflection and by option the shared components. <br>
+//! the deflection and by option the shared components.
class BRepMesh_FastDiscretFace : public Standard_Transient
{
public:
-
+
Standard_EXPORT BRepMesh_FastDiscretFace(const Standard_Real theAngle,
const Standard_Boolean theWithShare = Standard_True);
-
- Standard_EXPORT void Add(const TopoDS_Face& theFace,
- const Handle(BRepMesh_FaceAttribute)& theAttrib,
- const TopTools_DataMapOfShapeReal& theMapDefle,
- const TopTools_MutexForShapeProvider& theMutexProvider);
-
- Standard_EXPORT Standard_Real Control(const Handle(BRepAdaptor_HSurface)& theCaro,
- const Standard_Real theDefFace,
- BRepMeshCol::ListOfVertex& theInternalV,
- BRepMeshCol::ListOfInteger& theBadTriangles,
- BRepMeshCol::ListOfInteger& theNulTriangles,
- BRepMesh_Delaun& theTrigu,
- const Standard_Boolean theIsFirst);
+
+ Standard_EXPORT void Add(const Handle(BRepMesh_FaceAttribute)& theAttribute);
//! Gives the triangle of <Index>. <br>
Standard_EXPORT const BRepMesh_Triangle& Triangle(const Standard_Integer theIndex) const;
- //! Gives the edge of index <Index>. <br>
- Standard_EXPORT const BRepMesh_Edge& Edge(const Standard_Integer theIndex) const;
+ DEFINE_STANDARD_RTTI(BRepMesh_FastDiscretFace)
- //! Gives the vertex of <Index>. <br>
- Standard_EXPORT const BRepMesh_Vertex& Vertex(const Standard_Integer theIndex) const;
+private:
- //! Gives the location3d of the vertex of <Index>. <br>
- Standard_EXPORT const gp_Pnt& Pnt(const Standard_Integer theIndex) const;
+ void add(const TopoDS_Vertex& theVertex);
- DEFINE_STANDARD_RTTI(BRepMesh_FastDiscretFace)
+ Standard_Real control(BRepMeshCol::ListOfVertex& theNewVertices,
+ BRepMesh_Delaun& theMeshBuilder,
+ const Standard_Boolean theIsFirst);
-protected:
-
- Standard_Boolean RestoreStructureFromTriangulation(const TopoDS_Edge& theEdge,
- const TopoDS_Face& theFace,
- const Handle(BRepAdaptor_HSurface)& theSurf,
- const Handle(Poly_Triangulation)& theTrigu,
- const Standard_Real theDefEdge,
- const TopLoc_Location& theLoc,
- const TopTools_MutexForShapeProvider& theMutexProvider);
-
-private:
-
- void Add(const TopoDS_Vertex& theVert,
- const TopoDS_Face& theFace,
- const Handle(BRepAdaptor_HSurface)& theSFace);
-
- void InternalVertices(const Handle(BRepAdaptor_HSurface)& theCaro,
- BRepMeshCol::ListOfVertex& theInternalV,
- const Standard_Real theDefFace,
- const BRepMeshCol::HClassifier& theClassifier);
+ //! 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 BRepMeshCol::ListOfVertex& theVertices,
+ BRepMesh_Delaun& theMeshBuilder);
+
+ //! Calculates nodes lying on face's surface and inserts them to a mesh.
+ //! @param theNewVertices list of vertices to be extended and added to mesh.
+ //! @param theMeshBuilder initialized tool refining mesh
+ //! in respect to inserting nodes.
+ void insertInternalVertices(BRepMeshCol::ListOfVertex& theNewVertices,
+ BRepMesh_Delaun& theMeshBuilder);
+
+ //! Calculates nodes lying on spherical surface.
+ //! @param theNewVertices list of vertices to be extended and added to mesh.
+ void insertInternalVerticesSphere(BRepMeshCol::ListOfVertex& theNewVertices);
+
+ //! Calculates nodes lying on cylindrical surface.
+ //! @param theNewVertices list of vertices to be extended and added to mesh.
+ void insertInternalVerticesCylinder(BRepMeshCol::ListOfVertex& theNewVertices);
+
+ //! Calculates nodes lying on conical surface.
+ //! @param theNewVertices list of vertices to be extended and added to mesh.
+ void insertInternalVerticesCone(BRepMeshCol::ListOfVertex& theNewVertices);
+
+ //! Calculates nodes lying on toroidal surface.
+ //! @param theNewVertices list of vertices to be extended and added to mesh.
+ void insertInternalVerticesTorus(BRepMeshCol::ListOfVertex& theNewVertices);
+
+ //! Calculates nodes lying on Bezier/BSpline surface.
+ //! @param theNewVertices list of vertices to be extended and added to mesh.
+ void insertInternalVerticesBSpline(BRepMeshCol::ListOfVertex& theNewVertices);
+
+ //! Calculates nodes lying on custom-type surface.
+ //! @param theNewVertices list of vertices to be extended and added to mesh.
+ void insertInternalVerticesOther(BRepMeshCol::ListOfVertex& theNewVertices);
- void AddInShape(const TopoDS_Face& theFace,
- const Standard_Real theDefFace,
- const TopTools_MutexForShapeProvider& theMutexProvider);
+ //! 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,
+ BRepMeshCol::ListOfVertex& theVertices)
+ {
+ if (!myClassifier->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,
+ BRepMeshCol::ListOfVertex& theVertices);
private:
+
Standard_Real myAngle;
Standard_Boolean myWithShare;
- BRepMeshCol::DMapOfVertexInteger myVertices;
- BRepMeshCol::DMapOfShapePairOfPolygon myInternaledges;
- Standard_Integer myNbLocat;
- BRepMeshCol::DMapOfIntegerPnt myLocation3d;
- Handle_BRepMesh_DataStructureOfDelaun myStructure;
- BRepMeshCol::ListOfVertex myListver;
- BRepMeshCol::IMapOfInteger myVemap;
- BRepMeshCol::DMapOfIntegerListOfXY myLocation2d;
- Handle_BRepMesh_FaceAttribute myAttrib;
Standard_Boolean myInternalVerticesMode;
BRepMeshCol::IMapOfReal myUParam;
BRepMeshCol::IMapOfReal myVParam;
BRepMeshCol::Allocator myAllocator;
+
+ // Fast access to attributes of current face
+ Handle(BRepMesh_FaceAttribute) myAttribute;
+ Handle(BRepMesh_DataStructureOfDelaun) myStructure;
+ BRepMeshCol::HIMapOfInteger myVertexEdgeMap;
+ BRepMeshCol::HClassifier myClassifier;
+ BRepMeshCol::HDMapOfIntegerPnt mySurfacePoints;
};
DEFINE_STANDARD_HANDLE (BRepMesh_FastDiscretFace, Standard_Transient)
--- /dev/null
+// 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_HANDLE (BRepMesh_IEdgeTool, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_IEdgeTool, Standard_Transient)
--- /dev/null
+// 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.
+ virtual void Value(const Standard_Integer theIndex,
+ Standard_Real& theParameter,
+ gp_Pnt& thePoint,
+ gp_Pnt2d& theUV) = 0;
+
+ DEFINE_STANDARD_RTTI(BRepMesh_IEdgeTool)
+};
+
+DEFINE_STANDARD_HANDLE(BRepMesh_IEdgeTool, Standard_Transient)
+
+#endif
#include <BRepMesh_IncrementalMesh.hxx>
#include <Precision.hxx>
-#include <Standard_Mutex.hxx>
+#include <Standard_ErrorHandler.hxx>
#include <BRepMesh_FaceChecker.hxx>
#include <BRepMesh_ShapeTool.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopTools_MutexForShapeProvider.hxx>
#include <TColgp_Array1OfPnt.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TopTools_HArray1OfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <GCPnts_TangentialDeflection.hxx>
: myRelative (isRelative),
myInParallel(isInParallel)
{
- myDeflection = theLinDeflection;
- myAngle = theAngDeflection;
- myShape = theShape;
-
+ myDeflection = theLinDeflection;
+ myAngle = theAngDeflection;
+ myShape = theShape;
+
Perform();
}
myModified = Standard_False;
myEdgeDeflection.Clear();
- mySharedFaces.Clear();
myFaces.clear();
setDone();
if (aBox.IsVoid())
{
// Nothing to mesh.
- myMesher.Nullify();
+ myMesh.Nullify();
return;
}
BRepMesh_ShapeTool::BoxMaxDimension(aBox, myMaxShapeSize);
- TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, mySharedFaces);
- myMesher = new BRepMesh_FastDiscret(myDeflection, myAngle, aBox,
+ myMesh = new BRepMesh_FastDiscret(myDeflection, myAngle, aBox,
Standard_True, Standard_True, myRelative, Standard_True, myInParallel);
+
+ myMesh->InitSharedFaces(myShape);
}
//=======================================================================
{
init();
- if (myMesher.IsNull())
+ if (myMesh.IsNull())
return;
update();
#ifdef HAVE_TBB
if (myInParallel)
{
- myMesher->CreateMutexesForSubShapes(myShape, TopAbs_EDGE);
- tbb::parallel_for_each(myFaces.begin(), myFaces.end(), *myMesher);
- myMesher->RemoveAllMutexes();
+ tbb::parallel_for_each(myFaces.begin(), myFaces.end(), *myMesh);
}
else
{
#endif
for (aFaceIt = myFaces.begin(); aFaceIt != myFaces.end(); aFaceIt++)
- myMesher->Process(*aFaceIt);
+ myMesh->Process(*aFaceIt);
#ifdef HAVE_TBB
}
#endif
- discretizeFreeEdges();
+ commit();
}
//=======================================================================
if (!aTriangulation.IsNull() && !aPolygon.IsNull())
{
- if (aPolygon->Deflection() < 1.1 * aEdgeDeflection)
+ if (aPolygon->Deflection() < 1.1 * aEdgeDeflection &&
+ aPolygon->HasParameters())
+ {
continue;
+ }
myModified = Standard_True;
BRepMesh_ShapeTool::NullifyEdge(theEdge, aTriangulation, aLoc);
if (!myEmptyEdges.IsBound(theEdge))
myEmptyEdges.Bind(theEdge, BRepMeshCol::MapOfTriangulation());
- myEmptyEdges(theEdge).Add(aTriangulation);
+ if (!aTriangulation.IsNull())
+ myEmptyEdges(theEdge).Add(aTriangulation);
}
while (!aPolygon.IsNull());
}
if (!myEmptyEdges.IsBound(aEdge))
continue;
- isEdgesConsistent &= myEmptyEdges(aEdge).Contains(aTriangulation);
+ BRepMeshCol::MapOfTriangulation& aTriMap = myEmptyEdges(aEdge);
+ isEdgesConsistent &= !aTriMap.IsEmpty() && !aTriMap.Contains(aTriangulation);
}
if (isEdgesConsistent)
return;
myModified = Standard_True;
- myMesher->Add(theFace, mySharedFaces);
+ Standard_Integer aStatus = myMesh->Add(theFace);
- BRepMesh_Status aStatus = myMesher->CurrentFaceStatus();
- myStatus |= (Standard_Integer)aStatus;
+ myStatus |= aStatus;
if (aStatus != BRepMesh_ReMesh)
return;
BRepMeshCol::MapOfShape aUsedFaces;
aUsedFaces.Add(theFace);
+ const TopTools_IndexedDataMapOfShapeListOfShape& aMapOfSharedFaces =
+ myMesh->SharedFaces();
+
TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
for (; aEdgeIt.More(); aEdgeIt.Next())
{
const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
- if (mySharedFaces.FindIndex(aEdge) == 0)
+ if (aMapOfSharedFaces.FindIndex(aEdge) == 0)
continue;
- const TopTools_ListOfShape& aSharedFaces = mySharedFaces.FindFromKey(aEdge);
+ const TopTools_ListOfShape& aSharedFaces = aMapOfSharedFaces.FindFromKey(aEdge);
TopTools_ListIteratorOfListOfShape aSharedFaceIt(aSharedFaces);
for (; aSharedFaceIt.More(); aSharedFaceIt.Next())
{
aUsedFaces.Add(aFace);
toBeMeshed(aFace, Standard_False);
- myMesher->Add(aFace, mySharedFaces);
- myStatus |= (Standard_Integer)myMesher->CurrentFaceStatus();
+ myStatus |= myMesh->Add(aFace);
+ }
+ }
+}
+
+//=======================================================================
+//function : commit
+//purpose :
+//=======================================================================
+void BRepMesh_IncrementalMesh::commit()
+{
+ std::vector<TopoDS_Face>::iterator aFaceIt(myFaces.begin());
+ for (; aFaceIt != myFaces.end(); aFaceIt++)
+ commitFace(*aFaceIt);
+
+ discretizeFreeEdges();
+}
+
+//=======================================================================
+//function : commitFace
+//purpose :
+//=======================================================================
+void BRepMesh_IncrementalMesh::commitFace(const TopoDS_Face& theFace)
+{
+ TopoDS_Face aFace = theFace;
+ aFace.Orientation(TopAbs_FORWARD);
+
+ Handle(BRepMesh_FaceAttribute) aFaceAttribute;
+ if (!myMesh->GetFaceAttribute(aFace, aFaceAttribute))
+ return;
+
+ BRepMesh_ShapeTool::NullifyFace(aFace);
+
+ if (!aFaceAttribute->IsValid())
+ {
+ myStatus |= aFaceAttribute->GetStatus();
+ return;
+ }
+
+ TopLoc_Location aLoc = aFace.Location();
+ Handle(Poly_Triangulation) aOldTriangulation = BRep_Tool::Triangulation(aFace, aLoc);
+
+ try
+ {
+ OCC_CATCH_SIGNALS
+
+ Handle(BRepMesh_DataStructureOfDelaun)& aStructure = aFaceAttribute->ChangeStructure();
+ const BRepMeshCol::MapOfInteger& aTriangles = aStructure->ElementsOfDomain();
+ if (aTriangles.IsEmpty())
+ return;
+
+ BRepMeshCol::HIMapOfInteger& aVetrexEdgeMap = aFaceAttribute->ChangeVertexEdgeMap();
+
+ // Store triangles
+ Standard_Integer aVerticesNb = aVetrexEdgeMap->Extent();
+ Standard_Integer aTrianglesNb = aTriangles.Extent();
+ Handle(Poly_Triangulation) aNewTriangulation =
+ new Poly_Triangulation(aVerticesNb, aTrianglesNb, Standard_True);
+
+ Poly_Array1OfTriangle& aPolyTrianges = aNewTriangulation->ChangeTriangles();
+
+ Standard_Integer aTriangeId = 1;
+ BRepMeshCol::MapOfInteger::Iterator aTriIt(aTriangles);
+ for (; aTriIt.More(); aTriIt.Next())
+ {
+ const BRepMesh_Triangle& aCurElem = aStructure->GetElement(aTriIt.Key());
+
+ Standard_Integer aNode[3];
+ aStructure->ElementNodes(aCurElem, aNode);
+
+ Standard_Integer aNodeId[3];
+ for (Standard_Integer i = 0; i < 3; ++i)
+ aNodeId[i] = aVetrexEdgeMap->FindIndex(aNode[i]);
+
+ aPolyTrianges(aTriangeId++).Set(aNodeId[0], aNodeId[1], aNodeId[2]);
+ }
+
+ // Store mesh nodes
+ TColgp_Array1OfPnt& aNodes = aNewTriangulation->ChangeNodes();
+ TColgp_Array1OfPnt2d& aNodes2d = aNewTriangulation->ChangeUVNodes();
+
+ for (Standard_Integer i = 1; i <= aVerticesNb; ++i)
+ {
+ Standard_Integer aVertexId = aVetrexEdgeMap->FindKey(i);
+ const BRepMesh_Vertex& aVertex = aStructure->GetNode(aVertexId);
+ const gp_Pnt& aPoint = aFaceAttribute->GetPoint(aVertex);
+
+ aNodes(i) = aPoint;
+ aNodes2d(i) = aVertex.Coord();
}
+
+ aNewTriangulation->Deflection(aFaceAttribute->GetDefFace());
+ BRepMesh_ShapeTool::AddInFace(aFace, aNewTriangulation);
+
+ // Store discretization of edges
+ BRepMeshCol::HDMapOfShapePairOfPolygon& aInternalEdges = aFaceAttribute->ChangeInternalEdges();
+ BRepMeshCol::DMapOfShapePairOfPolygon::Iterator aEdgeIt(*aInternalEdges);
+ for (; aEdgeIt.More(); aEdgeIt.Next())
+ {
+ const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Key());
+ const BRepMesh_PairOfPolygon& aPolyPair = aEdgeIt.Value();
+ const Handle(Poly_PolygonOnTriangulation)& aPolygon1 = aPolyPair.First();
+ const Handle(Poly_PolygonOnTriangulation)& aPolygon2 = aPolyPair.Last();
+
+ BRepMesh_ShapeTool::NullifyEdge(aEdge, aOldTriangulation, aLoc);
+ if (aPolygon1 == aPolygon2)
+ BRepMesh_ShapeTool::UpdateEdge(aEdge, aPolygon1, aNewTriangulation, aLoc);
+ else
+ BRepMesh_ShapeTool::UpdateEdge(aEdge, aPolygon1, aPolygon2, aNewTriangulation, aLoc);
+ }
+ }
+ catch (Standard_Failure)
+ {
+ myStatus |= BRepMesh_Failure;
}
}
const TopoDS_Shape& theShape,
const Standard_Real theDeflection,
const Standard_Real theAngle,
- BRepMesh_PDiscretRoot& theAlgo)
+ BRepMesh_DiscretRoot* &theAlgo)
{
BRepMesh_IncrementalMesh* anAlgo = new BRepMesh_IncrementalMesh();
anAlgo->SetDeflection(theDeflection);
#include <BRepMesh_FastDiscret.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_DataMapOfShapeReal.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <BRepMesh_DiscretRoot.hxx>
-#include <BRepMesh_PDiscretRoot.hxx>
#include <Handle_Poly_Triangulation.hxx>
#include <BRepMesh_Collections.hxx>
Standard_EXPORT static Standard_Integer Discret(const TopoDS_Shape& theShape,
const Standard_Real theLinDeflection,
const Standard_Real theAngDeflection,
- BRepMesh_PDiscretRoot& theAlgo);
+ BRepMesh_DiscretRoot* &theAlgo);
//! Returns multi-threading usage flag set by default in
//! Discret() static method (thus applied only to Mesh Factories).
//! Discret() static method (thus applied only to Mesh Factories).
Standard_EXPORT static void SetParallelDefault(const Standard_Boolean isInParallel);
+ //! Returns mesh tool storing mesh data.
+ inline const Handle(BRepMesh_FastDiscret)& Mesh() const
+ {
+ return myMesh;
+ }
DEFINE_STANDARD_RTTI(BRepMesh_IncrementalMesh)
Standard_Boolean toBeMeshed(const TopoDS_Face& theFace,
const Standard_Boolean isWithCheck);
+ //! Stores mesh to the shape.
+ void commit();
+
+ //! Stores mesh to the face.
+ void commitFace(const TopoDS_Face& theFace);
+
protected:
- Standard_Boolean myRelative;
- Standard_Boolean myInParallel;
- BRepMeshCol::DMapOfEdgeListOfTriangulation myEmptyEdges;
- Handle(BRepMesh_FastDiscret) myMesher;
- Standard_Boolean myModified;
- TopTools_DataMapOfShapeReal myEdgeDeflection;
- TopTools_IndexedDataMapOfShapeListOfShape mySharedFaces;
- Standard_Real myMaxShapeSize;
- Standard_Integer myStatus;
- std::vector<TopoDS_Face> myFaces;
+ Standard_Boolean myRelative;
+ Standard_Boolean myInParallel;
+ BRepMeshCol::DMapOfEdgeListOfTriangulation myEmptyEdges;
+ Handle(BRepMesh_FastDiscret) myMesh;
+ Standard_Boolean myModified;
+ TopTools_DataMapOfShapeReal myEdgeDeflection;
+ Standard_Real myMaxShapeSize;
+ Standard_Integer myStatus;
+ std::vector<TopoDS_Face> myFaces;
};
DEFINE_STANDARD_HANDLE(BRepMesh_IncrementalMesh,BRepMesh_DiscretRoot)
Standard_EXPORT Standard_Integer DISCRETALGO(const TopoDS_Shape& , \
const Standard_Real, \
const Standard_Real, \
- BRepMesh_PDiscretRoot& ); \
+ BRepMesh_DiscretRoot* &); \
} \
\
-Standard_Integer DISCRETALGO(const TopoDS_Shape& theShape, \
- const Standard_Real theLinDeflection, \
- const Standard_Real theAngDeflection, \
- BRepMesh_PDiscretRoot& theAlgo) \
+Standard_Integer DISCRETALGO(const TopoDS_Shape& theShape, \
+ const Standard_Real theLinDeflection, \
+ const Standard_Real theAngDeflection, \
+ BRepMesh_DiscretRoot* &theAlgo) \
{ \
return name::Discret(theShape, theLinDeflection, \
theAngDeflection, theAlgo); \
#include <TColgp_Array1OfPnt.hxx>
#include <Poly_Triangulation.hxx>
#include <BRep_Builder.hxx>
+#include <TopExp.hxx>
+#include <BRepAdaptor_Curve.hxx>
namespace {
//! Auxilary struct to take a tolerance of edge.
return aDefEdge;
Bnd_Box aBox;
- BRepBndLib::Add(theEdge, aBox);
+ BRepBndLib::Add(theEdge, aBox, Standard_False);
BoxMaxDimension(aBox, aDefEdge);
// Adjust resulting value in relation to the total size
//purpose :
//=======================================================================
gp_XY BRepMesh_ShapeTool::FindUV(
- const Standard_Integer theIndexOfPnt3d,
- const gp_Pnt2d& thePnt2d,
- const TopoDS_Vertex& theVertex,
- const Standard_Real theMinDistance,
- const Handle(BRepMesh_FaceAttribute)& theFaceAttribute,
- const Handle(BRepAdaptor_HSurface)& theSurface,
- BRepMeshCol::DMapOfIntegerListOfXY& theLocation2dMap)
+ const Standard_Integer theIndexOfPnt3d,
+ const gp_Pnt2d& thePnt2d,
+ const TopoDS_Vertex& theVertex,
+ const Standard_Real theMinDistance,
+ const Handle(BRepMesh_FaceAttribute)& theFaceAttribute)
{
const gp_XY& aPnt2d = thePnt2d.Coord();
- if (!theLocation2dMap.IsBound(theIndexOfPnt3d))
+ BRepMeshCol::DMapOfIntegerListOfXY& aLocation2D =
+ theFaceAttribute->ChangeLocation2D();
+
+ if (!aLocation2D.IsBound(theIndexOfPnt3d))
{
BRepMeshCol::ListOfXY aPoints2d;
aPoints2d.Append(aPnt2d);
- theLocation2dMap.Bind(theIndexOfPnt3d, aPoints2d);
+ aLocation2D.Bind(theIndexOfPnt3d, aPoints2d);
return aPnt2d;
}
- BRepMeshCol::ListOfXY& aPoints2d =
- theLocation2dMap.ChangeFind(theIndexOfPnt3d);
+ BRepMeshCol::ListOfXY& aPoints2d = aLocation2D.ChangeFind(theIndexOfPnt3d);
// Find the most closest 2d point to the given one.
gp_XY aUV;
Min(2. * BRep_Tool::Tolerance(theVertex), theMinDistance);
// Get face limits
- Standard_Real aDiffU, aDiffV;
- if (theFaceAttribute.IsNull())
- {
- aDiffU = theSurface->LastUParameter() - theSurface->FirstUParameter();
- aDiffV = theSurface->LastVParameter() - theSurface->FirstVParameter();
- }
- else
- {
- aDiffU = theFaceAttribute->GetUMax() - theFaceAttribute->GetUMin();
- aDiffV = theFaceAttribute->GetVMax() - theFaceAttribute->GetVMin();
- }
+ Standard_Real aDiffU = theFaceAttribute->GetUMax() - theFaceAttribute->GetUMin();
+ Standard_Real aDiffV = theFaceAttribute->GetVMax() - theFaceAttribute->GetVMin();
const Standard_Real Utol2d = .5 * aDiffU;
const Standard_Real Vtol2d = .5 * aDiffV;
- const gp_Pnt aPnt1 = theSurface->Value( aUV.X(), aUV.Y());
- const gp_Pnt aPnt2 = theSurface->Value(aPnt2d.X(), aPnt2d.Y());
+ const Handle(BRepAdaptor_HSurface)& aSurface = theFaceAttribute->Surface();
+ const gp_Pnt aPnt1 = aSurface->Value(aUV.X(), aUV.Y());
+ const gp_Pnt aPnt2 = aSurface->Value(aPnt2d.X(), aPnt2d.Y());
//! If selected point is too far from the given one in parametric space
//! or their positions in 3d are different, add the given point as unique.
aBuilder.UpdateEdge(theEdge, thePolygon1, thePolygon2,
theTriangulation, theLocation);
}
+
+//=======================================================================
+//function : UseLocation
+//purpose :
+//=======================================================================
+gp_Pnt BRepMesh_ShapeTool::UseLocation(const gp_Pnt& thePnt,
+ const TopLoc_Location& theLoc)
+{
+ if (theLoc.IsIdentity())
+ return thePnt;
+
+ return thePnt.Transformed(theLoc.Transformation());
+}
+
+//=======================================================================
+//function : IsDegenerated
+//purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_ShapeTool::IsDegenerated(
+ const TopoDS_Edge& theEdge,
+ const TopoDS_Face& theFace)
+{
+ // Get vertices
+ TopoDS_Vertex pBegin, pEnd;
+ TopExp::Vertices(theEdge, pBegin, pEnd);
+ if (pBegin.IsNull() || pEnd.IsNull())
+ return Standard_True;
+
+ if (BRep_Tool::Degenerated(theEdge))
+ return Standard_True;
+
+ if (!pBegin.IsSame(pEnd))
+ return Standard_False;
+
+ Standard_Real wFirst, wLast;
+ BRep_Tool::Range(theEdge, theFace, wFirst, wLast);
+
+ // calculation of the length of the edge in 3D
+ Standard_Real longueur = 0.0;
+ Standard_Real du = (wLast - wFirst) * 0.05;
+ gp_Pnt P1, P2;
+ BRepAdaptor_Curve BC(theEdge);
+ BC.D0(wFirst, P1);
+ Standard_Real tolV = BRep_Tool::Tolerance(pBegin);
+ Standard_Real tolV2 = 1.2 * tolV;
+
+ for (Standard_Integer l = 1; l <= 20; ++l)
+ {
+ BC.D0(wFirst + l * du, P2);
+ longueur += P1.Distance(P2);
+
+ if (longueur > tolV2)
+ break;
+
+ P1 = P2;
+ }
+
+ if (longueur < tolV2)
+ return Standard_True;
+
+ return Standard_False;
+}
//! Gets the maximum dimension of the given bounding box.
//! If the given bounding box is void leaves the resulting value unchanged.
- //! \param theBox bounding box to be processed.
- //! \param theMaxDimension maximum dimension of the given box.
+ //! @param theBox bounding box to be processed.
+ //! @param theMaxDimension maximum dimension of the given box.
Standard_EXPORT static void BoxMaxDimension(const Bnd_Box& theBox,
Standard_Real& theMaxDimension);
//! Returns relative deflection for edge with respect to shape size.
- //! \param theEdge edge for which relative deflection should be computed.
- //! \param theDeflection absolute deflection.
- //! \param theMaxShapeSize maximum size of a shape.
- //! \param theAdjustmentCoefficient coefficient of adjustment between maximum
+ //! @param theEdge edge for which relative deflection should be computed.
+ //! @param theDeflection absolute deflection.
+ //! @param theMaxShapeSize maximum size of a shape.
+ //! @param theAdjustmentCoefficient coefficient of adjustment between maximum
//! size of shape and calculated relative deflection.
- //! \return relative deflection for the edge.
+ //! @return relative deflection for the edge.
Standard_EXPORT static Standard_Real RelativeEdgeDeflection(
const TopoDS_Edge& theEdge,
const Standard_Real theDeflection,
//! Checks 2d representations of 3d point with the
//! given index for equality to avoid duplications.
- //! \param theIndexOfPnt3d index of 3d point with which 2d
+ //! @param theIndexOfPnt3d index of 3d point with which 2d
//! representation should be associated.
- //! \param thePnt2d 2d representation of the point with the
+ //! @param thePnt2d 2d representation of the point with the
//! given index.
- //! \param theVertex vertex corresponded to 3d point with the
+ //! @param theVertex vertex corresponded to 3d point with the
//! given index. Used to extract vertex tolerance in 3d space.
- //! \param theMinDistance minimum distance between vertices
+ //! @param theMinDistance minimum distance between vertices
//! regarding which they could be treated as distinct ones.
//! This value is defined by mesher using parameters given by
//! user in connection with shape metrics.
- //! \param theFaceAttribute attributes contining data calculated
+ //! @param theFaceAttribute attributes contining data calculated
//! according to face geomtry and define limits of face in parametric
//! space. If defined, will be used instead of surface parameter.
- //! \param theSurface surface within which parametric space
- //! the 2d point is defined. Supposed to be used in case if face
- //! attributes are not defined by the moment of method invocation.
- //! \param theLocation2dMap map of 2d representations of 3d points.
- //! \return given 2d point in case if 3d poind does not alredy have
+ //! @param theLocation2dMap map of 2d representations of 3d points.
+ //! @return given 2d point in case if 3d poind does not alredy have
//! the similar representation, otherwice 2d point corresponding to
//! existing representation will be returned.
Standard_EXPORT static gp_XY FindUV(
const gp_Pnt2d& thePnt2d,
const TopoDS_Vertex& theVertex,
const Standard_Real theMinDistance,
- const Handle(BRepMesh_FaceAttribute)& theFaceAttribute,
- const Handle(BRepAdaptor_HSurface)& theSurface,
- BRepMeshCol::DMapOfIntegerListOfXY& theLocation2dMap);
+ const Handle(BRepMesh_FaceAttribute)& theFaceAttribute);
//! Stores the given triangulation into the given face.
- //! \param theFace face to be updated by triangulation.
- //! \param theTriangulation triangulation to be stored into the face.
+ //! @param theFace face to be updated by triangulation.
+ //! @param theTriangulation triangulation to be stored into the face.
Standard_EXPORT static void AddInFace(
const TopoDS_Face& theFace,
Handle(Poly_Triangulation)& theTriangulation);
//! Nullifies triangulation stored in the face.
- //! \param theFace face to be updated by null triangulation.
+ //! @param theFace face to be updated by null triangulation.
Standard_EXPORT static void NullifyFace(const TopoDS_Face& theFace);
//! Nullifies polygon on triangulation stored in the edge.
- //! \param theEdge edge to be updated by null polygon.
- //! \param theTriangulation triangulation the given edge is associated to.
- //! \param theLocation face location.
+ //! @param theEdge edge to be updated by null polygon.
+ //! @param theTriangulation triangulation the given edge is associated to.
+ //! @param theLocation face location.
Standard_EXPORT static void NullifyEdge(
const TopoDS_Edge& theEdge,
const Handle(Poly_Triangulation)& theTriangulation,
const TopLoc_Location& theLocation);
//! Updates the given edge by the given tessellated representation.
- //! \param theEdge edge to be updated.
- //! \param thePolygon tessellated representation of the edge to be stored.
- //! \param theTriangulation triangulation the given edge is associated to.
- //! \param theLocation face location.
+ //! @param theEdge edge to be updated.
+ //! @param thePolygon tessellated representation of the edge to be stored.
+ //! @param theTriangulation triangulation the given edge is associated to.
+ //! @param theLocation face location.
Standard_EXPORT static void UpdateEdge(
const TopoDS_Edge& theEdge,
const Handle(Poly_PolygonOnTriangulation)& thePolygon,
const TopLoc_Location& theLocation);
//! Updates the given seam edge by the given tessellated representations.
- //! \param theEdge edge to be updated.
- //! \param thePolygon1 tessellated representation corresponding to
+ //! @param theEdge edge to be updated.
+ //! @param thePolygon1 tessellated representation corresponding to
//! forward direction of the seam edge.
- //! \param thePolygon2 tessellated representation corresponding to
+ //! @param thePolygon2 tessellated representation corresponding to
//! reversed direction of the seam edge.
- //! \param theTriangulation triangulation the given edge is associated to.
- //! \param theLocation face location.
+ //! @param theTriangulation triangulation the given edge is associated to.
+ //! @param theLocation face location.
Standard_EXPORT static void UpdateEdge(
const TopoDS_Edge& theEdge,
const Handle(Poly_PolygonOnTriangulation)& thePolygon1,
const Handle(Poly_PolygonOnTriangulation)& thePolygon2,
const Handle(Poly_Triangulation)& theTriangulation,
const TopLoc_Location& theLocation);
+
+ //! Applies location to the given point and return result.
+ //! @param thePnt point to be transformed.
+ //! @param theLoc location to be applied.
+ Standard_EXPORT static gp_Pnt UseLocation(const gp_Pnt& thePnt,
+ const TopLoc_Location& theLoc);
+
+ //! Checks is the given edge degenerated.
+ //! Checks geometrical parameters in case if IsDegenerated flag is not set.
+ //! @param theEdge edge to be checked.
+ //! @param theFace face within which parametric space edge will be checked
+ //! for geometrical degenerativity.
+ Standard_EXPORT static Standard_Boolean IsDegenerated(
+ const TopoDS_Edge& theEdge,
+ const TopoDS_Face& theFace);
};
#endif
//! \return TRUE if equal, FALSE if not.
Standard_EXPORT Standard_Boolean IsEqual(const BRepMesh_Vertex& theOther) const
{
- if (myMovability != BRepMesh_Deleted ||
- theOther.myMovability != BRepMesh_Deleted)
+ if (myMovability == BRepMesh_Deleted ||
+ theOther.myMovability == BRepMesh_Deleted)
{
return Standard_False;
}
#include <BRepTools_WireExplorer.hxx>
#include <TopAbs_Orientation.hxx>
#include <TopoDS.hxx>
-#include <TopoDS_Iterator.hxx>
+#include <TopExp_Explorer.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <BRepMesh_PairOfPolygon.hxx>
#include <TColStd_SequenceOfInteger.hxx>
BRepMesh_WireChecker::BRepMesh_WireChecker(
const TopoDS_Face& theFace,
const Standard_Real theTolUV,
- const BRepMeshCol::DMapOfShapePairOfPolygon& theEdges,
- const TColStd_IndexedMapOfInteger& theVertexMap,
+ const BRepMeshCol::HDMapOfShapePairOfPolygon& theEdges,
+ const BRepMeshCol::HIMapOfInteger& theVertexMap,
const Handle(BRepMesh_DataStructureOfDelaun)& theStructure,
const Standard_Real theUmin,
const Standard_Real theUmax,
TopoDS_Face aFace = theFace;
aFace.Orientation(TopAbs_FORWARD);
- TopoDS_Iterator aFaceExplorer(aFace);
+ TopExp_Explorer aFaceExplorer(aFace, TopAbs_WIRE);
for (; aFaceExplorer.More(); aFaceExplorer.Next())
{
- const TopoDS_Shape& aWire = aFaceExplorer.Value();
- if (aWire.ShapeType() != TopAbs_WIRE)
- continue;
+ const TopoDS_Wire& aWire = TopoDS::Wire(aFaceExplorer.Current());
myWiresEdges.push_back(ListOfEdges());
ListOfEdges& aEdges = myWiresEdges.back();
// Start traversing the wires
- BRepTools_WireExplorer aWireExplorer(TopoDS::Wire(aWire), aFace);
+ BRepTools_WireExplorer aWireExplorer(aWire, aFace);
for (; aWireExplorer.More(); aWireExplorer.Next())
{
const TopoDS_Edge& aEdge = aWireExplorer.Current();
{
const TopoDS_Edge& aEdge = aEdgeIt.Value();
TopAbs_Orientation aOrient = aEdge.Orientation();
- if (!myEdges.IsBound(aEdge))
+ 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);
+ const BRepMesh_PairOfPolygon& aPair = myEdges->Find(aEdge);
Handle(Poly_PolygonOnTriangulation) aNOD;
if (aOrient == TopAbs_FORWARD)
{
}
const TColStd_Array1OfInteger& aIndices = aNOD->Nodes();
- const Standard_Integer aFirstVertexId = myVertexMap.FindKey(aIndices(aStartId));
- const Standard_Integer aLastVertexId = myVertexMap.FindKey(aIndices(aEndId) );
+ const Standard_Integer aFirstVertexId = myVertexMap->FindKey(aIndices(aStartId));
+ const Standard_Integer aLastVertexId = myVertexMap->FindKey(aIndices(aEndId) );
if (aFirstVertexId == aLastVertexId && (aEndId - aStartId) == aIncrement)
{
{
Standard_Integer aIndex = ((i == aStartId) ?
aFirstVertexId :
- myVertexMap.FindKey(aIndices(i)));
+ myVertexMap->FindKey(aIndices(i)));
aSeqPnt2d.Append(gp_Pnt2d(myStructure->GetNode(aIndex).Coord()));
}
Standard_EXPORT BRepMesh_WireChecker(
const TopoDS_Face& theFace,
const Standard_Real theTolUV,
- const BRepMeshCol::DMapOfShapePairOfPolygon& theEdges,
- const TColStd_IndexedMapOfInteger& theVertexMap,
+ const BRepMeshCol::HDMapOfShapePairOfPolygon& theEdges,
+ const BRepMeshCol::HIMapOfInteger& theVertexMap,
const Handle(BRepMesh_DataStructureOfDelaun)& theStructure,
const Standard_Real theUmin,
const Standard_Real theUmax,
private:
const Standard_Real myTolUV;
- const BRepMeshCol::DMapOfShapePairOfPolygon& myEdges;
- const TColStd_IndexedMapOfInteger& myVertexMap;
+ const BRepMeshCol::HDMapOfShapePairOfPolygon& myEdges;
+ const BRepMeshCol::HIMapOfInteger& myVertexMap;
const Handle(BRepMesh_DataStructureOfDelaun)& myStructure;
const Standard_Real myUmin;
const Standard_Real myUmax;
BRepMesh_FaceChecker.hxx
BRepMesh_SelectorOfDataStructureOfDelaun.hxx
BRepMesh_SelectorOfDataStructureOfDelaun.cxx
+BRepMesh_EdgeParameterProvider.hxx
+BRepMesh_EdgeParameterProvider.cxx
+BRepMesh_IEdgeTool.hxx
+BRepMesh_IEdgeTool.cxx
+BRepMesh_EdgeTessellationExtractor.hxx
+BRepMesh_EdgeTessellationExtractor.cxx
+BRepMesh_EdgeTessellator.hxx
+BRepMesh_EdgeTessellator.cxx
BRepMesh_FastDiscretFace.hxx
BRepMesh_FastDiscretFace.cxx
BRepMesh_FastDiscret.hxx
#include <BRepBndLib.hxx>
#include <BRepMesh_DiscretFactory.hxx>
#include <BRepMesh_DiscretRoot.hxx>
-#include <BRepMesh_PDiscretRoot.hxx>
#include <BRepTools.hxx>
#include <Hatch_Hatcher.hxx>
#include <GCPnts_QuasiUniformDeflection.hxx>
static Standard_Integer triangule(Draw_Interpretor& di, Standard_Integer nbarg, const char** argv)
{
- if (nbarg < 4) return 1;
-
- Standard_Boolean save = Standard_False;
+ if (nbarg < 4)
+ return 1;
const char *id1 = argv[2];
- TopoDS_Shape S = DBRep::Get(id1);
- if (S.IsNull()) return 1;
- di << argv[1] << " ";
- Standard_Real Deflect=Draw::Atof(argv[3]);
- if (Deflect<=0.) {
- di << " Donner la fleche !" << "\n";
+ TopoDS_Shape aShape = DBRep::Get(id1);
+ if (aShape.IsNull())
return 1;
- }
- if (nbarg >4) {
- save = (Draw::Atoi(argv[4])==1);
- }
+ di << argv[1] << " ";
- Standard_Boolean partage=Standard_True;
- if (nbarg>5) {
- partage=Draw::Atoi(argv[5])==1;
+ Standard_Real aDeflection = Draw::Atof(argv[3]);
+ if (aDeflection <= 0.)
+ {
+ di << " Incorrect value of deflection!" << "\n";
+ return 1;
}
- Handle(MeshTest_DrawableMesh) DM =
- new MeshTest_DrawableMesh(S,Deflect,partage, save);
+ Handle(MeshTest_DrawableMesh) aDMesh =
+ new MeshTest_DrawableMesh(aShape, aDeflection);
- Draw::Set(argv[1],DM);
+ Draw::Set(argv[1], aDMesh);
Standard_Integer nbn, nbl, nbe;
- MeshStats(S, nbe, nbl, nbn);
+ MeshStats(aShape, nbe, nbl, nbn);
di<<"(Resultat ("<<nbe<<" mailles) ("<<nbl<<" aretes) ("<<nbn<<" sommets))"<<"\n";
}
}*/
- Bnd_Box bobo;
- for (Standard_Integer lepnt=1; lepnt<DM->Mesh()->NbPoint3d(); lepnt++) {
- bobo.Add(DM->Mesh()->Point3d(lepnt));
+ Bnd_Box aBox;
+ const Handle(BRepMesh_FastDiscret)& aFastDiscret = aDMesh->Mesher()->Mesh();
+
+ TopExp_Explorer aFaceIt(aShape, TopAbs_FACE);
+ for (; aFaceIt.More(); aFaceIt.Next())
+ {
+ const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
+
+ Handle(BRepMesh_FaceAttribute) anAttribute;
+ if (aFastDiscret->GetFaceAttribute(aFace, anAttribute) && anAttribute->IsValid())
+ {
+ const Standard_Integer aNbPnts = anAttribute->LastPointId();
+ for (Standard_Integer i = 1; i < aNbPnts; ++i)
+ aBox.Add(anAttribute->GetPoint(i));
+ }
+ }
+
+ Standard_Real aDelta = 0.;
+ if (!aBox.IsVoid())
+ {
+ Standard_Real x, y, z, X, Y, Z;
+ aBox.Get(x, y, z, X, Y, Z);
+
+ aDelta = Max(X - x, Max(Y - y, Z - z));
+ if (aDelta > 0.0)
+ aDelta = aDeflection / aDelta;
}
- Standard_Real x,y,z,X,Y,Z;
- bobo.Get(x,y,z,X,Y,Z);
- Standard_Real delta=Max(X-x,Max(Y-y,Z-z));
- if (delta>0) delta=Deflect/delta;
- di << " Fleche de " << delta << " fois la taille de l''objet." << "\n";
+
+ di << " Ratio between deflection and total shape size is " << aDelta << "\n";
return 0;
}
//function : vertices
//purpose :
//=======================================================================
-
-static Standard_Integer vertices (Draw_Interpretor&, Standard_Integer n, const char** a)
+static Standard_Integer vertices(
+ Draw_Interpretor& /*di*/,
+ Standard_Integer /*argc*/,
+ const char** /*argv*/)
{
- if (n < 3) return 1;
-
- Handle(MeshTest_DrawableMesh) D =
- Handle(MeshTest_DrawableMesh)::DownCast(Draw::Get(a[1]));
- if (D.IsNull()) return 1;
- TopoDS_Shape S = DBRep::Get(a[2]);
- if (S.IsNull()) return 1;
-
- TopExp_Explorer ex;
- TColStd_SequenceOfInteger& vseq = D->Vertices();
- Handle(BRepMesh_FastDiscret) M = D->Mesh();
-
- // the faces
- for (ex.Init(S,TopAbs_FACE);ex.More();ex.Next()) {
- BRepMeshCol::MapOfInteger vtx;
- M->VerticesOfDomain(vtx);
- for (BRepMeshCol::MapOfInteger::Iterator it(vtx); it.More(); it.Next())
- vseq.Append(it.Key());
- }
-
+ return 0;
- // the edges
- //for (ex.Init(S,TopAbs_EDGE,TopAbs_FACE);ex.More();ex.Next()) {
+ // TODO: OAN re-implement this command according changes in BRepMesh
+ //if (argc < 3)
+ // return 1;
+
+ //Handle(MeshTest_DrawableMesh) aDrawableMesh =
+ // Handle(MeshTest_DrawableMesh)::DownCast(Draw::Get(argv[1]));
+ //if (aDrawableMesh.IsNull())
+ // return 1;
+
+ //TopoDS_Shape aShape = DBRep::Get(argv[2]);
+ //if (aShape.IsNull())
+ // return 1;
+
+ //TColStd_SequenceOfInteger& aVertexSeq = aDrawableMesh->Vertices();
+ //Handle(BRepMesh_FastDiscret) aMesh = aDrawableMesh->Mesh();
+
+ //TopExp_Explorer aFaceIt(aShape, TopAbs_FACE);
+ //for (; aFaceIt.More(); aFaceIt.Next())
+ //{
+ // const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
+
+ // Handle(BRepMesh_FaceAttribute) aAttribute;
+ // if (aMesh->GetFaceAttribute(aFace, aAttribute))
+ // {
+ // Handle(BRepMesh_DataStructureOfDelaun) aStructure = aAttribute->EditStructure();
+
+ // // Recuperate from the map of edges.
+ // const BRepMeshCol::MapOfInteger& aEdgeMap = aStructure->LinksOfDomain();
+
+ // // Iterator on edges.
+ // BRepMeshCol::MapOfInteger aVertices;
+ // BRepMeshCol::MapOfInteger::Iterator aEdgeIt(aEdgeMap);
+ // for (; aEdgeIt.More(); aEdgeIt.Next())
+ // {
+ // const BRepMesh_Edge& aEdge = aStructure->GetLink(aEdgeIt.Key());
+ // aVertices.Add(aEdge.FirstNode());
+ // aVertices.Add(aEdge.LastNode());
+ // }
+
+ // BRepMeshCol::MapOfInteger::Iterator anIt(vtx);
+ // for ( ; anIt.More(); anIt.Next() )
+ // aVertexSeq.Append(anIt.Key());
+ // }
//}
- Draw::Repaint();
- return 0;
+ //Draw::Repaint();
+ //return 0;
}
//=======================================================================
theCommands.Add("incmesh","incmesh shape deflection [inParallel (0/1) : 0 by default]",__FILE__, incrementalmesh, g);
theCommands.Add("MemLeakTest","MemLeakTest",__FILE__, MemLeakTest, g);
theCommands.Add("fastdiscret","fastdiscret shape deflection [shared [nbiter]]",__FILE__, fastdiscret, g);
- theCommands.Add("mesh","mesh result Shape deflection [save partage]",__FILE__, triangule, g);
+ theCommands.Add("mesh","mesh result Shape deflection",__FILE__, triangule, g);
theCommands.Add("addshape","addshape meshname Shape [deflection]",__FILE__, addshape, g);
//theCommands.Add("smooth","smooth meshname",__FILE__, smooth, g);
//theCommands.Add("edges","edges mesh shape, highlight the edges",__FILE__,edges, g);
#include <BRepMesh_Vertex.hxx>
#include <BRepMesh_Triangle.hxx>
#include <BRepMesh_DataStructureOfDelaun.hxx>
-#include <Bnd_Box.hxx>
-#include <BRepBndLib.hxx>
+#include <TopExp_Explorer.hxx>
IMPLEMENT_STANDARD_HANDLE (MeshTest_DrawableMesh, Draw_Drawable3D)
IMPLEMENT_STANDARD_RTTIEXT(MeshTest_DrawableMesh, Draw_Drawable3D)
//function : MeshTest_DrawableMesh
//purpose :
//=======================================================================
-
-MeshTest_DrawableMesh::MeshTest_DrawableMesh() :
-myDeflection(1.), myinshape(Standard_False)
+MeshTest_DrawableMesh::MeshTest_DrawableMesh()
+ : myDeflection(1.)
{
}
//function : MeshTest_DrawableMesh
//purpose :
//=======================================================================
-
-MeshTest_DrawableMesh::MeshTest_DrawableMesh(const TopoDS_Shape& S,
- const Standard_Real Deflect,
- const Standard_Boolean Partage,
- const Standard_Boolean inshape) :
-myDeflection(Deflect), myinshape(inshape)
+MeshTest_DrawableMesh::MeshTest_DrawableMesh(const TopoDS_Shape& theShape,
+ const Standard_Real theDeflection)
+ : myDeflection(theDeflection)
{
- Bnd_Box B;
- BRepBndLib::Add(S, B);
-
- myMesh = new BRepMesh_FastDiscret(S, Deflect, 0.5, B, Partage, inshape);
+ Add(theShape);
}
-
//=======================================================================
//function : MeshTest_DrawableMesh
//purpose :
//=======================================================================
-
-MeshTest_DrawableMesh::MeshTest_DrawableMesh(const Handle(BRepMesh_FastDiscret)& Tr):
-myDeflection(1.0)
+MeshTest_DrawableMesh::MeshTest_DrawableMesh(
+ const Handle(BRepMesh_IncrementalMesh)& theMesher)
+ : myDeflection(1.)
{
- myMesh = Tr;
+ myMesher = theMesher;
+ if (!myMesher.IsNull())
+ myDeflection = myMesher->Deflection();
}
-
//=======================================================================
//function : MeshTest_DrawableMesh
//purpose :
//=======================================================================
-
-void MeshTest_DrawableMesh::Add(const TopoDS_Shape& S)
-{
- Bnd_Box B;
- BRepBndLib::Add(S, B);
-
- if (myMesh.IsNull())
- myMesh=new BRepMesh_FastDiscret(S, myDeflection, 0.5, B, myinshape);
- else
- myMesh->Perform(S);
-}
-
-//=======================================================================
-//function : AddInShape
-//purpose :
-//=======================================================================
-
-void MeshTest_DrawableMesh::AddInShape(const Standard_Boolean inshape)
+void MeshTest_DrawableMesh::Add(const TopoDS_Shape& theShape)
{
- myinshape = inshape;
+ if (myMesher.IsNull())
+ {
+ myMesher = new BRepMesh_IncrementalMesh;
+ myMesher->SetDeflection(myDeflection);
+ myMesher->SetAngle(0.5);
+ }
+
+ myMesher->SetShape(theShape);
+ myMesher->Perform();
}
//=======================================================================
//function : Copy
//purpose :
//=======================================================================
-
Handle(Draw_Drawable3D) MeshTest_DrawableMesh::Copy() const
{
- Handle(MeshTest_DrawableMesh) D = new MeshTest_DrawableMesh();
- return D;
+ return new MeshTest_DrawableMesh(myMesher);
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
-
void MeshTest_DrawableMesh::Dump(Standard_OStream&) const
{
// Should be reimplemented
//function : Whatis
//purpose :
//=======================================================================
-
-void MeshTest_DrawableMesh::Whatis(Draw_Interpretor& S) const
+void MeshTest_DrawableMesh::Whatis(Draw_Interpretor& theStream) const
{
- S << " 3d mesh\n";
- S << " - Triangles : " << myMesh->NbTriangles() << "\n";
- S << " - Edges : " << myMesh->NbEdges() << "\n";
- S << " - Vertices : " << myMesh->NbVertices() << "\n";
- S << " - Point3d : " << myMesh->NbPoint3d() << "\n";
+ const Handle(BRepMesh_FastDiscret)& aMesh = myMesher->Mesh();
+ Standard_Integer aPointsNb = aMesh->NbBoundaryPoints();
+ Standard_Integer aTrianglesNb = 0;
+ Standard_Integer aEdgesNb = 0;
+
+ const TopoDS_Shape& aShape = myMesher->Shape();
+ TopExp_Explorer aFaceIt(aShape, TopAbs_FACE);
+ for (; aFaceIt.More(); aFaceIt.Next())
+ {
+ const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
+
+ Handle(BRepMesh_FaceAttribute) aAtrribure;
+ if (!aMesh->GetFaceAttribute(aFace, aAtrribure) || !aAtrribure->IsValid())
+ continue;
+
+ aPointsNb += aAtrribure->ChangeSurfacePoints()->Extent();
+
+ Handle(BRepMesh_DataStructureOfDelaun)& aStructure =
+ aAtrribure->ChangeStructure();
+
+ aTrianglesNb += aStructure->ElementsOfDomain().Extent();
+ aEdgesNb += aStructure->LinksOfDomain().Extent();
+ }
+
+ theStream << " 3d mesh\n";
+ theStream << " - Triangles : " << aTrianglesNb << "\n";
+ theStream << " - Edges : " << aEdgesNb << "\n";
+ theStream << " - Point3d : " << aPointsNb << "\n";
}
//=======================================================================
-//function : Mesh
+//function : Mesher
//purpose :
//=======================================================================
-
-Handle(BRepMesh_FastDiscret) MeshTest_DrawableMesh::Mesh() const
+const Handle(BRepMesh_IncrementalMesh)& MeshTest_DrawableMesh::Mesher() const
{
- return myMesh;
+ return myMesher;
}
//function : Edges
//purpose :
//=======================================================================
-
TColStd_SequenceOfInteger& MeshTest_DrawableMesh::Edges()
{
return myEdges;
//function : Vertices
//purpose :
//=======================================================================
-
TColStd_SequenceOfInteger& MeshTest_DrawableMesh::Vertices()
{
return myVertices;
//function : Triangles
//purpose :
//=======================================================================
-
TColStd_SequenceOfInteger& MeshTest_DrawableMesh::Triangles()
{
return myTriangles;
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
-#include <BRepMesh_FastDiscret.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
#include <TColStd_SequenceOfInteger.hxx>
#include <Draw_Drawable3D.hxx>
#include <Handle_Draw_Drawable3D.hxx>
Standard_EXPORT MeshTest_DrawableMesh();
- Standard_EXPORT MeshTest_DrawableMesh(const TopoDS_Shape& S,const Standard_Real Deflect,const Standard_Boolean Partage,const Standard_Boolean InShape = Standard_False);
+ Standard_EXPORT MeshTest_DrawableMesh(const TopoDS_Shape& theShape,
+ const Standard_Real theDeflection);
- Standard_EXPORT MeshTest_DrawableMesh(const Handle(BRepMesh_FastDiscret)& Tr);
+ Standard_EXPORT MeshTest_DrawableMesh(const Handle(BRepMesh_IncrementalMesh)& theMesher);
- Standard_EXPORT void AddInShape(const Standard_Boolean inshape) ;
+ Standard_EXPORT void Add(const TopoDS_Shape& theShape);
- Standard_EXPORT void Add(const TopoDS_Shape& S) ;
+ Standard_EXPORT TColStd_SequenceOfInteger& Edges();
- Standard_EXPORT TColStd_SequenceOfInteger& Edges() ;
+ Standard_EXPORT TColStd_SequenceOfInteger& Vertices();
- Standard_EXPORT TColStd_SequenceOfInteger& Vertices() ;
+ Standard_EXPORT TColStd_SequenceOfInteger& Triangles();
- Standard_EXPORT TColStd_SequenceOfInteger& Triangles() ;
+ Standard_EXPORT void DrawOn(Draw_Display& theDisplay) const;
- Standard_EXPORT void DrawOn(Draw_Display& dis) const;
+ Standard_EXPORT virtual Handle_Draw_Drawable3D Copy() const;
- Standard_EXPORT virtual Handle_Draw_Drawable3D Copy() const;
+ Standard_EXPORT virtual void Dump(Standard_OStream& theStream) const;
- Standard_EXPORT virtual void Dump(Standard_OStream& S) const;
+ Standard_EXPORT virtual void Whatis(Draw_Interpretor& theDi) const;
- Standard_EXPORT virtual void Whatis(Draw_Interpretor& S) const;
-
- Standard_EXPORT Handle(BRepMesh_FastDiscret) Mesh() const;
+ Standard_EXPORT const Handle(BRepMesh_IncrementalMesh)& Mesher() const;
DEFINE_STANDARD_RTTI(MeshTest_DrawableMesh)
private:
- Handle(BRepMesh_FastDiscret) myMesh;
- Standard_Real myDeflection;
- TColStd_SequenceOfInteger myEdges;
- TColStd_SequenceOfInteger myVertices;
- TColStd_SequenceOfInteger myTriangles;
- Standard_Boolean myinshape;
+ Handle(BRepMesh_IncrementalMesh) myMesher;
+ Standard_Real myDeflection;
+ TColStd_SequenceOfInteger myEdges;
+ TColStd_SequenceOfInteger myVertices;
+ TColStd_SequenceOfInteger myTriangles;
};
DEFINE_STANDARD_HANDLE(MeshTest_DrawableMesh, Draw_Drawable3D)
#include <BRepMesh_DiscretRoot.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <Bnd_Box.hxx>
-#include <BRepMesh_PDiscretRoot.hxx>
+#include <BRepMesh_DiscretRoot.hxx>
#include <Draw.hxx>
#include <DBRep.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
--- /dev/null
+XBRepMesh.hxx
+XBRepMesh.cxx
+++ /dev/null
--- Created on: 2008-04-11
--- Created by: Peter KURNEV
--- 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.
-
-package XBRepMesh
-
- ---Purpose:
-
-uses
- TopoDS,
- BRepMesh
-
-is
- Discret(theShape : Shape from TopoDS;
- theDeflection : Real from Standard;
- theAngle : Real from Standard;
- theAlgo:out PDiscretRoot from BRepMesh)
- returns Integer from Standard;
-
-end XBRepMesh;
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-#include <XBRepMesh.ixx>
+#include <XBRepMesh.hxx>
#include <BRepMesh_PluginMacro.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
//function : Discret
//purpose :
//=======================================================================
-Standard_Integer XBRepMesh::Discret(const TopoDS_Shape& theShape,
- const Standard_Real theDeflection,
- const Standard_Real theAngle,
- BRepMesh_PDiscretRoot& theAlgo)
+Standard_Integer XBRepMesh::Discret(
+ const TopoDS_Shape& theShape,
+ const Standard_Real theDeflection,
+ const Standard_Real theAngle,
+ BRepMesh_DiscretRoot* &theAlgo)
{
Standard_Integer iErr;
//
--- /dev/null
+// Created on: 2008-04-11
+// Created by: Peter KURNEV
+// 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.
+
+#ifndef _XBRepMesh_HeaderFile
+#define _XBRepMesh_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Macro.hxx>
+#include <BRepMesh_DiscretRoot.hxx>
+
+class TopoDS_Shape;
+
+class XBRepMesh
+{
+public:
+
+ DEFINE_STANDARD_ALLOC
+
+ Standard_EXPORT static Standard_Integer Discret(
+ const TopoDS_Shape& theShape,
+ const Standard_Real theDeflection,
+ const Standard_Real theAngle,
+ BRepMesh_DiscretRoot* &theAlgo);
+};
+
+#endif
#include <BRepMesh_Edge.hxx>
#include <Bnd_Box.hxx>
#include <BRepBndLib.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
#include <gp_Pnt.hxx> //ied_modif_for_compil_Nov-20-1998
//=======================================================================
Standard_Boolean XSDRAWSTLVRML_ToVRML::Write
- (const TopoDS_Shape& aShape, const Standard_CString filename) const
+ (const TopoDS_Shape& theShape, const Standard_CString theFileName) const
{
- filebuf thefile;
- ostream TheFileOut(&thefile);
-
- if (thefile.open(filename,ios::out))
- {
-
- // Creates facets from the shape
-// Create (defle : Real from Standard;
-// shape : Shape from TopoDS;
-// angl : Real from Standard= 0.17;
-// withShare : Boolean from Standard=Standard_True;
-// inshape : Boolean from Standard=Standard_False;
-// relative : Boolean from Standard=Standard_False;
-// shapetrigu: Boolean from Standard=Standard_False)
-// returns mutable Discret from BRepMesh;
- Bnd_Box B;
- BRepBndLib::Add(aShape, B);
-
- Handle(BRepMesh_FastDiscret) TheDiscret =
- new BRepMesh_FastDiscret(aShape,
- myDeflection,
- 0.17,
- B,
- Standard_True,
- Standard_False,
- Standard_True,
- Standard_True);
-
- Standard_Integer i,j;
-
- // header of the VRML file
- TheFileOut << "#VRML V2.0 utf8" << endl;
- TheFileOut << "Group {" << endl;
- TheFileOut << " children [ " << endl;
- TheFileOut << " NavigationInfo {" << endl;
- TheFileOut << " type \"EXAMINE\" " << endl;
- TheFileOut << " }," << endl;
- TheFileOut << "Shape {" << endl;
-
- TheFileOut << " appearance Appearance {" << endl;
- TheFileOut << " texture ImageTexture {" << endl;
- TheFileOut << " url " << myTexture.ToCString() << endl;
- TheFileOut << " }" << endl;
- TheFileOut << " material Material { " << endl;
- TheFileOut << " diffuseColor " << myDiffuseColorRed << " " << myDiffuseColorGreen << " " << myDiffuseColorBlue << " " << endl;
- TheFileOut << " emissiveColor " << myEmissiveColorRed << " "
- << myEmissiveColorGreen << " " << myEmissiveColorBlue << " " << endl;
- TheFileOut << " transparency " << myTransparency << endl;
- TheFileOut << " ambientIntensity " << myAmbientIntensity << " " << endl;
- TheFileOut << " specularColor " << mySpecularColorRed << " " << mySpecularColorGreen << " " << mySpecularColorBlue << " " << endl;
- TheFileOut << " shininess " <<myShininess << " " << endl;
- TheFileOut << " }" << endl;
- TheFileOut << " }" << endl;
-
- TheFileOut << " geometry IndexedFaceSet {" << endl;
- TheFileOut << " coord Coordinate {" << endl;
- TheFileOut << " point [" << endl;
-
- // puts the coordinates of all the vertices using the order
- // given during the discretisation
- for (i=1;i<=TheDiscret->NbVertices();i++)
+ filebuf aFile;
+ ostream anOut(&aFile);
+
+ if ( aFile.open(theFileName,ios::out) )
{
- gp_Pnt TheVertex=TheDiscret->Pnt(i);
- TheFileOut << " "
- << TheVertex.Coord().X() << " "
- << TheVertex.Coord().Y() << " "
- << TheVertex.Coord().Z() << "," << endl;
+ // Creates facets from the shape
+ // Create (defle : Real from Standard;
+ // shape : Shape from TopoDS;
+ // angl : Real from Standard = 0.17;
+ // withShare : Boolean from Standard = Standard_True;
+ // inshape : Boolean from Standard = Standard_False;
+ // relative : Boolean from Standard = Standard_False;
+ // shapetrigu: Boolean from Standard = Standard_False)
+ // returns mutable Discret from BRepMesh;
+
+ Bnd_Box aBox;
+ BRepBndLib::Add(theShape, aBox);
+
+ Handle(BRepMesh_FastDiscret) aDiscret =
+ new BRepMesh_FastDiscret( theShape,
+ myDeflection,
+ 0.17,
+ aBox,
+ Standard_True,
+ Standard_False,
+ Standard_True,
+ Standard_True );
+
+ // Header of the VRML file
+ anOut << "#VRML V2.0 utf8" << endl;
+ anOut << "Group {" << endl;
+ anOut << " children [ " << endl;
+ anOut << " NavigationInfo {" << endl;
+ anOut << " type \"EXAMINE\" " << endl;
+ anOut << " }," << endl;
+ anOut << " Shape {" << endl;
+
+ anOut << " appearance Appearance {" << endl;
+ anOut << " texture ImageTexture {" << endl;
+ anOut << " url " << myTexture.ToCString() << endl;
+ anOut << " }" << endl;
+ anOut << " material Material {" << endl;
+ anOut << " diffuseColor " << myDiffuseColorRed << " "
+ << myDiffuseColorGreen << " "
+ << myDiffuseColorBlue << " " << endl;
+ anOut << " emissiveColor " << myEmissiveColorRed << " "
+ << myEmissiveColorGreen << " "
+ << myEmissiveColorBlue << " " << endl;
+ anOut << " transparency " << myTransparency << endl;
+ anOut << " ambientIntensity " << myAmbientIntensity << " " << endl;
+ anOut << " specularColor " << mySpecularColorRed << " "
+ << mySpecularColorGreen << " "
+ << mySpecularColorBlue << " " << endl;
+ anOut << " shininess " << myShininess << " " << endl;
+ anOut << " }" << endl;
+ anOut << " }" << endl;
+
+ anOut << " geometry IndexedFaceSet {" << endl;
+ anOut << " coord Coordinate {" << endl;
+ anOut << " point [" << endl;
+
+ // Puts the coordinates of all the vertices using the order
+ // given during the discretisation
+ TopExp_Explorer aFaceIt(theShape, TopAbs_FACE);
+ for (; aFaceIt.More(); aFaceIt.Next())
+ {
+ Handle(BRepMesh_FaceAttribute) anAttribute;
+ const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
+ if (!aDiscret->GetFaceAttribute(aFace, anAttribute) || !anAttribute->IsValid())
+ continue;
+
+ Handle(BRepMesh_DataStructureOfDelaun)& aStructure =
+ anAttribute->ChangeStructure();
+
+ const Standard_Integer aNbVertices = aStructure->NbNodes();
+ for (Standard_Integer i = 1; i <= aNbVertices; ++i)
+ {
+ const BRepMesh_Vertex& aVertex = aStructure->GetNode(i);
+ const gp_Pnt& aPoint = anAttribute->GetPoint(aVertex);
+
+ anOut << " "
+ << aPoint.Coord().X() << " "
+ << aPoint.Coord().Y() << " "
+ << aPoint.Coord().Z() << "," << endl;
+ }
+ }
+
+ anOut << " ]" << endl;
+ anOut << " }" << endl;
+ anOut << " coordIndex [" << endl;
+
+ // Retrieves all the triangles in order to draw the facets
+ for (aFaceIt.Init(theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
+ {
+ Handle(BRepMesh_FaceAttribute) anAttribute;
+ const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
+
+ if (!aDiscret->GetFaceAttribute(aFace, anAttribute) || !anAttribute->IsValid())
+ continue;
+
+ Handle(BRepMesh_DataStructureOfDelaun)& aStructure =
+ anAttribute->ChangeStructure();
+
+ const Standard_Integer aNbTriangles = aStructure->NbElements();
+ for ( Standard_Integer i = 1; i <= aNbTriangles; ++i )
+ {
+ const BRepMesh_Triangle& aTriangle = aStructure->GetElement(i);
+
+ Standard_Integer v[3];
+ aStructure->ElementNodes(aTriangle, v);
+
+ anOut << " "
+ << v[0] - 1 << ", "
+ << v[1] - 1 << ", "
+ << v[2] - 1 << ", -1," << endl;
+ }
+ }
+
+ anOut << " ]" << endl;
+ anOut << " solid FALSE" << endl; // it is not a closed solid
+ anOut << " creaseAngle " << myCreaseAngle << " " << endl; // for smooth shading
+ anOut << " }" << endl;
+ anOut << " }" << endl;
+ anOut << " ]" << endl;
+ anOut << "}" << endl;
}
- TheFileOut << " ]" << endl;
- TheFileOut << " }" << endl;
-
- TheFileOut << " coordIndex [" << endl;
-
- // retrieves all the triangles in order to draw the facets
- for (j=1; j <= TheDiscret->NbTriangles(); j++)
+ else
{
- Standard_Integer v[3];
- TheDiscret->TriangleNodes(j, v);
-
- TheFileOut << " " << v[0]-1 << ", " << v[1]-1 << ", " << v[2]-1 << ", -1, " << endl;
+ // Failure when opening file
+ return Standard_False;
}
-
- TheFileOut << " ]" << endl;
- TheFileOut << " solid FALSE" << endl; // it is not a closed solid
- TheFileOut << " creaseAngle " << myCreaseAngle << " " << endl; // for smooth shading
- TheFileOut << " }" << endl;
- TheFileOut << " }" << endl;
- TheFileOut << " ]" << endl;
- TheFileOut << "} " << endl;
-
- }
- else return Standard_False; // failure when opening file
-
- thefile.close();
+ aFile.close();
return Standard_True;
}
--- /dev/null
+puts "========"
+puts "OCC23106"
+puts "========"
+puts ""
+###########################################
+## BRepMesh_IncrementalMesh returns wrong status
+###########################################
+
+set BugNumber OCC23106
+
+restore [locate_data_file bug23106_face_0triangles.brep] result
+
+incmesh result 0.01
+triangles result
+
+set tri 0
+set nod 0
+
+set tri_info [trinfo result]
+regexp { +([-0-9.+eE]+) +triangles} $tri_info full tri
+regexp { +([-0-9.+eE]+) +nodes} $tri_info full nod
+
+if { ${tri} > 0 && ${nod} > 0 } {
+ puts "${BugNumber} shading: OK"
+} else {
+ puts "${BugNumber} shading: Faulty"
+}
+
+set 3dviewer 1