1 // Created on: 1996-12-16
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
24 #include <BiTgte_Blend.ixx>
27 // - all small static functions.
29 //======================== START STATIC FUNCTIONS ============
30 #include <BiTgte_DataMapOfShapeBox.hxx>
31 #include <BiTgte_CurveOnEdge.hxx>
33 #include <Bnd_Box.hxx>
34 #include <BRepBndLib.hxx>
35 #include <BRepTools.hxx>
36 #include <BRepTools_Quilt.hxx>
37 #include <BRepBuilderAPI_Sewing.hxx>
38 #include <BRep_Tool.hxx>
39 #include <BRep_Builder.hxx>
40 #include <BRepLib_MakeEdge.hxx>
41 #include <BRepOffset_DataMapOfShapeOffset.hxx>
42 #include <BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx>
43 #include <BRepOffset_Offset.hxx>
44 #include <BRepOffset_MakeLoops.hxx>
45 #include <BRepOffset_Inter3d.hxx>
46 #include <BRepOffset_Inter2d.hxx>
47 #include <BRepOffset_Interval.hxx>
48 #include <BRepOffset_ListOfInterval.hxx>
49 #include <BRepOffset_Tool.hxx>
50 #include <BRepAlgo_Loop.hxx>
52 #include <GeomAbs_SurfaceType.hxx>
53 #include <GeomAPI_ProjectPointOnCurve.hxx>
54 #include <Geom_BSplineCurve.hxx>
55 #include <Geom_TrimmedCurve.hxx>
56 #include <Geom_Circle.hxx>
57 #include <Geom_Line.hxx>
58 #include <Geom2d_Curve.hxx>
59 #include <GeomAdaptor_Surface.hxx>
60 #include <Geom2dAdaptor_Curve.hxx>
61 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
62 #include <TopExp_Explorer.hxx>
63 #include <TopoDS_Wire.hxx>
64 #include <TopoDS_Vertex.hxx>
65 #include <TopoDS_Edge.hxx>
66 #include <TopoDS_Compound.hxx>
67 #include <TopTools_ListOfShape.hxx>
68 #include <TopTools_SequenceOfShape.hxx>
69 #include <TopTools_DataMapOfShapeShape.hxx>
70 #include <TopTools_MapIteratorOfMapOfShape.hxx>
71 #include <TopTools_ListIteratorOfListOfShape.hxx>
73 #include <gp_Pnt2d.hxx>
74 #include <gp_Lin2d.hxx>
76 #include <gp_Dir2d.hxx>
81 #include <gp_Circ.hxx>
82 #include <gp_Sphere.hxx>
84 #include <AppCont_Function.hxx>
85 #include <Approx_FitAndDivide.hxx>
86 #include <AppParCurves_MultiCurve.hxx>
87 #include <BSplCLib.hxx>
88 #include <Convert_CompBezierCurvesToBSplineCurve.hxx>
89 #include <Precision.hxx>
90 #include <TColgp_Array1OfPnt.hxx>
91 #include <TColStd_Array1OfReal.hxx>
92 #include <TColStd_Array1OfInteger.hxx>
94 #include <Standard_NotImplemented.hxx>
96 #include <BRepLib.hxx>
98 #include <GeomAPI.hxx>
100 #include <TopExp.hxx>
102 #include <OSD_Chronometer.hxx>
103 // variables for performance
104 Standard_Real t_mkcurve;
105 //Standard_IMPORT extern void ChFi3d_InitChron(OSD_Chronometer& ch);
106 Standard_EXPORT void ChFi3d_InitChron(OSD_Chronometer& ch);
107 //Standard_IMPORT extern void ChFi3d_ResultChron(OSD_Chronometer & ch,
108 Standard_IMPORT void ChFi3d_ResultChron(OSD_Chronometer & ch,
109 Standard_Real& time);
111 static Standard_Boolean Affich = Standard_False;
112 static char name[100];
116 //=======================================================================
117 //function : IsOnRestriction
119 //=======================================================================
121 static Standard_Boolean IsOnRestriction(const TopoDS_Vertex& V,
122 const TopoDS_Edge& CurE,
123 const TopoDS_Face& F,
126 // find if Vertex V of CurE is on a restriction of F.
127 // if yes, store this restriction in E.
130 // Method somewhat brutal : possible to really optimize by a
131 // direct call the SD of intersections -> See LBR
134 Handle(Geom2d_Curve) CurC = BRep_Tool::CurveOnSurface(CurE,F,f,l);
135 Standard_Real U = BRep_Tool::Parameter(V,CurE,F);
136 gp_Pnt2d P = CurC->Value(U);
138 Geom2dAPI_ProjectPointOnCurve Proj;
140 // The tolerance is exaggerated : it is better to construct too many
141 // tubes than to miss intersections.
142 // Standard_Real Tol = 100 * BRep_Tool::Tolerance(V);
143 Standard_Real Tol = BRep_Tool::Tolerance(V);
144 TopExp_Explorer exp(F,TopAbs_EDGE);
145 for ( ; exp.More(); exp.Next()) {
146 E = TopoDS::Edge(exp.Current());
147 Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(E,F,f,l);
149 if ( Proj.NbPoints() > 0) {
150 if (Proj.LowerDistance() < Tol) {
151 return Standard_True;
155 return Standard_False;
158 //=======================================================================
161 //=======================================================================
163 static void Add(const TopoDS_Edge& E,
164 TopTools_IndexedMapOfShape& Map,
165 const TopoDS_Shape& S,
166 const BRepOffset_Offset& OF,
167 const BRepOffset_Analyse& Analyse,
168 const Standard_Boolean WarningSurBordLibre)
169 // If WarningSurBordLibre = TRUE, no propagation if the edge is open.
171 TopAbs_ShapeEnum Type = S.ShapeType();
173 if ( Type == TopAbs_FACE) {
174 TopExp_Explorer exp(S,TopAbs_EDGE);
175 for ( ; exp.More(); exp.Next()) {
176 const TopoDS_Edge& OriE = TopoDS::Edge(exp.Current());
177 TopoDS_Shape aLocalShape = OF.Generated(OriE);
178 const TopoDS_Edge& IE = TopoDS::Edge(aLocalShape);
179 // const TopoDS_Edge& IE = TopoDS::Edge(OF.Generated(OriE));
180 if ( E.IsEqual(IE)) {
181 if (WarningSurBordLibre) {
182 // It is checked that the border is not free.
183 const TopTools_ListOfShape& L = Analyse.Ancestors(OriE);
184 if (L.Extent() == 1) break; // Nothing is done.
186 Map.Add(exp.Current());
191 else if ( Type == TopAbs_EDGE) {
192 TopExp_Explorer exp(S,TopAbs_VERTEX);
193 for ( ; exp.More(); exp.Next()) {
194 TopoDS_Shape aLocalShape = OF.Generated(exp.Current());
195 const TopoDS_Edge& IE = TopoDS::Edge(aLocalShape);
196 // const TopoDS_Edge& IE = TopoDS::Edge(OF.Generated(exp.Current()));
197 if ( E.IsEqual(IE)) {
198 const TopTools_ListOfShape& L = Analyse.Ancestors(exp.Current());
199 TopTools_ListIteratorOfListOfShape it(L);
200 for ( ; it.More(); it.Next()) {
210 //=======================================================================
211 //function : IsInFace
213 //=======================================================================
215 static Standard_Boolean IsInFace(const TopoDS_Edge& E,
216 const TopoDS_Face& F)
218 TopExp_Explorer exp(F,TopAbs_EDGE);
219 for ( ;exp.More(); exp.Next())
220 if ( E.IsSame(exp.Current())) return Standard_True;
221 return Standard_False;
225 //=======================================================================
226 //function : KPartCurve3d
228 //=======================================================================
230 static void KPartCurve3d(TopoDS_Edge Edge,
231 Handle(Geom2d_Curve) Curve,
232 Handle(Geom_Surface) Surf)
234 // try to find the particular case
235 // if not found call BRepLib::BuildCurve3d
238 Standard_Real Tol = Precision::Confusion();
240 Standard_Boolean IsComputed = Standard_False;
242 // Seach only isos on analytical surfaces.
243 Geom2dAdaptor_Curve C(Curve);
244 GeomAdaptor_Surface S(Surf);
245 GeomAbs_CurveType CTy = C.GetType();
246 GeomAbs_SurfaceType STy = S.GetType();
247 BRep_Builder TheBuilder;
249 if ( STy != GeomAbs_Plane) { // if plane buildcurve3d manage KPart
250 if ( CTy == GeomAbs_Line) {
251 gp_Dir2d D = C.Line().Direction();
252 if ( D.IsParallel(gp::DX2d(),Precision::Angular())) { // Iso V.
253 if ( STy == GeomAbs_Sphere) {
254 gp_Pnt2d P = C.Line().Location();
255 if ( Abs( Abs(P.Y()) -M_PI/2. ) < Precision::PConfusion()) {
256 TheBuilder.Degenerated(Edge, Standard_True);
259 gp_Sphere Sph = S.Sphere();
260 gp_Ax3 Axis = Sph.Position();
261 gp_Circ Ci = ElSLib::SphereVIso(Axis,
264 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
265 gp_Ax1 AxeRev(Axis.Location(), DRev);
266 Ci.Rotate(AxeRev, P.X());
267 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
268 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
270 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
272 IsComputed = Standard_True;
274 else if ( STy == GeomAbs_Cylinder) {
275 gp_Cylinder Cyl = S.Cylinder();
276 gp_Pnt2d P = C.Line().Location();
277 gp_Ax3 Axis = Cyl.Position();
278 gp_Circ Ci = ElSLib::CylinderVIso(Axis,
281 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
282 gp_Ax1 AxeRev(Axis.Location(), DRev);
283 Ci.Rotate(AxeRev, P.X());
284 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
285 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
287 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
288 IsComputed = Standard_True;
290 else if ( STy == GeomAbs_Cone) {
291 gp_Cone Cone = S.Cone();
292 gp_Pnt2d P = C.Line().Location();
293 gp_Ax3 Axis = Cone.Position();
294 gp_Circ Ci = ElSLib::ConeVIso(Axis,
298 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
299 gp_Ax1 AxeRev(Axis.Location(), DRev);
300 Ci.Rotate(AxeRev, P.X());
301 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
302 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
304 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
305 IsComputed = Standard_True;
307 else if ( STy == GeomAbs_Torus) {
308 gp_Torus Tore = S.Torus();
309 gp_Pnt2d P = C.Line().Location();
310 gp_Ax3 Axis = Tore.Position();
311 gp_Circ Ci = ElSLib::TorusVIso(Axis,
315 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
316 gp_Ax1 AxeRev(Axis.Location(), DRev);
317 Ci.Rotate(AxeRev, P.X());
318 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
319 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
321 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
322 IsComputed = Standard_True;
325 else if ( D.IsParallel(gp::DY2d(),Precision::Angular())) { // Iso U.
326 if ( STy == GeomAbs_Sphere) {
327 gp_Sphere Sph = S.Sphere();
328 gp_Pnt2d P = C.Line().Location();
329 gp_Ax3 Axis = Sph.Position();
331 gp_Circ Ci = ElSLib::SphereUIso(Axis, Sph.Radius(),0.);
333 // set to sameparameter (rotation of the circle - offset from Y)
334 gp_Dir DRev = Axis.XDirection().Crossed(Axis. Direction());
335 gp_Ax1 AxeRev(Axis.Location(),DRev);
336 Ci.Rotate(AxeRev, P.Y());
338 // transformation by iso U ( = P.X())
339 DRev = Axis.XDirection().Crossed(Axis.YDirection());
340 AxeRev = gp_Ax1(Axis.Location(), DRev);
341 Ci.Rotate(AxeRev, P.X());
342 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
344 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
346 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
347 IsComputed = Standard_True;
349 else if ( STy == GeomAbs_Cylinder) {
350 gp_Cylinder Cyl = S.Cylinder();
351 gp_Pnt2d P = C.Line().Location();
352 gp_Lin L = ElSLib::CylinderUIso(Cyl.Position(),
355 gp_Vec Tr(L.Direction());
358 Handle(Geom_Line) Line = new Geom_Line(L);
359 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
361 TheBuilder.UpdateEdge(Edge, Line, Loc, Tol);
362 IsComputed = Standard_True;
364 else if ( STy == GeomAbs_Cone) {
365 gp_Cone Cone = S.Cone();
366 gp_Pnt2d P = C.Line().Location();
367 gp_Lin L = ElSLib::ConeUIso(Cone.Position(),
371 gp_Vec Tr(L.Direction());
373 L.Translate(Tr); Handle(Geom_Line) Line = new Geom_Line(L);
374 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
376 TheBuilder.UpdateEdge(Edge, Line, Loc, Tol);
377 IsComputed = Standard_True;
379 else if ( STy == GeomAbs_Torus) {
385 Handle(Geom_Curve) C3d = GeomAPI::To3d(Curve,S.Plane());
386 TheBuilder.UpdateEdge(Edge, C3d, Loc, Tol);
387 IsComputed = Standard_True;
392 //=======================================================================
393 //function : MakeCurve
395 //=======================================================================
397 class MakeCurve_Function : public AppCont_Function
399 BiTgte_CurveOnEdge myCurve;
403 MakeCurve_Function(const BiTgte_CurveOnEdge& C) : myCurve(C) {};
405 Standard_Real FirstParameter() const
406 {return myCurve.FirstParameter();}
408 Standard_Real LastParameter() const
409 {return myCurve.LastParameter();}
411 gp_Pnt Value(const Standard_Real t) const
412 {return myCurve.Value(t);}
414 Standard_Boolean D1(const Standard_Real /*t*/, gp_Pnt& /*P*/, gp_Vec& /*V*/) const
415 {return Standard_False;}
419 Handle(Geom_Curve) MakeCurve (const BiTgte_CurveOnEdge& HC)
421 Handle(Geom_Curve) C;
425 ChFi3d_InitChron(ch);
428 if ( HC.GetType() == GeomAbs_Circle) {
429 C = new Geom_Circle(HC.Circle());
430 C = new Geom_TrimmedCurve(C,HC.FirstParameter(),HC.LastParameter());
432 else { // the approximation is done
433 MakeCurve_Function F(HC);
434 Standard_Integer Deg1, Deg2;
436 Standard_Real Tol = Precision::Approximation();
437 Approx_FitAndDivide Fit(F,Deg1,Deg2,Tol,Tol,Standard_True);
439 Standard_Integer NbCurves = Fit.NbMultiCurves();
440 // it is attempted to make the curve at least C1
441 Convert_CompBezierCurvesToBSplineCurve Conv;
443 for (i = 1; i <= NbCurves; i++) {
444 AppParCurves_MultiCurve MC = Fit.Value( i); //Load the Ith Curve
445 TColgp_Array1OfPnt Poles( 1, MC.Degree() + 1); //Return poles
448 Conv.AddCurve(Poles);
453 Standard_Integer NbPoles = Conv.NbPoles();
454 Standard_Integer NbKnots = Conv.NbKnots();
455 TColgp_Array1OfPnt NewPoles(1,NbPoles);
456 TColStd_Array1OfReal NewKnots(1,NbKnots);
457 TColStd_Array1OfInteger NewMults(1,NbKnots);
459 Conv.KnotsAndMults(NewKnots,NewMults);
460 Conv.Poles(NewPoles);
462 BSplCLib::Reparametrize(HC.FirstParameter(),
466 C = new Geom_BSplineCurve (NewPoles,
473 ChFi3d_ResultChron(ch, t_mkcurve);
480 //=======================================================================
482 //purpose : Only the faces connected with caps are given
483 //=======================================================================
485 static void Touched(const BRepOffset_Analyse& Analyse,
486 const TopTools_MapOfShape& StopFaces,
487 const TopoDS_Shape& Shape,
488 TopTools_MapOfShape& TouchedByCork)
490 // currently nothing is done !!
491 if ( Standard_True) {
495 TopExp_Explorer exp(Shape, TopAbs_EDGE);
496 for ( ; exp.More(); exp.Next()) {
497 const TopTools_ListOfShape& L = Analyse.Ancestors(exp.Current());
498 if (StopFaces.Contains(L.First()))
499 TouchedByCork.Add(L.Last());
500 else if (StopFaces.Contains(L.Last()))
501 TouchedByCork.Add(L.First());
506 //=======================================================================
507 //function : FindVertex
509 //=======================================================================
511 static TopoDS_Vertex FindVertex(const gp_Pnt& P,
512 const TopTools_MapOfShape& Map,
513 const Standard_Real Tol)
516 // Find in <Map> a vertex which represent the point <P>.
517 Standard_Real Tol2,Dist;
518 TopoDS_Vertex V,VV[2];
519 Standard_Real TolCarre = Tol*Tol;
520 TopTools_MapIteratorOfMapOfShape it(Map);
521 for ( ; it.More(); it.Next()) {
522 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
524 TopExp::Vertices(E,VV[0],VV[1]);
526 for (Standard_Integer i = 0; i < 2 ; i++) {
527 // if OK la Tolerance du Vertex
528 Tol2 = BRep_Tool::Tolerance(VV[i]);
530 gp_Pnt P1 = BRep_Tool::Pnt(VV[i]);
531 Dist = P.SquareDistance(P1);
532 if ( Dist <= Tol2) return VV[i];
533 // otherwise with the required tolerance.
534 if (TolCarre > Tol2) {
535 if ( Dist <= TolCarre) {
536 // so it is necessary to update the tolerance of Vertex.
537 B.UpdateVertex(VV[i],Tol);
549 //=======================================================================
550 //function : MakeDegeneratedEdge
552 //=======================================================================
554 static TopoDS_Edge MakeDegeneratedEdge(const Handle(Geom_Curve)& CC,
555 const TopoDS_Vertex& VfOnE)
558 Standard_Real Tol = Precision::Confusion();
559 // kill trimmed curves
560 Handle(Geom_Curve) C = CC;
561 Handle(Geom_TrimmedCurve) CT = Handle(Geom_TrimmedCurve)::DownCast(C);
562 while (!CT.IsNull()) {
563 C = CT->BasisCurve();
564 CT = Handle(Geom_TrimmedCurve)::DownCast(C);
568 if ( VfOnE.IsNull()) {
569 gp_Pnt P = C->Value(C->FirstParameter());
570 B.MakeVertex(V1,P,Tol);
576 V1.Orientation(TopAbs_FORWARD);
577 V2.Orientation(TopAbs_REVERSED);
581 B.Add(E,V1); B.Add(E,V2);
582 // B.UpdateVertex(V1,C->FirstParameter(),E,Tol);
583 // B.UpdateVertex(V2,C->LastParameter(),E,Tol);
584 B.Range(E,CC->FirstParameter(),CC->LastParameter());
589 //=======================================================================
590 //function : Orientation
592 //=======================================================================
594 static TopAbs_Orientation Orientation(const TopoDS_Edge& E,
595 const TopoDS_Face& F,
596 const TopTools_ListOfShape& L)
599 TopAbs_Orientation Orien = TopAbs_FORWARD;
601 TopAbs_Orientation Orien;
603 TopTools_ListIteratorOfListOfShape itld;
604 for ( itld.Initialize(L); itld.More(); itld.Next()) {
605 if ( itld.Value().IsSame(E)) {
606 Orien = itld.Value().Orientation();
610 if ( F.Orientation() == TopAbs_REVERSED)
611 Orien = TopAbs::Reverse(Orien);
616 //=======================================================================
617 //function : FindCreatedEdge
619 //=======================================================================
621 static TopoDS_Edge FindCreatedEdge
622 (const TopoDS_Vertex& V1,
623 const TopoDS_Edge& E,
624 const BRepOffset_DataMapOfShapeOffset& MapSF,
625 TopTools_MapOfShape& MapOnV,
626 const BRepOffset_Analyse& CenterAnalyse,
627 Standard_Real Radius,
631 if (!CenterAnalyse.HasAncestor(V1)) return E1; // return a Null Shape.
633 TopTools_ListOfShape TangE;
634 CenterAnalyse.TangentEdges(E,V1,TangE);
636 TopTools_ListIteratorOfListOfShape itl(TangE);
637 Standard_Boolean Find = Standard_False;
638 for ( ; itl.More() && !Find; itl.Next()) {
639 const TopoDS_Edge& ET = TopoDS::Edge(itl.Value());
640 if ( MapSF.IsBound(ET)) {
641 TopoDS_Shape aLocalShape = MapSF(ET).Generated(V1);
642 E1 = TopoDS::Edge(aLocalShape);
643 // E1 = TopoDS::Edge(MapSF(ET).Generated(V1));
645 Find = Standard_True;
648 // Find the sharing of vertices in case of tangent consecutive 3 edges
649 // the second of which is the edge that degenerates the tube.
650 TopLoc_Location CLoc;
652 Handle(Geom_Curve) CET =
653 BRep_Tool::Curve(ET,CLoc,ff,ll);
654 if ( CET->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
655 CET = Handle(Geom_TrimmedCurve)::DownCast(CET)->BasisCurve();
657 Handle(Geom_Circle) Circ = Handle(Geom_Circle)::DownCast(CET);
658 if ( Circ.IsNull()) continue;
659 if ( Abs(Circ->Radius() - Abs(Radius)) > Tol) continue;
662 TopExp::Vertices(ET,U1,U2);
663 if ( U1.IsSame(V1)) U1 = U2;
664 TopTools_ListOfShape Tang2;
665 CenterAnalyse.TangentEdges(ET,U1,Tang2);
666 TopTools_ListIteratorOfListOfShape it2(Tang2);
667 for ( ; it2.More() ; it2.Next()) {
668 const TopoDS_Edge& ET2 = TopoDS::Edge(it2.Value());
669 if ( MapSF.IsBound(ET2)) {
670 TopoDS_Shape aLocalShape = MapSF(ET2).Generated(U1);
671 MapOnV.Add(TopoDS::Edge(aLocalShape));
672 // MapOnV.Add(TopoDS::Edge(MapSF(ET2).Generated(U1)));
679 // CenterAnalyse.Edges(V1f, OT, TangE);
680 if (CenterAnalyse.HasAncestor(V1)) {
681 TangE = CenterAnalyse.Ancestors(V1);
682 itl.Initialize(TangE);
683 for ( ; itl.More() && !Find; itl.Next()) {
684 if ( MapSF.IsBound(itl.Value())) {
685 MapOnV.Add(MapSF(itl.Value()).Generated(V1));
694 //=======================================================================
696 //purpose : Sets in increasing order the sequence of vertices.
697 //=======================================================================
699 static void Bubble(const TopoDS_Edge& E,
700 TopTools_SequenceOfShape& Seq)
702 Standard_Boolean Invert = Standard_True;
703 Standard_Integer NbPoints = Seq.Length();
708 Invert = Standard_False;
709 for ( Standard_Integer i = 1; i < NbPoints; i++) {
710 TopoDS_Shape aLocalShape = Seq.Value(i) .Oriented(TopAbs_INTERNAL);
711 V1 = TopoDS::Vertex(aLocalShape);
712 aLocalShape = Seq.Value(i+1).Oriented(TopAbs_INTERNAL);
713 V2 = TopoDS::Vertex(aLocalShape);
714 // V1 = TopoDS::Vertex(Seq.Value(i) .Oriented(TopAbs_INTERNAL));
715 // V2 = TopoDS::Vertex(Seq.Value(i+1).Oriented(TopAbs_INTERNAL));
717 U1 = BRep_Tool::Parameter(V1,E);
718 U2 = BRep_Tool::Parameter(V2,E);
721 Invert = Standard_True;
727 //=======================================================================
730 //=======================================================================
732 static void CutEdge (const TopoDS_Edge& E,
733 const TopTools_ListOfShape& VOnE,
734 TopTools_ListOfShape& NE )
736 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
737 TopoDS_Edge WE = TopoDS::Edge(aLocalShape);
738 // TopoDS_Edge WE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
742 TopTools_SequenceOfShape SV;
743 TopTools_ListIteratorOfListOfShape it(VOnE);
746 for ( ; it.More(); it.Next()) {
747 SV.Append(it.Value());
749 //--------------------------------
750 // Parse vertices on the edge.
751 //--------------------------------
754 Standard_Integer NbVer = SV.Length();
755 //----------------------------------------------------------------
756 // Construction of new edges.
757 // The vertices at the extremities of edges are not
758 // necessarily in the list of vertices
759 //----------------------------------------------------------------
766 BRep_Tool::Range(WE,f,l);
767 TopExp::Vertices(WE,VF,VL);
770 if (SV(1).IsEqual(VF) && SV(2).IsEqual(VL)) {
775 //----------------------------------------------------
776 // Processing of closed edges
777 // If a vertex of intersection is on the common vertex,
778 // it should appear at the beginning and the end of SV.
779 //----------------------------------------------------
782 if (!VF.IsNull() && !VF.IsSame(SV.First())) SV.Prepend(VF);
783 if (!VL.IsNull() && !VL.IsSame(SV.Last ())) SV.Append (VL);
785 V1 = TopoDS::Vertex(SV.First());
788 while (!SV.IsEmpty()) {
790 V2 = TopoDS::Vertex(SV.First());
793 if ( V1.IsSame(V2)) {
794 cout << "Vertex Confondus dans CutEdges" << endl;
797 //-------------------------------------------
798 // Copy the edge and restriction by V1 V2.
799 //-------------------------------------------
800 TopoDS_Shape aLocalShape =WE.EmptyCopied();
801 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
802 // TopoDS_Edge NewEdge = TopoDS::Edge(WE.EmptyCopied());
803 B.Add (NewEdge,V1.Oriented(TopAbs_FORWARD));
804 B.Add (NewEdge,V2.Oriented(TopAbs_REVERSED));
808 aLocalShape = V1.Oriented(TopAbs_INTERNAL);
809 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),WE);
810 // U1 = BRep_Tool::Parameter
811 // (TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),WE);
816 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
817 U2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),WE);
818 // U2 = BRep_Tool::Parameter
819 // (TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),WE);
821 B.Range (NewEdge,U1,U2);
822 NE.Append(NewEdge.Oriented(E.Orientation()));
827 //======================== END OF STATIC FUNCTIONS ============
832 //=======================================================================
833 //function : BiTgte_Blend
835 //=======================================================================
837 BiTgte_Blend::BiTgte_Blend()
839 myAsDes = new BRepAlgo_AsDes();
844 //=======================================================================
845 //function : BiTgte_Blend
847 //=======================================================================
849 BiTgte_Blend::BiTgte_Blend(const TopoDS_Shape& S,
850 const Standard_Real Radius,
851 const Standard_Real Tol,
852 const Standard_Boolean NUBS)
854 myAsDes = new BRepAlgo_AsDes();
855 Init(S,Radius,Tol,NUBS);
859 //=======================================================================
862 //=======================================================================
864 void BiTgte_Blend::Init(const TopoDS_Shape& S,
865 const Standard_Real Radius,
866 const Standard_Real Tol,
867 const Standard_Boolean NUBS)
875 // TopExp::MapShapesAndAncestors(S,TopAbs_EDGE,TopAbs_FACE,myAncestors);
879 //=======================================================================
882 //=======================================================================
884 void BiTgte_Blend::Clear()
886 myInitOffsetFace.Clear();
888 myImageOffset .Clear();
889 myStopFaces .Clear();
893 myDone = Standard_False;
897 //=======================================================================
898 //function : SetStoppingFace
900 //=======================================================================
902 void BiTgte_Blend::SetStoppingFace(const TopoDS_Face& Face)
904 myStopFaces.Add(Face);
906 // MAJ SD. -> To end loop, set faces of edges
908 // myInitOffsetFace.SetRoot(Face);
909 // myInitOffsetFace.Bind (Face,Face);
910 // myImageOffset.SetRoot (Face);
914 //=======================================================================
915 //function : SetFaces
917 //=======================================================================
919 void BiTgte_Blend::SetFaces(const TopoDS_Face& F1,const TopoDS_Face& F2)
926 //=======================================================================
929 //=======================================================================
931 void BiTgte_Blend::SetEdge(const TopoDS_Edge& Edge)
937 //=======================================================================
940 //=======================================================================
942 void BiTgte_Blend::Perform(const Standard_Boolean BuildShape)
944 myBuildShape = BuildShape;
946 // Try cutting to avoid tubes on free borders
947 // that are not actually free.
948 Handle(BRepBuilderAPI_Sewing) Sew = new BRepBuilderAPI_Sewing(myTol);
949 BRepLib::BuildCurves3d(myShape);
950 TopExp_Explorer expf(myShape,TopAbs_FACE);
951 for ( ;expf.More(); expf.Next()) Sew->Add(expf.Current());
953 TopoDS_Shape SewedShape = Sew->SewedShape();
954 if ( SewedShape.IsNull()) Standard_Failure::Raise("Sewing aux fraises");
956 // Check if the sewing modified the orientation.
957 expf.Init(myShape,TopAbs_FACE);
958 TopoDS_Face FaceRef = TopoDS::Face(expf.Current());
959 TopAbs_Orientation OriRef = FaceRef.Orientation();
960 if (Sew->IsModified(FaceRef)) FaceRef = TopoDS::Face(Sew->Modified(FaceRef));
961 expf.Init(SewedShape, TopAbs_FACE);
962 for (; expf.More(); expf.Next()) {
963 const TopoDS_Face& FF = TopoDS::Face(expf.Current());
964 if (FaceRef.IsSame(FF) && (FF.Orientation() != OriRef)) {
965 SewedShape.Reverse();
970 // Make SameParameter if Sew does not do it (Detect that edges
971 // are not sameparameter but it does nothing.)
972 expf.Init(SewedShape, TopAbs_EDGE);
973 for (; expf.More(); expf.Next()) {
974 const TopoDS_Edge& sec = TopoDS::Edge(expf.Current());
975 BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
978 TopExp::MapShapesAndAncestors
979 (SewedShape,TopAbs_EDGE,TopAbs_FACE,myAncestors);
981 // Extend myFaces with the faces of the sewed shape.
982 expf.Init(myShape,TopAbs_FACE);
983 for ( ; expf.More(); expf.Next()) {
984 const TopoDS_Shape& F = expf.Current();
985 if ( myFaces.Contains(F) && Sew->IsModified(F)) {
987 TopoDS_Shape LastFace = myFaces(myFaces.Extent());
988 myFaces.RemoveLast();
989 if (myFaces.FindIndex(F) != 0)
990 myFaces.Substitute(myFaces.FindIndex(F), LastFace);
992 myFaces.Add(Sew->Modified(F));
996 myShape = SewedShape;
997 // end Sewing for false free borders.
1000 OSD_Chronometer cl_total, ch;
1001 Standard_Real t_total, t_center, t_surface, t_shape;
1003 t_total=0; t_center=0; t_surface=0; t_mkcurve=0; t_shape=0;
1004 ChFi3d_InitChron(cl_total);
1007 // ----------------------------------------------------------------
1008 // place faces with the proper orientation in the initial shape
1009 // ----------------------------------------------------------------
1010 TopExp_Explorer exp(myShape,TopAbs_FACE);
1011 for ( ; exp.More(); exp.Next()) {
1012 const TopoDS_Shape& F = exp.Current();
1013 if ( myFaces.Contains(F)) {
1014 //myFaces.Remove(F);
1015 TopoDS_Shape LastFace = myFaces(myFaces.Extent());
1016 myFaces.RemoveLast();
1017 if (myFaces.FindIndex(F) != 0)
1018 myFaces.Substitute(myFaces.FindIndex(F), LastFace);
1019 ////////////////////
1022 else if ( myStopFaces.Contains(F)) {
1023 myStopFaces.Remove(F);
1028 // ----------------------------------------------
1029 // Calculate lines of centers and of surfaces
1030 // ----------------------------------------------
1032 ChFi3d_InitChron(ch);
1038 ChFi3d_ResultChron(ch, t_center);
1041 // -----------------------------
1042 // Calculate connection Surfaces
1043 // -----------------------------
1045 ChFi3d_InitChron(ch);
1051 ChFi3d_ResultChron(ch, t_surface);
1054 // ----------------------------------
1055 // Calculate the generated shape if required
1056 // ----------------------------------
1058 ChFi3d_InitChron(ch);
1061 if ( myBuildShape) ComputeShape();
1064 ChFi3d_ResultChron(ch, t_shape);
1067 // Finally construct curves 3d from edges to be transfered
1068 // since the partition is provided ( A Priori);
1069 BRepLib::BuildCurves3d(myResult, Precision::Confusion());
1072 ChFi3d_ResultChron(cl_total, t_total);
1074 cout<<"Blend_PERFORM: temps total "<<t_total<<" s dont :"<<endl;
1075 cout<<"- ComputeCenters "<<t_center<<" s"<<endl;
1076 cout<<"- ComputeSurfaces "<<t_surface<<" s"<<endl;
1077 cout<<"----> MakeCurve "<<t_mkcurve<<" s"<<endl;
1078 if ( myBuildShape) cout<<"- ComputeShape "<<t_shape<<" s"<<endl;
1081 myDone = Standard_True;
1085 //=======================================================================
1088 //=======================================================================
1090 Standard_Boolean BiTgte_Blend::IsDone() const
1095 //=======================================================================
1098 //=======================================================================
1100 const TopoDS_Shape& BiTgte_Blend::Shape() const
1106 //=======================================================================
1107 //function : NbSurfaces
1109 //=======================================================================
1111 Standard_Integer BiTgte_Blend::NbSurfaces() const
1113 return myCenters.Extent();
1117 //=======================================================================
1118 //function : Surface
1120 //=======================================================================
1122 Handle(Geom_Surface) BiTgte_Blend::Surface(const Standard_Integer Index) const
1124 return Surface(myCenters(Index));
1127 //=======================================================================
1128 //function : TopoDS_Face&
1130 //=======================================================================
1132 const TopoDS_Face& BiTgte_Blend::Face(const Standard_Integer Index) const
1134 return Face(myCenters(Index));
1139 //=======================================================================
1140 //function : CenterLines
1142 //=======================================================================
1144 void BiTgte_Blend::CenterLines(TopTools_ListOfShape& LC) const
1147 Standard_Integer Nb = NbSurfaces();
1148 for ( Standard_Integer i = 1; i <= Nb; i++)
1149 LC.Append(myCenters(i));
1153 //=======================================================================
1154 //function : Surface
1156 //=======================================================================
1158 Handle(Geom_Surface) BiTgte_Blend::Surface(const TopoDS_Shape& CenterLine)
1161 const TopoDS_Face& F = myMapSF(CenterLine).Face();
1162 return BRep_Tool::Surface(F);
1165 //=======================================================================
1166 //function : TopoDS_Face&
1168 //=======================================================================
1170 const TopoDS_Face& BiTgte_Blend::Face(const TopoDS_Shape& CenterLine) const
1172 if ( !myMapSF.IsBound(CenterLine)) {
1173 Standard_DomainError::Raise("BiTgte_Blend::Face");
1176 return myMapSF(CenterLine).Face();
1179 //=======================================================================
1180 //function : ContactType
1182 //=======================================================================
1184 BiTgte_ContactType BiTgte_Blend::ContactType(const Standard_Integer Index)
1187 const TopoDS_Shape& S1 = SupportShape1(Index);
1188 const TopoDS_Shape& S2 = SupportShape2(Index);
1190 TopAbs_ShapeEnum Type1 = S1.ShapeType();
1191 TopAbs_ShapeEnum Type2 = S2.ShapeType();
1193 if (Type2 < Type1) {
1194 TopAbs_ShapeEnum Dummy = Type1;
1198 BiTgte_ContactType Type = BiTgte_VertexVertex;
1204 case TopAbs_VERTEX: Type = BiTgte_VertexVertex; break;
1205 case TopAbs_EDGE: Type = BiTgte_EdgeVertex; break;
1206 case TopAbs_FACE: Type = BiTgte_FaceVertex; break;
1213 case TopAbs_EDGE: Type = BiTgte_EdgeEdge; break;
1214 case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
1221 case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
1234 //=======================================================================
1235 //function : SupportShape1
1237 //=======================================================================
1239 const TopoDS_Shape& BiTgte_Blend::SupportShape1(const Standard_Integer Index)
1242 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1244 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1246 // --------------------------------------------------------------
1247 // F1 and F2 = 2 parallel faces intersecting at CurE.
1248 // --------------------------------------------------------------
1249 const TopoDS_Face& F1 = TopoDS::Face(L.First());
1250 const TopoDS_Shape& Or1 = myInitOffsetFace.ImageFrom(F1);
1255 //=======================================================================
1256 //function : SupportShape2
1258 //=======================================================================
1260 const TopoDS_Shape& BiTgte_Blend::SupportShape2(const Standard_Integer Index)
1263 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1265 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1267 // --------------------------------------------------------------
1268 // F1 and F2 = 2 parallel faces intersecting at CurE.
1269 // --------------------------------------------------------------
1270 const TopoDS_Face& F2 = TopoDS::Face(L.Last());
1271 const TopoDS_Shape& Or2 = myInitOffsetFace.ImageFrom(F2);
1276 //=======================================================================
1277 //function : CurveOnShape1
1279 //=======================================================================
1281 Handle(Geom_Curve) BiTgte_Blend::CurveOnShape1
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 Shape1.
1290 TopExp_Explorer exp(F,TopAbs_EDGE);
1291 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1292 Handle(Geom_Curve) C;
1293 if ( !BRep_Tool::Degenerated(E)) {
1295 C = BRep_Tool::Curve(E,f,l);
1296 C = new Geom_TrimmedCurve(C,f,l);
1302 //=======================================================================
1303 //function : CurveOnShape2
1305 //=======================================================================
1307 Handle(Geom_Curve) BiTgte_Blend::CurveOnShape2
1308 (const Standard_Integer Index) const
1310 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1311 const TopoDS_Shape& F = myMapSF(CurE).Face();
1313 // somewhat brutal method based ONLY on the construction of the fillet:
1314 // the first edge of the tube is exactly the edge on Shape2.
1316 TopExp_Explorer exp(F,TopAbs_EDGE);
1318 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1319 Handle(Geom_Curve) C;
1320 if ( !BRep_Tool::Degenerated(E)) {
1322 C = BRep_Tool::Curve(E,f,l);
1323 C = new Geom_TrimmedCurve(C,f,l);
1329 //=======================================================================
1330 //function : PCurveOnFace1
1332 //=======================================================================
1334 Handle(Geom2d_Curve) BiTgte_Blend::PCurveOnFace1
1335 (const Standard_Integer /*Index*/) const
1337 Handle(Geom2d_Curve) C;
1342 //=======================================================================
1343 //function : PCurve1OnFillet
1345 //=======================================================================
1347 Handle(Geom2d_Curve) BiTgte_Blend::PCurve1OnFillet
1348 (const Standard_Integer /*Index*/) const
1350 Handle(Geom2d_Curve) C;
1355 //=======================================================================
1356 //function : PCurveOnFace2
1358 //=======================================================================
1360 Handle(Geom2d_Curve) BiTgte_Blend::PCurveOnFace2
1361 (const Standard_Integer /*Index*/) const
1363 Handle(Geom2d_Curve) C;
1368 //=======================================================================
1369 //function : Curve2OnFillet
1371 //=======================================================================
1373 Handle(Geom2d_Curve) BiTgte_Blend::PCurve2OnFillet
1374 (const Standard_Integer /*Index*/) const
1376 Handle(Geom2d_Curve) C;
1382 //=======================================================================
1383 //function : NbBranches
1385 //=======================================================================
1387 Standard_Integer BiTgte_Blend::NbBranches()
1389 if (myNbBranches != -1) return myNbBranches;
1391 // else, compute the Branches.
1392 BRepTools_Quilt Glue;
1394 Standard_Integer NbFaces = myCenters.Extent();
1397 if (NbFaces == 0) return 0;
1401 for ( i = 1; i <= NbFaces; i++) {
1402 const TopoDS_Shape& CenterLine = myCenters(i);
1403 Glue.Add(myMapSF(CenterLine).Face());
1406 const TopoDS_Shape Shells = Glue.Shells();
1409 // Reorder Map myCenters.
1410 // The method is brutal and unpolished,
1411 // it is possible to refine it.
1413 TopTools_IndexedMapOfShape tmpMap;
1415 TopExp_Explorer exp(Shells,TopAbs_SHELL);
1416 for (; exp.More(); exp.Next()) {
1420 myIndices = new TColStd_HArray1OfInteger(1,myNbBranches+1);
1422 myIndices->SetValue(1,0);
1423 Standard_Integer Count = 0;
1424 Standard_Integer Index = 2;
1427 exp.Init(Shells,TopAbs_SHELL);
1428 for (; exp.More(); exp.Next()) {
1429 // CurS = the current Shell.
1430 const TopoDS_Shape CurS = exp.Current();
1432 TopExp_Explorer exp2(CurS, TopAbs_FACE);
1433 for (; exp2.More(); exp2.Next()) {
1434 // CurF = the current face of the current Shell.
1435 const TopoDS_Shape CurF = exp2.Current();
1437 for ( i = 1; i <= NbFaces; i++) {
1438 const TopoDS_Shape& Center = myCenters(i);
1439 const TopoDS_Shape& Rakk = myMapSF(Center).Face();
1440 // Rakk = the ith generated connection face
1441 if (CurF.IsEqual(Rakk)) {
1448 myIndices->SetValue(Index, Count);
1453 return myNbBranches;
1457 //=======================================================================
1458 //function : IndicesOfBranche
1460 //=======================================================================
1462 void BiTgte_Blend::IndicesOfBranche
1463 (const Standard_Integer Index,
1464 Standard_Integer& From,
1465 Standard_Integer& To ) const
1467 // Attention to the ranking in myIndices:
1468 // If the branches are 1-4 5-9 10-12, it is ranked in myIndices:
1470 From = myIndices->Value(Index) + 1;
1471 To = myIndices->Value(Index + 1);
1475 //=======================================================================
1476 //function : ComputeCenters
1478 //=======================================================================
1480 void BiTgte_Blend::ComputeCenters()
1485 Standard_Real TolAngle = 2*ASin(myTol/Abs(myRadius*0.5));
1486 myAnalyse.Perform(myShape,TolAngle);
1488 // ------------------------------------------
1489 // calculate faces touched by caps
1490 // ------------------------------------------
1491 TopTools_MapOfShape TouchedByCork;
1492 Touched(myAnalyse, myStopFaces, myShape, TouchedByCork);
1494 // -----------------------
1495 // init of the intersector
1496 // -----------------------
1497 TopAbs_State Side = TopAbs_IN;
1498 if (myRadius < 0.) Side = TopAbs_OUT;
1499 BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
1501 BiTgte_DataMapOfShapeBox MapSBox;
1502 TopTools_MapOfShape Done;
1503 //TopTools_MapIteratorOfMapOfShape it;
1506 TopoDS_Compound Co; // to only know on which edges the tubes are made
1509 // ----------------------------------------
1510 // Calculate Sections Face/Face + Propagation
1511 // ----------------------------------------
1512 Standard_Boolean JenRajoute = Standard_True;
1515 while ( JenRajoute) {
1516 JenRajoute = Standard_False;
1518 Standard_Boolean Fini = Standard_False;
1520 TopTools_DataMapOfShapeShape EdgeTgt;
1524 // -------------------------------------------------
1525 // locate in myFaces the Faces connected to myEdges.
1526 // -------------------------------------------------
1527 Fini = Standard_True;
1528 //for (it.Initialize(myEdges); it.More(); it.Next()) {
1529 for (i = 1; i <= myEdges.Extent(); i++) {
1530 const TopoDS_Edge& E = TopoDS::Edge(myEdges(i));
1531 if (BRep_Tool::Degenerated(E)) continue;
1533 const TopTools_ListOfShape& L = myAncestors.FindFromKey(E);
1534 if ( L.Extent() == 1) {
1535 // So this is a free border onwhich the ball should roll.
1538 // set in myStopFaces to not propagate the tube on free border.
1542 TopTools_ListIteratorOfListOfShape itl;
1543 for (itl.Initialize(L); itl.More(); itl.Next()) {
1544 const TopoDS_Shape& Sh = itl.Value();
1545 if ( !myStopFaces.Contains(Sh)) myFaces.Add(itl.Value());
1551 // --------------------------------------------
1552 // Construction of Offsets of all faces.
1553 // --------------------------------------------
1554 //for (it.Initialize(myFaces); it.More(); it.Next()) {
1555 for (i = 1; i <= myFaces.Extent(); i++) {
1556 const TopoDS_Shape& AS = myFaces(i);
1557 if ( myMapSF.IsBound(AS)) continue;
1559 BRepOffset_Offset OF1;
1562 if (AS.ShapeType() == TopAbs_FACE) {
1563 const TopoDS_Face& F = TopoDS::Face(myFaces(i));
1564 if ( TouchedByCork.Contains(F)) {
1565 BRepOffset_Tool::EnLargeFace(F,BigF,Standard_True);
1566 OF1.Init(BigF,myRadius,EdgeTgt);
1569 OF1.Init(F,myRadius,EdgeTgt);
1572 else { // So this is a Free Border edge on which the ball rolls.
1573 OF1.Init(TopoDS::Edge(AS),myRadius);
1576 // ------------------------------------
1577 // Increment the map of created tangents
1578 // ------------------------------------
1579 TopTools_ListOfShape Let;
1580 if ( AS.ShapeType() == TopAbs_FACE) {
1581 myAnalyse.Edges(TopoDS::Face(AS),BRepOffset_Tangent,Let);
1583 TopTools_ListIteratorOfListOfShape itlet(Let);
1585 for ( ; itlet.More(); itlet.Next()) {
1586 const TopoDS_Edge& Cur = TopoDS::Edge(itlet.Value());
1587 if ( !EdgeTgt.IsBound(Cur)) {
1588 TopoDS_Shape aLocalShape = OF1.Generated(Cur);
1589 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
1590 // const TopoDS_Edge& OTE = TopoDS::Edge(OF1.Generated(Cur));
1591 EdgeTgt.Bind(Cur,OF1.Generated(Cur));
1592 TopoDS_Vertex V1,V2,OV1,OV2;
1593 TopExp::Vertices (Cur,V1,V2);
1594 TopExp::Vertices (OTE,OV1,OV2);
1595 TopTools_ListOfShape LE;
1596 if (!EdgeTgt.IsBound(V1)) {
1597 myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
1598 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V1);
1599 if (LE.Extent() == LA.Extent())
1600 EdgeTgt.Bind(V1,OV1);
1602 if (!EdgeTgt.IsBound(V2)) {
1604 myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
1605 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V2);
1606 if (LE.Extent() == LA.Extent())
1607 EdgeTgt.Bind(V2,OV2);
1611 // end of map created tangent
1613 if (OF1.Status() == BRepOffset_Reversed ||
1614 OF1.Status() == BRepOffset_Degenerated ) continue;
1616 const TopoDS_Face& F1 = OF1.Face();
1619 myInitOffsetFace.SetRoot(AS);
1620 myInitOffsetFace.Bind(AS,F1);
1623 BRepBndLib::Add(F1,Box1);
1624 MapSBox.Bind(F1,Box1);
1626 // ---------------------------------------------
1627 // intersection with all already created faces.
1628 // ---------------------------------------------
1629 Fini = !Intersect(AS,F1,MapSBox,OF1,Inter);
1631 if (AS.ShapeType() == TopAbs_FACE) B.Add(Co,AS);
1633 myMapSF.Bind(AS, OF1);
1636 } // end of : while ( !Fini)
1639 //--------------------------------------------------------
1640 // so the offsets were created and intersected.
1641 // now the tubes are constructed.
1642 //--------------------------------------------------------
1643 // Construction of tubes on edge.
1644 //--------------------------------------------------------
1645 BRepOffset_Type OT = BRepOffset_Convex;
1646 if (myRadius < 0.) OT = BRepOffset_Concave;
1648 TopTools_IndexedDataMapOfShapeListOfShape Map;
1649 TopExp::MapShapesAndAncestors(Co,TopAbs_EDGE,TopAbs_FACE,Map);
1650 TopExp::MapShapesAndAncestors(Co,TopAbs_VERTEX,TopAbs_EDGE,Map);
1652 TopExp_Explorer exp(Co,TopAbs_EDGE);
1653 for ( ; exp.More(); exp.Next()) {
1654 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1655 if ( myMapSF.IsBound(E)) continue;
1657 const TopTools_ListOfShape& Anc = Map.FindFromKey(E);
1658 if (Anc.Extent() == 2) {
1659 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1660 if (!L.IsEmpty() && L.First().Type() == OT) {
1661 TopoDS_Shape aLocalShape = myMapSF(Anc.First()).Generated(E);
1662 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1663 aLocalShape = myMapSF(Anc.Last()) .Generated(E);
1664 TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
1665 // TopoDS_Edge EOn1 = TopoDS::Edge(myMapSF(Anc.First()).Generated(E));
1666 // TopoDS_Edge EOn2 = TopoDS::Edge(myMapSF(Anc.Last()) .Generated(E));
1667 // find if exits tangent edges in the original shape
1668 TopoDS_Edge E1f, E1l;
1669 TopoDS_Vertex V1f, V1l;
1670 TopExp::Vertices(E,V1f,V1l);
1671 TopTools_ListOfShape TangE;
1672 myAnalyse.TangentEdges(E,V1f,TangE);
1673 // find if the pipe on the tangent edges are soon created.
1674 TopTools_ListIteratorOfListOfShape itl(TangE);
1675 Standard_Boolean Find = Standard_False;
1676 for ( ; itl.More() && !Find; itl.Next()) {
1677 if ( myMapSF.IsBound(itl.Value())) {
1678 TopoDS_Shape aLocalShape = myMapSF(itl.Value()).Generated(V1f);
1679 E1f = TopoDS::Edge(aLocalShape);
1680 // E1f = TopoDS::Edge(myMapSF(itl.Value()).Generated(V1f));
1681 Find = Standard_True;
1685 myAnalyse.TangentEdges(E,V1l,TangE);
1686 // find if the pipe on the tangent edges are soon created.
1687 itl.Initialize(TangE);
1688 Find = Standard_False;
1689 for ( ; itl.More() && !Find; itl.Next()) {
1690 if ( myMapSF.IsBound(itl.Value())) {
1691 TopoDS_Shape aLocalShape = myMapSF(itl.Value()).Generated(V1l);
1692 E1l = TopoDS::Edge(aLocalShape);
1693 // E1l = TopoDS::Edge(myMapSF(itl.Value()).Generated(V1l));
1694 Find = Standard_True;
1697 BRepOffset_Offset OF1 (E,EOn1,EOn2,myRadius,E1f, E1l);
1698 const TopoDS_Face& F1 = OF1.Face();
1701 myInitOffsetFace.SetRoot(E);
1702 myInitOffsetFace.Bind(E,F1);
1705 BRepBndLib::Add(F1,Box1);
1706 MapSBox.Bind(F1,Box1);
1708 // ---------------------------------------------
1709 // intersection with all already created faces.
1710 // ---------------------------------------------
1711 Standard_Boolean IsOnRest = Intersect(E,F1,MapSBox,OF1,Inter);
1712 JenRajoute = JenRajoute || IsOnRest;
1714 myMapSF.Bind(E,OF1);
1719 } // end while JenRajoute
1723 myEdges = Inter.NewEdges();
1725 // -------------------------------------------------------------------
1726 // now it is necessary to limit edges on the neighbors (otherwise one
1727 // will go too far and will not be able to construct faces).
1728 // -------------------------------------------------------------------
1730 // Proceed with MakeLoops
1732 BRepOffset_Type OT = BRepOffset_Concave;
1733 if (myRadius < 0.) OT = BRepOffset_Convex;
1735 TopTools_ListOfShape LOF;
1736 //it.Initialize(myFaces);
1737 for (i = 1; i <= myFaces.Extent(); i++) {
1738 const TopoDS_Shape& CurS = myFaces(i);
1740 // tube on free border, it is undesirable.
1741 if ( myStopFaces.Contains(CurS)) continue;
1743 if ( !myMapSF.IsBound(CurS)) continue; // inverted or degenerated
1745 const TopoDS_Face& CurOF = myMapSF(CurS).Face();
1748 if (CurS.ShapeType() == TopAbs_FACE) {
1749 const TopoDS_Face& CurF = TopoDS::Face(CurS);
1750 TopExp_Explorer expe(CurF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1751 for (; expe.More(); expe.Next()) {
1752 // --------------------------------------------------------------
1753 // set in myAsDes the edges generated by limitations of the
1754 // initial square if the type is correct (The edges that will
1755 // disappear are not set)
1756 // --------------------------------------------------------------
1757 const TopoDS_Edge& CurE = TopoDS::Edge(expe.Current());
1758 const BRepOffset_ListOfInterval& L = myAnalyse.Type(CurE);
1759 if (!L.IsEmpty() && L.First().Type() != OT) {
1760 // a priori doe s not disappear, so it is set
1761 TopoDS_Shape aLocalShape = myMapSF(CurF).Generated(CurE);
1762 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
1763 // const TopoDS_Edge& CurOE =
1764 // TopoDS::Edge(myMapSF(CurF).Generated(CurE));
1765 myAsDes->Add(CurOF,CurOE.Oriented(CurE.Orientation()));
1768 const TopTools_ListOfShape& Lanc = myAnalyse.Ancestors(CurE);
1769 if ( !myFaces .Contains(Lanc.First())
1770 || !myFaces .Contains(Lanc.Last ())
1771 || myStopFaces.Contains(Lanc.First())
1772 || myStopFaces.Contains(Lanc.Last ())) {
1773 TopoDS_Shape aLocalShape = myMapSF(CurF).Generated(CurE);
1774 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
1775 // const TopoDS_Edge& CurOE =
1776 // TopoDS::Edge(myMapSF(CurF).Generated(CurE));
1777 myAsDes->Add(CurOF,CurOE.Oriented(CurE.Orientation()));
1781 BRepOffset_Inter2d::Compute(myAsDes,
1788 // ----------------------------------------------------------------
1789 // It is also required to make 2D intersections with generated tubes
1790 // (Useful for unwinding)
1791 // ----------------------------------------------------------------
1792 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(myMapSF);
1793 for ( ; It.More(); It.Next()) {
1794 const TopoDS_Shape& CurS = It.Key();
1795 if ( CurS.ShapeType() == TopAbs_FACE) continue;
1797 const TopoDS_Face& CurOF = It.Value().Face();
1799 // no unwinding by tubes on free border.
1800 if ( myStopFaces.Contains(CurS)) continue;
1804 // --------------------------------------------------------------
1805 // set in myAsDes the edge restrictions of the square
1806 // --------------------------------------------------------------
1807 TopExp_Explorer expe(CurOF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1808 for (; expe.More(); expe.Next()) {
1809 const TopoDS_Edge& CurOE = TopoDS::Edge(expe.Current());
1810 myAsDes->Add(CurOF,CurOE);
1813 BRepOffset_Inter2d::Compute(myAsDes,
1821 BRepOffset_MakeLoops MakeLoops;
1822 MakeLoops.Build( LOF, myAsDes, myImageOffset );
1824 // ------------------------------------------------------------
1825 // It is possible to unwind edges at least one ancestor which of
1826 // is a face of the initial shape, so:
1827 // the edges generated by intersection tube-tube are missing
1828 // ------------------------------------------------------------
1830 // --------------------------------------------------------------
1831 // Currently set the unwinded surfaces in <myResult>
1832 // --------------------------------------------------------------
1833 B.MakeCompound(TopoDS::Compound(myResult));
1834 TopTools_ListIteratorOfListOfShape itLOF(LOF);
1835 for ( ; itLOF.More(); itLOF.Next()) {
1836 const TopoDS_Shape& CurLOF = itLOF.Value();
1838 if ( !myImageOffset.HasImage(CurLOF))
1841 TopTools_ListOfShape Lim;
1842 myImageOffset.LastImage(CurLOF,Lim);
1843 TopTools_ListIteratorOfListOfShape itLim(Lim);
1844 for ( ;itLim.More(); itLim.Next()) {
1845 // If a face is its own image, it is not set
1846 const TopoDS_Shape& CurLIM = itLim.Value();
1847 if (CurLIM.IsSame(CurLOF)) break;
1849 B.Add(myResult,CurLIM);
1854 if ( myResult.IsNull()) {
1855 cout << " No Lines of Generated Centers" << endl;
1859 if (Affich) DBRep::Set("Unwind",myResult);
1866 //=======================================================================
1867 //function : ComputeSurfaces
1869 //=======================================================================
1871 void BiTgte_Blend::ComputeSurfaces()
1873 // set in myFaces, the faces actually implied in the connection
1877 // 1 - Tubes (True Fillets)
1881 Standard_Integer nbc = 1;
1884 TopTools_ListOfShape Empty;
1885 TopTools_DataMapOfShapeListOfShape EmptyMap;
1887 Handle(Geom_Surface) GS1, GS2;
1888 Handle(Geom_Curve) GC1, GC2;
1890 Standard_Real TolAngle = 2*ASin(myTol/Abs(myRadius*0.5));
1891 BRepOffset_Analyse CenterAnalyse(myResult,TolAngle);
1893 // -----------------------------------------------------
1894 // Construction of tubes in myResult
1895 // -----------------------------------------------------
1897 B.MakeCompound(TopoDS::Compound(myResult));
1899 // --------------------------------------------------------------------
1900 // Dummy: for construction of spheres:
1901 // Set in Co the center line, then it there are at least 3
1902 // center lines sharing the same vertex, Sphere on this vertex.
1903 // --------------------------------------------------------------------
1907 // --------------------------------------------------------------------
1908 // Iteration on the edges lines of center
1909 // and their valid valid part is taken after cut and tube construction.
1910 // --------------------------------------------------------------------
1911 BRepOffset_Type OT = BRepOffset_Concave;
1912 if (myRadius < 0.) OT = BRepOffset_Convex;
1914 //TopTools_MapIteratorOfMapOfShape ic(myEdges);
1916 for (i = 1; i <= myEdges.Extent(); i++) {
1917 const TopoDS_Edge& CurE = TopoDS::Edge(myEdges(i));
1919 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1920 if ( L.Extent() != 2) continue;
1922 // --------------------------------------------------------------
1923 // F1 and F2 = 2 parallel faces intersecting in CurE.
1924 // --------------------------------------------------------------
1925 const TopoDS_Face& F1 = TopoDS::Face(L.First());
1926 const TopoDS_Face& F2 = TopoDS::Face(L.Last());
1928 // -----------------------------------------------------
1929 // find the orientation of edges of intersection
1930 // in the initial faces.
1931 // -----------------------------------------------------
1932 const TopTools_ListOfShape& LD1 = myAsDes->Descendant(F1);
1933 const TopTools_ListOfShape& LD2 = myAsDes->Descendant(F2);
1935 TopAbs_Orientation Orien1 = Orientation(CurE, F1, LD1);
1936 TopAbs_Orientation Orien2 = Orientation(CurE, F2, LD2);
1938 // ---------------------------------------------------------
1939 // Or1 and Or2 : the shapes generators of parallel faces
1940 // ---------------------------------------------------------
1941 const TopoDS_Shape& Or1 = myInitOffsetFace.ImageFrom(F1);
1942 const TopoDS_Shape& Or2 = myInitOffsetFace.ImageFrom(F2);
1947 TopoDS_Edge OE1, OE2;
1948 TopoDS_Face OF1, OF2;
1949 TopLoc_Location Loc;
1950 Standard_Real f1,l1,f2,l2;
1952 Standard_Boolean OF1isEdge = Standard_False;
1954 if ( Or1.ShapeType() == TopAbs_EDGE) {
1955 OF1isEdge = Standard_True;
1956 OE1 = TopoDS::Edge(Or1);
1957 GC1 = BRep_Tool::Curve(OE1,Loc,f1,l1);
1959 Handle(Geom_Curve)::DownCast(GC1->Transformed(Loc.Transformation()));
1961 else if ( Or1.ShapeType() == TopAbs_FACE) {
1962 OF1 = TopoDS::Face(Or1);
1963 GS1 = BRep_Tool::Surface(OF1);
1966 // ----------------------------------------------------------------
1967 // If a vertex is used in contact, currently nothing is done
1968 // and the vertexes are not managed (Intersections with sphere);
1969 // ----------------------------------------------------------------
1970 if ( OF1.IsNull() && OE1.IsNull()) continue;
1972 Standard_Boolean OF2isEdge = Standard_False;
1974 if ( Or2.ShapeType() == TopAbs_EDGE) {
1975 OF2isEdge = Standard_True;
1976 OE2 = TopoDS::Edge(Or2);
1977 GC2 = BRep_Tool::Curve(OE2,Loc,f2,l2);
1979 Handle(Geom_Curve)::
1980 DownCast(GC2->Transformed(Loc.Transformation()));
1982 else if ( Or2.ShapeType() == TopAbs_FACE) {
1983 OF2 = TopoDS::Face(Or2);
1984 GS2 = BRep_Tool::Surface(OF2);
1986 // ----------------------------------------------------------------
1987 // If a vertex is used in contact, currently nothing is done
1988 // and the vertexes are not managed (Intersections with sphere);
1989 // ----------------------------------------------------------------
1990 if ( OF2.IsNull() && OE2.IsNull()) continue;
1993 TopTools_ListOfShape CurL;
1995 if ( !myImageOffset.HasImage(CurE)) {// the tubes are not unwinded
1996 if ( OF1isEdge && OF2isEdge) { // if I don't have the image, possibly
1997 CurL.Append(CurE); // I'm on intersection tube-tube
1998 } // See comment on the call to
2003 myImageOffset.LastImage(CurE,CurL);
2006 // ---------------------------------------------------------------
2007 // CurL = List of edges descending from CurE ( = Cuts of CurE)
2008 // ---------------------------------------------------------------
2009 TopTools_ListIteratorOfListOfShape itl(CurL);
2010 for ( ; itl.More(); itl.Next()) {
2011 const TopoDS_Edge& CurCutE = TopoDS::Edge(itl.Value());
2013 Handle(Geom2d_Curve) PC1 =
2014 BRep_Tool::CurveOnSurface(CurCutE,F1,f1,l1);
2015 Handle(Geom2d_Curve) PC2 =
2016 BRep_Tool::CurveOnSurface(CurCutE,F2,f2,l2);
2017 if ( PC1.IsNull() || PC2.IsNull()) {
2019 cout << "No PCurves on Intersections : No tubes constructed";
2025 TopoDS_Edge E1f, E1l;
2026 TopoDS_Vertex V1f, V1l;
2027 TopoDS_Vertex VfOnE1,VlOnE1,VfOnE2,VlOnE2;
2028 TopTools_ListOfShape TangE;
2029 TopTools_MapOfShape MapOnV1f, MapOnV1l;
2031 TopExp::Vertices(CurCutE,V1f,V1l);
2033 // find if the pipe on the tangent edges are soon created.
2034 // edges generated by V1f and V1l + Maj MapOnV1f/l
2035 E1f = FindCreatedEdge(V1f,CurCutE,myMapSF,MapOnV1f,
2036 CenterAnalyse,myRadius,myTol);
2038 E1l = FindCreatedEdge(V1l,CurCutE,myMapSF,MapOnV1l,
2039 CenterAnalyse,myRadius,myTol);
2043 BiTgte_CurveOnEdge ConE(CurCutE, OE1);
2044 Handle(Geom_Curve) C = MakeCurve(ConE);
2045 gp_Pnt P1 = C->Value(C->FirstParameter());
2046 gp_Pnt P2 = C->Value(C->LastParameter());
2047 VfOnE1 = FindVertex(P1,MapOnV1f,myTol);
2048 if ( VfOnE1.IsNull())
2049 VfOnE1 = FindVertex(P1,MapOnV1l,myTol);
2050 VlOnE1 = FindVertex(P2,MapOnV1l,myTol);
2051 if ( VlOnE1.IsNull())
2052 VlOnE1 = FindVertex(P2,MapOnV1f,myTol);
2053 if ( P1.SquareDistance(P2) < myTol*myTol) {
2054 //BRepOffset_Offset manages degenerated KPart
2055 //It is REQUIRED that C should be a circle with ZERO radius
2056 E1 = MakeDegeneratedEdge(C,VfOnE1);
2059 E1 = BRepLib_MakeEdge(C,VfOnE1,VlOnE1);
2064 P2d = PC1->Value(f1);
2065 gp_Pnt P1 = GS1->Value(P2d.X(),P2d.Y());
2066 P2d = PC1->Value(l1);
2067 gp_Pnt P2 = GS1->Value(P2d.X(),P2d.Y());
2068 VfOnE1 = FindVertex(P1,MapOnV1f,myTol);
2069 VlOnE1 = FindVertex(P2,MapOnV1l,myTol);
2070 BRepLib_MakeEdge MKE(PC1,GS1,VfOnE1,VlOnE1,f1,l1);
2074 cout << "Edge Not Done" << endl;
2078 KPartCurve3d(E1,PC1,GS1);
2082 BiTgte_CurveOnEdge ConE(CurCutE, OE2);
2083 Handle(Geom_Curve) C = MakeCurve(ConE);
2084 gp_Pnt P1 = C->Value(C->FirstParameter());
2085 gp_Pnt P2 = C->Value(C->LastParameter());
2086 VfOnE2 = FindVertex(P1,MapOnV1f,myTol);
2087 if ( VfOnE2.IsNull())
2088 VfOnE2 = FindVertex(P1,MapOnV1l,myTol);
2089 VlOnE2 = FindVertex(P2,MapOnV1l,myTol);
2090 if ( VlOnE2.IsNull())
2091 VlOnE2 = FindVertex(P2,MapOnV1f,myTol);
2092 if ( P1.SquareDistance(P2) < myTol*myTol) {
2093 //BRepOffset_Offset manages degenerated KParts
2094 //It is REQUIRED that C should be a circle with ZERO radius
2095 E2 = MakeDegeneratedEdge(C,VfOnE2);
2098 E2 = BRepLib_MakeEdge(C,VfOnE2,VlOnE2);
2103 P2d = PC2->Value(f2);
2104 gp_Pnt P1 = GS2->Value(P2d.X(),P2d.Y());
2105 P2d = PC2->Value(l2);
2106 gp_Pnt P2 = GS2->Value(P2d.X(),P2d.Y());
2107 VfOnE2 = FindVertex(P1,MapOnV1f,myTol);
2108 VlOnE2 = FindVertex(P2,MapOnV1l,myTol);
2109 BRepLib_MakeEdge MKE(PC2,GS2,VfOnE2,VlOnE2,f2,l2);
2113 cout << "edge not Done" << endl;
2116 KPartCurve3d(E2,PC2,GS2);
2118 // Increment of the Map of Created if reconstruction of the Shape is required
2119 if ( myBuildShape) {
2120 myCreated.Bind(CurCutE,EmptyMap);
2122 myCreated(CurCutE).Bind(Or1,Empty);
2123 myCreated(CurCutE)(Or1).Append(E1);
2125 myCreated(CurCutE).Bind(Or2,Empty);
2126 myCreated(CurCutE)(Or2).Append(E2);
2129 // ----------------------------------------------------------
2130 // try to init E1f, E1l, if not found with Analysis.
2131 // Should happen only if the THEORETICALLY tangent edges
2132 // are not actually tangent ( Cf: Approximation of lines
2133 // of intersection that add noise.)
2134 // ----------------------------------------------------------
2135 TopoDS_Vertex V1,V2;
2136 if ( E1f.IsNull() && !VfOnE1.IsNull() && !VfOnE2.IsNull()) {
2137 TopTools_MapIteratorOfMapOfShape it(MapOnV1f);
2138 for ( ; it.More(); it.Next()) {
2139 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
2141 TopExp::Vertices(E,V1,V2);
2142 if ((V1.IsSame(VfOnE1) && V2.IsSame(VfOnE2)) ||
2143 (V2.IsSame(VfOnE1) && V1.IsSame(VfOnE2)) ) {
2150 if ( E1l.IsNull() && !VlOnE1.IsNull() && !VlOnE2.IsNull()) {
2151 TopTools_MapIteratorOfMapOfShape it(MapOnV1l);
2152 for ( ; it.More(); it.Next()) {
2153 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
2155 TopExp::Vertices(E,V1,V2);
2156 if ((V1.IsSame(VlOnE1) && V2.IsSame(VlOnE2)) ||
2157 (V2.IsSame(VlOnE1) && V1.IsSame(VlOnE2)) ) {
2165 E1.Orientation(Orien1);
2166 E2.Orientation(Orien2);
2168 BRepOffset_Offset AnOffset(CurCutE,E1,E2,-myRadius,E1f,E1l,
2169 myNubs, myTol, GeomAbs_C2);
2170 myMapSF.Bind(CurCutE,AnOffset);
2171 myCenters.Add(CurCutE);
2174 const TopoDS_Face& Tuyo = AnOffset.Face();
2175 B.Add(myResult,Tuyo);
2177 if ( myBuildShape) {
2178 // method based ONLY on the construction of fillet:
2179 // the first edge of the tube is exactly on Shape1.
2180 GeomAPI_ProjectPointOnCurve Projector;
2181 TopExp_Explorer exp(Tuyo,TopAbs_EDGE);
2182 TopoDS_Vertex V1,V2;
2183 if (OF1isEdge) { // Update CutEdges.
2184 const TopoDS_Edge& EOnF1 = TopoDS::Edge(exp.Current());
2185 TopExp::Vertices(EOnF1,V1,V2);
2187 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2188 Projector.Init(P1,GC1);
2189 Standard_Real U1 = Projector.LowerDistanceParameter();
2191 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2192 Projector.Init(P2,GC1);
2193 Standard_Real U2 = Projector.LowerDistanceParameter();
2195 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
2196 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,TopoDS::Edge(Or1),myTol);
2197 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
2198 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,TopoDS::Edge(Or1),myTol);
2199 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),U1,
2200 // TopoDS::Edge(Or1),myTol);
2201 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),U2,
2202 // TopoDS::Edge(Or1),myTol);
2204 if (!myCutEdges.IsBound(Or1)) {
2205 TopTools_ListOfShape Dummy;
2206 myCutEdges.Bind(Or1,Dummy);
2208 TopTools_ListOfShape& L1 = myCutEdges(Or1);
2209 L1.Append(V1); L1.Append(V2);
2211 if (OF2isEdge) { // Update CutEdges.
2213 const TopoDS_Edge& EOnF2 = TopoDS::Edge(exp.Current());
2214 TopExp::Vertices(EOnF2,V1,V2);;
2216 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2217 Projector.Init(P1,GC2);
2218 Standard_Real U1 = Projector.LowerDistanceParameter();
2220 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2221 Projector.Init(P2,GC2);
2222 Standard_Real U2 = Projector.LowerDistanceParameter();
2224 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
2225 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,TopoDS::Edge(Or2),myTol);
2226 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
2227 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,TopoDS::Edge(Or2),myTol);
2228 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),U1,
2229 // TopoDS::Edge(Or2),myTol);
2230 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),U2,
2231 // TopoDS::Edge(Or2),myTol);
2233 if (!myCutEdges.IsBound(Or2)) {
2234 TopTools_ListOfShape Dummy;
2235 myCutEdges.Bind(Or2,Dummy);
2237 TopTools_ListOfShape& L2 = myCutEdges(Or2);
2238 L2.Append(V1); L2.Append(V2);
2244 sprintf(name,"%s_%d","SURF",nbc);
2245 DBRep::Set(name,AnOffset.Face());
2252 // ---------------------------------------------------
2253 // Construction of spheres,
2254 // if enough tubes arrive at the vertex
2255 // ---------------------------------------------------
2256 TopTools_IndexedDataMapOfShapeListOfShape Map;
2257 TopExp::MapShapesAndAncestors(Co,TopAbs_VERTEX,TopAbs_EDGE,Map);
2259 for ( Standard_Integer i = 1; i <= Map.Extent(); i++) {
2260 const TopoDS_Vertex& V = TopoDS::Vertex(Map.FindKey(i));
2261 if ( Map(i).Extent() != 3) continue;
2263 TopTools_ListOfShape LOE;
2264 TopTools_ListIteratorOfListOfShape it;
2266 for (it.Initialize(Map(i)) ; it.More(); it.Next()) {
2267 Standard_Boolean Reverse = Standard_True;
2269 LOE.Append(myMapSF(it.Value()).Generated(V).Reversed());
2271 LOE.Append(myMapSF(it.Value()).Generated(V));
2274 BRepOffset_Offset OFT(V,LOE,-myRadius,myNubs, myTol, GeomAbs_C2);
2275 myMapSF.Bind(V,OFT);
2278 B.Add(myResult,OFT.Face());
2282 sprintf(name,"%s_%d","SURF",nbc);
2283 DBRep::Set(name,OFT.Face());
2291 //=======================================================================
2292 //function : ComputeShape
2294 //=======================================================================
2295 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
2297 void BiTgte_Blend::ComputeShape()
2299 // Find in the initial Shapel:
2300 // - untouched Faces
2301 // - generated tubes
2302 // - the faces neighbors of tubes that sould be reconstucted preserving sharing.
2304 // For Debug : Visualize edges of the initial shape that should be reconstructed.
2307 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myCutEdges);
2308 Standard_Integer NbEdges = 0;
2309 for ( ; itm.More(); itm.Next()) {
2310 const TopoDS_Edge& E = TopoDS::Edge(itm.Key());
2311 const TopTools_ListOfShape& VonE = itm.Value();
2312 TopTools_ListOfShape NewE;
2314 CutEdge(E,VonE,NewE);
2315 for (TopTools_ListIteratorOfListOfShape it(NewE); it.More(); it.Next()) {
2316 sprintf(name,"%s_%d","CUTE",++NbEdges);
2317 DBRep::Set(name,it.Value());
2325 // modify the tubes on edge for partition of edges.
2327 Standard_Integer NbS = NbSurfaces();
2329 for (Standard_Integer i = 1; i <= NbS; i++) {
2330 const TopoDS_Shape& S1 = SupportShape1(i);
2332 if ( S1.ShapeType() == TopAbs_EDGE) {
2333 const TopoDS_Edge& E1 = TopoDS::Edge(S1);
2334 // it is required to replace in F the cut edges of E1, that
2336 const TopTools_ListOfShape& VonE = myCutEdges(E1);
2337 TopTools_ListOfShape NewE;
2338 CutEdge(E1,VonE,NewE);
2344 TopTools_DataMapOfShapeShape Created;
2346 TopTools_ListOfShape Empty;
2347 TopTools_DataMapOfShapeListOfShape EmptyMap;
2352 Standard_Integer NbNT = 1;
2355 // Maj of the Map of created.
2356 // Update edges that do not change in the resulting shape
2357 // i.e. invariant edges in the unwinding.
2358 TopExp_Explorer exp(myShape,TopAbs_FACE);
2359 // Standard_Integer nbe = 1;
2360 for ( ;exp.More(); exp.Next()) {
2362 const TopoDS_Face& CurF = TopoDS::Face(exp.Current());
2364 if ( !myFaces.Contains(CurF)) continue; // so the face is not touched
2366 // so the faces are unwinded
2367 if ( !myMapSF.IsBound(CurF)) continue; // inverted or degenerated
2369 const BRepOffset_Offset& Offset = myMapSF(CurF);
2370 const TopoDS_Face& CurOF = myMapSF(CurF).Face();
2372 if ( !myImageOffset.HasImage(CurOF)) // face disappears in unwinding
2375 TopExp_Explorer exp2(CurF,TopAbs_EDGE);
2376 for ( ;exp2.More(); exp2.Next()) {
2377 const TopoDS_Edge& CurE = TopoDS::Edge(exp2.Current());
2378 TopoDS_Shape aLocalShape = Offset.Generated(CurE);
2379 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
2380 // const TopoDS_Edge& CurOE = TopoDS::Edge(Offset.Generated(CurE));
2382 if (!myImageOffset.HasImage(CurOE)) continue;
2385 const TopoDS_Edge& ImE =
2386 TopoDS::Edge(myImageOffset.Image(CurOE).First());
2387 if (ImE.IsSame(CurOE)) {
2388 myCreated.Bind(CurOE,EmptyMap);
2389 myCreated(CurOE).Bind(CurF,Empty);
2390 myCreated(CurOE)(CurF).Append(CurE);
2395 // The connected faces are already in myResult.
2396 // So it is necessary to add faces:
2397 // - non-touched (so not in myFaces)
2398 // - issuing from the unwinding (non degenerated, non inverted, non disappeared)
2399 exp.Init(myShape,TopAbs_FACE);
2400 for ( ;exp.More(); exp.Next()) {
2402 const TopoDS_Face& CurF = TopoDS::Face(exp.Current());
2404 if ( !myFaces.Contains(CurF)) {
2405 // so the face is not touched
2406 B.Add(myResult,CurF);
2408 else { // so the faces are unwindeds
2410 if ( !myMapSF.IsBound(CurF)) continue; // inverted or degenerated
2412 const TopoDS_Face& CurOF = myMapSF(CurF).Face();
2414 if ( !myImageOffset.HasImage(CurOF)) // face disappears in unwinding
2417 // List of faces generated by a face in the unwinding
2418 TopTools_ListOfShape Lim;
2419 myImageOffset.LastImage(CurOF,Lim);
2420 TopTools_ListIteratorOfListOfShape itLim(Lim);
2421 for ( ;itLim.More(); itLim.Next()) {
2422 // DeboucFace = offset Face unwinded in "Debouc".
2423 const TopoDS_Face& DeboucFace = TopoDS::Face(itLim.Value());
2426 Handle(Geom_Surface) S = BRep_Tool::Surface(CurF,L);
2428 TopoDS_Face NewF; B.MakeFace(NewF);
2429 B.UpdateFace(NewF,S,L,BRep_Tool::Tolerance(CurF));
2431 TopTools_DataMapOfShapeShape MapSS;
2433 TopoDS_Shape aLocalShape = DeboucFace.Oriented(TopAbs_FORWARD);
2434 const TopoDS_Face& Face = TopoDS::Face(aLocalShape);
2435 // const TopoDS_Face& Face =
2436 // TopoDS::Face(DeboucFace.Oriented(TopAbs_FORWARD));
2437 TopExp_Explorer exp2(Face, TopAbs_EDGE);
2438 for ( ; exp2.More(); exp2.Next()) {
2439 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
2440 TopoDS_Vertex V1,V2,OV1,OV2;
2441 TopExp::Vertices(E ,V1 ,V2 );
2442 if (myCreated.IsBound(E)) {
2443 if (myCreated(E).IsBound(CurF)) {
2444 const TopoDS_Edge& OE = TopoDS::Edge(myCreated(E)(CurF).First());
2445 TopExp::Vertices(OE,OV1,OV2);
2446 if ( !myCreated.IsBound(V1)) myCreated.Bind(V1,EmptyMap);
2447 if ( !myCreated.IsBound(V2)) myCreated.Bind(V2,EmptyMap);
2448 if ( !myCreated(V1).IsBound(CurF)) {
2449 myCreated(V1).Bind(CurF,Empty);
2450 myCreated(V1)(CurF).Append(OV1);
2452 if ( !myCreated(V2).IsBound(CurF)) {
2453 myCreated(V2).Bind(CurF,Empty);
2454 myCreated(V2)(CurF).Append(OV2);
2460 TopExp_Explorer expw(Face, TopAbs_WIRE);
2461 for ( ; expw.More(); expw.Next()) {
2462 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
2463 TopExp_Explorer expe(W.Oriented(TopAbs_FORWARD),
2468 for ( ; expe.More(); expe.Next()) {
2469 const TopoDS_Edge& E = TopoDS::Edge(expe.Current());
2471 Handle(Geom2d_Curve) C2d =
2472 BRep_Tool::CurveOnSurface(E,Face,f,l);
2474 if ( MapSS.IsBound(E)) { // this is an edge of cutting
2475 OE = TopoDS::Edge(MapSS(E));
2476 TopoDS_Shape aLocalShape = E.Reversed();
2477 Handle(Geom2d_Curve) C2d_1 =
2478 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),Face,f,l);
2479 // Handle(Geom2d_Curve) C2d_1 =
2480 // BRep_Tool::CurveOnSurface(TopoDS::Edge(E.Reversed()),
2482 if ( E.Orientation() == TopAbs_FORWARD)
2483 B.UpdateEdge(OE,C2d,C2d_1,NewF,BRep_Tool::Tolerance(E));
2485 B.UpdateEdge(OE,C2d_1,C2d,NewF,BRep_Tool::Tolerance(E));
2489 // Is there an image in the Map of Created ?
2490 if ( myCreated.IsBound(E)) {
2491 if ( myCreated(E).IsBound(CurF)) {
2492 OE = TopoDS::Edge(myCreated(E)(CurF).First());
2497 TopoDS_Vertex V1,V2,OV1,OV2;
2498 TopExp::Vertices(E,V1,V2);
2499 if ( myCreated.IsBound(V1) && myCreated(V1).IsBound(CurF)) {
2500 OV1 = TopoDS::Vertex(myCreated(V1)(CurF).First());
2505 C2d->Value(BRep_Tool::Parameter(V1,E,Face));
2507 S->D0(P2d.X(),P2d.Y(),P);
2508 P.Transform(L.Transformation());
2509 B.UpdateVertex(OV1,P,BRep_Tool::Tolerance(V1));
2510 myCreated.Bind(V1,EmptyMap);
2511 myCreated(V1).Bind(CurF,Empty);
2512 myCreated(V1)(CurF).Append(OV1);
2514 if ( myCreated.IsBound(V2) && myCreated(V2).IsBound(CurF)) {
2515 OV2 = TopoDS::Vertex(myCreated(V2)(CurF).First());
2520 C2d->Value(BRep_Tool::Parameter(V2,E,Face));
2522 S->D0(P2d.X(),P2d.Y(),P);
2523 P.Transform(L.Transformation());
2524 B.UpdateVertex(OV2,P,BRep_Tool::Tolerance(V2));
2525 myCreated.Bind(V2,EmptyMap);
2526 myCreated(V2).Bind(CurF,Empty);
2527 myCreated(V2)(CurF).Append(OV2);
2529 B.Add(OE,OV1.Oriented(V1.Orientation()));
2530 B.Add(OE,OV2.Oriented(V2.Orientation()));
2532 B.UpdateEdge(OE,C2d,NewF,BRep_Tool::Tolerance(E));
2534 // ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
2537 B.Add(OW, OE.Oriented(E.Orientation()));
2539 B.Add(NewF, OW.Oriented(W.Orientation()));
2542 NewF.Orientation(DeboucFace.Orientation());
2544 BRepTools::Update(NewF);
2545 B.Add(myResult,NewF);
2550 // non-regarding the cause, there always remain greeb borders on this Shape, so it is sewn.
2551 Handle(BRepBuilderAPI_Sewing) Sew = new BRepBuilderAPI_Sewing(myTol);
2553 BRepLib::BuildCurves3d(myResult);
2555 exp.Init(myResult,TopAbs_FACE);
2556 for ( ;exp.More(); exp.Next())
2557 Sew->Add(exp.Current());
2561 // SameParameter is done in case Sew does not do it (Detect that the edges
2562 // are not sameparameter but does nothing.)
2564 const TopoDS_Shape& SewedShape = Sew->SewedShape();
2565 if ( !SewedShape.IsNull()) {
2566 exp.Init(Sew->SewedShape(), TopAbs_EDGE);
2567 for (; exp.More(); exp.Next()) {
2568 const TopoDS_Edge& sec = TopoDS::Edge(exp.Current());
2569 BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
2571 myResult = SewedShape;
2576 //=======================================================================
2577 //function : Intersect
2579 //=======================================================================
2581 Standard_Boolean BiTgte_Blend::Intersect
2582 (const TopoDS_Shape& Init,
2583 const TopoDS_Face& Face,
2584 const BiTgte_DataMapOfShapeBox& MapSBox,
2585 const BRepOffset_Offset& OF1,
2586 BRepOffset_Inter3d& Inter)
2588 Standard_Boolean JenRajoute = Standard_False;
2590 const Bnd_Box& Box1 = MapSBox(Face);
2592 // -----------------------------------------------
2593 // intersection with all already created faces.
2594 // -----------------------------------------------
2595 const TopoDS_Shape& InitShape1 = OF1.InitialShape();
2596 Standard_Boolean F1surBordLibre =
2597 InitShape1.ShapeType() == TopAbs_EDGE &&
2598 myStopFaces.Contains(InitShape1);
2600 TopTools_MapOfShape Done;
2601 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(myMapSF);
2602 for ( ; It.More(); It.Next()) {
2603 const BRepOffset_Offset& OF2 = It.Value();
2604 const TopoDS_Face& F2 = OF2.Face();
2606 if (Box1.IsOut(MapSBox(F2))) continue;
2608 if ( Inter.IsDone(Face,F2)) continue;
2610 // 2 tubes created on free border are not intersected.
2611 const TopoDS_Shape& InitShape2 = OF2.InitialShape();
2612 Standard_Boolean F2surBordLibre =
2613 InitShape2.ShapeType() == TopAbs_EDGE &&
2614 myStopFaces.Contains(InitShape2);
2617 if ( F1surBordLibre && F2surBordLibre) {
2618 cout << "Rejection : 2 tubes on free border are not intersected";
2623 if ( F1surBordLibre && F2surBordLibre) continue;
2625 // -------------------------------------------------------
2626 // Tubes are not intersected with neighbor faces.
2627 // -------------------------------------------------------
2628 const TopoDS_Shape& ItKey = It.Key();
2630 if ( Init.ShapeType() == TopAbs_EDGE) {
2631 if (ItKey.ShapeType() == TopAbs_FACE &&
2632 IsInFace(TopoDS::Edge(Init), TopoDS::Face(ItKey))) continue;
2635 Inter.FaceInter(Face,F2,myInitOffsetFace);
2637 // ------------------------------------------
2638 // an edge of F1 or F2 has been touched ?
2639 // if yes, add faces in myFaces
2640 // ==> JenRajoute = True
2641 // ------------------------------------------
2642 TopTools_ListOfShape LInt;
2644 if (myAsDes->HasCommonDescendant(Face,F2,LInt)) {
2645 TopTools_ListIteratorOfListOfShape itl2;
2646 for (itl2.Initialize(LInt); itl2.More(); itl2.Next()) {
2647 const TopoDS_Edge& CurE = TopoDS::Edge(itl2.Value());
2648 TopoDS_Vertex V1,V2;
2650 TopExp::Vertices(CurE,V1,V2);
2652 if ( Done.Add(V1)) {
2653 Standard_Boolean IsOnR1 = IsOnRestriction(V1,CurE,Face,E1);
2654 Standard_Boolean IsOnR2 = IsOnRestriction(V1,CurE,F2,E2);
2656 if (IsOnR1 && IsOnR2) {
2657 cout << "Leave in the same tps on 2 faces, ";
2658 cout << "propagation only on free border";
2663 if ( !myStopFaces.Contains(Init)) {
2664 Add(E1,myEdges,Init,OF1,myAnalyse,IsOnR1 && IsOnR2);
2665 JenRajoute = Standard_True;
2669 if ( !myStopFaces.Contains(ItKey)) {
2670 Add(E2,myEdges, ItKey,OF2,myAnalyse,IsOnR1 && IsOnR2);
2671 JenRajoute = Standard_True;
2676 if ( Done.Add(V2)) {
2677 Standard_Boolean IsOnR1 = IsOnRestriction(V2,CurE,Face,E1);
2678 Standard_Boolean IsOnR2 = IsOnRestriction(V2,CurE,F2,E2);
2680 // If IsOnR1 && IsOnR2,
2681 // Leave in the same tps on 2 faces, propagate only on
2683 // A priori, only facet is closed.
2685 if (IsOnR1 && IsOnR2) {
2686 cout << "Leave with the same tps on 2 faces, ";
2687 cout << "propagate only if the border is free";
2692 if ( !myStopFaces.Contains(Init)) {
2693 Add(E1,myEdges,Init,OF1,myAnalyse,IsOnR1 && IsOnR2);
2694 JenRajoute = Standard_True;
2698 if ( !myStopFaces.Contains(ItKey)) {
2699 Add(E2,myEdges,ItKey,OF2,myAnalyse,IsOnR1 && IsOnR2);
2700 JenRajoute = Standard_True;