-// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
#include <Standard_NullObject.hxx>
#include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
+#define MAX2(X, Y) (Abs(X) > Abs(Y) ? Abs(X) : Abs(Y))
+#define MAX3(X, Y, Z) (MAX2(MAX2(X,Y), Z))
+
#define STD_SORT_ALGO 1
+#define DEFAULT_TOLERANCE_TOLERANCE 1.e-02
+#define DEFAULT_MAX_TOLERANCE_TOLERANCE 1.e-06
+
// When the following macro is defined, ShapeFix_ShapeTolerance function is used to set max tolerance of curve
// in GEOMUtils::FixShapeCurves function; otherwise less restrictive BRep_Builder::UpdateEdge/UpdateVertex
// approach is used
return Standard_False;
}
- //=======================================================================
- //function : ShapeToDouble
- //purpose : used by CompareShapes::operator()
- //=======================================================================
- std::pair<double, double> ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting)
- {
- // Computing of CentreOfMass
- gp_Pnt GPoint;
- double Len;
-
- if (S.ShapeType() == TopAbs_VERTEX) {
- GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S));
- Len = (double)S.Orientation();
- }
- else {
- GProp_GProps GPr;
- // BEGIN: fix for Mantis issue 0020842
- if (isOldSorting) {
- BRepGProp::LinearProperties(S, GPr);
- }
- else {
- if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
- BRepGProp::LinearProperties(S, GPr);
- }
- else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
- BRepGProp::SurfaceProperties(S, GPr);
- }
- else {
- BRepGProp::VolumeProperties(S, GPr);
- }
- }
- // END: fix for Mantis issue 0020842
- GPoint = GPr.CentreOfMass();
- Len = GPr.Mass();
- }
-
- double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9;
- return std::make_pair(dMidXYZ, Len);
- }
-
void parseWard( const GEOMUtils::LevelsList &theLevelList, std::string &treeStr )
{
treeStr.append( "{" );
}
+//=======================================================================
+//function : ShapeToDouble
+//purpose : used by CompareShapes::operator()
+//=======================================================================
+std::pair<double, double> GEOMUtils::ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting)
+{
+ // Computing of CentreOfMass
+ gp_Pnt GPoint;
+ double Len;
+
+ if (S.ShapeType() == TopAbs_VERTEX) {
+ GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S));
+ Len = (double)S.Orientation();
+ }
+ else {
+ GProp_GProps GPr;
+ // BEGIN: fix for Mantis issue 0020842
+ if (isOldSorting) {
+ BRepGProp::LinearProperties(S, GPr);
+ }
+ else {
+ if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
+ BRepGProp::LinearProperties(S, GPr);
+ }
+ else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
+ BRepGProp::SurfaceProperties(S, GPr);
+ }
+ else {
+ BRepGProp::VolumeProperties(S, GPr);
+ }
+ }
+ // END: fix for Mantis issue 0020842
+ GPoint = GPr.CentreOfMass();
+ Len = GPr.Mass();
+ }
+
+ double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9;
+ return std::make_pair(dMidXYZ, Len);
+}
+
//=======================================================================
//function : GetPosition
//purpose :
bool GEOMUtils::FixShapeTolerance( TopoDS_Shape& shape,
TopAbs_ShapeEnum type,
- Standard_Real tolerance )
+ Standard_Real tolerance,
+ bool checkGeometry )
{
ShapeFix_ShapeTolerance aSft;
aSft.LimitTolerance( shape, tolerance, tolerance, type );
Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape( shape );
aSfs->Perform();
shape = aSfs->Shape();
- return CheckShape( shape );
+ return CheckShape( shape, checkGeometry );
+}
+
+bool GEOMUtils::FixShapeTolerance( TopoDS_Shape& shape,
+ Standard_Real tolerance,
+ bool checkGeometry )
+{
+ return FixShapeTolerance( shape, TopAbs_SHAPE, tolerance, checkGeometry );
}
bool GEOMUtils::FixShapeTolerance( TopoDS_Shape& shape,
- Standard_Real tolerance )
+ bool checkGeometry )
{
- return FixShapeTolerance( shape, TopAbs_SHAPE, tolerance );
+ return FixShapeTolerance( shape, Precision::Confusion(), checkGeometry );
}
bool GEOMUtils::FixShapeCurves( TopoDS_Shape& shape )
{
return BRepTools::Write( shape, fileName );
}
+
+TopoDS_Shape GEOMUtils::ReduceCompound( const TopoDS_Shape& shape )
+{
+ TopoDS_Shape result = shape;
+
+ if ( shape.ShapeType() == TopAbs_COMPOUND ||
+ shape.ShapeType() == TopAbs_COMPSOLID ) {
+
+ TopTools_ListOfShape l;
+
+ TopoDS_Iterator it ( shape );
+ for ( ; it.More(); it.Next() )
+ l.Append( it.Value() );
+ if ( l.Extent() == 1 && l.First() != shape )
+ result = ReduceCompound( l.First() );
+ }
+
+ return result;
+}
+
+void GEOMUtils::MeshShape( const TopoDS_Shape shape,
+ double deflection, bool theForced )
+{
+ Standard_Real aDeflection = ( deflection <= 0 ) ? DefaultDeflection() : deflection;
+
+ // Is shape triangulated?
+ Standard_Boolean alreadyMeshed = true;
+ TopExp_Explorer ex;
+ TopLoc_Location aLoc;
+ for ( ex.Init( shape, TopAbs_FACE ); ex.More() && alreadyMeshed; ex.Next() ) {
+ const TopoDS_Face& aFace = TopoDS::Face( ex.Current() );
+ Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation( aFace, aLoc );
+ alreadyMeshed = !aPoly.IsNull();
+ }
+
+ if ( !alreadyMeshed || theForced ) {
+ // Compute bounding box
+ Bnd_Box B;
+ BRepBndLib::Add( shape, B );
+ if ( B.IsVoid() )
+ return; // NPAL15983 (Bug when displaying empty groups)
+ Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
+ B.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
+
+ // This magic line comes from Prs3d_ShadedShape.gxx in OCCT
+ aDeflection = MAX3(aXmax-aXmin, aYmax-aYmin, aZmax-aZmin) * aDeflection * 4;
+
+ // Clean triangulation before compute incremental mesh
+ BRepTools::Clean( shape );
+
+ // Compute triangulation
+ BRepMesh_IncrementalMesh mesh( shape, aDeflection );
+ }
+}
+
+double GEOMUtils::DefaultDeflection()
+{
+ return 0.001;
+}
+
+//=======================================================================
+//function : IsOpenPath
+//purpose :
+//=======================================================================
+bool GEOMUtils::IsOpenPath(const TopoDS_Shape &theShape)
+{
+ bool isOpen = true;
+
+ if (theShape.IsNull() == Standard_False) {
+ if (theShape.Closed()) {
+ // The shape is closed
+ isOpen = false;
+ } else {
+ const TopAbs_ShapeEnum aType = theShape.ShapeType();
+
+ if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) {
+ // Check if path ends are coinsident.
+ TopoDS_Vertex aV[2];
+
+ if (aType == TopAbs_EDGE) {
+ // Edge
+ TopExp::Vertices(TopoDS::Edge(theShape), aV[0], aV[1]);
+ } else {
+ // Wire
+ TopExp::Vertices(TopoDS::Wire(theShape), aV[0], aV[1]);
+ }
+
+ if (aV[0].IsNull() == Standard_False &&
+ aV[1].IsNull() == Standard_False) {
+ if (aV[0].IsSame(aV[1])) {
+ // The shape is closed
+ isOpen = false;
+ } else {
+ const Standard_Real aTol1 = BRep_Tool::Tolerance(aV[0]);
+ const Standard_Real aTol2 = BRep_Tool::Tolerance(aV[1]);
+ const gp_Pnt aPnt1 = BRep_Tool::Pnt(aV[0]);
+ const gp_Pnt aPnt2 = BRep_Tool::Pnt(aV[1]);
+
+ if (aPnt1.Distance(aPnt2) <= aTol1 + aTol2) {
+ // The shape is closed
+ isOpen = false;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return isOpen;
+}
+
+//=======================================================================
+//function : CompareToleranceValues
+//purpose :
+//=======================================================================
+int GEOMUtils::CompareToleranceValues(const double theTolShape,
+ const double theTolRef)
+{
+ const double aTolTol = Min(DEFAULT_MAX_TOLERANCE_TOLERANCE,
+ theTolRef*DEFAULT_TOLERANCE_TOLERANCE);
+
+ int aResult = 0;
+
+ if (theTolShape < theTolRef - aTolTol) {
+ aResult = -1;
+ } else if (theTolShape > theTolRef + aTolTol) {
+ aResult = 1;
+ }
+
+ return aResult;
+}
+
+//=======================================================================
+//function : IsFitCondition
+//purpose :
+//=======================================================================
+bool GEOMUtils::IsFitCondition(const ComparisonCondition theCondition,
+ const double theTolShape,
+ const double theTolRef)
+{
+ const int aCompValue = CompareToleranceValues(theTolShape, theTolRef);
+ bool isFit = false;
+
+ switch (theCondition) {
+ case CC_GT:
+ isFit = aCompValue == 1;
+ break;
+ case GEOMUtils::CC_GE:
+ isFit = aCompValue != -1;
+ break;
+ case GEOMUtils::CC_LT:
+ isFit = aCompValue == -1;
+ break;
+ case GEOMUtils::CC_LE:
+ isFit = aCompValue != 1;
+ break;
+ default:
+ break;
+ }
+
+ return isFit;
+}