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