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