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),myCheckInterior(Standard_True),myDone(Standard_False)
98 //=======================================================================
101 //=======================================================================
103 void LocOpe_WiresOnShape::Init(const TopoDS_Shape& S)
106 myCheckInterior = Standard_True;
107 myDone = Standard_False;
114 //=======================================================================
117 //=======================================================================
119 void LocOpe_WiresOnShape::Bind(const TopoDS_Wire& W,
120 const TopoDS_Face& F)
122 for (TopExp_Explorer exp(W, TopAbs_EDGE); exp.More(); exp.Next()) {
123 Bind(TopoDS::Edge(exp.Current()),F);
127 //=======================================================================
130 //=======================================================================
132 void LocOpe_WiresOnShape::Bind(const TopoDS_Compound& Comp,
133 const TopoDS_Face& F)
135 for (TopExp_Explorer exp(Comp, TopAbs_EDGE); exp.More(); exp.Next()) {
136 Bind(TopoDS::Edge(exp.Current()),F);
138 myFacesWithSection.Add(F);
141 //=======================================================================
144 //=======================================================================
146 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& E,
147 const TopoDS_Face& F)
149 // if (!myMapEF.IsBound(E)) {
150 if (!myMapEF.Contains(E)) {
151 // for (TopExp_Explorer exp(F,TopAbs_EDGE);exp.More();exp.Next()) {
152 TopExp_Explorer exp(F,TopAbs_EDGE) ;
153 for ( ;exp.More();exp.Next()) {
154 if (exp.Current().IsSame(E)) {
159 // myMapEF.Bind(E,F);
164 Standard_ConstructionError::Raise();
169 //=======================================================================
172 //=======================================================================
174 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& Ewir,
175 const TopoDS_Edge& Efac)
177 if (Ewir.IsSame(Efac)) {
180 myMap.Bind(Ewir,Efac);
184 //=======================================================================
187 //=======================================================================
189 void LocOpe_WiresOnShape::BindAll()
194 TopTools_MapOfShape theMap;
196 // Detection des vertex a projeter ou a "binder" avec des vertex existants
197 TopTools_DataMapOfShapeShape mapV;
198 TopTools_DataMapIteratorOfDataMapOfShapeShape ite(myMap);
199 TopExp_Explorer exp,exp2;
200 for (; ite.More(); ite.Next()) {
201 const TopoDS_Edge& eref = TopoDS::Edge(ite.Key());
202 const TopoDS_Edge& eimg = TopoDS::Edge(ite.Value());
204 PutPCurves(eref,eimg,myShape);
206 for (exp.Init(eref,TopAbs_VERTEX); exp.More(); exp.Next()) {
207 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
208 if (!theMap.Contains(vtx)) { // pas deja traite
209 for (exp2.Init(eimg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
210 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
211 if (vtx2.IsSame(vtx)) {
214 else if (BRepTools::Compare(vtx,vtx2)) {
227 for (ite.Initialize(mapV); ite.More(); ite.Next()) {
228 myMap.Bind(ite.Key(),ite.Value());
231 TopTools_IndexedDataMapOfShapeListOfShape Splits;
232 Standard_Integer Ind;
233 for (Ind = 1; Ind <= myMapEF.Extent(); Ind++)
235 const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
236 const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
239 Standard_Real pf, pl;
240 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(edg, fac, pf, pl);
241 if (aPCurve.IsNull())
245 FindInternalIntersections(edg, fac, Splits, myMap, theMap);
248 for (Ind = 1; Ind <= Splits.Extent(); Ind++)
250 TopoDS_Shape anEdge = Splits.FindKey(Ind);
251 TopoDS_Shape aFace = myMapEF.FindFromKey(anEdge);
252 //Remove "anEdge" from "myMapEF"
253 TopoDS_Shape LastEdge = myMapEF.FindKey(myMapEF.Extent());
254 TopoDS_Shape LastFace = myMapEF(myMapEF.Extent());
255 myMapEF.RemoveLast();
256 if (myMapEF.FindIndex(anEdge) != 0)
257 myMapEF.Substitute(myMapEF.FindIndex(anEdge), LastEdge, LastFace);
258 ////////////////////////////////
259 TopTools_ListIteratorOfListOfShape itl(Splits(Ind));
260 for (; itl.More(); itl.Next())
261 myMapEF.Add(itl.Value(), aFace);
264 // Il faut s`occuper maintenant des vertex "de changement de face",
265 // et des vertex "libres"
266 // TopTools_DataMapIteratorOfDataMapOfShapeShape ite2;
268 // for (ite.Initialize(myMapEF); ite.More(); ite.Next()) {
269 // const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
270 // const TopoDS_Face& fac = TopoDS::Face(ite.Value());
271 for (Ind = 1; Ind <= myMapEF.Extent(); Ind++) {
272 const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
273 const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
274 // JAG 02.02.96 : On verifie les pcurves...
276 //PutPCurve(edg,fac);
278 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
279 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
280 if (theMap.Contains(vtx)) {
285 Standard_Boolean ok = Project(vtx,fac,Epro,prm);
287 for (exp2.Init(Epro,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
288 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
289 if (vtx2.IsSame(vtx)) {
292 else if (BRepTools::Compare(vtx,vtx2)) {
293 myMap.Bind(vtx,vtx2);
298 myMap.Bind(vtx,Epro);
305 // Modified by Sergey KHROMOV - Mon Feb 12 16:26:50 2001 Begin
306 for (ite.Initialize(myMap); ite.More(); ite.Next())
307 if ((ite.Key()).ShapeType() == TopAbs_EDGE)
308 myMapEF.Add(ite.Key(),ite.Value());
309 // Modified by Sergey KHROMOV - Mon Feb 12 16:26:52 2001 End
312 myDone = Standard_True;
317 //=======================================================================
318 //function : InitEdgeIterator
320 //=======================================================================
322 void LocOpe_WiresOnShape::InitEdgeIterator()
325 // myIt.Initialize(myMapEF);
330 //=======================================================================
331 //function : MoreEdge
333 //=======================================================================
335 Standard_Boolean LocOpe_WiresOnShape::MoreEdge()
337 // return myIt.More();
338 return (myIndex <= myMapEF.Extent());
342 //=======================================================================
345 //=======================================================================
347 TopoDS_Edge LocOpe_WiresOnShape::Edge()
349 // return TopoDS::Edge(myIt.Key());
350 return TopoDS::Edge(myMapEF.FindKey(myIndex));
354 //=======================================================================
357 //=======================================================================
359 TopoDS_Face LocOpe_WiresOnShape::OnFace()
361 // return TopoDS::Face(myIt.Value());
362 return TopoDS::Face(myMapEF(myIndex));
366 //=======================================================================
369 //=======================================================================
371 Standard_Boolean LocOpe_WiresOnShape::OnEdge(TopoDS_Edge& E)
373 // if (myMap.IsBound(myIt.Key())) {
374 if (myMap.IsBound(myMapEF.FindKey(myIndex))) {
375 // E = TopoDS::Edge(myMap(myIt.Key()));
376 E = TopoDS::Edge(myMap(myMapEF.FindKey(myIndex)));
377 return Standard_True;
379 return Standard_False;
385 //=======================================================================
386 //function : NextEdge
388 //=======================================================================
390 void LocOpe_WiresOnShape::NextEdge()
398 //=======================================================================
399 //function : OnVertex
401 //=======================================================================
403 Standard_Boolean LocOpe_WiresOnShape::OnVertex(const TopoDS_Vertex& Vw,
406 if (myMap.IsBound(Vw)) {
407 if (myMap(Vw).ShapeType() == TopAbs_VERTEX) {
408 Vs = TopoDS::Vertex(myMap(Vw));
409 return Standard_True;
411 return Standard_False;
413 return Standard_False;
419 //=======================================================================
422 //=======================================================================
424 Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
428 if (!myMap.IsBound(V) ||
429 myMap(V).ShapeType() == TopAbs_VERTEX) {
430 return Standard_False;
433 Ed = TopoDS::Edge(myMap(V));
435 return Standard_True;
439 //=======================================================================
442 //=======================================================================
444 Standard_Boolean Project(const TopoDS_Vertex& V,
445 const TopoDS_Face& F,
446 TopoDS_Edge& theEdge,
447 Standard_Real& param)
449 Handle(Geom_Curve) C;
453 Standard_Real dmin = RealLast();
454 gp_Pnt toproj(BRep_Tool::Pnt(V));
455 Standard_Boolean valret = Standard_False;
456 GeomAPI_ProjectPointOnCurve proj;
458 for (TopExp_Explorer exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
459 exp.More(); exp.Next()) {
460 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
461 if (!BRep_Tool::Degenerated(edg)) {
462 C = BRep_Tool::Curve(edg,Loc,f,l);
463 if (!Loc.IsIdentity()) {
464 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
465 C = *((Handle(Geom_Curve)*)&GG);
467 proj.Init(toproj,C,f,l);
468 if (proj.NbPoints() > 0) {
469 if (proj.LowerDistance() < dmin) {
471 theEdge.Orientation(edg.Orientation());
472 dmin = proj.LowerDistance();
473 param = proj.LowerDistanceParameter();
480 return Standard_False;
482 Standard_Real ttol = BRep_Tool::Tolerance(V) + BRep_Tool::Tolerance(theEdge);
484 valret = Standard_True;
486 B.UpdateVertex(V, Max(dmin, BRep_Tool::Tolerance(V)));
490 cout <<"LocOpe_WiresOnShape::Project --> le vertex projete est a une ";
491 cout <<"distance / la face = "<<dmin <<" superieure a la tolerance = "<<ttol<<endl;
497 //=======================================================================
500 //=======================================================================
502 Standard_Real Project(const TopoDS_Vertex& V,
503 const TopoDS_Edge& theEdge)
505 Handle(Geom_Curve) C;
509 gp_Pnt toproj(BRep_Tool::Pnt(V));
510 GeomAPI_ProjectPointOnCurve proj;
512 C = BRep_Tool::Curve(theEdge,Loc,f,l);
513 if (!Loc.IsIdentity()) {
514 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
515 C = *((Handle(Geom_Curve)*)&GG);
517 proj.Init(toproj,C,f,l);
520 return proj.LowerDistanceParameter();
524 //=======================================================================
525 //function : PutPCurve
527 //=======================================================================
529 void PutPCurve(const TopoDS_Edge& Edg,
530 const TopoDS_Face& Fac)
533 TopLoc_Location LocFac;
535 Handle(Geom_Surface) S = BRep_Tool::Surface(Fac, LocFac);
536 Handle(Standard_Type) styp = S->DynamicType();
538 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
539 S = (*((Handle(Geom_RectangularTrimmedSurface)*)&(S)))->BasisSurface();
540 styp = S->DynamicType();
543 if (styp == STANDARD_TYPE(Geom_Plane)) {
547 Standard_Real Umin,Umax,Vmin,Vmax;
548 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
552 //if (!BRep_Tool::CurveOnSurface(Edg,Fac,f,l).IsNull()) {
555 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(Edg,Fac,f,l);
556 if ( !aC2d.IsNull() ) {
559 Standard_Boolean IsIn = Standard_True;
560 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
561 ( p2d.X() > Umax+Precision::PConfusion() ) )
562 IsIn = Standard_False;
563 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
564 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
565 IsIn = Standard_False;
567 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
568 ( p2d.X() > Umax+Precision::PConfusion() ) )
569 IsIn = Standard_False;
570 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
571 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
572 IsIn = Standard_False;
578 Handle(Geom_Curve) C = BRep_Tool::Curve(Edg,Loc,f,l);
579 if (!Loc.IsIdentity()) {
580 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
581 C = *((Handle(Geom_Curve)*)&GG);
584 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
585 C = new Geom_TrimmedCurve(C,f,l);
588 S = BRep_Tool::Surface(Fac);
591 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Edg),
592 BRep_Tool::Tolerance(Fac));
593 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
594 Standard_Real TolU = Gas.UResolution(tol3d);
595 Standard_Real TolV = Gas.VResolution(tol3d);
596 Standard_Real tol2d = Max(TolU,TolV);
598 Handle(Geom2d_Curve) C2d =
599 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
602 gp_Pnt2d pf(C2d->Value(f));
603 gp_Pnt2d pl(C2d->Value(l));
605 S->D0(pf.X(),pf.Y(),PF);
606 S->D0(pl.X(),pl.Y(),PL);
608 if (Edg.Orientation() == TopAbs_REVERSED) {
609 V1 = TopExp::LastVertex(Edg);
613 V1 = TopExp::FirstVertex (Edg);
615 if (Edg.Orientation() == TopAbs_REVERSED) {
616 V2 = TopExp::FirstVertex(Edg);
620 V2 = TopExp::LastVertex (Edg);
623 if(!V1.IsNull() && V2.IsNull()) {
624 //Handling of internal vertices
625 Standard_Real old1 = BRep_Tool::Tolerance (V1);
626 Standard_Real old2 = BRep_Tool::Tolerance (V2);
627 gp_Pnt pnt1 = BRep_Tool::Pnt (V1);
628 gp_Pnt pnt2 = BRep_Tool::Pnt (V2);
629 Standard_Real tol1 = pnt1.Distance(PF);
630 Standard_Real tol2 = pnt2.Distance(PL);
631 B.UpdateVertex(V1,Max(old1,tol1));
632 B.UpdateVertex(V2,Max(old2,tol2));
635 if (S->IsUPeriodic()) {
636 Standard_Real up = S->UPeriod();
637 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
638 Standard_Integer nbtra = 0;
639 Standard_Real theUmin = Min(pf.X(),pl.X());
640 Standard_Real theUmax = Max(pf.X(),pl.X());
642 if (theUmin < Umin-tolu) {
643 while (theUmin < Umin-tolu) {
648 else if (theUmax > Umax+tolu) {
649 while (theUmax > Umax+tolu) {
656 if (theUmin > Umax-tolu) {
657 while (theUmin > Umax-tolu) {
662 else if (theUmax < Umin+tolu) {
663 while (theUmax < Umin+tolu) {
670 C2d->Translate(gp_Vec2d(nbtra*up,0.));
674 if (S->IsVPeriodic()) {
675 Standard_Real vp = S->VPeriod();
676 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
677 Standard_Integer nbtra = 0;
678 Standard_Real theVmin = Min(pf.Y(),pl.Y());
679 Standard_Real theVmax = Max(pf.Y(),pl.Y());
681 if (theVmin < Vmin-tolv) {
682 while (theVmin < Vmin-tolv) {
683 theVmin += vp; theVmax += vp;
687 else if (theVmax > Vmax+tolv) {
688 while (theVmax > Vmax+tolv) {
689 theVmax -= vp; theVmin -= vp;
694 if (theVmin > Vmax-tolv) {
695 while (theVmin > Vmax-tolv) {
700 else if (theVmax < Vmin+tolv) {
701 while (theVmax < Vmin+tolv) {
708 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
711 B.UpdateEdge(Edg,C2d,Fac,BRep_Tool::Tolerance(Edg));
713 B.SameParameter(Edg,Standard_False);
714 BRepLib::SameParameter(Edg,tol2d);
718 //=======================================================================
719 //function : PutPCurves
721 //=======================================================================
723 void PutPCurves(const TopoDS_Edge& Efrom,
724 const TopoDS_Edge& Eto,
725 const TopoDS_Shape& myShape)
728 TopTools_ListOfShape Lfaces;
729 TopExp_Explorer exp,exp2;
731 for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
732 for (exp2.Init(exp.Current(), TopAbs_EDGE); exp2.More();exp2.Next()) {
733 if (exp2.Current().IsSame(Eto)) {
734 Lfaces.Append(exp.Current());
739 if (Lfaces.Extent() != 1 && Lfaces.Extent() !=2) {
740 Standard_ConstructionError::Raise();
743 // soit bord libre, soit connexite entre 2 faces, eventuellement edge closed
745 if (Lfaces.Extent() ==1) {
746 return; // sera fait par PutPCurve.... on l`espere
750 Handle(Geom_Surface) S;
751 Handle(Standard_Type) styp;
752 Handle(Geom_Curve) C;
753 Standard_Real Umin,Umax,Vmin,Vmax;
755 TopLoc_Location Loc, LocFac;
757 if (!Lfaces.First().IsSame(Lfaces.Last())) {
758 TopTools_ListIteratorOfListOfShape itl(Lfaces);
759 for (; itl.More(); itl.Next()) {
760 const TopoDS_Face& Fac = TopoDS::Face(itl.Value());
762 if (!BRep_Tool::CurveOnSurface(Efrom,Fac,f,l).IsNull()) {
765 S = BRep_Tool::Surface(Fac, LocFac);
766 styp = S->DynamicType();
767 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
768 S = (*((Handle(Geom_RectangularTrimmedSurface)*)&(S)))->BasisSurface();
769 styp = S->DynamicType();
771 if (styp == STANDARD_TYPE(Geom_Plane)) {
776 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
777 C = BRep_Tool::Curve(Efrom,Loc,f,l);
778 if (!Loc.IsIdentity()) {
779 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
780 C = *((Handle(Geom_Curve)*)&GG);
783 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
784 C = new Geom_TrimmedCurve(C,f,l);
787 S = BRep_Tool::Surface(Fac);
790 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
791 BRep_Tool::Tolerance(Fac));
792 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
793 Standard_Real TolU = Gas.UResolution(tol3d);
794 Standard_Real TolV = Gas.VResolution(tol3d);
795 Standard_Real tol2d = Max(TolU,TolV);
797 Handle(Geom2d_Curve) C2d =
798 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
802 gp_Pnt2d pf(C2d->Value(f));
803 gp_Pnt2d pl(C2d->Value(l));
805 if (S->IsUPeriodic()) {
806 Standard_Real up = S->UPeriod();
807 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
808 Standard_Integer nbtra = 0;
809 Standard_Real theUmin = Min(pf.X(),pl.X());
810 Standard_Real theUmax = Max(pf.X(),pl.X());
812 if (theUmin < Umin-tolu) {
813 while (theUmin < Umin-tolu) {
814 theUmin += up; theUmax += up;
818 else if (theUmax > Umax+tolu) {
819 while (theUmax > Umax+tolu) {
820 theUmax -= up; theUmin -= up;
825 if (theUmin > Umax+tolu) {
826 while (theUmin > Umax+tolu) {
831 else if (theUmax < Umin-tolu) {
832 while (theUmax < Umin-tolu) {
839 C2d->Translate(gp_Vec2d(nbtra*up,0.));
843 if (S->IsVPeriodic()) {
844 Standard_Real vp = S->VPeriod();
845 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
846 Standard_Integer nbtra = 0;
847 Standard_Real theVmin = Min(pf.Y(),pl.Y());
848 Standard_Real theVmax = Max(pf.Y(),pl.Y());
850 if (theVmin < Vmin-tolv) {
851 while (theVmin < Vmin-tolv) {
852 theVmin += vp; theVmax += vp;
856 else if (theVmax > Vmax+tolv) {
857 while (theVmax > Vmax+tolv) {
858 theVmax -= vp; theVmin -= vp;
863 if (theVmin > Vmax+tolv) {
864 while (theVmin > Vmax+tolv) {
869 else if (theVmax < Vmin-tolv) {
870 while (theVmax < Vmin-tolv) {
877 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
880 B.UpdateEdge(Efrom,C2d,Fac,BRep_Tool::Tolerance(Efrom));
885 const TopoDS_Face& Fac = TopoDS::Face(Lfaces.First());
886 if (!BRep_Tool::IsClosed(Eto,Fac)) {
887 Standard_ConstructionError::Raise();
890 TopoDS_Shape aLocalE = Efrom.Oriented(TopAbs_FORWARD);
891 TopoDS_Shape aLocalF = Fac.Oriented(TopAbs_FORWARD);
892 Handle(Geom2d_Curve) c2dff =
893 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
894 TopoDS::Face(aLocalF),
897 // Handle(Geom2d_Curve) c2dff =
898 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_FORWARD)),
899 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
902 aLocalE = Efrom.Oriented(TopAbs_REVERSED);
903 aLocalF = Fac.Oriented(TopAbs_FORWARD);
904 Handle(Geom2d_Curve) c2dfr =
905 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
906 TopoDS::Face(aLocalF),
908 // Handle(Geom2d_Curve) c2dfr =
909 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_REVERSED)),
910 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
913 aLocalE = Eto.Oriented(TopAbs_FORWARD);
914 aLocalF = Fac.Oriented(TopAbs_FORWARD);
915 Handle(Geom2d_Curve) c2dtf =
916 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
917 TopoDS::Face(aLocalF),
920 // Handle(Geom2d_Curve) c2dtf =
921 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_FORWARD)),
922 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
924 aLocalE = Eto.Oriented(TopAbs_REVERSED);
925 aLocalF = Fac.Oriented(TopAbs_FORWARD);
926 Handle(Geom2d_Curve) c2dtr =
927 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
928 TopoDS::Face(aLocalF),
930 // Handle(Geom2d_Curve) c2dtr =
931 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_REVERSED)),
932 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
935 gp_Pnt2d ptf(c2dtf->Value(f)); // sur courbe frw
936 gp_Pnt2d ptr(c2dtr->Value(f)); // sur courbe rev
938 Standard_Boolean isoU = (Abs(ptf.Y()-ptr.Y())<Epsilon(ptf.X())); // meme V
940 // Efrom et Eto dans le meme sens???
942 C = BRep_Tool::Curve(Efrom,Loc,f,l);
943 if (!Loc.IsIdentity()) {
944 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
945 C = *((Handle(Geom_Curve)*)&GG);
953 Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),Eto);
955 C = BRep_Tool::Curve(Eto,Loc,f,l);
956 if (!Loc.IsIdentity()) {
957 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
958 C = *((Handle(Geom_Curve)*)&GG);
961 C->D1(prmproj,pt,d1t);
963 Standard_Real SameOri = (d1t.Dot(d1f)>0.);
966 if (c2dff.IsNull() && c2dfr.IsNull()) {
967 S = BRep_Tool::Surface(Fac);
968 styp = S->DynamicType();
969 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
970 S = (*((Handle(Geom_RectangularTrimmedSurface)*)&(S)))->BasisSurface();
971 styp = S->DynamicType();
974 C = BRep_Tool::Curve(Efrom,Loc,f,l);
975 if (!Loc.IsIdentity()) {
976 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
977 C = *((Handle(Geom_Curve)*)&GG);
980 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
981 C = new Geom_TrimmedCurve(C,f,l);
985 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
987 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
988 BRep_Tool::Tolerance(Fac));
989 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
990 Standard_Real TolU = Gas.UResolution(tol3d);
991 Standard_Real TolV = Gas.VResolution(tol3d);
992 Standard_Real tol2d = Max(TolU,TolV);
994 Handle(Geom2d_Curve) C2d =
995 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
999 else if (c2dfr.IsNull()) {
1003 else if (c2dff.IsNull()) {
1007 BRep_Tool::Range(Efrom,f,l);
1009 gp_Pnt2d p2f = c2dff->Value(f);
1010 gp_Pnt2d p2r = c2dfr->Value(f);
1014 if (Abs(ptf.X()-p2f.X()) > Epsilon(ptf.X())) {
1015 c2dff = Handle(Geom2d_Curve)::DownCast
1016 (c2dff->Translated(gp_Vec2d(ptf.X()-p2f.X(),0.)));
1018 if (Abs(ptr.X()-p2r.X()) > Epsilon(ptr.X())) {
1019 c2dfr = Handle(Geom2d_Curve)::DownCast
1020 (c2dfr->Translated(gp_Vec2d(ptr.X()-p2r.X(),0.)));
1024 if (Abs(ptr.X()-p2f.X()) > Epsilon(ptr.X())) {
1025 c2dff = Handle(Geom2d_Curve)::DownCast
1026 (c2dff->Translated(gp_Vec2d(ptr.X()-p2f.X(),0.)));
1029 if (Abs(ptf.X()-p2r.X()) > Epsilon(ptf.X())) {
1030 c2dfr = Handle(Geom2d_Curve)::DownCast
1031 (c2dfr->Translated(gp_Vec2d(ptf.X()-p2r.X(),0.)));
1035 // on est bien en U, recalage si periodique en V a faire
1041 else { // !isoU soit isoV
1043 if (Abs(ptf.Y()-p2f.Y()) > Epsilon(ptf.Y())) {
1044 c2dff = Handle(Geom2d_Curve)::DownCast
1045 (c2dff->Translated(gp_Vec2d(0.,ptf.Y()-p2f.Y())));
1047 if (Abs(ptr.Y()-p2r.Y()) > Epsilon(ptr.Y())) {
1048 c2dfr = Handle(Geom2d_Curve)::DownCast
1049 (c2dfr->Translated(gp_Vec2d(0.,ptr.Y()-p2r.Y())));
1053 if (Abs(ptr.Y()-p2f.Y()) > Epsilon(ptr.Y())) {
1054 c2dff = Handle(Geom2d_Curve)::DownCast
1055 (c2dff->Translated(gp_Vec2d(0.,ptr.Y()-p2f.Y())));
1057 if (Abs(ptf.Y()-p2r.Y()) > Epsilon(ptf.Y())) {
1058 c2dfr = Handle(Geom2d_Curve)::DownCast
1059 (c2dfr->Translated(gp_Vec2d(0.,ptf.Y()-p2r.Y())));
1062 // on est bien en V, recalage si periodique en U a faire
1065 B.UpdateEdge(Efrom,c2dff,c2dfr,Fac,BRep_Tool::Tolerance(Efrom));
1069 //=======================================================================
1070 //function : FindInternalIntersections
1072 //=======================================================================
1074 void FindInternalIntersections(const TopoDS_Edge& theEdge,
1075 const TopoDS_Face& theFace,
1076 TopTools_IndexedDataMapOfShapeListOfShape& Splits,
1077 TopTools_DataMapOfShapeShape& GlobalMap,
1078 TopTools_MapOfShape& theMap)
1080 Standard_Real TolExt = Precision::PConfusion();
1081 Standard_Integer i, j, aNbExt;
1083 TColStd_SequenceOfReal SplitPars;
1085 TopoDS_Vertex theVertices [2];
1086 TopExp::Vertices(theEdge, theVertices[0], theVertices[1]);
1087 if (theEdge.Orientation() == TopAbs_REVERSED)
1089 theVertices[0].Reverse();
1090 theVertices[1].Reverse();
1093 thePnt[0] = BRep_Tool::Pnt(theVertices[0]);
1094 thePnt[1] = BRep_Tool::Pnt(theVertices[1]);
1096 BRepAdaptor_Curve2d thePCurve(theEdge, theFace);
1098 BndLib_Add2dCurve::Add(thePCurve, BRep_Tool::Tolerance(theEdge), theBox);
1100 Standard_Real thePar [2];
1101 Standard_Real /*theFpar, theLpar,*/ aFpar, aLpar;
1102 const Handle(Geom_Curve)& theCurve = BRep_Tool::Curve(theEdge, thePar[0], thePar[1]);
1103 GeomAdaptor_Curve theGAcurve(theCurve, thePar[0], thePar[1]);
1105 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
1106 for (; Explo.More(); Explo.Next())
1108 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
1109 BRepAdaptor_Curve2d aPCurve(anEdge, theFace);
1111 BndLib_Add2dCurve::Add(aPCurve, BRep_Tool::Tolerance(anEdge), aBox);
1112 if (theBox.IsOut(aBox))
1115 const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(anEdge, aFpar, aLpar);
1116 GeomAdaptor_Curve aGAcurve(aCurve, aFpar, aLpar);
1117 Extrema_ExtCC anExtrema(theGAcurve, aGAcurve, TolExt, TolExt);
1119 if (!anExtrema.IsDone())
1121 if (anExtrema.IsParallel())
1124 aNbExt = anExtrema.NbExt();
1125 Standard_Real MaxTol = Max(BRep_Tool::Tolerance(theEdge), BRep_Tool::Tolerance(anEdge));
1126 for (i = 1; i <= aNbExt; i++)
1128 Standard_Real aDist = Sqrt(anExtrema.SquareDistance(i));
1132 Extrema_POnCurv aPOnC1, aPOnC2;
1133 anExtrema.Points(i, aPOnC1, aPOnC2);
1134 Standard_Real theIntPar = aPOnC1.Parameter();
1135 Standard_Real anIntPar = aPOnC2.Parameter();
1136 Standard_Boolean IntersFound = Standard_False;
1137 for (j = 0; j < 2; j++) //try to find intersection on an extremity of "theEdge"
1139 if (Abs(theIntPar - thePar[j]) <= Precision::PConfusion() &&
1140 aDist <= Precision::Confusion())
1142 theMap.Add(theVertices[j]);
1143 TopExp_Explorer exp2(anEdge, TopAbs_VERTEX);
1144 for (; exp2.More(); exp2.Next())
1146 const TopoDS_Vertex& aVertex = TopoDS::Vertex(exp2.Current());
1147 if (aVertex.IsSame(theVertices[j]))
1149 IntersFound = Standard_True;
1152 if (BRepTools::Compare(theVertices[j], aVertex))
1154 GlobalMap.Bind(theVertices[j], aVertex);
1155 IntersFound = Standard_True;
1161 GlobalMap.Bind(theVertices[j], anEdge);
1162 IntersFound = Standard_True;
1167 if (!IntersFound) //intersection is inside "theEdge" => split
1169 gp_Pnt aPoint = aCurve->Value(anIntPar);
1170 if (aPoint.Distance(thePnt[0]) > BRep_Tool::Tolerance(theVertices[0]) &&
1171 aPoint.Distance(thePnt[1]) > BRep_Tool::Tolerance(theVertices[1]))
1172 SplitPars.Append(theIntPar);
1177 if (SplitPars.IsEmpty())
1181 for (i = 1; i < SplitPars.Length(); i++)
1182 for (j = i+1; j <= SplitPars.Length(); j++)
1183 if (SplitPars(i) > SplitPars(j))
1185 Standard_Real Tmp = SplitPars(i);
1186 SplitPars(i) = SplitPars(j);
1190 //Remove repeating points
1192 while (i < SplitPars.Length())
1194 gp_Pnt Pnt1 = theCurve->Value(SplitPars(i));
1195 gp_Pnt Pnt2 = theCurve->Value(SplitPars(i+1));
1196 if (Pnt1.Distance(Pnt2) <= Precision::Confusion())
1197 SplitPars.Remove(i+1);
1203 TopTools_ListOfShape NewEdges;
1205 //theVertices[0].Orientation(TopAbs_FORWARD);
1206 //theVertices[1].Orientation(TopAbs_REVERSED);
1207 TopoDS_Vertex FirstVertex = theVertices[0], LastVertex;
1208 Standard_Real FirstPar = thePar[0], LastPar;
1209 for (i = 1; i <= SplitPars.Length()+1; i++)
1211 FirstVertex.Orientation(TopAbs_FORWARD);
1212 if (i <= SplitPars.Length())
1214 LastPar = SplitPars(i);
1215 gp_Pnt LastPoint = theCurve->Value(LastPar);
1216 LastVertex = BRepLib_MakeVertex(LastPoint);
1220 LastPar = thePar[1];
1221 LastVertex = theVertices[1];
1223 LastVertex.Orientation(TopAbs_REVERSED);
1225 TopoDS_Shape aLocalShape = theEdge.EmptyCopied();
1226 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
1227 BB.Range(NewEdge, FirstPar, LastPar);
1228 BB.Add(NewEdge, FirstVertex);
1229 BB.Add(NewEdge, LastVertex);
1231 NewEdges.Append(NewEdge);
1232 FirstVertex = LastVertex;
1236 if (!NewEdges.IsEmpty())
1237 Splits.Add(theEdge, NewEdges);