Integration of OCCT 6.5.0 from SVN
[occt.git] / src / ChFi3d / ChFi3d_FilBuilder_C3.cxx
1 // File:        ChFi3d_FilBuilder_C3.cxx
2 // Created:     Wed Apr 26 09:57:13 1995
3 // Author:      Modelistation
4 //              <model@phylox>
5
6
7 #include <ChFi3d_FilBuilder.jxx>
8 #include <ChFi3d_Builder_0.hxx>
9 #include <ChFi3d.hxx>
10
11 #include <Precision.hxx>
12
13 #include <Standard_Failure.hxx>
14 #include <Standard_NotImplemented.hxx>
15 #include <TColStd_ListOfInteger.hxx>
16
17 #include <math_Vector.hxx>
18
19 #include <gp_Pnt.hxx>
20 #include <gp_Vec.hxx>
21 #include <gp_Dir.hxx>
22 #include <gp_Pnt2d.hxx>
23 #include <gp_Ax2.hxx>
24 #include <gp_Ax3.hxx>
25 #include <gp_Lin.hxx>
26 #include <ElCLib.hxx>
27 #include <ElSLib.hxx>
28
29 #include <TColgp_Array1OfPnt2d.hxx>
30
31 #include <Geom_Plane.hxx>
32 #include <Geom_Circle.hxx>
33 #include <Geom_BezierCurve.hxx>
34 #include <Geom2d_BezierCurve.hxx>
35 #include <Geom2d_Curve.hxx>
36 #include <Geom2d_TrimmedCurve.hxx>
37 #include <Geom2d_Line.hxx>
38
39 #include <IntAna_QuadQuadGeo.hxx>
40 #include <IntCurveSurface_IntersectionPoint.hxx>
41
42 #include <TopoDS.hxx>
43 #include <TopoDS_Shape.hxx>
44 #include <TopoDS_Face.hxx>
45 #include <TopoDS_Edge.hxx>
46 #include <TopoDS_Vertex.hxx>
47
48 #include <Adaptor3d_HSurface.hxx>
49 #include <Adaptor3d_CurveOnSurface.hxx>
50 #include <Adaptor3d_TopolTool.hxx>
51 #include <Geom2dAdaptor_Curve.hxx>
52 #include <Geom2dAdaptor_HCurve.hxx>
53 #include <GeomAdaptor_Curve.hxx>
54 #include <GeomAdaptor_HCurve.hxx>
55 #include <GeomAdaptor_Surface.hxx>
56 #include <GeomAdaptor_HSurface.hxx>
57 #include <BRepAdaptor_Curve.hxx>
58 #include <BRepAdaptor_HCurve.hxx>
59 #include <BRepAdaptor_Surface.hxx>
60 #include <BRepAdaptor_HSurface.hxx>
61 #include <BRepTopAdaptor_TopolTool.hxx>
62
63 #include <TopAbs.hxx>
64 #include <TopAbs_Orientation.hxx>
65
66 #include <ChFiDS_SurfData.hxx>
67 #include <ChFiDS_CommonPoint.hxx>
68 #include <ChFiDS_FaceInterference.hxx>
69 #include <ChFiDS_Spine.hxx>
70 #include <ChFiDS_SequenceOfSurfData.hxx>
71 #include <ChFiDS_Stripe.hxx>
72 #include <ChFiDS_HData.hxx>
73 #include <ChFiDS_ListIteratorOfListOfStripe.hxx>
74 #include <ChFiDS_Regul.hxx>
75
76 #include <TopOpeBRepDS_HDataStructure.hxx>
77 #include <TopOpeBRepDS_DataStructure.hxx>
78 #include <TopOpeBRepDS_Curve.hxx>
79 #include <TopOpeBRepDS_Surface.hxx>
80
81 #include <ChFiKPart_ComputeData.hxx>
82 #include <BRepBlend_Line.hxx>
83 #include <BRepBlend_ConstRad.hxx>
84 #include <BRepBlend_ConstRadInv.hxx>
85 #include <BRepBlend_EvolRad.hxx>
86 #include <BRepBlend_EvolRadInv.hxx>
87 #include <Law_S.hxx>
88
89 #ifdef DRAW
90 #include <DrawTrSurf.hxx>
91 #endif
92 #ifdef DEB
93 #include <Geom_TrimmedCurve.hxx>
94 extern Standard_Boolean ChFi3d_GettraceDRAWSPINE();
95 extern Standard_Boolean ChFi3d_GetcontextSPINEBEZIER();
96 extern Standard_Boolean ChFi3d_GetcontextSPINECIRCLE();
97 extern Standard_Boolean ChFi3d_GetcontextSPINECE();
98 extern Standard_Boolean ChFi3d_GetcontextFORCEFILLING();
99 #include <OSD_Chronometer.hxx>
100
101 extern Standard_Real  t_t3cornerinit ,t_spherique,t_torique,
102 t_notfilling,t_filling,t_t3cornerDS;
103 extern void ChFi3d_InitChron(OSD_Chronometer& ch);
104 extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time);
105 #endif
106
107 //=======================================================================
108 //function : SearchPivot
109 //purpose  : 
110 //=======================================================================
111 static Standard_Integer SearchPivot(Standard_Integer* s,
112                                     Standard_Real u[3][3],
113                                     const Standard_Real t)
114 {
115   Standard_Boolean bondeb,bonfin;
116   for(Standard_Integer i = 0; i <= 2; i++){
117     if(s[(i+1)%3] == 1){bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] >= -t);}
118     else {bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] <= t);}
119     if(s[(i+2)%3] == 1){bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] >= -t);}
120     else {bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] <= t);}
121     if (bondeb && bonfin){ return i; }
122   }
123   return -1;
124 }
125
126
127 //=======================================================================
128 //function : SearchFD
129 //purpose  : 
130 //=======================================================================
131 static Standard_Boolean SearchFD(TopOpeBRepDS_DataStructure& DStr,
132                                  const Handle(ChFiDS_Stripe)& cd1, 
133                                  const Handle(ChFiDS_Stripe)& cd2,
134                                  const Standard_Integer sens1,
135                                  const Standard_Integer sens2,
136                                  Standard_Integer& i1,
137                                  Standard_Integer& i2,
138                                  Standard_Real& p1,
139                                  Standard_Real& p2,
140                                  const Standard_Integer ind1,
141                                  const Standard_Integer ind2,
142                                  TopoDS_Face& face,
143                                  Standard_Boolean& sameside,
144                                  Standard_Integer& jf1,
145                                  Standard_Integer& jf2)
146 {
147   Standard_Boolean found = Standard_False;
148   Standard_Integer id1 = ind1, id2 = ind2;
149   Standard_Integer if1 = ind1, if2 = ind2;
150   Standard_Integer l1 = cd1->SetOfSurfData()->Length();
151   Standard_Integer l2 = cd2->SetOfSurfData()->Length();
152   Standard_Integer i;
153   Standard_Boolean fini1 = Standard_False, fini2 = Standard_False;
154   Standard_Boolean visavis;
155   TopoDS_Vertex Vtx;
156   while( !found ){
157     for(i = id1; (i*sens1) <= (if1*sens1) && !found && !fini2; i = i+sens1 ){ 
158       if(ChFi3d_IsInFront(DStr,cd1,cd2,i,if2,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)){
159         i1 = i;
160         i2 = if2;
161         found = Standard_True;
162       }
163     }
164     if(!fini1){
165       if1 = if1 + sens1;
166       if(if1 < 1 || if1 > l1){ if1 = if1 - sens1; fini1 = Standard_True; }
167     }
168     
169     for(i = id2; (i*sens2) <= (if2*sens2) && !found && !fini1; i = i+sens2 ){ 
170       if(ChFi3d_IsInFront(DStr,cd1,cd2,if1,i,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)){
171         i1 = if1;
172         i2 = i;
173         found = Standard_True;
174       }
175     }
176     if(!fini2){
177       if2 = if2 + sens2;
178       if(if2 < 1 || if2 > l2){ if2 = if2 - sens2; fini2 = Standard_True; }
179     }
180     if(fini1 && fini2) break;
181   }
182   return found;
183 }
184
185
186 //=======================================================================
187 //function : ToricCorner
188 //purpose  : Teste si on est dans le cas pariculier d un coin torique 
189 //           (ou spherique limite par des isos).
190 //=======================================================================
191
192 static Standard_Boolean ToricCorner(const TopoDS_Face& F,
193                                     const Standard_Real rd,
194                                     const Standard_Real rf,
195                                     const gp_Vec& v)
196 {
197   if(Abs(rd-rf) > Precision::Confusion()){ return Standard_False; }
198   BRepAdaptor_Surface bs(F);
199   if(bs.GetType() != GeomAbs_Plane){ return Standard_False; }
200   Standard_Real scal1 = Abs(bs.Plane().Position().XDirection().Dot(v));
201   Standard_Real scal2 = Abs(bs.Plane().Position().YDirection().Dot(v));
202   return (scal1 <= Precision::Confusion() && 
203           scal2 <= Precision::Confusion());
204 }
205
206 //=======================================================================
207 //function : PerformThreeCorner
208 //purpose  : Calcul du conge sur un sommet avec trois aretes 
209 //           incidentes portant chacune un conge.
210 //=======================================================================
211
212 void ChFi3d_FilBuilder::PerformThreeCorner(const Standard_Integer Jndex)
213 {
214   
215 #ifdef DEB 
216   OSD_Chronometer ch;
217   ChFi3d_InitChron(ch); // init perf initialisation 
218 #endif 
219   
220   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
221   const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Jndex);
222   ChFiDS_ListIteratorOfListOfStripe It;
223   Standard_Integer Index[3],pivot,deb,fin,ii,jj,kk;
224   //Standard_Real R = 0.;
225   Standard_Boolean pivdif = Standard_True;
226   Standard_Boolean c1pointu = Standard_False;
227   Standard_Boolean c1toric = Standard_False;
228   Standard_Boolean c1spheric = Standard_False;
229   Handle(ChFiDS_Stripe) CD[3];
230   TopoDS_Face face[3];
231   Standard_Integer jf[3][3];
232   Standard_Boolean sameside[3], oksea[3];
233   for(Standard_Integer g = 0; g <= 2; g++){oksea[g] = Standard_False;}
234   Standard_Integer i[3][3];
235   Standard_Integer sens[3];
236   Standard_Real p[3][3];
237   
238   Standard_Boolean filling = 0;
239   
240   for (It.Initialize(myVDataMap(Jndex)),ii=0;It.More() && ii<3;It.Next(),ii++){
241     Index[ii] = ChFi3d_IndexOfSurfData(Vtx,It.Value(),sens[ii]);
242     CD[ii] = It.Value();
243   }
244   // On verifie que l une des CD ne figure pas deux fois, au quel cas 
245   // il faut modifier le retour de IndexOfSurfData qui prend la 
246   // premiere des solutions.
247   if(CD[0] == CD[1]){ 
248     Index[1] = CD[1]->SetOfSurfData()->Length();
249     sens[1] = -1;
250   }
251   else if(CD[1] == CD[2]){ 
252     Index[2] = CD[2]->SetOfSurfData()->Length();
253     sens[2] = -1;
254   }
255   else if(CD[0] == CD[2]){ 
256     Index[2] = CD[2]->SetOfSurfData()->Length();
257     sens[2] = -1;
258   }
259   oksea[2] = SearchFD(DStr,CD[0],CD[1],sens[0],sens[1],i[0][1],i[1][0],
260                       p[0][1],p[1][0],Index[0],Index[1],face[2],sameside[2],
261                       jf[0][1],jf[1][0]);
262   oksea[1] = SearchFD(DStr,CD[0],CD[2],sens[0],sens[2],i[0][2],i[2][0],
263                       p[0][2],p[2][0],Index[0],Index[2],face[1],sameside[1],
264                       jf[0][2],jf[2][0]);
265   oksea[0] = SearchFD(DStr,CD[1],CD[2],sens[1],sens[2],i[1][2],i[2][1],
266                       p[1][2],p[2][1],Index[1],Index[2],face[0],sameside[0],
267                       jf[1][2],jf[2][1]);
268   //
269   // Analyse des concavites des 3 conges :
270   //        - 2 concavites identiques et 1 inverse.
271   //        - 3 concavites identiques
272   //
273   if(oksea[2] && oksea[1] && !sameside[2] && !sameside[1])
274     { pivot = 0; deb = 1; fin = 2;}
275   else if(oksea[2] && oksea[0] && !sameside[2] && !sameside[0])
276     { pivot = 1; deb = 2; fin = 0;}
277   else if(oksea[1] && oksea[0] && !sameside[1] && !sameside[0])
278     { pivot = 2; deb = 0; fin = 1;}
279   else if(oksea[0] && oksea[1] && oksea[2]){ 
280     // 3 concavites identiques.
281     pivot = SearchPivot(sens,p,tol2d);
282     if(pivot < 0){ 
283 #ifdef DEB
284       cout<<"pivot non trouve, on appelle plate"<<endl;
285 #endif
286       PerformMoreThreeCorner(Jndex, 3);
287       return;
288     }
289     else{deb = (pivot+1)%3 ; fin = (pivot+2)%3;}
290     pivdif = Standard_False;
291     if(Abs(p[0][1]-p[0][2]) <= tol2d &&
292        Abs(p[1][0]-p[1][2]) <= tol2d &&
293        Abs(p[2][0]-p[2][1]) <= tol2d){
294       c1pointu = Standard_True;
295     }
296   }
297   else {
298     PerformMoreThreeCorner(Jndex, 3);
299     return;
300   }
301   Standard_Integer ifacdeb, ifacfin;
302   ifacdeb = CD[deb]->ChangeSetOfSurfData()->Value(i[deb][pivot])->Index(3-jf[deb][pivot]);
303   ifacfin = CD[fin]->ChangeSetOfSurfData()->Value(i[fin][pivot])->Index(3-jf[fin][pivot]);
304   if(ifacfin != ifacdeb){
305 #ifdef DEB
306     cout<<"plusieurs faces d'appui, on appelle plate"<<endl;
307 #endif
308     PerformMoreThreeCorner(Jndex, 3);
309     return;
310   }
311   if(i[pivot][deb] != i[pivot][fin]){
312 #ifdef DEB
313     cout<<"changement de surfdata sur le pivot, on appelle plate"<<endl;
314 #endif
315     PerformMoreThreeCorner(Jndex, 3);
316     return;
317   }
318   
319   Standard_Real Rdeb,Rfin,Rdp,Rfp;
320   gp_Pnt Pdeb,Pfin,Pdp,Pfp;
321   gp_Vec Vdeb,Vfin,Vdp,Vfp;
322   if(c1pointu){
323     gp_Pnt pbid;
324     gp_Vec qv[3];
325     Standard_Real qr[3];
326     for(ii = 0; ii<=2; ii++){
327       jj = (ii+1)%3 ; kk = (ii+2)%3;
328       ChFi3d_ExtrSpineCarac(DStr,CD[jj],i[jj][ii],p[jj][ii],1,
329                             sens[jj],pbid,qv[jj],qr[jj]);
330     }
331     for(ii = 0; ii<=2 && !c1toric; ii++){
332       jj = (ii+1)%3 ; kk = (ii+2)%3;
333       if(ToricCorner(face[ii],qr[jj],qr[kk],qv[ii])){
334         c1toric = Standard_True;
335         pivot = ii; deb = jj; fin = kk;
336       }
337     }
338     if(!c1toric)c1spheric=(Abs(qr[0]-qr[1])<tolesp && Abs(qr[0]-qr[2])<tolesp);
339   }
340   
341   //  Autrefois pour eviter les bouclages on mettait toujours les
342   //  points a l interieur, ca pouvait gener la construction de la
343   //  ligne guide du coin qui aujourd hui est un cercle.
344   //  Standard_Integer jjjd = jf[deb][fin], jjjf = jf[fin][deb];
345   //  if (pivdif) jjjd = jf[deb][pivot], jjjf = jf[fin][pivot];
346   Standard_Integer jjjd = jf[deb][pivot], jjjf = jf[fin][pivot];
347   ChFi3d_ExtrSpineCarac(DStr,CD[deb],i[deb][pivot],p[deb][pivot],
348                         jjjd,sens[deb],Pdeb,Vdeb,Rdeb);
349   ChFi3d_ExtrSpineCarac(DStr,CD[fin],i[fin][pivot],p[fin][pivot],
350                         jjjf,sens[fin],Pfin,Vfin,Rfin);
351   ChFi3d_ExtrSpineCarac(DStr,CD[pivot],i[pivot][deb],p[pivot][deb],
352                         0,sens[pivot],Pdp,Vdp,Rdp);
353   ChFi3d_ExtrSpineCarac(DStr,CD[pivot],i[pivot][fin],p[pivot][fin],
354                         0,sens[pivot],Pfp,Vfp,Rfp);
355   //dans le cas allsame on controle que les points sur la face ne 
356   //sont pas trop pres ce qui risque de faire foirer le cheminement.
357   if(!pivdif) {
358     gp_Pnt ptestdeb,ptestfin; gp_Vec bidvec; Standard_Real bidr;
359     ChFi3d_ExtrSpineCarac(DStr,CD[deb],i[deb][pivot],p[deb][pivot],
360                           jf[deb][fin],sens[deb],ptestdeb,bidvec,bidr);
361     ChFi3d_ExtrSpineCarac(DStr,CD[fin],i[fin][pivot],p[fin][pivot],
362                           jf[fin][deb],sens[fin],ptestfin,bidvec,bidr);
363     Standard_Real distest = ptestdeb.Distance(ptestfin);
364     if(distest < (Rdp+Rfp)*0.05) filling = 1;
365     if(distest < (Rdp+Rfp)*0.005) c1pointu = 1;
366   }
367   
368   if(!c1pointu){
369     if (!pivdif) c1pointu = (Abs(p[deb][pivot]-p[deb][fin]) <=tol2d &&
370                              Abs(p[fin][pivot]-p[fin][deb]) <=tol2d);
371     if(Abs(p[pivot][deb] - p[pivot][fin]) <= tol2d)
372       c1toric = ToricCorner(face[pivot],Rdeb,Rfin,Vdp);
373   }
374   // on a le pivot, le CD deb et le CD fin (enfin on espere !?!) :
375   // -------------------------------------------------------------
376   // les criteres determinant si le coin est un tore ou une sphere
377   // sont uniquement fondes sur la configuration des sections en 
378   // bout et la nature des faces, il faudra faire des tests pour 
379   // determiner si une analyse plus subtile des conges incidents
380   // n est pas necessaire pour assurer la tangence entre ceux-ci
381   // et le coin (en particulier dans les cas a rayon variable).
382   
383   
384   
385   Handle(ChFiDS_SurfData)& 
386     fddeb = CD[deb]->ChangeSetOfSurfData()->ChangeValue(i[deb][pivot]);
387   Handle(ChFiDS_SurfData)& 
388     fdfin = CD[fin]->ChangeSetOfSurfData()->ChangeValue(i[fin][pivot]);
389   Handle(ChFiDS_SurfData)& 
390     fdpiv = CD[pivot]->ChangeSetOfSurfData()->ChangeValue(i[pivot][deb]);
391   
392   
393   // On construit les HSurfaces et autres outils qui vont bien.
394   // ----------------------------------------------------------
395   
396   TopAbs_Orientation OFac = face[pivot].Orientation();
397   Handle(BRepAdaptor_HSurface) Fac = new BRepAdaptor_HSurface(face[pivot]);
398   gp_Pnt2d ppp1,ppp2;
399   const ChFiDS_FaceInterference& bid1 = CD[pivot]->SetOfSurfData()->
400     Value(i[pivot][deb])->InterferenceOnS1();
401   ppp1 = bid1.PCurveOnSurf()->Value(bid1.FirstParameter());
402   const ChFiDS_FaceInterference& bid2 = CD[pivot]->SetOfSurfData()->
403     Value(i[pivot][deb])->InterferenceOnS2();
404   ppp2 = bid2.PCurveOnSurf()->Value(bid2.LastParameter());
405   Standard_Real uu1 = ppp1.X(), uu2 = ppp2.X(), vv1 =  ppp1.Y(), vv2 =  ppp2.Y(); 
406   GeomAdaptor_Surface 
407     gasurf((DStr.Surface(CD[pivot]->SetOfSurfData()->
408                          Value(i[pivot][deb])->Surf())).Surface(),
409            uu1, uu2, vv1, vv2);
410   GeomAbs_SurfaceType styp = gasurf.GetType();
411   if(styp == GeomAbs_Cylinder){
412     Standard_Real h = vv2 - vv1;
413     vv1 -= 0.5*h;
414     vv2 += 0.5*h;
415     gasurf.Load((DStr.Surface(CD[pivot]->SetOfSurfData()->
416                               Value(i[pivot][deb])->Surf())).Surface(),
417                 uu1, uu2, vv1, vv2);
418   }
419   else if(styp == GeomAbs_Torus){
420     Standard_Real h = uu2 - uu1;
421     uu1 -= 0.1*h;
422     uu2 += 0.1*h;
423     gasurf.Load((DStr.Surface(CD[pivot]->SetOfSurfData()->
424                               Value(i[pivot][deb])->Surf())).Surface(),
425                 uu1, uu2, vv1, vv2);
426   }
427   else if(styp == GeomAbs_BezierSurface || styp == GeomAbs_BSplineSurface){
428     gasurf.Load((DStr.Surface(CD[pivot]->SetOfSurfData()->
429                               Value(i[pivot][deb])->Surf())).Surface());
430   }
431   
432   Handle(GeomAdaptor_HSurface) Surf = new GeomAdaptor_HSurface(gasurf);
433   //  Handle(BRepTopAdaptor_TopolTool) IFac = new BRepTopAdaptor_TopolTool(Fac);
434   // Essai de ne pas classifier sur la face pour les cas de conges rentrants
435   // qui debordent naturellement.  
436   Handle(GeomAdaptor_HSurface) 
437     bidsurf = new GeomAdaptor_HSurface(Fac->ChangeSurface().Surface());
438   Handle(Adaptor3d_TopolTool) 
439     IFac = new Adaptor3d_TopolTool(bidsurf);
440   // fin de l essai.
441   Handle(Adaptor3d_TopolTool) ISurf = new Adaptor3d_TopolTool(Surf);
442   Handle(ChFiDS_Stripe) corner = new ChFiDS_Stripe();
443   Handle(ChFiDS_HData)& cornerset = corner->ChangeSetOfSurfData();
444   cornerset = new ChFiDS_HData();
445   Handle(ChFiDS_SurfData) coin = new ChFiDS_SurfData();
446   cornerset->Append(coin);
447   TopAbs_Orientation o1,o2,os1,os2,oo1,oo2;
448   Standard_Integer choix = CD[deb]->Choix();
449   o1 = face[pivot].Orientation();
450   o2 = fdpiv->Orientation();
451   oo1 = o1; oo2 = o2;
452   os1 = CD[deb]->OrientationOnFace1();
453   os2 = CD[deb]->OrientationOnFace2();
454   if(jf[deb][fin] == 1){
455     choix = ChFi3d::NextSide(o1,o2,os1,os2,choix);
456     if(sens[deb] == 1){
457       if(choix%2 == 1) choix++;
458       else choix--;
459     }
460   }
461   else {
462     choix = ChFi3d::NextSide(o2,o1,os1,os2,-choix);
463     if(sens[deb] == -1){
464       if(choix%2 == 1) choix++;
465       else choix--;
466     }
467   }
468   
469   gp_Pnt2d pfac1,pfac2,psurf1,psurf2;
470   gp_Vec2d vfac1,vfac2;
471   CD[deb]->SetOfSurfData()->Value(i[deb][pivot])->
472     Interference(jf[deb][fin]).PCurveOnFace()->D1(p[deb][pivot],pfac1,vfac1);
473   CD[fin]->SetOfSurfData()->Value(i[fin][pivot])->
474     Interference(jf[fin][deb]).PCurveOnFace()->D1(p[fin][pivot],pfac2,vfac2);
475   psurf1 = CD[pivot]->SetOfSurfData()->Value(i[pivot][deb])->
476     Interference(jf[pivot][deb]).PCurveOnSurf()->Value(p[pivot][deb]);
477   psurf2 = CD[pivot]->SetOfSurfData()->Value(i[pivot][fin])->
478     Interference(jf[pivot][fin]).PCurveOnSurf()->Value(p[pivot][fin]);
479   
480   done = Standard_False;
481 #ifdef DEB
482   if(ChFi3d_GetcontextFORCEFILLING()) c1spheric = c1toric = 0;
483 #endif
484   
485 #ifdef DEB 
486   ChFi3d_ResultChron(ch , t_t3cornerinit); // result perf initialisations 
487 #endif 
488   
489   if (c1toric){
490     
491 #ifdef DEB 
492     ChFi3d_InitChron(ch); // init perf cas torique 
493 #endif 
494     
495     // Construction directe.
496     // ---------------------
497     done = ChFiKPart_ComputeData::ComputeCorner
498       (DStr,coin,Fac,Surf,oo1,oo2,o1,o2,Rdeb,Rdp,pfac1,pfac2,psurf1,psurf2);
499     
500 #ifdef DEB 
501     ChFi3d_ResultChron(ch , t_torique); // result perf cas torique 
502 #endif 
503     
504   }
505   else if(c1spheric){
506     
507 #ifdef DEB   
508     ChFi3d_InitChron(ch); //init perf cas spherique 
509 #endif 
510     
511     done = ChFiKPart_ComputeData::ComputeCorner
512       (DStr,coin,Fac,Surf,oo1,oo2,o1,o2,Rdp,pfac1,psurf1,psurf2);
513     
514 #ifdef DEB  
515     ChFi3d_ResultChron(ch , t_spherique);// result perf cas spherique 
516 #endif 
517     
518   }
519   else if(c1pointu){
520     filling = 1;
521   }
522   if(!done){
523     if(!filling) {
524       
525 #ifdef DEB   
526       ChFi3d_InitChron(ch);// init perf not filling 
527 #endif
528       
529       //on se calcule une ligne guide,
530       //------------------------------
531       //Problemes nombreux de bouclages et demi-tours lies 
532       //a la courbure de la ligne guide !!!!!! 
533       //POUR L INSTANT CERCLE.
534       //Si un jour on change de nature de ligne guide il faudra
535       //remettre les points Pdeb et Pfin a l interieur (voir le
536       //commentaire a ce sujet a la ligne du calcul de Pdeb et Pfin).
537       
538       Standard_Real radpondere = (Rdp+Rfp)/2.;
539       Standard_Real locfleche = fleche;
540       
541       Standard_Real WFirst,WLast;
542       Handle(Geom_Curve) spinecoin = ChFi3d_CircularSpine(WFirst,WLast,
543                                                           Pdeb,Vdeb,
544                                                           Pfin,Vfin,radpondere);
545       if(spinecoin.IsNull()){
546         // On est dans un cas pourri ou l intersection des plans 
547         // de section se fait en dehors du secteur.
548         spinecoin = ChFi3d_Spine(Pdeb,Vdeb,
549                                  Pfin,Vfin,radpondere);
550         WFirst = 0.; WLast = 1.;
551       }
552       else locfleche = radpondere * (WLast - WFirst) * fleche;
553       Standard_Real pasmax = (WLast-WFirst)*0.05;
554       Handle(ChFiDS_HElSpine) cornerspine = new ChFiDS_HElSpine();
555       cornerspine->ChangeCurve().SetCurve(spinecoin);
556       cornerspine->ChangeCurve().FirstParameter(WFirst - pasmax);
557       cornerspine->ChangeCurve().LastParameter(WLast + pasmax);
558       // Juste pour leurrer le Compute data qui ne doit pas
559       // en avoir besoin dans ce cas precis ...
560       Handle(ChFiDS_Spine) NullSpine;
561       // On calcule le conge : - de deb vers fin 
562       //                       - de la face vers la surface
563       //
564       math_Vector Soldep(1,4);
565       Soldep(1) = pfac1.X();
566       Soldep(2) = pfac1.Y();
567       Soldep(3) = psurf1.X();
568       Soldep(4) = psurf1.Y();
569       
570       Standard_Boolean Gd1,Gd2,Gf1,Gf2;
571       Handle(BRepBlend_Line) lin;
572       Standard_Real ffi = WFirst, lla = WLast + pasmax;
573       
574       if (Abs(Rdeb-Rfin)<=tolesp){
575         
576         BRepBlend_ConstRad func(Fac,Surf,cornerspine);
577         BRepBlend_ConstRadInv finv(Fac,Surf,cornerspine);
578         func.Set(Rdeb,choix);
579         func.Set(myShape);
580         finv.Set(Rdeb,choix);
581         Standard_Real TolGuide = cornerspine->Resolution(tolesp); 
582         
583         Standard_Boolean intf = 3, intl = 3;
584         done = ComputeData(coin,cornerspine,NullSpine,lin,Fac,IFac,Surf,ISurf,
585                            func,finv,ffi,pasmax,locfleche,TolGuide,ffi,lla,
586                            0,0,1,Soldep,intf,intl,Gd1,Gd2,Gf1,Gf2,0,1);
587 #ifdef DEB
588         if(ChFi3d_GetcontextFORCEFILLING()) done = 0;
589 #endif
590         if(done && Gf2){
591           done = CompleteData(coin,func,lin,Fac,Surf,OFac,Gd1,0,Gf1,0);
592           filling = !done;
593         }
594         else filling = 1;
595       }
596       else{
597         Handle(Law_S) law = new Law_S();
598         law->Set(WFirst,Rdeb,WLast,Rfin);
599         BRepBlend_EvolRad func(Fac,Surf,cornerspine,law);
600         BRepBlend_EvolRadInv finv(Fac,Surf,cornerspine,law);
601         func.Set(choix);
602         func.Set(myShape);
603         finv.Set(choix);
604         Standard_Real TolGuide = cornerspine->Resolution(tolesp);
605         Standard_Boolean intf = 3, intl = 3;
606         done = ComputeData(coin,cornerspine,NullSpine,lin,Fac,IFac,Surf,ISurf,
607                            func,finv,ffi,pasmax,locfleche,TolGuide,ffi,lla,
608                            0,0,1,Soldep,intf,intl,Gd1,Gd2,Gf1,Gf2,0,1);
609 #ifdef DEB
610         if(ChFi3d_GetcontextFORCEFILLING()) done = 0;
611 #endif
612         if(done && Gf2){
613           done = CompleteData(coin,func,lin,Fac,Surf,OFac,Gd1,0,Gf1,0);
614           filling = !done;
615         }
616         else filling = 1;
617       }
618       
619 #ifdef DEB  
620       ChFi3d_ResultChron(ch , t_notfilling);// result perf not filling 
621 #endif
622       
623     }
624     
625     if(filling) {
626       
627 #ifdef DEB    
628       ChFi3d_InitChron(ch); // init perf filling
629 #endif
630       
631       // le contour a remplir est constitue de droites uv sur deb et fin
632       // de deux pcurves (une seule si c1pointu) calculees comme on peut
633       // sur piv et la face opposee.
634       Handle(GeomFill_Boundary) Bdeb,Bfin,Bpiv,Bfac;
635       Handle(Geom2d_Curve) PCurveOnFace;
636       if(!c1pointu) 
637         Bfac = ChFi3d_mkbound(Fac,PCurveOnFace,sens[deb],pfac1,vfac1,
638                               sens[fin],pfac2,vfac2,tolesp,2.e-4);
639       Standard_Integer kkk;
640       gp_Pnt ppbid;
641       gp_Vec vp1,vp2;
642       kkk = CD[deb]->SetOfSurfData()->Value(i[deb][pivot])->
643         Interference(jf[deb][pivot]).LineIndex();
644       DStr.Curve(kkk).Curve()->D1(p[deb][pivot],ppbid,vp1);
645       kkk = CD[fin]->SetOfSurfData()->Value(i[fin][pivot])->
646         Interference(jf[fin][pivot]).LineIndex();
647       DStr.Curve(kkk).Curve()->D1(p[fin][pivot],ppbid,vp2);
648       Handle(Geom2d_Curve) PCurveOnPiv;
649 //      Bpiv = ChFi3d_mkbound(Surf,PCurveOnPiv,sens[deb],psurf1,vp1,
650 //                          sens[fin],psurf2,vp2,tolesp,2.e-4);
651       Bpiv = ChFi3d_mkbound(Surf,PCurveOnPiv,psurf1,psurf2,tolesp,2.e-4,0);
652       Standard_Real pardeb2 = p[deb][pivot];
653       Standard_Real parfin2 = p[fin][pivot];
654       if(c1pointu){
655         pardeb2 = p[deb][fin];
656         parfin2 = p[fin][deb];
657       }
658       gp_Pnt2d pdeb1 = CD[deb]->SetOfSurfData()->Value(i[deb][pivot])->
659         Interference(jf[deb][pivot]).PCurveOnSurf()->Value(p[deb][pivot]);
660       gp_Pnt2d pdeb2 = CD[deb]->SetOfSurfData()->Value(i[deb][pivot])->
661         Interference(jf[deb][fin]).PCurveOnSurf()->Value(pardeb2);
662       gp_Pnt2d pfin1 = CD[fin]->SetOfSurfData()->Value(i[fin][pivot])->
663         Interference(jf[fin][pivot]).PCurveOnSurf()->Value(p[fin][pivot]);
664       gp_Pnt2d pfin2 = CD[fin]->SetOfSurfData()->Value(i[fin][pivot])->
665         Interference(jf[fin][deb]).PCurveOnSurf()->Value(parfin2);
666       Handle(Geom_Surface) sdeb = 
667         DStr.Surface(CD[deb]->SetOfSurfData()->
668                      Value(i[deb][pivot])->Surf()).Surface();
669       Handle(Geom_Surface) sfin = 
670         DStr.Surface(CD[fin]->SetOfSurfData()->
671                      Value(i[fin][pivot])->Surf()).Surface();
672       
673       Bdeb = ChFi3d_mkbound(sdeb,pdeb1,pdeb2,tolesp,2.e-4);
674       Bfin = ChFi3d_mkbound(sfin,pfin1,pfin2,tolesp,2.e-4);
675       
676       GeomFill_ConstrainedFilling fil(11,20);
677       if(c1pointu) fil.Init(Bpiv,Bfin,Bdeb,1);
678       else fil.Init(Bpiv,Bfin,Bfac,Bdeb,1);
679       
680       Handle(Geom_Surface) Surfcoin = fil.Surface();
681       Surfcoin->VReverse(); // on se ramene au sens face surf;
682       done = CompleteData(coin,Surfcoin,
683                           Fac,PCurveOnFace,
684                           Surf,PCurveOnPiv,fdpiv->Orientation(),0,
685                           0,0,0,0);
686       
687 #ifdef DEB 
688       ChFi3d_ResultChron(ch , t_filling);// result perf filling 
689 #endif 
690       
691     }
692   }
693   Standard_Real P1deb,P2deb,P1fin,P2fin;
694   if(!c1pointu){
695     p[deb][fin] = p[deb][pivot];
696     p[fin][deb] = p[fin][pivot];
697   }
698   
699   if (done){    
700     // Mise a jour des 4 Stripes et de la DS
701     // -------------------------------------
702     
703 #ifdef DEB  
704     ChFi3d_InitChron(ch);// init perf mise a jour DS
705 #endif 
706     
707     gp_Pnt2d pp1,pp2;
708     Standard_Real parpp1,parpp2;
709     Standard_Integer If1,If2,Il1,Il2,Icf,Icl;
710     const ChFiDS_CommonPoint& Pf1 = coin->VertexFirstOnS1();
711     const ChFiDS_CommonPoint& Pf2 = coin->VertexFirstOnS2();
712     ChFiDS_CommonPoint& Pl1 = coin->ChangeVertexLastOnS1();
713     if(c1pointu) Pl1 = coin->ChangeVertexFirstOnS1();
714     const ChFiDS_CommonPoint& Pl2 = coin->VertexLastOnS2();
715     
716     Bnd_Box bf1,bl1,bf2,bl2;
717     Bnd_Box *pbf1 = &bf1,*pbl1 = &bl1,*pbf2 = &bf2,*pbl2 = &bl2;
718     if(c1pointu) pbl1 = pbf1;
719     pbf1->Add(Pf1.Point());pbf2->Add(Pf2.Point());
720     pbl1->Add(Pl1.Point());pbl2->Add(Pl2.Point());
721     
722     // le coin pour commencer,
723     // -----------------------
724     ChFiDS_Regul regdeb, regfin;
725     If1 = ChFi3d_IndexPointInDS(Pf1,DStr);
726     If2 = ChFi3d_IndexPointInDS(Pf2,DStr);
727     if(c1pointu) Il1 = If1;
728     else Il1 = ChFi3d_IndexPointInDS(Pl1,DStr);
729     Il2 = ChFi3d_IndexPointInDS(Pl2,DStr);
730     pp1 = coin->InterferenceOnS1().PCurveOnSurf()->
731       Value(coin->InterferenceOnS1().FirstParameter());
732     pp2 = coin->InterferenceOnS2().PCurveOnSurf()->
733       Value(coin->InterferenceOnS2().FirstParameter());
734     if(c1pointu) coin->ChangeIndexOfS1(0);
735     else coin->ChangeIndexOfS1(DStr.AddShape(face[pivot]));
736     coin->ChangeIndexOfS2(-fdpiv->Surf());
737     
738     Handle(Geom_Curve) C3d;
739     Standard_Real tolreached;
740     ChFi3d_ComputeArete(Pf1,pp1,Pf2,pp2,
741                         DStr.Surface(coin->Surf()).Surface(),C3d,
742                         corner->ChangeFirstPCurve(),P1deb,P2deb,
743                         tolesp,tol2d,tolreached,0);
744     TopOpeBRepDS_Curve Tcurv1(C3d,tolreached);
745     Icf = DStr.AddCurve(Tcurv1);
746     regdeb.SetCurve(Icf);
747     regdeb.SetS1(coin->Surf(),0);
748     regdeb.SetS2(fddeb->Surf(),0);
749     myRegul.Append(regdeb);
750     corner->ChangeFirstCurve(Icf);
751     corner->ChangeFirstParameters(P1deb,P2deb);
752     corner->ChangeIndexFirstPointOnS1(If1);
753     corner->ChangeIndexFirstPointOnS2(If2);
754     ChFi3d_EnlargeBox(DStr,corner,coin,*pbf1,*pbf2,1);
755     
756     pp1 = coin->InterferenceOnS1().PCurveOnSurf()->
757       Value(coin->InterferenceOnS1().LastParameter());
758     pp2 = coin->InterferenceOnS2().PCurveOnSurf()->
759       Value(coin->InterferenceOnS2().LastParameter());
760     ChFi3d_ComputeArete(Pl1,pp1,Pl2,pp2,
761                         DStr.Surface(coin->Surf()).Surface(),C3d,
762                         corner->ChangeLastPCurve(),P1fin,P2fin,
763                         tolesp,tol2d,tolreached,0);
764     TopOpeBRepDS_Curve Tcurv2(C3d,tolreached);
765     Icl = DStr.AddCurve(Tcurv2);
766     regfin.SetCurve(Icl);
767     regfin.SetS1(coin->Surf(),0);
768     regfin.SetS2(fdfin->Surf(),0);
769     myRegul.Append(regfin);
770     corner->ChangeLastCurve(Icl);
771     corner->ChangeLastParameters(P1fin,P2fin);
772     corner->ChangeIndexLastPointOnS1(Il1);
773     corner->ChangeIndexLastPointOnS2(Il2);
774     ChFi3d_EnlargeBox(DStr,corner,coin,*pbl1,*pbl2,0);
775     
776     // puis la CornerData du debut,
777     // ----------------------------
778     Standard_Boolean isfirst = (sens[deb] == 1), rev = (jf[deb][fin] == 2);
779     Standard_Integer isurf1 = 1, isurf2 = 2;
780     parpp1 = p[deb][fin]; parpp2 = p[deb][pivot]; 
781     if (rev) { 
782       isurf1 = 2; isurf2 = 1; 
783       parpp1 = p[deb][pivot]; parpp2 = p[deb][fin]; 
784       CD[deb]->SetOrientation(TopAbs_REVERSED,isfirst);
785     }
786     pp1 = fddeb->InterferenceOnS1().PCurveOnSurf()->Value(parpp1);
787     pp2 = fddeb->InterferenceOnS2().PCurveOnSurf()->Value(parpp2);
788     CD[deb]->SetCurve(Icf,isfirst);
789     CD[deb]->SetIndexPoint(If1,isfirst,isurf1);
790     CD[deb]->SetIndexPoint(If2,isfirst,isurf2);
791     CD[deb]->SetParameters(isfirst,P1deb,P2deb);
792     fddeb->ChangeVertex(isfirst,isurf1) = Pf1;
793     fddeb->ChangeVertex(isfirst,isurf2) = Pf2;
794     fddeb->ChangeInterferenceOnS1().SetParameter(parpp1,isfirst);
795     fddeb->ChangeInterferenceOnS2().SetParameter(parpp2,isfirst);
796     TopOpeBRepDS_Curve& tcdeb = DStr.ChangeCurve(Icf);
797     Handle(Geom_Curve) crefdeb = tcdeb.Curve();
798     Standard_Real tolrdeb;
799     ChFi3d_ComputePCurv(crefdeb,pp1,pp2,CD[deb]->ChangePCurve(isfirst),
800                         DStr.Surface(fddeb->Surf()).Surface(),
801                         P1deb,P2deb,tolesp,tolrdeb,rev);
802     tcdeb.Tolerance(Max(tolrdeb,tcdeb.Tolerance()));
803     if(rev) ChFi3d_EnlargeBox(DStr,CD[deb],fddeb,*pbf2,*pbf1,isfirst);
804     else ChFi3d_EnlargeBox(DStr,CD[deb],fddeb,*pbf1,*pbf2,isfirst);
805     
806     // puis la CornerData de la fin,
807     // -----------------------------
808     isfirst = (sens[fin] == 1); rev = (jf[fin][deb] == 2);
809     isurf1 = 1; isurf2 = 2;
810     parpp1 = p[fin][deb]; parpp2 = p[fin][pivot]; 
811     if (rev) { 
812       isurf1 = 2; isurf2 = 1; 
813       parpp1 = p[fin][pivot]; parpp2 = p[fin][deb]; 
814       CD[fin]->SetOrientation(TopAbs_REVERSED,isfirst);
815     }
816     pp1 = fdfin->InterferenceOnS1().PCurveOnSurf()->Value(parpp1);
817     pp2 = fdfin->InterferenceOnS2().PCurveOnSurf()->Value(parpp2);
818     CD[fin]->SetCurve(Icl,isfirst);
819     CD[fin]->SetIndexPoint(Il1,isfirst,isurf1);
820     CD[fin]->SetIndexPoint(Il2,isfirst,isurf2);
821     CD[fin]->SetParameters(isfirst,P1fin,P2fin);
822     fdfin->ChangeVertex(isfirst,isurf1) = Pl1;
823     fdfin->ChangeVertex(isfirst,isurf2) = Pl2;
824     fdfin->ChangeInterferenceOnS1().SetParameter(parpp1,isfirst);
825     fdfin->ChangeInterferenceOnS2().SetParameter(parpp2,isfirst);
826     TopOpeBRepDS_Curve& tcfin = DStr.ChangeCurve(Icl);
827     Handle(Geom_Curve) creffin = tcfin.Curve();
828     Standard_Real tolrfin;
829     ChFi3d_ComputePCurv(creffin,pp1,pp2,CD[fin]->ChangePCurve(isfirst),
830                         DStr.Surface(fdfin->Surf()).Surface(),
831                         P1fin,P2fin,tolesp,tolrfin,rev);
832     tcfin.Tolerance(Max(tolrfin,tcfin.Tolerance()));
833     if(rev) ChFi3d_EnlargeBox(DStr,CD[fin],fdfin,*pbl2,*pbl1,isfirst);
834     else ChFi3d_EnlargeBox(DStr,CD[fin],fdfin,*pbl1,*pbl2,isfirst);
835     
836     // et enfin le pivot.
837     // ------------------
838     ChFiDS_FaceInterference& fi = coin->ChangeInterferenceOnS2();
839     isfirst = (sens[pivot] == 1); rev = (jf[pivot][deb] == 2);
840     isurf1 = 1; isurf2 = 2;
841     if (rev) { 
842       isurf1 = 2; isurf2 = 1; 
843       CD[pivot]->SetOrientation(TopAbs_REVERSED,isfirst);
844     }
845     Standard_Integer ICcoinpiv = fi.LineIndex();
846     TopOpeBRepDS_Curve& TCcoinpiv = DStr.ChangeCurve(ICcoinpiv);
847     CD[pivot]->SetCurve(ICcoinpiv,isfirst);
848     Handle(Geom_Curve) Ccoinpiv = DStr.Curve(ICcoinpiv).Curve();
849     Handle(Geom2d_Curve)& C2dOnPiv = fi.ChangePCurveOnFace();
850     Handle(Geom_Surface) Spiv = DStr.Surface(fdpiv->Surf()).Surface();
851     Standard_Real tolr;
852     ChFi3d_SameParameter(Ccoinpiv,C2dOnPiv,Spiv,
853                          fi.FirstParameter(),fi.LastParameter(),
854                          tolesp,tolr);
855     TCcoinpiv.Tolerance(Max(TCcoinpiv.Tolerance(),tolr));
856     CD[pivot]->ChangePCurve(isfirst) = C2dOnPiv;
857     CD[pivot]->SetIndexPoint(If2,isfirst,isurf1);
858     CD[pivot]->SetIndexPoint(Il2,isfirst,isurf2);
859     CD[pivot]->SetParameters(isfirst,fi.FirstParameter(),fi.LastParameter());
860     fdpiv->ChangeVertex(isfirst,isurf1) = Pf2;
861     fdpiv->ChangeVertex(isfirst,isurf2) = Pl2;
862     fdpiv->ChangeInterference(isurf1).SetParameter(p[pivot][deb],isfirst);
863     fdpiv->ChangeInterference(isurf2).SetParameter(p[pivot][fin],isfirst);
864     CD[pivot]->InDS(isfirst); // filDS fait deja le boulot depuis le coin.
865     if(rev) ChFi3d_EnlargeBox(DStr,CD[pivot],fdpiv,*pbl2,*pbf2,isfirst);
866     else ChFi3d_EnlargeBox(DStr,CD[pivot],fdpiv,*pbf2,*pbl2,isfirst);
867     
868     //Pour finir on recale les tolerances des points.
869     ChFi3d_SetPointTolerance(DStr,*pbf1,If1);
870     ChFi3d_SetPointTolerance(DStr,*pbf2,If2);
871     ChFi3d_SetPointTolerance(DStr,*pbl1,Il1);
872     ChFi3d_SetPointTolerance(DStr,*pbl2,Il2);
873   }
874   
875   //On tronque les corners data et met a jour les index.
876   //----------------------------------------------------
877   
878   if(i[deb][pivot] < Index[deb]){
879     CD[deb]->ChangeSetOfSurfData()->Remove(i[deb][pivot]+1,Index[deb]);
880     Index[deb] = i[deb][pivot];
881   }
882   else if(i[deb][pivot] > Index[deb]) {
883     CD[deb]->ChangeSetOfSurfData()->Remove(Index[deb],i[deb][pivot]-1);
884     i[deb][pivot] = Index[deb]; 
885   }
886   if(i[fin][pivot] < Index[fin]) {
887     CD[fin]->ChangeSetOfSurfData()->Remove(i[fin][pivot]+1,Index[fin]);
888     Index[fin] = i[fin][pivot];
889   }
890   else if(i[fin][pivot] > Index[fin]) {
891     CD[fin]->ChangeSetOfSurfData()->Remove(Index[fin],i[fin][pivot]-1);
892     i[fin][pivot] = Index[fin]; 
893   }
894   // il faudra ici tenir compte des coins mutants.
895   if(i[pivot][deb] < Index[pivot]) {
896     CD[pivot]->ChangeSetOfSurfData()->Remove(i[pivot][deb]+1,Index[pivot]);
897     Index[pivot] = i[pivot][deb];
898   }
899   else if(i[pivot][deb] > Index[pivot]) {
900     CD[pivot]->ChangeSetOfSurfData()->Remove(Index[pivot],i[pivot][deb]-1);
901     i[pivot][deb] = Index[pivot]; 
902   }
903   if(!myEVIMap.IsBound(Vtx)){
904     TColStd_ListOfInteger li;
905     myEVIMap.Bind(Vtx,li);
906   }
907   myEVIMap.ChangeFind(Vtx).Append(coin->Surf());
908   corner->SetSolidIndex(CD[pivot]->SolidIndex());
909   myListStripe.Append(corner);
910   
911 #ifdef DEB  
912   ChFi3d_ResultChron(ch , t_t3cornerDS);// result perf mise a jour DS
913 #endif 
914 }