// File: ShapeUpgrade_SplitCurve2dContinuity.cxx // Created: Wed Apr 14 19:18:17 1999 // Author: Roman LYGIN // #include #include #include #include #include #include #include #include #include #include #include #include //======================================================================= //function : ShapeUpgrade_SplitCurve2dContinuity //purpose : //======================================================================= ShapeUpgrade_SplitCurve2dContinuity::ShapeUpgrade_SplitCurve2dContinuity() { myCriterion = GeomAbs_C1; myTolerance = Precision::PConfusion(); myCont =1; } //======================================================================= //function : SetCriterion //purpose : //======================================================================= void ShapeUpgrade_SplitCurve2dContinuity::SetCriterion(const GeomAbs_Shape Criterion) { myCriterion = Criterion; switch (myCriterion) { case GeomAbs_C0 : myCont = 0; break; case GeomAbs_C1 : myCont = 1; break; case GeomAbs_C2 : myCont = 2; break; case GeomAbs_C3 : myCont = 3; break; case GeomAbs_CN : myCont = 4; break; default : myCont = 1; } } //======================================================================= //function : SetTolerance //purpose : //======================================================================= void ShapeUpgrade_SplitCurve2dContinuity::SetTolerance(const Standard_Real Tol) { myTolerance = Tol; } //======================================================================= //function : Compute //purpose : //======================================================================= void ShapeUpgrade_SplitCurve2dContinuity::Compute() { if(myCurve->Continuity() < myCriterion) myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2); if (mySplitValues->Length() > 2) myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1); Standard_Real precision = Precision::PConfusion(); Standard_Real First = mySplitValues->Value(1); Standard_Real Last = mySplitValues->Value(mySplitValues->Length()); if (myCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) { Handle(Geom2d_TrimmedCurve) tmp = Handle(Geom2d_TrimmedCurve)::DownCast (myCurve); Handle(Geom2d_Curve) BasCurve = tmp->BasisCurve(); ShapeUpgrade_SplitCurve2dContinuity spc; // spc.Init(BasCurve,Max(First,tmp->FirstParameter()),Min(Last,tmp->LastParameter())); spc.Init(BasCurve,First,Last); spc.SetSplitValues(mySplitValues); spc.SetTolerance(myTolerance); spc.SetCriterion(myCriterion); spc.Compute(); mySplitValues->Clear(); mySplitValues->ChangeSequence() = spc.SplitValues()->Sequence(); //mySplitValues = spc.SplitValues(); myStatus |= spc.myStatus; return; } else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) { GeomAbs_Shape BasCriterion; switch (myCriterion) { default : case GeomAbs_C1 : BasCriterion = GeomAbs_C2; break; case GeomAbs_C2 : BasCriterion = GeomAbs_C3; break; case GeomAbs_C3 : //if (ShapeUpgrade::Debug()) cout<<". this criterion is not suitable for a Offset curve"<BasisCurve(); //Standard_Real Offset = tmp->Offset(); // Offset not used (skl) ShapeUpgrade_SplitCurve2dContinuity spc; // spc.Init(BasCurve,Max(tmp->FirstParameter(),First),Min(tmp->LastParameter(),Last)); spc.Init(BasCurve,First,Last); spc.SetSplitValues(mySplitValues); spc.SetTolerance(myTolerance); spc.SetCriterion(BasCriterion); spc.Compute(); mySplitValues->Clear(); mySplitValues->ChangeSequence() = spc.SplitValues()->Sequence(); myStatus |= spc.myStatus; return; } Handle(Geom2d_BSplineCurve) MyBSpline = Handle(Geom2d_BSplineCurve)::DownCast (myCurve); if (MyBSpline.IsNull()) { // if (ShapeUpgrade::Debug()) cout<<". curve is not a Bspline"<Degree(); Standard_Integer NbKnots= MyBSpline->NbKnots(); // if (ShapeUpgrade::Debug()) cout<<". NbKnots="<FirstUKnotIndex()+1, LastInd = MyBSpline->LastUKnotIndex()-1; Standard_Integer iknot = FirstInd; for(Standard_Integer j =2; j <= mySplitValues->Length(); j++) { Last = mySplitValues->Value(j); for (; iknot <= LastInd; iknot++) { Standard_Real valknot = MyBSpline->Knot(iknot); if(valknot <= First + precision) continue; if(valknot >= Last - precision) break; Standard_Integer Continuity=Deg-MyBSpline->Multiplicity(iknot); //Standard_Real tt = MyBSpline->Knot(iknot); // tt not used (skl) if (Continuity < myCont) { // At this knot, the curve is C0; try to remove Knot. Standard_Boolean corrected = Standard_False; Standard_Integer newMultiplicity = Deg - myCont; if (newMultiplicity < 0) newMultiplicity = 0; { try { OCC_CATCH_SIGNALS corrected = MyBSpline->RemoveKnot(iknot, newMultiplicity, myTolerance); } catch (Standard_Failure) { corrected = Standard_False; } } if (corrected && newMultiplicity > 0) { Continuity=Deg-MyBSpline->Multiplicity(iknot); corrected = (Continuity >= myCont); } if (corrected) { // at this knot, the continuity is now C1. Nothing else to do. // if (ShapeUpgrade::Debug()) cout<<". Correction at Knot "<InsertBefore(j++,MyBSpline->Knot(iknot)); myNbCurves++; // if (ShapeUpgrade::Debug()) cout<<". Splitting at Knot "<Length() > 2) myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1); }