EgtExecutor 1.6i5 :
- estensione nesting di rettangoli con anche funzioni Lua.
This commit is contained in:
+424
-21
@@ -23,6 +23,7 @@
|
||||
#include "/EgtDev/Include/EGkGdbIterator.h"
|
||||
#include "/EgtDev/Include/EGkIntervals.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <functional>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -487,42 +488,444 @@ ExeCreateFlatParts( int nType)
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
VerifyBox( const BBox3d& b3Test, const Vector3d& vtMove, const BOXVECTOR& vb3OnPlace)
|
||||
{
|
||||
BBox3d b3Moved = b3Test ;
|
||||
b3Moved.Translate( vtMove) ;
|
||||
for ( const auto& Box : vb3OnPlace) {
|
||||
if ( b3Moved.OverlapsXY( Box))
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
VerifyBoxAndMoveOnX( const BBox3d& b3Test, const Vector3d& vtMove, const BOXVECTOR& vb3OnPlace,
|
||||
double dXmax, double& dExtraMove)
|
||||
{
|
||||
BBox3d b3Moved = b3Test ;
|
||||
b3Moved.Translate( vtMove) ;
|
||||
dExtraMove = 0 ;
|
||||
for ( const auto& Box : vb3OnPlace) {
|
||||
if ( b3Moved.OverlapsXY( Box)) {
|
||||
double dNewMove = Box.GetMax().x - b3Moved.GetMin().x + 2 * EPS_SMALL ;
|
||||
dExtraMove += dNewMove ;
|
||||
b3Moved.Translate( Vector3d( dNewMove, 0, 0)) ;
|
||||
if ( b3Moved.GetMax().x > dXmax + EPS_SMALL)
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ExePackPart( int nId, double dXmin, double dYmin, double dXmax, double dOffs)
|
||||
ExePackPart( int nId, double dXmin, double dYmin, double dXmax, double dYmax, double dOffs, bool bBottomUp)
|
||||
{
|
||||
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
||||
VERIFY_GEOMDB( pGeomDB, false)
|
||||
// verifiche sui parametri
|
||||
if ( dOffs < - EPS_ZERO ||
|
||||
dXmax < dXmin + 2 * dOffs + EPS_SMALL ||
|
||||
dYmax < dYmin + 2 * dOffs + EPS_SMALL)
|
||||
return false ;
|
||||
// Determino il box del pezzo
|
||||
BBox3d b3Part ;
|
||||
if ( ! pGeomDB->GetGlobalBBox( nId, b3Part, BBF_ONLY_VISIBLE | BBF_IGNORE_TEXT | BBF_IGNORE_DIM))
|
||||
return false ;
|
||||
double dLarPz = b3Part.GetMax().x - b3Part.GetMin().x ;
|
||||
// Cerco prima posizione utile
|
||||
double dXok = dXmin ;
|
||||
double dYok = dYmin ;
|
||||
double dYtop = dYmin ;
|
||||
int nId2 = ExeGetFirstPart( false) ;
|
||||
Point3d ptPart = ( bBottomUp ? b3Part.GetMin() : Point3d( b3Part.GetMin().x, b3Part.GetMax().y, b3Part.GetMin().z)) ;
|
||||
b3Part.Expand( dOffs - 2 * EPS_SMALL, dOffs - 2 * EPS_SMALL, 0) ;
|
||||
// Box della regione di interesse
|
||||
BBox3d b3Region( dXmin, dYmin, 0, dXmax, dYmax, 0) ;
|
||||
// Determino il box di tutti gli altri pezzi compresi nella regione di interesse
|
||||
BOXVECTOR vBox ;
|
||||
int nId2 = ExeGetFirstPart( true) ;
|
||||
while ( nId2 != GDB_ID_NULL) {
|
||||
if ( nId2 != nId) {
|
||||
BBox3d b3Part2 ;
|
||||
if ( pGeomDB->GetGlobalBBox( nId2, b3Part2, BBF_ONLY_VISIBLE | BBF_IGNORE_TEXT | BBF_IGNORE_DIM)) {
|
||||
if ( b3Part2.GetMin().y < dYtop + 0.5 * dOffs) {
|
||||
dXok = max( dXok, b3Part2.GetMax().x + dOffs) ;
|
||||
}
|
||||
else {
|
||||
dXok = b3Part2.GetMax().x + dOffs ;
|
||||
dYok = dYtop + dOffs ;
|
||||
}
|
||||
dYtop = max( dYtop, b3Part2.GetMax().y) ;
|
||||
}
|
||||
if ( pGeomDB->GetGlobalBBox( nId2, b3Part2, BBF_ONLY_VISIBLE | BBF_IGNORE_TEXT | BBF_IGNORE_DIM) &&
|
||||
b3Region.OverlapsXY( b3Part2))
|
||||
vBox.emplace_back( b3Part2) ;
|
||||
}
|
||||
nId2 = ExeGetNextPart( nId2, false) ;
|
||||
nId2 = ExeGetNextPart( nId2, true) ;
|
||||
}
|
||||
if ( dXok + dLarPz > dXmax) {
|
||||
dXok = dXmin ;
|
||||
dYok = dYtop + dOffs ;
|
||||
// Ordino i box dei pezzi secondo la X crescente
|
||||
sort( vBox.begin(), vBox.end(), []( const BBox3d& a, const BBox3d& b)
|
||||
{ return a.GetMin().x < b.GetMin().x ; }) ;
|
||||
// Determino le Y interessanti
|
||||
DBLVECTOR vY ;
|
||||
if ( bBottomUp) {
|
||||
// Ymin del rettangolo e Ymax dei vari box
|
||||
vY.push_back( dYmin) ;
|
||||
for ( auto& Box : vBox) {
|
||||
double dY = Box.GetMax().y + dOffs ;
|
||||
if ( dY > dYmin && dY < dYmax)
|
||||
vY.push_back( dY) ;
|
||||
}
|
||||
// Le ordino in senso crescente
|
||||
sort( vY.begin(), vY.end()) ;
|
||||
}
|
||||
else {
|
||||
// Ymax del rettangolo e Ymin dei vari box
|
||||
vY.push_back( dYmax) ;
|
||||
for ( auto& Box : vBox) {
|
||||
double dY = Box.GetMin().y - dOffs ;
|
||||
if ( dY > dYmin && dY < dYmax)
|
||||
vY.push_back( dY) ;
|
||||
}
|
||||
// Le ordino in senso decrescente
|
||||
sort( vY.begin(), vY.end(), greater<double>()) ;
|
||||
}
|
||||
// Elimino i valori coincidenti
|
||||
vY.erase( unique( vY.begin(), vY.end(), [](double a, double b){ return fabs( a - b) < EPS_SMALL ;}), vY.end()) ;
|
||||
// Testo le Y in ordine opportuno
|
||||
double dXok = INFINITO, dYok = INFINITO ;
|
||||
for ( auto dY : vY) {
|
||||
double dExtraMove ;
|
||||
if ( VerifyBoxAndMoveOnX( b3Part, Point3d( dXmin, dY, 0) - ptPart, vBox, dXmax + dOffs, dExtraMove)) {
|
||||
dXok = dXmin + dExtraMove ;
|
||||
dYok = dY ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
// Verifico che il pezzo nella nuova posizione non esca da Ymax o Y min
|
||||
if ( bBottomUp && b3Part.GetMax().y - ptPart.y + dYok > dYmax + dOffs + EPS_SMALL)
|
||||
return false ;
|
||||
else if ( ! bBottomUp && b3Part.GetMin().y - ptPart.y + dYok < dYmin - dOffs - EPS_SMALL)
|
||||
return false ;
|
||||
// Porto il pezzo nella giusta posizione
|
||||
return pGeomDB->TranslateGlob( nId, Point3d( dXok, dYok, 0) - b3Part.GetMin()) ;
|
||||
return pGeomDB->TranslateGlob( nId, Point3d( dXok, dYok, 0) - ptPart) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ExePackCluster( const INTVECTOR& vIds, double dXmin, double dYmin, double dXmax, double dYmax, double dOffs, bool bBottomUp)
|
||||
{
|
||||
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
||||
VERIFY_GEOMDB( pGeomDB, false)
|
||||
// verifiche sui parametri
|
||||
if ( dOffs < - EPS_ZERO ||
|
||||
dXmax < dXmin + 2 * dOffs + EPS_SMALL ||
|
||||
dYmax < dYmin + 2 * dOffs + EPS_SMALL)
|
||||
return false ;
|
||||
// Risolvo eventuali riferimenti a oggetti selezionati
|
||||
INTVECTOR vTrueIds ;
|
||||
vTrueIds.reserve( vIds.size()) ;
|
||||
for ( auto nId : vIds) {
|
||||
int nTrueId = (( nId != GDB_ID_SEL) ? nId : pGeomDB->GetFirstSelectedObj()) ;
|
||||
while ( nTrueId != GDB_ID_NULL) {
|
||||
vTrueIds.push_back( nTrueId) ;
|
||||
// passo al successivo
|
||||
nTrueId = (( nId != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ;
|
||||
}
|
||||
}
|
||||
// Flag per calcolo box
|
||||
const int BBF_MY_FLAG = BBF_ONLY_VISIBLE | BBF_IGNORE_TEXT | BBF_IGNORE_DIM ;
|
||||
// Determino il box del cluster (insieme di pezzi)
|
||||
BBox3d b3Cluster ;
|
||||
for ( auto nTrueId : vTrueIds) {
|
||||
BBox3d b3Part ;
|
||||
if ( ! pGeomDB->GetGlobalBBox( nTrueId, b3Part, BBF_MY_FLAG))
|
||||
return false ;
|
||||
b3Cluster.Add( b3Part) ;
|
||||
}
|
||||
double dLarCl = b3Cluster.GetMax().x - b3Cluster.GetMin().x ;
|
||||
Point3d ptCluster = ( bBottomUp ? b3Cluster.GetMin() : Point3d( b3Cluster.GetMin().x, b3Cluster.GetMax().y, b3Cluster.GetMin().z)) ;
|
||||
b3Cluster.Expand( dOffs - 2 * EPS_SMALL, dOffs - 2 * EPS_SMALL, 0) ;
|
||||
// Box della regione di interesse
|
||||
BBox3d b3Region( dXmin, dYmin, 0, dXmax, dYmax, 0) ;
|
||||
// Determino il box di tutti gli altri pezzi compresi nella regione di interesse
|
||||
BOXVECTOR vBox ;
|
||||
int nId2 = ExeGetFirstPart( true) ;
|
||||
while ( nId2 != GDB_ID_NULL) {
|
||||
if ( find( vTrueIds.begin(), vTrueIds.end(), nId2) == vTrueIds.end()) {
|
||||
BBox3d b3Part2 ;
|
||||
if ( pGeomDB->GetGlobalBBox( nId2, b3Part2, BBF_MY_FLAG) &&
|
||||
b3Region.OverlapsXY( b3Part2))
|
||||
vBox.emplace_back( b3Part2) ;
|
||||
}
|
||||
nId2 = ExeGetNextPart( nId2, true) ;
|
||||
}
|
||||
// Ordino i box dei pezzi secondo la X crescente
|
||||
sort( vBox.begin(), vBox.end(), []( const BBox3d& a, const BBox3d& b)
|
||||
{ return a.GetMin().x < b.GetMin().x ; }) ;
|
||||
// Determino le Y interessanti
|
||||
DBLVECTOR vY ;
|
||||
if ( bBottomUp) {
|
||||
// Ymin del rettangolo e Ymax dei vari box
|
||||
vY.push_back( dYmin) ;
|
||||
for ( auto& Box : vBox) {
|
||||
double dY = Box.GetMax().y + dOffs ;
|
||||
if ( dY > dYmin && dY < dYmax)
|
||||
vY.push_back( dY) ;
|
||||
}
|
||||
// Le ordino in senso crescente
|
||||
sort( vY.begin(), vY.end()) ;
|
||||
}
|
||||
else {
|
||||
// Ymax del rettangolo e Ymin dei vari box
|
||||
vY.push_back( dYmax) ;
|
||||
for ( auto& Box : vBox) {
|
||||
double dY = Box.GetMin().y - dOffs ;
|
||||
if ( dY > dYmin && dY < dYmax)
|
||||
vY.push_back( dY) ;
|
||||
}
|
||||
// Le ordino in senso decrescente
|
||||
sort( vY.begin(), vY.end(), greater<double>()) ;
|
||||
}
|
||||
// Elimino i valori coincidenti
|
||||
vY.erase( unique( vY.begin(), vY.end(), [](double a, double b){ return fabs( a - b) < EPS_SMALL ;}), vY.end()) ;
|
||||
// Testo le Y in ordine opportuno
|
||||
double dXok = INFINITO, dYok = INFINITO ;
|
||||
for ( auto dY : vY) {
|
||||
double dExtraMove ;
|
||||
if ( VerifyBoxAndMoveOnX( b3Cluster, Point3d( dXmin, dY, 0) - ptCluster, vBox, dXmax + dOffs, dExtraMove)) {
|
||||
dXok = dXmin + dExtraMove ;
|
||||
dYok = dY ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
// Verifico che il cluster nella nuova posizione non esca da Ymax
|
||||
if ( bBottomUp && b3Cluster.GetMax().y - ptCluster.y + dYok > dYmax + dOffs + EPS_SMALL)
|
||||
return false ;
|
||||
else if ( ! bBottomUp && b3Cluster.GetMin().y - ptCluster.y + dYok < dYmin - dOffs - EPS_SMALL)
|
||||
return false ;
|
||||
// Porto il cluster nella giusta posizione
|
||||
for ( auto nTrueId : vTrueIds) {
|
||||
pGeomDB->TranslateGlob( nTrueId, Point3d( dXok, dYok, 0) - ptCluster) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool
|
||||
ExeGetClusterBBoxGlob( const INTVECTOR& vIds, BBox3d& b3Box)
|
||||
{
|
||||
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
||||
VERIFY_GEOMDB( pGeomDB, false)
|
||||
// Flag per calcolo box
|
||||
const int BBF_MY_FLAG = BBF_ONLY_VISIBLE | BBF_IGNORE_TEXT | BBF_IGNORE_DIM ;
|
||||
// Determino il box del cluster (insieme di pezzi)
|
||||
b3Box.Reset() ;
|
||||
for ( auto nId : vIds) {
|
||||
int nTrueId = (( nId != GDB_ID_SEL) ? nId : pGeomDB->GetFirstSelectedObj()) ;
|
||||
while ( nTrueId != GDB_ID_NULL) {
|
||||
BBox3d b3Part ;
|
||||
if ( ! pGeomDB->GetGlobalBBox( nTrueId, b3Part, BBF_MY_FLAG))
|
||||
return false ;
|
||||
b3Box.Add( b3Part) ;
|
||||
// passo al successivo
|
||||
nTrueId = (( nId != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static void
|
||||
VerifyBoxMoveInBox( const BBox3d& b3Region, const BBox3d& b3Box, Vector3d& vtMoveXY)
|
||||
{
|
||||
BBox3d b3Moved = b3Box ;
|
||||
b3Moved.Translate( vtMoveXY) ;
|
||||
if ( vtMoveXY.x < - EPS_SMALL) {
|
||||
double dDeltaX = b3Moved.GetMin().x - b3Region.GetMin().x ;
|
||||
if ( dDeltaX < - EPS_SMALL) {
|
||||
double dDeltaY = dDeltaX * vtMoveXY.y / vtMoveXY.x ;
|
||||
Vector3d vtCorr( - dDeltaX, - dDeltaY, 0) ;
|
||||
vtMoveXY += vtCorr ;
|
||||
b3Moved.Translate( vtCorr) ;
|
||||
}
|
||||
}
|
||||
if ( vtMoveXY.y < - EPS_SMALL) {
|
||||
double dDeltaY = b3Moved.GetMin().y - b3Region.GetMin().y ;
|
||||
if ( dDeltaY < - EPS_SMALL) {
|
||||
double dDeltaX = dDeltaY * vtMoveXY.x / vtMoveXY.y ;
|
||||
Vector3d vtCorr( - dDeltaX, - dDeltaY, 0) ;
|
||||
vtMoveXY += vtCorr ;
|
||||
b3Moved.Translate( vtCorr) ;
|
||||
}
|
||||
}
|
||||
if ( vtMoveXY.x > EPS_SMALL) {
|
||||
double dDeltaX = b3Moved.GetMax().x - b3Region.GetMax().x ;
|
||||
if ( dDeltaX > EPS_SMALL) {
|
||||
double dDeltaY = dDeltaX * vtMoveXY.y / vtMoveXY.x ;
|
||||
Vector3d vtCorr( - dDeltaX, - dDeltaY, 0) ;
|
||||
vtMoveXY += vtCorr ;
|
||||
b3Moved.Translate( vtCorr) ;
|
||||
}
|
||||
}
|
||||
if ( vtMoveXY.y > EPS_SMALL) {
|
||||
double dDeltaY = b3Moved.GetMax().y - b3Region.GetMax().y ;
|
||||
if ( dDeltaY > EPS_SMALL) {
|
||||
double dDeltaX = dDeltaY * vtMoveXY.x / vtMoveXY.y ;
|
||||
Vector3d vtCorr( - dDeltaX, - dDeltaY, 0) ;
|
||||
vtMoveXY += vtCorr ;
|
||||
b3Moved.Translate( vtCorr) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static void
|
||||
VerifyBoxMoveOutBox( const BBox3d& b3Other, const BBox3d& b3Box, Vector3d& vtMoveXY)
|
||||
{
|
||||
// box spostato
|
||||
BBox3d b3Moved = b3Box ;
|
||||
b3Moved.Translate( vtMoveXY) ;
|
||||
// verifico se collidono in modo significativo
|
||||
BBox3d b3Int ;
|
||||
if ( ! b3Other.FindIntersectionXY( b3Moved, b3Int) || b3Int.IsEpsilonXY( 2 * EPS_SMALL))
|
||||
return ;
|
||||
// calcolo le possibili riduzioni di movimento
|
||||
Vector3d vtCorr[4] ;
|
||||
vtCorr[0] = - vtMoveXY ;
|
||||
if ( vtMoveXY.x < - EPS_SMALL) {
|
||||
double dDeltaX = b3Moved.GetMin().x - b3Other.GetMax().x ;
|
||||
if ( dDeltaX < EPS_SMALL) {
|
||||
double dDeltaY = dDeltaX * vtMoveXY.y / vtMoveXY.x ;
|
||||
vtCorr[0].Set( - dDeltaX, - dDeltaY, 0) ;
|
||||
}
|
||||
}
|
||||
vtCorr[1] = - vtMoveXY ;
|
||||
if ( vtMoveXY.y < - EPS_SMALL) {
|
||||
double dDeltaY = b3Moved.GetMin().y - b3Other.GetMax().y ;
|
||||
if ( dDeltaY < EPS_SMALL) {
|
||||
double dDeltaX = dDeltaY * vtMoveXY.x / vtMoveXY.y ;
|
||||
vtCorr[1].Set( - dDeltaX, - dDeltaY, 0) ;
|
||||
}
|
||||
}
|
||||
vtCorr[2] = - vtMoveXY ;
|
||||
if ( vtMoveXY.x > EPS_SMALL) {
|
||||
double dDeltaX = b3Moved.GetMax().x - b3Other.GetMin().x ;
|
||||
if ( dDeltaX > - EPS_SMALL) {
|
||||
double dDeltaY = dDeltaX * vtMoveXY.y / vtMoveXY.x ;
|
||||
vtCorr[2].Set( - dDeltaX, - dDeltaY, 0) ;
|
||||
}
|
||||
}
|
||||
vtCorr[3] = - vtMoveXY ;
|
||||
if ( vtMoveXY.y > EPS_SMALL) {
|
||||
double dDeltaY = b3Moved.GetMax().y - b3Other.GetMin().y ;
|
||||
if ( dDeltaY > - EPS_SMALL) {
|
||||
double dDeltaX = dDeltaY * vtMoveXY.x / vtMoveXY.y ;
|
||||
vtCorr[3].Set( - dDeltaX, - dDeltaY, 0) ;
|
||||
}
|
||||
}
|
||||
// prendo la riduzione più piccola in modulo
|
||||
Vector3d vtMinCorr = vtCorr[0] ;
|
||||
for ( int i = 1 ; i < 4 ; ++ i) {
|
||||
if ( vtCorr[i].SqLenXY() < vtMinCorr.SqLenXY())
|
||||
vtMinCorr = vtCorr[i] ;
|
||||
}
|
||||
vtMoveXY += vtMinCorr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ExeMoveCluster( const INTVECTOR& vIds, const Vector3d& vtMove,
|
||||
double dXmin, double dYmin, double dXmax, double dYmax, double dOffs)
|
||||
{
|
||||
IGeomDB* pGeomDB = GetCurrGeomDB() ;
|
||||
VERIFY_GEOMDB( pGeomDB, false)
|
||||
// Verifiche sui parametri
|
||||
if ( dOffs < - EPS_ZERO ||
|
||||
dXmax < dXmin + 2 * dOffs + EPS_SMALL ||
|
||||
dYmax < dYmin + 2 * dOffs + EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// Vettore movimento nel solo piano XY
|
||||
Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ;
|
||||
if ( vtMoveXY.IsSmall())
|
||||
return true ;
|
||||
|
||||
// Box della regione di interesse
|
||||
BBox3d b3Region( dXmin, dYmin, 0, dXmax, dYmax, 0) ;
|
||||
// Flag per calcolo box
|
||||
const int BBF_MY_FLAG = BBF_ONLY_VISIBLE | BBF_IGNORE_TEXT | BBF_IGNORE_DIM ;
|
||||
|
||||
// Risolvo eventuali riferimenti a oggetti selezionati, escludo oggetti non completamente nella regione e
|
||||
// calcolo il box del cluster risultante
|
||||
INTVECTOR vTrueIds ;
|
||||
vTrueIds.reserve( vIds.size()) ;
|
||||
BBox3d b3Cluster ;
|
||||
for ( auto nId : vIds) {
|
||||
int nTrueId = (( nId != GDB_ID_SEL) ? nId : pGeomDB->GetFirstSelectedObj()) ;
|
||||
while ( nTrueId != GDB_ID_NULL) {
|
||||
BBox3d b3Part ;
|
||||
if ( pGeomDB->GetGlobalBBox( nTrueId, b3Part, BBF_MY_FLAG) &&
|
||||
b3Region.EnclosesXY( b3Part)) {
|
||||
// inserisco l'identificativo nel vettore dei validi
|
||||
vTrueIds.push_back( nTrueId) ;
|
||||
// aggiorno il box del cluster
|
||||
b3Cluster.Add( b3Part) ;
|
||||
}
|
||||
// passo al successivo
|
||||
nTrueId = (( nId != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ;
|
||||
}
|
||||
}
|
||||
// Se non sono rimasti oggetti, esco con successo
|
||||
if ( vTrueIds.empty())
|
||||
return true ;
|
||||
|
||||
// Determino i box di tutti gli altri pezzi compresi nella regione di interesse
|
||||
BOXVECTOR vBox ;
|
||||
int nId2 = ExeGetFirstPart( true) ;
|
||||
while ( nId2 != GDB_ID_NULL) {
|
||||
if ( find( vTrueIds.begin(), vTrueIds.end(), nId2) == vTrueIds.end()) {
|
||||
BBox3d b3Part2 ;
|
||||
if ( pGeomDB->GetGlobalBBox( nId2, b3Part2, BBF_MY_FLAG) &&
|
||||
b3Region.OverlapsXY( b3Part2))
|
||||
vBox.emplace_back( b3Part2) ;
|
||||
}
|
||||
nId2 = ExeGetNextPart( nId2, true) ;
|
||||
}
|
||||
// Ordino questi box in senso contrario al movimento
|
||||
if ( fabs( vtMoveXY.x) >= fabs( vtMoveXY.y)) {
|
||||
if ( vtMoveXY.x > 0)
|
||||
// movimento prevalente in X+ -> ordine secondo X decrescente
|
||||
sort( vBox.begin(), vBox.end(), []( const BBox3d& a, const BBox3d& b)
|
||||
{ return a.GetMin().x > b.GetMin().x ; }) ;
|
||||
else
|
||||
// movimento prevalente in X- -> ordine secondo X crescente
|
||||
sort( vBox.begin(), vBox.end(), []( const BBox3d& a, const BBox3d& b)
|
||||
{ return a.GetMin().x < b.GetMin().x ; }) ;
|
||||
}
|
||||
else {
|
||||
if ( vtMoveXY.y > 0)
|
||||
// movimento prevalente in Y+ -> ordine secondo Y decrescente
|
||||
sort( vBox.begin(), vBox.end(), []( const BBox3d& a, const BBox3d& b)
|
||||
{ return a.GetMin().y > b.GetMin().y ; }) ;
|
||||
else
|
||||
// movimento prevalente in Y- -> ordine secondo Y crescente
|
||||
sort( vBox.begin(), vBox.end(), []( const BBox3d& a, const BBox3d& b)
|
||||
{ return a.GetMin().y < b.GetMin().y ; }) ;
|
||||
}
|
||||
|
||||
// Verifico movimento del box del cluster rispetto alla regione
|
||||
VerifyBoxMoveInBox( b3Region, b3Cluster, vtMoveXY) ;
|
||||
|
||||
// Verifico movimento dei pezzi del cluster rispetto agli altri pezzi
|
||||
for ( auto nTrueId : vTrueIds) {
|
||||
// recupero box del pezzo, lo espando della minima distanza e verifico il mosso
|
||||
BBox3d b3Part ;
|
||||
pGeomDB->GetGlobalBBox( nTrueId, b3Part, BBF_MY_FLAG) ;
|
||||
b3Part.Expand( dOffs, dOffs, 0) ;
|
||||
// lo confronto con il box degli altri pezzi e se necessario riduco il movimento
|
||||
for ( const auto& Box : vBox) {
|
||||
VerifyBoxMoveOutBox( Box, b3Part, vtMoveXY) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Se movimento risultante nullo, non faccio alcunché
|
||||
if ( vtMoveXY.IsSmall())
|
||||
return true ;
|
||||
|
||||
// Eseguo movimento dei pezzi del cluster
|
||||
for ( auto nTrueId : vTrueIds)
|
||||
pGeomDB->TranslateGlob( nTrueId, vtMoveXY) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
Reference in New Issue
Block a user