diff --git a/src/BRepFill/BRepFill_OffsetWire.cxx b/src/BRepFill/BRepFill_OffsetWire.cxx index 2806ec1fe7..efd39b4f0d 100644 --- a/src/BRepFill/BRepFill_OffsetWire.cxx +++ b/src/BRepFill/BRepFill_OffsetWire.cxx @@ -217,26 +217,6 @@ static void MakeOffset const Standard_Boolean IsOpenResult, const TopoDS_Vertex * Ends); - - -//======================================================================= -//function : CheckFace -//purpose : Check if face contains an edge with C0 continuity -//======================================================================= -// -static void CheckFace(const TopoDS_Face& theFace) - { - TopExp_Explorer ex(theFace,TopAbs_EDGE); - for(; ex.More(); ex.Next()) - { - TopoDS_Edge anEdge=TopoDS::Edge(ex.Current()); - Standard_Real f,l; - const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(anEdge,theFace,f,l); - if (C->Continuity() == GeomAbs_C0) - Standard_ConstructionError::Raise("Initial shape contains an edge with C0 continuity"); - } - } - //======================================================================= //function : KPartCircle //purpose : @@ -368,9 +348,6 @@ void BRepFill_OffsetWire::Init(const TopoDS_Face& Spine, // mySpine = TopoDS::Face(Spine.Oriented(TopAbs_FORWARD)); myJoinType = Join; myIsOpenResult = IsOpenResult; - - CheckFace(mySpine); - myMap.Clear(); myMapSpine.Clear(); //------------------------------------------------------------------ diff --git a/src/BRepOffset/BRepOffset_Inter3d.cxx b/src/BRepOffset/BRepOffset_Inter3d.cxx index 92686696c9..334d800ccc 100644 --- a/src/BRepOffset/BRepOffset_Inter3d.cxx +++ b/src/BRepOffset/BRepOffset_Inter3d.cxx @@ -768,7 +768,22 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte //--------------------------------------------------- const TopoDS_Shape SI = Analyse.Ancestors(E).First(); OF1 = TopoDS::Face(InitOffsetFace.Image(SI).First()); - OE = TopoDS::Edge(InitOffsetEdge.Image(E).First()); + OE = TopoDS::Edge(InitOffsetEdge.Image(E).First()); + + { + //Check if OE has pcurve in CF + + Standard_Real f,l; + + Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(OE,CF,f,l); + Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(OE,OF1,f,l); + + if(C1.IsNull() || C2.IsNull()) + { + continue; + } + } + //-------------------------------------------------- // MAJ of OE on cap CF. //-------------------------------------------------- @@ -804,6 +819,21 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte //------------------------------------------------- OF1 = TopoDS::Face(InitOffsetFace.Image(EV).First()); OE = TopoDS::Edge(InitOffsetEdge.Image(V[i]).First()); + + { + //Check if OE has pcurve in CF and OF1 + + Standard_Real f,l; + + Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(OE,CF,f,l); + Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(OE,OF1,f,l); + + if(C1.IsNull() || C2.IsNull()) + { + continue; + } + } + //-------------------------------------------------- // MAj of OE on cap CF. //-------------------------------------------------- diff --git a/src/BRepOffset/BRepOffset_Tool.cxx b/src/BRepOffset/BRepOffset_Tool.cxx index a862d7af2c..66c80a0467 100644 --- a/src/BRepOffset/BRepOffset_Tool.cxx +++ b/src/BRepOffset/BRepOffset_Tool.cxx @@ -3610,101 +3610,135 @@ void BRepOffset_Tool::ExtentFace (const TopoDS_Face& F, TopoDS_Edge ERef; TopoDS_Vertex V1,V2; - for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - exp2.More(); exp2.Next()) { + for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); exp2.More(); exp2.Next()) + { const TopoDS_Edge& E = TopoDS::Edge(exp2.Current()); TopExp::Vertices (E,V1,V2); BRep_Tool::Range (E,f,l); TopoDS_Vertex V; - if (Build.IsBound(E)) { - const TopoDS_Edge& NEOnV1 = TopoDS::Edge(NOnV1(E)); - if (Build.IsBound(NEOnV1) && - (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV1))) { - if (E.IsSame(NEOnV1)) - V = TopExp::FirstVertex(TopoDS::Edge(Build(E))); - else { - //--------------- - // intersection. - //--------------- - if (!Build.IsBound(V1)) { - Inter2d (EF,TopoDS::Edge(Build(E)), - TopoDS::Edge(Build(NEOnV1)),LV,/*TolConf*/Precision::Confusion()); - if (Build(E).Orientation() == TopAbs_FORWARD) { - V = TopoDS::Vertex(LV.First()); - } - else { - V = TopoDS::Vertex(LV.Last()); - } - } - else { - V = TopoDS::Vertex(Build(V1)); - if (MVE (V1).Extent() > 2) { - V.Orientation(TopAbs_FORWARD); - if (Build(E).Orientation() == TopAbs_REVERSED) - V.Orientation(TopAbs_REVERSED); - ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf); - } - } - } - } - else { - //------------ - //projection - //------------ - V = V1; - if (ConstShapes.IsBound(V1)) V = TopoDS::Vertex(ConstShapes(V1)); - V.Orientation(TopAbs_FORWARD); - if (Build(E).Orientation() == TopAbs_REVERSED) - V.Orientation(TopAbs_REVERSED); - if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf)) - ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf); - } - ConstShapes.Bind(V1,V); - Build.Bind (V1,V); - const TopoDS_Edge& NEOnV2 = TopoDS::Edge(NOnV2(E)); - if (Build.IsBound(NEOnV2) && - (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV2))) { - if (E.IsSame(NEOnV2)) - V = TopExp::LastVertex(TopoDS::Edge(Build(E))); - else { - //-------------- - // intersection. - //--------------- - if (!Build.IsBound(V2)) { - Inter2d (EF,TopoDS::Edge(Build(E)), - TopoDS::Edge(Build(NEOnV2)),LV,/*TolConf*/Precision::Confusion()); - if (Build(E).Orientation() == TopAbs_FORWARD) { - V = TopoDS::Vertex(LV.Last()); - } - else { - V = TopoDS::Vertex(LV.First()); - } - } - else { - V = TopoDS::Vertex(Build(V2)); - if (MVE (V2).Extent() > 2) { - V.Orientation(TopAbs_REVERSED); - if (Build(E).Orientation() == TopAbs_REVERSED) - V.Orientation(TopAbs_FORWARD); - ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf); - } - } - } - } - else { - //------------ - //projection - //------------ - V = V2; - if (ConstShapes.IsBound(V2)) V = TopoDS::Vertex(ConstShapes(V2)); - V.Orientation(TopAbs_REVERSED); - if (Build(E).Orientation() == TopAbs_REVERSED) - V.Orientation(TopAbs_FORWARD); - if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf)) - ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf); - } - ConstShapes.Bind(V2,V); - Build.Bind(V2,V); + if (Build.IsBound(E)) + { + const TopoDS_Edge& NEOnV1 = TopoDS::Edge(NOnV1(E)); + if (Build.IsBound(NEOnV1) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV1))) + { + if (E.IsSame(NEOnV1)) + V = TopExp::FirstVertex(TopoDS::Edge(Build(E))); + else + { + //--------------- + // intersection. + //--------------- + if (!Build.IsBound(V1)) + { + Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV1)),LV,/*TolConf*/Precision::Confusion()); + + if(!LV.IsEmpty()) + { + if (Build(E).Orientation() == TopAbs_FORWARD) + { + V = TopoDS::Vertex(LV.First()); + } + else + { + V = TopoDS::Vertex(LV.Last()); + } + } + else + { + return; + } + } + else + { + V = TopoDS::Vertex(Build(V1)); + if (MVE (V1).Extent() > 2) + { + V.Orientation(TopAbs_FORWARD); + if (Build(E).Orientation() == TopAbs_REVERSED) + V.Orientation(TopAbs_REVERSED); + + ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf); + } + } + } + } + else + { + //------------ + //projection + //------------ + V = V1; + if (ConstShapes.IsBound(V1)) V = TopoDS::Vertex(ConstShapes(V1)); + V.Orientation(TopAbs_FORWARD); + if (Build(E).Orientation() == TopAbs_REVERSED) + V.Orientation(TopAbs_REVERSED); + if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf)) + ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf); + } + + ConstShapes.Bind(V1,V); + Build.Bind (V1,V); + const TopoDS_Edge& NEOnV2 = TopoDS::Edge(NOnV2(E)); + if (Build.IsBound(NEOnV2) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV2))) + { + if (E.IsSame(NEOnV2)) + V = TopExp::LastVertex(TopoDS::Edge(Build(E))); + else + { + //-------------- + // intersection. + //--------------- + + if (!Build.IsBound(V2)) + { + Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV2)),LV,/*TolConf*/Precision::Confusion()); + + if(!LV.IsEmpty()) + { + if (Build(E).Orientation() == TopAbs_FORWARD) + { + V = TopoDS::Vertex(LV.Last()); + } + else + { + V = TopoDS::Vertex(LV.First()); + } + } + else + { + return; + } + } + else + { + V = TopoDS::Vertex(Build(V2)); + if (MVE (V2).Extent() > 2) + { + V.Orientation(TopAbs_REVERSED); + if (Build(E).Orientation() == TopAbs_REVERSED) + V.Orientation(TopAbs_FORWARD); + + ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf); + } + } + } + } + else + { + //------------ + //projection + //------------ + V = V2; + if (ConstShapes.IsBound(V2)) + V = TopoDS::Vertex(ConstShapes(V2)); + V.Orientation(TopAbs_REVERSED); + if (Build(E).Orientation() == TopAbs_REVERSED) + V.Orientation(TopAbs_FORWARD); + if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf)) + ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf); + } + ConstShapes.Bind(V2,V); + Build.Bind(V2,V); } } diff --git a/src/BSplCLib/BSplCLib.cxx b/src/BSplCLib/BSplCLib.cxx index 683e4ab76e..e53a28df93 100644 --- a/src/BSplCLib/BSplCLib.cxx +++ b/src/BSplCLib/BSplCLib.cxx @@ -1175,7 +1175,8 @@ void BSplCLib::Bohm(const Standard_Real U, for (j = Degm1; j >= i; j--) { jDmi--; - *pole -= *tbis; *pole /= (knot[jDmi] - knot[j]); + *pole -= *tbis; + *pole = (knot[jDmi] == knot[j]) ? 0.0 : *pole / (knot[jDmi] - knot[j]); pole--; tbis--; } @@ -1219,7 +1220,7 @@ void BSplCLib::Bohm(const Standard_Real U, for (j = Degm1; j >= i; j--) { jDmi--; - coef = 1. / (knot[jDmi] - knot[j]); + coef = (knot[jDmi] == knot[j]) ? 0.0 : 1. / (knot[jDmi] - knot[j]); *pole -= *tbis; *pole *= coef; pole++; tbis++; *pole -= *tbis; *pole *= coef; pole -= 3; @@ -1267,7 +1268,7 @@ void BSplCLib::Bohm(const Standard_Real U, for (j = Degm1; j >= i; j--) { jDmi--; - coef = 1. / (knot[jDmi] - knot[j]); + coef = (knot[jDmi] == knot[j]) ? 0.0 : 1. / (knot[jDmi] - knot[j]); *pole -= *tbis; *pole *= coef; pole++; tbis++; *pole -= *tbis; *pole *= coef; pole++; tbis++; *pole -= *tbis; *pole *= coef; @@ -1318,7 +1319,7 @@ void BSplCLib::Bohm(const Standard_Real U, for (j = Degm1; j >= i; j--) { jDmi--; - coef = 1. / (knot[jDmi] - knot[j]); + coef = (knot[jDmi] == knot[j]) ? 0.0 : 1. /(knot[jDmi] - knot[j]) ; *pole -= *tbis; *pole *= coef; pole++; tbis++; *pole -= *tbis; *pole *= coef; pole++; tbis++; *pole -= *tbis; *pole *= coef; pole++; tbis++; @@ -1374,7 +1375,7 @@ void BSplCLib::Bohm(const Standard_Real U, for (j = Degm1; j >= i; j--) { jDmi--; - coef = 1. / (knot[jDmi] - knot[j]); + coef = (knot[jDmi] == knot[j]) ? 0.0 : 1. / (knot[jDmi] - knot[j]); for (k = 0; k < Dimension; k++) { *pole -= *tbis; *pole *= coef; pole++; tbis++; diff --git a/src/Geom/Geom_BSplineCurve.cdl b/src/Geom/Geom_BSplineCurve.cdl index 7334d8207c..40ba005ce4 100644 --- a/src/Geom/Geom_BSplineCurve.cdl +++ b/src/Geom/Geom_BSplineCurve.cdl @@ -563,6 +563,14 @@ is raises RangeError; ---Purpose : Raised if N < 0. + IsG1 (me; theTf, theTl, theAngTol : Real) returns Boolean; + ---Purpose : + -- Check if curve has at least G1 continuity in interval [theTf, theTl] + -- Returns true if IsCN(1) + -- or + -- angle betweem "left" and "right" first derivatives at + -- knots with C0 continuity is less then theAngTol + -- only knots in interval [theTf, theTl] is checked IsClosed (me) returns Boolean; ---Purpose : diff --git a/src/Geom/Geom_BSplineCurve_1.cxx b/src/Geom/Geom_BSplineCurve_1.cxx index b5454d5067..ec08ce5a43 100644 --- a/src/Geom/Geom_BSplineCurve_1.cxx +++ b/src/Geom/Geom_BSplineCurve_1.cxx @@ -62,6 +62,84 @@ Standard_Boolean Geom_BSplineCurve::IsCN ( const Standard_Integer N) const return Standard_False; } } +//======================================================================= +//function : IsG1 +//purpose : +//======================================================================= + +Standard_Boolean Geom_BSplineCurve::IsG1 ( const Standard_Real theTf, + const Standard_Real theTl, + const Standard_Real theAngTol) const +{ + if(IsCN(1)) + { + return Standard_True; + } + + Standard_Integer start = FirstUKnotIndex()+1, + finish = LastUKnotIndex()-1; + Standard_Integer aDeg = Degree(); + for(Standard_Integer aNKnot = start; aNKnot <= finish; aNKnot++) + { + const Standard_Real aTpar = Knot(aNKnot); + + if(aTpar < theTf) + continue; + if(aTpar > theTl) + break; + + Standard_Integer mult = Multiplicity(aNKnot); + if (mult < aDeg) + continue; + + gp_Pnt aP1, aP2; + gp_Vec aV1, aV2; + LocalD1(aTpar, aNKnot-1, aNKnot, aP1, aV1); + LocalD1(aTpar, aNKnot, aNKnot+1, aP2, aV2); + + if((aV1.SquareMagnitude() <= gp::Resolution()) || + aV2.SquareMagnitude() <= gp::Resolution()) + { + return Standard_False; + } + + if(Abs(aV1.Angle(aV2)) > theAngTol) + return Standard_False; + } + + if(!IsPeriodic()) + return Standard_True; + + const Standard_Real aFirstParam = FirstParameter(), + aLastParam = LastParameter(); + + if( ((aFirstParam - theTf)*(theTl - aFirstParam) < 0.0) && + ((aLastParam - theTf)*(theTl - aLastParam) < 0.0)) + { + //Range [theTf, theTl] does not intersect curve bounadries + return Standard_True; + } + + //Curve is closed or periodic and range [theTf, theTl] + //intersect curve boundary. Therefore, it is necessary to + //check if curve is smooth in its first and last point. + + gp_Pnt aP; + gp_Vec aV1, aV2; + D1(Knot(FirstUKnotIndex()), aP, aV1); + D1(Knot(LastUKnotIndex()), aP, aV2); + + if((aV1.SquareMagnitude() <= gp::Resolution()) || + aV2.SquareMagnitude() <= gp::Resolution()) + { + return Standard_False; + } + + if(Abs(aV1.Angle(aV2)) > theAngTol) + return Standard_False; + + return Standard_True; +} //======================================================================= //function : IsClosed diff --git a/src/Geom/Geom_OffsetCurve.cdl b/src/Geom/Geom_OffsetCurve.cdl index 19b5464fc4..02aeae36eb 100644 --- a/src/Geom/Geom_OffsetCurve.cdl +++ b/src/Geom/Geom_OffsetCurve.cdl @@ -84,7 +84,10 @@ is - Create (C : Curve from Geom; Offset : Real; V : Dir) + Create (C : Curve from Geom; + Offset : Real; + V : Dir; + isNotCheckC0 : Boolean = Standard_False) returns OffsetCurve ---Purpose : -- C is the basis curve, Offset is the distance between and @@ -94,6 +97,8 @@ is -- at this point, the corresponding point on the offset curve is -- in the direction of the vector-product N = V ^ T where -- N is a unitary vector. + -- If isNotCheckC0 = TRUE checking if basis curve has C0-continuity + -- is not made. -- Warnings : -- In this package the entities are not shared. The OffsetCurve is -- built with a copy of the curve C. So when C is modified the @@ -122,9 +127,14 @@ is -- the point of parameter U on this offset curve. - SetBasisCurve (me : mutable; C : Curve from Geom) + SetBasisCurve ( me : mutable; + C : Curve from Geom; + isNotCheckC0 : Boolean = Standard_False) raises ConstructionError; - ---Purpose : Changes this offset curve by assigning C as the basis curve from which it is built. + ---Purpose : Changes this offset curve by assigning C + -- as the basis curve from which it is built. + -- If isNotCheckC0 = TRUE checking if basis curve + -- has C0-continuity is not made. -- Exceptions -- Standard_ConstructionError if the curve C is not at least "C1" continuous. @@ -348,10 +358,15 @@ is Copy (me) returns like me; ---Purpose: Creates a new object which is a copy of this offset curve. + GetBasisCurveContinuity(me) + returns Shape from GeomAbs; + ---Purpose: Returns continuity of the basis curve. + fields basisCurve : Curve from Geom; direction : Dir; offsetValue : Real; - + myBasisCurveContinuity : Shape from GeomAbs; + end; diff --git a/src/Geom/Geom_OffsetCurve.cxx b/src/Geom/Geom_OffsetCurve.cxx index 58a1cf88ac..c273f9e7d7 100644 --- a/src/Geom/Geom_OffsetCurve.cxx +++ b/src/Geom/Geom_OffsetCurve.cxx @@ -59,6 +59,7 @@ typedef gp_XYZ XYZ; //derivee non nulle static const int maxDerivOrder = 3; static const Standard_Real MinStep = 1e-7; +static const Standard_Real MyAngularToleranceForG1 = Precision::Angular(); @@ -79,34 +80,17 @@ Handle(Geom_Geometry) Geom_OffsetCurve::Copy () const { //======================================================================= //function : Geom_OffsetCurve -//purpose : +//purpose : Basis curve cannot be an Offset curve or trimmed from +// offset curve. //======================================================================= -Geom_OffsetCurve::Geom_OffsetCurve (const Handle(Curve)& C, - const Standard_Real Offset, - const Dir& V ) - : direction(V), offsetValue(Offset) +Geom_OffsetCurve::Geom_OffsetCurve (const Handle(Geom_Curve)& theCurve, + const Standard_Real theOffset, + const gp_Dir& theDir, + const Standard_Boolean isTheNotCheckC0) + : direction(theDir), offsetValue(theOffset) { - if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) { - Handle(OffsetCurve) OC = Handle(OffsetCurve)::DownCast(C); - SetBasisCurve (OC->BasisCurve()); - - Standard_Real PrevOff = OC->Offset(); - gp_Vec V1(OC->Direction()); - gp_Vec V2(direction); - gp_Vec Vdir(PrevOff*V1 + offsetValue*V2); - - if (Offset >= 0.) { - offsetValue = Vdir.Magnitude(); - direction.SetXYZ(Vdir.XYZ()); - } else { - offsetValue = -Vdir.Magnitude(); - direction.SetXYZ((-Vdir).XYZ()); - } - } - else { - SetBasisCurve(C); - } + SetBasisCurve (theCurve, isTheNotCheckC0); } @@ -182,36 +166,78 @@ Standard_Real Geom_OffsetCurve::Period () const //purpose : //======================================================================= -void Geom_OffsetCurve::SetBasisCurve (const Handle(Curve)& C) +void Geom_OffsetCurve::SetBasisCurve (const Handle(Curve)& C, + const Standard_Boolean isNotCheckC0) { - Handle(Curve) aBasisCurve = Handle(Curve)::DownCast(C->Copy()); + const Standard_Real aUf = C->FirstParameter(), + aUl = C->LastParameter(); + Handle(Curve) aCheckingCurve = Handle(Curve)::DownCast(C->Copy()); + Standard_Boolean isTrimmed = Standard_False; + + while(aCheckingCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) || + aCheckingCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) + { + if (aCheckingCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) + { + Handle(Geom_TrimmedCurve) aTrimC = + Handle(Geom_TrimmedCurve)::DownCast(aCheckingCurve); + aCheckingCurve = aTrimC->BasisCurve(); + isTrimmed = Standard_True; + } + + if (aCheckingCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) + { + Handle(Geom_OffsetCurve) aOC = + Handle(Geom_OffsetCurve)::DownCast(aCheckingCurve); + aCheckingCurve = aOC->BasisCurve(); + Standard_Real PrevOff = aOC->Offset(); + gp_Vec V1(aOC->Direction()); + gp_Vec V2(direction); + gp_Vec Vdir(PrevOff*V1 + offsetValue*V2); + + if (offsetValue >= 0.) + { + offsetValue = Vdir.Magnitude(); + direction.SetXYZ(Vdir.XYZ()); + } + else + { + offsetValue = -Vdir.Magnitude(); + direction.SetXYZ((-Vdir).XYZ()); + } + } + } + + myBasisCurveContinuity = aCheckingCurve->Continuity(); + + Standard_Boolean isC0 = !isNotCheckC0 && + (myBasisCurveContinuity == GeomAbs_C0); // Basis curve must be at least C1 - if (aBasisCurve->Continuity() == GeomAbs_C0) + if (isC0 && aCheckingCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) { - // For B-splines it is sometimes possible to increase continuity by removing - // unnecessarily duplicated knots - if (aBasisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) + Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCheckingCurve); + if(aBC->IsG1(aUf, aUl, MyAngularToleranceForG1)) { - Handle(Geom_BSplineCurve) aBCurve = Handle(Geom_BSplineCurve)::DownCast(aBasisCurve); - Standard_Integer degree = aBCurve->Degree(); - Standard_Real Toler = Precision::Confusion(); - Standard_Integer start = aBCurve->IsPeriodic() ? 1 : aBCurve->FirstUKnotIndex(), - finish = aBCurve->IsPeriodic() ? aBCurve->NbKnots() : aBCurve->LastUKnotIndex(); - for (Standard_Integer i = start; i <= finish; i++) - { - Standard_Integer mult = aBCurve->Multiplicity(i); - if ( mult == degree ) - aBCurve->RemoveKnot(i,degree - 1, Toler); - } + //Checking if basis curve has more smooth (C1, G2 and above) is not done. + //It can be done in case of need. + myBasisCurveContinuity = GeomAbs_G1; + isC0 = Standard_False; } // Raise exception if still C0 - if (aBasisCurve->Continuity() == GeomAbs_C0) + if (isC0) Standard_ConstructionError::Raise("Offset on C0 curve"); } - - basisCurve = aBasisCurve; + // + if(isTrimmed) + { + basisCurve = new Geom_TrimmedCurve(aCheckingCurve, aUf, aUl); + } + else + { + basisCurve = aCheckingCurve; + } } @@ -235,7 +261,7 @@ Handle(Curve) Geom_OffsetCurve::BasisCurve () const GeomAbs_Shape Geom_OffsetCurve::Continuity () const { GeomAbs_Shape OffsetShape=GeomAbs_C0; - switch (basisCurve->Continuity()) { + switch (myBasisCurveContinuity) { case GeomAbs_C0 : OffsetShape = GeomAbs_C0; break; case GeomAbs_C1 : OffsetShape = GeomAbs_C0; break; case GeomAbs_C2 : OffsetShape = GeomAbs_C1; break; @@ -825,13 +851,13 @@ Standard_Real Geom_OffsetCurve::Offset () const { return offsetValue; } void Geom_OffsetCurve::Value (const Standard_Real theU, Pnt& theP, Pnt& thePbasis, Vec& theV1basis) const - { - if (basisCurve->Continuity() == GeomAbs_C0) +{ + if (myBasisCurveContinuity == GeomAbs_C0) Geom_UndefinedValue::Raise("Exception: Basis curve is C0 continuity!"); basisCurve->D1(theU, thePbasis, theV1basis); D0(theU,theP); - } +} //======================================================================= @@ -894,3 +920,12 @@ const { return basisCurve->ParametricTransformation(T); } + +//======================================================================= +//function : GetBasisCurveContinuity +//purpose : +//======================================================================= +GeomAbs_Shape Geom_OffsetCurve::GetBasisCurveContinuity() const +{ + return myBasisCurveContinuity; +} diff --git a/src/Geom/Geom_OffsetSurface.cdl b/src/Geom/Geom_OffsetSurface.cdl index 5dccb5d297..88a3260d31 100644 --- a/src/Geom/Geom_OffsetSurface.cdl +++ b/src/Geom/Geom_OffsetSurface.cdl @@ -68,7 +68,10 @@ is - Create (S : Surface from Geom; Offset : Real) returns OffsetSurface + Create (S : Surface from Geom; + Offset : Real; + isNotCheckC0 : Boolean = Standard_False) + returns OffsetSurface ---Purpose : Constructs a surface offset from the basis surface -- S, where Offset is the distance between the offset -- surface and the basis surface at any point. @@ -81,6 +84,8 @@ is -- which the offset value is measured is indicated by -- this normal vector if Offset is positive, or is the -- inverse sense if Offset is negative. + -- If isNotCheckC0 = TRUE checking if basis surface has C0-continuity + -- is not made. -- Warnings : -- - The offset surface is built with a copy of the -- surface S. Therefore, when S is modified the @@ -95,12 +100,16 @@ is - SetBasisSurface (me : mutable; S : Surface from Geom) + SetBasisSurface ( me : mutable; + S : Surface from Geom; + isNotCheckC0 : Boolean = Standard_False) raises ConstructionError; ---Purpose : Raised if S is not at least C1. -- Warnings : -- No check is done to verify that a unique normal direction is -- defined at any point of the basis surface S. + -- If isNotCheckC0 = TRUE checking if basis surface has C0-continuity + -- is not made. -- Exceptions -- Standard_ConstructionError if the surface S is not -- at least "C1" continuous. @@ -484,11 +493,15 @@ is -- these vectors have opposite direction. returns Boolean from Standard; - + GetBasisSurfContinuity(me) + returns Shape from GeomAbs; + ---Purpose: Returns continuity of the basis surface. + fields basisSurf : Surface from Geom; equivSurf : Surface from Geom; offsetValue : Real; myOscSurf : OsculatingSurface from Geom; + myBasisSurfContinuity : Shape from GeomAbs; end; diff --git a/src/Geom/Geom_OffsetSurface.cxx b/src/Geom/Geom_OffsetSurface.cxx index f4f298ce93..c708bb0a9f 100644 --- a/src/Geom/Geom_OffsetSurface.cxx +++ b/src/Geom/Geom_OffsetSurface.cxx @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,7 @@ #include #include #include +#include #include #include @@ -81,123 +83,125 @@ typedef gp_Vec Vec; typedef gp_Pnt Pnt; typedef gp_Trsf Trsf; typedef gp_XYZ XYZ; + +static const Standard_Real MyAngularToleranceForG1 = Precision::Angular(); //======================================================================= //function : derivatives //purpose : //======================================================================= static void derivatives(Standard_Integer MaxOrder, - Standard_Integer MinOrder, - const Standard_Real U, - const Standard_Real V, - const Handle(Geom_Surface)& basisSurf, - const Standard_Integer Nu, - const Standard_Integer Nv, - const Standard_Boolean AlongU, - const Standard_Boolean AlongV, - const Handle(Geom_BSplineSurface)& L, - TColgp_Array2OfVec& DerNUV, - TColgp_Array2OfVec& DerSurf) + Standard_Integer MinOrder, + const Standard_Real U, + const Standard_Real V, + const Handle(Geom_Surface)& basisSurf, + const Standard_Integer Nu, + const Standard_Integer Nv, + const Standard_Boolean AlongU, + const Standard_Boolean AlongV, + const Handle(Geom_BSplineSurface)& L, + TColgp_Array2OfVec& DerNUV, + TColgp_Array2OfVec& DerSurf) { - Standard_Integer i,j; - gp_Pnt P; - gp_Vec DL1U, DL1V, DL2U , DL2V , DL2UV ,DL3U, DL3UUV, DL3UVV, DL3V; - - if (AlongU || AlongV) - { - MaxOrder=0; - TColgp_Array2OfVec DerSurfL(0,MaxOrder+Nu+1,0,MaxOrder+Nv+1); - switch (MinOrder) - { - case 1 : - L->D1(U, V, P, DL1U, DL1V); - DerSurfL.SetValue(1, 0, DL1U); - DerSurfL.SetValue(0, 1, DL1V); - break; - case 2 : - L->D2(U, V, P, DL1U, DL1V, DL2U , DL2V , DL2UV); - DerSurfL.SetValue(1, 0, DL1U); - DerSurfL.SetValue(0, 1, DL1V); - DerSurfL.SetValue(1, 1, DL2UV); - DerSurfL.SetValue(2, 0, DL2U); - DerSurfL.SetValue(0, 2, DL2V); - break; - case 3 : - L->D3(U, V, P, DL1U, DL1V, DL2U , DL2V , DL2UV ,DL3U, DL3V ,DL3UUV, DL3UVV); - DerSurfL.SetValue(1, 0, DL1U); - DerSurfL.SetValue(0, 1, DL1V); - DerSurfL.SetValue(1, 1, DL2UV); - DerSurfL.SetValue(2, 0, DL2U); - DerSurfL.SetValue(0, 2, DL2V); - DerSurfL.SetValue(3, 0, DL3U); - DerSurfL.SetValue(2, 1, DL3UUV); - DerSurfL.SetValue(1, 2, DL3UVV); - DerSurfL.SetValue(0, 3, DL3V); - break; - default: - break; - } + Standard_Integer i,j; + gp_Pnt P; + gp_Vec DL1U, DL1V, DL2U , DL2V , DL2UV ,DL3U, DL3UUV, DL3UVV, DL3V; - if(Nu <= Nv) - { - for(i=0;i<=MaxOrder+1+Nu;i++) - for(j=i;j<=MaxOrder+Nv+1;j++) - if(i+j> MinOrder) - { - DerSurfL.SetValue(i,j,L->DN(U,V,i,j)); - DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j)); - if (i!=j && j <= Nu+1) - { - DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i)); - DerSurfL.SetValue(j,i,L->DN(U,V,j,i)); - } - } - } - else - { - for(j=0;j<=MaxOrder+1+Nv;j++) - for(i=j;i<=MaxOrder+Nu+1;i++) - if(i+j> MinOrder) - { - DerSurfL.SetValue(i,j,L->DN(U,V,i,j)); - DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j)); - if (i!=j && i <= Nv+1) - { - DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i)); - DerSurfL.SetValue(j,i,L->DN(U,V,j,i)); - } - } - } - for(i=0;i<=MaxOrder+Nu;i++) - for(j=0;j<=MaxOrder+Nv;j++) + if (AlongU || AlongV) + { + MaxOrder=0; + TColgp_Array2OfVec DerSurfL(0,MaxOrder+Nu+1,0,MaxOrder+Nv+1); + switch (MinOrder) + { + case 1 : + L->D1(U, V, P, DL1U, DL1V); + DerSurfL.SetValue(1, 0, DL1U); + DerSurfL.SetValue(0, 1, DL1V); + break; + case 2 : + L->D2(U, V, P, DL1U, DL1V, DL2U , DL2V , DL2UV); + DerSurfL.SetValue(1, 0, DL1U); + DerSurfL.SetValue(0, 1, DL1V); + DerSurfL.SetValue(1, 1, DL2UV); + DerSurfL.SetValue(2, 0, DL2U); + DerSurfL.SetValue(0, 2, DL2V); + break; + case 3 : + L->D3(U, V, P, DL1U, DL1V, DL2U , DL2V , DL2UV ,DL3U, DL3V ,DL3UUV, DL3UVV); + DerSurfL.SetValue(1, 0, DL1U); + DerSurfL.SetValue(0, 1, DL1V); + DerSurfL.SetValue(1, 1, DL2UV); + DerSurfL.SetValue(2, 0, DL2U); + DerSurfL.SetValue(0, 2, DL2V); + DerSurfL.SetValue(3, 0, DL3U); + DerSurfL.SetValue(2, 1, DL3UUV); + DerSurfL.SetValue(1, 2, DL3UVV); + DerSurfL.SetValue(0, 3, DL3V); + break; + default: + break; + } + + if(Nu <= Nv) + { + for(i=0;i<=MaxOrder+1+Nu;i++) + for(j=i;j<=MaxOrder+Nv+1;j++) + if(i+j> MinOrder) { - if (AlongU) - DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurfL,DerSurf)); - if (AlongV) - DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf,DerSurfL)); - } - - } - else - { - - for(i=0;i<=MaxOrder+Nu+1;i++) - for(j=i;j<=MaxOrder+Nv+1;j++) - if(i+j>MinOrder) - { - - DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j)); - if (i!=j) DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i)); - } - for(i=0;i<=MaxOrder+Nu;i++) - for(j=0;j<=MaxOrder+Nv;j++) + DerSurfL.SetValue(i,j,L->DN(U,V,i,j)); + DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j)); + if (i!=j && j <= Nu+1) { - DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf)); - } + DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i)); + DerSurfL.SetValue(j,i,L->DN(U,V,j,i)); + } + } + } + else + { + for(j=0;j<=MaxOrder+1+Nv;j++) + for(i=j;i<=MaxOrder+Nu+1;i++) + if(i+j> MinOrder) + { + DerSurfL.SetValue(i,j,L->DN(U,V,i,j)); + DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j)); + if (i!=j && i <= Nv+1) + { + DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i)); + DerSurfL.SetValue(j,i,L->DN(U,V,j,i)); + } + } + } + for(i=0;i<=MaxOrder+Nu;i++) + for(j=0;j<=MaxOrder+Nv;j++) + { + if (AlongU) + DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurfL,DerSurf)); + if (AlongV) + DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf,DerSurfL)); } - + + } + else + { + + for(i=0;i<=MaxOrder+Nu+1;i++) + for(j=i;j<=MaxOrder+Nv+1;j++) + if(i+j>MinOrder) + { + + DerSurf.SetValue(i,j,basisSurf->DN(U,V,i,j)); + if (i!=j) DerSurf.SetValue(j,i,basisSurf->DN(U,V,j,i)); + } + for(i=0;i<=MaxOrder+Nu;i++) + for(j=0;j<=MaxOrder+Nv;j++) + { + DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf)); + } + } + } - + //======================================================================= //function : Copy @@ -206,9 +210,9 @@ static void derivatives(Standard_Integer MaxOrder, Handle(Geom_Geometry) Geom_OffsetSurface::Copy () const { - Handle(OffsetSurface) S; - S = new OffsetSurface (basisSurf, offsetValue); - return S; + Handle(OffsetSurface) S; + S = new OffsetSurface (basisSurf, offsetValue); + return S; } @@ -217,78 +221,147 @@ Handle(Geom_Geometry) Geom_OffsetSurface::Copy () const { //======================================================================= //function : Geom_OffsetSurface -//purpose : +//purpose : Basis surface cannot be an Offset surface or trimmed from +// offset surface. //======================================================================= -Geom_OffsetSurface::Geom_OffsetSurface ( const Handle(Surface)& S, - const Standard_Real Offset ) - : offsetValue (Offset) +Geom_OffsetSurface::Geom_OffsetSurface (const Handle(Geom_Surface)& theSurf, + const Standard_Real theOffset, + const Standard_Boolean isTheNotCheckC0) + : offsetValue (theOffset) { - Handle(Geom_OffsetSurface) Off_S; - Off_S = Handle(Geom_OffsetSurface)::DownCast(S); - if (!Off_S.IsNull()) { - offsetValue += Off_S->Offset(); - SetBasisSurface (Off_S->BasisSurface()); - } - else { - SetBasisSurface(S); - } -// -// Tolerance en dur pour l'instant ,mais on devrait la proposer dans le constructeur -// et la mettre en champ, on pourrait utiliser par exemple pour l'extraction d'iso -// et aussi pour les singularite. Pour les surfaces osculatrices, on l'utilise pour -// detecter si une iso est degeneree. - Standard_Real Tol = Precision::Confusion(); //0.0001; - myOscSurf.Init(basisSurf,Tol); + SetBasisSurface(theSurf, isTheNotCheckC0); + } - - //======================================================================= //function : SetBasisSurface //purpose : //======================================================================= -void Geom_OffsetSurface::SetBasisSurface (const Handle(Surface)& S) +void Geom_OffsetSurface::SetBasisSurface (const Handle(Surface)& S, + const Standard_Boolean isNotCheckC0) { - Handle(Surface) aBasisSurf = Handle(Surface)::DownCast(S->Copy()); + Standard_Real aUf, aUl, aVf, aVl; + S->Bounds(aUf, aUl, aVf, aVl); + + Handle(Surface) aCheckingSurf = Handle(Surface)::DownCast(S->Copy()); + Standard_Boolean isTrimmed = Standard_False; + + while(aCheckingSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) || + aCheckingSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) + { + if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) + { + Handle(Geom_RectangularTrimmedSurface) aTrimS = + Handle(Geom_RectangularTrimmedSurface)::DownCast(aCheckingSurf); + aCheckingSurf = aTrimS->BasisSurface(); + isTrimmed = Standard_True; + } + + if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) + { + Handle(Geom_OffsetSurface) aOS = + Handle(Geom_OffsetSurface)::DownCast(aCheckingSurf); + aCheckingSurf = aOS->BasisSurface(); + offsetValue += aOS->Offset(); + } + } + + + myBasisSurfContinuity = aCheckingSurf->Continuity(); + + Standard_Boolean isC0 = !isNotCheckC0 && + (myBasisSurfContinuity == GeomAbs_C0); // Basis surface must be at least C1 - if (aBasisSurf->Continuity() == GeomAbs_C0) + if (isC0) { - // For B-splines it is sometimes possible to increase continuity by removing - // unnecessarily duplicated knots - if (aBasisSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) + Handle(Geom_Curve) aCurve; + + if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) { - Handle(Geom_BSplineSurface) aBSurf = Handle(Geom_BSplineSurface)::DownCast(aBasisSurf); - Standard_Integer uDegree = aBSurf->UDegree(), vDegree = aBSurf->VDegree(); - Standard_Real Toler = Precision::Confusion(); - Standard_Integer start = aBSurf->IsUPeriodic() ? 1 : aBSurf->FirstUKnotIndex(), - finish = aBSurf->IsUPeriodic() ? aBSurf->NbUKnots() : aBSurf->LastUKnotIndex(); - for (Standard_Integer i = start; i <= finish; i++) + Handle(Geom_SurfaceOfRevolution) aRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(aCheckingSurf); + aCurve = aRevSurf->BasisCurve(); + } + else if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) + { + Handle(Geom_SurfaceOfLinearExtrusion) aLESurf = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aCheckingSurf); + aCurve = aLESurf->BasisCurve(); + } + + if(!aCurve.IsNull()) + { + while(aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) || + aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) { - Standard_Integer mult = aBSurf->UMultiplicity(i); - if ( mult == uDegree ) - aBSurf->RemoveUKnot(i,uDegree - 1, Toler); - } - start = aBSurf->IsVPeriodic() ? 1 : aBSurf->FirstVKnotIndex(); - finish = aBSurf->IsVPeriodic() ? aBSurf->NbVKnots() : aBSurf->LastVKnotIndex(); - for (Standard_Integer i = start; i <= finish; i++) - { - Standard_Integer mult = aBSurf->VMultiplicity(i); - if ( mult == vDegree ) - aBSurf->RemoveVKnot(i,vDegree - 1, Toler); + if (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) + { + Handle(Geom_TrimmedCurve) aTrimC = + Handle(Geom_TrimmedCurve)::DownCast(aCurve); + aCurve = aTrimC->BasisCurve(); + } + + if (aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) + { + Handle(Geom_OffsetCurve) aOC = + Handle(Geom_OffsetCurve)::DownCast(aCurve); + aCurve = aOC->BasisCurve(); + } } } + Standard_Real aUIsoPar = (aUf + aUl)/2.0, aVIsoPar = (aVf + aVl)/2.0; + Standard_Boolean isUG1 = Standard_False, isVG1 = Standard_False; + + const Handle(Geom_Curve) aCurv1 = aCurve.IsNull() ? aCheckingSurf->UIso(aUIsoPar) : aCurve; + const Handle(Geom_Curve) aCurv2 = aCheckingSurf->VIso(aVIsoPar); + isUG1 = !aCurv1->IsKind(STANDARD_TYPE(Geom_BSplineCurve)); + isVG1 = !aCurv2->IsKind(STANDARD_TYPE(Geom_BSplineCurve)); + + if(!isUG1) + { + Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCurv1); + isUG1 = aBC->IsG1(aVf, aVl, MyAngularToleranceForG1); + } + // + if(!isVG1) + { + Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCurv2); + isVG1 = aBC->IsG1(aUf, aUl, MyAngularToleranceForG1); + } + // + if(isUG1 && isVG1) + { + myBasisSurfContinuity = GeomAbs_G1; + isC0 = Standard_False; + } + // Raise exception if still C0 - if (aBasisSurf->Continuity() == GeomAbs_C0) + if (isC0) Standard_ConstructionError::Raise("Offset with no C1 Surface"); } - basisSurf = aBasisSurf; + if(isTrimmed) + { + basisSurf = + new Geom_RectangularTrimmedSurface(aCheckingSurf, aUf, aUl, aVf, aVl); + } + else + { + basisSurf = aCheckingSurf; + } + equivSurf = Surface(); + // + // Tolerance en dur pour l'instant ,mais on devrait la proposer dans le constructeur + // et la mettre en champ, on pourrait utiliser par exemple pour l'extraction d'iso + // et aussi pour les singularite. Pour les surfaces osculatrices, on l'utilise pour + // detecter si une iso est degeneree. + Standard_Real Tol = Precision::Confusion(); //0.0001; + myOscSurf.Init(basisSurf,Tol); + } @@ -368,11 +441,11 @@ Handle(Surface) Geom_OffsetSurface::BasisSurface () const //======================================================================= void Geom_OffsetSurface::Bounds (Standard_Real& U1, - Standard_Real& U2, - Standard_Real& V1, - Standard_Real& V2) const { - - basisSurf->Bounds (U1, U2 ,V1, V2); + Standard_Real& U2, + Standard_Real& V1, + Standard_Real& V2) const { + + basisSurf->Bounds (U1, U2 ,V1, V2); } @@ -384,14 +457,14 @@ void Geom_OffsetSurface::Bounds (Standard_Real& U1, GeomAbs_Shape Geom_OffsetSurface::Continuity () const { GeomAbs_Shape OffsetShape=GeomAbs_C0; - switch (basisSurf->Continuity()) { - case GeomAbs_C0 : OffsetShape = GeomAbs_C0; break; - case GeomAbs_G1 : OffsetShape = GeomAbs_C0; break; - case GeomAbs_C1 : OffsetShape = GeomAbs_C0; break; - case GeomAbs_G2 : OffsetShape = GeomAbs_C0; break; - case GeomAbs_C2 : OffsetShape = GeomAbs_C1; break; - case GeomAbs_C3 : OffsetShape = GeomAbs_C2; break; - case GeomAbs_CN : OffsetShape = GeomAbs_CN; break; + switch (myBasisSurfContinuity) { + case GeomAbs_C0 : OffsetShape = GeomAbs_C0; break; + case GeomAbs_G1 : OffsetShape = GeomAbs_C0; break; + case GeomAbs_C1 : OffsetShape = GeomAbs_C0; break; + case GeomAbs_G2 : OffsetShape = GeomAbs_C0; break; + case GeomAbs_C2 : OffsetShape = GeomAbs_C1; break; + case GeomAbs_C3 : OffsetShape = GeomAbs_C2; break; + case GeomAbs_CN : OffsetShape = GeomAbs_CN; break; } return OffsetShape; } @@ -406,7 +479,7 @@ void Geom_OffsetSurface::D0 (const Standard_Real U, const Standard_Real V, Pnt& Vec D1U, D1V; #ifdef CHECK - if (basisSurf->Continuity() == GeomAbs_C0) Geom_UndefinedValue::Raise(); + if (myBasisSurfContinuity == GeomAbs_C0) Geom_UndefinedValue::Raise(); #endif if (equivSurf.IsNull()){ basisSurf->D1(U, V, P, D1U, D1V); @@ -422,14 +495,14 @@ void Geom_OffsetSurface::D0 (const Standard_Real U, const Standard_Real V, Pnt& //======================================================================= void Geom_OffsetSurface::D1 (const Standard_Real U, const Standard_Real V, - Pnt& P, - Vec& D1U, Vec& D1V) const + Pnt& P, + Vec& D1U, Vec& D1V) const { #ifdef CHECK - if (basisSurf->Continuity()==GeomAbs_C0 || - basisSurf->Continuity()==GeomAbs_C1) { - Geom_UndefinedDerivative::Raise(); + if (myBasisSurfContinuity==GeomAbs_C0 || + myBasisSurfContinuity==GeomAbs_C1) { + Geom_UndefinedDerivative::Raise(); } #endif if (equivSurf.IsNull()) @@ -451,24 +524,27 @@ void Geom_OffsetSurface::D1 (const Standard_Real U, const Standard_Real V, //======================================================================= void Geom_OffsetSurface::D2 (const Standard_Real U, const Standard_Real V, - Pnt& P, - Vec& D1U, Vec& D1V, - Vec& D2U, Vec& D2V, Vec& D2UV) const { - + Pnt& P, + Vec& D1U, Vec& D1V, + Vec& D2U, Vec& D2V, Vec& D2UV) const { + #ifdef CHECK - GeomAbs_Shape Continuity = basisSurf->Continuity(); - if (Continuity == GeomAbs_C0 || Continuity == GeomAbs_C1 || - Continuity == GeomAbs_C2) { Geom_UndefinedDerivative::Raise(); } + if (myBasisSurfContinuity == GeomAbs_C0 || + myBasisSurfContinuity == GeomAbs_C1 || + myBasisSurfContinuity == GeomAbs_C2) + { + Geom_UndefinedDerivative::Raise(); + } #endif - if (equivSurf.IsNull()) + if (equivSurf.IsNull()) { gp_Vec d3u, d3uuv, d3uvv, d3v; basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV, - d3u,d3v, d3uuv, d3uvv); - + d3u,d3v, d3uuv, d3uvv); + SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,d3u,d3v, d3uuv, d3uvv); } - else equivSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV); + else equivSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV); } @@ -478,26 +554,26 @@ void Geom_OffsetSurface::D2 (const Standard_Real U, const Standard_Real V, //======================================================================= void Geom_OffsetSurface::D3 (const Standard_Real U, const Standard_Real V, - Pnt& P, - Vec& D1U, Vec& D1V, - Vec& D2U, Vec& D2V, Vec& D2UV, - Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV) const { + Pnt& P, + Vec& D1U, Vec& D1V, + Vec& D2U, Vec& D2V, Vec& D2UV, + Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV) const { #ifdef CHECK - if (!(basisSurf->IsCNu (4) && basisSurf->IsCNv (4))) { - Geom_UndefinedDerivative::Raise(); + if (!(basisSurf->IsCNu (4) && basisSurf->IsCNv (4))) { + Geom_UndefinedDerivative::Raise(); } #endif - if (equivSurf.IsNull()) + if (equivSurf.IsNull()) { - + basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV, - D3U, D3V, D3UUV, D3UVV); + D3U, D3V, D3UUV, D3UVV); SetD3(U, V, P, D1U, D1V, D2U, D2V, D2UV, - D3U, D3V, D3UUV, D3UVV); + D3U, D3V, D3UUV, D3UVV); } - else equivSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); + else equivSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); } - + @@ -507,9 +583,9 @@ void Geom_OffsetSurface::D3 (const Standard_Real U, const Standard_Real V, //======================================================================= Vec Geom_OffsetSurface::DN ( const Standard_Real U , const Standard_Real V, - const Standard_Integer Nu, const Standard_Integer Nv) const + const Standard_Integer Nu, const Standard_Integer Nv) const { - + Standard_RangeError_Raise_if (Nu < 0 || Nv < 0 || Nu + Nv < 1, " "); #ifdef CHECK if (!(basisSurf->IsCNu (Nu) && basisSurf->IsCNv (Nv))) { @@ -520,12 +596,12 @@ Vec Geom_OffsetSurface::DN ( const Standard_Real U , const Standard_Real V if (equivSurf.IsNull()) { - Pnt P; - Vec D1U,D1V; - basisSurf->D1 (U, V, P, D1U, D1V); + Pnt P; + Vec D1U,D1V; + basisSurf->D1 (U, V, P, D1U, D1V); - D = SetDN(U,V,Nu,Nv,D1U,D1V); - } + D = SetDN(U,V,Nu,Nv,D1U,D1V); + } else D=equivSurf->DN(U,V,Nu,Nv); return D; } @@ -537,47 +613,47 @@ Vec Geom_OffsetSurface::DN ( const Standard_Real U , const Standard_Real V void Geom_OffsetSurface::D1 (const Standard_Real U, const Standard_Real V, - Pnt& P, Pnt& Pbasis, - Vec& D1U, Vec& D1V, Vec& D1Ubasis , Vec& D1Vbasis, - Vec& D2Ubasis, Vec& D2Vbasis, Vec& D2UVbasis) const { + Pnt& P, Pnt& Pbasis, + Vec& D1U, Vec& D1V, Vec& D1Ubasis , Vec& D1Vbasis, + Vec& D2Ubasis, Vec& D2Vbasis, Vec& D2UVbasis) const { - if (basisSurf->Continuity() == GeomAbs_C0 || - basisSurf->Continuity() == GeomAbs_C1) { - Geom_UndefinedDerivative::Raise(); - } - basisSurf->D2 (U, V, Pbasis, D1Ubasis, D1Vbasis, D2Ubasis, D2Vbasis, - D2UVbasis); - Vec Ndir = D1Ubasis.Crossed (D1Vbasis); - Standard_Real R2 = Ndir.SquareMagnitude(); - Standard_Real R = Sqrt (R2); - Standard_Real R3 = R * R2; - Vec DUNdir = D2Ubasis.Crossed (D1Vbasis); - DUNdir.Add (D1Ubasis.Crossed (D2UVbasis)); - Vec DVNdir = D2UVbasis.Crossed (D1Vbasis); - DVNdir.Add (D1Ubasis.Crossed (D2Vbasis)); - Standard_Real DRu = Ndir.Dot (DUNdir); - Standard_Real DRv = Ndir.Dot (DVNdir); - if (R3 <= gp::Resolution()) { - if (R2 <= gp::Resolution()) Geom_UndefinedDerivative::Raise(); - DUNdir.Multiply(R); - DUNdir.Subtract (Ndir.Multiplied (DRu/R)); - DUNdir.Multiply (offsetValue/R2); - D1U = D1Ubasis.Added (DUNdir); - DVNdir.Multiply(R); - DVNdir.Subtract (Ndir.Multiplied (DRv/R)); - DVNdir.Multiply (offsetValue/R2); - D1V = D1Vbasis.Added (DVNdir); - } - else { - DUNdir.Multiply (offsetValue / R); - DUNdir.Subtract (Ndir.Multiplied (offsetValue*DRu/R3)); - D1U = D1Ubasis.Added (DUNdir); - DVNdir.Multiply (offsetValue / R); - DVNdir.Subtract (Ndir.Multiplied (offsetValue*DRv/R3)); - D1V = D1Vbasis.Added (DVNdir); - } - Ndir.Multiply (offsetValue/R); - P.SetXYZ ((Ndir.XYZ()).Added (Pbasis.XYZ())); + if (basisSurf->Continuity() == GeomAbs_C0 || + basisSurf->Continuity() == GeomAbs_C1) { + Geom_UndefinedDerivative::Raise(); + } + basisSurf->D2 (U, V, Pbasis, D1Ubasis, D1Vbasis, D2Ubasis, D2Vbasis, + D2UVbasis); + Vec Ndir = D1Ubasis.Crossed (D1Vbasis); + Standard_Real R2 = Ndir.SquareMagnitude(); + Standard_Real R = Sqrt (R2); + Standard_Real R3 = R * R2; + Vec DUNdir = D2Ubasis.Crossed (D1Vbasis); + DUNdir.Add (D1Ubasis.Crossed (D2UVbasis)); + Vec DVNdir = D2UVbasis.Crossed (D1Vbasis); + DVNdir.Add (D1Ubasis.Crossed (D2Vbasis)); + Standard_Real DRu = Ndir.Dot (DUNdir); + Standard_Real DRv = Ndir.Dot (DVNdir); + if (R3 <= gp::Resolution()) { + if (R2 <= gp::Resolution()) Geom_UndefinedDerivative::Raise(); + DUNdir.Multiply(R); + DUNdir.Subtract (Ndir.Multiplied (DRu/R)); + DUNdir.Multiply (offsetValue/R2); + D1U = D1Ubasis.Added (DUNdir); + DVNdir.Multiply(R); + DVNdir.Subtract (Ndir.Multiplied (DRv/R)); + DVNdir.Multiply (offsetValue/R2); + D1V = D1Vbasis.Added (DVNdir); + } + else { + DUNdir.Multiply (offsetValue / R); + DUNdir.Subtract (Ndir.Multiplied (offsetValue*DRu/R3)); + D1U = D1Ubasis.Added (DUNdir); + DVNdir.Multiply (offsetValue / R); + DVNdir.Subtract (Ndir.Multiplied (offsetValue*DRv/R3)); + D1V = D1Vbasis.Added (DVNdir); + } + Ndir.Multiply (offsetValue/R); + P.SetXYZ ((Ndir.XYZ()).Added (Pbasis.XYZ())); } @@ -589,106 +665,106 @@ void Geom_OffsetSurface::D1 void Geom_OffsetSurface::D2 (const Standard_Real U, const Standard_Real V, - Pnt& P, Pnt& Pbasis, - Vec& D1U, Vec& D1V, Vec& D2U, Vec& D2V, Vec& D2UV, - Vec& D1Ubasis, Vec& D1Vbasis, - Vec& D2Ubasis, Vec& D2Vbasis, Vec& D2UVbasis, - Vec& D3Ubasis, Vec& D3Vbasis, Vec& D3UUVbasis, Vec& D3UVVbasis) const { + Pnt& P, Pnt& Pbasis, + Vec& D1U, Vec& D1V, Vec& D2U, Vec& D2V, Vec& D2UV, + Vec& D1Ubasis, Vec& D1Vbasis, + Vec& D2Ubasis, Vec& D2Vbasis, Vec& D2UVbasis, + Vec& D3Ubasis, Vec& D3Vbasis, Vec& D3UUVbasis, Vec& D3UVVbasis) const { - GeomAbs_Shape Continuity = basisSurf->Continuity(); - if (Continuity == GeomAbs_C0 || Continuity == GeomAbs_C1 || - Continuity == GeomAbs_C2) { Geom_UndefinedDerivative::Raise(); } -// Vec D3U, D3V, D3UVV, D3UUV; - basisSurf->D3 (U, V, P, D1Ubasis, D1Vbasis, D2Ubasis, D2Vbasis, D2UVbasis, - D3Ubasis, D3Vbasis, D3UUVbasis, D3UVVbasis); - Vec Ndir = D1Ubasis.Crossed (D1Vbasis); - Standard_Real R2 = Ndir.SquareMagnitude(); - Standard_Real R = Sqrt (R2); - Standard_Real R3 = R2 * R; - Standard_Real R4 = R2 * R2; - Standard_Real R5 = R3 * R2; - Vec DUNdir = D2Ubasis.Crossed (D1Vbasis); - DUNdir.Add (D1Ubasis.Crossed (D2UVbasis)); - Vec DVNdir = D2UVbasis.Crossed (D1Vbasis); - DVNdir.Add (D1Ubasis.Crossed (D2Vbasis)); - Standard_Real DRu = Ndir.Dot (DUNdir); - Standard_Real DRv = Ndir.Dot (DVNdir); - Vec D2UNdir = D3Ubasis.Crossed (D1Vbasis); - D2UNdir.Add (D1Ubasis.Crossed (D3UUVbasis)); - D2UNdir.Add (2.0 * (D2Ubasis.Crossed (D2UVbasis))); - Vec D2VNdir = D3UVVbasis.Crossed (D1Vbasis); - D2VNdir.Add (D1Ubasis.Crossed (D3Vbasis)); - D2VNdir.Add (2.0 * (D2UVbasis.Crossed (D2Vbasis))); - Vec D2UVNdir = D2UVbasis.Crossed (D1Vbasis); - D2UVNdir.Add (D1Ubasis.Crossed (D3UVVbasis)); - D2UVNdir.Add (D2Ubasis.Crossed (D2Vbasis)); - Standard_Real D2Ru = Ndir.Dot (D2UNdir) + DUNdir.Dot (DUNdir); - Standard_Real D2Rv = Ndir.Dot (D2VNdir) + DVNdir.Dot (DVNdir); - Standard_Real D2Ruv = DVNdir.Dot (DUNdir) + Ndir.Dot (D2UVNdir); + GeomAbs_Shape Continuity = basisSurf->Continuity(); + if (Continuity == GeomAbs_C0 || Continuity == GeomAbs_C1 || + Continuity == GeomAbs_C2) { Geom_UndefinedDerivative::Raise(); } + // Vec D3U, D3V, D3UVV, D3UUV; + basisSurf->D3 (U, V, P, D1Ubasis, D1Vbasis, D2Ubasis, D2Vbasis, D2UVbasis, + D3Ubasis, D3Vbasis, D3UUVbasis, D3UVVbasis); + Vec Ndir = D1Ubasis.Crossed (D1Vbasis); + Standard_Real R2 = Ndir.SquareMagnitude(); + Standard_Real R = Sqrt (R2); + Standard_Real R3 = R2 * R; + Standard_Real R4 = R2 * R2; + Standard_Real R5 = R3 * R2; + Vec DUNdir = D2Ubasis.Crossed (D1Vbasis); + DUNdir.Add (D1Ubasis.Crossed (D2UVbasis)); + Vec DVNdir = D2UVbasis.Crossed (D1Vbasis); + DVNdir.Add (D1Ubasis.Crossed (D2Vbasis)); + Standard_Real DRu = Ndir.Dot (DUNdir); + Standard_Real DRv = Ndir.Dot (DVNdir); + Vec D2UNdir = D3Ubasis.Crossed (D1Vbasis); + D2UNdir.Add (D1Ubasis.Crossed (D3UUVbasis)); + D2UNdir.Add (2.0 * (D2Ubasis.Crossed (D2UVbasis))); + Vec D2VNdir = D3UVVbasis.Crossed (D1Vbasis); + D2VNdir.Add (D1Ubasis.Crossed (D3Vbasis)); + D2VNdir.Add (2.0 * (D2UVbasis.Crossed (D2Vbasis))); + Vec D2UVNdir = D2UVbasis.Crossed (D1Vbasis); + D2UVNdir.Add (D1Ubasis.Crossed (D3UVVbasis)); + D2UVNdir.Add (D2Ubasis.Crossed (D2Vbasis)); + Standard_Real D2Ru = Ndir.Dot (D2UNdir) + DUNdir.Dot (DUNdir); + Standard_Real D2Rv = Ndir.Dot (D2VNdir) + DVNdir.Dot (DVNdir); + Standard_Real D2Ruv = DVNdir.Dot (DUNdir) + Ndir.Dot (D2UVNdir); - if (R5 <= gp::Resolution()) { - //We try another computation but the stability is not very good - //dixit ISG. - if (R4 <= gp::Resolution()) Geom_UndefinedDerivative::Raise(); - // V2 = P" (U) : - // Standard_Real R4 = R2 * R2; - D2UNdir.Subtract (DUNdir.Multiplied (2.0 * DRu / R2)); - D2UNdir.Subtract (Ndir.Multiplied (D2Ru/R2)); - D2UNdir.Add (Ndir.Multiplied (3.0 * DRu * DRu / R4)); - D2UNdir.Multiply (offsetValue / R); - D2U = D2Ubasis.Added (D2UNdir); - D2VNdir.Subtract (DVNdir.Multiplied (2.0 * DRv / R2)); - D2VNdir.Subtract (Ndir.Multiplied (D2Rv/R2)); - D2VNdir.Add (Ndir.Multiplied (3.0 * DRv * DRv / R4)); - D2VNdir.Multiply (offsetValue / R); - D2V = D2Vbasis.Added (D2VNdir); + if (R5 <= gp::Resolution()) { + //We try another computation but the stability is not very good + //dixit ISG. + if (R4 <= gp::Resolution()) Geom_UndefinedDerivative::Raise(); + // V2 = P" (U) : + // Standard_Real R4 = R2 * R2; + D2UNdir.Subtract (DUNdir.Multiplied (2.0 * DRu / R2)); + D2UNdir.Subtract (Ndir.Multiplied (D2Ru/R2)); + D2UNdir.Add (Ndir.Multiplied (3.0 * DRu * DRu / R4)); + D2UNdir.Multiply (offsetValue / R); + D2U = D2Ubasis.Added (D2UNdir); + D2VNdir.Subtract (DVNdir.Multiplied (2.0 * DRv / R2)); + D2VNdir.Subtract (Ndir.Multiplied (D2Rv/R2)); + D2VNdir.Add (Ndir.Multiplied (3.0 * DRv * DRv / R4)); + D2VNdir.Multiply (offsetValue / R); + D2V = D2Vbasis.Added (D2VNdir); - D2UVNdir.Subtract (DUNdir.Multiplied (DRv / R2)); - D2UVNdir.Subtract (DVNdir.Multiplied (DRu / R2)); - D2UVNdir.Subtract (Ndir.Multiplied (D2Ruv / R2)); - D2UVNdir.Add (Ndir.Multiplied (3.0 * DRu * DRv / R4)); - D2UVNdir.Multiply (offsetValue / R); - D2UV = D2UVbasis.Added (D2UVNdir); + D2UVNdir.Subtract (DUNdir.Multiplied (DRv / R2)); + D2UVNdir.Subtract (DVNdir.Multiplied (DRu / R2)); + D2UVNdir.Subtract (Ndir.Multiplied (D2Ruv / R2)); + D2UVNdir.Add (Ndir.Multiplied (3.0 * DRu * DRv / R4)); + D2UVNdir.Multiply (offsetValue / R); + D2UV = D2UVbasis.Added (D2UVNdir); - DUNdir.Multiply(R); - DUNdir.Subtract (Ndir.Multiplied (DRu/R)); - DUNdir.Multiply (offsetValue/R2); - D1U = D1Ubasis.Added (DUNdir); - DVNdir.Multiply(R); - DVNdir.Subtract (Ndir.Multiplied (DRv/R)); - DVNdir.Multiply (offsetValue/R2); - D1V = D1Vbasis.Added (DVNdir); - } - else { - D2UNdir.Multiply (offsetValue/R); - D2UNdir.Subtract (DUNdir.Multiplied (2.0 * offsetValue * DRu / R3)); - D2UNdir.Subtract (Ndir.Multiplied (offsetValue * D2Ru / R3)); - D2UNdir.Add (Ndir.Multiplied (offsetValue * 3.0 * DRu * DRu / R5)); - D2U = D2Ubasis.Added (D2UNdir); + DUNdir.Multiply(R); + DUNdir.Subtract (Ndir.Multiplied (DRu/R)); + DUNdir.Multiply (offsetValue/R2); + D1U = D1Ubasis.Added (DUNdir); + DVNdir.Multiply(R); + DVNdir.Subtract (Ndir.Multiplied (DRv/R)); + DVNdir.Multiply (offsetValue/R2); + D1V = D1Vbasis.Added (DVNdir); + } + else { + D2UNdir.Multiply (offsetValue/R); + D2UNdir.Subtract (DUNdir.Multiplied (2.0 * offsetValue * DRu / R3)); + D2UNdir.Subtract (Ndir.Multiplied (offsetValue * D2Ru / R3)); + D2UNdir.Add (Ndir.Multiplied (offsetValue * 3.0 * DRu * DRu / R5)); + D2U = D2Ubasis.Added (D2UNdir); - D2VNdir.Multiply (offsetValue/R); - D2VNdir.Subtract (DVNdir.Multiplied (2.0 * offsetValue * DRv / R3)); - D2VNdir.Subtract (Ndir.Multiplied (offsetValue * D2Rv / R3)); - D2VNdir.Add (Ndir.Multiplied (offsetValue * 3.0 * DRv * DRv / R5)); - D2V = D2Vbasis.Added (D2VNdir); + D2VNdir.Multiply (offsetValue/R); + D2VNdir.Subtract (DVNdir.Multiplied (2.0 * offsetValue * DRv / R3)); + D2VNdir.Subtract (Ndir.Multiplied (offsetValue * D2Rv / R3)); + D2VNdir.Add (Ndir.Multiplied (offsetValue * 3.0 * DRv * DRv / R5)); + D2V = D2Vbasis.Added (D2VNdir); - D2UVNdir.Multiply (offsetValue/R); - D2UVNdir.Subtract (DUNdir.Multiplied (offsetValue * DRv / R3)); - D2UVNdir.Subtract (DVNdir.Multiplied (offsetValue * DRu / R3)); - D2UVNdir.Subtract (Ndir.Multiplied (offsetValue * D2Ruv / R3)); - D2UVNdir.Add (Ndir.Multiplied (3.0 * offsetValue * DRu * DRv / R5)); - D2UV = D2UVbasis.Added (D2UVNdir); + D2UVNdir.Multiply (offsetValue/R); + D2UVNdir.Subtract (DUNdir.Multiplied (offsetValue * DRv / R3)); + D2UVNdir.Subtract (DVNdir.Multiplied (offsetValue * DRu / R3)); + D2UVNdir.Subtract (Ndir.Multiplied (offsetValue * D2Ruv / R3)); + D2UVNdir.Add (Ndir.Multiplied (3.0 * offsetValue * DRu * DRv / R5)); + D2UV = D2UVbasis.Added (D2UVNdir); - DUNdir.Multiply (offsetValue / R); - DUNdir.Subtract (Ndir.Multiplied (offsetValue*DRu/R3)); - D1U = D1Ubasis.Added (DUNdir); - DVNdir.Multiply (offsetValue / R); - DVNdir.Subtract (Ndir.Multiplied (offsetValue*DRv/R3)); - D1V = D1Vbasis.Added (DVNdir); - } - Ndir.Multiply (offsetValue/R); - P.SetXYZ ((Ndir.XYZ()).Added (Pbasis.XYZ())); + DUNdir.Multiply (offsetValue / R); + DUNdir.Subtract (Ndir.Multiplied (offsetValue*DRu/R3)); + D1U = D1Ubasis.Added (DUNdir); + DVNdir.Multiply (offsetValue / R); + DVNdir.Subtract (Ndir.Multiplied (offsetValue*DRv/R3)); + D1V = D1Vbasis.Added (DVNdir); + } + Ndir.Multiply (offsetValue/R); + P.SetXYZ ((Ndir.XYZ()).Added (Pbasis.XYZ())); } @@ -709,10 +785,10 @@ Standard_Real Geom_OffsetSurface::Offset () const { //======================================================================= void Geom_OffsetSurface::LocalD0 (const Standard_Real U, - const Standard_Real V, - const Standard_Integer USide, - const Standard_Integer VSide, - gp_Pnt& P ) const + const Standard_Real V, + const Standard_Integer USide, + const Standard_Integer VSide, + gp_Pnt& P ) const { if (equivSurf.IsNull()) { Vec D1U, D1V; @@ -724,14 +800,14 @@ void Geom_OffsetSurface::LocalD0 (const Standard_Real U, if (!RTS.IsNull()) { Basis = RTS->BasisSurface(); } - + // BSpline case Handle(Geom_BSplineSurface) BSplS; BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis); if (!BSplS.IsNull()) { Vec D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV; LocateSides(U,V,USide,VSide,BSplS,1,P,D1U,D1V,D2U,D2V,D2UV, - D3U,D3V,D3UUV,D3UVV); + D3U,D3V,D3UUV,D3UVV); SetD0(U,V,P,D1U,D1V); return; } @@ -754,7 +830,7 @@ void Geom_OffsetSurface::LocalD0 (const Standard_Real U, SetD0(U,V, P, D1U,D1V); return; } - + // General cases basisSurf->D1(U, V, P, D1U, D1V); SetD0(U,V, P, D1U,D1V); @@ -769,12 +845,12 @@ void Geom_OffsetSurface::LocalD0 (const Standard_Real U, //======================================================================= void Geom_OffsetSurface::LocalD1 (const Standard_Real U, - const Standard_Real V, - const Standard_Integer USide, - const Standard_Integer VSide, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const + const Standard_Real V, + const Standard_Integer USide, + const Standard_Integer VSide, + gp_Pnt& P, + gp_Vec& D1U, + gp_Vec& D1V) const { if (equivSurf.IsNull()) { Vec D2U,D2V,D2UV ; @@ -786,14 +862,14 @@ void Geom_OffsetSurface::LocalD1 (const Standard_Real U, if (!RTS.IsNull()) { Basis = RTS->BasisSurface(); } - + // BSpline case Handle(Geom_BSplineSurface) BSplS; BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis); if (!BSplS.IsNull()) { Vec D3U,D3V,D3UUV,D3UVV; LocateSides(U,V,USide,VSide,BSplS,2,P,D1U,D1V,D2U,D2V,D2UV, - D3U,D3V,D3UUV,D3UVV); + D3U,D3V,D3UUV,D3UVV); SetD1(U,V,P,D1U,D1V,D2U,D2V,D2UV); return; } @@ -816,7 +892,7 @@ void Geom_OffsetSurface::LocalD1 (const Standard_Real U, SetD1(U,V, P, D1U,D1V,D2U,D2V,D2UV); return; } - + // General cases basisSurf->D2(U, V, P, D1U, D1V,D2U,D2V,D2UV); SetD1(U,V, P, D1U,D1V,D2U,D2V,D2UV); @@ -831,15 +907,15 @@ void Geom_OffsetSurface::LocalD1 (const Standard_Real U, //======================================================================= void Geom_OffsetSurface::LocalD2 (const Standard_Real U, - const Standard_Real V, - const Standard_Integer USide, - const Standard_Integer VSide, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const + const Standard_Real V, + const Standard_Integer USide, + const Standard_Integer VSide, + gp_Pnt& P, + gp_Vec& D1U, + gp_Vec& D1V, + gp_Vec& D2U, + gp_Vec& D2V, + gp_Vec& D2UV) const { if (equivSurf.IsNull()) { Handle(Geom_Surface) Basis = basisSurf; @@ -851,13 +927,13 @@ void Geom_OffsetSurface::LocalD2 (const Standard_Real U, if (!RTS.IsNull()) { Basis = RTS->BasisSurface(); } - + // BSpline case Handle(Geom_BSplineSurface) BSplS; BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis); if (!BSplS.IsNull()) { LocateSides(U,V,USide,VSide,BSplS,3,P,D1U,D1V,D2U,D2V,D2UV, - D3U,D3V,D3UUV,D3UVV); + D3U,D3V,D3UUV,D3UVV); SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); return; } @@ -868,8 +944,8 @@ void Geom_OffsetSurface::LocalD2 (const Standard_Real U, if (!SE.IsNull()) { SE->LocalD3(U,V,USide,P,D1U,D1V, - D2U,D2V,D2UV, - D3U,D3V,D3UUV,D3UVV); + D2U,D2V,D2UV, + D3U,D3V,D3UUV,D3UVV); SetD2(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); return; } @@ -882,7 +958,7 @@ void Geom_OffsetSurface::LocalD2 (const Standard_Real U, SetD2(U,V, P, D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV); return; } - + // General cases basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV,D3U, D3V, D3UUV, D3UVV); SetD2(U,V, P, D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV); @@ -896,19 +972,19 @@ void Geom_OffsetSurface::LocalD2 (const Standard_Real U, //======================================================================= void Geom_OffsetSurface::LocalD3 (const Standard_Real U, - const Standard_Real V, - const Standard_Integer USide, - const Standard_Integer VSide, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const + const Standard_Real V, + const Standard_Integer USide, + const Standard_Integer VSide, + gp_Pnt& P, + gp_Vec& D1U, + gp_Vec& D1V, + gp_Vec& D2U, + gp_Vec& D2V, + gp_Vec& D2UV, + gp_Vec& D3U, + gp_Vec& D3V, + gp_Vec& D3UUV, + gp_Vec& D3UVV) const { if (equivSurf.IsNull()) { Handle(Geom_Surface) Basis = basisSurf; @@ -919,13 +995,13 @@ void Geom_OffsetSurface::LocalD3 (const Standard_Real U, if (!RTS.IsNull()) { Basis = RTS->BasisSurface(); } - + // BSpline case Handle(Geom_BSplineSurface) BSplS; BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis); if (!BSplS.IsNull()) { LocateSides(U,V,USide,VSide,BSplS,3,P,D1U,D1V,D2U,D2V,D2UV, - D3U,D3V,D3UUV,D3UVV); + D3U,D3V,D3UUV,D3UVV); SetD3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); return; } @@ -936,8 +1012,8 @@ void Geom_OffsetSurface::LocalD3 (const Standard_Real U, if (!SE.IsNull()) { SE->LocalD3(U,V,USide,P,D1U,D1V, - D2U,D2V,D2UV, - D3U,D3V,D3UUV,D3UVV); + D2U,D2V,D2UV, + D3U,D3V,D3UUV,D3UVV); SetD3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); return; } @@ -950,7 +1026,7 @@ void Geom_OffsetSurface::LocalD3 (const Standard_Real U, SetD3(U,V, P, D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV); return; } - + // General cases basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV,D3U, D3V, D3UUV, D3UVV); SetD3(U,V, P, D1U,D1V, D2U,D2V,D2UV, D3U,D3V,D3UUV,D3UVV); @@ -965,57 +1041,57 @@ void Geom_OffsetSurface::LocalD3 (const Standard_Real U, //======================================================================= gp_Vec Geom_OffsetSurface::LocalDN (const Standard_Real U, - const Standard_Real V, - const Standard_Integer USide, - const Standard_Integer VSide, - const Standard_Integer Nu, - const Standard_Integer Nv) const + const Standard_Real V, + const Standard_Integer USide, + const Standard_Integer VSide, + const Standard_Integer Nu, + const Standard_Integer Nv) const { gp_Vec D(0,0,0); - + if(equivSurf.IsNull()) { Vec D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV; Pnt P; Handle(Geom_Surface) Basis = basisSurf; - + // if Basis is Trimmed we make the basis`s basis Handle(Geom_RectangularTrimmedSurface) RTS; RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(Basis); - + if (!RTS.IsNull()) { Basis = RTS -> BasisSurface(); } - + //BSpline case Handle(Geom_BSplineSurface) BSplS; BSplS = Handle(Geom_BSplineSurface)::DownCast(Basis); - + if(!BSplS.IsNull()) { LocateSides(U,V,USide,VSide,BSplS,1,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); return D = SetDN(U,V,Nu,Nv,D1U,D1V); } - + //Extrusion case Handle( Geom_SurfaceOfLinearExtrusion) SE; SE = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Basis); - + if(!SE.IsNull()) { - + SE->LocalD1(U,V,USide,P,D1U,D1V); D = SetDN(U,V,Nu,Nv,D1U,D1V); return D; } - + //Revolution case Handle(Geom_SurfaceOfRevolution) SR; SR = Handle(Geom_SurfaceOfRevolution)::DownCast(Basis); - + if(!SR.IsNull()) { D = SR->LocalDN(U,V,VSide,Nu,Nv); return D = SetDN(U,V,Nu,Nv,D1U,D1V); } - + //General cases D = basisSurf->DN(U,V,Nu,Nv); return D = SetDN(U,V,Nu,Nv,D1U,D1V); @@ -1029,22 +1105,22 @@ gp_Vec Geom_OffsetSurface::LocalDN (const Standard_Real U, //purpose : //======================================================================= void Geom_OffsetSurface::LocateSides(const Standard_Real U, - const Standard_Real V, - const Standard_Integer USide, - const Standard_Integer VSide, - const Handle(Geom_BSplineSurface)& BSplS, - const Standard_Integer NDir, - gp_Pnt& P, - gp_Vec& D1U,gp_Vec& D1V, - gp_Vec& D2U,gp_Vec& D2V,gp_Vec& D2UV, - gp_Vec& D3U,gp_Vec& D3V,gp_Vec& D3UUV,gp_Vec& D3UVV ) const + const Standard_Real V, + const Standard_Integer USide, + const Standard_Integer VSide, + const Handle(Geom_BSplineSurface)& BSplS, + const Standard_Integer NDir, + gp_Pnt& P, + gp_Vec& D1U,gp_Vec& D1V, + gp_Vec& D2U,gp_Vec& D2V,gp_Vec& D2UV, + gp_Vec& D3U,gp_Vec& D3V,gp_Vec& D3UUV,gp_Vec& D3UVV ) const { Standard_Boolean UIsKnot=Standard_False, VIsKnot=Standard_False ; Standard_Integer Ideb, Ifin, IVdeb, IVfin; Standard_Real ParTol=Precision::PConfusion()/10.; BSplS->Geom_BSplineSurface::LocateU(U,ParTol,Ideb, Ifin, Standard_False); BSplS->Geom_BSplineSurface::LocateV(V,ParTol,IVdeb,IVfin,Standard_False); - + if(Ideb == Ifin ) { //knot if(USide == 1) {Ifin++; UIsKnot=Standard_True;} @@ -1074,21 +1150,21 @@ void Geom_OffsetSurface::LocateSides(const Standard_Real U, if(IVfin > BSplS->LastVKnotIndex()) {IVfin = BSplS->LastVKnotIndex(); IVdeb = IVfin - 1;} - + if((UIsKnot)||(VIsKnot)) switch(NDir) - { - case 0 : BSplS->Geom_BSplineSurface::LocalD0(U,V,Ideb,Ifin,IVdeb,IVfin,P); break; - case 1 : BSplS->Geom_BSplineSurface::LocalD1(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V); break; - case 2 : BSplS->Geom_BSplineSurface::LocalD2(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V,D2U,D2V,D2UV); break; - case 3 : BSplS->Geom_BSplineSurface::LocalD3(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); break; - }else switch(NDir) - { - case 0 : basisSurf->D0(U,V,P); break; - case 1 : basisSurf->D1(U,V,P,D1U,D1V); break; - case 2 : basisSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV); break; - case 3 : basisSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); break; - } + { + case 0 : BSplS->Geom_BSplineSurface::LocalD0(U,V,Ideb,Ifin,IVdeb,IVfin,P); break; + case 1 : BSplS->Geom_BSplineSurface::LocalD1(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V); break; + case 2 : BSplS->Geom_BSplineSurface::LocalD2(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V,D2U,D2V,D2UV); break; + case 3 : BSplS->Geom_BSplineSurface::LocalD3(U,V,Ideb,Ifin,IVdeb,IVfin,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); break; + }else switch(NDir) + { + case 0 : basisSurf->D0(U,V,P); break; + case 1 : basisSurf->D1(U,V,P,D1U,D1V); break; + case 2 : basisSurf->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV); break; + case 3 : basisSurf->D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); break; + } } @@ -1100,29 +1176,29 @@ void Geom_OffsetSurface::LocateSides(const Standard_Real U, class Geom_OffsetSurface_UIsoEvaluator : public AdvApprox_EvaluatorFunction { - public: +public: Geom_OffsetSurface_UIsoEvaluator (const Handle(Geom_Surface)& theSurface, - Standard_Real theU) - : CurrentSurface(theSurface), IsoPar(theU) {} - + Standard_Real theU) + : CurrentSurface(theSurface), IsoPar(theU) {} + virtual void Evaluate (Standard_Integer *Dimension, - Standard_Real StartEnd[2], - Standard_Real *Parameter, - Standard_Integer *DerivativeRequest, - Standard_Real *Result, // [Dimension] - Standard_Integer *ErrorCode); - - private: + Standard_Real StartEnd[2], + Standard_Real *Parameter, + Standard_Integer *DerivativeRequest, + Standard_Real *Result, // [Dimension] + Standard_Integer *ErrorCode); + +private: Handle(Geom_Surface) CurrentSurface; Standard_Real IsoPar; }; void Geom_OffsetSurface_UIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/ - Standard_Real /*StartEnd*/[2], - Standard_Real *Parameter, - Standard_Integer *DerivativeRequest, - Standard_Real *Result, - Standard_Integer *ReturnCode) + Standard_Real /*StartEnd*/[2], + Standard_Real *Parameter, + Standard_Integer *DerivativeRequest, + Standard_Real *Result, + Standard_Integer *ReturnCode) { gp_Pnt P; if (*DerivativeRequest == 0) { @@ -1141,29 +1217,29 @@ void Geom_OffsetSurface_UIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/ class Geom_OffsetSurface_VIsoEvaluator : public AdvApprox_EvaluatorFunction { - public: +public: Geom_OffsetSurface_VIsoEvaluator (const Handle(Geom_Surface)& theSurface, - Standard_Real theV) - : CurrentSurface(theSurface), IsoPar(theV) {} - + Standard_Real theV) + : CurrentSurface(theSurface), IsoPar(theV) {} + virtual void Evaluate (Standard_Integer *Dimension, - Standard_Real StartEnd[2], - Standard_Real *Parameter, - Standard_Integer *DerivativeRequest, - Standard_Real *Result, // [Dimension] - Standard_Integer *ErrorCode); - - private: + Standard_Real StartEnd[2], + Standard_Real *Parameter, + Standard_Integer *DerivativeRequest, + Standard_Real *Result, // [Dimension] + Standard_Integer *ErrorCode); + +private: Handle(Geom_Surface) CurrentSurface; Standard_Real IsoPar; }; void Geom_OffsetSurface_VIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/ - Standard_Real /*StartEnd*/[2], - Standard_Real *Parameter, - Standard_Integer *DerivativeRequest, - Standard_Real *Result, - Standard_Integer *ReturnCode) + Standard_Real /*StartEnd*/[2], + Standard_Real *Parameter, + Standard_Integer *DerivativeRequest, + Standard_Real *Result, + Standard_Integer *ReturnCode) { gp_Pnt P; if (*DerivativeRequest == 0) { @@ -1206,11 +1282,11 @@ Handle(Geom_Curve) Geom_OffsetSurface::UIso (const Standard_Real UU) const Geom_OffsetSurface_UIsoEvaluator ev (this, UU); AdvApprox_ApproxAFunction Approx(Num1, Num2, Num3, T1, T2, T3, - V1, V2, Cont, - MaxDeg,MaxSeg, ev); + V1, V2, Cont, + MaxDeg,MaxSeg, ev); Standard_ConstructionError_Raise_if (!Approx.IsDone(), - " Geom_OffsetSurface : UIso"); + " Geom_OffsetSurface : UIso"); Standard_Integer NbPoles = Approx.NbPoles(); @@ -1238,14 +1314,14 @@ Handle(Geom_Curve) Geom_OffsetSurface::UIso (const Standard_Real UU) const void Geom_OffsetSurface::Value ( const Standard_Real U, const Standard_Real V, -// Pnt& P, Pnt& Pbasis, - Pnt& P, Pnt& , - Vec& D1Ubasis, Vec& D1Vbasis) const { + // Pnt& P, Pnt& Pbasis, + Pnt& P, Pnt& , + Vec& D1Ubasis, Vec& D1Vbasis) const { - if (basisSurf->Continuity() == GeomAbs_C0) - Geom_UndefinedValue::Raise(); - - SetD0(U,V,P,D1Ubasis,D1Vbasis); + if (myBasisSurfContinuity == GeomAbs_C0) + Geom_UndefinedValue::Raise(); + + SetD0(U,V,P,D1Ubasis,D1Vbasis); } @@ -1273,10 +1349,10 @@ Handle(Geom_Curve) Geom_OffsetSurface::VIso (const Standard_Real VV) const Geom_OffsetSurface_VIsoEvaluator ev (this, VV); AdvApprox_ApproxAFunction Approx (Num1, Num2, Num3, T1, T2, T3, - U1, U2, Cont, MaxDeg, MaxSeg, ev); + U1, U2, Cont, MaxDeg, MaxSeg, ev); Standard_ConstructionError_Raise_if (!Approx.IsDone(), - " Geom_OffsetSurface : VIso"); + " Geom_OffsetSurface : VIso"); TColgp_Array1OfPnt Poles( 1, Approx.NbPoles()); TColStd_Array1OfReal Knots( 1, Approx.NbKnots()); @@ -1302,8 +1378,8 @@ Handle(Geom_Curve) Geom_OffsetSurface::VIso (const Standard_Real VV) const Standard_Boolean Geom_OffsetSurface::IsCNu (const Standard_Integer N) const { - Standard_RangeError_Raise_if (N < 0, " "); - return basisSurf->IsCNu (N+1); + Standard_RangeError_Raise_if (N < 0, " "); + return basisSurf->IsCNu (N+1); } @@ -1383,7 +1459,7 @@ Standard_Boolean Geom_OffsetSurface::IsUClosed () const { } else if (S->IsKind (STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) { Handle(Geom_SurfaceOfLinearExtrusion) Extru = - Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S); + Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S); Handle(Curve) C = Extru->BasisCurve(); if (C->IsKind (STANDARD_TYPE(Geom_Circle)) || C->IsKind (STANDARD_TYPE(Geom_Ellipse))) { @@ -1402,7 +1478,7 @@ Standard_Boolean Geom_OffsetSurface::IsUClosed () const { } else if (SBasis->IsKind (STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) { Handle(Geom_SurfaceOfLinearExtrusion) Extru = - Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(SBasis); + Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(SBasis); Handle(Curve) C = Extru->BasisCurve(); UClosed = (C->IsKind(STANDARD_TYPE(Geom_Circle)) || C->IsKind(STANDARD_TYPE(Geom_Ellipse))); @@ -1453,9 +1529,9 @@ Standard_Boolean Geom_OffsetSurface::IsVClosed () const { void Geom_OffsetSurface::Transform (const Trsf& T) { - basisSurf->Transform (T); - offsetValue *= T.ScaleFactor(); - equivSurf.Nullify(); + basisSurf->Transform (T); + offsetValue *= T.ScaleFactor(); + equivSurf.Nullify(); } //======================================================================= @@ -1464,9 +1540,9 @@ void Geom_OffsetSurface::Transform (const Trsf& T) //======================================================================= void Geom_OffsetSurface::TransformParameters(Standard_Real& U, - Standard_Real& V, - const gp_Trsf& T) -const + Standard_Real& V, + const gp_Trsf& T) + const { basisSurf->TransformParameters(U,V,T); if(!equivSurf.IsNull()) equivSurf->TransformParameters(U,V,T); @@ -1478,7 +1554,7 @@ const //======================================================================= gp_GTrsf2d Geom_OffsetSurface::ParametricTransformation -(const gp_Trsf& T) const + (const gp_Trsf& T) const { return basisSurf->ParametricTransformation(T); } @@ -1508,13 +1584,13 @@ Handle(Geom_Surface) Geom_OffsetSurface::Surface() const S->Bounds(U1,U2,V1,V2); IsTrimmed = Standard_True; } - else { - IsTrimmed = Standard_False; - Base = basisSurf; - } + else { + IsTrimmed = Standard_False; + Base = basisSurf; + } // Traite les surfaces cannonique - if (TheType == STANDARD_TYPE(Geom_Plane)) + if (TheType == STANDARD_TYPE(Geom_Plane)) { Handle(Geom_Plane) P = Handle(Geom_Plane)::DownCast(Base); @@ -1542,7 +1618,7 @@ Handle(Geom_Surface) Geom_OffsetSurface::Surface() const } else { -// surface degeneree + // surface degeneree } } else if (TheType == STANDARD_TYPE(Geom_ConicalSurface)) @@ -1560,7 +1636,7 @@ Handle(Geom_Surface) Geom_OffsetSurface::Surface() const } else { -// surface degeneree + // surface degeneree } } else if (TheType == STANDARD_TYPE(Geom_SphericalSurface)) { @@ -1582,7 +1658,7 @@ Handle(Geom_Surface) Geom_OffsetSurface::Surface() const Result->UReverse(); } else { -// surface degeneree + // surface degeneree } } else if (TheType == STANDARD_TYPE(Geom_ToroidalSurface)) @@ -1596,16 +1672,16 @@ Handle(Geom_Surface) Geom_OffsetSurface::Surface() const if (MinorRadius <= MajorRadius) { if (Axis.Direct()) - MinorRadius += offsetValue; + MinorRadius += offsetValue; else - MinorRadius -= offsetValue; + MinorRadius -= offsetValue; if (MinorRadius >= Tol) - Result = new Geom_ToroidalSurface(Axis,MajorRadius,MinorRadius); -// else if (MinorRadius <= -Tol) -// Result->UReverse(); + Result = new Geom_ToroidalSurface(Axis,MajorRadius,MinorRadius); + // else if (MinorRadius <= -Tol) + // Result->UReverse(); else { -// surface degeneree + // surface degeneree } } } @@ -1620,17 +1696,17 @@ Handle(Geom_Surface) Geom_OffsetSurface::Surface() const } Standard_Boolean Geom_OffsetSurface::UOsculatingSurface(const Standard_Real U, - const Standard_Real V, - Standard_Boolean& t, - Handle(Geom_BSplineSurface)& L) const + const Standard_Real V, + Standard_Boolean& t, + Handle(Geom_BSplineSurface)& L) const { return myOscSurf.UOscSurf(U,V,t,L); } Standard_Boolean Geom_OffsetSurface::VOsculatingSurface(const Standard_Real U, - const Standard_Real V, - Standard_Boolean& t, - Handle(Geom_BSplineSurface)& L) const + const Standard_Real V, + Standard_Boolean& t, + Handle(Geom_BSplineSurface)& L) const { return myOscSurf.VOscSurf(U,V,t,L); } @@ -1641,11 +1717,11 @@ Standard_Boolean Geom_OffsetSurface::VOsculatingSurface(const Standard_Real U, //purpose : private //======================================================================= void Geom_OffsetSurface::SetD0(const Standard_Real U, const Standard_Real V, - Pnt& P, - const Vec& D1U, const Vec& D1V)const + Pnt& P, + const Vec& D1U, const Vec& D1V)const { Standard_Boolean AlongU = Standard_False, - AlongV = Standard_False; + AlongV = Standard_False; Handle(Geom_BSplineSurface) L; Standard_Boolean IsOpposite=Standard_False; Standard_Real signe = 1.; @@ -1659,28 +1735,28 @@ void Geom_OffsetSurface::SetD0(const Standard_Real U, const Standard_Real V, CSLib::Normal (D1U, D1V, MagTol, NStatus, Normal); if (NStatus == CSLib_Defined) // akm - only in singularities && !AlongU && !AlongV) - { - P.SetXYZ(P.XYZ() + offsetValue * Normal.XYZ()); - } + { + P.SetXYZ(P.XYZ() + offsetValue * Normal.XYZ()); + } else - { - Standard_Integer MaxOrder=3; - TColgp_Array2OfVec DerNUV(0,MaxOrder,0,MaxOrder); - TColgp_Array2OfVec DerSurf(0,MaxOrder+1,0,MaxOrder+1); - Standard_Integer OrderU,OrderV; - Standard_Real Umin,Umax,Vmin,Vmax; - Bounds(Umin,Umax,Vmin,Vmax); - DerSurf.SetValue(1, 0, D1U); - DerSurf.SetValue(0, 1, D1V); - derivatives(MaxOrder,1,U,V,basisSurf,0,0,AlongU,AlongV,L,DerNUV,DerSurf); - - CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV); - if (NStatus == CSLib_Defined) - P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ()); - else - Geom_UndefinedValue::Raise(); - - } + { + Standard_Integer MaxOrder=3; + TColgp_Array2OfVec DerNUV(0,MaxOrder,0,MaxOrder); + TColgp_Array2OfVec DerSurf(0,MaxOrder+1,0,MaxOrder+1); + Standard_Integer OrderU,OrderV; + Standard_Real Umin,Umax,Vmin,Vmax; + Bounds(Umin,Umax,Vmin,Vmax); + DerSurf.SetValue(1, 0, D1U); + DerSurf.SetValue(0, 1, D1V); + derivatives(MaxOrder,1,U,V,basisSurf,0,0,AlongU,AlongV,L,DerNUV,DerSurf); + + CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV); + if (NStatus == CSLib_Defined) + P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ()); + else + Geom_UndefinedValue::Raise(); + + } } //======================================================================= @@ -1688,11 +1764,11 @@ void Geom_OffsetSurface::SetD0(const Standard_Real U, const Standard_Real V, //purpose : private //=======================================================================/ void Geom_OffsetSurface::SetD1(const Standard_Real U, const Standard_Real V, - Pnt& P, - Vec& D1U, Vec& D1V, - const Vec& d2u, const Vec& d2v, const Vec& d2uv ) const + Pnt& P, + Vec& D1U, Vec& D1V, + const Vec& d2u, const Vec& d2v, const Vec& d2uv ) const { - + Standard_Real MagTol=0.000000001; Dir Normal; CSLib_NormalStatus NStatus; @@ -1714,24 +1790,24 @@ void Geom_OffsetSurface::SetD1(const Standard_Real U, const Standard_Real V, DerSurf.SetValue(0, 2, d2v); Handle(Geom_BSplineSurface) L; Standard_Boolean AlongU = Standard_False, - AlongV = Standard_False; + AlongV = Standard_False; Standard_Boolean IsOpposite=Standard_False; Standard_Real signe = 1.; AlongU = UOsculatingSurface(U,V,IsOpposite,L); AlongV = VOsculatingSurface(U,V,IsOpposite,L); if ((AlongV || AlongU) && IsOpposite) signe = -1; derivatives(MaxOrder,2,U,V,basisSurf,1,1,AlongU,AlongV,L,DerNUV,DerSurf); - + CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV); if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise(); - + P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ()); - + D1U = DerSurf(1,0) + offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV); D1V = DerSurf(0,1) + offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV); - + } //======================================================================= @@ -1739,11 +1815,11 @@ void Geom_OffsetSurface::SetD1(const Standard_Real U, const Standard_Real V, //purpose : private //=======================================================================/ void Geom_OffsetSurface::SetD2(const Standard_Real U, const Standard_Real V, - Pnt& P, - Vec& D1U, Vec& D1V, - Vec& D2U, Vec& D2V, Vec& D2UV, - const Vec& d3u, const Vec& d3v, - const Vec& d3uuv, const Vec& d3uvv ) const + Pnt& P, + Vec& D1U, Vec& D1V, + Vec& D2U, Vec& D2V, Vec& D2UV, + const Vec& d3u, const Vec& d3v, + const Vec& d3uuv, const Vec& d3uvv ) const { Standard_Real MagTol=0.000000001; Dir Normal; @@ -1769,28 +1845,28 @@ void Geom_OffsetSurface::SetD2(const Standard_Real U, const Standard_Real V, DerSurf.SetValue(1, 2, d3uvv); DerSurf.SetValue(0, 3, d3v); //********************* - + Handle(Geom_BSplineSurface) L; Standard_Boolean AlongU = Standard_False, - AlongV = Standard_False; + AlongV = Standard_False; Standard_Boolean IsOpposite=Standard_False; Standard_Real signe = 1.; AlongU = UOsculatingSurface(U,V,IsOpposite,L); AlongV = VOsculatingSurface(U,V,IsOpposite,L); if ((AlongV || AlongU) && IsOpposite) signe = -1; derivatives(MaxOrder,3,U,V,basisSurf,2,2,AlongU,AlongV,L,DerNUV,DerSurf); - + CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV); if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise(); - - + + P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ()); - + D1U = DerSurf(1,0) + offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV); D1V = DerSurf(0,1) + offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV); - + D2U = basisSurf->DN(U,V,2,0) + signe * offsetValue * CSLib::DNNormal(2,0,DerNUV,OrderU,OrderV); D2V = basisSurf->DN(U,V,0,2) @@ -1805,10 +1881,10 @@ void Geom_OffsetSurface::SetD2(const Standard_Real U, const Standard_Real V, //purpose : private //=======================================================================/ void Geom_OffsetSurface::SetD3(const Standard_Real U, const Standard_Real V, - Pnt& P, - Vec& D1U, Vec& D1V, - Vec& D2U, Vec& D2V, Vec& D2UV, - Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV ) const + Pnt& P, + Vec& D1U, Vec& D1V, + Vec& D2U, Vec& D2V, Vec& D2UV, + Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV ) const { Standard_Real MagTol=0.000000001; Dir Normal; @@ -1824,7 +1900,7 @@ void Geom_OffsetSurface::SetD3(const Standard_Real U, const Standard_Real V, TColgp_Array2OfVec DerSurf(0,MaxOrder+4,0,MaxOrder+4); Standard_Real Umin,Umax,Vmin,Vmax; Bounds(Umin,Umax,Vmin,Vmax); - + DerSurf.SetValue(1, 0, D1U); DerSurf.SetValue(0, 1, D1V); DerSurf.SetValue(1, 1, D2UV); @@ -1834,30 +1910,30 @@ void Geom_OffsetSurface::SetD3(const Standard_Real U, const Standard_Real V, DerSurf.SetValue(2, 1, D3UUV); DerSurf.SetValue(1, 2, D3UVV); DerSurf.SetValue(0, 3, D3V); - - + + //********************* Handle(Geom_BSplineSurface) L; Standard_Boolean AlongU = Standard_False, - AlongV = Standard_False; + AlongV = Standard_False; Standard_Boolean IsOpposite=Standard_False; Standard_Real signe = 1.; AlongU = UOsculatingSurface(U,V,IsOpposite,L); AlongV = VOsculatingSurface(U,V,IsOpposite,L); if ((AlongV || AlongU) && IsOpposite) signe = -1; derivatives(MaxOrder,3,U,V,basisSurf,3,3,AlongU,AlongV,L,DerNUV,DerSurf); - + CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV); if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise(); - - + + P.SetXYZ(P.XYZ() + offsetValue * signe * Normal.XYZ()); - + D1U = DerSurf(1,0) + offsetValue * signe * CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV); D1V = DerSurf(0,1) + offsetValue * signe * CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV); - + D2U = basisSurf->DN(U,V,2,0) + signe * offsetValue * CSLib::DNNormal(2,0,DerNUV,OrderU,OrderV); D2V = basisSurf->DN(U,V,0,2) @@ -1881,8 +1957,8 @@ void Geom_OffsetSurface::SetD3(const Standard_Real U, const Standard_Real V, //======================================================================= Vec Geom_OffsetSurface::SetDN ( const Standard_Real U , const Standard_Real V, - const Standard_Integer Nu, const Standard_Integer Nv, - const Vec& D1U, const Vec& D1V) const + const Standard_Integer Nu, const Standard_Integer Nv, + const Vec& D1U, const Vec& D1V) const { gp_Vec D(0,0,0); Standard_Real MagTol=0.000000001; @@ -1899,7 +1975,7 @@ Vec Geom_OffsetSurface::SetDN ( const Standard_Real U , const Standard_Real TColgp_Array2OfVec DerSurf(0,MaxOrder+Nu+1,0,MaxOrder+Nv+1); Standard_Real Umin,Umax,Vmin,Vmax; Bounds(Umin,Umax,Vmin,Vmax); - + DerSurf.SetValue(1, 0, D1U); DerSurf.SetValue(0, 1, D1V); //********************* @@ -1910,15 +1986,23 @@ Vec Geom_OffsetSurface::SetDN ( const Standard_Real U , const Standard_Real Standard_Real signe = 1.; AlongU = UOsculatingSurface(U,V,IsOpposite,L); AlongV = VOsculatingSurface(U,V,IsOpposite,L); - if ((AlongV || AlongU) && IsOpposite) signe = -1; + if ((AlongV || AlongU) && IsOpposite) signe = -1; derivatives(MaxOrder,1,U,V,basisSurf,Nu,Nv,AlongU,AlongV,L,DerNUV,DerSurf); - + CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,NStatus,Normal,OrderU,OrderV); if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise(); - + D = basisSurf->DN(U,V,Nu,Nv) + signe * offsetValue * CSLib::DNNormal(Nu,Nv,DerNUV,OrderU,OrderV); - + return D; } +//======================================================================= +//function : GetBasisCurveContinuity +//purpose : +//======================================================================= +GeomAbs_Shape Geom_OffsetSurface::GetBasisSurfContinuity() const +{ + return myBasisSurfContinuity; +} diff --git a/src/Geom/Geom_OsculatingSurface.cxx b/src/Geom/Geom_OsculatingSurface.cxx index cc09d95078..cd2ab0a874 100644 --- a/src/Geom/Geom_OsculatingSurface.cxx +++ b/src/Geom/Geom_OsculatingSurface.cxx @@ -33,7 +33,7 @@ //======================================================================= Geom_OsculatingSurface::Geom_OsculatingSurface() -: myAlong(1,4) + : myAlong(1,4) { } //======================================================================= @@ -42,8 +42,8 @@ Geom_OsculatingSurface::Geom_OsculatingSurface() //======================================================================= Geom_OsculatingSurface::Geom_OsculatingSurface(const Handle(Geom_Surface)& BS, - const Standard_Real Tol) -: myAlong(1,4) + const Standard_Real Tol) + : myAlong(1,4) { Init(BS,Tol); } @@ -54,7 +54,7 @@ Geom_OsculatingSurface::Geom_OsculatingSurface(const Handle(Geom_Surface)& BS, //======================================================================= void Geom_OsculatingSurface::Init(const Handle(Geom_Surface)& BS, - const Standard_Real Tol) + const Standard_Real Tol) { ClearOsculFlags(); myTol=Tol; @@ -64,232 +64,232 @@ void Geom_OsculatingSurface::Init(const Handle(Geom_Surface)& BS, myOsculSurf1 = new Geom_HSequenceOfBSplineSurface(); myOsculSurf2 = new Geom_HSequenceOfBSplineSurface(); if ((BS->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) || - (BS->IsKind(STANDARD_TYPE(Geom_BezierSurface)))) + (BS->IsKind(STANDARD_TYPE(Geom_BezierSurface)))) + { + Standard_Real U1=0,U2=0,V1=0,V2=0; + + Standard_Integer i = 1; + BS->Bounds(U1,U2,V1,V2); + myAlong.SetValue(1,IsQPunctual(BS,V1,GeomAbs_IsoV,TolMin,Tol)); + myAlong.SetValue(2,IsQPunctual(BS,V2,GeomAbs_IsoV,TolMin,Tol)); + myAlong.SetValue(3,IsQPunctual(BS,U1,GeomAbs_IsoU,TolMin,Tol)); + myAlong.SetValue(4,IsQPunctual(BS,U2,GeomAbs_IsoU,TolMin,Tol)); +#ifdef OCCT_DEBUG + cout<Bounds(U1,U2,V1,V2); - myAlong.SetValue(1,IsQPunctual(BS,V1,GeomAbs_IsoV,TolMin,Tol)); - myAlong.SetValue(2,IsQPunctual(BS,V2,GeomAbs_IsoV,TolMin,Tol)); - myAlong.SetValue(3,IsQPunctual(BS,U1,GeomAbs_IsoU,TolMin,Tol)); - myAlong.SetValue(4,IsQPunctual(BS,U2,GeomAbs_IsoU,TolMin,Tol)); + Handle(Geom_BSplineSurface) InitSurf, L,S; + if (BS->IsKind(STANDARD_TYPE(Geom_BezierSurface))) + { + Handle(Geom_BezierSurface) BzS = Handle(Geom_BezierSurface)::DownCast(BS); + TColgp_Array2OfPnt P(1,BzS->NbUPoles(),1,BzS->NbVPoles()); + TColStd_Array1OfReal UKnots(1,2); + TColStd_Array1OfReal VKnots(1,2); + TColStd_Array1OfInteger UMults(1,2); + TColStd_Array1OfInteger VMults(1,2); + for (i=1;i<=2;i++) + { + UKnots.SetValue(i,(i-1)); + VKnots.SetValue(i,(i-1)); + UMults.SetValue(i,BzS->UDegree()+1); + VMults.SetValue(i,BzS->VDegree()+1); + } + BzS->Poles(P); + InitSurf = new Geom_BSplineSurface(P,UKnots,VKnots, + UMults,VMults, + BzS->UDegree(), + BzS->VDegree(), + BzS->IsUPeriodic(), + BzS->IsVPeriodic()); + } + else + { + InitSurf = Handle(Geom_BSplineSurface)::DownCast(myBasisSurf); + } #ifdef OCCT_DEBUG - cout<UDegree()<VDegree()<IsKind(STANDARD_TYPE(Geom_BezierSurface))) - { - Handle(Geom_BezierSurface) BzS = Handle(Geom_BezierSurface)::DownCast(BS); - TColgp_Array2OfPnt P(1,BzS->NbUPoles(),1,BzS->NbVPoles()); - TColStd_Array1OfReal UKnots(1,2); - TColStd_Array1OfReal VKnots(1,2); - TColStd_Array1OfInteger UMults(1,2); - TColStd_Array1OfInteger VMults(1,2); - for (i=1;i<=2;i++) - { - UKnots.SetValue(i,(i-1)); - VKnots.SetValue(i,(i-1)); - UMults.SetValue(i,BzS->UDegree()+1); - VMults.SetValue(i,BzS->VDegree()+1); - } - BzS->Poles(P); - InitSurf = new Geom_BSplineSurface(P,UKnots,VKnots, - UMults,VMults, - BzS->UDegree(), - BzS->VDegree(), - BzS->IsUPeriodic(), - BzS->IsVPeriodic()); - } - else - { - InitSurf = Handle(Geom_BSplineSurface)::DownCast(myBasisSurf); - } + + if(IsAlongU() && IsAlongV()) ClearOsculFlags(); + // Standard_ConstructionError_Raise_if((IsAlongU() && IsAlongV()),"Geom_OsculatingSurface"); + if ((IsAlongU() && InitSurf->VDegree()>1) || + (IsAlongV() && InitSurf->UDegree()>1)) + { + myKdeg = new TColStd_HSequenceOfInteger(); + Standard_Integer k=0; + Standard_Boolean IsQPunc; + Standard_Integer UKnot,VKnot; + if (myAlong(1) || myAlong(2)) + { + for (i=1;iNbUKnots();i++) + { + if (myAlong(1)) + { + S = InitSurf; k=0; IsQPunc=Standard_True; + UKnot=i; + VKnot=1; + while(IsQPunc) + { + OsculSurf = BuildOsculatingSurface(V1,UKnot,VKnot,S,L); + if(!OsculSurf) break; + k++; #ifdef OCCT_DEBUG - cout<<"UDEG: "<UDegree()<VDegree()<VDegree()>1) || - (IsAlongV() && InitSurf->UDegree()>1)) - { - myKdeg = new TColStd_HSequenceOfInteger(); - Standard_Integer k=0; - Standard_Boolean IsQPunc; - Standard_Integer UKnot,VKnot; - if (myAlong(1) || myAlong(2)) - { - for (i=1;iNbUKnots();i++) - { - if (myAlong(1)) - { - S = InitSurf; k=0; IsQPunc=Standard_True; - UKnot=i; - VKnot=1; - while(IsQPunc) - { - OsculSurf = BuildOsculatingSurface(V1,UKnot,VKnot,S,L); - if(!OsculSurf) break; - k++; + IsQPunc=IsQPunctual(L,V1,GeomAbs_IsoV,0.,Tol); + UKnot=1; + VKnot=1; + S=L; + + } + if (OsculSurf) + myOsculSurf1->Append(L); + else + ClearOsculFlags(); //myAlong.SetValue(1,Standard_False); + if (myAlong(2) && OsculSurf) + { + S = InitSurf; k=0; IsQPunc=Standard_True; + UKnot=i; + VKnot=InitSurf->NbVKnots()-1; + + while(IsQPunc) + { + OsculSurf = BuildOsculatingSurface(V2,UKnot,VKnot,S,L); + if(!OsculSurf) break; + k++; #ifdef OCCT_DEBUG - cout<<"1.k = "<UDegree(); vdeg = BS->VDegree(); if( (IsAlongU() && vdeg <=1) || (IsAlongV() && udeg <=1)) { #ifdef OCCT_DEBUG - cout<<" surface osculatrice nulle "<ChangeValue(i) = i-1; - PolynomialVIntervals->ChangeValue(i) = i-1; - TrueUIntervals->ChangeValue(i) = BS->UKnot(SUKnot+i-1); - TrueVIntervals->ChangeValue(i) = BS->VKnot(SVKnot+i-1); - } - - - Standard_Integer OscUNumCoeff=0, OscVNumCoeff=0; - if (IsAlongU()) - { -#ifdef OCCT_DEBUG - cout<<">>>>>>>>>>> AlongU"<>>>>>>>>>> AlongV"<ChangeValue(1,1) = OscUNumCoeff; - NumCoeffPerSurface->ChangeValue(1,2) = OscVNumCoeff; - - Handle(TColStd_HArray1OfReal) Coefficients = new TColStd_HArray1OfReal(1, - NumCoeffPerSurface->Value(1,1)*NumCoeffPerSurface->Value(1,2)*3); -// end for polynomial grid - -// building the cache - Standard_Integer ULocalIndex, VLocalIndex; - Standard_Real ucacheparameter, vcacheparameter,uspanlength, vspanlength; - TColgp_Array2OfPnt NewPoles(1, BS->NbUPoles(), 1, BS->NbVPoles()); - TColStd_Array1OfReal UFlatKnots(1, BS->NbUPoles() + BS->UDegree() + 1); - TColStd_Array1OfReal VFlatKnots(1, BS->NbVPoles() + BS->VDegree() + 1); - BS->Poles(NewPoles); - BS->UKnotSequence(UFlatKnots); - BS->VKnotSequence(VFlatKnots); - - VLocalIndex = 0; - ULocalIndex = 0; - for(j = 1; j <= SVKnot; j++) VLocalIndex += BS->VMultiplicity(j); - for(i = 1; i <= SUKnot; i++) ULocalIndex += BS->UMultiplicity(i); - ucacheparameter = BS->UKnot(SUKnot); - vcacheparameter = BS->VKnot(SVKnot); - vspanlength = BS->VKnot(SVKnot + 1) - BS->VKnot(SVKnot); - uspanlength = BS->UKnot(SUKnot + 1) - BS->UKnot(SUKnot); - - // On se ramene toujours a un parametrage tel que localement ce soit l'iso - // u=0 ou v=0 qui soit degeneree - - Standard_Boolean IsVNegative = Param > vcacheparameter + vspanlength/2; - Standard_Boolean IsUNegative = Param > ucacheparameter + uspanlength/2; - - if (IsAlongU() && (Param > vcacheparameter + vspanlength/2)) - vcacheparameter = vcacheparameter + vspanlength; - if (IsAlongV() && (Param > ucacheparameter + uspanlength/2)) - ucacheparameter = ucacheparameter + uspanlength; - - BSplSLib::BuildCache(ucacheparameter, - vcacheparameter, - uspanlength, - vspanlength, - BS->IsUPeriodic(), - BS->IsVPeriodic(), - BS->UDegree(), - BS->VDegree(), - ULocalIndex, - VLocalIndex, - UFlatKnots, - VFlatKnots, - NewPoles, - BSplSLib::NoWeights(), - cachepoles, - BSplSLib::NoWeights()); - Standard_Integer m, n, index; - TColgp_Array2OfPnt OscCoeff(1,OscUNumCoeff , 1, OscVNumCoeff); - - if (IsAlongU()) - { - if (udeg > vdeg) - { - for(n = 1; n <= udeg + 1; n++) - for(m = 1; m <= vdeg; m++) - OscCoeff(n,m) = cachepoles(n,m+1) ; - } - else - { - for(n = 1; n <= udeg + 1; n++) - for(m = 1; m <= vdeg; m++) - OscCoeff(n,m) = cachepoles(m+1,n) ; - } - if (IsVNegative) PLib::VTrimming(-1,0,OscCoeff,PLib::NoWeights2()); - - index=1; - for(n = 1; n <= udeg + 1; n++) - for(m = 1; m <= vdeg; m++) - { - Coefficients->ChangeValue(index++) = OscCoeff(n,m).X(); - Coefficients->ChangeValue(index++) = OscCoeff(n,m).Y(); - Coefficients->ChangeValue(index++) = OscCoeff(n,m).Z(); - } - } - - if (IsAlongV()) - { - if (udeg > vdeg) - { - for(n = 1; n <= udeg; n++) - for(m = 1; m <= vdeg + 1; m++) - OscCoeff(n,m) = cachepoles(n+1,m); - } - else - { - for(n = 1; n <= udeg; n++) - for(m = 1; m <= vdeg + 1; m++) - OscCoeff(n,m) = cachepoles(m,n+1); - } - if (IsUNegative) PLib::UTrimming(-1,0,OscCoeff,PLib::NoWeights2()); - index=1; - for(n = 1; n <= udeg; n++) - for(m = 1; m <= vdeg + 1; m++) - { - Coefficients->ChangeValue(index++) = OscCoeff(n,m).X(); - Coefficients->ChangeValue(index++) = OscCoeff(n,m).Y(); - Coefficients->ChangeValue(index++) = OscCoeff(n,m).Z(); - } - } - - if (IsAlongU()) MaxVDegree--; - if (IsAlongV()) MaxUDegree--; - UContinuity = - 1; - VContinuity = - 1; - - Convert_GridPolynomialToPoles Data(1,1, - UContinuity, - VContinuity, - MaxUDegree, - MaxVDegree, - NumCoeffPerSurface, - Coefficients, - PolynomialUIntervals, - PolynomialVIntervals, - TrueUIntervals, - TrueVIntervals); - -// Handle(Geom_BSplineSurface) BSpl = - BSpl =new Geom_BSplineSurface(Data.Poles()->Array2(), - Data.UKnots()->Array1(), - Data.VKnots()->Array1(), - Data.UMultiplicities()->Array1(), - Data.VMultiplicities()->Array1(), - Data.UDegree(), - Data.VDegree(), - 0, 0); -#ifdef OCCT_DEBUG - cout<<"^====================================^"<ChangeValue(i) = i-1; + PolynomialVIntervals->ChangeValue(i) = i-1; + TrueUIntervals->ChangeValue(i) = BS->UKnot(SUKnot+i-1); + TrueVIntervals->ChangeValue(i) = BS->VKnot(SVKnot+i-1); } + + + Standard_Integer OscUNumCoeff=0, OscVNumCoeff=0; + if (IsAlongU()) + { +#ifdef OCCT_DEBUG + cout<<">>>>>>>>>>> AlongU"<>>>>>>>>>> AlongV"<ChangeValue(1,1) = OscUNumCoeff; + NumCoeffPerSurface->ChangeValue(1,2) = OscVNumCoeff; + Standard_Integer nbc = NumCoeffPerSurface->Value(1,1)*NumCoeffPerSurface->Value(1,2)*3; + // + if(nbc == 0) + { + return Standard_False; + } + // + Handle(TColStd_HArray1OfReal) Coefficients = new TColStd_HArray1OfReal(1, nbc); + // end for polynomial grid + + // building the cache + Standard_Integer ULocalIndex, VLocalIndex; + Standard_Real ucacheparameter, vcacheparameter,uspanlength, vspanlength; + TColgp_Array2OfPnt NewPoles(1, BS->NbUPoles(), 1, BS->NbVPoles()); + + Standard_Integer aUfKnotsLength = BS->NbUPoles() + BS->UDegree() + 1; + Standard_Integer aVfKnotsLength = BS->NbVPoles() + BS->VDegree() + 1; + + if(BS->IsUPeriodic()) + { + TColStd_Array1OfInteger aMults(1, BS->NbUKnots()); + BS->UMultiplicities(aMults); + aUfKnotsLength = BSplCLib::KnotSequenceLength(aMults, BS->UDegree(), Standard_True); + } + + if(BS->IsVPeriodic()) + { + TColStd_Array1OfInteger aMults(1, BS->NbVKnots()); + BS->VMultiplicities(aMults); + aVfKnotsLength = BSplCLib::KnotSequenceLength(aMults, BS->VDegree(), Standard_True); + } + + TColStd_Array1OfReal UFlatKnots(1, aUfKnotsLength); + TColStd_Array1OfReal VFlatKnots(1, aVfKnotsLength); + BS->Poles(NewPoles); + BS->UKnotSequence(UFlatKnots); + BS->VKnotSequence(VFlatKnots); + + VLocalIndex = 0; + ULocalIndex = 0; + for(j = 1; j <= SVKnot; j++) VLocalIndex += BS->VMultiplicity(j); + for(i = 1; i <= SUKnot; i++) ULocalIndex += BS->UMultiplicity(i); + ucacheparameter = BS->UKnot(SUKnot); + vcacheparameter = BS->VKnot(SVKnot); + vspanlength = BS->VKnot(SVKnot + 1) - BS->VKnot(SVKnot); + uspanlength = BS->UKnot(SUKnot + 1) - BS->UKnot(SUKnot); + + // On se ramene toujours a un parametrage tel que localement ce soit l'iso + // u=0 ou v=0 qui soit degeneree + + Standard_Boolean IsVNegative = Param > vcacheparameter + vspanlength/2; + Standard_Boolean IsUNegative = Param > ucacheparameter + uspanlength/2; + + if (IsAlongU() && (Param > vcacheparameter + vspanlength/2)) + vcacheparameter = vcacheparameter + vspanlength; + if (IsAlongV() && (Param > ucacheparameter + uspanlength/2)) + ucacheparameter = ucacheparameter + uspanlength; + + BSplSLib::BuildCache(ucacheparameter, + vcacheparameter, + uspanlength, + vspanlength, + BS->IsUPeriodic(), + BS->IsVPeriodic(), + BS->UDegree(), + BS->VDegree(), + ULocalIndex, + VLocalIndex, + UFlatKnots, + VFlatKnots, + NewPoles, + BSplSLib::NoWeights(), + cachepoles, + BSplSLib::NoWeights()); + Standard_Integer m, n, index; + TColgp_Array2OfPnt OscCoeff(1,OscUNumCoeff , 1, OscVNumCoeff); + + if (IsAlongU()) + { + if (udeg > vdeg) + { + for(n = 1; n <= udeg + 1; n++) + for(m = 1; m <= vdeg; m++) + OscCoeff(n,m) = cachepoles(n,m+1) ; + } + else + { + for(n = 1; n <= udeg + 1; n++) + for(m = 1; m <= vdeg; m++) + OscCoeff(n,m) = cachepoles(m+1,n) ; + } + if (IsVNegative) PLib::VTrimming(-1,0,OscCoeff,PLib::NoWeights2()); + + index=1; + for(n = 1; n <= udeg + 1; n++) + for(m = 1; m <= vdeg; m++) + { + Coefficients->ChangeValue(index++) = OscCoeff(n,m).X(); + Coefficients->ChangeValue(index++) = OscCoeff(n,m).Y(); + Coefficients->ChangeValue(index++) = OscCoeff(n,m).Z(); + } + } + + if (IsAlongV()) + { + if (udeg > vdeg) + { + for(n = 1; n <= udeg; n++) + for(m = 1; m <= vdeg + 1; m++) + OscCoeff(n,m) = cachepoles(n+1,m); + } + else + { + for(n = 1; n <= udeg; n++) + for(m = 1; m <= vdeg + 1; m++) + OscCoeff(n,m) = cachepoles(m,n+1); + } + if (IsUNegative) PLib::UTrimming(-1,0,OscCoeff,PLib::NoWeights2()); + index=1; + for(n = 1; n <= udeg; n++) + for(m = 1; m <= vdeg + 1; m++) + { + Coefficients->ChangeValue(index++) = OscCoeff(n,m).X(); + Coefficients->ChangeValue(index++) = OscCoeff(n,m).Y(); + Coefficients->ChangeValue(index++) = OscCoeff(n,m).Z(); + } + } + + if (IsAlongU()) MaxVDegree--; + if (IsAlongV()) MaxUDegree--; + UContinuity = - 1; + VContinuity = - 1; + + Convert_GridPolynomialToPoles Data(1,1, + UContinuity, + VContinuity, + MaxUDegree, + MaxVDegree, + NumCoeffPerSurface, + Coefficients, + PolynomialUIntervals, + PolynomialVIntervals, + TrueUIntervals, + TrueVIntervals); + + // Handle(Geom_BSplineSurface) BSpl = + BSpl =new Geom_BSplineSurface(Data.Poles()->Array2(), + Data.UKnots()->Array1(), + Data.VKnots()->Array1(), + Data.UMultiplicities()->Array1(), + Data.VMultiplicities()->Array1(), + Data.UDegree(), + Data.VDegree(), + 0, 0); +#ifdef OCCT_DEBUG + cout<<"^====================================^"<Bounds(U1,U2,V1,V2); - gp_Vec D1U,D1V; - gp_Pnt P; - Standard_Real Step,D1NormMax; - if (IT == GeomAbs_IsoV) + Standard_Real U1=0,U2=0,V1=0,V2=0,T; + Standard_Boolean Along = Standard_True; + S->Bounds(U1,U2,V1,V2); + gp_Vec D1U,D1V; + gp_Pnt P; + Standard_Real Step,D1NormMax; + if (IT == GeomAbs_IsoV) + { + Step = (U2 - U1)/10; + D1NormMax=0.; + for (T=U1;T<=U2;T=T+Step) { - Step = (U2 - U1)/10; - D1NormMax=0.; - for (T=U1;T<=U2;T=T+Step) - { - S->D1(T,Param,P,D1U,D1V); - D1NormMax=Max(D1NormMax,D1U.Magnitude()); - } + S->D1(T,Param,P,D1U,D1V); + D1NormMax=Max(D1NormMax,D1U.Magnitude()); + } #ifdef OCCT_DEBUG - cout << " D1NormMax = " << D1NormMax << endl; + cout << " D1NormMax = " << D1NormMax << endl; #endif - if (D1NormMax >TolMax || D1NormMax < TolMin ) - Along = Standard_False; - } - else + if (D1NormMax >TolMax || D1NormMax < TolMin ) + Along = Standard_False; + } + else + { + Step = (V2 - V1)/10; + D1NormMax=0.; + for (T=V1;T<=V2;T=T+Step) { - Step = (V2 - V1)/10; - D1NormMax=0.; - for (T=V1;T<=V2;T=T+Step) - { - S->D1(Param,T,P,D1U,D1V); - D1NormMax=Max(D1NormMax,D1V.Magnitude()); - } -#ifdef OCCT_DEBUG - cout << " D1NormMax = " << D1NormMax << endl; -#endif - if (D1NormMax >TolMax || D1NormMax < TolMin ) - Along = Standard_False; - - + S->D1(Param,T,P,D1U,D1V); + D1NormMax=Max(D1NormMax,D1V.Magnitude()); } - return Along; +#ifdef OCCT_DEBUG + cout << " D1NormMax = " << D1NormMax << endl; +#endif + if (D1NormMax >TolMax || D1NormMax < TolMin ) + Along = Standard_False; + + + } + return Along; } //======================================================================= @@ -714,7 +737,7 @@ Standard_Boolean Geom_OsculatingSurface::IsQPunctual //purpose : //======================================================================= - Standard_Boolean Geom_OsculatingSurface::HasOscSurf() const +Standard_Boolean Geom_OsculatingSurface::HasOscSurf() const { return (myAlong(1) || myAlong(2) || myAlong(3) || myAlong(4)); } @@ -764,10 +787,10 @@ const Geom_SequenceOfBSplineSurface& Geom_OsculatingSurface::GetSeqOfL2() const void Geom_OsculatingSurface::ClearOsculFlags() { - myAlong.SetValue(1,Standard_False); - myAlong.SetValue(2,Standard_False); - myAlong.SetValue(3,Standard_False); - myAlong.SetValue(4,Standard_False); + myAlong.SetValue(1,Standard_False); + myAlong.SetValue(2,Standard_False); + myAlong.SetValue(3,Standard_False); + myAlong.SetValue(4,Standard_False); } diff --git a/src/Geom2d/Geom2d_BSplineCurve.cdl b/src/Geom2d/Geom2d_BSplineCurve.cdl index ddf9a7c721..0196187a54 100644 --- a/src/Geom2d/Geom2d_BSplineCurve.cdl +++ b/src/Geom2d/Geom2d_BSplineCurve.cdl @@ -614,6 +614,14 @@ is -- Exceptions Standard_RangeError if N is negative. raises RangeError; + IsG1 (me; theTf, theTl, theAngTol : Real) returns Boolean; + ---Purpose : + -- Check if curve has at least G1 continuity in interval [theTf, theTl] + -- Returns true if IsCN(1) + -- or + -- angle betweem "left" and "right" first derivatives at + -- knots with C0 continuity is less then theAngTol + -- only knots in interval [theTf, theTl] is checked IsClosed (me) returns Boolean; --- Purpose : diff --git a/src/Geom2d/Geom2d_BSplineCurve_1.cxx b/src/Geom2d/Geom2d_BSplineCurve_1.cxx index 08077e0b52..b80b4151e2 100644 --- a/src/Geom2d/Geom2d_BSplineCurve_1.cxx +++ b/src/Geom2d/Geom2d_BSplineCurve_1.cxx @@ -61,6 +61,87 @@ Standard_Boolean Geom2d_BSplineCurve::IsCN ( const Standard_Integer N) const return Standard_False; } } +//======================================================================= +//function : IsG1 +//purpose : +//======================================================================= + +Standard_Boolean Geom2d_BSplineCurve::IsG1 ( const Standard_Real theTf, + const Standard_Real theTl, + const Standard_Real theAngTol) const +{ + + if(IsCN(1)) + { + return Standard_True; + } + + Standard_Integer start = FirstUKnotIndex()+1, + finish = LastUKnotIndex()-1; + Standard_Integer aDeg = Degree(); + for(Standard_Integer aNKnot = start; aNKnot <= finish; aNKnot++) + { + const Standard_Real aTpar = Knot(aNKnot); + + if(aTpar < theTf) + continue; + if(aTpar > theTl) + break; + + Standard_Integer mult = Multiplicity(aNKnot); + if (mult < aDeg) + continue; + + gp_Pnt2d aP1, aP2; + gp_Vec2d aV1, aV2; + LocalD1(aTpar, aNKnot-1, aNKnot, aP1, aV1); + LocalD1(aTpar, aNKnot, aNKnot+1, aP2, aV2); + + if((aV1.SquareMagnitude() <= gp::Resolution()) || + aV2.SquareMagnitude() <= gp::Resolution()) + { + return Standard_False; + } + + if(Abs(aV1.Angle(aV2)) > theAngTol) + return Standard_False; + } + + if(!IsPeriodic()) + return Standard_True; + + const Standard_Real aFirstParam = FirstParameter(), + aLastParam = LastParameter(); + + if( ((aFirstParam - theTf)*(theTl - aFirstParam) < 0.0) && + ((aLastParam - theTf)*(theTl - aLastParam) < 0.0)) + { + //Range [theTf, theTl] does not intersect curve bounadries + return Standard_True; + } + + //Curve is closed or periodic and range [theTf, theTl] + //intersect curve boundary. Therefore, it is necessary to + //check if curve is smooth in its first and last point. + + gp_Pnt2d aP; + gp_Vec2d aV1, aV2; + D1(Knot(FirstUKnotIndex()), aP, aV1); + D1(Knot(LastUKnotIndex()), aP, aV2); + + if((aV1.SquareMagnitude() <= gp::Resolution()) || + aV2.SquareMagnitude() <= gp::Resolution()) + { + return Standard_False; + } + + if(Abs(aV1.Angle(aV2)) > theAngTol) + return Standard_False; + + + return Standard_True; + +} //======================================================================= //function : IsClosed diff --git a/src/Geom2d/Geom2d_OffsetCurve.cdl b/src/Geom2d/Geom2d_OffsetCurve.cdl index cca2edb526..7c994d4178 100644 --- a/src/Geom2d/Geom2d_OffsetCurve.cdl +++ b/src/Geom2d/Geom2d_OffsetCurve.cdl @@ -77,7 +77,11 @@ raises ConstructionError from Standard, is - Create (C : Curve from Geom2d; Offset : Real) returns OffsetCurve + Create (C : Curve from Geom2d; + Offset : Real; + isNotCheckC0 : Boolean = Standard_False) + + returns OffsetCurve --- Purpose : Constructs a curve offset from the basis curve C, -- where Offset is the distance between the offset -- curve and the basis curve at any point. @@ -89,11 +93,14 @@ is -- the offset value is measured is indicated by this -- normal vector if Offset is positive, or in the inverse -- sense if Offset is negative. + -- If isNotCheckC0 = TRUE checking if basis curve has C0-continuity + -- is not made. -- Warnings : -- In this package the entities are not shared. The OffsetCurve is -- built with a copy of the curve C. So when C is modified the -- OffsetCurve is not modified - -- Warning! ConstructionError raised if the basis curve C is not at least C1. + -- Warning! if isNotCheckC0 = false, + -- ConstructionError raised if the basis curve C is not at least C1. -- No check is done to know if ||V^Z|| != 0.0 at any point. raises ConstructionError; @@ -115,11 +122,16 @@ is -- the point of parameter U on this offset curve. - SetBasisCurve (me : mutable; C : Curve from Geom2d) + SetBasisCurve ( me : mutable; + C : Curve from Geom2d; + isNotCheckC0 : Boolean = Standard_False) raises ConstructionError; --- Purpose : Changes this offset curve by assigning C as the -- basis curve from which it is built. + -- If isNotCheckC0 = TRUE checking if basis curve has C0-continuity + -- is not made. -- Exceptions + -- if isNotCheckC0 = false, -- Standard_ConstructionError if the curve C is not at least "C1" continuous. SetOffsetValue (me : mutable; D : Real); @@ -329,10 +341,17 @@ is Copy (me) returns like me; - ---Purpose: Creates a new object, which is a copy of this offset curve. + ---Purpose: Creates a new object, which is a copy of this offset curve. + + GetBasisCurveContinuity(me) + returns Shape from GeomAbs; + ---Purpose: Returns continuity of the basis curve. + + fields basisCurve : Curve from Geom2d; offsetValue : Real; + myBasisCurveContinuity : Shape from GeomAbs; end; diff --git a/src/Geom2d/Geom2d_OffsetCurve.cxx b/src/Geom2d/Geom2d_OffsetCurve.cxx index 30c79401b1..07126a7475 100644 --- a/src/Geom2d/Geom2d_OffsetCurve.cxx +++ b/src/Geom2d/Geom2d_OffsetCurve.cxx @@ -34,6 +34,7 @@ #include #include #include +#include typedef Handle(Geom2d_OffsetCurve) Handle(OffsetCurve); typedef Geom2d_OffsetCurve OffsetCurve; @@ -51,7 +52,7 @@ typedef gp_XY XY; //derivee non nulle static const int maxDerivOrder = 3; static const Standard_Real MinStep = 1e-7; - +static const Standard_Real MyAngularToleranceForG1 = Precision::Angular(); //======================================================================= //function : Copy @@ -68,21 +69,16 @@ Handle(Geom2d_Geometry) Geom2d_OffsetCurve::Copy () const //======================================================================= //function : Geom2d_OffsetCurve -//purpose : +//purpose : Basis curve cannot be an Offset curve or trimmed from +// offset curve. //======================================================================= -Geom2d_OffsetCurve::Geom2d_OffsetCurve (const Handle(Curve)& C, - const Standard_Real Offset) -: offsetValue (Offset) +Geom2d_OffsetCurve::Geom2d_OffsetCurve (const Handle(Geom2d_Curve)& theCurve, + const Standard_Real theOffset, + const Standard_Boolean isTheNotCheckC0) +: offsetValue (theOffset) { - if (C->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)) { - Handle(OffsetCurve) OC = Handle(OffsetCurve)::DownCast(C); - SetBasisCurve (OC->BasisCurve()); - offsetValue += OC->Offset(); - } - else { - SetBasisCurve(C); - } + SetBasisCurve (theCurve, isTheNotCheckC0); } //======================================================================= @@ -111,36 +107,65 @@ Standard_Real Geom2d_OffsetCurve::ReversedParameter( const Standard_Real U) cons //purpose : //======================================================================= -void Geom2d_OffsetCurve::SetBasisCurve (const Handle(Curve)& C) +void Geom2d_OffsetCurve::SetBasisCurve (const Handle(Curve)& C, + const Standard_Boolean isNotCheckC0) { - Handle(Geom2d_Curve) aBasisCurve = Handle(Geom2d_Curve)::DownCast(C->Copy()); + const Standard_Real aUf = C->FirstParameter(), + aUl = C->LastParameter(); + Handle(Geom2d_Curve) aCheckingCurve = C; + Standard_Boolean isTrimmed = Standard_False; + + while(aCheckingCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)) || + aCheckingCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) + { + if (aCheckingCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) + { + Handle(Geom2d_TrimmedCurve) aTrimC = + Handle(Geom2d_TrimmedCurve)::DownCast(aCheckingCurve); + aCheckingCurve = aTrimC->BasisCurve(); + isTrimmed = Standard_True; + } + + if (aCheckingCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) + { + Handle(Geom2d_OffsetCurve) aOC = + Handle(Geom2d_OffsetCurve)::DownCast(aCheckingCurve); + aCheckingCurve = aOC->BasisCurve(); + offsetValue += aOC->Offset(); + } + } + + myBasisCurveContinuity = aCheckingCurve->Continuity(); + + Standard_Boolean isC0 = !isNotCheckC0 && + (myBasisCurveContinuity == GeomAbs_C0); // Basis curve must be at least C1 - if (aBasisCurve->Continuity() == GeomAbs_C0) + if (isC0 && aCheckingCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) { - // For B-splines it is sometimes possible to increase continuity by removing - // unnecessarily duplicated knots - if (aBasisCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) + Handle(Geom2d_BSplineCurve) aBC = Handle(Geom2d_BSplineCurve)::DownCast(aCheckingCurve); + if(aBC->IsG1(aUf, aUl, MyAngularToleranceForG1)) { - Handle(Geom2d_BSplineCurve) aBCurve = Handle(Geom2d_BSplineCurve)::DownCast(aBasisCurve); - Standard_Integer degree = aBCurve->Degree(); - Standard_Real Toler = 1e-7; - Standard_Integer start = aBCurve->IsPeriodic() ? 1 : aBCurve->FirstUKnotIndex(), - finish = aBCurve->IsPeriodic() ? aBCurve->NbKnots() : aBCurve->LastUKnotIndex(); - for (Standard_Integer i = start; i <= finish; i++) - { - Standard_Integer mult = aBCurve->Multiplicity(i); - if ( mult == degree ) - aBCurve->RemoveKnot(i,degree - 1, Toler); - } + //Checking if basis curve has more smooth (C1, G2 and above) is not done. + //It can be done in case of need. + myBasisCurveContinuity = GeomAbs_G1; + isC0 = Standard_False; } // Raise exception if still C0 - if (aBasisCurve->Continuity() == GeomAbs_C0) + if (isC0) Standard_ConstructionError::Raise("Offset on C0 curve"); } + // + if(isTrimmed) + { + basisCurve = new Geom2d_TrimmedCurve(aCheckingCurve, aUf, aUl); + } + else + { + basisCurve = aCheckingCurve; + } - basisCurve = aBasisCurve; } //======================================================================= @@ -168,7 +193,7 @@ Handle(Curve) Geom2d_OffsetCurve::BasisCurve () const GeomAbs_Shape Geom2d_OffsetCurve::Continuity () const { GeomAbs_Shape OffsetShape=GeomAbs_C0; - switch (basisCurve->Continuity()) { + switch (myBasisCurveContinuity) { case GeomAbs_C0 : OffsetShape = GeomAbs_C0; break; case GeomAbs_C1 : OffsetShape = GeomAbs_C0; break; case GeomAbs_C2 : OffsetShape = GeomAbs_C1; break; @@ -177,6 +202,7 @@ GeomAbs_Shape Geom2d_OffsetCurve::Continuity () const case GeomAbs_G1 : OffsetShape = GeomAbs_G1; break; case GeomAbs_G2 : OffsetShape = GeomAbs_G2; break; } + return OffsetShape; } @@ -926,3 +952,12 @@ Standard_Real Geom2d_OffsetCurve::ParametricTransformation(const gp_Trsf2d& T) c { return basisCurve->ParametricTransformation(T); } + +//======================================================================= +//function : GetBasisCurveContinuity +//purpose : +//======================================================================= +GeomAbs_Shape Geom2d_OffsetCurve::GetBasisCurveContinuity() const +{ + return myBasisCurveContinuity; +} diff --git a/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx b/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx index 56ca5099a9..a1cb67bbbe 100644 --- a/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx +++ b/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx @@ -214,12 +214,15 @@ GeomAbs_Shape Geom2dAdaptor_Curve::Continuity() const } else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){ GeomAbs_Shape S = - (*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve()->Continuity(); + (*((Handle(Geom2d_OffsetCurve)*)&myCurve))->GetBasisCurveContinuity(); switch(S){ case GeomAbs_CN: return GeomAbs_CN; case GeomAbs_C3: return GeomAbs_C2; case GeomAbs_C2: return GeomAbs_C1; case GeomAbs_C1: return GeomAbs_C0; + case GeomAbs_G1: return GeomAbs_G1; + case GeomAbs_G2: return GeomAbs_G2; + default: Standard_NoSuchObject::Raise("Geom2dAdaptor_Curve::Continuity"); } diff --git a/src/GeomAdaptor/GeomAdaptor_Curve.cxx b/src/GeomAdaptor/GeomAdaptor_Curve.cxx index 3f211fa132..8cb5a7363d 100644 --- a/src/GeomAdaptor/GeomAdaptor_Curve.cxx +++ b/src/GeomAdaptor/GeomAdaptor_Curve.cxx @@ -179,15 +179,17 @@ GeomAbs_Shape GeomAdaptor_Curve::Continuity() const if (myCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) { const GeomAbs_Shape S = - (*((Handle(Geom_OffsetCurve)*)&myCurve))->BasisCurve()->Continuity(); + (*((Handle(Geom_OffsetCurve)*)&myCurve))->GetBasisCurveContinuity(); switch(S) { case GeomAbs_CN: return GeomAbs_CN; case GeomAbs_C3: return GeomAbs_C2; case GeomAbs_C2: return GeomAbs_C1; - case GeomAbs_C1: return GeomAbs_C0; + case GeomAbs_C1: return GeomAbs_C0; + case GeomAbs_G1: return GeomAbs_G1; + case GeomAbs_G2: return GeomAbs_G2; default: - Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Continuity"); + Standard_NoSuchObject::Raise("GeomAdaptor_Curve::Continuity"); } } else if (myTypeCurve == GeomAbs_OtherCurve) { diff --git a/tests/bugs/modalg_5/bug25124_1 b/tests/bugs/modalg_5/bug25124_1 new file mode 100644 index 0000000000..f91699f8a8 --- /dev/null +++ b/tests/bugs/modalg_5/bug25124_1 @@ -0,0 +1,33 @@ +puts "========" +puts "OCC25124" +puts "========" +puts "" +###################################################### +# Removal of continuity checks for offset geometries +###################################################### + +smallview + +set ver_info_1 "\n\n*********** Dump of cc *************\nTrimmed curve\nParameters : 2 5\nBasis curve :\nOffsetCurveOffset : 10\nDirection : 0, 0, 1 \nBasis curve :\nTrimmed curve\nParameters : 1 6\nBasis curve :\nCircle" +set ver_info_2 "\n\n*********** Dump of oc *************\nOffsetCurveOffset : 20\nDirection : 0, 0, 1 \nBasis curve :\nTrimmed curve\nParameters : 2 5\nBasis curve :\nCircle" + +point pp 0 0 1 +circle cc 20 40 30 20 +trim cc cc 1 6 +offsetcurve oc cc 10 pp +trim cc oc 2 5 +set bug_info_1 [dump cc] +offsetcurve oc cc 10 pp +set bug_info_2 [dump oc] + +if {[string first $ver_info_1 $bug_info_1] == -1} { + puts "ERROR: OCC25124 is reproduced (dump of cc)." +} +if {[string first $ver_info_2 $bug_info_2] == -1} { + puts "ERROR: OCC25124 is reproduced (dump of oc)." +} + +donly oc cc +fit + +set only_screen_axo 1 diff --git a/tests/bugs/modalg_5/bug25124_2 b/tests/bugs/modalg_5/bug25124_2 new file mode 100644 index 0000000000..3860c681f9 --- /dev/null +++ b/tests/bugs/modalg_5/bug25124_2 @@ -0,0 +1,32 @@ +puts "========" +puts "OCC25124" +puts "========" +puts "" +###################################################### +# Removal of continuity checks for offset geometries +###################################################### + +smallview + +set ver_info_1 "\n\n*********** Dump of cc *************\nTrimmed curve\nParameters : 2 5\nBasis curve :\nOffsetCurveOffset : 10\nBasis curve :\nTrimmed curve\nParameters : 1 6\nBasis curve :\nCircle" +set ver_info_2 "\n\n*********** Dump of oc *************\nOffsetCurveOffset : 20\nBasis curve :\nTrimmed curve\nParameters : 2 5\nBasis curve :\nCircle" + +circle cc 20 40 20 +trim cc cc 1 6 +offset2dcurve oc cc 10 +trim cc oc 2 5 +set bug_info_1 [dump cc] +offset2dcurve oc cc 10 +set bug_info_2 [dump oc] + +if {[string first $ver_info_1 $bug_info_1] == -1} { + puts "ERROR: OCC25124 is reproduced (dump of cc)." +} +if {[string first $ver_info_2 $bug_info_2] == -1} { + puts "ERROR: OCC25124 is reproduced (dump of oc)." +} + +donly oc cc +fit + +set only_screen_axo 1 diff --git a/tests/bugs/modalg_5/bug25124_3 b/tests/bugs/modalg_5/bug25124_3 new file mode 100644 index 0000000000..7f1f1e06c0 --- /dev/null +++ b/tests/bugs/modalg_5/bug25124_3 @@ -0,0 +1,32 @@ +puts "========" +puts "OCC25124" +puts "========" +puts "" +###################################################### +# Removal of continuity checks for offset geometries +###################################################### + +smallview + +set ver_info_1 "\n\n*********** Dump of ss *************\nRectangularTrimmedSurface\nParameters : 1 5.5 -0.8 0.5\nBasisSurface :\nOffsetSurface\nOffset : 10\nBasisSurface :\nRectangularTrimmedSurface\nParameters : 1 5.5 -0.8 0.5\nBasisSurface :\nSphericalSurface" +set ver_info_2 "\n\n*********** Dump of os *************\nOffsetSurface\nOffset : 20\nBasisSurface :\nRectangularTrimmedSurface\nParameters : 1 5.5 -0.8 0.5\nBasisSurface :\nSphericalSurface" + +sphere ss 30 +trim ss ss 0.5 6 -1 1 +offset os ss 10 +trim ss os 1 5.5 -0.8 0.5 +set bug_info_1 [dump ss] +offset os ss 10 +set bug_info_2 [dump os] + +if {[string first $ver_info_1 $bug_info_1] == -1} { + puts "ERROR: OCC25124 is reproduced (dump of ss)." +} +if {[string first $ver_info_2 $bug_info_2] == -1} { + puts "ERROR: OCC25124 is reproduced (dump of os)." +} + +donly os ss +fit + +set only_screen_axo 1 diff --git a/tests/bugs/modalg_5/bug25124_4 b/tests/bugs/modalg_5/bug25124_4 new file mode 100644 index 0000000000..916a82e781 --- /dev/null +++ b/tests/bugs/modalg_5/bug25124_4 @@ -0,0 +1,38 @@ +puts "========" +puts "OCC25124" +puts "========" +puts "" +###################################################### +# Removal of continuity checks for offset geometries +###################################################### + +smallview + +point pp 0 0 1 +circle cc 20 40 30 20 +convert bc cc +trim bc bc 1 6 +offsetcurve oc bc 10 pp +trim bc oc 2 5 +extsurf se bc 0 0 1 +offset os se 15 + +set bug_info [getsurfcontinuity se] +getsurfcontinuity os + +if {[string compare $bug_info "se has G1 continuity.\n"] != 0} { + puts "ERROR: OCC25124 is reproduced (se does not have G1 continuity)." +} + +set bug_info_1 [dump se] +set bug_info_1 [string range $bug_info_1 39 [expr {[string length $bug_info_1] -1}]] +set bug_info_2 [dump os] +set bug_info_2 [string range $bug_info_2 39 [expr {[string length $bug_info_2] -1}]] +if {[string compare $bug_info_1 $bug_info_2] == 0} { + puts "ERROR: OCC25124 is reproduced (se = os)." +} + +donly os se +fit + +set only_screen_axo 1 diff --git a/tests/bugs/modalg_5/bug25124_5 b/tests/bugs/modalg_5/bug25124_5 new file mode 100644 index 0000000000..4480b041ec --- /dev/null +++ b/tests/bugs/modalg_5/bug25124_5 @@ -0,0 +1,38 @@ +puts "========" +puts "OCC25124" +puts "========" +puts "" +###################################################### +# Removal of continuity checks for offset geometries +###################################################### + +smallview + +point pp 0 0 1 +circle cc 20 40 30 20 +convert bc cc +trim bc bc 1 6 +offsetcurve oc bc 10 pp +trim bc oc 2 5 +revsurf se bc 0 0 0 0 1 0 +offset os se 15 + +set bug_info [getsurfcontinuity se] +getsurfcontinuity os + +if {[string compare $bug_info "se has G1 continuity.\n"] != 0} { + puts "ERROR: OCC25124 is reproduced (se does not have G1 continuity)." +} + +set bug_info_1 [dump se] +set bug_info_1 [string range $bug_info_1 39 [expr {[string length $bug_info_1] -1}]] +set bug_info_2 [dump os] +set bug_info_2 [string range $bug_info_2 39 [expr {[string length $bug_info_2] -1}]] +if {[string compare $bug_info_1 $bug_info_2] == 0} { + puts "ERROR: OCC25124 is reproduced (se = os)." +} + +donly os se +fit + +set only_screen_axo 1 diff --git a/tests/bugs/modalg_5/bug25124_6 b/tests/bugs/modalg_5/bug25124_6 new file mode 100644 index 0000000000..d3d94abd8d --- /dev/null +++ b/tests/bugs/modalg_5/bug25124_6 @@ -0,0 +1,27 @@ +puts "========" +puts "OCC25124" +puts "========" +puts "" +###################################################### +# Removal of continuity checks for offset geometries +###################################################### + +smallview + +restore [locate_data_file OCC25124_a_2999.draw] a1 +getsurfcontinuity a1 +offset o1 a1 20 +getsurfcontinuity o1 + +set bug_info_1 [dump a1] +set bug_info_1 [string range $bug_info_1 39 [expr {[string length $bug_info_1] -1}]] +set bug_info_2 [dump o1] +set bug_info_2 [string range $bug_info_2 39 [expr {[string length $bug_info_2] -1}]] +if {[string compare $bug_info_1 $bug_info_2] == 0} { + puts "ERROR: OCC25124 is reproduced (a1 = o1)." +} + +donly a1 o1 +fit + +set only_screen_axo 1 diff --git a/tests/bugs/modalg_5/bug25124_7 b/tests/bugs/modalg_5/bug25124_7 new file mode 100644 index 0000000000..57539d9b43 --- /dev/null +++ b/tests/bugs/modalg_5/bug25124_7 @@ -0,0 +1,27 @@ +puts "========" +puts "OCC25124" +puts "========" +puts "" +###################################################### +# Removal of continuity checks for offset geometries +###################################################### + +smallview + +restore [locate_data_file OCC25124_a_15592.draw] a2 +getsurfcontinuity a2 +offset o2 a2 20 +getsurfcontinuity o2 + +set bug_info_1 [dump a2] +set bug_info_1 [string range $bug_info_1 39 [expr {[string length $bug_info_1] -1}]] +set bug_info_2 [dump o2] +set bug_info_2 [string range $bug_info_2 39 [expr {[string length $bug_info_2] -1}]] +if {[string compare $bug_info_1 $bug_info_2] == 0} { + puts "ERROR: OCC25124 is reproduced (a2 = o2)." +} + +donly a2 o2 +fit + +set only_screen_axo 1 diff --git a/tests/offset/wire_unclosed_outside_0_005/B3 b/tests/offset/wire_unclosed_outside_0_005/B3 index 39385d6bd3..2b9eb8d70f 100644 --- a/tests/offset/wire_unclosed_outside_0_005/B3 +++ b/tests/offset/wire_unclosed_outside_0_005/B3 @@ -1,13 +1,9 @@ -puts "TODO ?OCC23068 ALL: Error : result is not a topological shape" -puts "TODO ?OCC23068 ALL: Error : The offset cannot be built." -puts "TODO ?OCC23068 ALL: An exception was caught" -puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*" -puts "TODO ?OCC23748 ALL: Error: Offset is not done." +puts "TODO OCC25124068 ALL: Error : big tolerance of shape result" restore [locate_data_file offset_wire_034.brep] s -set length 0 -set nbsh_v 0 -set nbsh_e 0 -set nbsh_w 0 +set length 910.505 +set nbsh_v 14 +set nbsh_e 14 +set nbsh_w 1 diff --git a/tests/offset/wire_unclosed_outside_0_005/B4 b/tests/offset/wire_unclosed_outside_0_005/B4 index 7194103072..f7be28eedb 100644 --- a/tests/offset/wire_unclosed_outside_0_005/B4 +++ b/tests/offset/wire_unclosed_outside_0_005/B4 @@ -1,13 +1,7 @@ -puts "TODO ?OCC23068 ALL: Error : result is not a topological shape" -puts "TODO ?OCC23068 ALL: Error : The offset cannot be built." -puts "TODO ?OCC23068 ALL: An exception was caught" -puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*" -puts "TODO ?OCC23748 ALL: Error: Offset is not done." - restore [locate_data_file case_3_wire2.brep] s -set length 0 -set nbsh_v 0 -set nbsh_e 0 -set nbsh_w 0 +set length 910.505 +set nbsh_v 30 +set nbsh_e 30 +set nbsh_w 1 diff --git a/tests/offset/wire_unclosed_outside_0_005/B6 b/tests/offset/wire_unclosed_outside_0_005/B6 index 32aafb795a..0011e4ea69 100644 --- a/tests/offset/wire_unclosed_outside_0_005/B6 +++ b/tests/offset/wire_unclosed_outside_0_005/B6 @@ -1,13 +1,7 @@ -puts "TODO ?OCC23068 ALL: Error : result is not a topological shape" -puts "TODO ?OCC23068 ALL: Error : The offset cannot be built." -puts "TODO ?OCC23068 ALL: An exception was caught" -puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*" -puts "TODO ?OCC23748 ALL: Error: Offset is not done." - restore [locate_data_file offset_wire_058.brep] s -set length 0 -set nbsh_v 0 -set nbsh_e 0 -set nbsh_w 0 +set length 3316.27 +set nbsh_v 62 +set nbsh_e 62 +set nbsh_w 1 diff --git a/tests/offset/wire_unclosed_outside_0_025/B2 b/tests/offset/wire_unclosed_outside_0_025/B2 index 4184b6b89c..f6a4e3af86 100644 --- a/tests/offset/wire_unclosed_outside_0_025/B2 +++ b/tests/offset/wire_unclosed_outside_0_025/B2 @@ -1,13 +1,7 @@ -puts "TODO ?OCC23068 ALL: Error : result is not a topological shape" -puts "TODO ?OCC23068 ALL: Error : The offset cannot be built." -puts "TODO ?OCC23068 ALL: An exception was caught" -puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*" -puts "TODO ?OCC23748 ALL: Error: Offset is not done." - restore [locate_data_file offset_wire_033.brep] s -set length 0 -set nbsh_v 0 -set nbsh_e 0 -set nbsh_w 0 +set length 68.7414 +set nbsh_v 61 +set nbsh_e 61 +set nbsh_w 1 diff --git a/tests/offset/wire_unclosed_outside_0_025/B4 b/tests/offset/wire_unclosed_outside_0_025/B4 index 7194103072..49cfa136ae 100644 --- a/tests/offset/wire_unclosed_outside_0_025/B4 +++ b/tests/offset/wire_unclosed_outside_0_025/B4 @@ -1,13 +1,9 @@ -puts "TODO ?OCC23068 ALL: Error : result is not a topological shape" -puts "TODO ?OCC23068 ALL: Error : The offset cannot be built." -puts "TODO ?OCC23068 ALL: An exception was caught" -puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*" -puts "TODO ?OCC23748 ALL: Error: Offset is not done." +puts "TODO OCC25109 ALL: Faulty shapes in variables" restore [locate_data_file case_3_wire2.brep] s -set length 0 -set nbsh_v 0 -set nbsh_e 0 -set nbsh_w 0 +set length 957.647 +set nbsh_v 86 +set nbsh_e 86 +set nbsh_w 2 diff --git a/tests/offset/wire_unclosed_outside_0_025/B6 b/tests/offset/wire_unclosed_outside_0_025/B6 index 32aafb795a..ecbabe56ca 100644 --- a/tests/offset/wire_unclosed_outside_0_025/B6 +++ b/tests/offset/wire_unclosed_outside_0_025/B6 @@ -1,13 +1,7 @@ -puts "TODO ?OCC23068 ALL: Error : result is not a topological shape" -puts "TODO ?OCC23068 ALL: Error : The offset cannot be built." -puts "TODO ?OCC23068 ALL: An exception was caught" -puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*" -puts "TODO ?OCC23748 ALL: Error: Offset is not done." - restore [locate_data_file offset_wire_058.brep] s -set length 0 -set nbsh_v 0 -set nbsh_e 0 -set nbsh_w 0 +set length 2582.56 +set nbsh_v 47 +set nbsh_e 47 +set nbsh_w 1 diff --git a/tests/offset/wire_unclosed_outside_0_075/B1 b/tests/offset/wire_unclosed_outside_0_075/B1 index 395f5e3155..6b01cec172 100644 --- a/tests/offset/wire_unclosed_outside_0_075/B1 +++ b/tests/offset/wire_unclosed_outside_0_075/B1 @@ -1,13 +1,7 @@ -puts "TODO ?OCC23068 ALL: Error : result is not a topological shape" -puts "TODO ?OCC23068 ALL: Error : The offset cannot be built." -puts "TODO ?OCC23068 ALL: An exception was caught" -puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*" -puts "TODO ?OCC23748 ALL: Error: Offset is not done." - restore [locate_data_file offset_wire_032.brep] s -set length 0 -set nbsh_v 0 -set nbsh_e 0 -set nbsh_w 0 +set length 92.0671 +set nbsh_v 41 +set nbsh_e 41 +set nbsh_w 1 diff --git a/tests/offset/wire_unclosed_outside_0_075/B2 b/tests/offset/wire_unclosed_outside_0_075/B2 index 4184b6b89c..1219529715 100644 --- a/tests/offset/wire_unclosed_outside_0_075/B2 +++ b/tests/offset/wire_unclosed_outside_0_075/B2 @@ -1,13 +1,7 @@ -puts "TODO ?OCC23068 ALL: Error : result is not a topological shape" -puts "TODO ?OCC23068 ALL: Error : The offset cannot be built." -puts "TODO ?OCC23068 ALL: An exception was caught" -puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*" -puts "TODO ?OCC23748 ALL: Error: Offset is not done." - restore [locate_data_file offset_wire_033.brep] s -set length 0 -set nbsh_v 0 -set nbsh_e 0 -set nbsh_w 0 +set length 78.0343 +set nbsh_v 60 +set nbsh_e 60 +set nbsh_w 1 diff --git a/tests/offset/wire_unclosed_outside_0_075/B6 b/tests/offset/wire_unclosed_outside_0_075/B6 index 32aafb795a..1736ba2df9 100644 --- a/tests/offset/wire_unclosed_outside_0_075/B6 +++ b/tests/offset/wire_unclosed_outside_0_075/B6 @@ -1,13 +1,7 @@ -puts "TODO ?OCC23068 ALL: Error : result is not a topological shape" -puts "TODO ?OCC23068 ALL: Error : The offset cannot be built." -puts "TODO ?OCC23068 ALL: An exception was caught" -puts "TODO ?OCC23068 ALL: \\*\\* Exception \\*\\*.*" -puts "TODO ?OCC23748 ALL: Error: Offset is not done." - restore [locate_data_file offset_wire_058.brep] s -set length 0 -set nbsh_v 0 -set nbsh_e 0 -set nbsh_w 0 +set length 3127.75 +set nbsh_v 39 +set nbsh_e 39 +set nbsh_w 1