1 // Created on: 1994-03-10
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1994-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.
17 // Modifed: Porting NT 7-5-97 DPF (stdio.h)
18 // Apr 16 2002 eap, classification against infinite solid (occ299)
21 // Modified by skv - Thu Sep 4 12:29:30 2003 OCC578
23 //-- Process the case of a hole!!
28 #include <Bnd_Box.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRepAdaptor_Curve2d.hxx>
31 #include <BRepAdaptor_HSurface.hxx>
32 #include <BRepAdaptor_Surface.hxx>
33 #include <BRepBndLib.hxx>
34 #include <BRepClass3d_DataMapIteratorOfMapOfInter.hxx>
35 #include <BRepClass3d_SolidExplorer.hxx>
36 #include <BRepClass_Edge.hxx>
37 #include <BRepClass_FaceClassifier.hxx>
38 #include <BRepClass_FacePassiveClassifier.hxx>
39 #include <BRepTools.hxx>
40 #include <BRepTopAdaptor_FClass2d.hxx>
42 #include <Extrema_ExtPS.hxx>
43 #include <Geom2d_Curve.hxx>
44 #include <GeomAbs_Shape.hxx>
49 #include <gp_Vec2d.hxx>
50 #include <IntCurvesFace_Intersector.hxx>
51 #include <Precision.hxx>
52 #include <TopAbs_Orientation.hxx>
53 #include <TopExp_Explorer.hxx>
55 #include <TopoDS_Face.hxx>
56 #include <TopoDS_Shape.hxx>
57 #include <TopoDS_Shell.hxx>
63 //=======================================================================
64 //function : FindAPointInTheFace
65 //purpose : Compute a point P in the face F. Param is a Real in
66 // ]0,1[ and is used to initialise the algorithm. For
67 // different values , different points are returned.
68 //=======================================================================
69 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
70 (const TopoDS_Face& _face,
72 Standard_Real& param_)
75 Standard_Boolean r = FindAPointInTheFace(_face,APoint_,u,v,param_);
79 //=======================================================================
80 //function : FindAPointInTheFace
82 //=======================================================================
84 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
85 (const TopoDS_Face& _face,
87 Standard_Real& u_, Standard_Real& v_,
88 Standard_Real& param_)
90 gp_Vec aVecD1U, aVecD1V;
91 return FindAPointInTheFace (_face, APoint_, u_, v_, param_, aVecD1U, aVecD1V);
94 //=======================================================================
95 //function : FindAPointInTheFace
97 //=======================================================================
99 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
100 (const TopoDS_Face& _face,
102 Standard_Real& u_, Standard_Real& v_,
103 Standard_Real& param_,
107 TopoDS_Face face = _face;
108 face.Orientation (TopAbs_FORWARD);
110 TopExp_Explorer faceexplorer;
111 BRepAdaptor_Curve2d c;
115 for (faceexplorer.Init(face,TopAbs_EDGE);
119 TopoDS_Edge Edge = TopoDS::Edge (faceexplorer.Current());
120 c.Initialize (Edge, face);
121 c.D1((c.LastParameter() - c.FirstParameter()) * param_ + c.FirstParameter(),P,T);
123 Standard_Real x = T.X();
124 Standard_Real y = T.Y();
125 if (Edge.Orientation() == TopAbs_FORWARD)
133 Standard_Real ParamInit = RealLast();
134 Standard_Real TolInit = 0.00001;
135 Standard_Boolean APointExist = Standard_False;
137 BRepClass_FacePassiveClassifier FClassifier;
140 P.SetCoord (P.X() + TolInit * T.X(), P.Y() + TolInit * T.Y());
141 FClassifier.Reset (gp_Lin2d (P, T), ParamInit, RealEpsilon()); //-- Length and Tolerance #######
143 TopExp_Explorer otherfaceexplorer;
144 Standard_Integer aNbEdges = 0;
145 for (otherfaceexplorer.Init (face, TopAbs_EDGE);
146 otherfaceexplorer.More();
147 otherfaceexplorer.Next(), ++aNbEdges)
149 TopoDS_Edge OtherEdge = TopoDS::Edge (otherfaceexplorer.Current());
150 if (OtherEdge.Orientation() != TopAbs_EXTERNAL && OtherEdge != Edge)
152 BRepClass_Edge AEdge (OtherEdge, face);
153 FClassifier.Compare (AEdge, OtherEdge.Orientation());
154 if (FClassifier.ClosestIntersection())
156 if(ParamInit > FClassifier.Parameter())
158 ParamInit = FClassifier.Parameter();
159 APointExist = Standard_True;
167 BRepClass_Edge AEdge (Edge, face);
168 FClassifier.Compare (AEdge, Edge.Orientation());
169 if (FClassifier.ClosestIntersection())
171 if (ParamInit > FClassifier.Parameter())
173 ParamInit = FClassifier.Parameter();
174 APointExist = Standard_True;
181 ParamInit *= 0.41234;
182 u_ = P.X() + ParamInit* T.X();
183 v_ = P.Y() + ParamInit* T.Y();
186 BRepTopAdaptor_FClass2d Classifier(face, Precision::Confusion());
187 gp_Pnt2d aPnt2d(u_, v_);
188 TopAbs_State StateOfResultingPoint = Classifier.Perform(aPnt2d);
189 if (StateOfResultingPoint != TopAbs_IN)
190 return Standard_False;
192 BRepAdaptor_Surface s;
193 s.Initialize (face, Standard_False);
194 s.D1 (u_, v_, APoint_, theVecD1U, theVecD1V);
196 if(theVecD1U.CrossMagnitude(theVecD1V) > gp::Resolution())
197 return Standard_True;
199 if(ParamInit < Precision::PConfusion())
200 return Standard_False;
203 return Standard_False;
206 //=======================================================================
207 //function : PointInTheFace
209 //=======================================================================
211 Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
212 (const TopoDS_Face& Face,
214 Standard_Real& u_, Standard_Real& v_,
215 Standard_Real& param_,
216 Standard_Integer& IndexPoint,
217 const Handle(BRepAdaptor_HSurface)& surf,
218 const Standard_Real U1,
219 const Standard_Real V1,
220 const Standard_Real U2,
221 const Standard_Real V2) const
223 gp_Vec aVecD1U, aVecD1V;
224 return PointInTheFace (Face, APoint_, u_, v_, param_, IndexPoint, surf,
225 U1, V1, U2, V2, aVecD1U, aVecD1V);
228 //=======================================================================
229 //function : ClassifyUVPoint
231 //=======================================================================
233 TopAbs_State BRepClass3d_SolidExplorer::ClassifyUVPoint
234 (const IntCurvesFace_Intersector& theIntersector,
235 const Handle(BRepAdaptor_HSurface)& theSurf,
236 const gp_Pnt2d& theP2d) const
238 // first find if the point is near an edge/vertex
239 gp_Pnt aP3d = theSurf->Value(theP2d.X(), theP2d.Y());
240 BRepClass3d_BndBoxTreeSelectorPoint aSelectorPoint(myMapEV);
241 aSelectorPoint.SetCurrentPoint(aP3d);
242 Standard_Integer aSelsVE = myTree.Select(aSelectorPoint);
245 // The point is inside the tolerance area of vertices/edges => return ON state.
248 return theIntersector.ClassifyUVPoint(theP2d);
251 //=======================================================================
252 //function : PointInTheFace
254 //=======================================================================
256 Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
257 (const TopoDS_Face& Face,
259 Standard_Real& u_, Standard_Real& v_,
260 Standard_Real& param_,
261 Standard_Integer& IndexPoint,
262 const Handle(BRepAdaptor_HSurface)& surf,
263 const Standard_Real U1,
264 const Standard_Real V1,
265 const Standard_Real U2,
266 const Standard_Real V2,
268 gp_Vec& theVecD1V) const
270 Standard_Real u,du = (U2-U1)/6.0;
271 Standard_Real v,dv = (V2-V1)/6.0;
272 if(du<1e-12) du=1e-12;
273 if(dv<1e-12) dv=1e-12;
274 Standard_Boolean IsNotUper = !surf->IsUPeriodic(), IsNotVper = !surf->IsVPeriodic();
275 Standard_Integer NbPntCalc=0;
276 if(myMapOfInter.IsBound(Face)) {
277 void *ptr = (void*)(myMapOfInter.Find(Face));
278 Standard_Boolean IsInside = Standard_True;
281 IsInside = (u_ >= U1) && (u_ <= U2);
285 IsInside &= (v_ >= V1) && (v_ <= V2);
288 const IntCurvesFace_Intersector& TheIntersector = (*((IntCurvesFace_Intersector *)ptr));
289 // Check if the point is already in the face
290 if (IsInside && (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u_, v_)) == TopAbs_IN)) {
292 surf->D1(u_, v_, aPnt, theVecD1U, theVecD1V);
293 if (aPnt.SquareDistance(APoint_) < Precision::Confusion() * Precision::Confusion())
294 return Standard_True;
297 //-- Take 4 points in each Quarter of surface
298 //-- -> Index : 1 -> 16
301 //-- Then take a matrix of points on a tight grid
303 for(u=du+(U1+U2)*0.5; u<U2; u+=du) { //-- 0 X u increases
304 for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) { //-- 0 0 v increases
305 if(++NbPntCalc>=IndexPoint) {
306 if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) {
308 surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
309 IndexPoint = NbPntCalc;
310 return(Standard_True);
316 for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- 0 0 u decreases
317 for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- X 0 v decreases
318 if(++NbPntCalc>=IndexPoint) {
319 if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) {
321 surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
322 IndexPoint = NbPntCalc;
323 return(Standard_True);
328 for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- X 0 u decreases
329 for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) { //-- 0 0 v increases
330 if(++NbPntCalc>=IndexPoint) {
331 if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) {
333 surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
334 IndexPoint = NbPntCalc;
335 return(Standard_True);
340 for(u=du+(U1+U2)*0.5; u<U2; u+=du) { //-- 0 0 u increases
341 for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- 0 X v decreases
342 if(++NbPntCalc>=IndexPoint) {
343 if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) {
345 surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
346 IndexPoint = NbPntCalc;
347 return(Standard_True);
355 if(du<1e-12) du=1e-12;
356 if(dv<1e-12) dv=1e-12;
358 for(u=du+U1; u<U2; u+=du) {
359 for(v=dv+V1; v<V2; v+=dv) {
360 if(++NbPntCalc>=IndexPoint) {
361 if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) {
363 surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
364 IndexPoint = NbPntCalc;
365 return(Standard_True);
372 if(++NbPntCalc>=IndexPoint) {
373 if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) {
375 surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
376 IndexPoint = NbPntCalc;
377 return(Standard_True);
381 IndexPoint = NbPntCalc;
384 //printf("BRepClass3d_SolidExplorer Face not found ds the map \n");
387 return BRepClass3d_SolidExplorer
388 ::FindAPointInTheFace (Face,APoint_, u_, v_, param_, theVecD1U, theVecD1V);
391 //=======================================================================
392 //function : LimitInfiniteUV
393 //purpose : Limit infinite parameters
394 //=======================================================================
395 static void LimitInfiniteUV (Standard_Real& U1,
401 infU1 = Precision::IsNegativeInfinite(U1),
402 infV1 = Precision::IsNegativeInfinite(V1),
403 infU2 = Precision::IsPositiveInfinite(U2),
404 infV2 = Precision::IsPositiveInfinite(V2);
406 if (infU1) U1 = -1e10;
407 if (infV1) V1 = -1e10;
408 if (infU2) U2 = 1e10;
409 if (infV2) V2 = 1e10;
411 //=======================================================================
412 //function : IsInfiniteUV
414 //=======================================================================
415 static Standard_Integer IsInfiniteUV (Standard_Real& U1,
420 Standard_Integer aVal = 0;
422 if (Precision::IsInfinite(U1))
425 if (Precision::IsInfinite(V1))
428 if (Precision::IsInfinite(U2))
431 if (Precision::IsInfinite(V2))
437 // Modified by skv - Tue Sep 16 13:50:39 2003 OCC578 End
438 //=======================================================================
439 //function : OtherSegment
440 //purpose : Returns in <L>, <Par> a segment having at least
441 // one intersection with the shape boundary to
442 // compute intersections.
443 // The First Call to this method returns a line which
444 // point to a point of the first face of the shape.
445 // The Second Call provide a line to the second face
447 //=======================================================================
448 Standard_Integer BRepClass3d_SolidExplorer::OtherSegment(const gp_Pnt& P,
452 const Standard_Real TolU = Precision::PConfusion();
453 const Standard_Real TolV = TolU;
456 TopExp_Explorer faceexplorer;
458 gp_Vec aVecD1U, aVecD1V;
459 Standard_Real maxscal=0;
460 Standard_Boolean ptfound=Standard_False;
463 Standard_Integer IndexPoint=0;
464 Standard_Integer NbPointsOK=0;
465 Standard_Integer NbFacesInSolid=0;
466 Standard_Boolean aRestr = Standard_True;
467 Standard_Boolean aTestInvert = Standard_False;
471 faceexplorer.Init(myShape,TopAbs_FACE);
472 // look for point on face starting from myFirstFace
473 // Modified by skv - Thu Sep 4 14:31:12 2003 OCC578 Begin
474 // while (faceexplorer.More()) {
476 for (; faceexplorer.More(); faceexplorer.Next()) {
477 // Modified by skv - Thu Sep 4 14:31:12 2003 OCC578 End
479 if (myFirstFace > NbFacesInSolid) continue;
480 face = TopoDS::Face(faceexplorer.Current());
482 Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
485 BRepTopAdaptor_FClass2d aClass(face, Precision::Confusion());
486 if(aClass.PerformInfinitePoint() == TopAbs_IN)
488 aRestr = Standard_False;
489 if(myMapOfInter.IsBound(face))
491 myMapOfInter.UnBind(face);
492 void *ptr = (void *)(new IntCurvesFace_Intersector(face, Precision::Confusion(),
493 aRestr, Standard_False));
494 myMapOfInter.Bind(face,ptr);
499 aRestr = Standard_True;
502 surf->ChangeSurface().Initialize(face, aRestr);
503 Standard_Real U1,V1,U2,V2;
504 U1 = surf->FirstUParameter();
505 V1 = surf->FirstVParameter();
506 U2 = surf->LastUParameter();
507 V2 = surf->LastVParameter();
508 face.Orientation(TopAbs_FORWARD);
510 //avoid process faces from uncorrected shells
511 const Standard_Real eps = Precision::PConfusion();
512 Standard_Real epsU = Max(eps * Max(Abs(U2), Abs(U1)), eps);
513 Standard_Real epsV = Max(eps * Max(Abs(V2), Abs(V1)), eps);
514 if( Abs (U2 - U1) < epsU || Abs(V2 - V1) < epsV) {
518 Standard_Real svmyparam=myParamOnEdge;
520 // Check if the point is on the face or the face is infinite.
521 Standard_Integer anInfFlag = IsInfiniteUV(U1,V1,U2,V2);
523 _u = (U1 + U2) * 0.5;
524 _v = (V1 + V2) * 0.5;
526 GeomAdaptor_Surface GA(BRep_Tool::Surface(face));
527 Extrema_ExtPS Ext(P, GA, TolU, TolV);
529 if (Ext.IsDone() && Ext.NbExt() > 0) {
530 Standard_Integer i, iNear, iEnd;
531 Standard_Real aUx, aVx, Dist2, Dist2Min;
535 Dist2Min = Ext.SquareDistance(1);
537 for (i = 2; i <= iEnd; i++) {
539 aPx.Parameter(aUx, aVx);
540 if (aUx>=U1 && aUx<=U2 && aVx>=V1 && aVx<=V2) {
541 Dist2 = Ext.SquareDistance(i);
542 if (Dist2 < Dist2Min) {
549 Standard_Real aDist2Tresh=1.e-24;
551 if (Dist2Min<aDist2Tresh) {
556 BRepClass_FaceClassifier classifier2d;
560 (Ext.Point(iNear)).Parameter(aU, aV);
562 gp_Pnt2d aPuv(aU, aV);
564 classifier2d.Perform(face,aPuv,Precision::PConfusion());
566 TopAbs_State aState = classifier2d.State();
568 if (aState == TopAbs_IN || aState == TopAbs_ON) {
572 return 3; // skv - the point is on surface but outside face.
577 APoint = (Ext.Point(iNear)).Value();
579 _Par = V.Magnitude();
581 ptfound=Standard_True;
585 // set the parameters found by extrema
586 aPx = Ext.Point(iNear);
587 aPx.Parameter(_u, _v);
588 APoint = aPx.Value();
590 //The point is not ON the face or surface. The face is restricted.
591 // find point in a face not too far from a projection of P on face
593 if (PointInTheFace (face, APoint, _u, _v, myParamOnEdge, ++IndexPoint, surf,
598 gp_Vec V (P, APoint);
600 if (Par > gp::Resolution() &&
601 aVecD1U.Magnitude() > gp::Resolution() &&
602 aVecD1V.Magnitude() > gp::Resolution())
604 gp_Vec Norm = aVecD1U.Crossed (aVecD1V);
605 Standard_Real tt = Norm.Magnitude();
606 tt = Abs (Norm.Dot (V)) / (tt * Par);
612 ptfound = Standard_True;
615 myParamOnEdge=svmyparam;
622 while(IndexPoint<200 && NbPointsOK<16);
624 myParamOnEdge=svmyparam;
630 // Modified by skv - Thu Sep 4 14:32:14 2003 OCC578 Begin
631 // Next is done in the main for(..) loop.
632 // faceexplorer.Next();
633 // Modified by skv - Thu Sep 4 14:32:14 2003 OCC578 End
636 Standard_Boolean encoreuneface = faceexplorer.More();
637 if(ptfound==Standard_False && encoreuneface==Standard_False) {
638 if(myParamOnEdge < 0.0001) {
639 //-- This case takes place when the point is on the solid
640 //-- and this solid is reduced to a face
641 gp_Pnt PBidon(P.X()+1.0,P.Y(),P.Z());
649 } //-- Exploration of the faces
651 if(NbFacesInSolid==0) {
653 myReject=Standard_True;
655 cout<<"\nWARNING : BRepClass3d_SolidExplorer.cxx (Solid without face)"<<endl;
664 if(myParamOnEdge==0.512345) myParamOnEdge = 0.4;
665 else if(myParamOnEdge==0.4) myParamOnEdge = 0.6;
666 else if(myParamOnEdge==0.6) myParamOnEdge = 0.3;
667 else if(myParamOnEdge==0.3) myParamOnEdge = 0.7;
668 else if(myParamOnEdge==0.7) myParamOnEdge = 0.2;
669 else if(myParamOnEdge==0.2) myParamOnEdge = 0.8;
670 else if(myParamOnEdge==0.8) myParamOnEdge = 0.1;
671 else if(myParamOnEdge==0.1) myParamOnEdge = 0.9;
675 if(myParamOnEdge < 0.0001) {
676 gp_Pnt PBidon(P.X()+1.0,P.Y(),P.Z());
684 aTestInvert = Standard_True;
685 } //-- for(;;) { ... }
688 // Modified by skv - Thu Sep 4 12:30:14 2003 OCC578 Begin
689 //=======================================================================
690 //function : GetFaceSegmentIndex
691 //purpose : Returns the index of face for which last segment is calculated.
692 //=======================================================================
694 Standard_Integer BRepClass3d_SolidExplorer::GetFaceSegmentIndex() const
698 // Modified by skv - Thu Sep 4 12:30:14 2003 OCC578 End
700 //=======================================================================
701 //function : PointInTheFace
703 //=======================================================================
705 Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
706 (const TopoDS_Face& _face,
708 Standard_Real& u_, Standard_Real& v_,
709 Standard_Real& param_,
710 Standard_Integer& IndexPoint) const
712 TopoDS_Face Face = _face;
713 Face.Orientation(TopAbs_FORWARD);
714 Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
715 surf->ChangeSurface().Initialize(Face);
716 Standard_Real U1,V1,U2,V2;//,u,v;
717 U1 = surf->FirstUParameter();
718 V1 = surf->FirstVParameter();
719 U2 = surf->LastUParameter();
720 V2 = surf->LastVParameter();
721 LimitInfiniteUV (U1,V1,U2,V2);
722 return(PointInTheFace(Face,APoint_,u_,v_,param_,IndexPoint,surf,U1,V1,U2,V2));
725 //=======================================================================
726 //function : FindAPointInTheFace
728 //=======================================================================
730 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
731 (const TopoDS_Face& _face,
733 Standard_Real& u_,Standard_Real& v_)
735 Standard_Real param = 0.1;
736 Standard_Boolean r = FindAPointInTheFace(_face,APoint_,u_,v_,param);
740 //=======================================================================
741 //function : FindAPointInTheFace
743 //=======================================================================
745 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
746 (const TopoDS_Face& _face,
749 Standard_Boolean r = FindAPointInTheFace(_face,APoint_,u,v);
753 //=======================================================================
754 //function : FindAPointInTheFace
756 //=======================================================================
758 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
759 (const TopoDS_Face& _face,
760 Standard_Real& u_,Standard_Real& v_)
762 Standard_Boolean r = FindAPointInTheFace(_face,APoint,u_,v_);
766 //=======================================================================
767 //function : BRepClass3d_SolidExplorer
769 //=======================================================================
771 BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer()
774 #include <Standard_ConstructionError.hxx>
776 //=======================================================================
777 //function : BRepClass3d_SolidExplorer
778 //purpose : Raise if called.
779 //=======================================================================
781 //BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const BRepClass3d_SolidExplorer& Oth)
782 BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const BRepClass3d_SolidExplorer& )
784 Standard_ConstructionError::Raise("Magic constructor not allowed");
787 //=======================================================================
788 //function : BRepClass3d_SolidExplorer
790 //=======================================================================
792 BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const TopoDS_Shape& S)
797 //=======================================================================
798 //function : ~BRepClass3d_SolidExplorer
800 //=======================================================================
802 BRepClass3d_SolidExplorer::~BRepClass3d_SolidExplorer()
807 //=======================================================================
809 //purpose : C++: alias ~
810 //=======================================================================
812 void BRepClass3d_SolidExplorer::Destroy() {
813 BRepClass3d_DataMapIteratorOfMapOfInter iter(myMapOfInter);
814 for(;iter.More();iter.Next()) {
815 void *ptr=iter.Value();
817 delete (IntCurvesFace_Intersector *)ptr;
818 myMapOfInter.ChangeFind(iter.Key()) = NULL;
821 myMapOfInter.Clear();
824 //=======================================================================
825 //function : InitShape
827 //=======================================================================
829 void BRepClass3d_SolidExplorer::InitShape(const TopoDS_Shape& S)
836 myParamOnEdge = 0.512345;
837 //-- Exploring of the Map and removal of allocated objects
840 BRepClass3d_DataMapIteratorOfMapOfInter iter(myMapOfInter);
841 for(;iter.More();iter.Next()) {
842 void *ptr=iter.Value();
844 delete (IntCurvesFace_Intersector *)ptr;
845 myMapOfInter.ChangeFind(iter.Key()) = NULL;
849 myMapOfInter.Clear();
851 myReject = Standard_True; //-- case of infinite solid (without any face)
853 TopExp_Explorer Expl;
854 for(Expl.Init(S,TopAbs_FACE);
857 const TopoDS_Face Face = TopoDS::Face(Expl.Current());
858 void *ptr = (void *)(new IntCurvesFace_Intersector(Face,Precision::Confusion(),Standard_True, Standard_False));
859 myMapOfInter.Bind(Face,ptr);
860 myReject=Standard_False; //-- at least one face in the solid
865 cout<<"\nWARNING : BRepClass3d_SolidExplorer.cxx (Solid without face)"<<endl;
870 BRepBndLib::Add(myShape,myBox);
873 // since the internal/external parts should be avoided in tree filler,
874 // there is no need to add these parts in the EV map as well
875 TopExp_Explorer aExpF(myShape, TopAbs_FACE);
876 for (; aExpF.More(); aExpF.Next()) {
877 const TopoDS_Shape& aF = aExpF.Current();
879 TopAbs_Orientation anOrF = aF.Orientation();
880 if (anOrF == TopAbs_INTERNAL || anOrF == TopAbs_EXTERNAL) {
884 TopExp_Explorer aExpE(aF, TopAbs_EDGE);
885 for (; aExpE.More(); aExpE.Next()) {
886 const TopoDS_Shape& aE = aExpE.Current();
888 TopAbs_Orientation anOrE = aE.Orientation();
889 if (anOrE == TopAbs_INTERNAL || anOrE == TopAbs_EXTERNAL) {
893 if (BRep_Tool::Degenerated(TopoDS::Edge(aE))) {
897 TopExp::MapShapes(aE, myMapEV);
901 // Fill mapEV with vertices and edges from shape
902 NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller (myTree);
904 Standard_Integer i, aNbEV = myMapEV.Extent();
905 for (i = 1; i <= aNbEV; ++i) {
906 const TopoDS_Shape& aS = myMapEV(i);
909 BRepBndLib::Add(aS, aBox);
910 aTreeFiller.Add(i, aBox);
915 //=======================================================================
917 //purpose : Should return True if P outside of bounding vol. of the shape
918 //=======================================================================
920 //Standard_Boolean BRepClass3d_SolidExplorer::Reject(const gp_Pnt& P) const
921 Standard_Boolean BRepClass3d_SolidExplorer::Reject(const gp_Pnt& ) const
923 return(myReject); // case of solid without face
926 //=======================================================================
927 //function : InitShell
928 //purpose : Starts an exploration of the shells.
929 //=======================================================================
931 void BRepClass3d_SolidExplorer::InitShell()
933 myShellExplorer.Init(myShape,TopAbs_SHELL);
936 //=======================================================================
937 //function : MoreShell
938 //purpose : Returns True if there is a current shell.
939 //=======================================================================
941 Standard_Boolean BRepClass3d_SolidExplorer::MoreShell() const
943 return(myShellExplorer.More());
946 //=======================================================================
947 //function : NextShell
948 //purpose : Sets the explorer to the next shell.
949 //=======================================================================
951 void BRepClass3d_SolidExplorer::NextShell()
953 myShellExplorer.Next();
956 //=======================================================================
957 //function : CurrentShell
958 //purpose : Returns the current shell.
959 //=======================================================================
961 TopoDS_Shell BRepClass3d_SolidExplorer::CurrentShell() const
963 return(TopoDS::Shell(myShellExplorer.Current()));
966 //=======================================================================
967 //function : RejectShell
968 //purpose : Returns True if the Shell is rejected.
969 //=======================================================================
971 Standard_Boolean BRepClass3d_SolidExplorer::RejectShell(const gp_Lin& ) const
973 return(Standard_False);
976 //=======================================================================
977 //function : InitFace
978 //purpose : Starts an exploration of the faces of the current shell.
979 //=======================================================================
981 void BRepClass3d_SolidExplorer::InitFace()
983 myFaceExplorer.Init(TopoDS::Shell(myShellExplorer.Current()),TopAbs_FACE);
986 //=======================================================================
987 //function : MoreFace
988 //purpose : Returns True if current face in current shell.
989 //=======================================================================
991 Standard_Boolean BRepClass3d_SolidExplorer::MoreFace() const
993 return(myFaceExplorer.More());
996 //=======================================================================
997 //function : NextFace
998 //purpose : Sets the explorer to the next Face of the current shell.
999 //=======================================================================
1001 void BRepClass3d_SolidExplorer::NextFace()
1003 myFaceExplorer.Next();
1006 //=======================================================================
1007 //function : CurrentFace
1008 //purpose : Returns the current face.
1009 //=======================================================================
1011 TopoDS_Face BRepClass3d_SolidExplorer::CurrentFace() const
1013 return(TopoDS::Face(myFaceExplorer.Current()));
1016 //=======================================================================
1017 //function : RejectFace
1018 //purpose : returns True if the face is rejected.
1019 //=======================================================================
1021 Standard_Boolean BRepClass3d_SolidExplorer::RejectFace(const gp_Lin& ) const
1023 return(Standard_False);
1027 #include <TopAbs_State.hxx>
1030 //=======================================================================
1031 //function : Segment
1032 //purpose : Returns in <L>, <Par> a segment having at least
1033 // one intersection with the shape boundary to
1034 // compute intersections.
1035 //=======================================================================
1036 Standard_Integer BRepClass3d_SolidExplorer::Segment(const gp_Pnt& P,
1040 Standard_Integer bRetFlag;
1042 bRetFlag=OtherSegment(P,L,Par);
1046 //=======================================================================
1047 //function : Intersector
1049 //=======================================================================
1051 IntCurvesFace_Intersector& BRepClass3d_SolidExplorer::Intersector(const TopoDS_Face& F) const {
1052 void *ptr = (void*)(myMapOfInter.Find(F));
1053 IntCurvesFace_Intersector& curr = (*((IntCurvesFace_Intersector *)ptr));
1057 //=======================================================================
1060 //=======================================================================
1062 const Bnd_Box& BRepClass3d_SolidExplorer::Box() const {
1066 //=======================================================================
1067 //function : DumpSegment
1069 //=======================================================================
1071 void BRepClass3d_SolidExplorer::DumpSegment(const gp_Pnt&,
1073 const Standard_Real,
1074 const TopAbs_State) const
1081 const TopoDS_Shape& BRepClass3d_SolidExplorer::GetShape() const