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