EgtGeomKernel 1.9b1 :
- in Zmap N_DEXVOXRATIO riportato a 1 - in Zmap migliorie a visualizzazione - in Zmap migliorate GetDepth e AvoidBox.
This commit is contained in:
Binary file not shown.
+1
-1
@@ -1036,7 +1036,7 @@ PolyLine::GetConvexHullXY( PNTVECTOR& vConvHull) const
|
||||
for each ( const auto& Pnt in m_lUPoints)
|
||||
vPnt[k++] = Point3d( Pnt.first.x, Pnt.first.y, 0) ;
|
||||
// ordino secondo le X crescenti
|
||||
std::sort( vPnt.begin(), vPnt.end(),
|
||||
sort( vPnt.begin(), vPnt.end(),
|
||||
[]( const Point3d& a, const Point3d& b) { return ( a.x < b.x) ; }) ;
|
||||
// elimino eventuali punti coincidenti
|
||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
||||
|
||||
@@ -30,8 +30,9 @@
|
||||
//----------------------------------------------------------------------------
|
||||
struct TriaStruct {
|
||||
int i, j, k ;
|
||||
std::vector<Point3d> ptCompoVert ;
|
||||
PNTVECTOR ptCompoVert ;
|
||||
std::vector<TRIA3DEXVECTOR> vCompoTria ;
|
||||
std::vector<std::vector<bool>> vbFlipped ;
|
||||
} ;
|
||||
|
||||
// Vettore di TriaStruct con sharp fature interni a un blocco
|
||||
@@ -176,7 +177,6 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax) ;
|
||||
bool AddIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ,
|
||||
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax) ;
|
||||
|
||||
|
||||
// SOTTRAZIONI
|
||||
// UTENSILI
|
||||
@@ -322,7 +322,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
||||
static const int N_MAPS = 3 ;
|
||||
static const int N_VOXBLOCK = 32 ;
|
||||
static const int N_DEXVOXRATIO = 2 ;
|
||||
static const int N_DEXVOXRATIO = 1 ;
|
||||
|
||||
private :
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
|
||||
+79
-104
@@ -218,10 +218,10 @@ VolZmap::GetDepth( const Point3d& ptPLoc, const Vector3d& vtDLoc, double& dInLen
|
||||
ptP.ToLoc( m_MapFrame) ;
|
||||
vtD.ToLoc( m_MapFrame) ;
|
||||
|
||||
if ( bExact)
|
||||
return GetDepthWithVoxel( ptP, vtD, dInLength, dOutLength, true) ;
|
||||
if ( bExact && m_nMapNum == 3)
|
||||
return GetDepthWithVoxel( ptP, vtD, dInLength, dOutLength, true) ;
|
||||
else
|
||||
return GetDepthWithDexel( ptP, vtD, dInLength, dOutLength) ;
|
||||
return GetDepthWithDexel( ptP, vtD, dInLength, dOutLength) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -272,7 +272,7 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
|
||||
swap( ptI.y, ptI.z) ;
|
||||
swap( ptI.x, ptI.z) ;
|
||||
swap( ptF.y, ptF.z) ;
|
||||
swap( ptF.x, ptF.z) ;
|
||||
swap( ptF.x, ptF.z) ;
|
||||
}
|
||||
else if ( nGrid == 2) {
|
||||
swap( ptP0.x, ptP0.z) ;
|
||||
@@ -281,21 +281,21 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
|
||||
swap( vtV0.y, vtV0.z) ;
|
||||
swap( ptI.x, ptI.z) ;
|
||||
swap( ptI.y, ptI.z) ;
|
||||
swap( ptF.x, ptF.z) ;
|
||||
swap( ptF.y, ptF.z) ;
|
||||
swap( ptF.x, ptF.z) ;
|
||||
swap( ptF.y, ptF.z) ;
|
||||
}
|
||||
|
||||
|
||||
// Inizializzo distanze
|
||||
dInLen[nGrid] = INFINITO ;
|
||||
dOutLen[nGrid] = - INFINITO ;
|
||||
|
||||
|
||||
// Determino asse di spostamento maggiore
|
||||
bool bOnX = ( abs( ptF.y - ptI.y) <= abs( ptF.x - ptI.x)) ;
|
||||
|
||||
|
||||
// Movimento crescente su asse di movimento principale
|
||||
if ( ( bOnX && ptF.x < ptI.x) || ( ! bOnX && ptF.y < ptI.y) )
|
||||
swap( ptI, ptF) ;
|
||||
|
||||
|
||||
// Pendenza
|
||||
double dDeltaX = ( ptF.x - ptI.x) ;
|
||||
double dDeltaY = ( ptF.y - ptI.y) ;
|
||||
@@ -304,24 +304,24 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
|
||||
dM = dDeltaY / dDeltaX ;
|
||||
else if ( ! bOnX && abs( dDeltaY) > EPS_SMALL)
|
||||
dM = dDeltaX / dDeltaY ;
|
||||
|
||||
// Determinazione degli indici i j dei punti ptI e ptF
|
||||
|
||||
// Determinazione degli indici i j dei punti ptI e ptF
|
||||
int nIi = Clamp( int( floor( ptI.x / m_dStep)), 0, m_nNx[nGrid] - 1) ;
|
||||
int nIj = Clamp( int( floor( ptI.y / m_dStep)), 0, m_nNy[nGrid] - 1) ;
|
||||
int nFi = Clamp( int( floor( ptF.x / m_dStep)), 0, m_nNx[nGrid] - 1) ;
|
||||
int nFj = Clamp( int( floor( ptF.y / m_dStep)), 0, m_nNy[nGrid] - 1) ;
|
||||
|
||||
|
||||
// mi muovo
|
||||
int i = nIi ; int j = nIj ;
|
||||
while ( ( bOnX && i <= nFi) || ( ! bOnX && j <= nFj)) {
|
||||
|
||||
|
||||
// Eseguo controllo
|
||||
double dU1, dU2 ;
|
||||
if ( IntersRayDexel( ptP0, vtV0, nGrid, i, j, dU1, dU2)) {
|
||||
dInLen[nGrid] = min( dInLen[nGrid], dU1) ;
|
||||
dOutLen[nGrid] = max( dOutLen[nGrid], dU2) ;
|
||||
}
|
||||
|
||||
|
||||
// Calcolo spostamento (a destra o sopra)
|
||||
if ( bOnX) {
|
||||
double dMoveX = ( ( i + 1) * m_dStep - ptI.x) ;
|
||||
@@ -344,11 +344,11 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
|
||||
++ j ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Se non abbiamo incontrato materiale
|
||||
if ( dInLen[nGrid] > dOutLen[nGrid] - EPS_SMALL) {
|
||||
dInLen[nGrid] = - 2 ;
|
||||
dOutLen[nGrid] = - 2 ;
|
||||
dOutLen[nGrid] = - 2 ;
|
||||
}
|
||||
// Se parto dall'interno
|
||||
else if ( dInLen[nGrid] < - EPS_SMALL)
|
||||
@@ -361,7 +361,6 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
if ( abs( dInLen[0] + 2) < EPS_SMALL &&
|
||||
abs( dInLen[1] + 2) < EPS_SMALL &&
|
||||
abs( dInLen[2] + 2) < EPS_SMALL) {
|
||||
@@ -370,7 +369,6 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
|
||||
return true ;
|
||||
}
|
||||
else {
|
||||
|
||||
dInLength = INFINITO ;
|
||||
dOutLength = - INFINITO ;
|
||||
for ( int nGr = 0 ; nGr < 3 ; ++ nGr) {
|
||||
@@ -380,8 +378,7 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
|
||||
dOutLength = dOutLen[nGr] ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -394,11 +391,10 @@ VolZmap::GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtV, double& dIn
|
||||
bool
|
||||
VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dInLength, double& dOutLength, bool bEnh) const
|
||||
{
|
||||
// Parametri di intersezione retta BBox dello Zmap
|
||||
double dU1, dU2 ;
|
||||
|
||||
// Intersezione fra semiretta e BBox dello Zmap
|
||||
double dU1, dU2 ;
|
||||
bool bLineBBoxInters = IntersLineZMapBBox( ptP, vtD, dU1, dU2) && ( dU1 > 0 || dU2 > 0) ;
|
||||
|
||||
// Semiretta esterna al box dello Zmap quindi esterna anche allo Zmap
|
||||
if ( ! bLineBBoxInters) {
|
||||
dInLength = - 2 ;
|
||||
@@ -406,28 +402,24 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Indici del voxel corrente
|
||||
int nVoxI, nVoxJ, nVoxK ;
|
||||
// Determino il voxel di partenza
|
||||
int nVoxI, nVoxJ, nVoxK ;
|
||||
if ( ! GetPointVoxel( ptP, nVoxI, nVoxJ, nVoxK)) {
|
||||
if ( ! GetPointVoxel( ptP + dU1 * vtD, nVoxI, nVoxJ, nVoxK))
|
||||
return false ;
|
||||
}
|
||||
|
||||
// Vettore di voxel
|
||||
vector<Voxel> vVox ;
|
||||
|
||||
// Incrementi degli indici per sguire la retta
|
||||
int nDeltaI = ( vtD.x > 0 ? 1 : ( vtD.x < 0 ? - 1 : 0)) ;
|
||||
int nDeltaJ = ( vtD.y > 0 ? 1 : ( vtD.y < 0 ? - 1 : 0)) ;
|
||||
int nDeltaK = ( vtD.z > 0 ? 1 : ( vtD.z < 0 ? - 1 : 0)) ;
|
||||
// Scelgo i piani del voxel con cui intersecare la retta,
|
||||
// per determinare il voxel successivo
|
||||
// Scelgo i piani del voxel con cui intersecare la retta, per determinare il voxel successivo
|
||||
int nPlaneI = ( vtD.x >= 0 ? 1 : 0) ;
|
||||
int nPlaneJ = ( vtD.y >= 0 ? 1 : 0) ;
|
||||
int nPlaneK = ( vtD.z >= 0 ? 1 : 0) ;
|
||||
|
||||
// Ciclo sui voxel
|
||||
vector<Voxel> vVox ;
|
||||
while ( IsValidVoxel( nVoxI, nVoxJ, nVoxK)) {
|
||||
// Estremi della diagonale del voxel corrente
|
||||
Point3d ptMin( ( nVoxI * N_DEXVOXRATIO + 0.5) * m_dStep,
|
||||
@@ -451,7 +443,7 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
|
||||
abs( ( ( ( nVoxJ + nPlaneJ) * N_DEXVOXRATIO + 0.5) * m_dStep - ptP.y) / vtD.y) : INFINITO) ;
|
||||
double dMaxTZ = ( abs( vtD.z) > EPS_ZERO ?
|
||||
abs( ( ( ( nVoxK + nPlaneK) * N_DEXVOXRATIO + 0.5) * m_dStep - ptP.z) / vtD.z) : INFINITO) ;
|
||||
|
||||
// Determino gli incrementi
|
||||
if ( dMaxTX < dMaxTY) {
|
||||
if ( dMaxTX < dMaxTZ)
|
||||
nVoxI += nDeltaI ;
|
||||
@@ -466,76 +458,54 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
|
||||
}
|
||||
}
|
||||
|
||||
// Triangoli di frontiera dei voxel
|
||||
TRIA3DEXLIST lstTria ;
|
||||
ExtMarchingCubes( vVox, lstTria, bEnh) ;
|
||||
|
||||
// Struttura studio dell'intersezione
|
||||
// Dati dell'intersezione
|
||||
struct LineTriaInt {
|
||||
double dPar ;
|
||||
double dDot ;
|
||||
int nNum ;
|
||||
double dPar1 ;
|
||||
double dPar2 ;
|
||||
double dDot ;
|
||||
LineTriaInt( void) : nNum( 0) {}
|
||||
LineTriaInt( double dP, double dD) : nNum( 1), dPar1( dP), dDot( dD) {}
|
||||
LineTriaInt( double dP1, double dP2, double dD)
|
||||
: nNum( 2), dPar1( dP1), dPar2( dP2), dDot( dD) {}
|
||||
} ;
|
||||
vector<vector<LineTriaInt>> IntMatrix ;
|
||||
vector<LineTriaInt> vInt ;
|
||||
|
||||
// Ciclo sui triangoli del voxel
|
||||
// Ciclo sui triangoli dei voxel
|
||||
for ( auto it = lstTria.begin() ; it != lstTria.end() ; ++it ) {
|
||||
// Triangolo corrente e suoi punti di intersezione con la retta
|
||||
Triangle3d CurrTria = *it ;
|
||||
// Triangolo corrente e suoi punti di intersezione con la retta
|
||||
const Triangle3d& CurrTria = *it ;
|
||||
Point3d ptLineTria1, ptLineTria2 ;
|
||||
// Studio dell'intersezione della retta con il triangolo corrente
|
||||
// Studio dell'intersezione della retta con il triangolo corrente
|
||||
int nIntType = IntersLineTria( ptP, vtD, 1.5 * dU2, CurrTria, ptLineTria1, ptLineTria2) ;
|
||||
// Se non ci sono intersezioni passo al prossimo triangolo
|
||||
// Se non ci sono intersezioni passo al prossimo triangolo
|
||||
if ( nIntType == ILTT_NO)
|
||||
continue ;
|
||||
// se altrimenti c'è una sola intersezione
|
||||
// se altrimenti c'è una sola intersezione
|
||||
else if ( nIntType == ILTT_VERT ||
|
||||
nIntType == ILTT_EDGE ||
|
||||
nIntType == ILTT_IN) {
|
||||
LineTriaInt NewInt ;
|
||||
NewInt.dPar = ( ptLineTria1 - ptP) * vtD ;
|
||||
NewInt.dDot = vtD * CurrTria.GetN() ;
|
||||
vector<LineTriaInt> vSing ;
|
||||
vSing.emplace_back( NewInt) ;
|
||||
|
||||
IntMatrix.emplace_back( vSing) ;
|
||||
vInt.emplace_back( ( ptLineTria1 - ptP) * vtD, vtD * CurrTria.GetN()) ;
|
||||
}
|
||||
// altrimenti ci sono due intersezioni
|
||||
// altrimenti ci sono due intersezioni
|
||||
else {
|
||||
LineTriaInt NewInt1, NewInt2 ;
|
||||
vector<LineTriaInt> vCouple ;
|
||||
double dP1 = ( ptLineTria1 - ptP) * vtD ;
|
||||
double dP2 = ( ptLineTria2 - ptP) * vtD ;
|
||||
NewInt1.dPar = ( dP1 < dP2 ? dP1 : dP2) ;
|
||||
NewInt2.dPar = ( dP1 < dP2 ? dP2 : dP1) ;
|
||||
NewInt1.dDot = vtD * CurrTria.GetN() ;
|
||||
NewInt2.dDot = NewInt1.dDot ;
|
||||
|
||||
vCouple.emplace_back( NewInt1) ;
|
||||
vCouple.emplace_back( NewInt2) ;
|
||||
IntMatrix.emplace_back( vCouple) ;
|
||||
double dD = vtD * CurrTria.GetN() ;
|
||||
vInt.emplace_back( ( dP1 < dP2 ? dP1 : dP2), ( dP1 < dP2 ? dP2 : dP1), dD) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Ordino le intersezioni in base al parametro distanza con segno da ptP
|
||||
for ( int nN = 0 ; nN < int( IntMatrix.size()) - 1 ; ++ nN) {
|
||||
for ( int nM = nN + 1 ; nM < int( IntMatrix.size()) ; ++ nM) {
|
||||
|
||||
double dFP = ( IntMatrix[nN].size() == 2 ? 0.5 * ( IntMatrix[nN][0].dPar + IntMatrix[nN][1].dPar) :
|
||||
IntMatrix[nN][0].dPar) ;
|
||||
double dLP = ( IntMatrix[nM].size() == 2 ? 0.5 * ( IntMatrix[nM][0].dPar + IntMatrix[nM][1].dPar) :
|
||||
IntMatrix[nM][0].dPar) ;
|
||||
|
||||
if ( dFP > dLP)
|
||||
swap( IntMatrix[nN], IntMatrix[nM]) ;
|
||||
}
|
||||
}
|
||||
|
||||
vector<LineTriaInt> vInt ;
|
||||
|
||||
for ( int nN = 0 ; nN < int( IntMatrix.size()) ; ++ nN) {
|
||||
vInt.emplace_back( IntMatrix[nN][0]) ;
|
||||
if ( IntMatrix[nN].size() == 2)
|
||||
vInt.emplace_back( IntMatrix[nN][1]) ;
|
||||
}
|
||||
sort( vInt.begin(), vInt.end(),
|
||||
[]( const LineTriaInt& a, const LineTriaInt& b)
|
||||
{ double dFP = ( a.nNum == 2 ? 0.5 * ( a.dPar1 + a.dPar2) : a.dPar1) ;
|
||||
double dLP = ( b.nNum == 2 ? 0.5 * ( b.dPar1 + b.dPar2) : b.dPar1) ;
|
||||
return ( dLP > dFP) ; }) ;
|
||||
|
||||
// Inizializzo le distanze di ingresso e uscita:
|
||||
// dInLength diminuisce, dOutLength aumenta.
|
||||
@@ -545,7 +515,7 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
|
||||
int nFirstPosN ;
|
||||
int nN = 0 ;
|
||||
for ( ; nN < int( vInt.size()) ; ++ nN) {
|
||||
if ( /*vInt[nN].dPar >= 0*/vInt[nN].dPar > - EPS_SMALL) { // SCEGLIERE FRA LE DUE OPZIONI
|
||||
if ( vInt[nN].dPar1 > - EPS_SMALL) {
|
||||
nFirstPosN = nN ;
|
||||
break ;
|
||||
}
|
||||
@@ -562,10 +532,9 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
|
||||
dInLength = -1 ;
|
||||
}
|
||||
else if ( nFirstPosN == 0) {
|
||||
|
||||
if ( vInt[nFirstPosN].dDot > EPS_ZERO) //
|
||||
if ( vInt[nFirstPosN].dDot > EPS_ZERO)
|
||||
dInLength = -1 ;
|
||||
else if ( GetPointVoxel( ptP, nVoxI, nVoxJ, nVoxK)) {
|
||||
else if ( GetPointVoxel( ptP, nVoxI, nVoxJ, nVoxK)) {
|
||||
int nCubeType = CalcIndex( nVoxI, nVoxJ, nVoxK) ;
|
||||
if ( nCubeType == 255)
|
||||
dInLength = -1 ;
|
||||
@@ -573,14 +542,15 @@ VolZmap::GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtD, double& dIn
|
||||
}
|
||||
|
||||
for ( int nN = nFirstPosN ; nN < int( vInt.size()) ; ++ nN) {
|
||||
|
||||
if ( vInt[nN].dDot > - EPS_ZERO &&
|
||||
dOutLength < vInt[nN].dPar)
|
||||
dOutLength = vInt[nN].dPar ;
|
||||
|
||||
if ( vInt[nN].dDot > - EPS_ZERO) {
|
||||
if ( vInt[nN].nNum == 2 && dOutLength < vInt[nN].dPar2)
|
||||
dOutLength = vInt[nN].dPar2 ;
|
||||
else if ( dOutLength < vInt[nN].dPar1)
|
||||
dOutLength = vInt[nN].dPar1 ;
|
||||
}
|
||||
if ( vInt[nN].dDot < EPS_ZERO &&
|
||||
dInLength > vInt[nN].dPar)
|
||||
dInLength = vInt[nN].dPar ;
|
||||
dInLength > vInt[nN].dPar1)
|
||||
dInLength = vInt[nN].dPar1 ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
@@ -620,23 +590,28 @@ VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const
|
||||
|
||||
// Ciclo di intersezione dei dexel con il BBox
|
||||
for ( int i = nStI ; i <= nEnI ; ++ i) {
|
||||
|
||||
for ( int j = nStJ ; j <= nEnJ ; ++ j) {
|
||||
|
||||
int nPos = j * m_nNx[0] + i ;
|
||||
int nSize = int( m_Values[0][nPos].size()) ;
|
||||
if ( nSize == 0)
|
||||
continue ;
|
||||
|
||||
Point3d ptC = ptO + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ;
|
||||
|
||||
double dZmin, dZmax ;
|
||||
if ( IntersLineBox( ptC, vtK, ORIG, ORIG + vtDiag, dZmin, dZmax)) {
|
||||
|
||||
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
||||
if ( ! ( dZmax < m_Values[0][nPos][nIndex].dMin - EPS_SMALL ||
|
||||
dZmin > m_Values[0][nPos][nIndex].dMax + EPS_SMALL))
|
||||
return false ;
|
||||
for ( int k = 0 ; k < 4 ; ++ k) {
|
||||
Point3d ptC = ptO + i * m_dStep * vtX + j * m_dStep * vtY ;
|
||||
if ( k == 0)
|
||||
ptC += 0.1 * m_dStep * vtX + 0.1 * m_dStep * vtY ;
|
||||
else if ( k == 1)
|
||||
ptC += 0.9 * m_dStep * vtX + 0.1 * m_dStep * vtY ;
|
||||
else if ( k == 2)
|
||||
ptC += 0.9 * m_dStep * vtX + 0.9 * m_dStep * vtY ;
|
||||
else if ( k == 3)
|
||||
ptC += 0.1 * m_dStep * vtX + 0.9 * m_dStep * vtY ;
|
||||
double dZmin, dZmax ;
|
||||
if ( IntersLineBox( ptC, vtK, ORIG, ORIG + vtDiag, dZmin, dZmax)) {
|
||||
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
|
||||
if ( ! ( dZmax < m_Values[0][nPos][nIndex].dMin - EPS_SMALL ||
|
||||
dZmin > m_Values[0][nPos][nIndex].dMax + EPS_SMALL))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+188
-272
@@ -2062,12 +2062,14 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold
|
||||
CurrentTriangle.SetGrade( 1) ;
|
||||
else
|
||||
CurrentTriangle.SetGrade( 0) ;
|
||||
// Valido il triangolo
|
||||
CurrentTriangle.Validate( true) ;
|
||||
// Setto le normali a ogni vertice
|
||||
CurrentTriangle.SetVertexNorm( 0, CurrentTriangle.GetN()) ;
|
||||
CurrentTriangle.SetVertexNorm( 1, CompoVert[nCompCount - 1][nj].vtNorm) ;
|
||||
CurrentTriangle.SetVertexNorm( 2, CompoVert[nCompCount - 1][ni].vtNorm) ;
|
||||
if ( CurrentTriangle.GetVertexNorm( 1) * CurrentTriangle.GetVertexNorm( 2) > 0)
|
||||
CurrentTriangle.SetVertexNorm( 0, 0.5 * ( CurrentTriangle.GetVertexNorm( 1) +
|
||||
CurrentTriangle.GetVertexNorm( 2))) ;
|
||||
// Valido il triangolo
|
||||
CurrentTriangle.Validate( true) ;
|
||||
// Aggiungo triangolo al vettore temporaneo
|
||||
triContainer.emplace_back( CurrentTriangle) ;
|
||||
}
|
||||
@@ -2155,6 +2157,12 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold
|
||||
CurrentTriangle.SetAttrib( 2, CompoVert[nCompCount - 1][ni].nToolFlag) ;
|
||||
CurrentTriangle.SetVertexNorm( 1, CompoVert[nCompCount - 1][nj].vtNorm) ;
|
||||
CurrentTriangle.SetVertexNorm( 2, CompoVert[nCompCount - 1][ni].vtNorm) ;
|
||||
if ( CurrentTriangle.GetVertexNorm( 1) * CurrentTriangle.GetVertexNorm( 2) > 0)
|
||||
CurrentTriangle.SetVertexNorm( 0, 0.5 * ( CurrentTriangle.GetVertexNorm( 1) +
|
||||
CurrentTriangle.GetVertexNorm( 2))) ;
|
||||
// Valido il triangolo
|
||||
CurrentTriangle.Validate( true) ;
|
||||
// Assegno i colori
|
||||
if ( CurrentTriangle.GetAttrib( 1) < 0 ||
|
||||
CurrentTriangle.GetAttrib( 2) < 0)
|
||||
CurrentTriangle.SetGrade( - 1) ;
|
||||
@@ -2163,7 +2171,6 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold
|
||||
CurrentTriangle.SetGrade( 1) ;
|
||||
else
|
||||
CurrentTriangle.SetGrade( 0) ;
|
||||
CurrentTriangle.Validate( true) ;
|
||||
// Aggiungo triangolo al vettore temporaneo
|
||||
triContainer.emplace_back( CurrentTriangle) ;
|
||||
}
|
||||
@@ -2232,13 +2239,18 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold
|
||||
// Costruisco triangoli di prova
|
||||
for ( int ni = 0 ; ni < nVertComp[nCompCount - 1] ; ++ ni) {
|
||||
int nj = ( ni + 1 < nVertComp[nCompCount - 1]) ? ni + 1 : 0 ;
|
||||
// Il triangolo è pronto
|
||||
// Il triangolo è pronto
|
||||
Triangle3dEx CurrentTriangle ;
|
||||
CurrentTriangle.Set( ptSol, CompoVert[nCompCount - 1][nj].ptInt, CompoVert[nCompCount - 1][ni].ptInt) ;
|
||||
CurrentTriangle.SetAttrib( 1, CompoVert[nCompCount - 1][nj].nToolFlag) ;
|
||||
CurrentTriangle.SetAttrib( 2, CompoVert[nCompCount - 1][ni].nToolFlag) ;
|
||||
CurrentTriangle.SetVertexNorm( 1, CompoVert[nCompCount - 1][nj].vtNorm) ;
|
||||
CurrentTriangle.SetVertexNorm( 2, CompoVert[nCompCount - 1][ni].vtNorm) ;
|
||||
if ( CurrentTriangle.GetVertexNorm( 1) * CurrentTriangle.GetVertexNorm( 2) > 0)
|
||||
CurrentTriangle.SetVertexNorm( 0, 0.5 * ( CurrentTriangle.GetVertexNorm( 1) +
|
||||
CurrentTriangle.GetVertexNorm( 2))) ;
|
||||
CurrentTriangle.Validate( true) ;
|
||||
// Assegno i colori
|
||||
if ( CurrentTriangle.GetAttrib( 1) < 0 ||
|
||||
CurrentTriangle.GetAttrib( 2) < 0)
|
||||
CurrentTriangle.SetGrade( - 1) ;
|
||||
@@ -2247,8 +2259,7 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold
|
||||
CurrentTriangle.SetGrade( 1) ;
|
||||
else
|
||||
CurrentTriangle.SetGrade( 0) ;
|
||||
CurrentTriangle.Validate( true) ;
|
||||
// Aggiungo triangolo al vettore temporaneo
|
||||
// Aggiungo triangolo al vettore temporaneo
|
||||
triContainer.emplace_back( CurrentTriangle) ;
|
||||
}
|
||||
}
|
||||
@@ -2346,11 +2357,16 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold
|
||||
// Aggiungo una componente per il vettore
|
||||
// dei triangoli della componente connessa.
|
||||
triHold[nCurrent].vCompoTria.resize( nNewFeatureNum) ;
|
||||
triHold[nCurrent].vbFlipped.resize( nNewFeatureNum) ;
|
||||
for ( int ni = 0 ; ni < int( vInnerTriaTemp.size()) ; ++ ni) {
|
||||
// Riporto le coordinate nel sistema in cui è immerso lo Zmap
|
||||
vInnerTriaTemp[ni].ToGlob( m_MapFrame) ;
|
||||
triHold[nCurrent].vCompoTria[nOldFeatureNum].emplace_back( vInnerTriaTemp[ni]) ;
|
||||
}
|
||||
triHold[nCurrent].vbFlipped[nOldFeatureNum].resize( vInnerTriaTemp.size()) ;
|
||||
for ( int ni = 0 ; ni < int( vInnerTriaTemp.size()) ; ++ ni) {
|
||||
triHold[nCurrent].vbFlipped[nOldFeatureNum][ni] = false ;
|
||||
}
|
||||
}
|
||||
|
||||
// Triangoli di frontiera
|
||||
@@ -2585,182 +2601,134 @@ VolZmap::FlipEdgesII( TriHolder& TriHold) const
|
||||
{
|
||||
// Numero di voxel in cui si presentano sharp feature
|
||||
int nVoxelNum = int( TriHold.size()) ;
|
||||
|
||||
// Ciclo sui voxel con sharp feature
|
||||
for ( int n1 = 0 ; n1 < nVoxelNum ; ++ n1) {
|
||||
for ( int n2 = n1 ; n2 < nVoxelNum ; ++ n2) {
|
||||
|
||||
// Se i voxel sono adiacenti proseguo
|
||||
if ( abs( TriHold[n2].i - TriHold[n1].i) <= 1 ||
|
||||
abs( TriHold[n2].j - TriHold[n1].j) <= 1 ||
|
||||
abs( TriHold[n2].k - TriHold[n1].k) <= 1 ) {
|
||||
|
||||
// Numero delle componenti connesse nei due voxel
|
||||
int nNumCompo1 = int( TriHold[n1].ptCompoVert.size()) ;
|
||||
int nNumCompo2 = int( TriHold[n2].ptCompoVert.size()) ;
|
||||
|
||||
// Ciclo sulle componenti
|
||||
int nCompo1 = 0 ;
|
||||
for ( ; nCompo1 < nNumCompo1 ; ++ nCompo1) {
|
||||
|
||||
int nCompo2 = ( n1 == n2 ? nCompo1 + 1 : 0) ;
|
||||
for ( ; nCompo2 < nNumCompo2 ; ++ nCompo2) {
|
||||
|
||||
// Numero di triangoli per le componenti connesse
|
||||
int nTriNum1 = int( TriHold[n1].vCompoTria[nCompo1].size()) ;
|
||||
int nTriNum2 = int( TriHold[n2].vCompoTria[nCompo2].size()) ;
|
||||
|
||||
for ( int nTri1 = 0 ; nTri1 < nTriNum1 ; ++ nTri1) {
|
||||
|
||||
bool bModified = false ;
|
||||
|
||||
for ( int nTri2 = 0 ; nTri2 < nTriNum2 ; ++ nTri2) {
|
||||
|
||||
INTVECTOR SharedIndex ;
|
||||
|
||||
for ( int nVert1 = 0 ; nVert1 < 3 ; ++ nVert1) {
|
||||
|
||||
for ( int nVert2 = 0 ; nVert2 < 3 ; ++ nVert2) {
|
||||
|
||||
Point3d ptP1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( nVert1) ;
|
||||
Point3d ptP2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetP( nVert2) ;
|
||||
|
||||
if ( AreSamePointEpsilon( ptP1, ptP2, EPS_ZERO)) {
|
||||
|
||||
Point3d ptVert1 = TriHold[n1].ptCompoVert[nCompo1] ;
|
||||
Point3d ptVert2 = TriHold[n2].ptCompoVert[nCompo2] ;
|
||||
|
||||
if ( ! ( AreSamePointEpsilon( ptP1, ptVert1, EPS_ZERO) ||
|
||||
AreSamePointEpsilon( ptP2, ptVert2, EPS_ZERO))) {
|
||||
SharedIndex.emplace_back( nVert1) ;
|
||||
SharedIndex.emplace_back( nVert2) ;
|
||||
}
|
||||
// Punti che devono essere in comune fra i due triangoli
|
||||
Point3d ptP11 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( 1) ;
|
||||
Point3d ptP12 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( 2) ;
|
||||
Point3d ptP21 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetP( 1) ;
|
||||
Point3d ptP22 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetP( 2) ;
|
||||
// I triangoli sono da flippare
|
||||
if ( AreSamePointEpsilon( ptP11, ptP22, EPS_ZERO) &&
|
||||
AreSamePointEpsilon( ptP12, ptP21, EPS_ZERO)) {
|
||||
// Assegno l'array dei punti di contorno
|
||||
Point3d vPnt[4] ;
|
||||
vPnt[0] = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( 1) ;
|
||||
vPnt[1] = TriHold[n1].ptCompoVert[nCompo1] ;
|
||||
vPnt[2] = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( 2) ;
|
||||
vPnt[3] = TriHold[n2].ptCompoVert[nCompo2] ;
|
||||
// Valuto se i triangoli giacciono su un piano
|
||||
PolygonPlane Polygon ;
|
||||
for ( int i = 0 ; i < 4 ; ++ i)
|
||||
Polygon.AddPoint( vPnt[i]) ;
|
||||
Plane3d plPlane ;
|
||||
bool bOnPlane = Polygon.GetPlane( plPlane) ;
|
||||
for ( int i = 0 ; i < 4 && bOnPlane ; ++ i)
|
||||
bOnPlane = PointInPlaneApprox( vPnt[i], plPlane) ;
|
||||
// Se sono su un piano controllo se avviene inversione
|
||||
bool bInv = false ;
|
||||
if ( bOnPlane) {
|
||||
Triangle3d trT1 = TriHold[n1].vCompoTria[nCompo1][nTri1] ;
|
||||
Triangle3d trT2 = TriHold[n2].vCompoTria[nCompo2][nTri2] ;
|
||||
int nVert1, nVert2 ;
|
||||
// Determino gli indici dei punti sharp-feature
|
||||
for ( int nP = 0 ; nP < 3 ; ++ nP) {
|
||||
if ( nP != 1 && nP != 2)
|
||||
nVert1 = nP ;
|
||||
if ( nP != 2 && nP != 1)
|
||||
nVert2 = nP ;
|
||||
}
|
||||
if ( SharedIndex.size() > 2)
|
||||
break ;
|
||||
trT1.SetP( 1, trT2.GetP( nVert2)) ;
|
||||
trT2.SetP( 1, trT1.GetP( nVert1)) ;
|
||||
trT1.Validate( true) ;
|
||||
trT2.Validate( true) ;
|
||||
bInv = ( trT1.GetN() * trT2.GetN() < 0) ;
|
||||
}
|
||||
if ( SharedIndex.size() > 2)
|
||||
// Se non vi è inversione eseguo il flipping
|
||||
if ( ! bInv) {
|
||||
// Vertice condiviso fra nTri1 e quello del suo fan
|
||||
int nCol1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetAttrib( 2) ;
|
||||
int nCol2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetAttrib( 2) ;
|
||||
// Modifico i punti e gli indici
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].SetP( 1, TriHold[n2].ptCompoVert[nCompo2]) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].SetP( 1, TriHold[n1].ptCompoVert[nCompo1]) ;
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol1) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol2) ;
|
||||
// Setto le normali
|
||||
Vector3d vtN1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetVertexNorm( 2) ;
|
||||
Vector3d vtN2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetVertexNorm( 2) ;
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].SetVertexNorm( 0, vtN1) ;
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].SetVertexNorm( 1, vtN1) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].SetVertexNorm( 0, vtN2) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].SetVertexNorm( 1, vtN2) ;
|
||||
// Valido i triangoli
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].Validate( true) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].Validate( true) ;
|
||||
// Avvenuto flipping
|
||||
bModified = true ;
|
||||
break ;
|
||||
}
|
||||
|
||||
// Si deve operare la modifica dei triangoli
|
||||
if ( SharedIndex.size() > 2) {
|
||||
|
||||
// Verifico che i due lati adiacenti siano controversi
|
||||
int nProd = ( SharedIndex[2] - SharedIndex[0]) * ( SharedIndex[3] - SharedIndex[1]) ;
|
||||
if ( nProd != 1 && nProd != - 2 && nProd != 4 && nProd != 0) {
|
||||
// Assegno l'array dei punti di contorno
|
||||
Point3d vPnt[4] ;
|
||||
vPnt[0] = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( SharedIndex[0]) ;
|
||||
vPnt[1] = TriHold[n1].ptCompoVert[nCompo1] ;
|
||||
vPnt[2] = TriHold[n1].vCompoTria[nCompo1][nTri1].GetP( SharedIndex[2]) ;
|
||||
vPnt[3] = TriHold[n2].ptCompoVert[nCompo2] ;
|
||||
// Valuto se i triangoli giacciono su un piano
|
||||
PolygonPlane Polygon ;
|
||||
for ( int i = 0 ; i < 4 ; ++ i)
|
||||
Polygon.AddPoint( vPnt[i]) ;
|
||||
Plane3d plPlane ;
|
||||
bool bOnPlane = Polygon.GetPlane( plPlane) ;
|
||||
for ( int i = 0 ; i < 4 && bOnPlane ; ++ i)
|
||||
bOnPlane = PointInPlaneApprox( vPnt[i], plPlane) ;
|
||||
// Se sono su un piano controllo se avviene inversione
|
||||
bool bInv = false ;
|
||||
if ( bOnPlane) {
|
||||
Triangle3d trT1 = TriHold[n1].vCompoTria[nCompo1][nTri1] ;
|
||||
Triangle3d trT2 = TriHold[n2].vCompoTria[nCompo2][nTri2] ;
|
||||
int nVert1, nVert2 ;
|
||||
// Determino gli indici dei punti sharp-feature
|
||||
for ( int nP = 0 ; nP < 3 ; ++ nP) {
|
||||
if ( nP != SharedIndex[0] && nP != SharedIndex[2])
|
||||
nVert1 = nP ;
|
||||
if ( nP != SharedIndex[1] && nP != SharedIndex[3])
|
||||
nVert2 = nP ;
|
||||
}
|
||||
trT1.SetP( SharedIndex[0], trT2.GetP( nVert2)) ;
|
||||
trT2.SetP( SharedIndex[3], trT1.GetP( nVert1)) ;
|
||||
trT1.Validate( true) ;
|
||||
trT2.Validate( true) ;
|
||||
bInv = ( trT1.GetN() * trT2.GetN() < 0) ;
|
||||
}
|
||||
else {
|
||||
// In questo caso i due triangoli sono necessariamente su un piano,
|
||||
// quindi hanno normali concordi. Per ognuno dei due cerco nei rispettivi
|
||||
// ventagli un triangolo con normale concorde con colore definito. Assegno
|
||||
// tale colore ai triangoli.
|
||||
int nPrv1 = ( nTri1 != 0 ? nTri1 : int( TriHold[n1].vCompoTria[nCompo1].size())) - 1 ;
|
||||
int nNxt1 = ( nTri1 != TriHold[n1].vCompoTria[nCompo1].size() - 1 ? nTri1 + 1 : 0) ;
|
||||
int nPrv2 = ( nTri2 != 0 ? nTri2 : int( TriHold[n2].vCompoTria[nCompo2].size())) - 1 ;
|
||||
int nNxt2 = ( nTri2 != TriHold[n2].vCompoTria[nCompo2].size() - 1 ? nTri2 + 1 : 0) ;
|
||||
// Prodotti scalari del primo triangolo con i suoi adiacenti
|
||||
double dDotP1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetN() *
|
||||
TriHold[n1].vCompoTria[nCompo1][nPrv1].GetN() ;
|
||||
double dDotN1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetN() *
|
||||
TriHold[n1].vCompoTria[nCompo1][nNxt1].GetN() ;
|
||||
// Prendo il maggiore fra i due, e comunque maggiore di 0.5
|
||||
int nAdjT1 = - 1 ;
|
||||
if ( dDotP1 > 0.5 || dDotN1 > 0.5)
|
||||
nAdjT1 = ( dDotP1 > dDotN1 ? nPrv1 : nNxt1) ;
|
||||
// Prodotti scalari del primo triangolo con i suoi adiacenti
|
||||
double dDotP2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetN() *
|
||||
TriHold[n2].vCompoTria[nCompo2][nPrv2].GetN() ;
|
||||
double dDotN2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetN() *
|
||||
TriHold[n2].vCompoTria[nCompo2][nNxt2].GetN() ;
|
||||
// Prendo il maggiore fra i due, e comunque maggiore di 0.5
|
||||
int nAdjT2 = - 1 ;
|
||||
if ( dDotP2 > 0.5 || dDotN2 > 0.5)
|
||||
nAdjT2 = ( dDotP2 > dDotN2 ? nPrv2 : nNxt2) ;
|
||||
// Se abbiamo trovato triangoli adiacenti validi
|
||||
// assegnamo il colorea quelli correnti.
|
||||
if ( nAdjT1 != - 1) {
|
||||
int nCol = TriHold[n1].vCompoTria[nCompo1][nAdjT1].GetGrade() ;
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol) ;
|
||||
}
|
||||
// Se non vi è inversione eseguo il flipping
|
||||
if ( ! bInv) {
|
||||
// Vertice condiviso fra nTri1 e quello del suo fan
|
||||
int nCol1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetAttrib( SharedIndex[2]) ;
|
||||
int nCol2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetAttrib( SharedIndex[1]) ;
|
||||
// Modifico i punti e gli indici
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].SetP( SharedIndex[0],
|
||||
TriHold[n2].ptCompoVert[nCompo2]) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].SetP( SharedIndex[3],
|
||||
TriHold[n1].ptCompoVert[nCompo1]) ;
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol1) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol2) ;
|
||||
// Valido i triangoli
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].Validate( true) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].Validate( true) ;
|
||||
// Setto le normali a ogni vertice
|
||||
Vector3d vtNorm1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetVertexNorm( SharedIndex[2]) ;
|
||||
Vector3d vtNorm2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetVertexNorm( SharedIndex[1]) ;
|
||||
|
||||
int nFeatureIndex1 = 0 ;
|
||||
int nFeatureIndex2 = 0 ;
|
||||
for ( ; nFeatureIndex1 < 3 && nFeatureIndex2 < 3 ; ) {
|
||||
if ( ! ( nFeatureIndex1 != SharedIndex[0] &&
|
||||
nFeatureIndex1 != SharedIndex[2]))
|
||||
++ nFeatureIndex1 ;
|
||||
else if ( ! ( nFeatureIndex2 != SharedIndex[1] &&
|
||||
nFeatureIndex2 != SharedIndex[3]))
|
||||
++ nFeatureIndex2 ;
|
||||
else
|
||||
break ;
|
||||
}
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].SetVertexNorm( SharedIndex[0], vtNorm1) ;
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].SetVertexNorm( nFeatureIndex1, vtNorm1) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].SetVertexNorm( SharedIndex[3], vtNorm2) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].SetVertexNorm( nFeatureIndex2, vtNorm2) ;
|
||||
|
||||
bModified = true ;
|
||||
break ;
|
||||
}
|
||||
else {
|
||||
// In questo caso i due triangoli sono necessariamente su un piano,
|
||||
// quindi hanno normali concordi. Per ognuno dei due cerco nei rispettivi
|
||||
// ventagli un triangolo con normale concorde con colore definito. Assegno
|
||||
// tale colore ai triangoli.
|
||||
int nPrv1 = ( nTri1 != 0 ? nTri1 : int( TriHold[n1].vCompoTria[nCompo1].size())) - 1 ;
|
||||
int nNxt1 = ( nTri1 != TriHold[n1].vCompoTria[nCompo1].size() - 1 ? nTri1 + 1 : 0) ;
|
||||
int nPrv2 = ( nTri2 != 0 ? nTri2 : int( TriHold[n2].vCompoTria[nCompo2].size())) - 1 ;
|
||||
int nNxt2 = ( nTri2 != TriHold[n2].vCompoTria[nCompo2].size() - 1 ? nTri2 + 1 : 0) ;
|
||||
|
||||
double dDotP1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetN() *
|
||||
TriHold[n1].vCompoTria[nCompo1][nPrv1].GetN() ;
|
||||
double dDotN1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetN() *
|
||||
TriHold[n1].vCompoTria[nCompo1][nNxt1].GetN() ;
|
||||
int nAdjT1 = - 1 ;
|
||||
if ( dDotP1 > 0.5 || dDotN1 > 0.5)
|
||||
nAdjT1 = ( dDotP1 > dDotN1 ? nPrv1 : nNxt1) ;
|
||||
|
||||
double dDotP2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetN() *
|
||||
TriHold[n2].vCompoTria[nCompo2][nPrv2].GetN() ;
|
||||
double dDotN2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetN() *
|
||||
TriHold[n2].vCompoTria[nCompo2][nNxt2].GetN() ;
|
||||
int nAdjT2 = - 1 ;
|
||||
if ( dDotP2 > 0.5 || dDotN2 > 0.5)
|
||||
nAdjT2 = ( dDotP2 > dDotN2 ? nPrv2 : nNxt2) ;
|
||||
|
||||
if ( nAdjT1 != - 1) {
|
||||
int nCol = TriHold[n1].vCompoTria[nCompo1][nAdjT1].GetGrade() ;
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol) ;
|
||||
}
|
||||
else if ( nAdjT2 != - 1) {
|
||||
int nCol = TriHold[n2].vCompoTria[nCompo2][nAdjT2].GetGrade() ;
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( nAdjT2 != - 1) {
|
||||
int nCol = TriHold[n2].vCompoTria[nCompo2][nAdjT2].GetGrade() ;
|
||||
TriHold[n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol) ;
|
||||
TriHold[n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( bModified)
|
||||
break ;
|
||||
}
|
||||
@@ -2778,28 +2746,21 @@ VolZmap::FlipEdgesBB( TriaMatrix& InterTria) const
|
||||
{
|
||||
// Numero di blocchi
|
||||
size_t nBlocksNum = InterTria.size() ;
|
||||
|
||||
// ciclo sui blocchi
|
||||
for ( size_t tFB = 0 ; tFB < nBlocksNum ; ++ tFB) {
|
||||
|
||||
int nFBijk[3] ;
|
||||
GetBlockIJKFromN( int( tFB), nFBijk) ;
|
||||
|
||||
for ( size_t tLB = tFB ; tLB < nBlocksNum ; ++ tLB) {
|
||||
|
||||
int nLBijk[3] ;
|
||||
GetBlockIJKFromN( int( tLB), nLBijk) ;
|
||||
|
||||
// Se i blocchi non sono adiacenti salto l'iterazione
|
||||
if ( ! ( abs( nFBijk[0] - nLBijk[0]) <= 1 &&
|
||||
abs( nFBijk[1] - nLBijk[1]) <= 1 &&
|
||||
abs( nFBijk[2] - nLBijk[2]) <= 1))
|
||||
continue ;
|
||||
|
||||
// Numero di voxel nei blocchi correnti
|
||||
size_t nVoxelNumFB = InterTria[tFB].size() ;
|
||||
size_t nVoxelNumLB = InterTria[tLB].size() ;
|
||||
|
||||
// Ciclo sui voxel dei due blocchi
|
||||
for ( size_t tVFB = 0 ; tVFB < nVoxelNumFB ; ++ tVFB) {
|
||||
for ( size_t tVLB = 0 ; tVLB < nVoxelNumLB ; ++ tVLB) {
|
||||
@@ -2817,118 +2778,73 @@ VolZmap::FlipEdgesBB( TriaMatrix& InterTria) const
|
||||
// Numero di triangoli delle componenti connesse
|
||||
size_t nTriFBNum = InterTria[tFB][tVFB].vCompoTria[tCmpF].size() ;
|
||||
size_t nTriLBNum = InterTria[tLB][tVLB].vCompoTria[tCmpL].size() ;
|
||||
|
||||
// Ciclo sui triangoli
|
||||
for ( size_t tTriFB = 0 ; tTriFB < nTriFBNum ; ++ tTriFB) {
|
||||
|
||||
bool bModified = false ;
|
||||
|
||||
for ( size_t tTriLB = 0 ; tTriLB < nTriLBNum ; ++ tTriLB) {
|
||||
|
||||
INTVECTOR SharedIndex ;
|
||||
|
||||
for ( int nVertF = 0 ; nVertF < 3 ; ++ nVertF) {
|
||||
for ( int nVertL = 0 ; nVertL < 3 ; ++ nVertL) {
|
||||
|
||||
Point3d ptPF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( nVertF) ;
|
||||
Point3d ptPL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( nVertL) ;
|
||||
|
||||
if ( AreSamePointEpsilon( ptPF, ptPL, EPS_ZERO)) {
|
||||
|
||||
Point3d ptVertF = InterTria[tFB][tVFB].ptCompoVert[tCmpF] ;
|
||||
Point3d ptVertL = InterTria[tLB][tVLB].ptCompoVert[tCmpL] ;
|
||||
|
||||
if ( ! ( AreSamePointEpsilon( ptPF, ptVertF, EPS_ZERO) ||
|
||||
AreSamePointEpsilon( ptPL, ptVertL, EPS_ZERO))) {
|
||||
|
||||
SharedIndex.emplace_back( nVertF) ;
|
||||
SharedIndex.emplace_back( nVertL) ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( SharedIndex.size() > 2)
|
||||
break ;
|
||||
}
|
||||
|
||||
if ( SharedIndex.size() > 2)
|
||||
break ;
|
||||
}
|
||||
|
||||
// Punti che devono essere in comune fra i due triangoli
|
||||
Point3d ptPF1 = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 1) ;
|
||||
Point3d ptPF2 = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 2) ;
|
||||
Point3d ptPL1 = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 1) ;
|
||||
Point3d ptPL2 = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 2) ;
|
||||
// Si deve operare la modifica dei triangoli
|
||||
if ( SharedIndex.size() > 2) {
|
||||
// Verifico che i due lati adiacenti siano controversi
|
||||
int nProd = ( SharedIndex[2] - SharedIndex[0]) * ( SharedIndex[3] - SharedIndex[1]) ;
|
||||
if ( nProd != 1 && nProd != - 2 && nProd != 4 && nProd != 0) {
|
||||
// Assegno l'array dei punti di contorno
|
||||
Point3d vPnt[4] ;
|
||||
vPnt[0] = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( SharedIndex[0]) ;
|
||||
vPnt[1] = InterTria[tFB][tVFB].ptCompoVert[tCmpF] ;
|
||||
vPnt[2] = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( SharedIndex[2]) ;
|
||||
vPnt[3] = InterTria[tLB][tVLB].ptCompoVert[tCmpL] ;
|
||||
// Valuto se i triangoli giacciono su un piano
|
||||
PolygonPlane Polygon ;
|
||||
for ( int i = 0 ; i < 4 ; ++ i)
|
||||
Polygon.AddPoint( vPnt[i]) ;
|
||||
Plane3d plPlane ;
|
||||
bool bOnPlane = Polygon.GetPlane( plPlane) ;
|
||||
for ( int i = 0 ; i < 4 && bOnPlane ; ++ i)
|
||||
bOnPlane = PointInPlaneApprox( vPnt[i], plPlane) ;
|
||||
// Se sono su un piano controllo se avviene inversione
|
||||
bool bInv = false ;
|
||||
if ( bOnPlane) {
|
||||
Triangle3dEx trTF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB] ;
|
||||
Triangle3dEx trTL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB] ;
|
||||
int nVertF, nVertL ;
|
||||
// Determino gli indici dei punti sharp-feature
|
||||
for ( int nP = 0 ; nP < 3 ; ++ nP) {
|
||||
if ( nP != SharedIndex[0] && nP != SharedIndex[2])
|
||||
nVertF = nP ;
|
||||
if ( nP != SharedIndex[1] && nP != SharedIndex[3])
|
||||
nVertL = nP ;
|
||||
}
|
||||
trTF.SetP( SharedIndex[0], trTL.GetP( nVertL)) ;
|
||||
trTF.Validate( true) ;
|
||||
trTL.SetP( SharedIndex[3], trTF.GetP( nVertF)) ;
|
||||
trTL.Validate( true) ;
|
||||
bInv = ( trTF.GetN() * trTL.GetN() < 0) ;
|
||||
}
|
||||
// Se non vi è inversione eseguo il flipping
|
||||
if ( ! bInv) {
|
||||
// Vertice condiviso fra nTri1 e quello del suo fan
|
||||
int nColF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetAttrib( SharedIndex[2]) ;
|
||||
int nColL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetAttrib( SharedIndex[1]) ;
|
||||
// modifico punti e colori
|
||||
InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetP( SharedIndex[0],
|
||||
InterTria[tLB][tVLB].ptCompoVert[tCmpL]) ;
|
||||
InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetP( SharedIndex[3],
|
||||
InterTria[tFB][tVFB].ptCompoVert[tCmpF]) ;
|
||||
InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetGrade( nColF) ;
|
||||
InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetGrade( nColL) ;
|
||||
// Valido i triangoli
|
||||
InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].Validate( true) ;
|
||||
InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].Validate( true) ;
|
||||
|
||||
// Setto le normali a ogni vertice
|
||||
Vector3d vtNormF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetVertexNorm( SharedIndex[2]) ;
|
||||
Vector3d vtNormL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetVertexNorm( SharedIndex[1]) ;
|
||||
int nFeatureIndexF = 0 ;
|
||||
int nFeatureIndexL = 0 ;
|
||||
for ( ; nFeatureIndexF < 3 && nFeatureIndexL < 3 ; ) {
|
||||
if ( ! ( nFeatureIndexF != SharedIndex[0] &&
|
||||
nFeatureIndexF != SharedIndex[2]))
|
||||
++ nFeatureIndexF ;
|
||||
else if ( ! ( nFeatureIndexL != SharedIndex[1] &&
|
||||
nFeatureIndexL != SharedIndex[3]))
|
||||
++ nFeatureIndexL ;
|
||||
else
|
||||
break ;
|
||||
}
|
||||
InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetVertexNorm( SharedIndex[0], vtNormF) ;
|
||||
InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetVertexNorm( nFeatureIndexF, vtNormF) ;
|
||||
InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( SharedIndex[3], vtNormL) ;
|
||||
InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( nFeatureIndexL, vtNormL) ;
|
||||
bModified = true ;
|
||||
break ;
|
||||
if ( AreSamePointEpsilon( ptPF1, ptPL2, EPS_ZERO) &&
|
||||
AreSamePointEpsilon( ptPF2, ptPL1, EPS_ZERO)) {
|
||||
// Assegno l'array dei punti di contorno
|
||||
Point3d vPnt[4] ;
|
||||
vPnt[0] = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 1) ;
|
||||
vPnt[1] = InterTria[tFB][tVFB].ptCompoVert[tCmpF] ;
|
||||
vPnt[2] = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 2) ;
|
||||
vPnt[3] = InterTria[tLB][tVLB].ptCompoVert[tCmpL] ;
|
||||
// Valuto se i triangoli giacciono su un piano
|
||||
PolygonPlane Polygon ;
|
||||
for ( int i = 0 ; i < 4 ; ++ i)
|
||||
Polygon.AddPoint( vPnt[i]) ;
|
||||
Plane3d plPlane ;
|
||||
bool bOnPlane = Polygon.GetPlane( plPlane) ;
|
||||
for ( int i = 0 ; i < 4 && bOnPlane ; ++ i)
|
||||
bOnPlane = PointInPlaneApprox( vPnt[i], plPlane) ;
|
||||
// Se sono su un piano controllo se avviene inversione
|
||||
bool bInv = false ;
|
||||
if ( bOnPlane) {
|
||||
Triangle3dEx trTF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB] ;
|
||||
Triangle3dEx trTL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB] ;
|
||||
int nVertF, nVertL ;
|
||||
// Determino gli indici dei punti sharp-feature
|
||||
for ( int nP = 0 ; nP < 3 ; ++ nP) {
|
||||
if ( nP != 1 && nP != 2)
|
||||
nVertF = nP ;
|
||||
if ( nP != 2 && nP != 1)
|
||||
nVertL = nP ;
|
||||
}
|
||||
trTF.SetP( 1, trTL.GetP( nVertL)) ;
|
||||
trTF.Validate( true) ;
|
||||
trTL.SetP( 1, trTF.GetP( nVertF)) ;
|
||||
trTL.Validate( true) ;
|
||||
bInv = ( trTF.GetN() * trTL.GetN() < 0) ;
|
||||
}
|
||||
// Se non vi è inversione eseguo il flipping
|
||||
if ( ! bInv) {
|
||||
// Vertice condiviso fra nTri1 e quello del suo fan
|
||||
int nColF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetAttrib( 2) ;
|
||||
int nColL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetAttrib( 2) ;
|
||||
// modifico punti e colori
|
||||
InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetP( 1, InterTria[tLB][tVLB].ptCompoVert[tCmpL]) ;
|
||||
InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetP( 1, InterTria[tFB][tVFB].ptCompoVert[tCmpF]) ;
|
||||
InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetGrade( nColF) ;
|
||||
InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetGrade( nColL) ;
|
||||
// Valido i triangoli
|
||||
InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].Validate( true) ;
|
||||
InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].Validate( true) ;
|
||||
// Setto le normali a ogni vertice
|
||||
Vector3d vtNormF = InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetVertexNorm( 2) ;
|
||||
Vector3d vtNormL = InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetVertexNorm( 2) ;
|
||||
InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetVertexNorm( 1, vtNormF) ;
|
||||
InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetVertexNorm( 0, vtNormF) ;
|
||||
InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( 1, vtNormL) ;
|
||||
InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( 0, vtNormL) ;
|
||||
bModified = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user