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,Standard_Transient)
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 myMapEF.RemoveKey(anEdge);
274 TopTools_ListIteratorOfListOfShape itl(Splits(Ind));
275 for (; itl.More(); itl.Next())
276 myMapEF.Add(itl.Value(), aFace);
279 TopTools_DataMapOfShapeReal aVertParam;
281 for (Ind = 1; Ind <= myMapEF.Extent(); Ind++) {
282 const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
283 const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
284 // JAG 02.02.96 : On verifie les pcurves...
286 //PutPCurve(edg,fac);
288 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
289 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
290 if (theMap.Contains(vtx)) {
294 Standard_Real vtx_param = BRep_Tool::Parameter(vtx, edg);
295 BRepAdaptor_Curve2d BAcurve2d(edg, fac);
297 gp_Pnt2d p2d = (!BAcurve2d.Curve().IsNull() ?
298 BAcurve2d.Value(vtx_param) : gp_Pnt2d(Precision::Infinite(), Precision::Infinite()));
301 Standard_Real prm = Precision::Infinite();
302 Standard_Boolean isProjected = myMap.IsBound(vtx);
304 //if vertex was already projected on the current edge on the previous face
305 //it is necessary to check tolerance of the vertex in the 2D space on the current
306 //face without projection and update tolerance of vertex if it is necessary
309 TopoDS_Shape aSh = myMap.Find(vtx);
310 if (aSh.ShapeType() != TopAbs_EDGE)
312 Epro = TopoDS::Edge(myMap.Find(vtx));
313 if (aVertParam.IsBound(vtx))
314 prm = aVertParam.Find(vtx);
316 Standard_Boolean ok = Project(vtx, p2d, fac, Epro, prm);
317 if (ok && !isProjected) {
319 for (exp2.Init(Epro, TopAbs_VERTEX); exp2.More(); exp2.Next()) {
320 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
321 if (vtx2.IsSame(vtx)) {
322 myMap.Bind(vtx, vtx2);
326 else if (BRepTools::Compare(vtx, vtx2)) {
327 Standard_Real aF1, aL1;
328 BRep_Tool::Range(Epro, fac, aF1, aL1);
329 if (!BRep_Tool::Degenerated(Epro) && (
330 Abs(prm - aF1) <= Precision::PConfusion() ||
331 Abs(prm - aL1) <= Precision::PConfusion()))
333 myMap.Bind(vtx, vtx2);
340 myMap.Bind(vtx,Epro);
341 aVertParam.Bind(vtx, prm);
347 // Modified by Sergey KHROMOV - Mon Feb 12 16:26:50 2001 Begin
348 for (ite.Initialize(myMap); ite.More(); ite.Next())
349 if ((ite.Key()).ShapeType() == TopAbs_EDGE)
350 myMapEF.Add(ite.Key(),ite.Value());
351 // Modified by Sergey KHROMOV - Mon Feb 12 16:26:52 2001 End
354 myDone = Standard_True;
359 //=======================================================================
360 //function : InitEdgeIterator
362 //=======================================================================
364 void LocOpe_WiresOnShape::InitEdgeIterator()
367 // myIt.Initialize(myMapEF);
372 //=======================================================================
373 //function : MoreEdge
375 //=======================================================================
377 Standard_Boolean LocOpe_WiresOnShape::MoreEdge()
379 // return myIt.More();
380 return (myIndex <= myMapEF.Extent());
384 //=======================================================================
387 //=======================================================================
389 TopoDS_Edge LocOpe_WiresOnShape::Edge()
391 // return TopoDS::Edge(myIt.Key());
392 return TopoDS::Edge(myMapEF.FindKey(myIndex));
396 //=======================================================================
399 //=======================================================================
401 TopoDS_Face LocOpe_WiresOnShape::OnFace()
403 // return TopoDS::Face(myIt.Value());
404 return TopoDS::Face(myMapEF(myIndex));
408 //=======================================================================
411 //=======================================================================
413 Standard_Boolean LocOpe_WiresOnShape::OnEdge(TopoDS_Edge& E)
415 // if (myMap.IsBound(myIt.Key())) {
416 if (myMap.IsBound(myMapEF.FindKey(myIndex))) {
417 // E = TopoDS::Edge(myMap(myIt.Key()));
418 E = TopoDS::Edge(myMap(myMapEF.FindKey(myIndex)));
419 return Standard_True;
421 return Standard_False;
427 //=======================================================================
428 //function : NextEdge
430 //=======================================================================
432 void LocOpe_WiresOnShape::NextEdge()
440 //=======================================================================
441 //function : OnVertex
443 //=======================================================================
445 Standard_Boolean LocOpe_WiresOnShape::OnVertex(const TopoDS_Vertex& Vw,
448 if (myMap.IsBound(Vw)) {
449 if (myMap(Vw).ShapeType() == TopAbs_VERTEX) {
450 Vs = TopoDS::Vertex(myMap(Vw));
451 return Standard_True;
453 return Standard_False;
455 return Standard_False;
459 //=======================================================================
462 //=======================================================================
464 Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
468 if (!myMap.IsBound(V) ||
469 myMap(V).ShapeType() == TopAbs_VERTEX) {
470 return Standard_False;
473 Ed = TopoDS::Edge(myMap(V));
475 return Standard_True;
478 //=======================================================================
481 //=======================================================================
483 Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
484 const TopoDS_Edge& EdgeFrom,
488 if (!myMap.IsBound(V) ||
489 myMap(V).ShapeType() == TopAbs_VERTEX) {
490 return Standard_False;
493 Ed = TopoDS::Edge(myMap(V));
494 if(!myMapEF.Contains(EdgeFrom))
495 return Standard_False;
497 TopoDS_Shape aShape = myMapEF.FindFromKey(EdgeFrom);
498 Standard_Real aF, aL;
499 Handle(Geom_Curve) aC = BRep_Tool::Curve(Ed, aF, aL);
500 if (aC.IsNull() && aShape.ShapeType() == TopAbs_FACE)
503 TopoDS_Face aFace = TopoDS::Face(aShape);
504 Standard_Real vtx_param = BRep_Tool::Parameter(V, EdgeFrom);
505 BRepAdaptor_Curve2d BAcurve2d(EdgeFrom, aFace);
506 gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
509 prm = Project(V, p2d, Ed, aFace);
512 prm = Project( V, TopoDS::Edge(Ed));
514 return Standard_True;
518 //=======================================================================
521 //=======================================================================
523 Standard_Boolean Project(const TopoDS_Vertex& V,
525 const TopoDS_Face& F,
526 TopoDS_Edge& theEdge,
527 Standard_Real& param)
529 Standard_Real aTolV = BRep_Tool::Tolerance(V);
530 Standard_Real dmin = (theEdge.IsNull() ? RealLast() : aTolV * aTolV);
532 Standard_Boolean valret = Standard_False;
534 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
536 if (theEdge.IsNull())
538 gp_Pnt toproj(BRep_Tool::Pnt(V));
539 for (TopExp_Explorer exp(F.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
540 exp.More(); exp.Next()) {
541 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
543 Handle(Geom_Curve) C = BRep_Tool::Curve(edg, f, l);
544 Standard_Real aCurDist = Precision::Infinite();
545 Standard_Real aCurPar = Precision::Infinite();
548 aCurPar = Project(V, edg);
549 if (Precision::IsInfinite(aCurPar))
552 C->D0(aCurPar, aCurPBound);
553 aCurDist = aCurPBound.SquareDistance(toproj);
556 else if(!Precision::IsInfinite(p2d.X()))
558 //Geom2dAPI_ProjectPointOnCurve proj;
559 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(edg,F , f, l);
563 aCurPar = Project(V, p2d, edg, F);
564 if (Precision::IsInfinite(aCurPar))
566 Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(edg, F, f, l);
568 PC->D0(aCurPar, aPProj);
570 aSurf->D0(aPProj.X(), aPProj.Y(), aCurPBound);
571 aCurDist = aCurPBound.SquareDistance(toproj);
575 if (aCurDist < dmin) {
577 theEdge.Orientation(edg.Orientation());
584 if (theEdge.IsNull())
585 return Standard_False;
587 else if (Precision::IsInfinite(param))
590 Handle(Geom_Curve) C = BRep_Tool::Curve(theEdge, f, l);
591 param = (!C.IsNull() ? Project(V, theEdge) : Project(V, p2d, theEdge, F));
595 Standard_Real ttol = aTolV + BRep_Tool::Tolerance(theEdge);
596 if (dmin <= ttol* ttol) {
597 valret = Standard_True;
598 GeomAdaptor_Surface adSurf(aSurf);
600 Standard_Real anUResolution = adSurf.UResolution(1.);
601 Standard_Real aVResolution = adSurf.UResolution(1.);
604 Handle(Geom2d_Curve) aCrvBound = BRep_Tool::CurveOnSurface(theEdge, F, f, l);
605 if (!aCrvBound.IsNull())
608 aCrvBound->D0(param, aPBound2d);
610 //distance in 2D space recomputed in the 3D space in order to tolerance of vertex
611 //cover gap in 2D space. For consistency with check of the validity in the BRepCheck_Wire
612 Standard_Real dumax = 0.01 * (adSurf.LastUParameter() - adSurf.FirstUParameter());
613 Standard_Real dvmax = 0.01 * (adSurf.LastVParameter() - adSurf.FirstVParameter());
615 gp_Pnt2d aPcur = p2d;
616 Standard_Real dumin = Abs(aPcur.X() - aPBound2d.X());
617 Standard_Real dvmin = Abs(aPcur.Y() - aPBound2d.Y());
618 if (dumin > dumax && adSurf.IsUPeriodic())
620 Standard_Real aX1 = aPBound2d.X();
621 Standard_Real aShift = ShapeAnalysis::AdjustToPeriod(aX1, adSurf.FirstUParameter(), adSurf.LastUParameter());
624 Standard_Real aX2 = p2d.X();
625 aShift = ShapeAnalysis::AdjustToPeriod(aX2, adSurf.FirstUParameter(), adSurf.LastUParameter());
627 dumin = Abs(aX2 - aX1);
628 if (dumin > dumax && (Abs(dumin - adSurf.UPeriod()) < Precision::PConfusion()) )
637 if (dvmin > dvmax && adSurf.IsVPeriodic())
639 Standard_Real aY1 = aPBound2d.Y();
640 Standard_Real aShift = ShapeAnalysis::AdjustToPeriod(aY1, adSurf.FirstVParameter(), adSurf.LastVParameter());
643 Standard_Real aY2 = p2d.Y();
644 aShift = ShapeAnalysis::AdjustToPeriod(aY2, adSurf.FirstVParameter(), adSurf.LastVParameter());
646 dvmin = Abs(aY1 - aY2);
647 if (dvmin > dvmax && ( Abs(dvmin - adSurf.VPeriod()) < Precision::Confusion()) )
654 Standard_Real aDist3d = aTolV;
655 if ((dumin > dumax) || (dvmin > dvmax))
658 dumax = adSurf.UResolution(aTolV);
659 dvmax = adSurf.VResolution(aTolV);
660 Standard_Real aTol2d = 2. * Max(dumax, dvmax);
661 Standard_Real aDist2d = Max(dumin, dvmin);
663 if (aDist2d > aTol2d)
665 Standard_Real aDist3d1 = aDist2d / Max(anUResolution, aVResolution);
666 if( aDist3d1 > aDist3d)
671 //added check by 3D the same as in the BRepCheck_Wire::SelfIntersect
673 aSurf->D0(aPBound2d.X(), aPBound2d.Y(), aPBound);
675 aSurf->D0(p2d.X(), p2d.Y(), aPV2d);
676 Standard_Real aDistPoints_3D = aPV2d.SquareDistance(aPBound);
677 Standard_Real aMaxDist = Max(aDistPoints_3D, aDist3d * aDist3d);
680 if (aTolV * aTolV < aMaxDist)
682 Standard_Real aNewTol = sqrt(aMaxDist);
683 B.UpdateVertex(V, aNewTol);
687 #ifdef OCCT_DEBUG_MESH
689 cout <<"LocOpe_WiresOnShape::Project --> le vertex projete est a une ";
690 cout <<"distance / la face = "<<dmin <<" superieure a la tolerance = "<<ttol<<endl;
696 //=======================================================================
699 //=======================================================================
701 Standard_Real Project(const TopoDS_Vertex& V,
702 const TopoDS_Edge& theEdge)
704 Handle(Geom_Curve) C;
708 gp_Pnt toproj(BRep_Tool::Pnt(V));
709 GeomAPI_ProjectPointOnCurve proj;
711 C = BRep_Tool::Curve(theEdge,Loc,f,l);
712 if (!Loc.IsIdentity()) {
713 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
714 C = Handle(Geom_Curve)::DownCast (GG);
716 proj.Init(toproj,C,f,l);
720 return (proj.NbPoints() > 0 ? proj.LowerDistanceParameter() : Precision::Infinite());
723 //=======================================================================
726 //=======================================================================
728 Standard_Real Project(const TopoDS_Vertex&,
730 const TopoDS_Edge& theEdge,
731 const TopoDS_Face& theFace)
735 Handle(Geom2d_Curve) PC;
739 Geom2dAPI_ProjectPointOnCurve proj;
741 PC = BRep_Tool::CurveOnSurface(theEdge, theFace, f, l);
743 proj.Init(p2d, PC, f, l);
745 return proj.NbPoints() > 0 ? proj.LowerDistanceParameter() : Precision::Infinite();
749 //=======================================================================
750 //function : PutPCurve
752 //=======================================================================
754 void PutPCurve(const TopoDS_Edge& Edg,
755 const TopoDS_Face& Fac)
758 TopLoc_Location LocFac;
760 Handle(Geom_Surface) S = BRep_Tool::Surface(Fac, LocFac);
761 Handle(Standard_Type) styp = S->DynamicType();
763 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
764 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
765 styp = S->DynamicType();
768 if (styp == STANDARD_TYPE(Geom_Plane)) {
772 Standard_Real Umin,Umax,Vmin,Vmax;
773 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
777 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(Edg,Fac,f,l);
778 if ( !aC2d.IsNull() ) {
780 aC2d->D0((f + l) *0.5, p2d);
781 Standard_Boolean IsIn = Standard_True;
782 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
783 ( p2d.X() > Umax+Precision::PConfusion() ) )
784 IsIn = Standard_False;
785 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
786 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
787 IsIn = Standard_False;
794 Handle(Geom_Curve) C = BRep_Tool::Curve(Edg,Loc,f,l);
795 if (!Loc.IsIdentity()) {
796 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
797 C = Handle(Geom_Curve)::DownCast (GG);
800 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
801 C = new Geom_TrimmedCurve(C,f,l);
804 S = BRep_Tool::Surface(Fac);
806 Standard_Real TolFirst = -1, TolLast = -1;
807 TopoDS_Vertex V1, V2;
808 TopExp::Vertices(Edg, V1, V2);
810 TolFirst = BRep_Tool::Tolerance(V1);
812 TolLast = BRep_Tool::Tolerance(V2);
814 Standard_Real tol2d = Precision::Confusion();
815 Handle(Geom2d_Curve) C2d;
816 ShapeConstruct_ProjectCurveOnSurface aToolProj;
817 aToolProj.Init(S, tol2d);
819 aToolProj.Perform(C,f,l,C2d,TolFirst,TolLast);
825 gp_Pnt2d pf(C2d->Value(f));
826 gp_Pnt2d pl(C2d->Value(l));
828 S->D0(pf.X(),pf.Y(),PF);
829 S->D0(pl.X(),pl.Y(),PL);
830 if (Edg.Orientation() == TopAbs_REVERSED) {
831 V1 = TopExp::LastVertex(Edg);
835 V1 = TopExp::FirstVertex (Edg);
837 if (Edg.Orientation() == TopAbs_REVERSED) {
838 V2 = TopExp::FirstVertex(Edg);
842 V2 = TopExp::LastVertex (Edg);
845 if(!V1.IsNull() && V2.IsNull()) {
846 //Handling of internal vertices
847 Standard_Real old1 = BRep_Tool::Tolerance (V1);
848 Standard_Real old2 = BRep_Tool::Tolerance (V2);
849 gp_Pnt pnt1 = BRep_Tool::Pnt (V1);
850 gp_Pnt pnt2 = BRep_Tool::Pnt (V2);
851 Standard_Real tol1 = pnt1.Distance(PF);
852 Standard_Real tol2 = pnt2.Distance(PL);
853 B.UpdateVertex(V1,Max(old1,tol1));
854 B.UpdateVertex(V2,Max(old2,tol2));
857 if (S->IsUPeriodic()) {
858 Standard_Real up = S->UPeriod();
859 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
860 Standard_Integer nbtra = 0;
861 Standard_Real theUmin = Min(pf.X(),pl.X());
862 Standard_Real theUmax = Max(pf.X(),pl.X());
864 if (theUmin < Umin-tolu) {
865 while (theUmin < Umin-tolu) {
870 else if (theUmax > Umax+tolu) {
871 while (theUmax > Umax+tolu) {
878 C2d->Translate(gp_Vec2d(nbtra*up,0.));
882 if (S->IsVPeriodic()) {
883 Standard_Real vp = S->VPeriod();
884 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
885 Standard_Integer nbtra = 0;
886 Standard_Real theVmin = Min(pf.Y(),pl.Y());
887 Standard_Real theVmax = Max(pf.Y(),pl.Y());
889 if (theVmin < Vmin-tolv) {
890 while (theVmin < Vmin-tolv) {
891 theVmin += vp; theVmax += vp;
895 else if (theVmax > Vmax+tolv) {
896 while (theVmax > Vmax+tolv) {
897 theVmax -= vp; theVmin -= vp;
903 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
906 B.UpdateEdge(Edg,C2d,Fac,BRep_Tool::Tolerance(Edg));
908 B.SameParameter(Edg,Standard_False);
909 BRepLib::SameParameter(Edg,tol2d);
913 //=======================================================================
914 //function : PutPCurves
916 //=======================================================================
918 void PutPCurves(const TopoDS_Edge& Efrom,
919 const TopoDS_Edge& Eto,
920 const TopoDS_Shape& myShape)
923 TopTools_ListOfShape Lfaces;
924 TopExp_Explorer exp,exp2;
926 for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
927 for (exp2.Init(exp.Current(), TopAbs_EDGE); exp2.More();exp2.Next()) {
928 if (exp2.Current().IsSame(Eto)) {
929 Lfaces.Append(exp.Current());
934 if (Lfaces.Extent() != 1 && Lfaces.Extent() !=2) {
935 throw Standard_ConstructionError();
938 // soit bord libre, soit connexite entre 2 faces, eventuellement edge closed
940 if (Lfaces.Extent() ==1) {
941 return; // sera fait par PutPCurve.... on l`espere
945 Handle(Geom_Surface) S;
946 Handle(Standard_Type) styp;
947 Handle(Geom_Curve) C;
948 Standard_Real Umin,Umax,Vmin,Vmax;
950 TopLoc_Location Loc, LocFac;
952 if (!Lfaces.First().IsSame(Lfaces.Last())) {
953 TopTools_ListIteratorOfListOfShape itl(Lfaces);
954 for (; itl.More(); itl.Next()) {
955 const TopoDS_Face& Fac = TopoDS::Face(itl.Value());
957 if (!BRep_Tool::CurveOnSurface(Efrom,Fac,f,l).IsNull()) {
960 S = BRep_Tool::Surface(Fac, LocFac);
961 styp = S->DynamicType();
962 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
963 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
964 styp = S->DynamicType();
966 if (styp == STANDARD_TYPE(Geom_Plane)) {
971 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
972 C = BRep_Tool::Curve(Efrom,Loc,f,l);
973 if (!Loc.IsIdentity()) {
974 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
975 C = Handle(Geom_Curve)::DownCast (GG);
978 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
979 C = new Geom_TrimmedCurve(C,f,l);
982 S = BRep_Tool::Surface(Fac);
985 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
986 BRep_Tool::Tolerance(Fac));
987 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
988 Standard_Real TolU = Gas.UResolution(tol3d);
989 Standard_Real TolV = Gas.VResolution(tol3d);
990 Standard_Real tol2d = Max(TolU,TolV);
992 Handle(Geom2d_Curve) C2d =
993 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
997 gp_Pnt2d pf(C2d->Value(f));
998 gp_Pnt2d pl(C2d->Value(l));
1000 if (S->IsUPeriodic()) {
1001 Standard_Real up = S->UPeriod();
1002 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
1003 Standard_Integer nbtra = 0;
1004 Standard_Real theUmin = Min(pf.X(),pl.X());
1005 Standard_Real theUmax = Max(pf.X(),pl.X());
1007 if (theUmin < Umin-tolu) {
1008 while (theUmin < Umin-tolu) {
1009 theUmin += up; theUmax += up;
1013 else if (theUmax > Umax+tolu) {
1014 while (theUmax > Umax+tolu) {
1015 theUmax -= up; theUmin -= up;
1020 if (theUmin > Umax+tolu) {
1021 while (theUmin > Umax+tolu) {
1026 else if (theUmax < Umin-tolu) {
1027 while (theUmax < Umin-tolu) {
1034 C2d->Translate(gp_Vec2d(nbtra*up,0.));
1038 if (S->IsVPeriodic()) {
1039 Standard_Real vp = S->VPeriod();
1040 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
1041 Standard_Integer nbtra = 0;
1042 Standard_Real theVmin = Min(pf.Y(),pl.Y());
1043 Standard_Real theVmax = Max(pf.Y(),pl.Y());
1045 if (theVmin < Vmin-tolv) {
1046 while (theVmin < Vmin-tolv) {
1047 theVmin += vp; theVmax += vp;
1051 else if (theVmax > Vmax+tolv) {
1052 while (theVmax > Vmax+tolv) {
1053 theVmax -= vp; theVmin -= vp;
1058 if (theVmin > Vmax+tolv) {
1059 while (theVmin > Vmax+tolv) {
1064 else if (theVmax < Vmin-tolv) {
1065 while (theVmax < Vmin-tolv) {
1072 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
1075 B.UpdateEdge(Efrom,C2d,Fac,BRep_Tool::Tolerance(Efrom));
1080 const TopoDS_Face& Fac = TopoDS::Face(Lfaces.First());
1081 if (!BRep_Tool::IsClosed(Eto,Fac)) {
1082 throw Standard_ConstructionError();
1085 TopoDS_Shape aLocalE = Efrom.Oriented(TopAbs_FORWARD);
1086 TopoDS_Shape aLocalF = Fac.Oriented(TopAbs_FORWARD);
1087 Handle(Geom2d_Curve) c2dff =
1088 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1089 TopoDS::Face(aLocalF),
1092 // Handle(Geom2d_Curve) c2dff =
1093 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_FORWARD)),
1094 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1097 aLocalE = Efrom.Oriented(TopAbs_REVERSED);
1098 aLocalF = Fac.Oriented(TopAbs_FORWARD);
1099 Handle(Geom2d_Curve) c2dfr =
1100 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1101 TopoDS::Face(aLocalF),
1103 // Handle(Geom2d_Curve) c2dfr =
1104 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_REVERSED)),
1105 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1108 aLocalE = Eto.Oriented(TopAbs_FORWARD);
1109 aLocalF = Fac.Oriented(TopAbs_FORWARD);
1110 Handle(Geom2d_Curve) c2dtf =
1111 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1112 TopoDS::Face(aLocalF),
1115 // Handle(Geom2d_Curve) c2dtf =
1116 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_FORWARD)),
1117 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1119 aLocalE = Eto.Oriented(TopAbs_REVERSED);
1120 aLocalF = Fac.Oriented(TopAbs_FORWARD);
1121 Handle(Geom2d_Curve) c2dtr =
1122 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1123 TopoDS::Face(aLocalF),
1125 // Handle(Geom2d_Curve) c2dtr =
1126 // BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_REVERSED)),
1127 // TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1130 gp_Pnt2d ptf(c2dtf->Value(f)); // sur courbe frw
1131 gp_Pnt2d ptr(c2dtr->Value(f)); // sur courbe rev
1133 Standard_Boolean isoU = (Abs(ptf.Y()-ptr.Y())<Epsilon(ptf.X())); // meme V
1135 // Efrom et Eto dans le meme sens???
1137 C = BRep_Tool::Curve(Efrom,Loc,f,l);
1138 if (!Loc.IsIdentity()) {
1139 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1140 C = Handle(Geom_Curve)::DownCast (GG);
1149 TopoDS_Vertex FirstVertex = TopExp::FirstVertex(Efrom);
1150 Standard_Real vtx_param = BRep_Tool::Parameter(FirstVertex, Efrom);
1151 BRepAdaptor_Curve2d BAcurve2d(Efrom, Fac);
1152 gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
1154 Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),p2d,Eto,Fac);
1156 C = BRep_Tool::Curve(Eto,Loc,f,l);
1157 if (!Loc.IsIdentity()) {
1158 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1159 C = Handle(Geom_Curve)::DownCast (GG);
1162 C->D1(prmproj,pt,d1t);
1164 Standard_Real SameOri = (d1t.Dot(d1f)>0.);
1167 if (c2dff.IsNull() && c2dfr.IsNull()) {
1168 S = BRep_Tool::Surface(Fac);
1169 styp = S->DynamicType();
1170 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1171 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
1172 styp = S->DynamicType();
1175 C = BRep_Tool::Curve(Efrom,Loc,f,l);
1176 if (!Loc.IsIdentity()) {
1177 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1178 C = Handle(Geom_Curve)::DownCast (GG);
1181 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
1182 C = new Geom_TrimmedCurve(C,f,l);
1185 // Compute the tol2d
1186 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
1188 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
1189 BRep_Tool::Tolerance(Fac));
1190 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
1191 Standard_Real TolU = Gas.UResolution(tol3d);
1192 Standard_Real TolV = Gas.VResolution(tol3d);
1193 Standard_Real tol2d = Max(TolU,TolV);
1195 Handle(Geom2d_Curve) C2d =
1196 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
1200 else if (c2dfr.IsNull()) {
1204 else if (c2dff.IsNull()) {
1208 BRep_Tool::Range(Efrom,f,l);
1210 gp_Pnt2d p2f = c2dff->Value(f);
1211 gp_Pnt2d p2r = c2dfr->Value(f);
1215 if (Abs(ptf.X()-p2f.X()) > Epsilon(ptf.X())) {
1216 c2dff = Handle(Geom2d_Curve)::DownCast
1217 (c2dff->Translated(gp_Vec2d(ptf.X()-p2f.X(),0.)));
1219 if (Abs(ptr.X()-p2r.X()) > Epsilon(ptr.X())) {
1220 c2dfr = Handle(Geom2d_Curve)::DownCast
1221 (c2dfr->Translated(gp_Vec2d(ptr.X()-p2r.X(),0.)));
1225 if (Abs(ptr.X()-p2f.X()) > Epsilon(ptr.X())) {
1226 c2dff = Handle(Geom2d_Curve)::DownCast
1227 (c2dff->Translated(gp_Vec2d(ptr.X()-p2f.X(),0.)));
1230 if (Abs(ptf.X()-p2r.X()) > Epsilon(ptf.X())) {
1231 c2dfr = Handle(Geom2d_Curve)::DownCast
1232 (c2dfr->Translated(gp_Vec2d(ptf.X()-p2r.X(),0.)));
1236 // on est bien en U, recalage si periodique en V a faire
1242 else { // !isoU soit isoV
1244 if (Abs(ptf.Y()-p2f.Y()) > Epsilon(ptf.Y())) {
1245 c2dff = Handle(Geom2d_Curve)::DownCast
1246 (c2dff->Translated(gp_Vec2d(0.,ptf.Y()-p2f.Y())));
1248 if (Abs(ptr.Y()-p2r.Y()) > Epsilon(ptr.Y())) {
1249 c2dfr = Handle(Geom2d_Curve)::DownCast
1250 (c2dfr->Translated(gp_Vec2d(0.,ptr.Y()-p2r.Y())));
1254 if (Abs(ptr.Y()-p2f.Y()) > Epsilon(ptr.Y())) {
1255 c2dff = Handle(Geom2d_Curve)::DownCast
1256 (c2dff->Translated(gp_Vec2d(0.,ptr.Y()-p2f.Y())));
1258 if (Abs(ptf.Y()-p2r.Y()) > Epsilon(ptf.Y())) {
1259 c2dfr = Handle(Geom2d_Curve)::DownCast
1260 (c2dfr->Translated(gp_Vec2d(0.,ptf.Y()-p2r.Y())));
1263 // on est bien en V, recalage si periodique en U a faire
1266 B.UpdateEdge(Efrom,c2dff,c2dfr,Fac,BRep_Tool::Tolerance(Efrom));
1270 //=======================================================================
1271 //function : FindInternalIntersections
1273 //=======================================================================
1275 void FindInternalIntersections(const TopoDS_Edge& theEdge,
1276 const TopoDS_Face& theFace,
1277 TopTools_IndexedDataMapOfShapeListOfShape& Splits,
1278 Standard_Boolean& isOverlapped)
1280 Standard_Real TolExt = Precision::PConfusion();
1281 Standard_Integer i, j;
1283 BRepAdaptor_Surface anAdSurf(theFace, Standard_False);
1284 TColStd_SequenceOfReal SplitPars;
1286 TopoDS_Vertex theVertices [2];
1287 TopExp::Vertices(theEdge, theVertices[0], theVertices[1]);
1289 thePnt[0] = BRep_Tool::Pnt(theVertices[0]);
1290 thePnt[1] = BRep_Tool::Pnt(theVertices[1]);
1291 Standard_Real aTolV[2];
1292 aTolV[0] =BRep_Tool::Tolerance(theVertices[0]);
1293 aTolV[1] =BRep_Tool::Tolerance(theVertices[1]);
1295 BRepAdaptor_Curve2d thePCurve(theEdge, theFace);
1297 BndLib_Add2dCurve::Add(thePCurve, BRep_Tool::Tolerance(theEdge), theBox);
1299 Standard_Real thePar [2];
1300 Standard_Real aFpar, aLpar;
1301 const Handle(Geom_Curve)& theCurve = BRep_Tool::Curve(theEdge, thePar[0], thePar[1]);
1302 GeomAdaptor_Curve theGAcurve(theCurve, thePar[0], thePar[1]);
1303 Standard_Real aDistMax = Precision::Confusion() * Precision::Confusion();
1304 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
1305 for (; Explo.More(); Explo.Next())
1307 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
1308 BRepAdaptor_Curve2d aPCurve(anEdge, theFace);
1310 BndLib_Add2dCurve::Add(aPCurve, BRep_Tool::Tolerance(anEdge), aBox);
1311 if (theBox.IsOut(aBox))
1314 const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(anEdge, aFpar, aLpar);
1315 GeomAdaptor_Curve aGAcurve(aCurve, aFpar, aLpar);
1316 Extrema_ExtCC anExtrema(theGAcurve, aGAcurve, TolExt, TolExt);
1318 if (!anExtrema.IsDone() || !anExtrema.NbExt())
1321 Standard_Integer aNbExt = anExtrema.NbExt();
1322 Standard_Real MaxTol = BRep_Tool::Tolerance(anEdge);
1323 Standard_Real aMaxTol2 = MaxTol * MaxTol;
1324 if (anExtrema.IsParallel() && anExtrema.SquareDistance(1) <= aMaxTol2)
1326 isOverlapped = Standard_True;
1329 for (i = 1; i <= aNbExt; i++)
1331 Standard_Real aDist = anExtrema.SquareDistance(i);
1332 if (aDist > aMaxTol2)
1335 Extrema_POnCurv aPOnC1, aPOnC2;
1336 anExtrema.Points(i, aPOnC1, aPOnC2);
1337 Standard_Real theIntPar = aPOnC1.Parameter();
1338 Standard_Real anIntPar = aPOnC2.Parameter();
1339 for (j = 0; j < 2; j++) //try to find intersection on an extremity of "theEdge"
1341 if (Abs(theIntPar - thePar[j]) <= Precision::PConfusion())
1344 //intersection found in the middle of the edge
1345 if (j >= 2) //intersection is inside "theEdge" => split
1347 gp_Pnt aPoint = aCurve->Value(anIntPar);
1348 gp_Pnt aPointInt = theCurve->Value(theIntPar);
1350 if (aPointInt.SquareDistance(thePnt[0]) > aTolV[0] * aTolV[0] &&
1351 aPointInt.SquareDistance(thePnt[1]) > aTolV[1] * aTolV[1] &&
1352 aPoint.SquareDistance(thePnt[0]) > aTolV[0] * aTolV[0] &&
1353 aPoint.SquareDistance(thePnt[1]) > aTolV[1] * aTolV[1])
1355 SplitPars.Append(theIntPar);
1356 if( aDist > aDistMax)
1363 if (SplitPars.IsEmpty())
1367 for (i = 1; i < SplitPars.Length(); i++)
1368 for (j = i+1; j <= SplitPars.Length(); j++)
1369 if (SplitPars(i) > SplitPars(j))
1371 Standard_Real Tmp = SplitPars(i);
1372 SplitPars(i) = SplitPars(j);
1375 //Remove repeating points
1377 while (i < SplitPars.Length())
1379 gp_Pnt Pnt1 = theCurve->Value(SplitPars(i));
1380 gp_Pnt Pnt2 = theCurve->Value(SplitPars(i+1));
1381 if (Pnt1.SquareDistance(Pnt2) <= Precision::Confusion()* Precision::Confusion())
1382 SplitPars.Remove(i+1);
1388 TopTools_ListOfShape NewEdges;
1391 TopoDS_Vertex FirstVertex = theVertices[0], LastVertex;
1392 Standard_Real FirstPar = thePar[0], LastPar;
1393 for (i = 1; i <= SplitPars.Length()+1; i++)
1395 FirstVertex.Orientation(TopAbs_FORWARD);
1396 if (i <= SplitPars.Length())
1398 LastPar = SplitPars(i);
1399 gp_Pnt LastPoint = theCurve->Value(LastPar);
1400 LastVertex = BRepLib_MakeVertex(LastPoint);
1402 aB.UpdateVertex(LastVertex, sqrt(aDistMax));
1406 LastPar = thePar[1];
1407 LastVertex = theVertices[1];
1409 LastVertex.Orientation(TopAbs_REVERSED);
1411 TopoDS_Shape aLocalShape = theEdge.EmptyCopied();
1412 TopAbs_Orientation anOrient = aLocalShape.Orientation();
1413 aLocalShape.Orientation(TopAbs_FORWARD);
1414 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
1415 BB.Range(NewEdge, FirstPar, LastPar);
1416 BB.Add(NewEdge, FirstVertex);
1417 BB.Add(NewEdge, LastVertex);
1418 NewEdge.Orientation(anOrient);
1419 ShapeAnalysis_Edge aSae;
1420 Standard_Real amaxdev =0.;
1421 if (aSae.CheckSameParameter(NewEdge, theFace, amaxdev))
1424 aB.UpdateEdge(NewEdge, amaxdev);
1427 if (anOrient == TopAbs_FORWARD)
1428 NewEdges.Append(NewEdge);
1430 NewEdges.Prepend(NewEdge);
1431 FirstVertex = LastVertex;
1435 if (!NewEdges.IsEmpty())
1436 Splits.Add(theEdge, NewEdges);
1439 //=======================================================================
1440 //function : AddSplittingEdges
1442 //=======================================================================
1444 Standard_Boolean LocOpe_WiresOnShape::Add(const TopTools_SequenceOfShape& theEdges)
1446 TopTools_SequenceOfShape anEdges;
1447 Bnd_SeqOfBox anEdgeBoxes;
1448 Standard_Integer i = 1, nb = theEdges.Length();
1449 for (; i <= nb; i++)
1451 const TopoDS_Shape& aCurSplit = theEdges(i);
1452 TopExp_Explorer anExpE(aCurSplit, TopAbs_EDGE);
1453 for (; anExpE.More(); anExpE.Next())
1455 const TopoDS_Shape& aCurE = anExpE.Current();
1458 BRepBndLib::AddClose(aCurE, aBoxE);
1461 Standard_Real aTolE = BRep_Tool::Tolerance(TopoDS::Edge(aCurE));
1462 aBoxE.SetGap(aTolE);
1463 anEdgeBoxes.Append(aBoxE);
1464 anEdges.Append(aCurE);
1468 TopExp_Explorer anExpFaces(myShape, TopAbs_FACE);
1469 Standard_Integer numF = 1;
1470 TColStd_PackedMapOfInteger anUsedEdges;
1471 for (; anExpFaces.More(); anExpFaces.Next(), numF++)
1473 const TopoDS_Face& aCurF = TopoDS::Face(anExpFaces.Current());
1475 BRepBndLib::Add(aCurF, aBoxF);
1478 BRepAdaptor_Surface anAdF(aCurF, Standard_False);
1479 NCollection_Handle<BRepTopAdaptor_FClass2d> aCheckStateTool;
1482 nb = anEdgeBoxes.Length();
1483 for (; i <= nb; i++)
1485 if (anUsedEdges.Contains(i))
1488 if (aBoxF.IsOut(anEdgeBoxes(i)))
1491 const TopoDS_Edge& aCurE = TopoDS::Edge(anEdges(i));
1493 Standard_Real aF, aL;
1494 Handle(Geom_Curve) aC = BRep_Tool::Curve(aCurE, aF, aL);
1500 gp_Pnt aP = aC->Value((aF + aL)* 0.5);
1501 Extrema_ExtPS anExtr(aP, anAdF, Precision::Confusion(), Precision::Confusion());
1503 if (!anExtr.IsDone() || !anExtr.NbExt())
1505 Standard_Real aTolE = BRep_Tool::Tolerance(TopoDS::Edge(aCurE));
1506 Standard_Real aTol2 = (aTolE + Precision::Confusion()) * (aTolE + Precision::Confusion());
1507 Standard_Integer n = 1;
1508 for (; n <= anExtr.NbExt(); n++)
1510 Standard_Real aDist2 = anExtr.SquareDistance(n);
1513 const Extrema_POnSurf& aPS = anExtr.Point(n);
1514 Standard_Real aU, aV;
1515 aPS.Parameter(aU, aV);
1517 if (aCheckStateTool.IsNull())
1519 aCheckStateTool = new BRepTopAdaptor_FClass2d(aCurF, Precision::PConfusion());
1521 if (aCheckStateTool->Perform(gp_Pnt2d(aU, aV)) == TopAbs_IN)
1531 return !anUsedEdges.IsEmpty();