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