1 // Created on: 1996-12-16
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <AppCont_Function.hxx>
19 #include <AppParCurves_MultiCurve.hxx>
20 #include <Approx_FitAndDivide.hxx>
21 #include <BiTgte_Blend.hxx>
22 #include <BiTgte_CurveOnEdge.hxx>
23 #include <BiTgte_DataMapOfShapeBox.hxx>
24 #include <Bnd_Box.hxx>
25 #include <BRep_Builder.hxx>
26 #include <BRep_Tool.hxx>
27 #include <BRepAlgo_AsDes.hxx>
28 #include <BRepAlgo_Loop.hxx>
29 #include <BRepBndLib.hxx>
30 #include <BRepBuilderAPI_Sewing.hxx>
31 #include <BRepLib.hxx>
32 #include <BRepLib_MakeEdge.hxx>
33 #include <BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx>
34 #include <BRepOffset_DataMapOfShapeOffset.hxx>
35 #include <BRepOffset_Inter2d.hxx>
36 #include <BRepOffset_Inter3d.hxx>
37 #include <BRepOffset_Interval.hxx>
38 #include <BRepOffset_ListOfInterval.hxx>
39 #include <BRepOffset_MakeLoops.hxx>
40 #include <BRepOffset_Offset.hxx>
41 #include <BRepOffset_Tool.hxx>
42 #include <BRepTools.hxx>
43 #include <BRepTools_Quilt.hxx>
44 #include <BSplCLib.hxx>
46 #include <Convert_CompBezierCurvesToBSplineCurve.hxx>
48 #include <Geom2d_Curve.hxx>
49 #include <Geom2dAdaptor_Curve.hxx>
50 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
51 #include <Geom_BSplineCurve.hxx>
52 #include <Geom_Circle.hxx>
53 #include <Geom_Curve.hxx>
54 #include <Geom_Line.hxx>
55 #include <Geom_Surface.hxx>
56 #include <Geom_TrimmedCurve.hxx>
57 #include <GeomAbs_SurfaceType.hxx>
58 #include <GeomAdaptor_Surface.hxx>
59 #include <GeomAPI.hxx>
60 #include <GeomAPI_ProjectPointOnCurve.hxx>
64 #include <gp_Circ.hxx>
66 #include <gp_Dir2d.hxx>
68 #include <gp_Lin2d.hxx>
70 #include <gp_Pnt2d.hxx>
71 #include <gp_Sphere.hxx>
72 #include <OSD_Chronometer.hxx>
73 #include <Precision.hxx>
74 #include <Standard_NotImplemented.hxx>
75 #include <Standard_OutOfRange.hxx>
76 #include <StdFail_NotDone.hxx>
77 #include <TColgp_Array1OfPnt.hxx>
78 #include <TColStd_Array1OfInteger.hxx>
79 #include <TColStd_Array1OfReal.hxx>
81 #include <TopExp_Explorer.hxx>
83 #include <TopoDS_Compound.hxx>
84 #include <TopoDS_Edge.hxx>
85 #include <TopoDS_Face.hxx>
86 #include <TopoDS_Shape.hxx>
87 #include <TopoDS_Vertex.hxx>
88 #include <TopoDS_Wire.hxx>
89 #include <TopTools_DataMapOfShapeShape.hxx>
90 #include <TopTools_ListIteratorOfListOfShape.hxx>
91 #include <TopTools_ListOfShape.hxx>
92 #include <TopTools_MapIteratorOfMapOfShape.hxx>
93 #include <TopTools_SequenceOfShape.hxx>
97 // - all small static functions.
98 //======================== START STATIC FUNCTIONS ============
99 // variables for performance
100 Standard_Real t_mkcurve;
101 extern void ChFi3d_InitChron(OSD_Chronometer& ch);
102 extern void ChFi3d_ResultChron(OSD_Chronometer & ch, Standard_Real& time);
104 static Standard_Boolean Affich = Standard_False;
105 static char name[100];
109 //=======================================================================
110 //function : IsOnRestriction
112 //=======================================================================
114 static Standard_Boolean IsOnRestriction(const TopoDS_Vertex& V,
115 const TopoDS_Edge& CurE,
116 const TopoDS_Face& F,
119 // find if Vertex V of CurE is on a restriction of F.
120 // if yes, store this restriction in E.
123 // Method somewhat brutal : possible to really optimize by a
124 // direct call the SD of intersections -> See LBR
127 Handle(Geom2d_Curve) CurC = BRep_Tool::CurveOnSurface(CurE,F,f,l);
128 Standard_Real U = BRep_Tool::Parameter(V,CurE,F);
129 gp_Pnt2d P = CurC->Value(U);
131 Geom2dAPI_ProjectPointOnCurve Proj;
133 // The tolerance is exaggerated : it is better to construct too many
134 // tubes than to miss intersections.
135 // Standard_Real Tol = 100 * BRep_Tool::Tolerance(V);
136 Standard_Real Tol = BRep_Tool::Tolerance(V);
137 TopExp_Explorer exp(F,TopAbs_EDGE);
138 for ( ; exp.More(); exp.Next()) {
139 E = TopoDS::Edge(exp.Current());
140 Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(E,F,f,l);
142 if ( Proj.NbPoints() > 0) {
143 if (Proj.LowerDistance() < Tol) {
144 return Standard_True;
148 return Standard_False;
151 //=======================================================================
154 //=======================================================================
156 static void Add(const TopoDS_Edge& E,
157 TopTools_IndexedMapOfShape& Map,
158 const TopoDS_Shape& S,
159 const BRepOffset_Offset& OF,
160 const BRepOffset_Analyse& Analyse,
161 const Standard_Boolean WarningSurBordLibre)
162 // If WarningSurBordLibre = TRUE, no propagation if the edge is open.
164 TopAbs_ShapeEnum Type = S.ShapeType();
166 if ( Type == TopAbs_FACE) {
167 TopExp_Explorer exp(S,TopAbs_EDGE);
168 for ( ; exp.More(); exp.Next()) {
169 const TopoDS_Edge& OriE = TopoDS::Edge(exp.Current());
170 TopoDS_Shape aLocalShape = OF.Generated(OriE);
171 const TopoDS_Edge& IE = TopoDS::Edge(aLocalShape);
172 // const TopoDS_Edge& IE = TopoDS::Edge(OF.Generated(OriE));
173 if ( E.IsEqual(IE)) {
174 if (WarningSurBordLibre) {
175 // It is checked that the border is not free.
176 const TopTools_ListOfShape& L = Analyse.Ancestors(OriE);
177 if (L.Extent() == 1) break; // Nothing is done.
179 Map.Add(exp.Current());
184 else if ( Type == TopAbs_EDGE) {
185 TopExp_Explorer exp(S,TopAbs_VERTEX);
186 for ( ; exp.More(); exp.Next()) {
187 TopoDS_Shape aLocalShape = OF.Generated(exp.Current());
188 const TopoDS_Edge& IE = TopoDS::Edge(aLocalShape);
189 // const TopoDS_Edge& IE = TopoDS::Edge(OF.Generated(exp.Current()));
190 if ( E.IsEqual(IE)) {
191 const TopTools_ListOfShape& L = Analyse.Ancestors(exp.Current());
192 TopTools_ListIteratorOfListOfShape it(L);
193 for ( ; it.More(); it.Next()) {
203 //=======================================================================
204 //function : IsInFace
206 //=======================================================================
208 static Standard_Boolean IsInFace(const TopoDS_Edge& E,
209 const TopoDS_Face& F)
211 TopExp_Explorer exp(F,TopAbs_EDGE);
212 for ( ;exp.More(); exp.Next())
213 if ( E.IsSame(exp.Current())) return Standard_True;
214 return Standard_False;
218 //=======================================================================
219 //function : KPartCurve3d
221 //=======================================================================
223 static void KPartCurve3d(TopoDS_Edge Edge,
224 Handle(Geom2d_Curve) Curve,
225 Handle(Geom_Surface) Surf)
227 // try to find the particular case
228 // if not found call BRepLib::BuildCurve3d
231 Standard_Real Tol = Precision::Confusion();
233 // Seach only isos on analytical surfaces.
234 Geom2dAdaptor_Curve C(Curve);
235 GeomAdaptor_Surface S(Surf);
236 GeomAbs_CurveType CTy = C.GetType();
237 GeomAbs_SurfaceType STy = S.GetType();
238 BRep_Builder TheBuilder;
240 if ( STy != GeomAbs_Plane) { // if plane buildcurve3d manage KPart
241 if ( CTy == GeomAbs_Line) {
242 gp_Dir2d D = C.Line().Direction();
243 if ( D.IsParallel(gp::DX2d(),Precision::Angular())) { // Iso V.
244 if ( STy == GeomAbs_Sphere) {
245 gp_Pnt2d P = C.Line().Location();
246 if ( Abs( Abs(P.Y()) -M_PI/2. ) < Precision::PConfusion()) {
247 TheBuilder.Degenerated(Edge, Standard_True);
250 gp_Sphere Sph = S.Sphere();
251 gp_Ax3 Axis = Sph.Position();
252 gp_Circ Ci = ElSLib::SphereVIso(Axis,
255 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
256 gp_Ax1 AxeRev(Axis.Location(), DRev);
257 Ci.Rotate(AxeRev, P.X());
258 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
259 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
261 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
264 else if ( STy == GeomAbs_Cylinder) {
265 gp_Cylinder Cyl = S.Cylinder();
266 gp_Pnt2d P = C.Line().Location();
267 gp_Ax3 Axis = Cyl.Position();
268 gp_Circ Ci = ElSLib::CylinderVIso(Axis,
271 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
272 gp_Ax1 AxeRev(Axis.Location(), DRev);
273 Ci.Rotate(AxeRev, P.X());
274 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
275 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
277 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
279 else if ( STy == GeomAbs_Cone) {
280 gp_Cone Cone = S.Cone();
281 gp_Pnt2d P = C.Line().Location();
282 gp_Ax3 Axis = Cone.Position();
283 gp_Circ Ci = ElSLib::ConeVIso(Axis,
287 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
288 gp_Ax1 AxeRev(Axis.Location(), DRev);
289 Ci.Rotate(AxeRev, P.X());
290 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
291 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
293 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
295 else if ( STy == GeomAbs_Torus) {
296 gp_Torus Tore = S.Torus();
297 gp_Pnt2d P = C.Line().Location();
298 gp_Ax3 Axis = Tore.Position();
299 gp_Circ Ci = ElSLib::TorusVIso(Axis,
303 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
304 gp_Ax1 AxeRev(Axis.Location(), DRev);
305 Ci.Rotate(AxeRev, P.X());
306 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
307 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
309 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
312 else if ( D.IsParallel(gp::DY2d(),Precision::Angular())) { // Iso U.
313 if ( STy == GeomAbs_Sphere) {
314 gp_Sphere Sph = S.Sphere();
315 gp_Pnt2d P = C.Line().Location();
316 gp_Ax3 Axis = Sph.Position();
318 gp_Circ Ci = ElSLib::SphereUIso(Axis, Sph.Radius(),0.);
320 // set to sameparameter (rotation of the circle - offset from Y)
321 gp_Dir DRev = Axis.XDirection().Crossed(Axis. Direction());
322 gp_Ax1 AxeRev(Axis.Location(),DRev);
323 Ci.Rotate(AxeRev, P.Y());
325 // transformation by iso U ( = P.X())
326 DRev = Axis.XDirection().Crossed(Axis.YDirection());
327 AxeRev = gp_Ax1(Axis.Location(), DRev);
328 Ci.Rotate(AxeRev, P.X());
329 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
331 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
333 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
335 else if ( STy == GeomAbs_Cylinder) {
336 gp_Cylinder Cyl = S.Cylinder();
337 gp_Pnt2d P = C.Line().Location();
338 gp_Lin L = ElSLib::CylinderUIso(Cyl.Position(),
341 gp_Vec Tr(L.Direction());
344 Handle(Geom_Line) Line = new Geom_Line(L);
345 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
347 TheBuilder.UpdateEdge(Edge, Line, Loc, Tol);
349 else if ( STy == GeomAbs_Cone) {
350 gp_Cone Cone = S.Cone();
351 gp_Pnt2d P = C.Line().Location();
352 gp_Lin L = ElSLib::ConeUIso(Cone.Position(),
356 gp_Vec Tr(L.Direction());
358 L.Translate(Tr); Handle(Geom_Line) Line = new Geom_Line(L);
359 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
361 TheBuilder.UpdateEdge(Edge, Line, Loc, Tol);
363 else if ( STy == GeomAbs_Torus) {
369 Handle(Geom_Curve) C3d = GeomAPI::To3d(Curve,S.Plane());
370 TheBuilder.UpdateEdge(Edge, C3d, Loc, Tol);
375 //=======================================================================
376 //function : MakeCurve
378 //=======================================================================
380 class MakeCurve_Function : public AppCont_Function
382 BiTgte_CurveOnEdge myCurve;
386 MakeCurve_Function(const BiTgte_CurveOnEdge& C)
393 Standard_Real FirstParameter() const
395 return myCurve.FirstParameter();
398 Standard_Real LastParameter() const
400 return myCurve.LastParameter();
403 Standard_Boolean Value(const Standard_Real theT,
404 NCollection_Array1<gp_Pnt2d>& /*thePnt2d*/,
405 NCollection_Array1<gp_Pnt>& thePnt) const
407 thePnt(1) = myCurve.Value(theT);
408 return Standard_True;
411 Standard_Boolean D1(const Standard_Real /*theT*/,
412 NCollection_Array1<gp_Vec2d>& /*theVec2d*/,
413 NCollection_Array1<gp_Vec>& /*theVec*/) const
415 return Standard_False;
420 Handle(Geom_Curve) MakeCurve (const BiTgte_CurveOnEdge& HC)
422 Handle(Geom_Curve) C;
426 ChFi3d_InitChron(ch);
429 if ( HC.GetType() == GeomAbs_Circle) {
430 C = new Geom_Circle(HC.Circle());
431 C = new Geom_TrimmedCurve(C,HC.FirstParameter(),HC.LastParameter());
433 else { // the approximation is done
434 MakeCurve_Function F(HC);
435 Standard_Integer Deg1, Deg2;
437 Standard_Real Tol = Precision::Approximation();
438 Approx_FitAndDivide Fit(F,Deg1,Deg2,Tol,Tol,Standard_True);
440 Standard_Integer NbCurves = Fit.NbMultiCurves();
441 // it is attempted to make the curve at least C1
442 Convert_CompBezierCurvesToBSplineCurve Conv;
444 for (i = 1; i <= NbCurves; i++) {
445 AppParCurves_MultiCurve MC = Fit.Value( i); //Load the Ith Curve
446 TColgp_Array1OfPnt Poles( 1, MC.Degree() + 1); //Return poles
449 Conv.AddCurve(Poles);
454 Standard_Integer NbPoles = Conv.NbPoles();
455 Standard_Integer NbKnots = Conv.NbKnots();
456 TColgp_Array1OfPnt NewPoles(1,NbPoles);
457 TColStd_Array1OfReal NewKnots(1,NbKnots);
458 TColStd_Array1OfInteger NewMults(1,NbKnots);
460 Conv.KnotsAndMults(NewKnots,NewMults);
461 Conv.Poles(NewPoles);
463 BSplCLib::Reparametrize(HC.FirstParameter(),
467 C = new Geom_BSplineCurve (NewPoles,
474 ChFi3d_ResultChron(ch, t_mkcurve);
481 //=======================================================================
483 //purpose : Only the faces connected with caps are given
484 //=======================================================================
486 static void Touched(const BRepOffset_Analyse&,
487 const TopTools_MapOfShape&,
489 TopTools_MapOfShape&)
491 // currently nothing is done !!
492 /*if ( Standard_True) {
496 TopExp_Explorer exp(Shape, TopAbs_EDGE);
497 for ( ; exp.More(); exp.Next()) {
498 const TopTools_ListOfShape& L = Analyse.Ancestors(exp.Current());
499 if (StopFaces.Contains(L.First()))
500 TouchedByCork.Add(L.Last());
501 else if (StopFaces.Contains(L.Last()))
502 TouchedByCork.Add(L.First());
508 //=======================================================================
509 //function : FindVertex
511 //=======================================================================
513 static TopoDS_Vertex FindVertex(const gp_Pnt& P,
514 const TopTools_MapOfShape& Map,
515 const Standard_Real Tol)
518 // Find in <Map> a vertex which represent the point <P>.
519 Standard_Real Tol2,Dist;
520 TopoDS_Vertex V,VV[2];
521 Standard_Real TolCarre = Tol*Tol;
522 TopTools_MapIteratorOfMapOfShape it(Map);
523 for ( ; it.More(); it.Next()) {
524 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
526 TopExp::Vertices(E,VV[0],VV[1]);
528 for (Standard_Integer i = 0; i < 2 ; i++) {
529 // if OK la Tolerance du Vertex
530 Tol2 = BRep_Tool::Tolerance(VV[i]);
532 gp_Pnt P1 = BRep_Tool::Pnt(VV[i]);
533 Dist = P.SquareDistance(P1);
534 if ( Dist <= Tol2) return VV[i];
535 // otherwise with the required tolerance.
536 if (TolCarre > Tol2) {
537 if ( Dist <= TolCarre) {
538 // so it is necessary to update the tolerance of Vertex.
539 B.UpdateVertex(VV[i],Tol);
551 //=======================================================================
552 //function : MakeDegeneratedEdge
554 //=======================================================================
556 static TopoDS_Edge MakeDegeneratedEdge(const Handle(Geom_Curve)& CC,
557 const TopoDS_Vertex& VfOnE)
560 Standard_Real Tol = Precision::Confusion();
561 // kill trimmed curves
562 Handle(Geom_Curve) C = CC;
563 Handle(Geom_TrimmedCurve) CT = Handle(Geom_TrimmedCurve)::DownCast(C);
564 while (!CT.IsNull()) {
565 C = CT->BasisCurve();
566 CT = Handle(Geom_TrimmedCurve)::DownCast(C);
570 if ( VfOnE.IsNull()) {
571 gp_Pnt P = C->Value(C->FirstParameter());
572 B.MakeVertex(V1,P,Tol);
578 V1.Orientation(TopAbs_FORWARD);
579 V2.Orientation(TopAbs_REVERSED);
583 B.Add(E,V1); B.Add(E,V2);
584 // B.UpdateVertex(V1,C->FirstParameter(),E,Tol);
585 // B.UpdateVertex(V2,C->LastParameter(),E,Tol);
586 B.Range(E,CC->FirstParameter(),CC->LastParameter());
591 //=======================================================================
592 //function : Orientation
594 //=======================================================================
596 static TopAbs_Orientation Orientation(const TopoDS_Edge& E,
597 const TopoDS_Face& F,
598 const TopTools_ListOfShape& L)
600 TopAbs_Orientation Orien = TopAbs_FORWARD;
601 TopTools_ListIteratorOfListOfShape itld;
602 for ( itld.Initialize(L); itld.More(); itld.Next()) {
603 if ( itld.Value().IsSame(E)) {
604 Orien = itld.Value().Orientation();
608 if ( F.Orientation() == TopAbs_REVERSED)
609 Orien = TopAbs::Reverse(Orien);
614 //=======================================================================
615 //function : FindCreatedEdge
617 //=======================================================================
619 static TopoDS_Edge FindCreatedEdge
620 (const TopoDS_Vertex& V1,
621 const TopoDS_Edge& E,
622 const BRepOffset_DataMapOfShapeOffset& MapSF,
623 TopTools_MapOfShape& MapOnV,
624 const BRepOffset_Analyse& CenterAnalyse,
625 Standard_Real Radius,
629 if (!CenterAnalyse.HasAncestor(V1)) return E1; // return a Null Shape.
631 TopTools_ListOfShape TangE;
632 CenterAnalyse.TangentEdges(E,V1,TangE);
634 TopTools_ListIteratorOfListOfShape itl(TangE);
635 Standard_Boolean Find = Standard_False;
636 for ( ; itl.More() && !Find; itl.Next()) {
637 const TopoDS_Edge& ET = TopoDS::Edge(itl.Value());
638 if ( MapSF.IsBound(ET)) {
639 TopoDS_Shape aLocalShape = MapSF(ET).Generated(V1);
640 E1 = TopoDS::Edge(aLocalShape);
641 // E1 = TopoDS::Edge(MapSF(ET).Generated(V1));
643 Find = Standard_True;
646 // Find the sharing of vertices in case of tangent consecutive 3 edges
647 // the second of which is the edge that degenerates the tube.
648 TopLoc_Location CLoc;
650 Handle(Geom_Curve) CET =
651 BRep_Tool::Curve(ET,CLoc,ff,ll);
652 if ( CET->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
653 CET = Handle(Geom_TrimmedCurve)::DownCast(CET)->BasisCurve();
655 Handle(Geom_Circle) Circ = Handle(Geom_Circle)::DownCast(CET);
656 if ( Circ.IsNull()) continue;
657 if ( Abs(Circ->Radius() - Abs(Radius)) > Tol) continue;
660 TopExp::Vertices(ET,U1,U2);
661 if ( U1.IsSame(V1)) U1 = U2;
662 TopTools_ListOfShape Tang2;
663 CenterAnalyse.TangentEdges(ET,U1,Tang2);
664 TopTools_ListIteratorOfListOfShape it2(Tang2);
665 for ( ; it2.More() ; it2.Next()) {
666 const TopoDS_Edge& ET2 = TopoDS::Edge(it2.Value());
667 if ( MapSF.IsBound(ET2)) {
668 TopoDS_Shape aLocalShape = MapSF(ET2).Generated(U1);
669 MapOnV.Add(TopoDS::Edge(aLocalShape));
670 // MapOnV.Add(TopoDS::Edge(MapSF(ET2).Generated(U1)));
677 // CenterAnalyse.Edges(V1f, OT, TangE);
678 if (CenterAnalyse.HasAncestor(V1)) {
679 TangE = CenterAnalyse.Ancestors(V1);
680 itl.Initialize(TangE);
681 for ( ; itl.More() && !Find; itl.Next()) {
682 if ( MapSF.IsBound(itl.Value())) {
683 MapOnV.Add(MapSF(itl.Value()).Generated(V1));
692 //=======================================================================
694 //purpose : Sets in increasing order the sequence of vertices.
695 //=======================================================================
697 static void Bubble(const TopoDS_Edge& E,
698 TopTools_SequenceOfShape& Seq)
700 Standard_Boolean Invert = Standard_True;
701 Standard_Integer NbPoints = Seq.Length();
706 Invert = Standard_False;
707 for ( Standard_Integer i = 1; i < NbPoints; i++) {
708 TopoDS_Shape aLocalShape = Seq.Value(i) .Oriented(TopAbs_INTERNAL);
709 V1 = TopoDS::Vertex(aLocalShape);
710 aLocalShape = Seq.Value(i+1).Oriented(TopAbs_INTERNAL);
711 V2 = TopoDS::Vertex(aLocalShape);
712 // V1 = TopoDS::Vertex(Seq.Value(i) .Oriented(TopAbs_INTERNAL));
713 // V2 = TopoDS::Vertex(Seq.Value(i+1).Oriented(TopAbs_INTERNAL));
715 U1 = BRep_Tool::Parameter(V1,E);
716 U2 = BRep_Tool::Parameter(V2,E);
719 Invert = Standard_True;
725 //=======================================================================
728 //=======================================================================
730 static void CutEdge (const TopoDS_Edge& E,
731 const TopTools_ListOfShape& VOnE,
732 TopTools_ListOfShape& NE )
734 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
735 TopoDS_Edge WE = TopoDS::Edge(aLocalShape);
736 // TopoDS_Edge WE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
740 TopTools_SequenceOfShape SV;
741 TopTools_ListIteratorOfListOfShape it(VOnE);
744 for ( ; it.More(); it.Next()) {
745 SV.Append(it.Value());
747 //--------------------------------
748 // Parse vertices on the edge.
749 //--------------------------------
752 Standard_Integer NbVer = SV.Length();
753 //----------------------------------------------------------------
754 // Construction of new edges.
755 // The vertices at the extremities of edges are not
756 // necessarily in the list of vertices
757 //----------------------------------------------------------------
764 BRep_Tool::Range(WE,f,l);
765 TopExp::Vertices(WE,VF,VL);
768 if (SV(1).IsEqual(VF) && SV(2).IsEqual(VL)) {
773 //----------------------------------------------------
774 // Processing of closed edges
775 // If a vertex of intersection is on the common vertex,
776 // it should appear at the beginning and the end of SV.
777 //----------------------------------------------------
780 if (!VF.IsNull() && !VF.IsSame(SV.First())) SV.Prepend(VF);
781 if (!VL.IsNull() && !VL.IsSame(SV.Last ())) SV.Append (VL);
783 V1 = TopoDS::Vertex(SV.First());
786 while (!SV.IsEmpty()) {
788 V2 = TopoDS::Vertex(SV.First());
791 if ( V1.IsSame(V2)) {
792 cout << "Vertex Confondus dans CutEdges" << endl;
795 //-------------------------------------------
796 // Copy the edge and restriction by V1 V2.
797 //-------------------------------------------
798 TopoDS_Shape aLocalShape =WE.EmptyCopied();
799 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
800 // TopoDS_Edge NewEdge = TopoDS::Edge(WE.EmptyCopied());
801 B.Add (NewEdge,V1.Oriented(TopAbs_FORWARD));
802 B.Add (NewEdge,V2.Oriented(TopAbs_REVERSED));
806 aLocalShape = V1.Oriented(TopAbs_INTERNAL);
807 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),WE);
808 // U1 = BRep_Tool::Parameter
809 // (TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),WE);
814 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
815 U2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),WE);
816 // U2 = BRep_Tool::Parameter
817 // (TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),WE);
819 B.Range (NewEdge,U1,U2);
820 NE.Append(NewEdge.Oriented(E.Orientation()));
825 //======================== END OF STATIC FUNCTIONS ============
830 //=======================================================================
831 //function : BiTgte_Blend
833 //=======================================================================
835 BiTgte_Blend::BiTgte_Blend()
837 myAsDes = new BRepAlgo_AsDes();
842 //=======================================================================
843 //function : BiTgte_Blend
845 //=======================================================================
847 BiTgte_Blend::BiTgte_Blend(const TopoDS_Shape& S,
848 const Standard_Real Radius,
849 const Standard_Real Tol,
850 const Standard_Boolean NUBS)
852 myAsDes = new BRepAlgo_AsDes();
853 Init(S,Radius,Tol,NUBS);
857 //=======================================================================
860 //=======================================================================
862 void BiTgte_Blend::Init(const TopoDS_Shape& S,
863 const Standard_Real Radius,
864 const Standard_Real Tol,
865 const Standard_Boolean NUBS)
873 // TopExp::MapShapesAndAncestors(S,TopAbs_EDGE,TopAbs_FACE,myAncestors);
877 //=======================================================================
880 //=======================================================================
882 void BiTgte_Blend::Clear()
884 myInitOffsetFace.Clear();
886 myImageOffset .Clear();
887 myStopFaces .Clear();
891 myDone = Standard_False;
895 //=======================================================================
896 //function : SetStoppingFace
898 //=======================================================================
900 void BiTgte_Blend::SetStoppingFace(const TopoDS_Face& Face)
902 myStopFaces.Add(Face);
904 // MAJ SD. -> To end loop, set faces of edges
906 // myInitOffsetFace.SetRoot(Face);
907 // myInitOffsetFace.Bind (Face,Face);
908 // myImageOffset.SetRoot (Face);
912 //=======================================================================
913 //function : SetFaces
915 //=======================================================================
917 void BiTgte_Blend::SetFaces(const TopoDS_Face& F1,const TopoDS_Face& F2)
924 //=======================================================================
927 //=======================================================================
929 void BiTgte_Blend::SetEdge(const TopoDS_Edge& Edge)
935 //=======================================================================
938 //=======================================================================
940 void BiTgte_Blend::Perform(const Standard_Boolean BuildShape)
942 myBuildShape = BuildShape;
944 // Try cutting to avoid tubes on free borders
945 // that are not actually free.
946 Handle(BRepBuilderAPI_Sewing) Sew = new BRepBuilderAPI_Sewing(myTol);
947 BRepLib::BuildCurves3d(myShape);
948 TopExp_Explorer expf(myShape,TopAbs_FACE);
949 for ( ;expf.More(); expf.Next()) Sew->Add(expf.Current());
951 TopoDS_Shape SewedShape = Sew->SewedShape();
952 if ( SewedShape.IsNull()) Standard_Failure::Raise("Sewing aux fraises");
954 // Check if the sewing modified the orientation.
955 expf.Init(myShape,TopAbs_FACE);
956 TopoDS_Face FaceRef = TopoDS::Face(expf.Current());
957 TopAbs_Orientation OriRef = FaceRef.Orientation();
958 if (Sew->IsModified(FaceRef)) FaceRef = TopoDS::Face(Sew->Modified(FaceRef));
959 expf.Init(SewedShape, TopAbs_FACE);
960 for (; expf.More(); expf.Next()) {
961 const TopoDS_Face& FF = TopoDS::Face(expf.Current());
962 if (FaceRef.IsSame(FF) && (FF.Orientation() != OriRef)) {
963 SewedShape.Reverse();
968 // Make SameParameter if Sew does not do it (Detect that edges
969 // are not sameparameter but it does nothing.)
970 expf.Init(SewedShape, TopAbs_EDGE);
971 for (; expf.More(); expf.Next()) {
972 const TopoDS_Edge& sec = TopoDS::Edge(expf.Current());
973 BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
976 TopExp::MapShapesAndAncestors
977 (SewedShape,TopAbs_EDGE,TopAbs_FACE,myAncestors);
979 // Extend myFaces with the faces of the sewed shape.
980 expf.Init(myShape,TopAbs_FACE);
981 for ( ; expf.More(); expf.Next()) {
982 const TopoDS_Shape& F = expf.Current();
983 if ( myFaces.Contains(F) && Sew->IsModified(F)) {
985 TopoDS_Shape LastFace = myFaces(myFaces.Extent());
986 myFaces.RemoveLast();
987 if (myFaces.FindIndex(F) != 0)
988 myFaces.Substitute(myFaces.FindIndex(F), LastFace);
990 myFaces.Add(Sew->Modified(F));
994 myShape = SewedShape;
995 // end Sewing for false free borders.
998 OSD_Chronometer cl_total, ch;
999 Standard_Real t_total, t_center, t_surface, t_shape;
1001 t_total=0; t_center=0; t_surface=0; t_mkcurve=0; t_shape=0;
1002 ChFi3d_InitChron(cl_total);
1005 // ----------------------------------------------------------------
1006 // place faces with the proper orientation in the initial shape
1007 // ----------------------------------------------------------------
1008 TopExp_Explorer exp(myShape,TopAbs_FACE);
1009 for ( ; exp.More(); exp.Next()) {
1010 const TopoDS_Shape& F = exp.Current();
1011 if ( myFaces.Contains(F)) {
1012 //myFaces.Remove(F);
1013 TopoDS_Shape LastFace = myFaces(myFaces.Extent());
1014 myFaces.RemoveLast();
1015 if (myFaces.FindIndex(F) != 0)
1016 myFaces.Substitute(myFaces.FindIndex(F), LastFace);
1017 ////////////////////
1020 else if ( myStopFaces.Contains(F)) {
1021 myStopFaces.Remove(F);
1026 // ----------------------------------------------
1027 // Calculate lines of centers and of surfaces
1028 // ----------------------------------------------
1030 ChFi3d_InitChron(ch);
1036 ChFi3d_ResultChron(ch, t_center);
1039 // -----------------------------
1040 // Calculate connection Surfaces
1041 // -----------------------------
1043 ChFi3d_InitChron(ch);
1049 ChFi3d_ResultChron(ch, t_surface);
1052 // ----------------------------------
1053 // Calculate the generated shape if required
1054 // ----------------------------------
1056 ChFi3d_InitChron(ch);
1059 if ( myBuildShape) ComputeShape();
1062 ChFi3d_ResultChron(ch, t_shape);
1065 // Finally construct curves 3d from edges to be transfered
1066 // since the partition is provided ( A Priori);
1067 BRepLib::BuildCurves3d(myResult, Precision::Confusion());
1070 ChFi3d_ResultChron(cl_total, t_total);
1072 cout<<"Blend_PERFORM: temps total "<<t_total<<" s dont :"<<endl;
1073 cout<<"- ComputeCenters "<<t_center<<" s"<<endl;
1074 cout<<"- ComputeSurfaces "<<t_surface<<" s"<<endl;
1075 cout<<"----> MakeCurve "<<t_mkcurve<<" s"<<endl;
1076 if ( myBuildShape) cout<<"- ComputeShape "<<t_shape<<" s"<<endl;
1079 myDone = Standard_True;
1083 //=======================================================================
1086 //=======================================================================
1088 Standard_Boolean BiTgte_Blend::IsDone() const
1093 //=======================================================================
1096 //=======================================================================
1098 const TopoDS_Shape& BiTgte_Blend::Shape() const
1104 //=======================================================================
1105 //function : NbSurfaces
1107 //=======================================================================
1109 Standard_Integer BiTgte_Blend::NbSurfaces() const
1111 return myCenters.Extent();
1115 //=======================================================================
1116 //function : Surface
1118 //=======================================================================
1120 Handle(Geom_Surface) BiTgte_Blend::Surface(const Standard_Integer Index) const
1122 return Surface(myCenters(Index));
1125 //=======================================================================
1126 //function : TopoDS_Face&
1128 //=======================================================================
1130 const TopoDS_Face& BiTgte_Blend::Face(const Standard_Integer Index) const
1132 return Face(myCenters(Index));
1137 //=======================================================================
1138 //function : CenterLines
1140 //=======================================================================
1142 void BiTgte_Blend::CenterLines(TopTools_ListOfShape& LC) const
1145 Standard_Integer Nb = NbSurfaces();
1146 for ( Standard_Integer i = 1; i <= Nb; i++)
1147 LC.Append(myCenters(i));
1151 //=======================================================================
1152 //function : Surface
1154 //=======================================================================
1156 Handle(Geom_Surface) BiTgte_Blend::Surface(const TopoDS_Shape& CenterLine)
1159 const TopoDS_Face& F = myMapSF(CenterLine).Face();
1160 return BRep_Tool::Surface(F);
1163 //=======================================================================
1164 //function : TopoDS_Face&
1166 //=======================================================================
1168 const TopoDS_Face& BiTgte_Blend::Face(const TopoDS_Shape& CenterLine) const
1170 if ( !myMapSF.IsBound(CenterLine)) {
1171 Standard_DomainError::Raise("BiTgte_Blend::Face");
1174 return myMapSF(CenterLine).Face();
1177 //=======================================================================
1178 //function : ContactType
1180 //=======================================================================
1182 BiTgte_ContactType BiTgte_Blend::ContactType(const Standard_Integer Index)
1185 const TopoDS_Shape& S1 = SupportShape1(Index);
1186 const TopoDS_Shape& S2 = SupportShape2(Index);
1188 TopAbs_ShapeEnum Type1 = S1.ShapeType();
1189 TopAbs_ShapeEnum Type2 = S2.ShapeType();
1191 if (Type2 < Type1) {
1192 TopAbs_ShapeEnum Dummy = Type1;
1196 BiTgte_ContactType Type = BiTgte_VertexVertex;
1202 case TopAbs_VERTEX: Type = BiTgte_VertexVertex; break;
1203 case TopAbs_EDGE: Type = BiTgte_EdgeVertex; break;
1204 case TopAbs_FACE: Type = BiTgte_FaceVertex; break;
1211 case TopAbs_EDGE: Type = BiTgte_EdgeEdge; break;
1212 case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
1219 case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
1232 //=======================================================================
1233 //function : SupportShape1
1235 //=======================================================================
1237 const TopoDS_Shape& BiTgte_Blend::SupportShape1(const Standard_Integer Index)
1240 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1242 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1244 // --------------------------------------------------------------
1245 // F1 and F2 = 2 parallel faces intersecting at CurE.
1246 // --------------------------------------------------------------
1247 const TopoDS_Face& F1 = TopoDS::Face(L.First());
1248 const TopoDS_Shape& Or1 = myInitOffsetFace.ImageFrom(F1);
1253 //=======================================================================
1254 //function : SupportShape2
1256 //=======================================================================
1258 const TopoDS_Shape& BiTgte_Blend::SupportShape2(const Standard_Integer Index)
1261 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1263 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1265 // --------------------------------------------------------------
1266 // F1 and F2 = 2 parallel faces intersecting at CurE.
1267 // --------------------------------------------------------------
1268 const TopoDS_Face& F2 = TopoDS::Face(L.Last());
1269 const TopoDS_Shape& Or2 = myInitOffsetFace.ImageFrom(F2);
1274 //=======================================================================
1275 //function : CurveOnShape1
1277 //=======================================================================
1279 Handle(Geom_Curve) BiTgte_Blend::CurveOnShape1
1280 (const Standard_Integer Index) const
1282 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1283 const TopoDS_Shape& F = myMapSF(CurE).Face();
1285 // somewhat brutal method based ONLY on the construction of the fillet:
1286 // the first edge of the tube is exactly the edge on Shape1.
1288 TopExp_Explorer exp(F,TopAbs_EDGE);
1289 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1290 Handle(Geom_Curve) C;
1291 if ( !BRep_Tool::Degenerated(E)) {
1293 C = BRep_Tool::Curve(E,f,l);
1294 C = new Geom_TrimmedCurve(C,f,l);
1300 //=======================================================================
1301 //function : CurveOnShape2
1303 //=======================================================================
1305 Handle(Geom_Curve) BiTgte_Blend::CurveOnShape2
1306 (const Standard_Integer Index) const
1308 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1309 const TopoDS_Shape& F = myMapSF(CurE).Face();
1311 // somewhat brutal method based ONLY on the construction of the fillet:
1312 // the first edge of the tube is exactly the edge on Shape2.
1314 TopExp_Explorer exp(F,TopAbs_EDGE);
1316 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1317 Handle(Geom_Curve) C;
1318 if ( !BRep_Tool::Degenerated(E)) {
1320 C = BRep_Tool::Curve(E,f,l);
1321 C = new Geom_TrimmedCurve(C,f,l);
1327 //=======================================================================
1328 //function : PCurveOnFace1
1330 //=======================================================================
1332 Handle(Geom2d_Curve) BiTgte_Blend::PCurveOnFace1
1333 (const Standard_Integer /*Index*/) const
1335 Handle(Geom2d_Curve) C;
1340 //=======================================================================
1341 //function : PCurve1OnFillet
1343 //=======================================================================
1345 Handle(Geom2d_Curve) BiTgte_Blend::PCurve1OnFillet
1346 (const Standard_Integer /*Index*/) const
1348 Handle(Geom2d_Curve) C;
1353 //=======================================================================
1354 //function : PCurveOnFace2
1356 //=======================================================================
1358 Handle(Geom2d_Curve) BiTgte_Blend::PCurveOnFace2
1359 (const Standard_Integer /*Index*/) const
1361 Handle(Geom2d_Curve) C;
1366 //=======================================================================
1367 //function : Curve2OnFillet
1369 //=======================================================================
1371 Handle(Geom2d_Curve) BiTgte_Blend::PCurve2OnFillet
1372 (const Standard_Integer /*Index*/) const
1374 Handle(Geom2d_Curve) C;
1380 //=======================================================================
1381 //function : NbBranches
1383 //=======================================================================
1385 Standard_Integer BiTgte_Blend::NbBranches()
1387 if (myNbBranches != -1) return myNbBranches;
1389 // else, compute the Branches.
1390 BRepTools_Quilt Glue;
1392 Standard_Integer NbFaces = myCenters.Extent();
1395 if (NbFaces == 0) return 0;
1399 for ( i = 1; i <= NbFaces; i++) {
1400 const TopoDS_Shape& CenterLine = myCenters(i);
1401 Glue.Add(myMapSF(CenterLine).Face());
1404 const TopoDS_Shape Shells = Glue.Shells();
1407 // Reorder Map myCenters.
1408 // The method is brutal and unpolished,
1409 // it is possible to refine it.
1411 TopTools_IndexedMapOfShape tmpMap;
1413 TopExp_Explorer exp(Shells,TopAbs_SHELL);
1414 for (; exp.More(); exp.Next()) {
1418 myIndices = new TColStd_HArray1OfInteger(1,myNbBranches+1);
1420 myIndices->SetValue(1,0);
1421 Standard_Integer Count = 0;
1422 Standard_Integer Index = 2;
1425 exp.Init(Shells,TopAbs_SHELL);
1426 for (; exp.More(); exp.Next()) {
1427 // CurS = the current Shell.
1428 const TopoDS_Shape CurS = exp.Current();
1430 TopExp_Explorer exp2(CurS, TopAbs_FACE);
1431 for (; exp2.More(); exp2.Next()) {
1432 // CurF = the current face of the current Shell.
1433 const TopoDS_Shape CurF = exp2.Current();
1435 for ( i = 1; i <= NbFaces; i++) {
1436 const TopoDS_Shape& Center = myCenters(i);
1437 const TopoDS_Shape& Rakk = myMapSF(Center).Face();
1438 // Rakk = the ith generated connection face
1439 if (CurF.IsEqual(Rakk)) {
1446 myIndices->SetValue(Index, Count);
1451 return myNbBranches;
1455 //=======================================================================
1456 //function : IndicesOfBranche
1458 //=======================================================================
1460 void BiTgte_Blend::IndicesOfBranche
1461 (const Standard_Integer Index,
1462 Standard_Integer& From,
1463 Standard_Integer& To ) const
1465 // Attention to the ranking in myIndices:
1466 // If the branches are 1-4 5-9 10-12, it is ranked in myIndices:
1468 From = myIndices->Value(Index) + 1;
1469 To = myIndices->Value(Index + 1);
1473 //=======================================================================
1474 //function : ComputeCenters
1476 //=======================================================================
1478 void BiTgte_Blend::ComputeCenters()
1483 Standard_Real TolAngle = 2*ASin(myTol/Abs(myRadius*0.5));
1484 myAnalyse.Perform(myShape,TolAngle);
1486 // ------------------------------------------
1487 // calculate faces touched by caps
1488 // ------------------------------------------
1489 TopTools_MapOfShape TouchedByCork;
1490 Touched(myAnalyse, myStopFaces, myShape, TouchedByCork);
1492 // -----------------------
1493 // init of the intersector
1494 // -----------------------
1495 TopAbs_State Side = TopAbs_IN;
1496 if (myRadius < 0.) Side = TopAbs_OUT;
1497 BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
1499 BiTgte_DataMapOfShapeBox MapSBox;
1500 TopTools_MapOfShape Done;
1501 //TopTools_MapIteratorOfMapOfShape it;
1504 TopoDS_Compound Co; // to only know on which edges the tubes are made
1507 // ----------------------------------------
1508 // Calculate Sections Face/Face + Propagation
1509 // ----------------------------------------
1510 Standard_Boolean JenRajoute = Standard_True;
1513 while ( JenRajoute) {
1514 JenRajoute = Standard_False;
1516 Standard_Boolean Fini = Standard_False;
1518 TopTools_DataMapOfShapeShape EdgeTgt;
1522 // -------------------------------------------------
1523 // locate in myFaces the Faces connected to myEdges.
1524 // -------------------------------------------------
1525 Fini = Standard_True;
1526 //for (it.Initialize(myEdges); it.More(); it.Next()) {
1527 for (i = 1; i <= myEdges.Extent(); i++) {
1528 const TopoDS_Edge& E = TopoDS::Edge(myEdges(i));
1529 if (BRep_Tool::Degenerated(E)) continue;
1531 const TopTools_ListOfShape& L = myAncestors.FindFromKey(E);
1532 if ( L.Extent() == 1) {
1533 // So this is a free border onwhich the ball should roll.
1536 // set in myStopFaces to not propagate the tube on free border.
1540 TopTools_ListIteratorOfListOfShape itl;
1541 for (itl.Initialize(L); itl.More(); itl.Next()) {
1542 const TopoDS_Shape& Sh = itl.Value();
1543 if ( !myStopFaces.Contains(Sh)) myFaces.Add(itl.Value());
1549 // --------------------------------------------
1550 // Construction of Offsets of all faces.
1551 // --------------------------------------------
1552 //for (it.Initialize(myFaces); it.More(); it.Next()) {
1553 for (i = 1; i <= myFaces.Extent(); i++) {
1554 const TopoDS_Shape& AS = myFaces(i);
1555 if ( myMapSF.IsBound(AS)) continue;
1557 BRepOffset_Offset OF1;
1560 if (AS.ShapeType() == TopAbs_FACE) {
1561 const TopoDS_Face& F = TopoDS::Face(myFaces(i));
1562 if ( TouchedByCork.Contains(F)) {
1563 BRepOffset_Tool::EnLargeFace(F,BigF,Standard_True);
1564 OF1.Init(BigF,myRadius,EdgeTgt);
1567 OF1.Init(F,myRadius,EdgeTgt);
1570 else { // So this is a Free Border edge on which the ball rolls.
1571 OF1.Init(TopoDS::Edge(AS),myRadius);
1574 // ------------------------------------
1575 // Increment the map of created tangents
1576 // ------------------------------------
1577 TopTools_ListOfShape Let;
1578 if ( AS.ShapeType() == TopAbs_FACE) {
1579 myAnalyse.Edges(TopoDS::Face(AS),BRepOffset_Tangent,Let);
1581 TopTools_ListIteratorOfListOfShape itlet(Let);
1583 for ( ; itlet.More(); itlet.Next()) {
1584 const TopoDS_Edge& Cur = TopoDS::Edge(itlet.Value());
1585 if ( !EdgeTgt.IsBound(Cur)) {
1586 TopoDS_Shape aLocalShape = OF1.Generated(Cur);
1587 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
1588 // const TopoDS_Edge& OTE = TopoDS::Edge(OF1.Generated(Cur));
1589 EdgeTgt.Bind(Cur,OF1.Generated(Cur));
1590 TopoDS_Vertex V1,V2,OV1,OV2;
1591 TopExp::Vertices (Cur,V1,V2);
1592 TopExp::Vertices (OTE,OV1,OV2);
1593 TopTools_ListOfShape LE;
1594 if (!EdgeTgt.IsBound(V1)) {
1595 myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
1596 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V1);
1597 if (LE.Extent() == LA.Extent())
1598 EdgeTgt.Bind(V1,OV1);
1600 if (!EdgeTgt.IsBound(V2)) {
1602 myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
1603 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V2);
1604 if (LE.Extent() == LA.Extent())
1605 EdgeTgt.Bind(V2,OV2);
1609 // end of map created tangent
1611 if (OF1.Status() == BRepOffset_Reversed ||
1612 OF1.Status() == BRepOffset_Degenerated ) continue;
1614 const TopoDS_Face& F1 = OF1.Face();
1617 myInitOffsetFace.SetRoot(AS);
1618 myInitOffsetFace.Bind(AS,F1);
1621 BRepBndLib::Add(F1,Box1);
1622 MapSBox.Bind(F1,Box1);
1624 // ---------------------------------------------
1625 // intersection with all already created faces.
1626 // ---------------------------------------------
1627 Fini = !Intersect(AS,F1,MapSBox,OF1,Inter);
1629 if (AS.ShapeType() == TopAbs_FACE) B.Add(Co,AS);
1631 myMapSF.Bind(AS, OF1);
1634 } // end of : while ( !Fini)
1637 //--------------------------------------------------------
1638 // so the offsets were created and intersected.
1639 // now the tubes are constructed.
1640 //--------------------------------------------------------
1641 // Construction of tubes on edge.
1642 //--------------------------------------------------------
1643 BRepOffset_Type OT = BRepOffset_Convex;
1644 if (myRadius < 0.) OT = BRepOffset_Concave;
1646 TopTools_IndexedDataMapOfShapeListOfShape Map;
1647 TopExp::MapShapesAndAncestors(Co,TopAbs_EDGE,TopAbs_FACE,Map);
1648 TopExp::MapShapesAndAncestors(Co,TopAbs_VERTEX,TopAbs_EDGE,Map);
1650 TopExp_Explorer exp(Co,TopAbs_EDGE);
1651 for ( ; exp.More(); exp.Next()) {
1652 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1653 if ( myMapSF.IsBound(E)) continue;
1655 const TopTools_ListOfShape& Anc = Map.FindFromKey(E);
1656 if (Anc.Extent() == 2) {
1657 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1658 if (!L.IsEmpty() && L.First().Type() == OT) {
1659 TopoDS_Shape aLocalShape = myMapSF(Anc.First()).Generated(E);
1660 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1661 aLocalShape = myMapSF(Anc.Last()) .Generated(E);
1662 TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
1663 // TopoDS_Edge EOn1 = TopoDS::Edge(myMapSF(Anc.First()).Generated(E));
1664 // TopoDS_Edge EOn2 = TopoDS::Edge(myMapSF(Anc.Last()) .Generated(E));
1665 // find if exits tangent edges in the original shape
1666 TopoDS_Edge E1f, E1l;
1667 TopoDS_Vertex V1f, V1l;
1668 TopExp::Vertices(E,V1f,V1l);
1669 TopTools_ListOfShape TangE;
1670 myAnalyse.TangentEdges(E,V1f,TangE);
1671 // find if the pipe on the tangent edges are soon created.
1672 TopTools_ListIteratorOfListOfShape itl(TangE);
1673 Standard_Boolean Find = Standard_False;
1674 for ( ; itl.More() && !Find; itl.Next()) {
1675 if ( myMapSF.IsBound(itl.Value())) {
1676 TopoDS_Shape aLocalShape = myMapSF(itl.Value()).Generated(V1f);
1677 E1f = TopoDS::Edge(aLocalShape);
1678 // E1f = TopoDS::Edge(myMapSF(itl.Value()).Generated(V1f));
1679 Find = Standard_True;
1683 myAnalyse.TangentEdges(E,V1l,TangE);
1684 // find if the pipe on the tangent edges are soon created.
1685 itl.Initialize(TangE);
1686 Find = Standard_False;
1687 for ( ; itl.More() && !Find; itl.Next()) {
1688 if ( myMapSF.IsBound(itl.Value())) {
1689 TopoDS_Shape aLocalShape = myMapSF(itl.Value()).Generated(V1l);
1690 E1l = TopoDS::Edge(aLocalShape);
1691 // E1l = TopoDS::Edge(myMapSF(itl.Value()).Generated(V1l));
1692 Find = Standard_True;
1695 BRepOffset_Offset OF1 (E,EOn1,EOn2,myRadius,E1f, E1l);
1696 const TopoDS_Face& F1 = OF1.Face();
1699 myInitOffsetFace.SetRoot(E);
1700 myInitOffsetFace.Bind(E,F1);
1703 BRepBndLib::Add(F1,Box1);
1704 MapSBox.Bind(F1,Box1);
1706 // ---------------------------------------------
1707 // intersection with all already created faces.
1708 // ---------------------------------------------
1709 Standard_Boolean IsOnRest = Intersect(E,F1,MapSBox,OF1,Inter);
1710 JenRajoute = JenRajoute || IsOnRest;
1712 myMapSF.Bind(E,OF1);
1717 } // end while JenRajoute
1721 myEdges = Inter.NewEdges();
1723 // -------------------------------------------------------------------
1724 // now it is necessary to limit edges on the neighbors (otherwise one
1725 // will go too far and will not be able to construct faces).
1726 // -------------------------------------------------------------------
1728 // Proceed with MakeLoops
1730 BRepOffset_Type OT = BRepOffset_Concave;
1731 if (myRadius < 0.) OT = BRepOffset_Convex;
1733 TopTools_ListOfShape LOF;
1734 //it.Initialize(myFaces);
1735 for (i = 1; i <= myFaces.Extent(); i++) {
1736 const TopoDS_Shape& CurS = myFaces(i);
1738 // tube on free border, it is undesirable.
1739 if ( myStopFaces.Contains(CurS)) continue;
1741 if ( !myMapSF.IsBound(CurS)) continue; // inverted or degenerated
1743 const TopoDS_Face& CurOF = myMapSF(CurS).Face();
1746 if (CurS.ShapeType() == TopAbs_FACE) {
1747 const TopoDS_Face& CurF = TopoDS::Face(CurS);
1748 TopExp_Explorer expe(CurF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1749 for (; expe.More(); expe.Next()) {
1750 // --------------------------------------------------------------
1751 // set in myAsDes the edges generated by limitations of the
1752 // initial square if the type is correct (The edges that will
1753 // disappear are not set)
1754 // --------------------------------------------------------------
1755 const TopoDS_Edge& CurE = TopoDS::Edge(expe.Current());
1756 const BRepOffset_ListOfInterval& L = myAnalyse.Type(CurE);
1757 if (!L.IsEmpty() && L.First().Type() != OT) {
1758 // a priori doe s not disappear, so it is set
1759 TopoDS_Shape aLocalShape = myMapSF(CurF).Generated(CurE);
1760 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
1761 // const TopoDS_Edge& CurOE =
1762 // TopoDS::Edge(myMapSF(CurF).Generated(CurE));
1763 myAsDes->Add(CurOF,CurOE.Oriented(CurE.Orientation()));
1766 const TopTools_ListOfShape& Lanc = myAnalyse.Ancestors(CurE);
1767 if ( !myFaces .Contains(Lanc.First())
1768 || !myFaces .Contains(Lanc.Last ())
1769 || myStopFaces.Contains(Lanc.First())
1770 || myStopFaces.Contains(Lanc.Last ())) {
1771 TopoDS_Shape aLocalShape = myMapSF(CurF).Generated(CurE);
1772 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
1773 // const TopoDS_Edge& CurOE =
1774 // TopoDS::Edge(myMapSF(CurF).Generated(CurE));
1775 myAsDes->Add(CurOF,CurOE.Oriented(CurE.Orientation()));
1779 BRepOffset_Inter2d::Compute(myAsDes,
1786 // ----------------------------------------------------------------
1787 // It is also required to make 2D intersections with generated tubes
1788 // (Useful for unwinding)
1789 // ----------------------------------------------------------------
1790 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(myMapSF);
1791 for ( ; It.More(); It.Next()) {
1792 const TopoDS_Shape& CurS = It.Key();
1793 if ( CurS.ShapeType() == TopAbs_FACE) continue;
1795 const TopoDS_Face& CurOF = It.Value().Face();
1797 // no unwinding by tubes on free border.
1798 if ( myStopFaces.Contains(CurS)) continue;
1802 // --------------------------------------------------------------
1803 // set in myAsDes the edge restrictions of the square
1804 // --------------------------------------------------------------
1805 TopExp_Explorer expe(CurOF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1806 for (; expe.More(); expe.Next()) {
1807 const TopoDS_Edge& CurOE = TopoDS::Edge(expe.Current());
1808 myAsDes->Add(CurOF,CurOE);
1811 BRepOffset_Inter2d::Compute(myAsDes,
1819 BRepOffset_MakeLoops MakeLoops;
1820 MakeLoops.Build( LOF, myAsDes, myImageOffset );
1822 // ------------------------------------------------------------
1823 // It is possible to unwind edges at least one ancestor which of
1824 // is a face of the initial shape, so:
1825 // the edges generated by intersection tube-tube are missing
1826 // ------------------------------------------------------------
1828 // --------------------------------------------------------------
1829 // Currently set the unwinded surfaces in <myResult>
1830 // --------------------------------------------------------------
1831 B.MakeCompound(TopoDS::Compound(myResult));
1832 TopTools_ListIteratorOfListOfShape itLOF(LOF);
1833 for ( ; itLOF.More(); itLOF.Next()) {
1834 const TopoDS_Shape& CurLOF = itLOF.Value();
1836 if ( !myImageOffset.HasImage(CurLOF))
1839 TopTools_ListOfShape Lim;
1840 myImageOffset.LastImage(CurLOF,Lim);
1841 TopTools_ListIteratorOfListOfShape itLim(Lim);
1842 for ( ;itLim.More(); itLim.Next()) {
1843 // If a face is its own image, it is not set
1844 const TopoDS_Shape& CurLIM = itLim.Value();
1845 if (CurLIM.IsSame(CurLOF)) break;
1847 B.Add(myResult,CurLIM);
1852 if ( myResult.IsNull()) {
1853 cout << " No Lines of Generated Centers" << endl;
1857 if (Affich) DBRep::Set("Unwind",myResult);
1864 //=======================================================================
1865 //function : ComputeSurfaces
1867 //=======================================================================
1869 void BiTgte_Blend::ComputeSurfaces()
1871 // set in myFaces, the faces actually implied in the connection
1875 // 1 - Tubes (True Fillets)
1879 Standard_Integer nbc = 1;
1882 TopTools_ListOfShape Empty;
1883 TopTools_DataMapOfShapeListOfShape EmptyMap;
1885 Handle(Geom_Surface) GS1, GS2;
1886 Handle(Geom_Curve) GC1, GC2;
1888 Standard_Real TolAngle = 2*ASin(myTol/Abs(myRadius*0.5));
1889 BRepOffset_Analyse CenterAnalyse(myResult,TolAngle);
1891 // -----------------------------------------------------
1892 // Construction of tubes in myResult
1893 // -----------------------------------------------------
1895 B.MakeCompound(TopoDS::Compound(myResult));
1897 // --------------------------------------------------------------------
1898 // Dummy: for construction of spheres:
1899 // Set in Co the center line, then it there are at least 3
1900 // center lines sharing the same vertex, Sphere on this vertex.
1901 // --------------------------------------------------------------------
1905 // --------------------------------------------------------------------
1906 // Iteration on the edges lines of center
1907 // and their valid valid part is taken after cut and tube construction.
1908 // --------------------------------------------------------------------
1910 //TopTools_MapIteratorOfMapOfShape ic(myEdges);
1912 for (i = 1; i <= myEdges.Extent(); i++) {
1913 const TopoDS_Edge& CurE = TopoDS::Edge(myEdges(i));
1915 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1916 if ( L.Extent() != 2) continue;
1918 // --------------------------------------------------------------
1919 // F1 and F2 = 2 parallel faces intersecting in CurE.
1920 // --------------------------------------------------------------
1921 const TopoDS_Face& F1 = TopoDS::Face(L.First());
1922 const TopoDS_Face& F2 = TopoDS::Face(L.Last());
1924 // -----------------------------------------------------
1925 // find the orientation of edges of intersection
1926 // in the initial faces.
1927 // -----------------------------------------------------
1928 const TopTools_ListOfShape& LD1 = myAsDes->Descendant(F1);
1929 const TopTools_ListOfShape& LD2 = myAsDes->Descendant(F2);
1931 TopAbs_Orientation Orien1 = Orientation(CurE, F1, LD1);
1932 TopAbs_Orientation Orien2 = Orientation(CurE, F2, LD2);
1934 // ---------------------------------------------------------
1935 // Or1 and Or2 : the shapes generators of parallel faces
1936 // ---------------------------------------------------------
1937 const TopoDS_Shape& Or1 = myInitOffsetFace.ImageFrom(F1);
1938 const TopoDS_Shape& Or2 = myInitOffsetFace.ImageFrom(F2);
1943 TopoDS_Edge OE1, OE2;
1944 TopoDS_Face OF1, OF2;
1945 TopLoc_Location Loc;
1946 Standard_Real f1,l1,f2,l2;
1948 Standard_Boolean OF1isEdge = Standard_False;
1950 if ( Or1.ShapeType() == TopAbs_EDGE) {
1951 OF1isEdge = Standard_True;
1952 OE1 = TopoDS::Edge(Or1);
1953 GC1 = BRep_Tool::Curve(OE1,Loc,f1,l1);
1955 Handle(Geom_Curve)::DownCast(GC1->Transformed(Loc.Transformation()));
1957 else if ( Or1.ShapeType() == TopAbs_FACE) {
1958 OF1 = TopoDS::Face(Or1);
1959 GS1 = BRep_Tool::Surface(OF1);
1962 // ----------------------------------------------------------------
1963 // If a vertex is used in contact, currently nothing is done
1964 // and the vertexes are not managed (Intersections with sphere);
1965 // ----------------------------------------------------------------
1966 if ( OF1.IsNull() && OE1.IsNull()) continue;
1968 Standard_Boolean OF2isEdge = Standard_False;
1970 if ( Or2.ShapeType() == TopAbs_EDGE) {
1971 OF2isEdge = Standard_True;
1972 OE2 = TopoDS::Edge(Or2);
1973 GC2 = BRep_Tool::Curve(OE2,Loc,f2,l2);
1975 Handle(Geom_Curve)::
1976 DownCast(GC2->Transformed(Loc.Transformation()));
1978 else if ( Or2.ShapeType() == TopAbs_FACE) {
1979 OF2 = TopoDS::Face(Or2);
1980 GS2 = BRep_Tool::Surface(OF2);
1982 // ----------------------------------------------------------------
1983 // If a vertex is used in contact, currently nothing is done
1984 // and the vertexes are not managed (Intersections with sphere);
1985 // ----------------------------------------------------------------
1986 if ( OF2.IsNull() && OE2.IsNull()) continue;
1989 TopTools_ListOfShape CurL;
1991 if ( !myImageOffset.HasImage(CurE)) {// the tubes are not unwinded
1992 if ( OF1isEdge && OF2isEdge) { // if I don't have the image, possibly
1993 CurL.Append(CurE); // I'm on intersection tube-tube
1994 } // See comment on the call to
1999 myImageOffset.LastImage(CurE,CurL);
2002 // ---------------------------------------------------------------
2003 // CurL = List of edges descending from CurE ( = Cuts of CurE)
2004 // ---------------------------------------------------------------
2005 TopTools_ListIteratorOfListOfShape itl(CurL);
2006 for ( ; itl.More(); itl.Next()) {
2007 const TopoDS_Edge& CurCutE = TopoDS::Edge(itl.Value());
2009 Handle(Geom2d_Curve) PC1 =
2010 BRep_Tool::CurveOnSurface(CurCutE,F1,f1,l1);
2011 Handle(Geom2d_Curve) PC2 =
2012 BRep_Tool::CurveOnSurface(CurCutE,F2,f2,l2);
2013 if ( PC1.IsNull() || PC2.IsNull()) {
2015 cout << "No PCurves on Intersections : No tubes constructed";
2021 TopoDS_Edge E1f, E1l;
2022 TopoDS_Vertex V1f, V1l;
2023 TopoDS_Vertex VfOnE1,VlOnE1,VfOnE2,VlOnE2;
2024 TopTools_ListOfShape TangE;
2025 TopTools_MapOfShape MapOnV1f, MapOnV1l;
2027 TopExp::Vertices(CurCutE,V1f,V1l);
2029 // find if the pipe on the tangent edges are soon created.
2030 // edges generated by V1f and V1l + Maj MapOnV1f/l
2031 E1f = FindCreatedEdge(V1f,CurCutE,myMapSF,MapOnV1f,
2032 CenterAnalyse,myRadius,myTol);
2034 E1l = FindCreatedEdge(V1l,CurCutE,myMapSF,MapOnV1l,
2035 CenterAnalyse,myRadius,myTol);
2039 BiTgte_CurveOnEdge ConE(CurCutE, OE1);
2040 Handle(Geom_Curve) C = MakeCurve(ConE);
2041 gp_Pnt P1 = C->Value(C->FirstParameter());
2042 gp_Pnt P2 = C->Value(C->LastParameter());
2043 VfOnE1 = FindVertex(P1,MapOnV1f,myTol);
2044 if ( VfOnE1.IsNull())
2045 VfOnE1 = FindVertex(P1,MapOnV1l,myTol);
2046 VlOnE1 = FindVertex(P2,MapOnV1l,myTol);
2047 if ( VlOnE1.IsNull())
2048 VlOnE1 = FindVertex(P2,MapOnV1f,myTol);
2049 if ( P1.SquareDistance(P2) < myTol*myTol) {
2050 //BRepOffset_Offset manages degenerated KPart
2051 //It is REQUIRED that C should be a circle with ZERO radius
2052 E1 = MakeDegeneratedEdge(C,VfOnE1);
2055 E1 = BRepLib_MakeEdge(C,VfOnE1,VlOnE1);
2060 P2d = PC1->Value(f1);
2061 gp_Pnt P1 = GS1->Value(P2d.X(),P2d.Y());
2062 P2d = PC1->Value(l1);
2063 gp_Pnt P2 = GS1->Value(P2d.X(),P2d.Y());
2064 VfOnE1 = FindVertex(P1,MapOnV1f,myTol);
2065 VlOnE1 = FindVertex(P2,MapOnV1l,myTol);
2066 BRepLib_MakeEdge MKE(PC1,GS1,VfOnE1,VlOnE1,f1,l1);
2070 cout << "Edge Not Done" << endl;
2074 KPartCurve3d(E1,PC1,GS1);
2078 BiTgte_CurveOnEdge ConE(CurCutE, OE2);
2079 Handle(Geom_Curve) C = MakeCurve(ConE);
2080 gp_Pnt P1 = C->Value(C->FirstParameter());
2081 gp_Pnt P2 = C->Value(C->LastParameter());
2082 VfOnE2 = FindVertex(P1,MapOnV1f,myTol);
2083 if ( VfOnE2.IsNull())
2084 VfOnE2 = FindVertex(P1,MapOnV1l,myTol);
2085 VlOnE2 = FindVertex(P2,MapOnV1l,myTol);
2086 if ( VlOnE2.IsNull())
2087 VlOnE2 = FindVertex(P2,MapOnV1f,myTol);
2088 if ( P1.SquareDistance(P2) < myTol*myTol) {
2089 //BRepOffset_Offset manages degenerated KParts
2090 //It is REQUIRED that C should be a circle with ZERO radius
2091 E2 = MakeDegeneratedEdge(C,VfOnE2);
2094 E2 = BRepLib_MakeEdge(C,VfOnE2,VlOnE2);
2099 P2d = PC2->Value(f2);
2100 gp_Pnt P1 = GS2->Value(P2d.X(),P2d.Y());
2101 P2d = PC2->Value(l2);
2102 gp_Pnt P2 = GS2->Value(P2d.X(),P2d.Y());
2103 VfOnE2 = FindVertex(P1,MapOnV1f,myTol);
2104 VlOnE2 = FindVertex(P2,MapOnV1l,myTol);
2105 BRepLib_MakeEdge MKE(PC2,GS2,VfOnE2,VlOnE2,f2,l2);
2109 cout << "edge not Done" << endl;
2112 KPartCurve3d(E2,PC2,GS2);
2114 // Increment of the Map of Created if reconstruction of the Shape is required
2115 if ( myBuildShape) {
2116 myCreated.Bind(CurCutE,EmptyMap);
2118 myCreated(CurCutE).Bind(Or1,Empty);
2119 myCreated(CurCutE)(Or1).Append(E1);
2121 myCreated(CurCutE).Bind(Or2,Empty);
2122 myCreated(CurCutE)(Or2).Append(E2);
2125 // ----------------------------------------------------------
2126 // try to init E1f, E1l, if not found with Analysis.
2127 // Should happen only if the THEORETICALLY tangent edges
2128 // are not actually tangent ( Cf: Approximation of lines
2129 // of intersection that add noise.)
2130 // ----------------------------------------------------------
2131 TopoDS_Vertex V1,V2;
2132 if ( E1f.IsNull() && !VfOnE1.IsNull() && !VfOnE2.IsNull()) {
2133 TopTools_MapIteratorOfMapOfShape it(MapOnV1f);
2134 for ( ; it.More(); it.Next()) {
2135 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
2137 TopExp::Vertices(E,V1,V2);
2138 if ((V1.IsSame(VfOnE1) && V2.IsSame(VfOnE2)) ||
2139 (V2.IsSame(VfOnE1) && V1.IsSame(VfOnE2)) ) {
2146 if ( E1l.IsNull() && !VlOnE1.IsNull() && !VlOnE2.IsNull()) {
2147 TopTools_MapIteratorOfMapOfShape it(MapOnV1l);
2148 for ( ; it.More(); it.Next()) {
2149 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
2151 TopExp::Vertices(E,V1,V2);
2152 if ((V1.IsSame(VlOnE1) && V2.IsSame(VlOnE2)) ||
2153 (V2.IsSame(VlOnE1) && V1.IsSame(VlOnE2)) ) {
2161 E1.Orientation(Orien1);
2162 E2.Orientation(Orien2);
2164 BRepOffset_Offset AnOffset(CurCutE,E1,E2,-myRadius,E1f,E1l,
2165 myNubs, myTol, GeomAbs_C2);
2166 myMapSF.Bind(CurCutE,AnOffset);
2167 myCenters.Add(CurCutE);
2170 const TopoDS_Face& Tuyo = AnOffset.Face();
2171 B.Add(myResult,Tuyo);
2173 if ( myBuildShape) {
2174 // method based ONLY on the construction of fillet:
2175 // the first edge of the tube is exactly on Shape1.
2176 GeomAPI_ProjectPointOnCurve Projector;
2177 TopExp_Explorer exp(Tuyo,TopAbs_EDGE);
2178 TopoDS_Vertex V1,V2;
2179 if (OF1isEdge) { // Update CutEdges.
2180 const TopoDS_Edge& EOnF1 = TopoDS::Edge(exp.Current());
2181 TopExp::Vertices(EOnF1,V1,V2);
2183 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2184 Projector.Init(P1,GC1);
2185 Standard_Real U1 = Projector.LowerDistanceParameter();
2187 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2188 Projector.Init(P2,GC1);
2189 Standard_Real U2 = Projector.LowerDistanceParameter();
2191 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
2192 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,TopoDS::Edge(Or1),myTol);
2193 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
2194 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,TopoDS::Edge(Or1),myTol);
2195 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),U1,
2196 // TopoDS::Edge(Or1),myTol);
2197 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),U2,
2198 // TopoDS::Edge(Or1),myTol);
2200 if (!myCutEdges.IsBound(Or1)) {
2201 TopTools_ListOfShape Dummy;
2202 myCutEdges.Bind(Or1,Dummy);
2204 TopTools_ListOfShape& L1 = myCutEdges(Or1);
2205 L1.Append(V1); L1.Append(V2);
2207 if (OF2isEdge) { // Update CutEdges.
2209 const TopoDS_Edge& EOnF2 = TopoDS::Edge(exp.Current());
2210 TopExp::Vertices(EOnF2,V1,V2);;
2212 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2213 Projector.Init(P1,GC2);
2214 Standard_Real U1 = Projector.LowerDistanceParameter();
2216 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2217 Projector.Init(P2,GC2);
2218 Standard_Real U2 = Projector.LowerDistanceParameter();
2220 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
2221 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,TopoDS::Edge(Or2),myTol);
2222 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
2223 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,TopoDS::Edge(Or2),myTol);
2224 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),U1,
2225 // TopoDS::Edge(Or2),myTol);
2226 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),U2,
2227 // TopoDS::Edge(Or2),myTol);
2229 if (!myCutEdges.IsBound(Or2)) {
2230 TopTools_ListOfShape Dummy;
2231 myCutEdges.Bind(Or2,Dummy);
2233 TopTools_ListOfShape& L2 = myCutEdges(Or2);
2234 L2.Append(V1); L2.Append(V2);
2240 sprintf(name,"%s_%d","SURF",nbc);
2241 DBRep::Set(name,AnOffset.Face());
2248 // ---------------------------------------------------
2249 // Construction of spheres,
2250 // if enough tubes arrive at the vertex
2251 // ---------------------------------------------------
2252 TopTools_IndexedDataMapOfShapeListOfShape Map;
2253 TopExp::MapShapesAndAncestors(Co,TopAbs_VERTEX,TopAbs_EDGE,Map);
2255 for ( Standard_Integer i = 1; i <= Map.Extent(); i++) {
2256 const TopoDS_Vertex& V = TopoDS::Vertex(Map.FindKey(i));
2257 if ( Map(i).Extent() != 3) continue;
2259 TopTools_ListOfShape LOE;
2260 TopTools_ListIteratorOfListOfShape it;
2262 for (it.Initialize(Map(i)) ; it.More(); it.Next()) {
2263 Standard_Boolean Reverse = Standard_True;
2265 LOE.Append(myMapSF(it.Value()).Generated(V).Reversed());
2267 LOE.Append(myMapSF(it.Value()).Generated(V));
2270 BRepOffset_Offset OFT(V,LOE,-myRadius,myNubs, myTol, GeomAbs_C2);
2271 myMapSF.Bind(V,OFT);
2274 B.Add(myResult,OFT.Face());
2278 sprintf(name,"%s_%d","SURF",nbc);
2279 DBRep::Set(name,OFT.Face());
2287 //=======================================================================
2288 //function : ComputeShape
2290 //=======================================================================
2291 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
2292 #include <Geom_Curve.hxx>
2294 void BiTgte_Blend::ComputeShape()
2296 // Find in the initial Shapel:
2297 // - untouched Faces
2298 // - generated tubes
2299 // - the faces neighbors of tubes that sould be reconstucted preserving sharing.
2301 // For Debug : Visualize edges of the initial shape that should be reconstructed.
2304 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myCutEdges);
2305 Standard_Integer NbEdges = 0;
2306 for ( ; itm.More(); itm.Next()) {
2307 const TopoDS_Edge& E = TopoDS::Edge(itm.Key());
2308 const TopTools_ListOfShape& VonE = itm.Value();
2309 TopTools_ListOfShape NewE;
2311 CutEdge(E,VonE,NewE);
2312 for (TopTools_ListIteratorOfListOfShape it(NewE); it.More(); it.Next()) {
2313 sprintf(name,"%s_%d","CUTE",++NbEdges);
2314 DBRep::Set(name,it.Value());
2322 // modify the tubes on edge for partition of edges.
2324 Standard_Integer NbS = NbSurfaces();
2325 for (Standard_Integer i = 1; i <= NbS; i++) {
2326 const TopoDS_Shape& S1 = SupportShape1(i);
2328 if ( S1.ShapeType() == TopAbs_EDGE) {
2329 const TopoDS_Edge& E1 = TopoDS::Edge(S1);
2330 // it is required to replace in F the cut edges of E1, that
2332 const TopTools_ListOfShape& VonE = myCutEdges(E1);
2333 TopTools_ListOfShape NewE;
2334 CutEdge(E1,VonE,NewE);
2340 TopTools_DataMapOfShapeShape Created;
2342 TopTools_ListOfShape Empty;
2343 TopTools_DataMapOfShapeListOfShape EmptyMap;
2348 // Maj of the Map of created.
2349 // Update edges that do not change in the resulting shape
2350 // i.e. invariant edges in the unwinding.
2351 TopExp_Explorer exp(myShape,TopAbs_FACE);
2352 // Standard_Integer nbe = 1;
2353 for ( ;exp.More(); exp.Next()) {
2355 const TopoDS_Face& CurF = TopoDS::Face(exp.Current());
2357 if ( !myFaces.Contains(CurF)) continue; // so the face is not touched
2359 // so the faces are unwinded
2360 if ( !myMapSF.IsBound(CurF)) continue; // inverted or degenerated
2362 const BRepOffset_Offset& Offset = myMapSF(CurF);
2363 const TopoDS_Face& CurOF = myMapSF(CurF).Face();
2365 if ( !myImageOffset.HasImage(CurOF)) // face disappears in unwinding
2368 TopExp_Explorer exp2(CurF,TopAbs_EDGE);
2369 for ( ;exp2.More(); exp2.Next()) {
2370 const TopoDS_Edge& CurE = TopoDS::Edge(exp2.Current());
2371 TopoDS_Shape aLocalShape = Offset.Generated(CurE);
2372 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
2373 // const TopoDS_Edge& CurOE = TopoDS::Edge(Offset.Generated(CurE));
2375 if (!myImageOffset.HasImage(CurOE)) continue;
2378 const TopoDS_Edge& ImE =
2379 TopoDS::Edge(myImageOffset.Image(CurOE).First());
2380 if (ImE.IsSame(CurOE)) {
2381 myCreated.Bind(CurOE,EmptyMap);
2382 myCreated(CurOE).Bind(CurF,Empty);
2383 myCreated(CurOE)(CurF).Append(CurE);
2388 // The connected faces are already in myResult.
2389 // So it is necessary to add faces:
2390 // - non-touched (so not in myFaces)
2391 // - issuing from the unwinding (non degenerated, non inverted, non disappeared)
2392 exp.Init(myShape,TopAbs_FACE);
2393 for ( ;exp.More(); exp.Next()) {
2395 const TopoDS_Face& CurF = TopoDS::Face(exp.Current());
2397 if ( !myFaces.Contains(CurF)) {
2398 // so the face is not touched
2399 B.Add(myResult,CurF);
2401 else { // so the faces are unwindeds
2403 if ( !myMapSF.IsBound(CurF)) continue; // inverted or degenerated
2405 const TopoDS_Face& CurOF = myMapSF(CurF).Face();
2407 if ( !myImageOffset.HasImage(CurOF)) // face disappears in unwinding
2410 // List of faces generated by a face in the unwinding
2411 TopTools_ListOfShape Lim;
2412 myImageOffset.LastImage(CurOF,Lim);
2413 TopTools_ListIteratorOfListOfShape itLim(Lim);
2414 for ( ;itLim.More(); itLim.Next()) {
2415 // DeboucFace = offset Face unwinded in "Debouc".
2416 const TopoDS_Face& DeboucFace = TopoDS::Face(itLim.Value());
2419 Handle(Geom_Surface) S = BRep_Tool::Surface(CurF,L);
2421 TopoDS_Face NewF; B.MakeFace(NewF);
2422 B.UpdateFace(NewF,S,L,BRep_Tool::Tolerance(CurF));
2424 TopTools_DataMapOfShapeShape MapSS;
2426 TopoDS_Shape aLocalShape = DeboucFace.Oriented(TopAbs_FORWARD);
2427 const TopoDS_Face& Face = TopoDS::Face(aLocalShape);
2428 // const TopoDS_Face& Face =
2429 // TopoDS::Face(DeboucFace.Oriented(TopAbs_FORWARD));
2430 TopExp_Explorer exp2(Face, TopAbs_EDGE);
2431 for ( ; exp2.More(); exp2.Next()) {
2432 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
2433 TopoDS_Vertex V1,V2,OV1,OV2;
2434 TopExp::Vertices(E ,V1 ,V2 );
2435 if (myCreated.IsBound(E)) {
2436 if (myCreated(E).IsBound(CurF)) {
2437 const TopoDS_Edge& OE = TopoDS::Edge(myCreated(E)(CurF).First());
2438 TopExp::Vertices(OE,OV1,OV2);
2439 if ( !myCreated.IsBound(V1)) myCreated.Bind(V1,EmptyMap);
2440 if ( !myCreated.IsBound(V2)) myCreated.Bind(V2,EmptyMap);
2441 if ( !myCreated(V1).IsBound(CurF)) {
2442 myCreated(V1).Bind(CurF,Empty);
2443 myCreated(V1)(CurF).Append(OV1);
2445 if ( !myCreated(V2).IsBound(CurF)) {
2446 myCreated(V2).Bind(CurF,Empty);
2447 myCreated(V2)(CurF).Append(OV2);
2453 TopExp_Explorer expw(Face, TopAbs_WIRE);
2454 for ( ; expw.More(); expw.Next()) {
2455 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
2456 TopExp_Explorer expe(W.Oriented(TopAbs_FORWARD),
2461 for ( ; expe.More(); expe.Next()) {
2462 const TopoDS_Edge& E = TopoDS::Edge(expe.Current());
2464 Handle(Geom2d_Curve) C2d =
2465 BRep_Tool::CurveOnSurface(E,Face,f,l);
2467 if ( MapSS.IsBound(E)) { // this is an edge of cutting
2468 OE = TopoDS::Edge(MapSS(E));
2469 TopoDS_Shape aLocalShape = E.Reversed();
2470 Handle(Geom2d_Curve) C2d_1 =
2471 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),Face,f,l);
2472 // Handle(Geom2d_Curve) C2d_1 =
2473 // BRep_Tool::CurveOnSurface(TopoDS::Edge(E.Reversed()),
2475 if ( E.Orientation() == TopAbs_FORWARD)
2476 B.UpdateEdge(OE,C2d,C2d_1,NewF,BRep_Tool::Tolerance(E));
2478 B.UpdateEdge(OE,C2d_1,C2d,NewF,BRep_Tool::Tolerance(E));
2482 // Is there an image in the Map of Created ?
2483 if ( myCreated.IsBound(E)) {
2484 if ( myCreated(E).IsBound(CurF)) {
2485 OE = TopoDS::Edge(myCreated(E)(CurF).First());
2490 TopoDS_Vertex V1,V2,OV1,OV2;
2491 TopExp::Vertices(E,V1,V2);
2492 if ( myCreated.IsBound(V1) && myCreated(V1).IsBound(CurF)) {
2493 OV1 = TopoDS::Vertex(myCreated(V1)(CurF).First());
2498 C2d->Value(BRep_Tool::Parameter(V1,E,Face));
2500 S->D0(P2d.X(),P2d.Y(),P);
2501 P.Transform(L.Transformation());
2502 B.UpdateVertex(OV1,P,BRep_Tool::Tolerance(V1));
2503 myCreated.Bind(V1,EmptyMap);
2504 myCreated(V1).Bind(CurF,Empty);
2505 myCreated(V1)(CurF).Append(OV1);
2507 if ( myCreated.IsBound(V2) && myCreated(V2).IsBound(CurF)) {
2508 OV2 = TopoDS::Vertex(myCreated(V2)(CurF).First());
2513 C2d->Value(BRep_Tool::Parameter(V2,E,Face));
2515 S->D0(P2d.X(),P2d.Y(),P);
2516 P.Transform(L.Transformation());
2517 B.UpdateVertex(OV2,P,BRep_Tool::Tolerance(V2));
2518 myCreated.Bind(V2,EmptyMap);
2519 myCreated(V2).Bind(CurF,Empty);
2520 myCreated(V2)(CurF).Append(OV2);
2522 B.Add(OE,OV1.Oriented(V1.Orientation()));
2523 B.Add(OE,OV2.Oriented(V2.Orientation()));
2525 B.UpdateEdge(OE,C2d,NewF,BRep_Tool::Tolerance(E));
2527 // ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
2530 B.Add(OW, OE.Oriented(E.Orientation()));
2532 B.Add(NewF, OW.Oriented(W.Orientation()));
2535 NewF.Orientation(DeboucFace.Orientation());
2537 BRepTools::Update(NewF);
2538 B.Add(myResult,NewF);
2543 // non-regarding the cause, there always remain greeb borders on this Shape, so it is sewn.
2544 Handle(BRepBuilderAPI_Sewing) Sew = new BRepBuilderAPI_Sewing(myTol);
2546 BRepLib::BuildCurves3d(myResult);
2548 exp.Init(myResult,TopAbs_FACE);
2549 for ( ;exp.More(); exp.Next())
2550 Sew->Add(exp.Current());
2554 // SameParameter is done in case Sew does not do it (Detect that the edges
2555 // are not sameparameter but does nothing.)
2557 const TopoDS_Shape& SewedShape = Sew->SewedShape();
2558 if ( !SewedShape.IsNull()) {
2559 exp.Init(Sew->SewedShape(), TopAbs_EDGE);
2560 for (; exp.More(); exp.Next()) {
2561 const TopoDS_Edge& sec = TopoDS::Edge(exp.Current());
2562 BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
2564 myResult = SewedShape;
2569 //=======================================================================
2570 //function : Intersect
2572 //=======================================================================
2574 Standard_Boolean BiTgte_Blend::Intersect
2575 (const TopoDS_Shape& Init,
2576 const TopoDS_Face& Face,
2577 const BiTgte_DataMapOfShapeBox& MapSBox,
2578 const BRepOffset_Offset& OF1,
2579 BRepOffset_Inter3d& Inter)
2581 Standard_Boolean JenRajoute = Standard_False;
2583 const Bnd_Box& Box1 = MapSBox(Face);
2585 // -----------------------------------------------
2586 // intersection with all already created faces.
2587 // -----------------------------------------------
2588 const TopoDS_Shape& InitShape1 = OF1.InitialShape();
2589 Standard_Boolean F1surBordLibre =
2590 InitShape1.ShapeType() == TopAbs_EDGE &&
2591 myStopFaces.Contains(InitShape1);
2593 TopTools_MapOfShape Done;
2594 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(myMapSF);
2595 for ( ; It.More(); It.Next()) {
2596 const BRepOffset_Offset& OF2 = It.Value();
2597 const TopoDS_Face& F2 = OF2.Face();
2599 if (Box1.IsOut(MapSBox(F2))) continue;
2601 if ( Inter.IsDone(Face,F2)) continue;
2603 // 2 tubes created on free border are not intersected.
2604 const TopoDS_Shape& InitShape2 = OF2.InitialShape();
2605 Standard_Boolean F2surBordLibre =
2606 InitShape2.ShapeType() == TopAbs_EDGE &&
2607 myStopFaces.Contains(InitShape2);
2610 if ( F1surBordLibre && F2surBordLibre) {
2611 cout << "Rejection : 2 tubes on free border are not intersected";
2616 if ( F1surBordLibre && F2surBordLibre) continue;
2618 // -------------------------------------------------------
2619 // Tubes are not intersected with neighbor faces.
2620 // -------------------------------------------------------
2621 const TopoDS_Shape& ItKey = It.Key();
2623 if ( Init.ShapeType() == TopAbs_EDGE) {
2624 if (ItKey.ShapeType() == TopAbs_FACE &&
2625 IsInFace(TopoDS::Edge(Init), TopoDS::Face(ItKey))) continue;
2628 Inter.FaceInter(Face,F2,myInitOffsetFace);
2630 // ------------------------------------------
2631 // an edge of F1 or F2 has been touched ?
2632 // if yes, add faces in myFaces
2633 // ==> JenRajoute = True
2634 // ------------------------------------------
2635 TopTools_ListOfShape LInt;
2637 if (myAsDes->HasCommonDescendant(Face,F2,LInt)) {
2638 TopTools_ListIteratorOfListOfShape itl2;
2639 for (itl2.Initialize(LInt); itl2.More(); itl2.Next()) {
2640 const TopoDS_Edge& CurE = TopoDS::Edge(itl2.Value());
2641 TopoDS_Vertex V1,V2;
2643 TopExp::Vertices(CurE,V1,V2);
2645 if ( Done.Add(V1)) {
2646 Standard_Boolean IsOnR1 = IsOnRestriction(V1,CurE,Face,E1);
2647 Standard_Boolean IsOnR2 = IsOnRestriction(V1,CurE,F2,E2);
2649 if (IsOnR1 && IsOnR2) {
2650 cout << "Leave in the same tps on 2 faces, ";
2651 cout << "propagation only on free border";
2656 if ( !myStopFaces.Contains(Init)) {
2657 Add(E1,myEdges,Init,OF1,myAnalyse,IsOnR1 && IsOnR2);
2658 JenRajoute = Standard_True;
2662 if ( !myStopFaces.Contains(ItKey)) {
2663 Add(E2,myEdges, ItKey,OF2,myAnalyse,IsOnR1 && IsOnR2);
2664 JenRajoute = Standard_True;
2669 if ( Done.Add(V2)) {
2670 Standard_Boolean IsOnR1 = IsOnRestriction(V2,CurE,Face,E1);
2671 Standard_Boolean IsOnR2 = IsOnRestriction(V2,CurE,F2,E2);
2673 // If IsOnR1 && IsOnR2,
2674 // Leave in the same tps on 2 faces, propagate only on
2676 // A priori, only facet is closed.
2678 if (IsOnR1 && IsOnR2) {
2679 cout << "Leave with the same tps on 2 faces, ";
2680 cout << "propagate only if the border is free";
2685 if ( !myStopFaces.Contains(Init)) {
2686 Add(E1,myEdges,Init,OF1,myAnalyse,IsOnR1 && IsOnR2);
2687 JenRajoute = Standard_True;
2691 if ( !myStopFaces.Contains(ItKey)) {
2692 Add(E2,myEdges,ItKey,OF2,myAnalyse,IsOnR1 && IsOnR2);
2693 JenRajoute = Standard_True;