1 // File: BiTgte_Blend.cxx
2 // Created: Mon Dec 16 15:32:45 1996
3 // Author: Bruno DUMORTIER
4 // <dub@brunox.paris1.matra-dtv.fr>
8 #include <BiTgte_Blend.ixx>
11 // - all small static functions.
13 //======================== START STATIC FUNCTIONS ============
14 #include <BiTgte_DataMapOfShapeBox.hxx>
15 #include <BiTgte_CurveOnEdge.hxx>
17 #include <Bnd_Box.hxx>
18 #include <BRepBndLib.hxx>
19 #include <BRepTools.hxx>
20 #include <BRepTools_Quilt.hxx>
21 #include <BRepBuilderAPI_Sewing.hxx>
22 #include <BRep_Tool.hxx>
23 #include <BRep_Builder.hxx>
24 #include <BRepLib_MakeEdge.hxx>
25 #include <BRepOffset_DataMapOfShapeOffset.hxx>
26 #include <BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx>
27 #include <BRepOffset_Offset.hxx>
28 #include <BRepOffset_MakeLoops.hxx>
29 #include <BRepOffset_Inter3d.hxx>
30 #include <BRepOffset_Inter2d.hxx>
31 #include <BRepOffset_Interval.hxx>
32 #include <BRepOffset_ListOfInterval.hxx>
33 #include <BRepOffset_Tool.hxx>
34 #include <BRepAlgo_Loop.hxx>
36 #include <GeomAbs_SurfaceType.hxx>
37 #include <GeomAPI_ProjectPointOnCurve.hxx>
38 #include <Geom_BSplineCurve.hxx>
39 #include <Geom_TrimmedCurve.hxx>
40 #include <Geom_Circle.hxx>
41 #include <Geom_Line.hxx>
42 #include <Geom2d_Curve.hxx>
43 #include <GeomAdaptor_Surface.hxx>
44 #include <Geom2dAdaptor_Curve.hxx>
45 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
46 #include <TopExp_Explorer.hxx>
47 #include <TopoDS_Wire.hxx>
48 #include <TopoDS_Vertex.hxx>
49 #include <TopoDS_Edge.hxx>
50 #include <TopoDS_Compound.hxx>
51 #include <TopTools_ListOfShape.hxx>
52 #include <TopTools_SequenceOfShape.hxx>
53 #include <TopTools_DataMapOfShapeShape.hxx>
54 #include <TopTools_MapIteratorOfMapOfShape.hxx>
55 #include <TopTools_ListIteratorOfListOfShape.hxx>
57 #include <gp_Pnt2d.hxx>
58 #include <gp_Lin2d.hxx>
60 #include <gp_Dir2d.hxx>
65 #include <gp_Circ.hxx>
66 #include <gp_Sphere.hxx>
68 #include <AppCont_Function.hxx>
69 #include <Approx_FitAndDivide.hxx>
70 #include <AppParCurves_MultiCurve.hxx>
71 #include <BSplCLib.hxx>
72 #include <Convert_CompBezierCurvesToBSplineCurve.hxx>
73 #include <Precision.hxx>
74 #include <TColgp_Array1OfPnt.hxx>
75 #include <TColStd_Array1OfReal.hxx>
76 #include <TColStd_Array1OfInteger.hxx>
78 #include <Standard_NotImplemented.hxx>
80 #include <BRepLib.hxx>
82 #include <GeomAPI.hxx>
86 #include <OSD_Chronometer.hxx>
87 // variables for performance
88 Standard_Real t_mkcurve;
89 //Standard_IMPORT extern void ChFi3d_InitChron(OSD_Chronometer& ch);
90 Standard_EXPORT void ChFi3d_InitChron(OSD_Chronometer& ch);
91 //Standard_IMPORT extern void ChFi3d_ResultChron(OSD_Chronometer & ch,
92 Standard_IMPORT void ChFi3d_ResultChron(OSD_Chronometer & ch,
95 static Standard_Boolean Affich = Standard_False;
96 static char name[100];
100 //=======================================================================
101 //function : IsOnRestriction
103 //=======================================================================
105 static Standard_Boolean IsOnRestriction(const TopoDS_Vertex& V,
106 const TopoDS_Edge& CurE,
107 const TopoDS_Face& F,
110 // find if Vertex V of CurE is on a restriction of F.
111 // if yes, store this restriction in E.
114 // Method somewhat brutal : possible to really optimize by a
115 // direct call the SD of intersections -> See LBR
118 Handle(Geom2d_Curve) CurC = BRep_Tool::CurveOnSurface(CurE,F,f,l);
119 Standard_Real U = BRep_Tool::Parameter(V,CurE,F);
120 gp_Pnt2d P = CurC->Value(U);
122 Geom2dAPI_ProjectPointOnCurve Proj;
124 // The tolerance is exaggerated : it is better to construct too many
125 // tubes than to miss intersections.
126 // Standard_Real Tol = 100 * BRep_Tool::Tolerance(V);
127 Standard_Real Tol = BRep_Tool::Tolerance(V);
128 TopExp_Explorer exp(F,TopAbs_EDGE);
129 for ( ; exp.More(); exp.Next()) {
130 E = TopoDS::Edge(exp.Current());
131 Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(E,F,f,l);
133 if ( Proj.NbPoints() > 0) {
134 if (Proj.LowerDistance() < Tol) {
135 return Standard_True;
139 return Standard_False;
142 //=======================================================================
145 //=======================================================================
147 static void Add(const TopoDS_Edge& E,
148 TopTools_MapOfShape& Map,
149 const TopoDS_Shape& S,
150 const BRepOffset_Offset& OF,
151 const BRepOffset_Analyse& Analyse,
152 const Standard_Boolean WarningSurBordLibre)
153 // If WarningSurBordLibre = TRUE, no propagation if the edge is open.
155 TopAbs_ShapeEnum Type = S.ShapeType();
157 if ( Type == TopAbs_FACE) {
158 TopExp_Explorer exp(S,TopAbs_EDGE);
159 for ( ; exp.More(); exp.Next()) {
160 const TopoDS_Edge& OriE = TopoDS::Edge(exp.Current());
161 TopoDS_Shape aLocalShape = OF.Generated(OriE);
162 const TopoDS_Edge& IE = TopoDS::Edge(aLocalShape);
163 // const TopoDS_Edge& IE = TopoDS::Edge(OF.Generated(OriE));
164 if ( E.IsEqual(IE)) {
165 if (WarningSurBordLibre) {
166 // It is checked that the border is not free.
167 const TopTools_ListOfShape& L = Analyse.Ancestors(OriE);
168 if (L.Extent() == 1) break; // Nothing is done.
170 Map.Add(exp.Current());
175 else if ( Type == TopAbs_EDGE) {
176 TopExp_Explorer exp(S,TopAbs_VERTEX);
177 for ( ; exp.More(); exp.Next()) {
178 TopoDS_Shape aLocalShape = OF.Generated(exp.Current());
179 const TopoDS_Edge& IE = TopoDS::Edge(aLocalShape);
180 // const TopoDS_Edge& IE = TopoDS::Edge(OF.Generated(exp.Current()));
181 if ( E.IsEqual(IE)) {
182 const TopTools_ListOfShape& L = Analyse.Ancestors(exp.Current());
183 TopTools_ListIteratorOfListOfShape it(L);
184 for ( ; it.More(); it.Next()) {
194 //=======================================================================
195 //function : IsInFace
197 //=======================================================================
199 static Standard_Boolean IsInFace(const TopoDS_Edge& E,
200 const TopoDS_Face& F)
202 TopExp_Explorer exp(F,TopAbs_EDGE);
203 for ( ;exp.More(); exp.Next())
204 if ( E.IsSame(exp.Current())) return Standard_True;
205 return Standard_False;
209 //=======================================================================
210 //function : KPartCurve3d
212 //=======================================================================
214 static void KPartCurve3d(TopoDS_Edge Edge,
215 Handle(Geom2d_Curve) Curve,
216 Handle(Geom_Surface) Surf)
218 // try to find the particular case
219 // if not found call BRepLib::BuildCurve3d
222 Standard_Real Tol = Precision::Confusion();
224 Standard_Boolean IsComputed = Standard_False;
226 // Seach only isos on analytical surfaces.
227 Geom2dAdaptor_Curve C(Curve);
228 GeomAdaptor_Surface S(Surf);
229 GeomAbs_CurveType CTy = C.GetType();
230 GeomAbs_SurfaceType STy = S.GetType();
231 BRep_Builder TheBuilder;
233 if ( STy != GeomAbs_Plane) { // if plane buildcurve3d manage KPart
234 if ( CTy == GeomAbs_Line) {
235 gp_Dir2d D = C.Line().Direction();
236 if ( D.IsParallel(gp::DX2d(),Precision::Angular())) { // Iso V.
237 if ( STy == GeomAbs_Sphere) {
238 gp_Pnt2d P = C.Line().Location();
239 if ( Abs( Abs(P.Y()) -M_PI/2. ) < Precision::PConfusion()) {
240 TheBuilder.Degenerated(Edge, Standard_True);
243 gp_Sphere Sph = S.Sphere();
244 gp_Ax3 Axis = Sph.Position();
245 gp_Circ Ci = ElSLib::SphereVIso(Axis,
248 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
249 gp_Ax1 AxeRev(Axis.Location(), DRev);
250 Ci.Rotate(AxeRev, P.X());
251 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
252 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
254 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
256 IsComputed = Standard_True;
258 else if ( STy == GeomAbs_Cylinder) {
259 gp_Cylinder Cyl = S.Cylinder();
260 gp_Pnt2d P = C.Line().Location();
261 gp_Ax3 Axis = Cyl.Position();
262 gp_Circ Ci = ElSLib::CylinderVIso(Axis,
265 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
266 gp_Ax1 AxeRev(Axis.Location(), DRev);
267 Ci.Rotate(AxeRev, P.X());
268 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
269 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
271 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
272 IsComputed = Standard_True;
274 else if ( STy == GeomAbs_Cone) {
275 gp_Cone Cone = S.Cone();
276 gp_Pnt2d P = C.Line().Location();
277 gp_Ax3 Axis = Cone.Position();
278 gp_Circ Ci = ElSLib::ConeVIso(Axis,
282 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
283 gp_Ax1 AxeRev(Axis.Location(), DRev);
284 Ci.Rotate(AxeRev, P.X());
285 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
286 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
288 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
289 IsComputed = Standard_True;
291 else if ( STy == GeomAbs_Torus) {
292 gp_Torus Tore = S.Torus();
293 gp_Pnt2d P = C.Line().Location();
294 gp_Ax3 Axis = Tore.Position();
295 gp_Circ Ci = ElSLib::TorusVIso(Axis,
299 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
300 gp_Ax1 AxeRev(Axis.Location(), DRev);
301 Ci.Rotate(AxeRev, P.X());
302 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
303 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
305 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
306 IsComputed = Standard_True;
309 else if ( D.IsParallel(gp::DY2d(),Precision::Angular())) { // Iso U.
310 if ( STy == GeomAbs_Sphere) {
311 gp_Sphere Sph = S.Sphere();
312 gp_Pnt2d P = C.Line().Location();
313 gp_Ax3 Axis = Sph.Position();
315 gp_Circ Ci = ElSLib::SphereUIso(Axis, Sph.Radius(),0.);
317 // set to sameparameter (rotation of the circle - offset from Y)
318 gp_Dir DRev = Axis.XDirection().Crossed(Axis. Direction());
319 gp_Ax1 AxeRev(Axis.Location(),DRev);
320 Ci.Rotate(AxeRev, P.Y());
322 // transformation by iso U ( = P.X())
323 DRev = Axis.XDirection().Crossed(Axis.YDirection());
324 AxeRev = gp_Ax1(Axis.Location(), DRev);
325 Ci.Rotate(AxeRev, P.X());
326 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
328 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
330 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
331 IsComputed = Standard_True;
333 else if ( STy == GeomAbs_Cylinder) {
334 gp_Cylinder Cyl = S.Cylinder();
335 gp_Pnt2d P = C.Line().Location();
336 gp_Lin L = ElSLib::CylinderUIso(Cyl.Position(),
339 gp_Vec Tr(L.Direction());
342 Handle(Geom_Line) Line = new Geom_Line(L);
343 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
345 TheBuilder.UpdateEdge(Edge, Line, Loc, Tol);
346 IsComputed = Standard_True;
348 else if ( STy == GeomAbs_Cone) {
349 gp_Cone Cone = S.Cone();
350 gp_Pnt2d P = C.Line().Location();
351 gp_Lin L = ElSLib::ConeUIso(Cone.Position(),
355 gp_Vec Tr(L.Direction());
357 L.Translate(Tr); Handle(Geom_Line) Line = new Geom_Line(L);
358 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
360 TheBuilder.UpdateEdge(Edge, Line, Loc, Tol);
361 IsComputed = Standard_True;
363 else if ( STy == GeomAbs_Torus) {
369 Handle(Geom_Curve) C3d = GeomAPI::To3d(Curve,S.Plane());
370 TheBuilder.UpdateEdge(Edge, C3d, Loc, Tol);
371 IsComputed = Standard_True;
376 //=======================================================================
377 //function : MakeCurve
379 //=======================================================================
381 class MakeCurve_Function : public AppCont_Function
383 BiTgte_CurveOnEdge myCurve;
387 MakeCurve_Function(const BiTgte_CurveOnEdge& C) : myCurve(C) {};
389 Standard_Real FirstParameter() const
390 {return myCurve.FirstParameter();}
392 Standard_Real LastParameter() const
393 {return myCurve.LastParameter();}
395 gp_Pnt Value(const Standard_Real t) const
396 {return myCurve.Value(t);}
398 Standard_Boolean D1(const Standard_Real /*t*/, gp_Pnt& /*P*/, gp_Vec& /*V*/) const
399 {return Standard_False;}
403 Handle(Geom_Curve) MakeCurve (const BiTgte_CurveOnEdge& HC)
405 Handle(Geom_Curve) C;
409 ChFi3d_InitChron(ch);
412 if ( HC.GetType() == GeomAbs_Circle) {
413 C = new Geom_Circle(HC.Circle());
414 C = new Geom_TrimmedCurve(C,HC.FirstParameter(),HC.LastParameter());
416 else { // the approximation is done
417 MakeCurve_Function F(HC);
418 Standard_Integer Deg1, Deg2;
420 Standard_Real Tol = Precision::Approximation();
421 Approx_FitAndDivide Fit(F,Deg1,Deg2,Tol,Tol,Standard_True);
423 Standard_Integer NbCurves = Fit.NbMultiCurves();
424 // it is attempted to make the curve at least C1
425 Convert_CompBezierCurvesToBSplineCurve Conv;
427 for (i = 1; i <= NbCurves; i++) {
428 AppParCurves_MultiCurve MC = Fit.Value( i); //Load the Ith Curve
429 TColgp_Array1OfPnt Poles( 1, MC.Degree() + 1); //Return poles
432 Conv.AddCurve(Poles);
437 Standard_Integer NbPoles = Conv.NbPoles();
438 Standard_Integer NbKnots = Conv.NbKnots();
439 TColgp_Array1OfPnt NewPoles(1,NbPoles);
440 TColStd_Array1OfReal NewKnots(1,NbKnots);
441 TColStd_Array1OfInteger NewMults(1,NbKnots);
443 Conv.KnotsAndMults(NewKnots,NewMults);
444 Conv.Poles(NewPoles);
446 BSplCLib::Reparametrize(HC.FirstParameter(),
450 C = new Geom_BSplineCurve (NewPoles,
457 ChFi3d_ResultChron(ch, t_mkcurve);
464 //=======================================================================
466 //purpose : Only the faces connected with caps are given
467 //=======================================================================
469 static void Touched(const BRepOffset_Analyse& Analyse,
470 const TopTools_MapOfShape& StopFaces,
471 const TopoDS_Shape& Shape,
472 TopTools_MapOfShape& TouchedByCork)
474 // currently nothing is done !!
475 if ( Standard_True) {
479 TopExp_Explorer exp(Shape, TopAbs_EDGE);
480 for ( ; exp.More(); exp.Next()) {
481 const TopTools_ListOfShape& L = Analyse.Ancestors(exp.Current());
482 if (StopFaces.Contains(L.First()))
483 TouchedByCork.Add(L.Last());
484 else if (StopFaces.Contains(L.Last()))
485 TouchedByCork.Add(L.First());
490 //=======================================================================
491 //function : FindVertex
493 //=======================================================================
495 static TopoDS_Vertex FindVertex(const gp_Pnt& P,
496 const TopTools_MapOfShape& Map,
497 const Standard_Real Tol)
500 // Find in <Map> a vertex which represent the point <P>.
501 Standard_Real Tol2,Dist;
502 TopoDS_Vertex V,VV[2];
503 Standard_Real TolCarre = Tol*Tol;
504 TopTools_MapIteratorOfMapOfShape it(Map);
505 for ( ; it.More(); it.Next()) {
506 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
508 TopExp::Vertices(E,VV[0],VV[1]);
510 for (Standard_Integer i = 0; i < 2 ; i++) {
511 // if OK la Tolerance du Vertex
512 Tol2 = BRep_Tool::Tolerance(VV[i]);
514 gp_Pnt P1 = BRep_Tool::Pnt(VV[i]);
515 Dist = P.SquareDistance(P1);
516 if ( Dist <= Tol2) return VV[i];
517 // otherwise with the required tolerance.
518 if (TolCarre > Tol2) {
519 if ( Dist <= TolCarre) {
520 // so it is necessary to update the tolerance of Vertex.
521 B.UpdateVertex(VV[i],Tol);
533 //=======================================================================
534 //function : MakeDegeneratedEdge
536 //=======================================================================
538 static TopoDS_Edge MakeDegeneratedEdge(const Handle(Geom_Curve)& CC,
539 const TopoDS_Vertex& VfOnE)
542 Standard_Real Tol = Precision::Confusion();
543 // kill trimmed curves
544 Handle(Geom_Curve) C = CC;
545 Handle(Geom_TrimmedCurve) CT = Handle(Geom_TrimmedCurve)::DownCast(C);
546 while (!CT.IsNull()) {
547 C = CT->BasisCurve();
548 CT = Handle(Geom_TrimmedCurve)::DownCast(C);
552 if ( VfOnE.IsNull()) {
553 gp_Pnt P = C->Value(C->FirstParameter());
554 B.MakeVertex(V1,P,Tol);
560 V1.Orientation(TopAbs_FORWARD);
561 V2.Orientation(TopAbs_REVERSED);
565 B.Add(E,V1); B.Add(E,V2);
566 // B.UpdateVertex(V1,C->FirstParameter(),E,Tol);
567 // B.UpdateVertex(V2,C->LastParameter(),E,Tol);
568 B.Range(E,CC->FirstParameter(),CC->LastParameter());
573 //=======================================================================
574 //function : Orientation
576 //=======================================================================
578 static TopAbs_Orientation Orientation(const TopoDS_Edge& E,
579 const TopoDS_Face& F,
580 const TopTools_ListOfShape& L)
583 TopAbs_Orientation Orien = TopAbs_FORWARD;
585 TopAbs_Orientation Orien;
587 TopTools_ListIteratorOfListOfShape itld;
588 for ( itld.Initialize(L); itld.More(); itld.Next()) {
589 if ( itld.Value().IsSame(E)) {
590 Orien = itld.Value().Orientation();
594 if ( F.Orientation() == TopAbs_REVERSED)
595 Orien = TopAbs::Reverse(Orien);
600 //=======================================================================
601 //function : FindCreatedEdge
603 //=======================================================================
605 static TopoDS_Edge FindCreatedEdge
606 (const TopoDS_Vertex& V1,
607 const TopoDS_Edge& E,
608 const BRepOffset_DataMapOfShapeOffset& MapSF,
609 TopTools_MapOfShape& MapOnV,
610 const BRepOffset_Analyse& CenterAnalyse,
611 Standard_Real Radius,
615 if (!CenterAnalyse.HasAncestor(V1)) return E1; // return a Null Shape.
617 TopTools_ListOfShape TangE;
618 CenterAnalyse.TangentEdges(E,V1,TangE);
620 TopTools_ListIteratorOfListOfShape itl(TangE);
621 Standard_Boolean Find = Standard_False;
622 for ( ; itl.More() && !Find; itl.Next()) {
623 const TopoDS_Edge& ET = TopoDS::Edge(itl.Value());
624 if ( MapSF.IsBound(ET)) {
625 TopoDS_Shape aLocalShape = MapSF(ET).Generated(V1);
626 E1 = TopoDS::Edge(aLocalShape);
627 // E1 = TopoDS::Edge(MapSF(ET).Generated(V1));
629 Find = Standard_True;
632 // Find the sharing of vertices in case of tangent consecutive 3 edges
633 // the second of which is the edge that degenerates the tube.
634 TopLoc_Location CLoc;
636 Handle(Geom_Curve) CET =
637 BRep_Tool::Curve(ET,CLoc,ff,ll);
638 if ( CET->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
639 CET = Handle(Geom_TrimmedCurve)::DownCast(CET)->BasisCurve();
641 Handle(Geom_Circle) Circ = Handle(Geom_Circle)::DownCast(CET);
642 if ( Circ.IsNull()) continue;
643 if ( Abs(Circ->Radius() - Abs(Radius)) > Tol) continue;
646 TopExp::Vertices(ET,U1,U2);
647 if ( U1.IsSame(V1)) U1 = U2;
648 TopTools_ListOfShape Tang2;
649 CenterAnalyse.TangentEdges(ET,U1,Tang2);
650 TopTools_ListIteratorOfListOfShape it2(Tang2);
651 for ( ; it2.More() ; it2.Next()) {
652 const TopoDS_Edge& ET2 = TopoDS::Edge(it2.Value());
653 if ( MapSF.IsBound(ET2)) {
654 TopoDS_Shape aLocalShape = MapSF(ET2).Generated(U1);
655 MapOnV.Add(TopoDS::Edge(aLocalShape));
656 // MapOnV.Add(TopoDS::Edge(MapSF(ET2).Generated(U1)));
663 // CenterAnalyse.Edges(V1f, OT, TangE);
664 if (CenterAnalyse.HasAncestor(V1)) {
665 TangE = CenterAnalyse.Ancestors(V1);
666 itl.Initialize(TangE);
667 for ( ; itl.More() && !Find; itl.Next()) {
668 if ( MapSF.IsBound(itl.Value())) {
669 MapOnV.Add(MapSF(itl.Value()).Generated(V1));
678 //=======================================================================
680 //purpose : Sets in increasing order the sequence of vertices.
681 //=======================================================================
683 static void Bubble(const TopoDS_Edge& E,
684 TopTools_SequenceOfShape& Seq)
686 Standard_Boolean Invert = Standard_True;
687 Standard_Integer NbPoints = Seq.Length();
692 Invert = Standard_False;
693 for ( Standard_Integer i = 1; i < NbPoints; i++) {
694 TopoDS_Shape aLocalShape = Seq.Value(i) .Oriented(TopAbs_INTERNAL);
695 V1 = TopoDS::Vertex(aLocalShape);
696 aLocalShape = Seq.Value(i+1).Oriented(TopAbs_INTERNAL);
697 V2 = TopoDS::Vertex(aLocalShape);
698 // V1 = TopoDS::Vertex(Seq.Value(i) .Oriented(TopAbs_INTERNAL));
699 // V2 = TopoDS::Vertex(Seq.Value(i+1).Oriented(TopAbs_INTERNAL));
701 U1 = BRep_Tool::Parameter(V1,E);
702 U2 = BRep_Tool::Parameter(V2,E);
705 Invert = Standard_True;
711 //=======================================================================
714 //=======================================================================
716 static void CutEdge (const TopoDS_Edge& E,
717 const TopTools_ListOfShape& VOnE,
718 TopTools_ListOfShape& NE )
720 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
721 TopoDS_Edge WE = TopoDS::Edge(aLocalShape);
722 // TopoDS_Edge WE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
726 TopTools_SequenceOfShape SV;
727 TopTools_ListIteratorOfListOfShape it(VOnE);
730 for ( ; it.More(); it.Next()) {
731 SV.Append(it.Value());
733 //--------------------------------
734 // Parse vertices on the edge.
735 //--------------------------------
738 Standard_Integer NbVer = SV.Length();
739 //----------------------------------------------------------------
740 // Construction of new edges.
741 // The vertices at the extremities of edges are not
742 // necessarily in the list of vertices
743 //----------------------------------------------------------------
750 BRep_Tool::Range(WE,f,l);
751 TopExp::Vertices(WE,VF,VL);
754 if (SV(1).IsEqual(VF) && SV(2).IsEqual(VL)) {
759 //----------------------------------------------------
760 // Processing of closed edges
761 // If a vertex of intersection is on the common vertex,
762 // it should appear at the beginning and the end of SV.
763 //----------------------------------------------------
766 if (!VF.IsNull() && !VF.IsSame(SV.First())) SV.Prepend(VF);
767 if (!VL.IsNull() && !VL.IsSame(SV.Last ())) SV.Append (VL);
769 V1 = TopoDS::Vertex(SV.First());
772 while (!SV.IsEmpty()) {
774 V2 = TopoDS::Vertex(SV.First());
777 if ( V1.IsSame(V2)) {
778 cout << "Vertex Confondus dans CutEdges" << endl;
781 //-------------------------------------------
782 // Copy the edge and restriction by V1 V2.
783 //-------------------------------------------
784 TopoDS_Shape aLocalShape =WE.EmptyCopied();
785 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
786 // TopoDS_Edge NewEdge = TopoDS::Edge(WE.EmptyCopied());
787 B.Add (NewEdge,V1.Oriented(TopAbs_FORWARD));
788 B.Add (NewEdge,V2.Oriented(TopAbs_REVERSED));
792 aLocalShape = V1.Oriented(TopAbs_INTERNAL);
793 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),WE);
794 // U1 = BRep_Tool::Parameter
795 // (TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),WE);
800 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
801 U2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),WE);
802 // U2 = BRep_Tool::Parameter
803 // (TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),WE);
805 B.Range (NewEdge,U1,U2);
806 NE.Append(NewEdge.Oriented(E.Orientation()));
811 //======================== END OF STATIC FUNCTIONS ============
816 //=======================================================================
817 //function : BiTgte_Blend
819 //=======================================================================
821 BiTgte_Blend::BiTgte_Blend()
823 myAsDes = new BRepAlgo_AsDes();
828 //=======================================================================
829 //function : BiTgte_Blend
831 //=======================================================================
833 BiTgte_Blend::BiTgte_Blend(const TopoDS_Shape& S,
834 const Standard_Real Radius,
835 const Standard_Real Tol,
836 const Standard_Boolean NUBS)
838 myAsDes = new BRepAlgo_AsDes();
839 Init(S,Radius,Tol,NUBS);
843 //=======================================================================
846 //=======================================================================
848 void BiTgte_Blend::Init(const TopoDS_Shape& S,
849 const Standard_Real Radius,
850 const Standard_Real Tol,
851 const Standard_Boolean NUBS)
859 // TopExp::MapShapesAndAncestors(S,TopAbs_EDGE,TopAbs_FACE,myAncestors);
863 //=======================================================================
866 //=======================================================================
868 void BiTgte_Blend::Clear()
870 myInitOffsetFace.Clear();
872 myImageOffset .Clear();
873 myStopFaces .Clear();
877 myDone = Standard_False;
881 //=======================================================================
882 //function : SetStoppingFace
884 //=======================================================================
886 void BiTgte_Blend::SetStoppingFace(const TopoDS_Face& Face)
888 myStopFaces.Add(Face);
890 // MAJ SD. -> To end loop, set faces of edges
892 // myInitOffsetFace.SetRoot(Face);
893 // myInitOffsetFace.Bind (Face,Face);
894 // myImageOffset.SetRoot (Face);
898 //=======================================================================
899 //function : SetFaces
901 //=======================================================================
903 void BiTgte_Blend::SetFaces(const TopoDS_Face& F1,const TopoDS_Face& F2)
910 //=======================================================================
913 //=======================================================================
915 void BiTgte_Blend::SetEdge(const TopoDS_Edge& Edge)
921 //=======================================================================
924 //=======================================================================
926 void BiTgte_Blend::Perform(const Standard_Boolean BuildShape)
928 myBuildShape = BuildShape;
930 // Try cutting to avoid tubes on free borders
931 // that are not actually free.
932 Handle(BRepBuilderAPI_Sewing) Sew = new BRepBuilderAPI_Sewing(myTol);
933 BRepLib::BuildCurves3d(myShape);
934 TopExp_Explorer expf(myShape,TopAbs_FACE);
935 for ( ;expf.More(); expf.Next()) Sew->Add(expf.Current());
937 TopoDS_Shape SewedShape = Sew->SewedShape();
938 if ( SewedShape.IsNull()) Standard_Failure::Raise("Sewing aux fraises");
940 // Check if the sewing modified the orientation.
941 expf.Init(myShape,TopAbs_FACE);
942 TopoDS_Face FaceRef = TopoDS::Face(expf.Current());
943 TopAbs_Orientation OriRef = FaceRef.Orientation();
944 if (Sew->IsModified(FaceRef)) FaceRef = TopoDS::Face(Sew->Modified(FaceRef));
945 expf.Init(SewedShape, TopAbs_FACE);
946 for (; expf.More(); expf.Next()) {
947 const TopoDS_Face& FF = TopoDS::Face(expf.Current());
948 if (FaceRef.IsSame(FF) && (FF.Orientation() != OriRef)) {
949 SewedShape.Reverse();
954 // Make SameParameter if Sew does not do it (Detect that edges
955 // are not sameparameter but it does nothing.)
956 expf.Init(SewedShape, TopAbs_EDGE);
957 for (; expf.More(); expf.Next()) {
958 const TopoDS_Edge& sec = TopoDS::Edge(expf.Current());
959 BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
962 TopExp::MapShapesAndAncestors
963 (SewedShape,TopAbs_EDGE,TopAbs_FACE,myAncestors);
965 // Extend myFaces with the faces of the sewed shape.
966 expf.Init(myShape,TopAbs_FACE);
967 for ( ; expf.More(); expf.Next()) {
968 const TopoDS_Shape& F = expf.Current();
969 if ( myFaces.Contains(F) && Sew->IsModified(F)) {
971 myFaces.Add(Sew->Modified(F));
975 myShape = SewedShape;
976 // end Sewing for false free borders.
979 OSD_Chronometer cl_total, ch;
980 Standard_Real t_total, t_center, t_surface, t_shape;
982 t_total=0; t_center=0; t_surface=0; t_mkcurve=0; t_shape=0;
983 ChFi3d_InitChron(cl_total);
986 // ----------------------------------------------------------------
987 // place faces with the proper orientation in the initial shape
988 // ----------------------------------------------------------------
989 TopExp_Explorer exp(myShape,TopAbs_FACE);
990 for ( ; exp.More(); exp.Next()) {
991 const TopoDS_Shape& F = exp.Current();
992 if ( myFaces.Contains(F)) {
996 else if ( myStopFaces.Contains(F)) {
997 myStopFaces.Remove(F);
1002 // ----------------------------------------------
1003 // Calculate lines of centers and of surfaces
1004 // ----------------------------------------------
1006 ChFi3d_InitChron(ch);
1012 ChFi3d_ResultChron(ch, t_center);
1015 // -----------------------------
1016 // Calculate connection Surfaces
1017 // -----------------------------
1019 ChFi3d_InitChron(ch);
1025 ChFi3d_ResultChron(ch, t_surface);
1028 // ----------------------------------
1029 // Calculate the generated shape if required
1030 // ----------------------------------
1032 ChFi3d_InitChron(ch);
1035 if ( myBuildShape) ComputeShape();
1038 ChFi3d_ResultChron(ch, t_shape);
1041 // Finally construct curves 3d from edges to be transfered
1042 // since the partition is provided ( A Priori);
1043 BRepLib::BuildCurves3d(myResult, Precision::Confusion());
1046 ChFi3d_ResultChron(cl_total, t_total);
1048 cout<<"Blend_PERFORM: temps total "<<t_total<<" s dont :"<<endl;
1049 cout<<"- ComputeCenters "<<t_center<<" s"<<endl;
1050 cout<<"- ComputeSurfaces "<<t_surface<<" s"<<endl;
1051 cout<<"----> MakeCurve "<<t_mkcurve<<" s"<<endl;
1052 if ( myBuildShape) cout<<"- ComputeShape "<<t_shape<<" s"<<endl;
1055 myDone = Standard_True;
1059 //=======================================================================
1062 //=======================================================================
1064 Standard_Boolean BiTgte_Blend::IsDone() const
1069 //=======================================================================
1072 //=======================================================================
1074 const TopoDS_Shape& BiTgte_Blend::Shape() const
1080 //=======================================================================
1081 //function : NbSurfaces
1083 //=======================================================================
1085 Standard_Integer BiTgte_Blend::NbSurfaces() const
1087 return myCenters.Extent();
1091 //=======================================================================
1092 //function : Surface
1094 //=======================================================================
1096 Handle(Geom_Surface) BiTgte_Blend::Surface(const Standard_Integer Index) const
1098 return Surface(myCenters(Index));
1101 //=======================================================================
1102 //function : TopoDS_Face&
1104 //=======================================================================
1106 const TopoDS_Face& BiTgte_Blend::Face(const Standard_Integer Index) const
1108 return Face(myCenters(Index));
1113 //=======================================================================
1114 //function : CenterLines
1116 //=======================================================================
1118 void BiTgte_Blend::CenterLines(TopTools_ListOfShape& LC) const
1121 Standard_Integer Nb = NbSurfaces();
1122 for ( Standard_Integer i = 1; i <= Nb; i++)
1123 LC.Append(myCenters(i));
1127 //=======================================================================
1128 //function : Surface
1130 //=======================================================================
1132 Handle(Geom_Surface) BiTgte_Blend::Surface(const TopoDS_Shape& CenterLine)
1135 const TopoDS_Face& F = myMapSF(CenterLine).Face();
1136 return BRep_Tool::Surface(F);
1139 //=======================================================================
1140 //function : TopoDS_Face&
1142 //=======================================================================
1144 const TopoDS_Face& BiTgte_Blend::Face(const TopoDS_Shape& CenterLine) const
1146 if ( !myMapSF.IsBound(CenterLine)) {
1147 Standard_DomainError::Raise("BiTgte_Blend::Face");
1150 return myMapSF(CenterLine).Face();
1153 //=======================================================================
1154 //function : ContactType
1156 //=======================================================================
1158 BiTgte_ContactType BiTgte_Blend::ContactType(const Standard_Integer Index)
1161 const TopoDS_Shape& S1 = SupportShape1(Index);
1162 const TopoDS_Shape& S2 = SupportShape2(Index);
1164 TopAbs_ShapeEnum Type1 = S1.ShapeType();
1165 TopAbs_ShapeEnum Type2 = S2.ShapeType();
1167 if (Type2 < Type1) {
1168 TopAbs_ShapeEnum Dummy = Type1;
1172 BiTgte_ContactType Type = BiTgte_VertexVertex;
1178 case TopAbs_VERTEX: Type = BiTgte_VertexVertex; break;
1179 case TopAbs_EDGE: Type = BiTgte_EdgeVertex; break;
1180 case TopAbs_FACE: Type = BiTgte_FaceVertex; break;
1187 case TopAbs_EDGE: Type = BiTgte_EdgeEdge; break;
1188 case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
1195 case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
1208 //=======================================================================
1209 //function : SupportShape1
1211 //=======================================================================
1213 const TopoDS_Shape& BiTgte_Blend::SupportShape1(const Standard_Integer Index)
1216 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1218 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1220 // --------------------------------------------------------------
1221 // F1 and F2 = 2 parallel faces intersecting at CurE.
1222 // --------------------------------------------------------------
1223 const TopoDS_Face& F1 = TopoDS::Face(L.First());
1224 const TopoDS_Shape& Or1 = myInitOffsetFace.ImageFrom(F1);
1229 //=======================================================================
1230 //function : SupportShape2
1232 //=======================================================================
1234 const TopoDS_Shape& BiTgte_Blend::SupportShape2(const Standard_Integer Index)
1237 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1239 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1241 // --------------------------------------------------------------
1242 // F1 and F2 = 2 parallel faces intersecting at CurE.
1243 // --------------------------------------------------------------
1244 const TopoDS_Face& F2 = TopoDS::Face(L.Last());
1245 const TopoDS_Shape& Or2 = myInitOffsetFace.ImageFrom(F2);
1250 //=======================================================================
1251 //function : CurveOnShape1
1253 //=======================================================================
1255 Handle(Geom_Curve) BiTgte_Blend::CurveOnShape1
1256 (const Standard_Integer Index) const
1258 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1259 const TopoDS_Shape& F = myMapSF(CurE).Face();
1261 // somewhat brutal method based ONLY on the construction of the fillet:
1262 // the first edge of the tube is exactly the edge on Shape1.
1264 TopExp_Explorer exp(F,TopAbs_EDGE);
1265 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1266 Handle(Geom_Curve) C;
1267 if ( !BRep_Tool::Degenerated(E)) {
1269 C = BRep_Tool::Curve(E,f,l);
1270 C = new Geom_TrimmedCurve(C,f,l);
1276 //=======================================================================
1277 //function : CurveOnShape2
1279 //=======================================================================
1281 Handle(Geom_Curve) BiTgte_Blend::CurveOnShape2
1282 (const Standard_Integer Index) const
1284 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1285 const TopoDS_Shape& F = myMapSF(CurE).Face();
1287 // somewhat brutal method based ONLY on the construction of the fillet:
1288 // the first edge of the tube is exactly the edge on Shape2.
1290 TopExp_Explorer exp(F,TopAbs_EDGE);
1292 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1293 Handle(Geom_Curve) C;
1294 if ( !BRep_Tool::Degenerated(E)) {
1296 C = BRep_Tool::Curve(E,f,l);
1297 C = new Geom_TrimmedCurve(C,f,l);
1303 //=======================================================================
1304 //function : PCurveOnFace1
1306 //=======================================================================
1308 Handle(Geom2d_Curve) BiTgte_Blend::PCurveOnFace1
1309 (const Standard_Integer /*Index*/) const
1311 Handle(Geom2d_Curve) C;
1316 //=======================================================================
1317 //function : PCurve1OnFillet
1319 //=======================================================================
1321 Handle(Geom2d_Curve) BiTgte_Blend::PCurve1OnFillet
1322 (const Standard_Integer /*Index*/) const
1324 Handle(Geom2d_Curve) C;
1329 //=======================================================================
1330 //function : PCurveOnFace2
1332 //=======================================================================
1334 Handle(Geom2d_Curve) BiTgte_Blend::PCurveOnFace2
1335 (const Standard_Integer /*Index*/) const
1337 Handle(Geom2d_Curve) C;
1342 //=======================================================================
1343 //function : Curve2OnFillet
1345 //=======================================================================
1347 Handle(Geom2d_Curve) BiTgte_Blend::PCurve2OnFillet
1348 (const Standard_Integer /*Index*/) const
1350 Handle(Geom2d_Curve) C;
1356 //=======================================================================
1357 //function : NbBranches
1359 //=======================================================================
1361 Standard_Integer BiTgte_Blend::NbBranches()
1363 if (myNbBranches != -1) return myNbBranches;
1365 // else, compute the Branches.
1366 BRepTools_Quilt Glue;
1368 Standard_Integer NbFaces = myCenters.Extent();
1371 if (NbFaces == 0) return 0;
1375 for ( i = 1; i <= NbFaces; i++) {
1376 const TopoDS_Shape& CenterLine = myCenters(i);
1377 Glue.Add(myMapSF(CenterLine).Face());
1380 const TopoDS_Shape Shells = Glue.Shells();
1383 // Reorder Map myCenters.
1384 // The method is brutal and unpolished,
1385 // it is possible to refine it.
1387 TopTools_IndexedMapOfShape tmpMap;
1389 TopExp_Explorer exp(Shells,TopAbs_SHELL);
1390 for (; exp.More(); exp.Next()) {
1394 myIndices = new TColStd_HArray1OfInteger(1,myNbBranches+1);
1396 myIndices->SetValue(1,0);
1397 Standard_Integer Count = 0;
1398 Standard_Integer Index = 2;
1401 exp.Init(Shells,TopAbs_SHELL);
1402 for (; exp.More(); exp.Next()) {
1403 // CurS = the current Shell.
1404 const TopoDS_Shape CurS = exp.Current();
1406 TopExp_Explorer exp2(CurS, TopAbs_FACE);
1407 for (; exp2.More(); exp2.Next()) {
1408 // CurF = the current face of the current Shell.
1409 const TopoDS_Shape CurF = exp2.Current();
1411 for ( i = 1; i <= NbFaces; i++) {
1412 const TopoDS_Shape& Center = myCenters(i);
1413 const TopoDS_Shape& Rakk = myMapSF(Center).Face();
1414 // Rakk = the ith generated connection face
1415 if (CurF.IsEqual(Rakk)) {
1422 myIndices->SetValue(Index, Count);
1427 return myNbBranches;
1431 //=======================================================================
1432 //function : IndicesOfBranche
1434 //=======================================================================
1436 void BiTgte_Blend::IndicesOfBranche
1437 (const Standard_Integer Index,
1438 Standard_Integer& From,
1439 Standard_Integer& To ) const
1441 // Attention to the ranking in myIndices:
1442 // If the branches are 1-4 5-9 10-12, it is ranked in myIndices:
1444 From = myIndices->Value(Index) + 1;
1445 To = myIndices->Value(Index + 1);
1449 //=======================================================================
1450 //function : ComputeCenters
1452 //=======================================================================
1454 void BiTgte_Blend::ComputeCenters()
1459 Standard_Real TolAngle = 2*ASin(myTol/Abs(myRadius*0.5));
1460 myAnalyse.Perform(myShape,TolAngle);
1462 // ------------------------------------------
1463 // calculate faces touched by caps
1464 // ------------------------------------------
1465 TopTools_MapOfShape TouchedByCork;
1466 Touched(myAnalyse, myStopFaces, myShape, TouchedByCork);
1468 // -----------------------
1469 // init of the intersector
1470 // -----------------------
1471 TopAbs_State Side = TopAbs_IN;
1472 if (myRadius < 0.) Side = TopAbs_OUT;
1473 BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
1475 BiTgte_DataMapOfShapeBox MapSBox;
1476 TopTools_MapOfShape Done;
1477 TopTools_MapIteratorOfMapOfShape it;
1480 TopoDS_Compound Co; // to only know on which edges the tubes are made
1483 // ----------------------------------------
1484 // Calculate Sections Face/Face + Propagation
1485 // ----------------------------------------
1486 Standard_Boolean JenRajoute = Standard_True;
1488 while ( JenRajoute) {
1489 JenRajoute = Standard_False;
1491 Standard_Boolean Fini = Standard_False;
1493 TopTools_DataMapOfShapeShape EdgeTgt;
1497 // -------------------------------------------------
1498 // locate in myFaces the Faces connected to myEdges.
1499 // -------------------------------------------------
1500 Fini = Standard_True;
1501 for (it.Initialize(myEdges); it.More(); it.Next()) {
1502 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
1503 if (BRep_Tool::Degenerated(E)) continue;
1505 const TopTools_ListOfShape& L = myAncestors.FindFromKey(E);
1506 if ( L.Extent() == 1) {
1507 // So this is a free border onwhich the ball should roll.
1510 // set in myStopFaces to not propagate the tube on free border.
1514 TopTools_ListIteratorOfListOfShape itl;
1515 for (itl.Initialize(L); itl.More(); itl.Next()) {
1516 const TopoDS_Shape& Sh = itl.Value();
1517 if ( !myStopFaces.Contains(Sh)) myFaces.Add(itl.Value());
1523 // --------------------------------------------
1524 // Construction of Offsets of all faces.
1525 // --------------------------------------------
1526 for (it.Initialize(myFaces); it.More(); it.Next()) {
1527 const TopoDS_Shape& AS = it.Key();
1528 if ( myMapSF.IsBound(AS)) continue;
1530 BRepOffset_Offset OF1;
1533 if (AS.ShapeType() == TopAbs_FACE) {
1534 const TopoDS_Face& F = TopoDS::Face(it.Key());
1535 if ( TouchedByCork.Contains(F)) {
1536 BRepOffset_Tool::EnLargeFace(F,BigF,Standard_True);
1537 OF1.Init(BigF,myRadius,EdgeTgt);
1540 OF1.Init(F,myRadius,EdgeTgt);
1543 else { // So this is a Free Border edge on which the ball rolls.
1544 OF1.Init(TopoDS::Edge(AS),myRadius);
1547 // ------------------------------------
1548 // Increment the map of created tangents
1549 // ------------------------------------
1550 TopTools_ListOfShape Let;
1551 if ( AS.ShapeType() == TopAbs_FACE) {
1552 myAnalyse.Edges(TopoDS::Face(AS),BRepOffset_Tangent,Let);
1554 TopTools_ListIteratorOfListOfShape itlet(Let);
1556 for ( ; itlet.More(); itlet.Next()) {
1557 const TopoDS_Edge& Cur = TopoDS::Edge(itlet.Value());
1558 if ( !EdgeTgt.IsBound(Cur)) {
1559 TopoDS_Shape aLocalShape = OF1.Generated(Cur);
1560 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
1561 // const TopoDS_Edge& OTE = TopoDS::Edge(OF1.Generated(Cur));
1562 EdgeTgt.Bind(Cur,OF1.Generated(Cur));
1563 TopoDS_Vertex V1,V2,OV1,OV2;
1564 TopExp::Vertices (Cur,V1,V2);
1565 TopExp::Vertices (OTE,OV1,OV2);
1566 TopTools_ListOfShape LE;
1567 if (!EdgeTgt.IsBound(V1)) {
1568 myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
1569 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V1);
1570 if (LE.Extent() == LA.Extent())
1571 EdgeTgt.Bind(V1,OV1);
1573 if (!EdgeTgt.IsBound(V2)) {
1575 myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
1576 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V2);
1577 if (LE.Extent() == LA.Extent())
1578 EdgeTgt.Bind(V2,OV2);
1582 // end of map created tangent
1584 if (OF1.Status() == BRepOffset_Reversed ||
1585 OF1.Status() == BRepOffset_Degenerated ) continue;
1587 const TopoDS_Face& F1 = OF1.Face();
1590 myInitOffsetFace.SetRoot(AS);
1591 myInitOffsetFace.Bind(AS,F1);
1594 BRepBndLib::Add(F1,Box1);
1595 MapSBox.Bind(F1,Box1);
1597 // ---------------------------------------------
1598 // intersection with all already created faces.
1599 // ---------------------------------------------
1600 Fini = !Intersect(AS,F1,MapSBox,OF1,Inter);
1602 if (AS.ShapeType() == TopAbs_FACE) B.Add(Co,AS);
1604 myMapSF.Bind(AS, OF1);
1607 } // end of : while ( !Fini)
1610 //--------------------------------------------------------
1611 // so the offsets were created and intersected.
1612 // now the tubes are constructed.
1613 //--------------------------------------------------------
1614 // Construction of tubes on edge.
1615 //--------------------------------------------------------
1616 BRepOffset_Type OT = BRepOffset_Convex;
1617 if (myRadius < 0.) OT = BRepOffset_Concave;
1619 TopTools_IndexedDataMapOfShapeListOfShape Map;
1620 TopExp::MapShapesAndAncestors(Co,TopAbs_EDGE,TopAbs_FACE,Map);
1621 TopExp::MapShapesAndAncestors(Co,TopAbs_VERTEX,TopAbs_EDGE,Map);
1623 TopExp_Explorer exp(Co,TopAbs_EDGE);
1624 for ( ; exp.More(); exp.Next()) {
1625 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1626 if ( myMapSF.IsBound(E)) continue;
1628 const TopTools_ListOfShape& Anc = Map.FindFromKey(E);
1629 if (Anc.Extent() == 2) {
1630 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1631 if (!L.IsEmpty() && L.First().Type() == OT) {
1632 TopoDS_Shape aLocalShape = myMapSF(Anc.First()).Generated(E);
1633 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1634 aLocalShape = myMapSF(Anc.Last()) .Generated(E);
1635 TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
1636 // TopoDS_Edge EOn1 = TopoDS::Edge(myMapSF(Anc.First()).Generated(E));
1637 // TopoDS_Edge EOn2 = TopoDS::Edge(myMapSF(Anc.Last()) .Generated(E));
1638 // find if exits tangent edges in the original shape
1639 TopoDS_Edge E1f, E1l;
1640 TopoDS_Vertex V1f, V1l;
1641 TopExp::Vertices(E,V1f,V1l);
1642 TopTools_ListOfShape TangE;
1643 myAnalyse.TangentEdges(E,V1f,TangE);
1644 // find if the pipe on the tangent edges are soon created.
1645 TopTools_ListIteratorOfListOfShape itl(TangE);
1646 Standard_Boolean Find = Standard_False;
1647 for ( ; itl.More() && !Find; itl.Next()) {
1648 if ( myMapSF.IsBound(itl.Value())) {
1649 TopoDS_Shape aLocalShape = myMapSF(itl.Value()).Generated(V1f);
1650 E1f = TopoDS::Edge(aLocalShape);
1651 // E1f = TopoDS::Edge(myMapSF(itl.Value()).Generated(V1f));
1652 Find = Standard_True;
1656 myAnalyse.TangentEdges(E,V1l,TangE);
1657 // find if the pipe on the tangent edges are soon created.
1658 itl.Initialize(TangE);
1659 Find = Standard_False;
1660 for ( ; itl.More() && !Find; itl.Next()) {
1661 if ( myMapSF.IsBound(itl.Value())) {
1662 TopoDS_Shape aLocalShape = myMapSF(itl.Value()).Generated(V1l);
1663 E1l = TopoDS::Edge(aLocalShape);
1664 // E1l = TopoDS::Edge(myMapSF(itl.Value()).Generated(V1l));
1665 Find = Standard_True;
1668 BRepOffset_Offset OF1 (E,EOn1,EOn2,myRadius,E1f, E1l);
1669 const TopoDS_Face& F1 = OF1.Face();
1672 myInitOffsetFace.SetRoot(E);
1673 myInitOffsetFace.Bind(E,F1);
1676 BRepBndLib::Add(F1,Box1);
1677 MapSBox.Bind(F1,Box1);
1679 // ---------------------------------------------
1680 // intersection with all already created faces.
1681 // ---------------------------------------------
1682 Standard_Boolean IsOnRest = Intersect(E,F1,MapSBox,OF1,Inter);
1683 JenRajoute = JenRajoute || IsOnRest;
1685 myMapSF.Bind(E,OF1);
1690 } // end while JenRajoute
1694 myEdges = Inter.NewEdges();
1696 // -------------------------------------------------------------------
1697 // now it is necessary to limit edges on the neighbors (otherwise one
1698 // will go too far and will not be able to construct faces).
1699 // -------------------------------------------------------------------
1701 // Proceed with MakeLoops
1703 BRepOffset_Type OT = BRepOffset_Concave;
1704 if (myRadius < 0.) OT = BRepOffset_Convex;
1706 it.Initialize(myFaces);
1707 TopTools_ListOfShape LOF;
1708 for ( ; it.More(); it.Next()) {
1709 const TopoDS_Shape& CurS = it.Key();
1711 // tube on free border, it is undesirable.
1712 if ( myStopFaces.Contains(CurS)) continue;
1714 if ( !myMapSF.IsBound(CurS)) continue; // inverted or degenerated
1716 const TopoDS_Face& CurOF = myMapSF(CurS).Face();
1719 if (CurS.ShapeType() == TopAbs_FACE) {
1720 const TopoDS_Face& CurF = TopoDS::Face(CurS);
1721 TopExp_Explorer expe(CurF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1722 for (; expe.More(); expe.Next()) {
1723 // --------------------------------------------------------------
1724 // set in myAsDes the edges generated by limitations of the
1725 // initial square if the type is correct (The edges that will
1726 // disappear are not set)
1727 // --------------------------------------------------------------
1728 const TopoDS_Edge& CurE = TopoDS::Edge(expe.Current());
1729 const BRepOffset_ListOfInterval& L = myAnalyse.Type(CurE);
1730 if (!L.IsEmpty() && L.First().Type() != OT) {
1731 // a priori doe s not disappear, so it is set
1732 TopoDS_Shape aLocalShape = myMapSF(CurF).Generated(CurE);
1733 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
1734 // const TopoDS_Edge& CurOE =
1735 // TopoDS::Edge(myMapSF(CurF).Generated(CurE));
1736 myAsDes->Add(CurOF,CurOE.Oriented(CurE.Orientation()));
1739 const TopTools_ListOfShape& Lanc = myAnalyse.Ancestors(CurE);
1740 if ( !myFaces .Contains(Lanc.First())
1741 || !myFaces .Contains(Lanc.Last ())
1742 || myStopFaces.Contains(Lanc.First())
1743 || myStopFaces.Contains(Lanc.Last ())) {
1744 TopoDS_Shape aLocalShape = myMapSF(CurF).Generated(CurE);
1745 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
1746 // const TopoDS_Edge& CurOE =
1747 // TopoDS::Edge(myMapSF(CurF).Generated(CurE));
1748 myAsDes->Add(CurOF,CurOE.Oriented(CurE.Orientation()));
1752 BRepOffset_Inter2d::Compute(myAsDes,
1759 // ----------------------------------------------------------------
1760 // It is also required to make 2D intersections with generated tubes
1761 // (Useful for unwinding)
1762 // ----------------------------------------------------------------
1763 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(myMapSF);
1764 for ( ; It.More(); It.Next()) {
1765 const TopoDS_Shape& CurS = It.Key();
1766 if ( CurS.ShapeType() == TopAbs_FACE) continue;
1768 const TopoDS_Face& CurOF = It.Value().Face();
1770 // no unwinding by tubes on free border.
1771 if ( myStopFaces.Contains(CurS)) continue;
1775 // --------------------------------------------------------------
1776 // set in myAsDes the edge restrictions of the square
1777 // --------------------------------------------------------------
1778 TopExp_Explorer expe(CurOF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1779 for (; expe.More(); expe.Next()) {
1780 const TopoDS_Edge& CurOE = TopoDS::Edge(expe.Current());
1781 myAsDes->Add(CurOF,CurOE);
1784 BRepOffset_Inter2d::Compute(myAsDes,
1792 BRepOffset_MakeLoops MakeLoops;
1793 MakeLoops.Build( LOF, myAsDes, myImageOffset );
1795 // ------------------------------------------------------------
1796 // It is possible to unwind edges at least one ancestor which of
1797 // is a face of the initial shape, so:
1798 // the edges generated by intersection tube-tube are missing
1799 // ------------------------------------------------------------
1801 // --------------------------------------------------------------
1802 // Currently set the unwinded surfaces in <myResult>
1803 // --------------------------------------------------------------
1804 B.MakeCompound(TopoDS::Compound(myResult));
1805 TopTools_ListIteratorOfListOfShape itLOF(LOF);
1806 for ( ; itLOF.More(); itLOF.Next()) {
1807 const TopoDS_Shape& CurLOF = itLOF.Value();
1809 if ( !myImageOffset.HasImage(CurLOF))
1812 TopTools_ListOfShape Lim;
1813 myImageOffset.LastImage(CurLOF,Lim);
1814 TopTools_ListIteratorOfListOfShape itLim(Lim);
1815 for ( ;itLim.More(); itLim.Next()) {
1816 // If a face is its own image, it is not set
1817 const TopoDS_Shape& CurLIM = itLim.Value();
1818 if (CurLIM.IsSame(CurLOF)) break;
1820 B.Add(myResult,CurLIM);
1825 if ( myResult.IsNull()) {
1826 cout << " No Lines of Generated Centers" << endl;
1830 if (Affich) DBRep::Set("Unwind",myResult);
1837 //=======================================================================
1838 //function : ComputeSurfaces
1840 //=======================================================================
1842 void BiTgte_Blend::ComputeSurfaces()
1844 // set in myFaces, the faces actually implied in the connection
1848 // 1 - Tubes (True Fillets)
1852 Standard_Integer nbc = 1;
1855 TopTools_ListOfShape Empty;
1856 TopTools_DataMapOfShapeListOfShape EmptyMap;
1858 Handle(Geom_Surface) GS1, GS2;
1859 Handle(Geom_Curve) GC1, GC2;
1861 Standard_Real TolAngle = 2*ASin(myTol/Abs(myRadius*0.5));
1862 BRepOffset_Analyse CenterAnalyse(myResult,TolAngle);
1864 // -----------------------------------------------------
1865 // Construction of tubes in myResult
1866 // -----------------------------------------------------
1868 B.MakeCompound(TopoDS::Compound(myResult));
1870 // --------------------------------------------------------------------
1871 // Dummy: for construction of spheres:
1872 // Set in Co the center line, then it there are at least 3
1873 // center lines sharing the same vertex, Sphere on this vertex.
1874 // --------------------------------------------------------------------
1878 // --------------------------------------------------------------------
1879 // Iteration on the edges lines of center
1880 // and their valid valid part is taken after cut and tube construction.
1881 // --------------------------------------------------------------------
1882 BRepOffset_Type OT = BRepOffset_Concave;
1883 if (myRadius < 0.) OT = BRepOffset_Convex;
1885 TopTools_MapIteratorOfMapOfShape ic(myEdges);
1886 for ( ; ic.More(); ic.Next()) {
1887 const TopoDS_Edge& CurE = TopoDS::Edge(ic.Key());
1889 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1890 if ( L.Extent() != 2) continue;
1892 // --------------------------------------------------------------
1893 // F1 and F2 = 2 parallel faces intersecting in CurE.
1894 // --------------------------------------------------------------
1895 const TopoDS_Face& F1 = TopoDS::Face(L.First());
1896 const TopoDS_Face& F2 = TopoDS::Face(L.Last());
1898 // -----------------------------------------------------
1899 // find the orientation of edges of intersection
1900 // in the initial faces.
1901 // -----------------------------------------------------
1902 const TopTools_ListOfShape& LD1 = myAsDes->Descendant(F1);
1903 const TopTools_ListOfShape& LD2 = myAsDes->Descendant(F2);
1905 TopAbs_Orientation Orien1 = Orientation(CurE, F1, LD1);
1906 TopAbs_Orientation Orien2 = Orientation(CurE, F2, LD2);
1908 // ---------------------------------------------------------
1909 // Or1 and Or2 : the shapes generators of parallel faces
1910 // ---------------------------------------------------------
1911 const TopoDS_Shape& Or1 = myInitOffsetFace.ImageFrom(F1);
1912 const TopoDS_Shape& Or2 = myInitOffsetFace.ImageFrom(F2);
1917 TopoDS_Edge OE1, OE2;
1918 TopoDS_Face OF1, OF2;
1919 TopLoc_Location Loc;
1920 Standard_Real f1,l1,f2,l2;
1922 Standard_Boolean OF1isEdge = Standard_False;
1924 if ( Or1.ShapeType() == TopAbs_EDGE) {
1925 OF1isEdge = Standard_True;
1926 OE1 = TopoDS::Edge(Or1);
1927 GC1 = BRep_Tool::Curve(OE1,Loc,f1,l1);
1929 Handle(Geom_Curve)::DownCast(GC1->Transformed(Loc.Transformation()));
1931 else if ( Or1.ShapeType() == TopAbs_FACE) {
1932 OF1 = TopoDS::Face(Or1);
1933 GS1 = BRep_Tool::Surface(OF1);
1936 // ----------------------------------------------------------------
1937 // If a vertex is used in contact, currently nothing is done
1938 // and the vertexes are not managed (Intersections with sphere);
1939 // ----------------------------------------------------------------
1940 if ( OF1.IsNull() && OE1.IsNull()) continue;
1942 Standard_Boolean OF2isEdge = Standard_False;
1944 if ( Or2.ShapeType() == TopAbs_EDGE) {
1945 OF2isEdge = Standard_True;
1946 OE2 = TopoDS::Edge(Or2);
1947 GC2 = BRep_Tool::Curve(OE2,Loc,f2,l2);
1949 Handle(Geom_Curve)::
1950 DownCast(GC2->Transformed(Loc.Transformation()));
1952 else if ( Or2.ShapeType() == TopAbs_FACE) {
1953 OF2 = TopoDS::Face(Or2);
1954 GS2 = BRep_Tool::Surface(OF2);
1956 // ----------------------------------------------------------------
1957 // If a vertex is used in contact, currently nothing is done
1958 // and the vertexes are not managed (Intersections with sphere);
1959 // ----------------------------------------------------------------
1960 if ( OF2.IsNull() && OE2.IsNull()) continue;
1963 TopTools_ListOfShape CurL;
1965 if ( !myImageOffset.HasImage(CurE)) {// the tubes are not unwinded
1966 if ( OF1isEdge && OF2isEdge) { // if I don't have the image, possibly
1967 CurL.Append(CurE); // I'm on intersection tube-tube
1968 } // See comment on the call to
1973 myImageOffset.LastImage(CurE,CurL);
1976 // ---------------------------------------------------------------
1977 // CurL = List of edges descending from CurE ( = Cuts of CurE)
1978 // ---------------------------------------------------------------
1979 TopTools_ListIteratorOfListOfShape itl(CurL);
1980 for ( ; itl.More(); itl.Next()) {
1981 const TopoDS_Edge& CurCutE = TopoDS::Edge(itl.Value());
1983 Handle(Geom2d_Curve) PC1 =
1984 BRep_Tool::CurveOnSurface(CurCutE,F1,f1,l1);
1985 Handle(Geom2d_Curve) PC2 =
1986 BRep_Tool::CurveOnSurface(CurCutE,F2,f2,l2);
1987 if ( PC1.IsNull() || PC2.IsNull()) {
1989 cout << "No PCurves on Intersections : No tubes constructed";
1995 TopoDS_Edge E1f, E1l;
1996 TopoDS_Vertex V1f, V1l;
1997 TopoDS_Vertex VfOnE1,VlOnE1,VfOnE2,VlOnE2;
1998 TopTools_ListOfShape TangE;
1999 TopTools_MapOfShape MapOnV1f, MapOnV1l;
2001 TopExp::Vertices(CurCutE,V1f,V1l);
2003 // find if the pipe on the tangent edges are soon created.
2004 // edges generated by V1f and V1l + Maj MapOnV1f/l
2005 E1f = FindCreatedEdge(V1f,CurCutE,myMapSF,MapOnV1f,
2006 CenterAnalyse,myRadius,myTol);
2008 E1l = FindCreatedEdge(V1l,CurCutE,myMapSF,MapOnV1l,
2009 CenterAnalyse,myRadius,myTol);
2013 BiTgte_CurveOnEdge ConE(CurCutE, OE1);
2014 Handle(Geom_Curve) C = MakeCurve(ConE);
2015 gp_Pnt P1 = C->Value(C->FirstParameter());
2016 gp_Pnt P2 = C->Value(C->LastParameter());
2017 VfOnE1 = FindVertex(P1,MapOnV1f,myTol);
2018 if ( VfOnE1.IsNull())
2019 VfOnE1 = FindVertex(P1,MapOnV1l,myTol);
2020 VlOnE1 = FindVertex(P2,MapOnV1l,myTol);
2021 if ( VlOnE1.IsNull())
2022 VlOnE1 = FindVertex(P2,MapOnV1f,myTol);
2023 if ( P1.SquareDistance(P2) < myTol*myTol) {
2024 //BRepOffset_Offset manages degenerated KPart
2025 //It is REQUIRED that C should be a circle with ZERO radius
2026 E1 = MakeDegeneratedEdge(C,VfOnE1);
2029 E1 = BRepLib_MakeEdge(C,VfOnE1,VlOnE1);
2034 P2d = PC1->Value(f1);
2035 gp_Pnt P1 = GS1->Value(P2d.X(),P2d.Y());
2036 P2d = PC1->Value(l1);
2037 gp_Pnt P2 = GS1->Value(P2d.X(),P2d.Y());
2038 VfOnE1 = FindVertex(P1,MapOnV1f,myTol);
2039 VlOnE1 = FindVertex(P2,MapOnV1l,myTol);
2040 BRepLib_MakeEdge MKE(PC1,GS1,VfOnE1,VlOnE1,f1,l1);
2044 cout << "Edge Not Done" << endl;
2048 KPartCurve3d(E1,PC1,GS1);
2052 BiTgte_CurveOnEdge ConE(CurCutE, OE2);
2053 Handle(Geom_Curve) C = MakeCurve(ConE);
2054 gp_Pnt P1 = C->Value(C->FirstParameter());
2055 gp_Pnt P2 = C->Value(C->LastParameter());
2056 VfOnE2 = FindVertex(P1,MapOnV1f,myTol);
2057 if ( VfOnE2.IsNull())
2058 VfOnE2 = FindVertex(P1,MapOnV1l,myTol);
2059 VlOnE2 = FindVertex(P2,MapOnV1l,myTol);
2060 if ( VlOnE2.IsNull())
2061 VlOnE2 = FindVertex(P2,MapOnV1f,myTol);
2062 if ( P1.SquareDistance(P2) < myTol*myTol) {
2063 //BRepOffset_Offset manages degenerated KParts
2064 //It is REQUIRED that C should be a circle with ZERO radius
2065 E2 = MakeDegeneratedEdge(C,VfOnE2);
2068 E2 = BRepLib_MakeEdge(C,VfOnE2,VlOnE2);
2073 P2d = PC2->Value(f2);
2074 gp_Pnt P1 = GS2->Value(P2d.X(),P2d.Y());
2075 P2d = PC2->Value(l2);
2076 gp_Pnt P2 = GS2->Value(P2d.X(),P2d.Y());
2077 VfOnE2 = FindVertex(P1,MapOnV1f,myTol);
2078 VlOnE2 = FindVertex(P2,MapOnV1l,myTol);
2079 BRepLib_MakeEdge MKE(PC2,GS2,VfOnE2,VlOnE2,f2,l2);
2083 cout << "edge not Done" << endl;
2086 KPartCurve3d(E2,PC2,GS2);
2088 // Increment of the Map of Created if reconstruction of the Shape is required
2089 if ( myBuildShape) {
2090 myCreated.Bind(CurCutE,EmptyMap);
2092 myCreated(CurCutE).Bind(Or1,Empty);
2093 myCreated(CurCutE)(Or1).Append(E1);
2095 myCreated(CurCutE).Bind(Or2,Empty);
2096 myCreated(CurCutE)(Or2).Append(E2);
2099 // ----------------------------------------------------------
2100 // try to init E1f, E1l, if not found with Analysis.
2101 // Should happen only if the THEORETICALLY tangent edges
2102 // are not actually tangent ( Cf: Approximation of lines
2103 // of intersection that add noise.)
2104 // ----------------------------------------------------------
2105 TopoDS_Vertex V1,V2;
2106 if ( E1f.IsNull() && !VfOnE1.IsNull() && !VfOnE2.IsNull()) {
2107 TopTools_MapIteratorOfMapOfShape it(MapOnV1f);
2108 for ( ; it.More(); it.Next()) {
2109 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
2111 TopExp::Vertices(E,V1,V2);
2112 if ((V1.IsSame(VfOnE1) && V2.IsSame(VfOnE2)) ||
2113 (V2.IsSame(VfOnE1) && V1.IsSame(VfOnE2)) ) {
2120 if ( E1l.IsNull() && !VlOnE1.IsNull() && !VlOnE2.IsNull()) {
2121 TopTools_MapIteratorOfMapOfShape it(MapOnV1l);
2122 for ( ; it.More(); it.Next()) {
2123 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
2125 TopExp::Vertices(E,V1,V2);
2126 if ((V1.IsSame(VlOnE1) && V2.IsSame(VlOnE2)) ||
2127 (V2.IsSame(VlOnE1) && V1.IsSame(VlOnE2)) ) {
2135 E1.Orientation(Orien1);
2136 E2.Orientation(Orien2);
2138 BRepOffset_Offset AnOffset(CurCutE,E1,E2,-myRadius,E1f,E1l,
2139 myNubs, myTol, GeomAbs_C2);
2140 myMapSF.Bind(CurCutE,AnOffset);
2141 myCenters.Add(CurCutE);
2144 const TopoDS_Face& Tuyo = AnOffset.Face();
2145 B.Add(myResult,Tuyo);
2147 if ( myBuildShape) {
2148 // method based ONLY on the construction of fillet:
2149 // the first edge of the tube is exactly on Shape1.
2150 GeomAPI_ProjectPointOnCurve Projector;
2151 TopExp_Explorer exp(Tuyo,TopAbs_EDGE);
2152 TopoDS_Vertex V1,V2;
2153 if (OF1isEdge) { // Update CutEdges.
2154 const TopoDS_Edge& EOnF1 = TopoDS::Edge(exp.Current());
2155 TopExp::Vertices(EOnF1,V1,V2);
2157 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2158 Projector.Init(P1,GC1);
2159 Standard_Real U1 = Projector.LowerDistanceParameter();
2161 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2162 Projector.Init(P2,GC1);
2163 Standard_Real U2 = Projector.LowerDistanceParameter();
2165 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
2166 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,TopoDS::Edge(Or1),myTol);
2167 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
2168 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,TopoDS::Edge(Or1),myTol);
2169 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),U1,
2170 // TopoDS::Edge(Or1),myTol);
2171 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),U2,
2172 // TopoDS::Edge(Or1),myTol);
2174 if (!myCutEdges.IsBound(Or1)) {
2175 TopTools_ListOfShape Dummy;
2176 myCutEdges.Bind(Or1,Dummy);
2178 TopTools_ListOfShape& L1 = myCutEdges(Or1);
2179 L1.Append(V1); L1.Append(V2);
2181 if (OF2isEdge) { // Update CutEdges.
2183 const TopoDS_Edge& EOnF2 = TopoDS::Edge(exp.Current());
2184 TopExp::Vertices(EOnF2,V1,V2);;
2186 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2187 Projector.Init(P1,GC2);
2188 Standard_Real U1 = Projector.LowerDistanceParameter();
2190 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2191 Projector.Init(P2,GC2);
2192 Standard_Real U2 = Projector.LowerDistanceParameter();
2194 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
2195 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,TopoDS::Edge(Or2),myTol);
2196 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
2197 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,TopoDS::Edge(Or2),myTol);
2198 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),U1,
2199 // TopoDS::Edge(Or2),myTol);
2200 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),U2,
2201 // TopoDS::Edge(Or2),myTol);
2203 if (!myCutEdges.IsBound(Or2)) {
2204 TopTools_ListOfShape Dummy;
2205 myCutEdges.Bind(Or2,Dummy);
2207 TopTools_ListOfShape& L2 = myCutEdges(Or2);
2208 L2.Append(V1); L2.Append(V2);
2214 sprintf(name,"%s_%d","SURF",nbc);
2215 DBRep::Set(name,AnOffset.Face());
2222 // ---------------------------------------------------
2223 // Construction of spheres,
2224 // if enough tubes arrive at the vertex
2225 // ---------------------------------------------------
2226 TopTools_IndexedDataMapOfShapeListOfShape Map;
2227 TopExp::MapShapesAndAncestors(Co,TopAbs_VERTEX,TopAbs_EDGE,Map);
2229 for ( Standard_Integer i = 1; i <= Map.Extent(); i++) {
2230 const TopoDS_Vertex& V = TopoDS::Vertex(Map.FindKey(i));
2231 if ( Map(i).Extent() != 3) continue;
2233 TopTools_ListOfShape LOE;
2234 TopTools_ListIteratorOfListOfShape it;
2236 for (it.Initialize(Map(i)) ; it.More(); it.Next()) {
2237 Standard_Boolean Reverse = Standard_True;
2239 LOE.Append(myMapSF(it.Value()).Generated(V).Reversed());
2241 LOE.Append(myMapSF(it.Value()).Generated(V));
2244 BRepOffset_Offset OFT(V,LOE,-myRadius,myNubs, myTol, GeomAbs_C2);
2245 myMapSF.Bind(V,OFT);
2248 B.Add(myResult,OFT.Face());
2252 sprintf(name,"%s_%d","SURF",nbc);
2253 DBRep::Set(name,OFT.Face());
2261 //=======================================================================
2262 //function : ComputeShape
2264 //=======================================================================
2265 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
2267 void BiTgte_Blend::ComputeShape()
2269 // Find in the initial Shapel:
2270 // - untouched Faces
2271 // - generated tubes
2272 // - the faces neighbors of tubes that sould be reconstucted preserving sharing.
2274 // For Debug : Visualize edges of the initial shape that should be reconstructed.
2277 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myCutEdges);
2278 Standard_Integer NbEdges = 0;
2279 for ( ; itm.More(); itm.Next()) {
2280 const TopoDS_Edge& E = TopoDS::Edge(itm.Key());
2281 const TopTools_ListOfShape& VonE = itm.Value();
2282 TopTools_ListOfShape NewE;
2284 CutEdge(E,VonE,NewE);
2285 for (TopTools_ListIteratorOfListOfShape it(NewE); it.More(); it.Next()) {
2286 sprintf(name,"%s_%d","CUTE",++NbEdges);
2287 DBRep::Set(name,it.Value());
2295 // modify the tubes on edge for partition of edges.
2297 Standard_Integer NbS = NbSurfaces();
2299 for (Standard_Integer i = 1; i <= NbS; i++) {
2300 const TopoDS_Shape& S1 = SupportShape1(i);
2302 if ( S1.ShapeType() == TopAbs_EDGE) {
2303 const TopoDS_Edge& E1 = TopoDS::Edge(S1);
2304 // it is required to replace in F the cut edges of E1, that
2306 const TopTools_ListOfShape& VonE = myCutEdges(E1);
2307 TopTools_ListOfShape NewE;
2308 CutEdge(E1,VonE,NewE);
2314 TopTools_DataMapOfShapeShape Created;
2316 TopTools_ListOfShape Empty;
2317 TopTools_DataMapOfShapeListOfShape EmptyMap;
2322 Standard_Integer NbNT = 1;
2325 // Maj of the Map of created.
2326 // Update edges that do not change in the resulting shape
2327 // i.e. invariant edges in the unwinding.
2328 TopExp_Explorer exp(myShape,TopAbs_FACE);
2329 // Standard_Integer nbe = 1;
2330 for ( ;exp.More(); exp.Next()) {
2332 const TopoDS_Face& CurF = TopoDS::Face(exp.Current());
2334 if ( !myFaces.Contains(CurF)) continue; // so the face is not touched
2336 // so the faces are unwinded
2337 if ( !myMapSF.IsBound(CurF)) continue; // inverted or degenerated
2339 const BRepOffset_Offset& Offset = myMapSF(CurF);
2340 const TopoDS_Face& CurOF = myMapSF(CurF).Face();
2342 if ( !myImageOffset.HasImage(CurOF)) // face disappears in unwinding
2345 TopExp_Explorer exp2(CurF,TopAbs_EDGE);
2346 for ( ;exp2.More(); exp2.Next()) {
2347 const TopoDS_Edge& CurE = TopoDS::Edge(exp2.Current());
2348 TopoDS_Shape aLocalShape = Offset.Generated(CurE);
2349 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
2350 // const TopoDS_Edge& CurOE = TopoDS::Edge(Offset.Generated(CurE));
2352 if (!myImageOffset.HasImage(CurOE)) continue;
2355 const TopoDS_Edge& ImE =
2356 TopoDS::Edge(myImageOffset.Image(CurOE).First());
2357 if (ImE.IsSame(CurOE)) {
2358 myCreated.Bind(CurOE,EmptyMap);
2359 myCreated(CurOE).Bind(CurF,Empty);
2360 myCreated(CurOE)(CurF).Append(CurE);
2365 // The connected faces are already in myResult.
2366 // So it is necessary to add faces:
2367 // - non-touched (so not in myFaces)
2368 // - issuing from the unwinding (non degenerated, non inverted, non disappeared)
2369 exp.Init(myShape,TopAbs_FACE);
2370 for ( ;exp.More(); exp.Next()) {
2372 const TopoDS_Face& CurF = TopoDS::Face(exp.Current());
2374 if ( !myFaces.Contains(CurF)) {
2375 // so the face is not touched
2376 B.Add(myResult,CurF);
2378 else { // so the faces are unwindeds
2380 if ( !myMapSF.IsBound(CurF)) continue; // inverted or degenerated
2382 const TopoDS_Face& CurOF = myMapSF(CurF).Face();
2384 if ( !myImageOffset.HasImage(CurOF)) // face disappears in unwinding
2387 // List of faces generated by a face in the unwinding
2388 TopTools_ListOfShape Lim;
2389 myImageOffset.LastImage(CurOF,Lim);
2390 TopTools_ListIteratorOfListOfShape itLim(Lim);
2391 for ( ;itLim.More(); itLim.Next()) {
2392 // DeboucFace = offset Face unwinded in "Debouc".
2393 const TopoDS_Face& DeboucFace = TopoDS::Face(itLim.Value());
2396 Handle(Geom_Surface) S = BRep_Tool::Surface(CurF,L);
2398 TopoDS_Face NewF; B.MakeFace(NewF);
2399 B.UpdateFace(NewF,S,L,BRep_Tool::Tolerance(CurF));
2401 TopTools_DataMapOfShapeShape MapSS;
2403 TopoDS_Shape aLocalShape = DeboucFace.Oriented(TopAbs_FORWARD);
2404 const TopoDS_Face& Face = TopoDS::Face(aLocalShape);
2405 // const TopoDS_Face& Face =
2406 // TopoDS::Face(DeboucFace.Oriented(TopAbs_FORWARD));
2407 TopExp_Explorer exp2(Face, TopAbs_EDGE);
2408 for ( ; exp2.More(); exp2.Next()) {
2409 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
2410 TopoDS_Vertex V1,V2,OV1,OV2;
2411 TopExp::Vertices(E ,V1 ,V2 );
2412 if (myCreated.IsBound(E)) {
2413 if (myCreated(E).IsBound(CurF)) {
2414 const TopoDS_Edge& OE = TopoDS::Edge(myCreated(E)(CurF).First());
2415 TopExp::Vertices(OE,OV1,OV2);
2416 if ( !myCreated.IsBound(V1)) myCreated.Bind(V1,EmptyMap);
2417 if ( !myCreated.IsBound(V2)) myCreated.Bind(V2,EmptyMap);
2418 if ( !myCreated(V1).IsBound(CurF)) {
2419 myCreated(V1).Bind(CurF,Empty);
2420 myCreated(V1)(CurF).Append(OV1);
2422 if ( !myCreated(V2).IsBound(CurF)) {
2423 myCreated(V2).Bind(CurF,Empty);
2424 myCreated(V2)(CurF).Append(OV2);
2430 TopExp_Explorer expw(Face, TopAbs_WIRE);
2431 for ( ; expw.More(); expw.Next()) {
2432 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
2433 TopExp_Explorer expe(W.Oriented(TopAbs_FORWARD),
2438 for ( ; expe.More(); expe.Next()) {
2439 const TopoDS_Edge& E = TopoDS::Edge(expe.Current());
2441 Handle(Geom2d_Curve) C2d =
2442 BRep_Tool::CurveOnSurface(E,Face,f,l);
2444 if ( MapSS.IsBound(E)) { // this is an edge of cutting
2445 OE = TopoDS::Edge(MapSS(E));
2446 TopoDS_Shape aLocalShape = E.Reversed();
2447 Handle(Geom2d_Curve) C2d_1 =
2448 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),Face,f,l);
2449 // Handle(Geom2d_Curve) C2d_1 =
2450 // BRep_Tool::CurveOnSurface(TopoDS::Edge(E.Reversed()),
2452 if ( E.Orientation() == TopAbs_FORWARD)
2453 B.UpdateEdge(OE,C2d,C2d_1,NewF,BRep_Tool::Tolerance(E));
2455 B.UpdateEdge(OE,C2d_1,C2d,NewF,BRep_Tool::Tolerance(E));
2459 // Is there an image in the Map of Created ?
2460 if ( myCreated.IsBound(E)) {
2461 if ( myCreated(E).IsBound(CurF)) {
2462 OE = TopoDS::Edge(myCreated(E)(CurF).First());
2467 TopoDS_Vertex V1,V2,OV1,OV2;
2468 TopExp::Vertices(E,V1,V2);
2469 if ( myCreated.IsBound(V1) && myCreated(V1).IsBound(CurF)) {
2470 OV1 = TopoDS::Vertex(myCreated(V1)(CurF).First());
2475 C2d->Value(BRep_Tool::Parameter(V1,E,Face));
2477 S->D0(P2d.X(),P2d.Y(),P);
2478 P.Transform(L.Transformation());
2479 B.UpdateVertex(OV1,P,BRep_Tool::Tolerance(V1));
2480 myCreated.Bind(V1,EmptyMap);
2481 myCreated(V1).Bind(CurF,Empty);
2482 myCreated(V1)(CurF).Append(OV1);
2484 if ( myCreated.IsBound(V2) && myCreated(V2).IsBound(CurF)) {
2485 OV2 = TopoDS::Vertex(myCreated(V2)(CurF).First());
2490 C2d->Value(BRep_Tool::Parameter(V2,E,Face));
2492 S->D0(P2d.X(),P2d.Y(),P);
2493 P.Transform(L.Transformation());
2494 B.UpdateVertex(OV2,P,BRep_Tool::Tolerance(V2));
2495 myCreated.Bind(V2,EmptyMap);
2496 myCreated(V2).Bind(CurF,Empty);
2497 myCreated(V2)(CurF).Append(OV2);
2499 B.Add(OE,OV1.Oriented(V1.Orientation()));
2500 B.Add(OE,OV2.Oriented(V2.Orientation()));
2502 B.UpdateEdge(OE,C2d,NewF,BRep_Tool::Tolerance(E));
2504 // ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
2507 B.Add(OW, OE.Oriented(E.Orientation()));
2509 B.Add(NewF, OW.Oriented(W.Orientation()));
2512 NewF.Orientation(DeboucFace.Orientation());
2514 BRepTools::Update(NewF);
2515 B.Add(myResult,NewF);
2520 // non-regarding the cause, there always remain greeb borders on this Shape, so it is sewn.
2521 Handle(BRepBuilderAPI_Sewing) Sew = new BRepBuilderAPI_Sewing(myTol);
2523 BRepLib::BuildCurves3d(myResult);
2525 exp.Init(myResult,TopAbs_FACE);
2526 for ( ;exp.More(); exp.Next())
2527 Sew->Add(exp.Current());
2531 // SameParameter is done in case Sew does not do it (Detect that the edges
2532 // are not sameparameter but does nothing.)
2534 const TopoDS_Shape& SewedShape = Sew->SewedShape();
2535 if ( !SewedShape.IsNull()) {
2536 exp.Init(Sew->SewedShape(), TopAbs_EDGE);
2537 for (; exp.More(); exp.Next()) {
2538 const TopoDS_Edge& sec = TopoDS::Edge(exp.Current());
2539 BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
2541 myResult = SewedShape;
2546 //=======================================================================
2547 //function : Intersect
2549 //=======================================================================
2551 Standard_Boolean BiTgte_Blend::Intersect
2552 (const TopoDS_Shape& Init,
2553 const TopoDS_Face& Face,
2554 const BiTgte_DataMapOfShapeBox& MapSBox,
2555 const BRepOffset_Offset& OF1,
2556 BRepOffset_Inter3d& Inter)
2558 Standard_Boolean JenRajoute = Standard_False;
2560 const Bnd_Box& Box1 = MapSBox(Face);
2562 // -----------------------------------------------
2563 // intersection with all already created faces.
2564 // -----------------------------------------------
2565 const TopoDS_Shape& InitShape1 = OF1.InitialShape();
2566 Standard_Boolean F1surBordLibre =
2567 InitShape1.ShapeType() == TopAbs_EDGE &&
2568 myStopFaces.Contains(InitShape1);
2570 TopTools_MapOfShape Done;
2571 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(myMapSF);
2572 for ( ; It.More(); It.Next()) {
2573 const BRepOffset_Offset& OF2 = It.Value();
2574 const TopoDS_Face& F2 = OF2.Face();
2576 if (Box1.IsOut(MapSBox(F2))) continue;
2578 if ( Inter.IsDone(Face,F2)) continue;
2580 // 2 tubes created on free border are not intersected.
2581 const TopoDS_Shape& InitShape2 = OF2.InitialShape();
2582 Standard_Boolean F2surBordLibre =
2583 InitShape2.ShapeType() == TopAbs_EDGE &&
2584 myStopFaces.Contains(InitShape2);
2587 if ( F1surBordLibre && F2surBordLibre) {
2588 cout << "Rejection : 2 tubes on free border are not intersected";
2593 if ( F1surBordLibre && F2surBordLibre) continue;
2595 // -------------------------------------------------------
2596 // Tubes are not intersected with neighbor faces.
2597 // -------------------------------------------------------
2598 const TopoDS_Shape& ItKey = It.Key();
2600 if ( Init.ShapeType() == TopAbs_EDGE) {
2601 if (ItKey.ShapeType() == TopAbs_FACE &&
2602 IsInFace(TopoDS::Edge(Init), TopoDS::Face(ItKey))) continue;
2605 Inter.FaceInter(Face,F2,myInitOffsetFace);
2607 // ------------------------------------------
2608 // an edge of F1 or F2 has been touched ?
2609 // if yes, add faces in myFaces
2610 // ==> JenRajoute = True
2611 // ------------------------------------------
2612 TopTools_ListOfShape LInt;
2614 if (myAsDes->HasCommonDescendant(Face,F2,LInt)) {
2615 TopTools_ListIteratorOfListOfShape itl2;
2616 for (itl2.Initialize(LInt); itl2.More(); itl2.Next()) {
2617 const TopoDS_Edge& CurE = TopoDS::Edge(itl2.Value());
2618 TopoDS_Vertex V1,V2;
2620 TopExp::Vertices(CurE,V1,V2);
2622 if ( Done.Add(V1)) {
2623 Standard_Boolean IsOnR1 = IsOnRestriction(V1,CurE,Face,E1);
2624 Standard_Boolean IsOnR2 = IsOnRestriction(V1,CurE,F2,E2);
2626 if (IsOnR1 && IsOnR2) {
2627 cout << "Leave in the same tps on 2 faces, ";
2628 cout << "propagation only on free border";
2633 if ( !myStopFaces.Contains(Init)) {
2634 Add(E1,myEdges,Init,OF1,myAnalyse,IsOnR1 && IsOnR2);
2635 JenRajoute = Standard_True;
2639 if ( !myStopFaces.Contains(ItKey)) {
2640 Add(E2,myEdges, ItKey,OF2,myAnalyse,IsOnR1 && IsOnR2);
2641 JenRajoute = Standard_True;
2646 if ( Done.Add(V2)) {
2647 Standard_Boolean IsOnR1 = IsOnRestriction(V2,CurE,Face,E1);
2648 Standard_Boolean IsOnR2 = IsOnRestriction(V2,CurE,F2,E2);
2650 // If IsOnR1 && IsOnR2,
2651 // Leave in the same tps on 2 faces, propagate only on
2653 // A priori, only facet is closed.
2655 if (IsOnR1 && IsOnR2) {
2656 cout << "Leave with the same tps on 2 faces, ";
2657 cout << "propagate only if the border is free";
2662 if ( !myStopFaces.Contains(Init)) {
2663 Add(E1,myEdges,Init,OF1,myAnalyse,IsOnR1 && IsOnR2);
2664 JenRajoute = Standard_True;
2668 if ( !myStopFaces.Contains(ItKey)) {
2669 Add(E2,myEdges,ItKey,OF2,myAnalyse,IsOnR1 && IsOnR2);
2670 JenRajoute = Standard_True;