1 // Created on: 1996-01-11
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
23 #include <LocOpe_WiresOnShape.ixx>
25 #include <TopExp_Explorer.hxx>
26 #include <BRep_Builder.hxx>
27 #include <BRep_Tool.hxx>
28 #include <TopTools_MapOfShape.hxx>
29 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
30 #include <TopTools_ListOfShape.hxx>
31 #include <TopTools_ListIteratorOfListOfShape.hxx>
33 #include <GeomAPI_ProjectPointOnCurve.hxx>
34 #include <GeomAdaptor_Surface.hxx>
35 #include <Geom_Curve.hxx>
36 #include <Geom_TrimmedCurve.hxx>
37 #include <Geom_Surface.hxx>
38 #include <Geom_RectangularTrimmedSurface.hxx>
39 #include <Geom2d_Curve.hxx>
41 #include <gp_Pnt2d.hxx>
42 #include <gp_Vec2d.hxx>
47 #include <BRepTools.hxx>
48 #include <GeomProjLib.hxx>
50 #include <Precision.hxx>
52 #include <Standard_ConstructionError.hxx>
53 #include <TopoDS_Compound.hxx>
54 #include <BRepLib.hxx>
56 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
57 #include <BRepAdaptor_Curve2d.hxx>
58 #include <Bnd_Box2d.hxx>
59 #include <BndLib_Add2dCurve.hxx>
60 #include <Extrema_ExtCC.hxx>
61 #include <BRepLib_MakeVertex.hxx>
64 static Standard_Boolean Project(const TopoDS_Vertex&,
69 static Standard_Real Project(const TopoDS_Vertex&,
73 static void PutPCurve(const TopoDS_Edge&,
77 static void PutPCurves(const TopoDS_Edge&,
81 static void FindInternalIntersections(const TopoDS_Edge&,
83 TopTools_IndexedDataMapOfShapeListOfShape&,
84 TopTools_DataMapOfShapeShape&,
85 TopTools_MapOfShape&);
87 //=======================================================================
88 //function : LocOpe_WiresOnShape
90 //=======================================================================
92 LocOpe_WiresOnShape::LocOpe_WiresOnShape(const TopoDS_Shape& S):
93 myShape(S),myDone(Standard_False)
98 //=======================================================================
101 //=======================================================================
103 void LocOpe_WiresOnShape::Init(const TopoDS_Shape& S)
106 myDone = Standard_False;
113 //=======================================================================
116 //=======================================================================
118 void LocOpe_WiresOnShape::Bind(const TopoDS_Wire& W,
119 const TopoDS_Face& F)
121 for (TopExp_Explorer exp(W, TopAbs_EDGE); exp.More(); exp.Next()) {
122 Bind(TopoDS::Edge(exp.Current()),F);
126 //=======================================================================
129 //=======================================================================
131 void LocOpe_WiresOnShape::Bind(const TopoDS_Compound& Comp,
132 const TopoDS_Face& F)
134 for (TopExp_Explorer exp(Comp, TopAbs_EDGE); exp.More(); exp.Next()) {
135 Bind(TopoDS::Edge(exp.Current()),F);
137 myFacesWithSection.Add(F);
140 //=======================================================================
143 //=======================================================================
145 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& E,
146 const TopoDS_Face& F)
148 // if (!myMapEF.IsBound(E)) {
149 if (!myMapEF.Contains(E)) {
150 // for (TopExp_Explorer exp(F,TopAbs_EDGE);exp.More();exp.Next()) {
151 TopExp_Explorer exp(F,TopAbs_EDGE) ;
152 for ( ;exp.More();exp.Next()) {
153 if (exp.Current().IsSame(E)) {
158 // myMapEF.Bind(E,F);
163 Standard_ConstructionError::Raise();
168 //=======================================================================
171 //=======================================================================
173 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& Ewir,
174 const TopoDS_Edge& Efac)
176 if (Ewir.IsSame(Efac)) {
179 myMap.Bind(Ewir,Efac);
183 //=======================================================================
186 //=======================================================================
188 void LocOpe_WiresOnShape::BindAll()
193 TopTools_MapOfShape theMap;
195 // Detection des vertex a projeter ou a "binder" avec des vertex existants
196 TopTools_DataMapOfShapeShape mapV;
197 TopTools_DataMapIteratorOfDataMapOfShapeShape ite(myMap);
198 TopExp_Explorer exp,exp2;
199 for (; ite.More(); ite.Next()) {
200 const TopoDS_Edge& eref = TopoDS::Edge(ite.Key());
201 const TopoDS_Edge& eimg = TopoDS::Edge(ite.Value());
203 PutPCurves(eref,eimg,myShape);
205 for (exp.Init(eref,TopAbs_VERTEX); exp.More(); exp.Next()) {
206 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
207 if (!theMap.Contains(vtx)) { // pas deja traite
208 for (exp2.Init(eimg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
209 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
210 if (vtx2.IsSame(vtx)) {
213 else if (BRepTools::Compare(vtx,vtx2)) {
226 for (ite.Initialize(mapV); ite.More(); ite.Next()) {
227 myMap.Bind(ite.Key(),ite.Value());
230 TopTools_IndexedDataMapOfShapeListOfShape Splits;
231 Standard_Integer Ind;
232 for (Ind = 1; Ind <= myMapEF.Extent(); Ind++)
234 const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
235 const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
238 Standard_Real pf, pl;
239 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(edg, fac, pf, pl);
240 if (aPCurve.IsNull())
243 FindInternalIntersections(edg, fac, Splits, myMap, theMap);
246 for (Ind = 1; Ind <= Splits.Extent(); Ind++)
248 TopoDS_Shape anEdge = Splits.FindKey(Ind);
249 TopoDS_Shape aFace = myMapEF.FindFromKey(anEdge);
250 //Remove "anEdge" from "myMapEF"
251 TopoDS_Shape LastEdge = myMapEF.FindKey(myMapEF.Extent());
252 TopoDS_Shape LastFace = myMapEF(myMapEF.Extent());
253 myMapEF.RemoveLast();
254 if (myMapEF.FindIndex(anEdge) != 0)
255 myMapEF.Substitute(myMapEF.FindIndex(anEdge), LastEdge, LastFace);
256 ////////////////////////////////
257 TopTools_ListIteratorOfListOfShape itl(Splits(Ind));
258 for (; itl.More(); itl.Next())
259 myMapEF.Add(itl.Value(), aFace);
262 // Il faut s`occuper maintenant des vertex "de changement de face",
263 // et des vertex "libres"
264 // TopTools_DataMapIteratorOfDataMapOfShapeShape ite2;
266 // for (ite.Initialize(myMapEF); ite.More(); ite.Next()) {
267 // const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
268 // const TopoDS_Face& fac = TopoDS::Face(ite.Value());
269 for (Ind = 1; Ind <= myMapEF.Extent(); Ind++) {
270 const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
271 const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
272 // JAG 02.02.96 : On verifie les pcurves...
274 //PutPCurve(edg,fac);
276 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
277 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
278 if (theMap.Contains(vtx)) {
283 Standard_Boolean ok = Project(vtx,fac,Epro,prm);
285 for (exp2.Init(Epro,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
286 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
287 if (vtx2.IsSame(vtx)) {
290 else if (BRepTools::Compare(vtx,vtx2)) {
291 myMap.Bind(vtx,vtx2);
296 myMap.Bind(vtx,Epro);
303 // Modified by Sergey KHROMOV - Mon Feb 12 16:26:50 2001 Begin
304 for (ite.Initialize(myMap); ite.More(); ite.Next())
305 if ((ite.Key()).ShapeType() == TopAbs_EDGE)
306 myMapEF.Add(ite.Key(),ite.Value());
307 // Modified by Sergey KHROMOV - Mon Feb 12 16:26:52 2001 End
310 myDone = Standard_True;
315 //=======================================================================
316 //function : InitEdgeIterator
318 //=======================================================================
320 void LocOpe_WiresOnShape::InitEdgeIterator()
323 // myIt.Initialize(myMapEF);
328 //=======================================================================
329 //function : MoreEdge
331 //=======================================================================
333 Standard_Boolean LocOpe_WiresOnShape::MoreEdge()
335 // return myIt.More();
336 return (myIndex <= myMapEF.Extent());
340 //=======================================================================
343 //=======================================================================
345 TopoDS_Edge LocOpe_WiresOnShape::Edge()
347 // return TopoDS::Edge(myIt.Key());
348 return TopoDS::Edge(myMapEF.FindKey(myIndex));
352 //=======================================================================
355 //=======================================================================
357 TopoDS_Face LocOpe_WiresOnShape::OnFace()
359 // return TopoDS::Face(myIt.Value());
360 return TopoDS::Face(myMapEF(myIndex));
364 //=======================================================================
367 //=======================================================================
369 Standard_Boolean LocOpe_WiresOnShape::OnEdge(TopoDS_Edge& E)
371 // if (myMap.IsBound(myIt.Key())) {
372 if (myMap.IsBound(myMapEF.FindKey(myIndex))) {
373 // E = TopoDS::Edge(myMap(myIt.Key()));
374 E = TopoDS::Edge(myMap(myMapEF.FindKey(myIndex)));
375 return Standard_True;
377 return Standard_False;
383 //=======================================================================
384 //function : NextEdge
386 //=======================================================================
388 void LocOpe_WiresOnShape::NextEdge()
396 //=======================================================================
397 //function : OnVertex
399 //=======================================================================
401 Standard_Boolean LocOpe_WiresOnShape::OnVertex(const TopoDS_Vertex& Vw,
404 if (myMap.IsBound(Vw)) {
405 if (myMap(Vw).ShapeType() == TopAbs_VERTEX) {
406 Vs = TopoDS::Vertex(myMap(Vw));
407 return Standard_True;
409 return Standard_False;
411 return Standard_False;
417 //=======================================================================
420 //=======================================================================
422 Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
426 if (!myMap.IsBound(V) ||
427 myMap(V).ShapeType() == TopAbs_VERTEX) {
428 return Standard_False;
431 Ed = TopoDS::Edge(myMap(V));
433 return Standard_True;
437 //=======================================================================
440 //=======================================================================
442 Standard_Boolean Project(const TopoDS_Vertex& V,
443 const TopoDS_Face& F,
444 TopoDS_Edge& theEdge,
445 Standard_Real& param)
447 Handle(Geom_Curve) C;
451 Standard_Real dmin = RealLast();
452 gp_Pnt toproj(BRep_Tool::Pnt(V));
453 Standard_Boolean valret = Standard_False;
454 GeomAPI_ProjectPointOnCurve proj;
456 for (TopExp_Explorer exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
457 exp.More(); exp.Next()) {
458 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
459 if (!BRep_Tool::Degenerated(edg)) {
460 C = BRep_Tool::Curve(edg,Loc,f,l);
461 if (!Loc.IsIdentity()) {
462 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
463 C = *((Handle(Geom_Curve)*)&GG);
465 proj.Init(toproj,C,f,l);
466 if (proj.NbPoints() > 0) {
467 if (proj.LowerDistance() < dmin) {
469 theEdge.Orientation(edg.Orientation());
470 dmin = proj.LowerDistance();
471 param = proj.LowerDistanceParameter();
478 return Standard_False;
480 Standard_Real ttol = BRep_Tool::Tolerance(V) + BRep_Tool::Tolerance(theEdge);
482 valret = Standard_True;
484 B.UpdateVertex(V, Max(dmin, BRep_Tool::Tolerance(V)));
488 cout <<"LocOpe_WiresOnShape::Project --> le vertex projete est a une ";
489 cout <<"distance / la face = "<<dmin <<" superieure a la tolerance = "<<ttol<<endl;
495 //=======================================================================
498 //=======================================================================
500 Standard_Real Project(const TopoDS_Vertex& V,
501 const TopoDS_Edge& theEdge)
503 Handle(Geom_Curve) C;
507 gp_Pnt toproj(BRep_Tool::Pnt(V));
508 GeomAPI_ProjectPointOnCurve proj;
510 C = BRep_Tool::Curve(theEdge,Loc,f,l);
511 if (!Loc.IsIdentity()) {
512 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
513 C = *((Handle(Geom_Curve)*)&GG);
515 proj.Init(toproj,C,f,l);
518 return proj.LowerDistanceParameter();
522 //=======================================================================
523 //function : PutPCurve
525 //=======================================================================
527 void PutPCurve(const TopoDS_Edge& Edg,
528 const TopoDS_Face& Fac)
531 TopLoc_Location LocFac;
533 Handle(Geom_Surface) S = BRep_Tool::Surface(Fac, LocFac);
534 Handle(Standard_Type) styp = S->DynamicType();
536 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
537 S = (*((Handle(Geom_RectangularTrimmedSurface)*)&(S)))->BasisSurface();
538 styp = S->DynamicType();
541 if (styp == STANDARD_TYPE(Geom_Plane)) {
545 Standard_Real Umin,Umax,Vmin,Vmax;
546 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
550 //if (!BRep_Tool::CurveOnSurface(Edg,Fac,f,l).IsNull()) {
553 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(Edg,Fac,f,l);
554 if ( !aC2d.IsNull() ) {
557 Standard_Boolean IsIn = Standard_True;
558 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
559 ( p2d.X() > Umax+Precision::PConfusion() ) )
560 IsIn = Standard_False;
561 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
562 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
563 IsIn = Standard_False;
565 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
566 ( p2d.X() > Umax+Precision::PConfusion() ) )
567 IsIn = Standard_False;
568 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
569 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
570 IsIn = Standard_False;
576 Handle(Geom_Curve) C = BRep_Tool::Curve(Edg,Loc,f,l);
577 if (!Loc.IsIdentity()) {
578 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
579 C = *((Handle(Geom_Curve)*)&GG);
582 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
583 C = new Geom_TrimmedCurve(C,f,l);
586 S = BRep_Tool::Surface(Fac);
589 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Edg),
590 BRep_Tool::Tolerance(Fac));
591 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
592 Standard_Real TolU = Gas.UResolution(tol3d);
593 Standard_Real TolV = Gas.VResolution(tol3d);
594 Standard_Real tol2d = Max(TolU,TolV);
596 Handle(Geom2d_Curve) C2d =
597 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
600 gp_Pnt2d pf(C2d->Value(f));
601 gp_Pnt2d pl(C2d->Value(l));
603 S->D0(pf.X(),pf.Y(),PF);
604 S->D0(pl.X(),pl.Y(),PL);
606 if (Edg.Orientation() == TopAbs_REVERSED) {
607 V1 = TopExp::LastVertex(Edg);
611 V1 = TopExp::FirstVertex (Edg);
613 if (Edg.Orientation() == TopAbs_REVERSED) {
614 V2 = TopExp::FirstVertex(Edg);
618 V2 = TopExp::LastVertex (Edg);
621 if(!V1.IsNull() && V2.IsNull()) {
622 //Handling of internal vertices
623 Standard_Real old1 = BRep_Tool::Tolerance (V1);
624 Standard_Real old2 = BRep_Tool::Tolerance (V2);
625 gp_Pnt pnt1 = BRep_Tool::Pnt (V1);
626 gp_Pnt pnt2 = BRep_Tool::Pnt (V2);
627 Standard_Real tol1 = pnt1.Distance(PF);
628 Standard_Real tol2 = pnt2.Distance(PL);
629 B.UpdateVertex(V1,Max(old1,tol1));
630 B.UpdateVertex(V2,Max(old2,tol2));
633 if (S->IsUPeriodic()) {
634 Standard_Real up = S->UPeriod();
635 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
636 Standard_Integer nbtra = 0;
637 Standard_Real theUmin = Min(pf.X(),pl.X());
638 Standard_Real theUmax = Max(pf.X(),pl.X());
640 if (theUmin < Umin-tolu) {
641 while (theUmin < Umin-tolu) {
646 else if (theUmax > Umax+tolu) {
647 while (theUmax > Umax+tolu) {
654 if (theUmin > Umax-tolu) {
655 while (theUmin > Umax-tolu) {
660 else if (theUmax < Umin+tolu) {
661 while (theUmax < Umin+tolu) {
668 C2d->Translate(gp_Vec2d(nbtra*up,0.));
672 if (S->IsVPeriodic()) {
673 Standard_Real vp = S->VPeriod();
674 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
675 Standard_Integer nbtra = 0;
676 Standard_Real theVmin = Min(pf.Y(),pl.Y());
677 Standard_Real theVmax = Max(pf.Y(),pl.Y());
679 if (theVmin < Vmin-tolv) {
680 while (theVmin < Vmin-tolv) {
681 theVmin += vp; theVmax += vp;
685 else if (theVmax > Vmax+tolv) {
686 while (theVmax > Vmax+tolv) {
687 theVmax -= vp; theVmin -= vp;
692 if (theVmin > Vmax-tolv) {
693 while (theVmin > Vmax-tolv) {
698 else if (theVmax < Vmin+tolv) {
699 while (theVmax < Vmin+tolv) {
706 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
709 B.UpdateEdge(Edg,C2d,Fac,BRep_Tool::Tolerance(Edg));
711 B.SameParameter(Edg,Standard_False);
712 BRepLib::SameParameter(Edg,tol2d);
716 //=======================================================================
717 //function : PutPCurves
719 //=======================================================================
721 void PutPCurves(const TopoDS_Edge& Efrom,
722 const TopoDS_Edge& Eto,
723 const TopoDS_Shape& myShape)
726 TopTools_ListOfShape Lfaces;
727 TopExp_Explorer exp,exp2;
729 for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
730 for (exp2.Init(exp.Current(), TopAbs_EDGE); exp2.More();exp2.Next()) {
731 if (exp2.Current().IsSame(Eto)) {
732 Lfaces.Append(exp.Current());
737 if (Lfaces.Extent() != 1 && Lfaces.Extent() !=2) {
738 Standard_ConstructionError::Raise();
741 // soit bord libre, soit connexite entre 2 faces, eventuellement edge closed
743 if (Lfaces.Extent() ==1) {
744 return; // sera fait par PutPCurve.... on l`espere
748 Handle(Geom_Surface) S;
749 Handle(Standard_Type) styp;
750 Handle(Geom_Curve) C;
751 Standard_Real Umin,Umax,Vmin,Vmax;
753 TopLoc_Location Loc, LocFac;
755 if (!Lfaces.First().IsSame(Lfaces.Last())) {
756 TopTools_ListIteratorOfListOfShape itl(Lfaces);
757 for (; itl.More(); itl.Next()) {
758 const TopoDS_Face& Fac = TopoDS::Face(itl.Value());
760 if (!BRep_Tool::CurveOnSurface(Efrom,Fac,f,l).IsNull()) {
763 S = BRep_Tool::Surface(Fac, LocFac);
764 styp = S->DynamicType();
765 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
766 S = (*((Handle(Geom_RectangularTrimmedSurface)*)&(S)))->BasisSurface();
767 styp = S->DynamicType();
769 if (styp == STANDARD_TYPE(Geom_Plane)) {
774 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
775 C = BRep_Tool::Curve(Efrom,Loc,f,l);
776 if (!Loc.IsIdentity()) {
777 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
778 C = *((Handle(Geom_Curve)*)&GG);
781 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
782 C = new Geom_TrimmedCurve(C,f,l);
785 S = BRep_Tool::Surface(Fac);
788 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
789 BRep_Tool::Tolerance(Fac));
790 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
791 Standard_Real TolU = Gas.UResolution(tol3d);
792 Standard_Real TolV = Gas.VResolution(tol3d);
793 Standard_Real tol2d = Max(TolU,TolV);
795 Handle(Geom2d_Curve) C2d =
796 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
800 gp_Pnt2d pf(C2d->Value(f));
801 gp_Pnt2d pl(C2d->Value(l));
803 if (S->IsUPeriodic()) {
804 Standard_Real up = S->UPeriod();
805 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
806 Standard_Integer nbtra = 0;
807 Standard_Real theUmin = Min(pf.X(),pl.X());
808 Standard_Real theUmax = Max(pf.X(),pl.X());
810 if (theUmin < Umin-tolu) {
811 while (theUmin < Umin-tolu) {
812 theUmin += up; theUmax += up;
816 else if (theUmax > Umax+tolu) {
817 while (theUmax > Umax+tolu) {
818 theUmax -= up; theUmin -= up;
823 if (theUmin > Umax+tolu) {
824 while (theUmin > Umax+tolu) {
829 else if (theUmax < Umin-tolu) {
830 while (theUmax < Umin-tolu) {
837 C2d->Translate(gp_Vec2d(nbtra*up,0.));
841 if (S->IsVPeriodic()) {
842 Standard_Real vp = S->VPeriod();
843 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
844 Standard_Integer nbtra = 0;
845 Standard_Real theVmin = Min(pf.Y(),pl.Y());
846 Standard_Real theVmax = Max(pf.Y(),pl.Y());
848 if (theVmin < Vmin-tolv) {
849 while (theVmin < Vmin-tolv) {
850 theVmin += vp; theVmax += vp;
854 else if (theVmax > Vmax+tolv) {
855 while (theVmax > Vmax+tolv) {
856 theVmax -= vp; theVmin -= vp;
861 if (theVmin > Vmax+tolv) {
862 while (theVmin > Vmax+tolv) {
867 else if (theVmax < Vmin-tolv) {
868 while (theVmax < Vmin-tolv) {
875 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
878 B.UpdateEdge(Efrom,C2d,Fac,BRep_Tool::Tolerance(Efrom));
883 const TopoDS_Face& Fac = TopoDS::Face(Lfaces.First());
884 if (!BRep_Tool::IsClosed(Eto,Fac)) {
885 Standard_ConstructionError::Raise();
888 TopoDS_Shape aLocalE = Efrom.Oriented(TopAbs_FORWARD);
889 TopoDS_Shape aLocalF = Fac.Oriented(TopAbs_FORWARD);
890 Handle(Geom2d_Curve) c2dff =
891 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
892 TopoDS::Face(aLocalF),
895 // Handle(Geom2d_Curve) c2dff =
896 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_FORWARD)),
897 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
900 aLocalE = Efrom.Oriented(TopAbs_REVERSED);
901 aLocalF = Fac.Oriented(TopAbs_FORWARD);
902 Handle(Geom2d_Curve) c2dfr =
903 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
904 TopoDS::Face(aLocalF),
906 // Handle(Geom2d_Curve) c2dfr =
907 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_REVERSED)),
908 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
911 aLocalE = Eto.Oriented(TopAbs_FORWARD);
912 aLocalF = Fac.Oriented(TopAbs_FORWARD);
913 Handle(Geom2d_Curve) c2dtf =
914 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
915 TopoDS::Face(aLocalF),
918 // Handle(Geom2d_Curve) c2dtf =
919 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_FORWARD)),
920 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
922 aLocalE = Eto.Oriented(TopAbs_REVERSED);
923 aLocalF = Fac.Oriented(TopAbs_FORWARD);
924 Handle(Geom2d_Curve) c2dtr =
925 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
926 TopoDS::Face(aLocalF),
928 // Handle(Geom2d_Curve) c2dtr =
929 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_REVERSED)),
930 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
933 gp_Pnt2d ptf(c2dtf->Value(f)); // sur courbe frw
934 gp_Pnt2d ptr(c2dtr->Value(f)); // sur courbe rev
936 Standard_Boolean isoU = (Abs(ptf.Y()-ptr.Y())<Epsilon(ptf.X())); // meme V
938 // Efrom et Eto dans le meme sens???
940 C = BRep_Tool::Curve(Efrom,Loc,f,l);
941 if (!Loc.IsIdentity()) {
942 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
943 C = *((Handle(Geom_Curve)*)&GG);
951 Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),Eto);
953 C = BRep_Tool::Curve(Eto,Loc,f,l);
954 if (!Loc.IsIdentity()) {
955 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
956 C = *((Handle(Geom_Curve)*)&GG);
959 C->D1(prmproj,pt,d1t);
961 Standard_Real SameOri = (d1t.Dot(d1f)>0.);
964 if (c2dff.IsNull() && c2dfr.IsNull()) {
965 S = BRep_Tool::Surface(Fac);
966 styp = S->DynamicType();
967 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
968 S = (*((Handle(Geom_RectangularTrimmedSurface)*)&(S)))->BasisSurface();
969 styp = S->DynamicType();
972 C = BRep_Tool::Curve(Efrom,Loc,f,l);
973 if (!Loc.IsIdentity()) {
974 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
975 C = *((Handle(Geom_Curve)*)&GG);
978 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
979 C = new Geom_TrimmedCurve(C,f,l);
983 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
985 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
986 BRep_Tool::Tolerance(Fac));
987 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
988 Standard_Real TolU = Gas.UResolution(tol3d);
989 Standard_Real TolV = Gas.VResolution(tol3d);
990 Standard_Real tol2d = Max(TolU,TolV);
992 Handle(Geom2d_Curve) C2d =
993 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
997 else if (c2dfr.IsNull()) {
1001 else if (c2dff.IsNull()) {
1005 BRep_Tool::Range(Efrom,f,l);
1007 gp_Pnt2d p2f = c2dff->Value(f);
1008 gp_Pnt2d p2r = c2dfr->Value(f);
1012 if (Abs(ptf.X()-p2f.X()) > Epsilon(ptf.X())) {
1013 c2dff = Handle(Geom2d_Curve)::DownCast
1014 (c2dff->Translated(gp_Vec2d(ptf.X()-p2f.X(),0.)));
1016 if (Abs(ptr.X()-p2r.X()) > Epsilon(ptr.X())) {
1017 c2dfr = Handle(Geom2d_Curve)::DownCast
1018 (c2dfr->Translated(gp_Vec2d(ptr.X()-p2r.X(),0.)));
1022 if (Abs(ptr.X()-p2f.X()) > Epsilon(ptr.X())) {
1023 c2dff = Handle(Geom2d_Curve)::DownCast
1024 (c2dff->Translated(gp_Vec2d(ptr.X()-p2f.X(),0.)));
1027 if (Abs(ptf.X()-p2r.X()) > Epsilon(ptf.X())) {
1028 c2dfr = Handle(Geom2d_Curve)::DownCast
1029 (c2dfr->Translated(gp_Vec2d(ptf.X()-p2r.X(),0.)));
1033 // on est bien en U, recalage si periodique en V a faire
1039 else { // !isoU soit isoV
1041 if (Abs(ptf.Y()-p2f.Y()) > Epsilon(ptf.Y())) {
1042 c2dff = Handle(Geom2d_Curve)::DownCast
1043 (c2dff->Translated(gp_Vec2d(0.,ptf.Y()-p2f.Y())));
1045 if (Abs(ptr.Y()-p2r.Y()) > Epsilon(ptr.Y())) {
1046 c2dfr = Handle(Geom2d_Curve)::DownCast
1047 (c2dfr->Translated(gp_Vec2d(0.,ptr.Y()-p2r.Y())));
1051 if (Abs(ptr.Y()-p2f.Y()) > Epsilon(ptr.Y())) {
1052 c2dff = Handle(Geom2d_Curve)::DownCast
1053 (c2dff->Translated(gp_Vec2d(0.,ptr.Y()-p2f.Y())));
1055 if (Abs(ptf.Y()-p2r.Y()) > Epsilon(ptf.Y())) {
1056 c2dfr = Handle(Geom2d_Curve)::DownCast
1057 (c2dfr->Translated(gp_Vec2d(0.,ptf.Y()-p2r.Y())));
1060 // on est bien en V, recalage si periodique en U a faire
1063 B.UpdateEdge(Efrom,c2dff,c2dfr,Fac,BRep_Tool::Tolerance(Efrom));
1067 //=======================================================================
1068 //function : FindInternalIntersections
1070 //=======================================================================
1072 void FindInternalIntersections(const TopoDS_Edge& theEdge,
1073 const TopoDS_Face& theFace,
1074 TopTools_IndexedDataMapOfShapeListOfShape& Splits,
1075 TopTools_DataMapOfShapeShape& GlobalMap,
1076 TopTools_MapOfShape& theMap)
1078 Standard_Real TolExt = Precision::PConfusion();
1079 Standard_Integer i, j, aNbExt;
1081 TColStd_SequenceOfReal SplitPars;
1083 TopoDS_Vertex theVertices [2];
1084 TopExp::Vertices(theEdge, theVertices[0], theVertices[1]);
1085 if (theEdge.Orientation() == TopAbs_REVERSED)
1087 theVertices[0].Reverse();
1088 theVertices[1].Reverse();
1091 thePnt[0] = BRep_Tool::Pnt(theVertices[0]);
1092 thePnt[1] = BRep_Tool::Pnt(theVertices[1]);
1094 BRepAdaptor_Curve2d thePCurve(theEdge, theFace);
1096 BndLib_Add2dCurve::Add(thePCurve, BRep_Tool::Tolerance(theEdge), theBox);
1098 Standard_Real thePar [2];
1099 Standard_Real /*theFpar, theLpar,*/ aFpar, aLpar;
1100 const Handle(Geom_Curve)& theCurve = BRep_Tool::Curve(theEdge, thePar[0], thePar[1]);
1101 GeomAdaptor_Curve theGAcurve(theCurve, thePar[0], thePar[1]);
1103 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
1104 for (; Explo.More(); Explo.Next())
1106 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
1107 BRepAdaptor_Curve2d aPCurve(anEdge, theFace);
1109 BndLib_Add2dCurve::Add(aPCurve, BRep_Tool::Tolerance(anEdge), aBox);
1110 if (theBox.IsOut(aBox))
1113 const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(anEdge, aFpar, aLpar);
1114 GeomAdaptor_Curve aGAcurve(aCurve, aFpar, aLpar);
1115 Extrema_ExtCC anExtrema(theGAcurve, aGAcurve, TolExt, TolExt);
1117 if (!anExtrema.IsDone())
1119 if (anExtrema.IsParallel())
1122 aNbExt = anExtrema.NbExt();
1123 Standard_Real MaxTol = Max(BRep_Tool::Tolerance(theEdge), BRep_Tool::Tolerance(anEdge));
1124 for (i = 1; i <= aNbExt; i++)
1126 Standard_Real aDist = Sqrt(anExtrema.SquareDistance(i));
1130 Extrema_POnCurv aPOnC1, aPOnC2;
1131 anExtrema.Points(i, aPOnC1, aPOnC2);
1132 Standard_Real theIntPar = aPOnC1.Parameter();
1133 Standard_Real anIntPar = aPOnC2.Parameter();
1134 Standard_Boolean IntersFound = Standard_False;
1135 for (j = 0; j < 2; j++) //try to find intersection on an extremity of "theEdge"
1137 if (Abs(theIntPar - thePar[j]) <= Precision::PConfusion() &&
1138 aDist <= Precision::Confusion())
1140 theMap.Add(theVertices[j]);
1141 TopExp_Explorer exp2(anEdge, TopAbs_VERTEX);
1142 for (; exp2.More(); exp2.Next())
1144 const TopoDS_Vertex& aVertex = TopoDS::Vertex(exp2.Current());
1145 if (aVertex.IsSame(theVertices[j]))
1147 IntersFound = Standard_True;
1150 if (BRepTools::Compare(theVertices[j], aVertex))
1152 GlobalMap.Bind(theVertices[j], aVertex);
1153 IntersFound = Standard_True;
1159 GlobalMap.Bind(theVertices[j], anEdge);
1160 IntersFound = Standard_True;
1165 if (!IntersFound) //intersection is inside "theEdge" => split
1167 gp_Pnt aPoint = aCurve->Value(anIntPar);
1168 if (aPoint.Distance(thePnt[0]) > BRep_Tool::Tolerance(theVertices[0]) &&
1169 aPoint.Distance(thePnt[1]) > BRep_Tool::Tolerance(theVertices[1]))
1170 SplitPars.Append(theIntPar);
1175 if (SplitPars.IsEmpty())
1179 for (i = 1; i < SplitPars.Length(); i++)
1180 for (j = i+1; j <= SplitPars.Length(); j++)
1181 if (SplitPars(i) > SplitPars(j))
1183 Standard_Real Tmp = SplitPars(i);
1184 SplitPars(i) = SplitPars(j);
1188 //Remove repeating points
1190 while (i < SplitPars.Length())
1192 gp_Pnt Pnt1 = theCurve->Value(SplitPars(i));
1193 gp_Pnt Pnt2 = theCurve->Value(SplitPars(i+1));
1194 if (Pnt1.Distance(Pnt2) <= Precision::Confusion())
1195 SplitPars.Remove(i+1);
1201 TopTools_ListOfShape NewEdges;
1203 //theVertices[0].Orientation(TopAbs_FORWARD);
1204 //theVertices[1].Orientation(TopAbs_REVERSED);
1205 TopoDS_Vertex FirstVertex = theVertices[0], LastVertex;
1206 Standard_Real FirstPar = thePar[0], LastPar;
1207 for (i = 1; i <= SplitPars.Length()+1; i++)
1209 FirstVertex.Orientation(TopAbs_FORWARD);
1210 if (i <= SplitPars.Length())
1212 LastPar = SplitPars(i);
1213 gp_Pnt LastPoint = theCurve->Value(LastPar);
1214 LastVertex = BRepLib_MakeVertex(LastPoint);
1218 LastPar = thePar[1];
1219 LastVertex = theVertices[1];
1221 LastVertex.Orientation(TopAbs_REVERSED);
1223 TopoDS_Shape aLocalShape = theEdge.EmptyCopied();
1224 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
1225 BB.Range(NewEdge, FirstPar, LastPar);
1226 BB.Add(NewEdge, FirstVertex);
1227 BB.Add(NewEdge, LastVertex);
1229 NewEdges.Append(NewEdge);
1230 FirstVertex = LastVertex;
1234 if (!NewEdges.IsEmpty())
1235 Splits.Add(theEdge, NewEdges);