EgtExecutor 2.1i1 :

- migliorie a intersezioni tra trimesh.
This commit is contained in:
Dario Sassi
2019-09-12 07:42:17 +00:00
parent 1917a21a7c
commit f5f45b0794
2 changed files with 122 additions and 72 deletions
+122 -72
View File
@@ -448,7 +448,7 @@ MyPlaneSurfTmInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDes
// Inserisco il risultato nel DB
int nFirstId = GDB_ID_NULL ;
// Inserisco i punti nel DB
for ( size_t i = 0 ; i < vPnt.size() ; ++ i) {
for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) {
// creo il punto
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
if ( IsNull( pGeoPnt))
@@ -469,14 +469,14 @@ MyPlaneSurfTmInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDes
nFirstId = nNewId ;
++ nPntCount ;
}
// Concateno i tratti di curva
// Inserisco le curve nel DB (dopo averle concatenate)
double dToler = 20 * EPS_SMALL ;
ChainCurves chainC ;
chainC.Init( false, dToler, int( vBpt.size())) ;
for ( size_t i = 0 ; i < vBpt.size() ; ++ i) {
for ( int i = 0 ; i < int( vBpt.size()) ; ++ i) {
Vector3d vtDir = vBpt[i].second - vBpt[i].first ;
vtDir.Normalize() ;
if ( ! chainC.AddCurve( int( i) + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir))
if ( ! chainC.AddCurve( i + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir))
return GDB_ID_NULL ;
}
// recupero i percorsi concatenati
@@ -488,7 +488,7 @@ MyPlaneSurfTmInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDes
if ( IsNull( pCrvCompo))
return GDB_ID_NULL ;
// recupero gli estremi dei segmenti, creo le linee e le inserisco nella composita
for ( size_t i = 0 ; i < vId.size() ; ++ i) {
for ( int i = 0 ; i < int( vId.size()) ; ++ i) {
// creo una segmento di retta
int nInd = abs( vId[i]) - 1 ;
bool bInvert = ( vId[i] < 0) ;
@@ -534,11 +534,11 @@ MyPlaneSurfTmInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDes
nFirstId = nNewId ;
++ nCrvCount ;
}
// Costruisco una superficie trimesh dall'insieme di triangoli
// Inserisco i triangoli nel DB (dopo averli uniti in una superficie trimesh)
StmFromTriangleSoup StmFts ;
if ( ! StmFts.Start())
return GDB_ID_NULL ;
for ( size_t i = 0 ; i < vTria.size() ; ++ i)
for ( int i = 0 ; i < int( vTria.size()) ; ++ i)
// inserisco il triangolo nella nuova superficie
StmFts.AddTriangle( vTria[i]) ;
// valido la superficie e calcolo le adiacenze
@@ -598,6 +598,115 @@ ExePlaneSurfTmInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDe
return nFirstId ;
}
//-------------------------------------------------------------------------------
static bool
MyChainCurvesForSurfSurfInters( const BIPNTVECTOR& vBpt, IGeomDB* pGeomDB, int nDestGrpId, int nId1, int& nFirstId, int& nCrvCount)
{
// Concateno i tratti di curva
const double dToler = 20 * EPS_SMALL ;
ChainCurves chainC ;
chainC.Init( false, dToler, int( vBpt.size())) ;
for ( int i = 0 ; i < int( vBpt.size()) ; ++ i) {
Vector3d vtDir = vBpt[i].second - vBpt[i].first ;
vtDir.Normalize() ;
if ( ! chainC.AddCurve( i + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir))
return false ;
}
// recupero i percorsi concatenati
ICRVCOMPOPOVECTOR vCrvCompo ;
Point3d ptNear = ( vBpt.empty() ? ORIG : vBpt[0].first) ;
INTVECTOR vId ;
while ( chainC.GetChainFromNear( ptNear, true, vId)) {
// creo una curva composita
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo))
return false ;
// recupero gli estremi dei segmenti, creo le linee e le inserisco nella composita
for ( int i = 0 ; i < int( vId.size()) ; ++ i) {
// creo un segmento di retta
int nInd = abs( vId[i]) - 1 ;
bool bInvert = ( vId[i] < 0) ;
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
if ( IsNull( pLine) || ! pLine->Set( vBpt[nInd].first, vBpt[nInd].second))
return false ;
if ( bInvert)
pLine->Invert() ;
// lo accodo alla composita
if ( ! pCrvCompo->AddCurve( Release( pLine), true, 1.1 * dToler) &&
! AreSamePointApprox( ptNear, ( bInvert ? vBpt[nInd].first : vBpt[nInd].second)))
return false ;
// aggiorno il prossimo near
ptNear = vBpt[nInd].second ;
}
// se lunghezza curva inferiore a 5 volte la tolleranza, la salto
double dCrvLen ;
if ( ! pCrvCompo->GetLength( dCrvLen) || dCrvLen < 5 * dToler)
continue ;
// unisco segmenti allineati
pCrvCompo->MergeCurves( dToler, ANG_TOL_STD_DEG) ;
// la salvo
vCrvCompo.emplace_back( Release( pCrvCompo)) ;
}
//return true ;
// Ripeto concatenamento sulle curve appena create (per riempire eventuali mini buchi)
chainC.Init( false, dToler, int( vCrvCompo.size())) ;
for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) {
Point3d ptStart ; vCrvCompo[i]->GetStartPoint( ptStart) ;
Vector3d vtStart ; vCrvCompo[i]->GetStartDir( vtStart) ;
Point3d ptEnd ; vCrvCompo[i]->GetEndPoint( ptEnd) ;
Vector3d vtEnd ; vCrvCompo[i]->GetEndDir( vtEnd) ;
if ( ! chainC.AddCurve( i + 1, ptStart, vtStart, ptEnd, vtEnd))
return false ;
}
// recupero i percorsi concatenati
if ( ! vCrvCompo.empty())
vCrvCompo[0]->GetStartPoint( ptNear) ;
else
ptNear = ORIG ;
while ( chainC.GetChainFromNear( ptNear, true, vId)) {
// creo una curva composita
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo))
return false ;
// inserisco le curve nella composita
for ( int i = 0 ; i < int( vId.size()) ; ++ i) {
// recupero dati
int nInd = abs( vId[i]) - 1 ;
bool bInvert = ( vId[i] < 0) ;
if ( bInvert)
vCrvCompo[nInd]->Invert() ;
// accodo
if ( ! pCrvCompo->AddCurve( Release( vCrvCompo[nInd]), true, 1.1 * dToler))
return false ;
// aggiorno il prossimo near
pCrvCompo->GetEndPoint( ptNear) ;
}
// se curva chiusa entro 5 volte la tolleranza ma considerata aperta, la chiudo bene
Point3d ptStart, ptEnd ;
if ( pCrvCompo->GetStartPoint( ptStart) &&
pCrvCompo->GetEndPoint( ptEnd) &&
AreSamePointEpsilon( ptStart, ptEnd, 5 * dToler) &&
! AreSamePointApprox( ptStart, ptEnd)) {
// porto il punto finale a coincidere esattamente con l'inizio
pCrvCompo->ModifyEnd( ptStart) ;
}
// unisco segmenti allineati
pCrvCompo->MergeCurves( dToler, ANG_TOL_STD_DEG) ;
// la inserisco nel DB geometrico
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) ;
if ( nNewId == GDB_ID_NULL)
return false ;
// copio il materiale
if ( ! pGeomDB->CopyMaterial( nId1, nNewId))
return false ;
// aggiorno contatori
if ( nFirstId == GDB_ID_NULL)
nFirstId = nNewId ;
++ nCrvCount ;
}
return true ;
}
//-------------------------------------------------------------------------------
static int
MySurfTmSurfTmInters( int nId1, int nId2, int nDestGrpId,
@@ -628,7 +737,7 @@ MySurfTmSurfTmInters( int nId1, int nId2, int nDestGrpId,
// Inserisco il risultato nel DB
int nFirstId = GDB_ID_NULL ;
// Inserisco i punti nel DB
for ( size_t i = 0 ; i < vPnt.size() ; ++ i) {
for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) {
// creo il punto
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
if ( IsNull( pGeoPnt))
@@ -647,73 +756,14 @@ MySurfTmSurfTmInters( int nId1, int nId2, int nDestGrpId,
nFirstId = nNewId ;
++ nPntCount ;
}
// Concateno i tratti di curva
double dToler = 20 * EPS_SMALL ;
ChainCurves chainC ;
chainC.Init( false, dToler, int( vBpt.size())) ;
for ( size_t i = 0 ; i < vBpt.size() ; ++ i) {
Vector3d vtDir = vBpt[i].second - vBpt[i].first ;
vtDir.Normalize() ;
if ( ! chainC.AddCurve( int( i) + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir))
return GDB_ID_NULL ;
}
// recupero i percorsi concatenati
Point3d ptNear = ( vBpt.empty() ? ORIG : vBpt[0].first) ;
INTVECTOR vId ;
while ( chainC.GetChainFromNear( ptNear, false, vId)) {
// creo una curva composita
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo))
return GDB_ID_NULL ;
// recupero gli estremi dei segmenti, creo le linee e le inserisco nella composita
for ( size_t i = 0 ; i < vId.size() ; ++ i) {
// creo una segmento di retta
int nInd = abs( vId[i]) - 1 ;
bool bInvert = ( vId[i] < 0) ;
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
if ( IsNull( pLine) || ! pLine->Set( vBpt[nInd].first, vBpt[nInd].second))
return GDB_ID_NULL ;
if ( bInvert)
pLine->Invert() ;
// lo accodo alla composita
if ( ! pCrvCompo->AddCurve( Release( pLine), true, 1.1 * dToler) &&
! AreSamePointApprox( ptNear, vBpt[nInd].second))
return GDB_ID_NULL ;
// aggiorno il prossimo near
ptNear = vBpt[nInd].second ;
}
// se lunghezza curva inferiore a 5 volte la tolleranza, la salto
double dCrvLen ;
if ( ! pCrvCompo->GetLength( dCrvLen) || dCrvLen < 5. * dToler)
continue ;
// se curva chiusa entro 5 volte la tolleranza ma considerata aperta, la chiudo bene
Point3d ptStart, ptEnd ;
if ( pCrvCompo->GetStartPoint( ptStart) &&
pCrvCompo->GetEndPoint( ptEnd) &&
AreSamePointEpsilon( ptStart, ptEnd, 5. * dToler) &&
! AreSamePointApprox( ptStart, ptEnd)) {
// porto il punto finale a coincidere esattamente con l'inizio
pCrvCompo->ModifyEnd( ptStart) ;
}
// unisco segmenti allineati
pCrvCompo->MergeCurves( 0.5 * dToler, ANG_TOL_STD_DEG) ;
// la inserisco nel DB geometrico
int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) ;
if ( nNewId == GDB_ID_NULL)
return GDB_ID_NULL ;
// copio il materiale
if ( ! pGeomDB->CopyMaterial( nId1, nNewId))
return GDB_ID_NULL ;
// aggiorno contatori
if ( nFirstId == GDB_ID_NULL)
nFirstId = nNewId ;
++ nCrvCount ;
}
// Costruisco una superficie trimesh dall'insieme di triangoli
// Inserisco le curve nel DB (dopo averle concatenate)
if ( ! MyChainCurvesForSurfSurfInters( vBpt, pGeomDB, nDestGrpId, nId1, nFirstId, nCrvCount))
return GDB_ID_NULL ;
// Inserisco i triangoli nel DB (dopo averli uniti in una superficie trimesh)
StmFromTriangleSoup StmFts ;
if ( ! StmFts.Start())
return GDB_ID_NULL ;
for ( size_t i = 0 ; i < vTria.size() ; ++ i)
for ( int i = 0 ; i < int( vTria.size()) ; ++ i)
// inserisco il triangolo nella nuova superficie
StmFts.AddTriangle( vTria[i]) ;
// valido la superficie e calcolo le adiacenze
BIN
View File
Binary file not shown.