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