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