EgtExecutor (Nst_SurfFr) :

- migliorata la collisione e l'allineamento per Regioni Piane.
This commit is contained in:
Riccardo Elitropi
2026-03-31 13:22:51 +02:00
parent 6c2437831d
commit 1d9ecd9b78
3 changed files with 153 additions and 56 deletions
+132 -36
View File
@@ -22,6 +22,7 @@
#include "/EgtDev/Include/EGkCurveLine.h"
#include "/EgtDev/Include/EGkCurveComposite.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkDistPointLine.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
#include "/EgtDev/Include/EGkCAvSimpleSurfFrMove.h"
#include "/EgtDev/Include/EGkCAvSurfFrMove.h"
@@ -94,7 +95,7 @@ ExeCreateOutRegion( int nParentId, double dXmin, double dYmin, double dXmax, dou
dYmax < dYmin + GAP + 2 * EPS_SMALL)
return false ;
// se già esiste, posso uscire
// se già esiste, posso uscire
int nBoxId = pGeomDB->GetFirstNameInGroup( nParentId, NST_SHEET_OUTREG) ;
if ( nBoxId != GDB_ID_NULL)
return true ;
@@ -151,7 +152,7 @@ ExeCreateOutRegion( int nParentId, int nOutCrvId)
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se già esiste, posso uscire
// se già esiste, posso uscire
int nBoxId = pGeomDB->GetFirstNameInGroup( nParentId, NST_SHEET_OUTREG) ;
if ( nBoxId != GDB_ID_NULL)
return true ;
@@ -189,7 +190,7 @@ ExeCreateOutRegion( int nParentId, int nOutCrvId)
BBox3d b3Box ;
pCompo->GetLocalBBox( b3Box) ;
b3Box.Expand( SPESS, SPESS, 0) ;
// determino il punto più vicino al massimo del box e lo faccio diventare il nuovo inizio
// determino il punto più vicino al massimo del box e lo faccio diventare il nuovo inizio
int nFlag ;
double dU ;
DistPointCurve distPC( b3Box.GetMax(), *pCompo) ;
@@ -252,7 +253,7 @@ ExeCreateReferenceRegion( int nParentId, int nOutCrvId, bool bBottomUp)
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se già esiste, posso uscire
// se già esiste, posso uscire
int nRegId = pGeomDB->GetFirstNameInGroup( nParentId, NST_REFERENCE_REG) ;
if ( nRegId != GDB_ID_NULL)
return true ;
@@ -285,7 +286,7 @@ ExeCreateReferenceRegion( int nParentId, int nOutCrvId, bool bBottomUp)
// ne ricavo il bbox
BBox3d b3Box ;
PL.GetLocalBBox( b3Box) ;
// cerco i punti più vicini ai quattro vertici (0=BL, 1=BR, 2=TR, 3=TL)
// cerco i punti più vicini ai quattro vertici (0=BL, 1=BR, 2=TR, 3=TL)
double dU[4] = { -1, -1, -1, -1} ;
double dMinSqDist[4] = { SQ_INFINITO, SQ_INFINITO, SQ_INFINITO, SQ_INFINITO} ;
Point3d ptVert[4] ;
@@ -393,7 +394,7 @@ ExeCreateDamagedRegion( int nParentId, int nDmgCrvId)
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// verifico se esiste già la regione associata
// verifico se esiste già la regione associata
int nRegId = pGeomDB->GetFirstNameInGroup( nParentId, NST_DAMAGED_REG) ;
while ( nRegId != GDB_ID_NULL) {
// recupero l'indice della curva di origine
@@ -1036,14 +1037,14 @@ ExePackPartCluster( const INTVECTOR& vIds, bool bReducedCut, bool bBottomUp)
double dRegClDimY = b3RegCluster.GetMax().y - b3RegCluster.GetMin().y ;
Point3d ptOrig = b3RegCluster.GetMin() ;
// Determino punto più in basso a sinistra del cluster
// Determino punto più in basso a sinistra del cluster
Point3d ptBL = b3RegCluster.GetMax() ;
double dDimBottom = 0 ;
for ( int nId : vTrueIds) {
// recupero l'approssimazione lineare del contorno del pezzo ( in globale)
PolyLine PL ;
if ( GetFlatPartApproxContour( pGeomDB, nId, PL)) {
// cerco il punto più in basso a sinistra
// cerco il punto più in basso a sinistra
Point3d ptP ;
bool bFound = PL.GetFirstPoint( ptP) ;
while ( bFound) {
@@ -1479,7 +1480,7 @@ MyMovePartCluster( IGeomDB* pGeomDB, const INTVECTOR& vTrueIds, BBox3d b3Cluster
}
}
// Se movimento risultante nullo, non faccio alcunché
// Se movimento risultante nullo, non faccio alcunché
vtMoveXY = vtDir * dLen ;
if ( vtMoveXY.IsSmall())
return true ;
@@ -1746,7 +1747,7 @@ MyRotatePartCluster( IGeomDB* pGeomDB, const INTVECTOR& vTrueIds, BBox3d& b3Clus
if ( ! bOk)
return false ;
// Se movimento risultante nullo, non faccio alcunché
// Se movimento risultante nullo, non faccio alcunché
dRotAngDeg = dAng ;
if ( abs( dAng) < EPS_ANG_SMALL)
return true ;
@@ -1863,7 +1864,7 @@ ExeAlignPartClusterOnCollision( const INTVECTOR& vIds, bool bReducedCut, bool& b
string sOut = "vtTp=(" + ToString( vtTp) + ") vtTn=(" + ToString( vtTn) + ")" ;
LOG_INFO( GetLogger(), sOut.c_str()) ;
}
// ruoto dalla parte dell'angolo più piccolo (componente più grande)
// ruoto dalla parte dell'angolo più piccolo (componente più grande)
double dRotAngDeg = ( abs( vtTp * s_scInfo.vtDirF) > abs( vtTn * s_scInfo.vtDirF)) ? 90 : - 90 ;
// provo a ruotare sul punto di collisione in senso orario
Point3d ptCen = s_scInfo.ptP1 ;
@@ -1887,6 +1888,7 @@ ExeMoveToSnapPointOnCollision( const INTVECTOR& vIds, bool bReducedCut, double d
// cerco i due tagli in collisione
int nCutM = GDB_ID_NULL ;
int nGeoM = GDB_ID_NULL ;
INTVECTOR vnGeoM, vnGeoF ;
Point3d ptStartM, ptEndM ;
Vector3d vtDirM ;
Frame3d frGeoM ;
@@ -1895,13 +1897,38 @@ ExeMoveToSnapPointOnCollision( const INTVECTOR& vIds, bool bReducedCut, double d
Point3d ptStartF, ptEndF ;
Vector3d vtDirF ;
Frame3d frGeoF ;
// se mobile è già un taglio, ne ricavo i dati
// se mobile è già un taglio, ne ricavo i dati
if ( s_scInfo.bIsCutM) {
if ( s_scInfo.nIdM == GDB_ID_NULL)
return false ;
nCutM = s_scInfo.nIdM ;
nGeoM = GetGeometryFromCut( pGeomDB, pMachMgr, nCutM) ;
ICurveLine* pLineM = GetCurveLine( pGeomDB->GetGeoObj( nGeoM)) ;
if ( nCutM == GDB_ID_NULL || nGeoM == GDB_ID_NULL ||
pLineM == nullptr || ! pGeomDB->GetGlobFrame( nGeoM, frGeoM))
vnGeoM = GetGeometryFromCut( pGeomDB, pMachMgr, nCutM) ;
if ( vnGeoM.empty())
return false ;
ICurveLine* pLineM = nullptr ;
// se ho un solo taglio, allora è quello
if ( ssize( vnGeoM) == 1) {
pLineM = GetCurveLine( pGeomDB->GetGeoObj( vnGeoM[0])) ;
nGeoM = vnGeoM[0] ;
}
// se più tagli, cerco quello più vicino alla linea corrente
else {
double dMinSqDist = INFINITO ;
for ( int i = 0 ; i < ssize( vnGeoM) ; ++ i) {
Frame3d frCurrGeoM ;
ICurveLine* pCurrLineM = GetCurveLine( pGeomDB->GetGeoObj( vnGeoM[i])) ;
if ( pCurrLineM == nullptr || ! pGeomDB->GetGlobFrame( vnGeoM[i], frCurrGeoM))
return false ;
double dCurrSqDist ;
DistPointLine( GetToLoc( s_scInfo.ptP1, frCurrGeoM), *pCurrLineM).GetSqDist( dCurrSqDist) ;
if ( dCurrSqDist < dMinSqDist) {
dMinSqDist = dCurrSqDist ;
pLineM = pCurrLineM ;
nGeoM = vnGeoM[i] ;
}
}
}
if ( pLineM == nullptr || ! pGeomDB->GetGlobFrame( nGeoM, frGeoM))
return false ;
ptStartM = pLineM->GetStart() ;
ptStartM.ToGlob( frGeoM) ;
@@ -1910,13 +1937,36 @@ ExeMoveToSnapPointOnCollision( const INTVECTOR& vIds, bool bReducedCut, double d
vtDirM = ptEndM - ptStartM ;
vtDirM.Normalize() ;
}
// se fisso è già un taglio, ne ricavo i dati
// se fisso è già un taglio, ne ricavo i dati
if ( s_scInfo.bIsCutF) {
if ( s_scInfo.nChunkF == GDB_ID_NULL)
return false ;
nCutF = s_scInfo.nIdF ;
nGeoF = GetGeometryFromCut( pGeomDB, pMachMgr, nCutF) ;
vnGeoF = GetGeometryFromCut( pGeomDB, pMachMgr, nCutF) ;
ICurveLine* pLineF = GetCurveLine( pGeomDB->GetGeoObj( nGeoF)) ;
if ( nCutF == GDB_ID_NULL || nGeoF == GDB_ID_NULL ||
pLineF == nullptr || ! pGeomDB->GetGlobFrame( nGeoF, frGeoF))
// se ho un solo taglio, allora è quello
if ( ssize( vnGeoF) == 1) {
pLineF = GetCurveLine( pGeomDB->GetGeoObj( vnGeoF[0])) ;
nGeoF = vnGeoF[0] ;
}
// se più tagli, cerco quello più vicino alla linea corrente
else {
double dMinSqDist = INFINITO ;
for ( int i = 0 ; i < ssize( vnGeoF) ; ++ i) {
Frame3d frCurrGeoF ;
ICurveLine* pCurrLineF = GetCurveLine( pGeomDB->GetGeoObj( vnGeoF[i])) ;
if ( pCurrLineF == nullptr || ! pGeomDB->GetGlobFrame( vnGeoF[i], frCurrGeoF))
return false ;
double dCurrSqDist ;
DistPointLine( GetToLoc( s_scInfo.ptP1, frCurrGeoF), *pCurrLineF).GetSqDist( dCurrSqDist) ;
if ( dCurrSqDist < dMinSqDist) {
dMinSqDist = dCurrSqDist ;
pLineF = pCurrLineF ;
nGeoF = vnGeoF[i] ;
}
}
}
if ( pLineF == nullptr || ! pGeomDB->GetGlobFrame( nGeoF, frGeoF))
return false ;
ptStartF = pLineF->GetStart() ;
ptStartF.ToGlob( frGeoF) ;
@@ -1941,8 +1991,31 @@ ExeMoveToSnapPointOnCollision( const INTVECTOR& vIds, bool bReducedCut, double d
BBox3d b3Temp ;
pGeomDB->GetGlobalBBox( nId, b3Temp) ;
if ( b3Temp.OverlapsXY( b3CutM)) {
int nGeom = GetGeometryFromCut( pGeomDB, pMachMgr, nId) ;
ICurveLine* pLine = GetCurveLine( pGeomDB->GetGeoObj( nGeom)) ;
int nGeom = GDB_ID_NULL ;
INTVECTOR vnGeom = GetGeometryFromCut( pGeomDB, pMachMgr, nId) ;
ICurveLine* pLine = nullptr ;
// se ho un solo taglio, allora è quello
if ( ssize( vnGeom) == 1) {
pLine = GetCurveLine( pGeomDB->GetGeoObj( vnGeom[0])) ;
nGeom = vnGeom[0] ;
}
// se ho più tagli, cerco quello più vicino alla linea corrente
else {
double dMinSqDist = INFINITO ;
for ( int i = 0 ; i < ssize( vnGeom) ; ++ i) {
Frame3d frCurrGeo ;
ICurveLine* pCurrLine = GetCurveLine( pGeomDB->GetGeoObj( vnGeom[i])) ;
if ( pCurrLine == nullptr || ! pGeomDB->GetGlobFrame( vnGeom[i], frCurrGeo))
return false ;
double dCurrSqDist ;
DistPointLine( GetToLoc( s_scInfo.ptP1, frCurrGeo), *pCurrLine).GetSqDist( dCurrSqDist) ;
if ( dCurrSqDist < dMinSqDist) {
dMinSqDist = dCurrSqDist ;
pLine = pCurrLine ;
nGeom = vnGeom[i] ;
}
}
}
if ( nGeom == GDB_ID_NULL || pLine == nullptr || ! pGeomDB->GetGlobFrame( nGeom, frGeoF))
continue ;
ptStartF = pLine->GetStart() ;
@@ -1975,8 +2048,31 @@ ExeMoveToSnapPointOnCollision( const INTVECTOR& vIds, bool bReducedCut, double d
BBox3d b3Temp ;
pGeomDB->GetGlobalBBox( nId, b3Temp) ;
if ( b3Temp.OverlapsXY( b3CutF)) {
int nGeom = GetGeometryFromCut( pGeomDB, pMachMgr, nId) ;
ICurveLine* pLine = GetCurveLine( pGeomDB->GetGeoObj( nGeom)) ;
int nGeom = GDB_ID_NULL ;
INTVECTOR vnGeom = GetGeometryFromCut( pGeomDB, pMachMgr, nId) ;
ICurveLine* pLine = nullptr ;
// se ho un solo taglio, allora è quello
if ( ssize( vnGeom) == 1) {
pLine = GetCurveLine( pGeomDB->GetGeoObj( vnGeom[0])) ;
nGeom = vnGeom[0] ;
}
// se ho più tagli, cerco quello più vicino alla linea corrente
else {
double dMinSqDist = INFINITO ;
for ( int i = 0 ; i < ssize( vnGeom) ; ++ i) {
Frame3d frCurrGeo ;
ICurveLine* pCurrLine = GetCurveLine( pGeomDB->GetGeoObj( vnGeom[0])) ;
if ( pCurrLine == nullptr || ! pGeomDB->GetGlobFrame( vnGeom[i], frCurrGeo))
return false ;
double dCurrSqDist ;
DistPointLine( GetToLoc( s_scInfo.ptP1, frCurrGeo), *pCurrLine).GetSqDist( dCurrSqDist) ;
if ( dCurrSqDist < dMinSqDist) {
dMinSqDist = dCurrSqDist ;
pLine = pCurrLine ;
nGeom = vnGeom[i] ;
}
}
}
if ( nGeom == GDB_ID_NULL || pLine == nullptr || ! pGeomDB->GetGlobFrame( nGeom, frGeoM))
continue ;
ptStartM = pLine->GetStart() ;
@@ -2053,9 +2149,9 @@ ExeMoveToSnapPointOnCollision( const INTVECTOR& vIds, bool bReducedCut, double d
dMoveMn = CrossXY( ptStartF - ptEndM, vtDirFp) / dDenom ;
}
}
// pareggio la parte più vicina, se almeno una sotto soglia
// pareggio la parte più vicina, se almeno una sotto soglia
if ( abs( dMoveMp) < dMaxMove || abs( dMoveMn) < dMaxMove) {
// calcolo movimento necessario, se nullo già a posto
// calcolo movimento necessario, se nullo già a posto
Vector3d vtMove = (( abs( dMoveMp) < abs( dMoveMn)) ? dMoveMp : dMoveMn) * vtDirF ;
if ( vtMove.IsSmall()) {
bMoved = false ;
@@ -2080,7 +2176,7 @@ ExeMoveToSnapPointOnCollision( const INTVECTOR& vIds, bool bReducedCut, double d
pGeomDB->GetRefBBox( nCutM, frCutF, b3CutM) ;
double dStartDelta = b3CutF.GetMin().x - b3CutM.GetMin().x ;
double dEndDelta = b3CutF.GetMax().x - b3CutM.GetMax().x ;
// pareggio la parte più vicina, se sotto soglia
// pareggio la parte più vicina, se sotto soglia
if ( abs( dStartDelta) > dMaxMove && abs( dEndDelta) > dMaxMove)
return false ;
Vector3d vtMove = (( abs( dStartDelta) < abs( dEndDelta)) ? dStartDelta : dEndDelta) * vtDirF ;
@@ -2182,7 +2278,7 @@ ExeAutomaticPackParts( INTVECTOR& vIds, bool bMinimizeOnXvsY, bool bReducedCut,
// Avvio nesting automatico
ExeAutoNestStart() ;
// Modalità ghigliottina incompatibile con tagli completi
// Modalità ghigliottina incompatibile con tagli completi
if ( ! bReducedCut)
bGuillotineMode = false ;
@@ -2205,11 +2301,11 @@ ExeAutomaticPackParts( INTVECTOR& vIds, bool bMinimizeOnXvsY, bool bReducedCut,
nDamId = pGeomDB->GetNextName( nDamId, NST_DAMAGED_REG) ;
}
// Modalità ghigliottina incompatibile con pannelli non rettangolari
// Modalità ghigliottina incompatibile con pannelli non rettangolari
if ( ! bIsRect)
bGuillotineMode = false ;
// Assegno le aree occupate dai pezzi già nestati
// Assegno le aree occupate dai pezzi già nestati
bool bPartAlreadyNested = false ;
BBox3d b3Sheet ;
pGeomDB->GetGlobalBBox( nRefReg, b3Sheet) ;
@@ -2235,18 +2331,18 @@ ExeAutomaticPackParts( INTVECTOR& vIds, bool bMinimizeOnXvsY, bool bReducedCut,
GetFlatPartDownCutRegions( pGeomDB, nId, bReducedCut, vCutReg) ;
for ( int nRegId : vCutReg)
ExeAutoNestAddDefectToSheet( nSheetId, nRegId) ;
// dichiaro ci sono pezzi già nestati
// dichiaro ci sono pezzi già nestati
bPartAlreadyNested = true ;
}
}
nId = ( bInRoot ? ExeGetNextPart( nId, true) : ExeGetNextGroup( nId)) ;
}
// Pezzi già nestati incompatibili con ghigliottina
// Pezzi già nestati incompatibili con ghigliottina
if ( bPartAlreadyNested)
bGuillotineMode = false ;
// Se richiesta modalità ghigliottina
// Se richiesta modalità ghigliottina
if ( bGuillotineMode) {
// cerco il gap necessario tra le parti
double dGap = 0 ;
@@ -2256,7 +2352,7 @@ ExeAutomaticPackParts( INTVECTOR& vIds, bool bMinimizeOnXvsY, bool bReducedCut,
if ( GetFlatPartInterpartGap( pGeomDB, nPartId, dCurrGap) && dCurrGap > dGap)
dGap = dCurrGap ;
}
// se non trovato disabilito richiesta modalità ghigliottina
// se non trovato disabilito richiesta modalità ghigliottina
if ( dGap < EPS_SMALL)
bGuillotineMode = false ;
// altrimenti lo imposto
@@ -2264,7 +2360,7 @@ ExeAutomaticPackParts( INTVECTOR& vIds, bool bMinimizeOnXvsY, bool bReducedCut,
ExeAutoNestSetInterpartGap( dGap) ;
}
// Se richiesto e abilitato, imposto modalità ghigliottina
// Se richiesto e abilitato, imposto modalità ghigliottina
if ( bGuillotineMode)
ExeAutoNestSetGuillotineMode() ;
@@ -2280,7 +2376,7 @@ ExeAutomaticPackParts( INTVECTOR& vIds, bool bMinimizeOnXvsY, bool bReducedCut,
int nDwnRegId = GetFlatPartDownRegion( pGeomDB, nPartId) ;
if ( nDwnRegId != GDB_ID_NULL)
ExeAutoNestAddAnotherOutlineToPart( nPartId, nDwnRegId) ;
// se non è ghigliottina imposto le regioni dei tagli (con ghigliottina si usa il gap)
// se non è ghigliottina imposto le regioni dei tagli (con ghigliottina si usa il gap)
if ( ! bGuillotineMode) {
// recupero regioni dei tagli del pezzo
INTVECTOR vCutReg ;