//
// This file is part of Open CASCADE Technology software library.
//
-// This library is free software; you can redistribute it and / or modify it
-// under the terms of the GNU Lesser General Public version 2.1 as published
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
// Modified by skv - Thu Sep 4 11:22:05 2003 OCC578
-#include <BRepClass3d_SClassifier.ixx>
-
-#include <gp_Pnt.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepClass3d_Intersector3d.hxx>
+#include <BRepClass3d_SClassifier.hxx>
+#include <BRepClass3d_SolidExplorer.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
+#include <ElCLib.hxx>
+#include <Geom_Surface.hxx>
#include <gp_Lin.hxx>
+#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
-#include <BRepClass3d_Intersector3d.hxx>
-#include <TopoDS.hxx>
-
#include <IntCurvesFace_Intersector.hxx>
-// modified by NIZHNY-MKK Mon Jun 21 15:13:40 2004
+#include <math_BullardGenerator.hxx>
#include <Precision.hxx>
-#include <ElCLib.hxx>
-#include <Geom_Surface.hxx>
-#include <BRep_Tool.hxx>
+#include <Standard_DomainError.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Face.hxx>
+
+#include <vector>
+// modified by NIZHNY-MKK Mon Jun 21 15:13:40 2004
static
- void FaceNormal (const TopoDS_Face& aF,
- const Standard_Real U,
- const Standard_Real V,
- gp_Dir& aDN);
+ Standard_Boolean FaceNormal (const TopoDS_Face& aF,
+ const Standard_Real U,
+ const Standard_Real V,
+ gp_Dir& aDN);
static
Standard_Real GetAddToParam(const gp_Lin& L,const Standard_Real P,const Bnd_Box& B);
//=======================================================================
void BRepClass3d_SClassifier::PerformInfinitePoint(BRepClass3d_SolidExplorer& aSE,
const Standard_Real /*Tol*/) {
- //-- Idea : Take point A in face1 and point B in face B
- //-- (if there is only one face, take 2 points in the same face.)
- //--
- //-- Intersect straight line AB with the solid and produce transition of the
- //-- first point. If the solid has only one face and the straight line AB does not cut it
- //-- it is not possible to decide.
+ //Take a normal to the first extracted face in its random inner point
+ //and intersect this reversed normal with the faces of the solid.
+ //If the min.par.-intersection point is
+ // a) inner point of a face
+ // b) transition is not TANGENT
+ // (the line does not touch the face but pierces it)
+ //then set <myState> to IN or OUT according to transition
+ //else take the next random point inside the min.par.-intersected face
+ //and continue
+
if(aSE.Reject(gp_Pnt(0,0,0))) {
myState=3; //-- in ds solid case without face
return;
//
//------------------------------------------------------------
// 1
- Standard_Boolean bFound, bFlag;
- Standard_Integer nump;
- Standard_Real aParam, aU1 = 0., aV1 = 0., aU2 = 0., aV2 = 0.;
- gp_Pnt A,B;
- gp_Dir aDN1, aDN2;
- TopoDS_Face aF1, aF2;
- //
- nump = 0;
- aParam = 0.5;
+ Standard_Boolean bFound;
+ Standard_Real aParam, aU = 0., aV = 0.;
+ gp_Pnt aPoint;
+ gp_Dir aDN;
+
+ math_BullardGenerator aRandomGenerator;
myFace.Nullify();
- myState=2;
- for(aSE.InitShell(); aSE.MoreShell() && nump<2; aSE.NextShell()) {
- for(aSE.InitFace(); aSE.MoreFace() && nump<2; ) {
- TopoDS_Face aF = aSE.CurrentFace();
- aSE.NextFace();
- if(!nump) {
- nump++;
- bFound=aSE.FindAPointInTheFace(aF, A, aU1, aV1, aParam);
- if (!bFound) {
- return;
- }
- aF1=aF;
- if(!aSE.MoreFace()) {
- nump++;
- bFound=aSE.FindAPointInTheFace(aF, B, aU2, aV2, aParam);
- if (!bFound) {
- return;
- }
- aF2=aF;
- }
- }// if(nump==0) {
- else if(nump==1) {
- bFound=aSE.FindAPointInTheFace(aF, B, aU2, aV2, aParam);
- if(!bFound) {
- return;
- }
- aF2=aF;
- nump++;
- }
- }// for(aSE.InitFace(); aSE.MoreFace() && nump<2; ) {
- }// for(aSE.InitShell(); aSE.MoreShell() && nump<2; aSE.NextShell()) {
- //
- //------------------------------------------------------------
- // 2
- Standard_Integer cpasbon;
- Standard_Real parmin, aD2, aSP;
- IntCurveSurface_TransitionOnCurve aTC;
- TopAbs_State aState;
- //
- parmin = RealLast();
- //
- bFlag=Standard_False;
- if (aF1!=aF2) {
- FaceNormal(aF1, aU1, aV1, aDN1);
- FaceNormal(aF2, aU2, aV2, aDN2);
- aSP=1.-aDN1*aDN2;
- if (aSP < 1.e-5) {
- bFlag=!bFlag;
+ myState=2;
+
+ // Collect faces in sequence to iterate
+ std::vector<TopoDS_Face> aFaces;
+ for (aSE.InitShell(); aSE.MoreShell(); aSE.NextShell())
+ {
+ for (aSE.InitFace(); aSE.MoreFace(); aSE.NextFace())
+ {
+ aFaces.push_back (aSE.CurrentFace());
}
}
- //
- aD2=A.SquareDistance(B);
- if(aD2<0.000001 || bFlag) {
- B.SetCoord(A.X()+1,A.Y()+1,A.Z()+1);
- }
- //
- cpasbon = 0;
- gp_Vec AB(A,B);
- //
- do {
- switch (cpasbon)
+
+ // iteratively try up to 10 probing points from each face
+ const int NB_MAX_POINTS_PER_FACE = 10;
+ for (int itry = 0; itry < NB_MAX_POINTS_PER_FACE; itry++)
+ {
+ for (std::vector<TopoDS_Face>::iterator iFace = aFaces.begin(); iFace != aFaces.end(); ++iFace)
+ {
+ TopoDS_Face aF = *iFace;
+
+ TopAbs_State aState = TopAbs_OUT;
+ IntCurveSurface_TransitionOnCurve aTransition = IntCurveSurface_Tangent;
+
+ aParam = 0.1 + 0.8 * aRandomGenerator.NextReal(); // random number in range [0.1, 0.9]
+ bFound = aSE.FindAPointInTheFace(aF, aPoint, aU, aV, aParam);
+ if (!bFound || !FaceNormal(aF, aU, aV, aDN))
+ continue;
+
+ gp_Lin aLin(aPoint, -aDN);
+ Standard_Real parmin = RealLast();
+ for (aSE.InitShell();aSE.MoreShell();aSE.NextShell()) {
+ if (aSE.RejectShell(aLin) == Standard_False) {
+ for (aSE.InitFace();aSE.MoreFace(); aSE.NextFace()) {
+ if (aSE.RejectFace(aLin) == Standard_False) {
+ TopoDS_Shape aLocalShape = aSE.CurrentFace();
+ TopoDS_Face CurFace = TopoDS::Face(aLocalShape);
+ IntCurvesFace_Intersector& Intersector3d = aSE.Intersector(CurFace);
+ Intersector3d.Perform(aLin,-RealLast(),parmin);
+
+ if(Intersector3d.IsDone()) {
+ if(Intersector3d.NbPnt()) {
+ Standard_Integer imin = 1;
+ for (Standard_Integer i = 2; i <= Intersector3d.NbPnt(); i++)
+ if (Intersector3d.WParameter(i) < Intersector3d.WParameter(imin))
+ imin = i;
+ parmin = Intersector3d.WParameter(imin);
+ aState = Intersector3d.State(imin);
+ aTransition = Intersector3d.Transition(imin);
+ }
+ }
+ }
+ }
+ }
+ else
+ myState = 1;
+ } //end of loop on the whole solid
+
+ if (aState == TopAbs_IN)
{
- case 1 : AB.SetX(-AB.X());break;
- case 2 : AB.SetY(-AB.Y());break;
- case 3 : AB.SetZ(-AB.Z());break;
- case 4 : AB.SetY(-AB.Y());break;
- case 5 : AB.SetX(-AB.X());break;
- }
- gp_Lin L(A,gp_Dir(AB));
- //-- cout<<"\npoint A "<<A.X()<<" "<<A.Y()<<" "<<A.Z()<<endl;
- //-- cout<<"\npoint B "<<B.X()<<" "<<B.Y()<<" "<<B.Z()<<endl;
- for(aSE.InitShell();aSE.MoreShell();aSE.NextShell()) {
- if(aSE.RejectShell(L) == Standard_False) {
- for(aSE.InitFace();aSE.MoreFace(); aSE.NextFace()) {
- if(aSE.RejectFace(L) == Standard_False) {
- TopoDS_Shape aLocalShape = aSE.CurrentFace();
- TopoDS_Face f = TopoDS::Face(aLocalShape);
- IntCurvesFace_Intersector& Intersector3d = aSE.Intersector(f);
- Intersector3d.Perform(L,-RealLast(),parmin);
-
- if(Intersector3d.IsDone()) {
- if(Intersector3d.NbPnt()) {
- if(Intersector3d.WParameter(1) < parmin) {
- aState=Intersector3d.State(1);
- parmin = Intersector3d.WParameter(1);
- if(aState==TopAbs_IN || aState==TopAbs_ON) {
- aTC=Intersector3d.Transition(1);
- //-- The intersection point between the line and a face F
- // -- of the solid is in the face F
- if(aTC == IntCurveSurface_Out) {
- //-- The line is going from inside the solid to outside
- //-- the solid.
- myState = 3; //-- IN --
- }
- else if(aTC == IntCurveSurface_In) {
- myState = 4; //-- OUT --
- }
- myFace = f;
- }
- /*
- else if(Intersector3d.State(1)==TopAbs_ON) {
- //-- The intersection point between the line and a face F
- //-- of the solid is in the face F
- if(Intersector3d.Transition(1) == IntCurveSurface_Out) {
- //-- The line is going from inside the solid to outside
- //-- the solid.
- myState = 3; //-- IN --
- }
- else if(Intersector3d.Transition(1) == IntCurveSurface_In) {
- myState = 4; //-- OUT --
- }
- //-- myState = 2;
- myFace = f;
- }
- */
- }
-
- else {
- //-- No point has been found by the Intersector3d.
- //-- Or a Point has been found with a greater parameter.
- }
- }
- }
- }
- } //-- Exploration of the faces
- } //-- Shell has not been rejected
- else {
- myState=1;
+ if (aTransition == IntCurveSurface_Out) {
+ //-- The line is going from inside the solid to outside
+ //-- the solid.
+ myState = 3; //-- IN --
+ return;
+ }
+ else if (aTransition == IntCurveSurface_In) {
+ myState = 4; //-- OUT --
+ return;
+ }
}
- } //-- Exploration of the shells
- cpasbon++;
- }
- while(cpasbon!=0 && cpasbon<5);
+ } // iteration by faces
+ } // iteration by points
}
+
//=======================================================================
//function : Perform
//purpose :
if(Intersector3d.IsDone()) {
Standard_Integer i;
for (i=1; i <= Intersector3d.NbPnt(); i++) {
- if(Abs(Intersector3d.WParameter(i)) < Abs(parmin)) {
+ if(Abs(Intersector3d.WParameter(i)) < Abs(parmin) - Precision::PConfusion()) {
parmin = Intersector3d.WParameter(i);
// Modified by skv - Thu Sep 4 12:46:32 2003 OCC578 Begin
IntCurveSurface_TransitionOnCurve tran = Intersector3d.Transition(i);
if (tran == IntCurveSurface_Tangent) {
-#ifdef DEB
+#ifdef OCCT_DEBUG
cout<<"*Problem ds BRepClass3d_SClassifier.cxx"<<endl;
#endif
continue; // ignore this point
}
// Modified by skv - Thu Sep 4 11:42:03 2003 OCC578 End
-#ifdef DEB
+#ifdef OCCT_DEBUG
//#################################################
SolidExplorer.DumpSegment(P,L,parmin,State());
//#################################################
//function : FaceNormal
//purpose :
//=======================================================================
-void FaceNormal (const TopoDS_Face& aF,
- const Standard_Real U,
- const Standard_Real V,
- gp_Dir& aDN)
+Standard_Boolean FaceNormal (const TopoDS_Face& aF,
+ const Standard_Real U,
+ const Standard_Real V,
+ gp_Dir& aDN)
{
gp_Pnt aPnt ;
gp_Vec aD1U, aD1V, aN;
aS=BRep_Tool::Surface(aF);
aS->D1 (U, V, aPnt, aD1U, aD1V);
aN=aD1U.Crossed(aD1V);
+ if (aN.Magnitude() <= gp::Resolution())
+ return Standard_False;
+
aN.Normalize();
aDN.SetXYZ(aN.XYZ());
if (aF.Orientation() == TopAbs_REVERSED){
aDN.Reverse();
}
- return;
+ return Standard_True;
}