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 <BRep_Builder.hxx>
38 #include <BRep_Tool.hxx>
39 #include <BRepAdaptor_Curve.hxx>
40 #include <BRepExtrema_DistShapeShape.hxx>
41 #include <BRepExtrema_ExtPC.hxx>
42 #include <BRepFill.hxx>
43 #include <BRepGProp.hxx>
44 #include <BRepLib.hxx>
45 #include <BRepLib_FindSurface.hxx>
46 #include <BRepLib_MakeEdge.hxx>
47 #include <BRepLib_MakeFace.hxx>
48 #include <BRepLib_MakeVertex.hxx>
49 #include <BRepLib_MakeWire.hxx>
50 #include <BRepLProp.hxx>
51 #include <BRepTools_WireExplorer.hxx>
52 #include <GCPnts_AbscissaPoint.hxx>
53 #include <Geom2d_Line.hxx>
54 #include <Geom_Curve.hxx>
55 #include <Geom_Plane.hxx>
56 #include <Geom_Surface.hxx>
57 #include <Geom_TrimmedCurve.hxx>
58 #include <GeomAdaptor_Curve.hxx>
59 #include <GeomFill_Generator.hxx>
61 #include <gp_Circ.hxx>
63 #include <gp_Dir2d.hxx>
64 #include <gp_Elips.hxx>
68 #include <gp_Pnt2d.hxx>
70 #include <GProp_GProps.hxx>
71 #include <GProp_PrincipalProps.hxx>
72 #include <Precision.hxx>
73 #include <Standard_NoSuchObject.hxx>
74 #include <TColStd_Array1OfInteger.hxx>
76 #include <TopExp_Explorer.hxx>
77 #include <TopLoc_Location.hxx>
79 #include <TopoDS_Edge.hxx>
80 #include <TopoDS_Face.hxx>
81 #include <TopoDS_Shape.hxx>
82 #include <TopoDS_Shell.hxx>
83 #include <TopoDS_Vertex.hxx>
84 #include <TopoDS_Wire.hxx>
85 #include <TopTools_Array1OfShape.hxx>
86 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
87 #include <TopTools_DataMapOfShapeListOfShape.hxx>
88 #include <TopTools_HSequenceOfShape.hxx>
89 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
90 #include <TopTools_IndexedMapOfShape.hxx>
91 #include <TopTools_ListIteratorOfListOfShape.hxx>
92 #include <TopTools_ListOfShape.hxx>
93 #include <TopTools_SequenceOfShape.hxx>
95 static void MakeWire(const TopTools_Array1OfShape& Edges,
96 const Standard_Integer rangdeb,
97 const Standard_Boolean forward,
101 Standard_Integer rang, nbEdges = Edges.Length();
102 BW.MakeWire(newwire);
104 for (rang=rangdeb;rang<=nbEdges;rang++) {
105 BW.Add(newwire,TopoDS::Edge(Edges(rang)));
107 for (rang=1;rang<rangdeb;rang++) {
108 BW.Add(newwire,TopoDS::Edge(Edges(rang)));
114 for (rang=rangdeb;rang>=1;rang--) {
115 E = TopoDS::Edge(Edges(rang));
116 BW.Add(newwire,E.Reversed());
118 for (rang=nbEdges;rang>rangdeb;rang--) {
119 E = TopoDS::Edge(Edges(rang));
120 BW.Add(newwire, E.Reversed());
123 newwire.Orientation(TopAbs_FORWARD);
124 newwire.Closed (Standard_True);
127 static void CutEdge(const TopoDS_Edge& CurrentEdge,
128 const Standard_Real& Param,
131 const TopoDS_Vertex& VRef)
134 Standard_Real first,last;
135 Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
136 TopoDS_Vertex Vf, Vl, Vi;
137 B.MakeVertex(Vi, C->Value(Param), Precision::Confusion());
138 TopExp::Vertices(CurrentEdge, Vf, Vl);
139 if (VRef.IsSame(Vf)) {
140 E1 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
141 E2 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);
144 E2 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
145 E1 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);
150 static void TrimEdge (const TopoDS_Edge& CurrentEdge,
151 const TColStd_SequenceOfReal& CutValues,
152 const Standard_Real t0, const Standard_Real t1,
153 const Standard_Boolean SeqOrder,
154 TopTools_SequenceOfShape& S)
158 Standard_Integer j, ndec=CutValues.Length();
159 Standard_Real first,last,m0,m1;
160 Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
162 TopoDS_Vertex Vf,Vl,Vbid,V0,V1;
163 TopAbs_Orientation CurrentOrient = CurrentEdge.Orientation();
164 TopExp::Vertices(CurrentEdge,Vf,Vl);
168 // from first to last
171 for (j=1; j<=ndec; j++) {
173 m1 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
174 TopoDS_Edge CutE = BRepLib_MakeEdge(C,V0,Vbid,m0,m1);
175 CutE.Orientation(CurrentOrient);
178 V0 = TopExp::LastVertex(CutE);
181 TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
182 LastE.Orientation(CurrentOrient);
188 // from last to first
191 for (j=ndec; j>=1; j--) {
193 m0 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
194 TopoDS_Edge CutE = BRepLib_MakeEdge(C,Vbid,V1,m0,m1);
195 CutE.Orientation(CurrentOrient);
198 V1 = TopExp::FirstVertex(CutE);
201 TopoDS_Edge LastE = BRepLib_MakeEdge(C,Vf,V1,first,m1);
202 LastE.Orientation(CurrentOrient);
210 //=======================================================================
213 //=======================================================================
215 TopoDS_Face BRepFill::Face(const TopoDS_Edge& Edge1,
216 const TopoDS_Edge& Edge2 )
221 // Class BRep_Tool without fields and without Constructor :
224 TopLoc_Location L,L1,L2;
225 Standard_Real f1,f2,l1,l2, Tol;
227 // Handle(Geom_Curve) C1 = BT.Curve(Edge1,L1,f1,l1);
228 Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
229 // Handle(Geom_Curve) C2 = BT.Curve(Edge2,L2,f2,l2);
230 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
232 // compute the location
233 Standard_Boolean SameLoc = Standard_False;
236 L1 = L2 = TopLoc_Location();
237 SameLoc = Standard_True;
240 // transform and trim the curves
242 TopoDS_Vertex V1f,V1l,V2f,V2l;
244 // create a new Handle
245 if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
246 Abs(l1 - C1->LastParameter()) > Precision::PConfusion() ) {
247 C1 = new Geom_TrimmedCurve(C1,f1,l1);
250 C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
252 // eventually the curve is concerned
254 C1->Transform(L1.Transformation());
256 // it is set in the proper direction and its vertices are taken
257 if (Edge1.Orientation() == TopAbs_REVERSED) {
258 TopExp::Vertices(Edge1,V1l,V1f);
262 TopExp::Vertices(Edge1,V1f,V1l);
265 // a new Handle is created
266 if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
267 Abs(l2 - C2->LastParameter()) > Precision::PConfusion() ) {
268 C2 = new Geom_TrimmedCurve(C2,f2,l2);
271 C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
273 // eventually the curve is concerned
275 C2->Transform(L2.Transformation());
277 // it is set in the proper direction and its vertices are taken
278 if (Edge2.Orientation() == TopAbs_REVERSED) {
279 TopExp::Vertices(Edge2,V2l,V2f);
283 TopExp::Vertices(Edge2,V2f,V2l);
286 // Are they closed edges?
287 Standard_Boolean Closed = V1f.IsSame(V1l) && V2f.IsSame(V2l);
290 GeomFill_Generator Generator;
291 Generator.AddCurve( C1);
292 Generator.AddCurve( C2);
293 Generator.Perform( Precision::PConfusion());
295 Handle(Geom_Surface) Surf = Generator.Surface();
296 Handle(Geom_Curve) Iso;
298 B.MakeFace(Face,Surf,Precision::Confusion());
300 // make the missing edges
301 Surf->Bounds(f1,l1,f2,l2);
303 TopoDS_Edge Edge3, Edge4;
305 Iso = Surf->UIso(f1);
306 Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
307 if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
308 B.MakeEdge(Edge3,Iso,Precision::Confusion());
312 B.Degenerated(Edge3, Standard_True);
314 V1f.Orientation(TopAbs_FORWARD);
316 V2f.Orientation(TopAbs_REVERSED);
318 B.Range(Edge3,f2,l2);
324 Iso = Surf->UIso(l1);
325 Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
326 if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
327 B.MakeEdge(Edge4,Iso,Precision::Confusion());
331 B.Degenerated(Edge4, Standard_True);
333 V1l.Orientation(TopAbs_FORWARD);
335 V2l.Orientation(TopAbs_REVERSED);
337 B.Range(Edge4,f2,l2);
348 B.Add(W,Edge2.Reversed());
350 W.Closed (Standard_True);
356 Standard_Real T = Precision::Confusion();
358 if ( Edge1.Orientation() == TopAbs_REVERSED ) {
359 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),Face,T);
360 B.Range(Edge1,Face,-l1,-f1);
363 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),Face,T);
364 B.Range(Edge1,Face,f1,l1);
367 if ( Edge2.Orientation() == TopAbs_REVERSED ) {
368 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),Face,T);
369 B.Range(Edge2,Face,-l1,-f1);
372 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),Face,T);
373 B.Range(Edge2,Face,f1,l1);
378 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
379 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
382 B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
383 B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
386 // Set the non parameter flag;
387 B.SameParameter(Edge1,Standard_False);
388 B.SameParameter(Edge2,Standard_False);
389 B.SameParameter(Edge3,Standard_False);
390 B.SameParameter(Edge4,Standard_False);
391 B.SameRange(Edge1,Standard_False);
392 B.SameRange(Edge2,Standard_False);
393 B.SameRange(Edge3,Standard_False);
394 B.SameRange(Edge4,Standard_False);
396 BRepLib::SameParameter(Face);
398 if ( SameLoc) Face.Move(L);
403 //=======================================================================
406 //=======================================================================
408 TopoDS_Shell BRepFill::Shell(const TopoDS_Wire& Wire1,
409 const TopoDS_Wire& Wire2 )
414 TopoDS_Edge Edge1, Edge2, Edge3, Edge4, Couture;
417 // Class BRep_Tool without fields and without Constructor :
424 Standard_Boolean Closed = Wire1.Closed() && Wire2.Closed();
426 Standard_Boolean thefirst = Standard_True;
428 ex1.Init(Wire1,TopAbs_EDGE);
429 ex2.Init(Wire2,TopAbs_EDGE);
431 while ( ex1.More() && ex2.More() ) {
433 Edge1 = TopoDS::Edge(ex1.Current());
434 Edge2 = TopoDS::Edge(ex2.Current());
436 Standard_Boolean Periodic =
437 BRep_Tool::IsClosed(Edge1) && BRep_Tool::IsClosed(Edge2);
442 TopLoc_Location L,L1,L2;
443 Standard_Real f1,l1,f2,l2,Tol;
445 Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
446 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
448 // compute the location
449 Standard_Boolean SameLoc = Standard_False;
452 L1 = L2 = TopLoc_Location();
453 SameLoc = Standard_True;
456 // transform and trim the curves
458 TopoDS_Vertex V1f,V1l,V2f,V2l;
461 if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
462 Abs(l1 - C1->LastParameter()) > Precision::PConfusion() ) {
463 C1 = new Geom_TrimmedCurve(C1,f1,l1);
466 C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
469 C1->Transform(L1.Transformation());
471 if (Edge1.Orientation() == TopAbs_REVERSED) {
472 TopExp::Vertices(Edge1,V1l,V1f);
476 TopExp::Vertices(Edge1,V1f,V1l);
478 if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
479 Abs(l2 - C2->LastParameter()) > Precision::PConfusion() ) {
480 C2 = new Geom_TrimmedCurve(C2,f2,l2);
483 C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
486 C2->Transform(L2.Transformation());
488 if (Edge2.Orientation() == TopAbs_REVERSED) {
489 TopExp::Vertices(Edge2,V2l,V2f);
493 TopExp::Vertices(Edge2,V2f,V2l);
495 GeomFill_Generator Generator;
496 Generator.AddCurve( C1);
497 Generator.AddCurve( C2);
498 Generator.Perform( Precision::PConfusion());
500 Handle(Geom_Surface) Surf = Generator.Surface();
501 Handle(Geom_Curve) Iso;
503 B.MakeFace(Face,Surf,Precision::Confusion());
505 // make the missing edges
506 Surf->Bounds(f1,l1,f2,l2);
509 Iso = Surf->UIso(f1);
510 // Tol = Max(BT.Tolerance(V1f), BT.Tolerance(V2f));
511 Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
512 if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
513 B.MakeEdge(Edge3,Iso,Precision::Confusion());
517 B.Degenerated(Edge3, Standard_True);
519 V1f.Orientation(TopAbs_FORWARD);
521 V2f.Orientation(TopAbs_REVERSED);
523 B.Range(Edge3,f2,l2);
528 thefirst = Standard_False;
535 if ( Closed && !ex1.More() && !ex2.More() ) {
539 Iso = Surf->UIso(l1);
540 // Tol = Max(BT.Tolerance(V1l), BT.Tolerance(V2l));
541 Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
542 if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
543 B.MakeEdge(Edge4,Iso,Precision::Confusion());
547 B.Degenerated(Edge4, Standard_True);
549 V1l.Orientation(TopAbs_FORWARD);
551 V2l.Orientation(TopAbs_REVERSED);
553 B.Range(Edge4,f2,l2);
563 B.Add(W,Edge2.Reversed());
565 W.Closed (Standard_True);
569 if ( SameLoc) Face.Move( L);
575 Standard_Real T = Precision::Confusion();
577 if ( Edge1.Orientation() == TopAbs_REVERSED ) {
578 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),
580 B.Range(Edge1,Face,-l1,-f1);
583 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
585 B.Range(Edge1,Face,f1,l1);
588 if ( Edge2.Orientation() == TopAbs_REVERSED ) {
589 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),
591 B.Range(Edge2,Face,-l1,-f1);
594 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),
596 B.Range(Edge2,Face,f1,l1);
601 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
602 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),
606 B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
607 B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
610 // Set the non parameter flag;
611 B.SameParameter(Edge1,Standard_False);
612 B.SameParameter(Edge2,Standard_False);
613 B.SameParameter(Edge3,Standard_False);
614 B.SameParameter(Edge4,Standard_False);
615 B.SameRange(Edge1,Standard_False);
616 B.SameRange(Edge2,Standard_False);
617 B.SameRange(Edge3,Standard_False);
618 B.SameRange(Edge4,Standard_False);
621 Shell.Closed (BRep_Tool::IsClosed (Shell));
622 BRepLib::SameParameter(Shell);
626 //=======================================================================
629 //=======================================================================
631 void BRepFill::Axe (const TopoDS_Shape& Spine,
632 const TopoDS_Wire& Profile,
634 Standard_Boolean& ProfOnSpine,
635 const Standard_Real Tol)
637 gp_Pnt Loc,Loc1,Loc2;
638 gp_Vec Tang,Tang1,Tang2,Normal;
640 Handle(Geom_Surface) S;
645 // normal to the Spine.
646 if (Spine.ShapeType() == TopAbs_FACE) {
647 aFace = TopoDS::Face(Spine);
648 S = BRep_Tool::Surface(TopoDS::Face(Spine), L);
649 if ( !S->IsKind(STANDARD_TYPE(Geom_Plane))) {
650 BRepLib_FindSurface FS(TopoDS::Face(Spine), -1, Standard_True);
656 throw Standard_NoSuchObject("BRepFill_Evolved : The Face is not planar");
660 else if (Spine.ShapeType() == TopAbs_WIRE) {
661 aFace = BRepLib_MakeFace(TopoDS::Wire(Spine),Standard_True);
662 S = BRep_Tool::Surface(aFace, L);
665 if (S.IsNull()) throw Standard_DomainError("BRepFill_Evolved::Axe");
668 S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
670 Normal = Handle(Geom_Plane)::DownCast(S)->Pln().Axis().Direction();
672 // Find vertex of the profile closest to the spine.
673 Standard_Real DistMin = Precision::Infinite();
675 // Standard_Real Tol2 = Tol*Tol;
676 Standard_Real Tol2 = 1.e-10;
677 TopExp_Explorer PE, SE;
678 BRepExtrema_ExtPC BE;
679 Standard_Real Par =0.,f,l;
680 // Standard_Real D1,D2;
683 // First check if there is contact Vertex Vertex.
684 Standard_Boolean IsOnVertex = Standard_False;
685 SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
686 // modified by NIZHNY-EAP Wed Feb 23 12:31:52 2000 ___BEGIN___
687 // for (;SE.More() && !IsOnVertex ; SE.Next()) {
688 for (;SE.More(); SE.Next()) {
689 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SE.Current()));
691 PE.Init(Profile,TopAbs_VERTEX);
692 for ( ; PE.More(); PE.Next()) {
693 P2 = BRep_Tool::Pnt(TopoDS::Vertex(PE.Current()));
694 Standard_Real DistP1P2 = P1.SquareDistance(P2);
695 IsOnVertex = (DistP1P2 <= Tol2);
696 if (IsOnVertex) break;
698 // otherwise SE.Next() is done and VonF is wrong
699 if (IsOnVertex) break;
700 // modified by NIZHNY-EAP Wed Jan 26 09:08:36 2000 ___END___
704 // try to find on which edge which shared this vertex,
705 // the profile must be considered.
706 // E1, E2 : those two edges.
707 TopTools_IndexedDataMapOfShapeListOfShape Map;
708 TopExp::MapShapesAndAncestors(aFace.Oriented(TopAbs_FORWARD),
713 const TopoDS_Vertex& VonF = TopoDS::Vertex(SE.Current());
714 const TopTools_ListOfShape& List = Map.FindFromKey(VonF);
715 const TopoDS_Edge& E1 = TopoDS::Edge(List.First());
716 const TopoDS_Edge& E2 = TopoDS::Edge(List. Last());
718 Handle(Geom_Curve) CE1 = BRep_Tool::Curve(E1,L,f,l);
719 Standard_Real Par1 = BRep_Tool::Parameter(VonF,E1,aFace);
720 CE1->D1(Par1,Loc1,Tang1);
721 if (!L.IsIdentity()) {
722 Tang1.Transform(L.Transformation());
723 Loc1.Transform(L.Transformation());
725 if (E1.Orientation() == TopAbs_REVERSED) Tang1.Reverse();
727 Handle(Geom_Curve) CE2 = BRep_Tool::Curve(E2,L,f,l);
728 Standard_Real Par2 = BRep_Tool::Parameter(VonF,E2,aFace);
729 CE2->D1(Par2,Loc2,Tang2);
730 if (!L.IsIdentity()) {
731 Tang2.Transform(L.Transformation());
732 Loc2.Transform(L.Transformation());
734 if (E2.Orientation() == TopAbs_REVERSED) Tang2.Reverse();
736 // modified by NIZHNY-EAP Wed Feb 2 15:38:41 2000 ___BEGIN___
739 Standard_Real sca1=0., sca2=0.;
740 TopoDS_Vertex V1, V2;
742 for (PE.Init(Profile,TopAbs_EDGE); PE.More(); PE.Next()) {
743 E = TopoDS::Edge(PE.Current());
744 TopExp::Vertices(E, V1, V2);
745 P1 = BRep_Tool::Pnt(V1);
746 P2 = BRep_Tool::Pnt(V2);
748 sca1 += Abs(Tang1.Dot(vec));
749 sca2 += Abs(Tang2.Dot(vec));
751 // modified by NIZHNY-EAP Wed Feb 2 15:38:44 2000 ___END___
753 if ( Abs(sca1) < Abs(sca2)) {
764 SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
765 for ( ; SE.More(); SE.Next()) {
766 const TopoDS_Edge& E = TopoDS::Edge(SE.Current());
768 for (PE.Init(Profile,TopAbs_VERTEX) ; PE.More(); PE.Next()) {
769 Dist = Precision::Infinite();
770 const TopoDS_Vertex& V = TopoDS::Vertex(PE.Current());
774 for (Standard_Integer i = 1; i <= BE.NbExt(); i++) {
776 Dist = sqrt (BE.SquareDistance(i));
777 Par = BE.Parameter(i);
783 if (Dist < DistMin) {
785 BRepAdaptor_Curve BAC(E);
786 BAC.D1 (Par,Loc,Tang);
787 if (E.Orientation() == TopAbs_REVERSED) Tang.Reverse();
793 ProfOnSpine = (DistMin < Tol);
794 //Construction AxeProf;
795 gp_Ax3 A3 (Loc,Normal,Tang);
800 //=======================================================================
801 //function : SearchOrigin
802 //purpose : Cut and orientate a closed wire.
803 //=======================================================================
805 void BRepFill::SearchOrigin(TopoDS_Wire & W,
808 const Standard_Real Tol)
811 Standard_NoSuchObject::
812 Raise("BRepFill::SearchOrigin : the wire must be closed");
815 Standard_Boolean NewVertex = Standard_False;
816 Standard_Real theparam = 1.e101, angle;
820 // Class BRep_Tool without fields and without Constructor :
823 W.Orientation(TopAbs_FORWARD); //to avoid composing the orientations
825 // Calculate the distance
826 B.MakeVertex(V, P, Tol);
827 BRepExtrema_DistShapeShape DSS(V, W);
829 Standard_Integer isol = 1;
830 Standard_Real dss = P.Distance(DSS.PointOnShape2(isol));
831 for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++)
832 if (dss > P.Distance(DSS.PointOnShape2(iss))) {
833 dss = P.Distance(DSS.PointOnShape2(iss));
836 TopoDS_Shape supp = DSS.SupportOnShape2(isol);
837 if (DSS.SupportTypeShape2(isol)==BRepExtrema_IsVertex) {
838 V = TopoDS::Vertex(supp);
841 TopoDS_Vertex Vf, Vl;
842 Standard_Real d, dist;
843 E = TopoDS::Edge(supp);
844 TopExp::Vertices(E, Vf, Vl);
845 // dist = P.Distance(BT.Pnt(Vf));
846 dist = P.Distance(BRep_Tool::Pnt(Vf));
850 // d = P.Distance(BT.Pnt(Vl));
851 d = P.Distance(BRep_Tool::Pnt(Vl));
852 if ((d<Tol) && (d<dist)) {
856 NewVertex = (dist > Tol);
858 DSS.ParOnEdgeS2(isol, theparam);
864 cout << "BRepFill::SearchOrigine : Echec Distance" << endl;
868 Standard_Integer ii, rangdeb=0, NbEdges=0;
869 Standard_Boolean forward;
870 BRepTools_WireExplorer exp;
872 // Calculate the number of edges
873 for(exp.Init(W); exp.More(); exp.Next()) NbEdges++;
879 // Construct the Table and calculate rangdeb
880 TopTools_Array1OfShape Edges(1, NbEdges);
881 for(exp.Init(W), ii=1; exp.More(); exp.Next(), ii++) {
883 if (NewVertex && E.IsSame(Eref)) {
885 CutEdge(E, theparam, E1, E2, exp.CurrentVertex());
894 if (!NewVertex && V.IsSame(exp.CurrentVertex())) {
898 if (rangdeb == 0) rangdeb = NbEdges;
900 // Calculate the direction of parsing
901 E = TopoDS::Edge(Edges(rangdeb));
903 // theparam = BT.Parameter(V, E);
904 theparam = BRep_Tool::Parameter(V, E);
906 BRepAdaptor_Curve AC(E);
909 AC.D1(theparam, Pe, Ve);
910 if (E.Orientation()==TopAbs_REVERSED) {
913 angle = Ve.Angle(Dir);
914 if (angle > M_PI) angle = 2*M_PI - angle;
915 forward = (angle <= M_PI/2);
918 MakeWire( Edges, rangdeb, forward, W);
919 W.Closed(Standard_True);
924 //=======================================================================
925 //function : ComputeACR
927 //=======================================================================
929 void BRepFill::ComputeACR(const TopoDS_Wire& wire,
930 TColStd_Array1OfReal& ACR)
932 // calculate the reduced curvilinear abscisses and the length of the wire
933 BRepTools_WireExplorer anExp;
934 Standard_Integer nbEdges=0, i;
938 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
940 TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
941 ACR(nbEdges) = ACR(nbEdges-1);
942 if (!BRep_Tool::Degenerated(Ecur)) {
943 BRepAdaptor_Curve anEcur(Ecur);
944 ACR(nbEdges) += GCPnts_AbscissaPoint::Length(anEcur);
948 // total length of the wire
949 ACR(0) = ACR(nbEdges);
951 // reduced curvilinear abscisses
952 if (ACR(0)>Precision::Confusion()) {
953 for (i=1; i<=nbEdges; i++) {
964 //=======================================================================
965 //function : InsertACR
967 //=======================================================================
969 TopoDS_Wire BRepFill::InsertACR(const TopoDS_Wire& wire,
970 const TColStd_Array1OfReal& ACRcuts,
971 const Standard_Real prec)
973 // calculate ACR of the wire to be cut
974 BRepTools_WireExplorer anExp;
975 Standard_Integer nbEdges=0;
976 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
979 TColStd_Array1OfReal ACRwire(0,nbEdges);
980 ComputeACR(wire, ACRwire);
982 Standard_Integer i, j, nmax=ACRcuts.Length();
983 TColStd_Array1OfReal paradec(1,nmax);
986 Standard_Real t0,t1=0;
989 // processing edge by edge
990 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
993 t1 = ACRwire(nbEdges);
995 // parameters of cut on this edge
996 Standard_Integer ndec=0;
997 for (i=1; i<=ACRcuts.Length(); i++ ) {
998 if (t0+prec<ACRcuts(i) && ACRcuts(i)<t1-prec) {
1000 paradec(ndec) = ACRcuts(i);
1004 TopoDS_Edge E = anExp.Current();
1005 TopoDS_Vertex V = anExp.CurrentVertex();
1007 if (ndec==0 || BRep_Tool::Degenerated(E)) {
1012 // it is necessary to cut the edge
1013 // following the direction of parsing of the wire
1014 Standard_Boolean SO = (V.IsSame(TopExp::FirstVertex(E)));
1015 TopTools_SequenceOfShape SE;
1017 TColStd_SequenceOfReal SR;
1019 // the wire is always FORWARD
1020 // it is necesary to modify the parameter of cut6 if the edge is REVERSED
1021 if (E.Orientation() == TopAbs_FORWARD) {
1022 for (j=1; j<=ndec; j++) SR.Append(paradec(j));
1025 for (j=1; j<=ndec; j++) SR.Append(t0+t1-paradec(ndec+1-j));
1027 TrimEdge(E,SR,t0,t1,SO,SE);
1028 for (j=1; j<=SE.Length(); j++) {
1029 MW.Add(TopoDS::Edge(SE.Value(j)));
1035 TopAbs_Orientation Orien = wire.Orientation();
1036 TopoDS_Shape aLocalShape = MW.Wire();
1037 aLocalShape.Orientation(Orien);
1038 TopoDS_Wire wres = TopoDS::Wire(aLocalShape);
1039 // TopoDS_Wire wres = TopoDS::Wire(MW.Wire().Oriented(Orien));