0032181: Modeling Algorithms - ChFi3d missing error checking
[occt.git] / src / ChFi3d / ChFi3d_Builder_CnCrn.cxx
1 // Created on: 1997-03-01
2 // Created by: MPS  
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 // Modified by  MPS (14-04-97)  traitement des cas  ou il n'y a pas
18 //                              d'intersection entre les stripes 
19 //  Modified by  MPS (16-06-97) : on tient compte du fait que GeomPlate
20 //                                rend les courbes 2d dans meme ordre que les
21 //                                courbes frontieres passees en entree   
22 //  Modified by JLR (20-08-97) mise en place des nouveaux constructeurs de GeomPlate
23 //  Modified by MPS (03-11-97) on ne cree pas un  batten lorsque le rapport
24 //  entre les deux resolutions sur la surface est trop grand (PRO10649)  
25 //  Modified by MPS (05-12-97) on ne tient pas compte des aretes degenerees
26 //                             lors du calcul du nombre d'aretes.
27 //  Modified by JCT (08-12-97) traitement des aretes vives consecutives ou non
28 //                             (grille EDC412 sauf D2, L1, L2, L3)
29 //  Modified by JCT (11-12-97) pb osf avec indpoint + orientation de plate
30 //                             ( --> D2, L1, L2, L3 valides mais laids)
31 //  Modified by MPS (24-02-98)  traitement des aretes de regularite 
32 //  Modified by MPS (01-06-98)  traitement des aretes de couture 
33 //  Modified by MPS (01-12-98)  traitement des bords libres 
34 //  Modified by MPS (01-02-99)  traitement des aretes de regularite 
35 //                              consecutives   
36 // Traitement des coins                  
37
38 #include <Adaptor2d_Curve2d.hxx>
39 #include <Adaptor3d_CurveOnSurface.hxx>
40 #include <Adaptor3d_Surface.hxx>
41 #include <Adaptor3d_TopolTool.hxx>
42 #include <AppBlend_Approx.hxx>
43 #include <Blend_CurvPointFuncInv.hxx>
44 #include <Blend_FuncInv.hxx>
45 #include <Blend_Function.hxx>
46 #include <Blend_RstRstFunction.hxx>
47 #include <Blend_SurfCurvFuncInv.hxx>
48 #include <Blend_SurfPointFuncInv.hxx>
49 #include <Blend_SurfRstFunction.hxx>
50 #include <Bnd_Box2d.hxx>
51 #include <BndLib_Add2dCurve.hxx>
52 #include <BRep_Tool.hxx>
53 #include <BRepAdaptor_Curve2d.hxx>
54 #include <BRepAdaptor_Surface.hxx>
55 #include <BRepAlgo_NormalProjection.hxx>
56 #include <BRepBlend_Line.hxx>
57 #include <BRepLib_MakeEdge.hxx>
58 #include <BRepLib_MakeFace.hxx>
59 #include <BRepTools.hxx>
60 #include <BRepTopAdaptor_TopolTool.hxx>
61 #include <ChFi3d_Builder.hxx>
62 #include <ChFi3d_Builder_0.hxx>
63 #include <ChFiDS_CommonPoint.hxx>
64 #include <ChFiDS_FaceInterference.hxx>
65 #include <ChFiDS_HData.hxx>
66 #include <ChFiDS_ElSpine.hxx>
67 #include <ChFiDS_ListIteratorOfListOfStripe.hxx>
68 #include <ChFiDS_Regul.hxx>
69 #include <ChFiDS_SequenceOfSurfData.hxx>
70 #include <ChFiDS_Spine.hxx>
71 #include <ChFiDS_Stripe.hxx>
72 #include <ChFiDS_StripeArray1.hxx>
73 #include <ChFiDS_SurfData.hxx>
74 #include <Extrema_ExtCC.hxx>
75 #include <Extrema_ExtPC.hxx>
76 #include <Extrema_POnCurv.hxx>
77 #include <FairCurve_Batten.hxx>
78 #include <Geom2d_BSplineCurve.hxx>
79 #include <Geom2d_Curve.hxx>
80 #include <Geom2d_Line.hxx>
81 #include <Geom2d_TrimmedCurve.hxx>
82 #include <Geom2dAdaptor_Curve.hxx>
83 #include <Geom2dLProp_CLProps2d.hxx>
84 #include <Geom_BezierCurve.hxx>
85 #include <Geom_BSplineSurface.hxx>
86 #include <Geom_Curve.hxx>
87 #include <Geom_Line.hxx>
88 #include <Geom_Surface.hxx>
89 #include <GeomAdaptor.hxx>
90 #include <GeomAdaptor_Surface.hxx>
91 #include <GeomInt_IntSS.hxx>
92 #include <GeomLib.hxx>
93 #include <GeomPlate_BuildPlateSurface.hxx>
94 #include <GeomPlate_CurveConstraint.hxx>
95 #include <GeomPlate_HArray1OfHCurve.hxx>
96 #include <GeomPlate_MakeApprox.hxx>
97 #include <GeomPlate_PlateG0Criterion.hxx>
98 #include <GeomPlate_Surface.hxx>
99 #include <gp_Dir2d.hxx>
100 #include <gp_Pnt.hxx>
101 #include <gp_Pnt2d.hxx>
102 #include <math_Matrix.hxx>
103 #include <PLib.hxx>
104 #include <Precision.hxx>
105 #include <Standard_ConstructionError.hxx>
106 #include <Standard_NoSuchObject.hxx>
107 #include <Standard_OutOfRange.hxx>
108 #include <TColGeom2d_Array1OfCurve.hxx>
109 #include <TColGeom2d_HArray1OfCurve.hxx>
110 #include <TColGeom2d_SequenceOfCurve.hxx>
111 #include <TColGeom_Array1OfCurve.hxx>
112 #include <TColGeom_SequenceOfCurve.hxx>
113 #include <TColgp_Array1OfPnt.hxx>
114 #include <TColgp_Array1OfPnt2d.hxx>
115 #include <TColgp_Array1OfXYZ.hxx>
116 #include <TColgp_SequenceOfXY.hxx>
117 #include <TColgp_SequenceOfXYZ.hxx>
118 #include <TColStd_Array1OfBoolean.hxx>
119 #include <TColStd_Array1OfInteger.hxx>
120 #include <TColStd_Array1OfReal.hxx>
121 #include <TColStd_Array2OfInteger.hxx>
122 #include <TColStd_Array2OfReal.hxx>
123 #include <TColStd_HArray1OfInteger.hxx>
124 #include <TColStd_ListOfInteger.hxx>
125 #include <TopAbs_Orientation.hxx>
126 #include <TopExp.hxx>
127 #include <TopExp_Explorer.hxx>
128 #include <TopoDS_Edge.hxx>
129 #include <TopoDS_Face.hxx>
130 #include <TopoDS_Shape.hxx>
131 #include <TopoDS_Vertex.hxx>
132 #include <TopOpeBRepBuild_HBuilder.hxx>
133 #include <TopOpeBRepDS_Curve.hxx>
134 #include <TopOpeBRepDS_CurvePointInterference.hxx>
135 #include <TopOpeBRepDS_DataStructure.hxx>
136 #include <TopOpeBRepDS_HDataStructure.hxx>
137 #include <TopOpeBRepDS_Kind.hxx>
138 #include <TopOpeBRepDS_ListOfInterference.hxx>
139 #include <TopOpeBRepDS_Point.hxx>
140 #include <TopOpeBRepDS_SolidSurfaceInterference.hxx>
141 #include <TopOpeBRepDS_Surface.hxx>
142 #include <TopOpeBRepDS_SurfaceCurveInterference.hxx>
143 #include <TopOpeBRepDS_Transition.hxx>
144 #include <TopTools_Array2OfShape.hxx>
145 #include <TopTools_IndexedMapOfShape.hxx>
146 #include <ChFi3d.hxx>
147
148 // performances 
149 #ifdef OCCT_DEBUG
150 #include <OSD_Chronometer.hxx>
151 extern Standard_Real  t_plate ,t_approxplate,t_batten; 
152 extern void ChFi3d_InitChron(OSD_Chronometer& ch);
153 extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time);
154 #endif
155
156
157 //=======================================================================
158 //function : Indices
159 //purpose  : 
160 //=======================================================================
161
162 static void Indices (     const  Standard_Integer n,
163                    const Standard_Integer ic,
164                    Standard_Integer & icplus,
165                    Standard_Integer & icmoins)
166 {
167   if (ic== (n-1)) icplus=0;
168     else icplus=ic+1;  
169     if (ic==0) icmoins=n-1;
170     else icmoins=ic-1;
171 }
172
173 //=======================================================================
174 //function : Calcul_Param
175 //purpose  : 
176 //=======================================================================
177
178 static void Calcul_Param (const Handle(ChFiDS_Stripe)& stripe,
179                           const Standard_Integer jfposit,
180                           const Standard_Integer indice,
181                           const Standard_Boolean isfirst,
182                           Standard_Real & param)
183 {
184   if (jfposit==2 ) 
185     param=stripe->SetOfSurfData()->Value(indice)->InterferenceOnS2().Parameter(isfirst);   
186   else 
187     param=stripe->SetOfSurfData()->Value(indice)->InterferenceOnS1().Parameter(isfirst);
188 }
189
190 //=======================================================================
191 //function : Calcul_P2dOnSurf
192 //purpose  : 
193 //=======================================================================
194
195 static void Calcul_P2dOnSurf(const Handle(ChFiDS_Stripe)& stripe,
196                              const Standard_Integer jfposit,
197                              const Standard_Integer indice,
198                              const Standard_Real param,
199                              gp_Pnt2d & p2)
200
201 {
202   if (jfposit==1) 
203     stripe->SetOfSurfData()->Value(indice)
204       ->InterferenceOnS1().PCurveOnSurf()->D0(param,p2);   
205   else
206     stripe->SetOfSurfData()->Value(indice)
207       ->InterferenceOnS2().PCurveOnSurf()->D0(param,p2);        
208 }
209
210 //=======================================================================
211 //function : Calcul_C2dOnFace
212 //purpose  : 
213 //=======================================================================
214
215 static void Calcul_C2dOnFace (const Handle(ChFiDS_Stripe)& stripe,
216                               const Standard_Integer jfposit,
217                               const Standard_Integer indice,
218                               Handle(Geom2d_Curve) & c2d)
219
220 {
221   if (jfposit==1) 
222     c2d = stripe->SetOfSurfData()->Value(indice)
223       ->InterferenceOnS1().PCurveOnFace();   
224   else
225     c2d = stripe->SetOfSurfData()->Value(indice)
226       ->InterferenceOnS2().PCurveOnFace();        
227 }
228
229 //=======================================================================
230 //function : Calcul_Orientation
231 //purpose  : 
232 //=======================================================================
233
234 static void Calcul_Orientation(const Handle(ChFiDS_Stripe)& stripe,
235                                const Standard_Integer jfposit,
236                                const Standard_Integer indice,
237                                TopAbs_Orientation & orient)
238 {
239   if (jfposit==1)
240     orient = stripe->SetOfSurfData()->Value(indice)
241       ->InterferenceOnS1().Transition();       
242   else
243     orient = stripe->SetOfSurfData()->Value(indice)
244       ->InterferenceOnS2().Transition();
245 }
246
247 //=======================================================================
248 //function : RemoveSD
249 //purpose  : 
250 //=======================================================================
251
252 static void RemoveSD(Handle(ChFiDS_Stripe)& Stripe,
253                      const Standard_Integer num1,
254                      const Standard_Integer num2     )
255 {
256   ChFiDS_SequenceOfSurfData& Seq = 
257     Stripe->ChangeSetOfSurfData()->ChangeSequence();
258   if(Seq.IsEmpty()) return;
259   if (num1==num2) 
260     Seq.Remove(num1);
261   else
262     Seq.Remove(num1,num2);
263 }
264
265 //=======================================================================
266 //function : cherche_edge1
267 //purpose  : find common edge of faces F1 and F2 
268 //=======================================================================
269
270 static void cherche_edge1 (const TopoDS_Face & F1,
271                            const TopoDS_Face & F2,
272                            TopoDS_Edge & Edge)
273 { Standard_Integer i,j; 
274   TopoDS_Edge Ecur1,Ecur2;
275   Standard_Boolean trouve=Standard_False;
276   TopTools_IndexedMapOfShape  MapE1,MapE2;
277   TopExp::MapShapes( F1,TopAbs_EDGE,MapE1);
278   TopExp::MapShapes( F2,TopAbs_EDGE,MapE2);
279   for ( i=1; i<= MapE1.Extent()&&!trouve; i++)
280   { 
281     TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(i));
282     Ecur1=TopoDS::Edge(aLocalShape);
283     //  Ecur1=TopoDS::Edge(TopoDS_Shape (MapE1(i)));
284     for ( j=1; j<= MapE2.Extent()&&!trouve; j++)
285     { 
286       aLocalShape = TopoDS_Shape (MapE2(j));
287       Ecur2=TopoDS::Edge(aLocalShape);
288       //              Ecur2=TopoDS::Edge(TopoDS_Shape (MapE2(j)));
289       if (Ecur2.IsSame(Ecur1))
290       {Edge=Ecur1;trouve=Standard_True;}
291     }
292   }
293   if (Edge.IsNull()) {
294     throw Standard_ConstructionError ("Failed to find edge");
295   }
296 }
297
298 //=======================================================================
299 //function : CurveHermite
300 //purpose  : calculate a  curve 3d using polynoms of Hermite.
301 //           the edge is a regular edge. Curve 3D is constructed  
302 //           between edges icmoins and icplus. 
303 //=======================================================================
304
305 static void CurveHermite (const TopOpeBRepDS_DataStructure& DStr,
306                           const Handle(ChFiDS_Stripe)&   CDicmoins,
307                           const Standard_Integer jficmoins,
308                           const Standard_Integer icmoins,
309                           const Standard_Real    picmoins,
310                           const Standard_Integer sensicmoins,
311                           const Standard_Boolean sharpicmoins,
312                           const TopoDS_Edge & Eviveicmoins,
313                           const Handle(ChFiDS_Stripe)&   CDicplus,
314                           const Standard_Integer jficplus,
315                           const Standard_Integer icplus,
316                           const Standard_Real    picplus,
317                           const Standard_Integer sensicplus,
318                           const Standard_Boolean sharpicplus,
319                           const TopoDS_Edge & Eviveicplus,
320                           const Standard_Integer nbface,
321                           TopTools_SequenceOfShape & Ecom,
322                           const TopTools_SequenceOfShape & Face,
323                           TColGeom2d_SequenceOfCurve & proj2d,
324                           TColGeom_SequenceOfCurve & cproj,  
325                           TopTools_SequenceOfShape & Eproj,     
326                           TColStd_SequenceOfReal & param,
327                           Standard_Real & error)
328 {  
329   gp_Pnt p01,p02;
330   gp_Vec d11,d12;
331   Standard_Integer ii,jj;
332   Standard_Real up1,up2;
333   Standard_Integer ilin,jfp;
334   Handle (Geom_Curve) c1,c2;
335   if (sharpicmoins) {
336     c1=BRep_Tool::Curve(Eviveicmoins,up1,up2);
337   }
338   else {
339     if (jficmoins==1) 
340       ilin= CDicmoins->SetOfSurfData()->Value( icmoins)->InterferenceOnS1().LineIndex();
341     else ilin= CDicmoins->SetOfSurfData()->Value(icmoins)->InterferenceOnS2().LineIndex();
342     c1=DStr.Curve(ilin).Curve();
343   }
344   if (sharpicplus){
345     c2=BRep_Tool::Curve(Eviveicplus,up1,up2);
346   }
347   else {
348     jfp=3-jficplus;   
349     if (jfp==1) 
350       ilin= CDicplus->SetOfSurfData()->Value( icplus)->InterferenceOnS1().LineIndex();
351     else  ilin=CDicplus->SetOfSurfData()->Value(icplus)->InterferenceOnS2().LineIndex();
352     c2=DStr.Curve(ilin ).Curve();
353   }
354   if (c1.IsNull()) 
355     throw Standard_ConstructionError ("Failed to get 3D curve of edge");
356   if (c2.IsNull()) 
357     throw Standard_ConstructionError ("Failed to get 3D curve of edge");
358   c1->D1(picmoins,p01,d11);
359   c2->D1(picplus,p02,d12);
360   Standard_Integer size = 4;
361   math_Matrix  MatCoefs(1,size, 1,size);
362   TColgp_Array1OfXYZ Cont(1,size);
363   PLib::HermiteCoefficients(0, 1,1,1,MatCoefs);
364   Standard_Real L1=p01.Distance(p02);
365   Standard_Real lambda= ((Standard_Real)1) / Max (d11.Magnitude() / L1, 1.e-6);
366   Cont(1) = p01.XYZ();
367   if (sensicmoins==1) Cont(2) = d11.XYZ()*(-lambda) ;
368   else Cont(2) = d11.XYZ()*(lambda) ;
369   lambda= ((Standard_Real)1) / Max (d12.Magnitude() / L1, 1.e-6);
370   Cont(3) = p02.XYZ();
371   if (sensicplus==1) Cont(4) =  d12.XYZ()*(lambda);
372   else Cont(4) =  d12.XYZ()*(-lambda);
373   TColgp_Array1OfPnt ExtrapPoles(1, size);
374   TColgp_Array1OfPnt ExtraCoeffs(1, size);
375   gp_Pnt p0(0,0,0);
376   ExtraCoeffs.Init(p0);
377   for (ii=1; ii<=size; ii++) {
378     for (jj=1; jj<=size; jj++) {
379       ExtraCoeffs(jj).ChangeCoord() += MatCoefs(ii,jj)*Cont(ii);
380     }
381   }
382   PLib::CoefficientsPoles(ExtraCoeffs,  PLib::NoWeights(),
383                           ExtrapPoles,  PLib::NoWeights());
384   Handle(Geom_BezierCurve) Bezier = new (Geom_BezierCurve) (ExtrapPoles);
385   BRepLib_MakeEdge Bedge (Bezier);
386   TopoDS_Edge edg =Bedge. Edge();
387   TopoDS_Face F;
388   error=1.e-30;
389   Standard_Integer nb;
390   for(nb=1;nb<=nbface;nb++){
391     F=TopoDS::Face(Face.Value(nb));
392     TopTools_IndexedMapOfShape MapE1;
393     TopoDS_Edge E1;
394     Handle(Geom2d_Curve) proj1;
395     Handle(Geom_Curve) proj1c,proj2c;
396     BRepAlgo_NormalProjection OrtProj;
397     OrtProj.Init(F);
398     OrtProj.Add(edg);
399     OrtProj.SetParams(1.e-4, 1.e-4, GeomAbs_C1, 14, 16);
400     OrtProj.Build();
401     if ( OrtProj.IsDone()){
402       TopExp::MapShapes(OrtProj.Projection() , TopAbs_EDGE, MapE1);
403         if (MapE1.Extent()!=0){
404           if (MapE1.Extent()!=1) {
405             BRepLib_MakeFace Bface (BRep_Tool::Surface(F), Precision::Confusion());
406             F=Bface.Face();
407             OrtProj.Init(F);
408             OrtProj.Build();
409             MapE1.Clear();
410             if ( OrtProj.IsDone()) 
411               TopExp::MapShapes(OrtProj.Projection() ,TopAbs_EDGE, MapE1);
412           }
413           if (MapE1.Extent()!=0) { 
414             Standard_Boolean trouve=Standard_False;
415             for (Standard_Integer ind=1;ind<=MapE1.Extent()&&!trouve;ind++){
416               TopoDS_Shape aLocalShape = TopoDS_Shape( MapE1(ind));  
417               E1=TopoDS::Edge( aLocalShape );
418               //           E1=TopoDS::Edge( TopoDS_Shape (MapE1(ind)));
419               if (!BRep_Tool::Degenerated(E1)) trouve=Standard_True;
420             }
421             Eproj.Append(E1);
422             proj1=BRep_Tool::CurveOnSurface(E1,F,up1,up2);
423             if (proj1.IsNull()) 
424               throw Standard_ConstructionError ("Failed to get p-curve of edge");
425             proj2d.Append(new Geom2d_TrimmedCurve(proj1,up1,up2));
426             proj1c=BRep_Tool::Curve(E1,up1,up2);
427             if (proj1c.IsNull()) 
428               throw Standard_ConstructionError ("Failed to get 3D curve of edge");
429             cproj.Append(new Geom_TrimmedCurve(proj1c,up1,up2));
430             if (error>BRep_Tool::Tolerance(E1)) error=BRep_Tool::Tolerance(E1);
431           }
432           else {
433             Eproj.Append(E1);
434             proj2d.Append(proj1);
435             cproj.Append(proj1c);
436           } 
437         }
438         else {
439           Eproj.Append(E1);
440           proj2d.Append(proj1);
441           cproj.Append(proj1c);
442         }
443       }
444   }
445   for (nb=1;nb<=nbface-1;nb++) {
446     BRepAdaptor_Curve C(TopoDS::Edge(Ecom.Value(nb)));
447     C.D0(param.Value(nb),p02);
448     GeomAdaptor_Curve L (Bezier);
449     Extrema_ExtCC ext (C,L);
450     if (ext.IsDone()){ 
451       if (!ext.IsParallel() && ext.NbExt()!=0){ 
452         Extrema_POnCurv POnC, POnL;
453         ext.Points(1, POnC, POnL);
454         if (POnC.Value().Distance(POnL.Value()) < Precision::Confusion())
455           param.ChangeValue(nb) =POnC.Parameter();
456         else
457         {
458           if (!cproj.Value(nb).IsNull()) {
459             cproj.Value(nb)->D0(cproj.Value(nb)->LastParameter(),p01);
460           }
461           else if (!cproj.Value(nb+1).IsNull()) {
462             cproj.Value(nb+1)->D0(cproj.Value(nb+1)->FirstParameter(),p01);
463           }
464         }
465       }
466     }
467     if (!ext.IsDone()||ext.NbExt()==0) {
468       if (!cproj.Value(nb).IsNull()) {
469         cproj.Value(nb)->D0(cproj.Value(nb)->LastParameter(),p01); 
470       }
471       else if (!cproj.Value(nb+1).IsNull()) {
472         cproj.Value(nb+1)->D0(cproj.Value(nb+1)->FirstParameter(),p01);  
473       } 
474       if (p01.Distance(p02)>1.e-4 ){
475         Extrema_ExtPC ext1 (p01,C);
476         if (ext1.IsDone()){ 
477           if (ext1.NbExt()!=0){  
478             Extrema_POnCurv POnC(ext1.Point(1));
479             param.ChangeValue(nb) =POnC.Parameter();
480           }
481         }
482       }
483     }       
484   }
485 }
486
487 //=======================================================================
488 //function : CalculDroite
489 //purpose  : calculate a 2D straight line passing through point p2d1 and direction xdir ydir 
490 //=======================================================================
491
492 static void CalculDroite(const gp_Pnt2d & p2d1,
493                          const Standard_Real  xdir,
494                          const Standard_Real  ydir,
495                          Handle (Geom2d_Curve) & pcurve) 
496 { gp_Dir2d dir1 (xdir, ydir);
497   Handle(Geom2d_Line) l= new Geom2d_Line (p2d1,dir1);
498   Standard_Real l0 = sqrt(xdir*xdir+ ydir*ydir );
499   pcurve = new Geom2d_TrimmedCurve(l,0,l0);
500 }
501
502 //=======================================================================
503 //function : CalculBatten
504 //purpose  : calcule a batten between curves 2d  curv2d1 and curv2d2 at points p2d1 and p2d2  
505 //=======================================================================
506
507 static void CalculBatten (const Handle (GeomAdaptor_Surface) ASurf, 
508                           const TopoDS_Face Face ,
509                           const Standard_Real xdir,
510                           const Standard_Real  ydir,
511                           const gp_Pnt2d & p2d1,
512                           const gp_Pnt2d & p2d2,
513                           const Standard_Boolean contraint1,
514                           const Standard_Boolean contraint2,
515                           Handle (Geom2d_Curve) & curv2d1,
516                           Handle (Geom2d_Curve) & curv2d2,
517                           const Standard_Real  picicplus,
518                           const Standard_Real   picplusic,
519                           const Standard_Boolean inverseic,
520                           const Standard_Boolean inverseicplus,
521                           Handle (Geom2d_Curve)& pcurve)
522 {  
523   Standard_Boolean isplane;
524   Standard_Boolean anglebig = Standard_False;
525   isplane=ASurf->GetType()==GeomAbs_Plane;
526   gp_Dir2d dir1 (xdir, ydir);
527   Geom2dLProp_CLProps2d CL1(curv2d1, picicplus, 1, 1.e-4);
528   Geom2dLProp_CLProps2d CL2( curv2d2, picplusic, 1, 1.e-4);
529   gp_Dir2d dir3,dir4 ;
530   CL1.Tangent(dir3);
531   CL2.Tangent(dir4);
532   if (inverseic)  dir3.Reverse();
533   if (inverseicplus)  dir4.Reverse();
534   Standard_Real h =  p2d2.Distance(p2d1)/20;
535   FairCurve_Batten Bat(p2d1,p2d2,h);
536   Bat.SetFreeSliding (Standard_True);
537   Standard_Real ang1,ang2;
538   ang1=dir1.Angle(dir3);
539   if (dir1.Angle(dir4) >0 ) ang2=M_PI-dir1.Angle(dir4);
540   else ang2=-M_PI-dir1.Angle(dir4);
541   if (contraint1&&contraint2) 
542   anglebig=(Abs(ang1)>1.2)|| (Abs(ang2)>1.2 );
543   else if (contraint1) 
544   anglebig=Abs(ang1)>1.2;
545   else if (contraint2)
546   anglebig=Abs(ang2)>1.2; 
547   if (isplane && (Abs(ang1)>M_PI/2 || Abs(ang2)>M_PI/2))
548   isplane=Standard_False;
549   if (anglebig && !isplane) {
550     CalculDroite(p2d1,xdir,ydir,pcurve);
551   }
552   else {
553     if (contraint1) Bat.SetAngle1(ang1);
554     else  Bat.SetConstraintOrder1(0);
555     if (contraint2) Bat.SetAngle2(ang2);
556     else Bat.SetConstraintOrder2(0);
557     FairCurve_AnalysisCode Iana; 
558     Standard_Boolean Ok;
559     Ok = Bat.Compute(Iana,25,1.e-2);
560 #ifdef OCCT_DEBUG
561     if (!Ok) { 
562       std::cout<<"no batten :";
563       Bat.Dump(std::cout);
564     }    
565 #endif  
566     if (Ok) {
567        pcurve = Bat.Curve();
568        Standard_Real umin,vmin,umax,vmax;
569        BRepTools::UVBounds(Face,umin,umax,vmin,vmax);
570        Bnd_Box2d bf,bc;
571        Geom2dAdaptor_Curve acur(pcurve);
572        BndLib_Add2dCurve::Add(acur,0,bc);
573        bf.Update(umin,vmin,umax,vmax);
574        Standard_Real uminc,vminc,umaxc,vmaxc;
575        bc.Get(uminc,vminc,umaxc,vmaxc);
576        if (uminc<umin-1.e-7) Ok=Standard_False;
577        if (umaxc>umax+1.e-7) Ok=Standard_False;
578        if (vminc<vmin-1.e-7) Ok=Standard_False;
579        if (vmaxc>vmax+1.e-7) Ok=Standard_False;       
580     } 
581     if (!Ok) CalculDroite(p2d1, xdir,ydir, pcurve);    
582   }
583 }
584
585 //=======================================================================
586 //function : OrientationIcNonVive
587 //purpose  : calculate the orientation of the curve between ic and icplus knowing that ic 
588 //           is not a living edge.
589 //=======================================================================
590
591 static void OrientationIcNonVive (const Handle(ChFiDS_Stripe) & CDic,
592                                   const Standard_Integer jfic,
593                                   const Standard_Integer icicplus,
594                                   const Standard_Integer  sensic,
595                                   TopAbs_Orientation  & orien )
596 {
597   TopAbs_Orientation orinterf; 
598   Calcul_Orientation(CDic,jfic,icicplus,orinterf);
599   if (sensic!=1){
600     if (orinterf==TopAbs_FORWARD) orien=TopAbs_FORWARD;
601     else orien=TopAbs_REVERSED;                 
602   }
603   else {
604     if (orinterf==TopAbs_FORWARD) orien=TopAbs_REVERSED;
605     else orien=TopAbs_FORWARD;
606   }             
607 }
608
609 //=======================================================================
610 //function : OrientationIcplusNonVive
611 //purpose  : calculate the orientation of the curve between ic and icplus knowing that icplus
612 //           is not a living edge;
613 //=======================================================================
614
615 static void OrientationIcplusNonVive (const Handle(ChFiDS_Stripe) & CDicplus,
616                                       const Standard_Integer jficplus,
617                                       const Standard_Integer icplusic,
618                                       const Standard_Integer sensicplus,
619                                       TopAbs_Orientation & orien )
620 {
621   TopAbs_Orientation orinterf; 
622   Standard_Integer  jfp = 3 -jficplus;
623   Calcul_Orientation(CDicplus,jfp,icplusic,orinterf);
624   if (sensicplus==1){
625     if (orinterf==TopAbs_FORWARD) orien=TopAbs_FORWARD;
626     else orien=TopAbs_REVERSED;                 
627   }
628   else {
629     if (orinterf==TopAbs_FORWARD) orien=TopAbs_REVERSED;
630     else orien=TopAbs_FORWARD;
631   }             
632 }
633
634 //=======================================================================
635 //function : OrientationAreteViveConsecutive
636 //purpose  : calculate the orientation of the curve between edges ic and icplus 
637 //           where ic and icplus are consecutively living 
638 //=======================================================================
639
640 static void OrientationAreteViveConsecutive (const TopoDS_Shape & Fviveicicplus,
641                                              const TopoDS_Shape & Eviveic,
642                                              const TopoDS_Vertex & V1,
643                                              TopAbs_Orientation & orien)
644
645 { // orinterf is orientation of edge ic corresponding to face Fviveicicplus taken FORWARD
646   TopAbs_Orientation orinterf = TopAbs_FORWARD;
647   TopoDS_Face F=TopoDS::Face( Fviveicicplus);
648   TopoDS_Edge E=TopoDS::Edge( Eviveic);  
649   TopExp_Explorer ex;
650   for(ex.Init(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);ex.More(); ex.Next()){
651     if(E.IsSame(ex.Current())) {
652       orinterf = ex.Current().Orientation();
653       break;
654     }
655   }
656   // if V1 is vertex REVERSED of edge ic the curve  
657   // has the same orientation as ic 
658   TopoDS_Vertex vl;
659   vl=TopExp::LastVertex(E);
660   if (vl.IsSame(V1)){ 
661     if (orinterf==TopAbs_FORWARD) orien=TopAbs_FORWARD;
662     else orien=TopAbs_REVERSED;
663   }
664   else {
665     if (orinterf==TopAbs_FORWARD) orien=TopAbs_REVERSED;
666     else orien=TopAbs_FORWARD;
667   }
668 }
669
670 //=======================================================================
671 //function : PerformTwoCornerSameExt
672 //purpose  : calculate intersection between two stripes stripe1 and stripe2 
673 //=======================================================================
674
675 static void PerformTwoCornerSameExt(TopOpeBRepDS_DataStructure& DStr,
676                                     const Handle(ChFiDS_Stripe)& stripe1,
677                                     const Standard_Integer index1,
678                                     const Standard_Integer sens1,
679                                     const Handle(ChFiDS_Stripe) &stripe2,
680                                     const Standard_Integer index2,
681                                     const Standard_Integer sens2,
682                                     Standard_Boolean & trouve)
683                      
684 { Handle (TopOpeBRepDS_CurvePointInterference) Interfp1, Interfp2;
685   Handle (TopOpeBRepDS_SurfaceCurveInterference) Interfc;
686   TopAbs_Orientation orpcurve,trafil1,orsurf1,orsurf2;
687   Standard_Boolean isfirst;
688   Standard_Integer indic1,indic2, indpoint1,indpoint2,ind,indcurve;
689   Standard_Real tol;
690   gp_Pnt P1,P2,P3,P4;
691   gp_Pnt2d p2d;
692   Handle(Geom_Curve)cint;
693   Handle(Geom2d_Curve) C2dint1,C2dint2;
694   isfirst=sens1==1;
695   ChFiDS_CommonPoint& Com11= stripe1->SetOfSurfData()->Value(index1)->ChangeVertex (isfirst,1);
696   ChFiDS_CommonPoint& Com12= stripe1->SetOfSurfData()->Value(index1)->ChangeVertex (isfirst,2);
697   isfirst=sens2==1;
698   ChFiDS_CommonPoint& Com21= stripe2->SetOfSurfData()->Value(index2)->ChangeVertex (isfirst,1);
699 #ifdef OCCT_DEBUG
700 //  ChFiDS_CommonPoint& Com22= 
701 //    stripe2->SetOfSurfData()->Value(index2)->ChangeVertex (isfirst,2);
702 #endif
703   indic1=stripe1->SetOfSurfData()->Value(index1)->Surf();
704   indic2=stripe2->SetOfSurfData()->Value(index2)->Surf();
705   const Handle(ChFiDS_SurfData) Fd1=stripe1->SetOfSurfData()->Value(index1);
706   const Handle(ChFiDS_SurfData) Fd2=stripe2->SetOfSurfData()->Value(index2);
707
708   TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4);
709   const ChFiDS_FaceInterference& Fi11 = Fd1->InterferenceOnS1();
710   const ChFiDS_FaceInterference& Fi12 = Fd1->InterferenceOnS2();
711   const ChFiDS_FaceInterference& Fi21 = Fd2->InterferenceOnS1();
712   const ChFiDS_FaceInterference& Fi22 = Fd2->InterferenceOnS2();
713   gp_Pnt2d pfi11,pfi12,pfi21,pfi22;
714   isfirst=sens1==1;
715   pfi11 = Fi11.PCurveOnSurf()->Value(Fi11.Parameter(isfirst));
716   pfi12 = Fi12.PCurveOnSurf()->Value(Fi12.Parameter(isfirst));
717   isfirst=sens2==1;
718   if (Com11.Point().Distance(Com21.Point()) <1.e-4) { 
719     pfi21 = Fi21.PCurveOnSurf()->Value(Fi21.Parameter(isfirst)); 
720     pfi22 = Fi22.PCurveOnSurf()->Value(Fi22.Parameter(isfirst));
721   }
722   else {
723     pfi22 = Fi21.PCurveOnSurf()->Value(Fi21.Parameter(isfirst));        
724     pfi21 = Fi22.PCurveOnSurf()->Value(Fi22.Parameter(isfirst));
725   }
726   
727   Pardeb(1)= pfi11.X();Pardeb(2) = pfi11.Y();
728   Pardeb(3)= pfi21.X();Pardeb(4) = pfi21.Y();
729   Parfin(1)= pfi12.X();Parfin(2) = pfi12.Y();
730   Parfin(3)= pfi22.X();Parfin(4) = pfi22.Y();
731
732   Handle(GeomAdaptor_Surface) HS1= ChFi3d_BoundSurf(DStr,Fd1,1,2);
733   Handle(GeomAdaptor_Surface) HS2= ChFi3d_BoundSurf(DStr,Fd2,1,2);
734   trouve=Standard_False;
735   if (ChFi3d_ComputeCurves(HS1,HS2,Pardeb,Parfin,cint,
736                            C2dint1,C2dint2,1.e-4,1.e-5,tol)){
737     cint->D0(cint->FirstParameter(),P1);
738     cint->D0(cint->LastParameter(),P2);
739     trouve=((Com11.Point().Distance(P1) <1.e-4 || Com11.Point().Distance(P2)<1.e-4)&&
740             (Com12.Point().Distance(P1) <1.e-4 || Com12.Point().Distance(P2)<1.e-4));
741   }
742
743   if (trouve) {
744     isfirst=sens1==1;
745     stripe1->InDS(isfirst);
746     indpoint1=ChFi3d_IndexPointInDS(Com11,DStr);
747     indpoint2=ChFi3d_IndexPointInDS(Com12,DStr);
748     stripe1->SetIndexPoint(indpoint1,isfirst,1);
749     stripe1->SetIndexPoint(indpoint2,isfirst,2);
750     isfirst=sens2==1;
751     stripe2->InDS(isfirst); 
752     if (Com11.Point().Distance(Com21.Point()) <1.e-4) {
753       stripe2->SetIndexPoint(indpoint1,isfirst,1);
754       stripe2->SetIndexPoint(indpoint2,isfirst,2);
755     }
756     else {
757       stripe2->SetIndexPoint(indpoint2,isfirst,1);
758       stripe2->SetIndexPoint(indpoint1,isfirst,2);
759     }
760     
761     orsurf1=Fd1->Orientation();
762     trafil1 = DStr.Shape(Fd1->IndexOfS1()).Orientation();
763     trafil1 = TopAbs::Compose(trafil1,Fd1->Orientation());
764     trafil1 = TopAbs::Compose(TopAbs::Reverse(Fi11.Transition()),trafil1);
765     orsurf2=Fd2->Orientation();
766     TopOpeBRepDS_Curve tcurv3d(cint,tol);
767     indcurve= DStr.AddCurve(tcurv3d);
768     cint->D0(cint->FirstParameter(),P1);
769     cint->D0(cint->LastParameter(),P2);
770     Fi11.PCurveOnFace()->D0(Fi11.LastParameter(),p2d);
771     const Handle(Geom_Surface) Stemp = 
772       BRep_Tool::Surface(TopoDS::Face(DStr.Shape(Fd1->IndexOfS1())));
773     Stemp ->D0(p2d.X(),p2d.Y(),P4);
774     Fi11.PCurveOnFace()->D0(Fi11.FirstParameter(),p2d);
775     Stemp ->D0(p2d.X(),p2d.Y(),P3);
776     if (P1.Distance(P4)<1.e-4  || P2.Distance(P3)<1.e-4)
777       orpcurve=trafil1;
778     else  orpcurve=TopAbs::Reverse(trafil1);
779     if (Com11.Point().Distance(P1) >1.e-4) {
780       ind=indpoint1;
781       indpoint1=indpoint2;
782       indpoint2=ind;
783     }    
784     Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurve, indpoint1, cint->FirstParameter());
785     Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurve,indpoint2, cint->LastParameter());
786     DStr.ChangeCurveInterferences(indcurve).Append(Interfp1);
787     DStr.ChangeCurveInterferences(indcurve).Append(Interfp2);
788     Interfc=ChFi3d_FilCurveInDS(indcurve,indic1,C2dint1,orpcurve);
789     DStr.ChangeSurfaceInterferences(indic1).Append(Interfc);
790     if (orsurf1==orsurf2) orpcurve=TopAbs::Reverse(orpcurve);
791     Interfc=ChFi3d_FilCurveInDS(indcurve,indic2,C2dint2,orpcurve);
792     DStr.ChangeSurfaceInterferences(indic2).Append(Interfc);
793   }   
794 }
795
796 //=======================================================================
797 //function : CpOnEdge
798 //purpose  : determine if surfdata num has a common point on Eadj1 or Eadj2
799 //=======================================================================
800
801 static void  CpOnEdge (const  Handle(ChFiDS_Stripe) & stripe,
802                        Standard_Integer num,
803                        Standard_Boolean isfirst,
804                        const TopoDS_Edge & Eadj1,
805                        const TopoDS_Edge & Eadj2,
806                        Standard_Boolean & compoint)
807
808 { ChFiDS_CommonPoint cp1,cp2;
809   compoint=Standard_False;  
810   cp1 = stripe->SetOfSurfData()->Value(num)->ChangeVertex (isfirst,1);
811   cp2 = stripe->SetOfSurfData()->Value(num)->ChangeVertex (isfirst,2);
812   if(cp1.IsOnArc()){
813     if (cp1.Arc().IsSame(Eadj1)||cp1.Arc().IsSame(Eadj2))
814       compoint=Standard_True;
815   } 
816   if(cp2.IsOnArc()){
817     if (cp2.Arc().IsSame(Eadj1)||cp2.Arc().IsSame(Eadj2))
818       compoint=Standard_True; 
819   } 
820 }
821
822 //=======================================================================
823 //function : RemoveSurfData
824 //purpose  : for each stripe removal of unused surfdatas 
825 //=======================================================================
826
827 static void RemoveSurfData (const ChFiDS_StripeMap & myVDataMap,
828                             const ChFiDS_Map & myEFMap,
829                             const TopoDS_Edge &edgecouture,
830                             const TopoDS_Face & facecouture,
831                             const TopoDS_Vertex &V1)
832 { ChFiDS_ListIteratorOfListOfStripe It;
833   Standard_Boolean isfirst;
834   TopoDS_Edge Ecur,Eadj1,Eadj2;
835   TopoDS_Face Fg,Fd,F1,F2;
836   TopoDS_Vertex Vbid;
837   Standard_Integer nbsurf,nbedge,sense,num;
838   for (It.Initialize(myVDataMap(V1));It.More();It.Next()) {
839     nbsurf= It.Value()->SetOfSurfData()->Length();
840     nbedge = It.Value()->Spine()->NbEdges();
841     if  (nbsurf!=1){
842       num=ChFi3d_IndexOfSurfData(V1,It.Value(),sense);
843       if (sense==1) 
844         Ecur = It.Value()->Spine()->Edges(1);
845       else  
846         Ecur = It.Value()->Spine()->Edges(nbedge);
847       ChFi3d_edge_common_faces(myEFMap(Ecur),F1,F2);
848       if (F1.IsSame(facecouture)) Eadj1=edgecouture; 
849       else ChFi3d_cherche_element(V1,Ecur,F1,Eadj1,Vbid);
850       ChFi3d_edge_common_faces(myEFMap(Eadj1),Fg,Fd);
851       if (F2.IsSame(facecouture)) Eadj2=edgecouture;
852       else ChFi3d_cherche_element(V1,Ecur,F2,Eadj2,Vbid);
853       ChFi3d_edge_common_faces(myEFMap(Eadj2),Fg,Fd); 
854       Standard_Boolean compoint=Standard_False;
855       isfirst=(sense==1); 
856       Standard_Integer ind;
857       if (sense==1) {
858         ind=0;
859         // among surfdatas find the greatest indice ind so that 
860         // surfdata could have one of commonpoint on Eadj1 and Eadj2
861         // remove surfdata from 1 to ind-1   
862         for (Standard_Integer i=1;i<=nbsurf;i++) {
863           CpOnEdge (It.Value(),i,isfirst,Eadj1,Eadj2,compoint);
864           if (compoint) ind=i;
865         }
866         if (ind>=2) RemoveSD(It.Value(),1,ind-1);
867       }
868       else {
869         ind=num;
870         // among surfdatas find the smallest indice ind so that 
871         // surfdata could have one of commonpoint on Eadj1 and Eadj2
872         // remove surfdata from ind+1 to num   
873         for (Standard_Integer i=num;i>=1;i--) {
874           CpOnEdge (It.Value(),i,isfirst,Eadj1,Eadj2,compoint);
875           if (compoint) ind=i;
876         }
877         if (ind<num) RemoveSD(It.Value(),ind+1,num);
878       }
879     }
880   }
881 }
882
883 //=======================================================================
884 //function : ParametrePlate
885 //purpose  : 
886 //=======================================================================
887
888 static void ParametrePlate(const Standard_Integer n3d,
889                            const GeomPlate_BuildPlateSurface & PSurf,
890                            const Handle(Geom_Surface) & Surf,
891                            const gp_Pnt & point,
892                            const Standard_Real apperror,
893                            gp_Pnt2d & uv)
894 {  Standard_Integer ip;
895    gp_Pnt P1;
896    Standard_Real par;
897    Standard_Boolean trouve=Standard_False;
898    for (ip=1;ip<=n3d && !trouve;ip++){
899      par=PSurf.Curves2d()->Value(ip)->FirstParameter();
900      PSurf.Curves2d()->Value(ip)->D0(par,uv);
901      Surf->D0(uv.X(),uv.Y(),P1);       
902      trouve=P1.IsEqual(point,apperror);
903      if (!trouve) {
904         par=PSurf.Curves2d()->Value(ip)->LastParameter();
905         PSurf.Curves2d()->Value(ip)->D0(par,uv);
906         Surf->D0(uv.X(),uv.Y(),P1);       
907         trouve=P1.IsEqual(point,apperror); 
908      } 
909   }
910 }
911
912 //=======================================================================
913 //function : SummarizeNormal
914 //purpose  : 
915 //=======================================================================
916
917 static void SummarizeNormal(const TopoDS_Vertex& V1,
918                             const TopoDS_Face& Fcur,
919                             const TopoDS_Edge& Ecur,
920                             gp_Vec& SumFaceNormalAtV1)
921 {
922   gp_Pnt2d uv1, uv2;
923   BRep_Tool::UVPoints(Ecur,Fcur,uv1,uv2);
924   if ( ! V1.IsSame(TopExp::FirstVertex(Ecur))) uv1 = uv2;
925   
926   gp_Pnt P;
927   gp_Vec d1U, d1V;
928   BRep_Tool::Surface(Fcur)->D1( uv1.X(), uv1.Y(), P, d1U, d1V);
929   gp_Vec N = d1U.Crossed(d1V);
930   if (Fcur.Orientation() == TopAbs_REVERSED) N.Reverse();
931   
932   if (N.SquareMagnitude() <= Precision::PConfusion()) return;
933   
934   SumFaceNormalAtV1 += N.Normalized();
935   SumFaceNormalAtV1.Normalize();
936 }
937
938 enum ChFi3d_SurfType { ChFiSURFACE, FACE1, FACE2 }; // for call SurfIndex(...)
939
940 //=======================================================================
941 //function : SurfIndex
942 //purpose  : 
943 //=======================================================================
944
945 static Standard_Integer SurfIndex(const ChFiDS_StripeArray1& StripeArray1,
946                                   const Standard_Integer     StripeIndex,
947                                   const Standard_Integer     SurfDataIndex,
948                                   const ChFi3d_SurfType      SurfType)
949 {
950   const Handle(ChFiDS_SurfData)& aSurfData =
951     StripeArray1(StripeIndex)->SetOfSurfData()->Value(SurfDataIndex);
952   switch (SurfType) {
953   case ChFiSURFACE: return aSurfData->Surf();
954   case FACE1:       return aSurfData->IndexOfS1();
955   case FACE2:       return aSurfData->IndexOfS2();
956   default:          return -1;
957   }
958 }
959
960 //=======================================================================
961 //function : PlateOrientation
962 //purpose  : Define Plate orientation compared to <theRefDir> previewing
963 //           that Plate surface can have a sharp angle with adjacent 
964 //           filet (bug occ266: 2 chamfs, OnSame and OnDiff) and
965 //           can be even twisted (grid tests cfi900 B1)
966 //=======================================================================
967
968 static TopAbs_Orientation PlateOrientation(const Handle(Geom_Surface)& thePlateSurf,
969                                            const Handle(TColGeom2d_HArray1OfCurve)& thePCArr,
970                                            const gp_Vec& theRefDir)
971 {
972   gp_Vec du,dv;
973   gp_Pnt pp1,pp2,pp3;
974   gp_Pnt2d uv;
975   Standard_Real fpar, lpar;
976   Standard_Real SumScal1 = 0, SumScal2 = 0;
977   
978   Standard_Integer i, nb = thePCArr->Upper();
979   Handle(Geom2d_Curve) aPC = thePCArr->Value(nb);
980   fpar = aPC->FirstParameter();
981   lpar = aPC->LastParameter();
982   aPC->D0( (fpar + lpar) / 2., uv);
983   thePlateSurf-> D0(uv.X(),uv.Y(),pp1);
984   aPC->D0( lpar ,uv);
985   thePlateSurf-> D0(uv.X(),uv.Y(),pp2);
986   
987   for (i=1; i<=nb; i++) {
988     aPC = thePCArr->Value(i);
989     fpar = aPC->FirstParameter();
990     lpar = aPC->LastParameter();
991     aPC->D0( fpar ,uv);
992     thePlateSurf -> D1(uv.X(),uv.Y(),pp2,du,dv);
993     gp_Vec n1 = du^dv;
994     n1.Normalize();
995     
996     aPC->D0( (fpar + lpar) / 2., uv);
997     thePlateSurf-> D0(uv.X(),uv.Y(),pp3);
998     
999     gp_Vec vv1(pp2,pp1), vv2(pp2,pp3);
1000     gp_Vec n2 = vv2^vv1;
1001     n2.Normalize();
1002     
1003     SumScal1 += n1*n2;
1004     SumScal2 += n2*theRefDir;
1005
1006     pp1 = pp3;
1007   }
1008   if (SumScal2*SumScal1>0) return TopAbs_FORWARD;
1009   else                     return TopAbs_REVERSED;
1010 }
1011                                           
1012 //=======================================================================
1013 //function : PerformMoreThreeCorner
1014 //purpose  : Process case of a top with n edges.      
1015 //=======================================================================
1016
1017 void  ChFi3d_Builder::PerformMoreThreeCorner(const Standard_Integer Jndex,
1018                                              const Standard_Integer nconges)
1019
1020 //    ========================================
1021 //             Initialisations
1022 //     ========================================
1023 #ifdef OCCT_DEBUG
1024   OSD_Chronometer ch;
1025 #endif 
1026   TopOpeBRepDS_DataStructure& DStr=myDS->ChangeDS();  
1027   const TopoDS_Vertex& V1 = myVDataMap.FindKey(Jndex);
1028   Standard_Integer nedge;
1029   Standard_Boolean bordlibre;
1030   TopoDS_Edge edgelibre1,edgelibre2;
1031 //  TopTools_ListIteratorOfListOfShape ItE;
1032   nedge=ChFi3d_NbNotDegeneratedEdges(V1,myVEMap);
1033   ChFi3d_ChercheBordsLibres(myVEMap,V1,bordlibre,edgelibre1,edgelibre2);
1034   Standard_Boolean droit=Standard_False;
1035   if (bordlibre) {nedge=(nedge-2)/2 +2;
1036      Standard_Real angedg=Abs(ChFi3d_AngleEdge(V1,edgelibre1,edgelibre2));
1037      droit=Abs(angedg-M_PI)<0.01;   
1038   }
1039   else  nedge=nedge/2;
1040   Standard_Integer size=nedge*2;
1041   ChFiDS_StripeArray1 CD(0,size);
1042   TColStd_Array1OfInteger jf(0,size);
1043   TColStd_Array1OfInteger Index(0,size);
1044   TColStd_Array1OfInteger Indice(0,size);
1045   TColStd_Array1OfInteger sens(0,size);
1046   TColStd_Array1OfInteger indcurve3d(0,size);
1047   TColStd_Array2OfInteger numfa( 0,size,0,size);
1048   TColStd_Array1OfInteger Order( 0,size);
1049   TColStd_Array2OfInteger i(0,size,0,size);
1050   TColStd_Array2OfInteger indpoint(0,size,0,1);
1051   TColStd_Array1OfBoolean  oksea(0,size);
1052   TColStd_Array1OfBoolean  sharp(0,size);
1053   TColStd_Array1OfBoolean regul(0,size);
1054   TColStd_Array2OfReal p (0,size,0,size);
1055   TColStd_Array1OfReal errapp (0,size);
1056   TopTools_Array1OfShape Evive(0,size);
1057   TopTools_Array2OfShape Fvive(0,size,0,size);
1058   TColStd_Array1OfBoolean ponctuel (0,size);
1059   TColStd_Array1OfBoolean samedge (0,size);
1060   TColStd_Array1OfBoolean moresurf (0,size);
1061   TColStd_Array1OfBoolean libre(0,size);
1062   TColStd_Array1OfBoolean tangentregul (0,size);
1063   TColStd_Array1OfBoolean isG1(0,size);
1064 //  for(Standard_Integer ind=0;ind<=size;ind++){
1065   Standard_Integer ind;
1066   for(ind=0;ind<=size;ind++){
1067    indpoint.SetValue(ind,0,0);
1068     indpoint.SetValue(ind,1,0);
1069     Indice.SetValue(ind,0);
1070     oksea.SetValue(ind,Standard_False);
1071     sharp.SetValue(ind,Standard_False);
1072     regul.SetValue(ind,Standard_False);
1073     ponctuel.SetValue(ind,Standard_False);
1074     samedge.SetValue(ind,Standard_False);
1075     moresurf.SetValue(ind,Standard_False);
1076     libre.SetValue(ind,Standard_False);
1077     tangentregul.SetValue(ind,Standard_False);
1078     isG1.SetValue(ind,Standard_False);
1079   }
1080   ChFiDS_ListIteratorOfListOfStripe It;
1081   Handle(ChFiDS_Stripe) cd2,cdbid,cnext;
1082   TopoDS_Face face;
1083   Standard_Integer jfp = 0,ii;
1084   Standard_Integer ic,icplus,icmoins,icplus2,
1085                    sense,index = 0,indice,isurf1,isurf2;
1086   Standard_Integer cbplus=0, n3d=0,IVtx = 0,nb;
1087   Standard_Boolean sameside,trouve,isfirst;
1088   Standard_Real pardeb ,parfin,xdir,ydir;
1089   Standard_Real tolapp=1.e-4,maxapp = 0.,maxapp1 = 0.,avedev;
1090   Handle (TopOpeBRepDS_CurvePointInterference) Interfp1, Interfp2;
1091   Handle (TopOpeBRepDS_SurfaceCurveInterference) Interfc;
1092   Handle(Geom_Curve) Curv3d;
1093   ChFiDS_Regul regular;
1094   TopTools_SequenceOfShape Fproj;
1095   Standard_Integer num;
1096   TopoDS_Edge Ecur; 
1097   TopTools_ListIteratorOfListOfShape ItF;
1098 #ifdef OCCT_DEBUG
1099 //  Standard_Integer nface=ChFi3d_nbface(myVFMap(V1));
1100 #endif
1101   TopoDS_Face F1,F2;
1102   gp_Vec SumFaceNormalAtV1(0,0,0); // is used to define Plate orientation 
1103
1104   // it is determined if there is a sewing edge
1105   Standard_Boolean couture=Standard_False;
1106   TopoDS_Face facecouture;
1107   TopoDS_Edge edgecouture;
1108   for(ItF.Initialize(myVFMap(V1));ItF.More()&&!couture;ItF.Next()) {
1109     TopoDS_Face fcur = TopoDS::Face(ItF.Value());
1110     ChFi3d_CoutureOnVertex(fcur,V1,couture,edgecouture);
1111     if (couture)
1112       facecouture=fcur;
1113   }
1114
1115 // unused surfdata are removed 
1116   RemoveSurfData (myVDataMap, myEFMap,edgecouture,facecouture,V1);
1117
1118  // parse edges and faces
1119   trouve=Standard_False;
1120   TopoDS_Edge Enext;
1121   TopoDS_Vertex VV;
1122   TopoDS_Face Fcur,Fnext;
1123   for (It.Initialize(myVDataMap(Jndex));It.More()&&!trouve;It.Next()) {
1124     cnext=It.Value();
1125     CD.SetValue(0,cnext);
1126     Index.SetValue(0,ChFi3d_IndexOfSurfData(V1,cnext,sense));
1127     sens.SetValue(0,sense);
1128     numfa.SetValue(0 ,1,SurfIndex(CD, 0, Index.Value(0), FACE2));
1129     numfa.SetValue(1 ,0, numfa.Value(0 ,1));
1130     Fcur=TopoDS::Face(DStr.Shape(numfa.Value(0,1)));
1131     Fvive.SetValue(0,1,Fcur);
1132     Fvive.SetValue(1,0,Fcur);
1133     jf.SetValue(0,2);
1134     if (sens.Value(0)==1) 
1135       Ecur = CD.Value(0)->Spine()->Edges(1);
1136     else  
1137       Ecur = CD.Value(0)->Spine()->Edges(CD.Value(0)->Spine()->NbEdges());
1138     Evive.SetValue(0,Ecur);
1139     ChFi3d_cherche_edge(V1,Evive,Fcur,Enext,VV);
1140     trouve= !Enext.IsNull();
1141   }
1142   // find sum of all face normals at V1
1143   SummarizeNormal(V1, Fcur, Ecur, SumFaceNormalAtV1);
1144   
1145   Standard_Integer nbcouture=0;
1146   for ( ii=1; ii<nedge; ii++) {
1147     if (Fcur.IsSame(facecouture)&& nbcouture==0) {
1148       Enext=edgecouture;
1149       nbcouture++;
1150     }
1151     else ChFi3d_cherche_edge(V1,Evive,Fcur,Enext,VV);
1152     if (Enext.IsNull())
1153       throw Standard_ConstructionError ("PerformMoreThreeCorner: pb in the parsing of edges and faces");
1154     if (Enext.IsSame(edgelibre1)|| Enext.IsSame(edgelibre2)) {
1155       CD.SetValue(ii, cdbid);
1156       Index.SetValue(ii, 0);
1157       sens.SetValue(ii, -1);
1158       TopoDS_Vertex Vref;
1159       Vref = TopExp::FirstVertex(Enext);
1160       if (Vref.IsSame(V1)) sens.SetValue(ii, 1);   
1161       sharp.SetValue(ii, Standard_True);
1162       Evive.SetValue(ii, Enext);
1163       jf.SetValue(ii, 0);
1164       Indices(nedge,ii,icplus,icmoins);
1165       Fvive.SetValue(ii,icplus, Fcur);
1166       Fvive.SetValue(icplus,ii, Fcur);
1167       numfa.SetValue(ii,icplus, DStr.AddShape(Fcur));
1168       numfa.SetValue(icplus,ii,numfa.Value(ii,icplus));
1169       ii++;
1170       if (Enext.IsSame (edgelibre1)) Ecur=edgelibre2;
1171       else Ecur=edgelibre1;
1172       ChFi3d_edge_common_faces(myEFMap(Ecur),Fcur,Fcur);
1173       Indices(nedge,ii,icplus,icmoins);
1174       Fvive.SetValue(ii,icplus, Fcur);
1175       Fvive.SetValue(icplus,ii, Fcur);
1176       numfa.SetValue(ii,icplus, DStr.AddShape(Fcur));
1177       numfa.SetValue(icplus,ii,numfa.Value(ii,icplus));
1178       CD.SetValue(ii, cdbid);
1179       Index.SetValue(ii, 0);
1180       sens.SetValue(ii, -1);
1181       Vref = TopExp::FirstVertex(Ecur);
1182       if (Vref.IsSame(V1)) sens.SetValue(ii, 1);   
1183       sharp.SetValue(ii, Standard_True);
1184       Evive.SetValue(ii, Ecur);
1185       jf.SetValue(ii, 0); 
1186     }
1187     else {
1188 // it is found if Enext is in the map of stripes 
1189       TopoDS_Edge EE;
1190       /*Standard_Boolean */trouve = Standard_False;
1191       for (It.Initialize(myVDataMap(Jndex));It.More()&&!trouve;It.Next()) {
1192         index = ChFi3d_IndexOfSurfData(V1,It.Value(),sense);
1193         if (sense==1) 
1194           EE = It.Value()->Spine()->Edges(1);
1195         else  
1196           EE = It.Value()->Spine()->Edges(It.Value()->Spine()->NbEdges());
1197         if (Enext.IsSame(EE)) {
1198           cnext=It.Value();
1199           trouve=Standard_True;
1200         }
1201       }
1202       if (trouve) {
1203         CD.SetValue(ii, cnext);
1204         Index.SetValue(ii, index);
1205         sens.SetValue(ii, sense);
1206         sharp.SetValue(ii, Standard_False);
1207         Evive.SetValue(ii, Enext);
1208       }
1209       else {
1210         //      edge ii is alive
1211         CD.SetValue(ii, cdbid);
1212         Index.SetValue(ii, 0);
1213         sens.SetValue(ii, -1);
1214         TopoDS_Vertex Vref;
1215         Vref = TopExp::FirstVertex(Enext);
1216         if (Vref.IsSame(V1)) sens.SetValue(ii, 1);   
1217         sharp.SetValue(ii, Standard_True);
1218         Evive.SetValue(ii, Enext);
1219         jf.SetValue(ii, 0);
1220       }
1221       // Face Fnext!=Fcur containing Enext 
1222       Fnext=Fcur;
1223       ChFi3d_cherche_face1(myEFMap(Enext),Fcur,Fnext);
1224       Indices(nedge,ii,icplus,icmoins);
1225       Fvive.SetValue(ii,icplus, Fnext);
1226       Fvive.SetValue(icplus,ii, Fnext);
1227       numfa.SetValue(ii,icplus, DStr.AddShape(Fnext));
1228       numfa.SetValue(icplus,ii,numfa.Value(ii,icplus));
1229       Standard_Integer numface1,numface2;
1230       if (trouve) {
1231         // it is checked if numfa corresponds to IndexOfS1 or IndexOfS2 
1232         // jf is updated is consequently updated
1233         // if it is not the case among the previous faces are found 
1234         // those which correspond to  IndexOfs1 IndexOfS2  and  
1235         // numfa and Fvive are reupdated (cts16288)  
1236         numface2 = SurfIndex(CD, ii, Index.Value(ii), FACE2);
1237         if (numface2==numfa.Value(ii,icplus))
1238           jf.SetValue(ii, 2);
1239         else {
1240           numface1 = SurfIndex(CD, ii, Index.Value(ii), FACE1);
1241           if (numface1==numfa.Value(ii,icplus))
1242             jf.SetValue(ii, 1);
1243           else {
1244             if (numface1==numfa.Value(icmoins,ii))  {
1245               jf.SetValue(ii, 2);
1246               Fvive.SetValue(ii,icplus,TopoDS::Face(DStr.Shape(numface2)));
1247               Fvive.SetValue(icplus,ii,TopoDS::Face(DStr.Shape(numface2)));
1248               numfa.SetValue(ii,icplus, DStr.AddShape(TopoDS::Face(DStr.Shape(numface2))));
1249               numfa.SetValue(icplus,ii, numfa.Value (ii,icplus));
1250             }
1251             if (numface2==numfa.Value(icmoins,ii)) {
1252               jf.SetValue(ii, 1);
1253               Fvive.SetValue(ii,icplus,TopoDS::Face(DStr.Shape(numface1)));
1254               Fvive.SetValue(icplus,ii,TopoDS::Face(DStr.Shape(numface1)));
1255               numfa.SetValue(ii,icplus, DStr.AddShape(TopoDS::Face(DStr.Shape(numface1))));
1256               numfa.SetValue(icplus,ii, numfa.Value (ii,icplus));
1257             }
1258           }
1259         }
1260       }
1261       Ecur = Enext;
1262       Fcur = Fnext;
1263       // find sum of all face normales at V1
1264       SummarizeNormal(V1, Fcur, Ecur, SumFaceNormalAtV1);
1265     }
1266   }
1267   // mise a jour du tableau regul 
1268   for (ic=0;ic<nedge;ic++) {
1269     if (sharp.Value(ic)) {
1270       Ecur=TopoDS::Edge(Evive.Value(ic));
1271       if (!Ecur.IsSame(edgecouture)) {
1272         ChFi3d_edge_common_faces(myEFMap(Ecur),F1,F2);   
1273 //  Modified by Sergey KHROMOV - Fri Dec 21 18:11:02 2001 Begin
1274 //      regul.SetValue(ic,BRep_Tool::Continuity(TopoDS::Edge(Evive.Value(ic)),F1,F2)
1275 //                   !=GeomAbs_C0); 
1276         regul.SetValue(ic, ChFi3d::IsTangentFaces(TopoDS::Edge(Evive.Value(ic)),F1,F2)); 
1277 //  Modified by Sergey KHROMOV - Fri Dec 21 18:11:07 2001 End
1278       }
1279     }
1280   }
1281   // it is checked if a regular edge is not tangent to another edge
1282   // in case if it is not considered regular (cts60072)
1283   for (ic=0;ic<nedge;ic++) {
1284     if (regul.Value(ic) ) {
1285       trouve=Standard_False;
1286       TopoDS_Edge ereg=TopoDS::Edge(Evive.Value(ic));
1287       for( ind=0;ind<nedge &&!trouve;ind++) {
1288         if (ind!=ic) {
1289           TopoDS_Edge ecur=TopoDS::Edge(Evive.Value(ind));
1290           Standard_Real ang=Abs(ChFi3d_AngleEdge(V1,ecur,ereg)); 
1291           if (ang<0.01 || Abs(ang-M_PI) <0.01) {
1292             regul.SetValue(ic,Standard_False);
1293             tangentregul.SetValue(ic,Standard_True);
1294             trouve=Standard_True;
1295           }  
1296         }
1297       }   
1298     }
1299   }
1300
1301   // variable deuxconges allows detecting cases when there is a top with 
1302   // n edges and two fillets on two tangent edges that are not free borders
1303   // the connecting curves start from the fillet and end on top 
1304   
1305   Standard_Boolean deuxconges,deuxcgnontg;
1306   deuxconges=Standard_False;
1307   trouve=Standard_False;
1308   if (nconges==2) {
1309     TopoDS_Edge E1,E2; 
1310     for (ic=0;ic<nedge&&!trouve;ic++) {
1311       Indices(nedge,ic,icplus,icmoins);
1312       if (!sharp.Value(ic) && !sharp.Value(icplus)){
1313         E1=TopoDS::Edge(Evive.Value(ic));
1314         E2=TopoDS::Edge(Evive.Value(icplus));                                   
1315         deuxconges=(Abs(ChFi3d_AngleEdge(V1 ,E1,E2)   )<0.01) ;
1316         trouve=deuxconges;
1317       }
1318     }
1319   }
1320
1321   // variable deuxconges is used in the special case when there are 
1322   // two fillets and if two other living edges are tangent (cts60072) 
1323   if (nconges==2 && nedge==4) {
1324     TopoDS_Edge E1,E2; 
1325      for (ic=0;ic<nedge&&!deuxconges;ic++) {
1326        Indices(nedge,ic,icplus,icmoins);
1327        if (sharp.Value(ic) && sharp.Value(icplus)){
1328          E1=TopoDS::Edge(Evive.Value(ic));
1329          E2=TopoDS::Edge(Evive.Value(icplus));
1330          if ( !E1.IsSame(edgelibre1) && !E1.IsSame(edgelibre2) &&
1331               !E2.IsSame(edgelibre1) && !E2.IsSame(edgelibre2)){ 
1332            Standard_Real ang=Abs(ChFi3d_AngleEdge(V1 ,E1,E2));
1333            deuxconges=(ang<0.01 || Abs(ang-M_PI)<0.01);
1334          }
1335        }
1336      }
1337   }
1338   
1339   deuxcgnontg=nconges==2&& nedge==3 && !deuxconges; // pro12305 
1340
1341   if (deuxconges )
1342   for  (ic=0;ic<nedge;ic++){
1343    regul.SetValue(ic,Standard_False);
1344   }
1345
1346   // Detect case of 3 edges & 2 conges: OnSame + OnDiff
1347   // (eap, Arp 9 2002, occ266)
1348   Standard_Boolean isOnSameDiff = Standard_False;
1349   if (deuxcgnontg) {
1350     Standard_Boolean isOnSame = Standard_False, isOnDiff = Standard_False;
1351     for (ic=0; ic<nedge; ic++) {
1352       if (sharp.Value(ic)) continue;
1353       ChFiDS_State stat;
1354       if ( sens(ic) == 1 )
1355         stat = CD.Value(ic)->Spine()->FirstStatus();
1356       else
1357         stat = CD.Value(ic)->Spine()->LastStatus();
1358       
1359       if      (stat == ChFiDS_OnSame) isOnSame = Standard_True;
1360       else if (stat == ChFiDS_OnDiff) isOnDiff = Standard_True;
1361     }
1362     isOnSameDiff = isOnSame && isOnDiff;
1363   }
1364   if ( isOnSameDiff ) {
1365 #ifdef OCCT_DEBUG
1366     std::cout << "OnSame + OnDiff, PerformMoreThreeCorner() calls PerformOneCorner()" << std::endl;
1367 #endif
1368     PerformOneCorner (Jndex, Standard_True);
1369   }
1370
1371 // if the commonpoint is on an edge that does not have a 
1372 // vertex at the extremity, Evive is found anew    
1373 // Fvive is found anew if it does not correspond 
1374 // to two faces adjacent to Evive (cts16288)
1375
1376   if (!deuxconges && !isOnSameDiff) 
1377     for (ic=0;ic<nedge;ic++) { 
1378       if (sharp.Value(ic)) {
1379         Indices(nedge,ic,icplus,icmoins);
1380         TopoDS_Edge Arc=TopoDS::Edge(Evive.Value(ic));
1381         ChFiDS_CommonPoint cp1, cp2;
1382         Standard_Real angedg=M_PI;
1383         TopoDS_Vertex Vcom;
1384         if (!sharp.Value(icplus)) {
1385           isfirst=(sens.Value(icplus)==1);
1386           jfp = 3 - jf.Value(icplus);
1387           cp1 = CD.Value(icplus)->SetOfSurfData()->Value(Index.Value(icplus))->
1388             ChangeVertex (isfirst,jfp);
1389           if (cp1.IsOnArc()){
1390             ChFi3d_cherche_vertex(Arc,cp1.Arc(),Vcom,trouve);
1391             if (trouve) angedg=Abs(ChFi3d_AngleEdge(Vcom,Arc,cp1.Arc()));
1392             if (!cp1.Arc().IsSame(Arc) && Abs(angedg-M_PI)<0.01){
1393               Evive.SetValue(ic,cp1.Arc());
1394               ChFi3d_edge_common_faces(myEFMap(cp1.Arc()),F1,F2);
1395               if (!Fvive.Value(ic,icplus).IsSame(F1) && !Fvive.Value(ic,icplus).IsSame(F2)) {
1396                 if (Fvive.Value(ic,icmoins).IsSame(F2))  {
1397                   Fvive.SetValue(ic,icplus,F1);
1398                   Fvive.SetValue(icplus,ic,F1);
1399                   numfa.SetValue(ic,icplus,DStr.AddShape(F1)); 
1400                   numfa.SetValue(icplus,ic,DStr.AddShape(F1)); 
1401                 }
1402                 else  {
1403                   Fvive.SetValue(ic,icplus,F2);
1404                   Fvive.SetValue(icplus,ic,F2);
1405                   numfa.SetValue(ic,icplus,DStr.AddShape(F2)); 
1406                   numfa.SetValue(icplus,ic,DStr.AddShape(F2)); 
1407                 }
1408               }
1409               samedge.SetValue(ic,Standard_True);
1410               p.SetValue(ic,icplus,cp1.ParameterOnArc());
1411               p.SetValue(ic,icmoins,cp1.ParameterOnArc());  
1412               i.SetValue(ic,icplus,1);        
1413             }
1414           }
1415         }
1416         if (!sharp.Value(icmoins)) {
1417           isfirst=(sens.Value(icmoins)==1);
1418           cp2 = CD.Value(icmoins)->SetOfSurfData()->Value(Index.Value(icmoins))->
1419             ChangeVertex (isfirst,jf.Value(icmoins));
1420           if (cp2.IsOnArc()) {
1421             angedg=M_PI;
1422             ChFi3d_cherche_vertex(Arc,cp2.Arc(),Vcom,trouve);
1423             if (trouve) angedg=Abs(ChFi3d_AngleEdge(Vcom,Arc,cp2.Arc()));
1424             if (!cp2.Arc().IsSame(Arc)&&Abs(angedg-M_PI)<0.01) {
1425               Evive.SetValue(ic,cp2.Arc());
1426               ChFi3d_edge_common_faces(myEFMap(cp2.Arc()),F1,F2);
1427               if (!Fvive.Value(ic,icmoins).IsSame(F1) && !Fvive.Value(ic,icmoins).IsSame(F2)) {
1428                 if (Fvive.Value(ic,icplus).IsSame(F2))  {
1429                   Fvive.SetValue(ic,icmoins,F1);
1430                   numfa.SetValue(ic,icmoins,DStr.AddShape(F1));
1431                   Fvive.SetValue(icmoins,ic,F1);
1432                   numfa.SetValue(icmoins,ic,DStr.AddShape(F1)); 
1433                 }
1434                 else  {
1435                   Fvive.SetValue(ic,icmoins,F2);
1436                   numfa.SetValue(ic,icmoins,DStr.AddShape(F2));
1437                   Fvive.SetValue(icmoins,ic,F2);
1438                   numfa.SetValue(icmoins,ic,DStr.AddShape(F2)); 
1439                 }
1440               }
1441               samedge.SetValue(ic,Standard_True);
1442               p.SetValue(ic,icmoins,cp2.ParameterOnArc());
1443               p.SetValue(ic,icplus,cp2.ParameterOnArc());
1444               i.SetValue(ic,icmoins,1);   
1445             }
1446           }
1447         }     
1448       }
1449     } 
1450
1451 // the first free edge is restored if it exists
1452   trouve=Standard_False;
1453   for (ic=0; ic<nedge&&!trouve;ic++) {  
1454     TopoDS_Edge ecom;
1455     ecom=TopoDS::Edge(Evive.Value(ic));
1456     if (ecom.IsSame(edgelibre1)||ecom.IsSame(edgelibre2)){ 
1457       libre.SetValue(ic,Standard_True);
1458       trouve=Standard_True;
1459     }
1460   }  
1461
1462 // determine the minimum recoil distance that can't be exceeded 
1463   Standard_Boolean distmini=Standard_False;
1464   gp_Pnt som=BRep_Tool::Pnt(V1),pic;  
1465   gp_Pnt2d p2;
1466   TopoDS_Edge edgemin;
1467   TopoDS_Vertex V,V2;
1468   Standard_Real dst,distmin;
1469   distmin=1.e30;
1470   for (ic=0;ic<nedge;ic++) {
1471     if (sharp.Value(ic))
1472       edgemin=TopoDS::Edge(Evive.Value(ic));
1473     else {
1474       if (sens.Value(ic)==1) 
1475         edgemin= CD.Value(ic)->Spine()->Edges(1);
1476       else  
1477         edgemin = CD.Value(ic)->Spine()->Edges(CD.Value(ic)->Spine()->NbEdges());
1478     }
1479     V=TopExp::FirstVertex(edgemin);
1480     V2=TopExp::LastVertex(edgemin);
1481     dst=(BRep_Tool::Pnt(V)).Distance(BRep_Tool::Pnt(V2))/1.5;
1482     if (dst<distmin) distmin=dst;
1483   }
1484
1485 //  calculate intersections between stripes and determine the parameters on each pcurve  
1486   Standard_Boolean inters=Standard_True;
1487   for (ic=0;ic<nedge;ic++) {
1488     Indices(nedge,ic,icplus,icmoins);
1489     if (sharp.Value(ic)||sharp.Value(icplus)) {
1490       oksea.SetValue(ic, Standard_False);
1491     }
1492     else {
1493       Standard_Integer jf1 = 0;
1494       Standard_Integer i1 = 0,i2 = 0;
1495       Standard_Real pa1 = 0.,pa2;
1496       Standard_Boolean ok;
1497       Handle(ChFiDS_Stripe) strip;
1498       Standard_Real angedg;
1499       Standard_Integer iface;
1500       // if two edges are tangent the intersection is not attempted (cts60046)
1501       angedg=Abs(ChFi3d_AngleEdge(V1,TopoDS::Edge(Evive.Value(ic)),TopoDS::Edge(Evive.Value(icplus))));
1502       if (Abs(angedg-M_PI)>0.01)
1503         ok = ChFi3d_SearchFD(DStr,CD.Value(ic),CD.Value(icplus),sens.Value(ic),sens.Value(icplus),
1504                                   i1,i2,pa1,pa2,
1505                                   Index.Value(ic),Index.Value(icplus),
1506                                   face,sameside,jf1,jfp);
1507       else ok=Standard_False;
1508      // if there is an intersection it is checked if surfdata with the intersection
1509      // corresponds to the first or the last 
1510      // if this is not the case, the surfdata are removed from SD 
1511       
1512       if (ok) {
1513         if (i1!=Index.Value(ic) ){
1514           Standard_Integer ideb,ifin;
1515           strip=CD.Value(ic);
1516           if (sens.Value(ic)==1) {
1517             ideb=Index.Value(ic);
1518             ifin=i1-1;
1519           }
1520           else {
1521             ifin=Index.Value(ic);
1522             ideb=i1+1;
1523           }
1524           if (i1<Index.Value(ic)) {
1525             for (nb=Index.Value(ic);nb>=i1;nb--) {
1526               if ((3-jf1)==1) 
1527                 iface=SurfIndex(CD, ic, nb , FACE1);
1528               else    iface=SurfIndex(CD, ic, nb , FACE2);
1529               Fproj.Append(TopoDS::Face(myDS->Shape(iface)));  
1530             }
1531           }
1532           if (i1>Index.Value(ic)) {
1533             for (nb=Index.Value(ic);nb<=i1;nb++) {
1534               if ((3-jf1)==1) 
1535                 iface=SurfIndex(CD, ic, nb , FACE1);
1536               else    iface=SurfIndex(CD, ic, nb , FACE2);
1537                Fproj.Append(TopoDS::Face(myDS->Shape(iface)));  
1538             }
1539           }    
1540           strip=CD.Value(ic);
1541           RemoveSD(strip,ideb,ifin);
1542           num=ChFi3d_IndexOfSurfData(V1,CD.Value(ic),sense);
1543           Index.SetValue(ic,num);
1544           i1=num; 
1545         }
1546         if (i2!=Index.Value(icplus) ){
1547           Standard_Integer ideb,ifin;
1548           strip=CD.Value(icplus);
1549           if (sens.Value(icplus)==1) {
1550             ideb=Index.Value(icplus);
1551             ifin=i2-1;
1552           }
1553           else {
1554             ifin=Index.Value(icplus);
1555             ideb=i2+1;
1556           }
1557           
1558           if (i2<Index.Value(icplus)) {
1559             for (nb=i2;nb<=Index.Value(icplus);nb++) {
1560               if ((3-jfp)==1) 
1561                 iface=SurfIndex(CD, icplus, nb , FACE1);
1562               else    iface=SurfIndex(CD, icplus, nb , FACE2);
1563               Fproj.Append(TopoDS::Face(myDS->Shape(iface)));  
1564             }
1565           }
1566           if (i2>Index.Value(icplus)) {
1567             for (nb=i2;nb>=Index.Value(icplus);nb--) {
1568               if ((3-jfp)==1) 
1569                 iface=SurfIndex(CD, icplus, nb , FACE1);
1570               else    iface=SurfIndex(CD, icplus, nb , FACE2);
1571               Fproj.Append(TopoDS::Face(myDS->Shape(iface)));  
1572             }
1573           }    
1574           RemoveSD(strip,ideb,ifin);
1575           num=ChFi3d_IndexOfSurfData(V1,CD.Value(icplus),sense);
1576           Index.SetValue(icplus,num);
1577           i2=num; 
1578       }
1579         Calcul_P2dOnSurf(CD.Value(ic),jf1,i1,pa1,p2);
1580         indice=SurfIndex(CD, ic, i1, ChFiSURFACE);
1581         DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),pic);
1582         if (pic.Distance(som)>distmin) distmini =Standard_True;
1583         jf.SetValue(ic,jf1);
1584         i.SetValue(ic,icplus,i1);
1585         i.SetValue(icplus,ic,i2);
1586         p.SetValue(ic,icplus,pa1);
1587         p.SetValue(icplus,ic,pa2);
1588       }
1589       oksea.SetValue(ic, ok);
1590     }
1591     if (!oksea.Value(ic) ) inters=Standard_False; 
1592   }
1593
1594   // case if there are only intersections 
1595   // the parametres on Pcurves are the extremities of the stripe
1596   Standard_Real para;
1597   if (!inters) {
1598     for (ic=0;ic<nedge;ic++) {
1599       Indices(nedge,ic,icplus,icmoins);
1600       Indices(nedge,icplus,icplus2,ic);
1601       if (!oksea.Value(ic)) {
1602         cbplus++;
1603         if (sharp.Value(ic)) {
1604           if (!samedge.Value(ic)){
1605             para=BRep_Tool::Parameter(V1,TopoDS::Edge(Evive.Value(ic)));
1606             p.SetValue(ic,icplus,para);
1607             i.SetValue(ic,icplus,1);
1608           }
1609         }
1610         else {
1611           isfirst= (sens.Value(ic)==1);
1612           i.SetValue(ic,icplus,ChFi3d_IndexOfSurfData(V1,CD.Value(ic),sense));
1613           if (oksea.Value(icmoins)) {
1614            para=p.Value(ic,icmoins);
1615            p.SetValue(ic,icplus,para);
1616           }
1617           else {
1618             Calcul_Param(CD.Value(ic),jf.Value(ic),i.Value(ic,icplus),isfirst,para);
1619             p.SetValue(ic,icplus,para);
1620           }
1621         }
1622         if (sharp.Value(icplus)) {
1623           if (!samedge.Value(icplus)) {
1624             para=BRep_Tool::Parameter(V1,TopoDS::Edge(Evive.Value(icplus)));
1625             p.SetValue(icplus,ic, para);
1626             i.SetValue(icplus,ic,1);
1627           }
1628         }
1629         else {
1630           isfirst= (sens.Value(icplus)==1);
1631           i.SetValue(icplus,ic,ChFi3d_IndexOfSurfData(V1,CD.Value(icplus),sense));
1632           if (oksea.Value(icplus)){
1633           para=p.Value(icplus,icplus2);
1634           p.SetValue(icplus,ic,para);
1635           }
1636           else {
1637             jfp = 3 - jf.Value(icplus);
1638             Calcul_Param(CD.Value(icplus),jfp,i.Value(icplus,ic),isfirst,para);
1639             p.SetValue(icplus,ic,para);
1640           }
1641         }
1642       }
1643     }
1644       
1645 //  calculate max distance to the top at each point  
1646     TColStd_Array1OfReal dist1(0,size);
1647     TColStd_Array1OfReal dist2(0,size);
1648     Standard_Real distance=0.;
1649     gp_Pnt sommet=BRep_Tool::Pnt(V1);
1650     if (!deuxconges)
1651     for (ic=0;ic<nedge;ic++) {
1652       Indices(nedge,ic,icplus,icmoins);
1653       if (sharp.Value(ic)) {
1654         dist1.SetValue(ic, 0);
1655         dist2.SetValue(ic, 0);
1656       }
1657       else {        
1658         jfp = 3 - jf.Value(ic);       
1659         Calcul_P2dOnSurf(CD.Value(ic),jfp,i.Value(ic,icmoins),p.Value(ic,icmoins),p2);
1660         indice=SurfIndex(CD, ic, i.Value(ic,icmoins), ChFiSURFACE);
1661         DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),pic);
1662         dist1.SetValue(ic, sommet.Distance(pic));
1663         if (dist1.Value(ic) > distance ) distance= dist1.Value(ic);
1664
1665         Calcul_P2dOnSurf(CD.Value(ic),jf.Value(ic),i.Value(ic,icplus),p.Value(ic,icplus),p2);
1666         indice=SurfIndex(CD, ic, i.Value(ic,icplus), ChFiSURFACE);
1667         DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),pic);
1668         dist2.SetValue(ic, sommet.Distance(pic));
1669         if( dist2.Value(ic) > distance  )  
1670           distance= dist2.Value(ic);
1671       }
1672     }
1673
1674 //  offset of parameters and removal of intersection points 
1675 //  too close to the top 
1676
1677     Standard_Real ec, dist; 
1678     if (!deuxconges && !deuxcgnontg)
1679     for (ic=0;ic<nedge;ic++) {
1680       Indices(nedge,ic,icplus,icmoins);
1681       if (sharp.Value(ic) ) {
1682         BRepAdaptor_Curve C(TopoDS::Edge(Evive.Value(ic)));
1683         // to pass from 3D distance to a parametric distance
1684         if (!tangentregul(ic))
1685           ec = distance*100*C.Resolution(0.01);
1686         else ec=0.0;
1687         if (TopExp::FirstVertex(TopoDS::Edge(Evive.Value(ic))).IsSame(V1)) {
1688           para=p.Value(ic,icmoins) + ec;
1689           p.SetValue(ic,icmoins, para);
1690         }
1691         else {
1692           para=p.Value(ic,icmoins) - ec;
1693           p.SetValue(ic,icmoins,para);
1694         }
1695 // it is necessary to be on to remain on the edge
1696         p.SetValue(ic,icplus, p.Value(ic,icmoins));
1697       }
1698       else if (!distmini) {
1699         dist = dist1.Value(ic);
1700         if ((!oksea.Value(icmoins))||(oksea.Value(icmoins)&&(distance>1.3*dist))) {
1701           ec= distance-dist;
1702           if (oksea.Value(icmoins)) {
1703             oksea.SetValue(icmoins,Standard_False);
1704             inters=Standard_False;
1705             cbplus++;
1706           }
1707           if (sens.Value(ic)==1) {
1708             para=p.Value(ic,icmoins) + ec;
1709             p.SetValue(ic,icmoins, para);
1710           }
1711           else{
1712              para=p.Value(ic,icmoins) - ec;
1713              p.SetValue(ic,icmoins,para);
1714           }
1715         }
1716         dist = dist2.Value(ic);
1717         if ((!oksea.Value(ic))||(oksea.Value(ic)&&(distance>1.3*dist))) {
1718           if(oksea.Value(ic)) { 
1719             oksea.SetValue(ic,Standard_False);
1720             inters=Standard_False;
1721             cbplus++;
1722           }
1723           if (nconges!=1) {
1724             Standard_Real parold,parnew;
1725             parold=p.Value(ic,icplus);
1726             parnew=p.Value(ic,icmoins);
1727             if (sens.Value(ic)==1) {
1728               if (parnew> parold) p.SetValue(ic,icplus, p.Value(ic,icmoins));
1729             }
1730             else {
1731               if (parnew<parold) p.SetValue(ic,icplus, p.Value(ic,icmoins));
1732             }
1733           }  
1734         }
1735       }
1736     }
1737   }
1738
1739 // it is attempted to limit the edge by a commonpoint
1740 //
1741  
1742   Standard_Real tolcp=0;
1743   gp_Pnt PE, sommet=BRep_Tool::Pnt(V1);
1744   if (!deuxconges)  
1745   for (ic=0;ic<nedge;ic++) {
1746     if (sharp.Value(ic)) {
1747       Indices(nedge,ic,icplus,icmoins);
1748       BRepAdaptor_Curve C(TopoDS::Edge(Evive.Value(ic)));
1749       PE = C.Value(p.Value(ic,icplus));
1750       Standard_Real d1=0., d2=0., dS = PE.Distance(sommet);
1751       ChFiDS_CommonPoint cp1, cp2;
1752       if (!sharp.Value(icplus)) {
1753         isfirst=(sens.Value(icplus)==1);
1754         jfp = 3 - jf.Value(icplus);
1755         cp1 = CD.Value(icplus)->SetOfSurfData()->Value(i.Value(icplus,ic))->
1756           ChangeVertex (isfirst,jfp);
1757         d1 = cp1.Point().Distance(sommet);
1758       }
1759       if (!sharp.Value(icmoins)) {
1760         isfirst=(sens.Value(icmoins)==1);
1761         cp2 = CD.Value(icmoins)->SetOfSurfData()->Value(i.Value(icmoins,ic))->
1762           ChangeVertex (isfirst,jf.Value(icmoins));
1763         d2 = cp2.Point().Distance(sommet);
1764       }
1765       Standard_Boolean samecompoint=Standard_False;
1766       if (!sharp.Value(icmoins) &&  !sharp.Value(icplus))
1767         samecompoint=cp1.Point().Distance(cp2.Point())<tolapp;
1768       if ((dS<d1 || dS<d2)&& !samecompoint) {
1769 // step back till Common Points
1770 // without leaving the Edge ??
1771         if (d2<d1 &&cp1.IsOnArc() ) {
1772 // cp1 is chosen
1773           p.SetValue(ic,icmoins, cp1.ParameterOnArc());
1774           p.SetValue(ic,icplus, p.Value(ic,icmoins));
1775           isfirst=(sens.Value(icplus)==1);
1776           jfp = 3 - jf.Value(icplus);
1777           Calcul_Param(CD.Value(icplus),jfp,i.Value(icplus,ic),isfirst,para);
1778           p.SetValue(icplus,ic,para);
1779           if (cp1.Tolerance()>tolcp &&cp1.Tolerance()<1 ) tolcp=cp1.Tolerance();
1780         }
1781         else if( cp2.IsOnArc()){
1782 // cp2 is chosen
1783           p.SetValue(ic,icmoins, cp2.ParameterOnArc());
1784           p.SetValue(ic,icplus, p.Value(ic,icmoins));
1785           isfirst=(sens.Value(icmoins)==1);
1786           Calcul_Param(CD.Value(icmoins),jf.Value(icmoins),i.Value(icmoins,ic),isfirst, para);
1787           p.SetValue(icmoins,ic,para);
1788            if (cp2.Tolerance()>tolcp&&cp2.Tolerance()<1) tolcp=cp2.Tolerance();
1789         }
1790       }
1791       else {
1792 // step back till Common Point only if it is very close
1793         if (!sharp.Value(icplus)) {
1794           if ((cp1.Point().Distance(PE)<cp1.Tolerance() || 
1795                samecompoint || nconges==1) && cp1.IsOnArc()) {
1796 // it is very close to cp1
1797             p.SetValue(ic,icmoins, cp1.ParameterOnArc());
1798             ponctuel.SetValue(ic,Standard_True);
1799             p.SetValue(ic,icplus, p.Value(ic,icmoins));
1800             isfirst=(sens.Value(icplus)==1);
1801             jfp = 3 - jf.Value(icplus);
1802             Calcul_Param(CD.Value(icplus),jfp,i.Value(icplus,ic),isfirst,para);
1803             p.SetValue(icplus,ic,para);
1804             if (cp1.Tolerance()>tolcp &&cp1.Tolerance()<1) tolcp=cp1.Tolerance();
1805           }
1806         }
1807          if (!sharp.Value(icmoins)){
1808           if ((cp2.Point().Distance(PE)<cp2.Tolerance() || 
1809                samecompoint || nconges==1) && cp2.IsOnArc()) {
1810 // it is very close to cp2
1811             ponctuel.SetValue(icmoins,Standard_True);
1812             p.SetValue(ic,icmoins, cp2.ParameterOnArc());
1813             p.SetValue(ic,icplus,p.Value(ic,icmoins));
1814             isfirst=(sens.Value(icmoins)==1);
1815             Calcul_Param(CD.Value(icmoins),jf.Value(icmoins),i.Value(icmoins,ic),isfirst,para);
1816             p.SetValue(icmoins,ic,para);
1817             if (cp2.Tolerance()>tolcp&&cp2.Tolerance()<1 ) tolcp=cp2.Tolerance();
1818           }
1819         }
1820       }
1821     }
1822   }
1823
1824 // in case of a free border the parameter corresponding 
1825 // to the common point on the free edge is chosen. 
1826
1827   for (ic=0;ic<nedge;ic++) {
1828     if (TopoDS::Edge(Evive.Value(ic)).IsSame(edgelibre1) || 
1829         TopoDS::Edge(Evive.Value(ic)).IsSame(edgelibre2)) {
1830       Standard_Integer indic;
1831       ChFiDS_CommonPoint CP1;
1832       Indices(nedge,ic,icplus,icmoins);
1833       if (libre.Value(ic))indic=icmoins;
1834       else indic=icplus;
1835       if (!sharp(indic)) {
1836         isfirst=sens.Value(indic)==1;         
1837         CP1 = CD.Value(indic)->SetOfSurfData()->Value(Index.Value(indic))->ChangeVertex(isfirst,1);
1838         /*Standard_Boolean*/ trouve=Standard_False;
1839         if (CP1.IsOnArc()) {
1840           if(CP1.Arc().IsSame(TopoDS::Edge(Evive.Value(ic)))) {
1841             p.SetValue(ic,icmoins,CP1.ParameterOnArc());
1842             p.SetValue(ic,icplus,CP1.ParameterOnArc());
1843             trouve=Standard_True;
1844           }  
1845         }
1846         if (!trouve) {
1847           CP1 = CD.Value(indic)->SetOfSurfData()->Value(Index.Value(indic))->ChangeVertex(isfirst,2);
1848           if (CP1.IsOnArc()) {
1849             if(CP1.Arc().IsSame(TopoDS::Edge(Evive.Value(ic)))) {
1850               p.SetValue(ic,icmoins,CP1.ParameterOnArc());
1851               p.SetValue(ic,icplus,CP1.ParameterOnArc());
1852             }  
1853           }
1854         }
1855       }
1856     }   
1857   }
1858
1859 // if ic is a regular edge, one finds edge indfin which is not 
1860 // a regular edge, and construtc a curve 3d 
1861 // between edges (or stripes ) icmoins and indfin. 
1862 // Then this courbe3d is projected on all faces (nbface) that
1863 // separate icmoins and indfin
1864   Standard_Integer nbface = 0;
1865   Standard_Real  error = 0.;
1866   TColGeom2d_Array1OfCurve proj2d1(0,size);
1867   TColGeom2d_Array1OfCurve proj2d2(0,size);
1868   TColGeom_Array1OfCurve cproj1(0,size);
1869   TColGeom_Array1OfCurve cproj2(0,size);
1870   if (!deuxconges) 
1871   for (ic=0;ic<nedge;ic++) {
1872     Standard_Integer ilin;
1873     TColGeom_SequenceOfCurve cr;
1874     TColGeom2d_SequenceOfCurve pr;
1875     TopTools_SequenceOfShape Lface;
1876     TopTools_SequenceOfShape Ledge;
1877     Lface.Clear();
1878     if (regul.Value(ic)){
1879       Indices(nedge,ic,icplus,icmoins);
1880       Indices(nedge,icplus,icplus2,ic);
1881       Standard_Integer indfin,indfinmoins,indfinplus;
1882       indfin=icplus;
1883       trouve=Standard_False;
1884       ii=icplus;
1885       while (!trouve) { 
1886         if (!regul.Value(ii)) { 
1887           indfin=ii;
1888           trouve=Standard_True;
1889         }
1890         if (ii==nedge-1) ii=0;
1891         else ii++;
1892       } 
1893       Indices(nedge,indfin,indfinplus,indfinmoins);
1894       if (!sharp.Value(icmoins)){
1895         if( jf.Value(icmoins)==1)
1896           ilin= SurfIndex(CD, icmoins, i.Value(icmoins,ic), FACE1);
1897         else 
1898           ilin= SurfIndex(CD, icmoins, i.Value(icmoins,ic), FACE2);
1899         Lface.Append(TopoDS::Face(DStr.Shape(ilin)));
1900       }
1901       else Lface.Append( Fvive(ic,icmoins));
1902       if (indfin>icmoins) 
1903         nbface=indfin-icmoins;
1904       else nbface =nedge-(icmoins-indfin);
1905       TopTools_SequenceOfShape Epj;
1906       TColStd_SequenceOfReal  seqpr;
1907       ii=ic;
1908       for (Standard_Integer nf=1;nf<=nbface-1;nf++) { 
1909         Standard_Integer iimoins,iiplus;
1910         Indices(nedge,ii,iiplus,iimoins); 
1911         Ledge.Append(TopoDS::Edge(Evive.Value(ii)));
1912         seqpr.Append(p.Value(ii,iiplus));
1913         if (nf!=nbface-1) Lface.Append( Fvive(ii,iiplus));
1914         if (ii==nedge-1) ii=0;
1915         else ii++;
1916       }
1917       if (!sharp.Value(indfin) ){
1918         jfp=3-jf.Value(indfin);   
1919         if (jfp==1) 
1920           ilin= SurfIndex(CD, indfin, i.Value(indfin,indfinmoins), FACE1);
1921         else  ilin=SurfIndex(CD, indfin, i.Value(indfin,indfinmoins), FACE2);
1922         Lface.Append(TopoDS::Face(DStr.Shape(ilin)));
1923       }
1924       else  Lface.Append(Fvive(indfin,indfinmoins));
1925       CurveHermite(DStr,CD.Value(icmoins),jf.Value(icmoins),i.Value(icmoins,ic),
1926                    p.Value(icmoins,ic),sens.Value(icmoins),sharp.Value(icmoins),
1927                    TopoDS::Edge(Evive.Value(icmoins)),CD.Value(indfin),jf.Value(indfin),
1928                    i.Value(indfin,indfinmoins),p.Value(indfin,indfinmoins),sens.Value(indfin),
1929                    sharp.Value(indfin),TopoDS::Edge(Evive.Value(indfin)),nbface,Ledge,
1930                    Lface,pr,cr,Epj,seqpr,error);
1931       ii=ic;
1932       for (ind=1;ind<=nbface-1;ind++) {
1933         Standard_Integer iimoins,iiplus;
1934         Indices(nedge,ii,iiplus,iimoins);
1935         p.SetValue(ii,iiplus,seqpr.Value(ind));
1936         p.SetValue(ii,iimoins,seqpr.Value(ind));
1937         proj2d1.SetValue(ii,pr.Value(ind));
1938         proj2d2.SetValue(ii,pr.Value(ind+1));
1939         cproj1.SetValue(ii,cr.Value(ind));
1940         cproj2.SetValue(ii,cr.Value(ind+1));
1941         if (ii==nedge-1) ii=0;
1942         else ii++;
1943       }
1944       if (!sharp.Value(icmoins)&&!sharp.Value(indfin)) {   
1945         ii=icmoins;
1946         while (ii!=indfin) {
1947          isG1.SetValue(ii,Standard_True);
1948          if (ii==nedge-1) ii=0;
1949          else ii++;
1950         }
1951       }
1952       ic=ic+nbface-1;
1953     }       
1954   }
1955
1956  // case when the conncting curve between ic and icplus crosses many faces
1957   
1958   TopTools_SequenceOfShape Ecom;
1959   TopTools_SequenceOfShape Eproj;
1960   TColStd_SequenceOfReal parcom; 
1961   if (!deuxconges) 
1962   for (ic=0;ic<nedge;ic++) {
1963     Standard_Integer iface1,iface2;
1964     TopoDS_Face face1,face2;
1965     TopoDS_Edge edge;
1966     TColGeom_SequenceOfCurve cr;
1967     TColGeom2d_SequenceOfCurve pr;
1968     Indices(nedge,ic,icplus,icmoins);
1969     if (!oksea.Value(ic)){
1970       iface1=numfa.Value(ic,icplus);
1971       iface2=numfa.Value(icplus,ic);
1972        if (!sharp.Value(ic)) {
1973         if (jf.Value(ic)==1)
1974           iface1 =SurfIndex(CD, ic, i.Value(ic,icplus), FACE1);
1975         else   iface1=SurfIndex(CD, ic, i.Value(ic,icplus), FACE2);
1976       }
1977       face1=TopoDS::Face(myDS->Shape(iface1));
1978       
1979       if (!sharp.Value(icplus)) {
1980         if (jf.Value(icplus)==1)
1981           iface2 =SurfIndex(CD, icplus, i.Value(icplus,ic), FACE2);
1982         else   iface2=SurfIndex(CD, icplus, i.Value(icplus,ic), FACE1);
1983       }
1984       face2=TopoDS::Face(myDS->Shape(iface2));
1985       if (!face1.IsSame(face2)) {
1986         if (Fproj.Length()==0) {
1987           Fproj.Append(face1);
1988           Fproj.Append(face2); 
1989         }
1990         moresurf.SetValue(ic,Standard_True);    
1991         nbface=Fproj.Length();
1992         if (!TopoDS::Face(Fproj.Value(nbface)).IsSame(face2)) {
1993           Fproj.Remove(nbface); 
1994           Fproj.Append(face2);   
1995         }
1996         if (!TopoDS::Face(Fproj.Value(1)).IsSame(face1)) {
1997           Fproj.Remove(1); 
1998           Fproj.Prepend(face1);   
1999         }
2000         for (nb=1;nb<=nbface-1; nb++) {
2001           cherche_edge1 ( TopoDS::Face(Fproj.Value(nb)), TopoDS::Face(Fproj.Value(nb+1)),edge);
2002           Ecom.Append(edge); 
2003           para=BRep_Tool::Parameter(TopExp::FirstVertex(edge),edge);
2004           parcom.Append(para);   
2005         }      
2006         CurveHermite (DStr,CD.Value(ic),jf.Value(ic),i.Value(ic,icplus),
2007                     p.Value(ic,icplus),sens.Value(ic),sharp.Value(ic),
2008                     TopoDS::Edge(Evive.Value(ic)),
2009                     CD.Value(icplus),jf.Value(icplus),i.Value(icplus,ic),
2010                     p.Value(icplus,ic),sens.Value(icplus),sharp.Value(icplus),
2011                     TopoDS::Edge(Evive.Value(icplus)),nbface,Ecom,Fproj, pr,cr,Eproj,parcom,error);
2012         Ecom.Append(Ecom.Value(nbface-1)); 
2013         parcom.Append(parcom.Value(nbface-1));
2014       }
2015     }
2016   } 
2017
2018 // case when two fillets have the same commonpoints 
2019 // one continues then by intersection 
2020 // it is checked if the extremities of the intersection coincide with commonpoints
2021
2022   Standard_Boolean intersection=Standard_False, introuve;
2023   if (nconges==2 && !deuxconges) { 
2024     gp_Pnt P1,P2,P3,P4;
2025     Standard_Integer ic1 = 0,ic2 = 0;
2026     trouve=Standard_False;
2027     for (ic=0;ic<nedge&&!trouve;ic++) {
2028       if (!sharp.Value(ic)){ 
2029         ic1=ic;
2030         trouve=Standard_True;
2031       }
2032     }
2033     for (ic=0;ic<nedge;ic++) {
2034       if (!sharp.Value(ic)&& ic!=ic1) ic2=ic;   
2035     }
2036     jfp = 3 - jf.Value(ic1);
2037     Indices(nedge,ic1,icplus,icmoins);   
2038     Calcul_P2dOnSurf(CD.Value(ic1),jfp,i.Value(ic1,icmoins),p.Value(ic1,icmoins),p2);
2039     indice=SurfIndex(CD, ic1, i.Value(ic1,icmoins), ChFiSURFACE);
2040     DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),P1);
2041     
2042     Calcul_P2dOnSurf(CD.Value(ic1),jf.Value(ic1),i.Value(ic1,icplus),p.Value(ic1,icplus),p2);
2043     indice=SurfIndex(CD, ic1, i.Value(ic1,icplus), ChFiSURFACE);
2044     DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),P2);
2045     
2046     jfp = 3 - jf.Value(ic2);    
2047     Indices(nedge,ic2,icplus,icmoins);   
2048     Calcul_P2dOnSurf(CD.Value(ic2),jfp,i.Value(ic2,icmoins),p.Value(ic2,icmoins),p2);
2049     indice=SurfIndex(CD, ic2, i.Value(ic2,icmoins), ChFiSURFACE);
2050     DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),P3);
2051     
2052     Calcul_P2dOnSurf(CD.Value(ic2),jf.Value(ic2),i.Value(ic2,icplus),p.Value(ic2,icplus),p2);
2053     indice=SurfIndex(CD, ic2, i.Value(ic2,icplus), ChFiSURFACE);
2054     DStr.Surface(indice).Surface()->D0(p2.X(),p2.Y(),P4);
2055     intersection=(P1.Distance(P4)<=1.e-7 ||  P1.Distance(P3)<=1.e-7) &&
2056       (P2.Distance(P4)<=1.e-7 ||  P2.Distance(P3)<=1.e-7);
2057     if (intersection) { 
2058       PerformTwoCornerSameExt(DStr,CD.Value(ic1),Index.Value(ic1),sens.Value(ic1),
2059                               CD.Value(ic2),Index.Value(ic2),sens.Value(ic2),introuve);      
2060       if (introuve) return;
2061     }
2062   } 
2063
2064 // declaration for plate 
2065   GeomPlate_BuildPlateSurface PSurf(3,10,3,tol2d,tolesp,angular);
2066
2067 // calculation of curves on surface for each stripe 
2068   for (ic=0;ic<nedge;ic++) {
2069     gp_Pnt2d p2d1, p2d2;
2070     if (!sharp.Value(ic)) {
2071       n3d++;
2072       Indices(nedge,ic,icplus,icmoins);
2073       jfp = 3 - jf.Value(ic);
2074       Calcul_P2dOnSurf(CD.Value(ic),jfp,i.Value(ic,icmoins),p.Value(ic,icmoins),p2d1);
2075       Calcul_P2dOnSurf(CD.Value(ic),jf.Value(ic),i.Value(ic,icplus),p.Value(ic,icplus),p2d2);
2076 //      if (i[ic][icplus]!=  i[ic][icmoins]) std::cout<<"probleme surface"<<std::endl;
2077       indice= SurfIndex(CD, ic, i.Value(ic,icplus), ChFiSURFACE);
2078       Handle (GeomAdaptor_Surface) Asurf =
2079         new GeomAdaptor_Surface(DStr.Surface(indice).Surface());
2080       // calculation of curve 2d  
2081       xdir= p2d2.X()-p2d1.X();  
2082       ydir= p2d2.Y()-p2d1.Y();
2083       Standard_Real l0 = sqrt(xdir*xdir+ ydir*ydir );
2084       gp_Dir2d dir (xdir, ydir);
2085       Handle(Geom2d_Line) l= new Geom2d_Line (p2d1 ,dir);
2086       Handle (Geom2d_Curve) pcurve = new  Geom2d_TrimmedCurve(l,0,l0); 
2087       Handle (Geom2dAdaptor_Curve) Acurv = new Geom2dAdaptor_Curve(pcurve);
2088       Adaptor3d_CurveOnSurface  CurvOnS (Acurv,Asurf);
2089       Handle(Adaptor3d_CurveOnSurface) HCons =
2090         new Adaptor3d_CurveOnSurface(CurvOnS);
2091       Order.SetValue(ic,1);
2092       Handle(GeomPlate_CurveConstraint) Cont = 
2093         new GeomPlate_CurveConstraint(HCons,Order.Value(ic),10,tolesp,angular,0.1);
2094       PSurf.Add(Cont);
2095       
2096       // calculate indexes of points and of the curve for the DS         
2097       isfirst=(sens.Value(ic)==1);
2098       GeomLib::BuildCurve3d(tolapp,CurvOnS,CurvOnS.FirstParameter(),
2099                             CurvOnS.LastParameter(),Curv3d,maxapp,avedev);
2100       TopOpeBRepDS_Curve tcurv3d( Curv3d,maxapp);
2101       indcurve3d.SetValue(n3d,DStr.AddCurve(tcurv3d));
2102       gp_Pnt point1,point2; 
2103       point1=  CurvOnS.Value(CurvOnS.FirstParameter());
2104       point2 =CurvOnS.Value(CurvOnS.LastParameter());
2105       
2106       TopOpeBRepDS_Point tpoint1 (point1,maxapp);
2107       TopOpeBRepDS_Point tpoint2 (point2,maxapp);
2108       errapp.SetValue(ic,maxapp);
2109       if (ic==0) {
2110 // it is necessary to create two points
2111         indpoint.SetValue(ic,0,DStr.AddPoint(tpoint1));
2112         indpoint.SetValue(ic,1,DStr.AddPoint(tpoint2));
2113       }
2114       else {
2115 // probably the points are already on the fillet 
2116 // (previous intersection...)
2117         trouve = Standard_False;
2118         for (ii=0;ii<ic&&(!trouve);ii++) {
2119           if (!sharp.Value(ii)) {
2120             TopOpeBRepDS_Point & tpt= DStr.ChangePoint(indpoint.Value(ii,1));
2121             if (point1.Distance(tpt.Point())<1.e-4)
2122               trouve = Standard_True;
2123           }
2124         }
2125         if (trouve)
2126           indpoint.SetValue(ic,0,indpoint.Value(ii-1,1));
2127         else
2128           indpoint.SetValue(ic,0,DStr.AddPoint(tpoint1));
2129
2130         trouve = Standard_False;
2131         for (ii=0;ii<ic&&(!trouve);ii++) {
2132           if (!sharp.Value(ii)) {
2133             TopOpeBRepDS_Point & tpt= DStr.ChangePoint(indpoint.Value(ii,0));
2134             if (point2.Distance(tpt.Point())<1.e-4)
2135               trouve = Standard_True;
2136           }
2137         }
2138         if (trouve)
2139           indpoint.SetValue(ic,1,indpoint.Value(ii-1,0));
2140         else
2141           indpoint.SetValue(ic,1,DStr.AddPoint(tpoint2));
2142       }
2143       
2144       //   update of the stripe 
2145       isurf1=3-jf.Value(ic); isurf2=jf.Value(ic);
2146       if (isurf1==2)  CD.Value(ic)->SetOrientation(TopAbs_REVERSED,isfirst);
2147       CD.Value(ic)->SetCurve(indcurve3d.Value(n3d),isfirst);
2148       CD.Value(ic)->SetIndexPoint(indpoint.Value(ic,0),isfirst,isurf1); 
2149       CD.Value(ic)->SetIndexPoint(indpoint.Value(ic,1),isfirst,isurf2);
2150       CD.Value(ic)->SetParameters(isfirst,pcurve->FirstParameter(),pcurve->LastParameter());     
2151       ChFiDS_CommonPoint cp1;
2152       ChFiDS_CommonPoint cp2;
2153       cp1.SetPoint (point1);
2154       cp2.SetPoint( point2);
2155       CD.Value(ic)->SetOfSurfData()->Value(i.Value(ic,icmoins))->
2156         ChangeVertex (isfirst,isurf1)=cp1;
2157       CD.Value(ic)->SetOfSurfData()->Value(i.Value(ic,icmoins))->
2158         ChangeVertex (isfirst,isurf2)=cp2; 
2159       CD.Value(ic)->SetOfSurfData()->Value(i.Value(ic,icmoins))->
2160         ChangeInterference(isurf1).SetParameter(p.Value(ic,icmoins),isfirst);
2161       CD.Value(ic)->SetOfSurfData()->Value(i.Value(ic,icmoins))->
2162         ChangeInterference(isurf2).SetParameter(p.Value(ic,icplus),isfirst);
2163       CD.Value(ic)-> ChangePCurve(isfirst)= pcurve;
2164     }
2165   }
2166       
2167 // calculate the indices of points for living edges    
2168   for (ic=0;ic<nedge;ic++) {
2169     if (sharp.Value(ic)) {
2170       Indices(nedge,ic,icplus,icmoins);
2171       BRepAdaptor_Curve C(TopoDS::Edge(Evive.Value(ic)));
2172       /*gp_Pnt*/ PE = C.Value(p.Value(ic,icplus));
2173       TopOpeBRepDS_Point TPE(PE,BRep_Tool::Tolerance(TopoDS::Edge(Evive.Value(ic))));
2174       ChFiDS_CommonPoint cp;
2175       if (deuxconges ) {
2176         IVtx = DStr.AddShape(V1);
2177         indpoint.SetValue(ic,0, IVtx );
2178         indpoint.SetValue(ic,1, IVtx );
2179       }
2180       if (!sharp.Value(icplus)) {
2181         isfirst=(sens.Value(icplus)==1);
2182         jfp = 3 - jf.Value(icplus);
2183         cp = CD.Value(icplus)->SetOfSurfData()->Value(i.Value(icplus,ic))->
2184           ChangeVertex (isfirst,jfp);
2185         if ( cp.Point().Distance(PE) <= Max(1.e-4,tolcp)) {
2186 // edge was limited by the 1st CommonPoint of CD[icplus]
2187           indpoint.SetValue(ic,0,indpoint.Value(icplus,0));
2188           indpoint.SetValue(ic,1,indpoint.Value(icplus,0));
2189         }
2190       }
2191       if (!sharp.Value(icmoins)) {
2192         isfirst=(sens.Value(icmoins)==1);
2193         cp = CD.Value(icmoins)->SetOfSurfData()->Value(i.Value(icmoins,ic))->
2194           ChangeVertex (isfirst,jf.Value(icmoins));
2195         if ( cp.Point().Distance(PE) <= Max(1.e-4,tolcp)) {
2196 // edge was limited by the 2nd CommonPoint of CD[icmoins]
2197          if (indpoint.Value(ic,0)==0) { 
2198           indpoint.SetValue(ic,0, indpoint.Value(icmoins,1));
2199           indpoint.SetValue(ic,1, indpoint.Value(icmoins,1));
2200          }
2201         }
2202       }
2203       if (indpoint.Value(ic,0)==0) { 
2204          indpoint.SetValue(ic,0,DStr.AddPoint(TPE));
2205          indpoint.SetValue(ic,1, indpoint.Value(ic,0));
2206       }
2207     }
2208   }
2209
2210 // calculation of intermediary curves connecting two stripes in case if  
2211 // there is no intersection. The curve is a straight line, projection or batten 
2212   
2213   Standard_Boolean raccordbatten;
2214   if (!inters) {
2215
2216     for (ic=0;ic<nedge;ic++) {
2217        
2218       if (!oksea.Value(ic)&& !moresurf.Value(ic) && !libre.Value(ic) ) {
2219         Indices(nedge,ic,icplus,icmoins);
2220         raccordbatten=Standard_False;
2221         if (!regul.Value(ic)) {
2222           raccordbatten=Standard_True;
2223           if (regul.Value(icplus))
2224           raccordbatten=Standard_False;
2225         }
2226         n3d++;
2227         gp_Pnt2d p2d1, p2d2;
2228         Handle(Geom2d_Curve) curv2d1,curv2d2;
2229         Handle (Geom2d_Curve) pcurve;
2230         Handle (Geom_Curve) curveint;
2231         Handle (GeomAdaptor_Surface) Asurf;
2232         Standard_Real u1bid,u2bid;
2233         
2234         // return the 1st curve 2d 
2235         // and the 1st connection point 
2236         if (sharp.Value(ic))
2237           curv2d1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(Evive.Value(ic)),TopoDS::Face(Fvive.Value(ic,icplus)),
2238                                               u1bid,u2bid);
2239         else
2240           Calcul_C2dOnFace(CD.Value(ic),jf.Value(ic),i.Value(ic,icplus),curv2d1);
2241
2242         if (curv2d1.IsNull()) 
2243           throw Standard_ConstructionError ("Failed to get p-curve of edge");
2244         p2d1 = curv2d1 ->Value(p.Value(ic,icplus));
2245         
2246         // recuperation de la deuxieme courbe 2d
2247         // et du deuxieme point de raccordement
2248         if (sharp.Value(icplus))
2249           curv2d2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(Evive.Value(icplus)),
2250                                               TopoDS::Face(Fvive.Value(ic,icplus)),u1bid,u2bid);
2251         else {
2252           jfp = 3 - jf.Value(icplus);
2253           Calcul_C2dOnFace(CD.Value(icplus),jfp,i.Value(icplus,ic),curv2d2);
2254         }
2255         if (curv2d2.IsNull()) 
2256           throw Standard_ConstructionError ("Failed to get p-curve of edge");
2257         p2d2 = curv2d2 ->Value(p.Value(icplus,ic));
2258
2259         Asurf = new GeomAdaptor_Surface(BRep_Tool::Surface(TopoDS::Face(Fvive.Value(ic,icplus))));
2260         Standard_Real tolu,tolv,ratio; 
2261         tolu=Asurf->UResolution(1.e-3);
2262         tolv=Asurf->VResolution(1.e-3);
2263         if (tolu>tolv) ratio=tolu/tolv;
2264         else ratio=tolv/tolu;
2265         
2266         // in case of a sewing edge the parameters are reframed 
2267         if (couture) {
2268           Standard_Boolean PI1=Standard_False, PI2=Standard_False;
2269           Standard_Real xx;
2270           PI1=0<=p2d1.X() && p2d1.X() <=M_PI;
2271           PI2=0<=p2d2.X() && p2d2.X() <=M_PI;
2272           
2273           if (Evive.Value(ic).IsSame(edgecouture)){
2274             xx=p2d1.X();
2275             if (PI2&&!PI1) xx=xx-2*M_PI;
2276             if (!PI2&&PI1) xx=xx+2*M_PI;
2277             p2d1.SetX(xx);
2278               
2279           }
2280           if (Evive.Value(icplus).IsSame(edgecouture)){
2281             xx=p2d2.X();
2282             if (PI2&&!PI1) xx=xx+2*M_PI;
2283             if (!PI2&&PI1) xx=xx-2*M_PI;
2284             p2d2.SetX(xx); 
2285           }
2286         }
2287         xdir= p2d2.X()-p2d1.X();
2288         ydir= p2d2.Y()-p2d1.Y();
2289
2290         Standard_Real l0 = sqrt(xdir*xdir+ ydir*ydir );
2291         if (l0<1.e-7|| ponctuel.Value(ic)) {
2292 // unused connection
2293           n3d--;
2294           ponctuel.SetValue(ic,Standard_True);
2295           if (!deuxconges) {
2296             if ( sharp.Value(icplus) && indpoint.Value(icplus,0) == 0 ) {
2297               indpoint.SetValue(icplus,0, indpoint.Value(ic,1));
2298               indpoint.SetValue(icplus,1, indpoint.Value(ic,1));
2299             }
2300             if ( sharp.Value(ic) && indpoint.Value(ic,0) == 0 ) {
2301               indpoint.SetValue(ic,0,indpoint.Value(icmoins,1));
2302               indpoint.SetValue(ic,1,indpoint.Value(icmoins,1));
2303            }
2304           }
2305         }
2306         else {  // the connection is a straight line, projection or batten 
2307          if (ratio>10 && nconges==1) raccordbatten=Standard_True; 
2308          if (ratio>10 && raccordbatten) {
2309             CalculDroite(p2d1,xdir,ydir,pcurve);
2310             raccordbatten=Standard_False;
2311           }
2312           else  if (!raccordbatten){  // the projected curves are returned 
2313             if (regul.Value(ic)) {
2314                if (cproj2.Value(ic).IsNull()){ 
2315                    raccordbatten=Standard_True;
2316                }
2317                else {
2318                 pcurve=proj2d2.Value(ic);
2319                 curveint=cproj2.Value(ic);
2320                 maxapp1=1.e-6;
2321                }
2322                
2323             }
2324             else  {
2325               if (cproj1.Value(ic+1).IsNull()) {
2326                   raccordbatten=Standard_True; 
2327               }
2328               else {
2329                 pcurve=proj2d1.Value(ic+1);
2330                 curveint=cproj1.Value(ic+1); 
2331                 maxapp1=1.e-6;
2332               }
2333             }
2334           }
2335           Standard_Boolean contraint1=Standard_True,
2336                             contraint2=Standard_True;
2337           if (raccordbatten) {
2338 #ifdef OCCT_DEBUG
2339             ChFi3d_InitChron(ch);// initial performances for  battens  
2340 #endif  
2341             Standard_Boolean inverseic,inverseicplus;
2342             if (sharp.Value(ic)) {
2343                  inverseic=TopExp::FirstVertex(TopoDS::Edge(Evive.Value(ic))).
2344                          IsSame(V1);   
2345             }
2346             else {
2347               inverseic=sens.Value(ic)==1;
2348             }
2349             if (sharp.Value(icplus)){
2350               inverseicplus=TopExp::FirstVertex(TopoDS::Edge(Evive.Value(icplus))).
2351                          IsSame(V1);
2352             }
2353             else {
2354               inverseicplus=sens.Value(icplus)==1;
2355             } 
2356             if (TopoDS::Edge(Evive.Value(ic)).IsSame(edgelibre1) ||
2357                 TopoDS::Edge(Evive.Value(ic)).IsSame(edgelibre2)) 
2358                 contraint1=Standard_False;
2359             if (TopoDS::Edge(Evive.Value(icplus)).IsSame(edgelibre1) ||
2360                 TopoDS::Edge(Evive.Value(icplus)).IsSame(edgelibre2))
2361             contraint2=Standard_False;
2362             CalculBatten(Asurf,TopoDS::Face(Fvive(ic,icplus)),xdir,ydir,p2d1,p2d2,contraint1,contraint2,curv2d1,curv2d2,p.Value(ic,icplus),
2363                          p.Value(icplus,ic),inverseic,inverseicplus,pcurve);
2364 #ifdef OCCT_DEBUG
2365             ChFi3d_ResultChron( ch,t_batten);  // resulting performances for battens 
2366 #endif 
2367           }
2368
2369          // construction of borders for Plate 
2370          Handle (Geom2dAdaptor_Curve)  Acurv=new Geom2dAdaptor_Curve(pcurve);
2371          Adaptor3d_CurveOnSurface  CurvOnS (Acurv,Asurf);
2372          Handle(Adaptor3d_CurveOnSurface) HCons =
2373            new Adaptor3d_CurveOnSurface(CurvOnS);
2374
2375          // constraints G1 are set if edges ic and icplus are not both alive 
2376
2377
2378          Order.SetValue(n3d,0);
2379          if (!sharp.Value(ic)&& !sharp.Value(icplus))
2380            Order.SetValue(n3d,1);
2381          if (!contraint1 && !sharp.Value(icplus))
2382            Order.SetValue(n3d,1);
2383          if (!contraint2 && !sharp.Value(ic))
2384            Order.SetValue(n3d,1);
2385          if (tangentregul(ic) || tangentregul(icplus) )
2386            Order.SetValue(n3d,1);
2387          if (isG1.Value(ic)) 
2388            Order.SetValue(n3d,1);
2389          Handle(GeomPlate_CurveConstraint) Cont =
2390            new GeomPlate_CurveConstraint(HCons,Order.Value(n3d),10,tolesp,angular,0.1);
2391          PSurf.Add(Cont);
2392
2393          //calculation of curve 3d if it is not a projection 
2394          if (curveint.IsNull()) {
2395            GeomLib::BuildCurve3d(tolapp,CurvOnS,CurvOnS.FirstParameter(),
2396                                  CurvOnS.LastParameter(),Curv3d,maxapp1,avedev);
2397            pardeb=CurvOnS.FirstParameter();
2398            parfin= CurvOnS.LastParameter();
2399            curveint= new Geom_TrimmedCurve(Curv3d,pardeb,parfin);
2400          }
2401
2402          //storage in the DS  
2403          TopOpeBRepDS_Curve tcurv3d( curveint,maxapp1);
2404          indcurve3d.SetValue(n3d, DStr.AddCurve(tcurv3d));
2405          pardeb=curveint->FirstParameter();
2406          parfin=curveint->LastParameter();
2407          if ( sharp.Value(icplus) && indpoint.Value(icplus,0) == 0) {
2408            // it is necessary to initialize indpoint[icplus][0] and indpoint[icplus][1]
2409            gp_Pnt point2; 
2410            point2 =curveint->Value(parfin);
2411            TopOpeBRepDS_Point tpoint2 (point2,maxapp); 
2412            indpoint.SetValue(icplus,0,DStr.AddPoint(tpoint2));
2413            indpoint.SetValue(icplus,1,indpoint.Value(icplus,0));
2414          }
2415          Standard_Boolean IsVt1=Standard_False;
2416          Standard_Boolean IsVt2=Standard_False;
2417          if(deuxconges) {
2418            IsVt1=sharp.Value(ic);
2419            IsVt2=sharp.Value(icplus);
2420           }
2421           Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurve3d.Value(n3d),
2422                                        indpoint.Value(ic,1),pardeb,IsVt1);
2423           Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurve3d.Value(n3d),
2424                                        indpoint(icplus,0),parfin,IsVt2);
2425           DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append(Interfp1);
2426           DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append(Interfp2);
2427           if (!IsVt1) {
2428             TopOpeBRepDS_Point & tpt1= DStr.ChangePoint(indpoint(ic,1));
2429             tpt1.Tolerance (tpt1.Tolerance()+maxapp1);
2430           }       
2431           if (!IsVt2) {
2432             TopOpeBRepDS_Point &tpt2= DStr.ChangePoint(indpoint(icplus,0));
2433             tpt2.Tolerance (tpt2.Tolerance()+maxapp1);     
2434           }
2435
2436         // calculate orientation of the curve  
2437           TopAbs_Orientation orinterf; 
2438           if (!sharp.Value(ic)) {
2439               OrientationIcNonVive(CD.Value(ic),jf.Value(ic),i.Value(ic,icplus),sens.Value(ic),orinterf);
2440           }
2441           else if (!sharp.Value(icplus)) {
2442               OrientationIcplusNonVive(CD.Value(icplus),jf.Value(icplus),i.Value(icplus,ic),sens.Value(icplus),orinterf);
2443             }
2444           else {
2445                 OrientationAreteViveConsecutive (Fvive.Value(ic,icplus) ,Evive.Value(ic),V1,orinterf);                                      
2446           } 
2447           Interfc=ChFi3d_FilCurveInDS(indcurve3d.Value(n3d),numfa.Value(ic,icplus),pcurve,orinterf);      
2448           DStr.ChangeShapeInterferences(numfa.Value(ic,icplus)).Append(Interfc);
2449         }
2450        } // end of processing by edge 
2451     } // end of the loop on edges 
2452   }  // end of processing for intermediary curves 
2453         
2454 //  storage in the DS of curves projected on several faces 
2455   for (ic=0;ic<nedge;ic++) {
2456     if (moresurf.Value(ic) ){
2457       TopoDS_Vertex Vf,Vl;
2458       gp_Pnt Pf,Pl,P1,P2,Pcom;
2459       ind = 0; //must be initialized because of possible use, see L2249
2460       Standard_Real up1,up2;
2461       TopAbs_Orientation orvt;
2462       TopAbs_Orientation oredge = TopAbs_FORWARD;
2463       Standard_Integer indpoint1,indpoint2;
2464       Indices(nedge,ic,icplus,icmoins);
2465       Handle(Geom2d_Curve) proj,proj2d;
2466       Handle(Geom_Curve) projc,cproj;
2467       TopOpeBRepDS_Point& tpt1= DStr.ChangePoint(indpoint(ic,1));
2468       TopOpeBRepDS_Point& tpt2= DStr.ChangePoint(indpoint(icplus,0));
2469       tpt1.Tolerance (tpt1.Tolerance()+error);
2470       tpt2.Tolerance (tpt1.Tolerance()+error);
2471       for(nb=1;nb<=nbface;nb++) {
2472         orvt=TopAbs_REVERSED;
2473         Vf=TopExp::FirstVertex(TopoDS::Edge(Ecom.Value(nb)));
2474         Vl=TopExp::LastVertex (TopoDS::Edge(Ecom.Value(nb)));
2475         Pf=BRep_Tool::Pnt(Vf);
2476         Pl=BRep_Tool::Pnt(Vl);
2477         para=parcom.Value(nb);
2478         Pcom=BRep_Tool::Curve(TopoDS::Edge(Ecom.Value(nb)),up1,up2)->Value(para);
2479         if (Pf.Distance(BRep_Tool::Pnt(V1))< Pl.Distance(BRep_Tool::Pnt(V1)))
2480           orvt=TopAbs_FORWARD;
2481         if (!Eproj.Value(nb).IsNull())  {
2482           n3d++;
2483           proj=BRep_Tool::CurveOnSurface(TopoDS::Edge(Eproj.Value(nb)),
2484                                          TopoDS::Face(Fproj.Value(nb)),up1,up2);
2485           if (proj.IsNull()) 
2486             throw Standard_ConstructionError ("Failed to get p-curve of edge");
2487           proj2d=new Geom2d_TrimmedCurve(proj,up1,up2);
2488           projc=BRep_Tool::Curve(TopoDS::Edge(Eproj.Value(nb)),up1,up2);
2489           if (projc.IsNull()) 
2490             throw Standard_ConstructionError ("Failed to get 3D curve of edge");
2491           cproj=new Geom_TrimmedCurve(projc,up1,up2);
2492           pardeb=cproj->FirstParameter();
2493           parfin=cproj->LastParameter();
2494           P1=cproj->Value(pardeb);
2495           P2=cproj->Value(parfin);
2496           if (P1.Distance(tpt1.Point())<1.e-3) 
2497             indpoint1=indpoint(ic,1); 
2498           else  indpoint1=ind;
2499           if (P2.Distance(tpt2.Point())<1.e-3) 
2500             indpoint2=indpoint(icplus,0); 
2501           else  {
2502             TopOpeBRepDS_Point tpoint2 (P2,error);
2503             indpoint2= DStr.AddPoint(tpoint2);
2504             ind=indpoint2;    
2505           }
2506           Handle (GeomAdaptor_Surface) Asurf;
2507           Asurf = new GeomAdaptor_Surface(BRep_Tool::Surface
2508                                            (TopoDS::Face(Fproj.Value(nb))));
2509           Handle (Geom2dAdaptor_Curve)  Acurv=new Geom2dAdaptor_Curve(proj2d);
2510           Adaptor3d_CurveOnSurface  CurvOnS (Acurv,Asurf);
2511           Handle(Adaptor3d_CurveOnSurface) HCons =new Adaptor3d_CurveOnSurface(CurvOnS);
2512           Order.SetValue(n3d,1);
2513           Handle(GeomPlate_CurveConstraint) Cont =
2514             new GeomPlate_CurveConstraint(HCons,Order.Value(n3d),10,tolesp,angular,0.1);
2515           PSurf.Add(Cont);
2516           TopOpeBRepDS_Curve tcurv3d( cproj,error);
2517           indcurve3d.SetValue(n3d, DStr.AddCurve(tcurv3d));
2518           Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurve3d.Value(n3d),
2519                                        indpoint1,pardeb);
2520           Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurve3d.Value(n3d),
2521                                        indpoint2,parfin);
2522           DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append(Interfp1);
2523           DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append(Interfp2);
2524           num=DStr.AddShape(Fproj.Value(nb));
2525           TopExp_Explorer ex;
2526           for(ex.Init(Fproj.Value(nb).Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
2527               ex.More(); ex.Next()){
2528             if(Ecom.Value(nb).IsSame(ex.Current())) {
2529               oredge = ex.Current().Orientation();
2530               break;
2531             }
2532           }
2533
2534           //calculation of the orientation        
2535           TopAbs_Orientation orinterf;
2536           if (P1.Distance(Pcom)>1.e-4) {
2537             if (orvt==TopAbs_FORWARD) {
2538               orinterf=oredge;
2539             }
2540             else {
2541               orinterf=TopAbs::Reverse(oredge);
2542             }
2543           }
2544           else {
2545             if (orvt==TopAbs_FORWARD) {
2546               orinterf=TopAbs::Reverse(oredge); 
2547             }
2548             else {
2549               orinterf=oredge;
2550             }
2551           }
2552           Interfc=ChFi3d_FilCurveInDS(indcurve3d.Value(n3d),num,proj2d,orinterf);         
2553           DStr.ChangeShapeInterferences(num).Append(Interfc);
2554         }
2555         indice=ind;
2556         if (nb!=nbface) {    
2557           if (Eproj.Value(nb).IsNull())  indice=indpoint(ic,1);
2558           if (Eproj.Value(nb+1).IsNull()) indice=indpoint(icplus,0); 
2559           Indice.SetValue(n3d,indice);
2560           Standard_Integer Iarc1=DStr.AddShape(TopoDS::Edge(Ecom.Value(nb)));
2561           Interfp1=ChFi3d_FilPointInDS(orvt,Iarc1,indice,parcom.Value(nb));
2562           DStr.ChangeShapeInterferences(Iarc1).Append(Interfp1);
2563         }
2564       }
2565     }                     
2566   }
2567             
2568 // case when two free borders are tangent
2569   if (droit)      
2570     for (ic=0;ic<nedge;ic++) {
2571       Handle(Geom_Curve) curve,ctrim,rcurve;
2572       Handle(Geom2d_Curve) curve2d,ctrim2d,rcurve2d;
2573       Standard_Real ufirst,ulast;  
2574       Indices(nedge,ic,icplus,icmoins);
2575       Standard_Integer indpoint1,indpoint2;
2576       Standard_Boolean isvt1=Standard_False,isvt2=Standard_False;
2577       TopoDS_Edge ecur =TopoDS::Edge(Evive.Value(ic));
2578       if (ecur.IsSame(edgelibre1)|| ecur.IsSame(edgelibre2)) {
2579         n3d++;
2580         curve2d=BRep_Tool::CurveOnSurface(TopoDS::Edge(Evive.Value(ic)),
2581                                           TopoDS::Face(Fvive.Value(ic,icplus)),ufirst,ulast);
2582         curve=BRep_Tool::Curve(TopoDS::Edge(Evive.Value(ic)),ufirst,ulast);
2583         if (TopExp::FirstVertex((TopoDS::Edge(Evive.Value(ic)))).IsSame (V1)) { 
2584           ctrim=new Geom_TrimmedCurve(curve,ufirst,p.Value(ic,icmoins));
2585           ctrim2d=new Geom2d_TrimmedCurve(curve2d,ufirst,p.Value(ic,icmoins)); 
2586           indpoint1=DStr.AddShape(V1);
2587           isvt1=1;
2588           indpoint2=indpoint(ic,1);
2589         }
2590         else { 
2591           ctrim=new Geom_TrimmedCurve(curve, p.Value(ic,icmoins),ulast);
2592           ctrim2d=new Geom2d_TrimmedCurve(curve2d,p.Value(ic,icmoins),ulast);
2593           indpoint2=DStr.AddShape(V1);
2594           isvt2=1;
2595           indpoint1=indpoint(ic,1);
2596         }
2597         if (libre.Value(ic)){
2598           if (TopExp::FirstVertex((TopoDS::Edge(Evive.Value(ic)))).IsSame(V1)) { 
2599             ctrim->Reverse();
2600             ctrim2d->Reverse();
2601             indpoint2=DStr.AddShape(V1);
2602             isvt2=1;
2603             isvt1=0;
2604             indpoint1=indpoint(ic,1);
2605           }
2606         }
2607         else {
2608           if (TopExp::LastVertex((TopoDS::Edge(Evive.Value(ic)))).IsSame(V1)) {
2609             ctrim->Reverse();
2610             ctrim2d->Reverse();
2611             indpoint1=DStr.AddShape(V1);
2612             isvt1=1;
2613             isvt2=0;
2614             indpoint2=indpoint(ic,1);  
2615           } 
2616         }       
2617         ufirst=ctrim->FirstParameter();
2618         ulast=ctrim->LastParameter();
2619         Handle (GeomAdaptor_Surface) Asurf;
2620         Asurf = new GeomAdaptor_Surface(BRep_Tool::Surface
2621                                          (TopoDS::Face(Fvive.Value(ic,icplus))));
2622         Handle (Geom2dAdaptor_Curve)  Acurv=new Geom2dAdaptor_Curve(ctrim2d);
2623         Adaptor3d_CurveOnSurface  CurvOnS (Acurv,Asurf);
2624         Handle(Adaptor3d_CurveOnSurface) HCons =new Adaptor3d_CurveOnSurface(CurvOnS);
2625         Order.SetValue(n3d,0);
2626         Handle(GeomPlate_CurveConstraint) Cont =
2627           new GeomPlate_CurveConstraint(HCons,Order.Value(n3d),10,tolesp,angular,0.1);
2628         PSurf.Add(Cont);
2629         TopOpeBRepDS_Curve tcurv3d( ctrim,1.e-4);
2630         indcurve3d.SetValue(n3d, DStr.AddCurve(tcurv3d));
2631         Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurve3d.Value(n3d),
2632                                      indpoint1,ufirst,isvt1);
2633         Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurve3d.Value(n3d),
2634                                      indpoint2,ulast,isvt2);
2635         DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append(Interfp1);
2636         DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append(Interfp2);
2637       }
2638   } 
2639  
2640 #ifdef OCCT_DEBUG
2641   ChFi3d_InitChron(ch); // init performances for plate 
2642 #endif
2643
2644   PSurf.Perform();
2645
2646 #ifdef OCCT_DEBUG
2647   ChFi3d_ResultChron(ch, t_plate); //result performances for plate 
2648 #endif 
2649
2650   // call of approx  
2651  
2652 #ifdef OCCT_DEBUG
2653   ChFi3d_InitChron(ch);  // init performances for approxplate
2654 #endif
2655   if (PSurf.IsDone()) {
2656     Standard_Integer nbcarreau=9;
2657     Standard_Integer degmax=8;
2658     Standard_Real seuil;
2659     Handle(GeomPlate_Surface) gpPlate = PSurf.Surface();
2660
2661     TColgp_SequenceOfXY S2d;
2662     TColgp_SequenceOfXYZ S3d;
2663     S2d.Clear();
2664     S3d.Clear();
2665     PSurf.Disc2dContour(4,S2d);
2666     PSurf.Disc3dContour(4,0,S3d);
2667     seuil = Max(tolapp,10*PSurf.G0Error());
2668     GeomPlate_PlateG0Criterion critere (S2d,S3d,seuil);
2669     GeomPlate_MakeApprox Mapp(gpPlate,critere,tolapp,nbcarreau,degmax);
2670     Handle (Geom_Surface) Surf (Mapp.Surface());
2671     Standard_Real coef = 1.1 ,apperror;
2672     apperror=Mapp.CriterionError()*coef;
2673
2674 #ifdef OCCT_DEBUG
2675   ChFi3d_ResultChron(ch, t_approxplate); // result performances for approxplate
2676 #endif
2677   
2678 //  Storage of the surface plate and corresponding curves in the DS 
2679
2680     TopAbs_Orientation orplate,orsurfdata,orpcurve,orien;
2681 #ifdef OCCT_DEBUG
2682 //    Standard_Real ang1=PSurf.G1Error();
2683 #endif
2684 //     gp_Vec n1,n2,du,dv,du1,dv1;
2685 //     gp_Pnt pp,pp1;
2686 //     Standard_Real tpar;
2687 //     gp_Pnt2d uv; 
2688 //     Standard_Real scal;
2689     
2690     TopOpeBRepDS_Surface Tsurf(Surf,Mapp.ApproxError());
2691     Standard_Integer Isurf=DStr.AddSurface(Tsurf);
2692     //lbo : historique QDF.
2693     if(!myEVIMap.IsBound(V1)){
2694       TColStd_ListOfInteger li;
2695       myEVIMap.Bind(V1,li);
2696     }
2697     myEVIMap.ChangeFind(V1).Append(Isurf);
2698   
2699     Standard_Integer SolInd = CD.Value(0)->SolidIndex();
2700     TopOpeBRepDS_ListOfInterference& SolidInterfs = 
2701       DStr.ChangeShapeInterferences(SolInd);
2702  
2703 // in case when one rereads at top, it is necessary that 
2704 // alive edges that arrive at the top should be removed from the DS. 
2705 // For this they are stored in the DS with their inverted orientation 
2706     Standard_Integer nbedge;
2707     TopExp_Explorer ex;
2708     if (deuxconges)
2709       for (ic=0;ic<nedge;ic++) {
2710         if (!sharp.Value(ic)){
2711           nbedge = CD.Value(ic)->Spine()->NbEdges();
2712           TopoDS_Edge Arcspine; 
2713           if (sens.Value(ic) ==1) 
2714             Arcspine=CD.Value(ic) ->Spine()->Edges(1);
2715           else  
2716             Arcspine= CD.Value(ic)->Spine()->Edges(nbedge);
2717           Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2718           TopAbs_Orientation OVtx = TopAbs_FORWARD;
2719           for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); 
2720               ex.More(); ex.Next()){
2721             if(V1.IsSame(ex.Current())) {
2722               OVtx = ex.Current().Orientation();
2723               break;
2724             }
2725           }
2726           OVtx = TopAbs::Reverse(OVtx);
2727           Standard_Real parVtx = BRep_Tool::Parameter(V1,Arcspine);
2728           Handle(TopOpeBRepDS_CurvePointInterference) 
2729             interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2730           DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
2731         }
2732       }
2733     
2734     // calculate orientation of Plate orplate corresponding to surfdata 
2735     // calculation corresponding to the first stripe 
2736     Indices(nedge,0,icplus,icmoins);
2737     isfirst=(sens.Value(0)==1);
2738     const Handle(ChFiDS_SurfData)& Fd = 
2739       CD.Value(0)->SetOfSurfData()->Value(i.Value(0,icmoins));
2740     indice= Fd->Surf();
2741 //    Handle (Geom_Surface) surfdata  = DStr.Surface(indice).Surface();
2742 //     tpar= (CD.Value(0)->PCurve(isfirst)->FirstParameter()+
2743 //       CD.Value(0)->PCurve(isfirst)->LastParameter())/2 ;
2744 //     CD.Value(0)->PCurve(isfirst)->D0(tpar,uv);
2745 //     surfdata->D1(uv.X(),uv.Y(),pp,du,dv);
2746 //     tpar=(PSurf.Curves2d()->Value(1)->FirstParameter()+
2747 //        PSurf.Curves2d()->Value(1)->LastParameter())/2;
2748 //     (PSurf.Curves2d())->Value(1)->D0(tpar,uv);
2749 //     Surf-> D1(uv.X(),uv.Y(),pp1,du1,dv1);
2750 //     n1=du.Crossed(dv);
2751 //     n2=du1.Crossed(dv1);  
2752 //     scal= n1.Dot(n2);
2753     orsurfdata=Fd->Orientation();
2754 //     if (scal>0) orplate=orsurfdata;
2755 //     else  orplate=TopAbs::Reverse(orsurfdata);  
2756     orplate = PlateOrientation(Surf,PSurf.Curves2d(),SumFaceNormalAtV1);
2757     
2758     //  creation of solidinterderence for Plate 
2759     Handle(TopOpeBRepDS_SolidSurfaceInterference) SSI = 
2760       new TopOpeBRepDS_SolidSurfaceInterference(TopOpeBRepDS_Transition(orplate),
2761                                               TopOpeBRepDS_SOLID,
2762                                               SolInd,
2763                                               TopOpeBRepDS_SURFACE,
2764                                               Isurf);
2765     SolidInterfs.Append(SSI);
2766   
2767   // calculate orientation orien of pcurves of Plate
2768   // the curves from ic to icplus the pcurves of Plate 
2769   // all have the same orientation  
2770     Standard_Integer Ishape1,Ishape2; 
2771     TopAbs_Orientation trafil1 = TopAbs_FORWARD, trafil2 = TopAbs_FORWARD;
2772     Ishape1 = Fd->IndexOfS1();
2773     Ishape2 = Fd->IndexOfS2();
2774     const ChFiDS_FaceInterference& Fi1 = Fd->InterferenceOnS1();
2775     const ChFiDS_FaceInterference& Fi2 = Fd->InterferenceOnS2();     
2776     if (Ishape1 != 0) {
2777       if (Ishape1 > 0) {
2778         trafil1 = DStr.Shape(Ishape1).Orientation();
2779       }
2780       trafil1 = TopAbs::Compose(trafil1,Fd->Orientation());
2781       trafil1 = TopAbs::Compose(TopAbs::Reverse(Fi1.Transition()),trafil1);
2782       trafil2 = TopAbs::Reverse(trafil1);
2783     }
2784     else {
2785       if (Ishape2 > 0) {
2786         trafil2 = DStr.Shape(Ishape2).Orientation();
2787       }
2788       trafil2 = TopAbs::Compose(trafil2,Fd->Orientation());
2789       trafil2 = TopAbs::Compose(TopAbs::Reverse(Fi2.Transition()),trafil2);
2790       trafil1 = TopAbs::Reverse(trafil2);
2791     }
2792     if (isfirst) {
2793       orpcurve=TopAbs::Reverse(trafil1);
2794       orpcurve= TopAbs::Compose(orpcurve,CD.Value(0)->FirstPCurveOrientation ()); }
2795     else {
2796       orpcurve=trafil1;
2797       orpcurve= TopAbs::Compose(orpcurve,CD.Value(0)->LastPCurveOrientation ());
2798     }
2799     if (orsurfdata==orplate) 
2800       orien =TopAbs::Reverse(orpcurve);
2801     else  orien=orpcurve; 
2802     
2803     
2804     if (!droit)
2805       for (ic=0;ic<=nedge;ic++) {
2806         if (libre.Value(ic)) {
2807           Standard_Integer icplus21;
2808           Indices(nedge,ic,icplus,icmoins);
2809           Indices(nedge,icplus,icplus21,ic);
2810           gp_Pnt2d UV1,UV2;
2811           Handle (Geom_Curve) C3d;
2812           Handle (Geom2d_Curve) C2d,curv2d;
2813           gp_Pnt ptic,pticplus;
2814           BRepAdaptor_Curve BCurv1(TopoDS::Edge(Evive.Value(ic)));
2815           BRepAdaptor_Curve BCurv2(TopoDS::Edge(Evive.Value(icplus)));
2816           Standard_Real par1=p.Value(ic,icplus);
2817           Standard_Real par2=p.Value(icplus,ic);
2818           BCurv1.D0(par1,ptic);
2819           BCurv2.D0(par2,pticplus);
2820           ParametrePlate(n3d,PSurf,Surf,ptic,apperror,UV1);
2821           ParametrePlate(n3d,PSurf,Surf,pticplus,apperror,UV2);
2822           Standard_Real to3d=1.e-3,to2d=1.e-6,tolreached;
2823           ChFiDS_CommonPoint CP1,CP2;
2824           CP1.SetArc(1.e-3, TopoDS::Edge(Evive.Value(ic)),par1,TopAbs_FORWARD);
2825           CP1.SetPoint(ptic);
2826           CP2.SetArc(1.e-3, TopoDS::Edge(Evive.Value(icplus)),par2,TopAbs_FORWARD);
2827           CP2.SetPoint(pticplus);
2828           Standard_Real param1,param2;
2829           ChFi3d_ComputeArete( CP1,UV1,CP2,UV2,Surf,C3d,C2d,param1,param2, 
2830                               to3d,to2d,tolreached,0);
2831           TopOpeBRepDS_Curve tcurv3d( C3d,tolreached);
2832           Standard_Integer ind1,ind2;
2833           ind1=indpoint(ic,0);
2834           ind2=indpoint(icplus,0);
2835           Standard_Integer indcurv=DStr.AddCurve(tcurv3d);
2836           Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurv,ind1,param1);
2837           Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurv,ind2,param2);
2838           DStr.ChangeCurveInterferences(indcurv).Append(Interfp1);
2839           DStr.ChangeCurveInterferences(indcurv).Append(Interfp2);
2840           Interfc=ChFi3d_FilCurveInDS(indcurv,Isurf,C2d,orien);
2841           DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc);
2842         }
2843   }
2844     
2845     //  stockage des courbes relatives aux stripes  
2846     n3d = 0;
2847     for (ic=0; ic<nedge ;ic++) {
2848       if (!sharp.Value(ic)) {
2849         n3d++;
2850         Indices(nedge,ic,icplus,icmoins);
2851         
2852         isfirst=(sens.Value(ic)==1);
2853       //   calculate curves interference relative to stripes
2854       
2855         apperror=Mapp.CriterionError()*coef;
2856         pardeb=CD.Value(ic)->PCurve(isfirst)->FirstParameter();
2857         parfin=CD.Value(ic)->PCurve(isfirst)->LastParameter();
2858       
2859         Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurve3d.Value(n3d),
2860                                      indpoint.Value(ic,0),pardeb);
2861         Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurve3d.Value(n3d),
2862                                      indpoint.Value(ic,1),parfin);
2863         DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append( Interfp1);
2864         DStr.ChangeCurveInterferences(indcurve3d.Value(n3d)).Append( Interfp2);
2865         TopOpeBRepDS_Curve& tcourb = DStr.ChangeCurve(indcurve3d.Value(n3d));
2866         
2867         tcourb.Tolerance(errapp.Value(ic)+apperror);
2868         TopOpeBRepDS_Point& tpt1= DStr.ChangePoint(indpoint(ic,0));
2869         TopOpeBRepDS_Point& tpt2= DStr.ChangePoint(indpoint(ic,1));
2870         tpt1.Tolerance (tpt1.Tolerance()+apperror);
2871         tpt2.Tolerance (tpt2.Tolerance()+apperror ); 
2872         
2873       // calculate surfaceinterference
2874         Interfc=ChFi3d_FilCurveInDS(indcurve3d.Value(n3d),Isurf,
2875                                   PSurf.Curves2d()->Value(n3d),orien);     
2876         DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc);
2877         regular.SetCurve(indcurve3d.Value(n3d));
2878         regular.SetS1(Isurf,Standard_False);
2879         indice=CD.Value(ic)->SetOfSurfData()->Value( i.Value(ic,icmoins))->Surf();
2880         regular.SetS2(indice,Standard_False);
2881         myRegul.Append(regular);
2882       }
2883     }
2884
2885   // storage of connection curves 
2886
2887     for (ic=0; ic<nedge;ic++) {
2888       Indices(nedge,ic,icplus,icmoins);
2889       if (!oksea.Value(ic)) {
2890         if (sharp.Value(ic) &&!deuxconges) {
2891           // limitation of the alive edge 
2892           TopAbs_Orientation ori;
2893           gp_Pnt Pf,Pl,sommet1;
2894           TopoDS_Vertex Vd = TopExp::FirstVertex(TopoDS::Edge(Evive.Value(ic)));
2895           TopoDS_Vertex Vf = TopExp::LastVertex(TopoDS::Edge(Evive.Value(ic)));
2896           Pf=BRep_Tool::Pnt(Vd);
2897           Pl=BRep_Tool::Pnt(Vf);
2898           sommet1=BRep_Tool::Pnt(V1);
2899           if (Pf.Distance(sommet1)<Pl.Distance(sommet1))
2900             ori = TopAbs_FORWARD;
2901           else
2902             ori = TopAbs_REVERSED;
2903           Standard_Integer Iarc1=DStr.AddShape(TopoDS::Edge(Evive.Value(ic)));
2904           Interfp1=ChFi3d_FilPointInDS(ori,Iarc1,indpoint(ic,1),p.Value(ic,icplus));
2905           DStr.ChangeShapeInterferences(TopoDS::Edge(Evive.Value(ic))).Append(Interfp1);
2906         }
2907         
2908         if (!ponctuel.Value(ic) && !libre.Value(ic)) {
2909           // actual connection
2910           if (!moresurf.Value(ic)){
2911             n3d++;
2912             TopOpeBRepDS_Curve& tcourb1 = DStr.ChangeCurve(indcurve3d.Value(n3d));
2913             tcourb1.Tolerance(tcourb1.Tolerance()+apperror);
2914             if (!deuxconges) {
2915               TopOpeBRepDS_Point& tpt11= DStr.ChangePoint(indpoint(ic,1));
2916               TopOpeBRepDS_Point& tpt21= DStr.ChangePoint(indpoint(icplus,0));
2917               tpt11.Tolerance (tpt11.Tolerance()+apperror);
2918               tpt21.Tolerance (tpt21.Tolerance()+apperror ); 
2919             }
2920             Interfc=ChFi3d_FilCurveInDS(indcurve3d.Value(n3d),Isurf,
2921                                         PSurf.Curves2d()->Value(n3d),orien);
2922             DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc);
2923             if( Order.Value(n3d)==1) {
2924               regular.SetCurve(indcurve3d.Value(n3d));
2925               regular.SetS1(Isurf,Standard_False);
2926               regular.SetS2(numfa.Value(ic,icplus));
2927               myRegul.Append(regular);
2928             }
2929           }
2930         }
2931       }
2932     }
2933
2934   //storage of curves projected on several faces 
2935     for (ic=0; ic<nedge;ic++) {
2936       Indices(nedge,ic,icplus,icmoins);
2937       if (moresurf(ic))
2938         for (nb=1;nb<=nbface;nb++){ 
2939           if (!Eproj.Value(nb).IsNull()) {
2940             n3d++;
2941             TopOpeBRepDS_Curve& tcourb1 = DStr.ChangeCurve(indcurve3d.Value(n3d));
2942             tcourb1.Tolerance(tcourb1.Tolerance()+apperror);
2943             if(Indice.Value(n3d)!=0) {
2944               TopOpeBRepDS_Point& tpt11= DStr.ChangePoint(Indice.Value(n3d));
2945               tpt11.Tolerance (tpt11.Tolerance()+apperror);
2946             }
2947             Interfc=ChFi3d_FilCurveInDS(indcurve3d.Value(n3d),Isurf,
2948                                         PSurf.Curves2d()->Value(n3d),orien);
2949             DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc);
2950             if( Order.Value(n3d)==1) {
2951               regular.SetCurve(indcurve3d.Value(n3d));
2952               regular.SetS1(Isurf,Standard_False);
2953               regular.SetS2(DStr.AddShape(TopoDS::Face(Fproj.Value(nb))));
2954               myRegul.Append(regular);
2955             }  
2956           }
2957         } 
2958     }
2959
2960   // storage of curves in case of tangent free borders 
2961     if (droit)
2962       for (ic=0; ic<nedge;ic++) {
2963         Indices(nedge,ic,icplus,icmoins);  
2964         TopoDS_Edge ecom;
2965         ecom=TopoDS::Edge(Evive.Value(ic));
2966         if (ecom.IsSame(edgelibre1)||ecom.IsSame(edgelibre2)) {
2967           n3d++;
2968           TopOpeBRepDS_Curve& tcourb1 = DStr.ChangeCurve(indcurve3d.Value(n3d));
2969           tcourb1.Tolerance(tcourb1.Tolerance()+apperror);
2970           Interfc=ChFi3d_FilCurveInDS(indcurve3d.Value(n3d),Isurf,
2971                                     PSurf.Curves2d()->Value(n3d),orien);
2972           DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc);
2973         }         
2974       } 
2975   }
2976   else { // there is only one partial result 
2977     done=Standard_False;
2978     hasresult=Standard_True;
2979     for (ic=0; ic<nedge;ic++) {
2980       Indices(nedge,ic,icplus,icmoins);
2981       if (!oksea.Value(ic)) {
2982         if (sharp.Value(ic) &&!deuxconges) {
2983           // limitation of the alive edge
2984           TopAbs_Orientation ori;
2985           gp_Pnt Pf,Pl,sommet1;
2986           TopoDS_Vertex Vd = TopExp::FirstVertex(TopoDS::Edge(Evive.Value(ic)));
2987           TopoDS_Vertex Vf = TopExp::LastVertex(TopoDS::Edge(Evive.Value(ic)));
2988           Pf=BRep_Tool::Pnt(Vd);
2989           Pl=BRep_Tool::Pnt(Vf);
2990           sommet1=BRep_Tool::Pnt(V1);
2991           if (Pf.Distance(sommet1)<Pl.Distance(sommet1))
2992             ori = TopAbs_FORWARD;
2993           else
2994             ori = TopAbs_REVERSED;
2995           Standard_Integer Iarc1=DStr.AddShape(TopoDS::Edge(Evive.Value(ic)));
2996           Interfp1=ChFi3d_FilPointInDS(ori,Iarc1,indpoint(ic,1),p.Value(ic,icplus));
2997           DStr.ChangeShapeInterferences(TopoDS::Edge(Evive.Value(ic))).Append(Interfp1);
2998         }
2999       }
3000     }
3001   }
3002 }