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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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>
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>
56 #include <gp_Dir2d.hxx>
57 #include <gp_Lin2d.hxx>
59 #include <gp_Pnt2d.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>
79 //=======================================================================
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,
90 gp_Vec vecAB(PntA, PntB);
91 gp_Vec vecAC(PntA, PntC);
92 gp_Vec vecAD(PntA, PntD);
94 Standard_Real nor2AB = vecAB.SquareMagnitude();
95 Standard_Real nor2AC = vecAC.SquareMagnitude();
96 Standard_Real ProABAC = vecAB.Dot(vecAC);
99 Standard_Real Alpha = nor2AB * nor2AC - ProABAC * ProABAC;
101 if (Alpha < Precision::Confusion()) {
102 return Standard_True;
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;
111 return (vecDABC.Magnitude() / Alpha) < Precision::Confusion();
117 //=======================================================================
118 //function : BoundSurf
119 //purpose : computes a GeomAdaptor_Surface from the surface and trims
120 // it to allow the intersection computation
121 //=======================================================================
123 static Handle(GeomAdaptor_HSurface) BoundSurf(const Handle(Geom_Surface)& S,
124 const gp_Pnt2d& Pdeb,
125 const gp_Pnt2d& Pfin)
127 Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface();
128 GeomAdaptor_Surface& GAS = HS->ChangeSurface();
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));
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);
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 //=======================================================================
156 static Standard_Boolean ComputeIntersection(TopOpeBRepDS_DataStructure& DStr,
157 const Handle(ChFiDS_SurfData)& SD,
158 const Handle(ChFiDS_SurfData)& SDCoin,
160 const gp_Pnt2d& p2ddeb,
162 const gp_Pnt2d& p2dfin,
163 Handle(Geom_Curve)& gc,
164 Handle(Geom2d_Curve)& pc1,
165 Handle(Geom2d_Curve)& pc2,
169 const Standard_Real tol3d,
170 const Standard_Real tol2d,
171 Standard_Real& tolreached)
173 // gp_Pnt2d UVf1,UVf2,UVl1,UVl2;
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);
180 const Handle(Geom_Surface)& gpl = DStr.Surface(SDCoin->Surf()).Surface();
181 const Handle(Geom_Surface)& gSD = DStr.Surface(SD->Surf()).Surface();
184 TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4);
189 gSD->D1(u,v,Pbidon,derudeb,dervdeb);
192 // gp_Pnt2d pd2(u,v);
194 ChFi3d_Parameters(gpl,pdeb,u,v);
197 ptcoindeb.SetCoord(u,v);
204 // gp_Pnt2d pf2(u,v);
206 ChFi3d_Parameters(gpl,pfin,u,v);
211 // Trims the chamfer surface to allow the intersection computation
212 // and computes a GeomAdaptor_Surface for using the ComputeCurves
214 Handle(GeomAdaptor_HSurface) HS2;
215 HS2 = BoundSurf(gpl,ptcoindeb,cpf2);
217 // compute the intersection curves and pcurves
218 return ChFi3d_ComputeCurves(HS1,HS2,Pardeb,Parfin,gc,
219 pc1,pc2,tol3d,tol2d,tolreached);
222 //======================================================================
223 // function : PerformThreeCorner
224 // purpose : compute the intersection of three chamfers on a same
225 // vertex of index <Jndex> in myVDataMap
226 //======================================================================
228 void ChFi3d_ChBuilder::PerformThreeCorner(const Standard_Integer Jndex)
231 //modifier pour le passer en option dans le cdl!!!!!!!!!!!!
232 Standard_Boolean issmooth = Standard_False;
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];
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];
248 Standard_Boolean c1triangle = Standard_False;
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]);
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.
258 Index[1] = CD[1]->SetOfSurfData()->Length();
261 else if(CD[1] == CD[2]){
262 Index[2] = CD[2]->SetOfSurfData()->Length();
265 else if(CD[0] == CD[2]){
266 Index[2] = CD[2]->SetOfSurfData()->Length();
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],
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],
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],
279 // Analyse des concavites des 3 chanfreins :
280 // - 2 concavites identiques et 1 inverse.
281 // - 3 concavites identiques
283 Standard_Boolean CornerAllSame = Standard_False;
284 Standard_Boolean okinter = Standard_True;
285 Standard_Boolean visavis;
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
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);
295 else if(oksea[2] && oksea[0] && !sameside[2] && !sameside[0]) {
296 pivot = 1; deb = 2; fin = 0;
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);
302 else if(oksea[1] && oksea[0] && !sameside[1] && !sameside[0]) {
303 pivot = 2; deb = 0; fin = 1;
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);
309 else if(oksea[0] && oksea[1] && oksea[2]){
310 // 3 concavites identiques.
311 pivot = ChFi3d_SearchPivot(sens,p,tol2d);
313 // on prend un pivot au hasard!!!!!!!!!!!!!!!
315 deb = (pivot+1)%3 ; fin = (pivot+2)%3;
316 CornerAllSame = Standard_True;
318 else throw Standard_Failure("FD en vis a vis non trouvees");
320 throw Standard_Failure("Echec intersection PCurves OnCommonFace");
322 // on a le pivot, le CD deb et le CD fin (enfin on espere !?!) :
323 // -------------------------------------------------------------
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");
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.*/
339 (i[deb][pivot] != i[deb][fin] || i[fin][pivot] != i[fin][deb])){
340 throw Standard_NotImplemented("coin sur plusieurs faces non programme");
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]);
351 // On construit les HSurfaces et autres outils qui vont bien.
352 // ----------------------------------------------------------
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);
359 Handle(GeomAdaptor_HSurface) Surf = ChFi3d_BoundSurf (DStr,fdpiv,jf[pivot][deb],jf[pivot][fin]);
360 Handle(Adaptor3d_TopolTool) ISurf = new Adaptor3d_TopolTool(Surf);
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);
369 // Pour plus de surete, on verifie les intersections des pcurves des chanfreins sur leur
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()) );
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);
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
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]
401 // if (CornerAllSame)
402 // c1triangle = (Abs(p[deb][pivot]-p[deb][fin])<tolesp &&
403 // Abs(p[fin][pivot]-p[fin][deb])<tolesp);
408 // p2d[pivot] = fddeb->Interference(jf[deb][fin]).PCurveOnFace()->Value(p[deb][pivot]);
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);
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]);
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]);
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);
430 p3d[3] = Fac->Value(p2d[3].X(),p2d[3].Y());
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]);
436 if (DistTmp > DistMin) DistMin = DistTmp;
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
442 c1triangle = (DistDebFin < 0.3 * DistMin);
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);
458 done = Standard_False;
460 Standard_Integer Icf=0,Icl=0;
461 Handle(Geom2d_Curve) debpc1,finpc1;
464 c1plan = CoPlanar(p3d[0], p3d[1], p3d[2], p3d[3]);
471 // on construit le plan
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.)
478 Handle(Geom_Plane) gpl= new Geom_Plane(planAx3);
479 coin->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gpl,DStr));
482 gp_Vec norface = norpl;
483 if (face[pivot].Orientation() == TopAbs_REVERSED )
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;
490 coin->ChangeOrientation() = TopAbs_FORWARD;
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;
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);
507 //intersection coin-deb
508 Standard_Real tolrcoindeb;
511 p2d1 = fddeb->Interference(jf[deb][fin]).PCurveOnSurf()->Value(p[deb][fin]);
513 p2d1 = fddeb->Interference(jf[deb][fin]).PCurveOnSurf()->Value(p[deb][pivot]);
515 p2d2 = fddeb->Interference(jf[deb][pivot]).PCurveOnSurf()->Value(p[deb][pivot]);
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));
524 //intersection coin-fin
525 Standard_Real tolrcoinfin;
528 p3dface = p3d[pivot];
529 p2d1 = fdfin->Interference(jf[fin][deb]).PCurveOnSurf()->Value(p[fin][deb]);
533 p2d1 = fdfin->Interference(jf[fin][deb]).PCurveOnSurf()->Value(p[fin][pivot]);
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));
543 //!c1triangle: intersection coin-face[pivot]
546 BRepAdaptor_Surface facebid(face[pivot]);
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();
554 std::cout<<"trop d'intersection entre les surfaces"<<std::endl;
558 ChFi3d_TrimCurve(inter.Line(1),p3d[pivot],p3dface,gcface);
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]);
568 ChFi3d_ProjectPCurv(gac,gaf,facepc1,tolesp,tolr);
569 ChFi3d_ProjectPCurv(gac,gas,facepc2,tolesp,tolr);
574 // on remplit les donnees du coin oriente face-pivot
575 TopAbs_Orientation trans;
577 //avec les CommonPoints
578 coin->ChangeVertexFirstOnS1().SetPoint(p3d[pivot]);
579 coin->ChangeVertexFirstOnS2().SetPoint(p3d[fin]);
581 coin->ChangeVertexLastOnS1().SetPoint(p3d[pivot]);
583 coin->ChangeVertexLastOnS1().SetPoint(p3d[3]);
584 coin->ChangeVertexLastOnS2().SetPoint(p3d[deb]);
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();
593 if (norcoin.Dot(norpl) <= 0.)
594 trans = TopAbs_FORWARD;
596 trans = TopAbs_REVERSED;
597 Handle(Geom2d_Curve) bidpc;
599 fi1.SetInterference(0,trans,bidpc,bidpc);
601 Igcface = ChFiKPart_IndexCurveInDS(gcface,DStr);
602 fi1.SetInterference(Igcface,trans,facepc1,facepc2);
603 fi1.SetFirstParameter(gcface->FirstParameter());
604 fi1.SetLastParameter(gcface->LastParameter());
607 if (norcoin.Dot(norpiv) <= 0.)
608 trans = TopAbs_REVERSED;
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());
616 done = Standard_True;
623 Handle(Geom_Surface) Surfcoin;
624 Handle(Geom2d_Curve) PCurveOnFace,PCurveOnPiv;
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();
634 DStr.Curve(ind1).Curve()->D1(p[deb][pivot],Pfin,vpfin);
635 DStr.Curve(ind2).Curve()->D1(p[fin][pivot],Pdeb,vpdeb);
638 // les bords de coin sont des lignes courbes qui suivent les
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);
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);
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]);
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);
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);
672 GeomFill_ConstrainedFilling fil(8,20);
673 fil.Init(Bpiv,Bfin,Bfac,Bdeb);
675 Surfcoin = fil.Surface();
676 // on se ramene au sens face surf: S1 = face, S2 = surf
677 Surfcoin->VReverse();
679 done = CompleteData(coin,Surfcoin,
681 Surf,PCurveOnPiv,fdpiv->Orientation(),0,
684 Standard_Real P1deb,P2deb,P1fin,P2fin;
687 Standard_Integer If1,If2,Il1,Il2;
689 // Mise a jour des 4 Stripes et de la DS
690 // -------------------------------------
692 const ChFiDS_CommonPoint& Pf1 = coin->VertexFirstOnS1();
693 const ChFiDS_CommonPoint& Pf2 = coin->VertexFirstOnS2();
694 ChFiDS_CommonPoint& Pl1 = coin->ChangeVertexLastOnS1();
696 Pl1 = coin->ChangeVertexFirstOnS1();
697 const ChFiDS_CommonPoint& Pl2 = coin->VertexLastOnS2();
699 // le coin pour commencer,
700 // -----------------------
701 ChFiDS_Regul regdeb, regfin;
702 If1 = ChFi3d_IndexPointInDS(Pf1,DStr);
703 If2 = ChFi3d_IndexPointInDS(Pf2,DStr);
707 Il1 = ChFi3d_IndexPointInDS(Pl1,DStr);
708 Il2 = ChFi3d_IndexPointInDS(Pl2,DStr);
710 coin->ChangeIndexOfS1(DStr.AddShape(face[pivot]));
711 coin->ChangeIndexOfS2(-fdpiv->Surf());
716 P1deb = DStr.Curve(Icf).Curve()->FirstParameter();
717 P2deb = DStr.Curve(Icf).Curve()->LastParameter();
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);
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);
745 P1fin = DStr.Curve(Icl).Curve()->FirstParameter();
746 P2fin = DStr.Curve(Icl).Curve()->LastParameter();
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);
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);
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];
778 isurf1 = 2; isurf2 = 1;
779 CD[deb]->SetOrientation(TopAbs_REVERSED,isfirst);
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);
790 CD[deb]->ChangePCurve(isfirst) = debpc1;
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);
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];
804 isurf1 = 2; isurf2 = 1;
805 CD[fin]->SetOrientation(TopAbs_REVERSED,isfirst);
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);
816 CD[fin]->ChangePCurve(isfirst) = finpc1;
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);
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;
829 isurf1 = 2; isurf2 = 1;
830 CD[pivot]->SetOrientation(TopAbs_REVERSED,isfirst);
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.
844 //On tronque les corners data et met a jour les index.
845 //----------------------------------------------------
847 if(i[deb][pivot] < Index[deb]){
848 CD[deb]->ChangeSetOfSurfData()->Remove(i[deb][pivot]+1,Index[deb]);
849 Index[deb] = i[deb][pivot];
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];
855 if(i[fin][pivot] < Index[fin]) {
856 CD[fin]->ChangeSetOfSurfData()->Remove(i[fin][pivot]+1,Index[fin]);
857 Index[fin] = i[fin][pivot];
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];
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];
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];
872 if(!myEVIMap.IsBound(Vtx)){
873 TColStd_ListOfInteger li;
874 myEVIMap.Bind(Vtx,li);
876 myEVIMap.ChangeFind(Vtx).Append(coin->Surf());
877 corner->SetSolidIndex(CD[pivot]->SolidIndex());
878 myListStripe.Append(corner);