// File: ShapeUpgrade_SplitCurve3dContinuity.cxx // Created: Thu Apr 15 11:15:10 1999 // Author: Roman LYGIN // #include #include #include #include #include #include #include #include #include #include #include #include #include //======================================================================= //function : ShapeUpgrade_SplitCurve3dContinuity //purpose : //======================================================================= ShapeUpgrade_SplitCurve3dContinuity::ShapeUpgrade_SplitCurve3dContinuity() { myCriterion = GeomAbs_C1; myTolerance = Precision::Confusion(); myCont =1; } //======================================================================= //function : SetCriterion //purpose : //======================================================================= void ShapeUpgrade_SplitCurve3dContinuity::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_SplitCurve3dContinuity::SetTolerance(const Standard_Real Tol) { myTolerance = Tol; } //======================================================================= //function : Compute //purpose : //=================================================================== void ShapeUpgrade_SplitCurve3dContinuity::Compute() { Standard_Real First = mySplitValues->Value(1); Standard_Real Last = mySplitValues->Value(mySplitValues->Length()); Standard_Real precision = Precision::PConfusion(); if(myCurve->Continuity() < myCriterion) myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2); if (mySplitValues->Length() > 2) myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1); if (myCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tmp = Handle(Geom_TrimmedCurve)::DownCast (myCurve); Handle(Geom_Curve) BasCurve = tmp->BasisCurve(); ShapeUpgrade_SplitCurve3dContinuity 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(myCriterion); spc.Compute(); mySplitValues->Clear(); mySplitValues->ChangeSequence() = spc.SplitValues()->Sequence(); myStatus |= spc.myStatus; return; } else if (myCurve->IsKind(STANDARD_TYPE(Geom_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) //gp_Dir Direct = tmp->Direction(); // Direct not used (skl) ShapeUpgrade_SplitCurve3dContinuity 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(Geom_BSplineCurve) MyBSpline = Handle(Geom_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; for(Standard_Integer j =2; j <= mySplitValues->Length(); j++) { Last = mySplitValues->Value(j); for (Standard_Integer iknot = FirstInd; 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); 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 "<LastUKnotIndex()-1; iknot--; } } else { // impossible to force C1 within the tolerance: // this knot will be a splitting value. mySplitValues->InsertBefore(j++,MyBSpline->Knot(iknot)); myNbCurves++; // if (ShapeUpgrade::Debug()) cout<<". Splitting at Knot "<Length() > 2) myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1); } //======================================================================= //function : GetCurve //purpose : //======================================================================= const Handle(Geom_Curve)& ShapeUpgrade_SplitCurve3dContinuity::GetCurve() const { return myCurve; }