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