Integration of OCCT 6.5.0 from SVN
[occt.git] / src / BiTgte / BiTgte_Blend.cxx
CommitLineData
7fd59977 1// File: BiTgte_Blend.cxx
2// Created: Mon Dec 16 15:32:45 1996
3// Author: Bruno DUMORTIER
4// <dub@brunox.paris1.matra-dtv.fr>
5
6#include <stdio.h>
7
8#include <BiTgte_Blend.ixx>
9
10// include - de tous les hxx,
11// - de toutes les petites fonctions statiques.
12
13//======================== DEBUT DES FUNCTIONS STATIQUES ============
14#include <BiTgte_DataMapOfShapeBox.hxx>
15#include <BiTgte_CurveOnEdge.hxx>
16
17#include <Bnd_Box.hxx>
18#include <BRepBndLib.hxx>
19#include <BRepTools.hxx>
20#include <BRepTools_Quilt.hxx>
21#include <BRepBuilderAPI_Sewing.hxx>
22#include <BRep_Tool.hxx>
23#include <BRep_Builder.hxx>
24#include <BRepLib_MakeEdge.hxx>
25#include <BRepOffset_DataMapOfShapeOffset.hxx>
26#include <BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx>
27#include <BRepOffset_Offset.hxx>
28#include <BRepOffset_MakeLoops.hxx>
29#include <BRepOffset_Inter3d.hxx>
30#include <BRepOffset_Inter2d.hxx>
31#include <BRepOffset_Interval.hxx>
32#include <BRepOffset_ListOfInterval.hxx>
33#include <BRepOffset_Tool.hxx>
34#include <BRepAlgo_Loop.hxx>
35#include <ChFi3d.hxx>
36#include <GeomAbs_SurfaceType.hxx>
37#include <GeomAPI_ProjectPointOnCurve.hxx>
38#include <Geom_BSplineCurve.hxx>
39#include <Geom_TrimmedCurve.hxx>
40#include <Geom_Circle.hxx>
41#include <Geom_Line.hxx>
42#include <Geom2d_Curve.hxx>
43#include <GeomAdaptor_Surface.hxx>
44#include <Geom2dAdaptor_Curve.hxx>
45#include <Geom2dAPI_ProjectPointOnCurve.hxx>
46#include <TopExp_Explorer.hxx>
47#include <TopoDS_Wire.hxx>
48#include <TopoDS_Vertex.hxx>
49#include <TopoDS_Edge.hxx>
50#include <TopoDS_Compound.hxx>
51#include <TopTools_ListOfShape.hxx>
52#include <TopTools_SequenceOfShape.hxx>
53#include <TopTools_DataMapOfShapeShape.hxx>
54#include <TopTools_MapIteratorOfMapOfShape.hxx>
55#include <TopTools_ListIteratorOfListOfShape.hxx>
56#include <gp.hxx>
57#include <gp_Pnt2d.hxx>
58#include <gp_Lin2d.hxx>
59#include <gp_Lin.hxx>
60#include <gp_Dir2d.hxx>
61#include <gp_Pnt.hxx>
62#include <gp_Dir.hxx>
63#include <gp_Ax1.hxx>
64#include <gp_Ax3.hxx>
65#include <gp_Circ.hxx>
66#include <gp_Sphere.hxx>
67
68#include <AppCont_Function.hxx>
69#include <Approx_FitAndDivide.hxx>
70#include <AppParCurves_MultiCurve.hxx>
71#include <BSplCLib.hxx>
72#include <Convert_CompBezierCurvesToBSplineCurve.hxx>
73#include <Precision.hxx>
74#include <TColgp_Array1OfPnt.hxx>
75#include <TColStd_Array1OfReal.hxx>
76#include <TColStd_Array1OfInteger.hxx>
77
78#include <Standard_NotImplemented.hxx>
79
80#include <BRepLib.hxx>
81#include <ElSLib.hxx>
82#include <GeomAPI.hxx>
83#include <TopoDS.hxx>
84#include <TopExp.hxx>
85
86#include <OSD_Chronometer.hxx>
87// variables pour les performances
88Standard_Real t_mkcurve;
89//Standard_IMPORT extern void ChFi3d_InitChron(OSD_Chronometer& ch);
90Standard_EXPORT void ChFi3d_InitChron(OSD_Chronometer& ch);
91//Standard_IMPORT extern void ChFi3d_ResultChron(OSD_Chronometer & ch,
92Standard_IMPORT void ChFi3d_ResultChron(OSD_Chronometer & ch,
93 Standard_Real& time);
94#ifdef DRAW
95static Standard_Boolean Affich = Standard_False;
96static char name[100];
97#include <DBRep.hxx>
98#endif
99
100//=======================================================================
101//function : IsOnRestriction
102//purpose :
103//=======================================================================
104
105static Standard_Boolean IsOnRestriction(const TopoDS_Vertex& V,
106 const TopoDS_Edge& CurE,
107 const TopoDS_Face& F,
108 TopoDS_Edge& E)
109{
110 // on cherche si le Vertex V de CurE est sur une restriction de F.
111 // si oui, on stocke dans E cette restriction.
112
113 // dub - 03 01 97
114 // Methode un peu brutale : on peut vraisemblablement optimiser par
115 // un appel direct a la SD des intersections -> Voir LBR
116
117 Standard_Real f,l;
118 Handle(Geom2d_Curve) CurC = BRep_Tool::CurveOnSurface(CurE,F,f,l);
119 Standard_Real U = BRep_Tool::Parameter(V,CurE,F);
120 gp_Pnt2d P = CurC->Value(U);
121
122 Geom2dAPI_ProjectPointOnCurve Proj;
123
124 // On gonfle la tolerance : il vaut mieux construire trop de tuyaux
125 // que de rater des intersections.
126 // Standard_Real Tol = 100 * BRep_Tool::Tolerance(V);
127 Standard_Real Tol = BRep_Tool::Tolerance(V);
128 TopExp_Explorer exp(F,TopAbs_EDGE);
129 for ( ; exp.More(); exp.Next()) {
130 E = TopoDS::Edge(exp.Current());
131 Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(E,F,f,l);
132 Proj.Init(P,PC,f,l);
133 if ( Proj.NbPoints() > 0) {
134 if (Proj.LowerDistance() < Tol) {
135 return Standard_True;
136 }
137 }
138 }
139 return Standard_False;
140}
141
142//=======================================================================
143//function : Add
144//purpose :
145//=======================================================================
146
147static void Add(const TopoDS_Edge& E,
148 TopTools_MapOfShape& Map,
149 const TopoDS_Shape& S,
150 const BRepOffset_Offset& OF,
151 const BRepOffset_Analyse& Analyse,
152 const Standard_Boolean WarningSurBordLibre)
153// Si WarningSurBordLibre = TRUE, pas de propagation si l'arete est verte
154{
155 TopAbs_ShapeEnum Type = S.ShapeType();
156
157 if ( Type == TopAbs_FACE) {
158 TopExp_Explorer exp(S,TopAbs_EDGE);
159 for ( ; exp.More(); exp.Next()) {
160 const TopoDS_Edge& OriE = TopoDS::Edge(exp.Current());
161 TopoDS_Shape aLocalShape = OF.Generated(OriE);
162 const TopoDS_Edge& IE = TopoDS::Edge(aLocalShape);
163// const TopoDS_Edge& IE = TopoDS::Edge(OF.Generated(OriE));
164 if ( E.IsEqual(IE)) {
165 if (WarningSurBordLibre) {
166 // On s'assure alors que ce n'est pas un bord libre.
167 const TopTools_ListOfShape& L = Analyse.Ancestors(OriE);
168 if (L.Extent() == 1) break; // On ne fait rien.
169 }
170 Map.Add(exp.Current());
171 break;
172 }
173 }
174 }
175 else if ( Type == TopAbs_EDGE) {
176 TopExp_Explorer exp(S,TopAbs_VERTEX);
177 for ( ; exp.More(); exp.Next()) {
178 TopoDS_Shape aLocalShape = OF.Generated(exp.Current());
179 const TopoDS_Edge& IE = TopoDS::Edge(aLocalShape);
180// const TopoDS_Edge& IE = TopoDS::Edge(OF.Generated(exp.Current()));
181 if ( E.IsEqual(IE)) {
182 const TopTools_ListOfShape& L = Analyse.Ancestors(exp.Current());
183 TopTools_ListIteratorOfListOfShape it(L);
184 for ( ; it.More(); it.Next()) {
185 Map.Add(it.Value());
186 }
187 break;
188 }
189 }
190 }
191}
192
193
194//=======================================================================
195//function : IsInFace
196//purpose :
197//=======================================================================
198
199static Standard_Boolean IsInFace(const TopoDS_Edge& E,
200 const TopoDS_Face& F)
201{
202 TopExp_Explorer exp(F,TopAbs_EDGE);
203 for ( ;exp.More(); exp.Next())
204 if ( E.IsSame(exp.Current())) return Standard_True;
205 return Standard_False;
206}
207
208
209//=======================================================================
210//function : KPartCurve3d
211//purpose :
212//=======================================================================
213
214static void KPartCurve3d(TopoDS_Edge Edge,
215 Handle(Geom2d_Curve) Curve,
216 Handle(Geom_Surface) Surf)
217{
218 // try to find the particular case
219 // if not found call BRepLib::BuildCurve3d
220
221 TopLoc_Location Loc;
222 Standard_Real Tol = Precision::Confusion();
223
224 Standard_Boolean IsComputed = Standard_False;
225
226 // Seach only isos on analytiques surfaces.
227 Geom2dAdaptor_Curve C(Curve);
228 GeomAdaptor_Surface S(Surf);
229 GeomAbs_CurveType CTy = C.GetType();
230 GeomAbs_SurfaceType STy = S.GetType();
231 BRep_Builder TheBuilder;
232
233 if ( STy != GeomAbs_Plane) { // if plane buildcurve3d gere KPart
234 if ( CTy == GeomAbs_Line) {
235 gp_Dir2d D = C.Line().Direction();
236 if ( D.IsParallel(gp::DX2d(),Precision::Angular())) { // Iso V.
237 if ( STy == GeomAbs_Sphere) {
238 gp_Pnt2d P = C.Line().Location();
239 if ( Abs( Abs(P.Y()) -PI/2. ) < Precision::PConfusion()) {
240 TheBuilder.Degenerated(Edge, Standard_True);
241 }
242 else {
243 gp_Sphere Sph = S.Sphere();
244 gp_Ax3 Axis = Sph.Position();
245 gp_Circ Ci = ElSLib::SphereVIso(Axis,
246 Sph.Radius(),
247 P.Y());
248 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
249 gp_Ax1 AxeRev(Axis.Location(), DRev);
250 Ci.Rotate(AxeRev, P.X());
251 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
252 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
253 Circle->Reverse();
254 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
255 }
256 IsComputed = Standard_True;
257 }
258 else if ( STy == GeomAbs_Cylinder) {
259 gp_Cylinder Cyl = S.Cylinder();
260 gp_Pnt2d P = C.Line().Location();
261 gp_Ax3 Axis = Cyl.Position();
262 gp_Circ Ci = ElSLib::CylinderVIso(Axis,
263 Cyl.Radius(),
264 P.Y());
265 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
266 gp_Ax1 AxeRev(Axis.Location(), DRev);
267 Ci.Rotate(AxeRev, P.X());
268 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
269 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
270 Circle->Reverse();
271 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
272 IsComputed = Standard_True;
273 }
274 else if ( STy == GeomAbs_Cone) {
275 gp_Cone Cone = S.Cone();
276 gp_Pnt2d P = C.Line().Location();
277 gp_Ax3 Axis = Cone.Position();
278 gp_Circ Ci = ElSLib::ConeVIso(Axis,
279 Cone.RefRadius(),
280 Cone.SemiAngle(),
281 P.Y());
282 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
283 gp_Ax1 AxeRev(Axis.Location(), DRev);
284 Ci.Rotate(AxeRev, P.X());
285 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
286 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
287 Circle->Reverse();
288 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
289 IsComputed = Standard_True;
290 }
291 else if ( STy == GeomAbs_Torus) {
292 gp_Torus Tore = S.Torus();
293 gp_Pnt2d P = C.Line().Location();
294 gp_Ax3 Axis = Tore.Position();
295 gp_Circ Ci = ElSLib::TorusVIso(Axis,
296 Tore.MajorRadius(),
297 Tore.MinorRadius(),
298 P.Y());
299 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
300 gp_Ax1 AxeRev(Axis.Location(), DRev);
301 Ci.Rotate(AxeRev, P.X());
302 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
303 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
304 Circle->Reverse();
305 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
306 IsComputed = Standard_True;
307 }
308 }
309 else if ( D.IsParallel(gp::DY2d(),Precision::Angular())) { // Iso U.
310 if ( STy == GeomAbs_Sphere) {
311 gp_Sphere Sph = S.Sphere();
312 gp_Pnt2d P = C.Line().Location();
313 gp_Ax3 Axis = Sph.Position();
314 // calculde l'iso 0.
315 gp_Circ Ci = ElSLib::SphereUIso(Axis, Sph.Radius(),0.);
316
317 // mise a sameparameter (rotation du cercle - decalage du Y)
318 gp_Dir DRev = Axis.XDirection().Crossed(Axis. Direction());
319 gp_Ax1 AxeRev(Axis.Location(),DRev);
320 Ci.Rotate(AxeRev, P.Y());
321
322 // transformation en iso U ( = P.X())
323 DRev = Axis.XDirection().Crossed(Axis.YDirection());
324 AxeRev = gp_Ax1(Axis.Location(), DRev);
325 Ci.Rotate(AxeRev, P.X());
326 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
327
328 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
329 Circle->Reverse();
330 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
331 IsComputed = Standard_True;
332 }
333 else if ( STy == GeomAbs_Cylinder) {
334 gp_Cylinder Cyl = S.Cylinder();
335 gp_Pnt2d P = C.Line().Location();
336 gp_Lin L = ElSLib::CylinderUIso(Cyl.Position(),
337 Cyl.Radius(),
338 P.X());
339 gp_Vec Tr(L.Direction());
340 Tr.Multiply(P.Y());
341 L.Translate(Tr);
342 Handle(Geom_Line) Line = new Geom_Line(L);
343 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
344 Line->Reverse();
345 TheBuilder.UpdateEdge(Edge, Line, Loc, Tol);
346 IsComputed = Standard_True;
347 }
348 else if ( STy == GeomAbs_Cone) {
349 gp_Cone Cone = S.Cone();
350 gp_Pnt2d P = C.Line().Location();
351 gp_Lin L = ElSLib::ConeUIso(Cone.Position(),
352 Cone.RefRadius(),
353 Cone.SemiAngle(),
354 P.X());
355 gp_Vec Tr(L.Direction());
356 Tr.Multiply(P.Y());
357 L.Translate(Tr); Handle(Geom_Line) Line = new Geom_Line(L);
358 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
359 Line->Reverse();
360 TheBuilder.UpdateEdge(Edge, Line, Loc, Tol);
361 IsComputed = Standard_True;
362 }
363 else if ( STy == GeomAbs_Torus) {
364 }
365 }
366 }
367 }
368 else { // Cas Plan
369 Handle(Geom_Curve) C3d = GeomAPI::To3d(Curve,S.Plane());
370 TheBuilder.UpdateEdge(Edge, C3d, Loc, Tol);
371 IsComputed = Standard_True;
372 }
373}
374
375
376//=======================================================================
377//function : MakeCurve
378//purpose :
379//=======================================================================
380
381class MakeCurve_Function : public AppCont_Function
382{
383 BiTgte_CurveOnEdge myCurve;
384
385 public :
386
387 MakeCurve_Function(const BiTgte_CurveOnEdge& C) : myCurve(C) {};
388
389 Standard_Real FirstParameter() const
390 {return myCurve.FirstParameter();}
391
392 Standard_Real LastParameter() const
393 {return myCurve.LastParameter();}
394
395 gp_Pnt Value(const Standard_Real t) const
396 {return myCurve.Value(t);}
397
398 Standard_Boolean D1(const Standard_Real /*t*/, gp_Pnt& /*P*/, gp_Vec& /*V*/) const
399 {return Standard_False;}
400
401};
402
403Handle(Geom_Curve) MakeCurve (const BiTgte_CurveOnEdge& HC)
404{
405 Handle(Geom_Curve) C;
406
407#if DEB
408 OSD_Chronometer ch;
409 ChFi3d_InitChron(ch);
410#endif
411
412 if ( HC.GetType() == GeomAbs_Circle) {
413 C = new Geom_Circle(HC.Circle());
414 C = new Geom_TrimmedCurve(C,HC.FirstParameter(),HC.LastParameter());
415 }
416 else { // on fait l'approx
417 MakeCurve_Function F(HC);
418 Standard_Integer Deg1, Deg2;
419 Deg1 = Deg2 = 8;
420 Standard_Real Tol = Precision::Approximation();
421 Approx_FitAndDivide Fit(F,Deg1,Deg2,Tol,Tol,Standard_True);
422 Standard_Integer i;
423 Standard_Integer NbCurves = Fit.NbMultiCurves();
424 // on essaie de rendre la courbe au moins C1
425 Convert_CompBezierCurvesToBSplineCurve Conv;
426
427 for (i = 1; i <= NbCurves; i++) {
428 AppParCurves_MultiCurve MC = Fit.Value( i); //Charge la Ieme Curve
429 TColgp_Array1OfPnt Poles( 1, MC.Degree() + 1); //Recupere les poles
430 MC.Curve(1, Poles);
431
432 Conv.AddCurve(Poles);
433 }
434
435 Conv.Perform();
436
437 Standard_Integer NbPoles = Conv.NbPoles();
438 Standard_Integer NbKnots = Conv.NbKnots();
439 TColgp_Array1OfPnt NewPoles(1,NbPoles);
440 TColStd_Array1OfReal NewKnots(1,NbKnots);
441 TColStd_Array1OfInteger NewMults(1,NbKnots);
442
443 Conv.KnotsAndMults(NewKnots,NewMults);
444 Conv.Poles(NewPoles);
445
446 BSplCLib::Reparametrize(HC.FirstParameter(),
447 HC.LastParameter(),
448 NewKnots);
449
450 C = new Geom_BSplineCurve (NewPoles,
451 NewKnots,
452 NewMults,
453 Conv.Degree());
454 }
455
456#if DEB
457 ChFi3d_ResultChron(ch, t_mkcurve);
458#endif
459
460 return C;
461}
462
463
464//=======================================================================
465//function : Touched
466//purpose : On ne donne que les faces connexes aux bouchons
467//=======================================================================
468
469static void Touched(const BRepOffset_Analyse& Analyse,
470 const TopTools_MapOfShape& StopFaces,
471 const TopoDS_Shape& Shape,
472 TopTools_MapOfShape& TouchedByCork)
473{
474 // pour l'instant on ne fait rien !!
475 // Le traitement merde !!
476 if ( Standard_True) {
477 return;
478 }
479 else {
480 TopExp_Explorer exp(Shape, TopAbs_EDGE);
481 for ( ; exp.More(); exp.Next()) {
482 const TopTools_ListOfShape& L = Analyse.Ancestors(exp.Current());
483 if (StopFaces.Contains(L.First()))
484 TouchedByCork.Add(L.Last());
485 else if (StopFaces.Contains(L.Last()))
486 TouchedByCork.Add(L.First());
487 }
488 }
489}
490
491//=======================================================================
492//function : FindVertex
493//purpose :
494//=======================================================================
495
496static TopoDS_Vertex FindVertex(const gp_Pnt& P,
497 const TopTools_MapOfShape& Map,
498 const Standard_Real Tol)
499{
500 BRep_Builder B;
501 // Find in <Map> a vertex which represent the point <P>.
502 Standard_Real Tol2,Dist;
503 TopoDS_Vertex V,VV[2];
504 Standard_Real TolCarre = Tol*Tol;
505 TopTools_MapIteratorOfMapOfShape it(Map);
506 for ( ; it.More(); it.Next()) {
507 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
508 if ( !E.IsNull()) {
509 TopExp::Vertices(E,VV[0],VV[1]);
510
511 for (Standard_Integer i = 0; i < 2 ; i++) {
512 // si OK dans la Tolerance du Vertex
513 Tol2 = BRep_Tool::Tolerance(VV[i]);
514 Tol2 *= Tol2;
515 gp_Pnt P1 = BRep_Tool::Pnt(VV[i]);
516 Dist = P.SquareDistance(P1);
517 if ( Dist <= Tol2) return VV[i];
518 // sinon dans la tolerance demandee.
519 if (TolCarre > Tol2) {
520 if ( Dist <= TolCarre) {
521 // il faut alors updater la tolerance du Vertex.
522 B.UpdateVertex(VV[i],Tol);
523 return VV[i];
524 }
525 }
526 }
527 }
528 }
529
530 return V;
531}
532
533
534//=======================================================================
535//function : MakeDegeneratedEdge
536//purpose :
537//=======================================================================
538
539static TopoDS_Edge MakeDegeneratedEdge(const Handle(Geom_Curve)& CC,
540 const TopoDS_Vertex& VfOnE)
541{
542 BRep_Builder B;
543 Standard_Real Tol = Precision::Confusion();
544 // kill trimmed curves
545 Handle(Geom_Curve) C = CC;
546 Handle(Geom_TrimmedCurve) CT = Handle(Geom_TrimmedCurve)::DownCast(C);
547 while (!CT.IsNull()) {
548 C = CT->BasisCurve();
549 CT = Handle(Geom_TrimmedCurve)::DownCast(C);
550 }
551
552 TopoDS_Vertex V1,V2;
553 if ( VfOnE.IsNull()) {
554 gp_Pnt P = C->Value(C->FirstParameter());
555 B.MakeVertex(V1,P,Tol);
556 V2 = V1;
557 }
558 else {
559 V1 = V2 = VfOnE;
560 }
561 V1.Orientation(TopAbs_FORWARD);
562 V2.Orientation(TopAbs_REVERSED);
563
564 TopoDS_Edge E;
565 B.MakeEdge(E,C,Tol);
566 B.Add(E,V1); B.Add(E,V2);
567// B.UpdateVertex(V1,C->FirstParameter(),E,Tol);
568// B.UpdateVertex(V2,C->LastParameter(),E,Tol);
569 B.Range(E,CC->FirstParameter(),CC->LastParameter());
570 return E;
571}
572
573
574//=======================================================================
575//function : Orientation
576//purpose :
577//=======================================================================
578
579static TopAbs_Orientation Orientation(const TopoDS_Edge& E,
580 const TopoDS_Face& F,
581 const TopTools_ListOfShape& L)
582{
583#ifndef DEB
584 TopAbs_Orientation Orien = TopAbs_FORWARD;
585#else
586 TopAbs_Orientation Orien;
587#endif
588 TopTools_ListIteratorOfListOfShape itld;
589 for ( itld.Initialize(L); itld.More(); itld.Next()) {
590 if ( itld.Value().IsSame(E)) {
591 Orien = itld.Value().Orientation();
592 break;
593 }
594 }
595 if ( F.Orientation() == TopAbs_REVERSED)
596 Orien = TopAbs::Reverse(Orien);
597
598 return Orien;
599}
600
601//=======================================================================
602//function : FindCreatedEdge
603//purpose :
604//=======================================================================
605
606static TopoDS_Edge FindCreatedEdge
607(const TopoDS_Vertex& V1,
608 const TopoDS_Edge& E,
609 const BRepOffset_DataMapOfShapeOffset& MapSF,
610 TopTools_MapOfShape& MapOnV,
611 const BRepOffset_Analyse& CenterAnalyse,
612 Standard_Real Radius,
613 Standard_Real Tol)
614{
615 TopoDS_Edge E1;
616 if (!CenterAnalyse.HasAncestor(V1)) return E1; // return a Null Shape.
617
618 TopTools_ListOfShape TangE;
619 CenterAnalyse.TangentEdges(E,V1,TangE);
620
621 TopTools_ListIteratorOfListOfShape itl(TangE);
622 Standard_Boolean Find = Standard_False;
623 for ( ; itl.More() && !Find; itl.Next()) {
624 const TopoDS_Edge& ET = TopoDS::Edge(itl.Value());
625 if ( MapSF.IsBound(ET)) {
626 TopoDS_Shape aLocalShape = MapSF(ET).Generated(V1);
627 E1 = TopoDS::Edge(aLocalShape);
628// E1 = TopoDS::Edge(MapSF(ET).Generated(V1));
629 MapOnV.Add(E1);
630 Find = Standard_True;
631 }
632 else {
633 // On cherche le partage des vertex dans le cas de 3 edges
634 // tgts consecutifs dont le deuxieme est un edge qui degenere
635 // le tuyau.
636 TopLoc_Location CLoc;
637 Standard_Real ff,ll;
638 Handle(Geom_Curve) CET =
639 BRep_Tool::Curve(ET,CLoc,ff,ll);
640 if ( CET->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
641 CET = Handle(Geom_TrimmedCurve)::DownCast(CET)->BasisCurve();
642 }
643 Handle(Geom_Circle) Circ = Handle(Geom_Circle)::DownCast(CET);
644 if ( Circ.IsNull()) continue;
645 if ( Abs(Circ->Radius() - Abs(Radius)) > Tol) continue;
646
647 TopoDS_Vertex U1,U2;
648 TopExp::Vertices(ET,U1,U2);
649 if ( U1.IsSame(V1)) U1 = U2;
650 TopTools_ListOfShape Tang2;
651 CenterAnalyse.TangentEdges(ET,U1,Tang2);
652 TopTools_ListIteratorOfListOfShape it2(Tang2);
653 for ( ; it2.More() ; it2.Next()) {
654 const TopoDS_Edge& ET2 = TopoDS::Edge(it2.Value());
655 if ( MapSF.IsBound(ET2)) {
656 TopoDS_Shape aLocalShape = MapSF(ET2).Generated(U1);
657 MapOnV.Add(TopoDS::Edge(aLocalShape));
658// MapOnV.Add(TopoDS::Edge(MapSF(ET2).Generated(U1)));
659 }
660 }
661 }
662 }
663 if (!Find) {
664 TangE.Clear();
665 // CenterAnalyse.Edges(V1f, OT, TangE);
666 if (CenterAnalyse.HasAncestor(V1)) {
667 TangE = CenterAnalyse.Ancestors(V1);
668 itl.Initialize(TangE);
669 for ( ; itl.More() && !Find; itl.Next()) {
670 if ( MapSF.IsBound(itl.Value())) {
671 MapOnV.Add(MapSF(itl.Value()).Generated(V1));
672 }
673 }
674 }
675 }
676
677 return E1;
678}
679
680//=======================================================================
681//function : Bubble
682//purpose : Ordonne la sequence de vertex en parametre croissant.
683//=======================================================================
684
685static void Bubble(const TopoDS_Edge& E,
686 TopTools_SequenceOfShape& Seq)
687{
688 Standard_Boolean Invert = Standard_True;
689 Standard_Integer NbPoints = Seq.Length();
690 Standard_Real U1,U2;
691 TopoDS_Vertex V1,V2;
692
693 while (Invert) {
694 Invert = Standard_False;
695 for ( Standard_Integer i = 1; i < NbPoints; i++) {
696 TopoDS_Shape aLocalShape = Seq.Value(i) .Oriented(TopAbs_INTERNAL);
697 V1 = TopoDS::Vertex(aLocalShape);
698 aLocalShape = Seq.Value(i+1).Oriented(TopAbs_INTERNAL);
699 V2 = TopoDS::Vertex(aLocalShape);
700// V1 = TopoDS::Vertex(Seq.Value(i) .Oriented(TopAbs_INTERNAL));
701// V2 = TopoDS::Vertex(Seq.Value(i+1).Oriented(TopAbs_INTERNAL));
702
703 U1 = BRep_Tool::Parameter(V1,E);
704 U2 = BRep_Tool::Parameter(V2,E);
705 if (U2 < U1) {
706 Seq.Exchange(i,i+1);
707 Invert = Standard_True;
708 }
709 }
710 }
711}
712
713//=======================================================================
714//function : CutEdge
715//purpose :
716//=======================================================================
717
718static void CutEdge (const TopoDS_Edge& E,
719 const TopTools_ListOfShape& VOnE,
720 TopTools_ListOfShape& NE )
721{
722 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
723 TopoDS_Edge WE = TopoDS::Edge(aLocalShape);
724// TopoDS_Edge WE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
725
726 Standard_Real U1,U2;
727 TopoDS_Vertex V1,V2;
728 TopTools_SequenceOfShape SV;
729 TopTools_ListIteratorOfListOfShape it(VOnE);
730 BRep_Builder B;
731
732 for ( ; it.More(); it.Next()) {
733 SV.Append(it.Value());
734 }
735 //--------------------------------
736 // Tri des vertex sur l edge.
737 //--------------------------------
738 Bubble (WE,SV);
739
740 Standard_Integer NbVer = SV.Length();
741 //----------------------------------------------------------------
742 // Construction des nouvelles edges.
743 // Remarque : les vertex extremites de l edges ne sont pas
744 // forcement dans la liste des vertex
745 //----------------------------------------------------------------
746 if (SV.IsEmpty()) {
747 NE.Append(E);
748 return;
749 }
750 TopoDS_Vertex VF,VL;
751 Standard_Real f,l;
752 BRep_Tool::Range(WE,f,l);
753 TopExp::Vertices(WE,VF,VL);
754
755 if (NbVer == 2) {
756 if (SV(1).IsEqual(VF) && SV(2).IsEqual(VL)) {
757 NE.Append(E);
758 return;
759 }
760 }
761 //----------------------------------------------------
762 // Traitement des edges fermes
763 // Si un vertex d intersection est sur le vertex
764 // commun il doit apparaitre eb debut et en fin de SV.
765 //----------------------------------------------------
766 TopoDS_Vertex VCEI;
767
768 if (!VF.IsNull() && !VF.IsSame(SV.First())) SV.Prepend(VF);
769 if (!VL.IsNull() && !VL.IsSame(SV.Last ())) SV.Append (VL);
770
771 V1 = TopoDS::Vertex(SV.First());
772 SV.Remove(1);
773
774 while (!SV.IsEmpty()) {
775
776 V2 = TopoDS::Vertex(SV.First());
777 SV.Remove(1);
778
779 if ( V1.IsSame(V2)) {
780 cout << "Vertex Confondus dans CutEdges" << endl;
781 continue;
782 }
783 //-------------------------------------------
784 // Copie de l edge et restriction par V1 V2.
785 //-------------------------------------------
786 TopoDS_Shape aLocalShape =WE.EmptyCopied();
787 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
788// TopoDS_Edge NewEdge = TopoDS::Edge(WE.EmptyCopied());
789 B.Add (NewEdge,V1.Oriented(TopAbs_FORWARD));
790 B.Add (NewEdge,V2.Oriented(TopAbs_REVERSED));
791 if (V1.IsSame(VF))
792 U1 = f;
793 else {
794 aLocalShape = V1.Oriented(TopAbs_INTERNAL);
795 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),WE);
796// U1 = BRep_Tool::Parameter
797// (TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),WE);
798 }
799 if (V2.IsSame(VL))
800 U2 = l;
801 else {
802 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
803 U2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),WE);
804// U2 = BRep_Tool::Parameter
805// (TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),WE);
806 }
807 B.Range (NewEdge,U1,U2);
808 NE.Append(NewEdge.Oriented(E.Orientation()));
809
810 V1 = V2;
811 }
812}
813//======================== FIN DES FUNCTIONS STATIQUES ============
814
815
816
817
818//=======================================================================
819//function : BiTgte_Blend
820//purpose :
821//=======================================================================
822
823BiTgte_Blend::BiTgte_Blend()
824{
825 myAsDes = new BRepAlgo_AsDes();
826 myNbBranches = -1;
827}
828
829
830//=======================================================================
831//function : BiTgte_Blend
832//purpose :
833//=======================================================================
834
835BiTgte_Blend::BiTgte_Blend(const TopoDS_Shape& S,
836 const Standard_Real Radius,
837 const Standard_Real Tol,
838 const Standard_Boolean NUBS)
839{
840 myAsDes = new BRepAlgo_AsDes();
841 Init(S,Radius,Tol,NUBS);
842}
843
844
845//=======================================================================
846//function : Init
847//purpose :
848//=======================================================================
849
850void BiTgte_Blend::Init(const TopoDS_Shape& S,
851 const Standard_Real Radius,
852 const Standard_Real Tol,
853 const Standard_Boolean NUBS)
854{
855 Clear();
856 myShape = S;
857 myTol = Tol;
858 myNubs = NUBS;
859 myRadius = Radius;
860 myNbBranches = -1;
861// TopExp::MapShapesAndAncestors(S,TopAbs_EDGE,TopAbs_FACE,myAncestors);
862}
863
864
865//=======================================================================
866//function : Clear
867//purpose :
868//=======================================================================
869
870void BiTgte_Blend::Clear()
871{
872 myInitOffsetFace.Clear();
873 myImage .Clear();
874 myImageOffset .Clear();
875 myStopFaces .Clear();
876 myAnalyse .Clear();
877 myAsDes ->Clear();
878 myNbBranches = -1;
879 myDone = Standard_False;
880}
881
882
883//=======================================================================
884//function : SetStoppingFace
885//purpose :
886//=======================================================================
887
888void BiTgte_Blend::SetStoppingFace(const TopoDS_Face& Face)
889{
890 myStopFaces.Add(Face);
891 //-------------
892 // MAJ SD. -> Pour le debouclage, on met les faces d'arrets
893 //-------------
894// myInitOffsetFace.SetRoot(Face);
895// myInitOffsetFace.Bind (Face,Face);
896// myImageOffset.SetRoot (Face);
897}
898
899
900//=======================================================================
901//function : SetFaces
902//purpose :
903//=======================================================================
904
905void BiTgte_Blend::SetFaces(const TopoDS_Face& F1,const TopoDS_Face& F2)
906{
907 myFaces.Add(F1);
908 myFaces.Add(F2);
909}
910
911
912//=======================================================================
913//function : SetEdge
914//purpose :
915//=======================================================================
916
917void BiTgte_Blend::SetEdge(const TopoDS_Edge& Edge)
918{
919 myEdges.Add(Edge);
920}
921
922
923//=======================================================================
924//function : Perform
925//purpose :
926//=======================================================================
927
928void BiTgte_Blend::Perform(const Standard_Boolean BuildShape)
929{
930 myBuildShape = BuildShape;
931
932 // On essaie la couture pour eviter des tuyaux sur bords libres
933 // qui n en sont pas vraiment.
934 Handle(BRepBuilderAPI_Sewing) Sew = new BRepBuilderAPI_Sewing(myTol);
935 BRepLib::BuildCurves3d(myShape);
936 TopExp_Explorer expf(myShape,TopAbs_FACE);
937 for ( ;expf.More(); expf.Next()) Sew->Add(expf.Current());
938 Sew->Perform();
939 TopoDS_Shape SewedShape = Sew->SewedShape();
940 if ( SewedShape.IsNull()) Standard_Failure::Raise("Sewing aux fraises");
941
942 // Le sewing a t il modifie des orientations.
943 expf.Init(myShape,TopAbs_FACE);
944 TopoDS_Face FaceRef = TopoDS::Face(expf.Current());
945 TopAbs_Orientation OriRef = FaceRef.Orientation();
946 if (Sew->IsModified(FaceRef)) FaceRef = TopoDS::Face(Sew->Modified(FaceRef));
947 expf.Init(SewedShape, TopAbs_FACE);
948 for (; expf.More(); expf.Next()) {
949 const TopoDS_Face& FF = TopoDS::Face(expf.Current());
950 if (FaceRef.IsSame(FF) && (FF.Orientation() != OriRef)) {
951 SewedShape.Reverse();
952 break;
953 }
954 }
955
956 // On fait le SameParameter cas Sew ne le fait pas (Detecte que les edges
957 // ne sont pas sameparameter mais ne fait rien.)
958 expf.Init(SewedShape, TopAbs_EDGE);
959 for (; expf.More(); expf.Next()) {
960 const TopoDS_Edge& sec = TopoDS::Edge(expf.Current());
961 BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
962 }
963
964 TopExp::MapShapesAndAncestors
965 (SewedShape,TopAbs_EDGE,TopAbs_FACE,myAncestors);
966
967 // Maj myFaces avec les faces du sewed shape.
968 expf.Init(myShape,TopAbs_FACE);
969 for ( ; expf.More(); expf.Next()) {
970 const TopoDS_Shape& F = expf.Current();
971 if ( myFaces.Contains(F) && Sew->IsModified(F)) {
972 myFaces.Remove(F);
973 myFaces.Add(Sew->Modified(F));
974 }
975 }
976
977 myShape = SewedShape;
978// fin Sewing pour faux bords libres.
979
980#if DEB
981 OSD_Chronometer cl_total, ch;
982 Standard_Real t_total, t_center, t_surface, t_shape;
983
984 t_total=0; t_center=0; t_surface=0; t_mkcurve=0; t_shape=0;
985 ChFi3d_InitChron(cl_total);
986#endif
987
988 // ----------------------------------------------------------------
989 // on met les faces avec la bonne orientation dans le shape initial
990 // ----------------------------------------------------------------
991 TopExp_Explorer exp(myShape,TopAbs_FACE);
992 for ( ; exp.More(); exp.Next()) {
993 const TopoDS_Shape& F = exp.Current();
994 if ( myFaces.Contains(F)) {
995 myFaces.Remove(F);
996 myFaces.Add(F);
997 }
998 else if ( myStopFaces.Contains(F)) {
999 myStopFaces.Remove(F);
1000 myStopFaces.Add(F);
1001 }
1002 }
1003
1004 // ----------------------------------------------
1005 // Calcul des lignes de centres et des surfaces
1006 // ----------------------------------------------
1007#if DEB
1008 ChFi3d_InitChron(ch);
1009#endif
1010
1011 ComputeCenters();
1012
1013#if DEB
1014 ChFi3d_ResultChron(ch, t_center);
1015#endif
1016
1017 // -----------------------------
1018 // Calcul des Surfaces raccords
1019 // -----------------------------
1020#if DEB
1021 ChFi3d_InitChron(ch);
1022#endif
1023
1024 ComputeSurfaces();
1025
1026#if DEB
1027 ChFi3d_ResultChron(ch, t_surface);
1028#endif
1029
1030 // ----------------------------------
1031 // Calcul du shape genere si demande
1032 // ----------------------------------
1033#if DEB
1034 ChFi3d_InitChron(ch);
1035#endif
1036
1037 if ( myBuildShape) ComputeShape();
1038
1039#if DEB
1040 ChFi3d_ResultChron(ch, t_shape);
1041#endif
1042
1043 // Finalement on construit les courbes 3d des edges
1044 // A VIRER des que le partage sera assure ( A Priori);
1045 BRepLib::BuildCurves3d(myResult, Precision::Confusion());
1046
1047#ifdef DEB
1048 ChFi3d_ResultChron(cl_total, t_total);
1049 cout<<endl;
1050 cout<<"Blend_PERFORM: temps total "<<t_total<<" s dont :"<<endl;
1051 cout<<"- ComputeCenters "<<t_center<<" s"<<endl;
1052 cout<<"- ComputeSurfaces "<<t_surface<<" s"<<endl;
1053 cout<<"----> MakeCurve "<<t_mkcurve<<" s"<<endl;
1054 if ( myBuildShape) cout<<"- ComputeShape "<<t_shape<<" s"<<endl;
1055#endif
1056
1057 myDone = Standard_True;
1058}
1059
1060
1061//=======================================================================
1062//function : IsDone
1063//purpose :
1064//=======================================================================
1065
1066Standard_Boolean BiTgte_Blend::IsDone() const
1067{
1068 return myDone;
1069}
1070
1071//=======================================================================
1072//function : Shape
1073//purpose :
1074//=======================================================================
1075
1076const TopoDS_Shape& BiTgte_Blend::Shape() const
1077{
1078 return myResult;
1079}
1080
1081
1082//=======================================================================
1083//function : NbSurfaces
1084//purpose :
1085//=======================================================================
1086
1087Standard_Integer BiTgte_Blend::NbSurfaces() const
1088{
1089 return myCenters.Extent();
1090}
1091
1092
1093//=======================================================================
1094//function : Surface
1095//purpose :
1096//=======================================================================
1097
1098Handle(Geom_Surface) BiTgte_Blend::Surface(const Standard_Integer Index) const
1099{
1100 return Surface(myCenters(Index));
1101}
1102
1103//=======================================================================
1104//function : TopoDS_Face&
1105//purpose :
1106//=======================================================================
1107
1108const TopoDS_Face& BiTgte_Blend::Face(const Standard_Integer Index) const
1109{
1110 return Face(myCenters(Index));
1111}
1112
1113
1114
1115//=======================================================================
1116//function : CenterLines
1117//purpose :
1118//=======================================================================
1119
1120void BiTgte_Blend::CenterLines(TopTools_ListOfShape& LC) const
1121{
1122 LC.Clear();
1123 Standard_Integer Nb = NbSurfaces();
1124 for ( Standard_Integer i = 1; i <= Nb; i++)
1125 LC.Append(myCenters(i));
1126}
1127
1128
1129//=======================================================================
1130//function : Surface
1131//purpose :
1132//=======================================================================
1133
1134Handle(Geom_Surface) BiTgte_Blend::Surface(const TopoDS_Shape& CenterLine)
1135const
1136{
1137 const TopoDS_Face& F = myMapSF(CenterLine).Face();
1138 return BRep_Tool::Surface(F);
1139}
1140
1141//=======================================================================
1142//function : TopoDS_Face&
1143//purpose :
1144//=======================================================================
1145
1146const TopoDS_Face& BiTgte_Blend::Face(const TopoDS_Shape& CenterLine) const
1147{
1148 if ( !myMapSF.IsBound(CenterLine)) {
1149 Standard_DomainError::Raise("BiTgte_Blend::Face");
1150 }
1151
1152 return myMapSF(CenterLine).Face();
1153}
1154
1155//=======================================================================
1156//function : ContactType
1157//purpose :
1158//=======================================================================
1159
1160BiTgte_ContactType BiTgte_Blend::ContactType(const Standard_Integer Index)
1161 const
1162{
1163 const TopoDS_Shape& S1 = SupportShape1(Index);
1164 const TopoDS_Shape& S2 = SupportShape2(Index);
1165
1166 TopAbs_ShapeEnum Type1 = S1.ShapeType();
1167 TopAbs_ShapeEnum Type2 = S2.ShapeType();
1168
1169 if (Type2 < Type1) {
1170 TopAbs_ShapeEnum Dummy = Type1;
1171 Type1 = Type2;
1172 Type2 = Dummy;
1173 }
1174 BiTgte_ContactType Type = BiTgte_VertexVertex;
1175
1176 switch (Type1) {
1177
1178 case TopAbs_VERTEX:
1179 switch (Type2) {
1180 case TopAbs_VERTEX: Type = BiTgte_VertexVertex; break;
1181 case TopAbs_EDGE: Type = BiTgte_EdgeVertex; break;
1182 case TopAbs_FACE: Type = BiTgte_FaceVertex; break;
1183 default:
1184 break;
1185 }
1186
1187 case TopAbs_EDGE:
1188 switch (Type2) {
1189 case TopAbs_EDGE: Type = BiTgte_EdgeEdge; break;
1190 case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
1191 default:
1192 break;
1193 }
1194
1195 case TopAbs_FACE:
1196 switch (Type2) {
1197 case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
1198 default:
1199 break;
1200 }
1201 default:
1202 break;
1203 }
1204
1205 return Type;
1206}
1207
1208
1209
1210//=======================================================================
1211//function : SupportShape1
1212//purpose :
1213//=======================================================================
1214
1215const TopoDS_Shape& BiTgte_Blend::SupportShape1(const Standard_Integer Index)
1216 const
1217{
1218 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1219
1220 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1221
1222 // --------------------------------------------------------------
1223 // F1 et F2 = les 2 faces paralleles qui s'intersectent en CurE.
1224 // --------------------------------------------------------------
1225 const TopoDS_Face& F1 = TopoDS::Face(L.First());
1226 const TopoDS_Shape& Or1 = myInitOffsetFace.ImageFrom(F1);
1227 return Or1;
1228}
1229
1230
1231//=======================================================================
1232//function : SupportShape2
1233//purpose :
1234//=======================================================================
1235
1236const TopoDS_Shape& BiTgte_Blend::SupportShape2(const Standard_Integer Index)
1237 const
1238{
1239 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1240
1241 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1242
1243 // --------------------------------------------------------------
1244 // F1 et F2 = les 2 faces paralleles qui s'intersectent en CurE.
1245 // --------------------------------------------------------------
1246 const TopoDS_Face& F2 = TopoDS::Face(L.Last());
1247 const TopoDS_Shape& Or2 = myInitOffsetFace.ImageFrom(F2);
1248 return Or2;
1249}
1250
1251
1252//=======================================================================
1253//function : CurveOnShape1
1254//purpose :
1255//=======================================================================
1256
1257Handle(Geom_Curve) BiTgte_Blend::CurveOnShape1
1258(const Standard_Integer Index) const
1259{
1260 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1261 const TopoDS_Shape& F = myMapSF(CurE).Face();
1262
1263 // methode un peu brutale basee UNIQUEMENT sur la construction du conge:
1264 // le premier edge du tuyau est justement celui sur Shape1.
1265
1266 TopExp_Explorer exp(F,TopAbs_EDGE);
1267 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1268 Handle(Geom_Curve) C;
1269 if ( !BRep_Tool::Degenerated(E)) {
1270 Standard_Real f,l;
1271 C = BRep_Tool::Curve(E,f,l);
1272 C = new Geom_TrimmedCurve(C,f,l);
1273 }
1274 return C;
1275}
1276
1277
1278//=======================================================================
1279//function : CurveOnShape2
1280//purpose :
1281//=======================================================================
1282
1283Handle(Geom_Curve) BiTgte_Blend::CurveOnShape2
1284(const Standard_Integer Index) const
1285{
1286 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1287 const TopoDS_Shape& F = myMapSF(CurE).Face();
1288
1289 // methode un peu brutale basee UNIQUEMENT sur la construction du conge:
1290 // le second edge du tuyau est justement celui sur Shape2.
1291
1292 TopExp_Explorer exp(F,TopAbs_EDGE);
1293 exp.Next();
1294 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1295 Handle(Geom_Curve) C;
1296 if ( !BRep_Tool::Degenerated(E)) {
1297 Standard_Real f,l;
1298 C = BRep_Tool::Curve(E,f,l);
1299 C = new Geom_TrimmedCurve(C,f,l);
1300 }
1301 return C;
1302}
1303
1304
1305//=======================================================================
1306//function : PCurveOnFace1
1307//purpose :
1308//=======================================================================
1309
1310Handle(Geom2d_Curve) BiTgte_Blend::PCurveOnFace1
1311(const Standard_Integer /*Index*/) const
1312{
1313 Handle(Geom2d_Curve) C;
1314 return C;
1315}
1316
1317
1318//=======================================================================
1319//function : PCurve1OnFillet
1320//purpose :
1321//=======================================================================
1322
1323Handle(Geom2d_Curve) BiTgte_Blend::PCurve1OnFillet
1324(const Standard_Integer /*Index*/) const
1325{
1326 Handle(Geom2d_Curve) C;
1327 return C;
1328}
1329
1330
1331//=======================================================================
1332//function : PCurveOnFace2
1333//purpose :
1334//=======================================================================
1335
1336Handle(Geom2d_Curve) BiTgte_Blend::PCurveOnFace2
1337(const Standard_Integer /*Index*/) const
1338{
1339 Handle(Geom2d_Curve) C;
1340 return C;
1341}
1342
1343
1344//=======================================================================
1345//function : Curve2OnFillet
1346//purpose :
1347//=======================================================================
1348
1349Handle(Geom2d_Curve) BiTgte_Blend::PCurve2OnFillet
1350(const Standard_Integer /*Index*/) const
1351{
1352 Handle(Geom2d_Curve) C;
1353 return C;
1354}
1355
1356
1357
1358//=======================================================================
1359//function : NbBranches
1360//purpose :
1361//=======================================================================
1362
1363Standard_Integer BiTgte_Blend::NbBranches()
1364{
1365 if (myNbBranches != -1) return myNbBranches;
1366
1367 // else, compute the Branches.
1368 BRepTools_Quilt Glue;
1369
1370 Standard_Integer NbFaces = myCenters.Extent();
1371
1372 // pour les cons qui veulent tout savoir avant le Calcul !!
1373 if (NbFaces == 0) return 0;
1374
1375 // pour les autres !!
1376 Standard_Integer i;
1377 for ( i = 1; i <= NbFaces; i++) {
1378 const TopoDS_Shape& CenterLine = myCenters(i);
1379 Glue.Add(myMapSF(CenterLine).Face());
1380 }
1381
1382 const TopoDS_Shape Shells = Glue.Shells();
1383
1384
1385 // On reordonne la Map myCenters.
1386 // La methode est brutale et vraisemblablement en n24,
1387 // on fera mieux plus tard.
1388 // Cela dit, je suis d'accord, ce n'est vraiment pas elegant !!!!!!!!
1389 myNbBranches = 0;
1390 TopTools_IndexedMapOfShape tmpMap;
1391
1392 TopExp_Explorer exp(Shells,TopAbs_SHELL);
1393 for (; exp.More(); exp.Next()) {
1394 myNbBranches++;
1395 }
1396
1397 myIndices = new TColStd_HArray1OfInteger(1,myNbBranches+1);
1398
1399 myIndices->SetValue(1,0);
1400 Standard_Integer Count = 0;
1401 Standard_Integer Index = 2;
1402
1403
1404 exp.Init(Shells,TopAbs_SHELL);
1405 for (; exp.More(); exp.Next()) {
1406 // CurS = le Shell courant.
1407 const TopoDS_Shape CurS = exp.Current();
1408
1409 TopExp_Explorer exp2(CurS, TopAbs_FACE);
1410 for (; exp2.More(); exp2.Next()) {
1411 // CurF = La face courante du Shell courant.
1412 const TopoDS_Shape CurF = exp2.Current();
1413
1414 for ( i = 1; i <= NbFaces; i++) {
1415 const TopoDS_Shape& Center = myCenters(i);
1416 const TopoDS_Shape& Rakk = myMapSF(Center).Face();
1417 // Rakk = la ieme face raccord generee
1418 if (CurF.IsEqual(Rakk)) {
1419 tmpMap.Add(Center);
1420 Count++;
1421 break;
1422 }
1423 }
1424 }
1425 myIndices->SetValue(Index, Count);
1426 Index++;
1427 }
1428
1429 myCenters = tmpMap;
1430 return myNbBranches;
1431}
1432
1433
1434//=======================================================================
1435//function : IndicesOfBranche
1436//purpose :
1437//=======================================================================
1438
1439void BiTgte_Blend::IndicesOfBranche
1440(const Standard_Integer Index,
1441 Standard_Integer& From,
1442 Standard_Integer& To ) const
1443{
1444 // Attention au rangement dans myIndices:
1445 // Si les branches sont 1-4 5-9 10-12, on range dans myIndices:
1446 // 0 4 9 12
1447 From = myIndices->Value(Index) + 1;
1448 To = myIndices->Value(Index + 1);
1449}
1450
1451
1452//=======================================================================
1453//function : ComputeCenters
1454//purpose :
1455//=======================================================================
1456
1457void BiTgte_Blend::ComputeCenters()
1458{
1459 // ------------
1460 // Preanalyse.
1461 // ------------
1462 Standard_Real TolAngle = 2*ASin(myTol/Abs(myRadius*0.5));
1463 myAnalyse.Perform(myShape,TolAngle);
1464
1465 // ------------------------------------------
1466 // calcul des faces touchees par les bouchons
1467 // ------------------------------------------
1468 TopTools_MapOfShape TouchedByCork;
1469 Touched(myAnalyse, myStopFaces, myShape, TouchedByCork);
1470
1471 // -----------------------
1472 // init de l'intersector
1473 // -----------------------
1474 TopAbs_State Side = TopAbs_IN;
1475 if (myRadius < 0.) Side = TopAbs_OUT;
1476 BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
1477
1478 BiTgte_DataMapOfShapeBox MapSBox;
1479 TopTools_MapOfShape Done;
1480 TopTools_MapIteratorOfMapOfShape it;
1481
1482 BRep_Builder B;
1483 TopoDS_Compound Co; // juste pour savoir sur quels edges on fait les tuyaux
1484 B.MakeCompound(Co);
1485
1486 // ----------------------------------------
1487 // Calcul Sections Face/Face + Propagation
1488 // ----------------------------------------
1489 Standard_Boolean JenRajoute = Standard_True;
1490
1491 while ( JenRajoute) {
1492 JenRajoute = Standard_False;
1493
1494 Standard_Boolean Fini = Standard_False;
1495
1496 TopTools_DataMapOfShapeShape EdgeTgt;
1497
1498 while ( !Fini) {
1499
1500 // -------------------------------------------------
1501 // on met dans myFaces les Faces connexes a myEdges.
1502 // -------------------------------------------------
1503 Fini = Standard_True;
1504 for (it.Initialize(myEdges); it.More(); it.Next()) {
1505 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
1506 if (BRep_Tool::Degenerated(E)) continue;
1507
1508 const TopTools_ListOfShape& L = myAncestors.FindFromKey(E);
1509 if ( L.Extent() == 1) {
1510 // Alors c'est un bord libre sur lequel la bille
1511 // doit rouler.
1512 myFaces.Add(E);
1513
1514 // on le mets dans myStopFaces pour ne pas propager sur
1515 // le tuyau sur bord libre.
1516 myStopFaces.Add(E);
1517 }
1518 else {
1519 TopTools_ListIteratorOfListOfShape itl;
1520 for (itl.Initialize(L); itl.More(); itl.Next()) {
1521 const TopoDS_Shape& Sh = itl.Value();
1522 if ( !myStopFaces.Contains(Sh)) myFaces.Add(itl.Value());
1523 }
1524 }
1525 }
1526 myEdges.Clear();
1527
1528 // --------------------------------------------
1529 // Construction des Offsets a toutes les faces.
1530 // --------------------------------------------
1531 for (it.Initialize(myFaces); it.More(); it.Next()) {
1532 const TopoDS_Shape& AS = it.Key();
1533 if ( myMapSF.IsBound(AS)) continue;
1534
1535 BRepOffset_Offset OF1;
1536 TopoDS_Face BigF;
1537
1538 if (AS.ShapeType() == TopAbs_FACE) {
1539 const TopoDS_Face& F = TopoDS::Face(it.Key());
1540 if ( TouchedByCork.Contains(F)) {
1541 BRepOffset_Tool::EnLargeFace(F,BigF,Standard_True);
1542 OF1.Init(BigF,myRadius,EdgeTgt);
1543 }
1544 else {
1545 OF1.Init(F,myRadius,EdgeTgt);
1546 }
1547 }
1548 else { // Alors c'est un edge Bord libre sur lequel la bille roule.
1549 OF1.Init(TopoDS::Edge(AS),myRadius);
1550 }
1551
1552 // ------------------------------------
1553 // Maj de la map des created tangents
1554 // ------------------------------------
1555 TopTools_ListOfShape Let;
1556 if ( AS.ShapeType() == TopAbs_FACE) {
1557 myAnalyse.Edges(TopoDS::Face(AS),BRepOffset_Tangent,Let);
1558 }
1559 TopTools_ListIteratorOfListOfShape itlet(Let);
1560
1561 for ( ; itlet.More(); itlet.Next()) {
1562 const TopoDS_Edge& Cur = TopoDS::Edge(itlet.Value());
1563 if ( !EdgeTgt.IsBound(Cur)) {
1564 TopoDS_Shape aLocalShape = OF1.Generated(Cur);
1565 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
1566// const TopoDS_Edge& OTE = TopoDS::Edge(OF1.Generated(Cur));
1567 EdgeTgt.Bind(Cur,OF1.Generated(Cur));
1568 TopoDS_Vertex V1,V2,OV1,OV2;
1569 TopExp::Vertices (Cur,V1,V2);
1570 TopExp::Vertices (OTE,OV1,OV2);
1571 TopTools_ListOfShape LE;
1572 if (!EdgeTgt.IsBound(V1)) {
1573 myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
1574 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V1);
1575 if (LE.Extent() == LA.Extent())
1576 EdgeTgt.Bind(V1,OV1);
1577 }
1578 if (!EdgeTgt.IsBound(V2)) {
1579 LE.Clear();
1580 myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
1581 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V2);
1582 if (LE.Extent() == LA.Extent())
1583 EdgeTgt.Bind(V2,OV2);
1584 }
1585 }
1586 }
1587 // fin MaJ map created tgt
1588
1589 if (OF1.Status() == BRepOffset_Reversed ||
1590 OF1.Status() == BRepOffset_Degenerated ) continue;
1591
1592 const TopoDS_Face& F1 = OF1.Face();
1593
1594 // maj S D
1595 myInitOffsetFace.SetRoot(AS);
1596 myInitOffsetFace.Bind(AS,F1);
1597
1598 Bnd_Box Box1;
1599 BRepBndLib::Add(F1,Box1);
1600 MapSBox.Bind(F1,Box1);
1601
1602 // ---------------------------------------------
1603 // intersection avec toutes les faces deja crees.
1604 // ---------------------------------------------
1605 Fini = !Intersect(AS,F1,MapSBox,OF1,Inter);
1606
1607 if (AS.ShapeType() == TopAbs_FACE) B.Add(Co,AS);
1608
1609 myMapSF.Bind(AS, OF1);
1610
1611 }
1612 } // end of : while ( !Fini)
1613
1614
1615 //--------------------------------------------------------
1616 // on a alors cree et intersecte les offsets.
1617 // on construit maintenant les tuyaux.
1618 //--------------------------------------------------------
1619 // Construction des tuyaux sur arete.
1620 //--------------------------------------------------------
1621 BRepOffset_Type OT = BRepOffset_Convex;
1622 if (myRadius < 0.) OT = BRepOffset_Concave;
1623
1624 TopTools_IndexedDataMapOfShapeListOfShape Map;
1625 TopExp::MapShapesAndAncestors(Co,TopAbs_EDGE,TopAbs_FACE,Map);
1626 TopExp::MapShapesAndAncestors(Co,TopAbs_VERTEX,TopAbs_EDGE,Map);
1627
1628 TopExp_Explorer exp(Co,TopAbs_EDGE);
1629 for ( ; exp.More(); exp.Next()) {
1630 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1631 if ( myMapSF.IsBound(E)) continue;
1632
1633 const TopTools_ListOfShape& Anc = Map.FindFromKey(E);
1634 if (Anc.Extent() == 2) {
1635 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1636 if (!L.IsEmpty() && L.First().Type() == OT) {
1637 TopoDS_Shape aLocalShape = myMapSF(Anc.First()).Generated(E);
1638 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1639 aLocalShape = myMapSF(Anc.Last()) .Generated(E);
1640 TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
1641// TopoDS_Edge EOn1 = TopoDS::Edge(myMapSF(Anc.First()).Generated(E));
1642// TopoDS_Edge EOn2 = TopoDS::Edge(myMapSF(Anc.Last()) .Generated(E));
1643 // find if exits tangent edges in the original shape
1644 TopoDS_Edge E1f, E1l;
1645 TopoDS_Vertex V1f, V1l;
1646 TopExp::Vertices(E,V1f,V1l);
1647 TopTools_ListOfShape TangE;
1648 myAnalyse.TangentEdges(E,V1f,TangE);
1649 // find if the pipe on the tangent edges are soon created.
1650 TopTools_ListIteratorOfListOfShape itl(TangE);
1651 Standard_Boolean Find = Standard_False;
1652 for ( ; itl.More() && !Find; itl.Next()) {
1653 if ( myMapSF.IsBound(itl.Value())) {
1654 TopoDS_Shape aLocalShape = myMapSF(itl.Value()).Generated(V1f);
1655 E1f = TopoDS::Edge(aLocalShape);
1656// E1f = TopoDS::Edge(myMapSF(itl.Value()).Generated(V1f));
1657 Find = Standard_True;
1658 }
1659 }
1660 TangE.Clear();
1661 myAnalyse.TangentEdges(E,V1l,TangE);
1662 // find if the pipe on the tangent edges are soon created.
1663 itl.Initialize(TangE);
1664 Find = Standard_False;
1665 for ( ; itl.More() && !Find; itl.Next()) {
1666 if ( myMapSF.IsBound(itl.Value())) {
1667 TopoDS_Shape aLocalShape = myMapSF(itl.Value()).Generated(V1l);
1668 E1l = TopoDS::Edge(aLocalShape);
1669// E1l = TopoDS::Edge(myMapSF(itl.Value()).Generated(V1l));
1670 Find = Standard_True;
1671 }
1672 }
1673 BRepOffset_Offset OF1 (E,EOn1,EOn2,myRadius,E1f, E1l);
1674 const TopoDS_Face& F1 = OF1.Face();
1675
1676 // maj S D
1677 myInitOffsetFace.SetRoot(E);
1678 myInitOffsetFace.Bind(E,F1);
1679
1680 Bnd_Box Box1;
1681 BRepBndLib::Add(F1,Box1);
1682 MapSBox.Bind(F1,Box1);
1683
1684 // ---------------------------------------------
1685 // intersection avec toutes les faces deja crees.
1686 // ---------------------------------------------
1687 Standard_Boolean IsOnRest = Intersect(E,F1,MapSBox,OF1,Inter);
1688 JenRajoute = JenRajoute || IsOnRest;
1689
1690 myMapSF.Bind(E,OF1);
1691 }
1692 }
1693 }
1694
1695 } // fin while JenRajoute
1696
1697
1698 myEdges.Clear();
1699 myEdges = Inter.NewEdges();
1700
1701 // -------------------------------------------------------------------
1702 // il faut maintenant restreindre les edges sur les voisins (sinon on
1703 // va trop loin et on ne peut plus construire les faces).
1704 // -------------------------------------------------------------------
1705
1706 // On y va avec le MakeLoops
1707
1708 BRepOffset_Type OT = BRepOffset_Concave;
1709 if (myRadius < 0.) OT = BRepOffset_Convex;
1710
1711 it.Initialize(myFaces);
1712 TopTools_ListOfShape LOF;
1713 for ( ; it.More(); it.Next()) {
1714 const TopoDS_Shape& CurS = it.Key();
1715
1716 // tuyau sur bord libre, on n en veut pas.
1717 if ( myStopFaces.Contains(CurS)) continue;
1718
1719 if ( !myMapSF.IsBound(CurS)) continue; // inverted ou degenere
1720
1721 const TopoDS_Face& CurOF = myMapSF(CurS).Face();
1722 LOF.Append(CurOF);
1723
1724 if (CurS.ShapeType() == TopAbs_FACE) {
1725 const TopoDS_Face& CurF = TopoDS::Face(CurS);
1726 TopExp_Explorer expe(CurF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1727 for (; expe.More(); expe.Next()) {
1728 // --------------------------------------------------------------
1729 // on met dans myAsDes les edges generes par les restrictions du
1730 // carreau initial si du bon type (On ne met pas les edges qui
1731 // vont disparaitre)
1732 // --------------------------------------------------------------
1733 const TopoDS_Edge& CurE = TopoDS::Edge(expe.Current());
1734 const BRepOffset_ListOfInterval& L = myAnalyse.Type(CurE);
1735 if (!L.IsEmpty() && L.First().Type() != OT) {
1736 // a priori ne disparait pas, donc on le met
1737 TopoDS_Shape aLocalShape = myMapSF(CurF).Generated(CurE);
1738 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
1739// const TopoDS_Edge& CurOE =
1740// TopoDS::Edge(myMapSF(CurF).Generated(CurE));
1741 myAsDes->Add(CurOF,CurOE.Oriented(CurE.Orientation()));
1742 }
1743 else {
1744 const TopTools_ListOfShape& Lanc = myAnalyse.Ancestors(CurE);
1745 if ( !myFaces .Contains(Lanc.First())
1746 || !myFaces .Contains(Lanc.Last ())
1747 || myStopFaces.Contains(Lanc.First())
1748 || myStopFaces.Contains(Lanc.Last ())) {
1749 TopoDS_Shape aLocalShape = myMapSF(CurF).Generated(CurE);
1750 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
1751// const TopoDS_Edge& CurOE =
1752// TopoDS::Edge(myMapSF(CurF).Generated(CurE));
1753 myAsDes->Add(CurOF,CurOE.Oriented(CurE.Orientation()));
1754 }
1755 }
1756 }
1757 BRepOffset_Inter2d::Compute(myAsDes,
1758 CurOF,
1759 myEdges,
1760 myTol);
1761 }
1762 }
1763
1764 // ----------------------------------------------------------------
1765 // Il faut aussi faire les intersections 2d avec les tuyaux generes
1766 // (Utile au debouclage)
1767 // ----------------------------------------------------------------
1768 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(myMapSF);
1769 for ( ; It.More(); It.Next()) {
1770 const TopoDS_Shape& CurS = It.Key();
1771 if ( CurS.ShapeType() == TopAbs_FACE) continue;
1772
1773 const TopoDS_Face& CurOF = It.Value().Face();
1774
1775 // on ne deboucle pas les tuyaux sur bord libre.
1776 if ( myStopFaces.Contains(CurS)) continue;
1777
1778 LOF.Append(CurOF);
1779
1780 // --------------------------------------------------------------
1781 // on met dans myAsDes les edges restrictions du carreau.
1782 // --------------------------------------------------------------
1783 TopExp_Explorer expe(CurOF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1784 for (; expe.More(); expe.Next()) {
1785 const TopoDS_Edge& CurOE = TopoDS::Edge(expe.Current());
1786 myAsDes->Add(CurOF,CurOE);
1787 }
1788
1789 BRepOffset_Inter2d::Compute(myAsDes,
1790 CurOF,
1791 myEdges,
1792 myTol);
1793 }
1794 // ------------
1795 // On deboucle
1796 // ------------
1797 BRepOffset_MakeLoops MakeLoops;
1798 MakeLoops.Build( LOF, myAsDes, myImageOffset );
1799
1800 // ------------------------------------------------------------
1801 // On a deboucle les edges dont l'un au moins des ancetres est
1802 // une face du shape initial, donc:
1803 // il manque les edges generes par intersection tuyau-tuyau
1804 // ------------------------------------------------------------
1805
1806 // --------------------------------------------------------------
1807 // On met pour l'instant dans <myResult> les surfaces debouclees
1808 // --------------------------------------------------------------
1809 B.MakeCompound(TopoDS::Compound(myResult));
1810 TopTools_ListIteratorOfListOfShape itLOF(LOF);
1811 for ( ; itLOF.More(); itLOF.Next()) {
1812 const TopoDS_Shape& CurLOF = itLOF.Value();
1813
1814 if ( !myImageOffset.HasImage(CurLOF))
1815 continue;
1816
1817 TopTools_ListOfShape Lim;
1818 myImageOffset.LastImage(CurLOF,Lim);
1819 TopTools_ListIteratorOfListOfShape itLim(Lim);
1820 for ( ;itLim.More(); itLim.Next()) {
1821 // Si une face est sa propre image, on ne la mets pas
1822 const TopoDS_Shape& CurLIM = itLim.Value();
1823 if (CurLIM.IsSame(CurLOF)) break;
1824
1825 B.Add(myResult,CurLIM);
1826 }
1827 }
1828
1829#ifdef DEB
1830 if ( myResult.IsNull()) {
1831 cout << " Pas de Lignes de Centres Generees" << endl;
1832 }
1833#ifdef DRAW
1834 else {
1835 if (Affich) DBRep::Set("Debouc",myResult);
1836 }
1837#endif
1838#endif
1839}
1840
1841
1842//=======================================================================
1843//function : ComputeSurfaces
1844//purpose :
1845//=======================================================================
1846
1847void BiTgte_Blend::ComputeSurfaces()
1848{
1849 // on met dans myFaces, les faces reellement impliquee dans
1850 // le raccord
1851 myFaces.Clear();
1852
1853 // on construit
1854 // 1 - Les Tuyaux ( Les Vrais Conges)
1855 // 2 - Les Spheres.
1856
1857#ifdef DRAW
1858 Standard_Integer nbc = 1;
1859#endif
1860
1861 TopTools_ListOfShape Empty;
1862 TopTools_DataMapOfShapeListOfShape EmptyMap;
1863
1864 Handle(Geom_Surface) GS1, GS2;
1865 Handle(Geom_Curve) GC1, GC2;
1866
1867 Standard_Real TolAngle = 2*ASin(myTol/Abs(myRadius*0.5));
1868 BRepOffset_Analyse CenterAnalyse(myResult,TolAngle);
1869
1870 // -----------------------------------------------------
1871 // Construction des tuyaux que l'on benne dans myResult
1872 // -----------------------------------------------------
1873 BRep_Builder B;
1874 B.MakeCompound(TopoDS::Compound(myResult));
1875
1876 // --------------------------------------------------------------------
1877 // Dummy: pour construction des spheres:
1878 // On met dans Co les lignes de centres, puis si il existe au moins 3
1879 // ligne de centre partageant un meme vertex, Sphere sur ce vertex.
1880 // --------------------------------------------------------------------
1881 TopoDS_Compound Co;
1882 B.MakeCompound(Co);
1883
1884 // --------------------------------------------------------------------
1885 // Iteration sur les les edges lignes de centre
1886 // et On prend leur partie valide apres decoupe, et construction tuyau.
1887 // --------------------------------------------------------------------
1888 BRepOffset_Type OT = BRepOffset_Concave;
1889 if (myRadius < 0.) OT = BRepOffset_Convex;
1890
1891 TopTools_MapIteratorOfMapOfShape ic(myEdges);
1892 for ( ; ic.More(); ic.Next()) {
1893 const TopoDS_Edge& CurE = TopoDS::Edge(ic.Key());
1894
1895 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1896 if ( L.Extent() != 2) continue;
1897
1898 // --------------------------------------------------------------
1899 // F1 et F2 = les 2 faces paralleles qui s'intersectent en CurE.
1900 // --------------------------------------------------------------
1901 const TopoDS_Face& F1 = TopoDS::Face(L.First());
1902 const TopoDS_Face& F2 = TopoDS::Face(L.Last());
1903
1904 // -----------------------------------------------------
1905 // on cherche les orientations des edges d'intersection
1906 // dans les faces initiales.
1907 // -----------------------------------------------------
1908 const TopTools_ListOfShape& LD1 = myAsDes->Descendant(F1);
1909 const TopTools_ListOfShape& LD2 = myAsDes->Descendant(F2);
1910
1911 TopAbs_Orientation Orien1 = Orientation(CurE, F1, LD1);
1912 TopAbs_Orientation Orien2 = Orientation(CurE, F2, LD2);
1913
1914 // ---------------------------------------------------------
1915 // Or1 et Or2 : les shapes generateurs des faces paralleles.
1916 // ---------------------------------------------------------
1917 const TopoDS_Shape& Or1 = myInitOffsetFace.ImageFrom(F1);
1918 const TopoDS_Shape& Or2 = myInitOffsetFace.ImageFrom(F2);
1919
1920 myFaces.Add(Or1);
1921 myFaces.Add(Or2);
1922
1923 TopoDS_Edge OE1, OE2;
1924 TopoDS_Face OF1, OF2;
1925 TopLoc_Location Loc;
1926 Standard_Real f1,l1,f2,l2;
1927
1928 Standard_Boolean OF1isEdge = Standard_False;
1929
1930 if ( Or1.ShapeType() == TopAbs_EDGE) {
1931 OF1isEdge = Standard_True;
1932 OE1 = TopoDS::Edge(Or1);
1933 GC1 = BRep_Tool::Curve(OE1,Loc,f1,l1);
1934 GC1 =
1935 Handle(Geom_Curve)::DownCast(GC1->Transformed(Loc.Transformation()));
1936 }
1937 else if ( Or1.ShapeType() == TopAbs_FACE) {
1938 OF1 = TopoDS::Face(Or1);
1939 GS1 = BRep_Tool::Surface(OF1);
1940 }
1941
1942 // ----------------------------------------------------------------
1943 // Si mise en jeu d'un vertex dans le contact, on ne fait rien
1944 // pour l'instant on ne gere pas les vertex ( Inters avec sphere);
1945 // ----------------------------------------------------------------
1946 if ( OF1.IsNull() && OE1.IsNull()) continue;
1947
1948 Standard_Boolean OF2isEdge = Standard_False;
1949
1950 if ( Or2.ShapeType() == TopAbs_EDGE) {
1951 OF2isEdge = Standard_True;
1952 OE2 = TopoDS::Edge(Or2);
1953 GC2 = BRep_Tool::Curve(OE2,Loc,f2,l2);
1954 GC2 =
1955 Handle(Geom_Curve)::
1956 DownCast(GC2->Transformed(Loc.Transformation()));
1957 }
1958 else if ( Or2.ShapeType() == TopAbs_FACE) {
1959 OF2 = TopoDS::Face(Or2);
1960 GS2 = BRep_Tool::Surface(OF2);
1961 }
1962 // ----------------------------------------------------------------
1963 // Si mise en jeu d'un vertex dans le contact, on ne fait rien
1964 // pour l'instant on ne gere pas les vertex ( Inters avec sphere);
1965 // ----------------------------------------------------------------
1966 if ( OF2.IsNull() && OE2.IsNull()) continue;
1967
1968
1969 TopTools_ListOfShape CurL;
1970
1971 if ( !myImageOffset.HasImage(CurE)) {// les tuyaux ne sont pas deboucles
1972 if ( OF1isEdge && OF2isEdge) { // si je n'ai pas d'image, peut etre
1973 CurL.Append(CurE); // suis-je sur inters tuyau tuyau
1974 } // Voir commentaire sur l'appel a
1975 else // MakeLoops
1976 continue;
1977 }
1978 else {
1979 myImageOffset.LastImage(CurE,CurL);
1980 }
1981
1982 // ---------------------------------------------------------------
1983 // CurL = List des edges descendant de CurE ( = Decoupes de CurE)
1984 // ---------------------------------------------------------------
1985 TopTools_ListIteratorOfListOfShape itl(CurL);
1986 for ( ; itl.More(); itl.Next()) {
1987 const TopoDS_Edge& CurCutE = TopoDS::Edge(itl.Value());
1988
1989 Handle(Geom2d_Curve) PC1 =
1990 BRep_Tool::CurveOnSurface(CurCutE,F1,f1,l1);
1991 Handle(Geom2d_Curve) PC2 =
1992 BRep_Tool::CurveOnSurface(CurCutE,F2,f2,l2);
1993 if ( PC1.IsNull() || PC2.IsNull()) {
1994#ifdef DEB
1995 cout << "Pas de PCurves sur Intersections : Pas de tuyau construit";
1996 cout << endl;
1997#endif
1998 continue;
1999 }
2000
2001 TopoDS_Edge E1f, E1l;
2002 TopoDS_Vertex V1f, V1l;
2003 TopoDS_Vertex VfOnE1,VlOnE1,VfOnE2,VlOnE2;
2004 TopTools_ListOfShape TangE;
2005 TopTools_MapOfShape MapOnV1f, MapOnV1l;
2006
2007 TopExp::Vertices(CurCutE,V1f,V1l);
2008
2009 // find if the pipe on the tangent edges are soon created.
2010 // edges generes par V1f et V1l + Maj MapOnV1f/l
2011 E1f = FindCreatedEdge(V1f,CurCutE,myMapSF,MapOnV1f,
2012 CenterAnalyse,myRadius,myTol);
2013
2014 E1l = FindCreatedEdge(V1l,CurCutE,myMapSF,MapOnV1l,
2015 CenterAnalyse,myRadius,myTol);
2016
2017 TopoDS_Edge E1, E2;
2018 if ( OF1isEdge) {
2019 BiTgte_CurveOnEdge ConE(CurCutE, OE1);
2020 Handle(Geom_Curve) C = MakeCurve(ConE);
2021 gp_Pnt P1 = C->Value(C->FirstParameter());
2022 gp_Pnt P2 = C->Value(C->LastParameter());
2023 VfOnE1 = FindVertex(P1,MapOnV1f,myTol);
2024 if ( VfOnE1.IsNull())
2025 VfOnE1 = FindVertex(P1,MapOnV1l,myTol);
2026 VlOnE1 = FindVertex(P2,MapOnV1l,myTol);
2027 if ( VlOnE1.IsNull())
2028 VlOnE1 = FindVertex(P2,MapOnV1f,myTol);
2029 if ( P1.SquareDistance(P2) < myTol*myTol) {
2030 //BRepOffset_Offset gere les KPart degeneres
2031 //IL FAUT que C soit un cercle de rayon NUL
2032 E1 = MakeDegeneratedEdge(C,VfOnE1);
2033 }
2034 else {
2035 E1 = BRepLib_MakeEdge(C,VfOnE1,VlOnE1);
2036 }
2037 }
2038 else {
2039 gp_Pnt2d P2d;
2040 P2d = PC1->Value(f1);
2041 gp_Pnt P1 = GS1->Value(P2d.X(),P2d.Y());
2042 P2d = PC1->Value(l1);
2043 gp_Pnt P2 = GS1->Value(P2d.X(),P2d.Y());
2044 VfOnE1 = FindVertex(P1,MapOnV1f,myTol);
2045 VlOnE1 = FindVertex(P2,MapOnV1l,myTol);
2046 BRepLib_MakeEdge MKE(PC1,GS1,VfOnE1,VlOnE1,f1,l1);
2047 if (MKE.IsDone())
2048 E1 = MKE.Edge();
2049 else {
2050 cout << "Edge Not Done" << endl;
2051 E1 = MKE.Edge();
2052 }
2053
2054 KPartCurve3d(E1,PC1,GS1);
2055 }
2056
2057 if ( OF2isEdge) {
2058 BiTgte_CurveOnEdge ConE(CurCutE, OE2);
2059 Handle(Geom_Curve) C = MakeCurve(ConE);
2060 gp_Pnt P1 = C->Value(C->FirstParameter());
2061 gp_Pnt P2 = C->Value(C->LastParameter());
2062 VfOnE2 = FindVertex(P1,MapOnV1f,myTol);
2063 if ( VfOnE2.IsNull())
2064 VfOnE2 = FindVertex(P1,MapOnV1l,myTol);
2065 VlOnE2 = FindVertex(P2,MapOnV1l,myTol);
2066 if ( VlOnE2.IsNull())
2067 VlOnE2 = FindVertex(P2,MapOnV1f,myTol);
2068 if ( P1.SquareDistance(P2) < myTol*myTol) {
2069 //BRepOffset_Offset gere les KPart degeneres
2070 //IL FAUT que C soit un cercle de rayon NUL
2071 E2 = MakeDegeneratedEdge(C,VfOnE2);
2072 }
2073 else {
2074 E2 = BRepLib_MakeEdge(C,VfOnE2,VlOnE2);
2075 }
2076 }
2077 else {
2078 gp_Pnt2d P2d;
2079 P2d = PC2->Value(f2);
2080 gp_Pnt P1 = GS2->Value(P2d.X(),P2d.Y());
2081 P2d = PC2->Value(l2);
2082 gp_Pnt P2 = GS2->Value(P2d.X(),P2d.Y());
2083 VfOnE2 = FindVertex(P1,MapOnV1f,myTol);
2084 VlOnE2 = FindVertex(P2,MapOnV1l,myTol);
2085 BRepLib_MakeEdge MKE(PC2,GS2,VfOnE2,VlOnE2,f2,l2);
2086 if (MKE.IsDone())
2087 E2 = MKE.Edge();
2088 else {
2089 cout << "edge not Done" << endl;
2090 E2 = MKE.Edge();
2091 }
2092 KPartCurve3d(E2,PC2,GS2);
2093 }
2094 // Maj de la Map des Created si reconstruction du Shape est demandee.
2095 if ( myBuildShape) {
2096 myCreated.Bind(CurCutE,EmptyMap);
2097
2098 myCreated(CurCutE).Bind(Or1,Empty);
2099 myCreated(CurCutE)(Or1).Append(E1);
2100
2101 myCreated(CurCutE).Bind(Or2,Empty);
2102 myCreated(CurCutE)(Or2).Append(E2);
2103 }
2104
2105 // ----------------------------------------------------------
2106 // try to init E1f, E1l, if not found with Analysis.
2107 // Ne devrait se produire que si les edges tangents THEORIQUES
2108 // ne sont pas reelememt tangent ( Cf: Approx des lignes
2109 // d'intersection qui bruitent)
2110 // ----------------------------------------------------------
2111 TopoDS_Vertex V1,V2;
2112 if ( E1f.IsNull() && !VfOnE1.IsNull() && !VfOnE2.IsNull()) {
2113 TopTools_MapIteratorOfMapOfShape it(MapOnV1f);
2114 for ( ; it.More(); it.Next()) {
2115 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
2116 if ( !E.IsNull()) {
2117 TopExp::Vertices(E,V1,V2);
2118 if ((V1.IsSame(VfOnE1) && V2.IsSame(VfOnE2)) ||
2119 (V2.IsSame(VfOnE1) && V1.IsSame(VfOnE2)) ) {
2120 E1f = E;
2121 break;
2122 }
2123 }
2124 }
2125 }
2126 if ( E1l.IsNull() && !VlOnE1.IsNull() && !VlOnE2.IsNull()) {
2127 TopTools_MapIteratorOfMapOfShape it(MapOnV1l);
2128 for ( ; it.More(); it.Next()) {
2129 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
2130 if ( !E.IsNull()) {
2131 TopExp::Vertices(E,V1,V2);
2132 if ((V1.IsSame(VlOnE1) && V2.IsSame(VlOnE2)) ||
2133 (V2.IsSame(VlOnE1) && V1.IsSame(VlOnE2)) ) {
2134 E1l = E;
2135 break;
2136 }
2137 }
2138 }
2139 }
2140
2141 E1.Orientation(Orien1);
2142 E2.Orientation(Orien2);
2143
2144 BRepOffset_Offset AnOffset(CurCutE,E1,E2,-myRadius,E1f,E1l,
2145 myNubs, myTol, GeomAbs_C2);
2146 myMapSF.Bind(CurCutE,AnOffset);
2147 myCenters.Add(CurCutE);
2148 B.Add(Co, CurCutE);
2149
2150 const TopoDS_Face& Tuyo = AnOffset.Face();
2151 B.Add(myResult,Tuyo);
2152
2153 if ( myBuildShape) {
2154 // methode basee UNIQUEMENT sur la construction du conge:
2155 // le premier edge du tuyau est justement celui sur Shape1.
2156 GeomAPI_ProjectPointOnCurve Projector;
2157 TopExp_Explorer exp(Tuyo,TopAbs_EDGE);
2158 TopoDS_Vertex V1,V2;
2159 if (OF1isEdge) { // On met les CutEdges a jour.
2160 const TopoDS_Edge& EOnF1 = TopoDS::Edge(exp.Current());
2161 TopExp::Vertices(EOnF1,V1,V2);
2162
2163 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2164 Projector.Init(P1,GC1);
2165 Standard_Real U1 = Projector.LowerDistanceParameter();
2166
2167 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2168 Projector.Init(P2,GC1);
2169 Standard_Real U2 = Projector.LowerDistanceParameter();
2170
2171 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
2172 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,TopoDS::Edge(Or1),myTol);
2173 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
2174 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,TopoDS::Edge(Or1),myTol);
2175// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),U1,
2176// TopoDS::Edge(Or1),myTol);
2177// B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),U2,
2178// TopoDS::Edge(Or1),myTol);
2179
2180 if (!myCutEdges.IsBound(Or1)) {
2181 TopTools_ListOfShape Dummy;
2182 myCutEdges.Bind(Or1,Dummy);
2183 }
2184 TopTools_ListOfShape& L1 = myCutEdges(Or1);
2185 L1.Append(V1); L1.Append(V2);
2186 }
2187 if (OF2isEdge) { // On met les CutEdges a jour.
2188 exp.Next();
2189 const TopoDS_Edge& EOnF2 = TopoDS::Edge(exp.Current());
2190 TopExp::Vertices(EOnF2,V1,V2);;
2191
2192 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2193 Projector.Init(P1,GC2);
2194 Standard_Real U1 = Projector.LowerDistanceParameter();
2195
2196 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2197 Projector.Init(P2,GC2);
2198 Standard_Real U2 = Projector.LowerDistanceParameter();
2199
2200 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
2201 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,TopoDS::Edge(Or2),myTol);
2202 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
2203 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,TopoDS::Edge(Or2),myTol);
2204// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),U1,
2205// TopoDS::Edge(Or2),myTol);
2206// B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),U2,
2207// TopoDS::Edge(Or2),myTol);
2208
2209 if (!myCutEdges.IsBound(Or2)) {
2210 TopTools_ListOfShape Dummy;
2211 myCutEdges.Bind(Or2,Dummy);
2212 }
2213 TopTools_ListOfShape& L2 = myCutEdges(Or2);
2214 L2.Append(V1); L2.Append(V2);
2215 }
2216 }
2217
2218#ifdef DRAW
2219 if ( Affich) {
2220 sprintf(name,"%s_%d","SURF",nbc);
2221 DBRep::Set(name,AnOffset.Face());
2222 nbc++;
2223 }
2224#endif
2225 }
2226 }
2227
2228 // ---------------------------------------------------
2229 // Construction des spheres,
2230 // si nombre suffisant de tuyaux arrive sur le vertex
2231 // ---------------------------------------------------
2232 TopTools_IndexedDataMapOfShapeListOfShape Map;
2233 TopExp::MapShapesAndAncestors(Co,TopAbs_VERTEX,TopAbs_EDGE,Map);
2234
2235 for ( Standard_Integer i = 1; i <= Map.Extent(); i++) {
2236 const TopoDS_Vertex& V = TopoDS::Vertex(Map.FindKey(i));
2237 if ( Map(i).Extent() != 3) continue;
2238
2239 TopTools_ListOfShape LOE;
2240 TopTools_ListIteratorOfListOfShape it;
2241
2242 for (it.Initialize(Map(i)) ; it.More(); it.Next()) {
2243 Standard_Boolean Reverse = Standard_True;
2244 if ( Reverse)
2245 LOE.Append(myMapSF(it.Value()).Generated(V).Reversed());
2246 else
2247 LOE.Append(myMapSF(it.Value()).Generated(V));
2248 }
2249
2250 BRepOffset_Offset OFT(V,LOE,-myRadius,myNubs, myTol, GeomAbs_C2);
2251 myMapSF.Bind(V,OFT);
2252 myCenters.Add(V);
2253
2254 B.Add(myResult,OFT.Face());
2255
2256#ifdef DRAW
2257 if (Affich) {
2258 sprintf(name,"%s_%d","SURF",nbc);
2259 DBRep::Set(name,OFT.Face());
2260 nbc++;
2261 }
2262#endif
2263 }
2264}
2265
2266
2267//=======================================================================
2268//function : ComputeShape
2269//purpose :
2270//=======================================================================
2271#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
2272
2273void BiTgte_Blend::ComputeShape()
2274{
2275 // On trouvera dans le Shape final:
2276 // - les Faces non touchees.
2277 // - les tuyaux generes
2278 // - les faces voisines des tuyaux qu'il faut reconstruire en assurant
2279 // le partage.
2280
2281 // Pour Debug : Visu des edges du shape initial qui sont a reconstruire.
2282#ifdef DRAW
2283 if (Affich) {
2284 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myCutEdges);
2285 Standard_Integer NbEdges = 0;
2286 for ( ; itm.More(); itm.Next()) {
2287 const TopoDS_Edge& E = TopoDS::Edge(itm.Key());
2288 const TopTools_ListOfShape& VonE = itm.Value();
2289 TopTools_ListOfShape NewE;
2290
2291 CutEdge(E,VonE,NewE);
2292 for (TopTools_ListIteratorOfListOfShape it(NewE); it.More(); it.Next()) {
2293 sprintf(name,"%s_%d","CUTE",++NbEdges);
2294 DBRep::Set(name,it.Value());
2295 }
2296 }
2297 }
2298#endif
2299 // fin debug
2300
2301 //
2302 // On modifie les tuyaux sur arete pour le partage des edges.
2303 //
2304 Standard_Integer NbS = NbSurfaces();
2305 NbS = 0;
2306 for (Standard_Integer i = 1; i <= NbS; i++) {
2307 const TopoDS_Shape& S1 = SupportShape1(i);
2308
2309 if ( S1.ShapeType() == TopAbs_EDGE) {
2310 const TopoDS_Edge& E1 = TopoDS::Edge(S1);
2311 // il faut remplacer dans F, les edges decoupe de E1, qui
2312 // representent CutE
2313 const TopTools_ListOfShape& VonE = myCutEdges(E1);
2314 TopTools_ListOfShape NewE;
2315 CutEdge(E1,VonE,NewE);
2316
2317 }
2318 }
2319
2320
2321 TopTools_DataMapOfShapeShape Created;
2322
2323 TopTools_ListOfShape Empty;
2324 TopTools_DataMapOfShapeListOfShape EmptyMap;
2325
2326 BRep_Builder B;
2327
2328#ifdef DRAW
2329 Standard_Integer NbNT = 1;
2330#endif
2331
2332 // Maj de la Map des created.
2333 // On met a jour les edges qui ne changent pas dans le shape resultat
2334 // i.e. les edges invariants dans le debouclage.
2335 TopExp_Explorer exp(myShape,TopAbs_FACE);
2336 // Standard_Integer nbe = 1;
2337 for ( ;exp.More(); exp.Next()) {
2338
2339 const TopoDS_Face& CurF = TopoDS::Face(exp.Current());
2340
2341 if ( !myFaces.Contains(CurF)) continue; // alors la face n'est pas touchee
2342
2343 // alors les faces sont debouclees
2344 if ( !myMapSF.IsBound(CurF)) continue; // inverted ou degenere
2345
2346 const BRepOffset_Offset& Offset = myMapSF(CurF);
2347 const TopoDS_Face& CurOF = myMapSF(CurF).Face();
2348
2349 if ( !myImageOffset.HasImage(CurOF)) // face disparait dans debouclage
2350 continue;
2351
2352 TopExp_Explorer exp2(CurF,TopAbs_EDGE);
2353 for ( ;exp2.More(); exp2.Next()) {
2354 const TopoDS_Edge& CurE = TopoDS::Edge(exp2.Current());
2355 TopoDS_Shape aLocalShape = Offset.Generated(CurE);
2356 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
2357// const TopoDS_Edge& CurOE = TopoDS::Edge(Offset.Generated(CurE));
2358
2359 if (!myImageOffset.HasImage(CurOE)) continue;
2360 // CurOE disparait
2361
2362 const TopoDS_Edge& ImE =
2363 TopoDS::Edge(myImageOffset.Image(CurOE).First());
2364 if (ImE.IsSame(CurOE)) {
2365 myCreated.Bind(CurOE,EmptyMap);
2366 myCreated(CurOE).Bind(CurF,Empty);
2367 myCreated(CurOE)(CurF).Append(CurE);
2368 }
2369 }
2370 }
2371
2372 // Les faces raccords sont deja dans myResult.
2373 // Il faut alors rajouter les faces:
2374 // - non touchees (donc pas dans myFaces)
2375 // - issues du debouclage(non degenerees, non inverted, non disparues)
2376 exp.Init(myShape,TopAbs_FACE);
2377 for ( ;exp.More(); exp.Next()) {
2378
2379 const TopoDS_Face& CurF = TopoDS::Face(exp.Current());
2380
2381 if ( !myFaces.Contains(CurF)) {
2382 // alors la face n'est pas touchee
2383 B.Add(myResult,CurF);
2384 }
2385 else { // alors les faces sont debouclees
2386
2387 if ( !myMapSF.IsBound(CurF)) continue; // inverted ou degenere
2388
2389 const TopoDS_Face& CurOF = myMapSF(CurF).Face();
2390
2391 if ( !myImageOffset.HasImage(CurOF)) // face disparait dans debouclage
2392 continue;
2393
2394 // Liste des faces generees par une face dans le debouclage.
2395 TopTools_ListOfShape Lim;
2396 myImageOffset.LastImage(CurOF,Lim);
2397 TopTools_ListIteratorOfListOfShape itLim(Lim);
2398 for ( ;itLim.More(); itLim.Next()) {
2399 // DeboucFace = La Face offset debouclee dans "Debouc".
2400 const TopoDS_Face& DeboucFace = TopoDS::Face(itLim.Value());
2401
2402 TopLoc_Location L;
2403 Handle(Geom_Surface) S = BRep_Tool::Surface(CurF,L);
2404
2405 TopoDS_Face NewF; B.MakeFace(NewF);
2406 B.UpdateFace(NewF,S,L,BRep_Tool::Tolerance(CurF));
2407
2408 TopTools_DataMapOfShapeShape MapSS;
2409
2410 TopoDS_Shape aLocalShape = DeboucFace.Oriented(TopAbs_FORWARD);
2411 const TopoDS_Face& Face = TopoDS::Face(aLocalShape);
2412// const TopoDS_Face& Face =
2413// TopoDS::Face(DeboucFace.Oriented(TopAbs_FORWARD));
2414 TopExp_Explorer exp2(Face, TopAbs_EDGE);
2415 for ( ; exp2.More(); exp2.Next()) {
2416 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
2417 TopoDS_Vertex V1,V2,OV1,OV2;
2418 TopExp::Vertices(E ,V1 ,V2 );
2419 if (myCreated.IsBound(E)) {
2420 if (myCreated(E).IsBound(CurF)) {
2421 const TopoDS_Edge& OE = TopoDS::Edge(myCreated(E)(CurF).First());
2422 TopExp::Vertices(OE,OV1,OV2);
2423 if ( !myCreated.IsBound(V1)) myCreated.Bind(V1,EmptyMap);
2424 if ( !myCreated.IsBound(V2)) myCreated.Bind(V2,EmptyMap);
2425 if ( !myCreated(V1).IsBound(CurF)) {
2426 myCreated(V1).Bind(CurF,Empty);
2427 myCreated(V1)(CurF).Append(OV1);
2428 }
2429 if ( !myCreated(V2).IsBound(CurF)) {
2430 myCreated(V2).Bind(CurF,Empty);
2431 myCreated(V2)(CurF).Append(OV2);
2432 }
2433 }
2434 }
2435 }
2436
2437 TopExp_Explorer expw(Face, TopAbs_WIRE);
2438 for ( ; expw.More(); expw.Next()) {
2439 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
2440 TopExp_Explorer expe(W.Oriented(TopAbs_FORWARD),
2441 TopAbs_EDGE);
2442 TopoDS_Wire OW;
2443 B.MakeWire(OW);
2444
2445 for ( ; expe.More(); expe.Next()) {
2446 const TopoDS_Edge& E = TopoDS::Edge(expe.Current());
2447 Standard_Real f,l;
2448 Handle(Geom2d_Curve) C2d =
2449 BRep_Tool::CurveOnSurface(E,Face,f,l);
2450 TopoDS_Edge OE;
2451 if ( MapSS.IsBound(E)) { // c`est un edge de couture
2452 OE = TopoDS::Edge(MapSS(E));
2453 TopoDS_Shape aLocalShape = E.Reversed();
2454 Handle(Geom2d_Curve) C2d_1 =
2455 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),Face,f,l);
2456// Handle(Geom2d_Curve) C2d_1 =
2457// BRep_Tool::CurveOnSurface(TopoDS::Edge(E.Reversed()),
2458// Face,f,l);
2459 if ( E.Orientation() == TopAbs_FORWARD)
2460 B.UpdateEdge(OE,C2d,C2d_1,NewF,BRep_Tool::Tolerance(E));
2461 else
2462 B.UpdateEdge(OE,C2d_1,C2d,NewF,BRep_Tool::Tolerance(E));
2463 B.Range(OE,f,l);
2464 }
2465 else {
2466 // E a-t-il ume image dans la Map des Created ?
2467 if ( myCreated.IsBound(E)) {
2468 if ( myCreated(E).IsBound(CurF)) {
2469 OE = TopoDS::Edge(myCreated(E)(CurF).First());
2470 }
2471 }
2472 else {
2473 B.MakeEdge(OE);
2474 TopoDS_Vertex V1,V2,OV1,OV2;
2475 TopExp::Vertices(E,V1,V2);
2476 if ( myCreated.IsBound(V1) && myCreated(V1).IsBound(CurF)) {
2477 OV1 = TopoDS::Vertex(myCreated(V1)(CurF).First());
2478 }
2479 else {
2480 B.MakeVertex(OV1);
2481 gp_Pnt2d P2d =
2482 C2d->Value(BRep_Tool::Parameter(V1,E,Face));
2483 gp_Pnt P;
2484 S->D0(P2d.X(),P2d.Y(),P);
2485 P.Transform(L.Transformation());
2486 B.UpdateVertex(OV1,P,BRep_Tool::Tolerance(V1));
2487 myCreated.Bind(V1,EmptyMap);
2488 myCreated(V1).Bind(CurF,Empty);
2489 myCreated(V1)(CurF).Append(OV1);
2490 }
2491 if ( myCreated.IsBound(V2) && myCreated(V2).IsBound(CurF)) {
2492 OV2 = TopoDS::Vertex(myCreated(V2)(CurF).First());
2493 }
2494 else {
2495 B.MakeVertex(OV2);
2496 gp_Pnt2d P2d =
2497 C2d->Value(BRep_Tool::Parameter(V2,E,Face));
2498 gp_Pnt P;
2499 S->D0(P2d.X(),P2d.Y(),P);
2500 P.Transform(L.Transformation());
2501 B.UpdateVertex(OV2,P,BRep_Tool::Tolerance(V2));
2502 myCreated.Bind(V2,EmptyMap);
2503 myCreated(V2).Bind(CurF,Empty);
2504 myCreated(V2)(CurF).Append(OV2);
2505 }
2506 B.Add(OE,OV1.Oriented(V1.Orientation()));
2507 B.Add(OE,OV2.Oriented(V2.Orientation()));
2508 }
2509 B.UpdateEdge(OE,C2d,NewF,BRep_Tool::Tolerance(E));
2510 B.Range(OE,f,l);
2511// ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
2512 MapSS.Bind(E,OE);
2513 }
2514 B.Add(OW, OE.Oriented(E.Orientation()));
2515 }
2516 B.Add(NewF, OW.Oriented(W.Orientation()));
2517 }
2518
2519 NewF.Orientation(DeboucFace.Orientation());
2520
2521 BRepTools::Update(NewF);
2522 B.Add(myResult,NewF);
2523 }
2524 }
2525 }
2526
2527 // en desespoir de cause, s'il reste toujours des bords verts sur ce
2528 // satane Shape, on sew le shape.
2529 Handle(BRepBuilderAPI_Sewing) Sew = new BRepBuilderAPI_Sewing(myTol);
2530
2531 BRepLib::BuildCurves3d(myResult);
2532
2533 exp.Init(myResult,TopAbs_FACE);
2534 for ( ;exp.More(); exp.Next())
2535 Sew->Add(exp.Current());
2536
2537 Sew->Perform();
2538
2539 // On fait le SameParameter cas Sew ne le fait pas (Detecte que les edges
2540 // ne sont pas sameparameter mais ne fait rien.)
2541
2542 const TopoDS_Shape& SewedShape = Sew->SewedShape();
2543 if ( !SewedShape.IsNull()) {
2544 exp.Init(Sew->SewedShape(), TopAbs_EDGE);
2545 for (; exp.More(); exp.Next()) {
2546 const TopoDS_Edge& sec = TopoDS::Edge(exp.Current());
2547 BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
2548 }
2549 myResult = SewedShape;
2550 }
2551}
2552
2553
2554//=======================================================================
2555//function : Intersect
2556//purpose :
2557//=======================================================================
2558
2559Standard_Boolean BiTgte_Blend::Intersect
2560(const TopoDS_Shape& Init,
2561 const TopoDS_Face& Face,
2562 const BiTgte_DataMapOfShapeBox& MapSBox,
2563 const BRepOffset_Offset& OF1,
2564 BRepOffset_Inter3d& Inter)
2565{
2566 Standard_Boolean JenRajoute = Standard_False;
2567
2568 const Bnd_Box& Box1 = MapSBox(Face);
2569
2570 // -----------------------------------------------
2571 // intersection avec toutes les faces deja creees.
2572 // -----------------------------------------------
2573 const TopoDS_Shape& InitShape1 = OF1.InitialShape();
2574 Standard_Boolean F1surBordLibre =
2575 InitShape1.ShapeType() == TopAbs_EDGE &&
2576 myStopFaces.Contains(InitShape1);
2577
2578 TopTools_MapOfShape Done;
2579 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(myMapSF);
2580 for ( ; It.More(); It.Next()) {
2581 const BRepOffset_Offset& OF2 = It.Value();
2582 const TopoDS_Face& F2 = OF2.Face();
2583
2584 if (Box1.IsOut(MapSBox(F2))) continue;
2585
2586 if ( Inter.IsDone(Face,F2)) continue;
2587
2588 // on n intersecte pas 2 tuyaix construits sur bord libre.
2589 const TopoDS_Shape& InitShape2 = OF2.InitialShape();
2590 Standard_Boolean F2surBordLibre =
2591 InitShape2.ShapeType() == TopAbs_EDGE &&
2592 myStopFaces.Contains(InitShape2);
2593
2594#ifdef DEB
2595 if ( F1surBordLibre && F2surBordLibre) {
2596 cout << "Rejection : On n intersecte pas 2 tuyaux sur bord libre";
2597 cout << endl;
2598 }
2599#endif
2600
2601 if ( F1surBordLibre && F2surBordLibre) continue;
2602
2603 // -------------------------------------------------------
2604 // On n'intersecte pas les tuyaux avec ses faces voisines.
2605 // -------------------------------------------------------
2606 const TopoDS_Shape& ItKey = It.Key();
2607
2608 if ( Init.ShapeType() == TopAbs_EDGE) {
2609 if (ItKey.ShapeType() == TopAbs_FACE &&
2610 IsInFace(TopoDS::Edge(Init), TopoDS::Face(ItKey))) continue;
2611 }
2612
2613 Inter.FaceInter(Face,F2,myInitOffsetFace);
2614
2615 // ------------------------------------------
2616 // un edge de F1 ou F2 a-t-il ete touche ?
2617 // si oui, on rajoute des faces dans myFaces
2618 // ==> JenRajoute = True
2619 // ------------------------------------------
2620 TopTools_ListOfShape LInt;
2621 Done.Clear();
2622 if (myAsDes->HasCommonDescendant(Face,F2,LInt)) {
2623 TopTools_ListIteratorOfListOfShape itl2;
2624 for (itl2.Initialize(LInt); itl2.More(); itl2.Next()) {
2625 const TopoDS_Edge& CurE = TopoDS::Edge(itl2.Value());
2626 TopoDS_Vertex V1,V2;
2627 TopoDS_Edge E1,E2;
2628 TopExp::Vertices(CurE,V1,V2);
2629
2630 if ( Done.Add(V1)) {
2631 Standard_Boolean IsOnR1 = IsOnRestriction(V1,CurE,Face,E1);
2632 Standard_Boolean IsOnR2 = IsOnRestriction(V1,CurE,F2,E2);
2633#ifdef DEB
2634 if (IsOnR1 && IsOnR2) {
2635 cout << "On sort en meme tps sur les 2 faces, ";
2636 cout << "on ne propage pas si bord libre";
2637 cout << endl;
2638 }
2639#endif
2640 if ( IsOnR1 ) {
2641 if ( !myStopFaces.Contains(Init)) {
2642 Add(E1,myEdges,Init,OF1,myAnalyse,IsOnR1 && IsOnR2);
2643 JenRajoute = Standard_True;
2644 }
2645 }
2646 if ( IsOnR2) {
2647 if ( !myStopFaces.Contains(ItKey)) {
2648 Add(E2,myEdges, ItKey,OF2,myAnalyse,IsOnR1 && IsOnR2);
2649 JenRajoute = Standard_True;
2650 }
2651 }
2652 }
2653
2654 if ( Done.Add(V2)) {
2655 Standard_Boolean IsOnR1 = IsOnRestriction(V2,CurE,Face,E1);
2656 Standard_Boolean IsOnR2 = IsOnRestriction(V2,CurE,F2,E2);
2657
2658 // Si IsOnR1 && IsOnR2,
2659 // On sort en meme tps sur les 2 faces, on ne propage pas
2660 // sur les bords libres.
2661 // A priori, la facette se ferme toute seule.
2662#ifdef DEB
2663 if (IsOnR1 && IsOnR2) {
2664 cout << "On sort en meme tps sur les 2 faces, ";
2665 cout << "on ne propage pas si bord libre";
2666 cout << endl;
2667 }
2668#endif
2669 if ( IsOnR1) {
2670 if ( !myStopFaces.Contains(Init)) {
2671 Add(E1,myEdges,Init,OF1,myAnalyse,IsOnR1 && IsOnR2);
2672 JenRajoute = Standard_True;
2673 }
2674 }
2675 if ( IsOnR2) {
2676 if ( !myStopFaces.Contains(ItKey)) {
2677 Add(E2,myEdges,ItKey,OF2,myAnalyse,IsOnR1 && IsOnR2);
2678 JenRajoute = Standard_True;
2679 }
2680 }
2681 }
2682 }
2683 }
2684 }
2685
2686 return JenRajoute;
2687}
2688
2689