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.
19 #include <BiTgte_Blend.ixx>
22 // - all small static functions.
24 //======================== START STATIC FUNCTIONS ============
25 #include <BiTgte_DataMapOfShapeBox.hxx>
26 #include <BiTgte_CurveOnEdge.hxx>
28 #include <Bnd_Box.hxx>
29 #include <BRepBndLib.hxx>
30 #include <BRepTools.hxx>
31 #include <BRepTools_Quilt.hxx>
32 #include <BRepBuilderAPI_Sewing.hxx>
33 #include <BRep_Tool.hxx>
34 #include <BRep_Builder.hxx>
35 #include <BRepLib_MakeEdge.hxx>
36 #include <BRepOffset_DataMapOfShapeOffset.hxx>
37 #include <BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx>
38 #include <BRepOffset_Offset.hxx>
39 #include <BRepOffset_MakeLoops.hxx>
40 #include <BRepOffset_Inter3d.hxx>
41 #include <BRepOffset_Inter2d.hxx>
42 #include <BRepOffset_Interval.hxx>
43 #include <BRepOffset_ListOfInterval.hxx>
44 #include <BRepOffset_Tool.hxx>
45 #include <BRepAlgo_Loop.hxx>
47 #include <GeomAbs_SurfaceType.hxx>
48 #include <GeomAPI_ProjectPointOnCurve.hxx>
49 #include <Geom_BSplineCurve.hxx>
50 #include <Geom_TrimmedCurve.hxx>
51 #include <Geom_Circle.hxx>
52 #include <Geom_Line.hxx>
53 #include <Geom2d_Curve.hxx>
54 #include <GeomAdaptor_Surface.hxx>
55 #include <Geom2dAdaptor_Curve.hxx>
56 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
57 #include <TopExp_Explorer.hxx>
58 #include <TopoDS_Wire.hxx>
59 #include <TopoDS_Vertex.hxx>
60 #include <TopoDS_Edge.hxx>
61 #include <TopoDS_Compound.hxx>
62 #include <TopTools_ListOfShape.hxx>
63 #include <TopTools_SequenceOfShape.hxx>
64 #include <TopTools_DataMapOfShapeShape.hxx>
65 #include <TopTools_MapIteratorOfMapOfShape.hxx>
66 #include <TopTools_ListIteratorOfListOfShape.hxx>
68 #include <gp_Pnt2d.hxx>
69 #include <gp_Lin2d.hxx>
71 #include <gp_Dir2d.hxx>
76 #include <gp_Circ.hxx>
77 #include <gp_Sphere.hxx>
79 #include <AppCont_Function.hxx>
80 #include <Approx_FitAndDivide.hxx>
81 #include <AppParCurves_MultiCurve.hxx>
82 #include <BSplCLib.hxx>
83 #include <Convert_CompBezierCurvesToBSplineCurve.hxx>
84 #include <Precision.hxx>
85 #include <TColgp_Array1OfPnt.hxx>
86 #include <TColStd_Array1OfReal.hxx>
87 #include <TColStd_Array1OfInteger.hxx>
89 #include <Standard_NotImplemented.hxx>
91 #include <BRepLib.hxx>
93 #include <GeomAPI.hxx>
97 #include <OSD_Chronometer.hxx>
98 // variables for performance
99 Standard_Real t_mkcurve;
100 extern void ChFi3d_InitChron(OSD_Chronometer& ch);
101 extern void ChFi3d_ResultChron(OSD_Chronometer & ch, Standard_Real& time);
103 static Standard_Boolean Affich = Standard_False;
104 static char name[100];
108 //=======================================================================
109 //function : IsOnRestriction
111 //=======================================================================
113 static Standard_Boolean IsOnRestriction(const TopoDS_Vertex& V,
114 const TopoDS_Edge& CurE,
115 const TopoDS_Face& F,
118 // find if Vertex V of CurE is on a restriction of F.
119 // if yes, store this restriction in E.
122 // Method somewhat brutal : possible to really optimize by a
123 // direct call the SD of intersections -> See LBR
126 Handle(Geom2d_Curve) CurC = BRep_Tool::CurveOnSurface(CurE,F,f,l);
127 Standard_Real U = BRep_Tool::Parameter(V,CurE,F);
128 gp_Pnt2d P = CurC->Value(U);
130 Geom2dAPI_ProjectPointOnCurve Proj;
132 // The tolerance is exaggerated : it is better to construct too many
133 // tubes than to miss intersections.
134 // Standard_Real Tol = 100 * BRep_Tool::Tolerance(V);
135 Standard_Real Tol = BRep_Tool::Tolerance(V);
136 TopExp_Explorer exp(F,TopAbs_EDGE);
137 for ( ; exp.More(); exp.Next()) {
138 E = TopoDS::Edge(exp.Current());
139 Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(E,F,f,l);
141 if ( Proj.NbPoints() > 0) {
142 if (Proj.LowerDistance() < Tol) {
143 return Standard_True;
147 return Standard_False;
150 //=======================================================================
153 //=======================================================================
155 static void Add(const TopoDS_Edge& E,
156 TopTools_IndexedMapOfShape& Map,
157 const TopoDS_Shape& S,
158 const BRepOffset_Offset& OF,
159 const BRepOffset_Analyse& Analyse,
160 const Standard_Boolean WarningSurBordLibre)
161 // If WarningSurBordLibre = TRUE, no propagation if the edge is open.
163 TopAbs_ShapeEnum Type = S.ShapeType();
165 if ( Type == TopAbs_FACE) {
166 TopExp_Explorer exp(S,TopAbs_EDGE);
167 for ( ; exp.More(); exp.Next()) {
168 const TopoDS_Edge& OriE = TopoDS::Edge(exp.Current());
169 TopoDS_Shape aLocalShape = OF.Generated(OriE);
170 const TopoDS_Edge& IE = TopoDS::Edge(aLocalShape);
171 // const TopoDS_Edge& IE = TopoDS::Edge(OF.Generated(OriE));
172 if ( E.IsEqual(IE)) {
173 if (WarningSurBordLibre) {
174 // It is checked that the border is not free.
175 const TopTools_ListOfShape& L = Analyse.Ancestors(OriE);
176 if (L.Extent() == 1) break; // Nothing is done.
178 Map.Add(exp.Current());
183 else if ( Type == TopAbs_EDGE) {
184 TopExp_Explorer exp(S,TopAbs_VERTEX);
185 for ( ; exp.More(); exp.Next()) {
186 TopoDS_Shape aLocalShape = OF.Generated(exp.Current());
187 const TopoDS_Edge& IE = TopoDS::Edge(aLocalShape);
188 // const TopoDS_Edge& IE = TopoDS::Edge(OF.Generated(exp.Current()));
189 if ( E.IsEqual(IE)) {
190 const TopTools_ListOfShape& L = Analyse.Ancestors(exp.Current());
191 TopTools_ListIteratorOfListOfShape it(L);
192 for ( ; it.More(); it.Next()) {
202 //=======================================================================
203 //function : IsInFace
205 //=======================================================================
207 static Standard_Boolean IsInFace(const TopoDS_Edge& E,
208 const TopoDS_Face& F)
210 TopExp_Explorer exp(F,TopAbs_EDGE);
211 for ( ;exp.More(); exp.Next())
212 if ( E.IsSame(exp.Current())) return Standard_True;
213 return Standard_False;
217 //=======================================================================
218 //function : KPartCurve3d
220 //=======================================================================
222 static void KPartCurve3d(TopoDS_Edge Edge,
223 Handle(Geom2d_Curve) Curve,
224 Handle(Geom_Surface) Surf)
226 // try to find the particular case
227 // if not found call BRepLib::BuildCurve3d
230 Standard_Real Tol = Precision::Confusion();
232 // Seach only isos on analytical surfaces.
233 Geom2dAdaptor_Curve C(Curve);
234 GeomAdaptor_Surface S(Surf);
235 GeomAbs_CurveType CTy = C.GetType();
236 GeomAbs_SurfaceType STy = S.GetType();
237 BRep_Builder TheBuilder;
239 if ( STy != GeomAbs_Plane) { // if plane buildcurve3d manage KPart
240 if ( CTy == GeomAbs_Line) {
241 gp_Dir2d D = C.Line().Direction();
242 if ( D.IsParallel(gp::DX2d(),Precision::Angular())) { // Iso V.
243 if ( STy == GeomAbs_Sphere) {
244 gp_Pnt2d P = C.Line().Location();
245 if ( Abs( Abs(P.Y()) -M_PI/2. ) < Precision::PConfusion()) {
246 TheBuilder.Degenerated(Edge, Standard_True);
249 gp_Sphere Sph = S.Sphere();
250 gp_Ax3 Axis = Sph.Position();
251 gp_Circ Ci = ElSLib::SphereVIso(Axis,
254 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
255 gp_Ax1 AxeRev(Axis.Location(), DRev);
256 Ci.Rotate(AxeRev, P.X());
257 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
258 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
260 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
263 else if ( STy == GeomAbs_Cylinder) {
264 gp_Cylinder Cyl = S.Cylinder();
265 gp_Pnt2d P = C.Line().Location();
266 gp_Ax3 Axis = Cyl.Position();
267 gp_Circ Ci = ElSLib::CylinderVIso(Axis,
270 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
271 gp_Ax1 AxeRev(Axis.Location(), DRev);
272 Ci.Rotate(AxeRev, P.X());
273 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
274 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
276 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
278 else if ( STy == GeomAbs_Cone) {
279 gp_Cone Cone = S.Cone();
280 gp_Pnt2d P = C.Line().Location();
281 gp_Ax3 Axis = Cone.Position();
282 gp_Circ Ci = ElSLib::ConeVIso(Axis,
286 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
287 gp_Ax1 AxeRev(Axis.Location(), DRev);
288 Ci.Rotate(AxeRev, P.X());
289 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
290 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
292 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
294 else if ( STy == GeomAbs_Torus) {
295 gp_Torus Tore = S.Torus();
296 gp_Pnt2d P = C.Line().Location();
297 gp_Ax3 Axis = Tore.Position();
298 gp_Circ Ci = ElSLib::TorusVIso(Axis,
302 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
303 gp_Ax1 AxeRev(Axis.Location(), DRev);
304 Ci.Rotate(AxeRev, P.X());
305 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
306 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
308 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
311 else if ( D.IsParallel(gp::DY2d(),Precision::Angular())) { // Iso U.
312 if ( STy == GeomAbs_Sphere) {
313 gp_Sphere Sph = S.Sphere();
314 gp_Pnt2d P = C.Line().Location();
315 gp_Ax3 Axis = Sph.Position();
317 gp_Circ Ci = ElSLib::SphereUIso(Axis, Sph.Radius(),0.);
319 // set to sameparameter (rotation of the circle - offset from Y)
320 gp_Dir DRev = Axis.XDirection().Crossed(Axis. Direction());
321 gp_Ax1 AxeRev(Axis.Location(),DRev);
322 Ci.Rotate(AxeRev, P.Y());
324 // transformation by iso U ( = P.X())
325 DRev = Axis.XDirection().Crossed(Axis.YDirection());
326 AxeRev = gp_Ax1(Axis.Location(), DRev);
327 Ci.Rotate(AxeRev, P.X());
328 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
330 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
332 TheBuilder.UpdateEdge(Edge, Circle, Loc, Tol);
334 else if ( STy == GeomAbs_Cylinder) {
335 gp_Cylinder Cyl = S.Cylinder();
336 gp_Pnt2d P = C.Line().Location();
337 gp_Lin L = ElSLib::CylinderUIso(Cyl.Position(),
340 gp_Vec Tr(L.Direction());
343 Handle(Geom_Line) Line = new Geom_Line(L);
344 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
346 TheBuilder.UpdateEdge(Edge, Line, Loc, Tol);
348 else if ( STy == GeomAbs_Cone) {
349 gp_Cone Cone = S.Cone();
350 gp_Pnt2d P = C.Line().Location();
351 gp_Lin L = ElSLib::ConeUIso(Cone.Position(),
355 gp_Vec Tr(L.Direction());
357 L.Translate(Tr); Handle(Geom_Line) Line = new Geom_Line(L);
358 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
360 TheBuilder.UpdateEdge(Edge, Line, Loc, Tol);
362 else if ( STy == GeomAbs_Torus) {
368 Handle(Geom_Curve) C3d = GeomAPI::To3d(Curve,S.Plane());
369 TheBuilder.UpdateEdge(Edge, C3d, Loc, Tol);
374 //=======================================================================
375 //function : MakeCurve
377 //=======================================================================
379 class MakeCurve_Function : public AppCont_Function
381 BiTgte_CurveOnEdge myCurve;
385 MakeCurve_Function(const BiTgte_CurveOnEdge& C)
392 Standard_Real FirstParameter() const
394 return myCurve.FirstParameter();
397 Standard_Real LastParameter() const
399 return myCurve.LastParameter();
402 Standard_Boolean Value(const Standard_Real theT,
403 NCollection_Array1<gp_Pnt2d>& /*thePnt2d*/,
404 NCollection_Array1<gp_Pnt>& thePnt) const
406 thePnt(1) = myCurve.Value(theT);
407 return Standard_True;
410 Standard_Boolean D1(const Standard_Real /*theT*/,
411 NCollection_Array1<gp_Vec2d>& /*theVec2d*/,
412 NCollection_Array1<gp_Vec>& /*theVec*/) const
414 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&,
486 const TopTools_MapOfShape&,
488 TopTools_MapOfShape&)
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());
507 //=======================================================================
508 //function : FindVertex
510 //=======================================================================
512 static TopoDS_Vertex FindVertex(const gp_Pnt& P,
513 const TopTools_MapOfShape& Map,
514 const Standard_Real Tol)
517 // Find in <Map> a vertex which represent the point <P>.
518 Standard_Real Tol2,Dist;
519 TopoDS_Vertex V,VV[2];
520 Standard_Real TolCarre = Tol*Tol;
521 TopTools_MapIteratorOfMapOfShape it(Map);
522 for ( ; it.More(); it.Next()) {
523 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
525 TopExp::Vertices(E,VV[0],VV[1]);
527 for (Standard_Integer i = 0; i < 2 ; i++) {
528 // if OK la Tolerance du Vertex
529 Tol2 = BRep_Tool::Tolerance(VV[i]);
531 gp_Pnt P1 = BRep_Tool::Pnt(VV[i]);
532 Dist = P.SquareDistance(P1);
533 if ( Dist <= Tol2) return VV[i];
534 // otherwise with the required tolerance.
535 if (TolCarre > Tol2) {
536 if ( Dist <= TolCarre) {
537 // so it is necessary to update the tolerance of Vertex.
538 B.UpdateVertex(VV[i],Tol);
550 //=======================================================================
551 //function : MakeDegeneratedEdge
553 //=======================================================================
555 static TopoDS_Edge MakeDegeneratedEdge(const Handle(Geom_Curve)& CC,
556 const TopoDS_Vertex& VfOnE)
559 Standard_Real Tol = Precision::Confusion();
560 // kill trimmed curves
561 Handle(Geom_Curve) C = CC;
562 Handle(Geom_TrimmedCurve) CT = Handle(Geom_TrimmedCurve)::DownCast(C);
563 while (!CT.IsNull()) {
564 C = CT->BasisCurve();
565 CT = Handle(Geom_TrimmedCurve)::DownCast(C);
569 if ( VfOnE.IsNull()) {
570 gp_Pnt P = C->Value(C->FirstParameter());
571 B.MakeVertex(V1,P,Tol);
577 V1.Orientation(TopAbs_FORWARD);
578 V2.Orientation(TopAbs_REVERSED);
582 B.Add(E,V1); B.Add(E,V2);
583 // B.UpdateVertex(V1,C->FirstParameter(),E,Tol);
584 // B.UpdateVertex(V2,C->LastParameter(),E,Tol);
585 B.Range(E,CC->FirstParameter(),CC->LastParameter());
590 //=======================================================================
591 //function : Orientation
593 //=======================================================================
595 static TopAbs_Orientation Orientation(const TopoDS_Edge& E,
596 const TopoDS_Face& F,
597 const TopTools_ListOfShape& L)
599 TopAbs_Orientation Orien = TopAbs_FORWARD;
600 TopTools_ListIteratorOfListOfShape itld;
601 for ( itld.Initialize(L); itld.More(); itld.Next()) {
602 if ( itld.Value().IsSame(E)) {
603 Orien = itld.Value().Orientation();
607 if ( F.Orientation() == TopAbs_REVERSED)
608 Orien = TopAbs::Reverse(Orien);
613 //=======================================================================
614 //function : FindCreatedEdge
616 //=======================================================================
618 static TopoDS_Edge FindCreatedEdge
619 (const TopoDS_Vertex& V1,
620 const TopoDS_Edge& E,
621 const BRepOffset_DataMapOfShapeOffset& MapSF,
622 TopTools_MapOfShape& MapOnV,
623 const BRepOffset_Analyse& CenterAnalyse,
624 Standard_Real Radius,
628 if (!CenterAnalyse.HasAncestor(V1)) return E1; // return a Null Shape.
630 TopTools_ListOfShape TangE;
631 CenterAnalyse.TangentEdges(E,V1,TangE);
633 TopTools_ListIteratorOfListOfShape itl(TangE);
634 Standard_Boolean Find = Standard_False;
635 for ( ; itl.More() && !Find; itl.Next()) {
636 const TopoDS_Edge& ET = TopoDS::Edge(itl.Value());
637 if ( MapSF.IsBound(ET)) {
638 TopoDS_Shape aLocalShape = MapSF(ET).Generated(V1);
639 E1 = TopoDS::Edge(aLocalShape);
640 // E1 = TopoDS::Edge(MapSF(ET).Generated(V1));
642 Find = Standard_True;
645 // Find the sharing of vertices in case of tangent consecutive 3 edges
646 // the second of which is the edge that degenerates the tube.
647 TopLoc_Location CLoc;
649 Handle(Geom_Curve) CET =
650 BRep_Tool::Curve(ET,CLoc,ff,ll);
651 if ( CET->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
652 CET = Handle(Geom_TrimmedCurve)::DownCast(CET)->BasisCurve();
654 Handle(Geom_Circle) Circ = Handle(Geom_Circle)::DownCast(CET);
655 if ( Circ.IsNull()) continue;
656 if ( Abs(Circ->Radius() - Abs(Radius)) > Tol) continue;
659 TopExp::Vertices(ET,U1,U2);
660 if ( U1.IsSame(V1)) U1 = U2;
661 TopTools_ListOfShape Tang2;
662 CenterAnalyse.TangentEdges(ET,U1,Tang2);
663 TopTools_ListIteratorOfListOfShape it2(Tang2);
664 for ( ; it2.More() ; it2.Next()) {
665 const TopoDS_Edge& ET2 = TopoDS::Edge(it2.Value());
666 if ( MapSF.IsBound(ET2)) {
667 TopoDS_Shape aLocalShape = MapSF(ET2).Generated(U1);
668 MapOnV.Add(TopoDS::Edge(aLocalShape));
669 // MapOnV.Add(TopoDS::Edge(MapSF(ET2).Generated(U1)));
676 // CenterAnalyse.Edges(V1f, OT, TangE);
677 if (CenterAnalyse.HasAncestor(V1)) {
678 TangE = CenterAnalyse.Ancestors(V1);
679 itl.Initialize(TangE);
680 for ( ; itl.More() && !Find; itl.Next()) {
681 if ( MapSF.IsBound(itl.Value())) {
682 MapOnV.Add(MapSF(itl.Value()).Generated(V1));
691 //=======================================================================
693 //purpose : Sets in increasing order the sequence of vertices.
694 //=======================================================================
696 static void Bubble(const TopoDS_Edge& E,
697 TopTools_SequenceOfShape& Seq)
699 Standard_Boolean Invert = Standard_True;
700 Standard_Integer NbPoints = Seq.Length();
705 Invert = Standard_False;
706 for ( Standard_Integer i = 1; i < NbPoints; i++) {
707 TopoDS_Shape aLocalShape = Seq.Value(i) .Oriented(TopAbs_INTERNAL);
708 V1 = TopoDS::Vertex(aLocalShape);
709 aLocalShape = Seq.Value(i+1).Oriented(TopAbs_INTERNAL);
710 V2 = TopoDS::Vertex(aLocalShape);
711 // V1 = TopoDS::Vertex(Seq.Value(i) .Oriented(TopAbs_INTERNAL));
712 // V2 = TopoDS::Vertex(Seq.Value(i+1).Oriented(TopAbs_INTERNAL));
714 U1 = BRep_Tool::Parameter(V1,E);
715 U2 = BRep_Tool::Parameter(V2,E);
718 Invert = Standard_True;
724 //=======================================================================
727 //=======================================================================
729 static void CutEdge (const TopoDS_Edge& E,
730 const TopTools_ListOfShape& VOnE,
731 TopTools_ListOfShape& NE )
733 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
734 TopoDS_Edge WE = TopoDS::Edge(aLocalShape);
735 // TopoDS_Edge WE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
739 TopTools_SequenceOfShape SV;
740 TopTools_ListIteratorOfListOfShape it(VOnE);
743 for ( ; it.More(); it.Next()) {
744 SV.Append(it.Value());
746 //--------------------------------
747 // Parse vertices on the edge.
748 //--------------------------------
751 Standard_Integer NbVer = SV.Length();
752 //----------------------------------------------------------------
753 // Construction of new edges.
754 // The vertices at the extremities of edges are not
755 // necessarily in the list of vertices
756 //----------------------------------------------------------------
763 BRep_Tool::Range(WE,f,l);
764 TopExp::Vertices(WE,VF,VL);
767 if (SV(1).IsEqual(VF) && SV(2).IsEqual(VL)) {
772 //----------------------------------------------------
773 // Processing of closed edges
774 // If a vertex of intersection is on the common vertex,
775 // it should appear at the beginning and the end of SV.
776 //----------------------------------------------------
779 if (!VF.IsNull() && !VF.IsSame(SV.First())) SV.Prepend(VF);
780 if (!VL.IsNull() && !VL.IsSame(SV.Last ())) SV.Append (VL);
782 V1 = TopoDS::Vertex(SV.First());
785 while (!SV.IsEmpty()) {
787 V2 = TopoDS::Vertex(SV.First());
790 if ( V1.IsSame(V2)) {
791 cout << "Vertex Confondus dans CutEdges" << endl;
794 //-------------------------------------------
795 // Copy the edge and restriction by V1 V2.
796 //-------------------------------------------
797 TopoDS_Shape aLocalShape =WE.EmptyCopied();
798 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
799 // TopoDS_Edge NewEdge = TopoDS::Edge(WE.EmptyCopied());
800 B.Add (NewEdge,V1.Oriented(TopAbs_FORWARD));
801 B.Add (NewEdge,V2.Oriented(TopAbs_REVERSED));
805 aLocalShape = V1.Oriented(TopAbs_INTERNAL);
806 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),WE);
807 // U1 = BRep_Tool::Parameter
808 // (TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),WE);
813 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
814 U2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),WE);
815 // U2 = BRep_Tool::Parameter
816 // (TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),WE);
818 B.Range (NewEdge,U1,U2);
819 NE.Append(NewEdge.Oriented(E.Orientation()));
824 //======================== END OF STATIC FUNCTIONS ============
829 //=======================================================================
830 //function : BiTgte_Blend
832 //=======================================================================
834 BiTgte_Blend::BiTgte_Blend()
836 myAsDes = new BRepAlgo_AsDes();
841 //=======================================================================
842 //function : BiTgte_Blend
844 //=======================================================================
846 BiTgte_Blend::BiTgte_Blend(const TopoDS_Shape& S,
847 const Standard_Real Radius,
848 const Standard_Real Tol,
849 const Standard_Boolean NUBS)
851 myAsDes = new BRepAlgo_AsDes();
852 Init(S,Radius,Tol,NUBS);
856 //=======================================================================
859 //=======================================================================
861 void BiTgte_Blend::Init(const TopoDS_Shape& S,
862 const Standard_Real Radius,
863 const Standard_Real Tol,
864 const Standard_Boolean NUBS)
872 // TopExp::MapShapesAndAncestors(S,TopAbs_EDGE,TopAbs_FACE,myAncestors);
876 //=======================================================================
879 //=======================================================================
881 void BiTgte_Blend::Clear()
883 myInitOffsetFace.Clear();
885 myImageOffset .Clear();
886 myStopFaces .Clear();
890 myDone = Standard_False;
894 //=======================================================================
895 //function : SetStoppingFace
897 //=======================================================================
899 void BiTgte_Blend::SetStoppingFace(const TopoDS_Face& Face)
901 myStopFaces.Add(Face);
903 // MAJ SD. -> To end loop, set faces of edges
905 // myInitOffsetFace.SetRoot(Face);
906 // myInitOffsetFace.Bind (Face,Face);
907 // myImageOffset.SetRoot (Face);
911 //=======================================================================
912 //function : SetFaces
914 //=======================================================================
916 void BiTgte_Blend::SetFaces(const TopoDS_Face& F1,const TopoDS_Face& F2)
923 //=======================================================================
926 //=======================================================================
928 void BiTgte_Blend::SetEdge(const TopoDS_Edge& Edge)
934 //=======================================================================
937 //=======================================================================
939 void BiTgte_Blend::Perform(const Standard_Boolean BuildShape)
941 myBuildShape = BuildShape;
943 // Try cutting to avoid tubes on free borders
944 // that are not actually free.
945 Handle(BRepBuilderAPI_Sewing) Sew = new BRepBuilderAPI_Sewing(myTol);
946 BRepLib::BuildCurves3d(myShape);
947 TopExp_Explorer expf(myShape,TopAbs_FACE);
948 for ( ;expf.More(); expf.Next()) Sew->Add(expf.Current());
950 TopoDS_Shape SewedShape = Sew->SewedShape();
951 if ( SewedShape.IsNull()) Standard_Failure::Raise("Sewing aux fraises");
953 // Check if the sewing modified the orientation.
954 expf.Init(myShape,TopAbs_FACE);
955 TopoDS_Face FaceRef = TopoDS::Face(expf.Current());
956 TopAbs_Orientation OriRef = FaceRef.Orientation();
957 if (Sew->IsModified(FaceRef)) FaceRef = TopoDS::Face(Sew->Modified(FaceRef));
958 expf.Init(SewedShape, TopAbs_FACE);
959 for (; expf.More(); expf.Next()) {
960 const TopoDS_Face& FF = TopoDS::Face(expf.Current());
961 if (FaceRef.IsSame(FF) && (FF.Orientation() != OriRef)) {
962 SewedShape.Reverse();
967 // Make SameParameter if Sew does not do it (Detect that edges
968 // are not sameparameter but it does nothing.)
969 expf.Init(SewedShape, TopAbs_EDGE);
970 for (; expf.More(); expf.Next()) {
971 const TopoDS_Edge& sec = TopoDS::Edge(expf.Current());
972 BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
975 TopExp::MapShapesAndAncestors
976 (SewedShape,TopAbs_EDGE,TopAbs_FACE,myAncestors);
978 // Extend myFaces with the faces of the sewed shape.
979 expf.Init(myShape,TopAbs_FACE);
980 for ( ; expf.More(); expf.Next()) {
981 const TopoDS_Shape& F = expf.Current();
982 if ( myFaces.Contains(F) && Sew->IsModified(F)) {
984 TopoDS_Shape LastFace = myFaces(myFaces.Extent());
985 myFaces.RemoveLast();
986 if (myFaces.FindIndex(F) != 0)
987 myFaces.Substitute(myFaces.FindIndex(F), LastFace);
989 myFaces.Add(Sew->Modified(F));
993 myShape = SewedShape;
994 // end Sewing for false free borders.
997 OSD_Chronometer cl_total, ch;
998 Standard_Real t_total, t_center, t_surface, t_shape;
1000 t_total=0; t_center=0; t_surface=0; t_mkcurve=0; t_shape=0;
1001 ChFi3d_InitChron(cl_total);
1004 // ----------------------------------------------------------------
1005 // place faces with the proper orientation in the initial shape
1006 // ----------------------------------------------------------------
1007 TopExp_Explorer exp(myShape,TopAbs_FACE);
1008 for ( ; exp.More(); exp.Next()) {
1009 const TopoDS_Shape& F = exp.Current();
1010 if ( myFaces.Contains(F)) {
1011 //myFaces.Remove(F);
1012 TopoDS_Shape LastFace = myFaces(myFaces.Extent());
1013 myFaces.RemoveLast();
1014 if (myFaces.FindIndex(F) != 0)
1015 myFaces.Substitute(myFaces.FindIndex(F), LastFace);
1016 ////////////////////
1019 else if ( myStopFaces.Contains(F)) {
1020 myStopFaces.Remove(F);
1025 // ----------------------------------------------
1026 // Calculate lines of centers and of surfaces
1027 // ----------------------------------------------
1029 ChFi3d_InitChron(ch);
1035 ChFi3d_ResultChron(ch, t_center);
1038 // -----------------------------
1039 // Calculate connection Surfaces
1040 // -----------------------------
1042 ChFi3d_InitChron(ch);
1048 ChFi3d_ResultChron(ch, t_surface);
1051 // ----------------------------------
1052 // Calculate the generated shape if required
1053 // ----------------------------------
1055 ChFi3d_InitChron(ch);
1058 if ( myBuildShape) ComputeShape();
1061 ChFi3d_ResultChron(ch, t_shape);
1064 // Finally construct curves 3d from edges to be transfered
1065 // since the partition is provided ( A Priori);
1066 BRepLib::BuildCurves3d(myResult, Precision::Confusion());
1069 ChFi3d_ResultChron(cl_total, t_total);
1071 cout<<"Blend_PERFORM: temps total "<<t_total<<" s dont :"<<endl;
1072 cout<<"- ComputeCenters "<<t_center<<" s"<<endl;
1073 cout<<"- ComputeSurfaces "<<t_surface<<" s"<<endl;
1074 cout<<"----> MakeCurve "<<t_mkcurve<<" s"<<endl;
1075 if ( myBuildShape) cout<<"- ComputeShape "<<t_shape<<" s"<<endl;
1078 myDone = Standard_True;
1082 //=======================================================================
1085 //=======================================================================
1087 Standard_Boolean BiTgte_Blend::IsDone() const
1092 //=======================================================================
1095 //=======================================================================
1097 const TopoDS_Shape& BiTgte_Blend::Shape() const
1103 //=======================================================================
1104 //function : NbSurfaces
1106 //=======================================================================
1108 Standard_Integer BiTgte_Blend::NbSurfaces() const
1110 return myCenters.Extent();
1114 //=======================================================================
1115 //function : Surface
1117 //=======================================================================
1119 Handle(Geom_Surface) BiTgte_Blend::Surface(const Standard_Integer Index) const
1121 return Surface(myCenters(Index));
1124 //=======================================================================
1125 //function : TopoDS_Face&
1127 //=======================================================================
1129 const TopoDS_Face& BiTgte_Blend::Face(const Standard_Integer Index) const
1131 return Face(myCenters(Index));
1136 //=======================================================================
1137 //function : CenterLines
1139 //=======================================================================
1141 void BiTgte_Blend::CenterLines(TopTools_ListOfShape& LC) const
1144 Standard_Integer Nb = NbSurfaces();
1145 for ( Standard_Integer i = 1; i <= Nb; i++)
1146 LC.Append(myCenters(i));
1150 //=======================================================================
1151 //function : Surface
1153 //=======================================================================
1155 Handle(Geom_Surface) BiTgte_Blend::Surface(const TopoDS_Shape& CenterLine)
1158 const TopoDS_Face& F = myMapSF(CenterLine).Face();
1159 return BRep_Tool::Surface(F);
1162 //=======================================================================
1163 //function : TopoDS_Face&
1165 //=======================================================================
1167 const TopoDS_Face& BiTgte_Blend::Face(const TopoDS_Shape& CenterLine) const
1169 if ( !myMapSF.IsBound(CenterLine)) {
1170 Standard_DomainError::Raise("BiTgte_Blend::Face");
1173 return myMapSF(CenterLine).Face();
1176 //=======================================================================
1177 //function : ContactType
1179 //=======================================================================
1181 BiTgte_ContactType BiTgte_Blend::ContactType(const Standard_Integer Index)
1184 const TopoDS_Shape& S1 = SupportShape1(Index);
1185 const TopoDS_Shape& S2 = SupportShape2(Index);
1187 TopAbs_ShapeEnum Type1 = S1.ShapeType();
1188 TopAbs_ShapeEnum Type2 = S2.ShapeType();
1190 if (Type2 < Type1) {
1191 TopAbs_ShapeEnum Dummy = Type1;
1195 BiTgte_ContactType Type = BiTgte_VertexVertex;
1201 case TopAbs_VERTEX: Type = BiTgte_VertexVertex; break;
1202 case TopAbs_EDGE: Type = BiTgte_EdgeVertex; break;
1203 case TopAbs_FACE: Type = BiTgte_FaceVertex; break;
1210 case TopAbs_EDGE: Type = BiTgte_EdgeEdge; break;
1211 case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
1218 case TopAbs_FACE: Type = BiTgte_FaceEdge; break;
1231 //=======================================================================
1232 //function : SupportShape1
1234 //=======================================================================
1236 const TopoDS_Shape& BiTgte_Blend::SupportShape1(const Standard_Integer Index)
1239 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1241 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1243 // --------------------------------------------------------------
1244 // F1 and F2 = 2 parallel faces intersecting at CurE.
1245 // --------------------------------------------------------------
1246 const TopoDS_Face& F1 = TopoDS::Face(L.First());
1247 const TopoDS_Shape& Or1 = myInitOffsetFace.ImageFrom(F1);
1252 //=======================================================================
1253 //function : SupportShape2
1255 //=======================================================================
1257 const TopoDS_Shape& BiTgte_Blend::SupportShape2(const Standard_Integer Index)
1260 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1262 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1264 // --------------------------------------------------------------
1265 // F1 and F2 = 2 parallel faces intersecting at CurE.
1266 // --------------------------------------------------------------
1267 const TopoDS_Face& F2 = TopoDS::Face(L.Last());
1268 const TopoDS_Shape& Or2 = myInitOffsetFace.ImageFrom(F2);
1273 //=======================================================================
1274 //function : CurveOnShape1
1276 //=======================================================================
1278 Handle(Geom_Curve) BiTgte_Blend::CurveOnShape1
1279 (const Standard_Integer Index) const
1281 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1282 const TopoDS_Shape& F = myMapSF(CurE).Face();
1284 // somewhat brutal method based ONLY on the construction of the fillet:
1285 // the first edge of the tube is exactly the edge on Shape1.
1287 TopExp_Explorer exp(F,TopAbs_EDGE);
1288 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1289 Handle(Geom_Curve) C;
1290 if ( !BRep_Tool::Degenerated(E)) {
1292 C = BRep_Tool::Curve(E,f,l);
1293 C = new Geom_TrimmedCurve(C,f,l);
1299 //=======================================================================
1300 //function : CurveOnShape2
1302 //=======================================================================
1304 Handle(Geom_Curve) BiTgte_Blend::CurveOnShape2
1305 (const Standard_Integer Index) const
1307 const TopoDS_Edge& CurE = TopoDS::Edge(myCenters(Index));
1308 const TopoDS_Shape& F = myMapSF(CurE).Face();
1310 // somewhat brutal method based ONLY on the construction of the fillet:
1311 // the first edge of the tube is exactly the edge on Shape2.
1313 TopExp_Explorer exp(F,TopAbs_EDGE);
1315 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1316 Handle(Geom_Curve) C;
1317 if ( !BRep_Tool::Degenerated(E)) {
1319 C = BRep_Tool::Curve(E,f,l);
1320 C = new Geom_TrimmedCurve(C,f,l);
1326 //=======================================================================
1327 //function : PCurveOnFace1
1329 //=======================================================================
1331 Handle(Geom2d_Curve) BiTgte_Blend::PCurveOnFace1
1332 (const Standard_Integer /*Index*/) const
1334 Handle(Geom2d_Curve) C;
1339 //=======================================================================
1340 //function : PCurve1OnFillet
1342 //=======================================================================
1344 Handle(Geom2d_Curve) BiTgte_Blend::PCurve1OnFillet
1345 (const Standard_Integer /*Index*/) const
1347 Handle(Geom2d_Curve) C;
1352 //=======================================================================
1353 //function : PCurveOnFace2
1355 //=======================================================================
1357 Handle(Geom2d_Curve) BiTgte_Blend::PCurveOnFace2
1358 (const Standard_Integer /*Index*/) const
1360 Handle(Geom2d_Curve) C;
1365 //=======================================================================
1366 //function : Curve2OnFillet
1368 //=======================================================================
1370 Handle(Geom2d_Curve) BiTgte_Blend::PCurve2OnFillet
1371 (const Standard_Integer /*Index*/) const
1373 Handle(Geom2d_Curve) C;
1379 //=======================================================================
1380 //function : NbBranches
1382 //=======================================================================
1384 Standard_Integer BiTgte_Blend::NbBranches()
1386 if (myNbBranches != -1) return myNbBranches;
1388 // else, compute the Branches.
1389 BRepTools_Quilt Glue;
1391 Standard_Integer NbFaces = myCenters.Extent();
1394 if (NbFaces == 0) return 0;
1398 for ( i = 1; i <= NbFaces; i++) {
1399 const TopoDS_Shape& CenterLine = myCenters(i);
1400 Glue.Add(myMapSF(CenterLine).Face());
1403 const TopoDS_Shape Shells = Glue.Shells();
1406 // Reorder Map myCenters.
1407 // The method is brutal and unpolished,
1408 // it is possible to refine it.
1410 TopTools_IndexedMapOfShape tmpMap;
1412 TopExp_Explorer exp(Shells,TopAbs_SHELL);
1413 for (; exp.More(); exp.Next()) {
1417 myIndices = new TColStd_HArray1OfInteger(1,myNbBranches+1);
1419 myIndices->SetValue(1,0);
1420 Standard_Integer Count = 0;
1421 Standard_Integer Index = 2;
1424 exp.Init(Shells,TopAbs_SHELL);
1425 for (; exp.More(); exp.Next()) {
1426 // CurS = the current Shell.
1427 const TopoDS_Shape CurS = exp.Current();
1429 TopExp_Explorer exp2(CurS, TopAbs_FACE);
1430 for (; exp2.More(); exp2.Next()) {
1431 // CurF = the current face of the current Shell.
1432 const TopoDS_Shape CurF = exp2.Current();
1434 for ( i = 1; i <= NbFaces; i++) {
1435 const TopoDS_Shape& Center = myCenters(i);
1436 const TopoDS_Shape& Rakk = myMapSF(Center).Face();
1437 // Rakk = the ith generated connection face
1438 if (CurF.IsEqual(Rakk)) {
1445 myIndices->SetValue(Index, Count);
1450 return myNbBranches;
1454 //=======================================================================
1455 //function : IndicesOfBranche
1457 //=======================================================================
1459 void BiTgte_Blend::IndicesOfBranche
1460 (const Standard_Integer Index,
1461 Standard_Integer& From,
1462 Standard_Integer& To ) const
1464 // Attention to the ranking in myIndices:
1465 // If the branches are 1-4 5-9 10-12, it is ranked in myIndices:
1467 From = myIndices->Value(Index) + 1;
1468 To = myIndices->Value(Index + 1);
1472 //=======================================================================
1473 //function : ComputeCenters
1475 //=======================================================================
1477 void BiTgte_Blend::ComputeCenters()
1482 Standard_Real TolAngle = 2*ASin(myTol/Abs(myRadius*0.5));
1483 myAnalyse.Perform(myShape,TolAngle);
1485 // ------------------------------------------
1486 // calculate faces touched by caps
1487 // ------------------------------------------
1488 TopTools_MapOfShape TouchedByCork;
1489 Touched(myAnalyse, myStopFaces, myShape, TouchedByCork);
1491 // -----------------------
1492 // init of the intersector
1493 // -----------------------
1494 TopAbs_State Side = TopAbs_IN;
1495 if (myRadius < 0.) Side = TopAbs_OUT;
1496 BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
1498 BiTgte_DataMapOfShapeBox MapSBox;
1499 TopTools_MapOfShape Done;
1500 //TopTools_MapIteratorOfMapOfShape it;
1503 TopoDS_Compound Co; // to only know on which edges the tubes are made
1506 // ----------------------------------------
1507 // Calculate Sections Face/Face + Propagation
1508 // ----------------------------------------
1509 Standard_Boolean JenRajoute = Standard_True;
1512 while ( JenRajoute) {
1513 JenRajoute = Standard_False;
1515 Standard_Boolean Fini = Standard_False;
1517 TopTools_DataMapOfShapeShape EdgeTgt;
1521 // -------------------------------------------------
1522 // locate in myFaces the Faces connected to myEdges.
1523 // -------------------------------------------------
1524 Fini = Standard_True;
1525 //for (it.Initialize(myEdges); it.More(); it.Next()) {
1526 for (i = 1; i <= myEdges.Extent(); i++) {
1527 const TopoDS_Edge& E = TopoDS::Edge(myEdges(i));
1528 if (BRep_Tool::Degenerated(E)) continue;
1530 const TopTools_ListOfShape& L = myAncestors.FindFromKey(E);
1531 if ( L.Extent() == 1) {
1532 // So this is a free border onwhich the ball should roll.
1535 // set in myStopFaces to not propagate the tube on free border.
1539 TopTools_ListIteratorOfListOfShape itl;
1540 for (itl.Initialize(L); itl.More(); itl.Next()) {
1541 const TopoDS_Shape& Sh = itl.Value();
1542 if ( !myStopFaces.Contains(Sh)) myFaces.Add(itl.Value());
1548 // --------------------------------------------
1549 // Construction of Offsets of all faces.
1550 // --------------------------------------------
1551 //for (it.Initialize(myFaces); it.More(); it.Next()) {
1552 for (i = 1; i <= myFaces.Extent(); i++) {
1553 const TopoDS_Shape& AS = myFaces(i);
1554 if ( myMapSF.IsBound(AS)) continue;
1556 BRepOffset_Offset OF1;
1559 if (AS.ShapeType() == TopAbs_FACE) {
1560 const TopoDS_Face& F = TopoDS::Face(myFaces(i));
1561 if ( TouchedByCork.Contains(F)) {
1562 BRepOffset_Tool::EnLargeFace(F,BigF,Standard_True);
1563 OF1.Init(BigF,myRadius,EdgeTgt);
1566 OF1.Init(F,myRadius,EdgeTgt);
1569 else { // So this is a Free Border edge on which the ball rolls.
1570 OF1.Init(TopoDS::Edge(AS),myRadius);
1573 // ------------------------------------
1574 // Increment the map of created tangents
1575 // ------------------------------------
1576 TopTools_ListOfShape Let;
1577 if ( AS.ShapeType() == TopAbs_FACE) {
1578 myAnalyse.Edges(TopoDS::Face(AS),BRepOffset_Tangent,Let);
1580 TopTools_ListIteratorOfListOfShape itlet(Let);
1582 for ( ; itlet.More(); itlet.Next()) {
1583 const TopoDS_Edge& Cur = TopoDS::Edge(itlet.Value());
1584 if ( !EdgeTgt.IsBound(Cur)) {
1585 TopoDS_Shape aLocalShape = OF1.Generated(Cur);
1586 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
1587 // const TopoDS_Edge& OTE = TopoDS::Edge(OF1.Generated(Cur));
1588 EdgeTgt.Bind(Cur,OF1.Generated(Cur));
1589 TopoDS_Vertex V1,V2,OV1,OV2;
1590 TopExp::Vertices (Cur,V1,V2);
1591 TopExp::Vertices (OTE,OV1,OV2);
1592 TopTools_ListOfShape LE;
1593 if (!EdgeTgt.IsBound(V1)) {
1594 myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
1595 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V1);
1596 if (LE.Extent() == LA.Extent())
1597 EdgeTgt.Bind(V1,OV1);
1599 if (!EdgeTgt.IsBound(V2)) {
1601 myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
1602 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V2);
1603 if (LE.Extent() == LA.Extent())
1604 EdgeTgt.Bind(V2,OV2);
1608 // end of map created tangent
1610 if (OF1.Status() == BRepOffset_Reversed ||
1611 OF1.Status() == BRepOffset_Degenerated ) continue;
1613 const TopoDS_Face& F1 = OF1.Face();
1616 myInitOffsetFace.SetRoot(AS);
1617 myInitOffsetFace.Bind(AS,F1);
1620 BRepBndLib::Add(F1,Box1);
1621 MapSBox.Bind(F1,Box1);
1623 // ---------------------------------------------
1624 // intersection with all already created faces.
1625 // ---------------------------------------------
1626 Fini = !Intersect(AS,F1,MapSBox,OF1,Inter);
1628 if (AS.ShapeType() == TopAbs_FACE) B.Add(Co,AS);
1630 myMapSF.Bind(AS, OF1);
1633 } // end of : while ( !Fini)
1636 //--------------------------------------------------------
1637 // so the offsets were created and intersected.
1638 // now the tubes are constructed.
1639 //--------------------------------------------------------
1640 // Construction of tubes on edge.
1641 //--------------------------------------------------------
1642 BRepOffset_Type OT = BRepOffset_Convex;
1643 if (myRadius < 0.) OT = BRepOffset_Concave;
1645 TopTools_IndexedDataMapOfShapeListOfShape Map;
1646 TopExp::MapShapesAndAncestors(Co,TopAbs_EDGE,TopAbs_FACE,Map);
1647 TopExp::MapShapesAndAncestors(Co,TopAbs_VERTEX,TopAbs_EDGE,Map);
1649 TopExp_Explorer exp(Co,TopAbs_EDGE);
1650 for ( ; exp.More(); exp.Next()) {
1651 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1652 if ( myMapSF.IsBound(E)) continue;
1654 const TopTools_ListOfShape& Anc = Map.FindFromKey(E);
1655 if (Anc.Extent() == 2) {
1656 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1657 if (!L.IsEmpty() && L.First().Type() == OT) {
1658 TopoDS_Shape aLocalShape = myMapSF(Anc.First()).Generated(E);
1659 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1660 aLocalShape = myMapSF(Anc.Last()) .Generated(E);
1661 TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
1662 // TopoDS_Edge EOn1 = TopoDS::Edge(myMapSF(Anc.First()).Generated(E));
1663 // TopoDS_Edge EOn2 = TopoDS::Edge(myMapSF(Anc.Last()) .Generated(E));
1664 // find if exits tangent edges in the original shape
1665 TopoDS_Edge E1f, E1l;
1666 TopoDS_Vertex V1f, V1l;
1667 TopExp::Vertices(E,V1f,V1l);
1668 TopTools_ListOfShape TangE;
1669 myAnalyse.TangentEdges(E,V1f,TangE);
1670 // find if the pipe on the tangent edges are soon created.
1671 TopTools_ListIteratorOfListOfShape itl(TangE);
1672 Standard_Boolean Find = Standard_False;
1673 for ( ; itl.More() && !Find; itl.Next()) {
1674 if ( myMapSF.IsBound(itl.Value())) {
1675 TopoDS_Shape aLocalShape = myMapSF(itl.Value()).Generated(V1f);
1676 E1f = TopoDS::Edge(aLocalShape);
1677 // E1f = TopoDS::Edge(myMapSF(itl.Value()).Generated(V1f));
1678 Find = Standard_True;
1682 myAnalyse.TangentEdges(E,V1l,TangE);
1683 // find if the pipe on the tangent edges are soon created.
1684 itl.Initialize(TangE);
1685 Find = Standard_False;
1686 for ( ; itl.More() && !Find; itl.Next()) {
1687 if ( myMapSF.IsBound(itl.Value())) {
1688 TopoDS_Shape aLocalShape = myMapSF(itl.Value()).Generated(V1l);
1689 E1l = TopoDS::Edge(aLocalShape);
1690 // E1l = TopoDS::Edge(myMapSF(itl.Value()).Generated(V1l));
1691 Find = Standard_True;
1694 BRepOffset_Offset OF1 (E,EOn1,EOn2,myRadius,E1f, E1l);
1695 const TopoDS_Face& F1 = OF1.Face();
1698 myInitOffsetFace.SetRoot(E);
1699 myInitOffsetFace.Bind(E,F1);
1702 BRepBndLib::Add(F1,Box1);
1703 MapSBox.Bind(F1,Box1);
1705 // ---------------------------------------------
1706 // intersection with all already created faces.
1707 // ---------------------------------------------
1708 Standard_Boolean IsOnRest = Intersect(E,F1,MapSBox,OF1,Inter);
1709 JenRajoute = JenRajoute || IsOnRest;
1711 myMapSF.Bind(E,OF1);
1716 } // end while JenRajoute
1720 myEdges = Inter.NewEdges();
1722 // -------------------------------------------------------------------
1723 // now it is necessary to limit edges on the neighbors (otherwise one
1724 // will go too far and will not be able to construct faces).
1725 // -------------------------------------------------------------------
1727 // Proceed with MakeLoops
1729 BRepOffset_Type OT = BRepOffset_Concave;
1730 if (myRadius < 0.) OT = BRepOffset_Convex;
1732 TopTools_ListOfShape LOF;
1733 //it.Initialize(myFaces);
1734 for (i = 1; i <= myFaces.Extent(); i++) {
1735 const TopoDS_Shape& CurS = myFaces(i);
1737 // tube on free border, it is undesirable.
1738 if ( myStopFaces.Contains(CurS)) continue;
1740 if ( !myMapSF.IsBound(CurS)) continue; // inverted or degenerated
1742 const TopoDS_Face& CurOF = myMapSF(CurS).Face();
1745 if (CurS.ShapeType() == TopAbs_FACE) {
1746 const TopoDS_Face& CurF = TopoDS::Face(CurS);
1747 TopExp_Explorer expe(CurF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1748 for (; expe.More(); expe.Next()) {
1749 // --------------------------------------------------------------
1750 // set in myAsDes the edges generated by limitations of the
1751 // initial square if the type is correct (The edges that will
1752 // disappear are not set)
1753 // --------------------------------------------------------------
1754 const TopoDS_Edge& CurE = TopoDS::Edge(expe.Current());
1755 const BRepOffset_ListOfInterval& L = myAnalyse.Type(CurE);
1756 if (!L.IsEmpty() && L.First().Type() != OT) {
1757 // a priori doe s not disappear, so it is set
1758 TopoDS_Shape aLocalShape = myMapSF(CurF).Generated(CurE);
1759 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
1760 // const TopoDS_Edge& CurOE =
1761 // TopoDS::Edge(myMapSF(CurF).Generated(CurE));
1762 myAsDes->Add(CurOF,CurOE.Oriented(CurE.Orientation()));
1765 const TopTools_ListOfShape& Lanc = myAnalyse.Ancestors(CurE);
1766 if ( !myFaces .Contains(Lanc.First())
1767 || !myFaces .Contains(Lanc.Last ())
1768 || myStopFaces.Contains(Lanc.First())
1769 || myStopFaces.Contains(Lanc.Last ())) {
1770 TopoDS_Shape aLocalShape = myMapSF(CurF).Generated(CurE);
1771 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
1772 // const TopoDS_Edge& CurOE =
1773 // TopoDS::Edge(myMapSF(CurF).Generated(CurE));
1774 myAsDes->Add(CurOF,CurOE.Oriented(CurE.Orientation()));
1778 BRepOffset_Inter2d::Compute(myAsDes,
1785 // ----------------------------------------------------------------
1786 // It is also required to make 2D intersections with generated tubes
1787 // (Useful for unwinding)
1788 // ----------------------------------------------------------------
1789 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(myMapSF);
1790 for ( ; It.More(); It.Next()) {
1791 const TopoDS_Shape& CurS = It.Key();
1792 if ( CurS.ShapeType() == TopAbs_FACE) continue;
1794 const TopoDS_Face& CurOF = It.Value().Face();
1796 // no unwinding by tubes on free border.
1797 if ( myStopFaces.Contains(CurS)) continue;
1801 // --------------------------------------------------------------
1802 // set in myAsDes the edge restrictions of the square
1803 // --------------------------------------------------------------
1804 TopExp_Explorer expe(CurOF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1805 for (; expe.More(); expe.Next()) {
1806 const TopoDS_Edge& CurOE = TopoDS::Edge(expe.Current());
1807 myAsDes->Add(CurOF,CurOE);
1810 BRepOffset_Inter2d::Compute(myAsDes,
1818 BRepOffset_MakeLoops MakeLoops;
1819 MakeLoops.Build( LOF, myAsDes, myImageOffset );
1821 // ------------------------------------------------------------
1822 // It is possible to unwind edges at least one ancestor which of
1823 // is a face of the initial shape, so:
1824 // the edges generated by intersection tube-tube are missing
1825 // ------------------------------------------------------------
1827 // --------------------------------------------------------------
1828 // Currently set the unwinded surfaces in <myResult>
1829 // --------------------------------------------------------------
1830 B.MakeCompound(TopoDS::Compound(myResult));
1831 TopTools_ListIteratorOfListOfShape itLOF(LOF);
1832 for ( ; itLOF.More(); itLOF.Next()) {
1833 const TopoDS_Shape& CurLOF = itLOF.Value();
1835 if ( !myImageOffset.HasImage(CurLOF))
1838 TopTools_ListOfShape Lim;
1839 myImageOffset.LastImage(CurLOF,Lim);
1840 TopTools_ListIteratorOfListOfShape itLim(Lim);
1841 for ( ;itLim.More(); itLim.Next()) {
1842 // If a face is its own image, it is not set
1843 const TopoDS_Shape& CurLIM = itLim.Value();
1844 if (CurLIM.IsSame(CurLOF)) break;
1846 B.Add(myResult,CurLIM);
1851 if ( myResult.IsNull()) {
1852 cout << " No Lines of Generated Centers" << endl;
1856 if (Affich) DBRep::Set("Unwind",myResult);
1863 //=======================================================================
1864 //function : ComputeSurfaces
1866 //=======================================================================
1868 void BiTgte_Blend::ComputeSurfaces()
1870 // set in myFaces, the faces actually implied in the connection
1874 // 1 - Tubes (True Fillets)
1878 Standard_Integer nbc = 1;
1881 TopTools_ListOfShape Empty;
1882 TopTools_DataMapOfShapeListOfShape EmptyMap;
1884 Handle(Geom_Surface) GS1, GS2;
1885 Handle(Geom_Curve) GC1, GC2;
1887 Standard_Real TolAngle = 2*ASin(myTol/Abs(myRadius*0.5));
1888 BRepOffset_Analyse CenterAnalyse(myResult,TolAngle);
1890 // -----------------------------------------------------
1891 // Construction of tubes in myResult
1892 // -----------------------------------------------------
1894 B.MakeCompound(TopoDS::Compound(myResult));
1896 // --------------------------------------------------------------------
1897 // Dummy: for construction of spheres:
1898 // Set in Co the center line, then it there are at least 3
1899 // center lines sharing the same vertex, Sphere on this vertex.
1900 // --------------------------------------------------------------------
1904 // --------------------------------------------------------------------
1905 // Iteration on the edges lines of center
1906 // and their valid valid part is taken after cut and tube construction.
1907 // --------------------------------------------------------------------
1909 //TopTools_MapIteratorOfMapOfShape ic(myEdges);
1911 for (i = 1; i <= myEdges.Extent(); i++) {
1912 const TopoDS_Edge& CurE = TopoDS::Edge(myEdges(i));
1914 const TopTools_ListOfShape& L = myAsDes->Ascendant(CurE);
1915 if ( L.Extent() != 2) continue;
1917 // --------------------------------------------------------------
1918 // F1 and F2 = 2 parallel faces intersecting in CurE.
1919 // --------------------------------------------------------------
1920 const TopoDS_Face& F1 = TopoDS::Face(L.First());
1921 const TopoDS_Face& F2 = TopoDS::Face(L.Last());
1923 // -----------------------------------------------------
1924 // find the orientation of edges of intersection
1925 // in the initial faces.
1926 // -----------------------------------------------------
1927 const TopTools_ListOfShape& LD1 = myAsDes->Descendant(F1);
1928 const TopTools_ListOfShape& LD2 = myAsDes->Descendant(F2);
1930 TopAbs_Orientation Orien1 = Orientation(CurE, F1, LD1);
1931 TopAbs_Orientation Orien2 = Orientation(CurE, F2, LD2);
1933 // ---------------------------------------------------------
1934 // Or1 and Or2 : the shapes generators of parallel faces
1935 // ---------------------------------------------------------
1936 const TopoDS_Shape& Or1 = myInitOffsetFace.ImageFrom(F1);
1937 const TopoDS_Shape& Or2 = myInitOffsetFace.ImageFrom(F2);
1942 TopoDS_Edge OE1, OE2;
1943 TopoDS_Face OF1, OF2;
1944 TopLoc_Location Loc;
1945 Standard_Real f1,l1,f2,l2;
1947 Standard_Boolean OF1isEdge = Standard_False;
1949 if ( Or1.ShapeType() == TopAbs_EDGE) {
1950 OF1isEdge = Standard_True;
1951 OE1 = TopoDS::Edge(Or1);
1952 GC1 = BRep_Tool::Curve(OE1,Loc,f1,l1);
1954 Handle(Geom_Curve)::DownCast(GC1->Transformed(Loc.Transformation()));
1956 else if ( Or1.ShapeType() == TopAbs_FACE) {
1957 OF1 = TopoDS::Face(Or1);
1958 GS1 = BRep_Tool::Surface(OF1);
1961 // ----------------------------------------------------------------
1962 // If a vertex is used in contact, currently nothing is done
1963 // and the vertexes are not managed (Intersections with sphere);
1964 // ----------------------------------------------------------------
1965 if ( OF1.IsNull() && OE1.IsNull()) continue;
1967 Standard_Boolean OF2isEdge = Standard_False;
1969 if ( Or2.ShapeType() == TopAbs_EDGE) {
1970 OF2isEdge = Standard_True;
1971 OE2 = TopoDS::Edge(Or2);
1972 GC2 = BRep_Tool::Curve(OE2,Loc,f2,l2);
1974 Handle(Geom_Curve)::
1975 DownCast(GC2->Transformed(Loc.Transformation()));
1977 else if ( Or2.ShapeType() == TopAbs_FACE) {
1978 OF2 = TopoDS::Face(Or2);
1979 GS2 = BRep_Tool::Surface(OF2);
1981 // ----------------------------------------------------------------
1982 // If a vertex is used in contact, currently nothing is done
1983 // and the vertexes are not managed (Intersections with sphere);
1984 // ----------------------------------------------------------------
1985 if ( OF2.IsNull() && OE2.IsNull()) continue;
1988 TopTools_ListOfShape CurL;
1990 if ( !myImageOffset.HasImage(CurE)) {// the tubes are not unwinded
1991 if ( OF1isEdge && OF2isEdge) { // if I don't have the image, possibly
1992 CurL.Append(CurE); // I'm on intersection tube-tube
1993 } // See comment on the call to
1998 myImageOffset.LastImage(CurE,CurL);
2001 // ---------------------------------------------------------------
2002 // CurL = List of edges descending from CurE ( = Cuts of CurE)
2003 // ---------------------------------------------------------------
2004 TopTools_ListIteratorOfListOfShape itl(CurL);
2005 for ( ; itl.More(); itl.Next()) {
2006 const TopoDS_Edge& CurCutE = TopoDS::Edge(itl.Value());
2008 Handle(Geom2d_Curve) PC1 =
2009 BRep_Tool::CurveOnSurface(CurCutE,F1,f1,l1);
2010 Handle(Geom2d_Curve) PC2 =
2011 BRep_Tool::CurveOnSurface(CurCutE,F2,f2,l2);
2012 if ( PC1.IsNull() || PC2.IsNull()) {
2014 cout << "No PCurves on Intersections : No tubes constructed";
2020 TopoDS_Edge E1f, E1l;
2021 TopoDS_Vertex V1f, V1l;
2022 TopoDS_Vertex VfOnE1,VlOnE1,VfOnE2,VlOnE2;
2023 TopTools_ListOfShape TangE;
2024 TopTools_MapOfShape MapOnV1f, MapOnV1l;
2026 TopExp::Vertices(CurCutE,V1f,V1l);
2028 // find if the pipe on the tangent edges are soon created.
2029 // edges generated by V1f and V1l + Maj MapOnV1f/l
2030 E1f = FindCreatedEdge(V1f,CurCutE,myMapSF,MapOnV1f,
2031 CenterAnalyse,myRadius,myTol);
2033 E1l = FindCreatedEdge(V1l,CurCutE,myMapSF,MapOnV1l,
2034 CenterAnalyse,myRadius,myTol);
2038 BiTgte_CurveOnEdge ConE(CurCutE, OE1);
2039 Handle(Geom_Curve) C = MakeCurve(ConE);
2040 gp_Pnt P1 = C->Value(C->FirstParameter());
2041 gp_Pnt P2 = C->Value(C->LastParameter());
2042 VfOnE1 = FindVertex(P1,MapOnV1f,myTol);
2043 if ( VfOnE1.IsNull())
2044 VfOnE1 = FindVertex(P1,MapOnV1l,myTol);
2045 VlOnE1 = FindVertex(P2,MapOnV1l,myTol);
2046 if ( VlOnE1.IsNull())
2047 VlOnE1 = FindVertex(P2,MapOnV1f,myTol);
2048 if ( P1.SquareDistance(P2) < myTol*myTol) {
2049 //BRepOffset_Offset manages degenerated KPart
2050 //It is REQUIRED that C should be a circle with ZERO radius
2051 E1 = MakeDegeneratedEdge(C,VfOnE1);
2054 E1 = BRepLib_MakeEdge(C,VfOnE1,VlOnE1);
2059 P2d = PC1->Value(f1);
2060 gp_Pnt P1 = GS1->Value(P2d.X(),P2d.Y());
2061 P2d = PC1->Value(l1);
2062 gp_Pnt P2 = GS1->Value(P2d.X(),P2d.Y());
2063 VfOnE1 = FindVertex(P1,MapOnV1f,myTol);
2064 VlOnE1 = FindVertex(P2,MapOnV1l,myTol);
2065 BRepLib_MakeEdge MKE(PC1,GS1,VfOnE1,VlOnE1,f1,l1);
2069 cout << "Edge Not Done" << endl;
2073 KPartCurve3d(E1,PC1,GS1);
2077 BiTgte_CurveOnEdge ConE(CurCutE, OE2);
2078 Handle(Geom_Curve) C = MakeCurve(ConE);
2079 gp_Pnt P1 = C->Value(C->FirstParameter());
2080 gp_Pnt P2 = C->Value(C->LastParameter());
2081 VfOnE2 = FindVertex(P1,MapOnV1f,myTol);
2082 if ( VfOnE2.IsNull())
2083 VfOnE2 = FindVertex(P1,MapOnV1l,myTol);
2084 VlOnE2 = FindVertex(P2,MapOnV1l,myTol);
2085 if ( VlOnE2.IsNull())
2086 VlOnE2 = FindVertex(P2,MapOnV1f,myTol);
2087 if ( P1.SquareDistance(P2) < myTol*myTol) {
2088 //BRepOffset_Offset manages degenerated KParts
2089 //It is REQUIRED that C should be a circle with ZERO radius
2090 E2 = MakeDegeneratedEdge(C,VfOnE2);
2093 E2 = BRepLib_MakeEdge(C,VfOnE2,VlOnE2);
2098 P2d = PC2->Value(f2);
2099 gp_Pnt P1 = GS2->Value(P2d.X(),P2d.Y());
2100 P2d = PC2->Value(l2);
2101 gp_Pnt P2 = GS2->Value(P2d.X(),P2d.Y());
2102 VfOnE2 = FindVertex(P1,MapOnV1f,myTol);
2103 VlOnE2 = FindVertex(P2,MapOnV1l,myTol);
2104 BRepLib_MakeEdge MKE(PC2,GS2,VfOnE2,VlOnE2,f2,l2);
2108 cout << "edge not Done" << endl;
2111 KPartCurve3d(E2,PC2,GS2);
2113 // Increment of the Map of Created if reconstruction of the Shape is required
2114 if ( myBuildShape) {
2115 myCreated.Bind(CurCutE,EmptyMap);
2117 myCreated(CurCutE).Bind(Or1,Empty);
2118 myCreated(CurCutE)(Or1).Append(E1);
2120 myCreated(CurCutE).Bind(Or2,Empty);
2121 myCreated(CurCutE)(Or2).Append(E2);
2124 // ----------------------------------------------------------
2125 // try to init E1f, E1l, if not found with Analysis.
2126 // Should happen only if the THEORETICALLY tangent edges
2127 // are not actually tangent ( Cf: Approximation of lines
2128 // of intersection that add noise.)
2129 // ----------------------------------------------------------
2130 TopoDS_Vertex V1,V2;
2131 if ( E1f.IsNull() && !VfOnE1.IsNull() && !VfOnE2.IsNull()) {
2132 TopTools_MapIteratorOfMapOfShape it(MapOnV1f);
2133 for ( ; it.More(); it.Next()) {
2134 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
2136 TopExp::Vertices(E,V1,V2);
2137 if ((V1.IsSame(VfOnE1) && V2.IsSame(VfOnE2)) ||
2138 (V2.IsSame(VfOnE1) && V1.IsSame(VfOnE2)) ) {
2145 if ( E1l.IsNull() && !VlOnE1.IsNull() && !VlOnE2.IsNull()) {
2146 TopTools_MapIteratorOfMapOfShape it(MapOnV1l);
2147 for ( ; it.More(); it.Next()) {
2148 const TopoDS_Edge& E = TopoDS::Edge(it.Key());
2150 TopExp::Vertices(E,V1,V2);
2151 if ((V1.IsSame(VlOnE1) && V2.IsSame(VlOnE2)) ||
2152 (V2.IsSame(VlOnE1) && V1.IsSame(VlOnE2)) ) {
2160 E1.Orientation(Orien1);
2161 E2.Orientation(Orien2);
2163 BRepOffset_Offset AnOffset(CurCutE,E1,E2,-myRadius,E1f,E1l,
2164 myNubs, myTol, GeomAbs_C2);
2165 myMapSF.Bind(CurCutE,AnOffset);
2166 myCenters.Add(CurCutE);
2169 const TopoDS_Face& Tuyo = AnOffset.Face();
2170 B.Add(myResult,Tuyo);
2172 if ( myBuildShape) {
2173 // method based ONLY on the construction of fillet:
2174 // the first edge of the tube is exactly on Shape1.
2175 GeomAPI_ProjectPointOnCurve Projector;
2176 TopExp_Explorer exp(Tuyo,TopAbs_EDGE);
2177 TopoDS_Vertex V1,V2;
2178 if (OF1isEdge) { // Update CutEdges.
2179 const TopoDS_Edge& EOnF1 = TopoDS::Edge(exp.Current());
2180 TopExp::Vertices(EOnF1,V1,V2);
2182 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2183 Projector.Init(P1,GC1);
2184 Standard_Real U1 = Projector.LowerDistanceParameter();
2186 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2187 Projector.Init(P2,GC1);
2188 Standard_Real U2 = Projector.LowerDistanceParameter();
2190 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
2191 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,TopoDS::Edge(Or1),myTol);
2192 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
2193 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,TopoDS::Edge(Or1),myTol);
2194 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),U1,
2195 // TopoDS::Edge(Or1),myTol);
2196 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),U2,
2197 // TopoDS::Edge(Or1),myTol);
2199 if (!myCutEdges.IsBound(Or1)) {
2200 TopTools_ListOfShape Dummy;
2201 myCutEdges.Bind(Or1,Dummy);
2203 TopTools_ListOfShape& L1 = myCutEdges(Or1);
2204 L1.Append(V1); L1.Append(V2);
2206 if (OF2isEdge) { // Update CutEdges.
2208 const TopoDS_Edge& EOnF2 = TopoDS::Edge(exp.Current());
2209 TopExp::Vertices(EOnF2,V1,V2);;
2211 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2212 Projector.Init(P1,GC2);
2213 Standard_Real U1 = Projector.LowerDistanceParameter();
2215 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2216 Projector.Init(P2,GC2);
2217 Standard_Real U2 = Projector.LowerDistanceParameter();
2219 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
2220 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,TopoDS::Edge(Or2),myTol);
2221 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
2222 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,TopoDS::Edge(Or2),myTol);
2223 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),U1,
2224 // TopoDS::Edge(Or2),myTol);
2225 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),U2,
2226 // TopoDS::Edge(Or2),myTol);
2228 if (!myCutEdges.IsBound(Or2)) {
2229 TopTools_ListOfShape Dummy;
2230 myCutEdges.Bind(Or2,Dummy);
2232 TopTools_ListOfShape& L2 = myCutEdges(Or2);
2233 L2.Append(V1); L2.Append(V2);
2239 sprintf(name,"%s_%d","SURF",nbc);
2240 DBRep::Set(name,AnOffset.Face());
2247 // ---------------------------------------------------
2248 // Construction of spheres,
2249 // if enough tubes arrive at the vertex
2250 // ---------------------------------------------------
2251 TopTools_IndexedDataMapOfShapeListOfShape Map;
2252 TopExp::MapShapesAndAncestors(Co,TopAbs_VERTEX,TopAbs_EDGE,Map);
2254 for ( Standard_Integer i = 1; i <= Map.Extent(); i++) {
2255 const TopoDS_Vertex& V = TopoDS::Vertex(Map.FindKey(i));
2256 if ( Map(i).Extent() != 3) continue;
2258 TopTools_ListOfShape LOE;
2259 TopTools_ListIteratorOfListOfShape it;
2261 for (it.Initialize(Map(i)) ; it.More(); it.Next()) {
2262 Standard_Boolean Reverse = Standard_True;
2264 LOE.Append(myMapSF(it.Value()).Generated(V).Reversed());
2266 LOE.Append(myMapSF(it.Value()).Generated(V));
2269 BRepOffset_Offset OFT(V,LOE,-myRadius,myNubs, myTol, GeomAbs_C2);
2270 myMapSF.Bind(V,OFT);
2273 B.Add(myResult,OFT.Face());
2277 sprintf(name,"%s_%d","SURF",nbc);
2278 DBRep::Set(name,OFT.Face());
2286 //=======================================================================
2287 //function : ComputeShape
2289 //=======================================================================
2290 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
2292 void BiTgte_Blend::ComputeShape()
2294 // Find in the initial Shapel:
2295 // - untouched Faces
2296 // - generated tubes
2297 // - the faces neighbors of tubes that sould be reconstucted preserving sharing.
2299 // For Debug : Visualize edges of the initial shape that should be reconstructed.
2302 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myCutEdges);
2303 Standard_Integer NbEdges = 0;
2304 for ( ; itm.More(); itm.Next()) {
2305 const TopoDS_Edge& E = TopoDS::Edge(itm.Key());
2306 const TopTools_ListOfShape& VonE = itm.Value();
2307 TopTools_ListOfShape NewE;
2309 CutEdge(E,VonE,NewE);
2310 for (TopTools_ListIteratorOfListOfShape it(NewE); it.More(); it.Next()) {
2311 sprintf(name,"%s_%d","CUTE",++NbEdges);
2312 DBRep::Set(name,it.Value());
2320 // modify the tubes on edge for partition of edges.
2322 Standard_Integer NbS = NbSurfaces();
2323 for (Standard_Integer i = 1; i <= NbS; i++) {
2324 const TopoDS_Shape& S1 = SupportShape1(i);
2326 if ( S1.ShapeType() == TopAbs_EDGE) {
2327 const TopoDS_Edge& E1 = TopoDS::Edge(S1);
2328 // it is required to replace in F the cut edges of E1, that
2330 const TopTools_ListOfShape& VonE = myCutEdges(E1);
2331 TopTools_ListOfShape NewE;
2332 CutEdge(E1,VonE,NewE);
2338 TopTools_DataMapOfShapeShape Created;
2340 TopTools_ListOfShape Empty;
2341 TopTools_DataMapOfShapeListOfShape EmptyMap;
2346 // Maj of the Map of created.
2347 // Update edges that do not change in the resulting shape
2348 // i.e. invariant edges in the unwinding.
2349 TopExp_Explorer exp(myShape,TopAbs_FACE);
2350 // Standard_Integer nbe = 1;
2351 for ( ;exp.More(); exp.Next()) {
2353 const TopoDS_Face& CurF = TopoDS::Face(exp.Current());
2355 if ( !myFaces.Contains(CurF)) continue; // so the face is not touched
2357 // so the faces are unwinded
2358 if ( !myMapSF.IsBound(CurF)) continue; // inverted or degenerated
2360 const BRepOffset_Offset& Offset = myMapSF(CurF);
2361 const TopoDS_Face& CurOF = myMapSF(CurF).Face();
2363 if ( !myImageOffset.HasImage(CurOF)) // face disappears in unwinding
2366 TopExp_Explorer exp2(CurF,TopAbs_EDGE);
2367 for ( ;exp2.More(); exp2.Next()) {
2368 const TopoDS_Edge& CurE = TopoDS::Edge(exp2.Current());
2369 TopoDS_Shape aLocalShape = Offset.Generated(CurE);
2370 const TopoDS_Edge& CurOE = TopoDS::Edge(aLocalShape);
2371 // const TopoDS_Edge& CurOE = TopoDS::Edge(Offset.Generated(CurE));
2373 if (!myImageOffset.HasImage(CurOE)) continue;
2376 const TopoDS_Edge& ImE =
2377 TopoDS::Edge(myImageOffset.Image(CurOE).First());
2378 if (ImE.IsSame(CurOE)) {
2379 myCreated.Bind(CurOE,EmptyMap);
2380 myCreated(CurOE).Bind(CurF,Empty);
2381 myCreated(CurOE)(CurF).Append(CurE);
2386 // The connected faces are already in myResult.
2387 // So it is necessary to add faces:
2388 // - non-touched (so not in myFaces)
2389 // - issuing from the unwinding (non degenerated, non inverted, non disappeared)
2390 exp.Init(myShape,TopAbs_FACE);
2391 for ( ;exp.More(); exp.Next()) {
2393 const TopoDS_Face& CurF = TopoDS::Face(exp.Current());
2395 if ( !myFaces.Contains(CurF)) {
2396 // so the face is not touched
2397 B.Add(myResult,CurF);
2399 else { // so the faces are unwindeds
2401 if ( !myMapSF.IsBound(CurF)) continue; // inverted or degenerated
2403 const TopoDS_Face& CurOF = myMapSF(CurF).Face();
2405 if ( !myImageOffset.HasImage(CurOF)) // face disappears in unwinding
2408 // List of faces generated by a face in the unwinding
2409 TopTools_ListOfShape Lim;
2410 myImageOffset.LastImage(CurOF,Lim);
2411 TopTools_ListIteratorOfListOfShape itLim(Lim);
2412 for ( ;itLim.More(); itLim.Next()) {
2413 // DeboucFace = offset Face unwinded in "Debouc".
2414 const TopoDS_Face& DeboucFace = TopoDS::Face(itLim.Value());
2417 Handle(Geom_Surface) S = BRep_Tool::Surface(CurF,L);
2419 TopoDS_Face NewF; B.MakeFace(NewF);
2420 B.UpdateFace(NewF,S,L,BRep_Tool::Tolerance(CurF));
2422 TopTools_DataMapOfShapeShape MapSS;
2424 TopoDS_Shape aLocalShape = DeboucFace.Oriented(TopAbs_FORWARD);
2425 const TopoDS_Face& Face = TopoDS::Face(aLocalShape);
2426 // const TopoDS_Face& Face =
2427 // TopoDS::Face(DeboucFace.Oriented(TopAbs_FORWARD));
2428 TopExp_Explorer exp2(Face, TopAbs_EDGE);
2429 for ( ; exp2.More(); exp2.Next()) {
2430 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
2431 TopoDS_Vertex V1,V2,OV1,OV2;
2432 TopExp::Vertices(E ,V1 ,V2 );
2433 if (myCreated.IsBound(E)) {
2434 if (myCreated(E).IsBound(CurF)) {
2435 const TopoDS_Edge& OE = TopoDS::Edge(myCreated(E)(CurF).First());
2436 TopExp::Vertices(OE,OV1,OV2);
2437 if ( !myCreated.IsBound(V1)) myCreated.Bind(V1,EmptyMap);
2438 if ( !myCreated.IsBound(V2)) myCreated.Bind(V2,EmptyMap);
2439 if ( !myCreated(V1).IsBound(CurF)) {
2440 myCreated(V1).Bind(CurF,Empty);
2441 myCreated(V1)(CurF).Append(OV1);
2443 if ( !myCreated(V2).IsBound(CurF)) {
2444 myCreated(V2).Bind(CurF,Empty);
2445 myCreated(V2)(CurF).Append(OV2);
2451 TopExp_Explorer expw(Face, TopAbs_WIRE);
2452 for ( ; expw.More(); expw.Next()) {
2453 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
2454 TopExp_Explorer expe(W.Oriented(TopAbs_FORWARD),
2459 for ( ; expe.More(); expe.Next()) {
2460 const TopoDS_Edge& E = TopoDS::Edge(expe.Current());
2462 Handle(Geom2d_Curve) C2d =
2463 BRep_Tool::CurveOnSurface(E,Face,f,l);
2465 if ( MapSS.IsBound(E)) { // this is an edge of cutting
2466 OE = TopoDS::Edge(MapSS(E));
2467 TopoDS_Shape aLocalShape = E.Reversed();
2468 Handle(Geom2d_Curve) C2d_1 =
2469 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),Face,f,l);
2470 // Handle(Geom2d_Curve) C2d_1 =
2471 // BRep_Tool::CurveOnSurface(TopoDS::Edge(E.Reversed()),
2473 if ( E.Orientation() == TopAbs_FORWARD)
2474 B.UpdateEdge(OE,C2d,C2d_1,NewF,BRep_Tool::Tolerance(E));
2476 B.UpdateEdge(OE,C2d_1,C2d,NewF,BRep_Tool::Tolerance(E));
2480 // Is there an image in the Map of Created ?
2481 if ( myCreated.IsBound(E)) {
2482 if ( myCreated(E).IsBound(CurF)) {
2483 OE = TopoDS::Edge(myCreated(E)(CurF).First());
2488 TopoDS_Vertex V1,V2,OV1,OV2;
2489 TopExp::Vertices(E,V1,V2);
2490 if ( myCreated.IsBound(V1) && myCreated(V1).IsBound(CurF)) {
2491 OV1 = TopoDS::Vertex(myCreated(V1)(CurF).First());
2496 C2d->Value(BRep_Tool::Parameter(V1,E,Face));
2498 S->D0(P2d.X(),P2d.Y(),P);
2499 P.Transform(L.Transformation());
2500 B.UpdateVertex(OV1,P,BRep_Tool::Tolerance(V1));
2501 myCreated.Bind(V1,EmptyMap);
2502 myCreated(V1).Bind(CurF,Empty);
2503 myCreated(V1)(CurF).Append(OV1);
2505 if ( myCreated.IsBound(V2) && myCreated(V2).IsBound(CurF)) {
2506 OV2 = TopoDS::Vertex(myCreated(V2)(CurF).First());
2511 C2d->Value(BRep_Tool::Parameter(V2,E,Face));
2513 S->D0(P2d.X(),P2d.Y(),P);
2514 P.Transform(L.Transformation());
2515 B.UpdateVertex(OV2,P,BRep_Tool::Tolerance(V2));
2516 myCreated.Bind(V2,EmptyMap);
2517 myCreated(V2).Bind(CurF,Empty);
2518 myCreated(V2)(CurF).Append(OV2);
2520 B.Add(OE,OV1.Oriented(V1.Orientation()));
2521 B.Add(OE,OV2.Oriented(V2.Orientation()));
2523 B.UpdateEdge(OE,C2d,NewF,BRep_Tool::Tolerance(E));
2525 // ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
2528 B.Add(OW, OE.Oriented(E.Orientation()));
2530 B.Add(NewF, OW.Oriented(W.Orientation()));
2533 NewF.Orientation(DeboucFace.Orientation());
2535 BRepTools::Update(NewF);
2536 B.Add(myResult,NewF);
2541 // non-regarding the cause, there always remain greeb borders on this Shape, so it is sewn.
2542 Handle(BRepBuilderAPI_Sewing) Sew = new BRepBuilderAPI_Sewing(myTol);
2544 BRepLib::BuildCurves3d(myResult);
2546 exp.Init(myResult,TopAbs_FACE);
2547 for ( ;exp.More(); exp.Next())
2548 Sew->Add(exp.Current());
2552 // SameParameter is done in case Sew does not do it (Detect that the edges
2553 // are not sameparameter but does nothing.)
2555 const TopoDS_Shape& SewedShape = Sew->SewedShape();
2556 if ( !SewedShape.IsNull()) {
2557 exp.Init(Sew->SewedShape(), TopAbs_EDGE);
2558 for (; exp.More(); exp.Next()) {
2559 const TopoDS_Edge& sec = TopoDS::Edge(exp.Current());
2560 BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
2562 myResult = SewedShape;
2567 //=======================================================================
2568 //function : Intersect
2570 //=======================================================================
2572 Standard_Boolean BiTgte_Blend::Intersect
2573 (const TopoDS_Shape& Init,
2574 const TopoDS_Face& Face,
2575 const BiTgte_DataMapOfShapeBox& MapSBox,
2576 const BRepOffset_Offset& OF1,
2577 BRepOffset_Inter3d& Inter)
2579 Standard_Boolean JenRajoute = Standard_False;
2581 const Bnd_Box& Box1 = MapSBox(Face);
2583 // -----------------------------------------------
2584 // intersection with all already created faces.
2585 // -----------------------------------------------
2586 const TopoDS_Shape& InitShape1 = OF1.InitialShape();
2587 Standard_Boolean F1surBordLibre =
2588 InitShape1.ShapeType() == TopAbs_EDGE &&
2589 myStopFaces.Contains(InitShape1);
2591 TopTools_MapOfShape Done;
2592 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(myMapSF);
2593 for ( ; It.More(); It.Next()) {
2594 const BRepOffset_Offset& OF2 = It.Value();
2595 const TopoDS_Face& F2 = OF2.Face();
2597 if (Box1.IsOut(MapSBox(F2))) continue;
2599 if ( Inter.IsDone(Face,F2)) continue;
2601 // 2 tubes created on free border are not intersected.
2602 const TopoDS_Shape& InitShape2 = OF2.InitialShape();
2603 Standard_Boolean F2surBordLibre =
2604 InitShape2.ShapeType() == TopAbs_EDGE &&
2605 myStopFaces.Contains(InitShape2);
2608 if ( F1surBordLibre && F2surBordLibre) {
2609 cout << "Rejection : 2 tubes on free border are not intersected";
2614 if ( F1surBordLibre && F2surBordLibre) continue;
2616 // -------------------------------------------------------
2617 // Tubes are not intersected with neighbor faces.
2618 // -------------------------------------------------------
2619 const TopoDS_Shape& ItKey = It.Key();
2621 if ( Init.ShapeType() == TopAbs_EDGE) {
2622 if (ItKey.ShapeType() == TopAbs_FACE &&
2623 IsInFace(TopoDS::Edge(Init), TopoDS::Face(ItKey))) continue;
2626 Inter.FaceInter(Face,F2,myInitOffsetFace);
2628 // ------------------------------------------
2629 // an edge of F1 or F2 has been touched ?
2630 // if yes, add faces in myFaces
2631 // ==> JenRajoute = True
2632 // ------------------------------------------
2633 TopTools_ListOfShape LInt;
2635 if (myAsDes->HasCommonDescendant(Face,F2,LInt)) {
2636 TopTools_ListIteratorOfListOfShape itl2;
2637 for (itl2.Initialize(LInt); itl2.More(); itl2.Next()) {
2638 const TopoDS_Edge& CurE = TopoDS::Edge(itl2.Value());
2639 TopoDS_Vertex V1,V2;
2641 TopExp::Vertices(CurE,V1,V2);
2643 if ( Done.Add(V1)) {
2644 Standard_Boolean IsOnR1 = IsOnRestriction(V1,CurE,Face,E1);
2645 Standard_Boolean IsOnR2 = IsOnRestriction(V1,CurE,F2,E2);
2647 if (IsOnR1 && IsOnR2) {
2648 cout << "Leave in the same tps on 2 faces, ";
2649 cout << "propagation only on free border";
2654 if ( !myStopFaces.Contains(Init)) {
2655 Add(E1,myEdges,Init,OF1,myAnalyse,IsOnR1 && IsOnR2);
2656 JenRajoute = Standard_True;
2660 if ( !myStopFaces.Contains(ItKey)) {
2661 Add(E2,myEdges, ItKey,OF2,myAnalyse,IsOnR1 && IsOnR2);
2662 JenRajoute = Standard_True;
2667 if ( Done.Add(V2)) {
2668 Standard_Boolean IsOnR1 = IsOnRestriction(V2,CurE,Face,E1);
2669 Standard_Boolean IsOnR2 = IsOnRestriction(V2,CurE,F2,E2);
2671 // If IsOnR1 && IsOnR2,
2672 // Leave in the same tps on 2 faces, propagate only on
2674 // A priori, only facet is closed.
2676 if (IsOnR1 && IsOnR2) {
2677 cout << "Leave with the same tps on 2 faces, ";
2678 cout << "propagate only if the border is free";
2683 if ( !myStopFaces.Contains(Init)) {
2684 Add(E1,myEdges,Init,OF1,myAnalyse,IsOnR1 && IsOnR2);
2685 JenRajoute = Standard_True;
2689 if ( !myStopFaces.Contains(ItKey)) {
2690 Add(E2,myEdges,ItKey,OF2,myAnalyse,IsOnR1 && IsOnR2);
2691 JenRajoute = Standard_True;