-// File: BRepClass3d_SolidExplorer.cxx
-// Created: Thu Mar 10 14:52:22 1994
-// Author: Laurent BUCHARD
-// <lbr@fuegox>
+// Created on: 1994-03-10
+// Created by: Laurent BUCHARD
+// Copyright (c) 1994-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// 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 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
// Modifed: Porting NT 7-5-97 DPF (stdio.h)
// Apr 16 2002 eap, classification against infinite solid (occ299)
#include <BRep_Tool.hxx>
#include <BRepClass_FaceClassifier.hxx>
//<-OCC454(apo)
+#include <BRepTopAdaptor_FClass2d.hxx>
+
//=======================================================================
//function : FindAPointInTheFace
{
TopoDS_Edge Edge = TopoDS::Edge (faceexplorer.Current());
c.Initialize (Edge, face);
-#ifdef DEB
- Standard_Integer nbinterval =
-#endif
- c.NbIntervals(GeomAbs_C1);
c.D1((c.LastParameter() - c.FirstParameter()) * param_ + c.FirstParameter(),P,T);
Standard_Real x = T.X();
}
}
- if (APointExist)
+ while (APointExist)
{
ParamInit *= 0.41234;
u_ = P.X() + ParamInit* T.X();
v_ = P.Y() + ParamInit* T.Y();
+
+ //Additional check
+ BRepTopAdaptor_FClass2d Classifier(face, Precision::Confusion());
+ gp_Pnt2d aPnt2d(u_, v_);
+ TopAbs_State StateOfResultingPoint = Classifier.Perform(aPnt2d);
+ if (StateOfResultingPoint != TopAbs_IN)
+ return Standard_False;
+
BRepAdaptor_Surface s;
s.Initialize (face, Standard_False);
s.D1 (u_, v_, APoint_, theVecD1U, theVecD1V);
- return Standard_True;
+
+ if(theVecD1U.CrossMagnitude(theVecD1V) > gp::Resolution())
+ return Standard_True;
+
+ if(ParamInit < Precision::PConfusion())
+ return Standard_False;
}
}
return Standard_False;
void *ptr = (void*)(myMapOfInter.Find(Face));
if(ptr) {
const IntCurvesFace_Intersector& TheIntersector = (*((IntCurvesFace_Intersector *)ptr));
+ // Check if the point is already in the face
+ if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u_,v_))==TopAbs_IN) {
+ gp_Pnt aPnt;
+ surf->D1(u_, v_, aPnt, theVecD1U, theVecD1V);
+ if (aPnt.SquareDistance(APoint_) < Precision::Confusion() * Precision::Confusion())
+ return Standard_True;
+ }
+
//-- Take 4 points in each Quarter of surface
//-- -> Index : 1 -> 16
//--
}
}
}
-
+
for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- 0 0 u decreases
- for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- X 0 v decreases
- if(++NbPntCalc>=IndexPoint) {
- if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) {
- u_=u; v_=v;
- surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
- IndexPoint = NbPntCalc;
- return(Standard_True);
- }
- }
- }
+ for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- X 0 v decreases
+ if(++NbPntCalc>=IndexPoint) {
+ if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) {
+ u_=u; v_=v;
+ surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
+ IndexPoint = NbPntCalc;
+ return(Standard_True);
+ }
+ }
+ }
}
for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- X 0 u decreases
- for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) { //-- 0 0 v increases
- if(++NbPntCalc>=IndexPoint) {
- if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) {
- u_=u; v_=v;
- surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
- IndexPoint = NbPntCalc;
- return(Standard_True);
- }
- }
- }
+ for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) { //-- 0 0 v increases
+ if(++NbPntCalc>=IndexPoint) {
+ if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) {
+ u_=u; v_=v;
+ surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
+ IndexPoint = NbPntCalc;
+ return(Standard_True);
+ }
+ }
+ }
}
for(u=du+(U1+U2)*0.5; u<U2; u+=du) { //-- 0 0 u increases
- for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- 0 X v decreases
- if(++NbPntCalc>=IndexPoint) {
- if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) {
- u_=u; v_=v;
- surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
- IndexPoint = NbPntCalc;
- return(Standard_True);
- }
- }
- }
+ for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- 0 X v decreases
+ if(++NbPntCalc>=IndexPoint) {
+ if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) {
+ u_=u; v_=v;
+ surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
+ IndexPoint = NbPntCalc;
+ return(Standard_True);
+ }
+ }
+ }
}
//-- the remainder
du = (U2-U1)/37.0;
if(dv<1e-12) dv=1e-12;
for(u=du+U1; u<U2; u+=du) {
- for(v=dv+V1; v<V2; v+=dv) {
- if(++NbPntCalc>=IndexPoint) {
- if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) {
- u_=u; v_=v;
- surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
- IndexPoint = NbPntCalc;
- return(Standard_True);
- }
- }
- }
+ for(v=dv+V1; v<V2; v+=dv) {
+ if(++NbPntCalc>=IndexPoint) {
+ if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) {
+ u_=u; v_=v;
+ surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
+ IndexPoint = NbPntCalc;
+ return(Standard_True);
+ }
+ }
+ }
}
u=(U1+U2)*0.5;
v=(V1+V2)*0.5;
if(++NbPntCalc>=IndexPoint) {
- if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) {
- u_=u; v_=v;
- surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
- IndexPoint = NbPntCalc;
- return(Standard_True);
- }
+ if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) {
+ u_=u; v_=v;
+ surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
+ IndexPoint = NbPntCalc;
+ return(Standard_True);
+ }
}
}
IndexPoint = NbPntCalc;
//function : LimitInfiniteUV
//purpose : Limit infinite parameters
//=======================================================================
-
static void LimitInfiniteUV (Standard_Real& U1,
- Standard_Real& V1,
- Standard_Real& U2,
- Standard_Real& V2)
+ Standard_Real& V1,
+ Standard_Real& U2,
+ Standard_Real& V2)
{
Standard_Boolean
infU1 = Precision::IsNegativeInfinite(U1),
if (infU2) U2 = 1e10;
if (infV2) V2 = 1e10;
}
-// Modified by skv - Tue Sep 16 13:50:38 2003 OCC578 Begin
-//OCC454(apo)->
-// static Standard_Boolean IsInfiniteUV (Standard_Real& U1, Standard_Real& V1, Standard_Real& U2, Standard_Real& V2) {
-// return (Precision::IsNegativeInfinite(U1) || Precision::IsNegativeInfinite(V1) ||
-// Precision::IsNegativeInfinite(U2) || Precision::IsNegativeInfinite(V2));
-// }
-static Standard_Integer IsInfiniteUV (Standard_Real& U1, Standard_Real& V1,
- Standard_Real& U2, Standard_Real& V2) {
+//=======================================================================
+//function : IsInfiniteUV
+//purpose :
+//=======================================================================
+static Standard_Integer IsInfiniteUV (Standard_Real& U1,
+ Standard_Real& V1,
+ Standard_Real& U2,
+ Standard_Real& V2)
+{
Standard_Integer aVal = 0;
if (Precision::IsInfinite(U1))
// The Second Call provide a line to the second face
// and so on.
//=======================================================================
-//modified by NIZNHY-PKV Thu Nov 14 14:34:05 2002 f
-//void BRepClass3d_SolidExplorer::OtherSegment(const gp_Pnt& P,
-// gp_Lin& L,
-// Standard_Real& _Par)
- Standard_Integer BRepClass3d_SolidExplorer::OtherSegment(const gp_Pnt& P,
- gp_Lin& L,
- Standard_Real& _Par)
-//modified by NIZNHY-PKV Thu Nov 14 14:34:10 2002 t
+Standard_Integer BRepClass3d_SolidExplorer::OtherSegment(const gp_Pnt& P,
+ gp_Lin& L,
+ Standard_Real& _Par)
{
const Standard_Real TolU = Precision::PConfusion();
const Standard_Real TolV = TolU;
TopoDS_Face face;
TopExp_Explorer faceexplorer;
- //TopExp_Explorer edgeexplorer;
gp_Pnt APoint;
gp_Vec aVecD1U, aVecD1V;
Standard_Real maxscal=0;
Standard_Boolean ptfound=Standard_False;
Standard_Real Par;
- //Standard_Integer i=1;
Standard_Real _u,_v;
Standard_Integer IndexPoint=0;
Standard_Integer NbPointsOK=0;
Standard_Integer NbFacesInSolid=0;
- do {
+ for(;;) {
myFirstFace++;
faceexplorer.Init(myShape,TopAbs_FACE);
// look for point on face starting from myFirstFace
//
//avoid process faces from uncorrected shells
if( Abs (U2 - U1) < 1.e-12 || Abs(V2 - V1) < 1.e-12) {
- //modified by NIZNHY-PKV Thu Nov 14 15:03:18 2002 f
- //gp_Vec avoidV(gp_Pnt(0.,0.,0.),gp_Pnt(0.,0.,1.));
- //gp_Lin avoidL(gp_Pnt(0.,0.,0.),avoidV);
- //_Par = RealLast();
- //L = avoidL;
- return 2;
- //return ;
- //modified by NIZNHY-PKV Thu Nov 14 12:25:33 2002 t
+ return 2;
}
//
Standard_Real svmyparam=myParamOnEdge;
//
- // Modified by skv - Tue Sep 16 13:55:27 2003 OCC578 Begin
// Check if the point is on the face or the face is infinite.
Standard_Integer anInfFlag = IsInfiniteUV(U1,V1,U2,V2);
+ // default values
+ _u = (U1 + U2) * 0.5;
+ _v = (V1 + V2) * 0.5;
-// if(IsInfiniteUV(U1,V1,U2,V2)){//OCC454(apo)->
GeomAdaptor_Surface GA(BRep_Tool::Surface(face));
- Extrema_ExtPS Ext(P,GA,TolU,TolV);
+ Extrema_ExtPS Ext(P, GA, TolU, TolV);
+ //
if (Ext.IsDone() && Ext.NbExt() > 0) {
- // evaluate the lower distance and its index;
- Standard_Real Dist2, Dist2Min = Ext.SquareDistance(1);
- Standard_Integer iNear = 1, i = 2, iEnd = Ext.NbExt();
- for (i = 2; i <= iEnd; i++) {
- Dist2 = Ext.SquareDistance(i);
- if (Dist2 < Dist2Min) {
- Dist2Min = Dist2; iNear = i;
- }
- }
- //modified by NIZNHY-PKV Thu Nov 14 12:31:01 2002 f
- Standard_Real aDist2Tresh=1.e-24;
-
- if (Dist2Min<aDist2Tresh) {
- if (anInfFlag) {
- return 1;
- } else {
- BRepClass_FaceClassifier classifier2d;
- Standard_Real aU;
- Standard_Real aV;
-
- (Ext.Point(iNear)).Parameter(aU, aV);
-
- gp_Pnt2d aPuv(aU, aV);
-
- classifier2d.Perform(face,aPuv,Precision::PConfusion());
-
- TopAbs_State aState = classifier2d.State();
-
- if (aState == TopAbs_IN || aState == TopAbs_ON)
- return 1;
- else
- return 3; // skv - the point is on surface but outside face.
- }
- }
- //modified by NIZNHY-PKV Thu Nov 14 12:31:03 2002 t
- if (anInfFlag) {
- APoint = (Ext.Point(iNear)).Value();
- gp_Vec V(P,APoint);
- _Par = V.Magnitude();
- L = gp_Lin(P,V);
- ptfound=Standard_True;
- //modified by NIZNHY-PKV Thu Nov 14 12:25:28 2002 f
- //return ;
- return 0;
- //modified by NIZNHY-PKV Thu Nov 14 12:25:33 2002 t
- }
- //<-OCC454(apo)
-// }else{
+ Standard_Integer i, iNear, iEnd;
+ Standard_Real aUx, aVx, Dist2, Dist2Min;
+ Extrema_POnSurf aPx;
+ //
+ iNear = 1;
+ Dist2Min = Ext.SquareDistance(1);
+ iEnd = Ext.NbExt();
+ for (i = 2; i <= iEnd; i++) {
+ aPx=Ext.Point(i);
+ aPx.Parameter(aUx, aVx);
+ if (aUx>=U1 && aUx<=U2 && aVx>=V1 && aVx<=V2) {
+ Dist2 = Ext.SquareDistance(i);
+ if (Dist2 < Dist2Min) {
+ Dist2Min = Dist2;
+ iNear = i;
+ }
+ }
+ }
+ //
+ Standard_Real aDist2Tresh=1.e-24;
+ //
+ if (Dist2Min<aDist2Tresh) {
+ if (anInfFlag) {
+ return 1;
+ }
+ else {
+ BRepClass_FaceClassifier classifier2d;
+ Standard_Real aU;
+ Standard_Real aV;
+
+ (Ext.Point(iNear)).Parameter(aU, aV);
+
+ gp_Pnt2d aPuv(aU, aV);
+
+ classifier2d.Perform(face,aPuv,Precision::PConfusion());
+
+ TopAbs_State aState = classifier2d.State();
+
+ if (aState == TopAbs_IN || aState == TopAbs_ON) {
+ return 1;
+ }
+ else {
+ return 3; // skv - the point is on surface but outside face.
+ }
+ }
+ }
+ if (anInfFlag) {
+ APoint = (Ext.Point(iNear)).Value();
+ gp_Vec V(P,APoint);
+ _Par = V.Magnitude();
+ L = gp_Lin(P,V);
+ ptfound=Standard_True;
+ return 0;
+ }
+
+ // set the parameters found by extrema
+ aPx = Ext.Point(iNear);
+ aPx.Parameter(_u, _v);
+ APoint = aPx.Value();
}
//The point is not ON the face or surface. The face is restricted.
// find point in a face not too far from a projection of P on face
- // Modified by skv - Tue Sep 16 15:25:00 2003 OCC578 End
-
do {
if (PointInTheFace (face, APoint, _u, _v, myParamOnEdge, ++IndexPoint, surf,
U1, V1, U2, V2,
++NbPointsOK;
gp_Vec V (P, APoint);
Par = V.Magnitude();
- if (Par > gp::Resolution())
+ if (Par > gp::Resolution() &&
+ aVecD1U.Magnitude() > gp::Resolution() &&
+ aVecD1V.Magnitude() > gp::Resolution())
{
gp_Vec Norm = aVecD1U.Crossed (aVecD1V);
Standard_Real tt = Norm.Magnitude();
while(IndexPoint<200 && NbPointsOK<16);
myParamOnEdge=svmyparam;
- if(maxscal>0.2) {
- //modified by NIZNHY-PKV Thu Nov 14 12:25:28 2002 f
- //return ;
- return 0;
- //modified by NIZNHY-PKV Thu Nov 14 12:25:33 2002 t
+ if(maxscal>0.2) {
+ return 0;
}
Standard_Boolean encoreuneface = faceexplorer.More();
if(ptfound==Standard_False && encoreuneface==Standard_False) {
- if(myParamOnEdge < 0.0001) {
- //-- This case takes place when the point is on the solid
- //-- and this solid is reduced to a face
- gp_Pnt PBidon(P.X()+1.0,P.Y(),P.Z());
- gp_Vec V(P,PBidon);
- Par= 1.0;
- _Par=Par;
- L = gp_Lin(P,V);
- //modified by NIZNHY-PKV Thu Nov 14 12:25:28 2002 f
- //return ;
- return 0;
- //modified by NIZNHY-PKV Thu Nov 14 12:25:33 2002 t
- //-- cout<<" FindAPoint **** Pas OK "<<endl;
- }
+ if(myParamOnEdge < 0.0001) {
+ //-- This case takes place when the point is on the solid
+ //-- and this solid is reduced to a face
+ gp_Pnt PBidon(P.X()+1.0,P.Y(),P.Z());
+ gp_Vec V(P,PBidon);
+ Par= 1.0;
+ _Par=Par;
+ L = gp_Lin(P,V);
+ return 0;
+ }
}
} //-- Exploration of the faces
if(NbFacesInSolid==0) {
_Par=0.0;
myReject=Standard_True;
-#if DEB
+#ifdef OCCT_DEBUG
cout<<"\nWARNING : BRepClass3d_SolidExplorer.cxx (Solid without face)"<<endl;
#endif
- //modified by NIZNHY-PKV Thu Nov 14 12:25:28 2002 f
- //return ;
return 0;
- //modified by NIZNHY-PKV Thu Nov 14 12:25:33 2002 t
}
if(ptfound) {
- //modified by NIZNHY-PKV Thu Nov 14 12:25:28 2002 f
- //return ;
return 0;
- //modified by NIZNHY-PKV Thu Nov 14 12:25:33 2002 t
}
myFirstFace = 0;
if(myParamOnEdge==0.512345) myParamOnEdge = 0.4;
else if(myParamOnEdge==0.2) myParamOnEdge = 0.8;
else if(myParamOnEdge==0.8) myParamOnEdge = 0.1;
else if(myParamOnEdge==0.1) myParamOnEdge = 0.9;
- else { myParamOnEdge*=0.5; }
-
-
- } //-- do { ... }
- while(1);
- //modified by NIZNHY-PKV Thu Nov 14 12:25:28 2002 f
- //return ;
- return 0;
- //modified by NIZNHY-PKV Thu Nov 14 12:25:33 2002 t
+ //
+ else {
+ myParamOnEdge*=0.5;
+ if(myParamOnEdge < 0.0001) {
+ gp_Pnt PBidon(P.X()+1.0,P.Y(),P.Z());
+ gp_Vec V(P,PBidon);
+ Par= 1.0;
+ _Par=Par;
+ L = gp_Lin(P,V);
+ return 0;
+ }
+ }
+ } //-- for(;;) { ... }
}
// Modified by skv - Thu Sep 4 12:30:14 2003 OCC578 Begin
myReject=Standard_False; //-- at least one face in the solid
}
-#if DEB
+#ifdef OCCT_DEBUG
if(myReject) {
cout<<"\nWARNING : BRepClass3d_SolidExplorer.cxx (Solid without face)"<<endl;
}
return(Standard_False);
}
-#ifdef DEB
+#ifdef OCCT_DEBUG
#include <TopAbs_State.hxx>
#endif
// one intersection with the shape boundary to
// compute intersections.
//=======================================================================
-//modified by NIZNHY-PKV Thu Nov 14 14:40:35 2002 f
-//void BRepClass3d_SolidExplorer::Segment(const gp_Pnt& P,
-// gp_Lin& L,
-// Standard_Real& Par) {
-// myFirstFace = 0;
-// OtherSegment(P,L,Par);
-//}
- Standard_Integer BRepClass3d_SolidExplorer::Segment(const gp_Pnt& P,
- gp_Lin& L,
- Standard_Real& Par)
+Standard_Integer BRepClass3d_SolidExplorer::Segment(const gp_Pnt& P,
+ gp_Lin& L,
+ Standard_Real& Par)
{
Standard_Integer bRetFlag;
myFirstFace = 0;
bRetFlag=OtherSegment(P,L,Par);
return bRetFlag;
}
-//modified by NIZNHY-PKV Thu Nov 14 14:41:48 2002 t
//=======================================================================
//function : Intersector
IntCurvesFace_Intersector& BRepClass3d_SolidExplorer::Intersector(const TopoDS_Face& F) const {
void *ptr = (void*)(myMapOfInter.Find(F));
-#ifndef DEB
IntCurvesFace_Intersector& curr = (*((IntCurvesFace_Intersector *)ptr));
return curr;
-#else
- return(*((IntCurvesFace_Intersector *)ptr));
-#endif
}
//=======================================================================
//=======================================================================
void BRepClass3d_SolidExplorer::DumpSegment(const gp_Pnt&,
- const gp_Lin&,
- const Standard_Real,
- const TopAbs_State) const
+ const gp_Lin&,
+ const Standard_Real,
+ const TopAbs_State) const
{
-#ifdef DEB
+#ifdef OCCT_DEBUG
#endif
}