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 <Bnd_Box.hxx>
24 #include <BRep_Builder.hxx>
25 #include <BRep_Tool.hxx>
26 #include <BRepAlgo_AsDes.hxx>
27 #include <BRepAlgo_Loop.hxx>
28 #include <BRepBndLib.hxx>
29 #include <BRepBuilderAPI_Sewing.hxx>
30 #include <BRepLib.hxx>
31 #include <BRepLib_MakeEdge.hxx>
32 #include <BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx>
33 #include <BRepOffset_DataMapOfShapeOffset.hxx>
34 #include <BRepOffset_Inter2d.hxx>
35 #include <BRepOffset_Inter3d.hxx>
36 #include <BRepOffset_Interval.hxx>
37 #include <BRepOffset_ListOfInterval.hxx>
38 #include <BRepOffset_MakeLoops.hxx>
39 #include <BRepOffset_Offset.hxx>
40 #include <BRepOffset_Tool.hxx>
41 #include <BRepTools.hxx>
42 #include <BRepTools_Quilt.hxx>
43 #include <BSplCLib.hxx>
45 #include <Convert_CompBezierCurvesToBSplineCurve.hxx>
47 #include <Geom2d_Curve.hxx>
48 #include <Geom2dAdaptor_Curve.hxx>
49 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
50 #include <Geom_BSplineCurve.hxx>
51 #include <Geom_Circle.hxx>
52 #include <Geom_Curve.hxx>
53 #include <Geom_Line.hxx>
54 #include <Geom_Surface.hxx>
55 #include <Geom_TrimmedCurve.hxx>
56 #include <GeomAbs_SurfaceType.hxx>
57 #include <GeomAdaptor_Surface.hxx>
58 #include <GeomAPI.hxx>
59 #include <GeomAPI_ProjectPointOnCurve.hxx>
63 #include <gp_Circ.hxx>
65 #include <gp_Dir2d.hxx>
67 #include <gp_Lin2d.hxx>
69 #include <gp_Pnt2d.hxx>
70 #include <gp_Sphere.hxx>
71 #include <Precision.hxx>
72 #include <Standard_NotImplemented.hxx>
73 #include <Standard_OutOfRange.hxx>
74 #include <StdFail_NotDone.hxx>
75 #include <TColgp_Array1OfPnt.hxx>
76 #include <TColStd_Array1OfInteger.hxx>
77 #include <TColStd_Array1OfReal.hxx>
79 #include <TopExp_Explorer.hxx>
81 #include <TopoDS_Compound.hxx>
82 #include <TopoDS_Edge.hxx>
83 #include <TopoDS_Face.hxx>
84 #include <TopoDS_Shape.hxx>
85 #include <TopoDS_Vertex.hxx>
86 #include <TopoDS_Wire.hxx>
87 #include <TopTools_DataMapOfShapeShape.hxx>
88 #include <TopTools_ListIteratorOfListOfShape.hxx>
89 #include <TopTools_ListOfShape.hxx>
90 #include <TopTools_MapIteratorOfMapOfShape.hxx>
91 #include <TopTools_SequenceOfShape.hxx>
94 #include <OSD_Chronometer.hxx>
99 // - all small static functions.
100 //======================== START STATIC FUNCTIONS ============
101 // variables for performance
102 Standard_Real t_mkcurve;
104 extern void ChFi3d_InitChron(OSD_Chronometer& ch);
105 extern void ChFi3d_ResultChron(OSD_Chronometer & ch, Standard_Real& time);
108 static Standard_Boolean Affich = Standard_False;
109 static char name[100];
113 //=======================================================================
114 //function : IsOnRestriction
116 //=======================================================================
118 static Standard_Boolean IsOnRestriction(const TopoDS_Vertex& V,
119 const TopoDS_Edge& CurE,
120 const TopoDS_Face& F,
123 // find if Vertex V of CurE is on a restriction of F.
124 // if yes, store this restriction in E.
127 // Method somewhat brutal : possible to really optimize by a
128 // direct call the SD of intersections -> See LBR
131 Handle(Geom2d_Curve) CurC = BRep_Tool::CurveOnSurface(CurE,F,f,l);
132 Standard_Real U = BRep_Tool::Parameter(V,CurE,F);
133 gp_Pnt2d P = CurC->Value(U);
135 Geom2dAPI_ProjectPointOnCurve Proj;
137 // The tolerance is exaggerated : it is better to construct too many
138 // tubes than to miss intersections.
139 // Standard_Real Tol = 100 * BRep_Tool::Tolerance(V);
140 Standard_Real Tol = BRep_Tool::Tolerance(V);
141 TopExp_Explorer exp(F,TopAbs_EDGE);
142 for ( ; exp.More(); exp.Next()) {
143 E = TopoDS::Edge(exp.Current());
144 Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(E,F,f,l);
146 if ( Proj.NbPoints() > 0) {
147 if (Proj.LowerDistance() < Tol) {
148 return Standard_True;
152 return Standard_False;
155 //=======================================================================
158 //=======================================================================
160 static void Add(const TopoDS_Edge& E,
161 TopTools_IndexedMapOfShape& Map,
162 const TopoDS_Shape& S,
163 const BRepOffset_Offset& OF,
164 const BRepOffset_Analyse& Analyse,
165 const Standard_Boolean WarningSurBordLibre)
166 // If WarningSurBordLibre = TRUE, no propagation if the edge is open.
168 TopAbs_ShapeEnum Type = S.ShapeType();
170 if ( Type == TopAbs_FACE) {
171 TopExp_Explorer exp(S,TopAbs_EDGE);
172 for ( ; exp.More(); exp.Next()) {
173 const TopoDS_Edge& OriE = TopoDS::Edge(exp.Current());
174 TopoDS_Shape aLocalShape = OF.Generated(OriE);
175 const TopoDS_Edge& IE = TopoDS::Edge(aLocalShape);
176 // const TopoDS_Edge& IE = TopoDS::Edge(OF.Generated(OriE));
177 if ( E.IsEqual(IE)) {
178 if (WarningSurBordLibre) {
179 // It is checked that the border is not free.
180 const TopTools_ListOfShape& L = Analyse.Ancestors(OriE);
181 if (L.Extent() == 1) break; // Nothing is done.
183 Map.Add(exp.Current());
188 else if ( Type == TopAbs_EDGE) {
189 TopExp_Explorer exp(S,TopAbs_VERTEX);
190 for ( ; exp.More(); exp.Next()) {
191 TopoDS_Shape aLocalShape = OF.Generated(exp.Current());
192 const TopoDS_Edge& IE = TopoDS::Edge(aLocalShape);
193 // const TopoDS_Edge& IE = TopoDS::Edge(OF.Generated(exp.Current()));
194 if ( E.IsEqual(IE)) {
195 const TopTools_ListOfShape& L = Analyse.Ancestors(exp.Current());
196 TopTools_ListIteratorOfListOfShape it(L);
197 for ( ; it.More(); it.Next()) {
207 //=======================================================================
208 //function : IsInFace
210 //=======================================================================
212 static Standard_Boolean IsInFace(const TopoDS_Edge& E,
213 const TopoDS_Face& F)
215 TopExp_Explorer exp(F,TopAbs_EDGE);
216 for ( ;exp.More(); exp.Next())
217 if ( E.IsSame(exp.Current())) return Standard_True;
218 return Standard_False;
222 //=======================================================================
223 //function : KPartCurve3d
225 //=======================================================================
227 static void KPartCurve3d(TopoDS_Edge Edge,
228 Handle(Geom2d_Curve) Curve,
229 Handle(Geom_Surface) Surf)
231 // try to find the particular case
232 // if not found call BRepLib::BuildCurve3d
235 Standard_Real Tol = Precision::Confusion();
237 // Seach only isos on analytical surfaces.
238 Geom2dAdaptor_Curve C(Curve);
239 GeomAdaptor_Surface S(Surf);
240 GeomAbs_CurveType CTy = C.GetType();
241 GeomAbs_SurfaceType STy = S.GetType();
242 BRep_Builder TheBuilder;
244 if ( STy != GeomAbs_Plane) { // if plane buildcurve3d manage KPart
245 if ( CTy == GeomAbs_Line) {
246 gp_Dir2d D = C.Line().Direction();
247 if ( D.IsParallel(gp::DX2d(),Precision::Angular())) { // Iso V.
248 if ( STy == GeomAbs_Sphere) {
249 gp_Pnt2d P = C.Line().Location();
250 if ( Abs( Abs(P.Y()) -M_PI/2. ) < Precision::PConfusion()) {
251 TheBuilder.Degenerated(Edge, Standard_True);
254 gp_Sphere Sph = S.Sphere();
255 gp_Ax3 Axis = Sph.Position();
256 gp_Circ Ci = ElSLib::SphereVIso(Axis,
259 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
260 gp_Ax1 AxeRev(Axis.Location(), DRev);
261 Ci.Rotate(AxeRev, P.X());
262 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
263 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
265 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
268 else if ( STy == GeomAbs_Cylinder) {
269 gp_Cylinder Cyl = S.Cylinder();
270 gp_Pnt2d P = C.Line().Location();
271 gp_Ax3 Axis = Cyl.Position();
272 gp_Circ Ci = ElSLib::CylinderVIso(Axis,
275 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
276 gp_Ax1 AxeRev(Axis.Location(), DRev);
277 Ci.Rotate(AxeRev, P.X());
278 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
279 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
281 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
283 else if ( STy == GeomAbs_Cone) {
284 gp_Cone Cone = S.Cone();
285 gp_Pnt2d P = C.Line().Location();
286 gp_Ax3 Axis = Cone.Position();
287 gp_Circ Ci = ElSLib::ConeVIso(Axis,
291 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
292 gp_Ax1 AxeRev(Axis.Location(), DRev);
293 Ci.Rotate(AxeRev, P.X());
294 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
295 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
297 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
299 else if ( STy == GeomAbs_Torus) {
300 gp_Torus Tore = S.Torus();
301 gp_Pnt2d P = C.Line().Location();
302 gp_Ax3 Axis = Tore.Position();
303 gp_Circ Ci = ElSLib::TorusVIso(Axis,
307 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
308 gp_Ax1 AxeRev(Axis.Location(), DRev);
309 Ci.Rotate(AxeRev, P.X());
310 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
311 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
313 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
316 else if ( D.IsParallel(gp::DY2d(),Precision::Angular())) { // Iso U.
317 if ( STy == GeomAbs_Sphere) {
318 gp_Sphere Sph = S.Sphere();
319 gp_Pnt2d P = C.Line().Location();
320 gp_Ax3 Axis = Sph.Position();
322 gp_Circ Ci = ElSLib::SphereUIso(Axis, Sph.Radius(),0.);
324 // set to sameparameter (rotation of the circle - offset from Y)
325 gp_Dir DRev = Axis.XDirection().Crossed(Axis. Direction());
326 gp_Ax1 AxeRev(Axis.Location(),DRev);
327 Ci.Rotate(AxeRev, P.Y());
329 // transformation by iso U ( = P.X())
330 DRev = Axis.XDirection().Crossed(Axis.YDirection());
331 AxeRev = gp_Ax1(Axis.Location(), DRev);
332 Ci.Rotate(AxeRev, P.X());
333 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
335 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
337 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
339 else if ( STy == GeomAbs_Cylinder) {
340 gp_Cylinder Cyl = S.Cylinder();
341 gp_Pnt2d P = C.Line().Location();
342 gp_Lin L = ElSLib::CylinderUIso(Cyl.Position(),
345 gp_Vec Tr(L.Direction());
348 Handle(Geom_Line) Line = new Geom_Line(L);
349 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
351 TheBuilder.UpdateEdge(Edge, Line, Loc, Tol);
353 else if ( STy == GeomAbs_Cone) {
354 gp_Cone Cone = S.Cone();
355 gp_Pnt2d P = C.Line().Location();
356 gp_Lin L = ElSLib::ConeUIso(Cone.Position(),
360 gp_Vec Tr(L.Direction());
362 L.Translate(Tr); Handle(Geom_Line) Line = new Geom_Line(L);
363 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
365 TheBuilder.UpdateEdge(Edge, Line, Loc, Tol);
367 else if ( STy == GeomAbs_Torus) {
373 Handle(Geom_Curve) C3d = GeomAPI::To3d(Curve,S.Plane());
374 TheBuilder.UpdateEdge(Edge, C3d, Loc, Tol);
379 //=======================================================================
380 //function : MakeCurve
382 //=======================================================================
384 class MakeCurve_Function : public AppCont_Function
386 BiTgte_CurveOnEdge myCurve;
390 MakeCurve_Function(const BiTgte_CurveOnEdge& C)
397 Standard_Real FirstParameter() const
399 return myCurve.FirstParameter();
402 Standard_Real LastParameter() const
404 return myCurve.LastParameter();
407 Standard_Boolean Value(const Standard_Real theT,
408 NCollection_Array1<gp_Pnt2d>& /*thePnt2d*/,
409 NCollection_Array1<gp_Pnt>& thePnt) const
411 thePnt(1) = myCurve.Value(theT);
412 return Standard_True;
415 Standard_Boolean D1(const Standard_Real /*theT*/,
416 NCollection_Array1<gp_Vec2d>& /*theVec2d*/,
417 NCollection_Array1<gp_Vec>& /*theVec*/) const
419 return Standard_False;
424 Handle(Geom_Curve) MakeCurve (const BiTgte_CurveOnEdge& HC)
426 Handle(Geom_Curve) C;
430 ChFi3d_InitChron(ch);
433 if ( HC.GetType() == GeomAbs_Circle) {
434 C = new Geom_Circle(HC.Circle());
435 C = new Geom_TrimmedCurve(C,HC.FirstParameter(),HC.LastParameter());
437 else { // the approximation is done
438 MakeCurve_Function F(HC);
439 Standard_Integer Deg1, Deg2;
441 Standard_Real Tol = Precision::Approximation();
442 Approx_FitAndDivide Fit(F,Deg1,Deg2,Tol,Tol,Standard_True);
444 Standard_Integer NbCurves = Fit.NbMultiCurves();
445 // it is attempted to make the curve at least C1
446 Convert_CompBezierCurvesToBSplineCurve Conv;
448 for (i = 1; i <= NbCurves; i++) {
449 AppParCurves_MultiCurve MC = Fit.Value( i); //Load the Ith Curve
450 TColgp_Array1OfPnt Poles( 1, MC.Degree() + 1); //Return poles
453 Conv.AddCurve(Poles);
458 Standard_Integer NbPoles = Conv.NbPoles();
459 Standard_Integer NbKnots = Conv.NbKnots();
460 TColgp_Array1OfPnt NewPoles(1,NbPoles);
461 TColStd_Array1OfReal NewKnots(1,NbKnots);
462 TColStd_Array1OfInteger NewMults(1,NbKnots);
464 Conv.KnotsAndMults(NewKnots,NewMults);
465 Conv.Poles(NewPoles);
467 BSplCLib::Reparametrize(HC.FirstParameter(),
471 C = new Geom_BSplineCurve (NewPoles,
478 ChFi3d_ResultChron(ch, t_mkcurve);
485 //=======================================================================
487 //purpose : Only the faces connected with caps are given
488 //=======================================================================
490 static void Touched(const BRepOffset_Analyse&,
491 const TopTools_MapOfShape&,
493 TopTools_MapOfShape&)
495 // currently nothing is done !!
496 /*if ( Standard_True) {
500 TopExp_Explorer exp(Shape, TopAbs_EDGE);
501 for ( ; exp.More(); exp.Next()) {
502 const TopTools_ListOfShape& L = Analyse.Ancestors(exp.Current());
503 if (StopFaces.Contains(L.First()))
504 TouchedByCork.Add(L.Last());
505 else if (StopFaces.Contains(L.Last()))
506 TouchedByCork.Add(L.First());
512 //=======================================================================
513 //function : FindVertex
515 //=======================================================================
517 static TopoDS_Vertex FindVertex(const gp_Pnt& P,
518 const TopTools_MapOfShape& Map,
519 const Standard_Real Tol)
522 // Find in <Map> a vertex which represent the point <P>.
523 Standard_Real Tol2,Dist;
524 TopoDS_Vertex V,VV[2];
525 Standard_Real TolCarre = Tol*Tol;
526 TopTools_MapIteratorOfMapOfShape it(Map);
527 for ( ; it.More(); it.Next()) {
528 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
530 TopExp::Vertices(E,VV[0],VV[1]);
532 for (Standard_Integer i = 0; i < 2 ; i++) {
533 // if OK la Tolerance du Vertex
534 Tol2 = BRep_Tool::Tolerance(VV[i]);
536 gp_Pnt P1 = BRep_Tool::Pnt(VV[i]);
537 Dist = P.SquareDistance(P1);
538 if ( Dist <= Tol2) return VV[i];
539 // otherwise with the required tolerance.
540 if (TolCarre > Tol2) {
541 if ( Dist <= TolCarre) {
542 // so it is necessary to update the tolerance of Vertex.
543 B.UpdateVertex(VV[i],Tol);
555 //=======================================================================
556 //function : MakeDegeneratedEdge
558 //=======================================================================
560 static TopoDS_Edge MakeDegeneratedEdge(const Handle(Geom_Curve)& CC,
561 const TopoDS_Vertex& VfOnE)
564 Standard_Real Tol = Precision::Confusion();
565 // kill trimmed curves
566 Handle(Geom_Curve) C = CC;
567 Handle(Geom_TrimmedCurve) CT = Handle(Geom_TrimmedCurve)::DownCast(C);
568 while (!CT.IsNull()) {
569 C = CT->BasisCurve();
570 CT = Handle(Geom_TrimmedCurve)::DownCast(C);
574 if ( VfOnE.IsNull()) {
575 gp_Pnt P = C->Value(C->FirstParameter());
576 B.MakeVertex(V1,P,Tol);
582 V1.Orientation(TopAbs_FORWARD);
583 V2.Orientation(TopAbs_REVERSED);
587 B.Add(E,V1); B.Add(E,V2);
588 // B.UpdateVertex(V1,C->FirstParameter(),E,Tol);
589 // B.UpdateVertex(V2,C->LastParameter(),E,Tol);
590 B.Range(E,CC->FirstParameter(),CC->LastParameter());
595 //=======================================================================
596 //function : Orientation
598 //=======================================================================
600 static TopAbs_Orientation Orientation(const TopoDS_Edge& E,
601 const TopoDS_Face& F,
602 const TopTools_ListOfShape& L)
604 TopAbs_Orientation Orien = TopAbs_FORWARD;
605 TopTools_ListIteratorOfListOfShape itld;
606 for ( itld.Initialize(L); itld.More(); itld.Next()) {
607 if ( itld.Value().IsSame(E)) {
608 Orien = itld.Value().Orientation();
612 if ( F.Orientation() == TopAbs_REVERSED)
613 Orien = TopAbs::Reverse(Orien);
618 //=======================================================================
619 //function : FindCreatedEdge
621 //=======================================================================
623 static TopoDS_Edge FindCreatedEdge
624 (const TopoDS_Vertex& V1,
625 const TopoDS_Edge& E,
626 const BRepOffset_DataMapOfShapeOffset& MapSF,
627 TopTools_MapOfShape& MapOnV,
628 const BRepOffset_Analyse& CenterAnalyse,
629 Standard_Real Radius,
633 if (!CenterAnalyse.HasAncestor(V1)) return E1; // return a Null Shape.
635 TopTools_ListOfShape TangE;
636 CenterAnalyse.TangentEdges(E,V1,TangE);
638 TopTools_ListIteratorOfListOfShape itl(TangE);
639 Standard_Boolean Find = Standard_False;
640 for ( ; itl.More() && !Find; itl.Next()) {
641 const TopoDS_Edge& ET = TopoDS::Edge(itl.Value());
642 if ( MapSF.IsBound(ET)) {
643 TopoDS_Shape aLocalShape = MapSF(ET).Generated(V1);
644 E1 = TopoDS::Edge(aLocalShape);
645 // E1 = TopoDS::Edge(MapSF(ET).Generated(V1));
647 Find = Standard_True;
650 // Find the sharing of vertices in case of tangent consecutive 3 edges
651 // the second of which is the edge that degenerates the tube.
652 TopLoc_Location CLoc;
654 Handle(Geom_Curve) CET =
655 BRep_Tool::Curve(ET,CLoc,ff,ll);
656 if ( CET->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
657 CET = Handle(Geom_TrimmedCurve)::DownCast(CET)->BasisCurve();
659 Handle(Geom_Circle) Circ = Handle(Geom_Circle)::DownCast(CET);
660 if ( Circ.IsNull()) continue;
661 if ( Abs(Circ->Radius() - Abs(Radius)) > Tol) continue;
664 TopExp::Vertices(ET,U1,U2);
665 if ( U1.IsSame(V1)) U1 = U2;
666 TopTools_ListOfShape Tang2;
667 CenterAnalyse.TangentEdges(ET,U1,Tang2);
668 TopTools_ListIteratorOfListOfShape it2(Tang2);
669 for ( ; it2.More() ; it2.Next()) {
670 const TopoDS_Edge& ET2 = TopoDS::Edge(it2.Value());
671 if ( MapSF.IsBound(ET2)) {
672 TopoDS_Shape aLocalShape = MapSF(ET2).Generated(U1);
673 MapOnV.Add(TopoDS::Edge(aLocalShape));
674 // MapOnV.Add(TopoDS::Edge(MapSF(ET2).Generated(U1)));
681 // CenterAnalyse.Edges(V1f, OT, TangE);
682 if (CenterAnalyse.HasAncestor(V1)) {
683 TangE = CenterAnalyse.Ancestors(V1);
684 itl.Initialize(TangE);
685 for ( ; itl.More() && !Find; itl.Next()) {
686 if ( MapSF.IsBound(itl.Value())) {
687 MapOnV.Add(MapSF(itl.Value()).Generated(V1));
697 //=======================================================================
699 //purpose : Sets in increasing order the sequence of vertices.
700 //=======================================================================
702 static void Bubble(const TopoDS_Edge& E,
703 TopTools_SequenceOfShape& Seq)
705 Standard_Boolean Invert = Standard_True;
706 Standard_Integer NbPoints = Seq.Length();
711 Invert = Standard_False;
712 for ( Standard_Integer i = 1; i < NbPoints; i++) {
713 TopoDS_Shape aLocalShape = Seq.Value(i) .Oriented(TopAbs_INTERNAL);
714 V1 = TopoDS::Vertex(aLocalShape);
715 aLocalShape = Seq.Value(i+1).Oriented(TopAbs_INTERNAL);
716 V2 = TopoDS::Vertex(aLocalShape);
717 // V1 = TopoDS::Vertex(Seq.Value(i) .Oriented(TopAbs_INTERNAL));
718 // V2 = TopoDS::Vertex(Seq.Value(i+1).Oriented(TopAbs_INTERNAL));
720 U1 = BRep_Tool::Parameter(V1,E);
721 U2 = BRep_Tool::Parameter(V2,E);
724 Invert = Standard_True;
730 //=======================================================================
733 //=======================================================================
735 static void CutEdge (const TopoDS_Edge& E,
736 const TopTools_ListOfShape& VOnE,
737 TopTools_ListOfShape& NE )
739 TopoDS_Shape aLocalShapeOrientedE = E.Oriented(TopAbs_FORWARD);
740 TopoDS_Edge WE = TopoDS::Edge(aLocalShapeOrientedE);
741 // TopoDS_Edge WE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
745 TopTools_SequenceOfShape SV;
746 TopTools_ListIteratorOfListOfShape it(VOnE);
749 for ( ; it.More(); it.Next()) {
750 SV.Append(it.Value());
752 //--------------------------------
753 // Parse vertices on the edge.
754 //--------------------------------
757 Standard_Integer NbVer = SV.Length();
758 //----------------------------------------------------------------
759 // Construction of new edges.
760 // The vertices at the extremities of edges are not
761 // necessarily in the list of vertices
762 //----------------------------------------------------------------
769 BRep_Tool::Range(WE,f,l);
770 TopExp::Vertices(WE,VF,VL);
773 if (SV(1).IsEqual(VF) && SV(2).IsEqual(VL)) {
778 //----------------------------------------------------
779 // Processing of closed edges
780 // If a vertex of intersection is on the common vertex,
781 // it should appear at the beginning and the end of SV.
782 //----------------------------------------------------
785 if (!VF.IsNull() && !VF.IsSame(SV.First())) SV.Prepend(VF);
786 if (!VL.IsNull() && !VL.IsSame(SV.Last ())) SV.Append (VL);
788 V1 = TopoDS::Vertex(SV.First());
791 while (!SV.IsEmpty()) {
793 V2 = TopoDS::Vertex(SV.First());
796 if ( V1.IsSame(V2)) {
797 std::cout << "Vertex Confondus dans CutEdges" << std::endl;
800 //-------------------------------------------
801 // Copy the edge and restriction by V1 V2.
802 //-------------------------------------------
803 TopoDS_Shape aLocalShape =WE.EmptyCopied();
804 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
805 // TopoDS_Edge NewEdge = TopoDS::Edge(WE.EmptyCopied());
806 B.Add (NewEdge,V1.Oriented(TopAbs_FORWARD));
807 B.Add (NewEdge,V2.Oriented(TopAbs_REVERSED));
811 aLocalShape = V1.Oriented(TopAbs_INTERNAL);
812 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),WE);
813 // U1 = BRep_Tool::Parameter
814 // (TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),WE);
819 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
820 U2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),WE);
821 // U2 = BRep_Tool::Parameter
822 // (TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),WE);
824 B.Range (NewEdge,U1,U2);
825 NE.Append(NewEdge.Oriented(E.Orientation()));
832 //======================== END OF STATIC FUNCTIONS ============
837 //=======================================================================
838 //function : BiTgte_Blend
840 //=======================================================================
842 BiTgte_Blend::BiTgte_Blend()
844 myAsDes = new BRepAlgo_AsDes();
849 //=======================================================================
850 //function : BiTgte_Blend
852 //=======================================================================
854 BiTgte_Blend::BiTgte_Blend(const TopoDS_Shape& S,
855 const Standard_Real Radius,
856 const Standard_Real Tol,
857 const Standard_Boolean NUBS)
859 myAsDes = new BRepAlgo_AsDes();
860 Init(S,Radius,Tol,NUBS);
864 //=======================================================================
867 //=======================================================================
869 void BiTgte_Blend::Init(const TopoDS_Shape& S,
870 const Standard_Real Radius,
871 const Standard_Real Tol,
872 const Standard_Boolean NUBS)
880 // TopExp::MapShapesAndAncestors(S,TopAbs_EDGE,TopAbs_FACE,myAncestors);
884 //=======================================================================
887 //=======================================================================
889 void BiTgte_Blend::Clear()
891 myInitOffsetFace.Clear();
893 myImageOffset .Clear();
894 myStopFaces .Clear();
898 myDone = Standard_False;
902 //=======================================================================
903 //function : SetStoppingFace
905 //=======================================================================
907 void BiTgte_Blend::SetStoppingFace(const TopoDS_Face& Face)
909 myStopFaces.Add(Face);
911 // MAJ SD. -> To end loop, set faces of edges
913 // myInitOffsetFace.SetRoot(Face);
914 // myInitOffsetFace.Bind (Face,Face);
915 // myImageOffset.SetRoot (Face);
919 //=======================================================================
920 //function : SetFaces
922 //=======================================================================
924 void BiTgte_Blend::SetFaces(const TopoDS_Face& F1,const TopoDS_Face& F2)
931 //=======================================================================
934 //=======================================================================
936 void BiTgte_Blend::SetEdge(const TopoDS_Edge& Edge)
942 //=======================================================================
945 //=======================================================================
947 void BiTgte_Blend::Perform(const Standard_Boolean BuildShape)
949 myBuildShape = BuildShape;
951 // Try cutting to avoid tubes on free borders
952 // that are not actually free.
953 Handle(BRepBuilderAPI_Sewing) Sew = new BRepBuilderAPI_Sewing(myTol);
954 BRepLib::BuildCurves3d(myShape);
955 TopExp_Explorer expf(myShape,TopAbs_FACE);
956 for ( ;expf.More(); expf.Next()) Sew->Add(expf.Current());
958 TopoDS_Shape SewedShape = Sew->SewedShape();
959 if ( SewedShape.IsNull()) throw Standard_Failure("Sewing aux fraises");
961 // Check if the sewing modified the orientation.
962 expf.Init(myShape,TopAbs_FACE);
963 TopoDS_Face FaceRef = TopoDS::Face(expf.Current());
964 TopAbs_Orientation OriRef = FaceRef.Orientation();
965 if (Sew->IsModified(FaceRef)) FaceRef = TopoDS::Face(Sew->Modified(FaceRef));
966 expf.Init(SewedShape, TopAbs_FACE);
967 for (; expf.More(); expf.Next()) {
968 const TopoDS_Face& FF = TopoDS::Face(expf.Current());
969 if (FaceRef.IsSame(FF) && (FF.Orientation() != OriRef)) {
970 SewedShape.Reverse();
975 // Make SameParameter if Sew does not do it (Detect that edges
976 // are not sameparameter but it does nothing.)
977 expf.Init(SewedShape, TopAbs_EDGE);
978 for (; expf.More(); expf.Next()) {
979 const TopoDS_Edge& sec = TopoDS::Edge(expf.Current());
980 BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
983 TopExp::MapShapesAndAncestors
984 (SewedShape,TopAbs_EDGE,TopAbs_FACE,myAncestors);
986 // Extend myFaces with the faces of the sewed shape.
987 expf.Init(myShape,TopAbs_FACE);
988 for ( ; expf.More(); expf.Next()) {
989 const TopoDS_Shape& F = expf.Current();
990 if ( myFaces.Contains(F) && Sew->IsModified(F)) {
991 myFaces.RemoveKey(F);
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.RemoveKey(F);
1017 else if ( myStopFaces.Contains(F)) {
1018 myStopFaces.Remove(F);
1023 // ----------------------------------------------
1024 // Calculate lines of centers and of surfaces
1025 // ----------------------------------------------
1027 ChFi3d_InitChron(ch);
1033 ChFi3d_ResultChron(ch, t_center);
1036 // -----------------------------
1037 // Calculate connection Surfaces
1038 // -----------------------------
1040 ChFi3d_InitChron(ch);
1046 ChFi3d_ResultChron(ch, t_surface);
1049 // ----------------------------------
1050 // Calculate the generated shape if required
1051 // ----------------------------------
1053 ChFi3d_InitChron(ch);
1056 if ( myBuildShape) ComputeShape();
1059 ChFi3d_ResultChron(ch, t_shape);
1062 // Finally construct curves 3d from edges to be transfered
1063 // since the partition is provided ( A Priori);
1064 BRepLib::BuildCurves3d(myResult, Precision::Confusion());
1067 ChFi3d_ResultChron(cl_total, t_total);
1068 std::cout<<std::endl;
1069 std::cout<<"Blend_PERFORM: temps total "<<t_total<<" s dont :"<<std::endl;
1070 std::cout<<"- ComputeCenters "<<t_center<<" s"<<std::endl;
1071 std::cout<<"- ComputeSurfaces "<<t_surface<<" s"<<std::endl;
1072 std::cout<<"----> MakeCurve "<<t_mkcurve<<" s"<<std::endl;
1073 if ( myBuildShape) std::cout<<"- ComputeShape "<<t_shape<<" s"<<std::endl;
1076 myDone = Standard_True;
1080 //=======================================================================
1083 //=======================================================================
1085 Standard_Boolean BiTgte_Blend::IsDone() const
1090 //=======================================================================
1093 //=======================================================================
1095 const TopoDS_Shape& BiTgte_Blend::Shape() const
1101 //=======================================================================
1102 //function : NbSurfaces
1104 //=======================================================================
1106 Standard_Integer BiTgte_Blend::NbSurfaces() const
1108 return myCenters.Extent();
1112 //=======================================================================
1113 //function : Surface
1115 //=======================================================================
1117 Handle(Geom_Surface) BiTgte_Blend::Surface(const Standard_Integer Index) const
1119 return Surface(myCenters(Index));
1122 //=======================================================================
1123 //function : TopoDS_Face&
1125 //=======================================================================
1127 const TopoDS_Face& BiTgte_Blend::Face(const Standard_Integer Index) const
1129 return Face(myCenters(Index));
1134 //=======================================================================
1135 //function : CenterLines
1137 //=======================================================================
1139 void BiTgte_Blend::CenterLines(TopTools_ListOfShape& LC) const
1142 Standard_Integer Nb = NbSurfaces();
1143 for ( Standard_Integer i = 1; i <= Nb; i++)
1144 LC.Append(myCenters(i));
1148 //=======================================================================
1149 //function : Surface
1151 //=======================================================================
1153 Handle(Geom_Surface) BiTgte_Blend::Surface(const TopoDS_Shape& CenterLine)
1156 const TopoDS_Face& F = myMapSF(CenterLine).Face();
1157 return BRep_Tool::Surface(F);
1160 //=======================================================================
1161 //function : TopoDS_Face&
1163 //=======================================================================
1165 const TopoDS_Face& BiTgte_Blend::Face(const TopoDS_Shape& CenterLine) const
1167 if ( !myMapSF.IsBound(CenterLine)) {
1168 throw Standard_DomainError("BiTgte_Blend::Face");
1171 return myMapSF(CenterLine).Face();
1174 //=======================================================================
1175 //function : ContactType
1177 //=======================================================================
1179 BiTgte_ContactType BiTgte_Blend::ContactType(const Standard_Integer Index)
1182 const TopoDS_Shape& S1 = SupportShape1(Index);
1183 const TopoDS_Shape& S2 = SupportShape2(Index);
1185 TopAbs_ShapeEnum Type1 = S1.ShapeType();
1186 TopAbs_ShapeEnum Type2 = S2.ShapeType();
1188 if (Type2 < Type1) {
1189 TopAbs_ShapeEnum Dummy = Type1;
1193 BiTgte_ContactType Type = BiTgte_VertexVertex;
1199 case TopAbs_VERTEX: Type = BiTgte_VertexVertex; break;
1200 case TopAbs_EDGE: Type = BiTgte_EdgeVertex; break;
1201 case TopAbs_FACE: Type = BiTgte_FaceVertex; break;
1208 case TopAbs_EDGE: Type = BiTgte_EdgeEdge; break;
1209 case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
1216 case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
1229 //=======================================================================
1230 //function : SupportShape1
1232 //=======================================================================
1234 const TopoDS_Shape& BiTgte_Blend::SupportShape1(const Standard_Integer Index)
1237 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1239 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1241 // --------------------------------------------------------------
1242 // F1 and F2 = 2 parallel faces intersecting at CurE.
1243 // --------------------------------------------------------------
1244 const TopoDS_Face& F1 = TopoDS::Face(L.First());
1245 const TopoDS_Shape& Or1 = myInitOffsetFace.ImageFrom(F1);
1250 //=======================================================================
1251 //function : SupportShape2
1253 //=======================================================================
1255 const TopoDS_Shape& BiTgte_Blend::SupportShape2(const Standard_Integer Index)
1258 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1260 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1262 // --------------------------------------------------------------
1263 // F1 and F2 = 2 parallel faces intersecting at CurE.
1264 // --------------------------------------------------------------
1265 const TopoDS_Face& F2 = TopoDS::Face(L.Last());
1266 const TopoDS_Shape& Or2 = myInitOffsetFace.ImageFrom(F2);
1271 //=======================================================================
1272 //function : CurveOnShape1
1274 //=======================================================================
1276 Handle(Geom_Curve) BiTgte_Blend::CurveOnShape1
1277 (const Standard_Integer Index) const
1279 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1280 const TopoDS_Shape& F = myMapSF(CurE).Face();
1282 // somewhat brutal method based ONLY on the construction of the fillet:
1283 // the first edge of the tube is exactly the edge on Shape1.
1285 TopExp_Explorer exp(F,TopAbs_EDGE);
1286 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1287 Handle(Geom_Curve) C;
1288 if ( !BRep_Tool::Degenerated(E)) {
1290 C = BRep_Tool::Curve(E,f,l);
1291 C = new Geom_TrimmedCurve(C,f,l);
1297 //=======================================================================
1298 //function : CurveOnShape2
1300 //=======================================================================
1302 Handle(Geom_Curve) BiTgte_Blend::CurveOnShape2
1303 (const Standard_Integer Index) const
1305 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1306 const TopoDS_Shape& F = myMapSF(CurE).Face();
1308 // somewhat brutal method based ONLY on the construction of the fillet:
1309 // the first edge of the tube is exactly the edge on Shape2.
1311 TopExp_Explorer exp(F,TopAbs_EDGE);
1313 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1314 Handle(Geom_Curve) C;
1315 if ( !BRep_Tool::Degenerated(E)) {
1317 C = BRep_Tool::Curve(E,f,l);
1318 C = new Geom_TrimmedCurve(C,f,l);
1324 //=======================================================================
1325 //function : PCurveOnFace1
1327 //=======================================================================
1329 Handle(Geom2d_Curve) BiTgte_Blend::PCurveOnFace1
1330 (const Standard_Integer /*Index*/) const
1332 Handle(Geom2d_Curve) C;
1337 //=======================================================================
1338 //function : PCurve1OnFillet
1340 //=======================================================================
1342 Handle(Geom2d_Curve) BiTgte_Blend::PCurve1OnFillet
1343 (const Standard_Integer /*Index*/) const
1345 Handle(Geom2d_Curve) C;
1350 //=======================================================================
1351 //function : PCurveOnFace2
1353 //=======================================================================
1355 Handle(Geom2d_Curve) BiTgte_Blend::PCurveOnFace2
1356 (const Standard_Integer /*Index*/) const
1358 Handle(Geom2d_Curve) C;
1363 //=======================================================================
1364 //function : Curve2OnFillet
1366 //=======================================================================
1368 Handle(Geom2d_Curve) BiTgte_Blend::PCurve2OnFillet
1369 (const Standard_Integer /*Index*/) const
1371 Handle(Geom2d_Curve) C;
1377 //=======================================================================
1378 //function : NbBranches
1380 //=======================================================================
1382 Standard_Integer BiTgte_Blend::NbBranches()
1384 if (myNbBranches != -1) return myNbBranches;
1386 // else, compute the Branches.
1387 BRepTools_Quilt Glue;
1389 Standard_Integer NbFaces = myCenters.Extent();
1392 if (NbFaces == 0) return 0;
1396 for ( i = 1; i <= NbFaces; i++) {
1397 const TopoDS_Shape& CenterLine = myCenters(i);
1398 Glue.Add(myMapSF(CenterLine).Face());
1401 const TopoDS_Shape Shells = Glue.Shells();
1404 // Reorder Map myCenters.
1405 // The method is brutal and unpolished,
1406 // it is possible to refine it.
1408 TopTools_IndexedMapOfShape tmpMap;
1410 TopExp_Explorer exp(Shells,TopAbs_SHELL);
1411 for (; exp.More(); exp.Next()) {
1415 myIndices = new TColStd_HArray1OfInteger(1,myNbBranches+1);
1417 myIndices->SetValue(1,0);
1418 Standard_Integer Count = 0;
1419 Standard_Integer Index = 2;
1422 exp.Init(Shells,TopAbs_SHELL);
1423 for (; exp.More(); exp.Next()) {
1424 // CurS = the current Shell.
1425 const TopoDS_Shape CurS = exp.Current();
1427 TopExp_Explorer exp2(CurS, TopAbs_FACE);
1428 for (; exp2.More(); exp2.Next()) {
1429 // CurF = the current face of the current Shell.
1430 const TopoDS_Shape CurF = exp2.Current();
1432 for ( i = 1; i <= NbFaces; i++) {
1433 const TopoDS_Shape& Center = myCenters(i);
1434 const TopoDS_Shape& Rakk = myMapSF(Center).Face();
1435 // Rakk = the ith generated connection face
1436 if (CurF.IsEqual(Rakk)) {
1443 myIndices->SetValue(Index, Count);
1448 return myNbBranches;
1452 //=======================================================================
1453 //function : IndicesOfBranche
1455 //=======================================================================
1457 void BiTgte_Blend::IndicesOfBranche
1458 (const Standard_Integer Index,
1459 Standard_Integer& From,
1460 Standard_Integer& To ) const
1462 // Attention to the ranking in myIndices:
1463 // If the branches are 1-4 5-9 10-12, it is ranked in myIndices:
1465 From = myIndices->Value(Index) + 1;
1466 To = myIndices->Value(Index + 1);
1470 //=======================================================================
1471 //function : ComputeCenters
1473 //=======================================================================
1475 void BiTgte_Blend::ComputeCenters()
1480 Standard_Real TolAngle = 2*ASin(myTol/Abs(myRadius*0.5));
1481 myAnalyse.Perform(myShape,TolAngle);
1483 // ------------------------------------------
1484 // calculate faces touched by caps
1485 // ------------------------------------------
1486 TopTools_MapOfShape TouchedByCork;
1487 Touched(myAnalyse, myStopFaces, myShape, TouchedByCork);
1489 // -----------------------
1490 // init of the intersector
1491 // -----------------------
1492 TopAbs_State Side = TopAbs_IN;
1493 if (myRadius < 0.) Side = TopAbs_OUT;
1494 BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
1496 TopTools_DataMapOfShapeBox MapSBox;
1497 TopTools_MapOfShape Done;
1498 //TopTools_MapIteratorOfMapOfShape it;
1501 TopoDS_Compound Co; // to only know on which edges the tubes are made
1504 // ----------------------------------------
1505 // Calculate Sections Face/Face + Propagation
1506 // ----------------------------------------
1507 Standard_Boolean JenRajoute = Standard_True;
1510 while ( JenRajoute) {
1511 JenRajoute = Standard_False;
1513 Standard_Boolean Fini = Standard_False;
1515 TopTools_DataMapOfShapeShape EdgeTgt;
1519 // -------------------------------------------------
1520 // locate in myFaces the Faces connected to myEdges.
1521 // -------------------------------------------------
1522 Fini = Standard_True;
1523 //for (it.Initialize(myEdges); it.More(); it.Next()) {
1524 for (i = 1; i <= myEdges.Extent(); i++) {
1525 const TopoDS_Edge& E = TopoDS::Edge(myEdges(i));
1526 if (BRep_Tool::Degenerated(E)) continue;
1528 const TopTools_ListOfShape& L = myAncestors.FindFromKey(E);
1529 if ( L.Extent() == 1) {
1530 // So this is a free border onwhich the ball should roll.
1533 // set in myStopFaces to not propagate the tube on free border.
1537 TopTools_ListIteratorOfListOfShape itl;
1538 for (itl.Initialize(L); itl.More(); itl.Next()) {
1539 const TopoDS_Shape& Sh = itl.Value();
1540 if ( !myStopFaces.Contains(Sh)) myFaces.Add(itl.Value());
1546 // --------------------------------------------
1547 // Construction of Offsets of all faces.
1548 // --------------------------------------------
1549 //for (it.Initialize(myFaces); it.More(); it.Next()) {
1550 for (i = 1; i <= myFaces.Extent(); i++) {
1551 const TopoDS_Shape& AS = myFaces(i);
1552 if ( myMapSF.IsBound(AS)) continue;
1554 BRepOffset_Offset OF1;
1557 if (AS.ShapeType() == TopAbs_FACE) {
1558 const TopoDS_Face& F = TopoDS::Face(myFaces(i));
1559 if ( TouchedByCork.Contains(F)) {
1560 BRepOffset_Tool::EnLargeFace(F,BigF,Standard_True);
1561 OF1.Init(BigF,myRadius,EdgeTgt);
1564 OF1.Init(F,myRadius,EdgeTgt);
1567 else { // So this is a Free Border edge on which the ball rolls.
1568 OF1.Init(TopoDS::Edge(AS),myRadius);
1571 // ------------------------------------
1572 // Increment the map of created tangents
1573 // ------------------------------------
1574 TopTools_ListOfShape Let;
1575 if ( AS.ShapeType() == TopAbs_FACE) {
1576 myAnalyse.Edges(TopoDS::Face(AS),BRepOffset_Tangent,Let);
1578 TopTools_ListIteratorOfListOfShape itlet(Let);
1580 for ( ; itlet.More(); itlet.Next()) {
1581 const TopoDS_Edge& Cur = TopoDS::Edge(itlet.Value());
1582 if ( !EdgeTgt.IsBound(Cur)) {
1583 TopoDS_Shape aLocalShape = OF1.Generated(Cur);
1584 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
1585 // const TopoDS_Edge& OTE = TopoDS::Edge(OF1.Generated(Cur));
1586 EdgeTgt.Bind(Cur,OF1.Generated(Cur));
1587 TopoDS_Vertex V1,V2,OV1,OV2;
1588 TopExp::Vertices (Cur,V1,V2);
1589 TopExp::Vertices (OTE,OV1,OV2);
1590 TopTools_ListOfShape LE;
1591 if (!EdgeTgt.IsBound(V1)) {
1592 myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
1593 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V1);
1594 if (LE.Extent() == LA.Extent())
1595 EdgeTgt.Bind(V1,OV1);
1597 if (!EdgeTgt.IsBound(V2)) {
1599 myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
1600 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V2);
1601 if (LE.Extent() == LA.Extent())
1602 EdgeTgt.Bind(V2,OV2);
1606 // end of map created tangent
1608 if (OF1.Status() == BRepOffset_Reversed ||
1609 OF1.Status() == BRepOffset_Degenerated ) continue;
1611 const TopoDS_Face& F1 = OF1.Face();
1614 myInitOffsetFace.SetRoot(AS);
1615 myInitOffsetFace.Bind(AS,F1);
1618 BRepBndLib::Add(F1,Box1);
1619 MapSBox.Bind(F1,Box1);
1621 // ---------------------------------------------
1622 // intersection with all already created faces.
1623 // ---------------------------------------------
1624 Fini = !Intersect(AS,F1,MapSBox,OF1,Inter);
1626 if (AS.ShapeType() == TopAbs_FACE) B.Add(Co,AS);
1628 myMapSF.Bind(AS, OF1);
1631 } // end of : while ( !Fini)
1634 //--------------------------------------------------------
1635 // so the offsets were created and intersected.
1636 // now the tubes are constructed.
1637 //--------------------------------------------------------
1638 // Construction of tubes on edge.
1639 //--------------------------------------------------------
1640 BRepOffset_Type OT = BRepOffset_Convex;
1641 if (myRadius < 0.) OT = BRepOffset_Concave;
1643 TopTools_IndexedDataMapOfShapeListOfShape Map;
1644 TopExp::MapShapesAndAncestors(Co,TopAbs_EDGE,TopAbs_FACE,Map);
1645 TopExp::MapShapesAndAncestors(Co,TopAbs_VERTEX,TopAbs_EDGE,Map);
1647 TopExp_Explorer exp(Co,TopAbs_EDGE);
1648 for ( ; exp.More(); exp.Next()) {
1649 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1650 if ( myMapSF.IsBound(E)) continue;
1652 const TopTools_ListOfShape& Anc = Map.FindFromKey(E);
1653 if (Anc.Extent() == 2) {
1654 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1655 if (!L.IsEmpty() && L.First().Type() == OT) {
1656 TopoDS_Shape aLocalShapeGen = myMapSF(Anc.First()).Generated(E);
1657 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShapeGen);
1658 aLocalShapeGen = myMapSF(Anc.Last()) .Generated(E);
1659 TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShapeGen);
1660 // TopoDS_Edge EOn1 = TopoDS::Edge(myMapSF(Anc.First()).Generated(E));
1661 // TopoDS_Edge EOn2 = TopoDS::Edge(myMapSF(Anc.Last()) .Generated(E));
1662 // find if exits tangent edges in the original shape
1663 TopoDS_Edge E1f, E1l;
1664 TopoDS_Vertex V1f, V1l;
1665 TopExp::Vertices(E,V1f,V1l);
1666 TopTools_ListOfShape TangE;
1667 myAnalyse.TangentEdges(E,V1f,TangE);
1668 // find if the pipe on the tangent edges are soon created.
1669 TopTools_ListIteratorOfListOfShape itl(TangE);
1670 Standard_Boolean Find = Standard_False;
1671 for ( ; itl.More() && !Find; itl.Next()) {
1672 if ( myMapSF.IsBound(itl.Value())) {
1673 TopoDS_Shape aLocalShape = myMapSF(itl.Value()).Generated(V1f);
1674 E1f = TopoDS::Edge(aLocalShape);
1675 // E1f = TopoDS::Edge(myMapSF(itl.Value()).Generated(V1f));
1676 Find = Standard_True;
1680 myAnalyse.TangentEdges(E,V1l,TangE);
1681 // find if the pipe on the tangent edges are soon created.
1682 itl.Initialize(TangE);
1683 Find = Standard_False;
1684 for ( ; itl.More() && !Find; itl.Next()) {
1685 if ( myMapSF.IsBound(itl.Value())) {
1686 TopoDS_Shape aLocalShape = myMapSF(itl.Value()).Generated(V1l);
1687 E1l = TopoDS::Edge(aLocalShape);
1688 // E1l = TopoDS::Edge(myMapSF(itl.Value()).Generated(V1l));
1689 Find = Standard_True;
1692 BRepOffset_Offset OF1 (E,EOn1,EOn2,myRadius,E1f, E1l);
1693 const TopoDS_Face& F1 = OF1.Face();
1696 myInitOffsetFace.SetRoot(E);
1697 myInitOffsetFace.Bind(E,F1);
1700 BRepBndLib::Add(F1,Box1);
1701 MapSBox.Bind(F1,Box1);
1703 // ---------------------------------------------
1704 // intersection with all already created faces.
1705 // ---------------------------------------------
1706 Standard_Boolean IsOnRest = Intersect(E,F1,MapSBox,OF1,Inter);
1707 JenRajoute = JenRajoute || IsOnRest;
1709 myMapSF.Bind(E,OF1);
1714 } // end while JenRajoute
1718 myEdges = Inter.NewEdges();
1720 // -------------------------------------------------------------------
1721 // now it is necessary to limit edges on the neighbors (otherwise one
1722 // will go too far and will not be able to construct faces).
1723 // -------------------------------------------------------------------
1725 // Proceed with MakeLoops
1726 TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
1727 BRepOffset_Type OT = BRepOffset_Concave;
1728 if (myRadius < 0.) OT = BRepOffset_Convex;
1730 TopTools_ListOfShape LOF;
1731 //it.Initialize(myFaces);
1732 for (i = 1; i <= myFaces.Extent(); i++) {
1733 const TopoDS_Shape& CurS = myFaces(i);
1735 // tube on free border, it is undesirable.
1736 if ( myStopFaces.Contains(CurS)) continue;
1738 if ( !myMapSF.IsBound(CurS)) continue; // inverted or degenerated
1740 const TopoDS_Face& CurOF = myMapSF(CurS).Face();
1743 if (CurS.ShapeType() == TopAbs_FACE) {
1744 const TopoDS_Face& CurF = TopoDS::Face(CurS);
1745 TopExp_Explorer expe(CurF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1746 for (; expe.More(); expe.Next()) {
1747 // --------------------------------------------------------------
1748 // set in myAsDes the edges generated by limitations of the
1749 // initial square if the type is correct (The edges that will
1750 // disappear are not set)
1751 // --------------------------------------------------------------
1752 const TopoDS_Edge& CurE = TopoDS::Edge(expe.Current());
1753 const BRepOffset_ListOfInterval& L = myAnalyse.Type(CurE);
1754 if (!L.IsEmpty() && L.First().Type() != OT) {
1755 // a priori doe s not disappear, so it is set
1756 TopoDS_Shape aLocalShape = myMapSF(CurF).Generated(CurE);
1757 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
1758 // const TopoDS_Edge& CurOE =
1759 // TopoDS::Edge(myMapSF(CurF).Generated(CurE));
1760 myAsDes->Add(CurOF,CurOE.Oriented(CurE.Orientation()));
1763 const TopTools_ListOfShape& Lanc = myAnalyse.Ancestors(CurE);
1764 if ( !myFaces .Contains(Lanc.First())
1765 || !myFaces .Contains(Lanc.Last ())
1766 || myStopFaces.Contains(Lanc.First())
1767 || myStopFaces.Contains(Lanc.Last ())) {
1768 TopoDS_Shape aLocalShape = myMapSF(CurF).Generated(CurE);
1769 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
1770 // const TopoDS_Edge& CurOE =
1771 // TopoDS::Edge(myMapSF(CurF).Generated(CurE));
1772 myAsDes->Add(CurOF,CurOE.Oriented(CurE.Orientation()));
1776 BRepOffset_Inter2d::Compute(myAsDes,
1784 // ----------------------------------------------------------------
1785 // It is also required to make 2D intersections with generated tubes
1786 // (Useful for unwinding)
1787 // ----------------------------------------------------------------
1788 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(myMapSF);
1789 for ( ; It.More(); It.Next()) {
1790 const TopoDS_Shape& CurS = It.Key();
1791 if ( CurS.ShapeType() == TopAbs_FACE) continue;
1793 const TopoDS_Face& CurOF = It.Value().Face();
1795 // no unwinding by tubes on free border.
1796 if ( myStopFaces.Contains(CurS)) continue;
1800 // --------------------------------------------------------------
1801 // set in myAsDes the edge restrictions of the square
1802 // --------------------------------------------------------------
1803 TopExp_Explorer expe(CurOF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1804 for (; expe.More(); expe.Next()) {
1805 const TopoDS_Edge& CurOE = TopoDS::Edge(expe.Current());
1806 myAsDes->Add(CurOF,CurOE);
1809 BRepOffset_Inter2d::Compute(myAsDes,
1816 // fuse vertices on edges stored in AsDes
1817 BRepOffset_Inter2d::FuseVertices(aDMVV, 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 std::cout << " No Lines of Generated Centers" << std::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 // --------------------------------------------------------------------
1912 //TopTools_MapIteratorOfMapOfShape ic(myEdges);
1914 for (i = 1; i <= myEdges.Extent(); i++) {
1915 const TopoDS_Edge& CurE = TopoDS::Edge(myEdges(i));
1917 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1918 if ( L.Extent() != 2) continue;
1920 // --------------------------------------------------------------
1921 // F1 and F2 = 2 parallel faces intersecting in CurE.
1922 // --------------------------------------------------------------
1923 const TopoDS_Face& F1 = TopoDS::Face(L.First());
1924 const TopoDS_Face& F2 = TopoDS::Face(L.Last());
1926 // -----------------------------------------------------
1927 // find the orientation of edges of intersection
1928 // in the initial faces.
1929 // -----------------------------------------------------
1930 const TopTools_ListOfShape& LD1 = myAsDes->Descendant(F1);
1931 const TopTools_ListOfShape& LD2 = myAsDes->Descendant(F2);
1933 TopAbs_Orientation Orien1 = Orientation(CurE, F1, LD1);
1934 TopAbs_Orientation Orien2 = Orientation(CurE, F2, LD2);
1936 // ---------------------------------------------------------
1937 // Or1 and Or2 : the shapes generators of parallel faces
1938 // ---------------------------------------------------------
1939 const TopoDS_Shape& Or1 = myInitOffsetFace.ImageFrom(F1);
1940 const TopoDS_Shape& Or2 = myInitOffsetFace.ImageFrom(F2);
1945 TopoDS_Edge OE1, OE2;
1946 TopoDS_Face OF1, OF2;
1947 TopLoc_Location Loc;
1948 Standard_Real f1,l1,f2,l2;
1950 Standard_Boolean OF1isEdge = Standard_False;
1952 if ( Or1.ShapeType() == TopAbs_EDGE) {
1953 OF1isEdge = Standard_True;
1954 OE1 = TopoDS::Edge(Or1);
1955 GC1 = BRep_Tool::Curve(OE1,Loc,f1,l1);
1957 Handle(Geom_Curve)::DownCast(GC1->Transformed(Loc.Transformation()));
1959 else if ( Or1.ShapeType() == TopAbs_FACE) {
1960 OF1 = TopoDS::Face(Or1);
1961 GS1 = BRep_Tool::Surface(OF1);
1964 // ----------------------------------------------------------------
1965 // If a vertex is used in contact, currently nothing is done
1966 // and the vertexes are not managed (Intersections with sphere);
1967 // ----------------------------------------------------------------
1968 if ( OF1.IsNull() && OE1.IsNull()) continue;
1970 Standard_Boolean OF2isEdge = Standard_False;
1972 if ( Or2.ShapeType() == TopAbs_EDGE) {
1973 OF2isEdge = Standard_True;
1974 OE2 = TopoDS::Edge(Or2);
1975 GC2 = BRep_Tool::Curve(OE2,Loc,f2,l2);
1977 Handle(Geom_Curve)::
1978 DownCast(GC2->Transformed(Loc.Transformation()));
1980 else if ( Or2.ShapeType() == TopAbs_FACE) {
1981 OF2 = TopoDS::Face(Or2);
1982 GS2 = BRep_Tool::Surface(OF2);
1984 // ----------------------------------------------------------------
1985 // If a vertex is used in contact, currently nothing is done
1986 // and the vertexes are not managed (Intersections with sphere);
1987 // ----------------------------------------------------------------
1988 if ( OF2.IsNull() && OE2.IsNull()) continue;
1991 TopTools_ListOfShape CurL;
1993 if ( !myImageOffset.HasImage(CurE)) {// the tubes are not unwinded
1994 if ( OF1isEdge && OF2isEdge) { // if I don't have the image, possibly
1995 CurL.Append(CurE); // I'm on intersection tube-tube
1996 } // See comment on the call to
2001 myImageOffset.LastImage(CurE,CurL);
2004 // ---------------------------------------------------------------
2005 // CurL = List of edges descending from CurE ( = Cuts of CurE)
2006 // ---------------------------------------------------------------
2007 TopTools_ListIteratorOfListOfShape itl(CurL);
2008 for ( ; itl.More(); itl.Next()) {
2009 const TopoDS_Edge& CurCutE = TopoDS::Edge(itl.Value());
2011 Handle(Geom2d_Curve) PC1 =
2012 BRep_Tool::CurveOnSurface(CurCutE,F1,f1,l1);
2013 Handle(Geom2d_Curve) PC2 =
2014 BRep_Tool::CurveOnSurface(CurCutE,F2,f2,l2);
2015 if ( PC1.IsNull() || PC2.IsNull()) {
2017 std::cout << "No PCurves on Intersections : No tubes constructed";
2018 std::cout << std::endl;
2023 TopoDS_Edge E1f, E1l;
2024 TopoDS_Vertex V1f, V1l;
2025 TopoDS_Vertex VfOnE1,VlOnE1,VfOnE2,VlOnE2;
2026 TopTools_ListOfShape TangE;
2027 TopTools_MapOfShape MapOnV1f, MapOnV1l;
2029 TopExp::Vertices(CurCutE,V1f,V1l);
2031 // find if the pipe on the tangent edges are soon created.
2032 // edges generated by V1f and V1l + Maj MapOnV1f/l
2033 E1f = FindCreatedEdge(V1f,CurCutE,myMapSF,MapOnV1f,
2034 CenterAnalyse,myRadius,myTol);
2036 E1l = FindCreatedEdge(V1l,CurCutE,myMapSF,MapOnV1l,
2037 CenterAnalyse,myRadius,myTol);
2041 BiTgte_CurveOnEdge ConE(CurCutE, OE1);
2042 Handle(Geom_Curve) C = MakeCurve(ConE);
2043 gp_Pnt P1 = C->Value(C->FirstParameter());
2044 gp_Pnt P2 = C->Value(C->LastParameter());
2045 VfOnE1 = FindVertex(P1,MapOnV1f,myTol);
2046 if ( VfOnE1.IsNull())
2047 VfOnE1 = FindVertex(P1,MapOnV1l,myTol);
2048 VlOnE1 = FindVertex(P2,MapOnV1l,myTol);
2049 if ( VlOnE1.IsNull())
2050 VlOnE1 = FindVertex(P2,MapOnV1f,myTol);
2051 if ( P1.SquareDistance(P2) < myTol*myTol) {
2052 //BRepOffset_Offset manages degenerated KPart
2053 //It is REQUIRED that C should be a circle with ZERO radius
2054 E1 = MakeDegeneratedEdge(C,VfOnE1);
2057 E1 = BRepLib_MakeEdge(C,VfOnE1,VlOnE1);
2062 P2d = PC1->Value(f1);
2063 gp_Pnt P1 = GS1->Value(P2d.X(),P2d.Y());
2064 P2d = PC1->Value(l1);
2065 gp_Pnt P2 = GS1->Value(P2d.X(),P2d.Y());
2066 VfOnE1 = FindVertex(P1,MapOnV1f,myTol);
2067 VlOnE1 = FindVertex(P2,MapOnV1l,myTol);
2068 BRepLib_MakeEdge MKE(PC1,GS1,VfOnE1,VlOnE1,f1,l1);
2072 std::cout << "Edge Not Done" << std::endl;
2076 KPartCurve3d(E1,PC1,GS1);
2080 BiTgte_CurveOnEdge ConE(CurCutE, OE2);
2081 Handle(Geom_Curve) C = MakeCurve(ConE);
2082 gp_Pnt P1 = C->Value(C->FirstParameter());
2083 gp_Pnt P2 = C->Value(C->LastParameter());
2084 VfOnE2 = FindVertex(P1,MapOnV1f,myTol);
2085 if ( VfOnE2.IsNull())
2086 VfOnE2 = FindVertex(P1,MapOnV1l,myTol);
2087 VlOnE2 = FindVertex(P2,MapOnV1l,myTol);
2088 if ( VlOnE2.IsNull())
2089 VlOnE2 = FindVertex(P2,MapOnV1f,myTol);
2090 if ( P1.SquareDistance(P2) < myTol*myTol) {
2091 //BRepOffset_Offset manages degenerated KParts
2092 //It is REQUIRED that C should be a circle with ZERO radius
2093 E2 = MakeDegeneratedEdge(C,VfOnE2);
2096 E2 = BRepLib_MakeEdge(C,VfOnE2,VlOnE2);
2101 P2d = PC2->Value(f2);
2102 gp_Pnt P1 = GS2->Value(P2d.X(),P2d.Y());
2103 P2d = PC2->Value(l2);
2104 gp_Pnt P2 = GS2->Value(P2d.X(),P2d.Y());
2105 VfOnE2 = FindVertex(P1,MapOnV1f,myTol);
2106 VlOnE2 = FindVertex(P2,MapOnV1l,myTol);
2107 BRepLib_MakeEdge MKE(PC2,GS2,VfOnE2,VlOnE2,f2,l2);
2111 std::cout << "edge not Done" << std::endl;
2114 KPartCurve3d(E2,PC2,GS2);
2116 // Increment of the Map of Created if reconstruction of the Shape is required
2117 if ( myBuildShape) {
2118 myCreated.Bind(CurCutE,EmptyMap);
2120 myCreated(CurCutE).Bind(Or1,Empty);
2121 myCreated(CurCutE)(Or1).Append(E1);
2123 myCreated(CurCutE).Bind(Or2,Empty);
2124 myCreated(CurCutE)(Or2).Append(E2);
2127 // ----------------------------------------------------------
2128 // try to init E1f, E1l, if not found with Analysis.
2129 // Should happen only if the THEORETICALLY tangent edges
2130 // are not actually tangent ( Cf: Approximation of lines
2131 // of intersection that add noise.)
2132 // ----------------------------------------------------------
2133 TopoDS_Vertex aVertex1, aVertex2;
2134 if ( E1f.IsNull() && !VfOnE1.IsNull() && !VfOnE2.IsNull()) {
2135 TopTools_MapIteratorOfMapOfShape it(MapOnV1f);
2136 for ( ; it.More(); it.Next()) {
2137 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
2139 TopExp::Vertices(E, aVertex1, aVertex2);
2140 if ((aVertex1.IsSame(VfOnE1) && aVertex2.IsSame(VfOnE2)) ||
2141 (aVertex2.IsSame(VfOnE1) && aVertex1.IsSame(VfOnE2)) ) {
2148 if ( E1l.IsNull() && !VlOnE1.IsNull() && !VlOnE2.IsNull()) {
2149 TopTools_MapIteratorOfMapOfShape it(MapOnV1l);
2150 for ( ; it.More(); it.Next()) {
2151 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
2153 TopExp::Vertices(E, aVertex1, aVertex2);
2154 if ((aVertex1.IsSame(VlOnE1) && aVertex2.IsSame(VlOnE2)) ||
2155 (aVertex2.IsSame(VlOnE1) && aVertex1.IsSame(VlOnE2)) ) {
2163 E1.Orientation(Orien1);
2164 E2.Orientation(Orien2);
2166 BRepOffset_Offset AnOffset(CurCutE,E1,E2,-myRadius,E1f,E1l,
2167 myNubs, myTol, GeomAbs_C2);
2168 myMapSF.Bind(CurCutE,AnOffset);
2169 myCenters.Add(CurCutE);
2172 const TopoDS_Face& Tuyo = AnOffset.Face();
2173 B.Add(myResult,Tuyo);
2175 if ( myBuildShape) {
2176 // method based ONLY on the construction of fillet:
2177 // the first edge of the tube is exactly on Shape1.
2178 GeomAPI_ProjectPointOnCurve Projector;
2179 TopExp_Explorer exp(Tuyo,TopAbs_EDGE);
2180 TopoDS_Vertex V1,V2;
2181 if (OF1isEdge) { // Update CutEdges.
2182 const TopoDS_Edge& EOnF1 = TopoDS::Edge(exp.Current());
2183 TopExp::Vertices(EOnF1,V1,V2);
2185 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2186 Projector.Init(P1,GC1);
2187 Standard_Real U1 = Projector.LowerDistanceParameter();
2189 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2190 Projector.Init(P2,GC1);
2191 Standard_Real U2 = Projector.LowerDistanceParameter();
2193 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
2194 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,TopoDS::Edge(Or1),myTol);
2195 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
2196 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,TopoDS::Edge(Or1),myTol);
2197 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),U1,
2198 // TopoDS::Edge(Or1),myTol);
2199 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),U2,
2200 // TopoDS::Edge(Or1),myTol);
2202 if (!myCutEdges.IsBound(Or1)) {
2203 TopTools_ListOfShape Dummy;
2204 myCutEdges.Bind(Or1,Dummy);
2206 TopTools_ListOfShape& L1 = myCutEdges(Or1);
2207 L1.Append(V1); L1.Append(V2);
2209 if (OF2isEdge) { // Update CutEdges.
2211 const TopoDS_Edge& EOnF2 = TopoDS::Edge(exp.Current());
2212 TopExp::Vertices(EOnF2,V1,V2);;
2214 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2215 Projector.Init(P1,GC2);
2216 Standard_Real U1 = Projector.LowerDistanceParameter();
2218 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2219 Projector.Init(P2,GC2);
2220 Standard_Real U2 = Projector.LowerDistanceParameter();
2222 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
2223 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,TopoDS::Edge(Or2),myTol);
2224 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
2225 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,TopoDS::Edge(Or2),myTol);
2226 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),U1,
2227 // TopoDS::Edge(Or2),myTol);
2228 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),U2,
2229 // TopoDS::Edge(Or2),myTol);
2231 if (!myCutEdges.IsBound(Or2)) {
2232 TopTools_ListOfShape Dummy;
2233 myCutEdges.Bind(Or2,Dummy);
2235 TopTools_ListOfShape& L2 = myCutEdges(Or2);
2236 L2.Append(V1); L2.Append(V2);
2242 sprintf(name,"%s_%d","SURF",nbc);
2243 DBRep::Set(name,AnOffset.Face());
2250 // ---------------------------------------------------
2251 // Construction of spheres,
2252 // if enough tubes arrive at the vertex
2253 // ---------------------------------------------------
2254 TopTools_IndexedDataMapOfShapeListOfShape Map;
2255 TopExp::MapShapesAndAncestors(Co,TopAbs_VERTEX,TopAbs_EDGE,Map);
2257 for ( Standard_Integer j = 1; j <= Map.Extent(); j++) {
2258 const TopoDS_Vertex& V = TopoDS::Vertex(Map.FindKey(j));
2259 if ( Map(j).Extent() != 3) continue;
2261 TopTools_ListOfShape LOE;
2262 TopTools_ListIteratorOfListOfShape it;
2264 for (it.Initialize(Map(j)) ; it.More(); it.Next()) {
2265 Standard_Boolean Reverse = Standard_True;
2267 LOE.Append(myMapSF(it.Value()).Generated(V).Reversed());
2269 LOE.Append(myMapSF(it.Value()).Generated(V));
2272 BRepOffset_Offset OFT(V,LOE,-myRadius,myNubs, myTol, GeomAbs_C2);
2273 myMapSF.Bind(V,OFT);
2276 B.Add(myResult,OFT.Face());
2280 sprintf(name,"%s_%d","SURF",nbc);
2281 DBRep::Set(name,OFT.Face());
2289 //=======================================================================
2290 //function : ComputeShape
2292 //=======================================================================
2293 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
2294 #include <Geom_Curve.hxx>
2296 void BiTgte_Blend::ComputeShape()
2298 // Find in the initial Shapel:
2299 // - untouched Faces
2300 // - generated tubes
2301 // - the faces neighbors of tubes that sould be reconstucted preserving sharing.
2303 // For Debug : Visualize edges of the initial shape that should be reconstructed.
2306 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myCutEdges);
2307 Standard_Integer NbEdges = 0;
2308 for ( ; itm.More(); itm.Next()) {
2309 const TopoDS_Edge& E = TopoDS::Edge(itm.Key());
2310 const TopTools_ListOfShape& VonE = itm.Value();
2311 TopTools_ListOfShape NewE;
2313 CutEdge(E,VonE,NewE);
2314 for (TopTools_ListIteratorOfListOfShape it(NewE); it.More(); it.Next()) {
2315 sprintf(name,"%s_%d","CUTE",++NbEdges);
2316 DBRep::Set(name,it.Value());
2323 TopTools_DataMapOfShapeShape Created;
2325 TopTools_ListOfShape Empty;
2326 TopTools_DataMapOfShapeListOfShape EmptyMap;
2331 // Maj of the Map of created.
2332 // Update edges that do not change in the resulting shape
2333 // i.e. invariant edges in the unwinding.
2334 TopExp_Explorer exp(myShape,TopAbs_FACE);
2335 // Standard_Integer nbe = 1;
2336 for ( ;exp.More(); exp.Next()) {
2338 const TopoDS_Face& CurF = TopoDS::Face(exp.Current());
2340 if ( !myFaces.Contains(CurF)) continue; // so the face is not touched
2342 // so the faces are unwinded
2343 if ( !myMapSF.IsBound(CurF)) continue; // inverted or degenerated
2345 const BRepOffset_Offset& Offset = myMapSF(CurF);
2346 const TopoDS_Face& CurOF = myMapSF(CurF).Face();
2348 if ( !myImageOffset.HasImage(CurOF)) // face disappears in unwinding
2351 TopExp_Explorer exp2(CurF,TopAbs_EDGE);
2352 for ( ;exp2.More(); exp2.Next()) {
2353 const TopoDS_Edge& CurE = TopoDS::Edge(exp2.Current());
2354 TopoDS_Shape aLocalShape = Offset.Generated(CurE);
2355 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
2356 // const TopoDS_Edge& CurOE = TopoDS::Edge(Offset.Generated(CurE));
2358 if (!myImageOffset.HasImage(CurOE)) continue;
2361 const TopoDS_Edge& ImE =
2362 TopoDS::Edge(myImageOffset.Image(CurOE).First());
2363 if (ImE.IsSame(CurOE)) {
2364 myCreated.Bind(CurOE,EmptyMap);
2365 myCreated(CurOE).Bind(CurF,Empty);
2366 myCreated(CurOE)(CurF).Append(CurE);
2371 // The connected faces are already in myResult.
2372 // So it is necessary to add faces:
2373 // - non-touched (so not in myFaces)
2374 // - issuing from the unwinding (non degenerated, non inverted, non disappeared)
2375 exp.Init(myShape,TopAbs_FACE);
2376 for ( ;exp.More(); exp.Next()) {
2378 const TopoDS_Face& CurF = TopoDS::Face(exp.Current());
2380 if ( !myFaces.Contains(CurF)) {
2381 // so the face is not touched
2382 B.Add(myResult,CurF);
2384 else { // so the faces are unwindeds
2386 if ( !myMapSF.IsBound(CurF)) continue; // inverted or degenerated
2388 const TopoDS_Face& CurOF = myMapSF(CurF).Face();
2390 if ( !myImageOffset.HasImage(CurOF)) // face disappears in unwinding
2393 // List of faces generated by a face in the unwinding
2394 TopTools_ListOfShape Lim;
2395 myImageOffset.LastImage(CurOF,Lim);
2396 TopTools_ListIteratorOfListOfShape itLim(Lim);
2397 for ( ;itLim.More(); itLim.Next()) {
2398 // DeboucFace = offset Face unwinded in "Debouc".
2399 const TopoDS_Face& DeboucFace = TopoDS::Face(itLim.Value());
2402 Handle(Geom_Surface) S = BRep_Tool::Surface(CurF,L);
2404 TopoDS_Face NewF; B.MakeFace(NewF);
2405 B.UpdateFace(NewF,S,L,BRep_Tool::Tolerance(CurF));
2407 TopTools_DataMapOfShapeShape MapSS;
2409 TopoDS_Shape aLocalShape = DeboucFace.Oriented(TopAbs_FORWARD);
2410 const TopoDS_Face& Face = TopoDS::Face(aLocalShape);
2411 // const TopoDS_Face& Face =
2412 // TopoDS::Face(DeboucFace.Oriented(TopAbs_FORWARD));
2413 TopExp_Explorer exp2(Face, TopAbs_EDGE);
2414 for ( ; exp2.More(); exp2.Next()) {
2415 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
2416 TopoDS_Vertex V1,V2,OV1,OV2;
2417 TopExp::Vertices(E ,V1 ,V2 );
2418 if (myCreated.IsBound(E)) {
2419 if (myCreated(E).IsBound(CurF)) {
2420 const TopoDS_Edge& OE = TopoDS::Edge(myCreated(E)(CurF).First());
2421 TopExp::Vertices(OE,OV1,OV2);
2422 if ( !myCreated.IsBound(V1)) myCreated.Bind(V1,EmptyMap);
2423 if ( !myCreated.IsBound(V2)) myCreated.Bind(V2,EmptyMap);
2424 if ( !myCreated(V1).IsBound(CurF)) {
2425 myCreated(V1).Bind(CurF,Empty);
2426 myCreated(V1)(CurF).Append(OV1);
2428 if ( !myCreated(V2).IsBound(CurF)) {
2429 myCreated(V2).Bind(CurF,Empty);
2430 myCreated(V2)(CurF).Append(OV2);
2436 TopExp_Explorer expw(Face, TopAbs_WIRE);
2437 for ( ; expw.More(); expw.Next()) {
2438 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
2439 TopExp_Explorer expe(W.Oriented(TopAbs_FORWARD),
2444 for ( ; expe.More(); expe.Next()) {
2445 const TopoDS_Edge& E = TopoDS::Edge(expe.Current());
2447 Handle(Geom2d_Curve) C2d =
2448 BRep_Tool::CurveOnSurface(E,Face,f,l);
2450 if ( MapSS.IsBound(E)) { // this is an edge of cutting
2451 OE = TopoDS::Edge(MapSS(E));
2452 TopoDS_Shape aLocalShapeReversedE = E.Reversed();
2453 Handle(Geom2d_Curve) C2d_1 =
2454 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShapeReversedE),Face,f,l);
2455 // Handle(Geom2d_Curve) C2d_1 =
2456 // BRep_Tool::CurveOnSurface(TopoDS::Edge(E.Reversed()),
2458 if ( E.Orientation() == TopAbs_FORWARD)
2459 B.UpdateEdge(OE,C2d,C2d_1,NewF,BRep_Tool::Tolerance(E));
2461 B.UpdateEdge(OE,C2d_1,C2d,NewF,BRep_Tool::Tolerance(E));
2465 // Is there an image in the Map of Created ?
2466 if ( myCreated.IsBound(E)) {
2467 if ( myCreated(E).IsBound(CurF)) {
2468 OE = TopoDS::Edge(myCreated(E)(CurF).First());
2473 TopoDS_Vertex V1,V2,OV1,OV2;
2474 TopExp::Vertices(E,V1,V2);
2475 if ( myCreated.IsBound(V1) && myCreated(V1).IsBound(CurF)) {
2476 OV1 = TopoDS::Vertex(myCreated(V1)(CurF).First());
2481 C2d->Value(BRep_Tool::Parameter(V1,E,Face));
2483 S->D0(P2d.X(),P2d.Y(),P);
2484 P.Transform(L.Transformation());
2485 B.UpdateVertex(OV1,P,BRep_Tool::Tolerance(V1));
2486 myCreated.Bind(V1,EmptyMap);
2487 myCreated(V1).Bind(CurF,Empty);
2488 myCreated(V1)(CurF).Append(OV1);
2490 if ( myCreated.IsBound(V2) && myCreated(V2).IsBound(CurF)) {
2491 OV2 = TopoDS::Vertex(myCreated(V2)(CurF).First());
2496 C2d->Value(BRep_Tool::Parameter(V2,E,Face));
2498 S->D0(P2d.X(),P2d.Y(),P);
2499 P.Transform(L.Transformation());
2500 B.UpdateVertex(OV2,P,BRep_Tool::Tolerance(V2));
2501 myCreated.Bind(V2,EmptyMap);
2502 myCreated(V2).Bind(CurF,Empty);
2503 myCreated(V2)(CurF).Append(OV2);
2505 B.Add(OE,OV1.Oriented(V1.Orientation()));
2506 B.Add(OE,OV2.Oriented(V2.Orientation()));
2508 B.UpdateEdge(OE,C2d,NewF,BRep_Tool::Tolerance(E));
2510 // ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
2513 B.Add(OW, OE.Oriented(E.Orientation()));
2515 B.Add(NewF, OW.Oriented(W.Orientation()));
2518 NewF.Orientation(DeboucFace.Orientation());
2520 BRepTools::Update(NewF);
2521 B.Add(myResult,NewF);
2526 // non-regarding the cause, there always remain greeb borders on this Shape, so it is sewn.
2527 Handle(BRepBuilderAPI_Sewing) Sew = new BRepBuilderAPI_Sewing(myTol);
2529 BRepLib::BuildCurves3d(myResult);
2531 exp.Init(myResult,TopAbs_FACE);
2532 for ( ;exp.More(); exp.Next())
2533 Sew->Add(exp.Current());
2537 // SameParameter is done in case Sew does not do it (Detect that the edges
2538 // are not sameparameter but does nothing.)
2540 const TopoDS_Shape& SewedShape = Sew->SewedShape();
2541 if ( !SewedShape.IsNull()) {
2542 exp.Init(Sew->SewedShape(), TopAbs_EDGE);
2543 for (; exp.More(); exp.Next()) {
2544 const TopoDS_Edge& sec = TopoDS::Edge(exp.Current());
2545 BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
2547 myResult = SewedShape;
2552 //=======================================================================
2553 //function : Intersect
2555 //=======================================================================
2557 Standard_Boolean BiTgte_Blend::Intersect
2558 (const TopoDS_Shape& Init,
2559 const TopoDS_Face& Face,
2560 const TopTools_DataMapOfShapeBox& MapSBox,
2561 const BRepOffset_Offset& OF1,
2562 BRepOffset_Inter3d& Inter)
2564 Standard_Boolean JenRajoute = Standard_False;
2566 const Bnd_Box& Box1 = MapSBox(Face);
2568 // -----------------------------------------------
2569 // intersection with all already created faces.
2570 // -----------------------------------------------
2571 const TopoDS_Shape& InitShape1 = OF1.InitialShape();
2572 Standard_Boolean F1surBordLibre =
2573 InitShape1.ShapeType() == TopAbs_EDGE &&
2574 myStopFaces.Contains(InitShape1);
2576 TopTools_MapOfShape Done;
2577 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(myMapSF);
2578 for ( ; It.More(); It.Next()) {
2579 const BRepOffset_Offset& OF2 = It.Value();
2580 const TopoDS_Face& F2 = OF2.Face();
2582 if (Box1.IsOut(MapSBox(F2))) continue;
2584 if ( Inter.IsDone(Face,F2)) continue;
2586 // 2 tubes created on free border are not intersected.
2587 const TopoDS_Shape& InitShape2 = OF2.InitialShape();
2588 Standard_Boolean F2surBordLibre =
2589 InitShape2.ShapeType() == TopAbs_EDGE &&
2590 myStopFaces.Contains(InitShape2);
2593 if ( F1surBordLibre && F2surBordLibre) {
2594 std::cout << "Rejection : 2 tubes on free border are not intersected";
2595 std::cout << std::endl;
2599 if ( F1surBordLibre && F2surBordLibre) continue;
2601 // -------------------------------------------------------
2602 // Tubes are not intersected with neighbor faces.
2603 // -------------------------------------------------------
2604 const TopoDS_Shape& ItKey = It.Key();
2606 if ( Init.ShapeType() == TopAbs_EDGE) {
2607 if (ItKey.ShapeType() == TopAbs_FACE &&
2608 IsInFace(TopoDS::Edge(Init), TopoDS::Face(ItKey))) continue;
2611 Inter.FaceInter(Face,F2,myInitOffsetFace);
2613 // ------------------------------------------
2614 // an edge of F1 or F2 has been touched ?
2615 // if yes, add faces in myFaces
2616 // ==> JenRajoute = True
2617 // ------------------------------------------
2618 TopTools_ListOfShape LInt;
2620 if (myAsDes->HasCommonDescendant(Face,F2,LInt)) {
2621 TopTools_ListIteratorOfListOfShape itl2;
2622 for (itl2.Initialize(LInt); itl2.More(); itl2.Next()) {
2623 const TopoDS_Edge& CurE = TopoDS::Edge(itl2.Value());
2624 TopoDS_Vertex V1,V2;
2626 TopExp::Vertices(CurE,V1,V2);
2628 if ( Done.Add(V1)) {
2629 Standard_Boolean IsOnR1 = IsOnRestriction(V1,CurE,Face,E1);
2630 Standard_Boolean IsOnR2 = IsOnRestriction(V1,CurE,F2,E2);
2632 if (IsOnR1 && IsOnR2) {
2633 std::cout << "Leave in the same tps on 2 faces, ";
2634 std::cout << "propagation only on free border";
2635 std::cout << std::endl;
2639 if ( !myStopFaces.Contains(Init)) {
2640 Add(E1,myEdges,Init,OF1,myAnalyse,IsOnR1 && IsOnR2);
2641 JenRajoute = Standard_True;
2645 if ( !myStopFaces.Contains(ItKey)) {
2646 Add(E2,myEdges, ItKey,OF2,myAnalyse,IsOnR1 && IsOnR2);
2647 JenRajoute = Standard_True;
2652 if ( Done.Add(V2)) {
2653 Standard_Boolean IsOnR1 = IsOnRestriction(V2,CurE,Face,E1);
2654 Standard_Boolean IsOnR2 = IsOnRestriction(V2,CurE,F2,E2);
2656 // If IsOnR1 && IsOnR2,
2657 // Leave in the same tps on 2 faces, propagate only on
2659 // A priori, only facet is closed.
2661 if (IsOnR1 && IsOnR2) {
2662 std::cout << "Leave with the same tps on 2 faces, ";
2663 std::cout << "propagate only if the border is free";
2664 std::cout << std::endl;
2668 if ( !myStopFaces.Contains(Init)) {
2669 Add(E1,myEdges,Init,OF1,myAnalyse,IsOnR1 && IsOnR2);
2670 JenRajoute = Standard_True;
2674 if ( !myStopFaces.Contains(ItKey)) {
2675 Add(E2,myEdges,ItKey,OF2,myAnalyse,IsOnR1 && IsOnR2);
2676 JenRajoute = Standard_True;