EgtGeomKernel 2.2b3 :
- correzioni per triangoli che scompaiono in booleane di trimesh.
This commit is contained in:
+168
-37
@@ -745,7 +745,8 @@ SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMA
|
||||
PNTVECTOR Loop1, Loop2 ;
|
||||
bool bChangedStart = ChangeStart( ptOpenLoopStP, cvBoundClosedLoopVec[nLoop]) ;
|
||||
bool bSplitted = SplitAtPoint( ptOpenLoopEnP, cvBoundClosedLoopVec[nLoop], Loop1, Loop2) ;
|
||||
if ( ! ( bChangedStart && bSplitted))
|
||||
if ( ! ( bChangedStart && bSplitted) ||
|
||||
( nLastOpenLoopPoint == 0 && ( Loop1.size() == 2 || Loop2.size() == 2)))
|
||||
continue ;
|
||||
bLoopSplitted = true ;
|
||||
Chain cvCounterChain ;
|
||||
@@ -1083,8 +1084,61 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
BOOLVECTOR vbInOut ;
|
||||
vbInOut.push_back( true) ;
|
||||
// Divido il loop usando le catene
|
||||
if ( ! DecomposeLoop( cvOpenChain, vnDegVec, cvBoundClosedLoopVec, vbInOut))
|
||||
continue ;
|
||||
if ( ! DecomposeLoop( cvOpenChain, vnDegVec, cvBoundClosedLoopVec, vbInOut)) {
|
||||
if ( int( cvBoundClosedLoopVec.size()) == 1 && int( cvOpenChain.size()) == 2) {
|
||||
Point3d ptLink0St = cvOpenChain[0][0].ptSt ;
|
||||
Point3d ptLink0En = cvOpenChain[0].back().ptEn ;
|
||||
Point3d ptLink1St = cvOpenChain.back()[0].ptSt ;
|
||||
Point3d ptLink1En = cvOpenChain.back().back().ptEn ;
|
||||
double dDist01 = sqrt( ( ptLink0En - ptLink1St) * ( ptLink0En - ptLink1St)) ;
|
||||
double dDist10 = sqrt( ( ptLink1En - ptLink0St) * ( ptLink1En - ptLink0St)) ;
|
||||
if ( dDist01 < 2 * EPS_SMALL) {
|
||||
IntSegment LinkingSeg ;
|
||||
LinkingSeg.ptSt = ptLink0En ;
|
||||
LinkingSeg.ptEn = ptLink1St ;
|
||||
LinkingSeg.vtOuter = cvOpenChain[0].back().vtOuter ;
|
||||
LinkingSeg.bDegenerate = false ;
|
||||
cvOpenChain[0].emplace_back( LinkingSeg) ;
|
||||
for ( int nLinkI = 0 ; nLinkI < int( cvOpenChain.back().size()) ; ++ nLinkI) {
|
||||
cvOpenChain[0].emplace_back( cvOpenChain.back()[nLinkI]) ;
|
||||
}
|
||||
cvOpenChain.resize( 1) ;
|
||||
int nComplDeg = vnDegVec[0] * vnDegVec[1] ;
|
||||
vnDegVec[0] = nComplDeg ;
|
||||
vnDegVec.resize( 1) ;
|
||||
}
|
||||
else if ( dDist10 < 2 * EPS_SMALL) {
|
||||
IntSegment LinkingSeg ;
|
||||
LinkingSeg.ptSt = cvOpenChain.back().back().ptEn ;
|
||||
LinkingSeg.ptEn = cvOpenChain[0].back().ptSt ;
|
||||
LinkingSeg.vtOuter = cvOpenChain.back().back().vtOuter ;
|
||||
LinkingSeg.bDegenerate = false ;
|
||||
cvOpenChain.back().emplace_back( LinkingSeg) ;
|
||||
for ( int nLinkI = 0 ; nLinkI < int( cvOpenChain[0].size()) ; ++ nLinkI) {
|
||||
cvOpenChain.back().emplace_back( cvOpenChain[0][nLinkI]) ;
|
||||
}
|
||||
cvOpenChain.erase( cvOpenChain.begin()) ;
|
||||
int nComplDeg = vnDegVec[0] * vnDegVec[1] ;
|
||||
vnDegVec[0] = nComplDeg ;
|
||||
vnDegVec.resize( 1) ;
|
||||
}
|
||||
else {
|
||||
Surf.m_vTria[it->first].nTempPart = 0 ;
|
||||
continue ;
|
||||
}
|
||||
vbInOut.resize( 1) ;
|
||||
vbInOut[0] = true ;
|
||||
if ( ! DecomposeLoop( cvOpenChain, vnDegVec, cvBoundClosedLoopVec, vbInOut)) {
|
||||
Surf.m_vTria[it->first].nTempPart = 0 ;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Surf.m_vTria[it->first].nTempPart = 0 ;
|
||||
/*Surf.m_vTria[it->first].nTempPart *= 10 ;*/
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
// Rimuovo il triangolo corrente
|
||||
Surf.RemoveTriangle( it->first) ;
|
||||
// Trasformo i loop compositi in loop polyline
|
||||
@@ -1203,8 +1257,16 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
vInnerLoop.emplace_back( nCLI) ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( vInnerLoop.size() == 0) {
|
||||
// Elimino loop interni non validi
|
||||
bool bDouble = true ;
|
||||
for ( int nInnLoop = 0 ; nInnLoop < int( vInnerLoop.size()) ; ++ nInnLoop) {
|
||||
if ( int( cvClosedChain[vInnerLoop[nInnLoop]].size()) > 2) {
|
||||
bDouble = false ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( vInnerLoop.size() == 0 || bDouble) {
|
||||
// Eseguo triangolazione
|
||||
PNTVECTOR vPt ;
|
||||
INTVECTOR vTr ;
|
||||
@@ -1297,33 +1359,101 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf)
|
||||
{
|
||||
for ( auto it = Ambiguos.begin() ; it != Ambiguos.end() ; ++ it) {
|
||||
Triangle3d trTria ;
|
||||
Surf.GetTriangle( it->first, trTria) ;
|
||||
trTria.Validate() ;
|
||||
Point3d ptBar = ( trTria.GetP( 0) + trTria.GetP( 1) + trTria.GetP( 2)) / 3 ;
|
||||
double dMinDist = DBL_MAX ;
|
||||
int nTriaIndex = - 1 ;
|
||||
for ( int nOthSurfT = 0 ; nOthSurfT < int( it->second.size()) ; ++ nOthSurfT) {
|
||||
Triangle3d trOthSurfTria = it->second[nOthSurfT] ;
|
||||
double dDot = ( ptBar - trOthSurfTria.GetP( 0)) * trOthSurfTria.GetN() ;
|
||||
if ( abs( dDot) > EPS_SMALL) {
|
||||
double dDist ;
|
||||
if ( DistPointTriangle( ptBar, trOthSurfTria).GetDist( dDist) && dDist < dMinDist) {
|
||||
nTriaIndex = nOthSurfT ;
|
||||
dMinDist = dDist ;
|
||||
FindTriaIncidence( const Triangle3d& trTria, const TRIA3DVECTOR& vOthTriaVec, INTMATRIX& vAdjSegToCurTria)
|
||||
{
|
||||
int nNumFoundContact = 0 ;
|
||||
vAdjSegToCurTria.resize( 3) ;
|
||||
for ( int nEdge = 0 ; nEdge < 3 ; ++ nEdge) {
|
||||
for ( int nOther = 0 ; nOther < int( vOthTriaVec.size()) ; ++ nOther) {
|
||||
Triangle3d trOthTria = vOthTriaVec[nOther] ;
|
||||
Point3d ptSt = trTria.GetP( nEdge) ;
|
||||
Point3d ptEn = trTria.GetP( ( nEdge + 1) % 3) ;
|
||||
CurveLine cvEdgeLine ;
|
||||
cvEdgeLine.Set( ptSt, ptEn) ;
|
||||
for ( int nOthEdge = 0 ; nOthEdge < 3 ; ++ nOthEdge) {
|
||||
Point3d ptOthSt = trOthTria.GetP( nOthEdge) ;
|
||||
Point3d ptOthEn = trOthTria.GetP( ( nOthEdge + 1) % 3) ;
|
||||
CurveLine cvOthEdgeLine ;
|
||||
cvOthEdgeLine.Set( ptOthSt, ptOthEn) ;
|
||||
DistPointLine DistCalculatorCurOth( 0.5 * ( ptSt + ptEn), cvOthEdgeLine, false) ;
|
||||
double dSqDistCurOth ;
|
||||
DistCalculatorCurOth.GetSqDist( dSqDistCurOth) ;
|
||||
DistPointLine DistCalculatorOthCur( 0.5 * ( ptOthSt + ptOthEn), cvEdgeLine, false) ;
|
||||
double dSqDistOthCur ;
|
||||
DistCalculatorOthCur.GetSqDist( dSqDistOthCur) ;
|
||||
if ( dSqDistCurOth < EPS_SMALL * EPS_SMALL && dSqDistOthCur < EPS_SMALL * EPS_SMALL) {
|
||||
vAdjSegToCurTria[nEdge].emplace_back( nOther) ;
|
||||
++ nNumFoundContact ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( nTriaIndex != -1) {
|
||||
Triangle3d trOthSurfTria = it->second[nTriaIndex] ;
|
||||
trOthSurfTria.Validate() ;
|
||||
double dDot = ( ptBar - trOthSurfTria.GetP( 0)) * trOthSurfTria.GetN() ;
|
||||
Surf.m_vTria[it->first].nTempPart = ( dDot < 0 ? 1 : -1) ;
|
||||
}
|
||||
if (nNumFoundContact != int(vOthTriaVec.size()))
|
||||
int dudu = 0 ;
|
||||
return ( nNumFoundContact == int( vOthTriaVec.size())) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf)
|
||||
{
|
||||
for ( auto it = Ambiguos.begin() ; it != Ambiguos.end() ; ++ it) {
|
||||
// Se il triangolo ha l'indice diverso da zero vuol dire che oltre a un
|
||||
// contatto edge-edge ha avuto dei contatti che lo hanno già classificato.
|
||||
if ( Surf.m_vTria[it->first].nTempPart != 0)
|
||||
continue ;
|
||||
// Recupero il triangolo corrente
|
||||
Triangle3d trTria ;
|
||||
Surf.GetTriangle( it->first, trTria) ;
|
||||
trTria.Validate() ;
|
||||
// Vettore dei triangoli i cui edge incidono su quelli del triangolo corrente
|
||||
TRIA3DVECTOR& vOthTriaVec = it->second ;
|
||||
// Vettore degli indici dei segmenti del triangolo adiacenti agli altri triangoli
|
||||
INTMATRIX vAdjSegToCurTria ;
|
||||
if ( ! FindTriaIncidence( trTria, vOthTriaVec, vAdjSegToCurTria))
|
||||
return false ;
|
||||
// Classifico il triangolo in base ai triangoli che incidono sui suoi edge
|
||||
int nTriaClassificationByEdges[3] = { 0, 0, 0 } ;
|
||||
for ( int nEdge = 0 ; nEdge < 3 ; ++ nEdge) {
|
||||
if ( int( vAdjSegToCurTria[nEdge].size()) == 0)
|
||||
continue ;
|
||||
// Calcolo la normale media ai triangoli che incidono sull'edge corrente
|
||||
Vector3d vtAvVec ;
|
||||
for ( int nTr = 0 ; nTr < int( vAdjSegToCurTria[nEdge].size()) ; ++ nTr) {
|
||||
vtAvVec += vOthTriaVec[vAdjSegToCurTria[nEdge][nTr]].GetN() ;
|
||||
}
|
||||
// Calcolo il vettore ortogonale all'edge corrente che punta al baricentro del triangolo corrente
|
||||
Point3d ptBar = ( trTria.GetP(0) + trTria.GetP(1) + trTria.GetP(2)) / 3. ;
|
||||
Vector3d vtBarVec = ptBar - trTria.GetP( nEdge) ;
|
||||
Vector3d vtEdgeDir = trTria.GetP( ( nEdge + 1) % 3) - trTria.GetP( nEdge) ;
|
||||
vtEdgeDir.Normalize() ;
|
||||
vtBarVec -= ( vtBarVec * vtEdgeDir) * vtEdgeDir ;
|
||||
// Se entrambi i vettori sono definiti classifico il triangolo in modo opportuno
|
||||
if ( vtBarVec.Normalize( 0.01 * EPS_SMALL) && vtAvVec.Normalize( 0.01 * EPS_SMALL)) {
|
||||
if ( vtBarVec * vtAvVec < - EPS_ZERO) {
|
||||
nTriaClassificationByEdges[nEdge] = 1 ;
|
||||
}
|
||||
else if ( vtBarVec * vtAvVec > EPS_ZERO) {
|
||||
nTriaClassificationByEdges[nEdge] = -1 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Verifico che le classificazioni siano coerenti
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
if ( nTriaClassificationByEdges[i] == 0)
|
||||
continue ;
|
||||
Surf.m_vTria[it->first].nTempPart = nTriaClassificationByEdges[i] ;
|
||||
int j ;
|
||||
for ( j = i + 1 ; j < 3 ; ++ j) {
|
||||
if ( nTriaClassificationByEdges[j] != 0 && nTriaClassificationByEdges[i] != nTriaClassificationByEdges[j]) {
|
||||
Surf.m_vTria[it->first].nTempPart = 0 ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( j < 3)
|
||||
break ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -2080,15 +2210,16 @@ SurfTriMesh::GetSurfClassification( const ISurfTriMesh& ClassifierSurf,
|
||||
}
|
||||
|
||||
///////////////////////// DEBUG /////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//if ( ( AreSamePointApprox(trTriaA.GetP(0), Point3d(0.6312, 42.0801, 100)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(1), Point3d(0.3554, 44.0491, 100)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(2), Point3d(0.6312, 42.0801, 0))) ||
|
||||
// ( AreSamePointApprox(trTriaA.GetP(2), Point3d(0.6312, 42.0801, 100)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(0), Point3d(0.3554, 44.0491, 100)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(1), Point3d(0.6312, 42.0801, 0))) ||
|
||||
// ( AreSamePointApprox(trTriaA.GetP(1), Point3d(0.6312, 42.0801, 100)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(2), Point3d(0.3554, 44.0491, 100)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(0), Point3d(0.6312, 42.0801, 0)))) {
|
||||
//if ( nTriaNumB == 76 &&
|
||||
// ( AreSamePointApprox(trTriaA.GetP(0), Point3d( 920.5333, 0.0000, 190.5)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(1), Point3d( 1150.6666, 0.0000, 190.5)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(2), Point3d( 920.5333, 245.89, 190.5))) ||
|
||||
// ( AreSamePointApprox(trTriaA.GetP(2), Point3d( 920.5333, 0.0000, 190.5)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(0), Point3d( 1150.6666, 0.0000, 190.5)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(1), Point3d( 920.5333, 245.89, 190.5))) ||
|
||||
// ( AreSamePointApprox(trTriaA.GetP(1), Point3d( 920.5333, 0.0000, 190.5)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(2), Point3d( 1150.6666, 0.0000, 190.5)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(0), Point3d( 920.5333, 245.89, 190.5)))) {
|
||||
// int a = 0 ;
|
||||
//}
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user