1 // Created on: 1994-03-03
2 // Created by: Joelle CHAUVET
3 // Copyright (c) 1994-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.
17 // Modified: Mon Jan 12 10:50:10 1998
18 // automatic management of origin and orientation
19 // with method Organize
20 // Modified: Mon Feb 23 09:28:46 1998
21 // method Organize with option of projection for closed wires
22 // new method SameNumber with option to report cuts
23 // + utilities ComputeACR and InsertACR
24 // + processing of the case of last point section
25 // Modified: Thu Apr 30 15:24:17 1998
26 // separation closed / open sections + debug
27 // Organize becomes ComputeOrigin and SearchOrigin
28 // Modified: Tue Jul 21 16:48:35 1998
29 // limited case for Pnext of a twist (BUC60281)
30 // Modified: Thu Jul 23 11:38:36 1998
31 // calculate the angle of rotation in SearchOrigin
32 // Modified: Fri Jul 31 15:14:19 1998
33 // IntersectOnWire + MapVLV
34 // Modified: Mon Oct 12 09:42:33 1998
35 // number of edges in EdgesFromVertex (CTS21570)
37 #include <BRepFill.hxx>
39 #include <BRep_Builder.hxx>
40 #include <BRep_Tool.hxx>
41 #include <BRepExtrema_DistShapeShape.hxx>
42 #include <BRepExtrema_ExtPC.hxx>
43 #include <BRepLib.hxx>
44 #include <BRepLib_FindSurface.hxx>
45 #include <BRepLib_MakeEdge.hxx>
46 #include <BRepLib_MakeFace.hxx>
47 #include <BRepLib_MakeWire.hxx>
48 #include <BRepTools_WireExplorer.hxx>
49 #include <GCPnts_AbscissaPoint.hxx>
50 #include <Geom2d_Line.hxx>
51 #include <Geom_Curve.hxx>
52 #include <Geom_Plane.hxx>
53 #include <Geom_Surface.hxx>
54 #include <Geom_TrimmedCurve.hxx>
55 #include <GeomFill_Generator.hxx>
57 #include <gp_Dir2d.hxx>
60 #include <gp_Pnt2d.hxx>
62 #include <Precision.hxx>
63 #include <Standard_NoSuchObject.hxx>
65 #include <TopExp_Explorer.hxx>
66 #include <TopLoc_Location.hxx>
68 #include <TopoDS_Edge.hxx>
69 #include <TopoDS_Face.hxx>
70 #include <TopoDS_Shape.hxx>
71 #include <TopoDS_Shell.hxx>
72 #include <TopoDS_Vertex.hxx>
73 #include <TopoDS_Wire.hxx>
74 #include <TopTools_Array1OfShape.hxx>
75 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
76 #include <TopTools_IndexedMapOfShape.hxx>
77 #include <TopTools_ListOfShape.hxx>
78 #include <TopTools_SequenceOfShape.hxx>
80 static void MakeWire(const TopTools_Array1OfShape& Edges,
81 const Standard_Integer rangdeb,
82 const Standard_Boolean forward,
86 Standard_Integer rang, nbEdges = Edges.Length();
89 for (rang=rangdeb;rang<=nbEdges;rang++) {
90 BW.Add(newwire,TopoDS::Edge(Edges(rang)));
92 for (rang=1;rang<rangdeb;rang++) {
93 BW.Add(newwire,TopoDS::Edge(Edges(rang)));
99 for (rang=rangdeb;rang>=1;rang--) {
100 E = TopoDS::Edge(Edges(rang));
101 BW.Add(newwire,E.Reversed());
103 for (rang=nbEdges;rang>rangdeb;rang--) {
104 E = TopoDS::Edge(Edges(rang));
105 BW.Add(newwire, E.Reversed());
108 newwire.Orientation(TopAbs_FORWARD);
109 newwire.Closed (Standard_True);
112 static void CutEdge(const TopoDS_Edge& CurrentEdge,
113 const Standard_Real& Param,
116 const TopoDS_Vertex& VRef)
119 Standard_Real first,last;
120 Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
121 TopoDS_Vertex Vf, Vl, Vi;
122 B.MakeVertex(Vi, C->Value(Param), Precision::Confusion());
123 TopExp::Vertices(CurrentEdge, Vf, Vl);
124 if (VRef.IsSame(Vf)) {
125 E1 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
126 E2 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);
129 E2 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
130 E1 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);
135 static void TrimEdge (const TopoDS_Edge& CurrentEdge,
136 const TColStd_SequenceOfReal& CutValues,
137 const Standard_Real t0, const Standard_Real t1,
138 const Standard_Boolean SeqOrder,
139 TopTools_SequenceOfShape& S)
143 Standard_Integer j, ndec=CutValues.Length();
144 Standard_Real first,last,m0,m1;
145 Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
147 TopoDS_Vertex Vf,Vl,Vbid,V0,V1;
148 TopAbs_Orientation CurrentOrient = CurrentEdge.Orientation();
149 TopExp::Vertices(CurrentEdge,Vf,Vl);
153 // from first to last
156 for (j=1; j<=ndec; j++) {
158 m1 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
159 TopoDS_Edge CutE = BRepLib_MakeEdge(C,V0,Vbid,m0,m1);
160 CutE.Orientation(CurrentOrient);
163 V0 = TopExp::LastVertex(CutE);
166 TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
167 LastE.Orientation(CurrentOrient);
173 // from last to first
176 for (j=ndec; j>=1; j--) {
178 m0 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
179 TopoDS_Edge CutE = BRepLib_MakeEdge(C,Vbid,V1,m0,m1);
180 CutE.Orientation(CurrentOrient);
183 V1 = TopExp::FirstVertex(CutE);
186 TopoDS_Edge LastE = BRepLib_MakeEdge(C,Vf,V1,first,m1);
187 LastE.Orientation(CurrentOrient);
195 //=======================================================================
198 //=======================================================================
200 TopoDS_Face BRepFill::Face(const TopoDS_Edge& Edge1,
201 const TopoDS_Edge& Edge2 )
206 // Class BRep_Tool without fields and without Constructor :
209 TopLoc_Location L,L1,L2;
210 Standard_Real f1,f2,l1,l2, Tol;
212 // Handle(Geom_Curve) C1 = BT.Curve(Edge1,L1,f1,l1);
213 Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
214 // Handle(Geom_Curve) C2 = BT.Curve(Edge2,L2,f2,l2);
215 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
217 // compute the location
218 Standard_Boolean SameLoc = Standard_False;
221 L1 = L2 = TopLoc_Location();
222 SameLoc = Standard_True;
225 // transform and trim the curves
227 TopoDS_Vertex V1f,V1l,V2f,V2l;
229 // create a new Handle
230 if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
231 Abs(l1 - C1->LastParameter()) > Precision::PConfusion() ) {
232 C1 = new Geom_TrimmedCurve(C1,f1,l1);
235 C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
237 // eventually the curve is concerned
239 C1->Transform(L1.Transformation());
241 // it is set in the proper direction and its vertices are taken
242 if (Edge1.Orientation() == TopAbs_REVERSED) {
243 TopExp::Vertices(Edge1,V1l,V1f);
247 TopExp::Vertices(Edge1,V1f,V1l);
250 // a new Handle is created
251 if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
252 Abs(l2 - C2->LastParameter()) > Precision::PConfusion() ) {
253 C2 = new Geom_TrimmedCurve(C2,f2,l2);
256 C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
258 // eventually the curve is concerned
260 C2->Transform(L2.Transformation());
262 // it is set in the proper direction and its vertices are taken
263 if (Edge2.Orientation() == TopAbs_REVERSED) {
264 TopExp::Vertices(Edge2,V2l,V2f);
268 TopExp::Vertices(Edge2,V2f,V2l);
271 // Are they closed edges?
272 Standard_Boolean Closed = V1f.IsSame(V1l) && V2f.IsSame(V2l);
275 GeomFill_Generator Generator;
276 Generator.AddCurve( C1);
277 Generator.AddCurve( C2);
278 Generator.Perform( Precision::PConfusion());
280 Handle(Geom_Surface) Surf = Generator.Surface();
281 Handle(Geom_Curve) Iso;
283 B.MakeFace(Face,Surf,Precision::Confusion());
285 // make the missing edges
286 Surf->Bounds(f1,l1,f2,l2);
288 TopoDS_Edge Edge3, Edge4;
290 Iso = Surf->UIso(f1);
291 Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
292 if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
293 B.MakeEdge(Edge3,Iso,Precision::Confusion());
297 B.Degenerated(Edge3, Standard_True);
299 V1f.Orientation(TopAbs_FORWARD);
301 V2f.Orientation(TopAbs_REVERSED);
303 B.Range(Edge3,f2,l2);
309 Iso = Surf->UIso(l1);
310 Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
311 if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
312 B.MakeEdge(Edge4,Iso,Precision::Confusion());
316 B.Degenerated(Edge4, Standard_True);
318 V1l.Orientation(TopAbs_FORWARD);
320 V2l.Orientation(TopAbs_REVERSED);
322 B.Range(Edge4,f2,l2);
333 B.Add(W,Edge2.Reversed());
335 W.Closed (Standard_True);
341 Standard_Real T = Precision::Confusion();
343 if ( Edge1.Orientation() == TopAbs_REVERSED ) {
344 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),Face,T);
345 B.Range(Edge1,Face,-l1,-f1);
348 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),Face,T);
349 B.Range(Edge1,Face,f1,l1);
352 if ( Edge2.Orientation() == TopAbs_REVERSED ) {
353 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),Face,T);
354 B.Range(Edge2,Face,-l1,-f1);
357 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),Face,T);
358 B.Range(Edge2,Face,f1,l1);
363 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
364 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
367 B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
368 B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
371 // Set the non parameter flag;
372 B.SameParameter(Edge1,Standard_False);
373 B.SameParameter(Edge2,Standard_False);
374 B.SameParameter(Edge3,Standard_False);
375 B.SameParameter(Edge4,Standard_False);
376 B.SameRange(Edge1,Standard_False);
377 B.SameRange(Edge2,Standard_False);
378 B.SameRange(Edge3,Standard_False);
379 B.SameRange(Edge4,Standard_False);
381 BRepLib::SameParameter(Face);
383 if ( SameLoc) Face.Move(L);
388 //=======================================================================
391 //=======================================================================
393 TopoDS_Shell BRepFill::Shell(const TopoDS_Wire& Wire1,
394 const TopoDS_Wire& Wire2 )
399 TopoDS_Edge Edge1, Edge2, Edge3, Edge4, Couture;
402 // Class BRep_Tool without fields and without Constructor :
409 Standard_Boolean Closed = Wire1.Closed() && Wire2.Closed();
411 Standard_Boolean thefirst = Standard_True;
413 ex1.Init(Wire1,TopAbs_EDGE);
414 ex2.Init(Wire2,TopAbs_EDGE);
416 while ( ex1.More() && ex2.More() ) {
418 Edge1 = TopoDS::Edge(ex1.Current());
419 Edge2 = TopoDS::Edge(ex2.Current());
421 Standard_Boolean Periodic =
422 BRep_Tool::IsClosed(Edge1) && BRep_Tool::IsClosed(Edge2);
427 TopLoc_Location L,L1,L2;
428 Standard_Real f1,l1,f2,l2,Tol;
430 Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
431 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
433 // compute the location
434 Standard_Boolean SameLoc = Standard_False;
437 L1 = L2 = TopLoc_Location();
438 SameLoc = Standard_True;
441 // transform and trim the curves
443 TopoDS_Vertex V1f,V1l,V2f,V2l;
446 if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
447 Abs(l1 - C1->LastParameter()) > Precision::PConfusion() ) {
448 C1 = new Geom_TrimmedCurve(C1,f1,l1);
451 C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
454 C1->Transform(L1.Transformation());
456 if (Edge1.Orientation() == TopAbs_REVERSED) {
457 TopExp::Vertices(Edge1,V1l,V1f);
461 TopExp::Vertices(Edge1,V1f,V1l);
463 if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
464 Abs(l2 - C2->LastParameter()) > Precision::PConfusion() ) {
465 C2 = new Geom_TrimmedCurve(C2,f2,l2);
468 C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
471 C2->Transform(L2.Transformation());
473 if (Edge2.Orientation() == TopAbs_REVERSED) {
474 TopExp::Vertices(Edge2,V2l,V2f);
478 TopExp::Vertices(Edge2,V2f,V2l);
480 GeomFill_Generator Generator;
481 Generator.AddCurve( C1);
482 Generator.AddCurve( C2);
483 Generator.Perform( Precision::PConfusion());
485 Handle(Geom_Surface) Surf = Generator.Surface();
486 Handle(Geom_Curve) Iso;
488 B.MakeFace(Face,Surf,Precision::Confusion());
490 // make the missing edges
491 Surf->Bounds(f1,l1,f2,l2);
494 Iso = Surf->UIso(f1);
495 // Tol = Max(BT.Tolerance(V1f), BT.Tolerance(V2f));
496 Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
497 if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
498 B.MakeEdge(Edge3,Iso,Precision::Confusion());
502 B.Degenerated(Edge3, Standard_True);
504 V1f.Orientation(TopAbs_FORWARD);
506 V2f.Orientation(TopAbs_REVERSED);
508 B.Range(Edge3,f2,l2);
513 thefirst = Standard_False;
520 if ( Closed && !ex1.More() && !ex2.More() ) {
524 Iso = Surf->UIso(l1);
525 // Tol = Max(BT.Tolerance(V1l), BT.Tolerance(V2l));
526 Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
527 if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
528 B.MakeEdge(Edge4,Iso,Precision::Confusion());
532 B.Degenerated(Edge4, Standard_True);
534 V1l.Orientation(TopAbs_FORWARD);
536 V2l.Orientation(TopAbs_REVERSED);
538 B.Range(Edge4,f2,l2);
548 B.Add(W,Edge2.Reversed());
550 W.Closed (Standard_True);
554 if ( SameLoc) Face.Move( L);
560 Standard_Real T = Precision::Confusion();
562 if ( Edge1.Orientation() == TopAbs_REVERSED ) {
563 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),
565 B.Range(Edge1,Face,-l1,-f1);
568 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
570 B.Range(Edge1,Face,f1,l1);
573 if ( Edge2.Orientation() == TopAbs_REVERSED ) {
574 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),
576 B.Range(Edge2,Face,-l1,-f1);
579 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),
581 B.Range(Edge2,Face,f1,l1);
586 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
587 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),
591 B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
592 B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
595 // Set the non parameter flag;
596 B.SameParameter(Edge1,Standard_False);
597 B.SameParameter(Edge2,Standard_False);
598 B.SameParameter(Edge3,Standard_False);
599 B.SameParameter(Edge4,Standard_False);
600 B.SameRange(Edge1,Standard_False);
601 B.SameRange(Edge2,Standard_False);
602 B.SameRange(Edge3,Standard_False);
603 B.SameRange(Edge4,Standard_False);
606 Shell.Closed (BRep_Tool::IsClosed (Shell));
607 BRepLib::SameParameter(Shell);
611 //=======================================================================
614 //=======================================================================
616 void BRepFill::Axe (const TopoDS_Shape& Spine,
617 const TopoDS_Wire& Profile,
619 Standard_Boolean& ProfOnSpine,
620 const Standard_Real Tol)
622 gp_Pnt Loc,Loc1,Loc2;
623 gp_Vec Tang,Tang1,Tang2,Normal;
625 Handle(Geom_Surface) S;
630 // normal to the Spine.
631 if (Spine.ShapeType() == TopAbs_FACE) {
632 aFace = TopoDS::Face(Spine);
633 S = BRep_Tool::Surface(TopoDS::Face(Spine), L);
634 if ( !S->IsKind(STANDARD_TYPE(Geom_Plane))) {
635 BRepLib_FindSurface FS(TopoDS::Face(Spine), -1, Standard_True);
641 throw Standard_NoSuchObject("BRepFill_Evolved : The Face is not planar");
645 else if (Spine.ShapeType() == TopAbs_WIRE) {
646 aFace = BRepLib_MakeFace(TopoDS::Wire(Spine),Standard_True);
647 S = BRep_Tool::Surface(aFace, L);
650 if (S.IsNull()) throw Standard_DomainError("BRepFill_Evolved::Axe");
653 S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
655 Normal = Handle(Geom_Plane)::DownCast(S)->Pln().Axis().Direction();
657 // Find vertex of the profile closest to the spine.
658 Standard_Real DistMin = Precision::Infinite();
660 // Standard_Real Tol2 = Tol*Tol;
661 Standard_Real Tol2 = 1.e-10;
662 TopExp_Explorer PE, SE;
663 BRepExtrema_ExtPC BE;
664 Standard_Real Par =0.,f,l;
665 // Standard_Real D1,D2;
668 // First check if there is contact Vertex Vertex.
669 Standard_Boolean IsOnVertex = Standard_False;
670 SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
671 // modified by NIZHNY-EAP Wed Feb 23 12:31:52 2000 ___BEGIN___
672 // for (;SE.More() && !IsOnVertex ; SE.Next()) {
673 for (;SE.More(); SE.Next()) {
674 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SE.Current()));
676 PE.Init(Profile,TopAbs_VERTEX);
677 for ( ; PE.More(); PE.Next()) {
678 P2 = BRep_Tool::Pnt(TopoDS::Vertex(PE.Current()));
679 Standard_Real DistP1P2 = P1.SquareDistance(P2);
680 IsOnVertex = (DistP1P2 <= Tol2);
681 if (IsOnVertex) break;
683 // otherwise SE.Next() is done and VonF is wrong
684 if (IsOnVertex) break;
685 // modified by NIZHNY-EAP Wed Jan 26 09:08:36 2000 ___END___
689 // try to find on which edge which shared this vertex,
690 // the profile must be considered.
691 // E1, E2 : those two edges.
692 TopTools_IndexedDataMapOfShapeListOfShape Map;
693 TopExp::MapShapesAndAncestors(aFace.Oriented(TopAbs_FORWARD),
698 const TopoDS_Vertex& VonF = TopoDS::Vertex(SE.Current());
699 const TopTools_ListOfShape& List = Map.FindFromKey(VonF);
700 const TopoDS_Edge& E1 = TopoDS::Edge(List.First());
701 const TopoDS_Edge& E2 = TopoDS::Edge(List. Last());
703 Handle(Geom_Curve) CE1 = BRep_Tool::Curve(E1,L,f,l);
704 Standard_Real Par1 = BRep_Tool::Parameter(VonF,E1,aFace);
705 CE1->D1(Par1,Loc1,Tang1);
706 if (!L.IsIdentity()) {
707 Tang1.Transform(L.Transformation());
708 Loc1.Transform(L.Transformation());
710 if (E1.Orientation() == TopAbs_REVERSED) Tang1.Reverse();
712 Handle(Geom_Curve) CE2 = BRep_Tool::Curve(E2,L,f,l);
713 Standard_Real Par2 = BRep_Tool::Parameter(VonF,E2,aFace);
714 CE2->D1(Par2,Loc2,Tang2);
715 if (!L.IsIdentity()) {
716 Tang2.Transform(L.Transformation());
717 Loc2.Transform(L.Transformation());
719 if (E2.Orientation() == TopAbs_REVERSED) Tang2.Reverse();
721 // modified by NIZHNY-EAP Wed Feb 2 15:38:41 2000 ___BEGIN___
724 Standard_Real sca1=0., sca2=0.;
725 TopoDS_Vertex V1, V2;
727 for (PE.Init(Profile,TopAbs_EDGE); PE.More(); PE.Next()) {
728 E = TopoDS::Edge(PE.Current());
729 TopExp::Vertices(E, V1, V2);
730 P1 = BRep_Tool::Pnt(V1);
731 P2 = BRep_Tool::Pnt(V2);
733 sca1 += Abs(Tang1.Dot(vec));
734 sca2 += Abs(Tang2.Dot(vec));
736 // modified by NIZHNY-EAP Wed Feb 2 15:38:44 2000 ___END___
738 if ( Abs(sca1) < Abs(sca2)) {
749 SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
750 for ( ; SE.More(); SE.Next()) {
751 const TopoDS_Edge& E = TopoDS::Edge(SE.Current());
753 for (PE.Init(Profile,TopAbs_VERTEX) ; PE.More(); PE.Next()) {
754 Dist = Precision::Infinite();
755 const TopoDS_Vertex& V = TopoDS::Vertex(PE.Current());
759 for (Standard_Integer i = 1; i <= BE.NbExt(); i++) {
761 Dist = sqrt (BE.SquareDistance(i));
762 Par = BE.Parameter(i);
768 if (Dist < DistMin) {
770 BRepAdaptor_Curve BAC(E);
771 BAC.D1 (Par,Loc,Tang);
772 if (E.Orientation() == TopAbs_REVERSED) Tang.Reverse();
778 ProfOnSpine = (DistMin < Tol);
779 //Construction AxeProf;
780 gp_Ax3 A3 (Loc,Normal,Tang);
785 //=======================================================================
786 //function : SearchOrigin
787 //purpose : Cut and orientate a closed wire.
788 //=======================================================================
790 void BRepFill::SearchOrigin(TopoDS_Wire & W,
793 const Standard_Real Tol)
796 Standard_NoSuchObject::
797 Raise("BRepFill::SearchOrigin : the wire must be closed");
800 Standard_Boolean NewVertex = Standard_False;
801 Standard_Real theparam = 1.e101, angle;
805 // Class BRep_Tool without fields and without Constructor :
808 W.Orientation(TopAbs_FORWARD); //to avoid composing the orientations
810 // Calculate the distance
811 B.MakeVertex(V, P, Tol);
812 BRepExtrema_DistShapeShape DSS(V, W);
814 Standard_Integer isol = 1;
815 Standard_Real dss = P.Distance(DSS.PointOnShape2(isol));
816 for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++)
817 if (dss > P.Distance(DSS.PointOnShape2(iss))) {
818 dss = P.Distance(DSS.PointOnShape2(iss));
821 TopoDS_Shape supp = DSS.SupportOnShape2(isol);
822 if (DSS.SupportTypeShape2(isol)==BRepExtrema_IsVertex) {
823 V = TopoDS::Vertex(supp);
826 TopoDS_Vertex Vf, Vl;
827 Standard_Real d, dist;
828 E = TopoDS::Edge(supp);
829 TopExp::Vertices(E, Vf, Vl);
830 // dist = P.Distance(BT.Pnt(Vf));
831 dist = P.Distance(BRep_Tool::Pnt(Vf));
835 // d = P.Distance(BT.Pnt(Vl));
836 d = P.Distance(BRep_Tool::Pnt(Vl));
837 if ((d<Tol) && (d<dist)) {
841 NewVertex = (dist > Tol);
843 DSS.ParOnEdgeS2(isol, theparam);
849 std::cout << "BRepFill::SearchOrigine : Echec Distance" << std::endl;
853 Standard_Integer ii, rangdeb=0, NbEdges=0;
854 Standard_Boolean forward;
855 BRepTools_WireExplorer exp;
857 // Calculate the number of edges
858 for(exp.Init(W); exp.More(); exp.Next()) NbEdges++;
864 // Construct the Table and calculate rangdeb
865 TopTools_Array1OfShape Edges(1, NbEdges);
866 for(exp.Init(W), ii=1; exp.More(); exp.Next(), ii++) {
868 if (NewVertex && E.IsSame(Eref)) {
870 CutEdge(E, theparam, E1, E2, exp.CurrentVertex());
879 if (!NewVertex && V.IsSame(exp.CurrentVertex())) {
883 if (rangdeb == 0) rangdeb = NbEdges;
885 // Calculate the direction of parsing
886 E = TopoDS::Edge(Edges(rangdeb));
888 // theparam = BT.Parameter(V, E);
889 theparam = BRep_Tool::Parameter(V, E);
891 BRepAdaptor_Curve AC(E);
894 AC.D1(theparam, Pe, Ve);
895 if (E.Orientation()==TopAbs_REVERSED) {
898 angle = Ve.Angle(Dir);
899 if (angle > M_PI) angle = 2*M_PI - angle;
900 forward = (angle <= M_PI/2);
903 MakeWire( Edges, rangdeb, forward, W);
904 W.Closed(Standard_True);
909 //=======================================================================
910 //function : ComputeACR
912 //=======================================================================
914 void BRepFill::ComputeACR(const TopoDS_Wire& wire,
915 TColStd_Array1OfReal& ACR)
917 // calculate the reduced curvilinear abscisses and the length of the wire
918 BRepTools_WireExplorer anExp;
919 Standard_Integer nbEdges=0, i;
923 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
925 TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
926 ACR(nbEdges) = ACR(nbEdges-1);
927 if (!BRep_Tool::Degenerated(Ecur)) {
928 BRepAdaptor_Curve anEcur(Ecur);
929 ACR(nbEdges) += GCPnts_AbscissaPoint::Length(anEcur);
933 // total length of the wire
934 ACR(0) = ACR(nbEdges);
936 // reduced curvilinear abscisses
937 if (ACR(0)>Precision::Confusion()) {
938 for (i=1; i<=nbEdges; i++) {
949 //=======================================================================
950 //function : InsertACR
952 //=======================================================================
954 TopoDS_Wire BRepFill::InsertACR(const TopoDS_Wire& wire,
955 const TColStd_Array1OfReal& ACRcuts,
956 const Standard_Real prec)
958 // calculate ACR of the wire to be cut
959 BRepTools_WireExplorer anExp;
960 Standard_Integer nbEdges=0;
961 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
964 TColStd_Array1OfReal ACRwire(0,nbEdges);
965 ComputeACR(wire, ACRwire);
967 Standard_Integer i, j, nmax=ACRcuts.Length();
968 TColStd_Array1OfReal paradec(1,nmax);
971 Standard_Real t0,t1=0;
974 // processing edge by edge
975 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
978 t1 = ACRwire(nbEdges);
980 // parameters of cut on this edge
981 Standard_Integer ndec=0;
982 for (i=1; i<=ACRcuts.Length(); i++ ) {
983 if (t0+prec<ACRcuts(i) && ACRcuts(i)<t1-prec) {
985 paradec(ndec) = ACRcuts(i);
989 const TopoDS_Edge& E = anExp.Current();
990 const TopoDS_Vertex& V = anExp.CurrentVertex();
992 if (ndec==0 || BRep_Tool::Degenerated(E)) {
997 // it is necessary to cut the edge
998 // following the direction of parsing of the wire
999 Standard_Boolean SO = (V.IsSame(TopExp::FirstVertex(E)));
1000 TopTools_SequenceOfShape SE;
1002 TColStd_SequenceOfReal SR;
1004 // the wire is always FORWARD
1005 // it is necessary to modify the parameter of cut6 if the edge is REVERSED
1006 if (E.Orientation() == TopAbs_FORWARD) {
1007 for (j=1; j<=ndec; j++) SR.Append(paradec(j));
1010 for (j=1; j<=ndec; j++) SR.Append(t0+t1-paradec(ndec+1-j));
1012 TrimEdge(E,SR,t0,t1,SO,SE);
1013 for (j=1; j<=SE.Length(); j++) {
1014 MW.Add(TopoDS::Edge(SE.Value(j)));
1020 TopAbs_Orientation Orien = wire.Orientation();
1021 TopoDS_Shape aLocalShape = MW.Wire();
1022 aLocalShape.Orientation(Orien);
1023 TopoDS_Wire wres = TopoDS::Wire(aLocalShape);
1024 // TopoDS_Wire wres = TopoDS::Wire(MW.Wire().Oriented(Orien));