1ba961c2fc
- le regioni sopra e sotto dei grezzi impostate con modo Hidden per non essere visualizzate.
1382 lines
55 KiB
C++
1382 lines
55 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2015
|
|
//----------------------------------------------------------------------------
|
|
// File : MachMgr.cpp Data : 16.04.15 Versione : 1.6d3
|
|
// Contenuto : Implementazione gestione grezzi e pezzi della classe MachMgr.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 16.04.15 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "DllMain.h"
|
|
#include "MachMgr.h"
|
|
#include "MachConst.h"
|
|
#include "Disposition.h"
|
|
#include "/EgtDev/Include/EMkMachiningGeoConst.h"
|
|
#include "/EgtDev/Include/EXeCmdLogOff.h"
|
|
#include "/EgtDev/Include/EGkCurveComposite.h"
|
|
#include "/EgtDev/Include/EGkGdbIterator.h"
|
|
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
|
#include "/EgtDev/Include/EGkCurveAux.h"
|
|
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
|
#include "/EgtDev/Include/EGkSfrCreate.h"
|
|
#include "/EgtDev/Include/EGkStmStandard.h"
|
|
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
|
#include "/EgtDev/Include/EGkSurfBezier.h"
|
|
#include "/EgtDev/Include/EGkCAvSilhouetteSurfTm.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
#include "/EgtDev/Include/EXeConst.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
MachMgr::GetRawPartCount( void) const
|
|
{
|
|
// recupero il gruppo dei grezzi nella macchinata corrente
|
|
int nRawGroupId = GetCurrRawGroupId() ;
|
|
if ( nRawGroupId == GDB_ID_NULL)
|
|
return 0 ;
|
|
// ritorno numero dei grezzi della macchinata
|
|
return m_pGeomDB->GetGroupObjs( nRawGroupId) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
MachMgr::GetFirstRawPart( void) const
|
|
{
|
|
// recupero il gruppo dei grezzi nella macchinata corrente
|
|
int nRawGroupId = GetCurrRawGroupId() ;
|
|
if ( nRawGroupId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// recupero il primo sottogruppo
|
|
int nId = m_pGeomDB->GetFirstGroupInGroup( nRawGroupId) ;
|
|
return nId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
MachMgr::GetNextRawPart( int nId) const
|
|
{
|
|
// recupero il gruppo dei grezzi nella macchinata corrente
|
|
int nRawGroupId = GetCurrRawGroupId() ;
|
|
if ( nRawGroupId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// verifico che il gruppo ricevuto sia corretto
|
|
if ( m_pGeomDB->GetParentId( nId) != nRawGroupId)
|
|
return GDB_ID_NULL ;
|
|
// recupero il successivo sottogruppo
|
|
int nNextId = m_pGeomDB->GetNextGroup( nId) ;
|
|
return nNextId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
MachMgr::AddRawPart( const Point3d& ptOrig, double dLen, double dWidth, double dHeight, Color cCol)
|
|
{
|
|
// recupero il gruppo dei grezzi nella macchinata corrente
|
|
int nRawGroupId = GetCurrRawGroupId() ;
|
|
if ( nRawGroupId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// se definita una tavola corrente, esprimo il punto rispetto alla sua prima origine
|
|
Point3d ptMyOrig = ptOrig ;
|
|
Point3d ptRef1 ;
|
|
if ( GetTableRef( 1, ptRef1))
|
|
ptMyOrig += ptRef1 ;
|
|
// inserisco il gruppo del grezzo nei grezzi della macchinata
|
|
int nRawId = m_pGeomDB->AddGroup( GDB_ID_NULL, nRawGroupId, Frame3d( ptMyOrig)) ;
|
|
if ( nRawId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// assegno il nome al gruppo
|
|
bool bOk = m_pGeomDB->SetName( nRawId, MACH_RAW_PART) ;
|
|
// assegno la fase al gruppo
|
|
m_pGeomDB->SetInfo( nRawId, MACH_RAW_PHASE, m_nCurrPhase) ;
|
|
// creo solido e outline
|
|
bOk = bOk && ModifyRawPart( nRawId, ptOrig, dLen, dWidth, dHeight, cCol) ;
|
|
// se qualcosa è andato storto, cancello tutto
|
|
if ( ! bOk) {
|
|
m_pGeomDB->Erase( nRawId) ;
|
|
return GDB_ID_NULL ;
|
|
}
|
|
// tutto ok
|
|
return nRawId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::ModifyRawPart( int nRawId, const Point3d& ptOrig, double dLen, double dWidth, double dHeight, Color cCol)
|
|
{
|
|
// le dimensioni non possono essere nulle
|
|
if ( dLen < EPS_SMALL || dWidth < EPS_SMALL || dHeight < EPS_SMALL)
|
|
return false ;
|
|
// verifica validità grezzo
|
|
if ( ! VerifyRawPart( nRawId))
|
|
return false ;
|
|
// creo il solido
|
|
PtrOwner<ISurfTriMesh> pStm( GetSurfTriMeshBox( dLen, dWidth, dHeight)) ;
|
|
if ( IsNull( pStm))
|
|
return false ;
|
|
// creo il contorno esterno
|
|
PolyLine PL ;
|
|
PL.AddUPoint( 0, ORIG) ;
|
|
PL.AddUPoint( 1, Point3d( dLen, 0, 0)) ;
|
|
PL.AddUPoint( 2, Point3d( dLen, dWidth, 0)) ;
|
|
PL.AddUPoint( 3, Point3d( 0, dWidth, 0)) ;
|
|
PL.AddUPoint( 4, ORIG) ;
|
|
// creo la curva
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyLine( PL) || ! pCrvCompo->SetExtrusion( Z_AX))
|
|
return false ;
|
|
// cancello eventuali vecchi solidi e curve di outline
|
|
int nOldRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
|
|
if ( nOldRawSolId != GDB_ID_NULL)
|
|
m_pGeomDB->Erase( nOldRawSolId) ;
|
|
int nOldRawOutId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_OUTLINE) ;
|
|
if ( nOldRawOutId != GDB_ID_NULL)
|
|
m_pGeomDB->Erase( nOldRawOutId) ;
|
|
// se definita una tavola corrente, esprimo il punto rispetto alla sua prima origine
|
|
Point3d ptMyOrig = ptOrig ;
|
|
Point3d ptRef1 ;
|
|
if ( GetTableRef( 1, ptRef1))
|
|
ptMyOrig += ptRef1 ;
|
|
// aggiorno l'origine del gruppo
|
|
m_pGeomDB->GetGroupFrame( nRawId)->ChangeOrig( ptMyOrig) ;
|
|
// inserisco il solido nel gruppo
|
|
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pStm)) ;
|
|
bool bOk = ( nId != GDB_ID_NULL) ;
|
|
// assegno il nome al solido
|
|
bOk = bOk && m_pGeomDB->SetName( nId, MACH_RAW_SOLID) ;
|
|
// assegno il colore al solido
|
|
bOk = bOk && m_pGeomDB->SetMaterial( nId, cCol) ;
|
|
// calcolo il punto centro del solido
|
|
bOk = bOk && SetRawPartCenter( nRawId) ;
|
|
// inserisco la curva composita nel DB
|
|
int nCrvId = ( bOk ? m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pCrvCompo)) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nCrvId != GDB_ID_NULL) ;
|
|
// assegno il nome al contorno
|
|
bOk = bOk && m_pGeomDB->SetName( nCrvId, MACH_RAW_OUTLINE) ;
|
|
// assegno il colore al contorno
|
|
bOk = bOk && m_pGeomDB->SetMaterial( nCrvId, cCol) ;
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
MachMgr::AddRawPartWithPart( int nPartId, int nCrvSrfId, double dOverMat, Color cCol)
|
|
{
|
|
// verifico il gruppo dei grezzi nella macchinata corrente
|
|
if ( GetCurrRawGroupId() == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// verifico che il pezzo non sia già usato nella macchinata corrente
|
|
if ( m_pGeomDB->GetParentId( nPartId) != GDB_ID_ROOT)
|
|
return GDB_ID_NULL ;
|
|
// recupero il tipo di oggetto per definire il grezzo
|
|
int nGtype = m_pGeomDB->GetGeoType( nCrvSrfId) ;
|
|
// punto di riferimento del pezzo nel grezzo
|
|
Point3d ptRef ;
|
|
// costruzione del grezzo
|
|
int nRawId = GDB_ID_NULL ;
|
|
// se grezzo da superficie (per ora senza possibilità di offset)
|
|
if ( ( nGtype & GEO_SURF) != 0) {
|
|
// inserisco il grezzo
|
|
nRawId = AddRawPart( nCrvSrfId, cCol) ;
|
|
// annullo il sovra-materiale
|
|
dOverMat = 0 ;
|
|
// calcolo il punto di inserimento nel grezzo
|
|
// determino l'ingombro del pezzo
|
|
BBox3d b3Part ;
|
|
if ( ! m_pGeomDB->GetGlobalBBox( nPartId, b3Part, BBF_EXACT))
|
|
return GDB_ID_NULL ;
|
|
// recupero il box del solido del grezzo in globale
|
|
int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
|
|
BBox3d b3RawSolid ;
|
|
if ( ! m_pGeomDB->GetGlobalBBox( nRawSolidId, b3RawSolid))
|
|
return false ;
|
|
// calcolo il punto di inserimento (come differenza tra i punti minimi)
|
|
ptRef = b3Part.GetMin() + ( ORIG - b3RawSolid.GetMin()) ;
|
|
}
|
|
// se altrimenti grezzo da contorno
|
|
else if ( ( nGtype & GEO_CURVE) != 0) {
|
|
// determino l'ingombro del pezzo
|
|
BBox3d b3Part ;
|
|
if ( ! m_pGeomDB->GetGlobalBBox( nPartId, b3Part, BBF_EXACT))
|
|
return GDB_ID_NULL ;
|
|
// inserisco il grezzo
|
|
double dZmin = b3Part.GetMin().z ;
|
|
double dH = ( b3Part.GetMax() - b3Part.GetMin()).z ;
|
|
if ( dH < RAW_MIN_H)
|
|
dH = RAW_MIN_H ;
|
|
nRawId = AddRawPart( nCrvSrfId, dOverMat, dZmin, dH, cCol) ;
|
|
// calcolo il punto di inserimento nel grezzo
|
|
// recupero il box del solido del grezzo in globale
|
|
int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
|
|
BBox3d b3RawSolid ;
|
|
if ( ! m_pGeomDB->GetGlobalBBox( nRawSolidId, b3RawSolid))
|
|
return false ;
|
|
// calcolo il punto di inserimento (come differenza tra i punti minimi)
|
|
ptRef = b3Part.GetMin() + ( ORIG - b3RawSolid.GetMin()) ;
|
|
}
|
|
// altrimenti grezzo rettangolare da ingombro pezzo
|
|
else {
|
|
// determino l'ingombro del pezzo
|
|
BBox3d b3Part ;
|
|
if ( ! m_pGeomDB->GetGlobalBBox( nPartId, b3Part, BBF_EXACT))
|
|
return GDB_ID_NULL ;
|
|
// deduco i dati del grezzo
|
|
b3Part.Expand( dOverMat, dOverMat, 0) ;
|
|
Vector3d vtDiff = b3Part.GetMax() - b3Part.GetMin() ;
|
|
if ( vtDiff.z < RAW_MIN_H)
|
|
vtDiff.z = RAW_MIN_H ;
|
|
// inserisco il grezzo
|
|
nRawId = AddRawPart( ORIG, vtDiff.x, vtDiff.y, vtDiff.z, cCol) ;
|
|
// il riferimento deve tenere conto dell'offset
|
|
ptRef = Point3d( dOverMat, dOverMat, 0) ;
|
|
}
|
|
// verifico costruzione grezzo
|
|
if ( nRawId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// se definita tavola, aggiusto posizione del grezzo
|
|
Point3d ptTabRef ;
|
|
if ( GetTableRef( 1, ptTabRef)) {
|
|
// recupero box del solido
|
|
int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
|
|
BBox3d b3RawSolid ;
|
|
// lo porto nell'angolo in basso a sinistra della tavola
|
|
if ( m_pGeomDB->GetGlobalBBox( nRawSolidId, b3RawSolid))
|
|
m_pGeomDB->TranslateGlob( nRawId, ptTabRef - b3RawSolid.GetMin()) ;
|
|
}
|
|
// inserisco il pezzo nel grezzo
|
|
if ( ! AddPartToRawPart( nPartId, ptRef, nRawId)) {
|
|
RemoveRawPart( nRawId) ;
|
|
return GDB_ID_NULL ;
|
|
}
|
|
|
|
return nRawId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
MachMgr::AddRawPart( int nCrvId, double dOverMat, double dZmin, double dHeight, Color cCol)
|
|
{
|
|
// recupero il gruppo dei grezzi nella macchinata corrente
|
|
int nRawGroupId = GetCurrRawGroupId() ;
|
|
if ( nRawGroupId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// recupero l'ingombro della curva in globale
|
|
BBox3d b3Crv ;
|
|
if ( ! m_pGeomDB->GetGlobalBBox( nCrvId, b3Crv))
|
|
return GDB_ID_NULL ;
|
|
// determino il riferimento del grezzo
|
|
Point3d ptOrig = b3Crv.GetMin() ;
|
|
ptOrig.z = dZmin ;
|
|
Frame3d frRaw( ptOrig) ;
|
|
// inserisco il gruppo del grezzo nella macchinata
|
|
int nRawId = m_pGeomDB->AddGroup( GDB_ID_NULL, nRawGroupId, frRaw) ;
|
|
if ( nRawId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// assegno il nome al gruppo
|
|
bool bOk = m_pGeomDB->SetName( nRawId, MACH_RAW_PART) ;
|
|
// assegno la fase al gruppo
|
|
m_pGeomDB->SetInfo( nRawId, MACH_RAW_PHASE, m_nCurrPhase) ;
|
|
// creo solido e outline
|
|
bOk = bOk && ModifyRawPart( nRawId, nCrvId, dOverMat, dHeight, cCol) ;
|
|
// se qualcosa è andato storto, cancello tutto
|
|
if ( ! bOk) {
|
|
m_pGeomDB->Erase( nRawId) ;
|
|
return GDB_ID_NULL ;
|
|
}
|
|
// tutto ok
|
|
return nRawId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::ModifyRawPart( int nRawId, int nCrvId, double dOverMat, double dHeight, Color cCol)
|
|
{
|
|
// verifica validità grezzo
|
|
if ( ! VerifyRawPart( nRawId))
|
|
return false ;
|
|
// recupero il riferimento della curva
|
|
Frame3d frCrv ;
|
|
if ( ! m_pGeomDB->GetGlobFrame( nCrvId, frCrv))
|
|
return false ;
|
|
// recupero la curva
|
|
const ICurve* pCrv = GetCurve( m_pGeomDB->GetGeoObj( nCrvId)) ;
|
|
if ( pCrv == nullptr)
|
|
return false ;
|
|
// copio la curva in una composita
|
|
PtrOwner<ICurveComposite> pMyCrv( CreateCurveComposite()) ;
|
|
if ( IsNull( pMyCrv) || ! pMyCrv->AddCurve( *pCrv))
|
|
return false ;
|
|
// determino il riferimento del grezzo
|
|
Frame3d frRaw ;
|
|
if ( ! m_pGeomDB->GetGroupGlobFrame( nRawId, frRaw))
|
|
return false ;
|
|
// porto la curva in questo riferimento
|
|
pMyCrv->LocToLoc( frCrv, frRaw) ;
|
|
// la schiaccio a Z = 0
|
|
if ( ! pMyCrv->Scale( Frame3d(), 1, 1, 0))
|
|
return false ;
|
|
// se non è chiusa, la chiudo
|
|
pMyCrv->Close() ;
|
|
// la oriento in senso CCW
|
|
double dAreaXY ;
|
|
if ( ! pMyCrv->GetAreaXY( dAreaXY))
|
|
return false ;
|
|
if ( dAreaXY < 0)
|
|
pMyCrv->Invert() ;
|
|
// ne eseguo l'offset
|
|
OffsetCurve OffsCrv ;
|
|
OffsCrv.Make( pMyCrv, dOverMat, ICurve::OFF_EXTEND) ;
|
|
PtrOwner<ICurve> pOffsCrv( OffsCrv.GetLongerCurve()) ;
|
|
if ( IsNull( pOffsCrv))
|
|
return false ;
|
|
// creo il solido
|
|
PtrOwner<ISurfTriMesh> pStm( GetSurfTriMeshByExtrusion( pOffsCrv, Vector3d( 0, 0, dHeight), true)) ;
|
|
if ( IsNull( pStm))
|
|
return false ;
|
|
// cancello eventuali vecchi solidi e curve di outline
|
|
int nOldRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
|
|
if ( nOldRawSolId != GDB_ID_NULL)
|
|
m_pGeomDB->Erase( nOldRawSolId) ;
|
|
int nOldRawOutId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_OUTLINE) ;
|
|
if ( nOldRawOutId != GDB_ID_NULL)
|
|
m_pGeomDB->Erase( nOldRawOutId) ;
|
|
// inserisco il solido nel gruppo
|
|
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pStm)) ;
|
|
bool bOk = ( nId != GDB_ID_NULL) ;
|
|
// assegno il nome al solido
|
|
bOk = bOk && m_pGeomDB->SetName( nId, MACH_RAW_SOLID) ;
|
|
// assegno il colore al solido
|
|
bOk = bOk && m_pGeomDB->SetMaterial( nId, cCol) ;
|
|
// calcolo il punto centro del solido
|
|
bOk = bOk && SetRawPartCenter( nRawId) ;
|
|
// inserisco nel DB la curva di offset come contorno del grezzo
|
|
int nOutCrvId = ( bOk ? m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pOffsCrv)) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nOutCrvId != GDB_ID_NULL) ;
|
|
// assegno il nome al contorno
|
|
bOk = bOk && m_pGeomDB->SetName( nOutCrvId, MACH_RAW_OUTLINE) ;
|
|
// assegno il colore al contorno
|
|
bOk = bOk && m_pGeomDB->SetMaterial( nOutCrvId, cCol) ;
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
MachMgr::AddRawPart( int nSurfId, Color cCol)
|
|
{
|
|
// recupero il gruppo dei grezzi nella macchinata corrente
|
|
int nRawGroupId = GetCurrRawGroupId() ;
|
|
if ( nRawGroupId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// verifico che la superficie sia chiusa
|
|
const ISurf* pSurf = GetSurf( m_pGeomDB->GetGeoObj( nSurfId)) ;
|
|
if ( pSurf == nullptr || ! pSurf->IsClosed())
|
|
return GDB_ID_NULL ;
|
|
// recupero l'ingombro della superficie in globale
|
|
BBox3d b3Surf ;
|
|
if ( ! m_pGeomDB->GetGlobalBBox( nSurfId, b3Surf))
|
|
return GDB_ID_NULL ;
|
|
// inserisco il gruppo del grezzo nella macchinata
|
|
Frame3d frRaw( b3Surf.GetMin()) ;
|
|
int nRawId = m_pGeomDB->AddGroup( GDB_ID_NULL, nRawGroupId, frRaw) ;
|
|
if ( nRawId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// assegno il nome al gruppo
|
|
bool bOk = m_pGeomDB->SetName( nRawId, MACH_RAW_PART) ;
|
|
// assegno la fase al gruppo
|
|
m_pGeomDB->SetInfo( nRawId, MACH_RAW_PHASE, m_nCurrPhase) ;
|
|
// creo il grezzo
|
|
int nId = GDB_ID_NULL ;
|
|
// partendo da superficie Trimesh copio
|
|
if ( pSurf->GetType() == SRF_TRIMESH)
|
|
nId = m_pGeomDB->CopyGlob( nSurfId, GDB_ID_NULL, nRawId) ;
|
|
// partendo da superficie Bezier devo recuperare la Trimesh ausiliaria e copiarla
|
|
else if ( pSurf->GetType() == SRF_BEZIER) {
|
|
const ISurfBezier* pSbez = GetSurfBezier( pSurf) ;
|
|
const ISurfTriMesh* pAuxStm = ( pSbez != nullptr ? pSbez->GetAuxSurf() : nullptr) ;
|
|
PtrOwner<ISurfTriMesh> pStm( pAuxStm != nullptr ? pAuxStm->Clone() : nullptr) ;
|
|
if ( ! IsNull( pStm)) {
|
|
Frame3d frSbez ;
|
|
m_pGeomDB->GetGlobFrame( nSurfId, frSbez) ;
|
|
pStm->LocToLoc( frSbez, frRaw) ;
|
|
nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pStm)) ;
|
|
}
|
|
}
|
|
bOk = bOk && ( nId != GDB_ID_NULL) ;
|
|
// assegno il nome al solido
|
|
bOk = bOk && m_pGeomDB->SetName( nId, MACH_RAW_SOLID) ;
|
|
// assegno il colore al solido
|
|
bOk = bOk && m_pGeomDB->SetMaterial( nId, cCol) ;
|
|
// rendo visibile il solido
|
|
bOk = bOk && m_pGeomDB->SetStatus( nId, GDB_ST_ON) ;
|
|
// calcolo il punto centro del solido
|
|
bOk = bOk && SetRawPartCenter( nRawId) ;
|
|
// calcolo la curva di contorno
|
|
if ( bOk) {
|
|
// creo la curva
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvCompo))
|
|
return GDB_ID_NULL ;
|
|
// recupero la superficie trimesh
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pStm == nullptr)
|
|
return GDB_ID_NULL ;
|
|
// recupero l'ingombro della superficie in locale
|
|
BBox3d b3Srf ;
|
|
pStm->GetLocalBBox( b3Srf) ;
|
|
// ne calcolo la silhouette secondo Z+
|
|
bool bSilh = false ;
|
|
const int NUM_TRIA_LIM = 500 ;
|
|
if ( pStm->GetTriangleCount() < NUM_TRIA_LIM) {
|
|
POLYLINEVECTOR vPL ;
|
|
if ( pStm->GetSilhouette( Z_AX, 10.0, vPL) && ! vPL.empty()) {
|
|
// cerco il contorno esterno
|
|
int nInd = - 1 ;
|
|
double dMaxArea = 0 ;
|
|
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
|
double dArea ;
|
|
if ( vPL[i].GetAreaXY( dArea) && abs( dArea) > dMaxArea) {
|
|
if ( dArea < 0)
|
|
vPL[i].Invert() ;
|
|
dMaxArea = abs( dArea) ;
|
|
nInd = i ;
|
|
}
|
|
}
|
|
// ne deduco la curva
|
|
PtrOwner<ICurveComposite> pCrvSilh( CreateCurveComposite()) ;
|
|
if ( nInd >= 0 && pCrvSilh->FromPolyLine( vPL[nInd])) {
|
|
pCrvSilh->SetExtrusion( Z_AX) ;
|
|
Plane3d plProj ;
|
|
plProj.Set( b3Srf.GetMin(), Z_AX) ;
|
|
pCrvCompo.Set( GetCurveComposite( ProjectCurveOnPlane( *pCrvSilh, plProj))) ;
|
|
if ( ! IsNull( pCrvCompo)) {
|
|
pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ;
|
|
bSilh = true ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
PtrOwner<ICAvParSilhouettesSurfTm> pCavParSilh( CreateCAvParSilhouettesSurfTm()) ;
|
|
if ( ! IsNull( pCavParSilh)) {
|
|
Frame3d frSrf( b3Srf.GetMin()) ;
|
|
const double SILH_TOL = 1.0 ;
|
|
POLYLINEVECTOR vPL ;
|
|
if ( pCavParSilh->SetData( { pStm}, frSrf, SILH_TOL) &&
|
|
pCavParSilh->GetSilhouette( 0, vPL)) {
|
|
// cerco il contorno esterno
|
|
int nInd = - 1 ;
|
|
double dMaxArea = 0 ;
|
|
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
|
double dArea ;
|
|
if ( vPL[i].GetAreaXY( dArea) && abs( dArea) > dMaxArea) {
|
|
if ( dArea < 0)
|
|
vPL[i].Invert() ;
|
|
dMaxArea = abs( dArea) ;
|
|
nInd = i ;
|
|
}
|
|
}
|
|
// ne deduco la curva
|
|
if ( nInd >= 0 && pCrvCompo->FromPolyLine( vPL[nInd])) {
|
|
pCrvCompo->SetExtrusion( Z_AX) ;
|
|
bSilh = true ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// non riuscita, la calcolo come contorno del box
|
|
if ( ! bSilh) {
|
|
Point3d ptMin ;
|
|
double dDimX, dDimY, dDimZ ;
|
|
b3Srf.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ;
|
|
PolyLine PL ;
|
|
PL.AddUPoint( 0, ptMin) ;
|
|
PL.AddUPoint( 1, ptMin + Vector3d( dDimX, 0,0)) ;
|
|
PL.AddUPoint( 2, ptMin + Vector3d( dDimX, dDimY,0)) ;
|
|
PL.AddUPoint( 3, ptMin + Vector3d( 0, dDimY,0)) ;
|
|
PL.AddUPoint( 4, ptMin) ;
|
|
if ( pCrvCompo->FromPolyLine( PL))
|
|
pCrvCompo->SetExtrusion( Z_AX) ;
|
|
else
|
|
bOk = false ;
|
|
}
|
|
// inserisco la curva composita nel DB
|
|
int nCrvId = ( bOk ? m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pCrvCompo)) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nCrvId != GDB_ID_NULL) ;
|
|
// assegno il nome alla curva
|
|
bOk = bOk && m_pGeomDB->SetName( nCrvId, MACH_RAW_OUTLINE) ;
|
|
// assegno il colore alla curva
|
|
bOk = bOk && m_pGeomDB->SetMaterial( nCrvId, cCol) ;
|
|
}
|
|
// se qualcosa è andato storto, cancello tutto
|
|
if ( ! bOk) {
|
|
m_pGeomDB->Erase( nRawId) ;
|
|
return GDB_ID_NULL ;
|
|
}
|
|
// nascondo la superficie originale
|
|
m_pGeomDB->SetStatus( nSurfId, GDB_ST_OFF) ;
|
|
// tutto ok
|
|
return nRawId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
MachMgr::AddRawPart( int nSfrUpId, int nSfrDownId, double dHeight, Color cCol)
|
|
{
|
|
// recupero il gruppo dei grezzi nella macchinata corrente
|
|
int nRawGroupId = GetCurrRawGroupId() ;
|
|
if ( nRawGroupId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
|
|
// recupero l'ingombro della superficie up in globale
|
|
BBox3d b3Surf ;
|
|
if ( ! m_pGeomDB->GetGlobalBBox( nSfrUpId, b3Surf))
|
|
return GDB_ID_NULL ;
|
|
// inserisco il gruppo del grezzo nella macchinata
|
|
Frame3d frRaw( b3Surf.GetMin()) ;
|
|
int nRawId = m_pGeomDB->AddGroup( GDB_ID_NULL, nRawGroupId, frRaw) ;
|
|
if ( nRawId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// assegno il nome al gruppo
|
|
bool bOk = m_pGeomDB->SetName( nRawId, MACH_RAW_PART) ;
|
|
// assegno la fase al gruppo
|
|
bOk = bOk && m_pGeomDB->SetInfo( nRawId, MACH_RAW_PHASE, m_nCurrPhase) ;
|
|
|
|
// recupero il frame originale della superficie up ( deve essere lo stesso della down)
|
|
Frame3d frSurf ;
|
|
bOk = bOk && m_pGeomDB->GetGlobFrame( nSfrUpId, frSurf) ;
|
|
|
|
// creo il volume in modo approssimativo a partire dalle due superfici considerando soltanto un'approssimazione dei bordi esterni
|
|
// regione up
|
|
PtrOwner<ISurfFlatRegion> pSurfUp( CloneSurfFlatRegion( m_pGeomDB->GetGeoObj( nSfrUpId))) ;
|
|
bOk = bOk && ( ! IsNull( pSurfUp)) ;
|
|
// calcolo offset e contro-offset per unificare i chunk ed eliminare eventuali rientranze nella superficie
|
|
double dOffs = 8 ;
|
|
bOk = bOk && pSurfUp->Offset( dOffs, ICurve::OFF_FILLET) ;
|
|
bOk = bOk && pSurfUp->Offset( -dOffs, ICurve::OFF_FILLET) ;
|
|
// recupero il chunk di area maggiore
|
|
int nKMax = 0 ;
|
|
if ( bOk && pSurfUp->GetChunkCount() > 1) {
|
|
double dAreaMax = -1 ;
|
|
for ( int k = 0 ; k < pSurfUp->GetChunkCount() ; k ++) {
|
|
PtrOwner<ISurfFlatRegion> pSfrChunk( pSurfUp->CloneChunk( k)) ;
|
|
double dArea = -1 ; pSfrChunk->GetGrossArea( dArea) ;
|
|
if ( dArea > dAreaMax) {
|
|
nKMax = k ;
|
|
dAreaMax = dArea ;
|
|
}
|
|
}
|
|
}
|
|
PtrOwner<ICurve> pCrvUp ;
|
|
bOk = bOk && pCrvUp.Set( pSurfUp->GetLoop( nKMax, 0)) ;
|
|
bOk = bOk && ( ! IsNull( pCrvUp)) ;
|
|
|
|
// regione down
|
|
PtrOwner<ISurfFlatRegion> pSurfDown( CloneSurfFlatRegion( m_pGeomDB->GetGeoObj( nSfrDownId))) ;
|
|
bOk = bOk && ( ! IsNull( pSurfDown)) ;
|
|
bOk = bOk && pSurfDown->Offset( dOffs, ICurve::OFF_FILLET) ;
|
|
bOk = bOk && pSurfDown->Offset( -dOffs, ICurve::OFF_FILLET) ;
|
|
nKMax = 0 ;
|
|
if ( bOk && pSurfDown->GetChunkCount() > 1) {
|
|
double dAreaMax = -1 ;
|
|
for ( int k = 0 ; k < pSurfDown->GetChunkCount() ; k ++) {
|
|
PtrOwner<ISurfFlatRegion> pSfrChunk( pSurfDown->CloneChunk( k)) ;
|
|
double dArea = -1 ; pSfrChunk->GetGrossArea( dArea) ;
|
|
if ( dArea > dAreaMax) {
|
|
nKMax = k ;
|
|
dAreaMax = dArea ;
|
|
}
|
|
}
|
|
}
|
|
PtrOwner<ICurveComposite> pCrvDown ;
|
|
bOk = bOk && pCrvDown.Set( ConvertCurveToComposite( pSurfDown->GetLoop( nKMax, 0))) ;
|
|
bOk = bOk && ( ! IsNull( pCrvDown)) ;
|
|
// sposto il punto di inizio il più vicino possibile a quello della curva up per migliorare il calcolo della rigata
|
|
if ( bOk) {
|
|
Point3d ptS ; pCrvUp->GetStartPoint( ptS) ;
|
|
DistPointCurve distPC( ptS, *pCrvDown) ;
|
|
double dPar ; int nFlag ;
|
|
bOk = bOk && distPC.GetParamAtMinDistPoint( 0, dPar, nFlag) ;
|
|
bOk = bOk && pCrvDown->ChangeStartPoint( dPar) ;
|
|
}
|
|
|
|
// volume
|
|
PtrOwner<ISurfTriMesh> pStmRaw ;
|
|
bOk = bOk && pStmRaw.Set( GetSurfTriMeshByFlatContour( pCrvUp)) ;
|
|
bOk = bOk && ( ! IsNull( pStmRaw)) ;
|
|
PtrOwner<ISurfTriMesh> pStmLat ;
|
|
bOk = bOk && pStmLat.Set( GetSurfTriMeshRuled( pCrvDown, pCrvUp, ISurfTriMesh::RLT_MINDIST)) ;
|
|
bOk = bOk && ( ! IsNull( pStmLat)) ;
|
|
bOk = bOk && pStmRaw->DoSewing( *pStmLat) ;
|
|
PtrOwner<ISurfTriMesh> pStmDown ;
|
|
bOk = bOk && pStmDown.Set( GetSurfTriMeshByFlatContour( pCrvDown)) ;
|
|
|
|
bOk = bOk && pStmDown->Invert() ;
|
|
bOk = bOk && pStmRaw->DoSewing( *pStmDown) ;
|
|
bOk = bOk && pStmRaw->DoCompacting() ;
|
|
bOk = bOk && pStmRaw->Repair() ;
|
|
bOk = bOk && pStmRaw->LocToLoc( frSurf, frRaw) ;
|
|
int nId = bOk ? m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pStmRaw)) : GDB_ID_NULL ;
|
|
bOk = bOk && ( nId != GDB_ID_NULL) ;
|
|
// assegno il nome al solido
|
|
bOk = bOk && m_pGeomDB->SetName( nId, MACH_RAW_SOLID) ;
|
|
// assegno il colore al solido
|
|
bOk = bOk && m_pGeomDB->SetMaterial( nId, cCol) ;
|
|
// rendo visibile il solido
|
|
bOk = bOk && m_pGeomDB->SetStatus( nId, GDB_ST_ON) ;
|
|
// calcolo il punto centro del solido
|
|
bOk = bOk && SetRawPartCenter( nRawId) ;
|
|
|
|
if ( bOk) {
|
|
// costruisco la curva di contorno
|
|
PtrOwner<ISurfFlatRegion> pSfrUp( CloneSurfFlatRegion( m_pGeomDB->GetGeoObj( nSfrUpId))) ;
|
|
PtrOwner<ISurfFlatRegion> pSfrDown( CloneSurfFlatRegion( m_pGeomDB->GetGeoObj( nSfrDownId))) ;
|
|
bOk = bOk && ( ! IsNull( pSfrUp)) && ( ! IsNull( pSfrDown)) ;
|
|
if ( bOk)
|
|
pSfrUp->Add( *pSfrDown) ;
|
|
PtrOwner<ICurve> pCrv ;
|
|
bOk = bOk && pCrv.Set( pSfrUp->GetLoop( 0, 0)) ;
|
|
bOk = bOk && ( ! IsNull( pCrv)) ;
|
|
bOk = bOk && pCrv->LocToLoc( frSurf, frRaw) ;
|
|
int nLoop = bOk ? m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pCrv)) : GDB_ID_NULL ;
|
|
bOk = bOk && ( nLoop != GDB_ID_NULL) ;
|
|
bOk = bOk && ExeMove( {nLoop}, -dHeight * Z_AX, RTY_LOC) ;
|
|
// assegno il nome alla curva
|
|
bOk = bOk && m_pGeomDB->SetName( nLoop, MACH_RAW_OUTLINE) ;
|
|
// assegno il colore alla curva
|
|
bOk = bOk && m_pGeomDB->SetMaterial( nLoop, cCol) ;
|
|
|
|
// recupero le superfici up e down
|
|
int nSurfUpId = ( bOk ? m_pGeomDB->CopyGlob( nSfrUpId, GDB_ID_NULL, nRawId) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nSurfUpId != GDB_ID_NULL) ;
|
|
bOk = bOk && m_pGeomDB->SetName( nSurfUpId, MACH_RAW_UP_REG) ;
|
|
bOk = bOk && m_pGeomDB->SetMaterial( nSurfUpId, cCol) ;
|
|
bOk = bOk && m_pGeomDB->SetMode( nSurfUpId, GDB_MD_HIDDEN) ;
|
|
int nSurfDownId = ( bOk ? m_pGeomDB->CopyGlob( nSfrDownId, GDB_ID_NULL, nRawId) : GDB_ID_NULL) ;
|
|
bOk = bOk && ( nSurfDownId != GDB_ID_NULL) ;
|
|
bOk = bOk && m_pGeomDB->SetName( nSurfDownId, MACH_RAW_DOWN_REG) ;
|
|
bOk = bOk && m_pGeomDB->SetMaterial( nSurfDownId, cCol) ;
|
|
bOk = bOk && m_pGeomDB->SetMode( nSurfDownId, GDB_MD_HIDDEN) ;
|
|
}
|
|
|
|
// se qualcosa è andato storto, cancello tutto
|
|
if ( ! bOk) {
|
|
m_pGeomDB->Erase( nRawId) ;
|
|
return GDB_ID_NULL ;
|
|
}
|
|
|
|
// tutto ok
|
|
return nRawId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::ModifyRawPartSize( int nRawId, double dLength, double dWidth, double dHeight)
|
|
{
|
|
// le nuove dimensioni non possono essere nulle
|
|
if ( dLength < EPS_SMALL || dWidth < EPS_SMALL || dHeight < EPS_SMALL)
|
|
return false ;
|
|
// verifica validità grezzo
|
|
if ( ! VerifyRawPart( nRawId))
|
|
return false ;
|
|
// recupero il solido del grezzo
|
|
int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
|
|
if ( nRawSolId == GDB_ID_NULL)
|
|
return false ;
|
|
// recupero il contorno del grezzo
|
|
int nRawOutId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_OUTLINE) ;
|
|
if ( nRawOutId == GDB_ID_NULL)
|
|
return false ;
|
|
// recupero il box del grezzo
|
|
BBox3d b3Raw ;
|
|
if ( ! m_pGeomDB->GetLocalBBox( nRawSolId, b3Raw))
|
|
return false ;
|
|
// determino il coefficente di scalatura in X
|
|
double dOldL = b3Raw.GetMax().x - b3Raw.GetMin().x ;
|
|
if ( dOldL < EPS_SMALL)
|
|
return false ;
|
|
double dCoeffX = dLength / dOldL ;
|
|
// determino il coefficente di scalatura in Y
|
|
double dOldW = b3Raw.GetMax().y - b3Raw.GetMin().y ;
|
|
if ( dOldW < EPS_SMALL)
|
|
return false ;
|
|
double dCoeffY = dWidth / dOldW ;
|
|
// determino il coefficente di scalatura in Z
|
|
double dOldH = b3Raw.GetMax().z - b3Raw.GetMin().z ;
|
|
if ( dOldH < EPS_SMALL)
|
|
return false ;
|
|
double dCoeffZ = dHeight / dOldH ;
|
|
// eseguo scalature
|
|
bool bOk = m_pGeomDB->Scale( nRawSolId, Frame3d( b3Raw.GetMin()), dCoeffX, dCoeffY, dCoeffZ) &&
|
|
m_pGeomDB->Scale( nRawOutId, Frame3d( b3Raw.GetMin()), dCoeffX, dCoeffY, dCoeffZ) ;
|
|
// calcolo il punto centro del solido
|
|
bOk = bOk && SetRawPartCenter( nRawId) ;
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::ModifyRawPartHeight( int nRawId, double dHeight)
|
|
{
|
|
// la nuova altezza non può essere nulla
|
|
if ( dHeight < EPS_SMALL)
|
|
return false ;
|
|
// verifica validità grezzo
|
|
if ( ! VerifyRawPart( nRawId))
|
|
return false ;
|
|
// recupero il solido del grezzo
|
|
int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
|
|
if ( nRawSolId == GDB_ID_NULL)
|
|
return false ;
|
|
// recupero il box del grezzo
|
|
BBox3d b3Raw ;
|
|
if ( ! m_pGeomDB->GetLocalBBox( nRawSolId, b3Raw))
|
|
return false ;
|
|
// determino il coefficente di scalatura in Z
|
|
double dOldH = b3Raw.GetMax().z - b3Raw.GetMin().z ;
|
|
if ( dOldH < EPS_SMALL)
|
|
return false ;
|
|
double dCoeff = dHeight / dOldH ;
|
|
// eseguo scalatura
|
|
bool bOk = m_pGeomDB->Scale( nRawSolId, Frame3d( b3Raw.GetMin()), 1, 1, dCoeff) ;
|
|
// calcolo il punto centro del solido
|
|
bOk = bOk && SetRawPartCenter( nRawId) ;
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::GetRawPartPhases( int nRawId, INTVECTOR& vPhase) const
|
|
{
|
|
// pulisco parametro di ritorno
|
|
vPhase.clear() ;
|
|
// verifica validità grezzo
|
|
if ( ! VerifyRawPart( nRawId))
|
|
return false ;
|
|
// recupero le fasi in cui è presente il grezzo (se manca è fase 1)
|
|
if ( ! m_pGeomDB->GetInfo( nRawId, MACH_RAW_PHASE, vPhase) || vPhase.empty())
|
|
vPhase.emplace_back( 1) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::KeepRawPart( int nRawId, int nSouPhase)
|
|
{
|
|
// verifico validità e recupero fasi in cui è presente
|
|
INTVECTOR vPhase ;
|
|
if ( ! GetRawPartPhases( nRawId, vPhase))
|
|
return false ;
|
|
// se fase corrente già presente, non devo fare alcunché
|
|
if ( find( vPhase.begin(), vPhase.end(), m_nCurrPhase) != vPhase.end())
|
|
return true ;
|
|
// aggiungo la fase corrente
|
|
vPhase.emplace_back( m_nCurrPhase) ;
|
|
if ( ! m_pGeomDB->SetInfo( nRawId, MACH_RAW_PHASE, vPhase))
|
|
return false ;
|
|
// annullo eventuali movimenti del grezzo (riferimento riportato a globale)
|
|
Frame3d* pfrRaw = m_pGeomDB->GetGroupFrame( nRawId) ;
|
|
if ( pfrRaw == nullptr)
|
|
return false ;
|
|
pfrRaw->Reset() ;
|
|
// visualizzo il grezzo e ne attivo i pezzi
|
|
if ( ! m_pGeomDB->SetStatus( nRawId, GDB_ST_ON))
|
|
return false ;
|
|
if ( ! SwapRawPartParts( nRawId, true))
|
|
return false ;
|
|
// se fase di origine non definita o uguale alla corrente, esco con successo
|
|
if ( nSouPhase == 0 || nSouPhase == m_nCurrPhase)
|
|
return true ;
|
|
// copio il posizionamento
|
|
Disposition* pSouDisp = GetDisposition( m_pGeomDB->GetUserObj( GetPhaseDisposition( nSouPhase))) ;
|
|
Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( GetPhaseDisposition( m_nCurrPhase))) ;
|
|
if ( pSouDisp == nullptr || pDisp == nullptr)
|
|
return false ;
|
|
for ( int i = 0 ; ; ++ i) {
|
|
int nId ; int nType ; Point3d ptPos ; int nFlag ;
|
|
if ( pSouDisp->GetMoveRawData( i, nId, nType, ptPos, nFlag)) {
|
|
if ( nId == nRawId) {
|
|
switch ( nType) {
|
|
case MoveRawData::COR :
|
|
pDisp->MoveToCornerRawPart( nRawId, ptPos, nFlag, true, false) ;
|
|
break ;
|
|
case MoveRawData::CEN :
|
|
pDisp->MoveToCenterRawPart( nRawId, ptPos, nFlag, true, false) ;
|
|
break ;
|
|
case MoveRawData::ROT :
|
|
pDisp->ApplyRotationToRawPart( nRawId, ptPos.x, ptPos.y, ptPos.z, true) ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
break ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::VerifyRawPartPhase( int nRawId, int nPhase) const
|
|
{
|
|
// verifico validità e recupero fasi in cui è presente
|
|
INTVECTOR vPhase ;
|
|
if ( ! GetRawPartPhases( nRawId, vPhase))
|
|
return false ;
|
|
// verifico presenza nella fase indicata
|
|
return ( find( vPhase.begin(), vPhase.end(), nPhase) != vPhase.end()) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::RemoveRawPartFromCurrPhase( int nRawId)
|
|
{
|
|
// verifico validità e recupero fasi in cui è presente
|
|
INTVECTOR vPhase ;
|
|
if ( ! GetRawPartPhases( nRawId, vPhase))
|
|
return false ;
|
|
// se non appartiene alla fase corrente, non devo fare alcunché
|
|
auto iIter = find( vPhase.begin(), vPhase.end(), m_nCurrPhase) ;
|
|
if ( iIter == vPhase.end())
|
|
return true ;
|
|
// se appartiene solo a questa fase, lo elimino
|
|
if ( vPhase.size() == 1)
|
|
RemoveRawPart( nRawId) ;
|
|
// altrimenti
|
|
else {
|
|
// tolgo dalla disposizione corrente gli eventuali movimenti registrati di questo grezzo
|
|
Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( GetPhaseDisposition( m_nCurrPhase))) ;
|
|
if ( pDisp != nullptr)
|
|
pDisp->RemoveRawPart( nRawId) ;
|
|
// aggiorno l'elenco delle fasi di appartenenza
|
|
vPhase.erase( iIter) ;
|
|
m_pGeomDB->SetInfo( nRawId, MACH_RAW_PHASE, vPhase) ;
|
|
// tolgo i pezzi dal grezzo e lo nascondo
|
|
SwapRawPartParts( nRawId, false) ;
|
|
m_pGeomDB->SetStatus( nRawId, GDB_ST_OFF) ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::RemoveRawPart( int nRawId)
|
|
{
|
|
// verifica validità grezzo
|
|
if ( ! VerifyRawPart( nRawId))
|
|
return false ;
|
|
// tolgo dalle disposizioni in cui compare gli eventuali movimenti registrati di questo grezzo
|
|
for ( int nPhase = 1 ; nPhase <= m_nPhasesCount ; ++ nPhase) {
|
|
Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( GetPhaseDisposition( nPhase))) ;
|
|
if ( pDisp != nullptr)
|
|
pDisp->RemoveRawPart( nRawId) ;
|
|
}
|
|
// devo estrarre i pezzi e riportarli in lista generale
|
|
SwapRawPartParts( nRawId, false) ;
|
|
// cancello il grezzo
|
|
m_pGeomDB->Erase( nRawId) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::VerifyRawPart( int nRawId, bool bLinkedAllowed) const
|
|
{
|
|
// se il grezzo fa parte del gruppo dei grezzi, va bene
|
|
int nRawGroupId = GetCurrRawGroupId() ;
|
|
if ( nRawGroupId != GDB_ID_NULL && m_pGeomDB->GetParentId( nRawId) == nRawGroupId)
|
|
return true ;
|
|
// se consentito linkaggio ed il grezzo è linkato ad un gruppo della macchina corrente, va bene
|
|
if ( bLinkedAllowed) {
|
|
Machine* pMch = GetCurrMachine() ;
|
|
if ( pMch != nullptr && pMch->IsLinkedRawPart( nRawId))
|
|
return true ;
|
|
}
|
|
// altrimenti errore
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::RotateRawPart( int nRawId, const Vector3d& vtAx, double dAngRotDeg)
|
|
{
|
|
// recupero l'oggetto disposizione corrente
|
|
Disposition* pDisp = ::GetDisposition( m_pGeomDB->GetUserObj( m_nCurrDispId)) ;
|
|
if ( pDisp == nullptr)
|
|
return false ;
|
|
// eseguo l'operazione
|
|
if ( ! pDisp->RotateRawPart( nRawId, vtAx, dAngRotDeg)) {
|
|
LOG_ERROR( GetEMkLogger(), "Error on RotateRawPart") ;
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::MoveToCornerRawPart( int nRawId, const Point3d& ptP, int nFlag)
|
|
{
|
|
// recupero l'oggetto disposizione corrente
|
|
Disposition* pDisp = ::GetDisposition( m_pGeomDB->GetUserObj( m_nCurrDispId)) ;
|
|
if ( pDisp == nullptr)
|
|
return false ;
|
|
// eseguo l'operazione
|
|
if ( ! pDisp->MoveToCornerRawPart( nRawId, ptP, nFlag)) {
|
|
LOG_ERROR( GetEMkLogger(), "Error on MoveToCornerRawPart") ;
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::MoveToCenterRawPart( int nRawId, const Point3d& ptP, int nFlag)
|
|
{
|
|
// recupero l'oggetto disposizione corrente
|
|
Disposition* pDisp = ::GetDisposition( m_pGeomDB->GetUserObj( m_nCurrDispId)) ;
|
|
if ( pDisp == nullptr)
|
|
return false ;
|
|
// eseguo l'operazione
|
|
if ( ! pDisp->MoveToCenterRawPart( nRawId, ptP, nFlag)) {
|
|
LOG_ERROR( GetEMkLogger(), "Error on MoveToCenterRawPart") ;
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::MoveRawPart( int nRawId, const Vector3d& vtMove)
|
|
{
|
|
// recupero l'oggetto disposizione corrente
|
|
Disposition* pDisp = ::GetDisposition( m_pGeomDB->GetUserObj( m_nCurrDispId)) ;
|
|
if ( pDisp == nullptr)
|
|
return false ;
|
|
// eseguo l'operazione
|
|
if ( ! pDisp->MoveRawPart( nRawId, vtMove)) {
|
|
LOG_ERROR( GetEMkLogger(), "Error on MoveRawPart") ;
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::SetRawPartCenter( int nRawId)
|
|
{
|
|
// recupero il solido
|
|
int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
|
|
const ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nRawSolId)) ;
|
|
if ( pStm == nullptr)
|
|
return false ;
|
|
// recupero il punto centro, se non esiste lo creo
|
|
int nGPntId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_CENTER) ;
|
|
if ( nGPntId == GDB_ID_NULL) {
|
|
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
|
|
nGPntId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pGeoPnt)) ;
|
|
m_pGeomDB->SetName( nGPntId, MACH_RAW_CENTER) ;
|
|
Color cCol ;
|
|
if ( m_pGeomDB->GetCalcMaterial( nRawSolId, cCol))
|
|
m_pGeomDB->SetMaterial( nGPntId, cCol) ;
|
|
}
|
|
IGeoPoint3d* pGeoPnt = GetGeoPoint3d( m_pGeomDB->GetGeoObj( nGPntId)) ;
|
|
if ( pGeoPnt == nullptr)
|
|
return false ;
|
|
// calcolo il valore del centro
|
|
Point3d ptCen ;
|
|
if ( ! pStm->GetCentroid( ptCen))
|
|
return false ;
|
|
// aggiorno e imposto modo a standard
|
|
return ( pGeoPnt->Set( ptCen) && m_pGeomDB->SetMode( nGPntId, GDB_MD_STD)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::ResetRawPartCenter( int nRawId)
|
|
{
|
|
// recupero il punto centro
|
|
int nGPntId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_CENTER) ;
|
|
if ( nGPntId == GDB_ID_NULL)
|
|
return true ;
|
|
// imposto modo a bloccato
|
|
return m_pGeomDB->SetMode( nGPntId, GDB_MD_HIDDEN) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::GetRawPartCenter( int nRawId, Point3d& ptCen)
|
|
{
|
|
// verifica validità grezzo
|
|
if ( ! VerifyRawPart( nRawId))
|
|
return false ;
|
|
// cerco di recuperare l'oggetto
|
|
int nGPntId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_CENTER) ;
|
|
// ne verifico la validità
|
|
int nMode ;
|
|
if ( nGPntId == GDB_ID_NULL ||
|
|
! m_pGeomDB->GetMode( nGPntId, nMode) || nMode != GDB_MD_STD) {
|
|
// provo a crearlo
|
|
SetRawPartCenter( nRawId) ;
|
|
nGPntId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_CENTER) ;
|
|
// se non riesco, errore
|
|
if ( nGPntId == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
// ne recupero il riferimento globale
|
|
Frame3d frGPnt ;
|
|
if ( ! m_pGeomDB->GetGlobFrame( nGPntId, frGPnt))
|
|
return false ;
|
|
// recupero il punto
|
|
IGeoPoint3d* pGeoPnt = GetGeoPoint3d( m_pGeomDB->GetGeoObj( nGPntId)) ;
|
|
if ( pGeoPnt == nullptr)
|
|
return false ;
|
|
ptCen = pGeoPnt->GetPoint() ;
|
|
ptCen.ToGlob( frGPnt) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
MachMgr::GetRawPartBBox( int nRawId, BBox3d& b3Raw)
|
|
{
|
|
// verifica validità grezzo
|
|
if ( ! VerifyRawPart( nRawId))
|
|
return false ;
|
|
// recupero solido del grezzo
|
|
int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
|
|
return m_pGeomDB->GetGlobalBBox( nRawSolidId, b3Raw) ;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
static bool
|
|
AssociateSurfs( IGeomDB* pGeomDB, int nSurfUpId, int nSurfDownId, vector<pair<int,int>>& vRawSurfs)
|
|
{
|
|
// vRawSurfs contiene tutte le coppie ( id regioneUp, id regioneDown) che definiscono i nuovi grezzi
|
|
vRawSurfs.clear() ;
|
|
|
|
int nUpCnt = ExeSurfFrChunkCount( nSurfUpId) ;
|
|
int nDownCnt = ExeSurfFrChunkCount( nSurfDownId) ;
|
|
// se non sono stati creati più grezzi
|
|
if ( nUpCnt == 1 || nDownCnt == 1) {
|
|
vRawSurfs.emplace_back( nSurfUpId, nSurfDownId) ;
|
|
return true ;
|
|
}
|
|
|
|
int nUpFirstId = ExeExplodeSurface( nSurfUpId, &nUpCnt) ;
|
|
int nDownFirstId = ExeExplodeSurface( nSurfDownId, &nDownCnt) ;
|
|
|
|
// ad ogni chunk della regione up associo i chunk corrispondenti della regione down
|
|
INTVECTOR vChunks( nUpCnt, GDB_ID_NULL) ;
|
|
for ( int nIdD = nDownFirstId ; nIdD < nDownFirstId + nDownCnt ; nIdD ++) {
|
|
ISurfFlatRegion* pSfrD = GetSurfFlatRegion( pGeomDB->GetGeoObj( nIdD)) ;
|
|
if ( pSfrD == nullptr)
|
|
return false ;
|
|
BBox3d bBoxD ; ExeGetBBox( nIdD, BBF_STANDARD, bBoxD) ;
|
|
// inidividuo il chunk della superficie up che interagisce maggiormente con il chunk corrente della superficie down
|
|
int k = -1 ;
|
|
double dMaxArea = -1 ;
|
|
for ( int j = 0 ; j < nUpCnt ; j ++) {
|
|
BBox3d bBoxU ; ExeGetBBox( nUpFirstId + j, BBF_STANDARD, bBoxU) ;
|
|
if ( bBoxU.OverlapsXY( bBoxD)) {
|
|
PtrOwner<ISurfFlatRegion> pSfrU( CloneSurfFlatRegion( pGeomDB->GetGeoObj( nUpFirstId + j))) ;
|
|
if ( IsNull( pSfrU))
|
|
return false ;
|
|
// le due superfici sono nello stesso frame
|
|
pSfrU->Intersect( *pSfrD) ;
|
|
double dArea = -1 ; pSfrU->GetArea( dArea) ;
|
|
if ( dArea > dMaxArea) {
|
|
k = j ;
|
|
dMaxArea = dArea ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// aggiorno le superfici con l'associazione trovata
|
|
if ( k == -1)
|
|
return false ;
|
|
if ( vChunks[k] == GDB_ID_NULL)
|
|
vChunks[k] = nIdD ;
|
|
else {
|
|
ExeSurfFrAdd( vChunks[k], nIdD) ;
|
|
ExeErase( {nIdD}) ;
|
|
}
|
|
}
|
|
|
|
// controllo per ogni chunk della superficie up il corrispondente della nuova superficie down
|
|
for ( int i = 0 ; i < nUpCnt ; i ++) {
|
|
ISurfFlatRegion* pSfrU = GetSurfFlatRegion( pGeomDB->GetGeoObj( nUpFirstId + i)) ;
|
|
if ( pSfrU == nullptr)
|
|
return false ;
|
|
BBox3d bBoxU ; ExeGetBBox( nUpFirstId + i, BBF_STANDARD, bBoxU) ;
|
|
// individuo il chunk della superficie down che interagisce maggiormente con il chunk corrente della superficie up
|
|
int k = -1 ;
|
|
double dMaxArea = -1 ;
|
|
for ( int j = 0 ; j < int( vChunks.size()) ; j ++) {
|
|
BBox3d bBoxD ; ExeGetBBox( vChunks[j], BBF_STANDARD, bBoxD) ;
|
|
// se i box interferiscono allora verifico di quanto si sovrappongono le due regioni
|
|
if ( bBoxD.OverlapsXY( bBoxU)) {
|
|
PtrOwner<ISurfFlatRegion> pSfrD( CloneSurfFlatRegion( pGeomDB->GetGeoObj( vChunks[j]))) ;
|
|
if ( IsNull( pSfrD))
|
|
return false ;
|
|
pSfrD->Intersect( *pSfrU) ;
|
|
double dArea = -1 ; pSfrD->GetArea( dArea) ;
|
|
if ( dArea > dMaxArea) {
|
|
k = j ;
|
|
dMaxArea = dArea ;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( k == -1)
|
|
return false ;
|
|
// se è la stessa associazione individuata da vChunks allora aggiorno il vettore finale dei grezzi
|
|
if ( k == i)
|
|
vRawSurfs.emplace_back( nUpFirstId + i, vChunks[i]) ;
|
|
else {
|
|
// altrimenti unisco le regioni associate appena individuate sia per la superficie up sia per la down
|
|
ExeSurfFrAdd( nUpFirstId + k, nUpFirstId + i) ;
|
|
ExeErase( {nUpFirstId + i}) ;
|
|
ExeSurfFrAdd( vChunks[k], vChunks[i]) ;
|
|
ExeErase( {vChunks[i]}) ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
MachMgr::SplitFlatRawPartWithMachinings( int nRawId, const INTVECTOR& vMchId)
|
|
{
|
|
if ( m_pGeomDB == nullptr)
|
|
return GDB_ID_NULL ;
|
|
|
|
// verifico sia un grezzo e non appartenga alla fase corrente
|
|
if ( ! VerifyRawPart( nRawId) || VerifyRawPartPhase( nRawId, m_nCurrPhase))
|
|
return GDB_ID_NULL ;
|
|
|
|
// disabilito eventuale registrazione comandi EXE (riabilitazione automatica)
|
|
CmdLogOff cmdLogOff ;
|
|
|
|
// recupero alcuni dati del grezzo
|
|
// il solido del grezzo
|
|
int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
|
|
if ( nRawSolId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// il box del grezzo
|
|
BBox3d b3Raw ;
|
|
if ( ! m_pGeomDB->GetGlobalBBox( nRawSolId, b3Raw))
|
|
return GDB_ID_NULL ;
|
|
double dHeight = b3Raw.GetMax().z - b3Raw.GetMin().z ;
|
|
// il colore del grezzo
|
|
Color cCol = AQUA ;
|
|
m_pGeomDB->GetCalcMaterial( nRawSolId, cCol) ;
|
|
// il riferimento del grezzo
|
|
Frame3d frRaw ;
|
|
if ( ! m_pGeomDB->GetGroupGlobFrame( nRawId, frRaw))
|
|
return GDB_ID_NULL ;
|
|
// recupero il contorno
|
|
int nOutCrvId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_OUTLINE) ;
|
|
if ( nOutCrvId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
|
|
// creo le regioni inferiore e superiore del grezzo da aggiornare con le lavorazioni
|
|
int nSfrDownId = GDB_ID_NULL, nSfrUpId = GDB_ID_NULL ;
|
|
int nSfrDownOrigId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_DOWN_REG) ;
|
|
int nSfrUpOrigId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_UP_REG) ;
|
|
if ( nSfrDownOrigId == GDB_ID_NULL || nSfrUpOrigId == GDB_ID_NULL) {
|
|
// se le regioni del grezzo di partenza non sono definite, le creo a partire dall'outline
|
|
nSfrDownId = ExeCreateSurfFlatRegion( nRawId, {nOutCrvId}, nullptr) ;
|
|
if ( nSfrDownId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
nSfrUpId = ExeCopyGlob( nSfrDownId, nRawId, GDB_LAST_SON) ;
|
|
if ( nSfrUpId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
ExeMove( { nSfrUpId}, dHeight * Z_AX, RTY_LOC) ;
|
|
}
|
|
else {
|
|
nSfrDownId = ExeCopyGlob( nSfrDownOrigId, nRawId, GDB_LAST_SON) ;
|
|
nSfrUpId = ExeCopyGlob( nSfrUpOrigId, nRawId, GDB_LAST_SON) ;
|
|
if ( nSfrDownId == GDB_ID_NULL || nSfrUpId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
}
|
|
|
|
// se esiste il kerf, ne creo la regione
|
|
PtrOwner<ISurfFlatRegion> pSfrKerf ;
|
|
int nKerfId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_KERF) ;
|
|
ICurve* pKerfCrv = GetCurve( m_pGeomDB->GetGeoObj( nKerfId)) ;
|
|
if ( pKerfCrv != nullptr) {
|
|
SurfFlatRegionByContours SfrCntr ;
|
|
SfrCntr.AddCurve( pKerfCrv->Clone()) ;
|
|
pSfrKerf.Set( SfrCntr.GetSurf()) ;
|
|
if ( IsNull( pSfrKerf))
|
|
return GDB_ID_NULL ;
|
|
}
|
|
|
|
// recupero le regioni delle lavorazioni
|
|
INTVECTOR vMchRRegUp ;
|
|
INTVECTOR vMchRRegDown ;
|
|
for ( auto nMchId : vMchId) {
|
|
// recupero gruppo preview lavorazioni nella lavorazione
|
|
int nPVGrp = m_pGeomDB->GetFirstNameInGroup( nMchId, MCH_PV) ;
|
|
if ( nPVGrp == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// se vuoto, cerco il rimando al preview nel pezzo
|
|
if ( m_pGeomDB->GetGroupObjs( nPVGrp) == 0 &&
|
|
! m_pGeomDB->GetInfo( nPVGrp, MCH_PV_KEY_RELOCATE, nPVGrp))
|
|
return GDB_ID_NULL ;
|
|
// ciclo sui percorsi utensile (CL)
|
|
int nClId = m_pGeomDB->GetFirstGroupInGroup( nPVGrp) ;
|
|
while ( nClId != GDB_ID_NULL) {
|
|
// lavorazioni per regione inferiore
|
|
int nCrDownId = m_pGeomDB->GetFirstNameInGroup( nClId, MCH_PV_DOWN_RAWCUT) ;
|
|
// se non esiste la regione inferiore la lavorazione non è passante quindi può essere ignorata
|
|
if ( nCrDownId != GDB_ID_NULL) {
|
|
while ( nCrDownId != GDB_ID_NULL) {
|
|
vMchRRegDown.emplace_back( nCrDownId) ;
|
|
nCrDownId = m_pGeomDB->GetNextName( nCrDownId, MCH_PV_DOWN_RAWCUT) ;
|
|
}
|
|
// lavorazioni per regione superiore
|
|
int nCrUpId = m_pGeomDB->GetFirstNameInGroup( nClId, MCH_PV_UP_RAWCUT) ;
|
|
while ( nCrUpId != GDB_ID_NULL) {
|
|
vMchRRegUp.emplace_back( nCrUpId) ;
|
|
nCrUpId = m_pGeomDB->GetNextName( nCrUpId, MCH_PV_UP_RAWCUT) ;
|
|
}
|
|
}
|
|
// passo al successivo percorso utensile
|
|
nClId = m_pGeomDB->GetNextGroup( nClId) ;
|
|
}
|
|
}
|
|
|
|
// sottraggo le lavorazioni alle superfici del grezzo
|
|
for ( auto nMchRReg : vMchRRegUp)
|
|
ExeSurfFrSubtract( nSfrUpId, nMchRReg) ;
|
|
for ( auto nMchRReg : vMchRRegDown)
|
|
ExeSurfFrSubtract( nSfrDownId, nMchRReg) ;
|
|
|
|
// classifico i chunks della regione up e down per individuare le regioni che definiscono i nuovi grezzi
|
|
vector<pair<int,int>> vSurfRaws ;
|
|
AssociateSurfs( m_pGeomDB, nSfrUpId, nSfrDownId, vSurfRaws) ;
|
|
|
|
// creo i grezzi risultanti
|
|
INTVECTOR vNewIds ;
|
|
for ( int i = 0 ; i < int( vSurfRaws.size()) ; i++) {
|
|
|
|
// aggiungo il grezzo
|
|
int nId = AddRawPart( vSurfRaws[i].first, vSurfRaws[i].second, dHeight, cCol) ;
|
|
m_pGeomDB->Erase( vSurfRaws[i].first) ;
|
|
m_pGeomDB->Erase( vSurfRaws[i].second) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
vNewIds.emplace_back( nId) ;
|
|
|
|
// imposto lo stato del contorno di questo grezzo come quello del grezzo di partenza
|
|
int nStat = GDB_ST_ON ;
|
|
if ( m_pGeomDB->GetStatus( nOutCrvId, nStat) && nStat == GDB_ST_OFF)
|
|
m_pGeomDB->SetStatus( m_pGeomDB->GetFirstNameInGroup( nId, MACH_RAW_OUTLINE), nStat) ;
|
|
// assegno la fase al gruppo
|
|
m_pGeomDB->SetInfo( nId, MACH_RAW_PHASE, m_nCurrPhase) ;
|
|
// se esiste il kerf uso questa curva per creare il kerf del nuovo grezzo
|
|
if ( ! IsNull( pSfrKerf)) {
|
|
// riferimento del nuovo grezzo
|
|
Frame3d frNewRaw ;
|
|
if ( ! m_pGeomDB->GetGroupGlobFrame( nId, frNewRaw))
|
|
return GDB_ID_NULL ;
|
|
// considero il nuovo kerf come la regione superiore del nuovo grezzo
|
|
int nSfrUpId = m_pGeomDB->GetFirstNameInGroup( nId, MACH_RAW_UP_REG) ;
|
|
if ( nSfrUpId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
PtrOwner<ISurfFlatRegion> pSfrNewKerf( CloneSurfFlatRegion( m_pGeomDB->GetGeoObj( nSfrUpId))) ;
|
|
if ( IsNull( pSfrNewKerf))
|
|
return GDB_ID_NULL ;
|
|
// porto nello stesso riferimento del grezzo originale
|
|
pSfrNewKerf->LocToLoc( frNewRaw, frRaw) ;
|
|
// la limito con la regione di kerf precedente ( va bene anche se fallisce)
|
|
pSfrNewKerf->Intersect( *pSfrKerf) ;
|
|
// se risultato non vuoto
|
|
if ( pSfrNewKerf->IsValid()) {
|
|
// la porto dal riferimento del grezzo originale al riferimento di questo grezzo
|
|
pSfrNewKerf->LocToLoc( frRaw, frNewRaw) ;
|
|
// recupero il contorno esterno del chunk più grande e lo inserisco come kerf del nuovo grezzo
|
|
double dAreaMax = -1 ;
|
|
int nKMax = 0 ;
|
|
for ( int k = 0 ; k < pSfrNewKerf->GetChunkCount() ; k ++) {
|
|
PtrOwner<ISurfFlatRegion> pSfrChunk( pSfrNewKerf->CloneChunk( k)) ;
|
|
double dArea = -1 ; pSfrChunk->GetGrossArea( dArea) ;
|
|
if ( dArea > dAreaMax) {
|
|
nKMax = k ;
|
|
dAreaMax = dArea ;
|
|
}
|
|
}
|
|
PtrOwner<ICurve> pCrv( pSfrNewKerf->GetLoop( nKMax, 0)) ;
|
|
if ( IsNull( pCrv))
|
|
return GDB_ID_NULL ;
|
|
int nNewKerfId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nId, Release( pCrv)) ;
|
|
if ( nNewKerfId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
m_pGeomDB->CopyMaterial( nKerfId, nNewKerfId) ;
|
|
m_pGeomDB->SetName( nNewKerfId, MACH_RAW_KERF) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// cancello le regioni usate per i conti
|
|
m_pGeomDB->Erase( nSfrUpId) ;
|
|
m_pGeomDB->Erase( nSfrDownId) ;
|
|
// verifico esista almeno un nuovo grezzo
|
|
if ( vNewIds.empty())
|
|
return GDB_ID_NULL ;
|
|
|
|
// inserisco i pezzi del grezzo originale nei nuovi grezzi
|
|
int nGroupId = m_pGeomDB->GetFirstGroupInGroup( nRawId) ;
|
|
while ( nGroupId != GDB_ID_NULL) {
|
|
for ( auto nNewId : vNewIds) {
|
|
// copio il gruppo
|
|
int nNewGroupId = m_pGeomDB->CopyGlob( nGroupId, GDB_ID_NULL, nNewId) ;
|
|
// scambio con pezzo
|
|
int nPartId = SwapRawPartPart( nNewGroupId, true) ;
|
|
// verifico se il pezzo sta nel grezzo
|
|
int nLayerId = m_pGeomDB->GetFirstNameInGroup( nPartId, NST_PARTREG_LAYER) ;
|
|
if ( nLayerId == GDB_ID_NULL || m_pGeomDB->GetGdbType( nLayerId) != GDB_TY_GROUP)
|
|
nLayerId = m_pGeomDB->GetFirstGroupInGroup( nPartId) ;
|
|
// cerco la regione del pezzo
|
|
int nEntId = m_pGeomDB->GetFirstInGroup( nLayerId) ;
|
|
while ( nEntId != GDB_ID_NULL) {
|
|
int nEntGeoType = m_pGeomDB->GetGeoType( nEntId) ;
|
|
if ( nEntGeoType == SRF_FLATRGN)
|
|
break ;
|
|
nEntId = m_pGeomDB->GetNext( nEntId) ;
|
|
}
|
|
if ( nEntId != GDB_ID_NULL) {
|
|
// verifico se è interna al grezzo
|
|
int nOutCrvId = m_pGeomDB->GetFirstNameInGroup( nNewId, MACH_RAW_OUTLINE) ;
|
|
BBox3d b3Raw ; m_pGeomDB->GetGlobalBBox( nOutCrvId, b3Raw) ;
|
|
double dRawDiam = 0 ; b3Raw.GetDiameter( dRawDiam) ;
|
|
BBox3d b3Part ; m_pGeomDB->GetGlobalBBox( nEntId, b3Part) ;
|
|
double dPartDiam = 0 ; b3Part.GetDiameter( dPartDiam) ;
|
|
if ( dRawDiam > 0.9 * dPartDiam) {
|
|
int nSfrUp = m_pGeomDB->GetFirstNameInGroup( nNewId, MACH_RAW_UP_REG) ;
|
|
if ( ! ExeSurfFrTestExternal( nSfrUp, nEntId, EPS_SMALL))
|
|
break ;
|
|
}
|
|
}
|
|
|
|
// altrimenti scambio pezzo ed elimino gruppo
|
|
nNewGroupId = SwapRawPartPart( nPartId, false) ;
|
|
m_pGeomDB->Erase( nNewGroupId) ;
|
|
}
|
|
nGroupId = m_pGeomDB->GetNextGroup( nGroupId) ;
|
|
}
|
|
|
|
return vNewIds[0] ;
|
|
}
|