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.ixx>
39 #include <BRepLib.hxx>
40 #include <BRepLib_FindSurface.hxx>
41 #include <BRepLib_MakeFace.hxx>
42 #include <BRepLib_MakeEdge.hxx>
43 #include <BRepLib_MakeVertex.hxx>
44 #include <BRepLib_MakeWire.hxx>
45 #include <BRepExtrema_ExtPC.hxx>
46 #include <BRepExtrema_DistShapeShape.hxx>
47 #include <BRep_Tool.hxx>
48 #include <BRepTools_WireExplorer.hxx>
50 #include <TopoDS_Face.hxx>
51 #include <TopoDS_Wire.hxx>
52 #include <TopoDS_Vertex.hxx>
53 #include <BRep_Builder.hxx>
54 #include <TopLoc_Location.hxx>
55 #include <TopExp_Explorer.hxx>
59 #include <gp_Pnt2d.hxx>
61 #include <gp_Dir2d.hxx>
62 #include <gp_Circ.hxx>
63 #include <gp_Elips.hxx>
64 #include <Geom_Curve.hxx>
65 #include <Geom_TrimmedCurve.hxx>
66 #include <Geom_Surface.hxx>
67 #include <Geom_Plane.hxx>
68 #include <Geom2d_Line.hxx>
69 #include <GeomFill_Generator.hxx>
70 #include <GeomAdaptor_Curve.hxx>
71 #include <BRepLProp.hxx>
72 #include <BRepGProp.hxx>
73 #include <GProp_GProps.hxx>
74 #include <GProp_PrincipalProps.hxx>
75 #include <GCPnts_AbscissaPoint.hxx>
76 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
77 #include <TopTools_DataMapOfShapeListOfShape.hxx>
78 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
79 #include <TopTools_ListIteratorOfListOfShape.hxx>
80 #include <TopTools_ListOfShape.hxx>
81 #include <TopTools_Array1OfShape.hxx>
82 #include <TopTools_SequenceOfShape.hxx>
83 #include <TopTools_HSequenceOfShape.hxx>
84 #include <BRepAdaptor_Curve.hxx>
85 #include <TopTools_IndexedMapOfShape.hxx>
87 #include <BRep_Tool.hxx>
90 #include <Precision.hxx>
92 #include <TColStd_Array1OfInteger.hxx>
93 #include <Standard_NoSuchObject.hxx>
96 static void MakeWire(const TopTools_Array1OfShape& Edges,
97 const Standard_Integer rangdeb,
98 const Standard_Boolean forward,
102 Standard_Integer rang, nbEdges = Edges.Length();
103 BW.MakeWire(newwire);
105 for (rang=rangdeb;rang<=nbEdges;rang++) {
106 BW.Add(newwire,TopoDS::Edge(Edges(rang)));
108 for (rang=1;rang<rangdeb;rang++) {
109 BW.Add(newwire,TopoDS::Edge(Edges(rang)));
115 for (rang=rangdeb;rang>=1;rang--) {
116 E = TopoDS::Edge(Edges(rang));
117 BW.Add(newwire,E.Reversed());
119 for (rang=nbEdges;rang>rangdeb;rang--) {
120 E = TopoDS::Edge(Edges(rang));
121 BW.Add(newwire, E.Reversed());
124 newwire.Orientation(TopAbs_FORWARD);
125 newwire.Closed (Standard_True);
128 static void CutEdge(const TopoDS_Edge& CurrentEdge,
129 const Standard_Real& Param,
132 const TopoDS_Vertex& VRef)
135 Standard_Real first,last;
136 Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
137 TopoDS_Vertex Vf, Vl, Vi;
138 B.MakeVertex(Vi, C->Value(Param), Precision::Confusion());
139 TopExp::Vertices(CurrentEdge, Vf, Vl);
140 if (VRef.IsSame(Vf)) {
141 E1 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
142 E2 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);
145 E2 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
146 E1 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);
151 static void TrimEdge (const TopoDS_Edge& CurrentEdge,
152 const TColStd_SequenceOfReal& CutValues,
153 const Standard_Real t0, const Standard_Real t1,
154 const Standard_Boolean SeqOrder,
155 TopTools_SequenceOfShape& S)
159 Standard_Integer j, ndec=CutValues.Length();
160 Standard_Real first,last,m0,m1;
161 Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
163 TopoDS_Vertex Vf,Vl,Vbid,V0,V1;
164 TopAbs_Orientation CurrentOrient = CurrentEdge.Orientation();
165 TopExp::Vertices(CurrentEdge,Vf,Vl);
169 // from first to last
172 for (j=1; j<=ndec; j++) {
174 m1 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
175 TopoDS_Edge CutE = BRepLib_MakeEdge(C,V0,Vbid,m0,m1);
176 CutE.Orientation(CurrentOrient);
179 V0 = TopExp::LastVertex(CutE);
182 TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
183 LastE.Orientation(CurrentOrient);
189 // from last to first
192 for (j=ndec; j>=1; j--) {
194 m0 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
195 TopoDS_Edge CutE = BRepLib_MakeEdge(C,Vbid,V1,m0,m1);
196 CutE.Orientation(CurrentOrient);
199 V1 = TopExp::FirstVertex(CutE);
202 TopoDS_Edge LastE = BRepLib_MakeEdge(C,Vf,V1,first,m1);
203 LastE.Orientation(CurrentOrient);
211 //=======================================================================
214 //=======================================================================
216 TopoDS_Face BRepFill::Face(const TopoDS_Edge& Edge1,
217 const TopoDS_Edge& Edge2 )
222 // Class BRep_Tool without fields and without Constructor :
225 TopLoc_Location L,L1,L2;
226 Standard_Real f1,f2,l1,l2, Tol;
228 // Handle(Geom_Curve) C1 = BT.Curve(Edge1,L1,f1,l1);
229 Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
230 // Handle(Geom_Curve) C2 = BT.Curve(Edge2,L2,f2,l2);
231 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
233 // compute the location
234 Standard_Boolean SameLoc = Standard_False;
237 L1 = L2 = TopLoc_Location();
238 SameLoc = Standard_True;
241 // transform and trim the curves
243 TopoDS_Vertex V1f,V1l,V2f,V2l;
245 // create a new Handle
246 if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
247 Abs(l1 - C1->LastParameter()) > Precision::PConfusion() ) {
248 C1 = new Geom_TrimmedCurve(C1,f1,l1);
251 C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
253 // eventually the curve is concerned
255 C1->Transform(L1.Transformation());
257 // it is set in the proper direction and its vertices are taken
258 if (Edge1.Orientation() == TopAbs_REVERSED) {
259 TopExp::Vertices(Edge1,V1l,V1f);
263 TopExp::Vertices(Edge1,V1f,V1l);
266 // a new Handle is created
267 if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
268 Abs(l2 - C2->LastParameter()) > Precision::PConfusion() ) {
269 C2 = new Geom_TrimmedCurve(C2,f2,l2);
272 C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
274 // eventually the curve is concerned
276 C2->Transform(L2.Transformation());
278 // it is set in the proper direction and its vertices are taken
279 if (Edge2.Orientation() == TopAbs_REVERSED) {
280 TopExp::Vertices(Edge2,V2l,V2f);
284 TopExp::Vertices(Edge2,V2f,V2l);
287 // Are they closed edges?
288 Standard_Boolean Closed = V1f.IsSame(V1l) && V2f.IsSame(V2l);
291 GeomFill_Generator Generator;
292 Generator.AddCurve( C1);
293 Generator.AddCurve( C2);
294 Generator.Perform( Precision::PConfusion());
296 Handle(Geom_Surface) Surf = Generator.Surface();
297 Handle(Geom_Curve) Iso;
299 B.MakeFace(Face,Surf,Precision::Confusion());
301 // make the missing edges
302 Surf->Bounds(f1,l1,f2,l2);
304 TopoDS_Edge Edge3, Edge4;
306 Iso = Surf->UIso(f1);
307 Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
308 if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
309 B.MakeEdge(Edge3,Iso,Precision::Confusion());
313 B.Degenerated(Edge3, Standard_True);
315 V1f.Orientation(TopAbs_FORWARD);
317 V2f.Orientation(TopAbs_REVERSED);
319 B.Range(Edge3,f2,l2);
325 Iso = Surf->UIso(l1);
326 Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
327 if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
328 B.MakeEdge(Edge4,Iso,Precision::Confusion());
332 B.Degenerated(Edge4, Standard_True);
334 V1l.Orientation(TopAbs_FORWARD);
336 V2l.Orientation(TopAbs_REVERSED);
338 B.Range(Edge4,f2,l2);
349 B.Add(W,Edge2.Reversed());
351 W.Closed (Standard_True);
357 Standard_Real T = Precision::Confusion();
359 if ( Edge1.Orientation() == TopAbs_REVERSED ) {
360 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),Face,T);
361 B.Range(Edge1,Face,-l1,-f1);
364 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),Face,T);
365 B.Range(Edge1,Face,f1,l1);
368 if ( Edge2.Orientation() == TopAbs_REVERSED ) {
369 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),Face,T);
370 B.Range(Edge2,Face,-l1,-f1);
373 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),Face,T);
374 B.Range(Edge2,Face,f1,l1);
379 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
380 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
383 B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
384 B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
387 // Set the non parameter flag;
388 B.SameParameter(Edge1,Standard_False);
389 B.SameParameter(Edge2,Standard_False);
390 B.SameParameter(Edge3,Standard_False);
391 B.SameParameter(Edge4,Standard_False);
392 B.SameRange(Edge1,Standard_False);
393 B.SameRange(Edge2,Standard_False);
394 B.SameRange(Edge3,Standard_False);
395 B.SameRange(Edge4,Standard_False);
397 BRepLib::SameParameter(Face);
399 if ( SameLoc) Face.Move(L);
404 //=======================================================================
407 //=======================================================================
409 TopoDS_Shell BRepFill::Shell(const TopoDS_Wire& Wire1,
410 const TopoDS_Wire& Wire2 )
415 TopoDS_Edge Edge1, Edge2, Edge3, Edge4, Couture;
418 // Class BRep_Tool without fields and without Constructor :
425 Standard_Boolean Closed = Wire1.Closed() && Wire2.Closed();
427 Standard_Boolean thefirst = Standard_True;
429 ex1.Init(Wire1,TopAbs_EDGE);
430 ex2.Init(Wire2,TopAbs_EDGE);
432 while ( ex1.More() && ex2.More() ) {
434 Edge1 = TopoDS::Edge(ex1.Current());
435 Edge2 = TopoDS::Edge(ex2.Current());
437 Standard_Boolean Periodic =
438 BRep_Tool::IsClosed(Edge1) && BRep_Tool::IsClosed(Edge2);
443 TopLoc_Location L,L1,L2;
444 Standard_Real f1,l1,f2,l2,Tol;
446 Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
447 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
449 // compute the location
450 Standard_Boolean SameLoc = Standard_False;
453 L1 = L2 = TopLoc_Location();
454 SameLoc = Standard_True;
457 // transform and trim the curves
459 TopoDS_Vertex V1f,V1l,V2f,V2l;
462 if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
463 Abs(l1 - C1->LastParameter()) > Precision::PConfusion() ) {
464 C1 = new Geom_TrimmedCurve(C1,f1,l1);
467 C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
470 C1->Transform(L1.Transformation());
472 if (Edge1.Orientation() == TopAbs_REVERSED) {
473 TopExp::Vertices(Edge1,V1l,V1f);
477 TopExp::Vertices(Edge1,V1f,V1l);
479 if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
480 Abs(l2 - C2->LastParameter()) > Precision::PConfusion() ) {
481 C2 = new Geom_TrimmedCurve(C2,f2,l2);
484 C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
487 C2->Transform(L2.Transformation());
489 if (Edge2.Orientation() == TopAbs_REVERSED) {
490 TopExp::Vertices(Edge2,V2l,V2f);
494 TopExp::Vertices(Edge2,V2f,V2l);
496 GeomFill_Generator Generator;
497 Generator.AddCurve( C1);
498 Generator.AddCurve( C2);
499 Generator.Perform( Precision::PConfusion());
501 Handle(Geom_Surface) Surf = Generator.Surface();
502 Handle(Geom_Curve) Iso;
504 B.MakeFace(Face,Surf,Precision::Confusion());
506 // make the missing edges
507 Surf->Bounds(f1,l1,f2,l2);
510 Iso = Surf->UIso(f1);
511 // Tol = Max(BT.Tolerance(V1f), BT.Tolerance(V2f));
512 Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
513 if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
514 B.MakeEdge(Edge3,Iso,Precision::Confusion());
518 B.Degenerated(Edge3, Standard_True);
520 V1f.Orientation(TopAbs_FORWARD);
522 V2f.Orientation(TopAbs_REVERSED);
524 B.Range(Edge3,f2,l2);
529 thefirst = Standard_False;
536 if ( Closed && !ex1.More() && !ex2.More() ) {
540 Iso = Surf->UIso(l1);
541 // Tol = Max(BT.Tolerance(V1l), BT.Tolerance(V2l));
542 Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
543 if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
544 B.MakeEdge(Edge4,Iso,Precision::Confusion());
548 B.Degenerated(Edge4, Standard_True);
550 V1l.Orientation(TopAbs_FORWARD);
552 V2l.Orientation(TopAbs_REVERSED);
554 B.Range(Edge4,f2,l2);
564 B.Add(W,Edge2.Reversed());
566 W.Closed (Standard_True);
570 if ( SameLoc) Face.Move( L);
576 Standard_Real T = Precision::Confusion();
578 if ( Edge1.Orientation() == TopAbs_REVERSED ) {
579 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),
581 B.Range(Edge1,Face,-l1,-f1);
584 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
586 B.Range(Edge1,Face,f1,l1);
589 if ( Edge2.Orientation() == TopAbs_REVERSED ) {
590 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),
592 B.Range(Edge2,Face,-l1,-f1);
595 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),
597 B.Range(Edge2,Face,f1,l1);
602 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
603 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),
607 B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
608 B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
611 // Set the non parameter flag;
612 B.SameParameter(Edge1,Standard_False);
613 B.SameParameter(Edge2,Standard_False);
614 B.SameParameter(Edge3,Standard_False);
615 B.SameParameter(Edge4,Standard_False);
616 B.SameRange(Edge1,Standard_False);
617 B.SameRange(Edge2,Standard_False);
618 B.SameRange(Edge3,Standard_False);
619 B.SameRange(Edge4,Standard_False);
622 Shell.Closed (BRep_Tool::IsClosed (Shell));
623 BRepLib::SameParameter(Shell);
627 //=======================================================================
630 //=======================================================================
632 void BRepFill::Axe (const TopoDS_Shape& Spine,
633 const TopoDS_Wire& Profile,
635 Standard_Boolean& ProfOnSpine,
636 const Standard_Real Tol)
638 gp_Pnt Loc,Loc1,Loc2;
639 gp_Vec Tang,Tang1,Tang2,Normal;
641 Handle(Geom_Surface) S;
646 // normal to the Spine.
647 if (Spine.ShapeType() == TopAbs_FACE) {
648 aFace = TopoDS::Face(Spine);
649 S = BRep_Tool::Surface(TopoDS::Face(Spine), L);
650 if ( !S->IsKind(STANDARD_TYPE(Geom_Plane))) {
651 BRepLib_FindSurface FS(TopoDS::Face(Spine), -1, Standard_True);
657 Standard_NoSuchObject::Raise
658 ("BRepFill_Evolved : The Face is not planar");
662 else if (Spine.ShapeType() == TopAbs_WIRE) {
663 aFace = BRepLib_MakeFace(TopoDS::Wire(Spine),Standard_True);
664 S = BRep_Tool::Surface(aFace, L);
667 if (S.IsNull()) Standard_DomainError::Raise("BRepFill_Evolved::Axe");
670 S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
672 Normal = Handle(Geom_Plane)::DownCast(S)->Pln().Axis().Direction();
674 // Find vertex of the profile closest to the spine.
675 Standard_Real DistMin = Precision::Infinite();
677 // Standard_Real Tol2 = Tol*Tol;
678 Standard_Real Tol2 = 1.e-10;
679 TopExp_Explorer PE, SE;
680 BRepExtrema_ExtPC BE;
681 Standard_Real Par =0.,f,l;
682 // Standard_Real D1,D2;
685 // First check if there is contact Vertex Vertex.
686 Standard_Boolean IsOnVertex = Standard_False;
687 SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
688 // modified by NIZHNY-EAP Wed Feb 23 12:31:52 2000 ___BEGIN___
689 // for (;SE.More() && !IsOnVertex ; SE.Next()) {
690 for (;SE.More(); SE.Next()) {
691 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SE.Current()));
693 PE.Init(Profile,TopAbs_VERTEX);
694 for ( ; PE.More(); PE.Next()) {
695 P2 = BRep_Tool::Pnt(TopoDS::Vertex(PE.Current()));
696 Standard_Real DistP1P2 = P1.SquareDistance(P2);
697 IsOnVertex = (DistP1P2 <= Tol2);
698 if (IsOnVertex) break;
700 // otherwise SE.Next() is done and VonF is wrong
701 if (IsOnVertex) break;
702 // modified by NIZHNY-EAP Wed Jan 26 09:08:36 2000 ___END___
706 // try to find on which edge which shared this vertex,
707 // the profile must be considered.
708 // E1, E2 : those two edges.
709 TopTools_IndexedDataMapOfShapeListOfShape Map;
710 TopExp::MapShapesAndAncestors(aFace.Oriented(TopAbs_FORWARD),
715 const TopoDS_Vertex& VonF = TopoDS::Vertex(SE.Current());
716 const TopTools_ListOfShape& List = Map.FindFromKey(VonF);
717 const TopoDS_Edge& E1 = TopoDS::Edge(List.First());
718 const TopoDS_Edge& E2 = TopoDS::Edge(List. Last());
720 Handle(Geom_Curve) CE1 = BRep_Tool::Curve(E1,L,f,l);
721 Standard_Real Par1 = BRep_Tool::Parameter(VonF,E1,aFace);
722 CE1->D1(Par1,Loc1,Tang1);
723 if (!L.IsIdentity()) {
724 Tang1.Transform(L.Transformation());
725 Loc1.Transform(L.Transformation());
727 if (E1.Orientation() == TopAbs_REVERSED) Tang1.Reverse();
729 Handle(Geom_Curve) CE2 = BRep_Tool::Curve(E2,L,f,l);
730 Standard_Real Par2 = BRep_Tool::Parameter(VonF,E2,aFace);
731 CE2->D1(Par2,Loc2,Tang2);
732 if (!L.IsIdentity()) {
733 Tang2.Transform(L.Transformation());
734 Loc2.Transform(L.Transformation());
736 if (E2.Orientation() == TopAbs_REVERSED) Tang2.Reverse();
738 // modified by NIZHNY-EAP Wed Feb 2 15:38:41 2000 ___BEGIN___
741 Standard_Real sca1=0., sca2=0.;
742 TopoDS_Vertex V1, V2;
744 for (PE.Init(Profile,TopAbs_EDGE); PE.More(); PE.Next()) {
745 E = TopoDS::Edge(PE.Current());
746 TopExp::Vertices(E, V1, V2);
747 P1 = BRep_Tool::Pnt(V1);
748 P2 = BRep_Tool::Pnt(V2);
750 sca1 += Abs(Tang1.Dot(vec));
751 sca2 += Abs(Tang2.Dot(vec));
753 // modified by NIZHNY-EAP Wed Feb 2 15:38:44 2000 ___END___
755 if ( Abs(sca1) < Abs(sca2)) {
766 SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
767 for ( ; SE.More(); SE.Next()) {
768 const TopoDS_Edge& E = TopoDS::Edge(SE.Current());
770 for (PE.Init(Profile,TopAbs_VERTEX) ; PE.More(); PE.Next()) {
771 Dist = Precision::Infinite();
772 const TopoDS_Vertex& V = TopoDS::Vertex(PE.Current());
776 for (Standard_Integer i = 1; i <= BE.NbExt(); i++) {
778 Dist = sqrt (BE.SquareDistance(i));
779 Par = BE.Parameter(i);
785 if (Dist < DistMin) {
787 BRepAdaptor_Curve BAC(E);
788 BAC.D1 (Par,Loc,Tang);
789 if (E.Orientation() == TopAbs_REVERSED) Tang.Reverse();
795 ProfOnSpine = (DistMin < Tol);
796 //Construction AxeProf;
797 gp_Ax3 A3 (Loc,Normal,Tang);
802 //=======================================================================
803 //function : SearchOrigin
804 //purpose : Cut and orientate a closed wire.
805 //=======================================================================
807 void BRepFill::SearchOrigin(TopoDS_Wire & W,
810 const Standard_Real Tol)
813 Standard_NoSuchObject::
814 Raise("BRepFill::SearchOrigin : the wire must be closed");
817 Standard_Boolean NewVertex = Standard_False;
818 Standard_Real theparam = 1.e101, angle;
820 TopoDS_Edge E, Eref, E1 , E2;
822 // Class BRep_Tool without fields and without Constructor :
825 W.Orientation(TopAbs_FORWARD); //to avoid composing the orientations
827 // Calculate the distance
828 B.MakeVertex(V, P, Tol);
829 BRepExtrema_DistShapeShape DSS(V, W);
831 Standard_Integer isol = 1;
832 Standard_Real dss = P.Distance(DSS.PointOnShape2(isol));
833 for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++)
834 if (dss > P.Distance(DSS.PointOnShape2(iss))) {
835 dss = P.Distance(DSS.PointOnShape2(iss));
838 TopoDS_Shape supp = DSS.SupportOnShape2(isol);
839 if (DSS.SupportTypeShape2(isol)==BRepExtrema_IsVertex) {
840 V = TopoDS::Vertex(supp);
843 TopoDS_Vertex Vf, Vl;
844 Standard_Real d, dist;
845 E = TopoDS::Edge(supp);
846 TopExp::Vertices(E, Vf, Vl);
847 // dist = P.Distance(BT.Pnt(Vf));
848 dist = P.Distance(BRep_Tool::Pnt(Vf));
852 // d = P.Distance(BT.Pnt(Vl));
853 d = P.Distance(BRep_Tool::Pnt(Vl));
854 if ((d<Tol) && (d<dist)) {
858 NewVertex = (dist > Tol);
860 DSS.ParOnEdgeS2(isol, theparam);
866 cout << "BRepFill::SearchOrigine : Echec Distance" << endl;
870 Standard_Integer ii, rangdeb=0, NbEdges=0;
871 Standard_Boolean forward;
872 BRepTools_WireExplorer exp;
874 // Calculate the number of edges
875 for(exp.Init(W); exp.More(); exp.Next()) NbEdges++;
881 // Construct the Table and calculate rangdeb
882 TopTools_Array1OfShape Edges(1, NbEdges);
883 for(exp.Init(W), ii=1; exp.More(); exp.Next(), ii++) {
885 if (NewVertex && E.IsSame(Eref)) {
887 CutEdge(E, theparam, E1, E2, exp.CurrentVertex());
896 if (!NewVertex && V.IsSame(exp.CurrentVertex())) {
900 if (rangdeb == 0) rangdeb = NbEdges;
902 // Calculate the direction of parsing
903 E = TopoDS::Edge(Edges(rangdeb));
905 // theparam = BT.Parameter(V, E);
906 theparam = BRep_Tool::Parameter(V, E);
908 BRepAdaptor_Curve AC(E);
911 AC.D1(theparam, Pe, Ve);
912 if (E.Orientation()==TopAbs_REVERSED) {
915 angle = Ve.Angle(Dir);
916 if (angle > M_PI) angle = 2*M_PI - angle;
917 forward = (angle <= M_PI/2);
920 MakeWire( Edges, rangdeb, forward, W);
921 W.Closed(Standard_True);
926 //=======================================================================
927 //function : ComputeACR
929 //=======================================================================
931 void BRepFill::ComputeACR(const TopoDS_Wire& wire,
932 TColStd_Array1OfReal& ACR)
934 // calculate the reduced curvilinear abscisses and the length of the wire
935 BRepTools_WireExplorer anExp;
936 Standard_Integer nbEdges=0, i;
940 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
942 TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
943 ACR(nbEdges) = ACR(nbEdges-1);
944 if (!BRep_Tool::Degenerated(Ecur)) {
945 BRepAdaptor_Curve anEcur(Ecur);
946 ACR(nbEdges) += GCPnts_AbscissaPoint::Length(anEcur);
950 // total length of the wire
951 ACR(0) = ACR(nbEdges);
953 // reduced curvilinear abscisses
954 if (ACR(0)>Precision::Confusion()) {
955 for (i=1; i<=nbEdges; i++) {
966 //=======================================================================
967 //function : InsertACR
969 //=======================================================================
971 TopoDS_Wire BRepFill::InsertACR(const TopoDS_Wire& wire,
972 const TColStd_Array1OfReal& ACRcuts,
973 const Standard_Real prec)
975 // calculate ACR of the wire to be cut
976 BRepTools_WireExplorer anExp;
977 Standard_Integer nbEdges=0;
978 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
981 TColStd_Array1OfReal ACRwire(0,nbEdges);
982 ComputeACR(wire, ACRwire);
984 Standard_Integer i, j, nmax=ACRcuts.Length();
985 TColStd_Array1OfReal paradec(1,nmax);
988 Standard_Real t0,t1=0;
991 // processing edge by edge
992 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
995 t1 = ACRwire(nbEdges);
997 // parameters of cut on this edge
998 Standard_Integer ndec=0;
999 for (i=1; i<=ACRcuts.Length(); i++ ) {
1000 if (t0+prec<ACRcuts(i) && ACRcuts(i)<t1-prec) {
1002 paradec(ndec) = ACRcuts(i);
1006 TopoDS_Edge E = anExp.Current();
1007 TopoDS_Vertex V = anExp.CurrentVertex();
1009 if (ndec==0 || BRep_Tool::Degenerated(E)) {
1014 // it is necessary to cut the edge
1015 // following the direction of parsing of the wire
1016 Standard_Boolean SO = (V.IsSame(TopExp::FirstVertex(E)));
1017 TopTools_SequenceOfShape SE;
1019 TColStd_SequenceOfReal SR;
1021 // the wire is always FORWARD
1022 // it is necesary to modify the parameter of cut6 if the edge is REVERSED
1023 if (E.Orientation() == TopAbs_FORWARD) {
1024 for (j=1; j<=ndec; j++) SR.Append(paradec(j));
1027 for (j=1; j<=ndec; j++) SR.Append(t0+t1-paradec(ndec+1-j));
1029 TrimEdge(E,SR,t0,t1,SO,SE);
1030 for (j=1; j<=SE.Length(); j++) {
1031 MW.Add(TopoDS::Edge(SE.Value(j)));
1037 TopAbs_Orientation Orien = wire.Orientation();
1038 TopoDS_Shape aLocalShape = MW.Wire();
1039 aLocalShape.Orientation(Orien);
1040 TopoDS_Wire wres = TopoDS::Wire(aLocalShape);
1041 // TopoDS_Wire wres = TopoDS::Wire(MW.Wire().Oriented(Orien));