//:r5 abv 06.04.99: ec_turbine-A.stp, #4313: protect against null curve // abv 09.04.99 S4136: add parameter preci (to eliminate BRepAPI::Precision) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //======================================================================= //function : ShapeFix_EdgeProjAux //purpose : //======================================================================= ShapeFix_EdgeProjAux::ShapeFix_EdgeProjAux () { myFirstDone = myLastDone = Standard_False; } //======================================================================= //function : ShapeFix_EdgeProjAux //purpose : //======================================================================= ShapeFix_EdgeProjAux::ShapeFix_EdgeProjAux (const TopoDS_Face& F, const TopoDS_Edge& E) { Init (F, E); } //======================================================================= //function : Init //purpose : //======================================================================= void ShapeFix_EdgeProjAux::Init (const TopoDS_Face& F, const TopoDS_Edge& E) { myFace = F; myEdge = E; myFirstDone = myLastDone = Standard_False; } //======================================================================= //function : Compute //purpose : //======================================================================= void ShapeFix_EdgeProjAux::Compute (const Standard_Real preci) { myFirstDone = myLastDone = Standard_False; // Project Point3d on Surface // TEMPORARY Call ShapeFix_EdgeProjAux Init2d(preci); if (IsFirstDone() && IsLastDone()) { Standard_Real U1 = FirstParam(); Standard_Real U2 = LastParam(); if (U1>=U2) { #ifdef DEBUG cout << "Parametres inverses ... " << endl; #endif Standard_Real tmp = U1; U1 = U2; U2 = tmp; } myFirstParam = U1; myFirstDone = Standard_True; myLastParam = U2; myLastDone = Standard_True; } } //======================================================================= //function : IsFirstDone //purpose : //======================================================================= Standard_Boolean ShapeFix_EdgeProjAux::IsFirstDone() const { return myFirstDone; } //======================================================================= //function : IsLastDone //purpose : //======================================================================= Standard_Boolean ShapeFix_EdgeProjAux::IsLastDone() const { return myLastDone; } //======================================================================= //function : FirstParam //purpose : //======================================================================= Standard_Real ShapeFix_EdgeProjAux::FirstParam() const { return myFirstParam; } //======================================================================= //function : LastParam //purpose : //======================================================================= Standard_Real ShapeFix_EdgeProjAux::LastParam() const { return myLastParam; } //======================================================================= //function : IsIso //purpose : //======================================================================= Standard_Boolean ShapeFix_EdgeProjAux::IsIso (const Handle(Geom2d_Curve)& /*theCurve2d*/) { // Until an ISO is recognized by Adaptor3d_Curve /* if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) { Handle(Geom2d_Line) theLine2d = Handle(Geom2d_Line)::DownCast(theCurve2d); gp_Dir2d theDir2d = theLine2d->Direction(); gp_Dir2d dir1(0.,1.); gp_Dir2d dir2(0.,-1.); return (theDir2d.IsEqual(dir1,Precision::Angular()) || theDir2d.IsEqual(dir2,Precision::Angular()) || theDir2d.IsNormal(dir1,Precision::Angular()) || theDir2d.IsNormal(dir2,Precision::Angular()) ); } */ return Standard_False; } // ---------------------------------------------------------------------------- // static : FindParameterWithExt // Purpose : Computes the trimming parameter of Pt1 on COnS // ---------------------------------------------------------------------------- static Standard_Boolean FindParameterWithExt (const gp_Pnt& Pt1, const Adaptor3d_CurveOnSurface& COnS, const Standard_Real Uinf, const Standard_Real Usup, const Standard_Real preci, Standard_Real& w1) { try { // et allez donc ! OCC_CATCH_SIGNALS Extrema_ExtPC myExtPC (Pt1, COnS, Uinf, Usup, preci); //ShapeFix_ExtPCOnS myExtPCOnS1 = //ShapeFix_ExtPCOnS(Pt1, COnS, Uinf, Usup, preci); if (myExtPC.IsDone()) { Standard_Integer NbExt1 = myExtPC.NbExt(); for (Standard_Integer i=1; i<=NbExt1; i++) { if (myExtPC.IsMin(i)) { //Standard_Real dist = myExtPC.Value(i); //szv#4:S4163:12Mar99 debug mode only w1 = myExtPC.Point(i).Parameter(); } } return Standard_True; } else return Standard_False; } // end try catch(Standard_Failure) { #ifdef DEB //:s5 cout << "Warning: ShapeFix_EdgeProjAux, FindParameterWithExt(): Exception: "; Standard_Failure::Caught()->Print(cout); cout << endl; #endif return Standard_False; } #ifndef _MSC_VER return Standard_False; // normalement, on n y passe jamais #endif } //======================================================================= //function : Init2d //purpose : //======================================================================= void ShapeFix_EdgeProjAux::Init2d (const Standard_Real preci) { Standard_Real cl, cf; // Extract Geometries Handle(Geom_Surface) theSurface = BRep_Tool::Surface(myFace); Handle(Geom2d_Curve) theCurve2d = BRep_Tool::CurveOnSurface(myEdge, myFace, cf, cl); if ( theCurve2d.IsNull() ) return; //:r5 abv 6 Apr 99: ec_turbine-A.stp, #4313 TopoDS_Vertex V1,V2; TopExp::Vertices(myEdge, V1, V2); gp_Pnt Pt1,Pt2; // pdn 28.12.98: r_39-db.stp #605: use ends of 3d curve instead of vertices ShapeAnalysis_Edge sae; Standard_Real a,b; Handle(Geom_Curve) C3d; if(sae.Curve3d(myEdge,C3d,a,b,Standard_False)) { Pt1 = C3d->Value(a); Pt2 = C3d->Value(b); } else { Pt1 = BRep_Tool::Pnt(V1); Pt2 = BRep_Tool::Pnt(V2); } //:S4136 Standard_Real preci = BRepAPI::Precision(); //pdn to manage degenerated case if (V1.IsSame(V2)) { Handle(ShapeAnalysis_Surface) stsu = new ShapeAnalysis_Surface (theSurface); gp_Pnt2d aPt1,aPt2; Standard_Real firstpar,lastpar; if (stsu->DegeneratedValues(Pt1,preci,aPt1,aPt2,firstpar,lastpar)){ if(theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) { if (aPt1.IsEqual(theCurve2d->Value(firstpar),preci) && aPt2.IsEqual(theCurve2d->Value(lastpar),preci)){ myFirstParam = firstpar; myLastParam = lastpar; myFirstDone = myLastDone = Standard_True; return; } } #ifdef DEBUG else cout <<"Other type of deg curve"<FirstParameter(); cl = theCurve2d->LastParameter(); //pdn cutting pcurve by suface bounds if (Precision::IsInfinite(cf)||Precision::IsInfinite(cf)) { if(theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) { Standard_Real uf,ul,vf,vl; theSurface->Bounds(uf,ul,vf,vl); if(!Precision::IsInfinite(uf)&&!Precision::IsInfinite(ul)&& !Precision::IsInfinite(vf)&&!Precision::IsInfinite(vl)) { Standard_Real cfi,cli; Handle(Geom2d_Line) lin = Handle(Geom2d_Line)::DownCast(theCurve2d); gp_Pnt2d pnt = lin->Location(); gp_Dir2d dir = lin->Direction(); if (dir.Y()==0) { parU = Standard_True; cfi = (uf-pnt.X())/dir.X(); cli = (ul-pnt.X())/dir.X(); } else if (dir.X()==0) { parV = Standard_True; cfi = (vf-pnt.Y())/dir.Y(); cli = (vl-pnt.Y())/dir.Y(); } else {//common case Standard_Real xfi, xli, yfi, yli; xfi = (uf-pnt.X())/dir.X(); xli = (ul-pnt.X())/dir.X(); yfi = (vf-pnt.Y())/dir.Y(); yli = (vl-pnt.Y())/dir.Y(); if (dir.X()*dir.Y() > 0) { cfi = (Abs(xli-xfi) < Abs(xli-yfi)? xfi : yfi); cli = (Abs(xfi-xli) < Abs(xfi-yli)? xli : yli); } else { cfi = (Abs(xli-xfi) < Abs(xli-yli)? xfi : yli); cli = (Abs(yli-xli) < Abs(yli-yfi)? xli : yfi); } } if (cfi < cli) { cf = cfi; cl = cli; } else { cf = cli; cl = cfi; } } else if(!Precision::IsInfinite(uf)&&!Precision::IsInfinite(ul)){ Handle(Geom2d_Line) lin = Handle(Geom2d_Line)::DownCast(theCurve2d); gp_Dir2d dir = lin->Direction(); if (dir.X()!=0) { if (dir.Y()==0) parU = Standard_True; gp_Pnt2d pnt = lin->Location(); //szv#4:S4163:12Mar99 moved Standard_Real cfi = (uf-pnt.X())/dir.X(); Standard_Real cli = (ul-pnt.X())/dir.X(); if (cfi < cli) { cf = cfi; cl = cli; } else { cf = cli; cl = cfi; } } else { cf=-10000; cl= 10000; } } else { cf=-10000; cl= 10000; //pdn not cutted by bounds #ifdef DEBUG cout<<"Infinite Surface"< preci) return; dist = sac.Project(COnS,Pt2,preci,pnt,w2,Standard_False); if (dist > preci) return; myFirstParam = w1; myLastParam = w2; myFirstDone = myLastDone = Standard_True; if ( myFirstParam == Uinf && myLastParam == Usup ) return; if ( myFirstParam == Usup && myLastParam == Uinf ) { myFirstParam = theCurve2d->ReversedParameter(Usup); myLastParam = theCurve2d->ReversedParameter(Uinf); theCurve2d->Reverse(); #ifdef DEB cout << "Warning: ShapeFix_EdgeProjAux: pcurve reversed" << endl; #endif return; } //:abv 29.08.01: SAT: fix for closed case if ( COnS.Value(Uinf).Distance ( COnS.Value(Usup) ) < Precision::Confusion() ) { // 18.11.2002 SKL OCC630 compare values with tolerance Precision::PConfusion() instead of "==" if ( Abs(myFirstParam-Uinf) < ::Precision::PConfusion() && Abs(myLastParam-Uinf) < ::Precision::PConfusion() ) myLastParam = w2 = Usup; // 18.11.2002 SKL OCC630 compare values with tolerance Precision::PConfusion() instead of "==" else if ( Abs(myFirstParam-Usup) < ::Precision::PConfusion() && Abs(myLastParam-Usup) < ::Precision::PConfusion() ) myFirstParam = w1 = Uinf; } //pdn adjust parameters in periodic case if(parU || parV) { Standard_Real uf,ul,vf,vl; theSurface->Bounds(uf,ul,vf,vl); Standard_Real period = (parU ? ul-uf : vl-vf); w1+=ShapeAnalysis::AdjustToPeriod(w1,0,period); myFirstParam = w1; w2+=ShapeAnalysis::AdjustToPeriod(w2,0,period); myLastParam = w2; Handle(Geom_Curve) C3d1; if(!sae.Curve3d (myEdge, C3d1, cf, cl, Standard_False )) { UpdateParam2d(theCurve2d); return; } gp_Pnt mid = C3d1->Value((cf+cl)/2); Standard_Real wmid; sac.Project(COnS,mid,preci,pnt,wmid,Standard_False); wmid+=ShapeAnalysis::AdjustToPeriod(wmid,0,period); if(w1>w2) { if(w2 > wmid) myFirstParam -= period; else if (w1 > wmid) UpdateParam2d(theCurve2d); else { myLastParam+=period; #ifdef DEBUG cout <<" Added"< wmid) { myLastParam -=period; UpdateParam2d(theCurve2d); #ifdef DEBUG cout <<" Added & Inverted"<FirstParameter(); Standard_Real Usup = theCurve2d->LastParameter(); // ---------------------------------------------- // --- topological limit == geometric limit ? --- // ---------------------------------------------- if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) { gp_Pnt Pdeb = COnS.Value(Uinf); gp_Pnt Pfin = COnS.Value(Usup); //szv#4:S4163:12Mar99 optimized if ( Pdeb.IsEqual(Pt1, preci) && Pfin.IsEqual(Pt2, preci) ) { myFirstParam = Uinf; myLastParam = Usup; myFirstDone = myLastDone = Standard_True; return; } } // ------------------------------------------ // --- The CurveOnSurface is not infinite --- // --- Try with Extrema --- // ------------------------------------------ Standard_Real w1 = COnS.FirstParameter(); Standard_Real w2 = COnS.LastParameter(); if ((!Precision::IsInfinite(w1) && !Precision::IsInfinite(w2) && theCurve2d->Continuity() != GeomAbs_C0) || IsIso(theCurve2d)) { //szv#4:S4163:12Mar99 optimized if ( FindParameterWithExt(Pt1, COnS, Uinf, Usup, preci, w1) && FindParameterWithExt(Pt2, COnS, Uinf, Usup, preci, w2) ) { myFirstParam = w1; myLastParam = w2; UpdateParam2d(theCurve2d); myFirstDone = myLastDone = Standard_True; return; } } myFirstDone = myLastDone = Standard_True; } //======================================================================= //function : UpdateParam2d //purpose : //======================================================================= void ShapeFix_EdgeProjAux::UpdateParam2d (const Handle(Geom2d_Curve)& theCurve2d) { if (myFirstParam < myLastParam) return; Standard_Real cf = theCurve2d->FirstParameter(); Standard_Real cl = theCurve2d->LastParameter(); //:S4136 Standard_Real preci = BRepAPI::Precision(); Standard_Real preci2d = Precision::PConfusion(); //:S4136: Parametric(preci, 0.01); // 15.11.2002 PTV OCC966 if (ShapeAnalysis_Curve::IsPeriodic(theCurve2d)) { ElCLib::AdjustPeriodic(cf,cl,preci2d,myFirstParam,myLastParam); } else if (theCurve2d->IsClosed()) { //szv#4:S4163:12Mar99 optimized if ( Abs ( myFirstParam - cl ) <= preci2d ) myFirstParam = cf; else if ( Abs ( myLastParam - cf ) <= preci2d ) myLastParam = cl; else { #ifdef DEBUG cout << "Error : curve 2d range crossing non periodic curve origin"; cout << endl; #endif // add fail result; return; } } // the curve is closed within the 'file' 2D tolerance else if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) { Handle(Geom2d_BSplineCurve) aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d); if (aBSpline2d->StartPoint().Distance(aBSpline2d->EndPoint()) <= preci2d) { if ( Abs ( myFirstParam - cl ) <= preci2d ) myFirstParam = cf; else if ( Abs ( myLastParam - cf ) <= preci2d ) myLastParam = cl; } } else { #ifdef DEBUG cout << "Warning : non increasing parameters for 2d curve." << endl; cout << " update parameter 2d uncertain." << endl; #endif Standard_Real tmp1 = myFirstParam, tmp2 = myLastParam; myFirstParam = theCurve2d->ReversedParameter(tmp1); myLastParam = theCurve2d->ReversedParameter(tmp2); theCurve2d->Reverse(); //cout<<"Reversed case 2"<