mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-26 10:19:45 +03:00
Standard_IMPORT removed or replaced by 'export' where it applies to a symbol defined in the same toolkit
1550 lines
51 KiB
C++
Executable File
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;
|
|
}
|