-
-//=======================================================================
-//function : CheckSingularCase
-//purpose : auxilary for GetMinDistance()
-// workaround for bugs 19899, 19908 and 19910 from Mantis
-//=======================================================================
-static double CheckSingularCase(const TopoDS_Shape& aSh1,
- const TopoDS_Shape& aSh2,
- gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
-{
- bool IsChange1 = false;
- double AddDist1 = 0.0;
- TopExp_Explorer anExp;
- TopoDS_Shape tmpSh1, tmpSh2;
- int nbf = 0;
- for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
- nbf++;
- tmpSh1 = anExp.Current();
- }
- if(nbf==1) {
- TopoDS_Shape sh = aSh1;
- while(sh.ShapeType()==TopAbs_COMPOUND) {
- TopoDS_Iterator it(sh);
- sh = it.Value();
- }
- Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
- if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
- S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
- if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
- // non solid case
- double U1,U2,V1,V2;
- // changes for 0020677: EDF 1219 GEOM: MinDistance gives 0 instead of 20.88
- //S->Bounds(U1,U2,V1,V2); changed by
- ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh1),U1,U2,V1,V2);
- // end of changes for 020677 (dmv)
- Handle(Geom_RectangularTrimmedSurface) TrS1 =
- new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
- Handle(Geom_RectangularTrimmedSurface) TrS2 =
- new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
- BRep_Builder B;
- TopoDS_Face F1,F2;
- TopoDS_Compound Comp;
- B.MakeCompound(Comp);
- B.MakeFace(F1,TrS1,1.e-7);
- B.Add(Comp,F1);
- B.MakeFace(F2,TrS2,1.e-7);
- B.Add(Comp,F2);
- Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
- sfs->Init(Comp);
- sfs->SetPrecision(1.e-6);
- sfs->SetMaxTolerance(1.0);
- sfs->Perform();
- tmpSh1 = sfs->Shape();
- IsChange1 = true;
- }
- else {
- if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
- Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
- gp_Pnt PC = SS->Location();
- BRep_Builder B;
- TopoDS_Vertex V;
- B.MakeVertex(V,PC,1.e-7);
- tmpSh1 = V;
- AddDist1 = SS->Radius();
- IsChange1 = true;
- }
- else {
- Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
- gp_Ax3 ax3 = TS->Position();
- Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
- BRep_Builder B;
- TopoDS_Edge E;
- B.MakeEdge(E,C,1.e-7);
- tmpSh1 = E;
- AddDist1 = TS->MinorRadius();
- IsChange1 = true;
- }
- }
- }
- else
- tmpSh1 = aSh1;
- }
- else
- tmpSh1 = aSh1;
- bool IsChange2 = false;
- double AddDist2 = 0.0;
- nbf = 0;
- for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
- nbf++;
- tmpSh2 = anExp.Current();
- }
- if(nbf==1) {
- TopoDS_Shape sh = aSh2;
- while(sh.ShapeType()==TopAbs_COMPOUND) {
- TopoDS_Iterator it(sh);
- sh = it.Value();
- }
- Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
- if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
- S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
- if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
- // non solid case
- double U1,U2,V1,V2;
- //S->Bounds(U1,U2,V1,V2);
- ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh2),U1,U2,V1,V2);
- Handle(Geom_RectangularTrimmedSurface) TrS1 =
- new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
- Handle(Geom_RectangularTrimmedSurface) TrS2 =
- new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
- BRep_Builder B;
- TopoDS_Face F1,F2;
- TopoDS_Compound Comp;
- B.MakeCompound(Comp);
- B.MakeFace(F1,TrS1,1.e-7);
- B.Add(Comp,F1);
- B.MakeFace(F2,TrS2,1.e-7);
- B.Add(Comp,F2);
- Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
- sfs->Init(Comp);
- sfs->SetPrecision(1.e-6);
- sfs->SetMaxTolerance(1.0);
- sfs->Perform();
- tmpSh2 = sfs->Shape();
- IsChange2 = true;
- }
- else {
- if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
- Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
- gp_Pnt PC = SS->Location();
- BRep_Builder B;
- TopoDS_Vertex V;
- B.MakeVertex(V,PC,1.e-7);
- tmpSh2 = V;
- AddDist2 = SS->Radius();
- IsChange2 = true;
- }
- else if( S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
- Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
- gp_Ax3 ax3 = TS->Position();
- Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
- BRep_Builder B;
- TopoDS_Edge E;
- B.MakeEdge(E,C,1.e-7);
- tmpSh2 = E;
- AddDist2 = TS->MinorRadius();
- IsChange2 = true;
- }
- }
- }
- else
- tmpSh2 = aSh2;
- }
- else
- tmpSh2 = aSh2;
-
- if( !IsChange1 && !IsChange2 )
- return -2.0;
-
- BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2);
- if (dst.IsDone()) {
- double MinDist = 1.e9;
- gp_Pnt PMin1, PMin2, P1, P2;
- for (int i = 1; i <= dst.NbSolution(); i++) {
- P1 = dst.PointOnShape1(i);
- P2 = dst.PointOnShape2(i);
- Standard_Real Dist = P1.Distance(P2);
- if (MinDist > Dist) {
- MinDist = Dist;
- PMin1 = P1;
- PMin2 = P2;
- }
- }
- if(MinDist<1.e-7) {
- Ptmp1 = PMin1;
- Ptmp2 = PMin2;
- }
- else {
- gp_Dir aDir(gp_Vec(PMin1,PMin2));
- if( MinDist > (AddDist1+AddDist2) ) {
- Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
- PMin1.Y() + aDir.Y()*AddDist1,
- PMin1.Z() + aDir.Z()*AddDist1 );
- Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
- PMin2.Y() - aDir.Y()*AddDist2,
- PMin2.Z() - aDir.Z()*AddDist2 );
- return (MinDist - AddDist1 - AddDist2);
- }
- else {
- if( AddDist1 > 0 ) {
- Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
- PMin1.Y() + aDir.Y()*AddDist1,
- PMin1.Z() + aDir.Z()*AddDist1 );
- Ptmp2 = Ptmp1;
- }
- else {
- Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
- PMin2.Y() - aDir.Y()*AddDist2,
- PMin2.Z() - aDir.Z()*AddDist2 );
- Ptmp1 = Ptmp2;
- }
- }
- }
- double res = MinDist - AddDist1 - AddDist2;
- if(res<0.) res = 0.0;
- return res;
- }
- return -2.0;
-}
-/* old variant
-static bool CheckSingularCase(const TopoDS_Shape& aSh1,
- const TopoDS_Shape& aSh2,
- gp_Pnt& Ptmp)
-{
- TopExp_Explorer anExp;
- TopoDS_Shape tmpSh1, tmpSh2;
- int nbf = 0;
- for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
- nbf++;
- tmpSh1 = anExp.Current();
- }
- if(nbf==1) {
- Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
- if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
- S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
- nbf = 0;
- for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
- nbf++;
- tmpSh2 = anExp.Current();
- Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
- GeomAPI_IntSS ISS(S1,S2,1.e-7);
- if(ISS.IsDone()) {
- for(int i=1; i<=ISS.NbLines(); i++) {
- Handle(Geom_Curve) C3d = ISS.Line(i);
- BRep_Builder B;
- TopoDS_Edge E;
- B.MakeEdge(E,C3d,1.e-7);
- BRepExtrema_DistShapeShape dst(tmpSh2,E);
- if (dst.IsDone()) {
- gp_Pnt PMin1, PMin2, P1, P2;
- double MinDist = 1.e9;
- for (int i = 1; i <= dst.NbSolution(); i++) {
- P1 = dst.PointOnShape1(i);
- P2 = dst.PointOnShape2(i);
- Standard_Real Dist = P1.Distance(P2);
- if (MinDist > Dist) {
- MinDist = Dist;
- Ptmp = P1;
- }
- }
- if(MinDist<1.e-7)
- return true;
- }
- }
- }
- }
- }
- }
- nbf = 0;
- for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
- nbf++;
- tmpSh1 = anExp.Current();
- }
- if(nbf==1) {
- Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
- if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
- S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
- nbf = 0;
- for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
- nbf++;
- tmpSh2 = anExp.Current();
- Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
- GeomAPI_IntSS ISS(S1,S2,1.e-7);
- if(ISS.IsDone()) {
- for(int i=1; i<=ISS.NbLines(); i++) {
- Handle(Geom_Curve) C3d = ISS.Line(i);
- BRep_Builder B;
- TopoDS_Edge E;
- B.MakeEdge(E,C3d,1.e-7);
- BRepExtrema_DistShapeShape dst(tmpSh2,E);
- if (dst.IsDone()) {
- gp_Pnt P1,P2;
- double MinDist = 1.e9;
- for (int i = 1; i <= dst.NbSolution(); i++) {
- P1 = dst.PointOnShape1(i);
- P2 = dst.PointOnShape2(i);
- Standard_Real Dist = P1.Distance(P2);
- if (MinDist > Dist) {
- MinDist = Dist;
- Ptmp = P1;
- }
- }
- if(MinDist<1.e-7)
- return true;
- }
- }
- }
- }
- }
- }
- return false;
-}
-*/
-
-