d0a9966fa15d2c5dcc600b2d3f699fc74c14f7b5
[occt.git] / src / ChFi3d / ChFi3d_ChBuilder_C3.cxx
1 // Created on: 1995-07-04
2 // Created by: Stagiaire Flore Lantheaume
3 // Copyright (c) 1995-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 #include <StdFail_NotDone.hxx>
18 #include <Standard_ConstructionError.hxx>
19 #include <Standard_NotImplemented.hxx>
20
21 #include <TColStd_ListOfInteger.hxx>
22 #include <ChFi3d_ChBuilder.jxx>
23 #include <ChFi3d_Builder_0.hxx>
24
25 #include <ChFiKPart_ComputeData_Fcts.hxx>
26
27 #include <ChFiDS_HData.hxx>
28 #include <ChFiDS_ListIteratorOfListOfStripe.hxx>
29 #include <ChFiDS_Stripe.hxx>
30 #include <ChFiDS_Spine.hxx>
31 #include <ChFiDS_ChamfSpine.hxx>
32 #include <ChFiDS_SurfData.hxx>
33 #include <ChFiDS_Regul.hxx>
34
35 #include <gp.hxx>
36 #include <gp_Pnt.hxx>
37 #include <gp_Pnt2d.hxx>
38 #include <gp_Vec.hxx>
39 #include <gp_Dir.hxx>
40 #include <gp_Vec2d.hxx>
41 #include <gp_Dir2d.hxx>
42 #include <gp_Lin2d.hxx>
43
44 #include <GeomAbs_SurfaceType.hxx>
45 #include <Geom_Curve.hxx>
46 #include <Geom2d_Curve.hxx>
47 #include <Geom_Surface.hxx>
48 #include <Geom_Plane.hxx>
49 #include <Geom2d_Line.hxx>
50 #include <Geom_Line.hxx>
51 #include <GeomAdaptor_HSurface.hxx>
52
53 #include <BRepAdaptor_Surface.hxx>
54 #include <Geom2dAdaptor_Curve.hxx>
55 #include <Geom2dAdaptor_HCurve.hxx>
56 #include <IntRes2d_IntersectionPoint.hxx>
57 #include <Geom2dInt_GInter.hxx>
58
59 #include <GeomInt_IntSS.hxx>
60 #include <GeomAdaptor_HCurve.hxx>
61 #include <Geom_TrimmedCurve.hxx>
62 #include <GeomAPI_ProjectPointOnSurf.hxx>
63 #include <GeomAPI_ProjectPointOnCurve.hxx>
64
65 #include <TopOpeBRepDS_HDataStructure.hxx>
66
67 #include <TopOpeBRepDS_DataStructure.hxx>
68 #include <BRepAdaptor_HSurface.hxx>
69 #include <BRep_Tool.hxx>
70 #include <BRepLib_MakeEdge.hxx>
71
72 #include <ProjLib_ProjectedCurve.hxx>
73
74 #include <ElSLib.hxx>
75 #include <ElCLib.hxx>
76 #include <IntCurveSurface_HInter.hxx>
77 #include <IntCurveSurface_IntersectionPoint.hxx>
78
79
80 #include <Precision.hxx>
81
82
83
84
85 //=======================================================================
86 //function : CoPlanar
87 //purpose  : Sert a savoir si 4 points sont coplanaires, pour cela on calcul
88 //           la distance de PntD par rapport au plan passant par les trois 
89 //           points PntA, PntB, PntC
90 //=======================================================================
91
92 static int CoPlanar(const gp_Pnt  PntA,
93                     const gp_Pnt  PntB,
94                     const gp_Pnt  PntC,
95                     const gp_Pnt  PntD)
96 {
97   Standard_Boolean IsCoplanar;
98
99   gp_Vec vecAB(PntA, PntB);
100   gp_Vec vecAC(PntA, PntC);
101   gp_Vec vecAD(PntA, PntD);
102
103   Standard_Real nor2AB  = vecAB.SquareMagnitude();
104   Standard_Real nor2AC  = vecAC.SquareMagnitude();
105   Standard_Real ProABAC = vecAB.Dot(vecAC);
106
107
108   Standard_Real Alpha  = nor2AB * nor2AC - ProABAC * ProABAC;
109
110   if (Alpha < Precision::Confusion()) {
111     IsCoplanar = Standard_True;
112   }
113   else {
114     Standard_Real ProABAD = vecAB.Dot(vecAD);
115     Standard_Real ProACAD = vecAC.Dot(vecAD);
116     Standard_Real Alpha1 = ProABAD * nor2AC - ProABAC * ProACAD;
117     Standard_Real Alpha2 = ProACAD * nor2AB - ProABAC * ProABAD;
118     gp_Vec vecDABC = Alpha1 * vecAB + Alpha2 * vecAC - Alpha * vecAD;
119
120     IsCoplanar = (vecDABC.Magnitude() / Alpha < Precision::Confusion() );
121
122   }
123
124   return IsCoplanar;
125 }
126
127
128
129
130 //=======================================================================
131 //function : BoundSurf
132 //purpose  : computes a GeomAdaptor_Surface from the surface and trims
133 //           it to allow the intersection computation
134 //=======================================================================
135
136 static Handle(GeomAdaptor_HSurface) BoundSurf(const Handle(Geom_Surface)& S,
137                                               const gp_Pnt2d& Pdeb,
138                                               const gp_Pnt2d& Pfin)
139 {
140   Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface();
141   GeomAdaptor_Surface& GAS = HS->ChangeSurface();
142   GAS.Load(S);
143
144   Standard_Real uu1,uu2,vv1,vv2;
145   Standard_Real uuu1,uuu2,vvv1,vvv2;
146   S->Bounds(uuu1,uuu2,vvv1,vvv2);
147   ChFi3d_Boite(Pdeb,Pfin,uu1,uu2,vv1,vv2);
148   Standard_Real Step = Max((uu2-uu1),(vv2-vv1));
149   Step *= 0.2;
150   uuu1 = Max((uu1-Step),uuu1);  uuu2 = Min((uu2+Step),uuu2);
151   vvv1 = Max((vv1-Step),vvv1);  vvv2 = Min((vv2+Step),vvv2);
152   GAS.Load(S,uuu1,uuu2,vvv1,vvv2);
153   return HS;
154 }
155
156 //=======================================================================
157 //function : ComputeIntersection
158 //purpose  : compute the 3d curve <gc> and the pcurves <pc1> and <pc2>
159 //           of the intersection between one of the 3 SurfData <SD> and 
160 //           the SurfData of the corner <SDCoin>. Here we know the 
161 //           extremities of the intersection <pdeb> and <pfin>, and
162 //           their parameters <p2dfin>, <p2ddeb> on <SD>.
163 //           <ptcoindeb> cointains the intersection 2d point on the corner
164 //            which corresponds to the point <pdeb>
165 //           <derudeb> and <dervdeb> are the derivative vectors on the 
166 //            SurfData <SD> at the point <ptdeb>
167 //=======================================================================
168
169 static Standard_Boolean ComputeIntersection(TopOpeBRepDS_DataStructure&    DStr,
170                                             const Handle(ChFiDS_SurfData)& SD,
171                                             const Handle(ChFiDS_SurfData)& SDCoin,
172                                             const gp_Pnt&                  pdeb,
173                                             const gp_Pnt2d&                p2ddeb,
174                                             const gp_Pnt&                  pfin,
175                                             const gp_Pnt2d&                p2dfin,
176                                             Handle(Geom_Curve)&            gc,
177                                             Handle(Geom2d_Curve)&          pc1,
178                                             Handle(Geom2d_Curve)&          pc2,
179                                             gp_Vec&                        derudeb,
180                                             gp_Vec&                        dervdeb,
181                                             gp_Pnt2d&                      ptcoindeb,
182                                             const Standard_Real            tol3d,
183                                             const Standard_Real            tol2d,
184                                             Standard_Real&                 tolreached)
185 {
186 //  gp_Pnt2d UVf1,UVf2,UVl1,UVl2;
187
188     // take the surface of the pivot SurfData and trim it to allow
189     // the intersection computation if it's an analytic surface
190   Handle(GeomAdaptor_HSurface) HS1;
191   HS1 = ChFi3d_BoundSurf(DStr,SD,1,2);
192
193   const Handle(Geom_Surface)& gpl = DStr.Surface(SDCoin->Surf()).Surface();
194   const Handle(Geom_Surface)& gSD = DStr.Surface(SD->Surf()).Surface();
195
196     // compute pardeb
197   TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4);
198   Standard_Real u,v;
199   gp_Pnt Pbidon;
200   u = p2ddeb.X();
201   v = p2ddeb.Y();
202   gSD->D1(u,v,Pbidon,derudeb,dervdeb);
203   Pardeb(1) = u;
204   Pardeb(2) = v;
205 //  gp_Pnt2d pd2(u,v);
206
207   ChFi3d_Parameters(gpl,pdeb,u,v);
208   Pardeb(3) = u;
209   Pardeb(4) = v;
210   ptcoindeb.SetCoord(u,v);
211
212     // compute parfin
213   u = p2dfin.X();
214   v = p2dfin.Y();
215   Parfin(1) = u;
216   Parfin(2) = v;
217 //  gp_Pnt2d pf2(u,v);
218
219   ChFi3d_Parameters(gpl,pfin,u,v);
220   Parfin(3) = u; 
221   Parfin(4) = v;
222   gp_Pnt2d cpf2(u,v);
223
224   // Trims the chamfer surface to allow the intersection computation
225   // and computes a GeomAdaptor_Surface for using the ComputeCurves
226   // function
227   Handle(GeomAdaptor_HSurface) HS2;
228   HS2 = BoundSurf(gpl,ptcoindeb,cpf2);
229   
230   // compute the intersection curves and pcurves
231   return ChFi3d_ComputeCurves(HS1,HS2,Pardeb,Parfin,gc,
232                               pc1,pc2,tol3d,tol2d,tolreached);
233 }
234
235 //======================================================================
236 // function : PerformThreeCorner
237 // purpose  : compute the intersection of three chamfers on a same 
238 //            vertex of index <Jndex> in myVDataMap
239 //======================================================================
240
241 void ChFi3d_ChBuilder::PerformThreeCorner(const Standard_Integer Jndex) 
242 {
243
244   //modifier pour le passer en option dans le cdl!!!!!!!!!!!!
245   Standard_Boolean issmooth = Standard_False;
246
247   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
248   const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Jndex);
249   ChFiDS_ListIteratorOfListOfStripe It;
250 //  Standard_Integer Index[3],pivot,deb,fin,ii,jj,kk;
251   Standard_Integer Index[3],pivot=0,deb=0,fin=0,ii;
252   Handle(ChFiDS_Stripe) CD[3];
253   TopoDS_Face face[3];
254   Standard_Integer jf[3][3];
255   Standard_Boolean sameside[3], oksea[3];
256   for(Standard_Integer g = 0; g <= 2; g++){oksea[g] = Standard_False;}
257   Standard_Integer i[3][3];
258   Standard_Integer sens[3];
259   Standard_Real p[3][3];
260
261   Standard_Boolean c1triangle = Standard_False;
262   
263   for (It.Initialize(myVDataMap(Jndex)),ii=0;It.More() && ii<3;It.Next(),ii++){
264     Index[ii] = ChFi3d_IndexOfSurfData(Vtx,It.Value(),sens[ii]);
265     CD[ii] = It.Value();
266   }
267   // On verifie que l une des CD ne figure pas deux fois, au quel cas 
268   // il faut modifier le retour de IndexOfSurfData qui prend la 
269   // premiere des solutions.
270   if(CD[0] == CD[1]){ 
271     Index[1] = CD[1]->SetOfSurfData()->Length();
272     sens[1] = -1;
273   }
274   else if(CD[1] == CD[2]){ 
275     Index[2] = CD[2]->SetOfSurfData()->Length();
276     sens[2] = -1;
277   }
278   else if(CD[0] == CD[2]){ 
279     Index[2] = CD[2]->SetOfSurfData()->Length();
280     sens[2] = -1;
281   }
282   oksea[2] = ChFi3d_SearchFD(DStr,CD[0],CD[1],sens[0],sens[1],i[0][1],i[1][0],
283                       p[0][1],p[1][0],Index[0],Index[1],face[2],sameside[2],
284                       jf[0][1],jf[1][0]);
285   oksea[1] = ChFi3d_SearchFD(DStr,CD[0],CD[2],sens[0],sens[2],i[0][2],i[2][0],
286                       p[0][2],p[2][0],Index[0],Index[2],face[1],sameside[1],
287                       jf[0][2],jf[2][0]);
288   oksea[0] = ChFi3d_SearchFD(DStr,CD[1],CD[2],sens[1],sens[2],i[1][2],i[2][1],
289                       p[1][2],p[2][1],Index[1],Index[2],face[0],sameside[0],
290                       jf[1][2],jf[2][1]);
291   //
292   // Analyse des concavites des 3 chanfreins :
293   //        - 2 concavites identiques et 1 inverse.
294   //        - 3 concavites identiques
295   //
296   Standard_Boolean CornerAllSame = Standard_False;
297   Standard_Boolean okinter = Standard_True;
298   Standard_Boolean visavis;
299
300   if(oksea[2] && oksea[1] && !sameside[2] && !sameside[1]) {
301      pivot = 0; deb = 1; fin = 2;
302      //on calcule l'intersection des pcurves sans les restreindre a leur common point
303      if (!oksea[0])
304        okinter =  ChFi3d_IsInFront(DStr,CD[1],CD[2],i[1][2],i[2][1],sens[1],sens[2],
305                                    p[1][2],p[2][1],face[0],sameside[0],
306                                    jf[1][2],jf[2][1],visavis,Vtx,Standard_False,1);
307    }
308   else if(oksea[2] && oksea[0] && !sameside[2] && !sameside[0]) {
309     pivot = 1; deb = 2; fin = 0;
310     if (!oksea[1])
311       okinter =  ChFi3d_IsInFront(DStr,CD[0],CD[2],i[0][2],i[2][0],sens[0],sens[2],
312                                   p[0][2],p[2][0],face[1],sameside[1],
313                                   jf[0][2],jf[2][0],visavis,Vtx,Standard_False,1);
314   }
315   else if(oksea[1] && oksea[0] && !sameside[1] && !sameside[0]) {
316     pivot = 2; deb = 0; fin = 1;
317     if (!oksea[2])
318       okinter =  ChFi3d_IsInFront(DStr,CD[0],CD[1],i[0][1],i[1][0],sens[0],sens[1],
319                                   p[0][1],p[1][0],face[2],sameside[2],
320                                   jf[0][1],jf[1][0],visavis,Vtx,Standard_False,1);
321   }
322   else if(oksea[0] && oksea[1] && oksea[2]){ 
323     // 3 concavites identiques.
324     pivot = ChFi3d_SearchPivot(sens,p,tol2d);
325     if(pivot < 0)
326       // on prend un pivot au hasard!!!!!!!!!!!!!!!
327       pivot = 0;
328     deb = (pivot+1)%3 ; fin = (pivot+2)%3;
329     CornerAllSame = Standard_True;
330   } 
331   else Standard_Failure::Raise("FD en vis a vis non trouvees");
332   if (!okinter)
333      Standard_Failure::Raise("Echec intersection PCurves OnCommonFace");
334
335   // on a le pivot, le CD deb et le CD fin (enfin on espere !?!) :
336   // -------------------------------------------------------------
337   
338   /* Remarque Importante : dans le cas ou les indices des Surf data
339      du pivot sur lesquelles ont ete trouvees les intersections de pcurves
340      ne sont pas egaux, il va y avoir changement de Surf data lors du 
341      cheminement et creations de Surf data mutantes a 3 ou 5 cotes!!!
342      NON TRAITE !!!!!! (pour l instant)*/
343   if(i[pivot][deb] != i[pivot][fin]){
344     Standard_NotImplemented::Raise("coin mutant non programme");
345   }
346   /* Autre Remarque : dans le cas ou les indices des Surf data
347      du deb (de la fin) sur lesquelles ont ete trouvees les intersections
348      de pcurves ne sont pas egaux, il va y avoir changement de face lors du
349      cheminement NON GERE !!!!!! (pour l instant). Prevoir un
350      PerformSetOfSurf adapte.*/
351   if(oksea[pivot] && 
352      (i[deb][pivot] != i[deb][fin] || i[fin][pivot] != i[fin][deb])){
353     Standard_NotImplemented::Raise("coin sur plusieurs faces non programme");
354   }
355   
356   Handle(ChFiDS_SurfData)& 
357     fddeb = CD[deb]->ChangeSetOfSurfData()->ChangeValue(i[deb][pivot]);
358   Handle(ChFiDS_SurfData)& 
359     fdfin = CD[fin]->ChangeSetOfSurfData()->ChangeValue(i[fin][pivot]);
360   Handle(ChFiDS_SurfData)& 
361     fdpiv = CD[pivot]->ChangeSetOfSurfData()->ChangeValue(i[pivot][deb]);
362   
363   
364   // On construit les HSurfaces et autres outils qui vont bien.
365   // ----------------------------------------------------------
366
367   Handle(BRepAdaptor_HSurface) Fac = new BRepAdaptor_HSurface(face[pivot]);
368   Handle(GeomAdaptor_HSurface) 
369     bidsurf = new GeomAdaptor_HSurface(Fac->ChangeSurface().Surface());
370   Handle(Adaptor3d_TopolTool)  IFac = new Adaptor3d_TopolTool(bidsurf);
371
372   Handle(GeomAdaptor_HSurface) Surf = ChFi3d_BoundSurf (DStr,fdpiv,jf[pivot][deb],jf[pivot][fin]);
373   Handle(Adaptor3d_TopolTool) ISurf = new Adaptor3d_TopolTool(Surf);
374  
375   // Creation of a new Stripe for the corner
376   Handle(ChFiDS_Stripe) corner = new ChFiDS_Stripe();
377   Handle(ChFiDS_HData)& cornerset = corner->ChangeSetOfSurfData();
378   cornerset = new ChFiDS_HData();
379   Handle(ChFiDS_SurfData) coin = new ChFiDS_SurfData();
380   cornerset->Append(coin);
381
382   // Pour plus de surete, on verifie les intersections des pcurves des chanfreins sur leur
383   // face commune
384   Handle(GeomAdaptor_HSurface) HSdeb
385     = new GeomAdaptor_HSurface( GeomAdaptor_Surface(DStr.Surface(fddeb->Surf()).Surface()) );
386   Handle(GeomAdaptor_HSurface) HSfin
387     = new GeomAdaptor_HSurface( GeomAdaptor_Surface(DStr.Surface(fdfin->Surf()).Surface()) );
388   Handle(GeomAdaptor_HSurface) HSpiv
389     = new GeomAdaptor_HSurface( GeomAdaptor_Surface(DStr.Surface(fdpiv->Surf()).Surface()) );
390
391   gp_Pnt2d p2d[4];
392   gp_Pnt p3d[4], PSom;
393
394   ChFi3d_ComputesIntPC (fdpiv->Interference(jf[pivot][deb]),fddeb->Interference(jf[deb][pivot]),
395                         HSpiv,HSdeb,p[pivot][deb],p[deb][pivot], p3d[fin]);
396   ChFi3d_ComputesIntPC (fdpiv->Interference(jf[pivot][fin]),fdfin->Interference(jf[fin][pivot]),
397                         HSpiv,HSfin,p[pivot][fin],p[fin][pivot], p3d[deb]);
398   ChFi3d_ComputesIntPC (fddeb->Interference(jf[deb][fin]),fdfin->Interference(jf[fin][deb]),
399                         HSdeb,HSfin,p[deb][fin],p[fin][deb], PSom);
400
401
402
403   // On determine les extremites du coin
404   //------------------------------------
405   // c1triangle : on n'a besoin que des 3 points intersection des 3 chanfreins
406   // sinon : on a les 2 points intersection de fdpiv avec fddeb et fdfin, et on
407   //         cree 2 autres points sur la face commune a l'aide des deux premiers
408
409     // p2d[deb] et p2d[fin] sur la surface du chanfrein fdpiv.
410     // p2d[piv], p2d[3] (confondus si c1triangle) sur la face en bout du chanfrein de fdpiv
411     // p2d[piv](resp.vp2d[3]) est sur la Uiso de fddeb(resp. fdfin) passant par p2d[deb]
412     // (resp. p2d[fin]) 
413
414 //  if (CornerAllSame) 
415 //    c1triangle = (Abs(p[deb][pivot]-p[deb][fin])<tolesp &&
416 //                Abs(p[fin][pivot]-p[fin][deb])<tolesp);
417
418   gp_Vec2d Tg3,Tgpiv;
419   
420 //  if (c1triangle)
421 //    p2d[pivot] = fddeb->Interference(jf[deb][fin]).PCurveOnFace()->Value(p[deb][pivot]);
422 //  else {
423     if (issmooth) {
424       fddeb->Interference(jf[deb][fin]).PCurveOnFace()->D1(p[deb][pivot],p2d[pivot],Tgpiv);
425       fdfin->Interference(jf[fin][deb]).PCurveOnFace()->D1(p[fin][pivot],p2d[3],Tg3);
426     }
427     else {
428       p2d[pivot] = fddeb->Interference(jf[deb][fin]).PCurveOnFace()->Value(p[deb][pivot]);
429       p2d[3] = fdfin->Interference(jf[fin][deb]).PCurveOnFace()->Value(p[fin][pivot]);
430     }
431 //  }
432   p2d[fin] = fdpiv->Interference(jf[pivot][deb]).PCurveOnSurf()->Value(p[pivot][deb]);
433   p2d[deb] = fdpiv->Interference(jf[pivot][fin]).PCurveOnSurf()->Value(p[pivot][fin]);
434
435 //  gp_Pnt pnt;
436   gp_Vec deru,derv;
437
438 //  p3d[fin] = HSpiv->Value(p2d[fin].X(),p2d[fin].Y());
439 //  p3d[deb] = HSpiv->Value(p2d[deb].X(),p2d[deb].Y());
440   Fac->D1(p2d[pivot].X(),p2d[pivot].Y(),p3d[pivot],deru,derv);
441   gp_Vec norpl = deru.Crossed(derv);
442 //  if (!c1triangle)
443     p3d[3] = Fac->Value(p2d[3].X(),p2d[3].Y());
444
445   Standard_Real DistMin    = (p3d[3]).Distance(p3d[fin]);
446   Standard_Real DistTmp    = (p3d[pivot]).Distance(p3d[deb]);
447   Standard_Real DistDebFin = (p3d[pivot]).Distance(p3d[3]);
448
449   if (DistTmp > DistMin) DistMin = DistTmp;
450
451   // on elargi la notion de triangle pour eviter de creer
452   // des surfaces ecraser avec deux coins proches
453   // attention ceci entraine un effet de seuil
454   if (CornerAllSame) 
455     c1triangle = (DistDebFin  < 0.3 * DistMin);
456
457   if (c1triangle)
458     p3d[pivot] = PSom;
459
460
461   // on calcule la surface portant le coin
462   //--------------------------------------
463   // Si c1triangle ou les 4 points p3d sont coplanaires, alors 
464   // le chanfrein est porte par le plan passant par les 3  premiers p3d.
465   // Sinon, on construit le chanfrein par la methode GeomFill_ConstrainedFilling
466   Standard_Boolean c1plan = c1triangle;
467   gp_Vec v1(p3d[pivot],p3d[deb]);
468   gp_Vec v2(p3d[pivot],p3d[fin]);
469   gp_Vec nor = v1.Crossed(v2);
470
471   done = Standard_False;
472
473   Standard_Integer Icf=0,Icl=0;
474   Handle(Geom2d_Curve) debpc1,finpc1;
475
476   if (!c1triangle) {
477     c1plan = CoPlanar(p3d[0], p3d[1], p3d[2], p3d[3]);
478   }
479
480   if (c1plan) {    
481     // c1plan
482     //-------
483
484     // on construit le plan
485     gp_Dir ndir(nor);
486 //    gp_Dir xdir(gp_Vec(p3d[fin],p3d[deb]));
487     gp_Dir xdir = gp_Dir(gp_Vec(p3d[fin],p3d[deb]));
488     gp_Ax3 planAx3(p3d[pivot],ndir,xdir);
489     if (planAx3.YDirection().Dot(v1)<=0.)
490       planAx3.YReverse();
491     Handle(Geom_Plane) gpl= new Geom_Plane(planAx3);
492     coin->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gpl,DStr));
493     
494     // on oriente coin
495     gp_Vec norface = norpl;
496     if (face[pivot].Orientation() == TopAbs_REVERSED )
497       norface.Reverse();
498     gp_Vec norcoin =  gpl->Pln().Position().XDirection().
499       Crossed (gpl->Pln().Position().YDirection());
500     if  ( norcoin.Dot(norface) <= 0. )
501       coin->ChangeOrientation() = TopAbs_REVERSED;
502     else
503       coin->ChangeOrientation() = TopAbs_FORWARD; 
504
505     // on calcule les intersections 
506     Handle(Geom_Curve) gcpiv,gcdeb,gcfin;
507     Handle(Geom_TrimmedCurve) gcface;
508     Handle(Geom2d_Curve) pivpc1,pivpc2,debpc2,finpc2,facepc1,facepc2;
509     gp_Pnt2d ptbid; 
510                
511       //intersection coin-pivot
512     Standard_Real tolrcoinpiv;
513     if (!ComputeIntersection(DStr,fdpiv,coin,
514                              p3d[fin],p2d[fin],p3d[deb],p2d[deb],
515                              gcpiv,pivpc1,pivpc2,deru,derv,ptbid,
516                              tolesp,tol2d,tolrcoinpiv))
517       StdFail_NotDone::Raise("echec calcul intersection coin-pivot");
518     gp_Vec norpiv = deru.Crossed(derv);
519     
520     //intersection coin-deb
521     Standard_Real tolrcoindeb;
522     gp_Pnt2d p2d1,p2d2;
523     if(c1triangle) 
524       p2d1 = fddeb->Interference(jf[deb][fin]).PCurveOnSurf()->Value(p[deb][fin]);
525     else
526       p2d1 = fddeb->Interference(jf[deb][fin]).PCurveOnSurf()->Value(p[deb][pivot]);
527
528     p2d2 = fddeb->Interference(jf[deb][pivot]).PCurveOnSurf()->Value(p[deb][pivot]);
529    
530     if (!ComputeIntersection(DStr,fddeb,coin,
531                              p3d[pivot],p2d1,p3d[fin],p2d2,
532                              gcdeb,debpc1,debpc2,deru,derv,ptbid,
533                              tolesp,tol2d,tolrcoindeb))
534       StdFail_NotDone::Raise("echec calcul intersection coin-deb"); 
535     Icf = DStr.AddCurve(TopOpeBRepDS_Curve(gcdeb,tolrcoindeb));    
536
537     //intersection coin-fin
538     Standard_Real tolrcoinfin;
539     gp_Pnt p3dface;
540     if (c1triangle){
541       p3dface = p3d[pivot];
542       p2d1 = fdfin->Interference(jf[fin][deb]).PCurveOnSurf()->Value(p[fin][deb]);
543     }
544     else { 
545       p3dface = p3d[3];
546       p2d1 = fdfin->Interference(jf[fin][deb]).PCurveOnSurf()->Value(p[fin][pivot]);
547     }
548     p2d2 = fdfin->Interference(jf[fin][pivot]).PCurveOnSurf()->Value(p[fin][pivot]);
549     if (!ComputeIntersection(DStr,fdfin,coin,
550                              p3dface,p2d1,p3d[deb],p2d2,
551                              gcfin,finpc1,finpc2,deru,derv,ptbid,
552                              tolesp,tol2d,tolrcoinfin)) 
553       StdFail_NotDone::Raise("echec calcul intersection coin-face");
554     Icl = DStr.AddCurve(TopOpeBRepDS_Curve(gcfin,tolrcoinfin));  
555     
556     //!c1triangle: intersection coin-face[pivot]
557     if (!c1triangle) {
558       GeomInt_IntSS inter;
559       BRepAdaptor_Surface facebid(face[pivot]);
560       Handle(Geom_Surface) 
561       surfbid = Handle(Geom_Surface)::DownCast(facebid.Surface().Surface()->Transformed(facebid.Trsf()));
562       inter.Perform(gpl,surfbid,Precision::Intersection());
563       if (inter.IsDone()) {
564         Standard_Integer nbl = inter.NbLines();
565         if (nbl > 1) {
566 #ifdef OCCT_DEBUG
567           cout<<"trop d'intersection entre les surfaces"<<endl;
568 #endif
569         }
570         else if (nbl == 1) {
571           ChFi3d_TrimCurve(inter.Line(1),p3d[pivot],p3dface,gcface);
572           
573           Handle(GeomAdaptor_HCurve) gac = new GeomAdaptor_HCurve();
574           gac->ChangeCurve().Load(gcface);
575           Handle(GeomAdaptor_HSurface) gas = new GeomAdaptor_HSurface;
576           gas->ChangeSurface().Load(gpl);
577           Handle(BRepAdaptor_HSurface) gaf = new BRepAdaptor_HSurface;
578           gaf->ChangeSurface().Initialize(face[pivot]);
579           
580           Standard_Real tolr;
581           ChFi3d_ProjectPCurv(gac,gaf,facepc1,tolesp,tolr);
582           ChFi3d_ProjectPCurv(gac,gas,facepc2,tolesp,tolr);
583         }
584       }
585     }
586     
587     // on remplit les donnees du coin oriente face-pivot 
588     TopAbs_Orientation trans;
589     
590     //avec les CommonPoints
591     coin->ChangeVertexFirstOnS1().SetPoint(p3d[pivot]);
592     coin->ChangeVertexFirstOnS2().SetPoint(p3d[fin]);
593     if (c1triangle)
594       coin->ChangeVertexLastOnS1().SetPoint(p3d[pivot]);
595     else
596       coin->ChangeVertexLastOnS1().SetPoint(p3d[3]);
597     coin->ChangeVertexLastOnS2().SetPoint(p3d[deb]);
598     
599     //avec les FaceInterference
600 //    Standard_Integer Igcpiv,Igcdeb,Igcfin,Igcface;
601     Standard_Integer Igcpiv,Igcface;
602     ChFiDS_FaceInterference& fi1 = coin->ChangeInterferenceOnS1();    
603     ChFiDS_FaceInterference& fi2 = coin->ChangeInterferenceOnS2();
604     
605     //sur face[pivot]
606     if (norcoin.Dot(norpl) <= 0.) 
607       trans =  TopAbs_FORWARD;
608     else
609       trans = TopAbs_REVERSED;
610     Handle(Geom2d_Curve) bidpc;
611     if (c1triangle)
612       fi1.SetInterference(0,trans,bidpc,bidpc);
613     else {
614       Igcface = ChFiKPart_IndexCurveInDS(gcface,DStr);
615       fi1.SetInterference(Igcface,trans,facepc1,facepc2);
616       fi1.SetFirstParameter(gcface->FirstParameter());
617       fi1.SetLastParameter(gcface->LastParameter());
618     }
619     //sur le pivot
620     if (norcoin.Dot(norpiv) <= 0.) 
621       trans =  TopAbs_REVERSED;
622     else
623       trans = TopAbs_FORWARD;
624     Igcpiv = ChFiKPart_IndexCurveInDS(gcpiv,DStr);
625     fi2.SetInterference(Igcpiv,trans,pivpc1,pivpc2);
626     fi2.SetFirstParameter(gcpiv->FirstParameter());
627     fi2.SetLastParameter(gcpiv->LastParameter());
628     
629     done = Standard_True;
630     
631   }
632   else {
633     // !c1plan
634     //--------
635     
636     Handle(Geom_Surface) Surfcoin;
637     Handle(Geom2d_Curve) PCurveOnFace,PCurveOnPiv;
638     
639     // le contour a remplir est constitue de courbes isos sur deb et fin
640     // de deux pcurves calculees sur piv et la face opposee.
641     Handle(GeomFill_Boundary) Bdeb,Bfin,Bpiv,Bfac;
642     Standard_Integer ind1 = fddeb->Interference(jf[deb][pivot]).LineIndex();
643     Standard_Integer ind2 = fdfin->Interference(jf[fin][pivot]).LineIndex();
644     gp_Pnt Pfin,Pdeb;
645     gp_Vec vpfin,vpdeb;
646     
647     DStr.Curve(ind1).Curve()->D1(p[deb][pivot],Pfin,vpfin);
648     DStr.Curve(ind2).Curve()->D1(p[fin][pivot],Pdeb,vpdeb);
649     
650     if (issmooth) {
651       // les bords de coin sont des lignes courbes qui suivent les 
652       // tangentes donnees
653       Bfac = ChFi3d_mkbound(Fac,PCurveOnFace,sens[deb],p2d[pivot],Tgpiv,
654                             sens[fin],p2d[3],Tg3,tolesp,2.e-4);
655       Bpiv = ChFi3d_mkbound(Surf,PCurveOnPiv,sens[deb],p2d[fin],vpfin,
656                             sens[fin],p2d[deb],vpdeb,tolesp,2.e-4);
657     }
658     else {
659       // les bords de coin sont des segments
660       //      Bfac = ChFi3d_mkbound(Fac,PCurveOnFace,p2d[pivot],
661       //                            p2d[3],tolesp,2.e-4);
662       Bfac = ChFi3d_mkbound(Fac,PCurveOnFace,p2d[pivot],
663                             p2d[3],tolesp,2.e-4);
664       Bpiv = ChFi3d_mkbound(Surf,PCurveOnPiv,p2d[fin],
665                             p2d[deb],tolesp,2.e-4);
666     }
667     
668     gp_Pnt2d pdeb1 = fddeb->Interference(jf[deb][pivot]).PCurveOnSurf()->Value(p[deb][pivot]);
669     gp_Pnt2d pdeb2 = fddeb->Interference(jf[deb][fin]).PCurveOnSurf()->Value(p[deb][pivot]);
670     gp_Pnt2d pfin1 = fdfin->Interference(jf[fin][pivot]).PCurveOnSurf()->Value(p[fin][pivot]);
671     gp_Pnt2d pfin2 = fdfin->Interference(jf[fin][deb]).PCurveOnSurf()->Value(p[fin][pivot]);
672     
673     if (issmooth) {
674       // il faut homogeneiser, mettre les bords "BoundWithSurf"
675       Bdeb = ChFi3d_mkbound(DStr.Surface(fddeb->Surf()).Surface(),pdeb1,pdeb2,tolesp,2.e-4);
676       Bfin = ChFi3d_mkbound(DStr.Surface(fdfin->Surf()).Surface(),pfin1,pfin2,tolesp,2.e-4);
677     }
678     else {
679       // ou les 4 bords de type "FreeBoundary"
680       Bdeb = ChFi3d_mkbound(DStr.Surface(fddeb->Surf()).Surface(),pdeb1,pdeb2,
681                             tolesp,2.e-4,Standard_True);
682       Bfin = ChFi3d_mkbound(DStr.Surface(fdfin->Surf()).Surface(),pfin1,pfin2,
683                             tolesp,2.e-4,Standard_True);
684     }
685     GeomFill_ConstrainedFilling fil(8,20);
686     fil.Init(Bpiv,Bfin,Bfac,Bdeb);
687     
688     Surfcoin = fil.Surface();
689     // on se ramene au sens face surf: S1 = face, S2 = surf
690     Surfcoin->VReverse();
691     
692     done = CompleteData(coin,Surfcoin,
693                         Fac,PCurveOnFace,
694                         Surf,PCurveOnPiv,fdpiv->Orientation(),0,
695                         0,0,0,0);
696   }
697   Standard_Real P1deb,P2deb,P1fin,P2fin;
698   
699   if (done){
700     Standard_Integer If1,If2,Il1,Il2;
701     
702     // Mise a jour des 4 Stripes et de la DS
703     // -------------------------------------
704     
705     const ChFiDS_CommonPoint& Pf1 = coin->VertexFirstOnS1();
706     const ChFiDS_CommonPoint& Pf2 = coin->VertexFirstOnS2();
707     ChFiDS_CommonPoint& Pl1 = coin->ChangeVertexLastOnS1();
708     if(c1triangle) 
709       Pl1 = coin->ChangeVertexFirstOnS1();
710     const ChFiDS_CommonPoint& Pl2 = coin->VertexLastOnS2();
711     
712     // le coin pour commencer,
713     // -----------------------
714     ChFiDS_Regul regdeb, regfin;
715     If1 = ChFi3d_IndexPointInDS(Pf1,DStr);
716     If2 = ChFi3d_IndexPointInDS(Pf2,DStr);
717     if (c1triangle)
718       Il1 = If1;
719     else
720       Il1 = ChFi3d_IndexPointInDS(Pl1,DStr);
721     Il2 = ChFi3d_IndexPointInDS(Pl2,DStr);
722
723     coin->ChangeIndexOfS1(DStr.AddShape(face[pivot]));
724     coin->ChangeIndexOfS2(-fdpiv->Surf());
725
726     // first points
727     gp_Pnt2d pp1,pp2;
728     if (c1plan) {
729       P1deb = DStr.Curve(Icf).Curve()->FirstParameter();
730       P2deb = DStr.Curve(Icf).Curve()->LastParameter();
731     }
732     else {
733       pp1 = coin->InterferenceOnS1().PCurveOnSurf()->
734         Value(coin->InterferenceOnS1().FirstParameter());
735       pp2 = coin->InterferenceOnS2().PCurveOnSurf()->
736         Value( coin->InterferenceOnS2().FirstParameter());
737       Handle(Geom_Curve) C3d;
738       Standard_Real tolreached;
739       ChFi3d_ComputeArete(Pf1,pp1,Pf2,pp2,
740                           DStr.Surface(coin->Surf()).Surface(),C3d,
741                           corner->ChangeFirstPCurve(),P1deb,P2deb,
742                           tolesp,tol2d,tolreached,0);
743       TopOpeBRepDS_Curve Tcurv(C3d,tolreached);
744       Icf = DStr.AddCurve(Tcurv);
745     }
746  
747     regdeb.SetCurve(Icf);
748     regdeb.SetS1(coin->Surf(),0);
749     regdeb.SetS2(fddeb->Surf(),0);
750     myRegul.Append(regdeb);
751     corner->ChangeFirstCurve(Icf);
752     corner->ChangeFirstParameters(P1deb,P2deb);
753     corner->ChangeIndexFirstPointOnS1(If1);
754     corner->ChangeIndexFirstPointOnS2(If2);
755
756     // last points
757     if (c1plan) {
758       P1fin = DStr.Curve(Icl).Curve()->FirstParameter();
759       P2fin = DStr.Curve(Icl).Curve()->LastParameter();
760     } 
761     else {
762       pp1 = coin->InterferenceOnS1().PCurveOnSurf()->
763         Value(coin->InterferenceOnS1().LastParameter());
764       pp2 = coin->InterferenceOnS2().PCurveOnSurf()->
765         Value(coin->InterferenceOnS2().LastParameter());
766       Handle(Geom_Curve) C3d;
767       Standard_Real tolreached;
768       ChFi3d_ComputeArete(Pl1,pp1,Pl2,pp2,
769                           DStr.Surface(coin->Surf()).Surface(),C3d,
770                           corner->ChangeLastPCurve(),P1fin,P2fin,
771                           tolesp,tol2d,tolreached,0);
772       TopOpeBRepDS_Curve Tcurv(C3d,tolreached);
773       Icl = DStr.AddCurve(Tcurv);
774     }
775     regfin.SetCurve(Icl);
776     regfin.SetS1(coin->Surf(),0);
777     regfin.SetS2(fdfin->Surf(),0);
778     myRegul.Append(regfin);
779     corner->ChangeLastCurve(Icl);
780     corner->ChangeLastParameters(P1fin,P2fin);
781     corner->ChangeIndexLastPointOnS1(Il1);
782     corner->ChangeIndexLastPointOnS2(Il2);
783     
784     // puis la CornerData du debut,
785     // ----------------------------
786     Standard_Boolean isfirst = (sens[deb] == 1), rev = (jf[deb][fin] == 2);
787     Standard_Integer isurf1 = 1, isurf2 = 2;
788     Standard_Real par = p[deb][pivot], par2 = p[deb][pivot];
789     if(c1triangle) par2 = p[deb][fin];
790     if (rev) { 
791       isurf1 = 2; isurf2 = 1; 
792       CD[deb]->SetOrientation(TopAbs_REVERSED,isfirst);
793     }
794     CD[deb]->SetCurve(Icf,isfirst);
795     CD[deb]->SetIndexPoint(If1,isfirst,isurf1);
796     CD[deb]->SetIndexPoint(If2,isfirst,isurf2);
797     CD[deb]->SetParameters(isfirst,P1deb,P2deb);
798     fddeb->ChangeVertex(isfirst,isurf1) = Pf1;
799     fddeb->ChangeVertex(isfirst,isurf2) = Pf2;
800     fddeb->ChangeInterference(isurf1).SetParameter(par2,isfirst);
801     fddeb->ChangeInterference(isurf2).SetParameter(par,isfirst);
802     if (c1plan) 
803       CD[deb]->ChangePCurve(isfirst) = debpc1;
804     else {
805       pp1 = fddeb->InterferenceOnS1().PCurveOnSurf()->Value(par);
806       pp2 = fddeb->InterferenceOnS2().PCurveOnSurf()->Value(par);
807       ChFi3d_ComputePCurv(pp1,pp2,CD[deb]->ChangePCurve(isfirst),P1deb,P2deb,rev);
808     }
809
810     // puis la CornerData de la fin,
811     // -----------------------------
812     isfirst = (sens[fin] == 1); rev = (jf[fin][deb] == 2);
813     isurf1 = 1; isurf2 = 2;
814     par = p[fin][pivot]; par2 = p[fin][pivot];
815     if(c1triangle) par2 = p[fin][deb];
816     if (rev) { 
817       isurf1 = 2; isurf2 = 1; 
818       CD[fin]->SetOrientation(TopAbs_REVERSED,isfirst);
819     }
820     CD[fin]->SetCurve(Icl,isfirst);
821     CD[fin]->SetIndexPoint(Il1,isfirst,isurf1);
822     CD[fin]->SetIndexPoint(Il2,isfirst,isurf2);
823     CD[fin]->SetParameters(isfirst,P1fin,P2fin);
824     fdfin->ChangeVertex(isfirst,isurf1) = Pl1;
825     fdfin->ChangeVertex(isfirst,isurf2) = Pl2;
826     fdfin->ChangeInterference(isurf1).SetParameter(par2,isfirst);
827     fdfin->ChangeInterference(isurf2).SetParameter(par,isfirst);
828     if (c1plan) 
829       CD[fin]->ChangePCurve(isfirst) = finpc1;
830     else {
831       pp1 = fdfin->InterferenceOnS1().PCurveOnSurf()->Value(par);
832       pp2 = fdfin->InterferenceOnS2().PCurveOnSurf()->Value(par);
833       ChFi3d_ComputePCurv(pp1,pp2,CD[fin]->ChangePCurve(isfirst),P1fin,P2fin,rev);
834     }
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     CD[pivot]->SetCurve(fi.LineIndex(),isfirst);
846     CD[pivot]->ChangePCurve(isfirst) = fi.PCurveOnFace();
847     CD[pivot]->SetIndexPoint(If2,isfirst,isurf1);
848     CD[pivot]->SetIndexPoint(Il2,isfirst,isurf2);
849     CD[pivot]->SetParameters(isfirst,fi.FirstParameter(),fi.LastParameter());
850     fdpiv->ChangeVertex(isfirst,isurf1) = Pf2;
851     fdpiv->ChangeVertex(isfirst,isurf2) = Pl2;
852     fdpiv->ChangeInterference(isurf1).SetParameter(p[pivot][deb],isfirst);
853     fdpiv->ChangeInterference(isurf2).SetParameter(p[pivot][fin],isfirst);
854     CD[pivot]->InDS(isfirst); // filDS fait deja le boulot depuis le coin.
855   }
856   
857   //On tronque les corners data et met a jour les index.
858   //----------------------------------------------------
859   
860   if(i[deb][pivot] < Index[deb]){
861     CD[deb]->ChangeSetOfSurfData()->Remove(i[deb][pivot]+1,Index[deb]);
862     Index[deb] = i[deb][pivot];
863   }
864   else if(i[deb][pivot] > Index[deb]) {
865     CD[deb]->ChangeSetOfSurfData()->Remove(Index[deb],i[deb][pivot]-1);
866     i[deb][pivot] = Index[deb]; 
867   }
868   if(i[fin][pivot] < Index[fin]) {
869     CD[fin]->ChangeSetOfSurfData()->Remove(i[fin][pivot]+1,Index[fin]);
870     Index[fin] = i[fin][pivot];
871   }
872   else if(i[fin][pivot] > Index[fin]) {
873     CD[fin]->ChangeSetOfSurfData()->Remove(Index[fin],i[fin][pivot]-1);
874     i[fin][pivot] = Index[fin]; 
875   }
876   // il faudra ici tenir compte des coins mutants.
877   if(i[pivot][deb] < Index[pivot]) {
878     CD[pivot]->ChangeSetOfSurfData()->Remove(i[pivot][deb]+1,Index[pivot]);
879     Index[pivot] = i[pivot][deb];
880   }
881   else if(i[pivot][deb] > Index[pivot]) {
882     CD[pivot]->ChangeSetOfSurfData()->Remove(Index[pivot],i[pivot][deb]-1);
883     i[pivot][deb] = Index[pivot]; 
884   }
885   if(!myEVIMap.IsBound(Vtx)){
886     TColStd_ListOfInteger li;
887     myEVIMap.Bind(Vtx,li);
888   }
889   myEVIMap.ChangeFind(Vtx).Append(coin->Surf());
890   corner->SetSolidIndex(CD[pivot]->SolidIndex());
891   myListStripe.Append(corner);
892 }