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