1 // Created on: 1996-01-11
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1996-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.
18 #include <Bnd_Box2d.hxx>
19 #include <BndLib_Add2dCurve.hxx>
20 #include <BRep_Builder.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepAdaptor_Curve2d.hxx>
23 #include <BRepLib.hxx>
24 #include <BRepLib_MakeVertex.hxx>
25 #include <BRepTools.hxx>
26 #include <Extrema_ExtCC.hxx>
27 #include <Geom2d_Curve.hxx>
28 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
29 #include <Geom_Curve.hxx>
30 #include <Geom_Plane.hxx>
31 #include <Geom_RectangularTrimmedSurface.hxx>
32 #include <Geom_Surface.hxx>
33 #include <Geom_TrimmedCurve.hxx>
34 #include <GeomAdaptor_Surface.hxx>
35 #include <GeomAPI_ProjectPointOnCurve.hxx>
36 #include <GeomProjLib.hxx>
37 #include <gp_Pnt2d.hxx>
39 #include <gp_Vec2d.hxx>
41 #include <LocOpe_WiresOnShape.hxx>
42 #include <Precision.hxx>
43 #include <Standard_ConstructionError.hxx>
44 #include <Standard_Type.hxx>
46 #include <TopExp_Explorer.hxx>
48 #include <TopoDS_Compound.hxx>
49 #include <TopoDS_Edge.hxx>
50 #include <TopoDS_Face.hxx>
51 #include <TopoDS_Shape.hxx>
52 #include <TopoDS_Vertex.hxx>
53 #include <TopoDS_Wire.hxx>
54 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
55 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
56 #include <TopTools_ListIteratorOfListOfShape.hxx>
57 #include <TopTools_ListOfShape.hxx>
58 #include <TopTools_MapOfShape.hxx>
60 IMPLEMENT_STANDARD_RTTIEXT(LocOpe_WiresOnShape,MMgt_TShared)
62 static Standard_Boolean Project(const TopoDS_Vertex&,
68 static Standard_Real Project(const TopoDS_Vertex&,
71 static Standard_Real Project(const TopoDS_Vertex&,
77 static void PutPCurve(const TopoDS_Edge&,
81 static void PutPCurves(const TopoDS_Edge&,
85 static void FindInternalIntersections(const TopoDS_Edge&,
87 TopTools_IndexedDataMapOfShapeListOfShape&,
88 TopTools_DataMapOfShapeShape&,
89 TopTools_MapOfShape&);
91 //=======================================================================
92 //function : LocOpe_WiresOnShape
94 //=======================================================================
96 LocOpe_WiresOnShape::LocOpe_WiresOnShape(const TopoDS_Shape& S):
97 myShape(S),myCheckInterior(Standard_True),myDone(Standard_False)
102 //=======================================================================
105 //=======================================================================
107 void LocOpe_WiresOnShape::Init(const TopoDS_Shape& S)
110 myCheckInterior = Standard_True;
111 myDone = Standard_False;
118 //=======================================================================
121 //=======================================================================
123 void LocOpe_WiresOnShape::Bind(const TopoDS_Wire& W,
124 const TopoDS_Face& F)
126 for (TopExp_Explorer exp(W, TopAbs_EDGE); exp.More(); exp.Next()) {
127 Bind(TopoDS::Edge(exp.Current()),F);
131 //=======================================================================
134 //=======================================================================
136 void LocOpe_WiresOnShape::Bind(const TopoDS_Compound& Comp,
137 const TopoDS_Face& F)
139 for (TopExp_Explorer exp(Comp, TopAbs_EDGE); exp.More(); exp.Next()) {
140 Bind(TopoDS::Edge(exp.Current()),F);
142 myFacesWithSection.Add(F);
145 //=======================================================================
148 //=======================================================================
150 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& E,
151 const TopoDS_Face& F)
153 // if (!myMapEF.IsBound(E)) {
154 if (!myMapEF.Contains(E)) {
155 // for (TopExp_Explorer exp(F,TopAbs_EDGE);exp.More();exp.Next()) {
156 TopExp_Explorer exp(F,TopAbs_EDGE) ;
157 for ( ;exp.More();exp.Next()) {
158 if (exp.Current().IsSame(E)) {
163 // myMapEF.Bind(E,F);
168 Standard_ConstructionError::Raise();
173 //=======================================================================
176 //=======================================================================
178 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& Ewir,
179 const TopoDS_Edge& Efac)
181 myMap.Bind(Ewir,Efac);
185 //=======================================================================
188 //=======================================================================
190 void LocOpe_WiresOnShape::BindAll()
195 TopTools_MapOfShape theMap;
197 // Detection des vertex a projeter ou a "binder" avec des vertex existants
198 TopTools_DataMapOfShapeShape mapV;
199 TopTools_DataMapIteratorOfDataMapOfShapeShape ite(myMap);
200 TopExp_Explorer exp,exp2;
201 for (; ite.More(); ite.Next()) {
202 const TopoDS_Edge& eref = TopoDS::Edge(ite.Key());
203 const TopoDS_Edge& eimg = TopoDS::Edge(ite.Value());
205 PutPCurves(eref,eimg,myShape);
207 for (exp.Init(eref,TopAbs_VERTEX); exp.More(); exp.Next()) {
208 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
209 if (!theMap.Contains(vtx)) { // pas deja traite
210 for (exp2.Init(eimg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
211 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
212 if (vtx2.IsSame(vtx)) {
215 else if (BRepTools::Compare(vtx,vtx2)) {
228 for (ite.Initialize(mapV); ite.More(); ite.Next()) {
229 myMap.Bind(ite.Key(),ite.Value());
232 TopTools_IndexedDataMapOfShapeListOfShape Splits;
233 Standard_Integer Ind;
234 for (Ind = 1; Ind <= myMapEF.Extent(); Ind++)
236 const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
237 const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
240 Standard_Real pf, pl;
241 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(edg, fac, pf, pl);
242 if (aPCurve.IsNull())
246 FindInternalIntersections(edg, fac, Splits, myMap, theMap);
249 for (Ind = 1; Ind <= Splits.Extent(); Ind++)
251 TopoDS_Shape anEdge = Splits.FindKey(Ind);
252 TopoDS_Shape aFace = myMapEF.FindFromKey(anEdge);
253 //Remove "anEdge" from "myMapEF"
254 TopoDS_Shape LastEdge = myMapEF.FindKey(myMapEF.Extent());
255 TopoDS_Shape LastFace = myMapEF(myMapEF.Extent());
256 myMapEF.RemoveLast();
257 if (myMapEF.FindIndex(anEdge) != 0)
258 myMapEF.Substitute(myMapEF.FindIndex(anEdge), LastEdge, LastFace);
259 ////////////////////////////////
260 TopTools_ListIteratorOfListOfShape itl(Splits(Ind));
261 for (; itl.More(); itl.Next())
262 myMapEF.Add(itl.Value(), aFace);
265 // Il faut s`occuper maintenant des vertex "de changement de face",
266 // et des vertex "libres"
267 // TopTools_DataMapIteratorOfDataMapOfShapeShape ite2;
269 // for (ite.Initialize(myMapEF); ite.More(); ite.Next()) {
270 // const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
271 // const TopoDS_Face& fac = TopoDS::Face(ite.Value());
272 for (Ind = 1; Ind <= myMapEF.Extent(); Ind++) {
273 const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
274 const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
275 // JAG 02.02.96 : On verifie les pcurves...
277 //PutPCurve(edg,fac);
279 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
280 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
281 if (theMap.Contains(vtx)) {
285 Standard_Real vtx_param = BRep_Tool::Parameter(vtx, edg);
286 BRepAdaptor_Curve2d BAcurve2d(edg, fac);
287 gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
290 Standard_Real prm = 0.;
291 Standard_Boolean ok = Project(vtx, p2d, fac, Epro, prm);
293 for (exp2.Init(Epro,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
294 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
295 if (vtx2.IsSame(vtx)) {
298 else if (BRepTools::Compare(vtx,vtx2)) {
299 if (!BRep_Tool::Degenerated(Epro) ||
300 Abs(prm-BAcurve2d.FirstParameter()) <= Precision::PConfusion() ||
301 Abs(prm-BAcurve2d.LastParameter()) <= Precision::PConfusion())
303 myMap.Bind(vtx,vtx2);
309 myMap.Bind(vtx,Epro);
316 // Modified by Sergey KHROMOV - Mon Feb 12 16:26:50 2001 Begin
317 for (ite.Initialize(myMap); ite.More(); ite.Next())
318 if ((ite.Key()).ShapeType() == TopAbs_EDGE)
319 myMapEF.Add(ite.Key(),ite.Value());
320 // Modified by Sergey KHROMOV - Mon Feb 12 16:26:52 2001 End
323 myDone = Standard_True;
328 //=======================================================================
329 //function : InitEdgeIterator
331 //=======================================================================
333 void LocOpe_WiresOnShape::InitEdgeIterator()
336 // myIt.Initialize(myMapEF);
341 //=======================================================================
342 //function : MoreEdge
344 //=======================================================================
346 Standard_Boolean LocOpe_WiresOnShape::MoreEdge()
348 // return myIt.More();
349 return (myIndex <= myMapEF.Extent());
353 //=======================================================================
356 //=======================================================================
358 TopoDS_Edge LocOpe_WiresOnShape::Edge()
360 // return TopoDS::Edge(myIt.Key());
361 return TopoDS::Edge(myMapEF.FindKey(myIndex));
365 //=======================================================================
368 //=======================================================================
370 TopoDS_Face LocOpe_WiresOnShape::OnFace()
372 // return TopoDS::Face(myIt.Value());
373 return TopoDS::Face(myMapEF(myIndex));
377 //=======================================================================
380 //=======================================================================
382 Standard_Boolean LocOpe_WiresOnShape::OnEdge(TopoDS_Edge& E)
384 // if (myMap.IsBound(myIt.Key())) {
385 if (myMap.IsBound(myMapEF.FindKey(myIndex))) {
386 // E = TopoDS::Edge(myMap(myIt.Key()));
387 E = TopoDS::Edge(myMap(myMapEF.FindKey(myIndex)));
388 return Standard_True;
390 return Standard_False;
396 //=======================================================================
397 //function : NextEdge
399 //=======================================================================
401 void LocOpe_WiresOnShape::NextEdge()
409 //=======================================================================
410 //function : OnVertex
412 //=======================================================================
414 Standard_Boolean LocOpe_WiresOnShape::OnVertex(const TopoDS_Vertex& Vw,
417 if (myMap.IsBound(Vw)) {
418 if (myMap(Vw).ShapeType() == TopAbs_VERTEX) {
419 Vs = TopoDS::Vertex(myMap(Vw));
420 return Standard_True;
422 return Standard_False;
424 return Standard_False;
428 //=======================================================================
431 //=======================================================================
433 Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
437 if (!myMap.IsBound(V) ||
438 myMap(V).ShapeType() == TopAbs_VERTEX) {
439 return Standard_False;
442 Ed = TopoDS::Edge(myMap(V));
444 return Standard_True;
447 //=======================================================================
450 //=======================================================================
452 Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
453 const TopoDS_Edge& EdgeFrom,
457 if (!myMap.IsBound(V) ||
458 myMap(V).ShapeType() == TopAbs_VERTEX) {
459 return Standard_False;
462 Ed = TopoDS::Edge(myMap(V));
463 TopoDS_Face theFace = TopoDS::Face(myMapEF.FindFromKey(EdgeFrom));
465 Standard_Real vtx_param = BRep_Tool::Parameter(V, EdgeFrom);
466 BRepAdaptor_Curve2d BAcurve2d(EdgeFrom, theFace);
467 gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
469 prm = Project(V, p2d, Ed, theFace);
470 return Standard_True;
474 //=======================================================================
477 //=======================================================================
479 Standard_Boolean Project(const TopoDS_Vertex& V,
481 const TopoDS_Face& F,
482 TopoDS_Edge& theEdge,
483 Standard_Real& param)
485 Handle(Geom2d_Curve) PC;
486 //TopLoc_Location Loc;
489 Standard_Real dmin = RealLast();
490 //gp_Pnt toproj(BRep_Tool::Pnt(V));
491 Standard_Boolean valret = Standard_False;
492 Geom2dAPI_ProjectPointOnCurve proj;
494 for (TopExp_Explorer exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
495 exp.More(); exp.Next()) {
496 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
497 //C = BRep_Tool::Curve(edg,Loc,f,l);
498 PC = BRep_Tool::CurveOnSurface(edg, F, f, l);
499 proj.Init(p2d, PC, f, l);
500 if (proj.NbPoints() > 0) {
501 if (proj.LowerDistance() < dmin) {
503 theEdge.Orientation(edg.Orientation());
504 dmin = proj.LowerDistance();
505 param = proj.LowerDistanceParameter();
511 return Standard_False;
513 Standard_Real ttol = BRep_Tool::Tolerance(V) + BRep_Tool::Tolerance(theEdge);
515 valret = Standard_True;
517 B.UpdateVertex(V, Max(dmin, BRep_Tool::Tolerance(V)));
519 #ifdef OCCT_DEBUG_MESH
521 cout <<"LocOpe_WiresOnShape::Project --> le vertex projete est a une ";
522 cout <<"distance / la face = "<<dmin <<" superieure a la tolerance = "<<ttol<<endl;
528 //=======================================================================
531 //=======================================================================
533 Standard_Real Project(const TopoDS_Vertex& V,
534 const TopoDS_Edge& theEdge)
536 Handle(Geom_Curve) C;
540 gp_Pnt toproj(BRep_Tool::Pnt(V));
541 GeomAPI_ProjectPointOnCurve proj;
543 C = BRep_Tool::Curve(theEdge,Loc,f,l);
544 if (!Loc.IsIdentity()) {
545 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
546 C = Handle(Geom_Curve)::DownCast (GG);
548 proj.Init(toproj,C,f,l);
551 return proj.LowerDistanceParameter();
554 //=======================================================================
557 //=======================================================================
559 Standard_Real Project(const TopoDS_Vertex&,
561 const TopoDS_Edge& theEdge,
562 const TopoDS_Face& theFace)
564 //Handle(Geom_Curve) C;
565 Handle(Geom2d_Curve) PC;
566 //TopLoc_Location Loc;
569 Geom2dAPI_ProjectPointOnCurve proj;
571 PC = BRep_Tool::CurveOnSurface(theEdge, theFace, f, l);
573 if (!Loc.IsIdentity()) {
574 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
575 C = Handle(Geom_Curve)::DownCast (GG);
578 proj.Init(p2d, PC, f, l);
580 return proj.LowerDistanceParameter();
584 //=======================================================================
585 //function : PutPCurve
587 //=======================================================================
589 void PutPCurve(const TopoDS_Edge& Edg,
590 const TopoDS_Face& Fac)
593 TopLoc_Location LocFac;
595 Handle(Geom_Surface) S = BRep_Tool::Surface(Fac, LocFac);
596 Handle(Standard_Type) styp = S->DynamicType();
598 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
599 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
600 styp = S->DynamicType();
603 if (styp == STANDARD_TYPE(Geom_Plane)) {
607 Standard_Real Umin,Umax,Vmin,Vmax;
608 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
612 //if (!BRep_Tool::CurveOnSurface(Edg,Fac,f,l).IsNull()) {
615 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(Edg,Fac,f,l);
616 if ( !aC2d.IsNull() ) {
619 Standard_Boolean IsIn = Standard_True;
620 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
621 ( p2d.X() > Umax+Precision::PConfusion() ) )
622 IsIn = Standard_False;
623 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
624 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
625 IsIn = Standard_False;
627 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
628 ( p2d.X() > Umax+Precision::PConfusion() ) )
629 IsIn = Standard_False;
630 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
631 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
632 IsIn = Standard_False;
638 Handle(Geom_Curve) C = BRep_Tool::Curve(Edg,Loc,f,l);
639 if (!Loc.IsIdentity()) {
640 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
641 C = Handle(Geom_Curve)::DownCast (GG);
644 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
645 C = new Geom_TrimmedCurve(C,f,l);
648 S = BRep_Tool::Surface(Fac);
651 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Edg),
652 BRep_Tool::Tolerance(Fac));
653 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
654 Standard_Real TolU = Gas.UResolution(tol3d);
655 Standard_Real TolV = Gas.VResolution(tol3d);
656 Standard_Real tol2d = Max(TolU,TolV);
658 Handle(Geom2d_Curve) C2d =
659 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
662 gp_Pnt2d pf(C2d->Value(f));
663 gp_Pnt2d pl(C2d->Value(l));
665 S->D0(pf.X(),pf.Y(),PF);
666 S->D0(pl.X(),pl.Y(),PL);
668 if (Edg.Orientation() == TopAbs_REVERSED) {
669 V1 = TopExp::LastVertex(Edg);
673 V1 = TopExp::FirstVertex (Edg);
675 if (Edg.Orientation() == TopAbs_REVERSED) {
676 V2 = TopExp::FirstVertex(Edg);
680 V2 = TopExp::LastVertex (Edg);
683 if(!V1.IsNull() && V2.IsNull()) {
684 //Handling of internal vertices
685 Standard_Real old1 = BRep_Tool::Tolerance (V1);
686 Standard_Real old2 = BRep_Tool::Tolerance (V2);
687 gp_Pnt pnt1 = BRep_Tool::Pnt (V1);
688 gp_Pnt pnt2 = BRep_Tool::Pnt (V2);
689 Standard_Real tol1 = pnt1.Distance(PF);
690 Standard_Real tol2 = pnt2.Distance(PL);
691 B.UpdateVertex(V1,Max(old1,tol1));
692 B.UpdateVertex(V2,Max(old2,tol2));
695 if (S->IsUPeriodic()) {
696 Standard_Real up = S->UPeriod();
697 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
698 Standard_Integer nbtra = 0;
699 Standard_Real theUmin = Min(pf.X(),pl.X());
700 Standard_Real theUmax = Max(pf.X(),pl.X());
702 if (theUmin < Umin-tolu) {
703 while (theUmin < Umin-tolu) {
708 else if (theUmax > Umax+tolu) {
709 while (theUmax > Umax+tolu) {
716 if (theUmin > Umax-tolu) {
717 while (theUmin > Umax-tolu) {
722 else if (theUmax < Umin+tolu) {
723 while (theUmax < Umin+tolu) {
730 C2d->Translate(gp_Vec2d(nbtra*up,0.));
734 if (S->IsVPeriodic()) {
735 Standard_Real vp = S->VPeriod();
736 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
737 Standard_Integer nbtra = 0;
738 Standard_Real theVmin = Min(pf.Y(),pl.Y());
739 Standard_Real theVmax = Max(pf.Y(),pl.Y());
741 if (theVmin < Vmin-tolv) {
742 while (theVmin < Vmin-tolv) {
743 theVmin += vp; theVmax += vp;
747 else if (theVmax > Vmax+tolv) {
748 while (theVmax > Vmax+tolv) {
749 theVmax -= vp; theVmin -= vp;
754 if (theVmin > Vmax-tolv) {
755 while (theVmin > Vmax-tolv) {
760 else if (theVmax < Vmin+tolv) {
761 while (theVmax < Vmin+tolv) {
768 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
771 B.UpdateEdge(Edg,C2d,Fac,BRep_Tool::Tolerance(Edg));
773 B.SameParameter(Edg,Standard_False);
774 BRepLib::SameParameter(Edg,tol2d);
778 //=======================================================================
779 //function : PutPCurves
781 //=======================================================================
783 void PutPCurves(const TopoDS_Edge& Efrom,
784 const TopoDS_Edge& Eto,
785 const TopoDS_Shape& myShape)
788 TopTools_ListOfShape Lfaces;
789 TopExp_Explorer exp,exp2;
791 for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
792 for (exp2.Init(exp.Current(), TopAbs_EDGE); exp2.More();exp2.Next()) {
793 if (exp2.Current().IsSame(Eto)) {
794 Lfaces.Append(exp.Current());
799 if (Lfaces.Extent() != 1 && Lfaces.Extent() !=2) {
800 Standard_ConstructionError::Raise();
803 // soit bord libre, soit connexite entre 2 faces, eventuellement edge closed
805 if (Lfaces.Extent() ==1) {
806 return; // sera fait par PutPCurve.... on l`espere
810 Handle(Geom_Surface) S;
811 Handle(Standard_Type) styp;
812 Handle(Geom_Curve) C;
813 Standard_Real Umin,Umax,Vmin,Vmax;
815 TopLoc_Location Loc, LocFac;
817 if (!Lfaces.First().IsSame(Lfaces.Last())) {
818 TopTools_ListIteratorOfListOfShape itl(Lfaces);
819 for (; itl.More(); itl.Next()) {
820 const TopoDS_Face& Fac = TopoDS::Face(itl.Value());
822 if (!BRep_Tool::CurveOnSurface(Efrom,Fac,f,l).IsNull()) {
825 S = BRep_Tool::Surface(Fac, LocFac);
826 styp = S->DynamicType();
827 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
828 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
829 styp = S->DynamicType();
831 if (styp == STANDARD_TYPE(Geom_Plane)) {
836 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
837 C = BRep_Tool::Curve(Efrom,Loc,f,l);
838 if (!Loc.IsIdentity()) {
839 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
840 C = Handle(Geom_Curve)::DownCast (GG);
843 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
844 C = new Geom_TrimmedCurve(C,f,l);
847 S = BRep_Tool::Surface(Fac);
850 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
851 BRep_Tool::Tolerance(Fac));
852 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
853 Standard_Real TolU = Gas.UResolution(tol3d);
854 Standard_Real TolV = Gas.VResolution(tol3d);
855 Standard_Real tol2d = Max(TolU,TolV);
857 Handle(Geom2d_Curve) C2d =
858 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
862 gp_Pnt2d pf(C2d->Value(f));
863 gp_Pnt2d pl(C2d->Value(l));
865 if (S->IsUPeriodic()) {
866 Standard_Real up = S->UPeriod();
867 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
868 Standard_Integer nbtra = 0;
869 Standard_Real theUmin = Min(pf.X(),pl.X());
870 Standard_Real theUmax = Max(pf.X(),pl.X());
872 if (theUmin < Umin-tolu) {
873 while (theUmin < Umin-tolu) {
874 theUmin += up; theUmax += up;
878 else if (theUmax > Umax+tolu) {
879 while (theUmax > Umax+tolu) {
880 theUmax -= up; theUmin -= up;
885 if (theUmin > Umax+tolu) {
886 while (theUmin > Umax+tolu) {
891 else if (theUmax < Umin-tolu) {
892 while (theUmax < Umin-tolu) {
899 C2d->Translate(gp_Vec2d(nbtra*up,0.));
903 if (S->IsVPeriodic()) {
904 Standard_Real vp = S->VPeriod();
905 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
906 Standard_Integer nbtra = 0;
907 Standard_Real theVmin = Min(pf.Y(),pl.Y());
908 Standard_Real theVmax = Max(pf.Y(),pl.Y());
910 if (theVmin < Vmin-tolv) {
911 while (theVmin < Vmin-tolv) {
912 theVmin += vp; theVmax += vp;
916 else if (theVmax > Vmax+tolv) {
917 while (theVmax > Vmax+tolv) {
918 theVmax -= vp; theVmin -= vp;
923 if (theVmin > Vmax+tolv) {
924 while (theVmin > Vmax+tolv) {
929 else if (theVmax < Vmin-tolv) {
930 while (theVmax < Vmin-tolv) {
937 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
940 B.UpdateEdge(Efrom,C2d,Fac,BRep_Tool::Tolerance(Efrom));
945 const TopoDS_Face& Fac = TopoDS::Face(Lfaces.First());
946 if (!BRep_Tool::IsClosed(Eto,Fac)) {
947 Standard_ConstructionError::Raise();
950 TopoDS_Shape aLocalE = Efrom.Oriented(TopAbs_FORWARD);
951 TopoDS_Shape aLocalF = Fac.Oriented(TopAbs_FORWARD);
952 Handle(Geom2d_Curve) c2dff =
953 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
954 TopoDS::Face(aLocalF),
957 // Handle(Geom2d_Curve) c2dff =
958 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_FORWARD)),
959 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
962 aLocalE = Efrom.Oriented(TopAbs_REVERSED);
963 aLocalF = Fac.Oriented(TopAbs_FORWARD);
964 Handle(Geom2d_Curve) c2dfr =
965 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
966 TopoDS::Face(aLocalF),
968 // Handle(Geom2d_Curve) c2dfr =
969 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_REVERSED)),
970 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
973 aLocalE = Eto.Oriented(TopAbs_FORWARD);
974 aLocalF = Fac.Oriented(TopAbs_FORWARD);
975 Handle(Geom2d_Curve) c2dtf =
976 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
977 TopoDS::Face(aLocalF),
980 // Handle(Geom2d_Curve) c2dtf =
981 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_FORWARD)),
982 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
984 aLocalE = Eto.Oriented(TopAbs_REVERSED);
985 aLocalF = Fac.Oriented(TopAbs_FORWARD);
986 Handle(Geom2d_Curve) c2dtr =
987 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
988 TopoDS::Face(aLocalF),
990 // Handle(Geom2d_Curve) c2dtr =
991 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_REVERSED)),
992 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
995 gp_Pnt2d ptf(c2dtf->Value(f)); // sur courbe frw
996 gp_Pnt2d ptr(c2dtr->Value(f)); // sur courbe rev
998 Standard_Boolean isoU = (Abs(ptf.Y()-ptr.Y())<Epsilon(ptf.X())); // meme V
1000 // Efrom et Eto dans le meme sens???
1002 C = BRep_Tool::Curve(Efrom,Loc,f,l);
1003 if (!Loc.IsIdentity()) {
1004 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1005 C = Handle(Geom_Curve)::DownCast (GG);
1014 TopoDS_Vertex FirstVertex = TopExp::FirstVertex(Efrom);
1015 Standard_Real vtx_param = BRep_Tool::Parameter(FirstVertex, Efrom);
1016 BRepAdaptor_Curve2d BAcurve2d(Efrom, Fac);
1017 gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
1019 Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),p2d,Eto,Fac);
1021 C = BRep_Tool::Curve(Eto,Loc,f,l);
1022 if (!Loc.IsIdentity()) {
1023 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1024 C = Handle(Geom_Curve)::DownCast (GG);
1027 C->D1(prmproj,pt,d1t);
1029 Standard_Real SameOri = (d1t.Dot(d1f)>0.);
1032 if (c2dff.IsNull() && c2dfr.IsNull()) {
1033 S = BRep_Tool::Surface(Fac);
1034 styp = S->DynamicType();
1035 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1036 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
1037 styp = S->DynamicType();
1040 C = BRep_Tool::Curve(Efrom,Loc,f,l);
1041 if (!Loc.IsIdentity()) {
1042 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1043 C = Handle(Geom_Curve)::DownCast (GG);
1046 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
1047 C = new Geom_TrimmedCurve(C,f,l);
1050 // Compute the tol2d
1051 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
1053 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
1054 BRep_Tool::Tolerance(Fac));
1055 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
1056 Standard_Real TolU = Gas.UResolution(tol3d);
1057 Standard_Real TolV = Gas.VResolution(tol3d);
1058 Standard_Real tol2d = Max(TolU,TolV);
1060 Handle(Geom2d_Curve) C2d =
1061 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
1065 else if (c2dfr.IsNull()) {
1069 else if (c2dff.IsNull()) {
1073 BRep_Tool::Range(Efrom,f,l);
1075 gp_Pnt2d p2f = c2dff->Value(f);
1076 gp_Pnt2d p2r = c2dfr->Value(f);
1080 if (Abs(ptf.X()-p2f.X()) > Epsilon(ptf.X())) {
1081 c2dff = Handle(Geom2d_Curve)::DownCast
1082 (c2dff->Translated(gp_Vec2d(ptf.X()-p2f.X(),0.)));
1084 if (Abs(ptr.X()-p2r.X()) > Epsilon(ptr.X())) {
1085 c2dfr = Handle(Geom2d_Curve)::DownCast
1086 (c2dfr->Translated(gp_Vec2d(ptr.X()-p2r.X(),0.)));
1090 if (Abs(ptr.X()-p2f.X()) > Epsilon(ptr.X())) {
1091 c2dff = Handle(Geom2d_Curve)::DownCast
1092 (c2dff->Translated(gp_Vec2d(ptr.X()-p2f.X(),0.)));
1095 if (Abs(ptf.X()-p2r.X()) > Epsilon(ptf.X())) {
1096 c2dfr = Handle(Geom2d_Curve)::DownCast
1097 (c2dfr->Translated(gp_Vec2d(ptf.X()-p2r.X(),0.)));
1101 // on est bien en U, recalage si periodique en V a faire
1107 else { // !isoU soit isoV
1109 if (Abs(ptf.Y()-p2f.Y()) > Epsilon(ptf.Y())) {
1110 c2dff = Handle(Geom2d_Curve)::DownCast
1111 (c2dff->Translated(gp_Vec2d(0.,ptf.Y()-p2f.Y())));
1113 if (Abs(ptr.Y()-p2r.Y()) > Epsilon(ptr.Y())) {
1114 c2dfr = Handle(Geom2d_Curve)::DownCast
1115 (c2dfr->Translated(gp_Vec2d(0.,ptr.Y()-p2r.Y())));
1119 if (Abs(ptr.Y()-p2f.Y()) > Epsilon(ptr.Y())) {
1120 c2dff = Handle(Geom2d_Curve)::DownCast
1121 (c2dff->Translated(gp_Vec2d(0.,ptr.Y()-p2f.Y())));
1123 if (Abs(ptf.Y()-p2r.Y()) > Epsilon(ptf.Y())) {
1124 c2dfr = Handle(Geom2d_Curve)::DownCast
1125 (c2dfr->Translated(gp_Vec2d(0.,ptf.Y()-p2r.Y())));
1128 // on est bien en V, recalage si periodique en U a faire
1131 B.UpdateEdge(Efrom,c2dff,c2dfr,Fac,BRep_Tool::Tolerance(Efrom));
1135 //=======================================================================
1136 //function : FindInternalIntersections
1138 //=======================================================================
1140 void FindInternalIntersections(const TopoDS_Edge& theEdge,
1141 const TopoDS_Face& theFace,
1142 TopTools_IndexedDataMapOfShapeListOfShape& Splits,
1143 TopTools_DataMapOfShapeShape& GlobalMap,
1144 TopTools_MapOfShape& theMap)
1146 Standard_Real TolExt = Precision::PConfusion();
1147 Standard_Integer i, j, aNbExt;
1149 TColStd_SequenceOfReal SplitPars;
1151 TopoDS_Vertex theVertices [2];
1152 TopExp::Vertices(theEdge, theVertices[0], theVertices[1]);
1154 thePnt[0] = BRep_Tool::Pnt(theVertices[0]);
1155 thePnt[1] = BRep_Tool::Pnt(theVertices[1]);
1157 BRepAdaptor_Curve2d thePCurve(theEdge, theFace);
1159 BndLib_Add2dCurve::Add(thePCurve, BRep_Tool::Tolerance(theEdge), theBox);
1161 Standard_Real thePar [2];
1162 Standard_Real /*theFpar, theLpar,*/ aFpar, aLpar;
1163 const Handle(Geom_Curve)& theCurve = BRep_Tool::Curve(theEdge, thePar[0], thePar[1]);
1164 GeomAdaptor_Curve theGAcurve(theCurve, thePar[0], thePar[1]);
1166 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
1167 for (; Explo.More(); Explo.Next())
1169 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
1170 BRepAdaptor_Curve2d aPCurve(anEdge, theFace);
1172 BndLib_Add2dCurve::Add(aPCurve, BRep_Tool::Tolerance(anEdge), aBox);
1173 if (theBox.IsOut(aBox))
1176 const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(anEdge, aFpar, aLpar);
1177 GeomAdaptor_Curve aGAcurve(aCurve, aFpar, aLpar);
1178 Extrema_ExtCC anExtrema(theGAcurve, aGAcurve, TolExt, TolExt);
1180 if (!anExtrema.IsDone())
1182 if (anExtrema.IsParallel())
1185 aNbExt = anExtrema.NbExt();
1186 Standard_Real MaxTol = Max(BRep_Tool::Tolerance(theEdge), BRep_Tool::Tolerance(anEdge));
1187 for (i = 1; i <= aNbExt; i++)
1189 Standard_Real aDist = Sqrt(anExtrema.SquareDistance(i));
1193 Extrema_POnCurv aPOnC1, aPOnC2;
1194 anExtrema.Points(i, aPOnC1, aPOnC2);
1195 Standard_Real theIntPar = aPOnC1.Parameter();
1196 Standard_Real anIntPar = aPOnC2.Parameter();
1197 Standard_Boolean IntersFound = Standard_False;
1198 for (j = 0; j < 2; j++) //try to find intersection on an extremity of "theEdge"
1200 if (Abs(theIntPar - thePar[j]) <= Precision::PConfusion() &&
1201 aDist <= Precision::Confusion())
1203 theMap.Add(theVertices[j]);
1204 TopExp_Explorer exp2(anEdge, TopAbs_VERTEX);
1205 for (; exp2.More(); exp2.Next())
1207 const TopoDS_Vertex& aVertex = TopoDS::Vertex(exp2.Current());
1208 if (aVertex.IsSame(theVertices[j]))
1210 IntersFound = Standard_True;
1213 if (BRepTools::Compare(theVertices[j], aVertex))
1215 GlobalMap.Bind(theVertices[j], aVertex);
1216 IntersFound = Standard_True;
1222 GlobalMap.Bind(theVertices[j], anEdge);
1223 IntersFound = Standard_True;
1228 if (!IntersFound && aDist <= Precision::Confusion()) //intersection is inside "theEdge" => split
1230 gp_Pnt aPoint = aCurve->Value(anIntPar);
1231 if (aPoint.Distance(thePnt[0]) > BRep_Tool::Tolerance(theVertices[0]) &&
1232 aPoint.Distance(thePnt[1]) > BRep_Tool::Tolerance(theVertices[1]))
1233 SplitPars.Append(theIntPar);
1238 if (SplitPars.IsEmpty())
1242 for (i = 1; i < SplitPars.Length(); i++)
1243 for (j = i+1; j <= SplitPars.Length(); j++)
1244 if (SplitPars(i) > SplitPars(j))
1246 Standard_Real Tmp = SplitPars(i);
1247 SplitPars(i) = SplitPars(j);
1251 //Remove repeating points
1253 while (i < SplitPars.Length())
1255 gp_Pnt Pnt1 = theCurve->Value(SplitPars(i));
1256 gp_Pnt Pnt2 = theCurve->Value(SplitPars(i+1));
1257 if (Pnt1.Distance(Pnt2) <= Precision::Confusion())
1258 SplitPars.Remove(i+1);
1264 TopTools_ListOfShape NewEdges;
1266 //theVertices[0].Orientation(TopAbs_FORWARD);
1267 //theVertices[1].Orientation(TopAbs_REVERSED);
1268 TopoDS_Vertex FirstVertex = theVertices[0], LastVertex;
1269 Standard_Real FirstPar = thePar[0], LastPar;
1270 for (i = 1; i <= SplitPars.Length()+1; i++)
1272 FirstVertex.Orientation(TopAbs_FORWARD);
1273 if (i <= SplitPars.Length())
1275 LastPar = SplitPars(i);
1276 gp_Pnt LastPoint = theCurve->Value(LastPar);
1277 LastVertex = BRepLib_MakeVertex(LastPoint);
1281 LastPar = thePar[1];
1282 LastVertex = theVertices[1];
1284 LastVertex.Orientation(TopAbs_REVERSED);
1286 TopoDS_Shape aLocalShape = theEdge.EmptyCopied();
1287 TopAbs_Orientation anOrient = aLocalShape.Orientation();
1288 aLocalShape.Orientation(TopAbs_FORWARD);
1289 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
1290 BB.Range(NewEdge, FirstPar, LastPar);
1291 BB.Add(NewEdge, FirstVertex);
1292 BB.Add(NewEdge, LastVertex);
1293 NewEdge.Orientation(anOrient);
1294 NewEdges.Append(NewEdge);
1295 FirstVertex = LastVertex;
1299 if (!NewEdges.IsEmpty())
1300 Splits.Add(theEdge, NewEdges);