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