summaryrefslogtreecommitdiff
path: root/src/ChFi3d
diff options
context:
space:
mode:
authorDenis Barbier <bouzim@gmail.com>2011-07-18 00:00:51 +0200
committerDenis Barbier <bouzim@gmail.com>2011-07-18 00:10:18 +0200
commit3a125a461d5cac09be38a87f219de9dbc65b4ff6 (patch)
tree1536173071d6a122a1f887c086c1b40bf5227e74 /src/ChFi3d
parentc99e70bc570ec25d00beb59b9429c183d8238e89 (diff)
downloadoce-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')
-rw-r--r--src/ChFi3d/ChFi3d.cdl112
-rw-r--r--src/ChFi3d/ChFi3d.cxx271
-rw-r--r--src/ChFi3d/ChFi3d_Builder.cdl973
-rw-r--r--src/ChFi3d/ChFi3d_Builder.cxx814
-rw-r--r--src/ChFi3d/ChFi3d_Builder_0.cxx4765
-rw-r--r--src/ChFi3d/ChFi3d_Builder_0.hxx570
-rw-r--r--src/ChFi3d/ChFi3d_Builder_1.cxx996
-rw-r--r--src/ChFi3d/ChFi3d_Builder_2.cxx2985
-rw-r--r--src/ChFi3d/ChFi3d_Builder_6.cxx2213
-rw-r--r--src/ChFi3d/ChFi3d_Builder_C1.cxx4358
-rw-r--r--src/ChFi3d/ChFi3d_Builder_C2.cxx670
-rw-r--r--src/ChFi3d/ChFi3d_Builder_CnCrn.cxx2969
-rw-r--r--src/ChFi3d/ChFi3d_Builder_NotImp.cxx229
-rw-r--r--src/ChFi3d/ChFi3d_Builder_SpKP.cxx1179
-rw-r--r--src/ChFi3d/ChFi3d_CMPLRS.edl21
-rw-r--r--src/ChFi3d/ChFi3d_ChBuilder.cdl451
-rw-r--r--src/ChFi3d/ChFi3d_ChBuilder.cxx2257
-rw-r--r--src/ChFi3d/ChFi3d_ChBuilder_C2.cxx18
-rw-r--r--src/ChFi3d/ChFi3d_ChBuilder_C3.cxx883
-rw-r--r--src/ChFi3d/ChFi3d_Debug.cxx298
-rw-r--r--src/ChFi3d/ChFi3d_FilBuilder.cdl466
-rw-r--r--src/ChFi3d/ChFi3d_FilBuilder.cxx2011
-rw-r--r--src/ChFi3d/ChFi3d_FilBuilder_C2.cxx943
-rw-r--r--src/ChFi3d/ChFi3d_FilBuilder_C3.cxx914
-rw-r--r--src/ChFi3d/ChFi3d_SearchSing.cdl44
-rw-r--r--src/ChFi3d/ChFi3d_SearchSing.cxx59
-rw-r--r--src/ChFi3d/FILES16
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