EgtMachKernel :

- aggiunto ricalcolo RawOutline dopo rotazione dello stesso attorno ad asse diverso da Z.
This commit is contained in:
Dario Sassi
2026-05-15 18:33:27 +02:00
parent 8c59084a99
commit db30954eb3
2 changed files with 122 additions and 96 deletions
+1
View File
@@ -538,6 +538,7 @@ class MachMgr : public IMachMgr
int AddRawPart( int nSurfUpId, int nSurfDownId, double dHeight, Color cCol) ;
bool SetRawPartCenter( int nRawId) ;
bool ResetRawPartCenter( int nRawId) ;
bool UpdateRawOutline( int nRawId) ;
// Parts
bool SwapParts( bool bToRawPart) ;
bool SwapRawPartParts( int nRawId, bool bToRawPart) ;
+121 -96
View File
@@ -29,6 +29,7 @@
#include "/EgtDev/Include/EGkStmStandard.h"
#include "/EgtDev/Include/EGkStmFromCurves.h"
#include "/EgtDev/Include/EGkSurfBezier.h"
#include "/EgtDev/Include/EGkSurfLocal.h"
#include "/EgtDev/Include/EGkCAvSilhouetteSurfTm.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include "/EgtDev/Include/EXeConst.h"
@@ -506,102 +507,7 @@ MachMgr::AddRawPart( int nSurfId, Color cCol)
// 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) ;
}
bOk = bOk && UpdateRawOutline( nRawId) ;
// se qualcosa è andato storto, cancello tutto
if ( ! bOk) {
m_pGeomDB->Erase( nRawId) ;
@@ -1001,6 +907,9 @@ MachMgr::RotateRawPart( int nRawId, const Vector3d& vtAx, double dAngRotDeg)
LOG_ERROR( GetEMkLogger(), "Error on RotateRawPart") ;
return false ;
}
// se rotazione non è attorno a Z, aggiorno la curva di outline
if ( abs( dAngRotDeg) > EPS_ANG_ZERO && ! vtAx.IsZ())
UpdateRawOutline( nRawId) ;
return true ;
}
@@ -1139,6 +1048,122 @@ MachMgr::GetRawPartBBox( int nRawId, BBox3d& b3Raw)
return m_pGeomDB->GetGlobalBBox( nRawSolidId, b3Raw) ;
}
//----------------------------------------------------------------------------
bool
MachMgr::UpdateRawOutline( int nRawId)
{
// cerco il solido del grezzo
int nSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
if ( nSolId == GDB_ID_NULL)
return false ;
// creo la curva
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo))
return false ;
// recupero la superficie trimesh in globale
SurfLocal pStmG( m_pGeomDB, nSolId, GLOB_FRM) ;
const ISurfTriMesh* pStm = GetSurfTriMesh( pStmG) ;
if ( pStm == nullptr)
return false ;
// recupero l'ingombro della superficie
BBox3d b3Srf ;
pStm->GetLocalBBox( b3Srf) ;
// ne calcolo la silhouette secondo Z+ globale
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
return false ;
}
// rimuovo eventuale vecchia curva
int nOtlId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_OUTLINE) ;
m_pGeomDB->Erase( nOtlId) ;
// inserisco la curva composita nel DB
Frame3d frRaw ;
m_pGeomDB->GetGroupGlobFrame( nRawId, frRaw) ;
pCrvCompo->ToLoc( frRaw) ;
int nCrvId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pCrvCompo)) ;
if ( nCrvId == GDB_ID_NULL)
return false ;
// assegno il nome alla curva
m_pGeomDB->SetName( nCrvId, MACH_RAW_OUTLINE) ;
// assegno il colore alla curva
Color cCol ;
if ( m_pGeomDB->GetMaterial( nSolId, cCol))
m_pGeomDB->SetMaterial( nCrvId, cCol) ;
return true ;
}
//---------------------------------------------------------------------------
static bool
AssociateSurfs( IGeomDB* pGeomDB, int nSurfUpId, int nSurfDownId, vector<pair<int,int>>& vRawSurfs)