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