EgtGeomKernel 2.3k3 :
- modifiche per GeneralizedCut di SurfTriMesh - Cut e GeneralizedCut di SurfTriMesh spostati in nuovo sorgente SurfTriMeshCuts.cpp.
This commit is contained in:
@@ -248,3 +248,192 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen)
|
||||
// Eseguo aggiustamenti
|
||||
return ( AdjustVertices() && DoCompacting()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::AddChainToChain( const Chain& ChainToAdd, PNTVECTOR& OrigChain)
|
||||
{
|
||||
// Se la catena da aggiungere è vuota, non devo fare alcunchè
|
||||
if ( ChainToAdd.size() == 0)
|
||||
return true ;
|
||||
// Se la catena originale è vuota, non è possibile aggiungere nulla
|
||||
if ( OrigChain.size() == 0)
|
||||
return false ;
|
||||
// Se la catena originale è chiusa non posso aggiungere nulla
|
||||
int nLastOrig = max( int( OrigChain.size()) - 1, 0) ;
|
||||
if ( AreSamePointApprox( OrigChain[0], OrigChain[nLastOrig]))
|
||||
return false ;
|
||||
int nLastToAdd = max( int( ChainToAdd.size()) - 1, 0) ;
|
||||
if ( AreSamePointApprox( OrigChain[nLastOrig], ChainToAdd[0].ptSt)) {
|
||||
for ( int nPt = 1 ; nPt <= nLastToAdd ; ++ nPt) {
|
||||
if ( nPt == nLastToAdd) {
|
||||
if ( ! AreSamePointApprox(OrigChain[0], ChainToAdd[nPt].ptSt))
|
||||
OrigChain.emplace_back( ChainToAdd[nPt].ptSt) ;
|
||||
}
|
||||
else if ( nPt == 1) {
|
||||
if ( ! AreSamePointApprox( OrigChain[nLastOrig], ChainToAdd[nPt].ptSt))
|
||||
OrigChain.emplace_back( ChainToAdd[nPt].ptSt) ;
|
||||
}
|
||||
else
|
||||
OrigChain.emplace_back( ChainToAdd[nPt].ptSt) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Una faccia di una trimesh ha una sola componente connessa, con un loop esterno e possibili loop interni
|
||||
bool
|
||||
SurfTriMesh::DistPointFacet( const Point3d& ptP, const POLYLINEVECTOR& vPolyVec, double& dPointFacetDist)
|
||||
{
|
||||
// Verifico la presenza del loop esterno
|
||||
if ( vPolyVec.size() < 1)
|
||||
return false ;
|
||||
// Proietto il punto sul piano della faccia, utilizzando il loop esterno
|
||||
Plane3d plPlane ;
|
||||
double dArea ;
|
||||
if ( ! vPolyVec[0].IsClosedAndFlat( plPlane, dArea))
|
||||
return false ;
|
||||
double dDistPtPl = DistPointPlane( ptP, plPlane) ;
|
||||
Point3d ptProjP = ptP + dDistPtPl * plPlane.GetVersN() ;
|
||||
// Verifico se il punto proiettato è esterno al loop esterno
|
||||
int nPtOut = -1 ;
|
||||
if ( ! IsPointInsidePolyLine( ptProjP, vPolyVec[0], EPS_SMALL))
|
||||
nPtOut = 0 ;
|
||||
// Verifico se il punto proiettato è interno ai loop interni (quindi esterno alla faccia)
|
||||
for ( int nLoop = 1 ; nLoop < int( vPolyVec.size()) && nPtOut < 0 ; ++ nLoop) {
|
||||
Plane3d plPlane ;
|
||||
double dArea ;
|
||||
if ( ! vPolyVec[nLoop].IsClosedAndFlat( plPlane, dArea))
|
||||
return false ;
|
||||
if ( IsPointInsidePolyLine( ptProjP, vPolyVec[nLoop], EPS_SMALL))
|
||||
nPtOut = nLoop ;
|
||||
}
|
||||
// Se il punto si proietta sulla faccia, la distanza dalla faccia coincide con quella dal piano
|
||||
if ( nPtOut < 0) {
|
||||
dPointFacetDist = abs( dDistPtPl) ;
|
||||
return true ;
|
||||
}
|
||||
// Altrimenti calcolo la minima distanza del punto dalla polilinea del contorno a cui è esterno
|
||||
double dDist ;
|
||||
if ( DistPointPolyLine( ptP, vPolyVec[nPtOut], dDist)) {
|
||||
dPointFacetDist = dDist ;
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop)
|
||||
{
|
||||
// Cerco il tratto del loop chiuso più vicino al punto
|
||||
int nMinSeg = - 1 ;
|
||||
double dMinSqDinst = DBL_MAX ;
|
||||
for ( int nPt = 0 ; nPt < int( Loop.size()) ; ++ nPt) {
|
||||
// Estremi del segmento corrente del loop
|
||||
Point3d ptSegSt = Loop[nPt] ;
|
||||
Point3d ptSegEn = Loop[( nPt + 1) % int( Loop.size())] ;
|
||||
// Distanza del punto dal segmento del loop
|
||||
DistPointLine dDistCalc( ptNewStart, ptSegSt, ptSegEn) ;
|
||||
double dSqDist ;
|
||||
dDistCalc.GetSqDist( dSqDist) ;
|
||||
if ( dSqDist < dMinSqDinst) {
|
||||
dMinSqDinst = dSqDist ;
|
||||
nMinSeg = nPt ;
|
||||
}
|
||||
}
|
||||
// Se il punto non sta sul loop, errore
|
||||
if ( dMinSqDinst > SQ_EPS_SMALL)
|
||||
return false ;
|
||||
// Verifico che il punto stia su un vertice, in tal caso non devo fare nulla
|
||||
bool bOnStart = AreSamePointApprox( Loop[nMinSeg], ptNewStart) ;
|
||||
bool bOnEnd = AreSamePointApprox( Loop[( nMinSeg + 1) % int( Loop.size())], ptNewStart) ;
|
||||
if ( bOnStart || bOnEnd) {
|
||||
if ( bOnEnd) {
|
||||
++ nMinSeg ;
|
||||
if ( nMinSeg % int( Loop.size()) == 0)
|
||||
return true ;
|
||||
}
|
||||
PNTVECTOR vTempVec ;
|
||||
for ( int nPt = 0 ; nPt < nMinSeg ; ++ nPt)
|
||||
vTempVec.emplace_back( Loop[nPt]) ;
|
||||
int nSize = int( Loop.size()) ;
|
||||
for ( int nPt = 0 ; nPt < nSize - nMinSeg ; ++ nPt) {
|
||||
Loop[nPt] = Loop[nPt + nMinSeg] ;
|
||||
}
|
||||
for ( int nPt = 0 ; nPt < int( vTempVec.size()) ; ++ nPt) {
|
||||
Loop[nPt + nSize - nMinSeg] = vTempVec[nPt] ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
// Ridimensiono il loop
|
||||
Loop.resize( Loop.size() + 1) ;
|
||||
// Copio i primi punti
|
||||
PNTVECTOR LoopTemp ;
|
||||
for ( int nPt = 0 ; nPt <= nMinSeg ; ++ nPt)
|
||||
LoopTemp.emplace_back( Loop[nPt]) ;
|
||||
// Aggiungo il nuovo punto all'inizio
|
||||
Loop[0] = ptNewStart ;
|
||||
// Sposto gli ultimi in testa
|
||||
int nLastPointNum = int( Loop.size()) - 1 - nMinSeg ;
|
||||
for ( int nPt = 1 ; nPt <= nLastPointNum ; ++ nPt) {
|
||||
Loop[nPt] = Loop[nPt + nMinSeg] ;
|
||||
}
|
||||
// Porto i primi in fondo
|
||||
for ( int nPt = 0 ; nPt < int( LoopTemp.size()) ; ++ nPt) {
|
||||
Loop[nPt + nLastPointNum] = LoopTemp[nPt] ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::SplitAtPoint( const Point3d& ptStop, const PNTVECTOR& Loop, PNTVECTOR& Loop1, PNTVECTOR& Loop2)
|
||||
{
|
||||
// Cerco il tratto del loop chiuso più vicino al punto
|
||||
int nMinSeg = -1 ;
|
||||
double dMinSqDinst = DBL_MAX ;
|
||||
for ( int nPt = 0 ; nPt < int( Loop.size()) ; ++ nPt) {
|
||||
// Estremi del segmento corrente del loop
|
||||
Point3d ptSegSt = Loop[nPt] ;
|
||||
Point3d ptSegEn = Loop[( nPt + 1) % int(Loop.size())] ;
|
||||
// Distanza del punto dal segmento del loop
|
||||
DistPointLine dDistCalc( ptStop, ptSegSt, ptSegEn) ;
|
||||
double dSqDist ;
|
||||
dDistCalc.GetSqDist( dSqDist) ;
|
||||
if ( dSqDist < dMinSqDinst) {
|
||||
dMinSqDinst = dSqDist ;
|
||||
nMinSeg = nPt ;
|
||||
}
|
||||
}
|
||||
// Se il punto non sta sul loop, errore
|
||||
if ( dMinSqDinst > SQ_EPS_SMALL)
|
||||
return false ;
|
||||
// Verifico che il punto stia su un vertice, in tal caso non devo aggiungerlo
|
||||
bool bFirst = AreSamePointApprox( Loop[nMinSeg], ptStop) ;
|
||||
bool bLast = AreSamePointApprox( Loop[( nMinSeg + 1) % int( Loop.size())], ptStop) ;
|
||||
// Se il punto è sul vertice finale del segmento, aggiungo il vertice alla lista da inglobare al primo loop
|
||||
if ( bLast)
|
||||
++ nMinSeg ;
|
||||
// Inglobo fino a nSeg nel primo loop
|
||||
for ( int nPt = 0 ; nPt <= nMinSeg && nPt < int( Loop.size()) ; ++ nPt)
|
||||
Loop1.emplace_back( Loop[nPt]) ;
|
||||
// Se il punto è interno al segmento, lo inglobo in entrambi i loop
|
||||
if ( ! ( bFirst || bLast)) {
|
||||
Loop1.emplace_back( ptStop) ;
|
||||
Loop2.emplace_back( ptStop) ;
|
||||
}
|
||||
else {
|
||||
if ( nMinSeg != int( Loop.size()) )
|
||||
Loop2.emplace_back( Loop[nMinSeg]) ;
|
||||
}
|
||||
// Inglobo gli ultimi vertici in Loop2
|
||||
for ( int nPt = nMinSeg + 1 ; nPt < int( Loop.size()) ; ++ nPt)
|
||||
Loop2.emplace_back( Loop[nPt]) ;
|
||||
Loop2.emplace_back( Loop[0]) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user