1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-26 10:19:45 +03:00
occt/src/TopOpeBRep/TopOpeBRep_FacesIntersector.cxx
abv 1d0a9d4d46 0023664: Eliminate linker warnings on import of local symbol
Standard_IMPORT removed or replaced by 'export' where it applies to a symbol defined in the same toolkit
2013-02-01 15:42:05 +04:00

1550 lines
51 KiB
C++
Executable File

// Created on: 1993-11-18
// Created by: Jean Yves LEBEY
// Copyright (c) 1993-1999 Matra Datavision
// Copyright (c) 1999-2012 OPEN CASCADE SAS
//
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 6.5 (the "License"). You may not use the content of this file
// except in compliance with the License. Please obtain a copy of the License
// at http://www.opencascade.org and read it completely before using this file.
//
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
//
// The Original Code and all software distributed under the License is
// distributed on an "AS IS" basis, without warranty of any kind, and the
// Initial Developer hereby disclaims all such warranties, including without
// limitation, any warranties of merchantability, fitness for a particular
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
#include <TopOpeBRep_FacesIntersector.ixx>
#ifdef DRAW
#include <TopOpeBRep_DRAW.hxx>
#endif
#include <IntPatch_LineConstructor.hxx>
#include <TopOpeBRep_TypeLineCurve.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Edge.hxx>
#include <BRep_Tool.hxx>
#include <TopExp_Explorer.hxx>
#include <TopOpeBRepTool_ShapeTool.hxx>
#include <Precision.hxx>
#include <Geom_Curve.hxx>
#include <Standard_ProgramError.hxx>
#include <TCollection_AsciiString.hxx>
#include <Standard_CString.hxx>
#include <BRepTools.hxx>
#include <TopOpeBRepTool_tol.hxx>
Standard_EXPORT Standard_Real GLOBAL_tolFF = 1.e-7;
#ifdef DEB
#include <TopAbs.hxx>
extern Standard_Boolean TopOpeBRep_GettraceFI();
extern Standard_Boolean TopOpeBRep_GettraceFITOL();
extern Standard_Boolean TopOpeBRep_GettraceSAVFF();
Standard_Integer SAVFFi1 = 0;
Standard_Integer SAVFFi2 = 0;
static void SAVFF(const TopoDS_Face& F1,const TopoDS_Face& F2)
{
TCollection_AsciiString an1("SAVA");if (SAVFFi1) an1=an1+SAVFFi1;
TCollection_AsciiString an2("SAVB");if (SAVFFi2) an2=an2+SAVFFi2;
Standard_CString n1=an1.ToCString();Standard_CString n2=an2.ToCString();
#ifdef DRAW
cout<<"FaceIntersector : set "<<n1<<","<<n2<<endl;DBRep::Set(n1,F1);DBRep::Set(n2,F2);
#endif
cout<<"FaceIntersector : write "<<n1<<","<<n2<<endl;BRepTools::Write(F1,n1);BRepTools::Write(F2,n2);
}
extern Standard_Boolean TopOpeBRepTool_GettraceKRO();
#include <TopOpeBRepTool_KRO.hxx>
Standard_EXPORT TOPKRO KRO_DSFILLER_INTFF("intersection face/face");
#endif
// NYI
// NYI : IntPatch_Intersection : TolArc,TolTang exact definition
// NYI
// modified by NIZHNY-MKK Mon Apr 2 12:14:32 2001.BEGIN
#include <IntPatch_WLine.hxx>
#include <IntPatch_RLine.hxx>
#include <IntPatch_Point.hxx>
#include <Adaptor3d_HSurface.hxx>
#include <Adaptor3d_TopolTool.hxx>
#include <Adaptor3d_HVertex.hxx>
#include <Adaptor2d_HCurve2d.hxx>
#include <Geom2dInt_TheProjPCurOfGInter.hxx>
static Standard_Boolean TestWLineAlongRestriction(const Handle(IntPatch_WLine)& theWLine,
const Standard_Integer theRank,
const Handle(Adaptor3d_HSurface)& theSurface,
const Handle(Adaptor3d_TopolTool)& theDomain,
const Standard_Real theTolArc);
static
Handle(IntPatch_RLine) BuildRLineBasedOnWLine(const Handle(IntPatch_WLine)& theWLine,
const Handle(Adaptor2d_HCurve2d)& theArc,
const Standard_Integer theRank);
static
Handle(IntPatch_RLine) BuildRLine(const IntPatch_SequenceOfLine& theSeqOfWLine,
const Standard_Integer theRank,
const Handle(Adaptor3d_HSurface)& theSurface,
const Handle(Adaptor3d_TopolTool)& theDomain,
const Standard_Real theTolArc);
static void TestWLinesToAnArc(IntPatch_SequenceOfLine& slin,
const Handle(Adaptor3d_HSurface)& theSurface1,
const Handle(Adaptor3d_TopolTool)& theDomain1,
const Handle(Adaptor3d_HSurface)& theSurface2,
const Handle(Adaptor3d_TopolTool)& theDomain2,
const Standard_Real theTolArc);
// modified by NIZHNY-MKK Mon Apr 2 12:14:38 2001.END
// modified by NIZHNY-OFV Fri Mar 29 12:37:21 2002.BEGIN
#include <TColgp_SequenceOfPnt.hxx>
#include <TopExp.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <Extrema_ExtPS.hxx>
#include <Extrema_ExtPC.hxx>
#include <Extrema_POnSurf.hxx>
#include <GeomAdaptor_Curve.hxx>
static void MergeWLinesIfAllSegmentsAlongRestriction(IntPatch_SequenceOfLine& theSlin,
const Handle(Adaptor3d_HSurface)& theSurface1,
const Handle(Adaptor3d_TopolTool)& theDomain1,
const Handle(Adaptor3d_HSurface)& theSurface2,
const Handle(Adaptor3d_TopolTool)& theDomain2,
const Standard_Real theTolArc);
//------------------------------------------------------------------------------------------------
static Standard_Integer GetArc(IntPatch_SequenceOfLine& theSlin,
const Standard_Integer& theRankS,
const Handle(Adaptor3d_HSurface)& theSurfaceObj,
const Handle(Adaptor3d_TopolTool)& theDomainObj,
const Handle(Adaptor3d_HSurface)& theSurfaceTool,
const gp_Pnt& theTestPoint,
Standard_Real& theVrtxTol,
Handle(IntSurf_LineOn2S)& theLineOn2S,
Standard_Real& theFirst,
Standard_Real& theLast);
//------------------------------------------------------------------------------------------------
static Standard_Boolean IsPointOK(const gp_Pnt& theTestPnt,
const Adaptor3d_Surface& theTestSurface,
const Standard_Real& theTol);
//-------------------------------------------------------------------------------------------------
static Standard_Boolean GetPointOn2S(const gp_Pnt& theTestPnt,
const Adaptor3d_Surface& theTestSurface,
const Standard_Real& theTol,
Extrema_POnSurf& theResultPoint);
//-------------------------------------------------------------------------------------------------------------------------
static Handle(IntPatch_WLine) GetMergedWLineOnRestriction(IntPatch_SequenceOfLine& theSlin,
const Standard_Real& theVrtxTol,
const Handle(IntSurf_LineOn2S)& theLineOn2S);
//---------------------------------------------------------------------------------------------------------------------------
// modified by NIZHNY-OFV Fri Mar 29 12:41:02 2002.END
//=======================================================================
//function : TopOpeBRep_FacesIntersector
//purpose :
//=======================================================================
TopOpeBRep_FacesIntersector::TopOpeBRep_FacesIntersector ()
{
ResetIntersection();
myTol1 = myTol2 = Precision::Confusion();
myForceTolerances = Standard_False;
mySurface1 = new BRepAdaptor_HSurface();
mySurface2 = new BRepAdaptor_HSurface();
myDomain1 = new BRepTopAdaptor_TopolTool();
myDomain2 = new BRepTopAdaptor_TopolTool();
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void TopOpeBRep_FacesIntersector::Perform(const TopoDS_Shape& F1,const TopoDS_Shape& F2,
const Bnd_Box& B1,const Bnd_Box& B2)
{
#ifdef DEB
if (TopOpeBRep_GettraceSAVFF()) SAVFF(TopoDS::Face(F1),TopoDS::Face(F2));
#endif
ResetIntersection();
if (!myForceTolerances) ShapeTolerances(F1,F2);
myFace1 = TopoDS::Face(F1); myFace1.Orientation(TopAbs_FORWARD);
myFace2 = TopoDS::Face(F2); myFace2.Orientation(TopAbs_FORWARD);
BRepAdaptor_Surface& S1 = mySurface1->ChangeSurface(); S1.Initialize(myFace1);
BRepAdaptor_Surface& S2 = mySurface2->ChangeSurface(); S2.Initialize(myFace2);
mySurfaceType1 = S1.GetType();
mySurfaceType2 = S2.GetType();
myDomain1->Initialize(mySurface1);
myDomain2->Initialize(mySurface2);
#ifdef DEB
if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFF.Start();
#endif
Standard_Real Deflection=0.01,MaxUV=0.01;
if (!myForceTolerances) {
FTOL_FaceTolerances3d(B1,B2,myFace1,myFace2,S1,S2,
myTol1,myTol2,Deflection,MaxUV);
myTol1 = (myTol1 > 1.e-4)? 1.e-4: myTol1;
myTol2 = (myTol2 > 1.e-4)? 1.e-4: myTol2;
}
Standard_Real tol1 = myTol1;
Standard_Real tol2 = myTol2;
GLOBAL_tolFF = Max(tol1,tol2);
#ifdef DEB
if (TopOpeBRep_GettraceFITOL()) {
cout<<"FacesIntersector : Perform tol1 = "<<tol1<<endl;
cout<<" tol2 = "<<tol2<<endl;
cout<<" defl = "<<Deflection<<" MaxUV = "<<MaxUV<<endl;
}
#endif
myIntersector.SetTolerances(myTol1,myTol2,MaxUV,Deflection);
myIntersector.Perform(mySurface1,myDomain1,mySurface2,myDomain2,myTol1,myTol2);
#ifdef DEB
if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFF.Stop();
#endif
//xpu180998 : cto900Q1
Standard_Boolean done = myIntersector.IsDone();
if (!done) return;
PrepareLines();
myIntersectionDone = Standard_True;
// mySurfacesSameOriented : a mettre dans IntPatch NYI
if ( SameDomain() ) {
mySurfacesSameOriented = TopOpeBRepTool_ShapeTool::SurfacesSameOriented(S1,S2);
}
// build the map of edges found as RESTRICTION
for (InitLine(); MoreLine(); NextLine()) {
TopOpeBRep_LineInter& L = CurrentLine();
if (L.TypeLineCurve() == TopOpeBRep_RESTRICTION) {
const TopoDS_Shape& E = L.Arc();
myEdgeRestrictionMap.Add(E);
}
}
#ifdef DEB
if (TopOpeBRep_GettraceFI()) cout<<"Perform : isempty "<<IsEmpty()<<endl;
#endif
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void TopOpeBRep_FacesIntersector::Perform(const TopoDS_Shape& F1,const TopoDS_Shape& F2)
{
Bnd_Box B1,B2;
Perform(F1,F2,B1,B2);
}
//=======================================================================
//function : IsEmpty
//purpose :
//=======================================================================
Standard_Boolean TopOpeBRep_FacesIntersector::IsEmpty ()
{
if ( ! myIntersectionDone ) return Standard_False;
Standard_Boolean done = myIntersector.IsDone();
Standard_Boolean empty = myIntersector.IsEmpty();
if ( !done || empty ) return Standard_True;
else {
// ElemIntersector is done and is not empty
// returns True if at least one VPoint is found
empty = Standard_True;
for ( InitLine(); MoreLine(); NextLine() ) {
empty = (CurrentLine().NbVPoint() == 0);
if ( ! empty ) break;
}
return empty;
}
}
//=======================================================================
//function : IsDone
//purpose :
//=======================================================================
Standard_Boolean TopOpeBRep_FacesIntersector::IsDone () const
{
return myIntersectionDone;
}
//=======================================================================
//function : SameDomain
//purpose :
//=======================================================================
Standard_Boolean TopOpeBRep_FacesIntersector::SameDomain () const
{
if (!myIntersectionDone)
Standard_ProgramError::Raise("FacesIntersector : bad SameDomain");
Standard_Boolean sd = myIntersector.TangentFaces();
//Standard_Boolean plpl = (mySurfaceType1 == GeomAbs_Plane) && (mySurfaceType2 == GeomAbs_Plane);
// if (!plpl) return Standard_False;
return sd;
}
//=======================================================================
//function : Face
//purpose :
//=======================================================================
const TopoDS_Shape& TopOpeBRep_FacesIntersector::Face
(const Standard_Integer Index) const
{
if ( Index == 1 ) return myFace1;
else if ( Index == 2 ) return myFace2;
else Standard_ProgramError::Raise("TopOpeBRep_FacesIntersector::Face");
return myNullShape;
}
//=======================================================================
//function : SurfacesSameOriented
//purpose :
//=======================================================================
Standard_Boolean TopOpeBRep_FacesIntersector::SurfacesSameOriented () const
{
if ( SameDomain() ) {
return mySurfacesSameOriented;
}
Standard_ProgramError::Raise("FacesIntersector : bad SurfacesSameOriented");
return Standard_False;
}
//=======================================================================
//function : IsRestriction
//purpose :
//=======================================================================
Standard_Boolean TopOpeBRep_FacesIntersector::IsRestriction
(const TopoDS_Shape& E) const
{
Standard_Boolean isrest = myEdgeRestrictionMap.Contains(E);
return isrest;
}
//=======================================================================
//function : Restrictions
//purpose :
//=======================================================================
const TopTools_IndexedMapOfShape& TopOpeBRep_FacesIntersector::Restrictions
() const
{
return myEdgeRestrictionMap;
}
//=======================================================================
//function : PrepareLines
//purpose :
//=======================================================================
void TopOpeBRep_FacesIntersector::PrepareLines()
{
myLineNb = 0;
Standard_Integer n = myIntersector.NbLines();
myHAL = new TopOpeBRep_HArray1OfLineInter(0,n);
BRepAdaptor_Surface& S1 = *((BRepAdaptor_Surface*)&(mySurface1->Surface()));
BRepAdaptor_Surface& S2 = *((BRepAdaptor_Surface*)&(mySurface2->Surface()));
// modified by NIZHNY-MKK Mon Apr 2 12:14:58 2001.BEGIN
if(n==0)
return;
// modified by NIZHNY-MKK Mon Apr 2 12:15:09 2001.END
Standard_Boolean newV = Standard_True;
if (!newV) {
/*for ( Standard_Integer i=1; i<=n; i++) {
TopOpeBRep_LineInter& LI = myHAL->ChangeValue(i);
const Handle(IntPatch_Line)& L = myIntersector.Line(i);
LI.SetLine(L,S1,S2);
LI.Index(i);
myLineNb++;;
}*/}
if (newV) {
//-- lbr
// modified by NIZHNY-MKK Mon Apr 2 12:16:04 2001
IntPatch_SequenceOfLine aSeqOfLines, aSeqOfResultLines;
Standard_Integer i ;
// Standard_Integer nbl=0;
IntPatch_LineConstructor **Ptr =
(IntPatch_LineConstructor **)malloc(n*sizeof(IntPatch_LineConstructor *));
for( i=1;i<=n;i++) {
Ptr[i-1]=new IntPatch_LineConstructor(2);
Ptr[i-1]->Perform(myIntersector.SequenceOfLine(),
myIntersector.Line(i),
mySurface1,myDomain1,
mySurface2,myDomain2,
myTol1);
// modified by NIZHNY-MKK Mon Apr 2 12:16:26 2001.BEGIN
aSeqOfLines.Clear();
for(Standard_Integer k=1; k<=Ptr[i-1]->NbLines(); k++) {
aSeqOfLines.Append(Ptr[i-1]->Line(k));
}
TestWLinesToAnArc(aSeqOfLines, mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
for(Standard_Integer j=1; j<=aSeqOfLines.Length(); j++) {
aSeqOfResultLines.Append(aSeqOfLines.Value(j));
}
delete Ptr[i-1];
// nbl+=Ptr[i-1]->NbLines();
// modified by NIZHNY-MKK Mon Apr 2 12:16:31 2001.END
}
// modified by NIZHNY-MKK Mon Apr 2 12:17:22 2001.BEGIN
// myHAL = new TopOpeBRep_HArray1OfLineInter(0,nbl);
myLineNb = aSeqOfResultLines.Length();
//Fun_ConvertWLinesToRLine(aSeqOfResultLines,mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
MergeWLinesIfAllSegmentsAlongRestriction(aSeqOfResultLines,mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
myLineNb = aSeqOfResultLines.Length();
if(myLineNb > 0) {
myHAL = new TopOpeBRep_HArray1OfLineInter(1, myLineNb);
for(Standard_Integer index = 1; index <= myLineNb; index++) {
TopOpeBRep_LineInter& LI = myHAL->ChangeValue(index);
const Handle(IntPatch_Line)& L = aSeqOfResultLines.Value(index);
LI.SetLine(L,S1,S2);
LI.Index(index);
}
}
// nbl=1;
// for(i=1;i<=n;i++) {
// for(Standard_Integer k=1;k<=Ptr[i-1]->NbLines();k++) {
// TopOpeBRep_LineInter& LI = myHAL->ChangeValue(nbl);
// const Handle(IntPatch_Line)& L = Ptr[i-1]->Line(k);
// LI.SetLine(L,S1,S2);
// LI.Index(nbl);
// myLineNb++;
// nbl++;
// }
// delete Ptr[i-1];
// }
// modified by NIZHNY-MKK Mon Apr 2 12:17:57 2001.END
free(Ptr);
}
}
//=======================================================================
//function : Lines
//purpose :
//=======================================================================
Handle(TopOpeBRep_HArray1OfLineInter) TopOpeBRep_FacesIntersector::Lines()
{
return myHAL;
}
//=======================================================================
//function : NbLines
//purpose :
//=======================================================================
Standard_Integer TopOpeBRep_FacesIntersector::NbLines()const
{
return myLineNb;
}
//=======================================================================
//function : InitLine
//purpose :
//=======================================================================
void TopOpeBRep_FacesIntersector::InitLine()
{
myLineIndex = 1;
FindLine();
}
//=======================================================================
//function : FindLine
//purpose :
//=======================================================================
void TopOpeBRep_FacesIntersector::FindLine()
{
myLineFound = Standard_False;
if ( ! myIntersectionDone ) return;
while (myLineIndex <= myLineNb) {
const TopOpeBRep_LineInter& L = myHAL->Value(myLineIndex);
myLineFound = L.OK();
if (myLineFound) break;
else myLineIndex++;
}
}
//=======================================================================
//function : MoreLine
//purpose :
//=======================================================================
Standard_Boolean TopOpeBRep_FacesIntersector::MoreLine()const
{
return myLineFound;
}
//=======================================================================
//function : NextLine
//purpose :
//=======================================================================
void TopOpeBRep_FacesIntersector::NextLine()
{
myLineIndex++;
FindLine();
}
//=======================================================================
//function : CurrentLine
//purpose :
//=======================================================================
TopOpeBRep_LineInter& TopOpeBRep_FacesIntersector::CurrentLine()
{
TopOpeBRep_LineInter& TLI = myHAL->ChangeValue(myLineIndex);
return TLI;
}
//=======================================================================
//function : CurrentLineIndex
//purpose :
//=======================================================================
Standard_Integer TopOpeBRep_FacesIntersector::CurrentLineIndex()const
{
return myLineIndex;
}
//=======================================================================
//function : Line
//purpose :
//=======================================================================
TopOpeBRep_LineInter& TopOpeBRep_FacesIntersector::ChangeLine(const Standard_Integer IL)
{
TopOpeBRep_LineInter& TLI = myHAL->ChangeValue(IL);
return TLI;
}
//=======================================================================
//function : ResetIntersection
//purpose :
//=======================================================================
void TopOpeBRep_FacesIntersector::ResetIntersection()
{
myIntersectionDone = Standard_False;
myLineIndex = 1;
myLineNb = 0;
myEdgeRestrictionMap.Clear();
myLineFound = Standard_False;
}
//=======================================================================
//function : ForceTolerances
//purpose :
//=======================================================================
void TopOpeBRep_FacesIntersector::ForceTolerances(const Standard_Real Tol1,
const Standard_Real Tol2)
{
myTol1 = Tol1;
myTol2 = Tol2;
myForceTolerances = Standard_True;
#ifdef DEB
if (TopOpeBRep_GettraceFITOL())
cout<<"ForceTolerances : myTol1,myTol2 = "<<myTol1<<","<<myTol2<<endl;
#endif
}
//=======================================================================
//function : GetTolerances
//purpose :
//=======================================================================
void TopOpeBRep_FacesIntersector::GetTolerances(Standard_Real& Tol1,
Standard_Real& Tol2) const
{
Tol1 = myTol1;
Tol2 = myTol2;
}
//=======================================================================
//function : ShapeTolerances
//purpose : (private)
//=======================================================================
#ifdef DEB
void TopOpeBRep_FacesIntersector::ShapeTolerances(const TopoDS_Shape& S1,
const TopoDS_Shape& S2)
#else
void TopOpeBRep_FacesIntersector::ShapeTolerances(const TopoDS_Shape& ,
const TopoDS_Shape& )
#endif
{
// myTol1 = Max(ToleranceMax(S1,TopAbs_EDGE),ToleranceMax(S2,TopAbs_EDGE));
myTol1 = Precision::Confusion();
myTol2 = myTol1;
myForceTolerances = Standard_False;
#ifdef DEB
if (TopOpeBRep_GettraceFITOL()) {
cout<<"ShapeTolerances on S1 = ";TopAbs::Print(S1.ShapeType(),cout);
cout<<" S2 = ";TopAbs::Print(S2.ShapeType(),cout);
cout<<" : myTol1,myTol2 = "<<myTol1<<","<<myTol2<<endl;
}
#endif
}
//=======================================================================
//function : ToleranceMax
//purpose : (private)
//=======================================================================
Standard_Real TopOpeBRep_FacesIntersector::ToleranceMax
(const TopoDS_Shape& S,const TopAbs_ShapeEnum T) const
{
TopExp_Explorer e(S,T);
if ( ! e.More() ) return Precision::Intersection();
else {
Standard_Real tol = RealFirst();
for (; e.More(); e.Next())
tol = Max(tol,TopOpeBRepTool_ShapeTool::Tolerance(e.Current()));
return tol;
}
}
// modified by NIZHNY-MKK Mon Apr 2 12:18:30 2001.BEGIN
// ================================================================================================
// static function: TestWLineAlongRestriction
// purpose:
// ================================================================================================
static Standard_Boolean TestWLineAlongRestriction(const Handle(IntPatch_WLine)& theWLine,
const Standard_Integer theRank,
const Handle(Adaptor3d_HSurface)& theSurface,
const Handle(Adaptor3d_TopolTool)& theDomain,
const Standard_Real theTolArc) {
Standard_Boolean result = Standard_False;
Standard_Integer NbPnts = theWLine->NbPnts();
Standard_Integer along = 0;
for(Standard_Integer i=1; i<=NbPnts; i++) {
const IntSurf_PntOn2S& Pmid = theWLine->Point(i);
Standard_Real u=0., v=0.;
if(theRank==1) Pmid.ParametersOnS1(u, v);
else Pmid.ParametersOnS2(u, v);
//------------------------------------------
gp_Pnt ap;
gp_Vec ad1u, ad1v;
//Standard_Real nad1u, nad1v, tolu, tolv;
theSurface->D1(u, v, ap, ad1u, ad1v);
//nad1u=ad1u.Magnitude();
//nad1v=ad1v.Magnitude();
//if(nad1u>1e-12) tolu=theTolArc/nad1u; else tolu=0.1;
//if(nad1v>1e-12) tolv=theTolArc/nad1v; else tolv=0.1;
//if(tolu>tolv) tolu=tolv;
//------------------------------------------
//if(theDomain->IsThePointOn(gp_Pnt2d(u, v),tolu)) {
// along++;
//}
if(theDomain->IsThePointOn(gp_Pnt2d(u, v),theTolArc)) along++;
//if(along!=i) break;
}
if(along==NbPnts) result = Standard_True;
return result;
}
// ================================================================================================
// static function: BuildRLineBasedOnWLine
// purpose:
// ================================================================================================
static
Handle(IntPatch_RLine) BuildRLineBasedOnWLine(const Handle(IntPatch_WLine)& theWLine,
const Handle(Adaptor2d_HCurve2d)& theArc,
const Standard_Integer theRank) {
Handle(IntPatch_RLine) anRLine;
if((theRank != 1) && (theRank != 2))
return anRLine;
gp_Pnt2d aPOnLine;
Standard_Real u=0., v=0.;
Standard_Integer nbvtx = theWLine->NbVertex();
const IntPatch_Point& Vtx1 = theWLine->Vertex(1);
const IntPatch_Point& Vtx2 = theWLine->Vertex(nbvtx);
if(theRank == 1) {
Vtx1.ParametersOnS1(u, v);
}
else {
Vtx1.ParametersOnS2(u, v);
}
aPOnLine = gp_Pnt2d(u, v);
Standard_Real par1 = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), aPOnLine, 1.e-7);
if(theRank == 1) {
Vtx2.ParametersOnS1(u, v);
}
else {
Vtx2.ParametersOnS2(u, v);
}
aPOnLine = gp_Pnt2d(u, v);
Standard_Real par2 = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), aPOnLine, 1.e-7);
Standard_Real tol = (Vtx1.Tolerance() > Vtx2.Tolerance()) ? Vtx1.Tolerance() : Vtx2.Tolerance();
if(Abs(par1 - par2) < theArc->Resolution(tol))
return anRLine;
Standard_Boolean IsOnFirst = (theRank == 1);
Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
const Handle(IntSurf_LineOn2S)& Lori = theWLine->Curve();
IntSurf_Transition TransitionUndecided;
anRLine = new IntPatch_RLine(Standard_False, theWLine->TransitionOnS1(), theWLine->TransitionOnS2());
if(IsOnFirst) {
anRLine->SetArcOnS1(theArc);
}
else {
anRLine->SetArcOnS2(theArc);
}
Standard_Integer k = 0;
if(par1 < par2) {
for(k = 1; k <= Lori->NbPoints(); k++) {
aLineOn2S->Add(Lori->Value(k));
}
anRLine->Add(aLineOn2S);
IntPatch_Point VtxFirst = Vtx1;
VtxFirst.SetArc(IsOnFirst, //-- On First
theArc,
par1,
TransitionUndecided,
TransitionUndecided);
VtxFirst.SetParameter(par1);
anRLine->AddVertex(VtxFirst);
for(k = 2; k < nbvtx; k++) {
IntPatch_Point Vtx = theWLine->Vertex(k);
if(theRank == 1) {
Vtx.ParametersOnS1(u, v);
}
else {
Vtx.ParametersOnS2(u, v);
}
gp_Pnt2d atmpPoint(u, v);
Standard_Real apar = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), atmpPoint, 1.e-7);
Vtx.SetParameter(apar);
anRLine->AddVertex(Vtx);
}
IntPatch_Point VtxLast = Vtx2;
VtxLast.SetArc(IsOnFirst, //-- On First
theArc,
par2,
TransitionUndecided,
TransitionUndecided);
VtxLast.SetParameter(par2);
anRLine->AddVertex(VtxLast);
anRLine->SetFirstPoint(1);
anRLine->SetLastPoint(nbvtx);
anRLine->ComputeVertexParameters(Precision::Confusion());
}
else {
for(k = Lori->NbPoints(); k >= 1; k--) {
aLineOn2S->Add(Lori->Value(k));
}
anRLine->Add(aLineOn2S);
IntPatch_Point VtxFirst = Vtx2;
VtxFirst.SetArc(IsOnFirst, //-- On First
theArc,
par2,
TransitionUndecided,
TransitionUndecided);
VtxFirst.SetParameter(par2);
anRLine->AddVertex(VtxFirst);
for(k = nbvtx - 1; k >= 2; k--) {
IntPatch_Point Vtx = theWLine->Vertex(k);
Vtx.ReverseTransition();
if(theRank == 1) {
Vtx.ParametersOnS1(u, v);
}
else {
Vtx.ParametersOnS2(u, v);
}
gp_Pnt2d atmpPoint(u, v);
Standard_Real apar = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), atmpPoint, 1.e-7);
Vtx.SetParameter(apar);
anRLine->AddVertex(Vtx);
}
IntPatch_Point VtxLast = Vtx1;
VtxLast.SetArc(IsOnFirst, //-- On First
theArc,
par1,
TransitionUndecided,
TransitionUndecided);
VtxLast.SetParameter(par1);
anRLine->AddVertex(VtxLast);
anRLine->SetFirstPoint(1);
anRLine->SetLastPoint(nbvtx);
anRLine->ComputeVertexParameters(Precision::Confusion());
}
return anRLine;
}
// ================================================================================================
// static function: BuildRLine
// purpose: build rline based on group of wlines
// return null handle if it is not possible to build rline
// ================================================================================================
static
Handle(IntPatch_RLine) BuildRLine(const IntPatch_SequenceOfLine& theSeqOfWLine,
const Standard_Integer theRank,
const Handle(Adaptor3d_HSurface)& theSurface,
const Handle(Adaptor3d_TopolTool)& theDomain,
const Standard_Real theTolArc) {
Handle(IntPatch_RLine) anRLine;
const Handle(IntPatch_WLine)& aWLine1 = *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(1)));
const Handle(IntPatch_WLine)& aWLine2 = *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(theSeqOfWLine.Length())));
const IntPatch_Point& P1 = aWLine1->Vertex(1);
const IntPatch_Point& P2 = aWLine2->Vertex(aWLine2->NbVertex());
const Handle(Adaptor3d_HVertex)& aV1 = (theRank==1) ? P1.VertexOnS1() : P1.VertexOnS2();
const Handle(Adaptor3d_HVertex)& aV2 = (theRank==1) ? P2.VertexOnS1() : P2.VertexOnS2();
// avoid closed and degenerated edges
if(aV1->IsSame(aV2))
return anRLine;
for(theDomain->Init(); theDomain->More(); theDomain->Next()) {
theDomain->Initialize(theDomain->Value());
Standard_Boolean foundVertex1 = Standard_False;
Standard_Boolean foundVertex2 = Standard_False;
for(theDomain->InitVertexIterator(); (!foundVertex1 || !foundVertex2) && theDomain->MoreVertex(); theDomain->NextVertex()) {
if(!foundVertex1 && aV1->IsSame(theDomain->Vertex()))
foundVertex1 = Standard_True;
if(!foundVertex2 && aV2->IsSame(theDomain->Vertex()))
foundVertex2 = Standard_True;
}
if(foundVertex1 && foundVertex2) {
Standard_Boolean buildrline = (theSeqOfWLine.Length() > 0);
for(Standard_Integer i = 1; buildrline && i<=theSeqOfWLine.Length(); i++) {
const Handle(IntPatch_WLine)& aWLine =
*((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(i)));
Standard_Integer indexpnt = aWLine->NbPnts()/2;
if(indexpnt < 1)
buildrline = Standard_False;
else {
Standard_Real u = RealLast(), v = RealLast();
const IntSurf_PntOn2S& POn2S = aWLine->Point(indexpnt);
if(theRank==1) {
POn2S.ParametersOnS1(u, v);
}
else {
POn2S.ParametersOnS2(u, v);
}
gp_Pnt2d aPOnArc, aPOnLine(u, v);
Standard_Real par = Geom2dInt_TheProjPCurOfGInter::FindParameter(theDomain->Value()->Curve2d(), aPOnLine, 1e-7);
aPOnArc = theDomain->Value()->Value(par);
gp_Pnt ap;
gp_Vec ad1u, ad1v;
Standard_Real nad1u, nad1v, tolu, tolv;
theSurface->D1(u, v, ap, ad1u, ad1v);
nad1u=ad1u.Magnitude();
nad1v=ad1v.Magnitude();
if(nad1u>1e-12) tolu=theTolArc/nad1u; else tolu=0.1;
if(nad1v>1e-12) tolv=theTolArc/nad1v; else tolv=0.1;
Standard_Real aTolerance = (tolu > tolv) ? tolv : tolu;
if(aPOnArc.Distance(aPOnLine) > aTolerance) {
buildrline = Standard_False;
}
}
} //end for
if(buildrline) {
IntSurf_TypeTrans trans1 = IntSurf_Undecided, trans2 = IntSurf_Undecided;
Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
for(Standard_Integer j = 1; j<=theSeqOfWLine.Length(); j++) {
const Handle(IntPatch_WLine)& atmpWLine =
*((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(j)));
const Handle(IntSurf_LineOn2S)& Lori = atmpWLine->Curve();
if(atmpWLine->TransitionOnS1()!=IntSurf_Undecided && atmpWLine->TransitionOnS1()!=IntSurf_Touch) {
trans1 = atmpWLine->TransitionOnS1();
}
if(atmpWLine->TransitionOnS2()!=IntSurf_Undecided && atmpWLine->TransitionOnS2()!=IntSurf_Touch) {
trans2 = atmpWLine->TransitionOnS2();
}
Standard_Integer ParamMinOnLine = (Standard_Integer) atmpWLine->Vertex(1).ParameterOnLine();
Standard_Integer ParamMaxOnLine = (Standard_Integer) atmpWLine->Vertex(atmpWLine->NbVertex()).ParameterOnLine();
for(Standard_Integer k = ParamMinOnLine; k <= ParamMaxOnLine; k++) {
aLineOn2S->Add(Lori->Value(k));
}
}
Handle(IntPatch_WLine) emulatedWLine =
new IntPatch_WLine(aLineOn2S, Standard_False, trans1, trans2);
IntPatch_Point aFirstVertex = P1;
IntPatch_Point aLastVertex = P2;
aFirstVertex.SetParameter(1);
aLastVertex.SetParameter(aLineOn2S->NbPoints());
emulatedWLine->AddVertex(aFirstVertex);
Standard_Integer apointindex = 0;
for(apointindex = 2; apointindex <= aWLine1->NbVertex(); apointindex++) {
IntPatch_Point aPoint = aWLine1->Vertex(apointindex);
Standard_Real aTolerance = (aPoint.Tolerance() > P1.Tolerance()) ? aPoint.Tolerance() : P1.Tolerance();
if(aPoint.Value().IsEqual(P1.Value(), aTolerance)) {
aPoint.SetParameter(1);
emulatedWLine->AddVertex(aPoint);
}
}
for(apointindex = 1; apointindex < aWLine2->NbVertex(); apointindex++) {
IntPatch_Point aPoint = aWLine2->Vertex(apointindex);
Standard_Real aTolerance = (aPoint.Tolerance() > P2.Tolerance()) ? aPoint.Tolerance() : P2.Tolerance();
if(aPoint.Value().IsEqual(P2.Value(), aTolerance)) {
aPoint.SetParameter(aLineOn2S->NbPoints());
emulatedWLine->AddVertex(aPoint);
}
}
emulatedWLine->AddVertex(aLastVertex);
anRLine = BuildRLineBasedOnWLine(emulatedWLine, theDomain->Value(), theRank);
break;
}
}
} //end for
return anRLine;
}
// ================================================================================================
// static function: TestWLinesToAnArc
// purpose: test if possible to replace group of wlines by rline and replace in the sequence slin
// ================================================================================================
static void TestWLinesToAnArc(IntPatch_SequenceOfLine& slin,
const Handle(Adaptor3d_HSurface)& theSurface1,
const Handle(Adaptor3d_TopolTool)& theDomain1,
const Handle(Adaptor3d_HSurface)& theSurface2,
const Handle(Adaptor3d_TopolTool)& theDomain2,
const Standard_Real theTolArc) {
IntPatch_SequenceOfLine aSeqOfWLine;
IntPatch_SequenceOfLine aSeqOfRLine;
for(Standard_Integer rank = 1; rank <= 2; rank++) {
for(Standard_Integer i=1; i<=slin.Length(); i++) {
if(slin.Value(i)->ArcType()!=IntPatch_Walking)
continue;
const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (slin.Value(i)));
Standard_Integer nbvtx = aWLine->NbVertex();
const IntPatch_Point& Vtx1 = aWLine->Vertex(1);
const IntPatch_Point& Vtx2 = aWLine->Vertex(nbvtx);
Standard_Boolean isvertex = Standard_False, wlineWasAppended = Standard_False;
if(rank==1)
isvertex = Vtx1.IsVertexOnS1();
else
isvertex = Vtx1.IsVertexOnS2();
if(isvertex) {
Standard_Boolean appendwline = Standard_True;
if(rank==1) {
if(!aWLine->HasArcOnS1() && !TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc)) {
appendwline = Standard_False;
}
}
if(rank==2) {
if(!aWLine->HasArcOnS2() && !TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc)) {
appendwline = Standard_False;
}
}
wlineWasAppended = appendwline;
if(appendwline)
aSeqOfWLine.Append(aWLine);
}
else {
if(aSeqOfWLine.Length()==0)
continue;
const Handle(IntPatch_WLine)& aLastWLine =
*((Handle(IntPatch_WLine) *)& (aSeqOfWLine.Value(aSeqOfWLine.Length())));
const IntPatch_Point& aLastPoint = aLastWLine->Vertex(aLastWLine->NbVertex());
Standard_Real aTolerance = (aLastPoint.Tolerance() > Vtx1.Tolerance()) ? aLastPoint.Tolerance() : Vtx1.Tolerance();
if(aLastPoint.Value().IsEqual(Vtx1.Value(), aTolerance)) {
Standard_Boolean appendwline = Standard_True;
if(rank==1) {
if(!aWLine->HasArcOnS1() && !TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc)) {
appendwline = Standard_False;
}
}
if(rank==2) {
if(!aWLine->HasArcOnS2() && !TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc)) {
appendwline = Standard_False;
}
}
wlineWasAppended = appendwline;
if(appendwline)
aSeqOfWLine.Append(aWLine);
}
else {
aSeqOfWLine.Clear();
}
}
isvertex = Standard_False;
if(rank==1)
isvertex = Vtx2.IsVertexOnS1();
else
isvertex = Vtx2.IsVertexOnS2();
if(wlineWasAppended && isvertex) {
// build rline based on sequence of wlines.
Handle(IntPatch_RLine) anRLine;
if(rank==1) {
anRLine = BuildRLine(aSeqOfWLine, rank, theSurface1, theDomain1, theTolArc);
}
else {
anRLine = BuildRLine(aSeqOfWLine, rank, theSurface2, theDomain2, theTolArc);
}
if(!anRLine.IsNull()) {
aSeqOfRLine.Append(anRLine);
for(Standard_Integer k=1; k<=aSeqOfWLine.Length(); k++) {
for(Standard_Integer j=1; j<=slin.Length(); j++) {
if(aSeqOfWLine(k)==slin(j)) {
slin.Remove(j);
break;
}
}
}
}
aSeqOfWLine.Clear();
}
}
}
for(Standard_Integer i=1; i<=aSeqOfRLine.Length(); i++) {
slin.Append(aSeqOfRLine.Value(i));
}
}
// modified by NIZHNY-MKK Mon Apr 2 12:18:34 2001.END
//====================================================================================
// function: MergeWLinesIfAllSegmentsAlongRestriction
//
// purpose: If the result of LineConstructor is a set of WLines segments which are
// placed along RESTRICTION, we can suppose that this result is not correct:
// here we should have a RLine. If it is not possible to construct RLine
// we should merge segments of WLines into single WLine equals to the same
// RLine.
//====================================================================================
static void MergeWLinesIfAllSegmentsAlongRestriction(IntPatch_SequenceOfLine& theSlin,
const Handle(Adaptor3d_HSurface)& theSurface1,
const Handle(Adaptor3d_TopolTool)& theDomain1,
const Handle(Adaptor3d_HSurface)& theSurface2,
const Handle(Adaptor3d_TopolTool)& theDomain2,
const Standard_Real theTolArc)
{
Standard_Integer i = 0, rank = 0;
Standard_Real tol = 1.e-9;
// here we check that all segments of WLines placed along restriction
Standard_Integer WLOnRS1 = 0;
Standard_Integer WLOnRS2 = 0;
Standard_Integer NbWLines = 0;
TColgp_SequenceOfPnt sqVertexPoints;
for(rank = 1; rank <= 2; rank++)
{
NbWLines = 0;
for(i = 1; i <= theSlin.Length(); i++)
{
if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
continue;
NbWLines++;
const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
Standard_Integer nbvtx = aWLine->NbVertex();
const IntPatch_Point& Vtx1 = aWLine->Vertex(1);
const IntPatch_Point& Vtx2 = aWLine->Vertex(nbvtx);
if( rank==1 )
{
sqVertexPoints.Append(Vtx1.Value());
sqVertexPoints.Append(Vtx2.Value());
if( TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc) )
WLOnRS1++;
}
else
{
if( TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc) )
WLOnRS2++;
}
}
if( NbWLines == WLOnRS1 || NbWLines == WLOnRS2 ) break;
}
Standard_Integer WLineRank = 0; // not possible to merge WLines
if( WLOnRS1 == NbWLines )
WLineRank = 1; // create merged WLine based on arc of S1
else if( WLOnRS2 == NbWLines )
WLineRank = 2; // create merged WLine based on arc of S2
else
return;
// avoid closed (degenerated) edges
if( sqVertexPoints.Length() <= 2 )
return;
if( sqVertexPoints.Value(1).IsEqual(sqVertexPoints.Value(sqVertexPoints.Length()),tol) )
return;
Standard_Real TolVrtx = 1.e-5;
Standard_Integer testPointIndex = ( sqVertexPoints.Length() > 3 ) ? ((Standard_Integer) sqVertexPoints.Length() / 2) : 2;
gp_Pnt testPoint = sqVertexPoints.Value( testPointIndex );
Standard_Real Fp = 0., Lp = 0.;
if( WLineRank == 1 )
{
Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
Standard_Integer arcnumber = GetArc(theSlin,WLineRank,theSurface1,theDomain1,theSurface2,testPoint,TolVrtx,aLineOn2S,Fp,Lp);
if( arcnumber == 0 )
return;
Handle(IntPatch_WLine) anWLine = NULL;
anWLine = GetMergedWLineOnRestriction(theSlin,TolVrtx,aLineOn2S);
#ifdef DEB
cout << "*** TopOpeBRep_FaceIntersector: Merge WLines on Restriction S1 to WLine ***" << endl;
#endif
theSlin.Clear();
theSlin.Append(anWLine);
}
else
{
Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
Standard_Integer arcnumber = GetArc(theSlin,WLineRank,theSurface2,theDomain2,theSurface1,testPoint,TolVrtx,aLineOn2S,Fp,Lp);
if( arcnumber == 0 )
return;
Handle(IntPatch_WLine) anWLine = NULL;
anWLine = GetMergedWLineOnRestriction(theSlin,TolVrtx,aLineOn2S);
#ifdef DEB
cout << "*** TopOpeBRep_FaceIntersector: Merge WLines on Restriction S2 to WLine***" << endl;
#endif
theSlin.Clear();
theSlin.Append(anWLine);
}
}
//=========================================================================================
// function: GetArc
//
// purpose: Define arc on (OBJ) surface which all WLine segments are placed along.
// Check states of points in the gaps between segments on (TOOL). If those states
// are IN or ON return the LineOn2S based on points3D were given from detected arc.
// Returns 0 if it is not possible to create merged WLine.
//========================================================================================
static Standard_Integer GetArc(IntPatch_SequenceOfLine& theSlin,
const Standard_Integer& theRankS,
const Handle(Adaptor3d_HSurface)& theSurfaceObj,
const Handle(Adaptor3d_TopolTool)& theDomainObj,
const Handle(Adaptor3d_HSurface)& theSurfaceTool,
const gp_Pnt& theTestPoint,
Standard_Real& theVrtxTol,
Handle(IntSurf_LineOn2S)& theLineOn2S,
Standard_Real& theFirst,
Standard_Real& theLast)
{
// 1. find number of arc (edge) on which the WLine segments are placed.
Standard_Real MinDistance2 = 1.e+200, firstES1 = 0., lastES1 = 0.;
Standard_Integer ArcNumber = 0, CurArc = 0, i = 0, j = 0;
theFirst = 0.;
theLast = 0.;
for(theDomainObj->Init(); theDomainObj->More(); theDomainObj->Next())
{
CurArc++;
Standard_Address anEAddress = theDomainObj->Edge();
if( anEAddress == NULL )
continue;
TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, firstES1, lastES1);
if ( aCEdge.IsNull() ) // e.g. degenerated edge, see OCC21770
continue;
GeomAdaptor_Curve CE;
CE.Load(aCEdge);
Extrema_ExtPC epc(theTestPoint, CE, 1.e-7);
if( epc.IsDone() )
{
for( i = 1; i <= epc.NbExt(); i++ )
{
if( epc.SquareDistance( i ) < MinDistance2 )
{
MinDistance2 = epc.SquareDistance( i );
ArcNumber = CurArc;
}
}
}
}
if( ArcNumber == 0 )
return 0;
// 2. load parameters of founded edge and its arc.
CurArc = 0;
TColgp_SequenceOfPnt PointsFromArc;
Handle(Adaptor2d_HCurve2d) arc = NULL;
Standard_Real tol = 1.e-7;
TColStd_SequenceOfReal WLVertexParameters;
Standard_Boolean classifyOK = Standard_True;
Standard_Real CheckTol = 1.e-5;
for(theDomainObj->Init(); theDomainObj->More(); theDomainObj->Next())
{
CurArc++;
if( CurArc != ArcNumber )
continue;
arc = theDomainObj->Value();
for(i = 1; i <= theSlin.Length(); i++)
{
if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
continue;
const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
Standard_Integer nbpnts = aWLine->NbPnts();
const IntSurf_PntOn2S& POn2S_F = aWLine->Point(1);
const IntSurf_PntOn2S& POn2S_L = aWLine->Point(nbpnts);
Standard_Real Upf = 0., Vpf = 0., Upl = 0., Vpl = 0.;
if(theRankS == 1)
{
POn2S_F.ParametersOnS1(Upf, Vpf);
POn2S_L.ParametersOnS1(Upl, Vpl);
}
else
{
POn2S_F.ParametersOnS2(Upf, Vpf);
POn2S_L.ParametersOnS2(Upl, Vpl);
}
gp_Pnt2d aPOnLine_F(Upf, Vpf);
gp_Pnt2d aPOnLine_L(Upl, Vpl);
Standard_Real par_F = Geom2dInt_TheProjPCurOfGInter::FindParameter(arc->Curve2d(), aPOnLine_F, tol);
Standard_Real par_L = Geom2dInt_TheProjPCurOfGInter::FindParameter(arc->Curve2d(), aPOnLine_L, tol);
WLVertexParameters.Append(par_F);
WLVertexParameters.Append(par_L);
}
for(i = 1; i <= WLVertexParameters.Length(); i++)
{
for(j = i; j <= WLVertexParameters.Length(); j++)
{
if(j == i)
continue;
if(WLVertexParameters.Value(i) > WLVertexParameters.Value(j))
{
Standard_Real pol = WLVertexParameters.Value(i);
WLVertexParameters.SetValue(i, WLVertexParameters.Value(j));
WLVertexParameters.SetValue(j, pol);
}
}
}
Standard_Address anEAddress = theDomainObj->Edge();
TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
TopoDS_Vertex V1, V2;
TopExp::Vertices(*anE,V1,V2);
Standard_Real MaxVertexTol = Max(BRep_Tool::Tolerance(V1),BRep_Tool::Tolerance(V2));
theVrtxTol = MaxVertexTol;
Standard_Real EdgeTol = BRep_Tool::Tolerance(*anE);
CheckTol = Max(MaxVertexTol, EdgeTol);
Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, firstES1, lastES1);
// classification gaps
// a. min - first
if(Abs(firstES1 - WLVertexParameters.Value(1)) > arc->Resolution(MaxVertexTol))
{
Standard_Real param = (firstES1 + WLVertexParameters.Value(1)) / 2.;
gp_Pnt point;
aCEdge->D0(param, point);
if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
{
classifyOK = Standard_False;
break;
}
}
// b. max - last
if(Abs(lastES1 - WLVertexParameters.Value(WLVertexParameters.Length())) > arc->Resolution(MaxVertexTol))
{
Standard_Real param = (lastES1 + WLVertexParameters.Value(WLVertexParameters.Length())) / 2.;
gp_Pnt point;
aCEdge->D0(param, point);
if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
{
classifyOK = Standard_False;
break;
}
}
// c. all middle gaps
Standard_Integer NbChkPnts = WLVertexParameters.Length() / 2 - 1;
for(i = 1; i <= NbChkPnts; i++)
{
if( Abs(WLVertexParameters.Value(i*2+1) - WLVertexParameters.Value(i*2)) > arc->Resolution(MaxVertexTol))
{
Standard_Real param = (WLVertexParameters.Value(i*2) + WLVertexParameters.Value(i*2+1)) / 2.;
gp_Pnt point;
aCEdge->D0(param, point);
if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
{
classifyOK = Standard_False;
break;
}
}
}
if( !classifyOK )
break;
// if classification gaps OK, fill sequence by the points from arc (edge)
Standard_Real ParamFirst = WLVertexParameters.Value(1);
Standard_Real ParamLast = WLVertexParameters.Value(WLVertexParameters.Length());
Standard_Real dParam = Abs(ParamLast - ParamFirst) / 100.;
Standard_Real cParam = ParamFirst;
for( i = 0; i < 100; i++ )
{
if( i == 99 )
cParam = ParamLast;
gp_Pnt cPnt;
aCEdge->D0(cParam, cPnt);
PointsFromArc.Append(cPnt);
cParam += dParam;
}
theFirst = ParamFirst;
theLast = ParamLast;
}
if( !classifyOK )
return 0;
// create IntSurf_LineOn2S from points < PointsFromArc >
for( i = 1; i <= PointsFromArc.Length(); i++ )
{
Extrema_POnSurf pOnS1;
Extrema_POnSurf pOnS2;
gp_Pnt arcpoint = PointsFromArc.Value( i );
Standard_Boolean isOnS1 = GetPointOn2S( arcpoint, theSurfaceObj->Surface(), CheckTol, pOnS1 );
Standard_Boolean isOnS2 = GetPointOn2S( arcpoint, theSurfaceTool->Surface(), CheckTol, pOnS2 );
if( isOnS1 && isOnS2 )
{
Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
pOnS1.Parameter(u1, v1);
pOnS2.Parameter(u2, v2);
IntSurf_PntOn2S pOn2S;
pOn2S.SetValue(arcpoint, u1, v1, u2, v2 );
theLineOn2S->Add( pOn2S );
}
}
return ArcNumber;
}
//=========================================================================================
// function: IsPointOK
//
// purpose: returns the state of testPoint on OTHER face.
//========================================================================================
static Standard_Boolean IsPointOK(const gp_Pnt& theTestPnt,
const Adaptor3d_Surface& theTestSurface,
const Standard_Real& theTol)
{
Standard_Boolean result = Standard_False;
Standard_Real ExtTol = theTol;//1.e-7;
Extrema_ExtPS extPS(theTestPnt,theTestSurface,ExtTol,ExtTol);
if( extPS.IsDone() && extPS.NbExt() > 0 )
{
Standard_Integer i = 0, minext = 1;
Standard_Real MinDist2 = 1.e+200;
for(i = 1; i <= extPS.NbExt(); i++)
{
if( extPS.SquareDistance(i) < MinDist2 )
{
minext = i;
MinDist2 = extPS.SquareDistance(i);
}
}
if( MinDist2 <= theTol * theTol )
result = Standard_True;
}
return result;
}
//=========================================================================================
// function: GetPointOn2S
//
// purpose: check state of testPoint and returns result point if state is OK.
//========================================================================================
static Standard_Boolean GetPointOn2S(const gp_Pnt& theTestPnt,
const Adaptor3d_Surface& theTestSurface,
const Standard_Real& theTol,
Extrema_POnSurf& theResultPoint)
{
Standard_Boolean result = Standard_False;
Standard_Real ExtTol = theTol;//1.e-7;
Extrema_ExtPS extPS(theTestPnt,theTestSurface,ExtTol,ExtTol);
if( extPS.IsDone() && extPS.NbExt() > 0 )
{
Standard_Integer i = 0, minext = 1;
Standard_Real MinDist2 = 1.e+200;
for(i = 1; i <= extPS.NbExt(); i++)
{
if( extPS.SquareDistance(i) < MinDist2 )
{
minext = i;
MinDist2 = extPS.SquareDistance(i);
}
}
if( MinDist2 <= theTol * theTol )
{
result = Standard_True;
theResultPoint = extPS.Point(minext);
}
}
return result;
}
//=========================================================================================
// function: GetMergedWLineOnRestriction
//
// purpose: merge sequence of WLines all placed along restriction if the conditions of
// merging are OK.
//========================================================================================
static Handle(IntPatch_WLine) GetMergedWLineOnRestriction(IntPatch_SequenceOfLine& theSlin,
const Standard_Real& theVrtxTol,
const Handle(IntSurf_LineOn2S)& theLineOn2S)
{
IntSurf_TypeTrans trans1 = IntSurf_Undecided;
IntSurf_TypeTrans trans2 = IntSurf_Undecided;
Standard_Integer i = 0;
for(i = 1; i <= theSlin.Length(); i++)
{
if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
continue;
const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
if( aWLine->TransitionOnS1() != IntSurf_Undecided && aWLine->TransitionOnS1() != IntSurf_Touch )
trans1 = aWLine->TransitionOnS1();
if( aWLine->TransitionOnS2() != IntSurf_Undecided && aWLine->TransitionOnS2() != IntSurf_Touch )
trans2 = aWLine->TransitionOnS2();
}
Handle(IntPatch_WLine) mWLine = new IntPatch_WLine(theLineOn2S, Standard_False, trans1, trans2);
Standard_Integer NbPnts = mWLine->NbPnts();
IntPatch_Point aFirstVertex, aLastVertex;
aFirstVertex.SetValue(mWLine->Point(1).Value(),theVrtxTol,Standard_False);
aLastVertex.SetValue(mWLine->Point(NbPnts).Value(),theVrtxTol,Standard_False);
Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
mWLine->Point(1).Parameters(u1, v1, u2, v2);
aFirstVertex.SetParameters(u1, v1, u2, v2);
mWLine->Point(NbPnts).Parameters(u1, v1, u2, v2);
aLastVertex.SetParameters(u1, v1, u2, v2);
aFirstVertex.SetParameter(1);
aLastVertex.SetParameter(theLineOn2S->NbPoints());
mWLine->AddVertex(aFirstVertex);
mWLine->AddVertex(aLastVertex);
mWLine->ComputeVertexParameters(theVrtxTol);
return mWLine;
}