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>
59 #include <TopTools_DataMapOfShapeReal.hxx>
60 #include <Extrema_ExtCC2d.hxx>
61 #include <BRepAdaptor_Surface.hxx>
62 #include <ShapeAnalysis_Edge.hxx>
64 #include <TopTools_SequenceOfShape.hxx>
65 #include <BRepBndLib.hxx>
66 #include <Bnd_Box.hxx>
67 #include <Bnd_SeqOfBox.hxx>
68 #include <NCollection_Handle.hxx>
69 #include <TColStd_PackedMapOfInteger.hxx>
70 #include <Extrema_ExtPS.hxx>
72 #include <BRepTopAdaptor_FClass2d.hxx>
73 #include <ShapeConstruct_ProjectCurveOnSurface.hxx>
74 #include <ShapeAnalysis.hxx>
76 IMPLEMENT_STANDARD_RTTIEXT(LocOpe_WiresOnShape,MMgt_TShared)
78 static Standard_Boolean Project(const TopoDS_Vertex&,
84 static Standard_Real Project(const TopoDS_Vertex&,
87 static Standard_Real Project(const TopoDS_Vertex&,
93 static void PutPCurve(const TopoDS_Edge&,
97 static void PutPCurves(const TopoDS_Edge&,
101 static void FindInternalIntersections(const TopoDS_Edge&,
103 TopTools_IndexedDataMapOfShapeListOfShape&,
106 //=======================================================================
107 //function : LocOpe_WiresOnShape
109 //=======================================================================
111 LocOpe_WiresOnShape::LocOpe_WiresOnShape(const TopoDS_Shape& S):
112 myShape(S),myCheckInterior(Standard_True),myDone(Standard_False)
115 //=======================================================================
118 //=======================================================================
120 void LocOpe_WiresOnShape::Init(const TopoDS_Shape& S)
123 myCheckInterior = Standard_True;
124 myDone = Standard_False;
129 //=======================================================================
132 //=======================================================================
134 void LocOpe_WiresOnShape::Bind(const TopoDS_Wire& W,
135 const TopoDS_Face& F)
137 for (TopExp_Explorer exp(W, TopAbs_EDGE); exp.More(); exp.Next()) {
138 Bind(TopoDS::Edge(exp.Current()),F);
142 //=======================================================================
145 //=======================================================================
147 void LocOpe_WiresOnShape::Bind(const TopoDS_Compound& Comp,
148 const TopoDS_Face& F)
150 for (TopExp_Explorer exp(Comp, TopAbs_EDGE); exp.More(); exp.Next()) {
151 Bind(TopoDS::Edge(exp.Current()),F);
153 myFacesWithSection.Add(F);
156 //=======================================================================
159 //=======================================================================
161 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& E,
162 const TopoDS_Face& F)
164 // if (!myMapEF.IsBound(E)) {
165 if (!myMapEF.Contains(E)) {
166 // for (TopExp_Explorer exp(F,TopAbs_EDGE);exp.More();exp.Next()) {
167 TopExp_Explorer exp(F,TopAbs_EDGE) ;
168 for ( ;exp.More();exp.Next()) {
169 if (exp.Current().IsSame(E)) {
174 // myMapEF.Bind(E,F);
179 throw Standard_ConstructionError();
184 //=======================================================================
187 //=======================================================================
189 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& Ewir,
190 const TopoDS_Edge& Efac)
192 myMap.Bind(Ewir,Efac);
196 //=======================================================================
199 //=======================================================================
201 void LocOpe_WiresOnShape::BindAll()
206 TopTools_MapOfShape theMap;
208 // Detection des vertex a projeter ou a "binder" avec des vertex existants
209 TopTools_DataMapOfShapeShape mapV;
210 TopTools_DataMapIteratorOfDataMapOfShapeShape ite(myMap);
211 TopExp_Explorer exp,exp2;
212 for (; ite.More(); ite.Next()) {
213 const TopoDS_Edge& eref = TopoDS::Edge(ite.Key());
214 const TopoDS_Edge& eimg = TopoDS::Edge(ite.Value());
216 PutPCurves(eref,eimg,myShape);
218 for (exp.Init(eref,TopAbs_VERTEX); exp.More(); exp.Next()) {
219 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
220 if (!theMap.Contains(vtx)) { // pas deja traite
221 for (exp2.Init(eimg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
222 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
223 if (vtx2.IsSame(vtx)) {
226 else if (BRepTools::Compare(vtx,vtx2)) {
239 for (ite.Initialize(mapV); ite.More(); ite.Next()) {
240 myMap.Bind(ite.Key(),ite.Value());
243 TopTools_IndexedDataMapOfShapeListOfShape Splits;
244 Standard_Integer Ind;
245 TopTools_MapOfShape anOverlappedEdges;
246 for (Ind = 1; Ind <= myMapEF.Extent(); Ind++)
248 const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
249 const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
252 Standard_Real pf, pl;
253 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(edg, fac, pf, pl);
254 if (aPCurve.IsNull())
259 Standard_Boolean isOverlapped = Standard_False;
260 FindInternalIntersections(edg, fac, Splits, isOverlapped);
262 anOverlappedEdges.Add(edg);
266 for (Ind = 1; Ind <= Splits.Extent(); Ind++)
268 TopoDS_Shape anEdge = Splits.FindKey(Ind);
269 if(anOverlappedEdges.Contains(anEdge))
271 TopoDS_Shape aFace = myMapEF.FindFromKey(anEdge);
272 //Remove "anEdge" from "myMapEF"
273 TopoDS_Shape LastEdge = myMapEF.FindKey(myMapEF.Extent());
274 TopoDS_Shape LastFace = myMapEF(myMapEF.Extent());
275 myMapEF.RemoveLast();
276 if (myMapEF.FindIndex(anEdge) != 0)
277 myMapEF.Substitute(myMapEF.FindIndex(anEdge), LastEdge, LastFace);
278 ////////////////////////////////
279 TopTools_ListIteratorOfListOfShape itl(Splits(Ind));
280 for (; itl.More(); itl.Next())
281 myMapEF.Add(itl.Value(), aFace);
284 TopTools_DataMapOfShapeReal aVertParam;
286 for (Ind = 1; Ind <= myMapEF.Extent(); Ind++) {
287 const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
288 const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
289 // JAG 02.02.96 : On verifie les pcurves...
291 //PutPCurve(edg,fac);
293 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
294 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
295 if (theMap.Contains(vtx)) {
299 Standard_Real vtx_param = BRep_Tool::Parameter(vtx, edg);
300 BRepAdaptor_Curve2d BAcurve2d(edg, fac);
302 gp_Pnt2d p2d = (!BAcurve2d.Curve().IsNull() ?
303 BAcurve2d.Value(vtx_param) : gp_Pnt2d(Precision::Infinite(), Precision::Infinite()));
306 Standard_Real prm = Precision::Infinite();
307 Standard_Boolean isProjected = myMap.IsBound(vtx);
309 //if vertex was already projected on the current edge on the previous face
310 //it is necessary to check tolerance of the vertex in the 2D space on the current
311 //face without projection and update tolerance of vertex if it is necessary
314 TopoDS_Shape aSh = myMap.Find(vtx);
315 if (aSh.ShapeType() != TopAbs_EDGE)
317 Epro = TopoDS::Edge(myMap.Find(vtx));
318 if (aVertParam.IsBound(vtx))
319 prm = aVertParam.Find(vtx);
321 Standard_Boolean ok = Project(vtx, p2d, fac, Epro, prm);
322 if (ok && !isProjected) {
324 for (exp2.Init(Epro, TopAbs_VERTEX); exp2.More(); exp2.Next()) {
325 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
326 if (vtx2.IsSame(vtx)) {
327 myMap.Bind(vtx, vtx2);
331 else if (BRepTools::Compare(vtx, vtx2)) {
332 Standard_Real aF1, aL1;
333 BRep_Tool::Range(Epro, fac, aF1, aL1);
334 if (!BRep_Tool::Degenerated(Epro) && (
335 Abs(prm - aF1) <= Precision::PConfusion() ||
336 Abs(prm - aL1) <= Precision::PConfusion()))
338 myMap.Bind(vtx, vtx2);
345 myMap.Bind(vtx,Epro);
346 aVertParam.Bind(vtx, prm);
352 // Modified by Sergey KHROMOV - Mon Feb 12 16:26:50 2001 Begin
353 for (ite.Initialize(myMap); ite.More(); ite.Next())
354 if ((ite.Key()).ShapeType() == TopAbs_EDGE)
355 myMapEF.Add(ite.Key(),ite.Value());
356 // Modified by Sergey KHROMOV - Mon Feb 12 16:26:52 2001 End
359 myDone = Standard_True;
364 //=======================================================================
365 //function : InitEdgeIterator
367 //=======================================================================
369 void LocOpe_WiresOnShape::InitEdgeIterator()
372 // myIt.Initialize(myMapEF);
377 //=======================================================================
378 //function : MoreEdge
380 //=======================================================================
382 Standard_Boolean LocOpe_WiresOnShape::MoreEdge()
384 // return myIt.More();
385 return (myIndex <= myMapEF.Extent());
389 //=======================================================================
392 //=======================================================================
394 TopoDS_Edge LocOpe_WiresOnShape::Edge()
396 // return TopoDS::Edge(myIt.Key());
397 return TopoDS::Edge(myMapEF.FindKey(myIndex));
401 //=======================================================================
404 //=======================================================================
406 TopoDS_Face LocOpe_WiresOnShape::OnFace()
408 // return TopoDS::Face(myIt.Value());
409 return TopoDS::Face(myMapEF(myIndex));
413 //=======================================================================
416 //=======================================================================
418 Standard_Boolean LocOpe_WiresOnShape::OnEdge(TopoDS_Edge& E)
420 // if (myMap.IsBound(myIt.Key())) {
421 if (myMap.IsBound(myMapEF.FindKey(myIndex))) {
422 // E = TopoDS::Edge(myMap(myIt.Key()));
423 E = TopoDS::Edge(myMap(myMapEF.FindKey(myIndex)));
424 return Standard_True;
426 return Standard_False;
432 //=======================================================================
433 //function : NextEdge
435 //=======================================================================
437 void LocOpe_WiresOnShape::NextEdge()
445 //=======================================================================
446 //function : OnVertex
448 //=======================================================================
450 Standard_Boolean LocOpe_WiresOnShape::OnVertex(const TopoDS_Vertex& Vw,
453 if (myMap.IsBound(Vw)) {
454 if (myMap(Vw).ShapeType() == TopAbs_VERTEX) {
455 Vs = TopoDS::Vertex(myMap(Vw));
456 return Standard_True;
458 return Standard_False;
460 return Standard_False;
464 //=======================================================================
467 //=======================================================================
469 Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
473 if (!myMap.IsBound(V) ||
474 myMap(V).ShapeType() == TopAbs_VERTEX) {
475 return Standard_False;
478 Ed = TopoDS::Edge(myMap(V));
480 return Standard_True;
483 //=======================================================================
486 //=======================================================================
488 Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
489 const TopoDS_Edge& EdgeFrom,
493 if (!myMap.IsBound(V) ||
494 myMap(V).ShapeType() == TopAbs_VERTEX) {
495 return Standard_False;
498 Ed = TopoDS::Edge(myMap(V));
499 if(!myMapEF.Contains(EdgeFrom))
500 return Standard_False;
502 TopoDS_Shape aShape = myMapEF.FindFromKey(EdgeFrom);
503 Standard_Real aF, aL;
504 Handle(Geom_Curve) aC = BRep_Tool::Curve(Ed, aF, aL);
505 if (aC.IsNull() && aShape.ShapeType() == TopAbs_FACE)
508 TopoDS_Face aFace = TopoDS::Face(aShape);
509 Standard_Real vtx_param = BRep_Tool::Parameter(V, EdgeFrom);
510 BRepAdaptor_Curve2d BAcurve2d(EdgeFrom, aFace);
511 gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
514 prm = Project(V, p2d, Ed, aFace);
517 prm = Project( V, TopoDS::Edge(Ed));
519 return Standard_True;
523 //=======================================================================
526 //=======================================================================
528 Standard_Boolean Project(const TopoDS_Vertex& V,
530 const TopoDS_Face& F,
531 TopoDS_Edge& theEdge,
532 Standard_Real& param)
534 Standard_Real aTolV = BRep_Tool::Tolerance(V);
535 Standard_Real dmin = (theEdge.IsNull() ? RealLast() : aTolV * aTolV);
537 Standard_Boolean valret = Standard_False;
539 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
541 if (theEdge.IsNull())
543 gp_Pnt toproj(BRep_Tool::Pnt(V));
544 for (TopExp_Explorer exp(F.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
545 exp.More(); exp.Next()) {
546 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
548 Handle(Geom_Curve) C = BRep_Tool::Curve(edg, f, l);
549 Standard_Real aCurDist = Precision::Infinite();
550 Standard_Real aCurPar = Precision::Infinite();
553 aCurPar = Project(V, edg);
554 if (Precision::IsInfinite(aCurPar))
557 C->D0(aCurPar, aCurPBound);
558 aCurDist = aCurPBound.SquareDistance(toproj);
561 else if(!Precision::IsInfinite(p2d.X()))
563 //Geom2dAPI_ProjectPointOnCurve proj;
564 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(edg,F , f, l);
568 aCurPar = Project(V, p2d, edg, F);
569 if (Precision::IsInfinite(aCurPar))
571 Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(edg, F, f, l);
573 PC->D0(aCurPar, aPProj);
575 aSurf->D0(aPProj.X(), aPProj.Y(), aCurPBound);
576 aCurDist = aCurPBound.SquareDistance(toproj);
580 if (aCurDist < dmin) {
582 theEdge.Orientation(edg.Orientation());
589 if (theEdge.IsNull())
590 return Standard_False;
592 else if (Precision::IsInfinite(param))
595 Handle(Geom_Curve) C = BRep_Tool::Curve(theEdge, f, l);
596 param = (!C.IsNull() ? Project(V, theEdge) : Project(V, p2d, theEdge, F));
600 Standard_Real ttol = aTolV + BRep_Tool::Tolerance(theEdge);
601 if (dmin <= ttol* ttol) {
602 valret = Standard_True;
603 GeomAdaptor_Surface adSurf(aSurf);
605 Standard_Real anUResolution = adSurf.UResolution(1.);
606 Standard_Real aVResolution = adSurf.UResolution(1.);
609 Handle(Geom2d_Curve) aCrvBound = BRep_Tool::CurveOnSurface(theEdge, F, f, l);
610 if (!aCrvBound.IsNull())
613 aCrvBound->D0(param, aPBound2d);
615 //distance in 2D space recomputed in the 3D space in order to tolerance of vertex
616 //cover gap in 2D space. For consistency with check of the validity in the BRepCheck_Wire
617 Standard_Real dumax = 0.01 * (adSurf.LastUParameter() - adSurf.FirstUParameter());
618 Standard_Real dvmax = 0.01 * (adSurf.LastVParameter() - adSurf.FirstVParameter());
620 gp_Pnt2d aPcur = p2d;
621 Standard_Real dumin = Abs(aPcur.X() - aPBound2d.X());
622 Standard_Real dvmin = Abs(aPcur.Y() - aPBound2d.Y());
623 if (dumin > dumax && adSurf.IsUPeriodic())
625 Standard_Real aX1 = aPBound2d.X();
626 Standard_Real aShift = ShapeAnalysis::AdjustToPeriod(aX1, adSurf.FirstUParameter(), adSurf.LastUParameter());
629 Standard_Real aX2 = p2d.X();
630 aShift = ShapeAnalysis::AdjustToPeriod(aX2, adSurf.FirstUParameter(), adSurf.LastUParameter());
632 dumin = Abs(aX2 - aX1);
633 if (dumin > dumax && (Abs(dumin - adSurf.UPeriod()) < Precision::PConfusion()) )
642 if (dvmin > dvmax && adSurf.IsVPeriodic())
644 Standard_Real aY1 = aPBound2d.Y();
645 Standard_Real aShift = ShapeAnalysis::AdjustToPeriod(aY1, adSurf.FirstVParameter(), adSurf.LastVParameter());
648 Standard_Real aY2 = p2d.Y();
649 aShift = ShapeAnalysis::AdjustToPeriod(aY2, adSurf.FirstVParameter(), adSurf.LastVParameter());
651 dvmin = Abs(aY1 - aY2);
652 if (dvmin > dvmax && ( Abs(dvmin - adSurf.VPeriod()) < Precision::Confusion()) )
659 Standard_Real aDist3d = aTolV;
660 if ((dumin > dumax) || (dvmin > dvmax))
663 dumax = adSurf.UResolution(aTolV);
664 dvmax = adSurf.VResolution(aTolV);
665 Standard_Real aTol2d = 2. * Max(dumax, dvmax);
666 Standard_Real aDist2d = Max(dumin, dvmin);
668 if (aDist2d > aTol2d)
670 Standard_Real aDist3d1 = aDist2d / Max(anUResolution, aVResolution);
671 if( aDist3d1 > aDist3d)
676 //added check by 3D the same as in the BRepCheck_Wire::SelfIntersect
678 aSurf->D0(aPBound2d.X(), aPBound2d.Y(), aPBound);
680 aSurf->D0(p2d.X(), p2d.Y(), aPV2d);
681 Standard_Real aDistPoints_3D = aPV2d.SquareDistance(aPBound);
682 Standard_Real aMaxDist = Max(aDistPoints_3D, aDist3d * aDist3d);
685 if (aTolV * aTolV < aMaxDist)
687 Standard_Real aNewTol = sqrt(aMaxDist);
688 B.UpdateVertex(V, aNewTol);
692 #ifdef OCCT_DEBUG_MESH
694 cout <<"LocOpe_WiresOnShape::Project --> le vertex projete est a une ";
695 cout <<"distance / la face = "<<dmin <<" superieure a la tolerance = "<<ttol<<endl;
701 //=======================================================================
704 //=======================================================================
706 Standard_Real Project(const TopoDS_Vertex& V,
707 const TopoDS_Edge& theEdge)
709 Handle(Geom_Curve) C;
713 gp_Pnt toproj(BRep_Tool::Pnt(V));
714 GeomAPI_ProjectPointOnCurve proj;
716 C = BRep_Tool::Curve(theEdge,Loc,f,l);
717 if (!Loc.IsIdentity()) {
718 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
719 C = Handle(Geom_Curve)::DownCast (GG);
721 proj.Init(toproj,C,f,l);
725 return (proj.NbPoints() > 0 ? proj.LowerDistanceParameter() : Precision::Infinite());
728 //=======================================================================
731 //=======================================================================
733 Standard_Real Project(const TopoDS_Vertex&,
735 const TopoDS_Edge& theEdge,
736 const TopoDS_Face& theFace)
740 Handle(Geom2d_Curve) PC;
744 Geom2dAPI_ProjectPointOnCurve proj;
746 PC = BRep_Tool::CurveOnSurface(theEdge, theFace, f, l);
748 proj.Init(p2d, PC, f, l);
750 return proj.NbPoints() > 0 ? proj.LowerDistanceParameter() : Precision::Infinite();
754 //=======================================================================
755 //function : PutPCurve
757 //=======================================================================
759 void PutPCurve(const TopoDS_Edge& Edg,
760 const TopoDS_Face& Fac)
763 TopLoc_Location LocFac;
765 Handle(Geom_Surface) S = BRep_Tool::Surface(Fac, LocFac);
766 Handle(Standard_Type) styp = S->DynamicType();
768 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
769 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
770 styp = S->DynamicType();
773 if (styp == STANDARD_TYPE(Geom_Plane)) {
777 Standard_Real Umin,Umax,Vmin,Vmax;
778 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
782 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(Edg,Fac,f,l);
783 if ( !aC2d.IsNull() ) {
785 aC2d->D0((f + l) *0.5, p2d);
786 Standard_Boolean IsIn = Standard_True;
787 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
788 ( p2d.X() > Umax+Precision::PConfusion() ) )
789 IsIn = Standard_False;
790 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
791 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
792 IsIn = Standard_False;
799 Handle(Geom_Curve) C = BRep_Tool::Curve(Edg,Loc,f,l);
800 if (!Loc.IsIdentity()) {
801 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
802 C = Handle(Geom_Curve)::DownCast (GG);
805 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
806 C = new Geom_TrimmedCurve(C,f,l);
809 S = BRep_Tool::Surface(Fac);
811 Standard_Real tol2d = Precision::Confusion();
812 Handle(Geom2d_Curve) C2d;
813 ShapeConstruct_ProjectCurveOnSurface aToolProj;
814 aToolProj.Init(S, tol2d);
816 aToolProj.Perform(C,f,l, C2d);
822 gp_Pnt2d pf(C2d->Value(f));
823 gp_Pnt2d pl(C2d->Value(l));
825 S->D0(pf.X(),pf.Y(),PF);
826 S->D0(pl.X(),pl.Y(),PL);
828 if (Edg.Orientation() == TopAbs_REVERSED) {
829 V1 = TopExp::LastVertex(Edg);
833 V1 = TopExp::FirstVertex (Edg);
835 if (Edg.Orientation() == TopAbs_REVERSED) {
836 V2 = TopExp::FirstVertex(Edg);
840 V2 = TopExp::LastVertex (Edg);
843 if(!V1.IsNull() && V2.IsNull()) {
844 //Handling of internal vertices
845 Standard_Real old1 = BRep_Tool::Tolerance (V1);
846 Standard_Real old2 = BRep_Tool::Tolerance (V2);
847 gp_Pnt pnt1 = BRep_Tool::Pnt (V1);
848 gp_Pnt pnt2 = BRep_Tool::Pnt (V2);
849 Standard_Real tol1 = pnt1.Distance(PF);
850 Standard_Real tol2 = pnt2.Distance(PL);
851 B.UpdateVertex(V1,Max(old1,tol1));
852 B.UpdateVertex(V2,Max(old2,tol2));
855 if (S->IsUPeriodic()) {
856 Standard_Real up = S->UPeriod();
857 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
858 Standard_Integer nbtra = 0;
859 Standard_Real theUmin = Min(pf.X(),pl.X());
860 Standard_Real theUmax = Max(pf.X(),pl.X());
862 if (theUmin < Umin-tolu) {
863 while (theUmin < Umin-tolu) {
868 else if (theUmax > Umax+tolu) {
869 while (theUmax > Umax+tolu) {
876 C2d->Translate(gp_Vec2d(nbtra*up,0.));
880 if (S->IsVPeriodic()) {
881 Standard_Real vp = S->VPeriod();
882 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
883 Standard_Integer nbtra = 0;
884 Standard_Real theVmin = Min(pf.Y(),pl.Y());
885 Standard_Real theVmax = Max(pf.Y(),pl.Y());
887 if (theVmin < Vmin-tolv) {
888 while (theVmin < Vmin-tolv) {
889 theVmin += vp; theVmax += vp;
893 else if (theVmax > Vmax+tolv) {
894 while (theVmax > Vmax+tolv) {
895 theVmax -= vp; theVmin -= vp;
901 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
904 B.UpdateEdge(Edg,C2d,Fac,BRep_Tool::Tolerance(Edg));
906 B.SameParameter(Edg,Standard_False);
907 BRepLib::SameParameter(Edg,tol2d);
911 //=======================================================================
912 //function : PutPCurves
914 //=======================================================================
916 void PutPCurves(const TopoDS_Edge& Efrom,
917 const TopoDS_Edge& Eto,
918 const TopoDS_Shape& myShape)
921 TopTools_ListOfShape Lfaces;
922 TopExp_Explorer exp,exp2;
924 for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
925 for (exp2.Init(exp.Current(), TopAbs_EDGE); exp2.More();exp2.Next()) {
926 if (exp2.Current().IsSame(Eto)) {
927 Lfaces.Append(exp.Current());
932 if (Lfaces.Extent() != 1 && Lfaces.Extent() !=2) {
933 throw Standard_ConstructionError();
936 // soit bord libre, soit connexite entre 2 faces, eventuellement edge closed
938 if (Lfaces.Extent() ==1) {
939 return; // sera fait par PutPCurve.... on l`espere
943 Handle(Geom_Surface) S;
944 Handle(Standard_Type) styp;
945 Handle(Geom_Curve) C;
946 Standard_Real Umin,Umax,Vmin,Vmax;
948 TopLoc_Location Loc, LocFac;
950 if (!Lfaces.First().IsSame(Lfaces.Last())) {
951 TopTools_ListIteratorOfListOfShape itl(Lfaces);
952 for (; itl.More(); itl.Next()) {
953 const TopoDS_Face& Fac = TopoDS::Face(itl.Value());
955 if (!BRep_Tool::CurveOnSurface(Efrom,Fac,f,l).IsNull()) {
958 S = BRep_Tool::Surface(Fac, LocFac);
959 styp = S->DynamicType();
960 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
961 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
962 styp = S->DynamicType();
964 if (styp == STANDARD_TYPE(Geom_Plane)) {
969 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
970 C = BRep_Tool::Curve(Efrom,Loc,f,l);
971 if (!Loc.IsIdentity()) {
972 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
973 C = Handle(Geom_Curve)::DownCast (GG);
976 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
977 C = new Geom_TrimmedCurve(C,f,l);
980 S = BRep_Tool::Surface(Fac);
983 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
984 BRep_Tool::Tolerance(Fac));
985 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
986 Standard_Real TolU = Gas.UResolution(tol3d);
987 Standard_Real TolV = Gas.VResolution(tol3d);
988 Standard_Real tol2d = Max(TolU,TolV);
990 Handle(Geom2d_Curve) C2d =
991 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
995 gp_Pnt2d pf(C2d->Value(f));
996 gp_Pnt2d pl(C2d->Value(l));
998 if (S->IsUPeriodic()) {
999 Standard_Real up = S->UPeriod();
1000 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
1001 Standard_Integer nbtra = 0;
1002 Standard_Real theUmin = Min(pf.X(),pl.X());
1003 Standard_Real theUmax = Max(pf.X(),pl.X());
1005 if (theUmin < Umin-tolu) {
1006 while (theUmin < Umin-tolu) {
1007 theUmin += up; theUmax += up;
1011 else if (theUmax > Umax+tolu) {
1012 while (theUmax > Umax+tolu) {
1013 theUmax -= up; theUmin -= up;
1018 if (theUmin > Umax+tolu) {
1019 while (theUmin > Umax+tolu) {
1024 else if (theUmax < Umin-tolu) {
1025 while (theUmax < Umin-tolu) {
1032 C2d->Translate(gp_Vec2d(nbtra*up,0.));
1036 if (S->IsVPeriodic()) {
1037 Standard_Real vp = S->VPeriod();
1038 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
1039 Standard_Integer nbtra = 0;
1040 Standard_Real theVmin = Min(pf.Y(),pl.Y());
1041 Standard_Real theVmax = Max(pf.Y(),pl.Y());
1043 if (theVmin < Vmin-tolv) {
1044 while (theVmin < Vmin-tolv) {
1045 theVmin += vp; theVmax += vp;
1049 else if (theVmax > Vmax+tolv) {
1050 while (theVmax > Vmax+tolv) {
1051 theVmax -= vp; theVmin -= vp;
1056 if (theVmin > Vmax+tolv) {
1057 while (theVmin > Vmax+tolv) {
1062 else if (theVmax < Vmin-tolv) {
1063 while (theVmax < Vmin-tolv) {
1070 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
1073 B.UpdateEdge(Efrom,C2d,Fac,BRep_Tool::Tolerance(Efrom));
1078 const TopoDS_Face& Fac = TopoDS::Face(Lfaces.First());
1079 if (!BRep_Tool::IsClosed(Eto,Fac)) {
1080 throw Standard_ConstructionError();
1083 TopoDS_Shape aLocalE = Efrom.Oriented(TopAbs_FORWARD);
1084 TopoDS_Shape aLocalF = Fac.Oriented(TopAbs_FORWARD);
1085 Handle(Geom2d_Curve) c2dff =
1086 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1087 TopoDS::Face(aLocalF),
1090 // Handle(Geom2d_Curve) c2dff =
1091 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_FORWARD)),
1092 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1095 aLocalE = Efrom.Oriented(TopAbs_REVERSED);
1096 aLocalF = Fac.Oriented(TopAbs_FORWARD);
1097 Handle(Geom2d_Curve) c2dfr =
1098 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1099 TopoDS::Face(aLocalF),
1101 // Handle(Geom2d_Curve) c2dfr =
1102 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_REVERSED)),
1103 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1106 aLocalE = Eto.Oriented(TopAbs_FORWARD);
1107 aLocalF = Fac.Oriented(TopAbs_FORWARD);
1108 Handle(Geom2d_Curve) c2dtf =
1109 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1110 TopoDS::Face(aLocalF),
1113 // Handle(Geom2d_Curve) c2dtf =
1114 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_FORWARD)),
1115 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1117 aLocalE = Eto.Oriented(TopAbs_REVERSED);
1118 aLocalF = Fac.Oriented(TopAbs_FORWARD);
1119 Handle(Geom2d_Curve) c2dtr =
1120 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1121 TopoDS::Face(aLocalF),
1123 // Handle(Geom2d_Curve) c2dtr =
1124 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_REVERSED)),
1125 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1128 gp_Pnt2d ptf(c2dtf->Value(f)); // sur courbe frw
1129 gp_Pnt2d ptr(c2dtr->Value(f)); // sur courbe rev
1131 Standard_Boolean isoU = (Abs(ptf.Y()-ptr.Y())<Epsilon(ptf.X())); // meme V
1133 // Efrom et Eto dans le meme sens???
1135 C = BRep_Tool::Curve(Efrom,Loc,f,l);
1136 if (!Loc.IsIdentity()) {
1137 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1138 C = Handle(Geom_Curve)::DownCast (GG);
1147 TopoDS_Vertex FirstVertex = TopExp::FirstVertex(Efrom);
1148 Standard_Real vtx_param = BRep_Tool::Parameter(FirstVertex, Efrom);
1149 BRepAdaptor_Curve2d BAcurve2d(Efrom, Fac);
1150 gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
1152 Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),p2d,Eto,Fac);
1154 C = BRep_Tool::Curve(Eto,Loc,f,l);
1155 if (!Loc.IsIdentity()) {
1156 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1157 C = Handle(Geom_Curve)::DownCast (GG);
1160 C->D1(prmproj,pt,d1t);
1162 Standard_Real SameOri = (d1t.Dot(d1f)>0.);
1165 if (c2dff.IsNull() && c2dfr.IsNull()) {
1166 S = BRep_Tool::Surface(Fac);
1167 styp = S->DynamicType();
1168 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1169 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
1170 styp = S->DynamicType();
1173 C = BRep_Tool::Curve(Efrom,Loc,f,l);
1174 if (!Loc.IsIdentity()) {
1175 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1176 C = Handle(Geom_Curve)::DownCast (GG);
1179 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
1180 C = new Geom_TrimmedCurve(C,f,l);
1183 // Compute the tol2d
1184 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
1186 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
1187 BRep_Tool::Tolerance(Fac));
1188 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
1189 Standard_Real TolU = Gas.UResolution(tol3d);
1190 Standard_Real TolV = Gas.VResolution(tol3d);
1191 Standard_Real tol2d = Max(TolU,TolV);
1193 Handle(Geom2d_Curve) C2d =
1194 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
1198 else if (c2dfr.IsNull()) {
1202 else if (c2dff.IsNull()) {
1206 BRep_Tool::Range(Efrom,f,l);
1208 gp_Pnt2d p2f = c2dff->Value(f);
1209 gp_Pnt2d p2r = c2dfr->Value(f);
1213 if (Abs(ptf.X()-p2f.X()) > Epsilon(ptf.X())) {
1214 c2dff = Handle(Geom2d_Curve)::DownCast
1215 (c2dff->Translated(gp_Vec2d(ptf.X()-p2f.X(),0.)));
1217 if (Abs(ptr.X()-p2r.X()) > Epsilon(ptr.X())) {
1218 c2dfr = Handle(Geom2d_Curve)::DownCast
1219 (c2dfr->Translated(gp_Vec2d(ptr.X()-p2r.X(),0.)));
1223 if (Abs(ptr.X()-p2f.X()) > Epsilon(ptr.X())) {
1224 c2dff = Handle(Geom2d_Curve)::DownCast
1225 (c2dff->Translated(gp_Vec2d(ptr.X()-p2f.X(),0.)));
1228 if (Abs(ptf.X()-p2r.X()) > Epsilon(ptf.X())) {
1229 c2dfr = Handle(Geom2d_Curve)::DownCast
1230 (c2dfr->Translated(gp_Vec2d(ptf.X()-p2r.X(),0.)));
1234 // on est bien en U, recalage si periodique en V a faire
1240 else { // !isoU soit isoV
1242 if (Abs(ptf.Y()-p2f.Y()) > Epsilon(ptf.Y())) {
1243 c2dff = Handle(Geom2d_Curve)::DownCast
1244 (c2dff->Translated(gp_Vec2d(0.,ptf.Y()-p2f.Y())));
1246 if (Abs(ptr.Y()-p2r.Y()) > Epsilon(ptr.Y())) {
1247 c2dfr = Handle(Geom2d_Curve)::DownCast
1248 (c2dfr->Translated(gp_Vec2d(0.,ptr.Y()-p2r.Y())));
1252 if (Abs(ptr.Y()-p2f.Y()) > Epsilon(ptr.Y())) {
1253 c2dff = Handle(Geom2d_Curve)::DownCast
1254 (c2dff->Translated(gp_Vec2d(0.,ptr.Y()-p2f.Y())));
1256 if (Abs(ptf.Y()-p2r.Y()) > Epsilon(ptf.Y())) {
1257 c2dfr = Handle(Geom2d_Curve)::DownCast
1258 (c2dfr->Translated(gp_Vec2d(0.,ptf.Y()-p2r.Y())));
1261 // on est bien en V, recalage si periodique en U a faire
1264 B.UpdateEdge(Efrom,c2dff,c2dfr,Fac,BRep_Tool::Tolerance(Efrom));
1268 //=======================================================================
1269 //function : FindInternalIntersections
1271 //=======================================================================
1273 void FindInternalIntersections(const TopoDS_Edge& theEdge,
1274 const TopoDS_Face& theFace,
1275 TopTools_IndexedDataMapOfShapeListOfShape& Splits,
1276 Standard_Boolean& isOverlapped)
1278 Standard_Real TolExt = Precision::PConfusion();
1279 Standard_Integer i, j;
1281 BRepAdaptor_Surface anAdSurf(theFace, Standard_False);
1282 TColStd_SequenceOfReal SplitPars;
1284 TopoDS_Vertex theVertices [2];
1285 TopExp::Vertices(theEdge, theVertices[0], theVertices[1]);
1287 thePnt[0] = BRep_Tool::Pnt(theVertices[0]);
1288 thePnt[1] = BRep_Tool::Pnt(theVertices[1]);
1289 Standard_Real aTolV[2];
1290 aTolV[0] =BRep_Tool::Tolerance(theVertices[0]);
1291 aTolV[1] =BRep_Tool::Tolerance(theVertices[1]);
1293 BRepAdaptor_Curve2d thePCurve(theEdge, theFace);
1295 BndLib_Add2dCurve::Add(thePCurve, BRep_Tool::Tolerance(theEdge), theBox);
1297 Standard_Real thePar [2];
1298 Standard_Real aFpar, aLpar;
1299 const Handle(Geom_Curve)& theCurve = BRep_Tool::Curve(theEdge, thePar[0], thePar[1]);
1300 GeomAdaptor_Curve theGAcurve(theCurve, thePar[0], thePar[1]);
1301 Standard_Real aDistMax = Precision::Confusion() * Precision::Confusion();
1302 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
1303 for (; Explo.More(); Explo.Next())
1305 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
1306 BRepAdaptor_Curve2d aPCurve(anEdge, theFace);
1308 BndLib_Add2dCurve::Add(aPCurve, BRep_Tool::Tolerance(anEdge), aBox);
1309 if (theBox.IsOut(aBox))
1312 const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(anEdge, aFpar, aLpar);
1313 GeomAdaptor_Curve aGAcurve(aCurve, aFpar, aLpar);
1314 Extrema_ExtCC anExtrema(theGAcurve, aGAcurve, TolExt, TolExt);
1316 if (!anExtrema.IsDone() || !anExtrema.NbExt())
1319 Standard_Integer aNbExt = anExtrema.NbExt();
1320 Standard_Real MaxTol = BRep_Tool::Tolerance(anEdge);
1321 Standard_Real aMaxTol2 = MaxTol * MaxTol;
1322 if (anExtrema.IsParallel() && anExtrema.SquareDistance(1) <= aMaxTol2)
1324 isOverlapped = Standard_True;
1327 for (i = 1; i <= aNbExt; i++)
1329 Standard_Real aDist = anExtrema.SquareDistance(i);
1330 if (aDist > aMaxTol2)
1333 Extrema_POnCurv aPOnC1, aPOnC2;
1334 anExtrema.Points(i, aPOnC1, aPOnC2);
1335 Standard_Real theIntPar = aPOnC1.Parameter();
1336 Standard_Real anIntPar = aPOnC2.Parameter();
1337 for (j = 0; j < 2; j++) //try to find intersection on an extremity of "theEdge"
1339 if (Abs(theIntPar - thePar[j]) <= Precision::PConfusion())
1342 //intersection found in the middle of the edge
1343 if (j >= 2) //intersection is inside "theEdge" => split
1345 gp_Pnt aPoint = aCurve->Value(anIntPar);
1346 gp_Pnt aPointInt = theCurve->Value(theIntPar);
1348 if (aPointInt.SquareDistance(thePnt[0]) > aTolV[0] * aTolV[0] &&
1349 aPointInt.SquareDistance(thePnt[1]) > aTolV[1] * aTolV[1] &&
1350 aPoint.SquareDistance(thePnt[0]) > aTolV[0] * aTolV[0] &&
1351 aPoint.SquareDistance(thePnt[1]) > aTolV[1] * aTolV[1])
1353 SplitPars.Append(theIntPar);
1354 if( aDist > aDistMax)
1361 if (SplitPars.IsEmpty())
1365 for (i = 1; i < SplitPars.Length(); i++)
1366 for (j = i+1; j <= SplitPars.Length(); j++)
1367 if (SplitPars(i) > SplitPars(j))
1369 Standard_Real Tmp = SplitPars(i);
1370 SplitPars(i) = SplitPars(j);
1373 //Remove repeating points
1375 while (i < SplitPars.Length())
1377 gp_Pnt Pnt1 = theCurve->Value(SplitPars(i));
1378 gp_Pnt Pnt2 = theCurve->Value(SplitPars(i+1));
1379 if (Pnt1.SquareDistance(Pnt2) <= Precision::Confusion()* Precision::Confusion())
1380 SplitPars.Remove(i+1);
1386 TopTools_ListOfShape NewEdges;
1389 TopoDS_Vertex FirstVertex = theVertices[0], LastVertex;
1390 Standard_Real FirstPar = thePar[0], LastPar;
1391 for (i = 1; i <= SplitPars.Length()+1; i++)
1393 FirstVertex.Orientation(TopAbs_FORWARD);
1394 if (i <= SplitPars.Length())
1396 LastPar = SplitPars(i);
1397 gp_Pnt LastPoint = theCurve->Value(LastPar);
1398 LastVertex = BRepLib_MakeVertex(LastPoint);
1400 aB.UpdateVertex(LastVertex, sqrt(aDistMax));
1404 LastPar = thePar[1];
1405 LastVertex = theVertices[1];
1407 LastVertex.Orientation(TopAbs_REVERSED);
1409 TopoDS_Shape aLocalShape = theEdge.EmptyCopied();
1410 TopAbs_Orientation anOrient = aLocalShape.Orientation();
1411 aLocalShape.Orientation(TopAbs_FORWARD);
1412 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
1413 BB.Range(NewEdge, FirstPar, LastPar);
1414 BB.Add(NewEdge, FirstVertex);
1415 BB.Add(NewEdge, LastVertex);
1416 NewEdge.Orientation(anOrient);
1417 ShapeAnalysis_Edge aSae;
1418 Standard_Real amaxdev =0.;
1419 if (aSae.CheckSameParameter(NewEdge, theFace, amaxdev))
1422 aB.UpdateEdge(NewEdge, amaxdev);
1425 if (anOrient == TopAbs_FORWARD)
1426 NewEdges.Append(NewEdge);
1428 NewEdges.Prepend(NewEdge);
1429 FirstVertex = LastVertex;
1433 if (!NewEdges.IsEmpty())
1434 Splits.Add(theEdge, NewEdges);
1437 //=======================================================================
1438 //function : AddSplittingEdges
1440 //=======================================================================
1442 Standard_Boolean LocOpe_WiresOnShape::Add(const TopTools_SequenceOfShape& theEdges)
1444 TopTools_SequenceOfShape anEdges;
1445 Bnd_SeqOfBox anEdgeBoxes;
1446 Standard_Integer i = 1, nb = theEdges.Length();
1447 for (; i <= nb; i++)
1449 const TopoDS_Shape& aCurSplit = theEdges(i);
1450 TopExp_Explorer anExpE(aCurSplit, TopAbs_EDGE);
1451 for (; anExpE.More(); anExpE.Next())
1453 const TopoDS_Shape& aCurE = anExpE.Current();
1456 BRepBndLib::AddClose(aCurE, aBoxE);
1459 Standard_Real aTolE = BRep_Tool::Tolerance(TopoDS::Edge(aCurE));
1460 aBoxE.SetGap(aTolE);
1461 anEdgeBoxes.Append(aBoxE);
1462 anEdges.Append(aCurE);
1466 TopExp_Explorer anExpFaces(myShape, TopAbs_FACE);
1467 Standard_Integer numF = 1;
1468 TColStd_PackedMapOfInteger anUsedEdges;
1469 for (; anExpFaces.More(); anExpFaces.Next(), numF++)
1471 const TopoDS_Face& aCurF = TopoDS::Face(anExpFaces.Current());
1473 BRepBndLib::Add(aCurF, aBoxF);
1476 BRepAdaptor_Surface anAdF(aCurF, Standard_False);
1477 NCollection_Handle<BRepTopAdaptor_FClass2d> aCheckStateTool;
1480 nb = anEdgeBoxes.Length();
1481 for (; i <= nb; i++)
1483 if (anUsedEdges.Contains(i))
1486 if (aBoxF.IsOut(anEdgeBoxes(i)))
1489 const TopoDS_Edge& aCurE = TopoDS::Edge(anEdges(i));
1491 Standard_Real aF, aL;
1492 Handle(Geom_Curve) aC = BRep_Tool::Curve(aCurE, aF, aL);
1498 gp_Pnt aP = aC->Value((aF + aL)* 0.5);
1499 Extrema_ExtPS anExtr(aP, anAdF, Precision::Confusion(), Precision::Confusion());
1501 if (!anExtr.IsDone() || !anExtr.NbExt())
1503 Standard_Real aTolE = BRep_Tool::Tolerance(TopoDS::Edge(aCurE));
1504 Standard_Real aTol2 = (aTolE + Precision::Confusion()) * (aTolE + Precision::Confusion());
1505 Standard_Integer n = 1;
1506 for (; n <= anExtr.NbExt(); n++)
1508 Standard_Real aDist2 = anExtr.SquareDistance(n);
1511 const Extrema_POnSurf& aPS = anExtr.Point(n);
1512 Standard_Real aU, aV;
1513 aPS.Parameter(aU, aV);
1515 if (aCheckStateTool.IsNull())
1517 aCheckStateTool = new BRepTopAdaptor_FClass2d(aCurF, Precision::PConfusion());
1519 if (aCheckStateTool->Perform(gp_Pnt2d(aU, aV)) == TopAbs_IN)
1529 return !anUsedEdges.IsEmpty();