EgtExecutor :

- aggiunta gestione giunzioni di curve composite
- riorganizzato ed esteso nesting di pezzi piani.
This commit is contained in:
Dario Sassi
2016-02-22 07:34:47 +00:00
parent 403d3a658d
commit 28f6f1240f
5 changed files with 563 additions and 265 deletions
+327 -262
View File
@@ -21,6 +21,7 @@
#include "/EgtDev/Include/EXeConst.h"
#include "/EgtDev/Include/EGkCurveLine.h"
#include "/EgtDev/Include/EGkCurveComposite.h"
#include "/EgtDev/Include/EgkDistPointCurve.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
#include "/EgtDev/Include/EGkSimpleCDSurfFrMove.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
@@ -44,97 +45,58 @@ struct SCollInfoEx : public SCollInfo
} ;
//----------------------------------------------------------------------------
int
GetFlatPartRegion( IGeomDB* pGeomDB, int nId)
{
// recupero regione del pezzo (è la prima del sottogruppo di nome Region)
int nRegGrp = pGeomDB->GetFirstNameInGroup( nId, NST_PARTREG_LAYER) ;
int nRegId = pGeomDB->GetFirstInGroup( nRegGrp) ;
while ( nRegId != GDB_ID_NULL) {
if ( pGeomDB->GetGeoType( nRegId) == SRF_FLATRGN)
break ;
nRegId = pGeomDB->GetNext( nRegId) ;
}
return nRegId ;
}
static const double SPESS = 100 ;
//----------------------------------------------------------------------------
bool
GetFlatPartCutRegions( IGeomDB* pGeomDB, int nId, bool bReduced, INTVECTOR& vCrId)
static bool MyMovePartCluster( IGeomDB* pGeomDB, const INTVECTOR& vTrueIds, BBox3d b3Cluster, bool bReducedCut, Vector3d& vtMove) ;
//----------------------------------------------------------------------------
static bool
AdjustClusterObjIds( IGeomDB* pGeomDB, const INTVECTOR& vIds, INTVECTOR& vTrueIds, BBox3d& b3Cluster)
{
// recupero gruppo preview lavorazioni del pezzo
int nPVGrp = pGeomDB->GetFirstNameInGroup( nId, MCH_PV) ;
if ( nPVGrp == GDB_ID_NULL)
return true ;
// ciclo sulle lavorazioni
int nMchId = pGeomDB->GetFirstGroupInGroup( nPVGrp) ;
while ( nMchId != GDB_ID_NULL) {
int nClId = pGeomDB->GetFirstGroupInGroup( nMchId) ;
while ( nClId != GDB_ID_NULL) {
int nCrId = pGeomDB->GetFirstNameInGroup( nClId, ( bReduced ? MCH_PV_RRCUT : MCH_PV_RCUT)) ;
while ( nCrId != GDB_ID_NULL) {
vCrId.emplace_back( nCrId) ;
nCrId = pGeomDB->GetNextName( nCrId, ( bReduced ? MCH_PV_RRCUT : MCH_PV_RCUT)) ;
if ( pGeomDB == nullptr)
return false ;
// Flag per calcolo box
const int BBF_MY_FLAG = BBF_ONLY_VISIBLE | BBF_IGNORE_TEXT | BBF_IGNORE_DIM ;
// Risolvo eventuali riferimenti a oggetti selezionati
vTrueIds.clear() ;
vTrueIds.reserve( vIds.size()) ;
b3Cluster.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)) {
// inserisco l'identificativo nel vettore dei validi
vTrueIds.push_back( nTrueId) ;
// aggiorno il box del cluster
b3Cluster.Add( b3Part) ;
}
nClId = pGeomDB->GetNextGroup( nClId) ;
// passo al successivo
nTrueId = (( nId != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ;
}
nMchId = pGeomDB->GetNextGroup( nMchId) ;
}
return true ;
}
//----------------------------------------------------------------------------
int
GetFlatPartFromRegion( IGeomDB* pGeomDB, int nId)
bool
ExeCreateOutRegion( int nParentId, double dXmin, double dYmin, double dXmax, double dYmax, double dZ)
{
// verifico che il layer di appartenenza sia una regione
int nLayerId = pGeomDB->GetParentId( nId) ;
string sName ;
if ( ! pGeomDB->GetName( nLayerId, sName) && ! EqualNoCase( sName, NST_PARTREG_LAYER))
return GDB_ID_NULL ;
// restituisco il padre del layer
return ( pGeomDB->GetParentId( nLayerId)) ;
}
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
//----------------------------------------------------------------------------
int
GetFlatPartFromCut( IGeomDB* pGeomDB, int nId)
{
// verifico appartenga al gruppo PreView (padre di padre di padre)
int nPvId = pGeomDB->GetParentId( pGeomDB->GetParentId( pGeomDB->GetParentId( nId))) ;
string sName ;
if ( ! pGeomDB->GetName( nPvId, sName) && ! EqualNoCase( sName, MCH_PV))
return GDB_ID_NULL ;
// restituisco il padre del layer
return ( pGeomDB->GetParentId( nPvId)) ;
}
// Verifiche sui parametri
if ( dXmax < dXmin + EPS_SMALL ||
dYmax < dYmin + EPS_SMALL)
return false ;
//----------------------------------------------------------------------------
int
GetGeometryFromCut( IGeomDB* pGeomDB, IMachMgr* pMachMgr, int nId)
{
// verifico appartenga ad una lavorazione
int nMchId ;
if ( ! pGeomDB->GetInfo( pGeomDB->GetParentId( pGeomDB->GetParentId( nId)), "MId", nMchId))
return GDB_ID_NULL ;
// recupero la geometria di applicazione della lavorazione (deve essere una sola)
if ( ! pMachMgr->SetCurrMachining( nMchId))
return GDB_ID_NULL ;
SELVECTOR vIds ;
pMachMgr->GetMachiningGeometry( vIds) ;
if ( vIds.size() == 1)
return vIds[0].nId ;
else
return GDB_ID_NULL ;
}
// se già esiste, posso uscire
int nBoxId = pGeomDB->GetFirstNameInGroup( nParentId, NST_SHEET_OUTREG) ;
if ( nBoxId != GDB_ID_NULL)
return true ;
//----------------------------------------------------------------------------
static int
CreateOutBoxRegion( IGeomDB* pGeomDB, int nParentId,
double dXmin, double dYmin, double dXmax, double dYmax, double dZ)
{
// creo polilinea attorno al box (avvolta a serpente)
const double SPESS = 100 ;
const double DELTA = 1 ;
PolyLine PL ;
PL.AddUPoint( 0, Point3d( dXmin, dYmin, dZ)) ;
@@ -170,11 +132,110 @@ CreateOutBoxRegion( IGeomDB* pGeomDB, int nParentId,
int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSfr) ;
if ( nId == GDB_ID_NULL)
return GDB_ID_NULL ;
// assegno nome e la dichiaro temporanea e invisibile
// assegno nome e la dichiaro di sistema e invisibile
pGeomDB->SetName( nId, NST_SHEET_OUTREG) ;
pGeomDB->SetLevel( nId, GDB_LV_SYSTEM) ;
pGeomDB->SetMaterial( nId, INVISIBLE) ;
return nId ;
return ( nId != GDB_ID_NULL) ;
}
//----------------------------------------------------------------------------
bool
ExeCreateOutRegion( int nParentId, int nOutCrvId)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// se già esiste, posso uscire
int nBoxId = pGeomDB->GetFirstNameInGroup( nParentId, NST_SHEET_OUTREG) ;
if ( nBoxId != GDB_ID_NULL)
return true ;
// recupero la curva
ICurve* pOutCrv = GetCurve( pGeomDB->GetGeoObj( nOutCrvId)) ;
if ( pOutCrv == nullptr)
return GDB_ID_NULL ;
// verifico sia chiusa
if ( ! pOutCrv->IsClosed())
return GDB_ID_NULL ;
// la approssimo con linee
const double LIN_TOL_STD = 0.1 ;
const double ANG_TOL_STD_DEG = 15 ;
PolyLine PL ;
if ( ! pOutCrv->ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
return GDB_ID_NULL ;
// porto la polilinea in globale
Frame3d frOutCrv ;
pGeomDB->GetGlobFrame( nOutCrvId, frOutCrv) ;
PL.ToGlob( frOutCrv) ;
// se antioraria la inverto
double dArea ;
if ( ! PL.GetAreaXY( dArea))
return GDB_ID_NULL ;
if ( dArea > 0)
PL.Invert() ;
// la appiattisco sulla Z iniziale
Point3d ptP ;
PL.GetFirstPoint( ptP) ;
PL.Flatten( ptP.z) ;
// la converto in curva composita
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL))
return GDB_ID_NULL ;
// ne ricavo il bbox e lo ingrandisco
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
int nFlag ;
double dU ;
DistPointCurve distPC( b3Box.GetMax(), *Get( pCompo)) ;
if ( ! distPC.GetParamAtMinDistPoint( 0, dU, nFlag) ||
! pCompo->ChangeStartPoint( dU))
return GDB_ID_NULL ;
// accorcio inizio
pCompo->TrimStartAtLen( 5 * EPS_SMALL) ;
// creo curva della parte esterna
PolyLine PL2 ;
Point3d ptEnd ;
pCompo->GetEndPoint( ptEnd) ;
PL2.AddUPoint( 0, ptEnd) ;
PL2.AddUPoint( 1, b3Box.GetMax()) ;
PL2.AddUPoint( 2, Point3d( b3Box.GetMin().x, b3Box.GetMax().y, b3Box.GetMin().z)) ;
PL2.AddUPoint( 3, b3Box.GetMin()) ;
PL2.AddUPoint( 4, Point3d( b3Box.GetMax().x, b3Box.GetMin().y, b3Box.GetMin().z)) ;
PL2.AddUPoint( 5, b3Box.GetMax() - Vector3d( 0, 5 * EPS_SMALL, 0)) ;
Point3d ptStart ;
pCompo->GetStartPoint( ptStart) ;
PL2.AddUPoint( 6, ptStart) ;
// la converto in curva composita
PtrOwner<ICurveComposite> pCompo2( CreateCurveComposite()) ;
if ( IsNull( pCompo2) || ! pCompo2->FromPolyLine( PL2))
return GDB_ID_NULL ;
// unisco le due curve composite
if ( ! pCompo->AddCurve( Release( pCompo2)))
return GDB_ID_NULL ;
// costruisco la regione piana
SurfFlatRegionByContours SfrCntr ;
SfrCntr.AddCurve( Release( pCompo)) ;
ISurfFlatRegion* pSfr = SfrCntr.GetSurf() ;
if ( pSfr == nullptr)
return GDB_ID_NULL ;
// recupero il riferimento del gruppo di inserimento
Frame3d frLoc ;
if ( ! pGeomDB->GetGroupGlobFrame( nParentId, frLoc))
return GDB_ID_NULL ;
// porto la regione nel riferimento
pSfr->ToLoc( frLoc) ;
// inserisco la superficie nel DB
int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSfr) ;
if ( nId == GDB_ID_NULL)
return GDB_ID_NULL ;
// assegno nome e la dichiaro di sistema e invisibile
pGeomDB->SetName( nId, NST_SHEET_OUTREG) ;
pGeomDB->SetLevel( nId, GDB_LV_SYSTEM) ;
pGeomDB->SetMaterial( nId, INVISIBLE) ;
return ( nId != GDB_ID_NULL) ;
}
//----------------------------------------------------------------------------
@@ -212,42 +273,13 @@ UpdateToolOffset( IGeomDB* pGeomDB, const INTVECTOR& vIds, bool bReducedCut, dou
}
//----------------------------------------------------------------------------
bool
ExeVerifyPartCluster( const INTVECTOR& vIds, bool bReducedCut,
double dXmin, double dYmin, double dXmax, double dYmax)
static bool
MyVerifyPartCluster( IGeomDB* pGeomDB, const INTVECTOR& vTrueIds, const BBox3d& b3Cluster, bool bReducedCut)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// 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, compresi 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)) {
// 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 le regioni dei pezzi rimasti
// Determino le regioni dei pezzi
INTVECTOR vReg ;
INTVECTOR vCutReg ;
BBox3d b3RegCluster ;
@@ -266,13 +298,24 @@ ExeVerifyPartCluster( const INTVECTOR& vIds, bool bReducedCut,
return false ;
}
// Verifico di essere all'interno del box esterno
if ( ! b3Region.EnclosesXY( b3RegCluster))
return false ;
// Verifico se pezzi sotto la radice o pezzi in altro gruppo
int nGroupId = pGeomDB->GetParentId( vTrueIds[0]) ;
bool bInRoot = ( nGroupId == GDB_ID_ROOT) ;
// Verifico di essere nella regione valida
int nBoxId = pGeomDB->GetFirstNameInGroup( nGroupId, NST_SHEET_OUTREG) ;
BBox3d b3Region ;
if ( nBoxId == GDB_ID_NULL || ! pGeomDB->GetGlobalBBox( nBoxId, b3Region))
return false ;
// box delle regioni dei pezzi rispetto al box dell'esterno
if ( ! b3Region.EnclosesXY( b3RegCluster))
return false ;
// regioni dei pezzi rispetto alla regione dell'esterno
for ( int nRegId : vReg) {
if ( ExeSurfFrChunkSimpleClassify( nRegId, 0, nBoxId, 0) != REGC_OUT)
return false ;
}
// Determino le regioni di tutti gli altri pezzi compresi nella regione di interesse
INTVECTOR vOthReg ;
INTVECTOR vOthCutReg ;
@@ -297,18 +340,17 @@ ExeVerifyPartCluster( const INTVECTOR& vIds, bool bReducedCut,
}
// Eseguo verifiche
bool bOk = true ;
// regioni dei pezzi
for ( int nRegId : vReg) {
// verifico con le regioni degli altri pezzi
for ( int nOthRegId : vOthReg) {
if ( ExeSurfFrChunkSimpleClassify( nRegId, 0, nOthRegId, 0) != REGC_OUT)
bOk = false ;
return false ;
}
// e con le regioni dei tagli degli altri pezzi
for ( int nOthCutRegId : vOthCutReg) {
if ( ExeSurfFrChunkSimpleClassify( nRegId, 0, nOthCutRegId, 0) != REGC_OUT)
bOk = false ;
return false ;
}
}
// regioni delle lavorazioni dei pezzi
@@ -316,39 +358,38 @@ ExeVerifyPartCluster( const INTVECTOR& vIds, bool bReducedCut,
// le confronto con le regioni degli altri pezzi
for ( int nOthRegId : vOthReg) {
if ( ExeSurfFrChunkSimpleClassify( nCutRegId, 0, nOthRegId, 0) != REGC_OUT)
bOk = false ;
return false ;
}
}
return bOk ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExeVerifyPartCluster( const INTVECTOR& vIds, bool bReducedCut)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// Risolvo identificativi a selezionati
INTVECTOR vTrueIds ;
BBox3d b3Cluster ;
AdjustClusterObjIds( pGeomDB, vIds, vTrueIds, b3Cluster) ;
if ( vTrueIds.empty())
return true ;
// Eseguo verifica
return MyVerifyPartCluster( pGeomDB, vTrueIds, b3Cluster, bReducedCut) ;
}
//----------------------------------------------------------------------------
static bool
MyPackPartCluster( const INTVECTOR& vIds, bool bReducedCut,
MyPackPartCluster( const INTVECTOR& vTrueIds, bool bReducedCut,
double dXmin, double dYmin, double dXmax, double dYmax, bool bBottomUp)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// Verifiche sui parametri
if ( dXmax < dXmin + EPS_SMALL ||
dYmax < dYmin + 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()) ;
}
}
// Se non sono rimasti oggetti, esco con successo
if ( vTrueIds.empty())
return true ;
// Verifico se pezzi sotto la radice o pezzi in altro gruppo
int nGroupId = pGeomDB->GetParentId( vTrueIds[0]) ;
@@ -393,9 +434,9 @@ MyPackPartCluster( const INTVECTOR& vIds, bool bReducedCut,
if ( bOk) {
const double BIG_MOVE = 1000 ;
Vector3d vtMoveY = ( bBottomUp ? - 1 : 1) * BIG_MOVE * Y_AX ;
ExeMovePartCluster( vTrueIds, bReducedCut, vtMoveY, dXmin, dYmin, dXmax, dYmax) ;
ExeMovePartCluster( vTrueIds, bReducedCut, vtMoveY) ;
Vector3d vtMoveX = - BIG_MOVE * X_AX ;
ExeMovePartCluster( vTrueIds, bReducedCut, vtMoveX, dXmin, dYmin, dXmax, dYmax) ;
ExeMovePartCluster( vTrueIds, bReducedCut, vtMoveX) ;
}
return bOk ;
@@ -408,17 +449,27 @@ ExePackPartCluster( const INTVECTOR& vIds, bool bReducedCut,
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// Risolvo eventuali riferimenti a oggetti selezionati
// Verifiche sui parametri
if ( dXmax < dXmin + EPS_SMALL ||
dYmax < dYmin + EPS_SMALL)
return false ;
// Risolvo identificativi a 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()) ;
}
}
BBox3d b3Cluster ;
AdjustClusterObjIds( pGeomDB, vIds, vTrueIds, b3Cluster) ;
if ( vTrueIds.empty())
return true ;
// Recupero gruppo dei pezzi
int nGroupId = pGeomDB->GetParentId( vTrueIds[0]) ;
// Se non esiste, creo SurfFlatRegion che delimita la regione valida
int nBoxId = pGeomDB->GetFirstNameInGroup( nGroupId, NST_SHEET_OUTREG) ;
if ( nBoxId == GDB_ID_NULL)
nBoxId = ExeCreateOutRegion( nGroupId, dXmin, dYmin, dXmax, dYmax, b3Cluster.GetMin().z) ;
if ( nBoxId == GDB_ID_NULL)
return false ;
// se con tagli ridotti
if ( bReducedCut) {
@@ -430,7 +481,7 @@ ExePackPartCluster( const INTVECTOR& vIds, bool bReducedCut,
if ( ! MyPackPartCluster( vTrueIds, true, dXmin, dYmin, dXmax, dYmax, bBottomUp))
return false ;
// se posizione valida
if ( ExeVerifyPartCluster( vTrueIds, false, dXmin, dYmin, dXmax, dYmax)) {
if ( MyVerifyPartCluster( pGeomDB, vTrueIds, b3Cluster, false)) {
return true ;
}
// altrimenti, riprovo con tagli standard
@@ -440,6 +491,77 @@ ExePackPartCluster( const INTVECTOR& vIds, bool bReducedCut,
}
}
//----------------------------------------------------------------------------
bool
ExePackPartCluster( const INTVECTOR& vIds, bool bReducedCut, bool bBottomUp)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// Risolvo identificativi a selezionati
INTVECTOR vTrueIds ;
BBox3d b3Cluster ;
AdjustClusterObjIds( pGeomDB, vIds, vTrueIds, b3Cluster) ;
if ( vTrueIds.empty())
return true ;
// Recupero gruppo dei pezzi
int nGroupId = pGeomDB->GetParentId( vTrueIds[0]) ;
// Calcolo il box di ingombro della regione valida
int nBoxId = pGeomDB->GetFirstNameInGroup( nGroupId, NST_SHEET_OUTREG) ;
BBox3d b3Box ;
if ( ! pGeomDB->GetGlobalBBox( nGroupId, b3Box))
return false ;
b3Box.Expand( - SPESS, - SPESS, 0) ;
// Procedo per tentativi
bool bFit = false ;
Point3d ptOrig = b3Cluster.GetMin() ;
Point3d ptLineStart = b3Box.GetMin() ;
Point3d ptIns = ptLineStart ;
while ( true) {
// porto nella posizione di prova
Vector3d vtMove = ptIns - b3Cluster.GetMin() ;
vtMove.z = 0 ;
for ( auto nId : vTrueIds)
pGeomDB->TranslateGlob( nId, vtMove) ;
b3Cluster.Translate( vtMove) ;
// verifico
if ( MyVerifyPartCluster( pGeomDB, vTrueIds, b3Cluster, bReducedCut)) {
bFit = true ;
break ;
}
// nuova posizione di inserimento (incrementando X)
ptIns += Vector3d( 50, 0, 0) ;
// se esco dal box torno all'inizio e incremento Y
if ( ! b3Box.EnclosesXY( ptIns)) {
ptLineStart += Vector3d( 0, 50, 0) ;
if ( ( ! b3Box.EnclosesXY( ptLineStart)))
break ;
ptIns = ptLineStart ;
}
}
// Se inserimento non riuscito
if ( ! bFit) {
// riporto nella posizione originale
Vector3d vtMove = ptOrig - b3Cluster.GetMin() ;
for ( auto nId : vTrueIds)
pGeomDB->TranslateGlob( nId, vtMove) ;
return false ;
}
// Inserimento riuscito, provo a migliorare
const double BIG_MOVE = 1000 ;
Vector3d vtMoveY = ( bBottomUp ? - 1 : 1) * BIG_MOVE * Y_AX ;
MyMovePartCluster( pGeomDB, vTrueIds, b3Cluster, bReducedCut, vtMoveY) ;
Vector3d vtMoveX = - BIG_MOVE * X_AX ;
MyMovePartCluster( pGeomDB, vTrueIds, b3Cluster, bReducedCut, vtMoveX) ;
return true ;
}
//----------------------------------------------------------------------------
static SCollInfoEx s_scInfo ;
static SCollInfoEx s_scInfoSaved ;
@@ -518,16 +640,8 @@ MySurfFrMoveSimpleNoCollision( int nId1, int nId2, const Vector3d& vtDir, double
//----------------------------------------------------------------------------
static bool
MyMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove,
double dXmin, double dYmin, double dXmax, double dYmax)
MyMovePartCluster( IGeomDB* pGeomDB, const INTVECTOR& vTrueIds, BBox3d b3Cluster, bool bReducedCut, Vector3d& vtMove)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// Verifiche sui parametri
if ( dXmax < dXmin + EPS_SMALL ||
dYmax < dYmin + EPS_SMALL)
return false ;
// Reset info di collisione
s_scInfo.nType = SCI_NONE ;
@@ -537,38 +651,19 @@ MyMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove,
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, compresi 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.OverlapsXY( 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 ;
// Verifico se pezzi sotto la radice o pezzi in altro gruppo
int nGroupId = pGeomDB->GetParentId( vTrueIds[0]) ;
bool bInRoot = ( nGroupId == GDB_ID_ROOT) ;
// Recupero regione di interesse
int nBoxId = pGeomDB->GetFirstNameInGroup( nGroupId, NST_SHEET_OUTREG) ;
BBox3d b3Region ;
if ( nBoxId == GDB_ID_NULL || ! pGeomDB->GetGlobalBBox( nBoxId, b3Region))
return false ;
// Determino le regioni di tutti gli altri pezzi compresi nella regione di interesse
INTVECTOR vOthReg ;
INTVECTOR vOthCutReg ;
@@ -592,13 +687,6 @@ MyMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove,
nId2 = ( bInRoot ? ExeGetNextPart( nId2, true) : ExeGetNextGroup( nId2)) ;
}
// Se non esiste, creo SurfFlatRegion che delimita la regione valida
int nBoxId = pGeomDB->GetFirstNameInGroup( nGroupId, NST_SHEET_OUTREG) ;
if ( nBoxId == GDB_ID_NULL)
nBoxId = CreateOutBoxRegion( pGeomDB, nGroupId, dXmin, dYmin, dXmax, dYmax, b3Cluster.GetMin().z) ;
if ( nBoxId == GDB_ID_NULL)
return false ;
// Verifico movimento dei pezzi del cluster rispetto agli altri pezzi
bool bOk = true ;
double dLen = vtMoveXY.Len() ;
@@ -684,35 +772,30 @@ MyMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove,
//----------------------------------------------------------------------------
bool
ExeMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove,
double dXmin, double dYmin, double dXmax, double dYmax)
ExeMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// Risolvo eventuali riferimenti a oggetti selezionati
// Risolvo identificativi a 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()) ;
}
}
BBox3d b3Cluster ;
AdjustClusterObjIds( pGeomDB, vIds, vTrueIds, b3Cluster) ;
if ( vTrueIds.empty())
return true ;
// se con tagli ridotti
if ( bReducedCut) {
return MyMovePartCluster( vTrueIds, true, vtMove, dXmin, dYmin, dXmax, dYmax) ;
return MyMovePartCluster( pGeomDB, vTrueIds, b3Cluster, true, vtMove) ;
}
// altrimenti
else {
// provo con tagli ridotti
Vector3d vtM = vtMove ;
if ( ! MyMovePartCluster( vTrueIds, true, vtM, dXmin, dYmin, dXmax, dYmax))
if ( ! MyMovePartCluster( pGeomDB, vTrueIds, b3Cluster, true, vtM))
return false ;
// se posizione valida
if ( ExeVerifyPartCluster( vTrueIds, false, dXmin, dYmin, dXmax, dYmax)) {
if ( MyVerifyPartCluster( pGeomDB, vTrueIds, b3Cluster, false)) {
vtMove = vtM ;
return true ;
}
@@ -722,60 +805,34 @@ ExeMovePartCluster( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove,
for ( int nId : vTrueIds)
pGeomDB->TranslateGlob( nId, - vtM) ;
// riprovo
return MyMovePartCluster( vTrueIds, false, vtMove, dXmin, dYmin, dXmax, dYmax) ;
return MyMovePartCluster( pGeomDB, vTrueIds, b3Cluster, false, vtMove) ;
}
}
}
//----------------------------------------------------------------------------
bool
ExeRotatePartCluster( const INTVECTOR& vIds, bool bReducedCut, const Point3d& ptCen, double& dRotAngDeg,
double dXmin, double dYmin, double dXmax, double dYmax)
MyRotatePartCluster( IGeomDB* pGeomDB, const INTVECTOR& vTrueIds, BBox3d& b3Cluster, bool bReducedCut,
const Point3d& ptCen, double& dRotAngDeg)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// Verifiche sui parametri
if ( dXmax < dXmin + EPS_SMALL ||
dYmax < dYmin + EPS_SMALL)
return false ;
// Reset info di collisione
s_scInfo.nType = SCI_NONE ;
// Rotazione nel piano XY globale
// 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, compresi 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.OverlapsXY( 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 ;
// Verifico se pezzi sotto la radice o pezzi in altro gruppo
int nGroupId = pGeomDB->GetParentId( vTrueIds[0]) ;
bool bInRoot = ( nGroupId == GDB_ID_ROOT) ;
// Recupero regione di interesse
int nBoxId = pGeomDB->GetFirstNameInGroup( nGroupId, NST_SHEET_OUTREG) ;
BBox3d b3Region ;
if ( nBoxId == GDB_ID_NULL || ! pGeomDB->GetGlobalBBox( nBoxId, b3Region))
return false ;
// Determino le regioni di tutti gli altri pezzi compresi nella regione di interesse
INTVECTOR vReg ;
INTVECTOR vCutReg ;
@@ -799,13 +856,6 @@ ExeRotatePartCluster( const INTVECTOR& vIds, bool bReducedCut, const Point3d& pt
nId2 = ( bInRoot ? ExeGetNextPart( nId2, true) : ExeGetNextGroup( nId2)) ;
}
// Creo SurfFlatRegion che delimita la regione valida
int nBoxId = pGeomDB->GetFirstNameInGroup( nGroupId, NST_SHEET_OUTREG) ;
if ( nBoxId == GDB_ID_NULL)
nBoxId = CreateOutBoxRegion( pGeomDB, nGroupId, dXmin, dYmin, dXmax, dYmax, b3Cluster.GetMin().z) ;
if ( nBoxId == GDB_ID_NULL)
return false ;
// Verifico rotazione dei pezzi del cluster rispetto agli altri pezzi
bool bOk = true ;
double dAng = dRotAngDeg ;
@@ -857,6 +907,24 @@ ExeRotatePartCluster( const INTVECTOR& vIds, bool bReducedCut, const Point3d& pt
return true ;
}
//----------------------------------------------------------------------------
bool
ExeRotatePartCluster( const INTVECTOR& vIds, bool bReducedCut, const Point3d& ptCen, double& dRotAngDeg)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
// Risolvo identificativi a selezionati
INTVECTOR vTrueIds ;
BBox3d b3Cluster ;
AdjustClusterObjIds( pGeomDB, vIds, vTrueIds, b3Cluster) ;
if ( vTrueIds.empty())
return true ;
// Eseguo rotazione
return MyRotatePartCluster( pGeomDB, vTrueIds, b3Cluster, bReducedCut, ptCen, dRotAngDeg) ;
}
//----------------------------------------------------------------------------
static bool
GetObstacleTangent( Vector3d& vtTang)
@@ -879,8 +947,7 @@ GetMovingTangent( Vector3d& vtTang)
//----------------------------------------------------------------------------
bool
ExeTgMovePartClusterOnCollision( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove,
double dXmin, double dYmin, double dXmax, double dYmax)
ExeTgMovePartClusterOnCollision( const INTVECTOR& vIds, bool bReducedCut, Vector3d& vtMove)
{
// recupero tangente lineare di ostacolo o di mobile
Vector3d vtTang ;
@@ -891,15 +958,14 @@ ExeTgMovePartClusterOnCollision( const INTVECTOR& vIds, bool bReducedCut, Vector
// calcolo il movimento tangente
vtMove = ( vtMove * vtTang) * vtTang ;
// riprovo con questo movimento
if ( ! ExeMovePartCluster( vIds, bReducedCut, vtMove, dXmin, dYmin, dXmax, dYmax))
if ( ! ExeMovePartCluster( vIds, bReducedCut, vtMove))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExeAlignPartClusterOnCollision( const INTVECTOR& vIds, bool bReducedCut,
double dXmin, double dYmin, double dXmax, double dYmax, bool& bMoved)
ExeAlignPartClusterOnCollision( const INTVECTOR& vIds, bool bReducedCut, bool& bMoved)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
@@ -947,7 +1013,7 @@ ExeAlignPartClusterOnCollision( const INTVECTOR& vIds, bool bReducedCut,
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 ;
if ( ! ExeRotatePartCluster( vIds, bReducedCut, ptCen, dRotAngDeg, dXmin, dYmin, dXmax, dYmax))
if ( ! ExeRotatePartCluster( vIds, bReducedCut, ptCen, dRotAngDeg))
return false ;
bMoved = ( fabs( dRotAngDeg) > EPS_ANG_SMALL) ;
return true ;
@@ -955,8 +1021,7 @@ ExeAlignPartClusterOnCollision( const INTVECTOR& vIds, bool bReducedCut,
//----------------------------------------------------------------------------
bool
ExeMoveToSnapPointOnCollision( const INTVECTOR& vIds, bool bReducedCut, double dMaxMove,
double dXmin, double dYmin, double dXmax, double dYmax, bool& bMoved)
ExeMoveToSnapPointOnCollision( const INTVECTOR& vIds, bool bReducedCut, double dMaxMove, bool& bMoved)
{
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false)
@@ -1141,7 +1206,7 @@ ExeMoveToSnapPointOnCollision( const INTVECTOR& vIds, bool bReducedCut, double d
return true ;
}
// eseguo movimento
if ( ExeMovePartCluster( vIds, bReducedCut, vtMove, dXmin, dYmin, dXmax, dYmax)) {
if ( ExeMovePartCluster( vIds, bReducedCut, vtMove)) {
if ( ! vtMove.IsSmall()) {
bMoved = true ;
return true ;
@@ -1163,7 +1228,7 @@ ExeMoveToSnapPointOnCollision( const INTVECTOR& vIds, bool bReducedCut, double d
if ( abs( dStartDelta) > dMaxMove && abs( dEndDelta) > dMaxMove)
return false ;
Vector3d vtMove = (( abs( dStartDelta) < abs( dEndDelta)) ? dStartDelta : dEndDelta) * vtDirF ;
if ( ! ExeMovePartCluster( vIds, bReducedCut, vtMove, dXmin, dYmin, dXmax, dYmax))
if ( ! ExeMovePartCluster( vIds, bReducedCut, vtMove))
return false ;
bMoved = ( ! vtMove.IsSmall()) ;
return true ;