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