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&);
89 //=======================================================================
90 //function : LocOpe_WiresOnShape
92 //=======================================================================
94 LocOpe_WiresOnShape::LocOpe_WiresOnShape(const TopoDS_Shape& S):
95 myShape(S),myCheckInterior(Standard_True),myDone(Standard_False)
100 //=======================================================================
103 //=======================================================================
105 void LocOpe_WiresOnShape::Init(const TopoDS_Shape& S)
108 myCheckInterior = Standard_True;
109 myDone = Standard_False;
116 //=======================================================================
119 //=======================================================================
121 void LocOpe_WiresOnShape::Bind(const TopoDS_Wire& W,
122 const TopoDS_Face& F)
124 for (TopExp_Explorer exp(W, TopAbs_EDGE); exp.More(); exp.Next()) {
125 Bind(TopoDS::Edge(exp.Current()),F);
129 //=======================================================================
132 //=======================================================================
134 void LocOpe_WiresOnShape::Bind(const TopoDS_Compound& Comp,
135 const TopoDS_Face& F)
137 for (TopExp_Explorer exp(Comp, TopAbs_EDGE); exp.More(); exp.Next()) {
138 Bind(TopoDS::Edge(exp.Current()),F);
140 myFacesWithSection.Add(F);
143 //=======================================================================
146 //=======================================================================
148 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& E,
149 const TopoDS_Face& F)
151 // if (!myMapEF.IsBound(E)) {
152 if (!myMapEF.Contains(E)) {
153 // for (TopExp_Explorer exp(F,TopAbs_EDGE);exp.More();exp.Next()) {
154 TopExp_Explorer exp(F,TopAbs_EDGE) ;
155 for ( ;exp.More();exp.Next()) {
156 if (exp.Current().IsSame(E)) {
161 // myMapEF.Bind(E,F);
166 Standard_ConstructionError::Raise();
171 //=======================================================================
174 //=======================================================================
176 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& Ewir,
177 const TopoDS_Edge& 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())
244 FindInternalIntersections(edg, fac, Splits);
247 for (Ind = 1; Ind <= Splits.Extent(); Ind++)
249 TopoDS_Shape anEdge = Splits.FindKey(Ind);
250 TopoDS_Shape aFace = myMapEF.FindFromKey(anEdge);
251 //Remove "anEdge" from "myMapEF"
252 TopoDS_Shape LastEdge = myMapEF.FindKey(myMapEF.Extent());
253 TopoDS_Shape LastFace = myMapEF(myMapEF.Extent());
254 myMapEF.RemoveLast();
255 if (myMapEF.FindIndex(anEdge) != 0)
256 myMapEF.Substitute(myMapEF.FindIndex(anEdge), LastEdge, LastFace);
257 ////////////////////////////////
258 TopTools_ListIteratorOfListOfShape itl(Splits(Ind));
259 for (; itl.More(); itl.Next())
260 myMapEF.Add(itl.Value(), aFace);
264 for (Ind = 1; Ind <= myMapEF.Extent(); Ind++) {
265 const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
266 const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
267 // JAG 02.02.96 : On verifie les pcurves...
269 //PutPCurve(edg,fac);
271 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
272 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
273 if (theMap.Contains(vtx)) {
277 Standard_Real vtx_param = BRep_Tool::Parameter(vtx, edg);
278 BRepAdaptor_Curve2d BAcurve2d(edg, fac);
279 gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
282 Standard_Real prm = 0.;
283 Standard_Boolean ok = Project(vtx, p2d, fac, Epro, prm);
286 for (exp2.Init(Epro,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
287 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
288 if (vtx2.IsSame(vtx)) {
291 else if (BRepTools::Compare(vtx,vtx2)) {
292 Standard_Real aF1, aL1;
293 BRep_Tool::Range(Epro, fac, aF1, aL1);
294 if (!BRep_Tool::Degenerated(Epro) ||
295 Abs(prm-aF1) <= Precision::PConfusion() ||
296 Abs(prm-aL1) <= Precision::PConfusion())
298 myMap.Bind(vtx,vtx2);
304 myMap.Bind(vtx,Epro);
311 // Modified by Sergey KHROMOV - Mon Feb 12 16:26:50 2001 Begin
312 for (ite.Initialize(myMap); ite.More(); ite.Next())
313 if ((ite.Key()).ShapeType() == TopAbs_EDGE)
314 myMapEF.Add(ite.Key(),ite.Value());
315 // Modified by Sergey KHROMOV - Mon Feb 12 16:26:52 2001 End
318 myDone = Standard_True;
323 //=======================================================================
324 //function : InitEdgeIterator
326 //=======================================================================
328 void LocOpe_WiresOnShape::InitEdgeIterator()
331 // myIt.Initialize(myMapEF);
336 //=======================================================================
337 //function : MoreEdge
339 //=======================================================================
341 Standard_Boolean LocOpe_WiresOnShape::MoreEdge()
343 // return myIt.More();
344 return (myIndex <= myMapEF.Extent());
348 //=======================================================================
351 //=======================================================================
353 TopoDS_Edge LocOpe_WiresOnShape::Edge()
355 // return TopoDS::Edge(myIt.Key());
356 return TopoDS::Edge(myMapEF.FindKey(myIndex));
360 //=======================================================================
363 //=======================================================================
365 TopoDS_Face LocOpe_WiresOnShape::OnFace()
367 // return TopoDS::Face(myIt.Value());
368 return TopoDS::Face(myMapEF(myIndex));
372 //=======================================================================
375 //=======================================================================
377 Standard_Boolean LocOpe_WiresOnShape::OnEdge(TopoDS_Edge& E)
379 // if (myMap.IsBound(myIt.Key())) {
380 if (myMap.IsBound(myMapEF.FindKey(myIndex))) {
381 // E = TopoDS::Edge(myMap(myIt.Key()));
382 E = TopoDS::Edge(myMap(myMapEF.FindKey(myIndex)));
383 return Standard_True;
385 return Standard_False;
391 //=======================================================================
392 //function : NextEdge
394 //=======================================================================
396 void LocOpe_WiresOnShape::NextEdge()
404 //=======================================================================
405 //function : OnVertex
407 //=======================================================================
409 Standard_Boolean LocOpe_WiresOnShape::OnVertex(const TopoDS_Vertex& Vw,
412 if (myMap.IsBound(Vw)) {
413 if (myMap(Vw).ShapeType() == TopAbs_VERTEX) {
414 Vs = TopoDS::Vertex(myMap(Vw));
415 return Standard_True;
417 return Standard_False;
419 return Standard_False;
423 //=======================================================================
426 //=======================================================================
428 Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
432 if (!myMap.IsBound(V) ||
433 myMap(V).ShapeType() == TopAbs_VERTEX) {
434 return Standard_False;
437 Ed = TopoDS::Edge(myMap(V));
439 return Standard_True;
442 //=======================================================================
445 //=======================================================================
447 Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
448 const TopoDS_Edge& EdgeFrom,
452 if (!myMap.IsBound(V) ||
453 myMap(V).ShapeType() == TopAbs_VERTEX) {
454 return Standard_False;
457 Ed = TopoDS::Edge(myMap(V));
458 if(!myMapEF.Contains(EdgeFrom))
459 return Standard_False;
461 TopoDS_Shape aShape = myMapEF.FindFromKey(EdgeFrom);
462 if( aShape.ShapeType() == TopAbs_FACE)
465 TopoDS_Face aFace = TopoDS::Face(aShape);
466 Standard_Real vtx_param = BRep_Tool::Parameter(V, EdgeFrom);
467 BRepAdaptor_Curve2d BAcurve2d(EdgeFrom, aFace);
468 gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
471 prm = Project(V, p2d, Ed, aFace);
474 prm = Project( V, TopoDS::Edge(Ed));
476 return Standard_True;
480 //=======================================================================
483 //=======================================================================
485 Standard_Boolean Project(const TopoDS_Vertex& V,
487 const TopoDS_Face& F,
488 TopoDS_Edge& theEdge,
489 Standard_Real& param)
491 Handle(Geom2d_Curve) PC;
492 //TopLoc_Location Loc;
495 Standard_Real dmin = RealLast();
496 //gp_Pnt toproj(BRep_Tool::Pnt(V));
497 Standard_Boolean valret = Standard_False;
498 Geom2dAPI_ProjectPointOnCurve proj;
500 for (TopExp_Explorer exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
501 exp.More(); exp.Next()) {
502 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
503 //C = BRep_Tool::Curve(edg,Loc,f,l);
504 PC = BRep_Tool::CurveOnSurface(edg, F, f, l);
505 proj.Init(p2d, PC, f, l);
506 if (proj.NbPoints() > 0) {
507 if (proj.LowerDistance() < dmin) {
509 theEdge.Orientation(edg.Orientation());
510 dmin = proj.LowerDistance();
511 param = proj.LowerDistanceParameter();
517 return Standard_False;
518 //compute distance in 3D space
520 Handle(Geom2d_Curve) aCrvBound = BRep_Tool::CurveOnSurface(theEdge, F, f, l);
522 aCrvBound->D0(param,aPBound2d);
524 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
525 aSurf->D0(aPBound2d.X(), aPBound2d.Y(), aPBound);
527 //point of vertex computed by pcurve of the splitting edge
529 aSurf->D0(p2d.X(), p2d.Y(), aPV2d);
530 //point of vertex in 3D splace
531 gp_Pnt aP3dV = BRep_Tool::Pnt(V);
533 Standard_Real aDist3d2 = Max( aPV2d.SquareDistance(aPBound), aP3dV.SquareDistance(aPBound));
534 Standard_Real aTolV = BRep_Tool::Tolerance(V);
535 Standard_Real ttol = aTolV + BRep_Tool::Tolerance(theEdge);
536 if (aDist3d2 <= ttol* ttol) {
537 valret = Standard_True;
540 if( aTolV * aTolV < aDist3d2)
542 Standard_Real aNewTol = sqrt(aDist3d2) + Precision::Confusion();
543 B.UpdateVertex(V, aNewTol);
546 #ifdef OCCT_DEBUG_MESH
548 cout <<"LocOpe_WiresOnShape::Project --> le vertex projete est a une ";
549 cout <<"distance / la face = "<<dmin <<" superieure a la tolerance = "<<ttol<<endl;
555 //=======================================================================
558 //=======================================================================
560 Standard_Real Project(const TopoDS_Vertex& V,
561 const TopoDS_Edge& theEdge)
563 Handle(Geom_Curve) C;
567 gp_Pnt toproj(BRep_Tool::Pnt(V));
568 GeomAPI_ProjectPointOnCurve proj;
570 C = BRep_Tool::Curve(theEdge,Loc,f,l);
571 if (!Loc.IsIdentity()) {
572 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
573 C = Handle(Geom_Curve)::DownCast (GG);
575 proj.Init(toproj,C,f,l);
578 return proj.LowerDistanceParameter();
581 //=======================================================================
584 //=======================================================================
586 Standard_Real Project(const TopoDS_Vertex&,
588 const TopoDS_Edge& theEdge,
589 const TopoDS_Face& theFace)
591 //Handle(Geom_Curve) C;
592 Handle(Geom2d_Curve) PC;
593 //TopLoc_Location Loc;
596 Geom2dAPI_ProjectPointOnCurve proj;
598 PC = BRep_Tool::CurveOnSurface(theEdge, theFace, f, l);
600 if (!Loc.IsIdentity()) {
601 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
602 C = Handle(Geom_Curve)::DownCast (GG);
605 proj.Init(p2d, PC, f, l);
607 return proj.LowerDistanceParameter();
611 //=======================================================================
612 //function : PutPCurve
614 //=======================================================================
616 void PutPCurve(const TopoDS_Edge& Edg,
617 const TopoDS_Face& Fac)
620 TopLoc_Location LocFac;
622 Handle(Geom_Surface) S = BRep_Tool::Surface(Fac, LocFac);
623 Handle(Standard_Type) styp = S->DynamicType();
625 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
626 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
627 styp = S->DynamicType();
630 if (styp == STANDARD_TYPE(Geom_Plane)) {
634 Standard_Real Umin,Umax,Vmin,Vmax;
635 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
639 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(Edg,Fac,f,l);
640 if ( !aC2d.IsNull() ) {
643 Standard_Boolean IsIn = Standard_True;
644 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
645 ( p2d.X() > Umax+Precision::PConfusion() ) )
646 IsIn = Standard_False;
647 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
648 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
649 IsIn = Standard_False;
651 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
652 ( p2d.X() > Umax+Precision::PConfusion() ) )
653 IsIn = Standard_False;
654 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
655 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
656 IsIn = Standard_False;
662 Handle(Geom_Curve) C = BRep_Tool::Curve(Edg,Loc,f,l);
663 if (!Loc.IsIdentity()) {
664 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
665 C = Handle(Geom_Curve)::DownCast (GG);
668 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
669 C = new Geom_TrimmedCurve(C,f,l);
672 S = BRep_Tool::Surface(Fac);
675 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Edg),
676 BRep_Tool::Tolerance(Fac));
677 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
678 Standard_Real TolU = Gas.UResolution(tol3d);
679 Standard_Real TolV = Gas.VResolution(tol3d);
680 Standard_Real tol2d = Max(TolU,TolV);
682 Handle(Geom2d_Curve) C2d =
683 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
686 gp_Pnt2d pf(C2d->Value(f));
687 gp_Pnt2d pl(C2d->Value(l));
689 S->D0(pf.X(),pf.Y(),PF);
690 S->D0(pl.X(),pl.Y(),PL);
692 if (Edg.Orientation() == TopAbs_REVERSED) {
693 V1 = TopExp::LastVertex(Edg);
697 V1 = TopExp::FirstVertex (Edg);
699 if (Edg.Orientation() == TopAbs_REVERSED) {
700 V2 = TopExp::FirstVertex(Edg);
704 V2 = TopExp::LastVertex (Edg);
707 if(!V1.IsNull() && V2.IsNull()) {
708 //Handling of internal vertices
709 Standard_Real old1 = BRep_Tool::Tolerance (V1);
710 Standard_Real old2 = BRep_Tool::Tolerance (V2);
711 gp_Pnt pnt1 = BRep_Tool::Pnt (V1);
712 gp_Pnt pnt2 = BRep_Tool::Pnt (V2);
713 Standard_Real tol1 = pnt1.Distance(PF);
714 Standard_Real tol2 = pnt2.Distance(PL);
715 B.UpdateVertex(V1,Max(old1,tol1));
716 B.UpdateVertex(V2,Max(old2,tol2));
719 if (S->IsUPeriodic()) {
720 Standard_Real up = S->UPeriod();
721 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
722 Standard_Integer nbtra = 0;
723 Standard_Real theUmin = Min(pf.X(),pl.X());
724 Standard_Real theUmax = Max(pf.X(),pl.X());
726 if (theUmin < Umin-tolu) {
727 while (theUmin < Umin-tolu) {
732 else if (theUmax > Umax+tolu) {
733 while (theUmax > Umax+tolu) {
740 C2d->Translate(gp_Vec2d(nbtra*up,0.));
744 if (S->IsVPeriodic()) {
745 Standard_Real vp = S->VPeriod();
746 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
747 Standard_Integer nbtra = 0;
748 Standard_Real theVmin = Min(pf.Y(),pl.Y());
749 Standard_Real theVmax = Max(pf.Y(),pl.Y());
751 if (theVmin < Vmin-tolv) {
752 while (theVmin < Vmin-tolv) {
753 theVmin += vp; theVmax += vp;
757 else if (theVmax > Vmax+tolv) {
758 while (theVmax > Vmax+tolv) {
759 theVmax -= vp; theVmin -= vp;
764 if (theVmin > Vmax-tolv) {
765 while (theVmin > Vmax-tolv) {
770 else if (theVmax < Vmin+tolv) {
771 while (theVmax < Vmin+tolv) {
778 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
781 B.UpdateEdge(Edg,C2d,Fac,BRep_Tool::Tolerance(Edg));
783 B.SameParameter(Edg,Standard_False);
784 BRepLib::SameParameter(Edg,tol2d);
788 //=======================================================================
789 //function : PutPCurves
791 //=======================================================================
793 void PutPCurves(const TopoDS_Edge& Efrom,
794 const TopoDS_Edge& Eto,
795 const TopoDS_Shape& myShape)
798 TopTools_ListOfShape Lfaces;
799 TopExp_Explorer exp,exp2;
801 for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
802 for (exp2.Init(exp.Current(), TopAbs_EDGE); exp2.More();exp2.Next()) {
803 if (exp2.Current().IsSame(Eto)) {
804 Lfaces.Append(exp.Current());
809 if (Lfaces.Extent() != 1 && Lfaces.Extent() !=2) {
810 Standard_ConstructionError::Raise();
813 // soit bord libre, soit connexite entre 2 faces, eventuellement edge closed
815 if (Lfaces.Extent() ==1) {
816 return; // sera fait par PutPCurve.... on l`espere
820 Handle(Geom_Surface) S;
821 Handle(Standard_Type) styp;
822 Handle(Geom_Curve) C;
823 Standard_Real Umin,Umax,Vmin,Vmax;
825 TopLoc_Location Loc, LocFac;
827 if (!Lfaces.First().IsSame(Lfaces.Last())) {
828 TopTools_ListIteratorOfListOfShape itl(Lfaces);
829 for (; itl.More(); itl.Next()) {
830 const TopoDS_Face& Fac = TopoDS::Face(itl.Value());
832 if (!BRep_Tool::CurveOnSurface(Efrom,Fac,f,l).IsNull()) {
835 S = BRep_Tool::Surface(Fac, LocFac);
836 styp = S->DynamicType();
837 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
838 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
839 styp = S->DynamicType();
841 if (styp == STANDARD_TYPE(Geom_Plane)) {
846 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
847 C = BRep_Tool::Curve(Efrom,Loc,f,l);
848 if (!Loc.IsIdentity()) {
849 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
850 C = Handle(Geom_Curve)::DownCast (GG);
853 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
854 C = new Geom_TrimmedCurve(C,f,l);
857 S = BRep_Tool::Surface(Fac);
860 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
861 BRep_Tool::Tolerance(Fac));
862 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
863 Standard_Real TolU = Gas.UResolution(tol3d);
864 Standard_Real TolV = Gas.VResolution(tol3d);
865 Standard_Real tol2d = Max(TolU,TolV);
867 Handle(Geom2d_Curve) C2d =
868 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
872 gp_Pnt2d pf(C2d->Value(f));
873 gp_Pnt2d pl(C2d->Value(l));
875 if (S->IsUPeriodic()) {
876 Standard_Real up = S->UPeriod();
877 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
878 Standard_Integer nbtra = 0;
879 Standard_Real theUmin = Min(pf.X(),pl.X());
880 Standard_Real theUmax = Max(pf.X(),pl.X());
882 if (theUmin < Umin-tolu) {
883 while (theUmin < Umin-tolu) {
884 theUmin += up; theUmax += up;
888 else if (theUmax > Umax+tolu) {
889 while (theUmax > Umax+tolu) {
890 theUmax -= up; theUmin -= up;
895 if (theUmin > Umax+tolu) {
896 while (theUmin > Umax+tolu) {
901 else if (theUmax < Umin-tolu) {
902 while (theUmax < Umin-tolu) {
909 C2d->Translate(gp_Vec2d(nbtra*up,0.));
913 if (S->IsVPeriodic()) {
914 Standard_Real vp = S->VPeriod();
915 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
916 Standard_Integer nbtra = 0;
917 Standard_Real theVmin = Min(pf.Y(),pl.Y());
918 Standard_Real theVmax = Max(pf.Y(),pl.Y());
920 if (theVmin < Vmin-tolv) {
921 while (theVmin < Vmin-tolv) {
922 theVmin += vp; theVmax += vp;
926 else if (theVmax > Vmax+tolv) {
927 while (theVmax > Vmax+tolv) {
928 theVmax -= vp; theVmin -= vp;
933 if (theVmin > Vmax+tolv) {
934 while (theVmin > Vmax+tolv) {
939 else if (theVmax < Vmin-tolv) {
940 while (theVmax < Vmin-tolv) {
947 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
950 B.UpdateEdge(Efrom,C2d,Fac,BRep_Tool::Tolerance(Efrom));
955 const TopoDS_Face& Fac = TopoDS::Face(Lfaces.First());
956 if (!BRep_Tool::IsClosed(Eto,Fac)) {
957 Standard_ConstructionError::Raise();
960 TopoDS_Shape aLocalE = Efrom.Oriented(TopAbs_FORWARD);
961 TopoDS_Shape aLocalF = Fac.Oriented(TopAbs_FORWARD);
962 Handle(Geom2d_Curve) c2dff =
963 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
964 TopoDS::Face(aLocalF),
967 // Handle(Geom2d_Curve) c2dff =
968 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_FORWARD)),
969 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
972 aLocalE = Efrom.Oriented(TopAbs_REVERSED);
973 aLocalF = Fac.Oriented(TopAbs_FORWARD);
974 Handle(Geom2d_Curve) c2dfr =
975 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
976 TopoDS::Face(aLocalF),
978 // Handle(Geom2d_Curve) c2dfr =
979 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_REVERSED)),
980 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
983 aLocalE = Eto.Oriented(TopAbs_FORWARD);
984 aLocalF = Fac.Oriented(TopAbs_FORWARD);
985 Handle(Geom2d_Curve) c2dtf =
986 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
987 TopoDS::Face(aLocalF),
990 // Handle(Geom2d_Curve) c2dtf =
991 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_FORWARD)),
992 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
994 aLocalE = Eto.Oriented(TopAbs_REVERSED);
995 aLocalF = Fac.Oriented(TopAbs_FORWARD);
996 Handle(Geom2d_Curve) c2dtr =
997 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
998 TopoDS::Face(aLocalF),
1000 // Handle(Geom2d_Curve) c2dtr =
1001 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_REVERSED)),
1002 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1005 gp_Pnt2d ptf(c2dtf->Value(f)); // sur courbe frw
1006 gp_Pnt2d ptr(c2dtr->Value(f)); // sur courbe rev
1008 Standard_Boolean isoU = (Abs(ptf.Y()-ptr.Y())<Epsilon(ptf.X())); // meme V
1010 // Efrom et Eto dans le meme sens???
1012 C = BRep_Tool::Curve(Efrom,Loc,f,l);
1013 if (!Loc.IsIdentity()) {
1014 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1015 C = Handle(Geom_Curve)::DownCast (GG);
1024 TopoDS_Vertex FirstVertex = TopExp::FirstVertex(Efrom);
1025 Standard_Real vtx_param = BRep_Tool::Parameter(FirstVertex, Efrom);
1026 BRepAdaptor_Curve2d BAcurve2d(Efrom, Fac);
1027 gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
1029 Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),p2d,Eto,Fac);
1031 C = BRep_Tool::Curve(Eto,Loc,f,l);
1032 if (!Loc.IsIdentity()) {
1033 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1034 C = Handle(Geom_Curve)::DownCast (GG);
1037 C->D1(prmproj,pt,d1t);
1039 Standard_Real SameOri = (d1t.Dot(d1f)>0.);
1042 if (c2dff.IsNull() && c2dfr.IsNull()) {
1043 S = BRep_Tool::Surface(Fac);
1044 styp = S->DynamicType();
1045 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1046 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
1047 styp = S->DynamicType();
1050 C = BRep_Tool::Curve(Efrom,Loc,f,l);
1051 if (!Loc.IsIdentity()) {
1052 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1053 C = Handle(Geom_Curve)::DownCast (GG);
1056 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
1057 C = new Geom_TrimmedCurve(C,f,l);
1060 // Compute the tol2d
1061 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
1063 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
1064 BRep_Tool::Tolerance(Fac));
1065 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
1066 Standard_Real TolU = Gas.UResolution(tol3d);
1067 Standard_Real TolV = Gas.VResolution(tol3d);
1068 Standard_Real tol2d = Max(TolU,TolV);
1070 Handle(Geom2d_Curve) C2d =
1071 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
1075 else if (c2dfr.IsNull()) {
1079 else if (c2dff.IsNull()) {
1083 BRep_Tool::Range(Efrom,f,l);
1085 gp_Pnt2d p2f = c2dff->Value(f);
1086 gp_Pnt2d p2r = c2dfr->Value(f);
1090 if (Abs(ptf.X()-p2f.X()) > Epsilon(ptf.X())) {
1091 c2dff = Handle(Geom2d_Curve)::DownCast
1092 (c2dff->Translated(gp_Vec2d(ptf.X()-p2f.X(),0.)));
1094 if (Abs(ptr.X()-p2r.X()) > Epsilon(ptr.X())) {
1095 c2dfr = Handle(Geom2d_Curve)::DownCast
1096 (c2dfr->Translated(gp_Vec2d(ptr.X()-p2r.X(),0.)));
1100 if (Abs(ptr.X()-p2f.X()) > Epsilon(ptr.X())) {
1101 c2dff = Handle(Geom2d_Curve)::DownCast
1102 (c2dff->Translated(gp_Vec2d(ptr.X()-p2f.X(),0.)));
1105 if (Abs(ptf.X()-p2r.X()) > Epsilon(ptf.X())) {
1106 c2dfr = Handle(Geom2d_Curve)::DownCast
1107 (c2dfr->Translated(gp_Vec2d(ptf.X()-p2r.X(),0.)));
1111 // on est bien en U, recalage si periodique en V a faire
1117 else { // !isoU soit isoV
1119 if (Abs(ptf.Y()-p2f.Y()) > Epsilon(ptf.Y())) {
1120 c2dff = Handle(Geom2d_Curve)::DownCast
1121 (c2dff->Translated(gp_Vec2d(0.,ptf.Y()-p2f.Y())));
1123 if (Abs(ptr.Y()-p2r.Y()) > Epsilon(ptr.Y())) {
1124 c2dfr = Handle(Geom2d_Curve)::DownCast
1125 (c2dfr->Translated(gp_Vec2d(0.,ptr.Y()-p2r.Y())));
1129 if (Abs(ptr.Y()-p2f.Y()) > Epsilon(ptr.Y())) {
1130 c2dff = Handle(Geom2d_Curve)::DownCast
1131 (c2dff->Translated(gp_Vec2d(0.,ptr.Y()-p2f.Y())));
1133 if (Abs(ptf.Y()-p2r.Y()) > Epsilon(ptf.Y())) {
1134 c2dfr = Handle(Geom2d_Curve)::DownCast
1135 (c2dfr->Translated(gp_Vec2d(0.,ptf.Y()-p2r.Y())));
1138 // on est bien en V, recalage si periodique en U a faire
1141 B.UpdateEdge(Efrom,c2dff,c2dfr,Fac,BRep_Tool::Tolerance(Efrom));
1145 //=======================================================================
1146 //function : FindInternalIntersections
1148 //=======================================================================
1150 void FindInternalIntersections(const TopoDS_Edge& theEdge,
1151 const TopoDS_Face& theFace,
1152 TopTools_IndexedDataMapOfShapeListOfShape& Splits)
1154 Standard_Real TolExt = Precision::PConfusion();
1155 Standard_Integer i, j, aNbExt;
1157 TColStd_SequenceOfReal SplitPars;
1159 TopoDS_Vertex theVertices [2];
1160 TopExp::Vertices(theEdge, theVertices[0], theVertices[1]);
1162 thePnt[0] = BRep_Tool::Pnt(theVertices[0]);
1163 thePnt[1] = BRep_Tool::Pnt(theVertices[1]);
1164 Standard_Real aTolV[2];
1165 aTolV[0] =BRep_Tool::Tolerance(theVertices[0]);
1166 aTolV[1] =BRep_Tool::Tolerance(theVertices[1]);
1168 BRepAdaptor_Curve2d thePCurve(theEdge, theFace);
1170 BndLib_Add2dCurve::Add(thePCurve, BRep_Tool::Tolerance(theEdge), theBox);
1172 Standard_Real thePar [2];
1173 Standard_Real aFpar, aLpar;
1174 const Handle(Geom_Curve)& theCurve = BRep_Tool::Curve(theEdge, thePar[0], thePar[1]);
1175 GeomAdaptor_Curve theGAcurve(theCurve, thePar[0], thePar[1]);
1176 Standard_Real aDistMax = Precision::Confusion() * Precision::Confusion();
1177 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
1178 for (; Explo.More(); Explo.Next())
1180 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
1181 BRepAdaptor_Curve2d aPCurve(anEdge, theFace);
1183 BndLib_Add2dCurve::Add(aPCurve, BRep_Tool::Tolerance(anEdge), aBox);
1184 if (theBox.IsOut(aBox))
1187 const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(anEdge, aFpar, aLpar);
1188 GeomAdaptor_Curve aGAcurve(aCurve, aFpar, aLpar);
1189 Extrema_ExtCC anExtrema(theGAcurve, aGAcurve, TolExt, TolExt);
1191 if (!anExtrema.IsDone())
1193 if (anExtrema.IsParallel())
1196 aNbExt = anExtrema.NbExt();
1197 Standard_Real MaxTol = Max(BRep_Tool::Tolerance(theEdge), BRep_Tool::Tolerance(anEdge));
1198 Standard_Real aMaxTol2 = MaxTol * MaxTol;
1199 for (i = 1; i <= aNbExt; i++)
1201 Standard_Real aDist = anExtrema.SquareDistance(i);
1202 if (aDist > aMaxTol2)
1205 Extrema_POnCurv aPOnC1, aPOnC2;
1206 anExtrema.Points(i, aPOnC1, aPOnC2);
1207 Standard_Real theIntPar = aPOnC1.Parameter();
1208 Standard_Real anIntPar = aPOnC2.Parameter();
1209 for (j = 0; j < 2; j++) //try to find intersection on an extremity of "theEdge"
1211 if (Abs(theIntPar - thePar[j]) <= Precision::PConfusion())
1214 //intersection found in the middle of the edge
1215 if (j >= 2) //intersection is inside "theEdge" => split
1217 gp_Pnt aPoint = aCurve->Value(anIntPar);
1218 if (aPoint.SquareDistance(thePnt[0]) > aTolV[0] * aTolV[0] &&
1219 aPoint.SquareDistance(thePnt[1]) > aTolV[1] * aTolV[1])
1221 SplitPars.Append(theIntPar);
1222 if( aDist > aDistMax)
1229 if (SplitPars.IsEmpty())
1233 for (i = 1; i < SplitPars.Length(); i++)
1234 for (j = i+1; j <= SplitPars.Length(); j++)
1235 if (SplitPars(i) > SplitPars(j))
1237 Standard_Real Tmp = SplitPars(i);
1238 SplitPars(i) = SplitPars(j);
1241 //Remove repeating points
1243 while (i < SplitPars.Length())
1245 gp_Pnt Pnt1 = theCurve->Value(SplitPars(i));
1246 gp_Pnt Pnt2 = theCurve->Value(SplitPars(i+1));
1247 if (Pnt1.SquareDistance(Pnt2) <= Precision::Confusion()* Precision::Confusion())
1248 SplitPars.Remove(i+1);
1254 TopTools_ListOfShape NewEdges;
1257 TopoDS_Vertex FirstVertex = theVertices[0], LastVertex;
1258 Standard_Real FirstPar = thePar[0], LastPar;
1259 for (i = 1; i <= SplitPars.Length()+1; i++)
1261 FirstVertex.Orientation(TopAbs_FORWARD);
1262 if (i <= SplitPars.Length())
1264 LastPar = SplitPars(i);
1265 gp_Pnt LastPoint = theCurve->Value(LastPar);
1266 LastVertex = BRepLib_MakeVertex(LastPoint);
1268 aB.UpdateVertex(LastVertex, sqrt(aDistMax));
1272 LastPar = thePar[1];
1273 LastVertex = theVertices[1];
1275 LastVertex.Orientation(TopAbs_REVERSED);
1277 TopoDS_Shape aLocalShape = theEdge.EmptyCopied();
1278 TopAbs_Orientation anOrient = aLocalShape.Orientation();
1279 aLocalShape.Orientation(TopAbs_FORWARD);
1280 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
1281 BB.Range(NewEdge, FirstPar, LastPar);
1282 BB.Add(NewEdge, FirstVertex);
1283 BB.Add(NewEdge, LastVertex);
1284 NewEdge.Orientation(anOrient);
1285 NewEdges.Append(NewEdge);
1286 FirstVertex = LastVertex;
1290 if (!NewEdges.IsEmpty())
1291 Splits.Add(theEdge, NewEdges);