diff options
author | Denis Barbier <bouzim@gmail.com> | 2011-07-18 00:00:51 +0200 |
---|---|---|
committer | Denis Barbier <bouzim@gmail.com> | 2011-07-18 00:10:18 +0200 |
commit | 3a125a461d5cac09be38a87f219de9dbc65b4ff6 (patch) | |
tree | 1536173071d6a122a1f887c086c1b40bf5227e74 /src/ChFi3d | |
parent | c99e70bc570ec25d00beb59b9429c183d8238e89 (diff) | |
download | oce-3a125a461d5cac09be38a87f219de9dbc65b4ff6.tar.gz oce-3a125a461d5cac09be38a87f219de9dbc65b4ff6.zip |
Import the ros/ directory of OCCT 6.5.1official/6.5.1
Make files non-executable in the archive, as in c99e70b.
Copy LICENSE from top-level directory.
Diffstat (limited to 'src/ChFi3d')
27 files changed, 31485 insertions, 0 deletions
diff --git a/src/ChFi3d/ChFi3d.cdl b/src/ChFi3d/ChFi3d.cdl new file mode 100644 index 00000000..24ff7555 --- /dev/null +++ b/src/ChFi3d/ChFi3d.cdl @@ -0,0 +1,112 @@ +-- File: ChFi3d.cdl +-- Created: Tue Nov 9 15:39:27 1993 +-- Author: Laurent BOURESCHE +-- <lbo@zerox> +---Copyright: Matra Datavision 1993 + + + +package ChFi3d + + ---Purpose: creation of spatial fillets on a solid. + +uses ChFiDS, + TopOpeBRepBuild, + TopOpeBRepDS, + BRepAdaptor, + BRepTopAdaptor, + BRepBlend, + BlendFunc, + Blend, + AppBlend, + Law, + gp, + Geom2d, + Geom, + GeomAbs, + TopoDS, + TopAbs, + TCollection, + TColStd, + TColgp, + TopTools, + MMgt, + StdFail, + math, + AdvApprox, + Adaptor3d, + Adaptor2d, + Standard + +is + deferred class Builder; + ---Purpose: Structure and methods common for the construction + -- of fillets and chamfers 3d. + + class ChBuilder; + ---Purpose: Tool constructing chamfers on a solid. + + class FilBuilder; + ---Purpose: Outil de construction de conges sur un solide. + + private class SearchSing; + ---Purpose: Searches singularities on fillet + + enumeration FilletShape is + Rational, + QuasiAngular, + Polynomial + --- Purpose: +-- Lists the types of fillet shapes. These include the following: +-- - ChFi3d_Rational (default value), which is the +-- standard NURBS representation of circles, +-- - ChFi3d_QuasiAngular, which is a NURBS +-- representation of circles where the parameters +-- match those of the circle, +-- - ChFi3d_Polynomial, which corresponds to a +-- polynomial approximation of circles. This type +-- facilitates the implementation of the construction algorithm. + + end FilletShape; + + + ConcaveSide (S1,S2 : Surface from BRepAdaptor; E : Edge from TopoDS; + Or1,Or2 : out Orientation from TopAbs) + ---Purpose: Returns Reversed in Or1 and(or) Or2 if + -- the concave edge defined by the interior of faces F1 and F2, + -- in the neighbourhood of their boundary E is of the edge opposite to the + -- normal of their surface support. The orientation of + -- faces is not taken into consideration in the calculation. The + -- function returns 0 if the calculation fails (tangence), + -- if not, it returns the number of choice of the fillet + -- or chamfer corresponding to the orientations calculated + -- and to the tangent to the guide line read in E. + -- + returns Integer from Standard; + + + NextSide (Or1,Or2 : in out Orientation from TopAbs; + OrSave1,OrSave2 : Orientation from TopAbs; + ChoixSauv : Integer from Standard) + ---Purpose: Same as ConcaveSide, but the orientations are + -- logically deduced from the result of the call of + -- ConcaveSide on the first pair of faces of the fillet or + -- chamnfer. + returns Integer from Standard; + + NextSide (Or : in out Orientation from TopAbs; + OrSave,OrFace : Orientation from TopAbs); + ---Purpose: Same as the other NextSide, but the calculation is done + -- on an edge only. + + + SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2 : Orientation from TopAbs) + ---Purpose: Enables to determine while processing an angle, if + -- two fillets or chamfers constituting a face have + -- identic or opposed concave edges. + returns Boolean from Standard; + + + +end ChFi3d; + diff --git a/src/ChFi3d/ChFi3d.cxx b/src/ChFi3d/ChFi3d.cxx new file mode 100644 index 00000000..668ab722 --- /dev/null +++ b/src/ChFi3d/ChFi3d.cxx @@ -0,0 +1,271 @@ +// File: ChFi3d.cxx +// Created: Tue Dec 21 16:19:36 1993 +// Author: Isabelle GRIGNON +// <isg@sdsun2> + + +#include <ChFi3d.ixx> +#include <ChFi3d_Builder_0.hxx> +#include <BRepAdaptor_Surface.hxx> +#include <BRepAdaptor_Curve2d.hxx> +#include <BRepAdaptor_Curve.hxx> +#include <BRep_Tool.hxx> + +#include <gp_Pnt.hxx> +#include <gp_Vec.hxx> +#include <gp_Pnt2d.hxx> +#include <gp_Vec2d.hxx> +#include <Precision.hxx> +#include <TopExp_Explorer.hxx> +#include <TopoDS.hxx> + + +//======================================================================= +//function : ConcaveSide +//purpose : calculate the concave face at the neighborhood of the border of +// 2 faces. +//======================================================================= + +Standard_Integer ChFi3d::ConcaveSide(const BRepAdaptor_Surface& S1, + const BRepAdaptor_Surface& S2, + const TopoDS_Edge& E, + TopAbs_Orientation& Or1, + TopAbs_Orientation& Or2) + +{ + Standard_Integer ChoixConge; + Or1 = Or2 = TopAbs_FORWARD; + BRepAdaptor_Curve CE(E); + Standard_Real first = CE.FirstParameter(); + Standard_Real last = CE.LastParameter(); + Standard_Real par = 0.691254*first + 0.308746*last; + + gp_Pnt pt, pt1, pt2; gp_Vec tgE, tgE1, tgE2, ns1, ns2, dint1, dint2; + TopoDS_Face F1 = S1.Face(); + TopoDS_Face F2 = S2.Face(); + F1.Orientation(TopAbs_FORWARD); + F2.Orientation(TopAbs_FORWARD); + + CE.D1(par,pt,tgE); + tgE.Normalize(); + tgE2 = tgE1 = tgE; + if(E.Orientation() == TopAbs_REVERSED) tgE.Reverse(); + + TopoDS_Edge E1 = E, E2 = E; + E1.Orientation(TopAbs_FORWARD); + E2.Orientation(TopAbs_FORWARD); + + if(F1.IsSame(F2) && BRep_Tool::IsClosed(E,F1)) { + E2.Orientation(TopAbs_REVERSED); + tgE2.Reverse(); + } + else { + TopExp_Explorer Exp; + Standard_Boolean found = 0; + for (Exp.Init(F1,TopAbs_EDGE); + Exp.More() && !found; + Exp.Next()) { + if (E.IsSame(TopoDS::Edge(Exp.Current()))){ + if(Exp.Current().Orientation() == TopAbs_REVERSED) tgE1.Reverse(); + found = Standard_True; + } + } + if (!found) { return 0; } + found = 0; + for (Exp.Init(F2,TopAbs_EDGE); + Exp.More() && !found; + Exp.Next()) { + if (E.IsSame(TopoDS::Edge(Exp.Current()))){ + if(Exp.Current().Orientation() == TopAbs_REVERSED) tgE2.Reverse(); + found = Standard_True; + } + } + if (!found) { return 0; } + } + BRepAdaptor_Curve2d pc1(E1,F1); + BRepAdaptor_Curve2d pc2(E2,F2); + gp_Pnt2d p2d1,p2d2; + gp_Vec DU1,DV1,DU2,DV2; + p2d1 = pc1.Value(par); + p2d2 = pc2.Value(par); + S1.D1(p2d1.X(),p2d1.Y(),pt1,DU1,DV1); + ns1 = DU1.Crossed(DV1); + ns1.Normalize(); + S2.D1(p2d2.X(),p2d2.Y(),pt2,DU2,DV2); + ns2 = DU2.Crossed(DV2); + ns2.Normalize(); + + dint1 = ns1.Crossed(tgE1); + dint2 = ns2.Crossed(tgE2); + Standard_Real ang = ns1.CrossMagnitude(ns2); + if(ang > 0.0001*PI){ + Standard_Real scal = ns2.Dot(dint1); + if ( scal <= 0. ){ + ns2.Reverse(); + Or2 = TopAbs_REVERSED; + } + scal = ns1.Dot(dint2); + if ( scal <= 0. ){ + ns1.Reverse(); + Or1 = TopAbs_REVERSED; + } + } + else { + //the faces are locally tangent - this is fake! + if(dint1.Dot(dint2) < 0.){ + //This is a forgotten regularity + gp_Vec DDU, DDV, DDUV; + S1.D2(p2d1.X(),p2d1.Y(),pt1,DU1,DV1,DDU,DDV,DDUV); + DU1 += ( DU1 * dint1 < 0) ? -DDU : DDU; + DV1 += ( DV1 * dint1 < 0) ? -DDV : DDV; + ns1 = DU1.Crossed(DV1); + ns1.Normalize(); + S2.D2(p2d2.X(),p2d2.Y(),pt2,DU2,DV2,DDU,DDV,DDUV); + DU2 += ( DU2 * dint2 < 0) ? -DDU : DDU; + DV2 += ( DV2 * dint2 < 0) ? -DDV : DDV; + ns2 = DU2.Crossed(DV2); + ns2.Normalize(); + + dint1 = ns1.Crossed(tgE1); + dint2 = ns2.Crossed(tgE2); + ang = ns1.CrossMagnitude(ns2); + if(ang > 0.0001*PI){ + Standard_Real scal = ns2.Dot(dint1); + if ( scal <= 0. ){ + ns2.Reverse(); + Or2 = TopAbs_REVERSED; + } + scal = ns1.Dot(dint2); + if ( scal <= 0. ){ + ns1.Reverse(); + Or1 = TopAbs_REVERSED; + } + } + else { +#ifdef DEB + cout<<"ConcaveSide : no concave face"<<endl; +#endif + //This 10 shows that the face at end is in the extension of one of two base faces + return 10; + } + } + else { + //here it turns back, the points are taken in faces + //neither too close nor too far as much as possible. + Standard_Real u,v; +#ifdef DEB +// Standard_Real deport = 1000*BRep_Tool::Tolerance(E); +#endif + ChFi3d_Coefficient(dint1,DU1,DV1,u,v); + p2d1.SetX(p2d1.X() + u); p2d1.SetY(p2d1.Y() + v); + ChFi3d_Coefficient(dint1,DU2,DV2,u,v); + p2d2.SetX(p2d2.X() + u); p2d2.SetY(p2d2.Y() + v); + S1.D1(p2d1.X(),p2d1.Y(),pt1,DU1,DV1); + ns1 = DU1.Crossed(DV1); + S2.D1(p2d2.X(),p2d2.Y(),pt2,DU2,DV2); + ns2 = DU2.Crossed(DV2); + gp_Vec vref(pt1,pt2); + if(ns1.Dot(vref) < 0.){ + Or1 = TopAbs_REVERSED; + } + if(ns2.Dot(vref) > 0.){ + Or2 = TopAbs_REVERSED; + } + } + } + + + if (Or1 == TopAbs_FORWARD) { + if (Or2 == TopAbs_FORWARD) ChoixConge = 1; + else ChoixConge = 7; + } + else { + if (Or2 == TopAbs_FORWARD) ChoixConge = 3; + else ChoixConge = 5; + } + if ((ns1.Crossed(ns2)).Dot(tgE) >= 0.) ChoixConge++ ; + return ChoixConge; +} + +//======================================================================= +//function : NextSide +//purpose : +// +//======================================================================= + +Standard_Integer ChFi3d::NextSide(TopAbs_Orientation& Or1, + TopAbs_Orientation& Or2, + const TopAbs_Orientation OrSave1, + const TopAbs_Orientation OrSave2, + const Standard_Integer ChoixSave) +{ + if (Or1 == TopAbs_FORWARD){Or1 = OrSave1;} + else { + Or1 = TopAbs::Reverse(OrSave1); + } + if (Or2 == TopAbs_FORWARD){Or2 = OrSave2;} + else { + Or2 = TopAbs::Reverse(OrSave2); + } + + Standard_Integer ChoixConge; + if (Or1 == TopAbs_FORWARD) { + if (Or2 == TopAbs_FORWARD) ChoixConge = 1; + else { + if(ChoixSave < 0) ChoixConge = 3; + else ChoixConge = 7; + } + } + else { + if (Or2 == TopAbs_FORWARD) { + if(ChoixSave < 0) ChoixConge = 7; + else ChoixConge = 3; + } + else ChoixConge = 5; + } + if (Abs(ChoixSave)%2 == 0) ChoixConge++; + return ChoixConge; +} + + +//======================================================================= +//function : NextSide +//purpose : +// +//======================================================================= + +void ChFi3d::NextSide(TopAbs_Orientation& Or, + const TopAbs_Orientation OrSave, + const TopAbs_Orientation OrFace) +{ + if (Or == OrFace){Or = OrSave;} + else { + Or = TopAbs::Reverse(OrSave); + } +} + + + +//======================================================================= +//function : SameSide +//purpose : +// +//======================================================================= + +Standard_Boolean ChFi3d::SameSide(const TopAbs_Orientation Or, + const TopAbs_Orientation OrSave1, + const TopAbs_Orientation OrSave2, + const TopAbs_Orientation OrFace1, + const TopAbs_Orientation OrFace2) +{ + TopAbs_Orientation o1,o2; + if (Or == OrFace1){o1 = OrSave1;} + else { + o1 = TopAbs::Reverse(OrSave1); + } + if (Or == OrFace2){o2 = OrSave2;} + else { + o2 = TopAbs::Reverse(OrSave2); + } + return (o1 == o2); +} diff --git a/src/ChFi3d/ChFi3d_Builder.cdl b/src/ChFi3d/ChFi3d_Builder.cdl new file mode 100644 index 00000000..0c92d323 --- /dev/null +++ b/src/ChFi3d/ChFi3d_Builder.cdl @@ -0,0 +1,973 @@ +-- File: ChFi3d_Builder.cdl +-- Created: Tue Nov 9 17:40:22 1993 +-- Author: Laurent BOURESCHE +-- <lbo@zerox> +---Copyright: Matra Datavision 1993 + + + +deferred class Builder from ChFi3d + + ---Purpose: Root class for calculation of surfaces (fillets, + -- chamfers) destined to smooth edges of + -- a gap on a Shape and the reconstruction of the Shape. + +uses + Spine from ChFiDS, + ListOfStripe from ChFiDS, + SequenceOfSurfData from ChFiDS, + SurfData from ChFiDS, + Stripe from ChFiDS, + StripeMap from ChFiDS, + Map from ChFiDS, + CommonPoint from ChFiDS, + Regularities from ChFiDS, + HElSpine from ChFiDS, + ErrorStatus from ChFiDS, + HDataStructure from TopOpeBRepDS, + HBuilder from TopOpeBRepBuild, + AppFunction from Blend, + Function from Blend, + CSFunction from Blend, + FuncInv from Blend, + SurfRstFunction from Blend, + RstRstFunction from Blend, + SurfPointFuncInv from Blend, + SurfCurvFuncInv from Blend, + CurvPointFuncInv from Blend, + Approx from AppBlend, + Line from BRepBlend, + DataMapOfShapeListOfInteger from TopTools, + ListOfShape from TopTools, + Shape from TopoDS, + Face from TopoDS, + Edge from TopoDS, + Vertex from TopoDS, + State from TopAbs, + Orientation from TopAbs, + HCurve from Adaptor3d, + HCurve2d from Adaptor2d, + HSurface from Adaptor3d, + HCurve2d from BRepAdaptor, + Surface from BRepAdaptor, + HSurface from BRepAdaptor, + TopolTool from Adaptor3d, + TopolTool from BRepTopAdaptor, + Vector from math, + Shape from GeomAbs, + Surface from Geom, + Curve from Geom2d, + Pnt2d from gp + +raises + OutOfRange from Standard, + NoSuchObject from Standard, + ConstructionError from Standard + +is + + -- Construction and general data. + ------------------------------------- + + Delete(me:out) is virtual; + ---C++: alias "Standard_EXPORT virtual ~ChFi3d_Builder(){Delete() ; }" + + Initialize(S : Shape from TopoDS; Ta : Real from Standard); + + + SetParams(me : in out; + Tang, Tesp, T2d, TApp3d, TolApp2d, Fleche: Real from Standard); + + + SetContinuity(me : in out; + InternalContinuity : Shape from GeomAbs; + AngularTolerance : Real); + + + -- Acquisition and questioning on trajectories. + ------------------------------------------------------- + + Remove(me : in out; E : Edge from TopoDS) + ---Purpose: extracts from the list the contour containing edge E. + -- + is static; + + Contains(me;E : Edge from TopoDS) + ---Purpose: gives the number of the contour containing E or 0 + -- if E does not belong to any contour. + returns Integer from Standard + is static; + + Contains(me;E : Edge from TopoDS; IndexInSpine : out Integer from Standard) + ---Purpose: gives the number of the contour containing E or 0 + -- if E does not belong to any contour. + -- Sets in IndexInSpine the index of E in the contour if it's found + returns Integer from Standard + is static; + + NbElements(me) returns Integer is static; + ---Purpose: gives the number of disjoint contours on which + -- the fillets are calculated + + Value(me; I : Integer) returns Spine from ChFiDS + ---Purpose: gives the n'th set of edges (contour) + raises OutOfRange from Standard + ---Purpose: if I >NbElements() + is static; + + + Length(me; IC : Integer from Standard) returns Real from Standard + ---Purpose: returns the length of the contour of index IC. + is static; + + + FirstVertex(me;IC : Integer from Standard) + returns Vertex from TopoDS + ---Purpose: returns the First vertex V of + -- the contour of index IC. + is static; + + + LastVertex(me;IC : Integer from Standard) + returns Vertex from TopoDS + ---Purpose: returns the Last vertex V of + -- the contour of index IC. + is static; + + + Abscissa(me; + IC : Integer from Standard; + V : Vertex from TopoDS) + returns Real from Standard + ---Purpose: returns the abscissa of the vertex V on + -- the contour of index IC. + is static; + + + RelativeAbscissa(me; + IC : Integer from Standard; + V : Vertex from TopoDS) + returns Real from Standard + ---Purpose: returns the relative abscissa([0.,1.]) of the + -- vertex V on the contour of index IC. + is static; + + + ClosedAndTangent(me; IC : Integer from Standard) + returns Boolean from Standard + ---Purpose: returns true if the contour of index IC is closed + -- an tangent. + is static; + + + Closed(me; IC : Integer from Standard) + returns Boolean from Standard + ---Purpose: returns true if the contour of index IC is closed + is static; + + + -- Calculation and the restoration of results. + ---------------------------------------------- + + Compute(me : in out) + ---Purpose: general calculation of geometry on all edges, + -- topologic reconstruction. + is static; + + IsDone(me) returns Boolean from Standard is static; + ---Purpose: returns True if the computation is success + + Shape(me) returns Shape from TopoDS + ---Purpose: if (Isdone()) makes the result. + raises NoSuchObject from Standard + ---Purpose: if (!Isdone()) + is static; + + Generated(me : in out; EouV : Shape from TopoDS) + ---Purpose: Advanced function for the history + returns ListOfShape from TopTools + ---C++: return const & + is static; + + NbFaultyContours(me) + ---Purpose: Returns the number of contours on which the calculation + -- has failed. + returns Integer from Standard is static; + + FaultyContour(me; I : Integer from Standard) + ---Purpose: Returns the number of I'th contour on which the calculation + -- has failed. + returns Integer from Standard is static; + + NbComputedSurfaces(me; IC : Integer from Standard) + ---Purpose: Returns the number of surfaces calculated on the contour IC. + returns Integer from Standard is static; + + ComputedSurface(me; IC, IS : Integer from Standard) + ---Purpose: Returns the IS'th surface calculated on the contour IC. + returns Surface from Geom is static; + + NbFaultyVertices(me) + ---Purpose: Returns the number of vertices on which the calculation + -- has failed. + returns Integer from Standard is static; + + FaultyVertex(me; IV : Integer from Standard) + ---Purpose: Returns the IV'th vertex on which the calculation has failed. + returns Vertex from TopoDS is static; + + HasResult(me) returns Boolean from Standard is static; + ---Purpose: returns True if a partial result has been calculated + + BadShape(me) returns Shape from TopoDS + ---Purpose: if (HasResult()) returns partial result + raises NoSuchObject from Standard + ---Purpose: if (!HasResult()) + is static; + + StripeStatus(me;IC:Integer from Standard) returns ErrorStatus from ChFiDS + ---Purpose: for the stripe IC ,indication on the cause + -- of failure WalkingFailure,TwistedSurface,Error, Ok + is static; + + Reset(me : in out) + ---Purpose: Reset all results of compute and returns the algorythm + -- in the state of the last acquisition to + -- enable modification of contours or areas. + is static; + + Builder(me) returns HBuilder from TopOpeBRepBuild + ---Purpose: Returns the Builder of topologic operations. + is static; + + + ---pour implementation + ---------------------- + + --- Simulation + + SimulKPart(me; SD : mutable SurfData from ChFiDS) + is deferred protected; + + SimulSurf(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro : Boolean from Standard; + Forward : Boolean from Standard; + RecOnS1,RecOnS2 : Boolean from Standard; + Soldep : Vector from math; + Intf,Intl : in out Boolean from Standard) + returns Boolean + is deferred protected; + + SimulSurf(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + PC1 : HCurve2d from BRepAdaptor; + Sref1 : HSurface from BRepAdaptor; + PCref1 : HCurve2d from BRepAdaptor; + Decroch1 : out Boolean from Standard; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + Or2 : Orientation from TopAbs; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard; + Soldep : Vector from math) + is virtual protected; + + SimulSurf(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + Or1 : Orientation from TopAbs; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + PC2 : HCurve2d from BRepAdaptor; + Sref2 : HSurface from BRepAdaptor; + PCref2 : HCurve2d from BRepAdaptor; + Decroch2 : out Boolean from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard; + Soldep : Vector from math) + + is virtual protected; + + SimulSurf(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + PC1 : HCurve2d from BRepAdaptor; + Sref1 : HSurface from BRepAdaptor; + PCref1 : HCurve2d from BRepAdaptor; + Decroch1 : out Boolean from Standard; + Or1 : Orientation from TopAbs; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + PC2 : HCurve2d from BRepAdaptor; + Sref2 : HSurface from BRepAdaptor; + PCref2 : HCurve2d from BRepAdaptor; + Decroch2 : out Boolean from Standard; + Or2 : Orientation from TopAbs; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP1,RecRst1 : Boolean from Standard; + RecP2,RecRst2 : Boolean from Standard; + Soldep : Vector from math) + + is virtual protected; + + SimulData(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Lin : out Line from BRepBlend; + S1 : HSurface from Adaptor3d; + I1 : TopolTool from Adaptor3d; + S2 : HSurface from Adaptor3d; + I2 : TopolTool from Adaptor3d; + Func : in out Function from Blend; + FInv : in out FuncInv from Blend; + PFirst : Real from Standard; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + Soldep : Vector from math; + NbSecMin : Integer from Standard; + RecOnS1 : Boolean from Standard = Standard_False; + RecOnS2 : Boolean from Standard = Standard_False) + returns Boolean from Standard is static protected; + + SimulData(me : in out; + Data : in out SurfData from ChFiDS; + HGuide : HElSpine from ChFiDS; + Lin : in out Line from BRepBlend; + S1 : HSurface from Adaptor3d; + I1 : TopolTool from Adaptor3d; + S2 : HSurface from Adaptor3d; + PC2 : HCurve2d from Adaptor2d; + I2 : TopolTool from Adaptor3d; + Decroch : out Boolean from Standard; + Func : in out SurfRstFunction from Blend; + FInv : in out FuncInv from Blend; + FInvP : in out SurfPointFuncInv from Blend; + FInvC : in out SurfCurvFuncInv from Blend; + PFirst : Real from Standard; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First : in out Real from Standard; + Last : in out Real from Standard; + Soldep : Vector from math; + NbSecMin : Integer from Standard; + Inside : Boolean from Standard; + Appro : Boolean from Standard; + Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard) + returns Boolean from Standard is static protected; + + + SimulData(me : in out; + Data : in out SurfData from ChFiDS; + HGuide : HElSpine from ChFiDS; + Lin : in out Line from BRepBlend; + S1 : HSurface from Adaptor3d; + PC1 : HCurve2d from Adaptor2d; + I1 : TopolTool from Adaptor3d; + Decroch1 : out Boolean from Standard; + S2 : HSurface from Adaptor3d; + PC2 : HCurve2d from Adaptor2d; + I2 : TopolTool from Adaptor3d; + Decroch2 : out Boolean from Standard; + Func : in out RstRstFunction from Blend; + FInv1 : in out SurfCurvFuncInv from Blend; + FInvP1 : in out CurvPointFuncInv from Blend; + FInv2 : in out SurfCurvFuncInv from Blend; + FInvP2 : in out CurvPointFuncInv from Blend; + PFirst : Real from Standard; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First : in out Real from Standard; + Last : in out Real from Standard; + Soldep : Vector from math; + NbSecMin : Integer from Standard; + Inside : Boolean from Standard; + Appro : Boolean from Standard; + Forward : Boolean from Standard; + RecP1, RecRst1 : Boolean from Standard; + RecP2, RecRst2 : Boolean from Standard) + returns Boolean from Standard is static protected; + + --- Calcul veritable + + SetRegul(me : in out) is deferred protected; + + FaceTangency(me ;E0,E1 : Edge from TopoDS; V : Vertex from TopoDS) + returns Boolean + is static private; + + PerformElement(me : in out ;CElement : Spine) + returns Boolean from Standard + is static protected; + + PerformExtremity(me : in out ;CElement : Spine) + is static protected; + + PerformSetOfSurf(me : in out; + S : in out Stripe from ChFiDS; + Simul : Boolean from Standard = Standard_False) + is static protected; + + PerformSetOfKPart(me : in out; + S : in out Stripe from ChFiDS; + Simul : Boolean from Standard = Standard_False) + is static protected; + + PerformSetOfKGen(me : in out; + S : in out Stripe from ChFiDS; + Simul : Boolean from Standard = Standard_False) + is static protected; + + PerformSetOfSurfOnElSpine + (me : in out; + ES : HElSpine from ChFiDS; + St : in out Stripe from ChFiDS; + It1,It2 : in out TopolTool from BRepTopAdaptor; + Simul : Boolean from Standard = Standard_False) + is static private; + + Trunc(me : in out; + SD : SurfData from ChFiDS; + Spine : Spine from ChFiDS; + S1 : HSurface from Adaptor3d; + S2 : HSurface from Adaptor3d; + iedge : Integer from Standard; + isfirst : Boolean from Standard; + cntlFiOnS : Integer from Standard) -- eap, occ354 + is static protected; + + SplitKPart(me : in out; + Data : SurfData from ChFiDS; + SetData : out SequenceOfSurfData from ChFiDS; + Spine : Spine from ChFiDS; + Iedge : Integer from Standard; + S1 : HSurface from Adaptor3d; + I1 : TopolTool from Adaptor3d; + S2 : HSurface from Adaptor3d; + I2 : TopolTool from Adaptor3d; + Intf,Intl : in out Boolean from Standard) + + returns Boolean from Standard is static; + ---Purpose: Method, implemented in the inheritants, calculates + -- the elements of construction of the surface (fillet or + -- chamfer). + + CallPerformSurf(me : in out; + Stripe : in out Stripe from ChFiDS; + Simul : Boolean from Standard; + SeqSD : in out SequenceOfSurfData from ChFiDS; + SD : in out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + HS1, HS3 : HSurface from BRepAdaptor; + P1, P3 : Pnt2d from gp; + I1 : in out TopolTool from Adaptor3d; + HS2, HS4 : HSurface from BRepAdaptor; + P2, P4 : Pnt2d from gp; + I2 : in out TopolTool from Adaptor3d; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro : Boolean from Standard; + Forward : Boolean from Standard; + RecOnS1,RecOnS2 : Boolean from Standard; + Soldep : in out Vector from math; + Intf,Intl : in out Boolean from Standard; + Surf1,Surf2 : in out HSurface from BRepAdaptor) + is protected; + + PerformSurf(me : in out; + Data : out SequenceOfSurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro : Boolean from Standard; + Forward : Boolean from Standard; + RecOnS1,RecOnS2 : Boolean from Standard; + Soldep : Vector from math; + Intf,Intl : in out Boolean from Standard) + returns Boolean + is deferred protected; + ---Purpose: Method, implemented in the inheritants, calculating + -- elements of construction of the surface (fillet or + -- chamfer). + + PerformSurf(me : in out; + Data : out SequenceOfSurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + PC1 : HCurve2d from BRepAdaptor; + Sref1 : HSurface from BRepAdaptor; + PCref1 : HCurve2d from BRepAdaptor; + Decroch1 : out Boolean from Standard; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + Or2 : Orientation from TopAbs; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard; + Soldep : Vector from math) + + is virtual protected; + ---Purpose: Method, implemented in inheritants, calculates + -- the elements of construction of the surface (fillet + -- or chamfer) contact edge/face. + + PerformSurf(me : in out; + Data : out SequenceOfSurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + Or1 : Orientation from TopAbs; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + PC2 : HCurve2d from BRepAdaptor; + Sref2 : HSurface from BRepAdaptor; + PCref2 : HCurve2d from BRepAdaptor; + Decroch2 : out Boolean from Standard; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard; + Soldep : Vector from math) + + is virtual protected; + ---Purpose: Method, implemented in inheritants, calculates + -- the elements of construction of the surface (fillet + -- or chamfer) contact edge/face. + + PerformSurf(me : in out; + Data : out SequenceOfSurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + PC1 : HCurve2d from BRepAdaptor; + Sref1 : HSurface from BRepAdaptor; + PCref1 : HCurve2d from BRepAdaptor; + Decroch1 : out Boolean from Standard; + Or1 : Orientation from TopAbs; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + PC2 : HCurve2d from BRepAdaptor; + Sref2 : HSurface from BRepAdaptor; + PCref2 : HCurve2d from BRepAdaptor; + Decroch2 : out Boolean from Standard; + Or2 : Orientation from TopAbs; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP1,RecRst1 : Boolean from Standard; + RecP2,RecRst2 : Boolean from Standard; + Soldep : Vector from math) + + is virtual protected; + ---Purpose: Method, implemented in inheritants, calculates + -- the elements of construction of the surface (fillet + -- or chamfer) contact edge/edge. + + PerformFilletOnVertex(me : in out; + Index: Integer from Standard) + is static private; + + PerformSingularCorner(me : in out ; + Index : Integer from Standard) + is static private; + + PerformOneCorner(me : in out ; + Index : Integer from Standard; + PrepareOnSame : Boolean from Standard = Standard_False) + is static private; + + IntersectMoreCorner(me : in out ; + Index : Integer from Standard) + is static private; + + PerformMoreSurfdata(me : in out ; + Index : Integer from Standard) + is static private; + + PerformTwoCornerbyInter(me : in out ; + Index : Integer from Standard) + returns Integer + is static; + + PerformTwoCorner(me : in out ; + Index : Integer from Standard) + is deferred protected; + + + PerformThreeCorner(me : in out ; + Index : Integer from Standard) + is deferred protected; + + PerformMoreThreeCorner(me : in out ; + Index : Integer from Standard; + nbcourb : Integer from Standard) + is static protected; + + PerformIntersectionAtEnd (me : in out ; + Index : Integer from Standard) + is static private; + + ExtentAnalyse(me : in out) + is static private; + + ExtentOneCorner(me : in out; + V : Vertex from TopoDS; + S : Stripe from ChFiDS) + is deferred protected; + + ExtentTwoCorner(me : in out; + V : Vertex from TopoDS; + LS : ListOfStripe from ChFiDS) + is deferred protected; + + ExtentThreeCorner(me : in out; + V : Vertex from TopoDS; + LS : ListOfStripe from ChFiDS) + is deferred protected; + + FindFace(me; + V : Vertex from TopoDS; + P1,P2 : CommonPoint from ChFiDS; + Fv : out Face from TopoDS) + returns Boolean from Standard + is static private; + + FindFace(me; + V : Vertex from TopoDS; + P1,P2 : CommonPoint from ChFiDS; + Fv : out Face from TopoDS; + Favoid: Face from TopoDS) + returns Boolean from Standard + is static private; + + MoreSurfdata(me; + Index : Integer from Standard ) + returns Boolean from Standard + is static private; + + StartSol(me; + Spine : Spine from ChFiDS; + HS : in out HSurface from BRepAdaptor; + P : in out Pnt2d from gp; + HC : in out HCurve2d from BRepAdaptor; + W : in out Real from Standard; + SD : SurfData from ChFiDS; + isFirst : Boolean from Standard; + OnS : Integer from Standard; + HSref : in out HSurface from BRepAdaptor; + HCref : in out HCurve2d from BRepAdaptor; + RecP : out Boolean from Standard; + RecS : out Boolean from Standard; + RecRst : out Boolean from Standard; + C1Obst : out Boolean from Standard; + HSbis : in out HSurface from BRepAdaptor; + Pbis : in out Pnt2d from gp; + Decroch : Boolean from Standard; + Vref : Vertex from TopoDS) + returns Boolean from Standard + is static private; + + StartSol(me; + S : Stripe from ChFiDS; + HGuide : HElSpine from ChFiDS; + HS1,HS2 : in out HSurface from BRepAdaptor; + I1,I2 : in out TopolTool from BRepTopAdaptor; + P1,P2 : in out Pnt2d from gp; + First : in out Real from Standard) + is static private; + + PerformFirstSection(me ; + S : Spine from ChFiDS; + HGuide : HElSpine from ChFiDS; + Choix : Integer from Standard; + S1,S2 : in out HSurface from BRepAdaptor; + I1,I2 : TopolTool from Adaptor3d; + Par : Real from Standard; + SolDep : in out Vector from math; + Pos1,Pos2 : out State from TopAbs) + returns Boolean from Standard + is deferred protected; + + SearchFace(me; + Sp : Spine from ChFiDS; + Pc : CommonPoint from ChFiDS; + FRef : Face from TopoDS; + FVoi : out Face from TopoDS) + returns Boolean from Standard + is static protected; + + ConexFaces(me; + Sp : Spine from ChFiDS; + IEdge : Integer from Standard; + RefChoix : Integer from Standard; + HS1,HS2 : out HSurface from BRepAdaptor) + is static private; + + StripeOrientations(me; + Sp : Spine from ChFiDS; + Or1,Or2 : out Orientation from TopAbs; + ChoixConge : out Integer from Standard) + returns Boolean from Standard is static protected; + + ComputeData(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Lin : out Line from BRepBlend; + S1 : HSurface from Adaptor3d; + I1 : TopolTool from Adaptor3d; + S2 : HSurface from Adaptor3d; + I2 : TopolTool from Adaptor3d; + Func : in out Function from Blend; + FInv : in out FuncInv from Blend; + PFirst : Real from Standard; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro : Boolean from Standard; + Forward : Boolean from Standard; + Soldep : Vector from math; + Intf,Intl : in out Boolean from Standard; + Gd1,Gd2,Gf1,Gf2 : out Boolean from Standard; + RecOnS1 : Boolean from Standard = Standard_False; + RecOnS2 : Boolean from Standard = Standard_False) + ---Purpose: Calculates a Line of contact face/face. + returns Boolean from Standard is static protected; + + ComputeData(me : in out; + Data : in out SurfData from ChFiDS; + HGuide : HElSpine from ChFiDS; + Lin : in out Line from BRepBlend; + S1 : HSurface from Adaptor3d; + I1 : TopolTool from Adaptor3d; + S2 : HSurface from Adaptor3d; + PC2 : HCurve2d from Adaptor2d; + I2 : TopolTool from Adaptor3d; + Decroch : out Boolean from Standard; + Func : in out SurfRstFunction from Blend; + FInv : in out FuncInv from Blend; + FInvP : in out SurfPointFuncInv from Blend; + FInvC : in out SurfCurvFuncInv from Blend; + PFirst : Real from Standard; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First : in out Real from Standard; + Last : in out Real from Standard; + Soldep : Vector from math; + Inside : Boolean from Standard; + Appro : Boolean from Standard; + Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard) + ---Purpose: Calculates a Line of contact edge/face. + returns Boolean from Standard is static protected; + + + ComputeData(me : in out; + Data : in out SurfData from ChFiDS; + HGuide : HElSpine from ChFiDS; + Lin : in out Line from BRepBlend; + S1 : HSurface from Adaptor3d; + PC1 : HCurve2d from Adaptor2d; + I1 : TopolTool from Adaptor3d; + Decroch1 : out Boolean from Standard; + S2 : HSurface from Adaptor3d; + PC2 : HCurve2d from Adaptor2d; + I2 : TopolTool from Adaptor3d; + Decroch2 : out Boolean from Standard; + Func : in out RstRstFunction from Blend; + FInv1 : in out SurfCurvFuncInv from Blend; + FInvP1 : in out CurvPointFuncInv from Blend; + FInv2 : in out SurfCurvFuncInv from Blend; + FInvP2 : in out CurvPointFuncInv from Blend; + PFirst : Real from Standard; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First : in out Real from Standard; + Last : in out Real from Standard; + Soldep : Vector from math; + Inside : Boolean from Standard; + Appro : Boolean from Standard; + Forward : Boolean from Standard; + RecP1, RecRst1 : Boolean from Standard; + RecP2, RecRst2 : Boolean from Standard) + ---Purpose: Calculates a Line of contact edge/edge. + returns Boolean from Standard is static protected; + + + CompleteData(me : in out; + Data : in out SurfData from ChFiDS; + Func : in out Function from Blend; + Lin : in out Line from BRepBlend; + S1 : HSurface from Adaptor3d; + S2 : HSurface from Adaptor3d; + Or1 : Orientation from TopAbs; + Gd1,Gd2,Gf1,Gf2 : Boolean from Standard; + Reversed : Boolean from Standard = Standard_False) + returns Boolean from Standard is static protected; + + CompleteData(me : in out; + Data : in out SurfData from ChFiDS; + Func : in out SurfRstFunction from Blend; + Lin : in out Line from BRepBlend; + S1 : HSurface from Adaptor3d; + S2 : HSurface from Adaptor3d; + Or : Orientation from TopAbs; + Reversed : Boolean from Standard) + returns Boolean from Standard is static protected; + + CompleteData(me : in out; + Data : in out SurfData from ChFiDS; + Func : in out RstRstFunction from Blend; + Lin : in out Line from BRepBlend; + S1 : HSurface from Adaptor3d; + S2 : HSurface from Adaptor3d; + Or : Orientation from TopAbs) + returns Boolean from Standard is static protected; + + + + StoreData(me : in out; + Data : in out SurfData from ChFiDS; + Approx : Approx from AppBlend; + Lin : Line from BRepBlend; + S1 : HSurface from Adaptor3d; + S2 : HSurface from Adaptor3d; + Or1 : Orientation from TopAbs; + Gd1,Gd2,Gf1,Gf2 : Boolean from Standard; + Reversed : Boolean from Standard = Standard_False) + returns Boolean from Standard is static protected; + + CompleteData(me : in out; + Data : in out SurfData from ChFiDS; + Surfcoin : Surface from Geom; + S1 : HSurface from Adaptor3d; + PC1 : Curve from Geom2d; + S2 : HSurface from Adaptor3d; + PC2 : Curve from Geom2d; + Or : Orientation from TopAbs; + On1 : Boolean from Standard; + Gd1,Gd2,Gf1,Gf2 : Boolean from Standard) + returns Boolean from Standard is static protected; + +fields + +-- Input part +myShape : Shape from TopoDS; + +-- Numeric data (tolerances) NOTE : suspend tol2d!!! +angular : Real from Standard; -- tangency of edges +tolappangle : Real from Standard is protected; -- angular approximation +tolesp : Real from Standard is protected; -- confusion 3d : def 1.e-4 +tol2d : Real from Standard is protected; -- confusion 2d : def 1.e-5 +tolapp3d : Real from Standard is protected; -- approx 3d : def 1.e-4 +tolapp2d : Real from Standard is protected; -- approx 2d : def 1.e-5 +fleche : Real from Standard is protected; -- vector of walking : def 1.e-6 + +-- Continuity for the approximated geometry +myConti : Shape from GeomAbs is protected; + +-- Maps of back-pointers to work +myEFMap : Map from ChFiDS is protected; +myESoMap : Map from ChFiDS is protected; +myEShMap : Map from ChFiDS is protected; +myVFMap : Map from ChFiDS is protected; +myVEMap : Map from ChFiDS is protected; + +-- Tools of storage and reconstruction +myDS : HDataStructure from TopOpeBRepDS is protected; +myCoup : HBuilder from TopOpeBRepBuild is protected; + +-- Tools of internal storage +myListStripe : ListOfStripe from ChFiDS is protected; +myVDataMap : StripeMap from ChFiDS is protected; +myRegul : Regularities from ChFiDS is protected; + +-- Stripes the calculation which of hangs +badstripes : ListOfStripe from ChFiDS is protected; + +-- Vertexes in the neighborhood which of the finition hangs +badvertices : ListOfShape from TopTools is protected; + +-- Data calculated during the computation for the history +myGenerated : ListOfShape from TopTools; +myEVIMap : DataMapOfShapeListOfInteger from TopTools is protected; + +-- flag if all has passed well +done : Boolean from Standard is protected; + +-- result +myShapeResult : Shape from TopoDS; + +-- flag there is partial result (badshape) +hasresult : Boolean from Standard is protected; + +-- eventual partial result +badShape : Shape from TopoDS; + + +end Builder; diff --git a/src/ChFi3d/ChFi3d_Builder.cxx b/src/ChFi3d/ChFi3d_Builder.cxx new file mode 100644 index 00000000..39892b33 --- /dev/null +++ b/src/ChFi3d/ChFi3d_Builder.cxx @@ -0,0 +1,814 @@ +// File: ChFi3d_Builder.cxx +// Created: Thu Nov 18 15:59:35 1993 +// Author: Isabelle GRIGNON +// <isg@zerox> + + +#include <ChFi3d_Builder.ixx> + +#include <Standard_Failure.hxx> +#include <Standard_NoSuchObject.hxx> +#include <Standard_NotImplemented.hxx> +#include <Standard_ErrorHandler.hxx> +#include <TColStd_MapIteratorOfMapOfInteger.hxx> +#include <TColStd_MapOfInteger.hxx> +#include <TColStd_ListIteratorOfListOfInteger.hxx> + +#include <TopoDS.hxx> +#include <TopoDS_Shape.hxx> +#include <TopoDS_Face.hxx> +#include <TopoDS_Edge.hxx> +#include <TopoDS_Vertex.hxx> + +#include <TopAbs.hxx> +#include <TopAbs_ShapeEnum.hxx> +#include <TopAbs_Orientation.hxx> +#include <BRep_Builder.hxx> +#include <BRep_Tool.hxx> +#include <TopExp.hxx> +#include <TopExp_Explorer.hxx> +#include <TopTools_ListOfShape.hxx> +#include <TopTools_ListIteratorOfListOfShape.hxx> + +#include <TopOpeBRepDS_CurveExplorer.hxx> +#include <TopOpeBRepDS_CurvePointInterference.hxx> +#include <TopOpeBRepDS_DataStructure.hxx> +#include <TopOpeBRepDS_BuildTool.hxx> +#include <TopOpeBRepDS_Curve.hxx> +#include <TopOpeBRepDS_PointIterator.hxx> +#include <TopTools_ListIteratorOfListOfShape.hxx> + +#include <BRep_Tool.hxx> +#include <ChFiDS_Stripe.hxx> +#include <ChFiDS_ListIteratorOfListOfStripe.hxx> +#include <ChFiDS_SequenceOfSurfData.hxx> +#include <ChFiDS_HData.hxx> + +#include <ChFi3d.hxx> + +#include <ChFi3d_Builder_0.hxx> +#include <TopOpeBRepDS_ListOfInterference.hxx> + + +#ifdef DRAW +#include <TestTopOpeTools.hxx> +#include <TestTopOpe.hxx> +#endif +#ifdef DEB +#include <OSD_Chronometer.hxx> + +// variables for performances + + +OSD_Chronometer cl_total,cl_extent,cl_perfsetofsurf,cl_perffilletonvertex, +cl_filds,cl_reconstruction,cl_setregul,cl_perform1corner,cl_perform2corner, +cl_performatend,cl_perform3corner,cl_performmore3corner; + +Standard_EXPORT Standard_Real t_total, t_extent,t_perfsetofsurf, +t_perffilletonvertex, t_filds,t_reconstruction,t_setregul, t_perfsetofkgen, +t_perfsetofkpart,t_makextremities,t_performatend,t_startsol,t_performsurf, +t_perform1corner,t_perform2corner,t_perform3corner,t_performmore3corner, +t_batten,t_inter,t_sameinter,t_same,t_plate,t_approxplate,t_t2cornerinit, +t_perf2cornerbyinter,t_chfikpartcompdata,t_cheminement,t_remplissage, +t_t3cornerinit ,t_spherique,t_torique, t_notfilling,t_filling,t_sameparam, +t_computedata,t_completedata,t_t2cornerDS,t_t3cornerDS; + +//Standard_IMPORT extern void ChFi3d_InitChron(OSD_Chronometer& ch); +Standard_IMPORT void ChFi3d_InitChron(OSD_Chronometer& ch); +//Standard_IMPORT extern void ChFi3d_ResultChron(OSD_Chronometer & ch, +Standard_IMPORT void ChFi3d_ResultChron(OSD_Chronometer & ch, + Standard_Real& time); +extern Standard_Boolean ChFi3d_GettraceCHRON(); +#endif + + +//======================================================================= +//function : CompleteDS +//purpose : +//======================================================================= + +static void CompleteDS(TopOpeBRepDS_DataStructure& DStr, + const TopoDS_Shape& S) +{ + ChFiDS_Map MapEW,MapFS; + MapEW.Fill(S,TopAbs_EDGE,TopAbs_WIRE); + MapFS.Fill(S,TopAbs_FACE,TopAbs_SHELL); + + TopExp_Explorer ExpE; + for (ExpE.Init(S,TopAbs_EDGE); ExpE.More(); ExpE.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(ExpE.Current()); + Standard_Boolean hasgeom = DStr.HasGeometry(E); + if (hasgeom) { + const TopTools_ListOfShape& WireListAnc = MapEW(E); + TopTools_ListIteratorOfListOfShape itaW(WireListAnc); + while (itaW.More()) { + const TopoDS_Shape& WireAnc = itaW.Value(); + DStr.AddShape(WireAnc); + itaW.Next(); + } + } + } + + TopExp_Explorer ExpF; + for (ExpF.Init(S,TopAbs_FACE); ExpF.More(); ExpF.Next()) { + const TopoDS_Face& F = TopoDS::Face(ExpF.Current()); + Standard_Boolean hasgeom = DStr.HasGeometry(F); + if (hasgeom) { + const TopTools_ListOfShape& ShellListAnc = MapFS(F); + TopTools_ListIteratorOfListOfShape itaS(ShellListAnc); + while (itaS.More()) { + const TopoDS_Shape& ShellAnc = itaS.Value(); + DStr.AddShape(ShellAnc); + itaS.Next(); + } + } + } + + // set the range on the DS Curves + for (Standard_Integer ic = 1; ic <= DStr.NbCurves(); ic++) { + Standard_Real parmin = RealLast(), parmax = RealFirst(); + const TopOpeBRepDS_ListOfInterference& LI = DStr.CurveInterferences(ic); + for (TopOpeBRepDS_PointIterator it(LI); + it.More(); + it.Next() ) { + Standard_Real par = it.Parameter(); + parmin = Min (parmin,par); parmax = Max (parmax,par); + } + DStr.ChangeCurve(ic).SetRange(parmin,parmax); + } +} + +void ChFi3d_Builder::Delete() +{} + +//======================================================================= +//function : ExtentAnalyse +//purpose : +//======================================================================= + +void ChFi3d_Builder::ExtentAnalyse () +{ + Standard_Integer nbedges, nbs; + for (Standard_Integer iv = 1; iv <= myVDataMap.Extent(); iv++) { + nbs = myVDataMap(iv).Extent(); + const TopoDS_Vertex& Vtx = myVDataMap.FindKey(iv); + nbedges = ChFi3d_NumberOfEdges(Vtx, myVEMap); + switch (nbs) { + case 1 : + ExtentOneCorner(Vtx, myVDataMap.FindFromIndex(iv).First()); + break; + case 2 : + if (nbedges <= 3) + ExtentTwoCorner(Vtx, myVDataMap.FindFromIndex(iv)); + break; + case 3 : + if (nbedges <= 3) + ExtentThreeCorner(Vtx, myVDataMap.FindFromIndex(iv)); + break; + default : + break; + } + } +} + +//======================================================================= +//function : Compute +//purpose : +//======================================================================= + +void ChFi3d_Builder::Compute() +{ + +#ifdef DEB //perf + t_total=0;t_extent=0; t_perfsetofsurf=0;t_perffilletonvertex=0; + t_filds=0;t_reconstruction=0;t_setregul=0; + t_perfsetofkpart=0; t_perfsetofkgen=0;t_makextremities=0; + t_performsurf=0;t_startsol=0; t_perform1corner=0;t_perform2corner=0; + t_perform3corner=0;t_performmore3corner=0;t_inter=0;t_same=0;t_sameinter=0; + t_plate=0;t_approxplate=0; t_batten=0;t_remplissage=0;t_t3cornerinit=0; + t_spherique=0;t_torique=0;t_notfilling=0;t_filling=0;t_performatend=0; + t_t2cornerinit=0; t_perf2cornerbyinter=0;t_chfikpartcompdata=0; + t_cheminement=0; t_sameparam=0; t_computedata=0;t_completedata=0; + t_t2cornerDS=0;t_t3cornerDS=0; + ChFi3d_InitChron(cl_total); + ChFi3d_InitChron(cl_extent); +#endif + + if (myListStripe.IsEmpty()) + Standard_Failure::Raise("There are no suitable edges for chamfer or fillet"); + + Reset(); + myDS = new TopOpeBRepDS_HDataStructure(); + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + done = Standard_True; + hasresult=Standard_False; +#ifdef DRAW + TestTopOpe::CurrentDS(myDS); + TopoDS_Shape bids; + TestTopOpe::Shapes(myShape,bids); +#endif + + // filling of myVDatatMap + ChFiDS_ListIteratorOfListOfStripe itel; + + for (itel.Initialize(myListStripe);itel.More(); itel.Next()) { + if ((itel.Value()->Spine()->FirstStatus() <= ChFiDS_BreakPoint)) + myVDataMap.Add(itel.Value()->Spine()->FirstVertex(),itel.Value()); + else if (itel.Value()->Spine()->FirstStatus() == ChFiDS_FreeBoundary) + ExtentOneCorner(itel.Value()->Spine()->FirstVertex(),itel.Value()); + if ((itel.Value()->Spine()->LastStatus() <= ChFiDS_BreakPoint)) + myVDataMap.Add(itel.Value()->Spine()->LastVertex() ,itel.Value()); + else if (itel.Value()->Spine()->LastStatus() == ChFiDS_FreeBoundary) + ExtentOneCorner(itel.Value()->Spine()->LastVertex(),itel.Value()); + } + // preanalysis to evaluate the extensions. + ExtentAnalyse(); + + +#ifdef DEB //perf + ChFi3d_ResultChron(cl_extent,t_extent); + ChFi3d_InitChron(cl_perfsetofsurf); +#endif + + // Construction of the stripe of fillet on each stripe. + for (itel.Initialize(myListStripe);itel.More(); itel.Next()) { + itel.Value()->Spine()->SetErrorStatus(ChFiDS_Ok); + try { + OCC_CATCH_SIGNALS + PerformSetOfSurf(itel.Value()); + } + catch(Standard_Failure) { + Handle(Standard_Failure) exc = Standard_Failure::Caught(); +#ifdef DEB + cout <<"EXCEPTION Stripe compute " << exc << endl; +#endif + badstripes.Append(itel.Value()); + done = Standard_True; + if (itel.Value()->Spine()->ErrorStatus()==ChFiDS_Ok) + itel.Value()->Spine()->SetErrorStatus(ChFiDS_Error); + } + if (!done) badstripes.Append(itel.Value()); + done = Standard_True; + } + done = (badstripes.IsEmpty()); + +#ifdef DEB //perf + ChFi3d_ResultChron(cl_perfsetofsurf,t_perfsetofsurf); + ChFi3d_InitChron(cl_perffilletonvertex); +#endif + + //construct fillets on each vertex + feed the Ds + if (done) { + //Standard_Integer nbresult=0; +// for (Standard_Integer j=1;j<=myVDataMap.Extent();j++) { +#ifndef DEB + static +#endif //to avoid Linux warning:<< variable `j' might be clobbered by `longjmp' or `vfork' >> + Standard_Integer j; + for (j=1;j<=myVDataMap.Extent();j++) { + try { + OCC_CATCH_SIGNALS + PerformFilletOnVertex(j); + } + catch(Standard_Failure) { + Handle(Standard_Failure) exc = Standard_Failure::Caught(); +#ifdef DEB + cout <<"EXCEPTION Corner compute " << exc << endl; +#endif + badvertices.Append(myVDataMap.FindKey(j)); + hasresult=Standard_False; + done = Standard_True; + } + if (!done) badvertices.Append(myVDataMap.FindKey(j)); + done = Standard_True; + } + if (!hasresult) done = badvertices.IsEmpty(); + } + + +#ifdef DEB //perf + ChFi3d_ResultChron(cl_perffilletonvertex,t_perffilletonvertex); + ChFi3d_InitChron(cl_filds); +#endif + + TColStd_MapOfInteger MapIndSo; + TopExp_Explorer expso(myShape,TopAbs_SOLID); + for(; expso.More(); expso.Next()){ + const TopoDS_Shape& cursol = expso.Current(); + Standard_Integer indcursol = DStr.AddShape(cursol); + MapIndSo.Add(indcursol); + } + TopExp_Explorer expsh(myShape,TopAbs_SHELL,TopAbs_SOLID); + for(; expsh.More(); expsh.Next()){ + const TopoDS_Shape& cursh = expsh.Current(); + Standard_Integer indcursh = DStr.AddShape(cursh); + MapIndSo.Add(indcursh); + } + if (done) { + Standard_Integer i1; + for (itel.Initialize(myListStripe), i1=0; + itel.More(); + itel.Next(), i1++) { + const Handle(ChFiDS_Stripe)& st = itel.Value(); + // 05/02/02 akm vvv : (OCC119) First we'll check ain't there + // intersections between fillets + ChFiDS_ListIteratorOfListOfStripe itel1; + Standard_Integer i2; + for (itel1.Initialize(myListStripe), i2=0; + itel1.More(); + itel1.Next(), i2++) { + if (i2 <= i1) + // Do not twice intersect the stripes + continue; + Handle(ChFiDS_Stripe) aCheckStripe = itel1.Value(); + try { + OCC_CATCH_SIGNALS + ChFi3d_StripeEdgeInter (st, aCheckStripe, DStr, tol2d); + } + catch(Standard_Failure) { + Handle(Standard_Failure) exc = Standard_Failure::Caught(); +#ifdef DEB + cout <<"EXCEPTION Fillets compute " << exc << endl; +#endif + badstripes.Append(itel.Value()); + hasresult=Standard_False; + done = Standard_False; + break; + } + } + // 05/02/02 akm ^^^ + Standard_Integer solidindex = st->SolidIndex(); + ChFi3d_FilDS(solidindex,st,DStr,myRegul,tolesp,tol2d); + if (!done) break; + } + +#ifdef DEB //perf + ChFi3d_ResultChron(cl_filds,t_filds); + ChFi3d_InitChron(cl_reconstruction); +#endif + + + if (done) { + BRep_Builder B1; + CompleteDS(DStr,myShape); + //Update tolerances on vertex to max adjacent edges or + //Update tolerances on degenerated edge to max of adjacent vertexes. + TopOpeBRepDS_CurveExplorer cex(DStr); + for(;cex.More();cex.Next()){ + TopOpeBRepDS_Curve& c = *((TopOpeBRepDS_Curve*)(void*)&(cex.Curve())); + Standard_Real tolc = 0.; + Standard_Boolean degen = c.Curve().IsNull(); + if(!degen) tolc = c.Tolerance(); + Standard_Integer ic = cex.Index(); + TopOpeBRepDS_PointIterator It(myDS->CurvePoints(ic)); + for(;It.More();It.Next()){ + Handle(TopOpeBRepDS_CurvePointInterference) II; + II = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(It.Value()); + if (II.IsNull()) continue; + TopOpeBRepDS_Kind gk = II->GeometryType(); + Standard_Integer gi = II->Geometry(); + if(gk == TopOpeBRepDS_VERTEX){ + const TopoDS_Vertex& v = TopoDS::Vertex(myDS->Shape(gi)); + Standard_Real tolv = BRep_Tool::Tolerance(v); + if( tolv > 0.0001 ) { + tolv += 0.0003; + if( tolc < tolv ) tolc = tolv + 0.00001; + } + if(degen && tolc < tolv) tolc = tolv; + else if(tolc>tolv) B1.UpdateVertex(v,tolc); + } + else if(gk == TopOpeBRepDS_POINT){ + TopOpeBRepDS_Point& p = DStr.ChangePoint(gi); + Standard_Real tolp = p.Tolerance(); + if(degen && tolc < tolp) tolc = tolp; + else if(tolc>tolp) p.Tolerance(tolc); + } + } + if(degen) c.Tolerance(tolc); + } + myCoup->Perform(myDS); + TColStd_MapIteratorOfMapOfInteger It(MapIndSo); + for(; It.More(); It.Next()){ + Standard_Integer indsol = It.Key(); + const TopoDS_Shape& curshape = DStr.Shape(indsol); + myCoup->MergeSolid(curshape,TopAbs_IN); + } + + Standard_Integer i=1,n=DStr.NbShapes(); + for (;i<=n;i++) { + const TopoDS_Shape S = DStr.Shape(i); + if (S.ShapeType() != TopAbs_EDGE) continue; + Standard_Boolean issplitIN = myCoup->IsSplit(S,TopAbs_IN); + if ( !issplitIN ) continue; + TopTools_ListIteratorOfListOfShape it(myCoup->Splits(S,TopAbs_IN)); + for (; it.More(); it.Next() ) { + const TopoDS_Edge& newE = TopoDS::Edge(it.Value()); + Standard_Real tole = BRep_Tool::Tolerance(newE); + TopExp_Explorer exv(newE,TopAbs_VERTEX); + for (; exv.More(); exv.Next() ) { + const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current()); + Standard_Real tolv = BRep_Tool::Tolerance(v); + if (tole>tolv) B1.UpdateVertex(v,tole); + } + } + } + if (!hasresult) { + B1.MakeCompound(TopoDS::Compound(myShapeResult)); + for(It.Reset(); It.More(); It.Next()){ + Standard_Integer indsol = It.Key(); + const TopoDS_Shape& curshape = DStr.Shape(indsol); + TopTools_ListIteratorOfListOfShape + its = myCoup->Merged(curshape,TopAbs_IN); + if(!its.More()) B1.Add(myShapeResult,curshape); + else { + //If the old type of Shape is Shell, Shell is placed instead of Solid, + //However there is a problem for compound of open Shell. + while (its.More()) { + const TopAbs_ShapeEnum letype = curshape.ShapeType(); + if (letype == TopAbs_SHELL){ + TopExp_Explorer expsh2(its.Value(),TopAbs_SHELL); + const TopoDS_Shape& cursh = expsh2.Current(); + TopoDS_Shape tt = cursh; + B1.Add(myShapeResult,cursh); + its.Next(); + } + else { + B1.Add(myShapeResult,its.Value()); + its.Next(); + } + } + } + } + } + else { + done=Standard_False; + B1.MakeCompound(TopoDS::Compound(badShape)); + for(It.Reset(); It.More(); It.Next()){ + Standard_Integer indsol = It.Key(); + const TopoDS_Shape& curshape = DStr.Shape(indsol); + TopTools_ListIteratorOfListOfShape + its = myCoup->Merged(curshape,TopAbs_IN); + if(!its.More()) B1.Add(badShape,curshape); + else { + while (its.More()) { + B1.Add(badShape,its.Value()); + its.Next(); + } + } + } + } +#ifdef DEB //perf + ChFi3d_ResultChron(cl_reconstruction ,t_reconstruction); + ChFi3d_InitChron(cl_setregul); +#endif + + // Regularities are coded after cutting. + SetRegul(); + + +#ifdef DEB //perf + ChFi3d_ResultChron(cl_setregul ,t_setregul); +#endif + } + } +#ifdef DEB //perf + ChFi3d_ResultChron(cl_total,t_total); +#endif + + + // display of time for perfs + +#ifdef DEB + cout<<endl; + cout<<"COMPUTE: temps total "<<t_total<<"s dont :"<<endl; + cout<<"- Init + ExtentAnalyse "<<t_extent<<"s"<<endl; + cout<<"- PerformSetOfSurf "<<t_perfsetofsurf<<"s"<<endl; + cout<<"- PerformFilletOnVertex "<<t_perffilletonvertex<<"s"<<endl; + cout<<"- FilDS "<<t_filds<<"s"<<endl; + cout<<"- Reconstruction "<<t_reconstruction<<"s"<<endl; + cout<<"- SetRegul "<<t_setregul<<"s"<<endl<<endl; + + if(ChFi3d_GettraceCHRON()){ + cout<<endl; + cout <<"temps PERFORMSETOFSURF "<<t_perfsetofsurf <<"s dont : "<<endl; + cout <<"- SetofKPart "<<t_perfsetofkpart<<"s"<<endl; + cout <<"- SetofKGen "<< t_perfsetofkgen <<"s"<<endl; + cout <<"- MakeExtremities "<<t_makextremities<<"s"<<endl<<endl; + + + cout <<"temps SETOFKGEN "<< t_perfsetofkgen<<"s dont : "<<endl; + cout<<"- PerformSurf "<<t_performsurf<<"s"<<endl; + cout<<"- starsol "<< t_startsol <<"s"<<endl<<endl; + + cout<<"temps PERFORMSURF "<<t_performsurf<<"s dont : " << endl; + cout<<"- computedata "<<t_computedata<<"s"<<endl; + cout<<"- completedata "<<t_completedata<<"s"<<endl<<endl; + + + cout<<"temps PERFORMFILLETVERTEX "<<t_perffilletonvertex <<"s dont : " << endl; + cout<<"- PerformOneCorner "<<t_perform1corner<<"s"<<endl; + cout<<"- PerformIntersectionAtEnd "<<t_performatend<<"s"<<endl; + cout<<"- PerformTwoCorner "<<t_perform2corner<<"s"<<endl; + cout<<"- PerformThreeCorner "<<t_perform3corner<<"s"<<endl; + cout<<"- PerformMoreThreeCorner "<<t_performmore3corner<<"s"<<endl<<endl; + + + cout<<"temps PerformOneCorner "<<t_perform1corner<<"s dont:"<<endl; + cout<<"- temps condition if (same) "<<t_same << "s "<<endl; + cout<<"- temps condition if (inter) "<<t_inter<<"s " <<endl; + cout<<"- temps condition if (same inter) "<<t_sameinter<<"s " <<endl<<endl; + + cout<<"temps PerformTwocorner "<<t_perform2corner<<"s dont:"<<endl; + cout<<"- temps initialisation "<< t_t2cornerinit<<"s"<<endl; + cout<<"- temps PerformTwoCornerbyInter "<<t_perf2cornerbyinter<<"s"<<endl; + cout<<"- temps ChFiKPart_ComputeData "<<t_chfikpartcompdata <<"s"<<endl; + cout<<"- temps cheminement "<<t_cheminement<<"s"<<endl; + cout<<"- temps remplissage "<<t_remplissage<<"s"<<endl; + cout<<"- temps mise a jour stripes "<<t_t2cornerDS<<"s"<<endl<<endl; + + cout<<" temps PerformThreecorner "<<t_perform3corner<<"s dont:"<<endl; + cout<<"- temps initialisation "<< t_t3cornerinit<<"s"<<endl; + cout<<"- temps cas spherique "<<t_spherique<<"s"<<endl; + cout<<"- temps cas torique "<<t_torique<<"s"<<endl; + cout<<"- temps notfilling "<<t_notfilling<<"s"<<endl; + cout<<"- temps filling "<<t_filling<<"s"<<endl; + cout<<"- temps mise a jour stripes "<<t_t3cornerDS<<"s"<<endl<<endl; + + cout<<"temps PerformMore3Corner "<<t_performmore3corner<<"s dont:"<<endl; + cout<<"-temps plate "<<t_plate << "s "<<endl; + cout<<"-temps approxplate "<<t_approxplate<<"s " <<endl; + cout<<"-temps batten "<< t_batten<<"s " <<endl<<endl; + + cout <<"TEMPS DIVERS "<<endl; + cout<<"-temps ChFi3d_sameparameter "<<t_sameparam<<"s"<<endl<<endl; + } +#endif +} + +//======================================================================= +//function : PerformSingularCorner +//purpose : Load vertex and degenerated edges. +//======================================================================= + +void ChFi3d_Builder::PerformSingularCorner +(const Standard_Integer Index){ + ChFiDS_ListIteratorOfListOfStripe It; + Handle(ChFiDS_Stripe) stripe; + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index); + + Handle(ChFiDS_SurfData) Fd; + Standard_Integer i, Icurv; +#ifndef DEB + Standard_Integer Ivtx = 0; +#else + Standard_Integer Ivtx; +#endif + for (It.Initialize(myVDataMap(Index)), i=0; It.More(); It.Next(),i++){ + stripe = It.Value(); + // SurfData concerned and its CommonPoints, + Standard_Integer sens = 0; + Standard_Integer num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens); + Standard_Boolean isfirst = (sens == 1); + Fd = stripe->SetOfSurfData()->Sequence().Value(num); + const ChFiDS_CommonPoint& CV1 = Fd->Vertex(isfirst,1); + const ChFiDS_CommonPoint& CV2 = Fd->Vertex(isfirst,2); + // Is it always degenerated ? + if ( CV1.Point().IsEqual( CV2.Point(), 0) ) { + // if yes the vertex is stored in the stripe + // and the edge at end is created + if (i==0) Ivtx = ChFi3d_IndexPointInDS(CV1, DStr); + Standard_Real tolreached; + Standard_Real Pardeb, Parfin; + gp_Pnt2d VOnS1, VOnS2; + Handle(Geom_Curve) C3d; + Handle(Geom2d_Curve) PCurv; + TopOpeBRepDS_Curve Crv; + if (isfirst) { + VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()-> + Value(Fd->InterferenceOnS1().FirstParameter()); + VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()-> + Value(Fd->InterferenceOnS2().FirstParameter()); + } + else { + VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()-> + Value(Fd->InterferenceOnS1().LastParameter()); + VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()-> + Value(Fd->InterferenceOnS2().LastParameter()); + } + + ChFi3d_ComputeArete(CV1, VOnS1, + CV2, VOnS2, + DStr.Surface(Fd->Surf()).Surface(), + C3d, PCurv, + Pardeb,Parfin,tolapp3d,tolapp2d,tolreached,0); + Crv = TopOpeBRepDS_Curve(C3d,tolreached); + Icurv = DStr.AddCurve(Crv); + + stripe->SetCurve(Icurv, isfirst); + stripe->SetParameters(isfirst, Pardeb,Parfin); + stripe->ChangePCurve(isfirst) = PCurv; + stripe->SetIndexPoint(Ivtx, isfirst, 1); + stripe->SetIndexPoint(Ivtx, isfirst, 2); + } + } +} + +//======================================================================= +//function : PerformFilletOnVertex +//purpose : +//======================================================================= + +void ChFi3d_Builder::PerformFilletOnVertex +(const Standard_Integer Index){ + + ChFiDS_ListIteratorOfListOfStripe It; + Handle(ChFiDS_Stripe) stripe; + Handle(ChFiDS_Spine) sp; + const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index); + + Handle(ChFiDS_SurfData) Fd; + Standard_Integer i; + Standard_Boolean nondegenere = Standard_True; + Standard_Boolean toujoursdegenere = Standard_True; +#ifndef DEB + Standard_Boolean isfirst = Standard_False; +#else + Standard_Boolean isfirst; +#endif + for (It.Initialize(myVDataMap(Index)), i=0; It.More(); It.Next(),i++){ + stripe = It.Value(); + sp = stripe->Spine(); + // SurfData and its CommonPoints, + Standard_Integer sens = 0; + Standard_Integer num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens); + isfirst = (sens == 1); + Fd = stripe->SetOfSurfData()->Sequence().Value(num); + const ChFiDS_CommonPoint& CV1 = Fd->Vertex(isfirst,1); + const ChFiDS_CommonPoint& CV2 = Fd->Vertex(isfirst,2); + // Is it always degenerated ? + if ( CV1.Point().IsEqual( CV2.Point(), 0) ) + nondegenere = Standard_False; + else toujoursdegenere = Standard_False; + } + + // calcul du nombre de faces = nombre d'aretes +/* TopTools_ListIteratorOfListOfShape ItF,JtF,ItE; + Standard_Integer nbf = 0, jf = 0; + for (ItF.Initialize(myVFMap(Vtx)); ItF.More(); ItF.Next()){ + jf++; + Standard_Integer kf = 1; + const TopoDS_Shape& cur = ItF.Value(); + for (JtF.Initialize(myVFMap(Vtx)); JtF.More() && (kf < jf); JtF.Next(), kf++){ + if(cur.IsSame(JtF.Value())) break; + } + if(kf == jf) nbf++; + } + Standard_Integer nba=myVEMap(Vtx).Extent(); + for (ItE.Initialize(myVEMap(Vtx)); ItE.More(); ItE.Next()){ + const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value()); + if (BRep_Tool::Degenerated(cur)) nba--; + } + nba=nba/2;*/ + Standard_Integer nba = ChFi3d_NumberOfEdges(Vtx, myVEMap); + + if (nondegenere) { // Normal processing + switch (i) { + case 1 : + { + if(sp->Status(isfirst) == ChFiDS_FreeBoundary) return; + if(nba>3) { +#ifdef DEB //perf + ChFi3d_InitChron(cl_performatend); +#endif + PerformIntersectionAtEnd(Index); +#ifdef DEB + ChFi3d_ResultChron(cl_performatend,t_performatend); +#endif + } + else { +#ifdef DEB //perf + ChFi3d_InitChron(cl_perform1corner); +#endif + if (MoreSurfdata(Index)) + PerformMoreSurfdata(Index); + else PerformOneCorner(Index); +#ifdef DEB //perf + ChFi3d_ResultChron(cl_perform1corner,t_perform1corner); +#endif + } + } + break; + case 2 : + { + if(nba>3){ +#ifdef DEB //perf + ChFi3d_InitChron(cl_performmore3corner); +#endif + PerformMoreThreeCorner(Index, i); +#ifdef DEB //perf + ChFi3d_ResultChron(cl_performmore3corner,t_performmore3corner); +#endif + } + else { +#ifdef DEB //perf + ChFi3d_InitChron(cl_perform2corner); +#endif + PerformTwoCorner(Index); +#ifdef DEB //perf + ChFi3d_ResultChron(cl_perform2corner,t_perform2corner); +#endif + } + } + break; + case 3 : + { + if(nba>3){ +#ifdef DEB //perf + ChFi3d_InitChron(cl_performmore3corner); +#endif + PerformMoreThreeCorner(Index, i); +#ifdef DEB //perf + ChFi3d_ResultChron(cl_performmore3corner,t_performmore3corner); +#endif + } + else { +#ifdef DEB //perf + ChFi3d_InitChron(cl_perform3corner); +#endif + PerformThreeCorner(Index); +#ifdef DEB //perf + ChFi3d_ResultChron(cl_perform3corner,t_perform3corner); +#endif + } + } + break; + default : { +#ifdef DEB //perf + ChFi3d_InitChron(cl_performmore3corner); +#endif + PerformMoreThreeCorner(Index, i); +#ifdef DEB //perf + ChFi3d_ResultChron(cl_performmore3corner,t_performmore3corner); +#endif + } + } + } + else { // Single case processing + if (toujoursdegenere) PerformSingularCorner(Index); + else PerformMoreThreeCorner(Index, i);//Last chance... + } +} + + +//======================================================================= +//function : Reset +//purpose : +//======================================================================= + +void ChFi3d_Builder::Reset() +{ + done = Standard_False; + myVDataMap.Clear(); + myRegul.Clear(); + myEVIMap.Clear(); + badstripes.Clear(); + badvertices.Clear(); + + ChFiDS_ListIteratorOfListOfStripe itel; + for (itel.Initialize(myListStripe); itel.More(); ){ + if(!itel.Value()->Spine().IsNull()){ + itel.Value()->Reset(); + itel.Next(); + } + else myListStripe.Remove(itel); + } +} + +//======================================================================= +//function : Generated +//purpose : +//======================================================================= + +const TopTools_ListOfShape& ChFi3d_Builder::Generated(const TopoDS_Shape& EouV) +{ + myGenerated.Clear(); + if(EouV.IsNull()) return myGenerated; + if(EouV.ShapeType() != TopAbs_EDGE && + EouV.ShapeType() != TopAbs_VERTEX) return myGenerated; + if(myEVIMap.IsBound(EouV)) { + const TColStd_ListOfInteger& L = myEVIMap.Find(EouV); + TColStd_ListIteratorOfListOfInteger IL; + for(IL.Initialize(L); IL.More(); IL.Next()){ + Standard_Integer I = IL.Value(); + const TopTools_ListOfShape& LS = myCoup->NewFaces(I); + TopTools_ListIteratorOfListOfShape ILS; + for(ILS.Initialize(LS); ILS.More(); ILS.Next()){ + myGenerated.Append(ILS.Value()); + } + } + } + return myGenerated; +} + + diff --git a/src/ChFi3d/ChFi3d_Builder_0.cxx b/src/ChFi3d/ChFi3d_Builder_0.cxx new file mode 100644 index 00000000..c5178140 --- /dev/null +++ b/src/ChFi3d/ChFi3d_Builder_0.cxx @@ -0,0 +1,4765 @@ +// File: ChFi3d_Builder_0.cxx +// Created: Thu Dec 16 15:54:39 1993 +// Author: Isabelle GRIGNON +// Copyright: OPEN CASCADE 1993 + +// modified by ofv - Thu Feb 26 11:18:16 2004 OCC5246 +// Modified by skv - Fri Oct 24 14:24:47 2003 OCC4077 +// Modified by skv - Mon Jun 16 15:50:44 2003 OCC615 + +#include <ChFi3d.hxx> +#include <Precision.hxx> + +#include <Standard_NotImplemented.hxx> +#include <Standard_ConstructionError.hxx> + +#include <gp.hxx> +#include <gp_Circ.hxx> +#include <gp_Elips.hxx> +#include <gp_Lin.hxx> +#include <gp_Pnt.hxx> +#include <gp_Pnt2d.hxx> +#include <gp_Lin2d.hxx> +#include <ElCLib.hxx> +#include <ElSLib.hxx> +#include <BSplCLib.hxx> +#include <GeomLib.hxx> + +#include <TColgp_Array1OfPnt2d.hxx> +#include <TColgp_Array1OfPnt.hxx> +#include <TColgp_Array1OfXYZ.hxx> +#include <TColStd_Array1OfInteger.hxx> +#include <TColStd_Array1OfReal.hxx> + +#include <Geom_TrimmedCurve.hxx> +#include <Geom_BSplineCurve.hxx> +#include <Geom_Surface.hxx> +#include <Geom_CylindricalSurface.hxx> +#include <Geom_RectangularTrimmedSurface.hxx> +#include <Geom_Plane.hxx> +#include <Geom_Line.hxx> +#include <Geom_Circle.hxx> +#include <Geom_Ellipse.hxx> +#include <Geom2d_BezierCurve.hxx> +#include <Geom2d_BSplineCurve.hxx> +#include <Geom2d_Line.hxx> +#include <Geom2d_Circle.hxx> +#include <Geom2d_Ellipse.hxx> +#include <Geom2d_Hyperbola.hxx> +#include <Geom2d_Parabola.hxx> +#include <Geom2d_TrimmedCurve.hxx> +#include <Geom2d_Line.hxx> +#include <Geom2d_OffsetCurve.hxx> +#include <Geom2dAdaptor_Curve.hxx> +#include <Geom2dAdaptor_HCurve.hxx> +#include <Adaptor3d_TopolTool.hxx> +#include <Adaptor3d_CurveOnSurface.hxx> +#include <Adaptor3d_HCurveOnSurface.hxx> +#include <GeomAdaptor_HSurface.hxx> + +#include <FairCurve_Batten.hxx> +#include <FairCurve_AnalysisCode.hxx> +#include <Convert_ParameterisationType.hxx> +#include <GeomConvert_CompCurveToBSplineCurve.hxx> +#include <GeomConvert.hxx> +#include <GeomLib_Interpolate.hxx> +#include <GeomAPI_ProjectPointOnSurf.hxx> +#include <GeomAPI_ProjectPointOnCurve.hxx> +#include <GC_MakeCircle.hxx> +#include <BRepAdaptor_Curve.hxx> +#include <BRepAdaptor_HCurve.hxx> +#include <BRepAdaptor_HCurve2d.hxx> +#include <BRepAdaptor_Surface.hxx> +#include <BRepTopAdaptor_HVertex.hxx> + +#include <BRep_Tool.hxx> +#include <BRep_Builder.hxx> +#include <BRepTools.hxx> +#include <BRepTools_WireExplorer.hxx> +#include <BRepLib.hxx> +#include <BRepLib_MakeEdge.hxx> +#include <BRepLib_MakeWire.hxx> +#include <BRepLib_MakeFace.hxx> + +#include <TopAbs.hxx> +#include <TopoDS_Shape.hxx> +#include <TopoDS_Edge.hxx> +#include <TopoDS_Vertex.hxx> +#include <TopoDS_Wire.hxx> +#include <TopoDS_Face.hxx> +#include <TopExp.hxx> +#include <TopExp_Explorer.hxx> +#include <TopTools_Array1OfShape.hxx> + + +#include <GeomAbs_Shape.hxx> +#include <Bnd_Box2d.hxx> + +//#include <math_FunctionSample.hxx> +//#include <math_FunctionAllRoots.hxx> +#include <GCPnts_AbscissaPoint.hxx> + +#include <IntCurveSurface_TheQuadCurvFuncOfTheQuadCurvExactHInter.hxx> +#include <IntCurveSurface_HInter.hxx> +#include <IntCurveSurface_IntersectionPoint.hxx> +#include <IntSurf_Quadric.hxx> +#include <IntSurf_PntOn2S.hxx> +#include <IntSurf_LineOn2S.hxx> +#include <IntAna_QuadQuadGeo.hxx> +#include <IntAna2d_AnaIntersection.hxx> +#include <IntRes2d_IntersectionPoint.hxx> +#include <IntPatch_ThePWalkingInter.hxx> +#include <IntPatch_WLine.hxx> +#include <Geom2dInt_GInter.hxx> +#include <GeomInt_WLApprox.hxx> +#include <GeomInt_IntSS.hxx> +#include <AppParCurves_MultiBSpCurve.hxx> +#include <Approx_SameParameter.hxx> + +#include <TopAbs.hxx> +#include <TopoDS_Shape.hxx> +#include <TopoDS_Edge.hxx> +#include <TopExp.hxx> + +#include <TopOpeBRepDS.hxx> +#include <TopOpeBRepDS_Surface.hxx> +#include <TopOpeBRepDS_Point.hxx> +#include <TopOpeBRepDS_SolidSurfaceInterference.hxx> +#include <TopOpeBRepDS_CurvePointInterference.hxx> +#include <TopOpeBRepDS_ListOfInterference.hxx> +#include <TopOpeBRepDS_InterferenceIterator.hxx> +#include <ProjLib_ProjectedCurve.hxx> + +#include <BRepBlend_PointOnRst.hxx> + +#include <ChFiDS_HData.hxx> +#include <ChFiDS_SurfData.hxx> +#include <ChFiDS_FaceInterference.hxx> +#include <ChFiDS_Spine.hxx> +#include <ChFiDS_FilSpine.hxx> +#include <ChFiDS_SequenceOfSurfData.hxx> +#include <ChFiDS_Regul.hxx> +#include <Law_Function.hxx> +#include <Law_Composite.hxx> +#include <GeomAPI_PointsToBSpline.hxx> +#include <GeomLProp_CLProps.hxx> + +#include <ChFi3d_Builder_0.hxx> + +#ifdef DEB +#include <OSD_Chronometer.hxx> +extern Standard_Boolean ChFi3d_GetcontextFORCEBLEND(); +extern Standard_Boolean ChFi3d_GettraceDRAWINT(); +extern Standard_Boolean ChFi3d_GettraceDRAWENLARGE(); +extern Standard_Boolean ChFi3d_GettraceDRAWSPINE(); +extern Standard_Real t_sameparam, t_batten; +extern void ChFi3d_SettraceDRAWINT(const Standard_Boolean b); +extern void ChFi3d_SettraceDRAWSPINE(const Standard_Boolean b); +extern void ChFi3d_InitChron(OSD_Chronometer& ch); +extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time); +#endif + +#include <stdio.h> + +#include <GeomAdaptor_HCurve.hxx> +#include <BRepAdaptor_HSurface.hxx> + +//======================================================================= +//function : ChFi3d_InPeriod +//purpose : +//======================================================================= +Standard_Real ChFi3d_InPeriod(const Standard_Real U, + const Standard_Real UFirst, + const Standard_Real ULast, + const Standard_Real Eps) +{ + const Standard_Real period = ULast - UFirst; + Standard_Real u = U; + while (Eps < (UFirst-u)) u += period; + while (Eps > (ULast -u)) u -= period; + if ( u < UFirst) u = UFirst; + return u; +} +//======================================================================= +//function : Box +//purpose : Calculation of min/max uv of the fillet to intersect. +//======================================================================= +void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2, + Standard_Real& mu,Standard_Real& Mu, + Standard_Real& mv,Standard_Real& Mv) +{ + mu = Min(p1.X(),p2.X()); Mu = Max(p1.X(),p2.X()); + mv = Min(p1.Y(),p2.Y()); Mv = Max(p1.Y(),p2.Y()); +} +//======================================================================= +//function : Box +//purpose : Calculation of min/max uv of the fillet to intersect. +//======================================================================= +void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2, + const gp_Pnt2d& p3,const gp_Pnt2d& p4, + Standard_Real& Du,Standard_Real& Dv, + Standard_Real& mu,Standard_Real& Mu, + Standard_Real& mv,Standard_Real& Mv) +{ + Standard_Real a,b; + a = Min(p1.X(),p2.X()); b = Min(p3.X(),p4.X()); mu = Min(a,b); + a = Max(p1.X(),p2.X()); b = Max(p3.X(),p4.X()); Mu = Max(a,b); + a = Min(p1.Y(),p2.Y()); b = Min(p3.Y(),p4.Y()); mv = Min(a,b); + a = Max(p1.Y(),p2.Y()); b = Max(p3.Y(),p4.Y()); Mv = Max(a,b); + Du = Mu - mu; + Dv = Mv - mv; +} +//======================================================================= +//function : EnlargeBox and its friends. +//purpose : +//======================================================================= +static Handle(Adaptor3d_HSurface) Geometry(TopOpeBRepDS_DataStructure& DStr, + const Standard_Integer ind) +{ + if(ind == 0) return Handle(Adaptor3d_HSurface)(); + if(ind > 0) { + TopoDS_Face F = TopoDS::Face(DStr.Shape(ind)); + if(F.IsNull()) return Handle(Adaptor3d_HSurface)(); + Handle(BRepAdaptor_HSurface) HS = new BRepAdaptor_HSurface(); + HS->ChangeSurface().Initialize(F,0); + return HS; + } + else{ + Handle(Geom_Surface) S = DStr.Surface(-ind).Surface(); + if(S.IsNull()) return Handle(Adaptor3d_HSurface)(); + return new GeomAdaptor_HSurface(S); + } +} +//======================================================================= +//function : ChFi3d_SetPointTolerance +//purpose : +//======================================================================= +void ChFi3d_SetPointTolerance(TopOpeBRepDS_DataStructure& DStr, + const Bnd_Box& box, + const Standard_Integer IP) +{ + Standard_Real a,b,c,d,e,f,vtol; + box.Get(a,b,c,d,e,f); + d-=a; e-=b; f-=c; + d*=d; e*=e; f*=f; + vtol = sqrt(d + e + f) * 1.5;// on prend un petit rab. + DStr.ChangePoint(IP).Tolerance(vtol); +} +//======================================================================= +//function : ChFi3d_EnlargeBox +//purpose : +//======================================================================= +void ChFi3d_EnlargeBox(const Handle(Geom_Curve)& C, + const Standard_Real wd, + const Standard_Real wf, + Bnd_Box& box1, + Bnd_Box& box2) +{ + box1.Add(C->Value(wd)); + box2.Add(C->Value(wf)); +} +//======================================================================= +//function : ChFi3d_EnlargeBox +//purpose : +//======================================================================= +void ChFi3d_EnlargeBox(const Handle(Adaptor3d_HSurface)& S, + const Handle(Geom2d_Curve)& PC, + const Standard_Real wd, + const Standard_Real wf, + Bnd_Box& box1, + Bnd_Box& box2) +{ + Standard_Real u,v; + PC->Value(wd).Coord(u,v); + box1.Add(S->Value(u,v)); + PC->Value(wf).Coord(u,v); + box2.Add(S->Value(u,v)); +} +//======================================================================= +//function : ChFi3d_EnlargeBox +//purpose : +//======================================================================= +void ChFi3d_EnlargeBox(const TopoDS_Edge& E, + const TopTools_ListOfShape& LF, + const Standard_Real w, + Bnd_Box& box) + +{ + BRepAdaptor_Curve BC(E); + box.Add(BC.Value(w)); + TopTools_ListIteratorOfListOfShape It; + for(It.Initialize(LF); It.More(); It.Next()) { + TopoDS_Face F = TopoDS::Face(It.Value()); + if(!F.IsNull()) { + BC.Initialize(E,F); + box.Add(BC.Value(w)); + } + } +} +//======================================================================= +//function : ChFi3d_EnlargeBox +//purpose : +//======================================================================= +void ChFi3d_EnlargeBox(TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_Stripe)& st, + const Handle(ChFiDS_SurfData)& sd, + Bnd_Box& b1, + Bnd_Box& b2, + const Standard_Boolean isfirst) +{ + Standard_Real u,v; + const ChFiDS_CommonPoint& cp1 = sd->Vertex(isfirst,1); + const ChFiDS_CommonPoint& cp2 = sd->Vertex(isfirst,2); + b1.Add(cp1.Point()); + b2.Add(cp2.Point()); + const ChFiDS_FaceInterference& fi1 = sd->InterferenceOnS1(); + const ChFiDS_FaceInterference& fi2 = sd->InterferenceOnS2(); + const Handle(Geom_Surface)& S = DStr.Surface(sd->Surf()).Surface(); + const Handle(Geom2d_Curve)& pcs1 = fi1.PCurveOnSurf(); + const Handle(Geom2d_Curve)& pcs2 = fi2.PCurveOnSurf(); + const Handle(Geom_Curve)& c3d1 = DStr.Curve(fi1.LineIndex()).Curve(); + const Handle(Geom_Curve)& c3d2 = DStr.Curve(fi2.LineIndex()).Curve(); + Handle(Adaptor3d_HSurface) F1 = Geometry(DStr,sd->IndexOfS1()); + Handle(Adaptor3d_HSurface) F2 = Geometry(DStr,sd->IndexOfS2()); + Standard_Real p1 = fi1.Parameter(isfirst); + if(!c3d1.IsNull()) b1.Add(c3d1->Value(p1)); + if(!pcs1.IsNull()) { + pcs1->Value(p1).Coord(u,v); + b1.Add(S->Value(u,v)); + } + if(!F1.IsNull()) { + const Handle(Geom2d_Curve)& pcf1 = fi1.PCurveOnFace(); + if(!pcf1.IsNull()) { + pcf1->Value(p1).Coord(u,v); + b1.Add(F1->Value(u,v)); + } + } + Standard_Real p2 = fi2.Parameter(isfirst); + if(!c3d2.IsNull()) b2.Add(c3d2->Value(p2)); + if(!pcs2.IsNull()) { + pcs2->Value(p2).Coord(u,v); + b2.Add(S->Value(u,v)); + } + if(!F2.IsNull()) { + const Handle(Geom2d_Curve)& pcf2 = fi2.PCurveOnFace(); + if(!pcf2.IsNull()) { + pcf2->Value(p2).Coord(u,v); + b2.Add(F2->Value(u,v)); + } + } + if(!st.IsNull()) { + const Handle(Geom_Curve)& c3d = DStr.Curve(st->Curve(isfirst)).Curve(); + const Handle(Geom2d_Curve)& c2d = st->PCurve(isfirst); + if(st->Orientation(isfirst) == TopAbs_FORWARD) st->Parameters(isfirst,p1,p2); + else st->Parameters(isfirst,p2,p1); + if(!c3d.IsNull()) { + b1.Add(c3d->Value(p1)); + b2.Add(c3d->Value(p2)); + } + if(!c2d.IsNull()) { + c2d->Value(p1).Coord(u,v); + b1.Add(S->Value(u,v)); + c2d->Value(p2).Coord(u,v); + b2.Add(S->Value(u,v)); + } + } +} +//======================================================================= +//function : conexfaces +//purpose : +//======================================================================= +void ChFi3d_conexfaces(const TopoDS_Edge& E, + TopoDS_Face& F1, + TopoDS_Face& F2, + const ChFiDS_Map& EFMap) +{ + TopTools_ListIteratorOfListOfShape It; + F1.Nullify(); + F2.Nullify(); + for(It.Initialize(EFMap(E));It.More();It.Next()) { + if (F1.IsNull()) { + F1 = TopoDS::Face(It.Value()); + } + else { + F2 = TopoDS::Face(It.Value()); + if(!F2.IsSame(F1) || BRep_Tool::IsClosed(E,F1)) { + break; + } + else F2.Nullify(); + } + } +} +//======================================================================= +//function : EdgeState +//purpose : check concavities for the tops with 3 edges. +//======================================================================= +ChFiDS_State ChFi3d_EdgeState(TopoDS_Edge* E, + const ChFiDS_Map& EFMap) +{ + ChFiDS_State sst; + Standard_Integer i,j; + TopoDS_Face F[3]; + TopoDS_Face F1,F2,F3,F4,F5,F6; + ChFi3d_conexfaces(E[0],F1,F2,EFMap); + ChFi3d_conexfaces(E[1],F3,F4,EFMap); + ChFi3d_conexfaces(E[2],F5,F6,EFMap); + if(F1.IsSame(F2)) { + F[0] = F[1] = F1; + if(F1.IsSame(F3)) F[2] = F4; + else F[2] = F3; + } + else if(F3.IsSame(F4)) { + F[0] = F[2] = F3; + if(F3.IsSame(F1)) F[1] = F2; + else F[1] = F1; + } + else if(F5.IsSame(F6)) { + F[1] = F[2] = F5; + if(F5.IsSame(F1)) F[0] = F2; + else F[0] = F1; + } + else{ + if(F1.IsSame(F3) || F1.IsSame(F4)) F[0] = F1; + else F[0] = F2; + if(F3.IsSame(F[0])) F[2] = F4; + else F[2] = F3; + if(F5.IsSame(F[2])) F[1] = F6; + else F[1] = F5; + + } + + if(F[0].IsNull() || F[1].IsNull() || F[2].IsNull()) sst = ChFiDS_FreeBoundary; + else{ + TopAbs_Orientation o01,o02,o11,o12,o21,o22; + i=ChFi3d::ConcaveSide(F[0],F[1],E[0],o01,o02); + i=ChFi3d::ConcaveSide(F[0],F[2],E[1],o11,o12); + j=ChFi3d::ConcaveSide(F[1],F[2],E[2],o21,o22); + if(o01==o11 && o02==o21 && o12==o22) sst = ChFiDS_AllSame; + else if(o12==o22 || i ==10 || j ==10) sst = ChFiDS_OnDiff; + else sst = ChFiDS_OnSame; + } + return sst; +} +//======================================================================= +//function : evalconti +//purpose : Method very fast to code regularities CN. It is necessary to +// refine the processing. +//======================================================================= +GeomAbs_Shape ChFi3d_evalconti(const TopoDS_Edge& /*E*/, + const TopoDS_Face& F1, + const TopoDS_Face& F2) +{ + GeomAbs_Shape cont = GeomAbs_G1; + if(!F1.IsSame(F2)) return cont; + TopoDS_Face F = F1; + F.Orientation(TopAbs_FORWARD); + BRepAdaptor_Surface S(F,Standard_False); + GeomAbs_SurfaceType typ = S.GetType(); + if(typ != GeomAbs_Cone && + typ != GeomAbs_Sphere && + typ != GeomAbs_Torus) return cont; + return GeomAbs_CN; +} +//modified by NIZNHY-PKV Wed Dec 15 11:22:35 2010f +//======================================================================= +//function : KParticular +//purpose : +//======================================================================= +Standard_Boolean ChFi3d_KParticular (const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer IE, + const BRepAdaptor_Surface& S1, + const BRepAdaptor_Surface& S2) +{ + Standard_Boolean bRet; + // + bRet=Standard_True; + // + Handle(ChFiDS_FilSpine) fs = Handle(ChFiDS_FilSpine)::DownCast(Spine); + if(!fs.IsNull() && !fs->IsConstant(IE)) { + return !bRet; + } + // + Standard_Boolean bIsPlane1, bIsPlane2; + Standard_Real aPA; + GeomAbs_CurveType aCT; + GeomAbs_SurfaceType aST1, aST2; + // + aST1=S1.GetType(); + aST2=S2.GetType(); + bIsPlane1=(aST1==GeomAbs_Plane); + bIsPlane2=(aST2==GeomAbs_Plane); + if (!(bIsPlane1 || bIsPlane2)) { + return !bRet; + } + // + const BRepAdaptor_Surface& aS1=(bIsPlane1)? S1 : S2; + const BRepAdaptor_Surface& aS2=(bIsPlane1)? S2 : S1; + aST1=aS1.GetType(); + aST2=aS2.GetType(); + // + if (!(aST2==GeomAbs_Plane || aST2==GeomAbs_Cylinder || aST2==GeomAbs_Cone)) { + return !bRet; + } + // + const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(IE); + aCT = bc.GetType(); + if (!(aCT==GeomAbs_Line || aCT==GeomAbs_Circle)) { + return !bRet; + } + // + aPA=Precision::Angular(); + // + if (aST2==GeomAbs_Plane){ + if (aCT==GeomAbs_Line) { + return bRet; + } + } + else if (aST2==GeomAbs_Cylinder) { + const gp_Dir& aD1=aS1.Plane().Axis().Direction(); + const gp_Dir& aD2=aS2.Cylinder().Axis().Direction(); + // + if (aCT==GeomAbs_Line && aD1.IsNormal(aD2, aPA)) { + return bRet; + } + else if (aCT==GeomAbs_Circle && aD1.IsParallel(aD2, aPA)) { + return bRet; + } + } + else if(aST2==GeomAbs_Cone) { + const gp_Dir& aD1=aS1.Plane().Axis().Direction(); + const gp_Dir& aD2=aS2.Cone().Axis().Direction(); + if (aCT == GeomAbs_Circle && aD1.IsParallel(aD2, aPA)) { + return bRet; + } + } + return !bRet; +} +//modified by NIZNHY-PKV Wed Dec 15 11:22:43 2010t +//======================================================================= +//function : BoundFac +//purpose : Resize the limits of surface adjacent to the given box +// Useful for intersections with known extremities. +//======================================================================= +void ChFi3d_BoundFac(BRepAdaptor_Surface& S, + const Standard_Real uumin, + const Standard_Real uumax, + const Standard_Real vvmin, + const Standard_Real vvmax, + const Standard_Boolean checknaturalbounds) +{ + ChFi3d_BoundSrf(S.ChangeSurface(), uumin,uumax,vvmin,vvmax,checknaturalbounds); +} +//======================================================================= +//function : ChFi3d_BoundSrf +//purpose : Resize the limits of surface adjacent to the given box +// Useful for intersections with known extremities. +//======================================================================= +void ChFi3d_BoundSrf(GeomAdaptor_Surface& S, + const Standard_Real uumin, + const Standard_Real uumax, + const Standard_Real vvmin, + const Standard_Real vvmax, + const Standard_Boolean checknaturalbounds) +{ + Standard_Real umin = uumin, umax = uumax, vmin = vvmin, vmax = vvmax; + Handle(Geom_Surface) surface = S.Surface(); + Handle(Geom_RectangularTrimmedSurface) + trs = Handle(Geom_RectangularTrimmedSurface)::DownCast(surface); + if(!trs.IsNull()) surface = trs->BasisSurface(); + Standard_Real u1,u2,v1,v2; + surface->Bounds(u1,u2,v1,v2); + Standard_Real peru=0, perv=0; + if(surface->IsUPeriodic()) { + peru = surface->UPeriod(); + } + if(surface->IsVPeriodic()) { + perv = surface->VPeriod(); + } + Standard_Real Stepu = umax - umin; + Standard_Real Stepv = vmax - vmin; + + //It is supposed that box uv is not null in at least + //one direction. + Standard_Real scalu = S.UResolution(1.); + Standard_Real scalv = S.VResolution(1.); + + Standard_Real step3du = Stepu/scalu; + Standard_Real step3dv = Stepv/scalv; + + if(step3du > step3dv) Stepv = step3du*scalv; + if(step3dv > step3du) Stepu = step3dv*scalu; + + if (peru > 0) Stepu = 0.1 * (peru - (umax - umin)); + if (perv > 0) Stepv = 0.1 * (perv - (vmax - vmin)); + + Standard_Real uu1 = umin - Stepu; + Standard_Real uu2 = umax + Stepu; + Standard_Real vv1 = vmin - Stepv; + Standard_Real vv2 = vmax + Stepv; + if(checknaturalbounds) { + if(!S.IsUPeriodic()) {uu1 = Max(uu1,u1); uu2 = Min(uu2,u2);} + if(!S.IsVPeriodic()) {vv1 = Max(vv1,v1); vv2 = Min(vv2,v2);} + } + S.Load(surface,uu1,uu2,vv1,vv2); +} +//======================================================================= +//function : ChFi3d_InterPlaneEdge +//purpose : +//======================================================================= +Standard_Boolean ChFi3d_InterPlaneEdge (Handle(Adaptor3d_HSurface)& Plan, + Handle(Adaptor3d_HCurve)& C, + Standard_Real& W, + const Standard_Boolean Sens, + const Standard_Real tolc) +{ + IntCurveSurface_HInter Intersection; + Standard_Integer isol = 0, nbp ,iip; + Standard_Real uf = C->FirstParameter(),ul = C->LastParameter(); + Standard_Real CW; + + Intersection.Perform(C,Plan); + + if(Intersection.IsDone()) { + nbp = Intersection.NbPoints(); + for (iip = 1; iip <= nbp; iip++) { + CW = Intersection.Point(iip).W(); + if(C->IsPeriodic()) + CW = ElCLib::InPeriod(CW,uf-tolc,uf-tolc+C->Period()); + if(uf - tolc <= CW && ul + tolc >= CW) { + if (isol == 0) { + isol = iip; W = CW; + } + else { + if ( Sens && CW < W) { + W = CW; isol = iip; + } + else if (!Sens && CW > W) { + W = CW; isol = iip; + } + } + } + } + } + if(isol == 0) return Standard_False; + return Standard_True; +} +//======================================================================= +//function : ExtrSpineCarac +//purpose : +//======================================================================= +void ChFi3d_ExtrSpineCarac(const TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_Stripe)& cd, + const Standard_Integer i, + const Standard_Real p, + const Standard_Integer jf, + const Standard_Integer sens, + gp_Pnt& P, + gp_Vec& V, + Standard_Real& R) //check if it is necessary to add D1,D2 and DR +{ + // Attention for approximated surfaces it is assumed that e + // the parameters of the pcurve are the same as of + // elspine used for its construction. + const Handle(Geom_Surface)& fffil = + DStr.Surface(cd->SetOfSurfData()->Value(i)->Surf()).Surface(); + gp_Pnt2d pp = cd->SetOfSurfData()->Value(i)->Interference(jf). + PCurveOnSurf()->Value(p); + GeomAdaptor_Surface gs(fffil); + P = fffil->Value(pp.X(),pp.Y()); + gp_Pnt Pbid; gp_Vec Vbid; + switch (gs.GetType()) { + case GeomAbs_Cylinder : + { + gp_Cylinder cyl = gs.Cylinder(); + R = cyl.Radius(); + ElSLib::D1(pp.X(),pp.Y(),cyl,Pbid,Vbid,V); + } + break; + case GeomAbs_Torus : + { + gp_Torus tor = gs.Torus(); + R = tor.MinorRadius(); + ElSLib::D1(pp.X(),pp.Y(),tor,Pbid,V,Vbid); + } + break; + default: + { Standard_Integer nbelspine; + const Handle(ChFiDS_Spine)& sp = cd->Spine(); + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(sp); + nbelspine=sp->NbEdges(); + Handle(ChFiDS_HElSpine) hels; + if (nbelspine==1) hels = sp->ElSpine(1); + else hels = sp->ElSpine(p); + if(fsp->IsConstant()) { R = fsp->Radius(); } + else { R = fsp->Law(hels)->Value(p); } + hels->D1(p,Pbid,V); + } + break; + } + V.Normalize(); + if(sens == 1) V.Reverse(); +} +//======================================================================= +//function : ChFi3d_CircularSpine +//purpose : Calculate a cicular guideline for the corner created from +// tangent points and vectors calculated at the extremities +// of guidelines of start and end fillets. +//======================================================================= +Handle(Geom_Circle) ChFi3d_CircularSpine(Standard_Real& WFirst, + Standard_Real& WLast, + const gp_Pnt& Pdeb, + const gp_Vec& Vdeb, + const gp_Pnt& Pfin, + const gp_Vec& Vfin, + const Standard_Real rad) +{ + gp_Circ ccc; + gp_Pln Pl1(Pdeb,gp_Dir(Vdeb)),Pl2(Pfin,gp_Dir(Vfin)); + IntAna_QuadQuadGeo LInt (Pl1,Pl2,Precision::Angular(), + Precision::Confusion()); + gp_Lin li; + if (LInt.IsDone()) { + li = LInt.Line(1); + gp_Pnt cendeb = ElCLib::Value(ElCLib::Parameter(li,Pdeb),li); + gp_Pnt cenfin = ElCLib::Value(ElCLib::Parameter(li,Pfin),li); + gp_Vec vvdeb(cendeb,Pdeb); + gp_Vec vvfin(cenfin,Pfin); + gp_Dir dddeb(vvdeb); + gp_Dir ddfin(vvfin); + if(Vdeb.Crossed(vvdeb).Dot(Vfin.Crossed(vvfin)) > 0.) { + return Handle(Geom_Circle)(); + } + gp_Ax2 circax2(cendeb,dddeb^ddfin,dddeb); + ccc.SetPosition(circax2); + ccc.SetRadius(rad); + WFirst = 0.; + WLast = dddeb.Angle(ddfin); + return new Geom_Circle(ccc); + } + + return Handle(Geom_Circle)(); +} +//======================================================================= +//function : ChFi3d_Spine +//purpose : Calculates the poles of the guideline for the corner from +// tangent points and vectors calculated at the extremities of +// guidelines of start and end fillets. +//======================================================================= +Handle(Geom_BezierCurve) ChFi3d_Spine(const gp_Pnt& pd, + gp_Vec& vd, + const gp_Pnt& pf, + gp_Vec& vf, + const Standard_Real R) +{ + TColgp_Array1OfPnt pol(1,4); + const Standard_Real fac = 0.5 * tan((PI-vd.Angle(vf)) * 0.5); + pol(1) = pd; + vd.Multiply(fac*R); + pol(2).SetCoord(pd.X()+vd.X(),pd.Y()+vd.Y(),pd.Z()+vd.Z()); + pol(4) = pf; + vf.Multiply(fac*R); + pol(3).SetCoord(pf.X()+vf.X(),pf.Y()+vf.Y(),pf.Z()+vf.Z()); + return new Geom_BezierCurve(pol); +} +//======================================================================= +//function : IsInFront +//purpose : Checks if surfdata i1 and i2 are face to face +//======================================================================= +Standard_Boolean ChFi3d_IsInFront(TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_Stripe)& cd1, + const Handle(ChFiDS_Stripe)& cd2, + const Standard_Integer i1, + const Standard_Integer i2, + const Standard_Integer sens1, + const Standard_Integer sens2, + Standard_Real& p1, + Standard_Real& p2, + TopoDS_Face& face, + Standard_Boolean& sameside, + Standard_Integer& jf1, + Standard_Integer& jf2, + Standard_Boolean& visavis, + const TopoDS_Vertex& Vtx, + const Standard_Boolean Check2dDistance, + const Standard_Boolean enlarge) +{ + Standard_Boolean isf1 = (sens1 == 1), isf2 = (sens2 == 1); + const Handle(ChFiDS_SurfData)& fd1 = cd1->SetOfSurfData()->Value(i1); + const Handle(ChFiDS_SurfData)& fd2 = cd2->SetOfSurfData()->Value(i2); + + TopAbs_Orientation Or,OrSave1,OrSave2,OrFace1,OrFace2; + visavis = Standard_False; + Standard_Real u1 = 0.,u2 = 0.; + Standard_Boolean ss = 0,ok = 0; + Standard_Integer j1 = 0,j2 = 0; + TopoDS_Face ff; + if(fd1->IndexOfS1() == fd2->IndexOfS1()) { + jf1 = 1; jf2 = 1; + face = TopoDS::Face(DStr.Shape(fd1->Index(jf1))); + OrSave1 = cd1->Orientation(jf1); + Or = OrFace1 = face.Orientation(); + OrSave2 = cd2->Orientation(jf2); + OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation(); + visavis = Standard_True; + sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2); + // The parameters of the other side are not used for orientation. This would raise problems + Standard_Integer kf1 = jf1, kf2 = jf2; + Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1); + Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2); + gp_Pnt2d P2d; + if (Check2dDistance) + P2d = BRep_Tool::Parameters( Vtx, face ); + if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) { + u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face; + ok = 1; + } + } + if(fd1->IndexOfS2() == fd2->IndexOfS1()) { + jf1 = 2; jf2 = 1; + face = TopoDS::Face(DStr.Shape(fd1->Index(jf1))); + OrSave1 = cd1->Orientation(jf1); + Or = OrFace1 = face.Orientation(); + OrSave2 = cd2->Orientation(jf2); + OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation(); + visavis = Standard_True; + sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2); + // The parameters of the other side are not used for orientation. This would raise problems + Standard_Integer kf1 = jf1, kf2 = jf2; + Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1); + Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2); + gp_Pnt2d P2d; + if (Check2dDistance) + P2d = BRep_Tool::Parameters( Vtx, face ); + if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) { + Standard_Boolean restore = + ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) || + (j2 == jf2 && sens2*(p2 - u2) > 0.)); + ok = 1; + if(restore) { + p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff; + } + else { + u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face; + } + } + //the re-initialization is added in case p1,... take wrong values + else if (ok) { + p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff; + } + } + if(fd1->IndexOfS1() == fd2->IndexOfS2()) { + jf1 = 1; jf2 = 2; + face = TopoDS::Face(DStr.Shape(fd1->Index(jf1))); + OrSave1 = cd1->Orientation(jf1); + Or = OrFace1 = face.Orientation(); + OrSave2 = cd2->Orientation(jf2); + OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation(); + visavis = Standard_True; + sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2); + // The parameters of the other side are not used for orientation. + Standard_Integer kf1 = jf1, kf2 = jf2; + Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1); + Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2); + gp_Pnt2d P2d; + if (Check2dDistance) + P2d = BRep_Tool::Parameters( Vtx, face ); + if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) { + Standard_Boolean restore = + ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) || + (j2 == jf2 && sens2*(p2 - u2) > 0.)); + ok = 1; + if(restore) { + p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff; + } + else { + u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face; + } + } + //the re-initialization is added in case p1,... take wrong values + else if (ok) { + p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff; + } + } + if(fd1->IndexOfS2() == fd2->IndexOfS2()) { + jf1 = 2; jf2 = 2; + face = TopoDS::Face(DStr.Shape(fd1->Index(jf1))); + OrSave1 = cd1->Orientation(jf1); + Or = OrFace1 = face.Orientation(); + OrSave2 = cd2->Orientation(jf2); + OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation(); + visavis = Standard_True; + sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2); + // The parameters of the other side are not used for orientation. + Standard_Integer kf1 = jf1, kf2 = jf2; + Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1); + Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2); + gp_Pnt2d P2d; + if (Check2dDistance) + P2d = BRep_Tool::Parameters( Vtx, face ); + if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) { + Standard_Boolean restore = + ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) || + (j2 == jf2 && sens2*(p2 - u2) > 0.)); + ok = 1; + if(restore) { + p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff; + } + else { + u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face; + } + } + //the re-initialization is added in case p1,... take wrong values + else if (ok) { + p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff; + } + } + return ok; +} +//======================================================================= +//function : recadre +//purpose : +//======================================================================= +static Standard_Real recadre(const Standard_Real p, + const Standard_Real ref, + const Standard_Integer sens, + const Standard_Real first, + const Standard_Real last) +{ + const Standard_Real pp = p + (sens > 0 ? (first - last) : (last - first)); + return ((Abs(pp - ref) < Abs(p - ref))? pp : p); +} +//======================================================================= +//function : ChFi3d_IntTraces +//purpose : +//======================================================================= +Standard_Boolean ChFi3d_IntTraces(const Handle(ChFiDS_SurfData)& fd1, + const Standard_Real pref1, + Standard_Real& p1, + const Standard_Integer jf1, + const Standard_Integer sens1, + const Handle(ChFiDS_SurfData)& fd2, + const Standard_Real pref2, + Standard_Real& p2, + const Standard_Integer jf2, + const Standard_Integer sens2, + const gp_Pnt2d& RefP2d, + const Standard_Boolean Check2dDistance, + const Standard_Boolean enlarge) +{ + Geom2dAdaptor_Curve C1; + Geom2dAdaptor_Curve C2; + // pcurves are enlarged to be sure that there is intersection + // additionally all periodic curves are taken and points on + // them are filtered using a specific criterion. + + Standard_Real first,last,delta = 0.; + first = fd1->Interference(jf1).FirstParameter(); + last = fd1->Interference(jf1).LastParameter(); + if ((last-first) < Precision::PConfusion()) + return Standard_False; + if(enlarge) delta = Min(0.1,0.05*(last-first)); + Handle(Geom2d_Curve) pcf1 = fd1->Interference(jf1).PCurveOnFace(); + if(pcf1.IsNull()) return Standard_False; + Standard_Boolean isper1 = pcf1->IsPeriodic(); + if(isper1) { + Handle(Geom2d_TrimmedCurve) tr1 = Handle(Geom2d_TrimmedCurve)::DownCast(pcf1); + if(!tr1.IsNull()) pcf1 = tr1->BasisCurve(); + C1.Load(pcf1); + } + else C1.Load(pcf1,first-delta,last+delta); + Standard_Real first1 = pcf1->FirstParameter(), last1 = pcf1->LastParameter(); + + first = fd2->Interference(jf2).FirstParameter(); + last = fd2->Interference(jf2).LastParameter(); + if ((last-first) < Precision::PConfusion()) + return Standard_False; + if(enlarge) delta = Min(0.1,0.05*(last-first)); + Handle(Geom2d_Curve) pcf2 = fd2->Interference(jf2).PCurveOnFace(); + if(pcf2.IsNull()) return Standard_False; + Standard_Boolean isper2 = pcf2->IsPeriodic(); + if(isper2) { + Handle(Geom2d_TrimmedCurve) tr2 = Handle(Geom2d_TrimmedCurve)::DownCast(pcf2); + if(!tr2.IsNull()) pcf2 = tr2->BasisCurve(); + C2.Load(pcf2); + } + else C2.Load(fd2->Interference(jf2).PCurveOnFace(),first-delta,last+delta); + Standard_Real first2 = pcf2->FirstParameter(), last2 = pcf2->LastParameter(); + + IntRes2d_IntersectionPoint int2d; + Geom2dInt_GInter Intersection; + Standard_Integer nbpt,nbseg; + gp_Pnt2d p2d; + if(fd1->Interference(jf1).PCurveOnFace() == fd2->Interference(jf2).PCurveOnFace()) { + Intersection.Perform(C1, + Precision::PIntersection(), + Precision::PIntersection()); + } + else{ + Intersection.Perform(C1,C2, + Precision::PIntersection(), + Precision::PIntersection()); + } + if (Intersection.IsDone()) { + if (!Intersection.IsEmpty()) { + nbseg = Intersection.NbSegments(); + if ( nbseg > 0 ) { + } + nbpt = Intersection.NbPoints(); + if ( nbpt >= 1 ) { + // The criteria sets to filter the found points in a strict way + // are missing. Two different criterions chosen somewhat randomly + // are used : + // - periodic curves : closest to the border. + // - non-periodic curves : the closest to the left of 2 curves + // modulo sens1 and sens2 + int2d = Intersection.Point(1); + p2d = int2d.Value(); + p1 = int2d.ParamOnFirst(); + p2 = int2d.ParamOnSecond(); + if(isper1) p1 = recadre(p1,pref1,sens1,first1,last1); + if(isper2) p2 = recadre(p2,pref2,sens2,first2,last2); + for(Standard_Integer i = 2; i<=nbpt; i++) { + int2d = Intersection.Point(i); + if(isper1) { + Standard_Real pp1 = int2d.ParamOnFirst(); + pp1 = recadre(pp1,pref1,sens1,first1,last1); + if((Abs(pp1 - pref1) < Abs(p1 - pref1))) { + p1 = pp1; + p2 = int2d.ParamOnSecond(); + p2d = int2d.Value(); + } + // Modified by skv - Mon Jun 16 15:51:21 2003 OCC615 Begin + else if (Check2dDistance && + RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d)) { + Standard_Real pp2 = int2d.ParamOnSecond(); + + if(isper2) + pp2 = recadre(pp2,pref2,sens2,first2,last2); + + p1 = pp1; + p2 = pp2; + p2d = int2d.Value(); + } + // Modified by skv - Mon Jun 16 15:51:22 2003 OCC615 End + } + else if(isper2) { + Standard_Real pp2 = int2d.ParamOnSecond(); + pp2 = recadre(pp2,pref2,sens2,first2,last2); + if((Abs(pp2 - pref2) < Abs(p2 - pref2))) { + p2 = pp2; + p1 = int2d.ParamOnFirst(); + p2d = int2d.Value(); + } + // Modified by skv - Mon Jun 16 15:51:21 2003 OCC615 Begin + else if (Check2dDistance && + RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d)) { + Standard_Real pp1 = int2d.ParamOnFirst(); + + if(isper1) + pp1 = recadre(pp1,pref1,sens1,first1,last1); + + p1 = pp1; + p2 = pp2; + p2d = int2d.Value(); + } + // Modified by skv - Mon Jun 16 15:51:22 2003 OCC615 End + } + else if(((int2d.ParamOnFirst() - p1)*sens1 < 0.) && + ((int2d.ParamOnSecond() - p2)*sens2 < 0.)) { + p1 = int2d.ParamOnFirst(); + p2 = int2d.ParamOnSecond(); + p2d = int2d.Value(); + } + else if((Abs(int2d.ParamOnFirst() - pref1) < Abs(p1 - pref1)) && + (Abs(int2d.ParamOnSecond() - pref2) < Abs(p2 - pref2))) { + p1 = int2d.ParamOnFirst(); + p2 = int2d.ParamOnSecond(); + p2d = int2d.Value(); + } + else if (Check2dDistance && RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d)) + { + p1 = int2d.ParamOnFirst(); + p2 = int2d.ParamOnSecond(); + p2d = int2d.Value(); + } + } + return Standard_True; + } + return Standard_False; + } + else { return Standard_False; } + } + else { return Standard_False; } +} +//======================================================================= +//function : Coefficient +//purpose : +//======================================================================= +void ChFi3d_Coefficient(const gp_Vec& V3d, + const gp_Vec& D1u, + const gp_Vec& D1v, + Standard_Real& DU, + Standard_Real& DV) +{ + const Standard_Real AA = D1u.SquareMagnitude(); + const Standard_Real BB = D1u.Dot(D1v); + const Standard_Real CC = D1v.SquareMagnitude(); + const Standard_Real DD = D1u.Dot(V3d); + const Standard_Real EE = D1v.Dot(V3d); + const Standard_Real Delta = AA*CC-BB*BB; + DU = (DD*CC-EE*BB)/Delta; + DV = (AA*EE-BB*DD)/Delta; +} +//======================================================================= +//function : ReparamPcurv +//purpose : Dans le cas ou la pcurve est une BSpline on verifie +// ses parametres et on la reparametre eventuellement. +//======================================================================= +void ChFi3d_ReparamPcurv(const Standard_Real Uf, + const Standard_Real Ul, + Handle(Geom2d_Curve)& Pcurv) +{ + if(Pcurv.IsNull()) return; + Standard_Real upcf = Pcurv->FirstParameter(); + Standard_Real upcl = Pcurv->LastParameter(); + Handle(Geom2d_Curve) basis = Pcurv; + Handle(Geom2d_TrimmedCurve) trpc = Handle(Geom2d_TrimmedCurve)::DownCast(Pcurv); + if(!trpc.IsNull()) basis = trpc->BasisCurve(); + Handle(Geom2d_BSplineCurve) pc = Handle(Geom2d_BSplineCurve)::DownCast(basis); + if(pc.IsNull()) return; + if(Abs(upcf - pc->FirstParameter()) > Precision::PConfusion() || + Abs(upcl - pc->LastParameter()) > Precision::PConfusion()) { + pc->Segment(upcf,upcl); + } + if(Abs(Uf - pc->FirstParameter()) > Precision::PConfusion() || + Abs(Ul - pc->LastParameter()) > Precision::PConfusion()) { + TColgp_Array1OfPnt2d pol(1,pc->NbPoles()); + pc->Poles(pol); + TColStd_Array1OfReal kn(1,pc->NbKnots()); + pc->Knots(kn); + TColStd_Array1OfInteger mu(1,pc->NbKnots()); + pc->Multiplicities(mu); + Standard_Integer deg = pc->Degree(); + BSplCLib::Reparametrize(Uf,Ul,kn); + pc = new Geom2d_BSplineCurve(pol,kn,mu,deg); + } + Pcurv = pc; +} +//======================================================================= +//function : ProjectPCurv +//purpose : Calculation of the pcurve corresponding to a line of intersection +// 3d. Should be called only in analytic cases. +//======================================================================= +void ChFi3d_ProjectPCurv(const Handle(Adaptor3d_HCurve)& HCg, + const Handle(Adaptor3d_HSurface)& HSg, + Handle(Geom2d_Curve)& Pcurv, + const Standard_Real tol, + Standard_Real& tolreached) +{ + if (HSg->GetType() != GeomAbs_BezierSurface && + HSg->GetType() != GeomAbs_BSplineSurface) { + + ProjLib_ProjectedCurve Projc (HSg,HCg,tol); + tolreached = Projc.GetTolerance(); + switch (Projc.GetType()) { + case GeomAbs_Line : + { + Pcurv = new Geom2d_Line(Projc.Line()); + } + break; + case GeomAbs_Circle : + { + Pcurv = new Geom2d_Circle(Projc.Circle()); + } + break; + case GeomAbs_Ellipse : + { + Pcurv = new Geom2d_Ellipse(Projc.Ellipse()); + } + break; + case GeomAbs_Hyperbola : + { + Pcurv = new Geom2d_Hyperbola(Projc.Hyperbola()); + } + break; + case GeomAbs_Parabola : + { + Pcurv = new Geom2d_Parabola(Projc.Parabola()); + } + break; + case GeomAbs_BezierCurve : + { + Pcurv = Projc.Bezier(); + } + break; + case GeomAbs_BSplineCurve : + { + Pcurv = Projc.BSpline(); + } + break; + default: + Standard_NotImplemented::Raise("echec approximation de la pcurve "); + } + } +} +//======================================================================= +//function : CheckSameParameter +//purpose : Controls a posteriori that sameparameter worked well +//======================================================================= +Standard_Boolean ChFi3d_CheckSameParameter (const Handle(Adaptor3d_HCurve)& C3d, + Handle(Geom2d_Curve)& Pcurv, + const Handle(Adaptor3d_HSurface)& S, + const Standard_Real tol3d, + Standard_Real& tolreached) +{ + tolreached = 0.; + Standard_Real f = C3d->FirstParameter(); + Standard_Real l = C3d->LastParameter(); + Standard_Integer nbp = 45; + Standard_Real step = 1./(nbp -1); + for(Standard_Integer i = 0; i < nbp; i++) { + Standard_Real t,u,v; + t = step * i; + t = (1-t) * f + t * l; + Pcurv->Value(t).Coord(u,v); + gp_Pnt pS = S->Value(u,v); + gp_Pnt pC = C3d->Value(t); + Standard_Real d2 = pS.SquareDistance(pC); + tolreached = Max(tolreached,d2); + } + tolreached = sqrt(tolreached); + if(tolreached > tol3d) { + tolreached *= 2.; + return Standard_False; + } + tolreached *= 2.; + tolreached = Max(tolreached,Precision::Confusion()); + return Standard_True; +} +//======================================================================= +//function : SameParameter +//purpose : Encapsulation of Sameparameter +//======================================================================= +Standard_Boolean ChFi3d_SameParameter(const Handle(Adaptor3d_HCurve)& C3d, + Handle(Geom2d_Curve)& Pcurv, + const Handle(Adaptor3d_HSurface)& S, + const Standard_Real tol3d, + Standard_Real& tolreached) +{ + if(ChFi3d_CheckSameParameter(C3d,Pcurv,S,tol3d,tolreached)) return Standard_True; + Approx_SameParameter sp(C3d,Pcurv,S,tol3d); + if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d(); + else if(!sp.IsDone() && !sp.IsSameParameter()) { + return Standard_False; + } + tolreached = sp.TolReached(); + return Standard_True; +} +//======================================================================= +//function : SameParameter +//purpose : Encapsulation de Sameparameter +//======================================================================= +Standard_Boolean ChFi3d_SameParameter(const Handle(Geom_Curve)& C3d, + Handle(Geom2d_Curve)& Pcurv, + const Handle(Geom_Surface)& S, + const Standard_Real Pardeb, + const Standard_Real Parfin, + const Standard_Real tol3d, + Standard_Real& tolreached) +{ + /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface(S)); + /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve(C3d,Pardeb,Parfin)); + return ChFi3d_SameParameter(hc,Pcurv,hs,tol3d,tolreached); +} +//======================================================================= +//function : ComputePCurv +//purpose : Calculates a straight line in form of BSpline +// to guarantee the same range and parameters as of the +// reference 3D curve. +//======================================================================= +void ChFi3d_ComputePCurv(const Handle(Adaptor3d_HCurve)& C3d, + const gp_Pnt2d& UV1, + const gp_Pnt2d& UV2, + Handle(Geom2d_Curve)& Pcurv, + const Handle(Adaptor3d_HSurface)& S, + const Standard_Real Pardeb, + const Standard_Real Parfin, + const Standard_Real tol3d, + Standard_Real& tolreached, + const Standard_Boolean reverse) +{ + ChFi3d_ComputePCurv(UV1,UV2,Pcurv,Pardeb,Parfin,reverse); + ChFi3d_SameParameter(C3d,Pcurv,S,tol3d,tolreached); +} +//======================================================================= +//function : ComputePCurv +//purpose : Calculates a straight line in form of BSpline +// to guarantee the same range and parameters as of the +// reference 3D curve. +//======================================================================= +void ChFi3d_ComputePCurv(const Handle(Geom_Curve)& C3d, + const gp_Pnt2d& UV1, + const gp_Pnt2d& UV2, + Handle(Geom2d_Curve)& Pcurv, + const Handle(Geom_Surface)& S, + const Standard_Real Pardeb, + const Standard_Real Parfin, + const Standard_Real tol3d, + Standard_Real& tolreached, + const Standard_Boolean reverse) +{ + /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface(S)); + /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve(C3d,Pardeb,Parfin)); + ChFi3d_ComputePCurv(hc,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,reverse); +} +//======================================================================= +//function : ComputePCurv +//purpose : Calculates a straight line in form of BSpline +// to guarantee the same range. +//======================================================================= +void ChFi3d_ComputePCurv(const gp_Pnt2d& UV1, + const gp_Pnt2d& UV2, + Handle(Geom2d_Curve)& Pcurv, + const Standard_Real Pardeb, + const Standard_Real Parfin, + const Standard_Boolean reverse) +{ + const Standard_Real tol = Precision::PConfusion(); + gp_Pnt2d p1,p2; + if (!reverse) { + p1 = UV1; + p2 = UV2; + } + else { + p1 = UV2; + p2 = UV1; + } + + if (Abs(p1.X()-p2.X()) <= tol && + Abs((p2.Y()-p1.Y())-(Parfin-Pardeb)) <= tol) { + gp_Pnt2d ppp(p1.X(),p1.Y()-Pardeb); + Pcurv = new Geom2d_Line(ppp,gp::DY2d()); + } + else if (Abs(p1.X()-p2.X()) <= tol && + Abs((p1.Y()-p2.Y())-(Parfin-Pardeb)) <= tol) { + gp_Pnt2d ppp(p1.X(),p1.Y()+Pardeb); + Pcurv = new Geom2d_Line(ppp,gp::DY2d().Reversed()); + } + else if (Abs(p1.Y()-p2.Y()) <= tol && + Abs((p2.X()-p1.X())-(Parfin-Pardeb)) <= tol) { + gp_Pnt2d ppp(p1.X()-Pardeb,p1.Y()); + Pcurv = new Geom2d_Line(ppp,gp::DX2d()); + } + else if (Abs(p1.Y()-p2.Y()) <= tol && + Abs((p1.X()-p2.X())-(Parfin-Pardeb)) <= tol) { + gp_Pnt2d ppp(p1.X()+Pardeb,p1.Y()); + Pcurv = new Geom2d_Line(ppp,gp::DX2d().Reversed()); + } + else{ + TColgp_Array1OfPnt2d p(1,2); + TColStd_Array1OfReal k(1,2); + TColStd_Array1OfInteger m(1,2); + m.Init(2); + k(1) = Pardeb; + k(2) = Parfin; + p(1) = p1; + p(2) = p2; + Pcurv = new Geom2d_BSplineCurve(p,k,m,1); + } + Pcurv = new Geom2d_TrimmedCurve(Pcurv,Pardeb,Parfin); +} +//======================================================================= +//function : ChFi3d_mkbound +//purpose : +//======================================================================= +Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Fac, + Handle(Geom2d_Curve)& curv, + const Standard_Integer sens1, + const gp_Pnt2d& pfac1, + const gp_Vec2d& vfac1, + const Standard_Integer sens2, + const gp_Pnt2d& pfac2, + const gp_Vec2d& vfac2, + const Standard_Real t3d, + const Standard_Real ta) +{ + gp_Dir2d v1(vfac1); + if(sens1 == 1) v1.Reverse(); + gp_Dir2d v2(vfac2); + if(sens2 == 1) v2.Reverse(); + curv = ChFi3d_BuildPCurve(Fac,pfac1,v1,pfac2,v2,Standard_False); + return ChFi3d_mkbound(Fac,curv,t3d,ta); +} +//======================================================================= +//function : ChFi3d_mkbound +//purpose : +//======================================================================= +Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Surf, + Handle(Geom2d_Curve)& curv, + const Standard_Integer sens1, + const gp_Pnt2d& p1, + gp_Vec& v1, + const Standard_Integer sens2, + const gp_Pnt2d& p2, + gp_Vec& v2, + const Standard_Real t3d, + const Standard_Real ta) +{ + if(sens1 == 1) v1.Reverse(); + if(sens2 == 1) v2.Reverse(); + curv = ChFi3d_BuildPCurve(Surf,p1,v1,p2,v2); + return ChFi3d_mkbound(Surf,curv,t3d,ta); +} +//======================================================================= +//function : ChFi3d_mkbound +//purpose : +//======================================================================= +Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Geom_Surface)& s, + const gp_Pnt2d& p1, + const gp_Pnt2d& p2, + const Standard_Real t3d, + const Standard_Real ta, + const Standard_Boolean isfreeboundary) +{ + Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(s); + return ChFi3d_mkbound(HS,p1,p2,t3d,ta,isfreeboundary); +} +//======================================================================= +//function : ChFi3d_mkbound +//purpose : +//======================================================================= +Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& HS, + const gp_Pnt2d& p1, + const gp_Pnt2d& p2, + const Standard_Real t3d, + const Standard_Real ta, + const Standard_Boolean isfreeboundary) +{ + TColgp_Array1OfPnt2d pol(1,2); + pol(1)=p1; + pol(2)=p2; + Handle(Geom2d_Curve) curv = new Geom2d_BezierCurve(pol); + return ChFi3d_mkbound(HS,curv,t3d,ta,isfreeboundary); +} +//======================================================================= +//function : ChFi3d_mkbound +//purpose : +//======================================================================= +Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& HS, + const Handle(Geom2d_Curve)& curv, + const Standard_Real t3d, + const Standard_Real ta, + const Standard_Boolean isfreeboundary) +{ + Handle(Geom2dAdaptor_HCurve) HC = new Geom2dAdaptor_HCurve(curv); + Adaptor3d_CurveOnSurface COnS(HC,HS); + if (isfreeboundary) { + Handle(Adaptor3d_HCurveOnSurface) HCOnS = new Adaptor3d_HCurveOnSurface(COnS); + return new GeomFill_SimpleBound(HCOnS,t3d,ta); + } + return new GeomFill_BoundWithSurf(COnS,t3d,ta); +} +//======================================================================= +//function : ChFi3d_mkbound +//purpose : +//======================================================================= +Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Fac, + Handle(Geom2d_Curve)& curv, + const gp_Pnt2d& p1, + const gp_Pnt2d& p2, + const Standard_Real t3d, + const Standard_Real ta, + const Standard_Boolean isfreeboundary) +{ + TColgp_Array1OfPnt2d pol(1,2); + pol(1)=p1; + pol(2)=p2; + curv = new Geom2d_BezierCurve(pol); + return ChFi3d_mkbound(Fac,curv,t3d,ta,isfreeboundary); +} +//======================================================================= +//function : ChFi3d_BuildPCurve +//purpose : +//======================================================================= +Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const gp_Pnt2d& p1, + gp_Dir2d& d1, + const gp_Pnt2d& p2, + gp_Dir2d& d2, + const Standard_Boolean redresse) +{ + gp_Vec2d vref(p1,p2); + gp_Dir2d dref(vref); + Standard_Real mref = vref.Magnitude(); + if(redresse) { + if(d1.Dot(dref) < 0.) d1.Reverse(); + if(d2.Dot(dref) > 0.) d2.Reverse(); + } + //On fait une cubique a la mords moi le noeud + TColgp_Array1OfPnt2d pol(1,4); + pol(1)=p1; + pol(4)=p2; + Standard_Real Lambda1 = Max(Abs(d2.Dot(d1)),Abs(dref.Dot(d1))); + Lambda1 = Max(0.5*mref*Lambda1,1.e-5); + pol(2) = gp_Pnt2d(p1.XY()+Lambda1*d1.XY()); + Standard_Real Lambda2 = Max(Abs(d1.Dot(d2)),Abs(dref.Dot(d2))); + Lambda2 = Max(0.5*mref*Lambda2,1.e-5); + pol(3)=gp_Pnt2d(p2.XY()+Lambda2*d2.XY()); + return new Geom2d_BezierCurve(pol); +} +//======================================================================= +//function : ChFi3d_BuildPCurve +//purpose : +//======================================================================= +Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const Handle(Adaptor3d_HSurface)& Surf, + const gp_Pnt2d& p1, + const gp_Vec2d& v1, + const gp_Pnt2d& p2, + const gp_Vec2d& v2, + const Standard_Boolean redresse) +{ + gp_Pnt2d pp1 = p1, pp2 = p2; + gp_Vec2d vv1 = v1, vv2 = v2; + const Standard_Real ures = Surf->UResolution(1.); + const Standard_Real vres = Surf->VResolution(1.); + const Standard_Real invures = 1./ures; + const Standard_Real invvres = 1./vres; + pp1.SetX(invures*pp1.X()); pp1.SetY(invvres*pp1.Y()); + pp2.SetX(invures*pp2.X()); pp2.SetY(invvres*pp2.Y()); + vv1.SetX(invures*vv1.X()); vv1.SetY(invvres*vv1.Y()); + vv2.SetX(invures*vv2.X()); vv2.SetY(invvres*vv2.Y()); + gp_Dir2d d1(vv1), d2(vv2); + Handle(Geom2d_Curve) g2dc = ChFi3d_BuildPCurve(pp1,d1,pp2,d2,redresse); + Handle(Geom2d_BezierCurve) pc = Handle(Geom2d_BezierCurve)::DownCast(g2dc); + const Standard_Integer nbp = pc->NbPoles(); + for(Standard_Integer ip = 1; ip <= nbp; ip++) { + gp_Pnt2d pol = pc->Pole(ip); + pol.SetX(ures*pol.X()); pol.SetY(vres*pol.Y()); + pc->SetPole(ip,pol); + } + return pc; +} +//======================================================================= +//function : ChFi3d_BuildPCurve +//purpose : +//======================================================================= +Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const Handle(Adaptor3d_HSurface)& Surf, + const gp_Pnt2d& p1, + const gp_Vec& v1, + const gp_Pnt2d& p2, + const gp_Vec& v2, + const Standard_Boolean redresse) +{ + gp_Vec D1u,D1v; + gp_Pnt PP1,PP2; + Standard_Real DU,DV; + Surf->D1(p1.X(),p1.Y(),PP1,D1u,D1v); + ChFi3d_Coefficient(v1,D1u,D1v,DU,DV); + gp_Vec2d vv1(DU,DV); + Surf->D1(p2.X(),p2.Y(),PP2,D1u,D1v); + ChFi3d_Coefficient(v2,D1u,D1v,DU,DV); + gp_Vec2d vv2(DU,DV); + gp_Vec Vref(PP1,PP2); + if(redresse) { + if(Vref.Dot(v1) < 0.) vv1.Reverse(); + if(Vref.Dot(v2) > 0.) vv2.Reverse(); + } + return ChFi3d_BuildPCurve(Surf,p1,vv1,p2,vv2,0); +} +//======================================================================= +//function : ComputeArete +//purpose : +// to fill with s.d. a fillet with pcurves constructed as follows +// firstpoint on S1 -------------edge:curve3d/pcurves--->lastpoint on S1 +// | | +// | | +// | | +// edge:curve 3d/pcurves fillet edge +// | attention it is necessary to test orientation of the fillet before| +// | determining the transitions pcurves/fillet | +// | | +// \/ \/ +// firstpoint sur S2 -------------edge:courbe3d/pcurves--->lastpoint sur S2 +// +//======================================================================= +void ChFi3d_ComputeArete(const ChFiDS_CommonPoint& P1, + const gp_Pnt2d& UV1, + const ChFiDS_CommonPoint& P2, + const gp_Pnt2d& UV2, + const Handle(Geom_Surface)& Surf, + Handle(Geom_Curve)& C3d, + Handle(Geom2d_Curve)& Pcurv, + Standard_Real& Pardeb, + Standard_Real& Parfin, + const Standard_Real tol3d, + const Standard_Real tol2d, + Standard_Real& tolreached, + const Standard_Integer IFlag) + // IFlag=0 pcurve et courbe 3d + // IFlag>0 pcurve (parametrage impose si IFlag=2) +{ + /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface()); + /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve()); + + tolreached = tol3d; + + if (Abs(UV1.X()-UV2.X()) <= tol2d) { + if (IFlag == 0) { + Pardeb = UV1.Y(); + Parfin = UV2.Y(); + C3d = Surf->UIso(UV1.X()); + if(Pardeb > Parfin) { + Pardeb = C3d->ReversedParameter(Pardeb); + Parfin = C3d->ReversedParameter(Parfin); + C3d->Reverse(); + } + Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C3d); + if(!tc.IsNull()) { + C3d = tc->BasisCurve(); + if (C3d->IsPeriodic()) { + ElCLib::AdjustPeriodic(C3d->FirstParameter(),C3d->LastParameter(), + tol2d,Pardeb,Parfin); + } + } + } + if(IFlag != 1) { + hs->ChangeSurface().Load(Surf); + hc->ChangeCurve().Load(C3d,Pardeb,Parfin); + ChFi3d_ComputePCurv(hc,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,Standard_False); + } + else{ + Pcurv = new Geom2d_Line(UV1,gp_Vec2d(UV1,UV2)); + } + } + else if (Abs(UV1.Y()-UV2.Y())<=tol2d) { + //iso v + if (IFlag == 0) { + Pardeb = UV1.X(); + Parfin = UV2.X(); + C3d = Surf->VIso(UV1.Y()); + if(Pardeb > Parfin) { + Pardeb = C3d->ReversedParameter(Pardeb); + Parfin = C3d->ReversedParameter(Parfin); + C3d->Reverse(); + } + Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C3d); + if(!tc.IsNull()) { + C3d = tc->BasisCurve(); + if (C3d->IsPeriodic()) { + ElCLib::AdjustPeriodic(C3d->FirstParameter(),C3d->LastParameter(), + tol2d,Pardeb,Parfin); + } + } + } + if(IFlag != 1) { + hs->ChangeSurface().Load(Surf); + hc->ChangeCurve().Load(C3d,Pardeb,Parfin); + ChFi3d_ComputePCurv(hc,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,Standard_False); + } + else{ + Pcurv = new Geom2d_Line(UV1,gp_Vec2d(UV1,UV2)); + } + } + else if (IFlag == 0) { + + if (P1.IsVertex() || P2.IsVertex() || !P1.IsOnArc() || !P2.IsOnArc()) { + // A straight line is constructed to avoid + // arc and tangent. + TColgp_Array1OfPnt2d qoles(1,2); + qoles(1)=UV1; + qoles(2)=UV2; + Pcurv = new Geom2d_BezierCurve(qoles); + } + else { + BRepAdaptor_Curve C1(P1.Arc()); + gp_Pnt Pp; + gp_Vec Vv1; + C1.D1(P1.ParameterOnArc(),Pp,Vv1); + C1.Initialize(P2.Arc()); + gp_Vec Vv2; + C1.D1(P2.ParameterOnArc(),Pp,Vv2); + hs->ChangeSurface().Load(Surf); + Pcurv = ChFi3d_BuildPCurve(hs,UV1,Vv1,UV2,Vv2,Standard_True); + // There are some cases when PCurve constructed in this way + // leaves the surface, in particular if it results from an + // extension. A posteriori checking is required and if + // the curve leaves the surface it is replaced by straight line UV1 UV2 + // non regarding the tangency with neighboring arcs! + Bnd_Box2d bs; + Standard_Real umin,umax,vmin,vmax; + Surf->Bounds(umin,umax,vmin,vmax); + bs.Update(umin,vmin,umax,vmax); + Standard_Boolean aIN = Standard_True; + for(Standard_Integer ii = 1; ii <= 4 && aIN; ii++) { + if(bs.IsOut((*((Handle_Geom2d_BezierCurve*) &Pcurv))->Pole(ii))) { + aIN = Standard_False; + TColgp_Array1OfPnt2d qoles(1,2); + qoles(1)=UV1; + qoles(2)=UV2; + Pcurv = new Geom2d_BezierCurve(qoles); + } + } + } + Geom2dAdaptor_Curve AC(Pcurv); + Handle(Geom2dAdaptor_HCurve) AHC = + new Geom2dAdaptor_HCurve(AC); + GeomAdaptor_Surface AS(Surf); + Handle(GeomAdaptor_HSurface) AHS = + new GeomAdaptor_HSurface(AS); + Adaptor3d_CurveOnSurface Cs(AHC,AHS); + Pardeb = Cs.FirstParameter(); + Parfin = Cs.LastParameter(); + Standard_Real avtol; + GeomLib::BuildCurve3d(tol3d,Cs,Pardeb,Parfin,C3d,tolreached,avtol); + } + else { + hs->ChangeSurface().Load(Surf); + hc->ChangeCurve().Load(C3d,Pardeb,Parfin); + ChFi3d_ProjectPCurv(hc,hs,Pcurv,tol3d,tolreached); + gp_Pnt2d p2d = Pcurv->Value(Pardeb); + if(!UV1.IsEqual(p2d,Precision::PConfusion())) { + gp_Vec2d v2d(p2d,UV1); + Pcurv->Translate(v2d); + } + } +} +//======================================================================= +//function : FilCurveInDS +//purpose : +//======================================================================= +Handle(TopOpeBRepDS_SurfaceCurveInterference) ChFi3d_FilCurveInDS +(const Standard_Integer Icurv, + const Standard_Integer Isurf, + const Handle(Geom2d_Curve)& Pcurv, + const TopAbs_Orientation Et) +{ + Handle(TopOpeBRepDS_SurfaceCurveInterference) SC1; + SC1 = new TopOpeBRepDS_SurfaceCurveInterference(TopOpeBRepDS_Transition(Et), + TopOpeBRepDS_SURFACE, + Isurf,TopOpeBRepDS_CURVE,Icurv, + Pcurv); + return SC1; +} +//======================================================================= +//function : TrsfTrans +//purpose : +// +//======================================================================= +TopAbs_Orientation ChFi3d_TrsfTrans(const IntSurf_TypeTrans T1) +{ + switch (T1) { + case IntSurf_In: return TopAbs_FORWARD; + case IntSurf_Out: return TopAbs_REVERSED; + } + return TopAbs_INTERNAL; +} +//======================================================================= +//function : FilCommonPoint +//purpose : Loading of the common point +// management of the case when it happens on already existing vertex. +//======================================================================= +Standard_EXPORT void ChFi3d_FilCommonPoint(const BRepBlend_Extremity& SP, + const IntSurf_TypeTrans TransLine, + const Standard_Boolean Start, + ChFiDS_CommonPoint& CP, + const Standard_Real Tol) +{ +// BRep_Tool Outil; + Standard_Real Dist, maxtol = Max(Tol,CP.Tolerance()); + + CP.SetPoint(SP.Value()); // One starts with the point and the vector + if (SP.HasTangent()) { + if (Start) { + CP.SetVector(SP.Tangent().Reversed()); // The tangent is oriented to the exit + } + else { + CP.SetVector(SP.Tangent()); + } + } + + CP.SetParameter(SP.ParameterOnGuide()); // and the parameter of the spine + + if (SP.IsVertex()) { // the Vertex is loaded if required + // (inside of a face) + TopoDS_Vertex V = + Handle(BRepTopAdaptor_HVertex)::DownCast(SP.Vertex())->Vertex(); + + CP.SetVertex(V); + Dist = (SP.Value()).Distance(BRep_Tool::Pnt(V)); + //// modified by jgv, 18.09.02 for OCC571 //// + //maxtol += Dist; + maxtol = Max( Dist, maxtol ); + ////////////////////////////////////////////// + CP.SetPoint(BRep_Tool::Pnt(V)); + + //the sequence of arcs the information is known by thee vertex (ancestor) + //in this case the transitions are not computed, it is done by this program + } + + if (SP.NbPointOnRst() != 0) { // An arc, and/or a vertex is loaded + + const BRepBlend_PointOnRst& PR = SP.PointOnRst(1); + Handle(BRepAdaptor_HCurve2d) + Harc = Handle(BRepAdaptor_HCurve2d)::DownCast(PR.Arc()); + if(!Harc.IsNull()) { + + Standard_Real DistF, DistL, LeParamAmoi; + Standard_Integer Index_min; + TopoDS_Edge E = Harc->ChangeCurve2d().Edge(); + + TopoDS_Vertex V[2]; + TopExp::Vertices(E, V[0], V[1]); + + DistF = (SP.Value()).Distance(BRep_Tool::Pnt(V[0])); + DistL = (SP.Value()).Distance(BRep_Tool::Pnt(V[1])); + if (DistF<DistL) { Index_min = 0; + Dist = DistF; } + else { Index_min = 1; + Dist = DistL; } + + if (Dist <= maxtol + BRep_Tool::Tolerance(V[Index_min]) ) { + // a prexisting vertex has been met + CP.SetVertex(V[Index_min]); //the old vertex is loaded + CP.SetPoint( BRep_Tool::Pnt(V[Index_min]) ); + maxtol = Max(BRep_Tool::Tolerance(V[Index_min]),maxtol); + //// modified by jgv, 18.09.02 for OCC571 //// + //maxtol += Dist; + maxtol = Max( Dist, maxtol ); + ////////////////////////////////////////////// + LeParamAmoi = BRep_Tool::Parameter(V[Index_min], E); + } + else { // Creation of an arc only + maxtol = Max(BRep_Tool::Tolerance(E),maxtol); + maxtol = Max(SP.Tolerance(),maxtol); + LeParamAmoi = PR.ParameterOnArc(); + } + + // Definition of the arc + TopAbs_Orientation Tr; + TopAbs_Orientation Or = E.Orientation(); + if (Start) { + Tr = TopAbs::Reverse(TopAbs::Compose(ChFi3d_TrsfTrans(TransLine),Or)); + } + else { + Tr = TopAbs::Compose(ChFi3d_TrsfTrans(TransLine),Or); + } + CP.SetArc(maxtol, E, LeParamAmoi, Tr); + } + } + CP.SetTolerance(maxtol); // Finally, the tolerance. +} + +//======================================================================= +//function : SolidIndex +//purpose : +//======================================================================= +Standard_Integer ChFi3d_SolidIndex(const Handle(ChFiDS_Spine)& sp, + TopOpeBRepDS_DataStructure& DStr, + ChFiDS_Map& MapESo, + ChFiDS_Map& MapESh) +{ + if(sp.IsNull() || sp->NbEdges() == 0) + Standard_Failure::Raise("SolidIndex : Spine incomplete"); + TopoDS_Shape edref= sp->Edges(1); + TopoDS_Shape shellousolid; + if(!MapESo(edref).IsEmpty()) shellousolid = MapESo(edref).First(); + else shellousolid = MapESh(edref).First(); + const Standard_Integer solidindex = DStr.AddShape(shellousolid); + return solidindex; +} +//======================================================================= +//function : IndexPointInDS +//purpose : +//======================================================================= +Standard_Integer ChFi3d_IndexPointInDS(const ChFiDS_CommonPoint& P1, + TopOpeBRepDS_DataStructure& DStr) +{ + if (P1.IsVertex()) { + // ---------------------------------> !*!*!* + // Attention : it is necessary ti implement a mechanism + // controlling tolerance. + BRep_Builder B; + B.UpdateVertex(P1.Vertex(), P1.Point(), P1.Tolerance()); + return DStr.AddShape(P1.Vertex()); + } + return DStr.AddPoint(TopOpeBRepDS_Point(P1.Point(),P1.Tolerance())); +} +//======================================================================= +//function : FilPointInDS +//purpose : +//======================================================================= +Handle(TopOpeBRepDS_CurvePointInterference) + ChFi3d_FilPointInDS(const TopAbs_Orientation Et, + const Standard_Integer Ic, + const Standard_Integer Ip, + const Standard_Real Par, + const Standard_Boolean IsVertex) +{ + Handle(TopOpeBRepDS_CurvePointInterference) CP1; + if (IsVertex) + CP1 = new TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et), + TopOpeBRepDS_CURVE,Ic, + TopOpeBRepDS_VERTEX,Ip,Par); + else + CP1 = new TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et), + TopOpeBRepDS_CURVE,Ic, + TopOpeBRepDS_POINT,Ip,Par); + return CP1; +} +//======================================================================= +//function : FilVertexInDS +//purpose : +//======================================================================= +Handle(TopOpeBRepDS_CurvePointInterference) + ChFi3d_FilVertexInDS(const TopAbs_Orientation Et, + const Standard_Integer Ic, + const Standard_Integer Ip, + const Standard_Real Par) +{ + + Handle(TopOpeBRepDS_CurvePointInterference) CP1 = new + TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et), + TopOpeBRepDS_CURVE,Ic, + TopOpeBRepDS_VERTEX,Ip,Par); + return CP1; +} +//======================================================================= +//function : Orientation +//purpose : returns the orientation of the interference (the first found +// in the list). +//======================================================================= + +static Standard_Boolean + ChFi3d_Orientation(const TopOpeBRepDS_ListOfInterference& LI, + const Standard_Integer igros, + const Standard_Integer ipetit, + TopAbs_Orientation& Or, + const Standard_Boolean isvertex = Standard_False, + const Standard_Boolean aprendre = Standard_False) +{ + //In case, when it is necessary to insert a point/vertex, it should be + //known if this is a point or a vertex, because their index can be the same. + TopOpeBRepDS_Kind typepetit; + if (isvertex) + typepetit = TopOpeBRepDS_VERTEX; + else + typepetit = TopOpeBRepDS_POINT; + TopOpeBRepDS_ListIteratorOfListOfInterference itLI(LI); + for (; itLI.More(); itLI.Next() ) { + const Handle(TopOpeBRepDS_Interference)& cur = itLI.Value(); + TopOpeBRepDS_Kind GK; + TopOpeBRepDS_Kind SK; + Standard_Integer S; + Standard_Integer G; + cur->GKGSKS(GK,G,SK,S); + if (aprendre) { + if ( S == igros && G == ipetit && GK == typepetit) { + Or = cur->Transition().Orientation(TopAbs_IN); + return Standard_True; + } + } + else { + if ( S == igros && G == ipetit) { + Or = cur->Transition().Orientation(TopAbs_IN); + return Standard_True; + } + } + } + return Standard_False; +} + +//======================================================================= +//function : Contains +//purpose : Check if the interference does not already exist. +//==================================================================== + +static Standard_Boolean ChFi3d_Contains +(const TopOpeBRepDS_ListOfInterference& LI, + const Standard_Integer igros, + const Standard_Integer ipetit, + const Standard_Boolean isvertex = Standard_False, + const Standard_Boolean aprendre = Standard_False) +{ + TopAbs_Orientation bidOr; + return ChFi3d_Orientation(LI,igros,ipetit,bidOr,isvertex,aprendre); +} +//======================================================================= +//function : QueryAddVertexInEdge +//purpose : +//======================================================================= +static void QueryAddVertexInEdge(TopOpeBRepDS_ListOfInterference& LI, + const Standard_Integer IC, + const Standard_Integer IV, + const Standard_Real par, + const TopAbs_Orientation Or) +{ + TopOpeBRepDS_ListIteratorOfListOfInterference it(LI); + for (; it.More(); it.Next() ) { + const Handle(TopOpeBRepDS_Interference)& cur = it.Value(); + const Handle(TopOpeBRepDS_CurvePointInterference)& cpi = + Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(cur); + if(!cpi.IsNull()) { + Standard_Integer newIV = cpi->Geometry(); + TopOpeBRepDS_Kind kv = cpi->GeometryType(); + TopAbs_Orientation newOr = cpi->Transition().Orientation(TopAbs_IN); + Standard_Real newpar = cpi->Parameter(); + if(IV == newIV && kv == TopOpeBRepDS_VERTEX && + Or == newOr && Abs(par - newpar) < 1.e-10) { + return; + } + } + } + Handle(TopOpeBRepDS_CurvePointInterference) interf = + ChFi3d_FilVertexInDS(Or,IC,IV,par); + LI.Append(interf); +} + +//======================================================================= +//function : CutEdge +//purpose : +//======================================================================= +static void CutEdge(const TopoDS_Vertex& V, + const Handle(ChFiDS_SurfData)& SD, + TopOpeBRepDS_DataStructure& DStr, + const Standard_Boolean , + const Standard_Integer ons) +{ + if(!SD->IsOnCurve(ons)) return; + Standard_Integer IC = SD->IndexOfC(ons); + Standard_Integer IV = DStr.AddShape(V); + TopOpeBRepDS_ListOfInterference& LI = DStr.ChangeShapeInterferences(IC); + TopoDS_Edge E = TopoDS::Edge(DStr.Shape(IC)); + E.Orientation(TopAbs_FORWARD); + TopExp_Explorer ex; + + // process them checking that it has not been done already. + for(ex.Init(E,TopAbs_VERTEX);ex.More();ex.Next()) { + const TopoDS_Vertex& vv = TopoDS::Vertex(ex.Current()); + if(vv.IsSame(V)) { + TopAbs_Orientation Or = TopAbs::Reverse(vv.Orientation()); + Standard_Real par = BRep_Tool::Parameter(vv,E); + QueryAddVertexInEdge(LI,IC,IV,par,Or); + } + } +} +//======================================================================= +//function : findIndexPoint +//purpose : returns in <ipon> index of point bounding a courve interfering +// with <Fd> and coinciding with last common point on <OnS> face +//======================================================================= +static Standard_Boolean + findIndexPoint(const TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_SurfData)& Fd, + const Standard_Integer OnS, + Standard_Integer& ipoin) +{ + ipoin = 0; + gp_Pnt P = Fd->Vertex(Standard_False,OnS).Point(); + + TopOpeBRepDS_ListIteratorOfListOfInterference SCIIt, CPIIt; + + SCIIt.Initialize (DStr.SurfaceInterferences(Fd->Surf())); + for (; SCIIt.More(); SCIIt.Next()) { + Handle(TopOpeBRepDS_SurfaceCurveInterference) SCI = + Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(SCIIt.Value()); + if (SCI.IsNull()) continue; + CPIIt.Initialize (DStr.CurveInterferences(SCI->Geometry())); + for (; CPIIt.More(); CPIIt.Next()) { + Handle(TopOpeBRepDS_CurvePointInterference) CPI = + Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(CPIIt.Value()); + if (CPI.IsNull()) continue; + Standard_Integer iPoint = CPI->Geometry(); + TopOpeBRepDS_Point tp = DStr.Point(iPoint); + if (P.IsEqual(tp.Point(), tp.Tolerance())) { + ipoin = iPoint; + return Standard_True; + } + } + } + return Standard_False; +} +//======================================================================= +//function : FilDS +//purpose : +//======================================================================= +void ChFi3d_FilDS(const Standard_Integer SolidIndex, + const Handle(ChFiDS_Stripe)& CorDat, + TopOpeBRepDS_DataStructure& DStr, + ChFiDS_Regularities& reglist, + const Standard_Real tol3d, + const Standard_Real tol2d) +{ +// BRep_Tool Outil; + TopExp_Explorer ex; + Handle(ChFiDS_Spine) spine = CorDat->Spine(); + Standard_Boolean Closed = Standard_False; + Standard_Boolean Degene = 0, isVertex1 = 0, isVertex2 = 0, Singulier_en_Bout = 0; + if(!spine.IsNull()) { + Closed = spine->IsPeriodic(); + } + const ChFiDS_SequenceOfSurfData& SeqFil = + CorDat->SetOfSurfData()->Sequence(); + Standard_Integer Ipoin1 = CorDat->IndexFirstPointOnS1(); + Standard_Integer Ipoin2 = CorDat->IndexFirstPointOnS2(); + Standard_Integer NumEdge = 1; + TopoDS_Vertex BoutdeVtx; + Standard_Integer Icurv = 0; + Standard_Integer Iarc1 = 0,Iarc2 = 0; + TopAbs_Orientation trafil1 = TopAbs_FORWARD, trafil2 = TopAbs_FORWARD; + Standard_Integer IcFil1,IcFil2,Isurf,Ishape1,Ishape2; + Standard_Real Pardeb,Parfin; + TopAbs_Orientation ET1; + Handle(TopOpeBRepDS_CurvePointInterference) Interfp1,Interfp2; + Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfc1,Interfc2; + Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfc3,Interfc4; + Handle(TopOpeBRepDS_CurvePointInterference) Interfp3,Interfp4; + Handle(TopOpeBRepDS_CurvePointInterference) Interfp5,Interfp6; + TopoDS_Face F; + Handle(Geom2d_Curve) PCurv; + TopOpeBRepDS_Curve Crv; + + TopOpeBRepDS_ListOfInterference& SolidInterfs = + DStr.ChangeShapeInterferences(SolidIndex); + + ChFiDS_Regul regcout; // for closed and tangent CD + ChFiDS_Regul regfilfil; // for connections Surf/Surf + + ChFiDS_CommonPoint V3; + ChFiDS_CommonPoint V4; + + // Nullify degenerated ChFi/Faces interferences, eap occ293 + Standard_Integer j; + if (SeqFil.Length() > 1) { + for (j=1; j<=SeqFil.Length(); j++) { + Handle(ChFiDS_SurfData) Fd = SeqFil(j); + Standard_Integer onS; + for (onS=1; onS<=2; onS++) { + const ChFiDS_FaceInterference& Fi = Fd->Interference(onS); + IcFil1 = Fi.LineIndex(); + if (!IcFil1) continue; + Standard_Real FiLen = Abs(Fi.FirstParameter()-Fi.LastParameter()); + if (FiLen > Precision::PConfusion()) continue; + TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil1); + cc.ChangeCurve().Nullify(); + + // care of CommonPoint, eap occ354 + if (j!=1 && j!=SeqFil.Length()) continue; + Standard_Boolean isfirst = (j==1); + Standard_Integer i = isfirst ? j+1 : j-1; + ChFiDS_CommonPoint& CP1 = SeqFil(i)->ChangeVertex(isfirst,onS); + if (Fd->Vertex(isfirst,onS).IsOnArc() && CP1.IsOnArc()) { + ChFiDS_CommonPoint& CP2 = Fd->ChangeVertex(!isfirst,onS); + CP1.Reset(); + CP1.SetPoint(CP2.Point()); + CP2.Reset(); + CP2.SetPoint(CP1.Point()); + } + } + } + } + + for (j=1; j<=SeqFil.Length(); j++) { + + const Handle(ChFiDS_SurfData)& Fd = SeqFil(j); + Isurf= Fd->Surf(); + Ishape1 = Fd->IndexOfS1(); + Ishape2 = Fd->IndexOfS2(); + + // eap, Apr 29 2002, occ 293 + // now IsInDS() returns nb of surfaces at end being in DS; + // vars showing which end is in DS + Standard_Boolean isInDS1 = Standard_False, isInDS2 = Standard_False; + if (j <= CorDat->IsInDS(Standard_True)) { + isInDS1 = Standard_True; + isInDS2 = (j+1 <= CorDat->IsInDS(Standard_True)); + } + if (SeqFil.Length()-j < CorDat->IsInDS(Standard_False)) { + isInDS2 = Standard_True; + isInDS1 = isInDS1 || SeqFil.Length()-j+1 < CorDat->IsInDS(Standard_False); + } + + // creation of SolidSurfaceInterference + + Handle(TopOpeBRepDS_SolidSurfaceInterference) + SSI = new TopOpeBRepDS_SolidSurfaceInterference + (TopOpeBRepDS_Transition(Fd->Orientation()), + TopOpeBRepDS_SOLID, + SolidIndex, + TopOpeBRepDS_SURFACE, + Isurf); + + SolidInterfs.Append(SSI); + + const ChFiDS_FaceInterference& Fi1 = Fd->InterferenceOnS1(); + const ChFiDS_FaceInterference& Fi2 = Fd->InterferenceOnS2(); + const ChFiDS_CommonPoint& V1 = Fd->VertexFirstOnS1(); + const ChFiDS_CommonPoint& V2 = Fd->VertexFirstOnS2(); + + // Processing to manage double interferences + if (j>1) { + if (V1.IsOnArc() && V3.IsOnArc() && V1.Arc().IsSame(V3.Arc())) { + //Iarc1 is initialized + //Iarc1 = DStr.AddShape(V1.Arc()); + if (ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1) && + (V1.TransitionOnArc() != V3.TransitionOnArc()) ) { + Interfp1= ChFi3d_FilPointInDS(V1.TransitionOnArc(),Iarc1,Ipoin1, + V1.ParameterOnArc()); + DStr.ChangeShapeInterferences(V1.Arc()).Append(Interfp1); + } + } + + if (V2.IsOnArc() && V4.IsOnArc() && V2.Arc().IsSame(V4.Arc())) { + //Iarc2 is initialized + //Iarc2 = DStr.AddShape(V2.Arc()); + if ( ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2) && + (V2.TransitionOnArc() != V4.TransitionOnArc()) ) { + Interfp2= ChFi3d_FilPointInDS(V2.TransitionOnArc(),Iarc2,Ipoin2, + V2.ParameterOnArc()); + DStr.ChangeShapeInterferences(V2.Arc()).Append(Interfp2); + } + } + } + + V3 = Fd->VertexLastOnS1(); + V4 = Fd->VertexLastOnS2(); + + if(Ishape1 != 0) { + if(Ishape1 > 0) { + trafil1 = DStr.Shape(Ishape1).Orientation(); + } + else{ + ChFi3d_Orientation(SolidInterfs,SolidIndex,-Ishape1,trafil1); + } + trafil1 = TopAbs::Compose(trafil1,Fd->Orientation()); + trafil1 = TopAbs::Compose(TopAbs::Reverse(Fi1.Transition()),trafil1); + trafil2 = TopAbs::Reverse(trafil1); + } + else{ + if(Ishape2 > 0) { + trafil2 = DStr.Shape(Ishape2).Orientation(); + } + else{ + ChFi3d_Orientation(SolidInterfs,SolidIndex,-Ishape2,trafil2); + } + trafil2 = TopAbs::Compose(trafil2,Fd->Orientation()); + trafil2 = TopAbs::Compose(TopAbs::Reverse(Fi2.Transition()),trafil2); + trafil1 = TopAbs::Reverse(trafil2); + } + + ET1 = TopAbs::Reverse(trafil1); + + // A small paragraph to process contacts of edges, which touch + // a vertex of the obstacle. + if(V1.IsVertex() && Fd->IsOnCurve1()) { + const TopoDS_Vertex& vv1 = V1.Vertex(); + CutEdge(vv1,Fd,DStr,1,1); + } + if(V2.IsVertex() && Fd->IsOnCurve2()) { + const TopoDS_Vertex& vv2 = V2.Vertex(); + CutEdge(vv2,Fd,DStr,1,2); + } + if(V3.IsVertex() && Fd->IsOnCurve1()) { + const TopoDS_Vertex& vv3 = V3.Vertex(); + CutEdge(vv3,Fd,DStr,0,1); + } + if(V4.IsVertex() && Fd->IsOnCurve2()) { + const TopoDS_Vertex& vv4 = V4.Vertex(); + CutEdge(vv4,Fd,DStr,0,2); + } + + if (j == 1) { + isVertex1 = V1.IsVertex(); + isVertex2 = V2.IsVertex(); + Singulier_en_Bout = (V1.Point().IsEqual(V2.Point(), 0)); + + if (Singulier_en_Bout) { + // Queue de Billard + if ((!V1.IsVertex()) || (!V2.IsVertex())) { + + } + else { + isVertex1 = isVertex2 = Standard_True; //caution... + // The edge is removed from spine starting on this vertex. + TopoDS_Edge Arcspine = spine->Edges(1); + BoutdeVtx = V1.Vertex(); + Standard_Integer IArcspine = DStr.AddShape(Arcspine); + Standard_Integer IVtx = CorDat->IndexFirstPointOnS1(); + + TopAbs_Orientation OVtx = TopAbs_FORWARD;; + + for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); + ex.More(); ex.Next()) { + if(BoutdeVtx.IsSame(ex.Current())) { + OVtx = ex.Current().Orientation(); + break; + } + } + OVtx = TopAbs::Reverse(OVtx); + Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine); + Handle(TopOpeBRepDS_CurvePointInterference) + interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx); + DStr.ChangeShapeInterferences(IArcspine).Append(interfv); + } + } + else { + if (V1.IsOnArc()) { + Iarc1 = DStr.AddShape(V1.Arc()); + if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1) ) { + Interfp1= ChFi3d_FilPointInDS(V1.TransitionOnArc(),Iarc1,Ipoin1, + V1.ParameterOnArc(), isVertex1); + DStr.ChangeShapeInterferences(V1.Arc()).Append(Interfp1); + } + } + + if (V2.IsOnArc()) { + Iarc2 = DStr.AddShape(V2.Arc()); + if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2) ) { + Interfp2= ChFi3d_FilPointInDS(V2.TransitionOnArc(),Iarc2,Ipoin2, + V2.ParameterOnArc(),isVertex2); + DStr.ChangeShapeInterferences(V2.Arc()).Append(Interfp2); + } + } + } + + if (!isInDS1) { + ET1 = TopAbs::Compose(ET1,CorDat->FirstPCurveOrientation()); + Icurv = CorDat->FirstCurve(); + if(Closed && !Singulier_en_Bout) { + regcout.SetCurve(Icurv); + regcout.SetS1(Isurf,Standard_False); + } + PCurv = CorDat->FirstPCurve(); + CorDat->FirstParameters(Pardeb,Parfin); + + TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(Icurv); + if (Li.IsEmpty()) { + if(CorDat->FirstPCurveOrientation()==TopAbs_REVERSED) { + Interfp1=ChFi3d_FilPointInDS + (TopAbs_REVERSED,Icurv,Ipoin1,Parfin,isVertex1); + Interfp2=ChFi3d_FilPointInDS + (TopAbs_FORWARD,Icurv,Ipoin2,Pardeb,isVertex2); + } + else{ + Interfp1=ChFi3d_FilPointInDS + (TopAbs_FORWARD,Icurv,Ipoin1,Pardeb,isVertex1); + Interfp2=ChFi3d_FilPointInDS + (TopAbs_REVERSED,Icurv,Ipoin2,Parfin,isVertex2); + } + Li.Append(Interfp1); + Li.Append(Interfp2); + } + Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1); + DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1); + if (Ipoin1 == Ipoin2) { + TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv); + TCurv.ChangeCurve().Nullify(); + Handle(TopOpeBRepDS_Interference) bidinterf; + TCurv.SetSCI(Interfc1,bidinterf); + } + } + } // End of the Initial Processing (j==1) + else { + // ---- Interference between Fillets ------ + + if (!isInDS1) {// eap, Apr 29 2002, occ 293 + + if (Degene && isVertex1) { + // The edge is removed from the spine starting on this vertex. + NumEdge++; // The previous edge of the vertex has already been found. + TopoDS_Edge Arcspine = spine->Edges(NumEdge); + Standard_Integer IArcspine = DStr.AddShape(Arcspine); + Standard_Integer IVtx = DStr.AddShape(BoutdeVtx); + TopAbs_Orientation OVtx = TopAbs_FORWARD; + for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); + ex.More(); ex.Next()) { + if(BoutdeVtx.IsSame(ex.Current())) { + OVtx = ex.Current().Orientation(); + break; + } + } + OVtx = TopAbs::Reverse(OVtx); + Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine); + Handle(TopOpeBRepDS_CurvePointInterference) + interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx); + DStr.ChangeShapeInterferences(IArcspine).Append(interfv); + } // End of the removal + + gp_Pnt2d UV1 = Fd->InterferenceOnS1().PCurveOnSurf()-> + Value(Fd->InterferenceOnS1().FirstParameter()); + gp_Pnt2d UV2 = Fd->InterferenceOnS2().PCurveOnSurf()-> + Value(Fd->InterferenceOnS2().FirstParameter()); + TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv); + if (Degene) { + // pcurve is associated via SCI to TopOpeBRepDSCurve. + ChFi3d_ComputePCurv(UV1,UV2,PCurv,Pardeb,Parfin); + Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1); + DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1); + TCurv.ChangeCurve().Nullify(); + Handle(TopOpeBRepDS_Interference) bidinterf; + TCurv.SetSCI(Interfc1,bidinterf); + } + else { + regfilfil.SetS2(Isurf,Standard_False); + reglist.Append(regfilfil); + Standard_Real tolreached; + ChFi3d_ComputePCurv(TCurv.ChangeCurve(),UV1,UV2,PCurv, + DStr.Surface(Fd->Surf()).Surface(), + Pardeb,Parfin,tol3d,tolreached); + TCurv.Tolerance(Max(TCurv.Tolerance(),tolreached)); + Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1); + DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1); + } + } + } // End of Interference between fillets + + // ---- Interference Fillets / Faces + IcFil1 = Fi1.LineIndex(); + + if (IcFil1!=0 ) { + Interfc3= ChFi3d_FilCurveInDS (IcFil1,Isurf, + Fi1.PCurveOnSurf(),trafil1); + DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc3); + Ishape1 = Fd->IndexOfS1(); + // Case of degenerated edge : pcurve is associated via SCI + // to TopOpeBRepDSCurve. + TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil1); + if(cc.Curve().IsNull()) { + Handle(TopOpeBRepDS_Interference) bidinterf; + cc.SetSCI(Interfc3,bidinterf); + } + else{ + ChFiDS_Regul regon1; + regon1.SetCurve(IcFil1); + regon1.SetS1(Isurf,Standard_False); + if ( Ishape1 < 0 ) { + Ishape1 = -Ishape1; + regon1.SetS2(Ishape1,Standard_False); + Interfc1=ChFi3d_FilCurveInDS(IcFil1,Ishape1,Fi1.PCurveOnFace(), + Fi1.Transition()); + DStr.ChangeSurfaceInterferences(Ishape1).Append(Interfc1); + } + else if ( Ishape1 > 0 ) { + regon1.SetS2(Ishape1,Standard_True); + Interfc1=ChFi3d_FilCurveInDS(IcFil1,Ishape1,Fi1.PCurveOnFace(), + Fi1.Transition()); + DStr.ChangeShapeInterferences(Ishape1).Append(Interfc1); + } + reglist.Append(regon1); + } + // Indice and type of the point at End + Standard_Integer ipoin; + Standard_Boolean isVertex = Fd->VertexLastOnS1().IsVertex(); + if (j == SeqFil.Length()) ipoin = CorDat->IndexLastPointOnS1(); + else if ( j == (SeqFil.Length()-1) && /*Closed &&*/ + (DStr.Curve(SeqFil.Last()->InterferenceOnS1(). + LineIndex()).Curve().IsNull())) { + if (Closed) { + ipoin = CorDat->IndexFirstPointOnS1(); + isVertex = SeqFil(1)->VertexFirstOnS1().IsVertex(); + } else { + ipoin = CorDat->IndexLastPointOnS1(); + isVertex = SeqFil.Last()->VertexLastOnS1().IsVertex(); + } + } + else if(DStr.Curve(IcFil1).Curve().IsNull()) {// Rotation !! + ipoin = Ipoin1; + isVertex = isVertex1; + } + else if ( ((j==1) || (j== SeqFil.Length()-1)) && + ( (Fd->VertexLastOnS1().Point().IsEqual( + SeqFil(1)->VertexFirstOnS1().Point(), 1.e-7)) || + (Fd->VertexLastOnS1().Point().IsEqual( + SeqFil(SeqFil.Length())->VertexLastOnS1().Point(), 1.e-7))) ) + // Case of SurfData cut in "Triangular" way. + ipoin=CorDat->IndexLastPointOnS1(); + + // eap, Apr 29 2002, occ 293 + else if (isInDS2 && findIndexPoint(DStr, Fd, 1, ipoin)) { + + } + else ipoin = ChFi3d_IndexPointInDS(Fd->VertexLastOnS1(),DStr); + + TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(IcFil1); + + if (!ChFi3d_Contains(Li,IcFil1,Ipoin1)) { + + Interfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,IcFil1,Ipoin1, + Fi1.FirstParameter(),isVertex1); + DStr.ChangeCurveInterferences(IcFil1).Append(Interfp1); + } + if (ipoin == Ipoin1 || !ChFi3d_Contains(Li,IcFil1,ipoin)) { + Interfp3 = ChFi3d_FilPointInDS(TopAbs_REVERSED,IcFil1,ipoin, + Fi1.LastParameter(), isVertex); + DStr.ChangeCurveInterferences(IcFil1).Append(Interfp3); + } + Ipoin1 = ipoin; + isVertex1 = isVertex; + } + + IcFil2 = Fi2.LineIndex(); + if (IcFil2!=0) { + Interfc4=ChFi3d_FilCurveInDS(IcFil2,Isurf, + Fi2.PCurveOnSurf(),trafil2); + DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc4); + Ishape2 = Fd->IndexOfS2(); + // Case of degenerated edge : pcurve is associated via SCI + // to TopOpeBRepDSCurve. + TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil2); + if(cc.Curve().IsNull()) { + Handle(TopOpeBRepDS_Interference) bidinterf; + cc.SetSCI(Interfc4,bidinterf); + } + else{ + ChFiDS_Regul regon2; + regon2.SetCurve(IcFil2); + regon2.SetS1(Isurf,Standard_False); + if ( Ishape2 < 0 ) { + Ishape2 = -Ishape2; + regon2.SetS2(Ishape2,Standard_False); + Interfc2=ChFi3d_FilCurveInDS(IcFil2,Ishape2,Fi2.PCurveOnFace(), + Fi2.Transition()); + DStr.ChangeSurfaceInterferences(Ishape2).Append(Interfc2); + } + else if ( Ishape2 > 0 ) { + regon2.SetS2(Ishape2,Standard_True); + Interfc2=ChFi3d_FilCurveInDS(IcFil2,Ishape2,Fi2.PCurveOnFace(), + Fi2.Transition()); + DStr.ChangeShapeInterferences(Ishape2).Append(Interfc2); + } + reglist.Append(regon2); + } + // Indice and type of the point in End + Standard_Integer ipoin; + Standard_Boolean isVertex = Fd->VertexLastOnS2().IsVertex(); + if (j == SeqFil.Length() ) ipoin = CorDat->IndexLastPointOnS2(); + else if ( j == (SeqFil.Length()-1) && /*Closed &&*/ + (DStr.Curve(SeqFil.Last()->InterferenceOnS2(). + LineIndex()).Curve().IsNull())) { + if (Closed) { + ipoin = CorDat->IndexFirstPointOnS2(); + isVertex = SeqFil(1)->VertexFirstOnS2().IsVertex(); + } else { + ipoin = CorDat->IndexLastPointOnS2(); + isVertex = SeqFil.Last()->VertexLastOnS2().IsVertex(); + } + } + else if(DStr.Curve(IcFil2).Curve().IsNull()) { // Rotation !! + ipoin = Ipoin2; + isVertex = isVertex2; + } + else if(Fd->VertexLastOnS2().Point().IsEqual( + Fd->VertexLastOnS1().Point(), 0) ) { //Pinch !! + ipoin = Ipoin1; + isVertex = isVertex1; + } + else if ( ((j==1) || (j==SeqFil.Length()-1)) && + ( (Fd->VertexLastOnS2().Point().IsEqual( + SeqFil(1)->VertexFirstOnS2().Point(), 1.e-7)) || + (Fd->VertexLastOnS2().Point().IsEqual( + SeqFil(SeqFil.Length())->VertexLastOnS2().Point(), 1.e-7))) ) + // Case of SurfData cut in "Triangular" way. + ipoin=CorDat->IndexLastPointOnS2(); + + // eap, Apr 29 2002, occ 293 + else if (isInDS2 && findIndexPoint(DStr, Fd, 2, ipoin)) { + + } + else ipoin = ChFi3d_IndexPointInDS(Fd->VertexLastOnS2(),DStr); + + TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(IcFil2); + + if (!ChFi3d_Contains(Li,IcFil2,Ipoin2)) { + Interfp2 = ChFi3d_FilPointInDS(TopAbs_FORWARD,IcFil2,Ipoin2, + Fi2.FirstParameter(), isVertex2); + DStr.ChangeCurveInterferences(IcFil2).Append(Interfp2); + } + if (ipoin == Ipoin2 || !ChFi3d_Contains(Li,IcFil2,ipoin)) { + Interfp4= ChFi3d_FilPointInDS(TopAbs_REVERSED,IcFil2,ipoin, + Fi2.LastParameter(), isVertex ); + DStr.ChangeCurveInterferences(IcFil2).Append(Interfp4); + } + Ipoin2 = ipoin; + isVertex2 = isVertex; + } + + ET1 = trafil1; + if (j == SeqFil.Length()) { + if (!isInDS2) { + Icurv = CorDat->LastCurve(); + if(Closed && !Singulier_en_Bout && (Ipoin1!=Ipoin2)) { + regcout.SetS2(Isurf,Standard_False); + reglist.Append(regcout); + } + PCurv = CorDat->LastPCurve(); + ET1 = TopAbs::Compose(ET1,CorDat->LastPCurveOrientation()); + CorDat->LastParameters(Pardeb,Parfin); + TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(Icurv); + if (Li.IsEmpty()) { + if(CorDat->LastPCurveOrientation()==TopAbs_REVERSED) { + Interfp5=ChFi3d_FilPointInDS + (TopAbs_REVERSED,Icurv,Ipoin1,Parfin, isVertex1); + Interfp6=ChFi3d_FilPointInDS + (TopAbs_FORWARD,Icurv,Ipoin2,Pardeb, isVertex2); + } + else{ + Interfp5=ChFi3d_FilPointInDS + (TopAbs_FORWARD,Icurv,Ipoin1,Pardeb, isVertex1); + Interfp6=ChFi3d_FilPointInDS + (TopAbs_REVERSED,Icurv,Ipoin2,Parfin, isVertex2); + } + Li.Append(Interfp5); + Li.Append(Interfp6); + } + Interfc1= ChFi3d_FilCurveInDS(Icurv,Isurf,PCurv,ET1); + DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1); + if (Ipoin1 == Ipoin2) { + TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv); + TCurv.ChangeCurve().Nullify(); + Handle(TopOpeBRepDS_Interference) bidinterf; + TCurv.SetSCI( Interfc1, bidinterf); +// bidinterf = TCurv.GetSCI1(); +// TCurv.SetSCI(bidinterf, Interfc1); + } + } + } + else { +// Degene = (Fd->VertexLastOnS1().Point().IsEqual( +// Fd->VertexLastOnS2().Point(), 0) ); + + // eap, Apr 29 2002, occ 293 + if (!isInDS2) { + + Handle(Geom_Curve) C3d; + Standard_Real tolreached; + ChFi3d_ComputeArete(Fd->VertexLastOnS1(), + Fd->InterferenceOnS1().PCurveOnSurf()-> + Value(Fd->InterferenceOnS1().LastParameter()), + Fd->VertexLastOnS2(), + Fd->InterferenceOnS2().PCurveOnSurf()-> + Value(Fd->InterferenceOnS2().LastParameter()), + DStr.Surface(Fd->Surf()).Surface(),C3d,PCurv, + Pardeb,Parfin,tol3d,tol2d,tolreached,0); + Crv = TopOpeBRepDS_Curve(C3d,tolreached); + Icurv = DStr.AddCurve(Crv); + regfilfil.SetCurve(Icurv); + regfilfil.SetS1(Isurf,Standard_False); + Interfp5 = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv,Ipoin1,Pardeb, isVertex1); + DStr.ChangeCurveInterferences(Icurv).Append(Interfp5); + Interfp6= ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv,Ipoin2,Parfin, isVertex2); + DStr.ChangeCurveInterferences(Icurv).Append(Interfp6); + Interfc1= ChFi3d_FilCurveInDS(Icurv,Isurf,PCurv,ET1); + DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1); + } + } + + Degene = V3.Point().IsEqual(V4.Point(), 0); + + // Processing of degenerated case + if (Degene) { + // Queue de Billard + Standard_Boolean Vertex = (V3.IsVertex()) && (V4.IsVertex()); + if (!Vertex) { + + } + else { + // The edge of the spine starting on this vertex is removed. + Standard_Boolean Trouve = Standard_False; + TopoDS_Edge Arcspine; + TopAbs_Orientation OVtx = TopAbs_FORWARD; + BoutdeVtx = V3.Vertex(); + + while (NumEdge<= spine->NbEdges() && !Trouve) { + Arcspine = spine->Edges(NumEdge); + for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); + ex.More() && (!Trouve); ex.Next()) { + if(BoutdeVtx.IsSame(ex.Current())) { + OVtx = ex.Current().Orientation(); + if (Closed && (NumEdge == 1)) + Trouve = (spine->NbEdges() == 1); + else Trouve = Standard_True; + } + } + if (!Trouve) NumEdge++; // Go to the next edge + } + Standard_Integer IArcspine = DStr.AddShape(Arcspine); + Standard_Integer IVtx; + if (j == SeqFil.Length()) { + IVtx = CorDat->IndexLastPointOnS1(); + } + else { IVtx = DStr.AddShape(BoutdeVtx); } + OVtx = TopAbs::Reverse(OVtx); + Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine); + Handle(TopOpeBRepDS_CurvePointInterference) + interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx); + DStr.ChangeShapeInterferences(IArcspine).Append(interfv); + } + } // end of degenerated case + else if (!(Closed && j == SeqFil.Length())) { + // Processing of interference Point / Edges + if (V3.IsOnArc()) { + if(!(V3.IsVertex() && Fd->IsOnCurve1())) { + Iarc1 = DStr.AddShape(V3.Arc()); + if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1,V3.IsVertex(),Standard_True) ) { + Handle(TopOpeBRepDS_CurvePointInterference) Interfpp = + ChFi3d_FilPointInDS(V3.TransitionOnArc(), + Iarc1,Ipoin1,V3.ParameterOnArc(), V3.IsVertex()); + DStr.ChangeShapeInterferences(V3.Arc()).Append(Interfpp); + } + } + } + + if (V4.IsOnArc()) { + if(!(V4.IsVertex() && Fd->IsOnCurve2())) { + Iarc2 = DStr.AddShape(V4.Arc()); + if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2,V4.IsVertex(),Standard_True) ) { + Handle(TopOpeBRepDS_CurvePointInterference) Intfpp= + ChFi3d_FilPointInDS(V4.TransitionOnArc(), + Iarc2,Ipoin2,V4.ParameterOnArc(), V4.IsVertex()); + DStr.ChangeShapeInterferences(V4.Arc()).Append(Intfpp); + } + } + } + } + } +} +//======================================================================= +//function : StripeEdgeInter +//purpose : This function examines two stripes for an intersection +// between curves of interference with faces. If the intersection +// exists, it will cause bad result, so it's better to quit. +//remark : If someone somewhen computes the interference between stripes, +// this function will become useless. +//author : akm, 06/02/02. Against bug OCC119. +//======================================================================= +void ChFi3d_StripeEdgeInter (const Handle(ChFiDS_Stripe)& theStripe1, + const Handle(ChFiDS_Stripe)& theStripe2, + TopOpeBRepDS_DataStructure& /*DStr*/, + const Standard_Real tol2d) +{ + // Do not check the stripeshaving common corner points + for (Standard_Integer iSur1=1; iSur1<=2; iSur1++) + for (Standard_Integer iSur2=1; iSur2<=2; iSur2++) + if (theStripe1->IndexPoint(0,iSur1)==theStripe2->IndexPoint(0,iSur2) || + theStripe1->IndexPoint(0,iSur1)==theStripe2->IndexPoint(1,iSur2) || + theStripe1->IndexPoint(1,iSur1)==theStripe2->IndexPoint(0,iSur2) || + theStripe1->IndexPoint(1,iSur1)==theStripe2->IndexPoint(1,iSur2)) + return; + + Handle(ChFiDS_HData) aSurDat1 = theStripe1->SetOfSurfData(); + Handle(ChFiDS_HData) aSurDat2 = theStripe2->SetOfSurfData(); + + Geom2dInt_GInter anIntersector; + Standard_Integer iPart1, iPart2; + Standard_Integer Ishape11, Ishape12, Ishape21, Ishape22; + // Loop on parts of the first stripe + for (iPart1=1; iPart1<=aSurDat1->Length(); iPart1++) + { + Handle(ChFiDS_SurfData) aDat1 = aSurDat1->Value(iPart1); + Ishape11 = aDat1->IndexOfS1(); + Ishape12 = aDat1->IndexOfS2(); + // Loop on parts of the second stripe + for (iPart2=1; iPart2<=aSurDat2->Length(); iPart2++) + { + Handle(ChFiDS_SurfData) aDat2 = aSurDat2->Value(iPart2); + Ishape21 = aDat2->IndexOfS1(); + Ishape22 = aDat2->IndexOfS2(); + + // Find those FaceInterferences able to intersect + ChFiDS_FaceInterference aFI1, aFI2; + if (Ishape11 == Ishape21) + { + aFI1 = aDat1->InterferenceOnS1(); + aFI2 = aDat2->InterferenceOnS1(); + } + else if (Ishape11 == Ishape22) + { + aFI1 = aDat1->InterferenceOnS1(); + aFI2 = aDat2->InterferenceOnS2(); + } + else if (Ishape12 == Ishape21) + { + aFI1 = aDat1->InterferenceOnS2(); + aFI2 = aDat2->InterferenceOnS1(); + } + else if (Ishape12 == Ishape22) + { + aFI1 = aDat1->InterferenceOnS2(); + aFI2 = aDat2->InterferenceOnS2(); + } + else + { + // No common faces + continue; + } + + if (IsEqual (aFI1.FirstParameter(),aFI1.LastParameter()) || + IsEqual (aFI2.FirstParameter(),aFI2.LastParameter()) || + aFI1.PCurveOnFace().IsNull() || + aFI2.PCurveOnFace().IsNull()) + // Do not waste time on degenerates + continue; + // Examine for intersections + Geom2dAdaptor_Curve aPCurve1 (aFI1.PCurveOnFace(), + aFI1.FirstParameter(), + aFI1.LastParameter()); + Geom2dAdaptor_Curve aPCurve2 (aFI2.PCurveOnFace(), + aFI2.FirstParameter(), + aFI2.LastParameter()); + anIntersector.Perform (aPCurve1, + aPCurve2, + tol2d, + Precision::PConfusion()); + if (anIntersector.NbSegments() > 0 || + anIntersector.NbPoints() > 0) + StdFail_NotDone::Raise ("StripeEdgeInter : fillets have too big radiuses"); + } + } +} + +//======================================================================= +//function : IndexOfSurfData +//purpose : +//======================================================================= +Standard_Integer ChFi3d_IndexOfSurfData(const TopoDS_Vertex& V1, + const Handle(ChFiDS_Stripe)& CD, + Standard_Integer& sens) +{ + Handle(ChFiDS_Spine) spine = CD->Spine(); + Standard_Integer Index = 0; + sens = 1; + TopoDS_Vertex Vref; + const TopoDS_Edge& E = spine->Edges(1); + if (E.Orientation() == TopAbs_REVERSED) Vref = TopExp::LastVertex(E); + else Vref = TopExp::FirstVertex(E); + if (Vref.IsSame(V1)) Index =1; + else { + const TopoDS_Edge& E1 = spine->Edges(spine->NbEdges()); + if (E1.Orientation() == TopAbs_REVERSED) Vref = TopExp::FirstVertex(E1); + else Vref = TopExp::LastVertex(E1); + sens = -1; + if(CD->SetOfSurfData().IsNull()) return 0; + else if (Vref.IsSame(V1)) Index = CD->SetOfSurfData()->Length(); + else Standard_ConstructionError::Raise(""); + } + return Index; +} +//======================================================================= +//function : EdgeFromV1 +//purpose : +//======================================================================= + +TopoDS_Edge ChFi3d_EdgeFromV1(const TopoDS_Vertex& V1, + const Handle(ChFiDS_Stripe)& CD, + Standard_Integer& sens) +{ + Handle(ChFiDS_Spine) spine = CD->Spine(); + sens = 1; + TopoDS_Vertex Vref; + const TopoDS_Edge& E = spine->Edges(1); + if (E.Orientation() == TopAbs_REVERSED) Vref = TopExp::LastVertex(E); + else Vref = TopExp::FirstVertex(E); + if (Vref.IsSame(V1)) return E; + else + { + const TopoDS_Edge& E1 = spine->Edges(spine->NbEdges()); + if (E1.Orientation() == TopAbs_REVERSED) Vref = TopExp::FirstVertex(E1); + else Vref = TopExp::LastVertex(E1); + sens = -1; + if (Vref.IsSame(V1)) return E1; + else Standard_ConstructionError::Raise(""); + } + return E; +} +//======================================================================= +//function : ConvTol2dToTol3d +//purpose : Comme son nom l indique. +//======================================================================= + +Standard_Real ChFi3d_ConvTol2dToTol3d(const Handle(Adaptor3d_HSurface)& S, + const Standard_Real tol2d) +{ + Standard_Real ures = S->UResolution(1.e-7); + Standard_Real vres = S->VResolution(1.e-7); + Standard_Real uresto3d = 1.e-7*tol2d/ures; + Standard_Real vresto3d = 1.e-7*tol2d/vres; + return Max(uresto3d,vresto3d); +} +//======================================================================= +//function : EvalTolReached +//purpose : The function above is too hard because +// parametrization of surfaces is not homogenous. +//======================================================================= + +Standard_Real ChFi3d_EvalTolReached(const Handle(Adaptor3d_HSurface)& S1, + const Handle(Geom2d_Curve)& pc1, + const Handle(Adaptor3d_HSurface)& S2, + const Handle(Geom2d_Curve)& pc2, + const Handle(Geom_Curve)& C) +{ + Standard_Real distmax = 0.; + + Standard_Real f = C->FirstParameter(); + Standard_Real l = C->LastParameter(); + Standard_Integer nbp = 45; + Standard_Real step = 1./(nbp -1); + for(Standard_Integer i = 0; i < nbp; i++) { + Standard_Real t,u,v; + t = step * i; + t = (1-t) * f + t * l; + pc1->Value(t).Coord(u,v); + gp_Pnt pS1 = S1->Value(u,v); + pc2->Value(t).Coord(u,v); + gp_Pnt pS2 = S2->Value(u,v); + gp_Pnt pC = C->Value(t); + Standard_Real d = pS1.SquareDistance(pC); + if(d>distmax) distmax = d; + d = pS2.SquareDistance(pC); + if(d>distmax) distmax = d; + d = pS1.SquareDistance(pS2); + if(d>distmax) distmax = d; + } + distmax = 1.5*sqrt(distmax); + distmax = Max(distmax, Precision::Confusion()); + return distmax; +} + +//======================================================================= +//function : trsfsurf +//purpose : +//======================================================================= +Handle(Geom_Surface) trsfsurf(const Handle(Adaptor3d_HSurface)& HS, + Handle(Adaptor3d_TopolTool)& /*dom*/) +{ + //Pour l utilisation des domaines voir avec BUBUCH!! + Handle(Geom_Surface) res; + Handle(BRepAdaptor_HSurface) hbs = Handle(BRepAdaptor_HSurface)::DownCast(HS); + Handle(GeomAdaptor_HSurface) hgs = Handle(GeomAdaptor_HSurface)::DownCast(HS); + if(!hbs.IsNull()) { + res = hbs->ChangeSurface().Surface().Surface(); + gp_Trsf trsf = hbs->ChangeSurface().Trsf(); + res = Handle(Geom_Surface)::DownCast(res->Transformed(trsf)); + } + else if(!hgs.IsNull()) { + res = hgs->ChangeSurface().Surface(); + } + Handle(Geom_RectangularTrimmedSurface) + tr = Handle(Geom_RectangularTrimmedSurface)::DownCast(res); + if(!tr.IsNull()) res = tr->BasisSurface(); + + Standard_Real U1 = HS->FirstUParameter(), U2 = HS->LastUParameter(); + Standard_Real V1 = HS->FirstVParameter(), V2 = HS->LastVParameter(); + if(!res.IsNull()) { + // Protection against Construction Errors + Standard_Real u1, u2, v1, v2; + res->Bounds( u1, u2, v1, v2); + if (!res->IsUPeriodic()) { + if (U1 < u1) U1 = u1; + if (U2 > u2) U2 = u2; + } + if (!res->IsVPeriodic()) { + if (V1 < v1) V1 = v1; + if (V2 > v2) V2 = v2; + } + res = new Geom_RectangularTrimmedSurface(res,U1,U2,V1,V2); + } +// Handle(GeomAdaptor_HSurface) temp = new GeomAdaptor_HSurface(res,U1,U2,V1,V2); +// dom = new Adaptor3d_TopolTool(temp); + return res; +} +//======================================================================= +//function : CurveCleaner +//purpose : Makes a BSpline as much continued as possible +// at a given tolerance +//======================================================================= +static void CurveCleaner(Handle(Geom_BSplineCurve)& BS, + const Standard_Real Tol, + const Standard_Integer MultMin) + +{ + Standard_Real tol = Tol; + Standard_Integer Mult, ii; + const Standard_Integer NbK=BS->NbKnots(); + + for (Mult = BS->Degree(); Mult > MultMin; Mult--) { + tol *= 0.5; // Progressive reduction + for (ii=NbK; ii>1; ii--) { + if (BS->Multiplicity(ii) == Mult) + BS->RemoveKnot(ii, Mult-1, tol); + } + } +} +//======================================================================= +//function : ComputeCurves +//purpose : Calculates intersection between two HSurfaces. +// It is necessary to know the extremities of intersection and +// the surfaces should be processed at input +// to fit as good as possible (neither too close nor too far) +// the points of beginning and end of the intersection. +// The analytic intersections are processed separately. +// <wholeCurv> means that the resulting curve is restricted by +// boundaries of input surfaces (eap 30 May occ354) +//======================================================================= +Standard_Boolean ChFi3d_ComputeCurves(Handle(Adaptor3d_HSurface)& S1, + Handle(Adaptor3d_HSurface)& S2, + const TColStd_Array1OfReal& Pardeb, + const TColStd_Array1OfReal& Parfin, + Handle(Geom_Curve)& C3d, + Handle(Geom2d_Curve)& Pc1, + Handle(Geom2d_Curve)& Pc2, + const Standard_Real tol3d, + const Standard_Real tol2d, + Standard_Real& tolreached, + const Standard_Boolean wholeCurv) +{ + Standard_Real Step = 0.1; + + gp_Pnt pdeb1 = S1->Value(Pardeb(1),Pardeb(2)); + gp_Pnt pfin1 = S1->Value(Parfin(1),Parfin(2)); + gp_Pnt pdeb2 = S2->Value(Pardeb(3),Pardeb(4)); + gp_Pnt pfin2 = S2->Value(Parfin(3),Parfin(4)); + + Standard_Real distrefdeb = pdeb1.Distance(pdeb2);//checks the worthiness + Standard_Real distreffin = pfin1.Distance(pfin2);//of input data + if(distrefdeb < tol3d) distrefdeb = tol3d; + if(distreffin < tol3d) distreffin = tol3d; + + gp_Pnt pdeb,pfin; + pdeb.SetXYZ(0.5*(pdeb1.XYZ()+pdeb2.XYZ())); + pfin.SetXYZ(0.5*(pfin1.XYZ()+pfin2.XYZ())); + + Standard_Real distref = 0.005*pdeb.Distance(pfin); + if(distref < distrefdeb) distref = distrefdeb; + if(distref < distreffin) distref = distreffin; + + //Some analytic cases are processed separately. + //To reorientate the result of the analythic intersection, + //it is stated that the beginning of the tangent should be + //in the direction of the start/end line. + gp_Vec Vint, Vref(pdeb,pfin); + gp_Pnt Pbid; + Standard_Real Udeb,Ufin; + Standard_Real tolr1,tolr2; + tolr1 = tolr2 = tolreached = tol3d; + if((S1->GetType() == GeomAbs_Cylinder && S2->GetType() == GeomAbs_Plane)|| + (S1->GetType() == GeomAbs_Plane && S2->GetType() == GeomAbs_Cylinder)) { + gp_Pln pl; + gp_Cylinder cyl; + if(S1->GetType() == GeomAbs_Plane) { + pl = S1->Plane(); + cyl = S2->Cylinder(); + } + else{ + pl = S2->Plane(); + cyl = S1->Cylinder(); + } + IntAna_QuadQuadGeo ImpKK(pl,cyl,Precision::Angular(),tol3d); + if (ImpKK.IsDone()) { + Standard_Boolean c1line = 0; + switch (ImpKK.TypeInter()) { + case IntAna_Line: + { + c1line = 1; + Standard_Integer nbsol = ImpKK.NbSolutions(); + gp_Lin C1; + for(Standard_Integer ilin = 1; ilin <= nbsol; ilin++) { + C1 = ImpKK.Line(ilin); + Udeb = ElCLib::Parameter(C1,pdeb); + gp_Pnt ptest = ElCLib::Value(Udeb,C1); + if(ptest.Distance(pdeb) < tol3d) break; + } + Ufin = ElCLib::Parameter(C1,pfin); + C3d = new Geom_Line(C1); + ElCLib::D1(Udeb,C1,Pbid,Vint); + } + break; + case IntAna_Circle: + { + gp_Circ C1 = ImpKK.Circle(1); + C3d = new Geom_Circle(C1); + Udeb = ElCLib::Parameter(C1,pdeb); + Ufin = ElCLib::Parameter(C1,pfin); + ElCLib::D1(Udeb,C1,Pbid,Vint); + } + break; + case IntAna_Ellipse: + { + gp_Elips C1 = ImpKK.Ellipse(1); + C3d = new Geom_Ellipse(C1); + Udeb = ElCLib::Parameter(C1,pdeb); + Ufin = ElCLib::Parameter(C1,pfin); + ElCLib::D1(Udeb,C1,Pbid,Vint); + } + break; + default: + break; + } + if (Vint.Dot(Vref)<0) { + C3d->Reverse(); + if(c1line) { + Udeb = -Udeb; + Ufin = -Ufin; + } + else{ + Udeb = 2*PI - Udeb; + Ufin = 2*PI - Ufin; + } + } + if(!c1line) ElCLib::AdjustPeriodic(0.,2*PI,Precision::Angular(),Udeb,Ufin); + Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve(); + HC->ChangeCurve().Load(C3d,Udeb,Ufin); + ChFi3d_ProjectPCurv(HC,S1,Pc1,tol3d,tolr1); + if(S1->GetType() == GeomAbs_Cylinder) { + Standard_Real x,y; + Pc1->Value(Udeb).Coord(x,y); + x = Pardeb(1) - x; + y = Pardeb(2) - y; + if(Abs(x) >= tol2d || Abs(y) >= tol2d) Pc1->Translate(gp_Vec2d(x,y)); + } + ChFi3d_ProjectPCurv(HC,S2,Pc2,tol3d,tolr2); + if(S2->GetType() == GeomAbs_Cylinder) { + Standard_Real x,y; + Pc2->Value(Udeb).Coord(x,y); + x = Pardeb(3) - x; + y = Pardeb(4) - y; + if(Abs(x) >= tol2d || Abs(y) >= tol2d) Pc2->Translate(gp_Vec2d(x,y)); + } + C3d = new Geom_TrimmedCurve(C3d,Udeb,Ufin); + tolreached = 1.5*Max(tolr1,tolr2); + tolreached = Min(tolreached,ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d)); + return Standard_True; + } + } + else if(S1->GetType() == GeomAbs_Plane && S2->GetType() == GeomAbs_Plane) { + IntAna_QuadQuadGeo LInt(S1->Plane(),S2->Plane(),Precision::Angular(),tol3d); + if (LInt.IsDone()) { + gp_Lin L = LInt.Line(1); + C3d = new Geom_Line(L); + Udeb = ElCLib::Parameter(L,pdeb); + Ufin = ElCLib::Parameter(L,pfin); + ElCLib::D1(Udeb,L,Pbid,Vint); + if (Vint.Dot(Vref)<0) { + C3d->Reverse(); + Udeb = - Udeb; + Ufin = - Ufin; + } + Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve(); + HC->ChangeCurve().Load(C3d,Udeb,Ufin); + ChFi3d_ProjectPCurv(HC,S1,Pc1,tol3d,tolr1); + ChFi3d_ProjectPCurv(HC,S2,Pc2,tol3d,tolr2); + C3d = new Geom_TrimmedCurve(C3d,Udeb,Ufin); + return Standard_True; + } + } + else { + // here GeomInt is approached. + Handle(Adaptor3d_TopolTool) dom1,dom2; + Handle(Geom_Surface) gs1 = trsfsurf(S1,dom1); + Handle(Geom_Surface) gs2 = trsfsurf(S2,dom2); + Standard_Integer nbl ; + if(!gs1.IsNull() && !gs2.IsNull()) { + GeomInt_IntSS inter; + // Modified by skv - Fri Oct 24 14:24:47 2003 OCC4077 Begin +// Standard_Real tolap = 1.e-7;//car l approx de la wline est faite dans [0,1] + // Set the lowest tolerance which is used in new boolean operations. + Standard_Real tolap = 2.e-7; + // Modified by skv - Fri Oct 24 14:24:48 2003 OCC4077 End + inter.Perform(gs1,gs2,tolap,1,1,1); + if(inter.IsDone()) { + nbl = inter.NbLines(); +#if defined(IRIX) || defined(__sgi) + if(nbl==0) { + +// solution of adjustment for SGI +// if the intersection of gs1 with gs2 doesnot worke +// then the intersection of gs2 with gs1 is attempted. + + inter.Perform(gs2,gs1,tolap,1,1,1); +// inter.Perform(gs2,dom2,gs1,dom1,tolap,1,1,1); + if(!inter.IsDone()) return Standard_False; + nbl = inter.NbLines(); + +// if GeomInt does not make the intersection the solution of adjustment +// is not attempted + if (nbl==0) return Standard_False; + } +#endif + GeomAPI_ProjectPointOnCurve proj; + for(Standard_Integer ilin = 1; ilin <= nbl; ilin++) { + if(inter.HasLineOnS1(ilin) && inter.HasLineOnS2(ilin)) { + C3d = inter.Line(ilin); + Pc1 = inter.LineOnS1(ilin); + Pc2 = inter.LineOnS2(ilin); + gp_Pnt ptestdeb, ptestfin; + Standard_Real Uf=0., Ul=0.; + if (wholeCurv) { + Uf = C3d->FirstParameter(); + Ul = C3d->LastParameter(); + ptestdeb = C3d->Value(Uf); + ptestfin = C3d->Value(Ul); + } + else { + // find end parameters + Standard_Boolean failedF, failedL; + failedF = failedL = Standard_False; + proj.Init( pdeb1, C3d); + if (proj.NbPoints()==0 && distrefdeb > Precision::Confusion()) + proj.Perform( pdeb2 ); + if (proj.NbPoints()==0) + failedF = Standard_True; + else + Uf = proj.LowerDistanceParameter(); + proj.Perform( pfin1 ); + if (proj.NbPoints()==0 && distreffin > Precision::Confusion()) + proj.Perform( pfin2 ); + if (proj.NbPoints()==0) + failedL = Standard_True; + else + Ul = proj.LowerDistanceParameter(); + + if (failedF && failedL) { + Uf = C3d->FirstParameter(); + Ul = C3d->LastParameter(); + } + else if (failedF || failedL) { + // select right end parameter + Standard_Real Uok = failedF ? Ul : Uf; + Standard_Real U1 = C3d->FirstParameter(), U2 = C3d->LastParameter(); + Uok = Abs(Uok-U1) > Abs(Uok-U2) ? U1 : U2; + if (failedF) Uf = Uok; + else Ul = Uok; + } + else { // both projected, but where? + if (Uf == Ul) continue; + } + ptestdeb = C3d->Value(Uf); + ptestfin = C3d->Value(Ul); + if (C3d->IsPeriodic() && !(failedF && failedL)) { + // assure the same order of ends, otherwise TrimmedCurve will take + // the other part of C3d + gp_Pnt Ptmp; + gp_Vec DirOld, DirNew(ptestdeb,ptestfin); + C3d->D1(Uf, Ptmp, DirOld); + if (DirOld * DirNew < 0) { + Standard_Real Utmp = Uf; Uf = Ul; Ul = Utmp; + Ptmp = ptestdeb; ptestdeb = ptestfin; ptestfin = Ptmp; + } + } + } + C3d = new Geom_TrimmedCurve(C3d,Uf,Ul); + Pc1 = new Geom2d_TrimmedCurve(Pc1,Uf,Ul); + Pc2 = new Geom2d_TrimmedCurve(Pc2,Uf,Ul); + //is it necesary to invert ? + Standard_Real distdeb = ptestdeb.Distance(pdeb); + Standard_Real distfin = ptestfin.Distance(pfin); + if(distdeb > distref || distfin > distref) { + C3d->Reverse(); + Pc1->Reverse(); + Pc2->Reverse(); + ptestdeb = C3d->Value(C3d->FirstParameter()); + ptestfin = C3d->Value(C3d->LastParameter()); + distdeb = ptestdeb.Distance(pdeb); + distfin = ptestfin.Distance(pfin); + } + if(distdeb < distref && distfin < distref) { + Uf = C3d->FirstParameter(); + Ul = C3d->LastParameter(); + ChFi3d_ReparamPcurv(Uf,Ul,Pc1); + ChFi3d_ReparamPcurv(Uf,Ul,Pc2); + Standard_Real x,y; + Pc1->Value(Uf).Coord(x,y); + x = Pardeb(1) - x; + y = Pardeb(2) - y; + if(Abs(x) > tol2d || Abs(y) > tol2d) Pc1->Translate(gp_Vec2d(x,y)); + Pc2->Value(Uf).Coord(x,y); + x = Pardeb(3) - x; + y = Pardeb(4) - y; + if(Abs(x) > tol2d || Abs(y) > tol2d) Pc2->Translate(gp_Vec2d(x,y)); + tolreached = ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d); + return Standard_True; + } + } + } + } + } + } + + // At this stage : + // classic intersections have failed, the path is approached in vain. +// Standard_Real Step = 0.1; + while(1) { + //Attention the parameters of arrow for the path and + //the tolerance for the approximation can't be taken as those of the + //Builder, so they are reestimated as much as possible. + Standard_Real fleche = 1.e-3 * pdeb.Distance(pfin); + Standard_Real tolap = 1.e-7; + IntPatch_ThePWalkingInter + IntKK(S1,S2,tol3d,tol3d,fleche,Step); + + //The extremities of the intersection (Pardeb,Parfin) are known, + //one tries to find the start point at the + //middle to avoid obstacles on the path. + Standard_Boolean depok = Standard_False; + IntSurf_PntOn2S pintdep; + TColStd_Array1OfReal depart(1,4); + for(Standard_Integer ipdep = 2; ipdep <= 7 && !depok; ipdep++) { + Standard_Real alpha = 0.1 * ipdep; + Standard_Real unmoinsalpha = 1. - alpha; + depart(1) = alpha*Pardeb(1) + unmoinsalpha*Parfin(1); + depart(2) = alpha*Pardeb(2) + unmoinsalpha*Parfin(2); + depart(3) = alpha*Pardeb(3) + unmoinsalpha*Parfin(3); + depart(4) = alpha*Pardeb(4) + unmoinsalpha*Parfin(4); + depok = IntKK.PerformFirstPoint(depart,pintdep); + } + if(!depok) { + return Standard_False; + } + pintdep.Parameters(depart(1),depart(2),depart(3),depart(4)); + IntKK.Perform(depart); + if (!IntKK.IsDone()) return Standard_False; + if (IntKK.NbPoints() <= 30) { + Step *= 0.5; + if (Step <= 0.0001) { + return Standard_False; + } + } + else{ + // At this stage there is a presentable LineOn2S, it is truncated + // between the points closest to known extremites + // in fact there is a WLine and the approximation is launched. + // Then the result is corrected to get proper start and end points. + const Handle(IntSurf_LineOn2S)& L2S = IntKK.Line(); + + gp_Pnt codeb1 = S1->Value(Pardeb(1),Pardeb(2)); + gp_Pnt codeb2 = S2->Value(Pardeb(3),Pardeb(4)); + Standard_Real tol1 = Max(codeb1.Distance(codeb2),tol3d); + Standard_Boolean bondeb = (tol1 == tol3d); + gp_Pnt pntd(0.5*(codeb1.Coord() + codeb2.Coord())); + + gp_Pnt cofin1 = S1->Value(Parfin(1),Parfin(2)); + gp_Pnt cofin2 = S2->Value(Parfin(3),Parfin(4)); + Standard_Real tol2 = Max(cofin1.Distance(cofin2),tol3d); + Standard_Boolean bonfin = (tol2 == tol3d); + gp_Pnt pntf(0.5*(cofin1.Coord() + cofin2.Coord())); + + Standard_Integer nbp = L2S->NbPoints(), i; + Standard_Real ddeb = Precision::Infinite(); + Standard_Real dfin = Precision::Infinite(); + Standard_Real dd; + Standard_Integer indd = 0, indf = 0; + for(i = 1; i <= nbp; i++) { + dd = L2S->Value(i).Value().Distance(pntd); + if(dd < ddeb) { ddeb = dd; indd = i;} + dd = L2S->Value(i).Value().Distance(pntf); + if(dd < dfin) { dfin = dd; indf = i;} + } + if(indd > indf) { + L2S->Reverse(); + indd = nbp - indd + 1; + indf = nbp - indf + 1; + } + for (i = 1; i < indd; i++) { L2S->RemovePoint(1); nbp--; indf--; } + for (i = indf + 1; i <= nbp; i++) { L2S->RemovePoint(indf + 1); } + nbp = indf; + if(nbp==1) return Standard_False; + //The extremities are inserted in the line if the extremity points on it + //are too far and if pardeb and parfin are good. + if(ddeb >= tol3d && bondeb) { + IntSurf_PntOn2S p1 = L2S->Value(1); + IntSurf_PntOn2S p2 = L2S->Value(2); + + gp_Vec v1(pntd,p1.Value()); + gp_Vec v2(p1.Value(),p2.Value()); + gp_Vec v3(pntd,p2.Value()); + p1.SetValue(pntd,Pardeb(1),Pardeb(2),Pardeb(3),Pardeb(4)); + if(v1.Dot(v3) < 0) { + if(v3.Magnitude() < 0.2*v2.Magnitude()) { + L2S->RemovePoint(1); + nbp--; + } + L2S->Value(1,p1); + } + else if(v1.Magnitude() > 0.2*v2.Magnitude()) { + L2S->InsertBefore(1,p1); + nbp++; + } + else{ + L2S->Value(1,p1); + } + ddeb = 0.; + } + if(dfin >= tol3d && bonfin) { + IntSurf_PntOn2S p1 = L2S->Value(nbp); + IntSurf_PntOn2S p2 = L2S->Value(nbp - 1); + gp_Vec v1(pntf,p1.Value()); + gp_Vec v2(p1.Value(),p2.Value()); + gp_Vec v3(pntf,p2.Value()); + p1.SetValue(pntf,Parfin(1),Parfin(2),Parfin(3),Parfin(4)); + if(v1.Dot(v3) < 0) { + if(v3.Magnitude() < 0.2*v2.Magnitude()) { + L2S->RemovePoint(nbp); + nbp--; + } + L2S->Value(nbp,p1); + } + else if(v1.Magnitude() > 0.2*v2.Magnitude()) { + L2S->Add(p1); + nbp++; + } + else{ + L2S->Value(nbp,p1); + } + dfin = 0.; + } + // + Handle(IntPatch_WLine) WL = new IntPatch_WLine(L2S,Standard_False); + + GeomInt_WLApprox approx; + approx.SetParameters(tolap,tol2d,4,8,0,1); + // manage here the approximations that are not useful on planes! + approx.Perform(S1,S2,WL, + Standard_True,Standard_True,Standard_True, + 1,nbp); + if(!approx.IsDone()) return Standard_False; +// tolreached = approx.TolReached3d(); +// Standard_Real tolr2d = approx.TolReached2d(); +// tolreached = Max(tolreached,ChFi3d_ConvTol2dToTol3d(S1,tolr2d)); +// tolreached = Max(tolreached,ChFi3d_ConvTol2dToTol3d(S2,tolr2d)); + const AppParCurves_MultiBSpCurve& mbs = approx.Value(1); + Standard_Integer nbpol = mbs.NbPoles(); + TColgp_Array1OfPnt pol3d(1,nbpol); + mbs.Curve(1,pol3d); + TColgp_Array1OfPnt2d pol2d1(1,nbpol); + mbs.Curve(2,pol2d1); + TColgp_Array1OfPnt2d pol2d2(1,nbpol); + mbs.Curve(3,pol2d2); + // The extremities of the intersection are reset on known points. + if(ddeb >= tol1) { + pol3d(1) = pntd; + pol2d1(1).SetCoord(Pardeb(1),Pardeb(2)); + pol2d2(1).SetCoord(Pardeb(3),Pardeb(4)); +// tolreached = Max(tolreached,ddeb); + } + + if(dfin >= tol2) { + pol3d(nbpol) = pntf; + pol2d1(nbpol).SetCoord(Parfin(1),Parfin(2)); + pol2d2(nbpol).SetCoord(Parfin(3),Parfin(4)); +// tolreached = Max(tolreached,dfin); + } + const TColStd_Array1OfReal& knots = mbs.Knots(); + const TColStd_Array1OfInteger& mults = mbs.Multiplicities(); + Standard_Integer deg = mbs.Degree(); + C3d = new Geom_BSplineCurve(pol3d,knots,mults,deg); + Pc1 = new Geom2d_BSplineCurve(pol2d1,knots,mults,deg); + Pc2 = new Geom2d_BSplineCurve(pol2d2,knots,mults,deg); + tolreached = ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d); + return Standard_True; + } + } +} + +//======================================================================= +//function : IntCS +//purpose : Fast calculation of the intersection curve surface. +// +//======================================================================= + +Standard_Boolean ChFi3d_IntCS(Handle(Adaptor3d_HSurface)& S, + Handle(Adaptor3d_HCurve)& C, + gp_Pnt2d& p2dS, + Standard_Real& wc) +{ + IntCurveSurface_HInter Intersection; + + Standard_Real uf = C->FirstParameter(), ul = C->LastParameter(); + Standard_Real u1 = S->FirstUParameter(), u2 = S->LastUParameter(); + Standard_Real v1 = S->FirstVParameter(), v2 = S->LastVParameter(); + IntCurveSurface_IntersectionPoint pint; + Intersection.Perform(C,S); + Standard_Boolean keepfirst = (wc < -1.e100), keeplast = (wc > 1.e100); + Standard_Real temp = 0.; + if(keepfirst) temp = 1.e100; + if(keeplast) temp = -1.e100; + Standard_Real dist = 2.e100; + if(Intersection.IsDone()) { + Standard_Integer nbp = Intersection.NbPoints(),i,isol = 0; + for (i = 1; i <= nbp; i++) { + pint = Intersection.Point(i); + Standard_Real up = pint.U(); + Standard_Real vp = pint.V(); + if(S->IsUPeriodic()) up = ChFi3d_InPeriod(up,u1,u1+S->UPeriod(),1.e-8); + if(S->IsVPeriodic()) vp = ChFi3d_InPeriod(vp,v1,v1+S->VPeriod(),1.e-8); + if(uf <= pint.W() && ul >= pint.W() && + u1 <= up && u2 >= up && + v1 <= vp && v2 >= vp) { + if(keepfirst && pint.W() < temp) { + temp = pint.W(); + isol = i; + } + else if(keeplast && pint.W() > temp) { + temp = pint.W(); + isol = i; + } + else if(Abs(pint.W() - wc) < dist) { + dist = Abs(pint.W() - wc); + isol = i; + } + } + } + if(isol == 0) return Standard_False; + pint = Intersection.Point(isol); + Standard_Real up = pint.U(); + Standard_Real vp = pint.V(); + if(S->IsUPeriodic()) up = ChFi3d_InPeriod(up,u1,u1+S->UPeriod(),1.e-8); + if(S->IsVPeriodic()) vp = ChFi3d_InPeriod(vp,v1,v1+S->VPeriod(),1.e-8); + p2dS.SetCoord(up,vp); + wc = pint.W(); + return Standard_True; + } + return Standard_False; +} + +//======================================================================= +//function : ComputesIntPC +//purpose : Intersection of two PCurves of type FaceInterference +// the parameters of the pcurves at the solution point are +// UInt1,UInt2 +//======================================================================= + +void ChFi3d_ComputesIntPC (const ChFiDS_FaceInterference& Fi1, + const ChFiDS_FaceInterference& Fi2, + const Handle(GeomAdaptor_HSurface)& HS1, + const Handle(GeomAdaptor_HSurface)& HS2, + Standard_Real& UInt1, + Standard_Real& UInt2) +{ + gp_Pnt bid; + ChFi3d_ComputesIntPC(Fi1,Fi2,HS1,HS2,UInt1,UInt2,bid); +} + +//======================================================================= +//function : ChFi3d_ComputesIntPC +//purpose : +//======================================================================= +void ChFi3d_ComputesIntPC (const ChFiDS_FaceInterference& Fi1, + const ChFiDS_FaceInterference& Fi2, + const Handle(GeomAdaptor_HSurface)& HS1, + const Handle(GeomAdaptor_HSurface)& HS2, + Standard_Real& UInt1, + Standard_Real& UInt2, + gp_Pnt& P) +{ + // Only one intersection to be carried out, however, the effort + // is taken to check the extremities by an extrema c3d/c3d + // created on pcurveonsurf of fillets. + + Standard_Real x,y,distref2; + Fi1.PCurveOnSurf()->Value(UInt1).Coord(x,y); + gp_Pnt p3d1 = HS1->Value(x,y); + Fi2.PCurveOnSurf()->Value(UInt2).Coord(x,y); + gp_Pnt p3d2 = HS2->Value(x,y); + distref2 = p3d1.SquareDistance(p3d2); + P.SetXYZ(0.5*(p3d1.XYZ() + p3d2.XYZ())); + // recalculation of the extremums + Standard_Real delt1 = + Min(0.1,0.05*(Fi1.LastParameter() - Fi1.FirstParameter())); + Handle(Geom2dAdaptor_HCurve) hc2d1 = + new Geom2dAdaptor_HCurve(Fi1.PCurveOnSurf(),UInt1-delt1,UInt1+delt1); + Adaptor3d_CurveOnSurface cons1(hc2d1,HS1); + Standard_Real delt2 = + Min(0.1,0.05*(Fi2.LastParameter() - Fi2.FirstParameter())); + Handle(Geom2dAdaptor_HCurve) hc2d2 = + new Geom2dAdaptor_HCurve(Fi2.PCurveOnSurf(),UInt2-delt2,UInt2+delt2); + Adaptor3d_CurveOnSurface cons2(hc2d2,HS2); + Extrema_LocateExtCC ext(cons1,cons2,UInt1,UInt2); + if(ext.IsDone()) { + Standard_Real dist2 = ext.SquareDistance(); + if(dist2<distref2) { + Extrema_POnCurv ponc1,ponc2; + ext.Point(ponc1,ponc2); + UInt1 = ponc1.Parameter(); + UInt2 = ponc2.Parameter(); + gp_Pnt Pnt1 = ponc1.Value(); + gp_Pnt Pnt2 = ponc2.Value(); + P.SetXYZ(0.5*(Pnt1.XYZ() + Pnt2.XYZ())); + } + } +} + +//======================================================================= +//function : BoundSurf +//purpose : computes a GeomAdaptor_Surface from the surface of the +// SurfData Fd1 and trims it to allow the intersection computation + +//======================================================================= +Handle(GeomAdaptor_HSurface) ChFi3d_BoundSurf(TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_SurfData)& Fd1, + const Standard_Integer& IFaCo1, + const Standard_Integer& IFaArc1) +{ + //rmq : as in fact 2 interferences of Fd1 serve only to set limits + // indexes IFaCo1 and IFaArc1 are not useful. + // They are preserver here as an option in case it will be necessary to set + // more restrictive limits (with intersection points as additional argument). + + Handle(GeomAdaptor_HSurface) HS1 = new GeomAdaptor_HSurface(); + GeomAdaptor_Surface& S1 = HS1->ChangeSurface(); + S1.Load(DStr.Surface(Fd1->Surf()).Surface()); + + if ((IFaCo1 == 0)||(IFaArc1 == 0)) + return HS1; + + const ChFiDS_FaceInterference& FiCo1 = Fd1->Interference(IFaCo1); + const ChFiDS_FaceInterference& FiArc1 = Fd1->Interference(IFaArc1); + + Standard_Real Du,Dv,mu,Mu,mv,Mv; + gp_Pnt2d UVf1,UVf2,UVl1,UVl2; + + UVf1 = FiCo1.PCurveOnSurf()->Value(FiCo1.FirstParameter()); + UVl1 = FiCo1.PCurveOnSurf()->Value(FiCo1.LastParameter()); + UVf2 = FiArc1.PCurveOnSurf()->Value(FiArc1.FirstParameter()); + UVl2 = FiArc1.PCurveOnSurf()->Value(FiArc1.LastParameter()); + ChFi3d_Boite(UVf1,UVf2,UVl1,UVl2,Du,Dv,mu,Mu,mv,Mv); + GeomAbs_SurfaceType styp = S1.GetType(); + if (styp == GeomAbs_Cylinder) { + Dv = Max(0.5*Dv,4.*S1.Cylinder().Radius()); + Du = 0.; + S1.Load(DStr.Surface(Fd1->Surf()).Surface(), + mu,Mu,mv-Dv,Mv+Dv); + } + //In the case of a torus or cone, it is not necessary that the bounds create a surface with period more than 2PI. + else if (styp == GeomAbs_Torus || + styp == GeomAbs_Cone) { + Du = Min(PI-0.5*Du,0.1*Du); + Dv = 0.; + S1.Load(DStr.Surface(Fd1->Surf()).Surface(), + mu-Du,Mu+Du,mv,Mv); + } + else if (styp == GeomAbs_Plane) { + Du = Max(0.5*Du,4.*Dv); + Dv = 0.; + S1.Load(DStr.Surface(Fd1->Surf()).Surface(), + mu-Du,Mu+Du,mv,Mv); + } + return HS1; +} +//======================================================================= +//function : SearchPivot +//purpose : +//======================================================================= +Standard_Integer ChFi3d_SearchPivot(Standard_Integer* s, + Standard_Real u[3][3], + const Standard_Real t) +{ + // This function finds as pivot a cd the sections which of + // do not cross on the opposite face. + // - probably there will be cases asymmetric to the point that + // none of tree fillets will match! To be SEEN. + // - in case when several fillets match the + // first one taken is not inevitably the best + // it should be refined by comparing the parameters on + // guide lines and (/or) radiuses. + + Standard_Boolean bondeb,bonfin; + for(Standard_Integer i = 0; i <= 2; i++) { + if(s[(i+1)%3] == 1) {bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] >= -t);} + else {bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] <= t);} + if(s[(i+2)%3] == 1) {bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] >= -t);} + else {bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] <= t);} + if (bondeb && bonfin) { return i; } + } + return -1; +} + + + +//======================================================================= +//function : SearchFD +//purpose : +//======================================================================= +Standard_Boolean ChFi3d_SearchFD(TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_Stripe)& cd1, + const Handle(ChFiDS_Stripe)& cd2, + const Standard_Integer sens1, + const Standard_Integer sens2, + Standard_Integer& i1, + Standard_Integer& i2, + Standard_Real& p1, + Standard_Real& p2, + const Standard_Integer ind1, + const Standard_Integer ind2, + TopoDS_Face& face, + Standard_Boolean& sameside, + Standard_Integer& jf1, + Standard_Integer& jf2) +{ + Standard_Boolean found = Standard_False; + Standard_Integer id1 = ind1, id2 = ind2; + Standard_Integer if1 = ind1, if2 = ind2; + Standard_Integer l1 = cd1->SetOfSurfData()->Length(); + Standard_Integer l2 = cd2->SetOfSurfData()->Length(); + Standard_Integer i; + Standard_Boolean fini1 = Standard_False, fini2 = Standard_False; + Standard_Boolean visavis,visavisok = Standard_False; + TopoDS_Vertex Vtx; + while( !found ) { + for(i = id1; (i*sens1) <= (if1*sens1) && !found && !fini2; i = i+sens1 ) { + if(ChFi3d_IsInFront(DStr,cd1,cd2,i,if2,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)) { + i1 = i; + i2 = if2; + found = Standard_True; + } + else if (visavis && !visavisok) { + visavisok = Standard_True; + i1 = i; + i2 = if2; + } + } + if(!fini1) { + if1 = if1 + sens1; + if(if1 < 1 || if1 > l1) { if1 = if1 - sens1; fini1 = Standard_True; } + } + + for(i = id2; (i*sens2) <= (if2*sens2) && !found && !fini1; i = i+sens2 ) { + if(ChFi3d_IsInFront(DStr,cd1,cd2,if1,i,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)) { + i1 = if1; + i2 = i; + found = Standard_True; + } + else if (visavis && !visavisok) { + visavisok = Standard_True; + i1 = if1; + i2 = i; + } + } + if(!fini2) { + if2 = if2 + sens2; + if(if2 < 1 || if2 > l2) { if2 = if2 - sens2; fini2 = Standard_True; } + } + if(fini1 && fini2) break; + } + return found; +} + +//======================================================================= +//function : Parameters +//purpose : compute the parameters <u> and <v> of the 3d point <p3d> +// on the surface <S> if it's an analytic surface +//======================================================================= + +void ChFi3d_Parameters(const Handle(Geom_Surface)& S, + const gp_Pnt& p3d, + Standard_Real& u, + Standard_Real& v) +{ + GeomAdaptor_Surface gas(S); + switch ( gas.GetType() ) { + case GeomAbs_Plane : + ElSLib::Parameters(gas.Plane(),p3d,u,v); + break; + case GeomAbs_Cylinder : + ElSLib::Parameters(gas.Cylinder(),p3d,u,v); + break; + case GeomAbs_Cone : + ElSLib::Parameters(gas.Cone(),p3d,u,v); + break; + case GeomAbs_Sphere : + ElSLib::Parameters(gas.Sphere(),p3d,u,v); + break; + case GeomAbs_Torus : + ElSLib::Parameters(gas.Torus(),p3d,u,v); + break; + case GeomAbs_BezierSurface : + case GeomAbs_BSplineSurface : + default : + { + GeomAPI_ProjectPointOnSurf tool(p3d,S); + if ( tool.NbPoints() != 1 ) + StdFail_NotDone::Raise(""); + else + tool.Parameters(1,u,v); + } + } +} + +//======================================================================= +//function : TrimCurve +//purpose : trims the curve <gc> between the points <FirstP> and +// <LastP>. The trimmed curve is <gtc> +//======================================================================= + +void ChFi3d_TrimCurve(const Handle(Geom_Curve)& gc, + const gp_Pnt& FirstP, + const gp_Pnt& LastP, + Handle(Geom_TrimmedCurve)& gtc) +{ + Standard_Real uf = 0.,ul = 0.; + GeomAdaptor_Curve gac(gc); + switch ( gac.GetType() ) { + case GeomAbs_Line : + { + uf = ElCLib::Parameter(gac.Line(),FirstP); + ul = ElCLib::Parameter(gac.Line(),LastP); + } + break; + case GeomAbs_Circle : + { + uf = ElCLib::Parameter(gac.Circle(),FirstP); + ul = ElCLib::Parameter(gac.Circle(),LastP); + } + break; + case GeomAbs_Ellipse : + { + uf = ElCLib::Parameter(gac.Ellipse(),FirstP); + ul = ElCLib::Parameter(gac.Ellipse(),LastP); + } + break; + case GeomAbs_Hyperbola : + { + uf = ElCLib::Parameter(gac.Hyperbola(),FirstP); + ul = ElCLib::Parameter(gac.Hyperbola(),LastP); + } + break; + case GeomAbs_Parabola : + { + uf = ElCLib::Parameter(gac.Parabola(),FirstP); + ul = ElCLib::Parameter(gac.Parabola(),LastP); + } + break; + default : + { + GeomAPI_ProjectPointOnCurve tool(FirstP,gc); + if ( tool.NbPoints() != 1 ) + StdFail_NotDone::Raise(""); + else + uf = tool.Parameter(1); + tool.Init(LastP,gc); + if ( tool.NbPoints() != 1 ) + StdFail_NotDone::Raise(""); + else + ul = tool.Parameter(1); + } + } + gtc = new Geom_TrimmedCurve(gc,uf,ul); +} + + + +//======================================================================= +//function : GoodExt +//purpose : +//======================================================================= +static Standard_Boolean GoodExt(const Handle(Geom_Curve)& C, + const gp_Vec& V, + const Standard_Real f, + const Standard_Real l, + const Standard_Real a) +{ + for(Standard_Integer i = 0; i < 6; i++) { + gp_Pnt d0; gp_Vec d1; + const Standard_Real t = i * 0.2; + C->D1(((1-t)*f+t*l),d0,d1); + const Standard_Real ang = d1.Angle(V); + const Standard_Real angref = a*t + 0.002; + if(ang > angref) return Standard_False; + } + return Standard_True; +} +//======================================================================= +//function : PerformElSpine +//purpose : +//======================================================================= +Standard_EXPORT + void ChFi3d_PerformElSpine(Handle(ChFiDS_HElSpine)& HES, + Handle(ChFiDS_Spine)& Spine, + const GeomAbs_Shape continuity, + const Standard_Real tol) +{ + + Standard_Boolean periodic, Bof, checkdeb, cepadur,bIsSmooth; + Standard_Integer IEdge,IF,IL,nbed, iToApproxByC2; + Standard_Real WF, WL, Wrefdeb, Wreffin,nwf,nwl,period,pared,tolpared; + Standard_Real First, Last, epsV, urefdeb, tolrac; + GeomAbs_Shape aContinuity; + gp_Pnt PDeb, PFin, Bout; + gp_Vec VrefDeb, VrefFin; + Handle(Geom_Curve) Cv; + Handle(Geom_BoundedCurve) TC; + Handle(Geom_BSplineCurve) BS, BSpline; + TopoDS_Edge E, Eold; + TopoDS_Vertex V; + // + ChFiDS_ElSpine& ES = HES->ChangeCurve(); + WF = ES.FirstParameter(); + WL = ES.LastParameter(); + Wrefdeb = WF; + Wreffin = WL; + nwf = WF; + nwl = WL; + nbed = Spine->NbEdges(); + periodic = Spine->IsPeriodic(); + if(periodic) { + period = Spine->Period(); + nwf = ElCLib::InPeriod(WF,-tol,period-tol); + IF = Spine->Index(nwf,1); + nwl = ElCLib::InPeriod(WL,tol,period+tol); + IL = Spine->Index(nwl,0); + if(nwl<nwf+tol) IL += nbed; + } + else{ + IF = Spine->Index(WF,1); + IL = Spine->Index(WL,0); + Wrefdeb = Max(Spine->FirstParameter(IF),WF); + Wreffin = Min(Spine->LastParameter(IL),WL); + } + // + Spine->D1(WF,PDeb,VrefDeb); + Spine->D1(WL,PFin,VrefFin); + VrefDeb.Normalize(); + VrefFin.Normalize(); + // + TColgp_Array1OfPnt ExtrapPole(1, 5); + TColgp_Array1OfPnt ExtraCoeffs(1, 5); + TColgp_Array1OfXYZ Cont(1,5); + // Attention on segmente eventuellement la premiere et la + // derniere arete. + // Traitment de la premiere arete + cepadur = 0; + E=Spine->Edges(IF); + Bof=BRepLib::BuildCurve3d(E); + const BRepAdaptor_Curve& edc = Spine->CurrentElementarySpine(IF); + tolpared = edc.Resolution(tol); + Cv = BRep_Tool::Curve(E, First, Last); + urefdeb = Spine->FirstParameter(IF); + checkdeb = (nwf > urefdeb); + if(checkdeb) { + Spine->Parameter(IF,nwf,pared,0); + } + // + if(E.Orientation() == TopAbs_REVERSED) { + Standard_Real sov = First; + First = Cv->ReversedParameter(Last); + Last = Cv->ReversedParameter(sov); + if(checkdeb) { + pared = Cv->ReversedParameter(pared); + } + else{ + pared = First; + } + if(First < pared) { + First = pared; + } + if(IL == IF) { + Standard_Real ureffin = Spine->LastParameter(IL); + Standard_Boolean checkfin = (nwl < ureffin); + if(checkfin) { + Spine->Parameter(IL,nwl,pared,0); + pared = Cv->ReversedParameter(pared); + } + else { + pared = Last; + } + if(pared < Last) { + Last = pared; + } + } + Cv = Cv->Reversed(); + }//if(E.Orientation() == TopAbs_REVERSED) + else {//#1 + if(!checkdeb) { + pared = First; + } + if(First < pared) { + First = pared; + } + if(IL == IF) { + Standard_Real ureffin = Spine->LastParameter(IL); + Standard_Boolean checkfin = (nwl < ureffin); + if(checkfin) { + Spine->Parameter(IL,nwl,pared,0); + } + else { + pared = Last; + } + if(pared < Last) { + Last = pared; + } + } + }// else {//#1 + // + if(Abs(Last-First) < tolpared) { + cepadur = 1; + } + // + //Petite veru pour les cas ou un KPart a bouffe l arete + //sans parvenir a terminer. On tire une droite. + if(cepadur) { + Handle(Geom_Line) L; + gp_Pnt ptemp; gp_Vec vtemp; + if(WL < Spine->FirstParameter(1) + tol) { + ES.LastPointAndTgt(ptemp,vtemp); + gp_Dir d(vtemp); + gp_Pnt olin; + olin.ChangeCoord().SetLinearForm(-WL,d.XYZ(),PFin.XYZ()); + L = new Geom_Line(olin,d); + ES.SetCurve(L); + } + else if(WF > Spine->LastParameter(nbed) - tol) { + ES.FirstPointAndTgt(ptemp,vtemp); + gp_Dir d(vtemp); + gp_Pnt olin; + olin.ChangeCoord().SetLinearForm(-WF,d.XYZ(),PDeb.XYZ()); + L = new Geom_Line(olin,d); + ES.SetCurve(L); + } + return;// => + } + // + TC = new (Geom_TrimmedCurve)(Cv, First, Last); + BS=GeomConvert::CurveToBSplineCurve(TC); + CurveCleaner(BS, Abs(WL-WF)*1.e-4, 0); + // + //Smoothing of the curve + iToApproxByC2=0; + aContinuity=TC->Continuity(); + bIsSmooth=ChFi3d_IsSmooth(TC); + if (aContinuity < GeomAbs_C2 && !bIsSmooth) { + ++iToApproxByC2; + BS = ChFi3d_ApproxByC2(TC); + TC=BS; + } + // + // Concatenation des aretes suivantes + GeomConvert_CompCurveToBSplineCurve Concat( TC, Convert_QuasiAngular ); + // + Eold = E; + for (IEdge=IF+1; IEdge<=IL; ++IEdge) { + Standard_Integer iloc = IEdge; + if(periodic) { + iloc = (IEdge - 1)%nbed + 1; + } + // + E = Spine->Edges(iloc); + if (BRep_Tool::Degenerated(E)) { + continue; + } + // + epsV = tol; + Bof = TopExp::CommonVertex(Eold, E, V); + if (Bof) { + epsV = BRep_Tool::Tolerance(V); + } + // + Bof = BRepLib::BuildCurve3d(E); + if (!Bof) { + Standard_ConstructionError::Raise("PerformElSpine : BuildCurve3d error"); + } + // + Cv = BRep_Tool::Curve(E, First, Last); + if(IEdge == IL) { + Standard_Real ureffin = Spine->LastParameter(iloc); + Standard_Boolean checkfin = (nwl < ureffin); + if(checkfin) { + Spine->Parameter(iloc,nwl,pared,0); + } + else { + pared = Last; + } + if(E.Orientation() == TopAbs_REVERSED) { + Standard_Real sov = First; + First = Cv->ReversedParameter(Last); + Last = Cv->ReversedParameter(sov); + if(checkfin) { + pared = Cv->ReversedParameter(pared); + } + else{ + pared = Last; + } + Cv = Cv->Reversed(); + } + if(pared < Last) { + Last = pared; + } + } + // + TC = new (Geom_TrimmedCurve)(Cv, First, Last); + BS = GeomConvert::CurveToBSplineCurve(TC); + CurveCleaner(BS, Abs(WL-WF)*1.e-4, 0); + // + //Smoothing of the curve + aContinuity=TC->Continuity(); + bIsSmooth=ChFi3d_IsSmooth(TC); + if (aContinuity < GeomAbs_C2 && !bIsSmooth) { + ++iToApproxByC2; + BS = ChFi3d_ApproxByC2( TC ); + TC = BS; + } + // + tolrac = Min(tol, epsV); + Bof = Concat.Add( TC, 2.*tolrac, Standard_True ); + // si l'ajout ne s'est pas bien passe on essai d'augmenter la tolerance + if (!Bof) { + Bof = Concat.Add( TC, 2.*epsV, Standard_True ); + } + if (!Bof) { + Bof = Concat.Add( TC, 200.*epsV, Standard_True ); + if (!Bof) { + Standard_ConstructionError::Raise("PerformElSpine: spine merged error"); + } + } + Eold = E; + }// for (IEdge=IF+1; IEdge<=IL; ++IEdge) { + // + // On a la portion d elspine calculee sans prolongements sur la partie + // valide des aretes du chemin. + BSpline = Concat.BSplineCurve(); + // There is a reparametrisation to maximally connect the abscissas of edges. + TColStd_Array1OfReal BSNoeuds (1, BSpline->NbKnots()); + BSpline->Knots(BSNoeuds); + BSplCLib::Reparametrize (Wrefdeb, Wreffin, BSNoeuds); + BSpline->SetKnots(BSNoeuds); + // + // Traitement des Extremites + Standard_Integer caredeb, carefin; + Standard_Real LocalWL, LocalWF, Angle; + GeomAdaptor_Curve gacurve; + Handle(Geom_BSplineCurve) newc; + // + caredeb = 0; + carefin = 0; + Angle = PI*0.75; + LocalWL = WL; + LocalWF = WF; + if (!ES.IsPeriodic() && !PDeb.IsEqual(BSpline->Pole(1), tol) ) { + // Prolongement C3 au debut + // afin d'eviter des pts d'inflexions dans la partie utile de la + // spine le prolongement se fait jusqu'a un point eloigne. + if(BSpline->IsRational()) { + caredeb = 1; + } + // + Standard_Real rabdist = Wrefdeb - WF; + Bout = PDeb.Translated(-20*rabdist * VrefDeb); + Standard_Boolean goodext = 0; + for(Standard_Integer icont = 3; icont>=1 && !goodext; icont--) { + newc = BSpline; + GeomLib::ExtendCurveToPoint( newc, Bout, icont, Standard_False); + gacurve.Load(newc); + GCPnts_AbscissaPoint GCP(gacurve,-rabdist,Wrefdeb,WF); + if(GCP.IsDone()) { + WF = GCP.Parameter(); + goodext = GoodExt(newc,VrefDeb,Wrefdeb,WF,Angle); + } + } + if(caredeb) { + caredeb = newc->NbKnots() - BSpline->NbKnots(); + } + BSpline = newc; + LocalWF = BSpline->FirstParameter(); + } + // + if (!ES.IsPeriodic() && !PFin.IsEqual(BSpline->Pole(BSpline->NbPoles()), tol) ) { + // Prolongement C3 en fin + if(BSpline->IsRational()) { + carefin = 1; + } + Standard_Real rabdist = WL - Wreffin; + Bout = PFin.Translated(20*rabdist * VrefFin); + Standard_Boolean goodext = 0; + for(Standard_Integer icont = 3; icont>=1 && !goodext; icont--) { + newc = BSpline; + GeomLib::ExtendCurveToPoint( newc, Bout, icont, Standard_True); + gacurve.Load(newc); + GCPnts_AbscissaPoint GCP(gacurve,rabdist,Wreffin,WL); + if(GCP.IsDone()) { + WL = GCP.Parameter(); + goodext = GoodExt(newc, VrefFin, Wreffin,WL,Angle); + } + } + if(carefin) { + carefin = newc->NbKnots() - BSpline->NbKnots(); + } + BSpline = newc; + LocalWL = BSpline->LastParameter(); + } + // + //Reparametrisation et segmentation sur le domaine de la Spine. + if(Abs(BSpline->FirstParameter() - WF)<tol) { + WF = BSpline->FirstParameter(); + } + if(Abs(BSpline->LastParameter() - WL)<tol) { + WL = BSpline->LastParameter(); + } + // + if ( (LocalWF<WF) || (LocalWL>WL)) { // pour eviter des pb avec segment! + BSpline->Segment(WF, WL); + ES.FirstParameter(WF); + ES.LastParameter(WL); + } + // + if (BSpline->IsRational()) { + Handle(Geom_BSplineCurve) C1; + C1 = Handle(Geom_BSplineCurve)::DownCast(BSpline->Copy()); + GeomConvert::C0BSplineToC1BSplineCurve(C1, tol, 0.1); + // Il faut s'assurer que l'origine n'a pas bouge (cts21158) + if (C1->FirstParameter() == BSpline->FirstParameter()) { + BSpline = C1; + } + else { + //cout << "Attention : Echec de C0BSplineToC1 !" << endl; + } + } + // + Standard_Integer fk, lk, MultMax, ii; + // Deformation eventuelle pour rendre la spine C2. + // ou C3 pour des approx C2 + if((caredeb || carefin) && BSpline->Degree() < 8) { + BSpline->IncreaseDegree(8); + } + // + fk = 2; + lk = BSpline->NbKnots()-1; + if(BSpline->IsPeriodic()) { + fk = 1; + } + if(caredeb) { + fk += caredeb; + } + if(carefin) { + lk -= carefin; + } + // + if (continuity == GeomAbs_C3) { + if (BSpline->Degree() < 7) { + BSpline->IncreaseDegree(7); + } + MultMax = BSpline->Degree() - 3; + } + else { + if (BSpline->Degree() < 5) { + BSpline->IncreaseDegree(5); + } + MultMax = BSpline->Degree() - 2; + } + // correction C2 or C3 (if possible) + CurveCleaner(BSpline, Abs(WL-WF)*1.e-4, 1); + CurveCleaner(BSpline, Abs(WL-WF)*1.e-2, MultMax); + Standard_Integer MultMin = Max(BSpline->Degree() - 4, 1); + for (ii = fk; ii <= lk; ii++) { + if( BSpline->Multiplicity(ii) > MultMax ) { + Bof = BSpline->RemoveKnot(ii, MultMax, Abs(WL-WF)/10); + } + // See C4 + if( BSpline->Multiplicity(ii) > MultMin ) { + Bof = BSpline->RemoveKnot(ii, MultMin, Abs(WL-WF)*1.e-4); + } + } + // elspine periodic => BSpline Periodic + if(ES.IsPeriodic()) { + if(!BSpline->IsPeriodic()) { + BSpline->SetPeriodic(); + //modified by NIZNHY-PKV Fri Dec 10 12:20:22 2010ft + if (iToApproxByC2) { + Bof = BSpline->RemoveKnot(1, MultMax, Abs(WL-WF)/10); + } + //Bof = BSpline->RemoveKnot(1, MultMax, Abs(WL-WF)/10); + //modified by NIZNHY-PKV Mon Dec 13 14:12:54 2010t + } + } + else { + // Otherwise is it necessary to move the poles to adapt + // them to new tangents ? + Standard_Boolean adjust = Standard_False; + gp_Pnt P1, P2; + gp_Vec V1, V2; + BSpline->D1(WF, P1, V1); + V1.Normalize(); + ES.FirstPointAndTgt(PDeb,VrefDeb); + Standard_Real scaldeb = VrefDeb.Dot(V1); + Standard_Real disdeb = PDeb.Distance(P1); + if((Abs(WF-LocalWF) < 1.e-12) && + ((scaldeb <= 0.9999999) || + disdeb >= tol)) { + // Yes if there was no extension and the tangent is not the good one. + adjust = Standard_True; + } + BSpline->D1(WL, P2, V2); + V2.Normalize(); + ES.LastPointAndTgt(PFin,VrefFin); + Standard_Real scalfin = VrefFin.Dot(V2); + Standard_Real disfin = PFin.Distance(P2); + if((Abs(WL-LocalWL) < 1.e-12) && + ((scalfin <= 0.9999999)|| + disfin >= tol)) { + // the same at the end + adjust = Standard_True; + } + if(adjust) { + GeomLib::AdjustExtremity(BSpline, PDeb, PFin, VrefDeb, VrefFin); + } + } + + // Le Resultat + ES.SetCurve(BSpline); +} + +//======================================================================= +//function : cherche_face1 +//purpose : find face F different from F1 in the map. +// The map contains two faces adjacent to an edge +//======================================================================= +void ChFi3d_cherche_face1 (const TopTools_ListOfShape & map, + const TopoDS_Face & F1, + TopoDS_Face & F) +{ + TopoDS_Face Fcur; + Standard_Boolean trouve=Standard_False; + TopTools_ListIteratorOfListOfShape It; + for (It.Initialize(map);It.More()&&!trouve;It.Next()) { + Fcur=TopoDS::Face (It.Value()); + if (!Fcur.IsSame(F1)) { + F=Fcur;trouve=Standard_True;} + } +} +//======================================================================= +//function : cherche_element +//purpose : find edge E of F1 other than E1 and containing vertex V +// Vtx is the other vertex of E +//======================================================================= +void ChFi3d_cherche_element(const TopoDS_Vertex & V, + const TopoDS_Edge & E1, + const TopoDS_Face & F1, + TopoDS_Edge & E , + TopoDS_Vertex & Vtx ) +{ + Standard_Integer ie; + TopoDS_Vertex V1,V2; + Standard_Boolean trouve=Standard_False; + TopoDS_Edge Ecur; + TopTools_IndexedMapOfShape MapE; + TopExp::MapShapes( F1,TopAbs_EDGE,MapE); + for ( ie=1; ie<= MapE.Extent()&& !trouve; ie++) { + Ecur = TopoDS::Edge (MapE(ie)); + if (!Ecur.IsSame(E1)) { + TopTools_IndexedMapOfShape MapV; + TopExp::MapShapes(Ecur, TopAbs_VERTEX, MapV); + if (MapV.Extent()==2) { + V1 = TopoDS::Vertex (MapV(1)); + V2 = TopoDS::Vertex (MapV(2)); + if (V1.IsSame(V)) { + Vtx=V2; + E=Ecur; + trouve=Standard_True; + } + else if (V2.IsSame(V)) { + Vtx=V1; + E=Ecur; + trouve=Standard_True; + } + } + } + } +} +//======================================================================= +//function : cherche_edge +//purpose : find edge E of F1 other than the list of edges E1 and +// containing vertex V Vtx is the other vertex of E. +//======================================================================= +void ChFi3d_cherche_edge(const TopoDS_Vertex & V, + const TopTools_Array1OfShape & E1, + const TopoDS_Face & F1, + TopoDS_Edge & E , + TopoDS_Vertex & Vtx ) +{ + Standard_Integer ie,i; + TopoDS_Vertex V1,V2; + Standard_Boolean trouve=Standard_False; + TopoDS_Edge Ecur; + Standard_Boolean same; + TopTools_IndexedMapOfShape MapE; + TopExp::MapShapes( F1,TopAbs_EDGE,MapE); + for ( ie=1; ie<= MapE.Extent()&& !trouve; ie++) { + Ecur=TopoDS::Edge (MapE(ie)); + same=Standard_False; + for (i=E1.Lower();i<=E1.Upper() ;i++) { + if (Ecur.IsSame(E1.Value(i))) same=Standard_True; + } + if (!same) { + TopTools_IndexedMapOfShape MapV; + TopExp::MapShapes(Ecur, TopAbs_VERTEX, MapV); + if (MapV.Extent()==2) { + V1 = TopoDS::Vertex (MapV(1)); + V2 = TopoDS::Vertex (MapV(2)); + if (V1.IsSame(V)) { + Vtx=V2; + E=Ecur; + trouve=Standard_True; + } + else if (V2.IsSame(V)) { + Vtx=V1; + E=Ecur; + trouve=Standard_True; + } + } + } + } +} + +//======================================================================= +//function : nbface +//purpose : calculates the number of faces common to a vertex +// +//======================================================================= +Standard_Integer ChFi3d_nbface (const TopTools_ListOfShape & mapVF ) +{ Standard_Integer nface=0; + TopTools_ListIteratorOfListOfShape ItF,JtF; + Standard_Integer fj = 0; + for (ItF.Initialize(mapVF); ItF.More(); ItF.Next()) { + fj++; + Standard_Integer kf = 1; + const TopoDS_Shape& cur = ItF.Value(); + for (JtF.Initialize(mapVF); JtF.More( )&&(kf<fj); JtF.Next(), kf++) { + if(cur.IsSame(JtF.Value())) break; + } + if(kf == fj) nface++; + } + return nface; +} + +//======================================================================= +//function : edge_common_faces +//purpose : determines two faces sharing an edge. +// F1 = F2 if there is an edge to parce +//======================================================================= +void ChFi3d_edge_common_faces (const TopTools_ListOfShape & mapEF, + TopoDS_Face & F1, + TopoDS_Face & F2) +{ TopTools_ListIteratorOfListOfShape It; + TopoDS_Face F; + Standard_Boolean trouve; + It.Initialize(mapEF); + F1=TopoDS::Face(It.Value()); + trouve=Standard_False; + for(It.Initialize(mapEF);It.More()&&!trouve;It.Next()) { + F=TopoDS::Face (It.Value()); + if (!F.IsSame(F1)) { + F2=F;trouve=Standard_True; + } + } + if (!trouve) F2=F1; +} + +/***********************************************************/ +// gives the angle between edges E1 and E2 . Vtx is the +// vertex common to the edges +/************************************************************/ +Standard_Real ChFi3d_AngleEdge (const TopoDS_Vertex & Vtx, + const TopoDS_Edge& E1, + const TopoDS_Edge & E2) +{ Standard_Real angle; + BRepAdaptor_Curve BCurv1(E1); + BRepAdaptor_Curve BCurv2(E2); + Standard_Real parE1,parE2; + gp_Vec dir1,dir2 ; + gp_Pnt P1,P2 ; + parE1=BRep_Tool::Parameter(Vtx,E1); + parE2=BRep_Tool::Parameter(Vtx,E2); + BCurv1.D1(parE1,P1,dir1); + BCurv2.D1(parE2,P2,dir2); + if (!Vtx.IsSame(TopExp::FirstVertex(E1))) dir1.Reverse(); + if (!Vtx.IsSame(TopExp::FirstVertex(E2))) dir2.Reverse(); + angle=Abs(dir1.Angle(dir2)); + return angle; +} + +//================================================================== +// ChercheBordsLibres +// determines if vertex V1 has edges on free borders +// edgelibre1 and edgelibre2 . +// It is supposed that a top can have only 2 edges on free borders +//=================================================================== +void ChFi3d_ChercheBordsLibres(const ChFiDS_Map & myVEMap, + const TopoDS_Vertex & V1, + Standard_Boolean & bordlibre, + TopoDS_Edge & edgelibre1, + TopoDS_Edge & edgelibre2) +{ + bordlibre=Standard_False; + TopTools_ListIteratorOfListOfShape ItE,ItE1; + Standard_Integer nboccur; + for (ItE.Initialize(myVEMap(V1)); ItE.More()&&!bordlibre; ItE.Next()) { + nboccur=0; + const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value()); + if (!BRep_Tool::Degenerated(cur)) { + for (ItE1.Initialize(myVEMap(V1)); ItE1.More(); ItE1.Next()) { + const TopoDS_Edge& cur1 = TopoDS::Edge(ItE1.Value()); + if (cur1.IsSame(cur)) nboccur++; + } + } + if (nboccur==1) { + edgelibre1=cur; + bordlibre=Standard_True; + } + } + if (bordlibre) { + bordlibre=Standard_False; + for (ItE.Initialize(myVEMap(V1)); ItE.More()&&!bordlibre; ItE.Next()) { + nboccur=0; + const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value()); + if (!BRep_Tool::Degenerated(cur)&&!cur.IsSame(edgelibre1)) { + for (ItE1.Initialize(myVEMap(V1)); ItE1.More(); ItE1.Next()) { + const TopoDS_Edge& cur1 = TopoDS::Edge(ItE1.Value()); + if (cur1.IsSame(cur)) nboccur++; + } + } + if (nboccur==1) { + edgelibre2=cur; + bordlibre=Standard_True; + } + } + } +} + +//======================================================================= +//function : NbNotDegeneratedEdges +//purpose : calculate the number of non-degenerated edges of Map VEMap(Vtx) +// Attention the edges of junctions are taken into account twice +//======================================================================= +Standard_Integer ChFi3d_NbNotDegeneratedEdges (const TopoDS_Vertex& Vtx, + const ChFiDS_Map& VEMap) +{ + TopTools_ListIteratorOfListOfShape ItE; + Standard_Integer nba=VEMap(Vtx).Extent(); + for (ItE.Initialize(VEMap(Vtx)); ItE.More(); ItE.Next()) { + const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value()); + if (BRep_Tool::Degenerated(cur)) nba--; + } + return nba; +} + +//======================================================================= +//function : NumberOfEdges +//purpose : calculate the number of edges arriving to the top Vtx +// degenerated edges are not taken into account. +//======================================================================= +Standard_Integer ChFi3d_NumberOfEdges(const TopoDS_Vertex& Vtx, + const ChFiDS_Map& VEMap) +{ + Standard_Integer nba; + Standard_Boolean bordlibre; + TopoDS_Edge edgelibre1,edgelibre2; + nba=ChFi3d_NbNotDegeneratedEdges(Vtx, VEMap); + ChFi3d_ChercheBordsLibres(VEMap,Vtx,bordlibre,edgelibre1,edgelibre2); + if (bordlibre) nba=(nba-2)/2 +2; + else nba=nba/2; + return nba; +} +//===================================================== +// function cherche_vertex +// finds common vertex between two edges +//===================================================== + +void ChFi3d_cherche_vertex (const TopoDS_Edge & E1, + const TopoDS_Edge & E2, + TopoDS_Vertex & vertex, + Standard_Boolean & trouve) +{ Standard_Integer i,j; + TopoDS_Vertex Vcur1,Vcur2; + trouve=Standard_False; + TopTools_IndexedMapOfShape MapV1,MapV2; + TopExp::MapShapes( E1,TopAbs_VERTEX,MapV1); + TopExp::MapShapes( E2,TopAbs_VERTEX,MapV2); + for ( i=1; i<= MapV1.Extent()&&!trouve; i++) { + TopoDS_Shape alocalshape = TopoDS_Shape (MapV1(i)); + Vcur1=TopoDS::Vertex(alocalshape); +// Vcur1=TopoDS::Vertex(TopoDS_Shape (MapV1(i))); + for ( j=1; j<= MapV2.Extent()&&!trouve; j++) { + TopoDS_Shape aLocalShape = TopoDS_Shape (MapV2(j)); + Vcur2=TopoDS::Vertex(aLocalShape); +// Vcur2=TopoDS::Vertex(TopoDS_Shape (MapV2(j))); + if (Vcur2.IsSame(Vcur1)) { + vertex=Vcur1;trouve=Standard_True; + } + } + } +} +//======================================================================= +//function : ChFi3d_Couture +//purpose : determine si F a une arete de couture +//======================================================================= +void ChFi3d_Couture( const TopoDS_Face & F, + Standard_Boolean & couture, + TopoDS_Edge & edgecouture) +{ TopoDS_Edge Ecur; + couture=Standard_False; + TopTools_IndexedMapOfShape MapE1; + TopExp::MapShapes( F,TopAbs_EDGE,MapE1); + TopLoc_Location Loc; + Handle(Geom_Surface) Surf =BRep_Tool::Surface(F,Loc); + for ( Standard_Integer i=1; i<= MapE1.Extent()&&!couture; i++) { + TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(i)); + Ecur=TopoDS::Edge(aLocalShape); +// Ecur=TopoDS::Edge(TopoDS_Shape (MapE1(i))); + if (BRep_Tool::IsClosed(Ecur,Surf,Loc)) { + couture=Standard_True; + edgecouture=Ecur; + } + } +} + +//======================================================================= +//function : ChFi3d_CoutureOnVertex +//purpose : +//======================================================================= +void ChFi3d_CoutureOnVertex( const TopoDS_Face & F, + const TopoDS_Vertex & V, + Standard_Boolean & couture, + TopoDS_Edge & edgecouture) +{ TopoDS_Edge Ecur; + couture = Standard_False; + TopTools_IndexedMapOfShape MapE1; + TopExp::MapShapes( F,TopAbs_EDGE,MapE1); + TopLoc_Location Loc; + Handle(Geom_Surface) Surf = BRep_Tool::Surface(F,Loc); + for ( Standard_Integer i=1; i <= MapE1.Extent(); i++) { + TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(i)); + Ecur=TopoDS::Edge(aLocalShape); +// Ecur=TopoDS::Edge(TopoDS_Shape (MapE1(i))); + if (BRep_Tool::IsClosed(Ecur,Surf,Loc)) { + TopoDS_Vertex Vf, Vl; + TopExp::Vertices( Ecur, Vf, Vl ); + if (Vf.IsSame(V) || Vl.IsSame(V)) + { + couture = Standard_True; + edgecouture = Ecur; + break; + } + } + } +} +//======================================================================= +//function : ChFi3d_IsPseudoSeam +//purpose : +//======================================================================= +Standard_Boolean ChFi3d_IsPseudoSeam( const TopoDS_Edge& E, + const TopoDS_Face& F ) +{ + if (! BRep_Tool::IsClosed( E, F )) + return Standard_False; + + Standard_Boolean NeighborSeamFound = Standard_False; + TopoDS_Vertex Vf, Vl, V1, V2; + TopExp::Vertices( E, Vf, Vl ); + TopExp_Explorer Explo( F, TopAbs_EDGE ); + for (; Explo.More(); Explo.Next()) + { + TopoDS_Edge Ecur = TopoDS::Edge( Explo.Current() ); + if (! Ecur.IsSame(E)) + { + TopExp::Vertices( Ecur, V1, V2 ); + if ((V1.IsSame(Vf) || V1.IsSame(Vl) || V2.IsSame(Vf) || V2.IsSame(Vl)) && + BRepTools::IsReallyClosed( Ecur, F )) + { + NeighborSeamFound = Standard_True; + break; + } + } + } + return NeighborSeamFound; +} + +//======================================================================= +//function : ChFi3d_ApproxByC2 +//purpose : +//======================================================================= +Handle(Geom_BSplineCurve) ChFi3d_ApproxByC2( const Handle(Geom_Curve)& C ) +{ + Standard_Real First = C->FirstParameter(), Last = C->LastParameter(); + Standard_Integer NbPoints = 101; + + TColgp_Array1OfPnt Points( 1, NbPoints ); + Standard_Real delta = (Last - First) / (NbPoints-1); + for (Standard_Integer i = 1; i <= NbPoints-1; i++) + Points(i) = C->Value(First + (i-1)*delta); + Points(NbPoints) = C->Value(Last); + + GeomAPI_PointsToBSpline Approx( Points , Approx_ChordLength, 3, 8, GeomAbs_C2, 1.000001e-3); + Handle(Geom_BSplineCurve) BS = Approx.Curve(); + return BS; +} +//======================================================================= +//function : ChFi3d_IsSmooth +//purpose : +//======================================================================= +Standard_Boolean ChFi3d_IsSmooth( const Handle(Geom_Curve)& C ) +{ + GeomAdaptor_Curve GAC( C ); + + Standard_Integer ii; + Standard_Integer intrv, nbintv = GAC.NbIntervals(GeomAbs_CN); + TColStd_Array1OfReal TI(1,nbintv+1); + GAC.Intervals(TI,GeomAbs_CN); + Standard_Real Resolution = gp::Resolution(), Curvature; + GeomLProp_CLProps LProp(C, 2, Resolution); + gp_Pnt P1, P2; + Standard_Integer Discretisation = 30; + + gp_Vec PrevVec; + Standard_Boolean prevVecFound = Standard_False; + Standard_Integer intrvFound = 0; + for( intrv = 1; intrv <= nbintv; intrv++) { + Standard_Real t = TI(intrv); + Standard_Real step = (TI(intrv+1) - t) / Discretisation; + for (ii = 1; ii <= Discretisation; ii++) { + LProp.SetParameter(t); + if (!LProp.IsTangentDefined()) + return Standard_False; + Curvature = Abs(LProp.Curvature()); + if (Curvature > Resolution) { + C->D0(t, P1); + LProp.CentreOfCurvature(P2); + PrevVec = gp_Vec(P1, P2); + prevVecFound = Standard_True; + break; + } + t += step; + } + if( prevVecFound ) { + intrvFound = intrv; + break; + } + } + + if( !prevVecFound ) + return Standard_True; + + //for (intrv = 1; intrv <= nbintv; intrv++) { + for (intrv = intrvFound; intrv <= nbintv; intrv++) { + Standard_Real t = TI(intrv); + Standard_Real step = (TI(intrv+1) - t) / Discretisation; + for (ii = 1; ii <= Discretisation; ii++) + { + LProp.SetParameter(t); + if (!LProp.IsTangentDefined()) + return Standard_False; + Curvature = Abs(LProp.Curvature()); + if (Curvature > Resolution) + { + C->D0(t, P1); + LProp.CentreOfCurvature(P2); + gp_Vec Vec(P1, P2); + Standard_Real Angle = PrevVec.Angle( Vec ); + if (Angle > PI/3.) + return Standard_False; + Standard_Real Ratio = Vec.Magnitude() / PrevVec.Magnitude(); + if (Ratio < 1.) + Ratio = 1. / Ratio; + if (Ratio > 2. && (intrv != nbintv || ii != Discretisation)) + return Standard_False; + PrevVec = Vec; + } + t += step; + } + } + + return Standard_True; +} diff --git a/src/ChFi3d/ChFi3d_Builder_0.hxx b/src/ChFi3d/ChFi3d_Builder_0.hxx new file mode 100644 index 00000000..eb3e942f --- /dev/null +++ b/src/ChFi3d/ChFi3d_Builder_0.hxx @@ -0,0 +1,570 @@ +// File: ChFi3d_Builder_0.hxx +// Created: Thu Mar 24 17:23:09 1994 +// Author: Isabelle GRIGNON +// <isg@zerox> + + +#ifndef ChFi3d_Builder_0_HeaderFile +#define ChFi3d_Builder_0_HeaderFile + +#include <TopOpeBRepDS_SurfaceCurveInterference.hxx> +#include <TopOpeBRepDS_CurvePointInterference.hxx> +#include <TopOpeBRepDS_DataStructure.hxx> +#include <TopOpeBRepDS_Curve.hxx> +#include <TopOpeBRepDS_Surface.hxx> +#include <BRepBlend_Extremity.hxx> +#include <ChFiDS_Stripe.hxx> +#include <ChFiDS_SurfData.hxx> +#include <ChFiDS_Spine.hxx> +#include <ChFiDS_HElSpine.hxx> +#include <ChFiDS_CommonPoint.hxx> +#include <ChFiDS_Regularities.hxx> +#include <ChFiDS_FaceInterference.hxx> +#include <ChFiDS_Map.hxx> +#include <TopoDS_Face.hxx> +#include <TopoDS_Vertex.hxx> +#include <TopoDS.hxx> +#include <TopAbs_Orientation.hxx> +#include <TopTools_ListOfShape.hxx> +#include <TopTools_ListIteratorOfListOfShape.hxx> +#include <IntSurf_LineOn2S.hxx> +#include <IntSurf_TypeTrans.hxx> +#include <GeomFill_Boundary.hxx> +#include <GeomFill_BoundWithSurf.hxx> +#include <GeomFill_SimpleBound.hxx> +#include <GeomFill_ConstrainedFilling.hxx> +#include <Geom2d_Curve.hxx> +#include <Geom_Curve.hxx> +#include <Geom_TrimmedCurve.hxx> +#include <Geom_Surface.hxx> +#include <Geom_BezierCurve.hxx> +#include <Geom_Circle.hxx> +#include <GeomAdaptor_Curve.hxx> +#include <GeomAdaptor_Surface.hxx> +#include <GeomAdaptor_HSurface.hxx> +#include <BRepAdaptor_Surface.hxx> +#include <BRepAdaptor_HSurface.hxx> +#include <Adaptor3d_HCurve.hxx> +#include <Adaptor3d_HCurveOnSurface.hxx> +#include <Adaptor3d_HSurface.hxx> +#include <Extrema_LocateExtCC.hxx> +#include <Extrema_POnCurv.hxx> +#include <Bnd_Box.hxx> +#include <GeomAbs_Shape.hxx> +#include <gp_Pnt.hxx> +#include <gp_Vec.hxx> +#include <gp_Pnt2d.hxx> +#include <gp_Vec2d.hxx> +#include <gp_Dir2d.hxx> +#include <TColgp_Array1OfPnt.hxx> +#include <TColgp_Array1OfVec.hxx> +#include <TColStd_Array1OfReal.hxx> +#include <TColStd_Array1OfInteger.hxx> +#include <TopTools_Array1OfShape.hxx> +#ifdef DEB +#include <OSD_Chronometer.hxx> +extern OSD_Chronometer simul,elspine,chemine; +#endif + +Standard_Real ChFi3d_InPeriod(const Standard_Real U, + const Standard_Real UFirst, + const Standard_Real ULast, + const Standard_Real Eps); + +void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2, + Standard_Real& mu,Standard_Real& Mu, + Standard_Real& mv,Standard_Real& Mv); + +void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2, + const gp_Pnt2d& p3,const gp_Pnt2d& p4, + Standard_Real& Du,Standard_Real& Dv, + Standard_Real& mu,Standard_Real& Mu, + Standard_Real& mv,Standard_Real& Mv); + +void ChFi3d_SetPointTolerance(TopOpeBRepDS_DataStructure& DStr, + const Bnd_Box& box, + const Standard_Integer IP); + +void ChFi3d_EnlargeBox(const Handle(Geom_Curve)& C, + const Standard_Real wd, + const Standard_Real wf, + Bnd_Box& box1, + Bnd_Box& box2); + +void ChFi3d_EnlargeBox(const Handle(Adaptor3d_HSurface)& S, + const Handle(Geom2d_Curve)& PC, + const Standard_Real wd, + const Standard_Real wf, + Bnd_Box& box1, + Bnd_Box& box2); + +void ChFi3d_EnlargeBox(const TopoDS_Edge& E, + const TopTools_ListOfShape& LF, + const Standard_Real w, + Bnd_Box& box); + +void ChFi3d_EnlargeBox(TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_Stripe)& st, + const Handle(ChFiDS_SurfData)& sd, + Bnd_Box& b1, + Bnd_Box& b2, + const Standard_Boolean isfirst); + +GeomAbs_Shape ChFi3d_evalconti(const TopoDS_Edge& E, + const TopoDS_Face& F1, + const TopoDS_Face& F2); + +void ChFi3d_conexfaces(const TopoDS_Edge& E, + TopoDS_Face& F1, + TopoDS_Face& F2, + const ChFiDS_Map& EFMap); + +ChFiDS_State ChFi3d_EdgeState(TopoDS_Edge* E, + const ChFiDS_Map& EFMap); + +Standard_Boolean ChFi3d_KParticular +(const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer IE, + const BRepAdaptor_Surface& S1, + const BRepAdaptor_Surface& S2); + +void ChFi3d_BoundFac(BRepAdaptor_Surface& S, + const Standard_Real umin, + const Standard_Real umax, + const Standard_Real vmin, + const Standard_Real vmax, + const Standard_Boolean checknaturalbounds = Standard_True); + +void ChFi3d_BoundSrf(GeomAdaptor_Surface& S, + const Standard_Real umin, + const Standard_Real umax, + const Standard_Real vmin, + const Standard_Real vmax, + const Standard_Boolean checknaturalbounds = Standard_True); + +Standard_Boolean ChFi3d_InterPlaneEdge (Handle(Adaptor3d_HSurface)& Plan, + Handle(Adaptor3d_HCurve)& C, + Standard_Real& W, + const Standard_Boolean Sens, + const Standard_Real tolc); + +void ChFi3d_ExtrSpineCarac(const TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_Stripe)& cd, + const Standard_Integer i, + const Standard_Real p, + const Standard_Integer jf, + const Standard_Integer sens, + gp_Pnt& P, + gp_Vec& V, + Standard_Real& R); + +Handle(Geom_Circle) ChFi3d_CircularSpine(Standard_Real& WFirst, + Standard_Real& WLast, + const gp_Pnt& Pdeb, + const gp_Vec& Vdeb, + const gp_Pnt& Pfin, + const gp_Vec& Vfin, + const Standard_Real rad); + +Handle(Geom_BezierCurve) ChFi3d_Spine(const gp_Pnt& pd, + gp_Vec& vd, + const gp_Pnt& pf, + gp_Vec& vf, + const Standard_Real R); + +Handle(GeomFill_Boundary) ChFi3d_mkbound +(const Handle(Adaptor3d_HSurface)& Fac, + Handle(Geom2d_Curve)& curv, + const Standard_Integer sens1, + const gp_Pnt2d& pfac1, + const gp_Vec2d& vfac1, + const Standard_Integer sens2, + const gp_Pnt2d& pfac2, + const gp_Vec2d& vfac2, + const Standard_Real t3d, + const Standard_Real ta); + +Handle(GeomFill_Boundary) ChFi3d_mkbound +(const Handle(Adaptor3d_HSurface)& Surf, + Handle(Geom2d_Curve)& curv, + const Standard_Integer sens1, + const gp_Pnt2d& p1, + gp_Vec& v1, + const Standard_Integer sens2, + const gp_Pnt2d& p2, + gp_Vec& v2, + const Standard_Real t3d, + const Standard_Real ta); + +Handle(GeomFill_Boundary) ChFi3d_mkbound +(const Handle(Geom_Surface)& s, + const gp_Pnt2d& p1, + const gp_Pnt2d& p2, + const Standard_Real t3d, + const Standard_Real ta, + const Standard_Boolean isfreeboundary = Standard_False); + +Handle(GeomFill_Boundary) ChFi3d_mkbound +(const Handle(Adaptor3d_HSurface)& HS, + const gp_Pnt2d& p1, + const gp_Pnt2d& p2, + const Standard_Real t3d, + const Standard_Real ta, + const Standard_Boolean isfreeboundary = Standard_False); + +Handle(GeomFill_Boundary) ChFi3d_mkbound +(const Handle(Adaptor3d_HSurface)& HS, + const Handle(Geom2d_Curve)& curv, + const Standard_Real t3d, + const Standard_Real ta, + const Standard_Boolean isfreeboundary = Standard_False); + +Handle(GeomFill_Boundary) ChFi3d_mkbound +(const Handle(Adaptor3d_HSurface)& Fac, + Handle(Geom2d_Curve)& curv, + const gp_Pnt2d& p1, + const gp_Pnt2d& p2, + const Standard_Real t3d, + const Standard_Real ta, + const Standard_Boolean isfreeboundary = Standard_False); + +void ChFi3d_Coefficient(const gp_Vec& V3d, + const gp_Vec& D1u, + const gp_Vec& D1v, + Standard_Real& DU, + Standard_Real& DV); + +Handle(Geom2d_Curve) ChFi3d_BuildPCurve +(const gp_Pnt2d& p1, + gp_Dir2d& d1, + const gp_Pnt2d& p2, + gp_Dir2d& d2, + const Standard_Boolean redresse = Standard_True); + +Handle(Geom2d_Curve) ChFi3d_BuildPCurve +(const Handle(Adaptor3d_HSurface)& Surf, + const gp_Pnt2d& p1, + const gp_Vec& v1, + const gp_Pnt2d& p2, + const gp_Vec& v2, + const Standard_Boolean redresse = Standard_False); + +Handle(Geom2d_Curve) ChFi3d_BuildPCurve +(const Handle(Adaptor3d_HSurface)& Surf, + const gp_Pnt2d& p1, + const gp_Vec2d& v1, + const gp_Pnt2d& p2, + const gp_Vec2d& v2, + const Standard_Boolean redresse = Standard_False); + +Standard_Boolean ChFi3d_CheckSameParameter +(const Handle(Adaptor3d_HCurve)& C3d, + Handle(Geom2d_Curve)& Pcurv, + const Handle(Adaptor3d_HSurface)& S, + const Standard_Real tol3d, + Standard_Real& tolreached); + +Standard_Boolean ChFi3d_SameParameter(const Handle(Adaptor3d_HCurve)& C3d, + Handle(Geom2d_Curve)& Pcurv, + const Handle(Adaptor3d_HSurface)& S, + const Standard_Real tol3d, + Standard_Real& tolreached); + +Standard_Boolean ChFi3d_SameParameter(const Handle(Geom_Curve)& C3d, + Handle(Geom2d_Curve)& Pcurv, + const Handle(Geom_Surface)& S, + const Standard_Real Pardeb, + const Standard_Real Parfin, + const Standard_Real tol3d, + Standard_Real& tolreached); + +void ChFi3d_ComputePCurv(const Handle(Geom_Curve)& C3d, + const gp_Pnt2d& UV1, + const gp_Pnt2d& UV2, + Handle(Geom2d_Curve)& Pcurv, + const Handle(Geom_Surface)& S, + const Standard_Real Pardeb, + const Standard_Real Parfin, + const Standard_Real tol3d, + Standard_Real& tolreached, + const Standard_Boolean reverse = Standard_False); + +void ChFi3d_ComputePCurv(const Handle(Adaptor3d_HCurve)& C3d, + const gp_Pnt2d& UV1, + const gp_Pnt2d& UV2, + Handle(Geom2d_Curve)& Pcurv, + const Handle(Adaptor3d_HSurface)& S, + const Standard_Real Pardeb, + const Standard_Real Parfin, + const Standard_Real tol3d, + Standard_Real& tolreached, + const Standard_Boolean reverse = Standard_False); + +void ChFi3d_ComputePCurv(const gp_Pnt2d& UV1, + const gp_Pnt2d& UV2, + Handle(Geom2d_Curve)& Pcurv, + const Standard_Real Pardeb, + const Standard_Real Parfin, + const Standard_Boolean reverse = Standard_False); + +Standard_Boolean ChFi3d_IntTraces(const Handle(ChFiDS_SurfData)& fd1, + const Standard_Real pref1, + Standard_Real& p1, + const Standard_Integer jf1, + const Standard_Integer sens1, + const Handle(ChFiDS_SurfData)& fd2, + const Standard_Real pref2, + Standard_Real& p2, + const Standard_Integer jf2, + const Standard_Integer sens2, + const gp_Pnt2d& RefP2d, + const Standard_Boolean Check2dDistance = Standard_False, + const Standard_Boolean enlarge = Standard_False); + +Standard_Boolean ChFi3d_IsInFront(TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_Stripe)& cd1, + const Handle(ChFiDS_Stripe)& cd2, + const Standard_Integer i1, + const Standard_Integer i2, + const Standard_Integer sens1, + const Standard_Integer sens2, + Standard_Real& p1, + Standard_Real& p2, + TopoDS_Face& face, + Standard_Boolean& sameside, + Standard_Integer& jf1, + Standard_Integer& jf2, + Standard_Boolean& visavis, + const TopoDS_Vertex& Vtx, + const Standard_Boolean Check2dDistance = Standard_False, + const Standard_Boolean enlarge = Standard_False); + +void ChFi3d_ProjectPCurv(const Handle(Adaptor3d_HCurve)& HCg, + const Handle(Adaptor3d_HSurface)& HSg, + Handle(Geom2d_Curve)& Pcurv, + const Standard_Real tol3d, + Standard_Real& tolreached) ; + +void ChFi3d_ReparamPcurv(const Standard_Real Uf, + const Standard_Real Ul, + Handle(Geom2d_Curve)& Pcurv) ; + +void ChFi3d_ComputeArete(const ChFiDS_CommonPoint& P1, + const gp_Pnt2d& UV1, + const ChFiDS_CommonPoint& P2, + const gp_Pnt2d& UV2, + const Handle(Geom_Surface)& Surf, + Handle(Geom_Curve)& C3d, + Handle(Geom2d_Curve)& Pcurv, + Standard_Real& Pardeb, + Standard_Real& Parfin, + const Standard_Real tol3d, + const Standard_Real tol2d, + Standard_Real& tolreached, + const Standard_Integer IFlag); + +Handle(TopOpeBRepDS_SurfaceCurveInterference) + ChFi3d_FilCurveInDS(const Standard_Integer Icurv, + const Standard_Integer Isurf, + const Handle(Geom2d_Curve)& Pcurv, + const TopAbs_Orientation Et); + +TopAbs_Orientation ChFi3d_TrsfTrans(const IntSurf_TypeTrans T1); + +Standard_EXPORT void ChFi3d_FilCommonPoint(const BRepBlend_Extremity& SP, + const IntSurf_TypeTrans TransLine, + const Standard_Boolean Start, + ChFiDS_CommonPoint& CP, + const Standard_Real Tol); + + +Standard_Integer ChFi3d_SolidIndex(const Handle(ChFiDS_Spine)& sp, + TopOpeBRepDS_DataStructure& DStr, + ChFiDS_Map& MapESo, + ChFiDS_Map& MapESh); + +Standard_Integer ChFi3d_IndexPointInDS(const ChFiDS_CommonPoint& P1, + TopOpeBRepDS_DataStructure& DStr); + +Handle(TopOpeBRepDS_CurvePointInterference) ChFi3d_FilPointInDS +(const TopAbs_Orientation Et, + const Standard_Integer Ic, + const Standard_Integer Ip, + const Standard_Real Par, + const Standard_Boolean IsVertex = Standard_False); + +Handle(TopOpeBRepDS_CurvePointInterference) ChFi3d_FilVertexInDS +(const TopAbs_Orientation Et, + const Standard_Integer Ic, + const Standard_Integer Ip, + const Standard_Real Par); + +void ChFi3d_FilDS(const Standard_Integer SolidIndex, + const Handle(ChFiDS_Stripe)& CorDat, + TopOpeBRepDS_DataStructure& DStr, + ChFiDS_Regularities& reglist, + const Standard_Real tol3d, + const Standard_Real tol2d); + + +void ChFi3d_StripeEdgeInter (const Handle(ChFiDS_Stripe)& theStripe1, + const Handle(ChFiDS_Stripe)& theStripe2, + TopOpeBRepDS_DataStructure& DStr, + const Standard_Real tol2d); + +Standard_Integer ChFi3d_IndexOfSurfData(const TopoDS_Vertex& V1, + const Handle(ChFiDS_Stripe)& CD, + Standard_Integer& sens); + +TopoDS_Edge ChFi3d_EdgeFromV1(const TopoDS_Vertex& V1, + const Handle(ChFiDS_Stripe)& CD, + Standard_Integer& sens); + +Standard_Real ChFi3d_ConvTol2dToTol3d(const Handle(Adaptor3d_HSurface)& S, + const Standard_Real tol2d); + +Standard_Boolean ChFi3d_ComputeCurves(Handle(Adaptor3d_HSurface)& S1, + Handle(Adaptor3d_HSurface)& S2, + const TColStd_Array1OfReal& Pardeb, + const TColStd_Array1OfReal& Parfin, + Handle(Geom_Curve)& C3d, + Handle(Geom2d_Curve)& Pc1, + Handle(Geom2d_Curve)& Pc2, + const Standard_Real tol3d, + const Standard_Real tol2d, + Standard_Real& tolreached, + const Standard_Boolean wholeCurv + = Standard_True); + +Standard_Boolean ChFi3d_IntCS(Handle(Adaptor3d_HSurface)& S, + Handle(Adaptor3d_HCurve)& C, + gp_Pnt2d& p2dS, + Standard_Real& wc); + +void ChFi3d_ComputesIntPC (const ChFiDS_FaceInterference& Fi1, + const ChFiDS_FaceInterference& Fi2, + const Handle(GeomAdaptor_HSurface)& HS1, + const Handle(GeomAdaptor_HSurface)& HS2, + Standard_Real& UInt1, + Standard_Real& UInt2); + +void ChFi3d_ComputesIntPC (const ChFiDS_FaceInterference& Fi1, + const ChFiDS_FaceInterference& Fi2, + const Handle(GeomAdaptor_HSurface)& HS1, + const Handle(GeomAdaptor_HSurface)& HS2, + Standard_Real& UInt1, + Standard_Real& UInt2, + gp_Pnt& P); + +Handle(GeomAdaptor_HSurface) ChFi3d_BoundSurf(TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_SurfData)& Fd1, + const Standard_Integer& IFaCo1, + const Standard_Integer& IFaArc1); + +Standard_Integer ChFi3d_SearchPivot(Standard_Integer* s, + Standard_Real u[3][3], + const Standard_Real t); + +Standard_Boolean ChFi3d_SearchFD(TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_Stripe)& cd1, + const Handle(ChFiDS_Stripe)& cd2, + const Standard_Integer sens1, + const Standard_Integer sens2, + Standard_Integer& i1, + Standard_Integer& i2, + Standard_Real& p1, + Standard_Real& p2, + const Standard_Integer ind1, + const Standard_Integer ind2, + TopoDS_Face& face, + Standard_Boolean& sameside, + Standard_Integer& jf1, + Standard_Integer& jf2); + + +void ChFi3d_Parameters(const Handle(Geom_Surface)& S, + const gp_Pnt& p3d, + Standard_Real& u, + Standard_Real& v); + +void ChFi3d_TrimCurve(const Handle(Geom_Curve)& gc, + const gp_Pnt& FirstP, + const gp_Pnt& LastP, + Handle(Geom_TrimmedCurve)& gtc); + +Standard_EXPORT void ChFi3d_PerformElSpine(Handle(ChFiDS_HElSpine)& HES, + Handle(ChFiDS_Spine)& Spine, + const GeomAbs_Shape continuity, + const Standard_Real tol); + +TopoDS_Face ChFi3d_EnlargeFace(const Handle(ChFiDS_Spine)& Spine, + const Handle(BRepAdaptor_HSurface)& HS, + const Standard_Real Tol ); + + +void ChFi3d_cherche_face1 (const TopTools_ListOfShape & map, + const TopoDS_Face & F1, + TopoDS_Face & F); + +void ChFi3d_cherche_element( const TopoDS_Vertex & V, + const TopoDS_Edge & E1, + const TopoDS_Face & F1, + TopoDS_Edge & E , + TopoDS_Vertex & Vtx ); + +Standard_Real ChFi3d_EvalTolReached(const Handle(Adaptor3d_HSurface)& S1, + const Handle(Geom2d_Curve)& pc1, + const Handle(Adaptor3d_HSurface)& S2, + const Handle(Geom2d_Curve)& pc2, + const Handle(Geom_Curve)& C); + +void ChFi3d_cherche_edge( const TopoDS_Vertex & V, + const TopTools_Array1OfShape & E1, + const TopoDS_Face & F1, + TopoDS_Edge & E , + TopoDS_Vertex & Vtx ); + +Standard_Integer ChFi3d_nbface (const TopTools_ListOfShape & mapVF ); + +void ChFi3d_edge_common_faces (const TopTools_ListOfShape & mapEF, + TopoDS_Face & F1, + TopoDS_Face & F2); + + +Standard_Real ChFi3d_AngleEdge (const TopoDS_Vertex & Vtx, + const TopoDS_Edge& E1, + const TopoDS_Edge & E2); + +void ChFi3d_ChercheBordsLibres(const ChFiDS_Map & myVEMap, + const TopoDS_Vertex & V1, + Standard_Boolean & bordlibre, + TopoDS_Edge & edgelibre1, + TopoDS_Edge & edgelibre2); + +Standard_Integer ChFi3d_NbNotDegeneratedEdges (const TopoDS_Vertex& Vtx, + const ChFiDS_Map& VEMap); +Standard_Integer ChFi3d_NumberOfEdges(const TopoDS_Vertex& Vtx, + const ChFiDS_Map& VEMap); + +void ChFi3d_cherche_vertex (const TopoDS_Edge & E1, + const TopoDS_Edge & E2, + TopoDS_Vertex & vertex, + Standard_Boolean & trouve); + +void ChFi3d_Couture( const TopoDS_Face & F, + Standard_Boolean & couture, + TopoDS_Edge & edgecouture); + +void ChFi3d_CoutureOnVertex( const TopoDS_Face & F, + const TopoDS_Vertex & V, + Standard_Boolean & couture, + TopoDS_Edge & edgecouture); + +Standard_Boolean ChFi3d_IsPseudoSeam( const TopoDS_Edge& E, + const TopoDS_Face& F ); + +Handle(Geom_BSplineCurve) ChFi3d_ApproxByC2( const Handle(Geom_Curve)& C ); + +Standard_Boolean ChFi3d_IsSmooth( const Handle(Geom_Curve)& C ); + +#endif diff --git a/src/ChFi3d/ChFi3d_Builder_1.cxx b/src/ChFi3d/ChFi3d_Builder_1.cxx new file mode 100644 index 00000000..877089b3 --- /dev/null +++ b/src/ChFi3d/ChFi3d_Builder_1.cxx @@ -0,0 +1,996 @@ +// File: ChFi3d_Builder_1.cxx +// Created: Wed Dec 15 11:01:29 1993 +// Author: Isabelle GRIGNON +// <isg@zerox> + +#include <ChFi3d_Builder.jxx> + +#include <Precision.hxx> + +#include <gp_Pnt.hxx> +#include <gp_Vec.hxx> + +#include <TopoDS.hxx> +#include <TopoDS_Shape.hxx> +#include <TopoDS_Face.hxx> +#include <TopoDS_Edge.hxx> +#include <TopoDS_Vertex.hxx> + +#include <BRepAdaptor_Curve.hxx> +#include <BRepAdaptor_Surface.hxx> +#include <BRepLProp_SLProps.hxx> + +#include <TopAbs.hxx> +#include <TopAbs_ShapeEnum.hxx> +#include <TopAbs_Orientation.hxx> + +#include <BRep_Tool.hxx> +#include <TopExp.hxx> +#include <TopTools_ListIteratorOfListOfShape.hxx> +#include <TopOpeBRepDS_Surface.hxx> + +#include <ChFiDS_ErrorStatus.hxx> +#include <ChFiDS_State.hxx> +#include <ChFiDS_Spine.hxx> +#include <ChFiDS_FilSpine.hxx> +#include <ChFiDS_HData.hxx> +#include <ChFiDS_SurfData.hxx> +#include <ChFiDS_Regul.hxx> +#include <ChFiDS_ListIteratorOfRegularities.hxx> +#include <ChFiDS_ListIteratorOfListOfStripe.hxx> + +#include <ChFi3d.hxx> +#include <ChFi3d_Builder_0.hxx> + +#include <LocalAnalysis_SurfaceContinuity.hxx> +#include <TopOpeBRepTool_TOOL.hxx> + +#ifdef DEB +extern Standard_Boolean ChFi3d_GetcontextFORCEBLEND(); +#endif + +static TopOpeBRepDS_BuildTool mkbuildtool() +{ + TopOpeBRepTool_GeomTool GT2(TopOpeBRepTool_BSPLINE1, + Standard_True, + Standard_False, + Standard_False); + TopOpeBRepDS_BuildTool BT(GT2); + BT.OverWrite(Standard_False); + BT.Translate(Standard_False); + return BT; +} + +// Modified by Sergey KHROMOV - Tue Dec 18 18:02:55 2001 Begin +Standard_Boolean isTangentFaces(const TopoDS_Edge &theEdge, + const TopoDS_Face &theFace1, + const TopoDS_Face &theFace2) +{ + if (BRep_Tool::Continuity( theEdge, theFace1, theFace2 ) != GeomAbs_C0) + return Standard_True; + + Standard_Real aFirst; + Standard_Real aLast; + +// Obtaining of pcurves of edge on two faces. + const Handle(Geom2d_Curve) aC2d1 = BRep_Tool::CurveOnSurface + (theEdge, theFace1, aFirst, aLast); + const Handle(Geom2d_Curve) aC2d2 = BRep_Tool::CurveOnSurface + (theEdge, theFace2, aFirst, aLast); + if (aC2d1.IsNull() || aC2d2.IsNull()) + return Standard_False; + +// Obtaining of two surfaces from adjacent faces. + Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1); + Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2); + + if (aSurf1.IsNull() || aSurf2.IsNull()) + return Standard_False; + +// Computation of the number of samples on the edge. + BRepAdaptor_Surface aBAS1(theFace1); + BRepAdaptor_Surface aBAS2(theFace2); + Handle(BRepAdaptor_HSurface) aBAHS1 = new BRepAdaptor_HSurface(aBAS1); + Handle(BRepAdaptor_HSurface) aBAHS2 = new BRepAdaptor_HSurface(aBAS2); + Handle(BRepTopAdaptor_TopolTool) aTool1 = new BRepTopAdaptor_TopolTool(aBAHS1); + Handle(BRepTopAdaptor_TopolTool) aTool2 = new BRepTopAdaptor_TopolTool(aBAHS2); + Standard_Integer aNbSamples1 = aTool1->NbSamples(); + Standard_Integer aNbSamples2 = aTool2->NbSamples(); + Standard_Integer aNbSamples = Max(aNbSamples1, aNbSamples2); + + +// Computation of the continuity. + Standard_Real aPar; + Standard_Real aDelta = (aLast - aFirst)/(aNbSamples - 1); + Standard_Integer i, nbNotDone = 0; + + for (i = 1, aPar = aFirst; i <= aNbSamples; i++, aPar += aDelta) { + if (i == aNbSamples) aPar = aLast; + + LocalAnalysis_SurfaceContinuity aCont(aC2d1, aC2d2, aPar, + aSurf1, aSurf2, GeomAbs_G1, + 0.001, 0.001, 0.1, 0.1, 0.1); + if (!aCont.IsDone()) + { + nbNotDone++; + continue; + } + if (!aCont.IsG1()) + return Standard_False; + } + + if (nbNotDone == aNbSamples) + return Standard_False; + + //Compare normals of tangent faces in the middle point + Standard_Real MidPar = (aFirst + aLast)/2.; + gp_Pnt2d uv1 = aC2d1->Value(MidPar); + gp_Pnt2d uv2 = aC2d2->Value(MidPar); + gp_Dir normal1, normal2; + TopOpeBRepTool_TOOL::Nt( uv1, theFace1, normal1 ); + TopOpeBRepTool_TOOL::Nt( uv2, theFace2, normal2 ); + Standard_Real dot = normal1.Dot(normal2); + if (dot < 0.) + return Standard_False; + return Standard_True; +} +// Modified by Sergey KHROMOV - Tue Dec 18 18:02:56 2001 End + +//======================================================================= +//function : ChFi3d_Builder +//purpose : +//======================================================================= +ChFi3d_Builder::ChFi3d_Builder(const TopoDS_Shape& S, + const Standard_Real Ta) : + done(Standard_False), myShape(S) +{ + myDS = new TopOpeBRepDS_HDataStructure(); + myCoup = new TopOpeBRepBuild_HBuilder(mkbuildtool()); + myEFMap.Fill(S,TopAbs_EDGE,TopAbs_FACE); + myESoMap.Fill(S,TopAbs_EDGE,TopAbs_SOLID); + myEShMap.Fill(S,TopAbs_EDGE,TopAbs_SHELL); + myVFMap.Fill(S,TopAbs_VERTEX,TopAbs_FACE); + myVEMap.Fill(S,TopAbs_VERTEX,TopAbs_EDGE); + SetParams(Ta,1.e-4,1.e-5,1.e-4,1.e-5,1.e-3); + SetContinuity(GeomAbs_C1, Ta); +} + +//======================================================================= +//function : SetParams +//purpose : +//======================================================================= + +void ChFi3d_Builder::SetParams(const Standard_Real Tang, + const Standard_Real Tesp, + const Standard_Real T2d, + const Standard_Real TApp3d, + const Standard_Real TolApp2d, + const Standard_Real Fleche) +{ + angular = Tang; + tolesp = Tesp; + tol2d = T2d; + tolapp3d = TApp3d; + tolapp2d = TolApp2d; + fleche = Fleche; +} + +//======================================================================= +//function : SetContinuity +//purpose : +//======================================================================= + +void ChFi3d_Builder::SetContinuity(const GeomAbs_Shape InternalContinuity, + const Standard_Real AngularTolerance) +{ + myConti = InternalContinuity; + tolappangle = AngularTolerance; +} + +//======================================================================= +//function : IsDone +//purpose : +//======================================================================= + +Standard_Boolean ChFi3d_Builder::IsDone() const +{ + return done; +} + +//======================================================================= +//function : Shape +//purpose : +//======================================================================= + +TopoDS_Shape ChFi3d_Builder::Shape()const +{ + Standard_NoSuchObject_Raise_if(!done,""); + return myShapeResult; +} + +//======================================================================= +//function : NbFaultyContours +//purpose : +//======================================================================= + +Standard_Integer ChFi3d_Builder::NbFaultyContours() const +{ + return badstripes.Extent(); +} + +//======================================================================= +//function : FaultyContour +//purpose : +//======================================================================= + +Standard_Integer ChFi3d_Builder::FaultyContour(const Standard_Integer I) const +{ + ChFiDS_ListIteratorOfListOfStripe itel; + Standard_Integer k = 0; + Handle(ChFiDS_Stripe) st; + for (itel.Initialize(badstripes);itel.More(); itel.Next()) { + k += 1; + if(k == I) { + st = itel.Value(); + break; + } + } + if(st.IsNull()) return 0; + k = 0; + for (itel.Initialize(myListStripe);itel.More(); itel.Next()) { + k += 1; + if(st == itel.Value()) return k; + } + return 0; +} + +//======================================================================= +//function : NbComputedSurfaces +//purpose : +//======================================================================= + +Standard_Integer ChFi3d_Builder::NbComputedSurfaces(const Standard_Integer IC) const +{ + ChFiDS_ListIteratorOfListOfStripe itel; + Standard_Integer k = 0; + Handle(ChFiDS_Stripe) st; + for (itel.Initialize(myListStripe);itel.More(); itel.Next()) { + k += 1; + if(k == IC) { + st = itel.Value(); + break; + } + } + if(st.IsNull()) return 0; + if(st->Spine().IsNull()) return 0; + Handle(ChFiDS_HData) hd = st->SetOfSurfData(); + if(hd.IsNull()) return 0; + return hd->Length(); +} + +//======================================================================= +//function : ComputedSurface +//purpose : +//======================================================================= + +Handle(Geom_Surface) ChFi3d_Builder::ComputedSurface(const Standard_Integer IC, + const Standard_Integer IS) const +{ + ChFiDS_ListIteratorOfListOfStripe itel; + Standard_Integer k = 0; + Handle(ChFiDS_Stripe) st; + for (itel.Initialize(myListStripe);itel.More(); itel.Next()) { + k += 1; + if(k == IC) { + st = itel.Value(); + break; + } + } + Handle(ChFiDS_HData) hd = st->SetOfSurfData(); + Standard_Integer isurf=hd->Value(IS)->Surf(); + return myDS->Surface(isurf).Surface(); +} + +//======================================================================= +//function : NbFaultyVertices +//purpose : +//======================================================================= + +Standard_Integer ChFi3d_Builder::NbFaultyVertices() const +{ + return badvertices.Extent(); +} + +//======================================================================= +//function : FaultyVertex +//purpose : +//======================================================================= + +TopoDS_Vertex ChFi3d_Builder::FaultyVertex(const Standard_Integer IV) const +{ + TopTools_ListIteratorOfListOfShape it; + TopoDS_Vertex V; + Standard_Integer k = 0; + for(it.Initialize(badvertices);it.More(); it.Next()) { + k += 1; + if(k == IV) { + V = TopoDS::Vertex(it.Value()); + break; + } + } + return V; +} + +//======================================================================= +//function : HasResult +//purpose : +//======================================================================= + +Standard_Boolean ChFi3d_Builder::HasResult() const +{ + return hasresult; +} + +//======================================================================= +//function : BadShape +//purpose : +//======================================================================= + +TopoDS_Shape ChFi3d_Builder::BadShape()const +{ + Standard_NoSuchObject_Raise_if(!hasresult,""); + return badShape; +} + +//======================================================================= +//function : StripeStatus +//purpose : +//======================================================================= + +ChFiDS_ErrorStatus ChFi3d_Builder::StripeStatus(const Standard_Integer IC)const +{ + ChFiDS_ListIteratorOfListOfStripe itel; + Standard_Integer k =0; + Handle(ChFiDS_Stripe) st; + for (itel.Initialize(myListStripe);itel.More(); itel.Next()) { + k += 1; + if(k == IC) { + st = itel.Value(); + break; + } + } + ChFiDS_ErrorStatus stat=st->Spine()->ErrorStatus(); + return stat; +} + +//======================================================================= +//function : Builder +//purpose : +//======================================================================= + +Handle(TopOpeBRepBuild_HBuilder) ChFi3d_Builder::Builder()const +{ + return myCoup; +} + +//======================================================================= +//function : ChFi3d_FaceTangency +//purpose : determine if the faces opposing to edges are tangent +// to go from opposing faces on e0 to opposing faces +// on e1, consider all faces starting at a common top. +//======================================================================= + +Standard_Boolean ChFi3d_Builder::FaceTangency(const TopoDS_Edge& E0, + const TopoDS_Edge& E1, + const TopoDS_Vertex& V) const +{ + TopTools_ListIteratorOfListOfShape It,Jt; + TopoDS_Edge Ec; + Standard_Integer Nbf; + TopoDS_Face F[2]; + + //It is checked if the connection is not on a regular edge. + for (It.Initialize(myEFMap(E1)), Nbf= 0 ;It.More();It.Next(), Nbf++) { + if (Nbf>1) + Standard_ConstructionError::Raise("ChFi3d_Builder:only 2 faces"); + F[Nbf] = TopoDS::Face(It.Value()); + } + if(Nbf < 2) return Standard_False; +// Modified by Sergey KHROMOV - Fri Dec 21 17:44:19 2001 Begin +//if (BRep_Tool::Continuity(E1,F[0],F[1]) != GeomAbs_C0) { + if (isTangentFaces(E1,F[0],F[1])) { +// Modified by Sergey KHROMOV - Fri Dec 21 17:44:21 2001 End + return Standard_False; + } + + for (Jt.Initialize(myVEMap(V));Jt.More();Jt.Next()) { + Ec = TopoDS::Edge(Jt.Value()); + if (!Ec.IsSame(E0) && !Ec.IsSame(E1) && + Ec.Orientation() != TopAbs_INTERNAL && + Ec.Orientation() != TopAbs_EXTERNAL && + !BRep_Tool::Degenerated(Ec)) { + for (It.Initialize(myEFMap(Ec)), Nbf= 0 ;It.More();It.Next(), Nbf++) { + if (Nbf>1) + Standard_ConstructionError::Raise("ChFi3d_Builder:only 2 faces"); + F[Nbf] = TopoDS::Face(It.Value()); + } + if(Nbf < 2) return Standard_False; +// Modified by Sergey KHROMOV - Tue Dec 18 18:10:40 2001 Begin +// if (BRep_Tool::Continuity(Ec,F[0],F[1]) < GeomAbs_G1) { + if (!isTangentFaces(Ec,F[0],F[1])) { +// Modified by Sergey KHROMOV - Tue Dec 18 18:10:41 2001 End + return Standard_False; + } + } + } + return Standard_True; + +} + + +//======================================================================= +//function : TangentExtremity +//purpose : Test if 2 faces are tangent at the end of an edge +//======================================================================= +static Standard_Boolean TangentExtremity(const TopoDS_Vertex& V, + const TopoDS_Edge& E, + const Handle(BRepAdaptor_HSurface)& hs1, + const Handle(BRepAdaptor_HSurface)& hs2, +// const Standard_Real t3d, + const Standard_Real tang) +{ + TopoDS_Face f1 = hs1->ChangeSurface().Face(); + TopAbs_Orientation O1 = f1.Orientation(); + f1.Orientation(TopAbs_FORWARD); + TopoDS_Face f2 = hs2->ChangeSurface().Face(); + TopAbs_Orientation O2 = f2.Orientation(); + f2.Orientation(TopAbs_FORWARD); + TopoDS_Edge e1 = E, e2 = E; + e1.Orientation(TopAbs_FORWARD); + e2.Orientation(TopAbs_FORWARD); + if(f1.IsSame(f2) && BRep_Tool::IsClosed(e1,f1)) + e2.Orientation(TopAbs_REVERSED); + Standard_Real p1 = BRep_Tool::Parameter(V,e1,f1); + Standard_Real p2 = BRep_Tool::Parameter(V,e2,f2); + Standard_Real u,v,f,l, Eps = 1.e-9; + gp_Vec n1, n2;// gp_Pnt pt1,pt2; + Handle(Geom2d_Curve) pc1 = BRep_Tool::CurveOnSurface(e1,f1,f,l); + pc1->Value(p1).Coord(u,v); + BRepLProp_SLProps theProp1(hs1->ChangeSurface(), u, v, 1, Eps); + if (theProp1.IsNormalDefined()) { + n1.SetXYZ(theProp1.Normal().XYZ()); + if (O1 == TopAbs_REVERSED) n1.Reverse(); + } + else return Standard_False; // It is not known... + + + Handle(Geom2d_Curve) pc2 = BRep_Tool::CurveOnSurface(e2,f2,f,l); + pc2->Value(p2).Coord(u,v); + BRepLProp_SLProps theProp2(hs2->ChangeSurface(), u, v, 1, Eps); + if (theProp2.IsNormalDefined()) { + n2.SetXYZ(theProp2.Normal().XYZ()); + if(O2 == TopAbs_REVERSED) n2.Reverse(); + } + else return Standard_False; // It is not known... + + return (n1.Angle(n2) < tang); +} + +//======================================================================= +//function : TangentOnVertex +//purpose : Test if support faces of an edge are tangent at end. +//======================================================================= +static Standard_Boolean TangentOnVertex(const TopoDS_Vertex& V, + const TopoDS_Edge& E, + const ChFiDS_Map& EFMap, + const Standard_Real tang) +{ + TopoDS_Face ff1,ff2; + ChFi3d_conexfaces(E,ff1,ff2,EFMap); + if(ff1.IsNull() || ff2.IsNull()) return 0; + Handle(BRepAdaptor_HSurface) S1 = new (BRepAdaptor_HSurface)(ff1); + Handle(BRepAdaptor_HSurface) S2 = new (BRepAdaptor_HSurface)(ff2); + return TangentExtremity(V, E, S1, S2, tang); +} + +//======================================================================= +//function : PerformExtremity +//purpose : In case if PerformElement returned BreakPoint at one or +// another extremity, it is attempted to refine +// depending on concavities between neighbour faces of the top. +//======================================================================= + +void ChFi3d_Builder::PerformExtremity (const Handle(ChFiDS_Spine)& Spine) +{ + for(Standard_Integer ii = 1; ii <= 2; ii++){ + TopoDS_Edge E[3],Ec; + TopoDS_Vertex V; + ChFiDS_State sst; + Standard_Integer iedge; + Handle(BRepAdaptor_HSurface) hs1,hs2; + if(ii == 1){ + sst = Spine->FirstStatus(); + iedge = 1; + V = Spine->FirstVertex(); + } + else{ + sst = Spine->LastStatus(); + iedge = Spine->NbEdges(); + E[0] = Spine->Edges(iedge); + V = Spine->LastVertex(); + } + //Before all it is checked if the tangency is not dead. + E[0] = Spine->Edges(iedge); + ConexFaces (Spine,iedge,0,hs1,hs2); + if(TangentExtremity(V,E[0],hs1,hs2,angular)){ + Spine->SetTangencyExtremity(Standard_True, (ii == 1)); + } + + if(sst == ChFiDS_BreakPoint){ + TopTools_ListIteratorOfListOfShape It;//,Jt; + Standard_Integer i = 0, j; + Standard_Boolean sommetpourri = Standard_False; + for (It.Initialize(myVEMap(V));It.More();It.Next()){ + Ec = TopoDS::Edge(It.Value()); + Standard_Boolean bonedge = !BRep_Tool::Degenerated(Ec); + if(bonedge){ + TopoDS_Vertex v1,v2; + TopExp::Vertices(Ec,v1,v2); + Standard_Boolean eclosed = v1.IsSame(v2); + Standard_Integer nboc = 0; + for(j = 0; j <= i && bonedge; j++){ + if(!eclosed) bonedge = !Ec.IsSame(E[j]); + else if(Ec.IsSame(E[j])){ + nboc++; + bonedge = nboc<2; + } + } + } + if(bonedge){ + if( i < 2 ){ + i++; + E[i] = Ec; + } + else{ +#ifdef DEB + cout<<"top has more than 3 edges"<<endl; +#endif + sommetpourri = Standard_True; + break; + } + } + } + if(i != 2) sommetpourri = Standard_True; + if(!sommetpourri){ + sst = ChFi3d_EdgeState(E,myEFMap); + } + if(ii==1)Spine->SetFirstStatus(sst); + else Spine->SetLastStatus(sst); + } + } + + if (!Spine->IsPeriodic()) { + TopTools_ListIteratorOfListOfShape It,Jt; + Standard_Integer nbf = 0, jf = 0; + for (It.Initialize(myVFMap(Spine->FirstVertex())); It.More(); It.Next()){ + jf++; + Standard_Integer kf = 1; + const TopoDS_Shape& cur = It.Value(); + for (Jt.Initialize(myVFMap(Spine->FirstVertex())); Jt.More() && (kf < jf); Jt.Next(), kf++){ + if(cur.IsSame(Jt.Value())) break; + } + if(kf == jf) nbf++; + } + if(nbf>3) { + Spine->SetFirstStatus(ChFiDS_BreakPoint); +#if DEB + cout<<"top has : "<<nbf<<" faces."<<endl; +#endif + } + nbf = 0, jf = 0; + for (It.Initialize(myVFMap(Spine->LastVertex())); It.More(); It.Next()){ + jf++; + Standard_Integer kf = 1; + const TopoDS_Shape& cur = It.Value(); + for (Jt.Initialize(myVFMap(Spine->LastVertex())); Jt.More() && (kf < jf); Jt.Next(), kf++){ + if(cur.IsSame(Jt.Value())) break; + } + if(kf == jf) nbf++; + } + if(nbf>3) { + Spine->SetLastStatus(ChFiDS_BreakPoint); +#if DEB + cout<<"top has : "<<nbf<<" faces."<<endl; +#endif + } + } +} + +//======================================================================= +//function : PerformElement +//purpose : find all mutually tangent edges ; +// Each edge has 2 opposing faces. For 2 adjacent tangent edges it is required that +// the opposing faces were tangent. +//======================================================================= + +Standard_Boolean ChFi3d_Builder::PerformElement(const Handle(ChFiDS_Spine)& Spine) +{ + Standard_Real ta = angular; + TopTools_ListIteratorOfListOfShape It; + Standard_Integer Nbface; + TopTools_ListIteratorOfListOfShape Jt; + Standard_Real Wl,Wf; + Standard_Boolean degeneOnEc; + gp_Pnt P2; + gp_Vec V1,V2; + TopoDS_Vertex Ve1,VStart,FVEc,LVEc,FVEv,LVEv; + TopoDS_Edge Ev,Ec(Spine->Edges(1)); + if(BRep_Tool::Degenerated(Ec)) return 0; + //it is checked if the edge is a cut edge + TopoDS_Face ff1,ff2; + ChFi3d_conexfaces(Ec,ff1,ff2,myEFMap); + if(ff1.IsNull() || ff2.IsNull()) return 0; +// Modified by Sergey KHROMOV - Fri Dec 21 17:46:22 2001 End +//if(BRep_Tool::Continuity(Ec,ff1,ff2) != GeomAbs_C0) return 0; + if (isTangentFaces(Ec,ff1,ff2)) return 0; +// Modified by Sergey KHROMOV - Fri Dec 21 17:46:24 2001 Begin + + BRepAdaptor_Curve CEc,CEv; + TopAbs_Orientation curor = Ec.Orientation(); + TopExp::Vertices(Ec,VStart,LVEc); + + + Standard_Boolean Fini = Standard_False; + Standard_Integer Nb; +#ifndef DEB + ChFiDS_State CurSt = ChFiDS_Closed; +#else + ChFiDS_State CurSt; +#endif + if (VStart.IsSame(LVEc)) {//case if only one edge is closed + CEc.Initialize(Ec); + Wl = BRep_Tool::Parameter(VStart,Ec); + CEc.D1(Wl,P2,V1); + Wl = BRep_Tool::Parameter(LVEc,Ec); + CEc.D1(Wl,P2,V2); + if (V1.IsParallel(V2,ta)) { + if (FaceTangency(Ec,Ec,VStart)) { + CurSt = ChFiDS_Closed; + } + else { + CurSt = ChFiDS_BreakPoint; + } + } + else { + CurSt = ChFiDS_BreakPoint; + } + Spine->SetLastStatus(CurSt); + Spine->SetFirstStatus(CurSt); + } + else { // Downstream progression + FVEc = VStart; + TopAbs_Orientation Or1; + while (!Fini) { + CurSt = ChFiDS_FreeBoundary; + Wl = BRep_Tool::Parameter(LVEc,Ec); + degeneOnEc = TangentOnVertex(LVEc, Ec, myEFMap, ta); + CEc.Initialize(Ec); + CEc.D1(Wl,P2,V1); + Nb = Spine->NbEdges(); + + for (It.Initialize(myVEMap(LVEc));It.More();It.Next()) { + Ev = TopoDS::Edge(It.Value()); + if (!Ev.IsSame(Ec) && !BRep_Tool::Degenerated(Ev)){ + TopExp::Vertices(Ev,FVEv,LVEv); + if (LVEc.IsSame(LVEv)) { + Ve1 = FVEv; + FVEv = LVEv; + LVEv = Ve1; + Or1 = TopAbs_REVERSED; + } + else Or1 = TopAbs_FORWARD; + + Wf = BRep_Tool::Parameter(FVEv,Ev); + CEv.Initialize(Ev); + CEv.D1(Wf,P2,V2); + Standard_Real av1v2 = V1.Angle(V2); + Standard_Boolean rev = (Or1 != curor); + Standard_Boolean OnAjoute = Standard_False; + if (FaceTangency(Ec,Ev,FVEv)) { + // there is no need of tolerance + // to make a decision (PRO9486) the regularity is enough. + // However, the abcense of turn-back is checked (PRO9810) + OnAjoute = ((!rev && av1v2 < PI/2) + ||(rev && av1v2 > PI/2)); + // mate attention to the single case (cf CTS21610_1) + if (OnAjoute && (degeneOnEc || + TangentOnVertex(LVEc, Ev,myEFMap, ta)) ) + OnAjoute=((!rev && av1v2 < ta) || (rev && (PI - av1v2) < ta)); + } + if (OnAjoute) { + Fini = Standard_False; // If this can be useful (Cf PRO14713) + Ec = Ev; +// Ec = TopoDS::Edge(Ev); + Ec.Orientation(Or1); + Wl = Wf; LVEc = LVEv; + Spine->SetEdges(Ec); + curor = Or1; + if (VStart.IsSame(LVEv)) { + if (FaceTangency(Ev,Spine->Edges(1),LVEv)) { + CurSt = ChFiDS_Closed; Fini = Standard_True; + } + else { + CurSt = ChFiDS_BreakPoint;Fini = Standard_True; + } + } + break; + } + else { + for (Jt.Initialize(myEFMap(Ev)), Nbface= 0 ;Jt.More();Jt.Next(), + Nbface++) {} + if (Nbface> 1) CurSt = ChFiDS_BreakPoint; + Fini = ((!rev && av1v2 < ta) || (rev && (PI - av1v2) < ta)); + } + } + } + Fini = Fini || (Nb == Spine->NbEdges()); + } + Spine->SetLastStatus(CurSt); + if (CurSt == ChFiDS_Closed) { + Spine->SetFirstStatus(CurSt); + } + else {// Upstream progression + Fini = Standard_False; + Ec = Spine->Edges(1); + curor = Ec.Orientation(); + FVEc = VStart; + while (!Fini) { + CurSt = ChFiDS_FreeBoundary; + Wl = BRep_Tool::Parameter(FVEc,Ec); + degeneOnEc = TangentOnVertex(FVEc, Ec, myEFMap, ta); + CEc.Initialize(Ec); + CEc.D1(Wl,P2,V1); + Nb = Spine->NbEdges(); + + for (It.Initialize(myVEMap(FVEc));It.More();It.Next()) { + Ev = TopoDS::Edge(It.Value()); + if (!Ev.IsSame(Ec) && !BRep_Tool::Degenerated(Ev)) { + TopExp::Vertices(Ev,FVEv,LVEv); + if (FVEc.IsSame(FVEv)) { + Ve1 = FVEv; + FVEv = LVEv; + LVEv = Ve1; + Or1 = TopAbs_REVERSED; + } + else { + Or1 = TopAbs_FORWARD; + } + Wf = BRep_Tool::Parameter(LVEv,Ev); + CEv.Initialize(Ev); + CEv.D1(Wf,P2,V2); + Standard_Real av1v2 = V1.Angle(V2); + Standard_Boolean rev = (Or1 != curor); + Standard_Boolean OnAjoute = Standard_False; + if (FaceTangency(Ec,Ev,LVEv)) { + OnAjoute = ((!rev && av1v2 < PI/2) + ||(rev && av1v2 > PI/2)); + if (OnAjoute && (degeneOnEc || + TangentOnVertex(FVEc, Ev,myEFMap, ta)) ) + OnAjoute=((!rev && av1v2 < ta) || (rev && (PI-av1v2) < ta)); + } + if (OnAjoute) { + Ec = Ev; +// Ec = TopoDS::Edge(Ev); + Ec.Orientation(Or1); + Wl = Wf; FVEc = FVEv; + Spine->PutInFirst(Ec); + curor = Or1; + break; + } + else { + for(Jt.Initialize(myEFMap(Ev)),Nbface= 0 ;Jt.More();Jt.Next(), + Nbface++) {} + if (Nbface> 1) CurSt = ChFiDS_BreakPoint; + Fini = ((!rev && av1v2 < ta) || (rev && (PI - av1v2) < ta)); + } + } + } + Fini = Fini || (Nb == Spine->NbEdges()); + } + Spine->SetFirstStatus(CurSt); + } + } + return 1; +} + +//======================================================================= +//function : Remove +//purpose : +//======================================================================= + +void ChFi3d_Builder::Remove(const TopoDS_Edge& E) +{ + ChFiDS_ListIteratorOfListOfStripe itel(myListStripe); + + for ( ; itel.More(); itel.Next()) { + const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine(); + for (Standard_Integer j = 1; j <= sp->NbEdges(); j++){ + if (E.IsSame(sp->Edges(j))){ + myListStripe.Remove(itel); + return; + } + } + } +} + + +//======================================================================= +//function : Value +//purpose : +//======================================================================= + +Handle(ChFiDS_Spine) ChFi3d_Builder::Value +(const Standard_Integer I)const +{ + ChFiDS_ListIteratorOfListOfStripe itel(myListStripe); + for (Standard_Integer ic = 1; ic < I; ic++) {itel.Next();} + return itel.Value()->Spine(); +} + +//======================================================================= +//function : NbElements +//purpose : +//======================================================================= + +Standard_Integer ChFi3d_Builder::NbElements()const +{ + Standard_Integer i = 0; + ChFiDS_ListIteratorOfListOfStripe itel(myListStripe); + for ( ;itel.More(); itel.Next()){ + const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine(); + if(sp.IsNull()) break; + i++; + } + return i; +} + +//======================================================================= +//function : Contains +//purpose : +//======================================================================= + +Standard_Integer ChFi3d_Builder::Contains(const TopoDS_Edge& E)const +{ + Standard_Integer i = 1,j; + ChFiDS_ListIteratorOfListOfStripe itel(myListStripe); + for ( ;itel.More(); itel.Next(), i++){ + const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine(); + if(sp.IsNull()) break; + for (j = 1; j <= sp->NbEdges(); j++){ + if(E.IsSame(sp->Edges(j))) return i; + } + } + return 0; +} + +//======================================================================= +//function : Contains +//purpose : +//======================================================================= + +Standard_Integer ChFi3d_Builder::Contains(const TopoDS_Edge& E, + Standard_Integer& IndexInSpine)const +{ + Standard_Integer i = 1,j; + IndexInSpine = 0; + ChFiDS_ListIteratorOfListOfStripe itel(myListStripe); + for ( ;itel.More(); itel.Next(), i++){ + const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine(); + if(sp.IsNull()) break; + for (j = 1; j <= sp->NbEdges(); j++){ + if(E.IsSame(sp->Edges(j))) + { + IndexInSpine = j; + return i; + } + } + } + return 0; +} + +//======================================================================= +//function : Length +//purpose : +//======================================================================= + +Standard_Real ChFi3d_Builder::Length(const Standard_Integer IC)const +{ + if(IC <= NbElements()){ + const Handle(ChFiDS_Spine)& sp = Value(IC); + return sp->LastParameter(sp->NbEdges()); + } + return -1; +} + + +//======================================================================= +//function : FirstVertex +//purpose : +//======================================================================= + +TopoDS_Vertex ChFi3d_Builder::FirstVertex(const Standard_Integer IC) const +{ + if(IC <= NbElements()){ + return Value(IC)->FirstVertex(); + } + return TopoDS_Vertex(); +} + +//======================================================================= +//function : LastVertex +//purpose : +//======================================================================= + +TopoDS_Vertex ChFi3d_Builder::LastVertex(const Standard_Integer IC) const +{ + if(IC <= NbElements()){ + return Value(IC)->LastVertex(); + } + return TopoDS_Vertex(); +} + +//======================================================================= +//function : Abscissa +//purpose : +//======================================================================= + +Standard_Real ChFi3d_Builder::Abscissa(const Standard_Integer IC, + const TopoDS_Vertex& V) const +{ + if(IC <= NbElements()){ + return Value(IC)->Absc(V); + } + return -1; +} + +//======================================================================= +//function : RelativeAbscissa +//purpose : +//======================================================================= + +Standard_Real ChFi3d_Builder::RelativeAbscissa(const Standard_Integer IC, + const TopoDS_Vertex& V) const +{ + if(IC <= NbElements()){ + return Abscissa(IC,V)/Length(IC); + } + return -1; +} + +//======================================================================= +//function : Closed +//purpose : +//======================================================================= + +Standard_Boolean ChFi3d_Builder::Closed(const Standard_Integer IC)const +{ + if(IC <= NbElements()){ + return Value(IC)->IsClosed(); + } + return Standard_False; +} + +//======================================================================= +//function : ClosedAndTangent +//purpose : +//======================================================================= + +Standard_Boolean ChFi3d_Builder::ClosedAndTangent +(const Standard_Integer IC)const +{ + if(IC <= NbElements()){ + return Value(IC)->IsPeriodic(); + } + return Standard_False; +} + diff --git a/src/ChFi3d/ChFi3d_Builder_2.cxx b/src/ChFi3d/ChFi3d_Builder_2.cxx new file mode 100644 index 00000000..17e9a240 --- /dev/null +++ b/src/ChFi3d/ChFi3d_Builder_2.cxx @@ -0,0 +1,2985 @@ +// File: ChFi3d_Builder_2.cxx +// Created: Wed Dec 15 11:03:27 1993 +// Author: Isabelle GRIGNON +// <isg@zerox> + +#include <ChFi3d_Builder.jxx> + +#include <Precision.hxx> + +#include <Standard_NotImplemented.hxx> +#include <TColStd_Array1OfReal.hxx> +#include <TColStd_Array1OfInteger.hxx> +#include <TColStd_ListOfInteger.hxx> + +#include <math_Vector.hxx> +#include <gp_Pnt.hxx> +#include <gp_XYZ.hxx> +#include <gp_Vec.hxx> +#include <gp_Pnt2d.hxx> +#include <gp_Pln.hxx> +#include <TColgp_Array1OfPnt.hxx> +#include <TColgp_Array1OfVec.hxx> +#include <ElCLib.hxx> + +#include <Geom_BSplineCurve.hxx> +#include <Geom_Line.hxx> +#include <Geom_Plane.hxx> +#include <Geom2d_Curve.hxx> +#include <GeomAPI_ProjectPointOnCurve.hxx> + +#include <TopoDS.hxx> +#include <TopoDS_Shape.hxx> +#include <TopoDS_Face.hxx> +#include <TopoDS_Wire.hxx> +#include <TopoDS_Edge.hxx> +#include <TopoDS_Vertex.hxx> + +#include <GeomAdaptor_Surface.hxx> +#include <GeomAdaptor_HSurface.hxx> +#include <GeomAdaptor_HCurve.hxx> + +#include <BRepAdaptor_Curve.hxx> +#include <BRepAdaptor_HCurve.hxx> +#include <BRepAdaptor_Surface.hxx> +#include <BRepAdaptor_HSurface.hxx> +#include <BRepTopAdaptor_TopolTool.hxx> +#include <BRepLProp_SLProps.hxx> +#include <Adaptor3d_TopolTool.hxx> + +#include <TopAbs.hxx> +#include <TopAbs_ShapeEnum.hxx> +#include <TopAbs_Orientation.hxx> +#include <BRep_Tool.hxx> +#include <BRepTools.hxx> +#include <BRepTools_WireExplorer.hxx> +#include <BRepLib_MakeFace.hxx> +#include <TopExp.hxx> +#include <TopExp_Explorer.hxx> +#include <TopTools_ListIteratorOfListOfShape.hxx> + +#include <Extrema_ExtPC.hxx> +#include <Extrema_LocateExtPC.hxx> +#include <Extrema_POnCurv.hxx> + +#include <ChFiDS_ErrorStatus.hxx> +#include <ChFiDS_State.hxx> +#include <ChFiDS_SurfData.hxx> +#include <ChFiDS_CommonPoint.hxx> +#include <ChFiDS_FaceInterference.hxx> +#include <ChFiDS_Spine.hxx> +#include <ChFiDS_FilSpine.hxx> +#include <ChFiDS_ChamfSpine.hxx> +#include <ChFiDS_SequenceOfSurfData.hxx> +#include <ChFiDS_Stripe.hxx> +#include <ChFiDS_HData.hxx> +#include <ChFiDS_ElSpine.hxx> +#include <ChFiDS_ListOfHElSpine.hxx> +#include <ChFiDS_ListIteratorOfListOfHElSpine.hxx> +#include <Extrema_ExtPS.hxx> +#include <ChFiKPart_ComputeData.hxx> +#include <ChFi3d.hxx> +#include <ChFi3d_Builder_0.hxx> + +#ifdef DEB +#ifdef DRAW +#include <DrawTrSurf.hxx> +#endif +#include <OSD_Chronometer.hxx> +//Standard_IMPORT extern Standard_Real t_perfsetofkpart,t_perfsetofkgen, +Standard_IMPORT Standard_Real t_perfsetofkpart,t_perfsetofkgen, +t_makextremities,t_performsurf,t_startsol; +//Standard_IMPORT extern Standard_Boolean ChFi3d_GettraceCHRON(); +Standard_IMPORT Standard_Boolean ChFi3d_GettraceCHRON(); +//Standard_IMPORT extern void ChFi3d_InitChron(OSD_Chronometer& ch); +Standard_IMPORT void ChFi3d_InitChron(OSD_Chronometer& ch); +//Standard_IMPORT extern void ChFi3d_ResultChron(OSD_Chronometer & ch, +Standard_IMPORT void ChFi3d_ResultChron(OSD_Chronometer & ch, + Standard_Real& time); +#endif + +// Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 Begin +Standard_Boolean isTangentFaces(const TopoDS_Edge &theEdge, + const TopoDS_Face &theFace1, + const TopoDS_Face &theFace2); +// Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 End + +//=================================================================== +// Definition by a plane +// +// It is considered that P1 and P2 are points associated to commonpoints compoint1 and +// compoint2, while E1 and E2 are edges containing P1 and P2. +// The plane containing three directions D12 T1 T2 ou D12 represente la direction formee +// par les points P1 et P2, T1 la tangente de E1 en P1 et T2 la tangente de +// E2 en P2 is found (if exists). +// Then fillet HConge is intersected by this plane +// to find associated curve 3d C3d and the curve 2d. +// +//==================================================================== +static void ChFi3d_CoupeParPlan (const ChFiDS_CommonPoint & compoint1, + const ChFiDS_CommonPoint & compoint2, + Handle(GeomAdaptor_HSurface)& HConge, + const gp_Pnt2d & UV1, + const gp_Pnt2d & UV2, + const Standard_Real tol3d, + const Standard_Real tol2d, + Handle(Geom_Curve) &C3d, + Handle(Geom2d_Curve) &pcurve, + Standard_Real & tolreached, + Standard_Real & Pardeb, + Standard_Real & Parfin, + Standard_Boolean & plane) +{ plane=Standard_True; + if(compoint1.IsOnArc() && compoint2.IsOnArc() ) { + gp_Pnt P1,P2; + BRepAdaptor_Curve BCurv1(compoint1.Arc()); + BRepAdaptor_Curve BCurv2(compoint2.Arc()); + Standard_Real parE1,parE2; + parE1=compoint1.ParameterOnArc(); + parE2=compoint2.ParameterOnArc(); + gp_Vec t1,t2; + BCurv1.D1(parE1,P1,t1); + BCurv2.D1(parE2,P2,t2); + gp_Dir tgt1(t1); + gp_Dir tgt2(t2); + gp_Vec v12(P2.X()-P1.X(),P2.Y()-P1.Y(),P2.Z()-P1.Z()); + gp_Dir d12(v12); + gp_Dir nor =tgt1.Crossed(d12); + Handle (Geom_Plane) Plan=new Geom_Plane(P1,nor); + Standard_Real scal; + scal=Abs(nor.Dot(tgt2)); + if (scal<0.01) { + Handle(GeomAdaptor_HSurface) HPlan=new GeomAdaptor_HSurface(Plan); + Handle(Geom2d_Curve) C2dint2; + TColStd_Array1OfReal Pdeb(1,4),Pfin(1,4); + GeomAdaptor_Surface AS(Plan); + Extrema_ExtPS ext(P1,AS,1.e-3,1.e-3); + Extrema_ExtPS ext1 (P2,AS,1.e-3,1.e-3); + Standard_Real u1,v1; + ext.Point(1).Parameter(u1,v1); + Pdeb(1)= UV1.X();Pdeb(2) = UV1.Y(); + Pdeb(3)= u1;Pdeb(4) =v1; + ext1.Point(1).Parameter(u1,v1); + Pfin(1)= UV2.X();Pfin(2) = UV2.Y(); + Pfin(3)= u1;Pfin(4) = v1; + if (ChFi3d_ComputeCurves(HConge,HPlan,Pdeb,Pfin,C3d, + pcurve,C2dint2,tol3d,tol2d,tolreached)){ + Pardeb=C3d->FirstParameter(); + Parfin=C3d->LastParameter(); + } + else plane=Standard_False; + } + else plane=Standard_False; + } + else plane=Standard_False; +} +//======================================================================= +//function : SortieTangente +//purpose : +//======================================================================= + +static Standard_Boolean SortieTangente(const ChFiDS_CommonPoint& CP, + const TopoDS_Face& /*F*/, + const Handle(ChFiDS_SurfData)& /*SD*/, + const Standard_Integer /*OnS*/, + const Standard_Real TolAngular) +{ + if(!CP.HasVector()) return Standard_False; + gp_Pnt P; + gp_Vec Darc, Dsurf; + Handle(Geom_Curve) C; + Standard_Real Uf, Ul; + C = BRep_Tool::Curve(CP.Arc(),Uf,Ul); + C->D1(CP.ParameterOnArc(), P, Darc); + Dsurf = CP.Vector(); + return Dsurf.IsParallel(Darc, TolAngular); +} + +//======================================================================= +//function : BonVoisin +//purpose : +//======================================================================= + +static Standard_Boolean BonVoisin(const gp_Pnt& Point, + Handle(BRepAdaptor_HSurface)& HS, + TopoDS_Face& F, + Handle(GeomAdaptor_HSurface)& plane, + const TopoDS_Edge& cured, + Standard_Real& XDep, + Standard_Real& YDep, + const ChFiDS_Map& EFMap, + const Standard_Real tolesp) +{ + Standard_Boolean bonvoisin = 1; + Standard_Real winter, Uf, Ul; + gp_Pnt papp = HS->Value(XDep, YDep); + Standard_Real dist = RealLast(); + Handle(BRepAdaptor_HCurve) hc = new BRepAdaptor_HCurve(); + Handle(Geom2d_Curve) PC; + Standard_Boolean found = 0; + + TopExp_Explorer Ex; + for(Ex.Init(F,TopAbs_EDGE); Ex.More(); Ex.Next()){ + const TopoDS_Edge& ecur = TopoDS::Edge(Ex.Current()); + if(!ecur.IsSame(cured)){ + hc->ChangeCurve().Initialize(ecur); + Standard_Real tolc = hc->ChangeCurve().Resolution(tolesp); + if(ChFi3d_InterPlaneEdge(plane,hc,winter,1,tolc)){ + gp_Pnt np = hc->Value(winter); + Standard_Real ndist = np.SquareDistance(papp); + if(ndist<dist){ + TopTools_ListIteratorOfListOfShape It; + TopoDS_Face ff; + Standard_Boolean isclosed = BRep_Tool::IsClosed(ecur, F); + Standard_Boolean isreallyclosed = + BRepTools::IsReallyClosed(ecur, F); + for(It.Initialize(EFMap(ecur));It.More();It.Next()){ + ff = TopoDS::Face(It.Value()); + Standard_Boolean issame = ff.IsSame(F); +// Modified by Sergey KHROMOV - Fri Dec 21 17:12:48 2001 Begin +// Standard_Boolean istg = +// BRep_Tool::Continuity(ecur,ff,F) != GeomAbs_C0; + Standard_Boolean istg = isTangentFaces(ecur,ff,F); +// Modified by Sergey KHROMOV - Fri Dec 21 17:12:51 2001 End + if((!issame || (issame && isreallyclosed)) && istg) { + found = 1; + TopoDS_Edge newe = ecur; + newe.Orientation(TopAbs_FORWARD); + dist = ndist; + HS->ChangeSurface().Initialize(ff); + if(isclosed && !isreallyclosed){ + TopoDS_Face fff = ff; + fff.Orientation(TopAbs_FORWARD); + TopExp_Explorer Ex2; + for(Ex2.Init(fff,TopAbs_EDGE); + Ex2.More(); Ex2.Next()){ + if(newe.IsSame(Ex2.Current())){ + newe = TopoDS::Edge(Ex2.Current()); + PC = BRep_Tool::CurveOnSurface(newe,fff,Uf,Ul); + break; + } + } + } + else PC = BRep_Tool::CurveOnSurface(newe,ff,Uf,Ul); + PC->Value(winter).Coord(XDep,YDep); + if(issame){ + gp_Pnt spt; gp_Vec sdu,sdv,nors; + HS->D1(XDep, YDep, spt, sdu, sdv); + nors = sdu.Crossed(sdv); + gp_Pnt cpt; gp_Vec cd; + hc->D1(winter,cpt,cd); + gp_Vec vref(Point, cpt); + TopoDS_Face fff = ff; + fff.Orientation(TopAbs_FORWARD); + if(vref.Dot(nors.Crossed(cd)) < 0.){ + newe.Orientation(TopAbs_REVERSED); + } + PC = BRep_Tool::CurveOnSurface(newe,fff,Uf,Ul); + PC->Value(winter).Coord(XDep, YDep); + } + break; + } + } + } + } + } + } + if(!found) bonvoisin = 0; + return bonvoisin; +} + +//======================================================================= +//function : Projection +//purpose : Projects a point on a curve +//======================================================================= + +static Standard_Boolean Projection(Extrema_ExtPC& PExt, + const gp_Pnt& P, + const Adaptor3d_Curve& C, + Standard_Real& W, + Standard_Real Tol) +{ + Standard_Real Dist2, daux2; + Dist2 = C.Value(W).SquareDistance(P); + + // It is checked if it is not already a solution + if (Dist2 < Tol * Tol) + return Standard_True; + + Standard_Boolean Ok = Standard_False; + + // On essai une resolution initialise + Extrema_LocateExtPC ext(P,C,W,Tol/10); + if(ext.IsDone()) { + daux2 = C.Value(ext.Point().Parameter()).SquareDistance(P); + if (daux2 <Dist2 ) { + W = ext.Point().Parameter(); + Dist2 = daux2; + Ok = Standard_True; + if (Dist2 < Tol * Tol) + return Standard_True; + } + } + + // Global resolution + PExt.Perform(P); + if ( PExt.IsDone() ) { + for (Standard_Integer ii=1; ii<= PExt.NbExt(); ii++) { + if (PExt.SquareDistance(ii) < Dist2) { + Dist2 = PExt.SquareDistance(ii); + W = PExt.Point(ii).Parameter(); + Ok = Standard_True; + } + } + } + return Ok; +} + +//======================================================================= +//function : TgtKP +//purpose : +//======================================================================= + +static void TgtKP(const Handle(ChFiDS_SurfData)& CD, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer iedge, + const Standard_Boolean isfirst, + gp_Pnt& ped, + gp_Vec& ded) +{ + Standard_Real wtg = CD->InterferenceOnS1().Parameter(isfirst); + const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(iedge); + if(Spine->Edges(iedge).Orientation() == TopAbs_FORWARD) + bc.D1(wtg+bc.FirstParameter(),ped,ded); + else{ + bc.D1(-wtg+bc.LastParameter(),ped,ded); + ded.Reverse(); + } + ded.Normalize(); +} + +//======================================================================= +//function : IsInput +//purpose : Checks if a vector belongs to a Face +//======================================================================= + +Standard_Boolean IsInput(const gp_Vec& Vec, + const TopoDS_Vertex& Ve, + const TopoDS_Face& Fa) +{ + TopExp_Explorer FaceExp(Fa, TopAbs_WIRE); + BRepTools_WireExplorer WireExp; + Standard_Integer Trouve = 0; + TopoDS_Wire W; + TopoDS_Edge E; + TopoDS_Vertex Vf, Vl; + gp_Vec Vec3d[2]; + gp_Pnt Point; + + // Find edges and compute 3D vectors + for ( ; (FaceExp.More() && (Trouve<2)); FaceExp.Next()) { + W = TopoDS::Wire(FaceExp.Current()); + for (Trouve=0, WireExp.Init(W) ; + WireExp.More() && (Trouve<2); WireExp.Next()) { + E = TopoDS::Edge(WireExp.Current()); + TopExp::Vertices(E, Vf, Vl); + if (Vf.IsSame(Ve)) { + BRepAdaptor_Curve Cb(E); + Cb.D1(BRep_Tool::Parameter(Ve, E), Point, Vec3d[Trouve]); + Trouve++; + } + else if (Vl.IsSame(Ve)) { + BRepAdaptor_Curve Cb(E); + Cb.D1(BRep_Tool::Parameter(Ve, E), Point, Vec3d[Trouve]); + Vec3d[Trouve].Reverse(); + Trouve++; + } + } + } + if (Trouve < 2) return Standard_False; + // Calculate the normal and the angles in the asssociated vector plane + gp_Vec Normal; + Normal = Vec3d[0] ^ Vec3d[1]; + if (Normal.SquareMagnitude() < Precision::Confusion()) {//Colinear case + return (Vec.IsParallel(Vec3d[0],Precision::Confusion())); + } + + Standard_Real amin, amax; + amax = Vec3d[1].AngleWithRef(Vec3d[0], Normal); + if (amax <0) { + amin = amax; + amax = 0; + } + else amin = 0; + + // Projection of the vector + gp_Ax3 Axe(Point, Normal, Vec3d[0]); + gp_Trsf Transf; + Transf.SetTransformation (Axe); + gp_XYZ coord = Vec.XYZ(); + Transf.Transforms(coord); + coord.SetZ(0); + Transf.Invert(); + Transf.Transforms(coord); + gp_Vec theProj(coord); + + // and finally... + Standard_Real Angle = theProj.AngleWithRef(Vec3d[0], Normal); + return ( (Angle >= amin) && (Angle<=amax)); +} + +//======================================================================= +//function : IsG1 +//purpose : Find a neighbor G1 by an edge +//======================================================================= + +Standard_Boolean IsG1(const ChFiDS_Map& TheMap, + const TopoDS_Edge& E, + const TopoDS_Face& FRef, + TopoDS_Face& FVoi) +{ + TopTools_ListIteratorOfListOfShape It; + // Find a neighbor of E different from FRef (general case). + for(It.Initialize(TheMap(E));It.More();It.Next()) { + if (!TopoDS::Face(It.Value()).IsSame(FRef)) { + FVoi = TopoDS::Face(It.Value()); +// Modified by Sergey KHROMOV - Fri Dec 21 17:09:32 2001 Begin +// if (BRep_Tool::Continuity(E,FRef,FVoi) != GeomAbs_C0) { + if (isTangentFaces(E,FRef,FVoi)) { +// Modified by Sergey KHROMOV - Fri Dec 21 17:09:33 2001 End + return Standard_True; + } + } + } + // If is was not found it is checked if E is a cutting edge, + // in which case FVoi = FRef is returned (less frequent case). + TopExp_Explorer Ex; + Standard_Boolean orset = Standard_False; +#ifndef DEB + TopAbs_Orientation orient = TopAbs_FORWARD ; +#else + TopAbs_Orientation orient; +#endif + TopoDS_Edge ed; + for(Ex.Init(FRef,TopAbs_EDGE); Ex.More(); Ex.Next()){ + ed = TopoDS::Edge(Ex.Current()); + if(ed.IsSame(E)){ + if(!orset){ orient = ed.Orientation(); orset = Standard_True; } + else if(ed.Orientation() == TopAbs::Reverse(orient)){ + FVoi = FRef; +// Modified by Sergey KHROMOV - Fri Dec 21 17:15:12 2001 Begin +// if (BRep_Tool::Continuity(E,FRef,FRef) >= GeomAbs_G1) { + if (isTangentFaces(E,FRef,FRef)) { +// Modified by Sergey KHROMOV - Fri Dec 21 17:15:16 2001 End + return Standard_True; + } + return Standard_False; + } + } + } + return Standard_False; +} + +//======================================================================= +//function : SearchFaceOnV +//purpose : Finds the output face(s) of the path by a vertex +// The following criteria should be followed +// -1 : The face shares regular edges with FRef +// (too hard condition that should be reconsidered) +// -2 : The vector starting in CommonPoint "belongs" to the face +//======================================================================== +static Standard_Integer SearchFaceOnV(const ChFiDS_CommonPoint& Pc, + const TopoDS_Face& FRef, + const ChFiDS_Map& VEMap, + const ChFiDS_Map& EFMap, + TopoDS_Face& F1, + TopoDS_Face& F2) +{ + // it is checked that it leaves the current face. + Standard_Boolean FindFace = IsInput(Pc.Vector(), Pc.Vertex(), FRef); + if (FindFace) { + FindFace = IsInput(Pc.Vector().Reversed(), Pc.Vertex(), FRef); + } + // If it does not leave, it is finished + if (FindFace) { + F1 = FRef; + return 1; + } + Standard_Integer Num = 0; + Standard_Boolean Trouve; + TopTools_ListIteratorOfListOfShape ItE, ItF; + TopoDS_Edge E; + TopoDS_Face FVoi; + + for(ItE.Initialize(VEMap(Pc.Vertex())); + ItE.More() && (Num < 2); ItE.Next()) { + E = TopoDS::Edge(ItE.Value()); + for(ItF.Initialize(EFMap(E)), Trouve=Standard_False; + ItF.More()&&(!Trouve); ItF.Next()) { + if (TopoDS::Face(ItF.Value()).IsSame(FRef)) { + Trouve = Standard_True; + } + } + if (Trouve) Trouve = IsG1(EFMap, E, FRef, FVoi); + if (Trouve) Trouve = IsInput(Pc.Vector(), Pc.Vertex(), FVoi); + if (Trouve) { + if (Num == 0) F1 = FVoi; + else F2 = FVoi; + Num++; + } + } + return Num; +} + +//======================================================================= +//function : ChangeTransition +//purpose : Changes the transition of the second common Point, when the surface +// does not cross the arc +// As it is supposed that the support Faces are the same, it is enough +// to examine the cas of cutting edges. +//======================================================================== +static void ChangeTransition(const ChFiDS_CommonPoint& Precedant, + ChFiDS_CommonPoint& Courant, + Standard_Integer FaceIndex, + const Handle(TopOpeBRepDS_HDataStructure)& DS) +{ + Standard_Boolean tochange = Standard_True; + Standard_Real f,l; + const TopoDS_Face& F = TopoDS::Face(DS->Shape(FaceIndex)); + const TopoDS_Edge& Arc = Precedant.Arc(); + Handle(Geom2d_Curve) PCurve1, PCurve2; + PCurve1 = BRep_Tool::CurveOnSurface(Arc, F, f, l); + TopoDS_Shape aLocalShape = Arc.Reversed(); + PCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape), F, f, l); +// PCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(Arc.Reversed()), F, f, l); + if (PCurve1 != PCurve2) { + // This is a cutting edge, it is necessary to make a small Geometric test + gp_Vec tgarc; + gp_Pnt P; + BRepAdaptor_Curve AC(Arc); + AC.D1(Precedant.ParameterOnArc(), P, tgarc); + tochange = tgarc.IsParallel(Precedant.Vector(), Precision::Confusion()); + } + + if (tochange) + Courant.SetArc(Precision::Confusion(), + Arc, + Precedant.ParameterOnArc(), + TopAbs::Reverse(Precedant.TransitionOnArc())); + +} + +//======================================================================= +//function : CallPerformSurf +//purpose : Encapsulates call to PerformSurf/SimulSurf +//======================================================================== + +void ChFi3d_Builder:: +CallPerformSurf(Handle(ChFiDS_Stripe)& Stripe, + const Standard_Boolean Simul, + ChFiDS_SequenceOfSurfData& SeqSD, + Handle(ChFiDS_SurfData)& SD, + const Handle(ChFiDS_HElSpine)& HGuide, + const Handle(ChFiDS_Spine)& Spine, + const Handle(BRepAdaptor_HSurface)& HS1, + const Handle(BRepAdaptor_HSurface)& HS3, + const gp_Pnt2d& pp1, + const gp_Pnt2d& pp3, + Handle(Adaptor3d_TopolTool)& It1, + const Handle(BRepAdaptor_HSurface)& HS2, + const Handle(BRepAdaptor_HSurface)& HS4, + const gp_Pnt2d& pp2, + const gp_Pnt2d& pp4, + Handle(Adaptor3d_TopolTool)& It2, + const Standard_Real MaxStep, + const Standard_Real Fleche, + const Standard_Real /*TolGuide*/, + Standard_Real& First, + Standard_Real& Last, + const Standard_Boolean Inside, + const Standard_Boolean /*Appro*/, + const Standard_Boolean forward, + const Standard_Boolean RecOnS1, + const Standard_Boolean RecOnS2, + math_Vector& Soldep, + Standard_Boolean& intf, + Standard_Boolean& intl, + Handle(BRepAdaptor_HSurface)& Surf1, + Handle(BRepAdaptor_HSurface)& Surf2) +{ +#ifdef DEB + OSD_Chronometer ch1; +#endif + Handle(BRepAdaptor_HSurface) HSon1, HSon2; + HSon1 = HS1; + HSon2 = HS2; + // Definition of the domain of path It1, It2 + It1->Initialize(HS1); + It2->Initialize(HS2); + + + TopAbs_Orientation Or1 = HS1->ChangeSurface().Face().Orientation(); + TopAbs_Orientation Or2 = HS2->ChangeSurface().Face().Orientation(); + Standard_Integer Choix = + ChFi3d::NextSide(Or1,Or2, + Stripe->OrientationOnFace1(), + Stripe->OrientationOnFace2(), + Stripe->Choix()); + Soldep(1) = pp1.X(); Soldep(2) = pp1.Y(); + Soldep(3) = pp2.X(); Soldep(4) = pp2.Y(); + + Standard_Real thef = First, thel = Last; + Standard_Boolean isdone; + + if(Simul){ + isdone = SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,HS2,It2,tolesp,First,Last, + Inside,Inside,forward,RecOnS1,RecOnS2,Soldep,intf,intl); + } + else{ + +#ifdef DEB + ChFi3d_InitChron(ch1);//initial perform for PerformSurf +#endif + + isdone = PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,HS2,It2, + MaxStep,Fleche,tolesp, + First,Last,Inside,Inside,forward, + RecOnS1,RecOnS2,Soldep,intf,intl); +#ifdef DEB + ChFi3d_ResultChron(ch1,t_performsurf);// result perf for PerformSurf +#endif + } + + // Case of error + if (!isdone) { + First = thef; + Last = thel; + Standard_Boolean reprise = Standard_False; + if (! HS3.IsNull()) { + HSon1 = HS3; + It1->Initialize(HS3); + Or1 = HS3->ChangeSurface().Face().Orientation(); + Soldep(1) = pp3.X(); Soldep(2) = pp3.Y(); + reprise = Standard_True; + } + else if (! HS4.IsNull()) { + HSon2 = HS4; + It2->Initialize(HS4); + Or2 = HS4->ChangeSurface().Face().Orientation(); + Soldep(3) = pp4.X(); Soldep(4) = pp4.Y(); + reprise = Standard_True; + } + + if (reprise) { + Choix = ChFi3d::NextSide(Or1,Or2, + Stripe->OrientationOnFace1(), + Stripe->OrientationOnFace2(), + Stripe->Choix()); + if(Simul){ + isdone = SimulSurf(SD,HGuide,Spine,Choix,HSon1,It1,HSon2,It2, + tolesp,First,Last, + Inside,Inside,forward,RecOnS1,RecOnS2, + Soldep,intf,intl); + } + else{ + +#ifdef DEB + ChFi3d_InitChron(ch1);//init perf for PerformSurf +#endif + + isdone = PerformSurf(SeqSD,HGuide,Spine,Choix,HSon1,It1,HSon2,It2, + MaxStep,Fleche,tolesp, + First,Last,Inside,Inside,forward, + RecOnS1,RecOnS2,Soldep,intf,intl); +#ifdef DEB + ChFi3d_ResultChron(ch1,t_performsurf);// result perf for PerformSurf +#endif + } + } + } + Surf1 = HSon1; + Surf2 = HSon2; +} + +//======================================================================= +//function : StripeOrientation +//purpose : Calculates the reference orientation determining the +// concave face for construction of the fillet. +//======================================================================= + +Standard_Boolean ChFi3d_Builder::StripeOrientations +(const Handle(ChFiDS_Spine)& Spine, + TopAbs_Orientation& Or1, + TopAbs_Orientation& Or2, + Standard_Integer& ChoixConge) const +{ + //TopTools_ListIteratorOfListOfShape It; + BRepAdaptor_Surface Sb1,Sb2; + TopAbs_Orientation Of1,Of2; + TopoDS_Face ff1,ff2; + ChFi3d_conexfaces(Spine->Edges(1),ff1,ff2,myEFMap); + Of1 = ff1.Orientation(); + ff1.Orientation(TopAbs_FORWARD); + Sb1.Initialize(ff1); + Of2 = ff2.Orientation(); + ff2.Orientation(TopAbs_FORWARD); + Sb2.Initialize(ff2); + + ChoixConge = ChFi3d::ConcaveSide(Sb1,Sb2,Spine->Edges(1), + Or1,Or2); + Or1 = TopAbs::Compose(Or1,Of1); + Or2 = TopAbs::Compose(Or2,Of2); + return Standard_True; +} + + +//======================================================================= +//function : ConexFaces +//purpose : +//======================================================================= + +void ChFi3d_Builder::ConexFaces (const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer IEdge, + const Standard_Integer RC, + Handle(BRepAdaptor_HSurface)& HS1, + Handle(BRepAdaptor_HSurface)& HS2) const +{ + if(HS1.IsNull()) HS1 = new BRepAdaptor_HSurface (); + if(HS2.IsNull()) HS2 = new BRepAdaptor_HSurface (); + BRepAdaptor_Surface& Sb1 = HS1->ChangeSurface(); + BRepAdaptor_Surface& Sb2 = HS2->ChangeSurface(); + + TopoDS_Face ff1,ff2; + ChFi3d_conexfaces(Spine->Edges(IEdge),ff1,ff2,myEFMap); + + Sb1.Initialize(ff1); + Sb2.Initialize(ff2); + + TopAbs_Orientation Or1,Or2; + Standard_Integer Choix = ChFi3d::ConcaveSide(Sb1,Sb2,Spine->Edges(IEdge), + Or1,Or2); + if (RC%2 != Choix%2) { + Sb1.Initialize(ff2); + Sb2.Initialize(ff1); + } +} + +//======================================================================= +//function : StartSol +//purpose : Calculates a starting solution : +// - one starts by parsing about ten points on the spine, +// - in case of fail one finds the solution on neighbor faces; +// section plane of edges of the adjacent face +// and identication of the face by connection to that edge. +//======================================================================= + +void ChFi3d_Builder::StartSol(const Handle(ChFiDS_Stripe)& Stripe, + const Handle(ChFiDS_HElSpine)& HGuide, + Handle(BRepAdaptor_HSurface)& HS1, + Handle(BRepAdaptor_HSurface)& HS2, + Handle(BRepTopAdaptor_TopolTool)& I1, + Handle(BRepTopAdaptor_TopolTool)& I2, + gp_Pnt2d& P1, + gp_Pnt2d& P2, + Standard_Real& First) const +{ + Handle(ChFiDS_Spine)& Spine = Stripe->ChangeSpine(); + ChFiDS_ElSpine& els = HGuide->ChangeCurve(); + Standard_Integer nbed = Spine->NbEdges(); + Standard_Integer nbessaimax = 3*nbed; + if (nbessaimax < 10) nbessaimax = 10; + Standard_Real unsurnbessaimax = 1./nbessaimax; + Standard_Real wf = 0.9981 * Spine->FirstParameter(1) + + 0.0019 * Spine->LastParameter(1); + Standard_Real wl = 0.9973 * Spine->LastParameter(nbed) + + 0.0027 * Spine->FirstParameter(nbed); + +#ifndef DEB + Standard_Real TolE = 1.0e-7; +#else + Standard_Real TolE; +#endif + BRepAdaptor_Surface AS; + + Standard_Integer nbessai; + Standard_Integer iedge = 0; + Standard_Integer RC = Stripe->Choix(); + gp_Vec2d derive; + gp_Pnt2d P2d; + TopoDS_Edge cured; + TopoDS_Face f1,f2; + TopAbs_Orientation Or1,Or2; +#ifndef DEB + Standard_Integer Choix = 0; +#else + Standard_Integer Choix; +#endif + math_Vector SolDep(1,4); + Handle(Geom2d_Curve) PC; + Extrema_ExtPC PExt; + PExt.Initialize(els, + Spine->FirstParameter(1), + Spine->LastParameter(nbed), + Precision::Confusion()); + TopAbs_State Pos1,Pos2; + for(nbessai = 0; nbessai <= nbessaimax; nbessai++){ + Standard_Real t = nbessai*unsurnbessaimax; + Standard_Real w = wf * (1. -t) + wl * t; + Standard_Integer ie = Spine->Index(w); + if(iedge != ie){ + iedge = ie; + cured = Spine->Edges(iedge); + TolE = BRep_Tool::Tolerance(cured); + ConexFaces(Spine,iedge,RC,HS1,HS2); + f1 = HS1->ChangeSurface().Face(); + f2 = HS2->ChangeSurface().Face(); + Or1 = f1.Orientation(); + Or2 = f2.Orientation(); + Choix = ChFi3d::NextSide(Or1,Or2, + Stripe->OrientationOnFace1(), + Stripe->OrientationOnFace2(), + RC); + } + + Standard_Real woned,Uf,Ul, ResU, ResV; + Spine->Parameter(iedge,w,woned,Standard_True); + cured.Orientation(TopAbs_FORWARD); + TopoDS_Face f1forward = f1, f2forward = f2; + f1forward.Orientation(TopAbs_FORWARD); + f2forward.Orientation(TopAbs_FORWARD); + PC = BRep_Tool::CurveOnSurface(cured,f1forward,Uf,Ul); + I1->Initialize(HS1); + PC->D1(woned, P1, derive); + // There are ponts on the border, and internal points are found + if (derive.Magnitude() > Precision::PConfusion()) { + derive.Normalized(); + derive.Rotate(PI/2); + AS.Initialize(f1); + ResU = AS.UResolution(TolE); + ResV = AS.VResolution(TolE); + derive *= 2*(Abs(derive.X())*ResU + Abs(derive.Y())*ResV); + P2d = P1.Translated(derive); + if (I1->Classify(P2d, Min(ResU, ResV), 0)== TopAbs_IN) { + P1 = P2d; + } + else { + P2d = P1.Translated(-derive); + if (I1->Classify(P2d, Min(ResU, ResV), 0)== TopAbs_IN) { + P1 = P2d; + } + } + } + if(f1.IsSame(f2)) cured.Orientation(TopAbs_REVERSED); + PC = BRep_Tool::CurveOnSurface(cured,f2forward,Uf,Ul); + P2 = PC->Value(woned); + I2->Initialize(HS2); + + SolDep(1) = P1.X(); SolDep(2) = P1.Y(); + SolDep(3) = P2.X(); SolDep(4) = P2.Y(); + const BRepAdaptor_Curve& Ced = Spine->CurrentElementarySpine(iedge); + gp_Pnt pnt = Ced.Value(woned); + + if (Projection(PExt, pnt, els, w, tolesp) && + PerformFirstSection(Spine,HGuide,Choix,HS1,HS2, + I1,I2,w,SolDep,Pos1,Pos2)) { + P1.SetCoord(SolDep(1),SolDep(2)); + P2.SetCoord(SolDep(3),SolDep(4)); + First = w; + return; + } + } + // No solution was found for the faces adjacent to the trajectory. + // Now one tries the neighbor faces. + iedge = 0; + for(nbessai = 0; nbessai <= nbessaimax; nbessai++){ + Standard_Real t = nbessai*unsurnbessaimax; + Standard_Real w = wf * (1. -t) + wl * t; + iedge = Spine->Index(w); + cured = Spine->Edges(iedge); + ConexFaces(Spine,iedge,RC,HS1,HS2); + f1 = HS1->ChangeSurface().Face(); + f2 = HS2->ChangeSurface().Face(); + Or1 = f1.Orientation(); + Or2 = f2.Orientation(); + Choix = ChFi3d::NextSide(Or1,Or2, + Stripe->OrientationOnFace1(), + Stripe->OrientationOnFace2(), + RC); + Standard_Real woned,Uf,Ul; + Spine->Parameter(iedge,w,woned,Standard_True); + TopoDS_Face f1forward = f1, f2forward = f2; + f1forward.Orientation(TopAbs_FORWARD); + f2forward.Orientation(TopAbs_FORWARD); + PC = BRep_Tool::CurveOnSurface(cured,f1forward,Uf,Ul); + P1 = PC->Value(woned); + PC = BRep_Tool::CurveOnSurface(cured,f2forward,Uf,Ul); + P2 = PC->Value(woned); + I1->Initialize(HS1); + I2->Initialize(HS2); + SolDep(1) = P1.X(); SolDep(2) = P1.Y(); + SolDep(3) = P2.X(); SolDep(4) = P2.Y(); + const BRepAdaptor_Curve& Ced = Spine->CurrentElementarySpine(iedge); + gp_Pnt pnt = Ced.Value(woned); +// Extrema_LocateExtPC ext(pnt,els,w,1.e-8); +// if(ext.IsDone()){ +// w = ext.Point().Parameter(); + if (Projection(PExt, pnt, els, w, tolesp)) { + PerformFirstSection(Spine,HGuide,Choix,HS1,HS2, + I1,I2,w,SolDep,Pos1,Pos2); + gp_Pnt P; + gp_Vec V; + HGuide->D1(w,P,V); + Handle(Geom_Plane) pl = new Geom_Plane(P,V); + Handle(GeomAdaptor_HSurface) plane = new GeomAdaptor_HSurface(pl); + + Standard_Boolean bonvoisin = 1, found = 0; + Standard_Integer NbChangement; + for (NbChangement = 1; bonvoisin && (!found) && (NbChangement < 5); + NbChangement++) { + if(Pos1 != TopAbs_IN){ + bonvoisin = BonVoisin(P, HS1, f1, plane, cured, + SolDep(1),SolDep(2), myEFMap, tolesp); + } + if(Pos2 != TopAbs_IN && bonvoisin){ + bonvoisin = BonVoisin(P, HS2, f2, plane, cured, + SolDep(3),SolDep(4), myEFMap, tolesp); + } + if(bonvoisin){ + f1 = HS1->ChangeSurface().Face(); + f2 = HS2->ChangeSurface().Face(); + Or1 = f1.Orientation(); + Or2 = f2.Orientation(); + Choix = ChFi3d::NextSide(Or1,Or2, + Stripe->OrientationOnFace1(), + Stripe->OrientationOnFace2(), + RC); + I1->Initialize(HS1); + I2->Initialize(HS2); + if(PerformFirstSection(Spine,HGuide,Choix,HS1,HS2, + I1,I2,w,SolDep,Pos1,Pos2)){ + P1.SetCoord(SolDep(1),SolDep(2)); + P2.SetCoord(SolDep(3),SolDep(4)); + First = w; + found = Standard_True; + } + } + } + if (found) return; + } + } + Spine->SetErrorStatus(ChFiDS_StartsolFailure); + Standard_Failure::Raise("StartSol echec"); +} + +//======================================================================= +//function : ChFi3d_BuildPlane +//purpose : +//======================================================================= + +static void ChFi3d_BuildPlane (TopOpeBRepDS_DataStructure& DStr, + Handle(BRepAdaptor_HSurface)& HS, + gp_Pnt2d& pons, + const Handle(ChFiDS_SurfData)& SD, + const Standard_Boolean isfirst, + const Standard_Integer ons) +{ + Handle(Geom2d_Curve) Hc; + TopoDS_Face F = TopoDS::Face(DStr.Shape(SD->Index(ons))); + Standard_Real u,v; + gp_Pnt P; + //gp_Vec V1,V2; + + if (SD->Vertex(isfirst,ons).IsOnArc()){ + Hc = BRep_Tool::CurveOnSurface + (SD->Vertex(isfirst,ons).Arc(),F,u,v); + Hc->Value(SD->Vertex(isfirst,ons).ParameterOnArc()).Coord(u,v); + BRepLProp_SLProps theProp(HS->ChangeSurface(), u, v, 1, 1.e-12); + if (theProp.IsNormalDefined()) { + P = theProp.Value(); + Handle(Geom_Plane) Pln = new Geom_Plane(P, theProp.Normal()); + TopoDS_Face NewF = BRepLib_MakeFace(Pln); + NewF.Orientation(F.Orientation()); + pons.SetCoord(0.,0.); + HS->ChangeSurface().Initialize(NewF); + return; // everything is good ! + } + } + Standard_Failure::Raise("ChFi3d_BuildPlane : echec ."); +} + +//======================================================================= +//function : StartSol +//purpose : If the commonpoint is not OnArc the input face +// is returned and 2D point is updated, +// if it is OnArc +// if it is detached the input face +// is returned and 2D point is updated, +// otherwise +// either there is a neighbor tangent face and it is returned +// with recalculated 2D point +// or if there is no face +// if the reference arc is Vref (extremity of the spine) +// this is the end and the input face is returned +// otherwise this is an obstacle and HC is updated. +//======================================================================= + +Standard_Boolean +ChFi3d_Builder::StartSol(const Handle(ChFiDS_Spine)& Spine, + Handle(BRepAdaptor_HSurface)& HS, // New face + gp_Pnt2d& pons,// " Localization + Handle(BRepAdaptor_HCurve2d)& HC, // Representation of the obstacle + Standard_Real& W, + const Handle(ChFiDS_SurfData)& SD, + const Standard_Boolean isfirst, + const Standard_Integer ons, + Handle(BRepAdaptor_HSurface)& HSref, // The other representation + Handle(BRepAdaptor_HCurve2d)& HCref, // of the obstacle + Standard_Boolean& RecP, + Standard_Boolean& RecS, + Standard_Boolean& RecRst, + Standard_Boolean& c1obstacle, + Handle(BRepAdaptor_HSurface)& HSBis, // Face of support + gp_Pnt2d& PBis, // and its point + const Standard_Boolean decroch, + const TopoDS_Vertex& Vref) const +{ + RecRst = RecS = RecP = c1obstacle = 0; + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + TopoDS_Face Fv,Fref; + //gp_Pnt2d pp1,pp2; + Handle(Geom2d_Curve) pc; + Standard_Real Uf,Ul; + + TopoDS_Face F = TopoDS::Face(DStr.Shape(SD->Index(ons))); + if(!HSref.IsNull()) Fref = HSref->ChangeSurface().Face(); + const ChFiDS_CommonPoint& CP = SD->Vertex(isfirst,ons); + HSBis.Nullify(); + + if (CP.IsOnArc()) { + Standard_Integer notons; + if (ons == 1) notons = 2; + else notons = 1; + const ChFiDS_CommonPoint& CPbis = SD->Vertex(isfirst,notons); + if (CPbis.IsOnArc()) { // It is checked if it is not the extension zone + // In case CP is not at the end of surfdata and it is not necesary to take it into account + // except for separate cases (ie pointus) ... + //ts and tns were earlier CP.Parameter() and CPbis.Parameter, but sometimes they had no values. + Standard_Real ts=SD->Interference(ons).Parameter(isfirst), tns=SD->Interference(notons).Parameter(isfirst); + Standard_Boolean isExtend; + // Arbitrary test (to precise) + if (isfirst) isExtend = (ts-tns > 100*tolesp); + else isExtend = (tns-ts > 100*tolesp); + if (isExtend && !CP.Point().IsEqual(CPbis.Point(), 0) ) { + // the state is preserved and False is returned (extension by the expected plane). + HS->ChangeSurface().Initialize(F); + pc = SD->Interference(ons).PCurveOnFace(); + // The 2nd point is given by its trace on the support surface + RecS = Standard_False; + pons = pc->Value(tns); + return Standard_False; + } + } + } + + if (CP.IsVertex() && !HC.IsNull() && !decroch){ + //The edge is changed, the parameter is updated and + //eventually the support face and(or) the reference face. + TopoDS_Vertex VCP = CP.Vertex(); + TopoDS_Edge EHC = HC->ChangeCurve2d().Edge(); + //One starts by searching in Fref another edge referencing VCP. + TopExp_Explorer ex1,ex2; + TopoDS_Edge newedge, edgereg; + TopoDS_Face bidface = Fref, facereg; + bidface.Orientation(TopAbs_FORWARD); + for(ex1.Init(bidface,TopAbs_EDGE); ex1.More(); ex1.Next()){ + const TopoDS_Edge& cured = TopoDS::Edge(ex1.Current()); + Standard_Boolean found = 0; + if(!cured.IsSame(EHC)){ + for(ex2.Init(cured,TopAbs_VERTEX); ex2.More() && !found; ex2.Next()){ + if(ex2.Current().IsSame(VCP)){ + if(IsG1(myEFMap,cured,Fref,Fv)){ + edgereg = cured; + facereg = Fv; + } + else found = 1; + } + } + } + if(found) { + newedge = cured; + break; + } + } + if(newedge.IsNull()){ + //It is checked if EHC is not a closed edge. + TopoDS_Vertex V1,V2; + TopExp::Vertices(EHC,V1,V2); + if(V1.IsSame(V2)){ + newedge = EHC; + Standard_Real w1 = BRep_Tool::Parameter(V1,EHC); + Standard_Real w2 = BRep_Tool::Parameter(V2,EHC); + const ChFiDS_FaceInterference& fi = SD->Interference(ons); + const Handle(Geom2d_Curve)& pcf = fi.PCurveOnFace(); + Standard_Real ww = fi.Parameter(isfirst); + + gp_Pnt2d pww; + if(!pcf.IsNull()) pww = pcf->Value(ww); + else pww = SD->Get2dPoints(isfirst,ons); + gp_Pnt2d p1 = HC->Value(w1); + gp_Pnt2d p2 = HC->Value(w2); + + if(p1.Distance(pww) > p2.Distance(pww)){ + W = w1; + pons = p1; + } + else { + W = w2; + pons = p2; + } + RecP = c1obstacle = 1; + return 1; + } + else if(!edgereg.IsNull()){ + // the reference edge and face are changed. + Fref = facereg; + HSref->ChangeSurface().Initialize(Fref); + for(ex1.Init(facereg,TopAbs_EDGE); ex1.More() && newedge.IsNull(); ex1.Next()){ + const TopoDS_Edge& cured = TopoDS::Edge(ex1.Current()); + if(!cured.IsSame(edgereg)){ + for(ex2.Init(cured,TopAbs_VERTEX); ex2.More(); ex2.Next()){ + if(ex2.Current().IsSame(VCP)){ + if(!IsG1(myEFMap,cured,Fref,Fv)){ + newedge = cured; + } + } + } + } + } + } + } + // it is necessary to find the new support face of the fillet : + // connected to FRef along the newedge. + if(newedge.IsNull()) { + Standard_Failure::Raise + ("StartSol : chain is not possible, new obstacle not found"); + } + if(IsG1(myEFMap,newedge,Fref,Fv)){ + Standard_Failure::Raise + ("StartSol : chain is not possible, config non processed"); + } + else if(Fv.IsNull()){ + Standard_Failure::Raise + ("StartSol : chain is not possible, new obstacle not found"); + } + else{ + HS->ChangeSurface().Initialize(Fv); + W = BRep_Tool::Parameter(VCP,newedge); + HCref->ChangeCurve2d().Initialize(newedge,Fref); + TopoDS_Face newface = Fv; + newface.Orientation(TopAbs_FORWARD); + TopExp_Explorer ex; + for(ex.Init(newface,TopAbs_EDGE); ex.More(); ex.Next()){ + if(ex.Current().IsSame(newedge)){ + newedge = TopoDS::Edge(ex.Current()); + break; + } + } + HC->ChangeCurve2d().Initialize(newedge,Fv); + pons = HC->Value(W); + } + RecP = c1obstacle = 1; + return 1; + } // End of Case Vertex && Obstacle + + else if (CP.IsOnArc() && !HC.IsNull() && !decroch){ + //Nothing is changed, the parameter is only updated. + W = CP.ParameterOnArc(); + c1obstacle = 1; + return 1; + } + + HC.Nullify(); + + if (CP.IsOnArc()){ + const TopoDS_Edge& E = CP.Arc(); + if(decroch){ + HS->ChangeSurface().Initialize(Fref); + W = CP.ParameterOnArc(); + pc = BRep_Tool::CurveOnSurface(E,Fref,Uf,Ul); + pons = pc->Value(W); + RecS = 1; + return 1; + } + if (SearchFace(Spine,CP,F,Fv)){ + HS->ChangeSurface().Initialize(Fv); + RecS = 1; + if (CP.IsVertex()) { + // One goes directly by the Vertex + Standard_Integer Nb; + TopoDS_Face aux; + // And it is checked that there are no other candidates + Nb = SearchFaceOnV(CP, F, myVEMap, myEFMap, Fv, aux); + + pons = BRep_Tool::Parameters(CP.Vertex(), Fv); + HS->ChangeSurface().Initialize(Fv); + if (Nb >=2) { + HSBis = new (BRepAdaptor_HSurface)(aux); + PBis = BRep_Tool::Parameters(CP.Vertex(), aux); + } + return 1; + } + // otherwise one passes by the arc... + if(!Fv.IsSame(F)){ + Fv.Orientation(TopAbs_FORWARD); + TopoDS_Edge newedge; + TopExp_Explorer ex; + for(ex.Init(Fv,TopAbs_EDGE); ex.More(); ex.Next()){ + if(ex.Current().IsSame(E)){ + newedge = TopoDS::Edge(ex.Current()); + break; + } + } + //gp_Vec Varc, VSurf; + // In cas of Tangent output, the current face becomes the support face + if (SortieTangente(CP, F, SD, ons, 0.1)) { + pc = BRep_Tool::CurveOnSurface(CP.Arc(),F,Uf,Ul); + HSBis = new (BRepAdaptor_HSurface)(F); + PBis = pc->Value(CP.ParameterOnArc()); + } + + + pc = BRep_Tool::CurveOnSurface(newedge,Fv,Uf,Ul); + } + else{ + TopoDS_Edge newedge = E; + newedge.Reverse(); + Fv.Orientation(TopAbs_FORWARD); + pc = BRep_Tool::CurveOnSurface(newedge,Fv,Uf,Ul); + } + pons = pc->Value(CP.ParameterOnArc()); + return 1; + } + else if(!Fv.IsNull()){ + c1obstacle = 1; + if(!Vref.IsNull()){ + TopExp_Explorer ex; + for(ex.Init(E,TopAbs_VERTEX); ex.More(); ex.Next()){ + if(ex.Current().IsSame(Vref)){ + c1obstacle = 0; + break; + } + } + } + if(c1obstacle){ + HS->ChangeSurface().Initialize(Fv); + HSref->ChangeSurface().Initialize(F); + W = CP.ParameterOnArc(); + HC = new BRepAdaptor_HCurve2d(); + TopoDS_Edge newedge; + TopoDS_Face newface = Fv; + newface.Orientation(TopAbs_FORWARD); + TopExp_Explorer ex; + for(ex.Init(newface,TopAbs_EDGE); ex.More(); ex.Next()){ + if(ex.Current().IsSame(E)){ + newedge = TopoDS::Edge(ex.Current()); + break; + } + } + HC->ChangeCurve2d().Initialize(newedge,Fv); + pons = HC->Value(W); + HCref->ChangeCurve2d().Initialize(E,F); + if(CP.IsVertex()) RecP = 1; + else RecRst = 1; + return 1; + } + else{ + HS->ChangeSurface().Initialize(F); + W = CP.ParameterOnArc(); + pc = BRep_Tool::CurveOnSurface(E,F,Uf,Ul); + pons = pc->Value(W); + return Standard_False; + } + } + else{ // there is no neighbor face, the state is preserved and False is returned. + HS->ChangeSurface().Initialize(F); + W = CP.ParameterOnArc(); + pc = BRep_Tool::CurveOnSurface(E,F,Uf,Ul); + pons = pc->Value(W); + return Standard_False; + } + } + else{ + HS->ChangeSurface().Initialize(F); + const ChFiDS_FaceInterference& FI = SD->Interference(ons); + if(FI.PCurveOnFace().IsNull()) pons = SD->Get2dPoints(isfirst,ons); + else pons = FI.PCurveOnFace()->Value(FI.Parameter(isfirst)); + } + return Standard_True; +} + +//======================================================================= +//function : SearchFace +//purpose : +//======================================================================= + +Standard_Boolean ChFi3d_Builder::SearchFace + (const Handle(ChFiDS_Spine)& Spine, + const ChFiDS_CommonPoint& Pc, + const TopoDS_Face& FRef, + TopoDS_Face& FVoi) const +{ + Standard_Boolean Trouve = Standard_False; + if (! Pc.IsOnArc()) return Standard_False; + FVoi.Nullify(); + TopoDS_Edge E; + if (Pc.IsVertex()){ + // attention it is necessary to analyze all faces that turn around of the vertex +#if DEB + cout<<"Commonpoint on vertex, the process hangs up"<<endl; +#endif + if (Pc.HasVector()) { //General processing + TopoDS_Face Fbis; + Standard_Integer nb_faces; + nb_faces = SearchFaceOnV(Pc, FRef, myVEMap, myEFMap, FVoi, Fbis); + return ( nb_faces > 0); + } + else { // Processing using the spine + Standard_Boolean FindFace=Standard_False; + gp_Pnt Point; + gp_Vec VecSpine; + Spine->D1(Pc.Parameter(), Point, VecSpine); + + // It is checked if one leaves from the current face. + FindFace = IsInput(VecSpine, Pc.Vertex(), FRef); + if (FindFace) { + VecSpine.Reverse(); + FindFace = IsInput(VecSpine, Pc.Vertex(), FRef); + } + // If one does not leave, it is ended + if (FindFace) { + FVoi = FRef; + return Standard_True; + } + + // Otherwise one finds the next among shared Faces + // by a common edge G1 + TopTools_ListIteratorOfListOfShape ItE, ItF; + for(ItE.Initialize(myVEMap(Pc.Vertex())); + ItE.More() && (!FindFace); ItE.Next()) { + E = TopoDS::Edge(ItE.Value()); + Trouve=Standard_False; + for(ItF.Initialize(myEFMap(E));//, Trouve=Standard_False; 15.11.99 SVV + ItF.More()&&(!Trouve); ItF.Next()) { + if (TopoDS::Face(ItF.Value()).IsSame(FRef)) { + Trouve = Standard_True; + } + } + if (Trouve) FindFace = IsG1(myEFMap, E, FRef, FVoi); + if (FindFace) { + FindFace = Standard_False; + if (Spine.IsNull()) { + //La Spine peut etre nulle (ThreeCorner) +#if DEB + cout << "FindFace sur vertex avec spine nulle! QUEZAKO ?" << endl; +#endif + return Standard_False; + } + + // It is checked if the selected face actually possesses edges of the spine + // containing the vertex on its front + // This processing should go only if the Vertex belongs to the spine + // This is a single case, for other vertexes it is required to do other things + Trouve=Standard_False; + for (Standard_Integer IE=1;//, Trouve=Standard_False; 15.11.99 SVV + (IE<=Spine->NbEdges()) && (!Trouve); IE++) { + E = Spine->Edges(IE); + if ( (TopExp::FirstVertex(E).IsSame(Pc.Vertex())) + ||(TopExp::LastVertex(E) .IsSame(Pc.Vertex())) ) { + for(ItF.Initialize(myEFMap(E)), Trouve=Standard_False; + ItF.More()&&(!Trouve); ItF.Next()) { + if (TopoDS::Face(ItF.Value()).IsSame(FVoi)) { + Trouve = Standard_True; + } + } + } + } + FindFace = Trouve; + } + } + } + } + else { + return IsG1(myEFMap, Pc.Arc(), FRef, FVoi); + } + return Standard_False; +} + + +//======================================================================= +//function : ChFi3d_SingularExtremity +//purpose : load the vertex in the DS and calculate the pcurve +// for an extremity in case of singular freeboundary +// or periodic and singular at the cut. +//======================================================================= +static void ChFi3d_SingularExtremity( Handle(ChFiDS_Stripe)& stripe, + TopOpeBRepDS_DataStructure& DStr, + const TopoDS_Vertex& Vtx, + const Standard_Real tol3d, + const Standard_Real tol2d) +{ + Handle(ChFiDS_SurfData) Fd; + Standard_Real tolreached; + Standard_Real Pardeb, Parfin; + gp_Pnt2d VOnS1, VOnS2; + Handle(Geom_Curve) C3d; + Handle(Geom2d_Curve) PCurv; + TopOpeBRepDS_Curve Crv; + // SurfData and its CommonPoints, + Standard_Integer Ivtx, Icurv; + Standard_Boolean isfirst; + + if (stripe->Spine()->IsPeriodic()) { + isfirst = Standard_True; + Fd = stripe->SetOfSurfData()->Sequence().First(); + } + else { + Standard_Integer sens; + Standard_Integer num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens); + Fd = stripe->SetOfSurfData()->Sequence().Value(num); + isfirst = (sens == 1); + } + + const ChFiDS_CommonPoint& CV1 = Fd->Vertex(isfirst,1); + const ChFiDS_CommonPoint& CV2 = Fd->Vertex(isfirst,2); + // Is it always degenerated ? + if ( CV1.Point().IsEqual( CV2.Point(), 0) ) { + Ivtx = ChFi3d_IndexPointInDS(CV1, DStr); + if (isfirst) { + VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()-> + Value(Fd->InterferenceOnS1().FirstParameter()); + VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()-> + Value(Fd->InterferenceOnS2().FirstParameter()); + } + else { + VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()-> + Value(Fd->InterferenceOnS1().LastParameter()); + VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()-> + Value(Fd->InterferenceOnS2().LastParameter()); + } + + ChFi3d_ComputeArete(CV1, VOnS1, + CV2, VOnS2, + DStr.Surface(Fd->Surf()).Surface(), + C3d, PCurv, + Pardeb,Parfin, tol3d, tol2d, tolreached,0); + Crv = TopOpeBRepDS_Curve(C3d,tolreached); + Icurv = DStr.AddCurve(Crv); + + stripe->SetCurve(Icurv, isfirst); + stripe->SetParameters(isfirst, Pardeb,Parfin); + stripe->ChangePCurve(isfirst) = PCurv; + stripe->SetIndexPoint(Ivtx, isfirst, 1); + stripe->SetIndexPoint(Ivtx, isfirst, 2); + + if (stripe->Spine()->IsPeriodic()) { + // periodic case : The operation is renewed + // the curve 3d is not shared. + // 2 degenerated edges coinciding in 3d + isfirst = Standard_False; + Fd = stripe->SetOfSurfData()->Sequence().Last(); + VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()-> + Value(Fd->InterferenceOnS1().LastParameter()); + VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()-> + Value(Fd->InterferenceOnS2().LastParameter()); + + ChFi3d_ComputeArete(CV1, VOnS1, + CV2, VOnS2, + DStr.Surface(Fd->Surf()).Surface(), + C3d, PCurv, + Pardeb,Parfin, tol3d, tol2d, tolreached,0); + Crv = TopOpeBRepDS_Curve(C3d,tolreached); + Icurv = DStr.AddCurve(Crv); + + stripe->SetCurve(Icurv, isfirst); + stripe->SetParameters(isfirst, Pardeb,Parfin); + stripe->ChangePCurve(isfirst) = PCurv; + stripe->SetIndexPoint(Ivtx, isfirst, 1); + stripe->SetIndexPoint(Ivtx, isfirst, 2); + } + } +} + +//======================================================================= +//function : ChFi3d_MakeExtremities +//purpose : calculate Curves3d and pcurves of extremities in +// periodic and freeboundary cases. +//======================================================================= +static Standard_Boolean IsFree(const TopoDS_Shape& E, + const ChFiDS_Map& EFMap) +{ + if(!EFMap.Contains(E)) return 0; + TopTools_ListIteratorOfListOfShape It; + TopoDS_Shape Fref; + for(It.Initialize(EFMap(E)); It.More(); It.Next()){ + if(Fref.IsNull()) Fref = It.Value(); + else if(!Fref.IsSame(It.Value())) return 0; + } + return 1; +} + +static void ChFi3d_MakeExtremities(Handle(ChFiDS_Stripe)& Stripe, + TopOpeBRepDS_DataStructure& DStr, + const ChFiDS_Map& EFMap, + const Standard_Real tol3d, + const Standard_Real tol2d) +{ + Handle(ChFiDS_Spine)& sp = Stripe->ChangeSpine(); + Standard_Real Pardeb,Parfin; + Handle(Geom_Curve) C3d; + Standard_Real tolreached; + if(sp->IsPeriodic()){ + Bnd_Box b1,b2; + const Handle(ChFiDS_SurfData)& + SDF = Stripe->SetOfSurfData()->Sequence().First(); + const ChFiDS_CommonPoint& CV1 = SDF->VertexFirstOnS1(); + const ChFiDS_CommonPoint& CV2 = SDF->VertexFirstOnS2(); + if ( !CV1.Point().IsEqual(CV2.Point(), 0) ) { + ChFi3d_ComputeArete(CV1, + SDF->InterferenceOnS1().PCurveOnSurf()-> + Value(SDF->InterferenceOnS1().FirstParameter()), + CV2, + SDF->InterferenceOnS2().PCurveOnSurf()-> + Value(SDF->InterferenceOnS2().FirstParameter()), + DStr.Surface(SDF->Surf()).Surface(),C3d, + Stripe->ChangeFirstPCurve(),Pardeb,Parfin, + tol3d,tol2d,tolreached,0); + TopOpeBRepDS_Curve Crv(C3d,tolreached); + Stripe->ChangeFirstCurve(DStr.AddCurve(Crv)); + Stripe->ChangeFirstParameters(Pardeb,Parfin); + Stripe->ChangeIndexFirstPointOnS1 + (ChFi3d_IndexPointInDS(SDF->VertexFirstOnS1(),DStr)); + Stripe->ChangeIndexFirstPointOnS2 + (ChFi3d_IndexPointInDS(SDF->VertexFirstOnS2(),DStr)); + Standard_Integer ICurv = Stripe->FirstCurve(); + Stripe->ChangeLastParameters(Pardeb,Parfin); + Stripe->ChangeLastCurve(ICurv); + Stripe->ChangeIndexLastPointOnS1(Stripe->IndexFirstPointOnS1()); + Stripe->ChangeIndexLastPointOnS2(Stripe->IndexFirstPointOnS2()); + + const Handle(ChFiDS_SurfData)& + SDL = Stripe->SetOfSurfData()->Sequence().Last(); + + + ChFi3d_ComputePCurv(C3d, + SDL->InterferenceOnS1().PCurveOnSurf()-> + Value(SDL->InterferenceOnS1().LastParameter()), + SDL->InterferenceOnS2().PCurveOnSurf()-> + Value(SDL->InterferenceOnS2().LastParameter()), + Stripe->ChangeLastPCurve(), + DStr.Surface(SDL->Surf()).Surface(), + Pardeb,Parfin,tol3d,tolreached); + Standard_Real oldtol = DStr.ChangeCurve(ICurv).Tolerance(); + DStr.ChangeCurve(ICurv).Tolerance(Max(oldtol,tolreached)); + if(CV1.IsOnArc()){ + ChFi3d_EnlargeBox(CV1.Arc(),EFMap(CV1.Arc()),CV1.ParameterOnArc(),b1); + } + + if(CV2.IsOnArc()){ + ChFi3d_EnlargeBox(CV2.Arc(),EFMap(CV2.Arc()),CV2.ParameterOnArc(),b2); + } + ChFi3d_EnlargeBox(DStr,Stripe,SDF,b1,b2,1); + ChFi3d_EnlargeBox(DStr,Stripe,SDL,b1,b2,0); + if (!CV1.IsVertex()) + ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexFirstPointOnS1()); + if (!CV2.IsVertex()) + ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexFirstPointOnS2()); + } + else { + // Case of the single extremity + if (CV1.IsVertex()) { + ChFi3d_SingularExtremity(Stripe, DStr, CV1.Vertex(), tol3d, tol2d); + } +# if DEB + else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; } +# endif + } + return; + } + + const Handle(ChFiDS_SurfData)& + SDdeb = Stripe->SetOfSurfData()->Sequence().First(); + + const ChFiDS_CommonPoint& cpdeb1 = SDdeb->VertexFirstOnS1(); + const ChFiDS_CommonPoint& cpdeb2 = SDdeb->VertexFirstOnS2(); + Standard_Boolean freedeb = sp->FirstStatus() == ChFiDS_FreeBoundary; + if(!freedeb && cpdeb1.IsOnArc() && cpdeb2.IsOnArc()){ + freedeb = (IsFree(cpdeb1.Arc(),EFMap) && IsFree(cpdeb2.Arc(),EFMap)); + } + if(freedeb){ + sp->SetFirstStatus(ChFiDS_FreeBoundary); + Bnd_Box b1,b2; + if ( !cpdeb1.Point().IsEqual(cpdeb2.Point(), 0) ) { + Standard_Boolean plane; + gp_Pnt2d UV1,UV2; + UV1=SDdeb->InterferenceOnS1().PCurveOnSurf()-> + Value(SDdeb->InterferenceOnS1().FirstParameter()); + UV2=SDdeb->InterferenceOnS2().PCurveOnSurf()-> + Value(SDdeb->InterferenceOnS2().FirstParameter()); +// The intersection of the fillet by a plane is attempted + + Handle(GeomAdaptor_HSurface) HConge=ChFi3d_BoundSurf(DStr,SDdeb,1,2); + ChFi3d_CoupeParPlan(cpdeb1,cpdeb2,HConge,UV1,UV2, + tol3d,tol2d,C3d,Stripe->ChangeFirstPCurve(),tolreached, + Pardeb,Parfin,plane); + if (!plane) + ChFi3d_ComputeArete(cpdeb1, + SDdeb->InterferenceOnS1().PCurveOnSurf()-> + Value(SDdeb->InterferenceOnS1().FirstParameter()), + cpdeb2, + SDdeb->InterferenceOnS2().PCurveOnSurf()-> + Value(SDdeb->InterferenceOnS2().FirstParameter()), + DStr.Surface(SDdeb->Surf()).Surface(),C3d, + Stripe->ChangeFirstPCurve(),Pardeb,Parfin, + tol3d,tol2d,tolreached,0); + TopOpeBRepDS_Curve Crv(C3d,tolreached); + Stripe->ChangeFirstCurve(DStr.AddCurve(Crv)); + Stripe->ChangeFirstParameters(Pardeb,Parfin); + Stripe->ChangeIndexFirstPointOnS1 + (ChFi3d_IndexPointInDS(SDdeb->VertexFirstOnS1(),DStr)); + Stripe->ChangeIndexFirstPointOnS2 + (ChFi3d_IndexPointInDS(SDdeb->VertexFirstOnS2(),DStr)); + if(cpdeb1.IsOnArc()){ + ChFi3d_EnlargeBox(cpdeb1.Arc(),EFMap(cpdeb1.Arc()),cpdeb1.ParameterOnArc(),b1); + } + if(cpdeb2.IsOnArc()){ + ChFi3d_EnlargeBox(cpdeb2.Arc(),EFMap(cpdeb2.Arc()),cpdeb2.ParameterOnArc(),b2); + } + ChFi3d_EnlargeBox(DStr,Stripe,SDdeb,b1,b2,1); + if (!cpdeb1.IsVertex()) + ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexFirstPointOnS1()); + if (!cpdeb2.IsVertex()) + ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexFirstPointOnS2()); + } + else { // Case of a singular extremity + if (cpdeb1.IsVertex()) { + ChFi3d_SingularExtremity(Stripe, DStr, cpdeb1.Vertex(), tol3d, tol2d); + } +# if DEB + else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; } +# endif + } + } + const Handle(ChFiDS_SurfData)& + SDfin = Stripe->SetOfSurfData()->Sequence().Last(); + const ChFiDS_CommonPoint& cpfin1 = SDfin->VertexLastOnS1(); + const ChFiDS_CommonPoint& cpfin2 = SDfin->VertexLastOnS2(); + Standard_Boolean freefin = sp->LastStatus() == ChFiDS_FreeBoundary; + if(!freefin && cpfin1.IsOnArc() && cpfin2.IsOnArc()){ + freefin = (IsFree(cpfin1.Arc(),EFMap) && IsFree(cpfin2.Arc(),EFMap)); + } + if(freefin){ + sp->SetLastStatus(ChFiDS_FreeBoundary); + Bnd_Box b1,b2; + if ( !cpfin1.Point().IsEqual(cpfin2.Point(), 0) ) { + Standard_Boolean plane; + gp_Pnt2d UV1,UV2; + UV1=SDfin->InterferenceOnS1().PCurveOnSurf()-> + Value(SDfin->InterferenceOnS1().LastParameter()); + UV2=SDfin->InterferenceOnS2().PCurveOnSurf()-> + Value(SDfin->InterferenceOnS2().LastParameter()); +// Intersection of the fillet by a plane is attempted + + Handle(GeomAdaptor_HSurface) HConge=ChFi3d_BoundSurf(DStr,SDfin,1,2); + ChFi3d_CoupeParPlan(cpfin1,cpfin2,HConge,UV1,UV2, + tol3d,tol2d,C3d,Stripe->ChangeLastPCurve(),tolreached, + Pardeb,Parfin,plane); + if (!plane) + ChFi3d_ComputeArete(cpfin1, + SDfin->InterferenceOnS1().PCurveOnSurf()-> + Value(SDfin->InterferenceOnS1().LastParameter()), + cpfin2, + SDfin->InterferenceOnS2().PCurveOnSurf()-> + Value(SDfin->InterferenceOnS2().LastParameter()), + DStr.Surface(SDfin->Surf()).Surface(),C3d, + Stripe->ChangeLastPCurve(),Pardeb,Parfin, + tol3d,tol2d,tolreached,0); + TopOpeBRepDS_Curve Crv(C3d,tolreached); + Stripe->ChangeLastCurve(DStr.AddCurve(Crv)); + Stripe->ChangeLastParameters(Pardeb,Parfin); + Stripe->ChangeIndexLastPointOnS1 + (ChFi3d_IndexPointInDS(SDfin->VertexLastOnS1(),DStr)); + Stripe->ChangeIndexLastPointOnS2 + (ChFi3d_IndexPointInDS(SDfin->VertexLastOnS2(),DStr)); + if(cpfin1.IsOnArc()){ + ChFi3d_EnlargeBox(cpfin1.Arc(),EFMap(cpfin1.Arc()),cpfin1.ParameterOnArc(),b1); + } + if(cpfin2.IsOnArc()){ + ChFi3d_EnlargeBox(cpfin2.Arc(),EFMap(cpfin2.Arc()),cpfin2.ParameterOnArc(),b2); + } + ChFi3d_EnlargeBox(DStr,Stripe,SDfin,b1,b2,0); + if (!cpfin1.IsVertex()) + ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexLastPointOnS1()); + if (!cpfin2.IsVertex()) + ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexLastPointOnS2()); + } + else { // Case of the single extremity + if (cpfin1.IsVertex()) { + ChFi3d_SingularExtremity(Stripe, DStr, cpfin1.Vertex(), tol3d, tol2d); + } +# if DEB + else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; } +# endif + } + } +} + +//======================================================================= +//function : ChFi3d_Purge +//purpose : +//======================================================================= + +static void ChFi3d_Purge (Handle(ChFiDS_Stripe)& Stripe, + Handle(ChFiDS_SurfData)& SD, + const ChFiDS_CommonPoint& VRef, + const Standard_Boolean isfirst, + const Standard_Integer ons, + Standard_Boolean& intf, + Standard_Boolean& intl) +{ + if (isfirst) intf = 1; else intl = 1; // End. + Standard_Integer opp = 3-ons; + if (!SD->Vertex(isfirst,opp).IsOnArc() || + SD->TwistOnS1() || SD->TwistOnS2() ) { +#ifdef DEB + cout<<"ChFi3d_Purge : No output on extension."<<endl; +#endif + ChFiDS_SequenceOfSurfData& Seq = + Stripe->ChangeSetOfSurfData()->ChangeSequence(); + if(isfirst) Seq.Remove(1); + else Seq.Remove(Seq.Length()); + return; + } + if (ons == 1) SD->ChangeIndexOfS1(0); + else SD->ChangeIndexOfS2(0); + + SD->ChangeVertex(!isfirst,ons) = VRef; + SD->ChangeVertex(isfirst,ons) = VRef; + + ChFiDS_FaceInterference& fi = SD->ChangeInterference(ons); + if(isfirst) fi.SetFirstParameter(fi.LastParameter()); + else fi.SetLastParameter(fi.FirstParameter()); + fi.SetLineIndex(0); +} + +//======================================================================= +//function : InsertAfter +//purpose : insert Item after ref in Seq. If ref is null, the item is +// inserted at the beginning. +//======================================================================= + +static void InsertAfter (Handle(ChFiDS_Stripe)& Stripe, + Handle(ChFiDS_SurfData)& Ref, + Handle(ChFiDS_SurfData)& Item) +{ + if (Ref == Item) + Standard_Failure::Raise("InsertAfter : twice the same surfdata."); + + ChFiDS_SequenceOfSurfData& Seq = + Stripe->ChangeSetOfSurfData()->ChangeSequence(); + + if (Seq.IsEmpty() || Ref.IsNull()) { + Seq.Prepend(Item); + } + for (Standard_Integer i = 1; i <= Seq.Length(); i++) { + if (Seq.Value(i) == Ref) { + Seq.InsertAfter(i,Item); + break; + } + } +} + +//======================================================================= +//function : RemoveSD +//purpose : +//======================================================================= + +static void RemoveSD (Handle(ChFiDS_Stripe)& Stripe, + Handle(ChFiDS_SurfData)& Prev, + Handle(ChFiDS_SurfData)& Next) +{ + ChFiDS_SequenceOfSurfData& Seq = + Stripe->ChangeSetOfSurfData()->ChangeSequence(); + if(Seq.IsEmpty()) return; + Standard_Integer iprev = 0, inext = 0; + for (Standard_Integer i = 1; i <= Seq.Length(); i++) { + if (Seq.Value(i) == Prev) iprev = i + 1; + if (Seq.Value(i) == Next) { inext = i - 1; break; } + } + if(Prev.IsNull()) iprev = 1; + if(Next.IsNull()) inext = Seq.Length(); + if(iprev <= inext) Seq.Remove(iprev,inext); +} + +//======================================================================= +//function : InsertBefore +//purpose : Insert item before ref in Seq. If ref is null, the item is +// inserted in the queue. +//======================================================================= + +static void InsertBefore (Handle(ChFiDS_Stripe)& Stripe, + Handle(ChFiDS_SurfData)& Ref, + Handle(ChFiDS_SurfData)& Item) +{ + if (Ref == Item) + Standard_Failure::Raise("InsertBefore : twice the same surfdata."); + + ChFiDS_SequenceOfSurfData& Seq = + Stripe->ChangeSetOfSurfData()->ChangeSequence(); + + if (Seq.IsEmpty() || Ref.IsNull()) { + Seq.Append(Item); + } + for (Standard_Integer i = 1; i <= Seq.Length(); i++) { + if (Seq.Value(i) == Ref) { + Seq.InsertBefore(i,Item); + break; + } + } +} + + +//======================================================================= +//function : PerformSetOfSurfOnElSpine +//purpose : +//======================================================================= + +void ChFi3d_Builder::PerformSetOfSurfOnElSpine +(const Handle(ChFiDS_HElSpine)& HGuide, + Handle(ChFiDS_Stripe)& Stripe, + Handle(BRepTopAdaptor_TopolTool)& It1, + Handle(BRepTopAdaptor_TopolTool)& It2, + const Standard_Boolean Simul) +{ +#ifdef DEB + OSD_Chronometer ch1; +#endif + + ChFiDS_ElSpine& Guide = HGuide->ChangeCurve(); + Standard_Real wf = Guide.FirstParameter(); + Standard_Real wl = Guide.LastParameter(); + Standard_Real locfleche = (wl - wf) * fleche; + Standard_Real wfsav = wf, wlsav = wl; + //Now the ElSpine is artificially extended to help rsnld. + Standard_Real prab = 0.01; + Guide.FirstParameter(wf-prab*(wl-wf)); + Guide.LastParameter (wl+prab*(wl-wf)); + Handle(ChFiDS_Spine)& Spine = Stripe->ChangeSpine(); + Standard_Integer ii, nbed = Spine->NbEdges(); + Standard_Real lastedlastp = Spine->LastParameter(nbed); + + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + + Handle(ChFiDS_SurfData) ref = Guide.Previous(); + Handle(ChFiDS_SurfData) refbis, SD; + Handle(ChFiDS_SurfData) raf = Guide.Next(); + RemoveSD(Stripe,ref,raf); + + Handle(BRepAdaptor_HSurface) HS1 = new BRepAdaptor_HSurface(); + Handle(BRepAdaptor_HSurface) HS2 = new BRepAdaptor_HSurface(); + Handle(BRepAdaptor_HSurface) HS3, HS4; + Handle(BRepAdaptor_HSurface) HSref1 = new BRepAdaptor_HSurface(); + Handle(BRepAdaptor_HSurface) HSref2 = new BRepAdaptor_HSurface(); + Handle(BRepAdaptor_HCurve2d) HC1,HC2; + Handle(BRepAdaptor_HCurve2d) HCref1 = new BRepAdaptor_HCurve2d(); + Handle(BRepAdaptor_HCurve2d) HCref2 = new BRepAdaptor_HCurve2d(); + Standard_Boolean decroch1 = 0, decroch2 = 0; + Standard_Boolean RecP1 = 0, RecS1 = 0, RecRst1 = 0, obstacleon1 = 0; + Standard_Boolean RecP2 = 0, RecS2 = 0, RecRst2 = 0, obstacleon2 = 0; + gp_Pnt2d pp1,pp2,pp3,pp4; + Standard_Real w1,w2; + math_Vector Soldep(1,4); + math_Vector SoldepCS(1,3); + math_Vector SoldepCC(1,2); + + // Restore a neighboring KPart. + // If no neighbor calculation start point. + Standard_Boolean forward = Standard_True; + Standard_Boolean Inside = Standard_False; + Standard_Real First = wf; + Standard_Real Last = wl; + Standard_Boolean Ok1 = 1,Ok2 = 1; + // Restore the next KPart if it exists + TopoDS_Vertex Vref; + if(ref.IsNull() && raf.IsNull()){ + //sinon solution approchee. + Inside = Standard_True; + +#ifdef DEB + ChFi3d_InitChron(ch1);// init perf for StartSol +#endif + + StartSol(Stripe,HGuide,HS1,HS2,It1,It2,pp1,pp2,First); + +#ifdef DEB + ChFi3d_ResultChron(ch1,t_startsol); // result perf for StartSol +#endif + + Last = wf; + if(Guide.IsPeriodic()) { + Last = First - Guide.Period(); + Guide.FirstParameter(Last); + Guide.LastParameter (First * 1.1);//Extension to help rsnld. + } + } + else{ + if(!Spine->IsPeriodic() && (wl - lastedlastp > -tolesp)){ + Vref = Spine->LastVertex(); + } + if (ref.IsNull()) { + if(!Spine->IsPeriodic() && (wf < tolesp)){ + Vref = Spine->FirstVertex(); + } + ref = raf; + forward = Standard_False; + First = wl; Last = Guide.FirstParameter(); + } + +#ifdef DEB + ChFi3d_InitChron(ch1);// init perf for startsol +#endif + + + Ok1 = StartSol(Spine,HS1,pp1,HC1,w1,ref,!forward,1, + HSref1,HCref1,RecP1,RecS1,RecRst1,obstacleon1, + HS3,pp3,decroch1,Vref); + Ok2 = StartSol(Spine,HS2,pp2,HC2,w2,ref,!forward,2, + HSref2,HCref2, RecP2,RecS2,RecRst2,obstacleon2, + HS4,pp4,decroch2,Vref); + HC1.Nullify(); + HC2.Nullify(); + +#ifdef DEB + ChFi3d_ResultChron(ch1,t_startsol); // result perf for startsol +#endif + + + if(Ok1 == 1 && Ok2 == 1) { + if(forward) Guide.FirstParameter(wf); + else Guide.LastParameter(wl); + } + } + Standard_Boolean fini = Standard_False; + Standard_Boolean complete = Inside; + if(!Guide.IsPeriodic()){ + Standard_Integer indf = Spine->Index(wf); + Standard_Integer indl = Spine->Index(wl,0); + if(Spine->IsPeriodic() && (indl < indf)) indl += nbed; + nbed = indl-indf+1; + } + // No Max at the touch : 20 points by edge at average without + // counting the extensions. + + Standard_Real bidf = wf, bidl = wl; + if(!Spine->IsPeriodic()) { + bidf = Max(0.,wf); + bidl = Min(wl,Spine->LastParameter(Spine->NbEdges())); + // PMN 20/07/98 : Attention in case if there is only extension + if ((bidl-bidf) < 0.01 * Spine->LastParameter(Spine->NbEdges())) { + bidf = wf; + bidl = wl; + } + } + Standard_Real MaxStep = (bidl-bidf)*0.05/nbed; +#ifndef DEB + Standard_Real Firstsov = 0.; +#else + Standard_Real Firstsov; +#endif + Standard_Boolean intf = 0, intl = 0; + while(!fini){ + // are these the ends (no extension on periodic). + Ok1 = 1,Ok2 = 1; + if(!Spine->IsPeriodic()){ + if(wf < tolesp && (complete == Inside)){ + if(Spine->FirstStatus() == ChFiDS_OnSame) intf = 2; + else intf = 1; + } + if(Spine->IsTangencyExtremity(Standard_True)){ + intf = 4; + Guide.FirstParameter(wfsav); + } + if(wl - lastedlastp > -tolesp){ + if(Spine->LastStatus() == ChFiDS_OnSame) intl = 2; + else intl = 1; + } + if(Spine->IsTangencyExtremity(Standard_False)){ + intl = 4; + Guide.LastParameter(wlsav); + } + } + if(intf && !forward) Vref = Spine->FirstVertex(); + if(intl && forward) Vref = Spine->LastVertex(); + if(!ref.IsNull()){ + +#ifdef DEB + ChFi3d_InitChron(ch1);// init perf for StartSol +#endif + + Ok1 = StartSol(Spine,HS1,pp1,HC1,w1,ref,!forward,1, + HSref1,HCref1, RecP1,RecS1,RecRst1,obstacleon1, + HS3,pp3,decroch1,Vref); + Ok2 = StartSol(Spine,HS2,pp2,HC2,w2,ref,!forward,2, + HSref2,HCref2, RecP2,RecS2,RecRst2,obstacleon2, + HS4,pp4,decroch2,Vref); + +#ifdef DEB + ChFi3d_ResultChron(ch1,t_startsol); // result perf for StartSol +#endif + + } + + // No more connected faces. Construction of the tangent plane to continue the path + // till the output on the other face. + if ((!Ok1 && HC1.IsNull()) || (!Ok2 && HC2.IsNull())) { + if ((intf && !forward) || (intl && forward)) { + if (!Ok1) ChFi3d_BuildPlane (DStr,HS1,pp1,ref,!forward,1); + if (!Ok2) ChFi3d_BuildPlane (DStr,HS2,pp2,ref,!forward,2); + if(intf) intf = 5; + else if(intl) intl = 5; + if(forward) Guide.FirstParameter(wf); + else Guide.LastParameter(wl); + } + else Standard_Failure::Raise("PerformSetOfSurfOnElSpine : Chaining is impossible."); + } + + // Definition of the domain of path It1, It2 + It1->Initialize(HS1); + It2->Initialize(HS2); + + // Calculate one (several if singularity) SurfaData + SD = new ChFiDS_SurfData(); + ChFiDS_SequenceOfSurfData SeqSD; + SeqSD.Append(SD); + + if(obstacleon1 && obstacleon2){ + TopAbs_Orientation Or1 = HSref1->ChangeSurface().Face().Orientation(); + TopAbs_Orientation Or2 = HSref2->ChangeSurface().Face().Orientation(); + Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2, + Stripe->OrientationOnFace1(), + Stripe->OrientationOnFace2(), + Stripe->Choix()); + + + // Calculate the criterion of Choice edge / edge + if (Choix%2 == 0) Choix = 4; + else Choix = 1; + + SoldepCC(1) = w1; SoldepCC(2) = w2; + if(Simul){ + SimulSurf(SD,HGuide,Spine,Choix, + HS1,It1,HC1,HSref1,HCref1,decroch1,Or1, + HS2,It2,HC2,HSref2,HCref2,decroch2,Or2, + locfleche,tolesp,First,Last,Inside,Inside,forward, + RecP1,RecRst1,RecP2,RecRst2,SoldepCC); + } + else{ +#ifdef DEB + ChFi3d_InitChron(ch1); // init perf for PerformSurf +#endif + PerformSurf(SeqSD,HGuide,Spine,Choix, + HS1,It1,HC1,HSref1,HCref1,decroch1,Or1, + HS2,It2,HC2,HSref2,HCref2,decroch2,Or2, + MaxStep,locfleche,tolesp,First,Last,Inside,Inside,forward, + RecP1,RecRst1,RecP2,RecRst2,SoldepCC); +#ifdef DEB + ChFi3d_ResultChron(ch1,t_performsurf); //result perf for PerformSurf +#endif + } + SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face())); + SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face())); + } + else if (obstacleon1){ + TopAbs_Orientation Or1 = HSref1->ChangeSurface().Face().Orientation(); + TopAbs_Orientation Or2 = HS2->ChangeSurface().Face().Orientation(); + Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2, + Stripe->OrientationOnFace1(), + Stripe->OrientationOnFace2(), + -Stripe->Choix()); + if(Choix%2 == 1) Choix++; + else Choix--; + SoldepCS(3) = w1; SoldepCS(1) = pp2.X(); SoldepCS(2) = pp2.Y(); + if(Simul){ + SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,HC1,HSref1,HCref1,decroch1, + HS2,It2,Or2,locfleche,tolesp,First,Last, + Inside,Inside,forward,RecP1,RecS2,RecRst1,SoldepCS); + } + else{ +#ifdef DEB + ChFi3d_InitChron(ch1); // init perf for PerformSurf +#endif + PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,HC1,HSref1,HCref1,decroch1, + HS2,It2,Or2,MaxStep,locfleche,tolesp,First,Last, + Inside,Inside,forward,RecP1,RecS2,RecRst1,SoldepCS); +#ifdef DEB + ChFi3d_ResultChron(ch1,t_performsurf);//result perf for PerformSurf +#endif + } + SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face())); + SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face())); + decroch2 = 0; + } + else if (obstacleon2){ + TopAbs_Orientation Or1 = HS1->ChangeSurface().Face().Orientation(); + TopAbs_Orientation Or2 = HSref2->ChangeSurface().Face().Orientation(); + Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2, + Stripe->OrientationOnFace1(), + Stripe->OrientationOnFace2(), + Stripe->Choix()); + SoldepCS(3) = w2; SoldepCS(1) = pp1.X(); SoldepCS(2) = pp1.Y(); + if(Simul){ + SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,Or1, + HS2,It2,HC2,HSref2,HCref2,decroch2,locfleche,tolesp, + First,Last,Inside,Inside,forward,RecP2,RecS1,RecRst2,SoldepCS); + } + else{ +#ifdef DEB + ChFi3d_InitChron(ch1); // init perf for PerformSurf +#endif + PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,Or1, + HS2,It2,HC2,HSref2,HCref2,decroch2,MaxStep,locfleche,tolesp, + First,Last,Inside,Inside,forward,RecP2,RecS1,RecRst2,SoldepCS); +#ifdef DEB + ChFi3d_ResultChron(ch1,t_performsurf); //result perf for PerformSurf +#endif + } + SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face())); + SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face())); + decroch1 = 0; + } + else{ + CallPerformSurf(Stripe, Simul, SeqSD, SD, + HGuide,Spine, + HS1, HS3, pp1, pp3, It1, + HS2, HS4, pp2, pp4, It2, + MaxStep,locfleche,tolesp, + First,Last,Inside,Inside,forward, + RecS1,RecS2,Soldep,intf,intl, + HS1, HS2); + decroch1 = decroch2 = 0; + } + + if(!done) { // Case of fail + if ((!Ok1 && !obstacleon1) || (!Ok2 && !obstacleon2)) { + //Fail in a part of extension is not serious + //Here one stops. + done = Standard_True; + Inside = Standard_False; + if (forward) intl = 1; + else intf = 1; + } + else { // Otherwise invalidation of the stripe. + Spine->SetErrorStatus(ChFiDS_WalkingFailure); + Standard_Failure::Raise("CallPerformSurf : Path failed!"); + } + } + + else { + refbis = ref; + if(forward) { + for (ii=1; ii<=SeqSD.Length(); ii++) { + SD = SeqSD(ii); + SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face())); + if(obstacleon1) SD->SetIndexOfC1(DStr.AddShape(HC1->ChangeCurve2d().Edge())); + SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face())); + if(obstacleon2) SD->SetIndexOfC2(DStr.AddShape(HC2->ChangeCurve2d().Edge())); + InsertAfter (Stripe, refbis, SD); + refbis = SD; + } + } + else { + for (ii=SeqSD.Length(); ii>=1; ii--) { + SD = SeqSD(ii); + SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face())); + if(obstacleon1) SD->SetIndexOfC1(DStr.AddShape(HC1->ChangeCurve2d().Edge())); + SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face())); + if(obstacleon2) SD->SetIndexOfC2(DStr.AddShape(HC2->ChangeCurve2d().Edge())); + InsertBefore(Stripe,refbis,SD); + refbis = SD; + } + } + + if (!Ok1 && !obstacleon1) + // clean infos on the plane of extension. + ChFi3d_Purge (Stripe,SD,ref->Vertex(!forward,1),!forward,1,intf,intl); + + if (!Ok2 && !obstacleon2) + // clean infos on the plane of extension. + ChFi3d_Purge (Stripe,SD,ref->Vertex(!forward,2),!forward,2,intf,intl); + + // The end. The reference is changed. + ref = refbis; + } + + if(Inside){// There are starting solutions for the next. + Inside = Standard_False; + Firstsov = First; + if(Guide.IsPeriodic()) { + complete = Standard_False; + wf = Guide.FirstParameter(); + wl = Guide.LastParameter(); + } + } + if(forward){ + fini = ((wl - Last) <= 10.*tolesp || + (intl && !(obstacleon1 || obstacleon2))); //General case + + if (!fini && Guide.IsPeriodic() && + ((wl - Last)< Guide.Period()*1.e-3)) { + // It is tested if reframing of extremes is done at the same edge + // Loop Condition + Handle(ChFiDS_SurfData) thefirst, thelast; + thefirst = Stripe->SetOfSurfData()->Sequence().First(); + thelast = Stripe->SetOfSurfData()->Sequence().Last(); + + if (thefirst->VertexFirstOnS1().IsOnArc() && + thelast->VertexLastOnS1().IsOnArc()) + fini = thefirst->VertexFirstOnS1().Arc().IsSame + (thelast->VertexLastOnS1().Arc()); + if (!fini && + thefirst->VertexFirstOnS2().IsOnArc() && + thelast->VertexLastOnS2().IsOnArc()) + fini = thefirst->VertexFirstOnS2().Arc().IsSame + (thelast->VertexLastOnS2().Arc()); + + if (fini) + return; //It is ended! + } + + if(fini && complete) { + // restart in the opposite direction. + ref = Stripe->SetOfSurfData()->Sequence().First(); + forward = Standard_False; + fini = Standard_False; + First = Firstsov; + } + else { + First = Last; + Last = wl; + } + } + if(!forward){ + fini = ((First - wf) <= 10.*tolesp || + (intf && !(obstacleon1 || obstacleon2))); + complete = Standard_False; + Last = wf; + } + } + // The initial state is restored + if(!Guide.IsPeriodic()){ + Guide.FirstParameter(wfsav); + Guide.LastParameter (wlsav); + } + +} + +//======================================================================= +//function : PerformSetOfKPart +//purpose : +//======================================================================= + +void ChFi3d_Builder::PerformSetOfKPart(Handle(ChFiDS_Stripe)& Stripe, + const Standard_Boolean Simul) +{ + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + Handle(ChFiDS_Spine)& Spine = Stripe->ChangeSpine(); + Handle(BRepAdaptor_HSurface) HS1,HS2; + TopAbs_Orientation Or1,Or2,RefOr1,RefOr2; + Standard_Integer Choix,RefChoix; + + // initialization of the stripe. + Stripe->Reset(); + Handle(ChFiDS_HData)& HData = Stripe->ChangeSetOfSurfData(); + HData = new ChFiDS_HData(); + ChFiDS_SequenceOfSurfData& SeqSurf = HData->ChangeSequence(); + + StripeOrientations(Spine,RefOr1,RefOr2,RefChoix); + Stripe->OrientationOnFace1(RefOr1); + Stripe->OrientationOnFace2(RefOr2); + Stripe->Choix(RefChoix); + + Handle(BRepTopAdaptor_TopolTool) It1 = new BRepTopAdaptor_TopolTool(); + Handle(BRepTopAdaptor_TopolTool) It2 = new BRepTopAdaptor_TopolTool(); + + Standard_Real WFirst,WLast = 0.; + gp_Vec TFirst,TLast,TEndPeriodic; + gp_Pnt PFirst,PLast,PEndPeriodic; + Standard_Boolean intf = 0, intl = 0; + + Handle(ChFiDS_HElSpine) CurrentHE = new ChFiDS_HElSpine(); + Spine->D1(Spine->FirstParameter(),PFirst,TFirst); + CurrentHE->ChangeCurve().FirstParameter(Spine->FirstParameter()); + CurrentHE->ChangeCurve().SetFirstPointAndTgt(PFirst,TFirst); + + Standard_Boolean YaKPart = Standard_False; + Standard_Integer iedgelastkpart = 0; + + Standard_Real WStartPeriodic = 0.; + Standard_Real WEndPeriodic = Spine->LastParameter(Spine->NbEdges()); + Spine->D1(WEndPeriodic,PEndPeriodic,TEndPeriodic); + + // Construction of particular cases. + + for (Standard_Integer iedge = 1; iedge <= Spine->NbEdges(); iedge++){ + + ConexFaces(Spine,iedge,RefChoix,HS1,HS2); + + if (ChFi3d_KParticular(Spine,iedge,HS1->ChangeSurface(),HS2->ChangeSurface())) { + intf = ((iedge == 1) && !Spine->IsPeriodic()); + intl = ((iedge == Spine->NbEdges()) && !Spine->IsPeriodic()); + Or1 = HS1->ChangeSurface().Face().Orientation(); + Or2 = HS2->ChangeSurface().Face().Orientation(); + Choix = ChFi3d::NextSide(Or1,Or2,RefOr1,RefOr2,RefChoix); + It1->Initialize(HS1); + It2->Initialize(HS2); + + Handle(ChFiDS_SurfData) SD = new ChFiDS_SurfData(); + ChFiDS_SequenceOfSurfData LSD; + + if(!ChFiKPart_ComputeData::Compute(DStr,SD,HS1,HS2,Or1,Or2,Spine,iedge)){ +#ifdef DEB + cout<<"failed calculation KPart"<<endl; +#endif + } + else if(!SplitKPart(SD,LSD,Spine,iedge,HS1,It1,HS2,It2,intf,intl)){ +#ifdef DEB + cout<<"failed calculation KPart"<<endl; +#endif + LSD.Clear(); + } + else iedgelastkpart = iedge; + if(Spine->IsPeriodic()){//debug provisory for SD that arrive in desorder. + Standard_Integer nbsd = LSD.Length(); + Standard_Real period = Spine->Period(); + Standard_Real wfp = WStartPeriodic, wlp = WEndPeriodic; +// modified by NIZHNY-EAP Thu Nov 25 12:57:53 1999 ___BEGIN___ + if(!YaKPart && nbsd>0){ +// if(!YaKPart){ +// modified by NIZHNY-EAP Thu Nov 25 12:57:57 1999 ___END___ + Handle(ChFiDS_SurfData) firstSD = LSD.ChangeValue(1); + Standard_Real wwf = firstSD->FirstSpineParam(); + Standard_Real wwl = firstSD->LastSpineParam(); + wwf = ChFi3d_InPeriod(wwf,wfp,wlp,tolesp); + wwl = ChFi3d_InPeriod(wwl,wfp,wlp,tolesp); + if (wwl <= wwf + tolesp) wwl += period; + wfp = wwf; + wlp = wfp + period; + } + for(Standard_Integer j = 1; j < nbsd; j++){ + Handle(ChFiDS_SurfData) jSD = LSD.Value(j); + for(Standard_Integer k = j+1; k <= nbsd; k++){ + Handle(ChFiDS_SurfData) kSD = LSD.Value(k); + Standard_Real jwf = jSD->FirstSpineParam(); + jwf = ChFi3d_InPeriod(jwf,wfp,wlp,tolesp); + Standard_Real kwf = kSD->FirstSpineParam(); + kwf = ChFi3d_InPeriod(kwf,wfp,wlp,tolesp); + if(kwf < jwf){ + LSD.SetValue(j,kSD); + LSD.SetValue(k,jSD); + } + } + } + } + TColStd_ListOfInteger li; + for(Standard_Integer j = 1; j <= LSD.Length(); j++){ + Handle(ChFiDS_SurfData)& curSD = LSD.ChangeValue(j); + if(Simul) SimulKPart(curSD); + SeqSurf.Append(curSD); + if(!Simul) li.Append(curSD->Surf()); + WFirst = LSD.Value(j)->FirstSpineParam(); + WLast = LSD.Value(j)->LastSpineParam(); + if(Spine->IsPeriodic()){ + WFirst = ChFi3d_InPeriod(WFirst,WStartPeriodic,WEndPeriodic,tolesp); + WLast = ChFi3d_InPeriod(WLast ,WStartPeriodic,WEndPeriodic,tolesp); + if (WLast <= WFirst + tolesp) WLast+= Spine->Period(); + } + TgtKP(LSD.Value(j),Spine,iedge,1,PFirst,TFirst); + TgtKP(LSD.Value(j),Spine,iedge,0,PLast,TLast); + + // Determine the sections to approximate + if(!YaKPart){ + if(Spine->IsPeriodic()){ + WStartPeriodic = WFirst; + WEndPeriodic = WStartPeriodic + Spine->Period(); + WLast = ElCLib::InPeriod(WLast,WStartPeriodic,WEndPeriodic); + if (WLast <= WFirst + tolesp) WLast+= Spine->Period(); + PEndPeriodic = PFirst; + TEndPeriodic = TFirst; + Spine->SetFirstParameter(WStartPeriodic); + Spine->SetLastParameter(WEndPeriodic); + } + else if(!intf || (iedge > 1)){ + // start section -> first KPart + // update of extension. + Spine->SetFirstTgt(Min(0.,WFirst)); + CurrentHE->ChangeCurve().LastParameter (WFirst); + CurrentHE->ChangeCurve().SetLastPointAndTgt(PFirst,TFirst); + Spine->AppendElSpine(CurrentHE); + CurrentHE->ChangeCurve().ChangeNext() = LSD.Value(j); + CurrentHE = new ChFiDS_HElSpine(); + } + CurrentHE->ChangeCurve().FirstParameter(WLast); + CurrentHE->ChangeCurve().SetFirstPointAndTgt(PLast,TLast); + CurrentHE->ChangeCurve().ChangePrevious() = LSD.Value(j); + YaKPart = Standard_True; + } + else { + if (WFirst - CurrentHE->FirstParameter() > tolesp) { + // section between two KPart + CurrentHE->ChangeCurve().LastParameter(WFirst); + CurrentHE->ChangeCurve().SetLastPointAndTgt(PFirst,TFirst); + Spine->AppendElSpine(CurrentHE); + CurrentHE->ChangeCurve().ChangeNext() = LSD.Value(j); + CurrentHE = new ChFiDS_HElSpine(); + } + CurrentHE->ChangeCurve().FirstParameter(WLast); + CurrentHE->ChangeCurve().SetFirstPointAndTgt(PLast,TLast); + CurrentHE->ChangeCurve().ChangePrevious() = LSD.Value(j); + } + } + if(!li.IsEmpty()) myEVIMap.Bind(Spine->Edges(iedge),li); + } + } + + if (!intl || (iedgelastkpart < Spine->NbEdges())) { + // section last KPart(or start of the spine) -> End of the spine. + // update of the extension. + + if(Spine->IsPeriodic()){ + if(WEndPeriodic - WLast > tolesp){ + CurrentHE->ChangeCurve().LastParameter(WEndPeriodic); + CurrentHE->ChangeCurve().SetLastPointAndTgt(PEndPeriodic,TEndPeriodic); + if(!YaKPart) CurrentHE->ChangeCurve().SetPeriodic(Standard_True); + Spine->AppendElSpine(CurrentHE); + } + } + else{ + Spine->D1(Spine->LastParameter(),PLast,TLast); + Spine->SetLastTgt(Max(Spine->LastParameter(Spine->NbEdges()), + WLast)); + if (Spine->LastParameter() - WLast > tolesp) { + CurrentHE->ChangeCurve().LastParameter(Spine->LastParameter()); + CurrentHE->ChangeCurve().SetLastPointAndTgt(PLast,TLast); + Spine->AppendElSpine(CurrentHE); + } + } + } + + ChFiDS_ListOfHElSpine& ll = Spine->ChangeElSpines(); + ChFiDS_ListIteratorOfListOfHElSpine ILES(ll); + for ( ; ILES.More(); ILES.Next()) { +#ifdef DEB + if(ChFi3d_GettraceCHRON()) elspine.Start(); +#endif + ChFi3d_PerformElSpine(ILES.Value(),Spine,myConti,tolesp); +#ifdef DEB + if(ChFi3d_GettraceCHRON()) { elspine.Stop(); } +#endif + } + Spine->SplitDone(Standard_True); +} + +static Standard_Real ChFi3d_BoxDiag(const Bnd_Box& box) +{ + Standard_Real a,b,c,d,e,f; + box.Get(a,b,c,d,e,f); + d-=a; e-=b; f-=c; + d*=d; e*=e; f*=f; + Standard_Real diag = sqrt(d + e + f); + return diag; +} + +//======================================================================= +//function : PerformSetOfKGen +//purpose : +//======================================================================= + +void ChFi3d_Builder::PerformSetOfKGen(Handle(ChFiDS_Stripe)& Stripe, + const Standard_Boolean Simul) +{ + Handle(BRepTopAdaptor_TopolTool) It1 = new BRepTopAdaptor_TopolTool(); + Handle(BRepTopAdaptor_TopolTool) It2 = new BRepTopAdaptor_TopolTool(); + Handle(ChFiDS_Spine)& Spine = Stripe->ChangeSpine(); + ChFiDS_ListOfHElSpine& ll = Spine->ChangeElSpines(); + ChFiDS_ListIteratorOfListOfHElSpine ILES(ll); + for ( ; ILES.More(); ILES.Next()) { +#ifdef DEB + if(ChFi3d_GettraceCHRON()) { chemine.Start(); } +#endif + PerformSetOfSurfOnElSpine(ILES.Value(),Stripe,It1,It2,Simul); +#ifdef DEB + if(ChFi3d_GettraceCHRON()) chemine.Stop(); +#endif + } + if(!Simul){ + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + Handle(ChFiDS_HData)& HData = Stripe->ChangeSetOfSurfData(); + ChFiDS_SequenceOfSurfData& SeqSurf = HData->ChangeSequence(); + Standard_Integer len = SeqSurf.Length(); + Standard_Integer last = len, i; + Standard_Boolean periodic = Spine->IsPeriodic(); + if(periodic) last++; + // It is attempted to reprocess the squares that bore. + for(i = 1; i <= len; i++){ + Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i); + Standard_Boolean tw1 = cursd->TwistOnS1(); + Standard_Boolean tw2 = cursd->TwistOnS2(); + Handle(ChFiDS_SurfData) prevsd, nextsd; + Standard_Integer iprev = i-1; + if(iprev == 0) { + if(periodic) iprev = len; + } + Standard_Integer inext = i + 1; + if(inext > len) { + if(periodic) inext = 1; + else inext = 0; + } + + // For the moment only the surfaces where the twist is + // detected at the path are corrected, it is necessary to control + // more subtly the ugly traces (size, curvature, inflexion... ) + if(!tw1 && !tw2) continue; + + // It is decided (fairly at random) if the extended surface is ready for the filling. + ChFiDS_FaceInterference& intf1 = cursd->ChangeInterferenceOnS1(); + ChFiDS_FaceInterference& intf2 = cursd->ChangeInterferenceOnS2(); + Standard_Integer cursurf1 = cursd->IndexOfS1(); + Standard_Integer cursurf2 = cursd->IndexOfS2(); + ChFiDS_CommonPoint& cpd1 = cursd->ChangeVertexFirstOnS1(); + ChFiDS_CommonPoint& cpd2 = cursd->ChangeVertexFirstOnS2(); + ChFiDS_CommonPoint& cpf1 = cursd->ChangeVertexLastOnS1(); + ChFiDS_CommonPoint& cpf2 = cursd->ChangeVertexLastOnS2(); + const gp_Pnt& pd1 = cpd1.Point(); + const gp_Pnt& pd2 = cpd2.Point(); + const gp_Pnt& pf1 = cpf1.Point(); + const gp_Pnt& pf2 = cpf2.Point(); + Standard_Real ddeb = pd1.Distance(pd2); + Standard_Real dfin = pf1.Distance(pf2); + Standard_Real don1 = pd1.Distance(pf1); + Standard_Real don2 = pd2.Distance(pf2); + Standard_Boolean possibleon1 = (don1 < 2*(ddeb + dfin)); + Standard_Boolean possibleon2 = (don2 < 2*(ddeb + dfin)); + if((tw1 && !possibleon1) || (tw2 && !possibleon2)) { + Spine->SetErrorStatus(ChFiDS_TwistedSurface); + Standard_Failure::Raise("adjustment by reprocessing the non-written points"); + } + + // It is checked if there are presentable neighbors + Standard_Boolean yaprevon1 = 0, yaprevon2 = 0; + Standard_Boolean samesurfon1 = 0, samesurfon2 = 0; + if(iprev){ + prevsd = SeqSurf.ChangeValue(iprev); + yaprevon1 = !prevsd->TwistOnS1(); + samesurfon1 = (prevsd->IndexOfS1() == cursurf1); + yaprevon2 = !prevsd->TwistOnS2(); + samesurfon2 = (prevsd->IndexOfS2() == cursurf2); + } + Standard_Boolean yanexton1 = 0, yanexton2 = 0; + if(inext){ + nextsd = SeqSurf.ChangeValue(inext); + yanexton1 = !nextsd->TwistOnS1(); + if(samesurfon1) samesurfon1 = (nextsd->IndexOfS1() == cursurf1); + yanexton2 = !nextsd->TwistOnS2(); + if(samesurfon2) samesurfon2 = (nextsd->IndexOfS2() == cursurf2); + } + // A contour of filling is constructed + Handle(Geom2d_Curve) PC1 = intf1.PCurveOnFace(); + Handle(Geom2d_Curve) PC2 = intf2.PCurveOnFace(); + Handle(BRepAdaptor_HSurface) S1 = new BRepAdaptor_HSurface(); + TopoDS_Face F1 = TopoDS::Face(DStr.Shape(cursurf1)); + S1->ChangeSurface().Initialize(F1); + Handle(BRepAdaptor_HSurface) S2 = new BRepAdaptor_HSurface(); + TopoDS_Face F2 = TopoDS::Face(DStr.Shape(cursurf2)); + S2->ChangeSurface().Initialize(F2); + Handle(GeomFill_Boundary) Bdeb,Bfin,Bon1,Bon2; + Standard_Boolean pointuon1 = 0, pointuon2 = 0; + if(tw1){ + if(!yaprevon1 || !yanexton1){ + Spine->SetErrorStatus(ChFiDS_TwistedSurface); + Standard_Failure::Raise + ("adjustment by reprocessing the non-written points: no neighbor"); + } + ChFiDS_FaceInterference& previntf1 = prevsd->ChangeInterferenceOnS1(); + ChFiDS_FaceInterference& nextintf1 = nextsd->ChangeInterferenceOnS1(); + Standard_Real prevpar1 = previntf1.LastParameter(); + Standard_Real nextpar1 = nextintf1.FirstParameter(); + if(samesurfon1){ + // It is checked if it is possible to intersect traces of neighbors + // to create a sharp end. + Handle(Geom2d_Curve) pcprev1 = previntf1.PCurveOnFace(); + Handle(Geom2d_Curve) pcnext1 = nextintf1.PCurveOnFace(); + Standard_Real nprevpar1,nnextpar1; + gp_Pnt2d p2d; +// Modified by Sergey KHROMOV - Wed Feb 5 12:03:17 2003 Begin +// if(ChFi3d_IntTraces(prevsd,prevpar1,nprevpar1,1,1, +// nextsd,nextpar1,nnextpar1,1,-1,p2d)){ + if(ChFi3d_IntTraces(prevsd,prevpar1,nprevpar1,1,1, + nextsd,nextpar1,nnextpar1,1,-1,p2d, + Standard_False, Standard_True)){ +// Modified by Sergey KHROMOV - Wed Feb 5 12:03:17 2003 End + previntf1.SetLastParameter(nprevpar1); + nextintf1.SetFirstParameter(nnextpar1); + pointuon1 = 1; + PC1.Nullify(); + } + else{ + gp_Pnt2d pdeb1,pfin1; + gp_Vec2d vdeb1,vfin1; + pcprev1->D1(prevpar1,pdeb1,vdeb1); + pcnext1->D1(nextpar1,pfin1,vfin1); + Bon1 = ChFi3d_mkbound(S1,PC1,-1,pdeb1,vdeb1,1, + pfin1,vfin1,tolesp,2.e-4); + } + } + else{ + //here the base is on 3D tangents of neighbors. + const Handle(Geom_Curve)& c3dprev1 = + DStr.Curve(previntf1.LineIndex()).Curve(); + const Handle(Geom_Curve)& c3dnext1 = + DStr.Curve(nextintf1.LineIndex()).Curve(); + gp_Pnt Pdeb1, Pfin1; + gp_Vec Vdeb1, Vfin1; + c3dprev1->D1(prevpar1,Pdeb1,Vdeb1); + c3dnext1->D1(nextpar1,Pfin1,Vfin1); + gp_Pnt2d pdeb1,pfin1; + Standard_Real pardeb1 = intf1.FirstParameter(); + Standard_Real parfin1 = intf1.LastParameter(); + pdeb1 = PC1->Value(pardeb1); + pfin1 = PC1->Value(parfin1); + Bon1 = ChFi3d_mkbound(S1,PC1,-1,pdeb1,Vdeb1,1, + pfin1,Vfin1,tolesp,2.e-4); + } + } + else{ + Bon1 = ChFi3d_mkbound(S1,PC1,tolesp,2.e-4); + } + if(tw2){ + if(!yaprevon2 || !yanexton2){ + Standard_Failure::Raise + ("adjustment by reprocessing the non-written points: no neighbor"); + } + ChFiDS_FaceInterference& previntf2 = prevsd->ChangeInterferenceOnS2(); + ChFiDS_FaceInterference& nextintf2 = nextsd->ChangeInterferenceOnS2(); + Standard_Real prevpar2 = previntf2.LastParameter(); + Standard_Real nextpar2 = nextintf2.FirstParameter(); + if(samesurfon2){ + // It is checked if it is possible to intersect traces of neighbors + // to create a sharp end. + Handle(Geom2d_Curve) pcprev2 = previntf2.PCurveOnFace(); + Handle(Geom2d_Curve) pcnext2 = nextintf2.PCurveOnFace(); + Standard_Real nprevpar2,nnextpar2; + gp_Pnt2d p2d; +// Modified by Sergey KHROMOV - Wed Feb 5 12:03:17 2003 Begin +// if(ChFi3d_IntTraces(prevsd,prevpar2,nprevpar2,2,1, +// nextsd,nextpar2,nnextpar2,2,-1,p2d)){ + if(ChFi3d_IntTraces(prevsd,prevpar2,nprevpar2,2,1, + nextsd,nextpar2,nnextpar2,2,-1,p2d, + Standard_False, Standard_True)){ +// Modified by Sergey KHROMOV - Wed Feb 5 12:03:17 2003 End + previntf2.SetLastParameter(nprevpar2); + nextintf2.SetFirstParameter(nnextpar2); + pointuon2 = 1; + PC2.Nullify(); + } + else{ + gp_Pnt2d pdeb2,pfin2; + gp_Vec2d vdeb2,vfin2; + pcprev2->D1(prevpar2,pdeb2,vdeb2); + pcnext2->D1(nextpar2,pfin2,vfin2); + Bon2 = ChFi3d_mkbound(S2,PC2,-1,pdeb2,vdeb2,1, + pfin2,vfin2,tolesp,2.e-4); + } + } + else{ + //here the base is on 3D tangents of neighbors. + const Handle(Geom_Curve)& c3dprev2 = + DStr.Curve(previntf2.LineIndex()).Curve(); + const Handle(Geom_Curve)& c3dnext2 = + DStr.Curve(nextintf2.LineIndex()).Curve(); + gp_Pnt Pdeb2, Pfin2; + gp_Vec Vdeb2, Vfin2; + c3dprev2->D1(prevpar2,Pdeb2,Vdeb2); + c3dnext2->D1(nextpar2,Pfin2,Vfin2); + gp_Pnt2d pdeb2,pfin2; + Standard_Real pardeb2 = intf2.FirstParameter(); + Standard_Real parfin2 = intf2.LastParameter(); + pdeb2 = PC2->Value(pardeb2); + pfin2 = PC2->Value(parfin2); + Bon2 = ChFi3d_mkbound(S2,PC2,-1,pdeb2,Vdeb2,1, + pfin2,Vfin2,tolesp,2.e-4); + } + } + else{ + Bon2 = ChFi3d_mkbound(S2,PC2,tolesp,2.e-4); + } + // The parameters of neighbor traces are updated, so + // straight lines uv are pulled. + const Handle(Geom_Surface)& + sprev = DStr.Surface(prevsd->Surf()).Surface(); + const Handle(Geom_Surface)& + snext = DStr.Surface(nextsd->Surf()).Surface(); + ChFiDS_FaceInterference& previntf1 = prevsd->ChangeInterferenceOnS1(); + ChFiDS_FaceInterference& nextintf1 = nextsd->ChangeInterferenceOnS1(); + ChFiDS_FaceInterference& previntf2 = prevsd->ChangeInterferenceOnS2(); + ChFiDS_FaceInterference& nextintf2 = nextsd->ChangeInterferenceOnS2(); + Handle(Geom2d_Curve) pcsprev1 = previntf1.PCurveOnSurf(); + Handle(Geom2d_Curve) pcsnext1 = nextintf1.PCurveOnSurf(); + Standard_Real prevpar1 = previntf1.LastParameter(); + Standard_Real nextpar1 = nextintf1.FirstParameter(); + Handle(Geom2d_Curve) pcsprev2 = previntf2.PCurveOnSurf(); + Handle(Geom2d_Curve) pcsnext2 = nextintf2.PCurveOnSurf(); + Standard_Real prevpar2 = previntf2.LastParameter(); + Standard_Real nextpar2 = nextintf2.FirstParameter(); + gp_Pnt2d pdebs1 = pcsprev1->Value(prevpar1); + gp_Pnt2d pdebs2 = pcsprev2->Value(prevpar2); + gp_Pnt2d pfins1 = pcsnext1->Value(nextpar1); + gp_Pnt2d pfins2 = pcsnext2->Value(nextpar2); + Bdeb = ChFi3d_mkbound(sprev,pdebs1,pdebs2,tolesp,2.e-4); + Bfin = ChFi3d_mkbound(snext,pfins1,pfins2,tolesp,2.e-4); + + GeomFill_ConstrainedFilling fil(11,20); + if(pointuon1) fil.Init(Bon2,Bfin,Bdeb,1); + else if(pointuon2) fil.Init(Bon1,Bfin,Bdeb,1); + else fil.Init(Bon1,Bfin,Bon2,Bdeb,1); + + ChFi3d_ReparamPcurv(0.,1.,PC1); + ChFi3d_ReparamPcurv(0.,1.,PC2); + Handle(Geom_Surface) newsurf = fil.Surface(); +#ifdef DEB +#ifdef DRAW + //POP for NT + char* pops = "newsurf"; + DrawTrSurf::Set(pops,newsurf); +#endif +#endif + if(pointuon1) { + newsurf->VReverse(); // we return to direction 1 from 2; + done = CompleteData(cursd,newsurf,S1,PC1,S2,PC2, + F2.Orientation(),0,0,0,0,0); + cursd->ChangeIndexOfS1(0); + } + else{ + done = CompleteData(cursd,newsurf,S1,PC1,S2,PC2, + F1.Orientation(),1,0,0,0,0); + if(pointuon2) cursd->ChangeIndexOfS2(0); + } + if(tw1){ + prevsd->ChangeVertexLastOnS1().SetPoint(cpd1.Point()); + nextsd->ChangeVertexFirstOnS1().SetPoint(cpf1.Point()); + } + if(tw2){ + prevsd->ChangeVertexLastOnS2().SetPoint(cpd2.Point()); + nextsd->ChangeVertexFirstOnS2().SetPoint(cpf2.Point()); + } + } + // The tolerance of points is updated. + for(i = 1; i < last; i++){ + Standard_Integer j = i%len + 1; + Standard_Integer curs1, curs2; + Standard_Integer nexts1, nexts2; + Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i); + Handle(ChFiDS_SurfData)& nextsd = SeqSurf.ChangeValue(j); + ChFiDS_CommonPoint& curp1 = cursd->ChangeVertexLastOnS1(); + ChFiDS_CommonPoint& nextp1 = nextsd->ChangeVertexFirstOnS1(); + if (cursd->IsOnCurve1()) curs1 = cursd->IndexOfC1(); + else curs1 = cursd->IndexOfS1(); + if (cursd->IsOnCurve2()) curs2 = cursd->IndexOfC2(); + else curs2 = cursd->IndexOfS2(); + Standard_Real tol1 = Max(curp1.Tolerance(),nextp1.Tolerance()); + ChFiDS_CommonPoint& curp2 = cursd->ChangeVertexLastOnS2(); + ChFiDS_CommonPoint& nextp2 = nextsd->ChangeVertexFirstOnS2(); + Standard_Real tol2 = Max(curp2.Tolerance(),nextp2.Tolerance()); + if (nextsd->IsOnCurve1()) nexts1 = nextsd->IndexOfC1(); + else nexts1 = nextsd->IndexOfS1(); + if (nextsd->IsOnCurve2()) nexts2 = nextsd->IndexOfC2(); + else nexts2 = nextsd->IndexOfS2(); + + if(!curp1.IsOnArc() && nextp1.IsOnArc()){ + curp1 = nextp1; + if ( (curs1 == nexts1) && !nextsd->IsOnCurve1()) + // Case when it is not possible to pass along the border without leaving + ChangeTransition(nextp1, curp1, nexts1, myDS); + } + else if(curp1.IsOnArc() && !nextp1.IsOnArc()) { + nextp1 = curp1; + if ( (curs1 == nexts1) && !cursd->IsOnCurve1()) + ChangeTransition(curp1, nextp1, curs1, myDS); + } + + if(!curp2.IsOnArc() && nextp2.IsOnArc()) { + curp2 = nextp2; + if ( (curs2 == nexts2) && !nextsd->IsOnCurve2()) + ChangeTransition(nextp2, curp2, curs2, myDS); + } + else if(curp2.IsOnArc() && !nextp2.IsOnArc()){ + nextp2 = curp2; + if ( (curs2 == nexts2) && !cursd->IsOnCurve2()) + ChangeTransition(curp2, nextp2, curs2, myDS); + } + + curp1.SetTolerance(tol1); nextp1.SetTolerance(tol1); + curp2.SetTolerance(tol2); nextp2.SetTolerance(tol2); + + Bnd_Box b1,b2; + if(curp1.IsOnArc()){ + ChFi3d_EnlargeBox(curp1.Arc(),myEFMap(curp1.Arc()),curp1.ParameterOnArc(),b1); + } + if(curp2.IsOnArc()){ + ChFi3d_EnlargeBox(curp2.Arc(),myEFMap(curp2.Arc()),curp2.ParameterOnArc(),b2); + } + Handle(ChFiDS_Stripe) bidst; + ChFi3d_EnlargeBox(DStr,bidst,cursd,b1,b2,0); + ChFi3d_EnlargeBox(DStr,bidst,nextsd,b1,b2,1); + tol1 = ChFi3d_BoxDiag(b1); + tol2 = ChFi3d_BoxDiag(b2); + curp1.SetTolerance(tol1); nextp1.SetTolerance(tol1); + curp2.SetTolerance(tol2); nextp2.SetTolerance(tol2); + } + // The connections edge/new faces are updated. + for (ILES.Initialize(ll) ; ILES.More(); ILES.Next()) { + const Handle(ChFiDS_HElSpine)& curhels = ILES.Value(); + const ChFiDS_ElSpine& curels = curhels->ChangeCurve(); + Standard_Real WF = curels.FirstParameter(); + Standard_Real WL = curels.LastParameter(); + Standard_Integer IF,IL; + Standard_Real nwf = WF, nwl = WL; + Standard_Real period = 0.; + Standard_Integer nbed = Spine->NbEdges(); + if(periodic){ + period = Spine->Period(); + nwf = ElCLib::InPeriod(WF,-tolesp,period-tolesp); + IF = Spine->Index(nwf,1); + nwl = ElCLib::InPeriod(WL,tolesp,period+tolesp); + IL = Spine->Index(nwl,0); + if(nwl<nwf+tolesp) IL += nbed; + } + else{ + IF = Spine->Index(WF,1); + IL = Spine->Index(WL,0); + } + if(IF == IL) { + //fast processing + Standard_Integer IFloc = IF; + if(periodic) IFloc = (IF - 1)%nbed + 1; + const TopoDS_Edge& Ej = Spine->Edges(IFloc); + for(i = 1; i <= len; i++){ + Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i); + Standard_Real fp = cursd->FirstSpineParam(); + Standard_Real lp = cursd->LastSpineParam(); + if(lp < WF+tolesp || fp > WL-tolesp) continue; + if(!myEVIMap.IsBound(Ej)) { + TColStd_ListOfInteger li; + myEVIMap.Bind(Ej,li); + } + myEVIMap.ChangeFind(Ej).Append(cursd->Surf()); + } + } + else if(IF < IL){ + TColStd_Array1OfReal wv(IF,IL - 1); +#ifdef DEB + cout<<"length of the trajectory : "<<(WL-WF)<<endl; +#endif + for(i = IF; i < IL; i++){ + Standard_Integer iloc = i; + if(periodic) iloc = (i - 1)%nbed + 1; + Standard_Real wi = Spine->LastParameter(iloc); + if(periodic) wi = ElCLib::InPeriod(wi,WF,WF+period); + gp_Pnt pv = Spine->Value(wi); +#ifdef DEB + gp_Pnt pelsapp = curels.Value(wi); + Standard_Real distinit = pv.Distance(pelsapp); + cout<<"distance psp/papp : "<<distinit<<endl; +#endif + Extrema_LocateExtPC ext(pv,curels,wi,1.e-8); + wv(i) = wi; + if(ext.IsDone()){ + wv(i) = ext.Point().Parameter(); + } + else { +#ifdef DEB + cout<<"fail of projection vertex ElSpine!!!"<<endl; +#endif + } + } + for(i = 1; i <= len; i++){ + Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i); + Standard_Real fp = cursd->FirstSpineParam(); + Standard_Real lp = cursd->LastSpineParam(); + Standard_Integer j; +#ifndef DEB + Standard_Integer jf = 0, jl = 0; +#else + Standard_Integer jf,jl; +#endif + if(lp < WF+tolesp || fp > WL-tolesp) continue; + for(j = IF; j < IL; j++){ + jf = j; + if(fp < wv(j) - tolesp) break; + } + for(j = IF; j < IL; j++){ + jl = j; + if(lp < wv(j) + tolesp) break; + } + for(j = jf; j <= jl; j++){ + Standard_Integer jloc = j; + if(periodic) jloc = (j - 1)%nbed + 1; + const TopoDS_Edge& Ej = Spine->Edges(jloc); + if(!myEVIMap.IsBound(Ej)) { + TColStd_ListOfInteger li; + myEVIMap.Bind(Ej,li); + } + myEVIMap.ChangeFind(Ej).Append(cursd->Surf()); + } + } + } + } + } +} + +//======================================================================= +//function : PerformSetOfSurf +//purpose : +//======================================================================= + +void ChFi3d_Builder::PerformSetOfSurf(Handle(ChFiDS_Stripe)& Stripe, + const Standard_Boolean Simul) +{ + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + +#ifdef DEB + OSD_Chronometer ch; + ChFi3d_InitChron(ch);// init perf for PerformSetOfKPart +#endif + + const Handle(ChFiDS_Spine)& sp = Stripe->Spine(); + Standard_Integer SI = ChFi3d_SolidIndex(sp,DStr,myESoMap,myEShMap); + Stripe->SetSolidIndex(SI); + if(!sp->SplitDone()) PerformSetOfKPart(Stripe,Simul); + +#ifdef DEB + ChFi3d_ResultChron(ch ,t_perfsetofkpart); // result perf PerformSetOfKPart( + ChFi3d_InitChron(ch); // init perf for PerformSetOfKGen +#endif + + PerformSetOfKGen(Stripe,Simul); + +#ifdef DEB + ChFi3d_ResultChron(ch, t_perfsetofkgen);//result perf PerformSetOfKGen + ChFi3d_InitChron(ch); // init perf for ChFi3d_MakeExtremities +#endif + + if(!Simul) ChFi3d_MakeExtremities(Stripe,DStr,myEFMap,tolesp,tol2d); + +#ifdef DEB + ChFi3d_ResultChron(ch, t_makextremities); // result perf t_makextremities +#endif +} diff --git a/src/ChFi3d/ChFi3d_Builder_6.cxx b/src/ChFi3d/ChFi3d_Builder_6.cxx new file mode 100644 index 00000000..ddb773f2 --- /dev/null +++ b/src/ChFi3d/ChFi3d_Builder_6.cxx @@ -0,0 +1,2213 @@ +// File: ChFi3d_Builder_6.cxx +// Created: Tue Oct 25 17:54:52 1994 +// Author: Laurent BOURESCHE +// <lbo@phylox> +// modif : jlr branchement F(t) pour Edge/Face + +// Modified by skv - Wed Jun 9 17:16:26 2004 OCC5898 +// modified by Edward AGAPOV (eap) Fri Feb 8 2002 (bug occ67 == BUC61052) +// ComputeData(), case where BRepBlend_Walking::Continu() can't get up to Target + +#include <stdio.h> + +#include <ChFi3d_Builder.jxx> +#include <ChFi3d_Builder_0.hxx> + +#include <Precision.hxx> +#include <math_Vector.hxx> +#include <BSplCLib.hxx> + +#include <gp_Pnt.hxx> +#include <gp_Vec.hxx> +#include <gp_Pnt2d.hxx> +#include <gp_Dir2d.hxx> +#include <gp_Vec2d.hxx> + +#include <Geom2d_TrimmedCurve.hxx> +#include <Geom2d_BSplineCurve.hxx> +#include <Geom2d_Curve.hxx> +#include <Geom2d_Line.hxx> +#include <Geom_Curve.hxx> +#include <Geom_BSplineSurface.hxx> +#include <GeomLib.hxx> + +#include <Adaptor3d_HSurface.hxx> +#include <Adaptor3d_TopolTool.hxx> +#include <GeomAdaptor_HCurve.hxx> +#include <GeomAdaptor_HSurface.hxx> +#include <BRepAdaptor_Surface.hxx> +#include <BRepAdaptor_Curve2d.hxx> +#include <BRepAdaptor_Curve.hxx> +#include <BRepAdaptor_HCurve2d.hxx> +#include <BRepTopAdaptor_TopolTool.hxx> +#include <BRepTopAdaptor_HVertex.hxx> +#include <BRep_Tool.hxx> + +#include <Approx_SweepFunction.hxx> +#include <Blend_Point.hxx> +#include <BRepBlend_Extremity.hxx> +#include <BRepBlend_PointOnRst.hxx> +#include <BRepBlend_Line.hxx> +#include <BRepBlend_AppSurf.hxx> +#include <BRepBlend_AppSurface.hxx> +#include <BRepBlend_AppFunc.hxx> +#include <BRepBlend_AppFuncRst.hxx> +#include <BRepBlend_AppFuncRstRst.hxx> +#include <BRepBlend_CSWalking.hxx> +#include <BRepBlend_Walking.hxx> +#include <BRepBlend_SurfRstLineBuilder.hxx> +#include <BRepBlend_RstRstLineBuilder.hxx> +#include <BRepBlend_ConstRad.hxx> +#include <BRepBlend_ConstRadInv.hxx> + +#include <TopOpeBRepDS_DataStructure.hxx> +#include <TopOpeBRepDS_Curve.hxx> +#include <TopOpeBRepDS_Surface.hxx> + +#include <IntRes2d_IntersectionPoint.hxx> +#include <Geom2dInt_GInter.hxx> +#include <Geom2dAPI_ProjectPointOnCurve.hxx> + +#include <ChFiDS_SurfData.hxx> +#include <ChFiDS_FaceInterference.hxx> +#include <ChFiDS_CommonPoint.hxx> + +#include <TopExp.hxx> +#include <TopTools_ListOfShape.hxx> +#include <TopTools_ListIteratorOfListOfShape.hxx> + +#ifdef DEB +// For measurements. +#include <OSD_Chronometer.hxx> +//static OSD_Chronometer appclock; +#endif + +//#define DRAW + +#ifdef DRAW +#include <Draw_Appli.hxx> +#include <Draw_Segment2D.hxx> +#include <Draw_Marker2D.hxx> +#include <Draw_Segment3D.hxx> +#include <Draw_Marker3D.hxx> +#include <Draw.hxx> +#include <DrawTrSurf.hxx> +static Standard_Integer IndexOfConge = 0; +#endif + +#ifdef DEB +extern Standard_Boolean ChFi3d_GettraceDRAWFIL(); +extern Standard_Boolean ChFi3d_GettraceDRAWWALK(); +extern Standard_Boolean ChFi3d_GetcontextNOOPT(); +extern void ChFi3d_SettraceDRAWFIL(const Standard_Boolean b); +extern void ChFi3d_SettraceDRAWWALK(const Standard_Boolean b); +extern void ChFi3d_SetcontextNOOPT(const Standard_Boolean b); +#endif + +#ifdef DRAW +static void drawline(const Handle(BRepBlend_Line)& lin, + const Standard_Boolean iscs) +{ + Handle(Draw_Marker3D) p3d; + Handle(Draw_Marker2D) p2d; + Handle(Draw_Segment3D) tg3d; + Handle(Draw_Segment2D) tg2d; + + for(Standard_Integer i = 1; i <= lin->NbPoints(); i++){ + const Blend_Point& pt = lin->Point(i); + gp_Pnt point = pt.PointOnS1(); + gp_Pnt extr = point.Translated(pt.TangentOnS1()); + p3d = new Draw_Marker3D(point,Draw_Square,Draw_rouge); + dout<<p3d; + tg3d = new Draw_Segment3D(point,extr,Draw_rouge); + dout<<tg3d; + point = pt.PointOnS2(); + extr = point.Translated(pt.TangentOnS2()); + p3d = new Draw_Marker3D(point,Draw_Plus,Draw_jaune); + dout<<p3d; + tg3d = new Draw_Segment3D(point,extr,Draw_jaune); + dout<<tg3d; + + Standard_Real u,v; + pt.ParametersOnS1(u,v); + gp_Pnt2d point2d(u,v); + gp_Pnt2d extr2d = point2d.Translated(pt.Tangent2dOnS1()); + p2d = new Draw_Marker2D(point2d,Draw_Square,Draw_rouge); + dout<<p2d; + tg2d = new Draw_Segment2D(point2d,extr2d,Draw_rouge); + dout<<tg2d; + pt.ParametersOnS2(u,v); + point2d.SetCoord(u,v); + extr2d = point2d.Translated(pt.Tangent2dOnS2()); + p2d = new Draw_Marker2D(point2d,Draw_Plus,Draw_jaune); + dout<<p2d; + tg2d = new Draw_Segment2D(point2d,extr2d,Draw_jaune); + dout<<tg2d; + dout.Flush(); + } +} +#endif +//======================================================================= +//function : SearchIndex +//purpose : +// +//======================================================================= +static Standard_Integer SearchIndex(const Standard_Real Value, + Handle(BRepBlend_Line)& Lin) +{ + Standard_Integer NbPnt = Lin->NbPoints(), Ind; + + for (Ind = 1; + (Ind < NbPnt) && (Lin->Point(Ind).Parameter() < Value); ) + Ind++; + return Ind; +} + + +//======================================================================= +//function : IsObst +//purpose : +// +//======================================================================= +static Standard_Integer nbedconnex(const TopTools_ListOfShape& L) +{ + Standard_Integer nb = 0, i = 0; + TopTools_ListIteratorOfListOfShape It1(L); + for(;It1.More();It1.Next(),i++){ + const TopoDS_Shape& curs = It1.Value(); + Standard_Boolean dejavu = 0; + TopTools_ListIteratorOfListOfShape It2(L); + for(Standard_Integer j = 0; j < i && It2.More(); j++, It2.Next()){ + if(curs.IsSame(It2.Value())){ + dejavu = 1; + break; + } + } + if(!dejavu) nb++; + } + return nb; +} + +static Standard_Boolean IsVois(const TopoDS_Edge& E, + const TopoDS_Vertex& Vref, + const ChFiDS_Map& VEMap, + TopTools_MapOfShape& DONE, + const Standard_Integer prof, + const Standard_Integer profmax) +{ + if(prof > profmax) return Standard_False; + if(DONE.Contains(E)) return Standard_False; + TopoDS_Vertex V1,V2; + TopExp::Vertices(E,V1,V2); + if(Vref.IsSame(V1) || Vref.IsSame(V2)) return Standard_True; + DONE.Add(E); + const TopTools_ListOfShape& L1 = VEMap(V1); + Standard_Integer i1 = nbedconnex(L1); + TopTools_ListIteratorOfListOfShape It1(L1); + for(;It1.More();It1.Next()){ + const TopoDS_Edge& curE = TopoDS::Edge(It1.Value()); + if(i1 <= 2){ + if(IsVois(curE,Vref,VEMap,DONE,prof,profmax)) return Standard_True; + } + else if(IsVois(curE,Vref,VEMap,DONE,prof+1,profmax)) return Standard_True; + } + const TopTools_ListOfShape& L2 = VEMap(V2); +#ifdef DEB +// Standard_Integer i2 = nbedconnex(L2); +#endif + TopTools_ListIteratorOfListOfShape It2(L2); + for(;It2.More();It2.Next()){ + const TopoDS_Edge& curE = TopoDS::Edge(It2.Value()); + if(i1 <= 2){ + if(IsVois(curE,Vref,VEMap,DONE,prof,profmax)) return Standard_True; + } + else if(IsVois(curE,Vref,VEMap,DONE,prof+1,profmax)) return Standard_True; + } + return Standard_False; +} + +static Standard_Boolean IsObst(const ChFiDS_CommonPoint& CP, + const TopoDS_Vertex& Vref, + const ChFiDS_Map& VEMap) +{ + if(!CP.IsOnArc()) return Standard_False; + const TopoDS_Edge& E = CP.Arc(); + TopTools_MapOfShape DONE; + Standard_Integer prof = 4; + return !IsVois(E,Vref,VEMap,DONE,0,prof); +} + +//======================================================================= +//function : CompParam +//purpose : +// +//======================================================================= + +static void CompParam(Geom2dAdaptor_Curve Carc, + Handle(Geom2d_Curve) Ctg, + Standard_Real& parc, + Standard_Real& ptg, + const Standard_Real prefarc, + const Standard_Real preftg) +{ + Standard_Boolean found = 0; + //(1) It is checked if the provided parameters are good + // if pcurves have the same parameters as the spine. + gp_Pnt2d point = Carc.Value(prefarc); + Standard_Real distini = point.Distance(Ctg->Value(preftg)); + if (distini <= Precision::PConfusion()) { + parc = prefarc; + ptg = preftg; + found = Standard_True; + } + else { + //(2) Intersection +#ifdef DEB + cout<< "CompParam : bad intersection parameters"<<endl; +#endif + IntRes2d_IntersectionPoint int2d; + Geom2dInt_GInter Intersection; + Standard_Integer nbpt,nbseg; + Intersection.Perform(Geom2dAdaptor_Curve(Ctg),Carc, + Precision::PIntersection(), + Precision::PIntersection()); + + Standard_Real dist = Precision::Infinite(), p1, p2; + if (Intersection.IsDone()){ + if (!Intersection.IsEmpty()){ + nbseg = Intersection.NbSegments(); + if ( nbseg > 0 ){ +#ifdef DEB + cout<< "segments of intersection on the restrictions"<<endl; +#endif + } + nbpt = Intersection.NbPoints(); + for (Standard_Integer i = 1; i <= nbpt; i++) { + int2d = Intersection.Point(i); + p1 = int2d.ParamOnFirst(); + p2 = int2d.ParamOnSecond(); + if(Abs(prefarc - p2) < dist){ + ptg = p1; + parc = p2; + dist = Abs(prefarc - p2); + found = 1; + } + } + } + } + } + + if(!found){ + // (3) Projection... +#ifdef DEB + cout<<"CompParam : failed intersection PC, projection is created."<<endl; +#endif + parc = prefarc; + Geom2dAPI_ProjectPointOnCurve projector(point,Ctg); + + if(projector.NbPoints() == 0){ + // This happens in some cases when there is a vertex + // at the end of spine... + ptg = preftg; +#ifdef DEB + cout<<"CompParam : failed proj p2d/c2d, the extremity is taken!" <<endl; +#endif + } + else { + // It is checked if everything was calculated correctly (EDC402 C2) + if (projector.LowerDistance() < distini) + ptg = projector.LowerDistanceParameter(); + else ptg = preftg; + } + } +} + +//======================================================================= +//function : CompBlendPoint +//purpose : create BlendPoint corresponding to a tangency on Vertex +// pmn : 15/10/1997 : returns false, if there is no pcurve +//======================================================================= + +static Standard_Boolean CompBlendPoint(const TopoDS_Vertex& V, + const TopoDS_Edge& E, + const Standard_Real W, + const TopoDS_Face F1, + const TopoDS_Face F2, + Blend_Point& BP) +{ + gp_Pnt2d P1, P2; + gp_Pnt P3d; + Standard_Real param, f, l; + Handle(Geom2d_Curve) pc; + + P3d = BRep_Tool::Pnt(V); + param = BRep_Tool::Parameter(V,E,F1); + pc = BRep_Tool::CurveOnSurface(E,F1,f,l); + if (pc.IsNull()) return Standard_False; + P1 = pc->Value(param); + param = BRep_Tool::Parameter(V,E,F2); + pc = BRep_Tool::CurveOnSurface(E,F2,f,l); + if (pc.IsNull()) return Standard_False; + P2 = pc->Value(param); + BP.SetValue(P3d, P3d, W, P1.X(), P1.Y(), P2.X(), P2.Y()); + return Standard_True; +} + +//======================================================================= +//function : UpdateLine +//purpose : Updates extremities after a partial invalidation +//======================================================================= + +static void UpdateLine(Handle(BRepBlend_Line)& Line, + const Standard_Boolean isfirst) +{ + Standard_Real tguide, U, V; + if (isfirst) { + const Blend_Point& BP = Line->Point(1); + tguide = BP.Parameter(); + if (Line->StartPointOnFirst().ParameterOnGuide() < tguide) { + BRepBlend_Extremity BE; + BP.ParametersOnS1(U, V); + BE.SetValue(BP.PointOnS1(), U, V, Precision::Confusion()); + Line->SetStartPoints(BE, Line->StartPointOnSecond()); + } + if (Line->StartPointOnSecond().ParameterOnGuide() < tguide) { + BRepBlend_Extremity BE; + BP.ParametersOnS2(U, V); + BE.SetValue(BP.PointOnS2(), U, V, Precision::Confusion()); + Line->SetStartPoints(Line->StartPointOnFirst(), BE); + } + } + else { + const Blend_Point& BP = Line->Point(Line->NbPoints()); + tguide = BP.Parameter(); + if (Line->EndPointOnFirst().ParameterOnGuide() > tguide) { + BRepBlend_Extremity BE; + BP.ParametersOnS1(U, V); + BE.SetValue(BP.PointOnS1(), U, V, Precision::Confusion()); + Line->SetEndPoints(BE, Line->EndPointOnSecond()); + } + if (Line->EndPointOnSecond().ParameterOnGuide() > tguide) { + BRepBlend_Extremity BE; + BP.ParametersOnS2(U, V); + BE.SetValue(BP.PointOnS2(), U, V, Precision::Confusion()); + Line->SetEndPoints(Line->EndPointOnFirst(), BE); + } + } +} + +//======================================================================= +//function : CompleteData +//purpose : Calculates curves and CommonPoints from the data +// calculated by filling. +//======================================================================= + +Standard_Boolean ChFi3d_Builder::CompleteData +(Handle(ChFiDS_SurfData)& Data, + const Handle(Geom_Surface)& Surfcoin, + const Handle(Adaptor3d_HSurface)& S1, + const Handle(Geom2d_Curve)& PC1, + const Handle(Adaptor3d_HSurface)& S2, + const Handle(Geom2d_Curve)& PC2, + const TopAbs_Orientation Or, + const Standard_Boolean On1, + const Standard_Boolean Gd1, + const Standard_Boolean Gd2, + const Standard_Boolean Gf1, + const Standard_Boolean Gf2) +{ + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surfcoin,tolesp))); +#ifdef DRAW + ChFi3d_SettraceDRAWFIL(Standard_True); + if (ChFi3d_GettraceDRAWFIL()) { + IndexOfConge++; +// char name[100]; + char* name = new char[100]; + sprintf(name,"%s_%d","Surf",IndexOfConge); + DrawTrSurf::Set(name,Surfcoin); + } +#endif + + Standard_Real UFirst,ULast,VFirst,VLast; + Surfcoin->Bounds(UFirst,ULast,VFirst,VLast); + if(!Gd1) Data->ChangeVertexFirstOnS1().SetPoint(Surfcoin->Value(UFirst,VFirst)); + if(!Gd2) Data->ChangeVertexFirstOnS2().SetPoint(Surfcoin->Value(UFirst,VLast)); + if(!Gf1) Data->ChangeVertexLastOnS1().SetPoint(Surfcoin->Value(ULast,VFirst)); + if(!Gf2) Data->ChangeVertexLastOnS2().SetPoint(Surfcoin->Value(ULast,VLast)); + + //calculate curves side S1 + Handle(Geom_Curve) Crv3d1; + if(!PC1.IsNull()) Crv3d1= Surfcoin->VIso(VFirst); + gp_Pnt2d pd1(UFirst,VFirst), pf1(ULast,VFirst); + gp_Lin2d lfil1(pd1,gp_Dir2d(gp_Vec2d(pd1,pf1))); + Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1); + TopAbs_Orientation tra1 = TopAbs_FORWARD, orsurf = Or; + Standard_Real x,y,w = 0.5*(UFirst+ULast); + gp_Pnt p; + gp_Vec du,dv; + Handle(Geom2d_Curve) c2dtrim; + Standard_Real tolreached; + if(!PC1.IsNull()){ + Handle(GeomAdaptor_HCurve) hcS1 = new GeomAdaptor_HCurve(Crv3d1); + c2dtrim = new Geom2d_TrimmedCurve(PC1,UFirst,ULast); + ChFi3d_SameParameter(hcS1,c2dtrim,S1,tolapp3d,tolreached); + c2dtrim->Value(w).Coord(x,y); + S1->D1(x,y,p,du,dv); + gp_Vec nf = du.Crossed(dv); + Surfcoin->D1(w,VFirst,p,du,dv); + gp_Vec ns = du.Crossed(dv); + if(nf.Dot(ns) > 0.) tra1 = TopAbs_REVERSED; + else if(On1) orsurf = TopAbs::Reverse(orsurf); + } + Standard_Integer Index1OfCurve = + DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolreached)); + ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1(); + Fint1.SetFirstParameter(UFirst); + Fint1.SetLastParameter(ULast); + Fint1.SetInterference(Index1OfCurve,tra1,c2dtrim,PCurveOnSurf); + //calculate curves side S2 + Handle(Geom_Curve) Crv3d2; + if(!PC2.IsNull()) Crv3d2 = Surfcoin->VIso(VLast); + gp_Pnt2d pd2(UFirst,VLast), pf2(ULast,VLast); + gp_Lin2d lfil2(pd2,gp_Dir2d(gp_Vec2d(pd2,pf2))); + PCurveOnSurf = new Geom2d_Line(lfil2); + TopAbs_Orientation tra2 = TopAbs_FORWARD; + if(!PC2.IsNull()){ + Handle(GeomAdaptor_HCurve) hcS2 = new GeomAdaptor_HCurve(Crv3d2); + c2dtrim = new Geom2d_TrimmedCurve(PC2,UFirst,ULast); + ChFi3d_SameParameter(hcS2,c2dtrim,S2,tolapp3d,tolreached); + c2dtrim->Value(w).Coord(x,y); + S2->D1(x,y,p,du,dv); + gp_Vec np = du.Crossed(dv); + Surfcoin->D1(w,VLast,p,du,dv); + gp_Vec ns = du.Crossed(dv); + if(np.Dot(ns) < 0.) { + tra2 = TopAbs_REVERSED; + if(!On1) orsurf = TopAbs::Reverse(orsurf); + } + } + Standard_Integer Index2OfCurve = + DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolreached)); + ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2(); + Fint2.SetFirstParameter(UFirst); + Fint2.SetLastParameter(ULast); + Fint2.SetInterference(Index2OfCurve,tra2,c2dtrim,PCurveOnSurf); + Data->ChangeOrientation() = orsurf; + return Standard_True; +} + +//======================================================================= +//function : CompleteData +//purpose : Calculates the surface of curves and eventually +// CommonPoints from the data calculated in ComputeData. +// +// 11/08/1996 : Use of F(t) +// +//======================================================================= + +Standard_Boolean ChFi3d_Builder::CompleteData +(Handle(ChFiDS_SurfData)& Data, + Blend_Function& Func, + Handle(BRepBlend_Line)& lin, + const Handle(Adaptor3d_HSurface)& S1, + const Handle(Adaptor3d_HSurface)& S2, + const TopAbs_Orientation Or1, + const Standard_Boolean Gd1, + const Standard_Boolean Gd2, + const Standard_Boolean Gf1, + const Standard_Boolean Gf2, + const Standard_Boolean Reversed) +{ + Handle(BRepBlend_AppFunc) TheFunc + = new (BRepBlend_AppFunc)(lin, Func, tolapp3d, 1.e-5); + BRepBlend_AppSurface approx (TheFunc, + lin->Point(1).Parameter(), + lin->Point(lin->NbPoints()).Parameter(), + tolapp3d, 1.e-5, //tolapp2d, tolerance max + tolappangle, // Contact G1 + myConti); + if (!approx.IsDone()) { +#ifdef DEB + cout << "Approximation non faite !!!" << endl; +#endif + return Standard_False; + } +#ifdef DEB + approx.Dump(cout); +#endif + return StoreData( Data, approx, lin, S1, S2, Or1, Gd1, Gd2, Gf1, Gf2, Reversed); +} + + +//======================================================================= +//function : CompleteData +//purpose : New overload for functions surf/rst +// jlr le 28/07/97 branchement F(t) +//======================================================================= + +Standard_Boolean ChFi3d_Builder::CompleteData +(Handle(ChFiDS_SurfData)& Data, + Blend_SurfRstFunction& Func, + Handle(BRepBlend_Line)& lin, + const Handle(Adaptor3d_HSurface)& S1, + const Handle(Adaptor3d_HSurface)& S2, + const TopAbs_Orientation Or, + const Standard_Boolean Reversed) +{ + Handle(BRepBlend_AppFuncRst) TheFunc + = new (BRepBlend_AppFuncRst)(lin, Func, tolapp3d, 1.e-5); + BRepBlend_AppSurface approx (TheFunc, + lin->Point(1).Parameter(), + lin->Point(lin->NbPoints()).Parameter(), + tolapp3d, 1.e-5, //tolapp2d, tolerance max + tolappangle, // Contact G1 + myConti); + if (!approx.IsDone()) { +#ifdef DEB + cout << "Approximation is not done!" << endl; +#endif + return Standard_False; + } +#ifdef DEB + approx.Dump(cout); +#endif + + return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0,Reversed); +} + + + +//======================================================================= +//function : CompleteData +//purpose : New overload for functions rst/rst +// jlr le 28/07/97 branchement F(t) +//======================================================================= + +Standard_Boolean ChFi3d_Builder::CompleteData +(Handle(ChFiDS_SurfData)& Data, + Blend_RstRstFunction& Func, + Handle(BRepBlend_Line)& lin, + const Handle(Adaptor3d_HSurface)& S1, + const Handle(Adaptor3d_HSurface)& S2, + const TopAbs_Orientation Or) +{ + Handle(BRepBlend_AppFuncRstRst) TheFunc + = new (BRepBlend_AppFuncRstRst)(lin, Func, tolapp3d, 1.e-5); + BRepBlend_AppSurface approx (TheFunc, + lin->Point(1).Parameter(), + lin->Point(lin->NbPoints()).Parameter(), + tolapp3d, 1.e-5, //tolapp2d, tolerance max + tolappangle, // Contact G1 + myConti); + if (!approx.IsDone()) { +#ifdef DEB + cout << "Approximation non faite !!!" << endl; +#endif + return Standard_False; + } +#ifdef DEB + approx.Dump(cout); +#endif + + return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0); +} + + + + +//======================================================================= +//function : StoreData +//purpose : Copy of an approximation result in SurfData. +//======================================================================= + +Standard_Boolean ChFi3d_Builder::StoreData(Handle(ChFiDS_SurfData)& Data, + const AppBlend_Approx& approx, + const Handle(BRepBlend_Line)& lin, + const Handle(Adaptor3d_HSurface)& S1, + const Handle(Adaptor3d_HSurface)& S2, + const TopAbs_Orientation Or1, + const Standard_Boolean Gd1, + const Standard_Boolean Gd2, + const Standard_Boolean Gf1, + const Standard_Boolean Gf2, + const Standard_Boolean Reversed) +{ + // Small control tools. + static Handle(GeomAdaptor_HCurve) checkcurve; + if(checkcurve.IsNull()) checkcurve = new GeomAdaptor_HCurve(); + GeomAdaptor_Curve& chc = checkcurve->ChangeCurve(); + Standard_Real tolget3d, tolget2d, tolaux, tolC1, tolcheck; +#ifndef DEB + Standard_Real tolC2 = 0.; +#else + Standard_Real tolC2; +#endif + approx.TolReached(tolget3d, tolget2d); + tolaux = approx.TolCurveOnSurf(1); + tolC1 = tolget3d + tolaux; + if(!S2.IsNull()) { + tolaux = approx.TolCurveOnSurf(2); + tolC2 = tolget3d + tolaux; + } + + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + // By default parametric space is created using a square surface + // to be able to parameterize in U by # R*teta // a revoir lbo 29/08/97 + const TColStd_Array1OfReal& ku = approx.SurfUKnots(); + const TColStd_Array1OfReal& kv = approx.SurfVKnots(); + Standard_Real larg = (kv(kv.Upper())-kv(kv.Lower())); + TColStd_Array1OfReal& kku = *((TColStd_Array1OfReal*)((void*)&ku)); + BSplCLib::Reparametrize(0.,larg,kku); + Handle(Geom_BSplineSurface) Surf = + new Geom_BSplineSurface(approx.SurfPoles(),approx.SurfWeights(), + kku,kv, + approx.SurfUMults(),approx.SurfVMults(), + approx.UDegree(),approx.VDegree()); +// extension of the surface + + Standard_Real length1,length2; + length1=Data->FirstExtensionValue(); + length2=Data->LastExtensionValue(); + if (length1 > Precision::Confusion()) + GeomLib::ExtendSurfByLength(Surf,length1,1,Standard_False,Standard_False); + if (length2 > Precision::Confusion()) + GeomLib::ExtendSurfByLength(Surf,length2,1,Standard_False,Standard_True); + + Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surf,tolget3d))); + +#ifdef DRAW + ChFi3d_SettraceDRAWFIL(Standard_True); + if (ChFi3d_GettraceDRAWFIL()) { + IndexOfConge++; +// char name[100]; + char* name=new char[100]; + sprintf(name,"%s_%d","Surf",IndexOfConge); + DrawTrSurf::Set(name,Surf); + } +#endif + Standard_Real UFirst,ULast,VFirst,VLast,pppdeb,pppfin; + Surf->Bounds(UFirst,ULast,VFirst,VLast); + BRepAdaptor_Curve2d brc; + BRepAdaptor_Curve CArc; + Handle(BRepAdaptor_HSurface) + BS1 = Handle(BRepAdaptor_HSurface)::DownCast(S1); + Handle(BRepAdaptor_HSurface) + BS2 = Handle(BRepAdaptor_HSurface)::DownCast(S2); + Geom2dAPI_ProjectPointOnCurve projector; + + Standard_Real Uon1 = UFirst, Uon2 = ULast; + Standard_Integer ion1 = 1, ion2 = 2; + if(Reversed) { Uon1 = ULast; Uon2 = UFirst; ion1 = 2; ion2 = 1; } + + // The SurfData is filled in what concerns S1, + Handle(Geom_Curve) Crv3d1 = Surf->UIso(Uon1); + gp_Pnt2d pori1(Uon1,0.); + gp_Lin2d lfil1(pori1,gp::DY2d()); + Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1); + Handle(Geom2d_Curve) PCurveOnFace; + PCurveOnFace = new + Geom2d_BSplineCurve(approx.Curve2dPoles(ion1),approx.Curves2dKnots(), + approx.Curves2dMults(),approx.Curves2dDegree()); + + + Standard_Real par1=PCurveOnFace->FirstParameter(); + Standard_Real par2= PCurveOnFace->LastParameter(); + chc.Load(Crv3d1,par1,par2); + + if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S1,tolC1,tolcheck)){ +#ifdef DEB + cout<<"aaproximate tolerance under-valued : "<<tolC1<<" for "<<tolcheck<<endl; +#endif + tolC1 = tolcheck; + } + Standard_Integer Index1OfCurve = + DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolC1)); + + Standard_Real uarc,utg; + if(Gd1){ + TopoDS_Face forwfac = BS1->ChangeSurface().Face(); + forwfac.Orientation(TopAbs_FORWARD); + brc.Initialize(Data->VertexFirstOnS1().Arc(),forwfac); + ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS1(); + CArc.Initialize(V.Arc()); + CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter()); + tolcheck = CArc.Value(uarc).Distance(V.Point()); + V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc()); + pppdeb = utg; + } + else pppdeb = VFirst; + if(Gf1){ + TopoDS_Face forwfac = BS1->ChangeSurface().Face(); + forwfac.Orientation(TopAbs_FORWARD); + ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS1(); + brc.Initialize(V.Arc(),forwfac); + CArc.Initialize(V.Arc()); + CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter()); + tolcheck = CArc.Value(uarc).Distance(V.Point()); + V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc()); + pppfin = utg; + } + else pppfin = VLast; + ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1(); + Fint1.SetFirstParameter(pppdeb); + Fint1.SetLastParameter(pppfin); + TopAbs_Orientation TraOn1; + if(Reversed) TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS2()); + else TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS1()); + Fint1.SetInterference(Index1OfCurve,TraOn1,PCurveOnFace,PCurveOnSurf); + + // SurfData is filled in what concerns S2, + Handle(Geom_Curve) Crv3d2 = Surf->UIso(Uon2); + gp_Pnt2d pori2(Uon2,0.); + gp_Lin2d lfil2(pori2,gp::DY2d()); + PCurveOnSurf = new Geom2d_Line(lfil2); + if(!S2.IsNull()){ + PCurveOnFace = new Geom2d_BSplineCurve(approx.Curve2dPoles(ion2), + approx.Curves2dKnots(), + approx.Curves2dMults(), + approx.Curves2dDegree()); + chc.Load(Crv3d2,par1,par2); + if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S2,tolC2,tolcheck)){ +#ifdef DEB + cout<<"approximate tolerance under-evaluated : "<<tolC2<<" for "<<tolcheck<<endl; +#endif + tolC2 = tolcheck; + } + } + Standard_Integer Index2OfCurve = + DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolC2)); + if(Gd2){ + TopoDS_Face forwfac = BS2->ChangeSurface().Face(); + forwfac.Orientation(TopAbs_FORWARD); + brc.Initialize(Data->VertexFirstOnS2().Arc(),forwfac); + ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS2(); + CArc.Initialize(V.Arc()); + CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter()); + tolcheck = CArc.Value(uarc).Distance(V.Point()); + V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc()); + pppdeb = utg; + } + else pppdeb = VFirst; + if(Gf2){ + TopoDS_Face forwfac = BS2->ChangeSurface().Face(); + forwfac.Orientation(TopAbs_FORWARD); + brc.Initialize(Data->VertexLastOnS2().Arc(),forwfac); + ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS2(); + CArc.Initialize(V.Arc()); + CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter()); + tolcheck = CArc.Value(uarc).Distance(V.Point()); + V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc()); + pppfin = utg; + } + else pppfin = VLast; + ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2(); + Fint2.SetFirstParameter(pppdeb); + Fint2.SetLastParameter(pppfin); + if(!S2.IsNull()){ + TopAbs_Orientation TraOn2; + if(Reversed) TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS1()); + else TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS2()); + Fint2.SetInterference(Index2OfCurve,TraOn2,PCurveOnFace,PCurveOnSurf); + } + else { + Handle(Geom2d_Curve) bidpc; + Fint2.SetInterference + (Index2OfCurve,TopAbs_FORWARD,bidpc,PCurveOnSurf); + } + + // the orientation of the fillet in relation to the faces is evaluated, + + Handle(Adaptor3d_HSurface) Sref = S1; + PCurveOnFace = Fint1.PCurveOnFace(); + if(Reversed){ Sref = S2; PCurveOnFace = Fint2.PCurveOnFace(); } + +// Modified by skv - Wed Jun 9 17:16:26 2004 OCC5898 Begin +// gp_Pnt2d PUV = PCurveOnFace->Value((VFirst+VLast)/2.); +// gp_Pnt P; +// gp_Vec Du1,Du2,Dv1,Dv2; +// Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1); +// Du1.Cross(Dv1); +// if (Or1 == TopAbs_REVERSED) Du1.Reverse(); +// Surf->D1(UFirst,(VFirst+VLast)/2.,P,Du2,Dv2); +// Du2.Cross(Dv2); +// if (Du1.Dot(Du2)>0) Data->ChangeOrientation() = TopAbs_FORWARD; +// else Data->ChangeOrientation() = TopAbs_REVERSED; + + Standard_Real aDelta = VLast - VFirst; + Standard_Integer aDenom = 2; + + while (Standard_True) { + Standard_Real aDeltav = aDelta/aDenom; + Standard_Real aParam = VFirst + aDeltav; + gp_Pnt2d PUV = PCurveOnFace->Value(aParam); + gp_Pnt P; + gp_Vec Du1,Du2,Dv1,Dv2; + + Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1); + Du1.Cross(Dv1); + + if (Or1 == TopAbs_REVERSED) + Du1.Reverse(); + + Surf->D1(UFirst, aParam, P, Du2, Dv2); + Du2.Cross(Dv2); + + if (Du1.Magnitude() <= tolget3d || + Du2.Magnitude() <= tolget3d) { + aDenom++; + + if (Abs(aDeltav) <= tolget2d) + return Standard_False; + + continue; + } + + if (Du1.Dot(Du2)>0) + Data->ChangeOrientation() = TopAbs_FORWARD; + else + Data->ChangeOrientation() = TopAbs_REVERSED; + + break; + } +// Modified by skv - Wed Jun 9 17:16:26 2004 OCC5898 End + + if(!Gd1 && !S1.IsNull()) + ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(), + Standard_True, Data->ChangeVertex(1,ion1),tolC1); + if(!Gf1 && !S1.IsNull()) + ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(), + Standard_False,Data->ChangeVertex(0,ion1),tolC1); + if(!Gd2 && !S2.IsNull()) + ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(), + Standard_True, Data->ChangeVertex(1,ion2),tolC2); + if(!Gf2 && !S2.IsNull()) + ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(), + Standard_False, Data->ChangeVertex(0,ion2),tolC2); + // Parameters on ElSpine + Standard_Integer nbp = lin->NbPoints(); + Data->FirstSpineParam(lin->Point(1).Parameter()); + Data->LastSpineParam(lin->Point(nbp).Parameter()); + return Standard_True; +} + + + +//======================================================================= +//function : ComputeData +//purpose : Head of the path edge/face for the bypass of obstacle. +//======================================================================= + +Standard_Boolean ChFi3d_Builder::ComputeData +(Handle(ChFiDS_SurfData)& Data, + const Handle(ChFiDS_HElSpine)& HGuide, + Handle(BRepBlend_Line)& Lin, + const Handle(Adaptor3d_HSurface)& S1, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(Adaptor3d_HSurface)& S2, + const Handle(Adaptor2d_HCurve2d)& PC2, + const Handle(Adaptor3d_TopolTool)& I2, + Standard_Boolean& Decroch, + Blend_SurfRstFunction& Func, + Blend_FuncInv& FInv, + Blend_SurfPointFuncInv& FInvP, + Blend_SurfCurvFuncInv& FInvC, + const Standard_Real PFirst, + const Standard_Real MaxStep, + const Standard_Real Fleche, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const math_Vector& Soldep, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecP, + const Standard_Boolean RecS, + const Standard_Boolean RecRst) +{ + BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2); + + Data->FirstExtensionValue(0); + Data->LastExtensionValue(0); + + Standard_Boolean reverse = (!Forward || Inside); + Standard_Real SpFirst = HGuide->FirstParameter(); + Standard_Real SpLast = HGuide->LastParameter(); + Standard_Real Target = SpLast; + if(reverse) Target = SpFirst; + Standard_Real Targetsov = Target; + + Standard_Real MS = MaxStep; + Standard_Integer again = 0; + Standard_Integer nbptmin = 3; //jlr +#ifndef DEB + Standard_Integer Nbpnt = 0; +#else + Standard_Integer Nbpnt; +#endif + // the initial solution is reframed if necessary. + math_Vector ParSol(1,3); + Standard_Real NewFirst = PFirst; + if(RecP || RecS || RecRst){ + if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep, + tolesp,TolGuide,RecRst,RecP,RecS, + NewFirst,ParSol)){ +#ifdef DEB + cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<endl; +#endif + return Standard_False; + } + } + else { + ParSol = Soldep; + } + + while (again < 2){ + TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last, + MS,TolGuide,ParSol,tolesp,Fleche,Appro); + + if (!TheWalk.IsDone()) { +#ifdef DEB + cout << "Path not created" << endl; +#endif + return Standard_False; + } + + if (reverse) { + if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) { +#ifdef DEB + cout << "Not completed" << endl; +#endif + } + } + + + Lin = TheWalk.Line(); + Nbpnt = Lin->NbPoints(); + if (Nbpnt <= 1 && again == 0) { + again++; +#ifdef DEB + cout <<"one point of the path MS/50 is attempted."<<endl; +#endif + MS = MS/50.; Target = Targetsov; + } + else if (Nbpnt<=nbptmin && again == 0) { + again++; +#ifdef DEB + cout <<"Number of points is too small, the step is reduced"<<endl; +#endif + Standard_Real u1 = Lin->Point(1).Parameter(); + Standard_Real u2 = Lin->Point(Nbpnt).Parameter(); + MS = (u2-u1)/(nbptmin+1.0); +// cout << " MS : " << MS << " u1 : " << u1 << " u2 : " << u2 << " nbptmin : " << nbptmin << endl; + Target = Targetsov; + } + else if(Nbpnt<=nbptmin){ +#ifdef DEB + cout <<"Number of points is still too small, quit"<<endl; +#endif + return Standard_False; + } + else { + again = 2; + } + } +#ifdef DRAW + ChFi3d_SettraceDRAWWALK(Standard_True); + if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True); +#endif + if(Forward) Decroch = TheWalk.DecrochEnd(); + else Decroch = TheWalk.DecrochStart(); + Last = Lin->Point(Nbpnt).Parameter(); + First = Lin->Point(1).Parameter(); + return Standard_True; +} + + +//======================================================================= +//function : ComputeData +//purpose : Heading of the path edge/edge for the bypass of obstacle. +//======================================================================= + +Standard_Boolean ChFi3d_Builder::ComputeData +(Handle(ChFiDS_SurfData)& Data, + const Handle(ChFiDS_HElSpine)& HGuide, + Handle(BRepBlend_Line)& Lin, + const Handle(Adaptor3d_HSurface)& S1, + const Handle(Adaptor2d_HCurve2d)& PC1, + const Handle(Adaptor3d_TopolTool)& I1, + Standard_Boolean& Decroch1, + const Handle(Adaptor3d_HSurface)& S2, + const Handle(Adaptor2d_HCurve2d)& PC2, + const Handle(Adaptor3d_TopolTool)& I2, + Standard_Boolean& Decroch2, + Blend_RstRstFunction& Func, + Blend_SurfCurvFuncInv& FInv1, + Blend_CurvPointFuncInv& FInvP1, + Blend_SurfCurvFuncInv& FInv2, + Blend_CurvPointFuncInv& FInvP2, + const Standard_Real PFirst, + const Standard_Real MaxStep, + const Standard_Real Fleche, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const math_Vector& Soldep, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecP1, + const Standard_Boolean RecRst1, + const Standard_Boolean RecP2, + const Standard_Boolean RecRst2) +{ + BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2); + + Data->FirstExtensionValue(0); + Data->LastExtensionValue(0); + + Standard_Boolean reverse = (!Forward || Inside); + Standard_Real SpFirst = HGuide->FirstParameter(); + Standard_Real SpLast = HGuide->LastParameter(); + Standard_Real Target = SpLast; + if(reverse) Target = SpFirst; + Standard_Real Targetsov = Target; + + Standard_Real MS = MaxStep; + Standard_Integer again = 0; + Standard_Integer nbptmin = 3; //jlr +#ifndef DEB + Standard_Integer Nbpnt = 0; +#else + Standard_Integer Nbpnt; +#endif + // the initial solution is reframed if necessary. + math_Vector ParSol(1,2); + Standard_Real NewFirst = PFirst; + if (RecP1 || RecRst1 || RecP2 || RecRst2) { + if (!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep, + tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2, + NewFirst, ParSol)){ +#ifdef DEB + cout<<"ChFi3d_Builder::ComputeData : fail calculation first section"<<endl; +#endif + return Standard_False; + } + } + else { + ParSol = Soldep; + } + + while (again < 2){ + TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last, + MS, TolGuide, ParSol, tolesp, Fleche, Appro); + + if (!TheWalk.IsDone()) { +#ifdef DEB + cout << "Path not done" << endl; +#endif + return Standard_False; + } + + if (reverse) { + if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) { +#ifdef DEB + cout << "Not completed" << endl; +#endif + } + } + + + Lin = TheWalk.Line(); + Nbpnt = Lin->NbPoints(); + if (Nbpnt <= 1 && again == 0) { + again++; +#ifdef DEB + cout <<"one point of path MS/50 is attempted."<<endl; +#endif + MS = MS/50.; Target = Targetsov; + } + else if (Nbpnt<=nbptmin && again == 0) { + again++; +#ifdef DEB + cout <<"Number of points is too small, the step is reduced"<<endl; +#endif + Standard_Real u1 = Lin->Point(1).Parameter(); + Standard_Real u2 = Lin->Point(Nbpnt).Parameter(); + MS = (u2-u1)/(nbptmin+1); + Target = Targetsov; + } + else if(Nbpnt<=nbptmin){ +#ifdef DEB + cout <<"Number of points is still too small, quit"<<endl; +#endif + return Standard_False; + } + else { + again = 2; + } + } +#ifdef DRAW + ChFi3d_SettraceDRAWWALK(Standard_True); + if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True); +#endif + if (Forward) { + Decroch1 = TheWalk.Decroch1End(); + Decroch2 = TheWalk.Decroch2End(); + } + else { + Decroch1 = TheWalk.Decroch1Start(); + Decroch2 = TheWalk.Decroch2Start(); + } + Last = Lin->Point(Nbpnt).Parameter(); + First = Lin->Point(1).Parameter(); + return Standard_True; +} + + +//======================================================================= +//function : SimulData +//purpose : Heading of the path edge/face for the bypass of obstacle in simulation mode. +//======================================================================= + +Standard_Boolean ChFi3d_Builder::SimulData +(Handle(ChFiDS_SurfData)& /*Data*/, + const Handle(ChFiDS_HElSpine)& HGuide, + Handle(BRepBlend_Line)& Lin, + const Handle(Adaptor3d_HSurface)& S1, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(Adaptor3d_HSurface)& S2, + const Handle(Adaptor2d_HCurve2d)& PC2, + const Handle(Adaptor3d_TopolTool)& I2, + Standard_Boolean& Decroch, + Blend_SurfRstFunction& Func, + Blend_FuncInv& FInv, + Blend_SurfPointFuncInv& FInvP, + Blend_SurfCurvFuncInv& FInvC, + const Standard_Real PFirst, + const Standard_Real MaxStep, + const Standard_Real Fleche, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const math_Vector& Soldep, + const Standard_Integer NbSecMin, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecP, + const Standard_Boolean RecS, + const Standard_Boolean RecRst) +{ + BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2); + + Standard_Boolean reverse = (!Forward || Inside); + Standard_Real SpFirst = HGuide->FirstParameter(); + Standard_Real SpLast = HGuide->LastParameter(); + Standard_Real Target = SpLast; + if(reverse) Target = SpFirst; + Standard_Real Targetsov = Target; + + Standard_Real MS = MaxStep; + Standard_Integer again = 0; +#ifndef DEB + Standard_Integer Nbpnt = 0; +#else + Standard_Integer Nbpnt; +#endif + // the starting solution is reframed if needed. + math_Vector ParSol(1,3); + Standard_Real NewFirst = PFirst; + if(RecP || RecS || RecRst){ + if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep, + tolesp,TolGuide,RecRst,RecP,RecS, + NewFirst,ParSol)){ +#ifdef DEB + + cout<<"ChFi3d_Builder::SimulData : fail calculate first section"<<endl; +#endif + return Standard_False; + } + } + else { + ParSol = Soldep; + } + + while (again < 2){ + TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last, + MS,TolGuide,ParSol,tolesp,Fleche,Appro); + if (!TheWalk.IsDone()) { +#ifdef DEB + cout << "Path not done" << endl; +#endif + return Standard_False; + } + if (reverse) { + if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) { +#ifdef DEB + cout << "Not completed" << endl; +#endif + } + } + Lin = TheWalk.Line(); + Nbpnt = Lin->NbPoints(); + if (Nbpnt <= 1 && again == 0) { + again++; +#ifdef DEB + cout <<"one point of path MS/50 is attempted."<<endl; +#endif + MS = MS/50.; Target = Targetsov; + } + else if (Nbpnt <= NbSecMin && again == 0) { + again++; +#ifdef DEB + cout <<"Number of points is too small, the step is reduced"<<endl; +#endif + Standard_Real u1 = Lin->Point(1).Parameter(); + Standard_Real u2 = Lin->Point(Nbpnt).Parameter(); + MS = (u2-u1)/(NbSecMin+1); + Target = Targetsov; + } + else if(Nbpnt<=NbSecMin){ +#ifdef DEB + cout <<"Number of points is still too small, quit"<<endl; +#endif + return Standard_False; + } + else { + again = 2; + } + } +#ifdef DRAW + ChFi3d_SettraceDRAWWALK(Standard_True); + if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True); +#endif + if(Forward) Decroch = TheWalk.DecrochEnd(); + else Decroch = TheWalk.DecrochStart(); + Last = Lin->Point(Nbpnt).Parameter(); + First = Lin->Point(1).Parameter(); + return Standard_True; +} + + +//======================================================================= +//function : SimulData +//purpose : Heading of path edge/edge for the bypass +// of obstacle in simulation mode. +//======================================================================= + +Standard_Boolean ChFi3d_Builder::SimulData +(Handle(ChFiDS_SurfData)& /*Data*/, + const Handle(ChFiDS_HElSpine)& HGuide, + Handle(BRepBlend_Line)& Lin, + const Handle(Adaptor3d_HSurface)& S1, + const Handle(Adaptor2d_HCurve2d)& PC1, + const Handle(Adaptor3d_TopolTool)& I1, + Standard_Boolean& Decroch1, + const Handle(Adaptor3d_HSurface)& S2, + const Handle(Adaptor2d_HCurve2d)& PC2, + const Handle(Adaptor3d_TopolTool)& I2, + Standard_Boolean& Decroch2, + Blend_RstRstFunction& Func, + Blend_SurfCurvFuncInv& FInv1, + Blend_CurvPointFuncInv& FInvP1, + Blend_SurfCurvFuncInv& FInv2, + Blend_CurvPointFuncInv& FInvP2, + const Standard_Real PFirst, + const Standard_Real MaxStep, + const Standard_Real Fleche, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const math_Vector& Soldep, + const Standard_Integer NbSecMin, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecP1, + const Standard_Boolean RecRst1, + const Standard_Boolean RecP2, + const Standard_Boolean RecRst2) +{ + BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2); + + Standard_Boolean reverse = (!Forward || Inside); + Standard_Real SpFirst = HGuide->FirstParameter(); + Standard_Real SpLast = HGuide->LastParameter(); + Standard_Real Target = SpLast; + if(reverse) Target = SpFirst; + Standard_Real Targetsov = Target; + + Standard_Real MS = MaxStep; + Standard_Integer again = 0; +#ifndef DEB + Standard_Integer Nbpnt = 0; +#else + Standard_Integer Nbpnt; +#endif + // The initial solution is reframed if necessary. + math_Vector ParSol(1,2); + Standard_Real NewFirst = PFirst; + if (RecP1 || RecRst1 || RecP2 || RecRst2) { + if(!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep, + tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2, + NewFirst,ParSol)){ +#ifdef DEB + + cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<endl; +#endif + return Standard_False; + } + } + else { + ParSol = Soldep; + } + + while (again < 2){ + TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last, + MS, TolGuide, ParSol, tolesp, Fleche, Appro); + if (!TheWalk.IsDone()) { +#ifdef DEB + cout << "Path not created" << endl; +#endif + return Standard_False; + } + if (reverse) { + if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) { +#ifdef DEB + cout << "Not completed" << endl; +#endif + } + } + Lin = TheWalk.Line(); + Nbpnt = Lin->NbPoints(); + if (Nbpnt <= 1 && again == 0) { + again++; +#ifdef DEB + cout <<"only one point of path MS/50 is attempted."<<endl; +#endif + MS = MS/50.; Target = Targetsov; + } + else if (Nbpnt <= NbSecMin && again == 0) { + again++; +#ifdef DEB + cout <<"Number of points is too small, the step is reduced"<<endl; +#endif + Standard_Real u1 = Lin->Point(1).Parameter(); + Standard_Real u2 = Lin->Point(Nbpnt).Parameter(); + MS = (u2-u1)/(NbSecMin+1); + Target = Targetsov; + } + else if(Nbpnt<=NbSecMin){ +#ifdef DEB + cout <<"Number of points is still too small, quit"<<endl; +#endif + return Standard_False; + } + else { + again = 2; + } + } +#ifdef DRAW + if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True); +#endif + if (Forward) { + Decroch1 = TheWalk.Decroch1End(); + Decroch2 = TheWalk.Decroch2End(); + } + else { + Decroch1 = TheWalk.Decroch1Start(); + Decroch2 = TheWalk.Decroch2Start(); + } + + Last = Lin->Point(Nbpnt).Parameter(); + First = Lin->Point(1).Parameter(); + return Standard_True; +} + + + + +//======================================================================= +//function : ComputeData +//purpose : Construction of elementary fillet by path. +// +//======================================================================= + +Standard_Boolean ChFi3d_Builder::ComputeData +(Handle(ChFiDS_SurfData)& Data, + const Handle(ChFiDS_HElSpine)& HGuide, + const Handle(ChFiDS_Spine)& Spine, + Handle(BRepBlend_Line)& Lin, + const Handle(Adaptor3d_HSurface)& S1, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(Adaptor3d_HSurface)& S2, + const Handle(Adaptor3d_TopolTool)& I2, + Blend_Function& Func, + Blend_FuncInv& FInv, + const Standard_Real PFirst, + const Standard_Real MaxStep, + const Standard_Real Fleche, + const Standard_Real tolguide, + Standard_Real& First, + Standard_Real& Last, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const math_Vector& Soldep, + Standard_Boolean& intf, + Standard_Boolean& intl, + Standard_Boolean& Gd1, + Standard_Boolean& Gd2, + Standard_Boolean& Gf1, + Standard_Boolean& Gf2, + const Standard_Boolean RecOnS1, + const Standard_Boolean RecOnS2) +{ + //The extrensions are created in case of output of two domains + //directly and not by path ( too hasardous ). + Data->FirstExtensionValue(0); + Data-> LastExtensionValue(0); + + //The eventual faces are restored to test the jump of edge. + TopoDS_Face F1, F2; + Handle(BRepAdaptor_HSurface) HS = Handle(BRepAdaptor_HSurface)::DownCast(S1); + if(!HS.IsNull()) F1 = HS->ChangeSurface().Face(); + HS = Handle(BRepAdaptor_HSurface)::DownCast(S2); + if(!HS.IsNull()) F2 = HS->ChangeSurface().Face(); + + // Path framing variables + Standard_Real TolGuide=tolguide, TolEsp = tolesp; + Standard_Integer nbptmin = 4; + + BRepBlend_Walking TheWalk(S1,S2,I1,I2); + + //Start of removal, 2D path controls + //that qui s'accomodent mal des surfaces a parametrages non homogenes + //en u et en v are extinguished. + TheWalk.Check2d(0); + + Standard_Real MS = MaxStep; + Standard_Integer Nbpnt; + Standard_Real SpFirst = HGuide->FirstParameter(); + Standard_Real SpLast = HGuide->LastParameter(); + + // When the start point is inside, the path goes first to the left + // to determine the Last for the periodicals. + Standard_Boolean reverse = (!Forward || Inside); + Standard_Real Target; + if(reverse){ + Target = SpFirst; + if(!intf) Target = Last; + } + else{ + Target = SpLast + Abs(SpLast); + if(!intl) Target = Last; + } + + // In case if the singularity is pre-determined, + // the path is indicated. + if (!Spine.IsNull()){ + if (Spine->IsTangencyExtremity(Standard_True)) { + TopoDS_Vertex V = Spine->FirstVertex(); + TopoDS_Edge E = Spine->Edges(1); + Standard_Real param = Spine->FirstParameter(); + Blend_Point BP; + if (CompBlendPoint(V, E, param, F1, F2, BP)) { + math_Vector vec(1,4); + BP.ParametersOnS1(vec(1),vec(2)); + BP.ParametersOnS2(vec(3),vec(4)); + Func.Set(param); + if (Func.IsSolution(vec, tolesp)) { + TheWalk.AddSingularPoint(BP); + } + } + } + if (Spine->IsTangencyExtremity(Standard_False)) { + TopoDS_Vertex V = Spine->LastVertex(); + TopoDS_Edge E = Spine->Edges( Spine->NbEdges()); + Standard_Real param = Spine->LastParameter(); + Blend_Point BP; + if (CompBlendPoint(V, E, param, F1, F2, BP)) { + math_Vector vec(1,4); + BP.ParametersOnS1(vec(1),vec(2)); + BP.ParametersOnS2(vec(3),vec(4)); + Func.Set(param); + if (Func.IsSolution(vec, tolesp)) { + TheWalk.AddSingularPoint(BP); + } + } + } + } + + //The starting solution is reframed if necessary. + //**********************************************// + math_Vector ParSol(1,4); + Standard_Real NewFirst = PFirst; + if(RecOnS1 || RecOnS2){ + if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep, + tolesp,TolGuide,RecOnS1,RecOnS2, + NewFirst,ParSol)){ +#ifdef DEB + cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<endl; +#endif + return Standard_False; + } + } + else { + ParSol = Soldep; + } + + //First the valid part is calculate, without caring for the extensions. + //******************************************************************// + Standard_Integer again = 0; + Standard_Boolean tchernobyl = 0; +#ifndef DEB + Standard_Real u1sov = 0., u2sov = 0.; +#else + Standard_Real u1sov, u2sov; +#endif + TopoDS_Face bif; + //Max step is relevant, but too great, the vector is required to detect + //the twists. + if( (Abs(Last-First) <= MS * 5.) && + (Abs(Last-First) >= 0.01*Abs(NewFirst-Target)) ){ + MS = Abs(Last-First)*0.2; + } + + while(again < 3){ + //Path. + if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide; + else { + if (5*TolGuide > MS) TolGuide = MS/5; + if (5*TolEsp > MS) TolEsp = MS/5; + } + TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide, + ParSol,TolEsp,Fleche,Appro); + if (!TheWalk.IsDone()) { +#ifdef DEB + cout << "Path is not created" << endl; +#endif + return Standard_False; + } + Lin = TheWalk.Line(); + if(HGuide->IsPeriodic() && Inside) { + SpFirst = Lin->Point(1).Parameter(); + SpLast = SpFirst + HGuide->Period(); + HGuide->ChangeCurve().FirstParameter(SpFirst); + HGuide->ChangeCurve().LastParameter (SpLast ); + HGuide->ChangeCurve().SetOrigin(SpFirst); + } + Standard_Boolean complmnt = Standard_True; + if (Inside) complmnt = TheWalk.Complete(Func,FInv,SpLast); + if(!complmnt){ +#ifdef DEB + cout << "Not completed" << endl; +#endif + return Standard_False; + } + + //The result is controlled using two criterions : + //- if there is enough points, + //- if one has gone far enough. + Nbpnt = Lin->NbPoints(); + if (Nbpnt == 0){ +#ifdef DEB + cout <<"0 point of path, quit."<<endl; +#endif + return Standard_False; + } + Standard_Real fpointpar = Lin->Point(1).Parameter(); + Standard_Real lpointpar = Lin->Point(Nbpnt).Parameter(); + + Standard_Real factor = 1./(nbptmin + 1); + Standard_Boolean okdeb = (Forward && !Inside); + Standard_Boolean okfin = (!Forward && !Inside); + if(!okdeb){ + Standard_Integer narc1 = Lin->StartPointOnFirst().NbPointOnRst(); + Standard_Integer narc2 = Lin->StartPointOnSecond().NbPointOnRst(); + okdeb = (narc1 > 0 || narc2 > 0 || (fpointpar-First) < 10*TolGuide); + } + if(!okfin){ + Standard_Integer narc1 = Lin->EndPointOnFirst().NbPointOnRst(); + Standard_Integer narc2 = Lin->EndPointOnSecond().NbPointOnRst(); + okfin = (narc1 > 0 || narc2 > 0 || (Last-lpointpar) < 10*TolGuide); + } + if(!okdeb || !okfin || Nbpnt == 1){ + //It drags, the controls are extended, it is expected to evaluate a + //satisfactory maximum step. If it already done, quit. + if(tchernobyl){ +#ifdef DEB + cout <<"If it drags without control, quit."<<endl; +#endif + return Standard_False; + } + tchernobyl = Standard_True; + TheWalk.Check(0); + if (Nbpnt == 1){ +#ifdef DEB + cout <<"only one point of path MS/100 is attempted"<<endl; + cout <<"and the controls are extended."<<endl; +#endif + MS *= 0.01; + } + else{ +#ifdef DEB + cout <<"It drags, the controls are extended."<<endl; +#endif + MS = (lpointpar-fpointpar)/Nbpnt; //EvalStep(Lin); + } + } + else if (Nbpnt < nbptmin){ + if(again == 0){ +#ifdef DEB + cout <<"Number of points is too small, the step is reduced"<<endl; +#endif + u1sov = fpointpar; + u2sov = lpointpar; + MS = (lpointpar - fpointpar) * factor; + } + else if(again == 1){ + if(Abs(fpointpar-u1sov)>=TolGuide || + Abs(lpointpar-u2sov)>=TolGuide){ +#ifdef DEB + cout <<"Number of points is still too small, the step is reduced"<<endl; +#endif + MS = (lpointpar - fpointpar) * factor; + } + else{ +#ifdef DEB + cout <<"Number of points is still too small, quit"<<endl; +#endif + return Standard_False; + } + } + again++; + } + else { + again = 3; + } + } + + if(TheWalk.TwistOnS1()){ + Data->TwistOnS1(Standard_True); +#ifdef DEB + cout<<"Path completed, but TWIST on S1"<<endl; +#endif + } + if(TheWalk.TwistOnS2()){ + Data->TwistOnS2(Standard_True); +#ifdef DEB + cout<<"Parh completed, but TWIST on S2"<<endl; +#endif + } + + + //Here there is a more or less presentable result + //however it covers a the minimum zone. + //The extensions are targeted. + //*****************************// + + Gd1 = Gd2 = Gf1 = Gf2 = Standard_False; + + Standard_Boolean unseulsuffitdeb = (intf >= 2); + Standard_Boolean unseulsuffitfin = (intl >= 2); + Standard_Boolean noproldeb = (intf >= 3); + Standard_Boolean noprolfin = (intl >= 3); + + Standard_Real Rab = 0.03*(SpLast-SpFirst); + + Standard_Boolean debarc1 = 0, debarc2 = 0; + Standard_Boolean debcas1 = 0, debcas2 = 0; + Standard_Boolean debobst1 = 0, debobst2 = 0; + + Standard_Boolean finarc1 = 0, finarc2 = 0; + Standard_Boolean fincas1 = 0, fincas2 = 0; + Standard_Boolean finobst1 = 0, finobst2 = 0; + + Standard_Integer narc1, narc2; + + Standard_Boolean backwContinueFailed = Standard_False; // eap + if(reverse && intf) { + narc1 = Lin->StartPointOnFirst().NbPointOnRst(); + narc2 = Lin->StartPointOnSecond().NbPointOnRst(); + if(narc1 != 0) { + ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(), + Standard_True, Data->ChangeVertexFirstOnS1(),tolesp); + debarc1 = Standard_True; + if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){ + //It is checked if there is not an obstacle. + debcas1 = Standard_True; + if(!Spine.IsNull()){ + if(Spine->IsPeriodic()){ + debobst1 = 1; + } + else{ + debobst1 = IsObst(Data->VertexFirstOnS1(), + Spine->FirstVertex(),myVEMap); + } + } + } + } + if(narc2 != 0){ + ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(), + Standard_True, Data->ChangeVertexFirstOnS2(),tolesp); + debarc2 = Standard_True; + if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){ + //It is checked if it is not an obstacle. + debcas2 = Standard_True; + if(!Spine.IsNull()){ + if(Spine->IsPeriodic()){ + debobst2 = 1; + } + else{ + debobst2 = IsObst(Data->VertexFirstOnS2(), + Spine->FirstVertex(),myVEMap); + } + } + } + } + Standard_Boolean oncontinue = !noproldeb && (narc1 != 0 || narc2 != 0); + if(debobst1 || debobst2) oncontinue = Standard_False; + else if(debcas1 && debcas2) oncontinue = Standard_False; + else if((!debcas1 && debarc1) || (!debcas2 && debarc2)) oncontinue = Standard_False; + + if(oncontinue) { + TheWalk.ClassificationOnS1(!debarc1); + TheWalk.ClassificationOnS2(!debarc2); + TheWalk.Check2d(Standard_True); // It should be strict (PMN) + TheWalk.Continu(Func,FInv,Target); + TheWalk.ClassificationOnS1(Standard_True); + TheWalk.ClassificationOnS2(Standard_True); + TheWalk.Check2d(Standard_False); + narc1 = Lin->StartPointOnFirst().NbPointOnRst(); + narc2 = Lin->StartPointOnSecond().NbPointOnRst(); +// modified by eap Fri Feb 8 11:43:48 2002 ___BEGIN___ + if(!debarc1) + if (narc1 == 0) + backwContinueFailed = Lin->StartPointOnFirst().ParameterOnGuide() > Target; + else { + ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(), + Standard_True, Data->ChangeVertexFirstOnS1(),tolesp); + debarc1 = Standard_True; + if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){ + //It is checked if it is not an obstacle. + debcas1 = Standard_True; +// if(!Spine.IsNull()) { +// if(Spine->IsPeriodic()){ +// debobst1 = 1; +// } +// else{ +// debobst1 = IsObst(Data->VertexFirstOnS1(), +// Spine->FirstVertex(),myVEMap); +// } +// } + } + } + if(!debarc2) + if (narc2 == 0) + backwContinueFailed = Lin->StartPointOnSecond().ParameterOnGuide() > Target; + else { + ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(), + Standard_True, Data->ChangeVertexFirstOnS2(),tolesp); + debarc2 = Standard_True; + if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){ + //It is checked if it is not an obstacle. + debcas2 = Standard_True; +// if(!Spine.IsNull()){ +// if(Spine->IsPeriodic()){ +// debobst2 = 1; +// } +// else{ +// debobst2 = IsObst(Data->VertexFirstOnS2(), +// Spine->FirstVertex(),myVEMap); +// } +// } + } + } + if (backwContinueFailed) { + // if we leave backwContinueFailed as is, we will stop in this direction + // but we are to continue if there are no more faces on the side with arc + // check this condition + const ChFiDS_CommonPoint& aCP + = debarc1 ? Data->VertexFirstOnS1() : Data->VertexFirstOnS2(); + if (aCP.IsOnArc() && bif.IsNull()) + backwContinueFailed = Standard_False; + } + } + } + Standard_Boolean forwContinueFailed = Standard_False; +// modified by eap Fri Feb 8 11:44:11 2002 ___END___ + if(Forward && intl) { + Target = SpLast; + narc1 = Lin->EndPointOnFirst().NbPointOnRst(); + narc2 = Lin->EndPointOnSecond().NbPointOnRst(); + if(narc1 != 0){ + ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(), + Standard_False, Data->ChangeVertexLastOnS1(),tolesp); + finarc1 = Standard_True; + if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){ + //It is checked if it is not an obstacle. + fincas1 = Standard_True; + if(!Spine.IsNull()){ + finobst1 = IsObst(Data->VertexLastOnS1(), + Spine->LastVertex(),myVEMap); + } + } + } + if(narc2 != 0){ + ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(), + Standard_False, Data->ChangeVertexLastOnS2(),tolesp); + finarc2 = Standard_True; + if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){ + //It is checked if it is not an obstacle. + fincas2 = Standard_True; + if(!Spine.IsNull()){ + finobst2 = IsObst(Data->VertexLastOnS2(), + Spine->LastVertex(),myVEMap); + } + } + } + Standard_Boolean oncontinue = !noprolfin && (narc1 != 0 || narc2 != 0); + if(finobst1 || finobst2) oncontinue = Standard_False; + else if(fincas1 && fincas2) oncontinue = Standard_False; + else if((!fincas1 && finarc1) || (!fincas2 && finarc2)) oncontinue = Standard_False; + + if(oncontinue){ + TheWalk.ClassificationOnS1(!finarc1); + TheWalk.ClassificationOnS2(!finarc2); + TheWalk.Check2d(Standard_True); // It should be strict (PMN) + TheWalk.Continu(Func,FInv,Target); + TheWalk.ClassificationOnS1(Standard_True); + TheWalk.ClassificationOnS2(Standard_True); + TheWalk.Check2d(Standard_False); + narc1 = Lin->EndPointOnFirst().NbPointOnRst(); + narc2 = Lin->EndPointOnSecond().NbPointOnRst(); +// modified by eap Fri Feb 8 11:44:57 2002 ___BEGIN___ + if(!finarc1) + if (narc1 == 0) + forwContinueFailed = Lin->EndPointOnFirst().ParameterOnGuide() < Target; + else { + ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(), + Standard_False, Data->ChangeVertexLastOnS1(),tolesp); + finarc1 = Standard_True; + if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){ + //It is checked if it is not an obstacle. + fincas1 = Standard_True; +// if(!Spine.IsNull()){ +// finobst1 = IsObst(Data->VertexLastOnS1(), +// Spine->LastVertex(),myVEMap); +// } + } + } + if(!finarc2) + if (narc2 == 0) + forwContinueFailed = Lin->EndPointOnSecond().ParameterOnGuide() < Target; + else { + ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(), + Standard_False, Data->ChangeVertexLastOnS2(),tolesp); + finarc2 = Standard_True; + if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){ + //On regarde si ce n'est pas un obstacle. + fincas2 = Standard_True; +// if(!Spine.IsNull()){ +// finobst2 = IsObst(Data->VertexLastOnS2(), +// Spine->LastVertex(),myVEMap); +// } + } + } + if (forwContinueFailed) { + // if we leave forwContinueFailed as is, we will stop in this direction + // but we are to continue if there are no more faces on the side with arc + // check this condition + const ChFiDS_CommonPoint& aCP + = finarc1 ? Data->VertexLastOnS1() : Data->VertexLastOnS2(); + if (aCP.IsOnArc() && bif.IsNull()) + forwContinueFailed = Standard_False; + } +// modified by eap Fri Feb 8 11:45:10 2002 ___END___ + } + } + Nbpnt = Lin->NbPoints(); +#ifdef DRAW + if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False); +#endif + First = Lin->Point(1).Parameter(); + Last = Lin->Point(Nbpnt).Parameter(); + + // ============= INVALIDATION EVENTUELLE ============= + // ------ Preparation des prolongement par plan tangent ----- + if(reverse && intf){ + Gd1 = debcas1/* && !debobst1*/; // skv(occ67) + Gd2 = debcas2/* && !debobst2*/; // skv(occ67) + if ((debarc1^debarc2) && !unseulsuffitdeb && (First!=SpFirst)) { + // Case of incomplete path, of course this ends badly : + // the result is truncated instead of exit. + Standard_Real sortie; + Standard_Integer ind; + if (debarc1) sortie = Data->VertexFirstOnS1().Parameter(); + else sortie = Data->VertexFirstOnS2().Parameter(); + if (sortie - First > tolesp) { + ind = SearchIndex(sortie, Lin); + if (Lin->Point(ind).Parameter() == sortie) ind--; + if (ind >= 1) { + Lin->Remove(1, ind); + UpdateLine(Lin, Standard_True); + } + Nbpnt = Lin->NbPoints(); + First = Lin->Point(1).Parameter(); + } + } + else if ((intf>=5) && !debarc1 && !debarc2 && (First!=SpFirst)) { + Standard_Real sortie = (2*First+Last)/3; + Standard_Integer ind; + if (sortie - First > tolesp) { + ind = SearchIndex(sortie, Lin); + if (Lin->Point(ind).Parameter() == sortie) ind--; + if (Nbpnt-ind < 3) ind = Nbpnt -3; + if (ind >= 1) { + Lin->Remove(1, ind); + UpdateLine(Lin, Standard_True); + } + Nbpnt = Lin->NbPoints(); + First = Lin->Point(1).Parameter(); + } + } + if(Gd1 && Gd2){ + Target = Min((Lin->Point(1).Parameter() - Rab),First); + Target = Max(Target,SpFirst); + Data->FirstExtensionValue(Abs(Lin->Point(1).Parameter()-Target)); + } + if (intf && !unseulsuffitdeb) intf = (Gd1 && Gd2)//; + || backwContinueFailed; // eap + else if (intf && unseulsuffitdeb && (intf<5)) { + intf = (Gd1 || Gd2); + // It is checked if there is no new face. + if (intf && + ((!debcas1 && debarc1) || (!debcas2 && debarc2)) ) intf = 0; + } + else if (intf < 5) intf = 0; + } + + if(Forward && intl){ + Gf1 = fincas1/* && !finobst1*/; // skv(occ67) + Gf2 = fincas2/* && !finobst2*/; // skv(occ67) + if ((finarc1 ^finarc2) && !unseulsuffitfin && (Last!=SpLast)) { + // Case of incomplete path, of course, this ends badly : + // the result is truncated instead of exit. + Standard_Real sortie; + Standard_Integer ind; + if (finarc1) sortie = Data->VertexLastOnS1().Parameter(); + else sortie = Data->VertexLastOnS2().Parameter(); + if (Last - sortie > tolesp) { + ind = SearchIndex(sortie, Lin); + if (Lin->Point(ind).Parameter() == sortie) ind++; + if (ind<= Nbpnt) { + Lin->Remove(ind, Nbpnt); + UpdateLine(Lin, Standard_False); + } + Nbpnt = Lin->NbPoints(); + Last = Lin->Point(Nbpnt).Parameter(); + } + } + else if ((intl>=5) && !finarc1 && !finarc2 && (Last!=SpLast) ) { + // The same in case when the entire "Lin" is an extension + Standard_Real sortie = (First+2*Last)/3; + Standard_Integer ind; + if (Last - sortie > tolesp) { + ind = SearchIndex(sortie, Lin); + if (Lin->Point(ind).Parameter() == sortie) ind++; + if (ind < 3) ind = 3; + if (ind <= Nbpnt) { + Lin->Remove(ind, Nbpnt); + UpdateLine(Lin, Standard_False); + } + Nbpnt = Lin->NbPoints(); + Last = Lin->Point(Nbpnt).Parameter(); + } + } + if(Gf1 && Gf2) { + Target = Max((Lin->Point(Nbpnt).Parameter() + Rab),Last); + Target = Min(Target,SpLast); + Data->LastExtensionValue(Abs(Target-Lin->Point(Nbpnt).Parameter())); + } + + if (intl && !unseulsuffitfin) intl = (Gf1 && Gf2)//; + || forwContinueFailed; // eap + else if (intl && unseulsuffitfin && (intl<5)) { + intl = (Gf1 || Gf2);// It is checked if there is no new face. + if (intl && + ((!fincas1 && finarc1) || (!fincas2 && finarc2)) ) intl = 0; + } + else if (intl <5) intl = 0; + } + return Standard_True; +} + +//======================================================================= +//function : SimulData +//purpose : +//======================================================================= + +Standard_Boolean ChFi3d_Builder::SimulData +(Handle(ChFiDS_SurfData)& /*Data*/, + const Handle(ChFiDS_HElSpine)& HGuide, + Handle(BRepBlend_Line)& Lin, + const Handle(Adaptor3d_HSurface)& S1, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(Adaptor3d_HSurface)& S2, + const Handle(Adaptor3d_TopolTool)& I2, + Blend_Function& Func, + Blend_FuncInv& FInv, + const Standard_Real PFirst, + const Standard_Real MaxStep, + const Standard_Real Fleche, + const Standard_Real tolguide, + Standard_Real& First, + Standard_Real& Last, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const math_Vector& Soldep, + const Standard_Integer NbSecMin, + const Standard_Boolean RecOnS1, + const Standard_Boolean RecOnS2) +{ + BRepBlend_Walking TheWalk(S1,S2,I1,I2); + TheWalk.Check2d(Standard_False); + + Standard_Real MS = MaxStep; + Standard_Real TolGuide=tolguide, TolEsp = tolesp; + Standard_Integer Nbpnt; + Standard_Real SpFirst = HGuide->FirstParameter(); + Standard_Real SpLast = HGuide->LastParameter(); + Standard_Boolean reverse = (!Forward || Inside); + Standard_Real Target; + if(reverse){ + Target = SpFirst; + } + else{ + Target = SpLast; + } + + Standard_Real Targetsov = Target; +#ifndef DEB + Standard_Real u1sov = 0., u2sov = 0.; +#else + Standard_Real u1sov, u2sov; +#endif + // on recadre la solution de depart a la demande. + math_Vector ParSol(1,4); + Standard_Real NewFirst = PFirst; + if(RecOnS1 || RecOnS2){ + if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep, + tolesp,TolGuide,RecOnS1,RecOnS2, + NewFirst,ParSol)){ +#ifdef DEB + cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<endl; +#endif + return Standard_False; + } + } + else { + ParSol = Soldep; + } + Standard_Integer again = 0; + while(again < 3){ + // When the start point is inside, the path goes first to the left + // to determine the Last for the periodicals. + if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide; + else { + if (5*TolGuide > MS) TolGuide = MS/5; + if (5*TolEsp > MS) TolEsp = MS/5; + } + + TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide, + ParSol,TolEsp,Fleche,Appro); + + if (!TheWalk.IsDone()) { +#ifdef DEB + cout << "Path not created" << endl; +#endif + return Standard_False; + } + Lin = TheWalk.Line(); + if(reverse){ + if(HGuide->IsPeriodic()) { + SpFirst = Lin->Point(1).Parameter(); + SpLast = SpFirst + HGuide->Period(); + HGuide->ChangeCurve().FirstParameter(SpFirst); + HGuide->ChangeCurve().LastParameter (SpLast ); + } + Standard_Boolean complmnt = Standard_True; + if (Inside) complmnt = TheWalk.Complete(Func,FInv,SpLast); + if(!complmnt){ +#ifdef DEB + cout << "Not completed" << endl; +#endif + return Standard_False; + } + } + Nbpnt = Lin->NbPoints(); + Standard_Real factor = 1./(NbSecMin + 1); + if (Nbpnt == 0){ +#ifdef DEB + cout <<"0 point of path, quit."<<endl; +#endif + return Standard_False; + } + else if (Nbpnt == 1 && again == 0) { + again++; +#ifdef DEB + cout <<"only one point of path, MS/100 is attempted."<<endl; +#endif + MS *= 0.01; Target = Targetsov; + u1sov = u2sov = Lin->Point(1).Parameter(); + } + else if (Nbpnt< NbSecMin && again == 0) { + again++; +#ifdef DEB + cout <<"Number of points is too small, the step is reduced"<<endl; +#endif + Standard_Real u1 = u1sov = Lin->Point(1).Parameter(); + Standard_Real u2 = u2sov = Lin->Point(Nbpnt).Parameter(); + MS = (u2-u1)*factor; + Target = Targetsov; + } + else if (Nbpnt < NbSecMin && again == 1) { + Standard_Real u1 = Lin->Point(1).Parameter(); + Standard_Real u2 = Lin->Point(Nbpnt).Parameter(); + if(Abs(u1-u1sov)>=TolGuide || Abs(u2-u2sov)>=TolGuide){ + again++; +#ifdef DEB + cout <<"Number of points is still too small, the step is reduced"<<endl; +#endif + MS /= 100; + Target = Targetsov; + } + else{ +#ifdef DEB + cout <<"Number of points is still too small, quit"<<endl; +#endif + return Standard_False; + } + } + else if(Nbpnt < NbSecMin){ +#ifdef DEB + cout <<"Number of points is still too small, quit"<<endl; +#endif + return Standard_False; + } + else { + again = 3; + } + } +#ifdef DRAW + if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False); +#endif + First = Lin->Point(1).Parameter(); + Last = Lin->Point(Nbpnt).Parameter(); + return Standard_True; +} + diff --git a/src/ChFi3d/ChFi3d_Builder_C1.cxx b/src/ChFi3d/ChFi3d_Builder_C1.cxx new file mode 100644 index 00000000..3ae4c9e2 --- /dev/null +++ b/src/ChFi3d/ChFi3d_Builder_C1.cxx @@ -0,0 +1,4358 @@ +// File: ChFi3d_Builder_3.cxx +// Created: Wed Mar 9 15:48:03 1994 +// Author: Isabelle GRIGNON +// <isg@zerox> + +// Modified by skv - Mon Jun 7 18:38:57 2004 OCC5898 +// Modified by skv - Thu Aug 21 11:55:58 2008 OCC20222 + +#include <ChFi3d_Builder.jxx> +#include <ChFi3d.hxx> +#include <ChFi3d_Builder_0.hxx> + +#include <Precision.hxx> + +#include <Standard_Failure.hxx> +#include <Standard_NotImplemented.hxx> +#include <StdFail_NotDone.hxx> + + +#include <gp_Pnt.hxx> +#include <gp_Dir.hxx> +#include <gp_Vec.hxx> +#include <gp_Ax3.hxx> +#include <gp_Pnt2d.hxx> +#include <gp_Vec2d.hxx> +#include <gp_Dir2d.hxx> +#include <gp_Elips.hxx> +#include <gp_Circ.hxx> + +#include <ElCLib.hxx> +#include <ElSLib.hxx> + +#include <Geom_Line.hxx> +#include <Geom_Circle.hxx> +#include <Geom_Ellipse.hxx> +#include <Geom_RectangularTrimmedSurface.hxx> +#include <Geom_Curve.hxx> +#include <Geom2d_Line.hxx> +#include <Geom2d_Curve.hxx> +#include <Geom_BSplineCurve.hxx> +#include <Geom_BSplineSurface.hxx> +#include <Geom_BezierSurface.hxx> +#include <Geom2d_BSplineCurve.hxx> +#include <Geom2dAdaptor_HCurve.hxx> +#include <Geom2d_TrimmedCurve.hxx> +#include <Geom2dInt_GInter.hxx> +#include <Geom_TrimmedCurve.hxx> +#include <GeomAPI_ExtremaCurveCurve.hxx> +#include <GeomAbs_Shape.hxx> +#include <GeomAdaptor_HCurve.hxx> +#include <GeomAdaptor_Surface.hxx> +#include <GeomAdaptor_HSurface.hxx> +#include <Geom_BoundedCurve.hxx> +#include <GeomLib.hxx> +#include <GeomInt_IntSS.hxx> +#include <GeomProjLib.hxx> + +#include <Adaptor3d_HCurveOnSurface.hxx> +#include <Adaptor3d_CurveOnSurface.hxx> +#include <BRepAdaptor_HSurface.hxx> +#include <BRepAdaptor_Curve.hxx> +#include <BRepAdaptor_Curve2d.hxx> +#include <BRepAdaptor_HCurve2d.hxx> +#include <BRepAdaptor_HCurve.hxx> +#include <BRepAdaptor_Surface.hxx> +#include <BRepLib_MakeEdge.hxx> +#include <BRepAlgo_NormalProjection.hxx> +#include <BRepExtrema_ExtCC.hxx> +#include <BRep_Tool.hxx> +#include <BRepTools.hxx> +#include <BRep_Builder.hxx> +#include <IntCurveSurface_HInter.hxx> +#include <IntCurveSurface_IntersectionPoint.hxx> +#include <IntRes2d_IntersectionPoint.hxx> +#include <IntRes2d_Transition.hxx> +#include <Extrema_LocateExtCC.hxx> +#include <Extrema_POnCurv.hxx> +#include <Extrema_ExtPC2d.hxx> +#include <Extrema_ExtPC.hxx> +#include <Extrema_ExtPS.hxx> +#include <Extrema_ExtCC.hxx> + +#include <TopoDS.hxx> +#include <TopoDS_Shape.hxx> +#include <TopoDS_Face.hxx> +#include <TopoDS_Edge.hxx> +#include <TopoDS_Vertex.hxx> + +#include <TopAbs.hxx> +#include <TopAbs_ShapeEnum.hxx> +#include <TopAbs_Orientation.hxx> +#include <TopExp.hxx> +#include <TopExp_Explorer.hxx> +#include <TopLoc_Location.hxx> +#include <TopTools_ListIteratorOfListOfShape.hxx> + +#include <TopOpeBRepDS_Point.hxx> +#include <TopOpeBRepDS_Curve.hxx> +#include <TopOpeBRepDS_Surface.hxx> +#include <TopOpeBRepDS_SurfaceCurveInterference.hxx> +#include <TopOpeBRepDS_CurvePointInterference.hxx> +#include <TopOpeBRepDS_DataStructure.hxx> +#include <TopOpeBRepDS_ListOfInterference.hxx> +#include <TopOpeBRepDS_ListIteratorOfListOfInterference.hxx> +#include <TopOpeBRepDS_SolidSurfaceInterference.hxx> +#include <TopOpeBRepDS_Kind.hxx> +#include <TopOpeBRepDS_Transition.hxx> +#include <TopTools_Array1OfShape.hxx> +#include <ChFiDS_HData.hxx> +#include <ChFiDS_SurfData.hxx> +#include <ChFiDS_CommonPoint.hxx> +#include <ChFiDS_FaceInterference.hxx> +#include <ChFiDS_SequenceOfSurfData.hxx> +#include <ChFiDS_Stripe.hxx> +#include <ChFiDS_ListIteratorOfListOfStripe.hxx> +#include <ChFiDS_Map.hxx> +#include <TColgp_Array1OfPnt.hxx> +#include <TColgp_Array1OfPnt2d.hxx> +#include <TColStd_Array1OfReal.hxx> +#include <TColStd_Array1OfInteger.hxx> + +#ifdef DEB +# ifdef DRAW +#include <OSD_Chronometer.hxx> +#include <DrawTrSurf.hxx> +# endif //DRAW +// Modified by Sergey KHROMOV - Thu Apr 11 12:23:40 2002 Begin +// The method +// ChFi3d_Builder::PerformMoreSurfdata(const Standard_Integer Index) +// is totally rewroted. +// Modified by Sergey KHROMOV - Thu Apr 11 12:23:40 2002 End + +extern Standard_Real t_same,t_inter,t_sameinter; +extern void ChFi3d_InitChron(OSD_Chronometer& ch); +extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time); +#endif +#include <Geom2dAPI_ProjectPointOnCurve.hxx> +#include <math_FunctionSample.hxx> +#include <Geom2dAdaptor_Curve.hxx> +#include <IntRes2d_IntersectionSegment.hxx> +// Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 Begin +Standard_Boolean isTangentFaces(const TopoDS_Edge &theEdge, + const TopoDS_Face &theFace1, + const TopoDS_Face &theFace2); +// Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 End + +static Standard_Real recadre(const Standard_Real p, + const Standard_Real ref, + const Standard_Boolean isfirst, + const Standard_Real first, + const Standard_Real last) +{ + Standard_Real pp = p; + if (isfirst) pp -= (last - first); + else pp += (last - first); + if (Abs(pp - ref) < Abs(p - ref)) return pp; + return p; +} + +//======================================================================= +//function : Update +//purpose : Calculate the intersection of the face at the end of +// the tangency line to update CommonPoint and its +// parameter in FaceInterference. +//======================================================================= + +static Standard_Boolean Update(Handle(Adaptor3d_HSurface)& fb, + Handle(Adaptor2d_HCurve2d)& pcfb, + Handle(Adaptor3d_HSurface)& surf, + ChFiDS_FaceInterference& fi, + ChFiDS_CommonPoint& cp, + gp_Pnt2d& p2dbout, + const Standard_Boolean isfirst, + Standard_Real& pared, + Standard_Real& wop, + const Standard_Real tol) +{ + Adaptor3d_CurveOnSurface c1(pcfb,fb); + Handle(Geom2d_Curve) pc = fi.PCurveOnSurf(); + Handle(Geom2dAdaptor_HCurve) hpc = new Geom2dAdaptor_HCurve(pc); + Adaptor3d_CurveOnSurface c2(hpc,surf); + Extrema_LocateExtCC ext(c1,c2,pared,wop); + if (ext.IsDone()) { + Standard_Real dist2 = ext.SquareDistance(); + if (dist2 < tol * tol) { + Extrema_POnCurv ponc1,ponc2; + ext.Point(ponc1,ponc2); + Standard_Real parfb = ponc1.Parameter(); + p2dbout = pcfb->Value(parfb); + pared = ponc1.Parameter(); + wop = ponc2.Parameter(); + fi.SetParameter(wop,isfirst); + cp.Reset(); + cp.SetPoint(ponc1.Value()); + return Standard_True; + } + } + return Standard_False; +} + +//======================================================================= +//function : Update +//purpose : Intersect surface <fb> and 3d curve <ct> +// Update <isfirst> parameter of FaceInterference <fi> and point of +// CommonPoint <cp>. Return new intersection parameters in <wop> +// and <p2dbout> +//======================================================================= + +static Standard_Boolean Update(Handle(Adaptor3d_HSurface)& fb, + Handle(Adaptor3d_HCurve)& ct, + ChFiDS_FaceInterference& fi, + ChFiDS_CommonPoint& cp, + gp_Pnt2d& p2dbout, + const Standard_Boolean isfirst, + Standard_Real& wop) +{ + IntCurveSurface_HInter Intersection; + //check if in KPart the limits of the tangency line + //are already in place at this stage. + //Modif lvt : the periodic cases are reframed, espercially if nothing was found. + Standard_Real w,uf = ct->FirstParameter(),ul = ct->LastParameter(); +#ifndef DEB + Standard_Real wbis = 0.; +#else + Standard_Real wbis; +#endif + Standard_Boolean isperiodic = ct->IsPeriodic(),recadrebis = Standard_False; + Intersection.Perform(ct,fb); + if (Intersection.IsDone()) { + Standard_Integer nbp = Intersection.NbPoints(),i,isol = 0,isolbis = 0; + Standard_Real dist = Precision::Infinite(); + Standard_Real distbis = Precision::Infinite(); + for (i = 1; i <= nbp; i++) { + w = Intersection.Point(i).W(); + if (isperiodic) w = recadre(w,wop,isfirst,uf,ul); + if (uf <= w && ul >= w && Abs(w-wop) < dist) { + isol = i; + dist = Abs(w-wop); + } + } + if (isperiodic) { + for (i = 1; i <= nbp; i++) { + w = Intersection.Point(i).W(); + if (uf <= w && ul >= w && Abs(w-wop) < distbis && (Abs(w-ul)<=0.01 || Abs(w-uf)<=0.01)) { + isolbis = i; + wbis = recadre(w,wop,isfirst,uf,ul); + distbis = Abs(wbis-wop); + recadrebis = Standard_True; + } + } + } + if (isol == 0 && isolbis == 0) { + return Standard_False; + } + if (!recadrebis) { + IntCurveSurface_IntersectionPoint pint = Intersection.Point(isol); + p2dbout.SetCoord(pint.U(),pint.V()); + w = pint.W(); + if (isperiodic) w = ElCLib::InPeriod(w,uf,ul); + } + else { + if (dist>distbis) { + IntCurveSurface_IntersectionPoint pint = Intersection.Point(isolbis); + p2dbout.SetCoord(pint.U(),pint.V()); + w = wbis; + } + else { + IntCurveSurface_IntersectionPoint pint = Intersection.Point(isol); + p2dbout.SetCoord(pint.U(),pint.V()); + w = pint.W(); + w = ElCLib::InPeriod(w,uf,ul); + } + } + fi.SetParameter(w,isfirst); + cp.Reset(); + cp.SetPoint(ct->Value(w)); + wop = w; + return Standard_True; + } + return Standard_False; +} + +//======================================================================= +//function : IntersUpdateOnSame +//purpose : Intersect curve <c3dFI> of ChFi-<Fop> interference with extended +// surface <HBs> of <Fprol> . Return intersection parameters in +// <FprolUV>, <c3dU> and updating <FIop> and <CPop> +// <HGs> is a surface of ChFi +// <Fop> is a face having 2 edges at corner with OnSame state +// <Fprol> is a face non-adjacent to spine edge +// <Vtx> is a corner vertex +//======================================================================= + +static Standard_Boolean IntersUpdateOnSame(Handle(GeomAdaptor_HSurface)& HGs, + Handle(BRepAdaptor_HSurface)& HBs, + const Handle(Geom_Curve)& c3dFI, + const TopoDS_Face& Fop, + const TopoDS_Face& Fprol, + const TopoDS_Edge& Eprol, + const TopoDS_Vertex& Vtx, + const Standard_Boolean isFirst, + const Standard_Real Tol, + ChFiDS_FaceInterference& FIop, + ChFiDS_CommonPoint& CPop, + gp_Pnt2d& FprolUV, + Standard_Real& c3dU) +{ + // add more or less restrictive criterions to + // decide if the intersection is done with the face at + // extended end or if the end is sharp. + Standard_Real uf = FIop.FirstParameter(); + Standard_Real ul = FIop.LastParameter(); + Handle(GeomAdaptor_HCurve) Hc3df; + if (c3dFI->IsPeriodic()) Hc3df = new GeomAdaptor_HCurve(c3dFI); + else Hc3df = new GeomAdaptor_HCurve(c3dFI,uf,ul); + + if ( Update(HBs,Hc3df,FIop,CPop,FprolUV,isFirst,c3dU) ) + return Standard_True; + + if (!isTangentFaces(Eprol,Fprol,Fop)) + return Standard_False; + + Handle(Geom2d_Curve) gpcprol = BRep_Tool::CurveOnSurface(Eprol,Fprol,uf,ul); + Handle(Geom2dAdaptor_HCurve) pcprol = new Geom2dAdaptor_HCurve(gpcprol); + Standard_Real partemp = BRep_Tool::Parameter(Vtx,Eprol); + + return + Update(HBs,pcprol,HGs,FIop,CPop,FprolUV,isFirst,partemp,c3dU,Tol); +} + +//======================================================================= +//function : Update +//purpose : Calculate the extrema curveonsurf/curveonsurf to prefer +// the values concerning the trace on surf and the pcurve on the +// face at end. +//======================================================================= + +static Standard_Boolean Update(Handle(Adaptor3d_HSurface)& face, + Handle(Adaptor2d_HCurve2d)& edonface, + Handle(Adaptor3d_HSurface)& surf, + ChFiDS_FaceInterference& fi, + ChFiDS_CommonPoint& cp, + const Standard_Boolean isfirst) +{ + if (!cp.IsOnArc()) return 0; + Adaptor3d_CurveOnSurface c1(edonface,face); + Standard_Real pared = cp.ParameterOnArc(); + Standard_Real parltg = fi.Parameter(isfirst); + Handle(Geom2d_Curve) pc = fi.PCurveOnSurf(); + Standard_Real f = fi.FirstParameter(); + Standard_Real l = fi.LastParameter(); + Standard_Real delta = 0.1 * ( l - f ); + f = Max(f-delta,pc->FirstParameter()); + l = Min(l+delta,pc->LastParameter()); + Handle(Geom2dAdaptor_HCurve) hpc = new Geom2dAdaptor_HCurve(pc,f,l); + Adaptor3d_CurveOnSurface c2(hpc,surf); + + Extrema_LocateExtCC ext(c1,c2,pared,parltg); + if (ext.IsDone()) { + Extrema_POnCurv ponc1,ponc2; + ext.Point(ponc1,ponc2); + pared = ponc1.Parameter(); + parltg = ponc2.Parameter(); + if ((parltg > f) && (parltg < l)) { + fi.SetParameter(parltg,isfirst); + cp.SetArc(cp.Tolerance(),cp.Arc(),pared,cp.TransitionOnArc()); + return Standard_True; + } + } + return Standard_False; +} + +//======================================================================= +//function : ChFi3d_ExtendSurface +//purpose : +//======================================================================= + +static void ChFi3d_ExtendSurface (Handle(Geom_Surface) & S , + Standard_Integer & prol ) +{ + if (prol) return; + Handle(Geom_BSplineSurface) S1; + Handle(Geom_BezierSurface) S2; + Standard_Real length,umin,umax,vmin,vmax; + gp_Pnt P1,P2; + S->Bounds(umin,umax,vmin,vmax); + S->D0(umin,vmin,P1); + S->D0(umax,vmax,P2); + length=P1.Distance(P2); + prol=0; + S1=Handle(Geom_BSplineSurface)::DownCast(S); + S2=Handle(Geom_BezierSurface)::DownCast(S); + if (!S1.IsNull()) { + GeomLib::ExtendSurfByLength(S1,length,1,Standard_False, + Standard_True); + GeomLib::ExtendSurfByLength(S1,length,1,Standard_True, + Standard_True); + GeomLib::ExtendSurfByLength(S1,length,1,Standard_False, + Standard_False); + GeomLib::ExtendSurfByLength(S1,length,1,Standard_True, + Standard_False); + S=S1; + prol=1; + } + if (!S2.IsNull()) { + GeomLib::ExtendSurfByLength(S2,length,1,Standard_False, + Standard_True); + GeomLib::ExtendSurfByLength(S2,length,1,Standard_True, + Standard_True); + GeomLib::ExtendSurfByLength(S2,length,1,Standard_False, + Standard_False); + GeomLib::ExtendSurfByLength(S2,length,1,Standard_True, + Standard_False); + S=S2; + prol=2; + + } +} + +//======================================================================= +//function : ComputeCurve2d +//purpose : calculate the 2d of the curve Ct on face Face +//======================================================================= + +static void ComputeCurve2d (Handle(Geom_Curve )& Ct, + TopoDS_Face & Face, + Handle(Geom2d_Curve) & C2d) +{ + TopoDS_Edge E1; + TopTools_IndexedMapOfShape MapE1; + BRepLib_MakeEdge Bedge (Ct); + TopoDS_Edge edg =Bedge. Edge(); + BRepAlgo_NormalProjection OrtProj; + OrtProj.Init(Face); + OrtProj.Add(edg); + OrtProj.SetParams(1.e-6, 1.e-6, GeomAbs_C1, 14, 16); + OrtProj.SetLimit(Standard_False); + OrtProj.Compute3d(Standard_False); + OrtProj.Build(); + Standard_Real up1,up2; + if ( OrtProj.IsDone()) { + TopExp::MapShapes(OrtProj.Projection() ,TopAbs_EDGE, MapE1); + if (MapE1.Extent()!=0) { + TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(1)); + E1=TopoDS::Edge(aLocalShape ); +// E1=TopoDS::Edge( TopoDS_Shape (MapE1(1))); + C2d=BRep_Tool::CurveOnSurface(E1,Face,up1,up2); + } + } +} + +//======================================================================= +//function : ChFi3d_Recale +//purpose : +//======================================================================= + +static void ChFi3d_Recale(BRepAdaptor_Surface& Bs, + gp_Pnt2d& p1, + gp_Pnt2d& p2, + const Standard_Boolean refon1) +{ + Handle(Geom_Surface) surf = Bs.ChangeSurface().Surface(); + Handle(Geom_RectangularTrimmedSurface) + ts = Handle(Geom_RectangularTrimmedSurface)::DownCast(surf); + if (!ts.IsNull()) surf = ts->BasisSurface(); + if (surf->IsUPeriodic()) { + Standard_Real u1 = p1.X(), u2 = p2.X(); + Standard_Real uper = surf->UPeriod(); + if (fabs(u2-u1) > 0.5*uper) { + if (u2<u1 && refon1) u2 += uper; + else if (u2<u1 && !refon1) u1 -= uper; + else if (u1<u2 && refon1) u2 -= uper; + else if (u1<u2 && !refon1) u1 += uper; + } + p1.SetX(u1); p2.SetX(u2); + } + if (surf->IsVPeriodic()) { + Standard_Real v1 = p1.Y(), v2 = p2.Y(); + Standard_Real vper = surf->VPeriod(); + if (fabs(v2-v1) > 0.5*vper) { + if (v2<v1 && refon1) v2 += vper; + else if (v2<v1 && !refon1) v1 -= vper; + else if (v1<v2 && refon1) v2 -= vper; + else if (v1<v2 && !refon1) v1 += vper; + } + p1.SetY(v1); p2.SetY(v2); + } +} + +//======================================================================= +//function : ChFi3d_SelectStripe +//purpose : find stripe with ChFiDS_OnSame state if <thePrepareOnSame> is True +//======================================================================= + +Standard_Boolean ChFi3d_SelectStripe(ChFiDS_ListIteratorOfListOfStripe & It, + const TopoDS_Vertex& Vtx, + const Standard_Boolean thePrepareOnSame) +{ + if (!thePrepareOnSame) return Standard_True; + + for (; It.More(); It.Next()) { + Standard_Integer sens = 0; + Handle(ChFiDS_Stripe) stripe = It.Value(); + ChFi3d_IndexOfSurfData(Vtx, stripe, sens); + ChFiDS_State stat; + if ( sens == 1 ) + stat = stripe->Spine()->FirstStatus(); + else + stat = stripe->Spine()->LastStatus(); + if ( stat == ChFiDS_OnSame ) return Standard_True; + } + + return Standard_False; +} +//======================================================================= +//function : PerformOneCorner +//purpose : Calculate a corner with three edges and a fillet. +// 3 separate case: (22/07/94 only 1st is implemented) +// +// - same concavity on three edges, intersection with the +// face at end, +// - concavity of 2 outgoing edges is opposite to the one of the fillet, +// if the face at end is ready for that, the same in case 1 on extended face, +// otherwise a small cap is done with GeomFill, +// - only one outgoing edge has concavity opposed to the edge of the +// fillet and the third edge, the top of the corner is reread +// in the empty of the fillet and closed, either by extending the face +// at end if it is plane and orthogonal to the +// guiding edge, or by a cap of type GeomFill. +// +// <thePrepareOnSame> means that only needed thing is redefinition +// of intersection pameter of OnSame-Stripe with <Arcprol> +// (eap, Arp 9 2002, occ266) +//======================================================================= + +void ChFi3d_Builder::PerformOneCorner(const Standard_Integer Index, + const Standard_Boolean thePrepareOnSame) +{ + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + +#ifdef DEB + OSD_Chronometer ch;// init perf for PerformSetOfKPart +#endif + // the top, + const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index); + // The fillet is returned, + ChFiDS_ListIteratorOfListOfStripe StrIt; + StrIt.Initialize(myVDataMap(Index)); + if ( ! ChFi3d_SelectStripe (StrIt, Vtx, thePrepareOnSame)) return; + Handle(ChFiDS_Stripe) stripe = StrIt.Value(); + const Handle(ChFiDS_Spine) spine = stripe->Spine(); + ChFiDS_SequenceOfSurfData& SeqFil = + stripe->ChangeSetOfSurfData()->ChangeSequence(); + // SurfData and its CommonPoints, + Standard_Integer sens = 0; + + // Choose proper SurfData + Standard_Integer num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens); + Standard_Boolean isfirst = (sens == 1); + if (isfirst) { + for (; num<SeqFil.Length() && ( + (SeqFil.Value(num)->IndexOfS1()==0) || + (SeqFil.Value(num)->IndexOfS2()==0) ); ) { + SeqFil.Remove(num); // The surplus is removed + } + } + else { + for (; num>1 && ( + (SeqFil.Value(num)->IndexOfS1()==0) || + (SeqFil.Value(num)->IndexOfS2()==0) ); ) { + SeqFil.Remove(num);// The surplus is removed + num--; + } + } + + Handle(ChFiDS_SurfData)& Fd = SeqFil.ChangeValue(num); + ChFiDS_CommonPoint& CV1 = Fd->ChangeVertex(isfirst,1); + ChFiDS_CommonPoint& CV2 = Fd->ChangeVertex(isfirst,2); + //To evaluate the new points. + Bnd_Box box1,box2; + + // The cases of cap and intersection are processed separately. + // ---------------------------------------------------------- + ChFiDS_State stat; + if (isfirst) stat = spine->FirstStatus(); + else stat = spine->LastStatus(); + Standard_Boolean onsame = (stat == ChFiDS_OnSame); + TopoDS_Face Fv,Fad,Fop; + TopoDS_Edge Arcpiv,Arcprol,Arcspine; + if (isfirst) Arcspine = spine->Edges(1); + else Arcspine = spine->Edges(spine->NbEdges()); +#ifndef DEB + TopAbs_Orientation OArcprolv = TopAbs_FORWARD, OArcprolop = TopAbs_FORWARD; +#else + TopAbs_Orientation OArcprolv,OArcprolop; +#endif + Standard_Integer ICurve; + Handle(BRepAdaptor_HSurface) HBs = new BRepAdaptor_HSurface(); + Handle(BRepAdaptor_HSurface) HBad = new BRepAdaptor_HSurface(); + Handle(BRepAdaptor_HSurface) HBop = new BRepAdaptor_HSurface(); + BRepAdaptor_Surface& Bs = HBs->ChangeSurface(); + BRepAdaptor_Surface& Bad = HBad->ChangeSurface(); + BRepAdaptor_Surface& Bop = HBop->ChangeSurface(); + Handle(Geom_Curve) Cc; + Handle(Geom2d_Curve) Pc,Ps; + Standard_Real Ubid,Vbid;//,mu,Mu,mv,Mv; +#ifndef DEB + Standard_Real Udeb = 0.,Ufin = 0.; +#else + Standard_Real Udeb,Ufin; +#endif +// gp_Pnt2d UVf1,UVl1,UVf2,UVl2; +// Standard_Real Du,Dv,Step; + Standard_Boolean inters = Standard_True; + Standard_Integer IFadArc = 1, IFopArc = 2; + Fop = TopoDS::Face(DStr.Shape(Fd->Index(IFopArc))); + TopExp_Explorer ex; + +#ifdef DEB + ChFi3d_InitChron(ch); // init perf condition if (onsame) +#endif + + if (onsame) { + if (!CV1.IsOnArc() && !CV2.IsOnArc()) + Standard_Failure::Raise("Corner OnSame : no point on arc"); + else if (CV1.IsOnArc() && CV2.IsOnArc()) { + Standard_Boolean sur1 = 0, sur2 = 0; + for(ex.Init(CV1.Arc(),TopAbs_VERTEX); ex.More(); ex.Next()) { + if (Vtx.IsSame(ex.Current())) { + sur1 = 1; + break; + } + } + for(ex.Init(CV2.Arc(),TopAbs_VERTEX); ex.More(); ex.Next()) { + if (Vtx.IsSame(ex.Current())) { + sur2 = 1; + break; + } + } + if (sur1 && sur2) { + TopoDS_Edge E[3]; + E[0] = CV1.Arc(); E[1] = CV2.Arc(); E[2] = Arcspine; + if (ChFi3d_EdgeState(E,myEFMap) != ChFiDS_OnDiff) IFadArc = 2; + } + else if (sur2) IFadArc = 2; + } + else if (CV2.IsOnArc()) IFadArc = 2; + IFopArc = 3-IFadArc; + + Arcpiv = Fd->Vertex(isfirst,IFadArc).Arc(); + Fad = TopoDS::Face(DStr.Shape(Fd->Index(IFadArc))); + Fop = TopoDS::Face(DStr.Shape(Fd->Index(IFopArc))); + TopTools_ListIteratorOfListOfShape It; + // The face at end is returned without check of its unicity. + for(It.Initialize(myEFMap(Arcpiv));It.More();It.Next()) { + if (!Fad.IsSame(It.Value())) { + Fv = TopoDS::Face(It.Value()); + break; + } + } + + // Does the face at bout contain the Vertex ? + Standard_Boolean isinface = Standard_False; + for (ex.Init(Fv,TopAbs_VERTEX); ex.More(); ex.Next()) { + if (ex.Current().IsSame(Vtx)) { + isinface = Standard_True; + break; + } + } + if (!isinface && Fd->Vertex(isfirst,3-IFadArc).IsOnArc()) { + IFadArc = 3-IFadArc; + IFopArc = 3-IFopArc; + Arcpiv = Fd->Vertex(isfirst,IFadArc).Arc(); + Fad = TopoDS::Face(DStr.Shape(Fd->Index(IFadArc))); + Fop = TopoDS::Face(DStr.Shape(Fd->Index(IFopArc))); + //TopTools_ListIteratorOfListOfShape It; + // The face at end is returned without check of its unicity. + for(It.Initialize(myEFMap(Arcpiv));It.More();It.Next()) { + if (!Fad.IsSame(It.Value())) { + Fv = TopoDS::Face(It.Value()); + break; + } + } + } + + if (Fv.IsNull()) StdFail_NotDone::Raise + ("OneCorner : face at end not found"); + + Fv.Orientation(TopAbs_FORWARD); + Fad.Orientation(TopAbs_FORWARD); + Fop.Orientation(TopAbs_FORWARD); + + // The edge that will be extended is returned. + for(It.Initialize(myVEMap(Vtx));It.More() && Arcprol.IsNull();It.Next()) { + if (!Arcpiv.IsSame(It.Value())) { + for(ex.Init(Fv,TopAbs_EDGE); ex.More(); ex.Next()) { + if (It.Value().IsSame(ex.Current())) { + Arcprol = TopoDS::Edge(It.Value()); + OArcprolv = ex.Current().Orientation(); + break; + } + } + } + } + if (Arcprol.IsNull()) /*StdFail_NotDone::Raise + ("OneCorner : edge a prolonger non trouve");*/ + { + PerformIntersectionAtEnd(Index); + return; + } + for(ex.Init(Fop,TopAbs_EDGE); ex.More(); ex.Next()) { + if (Arcprol.IsSame(ex.Current())) { + OArcprolop = ex.Current().Orientation(); + break; + } + } + TopoDS_Face FFv; + Standard_Real tol; + Standard_Integer prol=0; + BRep_Builder BRE; + Handle(Geom_Surface ) Sface; + Sface=BRep_Tool::Surface(Fv); + ChFi3d_ExtendSurface(Sface,prol); + tol=BRep_Tool::Tolerance(Fv); + BRE.MakeFace(FFv,Sface,tol); + if (prol) { + Bs.Initialize(FFv,Standard_False); + DStr.SetNewSurface(Fv,Sface); + } + else Bs.Initialize(Fv,Standard_False); + Bad.Initialize(Fad); + Bop.Initialize(Fop); + } + //in case of OnSame it is necessary to modify the CommonPoint + //in the empty and its parameter in the FaceInterference. + //They are both returned in non const references. Attention the modifications are done behind + //de CV1,CV2,Fi1,Fi2. + ChFiDS_CommonPoint& CPopArc = Fd->ChangeVertex(isfirst,IFopArc); + ChFiDS_FaceInterference& FiopArc = Fd->ChangeInterference(IFopArc); + ChFiDS_CommonPoint& CPadArc = Fd->ChangeVertex(isfirst,IFadArc); + ChFiDS_FaceInterference& FiadArc = Fd->ChangeInterference(IFadArc); + //the parameter of the vertex in the air is initialiced with the value of + //its opposite (point on arc). + Standard_Real wop = Fd->ChangeInterference(IFadArc).Parameter(isfirst); + Handle(Geom_Curve) c3df; + Handle(GeomAdaptor_HSurface) + HGs = new GeomAdaptor_HSurface(DStr.Surface(Fd->Surf()).Surface()); + gp_Pnt2d p2dbout; + + if (onsame) { + + ChFiDS_CommonPoint saveCPopArc = CPopArc; + c3df = DStr.Curve(FiopArc.LineIndex()).Curve(); + + inters = IntersUpdateOnSame (HGs,HBs,c3df,Fop,Fv,Arcprol,Vtx,isfirst,10*tolesp, // in + FiopArc,CPopArc,p2dbout,wop); // out + + Handle(BRepAdaptor_HCurve2d) pced = new BRepAdaptor_HCurve2d(); + pced->ChangeCurve2d().Initialize(CPadArc.Arc(),Fv); + // in the case of degenerated Fi, parameter difference can be even negative (eap, occ293) + if ((FiadArc.LastParameter() - FiadArc.FirstParameter()) > 10*tolesp) + Update(HBs,pced,HGs,FiadArc,CPadArc,isfirst); + + if (thePrepareOnSame) { + //saveCPopArc.SetParameter(wop); + saveCPopArc.SetPoint(CPopArc.Point()); + CPopArc = saveCPopArc; + return; + } + } + else { + inters = FindFace(Vtx,CV1,CV2,Fv,Fop); + if (!inters) { + PerformIntersectionAtEnd(Index); + return; + } + Bs.Initialize(Fv); + Handle(BRepAdaptor_HCurve2d) pced = new BRepAdaptor_HCurve2d(); + pced->ChangeCurve2d().Initialize(CV1.Arc(),Fv); + Update(HBs,pced,HGs,Fd->ChangeInterferenceOnS1(),CV1,isfirst); + pced->ChangeCurve2d().Initialize(CV2.Arc(),Fv); + Update(HBs,pced,HGs,Fd->ChangeInterferenceOnS2(),CV2,isfirst); + } + + +#ifdef DEB + ChFi3d_ResultChron(ch,t_same); // result perf condition if (same) + ChFi3d_InitChron(ch); // init perf condition if (inters) +#endif + + TopoDS_Edge edgecouture; + Standard_Boolean couture,intcouture=Standard_False;; + Standard_Real tolreached; +#ifndef DEB + Standard_Real par1 =0.,par2 =0.; + Standard_Integer indpt = 0,Icurv1 = 0,Icurv2 = 0; +#else + Standard_Real par1,par2; + Standard_Integer indpt,Icurv1,Icurv2; +#endif + Handle(Geom_TrimmedCurve) curv1,curv2; + Handle(Geom2d_Curve) c2d1,c2d2; + + Standard_Integer Isurf=Fd->Surf(); + + if (inters) { + HGs = ChFi3d_BoundSurf(DStr,Fd,1,2); + const ChFiDS_FaceInterference& Fi1 = Fd->InterferenceOnS1(); + const ChFiDS_FaceInterference& Fi2 = Fd->InterferenceOnS2(); + TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4); + gp_Pnt2d pfil1,pfac1,pfil2,pfac2; + Handle(Geom2d_Curve) Hc1,Hc2; + if (onsame && IFopArc == 1) pfac1 = p2dbout; + else { + Hc1 = BRep_Tool::CurveOnSurface(CV1.Arc(),Fv,Ubid,Ubid); + pfac1 = Hc1->Value(CV1.ParameterOnArc()); + } + if (onsame && IFopArc == 2) pfac2 = p2dbout; + else { + Hc2 = BRep_Tool::CurveOnSurface(CV2.Arc(),Fv,Ubid,Ubid); + pfac2 = Hc2->Value(CV2.ParameterOnArc()); + } + if (Fi1.LineIndex() != 0) { + pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(isfirst)); + } + else { + pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(!isfirst)); + } + if (Fi2.LineIndex() != 0) { + pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(isfirst)); + } + else { + pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(!isfirst)); + } + if (onsame) ChFi3d_Recale(Bs,pfac1,pfac2,(IFadArc == 1)); + + Pardeb(1)= pfil1.X(); Pardeb(2) = pfil1.Y(); + Pardeb(3)= pfac1.X(); Pardeb(4) = pfac1.Y(); + Parfin(1)= pfil2.X(); Parfin(2) = pfil2.Y(); + Parfin(3)= pfac2.X(); Parfin(4) = pfac2.Y(); + + Standard_Real uu1,uu2,vv1,vv2; + ChFi3d_Boite(pfac1,pfac2,uu1,uu2,vv1,vv2); + ChFi3d_BoundFac(Bs,uu1,uu2,vv1,vv2); + + if (!ChFi3d_ComputeCurves(HGs,HBs,Pardeb,Parfin,Cc, + Ps, + Pc,tolesp,tol2d,tolreached)) + Standard_Failure::Raise("OneCorner : echec calcul intersection"); + + Udeb = Cc->FirstParameter(); + Ufin = Cc->LastParameter(); + + // determine if the curve has an intersection with edge of sewing + + ChFi3d_Couture(Fv,couture,edgecouture); + + if (couture && !BRep_Tool::Degenerated(edgecouture)) { + + //Standard_Real Ubid,Vbid; + Handle (Geom_Curve) C=BRep_Tool::Curve(edgecouture,Ubid,Vbid); + Handle(Geom_TrimmedCurve) Ctrim=new Geom_TrimmedCurve (C,Ubid,Vbid); + GeomAdaptor_Curve cur1(Ctrim->BasisCurve()); + GeomAdaptor_Curve cur2(Cc); + Extrema_ExtCC extCC (cur1,cur2); + if (extCC.IsDone()&&extCC.NbExt()!=0) + { + Standard_Integer imin=0; + Standard_Real distmin2 = RealLast(); + for (Standard_Integer i = 1; i <= extCC.NbExt(); i++) + if (extCC.SquareDistance(i) < distmin2) + { + distmin2 = extCC.SquareDistance(i); + imin = i; + } + if (distmin2 <= Precision::Confusion() * Precision::Confusion()) + { + Extrema_POnCurv ponc1,ponc2; + extCC.Points( imin, ponc1, ponc2 ); + par1 = ponc1.Parameter(); + par2 = ponc2.Parameter(); + Standard_Real Tol = 1.e-4; + if (Abs(par2-Udeb) > Tol && Abs(Ufin-par2) > Tol) + { + gp_Pnt P1 = ponc1.Value(); + TopOpeBRepDS_Point tpoint( P1, Tol ); + indpt = DStr.AddPoint(tpoint); + intcouture = Standard_True; + curv1 = new Geom_TrimmedCurve(Cc,Udeb,par2); + curv2 = new Geom_TrimmedCurve(Cc,par2,Ufin); + TopOpeBRepDS_Curve tcurv1(curv1,tolreached); + TopOpeBRepDS_Curve tcurv2(curv2,tolreached); + Icurv1=DStr.AddCurve(tcurv1); + Icurv2=DStr.AddCurve(tcurv2); + } + } + } + } + } + else { // (!inters) + Standard_NotImplemented::Raise("OneCorner : bouchon non ecrit"); + } + Standard_Integer IShape = DStr.AddShape(Fv); +#ifndef DEB + TopAbs_Orientation Et = TopAbs_FORWARD; +#else + TopAbs_Orientation Et; +#endif + if (IFadArc == 1) { + TopExp_Explorer Exp; + for (Exp.Init(Fv.Oriented(TopAbs_FORWARD), + TopAbs_EDGE);Exp.More();Exp.Next()) { + if (Exp.Current().IsSame(CV1.Arc())) { + Et = TopAbs::Reverse(TopAbs::Compose + (Exp.Current().Orientation(), + CV1.TransitionOnArc())); + break; + } + } + } + else { + TopExp_Explorer Exp; + for (Exp.Init(Fv.Oriented(TopAbs_FORWARD), + TopAbs_EDGE);Exp.More();Exp.Next()) { + if (Exp.Current().IsSame(CV2.Arc())) { + Et = TopAbs::Compose(Exp.Current().Orientation(), + CV2.TransitionOnArc()); + break; + } + } + +// + + + } + +#ifdef DEB + ChFi3d_ResultChron(ch ,t_inter); //result perf condition if (inter) + ChFi3d_InitChron(ch); // init perf condition if (onsame && inters) +#endif + + stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV1,DStr),isfirst,1); + stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV2,DStr),isfirst,2); + + if (!intcouture) { +// there is no intersection with the sewing edge +// the curve Cc is stored in the stripe +// the storage in the DS is not done by FILDS. + + TopOpeBRepDS_Curve Tc(Cc,tolreached); + ICurve = DStr.AddCurve(Tc); + Handle(TopOpeBRepDS_SurfaceCurveInterference) + Interfc = ChFi3d_FilCurveInDS(ICurve,IShape,Pc,Et); + + // 31/01/02 akm vvv : (OCC119) Prevent the builder from creating + // intersecting fillets - they are bad. + Geom2dInt_GInter anIntersector; + Geom2dAdaptor_Curve aCorkPCurve (Pc, Udeb, Ufin); + + // Take all the interferences with faces from all the stripes + // and look if their pcurves intersect our cork pcurve. + // Unfortunately, by this moment they do not exist in DStr. + ChFiDS_ListIteratorOfListOfStripe aStrIt(myListStripe); + for (; aStrIt.More(); aStrIt.Next()) + { + Handle(ChFiDS_Stripe) aCheckStripe = aStrIt.Value(); + Handle(ChFiDS_HData) aSeqData = aCheckStripe->SetOfSurfData(); + // Loop on parts of the stripe + Standard_Integer iPart; + for (iPart=1; iPart<=aSeqData->Length(); iPart++) + { + Handle(ChFiDS_SurfData) aData = aSeqData->Value(iPart); + Geom2dAdaptor_Curve anOtherPCurve; + if (IShape == aData->IndexOfS1()) + { + anOtherPCurve.Load (aData->InterferenceOnS1().PCurveOnFace(), + aData->InterferenceOnS1().FirstParameter(), + aData->InterferenceOnS1().LastParameter()); + } + else if (IShape == aData->IndexOfS2()) + { + anOtherPCurve.Load (aData->InterferenceOnS2().PCurveOnFace(), + aData->InterferenceOnS2().FirstParameter(), + aData->InterferenceOnS2().LastParameter()); + } + else + { + // Normal case - no common surface + continue; + } + if (IsEqual(anOtherPCurve.LastParameter(),anOtherPCurve.FirstParameter())) + // Degenerates + continue; + anIntersector.Perform (aCorkPCurve, anOtherPCurve, + tol2d, Precision::PConfusion()); + if (anIntersector.NbSegments() > 0 || + anIntersector.NbPoints() > 0) + StdFail_NotDone::Raise ("OneCorner : fillets have too big radiuses"); + } + } + TopOpeBRepDS_ListIteratorOfListOfInterference + anIter(DStr.ChangeShapeInterferences(IShape)); + for (; anIter.More(); anIter.Next()) + { + Handle(TopOpeBRepDS_SurfaceCurveInterference) anOtherIntrf = + Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(anIter.Value()); + // We need only interferences between cork face and curves + // of intersection with another fillet surfaces + if (anOtherIntrf.IsNull()) + continue; + // Look if there is an intersection between pcurves + Handle(Geom_TrimmedCurve) anOtherCur = + Handle(Geom_TrimmedCurve)::DownCast(DStr.Curve (anOtherIntrf->Geometry()).Curve()); + if (anOtherCur.IsNull()) + continue; + Geom2dAdaptor_Curve anOtherPCurve (anOtherIntrf->PCurve(), + anOtherCur->FirstParameter(), + anOtherCur->LastParameter()); + anIntersector.Perform (aCorkPCurve, anOtherPCurve, + tol2d, Precision::PConfusion()); + if (anIntersector.NbSegments() > 0 || + anIntersector.NbPoints() > 0) + StdFail_NotDone::Raise ("OneCorner : fillets have too big radiuses"); + } + // 31/01/02 akm ^^^ + DStr.ChangeShapeInterferences(IShape).Append(Interfc); + //// modified by jgv, 26.03.02 for OCC32 //// + ChFiDS_CommonPoint CV [2]; + CV[0] = CV1; + CV[1] = CV2; + for (Standard_Integer i = 0; i < 2; i++) + { + if (CV[i].IsOnArc() && ChFi3d_IsPseudoSeam( CV[i].Arc(), Fv )) + { + gp_Pnt2d pfac1, PcF, PcL; + gp_Vec2d DerPc, DerHc; + Standard_Real first, last, prm1, prm2; + Standard_Boolean onfirst, FirstToPar; + Handle(Geom2d_Curve) Hc = BRep_Tool::CurveOnSurface( CV[i].Arc(), Fv, first, last ); + pfac1 = Hc->Value( CV[i].ParameterOnArc() ); + PcF = Pc->Value( Udeb ); + PcL = Pc->Value( Ufin ); + onfirst = (pfac1.Distance(PcF) < pfac1.Distance(PcL))? Standard_True : Standard_False; + if (onfirst) + Pc->D1( Udeb, PcF, DerPc ); + else + { + Pc->D1( Ufin, PcL, DerPc ); + DerPc.Reverse(); + } + Hc->D1( CV[i].ParameterOnArc(), pfac1, DerHc ); + if (DerHc.Dot(DerPc) > 0.) + { + prm1 = CV[i].ParameterOnArc(); + prm2 = last; + FirstToPar = Standard_False; + } + else + { + prm1 = first; + prm2 = CV[i].ParameterOnArc(); + FirstToPar = Standard_True; + } + Handle(Geom_Curve) Ct = BRep_Tool::Curve( CV[i].Arc(), first, last ); + Ct = new Geom_TrimmedCurve( Ct, prm1, prm2 ); + Standard_Real toled = BRep_Tool::Tolerance( CV[i].Arc() ); + TopOpeBRepDS_Curve tcurv( Ct, toled ); + Handle (TopOpeBRepDS_CurvePointInterference) Interfp1, Interfp2; + Standard_Integer indcurv; + indcurv = DStr.AddCurve( tcurv ); + Standard_Integer indpoint = (isfirst)? stripe->IndexFirstPointOnS1() : stripe->IndexLastPointOnS1(); + Standard_Integer indvertex = DStr.AddShape(Vtx); + if (FirstToPar) + { + Interfp1 = ChFi3d_FilPointInDS( TopAbs_FORWARD, indcurv, indvertex, prm1, Standard_True ); + Interfp2 = ChFi3d_FilPointInDS( TopAbs_REVERSED, indcurv, indpoint, prm2, Standard_False ); + } + else + { + Interfp1 = ChFi3d_FilPointInDS( TopAbs_FORWARD, indcurv, indpoint, prm1, Standard_False ); + Interfp2 = ChFi3d_FilPointInDS( TopAbs_REVERSED, indcurv, indvertex, prm2, Standard_True ); + } + DStr.ChangeCurveInterferences(indcurv).Append(Interfp1); + DStr.ChangeCurveInterferences(indcurv).Append(Interfp2); + Standard_Integer indface = DStr.AddShape( Fv ); + Interfc = ChFi3d_FilCurveInDS( indcurv, indface, Hc, CV[i].Arc().Orientation() ); + DStr.ChangeShapeInterferences(indface).Append( Interfc ); + TopoDS_Edge aLocalEdge = CV[i].Arc(); + aLocalEdge.Reverse(); + Handle(Geom2d_Curve) HcR = BRep_Tool::CurveOnSurface( aLocalEdge, Fv, first, last ); + Interfc = ChFi3d_FilCurveInDS( indcurv, indface, HcR, aLocalEdge.Orientation() ); + DStr.ChangeShapeInterferences(indface).Append( Interfc ); + //modify degenerated edge + Standard_Boolean DegenExist = Standard_False; + TopoDS_Edge Edeg; + TopExp_Explorer Explo( Fv, TopAbs_EDGE ); + for (; Explo.More(); Explo.Next()) + { + const TopoDS_Edge& Ecur = TopoDS::Edge( Explo.Current() ); + if (BRep_Tool::Degenerated( Ecur )) + { + TopoDS_Vertex Vf, Vl; + TopExp::Vertices( Ecur, Vf, Vl ); + if (Vf.IsSame(Vtx) || Vl.IsSame(Vtx)) + { + DegenExist = Standard_True; + Edeg = Ecur; + break; + } + } + } + if (DegenExist) + { + Standard_Real fd, ld; + Handle(Geom2d_Curve) Cd = BRep_Tool::CurveOnSurface( Edeg, Fv, fd, ld ); + Handle(Geom2d_TrimmedCurve) tCd = Handle(Geom2d_TrimmedCurve)::DownCast(Cd); + if (! tCd.IsNull()) + Cd = tCd->BasisCurve(); + gp_Pnt2d P2d = (FirstToPar)? Hc->Value(first) : Hc->Value(last); + Geom2dAPI_ProjectPointOnCurve Projector( P2d, Cd ); + Standard_Real par = Projector.LowerDistanceParameter(); + Standard_Integer Ideg = DStr.AddShape(Edeg); + TopAbs_Orientation ori = (par < fd)? TopAbs_FORWARD : TopAbs_REVERSED; //if par<fd => par>ld + Interfp1 = ChFi3d_FilPointInDS( ori, Ideg, indvertex, par, Standard_True ); + DStr.ChangeShapeInterferences(Ideg).Append(Interfp1); + } + } + } + ///////////////////////////////////////////// + stripe->ChangePCurve(isfirst)=Ps; + stripe->SetCurve(ICurve,isfirst); + stripe->SetParameters(isfirst,Udeb,Ufin); + } + else { +// curves curv1 are curv2 stored in the DS +// these curves will not be reconstructed by FILDS as +// one places stripe->InDS(isfirst); + + // interferences of curv1 and curv2 on Fv + ComputeCurve2d(curv1,Fv,c2d1); + Handle(TopOpeBRepDS_SurfaceCurveInterference) InterFv; + InterFv = ChFi3d_FilCurveInDS(Icurv1,IShape,c2d1,Et); + DStr.ChangeShapeInterferences(IShape).Append(InterFv); + ComputeCurve2d(curv2,Fv,c2d2); + InterFv = ChFi3d_FilCurveInDS(Icurv2,IShape,c2d2,Et); + DStr.ChangeShapeInterferences(IShape).Append(InterFv); + // interferences of curv1 and curv2 on Isurf + if (Fd->Orientation()== Fv.Orientation()) Et=TopAbs::Reverse(Et); + c2d1=new Geom2d_TrimmedCurve(Ps,Udeb,par2); + InterFv = ChFi3d_FilCurveInDS(Icurv1,Isurf,c2d1,Et); + DStr.ChangeSurfaceInterferences(Isurf).Append(InterFv); + c2d2=new Geom2d_TrimmedCurve(Ps,par2,Ufin); + InterFv = ChFi3d_FilCurveInDS(Icurv2,Isurf,c2d2,Et); + DStr.ChangeSurfaceInterferences(Isurf).Append(InterFv); + + // limitation of the sewing edge + Standard_Integer Iarc=DStr.AddShape(edgecouture); + Handle(TopOpeBRepDS_CurvePointInterference) Interfedge; + TopAbs_Orientation ori; + TopoDS_Vertex Vdeb,Vfin; + Vdeb=TopExp::FirstVertex(edgecouture); + Vfin=TopExp::LastVertex(edgecouture); + Standard_Real pard,parf; + pard=BRep_Tool::Parameter(Vdeb,edgecouture); + parf=BRep_Tool::Parameter(Vfin,edgecouture); + if (Abs(par1-pard)<Abs(parf-par1)) ori=TopAbs_FORWARD; + else ori=TopAbs_REVERSED; + Interfedge = ChFi3d_FilPointInDS(ori,Iarc,indpt,par1); + DStr.ChangeShapeInterferences(Iarc).Append(Interfedge); + + // creation of CurveInterferences from Icurv1 and Icurv2 + stripe->InDS(isfirst); + Standard_Integer ind1= stripe->IndexPoint(isfirst,1); + Standard_Integer ind2= stripe->IndexPoint(isfirst,2); + Handle(TopOpeBRepDS_CurvePointInterference) + interfprol = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv1,ind1,Udeb); + DStr.ChangeCurveInterferences(Icurv1).Append(interfprol); + interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv1,indpt,par2); + DStr.ChangeCurveInterferences(Icurv1).Append(interfprol); + interfprol = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv2,indpt,par2); + DStr.ChangeCurveInterferences(Icurv2).Append(interfprol); + interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv2,ind2,Ufin); + DStr.ChangeCurveInterferences(Icurv2).Append(interfprol); + + } + + ChFi3d_EnlargeBox(HBs,Pc,Udeb,Ufin,box1,box2); + + if (onsame && inters) { + // VARIANT 1: + // A small missing end of curve is added for the extension + // of the face at end and the limitation of the opposing face. + + // VARIANT 2 : extend Arcprol, not create new small edge + // To do: modify for intcouture + const Standard_Boolean variant1 = Standard_True; + + // First of all the ponts are cut with the edge of the spine. + Standard_Integer IArcspine = DStr.AddShape(Arcspine); + Standard_Integer IVtx = DStr.AddShape(Vtx); +#ifndef DEB + TopAbs_Orientation OVtx = TopAbs_FORWARD; +#else + TopAbs_Orientation OVtx; +#endif + for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); + ex.More(); ex.Next()) { + if (Vtx.IsSame(ex.Current())) { + OVtx = ex.Current().Orientation(); + break; + } + } + OVtx = TopAbs::Reverse(OVtx); + Standard_Real parVtx = BRep_Tool::Parameter(Vtx,Arcspine); + Handle(TopOpeBRepDS_CurvePointInterference) + interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx); + DStr.ChangeShapeInterferences(IArcspine).Append(interfv); + + // Now the missing curves are constructed. + TopoDS_Vertex V2; + for(ex.Init(Arcprol.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); + ex.More(); ex.Next()) { + if (Vtx.IsSame(ex.Current())) + OVtx = ex.Current().Orientation(); + else + V2 = TopoDS::Vertex(ex.Current()); + } + + Handle(Geom2d_Curve) Hc; + if (variant1) + parVtx = BRep_Tool::Parameter(Vtx,Arcprol); + else + parVtx = BRep_Tool::Parameter(V2,Arcprol); + const ChFiDS_FaceInterference& Fiop = Fd->Interference(IFopArc); + gp_Pnt2d pop1, pop2, pv1, pv2; + Hc = BRep_Tool::CurveOnSurface(Arcprol,Fop,Ubid,Ubid); + pop1 = Hc->Value(parVtx); + pop2 = Fiop.PCurveOnFace()->Value(Fiop.Parameter(isfirst)); + Hc = BRep_Tool::CurveOnSurface(Arcprol,Fv,Ubid,Ubid); + pv1 = Hc->Value(parVtx); + pv2 = p2dbout; + ChFi3d_Recale(Bs,pv1,pv2,1); + TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4); + Pardeb(1) = pop1.X(); Pardeb(2) = pop1.Y(); + Pardeb(3) = pv1.X(); Pardeb(4) = pv1.Y(); + Parfin(1) = pop2.X(); Parfin(2) = pop2.Y(); + Parfin(3) = pv2.X(); Parfin(4) = pv2.Y(); + Standard_Real uu1,uu2,vv1,vv2; + ChFi3d_Boite(pv1,pv2,uu1,uu2,vv1,vv2); + ChFi3d_BoundFac(Bs,uu1,uu2,vv1,vv2); + ChFi3d_Boite(pop1,pop2,uu1,uu2,vv1,vv2); + ChFi3d_BoundFac(Bop,uu1,uu2,vv1,vv2); + + Handle(Geom_Curve) zob3d; + Handle(Geom2d_Curve) zob2dop, zob2dv; + //Standard_Real tolreached; + if (!ChFi3d_ComputeCurves(HBop,HBs,Pardeb,Parfin,zob3d,zob2dop, + zob2dv,tolesp,tol2d,tolreached)) + Standard_Failure::Raise("OneCorner : echec calcul intersection"); + + Udeb = zob3d->FirstParameter(); + Ufin = zob3d->LastParameter(); + TopOpeBRepDS_Curve Zob(zob3d,tolreached); + Standard_Integer IZob = DStr.AddCurve(Zob); + +// it is determined if Fop has an edge of sewing +// it is determined if the curve has an intersection with the edge of sewing + + //TopoDS_Edge edgecouture; + //Standard_Boolean couture; + ChFi3d_Couture(Fop,couture,edgecouture); + + if (couture && !BRep_Tool::Degenerated(edgecouture)) { + BRepLib_MakeEdge Bedge (zob3d); + TopoDS_Edge edg =Bedge. Edge(); + BRepExtrema_ExtCC extCC (edgecouture,edg); + if (extCC.IsDone()&&extCC.NbExt()!=0) { + for (Standard_Integer i=1; i<=extCC.NbExt()&&!intcouture;i++) { + if (extCC.SquareDistance(i)<=1.e-8) { + par1=extCC.ParameterOnE1(i); + par2=extCC.ParameterOnE2(i); + gp_Pnt P1=extCC.PointOnE1(i); + TopOpeBRepDS_Point tpoint(P1,1.e-4); + indpt=DStr.AddPoint(tpoint); + intcouture=Standard_True; + curv1 = new Geom_TrimmedCurve(zob3d,Udeb,par2); + curv2 = new Geom_TrimmedCurve(zob3d,par2,Ufin); + TopOpeBRepDS_Curve tcurv1(curv1,tolreached); + TopOpeBRepDS_Curve tcurv2(curv2,tolreached); + Icurv1=DStr.AddCurve(tcurv1); + Icurv2=DStr.AddCurve(tcurv2); + } + } + } + } + if (intcouture) { + +// interference of curv1 and curv2 on Ishape + Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolv)); + ComputeCurve2d(curv1,Fop,c2d1); + Handle(TopOpeBRepDS_SurfaceCurveInterference) + InterFv = ChFi3d_FilCurveInDS(Icurv1,IShape,/*zob2dv*/c2d1,Et); + DStr.ChangeShapeInterferences(IShape).Append(InterFv); + ComputeCurve2d(curv2,Fop,c2d2); + InterFv = ChFi3d_FilCurveInDS(Icurv2,IShape,/*zob2dv*/c2d2,Et); + DStr.ChangeShapeInterferences(IShape).Append(InterFv); + + // limitation of the sewing edge + Standard_Integer Iarc=DStr.AddShape(edgecouture); + Handle(TopOpeBRepDS_CurvePointInterference) Interfedge; + TopAbs_Orientation ori; + TopoDS_Vertex Vdeb,Vfin; + Vdeb=TopExp::FirstVertex(edgecouture); + Vfin=TopExp::LastVertex(edgecouture); + Standard_Real pard,parf; + pard=BRep_Tool::Parameter(Vdeb,edgecouture); + parf=BRep_Tool::Parameter(Vfin,edgecouture); + if (Abs(par1-pard)<Abs(parf-par1)) ori=TopAbs_REVERSED; + else ori=TopAbs_FORWARD; + Interfedge = ChFi3d_FilPointInDS(ori,Iarc,indpt,par1); + DStr.ChangeShapeInterferences(Iarc).Append(Interfedge); + + // interference of curv1 and curv2 on Iop + Standard_Integer Iop = DStr.AddShape(Fop); + Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolop)); + Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfop; + ComputeCurve2d(curv1,Fop,c2d1); + Interfop = ChFi3d_FilCurveInDS(Icurv1,Iop,c2d1,Et); + DStr.ChangeShapeInterferences(Iop).Append(Interfop); + ComputeCurve2d(curv2,Fop,c2d2); + Interfop = ChFi3d_FilCurveInDS(Icurv2,Iop,c2d2,Et); + DStr.ChangeShapeInterferences(Iop).Append(Interfop); + Handle(TopOpeBRepDS_CurvePointInterference) + interfprol = ChFi3d_FilVertexInDS(TopAbs_FORWARD,Icurv1,IVtx,Udeb); + DStr.ChangeCurveInterferences(Icurv1).Append(interfprol); + interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv1,indpt,par2); + DStr.ChangeCurveInterferences(Icurv1).Append(interfprol); + Standard_Integer icc = stripe->IndexPoint(isfirst,IFopArc); + interfprol = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv2,indpt,par2); + DStr.ChangeCurveInterferences(Icurv2).Append(interfprol); + interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv2,icc,Ufin); + DStr.ChangeCurveInterferences(Icurv2).Append(interfprol); + } + else { + Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolv)); + Handle(TopOpeBRepDS_SurfaceCurveInterference) + InterFv = ChFi3d_FilCurveInDS(IZob,IShape,zob2dv,Et); + DStr.ChangeShapeInterferences(IShape).Append(InterFv); + Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolop)); + Standard_Integer Iop = DStr.AddShape(Fop); + Handle(TopOpeBRepDS_SurfaceCurveInterference) + Interfop = ChFi3d_FilCurveInDS(IZob,Iop,zob2dop,Et); + DStr.ChangeShapeInterferences(Iop).Append(Interfop); + Handle(TopOpeBRepDS_CurvePointInterference) interfprol; + if (variant1) + interfprol = ChFi3d_FilVertexInDS(TopAbs_FORWARD,IZob,IVtx,Udeb); + else { + Standard_Integer IV2 = DStr.AddShape(V2); // VARIANT 2 + interfprol = ChFi3d_FilVertexInDS(TopAbs_FORWARD,IZob,IV2,Udeb); + } + DStr.ChangeCurveInterferences(IZob).Append(interfprol); + Standard_Integer icc = stripe->IndexPoint(isfirst,IFopArc); + interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,IZob,icc,Ufin); + DStr.ChangeCurveInterferences(IZob).Append(interfprol); + if (variant1) { + if (IFopArc == 1) box1.Add( zob3d->Value(Ufin) ); + else box2.Add( zob3d->Value(Ufin) ); + } + else { + // cut off existing Arcprol + Standard_Integer iArcprol = DStr.AddShape(Arcprol); + interfprol = ChFi3d_FilPointInDS(OVtx,iArcprol,icc,Udeb); + DStr.ChangeShapeInterferences(Arcprol).Append(interfprol); + } + } + } + ChFi3d_EnlargeBox(DStr,stripe,Fd,box1,box2,isfirst); + if (CV1.IsOnArc()) { + ChFi3d_EnlargeBox(CV1.Arc(),myEFMap(CV1.Arc()),CV1.ParameterOnArc(),box1); + } + if (CV2.IsOnArc()) { + ChFi3d_EnlargeBox(CV2.Arc(),myEFMap(CV2.Arc()),CV2.ParameterOnArc(),box2); + } + if (!CV1.IsVertex()) + ChFi3d_SetPointTolerance(DStr,box1,stripe->IndexPoint(isfirst,1)); + if (!CV2.IsVertex()) + ChFi3d_SetPointTolerance(DStr,box2,stripe->IndexPoint(isfirst,2)); + +#ifdef DEB + ChFi3d_ResultChron(ch, t_sameinter);//result perf condition if (same &&inter) +#endif +} + +//======================================================================= +//function : cherche_face +//purpose : find face F belonging to the map, different from faces +// F1 F2 F3 and containing edge E +//======================================================================= + +static void cherche_face (const TopTools_ListOfShape & map, + const TopoDS_Edge & E, + const TopoDS_Face & F1, + const TopoDS_Face & F2, + const TopoDS_Face & F3, + TopoDS_Face & F) +{ TopoDS_Face Fcur; + Standard_Boolean trouve=Standard_False; + TopTools_ListIteratorOfListOfShape It; + Standard_Integer ie; + for (It.Initialize(map);It.More()&&!trouve;It.Next()) + { Fcur=TopoDS::Face (It.Value()); + if (!Fcur.IsSame(F1) && !Fcur.IsSame(F2)&& !Fcur.IsSame(F3) ) + { TopTools_IndexedMapOfShape MapE; + TopExp::MapShapes( Fcur,TopAbs_EDGE,MapE); + for ( ie=1; ie<= MapE.Extent()&&!trouve; ie++) + { + TopoDS_Shape aLocalShape = TopoDS_Shape (MapE(ie)); + if (E.IsSame(TopoDS::Edge(aLocalShape))) + // if (E.IsSame(TopoDS::Edge(TopoDS_Shape (MapE(ie))))) + { F= Fcur; trouve=Standard_True;} + } + } + } +} + +//======================================================================= +//function : cherche_edge1 +//purpose : find common edge between faces F1 and F2 +//======================================================================= + +static void cherche_edge1 (const TopoDS_Face & F1, + const TopoDS_Face & F2, + TopoDS_Edge & Edge) +{ Standard_Integer i,j; + TopoDS_Edge Ecur1,Ecur2; + Standard_Boolean trouve=Standard_False; + TopTools_IndexedMapOfShape MapE1,MapE2; + TopExp::MapShapes( F1,TopAbs_EDGE,MapE1); + TopExp::MapShapes( F2,TopAbs_EDGE,MapE2); + for ( i=1; i<= MapE1.Extent()&&!trouve; i++) + { + TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(i)); + Ecur1=TopoDS::Edge(aLocalShape); +// Ecur1=TopoDS::Edge(TopoDS_Shape (MapE1(i))); + for ( j=1; j<= MapE2.Extent()&&!trouve; j++) + { + aLocalShape = TopoDS_Shape (MapE2(j)); + Ecur2=TopoDS::Edge(aLocalShape); +// Ecur2=TopoDS::Edge(TopoDS_Shape (MapE2(j))); + if (Ecur2.IsSame(Ecur1)) + {Edge=Ecur1;trouve=Standard_True;} + } + } +} + +//======================================================================= +//function : containV +//purpose : return true if vertex V belongs to F1 +//======================================================================= + +static Standard_Boolean containV(const TopoDS_Face & F1, + const TopoDS_Vertex & V) +{ Standard_Integer i; + TopoDS_Vertex Vcur; + Standard_Boolean trouve=Standard_False; + Standard_Boolean contain=Standard_False; + TopTools_IndexedMapOfShape MapV; + TopExp::MapShapes( F1,TopAbs_VERTEX,MapV); + for ( i=1; i<= MapV.Extent()&&!trouve; i++) + { + TopoDS_Shape aLocalShape = TopoDS_Shape (MapV(i)); + Vcur=TopoDS::Vertex(aLocalShape); +// Vcur=TopoDS::Vertex(TopoDS_Shape (MapV(i))); + if (Vcur.IsSame(V) ) + {contain=Standard_True; trouve=Standard_True;} + } + return contain; +} + +//======================================================================= +//function : containE +//purpose : return true if edge E belongs to F1 +//======================================================================= + +static Standard_Boolean containE(const TopoDS_Face & F1, + const TopoDS_Edge & E) +{ Standard_Integer i; + TopoDS_Edge Ecur; + Standard_Boolean trouve=Standard_False; + Standard_Boolean contain=Standard_False; + TopTools_IndexedMapOfShape MapE; + TopExp::MapShapes( F1,TopAbs_EDGE,MapE); + for ( i=1; i<= MapE.Extent()&&!trouve; i++) + { + TopoDS_Shape aLocalShape = TopoDS_Shape (MapE(i)); + Ecur=TopoDS::Edge(aLocalShape); +// Ecur=TopoDS::Edge(TopoDS_Shape (MapE(i))); + if (Ecur.IsSame(E) ) + {contain=Standard_True; trouve=Standard_True;} + } + return contain; +} + + +//======================================================================= +//function : IsShrink +//purpose : check if U (if <isU>==True) or V of points of <PC> is within +// <tol> from <Param>, check points between <Pf> and <Pl> +//======================================================================= + +static Standard_Boolean IsShrink(const Geom2dAdaptor_Curve PC, + const Standard_Real Pf, + const Standard_Real Pl, + const Standard_Real Param, + const Standard_Boolean isU, + const Standard_Real tol) +{ + switch (PC.GetType()) { + case GeomAbs_Line: { + gp_Pnt2d P1 = PC.Value(Pf); + gp_Pnt2d P2 = PC.Value(Pl); + if (Abs(P1.Coord(isU ? 1 : 2) - Param) <= tol && + Abs(P2.Coord(isU ? 1 : 2) - Param) <= tol ) + return Standard_True; + else + return Standard_False; + } + case GeomAbs_BezierCurve: + case GeomAbs_BSplineCurve: { + math_FunctionSample aSample (Pf,Pl,10); + Standard_Integer i; + for (i=1; i<=aSample.NbPoints(); i++) { + gp_Pnt2d P = PC.Value(aSample.GetParameter(i)); + if (Abs(P.Coord(isU ? 1 : 2) - Param) > tol ) + return Standard_False; + } + return Standard_True; + } + default:; + } + return Standard_False; +} +//======================================================================= +//function : PerformIntersectionAtEnd +//purpose : +//======================================================================= + +void ChFi3d_Builder::PerformIntersectionAtEnd(const Standard_Integer Index) +{ + + // intersection at end of fillet with at least two faces + // process the following cases: + // - top has n (n>3) adjacent edges + // - top has 3 edges and fillet on one of edges touches + // more than one face + +#ifdef DEB + OSD_Chronometer ch;// init perf +#endif + + TopOpeBRepDS_DataStructure& DStr= myDS->ChangeDS(); + const Standard_Integer nn=15; + ChFiDS_ListIteratorOfListOfStripe It; + It.Initialize(myVDataMap(Index)); + Handle(ChFiDS_Stripe) stripe = It.Value(); + const Handle(ChFiDS_Spine) spine = stripe->Spine(); + ChFiDS_SequenceOfSurfData& SeqFil = + stripe->ChangeSetOfSurfData()->ChangeSequence(); + const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index); + Standard_Integer sens = 0,num,num1; + Standard_Boolean couture=Standard_False,isfirst; + //Standard_Integer sense; + TopoDS_Edge edgelibre1,edgelibre2,EdgeSpine; + Standard_Boolean bordlibre; + // determine the number of faces and edges + TopTools_Array1OfShape tabedg(0,nn); + TopoDS_Face F1,F2; + Standard_Integer nface=ChFi3d_nbface(myVFMap(Vtx)); + TopTools_ListIteratorOfListOfShape ItF; + Standard_Integer nbarete; + nbarete=ChFi3d_NbNotDegeneratedEdges(Vtx,myVEMap); + ChFi3d_ChercheBordsLibres(myVEMap,Vtx,bordlibre,edgelibre1,edgelibre2); + if (bordlibre) nbarete=(nbarete-2)/2 +2; + else nbarete=nbarete/2; + // it is determined if there is an edge of sewing and it face + + TopoDS_Face facecouture; + TopoDS_Edge edgecouture; + + Standard_Boolean trouve=Standard_False; + for(ItF.Initialize(myVFMap(Vtx));ItF.More()&&!couture;ItF.Next()) { + TopoDS_Face fcur = TopoDS::Face(ItF.Value()); + ChFi3d_CoutureOnVertex(fcur,Vtx,couture,edgecouture); + if (couture) + facecouture=fcur; + } + // it is determined if one of edges adjacent to the fillet is regular + Standard_Boolean reg1,reg2; + TopoDS_Edge Ecur,Eadj1,Eadj2; + TopoDS_Face Fga,Fdr; + TopoDS_Vertex Vbid1; + Standard_Integer nbsurf,nbedge; + reg1=Standard_False; + reg2=Standard_False; + nbsurf= SeqFil.Length(); + nbedge = spine->NbEdges(); + num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens); + isfirst = (sens == 1); + ChFiDS_State state; + if (isfirst) { + EdgeSpine=spine->Edges(1); + num1=num+1; + state = spine->FirstStatus(); + } + else { + EdgeSpine=spine->Edges(nbedge); + num1=num-1; + state = spine->LastStatus(); + } + if (nbsurf!=nbedge && nbsurf!=1) { + ChFi3d_edge_common_faces(myEFMap(EdgeSpine),F1,F2); + if (F1.IsSame(facecouture)) Eadj1=edgecouture; + else ChFi3d_cherche_element(Vtx,EdgeSpine,F1,Eadj1,Vbid1); + ChFi3d_edge_common_faces(myEFMap(Eadj1),Fga,Fdr); +// Modified by Sergey KHROMOV - Fri Dec 21 17:57:32 2001 Begin +// reg1=BRep_Tool::Continuity(Eadj1,Fga,Fdr)!=GeomAbs_C0; + reg1=isTangentFaces(Eadj1,Fga,Fdr); +// Modified by Sergey KHROMOV - Fri Dec 21 17:57:33 2001 End + if (F2.IsSame(facecouture)) Eadj2=edgecouture; + else ChFi3d_cherche_element(Vtx,EdgeSpine,F2,Eadj2,Vbid1); + ChFi3d_edge_common_faces(myEFMap(Eadj2),Fga,Fdr); +// Modified by Sergey KHROMOV - Fri Dec 21 17:58:22 2001 Begin +// reg2=BRep_Tool::Continuity(Eadj2,Fga,Fdr)!=GeomAbs_C0; + reg2=isTangentFaces(Eadj2,Fga,Fdr); +// Modified by Sergey KHROMOV - Fri Dec 21 17:58:24 2001 End + +// two faces common to the edge are found + if (reg1 || reg2) { + Standard_Boolean compoint1=Standard_False; + Standard_Boolean compoint2=Standard_False; + ChFiDS_CommonPoint cp1, cp2; + cp1 = SeqFil(num1)->ChangeVertex (isfirst,1); + cp2 = SeqFil(num1)->ChangeVertex (isfirst,2); + if (cp1.IsOnArc()) { + if (cp1.Arc().IsSame(Eadj1)||cp1.Arc().IsSame(Eadj2)) + compoint1=Standard_True; + } + if (cp2.IsOnArc()) { + if (cp2.Arc().IsSame(Eadj1)||cp2.Arc().IsSame(Eadj2)) + compoint2=Standard_True; + } + if (compoint1 && compoint2) { + SeqFil.Remove(num); + reg1=Standard_False; reg2=Standard_False; + } + } + } +// there is only one face at end if FindFace is true and if the face +// is not the face with sewing edge + TopoDS_Face face; + Handle(ChFiDS_SurfData) Fd = SeqFil.ChangeValue(num); + ChFiDS_CommonPoint& CV1 = Fd->ChangeVertex(isfirst,1); + ChFiDS_CommonPoint& CV2 = Fd->ChangeVertex(isfirst,2); + Standard_Boolean onecorner=Standard_False; + if (FindFace(Vtx,CV1,CV2,face)) { + if (!couture) onecorner =Standard_True; + else if (!face.IsSame(facecouture)) + onecorner=Standard_True; + } + if (onecorner) { + if (ChFi3d_Builder::MoreSurfdata(Index)) { + ChFi3d_Builder::PerformMoreSurfdata(Index); + return; + } + } + if (!onecorner && (reg1||reg2) && !couture && state!=ChFiDS_OnSame) { + PerformMoreThreeCorner (Index,1); + return; + } + Handle(GeomAdaptor_HSurface) HGs = ChFi3d_BoundSurf(DStr,Fd,1,2); + ChFiDS_FaceInterference Fi1 = Fd->InterferenceOnS1(); + ChFiDS_FaceInterference Fi2 = Fd->InterferenceOnS2(); + GeomAdaptor_Surface& Gs = HGs->ChangeSurface(); + Handle(BRepAdaptor_HSurface) HBs = new BRepAdaptor_HSurface(); + BRepAdaptor_Surface& Bs = HBs->ChangeSurface(); + Handle(Geom_Curve) Cc; + Handle(Geom2d_Curve) Pc,Ps; + Standard_Real Ubid,Vbid; + TopAbs_Orientation orsurfdata; + orsurfdata=Fd->Orientation(); + Standard_Integer IsurfPrev=0, Isurf=Fd->Surf(); + Handle(ChFiDS_SurfData) SDprev; + if (num1>0 && num1<=SeqFil.Length()) { + SDprev = SeqFil(num1); + IsurfPrev = SDprev->Surf(); + } + // calculate the orientation of curves at end + + Standard_Real tolpt=1.e-4; + Standard_Real tolreached; + TopAbs_Orientation orcourbe,orface,orien; + + stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV1,DStr),isfirst,1); + stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV2,DStr),isfirst,2); + +// gp_Pnt p3d; +// gp_Pnt2d p2d; + Standard_Real dist; + Standard_Integer Ishape1=Fd->IndexOfS1(); +#ifndef DEB + TopAbs_Orientation trafil1 = TopAbs_FORWARD; +#else + TopAbs_Orientation trafil1; +#endif + if (Ishape1 != 0) { + if (Ishape1 > 0) { + trafil1 = DStr.Shape(Ishape1).Orientation(); + } +#ifdef DEB + else { + cout<<"erreur"<<endl; + } +#endif + trafil1 = TopAbs::Compose(trafil1,Fd->Orientation()); + + trafil1 = TopAbs::Compose(TopAbs::Reverse(Fi1.Transition()),trafil1); + } +#ifdef DEB + else cout<<"erreur"<<endl; +#endif + // eap, Apr 22 2002, occ 293 +// Fi1.PCurveOnFace()->D0(Fi1.LastParameter(),p2d); +// const Handle(Geom_Surface) Stemp = +// BRep_Tool::Surface(TopoDS::Face(DStr.Shape(Ishape1))); +// Stemp ->D0(p2d.X(),p2d.Y(),p3d); +// dist=p3d.Distance(CV1.Point()); +// if (dist<tolpt) orcourbe=trafil1; +// else orcourbe=TopAbs::Reverse(trafil1); + if (!isfirst) orcourbe=trafil1; + else orcourbe=TopAbs::Reverse(trafil1); + + // eap, Apr 22 2002, occ 293 + // variables to show OnSame situation + Standard_Boolean isOnSame1, isOnSame2; + // In OnSame situation, the case of degenerated FaceInterference curve + // is probable when a corner cuts the ChFi3d earlier built on OnSame edge. + // In such a case, chamfer face can partially shrink to a line and we need + // to cut off that shrinked part + // If <isOnSame1>, FaceInterference with F2 can be degenerated + Standard_Boolean checkShrink, isShrink, isUShrink; + isShrink = isUShrink = isOnSame1 = isOnSame2 = Standard_False; + Standard_Real checkShrParam=0., prevSDParam=0.; + gp_Pnt2d midP2d; + Standard_Integer midIpoint=0; + + // find Fi1,Fi2 lengths used to extend ChFi surface + // and by the way define necessity to check shrink + gp_Pnt2d P2d1=Fi1.PCurveOnSurf()->Value(Fi1.Parameter(isfirst)); + gp_Pnt2d P2d2=Fi1.PCurveOnSurf()->Value(Fi1.Parameter(!isfirst)); + gp_Pnt aP1,aP2; + HGs->D0( P2d1.X(),P2d1.Y(),aP1); + HGs->D0( P2d2.X(),P2d2.Y(),aP2); + Standard_Real Fi1Length=aP1.Distance(aP2); +// Standard_Real eps = Precision::Confusion(); + checkShrink = (Fi1Length <= Precision::Confusion()); + + gp_Pnt2d P2d3=Fi2.PCurveOnSurf()->Value(Fi2.Parameter(isfirst)); + gp_Pnt2d P2d4=Fi2.PCurveOnSurf()->Value(Fi2.Parameter(!isfirst)); + HGs->D0( P2d3.X(),P2d3.Y(),aP1); + HGs->D0( P2d4.X(),P2d4.Y(),aP2); + Standard_Real Fi2Length=aP1.Distance(aP2); + checkShrink = checkShrink || (Fi2Length <= Precision::Confusion()); + + if (checkShrink) { + if (Abs(P2d2.Y()-P2d4.Y()) <= Precision::PConfusion()) { + isUShrink = Standard_False; + checkShrParam = P2d2.Y(); + } else if (Abs(P2d2.X()-P2d4.X()) <= Precision::PConfusion()) { + isUShrink = Standard_True; + checkShrParam = P2d2.X(); + } + else + checkShrink = Standard_False; + } + + /***********************************************************************/ + // find faces intersecting with the fillet and edges limiting intersections + // nbface is the nb of faces intersected, Face[i] contais the faces + // to intersect (i=0.. nbface-1). Edge[i] contains edges limiting + // the intersections (i=0 ..nbface) + /**********************************************************************/ + + Standard_Integer nb = 1,nbface; + TopoDS_Edge E1 ,E2, Edge[nn],E,Ei,edgesau; + TopoDS_Face facesau; + Standard_Boolean oneintersection1=Standard_False; + Standard_Boolean oneintersection2=Standard_False; + TopoDS_Face Face[nn],F,F3; + TopoDS_Vertex V1,V2,V,Vfin; + Standard_Boolean findonf1=Standard_False,findonf2=Standard_False; + TopTools_ListIteratorOfListOfShape It3; + F1=TopoDS::Face(DStr.Shape(Fd->IndexOfS1())); + F2=TopoDS::Face(DStr.Shape(Fd->IndexOfS2())); + F3=F1; + if (couture || bordlibre) nface=nface+1; + if (nface==3) nbface=2; + else nbface=nface-2; + if (!CV1.IsOnArc()||!CV2.IsOnArc()) { + PerformMoreThreeCorner(Index,1); + return; + } + + Edge[0]=CV1.Arc(); + Edge[nbface]=CV2.Arc(); + tabedg.SetValue(0,Edge[0]); + tabedg.SetValue(nbface,Edge[nbface]); + // processing of a fillet arriving on a vertex + // edge contained in CV.Arc is not inevitably good + // the edge concerned by the intersection is found + + Standard_Real dist1,dist2; + if (CV1.IsVertex()) { + trouve=Standard_False; + /*TopoDS_Vertex */V=CV1.Vertex(); + for (It3.Initialize(myVEMap(V));It3.More()&&!trouve;It3.Next()) { + E=TopoDS::Edge (It3.Value()); + if (!E.IsSame(Edge[0])&&(containE(F1,E))) + trouve=Standard_True; + } + TopoDS_Vertex Vt,V3,V4; + V1=TopExp::FirstVertex(Edge[0]); + V2=TopExp::LastVertex(Edge[0]); + if (V.IsSame(V1)) Vt=V2; + else Vt=V1; + dist1=(BRep_Tool::Pnt(Vt)).Distance(BRep_Tool::Pnt(Vtx)); + V3=TopExp::FirstVertex(E); + V4=TopExp::LastVertex(E); + if (V.IsSame(V3)) Vt=V4; + else Vt=V3; + dist2=(BRep_Tool::Pnt(Vt)).Distance(BRep_Tool::Pnt(Vtx)); + if (dist2<dist1) { + Edge[0]=E; + TopAbs_Orientation ori; + if (V2.IsSame(V3)||V1.IsSame(V4)) ori=CV1.TransitionOnArc(); + else ori=TopAbs::Reverse(CV1.TransitionOnArc()); + Standard_Real par= BRep_Tool::Parameter(V,Edge[0]); + Standard_Real tol= CV1.Tolerance(); + CV1.SetArc(tol,Edge[0],par,ori); + } + } + + if (CV2.IsVertex()) { + trouve=Standard_False; + /*TopoDS_Vertex*/ V=CV2.Vertex(); + for (It3.Initialize(myVEMap(V));It3.More()&&!trouve;It3.Next()) { + E=TopoDS::Edge (It3.Value()); + if (!E.IsSame(Edge[2])&&(containE(F2,E))) + trouve=Standard_True; + } + TopoDS_Vertex Vt,V3,V4; + V1=TopExp::FirstVertex(Edge[2]); + V2=TopExp::LastVertex(Edge[2]); + if (V.IsSame(V1)) Vt=V2; + else Vt=V1; + dist1=(BRep_Tool::Pnt(Vt)).Distance(BRep_Tool::Pnt(Vtx)); + V3=TopExp::FirstVertex(E); + V4=TopExp::LastVertex(E); + if (V.IsSame(V3)) Vt=V4; + else Vt=V3; + dist2=(BRep_Tool::Pnt(Vt)).Distance(BRep_Tool::Pnt(Vtx)); + if (dist2<dist1) { + Edge[2]=E; + TopAbs_Orientation ori; + if (V2.IsSame(V3)||V1.IsSame(V4)) ori=CV2.TransitionOnArc(); + else ori=TopAbs::Reverse(CV2.TransitionOnArc()); + Standard_Real par= BRep_Tool::Parameter(V,Edge[2]); + Standard_Real tol= CV2.Tolerance(); + CV2.SetArc(tol,Edge[2],par,ori); + } + } + if (!onecorner) { + // If there is a regular edge, the faces adjacent to it + // are not in Fd->IndexOfS1 or Fd->IndexOfS2 + +// TopoDS_Face Find1 ,Find2; +// if (isfirst) +// edge=stripe->Spine()->Edges(1); +// else edge=stripe->Spine()->Edges(stripe->Spine()->NbEdges()); +// It3.Initialize(myEFMap(edge)); +// Find1=TopoDS::Face(It3.Value()); +// trouve=Standard_False; +// for (It3.Initialize(myEFMap(edge));It3.More()&&!trouve;It3.Next()) { +// F=TopoDS::Face (It3.Value()); +// if (!F.IsSame(Find1)) { +// Find2=F;trouve=Standard_True; +// } +// } + + // if nface =3 there is a top with 3 edges and a fillet + // and their common points are on different faces + // otherwise there is a case when a top has more than 3 edges + + if (nface==3) { + if (CV1.IsVertex ()) findonf1=Standard_True; + if (CV2.IsVertex ()) findonf2=Standard_True; + if (!findonf1) { + TopTools_IndexedMapOfShape MapV; + TopExp::MapShapes(Edge[0], TopAbs_VERTEX, MapV); + if (MapV.Extent()==2) + if (!MapV(1).IsSame(Vtx) && !MapV(2).IsSame(Vtx)) + findonf1=Standard_True; + } + if (!findonf2) { + TopTools_IndexedMapOfShape MapV; + TopExp::MapShapes(Edge[2], TopAbs_VERTEX, MapV); + if (MapV.Extent()==2) + if (!MapV(1).IsSame(Vtx) && !MapV(2).IsSame(Vtx)) + findonf2=Standard_True; + } + + // detect and process OnSame situatuation + if (state == ChFiDS_OnSame) { + TopoDS_Edge threeE[3]; + ChFi3d_cherche_element(Vtx,EdgeSpine, F1,threeE[0], V2); + ChFi3d_cherche_element(Vtx,EdgeSpine, F2,threeE[1], V2); + threeE[2] = EdgeSpine; + if (ChFi3d_EdgeState(threeE,myEFMap) == ChFiDS_OnSame) { + isOnSame1 = Standard_True; + nb = 1; + Edge[0] = threeE[0]; + ChFi3d_cherche_face1(myEFMap(Edge[0]),F1,Face[0]); + if (findonf2) + findonf1 = Standard_True; // not to look for Face[0] again + else + Edge[1]=CV2.Arc(); + } + else { + isOnSame2 = Standard_True; + } + } + + // findonf1 findonf2 show if F1 and/or F2 are adjacent + // to many faces at end + // the faces at end and intersected edges are found + + if (findonf1 && !isOnSame1) { + if (CV1.TransitionOnArc()==TopAbs_FORWARD) + V1=TopExp::FirstVertex(CV1.Arc()); + else + V1=TopExp::LastVertex(CV1.Arc()); + ChFi3d_cherche_face1(myEFMap(CV1.Arc()),F1,Face[0]); + nb=1; + Ei=Edge[0]; + while (!V1.IsSame(Vtx)) { + ChFi3d_cherche_element(V1,Ei,F1,E,V2); + V1=V2; Ei=E; + ChFi3d_cherche_face1(myEFMap(E),F1,Face[nb]); + cherche_edge1(Face[nb-1],Face[nb],Edge[nb]); + nb++; + if (nb>=nn) Standard_Failure::Raise + ("IntersectionAtEnd : the max number of faces reached"); + } + if (!findonf2) Edge[nb]=CV2.Arc(); + } + if (findonf2 && !isOnSame2) { + if (!findonf1 ) nb=1; + V1=Vtx; + if (CV2.TransitionOnArc()==TopAbs_FORWARD) + Vfin=TopExp::LastVertex(CV2.Arc()); + else + Vfin=TopExp::FirstVertex(CV2.Arc()); + if (!findonf1) ChFi3d_cherche_face1(myEFMap(CV1.Arc()),F1,Face[nb-1]); + ChFi3d_cherche_element(V1,EdgeSpine,F2,E,V2); + Ei=E;V1=V2; + while (!V1.IsSame(Vfin)) { + ChFi3d_cherche_element(V1,Ei,F2,E,V2); + Ei=E; + V1=V2; + ChFi3d_cherche_face1(myEFMap(E),F2,Face[nb]); + cherche_edge1(Face[nb-1],Face[nb],Edge[nb]); + nb++; + if (nb>=nn) Standard_Failure::Raise + ("IntersectionAtEnd : the max number of faces reached"); + } + Edge[nb]=CV2.Arc(); + } + if (isOnSame2) { + cherche_edge1(Face[nb-1],F2,Edge[nb]); + Face[nb] = F2; + } + + nbface=nb; + } + + else { + +// this is the case when a top has more than three edges +// the faces and edges concerned are found + Standard_Boolean /*trouve,*/possible1, possible2; + trouve = possible1 = possible2 = Standard_False; + TopExp_Explorer ex; + nb=0; + for (ex.Init(CV1.Arc(),TopAbs_VERTEX);ex.More();ex.Next()) { + if (Vtx.IsSame(ex.Current())) possible1 = Standard_True; + } + for (ex.Init(CV2.Arc(),TopAbs_VERTEX);ex.More();ex.Next()) { + if (Vtx.IsSame(ex.Current())) possible2 = Standard_True; + } + if ((possible1 && possible2) || (!possible1 && !possible2) || (nbarete > 4)) { + while (!trouve) { + nb++; + if (nb!=1) F3=Face[nb-2]; + Face[nb-1]=F3; + if (CV1.Arc().IsSame(edgelibre1)) + cherche_face(myVFMap(Vtx),edgelibre2,F1,F2,F3,Face[nb-1]); + else if (CV1.Arc().IsSame(edgelibre2)) + cherche_face(myVFMap(Vtx),edgelibre1,F1,F2,F3,Face[nb-1]); + else cherche_face(myVFMap(Vtx),Edge[nb-1],F1,F2,F3,Face[nb-1]); + ChFi3d_cherche_edge(Vtx,tabedg,Face[nb-1],Edge[nb],V); + tabedg.SetValue(nb,Edge[nb]); + if (Edge[nb].IsSame(CV2.Arc())) trouve=Standard_True; + } + nbface=nb; + } + else { + IntersectMoreCorner (Index); + return; + } + if (nbarete==4) { + // if two consecutive edges are G1 there is only one face of intersection + Standard_Real ang1=0.0; + TopoDS_Vertex Vcom; + trouve=Standard_False; + ChFi3d_cherche_vertex ( Edge[0],Edge[1],Vcom,trouve); + if (Vcom.IsSame(Vtx)) ang1=ChFi3d_AngleEdge(Vtx,Edge[0],Edge[1]); + if (Abs(ang1-PI)<0.01) { + oneintersection1=Standard_True; + facesau=Face[0]; + edgesau=Edge[1]; + Face[0]=Face[1]; + Edge[1]=Edge[2]; + nbface=1; + } + + if (!oneintersection1) { + trouve=Standard_False; + ChFi3d_cherche_vertex ( Edge[1],Edge[2],Vcom,trouve); + if (Vcom.IsSame(Vtx)) ang1=ChFi3d_AngleEdge(Vtx,Edge[1],Edge[2]); + if (Abs(ang1-PI)<0.01) { + oneintersection2=Standard_True; + facesau=Face[1]; + edgesau=Edge[1]; + Edge[1]=Edge[2]; + nbface=1; + } + } + } + else if (nbarete==5) { + //pro15368 +// Modified by Sergey KHROMOV - Fri Dec 21 18:07:43 2001 End + Standard_Boolean isTangent0 = isTangentFaces(Edge[0],F1,Face[0]); + Standard_Boolean isTangent1 = isTangentFaces(Edge[1],Face[0],Face[1]); + Standard_Boolean isTangent2 = isTangentFaces(Edge[2],Face[1],Face[2]); + if ((isTangent0 || isTangent2) && isTangent1) { +// GeomAbs_Shape cont0,cont1,cont2; +// cont0=BRep_Tool::Continuity(Edge[0],F1,Face[0]); +// cont1=BRep_Tool::Continuity(Edge[1],Face[0],Face[1]); +// cont2=BRep_Tool::Continuity(Edge[2],Face[1],Face[2]); +// if ((cont0!=GeomAbs_C0 || cont2!=GeomAbs_C0) && cont1!=GeomAbs_C0) { +// Modified by Sergey KHROMOV - Fri Dec 21 18:07:49 2001 Begin + facesau=Face[0]; + edgesau=Edge[0]; + nbface=1; + Edge[1]=Edge[3]; + Face[0]=Face[2]; + oneintersection1=Standard_True; + } + } + } + } + else { + nbface=1; + Face[0]=face; + Edge[1]=Edge[2]; + } + + TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4); + gp_Pnt2d pfil1,pfac1,pfil2,pfac2,pint,pfildeb; + Handle(Geom2d_Curve) Hc1,Hc2; + IntCurveSurface_HInter inters; + Standard_Integer proledge[nn],prolface[nn+1];// last prolface[nn] is for Fd + Standard_Integer shrink[nn]; + TopoDS_Face faceprol[nn]; + Standard_Integer indcurve[nn],indpoint2=0,indpoint1 = 0; + Handle (TopOpeBRepDS_CurvePointInterference) Interfp1, Interfp2, Interfedge[nn]; + Handle (TopOpeBRepDS_SurfaceCurveInterference) Interfc,InterfPC[nn],InterfPS[nn]; + Standard_Real u2,v2,p1,p2,paredge1; + Standard_Real paredge2 = 0.,tolex = 1.e-4; + Standard_Boolean extend=Standard_False; + Handle(Geom_Surface) Sfacemoins1,Sface; + /***************************************************************************/ + // calculate intersection of the fillet and each face + // and storage in the DS + /***************************************************************************/ + for (nb=1;nb<=nbface;nb++) { + prolface[nb-1]=0; + proledge[nb-1]=0; + shrink [nb-1]=0; + } + proledge[nbface]=0; + prolface[nn]=0; + if (oneintersection1||oneintersection2) faceprol[1]=facesau; + if (!isOnSame1 && !isOnSame2) + checkShrink = Standard_False; + // in OnSame situation we need intersect Fd with Edge[0] or Edge[nbface] as well + if (isOnSame1) nb=0; + else nb=1; + Standard_Boolean intersOnSameFailed = Standard_False; + + for ( ; nb<=nbface; nb++) { + extend=Standard_False; + E2=Edge[nb]; + if (!nb) + F=F1; + else { + F=Face[nb-1]; + if (!prolface[nb-1]) faceprol[nb-1]=F; + } + Sfacemoins1=BRep_Tool::Surface(F); + Handle(Geom_Curve) cint; + Handle(Geom2d_Curve) C2dint1, C2dint2,cface,cfacemoins1; + + /////////////////////////////////////////////////////// + // determine intersections of edges and the fillet + // to find limitations of intersections face - fillet + /////////////////////////////////////////////////////// + + if (nb==1) { + Hc1 = BRep_Tool::CurveOnSurface(Edge[0],Face[0],Ubid,Ubid); + if (isOnSame1) { + // update interference param on Fi1 and point of CV1 + if (prolface[0]) Bs.Initialize(faceprol[0], Standard_False); + else Bs.Initialize(Face[0], Standard_False); + const Handle(Geom_Curve)& c3df = DStr.Curve(Fi1.LineIndex()).Curve(); + Standard_Real Ufi= Fi2.Parameter(isfirst); + ChFiDS_FaceInterference& Fi = Fd->ChangeInterferenceOnS1(); + if (!IntersUpdateOnSame (HGs,HBs,c3df,F1,Face[0],Edge[0],Vtx,isfirst,10*tolesp, // in + Fi,CV1,pfac1,Ufi)) // out + Standard_Failure::Raise("IntersectionAtEnd: pb intersection Face - Fi"); + Fi1 = Fi; + if (intersOnSameFailed) { // probable at fillet building + // look for paredge2 + Geom2dAPI_ProjectPointOnCurve proj; + if (C2dint2.IsNull()) proj.Init(pfac1,Hc1); + else proj.Init(pfac1,C2dint2); + paredge2 = proj.LowerDistanceParameter(); + } + // update stripe point + TopOpeBRepDS_Point tpoint (CV1.Point(),tolesp); + indpoint1=DStr.AddPoint(tpoint); + stripe->SetIndexPoint(indpoint1,isfirst,1); + // reset arc of CV1 + TopoDS_Vertex vert1,vert2; + TopExp::Vertices(Edge[0],vert1,vert2); + TopAbs_Orientation arcOri = Vtx.IsSame(vert1) ? TopAbs_FORWARD : TopAbs_REVERSED; + CV1.SetArc(tolesp,Edge[0],paredge2,arcOri); + } + else { + if (Hc1.IsNull()) { + // curve 2d not found. Sfacemoins1 is extended and projection is done there + // CV1.Point () + ChFi3d_ExtendSurface(Sfacemoins1,prolface[0]); + if (prolface[0]) { + extend=Standard_True; + BRep_Builder BRE; + Standard_Real tol=BRep_Tool::Tolerance(F); + BRE.MakeFace(faceprol[0],Sfacemoins1,F.Location(),tol); + if (!isOnSame1) { + GeomAdaptor_Surface Asurf; + Asurf.Load(Sfacemoins1); + Extrema_ExtPS ext (CV1.Point(),Asurf, tol,tol); + Standard_Real uc1,vc1; + if (ext.IsDone()) { + ext.Point(1).Parameter(uc1,vc1); + pfac1.SetX(uc1); + pfac1.SetY(vc1); + } + } + } + } + else + pfac1 = Hc1->Value(CV1.ParameterOnArc()); + } + paredge1=CV1.ParameterOnArc(); + if (Fi1.LineIndex() != 0) { + pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(isfirst));} + else { + pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(!isfirst));} + pfildeb=pfil1; + } + else { + pfil1=pfil2; + paredge1=paredge2; + pfac1=pint; + } + + if (nb!=nbface || isOnSame2) { + Standard_Integer nbp; + + Handle(Geom_Curve) C; + C=BRep_Tool::Curve(E2,Ubid,Vbid); + Handle(Geom_TrimmedCurve) Ctrim = new Geom_TrimmedCurve(C,Ubid,Vbid); + Standard_Real Utrim,Vtrim; + Utrim=Ctrim->BasisCurve()->FirstParameter(); + Vtrim=Ctrim->BasisCurve()->LastParameter(); + if (Ctrim->IsPeriodic()) { + if (Ubid>Ctrim->Period()) { + Ubid=(Utrim+Vtrim)/2; + Vbid= Vtrim; + } + else { + Ubid=Utrim; + Vbid=(Utrim+Vtrim)/2; + } + } + else { + Ubid=Utrim; + Vbid=Vtrim; + } + Handle(GeomAdaptor_HCurve) HC = + new GeomAdaptor_HCurve(C,Ubid,Vbid); + GeomAdaptor_Curve & Cad =HC->ChangeCurve(); + inters.Perform(HC, HGs); + if ( !prolface[nn] && ( !inters.IsDone() || (inters.NbPoints()==0) )) { + // extend surface of conge + Handle(Geom_BSplineSurface) S1= + Handle(Geom_BSplineSurface)::DownCast(DStr.Surface(Fd->Surf()).Surface()); + if (!S1.IsNull()) { + Standard_Real length = 0.5 * Max(Fi1Length,Fi2Length); + GeomLib::ExtendSurfByLength(S1,length,1,Standard_False,!isfirst); + prolface[nn] = 1; + if (!stripe->IsInDS(!isfirst)) { + Gs.Load(S1); + inters.Perform(HC, HGs); + if (inters.IsDone()&& inters.NbPoints()!=0) { + Fd->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(S1, DStr.ChangeSurface(Isurf).Tolerance()))); + Isurf=Fd->Surf(); + } + } + } + } + if (!inters.IsDone() || (inters.NbPoints()==0)) { + Handle(Geom_BSplineCurve) cd=Handle(Geom_BSplineCurve)::DownCast(C); + Handle(Geom_BezierCurve) cd1=Handle(Geom_BezierCurve)::DownCast(C); + if (!cd.IsNull() || !cd1.IsNull() ) { + BRep_Builder BRE; + Sface=BRep_Tool::Surface(Face[nb]); + ChFi3d_ExtendSurface(Sface,prolface[nb]); + Standard_Real tol=BRep_Tool::Tolerance(F); + BRE.MakeFace(faceprol[nb],Sface,Face[nb].Location(),tol); + if (nb && !prolface[nb-1]) { + ChFi3d_ExtendSurface(Sfacemoins1,prolface[nb-1]); + if (prolface[nb-1]) { + tol=BRep_Tool::Tolerance(F); + BRE.MakeFace(faceprol[nb-1],Sfacemoins1,F.Location(),tol); + } + } + else { + Standard_Integer prol = 0; + ChFi3d_ExtendSurface(Sfacemoins1,prol); + } + GeomInt_IntSS InterSS(Sfacemoins1,Sface,1.e-7,1,1,1); + if (InterSS.IsDone()) { + trouve=Standard_False; + for (Standard_Integer i=1; i<=InterSS.NbLines() && !trouve; i++) { + extend=Standard_True; + cint= InterSS.Line(i); + C2dint1= InterSS.LineOnS1(i); + C2dint2= InterSS.LineOnS2(i); + Cad.Load(cint); + inters.Perform(HC, HGs); + trouve=inters.IsDone()&&inters.NbPoints()!=0; + // eap occ293, eval tolex on finally trimmed curves +// Handle(GeomAdaptor_HSurface) H1=new GeomAdaptor_HSurface(Sfacemoins1); +// Handle(GeomAdaptor_HSurface) H2=new GeomAdaptor_HSurface(Sface); +// tolex=ChFi3d_EvalTolReached(H1,C2dint1,H2,C2dint2,cint); + tolex = InterSS.TolReached3d(); + } + } + } + } + if (inters.IsDone()) { + nbp = inters.NbPoints(); + if (nbp==0) { + if (nb==0 || nb==nbface) + intersOnSameFailed = Standard_True; + else { + PerformMoreThreeCorner (Index,1); + return; + } + } + else { + gp_Pnt P=BRep_Tool::Pnt(Vtx); + Standard_Real distmin=P.Distance(inters.Point(1).Pnt()); + nbp=1; + for (Standard_Integer i=2;i<=inters.NbPoints();i++) { + dist=P.Distance(inters.Point(i).Pnt()); + if (dist<distmin) { + distmin=dist; + nbp=i; + } + } + gp_Pnt2d pt2d (inters.Point(nbp).U(),inters.Point(nbp).V()); + pfil2=pt2d; + paredge2=inters.Point(nbp).W(); + if (!extend) { + cfacemoins1=BRep_Tool::CurveOnSurface(E2,F,u2,v2); + cface=BRep_Tool::CurveOnSurface(E2,Face[nb],u2,v2); + cfacemoins1->D0(paredge2,pfac2); + cface->D0(paredge2,pint); + } + else { + C2dint1->D0(paredge2,pfac2); + C2dint2->D0(paredge2,pint); + } + } + } + else Standard_Failure::Raise("IntersectionAtEnd: pb intersection Face cb"); + } + else { + Hc2 = BRep_Tool::CurveOnSurface(E2,Face[nbface-1],Ubid,Ubid); + if (Hc2.IsNull()) { + // curve 2d is not found, Sfacemoins1 is extended CV2.Point() is projected there + + ChFi3d_ExtendSurface(Sfacemoins1,prolface[0]); + if (prolface[0]) { + BRep_Builder BRE; + extend=Standard_True; + Standard_Real tol=BRep_Tool::Tolerance(F); + BRE.MakeFace(faceprol[nb-1],Sfacemoins1,F.Location(),tol); + GeomAdaptor_Surface Asurf; + Asurf.Load(Sfacemoins1); + Extrema_ExtPS ext (CV2.Point(),Asurf,tol,tol); + Standard_Real uc2,vc2; + if (ext.IsDone()) { + ext.Point(1).Parameter(uc2,vc2); + pfac2.SetX(uc2); + pfac2.SetY(vc2); + } + } + } + else pfac2 = Hc2->Value(CV2.ParameterOnArc()); + paredge2=CV2.ParameterOnArc(); + if (Fi2.LineIndex() != 0) { + pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(isfirst)); + } + else { + pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(!isfirst)); + } + } + if (!nb) continue; // found paredge1 on Edge[0] in OnSame situation on F1 + + if (nb==nbface && isOnSame2) { + // update interference param on Fi2 and point of CV2 + if (prolface[nb-1]) Bs.Initialize(faceprol[nb-1]); + else Bs.Initialize(Face[nb-1]); + const Handle(Geom_Curve)& c3df = DStr.Curve(Fi2.LineIndex()).Curve(); + Standard_Real Ufi= Fi1.Parameter(isfirst); + ChFiDS_FaceInterference& Fi = Fd->ChangeInterferenceOnS2(); + if (!IntersUpdateOnSame (HGs,HBs,c3df,F2,F,Edge[nb],Vtx,isfirst,10*tolesp, // in + Fi,CV2,pfac2,Ufi)) // out + Standard_Failure::Raise("IntersectionAtEnd: pb intersection Face - Fi"); + Fi2 = Fi; + if (intersOnSameFailed) { // probable at fillet building + // look for paredge2 + Geom2dAPI_ProjectPointOnCurve proj; + if (extend) + proj.Init(pfac2, C2dint2); + else + proj.Init(pfac2, BRep_Tool::CurveOnSurface (E2,Face[nbface-1],Ubid,Ubid)); + paredge2 = proj.LowerDistanceParameter(); + } + // update stripe point + TopOpeBRepDS_Point tpoint (CV2.Point(),tolesp); + indpoint2=DStr.AddPoint(tpoint); + stripe->SetIndexPoint(indpoint2,isfirst,2); + // reset arc of CV2 + TopoDS_Vertex vert1,vert2; + TopExp::Vertices(Edge[nbface],vert1,vert2); + TopAbs_Orientation arcOri = Vtx.IsSame(vert1) ? TopAbs_FORWARD : TopAbs_REVERSED; + CV2.SetArc(tolesp,Edge[nbface],paredge2,arcOri); + } + + + if (prolface[nb-1]) Bs.Initialize(faceprol[nb-1]); + else Bs.Initialize(Face[nb-1]); + + // offset of parameters if they are not in the same period + + // commented by eap 30 May 2002 occ354 + // the following code may cause trimming a wrong part of periodic surface + +// Standard_Real deb,xx1,xx2; +// Standard_Boolean moins2pi,moins2pi1,moins2pi2; +// if (DStr.Surface(Fd->Surf()).Surface()->IsUPeriodic()) { +// deb=pfildeb.X(); +// xx1=pfil1.X(); +// xx2=pfil2.X(); +// moins2pi=Abs(deb)< Abs(Abs(deb)-2*PI); +// moins2pi1=Abs(xx1)< Abs(Abs(xx1)-2*PI); +// moins2pi2=Abs(xx2)< Abs(Abs(xx2)-2*PI); +// if (moins2pi1!=moins2pi2) { +// if (moins2pi) { +// if (!moins2pi1) xx1=xx1-2*PI; +// if (!moins2pi2) xx2=xx2-2*PI; +// } +// else { +// if (moins2pi1) xx1=xx1+2*PI; +// if (moins2pi2) xx2=xx2+2*PI; +// } +// } +// pfil1.SetX(xx1); +// pfil2.SetX(xx2); +// } +// if (couture || Sfacemoins1->IsUPeriodic()) { + +// Standard_Real ufmin,ufmax,vfmin,vfmax; +// BRepTools::UVBounds(Face[nb-1],ufmin,ufmax,vfmin,vfmax); +// deb=ufmin; +// xx1=pfac1.X(); +// xx2=pfac2.X(); +// moins2pi=Abs(deb)< Abs(Abs(deb)-2*PI); +// moins2pi1=Abs(xx1)< Abs(Abs(xx1)-2*PI); +// moins2pi2=Abs(xx2)< Abs(Abs(xx2)-2*PI); +// if (moins2pi1!=moins2pi2) { +// if (moins2pi) { +// if (!moins2pi1) xx1=xx1-2*PI; +// if (!moins2pi2) xx2=xx2-2*PI; +// } +// else { +// if (moins2pi1) xx1=xx1+2*PI; +// if (moins2pi2) xx2=xx2+2*PI; +// } +// } +// pfac1.SetX(xx1); +// pfac2.SetX(xx2); +// } + + Pardeb(1)= pfil1.X();Pardeb(2) = pfil1.Y(); + Pardeb(3)= pfac1.X();Pardeb(4) = pfac1.Y(); + Parfin(1)= pfil2.X();Parfin(2) = pfil2.Y(); + Parfin(3)= pfac2.X();Parfin(4) = pfac2.Y(); + + Standard_Real uu1,uu2,vv1,vv2; + ChFi3d_Boite(pfac1,pfac2,uu1,uu2,vv1,vv2); + ChFi3d_BoundFac(Bs,uu1,uu2,vv1,vv2); + + + ////////////////////////////////////////////////////////////////////// + // calculate intersections face - fillet + ////////////////////////////////////////////////////////////////////// + + if (!ChFi3d_ComputeCurves(HGs,HBs,Pardeb,Parfin,Cc, + Ps,Pc,tolesp,tol2d,tolreached,nbface==1)) { + PerformMoreThreeCorner (Index,1); + return; + } + // storage of information in the data structure + + // evaluate tolerances + p1=Cc->FirstParameter(); + p2=Cc->LastParameter(); + Standard_Real to1,to2; + gp_Pnt2d p2d1,p2d2; + gp_Pnt P1,P2,P3,P4,P5,P6,P7,P8; + HGs->D0(Pardeb(1),Pardeb(2),P1); + HGs->D0(Parfin(1),Parfin(2),P2); + HBs->D0(Pardeb(3),Pardeb(4),P3); + HBs->D0(Parfin(3),Parfin(4),P4); + Pc->D0(p1,p2d1); + Pc->D0(p2,p2d2); + HBs->D0(p2d1.X(),p2d1.Y(),P7); + HBs->D0(p2d2.X(),p2d2.Y(),P8); + Ps->D0(p1,p2d1); + Ps->D0(p2,p2d2); + HGs->D0(p2d1.X(),p2d1.Y(),P5); + HGs->D0(p2d2.X(),p2d2.Y(),P6); + to1 = Max (P1.Distance(P5)+P3.Distance(P7), tolreached); + to2 = Max (P2.Distance(P6)+P4.Distance(P8), tolreached); + + + ////////////////////////////////////////////////////////////////////// + // storage in the DS of the intersection curve + ////////////////////////////////////////////////////////////////////// + + Standard_Boolean Isvtx1=0; + Standard_Boolean Isvtx2=0; + Standard_Integer indice; + + if (nb==1) + { + indpoint1 = stripe->IndexPoint(isfirst,1); + if (!CV1.IsVertex()) { + TopOpeBRepDS_Point& tpt= DStr.ChangePoint(indpoint1); + tpt.Tolerance ( Max (tpt.Tolerance(), to1)); + } + else Isvtx1=1; + } + if (nb==nbface) + { + indpoint2 = stripe->IndexPoint(isfirst,2); + if (!CV2.IsVertex()) { + TopOpeBRepDS_Point& tpt= DStr.ChangePoint(indpoint2); + tpt.Tolerance ( Max (tpt.Tolerance(), to2)); + } + else Isvtx2=1; + } + else + { + gp_Pnt point =Cc->Value(Cc->LastParameter()); + TopOpeBRepDS_Point tpoint (point,to2); + indpoint2=DStr.AddPoint(tpoint); + } + + if (nb!=1) + { + TopOpeBRepDS_Point& tpt= DStr.ChangePoint(indpoint1); + tpt.Tolerance ( Max (tpt.Tolerance(), to1)); + } + TopOpeBRepDS_Curve tcurv3d( Cc,tolreached); + indcurve[nb-1]= DStr.AddCurve(tcurv3d); + Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurve[nb-1], + indpoint1,Cc->FirstParameter(),Isvtx1); + Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurve[nb-1], + indpoint2,Cc->LastParameter(),Isvtx2); + + DStr.ChangeCurveInterferences(indcurve[nb-1]).Append(Interfp1); + DStr.ChangeCurveInterferences(indcurve[nb-1]).Append(Interfp2); + + ////////////////////////////////////////////////////////////////////// + // storage for the face + ////////////////////////////////////////////////////////////////////// + +#ifndef DEB + TopAbs_Orientation ori = TopAbs_FORWARD; +#else + TopAbs_Orientation ori; +#endif + orface=Face[nb-1].Orientation(); + if (orface==orsurfdata ) orien = TopAbs::Reverse(orcourbe); + else orien = orcourbe ; + // limitation of edges of faces + if (nb==1) { + Standard_Integer Iarc1= DStr.AddShape(Edge[0]); + Interfedge[0]= ChFi3d_FilPointInDS(CV1.TransitionOnArc(),Iarc1, + indpoint1,paredge1,Isvtx1); + //DStr.ChangeShapeInterferences(Edge[0]).Append(Interfp1); + } + if (nb==nbface) { + Standard_Integer Iarc2= DStr.AddShape(Edge[nb]); + Interfedge[nb]= ChFi3d_FilPointInDS(CV2.TransitionOnArc() ,Iarc2, + indpoint2,paredge2,Isvtx2); + //DStr.ChangeShapeInterferences(Edge[nb]).Append(Interfp2); + } + + if (nb!=nbface || oneintersection1 || oneintersection2) { + if (nface==3) { + V1= TopExp::FirstVertex(Edge[nb]); + V2= TopExp::LastVertex(Edge[nb]); + if (containV(F1,V1) || containV(F2,V1)) + ori=TopAbs_FORWARD; + else if (containV(F1,V2) || containV(F2,V2)) + ori=TopAbs_REVERSED; + else + Standard_Failure::Raise("IntersectionAtEnd : pb orientation"); + + if (containV(F1,V1) && containV(F1,V2)) { + dist1=(BRep_Tool::Pnt(V1)).Distance(BRep_Tool::Pnt(Vtx)); + dist2=(BRep_Tool::Pnt(V2)).Distance(BRep_Tool::Pnt(Vtx)); + if (dist1<dist2) ori=TopAbs_FORWARD; + else ori=TopAbs_REVERSED; + } + if (containV(F2,V1) && containV(F2,V2)) { + dist1=(BRep_Tool::Pnt(V1)).Distance(BRep_Tool::Pnt(Vtx)); + dist2=(BRep_Tool::Pnt(V2)).Distance(BRep_Tool::Pnt(Vtx)); + if (dist1<dist2) ori=TopAbs_FORWARD; + else ori=TopAbs_REVERSED; + } + } + else { + if (TopExp::FirstVertex(Edge[nb]).IsSame(Vtx)) + ori= TopAbs_FORWARD; + else ori=TopAbs_REVERSED; + } + if (!extend && !(oneintersection1 || oneintersection2)) { + Standard_Integer Iarc2= DStr.AddShape(Edge[nb]); + Interfedge[nb]= ChFi3d_FilPointInDS(ori,Iarc2, + indpoint2,paredge2); + // DStr.ChangeShapeInterferences(Edge[nb]).Append(Interfp2); + } + else { + if (!(oneintersection1 || oneintersection2) ) proledge[nb]=Standard_True; + Standard_Integer indp1,indp2,ind; + gp_Pnt pext; + Standard_Real ubid,vbid; + pext=BRep_Tool::Pnt(Vtx); + GeomAdaptor_Curve cad; + Handle(Geom_Curve) csau; + if ( ! (oneintersection1 || oneintersection2)) { + cad.Load(cint); + csau=cint; + } + else { + csau=BRep_Tool::Curve(edgesau,ubid,vbid ); + Handle(Geom_BoundedCurve) C1= + Handle(Geom_BoundedCurve)::DownCast(csau); + if (oneintersection1&&extend) { + if (!C1.IsNull()) { + gp_Pnt Pl; + Pl=C1->Value(C1->LastParameter()); + //Standard_Boolean sens; + sens=Pl.Distance(pext)<tolpt; + GeomLib::ExtendCurveToPoint(C1,CV1.Point(),1,sens); + csau=C1; + } + } + else if (oneintersection2&&extend) { + if (!C1.IsNull()) { + gp_Pnt Pl; + Pl=C1->Value(C1->LastParameter()); + //Standard_Boolean sens; + sens=Pl.Distance(pext)<tolpt; + GeomLib::ExtendCurveToPoint(C1,CV2.Point(),1,sens); + csau=C1; + } + } + cad.Load(csau); + } + Extrema_ExtPC ext(pext,cad,tolpt); + Standard_Real par1, par2, par, ParVtx; + Standard_Boolean vtx1=Standard_False; + Standard_Boolean vtx2=Standard_False; + par1=ext.Point(1).Parameter(); + ParVtx = par1; + if (oneintersection1 || oneintersection2 ) { + if (oneintersection2) { + pext=CV2.Point(); + ind=indpoint2; + } + else { + pext=CV1.Point(); + ind=indpoint1; + } + Extrema_ExtPC ext2(pext,cad,tolpt); + par2=ext2.Point(1).Parameter(); + } + else { + par2=paredge2; + ind=indpoint2; + } + if (par1>par2) { + indp1=ind; + indp2=DStr.AddShape(Vtx); + vtx2=Standard_True; + par=par1; + par1=par2; + par2=par; + } + else { + indp1=DStr.AddShape(Vtx); + indp2=ind; + vtx1=Standard_True; + } + Handle(Geom_Curve) Ct=new Geom_TrimmedCurve (csau,par1,par2); + TopAbs_Orientation orient; + Cc->D0(Cc->FirstParameter(),P1); + Cc->D0(Cc->LastParameter(),P2); + Ct->D0(Ct->FirstParameter(),P3); + Ct->D0(Ct->LastParameter(),P4); + if (P2.Distance(P3)<tolpt || P1.Distance(P4)<tolpt) orient=orien; + else orient=TopAbs::Reverse(orien); + if (oneintersection1||oneintersection2) { + indice=DStr.AddShape(Face[0]); + if (extend) { + DStr.SetNewSurface(Face[0],Sfacemoins1); + ComputeCurve2d(Ct,faceprol[0],C2dint1); + } + else + { + TopoDS_Edge aLocalEdge = edgesau; + if (edgesau.Orientation() != orient) + aLocalEdge.Reverse(); + C2dint1 = BRep_Tool::CurveOnSurface(aLocalEdge,Face[0],ubid,vbid); + } + } + else { + indice=DStr.AddShape(Face[nb-1]); + DStr.SetNewSurface(Face[nb-1],Sfacemoins1); + } + //// for periodic 3d curves //// + if (cad.IsPeriodic()) + { + gp_Pnt2d P2d = BRep_Tool::Parameters( Vtx, Face[0] ); + Geom2dAPI_ProjectPointOnCurve Projector( P2d, C2dint1 ); + par = Projector.LowerDistanceParameter(); + Standard_Real shift = par-ParVtx; + if (Abs(shift) > Precision::Confusion()) + { + par1 += shift; + par2 += shift; + } + } + //////////////////////////////// + + Ct=new Geom_TrimmedCurve (csau,par1,par2); + if (oneintersection1||oneintersection2) tolex=10*BRep_Tool::Tolerance(edgesau); + if (extend) { + Handle(GeomAdaptor_HSurface) H1, H2; + H1=new GeomAdaptor_HSurface(Sfacemoins1); + if (Sface.IsNull()) + tolex = Max (tolex, ChFi3d_EvalTolReached(H1,C2dint1,H1,C2dint1,Ct)); + else { + H2=new GeomAdaptor_HSurface(Sface); + tolex = Max (tolex, ChFi3d_EvalTolReached(H1,C2dint1,H2,C2dint2,Ct)); + } + } + TopOpeBRepDS_Curve tcurv( Ct,tolex); + Standard_Integer indcurv; + indcurv=DStr.AddCurve(tcurv); + Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurv,indp1,par1,vtx1); + Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurv,indp2,par2,vtx2); + DStr.ChangeCurveInterferences(indcurv).Append(Interfp1); + DStr.ChangeCurveInterferences(indcurv).Append(Interfp2); + + Interfc=ChFi3d_FilCurveInDS(indcurv,indice ,C2dint1,orient); + DStr.ChangeShapeInterferences(indice).Append(Interfc); + if (oneintersection1||oneintersection2) { + indice=DStr.AddShape(facesau); + if (facesau.Orientation()==Face[0].Orientation()) + orient=TopAbs::Reverse(orient); + if (extend) { + ComputeCurve2d(Ct,faceprol[1],C2dint2); + + } + else + { + TopoDS_Edge aLocalEdge = edgesau; + if (edgesau.Orientation() != orient) + aLocalEdge.Reverse(); + C2dint2 = BRep_Tool::CurveOnSurface(aLocalEdge,facesau,ubid,vbid); + //Reverse for case of edgesau on closed surface (Face[0] is equal to facesau) + } + } + else { + indice=DStr.AddShape(Face[nb]); + DStr.SetNewSurface(Face[nb],Sface); + if (Face[nb].Orientation()==Face[nb-1].Orientation()) + orient= TopAbs::Reverse(orient); + } + if (!bordlibre) { + Interfc=ChFi3d_FilCurveInDS(indcurv,indice,C2dint2,orient); + DStr.ChangeShapeInterferences(indice).Append(Interfc); + } + } + } + + if (checkShrink && + IsShrink(Ps,p1,p2,checkShrParam,isUShrink,Precision::Parametric(tolreached))) + { + shrink [nb-1] = 1; + // store section face-chamf curve for previous SurfData + // Suppose Fd and SDprev are parametrized similarly + if (!isShrink) { // first time + const ChFiDS_FaceInterference& Fi = SDprev->InterferenceOnS1(); + gp_Pnt2d UV = Fi.PCurveOnSurf()->Value(Fi.Parameter(isfirst)); + prevSDParam = isUShrink ? UV.X() : UV.Y(); + } + gp_Pnt2d UV1=p2d1,UV2=p2d2; + UV1.SetCoord(isUShrink ? 1 : 2, prevSDParam); + UV2.SetCoord(isUShrink ? 1 : 2, prevSDParam); + Standard_Real aTolreached; + ChFi3d_ComputePCurv(Cc,UV1,UV2,Ps, + DStr.Surface(SDprev->Surf()).Surface(), + p1,p2,tolesp,aTolreached); + TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(indcurve[nb-1]); + TCurv.Tolerance(Max(TCurv.Tolerance(),aTolreached)); + + InterfPS[nb-1]=ChFi3d_FilCurveInDS(indcurve[nb-1],IsurfPrev,Ps,orcourbe); + DStr.ChangeSurfaceInterferences(IsurfPrev).Append(InterfPS[nb-1]); + + if (isOnSame2) { + midP2d = p2d2; + midIpoint = indpoint2; + } + else if (!isShrink) { + midP2d = p2d1; + midIpoint = indpoint1; + } + isShrink = Standard_True; + } // end if shrink + + + indice=DStr.AddShape(Face[nb-1]); + InterfPC[nb-1]=ChFi3d_FilCurveInDS(indcurve[nb-1],indice ,Pc,orien); + if (!shrink [nb-1]) + InterfPS[nb-1]=ChFi3d_FilCurveInDS(indcurve[nb-1],Isurf,Ps,orcourbe); + indpoint1=indpoint2; + + } // end loop on faces being intersected with ChFi + + + if (isOnSame1) CV1.Reset(); + if (isOnSame2) CV2.Reset(); + + for(nb=1;nb<=nbface;nb++) { + Standard_Integer indice=DStr.AddShape(Face[nb-1]); + DStr.ChangeShapeInterferences(indice).Append(InterfPC[nb-1]); + if (!shrink [nb-1]) + DStr.ChangeSurfaceInterferences(Isurf).Append(InterfPS[nb-1]); + if (!proledge[nb-1]) + DStr.ChangeShapeInterferences(Edge[nb-1]).Append(Interfedge[nb-1]); + } + DStr.ChangeShapeInterferences(Edge[nbface]).Append(Interfedge[nbface]); + + if (!isShrink) + stripe->InDS(isfirst); + else { + // compute curves for !<isfirst> end of <Fd> and <isfirst> end of previous <SurfData> + + // for Fd + //Bnd_Box box; + gp_Pnt2d UV, UV1 = midP2d, UV2 = midP2d; + if (isOnSame1) + UV = UV2 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(!isfirst)); + else + UV = UV1 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(!isfirst)); + Standard_Real aTolreached; + Handle(Geom_Curve) C3d; + Handle(Geom_Surface) aSurf = DStr.Surface(Fd->Surf()).Surface(); + //box.Add(aSurf->Value(UV.X(), UV.Y())); + + ChFi3d_ComputeArete(CV1,UV1,CV2,UV2,aSurf, // in + C3d,Ps,p1,p2,tolesp,tol2d,aTolreached,0); // out except tolers + + indpoint1 = indpoint2 = midIpoint; + gp_Pnt point; + if (isOnSame1) { + point = C3d->Value(p2); + TopOpeBRepDS_Point tpoint (point,aTolreached); + indpoint2=DStr.AddPoint(tpoint); + UV = Ps->Value(p2); + } else { + point = C3d->Value(p1); + TopOpeBRepDS_Point tpoint (point,aTolreached); + indpoint1=DStr.AddPoint(tpoint); + UV = Ps->Value(p1); + } + //box.Add(point); + //box.Add(aSurf->Value(UV.X(), UV.Y())); + + TopOpeBRepDS_Curve Crv = TopOpeBRepDS_Curve(C3d,aTolreached); + Standard_Integer Icurv = DStr.AddCurve(Crv); + Interfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv,indpoint1,p1, Standard_False); + Interfp2 = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv,indpoint2,p2, Standard_False); + Interfc = ChFi3d_FilCurveInDS(Icurv,Isurf,Ps,orcourbe); + DStr.ChangeCurveInterferences(Icurv).Append(Interfp1); + DStr.ChangeCurveInterferences(Icurv).Append(Interfp2); + DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc); + + // for SDprev + aSurf = DStr.Surface(SDprev->Surf()).Surface(); + UV1.SetCoord(isUShrink ? 1 : 2, prevSDParam); + UV2.SetCoord(isUShrink ? 1 : 2, prevSDParam); + + ChFi3d_ComputePCurv(C3d,UV1,UV2,Pc,aSurf,p1,p2,tolesp,aTolreached); + + Crv.Tolerance(Max(Crv.Tolerance(),aTolreached)); + Interfc= ChFi3d_FilCurveInDS (Icurv,IsurfPrev,Pc,TopAbs::Reverse(orcourbe)); + DStr.ChangeSurfaceInterferences(IsurfPrev).Append(Interfc); + + //UV = isOnSame1 ? UV2 : UV1; + //box.Add(aSurf->Value(UV.X(), UV.Y())); + //UV = Ps->Value(isOnSame1 ? p2 : p1); + //box.Add(aSurf->Value(UV.X(), UV.Y())); + //ChFi3d_SetPointTolerance(DStr,box, isOnSame1 ? indpoint2 : indpoint1); + + // to process properly this case in ChFi3d_FilDS() + stripe->InDS(isfirst, 2); + Fd->ChangeInterference(isOnSame1 ? 2 : 1).SetLineIndex(0); + ChFiDS_CommonPoint& CPprev1 = SDprev->ChangeVertex( isfirst,isOnSame1 ? 2 : 1); + ChFiDS_CommonPoint& CPlast1 = Fd-> ChangeVertex( isfirst,isOnSame1 ? 2 : 1); + ChFiDS_CommonPoint& CPlast2 = Fd-> ChangeVertex(!isfirst,isOnSame1 ? 2 : 1); + if (CPprev1.IsOnArc()) { + CPlast1 = CPprev1; + CPprev1.Reset(); + CPprev1.SetPoint(CPlast1.Point()); + CPlast2.Reset(); + CPlast2.SetPoint(CPlast1.Point()); + } + + // in shrink case, self intersection is possible at <midIpoint>, + // eval its tolerance intersecting Ps and Pcurve at end. + // Find end curves closest to shrinked part + for (nb=0; nb < nbface; nb++) + if (isOnSame1 ? shrink [nb+1] : !shrink [nb]) break; + Handle(Geom_Curve) Cend = DStr.Curve(indcurve[nb]).Curve(); + Handle(Geom2d_Curve) PCend = InterfPS[nb]->PCurve(); + // point near which self intersection may occure + TopOpeBRepDS_Point& Pds = DStr.ChangePoint(midIpoint); + const gp_Pnt& Pvert = Pds.Point(); + Standard_Real tol = Pds.Tolerance(); + + Geom2dAdaptor_Curve PC1(Ps), PC2(PCend); + Geom2dInt_GInter Intersector(PC1,PC2,Precision::PConfusion(),Precision::PConfusion()); + if (!Intersector.IsDone()) return; + for (nb=1; nb <= Intersector.NbPoints(); nb++) { + const IntRes2d_IntersectionPoint& ip = Intersector.Point(nb); + gp_Pnt Pint = C3d->Value(ip.ParamOnFirst()); + tol = Max(tol, Pvert.Distance(Pint)); + Pint = Cend->Value(ip.ParamOnSecond()); + tol = Max(tol, Pvert.Distance(Pint)); + } + for (nb=1; nb <= Intersector.NbSegments(); nb++) { + const IntRes2d_IntersectionSegment& is = Intersector.Segment(nb); + if (is.HasFirstPoint()) { + const IntRes2d_IntersectionPoint& ip = is.FirstPoint(); + gp_Pnt Pint = C3d->Value(ip.ParamOnFirst()); + tol = Max(tol, Pvert.Distance(Pint)); + Pint = Cend->Value(ip.ParamOnSecond()); + tol = Max(tol, Pvert.Distance(Pint)); + } + if (is.HasLastPoint()) { + const IntRes2d_IntersectionPoint& ip = is.LastPoint(); + gp_Pnt Pint = C3d->Value(ip.ParamOnFirst()); + tol = Max(tol, Pvert.Distance(Pint)); + Pint = Cend->Value(ip.ParamOnSecond()); + tol = Max(tol, Pvert.Distance(Pint)); + } + } + Pds.Tolerance(tol); + } +} + +// Modified by Sergey KHROMOV - Thu Apr 11 12:23:40 2002 Begin + +//======================================================================= +//function : PerformMoreSurfdata +//purpose : determine intersections at end on several surfdata +//======================================================================= +void ChFi3d_Builder::PerformMoreSurfdata(const Standard_Integer Index) +{ + TopOpeBRepDS_DataStructure &DStr = myDS->ChangeDS(); + const ChFiDS_ListOfStripe &aLOfStripe = myVDataMap(Index); + Handle(ChFiDS_Stripe) aStripe; + Handle(ChFiDS_Spine) aSpine; + Standard_Real aTol3d = 1.e-4; + + + if (aLOfStripe.IsEmpty()) + return; + + aStripe = aLOfStripe.First(); + aSpine = aStripe->Spine(); + + ChFiDS_SequenceOfSurfData &aSeqSurfData = + aStripe->ChangeSetOfSurfData()->ChangeSequence(); + const TopoDS_Vertex &aVtx = myVDataMap.FindKey(Index); + Standard_Integer aSens = 0; + Standard_Integer anInd = + ChFi3d_IndexOfSurfData(aVtx,aStripe,aSens); + Standard_Boolean isFirst = (aSens == 1); + Standard_Integer anIndPrev; + Handle(ChFiDS_SurfData) aSurfData; + ChFiDS_CommonPoint aCP1; + ChFiDS_CommonPoint aCP2; + + aSurfData = aSeqSurfData.Value(anInd); + + aCP1 = aSurfData->Vertex(isFirst,1); + aCP2 = aSurfData->Vertex(isFirst,2); + + Handle(Geom_Surface) aSurfPrev; + Handle(Geom_Surface) aSurf; + TopoDS_Face aFace; + TopoDS_Face aNeighborFace; + + FindFace(aVtx, aCP1, aCP2, aFace); + aSurfPrev = BRep_Tool::Surface(aFace); + + if (aSens==1) anIndPrev=anInd+1; + else anIndPrev=anInd-1; + + TopoDS_Edge anArc1; + TopoDS_Edge anArc2; + TopTools_ListIteratorOfListOfShape anIter(myVEMap(aVtx)); + Standard_Boolean isFound = Standard_False; + + for(; anIter.More() && !isFound; anIter.Next()) { + anArc1 = TopoDS::Edge(anIter.Value()); + + if (containE(aFace, anArc1)) + isFound = Standard_True; + } + + isFound = Standard_False; + anIter.Initialize(myVEMap(aVtx)); + + for(; anIter.More() && !isFound; anIter.Next()) { + anArc2 = TopoDS::Edge(anIter.Value()); + + if (containE(aFace,anArc2) && !anArc2.IsSame(anArc1)) + isFound = Standard_True; + } + + // determination of common points aCP1onArc, aCP2onArc and aCP2NotonArc + // aCP1onArc is the point on arc of index anInd + // aCP2onArc is the point on arc of index anIndPrev + // aCP2NotonArc is the point of index anIndPrev which is not on arc. + + Standard_Boolean is1stCP1OnArc; + Standard_Boolean is2ndCP1OnArc; + ChFiDS_CommonPoint aCP1onArc; + ChFiDS_CommonPoint aCP2onArc; + ChFiDS_CommonPoint aCP2NotonArc; + + aSurfData = aSeqSurfData.Value(anIndPrev); + aCP1 = aSurfData->Vertex(isFirst,1); + aCP2 = aSurfData->Vertex(isFirst,2); + + if (aCP1.IsOnArc() && + (aCP1.Arc().IsSame(anArc1) || aCP1.Arc().IsSame(anArc2))) { + aCP2onArc = aCP1; + aCP2NotonArc = aCP2; + is2ndCP1OnArc = Standard_True; + } else if (aCP2.IsOnArc() && + (aCP2.Arc().IsSame(anArc1) || aCP2.Arc().IsSame(anArc2))) { + aCP2onArc = aCP2; + aCP2NotonArc = aCP1; + is2ndCP1OnArc = Standard_False; + } else + return; + + aSurfData = aSeqSurfData.Value(anInd); + aCP1 = aSurfData->Vertex(isFirst,1); + aCP2 = aSurfData->Vertex(isFirst,2); + + if (aCP1.Point().Distance(aCP2onArc.Point()) <= aTol3d){ + aCP1onArc = aCP2; + is1stCP1OnArc = Standard_False; + } + else { + aCP1onArc = aCP1; + is1stCP1OnArc = Standard_True; + } + + if (!aCP1onArc.IsOnArc()) + return; + +// determination of neighbor surface + Standard_Integer indSurface; + if (is1stCP1OnArc) + indSurface = myListStripe.First()->SetOfSurfData()->Value(anInd)->IndexOfS1(); + else + indSurface = myListStripe.First()->SetOfSurfData()->Value(anInd)->IndexOfS2(); + + aNeighborFace = TopoDS::Face(myDS->Shape(indSurface)); + +// calculation of intersections + Handle(Geom_Curve) aCracc; + Handle(Geom2d_Curve) aPCurv1; + Standard_Real aParf; + Standard_Real aParl; + Standard_Real aTolReached; + + aSurfData = aSeqSurfData.Value(anInd); + + if (isFirst) + ChFi3d_ComputeArete(aSurfData->VertexLastOnS1(), + aSurfData->InterferenceOnS1().PCurveOnSurf()-> + Value(aSurfData->InterferenceOnS1().LastParameter()), + aSurfData->VertexLastOnS2(), + aSurfData->InterferenceOnS2().PCurveOnSurf()-> + Value(aSurfData->InterferenceOnS2().LastParameter()), + DStr.Surface(aSurfData->Surf()).Surface(),aCracc,aPCurv1, + aParf,aParl,aTol3d,tol2d,aTolReached,0); + else + ChFi3d_ComputeArete(aSurfData->VertexFirstOnS1(), + aSurfData->InterferenceOnS1().PCurveOnSurf()-> + Value(aSurfData->InterferenceOnS1().FirstParameter()), + aSurfData->VertexFirstOnS2(), + aSurfData->InterferenceOnS2().PCurveOnSurf()-> + Value(aSurfData->InterferenceOnS2().FirstParameter()), + DStr.Surface(aSurfData->Surf()).Surface(),aCracc,aPCurv1, + aParf,aParl,aTol3d,tol2d,aTolReached,0); + +// calculation of the index of the line on anInd. +// aPClineOnSurf is the pcurve on anInd. +// aPClineOnFace is the pcurve on face. + ChFiDS_FaceInterference aFI; + + if (is1stCP1OnArc) + aFI = aSurfData->InterferenceOnS1(); + else + aFI = aSurfData->InterferenceOnS2(); + + Handle(Geom_Curve) aCline; + Handle(Geom2d_Curve) aPClineOnSurf; + Handle(Geom2d_Curve) aPClineOnFace; + Standard_Integer indLine; + + indLine = aFI.LineIndex(); + aCline = DStr.Curve(aFI.LineIndex()).Curve(); + aPClineOnSurf = aFI.PCurveOnSurf(); + aPClineOnFace = aFI.PCurveOnFace(); + +// intersection between the SurfData number anInd and the Face aFace. +// Obtaining of curves aCint1, aPCint11 and aPCint12. + aSurf = DStr.Surface(aSurfData->Surf()).Surface(); + + GeomInt_IntSS anInterSS(aSurfPrev,aSurf,1.e-7,1,1,1); + Handle(Geom_Curve) aCint1; + Handle(Geom2d_Curve) aPCint11; + Handle(Geom2d_Curve) aPCint12; + Handle(GeomAdaptor_HSurface) H1 = new GeomAdaptor_HSurface(aSurfPrev); + Handle(GeomAdaptor_HSurface) H2 = new GeomAdaptor_HSurface(aSurf); + Standard_Real aTolex1=0.; + Standard_Integer i; + gp_Pnt aPext1; + gp_Pnt aPext2; + gp_Pnt aPext; + Standard_Boolean isPextFound; + + + if (!anInterSS.IsDone()) + return; + + isFound = Standard_False; + + for (i = 1; i <= anInterSS.NbLines() && !isFound; i++) { + aCint1 = anInterSS.Line(i); + aPCint11 = anInterSS.LineOnS1(i); + aPCint12 = anInterSS.LineOnS2(i); + aTolex1 = ChFi3d_EvalTolReached(H1, aPCint11, H2, aPCint12, aCint1); + + aCint1->D0(aCint1->FirstParameter(), aPext1); + aCint1->D0(aCint1->LastParameter(), aPext2); + +// Modified by skv - Mon Jun 7 18:38:57 2004 OCC5898 Begin +// if (aPext1.Distance(aCP1onArc.Point()) <= aTol3d || +// aPext2.Distance(aCP1onArc.Point())) + if (aPext1.Distance(aCP1onArc.Point()) <= aTol3d || + aPext2.Distance(aCP1onArc.Point()) <= aTol3d) +// Modified by skv - Mon Jun 7 18:38:58 2004 OCC5898 End + isFound = Standard_True; + } + + if (!isFound) + return; + + if (aPext1.Distance(aCP2onArc.Point()) > aTol3d && + aPext1.Distance(aCP1onArc.Point()) > aTol3d) { + aPext = aPext1; + isPextFound = Standard_True; + } else if (aPext2.Distance(aCP2onArc.Point()) > aTol3d && + aPext2.Distance(aCP1onArc.Point()) > aTol3d) { + aPext = aPext2; + isPextFound = Standard_True; + } else { + isPextFound = Standard_False; + } + + + Standard_Boolean isDoSecondSection = Standard_False; + Standard_Real aPar=0.; + + if (isPextFound) { + GeomAdaptor_Curve aCad(aCracc); + Extrema_ExtPC anExt(aPext, aCad, aTol3d); + + if (!anExt.IsDone()) + return; + + isFound = Standard_False; + for (i = 1; i <= anExt.NbExt() && !isFound; i++) { + if (anExt.IsMin(i)) { + gp_Pnt aProjPnt = anExt.Point(i).Value(); + + if (aPext.Distance(aProjPnt) <= aTol3d) { + aPar = anExt.Point(i).Parameter(); + isDoSecondSection = Standard_True; + } + } + } + } + + Handle(Geom_Curve) aTrCracc; + TopAbs_Orientation anOrSD1; + TopAbs_Orientation anOrSD2; + Standard_Integer indShape; + + anOrSD1 = aSurfData->Orientation(); + aSurfData = aSeqSurfData.Value(anIndPrev); + anOrSD2 = aSurfData->Orientation(); + aSurf = DStr.Surface(aSurfData->Surf()).Surface(); + +// The following variables will be used if isDoSecondSection is true + Handle(Geom_Curve) aCint2; + Handle(Geom2d_Curve) aPCint21; + Handle(Geom2d_Curve) aPCint22; + Standard_Real aTolex2=0.; + + if (isDoSecondSection) { + Standard_Real aPar1; + + aCracc->D0(aCracc->FirstParameter(), aPext1); + + if (aPext1.Distance(aCP2NotonArc.Point()) <= aTol3d) + aPar1 = aCracc->FirstParameter(); + else + aPar1 = aCracc->LastParameter(); + + if (aPar1 < aPar) + aTrCracc = new Geom_TrimmedCurve (aCracc, aPar1, aPar); + else + aTrCracc = new Geom_TrimmedCurve (aCracc, aPar, aPar1); + +// Second section + GeomInt_IntSS anInterSS2(aSurfPrev,aSurf,1.e-7,1,1,1); + + if (!anInterSS2.IsDone()) + return; + + H1 = new GeomAdaptor_HSurface(aSurfPrev); + H2 = new GeomAdaptor_HSurface(aSurf); + + isFound = Standard_False; + + for (i = 1; i <= anInterSS2.NbLines() && !isFound; i++) { + aCint2 = anInterSS2.Line(i); + aPCint21 = anInterSS2.LineOnS1(i); + aPCint22 = anInterSS2.LineOnS2(i); + aTolex2 = ChFi3d_EvalTolReached(H1, aPCint21, H2, aPCint22, aCint2); + + aCint2->D0(aCint2->FirstParameter(), aPext1); + aCint2->D0(aCint2->LastParameter(), aPext2); + + if (aPext1.Distance(aCP2onArc.Point()) <= aTol3d || + aPext2.Distance(aCP2onArc.Point()) <= aTol3d) + isFound = Standard_True; + } + + if (!isFound) + return; + + } else { + aTrCracc = new Geom_TrimmedCurve(aCracc, + aCracc->FirstParameter(), + aCracc->LastParameter()); + } + +// Storage of the data structure + +// calculation of the orientation of line of surfdata number +// anIndPrev which contains aCP2onArc + + Handle(Geom2d_Curve) aPCraccS = GeomProjLib::Curve2d(aTrCracc,aSurf); + + if (is2ndCP1OnArc) { + aFI = aSurfData->InterferenceOnS1(); + indShape = aSurfData->IndexOfS1(); + } else { + aFI = aSurfData->InterferenceOnS2(); + indShape = aSurfData->IndexOfS2(); + } + + if (indShape <= 0) + return; + + + + TopAbs_Orientation aCurOrient; + + aCurOrient = DStr.Shape(indShape).Orientation(); + aCurOrient = TopAbs::Compose(aCurOrient, aSurfData->Orientation()); + aCurOrient = TopAbs::Compose(TopAbs::Reverse(aFI.Transition()), aCurOrient); + + +// Filling the data structure + aSurfData = aSeqSurfData.Value(anInd); + + TopOpeBRepDS_Point aPtCP1(aCP1onArc.Point(),aCP1onArc.Tolerance()); + Standard_Integer indCP1onArc = DStr.AddPoint(aPtCP1); + Standard_Integer indSurf1 = aSurfData->Surf(); + Standard_Integer indArc1 = DStr.AddShape(aCP1onArc.Arc()); + Standard_Integer indSol = aStripe->SolidIndex(); + + Handle (TopOpeBRepDS_CurvePointInterference) anInterfp1; + Handle (TopOpeBRepDS_CurvePointInterference) anInterfp2; + + anInterfp1= ChFi3d_FilPointInDS(aCP1onArc.TransitionOnArc(), indArc1, + indCP1onArc, aCP1onArc.ParameterOnArc()); + DStr.ChangeShapeInterferences(aCP1onArc.Arc()).Append(anInterfp1); + + TopOpeBRepDS_ListOfInterference &SolidInterfs = + DStr.ChangeShapeInterferences(indSol); + Handle(TopOpeBRepDS_SolidSurfaceInterference) SSI = + new TopOpeBRepDS_SolidSurfaceInterference + (TopOpeBRepDS_Transition(anOrSD1), + TopOpeBRepDS_SOLID, indSol, + TopOpeBRepDS_SURFACE, indSurf1); + SolidInterfs.Append(SSI); + +// deletion of Surface Data. + aSeqSurfData.Remove(anInd); + + if (!isFirst) + anInd--; + + aSurfData = aSeqSurfData.Value(anInd); + +// definition of indices of common points in Data Structure + + Standard_Integer indCP2onArc; + Standard_Integer indCP2NotonArc; + + if (is2ndCP1OnArc) { + aStripe->SetIndexPoint(ChFi3d_IndexPointInDS(aCP2onArc, DStr),isFirst,1); + aStripe->SetIndexPoint(ChFi3d_IndexPointInDS(aCP2NotonArc,DStr),isFirst,2); + + if (isFirst) { + indCP2onArc = aStripe->IndexFirstPointOnS1(); + indCP2NotonArc = aStripe->IndexFirstPointOnS2(); + } else { + indCP2onArc = aStripe->IndexLastPointOnS1(); + indCP2NotonArc = aStripe->IndexLastPointOnS2(); + } + } else { + aStripe->SetIndexPoint(ChFi3d_IndexPointInDS(aCP2onArc, DStr),isFirst,2); + aStripe->SetIndexPoint(ChFi3d_IndexPointInDS(aCP2NotonArc,DStr),isFirst,1); + + if (isFirst) { + indCP2onArc = aStripe->IndexFirstPointOnS2(); + indCP2NotonArc = aStripe->IndexFirstPointOnS1(); + } + else { + indCP2onArc = aStripe->IndexLastPointOnS2(); + indCP2NotonArc = aStripe->IndexLastPointOnS1(); + } + } + + Standard_Integer indPoint1; + Standard_Integer indPoint2; + gp_Pnt aPoint1; + gp_Pnt aPoint2; + + if (is2ndCP1OnArc) { + aFI = aSurfData->InterferenceOnS1(); + indShape = aSurfData->IndexOfS1(); + } else { + aFI = aSurfData->InterferenceOnS2(); + indShape = aSurfData->IndexOfS2(); + } + + gp_Pnt2d aP2d; + Handle (TopOpeBRepDS_SurfaceCurveInterference) anInterfc; + TopAbs_Orientation anOrSurf = aCurOrient; + TopAbs_Orientation anOrFace = aFace.Orientation(); + Standard_Integer indaFace = DStr.AddShape(aFace); + Standard_Integer indPoint = indCP2onArc; + Standard_Integer indCurve; + + aFI.PCurveOnFace()->D0(aFI.LastParameter(), aP2d); + Handle(Geom_Surface) Stemp2 = + BRep_Tool::Surface(TopoDS::Face(DStr.Shape(indShape))); + Stemp2->D0(aP2d.X(), aP2d.Y(), aPoint2); + aFI.PCurveOnFace()->D0(aFI.FirstParameter(), aP2d); + Stemp2->D0(aP2d.X(), aP2d.Y(), aPoint1); + + if (isDoSecondSection) { + TopOpeBRepDS_Point tpoint(aPext, aTolex2); + TopOpeBRepDS_Curve tcint2(aCint2, aTolex2); + + indPoint = DStr.AddPoint(tpoint); + indCurve = DStr.AddCurve(tcint2); + + aCint2->D0(aCint2->FirstParameter(), aPext1); + aCint2->D0(aCint2->LastParameter(), aPext2); + + if (aPext1.Distance(aPext) <= aTol3d){ + indPoint1 = indPoint; + indPoint2 = indCP2onArc; + } else { + indPoint1 = indCP2onArc; + indPoint2 = indPoint; + } + +// define the orientation of aCint2 + if (aPext1.Distance(aPoint2) > aTol3d && aPext2.Distance(aPoint1) > aTol3d) + anOrSurf = TopAbs::Reverse(anOrSurf); + +// --------------------------------------------------------------- +// storage of aCint2 + anInterfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD, indCurve, + indPoint1, aCint2->FirstParameter()); + anInterfp2 = ChFi3d_FilPointInDS(TopAbs_REVERSED, indCurve, + indPoint2, aCint2->LastParameter()); + DStr.ChangeCurveInterferences(indCurve).Append(anInterfp1); + DStr.ChangeCurveInterferences(indCurve).Append(anInterfp2); + + // interference of aCint2 on the SurfData number anIndPrev + anInterfc = ChFi3d_FilCurveInDS(indCurve, aSurfData->Surf(), + aPCint22, anOrSurf); + + DStr.ChangeSurfaceInterferences(aSurfData->Surf()).Append(anInterfc); + // interference of aCint2 on aFace + + if (anOrFace == anOrSD2) + anOrFace = TopAbs::Reverse(anOrSurf); + else + anOrFace = anOrSurf; + + anInterfc = ChFi3d_FilCurveInDS(indCurve, indaFace, aPCint21, anOrFace); + DStr.ChangeShapeInterferences(indaFace).Append(anInterfc); + } + + aTrCracc->D0(aTrCracc->FirstParameter(), aPext1); + aTrCracc->D0(aTrCracc->LastParameter(), aPext2); + if (aPext1.Distance(aCP2NotonArc.Point()) <= aTol3d){ + indPoint1 = indCP2NotonArc; + indPoint2 = indPoint; + } else { + indPoint1 = indPoint; + indPoint2 = indCP2NotonArc; + } + +// Define the orientation of aTrCracc + Standard_Boolean isToReverse; + gp_Pnt aP1; + gp_Pnt aP2; + gp_Pnt aP3; + gp_Pnt aP4; + + + if (isDoSecondSection) { + aTrCracc->D0(aTrCracc->FirstParameter(), aP1); + aTrCracc->D0(aTrCracc->LastParameter(), aP2); + aCint2->D0(aCint2->FirstParameter(), aP3); + aCint2->D0(aCint2->LastParameter(), aP4); + isToReverse = (aP1.Distance(aP4) > aTol3d && aP2.Distance(aP3) > aTol3d); + } else { + isToReverse = (aPext1.Distance(aPoint2) > aTol3d && + aPext2.Distance(aPoint1) > aTol3d); + } + + if (isToReverse) + anOrSurf = TopAbs::Reverse(anOrSurf); + +// --------------------------------------------------------------- +// storage of aTrCracc + TopOpeBRepDS_Curve tct2(aTrCracc, aTolReached); + + indCurve = DStr.AddCurve(tct2); + anInterfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,indCurve, + indPoint1, aTrCracc->FirstParameter()); + anInterfp2 = ChFi3d_FilPointInDS(TopAbs_REVERSED,indCurve, + indPoint2, aTrCracc->LastParameter()); + DStr.ChangeCurveInterferences(indCurve).Append(anInterfp1); + DStr.ChangeCurveInterferences(indCurve).Append(anInterfp2); + + // interference of aTrCracc on the SurfData number anIndPrev + + anInterfc = ChFi3d_FilCurveInDS(indCurve,aSurfData->Surf(),aPCraccS, anOrSurf); + DStr.ChangeSurfaceInterferences(aSurfData->Surf()).Append(anInterfc); + aStripe->InDS(isFirst); + + // interference of aTrCracc on the SurfData number anInd + if (anOrSD1 == anOrSD2) + anOrSurf = TopAbs::Reverse(anOrSurf); + + anInterfc = ChFi3d_FilCurveInDS(indCurve, indSurf1, aPCurv1, anOrSurf); + DStr.ChangeSurfaceInterferences(indSurf1).Append(anInterfc); + +// --------------------------------------------------------------- +// storage of aCint1 + + aCint1->D0(aCint1->FirstParameter(),aPext1); + if (aPext1.Distance(aCP1onArc.Point()) <= aTol3d){ + indPoint1 = indCP1onArc; + indPoint2 = indPoint; + } else { + indPoint1 = indPoint; + indPoint2 = indCP1onArc; + } + + // definition of the orientation of aCint1 + + aCint1->D0(aCint1->FirstParameter(), aP1); + aCint1->D0(aCint1->LastParameter(), aP2); + aTrCracc->D0(aTrCracc->FirstParameter(), aP3); + aTrCracc->D0(aTrCracc->LastParameter(), aP4); + + if (aP1.Distance(aP4) > aTol3d && aP2.Distance(aP3) > aTol3d) + anOrSurf=TopAbs::Reverse(anOrSurf); + + TopOpeBRepDS_Curve aTCint1(aCint1, aTolex1); + indCurve= DStr.AddCurve(aTCint1); + anInterfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD, indCurve, + indPoint1, aCint1->FirstParameter()); + anInterfp2 = ChFi3d_FilPointInDS(TopAbs_REVERSED, indCurve, + indPoint2, aCint1->LastParameter()); + DStr.ChangeCurveInterferences(indCurve).Append(anInterfp1); + DStr.ChangeCurveInterferences(indCurve).Append(anInterfp2); + + // interference of aCint1 on the SurfData number anInd + + anInterfc = ChFi3d_FilCurveInDS(indCurve, indSurf1, aPCint12, anOrSurf); + DStr.ChangeSurfaceInterferences(indSurf1).Append(anInterfc); + + // interference of aCint1 on aFace + + anOrFace = aFace.Orientation(); + + if (anOrFace == anOrSD1) + anOrFace = TopAbs::Reverse(anOrSurf); + else + anOrFace = anOrSurf; + + anInterfc = ChFi3d_FilCurveInDS(indCurve, indaFace, aPCint11, anOrFace); + DStr.ChangeShapeInterferences(indaFace).Append(anInterfc); +// --------------------------------------------------------------- +// storage of aCline passing through aCP1onArc and aCP2NotonArc + + Handle(Geom_Curve) aTrCline = + new Geom_TrimmedCurve(aCline, aCline->FirstParameter(), + aCline->LastParameter()); + Standard_Real aTolerance = DStr.Curve(indLine).Tolerance(); + TopOpeBRepDS_Curve aTct3(aTrCline, aTolerance); + + indCurve = DStr.AddCurve(aTct3); + + aTrCline->D0(aTrCline->FirstParameter(),aPext1); + + if (aPext1.Distance(aCP1onArc.Point()) < aTol3d) { + indPoint1 = indCP1onArc; + indPoint2 = indCP2NotonArc; + } else { + indPoint1 = indCP2NotonArc; + indPoint2 = indCP1onArc; + } + // definition of the orientation of aTrCline + + aTrCline->D0(aTrCline->FirstParameter(), aP1); + aTrCline->D0(aTrCline->LastParameter(), aP2); + aCint1->D0(aCint1->FirstParameter(), aP3); + aCint1->D0(aCint1->LastParameter(), aP4); + + if (aP1.Distance(aP4) > aTol3d && aP2.Distance(aP3) > aTol3d) + anOrSurf = TopAbs::Reverse(anOrSurf); + + anInterfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,indCurve, + indPoint1,aTrCline->FirstParameter()); + anInterfp2 = ChFi3d_FilPointInDS(TopAbs_REVERSED,indCurve, + indPoint2,aTrCline->LastParameter()); + DStr.ChangeCurveInterferences(indCurve).Append(anInterfp1); + DStr.ChangeCurveInterferences(indCurve).Append(anInterfp2); + + // interference of aTrCline on the SurfData number anInd + + anInterfc = ChFi3d_FilCurveInDS(indCurve, indSurf1, aPClineOnSurf, anOrSurf); + DStr.ChangeSurfaceInterferences(indSurf1).Append(anInterfc); + + // interference de ctlin par rapport a Fvoisin + indShape = DStr.AddShape(aNeighborFace); + anOrFace = aNeighborFace.Orientation(); + + if (anOrFace == anOrSD1) + anOrFace = TopAbs::Reverse(anOrSurf); + else + anOrFace = anOrSurf; + + anInterfc = ChFi3d_FilCurveInDS(indCurve, indShape, aPClineOnFace, anOrFace); + DStr.ChangeShapeInterferences(indShape).Append(anInterfc); +} +// Modified by Sergey KHROMOV - Thu Apr 11 12:23:40 2002 End + +//============================================================== +//function : FindFace +//purpose : attention it works only if there is only one common face +// between P1,P2,V +//=========================================================== + + +Standard_Boolean ChFi3d_Builder::FindFace(const TopoDS_Vertex& V, + const ChFiDS_CommonPoint& P1, + const ChFiDS_CommonPoint& P2, + TopoDS_Face& Fv) const +{ + TopoDS_Face Favoid; + return FindFace(V,P1,P2,Fv,Favoid); +} + +Standard_Boolean ChFi3d_Builder::FindFace(const TopoDS_Vertex& V, + const ChFiDS_CommonPoint& P1, + const ChFiDS_CommonPoint& P2, + TopoDS_Face& Fv, + const TopoDS_Face& Favoid) const +{ + if (P1.IsVertex() || P2.IsVertex()) { +#ifdef DEB + cout<<"change of face on vertex"<<endl; +#endif + } + if (!(P1.IsOnArc() && P2.IsOnArc())) { + return Standard_False; + } + TopTools_ListIteratorOfListOfShape It,Jt; + Standard_Boolean Found = Standard_False, ContainsV = Standard_False; + for(It.Initialize(myEFMap(P1.Arc()));It.More() && !Found;It.Next()) { + Fv = TopoDS::Face(It.Value()); + if(!Fv.IsSame(Favoid)){ + for(Jt.Initialize(myEFMap(P2.Arc()));Jt.More() && !Found ;Jt.Next()) { + if (TopoDS::Face(Jt.Value()).IsSame(Fv)) Found = Standard_True; + } + } + } + if (Found) { + for(It.Initialize(myVFMap(V));It.More();It.Next()) { + if (TopoDS::Face(It.Value()).IsSame(Fv)) { + ContainsV = Standard_True; + break; + } + } + } +#ifdef DEB + if(!ContainsV){ + cout<<"FindFace : the extremity of the spine is not in the end face"<<endl; + } +#endif + return Found; +} + +//======================================================================= +//function : MoreSurfdata +//purpose : detects if the intersection at end concerns several Surfdata +//======================================================================= +Standard_Boolean ChFi3d_Builder::MoreSurfdata(const Standard_Integer Index) const +{ + // intersection at end is created on several surfdata if : + // - the number of surfdata concerning the vertex is more than 1. + // - and if the last but one surfdata has one of commonpoints on one of + // two arcs, which constitute the intersections of the face at end and of the fillet + + ChFiDS_ListIteratorOfListOfStripe It; + It.Initialize(myVDataMap(Index)); + Handle(ChFiDS_Stripe)& stripe = It.Value(); + ChFiDS_SequenceOfSurfData& SeqFil = + stripe->ChangeSetOfSurfData()->ChangeSequence(); + const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index); + Standard_Integer sens = 0; + Standard_Integer num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens); + Standard_Boolean isfirst = (sens == 1); + Handle(ChFiDS_SurfData)& Fd = SeqFil.ChangeValue(num); + ChFiDS_CommonPoint& CV1 = Fd->ChangeVertex(isfirst,1); + ChFiDS_CommonPoint& CV2 = Fd->ChangeVertex(isfirst,2); + + Standard_Integer num1,num2,nbsurf; + TopoDS_Face Fv; + Standard_Boolean inters,oksurf; + nbsurf= stripe->SetOfSurfData()->Length(); + // Fv is the face at end + inters = FindFace(Vtx,CV1,CV2,Fv); + if (sens==1) { + num1=1; + num2=num1+1; + } + else { + num1=nbsurf; + num2=num1-1; + } + + oksurf=Standard_False; + + if (nbsurf!=1 && inters) { + + // determination of arc1 and arc2 intersection of the fillet and the face at end + + TopoDS_Edge arc1,arc2; + TopTools_ListIteratorOfListOfShape ItE; + Standard_Boolean trouve=Standard_False; + for(ItE.Initialize(myVEMap(Vtx));ItE.More()&&!trouve;ItE.Next()) { + arc1=TopoDS::Edge(ItE.Value()); + if (containE(Fv,arc1)) trouve=Standard_True; + } + trouve=Standard_False; + for(ItE.Initialize(myVEMap(Vtx));ItE.More()&&!trouve;ItE.Next()) { + arc2=TopoDS::Edge(ItE.Value()); + if (containE(Fv,arc2)&& !arc2.IsSame(arc1)) trouve=Standard_True; + } + + Handle(ChFiDS_SurfData) Fd1 = SeqFil.ChangeValue(num2); + ChFiDS_CommonPoint& CV3 = Fd1->ChangeVertex(isfirst,1); + ChFiDS_CommonPoint& CV4 = Fd1->ChangeVertex(isfirst,2); + + if (CV3.IsOnArc()) { + if (CV3.Arc().IsSame(arc1) ){ + if (CV1.Point().Distance(CV3.Point())<1.e-4) + oksurf=Standard_True; + } + else if (CV3.Arc().IsSame(arc2)){ + if (CV2.Point().Distance(CV3.Point())<1.e-4) + oksurf=Standard_True; + } + } + + if (CV4.IsOnArc()) { + if (CV1.Point().Distance(CV4.Point())<1.e-4) + oksurf=Standard_True; + else if (CV4.Arc().IsSame(arc2)){ + if (CV2.Point().Distance(CV4.Point())<1.e-4) + oksurf=Standard_True; + } + } + } + return oksurf; +} + + +//Case of fillets on top with 4 edges, one of them is on the same geometry as the edgeof the fillet + + +void ChFi3d_Builder::IntersectMoreCorner(const Standard_Integer Index) +{ + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + +#ifdef DEB + OSD_Chronometer ch;// init perf pour PerformSetOfKPart +#endif + // The fillet is returned, + ChFiDS_ListIteratorOfListOfStripe StrIt; + StrIt.Initialize(myVDataMap(Index)); + Handle(ChFiDS_Stripe) stripe = StrIt.Value(); + const Handle(ChFiDS_Spine) spine = stripe->Spine(); + ChFiDS_SequenceOfSurfData& SeqFil = + stripe->ChangeSetOfSurfData()->ChangeSequence(); + // the top, + const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index); + // the SurfData concerned and its CommonPoints, + Standard_Integer sens = 0; + + // Choose the proper SurfData + Standard_Integer num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens); + Standard_Boolean isfirst = (sens == 1); + if (isfirst) { + for (; num<SeqFil.Length() && ( + (SeqFil.Value(num)->IndexOfS1()==0) || + (SeqFil.Value(num)->IndexOfS2()==0) ); ) { + SeqFil.Remove(num); // The surplus is removed + } + } + else { + for (; num>1 && ( + (SeqFil.Value(num)->IndexOfS1()==0) || + (SeqFil.Value(num)->IndexOfS2()==0) ); ) { + SeqFil.Remove(num);// The surplus is removed + num--; + } + } + + Handle(ChFiDS_SurfData)& Fd = SeqFil.ChangeValue(num); + ChFiDS_CommonPoint& CV1 = Fd->ChangeVertex(isfirst,1); + ChFiDS_CommonPoint& CV2 = Fd->ChangeVertex(isfirst,2); + //To evaluate the cloud of new points. + Bnd_Box box1,box2; + + // The cases of cap are processed separately from intersection. + // ---------------------------------------------------------- + + TopoDS_Face Fv,Fad,Fop,Fopbis; + TopoDS_Edge Arcpiv,Arcprol,Arcspine,Arcprolbis; + if(isfirst) Arcspine = spine->Edges(1); + else Arcspine = spine->Edges(spine->NbEdges()); + TopAbs_Orientation OArcprolbis; +#ifndef DEB + TopAbs_Orientation OArcprolv = TopAbs_FORWARD, OArcprolop = TopAbs_FORWARD; +#else + TopAbs_Orientation OArcprolv, OArcprolop; +#endif + Standard_Integer ICurve; + Handle(BRepAdaptor_HSurface) HBs = new BRepAdaptor_HSurface(); + Handle(BRepAdaptor_HSurface) HBad = new BRepAdaptor_HSurface(); + Handle(BRepAdaptor_HSurface) HBop = new BRepAdaptor_HSurface(); + BRepAdaptor_Surface& Bs = HBs->ChangeSurface(); + BRepAdaptor_Surface& Bad = HBad->ChangeSurface(); + BRepAdaptor_Surface& Bop = HBop->ChangeSurface(); + Handle(Geom_Curve) Cc; + Handle(Geom2d_Curve) Pc,Ps; + Standard_Real Ubid,Vbid;//,mu,Mu,mv,Mv; +#ifndef DEB + Standard_Real Udeb = 0.,Ufin = 0.; +#else + Standard_Real Udeb,Ufin; +#endif + //gp_Pnt2d UVf1,UVl1,UVf2,UVl2; + //Standard_Real Du,Dv,Step; + Standard_Boolean inters = Standard_True; + Standard_Integer IFadArc = 1, IFopArc = 2; + Fop = TopoDS::Face(DStr.Shape(Fd->Index(IFopArc))); + TopExp_Explorer ex; + +#ifdef DEB + ChFi3d_InitChron(ch); // init perf condition +#endif + { + if(!CV1.IsOnArc() && !CV2.IsOnArc()) + Standard_Failure::Raise("Corner intersmore : no point on arc"); + else if(CV1.IsOnArc() && CV2.IsOnArc()){ + Standard_Boolean sur1 = 0, sur2 = 0; + for(ex.Init(CV1.Arc(),TopAbs_VERTEX); ex.More(); ex.Next()){ + if(Vtx.IsSame(ex.Current())) { + sur1 = 1; + break; + } + } + for(ex.Init(CV2.Arc(),TopAbs_VERTEX); ex.More(); ex.Next()){ + if(Vtx.IsSame(ex.Current())){ + sur2 = 1; + break; + } + } + if(sur2) IFadArc = 2; + } + else if(CV2.IsOnArc()) IFadArc = 2; + IFopArc = 3-IFadArc; + + Arcpiv = Fd->Vertex(isfirst,IFadArc).Arc(); + Fad = TopoDS::Face(DStr.Shape(Fd->Index(IFadArc))); + Fop = TopoDS::Face(DStr.Shape(Fd->Index(IFopArc))); + TopTools_ListIteratorOfListOfShape It; + // The face at end is returned without control of its unicity. + for(It.Initialize(myEFMap(Arcpiv));It.More();It.Next()) { + if(!Fad.IsSame(It.Value())){ + Fv = TopoDS::Face(It.Value()); + break; + } + } + + // does the face at end contain the Vertex ? + Standard_Boolean isinface = Standard_False; + for (ex.Init(Fv,TopAbs_VERTEX); ex.More(); ex.Next()){ + if (ex.Current().IsSame(Vtx)) { + isinface = Standard_True; + break; + } + } + if (!isinface) { + IFadArc = 3-IFadArc; + IFopArc = 3-IFopArc; + Arcpiv = Fd->Vertex(isfirst,IFadArc).Arc(); + Fad = TopoDS::Face(DStr.Shape(Fd->Index(IFadArc))); + Fop = TopoDS::Face(DStr.Shape(Fd->Index(IFopArc))); + //TopTools_ListIteratorOfListOfShape It; + // The face at end is returned without control of its unicity. + for(It.Initialize(myEFMap(Arcpiv));It.More();It.Next()) { + if(!Fad.IsSame(It.Value())){ + Fv = TopoDS::Face(It.Value()); + break; + } + } + } + + if(Fv.IsNull()) StdFail_NotDone::Raise + ("OneCorner : face at end is not found"); + + Fv.Orientation(TopAbs_FORWARD); + Fad.Orientation(TopAbs_FORWARD); + + // In the same way the edge to be extended is returned. + for(It.Initialize(myVEMap(Vtx));It.More() && Arcprol.IsNull();It.Next()){ + if(!Arcpiv.IsSame(It.Value())){ + for(ex.Init(Fv,TopAbs_EDGE); ex.More(); ex.Next()){ + if(It.Value().IsSame(ex.Current())) { + Arcprol = TopoDS::Edge(It.Value()); + OArcprolv = ex.Current().Orientation(); + break; + } + } + } + } + + //Fopbis is the face containing the trace of fillet CP.Arc() which of does not contain Vtx. + //Normallly Fobis is either the same as Fop (cylinder), or Fobis is G1 with Fop. + Fopbis.Orientation(TopAbs_FORWARD); + + //Fop calls the 4th face non-used for the vertex + cherche_face(myVFMap(Vtx),Arcprol,Fad,Fv,Fv,Fopbis); + Fop.Orientation(TopAbs_FORWARD); + + if(Arcprol.IsNull()) StdFail_NotDone::Raise + ("OneCorner : edge to be extended is not found"); + for(ex.Init(Fopbis,TopAbs_EDGE); ex.More(); ex.Next()){ + if(Arcprol.IsSame(ex.Current())) { + OArcprolop = ex.Current().Orientation(); + break; + } + } + TopoDS_Face FFv; + Standard_Real tol; + Standard_Integer prol; + BRep_Builder BRE; + Handle(Geom_Surface ) Sface; + Sface=BRep_Tool::Surface(Fv); + ChFi3d_ExtendSurface(Sface,prol); + tol=BRep_Tool::Tolerance(Fv); + BRE.MakeFace(FFv,Sface,tol); + if (prol) { + Bs.Initialize(FFv,Standard_False); + DStr.SetNewSurface(Fv,Sface); + } + else Bs.Initialize(Fv,Standard_False); + Bad.Initialize(Fad); + Bop.Initialize(Fop); + } + // it is necessary to modify the CommonPoint + // in the space and its parameter in FaceInterference. + // So both of them are returned in references + // non const. Attention the modifications are done behind + // CV1,CV2,Fi1,Fi2. + ChFiDS_CommonPoint& CPopArc = Fd->ChangeVertex(isfirst,IFopArc); + ChFiDS_FaceInterference& FiopArc = Fd->ChangeInterference(IFopArc); + ChFiDS_CommonPoint& CPadArc = Fd->ChangeVertex(isfirst,IFadArc); + ChFiDS_FaceInterference& FiadArc = Fd->ChangeInterference(IFadArc); + // the parameter of the vertex is initialized with the value + // of its opposing vertex (point on arc). + Standard_Real wop = Fd->ChangeInterference(IFadArc).Parameter(isfirst); + Handle(Geom_Curve) c3df; + Handle(GeomAdaptor_HSurface) + HGs = new GeomAdaptor_HSurface(DStr.Surface(Fd->Surf()).Surface()); + gp_Pnt2d p2dbout; + { + + // add here more or less restrictive criteria to + // decide if the intersection with face is done at the + // extended end or if there will be a cap on sharp end. + c3df = DStr.Curve(FiopArc.LineIndex()).Curve(); + Standard_Real uf = FiopArc.FirstParameter(); + Standard_Real ul = FiopArc.LastParameter(); + Handle(GeomAdaptor_HCurve) Hc3df; + if(c3df->IsPeriodic()){ + Hc3df = new GeomAdaptor_HCurve(c3df); + } + else{ + Hc3df = new GeomAdaptor_HCurve(c3df,uf,ul); + } + inters = Update(HBs,Hc3df,FiopArc,CPopArc,p2dbout,isfirst,wop); +// Modified by Sergey KHROMOV - Fri Dec 21 18:08:27 2001 Begin +// if(!inters && BRep_Tool::Continuity(Arcprol,Fv,Fop) != GeomAbs_C0){ + if(!inters && isTangentFaces(Arcprol,Fv,Fop)){ +// Modified by Sergey KHROMOV - Fri Dec 21 18:08:29 2001 End + // Arcprol is an edge of tangency, ultimate adjustment by an extrema curve/curve is attempted. + Standard_Real ff,ll; + Handle(Geom2d_Curve) gpcprol = BRep_Tool::CurveOnSurface(Arcprol,Fv,ff,ll); + Handle(Geom2dAdaptor_HCurve) pcprol = new Geom2dAdaptor_HCurve(gpcprol); + Standard_Real partemp = BRep_Tool::Parameter(Vtx,Arcprol); + inters = Update(HBs,pcprol,HGs,FiopArc,CPopArc,p2dbout, + isfirst,partemp,wop,10*tolesp); + } + Handle(BRepAdaptor_HCurve2d) pced = new BRepAdaptor_HCurve2d(); + pced->ChangeCurve2d().Initialize(CPadArc.Arc(),Fv); + Update(HBs,pced,HGs,FiadArc,CPadArc,isfirst); + } +#ifdef DEB + ChFi3d_ResultChron(ch,t_same); // result perf condition if (same) + ChFi3d_InitChron(ch); // init perf condition if (inters) +#endif + + TopoDS_Edge edgecouture; + Standard_Boolean couture,intcouture=Standard_False;; + Standard_Real tolreached; +#ifndef DEB + Standard_Real par1 = 0.,par2 = 0.; + Standard_Integer indpt =0,Icurv1 =0,Icurv2 =0; +#else + Standard_Real par1,par2; + Standard_Integer indpt,Icurv1,Icurv2; +#endif + Handle(Geom_TrimmedCurve) curv1,curv2; + Handle(Geom2d_Curve) c2d1,c2d2; + + Standard_Integer Isurf=Fd->Surf(); + + if (inters){ + HGs = ChFi3d_BoundSurf(DStr,Fd,1,2); + const ChFiDS_FaceInterference& Fi1 = Fd->InterferenceOnS1(); + const ChFiDS_FaceInterference& Fi2 = Fd->InterferenceOnS2(); + TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4); + gp_Pnt2d pfil1,pfac1,pfil2,pfac2; + Handle(Geom2d_Curve) Hc1,Hc2; + if( IFopArc == 1) pfac1 = p2dbout; + else { + Hc1 = BRep_Tool::CurveOnSurface(CV1.Arc(),Fv,Ubid,Ubid); + pfac1 = Hc1->Value(CV1.ParameterOnArc()); + } + if(IFopArc == 2) pfac2 = p2dbout; + else { + Hc2 = BRep_Tool::CurveOnSurface(CV2.Arc(),Fv,Ubid,Ubid); + pfac2 = Hc2->Value(CV2.ParameterOnArc()); + } + if(Fi1.LineIndex() != 0){ + pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(isfirst)); + } + else{ + pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(!isfirst)); + } + if(Fi2.LineIndex() != 0){ + pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(isfirst)); + } + else{ + pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(!isfirst)); + } + ChFi3d_Recale(Bs,pfac1,pfac2,(IFadArc == 1)); + Pardeb(1)= pfil1.X();Pardeb(2) = pfil1.Y(); + Pardeb(3)= pfac1.X();Pardeb(4) = pfac1.Y(); + Parfin(1)= pfil2.X();Parfin(2) = pfil2.Y(); + Parfin(3)= pfac2.X();Parfin(4) = pfac2.Y(); + Standard_Real uu1,uu2,vv1,vv2; + ChFi3d_Boite(pfac1,pfac2,uu1,uu2,vv1,vv2); + ChFi3d_BoundFac(Bs,uu1,uu2,vv1,vv2); + + if (!ChFi3d_ComputeCurves(HGs,HBs,Pardeb,Parfin,Cc, + Ps, + Pc,tolesp,tol2d,tolreached)) + Standard_Failure::Raise("OneCorner : failed calculation intersection"); + + Udeb = Cc->FirstParameter(); + Ufin = Cc->LastParameter(); + + // check if the curve has an intersection with sewing edge + + ChFi3d_Couture(Fv,couture,edgecouture); + + if (couture && !BRep_Tool::Degenerated(edgecouture)) { + + //Standard_Real Ubid,Vbid; + Handle (Geom_Curve) C=BRep_Tool::Curve(edgecouture,Ubid,Vbid); + Handle(Geom_TrimmedCurve) Ctrim=new Geom_TrimmedCurve (C,Ubid,Vbid); + GeomAdaptor_Curve cur1(Ctrim->BasisCurve()); + GeomAdaptor_Curve cur2(Cc); + Extrema_ExtCC extCC (cur1,cur2); + if (extCC.IsDone()&&extCC.NbExt()!=0) + { + Standard_Integer imin=0; + Standard_Real dist2min = RealLast(); + for (Standard_Integer i = 1; i <= extCC.NbExt(); i++) + if (extCC.SquareDistance(i) < dist2min) + { + dist2min = extCC.SquareDistance(i); + imin = i; + } + if (dist2min <= Precision::Confusion() * Precision::Confusion()) + { + Extrema_POnCurv ponc1,ponc2; + extCC.Points( imin, ponc1, ponc2 ); + par1 = ponc1.Parameter(); + par2 = ponc2.Parameter(); + Standard_Real Tol = 1.e-4; + if (Abs(par2-Udeb) > Tol && Abs(Ufin-par2) > Tol) + { + gp_Pnt P1=ponc1.Value(); + TopOpeBRepDS_Point tpoint( P1, Tol ); + indpt = DStr.AddPoint(tpoint); + intcouture = Standard_True; + curv1 = new Geom_TrimmedCurve(Cc,Udeb,par2); + curv2 = new Geom_TrimmedCurve(Cc,par2,Ufin); + TopOpeBRepDS_Curve tcurv1(curv1,tolreached); + TopOpeBRepDS_Curve tcurv2(curv2,tolreached); + Icurv1=DStr.AddCurve(tcurv1); + Icurv2=DStr.AddCurve(tcurv2); + } + } + } + } + } + + else{ + Standard_NotImplemented::Raise("OneCorner : cap not written"); + } + Standard_Integer IShape = DStr.AddShape(Fv); +#ifndef DEB + TopAbs_Orientation Et = TopAbs_FORWARD; +#else + TopAbs_Orientation Et; +#endif + if(IFadArc == 1){ + TopExp_Explorer Exp; + for (Exp.Init(Fv.Oriented(TopAbs_FORWARD), + TopAbs_EDGE);Exp.More();Exp.Next()) { + if (Exp.Current().IsSame(CV1.Arc())) { + Et = TopAbs::Reverse(TopAbs::Compose + (Exp.Current().Orientation(), + CV1.TransitionOnArc())); + break; + } + } + } + else{ + TopExp_Explorer Exp; + for (Exp.Init(Fv.Oriented(TopAbs_FORWARD), + TopAbs_EDGE);Exp.More();Exp.Next()) { + if (Exp.Current().IsSame(CV2.Arc())) { + Et = TopAbs::Compose(Exp.Current().Orientation(), + CV2.TransitionOnArc()); + break; + } + } + +// + + + } + +#ifdef DEB + ChFi3d_ResultChron(ch ,t_inter); //result perf condition if (inter) + ChFi3d_InitChron(ch); // init perf condition if ( inters) +#endif + + stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV1,DStr),isfirst,1); + stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV2,DStr),isfirst,2); + + if (!intcouture) { +// there is no intersection with edge of sewing +// curve Cc is stored in the stripe +// the storage in the DS is done by FILDS. + + TopOpeBRepDS_Curve Tc(Cc,tolreached); + ICurve = DStr.AddCurve(Tc); + Handle(TopOpeBRepDS_SurfaceCurveInterference) + Interfc = ChFi3d_FilCurveInDS(ICurve,IShape,Pc,Et); + DStr.ChangeShapeInterferences(IShape).Append(Interfc); + stripe->ChangePCurve(isfirst)=Ps; + stripe->SetCurve(ICurve,isfirst); + stripe->SetParameters(isfirst,Udeb,Ufin); + } + else { +// curves curv1 and curv2 are stored in the DS +// these curves are not reconstructed by FILDS as +// stripe->InDS(isfirst) is placed; + + // interferences of curv1 and curv2 on Fv + ComputeCurve2d(curv1,Fv,c2d1); + Handle(TopOpeBRepDS_SurfaceCurveInterference) InterFv; + InterFv = ChFi3d_FilCurveInDS(Icurv1,IShape,c2d1,Et); + DStr.ChangeShapeInterferences(IShape).Append(InterFv); + ComputeCurve2d(curv2,Fv,c2d2); + InterFv = ChFi3d_FilCurveInDS(Icurv2,IShape,c2d2,Et); + DStr.ChangeShapeInterferences(IShape).Append(InterFv); + // interferences of curv1 and curv2 on Isurf + if (Fd->Orientation()== Fv.Orientation()) Et=TopAbs::Reverse(Et); + c2d1=new Geom2d_TrimmedCurve(Ps,Udeb,par2); + InterFv = ChFi3d_FilCurveInDS(Icurv1,Isurf,c2d1,Et); + DStr.ChangeSurfaceInterferences(Isurf).Append(InterFv); + c2d2=new Geom2d_TrimmedCurve(Ps,par2,Ufin); + InterFv = ChFi3d_FilCurveInDS(Icurv2,Isurf,c2d2,Et); + DStr.ChangeSurfaceInterferences(Isurf).Append(InterFv); + + // limitation of the sewing edge + Standard_Integer Iarc=DStr.AddShape(edgecouture); + Handle(TopOpeBRepDS_CurvePointInterference) Interfedge; + TopAbs_Orientation ori; + TopoDS_Vertex Vdeb,Vfin; + Vdeb=TopExp::FirstVertex(edgecouture); + Vfin=TopExp::LastVertex(edgecouture); + Standard_Real pard,parf; + pard=BRep_Tool::Parameter(Vdeb,edgecouture); + parf=BRep_Tool::Parameter(Vfin,edgecouture); + if (Abs(par1-pard)<Abs(parf-par1)) ori=TopAbs_FORWARD; + else ori=TopAbs_REVERSED; + Interfedge = ChFi3d_FilPointInDS(ori,Iarc,indpt,par1); + DStr.ChangeShapeInterferences(Iarc).Append(Interfedge); + + // creation of CurveInterferences from Icurv1 and Icurv2 + stripe->InDS(isfirst); + Standard_Integer ind1= stripe->IndexPoint(isfirst,1); + Standard_Integer ind2= stripe->IndexPoint(isfirst,2); + Handle(TopOpeBRepDS_CurvePointInterference) + interfprol = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv1,ind1,Udeb); + DStr.ChangeCurveInterferences(Icurv1).Append(interfprol); + interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv1,indpt,par2); + DStr.ChangeCurveInterferences(Icurv1).Append(interfprol); + interfprol = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv2,indpt,par2); + DStr.ChangeCurveInterferences(Icurv2).Append(interfprol); + interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv2,ind2,Ufin); + DStr.ChangeCurveInterferences(Icurv2).Append(interfprol); + + } + + ChFi3d_EnlargeBox(HBs,Pc,Udeb,Ufin,box1,box2); + + if( inters){ +// + + // The small end of curve missing for the extension + // of the face at end and the limitation of the opposing face is added. + + // Above all the points cut the points with the edge of the spine. + Standard_Integer IArcspine = DStr.AddShape(Arcspine); + Standard_Integer IVtx = DStr.AddShape(Vtx); + TopAbs_Orientation OVtx2; +#ifndef DEB + TopAbs_Orientation OVtx = TopAbs_FORWARD; +#else + TopAbs_Orientation OVtx; +#endif + for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); + ex.More(); ex.Next()){ + if(Vtx.IsSame(ex.Current())) { + OVtx = ex.Current().Orientation(); + break; + } + } + OVtx = TopAbs::Reverse(OVtx); + Standard_Real parVtx = BRep_Tool::Parameter(Vtx,Arcspine); + Handle(TopOpeBRepDS_CurvePointInterference) + interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx); + DStr.ChangeShapeInterferences(IArcspine).Append(interfv); + + + //Modif of lvt to find the suite of Arcprol in the other face + { + TopTools_ListIteratorOfListOfShape It; + for (It.Initialize(myVEMap(Vtx)); It.More(); It.Next()){ + if (!(Arcprol.IsSame(It.Value()) || + Arcspine.IsSame(It.Value()) || + Arcpiv.IsSame(It.Value()))) { + Arcprolbis = TopoDS::Edge(It.Value()); + break; + } + } + } + //end of modif + + //Now the missing curves are constructed. + for(ex.Init(Arcprolbis.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); + ex.More(); ex.Next()){ + if(Vtx.IsSame(ex.Current())) { + OVtx2 = ex.Current().Orientation(); + break; + } + } + for(ex.Init(Arcprol.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); + ex.More(); ex.Next()){ + if(Vtx.IsSame(ex.Current())) { + OVtx = ex.Current().Orientation(); + break; + } + } +// it is checked if Fop has a sewing edge + +// TopoDS_Edge edgecouture; +// Standard_Boolean couture; + ChFi3d_Couture(Fop,couture,edgecouture); + Handle(Geom2d_Curve) Hc; +// parVtx = BRep_Tool::Parameter(Vtx,Arcprol); + const ChFiDS_FaceInterference& Fiop = Fd->Interference(IFopArc); + gp_Pnt2d pop1, pop2, pv1, pv2; + //deb modif + parVtx = BRep_Tool::Parameter(Vtx,Arcprolbis); +// Modified by skv - Thu Aug 21 11:55:58 2008 OCC20222 Begin +// if(Fop.IsSame(Fopbis)) OArcprolbis = OArcprolop; +// else OArcprolbis = Arcprolbis.Orientation(); + if(Fop.IsSame(Fopbis)) { + OArcprolbis = OArcprolop; + } else { + for(ex.Init(Fop,TopAbs_EDGE); ex.More(); ex.Next()){ + if(Arcprolbis.IsSame(ex.Current())) { + OArcprolbis = ex.Current().Orientation(); + break; + } + } + } +// Modified by skv - Thu Aug 21 11:55:58 2008 OCC20222 End + //fin modif + Hc = BRep_Tool::CurveOnSurface(Arcprolbis,Fop,Ubid,Ubid); + pop1 = Hc->Value(parVtx); + pop2 = Fiop.PCurveOnFace()->Value(Fiop.Parameter(isfirst)); + Hc = BRep_Tool::CurveOnSurface(Arcprol,Fv,Ubid,Ubid); + //modif + parVtx = BRep_Tool::Parameter(Vtx,Arcprol); + //fin modif + pv1 = Hc->Value(parVtx); + pv2 = p2dbout; + ChFi3d_Recale(Bs,pv1,pv2,1); + TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4); + Pardeb(1) = pop1.X(); Pardeb(2) = pop1.Y(); + Pardeb(3) = pv1.X(); Pardeb(4) = pv1.Y(); + Parfin(1) = pop2.X(); Parfin(2) = pop2.Y(); + Parfin(3) = pv2.X(); Parfin(4) = pv2.Y(); + Standard_Real uu1,uu2,vv1,vv2; + ChFi3d_Boite(pv1,pv2,uu1,uu2,vv1,vv2); + ChFi3d_BoundFac(Bs,uu1,uu2,vv1,vv2); + ChFi3d_Boite(pop1,pop2,uu1,uu2,vv1,vv2); + ChFi3d_BoundFac(Bop,uu1,uu2,vv1,vv2); + + Handle(Geom_Curve) zob3d; + Handle(Geom2d_Curve) zob2dop, zob2dv; +// Standard_Real tolreached; + if (!ChFi3d_ComputeCurves(HBop,HBs,Pardeb,Parfin,zob3d,zob2dop, + zob2dv,tolesp,tol2d,tolreached)) + Standard_Failure::Raise("OneCorner : echec calcul intersection"); + + Udeb = zob3d->FirstParameter(); + Ufin = zob3d->LastParameter(); + TopOpeBRepDS_Curve Zob(zob3d,tolreached); + Standard_Integer IZob = DStr.AddCurve(Zob); + + // it is not determined if the curve has an intersection with the sewing edge + + + { + Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolv)); + Standard_Integer Iop = DStr.AddShape(Fop); + Handle(TopOpeBRepDS_SurfaceCurveInterference) + InterFv = ChFi3d_FilCurveInDS(IZob,IShape,zob2dv,Et); + DStr.ChangeShapeInterferences(IShape).Append(InterFv); + //OVtx = TopAbs::Reverse(OVtx); +// Modified by skv - Thu Aug 21 11:55:58 2008 OCC20222 Begin +// Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolbis)); + Et = TopAbs::Reverse(TopAbs::Compose(OVtx2,OArcprolbis)); +// Modified by skv - Thu Aug 21 11:55:58 2008 OCC20222 End + //OVtx = TopAbs::Reverse(OVtx); +// Et = TopAbs::Reverse(Et); + Handle(TopOpeBRepDS_SurfaceCurveInterference) + Interfop = ChFi3d_FilCurveInDS(IZob,Iop,zob2dop,Et); + DStr.ChangeShapeInterferences(Iop).Append(Interfop); + Handle(TopOpeBRepDS_CurvePointInterference) + interfprol = ChFi3d_FilVertexInDS(TopAbs_FORWARD,IZob,IVtx,Udeb); + DStr.ChangeCurveInterferences(IZob).Append(interfprol); + Standard_Integer icc = stripe->IndexPoint(isfirst,IFopArc); + interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,IZob,icc,Ufin); + DStr.ChangeCurveInterferences(IZob).Append(interfprol); + + } + } + ChFi3d_EnlargeBox(DStr,stripe,Fd,box1,box2,isfirst); + if(CV1.IsOnArc()){ + ChFi3d_EnlargeBox(CV1.Arc(),myEFMap(CV1.Arc()),CV1.ParameterOnArc(),box1); + } + if(CV2.IsOnArc()){ + ChFi3d_EnlargeBox(CV2.Arc(),myEFMap(CV2.Arc()),CV2.ParameterOnArc(),box2); + } + if (!CV1.IsVertex()) + ChFi3d_SetPointTolerance(DStr,box1,stripe->IndexPoint(isfirst,1)); + if (!CV2.IsVertex()) + ChFi3d_SetPointTolerance(DStr,box2,stripe->IndexPoint(isfirst,2)); + +#ifdef DEB + ChFi3d_ResultChron(ch, t_sameinter);//result perf condition if (same &&inter) +#endif +} diff --git a/src/ChFi3d/ChFi3d_Builder_C2.cxx b/src/ChFi3d/ChFi3d_Builder_C2.cxx new file mode 100644 index 00000000..d4658c93 --- /dev/null +++ b/src/ChFi3d/ChFi3d_Builder_C2.cxx @@ -0,0 +1,670 @@ +// File: ChFi3d_Builder_C2.cxx +// Created: Tue Aug 20 14:14:29 1996 +// Author: Stagiaire Xuan Tang PHAMPHU +// <xpu@pomalox.paris1.matra-dtv.fr> + +#include <ChFi3d_Builder.jxx> +#include <ChFi3d.hxx> +#include <ChFi3d_Builder_0.hxx> + +#include <Precision.hxx> + +#include <Standard_Failure.hxx> +#include <Standard_NotImplemented.hxx> +#include <StdFail_NotDone.hxx> + + +#include <gp_Pnt.hxx> +#include <gp_Dir.hxx> +#include <gp_Vec.hxx> +#include <gp_Ax3.hxx> +#include <gp_Pnt2d.hxx> +#include <gp_Vec2d.hxx> +#include <gp_Dir2d.hxx> +#include <GeomLib.hxx> +#include <Extrema_ExtPC.hxx> +#include <Geom_Curve.hxx> +#include <Geom2d_Curve.hxx> +#include <Geom_BoundedCurve.hxx> + +#include <Geom2dAdaptor_HCurve.hxx> +#include <GeomAbs_Shape.hxx> +#include <GeomAdaptor_HCurve.hxx> +#include <GeomAdaptor_Surface.hxx> +#include <GeomAdaptor_HSurface.hxx> + +#include <Adaptor3d_HCurveOnSurface.hxx> +#include <BRepAdaptor_HSurface.hxx> +#include <BRepAdaptor_Curve.hxx> +#include <BRepAdaptor_Curve2d.hxx> +#include <BRepAdaptor_HCurve.hxx> +#include <BRepAdaptor_Surface.hxx> + +#include <BRep_Tool.hxx> + +#include <TopoDS.hxx> +#include <TopoDS_Shape.hxx> +#include <TopoDS_Face.hxx> +#include <TopoDS_Edge.hxx> +#include <TopoDS_Vertex.hxx> + +#include <TopAbs.hxx> +#include <TopAbs_ShapeEnum.hxx> +#include <TopAbs_Orientation.hxx> + +#include <TopExp.hxx> +#include <TopExp_Explorer.hxx> + +#include <TopTools_ListIteratorOfListOfShape.hxx> + +#include <TopOpeBRepDS_Point.hxx> +#include <TopOpeBRepDS_Curve.hxx> +#include <TopOpeBRepDS_Surface.hxx> +#include <TopOpeBRepDS_SurfaceCurveInterference.hxx> +#include <TopOpeBRepDS_CurvePointInterference.hxx> +#include <TopOpeBRepDS_DataStructure.hxx> +#include <TopOpeBRepDS_ListOfInterference.hxx> + +#include <ChFiDS_HData.hxx> +#include <ChFiDS_SurfData.hxx> +#include <ChFiDS_CommonPoint.hxx> +#include <ChFiDS_FaceInterference.hxx> +#include <ChFiDS_SequenceOfSurfData.hxx> +#include <ChFiDS_Stripe.hxx> +#include <ChFiDS_ListIteratorOfListOfStripe.hxx> + +#include <TColStd_Array1OfReal.hxx> + +static void Reduce(const Standard_Real& p1, + const Standard_Real& p2, + Handle(GeomAdaptor_HSurface)& hs1, + Handle(GeomAdaptor_HSurface)& hs2) +{ + GeomAdaptor_Surface& s1 = hs1->ChangeSurface(); + GeomAdaptor_Surface& s2 = hs2->ChangeSurface(); + const Handle(Geom_Surface&) surf = s1.Surface(); + Standard_Real ud,uf,vd,vf; + surf->Bounds(ud,uf,vd,vf); + Standard_Real milmoins = 0.51*vd+0.49*vf, milplus = 0.49*vd+0.51*vf; + if(p1 < p2) { + s1.Load(surf,ud,uf,vd,milmoins); + s2.Load(surf,ud,uf,milplus,vf); + } + else{ + s1.Load(surf,ud,uf,milplus,vf); + s2.Load(surf,ud,uf,vd,milmoins); + } +} + +static void Reduce(const Standard_Real& p1, + const Standard_Real& p2, + Handle(GeomAdaptor_HCurve)& hc) +{ + GeomAdaptor_Curve& c = hc->ChangeCurve(); + Standard_Real f = c.FirstParameter(); + Standard_Real l = c.LastParameter(); + Standard_Real milmoins = 0.51*f+0.49*l, milplus = 0.49*f+0.51*l; + if(p1 < p2) { + c.Load(c.Curve(),f,milmoins); + } + else{ + c.Load(c.Curve(),milplus,l); + } +} + + +//======================================================================= +//function : PerformTwoCornerbyInter +//purpose : Performs PerformTwoCorner by intersection. +// In case of Biseau for all cases the +// path is used; 3D curve and 2 pcurves are approximated. +//======================================================================= + +Standard_Integer ChFi3d_Builder::PerformTwoCornerbyInter(const Standard_Integer Index) + +{ + done = 0; + const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index); + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + + //Information on fillets is extracted + //------------------------------------------------------ + + //the first + //---------- + ChFiDS_ListIteratorOfListOfStripe It; + It.Initialize(myVDataMap(Index)); + Handle(ChFiDS_Stripe)& Corner1 = It.Value(); + Standard_Integer Sens1; + Standard_Integer IFd1 = + ChFi3d_IndexOfSurfData(Vtx,Corner1,Sens1); + ChFiDS_SequenceOfSurfData& SeqFil1 = + Corner1->ChangeSetOfSurfData()->ChangeSequence(); + Handle(ChFiDS_SurfData)& Fd1 = SeqFil1.ChangeValue(IFd1); + + //the second + //---------- + It.Next(); + Handle(ChFiDS_Stripe)& Corner2 = It.Value(); + Standard_Integer Sens2; + Standard_Integer IFd2; + if(Corner2 == Corner1) { + Sens2 = -1; + IFd2 = Corner2->SetOfSurfData()->Length(); + } + else{ IFd2 = ChFi3d_IndexOfSurfData(Vtx,Corner2,Sens2); } + ChFiDS_SequenceOfSurfData& SeqFil2 = + Corner2->ChangeSetOfSurfData()->ChangeSequence(); + Handle(ChFiDS_SurfData)& Fd2 = SeqFil2.ChangeValue(IFd2); + + // The concavities are analysed in case of differents concavities, + // preview an evolutionary connection of type ThreeCorner of R to 0. + // Otherwise the opposite face + // and the eventual intersection of 2 pcurves on this face are found. + + ChFiDS_State Stat1,Stat2; + Standard_Boolean isfirst1 = (Sens1 == 1); + Standard_Boolean isfirst2 = (Sens2 == 1); + Stat1 = Corner1->Spine()->Status(isfirst1); + Stat2 = Corner2->Spine()->Status(isfirst2); +/*#ifdef DEB + Standard_Boolean evolcoin = ((Stat1 == ChFiDS_OnSame && Stat2 == ChFiDS_OnDiff) || + (Stat2 == ChFiDS_OnSame && Stat1 == ChFiDS_OnDiff)); +#endif*/ + Standard_Boolean OkinterCC,Okvisavis,SameSide; + Standard_Integer IFaCo1,IFaCo2; + Standard_Real UIntPC1,UIntPC2; + TopoDS_Face FaCo; + OkinterCC = ChFi3d_IsInFront(DStr,Corner1,Corner2,IFd1,IFd2,Sens1,Sens2, + UIntPC1,UIntPC2,FaCo,SameSide, + IFaCo1,IFaCo2,Okvisavis,Vtx,Standard_True); + if (!Okvisavis) { +#if DEB + cout<<"TwoCorner : pas de face commune"<<endl; +#endif + done=Standard_False; + return done; + } + if (!OkinterCC) { + // The intersection of pcurves is calculated without restricting them by + // common points. + OkinterCC= ChFi3d_IsInFront(DStr,Corner1,Corner2,IFd1,IFd2,Sens1,Sens2, + UIntPC1,UIntPC2,FaCo,SameSide, + IFaCo1,IFaCo2,Okvisavis,Vtx,Standard_True,1); + } + + if (!Okvisavis) { +#if DEB + cout<<"TwoCorner : no common face"<<endl; +#endif + done=Standard_False; + return done; + } + if (!OkinterCC) { +#if DEB + cout<<"biseau : failed intersection of tangency lines on common face"<<endl; +#endif + done=Standard_False; + return done; + } + Standard_Integer IFaArc1 = 3-IFaCo1, IFaArc2 = 3-IFaCo2; + + // It is checked if the fillets have a commonpoint on a common arc. + // This edge is the pivot of the bevel or of the kneecap. + + ChFiDS_CommonPoint& CP1 = Fd1->ChangeVertex(isfirst1,IFaArc1); + ChFiDS_CommonPoint& CP2 = Fd2->ChangeVertex(isfirst2,IFaArc2); + + if (!CP1.IsOnArc() || !CP2.IsOnArc()) { +#if DEB + cout<<"fail 1 of 2 fillets are not on arc"<<endl; +#endif + done=Standard_False; + return done; + } + if ( ! CP1.Arc().IsSame( CP2.Arc()) ) { + // look like OnSame + OnDiff case (eap, Arp 9 2002, occ266) +#if DEB + cout<<"PerformTwoCornerbyInter(): fillets are not on the same arc"<<endl; +#endif + done = Standard_True; + PerformMoreThreeCorner(Index, 2); + return done; + } + + TopoDS_Edge pivot; + pivot = CP1.Arc(); + Standard_Real parCP1 = CP1.ParameterOnArc(); + Standard_Real parCP2 = CP2.ParameterOnArc(); + Handle(BRepAdaptor_HCurve) Hpivot = new BRepAdaptor_HCurve(pivot); + if (!pivot.IsSame(CP2.Arc())){ + Handle(Geom_Curve) csau; + Standard_Real ubid,vbid; + csau=BRep_Tool::Curve(pivot,ubid,vbid ); + Handle(Geom_BoundedCurve) C1= Handle(Geom_BoundedCurve)::DownCast(csau); + if (! C1.IsNull()) { + GeomLib::ExtendCurveToPoint(C1,CP2.Point(),1,Standard_False); + GeomAdaptor_Curve cad; + cad.Load(C1); + Extrema_ExtPC ext(CP2.Point(),cad,1.e-4); + parCP2 = ext.Point(1).Parameter(); + } + } + gp_Pnt psp1 = Hpivot->Value(parCP1); + gp_Pnt psp2 = Hpivot->Value(parCP2); + Standard_Real sameparam = (psp1.Distance(psp2) < 10 * tolesp); + + TopoDS_Face FF1 = TopoDS::Face(DStr.Shape(Fd1->Index(IFaArc1))); + TopoDS_Face FF2 = TopoDS::Face(DStr.Shape(Fd2->Index(IFaArc2))); + TopTools_ListIteratorOfListOfShape Kt; + Standard_Boolean ok1 = Standard_False, ok2 = Standard_False; + for (Kt.Initialize(myEFMap(pivot)); Kt.More(); Kt.Next()){ + TopoDS_Face F = TopoDS::Face(Kt.Value()); + if(!ok1 && FF1.IsSame(F)){ + ok1 = Standard_True; + } + if(!ok2 && FF2.IsSame(F)){ + ok2 = Standard_True; + } + } + if(!ok1 || !ok2){ +#if DEB + cout<<"fail one of surfaces has no common base face with the pivot edge"<<endl; +#endif + done=Standard_False; + return done; + } + + Handle(GeomAdaptor_HSurface) HS1, HS2; + HS1 = ChFi3d_BoundSurf (DStr,Fd1,IFaCo1,IFaArc1); + HS2 = ChFi3d_BoundSurf (DStr,Fd2,IFaCo2,IFaArc2); + + TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4); + + Handle(Geom2d_Curve) PGc1,PGc2; + Handle(Geom_Curve) Gc; + + if(sameparam) { + // Side common face, calculation of Pardeb. + ChFi3d_ComputesIntPC (Fd1->Interference(IFaCo1), + Fd2->Interference(IFaCo2), + HS1,HS2,UIntPC1,UIntPC2); + gp_Pnt2d UV; + UV = Fd1->Interference(IFaCo1).PCurveOnSurf()->Value(UIntPC1); + Pardeb(1)= UV.X(); Pardeb(2)=UV.Y(); + UV = Fd2->Interference(IFaCo2).PCurveOnSurf()->Value(UIntPC2); + Pardeb(3)= UV.X(); Pardeb(4)=UV.Y(); + gp_Pnt PFaCo = HS1->Surface().Value(Pardeb(1),Pardeb(2)); + + // Side arc, calculation of Parfin. + Standard_Real UIntArc1 = Fd1->Interference(IFaArc1).Parameter(isfirst1); + Standard_Real UIntArc2 = Fd2->Interference(IFaArc2).Parameter(isfirst2); + + ChFi3d_ComputesIntPC (Fd1->Interference(IFaArc1),Fd2->Interference(IFaArc2), + HS1,HS2,UIntArc1,UIntArc2); + UV = Fd1->Interference(IFaArc1).PCurveOnSurf()->Value(UIntArc1); + Parfin(1)= UV.X(); Parfin(2)=UV.Y(); + UV = Fd2->Interference(IFaArc2).PCurveOnSurf()->Value(UIntArc2); + Parfin(3)= UV.X(); Parfin(4)=UV.Y(); + + if(Fd1->Surf() == Fd2->Surf()){ + Reduce(UIntPC1,UIntPC2,HS1,HS2); + } + + Standard_Real tolreached; + if (IFaCo1 == 1 && + !ChFi3d_ComputeCurves(HS1,HS2,Pardeb,Parfin,Gc, + PGc1,PGc2,tolesp,tol2d,tolreached)) { +#if DEB + cout<<"failed to calculate bevel error interSS"<<endl; +#endif + done=Standard_False; + return done; + } + else if (IFaCo1 == 2 && + !ChFi3d_ComputeCurves(HS1,HS2,Parfin,Pardeb,Gc, + PGc1,PGc2,tolesp,tol2d,tolreached)) { +#if DEB + cout<<"failed to calculate bevel error interSS"<<endl; +#endif + done=Standard_False; + return done; + } + // CornerData are updated with results of the intersection. + Standard_Real WFirst = Gc->FirstParameter(); + Standard_Real WLast = Gc->LastParameter(); + Standard_Integer Ipoin1; + Standard_Integer Ipoin2; + ChFiDS_CommonPoint& cpco1 = Fd1->ChangeVertex(isfirst1,IFaCo1); + ChFiDS_CommonPoint& cpco2 = Fd2->ChangeVertex(isfirst2,IFaCo2); + Standard_Real tolpco = Max(cpco1.Tolerance(),cpco2.Tolerance()); + ChFiDS_CommonPoint& cparc1 = Fd1->ChangeVertex(isfirst1,IFaArc1); + ChFiDS_CommonPoint& cparc2 = Fd2->ChangeVertex(isfirst2,IFaArc2); + Standard_Real tolparc = Max(cparc1.Tolerance(),cparc2.Tolerance()); + Standard_Integer ICurv = DStr.AddCurve(TopOpeBRepDS_Curve(Gc,tolreached)); + //Corner1 + Corner1->SetParameters(isfirst1,WFirst,WLast); + Corner1->SetCurve(ICurv,isfirst1); + Corner1->ChangePCurve(isfirst1) = PGc1; + cpco1.Reset(); + cpco1.SetPoint(PFaCo); + cpco1.SetTolerance(Max(tolreached,tolpco)); + Fd1->ChangeInterference(IFaCo1).SetParameter(UIntPC1,isfirst1); + tolparc = Max(tolparc,tolreached); + cparc1.SetTolerance(Max(tolparc,tolreached)); + Ipoin1 = ChFi3d_IndexPointInDS(Fd1->Vertex(isfirst1,1),DStr); + Corner1->SetIndexPoint(Ipoin1,isfirst1,1); + Ipoin2 = ChFi3d_IndexPointInDS(Fd1->Vertex(isfirst1,2),DStr); + Corner1->SetIndexPoint(Ipoin2,isfirst1,2); + //Corner2 + Corner2->SetParameters(isfirst2,WFirst,WLast); + Corner2->SetCurve(ICurv,isfirst2); + Corner2->ChangePCurve(isfirst2) = PGc2; + Fd2->ChangeInterference(IFaCo2).SetParameter(UIntPC2,isfirst2); + Fd2->ChangeVertex(isfirst2,IFaCo2) = Fd1->Vertex(isfirst1,IFaCo1); + Fd2->ChangeVertex(isfirst2,IFaArc2) = Fd1->Vertex(isfirst1,IFaArc1); + if (IFaCo1!=IFaCo2) Corner2->SetOrientation(TopAbs_REVERSED,isfirst2); + Corner2->SetIndexPoint(Corner1->IndexPoint(isfirst1,IFaCo1), + isfirst2,IFaCo2); + Corner2->SetIndexPoint(Corner1->IndexPoint(isfirst1,IFaArc1), + isfirst2,IFaArc2); + //The tolerances of points are updated. + Bnd_Box bco,barc; + if(IFaCo1 == 1) ChFi3d_EnlargeBox(DStr,Corner1,Fd1,bco,barc,isfirst1); + else ChFi3d_EnlargeBox(DStr,Corner1,Fd1,barc,bco,isfirst1); + if(IFaCo2 == 1) ChFi3d_EnlargeBox(DStr,Corner2,Fd2,bco,barc,isfirst2); + else ChFi3d_EnlargeBox(DStr,Corner2,Fd2,barc,bco,isfirst2); + const ChFiDS_CommonPoint& cparc = Fd1->Vertex(isfirst1,IFaArc1); + ChFi3d_EnlargeBox(cparc.Arc(),myEFMap(cparc.Arc()),cparc.ParameterOnArc(),barc); + ChFi3d_SetPointTolerance(DStr,barc,Corner1->IndexPoint(isfirst1,IFaArc1)); + ChFi3d_SetPointTolerance(DStr,bco,Corner1->IndexPoint(isfirst1,IFaCo1)); + } + else { + // It is necessary to identify the border surface, + // find the end point of the intersection Surf/Surf + // by the intersection of the tangency line of the small + // on the opposing face with the surface of the big, + // and finally intersect the big with the face at end + // between this point and the point on arc. +#ifndef DEB + Standard_Boolean parcrois = Standard_False ; +#else + Standard_Boolean parcrois; +#endif + TopExp_Explorer Expl; + for(Expl.Init(pivot.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); + Expl.More(); Expl.Next()){ + if(Expl.Current().IsSame(Vtx)){ + parcrois = (Expl.Current().Orientation() == TopAbs_FORWARD); + break; + } + } + Handle(ChFiDS_Stripe) BigCD, SmaCD; + Handle(ChFiDS_SurfData) BigFD, SmaFD; + Handle(GeomAdaptor_HSurface) BigHS, SmaHS; + Standard_Integer IFaCoBig, IFaCoSma, IFaArcBig, IFaArcSma; + Standard_Boolean isfirstBig, isfirstSma; + Standard_Real UIntPCBig, UIntPCSma; + + if((parcrois && parCP2 > parCP1) || (!parcrois && parCP2 < parCP1)){ + UIntPCBig = UIntPC2; UIntPCSma = UIntPC1; + BigHS = HS2; SmaHS = HS1; + BigCD = Corner2; SmaCD = Corner1; + BigFD = Fd2; SmaFD = Fd1; + IFaCoBig = IFaCo2; IFaCoSma = IFaCo1; + IFaArcBig = IFaArc2; IFaArcSma = IFaArc1; + isfirstBig = isfirst2; isfirstSma = isfirst1; + } + else{ + UIntPCBig = UIntPC1, UIntPCSma = UIntPC2; + BigHS = HS1; SmaHS = HS2; + BigCD = Corner1; SmaCD = Corner2; + BigFD = Fd1; SmaFD = Fd2; + IFaCoBig = IFaCo1; IFaCoSma = IFaCo2; + IFaArcBig = IFaArc1; IFaArcSma = IFaArc2; + isfirstBig = isfirst1; isfirstSma = isfirst2; + } + + //Intersection of the big with the small : + //------------------------------------ + + // Pardeb (parameters of point PFaCo) + // the intersection is checked + ChFi3d_ComputesIntPC (SmaFD->Interference(IFaCoSma), + BigFD->Interference(IFaCoBig), + SmaHS,BigHS,UIntPCSma,UIntPCBig); + gp_Pnt2d UVi; + UVi = BigFD->Interference(IFaCoBig).PCurveOnSurf()->Value(UIntPCBig); + Pardeb(3)= UVi.X(); Pardeb(4)=UVi.Y(); + UVi = SmaFD->Interference(IFaCoSma).PCurveOnSurf()->Value(UIntPCSma); + Pardeb(1)= UVi.X(); Pardeb(2)=UVi.Y(); + gp_Pnt PFaCo = SmaHS->Value(UVi.X(),UVi.Y()); + + // Parfin (parameters of point PMil) + const ChFiDS_FaceInterference& FiArcSma = SmaFD->Interference(IFaArcSma); + Handle(Geom_Curve) ctg = DStr.Curve(FiArcSma.LineIndex()).Curve(); + Handle(GeomAdaptor_HCurve) Hctg = new GeomAdaptor_HCurve(); + GeomAdaptor_Curve& bid = Hctg->ChangeCurve(); + Standard_Real temp,wi; + + if (isfirstSma) { + wi = temp = FiArcSma.FirstParameter(); + if (UIntPCSma < temp) + temp = UIntPCSma; + bid.Load(ctg,temp,FiArcSma.LastParameter()); + } + else { + wi = temp = FiArcSma.LastParameter(); + if (UIntPCSma > temp) + temp = UIntPCSma; + bid.Load(ctg,FiArcSma.FirstParameter(),temp); + } + if(SmaFD->Surf() == BigFD->Surf()){ + Reduce(UIntPCSma,UIntPCBig,SmaHS,BigHS); + Reduce(UIntPCSma,UIntPCBig,Hctg); + } + if(!ChFi3d_IntCS(BigHS,Hctg,UVi,wi)){ +#if DEB + cout<<"bevel : failed inter C S"<<endl; +#endif + done=Standard_False; + return done; + } + Parfin(3) = UVi.X(); Parfin(4) = UVi.Y(); + UVi = FiArcSma.PCurveOnSurf()->Value(wi); + Parfin(1) = UVi.X(); Parfin(2) = UVi.Y(); + gp_Pnt PMil = SmaHS->Value(Parfin(1),Parfin(2)); + + Standard_Real tolreached; + if (!ChFi3d_ComputeCurves(SmaHS,BigHS,Pardeb,Parfin,Gc, + PGc1,PGc2,tolesp,tol2d,tolreached)) { +#if DEB + cout<<"failed to calculate bevel failed interSS"<<endl; +#endif + done=Standard_False; + return done; + } + // SmaCD is updated, for it this is all. + Standard_Real WFirst = Gc->FirstParameter(); + Standard_Real WLast = Gc->LastParameter(); + Standard_Integer IpointCo, IpointMil, IpointArc; + ChFiDS_CommonPoint& psmaco = SmaFD->ChangeVertex(isfirstSma,IFaCoSma); + ChFiDS_CommonPoint& pbigco = BigFD->ChangeVertex(isfirstBig,IFaCoBig); + Standard_Real tolpco = Max(psmaco.Tolerance(),pbigco.Tolerance()); + ChFiDS_CommonPoint& psmamil = SmaFD->ChangeVertex(isfirstSma,IFaArcSma); + Standard_Real tolpmil = psmamil.Tolerance(); + Standard_Integer ICurv = DStr.AddCurve(TopOpeBRepDS_Curve(Gc,tolreached)); + + SmaCD->SetParameters(isfirstSma,WFirst,WLast); + SmaCD->SetCurve(ICurv,isfirstSma); + SmaCD->ChangePCurve(isfirstSma) = PGc1; + psmaco.Reset(); + psmaco.SetPoint(PFaCo); + psmaco.SetTolerance(Max(tolpco,tolreached)); + SmaFD->ChangeInterference(IFaCoSma).SetParameter(UIntPCSma,isfirstSma); + psmamil.Reset(); + psmamil.SetPoint(PMil); + psmamil.SetTolerance(Max(tolpmil,tolreached)); + SmaFD->ChangeInterference(IFaArcSma).SetParameter(wi,isfirstSma); + IpointCo = ChFi3d_IndexPointInDS(psmaco,DStr); + SmaCD->SetIndexPoint(IpointCo,isfirstSma,IFaCoSma); + IpointMil = ChFi3d_IndexPointInDS(psmamil,DStr); + SmaCD->SetIndexPoint(IpointMil,isfirstSma,IFaArcSma); + if (IFaCoSma == 2) SmaCD->SetOrientation(TopAbs_REVERSED,isfirstSma); + + // For BigCD the first results are met in the DS. + BigCD->SetIndexPoint(IpointCo,isfirstBig,IFaCoBig); + BigFD->ChangeVertex(isfirstBig,IFaCoBig) = psmaco; + BigFD->ChangeInterference(IFaCoBig).SetParameter(UIntPCBig,isfirstBig); + + TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(ICurv); + Handle(TopOpeBRepDS_CurvePointInterference) Interfp; + Interfp = ChFi3d_FilPointInDS(TopAbs_FORWARD,ICurv,IpointCo,WFirst); + Li.Append(Interfp); + Interfp = ChFi3d_FilPointInDS(TopAbs_REVERSED,ICurv,IpointMil,WLast); + Li.Append(Interfp); + + // the transition of curves of intersection on the Big + TopAbs_Orientation tra = BigFD->InterferenceOnS1().Transition(); + TopAbs_Orientation ofac = DStr.Shape(BigFD->IndexOfS1()).Orientation(); + TopAbs_Orientation ofil = BigFD->Orientation(); + TopAbs_Orientation tracurv = TopAbs::Compose(ofac,ofil); + tracurv = TopAbs::Compose(tracurv,tra); + if(!isfirstBig) tracurv = TopAbs::Reverse(tracurv); + if(IFaCoBig != 1) tracurv = TopAbs::Reverse(tracurv); + + Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfc; + Standard_Integer ISurf = BigFD->Surf(); + Interfc = ChFi3d_FilCurveInDS (ICurv,ISurf,PGc2,tracurv); + DStr.ChangeSurfaceInterferences(ISurf).Append(Interfc); + + //The tolerances of points are updated (beginning). + Bnd_Box bco,bmil,barc; + if(IFaCoSma == 1) ChFi3d_EnlargeBox(DStr,SmaCD,SmaFD,bco,bmil,isfirstSma); + else ChFi3d_EnlargeBox(DStr,SmaCD,SmaFD,bmil,bco,isfirstSma); + ChFi3d_EnlargeBox(BigHS,PGc2,WFirst,WLast,bco,bmil); + + // Intersection of the big with the face at end : + // ------------------------------------------- + + // Pardeb (parameters of PMil) + // The intersection curve surface is tried again, now with representation + // pcurve on face of the curve to be sure. + TopoDS_Face F = TopoDS::Face(DStr.Shape(SmaFD->Index(IFaArcSma))); + Handle(BRepAdaptor_HSurface) HF = new BRepAdaptor_HSurface(F); + Standard_Real fsma = FiArcSma.FirstParameter(); + Standard_Real lsma = FiArcSma.LastParameter(); + Standard_Real deltSma = 0.05 * (lsma - fsma); + Handle(Geom2d_Curve) pcpc = SmaFD->Interference(IFaArcSma).PCurveOnFace(); + fsma = Max(pcpc->FirstParameter(),wi-deltSma); + lsma = Min(pcpc->LastParameter(),wi+deltSma); + if ( lsma<fsma ) { + done=Standard_False; + return done; + } + Handle(Geom2dAdaptor_HCurve) c2df = + new Geom2dAdaptor_HCurve(SmaFD->Interference(IFaArcSma).PCurveOnFace(),fsma,lsma); + Adaptor3d_CurveOnSurface consf(c2df,HF); + Handle(Adaptor3d_HCurveOnSurface) Hconsf = new Adaptor3d_HCurveOnSurface(consf); + if(!ChFi3d_IntCS(BigHS,Hconsf,UVi,wi)) { +#if DEB + cout<<"bevel : failed inter C S"<<endl; +#endif + done=Standard_False; + return done; + } + Pardeb(3) = UVi.X(); Pardeb(4) = UVi.Y(); + UVi = SmaFD->Interference(IFaArcSma).PCurveOnFace()->Value(wi); + Pardeb(1) = UVi.X(); Pardeb(2) = UVi.Y(); + gp_Pnt2d ppff1 = UVi; + + // Parfin (parameters of the point cpend) + Standard_Real ptg = BigFD->Interference(IFaArcBig).Parameter(isfirstBig); + UVi = BigFD->Interference(IFaArcBig).PCurveOnSurf()->Value(ptg); + Parfin(3) = UVi.X(); Parfin(4) = UVi.Y(); + ChFiDS_CommonPoint& cpend = BigFD->ChangeVertex(isfirstBig,IFaArcBig); + TopoDS_Edge etest = cpend.Arc(); + if(BRep_Tool::IsClosed(etest,F)) etest.Reverse(); + BRepAdaptor_Curve2d arc(etest,F); + UVi = arc.Value(cpend.ParameterOnArc()); + Parfin(1) = UVi.X(); Parfin(2) = UVi.Y(); + gp_Pnt2d ppff2 = UVi; + + // Intersection. + Standard_Real uu1,uu2,vv1,vv2; + ChFi3d_Boite(ppff1,ppff2,uu1,uu2,vv1,vv2); + // for the case when two chamfers are on two edges OnSame, + // it is necessary to extend the surface carrying F, or at least + // not to limit it. + ChFi3d_BoundFac(HF->ChangeSurface(),uu1,uu2,vv1,vv2,Standard_True); + + if (!ChFi3d_ComputeCurves(HF,BigHS,Pardeb,Parfin,Gc, + PGc1,PGc2,tolesp,tol2d,tolreached)) { +#if DEB + cout<<"fail calculation bevel fail interSS"<<endl; +#endif + done=Standard_False; + return done; + } + + // End of update of the BigCD and the DS. + WFirst = Gc->FirstParameter(); + WLast = Gc->LastParameter(); + ICurv = DStr.AddCurve(TopOpeBRepDS_Curve(Gc,tolreached)); + cpend.SetTolerance(Max(cpend.Tolerance(),tolreached)); + IpointArc = ChFi3d_IndexPointInDS(cpend,DStr); + BigCD->SetIndexPoint(IpointArc,isfirstBig,IFaArcBig); + + TopOpeBRepDS_ListOfInterference& Li7 = DStr.ChangeCurveInterferences(ICurv); + Interfp = ChFi3d_FilPointInDS(TopAbs_FORWARD,ICurv,IpointMil,WFirst); + Li7.Append(Interfp); + Interfp = ChFi3d_FilPointInDS(TopAbs_REVERSED,ICurv,IpointArc,WLast); + Li7.Append(Interfp); + Interfc = ChFi3d_FilCurveInDS (ICurv,ISurf,PGc2,tracurv); + DStr.ChangeSurfaceInterferences(ISurf).Append(Interfc); + BigCD->InDS(isfirstBig); + + // Finally the information on faces is placed in the DS. + Standard_Integer IShape = DStr.AddShape(F); + if(SmaFD->Surf() == BigFD->Surf()){ + tracurv = TopAbs::Compose(etest.Orientation(), + cpend.TransitionOnArc()); + } + else { + TopExp_Explorer Exp; + for (Exp.Init(F.Oriented(TopAbs_FORWARD), + TopAbs_EDGE);Exp.More();Exp.Next()) { + if (Exp.Current().IsSame(etest)) { + tracurv = TopAbs::Compose(Exp.Current().Orientation(), + cpend.TransitionOnArc()); + break; + } + } + } + Interfc = ChFi3d_FilCurveInDS(ICurv,IShape,PGc1,tracurv); + DStr.ChangeShapeInterferences(IShape).Append(Interfc); + + //The tolerances of points are updated (end). + Handle(ChFiDS_Stripe) bidst; + if(IFaCoBig == 1) ChFi3d_EnlargeBox(DStr,bidst,BigFD,bco,barc,isfirstBig); + else ChFi3d_EnlargeBox(DStr,bidst,BigFD,barc,bco,isfirstBig); + ChFi3d_EnlargeBox(BigHS,PGc2,WFirst,WLast,bmil,barc); + ChFi3d_EnlargeBox(HF,PGc1,WFirst,WLast,bmil,barc); + ChFi3d_EnlargeBox(Gc,WFirst,WLast,bmil,barc); + const ChFiDS_CommonPoint& cparc = BigFD->Vertex(isfirstBig,IFaArcBig); + ChFi3d_EnlargeBox(cparc.Arc(),myEFMap(cparc.Arc()),cparc.ParameterOnArc(),barc); + + ChFi3d_SetPointTolerance(DStr,bco,SmaCD->IndexPoint(isfirstSma,IFaCoSma)); + ChFi3d_SetPointTolerance(DStr,bmil,SmaCD->IndexPoint(isfirstSma,IFaArcSma)); + ChFi3d_SetPointTolerance(DStr,barc,BigCD->IndexPoint(isfirstBig,IFaArcBig)); + } + done = 1; + + return done; +} + + + + + + diff --git a/src/ChFi3d/ChFi3d_Builder_CnCrn.cxx b/src/ChFi3d/ChFi3d_Builder_CnCrn.cxx new file mode 100644 index 00000000..2a05ab58 --- /dev/null +++ b/src/ChFi3d/ChFi3d_Builder_CnCrn.cxx @@ -0,0 +1,2969 @@ +// File: ChFi3d_Builder_CnCrn.cxx +// Created: 03-01-97 +// Author: MPS +// Modified by MPS (14-04-97) traitement des cas ou il n'y a pas +// d'intersection entre les stripes +// Modified by MPS (16-06-97) : on tient compte du fait que GeomPlate +// rend les courbes 2d dans meme ordre que les +// courbes frontieres passees en entree +// Modified by JLR (20-08-97) mise en place des nouveaux constructeurs de GeomPlate +// +// Modified by MPS (03-11-97) on ne cree pas un batten lorsque le rapport +// entre les deux resolutions sur la surface est trop grand (PRO10649) +// +// Modified by MPS (05-12-97) on ne tient pas compte des aretes degenerees +// lors du calcul du nombre d'aretes. +// +// Modified by JCT (08-12-97) traitement des aretes vives consecutives ou non +// (grille EDC412 sauf D2, L1, L2, L3) +// +// Modified by JCT (11-12-97) pb osf avec indpoint + orientation de plate +// ( --> D2, L1, L2, L3 valides mais laids) +// +// Modified by MPS (24-02-98) traitement des aretes de regularite +// +// Modified by MPS (01-06-98) traitement des aretes de couture +// Modified by MPS (01-12-98) traitement des bords libres +// Modified by MPS (01-02-99) traitement des aretes de regularite +// consecutives +// Traitement des coins + +#include <Adaptor3d_HCurveOnSurface.hxx> +#include <Adaptor3d_CurveOnSurface.hxx> +#include <Bnd_Box2d.hxx> +#include <BndLib_Add2dCurve.hxx> +#include <BRep_Tool.hxx> +#include <BRepTools.hxx> +#include <BRepAlgo_NormalProjection.hxx> +#include <BRepLib_MakeEdge.hxx> +#include <ChFi3d_Builder.jxx> +#include <ChFi3d_Builder_0.hxx> +#include <ChFiDS_FaceInterference.hxx> +#include <ChFiDS_ListIteratorOfListOfStripe.hxx> +#include <ChFiDS_SurfData.hxx> +#include <ChFiDS_SequenceOfSurfData.hxx> +#include <ChFiDS_Stripe.hxx> +#include <ChFiDS_HData.hxx> +#include <ChFiDS_CommonPoint.hxx> +#include <ChFiDS_Regul.hxx> +#include <ChFiDS_StripeArray1.hxx> +#include <Extrema_ExtPC.hxx> +#include <Extrema_ExtCC.hxx> +#include <Extrema_POnCurv.hxx> +#include <GeomLib.hxx> +#include <Extrema_ExtPC.hxx> +#include <Geom2d_BSplineCurve.hxx> +#include <GeomAdaptor_HSurface.hxx> +#include <Geom2d_Line.hxx> +#include <Geom_Line.hxx> +#include <Geom_Curve.hxx> +#include <Geom2d_TrimmedCurve.hxx> +#include <GeomInt_IntSS.hxx> +#include <GeomLib.hxx> +#include <GeomAdaptor.hxx> +#include <Geom2dAdaptor_HCurve.hxx> +#include <GeomPlate_BuildPlateSurface.hxx> +#include <GeomPlate_Surface.hxx> +#include <GeomPlate_MakeApprox.hxx> +#include <GeomPlate_PlateG0Criterion.hxx> +#include <GeomPlate_HArray1OfHCurveOnSurface.hxx> +#include <Geom_Surface.hxx> +#include <Geom_BezierCurve.hxx> +#include <Geom2dLProp_CLProps2d.hxx> +#include <GeomPlate_CurveConstraint.hxx> +#include <FairCurve_Batten.hxx> +#include <Geom2d_BSplineCurve.hxx> +#include <gp_Pnt.hxx> +#include <gp_Pnt2d.hxx> +#include <gp_Dir2d.hxx> +#include <math_Matrix.hxx> +#include <PLib.hxx> +#include <TColStd_HArray1OfInteger.hxx> +#include <TColStd_ListOfInteger.hxx> +#include <TColgp_SequenceOfXY.hxx> +#include <TColgp_SequenceOfXYZ.hxx> +#include <TColgp_Array1OfXYZ.hxx> +#include <TColgp_Array1OfPnt.hxx> +#include <TColgp_Array1OfPnt2d.hxx> +#include <TopTools_IndexedMapOfShape.hxx> +#include <TColStd_Array1OfInteger.hxx> +#include <TColStd_Array1OfBoolean.hxx> +#include <TColStd_Array2OfInteger.hxx> +#include <TColStd_Array1OfReal.hxx> +#include <TColStd_Array2OfReal.hxx> +#include <TColGeom2d_Array1OfCurve.hxx> +#include <TColGeom2d_SequenceOfCurve.hxx> +#include <TColGeom_Array1OfCurve.hxx> +#include <TColGeom_SequenceOfCurve.hxx> +#include <TColGeom2d_HArray1OfCurve.hxx> +#include <TopAbs_Orientation.hxx> +#include <TopExp.hxx> +#include <TopExp_Explorer.hxx> +#include <TopOpeBRepDS_DataStructure.hxx> +#include <TopOpeBRepDS_Curve.hxx> +#include <TopOpeBRepDS_Point.hxx> +#include <TopOpeBRepDS_Surface.hxx> +#include <TopOpeBRepDS_ListOfInterference.hxx> +#include <TopOpeBRepDS_SolidSurfaceInterference.hxx> +#include <TopOpeBRepDS_Kind.hxx> +#include <TopOpeBRepDS_Transition.hxx> +#include <TopOpeBRepDS_CurvePointInterference.hxx> +#include <TopOpeBRepDS_SurfaceCurveInterference.hxx> +#include <TopTools_Array2OfShape.hxx> +#include <BRepLib_MakeFace.hxx> +#include <Precision.hxx> +// performances +#ifdef DEB +#include <OSD_Chronometer.hxx> +extern Standard_Real t_plate ,t_approxplate,t_batten; +extern void ChFi3d_InitChron(OSD_Chronometer& ch); +extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time); +#endif + +// Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 Begin +Standard_Boolean isTangentFaces(const TopoDS_Edge &theEdge, + const TopoDS_Face &theFace1, + const TopoDS_Face &theFace2); +// Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 End + +//======================================================================= +//function : Indices +//purpose : +//======================================================================= + +static void Indices ( const Standard_Integer n, + const Standard_Integer ic, + Standard_Integer & icplus, + Standard_Integer & icmoins) +{ + if (ic== (n-1)) icplus=0; + else icplus=ic+1; + if (ic==0) icmoins=n-1; + else icmoins=ic-1; +} + +//======================================================================= +//function : Calcul_Param +//purpose : +//======================================================================= + +static void Calcul_Param (const Handle(ChFiDS_Stripe)& stripe, + const Standard_Integer jfposit, + const Standard_Integer indice, + const Standard_Boolean isfirst, + Standard_Real & param) +{ + if (jfposit==2 ) + param=stripe->SetOfSurfData()->Value(indice)->InterferenceOnS2().Parameter(isfirst); + else + param=stripe->SetOfSurfData()->Value(indice)->InterferenceOnS1().Parameter(isfirst); +} + +//======================================================================= +//function : Calcul_P2dOnSurf +//purpose : +//======================================================================= + +static void Calcul_P2dOnSurf(const Handle(ChFiDS_Stripe)& stripe, + const Standard_Integer jfposit, + const Standard_Integer indice, + const Standard_Real param, + gp_Pnt2d & p2) + +{ + if (jfposit==1) + stripe->SetOfSurfData()->Value(indice) + ->InterferenceOnS1().PCurveOnSurf()->D0(param,p2); + else + stripe->SetOfSurfData()->Value(indice) + ->InterferenceOnS2().PCurveOnSurf()->D0(param,p2); +} + +//======================================================================= +//function : Calcul_C2dOnFace +//purpose : +//======================================================================= + +static void Calcul_C2dOnFace (const Handle(ChFiDS_Stripe)& stripe, + const Standard_Integer jfposit, + const Standard_Integer indice, + Handle(Geom2d_Curve) & c2d) + +{ + if (jfposit==1) + c2d = stripe->SetOfSurfData()->Value(indice) + ->InterferenceOnS1().PCurveOnFace(); + else + c2d = stripe->SetOfSurfData()->Value(indice) + ->InterferenceOnS2().PCurveOnFace(); +} + +//======================================================================= +//function : Calcul_Orientation +//purpose : +//======================================================================= + +static void Calcul_Orientation(const Handle(ChFiDS_Stripe)& stripe, + const Standard_Integer jfposit, + const Standard_Integer indice, + TopAbs_Orientation & orient) +{ + if (jfposit==1) + orient = stripe->SetOfSurfData()->Value(indice) + ->InterferenceOnS1().Transition(); + else + orient = stripe->SetOfSurfData()->Value(indice) + ->InterferenceOnS2().Transition(); +} + +//======================================================================= +//function : RemoveSD +//purpose : +//======================================================================= + +static void RemoveSD(Handle(ChFiDS_Stripe)& Stripe, + const Standard_Integer num1, + const Standard_Integer num2 ) +{ + ChFiDS_SequenceOfSurfData& Seq = + Stripe->ChangeSetOfSurfData()->ChangeSequence(); + if(Seq.IsEmpty()) return; + if (num1==num2) + Seq.Remove(num1); + else + Seq.Remove(num1,num2); +} + +//======================================================================= +//function : cherche_edge1 +//purpose : find common edge of faces F1 and F2 +//======================================================================= + +static void cherche_edge1 (const TopoDS_Face & F1, + const TopoDS_Face & F2, + TopoDS_Edge & Edge) +{ Standard_Integer i,j; + TopoDS_Edge Ecur1,Ecur2; + Standard_Boolean trouve=Standard_False; + TopTools_IndexedMapOfShape MapE1,MapE2; + TopExp::MapShapes( F1,TopAbs_EDGE,MapE1); + TopExp::MapShapes( F2,TopAbs_EDGE,MapE2); + for ( i=1; i<= MapE1.Extent()&&!trouve; i++) + { + TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(i)); + Ecur1=TopoDS::Edge(aLocalShape); + // Ecur1=TopoDS::Edge(TopoDS_Shape (MapE1(i))); + for ( j=1; j<= MapE2.Extent()&&!trouve; j++) + { + aLocalShape = TopoDS_Shape (MapE2(j)); + Ecur2=TopoDS::Edge(aLocalShape); + // Ecur2=TopoDS::Edge(TopoDS_Shape (MapE2(j))); + if (Ecur2.IsSame(Ecur1)) + {Edge=Ecur1;trouve=Standard_True;} + } + } +} + +//======================================================================= +//function : CurveHermite +//purpose : calculate a curve 3d using polynoms of Hermite. +// the edge is a regular edge. Curve 3D is constructed +// between edges icmoins and icplus. +//======================================================================= + +static void CurveHermite (const TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_Stripe)& CDicmoins, + const Standard_Integer jficmoins, + const Standard_Integer icmoins, + const Standard_Real picmoins, + const Standard_Integer sensicmoins, + const Standard_Boolean sharpicmoins, + const TopoDS_Edge & Eviveicmoins, + const Handle(ChFiDS_Stripe)& CDicplus, + const Standard_Integer jficplus, + const Standard_Integer icplus, + const Standard_Real picplus, + const Standard_Integer sensicplus, + const Standard_Boolean sharpicplus, + const TopoDS_Edge & Eviveicplus, + const Standard_Integer nbface, + TopTools_SequenceOfShape & Ecom, + const TopTools_SequenceOfShape & Face, + TColGeom2d_SequenceOfCurve & proj2d, + TColGeom_SequenceOfCurve & cproj, + TopTools_SequenceOfShape & Eproj, + TColStd_SequenceOfReal & param, + Standard_Real & error) +{ + gp_Pnt p01,p02; + gp_Vec d11,d12; + Standard_Integer ii,jj; + Standard_Real up1,up2; + Standard_Integer ilin,jfp; + Handle (Geom_Curve) c1,c2; + if (sharpicmoins) { + c1=BRep_Tool::Curve(Eviveicmoins,up1,up2); + } + else { + if (jficmoins==1) + ilin= CDicmoins->SetOfSurfData()->Value( icmoins)->InterferenceOnS1().LineIndex(); + else ilin= CDicmoins->SetOfSurfData()->Value(icmoins)->InterferenceOnS2().LineIndex(); + c1=DStr.Curve(ilin).Curve(); + } + if (sharpicplus){ + c2=BRep_Tool::Curve(Eviveicplus,up1,up2); + } + else { + jfp=3-jficplus; + if (jfp==1) + ilin= CDicplus->SetOfSurfData()->Value( icplus)->InterferenceOnS1().LineIndex(); + else ilin=CDicplus->SetOfSurfData()->Value(icplus)->InterferenceOnS2().LineIndex(); + c2=DStr.Curve(ilin ).Curve(); + } + c1->D1(picmoins,p01,d11); + c2->D1(picplus,p02,d12); + Standard_Integer size = 4; + math_Matrix MatCoefs(1,size, 1,size); + TColgp_Array1OfXYZ Cont(1,size); + PLib::HermiteCoefficients(0, 1,1,1,MatCoefs); + Standard_Real L1=p01.Distance(p02); + Standard_Real lambda= ((Standard_Real)1) / Max (d11.Magnitude() / L1, 1.e-6); + Cont(1) = p01.XYZ(); + if (sensicmoins==1) Cont(2) = d11.XYZ()*(-lambda) ; + else Cont(2) = d11.XYZ()*(lambda) ; + lambda= ((Standard_Real)1) / Max (d12.Magnitude() / L1, 1.e-6); + Cont(3) = p02.XYZ(); + if (sensicplus==1) Cont(4) = d12.XYZ()*(lambda); + else Cont(4) = d12.XYZ()*(-lambda); + TColgp_Array1OfPnt ExtrapPoles(1, size); + TColgp_Array1OfPnt ExtraCoeffs(1, size); + gp_Pnt p0(0,0,0); + ExtraCoeffs.Init(p0); + for (ii=1; ii<=size; ii++) { + for (jj=1; jj<=size; jj++) { + ExtraCoeffs(jj).ChangeCoord() += MatCoefs(ii,jj)*Cont(ii); + } + } + PLib::CoefficientsPoles(ExtraCoeffs, PLib::NoWeights(), + ExtrapPoles, PLib::NoWeights()); + Handle(Geom_BezierCurve) Bezier = new (Geom_BezierCurve) (ExtrapPoles); + BRepLib_MakeEdge Bedge (Bezier); + TopoDS_Edge edg =Bedge. Edge(); + TopoDS_Face F; + error=1.e-30; + Standard_Integer nb; + for(nb=1;nb<=nbface;nb++){ + F=TopoDS::Face(Face.Value(nb)); + TopTools_IndexedMapOfShape MapE1; + TopoDS_Edge E1; + Handle(Geom2d_Curve) proj1; + Handle(Geom_Curve) proj1c,proj2c; + BRepAlgo_NormalProjection OrtProj; + OrtProj.Init(F); + OrtProj.Add(edg); + OrtProj.SetParams(1.e-4, 1.e-4, GeomAbs_C1, 14, 16); + OrtProj.Build(); + if ( OrtProj.IsDone()){ + TopExp::MapShapes(OrtProj.Projection() , TopAbs_EDGE, MapE1); + if (MapE1.Extent()!=0){ + if (MapE1.Extent()!=1) { + BRepLib_MakeFace Bface (BRep_Tool::Surface(F)); + F=Bface.Face(); + OrtProj.Init(F); + OrtProj.Build(); + MapE1.Clear(); + if ( OrtProj.IsDone()) + TopExp::MapShapes(OrtProj.Projection() ,TopAbs_EDGE, MapE1); + } + if (MapE1.Extent()!=0) { + Standard_Boolean trouve=Standard_False; + for (Standard_Integer ind=1;ind<=MapE1.Extent()&&!trouve;ind++){ + TopoDS_Shape aLocalShape = TopoDS_Shape( MapE1(ind)); + E1=TopoDS::Edge( aLocalShape ); + // E1=TopoDS::Edge( TopoDS_Shape (MapE1(ind))); + if (!BRep_Tool::Degenerated(E1)) trouve=Standard_True; + } + Eproj.Append(E1); + proj1=BRep_Tool::CurveOnSurface(E1,F,up1,up2); + proj2d.Append(new Geom2d_TrimmedCurve(proj1,up1,up2)); + proj1c=BRep_Tool::Curve(E1,up1,up2); + cproj.Append(new Geom_TrimmedCurve(proj1c,up1,up2)); + if (error>BRep_Tool::Tolerance(E1)) error=BRep_Tool::Tolerance(E1); + } + else { + Eproj.Append(E1); + proj2d.Append(proj1); + cproj.Append(proj1c); + } + } + else { + Eproj.Append(E1); + proj2d.Append(proj1); + cproj.Append(proj1c); + } + } + } + for (nb=1;nb<=nbface-1;nb++) { + BRepAdaptor_Curve C(TopoDS::Edge(Ecom.Value(nb))); + C.D0(param.Value(nb),p02); + GeomAdaptor_Curve L (Bezier); + Extrema_ExtCC ext (C,L); + if (ext.IsDone()){ + if (ext.NbExt()!=0){ + Extrema_POnCurv POnC, POnL; + ext.Points(1, POnC, POnL); + param.ChangeValue(nb) =POnC.Parameter(); + } + } + if (!ext.IsDone()||ext.NbExt()==0) { + if (!cproj.Value(nb).IsNull()) { + cproj.Value(nb)->D0(cproj.Value(nb)->LastParameter(),p01); + } + else if (!cproj.Value(nb+1).IsNull()) { + cproj.Value(nb+1)->D0(cproj.Value(nb+1)->FirstParameter(),p01); + } + if (p01.Distance(p02)>1.e-4 ){ + Extrema_ExtPC ext1 (p01,C); + if (ext1.IsDone()){ + if (ext1.NbExt()!=0){ + Extrema_POnCurv POnC(ext1.Point(1)); + param.ChangeValue(nb) =POnC.Parameter(); + } + } + } + } + } +} + +//======================================================================= +//function : CalculDroite +//purpose : calculate a 2D straight line passing through point p2d1 and direction xdir ydir +//======================================================================= + +static void CalculDroite(const gp_Pnt2d & p2d1, + const Standard_Real xdir, + const Standard_Real ydir, + Handle (Geom2d_Curve) & pcurve) +{ gp_Dir2d dir1 (xdir, ydir); + Handle(Geom2d_Line) l= new Geom2d_Line (p2d1,dir1); + Standard_Real l0 = sqrt(xdir*xdir+ ydir*ydir ); + pcurve = new Geom2d_TrimmedCurve(l,0,l0); +} + +//======================================================================= +//function : CalculBatten +//purpose : calcule a batten between curves 2d curv2d1 and curv2d2 at points p2d1 and p2d2 +//======================================================================= + +static void CalculBatten (const Handle (GeomAdaptor_HSurface) ASurf, + const TopoDS_Face Face , + const Standard_Real xdir, + const Standard_Real ydir, + const gp_Pnt2d & p2d1, + const gp_Pnt2d & p2d2, + const Standard_Boolean contraint1, + const Standard_Boolean contraint2, + Handle (Geom2d_Curve) & curv2d1, + Handle (Geom2d_Curve) & curv2d2, + const Standard_Real picicplus, + const Standard_Real picplusic, + const Standard_Boolean inverseic, + const Standard_Boolean inverseicplus, + Handle (Geom2d_Curve)& pcurve) +{ + Standard_Boolean isplane; +#ifndef DEB + Standard_Boolean anglebig = Standard_False; +#else + Standard_Boolean anglebig; +#endif + isplane=ASurf->GetType()==GeomAbs_Plane; + gp_Dir2d dir1 (xdir, ydir); + Geom2dLProp_CLProps2d CL1(curv2d1, picicplus, 1, 1.e-4); + Geom2dLProp_CLProps2d CL2( curv2d2, picplusic, 1, 1.e-4); + gp_Dir2d dir3,dir4 ; + CL1.Tangent(dir3); + CL2.Tangent(dir4); + if (inverseic) dir3.Reverse(); + if (inverseicplus) dir4.Reverse(); + Standard_Real h = p2d2.Distance(p2d1)/20; + FairCurve_Batten Bat(p2d1,p2d2,h); + Bat.SetFreeSliding (Standard_True); + Standard_Real ang1,ang2; + ang1=dir1.Angle(dir3); + if (dir1.Angle(dir4) >0 ) ang2=PI-dir1.Angle(dir4); + else ang2=-PI-dir1.Angle(dir4); + if (contraint1&&contraint2) + anglebig=(Abs(ang1)>1.2)|| (Abs(ang2)>1.2 ); + else if (contraint1) + anglebig=Abs(ang1)>1.2; + else if (contraint2) + anglebig=Abs(ang2)>1.2; + if (isplane && (Abs(ang1)>PI/2 || Abs(ang2)>PI/2)) + isplane=Standard_False; + if (anglebig && !isplane) { + CalculDroite(p2d1,xdir,ydir,pcurve); + } + else { + if (contraint1) Bat.SetAngle1(ang1); + else Bat.SetConstraintOrder1(0); + if (contraint2) Bat.SetAngle2(ang2); + else Bat.SetConstraintOrder2(0); + FairCurve_AnalysisCode Iana; + Standard_Boolean Ok; + Ok = Bat.Compute(Iana,25,1.e-2); +#if DEB + if (!Ok) { + cout<<"no batten :"; + Bat.Dump(cout); + } +#endif + if (Ok) { + pcurve = Bat.Curve(); + Standard_Real umin,vmin,umax,vmax; + BRepTools::UVBounds(Face,umin,umax,vmin,vmax); + Bnd_Box2d bf,bc; + Geom2dAdaptor_Curve acur(pcurve); + BndLib_Add2dCurve::Add(acur,0,bc); + bf.Update(umin,vmin,umax,vmax); + Standard_Real uminc,vminc,umaxc,vmaxc; + bc.Get(uminc,vminc,umaxc,vmaxc); + if (uminc<umin-1.e-7) Ok=Standard_False; + if (umaxc>umax+1.e-7) Ok=Standard_False; + if (vminc<vmin-1.e-7) Ok=Standard_False; + if (vmaxc>vmax+1.e-7) Ok=Standard_False; + } + if (!Ok) CalculDroite(p2d1, xdir,ydir, pcurve); + } +} + +//======================================================================= +//function : OrientationIcNonVive +//purpose : calculate the orientation of the curve between ic and icplus knowing that ic +// is not a living edge. +//======================================================================= + +static void OrientationIcNonVive (const Handle(ChFiDS_Stripe) & CDic, + const Standard_Integer jfic, + const Standard_Integer icicplus, + const Standard_Integer sensic, + TopAbs_Orientation & orien ) +{ + TopAbs_Orientation orinterf; + Calcul_Orientation(CDic,jfic,icicplus,orinterf); + if (sensic!=1){ + if (orinterf==TopAbs_FORWARD) orien=TopAbs_FORWARD; + else orien=TopAbs_REVERSED; + } + else { + if (orinterf==TopAbs_FORWARD) orien=TopAbs_REVERSED; + else orien=TopAbs_FORWARD; + } +} + +//======================================================================= +//function : OrientationIcplusNonVive +//purpose : calculate the orientation of the curve between ic and icplus knowing that icplus +// is not a living edge; +//======================================================================= + +static void OrientationIcplusNonVive (const Handle(ChFiDS_Stripe) & CDicplus, + const Standard_Integer jficplus, + const Standard_Integer icplusic, + const Standard_Integer sensicplus, + TopAbs_Orientation & orien ) +{ + TopAbs_Orientation orinterf; + Standard_Integer jfp = 3 -jficplus; + Calcul_Orientation(CDicplus,jfp,icplusic,orinterf); + if (sensicplus==1){ + if (orinterf==TopAbs_FORWARD) orien=TopAbs_FORWARD; + else orien=TopAbs_REVERSED; + } + else { + if (orinterf==TopAbs_FORWARD) orien=TopAbs_REVERSED; + else orien=TopAbs_FORWARD; + } +} + +//======================================================================= +//function : OrientationAreteViveConsecutive +//purpose : calculate the orientation of the curve between edges ic and icplus +// where ic and icplus are consecutively living +//======================================================================= + +static void OrientationAreteViveConsecutive (const TopoDS_Shape & Fviveicicplus, + const TopoDS_Shape & Eviveic, + const TopoDS_Vertex & V1, + TopAbs_Orientation & orien) + +{ // orinterf is orientation of edge ic corresponding to face Fviveicicplus taken FORWARD +#ifndef DEB + TopAbs_Orientation orinterf = TopAbs_FORWARD; +#else + TopAbs_Orientation orinterf; +#endif + TopoDS_Face F=TopoDS::Face( Fviveicicplus); + TopoDS_Edge E=TopoDS::Edge( Eviveic); + TopExp_Explorer ex; + for(ex.Init(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);ex.More(); ex.Next()){ + if(E.IsSame(ex.Current())) { + orinterf = ex.Current().Orientation(); + break; + } + } + // if V1 is vertex REVERSED of edge ic the curve + // has the same orientation as ic + TopoDS_Vertex vl; + vl=TopExp::LastVertex(E); + if (vl.IsSame(V1)){ + if (orinterf==TopAbs_FORWARD) orien=TopAbs_FORWARD; + else orien=TopAbs_REVERSED; + } + else { + if (orinterf==TopAbs_FORWARD) orien=TopAbs_REVERSED; + else orien=TopAbs_FORWARD; + } +} + +//======================================================================= +//function : PerformTwoCornerSameExt +//purpose : calculate intersection between two stripes stripe1 and stripe2 +//======================================================================= + +static void PerformTwoCornerSameExt(TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_Stripe)& stripe1, + const Standard_Integer index1, + const Standard_Integer sens1, + const Handle(ChFiDS_Stripe) &stripe2, + const Standard_Integer index2, + const Standard_Integer sens2, + Standard_Boolean & trouve) + +{ Handle (TopOpeBRepDS_CurvePointInterference) Interfp1, Interfp2; + Handle (TopOpeBRepDS_SurfaceCurveInterference) Interfc; + TopAbs_Orientation orpcurve,trafil1,orsurf1,orsurf2; + Standard_Boolean isfirst; + Standard_Integer indic1,indic2, indpoint1,indpoint2,ind,indcurve; + Standard_Real tol; + gp_Pnt P1,P2,P3,P4; + gp_Pnt2d p2d; + Handle(Geom_Curve)cint; + Handle(Geom2d_Curve) C2dint1,C2dint2; + isfirst=sens1==1; + ChFiDS_CommonPoint& Com11= stripe1->SetOfSurfData()->Value(index1)->ChangeVertex (isfirst,1); + ChFiDS_CommonPoint& Com12= stripe1->SetOfSurfData()->Value(index1)->ChangeVertex (isfirst,2); + isfirst=sens2==1; + ChFiDS_CommonPoint& Com21= stripe2->SetOfSurfData()->Value(index2)->ChangeVertex (isfirst,1); +#ifdef DEB +// ChFiDS_CommonPoint& Com22= +// stripe2->SetOfSurfData()->Value(index2)->ChangeVertex (isfirst,2); +#endif + indic1=stripe1->SetOfSurfData()->Value(index1)->Surf(); + indic2=stripe2->SetOfSurfData()->Value(index2)->Surf(); + const Handle(ChFiDS_SurfData) Fd1=stripe1->SetOfSurfData()->Value(index1); + const Handle(ChFiDS_SurfData) Fd2=stripe2->SetOfSurfData()->Value(index2); + + TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4); + const ChFiDS_FaceInterference& Fi11 = Fd1->InterferenceOnS1(); + const ChFiDS_FaceInterference& Fi12 = Fd1->InterferenceOnS2(); + const ChFiDS_FaceInterference& Fi21 = Fd2->InterferenceOnS1(); + const ChFiDS_FaceInterference& Fi22 = Fd2->InterferenceOnS2(); + gp_Pnt2d pfi11,pfi12,pfi21,pfi22; + isfirst=sens1==1; + pfi11 = Fi11.PCurveOnSurf()->Value(Fi11.Parameter(isfirst)); + pfi12 = Fi12.PCurveOnSurf()->Value(Fi12.Parameter(isfirst)); + isfirst=sens2==1; + if (Com11.Point().Distance(Com21.Point()) <1.e-4) { + pfi21 = Fi21.PCurveOnSurf()->Value(Fi21.Parameter(isfirst)); + pfi22 = Fi22.PCurveOnSurf()->Value(Fi22.Parameter(isfirst)); + } + else { + pfi22 = Fi21.PCurveOnSurf()->Value(Fi21.Parameter(isfirst)); + pfi21 = Fi22.PCurveOnSurf()->Value(Fi22.Parameter(isfirst)); + } + + Pardeb(1)= pfi11.X();Pardeb(2) = pfi11.Y(); + Pardeb(3)= pfi21.X();Pardeb(4) = pfi21.Y(); + Parfin(1)= pfi12.X();Parfin(2) = pfi12.Y(); + Parfin(3)= pfi22.X();Parfin(4) = pfi22.Y(); + + Handle(GeomAdaptor_HSurface) HS1= ChFi3d_BoundSurf(DStr,Fd1,1,2); + Handle(GeomAdaptor_HSurface) HS2= ChFi3d_BoundSurf(DStr,Fd2,1,2); + trouve=Standard_False; + if (ChFi3d_ComputeCurves(HS1,HS2,Pardeb,Parfin,cint, + C2dint1,C2dint2,1.e-4,1.e-5,tol)){ + cint->D0(cint->FirstParameter(),P1); + cint->D0(cint->LastParameter(),P2); + trouve=((Com11.Point().Distance(P1) <1.e-4 || Com11.Point().Distance(P2)<1.e-4)&& + (Com12.Point().Distance(P1) <1.e-4 || Com12.Point().Distance(P2)<1.e-4)); + } + + if (trouve) { + isfirst=sens1==1; + stripe1->InDS(isfirst); + indpoint1=ChFi3d_IndexPointInDS(Com11,DStr); + indpoint2=ChFi3d_IndexPointInDS(Com12,DStr); + stripe1->SetIndexPoint(indpoint1,isfirst,1); + stripe1->SetIndexPoint(indpoint2,isfirst,2); + isfirst=sens2==1; + stripe2->InDS(isfirst); + if (Com11.Point().Distance(Com21.Point()) <1.e-4) { + stripe2->SetIndexPoint(indpoint1,isfirst,1); + stripe2->SetIndexPoint(indpoint2,isfirst,2); + } + else { + stripe2->SetIndexPoint(indpoint2,isfirst,1); + stripe2->SetIndexPoint(indpoint1,isfirst,2); + } + + orsurf1=Fd1->Orientation(); + trafil1 = DStr.Shape(Fd1->IndexOfS1()).Orientation(); + trafil1 = TopAbs::Compose(trafil1,Fd1->Orientation()); + trafil1 = TopAbs::Compose(TopAbs::Reverse(Fi11.Transition()),trafil1); + orsurf2=Fd2->Orientation(); + TopOpeBRepDS_Curve tcurv3d(cint,tol); + indcurve= DStr.AddCurve(tcurv3d); + cint->D0(cint->FirstParameter(),P1); + cint->D0(cint->LastParameter(),P2); + Fi11.PCurveOnFace()->D0(Fi11.LastParameter(),p2d); + const Handle(Geom_Surface) Stemp = + BRep_Tool::Surface(TopoDS::Face(DStr.Shape(Fd1->IndexOfS1()))); + Stemp ->D0(p2d.X(),p2d.Y(),P4); + Fi11.PCurveOnFace()->D0(Fi11.FirstParameter(),p2d); + Stemp ->D0(p2d.X(),p2d.Y(),P3); + if (P1.Distance(P4)<1.e-4 || P2.Distance(P3)<1.e-4) + orpcurve=trafil1; + else orpcurve=TopAbs::Reverse(trafil1); + if (Com11.Point().Distance(P1) >1.e-4) { + ind=indpoint1; + indpoint1=indpoint2; + indpoint2=ind; + } + Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurve, indpoint1, cint->FirstParameter()); + Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurve,indpoint2, cint->LastParameter()); + DStr.ChangeCurveInterferences(indcurve).Append(Interfp1); + DStr.ChangeCurveInterferences(indcurve).Append(Interfp2); + Interfc=ChFi3d_FilCurveInDS(indcurve,indic1,C2dint1,orpcurve); + DStr.ChangeSurfaceInterferences(indic1).Append(Interfc); + if (orsurf1==orsurf2) orpcurve=TopAbs::Reverse(orpcurve); + Interfc=ChFi3d_FilCurveInDS(indcurve,indic2,C2dint2,orpcurve); + DStr.ChangeSurfaceInterferences(indic2).Append(Interfc); + } +} + +//======================================================================= +//function : CpOnEdge +//purpose : determine if surfdata num has a common point on Eadj1 or Eadj2 +//======================================================================= + +static void CpOnEdge (const Handle(ChFiDS_Stripe) & stripe, + Standard_Integer num, + Standard_Boolean isfirst, + const TopoDS_Edge & Eadj1, + const TopoDS_Edge & Eadj2, + Standard_Boolean & compoint) + +{ ChFiDS_CommonPoint cp1,cp2; + compoint=Standard_False; + cp1 = stripe->SetOfSurfData()->Value(num)->ChangeVertex (isfirst,1); + cp2 = stripe->SetOfSurfData()->Value(num)->ChangeVertex (isfirst,2); + if(cp1.IsOnArc()){ + if (cp1.Arc().IsSame(Eadj1)||cp1.Arc().IsSame(Eadj2)) + compoint=Standard_True; + } + if(cp2.IsOnArc()){ + if (cp2.Arc().IsSame(Eadj1)||cp2.Arc().IsSame(Eadj2)) + compoint=Standard_True; + } +} + +//======================================================================= +//function : RemoveSurfData +//purpose : for each stripe removal of unused surfdatas +//======================================================================= + +static void RemoveSurfData (const ChFiDS_StripeMap & myVDataMap, + const ChFiDS_Map & myEFMap, + const TopoDS_Edge &edgecouture, + const TopoDS_Face & facecouture, + const TopoDS_Vertex &V1) +{ ChFiDS_ListIteratorOfListOfStripe It; + Standard_Boolean isfirst; + TopoDS_Edge Ecur,Eadj1,Eadj2; + TopoDS_Face Fg,Fd,F1,F2; + TopoDS_Vertex Vbid; + Standard_Integer nbsurf,nbedge,sense,num; + for (It.Initialize(myVDataMap(V1));It.More();It.Next()) { + nbsurf= It.Value()->SetOfSurfData()->Length(); + nbedge = It.Value()->Spine()->NbEdges(); + if (nbsurf!=1){ + num=ChFi3d_IndexOfSurfData(V1,It.Value(),sense); + if (sense==1) + Ecur = It.Value()->Spine()->Edges(1); + else + Ecur = It.Value()->Spine()->Edges(nbedge); + ChFi3d_edge_common_faces(myEFMap(Ecur),F1,F2); + if (F1.IsSame(facecouture)) Eadj1=edgecouture; + else ChFi3d_cherche_element(V1,Ecur,F1,Eadj1,Vbid); + ChFi3d_edge_common_faces(myEFMap(Eadj1),Fg,Fd); + if (F2.IsSame(facecouture)) Eadj2=edgecouture; + else ChFi3d_cherche_element(V1,Ecur,F2,Eadj2,Vbid); + ChFi3d_edge_common_faces(myEFMap(Eadj2),Fg,Fd); + Standard_Boolean compoint=Standard_False; + isfirst=(sense==1); + Standard_Integer ind; + if (sense==1) { + ind=0; + // among surfdatas find the greatest indice ind so that + // surfdata could have one of commonpoint on Eadj1 and Eadj2 + // remove surfdata from 1 to ind-1 + for (Standard_Integer i=1;i<=nbsurf;i++) { + CpOnEdge (It.Value(),i,isfirst,Eadj1,Eadj2,compoint); + if (compoint) ind=i; + } + if (ind>=2) RemoveSD(It.Value(),1,ind-1); + } + else { + ind=num; + // among surfdatas find the smallest indice ind so that + // surfdata could have one of commonpoint on Eadj1 and Eadj2 + // remove surfdata from ind+1 to num + for (Standard_Integer i=num;i>=1;i--) { + CpOnEdge (It.Value(),i,isfirst,Eadj1,Eadj2,compoint); + if (compoint) ind=i; + } + if (ind<num) RemoveSD(It.Value(),ind+1,num); + } + } + } +} + +//======================================================================= +//function : ParametrePlate +//purpose : +//======================================================================= + +static void ParametrePlate(const Standard_Integer n3d, + const GeomPlate_BuildPlateSurface & PSurf, + const Handle(Geom_Surface) & Surf, + const gp_Pnt & point, + const Standard_Real apperror, + gp_Pnt2d & uv) +{ Standard_Integer ip; + gp_Pnt P1; + Standard_Real par; + Standard_Boolean trouve=Standard_False; + for (ip=1;ip<=n3d && !trouve;ip++){ + par=PSurf.Curves2d()->Value(ip)->FirstParameter(); + PSurf.Curves2d()->Value(ip)->D0(par,uv); + Surf->D0(uv.X(),uv.Y(),P1); + trouve=P1.IsEqual(point,apperror); + if (!trouve) { + par=PSurf.Curves2d()->Value(ip)->LastParameter(); + PSurf.Curves2d()->Value(ip)->D0(par,uv); + Surf->D0(uv.X(),uv.Y(),P1); + trouve=P1.IsEqual(point,apperror); + } + } +} + +//======================================================================= +//function : SummarizeNormal +//purpose : +//======================================================================= + +static void SummarizeNormal(const TopoDS_Vertex& V1, + const TopoDS_Face& Fcur, + const TopoDS_Edge& Ecur, + gp_Vec& SumFaceNormalAtV1) +{ + gp_Pnt2d uv1, uv2; + BRep_Tool::UVPoints(Ecur,Fcur,uv1,uv2); + if ( ! V1.IsSame(TopExp::FirstVertex(Ecur))) uv1 = uv2; + + gp_Pnt P; + gp_Vec d1U, d1V; + BRep_Tool::Surface(Fcur)->D1( uv1.X(), uv1.Y(), P, d1U, d1V); + gp_Vec N = d1U.Crossed(d1V); + if (Fcur.Orientation() == TopAbs_REVERSED) N.Reverse(); + + if (N.SquareMagnitude() <= Precision::PConfusion()) return; + + SumFaceNormalAtV1 += N.Normalized(); + SumFaceNormalAtV1.Normalize(); +} + +enum ChFi3d_SurfType { ChFiSURFACE, FACE1, FACE2 }; // for call SurfIndex(...) + +//======================================================================= +//function : SurfIndex +//purpose : +//======================================================================= + +static Standard_Integer SurfIndex(const ChFiDS_StripeArray1& StripeArray1, + const Standard_Integer StripeIndex, + const Standard_Integer SurfDataIndex, + const ChFi3d_SurfType SurfType) +{ + const Handle(ChFiDS_SurfData)& aSurfData = + StripeArray1(StripeIndex)->SetOfSurfData()->Value(SurfDataIndex); + switch (SurfType) { + case ChFiSURFACE: return aSurfData->Surf(); + case FACE1: return aSurfData->IndexOfS1(); + case FACE2: return aSurfData->IndexOfS2(); + default: return -1; + } + return -1; +} + +//======================================================================= +//function : PlateOrientation +//purpose : Define Plate orientation compared to <theRefDir> previewing +// that Plate surface can have a sharp angle with adjacent +// filet (bug occ266: 2 chamfs, OnSame and OnDiff) and +// can be even twisted (grid tests cfi900 B1) +//======================================================================= + +static TopAbs_Orientation PlateOrientation(const Handle(Geom_Surface)& thePlateSurf, + const Handle(TColGeom2d_HArray1OfCurve)& thePCArr, + const gp_Vec& theRefDir) +{ + gp_Vec du,dv; + gp_Pnt pp1,pp2,pp3; + gp_Pnt2d uv; + Standard_Real fpar, lpar; + Standard_Real SumScal1 = 0, SumScal2 = 0; + + Standard_Integer i, nb = thePCArr->Upper(); + Handle(Geom2d_Curve) aPC = thePCArr->Value(nb); + fpar = aPC->FirstParameter(); + lpar = aPC->LastParameter(); + aPC->D0( (fpar + lpar) / 2., uv); + thePlateSurf-> D0(uv.X(),uv.Y(),pp1); + aPC->D0( lpar ,uv); + thePlateSurf-> D0(uv.X(),uv.Y(),pp2); + + for (i=1; i<=nb; i++) { + aPC = thePCArr->Value(i); + fpar = aPC->FirstParameter(); + lpar = aPC->LastParameter(); + aPC->D0( fpar ,uv); + thePlateSurf -> D1(uv.X(),uv.Y(),pp2,du,dv); + gp_Vec n1 = du^dv; + n1.Normalize(); + + aPC->D0( (fpar + lpar) / 2., uv); + thePlateSurf-> D0(uv.X(),uv.Y(),pp3); + + gp_Vec vv1(pp2,pp1), vv2(pp2,pp3); + gp_Vec n2 = vv2^vv1; + n2.Normalize(); + + SumScal1 += n1*n2; + SumScal2 += n2*theRefDir; + + pp1 = pp3; + } + if (SumScal2*SumScal1>0) return TopAbs_FORWARD; + else return TopAbs_REVERSED; +} + +//======================================================================= +//function : PerformMoreThreeCorner +//purpose : Process case of a top with n edges. +//======================================================================= + +void ChFi3d_Builder::PerformMoreThreeCorner(const Standard_Integer Jndex, + const Standard_Integer nconges) +{ +// ======================================== +// Initialisations +// ======================================== +#ifdef DEB + OSD_Chronometer ch; +#endif + TopOpeBRepDS_DataStructure& DStr=myDS->ChangeDS(); + const TopoDS_Vertex& V1 = myVDataMap.FindKey(Jndex); + Standard_Integer nedge; + Standard_Boolean bordlibre; + TopoDS_Edge edgelibre1,edgelibre2; +// TopTools_ListIteratorOfListOfShape ItE; + nedge=ChFi3d_NbNotDegeneratedEdges(V1,myVEMap); + ChFi3d_ChercheBordsLibres(myVEMap,V1,bordlibre,edgelibre1,edgelibre2); + Standard_Boolean droit=Standard_False; + if (bordlibre) {nedge=(nedge-2)/2 +2; + Standard_Real angedg=Abs(ChFi3d_AngleEdge(V1,edgelibre1,edgelibre2)); + droit=Abs(angedg-PI)<0.01; + } + else nedge=nedge/2; + Standard_Integer size=nedge*2; + ChFiDS_StripeArray1 CD(0,size); + TColStd_Array1OfInteger jf(0,size); + TColStd_Array1OfInteger Index(0,size); + TColStd_Array1OfInteger Indice(0,size); + TColStd_Array1OfInteger sens(0,size); + TColStd_Array1OfInteger indcurve3d(0,size); + TColStd_Array2OfInteger numfa( 0,size,0,size); + TColStd_Array1OfInteger Order( 0,size); + TColStd_Array2OfInteger i(0,size,0,size); + TColStd_Array2OfInteger indpoint(0,size,0,1); + TColStd_Array1OfBoolean oksea(0,size); + TColStd_Array1OfBoolean sharp(0,size); + TColStd_Array1OfBoolean regul(0,size); + TColStd_Array2OfReal p (0,size,0,size); + TColStd_Array1OfReal errapp (0,size); + TopTools_Array1OfShape Evive(0,size); + TopTools_Array2OfShape Fvive(0,size,0,size); + TColStd_Array1OfBoolean ponctuel (0,size); + TColStd_Array1OfBoolean samedge (0,size); + TColStd_Array1OfBoolean moresurf (0,size); + TColStd_Array1OfBoolean libre(0,size); + TColStd_Array1OfBoolean tangentregul (0,size); + TColStd_Array1OfBoolean isG1(0,size); +// for(Standard_Integer ind=0;ind<=size;ind++){ + Standard_Integer ind; + for(ind=0;ind<=size;ind++){ + indpoint.SetValue(ind,0,0); + indpoint.SetValue(ind,1,0); + Indice.SetValue(ind,0); + oksea.SetValue(ind,Standard_False); + sharp.SetValue(ind,Standard_False); + regul.SetValue(ind,Standard_False); + ponctuel.SetValue(ind,Standard_False); + samedge.SetValue(ind,Standard_False); + moresurf.SetValue(ind,Standard_False); + libre.SetValue(ind,Standard_False); + tangentregul.SetValue(ind,Standard_False); + isG1.SetValue(ind,Standard_False); + } + ChFiDS_ListIteratorOfListOfStripe It; + Handle(ChFiDS_Stripe) cd2,cdbid,cnext; + TopoDS_Face face; + Standard_Integer jfp,ii; + Standard_Integer ic,icplus,icmoins,icplus2, + sense,index,indice,isurf1,isurf2; + Standard_Integer cbplus=0, n3d=0,IVtx,nb; + Standard_Boolean sameside,trouve,isfirst; + Standard_Real pardeb ,parfin,xdir,ydir; + Standard_Real tolapp=1.e-4,maxapp,maxapp1,avedev; + Handle (TopOpeBRepDS_CurvePointInterference) Interfp1, Interfp2; + Handle (TopOpeBRepDS_SurfaceCurveInterference) Interfc; + Handle(Geom_Curve) Curv3d; + ChFiDS_Regul regular; + TopTools_SequenceOfShape Fproj; + Standard_Integer num; + TopoDS_Edge Ecur; + TopTools_ListIteratorOfListOfShape ItF; +#ifdef DEB +// Standard_Integer nface=ChFi3d_nbface(myVFMap(V1)); +#endif + TopoDS_Face F1,F2; + gp_Vec SumFaceNormalAtV1(0,0,0); // is used to define Plate orientation + + // it is determined if there is a sewing edge + Standard_Boolean couture=Standard_False; + TopoDS_Face facecouture; + TopoDS_Edge edgecouture; + for(ItF.Initialize(myVFMap(V1));ItF.More()&&!couture;ItF.Next()) { + TopoDS_Face fcur = TopoDS::Face(ItF.Value()); + ChFi3d_CoutureOnVertex(fcur,V1,couture,edgecouture); + if (couture) + facecouture=fcur; + } + +// unused surfdata are removed + RemoveSurfData (myVDataMap, myEFMap,edgecouture,facecouture,V1); + + // parse edges and faces + trouve=Standard_False; + TopoDS_Edge Enext; + TopoDS_Vertex VV; + TopoDS_Face Fcur,Fnext; + for (It.Initialize(myVDataMap(Jndex));It.More()&&!trouve;It.Next()) { + cnext=It.Value(); + CD.SetValue(0,cnext); + Index.SetValue(0,ChFi3d_IndexOfSurfData(V1,cnext,sense)); + sens.SetValue(0,sense); + numfa.SetValue(0 ,1,SurfIndex(CD, 0, Index.Value(0), FACE2)); + numfa.SetValue(1 ,0, numfa.Value(0 ,1)); + Fcur=TopoDS::Face(DStr.Shape(numfa.Value(0,1))); + Fvive.SetValue(0,1,Fcur); + Fvive.SetValue(1,0,Fcur); + jf.SetValue(0,2); + if (sens.Value(0)==1) + Ecur = CD.Value(0)->Spine()->Edges(1); + else + Ecur = CD.Value(0)->Spine()->Edges(CD.Value(0)->Spine()->NbEdges()); + Evive.SetValue(0,Ecur); + ChFi3d_cherche_edge(V1,Evive,Fcur,Enext,VV); + trouve= !Enext.IsNull(); + } + // find sum of all face normals at V1 + SummarizeNormal(V1, Fcur, Ecur, SumFaceNormalAtV1); + + Standard_Integer nbcouture=0; + for ( ii=1; ii<nedge; ii++) { + if (Fcur.IsSame(facecouture)&& nbcouture==0) { + Enext=edgecouture; + nbcouture++; + } + else ChFi3d_cherche_edge(V1,Evive,Fcur,Enext,VV); + if (Enext.IsNull())Standard_Failure::Raise + ("PerformMoreThreeCorner: pb in the parsing of edges and faces"); + if (Enext.IsSame(edgelibre1)|| Enext.IsSame(edgelibre2)) { + CD.SetValue(ii, cdbid); + Index.SetValue(ii, 0); + sens.SetValue(ii, -1); + TopoDS_Vertex Vref; + Vref = TopExp::FirstVertex(Enext); + if (Vref.IsSame(V1)) sens.SetValue(ii, 1); + sharp.SetValue(ii, Standard_True); + Evive.SetValue(ii, Enext); + jf.SetValue(ii, 0); + Indices(nedge,ii,icplus,icmoins); + Fvive.SetValue(ii,icplus, Fcur); + Fvive.SetValue(icplus,ii, Fcur); + numfa.SetValue(ii,icplus, DStr.AddShape(Fcur)); + numfa.SetValue(icplus,ii,numfa.Value(ii,icplus)); + ii++; + if (Enext.IsSame (edgelibre1)) Ecur=edgelibre2; + else Ecur=edgelibre1; + ChFi3d_edge_common_faces(myEFMap(Ecur),Fcur,Fcur); + Indices(nedge,ii,icplus,icmoins); + Fvive.SetValue(ii,icplus, Fcur); + Fvive.SetValue(icplus,ii, Fcur); + numfa.SetValue(ii,icplus, DStr.AddShape(Fcur)); + numfa.SetValue(icplus,ii,numfa.Value(ii,icplus)); + CD.SetValue(ii, cdbid); + Index.SetValue(ii, 0); + sens.SetValue(ii, -1); + Vref = TopExp::FirstVertex(Ecur); + if (Vref.IsSame(V1)) sens.SetValue(ii, 1); + sharp.SetValue(ii, Standard_True); + Evive.SetValue(ii, Ecur); + jf.SetValue(ii, 0); + } + else { +// it is found if Enext is in the map of stripes + TopoDS_Edge EE; + /*Standard_Boolean */trouve = Standard_False; + for (It.Initialize(myVDataMap(Jndex));It.More()&&!trouve;It.Next()) { + index = ChFi3d_IndexOfSurfData(V1,It.Value(),sense); + if (sense==1) + EE = It.Value()->Spine()->Edges(1); + else + EE = It.Value()->Spine()->Edges(It.Value()->Spine()->NbEdges()); + if (Enext.IsSame(EE)) { + cnext=It.Value(); + trouve=Standard_True; + } + } + if (trouve) { + CD.SetValue(ii, cnext); + Index.SetValue(ii, index); + sens.SetValue(ii, sense); + sharp.SetValue(ii, Standard_False); + Evive.SetValue(ii, Enext); + } + else { + // edge ii is alive + CD.SetValue(ii, cdbid); + Index.SetValue(ii, 0); + sens.SetValue(ii, -1); + TopoDS_Vertex Vref; + Vref = TopExp::FirstVertex(Enext); + if (Vref.IsSame(V1)) sens.SetValue(ii, 1); + sharp.SetValue(ii, Standard_True); + Evive.SetValue(ii, Enext); + jf.SetValue(ii, 0); + } + // Face Fnext!=Fcur containing Enext + Fnext=Fcur; + ChFi3d_cherche_face1(myEFMap(Enext),Fcur,Fnext); + Indices(nedge,ii,icplus,icmoins); + Fvive.SetValue(ii,icplus, Fnext); + Fvive.SetValue(icplus,ii, Fnext); + numfa.SetValue(ii,icplus, DStr.AddShape(Fnext)); + numfa.SetValue(icplus,ii,numfa.Value(ii,icplus)); + Standard_Integer numface1,numface2; + if (trouve) { + // it is checked if numfa corresponds to IndexOfS1 or IndexOfS2 + // jf is updated is consequently updated + // if it is not the case among the previous faces are found + // those which correspond to IndexOfs1 IndexOfS2 and + // numfa and Fvive are reupdated (cts16288) + numface2 = SurfIndex(CD, ii, Index.Value(ii), FACE2); + if (numface2==numfa.Value(ii,icplus)) + jf.SetValue(ii, 2); + else { + numface1 = SurfIndex(CD, ii, Index.Value(ii), FACE1); + if (numface1==numfa.Value(ii,icplus)) + jf.SetValue(ii, 1); + else { + if (numface1==numfa.Value(icmoins,ii)) { + jf.SetValue(ii, 2); + Fvive.SetValue(ii,icplus,TopoDS::Face(DStr.Shape(numface2))); + Fvive.SetValue(icplus,ii,TopoDS::Face(DStr.Shape(numface2))); + numfa.SetValue(ii,icplus, DStr.AddShape(TopoDS::Face(DStr.Shape(numface2)))); + numfa.SetValue(icplus,ii, numfa.Value (ii,icplus)); + } + if (numface2==numfa.Value(icmoins,ii)) { + jf.SetValue(ii, 1); + Fvive.SetValue(ii,icplus,TopoDS::Face(DStr.Shape(numface1))); + Fvive.SetValue(icplus,ii,TopoDS::Face(DStr.Shape(numface1))); + numfa.SetValue(ii,icplus, DStr.AddShape(TopoDS::Face(DStr.Shape(numface1)))); + numfa.SetValue(icplus,ii, numfa.Value (ii,icplus)); + } + } + } + } + Ecur = Enext; + Fcur = Fnext; + // find sum of all face normales at V1 + SummarizeNormal(V1, Fcur, Ecur, SumFaceNormalAtV1); + } + } + // mise a jour du tableau regul + for (ic=0;ic<nedge;ic++) { + if (sharp.Value(ic)) { + Ecur=TopoDS::Edge(Evive.Value(ic)); + if (!Ecur.IsSame(edgecouture)) { + ChFi3d_edge_common_faces(myEFMap(Ecur),F1,F2); +// Modified by Sergey KHROMOV - Fri Dec 21 18:11:02 2001 Begin +// regul.SetValue(ic,BRep_Tool::Continuity(TopoDS::Edge(Evive.Value(ic)),F1,F2) +// !=GeomAbs_C0); + regul.SetValue(ic,isTangentFaces(TopoDS::Edge(Evive.Value(ic)),F1,F2)); +// Modified by Sergey KHROMOV - Fri Dec 21 18:11:07 2001 End + } + } + } + // it is checked if a regular edge is not tangent to another edge + // in case if it is not considered regular (cts60072) + for (ic=0;ic<nedge;ic++) { + if (regul.Value(ic) ) { + trouve=Standard_False; + TopoDS_Edge ereg=TopoDS::Edge(Evive.Value(ic)); + for( ind=0;ind<nedge &&!trouve;ind++) { + if (ind!=ic) { + TopoDS_Edge ecur=TopoDS::Edge(Evive.Value(ind)); + Standard_Real ang=Abs(ChFi3d_AngleEdge(V1,ecur,ereg)); + if (ang<0.01 || Abs(ang-PI) <0.01) { + regul.SetValue(ic,Standard_False); + tangentregul.SetValue(ic,Standard_True); + trouve=Standard_True; + } + } + } + } + } + + // variable deuxconges allows detecting cases when there is a top with + // n edges and two fillets on two tangent edges that are not free borders + // the connecting curves start from the fillet and end on top + + Standard_Boolean deuxconges,deuxcgnontg; + deuxconges=Standard_False; + trouve=Standard_False; + if (nconges==2) { + TopoDS_Edge E1,E2; + for (ic=0;ic<nedge&&!trouve;ic++) { + Indices(nedge,ic,icplus,icmoins); + if (!sharp.Value(ic) && !sharp.Value(icplus)){ + E1=TopoDS::Edge(Evive.Value(ic)); + E2=TopoDS::Edge(Evive.Value(icplus)); + deuxconges=(Abs(ChFi3d_AngleEdge(V1 ,E1,E2) )<0.01) ; + trouve=deuxconges; + } + } + } + + // variable deuxconges is used in the special case when there are + // two fillets and if two other living edges are tangent (cts60072) + if (nconges==2 && nedge==4) { + TopoDS_Edge E1,E2; + for (ic=0;ic<nedge&&!deuxconges;ic++) { + Indices(nedge,ic,icplus,icmoins); + if (sharp.Value(ic) && sharp.Value(icplus)){ + E1=TopoDS::Edge(Evive.Value(ic)); + E2=TopoDS::Edge(Evive.Value(icplus)); + if ( !E1.IsSame(edgelibre1) && !E1.IsSame(edgelibre2) && + !E2.IsSame(edgelibre1) && !E2.IsSame(edgelibre2)){ + Standard_Real ang=Abs(ChFi3d_AngleEdge(V1 ,E1,E2)); + deuxconges=(ang<0.01 || Abs(ang-PI)<0.01); + } + } + } + } + + deuxcgnontg=nconges==2&& nedge==3 && !deuxconges; // pro12305 + + if (deuxconges ) + for (ic=0;ic<nedge;ic++){ + regul.SetValue(ic,Standard_False); + } + + // Detect case of 3 edges & 2 conges: OnSame + OnDiff + // (eap, Arp 9 2002, occ266) + Standard_Boolean isOnSameDiff = Standard_False; + if (deuxcgnontg) { + Standard_Boolean isOnSame = Standard_False, isOnDiff = Standard_False; + for (ic=0; ic<nedge; ic++) { + if (sharp.Value(ic)) continue; + ChFiDS_State stat; + if ( sens(ic) == 1 ) + stat = CD.Value(ic)->Spine()->FirstStatus(); + else + stat = CD.Value(ic)->Spine()->LastStatus(); + + if (stat == ChFiDS_OnSame) isOnSame = Standard_True; + else if (stat == ChFiDS_OnDiff) isOnDiff = Standard_True; + } + isOnSameDiff = isOnSame && isOnDiff; + } + if ( isOnSameDiff ) { +#ifdef DEB + cout << "OnSame + OnDiff, PerformMoreThreeCorner() calls PerformOneCorner()" << endl; +#endif + PerformOneCorner (Jndex, Standard_True); + } + +// if the commonpoint is on an edge that does not have a +// vertex at the extremity, Evive is found anew +// Fvive is found anew if it does not correspond +// to two faces adjacent to Evive (cts16288) + + if (!deuxconges && !isOnSameDiff) + for (ic=0;ic<nedge;ic++) { + if (sharp.Value(ic)) { + Indices(nedge,ic,icplus,icmoins); + TopoDS_Edge Arc=TopoDS::Edge(Evive.Value(ic)); + ChFiDS_CommonPoint cp1, cp2; + Standard_Real angedg=PI; + TopoDS_Vertex Vcom; + if (!sharp.Value(icplus)) { + isfirst=(sens.Value(icplus)==1); + jfp = 3 - jf.Value(icplus); + cp1 = CD.Value(icplus)->SetOfSurfData()->Value(Index.Value(icplus))-> + ChangeVertex (isfirst,jfp); + if (cp1.IsOnArc()){ + ChFi3d_cherche_vertex(Arc,cp1.Arc(),Vcom,trouve); + if (trouve) angedg=Abs(ChFi3d_AngleEdge(Vcom,Arc,cp1.Arc())); + if (!cp1.Arc().IsSame(Arc) && Abs(angedg-PI)<0.01){ + Evive.SetValue(ic,cp1.Arc()); + ChFi3d_edge_common_faces(myEFMap(cp1.Arc()),F1,F2); + if (!Fvive.Value(ic,icplus).IsSame(F1) && !Fvive.Value(ic,icplus).IsSame(F2)) { + if (Fvive.Value(ic,icmoins).IsSame(F2)) { + Fvive.SetValue(ic,icplus,F1); + Fvive.SetValue(icplus,ic,F1); + numfa.SetValue(ic,icplus,DStr.AddShape(F1)); + numfa.SetValue(icplus,ic,DStr.AddShape(F1)); + } + else { + Fvive.SetValue(ic,icplus,F2); + Fvive.SetValue(icplus,ic,F2); + numfa.SetValue(ic,icplus,DStr.AddShape(F2)); + numfa.SetValue(icplus,ic,DStr.AddShape(F2)); + } + } + samedge.SetValue(ic,Standard_True); + p.SetValue(ic,icplus,cp1.ParameterOnArc()); + p.SetValue(ic,icmoins,cp1.ParameterOnArc()); + i.SetValue(ic,icplus,1); + } + } + } + if (!sharp.Value(icmoins)) { + isfirst=(sens.Value(icmoins)==1); + cp2 = CD.Value(icmoins)->SetOfSurfData()->Value(Index.Value(icmoins))-> + ChangeVertex (isfirst,jf.Value(icmoins)); + if (cp2.IsOnArc()) { + angedg=PI; + ChFi3d_cherche_vertex(Arc,cp2.Arc(),Vcom,trouve); + if (trouve) angedg=Abs(ChFi3d_AngleEdge(Vcom,Arc,cp2.Arc())); + if (!cp2.Arc().IsSame(Arc)&&Abs(angedg-PI)<0.01) { + Evive.SetValue(ic,cp2.Arc()); + ChFi3d_edge_common_faces(myEFMap(cp2.Arc()),F1,F2); + if (!Fvive.Value(ic,icmoins).IsSame(F1) && !Fvive.Value(ic,icmoins).IsSame(F2)) { + if (Fvive.Value(ic,icplus).IsSame(F2)) { + Fvive.SetValue(ic,icmoins,F1); + numfa.SetValue(ic,icmoins,DStr.AddShape(F1)); + Fvive.SetValue(icmoins,ic,F1); + numfa.SetValue(icmoins,ic,DStr.AddShape(F1)); + } + else { + Fvive.SetValue(ic,icmoins,F2); + numfa.SetValue(ic,icmoins,DStr.AddShape(F2)); + Fvive.SetValue(icmoins,ic,F2); + numfa.SetValue(icmoins,ic,DStr.AddShape(F2)); + } + } + samedge.SetValue(ic,Standard_True); + p.SetValue(ic,icmoins,cp2.ParameterOnArc()); + p.SetValue(ic,icplus,cp2.ParameterOnArc()); + i.SetValue(ic,icmoins,1); + } + } + } + } + } + +// the first free edge is restored if it exists + trouve=Standard_False; + for (ic=0; ic<nedge&&!trouve;ic++) { + TopoDS_Edge ecom; + ecom=TopoDS::Edge(Evive.Value(ic)); + if (ecom.IsSame(edgelibre1)||ecom.IsSame(edgelibre2)){ + libre.SetValue(ic,Standard_True); + trouve=Standard_True; + } + } + +// determine the minimum recoil distance that can't be exceeded + Standard_Boolean distmini=Standard_False; + gp_Pnt som=BRep_Tool::Pnt(V1),pic; + gp_Pnt2d p2; + TopoDS_Edge edgemin; + TopoDS_Vertex V,V2; + Standard_Real dst,distmin; + distmin=1.e30; + for (ic=0;ic<nedge;ic++) { + if (sharp.Value(ic)) + edgemin=TopoDS::Edge(Evive.Value(ic)); + else { + if (sens.Value(ic)==1) + edgemin= CD.Value(ic)->Spine()->Edges(1); + else + edgemin = CD.Value(ic)->Spine()->Edges(CD.Value(ic)->Spine()->NbEdges()); + } + V=TopExp::FirstVertex(edgemin); + V2=TopExp::LastVertex(edgemin); + dst=(BRep_Tool::Pnt(V)).Distance(BRep_Tool::Pnt(V2))/1.5; + if (dst<distmin) distmin=dst; + } + +// calculate intersections between stripes and determine the parameters on each pcurve + Standard_Boolean inters=Standard_True; + for (ic=0;ic<nedge;ic++) { + Indices(nedge,ic,icplus,icmoins); + if (sharp.Value(ic)||sharp.Value(icplus)) { + oksea.SetValue(ic, Standard_False); + } + else { + Standard_Integer jf1; + Standard_Integer i1,i2; + Standard_Real pa1,pa2; + Standard_Boolean ok; + Handle(ChFiDS_Stripe) strip; + Standard_Real angedg; + Standard_Integer iface; + // if two edges are tangent the intersection is not attempted (cts60046) + angedg=Abs(ChFi3d_AngleEdge(V1,TopoDS::Edge(Evive.Value(ic)),TopoDS::Edge(Evive.Value(icplus)))); + if (Abs(angedg-PI)>0.01) + ok = ChFi3d_SearchFD(DStr,CD.Value(ic),CD.Value(icplus),sens.Value(ic),sens.Value(icplus), + i1,i2,pa1,pa2, + Index.Value(ic),Index.Value(icplus), + face,sameside,jf1,jfp); + else ok=Standard_False; + // if there is an intersection it is checked if surfdata with the intersection + // corresponds to the first or the last + // if this is not the case, the surfdata are removed from SD + + if (ok) { + if (i1!=Index.Value(ic) ){ + Standard_Integer ideb,ifin; + strip=CD.Value(ic); + if (sens.Value(ic)==1) { + ideb=Index.Value(ic); + ifin=i1-1; + } + else { + ifin=Index.Value(ic); + ideb=i1+1; + } + if (i1<Index.Value(ic)) { + for (nb=Index.Value(ic);nb>=i1;nb--) { + if ((3-jf1)==1) + iface=SurfIndex(CD, ic, nb , FACE1); + else iface=SurfIndex(CD, ic, nb , FACE2); + Fproj.Append(TopoDS::Face(myDS->Shape(iface))); + } + } + if (i1>Index.Value(ic)) { + for (nb=Index.Value(ic);nb<=i1;nb++) { + if ((3-jf1)==1) + iface=SurfIndex(CD, ic, nb , FACE1); + else iface=SurfIndex(CD, ic, nb , FACE2); + Fproj.Append(TopoDS::Face(myDS->Shape(iface))); + } + } + strip=CD.Value(ic); + RemoveSD(strip,ideb,ifin); + num=ChFi3d_IndexOfSurfData(V1,CD.Value(ic),sense); + Index.SetValue(ic,num); + i1=num; + } + if (i2!=Index.Value(icplus) ){ + Standard_Integer ideb,ifin; + strip=CD.Value(icplus); + if (sens.Value(icplus)==1) { + ideb=Index.Value(icplus); + ifin=i2-1; + } + else { + ifin=Index.Value(icplus); + ideb=i2+1; + } + + if (i2<Index.Value(icplus)) { + for (nb=i2;nb<=Index.Value(icplus);nb++) { + if ((3-jfp)==1) + iface=SurfIndex(CD, icplus, nb , FACE1); + else iface=SurfIndex(CD, icplus, nb , FACE2); + Fproj.Append(TopoDS::Face(myDS->Shape(iface))); + } + } + if (i2>Index.Value(icplus)) { + for (nb=i2;nb>=Index.Value(icplus);nb--) { + if ((3-jfp)==1) + iface=SurfIndex(CD, icplus, nb , FACE1); + else iface=SurfIndex(CD, icplus, nb , FACE2); + Fproj.Append(TopoDS::Face(myDS->Shape(iface))); + } + } + RemoveSD(strip,ideb,ifin); + num=ChFi3d_IndexOfSurfData(V1,CD.Value(icplus),sense); + Index.SetValue(icplus,num); + i2=num; + } + Calcul_P2dOnSurf(CD.Value(ic),jf1,i1,pa1,p2); + indice=SurfIndex(CD, ic, i1, ChFiSURFACE); + DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),pic); + if (pic.Distance(som)>distmin) distmini =Standard_True; + jf.SetValue(ic,jf1); + i.SetValue(ic,icplus,i1); + i.SetValue(icplus,ic,i2); + p.SetValue(ic,icplus,pa1); + p.SetValue(icplus,ic,pa2); + } + oksea.SetValue(ic, ok); + } + if (!oksea.Value(ic) ) inters=Standard_False; + } + + // case if there are only intersections + // the parametres on Pcurves are the extremities of the stripe + Standard_Real para; + if (!inters) { + for (ic=0;ic<nedge;ic++) { + Indices(nedge,ic,icplus,icmoins); + Indices(nedge,icplus,icplus2,ic); + if (!oksea.Value(ic)) { + cbplus++; + if (sharp.Value(ic)) { + if (!samedge.Value(ic)){ + para=BRep_Tool::Parameter(V1,TopoDS::Edge(Evive.Value(ic))); + p.SetValue(ic,icplus,para); + i.SetValue(ic,icplus,1); + } + } + else { + isfirst= (sens.Value(ic)==1); + i.SetValue(ic,icplus,ChFi3d_IndexOfSurfData(V1,CD.Value(ic),sense)); + if (oksea.Value(icmoins)) { + para=p.Value(ic,icmoins); + p.SetValue(ic,icplus,para); + } + else { + Calcul_Param(CD.Value(ic),jf.Value(ic),i.Value(ic,icplus),isfirst,para); + p.SetValue(ic,icplus,para); + } + } + if (sharp.Value(icplus)) { + if (!samedge.Value(icplus)) { + para=BRep_Tool::Parameter(V1,TopoDS::Edge(Evive.Value(icplus))); + p.SetValue(icplus,ic, para); + i.SetValue(icplus,ic,1); + } + } + else { + isfirst= (sens.Value(icplus)==1); + i.SetValue(icplus,ic,ChFi3d_IndexOfSurfData(V1,CD.Value(icplus),sense)); + if (oksea.Value(icplus)){ + para=p.Value(icplus,icplus2); + p.SetValue(icplus,ic,para); + } + else { + jfp = 3 - jf.Value(icplus); + Calcul_Param(CD.Value(icplus),jfp,i.Value(icplus,ic),isfirst,para); + p.SetValue(icplus,ic,para); + } + } + } + } + +// calculate max distance to the top at each point + TColStd_Array1OfReal dist1(0,size); + TColStd_Array1OfReal dist2(0,size); + Standard_Real distance=0.; + gp_Pnt sommet=BRep_Tool::Pnt(V1); + if (!deuxconges) + for (ic=0;ic<nedge;ic++) { + Indices(nedge,ic,icplus,icmoins); + if (sharp.Value(ic)) { + dist1.SetValue(ic, 0); + dist2.SetValue(ic, 0); + } + else { + jfp = 3 - jf.Value(ic); + Calcul_P2dOnSurf(CD.Value(ic),jfp,i.Value(ic,icmoins),p.Value(ic,icmoins),p2); + indice=SurfIndex(CD, ic, i.Value(ic,icmoins), ChFiSURFACE); + DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),pic); + dist1.SetValue(ic, sommet.Distance(pic)); + if (dist1.Value(ic) > distance ) distance= dist1.Value(ic); + + Calcul_P2dOnSurf(CD.Value(ic),jf.Value(ic),i.Value(ic,icplus),p.Value(ic,icplus),p2); + indice=SurfIndex(CD, ic, i.Value(ic,icplus), ChFiSURFACE); + DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),pic); + dist2.SetValue(ic, sommet.Distance(pic)); + if( dist2.Value(ic) > distance ) + distance= dist2.Value(ic); + } + } + +// offset of parameters and removal of intersection points +// too close to the top + + Standard_Real ec, dist; + if (!deuxconges && !deuxcgnontg) + for (ic=0;ic<nedge;ic++) { + Indices(nedge,ic,icplus,icmoins); + if (sharp.Value(ic) ) { + BRepAdaptor_Curve C(TopoDS::Edge(Evive.Value(ic))); + // to pass from 3D distance to a parametric distance + if (!tangentregul(ic)) + ec = distance*100*C.Resolution(0.01); + else ec=0.0; + if (TopExp::FirstVertex(TopoDS::Edge(Evive.Value(ic))).IsSame(V1)) { + para=p.Value(ic,icmoins) + ec; + p.SetValue(ic,icmoins, para); + } + else { + para=p.Value(ic,icmoins) - ec; + p.SetValue(ic,icmoins,para); + } +// it is necessary to be on to remain on the edge + p.SetValue(ic,icplus, p.Value(ic,icmoins)); + } + else if (!distmini) { + dist = dist1.Value(ic); + if ((!oksea.Value(icmoins))||(oksea.Value(icmoins)&&(distance>1.3*dist))) { + ec= distance-dist; + if (oksea.Value(icmoins)) { + oksea.SetValue(icmoins,Standard_False); + inters=Standard_False; + cbplus++; + } + if (sens.Value(ic)==1) { + para=p.Value(ic,icmoins) + ec; + p.SetValue(ic,icmoins, para); + } + else{ + para=p.Value(ic,icmoins) - ec; + p.SetValue(ic,icmoins,para); + } + } + dist = dist2.Value(ic); + if ((!oksea.Value(ic))||(oksea.Value(ic)&&(distance>1.3*dist))) { + if(oksea.Value(ic)) { + oksea.SetValue(ic,Standard_False); + inters=Standard_False; + cbplus++; + } + if (nconges!=1) { + Standard_Real parold,parnew; + parold=p.Value(ic,icplus); + parnew=p.Value(ic,icmoins); + if (sens.Value(ic)==1) { + if (parnew> parold) p.SetValue(ic,icplus, p.Value(ic,icmoins)); + } + else { + if (parnew<parold) p.SetValue(ic,icplus, p.Value(ic,icmoins)); + } + } + } + } + } + } + +// it is attempted to limit the edge by a commonpoint +// + + Standard_Real tolcp=0; + gp_Pnt PE, sommet=BRep_Tool::Pnt(V1); + if (!deuxconges) + for (ic=0;ic<nedge;ic++) { + if (sharp.Value(ic)) { + Indices(nedge,ic,icplus,icmoins); + BRepAdaptor_Curve C(TopoDS::Edge(Evive.Value(ic))); + PE = C.Value(p.Value(ic,icplus)); + Standard_Real d1=0., d2=0., dS = PE.Distance(sommet); + ChFiDS_CommonPoint cp1, cp2; + if (!sharp.Value(icplus)) { + isfirst=(sens.Value(icplus)==1); + jfp = 3 - jf.Value(icplus); + cp1 = CD.Value(icplus)->SetOfSurfData()->Value(i.Value(icplus,ic))-> + ChangeVertex (isfirst,jfp); + d1 = cp1.Point().Distance(sommet); + } + if (!sharp.Value(icmoins)) { + isfirst=(sens.Value(icmoins)==1); + cp2 = CD.Value(icmoins)->SetOfSurfData()->Value(i.Value(icmoins,ic))-> + ChangeVertex (isfirst,jf.Value(icmoins)); + d2 = cp2.Point().Distance(sommet); + } + Standard_Boolean samecompoint=Standard_False; + if (!sharp.Value(icmoins) && !sharp.Value(icplus)) + samecompoint=cp1.Point().Distance(cp2.Point())<tolapp; + if ((dS<d1 || dS<d2)&& !samecompoint) { +// step back till Common Points +// without leaving the Edge ?? + if (d2<d1 &&cp1.IsOnArc() ) { +// cp1 is chosen + p.SetValue(ic,icmoins, cp1.ParameterOnArc()); + p.SetValue(ic,icplus, p.Value(ic,icmoins)); + isfirst=(sens.Value(icplus)==1); + jfp = 3 - jf.Value(icplus); + Calcul_Param(CD.Value(icplus),jfp,i.Value(icplus,ic),isfirst,para); + p.SetValue(icplus,ic,para); + if (cp1.Tolerance()>tolcp &&cp1.Tolerance()<1 ) tolcp=cp1.Tolerance(); + } + else if( cp2.IsOnArc()){ +// cp2 is chosen + p.SetValue(ic,icmoins, cp2.ParameterOnArc()); + p.SetValue(ic,icplus, p.Value(ic,icmoins)); + isfirst=(sens.Value(icmoins)==1); + Calcul_Param(CD.Value(icmoins),jf.Value(icmoins),i.Value(icmoins,ic),isfirst, para); + p.SetValue(icmoins,ic,para); + if (cp2.Tolerance()>tolcp&&cp2.Tolerance()<1) tolcp=cp2.Tolerance(); + } + } + else { +// step back till Common Point only if it is very close + if (!sharp.Value(icplus)) { + if ((cp1.Point().Distance(PE)<cp1.Tolerance() || + samecompoint || nconges==1) && cp1.IsOnArc()) { +// it is very close to cp1 + p.SetValue(ic,icmoins, cp1.ParameterOnArc()); + ponctuel.SetValue(ic,Standard_True); + p.SetValue(ic,icplus, p.Value(ic,icmoins)); + isfirst=(sens.Value(icplus)==1); + jfp = 3 - jf.Value(icplus); + Calcul_Param(CD.Value(icplus),jfp,i.Value(icplus,ic),isfirst,para); + p.SetValue(icplus,ic,para); + if (cp1.Tolerance()>tolcp &&cp1.Tolerance()<1) tolcp=cp1.Tolerance(); + } + } + if (!sharp.Value(icmoins)){ + if ((cp2.Point().Distance(PE)<cp2.Tolerance() || + samecompoint || nconges==1) && cp2.IsOnArc()) { +// it is very close to cp2 + ponctuel.SetValue(icmoins,Standard_True); + p.SetValue(ic,icmoins, cp2.ParameterOnArc()); + p.SetValue(ic,icplus,p.Value(ic,icmoins)); + isfirst=(sens.Value(icmoins)==1); + Calcul_Param(CD.Value(icmoins),jf.Value(icmoins),i.Value(icmoins,ic),isfirst,para); + p.SetValue(icmoins,ic,para); + if (cp2.Tolerance()>tolcp&&cp2.Tolerance()<1 ) tolcp=cp2.Tolerance(); + } + } + } + } + } + +// in case of a free border the parameter corresponding +// to the common point on the free edge is chosen. + + for (ic=0;ic<nedge;ic++) { + if (TopoDS::Edge(Evive.Value(ic)).IsSame(edgelibre1) || + TopoDS::Edge(Evive.Value(ic)).IsSame(edgelibre2)) { + Standard_Integer indic; + ChFiDS_CommonPoint CP1; + Indices(nedge,ic,icplus,icmoins); + if (libre.Value(ic))indic=icmoins; + else indic=icplus; + if (!sharp(indic)) { + isfirst=sens.Value(indic)==1; + CP1 = CD.Value(indic)->SetOfSurfData()->Value(Index.Value(indic))->ChangeVertex(isfirst,1); + /*Standard_Boolean*/ trouve=Standard_False; + if (CP1.IsOnArc()) { + if(CP1.Arc().IsSame(TopoDS::Edge(Evive.Value(ic)))) { + p.SetValue(ic,icmoins,CP1.ParameterOnArc()); + p.SetValue(ic,icplus,CP1.ParameterOnArc()); + trouve=Standard_True; + } + } + if (!trouve) { + CP1 = CD.Value(indic)->SetOfSurfData()->Value(Index.Value(indic))->ChangeVertex(isfirst,2); + if (CP1.IsOnArc()) { + if(CP1.Arc().IsSame(TopoDS::Edge(Evive.Value(ic)))) { + p.SetValue(ic,icmoins,CP1.ParameterOnArc()); + p.SetValue(ic,icplus,CP1.ParameterOnArc()); + } + } + } + } + } + } + +// if ic is a regular edge, one finds edge indfin which is not +// a regular edge, and construtc a curve 3d +// between edges (or stripes ) icmoins and indfin. +// Then this courbe3d is projected on all faces (nbface) that +// separate icmoins and indfin +#ifndef DEB + Standard_Integer nbface = 0; +#else + Standard_Integer nbface; +#endif + Standard_Real error; + TColGeom2d_Array1OfCurve proj2d1(0,size); + TColGeom2d_Array1OfCurve proj2d2(0,size); + TColGeom_Array1OfCurve cproj1(0,size); + TColGeom_Array1OfCurve cproj2(0,size); + if (!deuxconges) + for (ic=0;ic<nedge;ic++) { + Standard_Integer ilin; + TColGeom_SequenceOfCurve cr; + TColGeom2d_SequenceOfCurve pr; + TopTools_SequenceOfShape Lface; + TopTools_SequenceOfShape Ledge; + Lface.Clear(); + if (regul.Value(ic)){ + Indices(nedge,ic,icplus,icmoins); + Indices(nedge,icplus,icplus2,ic); + Standard_Integer indfin,indfinmoins,indfinplus; + indfin=icplus; + trouve=Standard_False; + ii=icplus; + while (!trouve) { + if (!regul.Value(ii)) { + indfin=ii; + trouve=Standard_True; + } + if (ii==nedge-1) ii=0; + else ii++; + } + Indices(nedge,indfin,indfinplus,indfinmoins); + if (!sharp.Value(icmoins)){ + if( jf.Value(icmoins)==1) + ilin= SurfIndex(CD, icmoins, i.Value(icmoins,ic), FACE1); + else + ilin= SurfIndex(CD, icmoins, i.Value(icmoins,ic), FACE2); + Lface.Append(TopoDS::Face(DStr.Shape(ilin))); + } + else Lface.Append( Fvive(ic,icmoins)); + if (indfin>icmoins) + nbface=indfin-icmoins; + else nbface =nedge-(icmoins-indfin); + TopTools_SequenceOfShape Epj; + TColStd_SequenceOfReal seqpr; + ii=ic; + for (Standard_Integer nf=1;nf<=nbface-1;nf++) { + Standard_Integer iimoins,iiplus; + Indices(nedge,ii,iiplus,iimoins); + Ledge.Append(TopoDS::Edge(Evive.Value(ii))); + seqpr.Append(p.Value(ii,iiplus)); + if (nf!=nbface-1) Lface.Append( Fvive(ii,iiplus)); + if (ii==nedge-1) ii=0; + else ii++; + } + if (!sharp.Value(indfin) ){ + jfp=3-jf.Value(indfin); + if (jfp==1) + ilin= SurfIndex(CD, indfin, i.Value(indfin,indfinmoins), FACE1); + else ilin=SurfIndex(CD, indfin, i.Value(indfin,indfinmoins), FACE2); + Lface.Append(TopoDS::Face(DStr.Shape(ilin))); + } + else Lface.Append(Fvive(indfin,indfinmoins)); + CurveHermite(DStr,CD.Value(icmoins),jf.Value(icmoins),i.Value(icmoins,ic), + p.Value(icmoins,ic),sens.Value(icmoins),sharp.Value(icmoins), + TopoDS::Edge(Evive.Value(icmoins)),CD.Value(indfin),jf.Value(indfin), + i.Value(indfin,indfinmoins),p.Value(indfin,indfinmoins),sens.Value(indfin), + sharp.Value(indfin),TopoDS::Edge(Evive.Value(indfin)),nbface,Ledge, + Lface,pr,cr,Epj,seqpr,error); + ii=ic; + for (ind=1;ind<=nbface-1;ind++) { + Standard_Integer iimoins,iiplus; + Indices(nedge,ii,iiplus,iimoins); + p.SetValue(ii,iiplus,seqpr.Value(ind)); + p.SetValue(ii,iimoins,seqpr.Value(ind)); + proj2d1.SetValue(ii,pr.Value(ind)); + proj2d2.SetValue(ii,pr.Value(ind+1)); + cproj1.SetValue(ii,cr.Value(ind)); + cproj2.SetValue(ii,cr.Value(ind+1)); + if (ii==nedge-1) ii=0; + else ii++; + } + if (!sharp.Value(icmoins)&&!sharp.Value(indfin)) { + ii=icmoins; + while (ii!=indfin) { + isG1.SetValue(ii,Standard_True); + if (ii==nedge-1) ii=0; + else ii++; + } + } + ic=ic+nbface-1; + } + } + + // case when the conncting curve between ic and icplus crosses many faces + + TopTools_SequenceOfShape Ecom; + TopTools_SequenceOfShape Eproj; + TColStd_SequenceOfReal parcom; + if (!deuxconges) + for (ic=0;ic<nedge;ic++) { + Standard_Integer iface1,iface2; + TopoDS_Face face1,face2; + TopoDS_Edge edge; + TColGeom_SequenceOfCurve cr; + TColGeom2d_SequenceOfCurve pr; + Indices(nedge,ic,icplus,icmoins); + if (!oksea.Value(ic)){ + iface1=numfa.Value(ic,icplus); + iface2=numfa.Value(icplus,ic); + if (!sharp.Value(ic)) { + if (jf.Value(ic)==1) + iface1 =SurfIndex(CD, ic, i.Value(ic,icplus), FACE1); + else iface1=SurfIndex(CD, ic, i.Value(ic,icplus), FACE2); + } + face1=TopoDS::Face(myDS->Shape(iface1)); + + if (!sharp.Value(icplus)) { + if (jf.Value(icplus)==1) + iface2 =SurfIndex(CD, icplus, i.Value(icplus,ic), FACE2); + else iface2=SurfIndex(CD, icplus, i.Value(icplus,ic), FACE1); + } + face2=TopoDS::Face(myDS->Shape(iface2)); + if (!face1.IsSame(face2)) { + if (Fproj.Length()==0) { + Fproj.Append(face1); + Fproj.Append(face2); + } + moresurf.SetValue(ic,Standard_True); + nbface=Fproj.Length(); + if (!TopoDS::Face(Fproj.Value(nbface)).IsSame(face2)) { + Fproj.Remove(nbface); + Fproj.Append(face2); + } + if (!TopoDS::Face(Fproj.Value(1)).IsSame(face1)) { + Fproj.Remove(1); + Fproj.Prepend(face1); + } + for (nb=1;nb<=nbface-1; nb++) { + cherche_edge1 ( TopoDS::Face(Fproj.Value(nb)), TopoDS::Face(Fproj.Value(nb+1)),edge); + Ecom.Append(edge); + para=BRep_Tool::Parameter(TopExp::FirstVertex(edge),edge); + parcom.Append(para); + } + CurveHermite (DStr,CD.Value(ic),jf.Value(ic),i.Value(ic,icplus), + p.Value(ic,icplus),sens.Value(ic),sharp.Value(ic), + TopoDS::Edge(Evive.Value(ic)), + CD.Value(icplus),jf.Value(icplus),i.Value(icplus,ic), + p.Value(icplus,ic),sens.Value(icplus),sharp.Value(icplus), + TopoDS::Edge(Evive.Value(icplus)),nbface,Ecom,Fproj, pr,cr,Eproj,parcom,error); + Ecom.Append(Ecom.Value(nbface-1)); + parcom.Append(parcom.Value(nbface-1)); + } + } + } + +// case when two fillets have the same commonpoints +// one continues then by intersection +// it is checked if the extremities of the intersection coincide with commonpoints + + Standard_Boolean intersection=Standard_False, introuve; + if (nconges==2 && !deuxconges) { + gp_Pnt P1,P2,P3,P4; +#ifndef DEB + Standard_Integer ic1 = 0,ic2 = 0; +#else + Standard_Integer ic1,ic2; +#endif + trouve=Standard_False; + for (ic=0;ic<nedge&&!trouve;ic++) { + if (!sharp.Value(ic)){ + ic1=ic; + trouve=Standard_True; + } + } + for (ic=0;ic<nedge;ic++) { + if (!sharp.Value(ic)&& ic!=ic1) ic2=ic; + } + jfp = 3 - jf.Value(ic1); + Indices(nedge,ic1,icplus,icmoins); + Calcul_P2dOnSurf(CD.Value(ic1),jfp,i.Value(ic1,icmoins),p.Value(ic1,icmoins),p2); + indice=SurfIndex(CD, ic1, i.Value(ic1,icmoins), ChFiSURFACE); + DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),P1); + + Calcul_P2dOnSurf(CD.Value(ic1),jf.Value(ic1),i.Value(ic1,icplus),p.Value(ic1,icplus),p2); + indice=SurfIndex(CD, ic1, i.Value(ic1,icplus), ChFiSURFACE); + DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),P2); + + jfp = 3 - jf.Value(ic2); + Indices(nedge,ic2,icplus,icmoins); + Calcul_P2dOnSurf(CD.Value(ic2),jfp,i.Value(ic2,icmoins),p.Value(ic2,icmoins),p2); + indice=SurfIndex(CD, ic2, i.Value(ic2,icmoins), ChFiSURFACE); + DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),P3); + + Calcul_P2dOnSurf(CD.Value(ic2),jf.Value(ic2),i.Value(ic2,icplus),p.Value(ic2,icplus),p2); + indice=SurfIndex(CD, ic2, i.Value(ic2,icplus), ChFiSURFACE); + DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),P4); + intersection=(P1.Distance(P4)<=1.e-7 || P1.Distance(P3)<=1.e-7) && + (P2.Distance(P4)<=1.e-7 || P2.Distance(P3)<=1.e-7); + if (intersection) { + PerformTwoCornerSameExt(DStr,CD.Value(ic1),Index.Value(ic1),sens.Value(ic1), + CD.Value(ic2),Index.Value(ic2),sens.Value(ic2),introuve); + if (introuve) return; + } + } + +// declaration for plate + GeomPlate_BuildPlateSurface PSurf(3,10,3,tol2d,tolesp,angular); + +// calculation of curves on surface for each stripe + for (ic=0;ic<nedge;ic++) { + gp_Pnt2d p2d1, p2d2; + if (!sharp.Value(ic)) { + n3d++; + Indices(nedge,ic,icplus,icmoins); + jfp = 3 - jf.Value(ic); + Calcul_P2dOnSurf(CD.Value(ic),jfp,i.Value(ic,icmoins),p.Value(ic,icmoins),p2d1); + Calcul_P2dOnSurf(CD.Value(ic),jf.Value(ic),i.Value(ic,icplus),p.Value(ic,icplus),p2d2); +// if (i[ic][icplus]!= i[ic][icmoins]) cout<<"probleme surface"<<endl; + indice= SurfIndex(CD, ic, i.Value(ic,icplus), ChFiSURFACE); + Handle (GeomAdaptor_HSurface) Asurf = + new GeomAdaptor_HSurface(DStr.Surface(indice).Surface()); + // calculation of curve 2d + xdir= p2d2.X()-p2d1.X(); + ydir= p2d2.Y()-p2d1.Y(); + Standard_Real l0 = sqrt(xdir*xdir+ ydir*ydir ); + gp_Dir2d dir (xdir, ydir); + Handle(Geom2d_Line) l= new Geom2d_Line (p2d1 ,dir); + Handle (Geom2d_Curve) pcurve = new Geom2d_TrimmedCurve(l,0,l0); + Handle (Geom2dAdaptor_HCurve) Acurv = new Geom2dAdaptor_HCurve(pcurve); + Adaptor3d_CurveOnSurface CurvOnS (Acurv,Asurf); + Handle(Adaptor3d_HCurveOnSurface) HCons = + new Adaptor3d_HCurveOnSurface(CurvOnS); + Order.SetValue(ic,1); + Handle(GeomPlate_CurveConstraint) Cont = + new GeomPlate_CurveConstraint(HCons,Order.Value(ic),10,tolesp,angular,0.1); + PSurf.Add(Cont); + + // calculate indexes of points and of the curve for the DS + isfirst=(sens.Value(ic)==1); + GeomLib::BuildCurve3d(tolapp,CurvOnS,CurvOnS.FirstParameter(), + CurvOnS.LastParameter(),Curv3d,maxapp,avedev); + TopOpeBRepDS_Curve tcurv3d( Curv3d,maxapp); + indcurve3d.SetValue(n3d,DStr.AddCurve(tcurv3d)); + gp_Pnt point1,point2; + point1= CurvOnS.Value(CurvOnS.FirstParameter()); + point2 =CurvOnS.Value(CurvOnS.LastParameter()); + + TopOpeBRepDS_Point tpoint1 (point1,maxapp); + TopOpeBRepDS_Point tpoint2 (point2,maxapp); + errapp.SetValue(ic,maxapp); + if (ic==0) { +// it is necessary to create two points + indpoint.SetValue(ic,0,DStr.AddPoint(tpoint1)); + indpoint.SetValue(ic,1,DStr.AddPoint(tpoint2)); + } + else { +// probably the points are already on the fillet +// (previous intersection...) + trouve = Standard_False; + for (ii=0;ii<ic&&(!trouve);ii++) { + if (!sharp.Value(ii)) { + TopOpeBRepDS_Point & tpt= DStr.ChangePoint(indpoint.Value(ii,1)); + if (point1.Distance(tpt.Point())<1.e-4) + trouve = Standard_True; + } + } + if (trouve) + indpoint.SetValue(ic,0,indpoint.Value(ii-1,1)); + else + indpoint.SetValue(ic,0,DStr.AddPoint(tpoint1)); + + trouve = Standard_False; + for (ii=0;ii<ic&&(!trouve);ii++) { + if (!sharp.Value(ii)) { + TopOpeBRepDS_Point & tpt= DStr.ChangePoint(indpoint.Value(ii,0)); + if (point2.Distance(tpt.Point())<1.e-4) + trouve = Standard_True; + } + } + if (trouve) + indpoint.SetValue(ic,1,indpoint.Value(ii-1,0)); + else + indpoint.SetValue(ic,1,DStr.AddPoint(tpoint2)); + } + + // update of the stripe + isurf1=3-jf.Value(ic); isurf2=jf.Value(ic); + if (isurf1==2) CD.Value(ic)->SetOrientation(TopAbs_REVERSED,isfirst); + CD.Value(ic)->SetCurve(indcurve3d.Value(n3d),isfirst); + CD.Value(ic)->SetIndexPoint(indpoint.Value(ic,0),isfirst,isurf1); + CD.Value(ic)->SetIndexPoint(indpoint.Value(ic,1),isfirst,isurf2); + CD.Value(ic)->SetParameters(isfirst,pcurve->FirstParameter(),pcurve->LastParameter()); + ChFiDS_CommonPoint cp1; + ChFiDS_CommonPoint cp2; + cp1.SetPoint (point1); + cp2.SetPoint( point2); + CD.Value(ic)->SetOfSurfData()->Value(i.Value(ic,icmoins))-> + ChangeVertex (isfirst,isurf1)=cp1; + CD.Value(ic)->SetOfSurfData()->Value(i.Value(ic,icmoins))-> + ChangeVertex (isfirst,isurf2)=cp2; + CD.Value(ic)->SetOfSurfData()->Value(i.Value(ic,icmoins))-> + ChangeInterference(isurf1).SetParameter(p.Value(ic,icmoins),isfirst); + CD.Value(ic)->SetOfSurfData()->Value(i.Value(ic,icmoins))-> + ChangeInterference(isurf2).SetParameter(p.Value(ic,icplus),isfirst); + CD.Value(ic)-> ChangePCurve(isfirst)= pcurve; + } + } + +// calculate the indices of points for living edges + for (ic=0;ic<nedge;ic++) { + if (sharp.Value(ic)) { + Indices(nedge,ic,icplus,icmoins); + BRepAdaptor_Curve C(TopoDS::Edge(Evive.Value(ic))); + /*gp_Pnt*/ PE = C.Value(p.Value(ic,icplus)); + TopOpeBRepDS_Point TPE(PE,BRep_Tool::Tolerance(TopoDS::Edge(Evive.Value(ic)))); + ChFiDS_CommonPoint cp; + if (deuxconges ) { + IVtx = DStr.AddShape(V1); + indpoint.SetValue(ic,0, IVtx ); + indpoint.SetValue(ic,1, IVtx ); + } + if (!sharp.Value(icplus)) { + isfirst=(sens.Value(icplus)==1); + jfp = 3 - jf.Value(icplus); + cp = CD.Value(icplus)->SetOfSurfData()->Value(i.Value(icplus,ic))-> + ChangeVertex (isfirst,jfp); + if ( cp.Point().Distance(PE) <= Max(1.e-4,tolcp)) { +// edge was limited by the 1st CommonPoint of CD[icplus] + indpoint.SetValue(ic,0,indpoint.Value(icplus,0)); + indpoint.SetValue(ic,1,indpoint.Value(icplus,0)); + } + } + if (!sharp.Value(icmoins)) { + isfirst=(sens.Value(icmoins)==1); + cp = CD.Value(icmoins)->SetOfSurfData()->Value(i.Value(icmoins,ic))-> + ChangeVertex (isfirst,jf.Value(icmoins)); + if ( cp.Point().Distance(PE) <= Max(1.e-4,tolcp)) { +// edge was limited by the 2nd CommonPoint of CD[icmoins] + if (indpoint.Value(ic,0)==0) { + indpoint.SetValue(ic,0, indpoint.Value(icmoins,1)); + indpoint.SetValue(ic,1, indpoint.Value(icmoins,1)); + } + } + } + if (indpoint.Value(ic,0)==0) { + indpoint.SetValue(ic,0,DStr.AddPoint(TPE)); + indpoint.SetValue(ic,1, indpoint.Value(ic,0)); + } + } + } + +// calculation of intermediary curves connecting two stripes in case if +// there is no intersection. The curve is a straight line, projection or batten + + Standard_Boolean raccordbatten; + if (!inters) { + + for (ic=0;ic<nedge;ic++) { + + if (!oksea.Value(ic)&& !moresurf.Value(ic) && !libre.Value(ic) ) { + Indices(nedge,ic,icplus,icmoins); + raccordbatten=Standard_False; + if (!regul.Value(ic)) { + raccordbatten=Standard_True; + if (regul.Value(icplus)) + raccordbatten=Standard_False; + } + n3d++; + gp_Pnt2d p2d1, p2d2; + Handle(Geom2d_Curve) curv2d1,curv2d2; + Handle (Geom2d_Curve) pcurve; + Handle (Geom_Curve) curveint; + Handle (GeomAdaptor_HSurface) Asurf; + Standard_Real u1bid,u2bid; + + // return the 1st curve 2d + // and the 1st connection point + if (sharp.Value(ic)) + curv2d1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(Evive.Value(ic)),TopoDS::Face(Fvive.Value(ic,icplus)), + u1bid,u2bid); + else + Calcul_C2dOnFace(CD.Value(ic),jf.Value(ic),i.Value(ic,icplus),curv2d1); + p2d1 = curv2d1 ->Value(p.Value(ic,icplus)); + + // recuperation de la deuxieme courbe 2d + // et du deuxieme point de raccordement + if (sharp.Value(icplus)) + curv2d2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(Evive.Value(icplus)), + TopoDS::Face(Fvive.Value(ic,icplus)),u1bid,u2bid); + else { + jfp = 3 - jf.Value(icplus); + Calcul_C2dOnFace(CD.Value(icplus),jfp,i.Value(icplus,ic),curv2d2); + } + p2d2 = curv2d2 ->Value(p.Value(icplus,ic)); + + Asurf = new GeomAdaptor_HSurface(BRep_Tool::Surface(TopoDS::Face(Fvive.Value(ic,icplus)))); + Standard_Real tolu,tolv,ratio; + tolu=Asurf->Surface().UResolution(1.e-3); + tolv=Asurf->Surface().VResolution(1.e-3); + if (tolu>tolv) ratio=tolu/tolv; + else ratio=tolv/tolu; + + // in case of a sewing edge the parameters are reframed + if (couture) { + Standard_Boolean PI1=Standard_False, PI2=Standard_False; + Standard_Real xx; + PI1=0<=p2d1.X() && p2d1.X() <=PI; + PI2=0<=p2d2.X() && p2d2.X() <=PI; + + if (Evive.Value(ic).IsSame(edgecouture)){ + xx=p2d1.X(); + if (PI2&&!PI1) xx=xx-2*PI; + if (!PI2&&PI1) xx=xx+2*PI; + p2d1.SetX(xx); + + } + if (Evive.Value(icplus).IsSame(edgecouture)){ + xx=p2d2.X(); + if (PI2&&!PI1) xx=xx+2*PI; + if (!PI2&&PI1) xx=xx-2*PI; + p2d2.SetX(xx); + } + } + xdir= p2d2.X()-p2d1.X(); + ydir= p2d2.Y()-p2d1.Y(); + + Standard_Real l0 = sqrt(xdir*xdir+ ydir*ydir ); + if (l0<1.e-7|| ponctuel.Value(ic)) { +// unused connection + n3d--; + ponctuel.SetValue(ic,Standard_True); + if (!deuxconges) { + if ( sharp.Value(icplus) && indpoint.Value(icplus,0) == 0 ) { + indpoint.SetValue(icplus,0, indpoint.Value(ic,1)); + indpoint.SetValue(icplus,1, indpoint.Value(ic,1)); + } + if ( sharp.Value(ic) && indpoint.Value(ic,0) == 0 ) { + indpoint.SetValue(ic,0,indpoint.Value(icmoins,1)); + indpoint.SetValue(ic,1,indpoint.Value(icmoins,1)); + } + } + } + else { // the connection is a straight line, projection or batten + if (ratio>10 && nconges==1) raccordbatten=Standard_True; + if (ratio>10 && raccordbatten) { + CalculDroite(p2d1,xdir,ydir,pcurve); + raccordbatten=Standard_False; + } + else if (!raccordbatten){ // the projected curves are returned + if (regul.Value(ic)) { + if (cproj2.Value(ic).IsNull()){ + raccordbatten=Standard_True; + } + else { + pcurve=proj2d2.Value(ic); + curveint=cproj2.Value(ic); + maxapp1=1.e-6; + } + + } + else { + if (cproj1.Value(ic+1).IsNull()) { + raccordbatten=Standard_True; + } + else { + pcurve=proj2d1.Value(ic+1); + curveint=cproj1.Value(ic+1); + maxapp1=1.e-6; + } + } + } + Standard_Boolean contraint1=Standard_True, + contraint2=Standard_True; + if (raccordbatten) { +#ifdef DEB + ChFi3d_InitChron(ch);// initial performances for battens +#endif + Standard_Boolean inverseic,inverseicplus; + if (sharp.Value(ic)) { + inverseic=TopExp::FirstVertex(TopoDS::Edge(Evive.Value(ic))). + IsSame(V1); + } + else { + inverseic=sens.Value(ic)==1; + } + if (sharp.Value(icplus)){ + inverseicplus=TopExp::FirstVertex(TopoDS::Edge(Evive.Value(icplus))). + IsSame(V1); + } + else { + inverseicplus=sens.Value(icplus)==1; + } + if (TopoDS::Edge(Evive.Value(ic)).IsSame(edgelibre1) || + TopoDS::Edge(Evive.Value(ic)).IsSame(edgelibre2)) + contraint1=Standard_False; + if (TopoDS::Edge(Evive.Value(icplus)).IsSame(edgelibre1) || + TopoDS::Edge(Evive.Value(icplus)).IsSame(edgelibre2)) + contraint2=Standard_False; + CalculBatten(Asurf,TopoDS::Face(Fvive(ic,icplus)),xdir,ydir,p2d1,p2d2,contraint1,contraint2,curv2d1,curv2d2,p.Value(ic,icplus), + p.Value(icplus,ic),inverseic,inverseicplus,pcurve); +#ifdef DEB + ChFi3d_ResultChron( ch,t_batten); // resulting performances for battens +#endif + } + + // construction of borders for Plate + Handle (Geom2dAdaptor_HCurve) Acurv=new Geom2dAdaptor_HCurve(pcurve); + Adaptor3d_CurveOnSurface CurvOnS (Acurv,Asurf); + Handle(Adaptor3d_HCurveOnSurface) HCons = + new Adaptor3d_HCurveOnSurface(CurvOnS); + + // constraints G1 are set if edges ic and icplus are not both alive + + + Order.SetValue(n3d,0); + if (!sharp.Value(ic)&& !sharp.Value(icplus)) + Order.SetValue(n3d,1); + if (!contraint1 && !sharp.Value(icplus)) + Order.SetValue(n3d,1); + if (!contraint2 && !sharp.Value(ic)) + Order.SetValue(n3d,1); + if (tangentregul(ic) || tangentregul(icplus) ) + Order.SetValue(n3d,1); + if (isG1.Value(ic)) + Order.SetValue(n3d,1); + Handle(GeomPlate_CurveConstraint) Cont = + new GeomPlate_CurveConstraint(HCons,Order.Value(n3d),10,tolesp,angular,0.1); + PSurf.Add(Cont); + + //calculation of curve 3d if it is not a projection + if (curveint.IsNull()) { + GeomLib::BuildCurve3d(tolapp,CurvOnS,CurvOnS.FirstParameter(), + CurvOnS.LastParameter(),Curv3d,maxapp1,avedev); + pardeb=CurvOnS.FirstParameter(); + parfin= CurvOnS.LastParameter(); + curveint= new Geom_TrimmedCurve(Curv3d,pardeb,parfin); + } + + //storage in the DS + TopOpeBRepDS_Curve tcurv3d( curveint,maxapp1); + indcurve3d.SetValue(n3d, DStr.AddCurve(tcurv3d)); + pardeb=curveint->FirstParameter(); + parfin=curveint->LastParameter(); + if ( sharp.Value(icplus) && indpoint.Value(icplus,0) == 0) { + // it is necessary to initialize indpoint[icplus][0] and indpoint[icplus][1] + gp_Pnt point2; + point2 =curveint->Value(parfin); + TopOpeBRepDS_Point tpoint2 (point2,maxapp); + indpoint.SetValue(icplus,0,DStr.AddPoint(tpoint2)); + indpoint.SetValue(icplus,1,indpoint.Value(icplus,0)); + } + Standard_Boolean IsVt1=Standard_False; + Standard_Boolean IsVt2=Standard_False; + if(deuxconges) { + IsVt1=sharp.Value(ic); + IsVt2=sharp.Value(icplus); + } + Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurve3d.Value(n3d), + indpoint.Value(ic,1),pardeb,IsVt1); + Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurve3d.Value(n3d), + indpoint(icplus,0),parfin,IsVt2); + DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append(Interfp1); + DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append(Interfp2); + if (!IsVt1) { + TopOpeBRepDS_Point & tpt1= DStr.ChangePoint(indpoint(ic,1)); + tpt1.Tolerance (tpt1.Tolerance()+maxapp1); + } + if (!IsVt2) { + TopOpeBRepDS_Point &tpt2= DStr.ChangePoint(indpoint(icplus,0)); + tpt2.Tolerance (tpt2.Tolerance()+maxapp1); + } + + // calculate orientation of the curve + TopAbs_Orientation orinterf; + if (!sharp.Value(ic)) { + OrientationIcNonVive(CD.Value(ic),jf.Value(ic),i.Value(ic,icplus),sens.Value(ic),orinterf); + } + else if (!sharp.Value(icplus)) { + OrientationIcplusNonVive(CD.Value(icplus),jf.Value(icplus),i.Value(icplus,ic),sens.Value(icplus),orinterf); + } + else { + OrientationAreteViveConsecutive (Fvive.Value(ic,icplus) ,Evive.Value(ic),V1,orinterf); + } + Interfc=ChFi3d_FilCurveInDS(indcurve3d.Value(n3d),numfa.Value(ic,icplus),pcurve,orinterf); + DStr.ChangeShapeInterferences(numfa.Value(ic,icplus)).Append(Interfc); + } + } // end of processing by edge + } // end of the loop on edges + } // end of processing for intermediary curves + +// storage in the DS of curves projected on several faces + for (ic=0;ic<nedge;ic++) { + if (moresurf.Value(ic) ){ + TopoDS_Vertex Vf,Vl; + gp_Pnt Pf,Pl,P1,P2,Pcom; + ind = 0; //must be initialized because of possible use, see L2249 + Standard_Real up1,up2; + TopAbs_Orientation orvt; + TopAbs_Orientation oredge = TopAbs_FORWARD; + Standard_Integer indpoint1,indpoint2; + Indices(nedge,ic,icplus,icmoins); + Handle(Geom2d_Curve) proj,proj2d; + Handle(Geom_Curve) projc,cproj; + TopOpeBRepDS_Point& tpt1= DStr.ChangePoint(indpoint(ic,1)); + TopOpeBRepDS_Point& tpt2= DStr.ChangePoint(indpoint(icplus,0)); + tpt1.Tolerance (tpt1.Tolerance()+error); + tpt2.Tolerance (tpt1.Tolerance()+error); + for(nb=1;nb<=nbface;nb++) { + orvt=TopAbs_REVERSED; + Vf=TopExp::FirstVertex(TopoDS::Edge(Ecom.Value(nb))); + Vl=TopExp::LastVertex (TopoDS::Edge(Ecom.Value(nb))); + Pf=BRep_Tool::Pnt(Vf); + Pl=BRep_Tool::Pnt(Vl); + para=parcom.Value(nb); + Pcom=BRep_Tool::Curve(TopoDS::Edge(Ecom.Value(nb)),up1,up2)->Value(para); + if (Pf.Distance(BRep_Tool::Pnt(V1))< Pl.Distance(BRep_Tool::Pnt(V1))) + orvt=TopAbs_FORWARD; + if (!Eproj.Value(nb).IsNull()) { + n3d++; + proj=BRep_Tool::CurveOnSurface(TopoDS::Edge(Eproj.Value(nb)), + TopoDS::Face(Fproj.Value(nb)),up1,up2); + proj2d=new Geom2d_TrimmedCurve(proj,up1,up2); + projc=BRep_Tool::Curve(TopoDS::Edge(Eproj.Value(nb)),up1,up2); + cproj=new Geom_TrimmedCurve(projc,up1,up2); + pardeb=cproj->FirstParameter(); + parfin=cproj->LastParameter(); + P1=cproj->Value(pardeb); + P2=cproj->Value(parfin); + if (P1.Distance(tpt1.Point())<1.e-3) + indpoint1=indpoint(ic,1); + else indpoint1=ind; + if (P2.Distance(tpt2.Point())<1.e-3) + indpoint2=indpoint(icplus,0); + else { + TopOpeBRepDS_Point tpoint2 (P2,error); + indpoint2= DStr.AddPoint(tpoint2); + ind=indpoint2; + } + Handle (GeomAdaptor_HSurface) Asurf; + Asurf = new GeomAdaptor_HSurface(BRep_Tool::Surface + (TopoDS::Face(Fproj.Value(nb)))); + Handle (Geom2dAdaptor_HCurve) Acurv=new Geom2dAdaptor_HCurve(proj2d); + Adaptor3d_CurveOnSurface CurvOnS (Acurv,Asurf); + Handle(Adaptor3d_HCurveOnSurface) HCons =new Adaptor3d_HCurveOnSurface(CurvOnS); + Order.SetValue(n3d,1); + Handle(GeomPlate_CurveConstraint) Cont = + new GeomPlate_CurveConstraint(HCons,Order.Value(n3d),10,tolesp,angular,0.1); + PSurf.Add(Cont); + TopOpeBRepDS_Curve tcurv3d( cproj,error); + indcurve3d.SetValue(n3d, DStr.AddCurve(tcurv3d)); + Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurve3d.Value(n3d), + indpoint1,pardeb); + Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurve3d.Value(n3d), + indpoint2,parfin); + DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append(Interfp1); + DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append(Interfp2); + num=DStr.AddShape(Fproj.Value(nb)); + TopExp_Explorer ex; + for(ex.Init(Fproj.Value(nb).Oriented(TopAbs_FORWARD),TopAbs_EDGE); + ex.More(); ex.Next()){ + if(Ecom.Value(nb).IsSame(ex.Current())) { + oredge = ex.Current().Orientation(); + break; + } + } + + //calculation of the orientation + TopAbs_Orientation orinterf; + if (P1.Distance(Pcom)>1.e-4) { + if (orvt==TopAbs_FORWARD) { + orinterf=oredge; + } + else { + orinterf=TopAbs::Reverse(oredge); + } + } + else { + if (orvt==TopAbs_FORWARD) { + orinterf=TopAbs::Reverse(oredge); + } + else { + orinterf=oredge; + } + } + Interfc=ChFi3d_FilCurveInDS(indcurve3d.Value(n3d),num,proj2d,orinterf); + DStr.ChangeShapeInterferences(num).Append(Interfc); + } + indice=ind; + if (nb!=nbface) { + if (Eproj.Value(nb).IsNull()) indice=indpoint(ic,1); + if (Eproj.Value(nb+1).IsNull()) indice=indpoint(icplus,0); + Indice.SetValue(n3d,indice); + Standard_Integer Iarc1=DStr.AddShape(TopoDS::Edge(Ecom.Value(nb))); + Interfp1=ChFi3d_FilPointInDS(orvt,Iarc1,indice,parcom.Value(nb)); + DStr.ChangeShapeInterferences(Iarc1).Append(Interfp1); + } + } + } + } + +// case when two free borders are tangent + if (droit) + for (ic=0;ic<nedge;ic++) { + Handle(Geom_Curve) curve,ctrim,rcurve; + Handle(Geom2d_Curve) curve2d,ctrim2d,rcurve2d; + Standard_Real ufirst,ulast; + Indices(nedge,ic,icplus,icmoins); + Standard_Integer indpoint1,indpoint2; + Standard_Boolean isvt1=Standard_False,isvt2=Standard_False; + TopoDS_Edge ecur =TopoDS::Edge(Evive.Value(ic)); + if (ecur.IsSame(edgelibre1)|| ecur.IsSame(edgelibre2)) { + n3d++; + curve2d=BRep_Tool::CurveOnSurface(TopoDS::Edge(Evive.Value(ic)), + TopoDS::Face(Fvive.Value(ic,icplus)),ufirst,ulast); + curve=BRep_Tool::Curve(TopoDS::Edge(Evive.Value(ic)),ufirst,ulast); + if (TopExp::FirstVertex((TopoDS::Edge(Evive.Value(ic)))).IsSame (V1)) { + ctrim=new Geom_TrimmedCurve(curve,ufirst,p.Value(ic,icmoins)); + ctrim2d=new Geom2d_TrimmedCurve(curve2d,ufirst,p.Value(ic,icmoins)); + indpoint1=DStr.AddShape(V1); + isvt1=1; + indpoint2=indpoint(ic,1); + } + else { + ctrim=new Geom_TrimmedCurve(curve, p.Value(ic,icmoins),ulast); + ctrim2d=new Geom2d_TrimmedCurve(curve2d,p.Value(ic,icmoins),ulast); + indpoint2=DStr.AddShape(V1); + isvt2=1; + indpoint1=indpoint(ic,1); + } + if (libre.Value(ic)){ + if (TopExp::FirstVertex((TopoDS::Edge(Evive.Value(ic)))).IsSame(V1)) { + ctrim->Reverse(); + ctrim2d->Reverse(); + indpoint2=DStr.AddShape(V1); + isvt2=1; + isvt1=0; + indpoint1=indpoint(ic,1); + } + } + else { + if (TopExp::LastVertex((TopoDS::Edge(Evive.Value(ic)))).IsSame(V1)) { + ctrim->Reverse(); + ctrim2d->Reverse(); + indpoint1=DStr.AddShape(V1); + isvt1=1; + isvt2=0; + indpoint2=indpoint(ic,1); + } + } + ufirst=ctrim->FirstParameter(); + ulast=ctrim->LastParameter(); + Handle (GeomAdaptor_HSurface) Asurf; + Asurf = new GeomAdaptor_HSurface(BRep_Tool::Surface + (TopoDS::Face(Fvive.Value(ic,icplus)))); + Handle (Geom2dAdaptor_HCurve) Acurv=new Geom2dAdaptor_HCurve(ctrim2d); + Adaptor3d_CurveOnSurface CurvOnS (Acurv,Asurf); + Handle(Adaptor3d_HCurveOnSurface) HCons =new Adaptor3d_HCurveOnSurface(CurvOnS); + Order.SetValue(n3d,0); + Handle(GeomPlate_CurveConstraint) Cont = + new GeomPlate_CurveConstraint(HCons,Order.Value(n3d),10,tolesp,angular,0.1); + PSurf.Add(Cont); + TopOpeBRepDS_Curve tcurv3d( ctrim,1.e-4); + indcurve3d.SetValue(n3d, DStr.AddCurve(tcurv3d)); + Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurve3d.Value(n3d), + indpoint1,ufirst,isvt1); + Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurve3d.Value(n3d), + indpoint2,ulast,isvt2); + DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append(Interfp1); + DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append(Interfp2); + } + } + +#ifdef DEB + ChFi3d_InitChron(ch); // init performances for plate +#endif + + PSurf.Perform(); + +#ifdef DEB + ChFi3d_ResultChron(ch, t_plate); //result performances for plate +#endif + + // call of approx + +#ifdef DEB + ChFi3d_InitChron(ch); // init performances for approxplate +#endif + if (PSurf.IsDone()) { + Standard_Integer nbcarreau=9; + Standard_Integer degmax=8; + Standard_Real seuil; + Handle(GeomPlate_Surface) gpPlate = PSurf.Surface(); + + TColgp_SequenceOfXY S2d; + TColgp_SequenceOfXYZ S3d; + S2d.Clear(); + S3d.Clear(); + PSurf.Disc2dContour(4,S2d); + PSurf.Disc3dContour(4,0,S3d); + seuil = Max(tolapp,10*PSurf.G0Error()); + GeomPlate_PlateG0Criterion critere (S2d,S3d,seuil); + GeomPlate_MakeApprox Mapp(gpPlate,critere,tolapp,nbcarreau,degmax); + Handle (Geom_Surface) Surf (Mapp.Surface()); + Standard_Real coef = 1.1 ,apperror; + apperror=Mapp.CriterionError()*coef; + +#ifdef DEB + ChFi3d_ResultChron(ch, t_approxplate); // result performances for approxplate +#endif + +// Storage of the surface plate and corresponding curves in the DS + + TopAbs_Orientation orplate,orsurfdata,orpcurve,orien; +#ifdef DEB +// Standard_Real ang1=PSurf.G1Error(); +#endif +// gp_Vec n1,n2,du,dv,du1,dv1; +// gp_Pnt pp,pp1; +// Standard_Real tpar; +// gp_Pnt2d uv; +// Standard_Real scal; + + TopOpeBRepDS_Surface Tsurf(Surf,Mapp.ApproxError()); + Standard_Integer Isurf=DStr.AddSurface(Tsurf); + //lbo : historique QDF. + if(!myEVIMap.IsBound(V1)){ + TColStd_ListOfInteger li; + myEVIMap.Bind(V1,li); + } + myEVIMap.ChangeFind(V1).Append(Isurf); + + Standard_Integer SolInd = CD.Value(0)->SolidIndex(); + TopOpeBRepDS_ListOfInterference& SolidInterfs = + DStr.ChangeShapeInterferences(SolInd); + +// in case when one rereads at top, it is necessary that +// alive edges that arrive at the top should be removed from the DS. +// For this they are stored in the DS with their inverted orientation + Standard_Integer nbedge; + TopExp_Explorer ex; + if (deuxconges) + for (ic=0;ic<nedge;ic++) { + if (!sharp.Value(ic)){ + nbedge = CD.Value(ic)->Spine()->NbEdges(); + TopoDS_Edge Arcspine; + if (sens.Value(ic) ==1) + Arcspine=CD.Value(ic) ->Spine()->Edges(1); + else + Arcspine= CD.Value(ic)->Spine()->Edges(nbedge); + Standard_Integer IArcspine = DStr.AddShape(Arcspine); +#ifndef DEB + TopAbs_Orientation OVtx = TopAbs_FORWARD; +#else + TopAbs_Orientation OVtx; +#endif + for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); + ex.More(); ex.Next()){ + if(V1.IsSame(ex.Current())) { + OVtx = ex.Current().Orientation(); + break; + } + } + OVtx = TopAbs::Reverse(OVtx); + Standard_Real parVtx = BRep_Tool::Parameter(V1,Arcspine); + Handle(TopOpeBRepDS_CurvePointInterference) + interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx); + DStr.ChangeShapeInterferences(IArcspine).Append(interfv); + } + } + + // calculate orientation of Plate orplate corresponding to surfdata + // calculation corresponding to the first stripe + Indices(nedge,0,icplus,icmoins); + isfirst=(sens.Value(0)==1); + const Handle(ChFiDS_SurfData)& Fd = + CD.Value(0)->SetOfSurfData()->Value(i.Value(0,icmoins)); + indice= Fd->Surf(); +// Handle (Geom_Surface) surfdata = DStr.Surface(indice).Surface(); +// tpar= (CD.Value(0)->PCurve(isfirst)->FirstParameter()+ +// CD.Value(0)->PCurve(isfirst)->LastParameter())/2 ; +// CD.Value(0)->PCurve(isfirst)->D0(tpar,uv); +// surfdata->D1(uv.X(),uv.Y(),pp,du,dv); +// tpar=(PSurf.Curves2d()->Value(1)->FirstParameter()+ +// PSurf.Curves2d()->Value(1)->LastParameter())/2; +// (PSurf.Curves2d())->Value(1)->D0(tpar,uv); +// Surf-> D1(uv.X(),uv.Y(),pp1,du1,dv1); +// n1=du.Crossed(dv); +// n2=du1.Crossed(dv1); +// scal= n1.Dot(n2); + orsurfdata=Fd->Orientation(); +// if (scal>0) orplate=orsurfdata; +// else orplate=TopAbs::Reverse(orsurfdata); + orplate = PlateOrientation(Surf,PSurf.Curves2d(),SumFaceNormalAtV1); + + // creation of solidinterderence for Plate + Handle(TopOpeBRepDS_SolidSurfaceInterference) SSI = + new TopOpeBRepDS_SolidSurfaceInterference(TopOpeBRepDS_Transition(orplate), + TopOpeBRepDS_SOLID, + SolInd, + TopOpeBRepDS_SURFACE, + Isurf); + SolidInterfs.Append(SSI); + + // calculate orientation orien of pcurves of Plate + // the curves from ic to icplus the pcurves of Plate + // all have the same orientation + Standard_Integer Ishape1,Ishape2; +#ifndef DEB + TopAbs_Orientation trafil1 = TopAbs_FORWARD, trafil2 = TopAbs_FORWARD; +#else + TopAbs_Orientation trafil1,trafil2; +#endif + Ishape1 = Fd->IndexOfS1(); + Ishape2 = Fd->IndexOfS2(); + const ChFiDS_FaceInterference& Fi1 = Fd->InterferenceOnS1(); + const ChFiDS_FaceInterference& Fi2 = Fd->InterferenceOnS2(); + if (Ishape1 != 0) { + if (Ishape1 > 0) { + trafil1 = DStr.Shape(Ishape1).Orientation(); + } + trafil1 = TopAbs::Compose(trafil1,Fd->Orientation()); + trafil1 = TopAbs::Compose(TopAbs::Reverse(Fi1.Transition()),trafil1); + trafil2 = TopAbs::Reverse(trafil1); + } + else { + if (Ishape2 > 0) { + trafil2 = DStr.Shape(Ishape2).Orientation(); + } + trafil2 = TopAbs::Compose(trafil2,Fd->Orientation()); + trafil2 = TopAbs::Compose(TopAbs::Reverse(Fi2.Transition()),trafil2); + trafil1 = TopAbs::Reverse(trafil2); + } + if (isfirst) { + orpcurve=TopAbs::Reverse(trafil1); + orpcurve= TopAbs::Compose(orpcurve,CD.Value(0)->FirstPCurveOrientation ()); } + else { + orpcurve=trafil1; + orpcurve= TopAbs::Compose(orpcurve,CD.Value(0)->LastPCurveOrientation ()); + } + if (orsurfdata==orplate) + orien =TopAbs::Reverse(orpcurve); + else orien=orpcurve; + + + if (!droit) + for (ic=0;ic<=nedge;ic++) { + if (libre.Value(ic)) { + Standard_Integer icplus21; + Indices(nedge,ic,icplus,icmoins); + Indices(nedge,icplus,icplus21,ic); + gp_Pnt2d UV1,UV2; + Handle (Geom_Curve) C3d; + Handle (Geom2d_Curve) C2d,curv2d; + gp_Pnt ptic,pticplus; + BRepAdaptor_Curve BCurv1(TopoDS::Edge(Evive.Value(ic))); + BRepAdaptor_Curve BCurv2(TopoDS::Edge(Evive.Value(icplus))); + Standard_Real par1=p.Value(ic,icplus); + Standard_Real par2=p.Value(icplus,ic); + BCurv1.D0(par1,ptic); + BCurv2.D0(par2,pticplus); + ParametrePlate(n3d,PSurf,Surf,ptic,apperror,UV1); + ParametrePlate(n3d,PSurf,Surf,pticplus,apperror,UV2); + Standard_Real to3d=1.e-3,to2d=1.e-6,tolreached; + ChFiDS_CommonPoint CP1,CP2; + CP1.SetArc(1.e-3, TopoDS::Edge(Evive.Value(ic)),par1,TopAbs_FORWARD); + CP1.SetPoint(ptic); + CP2.SetArc(1.e-3, TopoDS::Edge(Evive.Value(icplus)),par2,TopAbs_FORWARD); + CP2.SetPoint(pticplus); + Standard_Real param1,param2; + ChFi3d_ComputeArete( CP1,UV1,CP2,UV2,Surf,C3d,C2d,param1,param2, + to3d,to2d,tolreached,0); + TopOpeBRepDS_Curve tcurv3d( C3d,tolreached); + Standard_Integer ind1,ind2; + ind1=indpoint(ic,0); + ind2=indpoint(icplus,0); + Standard_Integer indcurv=DStr.AddCurve(tcurv3d); + Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurv,ind1,param1); + Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurv,ind2,param2); + DStr.ChangeCurveInterferences(indcurv).Append(Interfp1); + DStr.ChangeCurveInterferences(indcurv).Append(Interfp2); + Interfc=ChFi3d_FilCurveInDS(indcurv,Isurf,C2d,orien); + DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc); + } + } + + // stockage des courbes relatives aux stripes + n3d = 0; + for (ic=0; ic<nedge ;ic++) { + if (!sharp.Value(ic)) { + n3d++; + Indices(nedge,ic,icplus,icmoins); + + isfirst=(sens.Value(ic)==1); + // calculate curves interference relative to stripes + + apperror=Mapp.CriterionError()*coef; + pardeb=CD.Value(ic)->PCurve(isfirst)->FirstParameter(); + parfin=CD.Value(ic)->PCurve(isfirst)->LastParameter(); + + Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurve3d.Value(n3d), + indpoint.Value(ic,0),pardeb); + Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurve3d.Value(n3d), + indpoint.Value(ic,1),parfin); + DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append( Interfp1); + DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append( Interfp2); + TopOpeBRepDS_Curve& tcourb = DStr.ChangeCurve(indcurve3d.Value(n3d)); + + tcourb.Tolerance(errapp.Value(ic)+apperror); + TopOpeBRepDS_Point& tpt1= DStr.ChangePoint(indpoint(ic,0)); + TopOpeBRepDS_Point& tpt2= DStr.ChangePoint(indpoint(ic,1)); + tpt1.Tolerance (tpt1.Tolerance()+apperror); + tpt2.Tolerance (tpt2.Tolerance()+apperror ); + + // calculate surfaceinterference + Interfc=ChFi3d_FilCurveInDS(indcurve3d.Value(n3d),Isurf, + PSurf.Curves2d()->Value(n3d),orien); + DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc); + regular.SetCurve(indcurve3d.Value(n3d)); + regular.SetS1(Isurf,Standard_False); + indice=CD.Value(ic)->SetOfSurfData()->Value( i.Value(ic,icmoins))->Surf(); + regular.SetS2(indice,Standard_False); + myRegul.Append(regular); + } + } + + // storage of connection curves + + for (ic=0; ic<nedge;ic++) { + Indices(nedge,ic,icplus,icmoins); + if (!oksea.Value(ic)) { + if (sharp.Value(ic) &&!deuxconges) { + // limitation of the alive edge + TopAbs_Orientation ori; + gp_Pnt Pf,Pl,sommet1; + TopoDS_Vertex Vd = TopExp::FirstVertex(TopoDS::Edge(Evive.Value(ic))); + TopoDS_Vertex Vf = TopExp::LastVertex(TopoDS::Edge(Evive.Value(ic))); + Pf=BRep_Tool::Pnt(Vd); + Pl=BRep_Tool::Pnt(Vf); + sommet1=BRep_Tool::Pnt(V1); + if (Pf.Distance(sommet1)<Pl.Distance(sommet1)) + ori = TopAbs_FORWARD; + else + ori = TopAbs_REVERSED; + Standard_Integer Iarc1=DStr.AddShape(TopoDS::Edge(Evive.Value(ic))); + Interfp1=ChFi3d_FilPointInDS(ori,Iarc1,indpoint(ic,1),p.Value(ic,icplus)); + DStr.ChangeShapeInterferences(TopoDS::Edge(Evive.Value(ic))).Append(Interfp1); + } + + if (!ponctuel.Value(ic) && !libre.Value(ic)) { + // actual connection + if (!moresurf.Value(ic)){ + n3d++; + TopOpeBRepDS_Curve& tcourb1 = DStr.ChangeCurve(indcurve3d.Value(n3d)); + tcourb1.Tolerance(tcourb1.Tolerance()+apperror); + if (!deuxconges) { + TopOpeBRepDS_Point& tpt11= DStr.ChangePoint(indpoint(ic,1)); + TopOpeBRepDS_Point& tpt21= DStr.ChangePoint(indpoint(icplus,0)); + tpt11.Tolerance (tpt11.Tolerance()+apperror); + tpt21.Tolerance (tpt21.Tolerance()+apperror ); + } + Interfc=ChFi3d_FilCurveInDS(indcurve3d.Value(n3d),Isurf, + PSurf.Curves2d()->Value(n3d),orien); + DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc); + if( Order.Value(n3d)==1) { + regular.SetCurve(indcurve3d.Value(n3d)); + regular.SetS1(Isurf,Standard_False); + regular.SetS2(numfa.Value(ic,icplus)); + myRegul.Append(regular); + } + } + } + } + } + + //storage of curves projected on several faces + for (ic=0; ic<nedge;ic++) { + Indices(nedge,ic,icplus,icmoins); + if (moresurf(ic)) + for (nb=1;nb<=nbface;nb++){ + if (!Eproj.Value(nb).IsNull()) { + n3d++; + TopOpeBRepDS_Curve& tcourb1 = DStr.ChangeCurve(indcurve3d.Value(n3d)); + tcourb1.Tolerance(tcourb1.Tolerance()+apperror); + if(Indice.Value(n3d)!=0) { + TopOpeBRepDS_Point& tpt11= DStr.ChangePoint(Indice.Value(n3d)); + tpt11.Tolerance (tpt11.Tolerance()+apperror); + } + Interfc=ChFi3d_FilCurveInDS(indcurve3d.Value(n3d),Isurf, + PSurf.Curves2d()->Value(n3d),orien); + DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc); + if( Order.Value(n3d)==1) { + regular.SetCurve(indcurve3d.Value(n3d)); + regular.SetS1(Isurf,Standard_False); + regular.SetS2(DStr.AddShape(TopoDS::Face(Fproj.Value(nb)))); + myRegul.Append(regular); + } + } + } + } + + // storage of curves in case of tangent free borders + if (droit) + for (ic=0; ic<nedge;ic++) { + Indices(nedge,ic,icplus,icmoins); + TopoDS_Edge ecom; + ecom=TopoDS::Edge(Evive.Value(ic)); + if (ecom.IsSame(edgelibre1)||ecom.IsSame(edgelibre2)) { + n3d++; + TopOpeBRepDS_Curve& tcourb1 = DStr.ChangeCurve(indcurve3d.Value(n3d)); + tcourb1.Tolerance(tcourb1.Tolerance()+apperror); + Interfc=ChFi3d_FilCurveInDS(indcurve3d.Value(n3d),Isurf, + PSurf.Curves2d()->Value(n3d),orien); + DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc); + } + } + } + else { // there is only one partial result + done=Standard_False; + hasresult=Standard_True; + for (ic=0; ic<nedge;ic++) { + Indices(nedge,ic,icplus,icmoins); + if (!oksea.Value(ic)) { + if (sharp.Value(ic) &&!deuxconges) { + // limitation of the alive edge + TopAbs_Orientation ori; + gp_Pnt Pf,Pl,sommet1; + TopoDS_Vertex Vd = TopExp::FirstVertex(TopoDS::Edge(Evive.Value(ic))); + TopoDS_Vertex Vf = TopExp::LastVertex(TopoDS::Edge(Evive.Value(ic))); + Pf=BRep_Tool::Pnt(Vd); + Pl=BRep_Tool::Pnt(Vf); + sommet1=BRep_Tool::Pnt(V1); + if (Pf.Distance(sommet1)<Pl.Distance(sommet1)) + ori = TopAbs_FORWARD; + else + ori = TopAbs_REVERSED; + Standard_Integer Iarc1=DStr.AddShape(TopoDS::Edge(Evive.Value(ic))); + Interfp1=ChFi3d_FilPointInDS(ori,Iarc1,indpoint(ic,1),p.Value(ic,icplus)); + DStr.ChangeShapeInterferences(TopoDS::Edge(Evive.Value(ic))).Append(Interfp1); + } + } + } + } +} diff --git a/src/ChFi3d/ChFi3d_Builder_NotImp.cxx b/src/ChFi3d/ChFi3d_Builder_NotImp.cxx new file mode 100644 index 00000000..b7226e00 --- /dev/null +++ b/src/ChFi3d/ChFi3d_Builder_NotImp.cxx @@ -0,0 +1,229 @@ +// File: ChFi3d_Builder_NotImp.cxx +// Created: Mon May 18 16:35:34 1998 +// Author: Philippe NOUAILLE +// <pne@cleox.paris1.matra-dtv.fr> + + +#include <ChFi3d_Builder.jxx> + +//======================================================================= +//function : SimulSurf +//purpose : +//======================================================================= + +void ChFi3d_Builder::SimulSurf(Handle(ChFiDS_SurfData)& , + const Handle(ChFiDS_HElSpine)& , + const Handle(ChFiDS_Spine)& , + const Standard_Integer , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const TopAbs_Orientation , + const Standard_Real , + const Standard_Real , + Standard_Real& , + Standard_Real& , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const math_Vector& ) +{ + Standard_Failure::Raise("SimulSurf Not Implemented"); +} + +//======================================================================= +//function : SimulSurf +//purpose : +//======================================================================= + +void ChFi3d_Builder::SimulSurf(Handle(ChFiDS_SurfData)& , + const Handle(ChFiDS_HElSpine)& , + const Handle(ChFiDS_Spine)& , + const Standard_Integer , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const TopAbs_Orientation , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const Standard_Real , + const Standard_Real , + Standard_Real& , + Standard_Real& , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const math_Vector& ) +{ + Standard_Failure::Raise("SimulSurf Not Implemented"); +} + + +//======================================================================= +//function : SimulSurf +//purpose : +//======================================================================= + +void ChFi3d_Builder::SimulSurf(Handle(ChFiDS_SurfData)& , + const Handle(ChFiDS_HElSpine)& , + const Handle(ChFiDS_Spine)& , + const Standard_Integer , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const TopAbs_Orientation , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const TopAbs_Orientation , + const Standard_Real , + const Standard_Real , + Standard_Real& , + Standard_Real& , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const math_Vector& ) +{ + Standard_Failure::Raise("SimulSurf Not Implemented"); +} + + + +//======================================================================= +//function : PerformSurf +//purpose : +//======================================================================= + +void ChFi3d_Builder::PerformSurf(ChFiDS_SequenceOfSurfData& , + const Handle(ChFiDS_HElSpine)& , + const Handle(ChFiDS_Spine)& , + const Standard_Integer , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const TopAbs_Orientation , + const Standard_Real , + const Standard_Real , + const Standard_Real , + Standard_Real& , + Standard_Real& , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const math_Vector& ) +{ + Standard_Failure::Raise("PerformSurf Not Implemented"); +} + +//======================================================================= +//function : PerformSurf +//purpose : +//======================================================================= + +void ChFi3d_Builder::PerformSurf(ChFiDS_SequenceOfSurfData& , + const Handle(ChFiDS_HElSpine)& , + const Handle(ChFiDS_Spine)& , + const Standard_Integer , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const TopAbs_Orientation , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const Standard_Real , + const Standard_Real , + const Standard_Real , + Standard_Real& , + Standard_Real& , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const math_Vector& ) +{ + Standard_Failure::Raise("PerformSurf Not Implemented"); + +} + + + + + +//======================================================================= +//function : PerformSurf +//purpose : +//======================================================================= + +void ChFi3d_Builder::PerformSurf(ChFiDS_SequenceOfSurfData& , + const Handle(ChFiDS_HElSpine)& , + const Handle(ChFiDS_Spine)& , + const Standard_Integer , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const TopAbs_Orientation , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const TopAbs_Orientation , + const Standard_Real , + const Standard_Real , + const Standard_Real , + Standard_Real& , + Standard_Real& , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const math_Vector& ) +{ + Standard_Failure::Raise("PerformSurf Not Implemented"); + +} diff --git a/src/ChFi3d/ChFi3d_Builder_SpKP.cxx b/src/ChFi3d/ChFi3d_Builder_SpKP.cxx new file mode 100644 index 00000000..6d4ac674 --- /dev/null +++ b/src/ChFi3d/ChFi3d_Builder_SpKP.cxx @@ -0,0 +1,1179 @@ +// File: ChFi3d_Builder_SpKP.cxx +// Created: Thu Jan 20 14:41:30 1994 +// Author: Isabelle GRIGNON +// <isg@nonox> + +#include <Standard_NotImplemented.hxx> +#include <Precision.hxx> +#include <TColStd_SequenceOfInteger.hxx> +#include <TColStd_Array1OfInteger.hxx> +#include <TColStd_Array1OfReal.hxx> +#include <gp.hxx> +#include <gp_Pnt2d.hxx> +#include <gp_Dir2d.hxx> +#include <gp_Pnt.hxx> +#include <gp_Circ.hxx> +#include <TColgp_Array1OfPnt2d.hxx> +#include <ElCLib.hxx> +#include <ElSLib.hxx> +#include <Geom2d_Curve.hxx> +#include <Geom2d_Line.hxx> +#include <Geom2d_BezierCurve.hxx> +#include <Geom2d_BSplineCurve.hxx> +#include <Geom_Curve.hxx> +#include <Geom_Plane.hxx> +#include <Geom_Surface.hxx> +#include <GeomAbs_CurveType.hxx> +#include <GeomAbs_SurfaceType.hxx> +#include <GeomAdaptor_Curve.hxx> +#include <Geom2dAdaptor_Curve.hxx> +#include <Geom2dAdaptor_HCurve.hxx> + +#include <GeomAdaptor_HSurface.hxx> +#include <BRepAdaptor_Curve2d.hxx> +#include <BRepAdaptor_HCurve.hxx> +#include <BRepAdaptor_HCurve2d.hxx> +#include <BRep_Tool.hxx> +#include <HatchGen_PointOnElement.hxx> +#include <HatchGen_PointOnHatching.hxx> +#include <HatchGen_Domain.hxx> +#include <Geom2dHatch_Intersector.hxx> +#include <Geom2dHatch_Hatcher.hxx> + +#include <TopExp.hxx> +#include <TopoDS_Edge.hxx> + +#include <TopOpeBRepDS_Curve.hxx> +#include <TopOpeBRepDS_Surface.hxx> + +#include <ChFiKPart_RstMap.hxx> + +#include <ChFi3d_Builder.jxx> +#include <ChFi3d_Builder_0.hxx> +#ifdef DEB +extern Standard_Boolean ChFi3d_GettraceDRAWFIL(); +extern void ChFi3d_CheckSurfData(const TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_SurfData)& Data); +#endif +//======================================================================= +//function : CompTra +//purpose : Calculate the Transition from start point. +//======================================================================= + +static TopAbs_Orientation CompTra (const TopAbs_Orientation O1, + const TopAbs_Orientation O2, + const Standard_Boolean isfirst) +{ + if(isfirst) return TopAbs::Reverse(TopAbs::Compose(O1,O2)); + else return TopAbs::Compose(O1,O2); +} + + +//======================================================================= +//function : CompCommonpoint +//purpose : Fill the commonpoint in case of a vertex. +//======================================================================= + +static void CompCommonPoint (ChFiDS_CommonPoint& FilPoint, + const TopoDS_Edge& arc, + const HatchGen_PointOnElement& PE, + const TopAbs_Orientation Or) +{ + TopAbs_Orientation pos = PE.Position(); + TopoDS_Vertex V; + if ( pos == TopAbs_FORWARD ) { + V = TopExp::FirstVertex(arc); + } + else { + V = TopExp::LastVertex(arc); + } + FilPoint.SetVertex(V); + FilPoint.SetArc(Precision::PIntersection(),arc, + PE.Parameter(),TopAbs::Compose(arc.Orientation(),Or)); +} + + +//======================================================================= +//function : CpInterf +//purpose : Construct new SurfData sharing faces, surface and curves. +//======================================================================= + +static ChFiDS_FaceInterference CpInterf (TopOpeBRepDS_DataStructure& DStr, + const ChFiDS_FaceInterference& FI) +{ + ChFiDS_FaceInterference newF = FI; + const TopOpeBRepDS_Curve& toc = DStr.Curve(FI.LineIndex()); + Handle(Geom_Curve) newC; + if (!toc.Curve().IsNull()) + newC = Handle(Geom_Curve)::DownCast(toc.Curve()->Copy()); + newF.SetLineIndex(DStr.AddCurve(TopOpeBRepDS_Curve(newC,toc.Tolerance()))); + + if (!FI.PCurveOnFace().IsNull()) + newF.ChangePCurveOnFace() = + Handle(Geom2d_Curve)::DownCast(FI.PCurveOnFace()->Copy()); + if (!FI.PCurveOnSurf().IsNull()) + newF.ChangePCurveOnSurf() = + Handle(Geom2d_Curve)::DownCast(FI.PCurveOnSurf()->Copy()); + return newF; +} + + +//======================================================================= +//function : CpSD +//purpose : Construct new SurfData sharing faces, surface and curves. +//======================================================================= + +static Handle(ChFiDS_SurfData) CpSD ( TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_SurfData)& Data) +{ + Handle(ChFiDS_SurfData) newData = new ChFiDS_SurfData(); + const TopOpeBRepDS_Surface& tos = DStr.Surface(Data->Surf()); + Handle(Geom_Surface) newS = Handle(Geom_Surface)::DownCast(tos.Surface()->Copy()); + Standard_Real tol = tos.Tolerance(); + newData->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(newS,tol))); + newData->ChangeIndexOfS1(Data->IndexOfS1()); + newData->ChangeIndexOfS2(Data->IndexOfS2()); + newData->ChangeOrientation() = Data->Orientation(); + newData->ChangeInterferenceOnS1() = CpInterf(DStr,Data->InterferenceOnS1()); + newData->ChangeInterferenceOnS2() = CpInterf(DStr,Data->InterferenceOnS2()); + return newData; +} + +//======================================================================= +//function : AdjustParam +//purpose : +//======================================================================= + +static Standard_Boolean AdjustParam(const HatchGen_Domain& Dom, + Standard_Real& f, + Standard_Real& l, + const Standard_Real wref, + const Standard_Real period, + const Standard_Real pitol) +{ + if(Dom.HasFirstPoint()) + f = Dom.FirstPoint().Parameter(); + else f = 0.; + if(Dom.HasSecondPoint()) + l = Dom.SecondPoint().Parameter(); + else l = period; + if (period == 0.) return Standard_False; + + f = ElCLib::InPeriod(f,wref - pitol, wref + period - pitol); + l = ElCLib::InPeriod(l,wref + pitol, wref + period + pitol); + if (l < f) { + f -= period; + return Standard_True; + } + return Standard_False; +} +//======================================================================= +//function : ComputeAbscissa +//purpose : +//======================================================================= + +static Standard_Real ComputeAbscissa(const BRepAdaptor_Curve& C, + const Standard_Real U) +{ + switch (C.GetType()) { + case GeomAbs_Line: + return U; + case GeomAbs_Circle: + return C.Circle().Radius()*U; + default: + return 0; + } + Standard_NotImplemented::Raise("calculate abscisse non-processed"); + return 0.; +} + +//======================================================================= +//function : ParamOnSpine +//purpose : +//======================================================================= + +static Standard_Real ParamOnSpine(const TopOpeBRepDS_DataStructure& DStr, + const Standard_Real ptg, + const Handle(ChFiDS_SurfData)& CD, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer iedge, + const Standard_Boolean intf, + const Standard_Boolean intl, + const Standard_Real tol, + Standard_Boolean& pok) +{ + Standard_Real Nl; + Standard_Real f = Spine->FirstParameter(iedge); + Standard_Real l = Spine->LastParameter(iedge); + + Nl = ComputeAbscissa(Spine->CurrentElementarySpine(iedge),ptg) + f; + if ((Nl >= (f - tol) || intf) && + (Nl <= (l + tol) || intl) ) { + pok = 1; + return Nl; + } + else { + //construction of the plane containing the section of CD with parameter ptg. + gp_Pnt PP; + gp_Vec VV; + Handle(Geom_Curve) c3d; + if (CD->InterferenceOnS1().LineIndex() != 0) { + c3d = DStr.Curve(CD->InterferenceOnS1().LineIndex()).Curve(); + } + if(c3d.IsNull()) { + c3d = DStr.Curve(CD->InterferenceOnS2().LineIndex()).Curve(); + } + c3d->D1(ptg,PP,VV); + + gp_Pln nlp(PP,gp_Dir(VV)); + Handle(Geom_Plane) pln = new Geom_Plane(nlp); + Handle(GeomAdaptor_HSurface) + plan = new GeomAdaptor_HSurface(GeomAdaptor_Surface(pln)); + + // intersection plane spine. + Standard_Boolean found = Standard_False; + Standard_Boolean fini = Standard_False; + Standard_Integer sens = 1; + if (Nl <= f) sens = -1; + Standard_Integer ii = iedge + sens; + if (Spine->IsPeriodic()) { + if (ii <= 0) ii += Spine->NbEdges(); + if (ii > Spine->NbEdges()) ii -= Spine->NbEdges(); + } + else if(ii < 1 || ii > Spine->NbEdges()) { + pok = 1; + return Nl; + } + Handle(BRepAdaptor_HCurve) HE = new BRepAdaptor_HCurve(); + BRepAdaptor_Curve& CE = HE->ChangeCurve(); + + while (!found && !fini) { + TopAbs_Orientation O = Spine->Edges(ii).Orientation(); + Standard_Boolean First = ((O == TopAbs_FORWARD && sens == 1) || + (O == TopAbs_REVERSED && sens == -1)); + CE.Initialize(Spine->Edges(ii)); + Standard_Real tolc = CE.Resolution(tol); + found = ChFi3d_InterPlaneEdge(plan,HE,Nl,First,tolc); + gp_Pnt point = CE.Value(Nl); +#ifdef DEB + cout<<"******* ParamOnSpine() for edge "<<iedge<<endl; + cout<<Nl<<endl; + cout<<"point ped "<<point.X()<<" "<<point.Y()<<" "<<point.Z()<<endl; +#endif + if(found) Nl = Spine->Absc(Nl,ii); + point = Spine->Value(Nl); +#ifdef DEB + if (found) cout << "found by edge " << ii << " : "; + cout<<Nl<<endl; + cout<<"point psp "<<point.X()<<" "<<point.Y()<<" "<<point.Z()<<endl; + cout<<endl; +#endif + + ii +=sens; + if (Spine->IsPeriodic()) { + if (ii <= 0) ii += Spine->NbEdges(); + if (ii > Spine->NbEdges()) ii -= Spine->NbEdges(); + fini = (ii == iedge); + } + else { + fini = (ii < 1 || ii > Spine->NbEdges()); + } + } + pok = found; + return Nl; + } +} + +//======================================================================= +//function : YaUnVoisin +//purpose : +//======================================================================= + +static Standard_Boolean YaUnVoisin(const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer iedge, + Standard_Integer& ivois, + const Standard_Boolean isfirst) +{ + Standard_Integer nbed = Spine->NbEdges(); + if(nbed == 1) return 0; + Standard_Boolean periodic = Spine->IsPeriodic(); + if(isfirst) ivois = iedge - 1; + else ivois = iedge + 1; + if(periodic) { + if(ivois == 0) ivois = nbed; + if(ivois == nbed+1) ivois = 1; + } + return (ivois > 0 && ivois <= nbed); +} + +//======================================================================= +//function : Trunc +//purpose : +//======================================================================= + +void ChFi3d_Builder::Trunc(const Handle(ChFiDS_SurfData)& SD, + const Handle(ChFiDS_Spine)& Spine, + const Handle(Adaptor3d_HSurface)& S1, + const Handle(Adaptor3d_HSurface)& S2, + const Standard_Integer iedge, + const Standard_Boolean isfirst, + const Standard_Integer cntlFiOnS) +{ + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + // Return points and tangents on edge and spine. + Standard_Real wtg = SD->InterferenceOnS1().Parameter(isfirst); + Standard_Boolean bid; + Standard_Real wsp = ParamOnSpine(DStr,wtg,SD,Spine,iedge,0,0,tolesp,bid); + gp_Pnt ped,psp; + gp_Vec ded,dsp; + TopoDS_Vertex bout1,bout2,boutemp; + + + const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(iedge); +//Modif against Vertex isolated on spine + TopoDS_Edge support = bc.Edge(); + TopExp::Vertices(support,bout1,bout2); + if (support.Orientation() == TopAbs_REVERSED) { + boutemp = bout2; + bout2 = bout1; + bout1 = boutemp; + } + if (!isfirst) { + bout1 = bout2; + } +//finmodif + Standard_Real edf = bc.FirstParameter(), edl = bc.LastParameter(); + Standard_Real edglen = edl - edf; + if(Spine->Edges(iedge).Orientation() == TopAbs_FORWARD) { + bc.D1(wtg+edf,ped,ded); + } + else{ + bc.D1(-wtg+edl,ped,ded); + ded.Reverse(); + } + Spine->D1(wsp,psp,dsp); + gp_Pnt p1,p2; + const Handle(Geom_Surface)& surf = DStr.Surface(SD->Surf()).Surface(); + gp_Pnt2d pp1,pp2; + pp1 = SD->InterferenceOnS1().PCurveOnSurf()->Value(wtg); + pp2 = SD->InterferenceOnS2().PCurveOnSurf()->Value(wtg); + p1 = surf->Value(pp1.X(),pp1.Y()); + p2 = surf->Value(pp2.X(),pp2.Y()); + Standard_Boolean tron = Standard_False; + Standard_Real Ang = dsp.Angle(ded); + Standard_Real dis1 = psp.Distance(ped); + Standard_Real dis2 = p1.Distance(p2); + if(Ang > PI/18.) tron = Standard_True; + if(dis1 >= 0.1*dis2) tron = Standard_True; + Standard_Integer ivois; + if(!tron && YaUnVoisin(Spine,iedge,ivois,isfirst)) { + Handle(BRepAdaptor_HSurface) BS1 = Handle(BRepAdaptor_HSurface)::DownCast(S1); + Handle(BRepAdaptor_HSurface) BS2 = Handle(BRepAdaptor_HSurface)::DownCast(S2); + if(!BS1.IsNull() && !BS2.IsNull()) { + TopoDS_Face FBID; + TopoDS_Face F1 = BS1->ChangeSurface().Face(); + TopoDS_Face F2 = BS2->ChangeSurface().Face(); + const ChFiDS_CommonPoint& cp1 = SD->Vertex(isfirst,1); + const ChFiDS_CommonPoint& cp2 = SD->Vertex(isfirst,2); + if(!(cp1.IsOnArc() && SearchFace(Spine,cp1,F1,FBID) || + cp2.IsOnArc() && SearchFace(Spine,cp2,F2,FBID))) { + tron = ChFi3d_KParticular(Spine,ivois,BS1->ChangeSurface(),BS2->ChangeSurface()); + } + } + } + //modification of lvt against isolated vertex + if(!tron && YaUnVoisin(Spine,iedge,ivois,isfirst)) { + TopTools_ListIteratorOfListOfShape It; + Standard_Integer nbed = -2; + for (It.Initialize(myVEMap(bout1));It.More();It.Next()) { + nbed++; + } + if(nbed<3) tron = Standard_True; + } +//finmodif + + if(tron) { + Standard_Real par = 0., x, y, dPar=0; + if(!isfirst) par = edglen; + if (cntlFiOnS) { + // detect the case where FaceInterference ends before the place we are + // going to truncate SD. Then we cut so that FaceInterference length to + // be at least zero, not negative (eap, occ354) + Standard_Real fiPar = SD->Interference(cntlFiOnS).Parameter(!isfirst); + Standard_Boolean isTheCase = isfirst ? (par > fiPar) : (par < fiPar); + if (isTheCase) { + dPar = par - fiPar; + par = fiPar; + } + } + for (Standard_Integer i = 1; i <= 2; i++) { + SD->ChangeInterference(i).SetParameter(par,isfirst); + Handle(Geom2d_Curve) pc = SD->Interference(i).PCurveOnSurf(); + pc->Value(par).Coord(x,y); + SD->ChangeVertex(isfirst,i).Reset(); + SD->ChangeVertex(isfirst,i).SetPoint(surf->Value(x,y)); + if(isfirst) SD->FirstSpineParam(Spine->FirstParameter(iedge)-dPar); + else SD->LastSpineParam (Spine->LastParameter(iedge) -dPar); + } + } +} + +//======================================================================= +//function : ResetProl +//purpose : +//======================================================================= + +static Standard_Real ResetProl(const TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_SurfData)& CD, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer iedge, + const Standard_Boolean isfirst) +{ + const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(iedge); + Standard_Real edglen = bc.LastParameter() - bc.FirstParameter(); + const Handle(Geom_Surface)& surf = DStr.Surface(CD->Surf()).Surface(); + Standard_Real par = 0., x, y; + if(!isfirst) par = edglen; + Standard_Real sppar; + for (Standard_Integer i = 1; i <= 2; i++) { + CD->ChangeInterference(i).SetParameter(par,isfirst); + Handle(Geom2d_Curve) pc = CD->Interference(i).PCurveOnSurf(); + pc->Value(par).Coord(x,y); + CD->ChangeVertex(isfirst,i).Reset(); + CD->ChangeVertex(isfirst,i).SetPoint(surf->Value(x,y)); + if(isfirst) { + sppar = Spine->FirstParameter(iedge); + CD->FirstSpineParam(sppar); + } + else{ + sppar = Spine->LastParameter(iedge); + CD->LastSpineParam (sppar); + } + } + return sppar; +} +//======================================================================= +//function : Tri +//purpose : +//======================================================================= + +static Standard_Boolean Tri(const Geom2dHatch_Hatcher& H, + const Standard_Integer iH, + TColStd_Array1OfInteger& Ind, + const Standard_Real wref, + const Standard_Real period, + const Standard_Real pitol, + Standard_Integer& Nbdom) +{ +// for (Standard_Integer i = 1; i <= Nbdom; i++) { Ind(i) = i; } + Standard_Integer i; + for ( i = 1; i <= Nbdom; i++) { Ind(i) = i; } + Standard_Real f1,f2,l; + Standard_Integer tmp; + Standard_Boolean Invert = Standard_True; + + while (Invert) { + Invert = Standard_False; + for ( i = 1; i < Nbdom; i++) { + AdjustParam(H.Domain(iH,Ind(i)),f1,l,wref,period,pitol); + AdjustParam(H.Domain(iH,Ind(i+1)),f2,l,wref,period,pitol); + if ( f2 < f1) { + tmp = Ind(i); + Ind(i) = Ind(i+1); + Ind(i+1) = tmp; + Invert = Standard_True; + } + } + } + + Standard_Integer iSansFirst = 0, iSansLast = 0; + + if (Nbdom != 1) { + for ( i = 1; i <= Nbdom; i++) { + if (!H.Domain(iH,Ind(i)).HasFirstPoint()) { + iSansFirst = i; + } + if (!H.Domain(iH,Ind(i)).HasSecondPoint()) { + iSansLast = i; + } + } + } + if (iSansFirst != 0) { + if (iSansLast == 0) { +#ifdef DEB + cout<<"Parsing : Pb of Hatcher"<<endl; +#endif + return 0; + } + HatchGen_Domain* Dom = ((HatchGen_Domain*) (void*) &H.Domain(iH,Ind(iSansFirst))); + HatchGen_PointOnHatching* PH = + ((HatchGen_PointOnHatching*) (void*) &H.Domain(iH,Ind(iSansLast)).FirstPoint()); + Standard_Real NewPar = H.HatchingCurve(iH).FirstParameter() - period + + H.Domain(iH,Ind(iSansLast)).FirstPoint().Parameter(); + PH->SetParameter(NewPar); + Dom->SetFirstPoint(*PH); + + for (Standard_Integer k = iSansLast; k < Nbdom; k++) { + Ind(k) = Ind(k+1); + } + Nbdom--; + } + return 1; +} + +//======================================================================= +//function : FillSD +//purpose : +//======================================================================= + +static void FillSD (TopOpeBRepDS_DataStructure& DStr, + Handle(ChFiDS_SurfData)& CD, + ChFiKPart_RstMap& M, + const HatchGen_Domain& Dom, + const Standard_Real ponH, + const Standard_Boolean isFirst, + const Standard_Integer ons, + const Standard_Real pitol, + const TopoDS_Vertex bout) + +{ + Standard_Integer opp = 3 - ons; + ChFiDS_CommonPoint& Pons = CD->ChangeVertex(isFirst,ons); + ChFiDS_CommonPoint& Popp = CD->ChangeVertex(isFirst,opp); + + const HatchGen_PointOnHatching* pPH = 0; + if(isFirst && Dom.HasFirstPoint()) { + const HatchGen_PointOnHatching& PHtemp = Dom.FirstPoint(); + pPH = &PHtemp; + } + else if(!isFirst && Dom.HasSecondPoint()) { + const HatchGen_PointOnHatching& PHtemp = Dom.SecondPoint(); + pPH = &PHtemp; + } + Standard_Real x,y; + Handle(Geom_Surface) Surf = DStr.Surface(CD->Surf()).Surface(); + if(pPH == 0) { + CD->ChangeInterference(ons).SetParameter(ponH,isFirst); + Handle(Geom2d_Curve) pcons = CD->Interference(ons).PCurveOnSurf(); + pcons->Value(ponH).Coord(x,y); + CD->ChangeVertex(isFirst,ons).SetPoint(Surf->Value(x,y)); + } + else { +//Modification to find already existing vertexes + Standard_Integer LeType = 1; + Standard_Integer NbInt = pPH->NbPoints(); + if (NbInt>1) { + Standard_Boolean trouve = Standard_True; + Standard_Integer IE; + TopoDS_Vertex V1 , V2; + Standard_Boolean suite = Standard_True; + for(;trouve;) { + const HatchGen_PointOnElement& PEtemp = pPH->Point(LeType); + IE = PEtemp.Index(); + Handle(BRepAdaptor_HCurve2d) HE = Handle(BRepAdaptor_HCurve2d::DownCast(M(IE))); + if(!HE.IsNull()) { + const TopoDS_Edge& Etemp = HE->ChangeCurve2d().Edge(); + TopExp::Vertices(Etemp,V1,V2); + } + else { + suite = Standard_False; + } + if(((V1.IsSame(bout)) || (V2.IsSame(bout))) && suite) { + trouve = Standard_True; + break; + } + else { + suite = Standard_True; + trouve = Standard_False; + LeType++; + if(LeType>NbInt) { + trouve = Standard_True; + LeType = 1; + } + } + } + } + const HatchGen_PointOnElement& PE = pPH->Point(LeType); + Standard_Integer IE = PE.Index(); + Handle(BRepAdaptor_HCurve2d) + HE = Handle(BRepAdaptor_HCurve2d)::DownCast(M(IE)); + if(HE.IsNull()) return; + const TopoDS_Edge& E = HE->ChangeCurve2d().Edge(); + + if (PE.Position() != TopAbs_INTERNAL) { + TopAbs_Orientation O = CD->Interference(ons).Transition(); + if(isFirst) O = TopAbs::Reverse(O); + CompCommonPoint(Pons,E,PE,O); + } + else{ + Pons.SetArc(pitol,E,PE.Parameter(), + CompTra(CD->Interference(ons).Transition(),E.Orientation(),isFirst)); + } + Handle(Geom2d_Curve) pcadj = CD->Interference(ons).PCurveOnSurf(); + pcadj->Value(ponH).Coord(x,y); + CD->ChangeInterference(ons).SetParameter(ponH,isFirst); + CD->ChangeVertex(isFirst,ons).SetPoint(Surf->Value(x,y)); + } + if(!Popp.IsOnArc()) { + CD->ChangeInterference(opp).SetParameter(ponH,isFirst); + Handle(Geom2d_Curve) pcopp = CD->Interference(opp).PCurveOnSurf(); + pcopp->Value(ponH).Coord(x,y); + CD->ChangeVertex(isFirst,opp).SetPoint(Surf->Value(x,y)); + } +} + +//======================================================================= +//function : SplitKPart +//purpose : Reconstruct SurfData depending on restrictions of faces. +//======================================================================= + +Standard_Boolean ChFi3d_Builder::SplitKPart + (const Handle(ChFiDS_SurfData)& Data, + ChFiDS_SequenceOfSurfData& SetData, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer Iedge, + const Handle(Adaptor3d_HSurface)& S1, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(Adaptor3d_HSurface)& S2, + const Handle(Adaptor3d_TopolTool)& I2, + Standard_Boolean& intf, + Standard_Boolean& intl) +{ + //The the hatching of each faces is started by tangency lines. + + Standard_Real pitol = Precision::PIntersection(); + + ChFiKPart_RstMap M1, M2; +#ifndef DEB + Standard_Integer iH1 = 0,iH2 = 0; +#else + Standard_Integer iH1,iH2; +#endif + Standard_Integer Nb1 = 1,Nb2 = 1; + + // Cutting of tangency lines (hatching). + Geom2dHatch_Intersector Inter(pitol,pitol); + Geom2dHatch_Hatcher H1(Inter,tol2d,tolesp), H2(Inter,tol2d,tolesp); + Standard_Integer ie; + Handle(Geom2d_Curve) C1 = Data->InterferenceOnS1().PCurveOnFace(); + Geom2dAdaptor_Curve ll1; + if (!C1.IsNull()) { + ll1.Load(C1); + for(I1->Init(); I1->More(); I1->Next()) { + Handle(BRepAdaptor_HCurve2d) + Bc = Handle(BRepAdaptor_HCurve2d)::DownCast(I1->Value()); + Handle(Geom2dAdaptor_HCurve) + Gc = Handle(Geom2dAdaptor_HCurve)::DownCast(I1->Value()); + if(Bc.IsNull()) ie = H1.AddElement(Gc->ChangeCurve2d(),TopAbs_FORWARD); + else ie = H1.AddElement(Bc->ChangeCurve2d(), + Bc->ChangeCurve2d().Edge().Orientation()); + M1.Bind(ie,I1->Value()); + } + iH1 = H1.Trim(ll1); + H1.ComputeDomains(iH1); + if(!H1.IsDone(iH1)) return 0; + Nb1 = H1.NbDomains(iH1); + if(Nb1 == 0) { +#ifdef DEB + cout<<"SplitKPart : tangency line out of the face"<<endl; +#endif + return Standard_False; + } + } + + Handle(Geom2d_Curve) C2 = Data->InterferenceOnS2().PCurveOnFace(); + Geom2dAdaptor_Curve ll2; + if (!C2.IsNull()) { + ll2.Load(C2); + for(I2->Init(); I2->More(); I2->Next()) { + Handle(BRepAdaptor_HCurve2d) + Bc = Handle(BRepAdaptor_HCurve2d)::DownCast(I2->Value()); + Handle(Geom2dAdaptor_HCurve) + Gc = Handle(Geom2dAdaptor_HCurve)::DownCast(I2->Value()); + if(Bc.IsNull()) ie = H2.AddElement(Gc->ChangeCurve2d(),TopAbs_FORWARD); + else ie = H2.AddElement(Bc->ChangeCurve2d(), + Bc->ChangeCurve2d().Edge().Orientation()); + M2.Bind(ie,I2->Value()); + } + iH2 = H2.Trim(ll2); + H2.ComputeDomains(iH2); + if(!H2.IsDone(iH2)) return 0; + Nb2 = H2.NbDomains(iH2); + if(Nb2 == 0) { +#ifdef DEB + cout<<"SplitKPart : tangency line out of the face"<<endl; +#endif + return Standard_False; + } + } + + //Return start and end vertexes of the Spine + TopoDS_Vertex bout1,bout2,boutemp; + const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(Iedge); + TopoDS_Edge support = bc.Edge(); + TopExp::Vertices(support,bout1,bout2); + if(support.Orientation() == TopAbs_REVERSED) { + boutemp = bout2; + bout2 = bout1; + bout1 = boutemp; + } + + // Return faces. + TopoDS_Face F1, F2; + Handle(BRepAdaptor_HSurface) + bhs = Handle(BRepAdaptor_HSurface)::DownCast(S1); + if(!bhs.IsNull()) F1 = bhs->ChangeSurface().Face(); + bhs = Handle(BRepAdaptor_HSurface)::DownCast(S2); + if(!bhs.IsNull()) F2 = bhs->ChangeSurface().Face(); + TopoDS_Face FBID; + + // Restriction of SurfDatas by cut lines. + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + Handle(ChFiDS_SurfData) CD = Data; + CD->ChangeIndexOfS1(DStr.AddShape(F1)); + CD->ChangeIndexOfS2(DStr.AddShape(F2)); + + Standard_Real f1,l1,f2,l2; + TColStd_Array1OfInteger Ind1(1,Nb1), Ind2(1,Nb2); + Standard_Real wref = 0.; + + Standard_Integer onS = 1; // switcher of access to surfs of SurfData, eap occ293 + Standard_Integer cntlFiOnS = 0; // FaceInterference to control length in OnSame + // situation, eap occ354 + + if (C1.IsNull() && C2.IsNull()) { +#ifdef DEB + cout<<"SplitData : 2 zero lines hatching impossible"<<endl; +#endif + return Standard_False; + } + else if (C1.IsNull() || (Nb1 == 1 && !H1.Domain(iH1,1).HasFirstPoint())) { + // It is checked if the point 2d of the degenerated edge is in the face. + if (C1.IsNull()) { + gp_Pnt2d p2d1 = CD->Get2dPoints(0,1); + TopAbs_State situ = I1->Classify(p2d1,1.e-8,0); + if(situ == TopAbs_OUT) return Standard_False; + } + + // Parsing of domains by increasing parameters, + if(!Tri(H2,iH2,Ind2,wref,0.,pitol,Nb2)) return 0; + // Filling of SurfData + for(Standard_Integer i = 1; i <= Nb2; i++) { + const HatchGen_Domain& Dom2 = H2.Domain(iH2,Ind2(i)); + FillSD(DStr,CD,M2,Dom2,Dom2.FirstPoint().Parameter(),1,2,pitol,bout1); + FillSD(DStr,CD,M2,Dom2,Dom2.SecondPoint().Parameter(),0,2,pitol,bout2); + SetData.Append(CD); + CD = CpSD(DStr,CD); + } + if(intf) { + Handle(ChFiDS_SurfData)& sd = SetData.ChangeValue(1); + ChFiDS_CommonPoint& CP2 = sd->ChangeVertexFirstOnS2(); + if(CP2.IsOnArc() && Spine->FirstStatus() == ChFiDS_OnSame) { + intf = !SearchFace(Spine,CP2,F2,FBID); + } + else intf = Standard_False; + } + if(intl) { + Handle(ChFiDS_SurfData)& sd = SetData.ChangeValue(SetData.Length()); + ChFiDS_CommonPoint& CP2 = sd->ChangeVertexLastOnS2(); + if(CP2.IsOnArc() && Spine->LastStatus() == ChFiDS_OnSame) { + intl = !SearchFace(Spine,CP2,F2,FBID); + } + else intl = Standard_False; + } + } + else if (C2.IsNull() || (Nb2 == 1 && !H2.Domain(iH2,1).HasFirstPoint())) { + // It is checked if the point 2d of the degenerated is in the face. + if (C2.IsNull()) { + gp_Pnt2d p2d2 = CD->Get2dPoints(0,2); + TopAbs_State situ = I2->Classify(p2d2,1.e-8,0); + if(situ == TopAbs_OUT) return Standard_False; + } + + // Parsing of domains by increasing parameters, + if(!Tri(H1,iH1,Ind1,wref,0.,pitol,Nb1)) return 0; + // Filling of SurfData + for(Standard_Integer i = 1; i <= Nb1; i++) { + const HatchGen_Domain& Dom1 = H1.Domain(iH1,Ind1(i)); + FillSD(DStr,CD,M1,Dom1,Dom1.FirstPoint().Parameter(),1,1,pitol,bout1); + FillSD(DStr,CD,M1,Dom1,Dom1.SecondPoint().Parameter(),0,1,pitol,bout2); + SetData.Append(CD); + CD = CpSD(DStr,CD); + } + if(intf) { + Handle(ChFiDS_SurfData)& sd = SetData.ChangeValue(1); + ChFiDS_CommonPoint& CP1 = sd->ChangeVertexFirstOnS1(); + if(CP1.IsOnArc() && Spine->FirstStatus() == ChFiDS_OnSame) { + intf = !SearchFace(Spine,CP1,F1,FBID); + } + else intf = Standard_False; + } + if(intl) { + Handle(ChFiDS_SurfData)& sd = SetData.ChangeValue(SetData.Length()); + ChFiDS_CommonPoint& CP1 = sd->ChangeVertexLastOnS1(); + if(CP1.IsOnArc() && Spine->LastStatus() == ChFiDS_OnSame) { + intl = !SearchFace(Spine,CP1,F1,FBID); + } + else intl = Standard_False; + } + } + else { + + // Parsing of domains by increasing parameters, + // if there is a 2d circle on a plane, one goes on 2D line of opposite face. + Standard_Real period1 = 0., period2 = 0.; + if(ll1.IsPeriodic()) { + if(!Tri(H2,iH2,Ind2,wref,0.,pitol,Nb2)) return 0; + period1 = ll1.Period(); + if(!Tri(H1,iH1,Ind1,wref,period1,pitol,Nb1)) return 0; + } + else{ + if(!Tri(H1,iH1,Ind1,wref,0.,pitol,Nb1)) return 0; + if(ll2.IsPeriodic()) { period2 = ll2.Period(); } + if(!Tri(H2,iH2,Ind2,wref,period2,pitol,Nb2)) return 0; + } + + + // Filling of SurfData + TColStd_SequenceOfInteger ion1, ion2; + for(Standard_Integer i = 1; i <= Nb1; i++) { + const HatchGen_Domain& Dom1 = H1.Domain(iH1,Ind1(i)); + Standard_Integer nbcoup1 = 1; + Standard_Boolean acheval1 = AdjustParam(Dom1,f1,l1,wref,period1,pitol); + if(acheval1) nbcoup1 = 2; + for (Standard_Integer icoup1 = 1; icoup1 <= nbcoup1; icoup1++) { + for(Standard_Integer j = 1; j <= Nb2; j++) { + const HatchGen_Domain& Dom2 = H2.Domain(iH2,j); + Standard_Integer nbcoup2 = 1; + Standard_Boolean acheval2 = + AdjustParam(Dom2,f2,l2,wref,period2,pitol); + if(acheval2) nbcoup2 = 2; + for (Standard_Integer icoup2 = 1; icoup2 <= nbcoup2; icoup2++) { + if(f2 <= l1 && f1 <= l2) { + if (f1 >= f2 - tol2d) + FillSD(DStr,CD,M1,Dom1,f1,1,1,pitol,bout1); + if (f2 >= f1 - tol2d) + FillSD(DStr,CD,M2,Dom2,f2,1,2,pitol,bout1); + if (l1 >= l2 - tol2d) + FillSD(DStr,CD,M2,Dom2,l2,0,2,pitol,bout2); + if (l2 >= l1 - tol2d) + FillSD(DStr,CD,M1,Dom1,l1,0,1,pitol,bout2); + SetData.Append(CD); + CD = CpSD(DStr,CD); + ion1.Append(i); + ion2.Append(j); + } + f2 += period2; + l2 += period2; + } + } + f1 += period1; + l1 += period1; + } + } + + // Processing of extensions. + // Do not truncate, otherwise, problems of intersection for PerformCorner + // ----------------------------------------------------------------- + // After call of SplitKPart in PerformSetOfKPart, spines have been + // extended to the extremities by methods Extent to permit + // intersections. Extensions of SurfData are preserved. + + if(intf) { + // We are at the beginning of the spine + //------------------------- + Standard_Integer ifirst = 0; + Standard_Real dist = RealLast(), ptg, dsp; + const BRepAdaptor_Curve& ed = Spine->CurrentElementarySpine(Iedge); + for (Standard_Integer i1 = 1; i1 <= SetData.Length(); i1++) { + Handle(ChFiDS_SurfData)& CD1 = SetData.ChangeValue(i1); + ChFiDS_CommonPoint& CP1 = CD1->ChangeVertexFirstOnS1(); + ChFiDS_CommonPoint& CP2 = CD1->ChangeVertexFirstOnS2(); + if(CP1.IsOnArc()&&!SearchFace(Spine,CP1,F1,FBID)) { + ptg = CD1->InterferenceOnS1().FirstParameter(); + dsp = ComputeAbscissa(ed,ptg); + if(Abs(dsp) < dist) { + ifirst = i1; + dist = Abs(dsp); + } + } + else if(CP2.IsOnArc()&&!SearchFace(Spine,CP2,F2,FBID)) { + ptg = CD1->InterferenceOnS2().FirstParameter(); + dsp = ComputeAbscissa(ed,ptg); + if(Abs(dsp) < dist) { + ifirst = i1; + dist = Abs(dsp); + } + } + } + if (ifirst>1) { + SetData.Remove(1,ifirst-1); + ion1.Remove(1,ifirst-1); + ion2.Remove(1,ifirst-1); + } + if(SetData.IsEmpty()) return Standard_False; + Handle(ChFiDS_SurfData)& CD2 = SetData.ChangeValue(1); + ChFiDS_CommonPoint& CP1 = CD2->ChangeVertexFirstOnS1(); + ChFiDS_CommonPoint& CP2 = CD2->ChangeVertexFirstOnS2(); + ChFiDS_CommonPoint sov; + + if(CP1.IsOnArc() && CP2.IsOnArc()) { + intf = !SearchFace(Spine,CP1,F1,FBID) && !SearchFace(Spine,CP2,F2,FBID); + } + else if(CP1.IsOnArc()) { + sov = CP2; + if(!SearchFace(Spine,CP1,F1,FBID)) { + FillSD(DStr,CD2,M2,H2.Domain(iH2,Ind2(ion2.First())), + H2.Domain(iH2,Ind2(ion2.First())).FirstPoint().Parameter(),1,2,pitol,bout1); + if(!CP2.IsOnArc() || (CP2.IsOnArc() && SearchFace(Spine,CP2,F2,FBID))) { + CP2 = sov; + if(Spine->FirstStatus() != ChFiDS_OnSame) { + CD2->ChangeInterference(2). + SetParameter(CD2->Interference(1).Parameter(1),1); + intf = Standard_False; + } + } + } + else intf = Standard_False; + } + else if(CP2.IsOnArc()) { + sov = CP1; + if(!SearchFace(Spine,CP2,F2,FBID)) { + FillSD(DStr,CD2,M1,H1.Domain(iH1,Ind1(ion1.First())), + H1.Domain(iH1,Ind1(ion1.First())).FirstPoint().Parameter(),1,1,pitol,bout1); + if(!CP1.IsOnArc() || (CP1.IsOnArc() && SearchFace(Spine,CP1,F1,FBID))) { + CP1 = sov; + if(Spine->FirstStatus() != ChFiDS_OnSame) { + CD2->ChangeInterference(1). + SetParameter(CD2->Interference(2).Parameter(1),1); + intf = Standard_False; + } + } + } + else intf = Standard_False; + } + // select <onS> switcher so that to get on spine params from + // Interference with a face where both edges at corner are OnSame + // eap occ293 + if (intf && Spine->FirstStatus() == ChFiDS_OnSame) { + TopoDS_Edge threeE[3]; + ChFi3d_cherche_element(bout1,support,F1,threeE[0],boutemp); + ChFi3d_cherche_element(bout1,support,F2,threeE[1],boutemp); + threeE[2] = support; + if (ChFi3d_EdgeState(threeE,myEFMap) == ChFiDS_OnSame) + onS = 1; + else + onS = 2; +#ifdef DEB + if (threeE[0].IsSame(threeE[1])) + cout << "SplitKPart(), wrong corner vertex at switcher search" << endl; +#endif + cntlFiOnS = 3 - onS; + } + } + if(intl) { + // we are at the end of the spine + //----------------------- + Standard_Integer ilast = 0; + Standard_Real dist = RealLast(), ptg, dsp; + Standard_Real f = Spine->FirstParameter(Iedge); + Standard_Real l = Spine->LastParameter(Iedge); + const BRepAdaptor_Curve& ed = Spine->CurrentElementarySpine(Iedge); + for (Standard_Integer i2 = 1; i2<= SetData.Length(); i2++) { + Handle(ChFiDS_SurfData)& CD3 = SetData.ChangeValue(i2); + ChFiDS_CommonPoint& CP1 = CD3->ChangeVertexLastOnS1(); + ChFiDS_CommonPoint& CP2 = CD3->ChangeVertexLastOnS2(); + if(CP1.IsOnArc()&&!SearchFace(Spine,CP1,F1,FBID)) { + ptg = CD3->InterferenceOnS1().LastParameter(); + dsp = -ComputeAbscissa(ed,ptg) - f + l; + if(Abs(dsp) < dist) { + ilast = i2; + dist = Abs(dsp); + } + } + else if(CP2.IsOnArc()&&!SearchFace(Spine,CP2,F2,FBID)) { + ptg = CD3->InterferenceOnS2().LastParameter(); + dsp = -ComputeAbscissa(ed,ptg) - f + l; + if(Abs(dsp) < dist) { + ilast = i2; + dist = Abs(dsp); + } + } + } + Standard_Integer lll = SetData.Length(); + if (ilast<lll) { + SetData.Remove(ilast+1, lll); + ion1.Remove(ilast+1, lll); + ion2.Remove(ilast+1, lll); + } + if(SetData.IsEmpty()) return Standard_False; + Handle(ChFiDS_SurfData)& CD4 = SetData.ChangeValue(SetData.Length()); + ChFiDS_CommonPoint& CP1 = CD4->ChangeVertexLastOnS1(); + ChFiDS_CommonPoint& CP2 = CD4->ChangeVertexLastOnS2(); + ChFiDS_CommonPoint sov; + if(CP1.IsOnArc() && CP2.IsOnArc()) { + intl = !SearchFace(Spine,CP1,F1,FBID) && !SearchFace(Spine,CP2,F2,FBID); + } + else if(CP1.IsOnArc()) { + sov = CP2; + if(!SearchFace(Spine,CP1,F1,FBID)) { + FillSD(DStr,CD4,M2,H2.Domain(iH2,Ind2(ion2.Last())), + H2.Domain(iH2,Ind2(ion2.Last())).SecondPoint().Parameter(),0,2,pitol,bout2); + if(!CP2.IsOnArc() || (CP2.IsOnArc() && SearchFace(Spine,CP2,F2,FBID))) { + CP2 = sov; + if(Spine->LastStatus() != ChFiDS_OnSame) { + CD4->ChangeInterference(2). + SetParameter(CD4->Interference(1).Parameter(0),0); + intl = Standard_False; + } + } + } + else intl = Standard_False; + } + else if(CP2.IsOnArc()) { + sov = CP1; + if(!SearchFace(Spine,CP2,F2,FBID)) { + FillSD(DStr,CD4,M1,H1.Domain(iH1,Ind1(ion1.Last())), + H1.Domain(iH1,Ind1(ion1.Last())).SecondPoint().Parameter(),0,1,pitol,bout2); + if(!CP1.IsOnArc() || (CP1.IsOnArc() && SearchFace(Spine,CP1,F1,FBID))) { + CP1 = sov; + if(Spine->LastStatus() != ChFiDS_OnSame) { + CD4->ChangeInterference(1). + SetParameter(CD4->Interference(2).Parameter(0),0); + intl = Standard_False; + } + } + } + else intl = Standard_False; + } + + // select <onS> switcher so that to get on spine params from + // Interference with a face where both edges at corner are OnSame + // eap occ293 + if (intl && Spine->LastStatus() == ChFiDS_OnSame) { + TopoDS_Edge threeE[3]; + ChFi3d_cherche_element(bout2,support,F1,threeE[0],boutemp); + ChFi3d_cherche_element(bout2,support,F2,threeE[1],boutemp); + threeE[2] = support; + if (ChFi3d_EdgeState(threeE,myEFMap) == ChFiDS_OnSame) + onS = 1; + else + onS = 2; +#ifdef DEB + if (threeE[0].IsSame(threeE[1])) + cout << "SplitKPart(), wrong corner vertex at switcher search" << endl; +#endif + cntlFiOnS = 3 - onS; + } + } + } + + if(!intf) { + // SurfData are entirely suspended before the beginning of the edge. + Standard_Boolean okdoc = SetData.IsEmpty(); + Standard_Integer i = 1; + while(!okdoc) { + Handle(ChFiDS_SurfData)& CD5 = SetData.ChangeValue(i); + Standard_Real ltg = CD5->Interference(onS).LastParameter(); + Standard_Real Nl = ComputeAbscissa(Spine->CurrentElementarySpine(Iedge),ltg); + if (Nl < -tolesp) SetData.Remove(i); + else i++; + okdoc = (SetData.IsEmpty() || i > SetData.Length()); + } + } + if(!intl) { + // SurfData are entirely suspended after the end of the edge. + Standard_Boolean okdoc = SetData.IsEmpty(); + Standard_Integer i = 1; + while(!okdoc) { + Handle(ChFiDS_SurfData)& CD6 = SetData.ChangeValue(i); + Standard_Real ftg = CD6->Interference(onS).FirstParameter(); + Standard_Real f = Spine->FirstParameter(Iedge); + Standard_Real l = Spine->LastParameter(Iedge); + Standard_Real Nl = ComputeAbscissa(Spine->CurrentElementarySpine(Iedge),ftg); + if (Nl > (l - f + tolesp)) SetData.Remove(i); + else i++; + okdoc = (SetData.IsEmpty() || i > SetData.Length()); + } + } + // Add parameters of the spine on SurfDatas. +// for (Standard_Integer i = 1; i <= SetData.Length(); i++) { + Standard_Integer i; + for ( i = 1; i <= SetData.Length(); i++) { + Standard_Boolean pokdeb = 0, pokfin = 0; + Handle(ChFiDS_SurfData)& CD7 = SetData.ChangeValue(i); + Standard_Real ftg = CD7->Interference(onS).FirstParameter(); + Standard_Real ltg = CD7->Interference(onS).LastParameter(); + Standard_Real fsp = ParamOnSpine(DStr,ftg,CD7,Spine,Iedge,intf,intl,tolesp,pokdeb); + if(!pokdeb) fsp = ResetProl(DStr,CD7,Spine,Iedge,1); + Standard_Real lsp = ParamOnSpine(DStr,ltg,CD7,Spine,Iedge,intf,intl,tolesp,pokfin); + if(!pokfin) lsp = ResetProl(DStr,CD7,Spine,Iedge,0); + if(Spine->IsPeriodic() && Iedge == Spine->NbEdges() && lsp < fsp) { + lsp += Spine->Period(); + } + else if(Spine->IsPeriodic() && Iedge == 1 && lsp < fsp) { + fsp -= Spine->Period(); + } + CD7->FirstSpineParam(fsp); + CD7->LastSpineParam (lsp); + } + + if (intf && !SetData.IsEmpty()) { + // extension of the spine + Spine->SetFirstParameter(SetData.First()->FirstSpineParam()); + } + else { + // Trnncation at the beginning. + for (i = 1; i <= SetData.Length(); i++) { + Handle(ChFiDS_SurfData)& CD8 = SetData.ChangeValue(i); + Standard_Real fsp = CD8->FirstSpineParam(); + Standard_Real lsp = CD8->LastSpineParam(); + if (lsp > Spine->FirstParameter(Iedge)) { + if (fsp > Spine->FirstParameter(Iedge)) { + break; + } + else { + Trunc(CD8,Spine,S1,S2,Iedge,1,cntlFiOnS); + break; + } + } + } + if (i > 1 ) { + SetData.Remove(1,i-1); + } + } + + + if (intl && !SetData.IsEmpty()) { + // extension of the spine + Spine->SetLastParameter(SetData.Last()->LastSpineParam()); + } + else { + // Truncation at the end. + for (i = SetData.Length(); i >= 1; i--) { + Handle(ChFiDS_SurfData)& CD9 = SetData.ChangeValue(i); + Standard_Real fsp = CD9->FirstSpineParam(); + Standard_Real lsp = CD9->LastSpineParam(); + if (fsp < Spine->LastParameter(Iedge)) { + if (lsp < Spine->LastParameter(Iedge)) { + break; + } + else { + Trunc(CD9,Spine,S1,S2,Iedge,0,cntlFiOnS); + break; + } + } + } + if (i < SetData.Length()) { + SetData.Remove(i+1,SetData.Length()); + } + } +#ifdef DEB + if(ChFi3d_GettraceDRAWFIL()) { + for (i = 1; i <= SetData.Length(); i++) { + ChFi3d_CheckSurfData(DStr,SetData.Value(i)); + } + } +#endif + return Standard_True; +} diff --git a/src/ChFi3d/ChFi3d_CMPLRS.edl b/src/ChFi3d/ChFi3d_CMPLRS.edl new file mode 100644 index 00000000..ec4f7e57 --- /dev/null +++ b/src/ChFi3d/ChFi3d_CMPLRS.edl @@ -0,0 +1,21 @@ +-- File: CMPLRS.edl +-- Author: Jean GAUTIER +-- History: Mon Feb 19 12:04:00 1996 Jean GAUTIER Creation +-- Copyright: Matra Datavision 1996 + + +-- +-- Templates HP-UX +-- +@if ( %Station == "hp" ) then + + @string %CMPLRS_CXX_Options = %CMPLRS_CXX_Options " -w "; +--- POP suivant directive POP : @string %CMPLRS_CXX_Options = %CMPLRS_CXX_Options " -w +a1 "; +-- +-- FSA : +O2 est trop consomateur de swap pour l'instant. + + @set %CMPLRS_CXX_ModeOpt = "+O1"; + +@endif; + + diff --git a/src/ChFi3d/ChFi3d_ChBuilder.cdl b/src/ChFi3d/ChFi3d_ChBuilder.cdl new file mode 100644 index 00000000..93fc4d8d --- /dev/null +++ b/src/ChFi3d/ChFi3d_ChBuilder.cdl @@ -0,0 +1,451 @@ +-- File: ChFi3d_ChBuilder.cdl +-- Created: Wed Apr 26 10:35:08 1995 +-- Author: Modelistation +-- <model@phylox> +---Copyright: Matra Datavision 1995 + +class ChBuilder from ChFi3d inherits Builder from ChFi3d + + ---Purpose: construction tool for 3D chamfers on edges. + +uses + Shape from TopoDS, + Edge from TopoDS, + Face from TopoDS, + Vertex from TopoDS, + State from TopAbs, + Orientation from TopAbs, + HElSpine from ChFiDS, + SequenceOfSurfData from ChFiDS, + SurfData from ChFiDS, + Stripe from ChFiDS, + ListOfStripe from ChFiDS, + Spine from ChFiDS, + SecHArray1 from ChFiDS, + Function from Blend, + HCurve from Adaptor3d, + HCurve2d from BRepAdaptor, + HSurface from BRepAdaptor, + HCurve from Adaptor3d, + TopolTool from Adaptor3d, + Vector from math, + ChamfMethod from ChFiDS , + Pnt2d from gp + +raises + ConstructionError from Standard, + DomainError from Standard + +is + + Create(S : Shape from TopoDS; Ta : Real from Standard = 1.0e-2) + returns ChBuilder from ChFi3d; + ---Purpose: initializes the Builder with the Shape <S> for the + -- computation of chamfers + + + Add(me : in out; E : Edge from TopoDS) + ---Purpose: initializes a contour with the edge <E> as first + -- (the next are found by propagation ). + -- The two distances (parameters of the chamfer) must + -- be set after. + raises ConstructionError from Standard + ---Purpose: if the edge <E> has more than 2 adjacent faces + is static; + + Add(me : in out; + Dis : Real from Standard; + E : Edge from TopoDS; + F : Face from TopoDS) + ---Purpose: initializes a new contour with the edge <E> as first + -- (the next are found by propagation ), and the + -- distance <Dis> + raises ConstructionError from Standard + ---Purpose: if the edge <E> has more than 2 adjacent faces + is static; + + SetDist(me : in out; + Dis : Real; + IC : Integer from Standard; + F : Face from TopoDS) + ---Purpose: set the distance <Dis> of the fillet + -- contour of index <IC> in the DS with <Dis> on <F>. + raises DomainError from Standard + ---Purpose: if the face <F> is not one of common faces + -- of an edge of the contour <IC> + is static; + + + GetDist(me ; + IC : Integer from Standard; + Dis : out Real from Standard) + ---Purpose: gives the distances <Dis> of the fillet + -- contour of index <IC> in the DS + is static; + + Add(me : in out; + Dis1, Dis2 : Real from Standard; + E : Edge from TopoDS; + F : Face from TopoDS) + ---Purpose: initializes a new contour with the edge <E> as first + -- (the next are found by propagation ), and the + -- distance <Dis1> and <Dis2> + raises ConstructionError from Standard + ---Purpose: if the edge <E> has more than 2 adjacent faces + is static; + + SetDists(me : in out; + Dis1, Dis2 : Real; + IC : Integer from Standard; + F : Face from TopoDS) + ---Purpose: set the distances <Dis1> and <Dis2> of the fillet + -- contour of index <IC> in the DS with <Dis1> on <F>. + raises DomainError from Standard + ---Purpose: if the face <F> is not one of common faces + -- of an edge of the contour <IC> + is static; + + + Dists(me ; + IC : Integer from Standard; + Dis1, Dis2 : out Real from Standard) + ---Purpose: gives the distances <Dis1> and <Dis2> of the fillet + -- contour of index <IC> in the DS + is static; + + + AddDA(me : in out; + Dis : Real from Standard; + Angle : Real from Standard; + E : Edge from TopoDS; + F : Face from TopoDS) + ---Purpose: initializes a new contour with the edge <E> as first + -- (the next are found by propagation ), and the + -- distance <Dis1> and <Angle> + raises ConstructionError from Standard + ---Purpose: if the edge <E> has more than 2 adjacent faces + is static; + + + SetDistAngle(me : in out; + Dis : Real from Standard; + Angle : Real from Standard; + IC : Integer from Standard; + F : Face from TopoDS) + ---Purpose: set the distance <Dis> and <Angle> of the fillet + -- contour of index <IC> in the DS with <Dis> on <F>. + raises DomainError from Standard + ---Purpose: if the face <F> is not one of common faces + -- of an edge of the contour <IC> + is static; + + + GetDistAngle(me ; + IC : Integer from Standard; + Dis : in out Real from Standard; + Angle : in out Real from Standard; + DisOnFace1 : in out Boolean from Standard) + ---Purpose: gives the distances <Dis> and <Angle> of the fillet + -- contour of index <IC> in the DS + is static; + + IsChamfer(me; + IC : Integer from Standard) + returns ChamfMethod from ChFiDS is static; + ---Purpose: renvoi la methode des chanfreins utilisee + + ResetContour(me : in out; + IC : Integer from Standard) + ---Purpose: Reset tous rayons du contour IC. + is static; + + ---Methods for quick simulation + ------------------------------- + + Simulate(me : in out; + IC : Integer from Standard); + + NbSurf(me; IC : Integer from Standard) + returns Integer from Standard; + + Sect(me; IC, IS : Integer from Standard) + returns mutable SecHArray1 from ChFiDS; + + SimulKPart(me; SD : mutable SurfData from ChFiDS) + is protected; + + SimulSurf(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro : Boolean from Standard; + Forward : Boolean from Standard; + RecOnS1,RecOnS2 : Boolean from Standard; + Soldep : Vector from math; + Intf,Intl : in out Boolean from Standard) + returns Boolean + is protected; + + SimulSurf(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + PC1 : HCurve2d from BRepAdaptor; + Sref1 : HSurface from BRepAdaptor; + PCref1 : HCurve2d from BRepAdaptor; + Decroch1 : out Boolean from Standard; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + Or2 : Orientation from TopAbs; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard; + Soldep : Vector from math) + is redefined; + + SimulSurf(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + Or1 : Orientation from TopAbs; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + PC2 : HCurve2d from BRepAdaptor; + Sref2 : HSurface from BRepAdaptor; + PCref2 : HCurve2d from BRepAdaptor; + Decroch2 : out Boolean from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard; + Soldep : Vector from math) + + is redefined; + + SimulSurf(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + PC1 : HCurve2d from BRepAdaptor; + Sref1 : HSurface from BRepAdaptor; + PCref1 : HCurve2d from BRepAdaptor; + Decroch1 : out Boolean from Standard; + Or1 : Orientation from TopAbs; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + PC2 : HCurve2d from BRepAdaptor; + Sref2 : HSurface from BRepAdaptor; + PCref2 : HCurve2d from BRepAdaptor; + Decroch2 : out Boolean from Standard; + Or2 : Orientation from TopAbs; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP1,RecRst1 : Boolean from Standard; + RecP2,RecRst2 : Boolean from Standard; + Soldep : Vector from math) + + is redefined; + + ---Methods for computation + -------------------------- + + PerformFirstSection(me ; + S : Spine from ChFiDS; + HGuide : HElSpine from ChFiDS; + Choix : Integer from Standard; + S1,S2 : in out HSurface from BRepAdaptor; + I1,I2 : TopolTool from Adaptor3d; + Par : Real from Standard; + SolDep : in out Vector from math; + Pos1,Pos2 : out State from TopAbs) + returns Boolean from Standard + is protected; + + PerformSurf(me : in out; + Data : out SequenceOfSurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro : Boolean from Standard; + Forward : Boolean from Standard; + RecOnS1,RecOnS2 : Boolean from Standard; + Soldep : Vector from math; + Intf,Intl : in out Boolean from Standard) + returns Boolean + is redefined; + ---Purpose: Methode, implemented in inheritants, calculates + -- the elements of construction of the surface (fillet + -- or chamfer). + + PerformSurf(me : in out; + Data : out SequenceOfSurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + PC1 : HCurve2d from BRepAdaptor; + Sref1 : HSurface from BRepAdaptor; + PCref1 : HCurve2d from BRepAdaptor; + Decroch1 : out Boolean from Standard; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + Or2 : Orientation from TopAbs; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard; + Soldep : Vector from math) + + is redefined; + ---Purpose: Method, implemented in the inheritants, calculates + -- the elements of construction of the surface (fillet + -- or chamfer) contact edge/face. + + PerformSurf(me : in out; + Data : out SequenceOfSurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + Or1 : Orientation from TopAbs; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + PC2 : HCurve2d from BRepAdaptor; + Sref2 : HSurface from BRepAdaptor; + PCref2 : HCurve2d from BRepAdaptor; + Decroch2 : out Boolean from Standard; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard; + Soldep : Vector from math) + + is redefined; + ---Purpose: Method, implemented in inheritants, calculates + -- the elements of construction of the surface (fillet + -- or chamfer) contact edge/face. + + PerformSurf(me : in out; + Data : out SequenceOfSurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + PC1 : HCurve2d from BRepAdaptor; + Sref1 : HSurface from BRepAdaptor; + PCref1 : HCurve2d from BRepAdaptor; + Decroch1 : out Boolean from Standard; + Or1 : Orientation from TopAbs; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + PC2 : HCurve2d from BRepAdaptor; + Sref2 : HSurface from BRepAdaptor; + PCref2 : HCurve2d from BRepAdaptor; + Decroch2 : out Boolean from Standard; + Or2 : Orientation from TopAbs; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP1,RecRst1 : Boolean from Standard; + RecP2,RecRst2 : Boolean from Standard; + Soldep : Vector from math) + + is redefined; + ---Purpose: Method, implemented in inheritants, calculates + -- the elements of construction of the surface (fillet + -- or chamfer) contact edge/edge. + + PerformTwoCorner(me : in out ; + Index : Integer from Standard) + is protected; + ---Purpose: computes the intersection of two chamfers on + -- the vertex of index <Index> in myVDataMap. + + PerformThreeCorner(me : in out ; + Index : Integer from Standard) + is protected; + ---Purpose: computes the intersection of three chamfers on + -- the vertex of index <Index> in myVDataMap. + + + ExtentOneCorner(me : in out; + V : Vertex from TopoDS; + S : Stripe from ChFiDS) + is protected; + ---Purpose: extends the spine of the Stripe <S> at the + -- extremity of the vertex <V>. + + + ExtentTwoCorner(me : in out; + V : Vertex from TopoDS; + LS : ListOfStripe from ChFiDS) + is protected; + ---Purpose: extends the spine of the 2 stripes of <LS> at the + -- extremity of the vertex <V> + + + ExtentThreeCorner(me : in out; + V : Vertex from TopoDS; + LS : ListOfStripe from ChFiDS) + is protected; + ---Purpose: extends the spine of the 2 stripes of <LS> at the + -- extremity of the vertex <V> + + + SetRegul(me : in out) is protected; + ---Purpose: set the regularities + + + ConexFaces(me; + Sp : Spine from ChFiDS; + IEdge : Integer from Standard; + F1, F2 : out Face from TopoDS) + is static private; + + FindChoiceDistAngle(me; + Choice : Integer from Standard; + DisOnF1 : Boolean from Standard) + returns Integer from Standard + is static; + +end ChBuilder; + + diff --git a/src/ChFi3d/ChFi3d_ChBuilder.cxx b/src/ChFi3d/ChFi3d_ChBuilder.cxx new file mode 100644 index 00000000..49537439 --- /dev/null +++ b/src/ChFi3d/ChFi3d_ChBuilder.cxx @@ -0,0 +1,2257 @@ +// File: ChFi3d_ChBuilder.cxx +// Created: Wed Apr 26 13:32:48 1995 +// Author: Flore Lantheaume +// <fla@phylox> + +#include <ChFi3d_ChBuilder.ixx> +#include <ChFi3d.hxx> +#include <ChFi3d_Builder_0.hxx> + +#include <TopOpeBRepDS_HDataStructure.hxx> +#include <TopOpeBRepBuild_HBuilder.hxx> +#include <ChFiDS_Spine.hxx> +#include <ChFiDS_ChamfSpine.hxx> +#include <ChFiDS_Stripe.hxx> +#include <ChFiDS_ListOfStripe.hxx> +#include <ChFiDS_ListIteratorOfListOfStripe.hxx> +#include <ChFiDS_Regul.hxx> +#include <ChFiDS_ListIteratorOfRegularities.hxx> +#include <ChFiDS_SecHArray1.hxx> +#include <ChFiDS_HData.hxx> +#include <ChFiDS_CircSection.hxx> + +#include <Blend_Point.hxx> +#include <BRepBlend_Line.hxx> +#include <BRepBlend_Chamfer.hxx> +#include <BRepBlend_ChamfInv.hxx> +#include <BRepBlend_ChAsym.hxx> +#include <BRepBlend_ChAsymInv.hxx> +#include <BlendFunc_SectionShape.hxx> +#include <BRepBlend_Walking.hxx> +#include <BRepAdaptor_HSurface.hxx> +#include <BRepAdaptor_Curve2d.hxx> +#include <GeomAdaptor_HCurve.hxx> + + +#include <Extrema_GenLocateExtPS.hxx> +#include <BRepAdaptor_Surface.hxx> +#include <TopTools_ListIteratorOfListOfShape.hxx> +#include <TopAbs.hxx> + +#include <ElSLib.hxx> +#include <BRepTools.hxx> + +#include <Standard_NotImplemented.hxx> +#include <Standard_DomainError.hxx> + +#ifdef DEB +extern Standard_Boolean ChFi3d_GettraceCHRON(); +#endif + +//======================================================================= +//function : SearchCommonFaces +//purpose : search the 2 common faces <F1> and <F2> of the edge <E> +// uses the EFMap and take the 2 first good faces +//======================================================================= + +void SearchCommonFaces(const ChFiDS_Map& EFMap, + const TopoDS_Edge& E, + TopoDS_Face& F1, + TopoDS_Face& F2) +{ + TopoDS_Face Fc; + TopTools_ListIteratorOfListOfShape It; + + F1.Nullify(); + F2.Nullify(); + for ( It.Initialize(EFMap(E)); It.More(); It.Next() ) { + Fc = TopoDS::Face(It.Value()); + if ( F1.IsNull() ) + F1 = Fc; + else if ( !Fc.IsSame(F1) ) { + F2 = Fc; + break; + } + } + + if (!F1.IsNull() && F2.IsNull() && BRepTools::IsReallyClosed( E, F1 )) + F2 = F1; +} + +//======================================================================= +//function : ExtentSpinesOnCommonFace +//purpose : Extend spines of two chamfers by distance dis1,dis2 +// on their common face +// Two guide lines Spine1 and Spine2 cross in V +// isfirst(i) = False if Spine(i) is oriented to V (i = 1,2) +//======================================================================= + +void ExtentSpineOnCommonFace(Handle(ChFiDS_Spine)& Spine1, + Handle(ChFiDS_Spine)& Spine2, + const TopoDS_Vertex& V, + const Standard_Real dis1, + const Standard_Real dis2, + const Standard_Boolean isfirst1, + const Standard_Boolean isfirst2) +{ + Standard_Real tolesp = 1.e-7; + + // alpha, the opening angle between two + // tangents of two guidelines in V is found + Standard_Real tga1,tga2; + Standard_Real d1plus = 0., d2plus = 0.; + + gp_Pnt tmp; + gp_Vec tg1, tg2; + Spine1->D1(Spine1->Absc(V),tmp,tg1); + Spine2->D1(Spine2->Absc(V),tmp,tg2); + tg1.Normalize(); + tg2.Normalize(); + if (isfirst1) + tg1.Reverse(); + if (isfirst2) + tg2.Reverse(); + + Standard_Real cosalpha,sinalpha; + cosalpha = tg1.Dot(tg2); + sinalpha = sqrt(1-cosalpha*cosalpha); + + //a1+a2 = alpha + Standard_Real temp; + temp = cosalpha+dis2/dis1; + if( Abs(temp) > tolesp ){ + tga1 = sinalpha/temp; + d1plus = dis1/tga1; + } + temp = cosalpha+dis1/dis2; + if( Abs(temp) > tolesp ){ + tga2 = sinalpha/temp; + d2plus = dis2/tga2; + } + + //extension by the calculated distance + if (d1plus > 0.) { + d1plus *= 3.; + if (isfirst1){ + Spine1->SetFirstParameter(-d1plus); + Spine1->SetFirstTgt(0.); + } + else{ + Standard_Real param = Spine1->LastParameter(Spine1->NbEdges()); + Spine1->SetLastParameter(d1plus+param); + Spine1->SetLastTgt(param); + } + } + if (d2plus > 0.) { + d2plus *= 1.5; + if (isfirst2){ + Spine2->SetFirstParameter(-d2plus); + Spine2->SetFirstTgt(0.); + } + else{ + Standard_Real param = Spine2->LastParameter(Spine2->NbEdges()); + Spine2->SetLastParameter(d2plus+param); + Spine2->SetLastTgt(param); + } + } +} + +//======================================================================= +//function : ChFi3d_ChBuilder +//purpose : +//======================================================================= + +ChFi3d_ChBuilder::ChFi3d_ChBuilder(const TopoDS_Shape& S, + const Standard_Real Ta) : + ChFi3d_Builder(S, Ta) +{ +} + + +//======================================================================= +//function : Add +//purpose : create a new stripe with a spine containing the edge <E> +// add on the spine the tangential edges to <E> +//======================================================================= + +void ChFi3d_ChBuilder::Add(const TopoDS_Edge& E) +{ + + if(!Contains(E) && myEFMap.Contains(E)){ + Handle(ChFiDS_Stripe) Stripe = new ChFiDS_Stripe(); + Handle(ChFiDS_Spine)& Sp = Stripe->ChangeSpine(); + Sp = new ChFiDS_ChamfSpine(tolesp); + Handle(ChFiDS_ChamfSpine) Spine = Handle(ChFiDS_ChamfSpine)::DownCast(Sp); + + TopoDS_Edge E_wnt = E; + E_wnt.Orientation(TopAbs_FORWARD); + Spine->SetEdges(E_wnt); + if(PerformElement(Spine)){ + PerformExtremity(Spine); + Spine->Load(); + myListStripe.Append(Stripe); + } + } +} + + +//======================================================================= +//function : Add +//purpose : create a new stripe with a ChamfSpine containing the edge <E> +// with the distance <Dis> on the face <F> +// . Add the tangential edges continuous to E in the spine +// +//======================================================================= + +void ChFi3d_ChBuilder::Add(const Standard_Real Dis, + const TopoDS_Edge& E, + const TopoDS_Face& F) +{ + if (!Contains(E) && myEFMap.Contains(E)) { + + // Take the 2 common faces of the egde <E> + TopoDS_Face F1,F2; + SearchCommonFaces(myEFMap,E,F1,F2); + + if (! F1.IsSame(F) && F2.IsSame(F) ) { + F2 = F1; + F1 = F; + } + + if ( F1.IsSame(F)) { + TopoDS_Edge E_wnt = E; + E_wnt.Orientation(TopAbs_FORWARD); + BRepAdaptor_Surface Sb1,Sb2; + Sb1.Initialize(F1); + Sb2.Initialize(F2); + TopAbs_Orientation Or1,Or2; + ChFi3d::ConcaveSide(Sb1,Sb2,E_wnt,Or1,Or2); + Handle(ChFiDS_Stripe) Stripe = new ChFiDS_Stripe(); + Handle(ChFiDS_Spine)& Sp = Stripe->ChangeSpine(); + Sp = new ChFiDS_ChamfSpine(tolesp); + Handle(ChFiDS_ChamfSpine) + Spine = Handle(ChFiDS_ChamfSpine)::DownCast(Sp); + + Spine->SetEdges(E_wnt); + if(PerformElement(Spine)){ + Spine->Load(); + myListStripe.Append(Stripe); + + Spine->SetDist(Dis); + + PerformExtremity(Spine); + } + } + } +} + + +//======================================================================= +//function : SetDist +//purpose : set the distances <Dis>of the contour of +// index IC +//======================================================================= + +void ChFi3d_ChBuilder::SetDist(const Standard_Real Dis, + const Standard_Integer IC, + const TopoDS_Face& F) +{ + + if(IC <= NbElements()) { + Handle(ChFiDS_ChamfSpine) csp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC)); + + // Search the first edge which has a common face equal to F + TopoDS_Face F1,F2,FirstF1,FirstF2; + //TopAbs_Orientation Or1,Or2; + //Standard_Integer Choix, ChoixConge; + BRepAdaptor_Surface Sb1,Sb2; + Standard_Integer i = 1; + Standard_Boolean Found = Standard_False; + while ( (i <= csp->NbEdges()) && (!Found) ) { + SearchCommonFaces(myEFMap,csp->Edges(i),F1,F2); + if ( i == 1) { + FirstF1 = F1; + FirstF2 = F2; + } + Found = ( F1.IsSame(F) || F2.IsSame(F) ); + i++; + } + + if (Found) { + if ( F2.IsSame(F) ) { + F2 = F1; + F1 = F; + } + csp->SetDist(Dis); + + } + else + Standard_DomainError::Raise("the face is not common to any of edges of the contour"); + + } +} + + +//======================================================================= +//function : GetDist +//purpose : +//======================================================================= + +void ChFi3d_ChBuilder::GetDist(const Standard_Integer IC, + Standard_Real& Dis) const +{ + Handle(ChFiDS_ChamfSpine) chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC)); + chsp->GetDist(Dis); + +} + + +//======================================================================= +//function : Add +//purpose : create a new stripe with a ChAsymSpine containing the edge <E> +// with the distance <Dis> and the angle Angle on the face <F> +// . Add the tangential edges continuous to E in the spine +// +//======================================================================= + +void ChFi3d_ChBuilder::Add(const Standard_Real Dis1, + const Standard_Real Dis2, + const TopoDS_Edge& E, + const TopoDS_Face& F) +{ + if (!Contains(E) && myEFMap.Contains(E)) { + + // Take the 2 common faces of the egde <E> + TopoDS_Face F1,F2; + SearchCommonFaces(myEFMap,E,F1,F2); + + if (! F1.IsSame(F) && F2.IsSame(F) ) { + F2 = F1; + F1 = F; + } + + if ( F1.IsSame(F)) { + TopoDS_Edge E_wnt = E; + E_wnt.Orientation(TopAbs_FORWARD); + BRepAdaptor_Surface Sb1,Sb2; + Sb1.Initialize(F1); + Sb2.Initialize(F2); + TopAbs_Orientation Or1,Or2; + Standard_Integer Choix = ChFi3d::ConcaveSide(Sb1,Sb2,E_wnt,Or1,Or2); + + Handle(ChFiDS_Stripe) Stripe = new ChFiDS_Stripe(); + Handle(ChFiDS_Spine)& Sp = Stripe->ChangeSpine(); + Sp = new ChFiDS_ChamfSpine(tolesp); + Handle(ChFiDS_ChamfSpine) + Spine = Handle(ChFiDS_ChamfSpine)::DownCast(Sp); + + Spine->SetEdges(E_wnt); + if(PerformElement(Spine)){ + Spine->Load(); + myListStripe.Append(Stripe); + + Standard_Integer ChoixConge; + SearchCommonFaces(myEFMap,Spine->Edges(1),F1,F2); + Sb1.Initialize(F1); + Sb2.Initialize(F2); + ChoixConge = ChFi3d::ConcaveSide(Sb1,Sb2, + Spine->Edges(1), + Or1,Or2); + + + // compare the 2 computed choices to know how to set the + // distances of the Spine according to the choice done + // on the added edge <e> + if ( ChoixConge%2 != Choix%2 ) + Spine->SetDists(Dis2, Dis1); + else Spine->SetDists(Dis1, Dis2); + + PerformExtremity(Spine); + } + } + } +} + + +//======================================================================= +//function : SetDists +//purpose : set the distances <Dis1> and <Dis2> of the contour of +// index IC +//======================================================================= + +void ChFi3d_ChBuilder::SetDists(const Standard_Real Dis1, + const Standard_Real Dis2, + const Standard_Integer IC, + const TopoDS_Face& F) +{ + + if(IC <= NbElements()) { + Handle(ChFiDS_ChamfSpine) csp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC)); + + // Search the first edge which has a common face equal to F + TopoDS_Face F1,F2,FirstF1,FirstF2; + TopAbs_Orientation Or1,Or2; + Standard_Integer Choix, ChoixConge; + BRepAdaptor_Surface Sb1,Sb2; + Standard_Integer i = 1; + Standard_Boolean Found = Standard_False; + while ( (i <= csp->NbEdges()) && (!Found) ) { + SearchCommonFaces(myEFMap,csp->Edges(i),F1,F2); + if ( i == 1) { + FirstF1 = F1; + FirstF2 = F2; + } + Found = ( F1.IsSame(F) || F2.IsSame(F) ); + i++; + } + + if (Found) { + if ( F2.IsSame(F) ) { + F2 = F1; + F1 = F; + } + Sb1.Initialize(F1); + Sb2.Initialize(F2); + Choix = ChFi3d::ConcaveSide(Sb1,Sb2, + csp->Edges(i-1), + Or1,Or2); + Sb1.Initialize(FirstF1); + Sb2.Initialize(FirstF2); + ChoixConge = ChFi3d::ConcaveSide(Sb1,Sb2, + csp->Edges(1), + Or1,Or2); + if ( ChoixConge%2 != Choix%2 ) + csp->SetDists(Dis2,Dis1); + else csp->SetDists(Dis1,Dis2); + } + else + Standard_DomainError::Raise("the face is not common to any of edges of the contour"); + + } +} + + +//======================================================================= +//function : Dists +//purpose : +//======================================================================= + +void ChFi3d_ChBuilder::Dists(const Standard_Integer IC, + Standard_Real& dis1, + Standard_Real& dis2) const +{ + Handle(ChFiDS_ChamfSpine) chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC)); + Standard_Real temp1, temp2; + chsp->Dists(temp1,temp2); + dis1 = temp1; + dis2 = temp2; +} + + +//======================================================================= +//function : Add +//purpose : create a new stripe with a ChAsymSpine containing the edge <E> +// with the distance <Dis> and the angle Angle on the face <F> +// . Add the tangential edges continuous to E in the spine +// +//======================================================================= + +void ChFi3d_ChBuilder::AddDA(const Standard_Real Dis1, + const Standard_Real Angle, + const TopoDS_Edge& E, + const TopoDS_Face& F) +{ + if (!Contains(E) && myEFMap.Contains(E)) { + + // Take the 2 common faces of the egde <E> + TopoDS_Face F1,F2; + SearchCommonFaces(myEFMap,E,F1,F2); + + if (! F1.IsSame(F) && F2.IsSame(F) ) { + F2 = F1; + F1 = F; + } + + if ( F1.IsSame(F)) { + TopoDS_Edge E_wnt = E; + E_wnt.Orientation(TopAbs_FORWARD); + BRepAdaptor_Surface Sb1,Sb2; + Sb1.Initialize(F1); + Sb2.Initialize(F2); + TopAbs_Orientation Or1,Or2; + Standard_Integer Choix = ChFi3d::ConcaveSide(Sb1,Sb2,E_wnt,Or1,Or2); + + Handle(ChFiDS_Stripe) Stripe = new ChFiDS_Stripe(); + Handle(ChFiDS_Spine)& Sp = Stripe->ChangeSpine(); + Sp = new ChFiDS_ChamfSpine(tolesp); + Handle(ChFiDS_ChamfSpine) + Spine = Handle(ChFiDS_ChamfSpine)::DownCast(Sp); + + Spine->SetEdges(E_wnt); + if(PerformElement(Spine)){ + Spine->Load(); + myListStripe.Append(Stripe); + + Standard_Integer ChoixConge; + SearchCommonFaces(myEFMap,Spine->Edges(1),F1,F2); + Sb1.Initialize(F1); + Sb2.Initialize(F2); + ChoixConge = ChFi3d::ConcaveSide(Sb1,Sb2, + Spine->Edges(1), + Or1,Or2); + + // compare the 2 computed choices to know how to set the + // distances of the Spine according to the choice done + // on the added edge <e> + if ( ChoixConge%2 != Choix%2 ) { + Spine->SetDistAngle(Dis1, Angle, Standard_False); + } + else { + Spine->SetDistAngle(Dis1, Angle, Standard_True); + } + + PerformExtremity(Spine); + } + } + } +} + + +//======================================================================= +//function : SetDistAngle +//purpose : set the distances <Dis> and <Angle> of the contour of +// index IC +//======================================================================= + +void ChFi3d_ChBuilder::SetDistAngle(const Standard_Real Dis, + const Standard_Real Angle, + const Standard_Integer IC, + const TopoDS_Face& F) +{ + + if(IC <= NbElements()) { + Handle(ChFiDS_ChamfSpine) csp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC)); + + // Search the first edge which has a common face equal to F + TopoDS_Face F1,F2,FirstF1,FirstF2; + TopAbs_Orientation Or1,Or2; + Standard_Integer Choix, ChoixConge; + BRepAdaptor_Surface Sb1,Sb2; + Standard_Integer i = 1; + Standard_Boolean Found = Standard_False; +// Standard_Boolean DisOnF1 = Standard_True; + + while ( (i <= csp->NbEdges()) && (!Found) ) { + SearchCommonFaces(myEFMap,csp->Edges(i),F1,F2); + if ( i == 1) { + FirstF1 = F1; + FirstF2 = F2; + } + Found = ( F1.IsSame(F) || F2.IsSame(F) ); + i++; + } + + if (Found) { + if ( F2.IsSame(F) ) { + F2 = F1; + F1 = F; + } + Sb1.Initialize(F1); + Sb2.Initialize(F2); + Choix = ChFi3d::ConcaveSide(Sb1,Sb2, + csp->Edges(i-1), + Or1,Or2); + Sb1.Initialize(FirstF1); + Sb2.Initialize(FirstF2); + ChoixConge = ChFi3d::ConcaveSide(Sb1,Sb2, + csp->Edges(1), + Or1,Or2); + if ( ChoixConge%2 != Choix%2 ) { + csp->SetDistAngle(Dis, Angle, Standard_False); + } + else { + csp->SetDistAngle(Dis, Angle, Standard_True); + } + } + else + Standard_DomainError::Raise("the face is not common to any edges of the contour"); + + } +} + + +//======================================================================= +//function : GetDistAngle +//purpose : +//======================================================================= + +void ChFi3d_ChBuilder::GetDistAngle(const Standard_Integer IC, + Standard_Real& Dis, + Standard_Real& Angle, + Standard_Boolean& DisOnFace1) const +{ + Handle(ChFiDS_ChamfSpine) chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC)); + + chsp->GetDistAngle(Dis, Angle, DisOnFace1); +} + +//======================================================================= +//function : IsChamfer +//purpose : +//======================================================================= +ChFiDS_ChamfMethod ChFi3d_ChBuilder::IsChamfer(const Standard_Integer IC) const +{ + Handle(ChFiDS_ChamfSpine) chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC)); + + ChFiDS_ChamfMethod ret = chsp->IsChamfer(); + + return ret; + +} + +//======================================================================= +//function : ResetContour +//purpose : +//======================================================================= + +void ChFi3d_ChBuilder::ResetContour(const Standard_Integer IC) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_ChamfSpine) chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC)); + chsp->Reset(Standard_True); + } +} + +//--------------------------------AJOUT---------------------------------- +//======================================================================= +//function : Simulate +//purpose : +//======================================================================= + +void ChFi3d_ChBuilder::Simulate (const Standard_Integer IC) +{ +#ifdef DEB + if(ChFi3d_GettraceCHRON()){ + simul.Reset();elspine.Reset();chemine.Reset(); + simul.Start(); + } +#endif + ChFiDS_ListIteratorOfListOfStripe itel; + Standard_Integer i = 1; + for (itel.Initialize(myListStripe);itel.More(); itel.Next(), i++) { + if(i == IC){ + PerformSetOfSurf(itel.Value(), Standard_True); + break; + } + } +#ifdef DEB + if(ChFi3d_GettraceCHRON()){ + simul.Stop(); + cout<<"Total simulation time : "; + simul.Show(); + cout<<"Spine construction time : "; + elspine.Show(); + cout<<"and progression time : "; + chemine.Show(); + } +#endif +} + +//---------------------------AJOUT--------------------------------------- +//======================================================================= +//function : NbSurf +//purpose : +//======================================================================= + +Standard_Integer ChFi3d_ChBuilder::NbSurf (const Standard_Integer IC) const +{ + ChFiDS_ListIteratorOfListOfStripe itel; + Standard_Integer i = 1; + for (itel.Initialize(myListStripe);itel.More(); itel.Next(), i++) { + if(i == IC){ + return itel.Value()->SetOfSurfData()->Length(); + } + } + return 0; +} + + +//--------------------------AJOUT--------------------------------------- +//======================================================================= +//function : Sect +//purpose : +//======================================================================= + +Handle(ChFiDS_SecHArray1) ChFi3d_ChBuilder::Sect (const Standard_Integer IC, + const Standard_Integer IS) const +{ + ChFiDS_ListIteratorOfListOfStripe itel; + Standard_Integer i = 1; + Handle(ChFiDS_SecHArray1) res; + for (itel.Initialize(myListStripe);itel.More(); itel.Next(), i++) { + if(i == IC){ + Handle(MMgt_TShared) bid = itel.Value()->SetOfSurfData()->Value(IS)->Simul(); + res = Handle(ChFiDS_SecHArray1)::DownCast(bid); + return res; + } + } + return Handle(ChFiDS_SecHArray1)(); +} + + +//-------------------MODIFS--------------------------------------------- +//======================================================================= +//function : SimulKPart +//purpose : Stores simulating sections in simul +//======================================================================= + +void ChFi3d_ChBuilder::SimulKPart(const Handle(ChFiDS_SurfData)& SD ) const +{ + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + Handle(Geom_Surface) S = DStr.Surface(SD->Surf()).Surface(); + gp_Pnt2d p1f = SD->InterferenceOnS1().PCurveOnSurf()-> + Value(SD->InterferenceOnS1().FirstParameter()); + gp_Pnt2d p1l = SD->InterferenceOnS1().PCurveOnSurf()-> + Value(SD->InterferenceOnS1().LastParameter()); + gp_Pnt2d p2f = SD->InterferenceOnS2().PCurveOnSurf()-> + Value(SD->InterferenceOnS2().FirstParameter()); + gp_Pnt2d p2l = SD->InterferenceOnS2().PCurveOnSurf()-> + Value(SD->InterferenceOnS2().LastParameter()); + GeomAdaptor_Surface AS(S); + Handle(ChFiDS_SecHArray1) sec; + Standard_Real u1,v1,u2,v2; + GeomAbs_SurfaceType typ = AS.GetType(); + switch (typ){ + case GeomAbs_Plane: + { + v1 = p1f.Y(); + v2 = p2f.Y(); + u1 = Max(p1f.X(),p2f.X()); + u2 = Min(p1l.X(),p2l.X()); + sec = new ChFiDS_SecHArray1(1,2); + gp_Pln Pl = AS.Plane(); + ChFiDS_CircSection& sec1 = sec->ChangeValue(1); + ChFiDS_CircSection& sec2 = sec->ChangeValue(2); + sec1.Set(ElSLib::PlaneUIso(Pl.Position(),u1),v1,v2); + sec2.Set(ElSLib::PlaneUIso(Pl.Position(),u2),v1,v2); + } + break; + case GeomAbs_Cone: + { + v1 = p1f.Y(); + v2 = p2f.Y(); + u1 = Max(p1f.X(),p2f.X()); + u2 = Min(p1l.X(),p2l.X()); + Standard_Real ang = (u2-u1); + gp_Cone Co = AS.Cone(); + Standard_Real rad = Co.RefRadius(), sang = Co.SemiAngle(); +//#ifndef DEB + Standard_Integer n = (Standard_Integer) (36.*ang/PI + 1); +//#else +// Standard_Integer n = 36.*ang/PI + 1; +//#endif + if(n<2) n = 2; + sec = new ChFiDS_SecHArray1(1, n); + for (Standard_Integer i = 1; i <= n; i++) { + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u = u1 + (i - 1)*(u2 - u1)/(n-1); + isec.Set(ElSLib::ConeUIso(Co.Position(), rad, sang, u), v1, v2); + } + } + break; + default: + break; + } + SD->SetSimul(sec); +} + +//------------------------MODIFS--------------------------------------- +//======================================================================= +//function : SimulSurf +//purpose : +//======================================================================= + +Standard_Boolean +ChFi3d_ChBuilder::SimulSurf(Handle(ChFiDS_SurfData)& Data, + const Handle(ChFiDS_HElSpine)& HGuide, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer Choix, + const Handle(BRepAdaptor_HSurface)& S1, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(BRepAdaptor_HSurface)& S2, + const Handle(Adaptor3d_TopolTool)& I2, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecOnS1, + const Standard_Boolean RecOnS2, + const math_Vector& Soldep, + Standard_Boolean& intf, + Standard_Boolean& intl) + +{ + Handle(ChFiDS_ChamfSpine) + chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Spine); + + if (chsp.IsNull()) + Standard_ConstructionError::Raise + ("SimulSurf : this is not the spine of a chamfer"); + + + Standard_Real radius; + // Flexible parameters! + Standard_Real la = HGuide->LastParameter(), fi = HGuide->FirstParameter(); + Standard_Real longueur = la - fi; + Standard_Real MaxStep = longueur * 0.05; + Standard_Real radiusspine = 0, locfleche, w; + gp_Pnt Pbid; + gp_Vec d1,d2; + // As ElSpine is parameterized by a curvilinear quasi-abscissa, + // the min radius is estimated as 1/D2 max; + //for(Standard_Integer i = 0; i <= 20; i++){ + Standard_Integer i; + for( i = 0; i <= 20; i++){ + w = fi + i*MaxStep; + HGuide->D2(w,Pbid,d1,d2); + Standard_Real temp = d2.SquareMagnitude(); + if(temp>radiusspine) radiusspine = temp; + } + + Handle(BRepBlend_Line) lin; + Standard_Real PFirst = First; + if(intf) First = chsp->FirstParameter(1); + if(intl) Last = chsp->LastParameter(chsp->NbEdges()); + + + + if (chsp->IsChamfer() == ChFiDS_Sym) { + Standard_Real dis; + chsp->GetDist(dis); + radius = Max(dis, radiusspine); + locfleche = radius*1.e-2; //graphic criterion + + BRepBlend_Chamfer Func(S1,S2,HGuide); + BRepBlend_ChamfInv FInv(S1,S2,HGuide); + Func.Set(dis, dis, Choix); + FInv.Set(dis, dis, Choix); + + done = SimulData(Data,HGuide,lin,S1,I1,S2,I2, + Func,FInv,PFirst,MaxStep,locfleche, + TolGuide,First,Last,Inside,Appro,Forward, + Soldep,4,RecOnS1,RecOnS2); + + if ( !done ) return Standard_False; + Handle(ChFiDS_SecHArray1) sec; + gp_Pnt2d pf1,pl1,pf2,pl2; + + Standard_Integer nbp = lin->NbPoints(); + sec = new ChFiDS_SecHArray1(1,nbp); + for( i = 1; i <= nbp; i++ ){ + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u1,v1,u2,v2,ww,p1,p2; + gp_Lin line; + const Blend_Point& p = lin->Point(i); + p.ParametersOnS1(u1,v1); + p.ParametersOnS2(u2,v2); + ww = p.Parameter(); + Func.Section(ww,u1,v1,u2,v2,p1,p2,line); + isec.Set(line,p1,p2); + if(i == 1) {pf1.SetCoord(u1,v1); pf2.SetCoord(u2,v2);} + if(i == nbp) {pl1.SetCoord(u1,v1); pl2.SetCoord(u2,v2);} + } + + Data->SetSimul(sec); + Data->Set2dPoints(pf1,pl1,pf2,pl2); + ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(), + Standard_True, Data->ChangeVertexFirstOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(), + Standard_False,Data->ChangeVertexLastOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(), + Standard_True, Data->ChangeVertexFirstOnS2(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(), + Standard_False, Data->ChangeVertexLastOnS2(),tolesp); + + Standard_Boolean reverse = (!Forward || Inside); + if(intf && reverse){ + Standard_Boolean ok = 0; + const ChFiDS_CommonPoint& cp1 = Data->VertexFirstOnS1(); + if(cp1.IsOnArc()){ + TopoDS_Face F1 = S1->ChangeSurface().Face(); + TopoDS_Face bid; + ok = intf = !SearchFace(Spine,cp1,F1,bid); + } + const ChFiDS_CommonPoint& cp2 = Data->VertexFirstOnS2(); + if(cp2.IsOnArc() && !ok){ + TopoDS_Face F2 = S2->ChangeSurface().Face(); + TopoDS_Face bid; + intf = !SearchFace(Spine,cp2,F2,bid); + } + } + if(intl){ + Standard_Boolean ok = 0; + const ChFiDS_CommonPoint& cp1 = Data->VertexLastOnS1(); + if(cp1.IsOnArc()){ + TopoDS_Face F1 = S1->ChangeSurface().Face(); + TopoDS_Face bid; + ok = intl = !SearchFace(Spine,cp1,F1,bid); + } + const ChFiDS_CommonPoint& cp2 = Data->VertexLastOnS2(); + if(cp2.IsOnArc() && !ok){ + TopoDS_Face F2 = S2->ChangeSurface().Face(); + TopoDS_Face bid; + intl = !SearchFace(Spine,cp2,F2,bid); + } + } + } + else if (chsp->IsChamfer() == ChFiDS_TwoDist) { + Standard_Real dis1, dis2; + chsp->Dists(dis1, dis2); + radius = Max(dis1, dis2); + radius = Max(radius, radiusspine); + locfleche = radius*1.e-2; //graphic criterion + + BRepBlend_Chamfer Func(S1,S2,HGuide); + BRepBlend_ChamfInv FInv(S1,S2,HGuide); + Func.Set(dis1,dis2,Choix); + FInv.Set(dis1,dis2,Choix); + + done = SimulData(Data,HGuide,lin,S1,I1,S2,I2, + Func,FInv,PFirst,MaxStep,locfleche, + TolGuide,First,Last,Inside,Appro,Forward, + Soldep,4,RecOnS1,RecOnS2); + + if ( !done ) return Standard_False; + Handle(ChFiDS_SecHArray1) sec; + gp_Pnt2d pf1,pl1,pf2,pl2; + + Standard_Integer nbp = lin->NbPoints(); + sec = new ChFiDS_SecHArray1(1,nbp); + for( i = 1; i <= nbp; i++ ){ + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u1,v1,u2,v2,ww,p1,p2; + gp_Lin line; + const Blend_Point& p = lin->Point(i); + p.ParametersOnS1(u1,v1); + p.ParametersOnS2(u2,v2); + ww = p.Parameter(); + Func.Section(ww,u1,v1,u2,v2,p1,p2,line); + isec.Set(line,p1,p2); + if(i == 1) {pf1.SetCoord(u1,v1); pf2.SetCoord(u2,v2);} + if(i == nbp) {pl1.SetCoord(u1,v1); pl2.SetCoord(u2,v2);} + } + + Data->SetSimul(sec); + Data->Set2dPoints(pf1,pl1,pf2,pl2); + ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(), + Standard_True, Data->ChangeVertexFirstOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(), + Standard_False,Data->ChangeVertexLastOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(), + Standard_True, Data->ChangeVertexFirstOnS2(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(), + Standard_False, Data->ChangeVertexLastOnS2(),tolesp); + + Standard_Boolean reverse = (!Forward || Inside); + if(intf && reverse){ + Standard_Boolean ok = 0; + const ChFiDS_CommonPoint& cp1 = Data->VertexFirstOnS1(); + if(cp1.IsOnArc()){ + TopoDS_Face F1 = S1->ChangeSurface().Face(); + TopoDS_Face bid; + ok = intf = !SearchFace(Spine,cp1,F1,bid); + } + const ChFiDS_CommonPoint& cp2 = Data->VertexFirstOnS2(); + if(cp2.IsOnArc() && !ok){ + TopoDS_Face F2 = S2->ChangeSurface().Face(); + TopoDS_Face bid; + intf = !SearchFace(Spine,cp2,F2,bid); + } + } + if(intl){ + Standard_Boolean ok = 0; + const ChFiDS_CommonPoint& cp1 = Data->VertexLastOnS1(); + if(cp1.IsOnArc()){ + TopoDS_Face F1 = S1->ChangeSurface().Face(); + TopoDS_Face bid; + ok = intl = !SearchFace(Spine,cp1,F1,bid); + } + const ChFiDS_CommonPoint& cp2 = Data->VertexLastOnS2(); + if(cp2.IsOnArc() && !ok){ + TopoDS_Face F2 = S2->ChangeSurface().Face(); + TopoDS_Face bid; + intl = !SearchFace(Spine,cp2,F2,bid); + } + } + } + else { + Standard_Real dis, angle; + Standard_Boolean disonF1; + chsp->GetDistAngle(dis, angle, disonF1); + radius = Max(dis, dis * tan(angle)); + radius = Max(radius, radiusspine); + locfleche = radius*1.e-2; //graphic criterion + + Standard_Integer Ch = FindChoiceDistAngle(Choix, disonF1); + + if (disonF1) { + BRepBlend_ChAsym Func(S1,S2,HGuide); + BRepBlend_ChAsymInv FInv(S1,S2,HGuide); + + Func.Set(dis, angle, Ch); + FInv.Set(dis, angle, Ch); + + done = SimulData(Data,HGuide,lin,S1,I1,S2,I2, + Func,FInv,PFirst,MaxStep,locfleche, + TolGuide,First,Last,Inside,Appro,Forward, + Soldep,4,RecOnS1,RecOnS2); + + if ( !done ) return Standard_False; + Handle(ChFiDS_SecHArray1) sec; + gp_Pnt2d pf1,pl1,pf2,pl2; + + Standard_Integer nbp = lin->NbPoints(); + sec = new ChFiDS_SecHArray1(1,nbp); + for( i = 1; i <= nbp; i++ ){ + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u1,v1,u2,v2,ww,p1,p2; + gp_Lin line; + const Blend_Point& p = lin->Point(i); + p.ParametersOnS1(u1,v1); + p.ParametersOnS2(u2,v2); + ww = p.Parameter(); + Func.Section(ww,u1,v1,u2,v2,p1,p2,line); + isec.Set(line,p1,p2); + if(i == 1) {pf1.SetCoord(u1,v1); pf2.SetCoord(u2,v2);} + if(i == nbp) {pl1.SetCoord(u1,v1); pl2.SetCoord(u2,v2);} + } + + Data->SetSimul(sec); + Data->Set2dPoints(pf1,pl1,pf2,pl2); + ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(), + Standard_True, Data->ChangeVertexFirstOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(), + Standard_False,Data->ChangeVertexLastOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(), + Standard_True, Data->ChangeVertexFirstOnS2(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(), + Standard_False, Data->ChangeVertexLastOnS2(),tolesp); + + Standard_Boolean reverse = (!Forward || Inside); + if(intf && reverse){ + Standard_Boolean ok = 0; + const ChFiDS_CommonPoint& cp1 = Data->VertexFirstOnS1(); + if(cp1.IsOnArc()){ + TopoDS_Face F1 = S1->ChangeSurface().Face(); + TopoDS_Face bid; + ok = intf = !SearchFace(Spine,cp1,F1,bid); + } + const ChFiDS_CommonPoint& cp2 = Data->VertexFirstOnS2(); + if(cp2.IsOnArc() && !ok){ + TopoDS_Face F2 = S2->ChangeSurface().Face(); + TopoDS_Face bid; + intf = !SearchFace(Spine,cp2,F2,bid); + } + } + + if(intl){ + Standard_Boolean ok = 0; + const ChFiDS_CommonPoint& cp1 = Data->VertexLastOnS1(); + if(cp1.IsOnArc()){ + TopoDS_Face F1 = S1->ChangeSurface().Face(); + TopoDS_Face bid; + ok = intl = !SearchFace(Spine,cp1,F1,bid); + } + const ChFiDS_CommonPoint& cp2 = Data->VertexLastOnS2(); + if(cp2.IsOnArc() && !ok){ + TopoDS_Face F2 = S2->ChangeSurface().Face(); + TopoDS_Face bid; + intl = !SearchFace(Spine,cp2,F2,bid); + } + } + } + else { + BRepBlend_ChAsym Func(S2,S1,HGuide); + BRepBlend_ChAsymInv FInv(S2,S1,HGuide); + + Func.Set(dis, angle, Ch); + FInv.Set(dis, angle, Ch); + + Standard_Real Rtemp; + Rtemp = Soldep(1); + Soldep(1) = Soldep(3); + Soldep(3) = Rtemp; + Rtemp = Soldep(2); + Soldep(2) = Soldep(4); + Soldep(4) = Rtemp; + + done = SimulData(Data,HGuide,lin,S2,I2,S1,I1, + Func,FInv,PFirst,MaxStep,locfleche, + TolGuide,First,Last,Inside,Appro,Forward, + Soldep,4,RecOnS2,RecOnS1); + + if ( !done ) return Standard_False; + Handle(ChFiDS_SecHArray1) sec; + gp_Pnt2d pf1,pl1,pf2,pl2; + + Standard_Integer nbp = lin->NbPoints(); + sec = new ChFiDS_SecHArray1(1,nbp); + for( i = 1; i <= nbp; i++ ){ + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u1,v1,u2,v2,ww,p1,p2; + gp_Lin line; + const Blend_Point& p = lin->Point(i); + p.ParametersOnS1(u1,v1); + p.ParametersOnS2(u2,v2); + ww = p.Parameter(); + Func.Section(ww,u1,v1,u2,v2,p1,p2,line); + isec.Set(line,p1,p2); + if(i == 1) {pf1.SetCoord(u1,v1); pf2.SetCoord(u2,v2);} + if(i == nbp) {pl1.SetCoord(u1,v1); pl2.SetCoord(u2,v2);} + } + + Data->SetSimul(sec); + Data->Set2dPoints(pf1,pl1,pf2,pl2); + ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(), + Standard_True, Data->ChangeVertexFirstOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(), + Standard_False,Data->ChangeVertexLastOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(), + Standard_True, Data->ChangeVertexFirstOnS2(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(), + Standard_False, Data->ChangeVertexLastOnS2(),tolesp); + + Standard_Boolean reverse = (!Forward || Inside); + if(intf && reverse){ + Standard_Boolean ok = 0; + const ChFiDS_CommonPoint& cp1 = Data->VertexFirstOnS1(); + if(cp1.IsOnArc()){ + TopoDS_Face F1 = S1->ChangeSurface().Face(); + TopoDS_Face bid; + ok = intf = !SearchFace(Spine,cp1,F1,bid); + } + const ChFiDS_CommonPoint& cp2 = Data->VertexFirstOnS2(); + if(cp2.IsOnArc() && !ok){ + TopoDS_Face F2 = S2->ChangeSurface().Face(); + TopoDS_Face bid; + intf = !SearchFace(Spine,cp2,F2,bid); + } + } + + if(intl){ + Standard_Boolean ok = 0; + const ChFiDS_CommonPoint& cp1 = Data->VertexLastOnS1(); + if(cp1.IsOnArc()){ + TopoDS_Face F1 = S1->ChangeSurface().Face(); + TopoDS_Face bid; + ok = intl = !SearchFace(Spine,cp1,F1,bid); + } + const ChFiDS_CommonPoint& cp2 = Data->VertexLastOnS2(); + if(cp2.IsOnArc() && !ok){ + TopoDS_Face F2 = S2->ChangeSurface().Face(); + TopoDS_Face bid; + intl = !SearchFace(Spine,cp2,F2,bid); + } + } + } + } + return Standard_True; +} + +void ChFi3d_ChBuilder::SimulSurf(Handle(ChFiDS_SurfData)& , + const Handle(ChFiDS_HElSpine)& , + const Handle(ChFiDS_Spine)& , + const Standard_Integer , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const TopAbs_Orientation , + const Standard_Real , + const Standard_Real , + Standard_Real& , + Standard_Real& , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const math_Vector& ) +{ + Standard_Failure::Raise("SimulSurf Not Implemented"); +} +void ChFi3d_ChBuilder::SimulSurf(Handle(ChFiDS_SurfData)& , + const Handle(ChFiDS_HElSpine)& , + const Handle(ChFiDS_Spine)& , + const Standard_Integer , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const TopAbs_Orientation , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const Standard_Real , + const Standard_Real , + Standard_Real& , + Standard_Real& , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const math_Vector& ) +{ + Standard_Failure::Raise("SimulSurf Not Implemented"); +} +void ChFi3d_ChBuilder::SimulSurf(Handle(ChFiDS_SurfData)& , + const Handle(ChFiDS_HElSpine)& , + const Handle(ChFiDS_Spine)& , + const Standard_Integer , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const TopAbs_Orientation , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const TopAbs_Orientation , + const Standard_Real , + const Standard_Real , + Standard_Real& , + Standard_Real& , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const math_Vector& ) +{ + Standard_Failure::Raise("SimulSurf Not Implemented"); +} +//------------------------MODIFS--------------------------------------- +//======================================================================= +//function : PerformFirstSection +//purpose : to implement the first section if there is no KPart +//======================================================================= + +Standard_Boolean ChFi3d_ChBuilder::PerformFirstSection +(const Handle(ChFiDS_Spine)& Spine, + const Handle(ChFiDS_HElSpine)& HGuide, + const Standard_Integer Choix, + Handle(BRepAdaptor_HSurface)& S1, + Handle(BRepAdaptor_HSurface)& S2, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(Adaptor3d_TopolTool)& I2, + const Standard_Real Par, + math_Vector& SolDep, + TopAbs_State& Pos1, + TopAbs_State& Pos2) const +{ + Handle(ChFiDS_ChamfSpine) + chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Spine); + + if (chsp.IsNull()) + Standard_ConstructionError::Raise + ("PerformSurf : this is not the spine of a chamfer"); + + Standard_Real TolGuide = HGuide->Resolution(tolesp) ; + + + if (chsp->IsChamfer() == ChFiDS_Sym) { + Standard_Real dis; + chsp->GetDist(dis); + + BRepBlend_Chamfer Func(S1,S2,HGuide); + Func.Set(dis,dis,Choix); + BRepBlend_Walking TheWalk(S1,S2,I1,I2); + + //calculate an approximate starting solution + gp_Vec TgF, TgL, tmp1, tmp2, d1gui; + gp_Pnt pt1, pt2, ptgui; + gp_XYZ temp; + + ( HGuide->Curve() ).D1(Par,ptgui,d1gui); + // ptgui = (S1->Surface()).Value(SolDep(1),SolDep(2)); + + Func.Set(Par); + Func.Tangent(SolDep(1),SolDep(2),SolDep(3),SolDep(4),TgF,TgL,tmp1,tmp2); + + Standard_Boolean rev1 = Standard_False; + Standard_Boolean rev2 = Standard_False; + Standard_Real sign = (TgF.Crossed(d1gui)).Dot(TgL); + + if( Choix%2 == 1 ) + rev1 = Standard_True; + else + rev2 = Standard_True; + + if( sign < 0. ){ + rev1 = !rev1; + rev2 = !rev2; + } + + if( rev1 ) + TgF.Reverse(); + if( rev2 ) + TgL.Reverse(); + + temp = (TgF.XYZ()).Multiplied(dis); + pt1.SetXYZ( (ptgui.XYZ()).Added(temp) ); + temp = (TgL.XYZ()).Multiplied(dis); + pt2.SetXYZ( (ptgui.XYZ()).Added(temp) ); + + Standard_Real tol = tolesp*1.e2; +// Standard_Real u,v; + Extrema_GenLocateExtPS proj1(pt1,S1->Surface(),SolDep(1),SolDep(2),tol,tol); + Extrema_GenLocateExtPS proj2(pt2,S2->Surface(),SolDep(3),SolDep(4),tol,tol); + if( proj1.IsDone() ){ + (proj1.Point()).Parameter(SolDep(1),SolDep(2)); + } + if( proj2.IsDone() ){ + (proj2.Point()).Parameter(SolDep(3),SolDep(4)); + } + + return TheWalk.PerformFirstSection(Func,Par,SolDep, + tolesp,TolGuide,Pos1,Pos2); + } + else if (chsp->IsChamfer() == ChFiDS_TwoDist) { + Standard_Real dis1, dis2; + chsp->Dists(dis1, dis2); + + BRepBlend_Chamfer Func(S1,S2,HGuide); + Func.Set(dis1,dis2,Choix); + BRepBlend_Walking TheWalk(S1,S2,I1,I2); + + //calculate an approximate starting solution + gp_Vec TgF, TgL, tmp1, tmp2, d1gui; + gp_Pnt pt1, pt2, ptgui; + gp_XYZ temp; + + ( HGuide->Curve() ).D1(Par,ptgui,d1gui); + // ptgui = (S1->Surface()).Value(SolDep(1),SolDep(2)); + + Func.Set(Par); + Func.Tangent(SolDep(1),SolDep(2),SolDep(3),SolDep(4),TgF,TgL,tmp1,tmp2); + + Standard_Boolean rev1 = Standard_False; + Standard_Boolean rev2 = Standard_False; + Standard_Real sign = (TgF.Crossed(d1gui)).Dot(TgL); + + if( Choix%2 == 1 ) + rev1 = Standard_True; + else + rev2 = Standard_True; + + if( sign < 0. ){ + rev1 = !rev1; + rev2 = !rev2; + } + + if( rev1 ) + TgF.Reverse(); + if( rev2 ) + TgL.Reverse(); + + temp = (TgF.XYZ()).Multiplied(dis1); + pt1.SetXYZ( (ptgui.XYZ()).Added(temp) ); + temp = (TgL.XYZ()).Multiplied(dis2); + pt2.SetXYZ( (ptgui.XYZ()).Added(temp) ); + + Standard_Real tol = tolesp*1.e2; +// Standard_Real u,v; + Extrema_GenLocateExtPS proj1(pt1,S1->Surface(),SolDep(1),SolDep(2),tol,tol); + Extrema_GenLocateExtPS proj2(pt2,S2->Surface(),SolDep(3),SolDep(4),tol,tol); + if( proj1.IsDone() ){ + (proj1.Point()).Parameter(SolDep(1),SolDep(2)); + } + if( proj2.IsDone() ){ + (proj2.Point()).Parameter(SolDep(3),SolDep(4)); + } + + return TheWalk.PerformFirstSection(Func,Par,SolDep, + tolesp,TolGuide,Pos1,Pos2); + } + else { + Standard_Real dis1, angle; + Standard_Boolean disonF1; + chsp->GetDistAngle(dis1, angle, disonF1); + + Standard_Integer Ch = FindChoiceDistAngle(Choix, disonF1); + + if (disonF1) { + BRepBlend_ChAsym Func(S1,S2,HGuide); + Func.Set(dis1, angle, Ch); + BRepBlend_Walking TheWalk(S1,S2,I1,I2); + + //calculate an approximate starting solution + gp_Vec TgF, TgL, tmp1, tmp2, d1gui; + gp_Pnt pt1, pt2, ptgui; + gp_XYZ temp; + + ( HGuide->Curve() ).D1(Par,ptgui,d1gui); + // ptgui = (S1->Surface()).Value(SolDep(1),SolDep(2)); + + Func.Set(Par); + Func.Tangent(SolDep(1),SolDep(2),SolDep(3),SolDep(4),TgF,TgL,tmp1,tmp2); + + Standard_Boolean rev1 = Standard_False; + Standard_Boolean rev2 = Standard_False; + Standard_Real sign = (TgF.Crossed(d1gui)).Dot(TgL); + + if( Ch%2 == 1 ) + rev1 = Standard_True; + else + rev2 = Standard_True; + + if( sign < 0. ){ + rev1 = !rev1; + rev2 = !rev2; + } + + if( rev1 ) + TgF.Reverse(); + if( rev2 ) + TgL.Reverse(); + + temp = (TgF.XYZ()).Multiplied(dis1); + pt1.SetXYZ( (ptgui.XYZ()).Added(temp) ); + + Standard_Real dis2, tmpcos, tmpsin; + tmpcos = TgF.Dot(TgL); + tmpsin = sqrt(1. - tmpcos * tmpcos); + + dis2 = dis1 / (tmpcos + tmpsin / tan(angle)); + + temp = (TgL.XYZ()).Multiplied(dis2); + pt2.SetXYZ( (ptgui.XYZ()).Added(temp) ); + + Standard_Real tol = tolesp*1.e2; +// Standard_Real u,v; + Extrema_GenLocateExtPS proj1(pt1,S1->Surface(),SolDep(1),SolDep(2),tol,tol); + Extrema_GenLocateExtPS proj2(pt2,S2->Surface(),SolDep(3),SolDep(4),tol,tol); + if( proj1.IsDone() ){ + (proj1.Point()).Parameter(SolDep(1),SolDep(2)); + } + if( proj2.IsDone() ){ + (proj2.Point()).Parameter(SolDep(3),SolDep(4)); + } + + return TheWalk.PerformFirstSection(Func,Par,SolDep, + tolesp,TolGuide,Pos1,Pos2); + } + else { + Standard_Real Rtemp; + BRepBlend_ChAsym Func(S2,S1,HGuide); + Func.Set(dis1, angle, Ch); + BRepBlend_Walking TheWalk(S2,S1,I2,I1); + + //calculate an approximate starting solution + gp_Vec TgF, TgL, tmp1, tmp2, d1gui; + gp_Pnt pt1, pt2, ptgui; + gp_XYZ temp; + + ( HGuide->Curve() ).D1(Par,ptgui,d1gui); + // ptgui = (S1->Surface()).Value(SolDep(1),SolDep(2)); + Rtemp = SolDep(1); + SolDep(1) = SolDep(3); + SolDep(3) = Rtemp; + Rtemp = SolDep(2); + SolDep(2) = SolDep(4); + SolDep(4) = Rtemp; + Func.Set(Par); + + Func.Tangent(SolDep(1),SolDep(2),SolDep(3),SolDep(4),TgF,TgL,tmp1,tmp2); + + Standard_Boolean rev1 = Standard_False; + Standard_Boolean rev2 = Standard_False; + Standard_Real sign = (TgF.Crossed(d1gui)).Dot(TgL); + + if( Ch%2 == 1 ) + rev1 = Standard_True; + else + rev2 = Standard_True; + + if( sign < 0. ){ + rev1 = !rev1; + rev2 = !rev2; + } + + if( rev1 ) + TgF.Reverse(); + if( rev2 ) + TgL.Reverse(); + + temp = (TgF.XYZ()).Multiplied(dis1); + pt1.SetXYZ( (ptgui.XYZ()).Added(temp) ); + + Standard_Real dis2, tmpcos, tmpsin; + tmpcos = TgF.Dot(TgL); + tmpsin = sqrt(1. - tmpcos * tmpcos); + + dis2 = dis1 / (tmpcos + tmpsin / tan(angle)); + + temp = (TgL.XYZ()).Multiplied(dis2); + pt2.SetXYZ( (ptgui.XYZ()).Added(temp) ); + + Standard_Real tol = tolesp*1.e2; +// Standard_Real u,v; + Extrema_GenLocateExtPS proj1(pt1,S2->Surface(),SolDep(1),SolDep(2),tol,tol); + Extrema_GenLocateExtPS proj2(pt2,S1->Surface(),SolDep(3),SolDep(4),tol,tol); + if( proj1.IsDone() ) { + (proj1.Point()).Parameter(SolDep(1),SolDep(2)); + } + if( proj2.IsDone() ){ + (proj2.Point()).Parameter(SolDep(3),SolDep(4)); + } + + Standard_Boolean RetWalk = TheWalk.PerformFirstSection(Func,Par,SolDep, + tolesp,TolGuide,Pos2,Pos1); + Rtemp = SolDep(1); + SolDep(1) = SolDep(3); + SolDep(3) = Rtemp; + Rtemp = SolDep(2); + SolDep(2) = SolDep(4); + SolDep(4) = Rtemp; + + return RetWalk; + } + } +} + + +//======================================================================= +//function : PerformSurf +//purpose : +//======================================================================= + +Standard_Boolean +ChFi3d_ChBuilder::PerformSurf(ChFiDS_SequenceOfSurfData& SeqData, + const Handle(ChFiDS_HElSpine)& HGuide, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer Choix, + const Handle(BRepAdaptor_HSurface)& S1, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(BRepAdaptor_HSurface)& S2, + const Handle(Adaptor3d_TopolTool)& I2, + const Standard_Real MaxStep, + const Standard_Real Fleche, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecOnS1, + const Standard_Boolean RecOnS2, + const math_Vector& Soldep, + Standard_Boolean& intf, + Standard_Boolean& intl) + +{ + Handle(ChFiDS_SurfData) Data = SeqData(1); + Handle(ChFiDS_ChamfSpine) + chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Spine); + + if (chsp.IsNull()) + Standard_ConstructionError::Raise + ("PerformSurf : this is not the spine of a chamfer"); + + Standard_Boolean gd1,gd2,gf1,gf2; + Handle(BRepBlend_Line) lin; + TopAbs_Orientation Or = S1->ChangeSurface().Face().Orientation(); + Standard_Real PFirst = First; + if(intf) First = chsp->FirstParameter(1); + if(intl) Last = chsp->LastParameter(chsp->NbEdges()); + + if (chsp->IsChamfer() == ChFiDS_Sym) { + BRepBlend_Chamfer Func(S1,S2,HGuide); + BRepBlend_ChamfInv FInv(S1,S2,HGuide); + Standard_Real dis; + chsp->GetDist(dis); + Func.Set(dis, dis, Choix); + FInv.Set(dis, dis, Choix); + + done = ComputeData(Data,HGuide,Spine,lin,S1,I1,S2,I2,Func,FInv, + PFirst,MaxStep,Fleche,TolGuide,First,Last, + Inside,Appro,Forward,Soldep,intf,intl, + gd1,gd2,gf1,gf2,RecOnS1,RecOnS2); + if(!done) return Standard_False; // ratrappage possible PMN 14/05/1998 + done = CompleteData(Data,Func,lin,S1,S2,Or,gd1,gd2,gf1,gf2); + if(!done) Standard_Failure::Raise("PerformSurf : Fail of approximation!"); + } + else if (chsp->IsChamfer() == ChFiDS_TwoDist) { + BRepBlend_Chamfer Func(S1,S2,HGuide); + BRepBlend_ChamfInv FInv(S1,S2,HGuide); + Standard_Real d1, d2; + chsp->Dists(d1,d2); + Func.Set(d1,d2,Choix); + FInv.Set(d1,d2,Choix); + + done = ComputeData(Data,HGuide,Spine,lin,S1,I1,S2,I2,Func,FInv, + PFirst,MaxStep,Fleche,TolGuide,First,Last, + Inside,Appro,Forward,Soldep,intf,intl, + gd1,gd2,gf1,gf2,RecOnS1,RecOnS2); + if(!done) return Standard_False; // ratrappage possible PMN 14/05/1998 + done = CompleteData(Data,Func,lin,S1,S2,Or,gd1,gd2,gf1,gf2); + if(!done) Standard_Failure::Raise("PerformSurf : Fail of approximation!"); + } + else { + Standard_Real d1, angle; + Standard_Boolean disonF1; + chsp->GetDistAngle(d1, angle, disonF1); + + Standard_Integer Ch = FindChoiceDistAngle(Choix, disonF1); + + if (disonF1) { + BRepBlend_ChAsym Func(S1,S2,HGuide); + BRepBlend_ChAsymInv FInv(S1,S2,HGuide); + Func.Set(d1, angle, Ch); + FInv.Set(d1, angle, Ch); + + done = ComputeData(Data,HGuide,Spine,lin,S1,I1,S2,I2,Func,FInv, + PFirst,MaxStep,Fleche,TolGuide,First,Last, + Inside,Appro,Forward,Soldep,intf,intl, + gd1,gd2,gf1,gf2,RecOnS1,RecOnS2); + + if(!done) return Standard_False; // ratrappage possible PMN 14/05/1998 + done = CompleteData(Data,Func,lin,S1,S2,Or,gd1,gd2,gf1,gf2); + if(!done) Standard_Failure::Raise("PerformSurf : Fail of approximation!"); + } + else { + Standard_Real Rtemp; + BRepBlend_ChAsym Func(S2, S1, HGuide); + BRepBlend_ChAsymInv FInv(S2, S1,HGuide); + Func.Set(d1, angle, Ch); + FInv.Set(d1, angle, Ch); + + Rtemp = Soldep(1); + Soldep(1) = Soldep(3); + Soldep(3) = Rtemp; + Rtemp = Soldep(2); + Soldep(2) = Soldep(4); + Soldep(4) = Rtemp; + + TopAbs_Orientation Or2 = S2->ChangeSurface().Face().Orientation(); + + done = ComputeData(Data,HGuide,Spine,lin,S2,I2,S1,I1,Func,FInv, + PFirst,MaxStep,Fleche,TolGuide,First,Last, + Inside,Appro,Forward,Soldep,intf,intl, + gd2,gd1,gf2,gf1,RecOnS2,RecOnS1); + + ChFiDS_CommonPoint tmp = Data->VertexFirstOnS1(); + Data->ChangeVertexFirstOnS1() = Data->VertexFirstOnS2(); + Data->ChangeVertexFirstOnS2() = tmp; + tmp = Data->VertexLastOnS1(); + Data->ChangeVertexLastOnS1() = Data->VertexLastOnS2(); + Data->ChangeVertexLastOnS2() = tmp; + if(!done) return Standard_False; // ratrappage possible PMN 14/05/1998 + done = CompleteData(Data,Func,lin,S1,S2,Or2,gd1,gd2,gf1,gf2, Standard_True); + if(!done) Standard_Failure::Raise("PerformSurf : Fail of approximation!"); + } + + } + return Standard_True; +} +void ChFi3d_ChBuilder::PerformSurf(ChFiDS_SequenceOfSurfData& , + const Handle(ChFiDS_HElSpine)& , + const Handle(ChFiDS_Spine)& , + const Standard_Integer , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const TopAbs_Orientation , + const Standard_Real , + const Standard_Real , + const Standard_Real , + Standard_Real& , + Standard_Real& , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const math_Vector& ) +{ + Standard_Failure::Raise("PerformSurf Not Implemented"); +} +void ChFi3d_ChBuilder::PerformSurf(ChFiDS_SequenceOfSurfData& , + const Handle(ChFiDS_HElSpine)& , + const Handle(ChFiDS_Spine)& , + const Standard_Integer , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const TopAbs_Orientation , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const Standard_Real , + const Standard_Real , + const Standard_Real , + Standard_Real& , + Standard_Real& , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const math_Vector& ) +{ + Standard_Failure::Raise("PerformSurf Not Implemented"); + +} +void ChFi3d_ChBuilder::PerformSurf(ChFiDS_SequenceOfSurfData& , + const Handle(ChFiDS_HElSpine)& , + const Handle(ChFiDS_Spine)& , + const Standard_Integer , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const TopAbs_Orientation , + const Handle(BRepAdaptor_HSurface)& , + const Handle(Adaptor3d_TopolTool)& , + const Handle(BRepAdaptor_HCurve2d)& , + const Handle(BRepAdaptor_HSurface)& , + const Handle(BRepAdaptor_HCurve2d)& , + Standard_Boolean& , + const TopAbs_Orientation , + const Standard_Real , + const Standard_Real , + const Standard_Real , + Standard_Real& , + Standard_Real& , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const Standard_Boolean , + const math_Vector& ) +{ + Standard_Failure::Raise("PerformSurf Not Implemented"); + +} +//======================================================================= +//function : ExtentOneCorner +//purpose : extends the spine of the stripe S on the side of the vertex V +// PMN : 28/11/97 : Reproduces the code of fillets, and it seems to work better... +//======================================================================= + +void ChFi3d_ChBuilder::ExtentOneCorner(const TopoDS_Vertex& V, + const Handle(ChFiDS_Stripe)& S) +{ + Standard_Integer Sens = 0; + Standard_Real Coeff = 0.5; + Handle(ChFiDS_Spine) Spine = S->Spine(); + ChFi3d_IndexOfSurfData(V,S,Sens); + if (Spine->IsTangencyExtremity((Sens == 1))) return; //No extension on queue + Standard_Real dU = Spine->LastParameter(Spine->NbEdges()); + if (Sens == 1) { + Spine->SetFirstParameter(-dU*Coeff); + Spine->SetFirstTgt(0.); + } + else { + Spine->SetLastParameter(dU*(1.+Coeff)); + Spine->SetLastTgt(dU); + } +/* + Standard_Integer Sens; + Standard_Boolean isfirst; + Standard_Integer Iedge = 1; + Standard_Real d1, d2; + + Handle(ChFiDS_Spine) Spine = S->Spine(); + Handle(ChFiDS_ChamfSpine) + chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Spine); + chsp->Dists(d1,d2); + Standard_Integer IE = ChFi3d_IndexOfSurfData(V,S,Sens); + isfirst = (Sens == 1); + if (!isfirst) + Iedge = Spine->NbEdges(); + + TopTools_ListIteratorOfListOfShape It, Jt; + TopoDS_Edge E1, E2, Ec; + TopoDS_Face F1, F2, Fc; + TopoDS_Edge EdgeSp = Spine->Edges(Iedge); + + ConexFaces(Spine,Iedge,F1,F2); + + for (Jt.Initialize(myVEMap(V));Jt.More();Jt.Next()) { + Ec = TopoDS::Edge(Jt.Value()); + if (!Ec.IsSame(EdgeSp)){ + for (It.Initialize(myEFMap(Ec));It.More();It.Next()) { + Fc = TopoDS::Face(It.Value()); + if (Fc.IsSame(F1)) + E1 = Ec; + else if (Fc.IsSame(F2)) + E2 = Ec; + } + } + } + + gp_Vec tg1, tg2, tgsp; + gp_Pnt tmp, ptgui; + Spine->D1(Spine->Absc(V),ptgui,tgsp); + if (isfirst) + tgsp.Reverse(); + + // tg1 + BRepAdaptor_Curve curv; + curv.Initialize(E1); + curv.D1(curv.FirstParameter(),tmp,tg1); //pour eviter les projections + tg1.Reverse(); + // pbm d'erreurs d'approx : baisser la tolerance + if( !tmp.IsEqual(ptgui,tolesp*1.e2) ) + curv.D1(curv.LastParameter(),tmp,tg1); + + // tg2 + curv.Initialize(E2); + curv.D1(curv.FirstParameter(),tmp,tg2); + tg2.Reverse(); + if( !tmp.IsEqual(ptgui,tolesp*1.e2) ) + curv.D1(curv.LastParameter(),tmp,tg2); + + // calcul de dspine + Standard_Real dspine; + Standard_Real d1plus = 0.; + Standard_Real d2plus = 0.; + + Standard_Real sinalpha = tg1.Dot(tgsp); + if (sinalpha < 0.){ + Standard_Real cosalpha = Sqrt(1 - sinalpha*sinalpha); + d1plus = -d1*sinalpha/cosalpha; + } + sinalpha = tg2.Dot(tgsp); + if (sinalpha < 0.){ + Standard_Real cosalpha = Sqrt(1 - sinalpha*sinalpha); + d2plus = -d2*sinalpha/cosalpha; + } + dspine = d1plus; + if (d2plus > d1plus) + dspine = d2plus; + + dspine *=1.5; + + // ExtentOneCorner + if (isfirst) { + Spine->SetFirstParameter(-dspine); + Spine->SetFirstTgt(0.); + } + else{ + Standard_Real param = Spine->LastParameter(Spine->NbEdges()); + Spine->SetLastParameter(param+dspine); + Spine->SetLastTgt(param); + } */ +} + + + +//======================================================================= +//function : ExtentTwoCorner +//purpose : extends the spines of the stripes contained in the list LS, +// on the side of the vertex V +//======================================================================= + + +void ChFi3d_ChBuilder::ExtentTwoCorner(const TopoDS_Vertex& V, + const ChFiDS_ListOfStripe& LS) +{ +#ifndef DEB + Standard_Integer Sens = 0; +#else + Standard_Integer Sens; +#endif + ChFiDS_ListIteratorOfListOfStripe itel(LS); + Standard_Boolean FF = Standard_True; + Standard_Boolean isfirst[2]; + Standard_Integer Iedge[2]; + Iedge[0] = 1; + Iedge[1] = 1; + Handle(ChFiDS_Stripe) Stripe[2]; + Handle(ChFiDS_Spine) Spine[2]; + + Standard_Integer i = 0; + for (; itel.More(); itel.Next(),i++) { + ChFi3d_IndexOfSurfData(V,itel.Value(),Sens); + if (!FF) + if ( Stripe[1] == itel.Value()) + Sens = -Sens; + + Stripe[i] = itel.Value(); + isfirst[i] = (Sens == 1); + Spine[i] = Stripe[i]->Spine(); + if( !isfirst[i] ) + Iedge[i] = Spine[i]->NbEdges(); + FF = Standard_False; + } + + + Handle(ChFiDS_ChamfSpine) chsp[2]; + Standard_Real d[4], dis[2]; + Standard_Integer j; + TopoDS_Face F[4]; + Standard_Real tmpang, tmd; + Standard_Boolean disonF1; + + + for (i=0, j=0; i<2; i++, j += 2) { + chsp[i] = Handle(ChFiDS_ChamfSpine)::DownCast(Spine[i]); + ConexFaces(Spine[i],Iedge[i],F[j],F[j+1]); + + if (chsp[i]->IsChamfer() == ChFiDS_Sym) { + chsp[i]->GetDist(d[j]); + d[j+1] = d[j]; + } + else if (chsp[i]->IsChamfer() == ChFiDS_TwoDist) { + chsp[i]->Dists(d[j],d[j+1]); + } + else { + chsp[i]->GetDistAngle(tmd, tmpang, disonF1); + // an approximate calculation of distance 2 is done + if (disonF1) { + d[j] = tmd; + d[j+1] = tmd * tan(tmpang); + } + else + { + d[j] = tmd * tan(tmpang); + d[j+1] = tmd; + } + } + + } + + Standard_Boolean notfound = Standard_True; + i = 0; + while (notfound && (i<2)) { + j = 0; + while (notfound && (j<2)) { + if (F[i].IsSame(F[j+2])) { + dis[0] = d[i]; +// dOnArc[0] = d[(i+1)%2]; + + dis[1] = d[j + 2]; +// dOnArc[1] = d[(j+1)%2 + 2]; + notfound = Standard_False; + } + j++; + } + i++; + } + // ExtentTwoCorner + + ChFiDS_State State[2]; + + for (i=0; i<2; i++) { + if (isfirst[i]) + State[i] = Spine[i]->FirstStatus(); + else + State[i] = Spine[i]->LastStatus(); + } + + if (State[0] == ChFiDS_AllSame ){ +/* + // The greatest intersection of the chamfer is found (on the incident edge) + // with the face at end + i = 0; + j = 1; + if(dOnArc[j] > dOnArc[i]) { + Standard_Integer temp = i; + i = j; + j = temp; + } + ExtentOneCorner( V, Stripe[i] ); */ + + // it is necessary that two chamfers touch the face at end + for (j=0; j<2; j++) + ExtentOneCorner( V, Stripe[j] ); + } + else if ((State[0] == ChFiDS_OnSame) && (State[1] == ChFiDS_OnSame)) { + + ExtentSpineOnCommonFace(Spine[0],Spine[1],V,dis[0],dis[1], + isfirst[0],isfirst[1]); + } + +} + +//======================================================================= +//function : ExtentThreeCorner +//purpose : +//======================================================================= + +void ChFi3d_ChBuilder::ExtentThreeCorner(const TopoDS_Vertex& V, + const ChFiDS_ListOfStripe& LS) +{ +#ifndef DEB + Standard_Integer Sens = 0; +#else + Standard_Integer Sens; +#endif + ChFiDS_ListOfStripe check; + Standard_Boolean isfirst[3]; + Standard_Integer Iedge[3]; + Iedge[0] = 1; + Iedge[1] = 1; + Iedge[2] = 1; + Handle(ChFiDS_Spine) Spine[3]; + + Standard_Integer i = 0; + for(ChFiDS_ListIteratorOfListOfStripe itel(LS); itel.More(); itel.Next(), i++) { + Handle(ChFiDS_Stripe) Stripe = itel.Value(); + ChFi3d_IndexOfSurfData(V,Stripe,Sens); + for(ChFiDS_ListIteratorOfListOfStripe ich(check); ich.More(); ich.Next()){ + if(Stripe == ich.Value()){ + Sens = -Sens; + break; + } + } + + isfirst[i] = (Sens == 1); + Spine[i] = Stripe->Spine(); + if( !isfirst[i] ) + Iedge[i] = Spine[i]->NbEdges(); + + check.Append(Stripe); + } + + Standard_Real d[3][2], tmd, tmpangle; + Standard_Boolean disonF1; + Standard_Integer j; + TopoDS_Face F[3][2]; + + Handle(ChFiDS_ChamfSpine) chsp[3]; + + for (i=0; i<3; i++) { + chsp[i] = Handle(ChFiDS_ChamfSpine)::DownCast(Spine[i]); + ConexFaces(Spine[i],Iedge[i],F[i][0],F[i][1]); + + if (chsp[i]->IsChamfer() == ChFiDS_Sym) { + chsp[i]->GetDist(d[i][0]); + d[i][1] = d[i][0]; + } + else if (chsp[i]->IsChamfer() == ChFiDS_TwoDist) { + chsp[i]->Dists(d[i][0],d[i][1]); + } + else { + chsp[i]->GetDistAngle(tmd, tmpangle, disonF1); + // an approximate calculation of distance 2 is done + + if (disonF1) { + d[i][0] = tmd; + d[i][1] = tmd * tan(tmpangle); + } + else { + d[i][0] = tmd * tan(tmpangle); + d[i][1] = tmd; + } + } + } + + + // dis[i][j] distance from chamfer i on the common face with + // chamfer j + Standard_Real dis[3][3]; + + for (i=0; i<3; i++) { +// for (Standard_Integer ii=0; ii<3; ii++) { +// j = (i+ii)%3; + j = (i+1)%3; + Standard_Boolean notfound = Standard_True; + Standard_Integer k, l; + k = 0; + while (notfound && (k<2)) { + l = 0; + while (notfound && (l<2)) { + if (F[i][k].IsSame(F[j][l])) { + dis[i][j] = d[i][k]; + dis[j][i] = d[j][l]; + notfound = Standard_False; + } + l++; + } + k++; + } +// } + } + + //ExtentThreeCorner + for (i=0; i<3; i++) { + j = (i+1)%3; + ExtentSpineOnCommonFace(Spine[i],Spine[j],V,dis[i][j],dis[j][i], + isfirst[i],isfirst[j]); + } + +} + +//======================================================================= +//function : SetRegul +//purpose : +//======================================================================= + +void ChFi3d_ChBuilder::SetRegul() + +{ + ChFiDS_ListIteratorOfRegularities it; + TopTools_ListIteratorOfListOfShape itc; + TopTools_ListIteratorOfListOfShape its1; + TopTools_ListIteratorOfListOfShape its2; + BRepAdaptor_Surface S; + BRepAdaptor_Curve2d PC; + Standard_Real u,v,t; + gp_Pnt p; + gp_Vec n1,n2,du,dv; + BRep_Builder B; + Standard_Real Seuil = PI/360.; + Standard_Real Seuil2 = Seuil * Seuil; + for (it.Initialize(myRegul); it.More(); it.Next()){ + const ChFiDS_Regul& reg = it.Value(); + itc.Initialize(myCoup->NewEdges(reg.Curve())); + if(itc.More()){ + TopoDS_Edge E = TopoDS::Edge(itc.Value()); + if(reg.IsSurface1() && reg.IsSurface2()){ + its1.Initialize(myCoup->NewFaces(reg.S1())); + its2.Initialize(myCoup->NewFaces(reg.S2())); + if(its1.More() && its2.More()){ + TopoDS_Face F1 = TopoDS::Face(its1.Value()); + TopoDS_Face F2 = TopoDS::Face(its2.Value()); + S.Initialize(F1,Standard_False); + PC.Initialize(E,F1); + t = 0.5*(PC.FirstParameter() + PC.LastParameter()); + PC.Value(t).Coord(u,v); + S.D1(u,v,p,du,dv); + n1 = du.Crossed(dv); + + S.Initialize(F2,Standard_False); + PC.Initialize(E,F2); + PC.Value(t).Coord(u,v); + S.D1(u,v,p,du,dv); + n2 = du.Crossed(dv); + + if(n1.SquareMagnitude() > 1.e-14 && n2.SquareMagnitude() > 1.e-14){ + n1.Normalize(); + n2.Normalize(); + Standard_Real sina2 = n1.Crossed(n2).SquareMagnitude(); + if(sina2 < Seuil2) { + GeomAbs_Shape cont = ChFi3d_evalconti(E,F1,F2); + B.Continuity(E,F1,F2,cont); + } + } + } + } + } + } +} + +//======================================================================= +//function : ConexFaces +//purpose : F1, F2 are connected to edge so that F1 corresponds to distance +//======================================================================= + +void ChFi3d_ChBuilder::ConexFaces (const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer IEdge, + TopoDS_Face& F1, + TopoDS_Face& F2) const +{ + BRepAdaptor_Surface Sb1,Sb2; + TopAbs_Orientation tmp1,tmp2; + Standard_Integer RC,Choix; + TopoDS_Face f1,f2,ff1,ff2; + + //calculate the reference orientation + // ChFi3d_Builder::StripeOrientations is private + SearchCommonFaces(myEFMap,Spine->Edges(1),ff1,ff2); + ff1.Orientation(TopAbs_FORWARD); + Sb1.Initialize(ff1); + ff2.Orientation(TopAbs_FORWARD); + Sb2.Initialize(ff2); + RC = ChFi3d::ConcaveSide(Sb1,Sb2,Spine->Edges(1),tmp1,tmp2); + + //calculate the connected faces + SearchCommonFaces(myEFMap,Spine->Edges(IEdge),f1,f2); + Sb1.Initialize(f1); + Sb2.Initialize(f2); + Choix = ChFi3d::ConcaveSide(Sb1,Sb2,Spine->Edges(IEdge),tmp1,tmp2); + + if (RC%2 != Choix%2) { + F1 = f2; + F2 = f1; + } + else { + F1 = f1; + F2 = f2; + } +} + + +//======================================================================= +//function : FindChoiceDistAngle +//purpose : F1, F2 connected to the edge so that F1 corresponds to distance +//======================================================================= + +Standard_Integer ChFi3d_ChBuilder::FindChoiceDistAngle(const Standard_Integer Choice, + const Standard_Boolean DisOnF1) const +{ +#ifndef DEB + Standard_Integer ch = 0; +#else + Standard_Integer ch; +#endif + if (!DisOnF1) { + + switch (Choice) { + case 1 : ch = 2; + break; + case 2 : ch = 1; + break; + case 3 : ch = 8; + break; + case 4 : ch = 7; + break; + case 5 : ch = 6; + break; + case 6 : ch = 5; + break; + case 7 : ch = 4; + break; + case 8 : ch = 3; + break; + } + + } + else + ch = Choice; + + return ch; +} diff --git a/src/ChFi3d/ChFi3d_ChBuilder_C2.cxx b/src/ChFi3d/ChFi3d_ChBuilder_C2.cxx new file mode 100644 index 00000000..a63cce3f --- /dev/null +++ b/src/ChFi3d/ChFi3d_ChBuilder_C2.cxx @@ -0,0 +1,18 @@ +// File: ChFi3d_ChBuilder_C2.cxx +// Created: Fri Jul 26 17:27:36 1996 +// Author: Stagiaire Xuan Trang PHAMPHU +// <xpu@pomalox.paris1.matra-dtv.fr> + + +#include <ChFi3d_ChBuilder.jxx> + +//======================================================================= +//function : PerformTwoCorner +//purpose : + +//======================================================================= + +void ChFi3d_ChBuilder::PerformTwoCorner(const Standard_Integer Index) +{ + PerformTwoCornerbyInter(Index); +} diff --git a/src/ChFi3d/ChFi3d_ChBuilder_C3.cxx b/src/ChFi3d/ChFi3d_ChBuilder_C3.cxx new file mode 100644 index 00000000..be672a05 --- /dev/null +++ b/src/ChFi3d/ChFi3d_ChBuilder_C3.cxx @@ -0,0 +1,883 @@ +// File: ChFi3d_ChBuilder_C3.cxx +// Created: Tue Jul 4 11:21:18 1995 +// Author: Stagiaire Flore Lantheaume +// <fla@phylox> + + +#include <StdFail_NotDone.hxx> +#include <Standard_ConstructionError.hxx> +#include <Standard_NotImplemented.hxx> + +#include <TColStd_ListOfInteger.hxx> +#include <ChFi3d_ChBuilder.jxx> +#include <ChFi3d_Builder_0.hxx> + +#include <ChFiKPart_ComputeData_Fcts.hxx> + +#include <ChFiDS_HData.hxx> +#include <ChFiDS_ListIteratorOfListOfStripe.hxx> +#include <ChFiDS_Stripe.hxx> +#include <ChFiDS_Spine.hxx> +#include <ChFiDS_ChamfSpine.hxx> +#include <ChFiDS_SurfData.hxx> +#include <ChFiDS_Regul.hxx> + +#include <gp.hxx> +#include <gp_Pnt.hxx> +#include <gp_Pnt2d.hxx> +#include <gp_Vec.hxx> +#include <gp_Dir.hxx> +#include <gp_Vec2d.hxx> +#include <gp_Dir2d.hxx> +#include <gp_Lin2d.hxx> + +#include <GeomAbs_SurfaceType.hxx> +#include <Geom_Curve.hxx> +#include <Geom2d_Curve.hxx> +#include <Geom_Surface.hxx> +#include <Geom_Plane.hxx> +#include <Geom2d_Line.hxx> +#include <Geom_Line.hxx> +#include <GeomAdaptor_HSurface.hxx> + +#include <BRepAdaptor_Surface.hxx> +#include <Geom2dAdaptor_Curve.hxx> +#include <Geom2dAdaptor_HCurve.hxx> +#include <IntRes2d_IntersectionPoint.hxx> +#include <Geom2dInt_GInter.hxx> + +#include <GeomInt_IntSS.hxx> +#include <GeomAdaptor_HCurve.hxx> +#include <Geom_TrimmedCurve.hxx> +#include <GeomAPI_ProjectPointOnSurf.hxx> +#include <GeomAPI_ProjectPointOnCurve.hxx> + +#include <TopOpeBRepDS_HDataStructure.hxx> + +#include <TopOpeBRepDS_DataStructure.hxx> +#include <BRepAdaptor_HSurface.hxx> +#include <BRep_Tool.hxx> +#include <BRepLib_MakeEdge.hxx> + +#include <ProjLib_ProjectedCurve.hxx> + +#include <ElSLib.hxx> +#include <ElCLib.hxx> +#include <IntCurveSurface_HInter.hxx> +#include <IntCurveSurface_IntersectionPoint.hxx> + + +#include <Precision.hxx> + + + + +//======================================================================= +//function : CoPlanar +//purpose : Sert a savoir si 4 points sont coplanaires, pour cela on calcul +// la distance de PntD par rapport au plan passant par les trois +// points PntA, PntB, PntC +// +//======================================================================= + +static int CoPlanar(const gp_Pnt PntA, + const gp_Pnt PntB, + const gp_Pnt PntC, + const gp_Pnt PntD) +{ + Standard_Boolean IsCoplanar; + + gp_Vec vecAB(PntA, PntB); + gp_Vec vecAC(PntA, PntC); + gp_Vec vecAD(PntA, PntD); + + Standard_Real nor2AB = vecAB.SquareMagnitude(); + Standard_Real nor2AC = vecAC.SquareMagnitude(); + Standard_Real ProABAC = vecAB.Dot(vecAC); + + + Standard_Real Alpha = nor2AB * nor2AC - ProABAC * ProABAC; + + if (Alpha < Precision::Confusion()) { + IsCoplanar = Standard_True; + } + else { + Standard_Real ProABAD = vecAB.Dot(vecAD); + Standard_Real ProACAD = vecAC.Dot(vecAD); + Standard_Real Alpha1 = ProABAD * nor2AC - ProABAC * ProACAD; + Standard_Real Alpha2 = ProACAD * nor2AB - ProABAC * ProABAD; + gp_Vec vecDABC = Alpha1 * vecAB + Alpha2 * vecAC - Alpha * vecAD; + + IsCoplanar = (vecDABC.Magnitude() / Alpha < Precision::Confusion() ); + + } + + return IsCoplanar; +} + + + + +//======================================================================= +//function : BoundSurf +//purpose : computes a GeomAdaptor_Surface from the surface and trims +// it to allow the intersection computation +//======================================================================= + +static Handle(GeomAdaptor_HSurface) BoundSurf(const Handle(Geom_Surface)& S, + const gp_Pnt2d& Pdeb, + const gp_Pnt2d& Pfin) +{ + Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(); + GeomAdaptor_Surface& GAS = HS->ChangeSurface(); + GAS.Load(S); + + Standard_Real uu1,uu2,vv1,vv2; + Standard_Real uuu1,uuu2,vvv1,vvv2; + S->Bounds(uuu1,uuu2,vvv1,vvv2); + ChFi3d_Boite(Pdeb,Pfin,uu1,uu2,vv1,vv2); + Standard_Real Step = Max((uu2-uu1),(vv2-vv1)); + Step *= 0.2; + uuu1 = Max((uu1-Step),uuu1); uuu2 = Min((uu2+Step),uuu2); + vvv1 = Max((vv1-Step),vvv1); vvv2 = Min((vv2+Step),vvv2); + GAS.Load(S,uuu1,uuu2,vvv1,vvv2); + return HS; +} + +//======================================================================= +//function : ComputeIntersection +//purpose : compute the 3d curve <gc> and the pcurves <pc1> and <pc2> +// of the intersection between one of the 3 SurfData <SD> and +// the SurfData of the corner <SDCoin>. Here we know the +// extremities of the intersection <pdeb> and <pfin>, and +// their parameters <p2dfin>, <p2ddeb> on <SD>. +// <ptcoindeb> cointains the intersection 2d point on the corner +// which corresponds to the point <pdeb> +// <derudeb> and <dervdeb> are the derivative vectors on the +// SurfData <SD> at the point <ptdeb> +//======================================================================= + +static Standard_Boolean ComputeIntersection(TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_SurfData)& SD, + const Handle(ChFiDS_SurfData)& SDCoin, + const gp_Pnt& pdeb, + const gp_Pnt2d& p2ddeb, + const gp_Pnt& pfin, + const gp_Pnt2d& p2dfin, + Handle(Geom_Curve)& gc, + Handle(Geom2d_Curve)& pc1, + Handle(Geom2d_Curve)& pc2, + gp_Vec& derudeb, + gp_Vec& dervdeb, + gp_Pnt2d& ptcoindeb, + const Standard_Real tol3d, + const Standard_Real tol2d, + Standard_Real& tolreached) +{ +// gp_Pnt2d UVf1,UVf2,UVl1,UVl2; + + // take the surface of the pivot SurfData and trim it to allow + // the intersection computation if it's an analytic surface + Handle(GeomAdaptor_HSurface) HS1; + HS1 = ChFi3d_BoundSurf(DStr,SD,1,2); + + const Handle(Geom_Surface)& gpl = DStr.Surface(SDCoin->Surf()).Surface(); + const Handle(Geom_Surface)& gSD = DStr.Surface(SD->Surf()).Surface(); + + // compute pardeb + TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4); + Standard_Real u,v; + gp_Pnt Pbidon; + u = p2ddeb.X(); + v = p2ddeb.Y(); + gSD->D1(u,v,Pbidon,derudeb,dervdeb); + Pardeb(1) = u; + Pardeb(2) = v; +// gp_Pnt2d pd2(u,v); + + ChFi3d_Parameters(gpl,pdeb,u,v); + Pardeb(3) = u; + Pardeb(4) = v; + ptcoindeb.SetCoord(u,v); + + // compute parfin + u = p2dfin.X(); + v = p2dfin.Y(); + Parfin(1) = u; + Parfin(2) = v; +// gp_Pnt2d pf2(u,v); + + ChFi3d_Parameters(gpl,pfin,u,v); + Parfin(3) = u; + Parfin(4) = v; + gp_Pnt2d cpf2(u,v); + + // Trims the chamfer surface to allow the intersection computation + // and computes a GeomAdaptor_Surface for using the ComputeCurves + // function + Handle(GeomAdaptor_HSurface) HS2; + HS2 = BoundSurf(gpl,ptcoindeb,cpf2); + + // compute the intersection curves and pcurves + return ChFi3d_ComputeCurves(HS1,HS2,Pardeb,Parfin,gc, + pc1,pc2,tol3d,tol2d,tolreached); +} + +//====================================================================== +// function : PerformThreeCorner +// purpose : compute the intersection of three chamfers on a same +// vertex of index <Jndex> in myVDataMap +//====================================================================== + +void ChFi3d_ChBuilder::PerformThreeCorner(const Standard_Integer Jndex) +{ + + //modifier pour le passer en option dans le cdl!!!!!!!!!!!! + Standard_Boolean issmooth = Standard_False; + + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Jndex); + ChFiDS_ListIteratorOfListOfStripe It; +// Standard_Integer Index[3],pivot,deb,fin,ii,jj,kk; + Standard_Integer Index[3],pivot=0,deb=0,fin=0,ii; + Handle(ChFiDS_Stripe) CD[3]; + TopoDS_Face face[3]; + Standard_Integer jf[3][3]; + Standard_Boolean sameside[3], oksea[3]; + for(Standard_Integer g = 0; g <= 2; g++){oksea[g] = Standard_False;} + Standard_Integer i[3][3]; + Standard_Integer sens[3]; + Standard_Real p[3][3]; + + Standard_Boolean c1triangle = Standard_False; + + for (It.Initialize(myVDataMap(Jndex)),ii=0;It.More() && ii<3;It.Next(),ii++){ + Index[ii] = ChFi3d_IndexOfSurfData(Vtx,It.Value(),sens[ii]); + CD[ii] = It.Value(); + } + // On verifie que l une des CD ne figure pas deux fois, au quel cas + // il faut modifier le retour de IndexOfSurfData qui prend la + // premiere des solutions. + if(CD[0] == CD[1]){ + Index[1] = CD[1]->SetOfSurfData()->Length(); + sens[1] = -1; + } + else if(CD[1] == CD[2]){ + Index[2] = CD[2]->SetOfSurfData()->Length(); + sens[2] = -1; + } + else if(CD[0] == CD[2]){ + Index[2] = CD[2]->SetOfSurfData()->Length(); + sens[2] = -1; + } + oksea[2] = ChFi3d_SearchFD(DStr,CD[0],CD[1],sens[0],sens[1],i[0][1],i[1][0], + p[0][1],p[1][0],Index[0],Index[1],face[2],sameside[2], + jf[0][1],jf[1][0]); + oksea[1] = ChFi3d_SearchFD(DStr,CD[0],CD[2],sens[0],sens[2],i[0][2],i[2][0], + p[0][2],p[2][0],Index[0],Index[2],face[1],sameside[1], + jf[0][2],jf[2][0]); + oksea[0] = ChFi3d_SearchFD(DStr,CD[1],CD[2],sens[1],sens[2],i[1][2],i[2][1], + p[1][2],p[2][1],Index[1],Index[2],face[0],sameside[0], + jf[1][2],jf[2][1]); + // + // Analyse des concavites des 3 chanfreins : + // - 2 concavites identiques et 1 inverse. + // - 3 concavites identiques + // + Standard_Boolean CornerAllSame = Standard_False; + Standard_Boolean okinter = Standard_True; + Standard_Boolean visavis; + + if(oksea[2] && oksea[1] && !sameside[2] && !sameside[1]) { + pivot = 0; deb = 1; fin = 2; + //on calcule l'intersection des pcurves sans les restreindre a leur common point + if (!oksea[0]) + okinter = ChFi3d_IsInFront(DStr,CD[1],CD[2],i[1][2],i[2][1],sens[1],sens[2], + p[1][2],p[2][1],face[0],sameside[0], + jf[1][2],jf[2][1],visavis,Vtx,Standard_False,1); + } + else if(oksea[2] && oksea[0] && !sameside[2] && !sameside[0]) { + pivot = 1; deb = 2; fin = 0; + if (!oksea[1]) + okinter = ChFi3d_IsInFront(DStr,CD[0],CD[2],i[0][2],i[2][0],sens[0],sens[2], + p[0][2],p[2][0],face[1],sameside[1], + jf[0][2],jf[2][0],visavis,Vtx,Standard_False,1); + } + else if(oksea[1] && oksea[0] && !sameside[1] && !sameside[0]) { + pivot = 2; deb = 0; fin = 1; + if (!oksea[2]) + okinter = ChFi3d_IsInFront(DStr,CD[0],CD[1],i[0][1],i[1][0],sens[0],sens[1], + p[0][1],p[1][0],face[2],sameside[2], + jf[0][1],jf[1][0],visavis,Vtx,Standard_False,1); + } + else if(oksea[0] && oksea[1] && oksea[2]){ + // 3 concavites identiques. + pivot = ChFi3d_SearchPivot(sens,p,tol2d); + if(pivot < 0) + // on prend un pivot au hasard!!!!!!!!!!!!!!! + pivot = 0; + deb = (pivot+1)%3 ; fin = (pivot+2)%3; + CornerAllSame = Standard_True; + } + else Standard_Failure::Raise("FD en vis a vis non trouvees"); + if (!okinter) + Standard_Failure::Raise("Echec intersection PCurves OnCommonFace"); + + // on a le pivot, le CD deb et le CD fin (enfin on espere !?!) : + // ------------------------------------------------------------- + + /* Remarque Importante : dans le cas ou les indices des Surf data + du pivot sur lesquelles ont ete trouvees les intersections de pcurves + ne sont pas egaux, il va y avoir changement de Surf data lors du + cheminement et creations de Surf data mutantes a 3 ou 5 cotes!!! + NON TRAITE !!!!!! (pour l instant)*/ + if(i[pivot][deb] != i[pivot][fin]){ + Standard_NotImplemented::Raise("coin mutant non programme"); + } + /* Autre Remarque : dans le cas ou les indices des Surf data + du deb (de la fin) sur lesquelles ont ete trouvees les intersections + de pcurves ne sont pas egaux, il va y avoir changement de face lors du + cheminement NON GERE !!!!!! (pour l instant). Prevoir un + PerformSetOfSurf adapte.*/ + if(oksea[pivot] && + (i[deb][pivot] != i[deb][fin] || i[fin][pivot] != i[fin][deb])){ + Standard_NotImplemented::Raise("coin sur plusieurs faces non programme"); + } + + Handle(ChFiDS_SurfData)& + fddeb = CD[deb]->ChangeSetOfSurfData()->ChangeValue(i[deb][pivot]); + Handle(ChFiDS_SurfData)& + fdfin = CD[fin]->ChangeSetOfSurfData()->ChangeValue(i[fin][pivot]); + Handle(ChFiDS_SurfData)& + fdpiv = CD[pivot]->ChangeSetOfSurfData()->ChangeValue(i[pivot][deb]); + + + // On construit les HSurfaces et autres outils qui vont bien. + // ---------------------------------------------------------- + + Handle(BRepAdaptor_HSurface) Fac = new BRepAdaptor_HSurface(face[pivot]); + Handle(GeomAdaptor_HSurface) + bidsurf = new GeomAdaptor_HSurface(Fac->ChangeSurface().Surface()); + Handle(Adaptor3d_TopolTool) IFac = new Adaptor3d_TopolTool(bidsurf); + + Handle(GeomAdaptor_HSurface) Surf = ChFi3d_BoundSurf (DStr,fdpiv,jf[pivot][deb],jf[pivot][fin]); + Handle(Adaptor3d_TopolTool) ISurf = new Adaptor3d_TopolTool(Surf); + + // Creation of a new Stripe for the corner + Handle(ChFiDS_Stripe) corner = new ChFiDS_Stripe(); + Handle(ChFiDS_HData)& cornerset = corner->ChangeSetOfSurfData(); + cornerset = new ChFiDS_HData(); + Handle(ChFiDS_SurfData) coin = new ChFiDS_SurfData(); + cornerset->Append(coin); + + // Pour plus de surete, on verifie les intersections des pcurves des chanfreins sur leur + // face commune + Handle(GeomAdaptor_HSurface) HSdeb + = new GeomAdaptor_HSurface( GeomAdaptor_Surface(DStr.Surface(fddeb->Surf()).Surface()) ); + Handle(GeomAdaptor_HSurface) HSfin + = new GeomAdaptor_HSurface( GeomAdaptor_Surface(DStr.Surface(fdfin->Surf()).Surface()) ); + Handle(GeomAdaptor_HSurface) HSpiv + = new GeomAdaptor_HSurface( GeomAdaptor_Surface(DStr.Surface(fdpiv->Surf()).Surface()) ); + + gp_Pnt2d p2d[4]; + gp_Pnt p3d[4], PSom; + + ChFi3d_ComputesIntPC (fdpiv->Interference(jf[pivot][deb]),fddeb->Interference(jf[deb][pivot]), + HSpiv,HSdeb,p[pivot][deb],p[deb][pivot], p3d[fin]); + ChFi3d_ComputesIntPC (fdpiv->Interference(jf[pivot][fin]),fdfin->Interference(jf[fin][pivot]), + HSpiv,HSfin,p[pivot][fin],p[fin][pivot], p3d[deb]); + ChFi3d_ComputesIntPC (fddeb->Interference(jf[deb][fin]),fdfin->Interference(jf[fin][deb]), + HSdeb,HSfin,p[deb][fin],p[fin][deb], PSom); + + + + // On determine les extremites du coin + //------------------------------------ + // c1triangle : on n'a besoin que des 3 points intersection des 3 chanfreins + // sinon : on a les 2 points intersection de fdpiv avec fddeb et fdfin, et on + // cree 2 autres points sur la face commune a l'aide des deux premiers + + // p2d[deb] et p2d[fin] sur la surface du chanfrein fdpiv. + // p2d[piv], p2d[3] (confondus si c1triangle) sur la face en bout du chanfrein de fdpiv + // p2d[piv](resp.vp2d[3]) est sur la Uiso de fddeb(resp. fdfin) passant par p2d[deb] + // (resp. p2d[fin]) + +// if (CornerAllSame) +// c1triangle = (Abs(p[deb][pivot]-p[deb][fin])<tolesp && +// Abs(p[fin][pivot]-p[fin][deb])<tolesp); + + gp_Vec2d Tg3,Tgpiv; + +// if (c1triangle) +// p2d[pivot] = fddeb->Interference(jf[deb][fin]).PCurveOnFace()->Value(p[deb][pivot]); +// else { + if (issmooth) { + fddeb->Interference(jf[deb][fin]).PCurveOnFace()->D1(p[deb][pivot],p2d[pivot],Tgpiv); + fdfin->Interference(jf[fin][deb]).PCurveOnFace()->D1(p[fin][pivot],p2d[3],Tg3); + } + else { + p2d[pivot] = fddeb->Interference(jf[deb][fin]).PCurveOnFace()->Value(p[deb][pivot]); + p2d[3] = fdfin->Interference(jf[fin][deb]).PCurveOnFace()->Value(p[fin][pivot]); + } +// } + p2d[fin] = fdpiv->Interference(jf[pivot][deb]).PCurveOnSurf()->Value(p[pivot][deb]); + p2d[deb] = fdpiv->Interference(jf[pivot][fin]).PCurveOnSurf()->Value(p[pivot][fin]); + +// gp_Pnt pnt; + gp_Vec deru,derv; + +// p3d[fin] = HSpiv->Value(p2d[fin].X(),p2d[fin].Y()); +// p3d[deb] = HSpiv->Value(p2d[deb].X(),p2d[deb].Y()); + Fac->D1(p2d[pivot].X(),p2d[pivot].Y(),p3d[pivot],deru,derv); + gp_Vec norpl = deru.Crossed(derv); +// if (!c1triangle) + p3d[3] = Fac->Value(p2d[3].X(),p2d[3].Y()); + + Standard_Real DistMin = (p3d[3]).Distance(p3d[fin]); + Standard_Real DistTmp = (p3d[pivot]).Distance(p3d[deb]); + Standard_Real DistDebFin = (p3d[pivot]).Distance(p3d[3]); + + if (DistTmp > DistMin) DistMin = DistTmp; + + // on elargi la notion de triangle pour eviter de creer + // des surfaces ecraser avec deux coins proches + // attention ceci entraine un effet de seuil + if (CornerAllSame) + c1triangle = (DistDebFin < 0.3 * DistMin); + + if (c1triangle) + p3d[pivot] = PSom; + + + // on calcule la surface portant le coin + //-------------------------------------- + // Si c1triangle ou les 4 points p3d sont coplanaires, alors + // le chanfrein est porte par le plan passant par les 3 premiers p3d. + // Sinon, on construit le chanfrein par la methode GeomFill_ConstrainedFilling + Standard_Boolean c1plan = c1triangle; + gp_Vec v1(p3d[pivot],p3d[deb]); + gp_Vec v2(p3d[pivot],p3d[fin]); + gp_Vec nor = v1.Crossed(v2); + + done = Standard_False; + + Standard_Integer Icf=0,Icl=0; + Handle(Geom2d_Curve) debpc1,finpc1; + + if (!c1triangle) { + c1plan = CoPlanar(p3d[0], p3d[1], p3d[2], p3d[3]); + } + + if (c1plan) { + // c1plan + //------- + + // on construit le plan + gp_Dir ndir(nor); +// gp_Dir xdir(gp_Vec(p3d[fin],p3d[deb])); + gp_Dir xdir = gp_Dir(gp_Vec(p3d[fin],p3d[deb])); + gp_Ax3 planAx3(p3d[pivot],ndir,xdir); + if (planAx3.YDirection().Dot(v1)<=0.) + planAx3.YReverse(); + Handle(Geom_Plane) gpl= new Geom_Plane(planAx3); + coin->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gpl,DStr)); + + // on oriente coin + gp_Vec norface = norpl; + if (face[pivot].Orientation() == TopAbs_REVERSED ) + norface.Reverse(); + gp_Vec norcoin = gpl->Pln().Position().XDirection(). + Crossed (gpl->Pln().Position().YDirection()); + if ( norcoin.Dot(norface) <= 0. ) + coin->ChangeOrientation() = TopAbs_REVERSED; + else + coin->ChangeOrientation() = TopAbs_FORWARD; + + // on calcule les intersections + Handle(Geom_Curve) gcpiv,gcdeb,gcfin; + Handle(Geom_TrimmedCurve) gcface; + Handle(Geom2d_Curve) pivpc1,pivpc2,debpc2,finpc2,facepc1,facepc2; + gp_Pnt2d ptbid; + + //intersection coin-pivot + Standard_Real tolrcoinpiv; + if (!ComputeIntersection(DStr,fdpiv,coin, + p3d[fin],p2d[fin],p3d[deb],p2d[deb], + gcpiv,pivpc1,pivpc2,deru,derv,ptbid, + tolesp,tol2d,tolrcoinpiv)) + StdFail_NotDone::Raise("echec calcul intersection coin-pivot"); + gp_Vec norpiv = deru.Crossed(derv); + + //intersection coin-deb + Standard_Real tolrcoindeb; + gp_Pnt2d p2d1,p2d2; + if(c1triangle) + p2d1 = fddeb->Interference(jf[deb][fin]).PCurveOnSurf()->Value(p[deb][fin]); + else + p2d1 = fddeb->Interference(jf[deb][fin]).PCurveOnSurf()->Value(p[deb][pivot]); + + p2d2 = fddeb->Interference(jf[deb][pivot]).PCurveOnSurf()->Value(p[deb][pivot]); + + if (!ComputeIntersection(DStr,fddeb,coin, + p3d[pivot],p2d1,p3d[fin],p2d2, + gcdeb,debpc1,debpc2,deru,derv,ptbid, + tolesp,tol2d,tolrcoindeb)) + StdFail_NotDone::Raise("echec calcul intersection coin-deb"); + Icf = DStr.AddCurve(TopOpeBRepDS_Curve(gcdeb,tolrcoindeb)); + + //intersection coin-fin + Standard_Real tolrcoinfin; + gp_Pnt p3dface; + if (c1triangle){ + p3dface = p3d[pivot]; + p2d1 = fdfin->Interference(jf[fin][deb]).PCurveOnSurf()->Value(p[fin][deb]); + } + else { + p3dface = p3d[3]; + p2d1 = fdfin->Interference(jf[fin][deb]).PCurveOnSurf()->Value(p[fin][pivot]); + } + p2d2 = fdfin->Interference(jf[fin][pivot]).PCurveOnSurf()->Value(p[fin][pivot]); + if (!ComputeIntersection(DStr,fdfin,coin, + p3dface,p2d1,p3d[deb],p2d2, + gcfin,finpc1,finpc2,deru,derv,ptbid, + tolesp,tol2d,tolrcoinfin)) + StdFail_NotDone::Raise("echec calcul intersection coin-face"); + Icl = DStr.AddCurve(TopOpeBRepDS_Curve(gcfin,tolrcoinfin)); + + //!c1triangle: intersection coin-face[pivot] + if (!c1triangle) { + GeomInt_IntSS inter; + BRepAdaptor_Surface facebid(face[pivot]); + Handle(Geom_Surface) + surfbid = Handle(Geom_Surface)::DownCast(facebid.Surface().Surface()->Transformed(facebid.Trsf())); + inter.Perform(gpl,surfbid,Precision::Intersection()); + if (inter.IsDone()) { + Standard_Integer nbl = inter.NbLines(); + if (nbl > 1) { +#ifdef DEB + cout<<"trop d'intersection entre les surfaces"<<endl; +#endif + } + else if (nbl == 1) { + ChFi3d_TrimCurve(inter.Line(1),p3d[pivot],p3dface,gcface); + + Handle(GeomAdaptor_HCurve) gac = new GeomAdaptor_HCurve(); + gac->ChangeCurve().Load(gcface); + Handle(GeomAdaptor_HSurface) gas = new GeomAdaptor_HSurface; + gas->ChangeSurface().Load(gpl); + Handle(BRepAdaptor_HSurface) gaf = new BRepAdaptor_HSurface; + gaf->ChangeSurface().Initialize(face[pivot]); + + Standard_Real tolr; + ChFi3d_ProjectPCurv(gac,gaf,facepc1,tolesp,tolr); + ChFi3d_ProjectPCurv(gac,gas,facepc2,tolesp,tolr); + } + } + } + + // on remplit les donnees du coin oriente face-pivot + TopAbs_Orientation trans; + + //avec les CommonPoints + coin->ChangeVertexFirstOnS1().SetPoint(p3d[pivot]); + coin->ChangeVertexFirstOnS2().SetPoint(p3d[fin]); + if (c1triangle) + coin->ChangeVertexLastOnS1().SetPoint(p3d[pivot]); + else + coin->ChangeVertexLastOnS1().SetPoint(p3d[3]); + coin->ChangeVertexLastOnS2().SetPoint(p3d[deb]); + + //avec les FaceInterference +// Standard_Integer Igcpiv,Igcdeb,Igcfin,Igcface; + Standard_Integer Igcpiv,Igcface; + ChFiDS_FaceInterference& fi1 = coin->ChangeInterferenceOnS1(); + ChFiDS_FaceInterference& fi2 = coin->ChangeInterferenceOnS2(); + + //sur face[pivot] + if (norcoin.Dot(norpl) <= 0.) + trans = TopAbs_FORWARD; + else + trans = TopAbs_REVERSED; + Handle(Geom2d_Curve) bidpc; + if (c1triangle) + fi1.SetInterference(0,trans,bidpc,bidpc); + else { + Igcface = ChFiKPart_IndexCurveInDS(gcface,DStr); + fi1.SetInterference(Igcface,trans,facepc1,facepc2); + fi1.SetFirstParameter(gcface->FirstParameter()); + fi1.SetLastParameter(gcface->LastParameter()); + } + //sur le pivot + if (norcoin.Dot(norpiv) <= 0.) + trans = TopAbs_REVERSED; + else + trans = TopAbs_FORWARD; + Igcpiv = ChFiKPart_IndexCurveInDS(gcpiv,DStr); + fi2.SetInterference(Igcpiv,trans,pivpc1,pivpc2); + fi2.SetFirstParameter(gcpiv->FirstParameter()); + fi2.SetLastParameter(gcpiv->LastParameter()); + + done = Standard_True; + + } + else { + // !c1plan + //-------- + + Handle(Geom_Surface) Surfcoin; + Handle(Geom2d_Curve) PCurveOnFace,PCurveOnPiv; + + // le contour a remplir est constitue de courbes isos sur deb et fin + // de deux pcurves calculees sur piv et la face opposee. + Handle(GeomFill_Boundary) Bdeb,Bfin,Bpiv,Bfac; + Standard_Integer ind1 = fddeb->Interference(jf[deb][pivot]).LineIndex(); + Standard_Integer ind2 = fdfin->Interference(jf[fin][pivot]).LineIndex(); + gp_Pnt Pfin,Pdeb; + gp_Vec vpfin,vpdeb; + + DStr.Curve(ind1).Curve()->D1(p[deb][pivot],Pfin,vpfin); + DStr.Curve(ind2).Curve()->D1(p[fin][pivot],Pdeb,vpdeb); + + if (issmooth) { + // les bords de coin sont des lignes courbes qui suivent les + // tangentes donnees + Bfac = ChFi3d_mkbound(Fac,PCurveOnFace,sens[deb],p2d[pivot],Tgpiv, + sens[fin],p2d[3],Tg3,tolesp,2.e-4); + Bpiv = ChFi3d_mkbound(Surf,PCurveOnPiv,sens[deb],p2d[fin],vpfin, + sens[fin],p2d[deb],vpdeb,tolesp,2.e-4); + } + else { + // les bords de coin sont des segments + // Bfac = ChFi3d_mkbound(Fac,PCurveOnFace,p2d[pivot], + // p2d[3],tolesp,2.e-4); + Bfac = ChFi3d_mkbound(Fac,PCurveOnFace,p2d[pivot], + p2d[3],tolesp,2.e-4); + Bpiv = ChFi3d_mkbound(Surf,PCurveOnPiv,p2d[fin], + p2d[deb],tolesp,2.e-4); + } + + gp_Pnt2d pdeb1 = fddeb->Interference(jf[deb][pivot]).PCurveOnSurf()->Value(p[deb][pivot]); + gp_Pnt2d pdeb2 = fddeb->Interference(jf[deb][fin]).PCurveOnSurf()->Value(p[deb][pivot]); + gp_Pnt2d pfin1 = fdfin->Interference(jf[fin][pivot]).PCurveOnSurf()->Value(p[fin][pivot]); + gp_Pnt2d pfin2 = fdfin->Interference(jf[fin][deb]).PCurveOnSurf()->Value(p[fin][pivot]); + + if (issmooth) { + // il faut homogeneiser, mettre les bords "BoundWithSurf" + Bdeb = ChFi3d_mkbound(DStr.Surface(fddeb->Surf()).Surface(),pdeb1,pdeb2,tolesp,2.e-4); + Bfin = ChFi3d_mkbound(DStr.Surface(fdfin->Surf()).Surface(),pfin1,pfin2,tolesp,2.e-4); + } + else { + // ou les 4 bords de type "FreeBoundary" + Bdeb = ChFi3d_mkbound(DStr.Surface(fddeb->Surf()).Surface(),pdeb1,pdeb2, + tolesp,2.e-4,Standard_True); + Bfin = ChFi3d_mkbound(DStr.Surface(fdfin->Surf()).Surface(),pfin1,pfin2, + tolesp,2.e-4,Standard_True); + } + GeomFill_ConstrainedFilling fil(8,20); + fil.Init(Bpiv,Bfin,Bfac,Bdeb); + + Surfcoin = fil.Surface(); + // on se ramene au sens face surf: S1 = face, S2 = surf + Surfcoin->VReverse(); + + done = CompleteData(coin,Surfcoin, + Fac,PCurveOnFace, + Surf,PCurveOnPiv,fdpiv->Orientation(),0, + 0,0,0,0); + } + Standard_Real P1deb,P2deb,P1fin,P2fin; + + if (done){ + Standard_Integer If1,If2,Il1,Il2; + + // Mise a jour des 4 Stripes et de la DS + // ------------------------------------- + + const ChFiDS_CommonPoint& Pf1 = coin->VertexFirstOnS1(); + const ChFiDS_CommonPoint& Pf2 = coin->VertexFirstOnS2(); + ChFiDS_CommonPoint& Pl1 = coin->ChangeVertexLastOnS1(); + if(c1triangle) + Pl1 = coin->ChangeVertexFirstOnS1(); + const ChFiDS_CommonPoint& Pl2 = coin->VertexLastOnS2(); + + // le coin pour commencer, + // ----------------------- + ChFiDS_Regul regdeb, regfin; + If1 = ChFi3d_IndexPointInDS(Pf1,DStr); + If2 = ChFi3d_IndexPointInDS(Pf2,DStr); + if (c1triangle) + Il1 = If1; + else + Il1 = ChFi3d_IndexPointInDS(Pl1,DStr); + Il2 = ChFi3d_IndexPointInDS(Pl2,DStr); + + coin->ChangeIndexOfS1(DStr.AddShape(face[pivot])); + coin->ChangeIndexOfS2(-fdpiv->Surf()); + + // first points + gp_Pnt2d pp1,pp2; + if (c1plan) { + P1deb = DStr.Curve(Icf).Curve()->FirstParameter(); + P2deb = DStr.Curve(Icf).Curve()->LastParameter(); + } + else { + pp1 = coin->InterferenceOnS1().PCurveOnSurf()-> + Value(coin->InterferenceOnS1().FirstParameter()); + pp2 = coin->InterferenceOnS2().PCurveOnSurf()-> + Value( coin->InterferenceOnS2().FirstParameter()); + Handle(Geom_Curve) C3d; + Standard_Real tolreached; + ChFi3d_ComputeArete(Pf1,pp1,Pf2,pp2, + DStr.Surface(coin->Surf()).Surface(),C3d, + corner->ChangeFirstPCurve(),P1deb,P2deb, + tolesp,tol2d,tolreached,0); + TopOpeBRepDS_Curve Tcurv(C3d,tolreached); + Icf = DStr.AddCurve(Tcurv); + } + + regdeb.SetCurve(Icf); + regdeb.SetS1(coin->Surf(),0); + regdeb.SetS2(fddeb->Surf(),0); + myRegul.Append(regdeb); + corner->ChangeFirstCurve(Icf); + corner->ChangeFirstParameters(P1deb,P2deb); + corner->ChangeIndexFirstPointOnS1(If1); + corner->ChangeIndexFirstPointOnS2(If2); + + // last points + if (c1plan) { + P1fin = DStr.Curve(Icl).Curve()->FirstParameter(); + P2fin = DStr.Curve(Icl).Curve()->LastParameter(); + } + else { + pp1 = coin->InterferenceOnS1().PCurveOnSurf()-> + Value(coin->InterferenceOnS1().LastParameter()); + pp2 = coin->InterferenceOnS2().PCurveOnSurf()-> + Value(coin->InterferenceOnS2().LastParameter()); + Handle(Geom_Curve) C3d; + Standard_Real tolreached; + ChFi3d_ComputeArete(Pl1,pp1,Pl2,pp2, + DStr.Surface(coin->Surf()).Surface(),C3d, + corner->ChangeLastPCurve(),P1fin,P2fin, + tolesp,tol2d,tolreached,0); + TopOpeBRepDS_Curve Tcurv(C3d,tolreached); + Icl = DStr.AddCurve(Tcurv); + } + regfin.SetCurve(Icl); + regfin.SetS1(coin->Surf(),0); + regfin.SetS2(fdfin->Surf(),0); + myRegul.Append(regfin); + corner->ChangeLastCurve(Icl); + corner->ChangeLastParameters(P1fin,P2fin); + corner->ChangeIndexLastPointOnS1(Il1); + corner->ChangeIndexLastPointOnS2(Il2); + + // puis la CornerData du debut, + // ---------------------------- + Standard_Boolean isfirst = (sens[deb] == 1), rev = (jf[deb][fin] == 2); + Standard_Integer isurf1 = 1, isurf2 = 2; + Standard_Real par = p[deb][pivot], par2 = p[deb][pivot]; + if(c1triangle) par2 = p[deb][fin]; + if (rev) { + isurf1 = 2; isurf2 = 1; + CD[deb]->SetOrientation(TopAbs_REVERSED,isfirst); + } + CD[deb]->SetCurve(Icf,isfirst); + CD[deb]->SetIndexPoint(If1,isfirst,isurf1); + CD[deb]->SetIndexPoint(If2,isfirst,isurf2); + CD[deb]->SetParameters(isfirst,P1deb,P2deb); + fddeb->ChangeVertex(isfirst,isurf1) = Pf1; + fddeb->ChangeVertex(isfirst,isurf2) = Pf2; + fddeb->ChangeInterference(isurf1).SetParameter(par2,isfirst); + fddeb->ChangeInterference(isurf2).SetParameter(par,isfirst); + if (c1plan) + CD[deb]->ChangePCurve(isfirst) = debpc1; + else { + pp1 = fddeb->InterferenceOnS1().PCurveOnSurf()->Value(par); + pp2 = fddeb->InterferenceOnS2().PCurveOnSurf()->Value(par); + ChFi3d_ComputePCurv(pp1,pp2,CD[deb]->ChangePCurve(isfirst),P1deb,P2deb,rev); + } + + // puis la CornerData de la fin, + // ----------------------------- + isfirst = (sens[fin] == 1); rev = (jf[fin][deb] == 2); + isurf1 = 1; isurf2 = 2; + par = p[fin][pivot]; par2 = p[fin][pivot]; + if(c1triangle) par2 = p[fin][deb]; + if (rev) { + isurf1 = 2; isurf2 = 1; + CD[fin]->SetOrientation(TopAbs_REVERSED,isfirst); + } + CD[fin]->SetCurve(Icl,isfirst); + CD[fin]->SetIndexPoint(Il1,isfirst,isurf1); + CD[fin]->SetIndexPoint(Il2,isfirst,isurf2); + CD[fin]->SetParameters(isfirst,P1fin,P2fin); + fdfin->ChangeVertex(isfirst,isurf1) = Pl1; + fdfin->ChangeVertex(isfirst,isurf2) = Pl2; + fdfin->ChangeInterference(isurf1).SetParameter(par2,isfirst); + fdfin->ChangeInterference(isurf2).SetParameter(par,isfirst); + if (c1plan) + CD[fin]->ChangePCurve(isfirst) = finpc1; + else { + pp1 = fdfin->InterferenceOnS1().PCurveOnSurf()->Value(par); + pp2 = fdfin->InterferenceOnS2().PCurveOnSurf()->Value(par); + ChFi3d_ComputePCurv(pp1,pp2,CD[fin]->ChangePCurve(isfirst),P1fin,P2fin,rev); + } + + // et enfin le pivot. + // ------------------ + ChFiDS_FaceInterference& fi = coin->ChangeInterferenceOnS2(); + isfirst = (sens[pivot] == 1); rev = (jf[pivot][deb] == 2); + isurf1 = 1; isurf2 = 2; + if (rev) { + isurf1 = 2; isurf2 = 1; + CD[pivot]->SetOrientation(TopAbs_REVERSED,isfirst); + } + CD[pivot]->SetCurve(fi.LineIndex(),isfirst); + CD[pivot]->ChangePCurve(isfirst) = fi.PCurveOnFace(); + CD[pivot]->SetIndexPoint(If2,isfirst,isurf1); + CD[pivot]->SetIndexPoint(Il2,isfirst,isurf2); + CD[pivot]->SetParameters(isfirst,fi.FirstParameter(),fi.LastParameter()); + fdpiv->ChangeVertex(isfirst,isurf1) = Pf2; + fdpiv->ChangeVertex(isfirst,isurf2) = Pl2; + fdpiv->ChangeInterference(isurf1).SetParameter(p[pivot][deb],isfirst); + fdpiv->ChangeInterference(isurf2).SetParameter(p[pivot][fin],isfirst); + CD[pivot]->InDS(isfirst); // filDS fait deja le boulot depuis le coin. + } + + //On tronque les corners data et met a jour les index. + //---------------------------------------------------- + + if(i[deb][pivot] < Index[deb]){ + CD[deb]->ChangeSetOfSurfData()->Remove(i[deb][pivot]+1,Index[deb]); + Index[deb] = i[deb][pivot]; + } + else if(i[deb][pivot] > Index[deb]) { + CD[deb]->ChangeSetOfSurfData()->Remove(Index[deb],i[deb][pivot]-1); + i[deb][pivot] = Index[deb]; + } + if(i[fin][pivot] < Index[fin]) { + CD[fin]->ChangeSetOfSurfData()->Remove(i[fin][pivot]+1,Index[fin]); + Index[fin] = i[fin][pivot]; + } + else if(i[fin][pivot] > Index[fin]) { + CD[fin]->ChangeSetOfSurfData()->Remove(Index[fin],i[fin][pivot]-1); + i[fin][pivot] = Index[fin]; + } + // il faudra ici tenir compte des coins mutants. + if(i[pivot][deb] < Index[pivot]) { + CD[pivot]->ChangeSetOfSurfData()->Remove(i[pivot][deb]+1,Index[pivot]); + Index[pivot] = i[pivot][deb]; + } + else if(i[pivot][deb] > Index[pivot]) { + CD[pivot]->ChangeSetOfSurfData()->Remove(Index[pivot],i[pivot][deb]-1); + i[pivot][deb] = Index[pivot]; + } + if(!myEVIMap.IsBound(Vtx)){ + TColStd_ListOfInteger li; + myEVIMap.Bind(Vtx,li); + } + myEVIMap.ChangeFind(Vtx).Append(coin->Surf()); + corner->SetSolidIndex(CD[pivot]->SolidIndex()); + myListStripe.Append(corner); +} diff --git a/src/ChFi3d/ChFi3d_Debug.cxx b/src/ChFi3d/ChFi3d_Debug.cxx new file mode 100644 index 00000000..c61ab92f --- /dev/null +++ b/src/ChFi3d/ChFi3d_Debug.cxx @@ -0,0 +1,298 @@ +// File: ChFi3d_Debug.cxx +// Created: Wed Sep 21 12:49:56 1994 +// Author: Laurent BOURESCHE +// <lbo@phylox> + +#include <stdio.h> + +#include <TopOpeBRepDS_DataStructure.hxx> +#include <ChFiDS_SurfData.hxx> +#include <TopOpeBRepDS_Surface.hxx> +#include <BRep_Builder.hxx> +#include <TopoDS_Vertex.hxx> +#include <TopoDS_Edge.hxx> +#include <TopoDS_Wire.hxx> +#include <TopoDS_Face.hxx> +#include <Geom_Surface.hxx> +#include <Geom2d_Line.hxx> +#include <gp_Pnt.hxx> +#include <gp_Pnt2d.hxx> +#include <gp_Dir.hxx> +#include <gp_Dir2d.hxx> +#include <gp_Vec.hxx> +#include <gp_Vec2d.hxx> +#include <gp_Ax1.hxx> +#include <OSD_Chronometer.hxx> + +#ifdef DRAW +#include <DBRep.hxx> +#endif + +#ifdef DEB +OSD_Chronometer simul,elspine,chemine; +#endif + +//********************************* +// timing of the simulation +//********************************* + +static Standard_Boolean ChFi3d_traceCHRON = Standard_False; +void ChFi3d_SettraceCHRON(const Standard_Boolean b) +{ ChFi3d_traceCHRON = b; } +Standard_Boolean ChFi3d_GettraceCHRON() +{ return ChFi3d_traceCHRON; } + +//********************************* +// trace a line of path +//********************************* + +static Standard_Boolean ChFi3d_traceDRAWWALK = Standard_False; +void ChFi3d_SettraceDRAWWALK(const Standard_Boolean b) +{ ChFi3d_traceDRAWWALK = b; } +Standard_Boolean ChFi3d_GettraceDRAWWALK() +{ return ChFi3d_traceDRAWWALK; } + +//********************************** +// trace a line of intersection +//********************************** + +static Standard_Boolean ChFi3d_traceDRAWINT = Standard_False; +void ChFi3d_SettraceDRAWINT(const Standard_Boolean b) +{ ChFi3d_traceDRAWINT = b; } +Standard_Boolean ChFi3d_GettraceDRAWINT() +{ return ChFi3d_traceDRAWINT; } + +//************************************************* +// return surfaces of approximated fillets. +//************************************************* + +static Standard_Boolean ChFi3d_traceDRAWFIL = Standard_False; +void ChFi3d_SettraceDRAWFIL(const Standard_Boolean b) +{ ChFi3d_traceDRAWFIL = b; } +Standard_Boolean ChFi3d_GettraceDRAWFIL() +{ return ChFi3d_traceDRAWFIL; } + + +//************************************************* +// return extended faces for the path. +//************************************************* + +static Standard_Boolean ChFi3d_traceDRAWENLARGE = Standard_False; +void ChFi3d_SettraceDRAWENLARGE(const Standard_Boolean b) +{ ChFi3d_traceDRAWENLARGE = b; } +Standard_Boolean ChFi3d_GettraceDRAWENLARGE() +{ return ChFi3d_traceDRAWENLARGE; } + +//************************************************* +// return the guideline for the triple corners. +//************************************************* + +static Standard_Boolean ChFi3d_traceDRAWSPINE = Standard_False; +void ChFi3d_SettraceDRAWSPINE(const Standard_Boolean b) +{ ChFi3d_traceDRAWSPINE = b; } +Standard_Boolean ChFi3d_GettraceDRAWSPINE() +{ return ChFi3d_traceDRAWSPINE; } + +//************************************************* +// set the type of guideline for the triple corners. +//************************************************* + +void ChFi3d_SetcontextSPINEBEZIER(const Standard_Boolean b); +void ChFi3d_SetcontextSPINECIRCLE(const Standard_Boolean b); +void ChFi3d_SetcontextSPINECE(const Standard_Boolean b); + +static Standard_Boolean ChFi3d_contextSPINEBEZIER = Standard_False; +void ChFi3d_SetcontextSPINEBEZIER(const Standard_Boolean b){ + ChFi3d_contextSPINEBEZIER = b; + if(b){ + ChFi3d_SetcontextSPINECIRCLE(Standard_False); + ChFi3d_SetcontextSPINECE(Standard_False); + } +} +Standard_Boolean ChFi3d_GetcontextSPINEBEZIER() +{ return ChFi3d_contextSPINEBEZIER; } + +static Standard_Boolean ChFi3d_contextSPINECIRCLE = Standard_False; +void ChFi3d_SetcontextSPINECIRCLE(const Standard_Boolean b){ + ChFi3d_contextSPINECIRCLE = b; + if(b){ + ChFi3d_SetcontextSPINEBEZIER(Standard_False); + ChFi3d_SetcontextSPINECE(Standard_False); + } +} +Standard_Boolean ChFi3d_GetcontextSPINECIRCLE() +{ return ChFi3d_contextSPINECIRCLE; } + +static Standard_Boolean ChFi3d_contextSPINECE = Standard_False; +void ChFi3d_SetcontextSPINECE(const Standard_Boolean b){ + ChFi3d_contextSPINECE = b; + if(b){ + ChFi3d_SetcontextSPINEBEZIER(Standard_False); + ChFi3d_SetcontextSPINECIRCLE(Standard_False); + } +} +Standard_Boolean ChFi3d_GetcontextSPINECE() +{ return ChFi3d_contextSPINECE; } + +//************************************************* +// Forced passage by the path for KPart +//************************************************* +static Standard_Boolean ChFi3d_contextFORCEBLEND = Standard_False; +void ChFi3d_SetcontextFORCEBLEND(const Standard_Boolean b) +{ ChFi3d_contextFORCEBLEND = b; } +Standard_Boolean ChFi3d_GetcontextFORCEBLEND() +{ return ChFi3d_contextFORCEBLEND; } + +static Standard_Boolean ChFi3d_contextFORCEFILLING = Standard_False; +void ChFi3d_SetcontextFORCEFILLING(const Standard_Boolean b) +{ ChFi3d_contextFORCEFILLING = b; } +Standard_Boolean ChFi3d_GetcontextFORCEFILLING() +{ return ChFi3d_contextFORCEFILLING; } + +//************************************************* +// No optimization for approx +//************************************************* +static Standard_Boolean ChFi3d_contextNOOPT = Standard_False; +void ChFi3d_SetcontextNOOPT(const Standard_Boolean b) +{ ChFi3d_contextNOOPT = b; } +Standard_Boolean ChFi3d_GetcontextNOOPT() +{ return ChFi3d_contextNOOPT; } + +// *********************************************** +// initialization and result of a chrono +//************************************************ +Standard_EXPORT void ChFi3d_InitChron(OSD_Chronometer& ch) +{ + ch.Reset(); + ch.Start(); +} + +Standard_EXPORT void ChFi3d_ResultChron( OSD_Chronometer & ch, + Standard_Real & time) +{ + Standard_Real tch ; + ch.Stop(); + ch.Show(tch); + time=time +tch; +} + + +//============================================================== +// function : ChFi3d_CheckSurfData +// purpose : function allows to trace SurfData to check +// construction of all elements, namely pcurves +//============================================================== +#ifdef DRAW +static Standard_Integer NbSD = 0; +#endif +void ChFi3d_CheckSurfData(const TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_SurfData)& Data) +{ + //trace of the surface defined by the chamfer or the fillet + // corresponding to SurfData + + Handle(Geom_Surface) surf = (DStr.Surface( Data->Surf())).Surface(); + if (!surf.IsNull()){ + BRep_Builder B; + TopoDS_Face F; + B.MakeFace(F,surf,0.); + TopoDS_Wire W; + B.MakeWire(W); + + TopoDS_Vertex V1,V2,V3,V4; + B.MakeVertex(V1,Data->VertexFirstOnS1().Point(),0.); + B.MakeVertex(V2,Data->VertexLastOnS1().Point(),0.); + B.MakeVertex(V3,Data->VertexLastOnS2().Point(),0.); + B.MakeVertex(V4,Data->VertexFirstOnS2().Point(),0.); + + TopoDS_Edge E1,E2,E3,E4; + B.MakeEdge(E1); + B.MakeEdge(E2); + B.MakeEdge(E3); + B.MakeEdge(E4); + + B.UpdateEdge(E1,Data->InterferenceOnS1().PCurveOnSurf(),F,0.); + B.UpdateEdge(E3,Data->InterferenceOnS2().PCurveOnSurf(),F,0.); + V1.Orientation(TopAbs_FORWARD); + B.Add(E1,V1); + B.UpdateVertex(V1,Data->InterferenceOnS1().FirstParameter(),E1,0.); + V2.Orientation(TopAbs_REVERSED); + B.Add(E1,V2); + B.UpdateVertex(V2,Data->InterferenceOnS1().LastParameter(),E1,0.); + + + V4.Orientation(TopAbs_FORWARD); + B.Add(E3,V4); + B.UpdateVertex(V4,Data->InterferenceOnS2().FirstParameter(),E3,0.); + V3.Orientation(TopAbs_REVERSED); + B.Add(E3,V3); + B.UpdateVertex(V3,Data->InterferenceOnS2().LastParameter(),E3,0.); + + gp_Pnt2d pp1,pp2,pp3,pp4; + pp1 = Data->InterferenceOnS1().PCurveOnSurf()-> + Value(Data->InterferenceOnS1().FirstParameter()); + pp2 = Data->InterferenceOnS1().PCurveOnSurf()-> + Value(Data->InterferenceOnS1().LastParameter()); + pp3 = Data->InterferenceOnS2().PCurveOnSurf()-> + Value(Data->InterferenceOnS2().LastParameter()); + pp4 = Data->InterferenceOnS2().PCurveOnSurf()-> + Value(Data->InterferenceOnS2().FirstParameter()); + gp_Dir2d d1(gp_Vec2d(pp1,pp4)); + gp_Dir2d d2(gp_Vec2d(pp2,pp3)); + Handle(Geom2d_Line) l1 = new Geom2d_Line(pp1,d1); + Handle(Geom2d_Line) l2 = new Geom2d_Line(pp2,d2); + + B.UpdateEdge(E4,l1,F,0.); + V1.Orientation(TopAbs_FORWARD); + B.Add(E4,V1); + B.UpdateVertex(V1,0.,E4,0.); + V4.Orientation(TopAbs_REVERSED); + B.Add(E4,V4); + B.UpdateVertex(V4,pp4.Distance(pp1),E4,0.); + + B.UpdateEdge(E2,l2,F,0.); + V2.Orientation(TopAbs_FORWARD); + B.Add(E2,V2); + B.UpdateVertex(V2,0.,E2,0.); + V3.Orientation(TopAbs_REVERSED); + B.Add(E2,V3); + B.UpdateVertex(V3,pp3.Distance(pp2),E2,0.); + + gp_Pnt pw1,pw2,ppp; + ppp = surf->Value(pp1.X(),pp1.Y()); + pw1 = surf->Value(0.9*pp1.X()+0.1*pp2.X(),0.9*pp1.Y()+0.1*pp2.Y()); + pw2 = surf->Value(0.9*pp1.X()+0.1*pp4.X(),0.9*pp1.Y()+0.1*pp4.Y()); + gp_Vec vv1(ppp,pw1); + gp_Vec vv2(ppp,pw2); + gp_Vec Vwire = vv1^vv2; + + surf->D1(pp1.X(),pp1.Y(),pw1,vv1,vv2); + gp_Vec Vsurf = vv1^vv2; + Standard_Boolean rev = Vsurf.Dot(Vwire)<=0.; + + E1.Orientation(TopAbs_FORWARD); + E2.Orientation(TopAbs_FORWARD); + E3.Orientation(TopAbs_REVERSED); + E4.Orientation(TopAbs_REVERSED); + if(rev){ + E1.Orientation(TopAbs_REVERSED); + E2.Orientation(TopAbs_REVERSED); + E3.Orientation(TopAbs_FORWARD); + E4.Orientation(TopAbs_FORWARD); + } + B.Add(W,E1); + B.Add(W,E2); + B.Add(W,E3); + B.Add(W,E4); + + W.Orientation(TopAbs_FORWARD); + B.Add(F,W); + +#ifdef DRAW +// char name[100]; + char* name = new char[100]; + sprintf(name,"fillet_%d",NbSD++); + DBRep::Set(name,F); +#endif + } +} diff --git a/src/ChFi3d/ChFi3d_FilBuilder.cdl b/src/ChFi3d/ChFi3d_FilBuilder.cdl new file mode 100644 index 00000000..8af69b7a --- /dev/null +++ b/src/ChFi3d/ChFi3d_FilBuilder.cdl @@ -0,0 +1,466 @@ +-- File: ChFi3d_FilBuilder.cdl +-- Created: Tue Apr 25 10:54:55 1995 +-- Author: Modelistation +-- <model@phylox> +---Copyright: Matra Datavision 1995 + + +class FilBuilder from ChFi3d inherits Builder from ChFi3d + + ---Purpose: Tool of construction of fillets 3d on edges. + +uses + Shape from TopoDS, + Edge from TopoDS, + Vertex from TopoDS, + XY from gp, + State from TopAbs, + Orientation from TopAbs, + Function from Law, + HCurve from Adaptor3d, + TopolTool from Adaptor3d, + HCurve2d from BRepAdaptor, + HSurface from BRepAdaptor, + HElSpine from ChFiDS, + SurfData from ChFiDS, + SequenceOfSurfData from ChFiDS, + Stripe from ChFiDS, + ListOfStripe from ChFiDS, + Spine from ChFiDS, + Function from Blend, + SecHArray1 from ChFiDS, + FilletShape from ChFi3d, + SectionShape from BlendFunc, + Vector from math, + Line from BRepBlend + +is + + Create(S : Shape from TopoDS; + FShape: FilletShape from ChFi3d = ChFi3d_Rational; + Ta : Real from Standard = 1.0e-2) + + returns FilBuilder from ChFi3d; + + SetFilletShape(me: in out; FShape: FilletShape from ChFi3d) + ---Purpose: Sets the type of fillet surface. + + is static; + + GetFilletShape(me) + ---Purpose: Returns the type of fillet surface. + returns FilletShape from ChFi3d + is static; + + ------------------------------------------------ + --- Ajout d un contour sans indication de rayon. + ------------------------------------------------ + + Add(me : in out; E : Edge from TopoDS) + ---Purpose: initialisation of a contour with the first edge + -- (the following are found by propagation). + -- Attention, you need to start with SetRadius. + -- + is static; + + ------------------------------------------------------------------ + --- Ajout ou update d un contour avec un rayon defini pour la + -- totalite du contour. + ------------------------------------------------------------------ + + Add(me : in out; Radius : Real; E : Edge from TopoDS) + ---Purpose: initialisation of the constant vector the corresponding 1st edge. + -- + is static; + + --Add(me : in out; C: Function from Law; E : Edge from TopoDS) + -- ---Purpose: initialisation of the vector (the vector is defined by + -- -- a curve - this is an evolutive vector). + --is static; + + --SetRadius(me : in out; Radius : Real; IC : Integer from Standard) + -- ---Purpose: Set the radius of the contour of index IC. + --is static; + + SetRadius(me : in out; + C : Function from Law; + IC : Integer from Standard; + IinC : Integer from Standard) + ---Purpose: Set the radius of the contour of index IC. + is static; + + IsConstant(me : in out; + IC : Integer from Standard) + returns Boolean from Standard + ---Purpose: Returns true the contour is flaged as edge constant. + is static; + + + Radius(me : in out; + IC : Integer from Standard) + returns Real from Standard + ---Purpose: Returns the vector if the contour is flagged as edge + -- constant. + is static; + + + ResetContour(me : in out; + IC : Integer from Standard) + ---Purpose: Reset all vectors of contour IC. + is static; + + + ------------------------------------------------------------------ + --- Update selectif d un contour avec un rayon constant applique + -- a la portion de contour correspondant a un edge. + ------------------------------------------------------------------ + + SetRadius(me : in out; + Radius : Real; + IC : Integer from Standard; + E : Edge from TopoDS) + ---Purpose: Set a constant on edge E of the contour of + -- index IC. Since then E is flagged as constant. + is static; + + UnSet(me : in out; + IC : Integer from Standard; + E : Edge from TopoDS) + ---Purpose: Extracts the flag constant and the vector of edge E. + is static; + + ------------------------------------------------------------------ + --- Update selectif d un contour avec une valeur de rayon + -- appliquee a un vertex du contour. + ------------------------------------------------------------------ + + SetRadius(me : in out; + Radius : Real; + IC : Integer from Standard; + V : Vertex from TopoDS) + ---Purpose: Set a vector on vertex V of the contour of index IC. + is static; + + UnSet(me : in out; + IC : Integer from Standard; + V : Vertex from TopoDS) + ---Purpose: Extracts the vector of the vertex V. + is static; + + ------------------------------------------------------------------ + --- Update selectif d un contour avec une valeur de rayon + -- appliquee a un parametre du contour. + ------------------------------------------------------------------ + + SetRadius(me : in out; + UandR : XY from gp; + IC : Integer from Standard; + IinC : Integer from Standard) + ---Purpose: Set a vertex on the point of parametre U in the edge IinC + -- of the contour of index IC + is static; + + ------------------------------------------------------------------ + --- Methode pour recuperer et editer la portion de contour a rayon + -- variable ou constant encadrant un edge donne. + ------------------------------------------------------------------ + + IsConstant(me : in out; + IC : Integer from Standard; + E : Edge from TopoDS) + returns Boolean from Standard + ---Purpose: Returns true E is flagged as edge constant. + is static; + + + Radius(me : in out; + IC : Integer from Standard; + E : Edge from TopoDS) + returns Real from Standard + ---Purpose: Returns the vector if E is flagged as edge constant. + is static; + + + GetBounds(me : in out; + IC : Integer from Standard; + E : Edge from TopoDS; + First,Last : out Real from Standard) + returns Boolean from Standard + ---Purpose: Returns in First and Last les extremities of the + -- part of variable vector framing E, returns + -- False if E is flagged as edge constant. + is static; + + GetLaw(me : in out; + IC : Integer from Standard; + E : Edge from TopoDS) + returns mutable Function from Law + ---Purpose: Returns the rule of elementary evolution of the + -- part to variable vector framing E, returns a + -- rule zero if E is flagged as edge constant. + is static; + + SetLaw(me : in out; + IC : Integer from Standard; + E : Edge from TopoDS; + L : Function from Law) + ---Purpose: Sets the rule of elementary evolution of the + -- part to variable vector framing E. + is static; + + + ---Methods for quick simulation + ------------------------------- + + Simulate(me : in out; + IC : Integer from Standard); + + NbSurf(me; IC : Integer from Standard) + returns Integer from Standard; + + Sect(me; IC, IS : Integer from Standard) + returns mutable SecHArray1 from ChFiDS; + + SimulKPart(me; SD : mutable SurfData from ChFiDS) + is protected; + + SimulSurf(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro : Boolean from Standard; + Forward : Boolean from Standard; + RecOnS1,RecOnS2 : Boolean from Standard; + Soldep : Vector from math; + Intf,Intl : in out Boolean from Standard) + returns Boolean is protected; + + SimulSurf(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + PC1 : HCurve2d from BRepAdaptor; + Sref1 : HSurface from BRepAdaptor; + PCref1 : HCurve2d from BRepAdaptor; + Decroch1 : out Boolean from Standard; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + Or2 : Orientation from TopAbs; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard; + Soldep : Vector from math) + is redefined protected; + + SimulSurf(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + Or1 : Orientation from TopAbs; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + PC2 : HCurve2d from BRepAdaptor; + Sref2 : HSurface from BRepAdaptor; + PCref2 : HCurve2d from BRepAdaptor; + Decroch2 : out Boolean from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard; + Soldep : Vector from math) + is redefined protected; + + SimulSurf(me : in out; + Data : out SurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + PC1 : HCurve2d from BRepAdaptor; + Sref1 : HSurface from BRepAdaptor; + PCref1 : HCurve2d from BRepAdaptor; + Decroch1 : out Boolean from Standard; + Or1 : Orientation from TopAbs; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + PC2 : HCurve2d from BRepAdaptor; + Sref2 : HSurface from BRepAdaptor; + PCref2 : HCurve2d from BRepAdaptor; + Decroch2 : out Boolean from Standard; + Or2 : Orientation from TopAbs; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP1,RecRst1 : Boolean from Standard; + RecP2,RecRst2 : Boolean from Standard; + Soldep : Vector from math) + is redefined protected; + + ---Methods for computation + -------------------------- + + PerformFirstSection(me ; + S : Spine from ChFiDS; + HGuide : HElSpine from ChFiDS; + Choix : Integer from Standard; + S1,S2 : in out HSurface from BRepAdaptor; + I1,I2 : TopolTool from Adaptor3d; + Par : Real from Standard; + SolDep : in out Vector from math; + Pos1,Pos2 : out State from TopAbs) + returns Boolean from Standard + is protected; + + PerformSurf(me : in out; + SeqData : out SequenceOfSurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro : Boolean from Standard; + Forward : Boolean from Standard; + RecOnS1,RecOnS2 : Boolean from Standard; + Soldep : Vector from math; + Intf,Intl : in out Boolean from Standard) + returns Boolean + is protected; + ---Purpose: Method calculates the elements of construction of the + -- fillet (constant or evolutive). + + PerformSurf(me : in out; + SeqData : out SequenceOfSurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + PC1 : HCurve2d from BRepAdaptor; + Sref1 : HSurface from BRepAdaptor; + PCref1 : HCurve2d from BRepAdaptor; + Decroch1 : out Boolean from Standard; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + Or2 : Orientation from TopAbs; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard; + Soldep : Vector from math) + is redefined protected; + + PerformSurf(me : in out; + SeqData : out SequenceOfSurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + Or1 : Orientation from TopAbs; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + PC2 : HCurve2d from BRepAdaptor; + Sref2 : HSurface from BRepAdaptor; + PCref2 : HCurve2d from BRepAdaptor; + Decroch2 : out Boolean from Standard; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP,RecS,RecRst : Boolean from Standard; + Soldep : Vector from math) + is redefined protected; + + PerformSurf(me : in out; + Data : out SequenceOfSurfData from ChFiDS; + Guide : HElSpine from ChFiDS; + Spine : Spine from ChFiDS; + Choix : Integer from Standard; + S1 : HSurface from BRepAdaptor; + I1 : TopolTool from Adaptor3d; + PC1 : HCurve2d from BRepAdaptor; + Sref1 : HSurface from BRepAdaptor; + PCref1 : HCurve2d from BRepAdaptor; + Decroch1 : out Boolean from Standard; + Or1 : Orientation from TopAbs; + S2 : HSurface from BRepAdaptor; + I2 : TopolTool from Adaptor3d; + PC2 : HCurve2d from BRepAdaptor; + Sref2 : HSurface from BRepAdaptor; + PCref2 : HCurve2d from BRepAdaptor; + Decroch2 : out Boolean from Standard; + Or2 : Orientation from TopAbs; + MaxStep : Real from Standard; + Fleche : Real from Standard; + TolGuide : Real from Standard; + First,Last : in out Real from Standard; + Inside,Appro,Forward : Boolean from Standard; + RecP1,RecRst1 : Boolean from Standard; + RecP2,RecRst2 : Boolean from Standard; + Soldep : Vector from math) + is redefined protected; + + SplitSurf(me : in out; + SeqData : in out SequenceOfSurfData from ChFiDS; + line : Line from BRepBlend) + is protected; + ---Purpose: Method to split an singular SurfData in several non + -- singular SurfData.. + + PerformTwoCorner(me : in out ; + Index : Integer from Standard) + is protected; + + PerformThreeCorner(me : in out ; + Index : Integer from Standard) + is protected; + + ExtentOneCorner(me : in out; + V : Vertex from TopoDS; + S : Stripe from ChFiDS) + is protected; + + ExtentTwoCorner(me : in out; + V : Vertex from TopoDS; + LS : ListOfStripe from ChFiDS) + is protected; + + ExtentThreeCorner(me : in out; + V : Vertex from TopoDS; + LS : ListOfStripe from ChFiDS) + is protected; + + SetRegul(me : in out) is protected; + +fields + + myShape : SectionShape from BlendFunc; + +end FilBuilder; diff --git a/src/ChFi3d/ChFi3d_FilBuilder.cxx b/src/ChFi3d/ChFi3d_FilBuilder.cxx new file mode 100644 index 00000000..de057d9f --- /dev/null +++ b/src/ChFi3d/ChFi3d_FilBuilder.cxx @@ -0,0 +1,2011 @@ +// File: ChFi3d_FilBuilder.cxx +// Created: Tue Apr 25 11:08:46 1995 +// Modified: MPS : (10-04-97) portage WNT pour GetFilletShape +// Author: Modelistation +// <model@phylox> + + +#include <ChFi3d_FilBuilder.ixx> +#include <ChFi3d_Builder_0.hxx> +#include <ChFi3d_SearchSing.hxx> + +#include <Law_Composite.hxx> +#include <Blend_Point.hxx> +#include <BRepBlend_Walking.hxx> +#include <BRepBlend_Line.hxx> +#include <BRepBlend_ConstRad.hxx> +#include <BRepBlend_ConstRadInv.hxx> +#include <BRepBlend_EvolRad.hxx> +#include <BRepBlend_EvolRadInv.hxx> +#include <BRepBlend_SurfRstConstRad.hxx> +#include <BRepBlend_SurfRstEvolRad.hxx> +#include <BRepBlend_RstRstConstRad.hxx> +#include <BRepBlend_RstRstEvolRad.hxx> +#include <BRepBlend_SurfCurvConstRadInv.hxx> +#include <BRepBlend_SurfCurvEvolRadInv.hxx> +#include <BRepBlend_SurfPointConstRadInv.hxx> +#include <BRepBlend_SurfPointEvolRadInv.hxx> +#include <BRepBlend_CurvPointRadInv.hxx> +#include <ChFiDS_SecHArray1.hxx> +#include <ChFiDS_HData.hxx> +#include <ChFiDS_FilSpine.hxx> +#include <ChFiDS_Stripe.hxx> +#include <ChFiDS_ListOfStripe.hxx> +#include <ChFiDS_ListIteratorOfListOfStripe.hxx> +#include <ChFiDS_ListIteratorOfRegularities.hxx> +#include <ChFiDS_Regul.hxx> +#include <ChFiDS_ErrorStatus.hxx> +#include <TopTools_ListIteratorOfListOfShape.hxx> +#include <TopOpeBRepDS_HDataStructure.hxx> +#include <TopOpeBRepDS_Surface.hxx> +#include <TopOpeBRepDS_Curve.hxx> +#include <TopOpeBRepBuild_HBuilder.hxx> +#include <ElSLib.hxx> +#include <math_FunctionRoot.hxx> +#include <TColStd_SequenceOfReal.hxx> +#include <Precision.hxx> + + +#include <GeomAdaptor_HCurve.hxx> +#include <Geom_Curve.hxx> + +#include <Standard_ConstructionError.hxx> +#include <Standard_Failure.hxx> +#ifdef DEB +extern Standard_Boolean ChFi3d_GettraceCHRON(); +extern Standard_Real t_computedata ,t_completedata; + +extern void ChFi3d_InitChron(OSD_Chronometer& ch); +extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time); +#endif + +static Standard_Real MaxRad(const Handle(ChFiDS_FilSpine)& fsp, + + const TopoDS_Edge& E) +{ + Standard_Integer IE = fsp->Index(E); + + // 1: case of constant R + if (fsp->IsConstant(IE)) + return (fsp->Radius(IE)); + else // 2,3: case of sequence ParAndRad and(or) Laws + return (fsp->MaxRadFromSeqAndLaws()); + +/* + Handle(ChFiDS_HElSpine) HGuide = fsp->ElSpine(IE); + Standard_Real la = HGuide->LastParameter(), fi = HGuide->FirstParameter(); + Standard_Real longueur = la - fi, temp, w; +//#ifndef DEB + Standard_Real radiussect = 0.; +//#else +// Standard_Real radiussect; +//#endif + Handle(Law_Composite) lc = fsp->Law(HGuide); + for(Standard_Integer i = 0; i <= 5; i++){ + w = fi + i*longueur*0.2; + temp = lc->Value(w); + if(temp>radiussect) radiussect = temp; + } + return radiussect; +*/ +} + +static void SimulParams(const Handle(ChFiDS_HElSpine)& HGuide, + const Handle(ChFiDS_FilSpine)& fsp, + Standard_Real& MaxStep, + Standard_Real& Fleche) +{ + Standard_Real la = HGuide->LastParameter(), fi = HGuide->FirstParameter(); + Standard_Real longueur = la - fi; + MaxStep = longueur * 0.05; + Standard_Real w; + //gp_Pnt Pbid; + //gp_Vec d1,d2; + Standard_Real radiussect; + if(fsp->IsConstant()) radiussect = fsp->Radius(); + else { + radiussect = 0.; + Handle(Law_Composite) lc = fsp->Law(HGuide); + for(Standard_Integer i = 0; i <= 5; i++){ + w = fi + i*longueur*0.2; + Standard_Real temp = lc->Value(w); + if(temp>radiussect) radiussect = temp; + } + } + Fleche = radiussect * 0.05; +} + +//======================================================================= +//function : ChFi3d_FilBuilder +//purpose : +//======================================================================= + +ChFi3d_FilBuilder::ChFi3d_FilBuilder(const TopoDS_Shape& S, + const ChFi3d_FilletShape FShape, + const Standard_Real Ta): + ChFi3d_Builder(S, Ta) +{ + SetFilletShape(FShape); +} + +//======================================================================= +//function : SetFilletShape +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::SetFilletShape(const ChFi3d_FilletShape FShape) +{ + switch (FShape) { + case ChFi3d_Rational: + myShape = BlendFunc_Rational; + break; + case ChFi3d_QuasiAngular: + myShape = BlendFunc_QuasiAngular; + break; + case ChFi3d_Polynomial: + myShape = BlendFunc_Polynomial; + break; + } +} + +//======================================================================= +//function : GetFilletShape +//purpose : +//======================================================================= + +ChFi3d_FilletShape ChFi3d_FilBuilder::GetFilletShape() const +{ +#ifndef DEB + ChFi3d_FilletShape filshape = ChFi3d_Rational; // need to set default value +#else + ChFi3d_FilletShape filshape; +#endif + switch (myShape) { + case BlendFunc_Rational: + filshape= ChFi3d_Rational; + break; + case BlendFunc_QuasiAngular: + filshape= ChFi3d_QuasiAngular; + break; + case BlendFunc_Polynomial: + filshape= ChFi3d_Polynomial; + break; + default: + break; + } + return filshape; +} + +//======================================================================= +//function : Add +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::Add(const TopoDS_Edge& E) +{ + if(!Contains(E) && myEFMap.Contains(E)){ + Handle(ChFiDS_Stripe) Stripe = new ChFiDS_Stripe(); + Handle(ChFiDS_Spine)& Sp = Stripe->ChangeSpine(); + Sp = new ChFiDS_FilSpine(tolesp); + Handle(ChFiDS_FilSpine) Spine = Handle(ChFiDS_FilSpine)::DownCast(Sp); + + TopoDS_Edge E_wnt = E; + E_wnt.Orientation(TopAbs_FORWARD); + Spine->SetEdges(E_wnt); + if(PerformElement(Spine)){ + PerformExtremity(Spine); + Spine->Load(); + myListStripe.Append(Stripe); + } + } +} + +//======================================================================= +//function : Add +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::Add(const Standard_Real Radius, const TopoDS_Edge& E) +{ + Add(E); + Standard_Integer IC = Contains(E); + if (IC) + SetRadius( Radius, IC, E ); +} + +//======================================================================= +//function : SetRadius +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::SetRadius(const Handle(Law_Function)& C, + const Standard_Integer IC, + const Standard_Integer IinC) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + fsp->SetRadius(C, IinC); + } +} + +//======================================================================= +//function : IsConstant +//purpose : +//======================================================================= + +Standard_Boolean ChFi3d_FilBuilder::IsConstant(const Standard_Integer IC) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + return fsp->IsConstant(); + } + return 0; +} + +//======================================================================= +//function : Radius +//purpose : +//======================================================================= + +Standard_Real ChFi3d_FilBuilder::Radius(const Standard_Integer IC) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + return fsp->Radius(); + } + return -1.; +} + +//======================================================================= +//function : ResetContour +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::ResetContour(const Standard_Integer IC) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + fsp->Reset(Standard_True); + } +} + +//======================================================================= +//function : SetRadius +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::SetRadius(const Standard_Real Radius, + const Standard_Integer IC, + const TopoDS_Edge& E) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + fsp->SetRadius(Radius, E); + } +} + +//======================================================================= +//function : UnSet +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::UnSet(const Standard_Integer IC, + const TopoDS_Edge& E) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + fsp->UnSetRadius(E); + } +} + +//======================================================================= +//function : SetRadius +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::SetRadius(const Standard_Real Radius, + const Standard_Integer IC, + const TopoDS_Vertex& V) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + fsp->SetRadius(Radius, V); + } +} + +//======================================================================= +//function : UnSet +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::UnSet(const Standard_Integer IC, + const TopoDS_Vertex& V) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + fsp->UnSetRadius(V); + } +} + +//======================================================================= +//function : SetRadius +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::SetRadius(const gp_XY& UandR, + const Standard_Integer IC, + const Standard_Integer IinC) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + fsp->SetRadius( UandR, IinC ); + } +} + +//======================================================================= +//function : IsConstant +//purpose : +//======================================================================= + +Standard_Boolean ChFi3d_FilBuilder::IsConstant(const Standard_Integer IC, + const TopoDS_Edge& E) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + return fsp->IsConstant(fsp->Index(E)); + } + return 0; +} + +//======================================================================= +//function : Radius +//purpose : +//======================================================================= + +Standard_Real ChFi3d_FilBuilder::Radius(const Standard_Integer IC, + const TopoDS_Edge& E) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + return fsp->Radius(E); + } + return -1.; +} + +//======================================================================= +//function : GetBounds +//purpose : +//======================================================================= + +Standard_Boolean ChFi3d_FilBuilder::GetBounds(const Standard_Integer IC, + const TopoDS_Edge& E, + Standard_Real& F, + Standard_Real& L) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + Handle(Law_Function)& loi = fsp->ChangeLaw(E); + if(!loi.IsNull()){ + loi->Bounds(F,L); + return Standard_True; + } + } + return Standard_False; +} + +//======================================================================= +//function : GetLaw +//purpose : +//======================================================================= + +Handle(Law_Function) ChFi3d_FilBuilder::GetLaw(const Standard_Integer IC, + const TopoDS_Edge& E) +{ + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + return fsp->ChangeLaw(E); + } + return Handle(Law_Function)(); +} + +//======================================================================= +//function : SetLaw +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::SetLaw(const Standard_Integer IC, + const TopoDS_Edge& E, + const Handle(Law_Function)& L) +{ + // Check if it is necessary to check borders! + if(IC <= NbElements()) { + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Value(IC)); + fsp->ChangeLaw(E) = L; + } +} + +//======================================================================= +//function : Simulate +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::Simulate (const Standard_Integer IC) +{ +#ifdef DEB + if(ChFi3d_GettraceCHRON()){ + simul.Reset();elspine.Reset();chemine.Reset(); + simul.Start(); + } +#endif + ChFiDS_ListIteratorOfListOfStripe itel; + Standard_Integer i = 1; + for (itel.Initialize(myListStripe);itel.More(); itel.Next(), i++) { + if(i == IC){ + PerformSetOfSurf(itel.Value(), Standard_True); + break; + } + } +#ifdef DEB + if(ChFi3d_GettraceCHRON()){ + simul.Stop(); + cout<<"Total simulation time : "; + simul.Show(); + cout<<"Spine construction time : "; + elspine.Show(); + cout<<"and process time : "; + chemine.Show(); + } +#endif +} + +//======================================================================= +//function : NbSurf +//purpose : +//======================================================================= + +Standard_Integer ChFi3d_FilBuilder::NbSurf (const Standard_Integer IC) const +{ + ChFiDS_ListIteratorOfListOfStripe itel; + Standard_Integer i = 1; + for (itel.Initialize(myListStripe);itel.More(); itel.Next(), i++) { + if(i == IC){ + return itel.Value()->SetOfSurfData()->Length(); + } + } + return 0; +} + +//======================================================================= +//function : Sect +//purpose : +//======================================================================= + +Handle(ChFiDS_SecHArray1) ChFi3d_FilBuilder::Sect (const Standard_Integer IC, + const Standard_Integer IS) const +{ + ChFiDS_ListIteratorOfListOfStripe itel; + Standard_Integer i = 1; + Handle(ChFiDS_SecHArray1) res; + for (itel.Initialize(myListStripe);itel.More(); itel.Next(), i++) { + if(i == IC){ + Handle(MMgt_TShared) bid = itel.Value()->SetOfSurfData()->Value(IS)->Simul(); + res = Handle(ChFiDS_SecHArray1)::DownCast(bid); + return res; + } + } + return Handle(ChFiDS_SecHArray1)(); +} + +//======================================================================= +//function : SimulKPart +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::SimulKPart(const Handle(ChFiDS_SurfData)& SD) const +{ + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + Handle(Geom_Surface) S = DStr.Surface(SD->Surf()).Surface(); + gp_Pnt2d p1f = SD->InterferenceOnS1().PCurveOnSurf()-> + Value(SD->InterferenceOnS1().FirstParameter()); + gp_Pnt2d p1l = SD->InterferenceOnS1().PCurveOnSurf()-> + Value(SD->InterferenceOnS1().LastParameter()); + gp_Pnt2d p2f = SD->InterferenceOnS2().PCurveOnSurf()-> + Value(SD->InterferenceOnS2().FirstParameter()); + gp_Pnt2d p2l = SD->InterferenceOnS2().PCurveOnSurf()-> + Value(SD->InterferenceOnS2().LastParameter()); + GeomAdaptor_Surface AS(S); + Handle(ChFiDS_SecHArray1) sec; + Standard_Real u1,v1,u2,v2; + GeomAbs_SurfaceType typ = AS.GetType(); + switch (typ){ + case GeomAbs_Cylinder: + { + u1 = p1f.X(); + u2 = p2f.X(); + v1 = Max(p1f.Y(),p2f.Y()); + v2 = Min(p1l.Y(),p2l.Y()); + sec = new ChFiDS_SecHArray1(1,2); + gp_Cylinder Cy = AS.Cylinder(); + ChFiDS_CircSection& sec1 = sec->ChangeValue(1); + ChFiDS_CircSection& sec2 = sec->ChangeValue(2); + sec1.Set(ElSLib::CylinderVIso(Cy.Position(), Cy.Radius(), v1), u1, u2); + sec2.Set(ElSLib::CylinderVIso(Cy.Position(), Cy.Radius(), v2), u1, u2); + } + break; + case GeomAbs_Torus: + { + v1 = p1f.Y(); + v2 = p2f.Y(); + u1 = Max(p1f.X(),p2f.X()); + u2 = Min(p1l.X(),p2l.X()); + Standard_Real ang = (u2-u1); + gp_Torus To = AS.Torus(); + Standard_Real majr = To.MajorRadius(), minr = To.MinorRadius(); +//#ifndef DEB + Standard_Integer n = (Standard_Integer) (36.*ang/PI + 1); +//#else +// Standard_Integer n = 36.*ang/PI + 1; +//#endif + if(n<2) n = 2; + sec = new ChFiDS_SecHArray1(1, n); + for (Standard_Integer i = 1; i <= n; i++) { + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u = u1 + (i - 1)*(u2 - u1)/(n-1); + isec.Set(ElSLib::TorusUIso(To.Position(), majr, minr, u), v1, v2); + } + } + break; + case GeomAbs_Sphere: + { + v1 = p1f.Y(); + v2 = p2f.Y(); + u1 = Max(p1f.X(),p2f.X()); + u2 = Min(p1l.X(),p2l.X()); + Standard_Real ang = (u2-u1); + gp_Sphere Sp = AS.Sphere(); + Standard_Real rad = Sp.Radius(); +//#ifndef DEB + Standard_Integer n = (Standard_Integer) (36.*ang/PI + 1); +//#else +// Standard_Integer n = 36.*ang/PI + 1; +//#endif + if(n<2) n = 2; + sec = new ChFiDS_SecHArray1(1, n); + for (Standard_Integer i = 1; i <= n; i++) { + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u = u1 + (i - 1)*(u2 - u1)/(n-1); + isec.Set(ElSLib::SphereUIso(Sp.Position(), rad, u), v1, v2); + } + } + break; + default: + break; + } + SD->SetSimul(sec); +} + + +//======================================================================= +//function : SimulSurf +//purpose : +//======================================================================= + +Standard_Boolean +ChFi3d_FilBuilder::SimulSurf(Handle(ChFiDS_SurfData)& Data, + const Handle(ChFiDS_HElSpine)& HGuide, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer Choix, + const Handle(BRepAdaptor_HSurface)& S1, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(BRepAdaptor_HSurface)& S2, + const Handle(Adaptor3d_TopolTool)& I2, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecOnS1, + const Standard_Boolean RecOnS2, + const math_Vector& Soldep, + Standard_Boolean& intf, + Standard_Boolean& intl) +{ + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Spine); + if(fsp.IsNull()) Standard_ConstructionError::Raise + ("SimulSurf : this is not the spine of the fillet"); + Handle(BRepBlend_Line) lin; +#ifdef DEB +// TopAbs_Orientation Or = S1->ChangeSurface().Face().Orientation(); +#endif + // Flexible parameters!!! + Standard_Real locfleche, MaxStep; + SimulParams(HGuide,fsp,MaxStep,locfleche); + Handle(ChFiDS_SecHArray1) sec; + gp_Pnt2d pf1,pl1,pf2,pl2; + + Standard_Real PFirst = First; + if(intf) First = fsp->FirstParameter(1); + if(intl) Last = fsp->LastParameter(fsp->NbEdges()); + if (fsp->IsConstant()) { + BRepBlend_ConstRad Func(S1,S2,HGuide); + BRepBlend_ConstRadInv FInv(S1,S2,HGuide); + Func.Set(fsp->Radius(),Choix); + FInv.Set(fsp->Radius(),Choix); + Func.Set(myShape); + done = SimulData(Data,HGuide,lin,S1,I1 , + S2,I2,Func,FInv,PFirst,MaxStep,locfleche, + TolGuide,First,Last,Inside,Appro,Forward, + Soldep,4,RecOnS1,RecOnS2); + if(!done) return Standard_False; + Standard_Integer nbp = lin->NbPoints(); + sec = new ChFiDS_SecHArray1(1,nbp); + for(Standard_Integer i = 1; i <= nbp; i++){ + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u1,v1,u2,v2,w,p1,p2; + gp_Circ ci; + const Blend_Point& p = lin->Point(i); + p.ParametersOnS1(u1,v1); + p.ParametersOnS2(u2,v2); + w = p.Parameter(); + Func.Section(w,u1,v1,u2,v2,p1,p2,ci); + isec.Set(ci,p1,p2); + if(i == 1) {pf1.SetCoord(u1,v1); pf2.SetCoord(u2,v2);} + if(i == nbp) {pl1.SetCoord(u1,v1); pl2.SetCoord(u2,v2);} + } + } + else{ + BRepBlend_EvolRad Func(S1,S2,HGuide,fsp->Law(HGuide)); + BRepBlend_EvolRadInv FInv(S1,S2,HGuide,fsp->Law(HGuide)); + Func.Set(Choix); + FInv.Set(Choix); + Func.Set(myShape); + done = SimulData(Data,HGuide,lin,S1,I1 , + S2,I2,Func,FInv,PFirst,MaxStep,locfleche, + TolGuide,First,Last,Inside,Appro,Forward, + Soldep,4,RecOnS1,RecOnS2); + if(!done) return Standard_False; + Standard_Integer nbp = lin->NbPoints(); + sec = new ChFiDS_SecHArray1(1,nbp); + for(Standard_Integer i = 1; i <= nbp; i++){ + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u1,v1,u2,v2,w,p1,p2; + gp_Circ ci; + const Blend_Point& p = lin->Point(i); + p.ParametersOnS1(u1,v1); + p.ParametersOnS2(u2,v2); + w = p.Parameter(); + Func.Section(w,u1,v1,u2,v2,p1,p2,ci); + isec.Set(ci,p1,p2); + if(i == 1) {pf1.SetCoord(u1,v1); pf2.SetCoord(u2,v2);} + if(i == nbp) {pl1.SetCoord(u1,v1); pl2.SetCoord(u2,v2);} + } + } + Data->SetSimul(sec); + Data->Set2dPoints(pf1,pl1,pf2,pl2); + ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(), + Standard_True, Data->ChangeVertexFirstOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(), + Standard_False,Data->ChangeVertexLastOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(), + Standard_True, Data->ChangeVertexFirstOnS2(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(), + Standard_False, Data->ChangeVertexLastOnS2(),tolesp); + Standard_Boolean reverse = (!Forward || Inside); + if(intf && reverse){ + Standard_Boolean ok = 0; + const ChFiDS_CommonPoint& cp1 = Data->VertexFirstOnS1(); + if(cp1.IsOnArc()){ + TopoDS_Face F1 = S1->ChangeSurface().Face(); + TopoDS_Face bid; + ok = intf = !SearchFace(Spine,cp1,F1,bid); + } + const ChFiDS_CommonPoint& cp2 = Data->VertexFirstOnS2(); + if(cp2.IsOnArc() && !ok){ + TopoDS_Face F2 = S2->ChangeSurface().Face(); + TopoDS_Face bid; + intf = !SearchFace(Spine,cp2,F2,bid); + } + } + if(intl){ + Standard_Boolean ok = 0; + const ChFiDS_CommonPoint& cp1 = Data->VertexLastOnS1(); + if(cp1.IsOnArc()){ + TopoDS_Face F1 = S1->ChangeSurface().Face(); + TopoDS_Face bid; + ok = intl = !SearchFace(Spine,cp1,F1,bid); + } + const ChFiDS_CommonPoint& cp2 = Data->VertexLastOnS2(); + if(cp2.IsOnArc() && !ok){ + TopoDS_Face F2 = S2->ChangeSurface().Face(); + TopoDS_Face bid; + intl = !SearchFace(Spine,cp2,F2,bid); + } + } + return Standard_True; +} + +//======================================================================= +//function : SimulSurf +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::SimulSurf(Handle(ChFiDS_SurfData)& Data, + const Handle(ChFiDS_HElSpine)& HGuide, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer Choix, + const Handle(BRepAdaptor_HSurface)& HS1, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(BRepAdaptor_HCurve2d)& PC1, + const Handle(BRepAdaptor_HSurface)& HSref1, + const Handle(BRepAdaptor_HCurve2d)& PCref1, + Standard_Boolean& Decroch1, + const Handle(BRepAdaptor_HSurface)& HS2, + const Handle(Adaptor3d_TopolTool)& I2, + const TopAbs_Orientation Or2, + const Standard_Real /*Fleche*/, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecP, + const Standard_Boolean RecS, + const Standard_Boolean RecRst, + const math_Vector& Soldep) +{ + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Spine); + if(fsp.IsNull()) Standard_ConstructionError::Raise + ("PerformSurf : this is not the spine of the fillet"); + Handle(BRepBlend_Line) lin; + + // Flexible parameters! + Standard_Real locfleche, MaxStep; + SimulParams(HGuide,fsp,MaxStep,locfleche); + Handle(ChFiDS_SecHArray1) sec; + gp_Pnt2d pf,pl,ppcf,ppcl; + + Standard_Real PFirst = First; + if(fsp->IsConstant()){ + BRepBlend_SurfRstConstRad func(HS2,HS1,PC1,HGuide); + func.Set(HSref1,PCref1); + Handle(Adaptor3d_HCurveOnSurface) HC = new Adaptor3d_HCurveOnSurface(); + HC->ChangeCurve().Load(HS1); + HC->ChangeCurve().Load(PC1); + BRepBlend_SurfCurvConstRadInv finvc(HS2,HC,HGuide); + BRepBlend_SurfPointConstRadInv finvp(HS2,HGuide); + BRepBlend_ConstRadInv finv(HS2,HSref1,HGuide); + finv.Set(Standard_False,PCref1); + + Standard_Real rad = fsp->Radius(); + Standard_Integer petitchoix = 1; + if(Or2 == TopAbs_REVERSED) petitchoix = 3; + if(Choix%2 == 0) petitchoix++; + finv.Set(rad,Choix); + finvc.Set(rad,petitchoix); + finvp.Set(rad,petitchoix); + func.Set(rad,petitchoix); + func.Set(myShape); + + done = SimulData(Data,HGuide,lin,HS2,I2,HS1,PC1,I1,Decroch1, + func,finv,finvp,finvc, + PFirst,MaxStep,locfleche,TolGuide,First,Last, + Soldep,4,Inside,Appro,Forward,RecP,RecS,RecRst); + if(!done) { + Standard_Failure::Raise("SimulSurf : Failed process!"); + } + Standard_Integer nbp = lin->NbPoints(); + sec = new ChFiDS_SecHArray1(1,nbp); + for(Standard_Integer i = 1; i <= nbp; i++){ + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u,v,w,param,p1,p2; + gp_Circ ci; + const Blend_Point& p = lin->Point(i); + p.ParametersOnS(u,v); + w = p.ParameterOnC(); + param = p.Parameter(); + func.Section(param,u,v,w,p1,p2,ci); + isec.Set(ci,p1,p2); + if(i == 1) {pf.SetCoord(u,v);p.ParametersOnS2(u,v);ppcf.SetCoord(u,v);} + if(i == nbp) {pl.SetCoord(u,v);p.ParametersOnS2(u,v);ppcl.SetCoord(u,v);} + } + } + else { + BRepBlend_SurfRstEvolRad func(HS2,HS1,PC1,HGuide,fsp->Law(HGuide)); + Handle(Adaptor3d_HCurveOnSurface) HC = new Adaptor3d_HCurveOnSurface(); + HC->ChangeCurve().Load(HS1); + HC->ChangeCurve().Load(PC1); + BRepBlend_SurfCurvEvolRadInv finvc(HS2,HC,HGuide,fsp->Law(HGuide)); + BRepBlend_SurfPointEvolRadInv finvp(HS2,HGuide,fsp->Law(HGuide)); + BRepBlend_EvolRadInv finv(HS2,HSref1,HGuide,fsp->Law(HGuide)); + finv.Set(Standard_False,PCref1); + Standard_Integer petitchoix = 1; + if(Or2 == TopAbs_REVERSED) petitchoix = 3; + if(Choix%2 == 0) petitchoix++; + finv.Set(Choix); + finvc.Set(petitchoix); + finvp.Set(petitchoix); + func.Set(petitchoix); + func.Set(myShape); + done = SimulData(Data,HGuide,lin,HS2,I2,HS1,PC1,I1,Decroch1, + func,finv,finvp,finvc, + PFirst,MaxStep,locfleche,TolGuide,First,Last, + Soldep,4,Inside,Appro,Forward,RecP,RecS,RecRst); + if(!done) Standard_Failure::Raise("SimulSurf : Fail !"); + Standard_Integer nbp = lin->NbPoints(); + sec = new ChFiDS_SecHArray1(1,nbp); + for(Standard_Integer i = 1; i <= nbp; i++){ + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u,v,w,param,p1,p2; + gp_Circ ci; + const Blend_Point& p = lin->Point(i); + p.ParametersOnS(u,v); + w = p.ParameterOnC(); + param = p.Parameter(); + func.Section(param,u,v,w,p1,p2,ci); + isec.Set(ci,p1,p2); + if(i == 1) {pf.SetCoord(u,v);p.ParametersOnS2(u,v);ppcf.SetCoord(u,v);} + if(i == nbp) {pl.SetCoord(u,v);p.ParametersOnS2(u,v);ppcl.SetCoord(u,v);} + } + } + Data->SetSimul(sec); +// gp_Pnt2d pbid; + Data->Set2dPoints(ppcf,ppcl,pf,pl); + ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(), + Standard_True, Data->ChangeVertexFirstOnS2(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(), + Standard_False,Data->ChangeVertexLastOnS2(),tolesp); + ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(), + Standard_True, Data->ChangeVertexFirstOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(), + Standard_False, Data->ChangeVertexLastOnS1(),tolesp); +} + +//======================================================================= +//function : SimulSurf +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::SimulSurf(Handle(ChFiDS_SurfData)& Data, + const Handle(ChFiDS_HElSpine)& HGuide, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer Choix, + const Handle(BRepAdaptor_HSurface)& HS1, + const Handle(Adaptor3d_TopolTool)& I1, + const TopAbs_Orientation Or1, + const Handle(BRepAdaptor_HSurface)& HS2, + const Handle(Adaptor3d_TopolTool)& I2, + const Handle(BRepAdaptor_HCurve2d)& PC2, + const Handle(BRepAdaptor_HSurface)& HSref2, + const Handle(BRepAdaptor_HCurve2d)& PCref2, + Standard_Boolean& Decroch2, + const Standard_Real /*Arrow*/, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecP, + const Standard_Boolean RecS, + const Standard_Boolean RecRst, + const math_Vector& Soldep) +{ + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Spine); + if(fsp.IsNull()) Standard_ConstructionError::Raise + ("PerformSurf : it is not the spine of a fillet"); + Handle(BRepBlend_Line) lin; + + // Flexible parameters! + Standard_Real locfleche, MaxStep; + SimulParams(HGuide,fsp,MaxStep,locfleche); + Handle(ChFiDS_SecHArray1) sec; + gp_Pnt2d pf,pl,ppcf,ppcl; + + Standard_Real PFirst = First; + if(fsp->IsConstant()){ + BRepBlend_SurfRstConstRad func(HS1,HS2,PC2,HGuide); + func.Set(HSref2,PCref2); + Handle(Adaptor3d_HCurveOnSurface) HC = new Adaptor3d_HCurveOnSurface(); + HC->ChangeCurve().Load(HS2); + HC->ChangeCurve().Load(PC2); + BRepBlend_SurfCurvConstRadInv finvc(HS1,HC,HGuide); + BRepBlend_SurfPointConstRadInv finvp(HS1,HGuide); + BRepBlend_ConstRadInv finv(HS1,HSref2,HGuide); + finv.Set(Standard_False,PCref2); + + Standard_Real rad = fsp->Radius(); + Standard_Integer petitchoix = 1; + if(Or1 == TopAbs_REVERSED) petitchoix = 3; + if(Choix%2 == 0) petitchoix++; + finv.Set(rad,Choix); + finvc.Set(rad,petitchoix); + finvp.Set(rad,petitchoix); + func.Set(rad,petitchoix); + func.Set(myShape); + + done = SimulData(Data,HGuide,lin,HS1,I1,HS2,PC2,I2,Decroch2, + func,finv,finvp,finvc, + PFirst,MaxStep,locfleche,TolGuide,First,Last, + Soldep,4,Inside,Appro,Forward,RecP,RecS,RecRst); + if(!done) Standard_Failure::Raise("SimulSurf : Failed Processing!"); + Standard_Integer nbp = lin->NbPoints(); + sec = new ChFiDS_SecHArray1(1,nbp); + for(Standard_Integer i = 1; i <= nbp; i++){ + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u,v,w,param,p1,p2; + gp_Circ ci; + const Blend_Point& p = lin->Point(i); + p.ParametersOnS(u,v); + w = p.ParameterOnC(); + param = p.Parameter(); + func.Section(param,u,v,w,p1,p2,ci); + isec.Set(ci,p1,p2); + if(i == 1) {pf.SetCoord(u,v);p.ParametersOnS2(u,v);ppcf.SetCoord(u,v);} + if(i == nbp) {pl.SetCoord(u,v);p.ParametersOnS2(u,v);ppcl.SetCoord(u,v);} + } + } + else { + BRepBlend_SurfRstEvolRad func(HS1,HS2,PC2,HGuide,fsp->Law(HGuide)); + Handle(Adaptor3d_HCurveOnSurface) HC = new Adaptor3d_HCurveOnSurface(); + HC->ChangeCurve().Load(HS2); + HC->ChangeCurve().Load(PC2); + BRepBlend_SurfCurvEvolRadInv finvc(HS1,HC,HGuide,fsp->Law(HGuide)); + BRepBlend_SurfPointEvolRadInv finvp(HS1,HGuide,fsp->Law(HGuide)); + BRepBlend_EvolRadInv finv(HS1,HSref2,HGuide,fsp->Law(HGuide)); + finv.Set(Standard_False,PCref2); + Standard_Integer petitchoix = 1; + if(Or1 == TopAbs_REVERSED) petitchoix = 3; + if(Choix%2 == 0) petitchoix++; + finv.Set(Choix); + finvc.Set(petitchoix); + finvp.Set(petitchoix); + func.Set(petitchoix); + func.Set(myShape); + done = SimulData(Data,HGuide,lin,HS1,I1,HS2,PC2,I2,Decroch2, + func,finv,finvp,finvc, + PFirst,MaxStep,locfleche,TolGuide,First,Last, + Soldep,4,Inside,Appro,Forward,RecP,RecS,RecRst); + if(!done) Standard_Failure::Raise("SimulSurf : Fail !"); + Standard_Integer nbp = lin->NbPoints(); + sec = new ChFiDS_SecHArray1(1,nbp); + for(Standard_Integer i = 1; i <= nbp; i++){ + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u,v,w,param,p1,p2; + gp_Circ ci; + const Blend_Point& p = lin->Point(i); + p.ParametersOnS(u,v); + w = p.ParameterOnC(); + param = p.Parameter(); + func.Section(param,u,v,w,p1,p2,ci); + isec.Set(ci,p1,p2); + if(i == 1) {pf.SetCoord(u,v);p.ParametersOnS2(u,v);ppcf.SetCoord(u,v);} + if(i == nbp) {pl.SetCoord(u,v);p.ParametersOnS2(u,v);ppcl.SetCoord(u,v);} + } + } + Data->SetSimul(sec); + //gp_Pnt2d pbid; + Data->Set2dPoints(pf,pl,ppcf,ppcl); + ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(), + Standard_True, Data->ChangeVertexFirstOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(), + Standard_False,Data->ChangeVertexLastOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(), + Standard_True, Data->ChangeVertexFirstOnS2(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(), + Standard_False, Data->ChangeVertexLastOnS2(),tolesp); +} + + + +//======================================================================= +//function : SimulSurf +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::SimulSurf(Handle(ChFiDS_SurfData)& Data, + const Handle(ChFiDS_HElSpine)& HGuide, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer Choix, + const Handle(BRepAdaptor_HSurface)& HS1, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(BRepAdaptor_HCurve2d)& PC1, + const Handle(BRepAdaptor_HSurface)& HSref1, + const Handle(BRepAdaptor_HCurve2d)& PCref1, + Standard_Boolean& Decroch1, + const TopAbs_Orientation Or1, + const Handle(BRepAdaptor_HSurface)& HS2, + const Handle(Adaptor3d_TopolTool)& I2, + const Handle(BRepAdaptor_HCurve2d)& PC2, + const Handle(BRepAdaptor_HSurface)& HSref2, + const Handle(BRepAdaptor_HCurve2d)& PCref2, + Standard_Boolean& Decroch2, + const TopAbs_Orientation Or2, + const Standard_Real /*Fleche*/, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecP1, + const Standard_Boolean RecRst1, + const Standard_Boolean RecP2, + const Standard_Boolean RecRst2, + const math_Vector& Soldep) +{ + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Spine); + if(fsp.IsNull()) Standard_ConstructionError::Raise + ("PerformSurf : it is not the spine of a fillet"); + Handle(BRepBlend_Line) lin; + + // Flexible parameters! + Standard_Real locfleche, MaxStep; + SimulParams(HGuide,fsp,MaxStep,locfleche); + Handle(ChFiDS_SecHArray1) sec; +// gp_Pnt2d pf,pl; + + Standard_Integer ch1 = 1, ch2 = 2; + Standard_Real PFirst = First; + + if(fsp->IsConstant()){ + BRepBlend_RstRstConstRad func(HS1, PC1, HS2, PC2, HGuide); + func.Set(HSref1, PCref1, HSref2, PCref2); + Handle(Adaptor3d_HCurveOnSurface) HC1 = new Adaptor3d_HCurveOnSurface(); + HC1->ChangeCurve().Load(HS1); + HC1->ChangeCurve().Load(PC1); + Handle(Adaptor3d_HCurveOnSurface) HC2 = new Adaptor3d_HCurveOnSurface(); + HC2->ChangeCurve().Load(HS2); + HC2->ChangeCurve().Load(PC2); + BRepBlend_SurfCurvConstRadInv finv1(HSref1, HC2, HGuide); + BRepBlend_CurvPointRadInv finvp1(HGuide, HC2); + BRepBlend_SurfCurvConstRadInv finv2(HSref2, HC1, HGuide); + BRepBlend_CurvPointRadInv finvp2(HGuide, HC1); + + finv1.Set(PCref1); + finv2.Set(PCref2); + + + Standard_Real rad = fsp->Radius(); + if(Or1 == TopAbs_REVERSED) ch1 = 3; + if(Or2 == TopAbs_REVERSED) ch2 = 3; + + finv1.Set(rad, ch1); + finvp1.Set(Choix); + finv2.Set(rad, ch2); + finvp2.Set(Choix); + func.Set(rad, Choix); + func.Set(myShape); + + done = SimulData(Data, HGuide, lin, HS1, PC1, I1, Decroch1, HS2, PC2, I2, Decroch2, + func, finv1, finvp1, finv2, finvp2, + PFirst, MaxStep, locfleche, TolGuide, First, Last, + Soldep, 4, Inside, Appro, Forward, RecP1, RecRst1, RecP2, RecRst2); + if(!done) Standard_Failure::Raise("SimulSurf : Failed processing!"); + Standard_Integer nbp = lin->NbPoints(); + sec = new ChFiDS_SecHArray1(1,nbp); + for(Standard_Integer i = 1; i <= nbp; i++){ + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u, v, param, p1, p2; + gp_Circ ci; + const Blend_Point& p = lin->Point(i); + u = p.ParameterOnC1(); + v = p.ParameterOnC2(); + param = p.Parameter(); + func.Section(param, u, v, p1, p2, ci); + isec.Set(ci, p1, p2); +// if(i == 1) {pf.SetCoord(u,v);} +// if(i == nbp) {pl.SetCoord(u,v);} + } + } + else { + BRepBlend_RstRstEvolRad func(HS1,PC1, HS2, PC2, HGuide, fsp->Law(HGuide)); + func.Set(HSref1, PCref1, HSref2, PCref2); + Handle(Adaptor3d_HCurveOnSurface) HC1 = new Adaptor3d_HCurveOnSurface(); + HC1->ChangeCurve().Load(HS1); + HC1->ChangeCurve().Load(PC1); + Handle(Adaptor3d_HCurveOnSurface) HC2 = new Adaptor3d_HCurveOnSurface(); + HC2->ChangeCurve().Load(HS2); + HC2->ChangeCurve().Load(PC2); + + BRepBlend_SurfCurvEvolRadInv finv1(HSref1, HC2, HGuide, fsp->Law(HGuide)); + BRepBlend_CurvPointRadInv finvp1(HGuide, HC2); + BRepBlend_SurfCurvEvolRadInv finv2(HSref2, HC1, HGuide, fsp->Law(HGuide)); + BRepBlend_CurvPointRadInv finvp2(HGuide, HC1); + + finv1.Set(PCref1); + finv2.Set(PCref2); + + Standard_Integer ch11 = 1, ch22 = 2; + + if(Or1 == TopAbs_REVERSED) ch11 = 3; + if(Or2 == TopAbs_REVERSED) ch22 = 3; + + + finv1.Set(ch11); + finvp1.Set(Choix); + finv2.Set(ch22); + finvp2.Set(Choix); + func.Set(Choix); + func.Set(myShape); + + done = SimulData(Data, HGuide, lin, HS1, PC1, I1, Decroch1, HS2, PC2, I2, Decroch2, + func, finv1, finvp1, finv2, finvp2, + PFirst, MaxStep, locfleche, TolGuide, First, Last, + Soldep, 4, Inside, Appro, Forward, RecP1, RecRst1, RecP2, RecRst2); + + if(!done) Standard_Failure::Raise("SimulSurf : Fail !"); + Standard_Integer nbp = lin->NbPoints(); + sec = new ChFiDS_SecHArray1(1, nbp); + for(Standard_Integer i = 1; i <= nbp; i++){ + ChFiDS_CircSection& isec = sec->ChangeValue(i); + Standard_Real u, v, param, p1, p2; + gp_Circ ci; + const Blend_Point& p = lin->Point(i); + u = p.ParameterOnC1(); + v = p.ParameterOnC2(); + param = p.Parameter(); + func.Section(param, u, v, p1, p2, ci); + isec.Set(ci, p1, p2); +// if(i == 1) {pf.SetCoord(u,v);} +// if(i == nbp) {pl.SetCoord(u,v);} + } + } + Data->SetSimul(sec); +// gp_Pnt2d pbid; +// Data->Set2dPoints(pf,pl,pbid,pbid); + + ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(), + Standard_True, Data->ChangeVertexFirstOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(), + Standard_False,Data->ChangeVertexLastOnS1(),tolesp); + ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(), + Standard_True, Data->ChangeVertexFirstOnS2(),tolesp); + ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(), + Standard_False, Data->ChangeVertexLastOnS2(),tolesp); +} + + + + + + + +//======================================================================= +//function : PerformFirstSection +//purpose : +//======================================================================= + +Standard_Boolean ChFi3d_FilBuilder::PerformFirstSection +(const Handle(ChFiDS_Spine)& Spine, + const Handle(ChFiDS_HElSpine)& HGuide, + const Standard_Integer Choix, + Handle(BRepAdaptor_HSurface)& S1, + Handle(BRepAdaptor_HSurface)& S2, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(Adaptor3d_TopolTool)& I2, + const Standard_Real Par, + math_Vector& SolDep, + TopAbs_State& Pos1, + TopAbs_State& Pos2) const +{ + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Spine); + if(fsp.IsNull()) Standard_ConstructionError::Raise + ("PerformSurf : this is not the spine of a fillet"); + Standard_Real TolGuide = HGuide->Resolution(tolesp); + if(fsp->IsConstant()){ + BRepBlend_ConstRad Func(S1,S2,HGuide); + Func.Set(fsp->Radius(),Choix); + Func.Set(myShape); + BRepBlend_Walking TheWalk(S1,S2,I1,I2); + return TheWalk.PerformFirstSection(Func,Par,SolDep, + tolesp,TolGuide,Pos1,Pos2); + } + else { + BRepBlend_EvolRad Func(S1,S2,HGuide,fsp->Law(HGuide)); + Func.Set(Choix); + Func.Set(myShape); + BRepBlend_Walking TheWalk(S1,S2,I1,I2); + return TheWalk.PerformFirstSection(Func,Par,SolDep, + tolesp,TolGuide,Pos1,Pos2); + } +} + +//======================================================================= +//function : PerformSurf +//purpose : +//======================================================================= + +Standard_Boolean +ChFi3d_FilBuilder::PerformSurf(ChFiDS_SequenceOfSurfData& SeqData, + const Handle(ChFiDS_HElSpine)& HGuide, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer Choix, + const Handle(BRepAdaptor_HSurface)& S1, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(BRepAdaptor_HSurface)& S2, + const Handle(Adaptor3d_TopolTool)& I2, + const Standard_Real MaxStep, + const Standard_Real Fleche, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecOnS1, + const Standard_Boolean RecOnS2, + const math_Vector& Soldep, + Standard_Boolean& intf, + Standard_Boolean& intl) +{ +#ifdef DEB + OSD_Chronometer ch; +#endif + Handle(ChFiDS_SurfData) Data = SeqData(1); + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Spine); + if(fsp.IsNull()) Standard_ConstructionError::Raise + ("PerformSurf : this is not the spine of a fillet"); + Standard_Boolean gd1,gd2,gf1,gf2, maybesingular; + Handle(BRepBlend_Line) lin; + TopAbs_Orientation Or = S1->ChangeSurface().Face().Orientation(); + Standard_Real PFirst = First; + if(intf) First = fsp->FirstParameter(1); + if(intl) Last = fsp->LastParameter(fsp->NbEdges()); + if(fsp->IsConstant()){ + BRepBlend_ConstRad Func(S1,S2,HGuide); + BRepBlend_ConstRadInv FInv(S1,S2,HGuide); + Func.Set(fsp->Radius(),Choix); + FInv.Set(fsp->Radius(),Choix); + Func.Set(myShape); + +#ifdef DEB + ChFi3d_InitChron(ch); //init perf ComputeData +#endif + + done = ComputeData(Data,HGuide,Spine,lin,S1,I1,S2,I2,Func,FInv, + PFirst,MaxStep,Fleche,TolGuide,First,Last, + Inside,Appro,Forward,Soldep,intf,intl, + gd1,gd2,gf1,gf2,RecOnS1,RecOnS2); + +#ifdef DEB + ChFi3d_ResultChron(ch , t_computedata);// result perf ComputeData +#endif + + if(!done) return Standard_False; // recovery is possible PMN 14/05/1998 + +#ifdef DEB + ChFi3d_InitChron(ch);// init perf CompleteData +#endif + + done = CompleteData(Data,Func,lin,S1,S2,Or,gd1,gd2,gf1,gf2); + +#ifdef DEB + ChFi3d_ResultChron(ch , t_completedata);// result perf CompleteData +#endif + + if(!done) Standard_Failure::Raise("PerformSurf : Failed approximation!"); + maybesingular = (Func.GetMinimalDistance()<=100*tolapp3d); + } + else { + BRepBlend_EvolRad Func(S1, S2, HGuide, fsp->Law(HGuide)); + BRepBlend_EvolRadInv FInv(S1, S2, HGuide, fsp->Law(HGuide)); + Func.Set(Choix); + FInv.Set(Choix); + Func.Set(myShape); + +#ifdef DEB + ChFi3d_InitChron(ch);// init perf ComputeData +#endif + + done = ComputeData(Data,HGuide,Spine,lin,S1,I1,S2,I2,Func,FInv, + PFirst,MaxStep,Fleche,TolGuide,First,Last, + Inside,Appro,Forward,Soldep,intf,intl, + gd1,gd2,gf1,gf2,RecOnS1,RecOnS2); +#ifdef DEB + ChFi3d_ResultChron(ch , t_computedata); //result perf ComputeData +#endif + + if(!done) return Standard_False; + +#ifdef DEB + ChFi3d_InitChron(ch);// init perf CompleteData +#endif + + done = CompleteData(Data,Func,lin,S1,S2,Or,gd1,gd2,gf1,gf2); + +#ifdef DEB + ChFi3d_ResultChron(ch , t_completedata);// result perf CompleteData +#endif + + if(!done) Standard_Failure::Raise("PerformSurf : Failed approximation!"); + maybesingular = (Func.GetMinimalDistance()<=100*tolapp3d); + } + if (maybesingular) SplitSurf(SeqData, lin); + return Standard_True; +} + +//======================================================================= +//function : PerformSurf +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::PerformSurf(ChFiDS_SequenceOfSurfData& SeqData, + const Handle(ChFiDS_HElSpine)& HGuide, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer Choix, + const Handle(BRepAdaptor_HSurface)& HS1, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(BRepAdaptor_HCurve2d)& PC1, + const Handle(BRepAdaptor_HSurface)& HSref1, + const Handle(BRepAdaptor_HCurve2d)& PCref1, + Standard_Boolean& Decroch1, + const Handle(BRepAdaptor_HSurface)& HS2, + const Handle(Adaptor3d_TopolTool)& I2, + const TopAbs_Orientation Or2, + const Standard_Real MaxStep, + const Standard_Real Fleche, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecP, + const Standard_Boolean RecS, + const Standard_Boolean RecRst, + const math_Vector& Soldep) +{ + Handle(ChFiDS_SurfData) Data = SeqData(1); + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Spine); + if(fsp.IsNull()) Standard_ConstructionError::Raise + ("PerformSurf : this is not the spine of a fillet"); + Handle(BRepBlend_Line) lin; + Standard_Real PFirst = First; + Standard_Boolean maybesingular; + + if(fsp->IsConstant()){ + BRepBlend_SurfRstConstRad func(HS2,HS1,PC1,HGuide); + func.Set(HSref1,PCref1); + Handle(Adaptor3d_HCurveOnSurface) HC = new Adaptor3d_HCurveOnSurface(); + HC->ChangeCurve().Load(HS1); + HC->ChangeCurve().Load(PC1); + BRepBlend_SurfCurvConstRadInv finvc(HS2,HC,HGuide); + BRepBlend_SurfPointConstRadInv finvp(HS2,HGuide); + BRepBlend_ConstRadInv finv(HS2,HSref1,HGuide); + finv.Set(Standard_False,PCref1); + + Standard_Real rad = fsp->Radius(); + Standard_Integer petitchoix = 1; + if(Or2 == TopAbs_REVERSED) petitchoix = 3; + if(Choix%2 == 0) petitchoix++; + finv.Set(rad,Choix); + finvc.Set(rad,petitchoix); + finvp.Set(rad,petitchoix); + func.Set(rad,petitchoix); + func.Set(myShape); + + done = ComputeData(Data,HGuide,lin,HS2,I2,HS1,PC1,I1,Decroch1, + func,finv,finvp,finvc, + PFirst,MaxStep,Fleche,TolGuide,First,Last, + Soldep,Inside,Appro,Forward,RecP,RecS,RecRst); + if(!done) { + Spine->SetErrorStatus(ChFiDS_WalkingFailure); + Standard_Failure::Raise("PerformSurf : Failed processing!"); + } + TopAbs_Orientation Or = HS2->ChangeSurface().Face().Orientation(); + done = CompleteData(Data,func,lin,HS1,HS2,Or,1); + if(!done) Standard_Failure::Raise("PerformSurf : Failed approximation!"); + maybesingular = (func.GetMinimalDistance()<=100*tolapp3d); + } + else { + Standard_Real SpFirst = HGuide->FirstParameter(); + Standard_Real SpLast = HGuide->LastParameter(); + BRepBlend_SurfRstEvolRad func(HS2,HS1,PC1,HGuide,fsp->Law(HGuide)); + func.Set(HSref1,PCref1); + Handle(Adaptor3d_HCurveOnSurface) HC = new Adaptor3d_HCurveOnSurface(); + HC->ChangeCurve().Load(HS1); + HC->ChangeCurve().Load(PC1); + BRepBlend_SurfCurvEvolRadInv finvc(HS2,HC,HGuide,fsp->Law(HGuide)); + BRepBlend_SurfPointEvolRadInv finvp(HS2,HGuide,fsp->Law(HGuide)); + BRepBlend_EvolRadInv finv(HS2,HSref1,HGuide,fsp->Law(HGuide)); + finv.Set(Standard_False,PCref1); + Standard_Integer petitchoix = 1; + if(Or2 == TopAbs_REVERSED) petitchoix = 3; + if(Choix%2 == 0) petitchoix++; + finv.Set(Choix); + finvc.Set(petitchoix); + finvp.Set(petitchoix); + func.Set(petitchoix); + func.Set(myShape); + SpFirst = HGuide->FirstParameter();SpLast = HGuide->LastParameter(); + done = ComputeData(Data,HGuide,lin,HS2,I2,HS1,PC1,I1,Decroch1, + func,finv,finvp,finvc, + PFirst,MaxStep,Fleche,TolGuide,First,Last, + Soldep,Inside,Appro,Forward,RecP,RecS,RecRst); + if(!done) { + Spine->SetErrorStatus(ChFiDS_WalkingFailure); + Standard_Failure::Raise("PerformSurf : Failed processing!"); + } + TopAbs_Orientation Or = HS2->ChangeSurface().Face().Orientation(); + done = CompleteData(Data,func,lin,HS1,HS2,Or,1); + if(!done) Standard_Failure::Raise("PerformSurf : Failed approximation!"); + maybesingular = (func.GetMinimalDistance()<=100*tolapp3d); + } + if (maybesingular) SplitSurf(SeqData, lin); +} + +//======================================================================= +//function : PerformSurf +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::PerformSurf(ChFiDS_SequenceOfSurfData& SeqData, + const Handle(ChFiDS_HElSpine)& HGuide, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer Choix, + const Handle(BRepAdaptor_HSurface)& HS1, + const Handle(Adaptor3d_TopolTool)& I1, + const TopAbs_Orientation Or1, + const Handle(BRepAdaptor_HSurface)& HS2, + const Handle(Adaptor3d_TopolTool)& I2, + const Handle(BRepAdaptor_HCurve2d)& PC2, + const Handle(BRepAdaptor_HSurface)& HSref2, + const Handle(BRepAdaptor_HCurve2d)& PCref2, + Standard_Boolean& Decroch2, + const Standard_Real MaxStep, + const Standard_Real Fleche, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecP, + const Standard_Boolean RecS, + const Standard_Boolean RecRst, + const math_Vector& Soldep) +{ + Handle(ChFiDS_SurfData) Data = SeqData(1);; + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Spine); + if(fsp.IsNull()) Standard_ConstructionError::Raise + ("PerformSurf : this is not the spine of a fillet"); + Handle(BRepBlend_Line) lin; + Standard_Real PFirst = First; + Standard_Boolean maybesingular; + + if(fsp->IsConstant()){ + BRepBlend_SurfRstConstRad func(HS1,HS2,PC2,HGuide); + func.Set(HSref2,PCref2); + Handle(Adaptor3d_HCurveOnSurface) HC = new Adaptor3d_HCurveOnSurface(); + HC->ChangeCurve().Load(HS2); + HC->ChangeCurve().Load(PC2); + BRepBlend_SurfCurvConstRadInv finvc(HS1,HC,HGuide); + BRepBlend_SurfPointConstRadInv finvp(HS1,HGuide); + BRepBlend_ConstRadInv finv(HS1,HSref2,HGuide); + finv.Set(Standard_False,PCref2); + + Standard_Real rad = fsp->Radius(); + Standard_Integer petitchoix = 1; + if(Or1 == TopAbs_REVERSED) petitchoix = 3; + if(Choix%2 == 0) petitchoix++; + finv.Set(rad,Choix); + finvc.Set(rad,petitchoix); + finvp.Set(rad,petitchoix); + func.Set(rad,petitchoix); + func.Set(myShape); + + done = ComputeData(Data,HGuide,lin,HS1,I1,HS2,PC2,I2,Decroch2, + func,finv,finvp,finvc, + PFirst,MaxStep,Fleche,TolGuide,First,Last, + Soldep,Inside,Appro,Forward,RecP,RecS,RecRst); + if(!done) { + Spine->SetErrorStatus(ChFiDS_WalkingFailure); + Standard_Failure::Raise("PerformSurf : Failed processing!"); + } + TopAbs_Orientation Or = HS1->ChangeSurface().Face().Orientation(); + done = CompleteData(Data,func,lin,HS1,HS2,Or,0); + if(!done) Standard_Failure::Raise("PerformSurf : Failed approximation!"); + maybesingular = (func.GetMinimalDistance()<=100*tolapp3d); + } + else { + BRepBlend_SurfRstEvolRad func(HS1,HS2,PC2,HGuide,fsp->Law(HGuide)); + func.Set(HSref2,PCref2); + Handle(Adaptor3d_HCurveOnSurface) HC = new Adaptor3d_HCurveOnSurface(); + HC->ChangeCurve().Load(HS2); + HC->ChangeCurve().Load(PC2); + BRepBlend_SurfCurvEvolRadInv finvc(HS1,HC,HGuide,fsp->Law(HGuide)); + BRepBlend_SurfPointEvolRadInv finvp(HS1,HGuide,fsp->Law(HGuide)); + BRepBlend_EvolRadInv finv(HS1,HSref2,HGuide,fsp->Law(HGuide)); + finv.Set(Standard_False,PCref2); + Standard_Integer petitchoix = 1; + if(Or1 == TopAbs_REVERSED) petitchoix = 3; + if(Choix%2 == 0) petitchoix++; + finv.Set(Choix); + finvc.Set(petitchoix); + finvp.Set(petitchoix); + func.Set(petitchoix); + func.Set(myShape); + + done = ComputeData(Data,HGuide,lin,HS1,I1,HS2,PC2,I2,Decroch2, + func,finv,finvp,finvc, + PFirst,MaxStep,Fleche,TolGuide,First,Last, + Soldep,Inside,Appro,Forward,RecP,RecS,RecRst); + if(!done) { + Spine->SetErrorStatus(ChFiDS_WalkingFailure); + Standard_Failure::Raise("PerformSurf : Failed processing!"); + } + TopAbs_Orientation Or = HS1->ChangeSurface().Face().Orientation(); + done = CompleteData(Data,func,lin,HS1,HS2,Or,0); + if(!done) Standard_Failure::Raise("PerformSurf : Failed approximation!"); + maybesingular = (func.GetMinimalDistance()<=100*tolapp3d); + } + if (maybesingular) SplitSurf(SeqData, lin); +} + + + + + + +//======================================================================= +//function : PerformSurf +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::PerformSurf(ChFiDS_SequenceOfSurfData& SeqData, + const Handle(ChFiDS_HElSpine)& HGuide, + const Handle(ChFiDS_Spine)& Spine, + const Standard_Integer Choix, + const Handle(BRepAdaptor_HSurface)& HS1, + const Handle(Adaptor3d_TopolTool)& I1, + const Handle(BRepAdaptor_HCurve2d)& PC1, + const Handle(BRepAdaptor_HSurface)& HSref1, + const Handle(BRepAdaptor_HCurve2d)& PCref1, + Standard_Boolean& Decroch1, + const TopAbs_Orientation Or1, + const Handle(BRepAdaptor_HSurface)& HS2, + const Handle(Adaptor3d_TopolTool)& I2, + const Handle(BRepAdaptor_HCurve2d)& PC2, + const Handle(BRepAdaptor_HSurface)& HSref2, + const Handle(BRepAdaptor_HCurve2d)& PCref2, + Standard_Boolean& Decroch2, + const TopAbs_Orientation Or2, + const Standard_Real MaxStep, + const Standard_Real Fleche, + const Standard_Real TolGuide, + Standard_Real& First, + Standard_Real& Last, + const Standard_Boolean Inside, + const Standard_Boolean Appro, + const Standard_Boolean Forward, + const Standard_Boolean RecP1, + const Standard_Boolean RecRst1, + const Standard_Boolean RecP2, + const Standard_Boolean RecRst2, + const math_Vector& Soldep) +{ + Handle(ChFiDS_SurfData) Data = SeqData(1);; + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Spine); + if(fsp.IsNull()) Standard_ConstructionError::Raise + ("PerformSurf : this is not the spine of a fillet"); + Handle(BRepBlend_Line) lin; + Standard_Real PFirst = First; + Standard_Boolean maybesingular; + + if(fsp->IsConstant()){ + BRepBlend_RstRstConstRad func(HS1, PC1, HS2, PC2, HGuide); + func.Set(HSref1, PCref1, HSref2, PCref2); + Handle(Adaptor3d_HCurveOnSurface) HC1 = new Adaptor3d_HCurveOnSurface(); + HC1->ChangeCurve().Load(HS1); + HC1->ChangeCurve().Load(PC1); + Handle(Adaptor3d_HCurveOnSurface) HC2 = new Adaptor3d_HCurveOnSurface(); + HC2->ChangeCurve().Load(HS2); + HC2->ChangeCurve().Load(PC2); + BRepBlend_SurfCurvConstRadInv finv1(HSref1, HC2, HGuide); + BRepBlend_CurvPointRadInv finvp1(HGuide, HC2); + BRepBlend_SurfCurvConstRadInv finv2(HSref2, HC1, HGuide); + BRepBlend_CurvPointRadInv finvp2(HGuide, HC1); + + finv1.Set(PCref1); + finv2.Set(PCref2); + + Standard_Integer ch1 = 1, ch2 = 2; + Standard_Real rad = fsp->Radius(); + if(Or1 == TopAbs_REVERSED) ch1 = 3; + if(Or2 == TopAbs_REVERSED) ch2 = 3; + + finv1.Set(rad, ch1); + finvp1.Set(Choix); + finv2.Set(rad, ch2); + finvp2.Set(Choix); + func.Set(rad, Choix); + func.Set(myShape); + + done = ComputeData(Data, HGuide, lin, HS1, PC1, I1, Decroch1, HS2, PC2, I2, Decroch2, + func, finv1, finvp1, finv2, finvp2, + PFirst, MaxStep, Fleche, TolGuide, First, Last, + Soldep, Inside, Appro, Forward, RecP1, RecRst1, RecP2, RecRst2); + if(!done) { + Spine->SetErrorStatus(ChFiDS_WalkingFailure); + Standard_Failure::Raise("PerformSurf : Failed processing!"); + } + TopAbs_Orientation Or = HS1->ChangeSurface().Face().Orientation(); + done = CompleteData(Data, func, lin, HS1, HS2, Or); + if(!done) Standard_Failure::Raise("PerformSurf : Failed approximation!"); + maybesingular = (func.GetMinimalDistance()<=100*tolapp3d); + } + else { + BRepBlend_RstRstEvolRad func(HS1,PC1, HS2, PC2, HGuide, fsp->Law(HGuide)); + func.Set(HSref1, PCref1, HSref2, PCref2); + Handle(Adaptor3d_HCurveOnSurface) HC1 = new Adaptor3d_HCurveOnSurface(); + HC1->ChangeCurve().Load(HS1); + HC1->ChangeCurve().Load(PC1); + Handle(Adaptor3d_HCurveOnSurface) HC2 = new Adaptor3d_HCurveOnSurface(); + HC2->ChangeCurve().Load(HS2); + HC2->ChangeCurve().Load(PC2); + + BRepBlend_SurfCurvEvolRadInv finv1(HSref1, HC2, HGuide, fsp->Law(HGuide)); + BRepBlend_CurvPointRadInv finvp1(HGuide, HC2); + BRepBlend_SurfCurvEvolRadInv finv2(HSref2, HC1, HGuide, fsp->Law(HGuide)); + BRepBlend_CurvPointRadInv finvp2(HGuide, HC1); + + finv1.Set(PCref1); + finv2.Set(PCref2); + + Standard_Integer ch1 = 1, ch2 = 2; + + if(Or1 == TopAbs_REVERSED) ch1 = 3; + if(Or2 == TopAbs_REVERSED) ch2 = 3; + + + finv1.Set(ch1); + finvp1.Set(Choix); + finv2.Set(ch2); + finvp2.Set(Choix); + func.Set(Choix); + func.Set(myShape); + + done = ComputeData(Data, HGuide, lin, HS1, PC1, I1, Decroch1, HS2, PC2,I2, Decroch2, + func, finv1, finvp1, finv2, finvp2, + PFirst, MaxStep, Fleche, TolGuide, First, Last, + Soldep, Inside, Appro, Forward, RecP1, RecRst1, RecP2, RecRst2); + + if(!done) { + Spine->SetErrorStatus(ChFiDS_WalkingFailure); + Standard_Failure::Raise("PerformSurf : Failed processing!"); + } + TopAbs_Orientation Or = HS1->ChangeSurface().Face().Orientation(); + done = CompleteData(Data, func, lin, HS1, HS2, Or); + if(!done) Standard_Failure::Raise("PerformSurf : Failed approximation!"); + maybesingular = (func.GetMinimalDistance()<=100*tolapp3d); + + + } + if (maybesingular) SplitSurf(SeqData, lin); +} + + + + +//======================================================================= +//function : SplitSurf +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::SplitSurf(ChFiDS_SequenceOfSurfData& SeqData, + const Handle(BRepBlend_Line)& Line) +{ + Standard_Integer ii, Nbpnt=Line->NbPoints(); + if (Nbpnt <3) return; + Standard_Real UFirst,ULast,VFirst,VLast; + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + Standard_Integer ISurf; + Handle(ChFiDS_SurfData) ref = SeqData(1); + Blend_Point P; + + ISurf= ref->Surf(); + Handle(Geom_Surface) Surf = DStr.Surface(ISurf).Surface(); + Surf->Bounds(UFirst,ULast,VFirst,VLast); + Handle(Geom_Curve) Courbe1 = Surf->UIso(UFirst); + Handle(Geom_Curve) Courbe2 = Surf->UIso(ULast); + ChFi3d_SearchSing Fonc(Courbe1, Courbe2); + + TColStd_SequenceOfReal LesVi; + Standard_Real precedant, suivant, courant; + Standard_Real a, b, c; + + // (1) Finds vi so that iso v=vi is punctual + VFirst = Min( ref->InterferenceOnS1().FirstParameter(), + ref->InterferenceOnS2().FirstParameter() ); + VLast = Max( ref->InterferenceOnS1().LastParameter(), + ref->InterferenceOnS2().LastParameter() ); + + // (1.1) Finds the first point inside + for (ii=1; ii<=Nbpnt && Line->Point(ii).Parameter()<VFirst; ii++) {} + if (ii==1) ii++; + P = Line->Point(ii); + b = P.Parameter(); + courant = P.PointOnS1().Distance(P.PointOnS2()); + P = Line->Point(ii-1); + a = P.Parameter(); + precedant = P.PointOnS1().Distance(P.PointOnS2()); + ii ++; + + // (1.2) Find a minimum by "points" + for ( ; ii<=Nbpnt && Line->Point(ii).Parameter()<=VLast; ii++) { + for (;ii<=Nbpnt && + Line->Point(ii).Parameter()<VLast && + Line->Point(ii).Parameter()-b<Precision::PConfusion(); ii++) {} + + const Blend_Point& pnt = Line->Point(ii); + c = pnt.Parameter(); + suivant = pnt.PointOnS1().Distance(pnt.PointOnS2()); + if ( (courant < precedant) && (courant < suivant) ) { + // (1.3) Find the exact minimum + math_FunctionRoot Resol(Fonc, (a+c)/2, + tol2d,//Surf->VResolution(toleps), + a, c, + 50); + if (Resol.IsDone()) { + Standard_Real Val, racine=Resol.Root(); + + Fonc.Value(Resol.Root(), Val); + if (Val< tolapp3d) { + // the solution (avoiding the risks of confusion) + if (LesVi.Length()==0) { + if ( (racine > VFirst+tol2d) && + (racine < VLast -tol2d) ) { + LesVi.Append(racine); + } + } + else { + if ( (racine > LesVi(LesVi.Length()) + tol2d) && + (racine < VLast-tol2d) ) { + LesVi.Append(racine); + } + } + } + } + else { +# if DEB + cout << "Failed calculation of the minimum length" << endl; +# endif + } + } + // update if non duplication + a = b; + precedant = courant; + b = c; + courant = suivant; + } + + // (2) Update of the sequence of SurfData + if (LesVi.Length()>0) { + TopOpeBRepDS_DataStructure& DStru = myDS->ChangeDS(); + Handle(ChFiDS_SurfData) SD; + TopOpeBRepDS_Surface S; + TopOpeBRepDS_Curve C1, C2; + Standard_Real T, VertexTol; + gp_Pnt P3d, P1, P2; + ChFiDS_CommonPoint LePoint; + for (ii=1 ; ii<=LesVi.Length(); ii++) { + + T = LesVi(ii); + // (2.0) copy and insertion + SD = new (ChFiDS_SurfData); + SD->Copy(ref); + SeqData.InsertBefore(ii, SD); + S = DStru.Surface(ref->Surf()); + SD->ChangeSurf(DStru.AddSurface(S)); + C1 = DStru.Curve(SD->InterferenceOnS1().LineIndex()); + SD->ChangeInterferenceOnS1().SetLineIndex( DStru.AddCurve(C1)); + C2 = DStru.Curve(SD->InterferenceOnS2().LineIndex()); + SD->ChangeInterferenceOnS2().SetLineIndex(DStru.AddCurve(C2)); + + // (2.1) Modification of common Point + SD-> ChangeVertexLastOnS1().Reset(); + SD-> ChangeVertexLastOnS2().Reset(); + ref->ChangeVertexFirstOnS1().Reset(); + ref->ChangeVertexFirstOnS2().Reset(); + Courbe1->D0(T, P1); + Courbe2->D0(T, P2); + P3d.SetXYZ((P1.XYZ()+ P2.XYZ())/2); + VertexTol = P1.Distance(P2); + VertexTol += Max(C1.Tolerance(), C2.Tolerance()); + + SD->ChangeVertexLastOnS1().SetPoint(P3d); + SD->ChangeVertexLastOnS2().SetPoint(P3d); + ref->ChangeVertexFirstOnS1().SetPoint(P3d); + ref->ChangeVertexFirstOnS2().SetPoint(P3d); + SD->ChangeVertexLastOnS1().SetTolerance(VertexTol); + SD->ChangeVertexLastOnS2().SetTolerance(VertexTol); + ref->ChangeVertexFirstOnS1().SetTolerance(VertexTol); + ref->ChangeVertexFirstOnS2().SetTolerance(VertexTol); + + // (2.2) Modification of interferences + SD->ChangeInterferenceOnS1().SetLastParameter(T); + SD->ChangeInterferenceOnS2().SetLastParameter(T); + ref->ChangeInterferenceOnS1().SetFirstParameter(T); + ref->ChangeInterferenceOnS2().SetFirstParameter(T); + + // Parameters on ElSpine + SD->LastSpineParam(T); + ref->FirstSpineParam(T); + } + } +} + +//======================================================================= +//function : ExtentOneCorner +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::ExtentOneCorner(const TopoDS_Vertex& V, + const Handle(ChFiDS_Stripe)& S) +{ + // review by using the data at end of fillets (point, radius, normal + // to the faces and tangents of the guideline). +#ifndef DEB + Standard_Integer Sens = 0; +#else + Standard_Integer Sens; +#endif + Standard_Real Coeff = 0.5; + Handle(ChFiDS_Spine) Spine = S->Spine(); + ChFi3d_IndexOfSurfData(V,S,Sens); + Standard_Real dU = Spine->LastParameter(Spine->NbEdges()); + if (Spine->IsTangencyExtremity((Sens == 1))) + return; //No extension in the queue + + if (Spine->Status((Sens == 1)) == ChFiDS_FreeBoundary) { + Coeff *= 2; // It is necessary to go to the end and to evaluate the length + } + + if (Sens == 1) { + Spine->SetFirstParameter(-dU*Coeff); + Spine->SetFirstTgt(0.); + } + else{ + Spine->SetLastParameter(dU*(1.+Coeff)); + Spine->SetLastTgt(dU); + } +} + +//======================================================================= +//function : ExtentTwoCorner +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::ExtentTwoCorner(const TopoDS_Vertex& V, + const ChFiDS_ListOfStripe& LS) +{ + // Review by using the data at end of fillets (point, radius, normal + // to faces and tangents to the guideline. + Standard_Integer Sens; + Standard_Real Coeff = 0.3, Eval=0.0, dU, rad; + Standard_Integer IE; + ChFiDS_ListIteratorOfListOfStripe itel(LS); + Standard_Boolean FF = Standard_True; + Handle(ChFiDS_Stripe) Stripe; + Handle(ChFiDS_Spine) Spine; + + // A value of symetric extension is calculated + for ( ; itel.More(); itel.Next()) { + Stripe = itel.Value(); + Spine = Stripe->Spine(); + dU = Spine->LastParameter(Spine->NbEdges())*Coeff; + Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(Spine); + if (fsp->IsConstant()) + rad = fsp->Radius(); + else + { + TopoDS_Edge E = ChFi3d_EdgeFromV1( V, itel.Value(), Sens); + rad = MaxRad( fsp, E ); + /* + IE = ChFi3d_IndexOfSurfData(V,itel.Value(),Sens); + rad = MaxRad(fsp, IE); + */ + } + rad *= 1.5; + if (rad > dU) dU = rad; + if (dU > Eval) Eval = dU; + } + + // One applies + for (itel.Initialize(LS) ; itel.More(); itel.Next()) { + IE = ChFi3d_IndexOfSurfData(V,itel.Value(),Sens); + if (!FF && Stripe == itel.Value()) Sens = -Sens; + Stripe = itel.Value(); + Spine = Stripe->Spine(); + if (! Spine->IsTangencyExtremity((Sens == 1))) { //No extension on queue + if (Sens == 1){ + Spine->SetFirstParameter(-Eval); + Spine->SetFirstTgt(0.); + } + else{ + dU = Spine->LastParameter(Spine->NbEdges()); + Spine->SetLastParameter(dU+Eval); + Spine->SetLastTgt(dU); + } + FF = Standard_False; + } + } +} + + +//======================================================================= +//function : ExtentThreeCorner +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::ExtentThreeCorner(const TopoDS_Vertex& V, + const ChFiDS_ListOfStripe& LS) +{ + // Review by using the data at end of fillets (point, radius, normal + // to faces and tangents to the guideline. +#ifndef DEB + Standard_Integer Sens = 0; +#else + Standard_Integer Sens; +#endif + Standard_Real Coeff = 0.1; + ChFiDS_ListOfStripe check; +// Standard_Boolean FF = Standard_True; + for(ChFiDS_ListIteratorOfListOfStripe itel(LS); itel.More(); itel.Next()) { + Handle(ChFiDS_Stripe) Stripe = itel.Value(); + ChFi3d_IndexOfSurfData(V,Stripe,Sens); + for(ChFiDS_ListIteratorOfListOfStripe ich(check); ich.More(); ich.Next()){ + if(Stripe == ich.Value()){ + Sens = -Sens; + break; + } + } + Handle(ChFiDS_Spine) Spine = Stripe->Spine(); + if (Spine->IsTangencyExtremity((Sens == 1))) return; //No extension on queue + Standard_Real dU = Spine->LastParameter(Spine->NbEdges()); + if (Sens == 1){ + Spine->SetFirstParameter(-dU*Coeff); + Spine->SetFirstTgt(0.); + } + else{ + Spine->SetLastParameter(dU*(1.+Coeff)); + Spine->SetLastTgt(dU); + } + check.Append(Stripe); + } +} + + +//======================================================================= +//function : SetRegul +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::SetRegul() + +{ + ChFiDS_ListIteratorOfRegularities it; + TopTools_ListIteratorOfListOfShape itc; + TopTools_ListIteratorOfListOfShape its1; + TopTools_ListIteratorOfListOfShape its2; + BRep_Builder B; + for (it.Initialize(myRegul); it.More(); it.Next()){ + const ChFiDS_Regul& reg = it.Value(); + itc.Initialize(myCoup->NewEdges(reg.Curve())); + if(itc.More()){ + TopoDS_Edge E = TopoDS::Edge(itc.Value()); + if(reg.IsSurface1()) its1.Initialize(myCoup->NewFaces(reg.S1())); + else its1.Initialize(myCoup->Merged(myDS->Shape(reg.S1()),TopAbs_IN)); + if(reg.IsSurface2()) its2.Initialize(myCoup->NewFaces(reg.S2())); + else its2.Initialize(myCoup->Merged(myDS->Shape(reg.S2()),TopAbs_IN)); + if(its1.More() && its2.More()){ + TopoDS_Face F1 = TopoDS::Face(its1.Value()); + TopoDS_Face F2 = TopoDS::Face(its2.Value()); + GeomAbs_Shape cont = ChFi3d_evalconti(E,F1,F2); + B.Continuity(E,F1,F2,cont); + } + } + } +} diff --git a/src/ChFi3d/ChFi3d_FilBuilder_C2.cxx b/src/ChFi3d/ChFi3d_FilBuilder_C2.cxx new file mode 100644 index 00000000..ba0032fb --- /dev/null +++ b/src/ChFi3d/ChFi3d_FilBuilder_C2.cxx @@ -0,0 +1,943 @@ +// File: ChFi3d_Builder_5.cxx +// Created: Tue Mar 29 16:13:48 1994 +// Author: Isabelle GRIGNON +// Copyright: OPEN CASCADE 1994 + +#include <ChFi3d_FilBuilder.jxx> + +#include <ChFi3d.hxx> +#include <ChFi3d_Builder_0.hxx> + +#include <StdFail_NotDone.hxx> +#include <Standard_NotImplemented.hxx> +#include <Standard_ErrorHandler.hxx> + +#include <math_Vector.hxx> +#include <TColgp_Array1OfPnt.hxx> +#include <TColgp_Array1OfPnt2d.hxx> +#include <TColStd_Array1OfReal.hxx> +#include <TColStd_Array1OfInteger.hxx> +#include <TColStd_ListOfInteger.hxx> +#include <gp_Pnt.hxx> +#include <gp_Pnt2d.hxx> +#include <gp_Dir.hxx> +#include <gp_Lin.hxx> +#include <gp_Pln.hxx> +#include <gp_Ax3.hxx> +#include <Geom_BSplineCurve.hxx> +#include <Geom2d_TrimmedCurve.hxx> +#include <Geom2d_BSplineCurve.hxx> +#include <Law_Linear.hxx> +#include <BRepBlend_CSCircular.hxx> +#include <BRepBlend_Line.hxx> +#include <Geom2dConvert.hxx> +#include <BSplCLib.hxx> + +#include <Adaptor3d_CurveOnSurface.hxx> +#include <Adaptor3d_HCurveOnSurface.hxx> +#include <BRepLProp_CLProps.hxx> +#include <GeomAdaptor_Curve.hxx> +#include <GeomAdaptor_HCurve.hxx> +#include <Geom2dAdaptor_Curve.hxx> +#include <Geom2dAdaptor_HCurve.hxx> +#include <GeomAdaptor_Surface.hxx> +#include <GeomAdaptor_HSurface.hxx> +#include <BRep_Tool.hxx> +#include <BRepAdaptor_Curve2d.hxx> +#include <BRepAdaptor_Curve.hxx> +#include <BRepAdaptor_HCurve.hxx> +#include <BRepAdaptor_Surface.hxx> +#include <BRepAdaptor_HSurface.hxx> +#include <BRepTopAdaptor_TopolTool.hxx> +#include <GeomFill_ConstrainedFilling.hxx> +#include <GeomFill_SimpleBound.hxx> + +#include <IntSurf_LineOn2S.hxx> +#include <IntSurf_Transition.hxx> +#include <IntSurf_TypeTrans.hxx> +#include <IntCurveSurface_HInter.hxx> +#include <IntCurveSurface_IntersectionPoint.hxx> + +#include <TopoDS.hxx> +#include <TopoDS_Vertex.hxx> +#include <TopoDS_Face.hxx> +#include <TopOpeBRepDS_DataStructure.hxx> +#include <TopOpeBRepDS_ListOfInterference.hxx> +#include <TopAbs.hxx> +#include <TopAbs_Orientation.hxx> +#include <TopExp.hxx> +#include <TopTools_ListIteratorOfListOfShape.hxx> +#include <TopOpeBRepDS_HDataStructure.hxx> +#include <ChFiDS_Regul.hxx> +#include <ChFiDS_State.hxx> +#include <ChFiDS_SequenceOfSurfData.hxx> +#include <ChFiDS_SurfData.hxx> +#include <ChFiDS_FaceInterference.hxx> +#include <ChFiDS_ListIteratorOfListOfStripe.hxx> +#include <ChFiDS_Stripe.hxx> +#include <ChFiDS_Spine.hxx> +#include <ChFiDS_FilSpine.hxx> +#include <ChFiDS_HData.hxx> +#include <ChFiDS_CommonPoint.hxx> + +#include <ChFiKPart_ComputeData.hxx> + +#ifdef DRAW +#include <DrawTrSurf.hxx> +#endif +#ifdef DEB +#include <Geom_TrimmedCurve.hxx> +extern Standard_Boolean ChFi3d_GettraceDRAWSPINE(); +extern Standard_Boolean ChFi3d_GetcontextFORCEFILLING(); +#include <OSD_Chronometer.hxx> + +extern Standard_Real t_t2cornerinit ,t_perf2cornerbyinter,t_chfikpartcompdata, + t_cheminement,t_remplissage,t_t2cornerDS; +extern void ChFi3d_InitChron(OSD_Chronometer& ch); +extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time); +#endif + +//======================================================================= +//function : ToricRotule +//purpose : Test if it is a particular case of torus routine. +// Three planes with two constant incident fillets +// of the same radius and the third face perpendicular to +// two others are required. +//======================================================================= + +static Standard_Boolean ToricRotule(const BRepAdaptor_Surface& fac, + const BRepAdaptor_Surface& s1, + const BRepAdaptor_Surface& s2, + const Handle(ChFiDS_Stripe)& c1, + const Handle(ChFiDS_Stripe)& c2) + +{ + Standard_Real tolesp = 1.e-7; + + Handle(ChFiDS_FilSpine) sp1=Handle(ChFiDS_FilSpine)::DownCast(c1->Spine()); + Handle(ChFiDS_FilSpine) sp2=Handle(ChFiDS_FilSpine)::DownCast(c2->Spine()); + if(sp1.IsNull() || sp2.IsNull()) return Standard_False; + if (!sp1->IsConstant() || !sp2->IsConstant()) + return Standard_False; + if ((fac.GetType() != GeomAbs_Plane) || + (s1.GetType() != GeomAbs_Plane) || + (s2.GetType() != GeomAbs_Plane)) return Standard_False; + gp_Dir df = fac.Plane().Position().Direction(); + gp_Dir ds1 = s1.Plane().Position().Direction(); + gp_Dir ds2 = s2.Plane().Position().Direction(); + if ( Abs(df.Dot(ds1)) >= tolesp || Abs(df.Dot(ds2)) >= tolesp ) + return Standard_False; + Standard_Real r1 = sp1->Radius(); + Standard_Real r2 = sp2->Radius(); + if(Abs(r1 - r2) >= tolesp) return Standard_False; + return Standard_True; +} + +static void RemoveSD(Handle(ChFiDS_Stripe)& Stripe, + const Standard_Integer num1, + const Standard_Integer num2 ) +{ + ChFiDS_SequenceOfSurfData& Seq = + Stripe->ChangeSetOfSurfData()->ChangeSequence(); + if(Seq.IsEmpty()) return; + if (num1==num2) + Seq.Remove(num1); + else + Seq.Remove(num1,num2); +} + + +//======================================================================= +//function : PerformTwoCorner +//purpose : +//======================================================================= + +void ChFi3d_FilBuilder::PerformTwoCorner(const Standard_Integer Index) +{ +#ifdef DEB + OSD_Chronometer ch; + ChFi3d_InitChron(ch); // init perf initialisation +#endif + + done = 0; + const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index); + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + ChFiDS_ListIteratorOfListOfStripe It; + It.Initialize(myVDataMap(Index)); + Handle(ChFiDS_Stripe) st1,st2; + Standard_Integer Sens1,Sens2; + Standard_Integer Isd1,Isd2,i1,i2; + Handle(ChFiDS_SurfData) sd1,sd2; + ChFiDS_SequenceOfSurfData SeqFil1,SeqFil2; + Handle(Geom_Surface) surf1,surf2; + Standard_Boolean OkinterCC,Okvisavis,SameSide; + Standard_Integer IFaCo1,IFaCo2; + Standard_Real UIntPC1,UIntPC2; + TopoDS_Face FaCo; + TopoDS_Edge E1,E2,E; + TopoDS_Vertex V1,V2; +// gp_Pnt P1,P2; + Standard_Integer nbsurf1,nbsurf2,deb1,fin1,deb2,fin2; + Standard_Real parE1,parE2; + //Necessary information on fillets is extracted + //------------------------------------------------------ + + //the first + //---------- + + st1 = It.Value(); + Isd1 = ChFi3d_IndexOfSurfData(Vtx,st1,Sens1); + + + //the second + //---------- + It.Next(); + st2 = It.Value(); + if(st2 == st1) { + Sens2 = -1; + Isd2 = st2->SetOfSurfData()->Length(); + } + else{ Isd2 = ChFi3d_IndexOfSurfData(Vtx,st2,Sens2); } + + // If two edges to rounded are tangent GeomPlate is called + + if (Sens1==1) E1= st1->Spine()->Edges(1); + else E1= st1->Spine()->Edges( st1->Spine()->NbEdges()); + + if (Sens2==1) E2= st2->Spine()->Edges(1); + else E2= st2->Spine()->Edges( st2->Spine()->NbEdges()); + + BRepAdaptor_Curve BCurv1(E1); + BRepAdaptor_Curve BCurv2(E2); + parE1=BRep_Tool::Parameter(Vtx,E1); + parE2=BRep_Tool::Parameter(Vtx,E2); + BRepLProp_CLProps CL1(BCurv1,parE1 , 1, 1.e-4); + BRepLProp_CLProps CL2(BCurv2,parE2 , 1, 1.e-4); + gp_Dir dir1,dir2 ; + CL1.Tangent(dir1); + CL2.Tangent(dir2); + if (Sens1==-1) dir1.Reverse(); + if (Sens2==-1) dir2.Reverse(); + Standard_Real ang1; + ang1=Abs(dir1.Angle(dir2)); + if (ang1<PI/180.) { + PerformMoreThreeCorner(Index,2); + done=1; + return; + } + + OkinterCC = ChFi3d_IsInFront(DStr,st1,st2,Isd1,Isd2,Sens1,Sens2, + UIntPC1,UIntPC2,FaCo,SameSide, + IFaCo1,IFaCo2,Okvisavis,Vtx,Standard_True); + + Standard_Boolean trouve=Standard_False; + if (!Okvisavis) { + + +// one is not limited to the first or the last surfdata +// to find the opposing data + nbsurf1=st1->SetOfSurfData()->Length(); + nbsurf2=st2->SetOfSurfData()->Length(); + deb1=1; + deb2=1; + fin1=1; + fin2=1; + if (nbsurf1!=1) { + if (Sens1==1) { + deb1=1; + fin1=2; + } + else { + deb1=nbsurf1-1; + fin1=nbsurf1; + } + } + if (nbsurf2!=1) { + if (Sens2==1 ) { + deb2=1; + fin2=2; + } + else { + deb2=nbsurf2-1; + fin2=nbsurf2; + } + } + + for (i1=deb1;i1<=fin1 &&!trouve;i1++) { + Isd1=i1; + for (i2=deb2;i2<=fin2 &&!trouve;i2++) { + Isd2=i2; + + OkinterCC = ChFi3d_IsInFront(DStr,st1,st2,Isd1,Isd2,Sens1,Sens2, + UIntPC1,UIntPC2,FaCo,SameSide, + IFaCo1,IFaCo2,Okvisavis,Vtx,Standard_True); + trouve=Okvisavis; + } + } + if (!trouve){ + PerformMoreThreeCorner(Index,2); + done=1; + return; + } + else { + if (Sens1==1 && Isd1!=1) RemoveSD(st1,1,1); + if (Sens1!=1 && Isd1!=nbsurf1) RemoveSD(st1,fin1,fin1); + if (Sens2==1 && Isd2!=1) RemoveSD(st2,1,1); + if (Sens2!=1 && Isd2!=nbsurf2) RemoveSD(st2,fin2,fin2); + + } + Isd1=ChFi3d_IndexOfSurfData(Vtx,st1,Sens1); + Isd2=ChFi3d_IndexOfSurfData(Vtx,st2,Sens2); + } + // StdFail_NotDone::Raise("TwoCorner : no common face"); + Standard_Integer IFaArc1 = 3-IFaCo1, IFaArc2 = 3-IFaCo2; + SeqFil1 = st1->ChangeSetOfSurfData()->ChangeSequence(); + SeqFil2 = st2->ChangeSetOfSurfData()->ChangeSequence(); + sd1 = SeqFil1.ChangeValue(Isd1); + surf1 = DStr.Surface(sd1->Surf()).Surface(); + sd2 = SeqFil2.ChangeValue(Isd2); + surf2 = DStr.Surface(sd2->Surf()).Surface(); + TopAbs_Orientation OFaCo = FaCo.Orientation(); + // The concavities are analyzed and the opposite face and the + // eventual intersection of 2 pcurves on this face are found. + + ChFiDS_State Stat1,Stat2; + Standard_Boolean isfirst1 = (Sens1 == 1); + Standard_Boolean isfirst2 = (Sens2 == 1); + Stat1 = st1->Spine()->Status(isfirst1); + Stat2 = st2->Spine()->Status(isfirst2); + Standard_Boolean c1biseau = (Stat1 == ChFiDS_AllSame); + Standard_Boolean c1rotule = (Stat1 == ChFiDS_OnSame && Stat2 == ChFiDS_OnSame); + + // It is checked if the fillets have a commonpoint on a common arc. + // This edge is the pivot of the bevel or the knee. + + ChFiDS_CommonPoint& CP1 = sd1->ChangeVertex(isfirst1,IFaArc1); + ChFiDS_CommonPoint& CP2 = sd2->ChangeVertex(isfirst2,IFaArc2); + + Standard_Boolean resetcp1 = 0; + Standard_Boolean resetcp2 = 0; + + TopoDS_Edge pivot; + Standard_Boolean yapiv = Standard_False; + if(CP1.IsOnArc()) pivot = CP1.Arc(); + else { + PerformMoreThreeCorner(Index,2); + done=1; + return; + } + if(CP1.IsOnArc()&& CP2.IsOnArc()){ + yapiv = (pivot.IsSame(CP2.Arc())); + } + Handle(BRepAdaptor_HCurve) Hpivot; +#ifndef DEB + Standard_Boolean sameparam = Standard_False; + Standard_Real parCP1 = 0., parCP2 = 0.; +#else + Standard_Boolean sameparam; + Standard_Real parCP1, parCP2; +#endif + if(yapiv) { + Hpivot = new BRepAdaptor_HCurve(pivot); + parCP1 = CP1.ParameterOnArc(); + parCP2 = CP2.ParameterOnArc(); + gp_Pnt tst1 = Hpivot->Value(parCP1); + gp_Pnt tst2 = Hpivot->Value(parCP2); + sameparam = tst1.Distance(tst2) <= tolesp; + } + Handle(BRepAdaptor_HSurface) HFaCo = new BRepAdaptor_HSurface(); + Handle(BRepAdaptor_HSurface) HFaPiv; + Handle(BRepAdaptor_HSurface) HBRS1 = new BRepAdaptor_HSurface(); + Handle(BRepAdaptor_HSurface) HBRS2 = new BRepAdaptor_HSurface(); + + BRepAdaptor_Surface& BRS1 = HBRS1->ChangeSurface(); + BRepAdaptor_Surface& BRS2 = HBRS2->ChangeSurface(); + BRepAdaptor_Surface& BRFaCo = HFaCo->ChangeSurface(); + BRFaCo.Initialize(FaCo); + + TopoDS_Face FF1,FF2,F,FaPiv; +#ifndef DEB + TopAbs_Orientation pctrans = TopAbs_FORWARD ; +#else + TopAbs_Orientation pctrans; +#endif + Handle(Geom2d_BSplineCurve) PCurveOnPiv; + FF1 = TopoDS::Face(DStr.Shape(sd1->Index(IFaArc1))); + FF2 = TopoDS::Face(DStr.Shape(sd2->Index(IFaArc2))); + if (FF1.IsNull()||FF2.IsNull()) + {PerformMoreThreeCorner(Index,2); + done=1; + return; + } + BRS1.Initialize(FF1); + BRS2.Initialize(FF2); + + if(yapiv ) { + TopTools_ListIteratorOfListOfShape Kt; + Standard_Boolean ok1 = Standard_False, ok2 = Standard_False; + for (Kt.Initialize(myEFMap(pivot)); Kt.More(); Kt.Next()){ + F = TopoDS::Face(Kt.Value()); + if(!ok1 && FF1.IsSame(F)){ + ok1 = Standard_True; + } + if(!ok2 && FF2.IsSame(F)){ + ok2 = Standard_True; + } + } + if(!ok1 || !ok2){ + PerformMoreThreeCorner(Index,2); + done=1; + return; + } + } + +#ifdef DEB + ChFi3d_ResultChron(ch ,t_t2cornerinit);//result perf initialisation +#endif + + //bevel + //------ + ChFiDS_CommonPoint cp11,cp12,cp21,cp22; + ChFiDS_FaceInterference intf11,intf12,intf21,intf22; + + if(c1biseau){ +#ifdef DEB + ChFi3d_InitChron(ch); // init perf PerformTwoCornerbyInter +#endif + + done = PerformTwoCornerbyInter(Index); + +#ifdef DEB + ChFi3d_ResultChron(ch , t_perf2cornerbyinter); // result perf PerformTwoCornerbyInter +#endif + + if (!done){ + PerformMoreThreeCorner(Index,2); + done=1; + return; + } + } + else if(c1rotule){//save. + cp11 = sd1->Vertex(isfirst1,1); + cp12 = sd1->Vertex(isfirst1,2); + cp21 = sd2->Vertex(isfirst2,1); + cp22 = sd2->Vertex(isfirst2,2); + intf11 = sd1->InterferenceOnS1(); + intf12 = sd1->InterferenceOnS2(); + intf21 = sd2->InterferenceOnS1(); + intf22 = sd2->InterferenceOnS2(); +#ifdef DEB + ChFi3d_InitChron(ch); // init perf PerformTwoCornerbyInter +#endif + + done = PerformTwoCornerbyInter(Index); + +#ifdef DEB + ChFi3d_ResultChron(ch , t_perf2cornerbyinter); // result perf PerformTwoCornerbyInter +#endif + if (!done) { + // restore + sd1->ChangeVertex(isfirst1,1) = cp11; + sd1->ChangeVertex(isfirst1,2) = cp12; + sd2->ChangeVertex(isfirst2,1) = cp21; + sd2->ChangeVertex(isfirst2,2) = cp22; + sd1->ChangeInterferenceOnS1() = intf11; + sd1->ChangeInterferenceOnS2() = intf12; + sd2->ChangeInterferenceOnS1() = intf21; + sd2->ChangeInterferenceOnS2() = intf22; + done = 0; + } + } + + if(!c1biseau && !done){ + //new cornerdata is created + //------------------------------- + Handle(ChFiDS_Stripe) corner = new ChFiDS_Stripe(); + Handle(ChFiDS_HData)& cornerset = corner->ChangeSetOfSurfData(); + cornerset = new ChFiDS_HData(); + Handle(ChFiDS_SurfData) coin = new ChFiDS_SurfData(); + cornerset->Append(coin); + + if (SameSide) { + if(ToricRotule(BRFaCo,BRS1,BRS2,st1,st2)){ + // Direct construction. + // --------------------- + + Standard_Integer bid; + TopAbs_Orientation ori = OFaCo; + TopAbs_Orientation oriS = st1->Orientation(IFaCo1); + TopAbs_Orientation OFF1 = FF1.Orientation(); + TopAbs_Orientation oriSFF1 = st1->Orientation(IFaArc1); + bid = 1; + bid = ChFi3d::NextSide(ori,OFF1,oriS,oriSFF1,bid); + TopAbs_Orientation op1,op2; + if(yapiv) bid = ChFi3d::ConcaveSide(BRS1,BRS2,pivot,op1,op2); + op1 = TopAbs::Reverse(op1); + op2 = TopAbs::Reverse(op2); +#ifdef DEB + ChFi3d_InitChron(ch);// init perf ChFiKPart_ComputeData +#endif + Standard_Real radius = + Handle(ChFiDS_FilSpine)::DownCast(st1->Spine())->Radius(); + done = ChFiKPart_ComputeData::ComputeCorner(DStr,coin,HFaCo,HBRS1,HBRS2, + OFaCo,ori,op1,op2,radius); +#ifdef DEB + ChFi3d_ResultChron(ch , t_chfikpartcompdata);//result perf ChFiKPart_ComputeData +#endif + } + else { + // Construction by filling remplissage + // ---------------------------- + Standard_Real uPCArc1, uPCArc2; + gp_Pnt2d p2da1,p2df1,p2da2,p2df2,p2dfac1,p2dfac2; + gp_Vec2d v2dfac1,v2dfac2; + Handle(GeomFill_Boundary) B1,B2,Bpiv,Bfac; + uPCArc1 = sd1->Interference(IFaArc1).Parameter(isfirst1); + p2da1 = sd1->Interference(IFaArc1).PCurveOnSurf()->Value(uPCArc1); + p2df1 = sd1->Interference(IFaCo1).PCurveOnSurf()->Value(uPCArc1); + sd1->Interference(IFaCo1).PCurveOnFace()->D1(uPCArc1,p2dfac1,v2dfac1); + uPCArc2 = sd2->Interference(IFaArc2).Parameter(isfirst2); + p2da2 = sd2->Interference(IFaArc2).PCurveOnSurf()->Value(uPCArc2); + p2df2 = sd2->Interference(IFaCo2).PCurveOnSurf()->Value(uPCArc2); + sd2->Interference(IFaCo2).PCurveOnFace()->D1(uPCArc2,p2dfac2,v2dfac2); +#ifdef DEB + ChFi3d_InitChron(ch ); // init perf filling +#endif + B1 = ChFi3d_mkbound(surf1,p2df1,p2da1,tolesp,2.e-4); + B2 = ChFi3d_mkbound(surf2,p2df2,p2da2,tolesp,2.e-4); + Handle(Geom2d_Curve) PCurveOnFace; + Bfac = ChFi3d_mkbound(HFaCo,PCurveOnFace,Sens1,p2dfac1,v2dfac1, + Sens2,p2dfac2,v2dfac2,tolesp,2.e-4); + GeomFill_ConstrainedFilling fil(8,20); + if(sameparam) { + fil.Init(Bfac,B2,B1,1); + } + else { + Handle(Adaptor3d_HCurve) HPivTrim = Hpivot->ChangeCurve(). + Trim(Min(parCP1,parCP2),Max(parCP1,parCP2),tolesp); + Bpiv = new GeomFill_SimpleBound(HPivTrim,tolesp,2.e-4); + fil.Init(Bfac,B2,Bpiv,B1,1); + BRepAdaptor_Curve2d pcpivot; + gp_Vec dArc,dcf; + gp_Pnt bidon; + Hpivot->D1(parCP1,bidon,dArc); + Standard_Real fb1,lb1; + B1->Bounds(fb1,lb1); + B1->D1(lb1,bidon,dcf); + Standard_Boolean pivotverslebas = dArc.Dot(dcf) <= 0.; + Standard_Boolean pcfalenvers = (parCP1 > parCP2); + if((pivotverslebas && !pcfalenvers)|| + (!pivotverslebas && pcfalenvers)) { + FaPiv = FF2; + HFaPiv = HBRS2; + resetcp2 = 1; + } + else { + FaPiv = FF1; + HFaPiv = HBRS1; + resetcp1 = 1; + } + FaPiv.Orientation(TopAbs_FORWARD); + pcpivot.Initialize(pivot,FaPiv); + TopExp_Explorer Expl; + for(Expl.Init(FaPiv,TopAbs_EDGE); Expl.More(); Expl.Next()){ + if(Expl.Current().IsSame(pivot)) { + pctrans = Expl.Current().Orientation(); + break; + } + } + if(pcpivot.GetType() != GeomAbs_BSplineCurve){ + Handle(Geom2d_TrimmedCurve) + trc = new Geom2d_TrimmedCurve(pcpivot.Curve(), + Min(parCP1,parCP2), + Max(parCP1,parCP2)); + PCurveOnPiv = Geom2dConvert::CurveToBSplineCurve(trc); + } + else { + PCurveOnPiv = Geom2dConvert::SplitBSplineCurve + (Handle(Geom2d_BSplineCurve)::DownCast(pcpivot.Curve()), + Min(parCP1,parCP2),Max(parCP1,parCP2),tol2d); + } + TColStd_Array1OfReal kk(1,PCurveOnPiv->NbKnots()); + PCurveOnPiv->Knots(kk); + BSplCLib::Reparametrize(0.,1.,kk); + PCurveOnPiv->SetKnots(kk); + if(pcfalenvers) { + PCurveOnPiv->Reverse(); + pctrans = TopAbs::Reverse(pctrans); + } + } + Handle(Geom_Surface) Surfcoin = fil.Surface(); + done = CompleteData(coin,Surfcoin, + HFaCo,PCurveOnFace, + HFaPiv,PCurveOnPiv,OFaCo,1, + 0,0,0,0); +#ifdef DEB + ChFi3d_ResultChron(ch , t_remplissage);// result perf filling +#endif + } +#ifdef DEB + ChFi3d_InitChron(ch); // init perf update DS +#endif + if (done){ + // Update 3 CornerData and the DS + // ---------------------------------------- + if(resetcp1){ + gp_Pnt pjyl = CP1.Point(); + Standard_Real tolsav = CP1.Tolerance(); + CP1.Reset(); + CP1.SetPoint(pjyl); + CP1.SetTolerance(tolsav); + } + else if(resetcp2){ + gp_Pnt pjyl = CP2.Point(); + Standard_Real tolsav = CP2.Tolerance(); + CP2.Reset(); + CP2.SetPoint(pjyl); + CP2.SetTolerance(tolsav); + } + Standard_Real P1deb,P2deb,P1fin,P2fin; + Standard_Integer If1,If2,Il1,Il2,Icf,Icl; + const ChFiDS_CommonPoint& Pf1 = coin->VertexFirstOnS1(); + ChFiDS_CommonPoint& Pf2 = coin->ChangeVertexFirstOnS2(); + const ChFiDS_CommonPoint& Pl1 = coin->VertexLastOnS1(); + ChFiDS_CommonPoint& Pl2 = coin->ChangeVertexLastOnS2(); + Pf2 = CP1; + Pl2 = CP2; + + // the corner to start, + // ----------------------- + ChFiDS_Regul regdeb, regfin; + If1 = ChFi3d_IndexPointInDS(Pf1,DStr); + If2 = ChFi3d_IndexPointInDS(Pf2,DStr); + Il1 = ChFi3d_IndexPointInDS(Pl1,DStr); + if(sameparam) Il2 = If2; + else Il2 = ChFi3d_IndexPointInDS(Pl2,DStr); + + gp_Pnt2d pp1,pp2; + pp1 = coin->InterferenceOnS1().PCurveOnSurf()-> + Value(coin->InterferenceOnS1().FirstParameter()); + pp2 = coin->InterferenceOnS2().PCurveOnSurf()-> + Value(coin->InterferenceOnS2().FirstParameter()); + Handle(Geom_Curve) C3d; + Standard_Real tolreached; + ChFi3d_ComputeArete(Pf1,pp1,Pf2,pp2, + DStr.Surface(coin->Surf()).Surface(),C3d, + corner->ChangeFirstPCurve(),P1deb,P2deb, + tolesp,tol2d,tolreached,0); + Standard_Real par1 = sd1->Interference(IFaArc1).Parameter(isfirst1); + pp1 = sd1->Interference(IFaCo1).PCurveOnSurf()->Value(par1); + pp2 = sd1->Interference(IFaArc1).PCurveOnSurf()->Value(par1); + Standard_Real tolr1; + ChFi3d_ComputePCurv(C3d,pp1,pp2,st1->ChangePCurve(isfirst1), + DStr.Surface(sd1->Surf()).Surface(), + P1deb,P2deb,tolesp,tolr1); + tolreached = Max(tolreached,tolr1); + TopOpeBRepDS_Curve Tcurv1(C3d,tolreached); + Icf = DStr.AddCurve(Tcurv1); + regdeb.SetCurve(Icf); + regdeb.SetS1(coin->Surf(),0); + regdeb.SetS2(sd1->Surf(),0); + myRegul.Append(regdeb); + corner->ChangeFirstCurve(Icf); + corner->ChangeFirstParameters(P1deb,P2deb); + corner->ChangeIndexFirstPointOnS1(If1); + corner->ChangeIndexFirstPointOnS2(If2); + + pp1 = coin->InterferenceOnS1().PCurveOnSurf()-> + Value(coin->InterferenceOnS1().LastParameter()); + pp2 = coin->InterferenceOnS2().PCurveOnSurf()-> + Value(coin->InterferenceOnS2().LastParameter()); + ChFi3d_ComputeArete(Pl1,pp1,Pl2,pp2, + DStr.Surface(coin->Surf()).Surface(),C3d, + corner->ChangeLastPCurve(),P1fin,P2fin, + tolesp,tol2d,tolreached,0); + Standard_Real par2 = sd2->Interference(IFaArc2).Parameter(isfirst2); + pp1 = sd2->Interference(IFaCo2).PCurveOnSurf()->Value(par2); + pp2 = sd2->Interference(IFaArc2).PCurveOnSurf()->Value(par2); + Standard_Real tolr2; + ChFi3d_ComputePCurv(C3d,pp1,pp2,st2->ChangePCurve(isfirst2), + DStr.Surface(sd2->Surf()).Surface(), + P1deb,P2deb,tolesp,tolr2); + tolreached = Max(tolreached,tolr2); + TopOpeBRepDS_Curve Tcurv2(C3d,tolreached); + Icl = DStr.AddCurve(Tcurv2); + regfin.SetCurve(Icl); + regfin.SetS1(coin->Surf(),0); + regfin.SetS2(sd2->Surf(),0); + myRegul.Append(regfin); + corner->ChangeLastCurve(Icl); + corner->ChangeLastParameters(P1fin,P2fin); + corner->ChangeIndexLastPointOnS1(Il1); + corner->ChangeIndexLastPointOnS2(Il2); + + coin->ChangeIndexOfS1(DStr.AddShape(FaCo)); + if(sameparam) coin->ChangeIndexOfS2(0); + else { + coin->ChangeIndexOfS2(DStr.AddShape(FaPiv)); + coin->ChangeInterferenceOnS2().SetTransition(pctrans); + } + corner->SetSolidIndex(st1->SolidIndex()); + + // then the starting Stripe, + // ------------------------ + st1->SetCurve(Icf,isfirst1); + st1->SetIndexPoint(If1,isfirst1,IFaCo1); + st1->SetIndexPoint(If2,isfirst1,IFaArc1); + st1->SetParameters(isfirst1,P1deb,P2deb); + sd1->ChangeVertex(isfirst1,IFaCo1) = Pf1; + sd1->ChangeVertex(isfirst1,IFaArc1) = Pf2; + sd1->ChangeInterference(IFaCo1).SetParameter(par1,isfirst1); + if (IFaCo1 == 2) st1->SetOrientation(TopAbs_REVERSED,isfirst1); + + // then the end Stripe, + // ------------------------- + st2->SetCurve(Icl,isfirst2); + st2->SetIndexPoint(Il1,isfirst2,IFaCo2); + st2->SetIndexPoint(Il2,isfirst2,IFaArc2); + st2->SetParameters(isfirst2,P1fin,P2fin); + sd2->ChangeVertex(isfirst2,IFaCo2) = Pl1; + sd2->ChangeVertex(isfirst2,IFaArc2) = Pl2; + sd2->ChangeInterference(IFaCo2).SetParameter(par2,isfirst2); + if (IFaCo2 == 2) st2->SetOrientation(TopAbs_REVERSED,isfirst2); + } +#ifdef DEB + ChFi3d_ResultChron(ch , t_t2cornerDS);// result perf update DS +#endif + } + else { + //it is necessary to make difference with + if(!OkinterCC) { + Standard_Failure::Raise("TwoCorner : No intersection pc pc"); + } + Handle(ChFiDS_Stripe) stsam, stdif; + Handle(ChFiDS_SurfData) sdsam, sddif; +#ifndef DEB + Standard_Real uintpcsam = 0., uintpcdif = 0.; + Standard_Integer ifacosam = 0, ifacodif = 0, ifaopsam = 0, ifaopdif = 0; + Standard_Boolean isfirstsam = Standard_False, isfirstdif = Standard_False; +#else + Standard_Real uintpcsam, uintpcdif; + Standard_Integer ifacosam, ifacodif, ifaopsam, ifaopdif; + Standard_Boolean isfirstsam, isfirstdif; +#endif + if(Stat1 == ChFiDS_OnSame && Stat2 == ChFiDS_OnDiff){ + stsam = st1; sdsam = sd1; uintpcsam = UIntPC1; + ifacosam = IFaCo1; ifaopsam = IFaArc1; isfirstsam = isfirst1; + stdif = st2; sddif = sd2; uintpcdif = UIntPC2; + ifacodif = IFaCo2; ifaopdif = IFaArc2; isfirstdif = isfirst2; + } + else if(Stat1 == ChFiDS_OnDiff && Stat2 == ChFiDS_OnSame){ + stsam = st2; sdsam = sd2; uintpcsam = UIntPC2; + ifacosam = IFaCo2; ifaopsam = IFaArc2; isfirstsam = isfirst2; + stdif = st1; sddif = sd1; uintpcdif = UIntPC1; + ifacodif = IFaCo1; ifaopdif = IFaArc1; isfirstdif = isfirst1; + } + else { + Standard_Failure::Raise("TwoCorner : Config unknown"); + } + //It is checked if surface ondiff has a point on arc from the side opposed + //to the common face and if this arc is connected to the base face + //opposed to common face of the surface onsame. + ChFiDS_CommonPoint& cpopdif = sddif->ChangeVertex(isfirstdif,ifaopdif); + if(!cpopdif.IsOnArc()) { + Standard_Failure::Raise + ("TwoCorner : No point on restriction on surface OnDiff"); + } + const TopoDS_Edge& Arcopdif = cpopdif.Arc(); + const TopoDS_Face& Fopsam = TopoDS::Face(DStr.Shape(sdsam->Index(ifaopsam))); + TopExp_Explorer ex; + for(ex.Init(Fopsam,TopAbs_EDGE); ex.More(); ex.Next()){ + if(ex.Current().IsSame(Arcopdif)) { + break; + } + else if(!ex.More()) { + Standard_Failure::Raise + ("TwoCorner : No common face to loop the contour"); + } + } +#ifdef DEB + ChFi3d_InitChron(ch ); // init perf filling +#endif + Handle(GeomFill_Boundary) Bsam,Bdif,Bfac; + gp_Pnt2d ppopsam = + sdsam->Interference(ifaopsam).PCurveOnSurf()->Value(uintpcsam); + gp_Pnt2d ppcosam = + sdsam->Interference(ifacosam).PCurveOnSurf()->Value(uintpcsam); + Handle(Geom_Surface) surfsam = DStr.Surface(sdsam->Surf()).Surface(); + Handle(GeomAdaptor_HSurface) Hsurfsam = new GeomAdaptor_HSurface(surfsam); + Handle(Geom2d_Curve) pcsurfsam; + Bsam = ChFi3d_mkbound(Hsurfsam,pcsurfsam,ppopsam,ppcosam,tolesp,2.e-4); + Standard_Real upcopdif = sddif->Interference(ifaopdif).Parameter(isfirstdif); + gp_Pnt2d ppopdif = + sddif->Interference(ifaopdif).PCurveOnSurf()->Value(upcopdif); + gp_Pnt2d ppcodif = + sddif->Interference(ifacodif).PCurveOnSurf()->Value(uintpcdif); + Handle(Geom_Surface) surfdif = DStr.Surface(sddif->Surf()).Surface(); + Handle(GeomAdaptor_HSurface) Hsurfdif = new GeomAdaptor_HSurface(surfdif); + Handle(Geom2d_Curve) pcsurfdif; + Bdif = ChFi3d_mkbound(Hsurfdif,pcsurfdif,ppcodif,ppopdif,tolesp,2.e-4); + gp_Pnt2d ppfacsam,ppfacdif; + gp_Pnt PPfacsam,PPfacdif; + gp_Vec VVfacsam,VVfacdif; + sdsam->Interference(ifaopsam).PCurveOnFace()->D0(uintpcsam,ppfacsam); + const Handle(Geom_Curve)& curvopsam = + DStr.Curve(sdsam->Interference(ifaopsam).LineIndex()).Curve(); + curvopsam->D1(uintpcsam,PPfacsam,VVfacsam); + BRepAdaptor_Curve2d PCArcFac(Arcopdif,Fopsam); + PCArcFac.D0(cpopdif.ParameterOnArc(),ppfacdif); + BRepAdaptor_Curve CArcFac(Arcopdif); + CArcFac.D1(cpopdif.ParameterOnArc(),PPfacdif,VVfacdif); + Handle(BRepAdaptor_HSurface) HBRFopsam = new BRepAdaptor_HSurface(); + BRepAdaptor_Surface& BRFopsam = HBRFopsam->ChangeSurface(); + BRFopsam.Initialize(Fopsam,Standard_False); + Handle(Geom2d_Curve) pcFopsam = ChFi3d_BuildPCurve(HBRFopsam, + ppfacsam,VVfacsam, + ppfacdif,VVfacdif,1); + Bfac = ChFi3d_mkbound(HBRFopsam,pcFopsam,tolesp,2.e-4); + GeomFill_ConstrainedFilling fil(8,20); + fil.Init(Bsam,Bdif,Bfac,1); +#if 0 + for(Standard_Integer ib = 0; ib < 4; ib++){ + if(ib == 2) continue; + fil.CheckCoonsAlgPatch(ib); + fil.CheckTgteField(ib); + fil.CheckApprox(ib); + fil.CheckResult(ib); + } +#endif + Handle(Geom_Surface) Surfcoin = fil.Surface(); + TopAbs_Orientation Osurfsam = sdsam->Orientation(); + Handle(Geom2d_Curve) pcnul; + done = CompleteData(coin,Surfcoin, + Hsurfsam,pcsurfsam, + HBRFopsam,pcnul,Osurfsam,1, + 0,0,0,0); +#ifdef DEB + ChFi3d_ResultChron(ch , t_remplissage);// result perf filling +#endif + if(!done) Standard_Failure::Raise("concavites inverted : fail"); +#ifdef DEB + ChFi3d_InitChron(ch); // init perf update DS +#endif + // Update 3 CornerData and the DS + // ---------------------------------------- + // the corner to start, + // ----------------------- + Standard_Real P1deb,P2deb,P1fin,P2fin; + Standard_Integer If1,If2,Il1,Il2,Icf,Icl; + const ChFiDS_CommonPoint& Pf1 = coin->VertexFirstOnS1(); + ChFiDS_CommonPoint& Pf2 = coin->ChangeVertexFirstOnS2(); + const ChFiDS_CommonPoint& Pl1 = coin->VertexLastOnS1(); + ChFiDS_CommonPoint& Pl2 = coin->ChangeVertexLastOnS2(); + Pf2 = Pl2 = cpopdif; + + ChFiDS_Regul regdeb, regfin; + If1 = ChFi3d_IndexPointInDS(Pf1,DStr); + If2 = ChFi3d_IndexPointInDS(Pf2,DStr); + Il1 = ChFi3d_IndexPointInDS(Pl1,DStr); + Il2 = If2; + + gp_Pnt2d pp1,pp2; + pp1 = coin->InterferenceOnS1().PCurveOnSurf()-> + Value(coin->InterferenceOnS1().FirstParameter()); + pp2 = coin->InterferenceOnS2().PCurveOnSurf()-> + Value(coin->InterferenceOnS2().FirstParameter()); + Handle(Geom_Curve) C3d; + Standard_Real tolreached; + ChFi3d_ComputeArete(Pf1,pp1,Pf2,pp2, + DStr.Surface(coin->Surf()).Surface(),C3d, + corner->ChangeFirstPCurve(),P1deb,P2deb, + tolesp,tol2d,tolreached,0); + Standard_Real tolr1; + Handle(GeomAdaptor_HCurve) HC3d = new GeomAdaptor_HCurve(C3d); + ChFi3d_SameParameter(HC3d,pcFopsam,HBRFopsam,tolesp,tolr1); + tolreached = Max(tolreached,tolr1); + TopOpeBRepDS_Curve Tcurv1(C3d,tolreached); + Icf = DStr.AddCurve(Tcurv1); + // place the pcurve on face in the DS + TopAbs_Orientation OpcFopsam = sdsam->Interference(ifaopsam).Transition(); + Standard_Integer IFopsam = sdsam->Index(ifaopsam); + if(isfirstsam) OpcFopsam = TopAbs::Reverse(OpcFopsam); + Handle(TopOpeBRepDS_SurfaceCurveInterference) + interf = ChFi3d_FilCurveInDS(Icf,IFopsam,pcFopsam,OpcFopsam); + DStr.ChangeShapeInterferences(IFopsam).Append(interf); + + regdeb.SetCurve(Icf); + regdeb.SetS1(coin->Surf(),0); + regdeb.SetS2(IFopsam,1); + myRegul.Append(regdeb); + corner->ChangeFirstCurve(Icf); + corner->ChangeFirstParameters(P1deb,P2deb); + corner->ChangeIndexFirstPointOnS1(If1); + corner->ChangeIndexFirstPointOnS2(If2); + + pp1 = coin->InterferenceOnS1().PCurveOnSurf()-> + Value(coin->InterferenceOnS1().LastParameter()); + pp2 = coin->InterferenceOnS2().PCurveOnSurf()-> + Value(coin->InterferenceOnS2().LastParameter()); + ChFi3d_ComputeArete(Pl1,pp1,Pl2,pp2, + DStr.Surface(coin->Surf()).Surface(),C3d, + corner->ChangeLastPCurve(),P1fin,P2fin, + tolesp,tol2d,tolreached,0); + Standard_Real tolr2; + HC3d->ChangeCurve().Load(C3d); + ChFi3d_SameParameter(HC3d,pcsurfdif,Hsurfdif,tolesp,tolr2); + tolreached = Max(tolreached,tolr2); + TopOpeBRepDS_Curve Tcurv2(C3d,tolreached); + Icl = DStr.AddCurve(Tcurv2); + regfin.SetCurve(Icl); + regfin.SetS1(coin->Surf(),0); + regfin.SetS2(sddif->Surf(),0); + myRegul.Append(regfin); + corner->ChangeLastCurve(Icl); + corner->ChangeLastParameters(P1fin,P2fin); + corner->ChangeIndexLastPointOnS1(Il1); + corner->ChangeIndexLastPointOnS2(Il2); + + coin->ChangeIndexOfS1(-sdsam->Surf()); + coin->ChangeIndexOfS2(0); + + corner->SetSolidIndex(stsam->SolidIndex()); + + // then Stripe OnSame + // --------------------- + const ChFiDS_FaceInterference& intcoin1 = coin->InterferenceOnS1(); + stsam->SetCurve(intcoin1.LineIndex(),isfirstsam); + stsam->InDS(isfirstsam); // filDS already works from the corner. + stsam->ChangePCurve(isfirstsam) = coin->InterferenceOnS1().PCurveOnFace(); + stsam->SetIndexPoint(If1,isfirstsam,ifaopsam); + stsam->SetIndexPoint(Il1,isfirstsam,ifacosam); + stsam->SetParameters(isfirstsam, + intcoin1.FirstParameter(), + intcoin1.LastParameter()); + sdsam->ChangeVertex(isfirstsam,ifaopsam) = Pf1; + sdsam->ChangeVertex(isfirstsam,ifacosam) = Pl1; + sdsam->ChangeInterferenceOnS1().SetParameter(uintpcsam,isfirstsam); + sdsam->ChangeInterferenceOnS2().SetParameter(uintpcsam,isfirstsam); + if (ifaopsam == 2) stsam->SetOrientation(TopAbs_REVERSED,isfirstsam); + + // then Stripe OnDiff + // --------------------- + stdif->SetCurve(Icl,isfirstdif); + stdif->ChangePCurve(isfirstdif) = pcsurfdif; + stdif->SetIndexPoint(Il2,isfirstdif,ifaopdif); + stdif->SetIndexPoint(Il1,isfirstdif,ifacodif); + stdif->SetParameters(isfirstdif,P1fin,P2fin); + sddif->ChangeVertex(isfirstdif,ifaopdif) = Pl2; + sddif->ChangeVertex(isfirstdif,ifacodif) = Pl1; + sddif->ChangeInterference(ifacodif).SetParameter(uintpcdif,isfirstdif); + if (ifaopdif == 1) stdif->SetOrientation(TopAbs_REVERSED,isfirstdif); +#ifdef DEB + ChFi3d_ResultChron(ch , t_t2cornerDS);// result perf update DS +#endif + } + if(!myEVIMap.IsBound(Vtx)){ + TColStd_ListOfInteger li; + myEVIMap.Bind(Vtx,li); + } + myEVIMap.ChangeFind(Vtx).Append(coin->Surf()); + myListStripe.Append(corner); + } +} + diff --git a/src/ChFi3d/ChFi3d_FilBuilder_C3.cxx b/src/ChFi3d/ChFi3d_FilBuilder_C3.cxx new file mode 100644 index 00000000..59e7ca9a --- /dev/null +++ b/src/ChFi3d/ChFi3d_FilBuilder_C3.cxx @@ -0,0 +1,914 @@ +// File: ChFi3d_FilBuilder_C3.cxx +// Created: Wed Apr 26 09:57:13 1995 +// Author: Modelistation +// <model@phylox> + + +#include <ChFi3d_FilBuilder.jxx> +#include <ChFi3d_Builder_0.hxx> +#include <ChFi3d.hxx> + +#include <Precision.hxx> + +#include <Standard_Failure.hxx> +#include <Standard_NotImplemented.hxx> +#include <TColStd_ListOfInteger.hxx> + +#include <math_Vector.hxx> + +#include <gp_Pnt.hxx> +#include <gp_Vec.hxx> +#include <gp_Dir.hxx> +#include <gp_Pnt2d.hxx> +#include <gp_Ax2.hxx> +#include <gp_Ax3.hxx> +#include <gp_Lin.hxx> +#include <ElCLib.hxx> +#include <ElSLib.hxx> + +#include <TColgp_Array1OfPnt2d.hxx> + +#include <Geom_Plane.hxx> +#include <Geom_Circle.hxx> +#include <Geom_BezierCurve.hxx> +#include <Geom2d_BezierCurve.hxx> +#include <Geom2d_Curve.hxx> +#include <Geom2d_TrimmedCurve.hxx> +#include <Geom2d_Line.hxx> + +#include <IntAna_QuadQuadGeo.hxx> +#include <IntCurveSurface_IntersectionPoint.hxx> + +#include <TopoDS.hxx> +#include <TopoDS_Shape.hxx> +#include <TopoDS_Face.hxx> +#include <TopoDS_Edge.hxx> +#include <TopoDS_Vertex.hxx> + +#include <Adaptor3d_HSurface.hxx> +#include <Adaptor3d_CurveOnSurface.hxx> +#include <Adaptor3d_TopolTool.hxx> +#include <Geom2dAdaptor_Curve.hxx> +#include <Geom2dAdaptor_HCurve.hxx> +#include <GeomAdaptor_Curve.hxx> +#include <GeomAdaptor_HCurve.hxx> +#include <GeomAdaptor_Surface.hxx> +#include <GeomAdaptor_HSurface.hxx> +#include <BRepAdaptor_Curve.hxx> +#include <BRepAdaptor_HCurve.hxx> +#include <BRepAdaptor_Surface.hxx> +#include <BRepAdaptor_HSurface.hxx> +#include <BRepTopAdaptor_TopolTool.hxx> + +#include <TopAbs.hxx> +#include <TopAbs_Orientation.hxx> + +#include <ChFiDS_SurfData.hxx> +#include <ChFiDS_CommonPoint.hxx> +#include <ChFiDS_FaceInterference.hxx> +#include <ChFiDS_Spine.hxx> +#include <ChFiDS_SequenceOfSurfData.hxx> +#include <ChFiDS_Stripe.hxx> +#include <ChFiDS_HData.hxx> +#include <ChFiDS_ListIteratorOfListOfStripe.hxx> +#include <ChFiDS_Regul.hxx> + +#include <TopOpeBRepDS_HDataStructure.hxx> +#include <TopOpeBRepDS_DataStructure.hxx> +#include <TopOpeBRepDS_Curve.hxx> +#include <TopOpeBRepDS_Surface.hxx> + +#include <ChFiKPart_ComputeData.hxx> +#include <BRepBlend_Line.hxx> +#include <BRepBlend_ConstRad.hxx> +#include <BRepBlend_ConstRadInv.hxx> +#include <BRepBlend_EvolRad.hxx> +#include <BRepBlend_EvolRadInv.hxx> +#include <Law_S.hxx> + +#ifdef DRAW +#include <DrawTrSurf.hxx> +#endif +#ifdef DEB +#include <Geom_TrimmedCurve.hxx> +extern Standard_Boolean ChFi3d_GettraceDRAWSPINE(); +extern Standard_Boolean ChFi3d_GetcontextSPINEBEZIER(); +extern Standard_Boolean ChFi3d_GetcontextSPINECIRCLE(); +extern Standard_Boolean ChFi3d_GetcontextSPINECE(); +extern Standard_Boolean ChFi3d_GetcontextFORCEFILLING(); +#include <OSD_Chronometer.hxx> + +extern Standard_Real t_t3cornerinit ,t_spherique,t_torique, +t_notfilling,t_filling,t_t3cornerDS; +extern void ChFi3d_InitChron(OSD_Chronometer& ch); +extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time); +#endif + +//======================================================================= +//function : SearchPivot +//purpose : +//======================================================================= +static Standard_Integer SearchPivot(Standard_Integer* s, + Standard_Real u[3][3], + const Standard_Real t) +{ + Standard_Boolean bondeb,bonfin; + for(Standard_Integer i = 0; i <= 2; i++){ + if(s[(i+1)%3] == 1){bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] >= -t);} + else {bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] <= t);} + if(s[(i+2)%3] == 1){bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] >= -t);} + else {bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] <= t);} + if (bondeb && bonfin){ return i; } + } + return -1; +} + + +//======================================================================= +//function : SearchFD +//purpose : +//======================================================================= +static Standard_Boolean SearchFD(TopOpeBRepDS_DataStructure& DStr, + const Handle(ChFiDS_Stripe)& cd1, + const Handle(ChFiDS_Stripe)& cd2, + const Standard_Integer sens1, + const Standard_Integer sens2, + Standard_Integer& i1, + Standard_Integer& i2, + Standard_Real& p1, + Standard_Real& p2, + const Standard_Integer ind1, + const Standard_Integer ind2, + TopoDS_Face& face, + Standard_Boolean& sameside, + Standard_Integer& jf1, + Standard_Integer& jf2) +{ + Standard_Boolean found = Standard_False; + Standard_Integer id1 = ind1, id2 = ind2; + Standard_Integer if1 = ind1, if2 = ind2; + Standard_Integer l1 = cd1->SetOfSurfData()->Length(); + Standard_Integer l2 = cd2->SetOfSurfData()->Length(); + Standard_Integer i; + Standard_Boolean fini1 = Standard_False, fini2 = Standard_False; + Standard_Boolean visavis; + TopoDS_Vertex Vtx; + while( !found ){ + for(i = id1; (i*sens1) <= (if1*sens1) && !found && !fini2; i = i+sens1 ){ + if(ChFi3d_IsInFront(DStr,cd1,cd2,i,if2,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)){ + i1 = i; + i2 = if2; + found = Standard_True; + } + } + if(!fini1){ + if1 = if1 + sens1; + if(if1 < 1 || if1 > l1){ if1 = if1 - sens1; fini1 = Standard_True; } + } + + for(i = id2; (i*sens2) <= (if2*sens2) && !found && !fini1; i = i+sens2 ){ + if(ChFi3d_IsInFront(DStr,cd1,cd2,if1,i,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)){ + i1 = if1; + i2 = i; + found = Standard_True; + } + } + if(!fini2){ + if2 = if2 + sens2; + if(if2 < 1 || if2 > l2){ if2 = if2 - sens2; fini2 = Standard_True; } + } + if(fini1 && fini2) break; + } + return found; +} + + +//======================================================================= +//function : ToricCorner +//purpose : Test if this is a paricular cas of a torus corner +// (or spherical limited by isos). +//======================================================================= + +static Standard_Boolean ToricCorner(const TopoDS_Face& F, + const Standard_Real rd, + const Standard_Real rf, + const gp_Vec& v) +{ + if(Abs(rd-rf) > Precision::Confusion()){ return Standard_False; } + BRepAdaptor_Surface bs(F); + if(bs.GetType() != GeomAbs_Plane){ return Standard_False; } + Standard_Real scal1 = Abs(bs.Plane().Position().XDirection().Dot(v)); + Standard_Real scal2 = Abs(bs.Plane().Position().YDirection().Dot(v)); + return (scal1 <= Precision::Confusion() && + scal2 <= Precision::Confusion()); +} + +//======================================================================= +//function : PerformThreeCorner +//purpose : Calculate fillet on a top with three edges +// incident carrying each edge. +//======================================================================= + +void ChFi3d_FilBuilder::PerformThreeCorner(const Standard_Integer Jndex) +{ + +#ifdef DEB + OSD_Chronometer ch; + ChFi3d_InitChron(ch); // init perf initialisation +#endif + + TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); + const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Jndex); + ChFiDS_ListIteratorOfListOfStripe It; + Standard_Integer Index[3],pivot,deb,fin,ii,jj,kk; + //Standard_Real R = 0.; + Standard_Boolean pivdif = Standard_True; + Standard_Boolean c1pointu = Standard_False; + Standard_Boolean c1toric = Standard_False; + Standard_Boolean c1spheric = Standard_False; + Handle(ChFiDS_Stripe) CD[3]; + TopoDS_Face face[3]; + Standard_Integer jf[3][3]; + Standard_Boolean sameside[3], oksea[3]; + for(Standard_Integer g = 0; g <= 2; g++){oksea[g] = Standard_False;} + Standard_Integer i[3][3]; + Standard_Integer sens[3]; + Standard_Real p[3][3]; + + Standard_Boolean filling = 0; + + for (It.Initialize(myVDataMap(Jndex)),ii=0;It.More() && ii<3;It.Next(),ii++){ + Index[ii] = ChFi3d_IndexOfSurfData(Vtx,It.Value(),sens[ii]); + CD[ii] = It.Value(); + } + // It is checked if one of CD is not present twice in which + // case it is necessary to modify the return of IndexOfSurfData + // that takes the first solution. + if(CD[0] == CD[1]){ + Index[1] = CD[1]->SetOfSurfData()->Length(); + sens[1] = -1; + } + else if(CD[1] == CD[2]){ + Index[2] = CD[2]->SetOfSurfData()->Length(); + sens[2] = -1; + } + else if(CD[0] == CD[2]){ + Index[2] = CD[2]->SetOfSurfData()->Length(); + sens[2] = -1; + } + oksea[2] = SearchFD(DStr,CD[0],CD[1],sens[0],sens[1],i[0][1],i[1][0], + p[0][1],p[1][0],Index[0],Index[1],face[2],sameside[2], + jf[0][1],jf[1][0]); + oksea[1] = SearchFD(DStr,CD[0],CD[2],sens[0],sens[2],i[0][2],i[2][0], + p[0][2],p[2][0],Index[0],Index[2],face[1],sameside[1], + jf[0][2],jf[2][0]); + oksea[0] = SearchFD(DStr,CD[1],CD[2],sens[1],sens[2],i[1][2],i[2][1], + p[1][2],p[2][1],Index[1],Index[2],face[0],sameside[0], + jf[1][2],jf[2][1]); + // + // Analyze concavities of 3 fillets : + // - 2 concavities identic and 1 inverted. + // - 3 concavities identic + // + if(oksea[2] && oksea[1] && !sameside[2] && !sameside[1]) + { pivot = 0; deb = 1; fin = 2;} + else if(oksea[2] && oksea[0] && !sameside[2] && !sameside[0]) + { pivot = 1; deb = 2; fin = 0;} + else if(oksea[1] && oksea[0] && !sameside[1] && !sameside[0]) + { pivot = 2; deb = 0; fin = 1;} + else if(oksea[0] && oksea[1] && oksea[2]){ + // 3 concavities identic. + pivot = SearchPivot(sens,p,tol2d); + if(pivot < 0){ +#ifdef DEB + cout<<"pivot not found, plate is called"<<endl; +#endif + PerformMoreThreeCorner(Jndex, 3); + return; + } + else{deb = (pivot+1)%3 ; fin = (pivot+2)%3;} + pivdif = Standard_False; + if(Abs(p[0][1]-p[0][2]) <= tol2d && + Abs(p[1][0]-p[1][2]) <= tol2d && + Abs(p[2][0]-p[2][1]) <= tol2d){ + c1pointu = Standard_True; + } + } + else { + PerformMoreThreeCorner(Jndex, 3); + return; + } + Standard_Integer ifacdeb, ifacfin; + ifacdeb = CD[deb]->ChangeSetOfSurfData()->Value(i[deb][pivot])->Index(3-jf[deb][pivot]); + ifacfin = CD[fin]->ChangeSetOfSurfData()->Value(i[fin][pivot])->Index(3-jf[fin][pivot]); + if(ifacfin != ifacdeb){ +#ifdef DEB + cout<<"several base faces, plate is called"<<endl; +#endif + PerformMoreThreeCorner(Jndex, 3); + return; + } + if(i[pivot][deb] != i[pivot][fin]){ +#ifdef DEB + cout<<"load surfdata on the pivot, plate is called"<<endl; +#endif + PerformMoreThreeCorner(Jndex, 3); + return; + } + + Standard_Real Rdeb,Rfin,Rdp,Rfp; + gp_Pnt Pdeb,Pfin,Pdp,Pfp; + gp_Vec Vdeb,Vfin,Vdp,Vfp; + if(c1pointu){ + gp_Pnt pbid; + gp_Vec qv[3]; + Standard_Real qr[3]; + for(ii = 0; ii<=2; ii++){ + jj = (ii+1)%3 ; kk = (ii+2)%3; + ChFi3d_ExtrSpineCarac(DStr,CD[jj],i[jj][ii],p[jj][ii],1, + sens[jj],pbid,qv[jj],qr[jj]); + } + for(ii = 0; ii<=2 && !c1toric; ii++){ + jj = (ii+1)%3 ; kk = (ii+2)%3; + if(ToricCorner(face[ii],qr[jj],qr[kk],qv[ii])){ + c1toric = Standard_True; + pivot = ii; deb = jj; fin = kk; + } + } + if(!c1toric)c1spheric=(Abs(qr[0]-qr[1])<tolesp && Abs(qr[0]-qr[2])<tolesp); + } + + // Previously to avoid loops the points were always located + // inside, which could impede the construction of the + // guideline of the corner which now is a circle. + // Standard_Integer jjjd = jf[deb][fin], jjjf = jf[fin][deb]; + // if (pivdif) jjjd = jf[deb][pivot], jjjf = jf[fin][pivot]; + Standard_Integer jjjd = jf[deb][pivot], jjjf = jf[fin][pivot]; + ChFi3d_ExtrSpineCarac(DStr,CD[deb],i[deb][pivot],p[deb][pivot], + jjjd,sens[deb],Pdeb,Vdeb,Rdeb); + ChFi3d_ExtrSpineCarac(DStr,CD[fin],i[fin][pivot],p[fin][pivot], + jjjf,sens[fin],Pfin,Vfin,Rfin); + ChFi3d_ExtrSpineCarac(DStr,CD[pivot],i[pivot][deb],p[pivot][deb], + 0,sens[pivot],Pdp,Vdp,Rdp); + ChFi3d_ExtrSpineCarac(DStr,CD[pivot],i[pivot][fin],p[pivot][fin], + 0,sens[pivot],Pfp,Vfp,Rfp); + //in cas of allsame it is checked that points on the face are not + //too close, which can stop the work. + if(!pivdif) { + gp_Pnt ptestdeb,ptestfin; gp_Vec bidvec; Standard_Real bidr; + ChFi3d_ExtrSpineCarac(DStr,CD[deb],i[deb][pivot],p[deb][pivot], + jf[deb][fin],sens[deb],ptestdeb,bidvec,bidr); + ChFi3d_ExtrSpineCarac(DStr,CD[fin],i[fin][pivot],p[fin][pivot], + jf[fin][deb],sens[fin],ptestfin,bidvec,bidr); + Standard_Real distest = ptestdeb.Distance(ptestfin); + if(distest < (Rdp+Rfp)*0.05) filling = 1; + if(distest < (Rdp+Rfp)*0.005) c1pointu = 1; + } + + if(!c1pointu){ + if (!pivdif) c1pointu = (Abs(p[deb][pivot]-p[deb][fin]) <=tol2d && + Abs(p[fin][pivot]-p[fin][deb]) <=tol2d); + if(Abs(p[pivot][deb] - p[pivot][fin]) <= tol2d) + c1toric = ToricCorner(face[pivot],Rdeb,Rfin,Vdp); + } + // there is a pivot, the start and the end CD (finally !?!) : + // ------------------------------------------------------------- + // the criterions determining if the corner is a torus or a sphere + // are based only on the configuration of sections at end and the + // nature of faces, it is necessary to make tests to + // determine if a more detailed analysis of incident fillets + // is necessare to provide tangency between them and + // the corner (in particular in the case with variable radius). + + + + Handle(ChFiDS_SurfData)& + fddeb = CD[deb]->ChangeSetOfSurfData()->ChangeValue(i[deb][pivot]); + Handle(ChFiDS_SurfData)& + fdfin = CD[fin]->ChangeSetOfSurfData()->ChangeValue(i[fin][pivot]); + Handle(ChFiDS_SurfData)& + fdpiv = CD[pivot]->ChangeSetOfSurfData()->ChangeValue(i[pivot][deb]); + + + // HSurfaces and other suitable tools are constructed. + // ---------------------------------------------------------- + + TopAbs_Orientation OFac = face[pivot].Orientation(); + Handle(BRepAdaptor_HSurface) Fac = new BRepAdaptor_HSurface(face[pivot]); + gp_Pnt2d ppp1,ppp2; + const ChFiDS_FaceInterference& bid1 = CD[pivot]->SetOfSurfData()-> + Value(i[pivot][deb])->InterferenceOnS1(); + ppp1 = bid1.PCurveOnSurf()->Value(bid1.FirstParameter()); + const ChFiDS_FaceInterference& bid2 = CD[pivot]->SetOfSurfData()-> + Value(i[pivot][deb])->InterferenceOnS2(); + ppp2 = bid2.PCurveOnSurf()->Value(bid2.LastParameter()); + Standard_Real uu1 = ppp1.X(), uu2 = ppp2.X(), vv1 = ppp1.Y(), vv2 = ppp2.Y(); + GeomAdaptor_Surface + gasurf((DStr.Surface(CD[pivot]->SetOfSurfData()-> + Value(i[pivot][deb])->Surf())).Surface(), + uu1, uu2, vv1, vv2); + GeomAbs_SurfaceType styp = gasurf.GetType(); + if(styp == GeomAbs_Cylinder){ + Standard_Real h = vv2 - vv1; + vv1 -= 0.5*h; + vv2 += 0.5*h; + gasurf.Load((DStr.Surface(CD[pivot]->SetOfSurfData()-> + Value(i[pivot][deb])->Surf())).Surface(), + uu1, uu2, vv1, vv2); + } + else if(styp == GeomAbs_Torus){ + Standard_Real h = uu2 - uu1; + uu1 -= 0.1*h; + uu2 += 0.1*h; + gasurf.Load((DStr.Surface(CD[pivot]->SetOfSurfData()-> + Value(i[pivot][deb])->Surf())).Surface(), + uu1, uu2, vv1, vv2); + } + else if(styp == GeomAbs_BezierSurface || styp == GeomAbs_BSplineSurface){ + gasurf.Load((DStr.Surface(CD[pivot]->SetOfSurfData()-> + Value(i[pivot][deb])->Surf())).Surface()); + } + + Handle(GeomAdaptor_HSurface) Surf = new GeomAdaptor_HSurface(gasurf); + // Handle(BRepTopAdaptor_TopolTool) IFac = new BRepTopAdaptor_TopolTool(Fac); + // Try to not classify on the face for cases of reentering fillets which naturally depass + // the border. + Handle(GeomAdaptor_HSurface) + bidsurf = new GeomAdaptor_HSurface(Fac->ChangeSurface().Surface()); + Handle(Adaptor3d_TopolTool) + IFac = new Adaptor3d_TopolTool(bidsurf); + // end of the attempt. + Handle(Adaptor3d_TopolTool) ISurf = new Adaptor3d_TopolTool(Surf); + Handle(ChFiDS_Stripe) corner = new ChFiDS_Stripe(); + Handle(ChFiDS_HData)& cornerset = corner->ChangeSetOfSurfData(); + cornerset = new ChFiDS_HData(); + Handle(ChFiDS_SurfData) coin = new ChFiDS_SurfData(); + cornerset->Append(coin); + TopAbs_Orientation o1,o2,os1,os2,oo1,oo2; + Standard_Integer choix = CD[deb]->Choix(); + o1 = face[pivot].Orientation(); + o2 = fdpiv->Orientation(); + oo1 = o1; oo2 = o2; + os1 = CD[deb]->OrientationOnFace1(); + os2 = CD[deb]->OrientationOnFace2(); + if(jf[deb][fin] == 1){ + choix = ChFi3d::NextSide(o1,o2,os1,os2,choix); + if(sens[deb] == 1){ + if(choix%2 == 1) choix++; + else choix--; + } + } + else { + choix = ChFi3d::NextSide(o2,o1,os1,os2,-choix); + if(sens[deb] == -1){ + if(choix%2 == 1) choix++; + else choix--; + } + } + + gp_Pnt2d pfac1,pfac2,psurf1,psurf2; + gp_Vec2d vfac1,vfac2; + CD[deb]->SetOfSurfData()->Value(i[deb][pivot])-> + Interference(jf[deb][fin]).PCurveOnFace()->D1(p[deb][pivot],pfac1,vfac1); + CD[fin]->SetOfSurfData()->Value(i[fin][pivot])-> + Interference(jf[fin][deb]).PCurveOnFace()->D1(p[fin][pivot],pfac2,vfac2); + psurf1 = CD[pivot]->SetOfSurfData()->Value(i[pivot][deb])-> + Interference(jf[pivot][deb]).PCurveOnSurf()->Value(p[pivot][deb]); + psurf2 = CD[pivot]->SetOfSurfData()->Value(i[pivot][fin])-> + Interference(jf[pivot][fin]).PCurveOnSurf()->Value(p[pivot][fin]); + + done = Standard_False; +#ifdef DEB + if(ChFi3d_GetcontextFORCEFILLING()) c1spheric = c1toric = 0; +#endif + +#ifdef DEB + ChFi3d_ResultChron(ch , t_t3cornerinit); // result perf initialisations +#endif + + if (c1toric){ + +#ifdef DEB + ChFi3d_InitChron(ch); // init perf case torus +#endif + + // Direct Construction. + // --------------------- + done = ChFiKPart_ComputeData::ComputeCorner + (DStr,coin,Fac,Surf,oo1,oo2,o1,o2,Rdeb,Rdp,pfac1,pfac2,psurf1,psurf2); + +#ifdef DEB + ChFi3d_ResultChron(ch , t_torique); // result perf case torus +#endif + + } + else if(c1spheric){ + +#ifdef DEB + ChFi3d_InitChron(ch); //init perf case sphere +#endif + + done = ChFiKPart_ComputeData::ComputeCorner + (DStr,coin,Fac,Surf,oo1,oo2,o1,o2,Rdp,pfac1,psurf1,psurf2); + +#ifdef DEB + ChFi3d_ResultChron(ch , t_spherique);// result perf cas sphere +#endif + + } + else if(c1pointu){ + filling = 1; + } + if(!done){ + if(!filling) { + +#ifdef DEB + ChFi3d_InitChron(ch);// init perf not filling +#endif + + //Calculate a guideline, + //------------------------------ + //Numerous problems with loops and half-turns connected to + //the curvature of the guideline !!!!!! + //FOR CIRCLE. + //If the nature of guideline is changed it is necessary to + //reset points Pdeb and Pfin at the inside (see the + //comments about it in the calculation of Pdeb and Pfin). + + Standard_Real radpondere = (Rdp+Rfp)/2.; + Standard_Real locfleche = fleche; + + Standard_Real WFirst,WLast; + Handle(Geom_Curve) spinecoin = ChFi3d_CircularSpine(WFirst,WLast, + Pdeb,Vdeb, + Pfin,Vfin,radpondere); + if(spinecoin.IsNull()){ + // This is a bad case when the intersection of + // section planes is done out of the sector. + spinecoin = ChFi3d_Spine(Pdeb,Vdeb, + Pfin,Vfin,radpondere); + WFirst = 0.; WLast = 1.; + } + else locfleche = radpondere * (WLast - WFirst) * fleche; + Standard_Real pasmax = (WLast-WFirst)*0.05; + Handle(ChFiDS_HElSpine) cornerspine = new ChFiDS_HElSpine(); + cornerspine->ChangeCurve().SetCurve(spinecoin); + cornerspine->ChangeCurve().FirstParameter(WFirst - pasmax); + cornerspine->ChangeCurve().LastParameter(WLast + pasmax); + // Just to confuse Compute that should not require this + // in this exact case ... + Handle(ChFiDS_Spine) NullSpine; + // The fillet is calculated - from beginning to end + // - from the face to the surface + // + math_Vector Soldep(1,4); + Soldep(1) = pfac1.X(); + Soldep(2) = pfac1.Y(); + Soldep(3) = psurf1.X(); + Soldep(4) = psurf1.Y(); + + Standard_Boolean Gd1,Gd2,Gf1,Gf2; + Handle(BRepBlend_Line) lin; + Standard_Real ffi = WFirst, lla = WLast + pasmax; + + if (Abs(Rdeb-Rfin)<=tolesp){ + + BRepBlend_ConstRad func(Fac,Surf,cornerspine); + BRepBlend_ConstRadInv finv(Fac,Surf,cornerspine); + func.Set(Rdeb,choix); + func.Set(myShape); + finv.Set(Rdeb,choix); + Standard_Real TolGuide = cornerspine->Resolution(tolesp); + + Standard_Boolean intf = 3, intl = 3; + done = ComputeData(coin,cornerspine,NullSpine,lin,Fac,IFac,Surf,ISurf, + func,finv,ffi,pasmax,locfleche,TolGuide,ffi,lla, + 0,0,1,Soldep,intf,intl,Gd1,Gd2,Gf1,Gf2,0,1); +#ifdef DEB + if(ChFi3d_GetcontextFORCEFILLING()) done = 0; +#endif + if(done && Gf2){ + done = CompleteData(coin,func,lin,Fac,Surf,OFac,Gd1,0,Gf1,0); + filling = !done; + } + else filling = 1; + } + else{ + Handle(Law_S) law = new Law_S(); + law->Set(WFirst,Rdeb,WLast,Rfin); + BRepBlend_EvolRad func(Fac,Surf,cornerspine,law); + BRepBlend_EvolRadInv finv(Fac,Surf,cornerspine,law); + func.Set(choix); + func.Set(myShape); + finv.Set(choix); + Standard_Real TolGuide = cornerspine->Resolution(tolesp); + Standard_Boolean intf = 3, intl = 3; + done = ComputeData(coin,cornerspine,NullSpine,lin,Fac,IFac,Surf,ISurf, + func,finv,ffi,pasmax,locfleche,TolGuide,ffi,lla, + 0,0,1,Soldep,intf,intl,Gd1,Gd2,Gf1,Gf2,0,1); +#ifdef DEB + if(ChFi3d_GetcontextFORCEFILLING()) done = 0; +#endif + if(done && Gf2){ + done = CompleteData(coin,func,lin,Fac,Surf,OFac,Gd1,0,Gf1,0); + filling = !done; + } + else filling = 1; + } + +#ifdef DEB + ChFi3d_ResultChron(ch , t_notfilling);// result perf not filling +#endif + + } + + if(filling) { + +#ifdef DEB + ChFi3d_InitChron(ch); // init perf filling +#endif + + // the contour to be fillet consists of straight lines uv in beginning and end + // of two pcurves (only one if c1pointu) calculted as possible + // on piv and the opposite face. + Handle(GeomFill_Boundary) Bdeb,Bfin,Bpiv,Bfac; + Handle(Geom2d_Curve) PCurveOnFace; + if(!c1pointu) + Bfac = ChFi3d_mkbound(Fac,PCurveOnFace,sens[deb],pfac1,vfac1, + sens[fin],pfac2,vfac2,tolesp,2.e-4); + Standard_Integer kkk; + gp_Pnt ppbid; + gp_Vec vp1,vp2; + kkk = CD[deb]->SetOfSurfData()->Value(i[deb][pivot])-> + Interference(jf[deb][pivot]).LineIndex(); + DStr.Curve(kkk).Curve()->D1(p[deb][pivot],ppbid,vp1); + kkk = CD[fin]->SetOfSurfData()->Value(i[fin][pivot])-> + Interference(jf[fin][pivot]).LineIndex(); + DStr.Curve(kkk).Curve()->D1(p[fin][pivot],ppbid,vp2); + Handle(Geom2d_Curve) PCurveOnPiv; +// Bpiv = ChFi3d_mkbound(Surf,PCurveOnPiv,sens[deb],psurf1,vp1, +// sens[fin],psurf2,vp2,tolesp,2.e-4); + Bpiv = ChFi3d_mkbound(Surf,PCurveOnPiv,psurf1,psurf2,tolesp,2.e-4,0); + Standard_Real pardeb2 = p[deb][pivot]; + Standard_Real parfin2 = p[fin][pivot]; + if(c1pointu){ + pardeb2 = p[deb][fin]; + parfin2 = p[fin][deb]; + } + gp_Pnt2d pdeb1 = CD[deb]->SetOfSurfData()->Value(i[deb][pivot])-> + Interference(jf[deb][pivot]).PCurveOnSurf()->Value(p[deb][pivot]); + gp_Pnt2d pdeb2 = CD[deb]->SetOfSurfData()->Value(i[deb][pivot])-> + Interference(jf[deb][fin]).PCurveOnSurf()->Value(pardeb2); + gp_Pnt2d pfin1 = CD[fin]->SetOfSurfData()->Value(i[fin][pivot])-> + Interference(jf[fin][pivot]).PCurveOnSurf()->Value(p[fin][pivot]); + gp_Pnt2d pfin2 = CD[fin]->SetOfSurfData()->Value(i[fin][pivot])-> + Interference(jf[fin][deb]).PCurveOnSurf()->Value(parfin2); + Handle(Geom_Surface) sdeb = + DStr.Surface(CD[deb]->SetOfSurfData()-> + Value(i[deb][pivot])->Surf()).Surface(); + Handle(Geom_Surface) sfin = + DStr.Surface(CD[fin]->SetOfSurfData()-> + Value(i[fin][pivot])->Surf()).Surface(); + + Bdeb = ChFi3d_mkbound(sdeb,pdeb1,pdeb2,tolesp,2.e-4); + Bfin = ChFi3d_mkbound(sfin,pfin1,pfin2,tolesp,2.e-4); + + GeomFill_ConstrainedFilling fil(11,20); + if(c1pointu) fil.Init(Bpiv,Bfin,Bdeb,1); + else fil.Init(Bpiv,Bfin,Bfac,Bdeb,1); + + Handle(Geom_Surface) Surfcoin = fil.Surface(); + Surfcoin->VReverse(); // revert to direction face surface; + done = CompleteData(coin,Surfcoin, + Fac,PCurveOnFace, + Surf,PCurveOnPiv,fdpiv->Orientation(),0, + 0,0,0,0); + +#ifdef DEB + ChFi3d_ResultChron(ch , t_filling);// result perf filling +#endif + + } + } + Standard_Real P1deb,P2deb,P1fin,P2fin; + if(!c1pointu){ + p[deb][fin] = p[deb][pivot]; + p[fin][deb] = p[fin][pivot]; + } + + if (done){ + // Update of 4 Stripes and the DS + // ------------------------------------- + +#ifdef DEB + ChFi3d_InitChron(ch);// init perf update DS +#endif + + gp_Pnt2d pp1,pp2; + Standard_Real parpp1,parpp2; + Standard_Integer If1,If2,Il1,Il2,Icf,Icl; + const ChFiDS_CommonPoint& Pf1 = coin->VertexFirstOnS1(); + const ChFiDS_CommonPoint& Pf2 = coin->VertexFirstOnS2(); + ChFiDS_CommonPoint& Pl1 = coin->ChangeVertexLastOnS1(); + if(c1pointu) Pl1 = coin->ChangeVertexFirstOnS1(); + const ChFiDS_CommonPoint& Pl2 = coin->VertexLastOnS2(); + + Bnd_Box bf1,bl1,bf2,bl2; + Bnd_Box *pbf1 = &bf1,*pbl1 = &bl1,*pbf2 = &bf2,*pbl2 = &bl2; + if(c1pointu) pbl1 = pbf1; + pbf1->Add(Pf1.Point());pbf2->Add(Pf2.Point()); + pbl1->Add(Pl1.Point());pbl2->Add(Pl2.Point()); + + // the start corner, + // ----------------------- + ChFiDS_Regul regdeb, regfin; + If1 = ChFi3d_IndexPointInDS(Pf1,DStr); + If2 = ChFi3d_IndexPointInDS(Pf2,DStr); + if(c1pointu) Il1 = If1; + else Il1 = ChFi3d_IndexPointInDS(Pl1,DStr); + Il2 = ChFi3d_IndexPointInDS(Pl2,DStr); + pp1 = coin->InterferenceOnS1().PCurveOnSurf()-> + Value(coin->InterferenceOnS1().FirstParameter()); + pp2 = coin->InterferenceOnS2().PCurveOnSurf()-> + Value(coin->InterferenceOnS2().FirstParameter()); + if(c1pointu) coin->ChangeIndexOfS1(0); + else coin->ChangeIndexOfS1(DStr.AddShape(face[pivot])); + coin->ChangeIndexOfS2(-fdpiv->Surf()); + + Handle(Geom_Curve) C3d; + Standard_Real tolreached; + ChFi3d_ComputeArete(Pf1,pp1,Pf2,pp2, + DStr.Surface(coin->Surf()).Surface(),C3d, + corner->ChangeFirstPCurve(),P1deb,P2deb, + tolesp,tol2d,tolreached,0); + TopOpeBRepDS_Curve Tcurv1(C3d,tolreached); + Icf = DStr.AddCurve(Tcurv1); + regdeb.SetCurve(Icf); + regdeb.SetS1(coin->Surf(),0); + regdeb.SetS2(fddeb->Surf(),0); + myRegul.Append(regdeb); + corner->ChangeFirstCurve(Icf); + corner->ChangeFirstParameters(P1deb,P2deb); + corner->ChangeIndexFirstPointOnS1(If1); + corner->ChangeIndexFirstPointOnS2(If2); + ChFi3d_EnlargeBox(DStr,corner,coin,*pbf1,*pbf2,1); + + pp1 = coin->InterferenceOnS1().PCurveOnSurf()-> + Value(coin->InterferenceOnS1().LastParameter()); + pp2 = coin->InterferenceOnS2().PCurveOnSurf()-> + Value(coin->InterferenceOnS2().LastParameter()); + ChFi3d_ComputeArete(Pl1,pp1,Pl2,pp2, + DStr.Surface(coin->Surf()).Surface(),C3d, + corner->ChangeLastPCurve(),P1fin,P2fin, + tolesp,tol2d,tolreached,0); + TopOpeBRepDS_Curve Tcurv2(C3d,tolreached); + Icl = DStr.AddCurve(Tcurv2); + regfin.SetCurve(Icl); + regfin.SetS1(coin->Surf(),0); + regfin.SetS2(fdfin->Surf(),0); + myRegul.Append(regfin); + corner->ChangeLastCurve(Icl); + corner->ChangeLastParameters(P1fin,P2fin); + corner->ChangeIndexLastPointOnS1(Il1); + corner->ChangeIndexLastPointOnS2(Il2); + ChFi3d_EnlargeBox(DStr,corner,coin,*pbl1,*pbl2,0); + + // then CornerData of the beginning, + // -------------------------------- + Standard_Boolean isfirst = (sens[deb] == 1), rev = (jf[deb][fin] == 2); + Standard_Integer isurf1 = 1, isurf2 = 2; + parpp1 = p[deb][fin]; parpp2 = p[deb][pivot]; + if (rev) { + isurf1 = 2; isurf2 = 1; + parpp1 = p[deb][pivot]; parpp2 = p[deb][fin]; + CD[deb]->SetOrientation(TopAbs_REVERSED,isfirst); + } + pp1 = fddeb->InterferenceOnS1().PCurveOnSurf()->Value(parpp1); + pp2 = fddeb->InterferenceOnS2().PCurveOnSurf()->Value(parpp2); + CD[deb]->SetCurve(Icf,isfirst); + CD[deb]->SetIndexPoint(If1,isfirst,isurf1); + CD[deb]->SetIndexPoint(If2,isfirst,isurf2); + CD[deb]->SetParameters(isfirst,P1deb,P2deb); + fddeb->ChangeVertex(isfirst,isurf1) = Pf1; + fddeb->ChangeVertex(isfirst,isurf2) = Pf2; + fddeb->ChangeInterferenceOnS1().SetParameter(parpp1,isfirst); + fddeb->ChangeInterferenceOnS2().SetParameter(parpp2,isfirst); + TopOpeBRepDS_Curve& tcdeb = DStr.ChangeCurve(Icf); + Handle(Geom_Curve) crefdeb = tcdeb.Curve(); + Standard_Real tolrdeb; + ChFi3d_ComputePCurv(crefdeb,pp1,pp2,CD[deb]->ChangePCurve(isfirst), + DStr.Surface(fddeb->Surf()).Surface(), + P1deb,P2deb,tolesp,tolrdeb,rev); + tcdeb.Tolerance(Max(tolrdeb,tcdeb.Tolerance())); + if(rev) ChFi3d_EnlargeBox(DStr,CD[deb],fddeb,*pbf2,*pbf1,isfirst); + else ChFi3d_EnlargeBox(DStr,CD[deb],fddeb,*pbf1,*pbf2,isfirst); + + // then the end CornerData, + // ------------------------ + isfirst = (sens[fin] == 1); rev = (jf[fin][deb] == 2); + isurf1 = 1; isurf2 = 2; + parpp1 = p[fin][deb]; parpp2 = p[fin][pivot]; + if (rev) { + isurf1 = 2; isurf2 = 1; + parpp1 = p[fin][pivot]; parpp2 = p[fin][deb]; + CD[fin]->SetOrientation(TopAbs_REVERSED,isfirst); + } + pp1 = fdfin->InterferenceOnS1().PCurveOnSurf()->Value(parpp1); + pp2 = fdfin->InterferenceOnS2().PCurveOnSurf()->Value(parpp2); + CD[fin]->SetCurve(Icl,isfirst); + CD[fin]->SetIndexPoint(Il1,isfirst,isurf1); + CD[fin]->SetIndexPoint(Il2,isfirst,isurf2); + CD[fin]->SetParameters(isfirst,P1fin,P2fin); + fdfin->ChangeVertex(isfirst,isurf1) = Pl1; + fdfin->ChangeVertex(isfirst,isurf2) = Pl2; + fdfin->ChangeInterferenceOnS1().SetParameter(parpp1,isfirst); + fdfin->ChangeInterferenceOnS2().SetParameter(parpp2,isfirst); + TopOpeBRepDS_Curve& tcfin = DStr.ChangeCurve(Icl); + Handle(Geom_Curve) creffin = tcfin.Curve(); + Standard_Real tolrfin; + ChFi3d_ComputePCurv(creffin,pp1,pp2,CD[fin]->ChangePCurve(isfirst), + DStr.Surface(fdfin->Surf()).Surface(), + P1fin,P2fin,tolesp,tolrfin,rev); + tcfin.Tolerance(Max(tolrfin,tcfin.Tolerance())); + if(rev) ChFi3d_EnlargeBox(DStr,CD[fin],fdfin,*pbl2,*pbl1,isfirst); + else ChFi3d_EnlargeBox(DStr,CD[fin],fdfin,*pbl1,*pbl2,isfirst); + + // anf finally the pivot. + // ------------------ + ChFiDS_FaceInterference& fi = coin->ChangeInterferenceOnS2(); + isfirst = (sens[pivot] == 1); rev = (jf[pivot][deb] == 2); + isurf1 = 1; isurf2 = 2; + if (rev) { + isurf1 = 2; isurf2 = 1; + CD[pivot]->SetOrientation(TopAbs_REVERSED,isfirst); + } + Standard_Integer ICcoinpiv = fi.LineIndex(); + TopOpeBRepDS_Curve& TCcoinpiv = DStr.ChangeCurve(ICcoinpiv); + CD[pivot]->SetCurve(ICcoinpiv,isfirst); + Handle(Geom_Curve) Ccoinpiv = DStr.Curve(ICcoinpiv).Curve(); + Handle(Geom2d_Curve)& C2dOnPiv = fi.ChangePCurveOnFace(); + Handle(Geom_Surface) Spiv = DStr.Surface(fdpiv->Surf()).Surface(); + Standard_Real tolr; + ChFi3d_SameParameter(Ccoinpiv,C2dOnPiv,Spiv, + fi.FirstParameter(),fi.LastParameter(), + tolesp,tolr); + TCcoinpiv.Tolerance(Max(TCcoinpiv.Tolerance(),tolr)); + CD[pivot]->ChangePCurve(isfirst) = C2dOnPiv; + CD[pivot]->SetIndexPoint(If2,isfirst,isurf1); + CD[pivot]->SetIndexPoint(Il2,isfirst,isurf2); + CD[pivot]->SetParameters(isfirst,fi.FirstParameter(),fi.LastParameter()); + fdpiv->ChangeVertex(isfirst,isurf1) = Pf2; + fdpiv->ChangeVertex(isfirst,isurf2) = Pl2; + fdpiv->ChangeInterference(isurf1).SetParameter(p[pivot][deb],isfirst); + fdpiv->ChangeInterference(isurf2).SetParameter(p[pivot][fin],isfirst); + CD[pivot]->InDS(isfirst); // filDS already does it from the corner. + if(rev) ChFi3d_EnlargeBox(DStr,CD[pivot],fdpiv,*pbl2,*pbf2,isfirst); + else ChFi3d_EnlargeBox(DStr,CD[pivot],fdpiv,*pbf2,*pbl2,isfirst); + + //To end the tolerances of points are rescaled. + ChFi3d_SetPointTolerance(DStr,*pbf1,If1); + ChFi3d_SetPointTolerance(DStr,*pbf2,If2); + ChFi3d_SetPointTolerance(DStr,*pbl1,Il1); + ChFi3d_SetPointTolerance(DStr,*pbl2,Il2); + } + + //The data corners are truncated and index is updated. + //---------------------------------------------------- + + if(i[deb][pivot] < Index[deb]){ + CD[deb]->ChangeSetOfSurfData()->Remove(i[deb][pivot]+1,Index[deb]); + Index[deb] = i[deb][pivot]; + } + else if(i[deb][pivot] > Index[deb]) { + CD[deb]->ChangeSetOfSurfData()->Remove(Index[deb],i[deb][pivot]-1); + i[deb][pivot] = Index[deb]; + } + if(i[fin][pivot] < Index[fin]) { + CD[fin]->ChangeSetOfSurfData()->Remove(i[fin][pivot]+1,Index[fin]); + Index[fin] = i[fin][pivot]; + } + else if(i[fin][pivot] > Index[fin]) { + CD[fin]->ChangeSetOfSurfData()->Remove(Index[fin],i[fin][pivot]-1); + i[fin][pivot] = Index[fin]; + } + // it is necessary to take into account mutant corners. + if(i[pivot][deb] < Index[pivot]) { + CD[pivot]->ChangeSetOfSurfData()->Remove(i[pivot][deb]+1,Index[pivot]); + Index[pivot] = i[pivot][deb]; + } + else if(i[pivot][deb] > Index[pivot]) { + CD[pivot]->ChangeSetOfSurfData()->Remove(Index[pivot],i[pivot][deb]-1); + i[pivot][deb] = Index[pivot]; + } + if(!myEVIMap.IsBound(Vtx)){ + TColStd_ListOfInteger li; + myEVIMap.Bind(Vtx,li); + } + myEVIMap.ChangeFind(Vtx).Append(coin->Surf()); + corner->SetSolidIndex(CD[pivot]->SolidIndex()); + myListStripe.Append(corner); + +#ifdef DEB + ChFi3d_ResultChron(ch , t_t3cornerDS);// result perf update DS +#endif +} diff --git a/src/ChFi3d/ChFi3d_SearchSing.cdl b/src/ChFi3d/ChFi3d_SearchSing.cdl new file mode 100644 index 00000000..725efff8 --- /dev/null +++ b/src/ChFi3d/ChFi3d_SearchSing.cdl @@ -0,0 +1,44 @@ +-- File: ChFi3d_SearchSing.cdl +-- Created: Fri Mar 28 11:11:47 1997 +-- Author: Philippe MANGIN +-- <pmn@sgi29> +---Copyright: Matra Datavision 1997 + + +private class SearchSing from ChFi3d inherits FunctionWithDerivative from math + + ---Purpose: F(t) = (C1(t) - C2(t)).(C1'(t) - C2'(t)); + +uses Curve from Geom + +is + Create(C1, C2 : Curve from Geom) + returns SearchSing from ChFi3d; + + Value(me: in out; X: Real; F: out Real) + ---Purpose: computes the value of the function <F> for the + -- variable <X>. + -- returns True if the computation was done successfully, + -- False otherwise. + returns Boolean; + + Derivative(me: in out; X: Real; D: out Real) + ---Purpose: computes the derivative <D> of the function + -- for the variable <X>. + -- Returns True if the calculation were successfully done, + -- False otherwise. + + returns Boolean; + + Values(me: in out; X: Real; F, D: out Real) + ---Purpose: computes the value <F> and the derivative <D> of the + -- function for the variable <X>. + -- Returns True if the calculation were successfully done, + -- False otherwise. + + returns Boolean; + +fields +myC1 : Curve from Geom; +myC2 : Curve from Geom; +end SearchSing; diff --git a/src/ChFi3d/ChFi3d_SearchSing.cxx b/src/ChFi3d/ChFi3d_SearchSing.cxx new file mode 100644 index 00000000..19712832 --- /dev/null +++ b/src/ChFi3d/ChFi3d_SearchSing.cxx @@ -0,0 +1,59 @@ +// File: ChFi3d_SearchSing.cxx +// Created: Fri Mar 28 15:37:38 1997 +// Author: Philippe MANGIN +// <pmn@sgi29> + + +#include <ChFi3d_SearchSing.ixx> + +#include <gp_Pnt.hxx> +#include <gp_Vec.hxx> + +ChFi3d_SearchSing::ChFi3d_SearchSing(const Handle(Geom_Curve)& C1, + const Handle(Geom_Curve)& C2) +{ + myC1 = C1; + myC2 = C2; +} + + + +Standard_Boolean ChFi3d_SearchSing::Value(const Standard_Real X, + Standard_Real& F) +{ + gp_Pnt P1, P2; + gp_Vec V1, V2; + myC1->D1(X, P1, V1); + myC2->D1(X, P2, V2); + gp_Vec V(P1,P2); + F = V * (V2-V1); + return Standard_True; +} + +Standard_Boolean ChFi3d_SearchSing::Derivative(const Standard_Real X, + Standard_Real& D ) +{ + gp_Pnt P1, P2; + gp_Vec V1, V2, W1, W2; + myC1->D2(X, P1, V1, W1); + myC2->D2(X, P2, V2, W2); + gp_Vec V(P1,P2), VPrim; + VPrim = V2 -V1; + D = VPrim.SquareMagnitude() + (V * (W2-W1)); + return Standard_True; +} + +Standard_Boolean ChFi3d_SearchSing::Values(const Standard_Real X, + Standard_Real& F, + Standard_Real& D ) +{ + gp_Pnt P1, P2; + gp_Vec V1, V2, W1, W2; + myC1->D2(X, P1, V1, W1); + myC2->D2(X, P2, V2, W2); + gp_Vec V(P1,P2), VPrim; + VPrim = V2 -V1; + F = V * VPrim; + D = VPrim.SquareMagnitude() + (V * (W2-W1)); + return Standard_True; +} diff --git a/src/ChFi3d/FILES b/src/ChFi3d/FILES new file mode 100644 index 00000000..b9661f22 --- /dev/null +++ b/src/ChFi3d/FILES @@ -0,0 +1,16 @@ +ChFi3d_CMPLRS.edl +ChFi3d_Builder_0.cxx +ChFi3d_Builder_0.hxx +ChFi3d_Builder_1.cxx +ChFi3d_Builder_2.cxx +ChFi3d_Builder_6.cxx +ChFi3d_Builder_C1.cxx +ChFi3d_Builder_C2.cxx +ChFi3d_Builder_SpKP.cxx +ChFi3d_Debug.cxx +ChFi3d_FilBuilder_C2.cxx +ChFi3d_FilBuilder_C3.cxx +ChFi3d_ChBuilder_C2.cxx +ChFi3d_ChBuilder_C3.cxx +ChFi3d_Builder_CnCrn.cxx +ChFi3d_Builder_NotImp.cxx |