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