Hello.
OCCT is openSource you be able to find our a source code. But it look like that the code can be moved to own C++ class. We will look on it.
Path: occt\src\BOPTest\BOPTest_TolerCommands.cxx
//=======================================================================
//function : ProcessEdge
//purpose :
//=======================================================================
void ProcessEdge(const TopoDS_Edge& aE, const Standard_Real aTolTreshold)
{
Standard_Integer i, aNb=23;
Standard_Real aD2, aTolMax2, aT1, aT2, aT, dT;
gp_Pnt aPC3D, aP3D;
gp_Pnt2d aPC2D;
//TopTools_ListIteratorOfListOfShape anIt;// Wng in Gcc 3.0
BRep_ListIteratorOfListOfCurveRepresentation itcr;
//
Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aE, aT1, aT2);
if (aC3D.IsNull()) {
return;
}
//
dT=(aT2-aT1)/aNb;
//
Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
const TopLoc_Location& Eloc = aE.Location();
//
aTolMax2=-1.e6;
const BRep_ListOfCurveRepresentation& aLCR=TE->Curves();
//
itcr.Initialize(aLCR);
for (; itcr.More(); itcr.Next()) {
const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
const TopLoc_Location& loc = cr->Location();
TopLoc_Location L = (Eloc * loc);//.Predivided(aV.Location());
//
// 3D-Curve
if (cr->IsCurve3D()) {
continue;
}
//
// 2D-Curve
else if (cr->IsCurveOnSurface()) {
const Handle(Geom2d_Curve)& aC2D = cr->PCurve();
if (aC2D.IsNull()) {
continue;
}
// Surface
const Handle(Geom_Surface)& aS=cr->Surface();
//
// 2D-point treatment
for (i=0; i<=aNb; ++i) {
aT=aT1+i*dT;
if (i==aNb) {
aT=aT2;
}
aPC3D=aC3D->Value(aT);
aPC2D=aC2D->Value(aT);
aS->D0(aPC2D.X(), aPC2D.Y(), aP3D);
aP3D.Transform(L.Transformation());
aD2=aPC3D.SquareDistance(aP3D);
if (aD2 > aTolMax2) {
aTolMax2=aD2;
}
}
} //if (cr->IsCurveOnSurface())
}//for (; itcr.More(); itcr.Next())
//#########################################################
//
if (aTolMax2<0.){
return;
}
//
//
aTolMax2=sqrt(aTolMax2);
//printf(" aTolMax=%15.10lf, aTolWas=%15.10lf\n", aTolMax2, aTolE);
Standard_Real aTolSet;
aTolSet=(aTolMax2>aTolTreshold) ? aTolMax2 : aTolTreshold;
TE->Tolerance(aTolSet);
}
//=======================================================================
//function : ProcessVertex
//purpose :
//=======================================================================
void ProcessVertex(const TopoDS_Vertex& aV,
const TopTools_ListOfShape& aLE,
const TopTools_ListOfShape& aLF)
{
Standard_Real aTol, aD2, aTolMax2, aTolE, aParam;
gp_Pnt aPC3D;
gp_Pnt2d aPC2D;
TopAbs_Orientation anOrV;
TopTools_ListIteratorOfListOfShape anIt;
TopExp_Explorer aVExp;
BRep_ListIteratorOfListOfCurveRepresentation itcr;
//
aTolMax2=-1.e6;
//
Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aV.TShape());
const gp_Pnt& aPV3D = TV->Pnt();
aTol =BRep_Tool::Tolerance(aV);
//
anIt.Initialize(aLE);
for (; anIt.More(); anIt.Next()) {
const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value());
//
Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
const TopLoc_Location& Eloc = aE.Location();
//
aVExp.Init(aE, TopAbs_VERTEX);
for (; aVExp.More(); aVExp.Next()) {
const TopoDS_Vertex& aVx=TopoDS::Vertex(aVExp.Current());
//
if (!aVx.IsSame(aV)) {
continue;
}
//
anOrV=aVx.Orientation();
if (!(anOrV==TopAbs_FORWARD || anOrV==TopAbs_REVERSED)) {
continue;
}
//
const BRep_ListOfCurveRepresentation& aLCR=TE->Curves();
itcr.Initialize(aLCR);
for (; itcr.More(); itcr.Next()) {
const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
const TopLoc_Location& loc = cr->Location();
TopLoc_Location L = (Eloc * loc).Predivided(aV.Location());
//
// 3D-Curve
if (cr->IsCurve3D()) {
const Handle(Geom_Curve)& aC3D = cr->Curve3D();
//
if (aC3D.IsNull()) {
continue;
}
// 3D-point treatment
aParam=BRep_Tool::Parameter(aVx, aE);
aPC3D= aC3D->Value(aParam);
aPC3D.Transform(L.Transformation());
aD2=aPV3D.SquareDistance(aPC3D);
if (aD2 > aTolMax2) {
aTolMax2=aD2;
}
//
}//if (cr->IsCurve3D())
//
// 2D-Curve
else if (cr->IsCurveOnSurface()) {
const Handle(Geom2d_Curve)& aC2D = cr->PCurve();
if (aC2D.IsNull()) {
continue;
}
// Surface
const Handle(Geom_Surface)& aS=cr->Surface();
//
// 2D-point treatment
aParam=BRep_Tool::Parameter(aVx, aE, aS, L);
aPC2D=aC2D->Value(aParam);
aS->D0(aPC2D.X(), aPC2D.Y(), aPC3D);
aPC3D.Transform(L.Transformation());
aD2=aPV3D.SquareDistance(aPC3D);
if (aD2 > aTolMax2) {
aTolMax2=aD2;
}
} //if (cr->IsCurveOnSurface())
}//for (; itcr.More(); itcr.Next())
}//for (; aVExp.More(); aVExp.Next())
}//for (; anIt.More(); anIt.Next())
//#########################################################
//
// Reducing
if (aTolMax2<0.){
return;
}
//
aTolMax2=sqrt(aTolMax2);
if (aTolMax2>aTol) {
return;
}
//
anIt.Initialize(aLE);
for (; anIt.More(); anIt.Next()) {
const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value());
aTolE =BRep_Tool::Tolerance(aE);
if (aTolMax2 < aTolE) {
aTolMax2=aTolE;
}
}
//
anIt.Initialize(aLF);
for (; anIt.More(); anIt.Next()) {
const TopoDS_Face& aF=TopoDS::Face(anIt.Value());
aTolE =BRep_Tool::Tolerance(aF);
if (aTolMax2 < aTolE) {
aTolMax2=aTolE;
}
}
//
if (aTolMax2>aTol) {
return;
}
//
// Update Tolerance
TV->Tolerance(aTolMax2);
}
//=======================================================================
//function : ReduceEdgeTolerance
//purpose :
//=======================================================================
void ReduceEdgeTolerance (const TopoDS_Shape& aS,
const Standard_Real aTolTreshold)
{
Standard_Integer i, aNbE;
TopTools_IndexedMapOfShape aEMap;
//
TopExp::MapShapes(aS, TopAbs_EDGE, aEMap);
//
aNbE=aEMap.Extent();
for (i=1; i<=aNbE; i++) {
const TopoDS_Edge& aE= TopoDS::Edge(aEMap(i));
ProcessEdge(aE, aTolTreshold);
}
}
//=======================================================================
//function : ReduceFaceTolerance
//purpose :
//=======================================================================
void ReduceFaceTolerance (const TopoDS_Shape& aS)
{
Standard_Integer i, j, aNbF, aNbE;
Standard_Real aTolE, aTolx, aTolEMin;
TopTools_IndexedMapOfShape aFMap, aEMap;
//
aTolEMin=1.e-7;
//
TopExp::MapShapes(aS, TopAbs_FACE, aFMap);
aNbF=aFMap.Extent();
for (i=1; i<=aNbF; i++) {
aTolx=1.e6;
const TopoDS_Face& aF= TopoDS::Face(aFMap(i));
Handle(BRep_TFace)& aTF = *((Handle(BRep_TFace)*)&aF.TShape());
//
TopExp::MapShapes(aF, TopAbs_EDGE, aEMap);
aNbE=aEMap.Extent();
for (j=1; j<=aNbE; ++j) {
const TopoDS_Edge& aE= TopoDS::Edge(aEMap(j));
aTolE =BRep_Tool::Tolerance(aE);
if (aTolE<aTolx) {
aTolx=aTolE;
}
}
aTolE=(aTolx>aTolEMin) ? aTolx : aTolEMin;
aTF->Tolerance(aTolE);
}
}
//=======================================================================
//function : ReduceVertexTolerance
//purpose :
//=======================================================================
void ReduceVertexTolerance (const TopoDS_Shape& aS)
{
Standard_Integer i, aNbV;
TopTools_IndexedDataMapOfShapeListOfShape aVEMap, aVFMap;
TopExp::MapShapesAndUniqueAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
TopExp::MapShapesAndUniqueAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aVFMap);
aNbV=aVEMap.Extent();
for (i=1; i<=aNbV; i++) {
const TopoDS_Vertex& aV= TopoDS::Vertex(aVEMap.FindKey(i));
const TopTools_ListOfShape& aLE=aVEMap(i);
const TopTools_ListOfShape& aLF=aVFMap.FindFromKey(aV);
ProcessVertex(aV, aLE, aLF);
}
}
//=======================================================================
//function : btolx
//purpose :
//=======================================================================
Standard_Integer btolx(Draw_Interpretor& di,
Standard_Integer n,
const char** a)
{
if (n<2) {
di << " use btolx Shape [minTol=1.e-7]\n";
return 1;
}
TopoDS_Shape aS = DBRep::Get(a[1]);
if (aS.IsNull()) {
di << " Null shape is not allowed\n";
return 1;
}
//
Standard_Real aTolEMin=1.e-7;
if (n==3) {
aTolEMin=Draw::Atof(a[2]);
}
//
// Edge Tolerances
ReduceEdgeTolerance(aS, aTolEMin);
//
// Face Tolerances
ReduceFaceTolerance(aS);
//
// Vertex Tolerances
ReduceVertexTolerance(aS);
//
BRepLib::SameParameter(aS, 1.e-7, Standard_True);
//
DBRep::Set (a[1], aS);
return 0;
}
Best regards, Commenter-2.