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