// File: ShapeUpgrade_SplitSurfaceContinuity.cxx // Created: Wed Apr 14 15:19:20 1999 // Author: Roman LYGIN // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //====================================================================== //function : ShapeUpgrade_SplitSurface //purpose : //======================================================================= ShapeUpgrade_SplitSurfaceContinuity::ShapeUpgrade_SplitSurfaceContinuity() { myCriterion = GeomAbs_C1; myTolerance = Precision::Confusion(); } //======================================================================= //function : SetCrierion //purpose : //======================================================================= void ShapeUpgrade_SplitSurfaceContinuity::SetCriterion(const GeomAbs_Shape Criterion) { myCriterion = Criterion; switch (myCriterion) { default : case GeomAbs_C1 : myCont = 1; break; case GeomAbs_C2 : myCont = 2; break; case GeomAbs_C3 : myCont = 3; break; case GeomAbs_CN : myCont = 4; break; } } //======================================================================= //function : SetTolerance //purpose : //======================================================================= void ShapeUpgrade_SplitSurfaceContinuity::SetTolerance(const Standard_Real Tol) { myTolerance = Tol; } //======================================================================= //function : Build //purpose : //======================================================================= void ShapeUpgrade_SplitSurfaceContinuity::Compute(const Standard_Boolean Segment) { if(!Segment) { Standard_Real UF,UL,VF,VL; mySurface->Bounds(UF,UL,VF,VL); if(!Precision::IsInfinite(UF)) myUSplitValues->SetValue(1,UF); if(!Precision::IsInfinite(UL)) myUSplitValues->SetValue(myUSplitValues->Length(),UL); if(!Precision::IsInfinite(VF)) myVSplitValues->SetValue(1,VF); if(!Precision::IsInfinite(VL)) myVSplitValues->SetValue(myVSplitValues->Length(),VL); } Standard_Real UFirst = myUSplitValues->Value(1); Standard_Real ULast = myUSplitValues->Value(myUSplitValues->Length()); Standard_Real VFirst = myVSplitValues->Value(1); Standard_Real VLast = myVSplitValues->Value(myVSplitValues->Length()); Standard_Real precision = Precision::Confusion(); // if (ShapeUpgrade::Debug()) cout << "SplitSurfaceContinuity::Build" << endl; if(mySurface->Continuity() < myCriterion) myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2); if (myUSplitValues->Length() >2 || myVSplitValues->Length() >2 ) myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1); if (mySurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) { Handle(Geom_SurfaceOfRevolution) Surface = Handle(Geom_SurfaceOfRevolution)::DownCast(mySurface); if(Surface->Continuity() >= myCriterion && myUSplitValues->Length() ==2 && myVSplitValues->Length() ==2 ) { return; } Handle(Geom_Curve) BasCurve = Surface->BasisCurve(); ShapeUpgrade_SplitCurve3dContinuity spc; spc.Init(BasCurve,VFirst,VLast); spc.SetCriterion(myCriterion); spc.SetTolerance(myTolerance); spc.SetSplitValues(myVSplitValues); spc.Compute(); myVSplitValues->Clear(); myVSplitValues->ChangeSequence() = spc.SplitValues()->Sequence(); if ( spc.Status ( ShapeExtend_DONE1 ) ) myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); if ( spc.Status ( ShapeExtend_DONE2 ) ) myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 ); if ( spc.Status ( ShapeExtend_DONE3 ) ) myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 ); return; } if (mySurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) { Handle(Geom_SurfaceOfLinearExtrusion) Surface = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(mySurface); if(Surface->Continuity() >= myCriterion && myUSplitValues->Length() ==2 && myVSplitValues->Length() == 2) { return; } Handle(Geom_Curve) BasCurve = Surface->BasisCurve(); ShapeUpgrade_SplitCurve3dContinuity spc; spc.Init(BasCurve,UFirst,ULast); spc.SetCriterion(myCriterion); spc.SetTolerance(myTolerance); spc.SetSplitValues(myUSplitValues); spc.Compute(); myUSplitValues->Clear(); myUSplitValues->ChangeSequence() = spc.SplitValues()->Sequence(); if ( spc.Status ( ShapeExtend_DONE1 ) ) myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); if ( spc.Status ( ShapeExtend_DONE2 ) ) myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 ); if ( spc.Status ( ShapeExtend_DONE3 ) ) { myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 ); Handle(Geom_Curve) aNewBascurve = spc.GetCurve(); Surface->SetBasisCurve(aNewBascurve); } return; } if (mySurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { Handle(Geom_RectangularTrimmedSurface) tmp = Handle(Geom_RectangularTrimmedSurface)::DownCast (mySurface); if(tmp->Continuity() >= myCriterion && myUSplitValues->Length() ==2 && myVSplitValues->Length() == 2) { return; } Standard_Real U1,U2,V1,V2; tmp->Bounds(U1,U2,V1,V2); Handle(Geom_Surface) theSurf = tmp->BasisSurface(); ShapeUpgrade_SplitSurfaceContinuity sps; sps.Init(theSurf,Max(U1,UFirst),Min(U2,ULast),Max(V1,VFirst),Min(V2,VLast)); sps.SetUSplitValues(myUSplitValues); sps.SetVSplitValues(myVSplitValues); sps.SetTolerance(myTolerance); sps.SetCriterion(myCriterion); sps.Compute(Standard_True); myUSplitValues->Clear(); myUSplitValues->ChangeSequence() = sps.USplitValues()->Sequence(); myVSplitValues->Clear(); myVSplitValues->ChangeSequence() = sps.VSplitValues()->Sequence(); myStatus |= sps.myStatus; return; } else if (mySurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) { 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 Surface"<BasisSurface(); if(theSurf->Continuity() >= BasCriterion && myUSplitValues->Length() ==2 && myVSplitValues->Length() == 2) { return; } ShapeUpgrade_SplitSurfaceContinuity sps; sps.Init(theSurf,UFirst,ULast,VFirst,VLast); sps.SetUSplitValues(myUSplitValues); sps.SetVSplitValues(myVSplitValues); sps.SetTolerance(myTolerance); sps.SetCriterion(BasCriterion); sps.Compute(Standard_True); myUSplitValues->Clear(); myUSplitValues->ChangeSequence() = sps.USplitValues()->Sequence(); myVSplitValues->Clear(); myVSplitValues->ChangeSequence() = sps.VSplitValues()->Sequence(); myStatus |= sps.myStatus; return; } Handle(Geom_BSplineSurface) MyBSpline; if(mySurface->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) MyBSpline = Handle(Geom_BSplineSurface)::DownCast(mySurface->Copy()); if (MyBSpline.IsNull()) { // if (ShapeUpgrade::Debug()) cout<<". "<<" Surface is not a Bspline"<Continuity() >= myCriterion) { return; } // it is a BSplineSurface Standard_Integer UDeg=MyBSpline->UDegree(); Standard_Integer VDeg=MyBSpline->VDegree(); Standard_Integer NbUKnots= MyBSpline->NbUKnots(); Standard_Integer UFirstInd =MyBSpline->FirstUKnotIndex()+1, ULastInd = MyBSpline->LastUKnotIndex()-1, VFirstInd =MyBSpline->FirstVKnotIndex()+1, VLastInd = MyBSpline->LastVKnotIndex()-1; Standard_Integer NbVKnots= MyBSpline->NbVKnots(); // if (ShapeUpgrade::Debug()) cout<<". NbUKnots="<2) { // Only the internal knots are checked. Standard_Integer iknot= UFirstInd; for(Standard_Integer j =2; j <= myUSplitValues->Length(); j++) { ULast = myUSplitValues->Value(j); for (; iknot <= ULastInd; iknot++) { Standard_Real valknot = MyBSpline->UKnot(iknot); if(valknot <= UFirst + precision) continue; if( valknot >= ULast - precision) break; Standard_Integer Continuity=UDeg-MyBSpline->UMultiplicity(iknot); if (Continuity < myCont) { // At this knot, the Surface is C0; try to remove Knot. Standard_Integer newMultiplicity=UDeg - myCont; Standard_Boolean corrected = Standard_False; if ( newMultiplicity >= 0 ) corrected=MyBSpline->RemoveUKnot(iknot, newMultiplicity, myTolerance); if (corrected && newMultiplicity > 0) { Continuity=UDeg-MyBSpline->UMultiplicity(iknot); corrected = (Continuity >= myCont); } if (corrected) { // at this knot, the continuity is now C1. Nothing else to do. // if (ShapeUpgrade::Debug()) cout<<". Correction at UKnot "<UKnot(iknot); myUSplitValues->InsertBefore(j++,u); myNbResultingRow++; // if (ShapeUpgrade::Debug()) cout<<". Splitting at Knot "<VKnot(iknot); myVSplitValues->InsertBefore(j1++,v); myNbResultingCol++; // if (ShapeUpgrade::Debug()) cout<<". Splitting at Knot "<Length() >2 || myVSplitValues->Length() >2 ) myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1); }