EgtGeomKernel :

- aggiunta gestione parti coincidenti in intersezione superfici TriMesh
- migliorie a distanza punti da curve.
This commit is contained in:
Dario Sassi
2018-09-03 05:28:48 +00:00
parent 7a051e4e29
commit 5afe1ddf16
13 changed files with 134 additions and 112 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ bool
ChainCurves::Init( bool bAllowInvert, double dToler, int nCrvNbrHint)
{
m_bAllowInvert = bAllowInvert ;
m_dToler = dToler ;
m_dToler = max( dToler, EPS_SMALL) ;
m_sCrvId.clear() ;
m_sCrvId.rehash( nCrvNbrHint) ;
m_vCrvData.clear() ;
+1 -2
View File
@@ -83,8 +83,7 @@ GetCircleCenTgLine( const Point3d& ptCen, const Vector3d& vtN, const CurveLine&
if ( ! DistPointLine( ptCen, ptP1, ptP2, false).GetMinDistPoint( ptTg))
return nullptr ;
// verifico che stia sul segmento
double dSqDist ;
if ( ! DistPointLine( ptTg, ptP1, ptP2).GetSqDist( dSqDist) || dSqDist > SQ_EPS_SMALL)
if ( ! DistPointLine( ptTg, ptP1, ptP2).IsSmall())
return nullptr ;
// creo l'arco
+2 -6
View File
@@ -1044,19 +1044,15 @@ bool
CurveArc::IsPointOn( const Point3d& ptP, double dTol) const
{
// verifico la distanza
double dSqDist ;
dTol = max( dTol, EPS_ZERO) ;
return ( DistPointArc( ptP, *this).GetSqDist( dSqDist) && dSqDist < dTol * dTol) ;
return ( DistPointArc( ptP, *this).IsEpsilon( dTol)) ;
}
//----------------------------------------------------------------------------
bool
CurveArc::GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol) const
{
double dSqDist ;
dTol = max( dTol, EPS_ZERO) ;
DistPointArc DPA( ptP, *this) ;
if ( ! DPA.GetSqDist( dSqDist) || dSqDist > dTol * dTol)
if ( ! DPA.IsEpsilon( dTol))
return false ;
int nFlag ;
return DPA.GetParamAtMinDistPoint( 0, dPar, nFlag) ;
+3 -6
View File
@@ -1281,19 +1281,16 @@ CurveBezier::GetParamAtLength( double dLen, double& dU) const
bool
CurveBezier::IsPointOn( const Point3d& ptP, double dTol) const
{
double dSqDist ;
dTol = max( dTol, EPS_ZERO) ;
return ( DistPointCrvBezier( ptP, *this).GetSqDist( dSqDist) && dSqDist < dTol * dTol) ;
// verifico la distanza
return ( DistPointCrvBezier( ptP, *this).IsEpsilon( dTol)) ;
}
//----------------------------------------------------------------------------
bool
CurveBezier::GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol) const
{
double dSqDist ;
dTol = max( dTol, EPS_ZERO) ;
DistPointCrvBezier DPB( ptP, *this) ;
if ( ! DPB.GetSqDist( dSqDist) || dSqDist > dTol * dTol)
if ( ! DPB.IsEpsilon( dTol))
return false ;
int nFlag ;
return DPB.GetParamAtMinDistPoint( 0, dPar, nFlag) ;
+2 -6
View File
@@ -1214,19 +1214,15 @@ CurveComposite::IsPointOn( const Point3d& ptP, double dTol) const
if ( m_nStatus != OK)
return false ;
// verifico che il punto sia sulla curva ( distanza minore di tolleranza)
double dSqDist ;
dTol = max( dTol, EPS_ZERO) ;
return ( DistPointCrvComposite( ptP, *this).GetSqDist( dSqDist) && dSqDist < dTol * dTol) ;
return ( DistPointCrvComposite( ptP, *this).IsEpsilon( dTol)) ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol) const
{
double dSqDist ;
dTol = max( dTol, EPS_ZERO) ;
DistPointCrvComposite DPC( ptP, *this) ;
if ( ! DPC.GetSqDist( dSqDist) || dSqDist > dTol * dTol)
if ( ! DPC.IsEpsilon( dTol))
return false ;
int nFlag ;
return DPC.GetParamAtMinDistPoint( 0, dPar, nFlag) ;
+6
View File
@@ -29,6 +29,12 @@ class DistPointArc
public :
bool GetSqDist( double& dSqDist) ;
bool GetDist( double& dDist) ;
bool IsEpsilon( double dTol)
{ double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; }
bool IsSmall( void)
{ return IsEpsilon( EPS_SMALL) ; }
bool IsZero( void)
{ return IsEpsilon( EPS_ZERO) ; }
int GetNbrMinDist( void) { return (int) m_Info.size() ; }
bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) ;
bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) ;
+6
View File
@@ -29,6 +29,12 @@ class DistPointCrvBezier
public :
bool GetSqDist( double& dSqDist) ;
bool GetDist( double& dDist) ;
bool IsEpsilon( double dTol)
{ double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; }
bool IsSmall( void)
{ return IsEpsilon( EPS_SMALL) ; }
bool IsZero( void)
{ return IsEpsilon( EPS_ZERO) ; }
int GetNbrMinDist( void) { return (int) m_Info.size() ; }
bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) ;
bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) ;
+6
View File
@@ -28,6 +28,12 @@ class DistPointCrvComposite
public :
bool GetSqDist( double& dSqDist) ;
bool GetDist( double& dDist) ;
bool IsEpsilon( double dTol)
{ double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; }
bool IsSmall( void)
{ return IsEpsilon( EPS_SMALL) ; }
bool IsZero( void)
{ return IsEpsilon( EPS_ZERO) ; }
int GetNbrMinDist( void) { return (int) m_Info.size() ; }
bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) ;
bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) ;
+4 -2
View File
@@ -33,10 +33,12 @@ class DistPointLine
public :
bool GetSqDist( double& dSqDist) ;
bool GetDist( double& dDist) ;
bool IsEpsilon( double dTol)
{ double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; }
bool IsSmall( void)
{ double dSqDist ; return ( GetSqDist( dSqDist) && dSqDist < SQ_EPS_SMALL) ; }
{ return IsEpsilon( EPS_SMALL) ; }
bool IsZero( void)
{ double dSqDist ; return ( GetSqDist( dSqDist) && dSqDist < SQ_EPS_ZERO) ; }
{ return IsEpsilon( EPS_ZERO) ; }
int GetNbrMinDist( void)
{ return (( m_dSqDist < 0) ? 0 : 1) ; }
bool GetMinDistPoint( Point3d& ptMinDist) ;
+1 -1
View File
@@ -39,7 +39,7 @@ void
DistPointTriangle::Calculate( const Point3d& ptP, const Triangle3d& Tria)
{
// Proiezione del punto sul piano del triangolo
Point3d ptQ = ptP - (( ptP - Tria.GetP( 0)) * Tria.GetN()) * Tria.GetN() ;
Point3d ptQ = ptP - (( ptP - Tria.GetCentroid()) * Tria.GetN()) * Tria.GetN() ;
// Verifico se il punto proiettato sta nel triangolo
if ( PointInTria( ptQ, Tria) != PTT_OUT) {
+4 -6
View File
@@ -148,8 +148,7 @@ IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm,
if ( LnGrid.Find( b3Pnt, vnIds)) {
for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) {
int nA = vnIds[j] ;
double dSqDist ;
if ( DistPointLine( vPnt[i], vBpt[nA].first, vBpt[nA].second).GetSqDist( dSqDist) && dSqDist < 100 * SQ_EPS_SMALL) {
if ( DistPointLine( vPnt[i], vBpt[nA].first, vBpt[nA].second).IsEpsilon( 10 * EPS_SMALL)) {
bFound = true ;
break ;
}
@@ -169,8 +168,7 @@ IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm,
for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) {
int nA = vnIds[j] ;
const Triangle3d& trOth = vTria[nA] ;
double dSqDist ;
if ( DistPointTriangle( vPnt[i], trOth).GetSqDist( dSqDist) && dSqDist < 100 * SQ_EPS_SMALL) {
if ( DistPointTriangle( vPnt[i], trOth).IsEpsilon( 10 * EPS_SMALL)) {
bFound = true ;
break ;
}
@@ -191,8 +189,8 @@ IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm,
for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) {
int nA = vnIds[j] ;
const Triangle3d& trOth = vTria[nA] ;
Point3d ptInt, ptInt2 ;
if ( IntersLineTria( ptStart, ptEnd, trOth, ptInt, ptInt2) == ILTT_SEGM_ON_EDGE) {
if ( DistPointTriangle( ptStart, trOth).IsEpsilon( 10 * EPS_SMALL) &&
DistPointTriangle( ptEnd, trOth).IsEpsilon( 10 * EPS_SMALL)) {
bFound = true ;
break ;
}
+40 -40
View File
@@ -62,14 +62,14 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
HashGrids3d HHGrids ;
const int LIM_SRFNBRSQUARED = 4095 ;
HHGrids.SetActivationGrid( long long( nTriaNbr1) * long long(nTriaNbr2) > LIM_SRFNBRSQUARED) ;
Triangle3d Tria ;
int nT = ( bHash1 ? Stm1.GetFirstTriangle( Tria) : Stm2.GetFirstTriangle( Tria)) ;
Triangle3d TriaH ;
int nT = ( bHash1 ? Stm1.GetFirstTriangle( TriaH) : Stm2.GetFirstTriangle( TriaH)) ;
while ( nT != SVT_NULL) {
BBox3d boxT ;
Tria.GetLocalBBox( boxT) ;
TriaH.GetLocalBBox( boxT) ;
if ( ! HHGrids.Add( nT, boxT))
return false ;
nT = ( bHash1 ? Stm1.GetNextTriangle( nT, Tria) : Stm2.GetNextTriangle( nT, Tria)) ;
nT = ( bHash1 ? Stm1.GetNextTriangle( nT, TriaH) : Stm2.GetNextTriangle( nT, TriaH)) ;
}
if ( ! HHGrids.Update())
return false ;
@@ -88,8 +88,8 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
if ( bHash1 ? Stm1.GetTriangle( nB, TriaB) : Stm2.GetTriangle( nB, TriaB)) {
// intersezione tra i triangoli
Point3d ptInt, ptInt2 ;
PNTVECTOR vPnt ;
int nRes = IntersTriaTria( TriaA, TriaB, ptInt, ptInt2, vPnt) ;
TRIA3DVECTOR vIttTria ;
int nRes = IntersTriaTria( TriaA, TriaB, ptInt, ptInt2, vIttTria) ;
// se punto
if ( nRes == ITTT_VERT || nRes == ITTT_PNT) {
// verifico se punto già inserito
@@ -131,34 +131,36 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
}
// se altrimenti sovrapposizione
else if ( nRes == ITTT_OVERLAPS) {
//// verifico se triangolo già inserito
// bool bFound = false ;
// BBox3d b3Tria( Tria.GetP( 0), Tria.GetP( 1)) ;
// b3Tria.Add( Tria.GetP( 2)) ;
// INTVECTOR vnIds ;
// if ( TrGrid.Find( b3Tria, vnIds)) {
// for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
// int nA = vnIds[i] ;
// const Triangle3d& trOth = vTria[nA] ;
// array< bool, 3> bOth = { false, false, false} ;
// for ( int j = 0 ; j < 3 ; ++ j) {
// for ( int k = 0 ; k < 3 ; ++ k) {
// if ( ! bOth[k])
// bOth[k] = AreSamePointEpsilon( Tria.GetP( j), trOth.GetP( k), 10 * EPS_SMALL) ;
// }
// }
// if ( bOth[0] && bOth[1] && bOth[2]) {
// bFound = true ;
// break ;
// }
// }
// }
//// se non inserito, procedo
// if ( ! bFound) {
// vTria.emplace_back( Tria) ;
// TrGrid.Add( int( vTria.size()) - 1, b3Tria) ;
// TrGrid.Update() ;
// }
for each ( const auto& Tria in vIttTria) {
// verifico se triangolo già inserito
bool bFound = false ;
BBox3d b3Tria ;
Tria.GetLocalBBox( b3Tria) ;
INTVECTOR vnIds ;
if ( TrGrid.Find( b3Tria, vnIds)) {
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
int nA = vnIds[i] ;
const Triangle3d& trOth = vTria[nA] ;
array< bool, 3> bOth = { false, false, false} ;
for ( int j = 0 ; j < 3 ; ++ j) {
for ( int k = 0 ; k < 3 ; ++ k) {
if ( ! bOth[k])
bOth[k] = AreSamePointEpsilon( Tria.GetP( j), trOth.GetP( k), 10 * EPS_SMALL) ;
}
}
if ( bOth[0] && bOth[1] && bOth[2]) {
bFound = true ;
break ;
}
}
}
// se non inserito, procedo
if ( ! bFound) {
vTria.emplace_back( Tria) ;
TrGrid.Add( int( vTria.size()) - 1, b3Tria) ;
TrGrid.Update() ;
}
}
}
}
}
@@ -176,8 +178,7 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
if ( LnGrid.Find( b3Pnt, vnIds)) {
for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) {
int nA = vnIds[j] ;
double dSqDist ;
if ( DistPointLine( vPnt[i], vBpt[nA].first, vBpt[nA].second).GetSqDist( dSqDist) && dSqDist < 100 * SQ_EPS_SMALL) {
if ( DistPointLine( vPnt[i], vBpt[nA].first, vBpt[nA].second).IsEpsilon( 10 * EPS_SMALL)) {
bFound = true ;
break ;
}
@@ -197,8 +198,7 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) {
int nA = vnIds[j] ;
const Triangle3d& trOth = vTria[nA] ;
double dSqDist ;
if ( DistPointTriangle( vPnt[i], trOth).GetSqDist( dSqDist) && dSqDist < 100 * SQ_EPS_SMALL) {
if ( DistPointTriangle( vPnt[i], trOth).IsEpsilon( 10 * EPS_SMALL)) {
bFound = true ;
break ;
}
@@ -219,8 +219,8 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) {
int nA = vnIds[j] ;
const Triangle3d& trOth = vTria[nA] ;
Point3d ptInt, ptInt2 ;
if ( IntersLineTria( ptStart, ptEnd, trOth, ptInt, ptInt2) == ILTT_SEGM_ON_EDGE) {
if ( DistPointTriangle( ptStart, trOth).IsEpsilon( 10 * EPS_SMALL) &&
DistPointTriangle( ptEnd, trOth).IsEpsilon( 10 * EPS_SMALL)) {
bFound = true ;
break ;
}
+58 -42
View File
@@ -15,6 +15,10 @@
#include "stdafx.h"
#include "ProjPlane.h"
#include "IntersLineTria.h"
#include "CurveComposite.h"
#include "SurfFlatRegion.h"
#include "Triangulate.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGkIntersTriaTria.h"
#include "/EgtDev/Include/EGkIntersPlanePlane.h"
#include <array>
@@ -22,11 +26,11 @@
using namespace std ;
//----------------------------------------------------------------------------
static int IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, PNTVECTOR& vPnt) ;
static int IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TRIA3DVECTOR& vTria) ;
//----------------------------------------------------------------------------
int
IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& ptInt, Point3d& ptInt2, PNTVECTOR& vPnt)
IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& ptInt, Point3d& ptInt2, TRIA3DVECTOR& vTria)
{
// piano del secondo triangolo
Plane3d plTria2 ;
@@ -68,7 +72,7 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
// se i triangoli sono complanari
if ( ( nVertPos1 == 0 && nVertNeg1 == 0) || ( nVertPos2 == 0 && nVertNeg2 == 0))
return IntersCoplanarTriaTria( trTria1, trTria2, vPnt) ;
return IntersCoplanarTriaTria( trTria1, trTria2, vTria) ;
// intersezione tra i piani dei due triangoli
Point3d ptL1 ; Vector3d vtL1 ;
@@ -101,48 +105,60 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
case ILTT_EDGE : return ITTT_PNT ;
default : return ITTT_NO ;
}
#if 0
// interseco il primo triangolo con il piano del secondo
Plane3d plPlane2 ;
plPlane2.Set( trTria2.GetCentroid(), trTria2.GetN()) ;
int nPtRes = IntersPlaneTria( plPlane2, trTria1, ptInt, ptInt2) ;
// se non c'è intersezione
if ( nPtRes == IPTT_NO)
return ITTT_NO ;
// se altrimenti complanari
else if ( nPtRes == IPTT_OVERLAPS)
return IntersCoplanarTriaTria( trTria1, trTria2, vPnt) ;
// se intersezione in un vertice
else if ( nPtRes == IPTT_VERT) {
// se l'intersezione sta anche nel secondo triangolo
if ( PointInTria( ptInt, trTria2))
return ITTT_VERT ;
else
return ITTT_NO ;
}
// altrimenti è un segmento, va limitato col secondo triangolo
Point3d ptL = ptInt ;
Vector3d vtL = ptInt2 - ptInt ;
double dLen = vtL.Len() ;
vtL /= dLen ;
int nRes = IntersCoplanarLineTria( ptL, vtL, dLen, trTria2, ptInt, ptInt2, true) ;
switch( nRes) {
case ILTT_NO : return ITTT_NO ;
case ILTT_SEGM : return ITTT_YES ;
case ILTT_SEGM_ON_EDGE : return ITTT_EDGE ;
case ILTT_VERT : return ITTT_VERT ;
case ILTT_EDGE : return ITTT_PNT ;
default : return ITTT_NO ;
}
#endif
}
//----------------------------------------------------------------------------
int
IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, PNTVECTOR& vPnt)
IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TRIA3DVECTOR& vTria)
{
// !!! PROVVISORIO !!!
return ITTT_NO ;
// creo la regione equivalente al primo triangolo
SurfFlatRegion sfrTria1 ;
PtrOwner<CurveComposite> pCcTria1( CreateBasicCurveComposite()) ;
if ( IsNull( pCcTria1))
return ITTT_NO ;
pCcTria1->AddPoint( trTria1.GetP( 0)) ;
pCcTria1->AddLine( trTria1.GetP( 1)) ;
pCcTria1->AddLine( trTria1.GetP( 2)) ;
pCcTria1->Close() ;
if ( ! sfrTria1.AddExtLoop( Release( pCcTria1)))
return ITTT_NO ;
// creo la regione equivalente al secondo triangolo
SurfFlatRegion sfrTria2 ;
PtrOwner<CurveComposite> pCcTria2( CreateBasicCurveComposite()) ;
if ( IsNull( pCcTria2))
return ITTT_NO ;
pCcTria2->AddPoint( trTria2.GetP( 0)) ;
pCcTria2->AddLine( trTria2.GetP( 1)) ;
pCcTria2->AddLine( trTria2.GetP( 2)) ;
pCcTria2->Close() ;
if ( ! sfrTria2.AddExtLoop( Release( pCcTria2)))
return ITTT_NO ;
if ( sfrTria1.GetNormVersor() * sfrTria2.GetNormVersor() < 0)
sfrTria2.Invert() ;
// calcolo l'intersezione tra le due regioni
if ( ! sfrTria1.Intersect( sfrTria2) || ! sfrTria1.IsValid())
return ITTT_NO ;
// recupero il contorno esterno del risultato come polilinea
PolyLine PL ;
if ( ! sfrTria1.ApproxLoopWithLines( 0, 0, LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
return ITTT_NO ;
// eseguo una triangolazione del contorno chiuso
PNTVECTOR vPnt ;
INTVECTOR vTrVert ;
Triangulate Tri ;
if ( ! Tri.Make( PL, vPnt, vTrVert))
return ITTT_NO ;
int nTrVert = int( vTrVert.size()) / 3 ;
for ( int i = 0 ; i < nTrVert ; ++i) {
Triangle3d Tria ;
Tria.Set( vPnt[vTrVert[3*i]], vPnt[vTrVert[3*i+1]], vPnt[vTrVert[3*i+2]]) ;
if ( Tria.Validate( true))
vTria.emplace_back( Tria) ;
}
return ITTT_OVERLAPS ;
}