EgtMachKernel :

- unificazione della funzione per la correzione dell'offset 3d.
This commit is contained in:
Daniele Bariletti
2026-06-18 16:27:16 +02:00
parent f597c5769b
commit e8b547b66c
+87 -237
View File
@@ -22,7 +22,9 @@
#include "/EgtDev/Include/EGkGeoVector3d.h"
#include "/EgtDev/Include/EGkCurveLine.h"
#include "/EgtDev/Include/EGkCurveArc.h"
#include "/EgtDev/Include/EGkCurveComposite.h"
#include "/EgtDev/Include/EGkIntersLineCylinder.h"
#include "/EgtDev/Include/EGkOffsetCurve3d.h"
#include "/EgtDev/Include/EGkGeomDB.h"
#include "/EgtDev/Include/EGkLuaAux.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
@@ -601,36 +603,6 @@ Machine::LuaEmtGetBackAuxDir( lua_State* L)
return 1 ;
}
struct Cyl {
Cyl( void): frCyl( GLOB_FRM), dH( 0.), dRad( 0.) {;} ;
Cyl( const Frame3d& _frCyl, double _dH, double _dRad, double _dLinTol) :
frCyl( _frCyl), dH( _dH), dRad( _dRad) { ;}
Cyl( const Point3d& _ptBase, const Vector3d& vtZ, double _dH, double _dRad, double _dLinTol) :
dH( _dH), dRad( _dRad){
frCyl.Set( _ptBase, vtZ); }
public :
Frame3d frCyl ;
public:
double dH ;
double dRad ;
};
typedef vector<Cyl> OFFSETCYLVECT ;
//----------------------------------------------------------------------------
bool
IsPointInsideCylinder( const Point3d& ptTest, const Cyl& offCyl, double dLinTol)
{
Point3d ptTestLoc = ptTest ; ptTestLoc.ToLoc( offCyl.frCyl) ;
if ( ptTestLoc.z > offCyl.dH || ptTestLoc.z < 0)
return false ;
double dDist = ptTestLoc.x * ptTestLoc.x + ptTestLoc.y * ptTestLoc.y ;
double dRadSq = ( offCyl.dRad - dLinTol) * ( offCyl.dRad - dLinTol) ;
if ( dDist > dRadSq)
return false ;
return true ;
}
//----------------------------------------------------------------------------
int
Machine::LuaEmtAdjustConcavePartsInPath( lua_State* L)
@@ -647,218 +619,96 @@ Machine::LuaEmtAdjustConcavePartsInPath( lua_State* L)
IGeomDB* pGeomDB = m_pMchLua->m_pGeomDB ;
int nId = pGeomDB->GetFirstInGroup( nPathId) ;
int nIdCrvAux = pGeomDB->GetFirstInGroup( nAuxPathId) ;
const ICurve* pCrvAux = GetCurve( pGeomDB->GetGeoObj(nIdCrvAux)) ;
const double dLinTol = 10 * EPS_SMALL ;
#if DRAWCYL
int nParent = pGeomDB->GetParentId( nPathId) ;
int nTempLay = pGeomDB->AddGroup( GDB_ID_NULL, nParent, GLOB_FRM) ;
#endif
const ICurveComposite* pCrvAux = GetCurveComposite( pGeomDB->GetGeoObj(nIdCrvAux)) ;
if ( pCrvAux == nullptr)
return GDB_ID_NULL ;
int nFirstCrvOffset = nId ;
OFFSETSEGVEC vOffsetCrvs ;
while ( nId != GDB_ID_NULL) {
if ( pGeomDB->GetGeoType( nId) == CRV_LINE) {
int nFlag = 0 ; pGeomDB->GetInfo( nId, "Flg2", nFlag) ;
if ( nFlag == 1) {
// scorro i prossimi finchè trovo la fine della zona concava
INTINTVECTOR vLines ;
while ( nFlag == 1 && nId != GDB_ID_NULL) {
nId = pGeomDB->GetNext( nId) ;
if ( nId != GDB_ID_NULL && pGeomDB->GetGeoType( nId) == CRV_LINE) {
int nDerivedFromId = GDB_ID_NULL ;
if ( pGeomDB->GetInfo( nId, "DerivFrom", nDerivedFromId)) {
pGeomDB->GetInfo( nId, "Flg2", nFlag) ;
vLines.emplace_back( nId, nDerivedFromId) ;
}
}
}
OFFSETCYLVECT vCyl ;
// creo un cilindro della dimensione del raggio
for ( int i = 0 ; i < ssize( vLines) ; ++i) {
#if COLOR5AX
pGeomDB->SetMaterial( vLines[i].first, GREEN) ;
#endif
const IGeoVector3d* pGV = GetGeoVector3d( pGeomDB->GetGeoObj( vLines[i].second)) ;
if ( pGV == nullptr)
return false ;
Point3d ptBase = pGV->GetBase() ;
double dPar = 0 ;
if ( ! pCrvAux->GetParamAtPoint( ptBase, dPar))
return false ;
const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nId)) ;
int nParent = -1 ;
int nDerivFrom = - 1 ;
pGeomDB->GetInfo( nId, "DerivFrom", nDerivFrom) ;
const IGeoVector3d* pGV = GetGeoVector3d( pGeomDB->GetGeoObj( nDerivFrom)) ;
if ( pGV != nullptr) {
Point3d ptBase = pGV->GetBase() ;
double dPar = 0 ;
if ( pCrvAux->GetParamAtPoint( ptBase, dPar))
nParent = int( round( dPar)) - 1 ;
}
int nFlagAng = 0 ;
pGeomDB->GetInfo( nId, "FlgAng", nFlagAng) ;
vOffsetCrvs.emplace_back( pCrv->Clone(), nFlagAng, nParent) ;
}
nId = pGeomDB->GetNext( nId) ;
}
EDITCRVINFOVEC vEditInfo ;
if ( ! CalcAdjustConcavePartsInPath( pCrvAux, vOffsetCrvs, dRad, vEditInfo))
return GDB_ID_NULL ;
dPar = round( dPar) ;
if ( dPar > 0) {
Point3d ptStart, ptEnd ;
Vector3d vtHeight ;
pCrvAux->GetPointD1D2( dPar, ICurve::FROM_MINUS, ptEnd, &vtHeight) ;
pCrvAux->GetPointD1D2( dPar - 1, ICurve::FROM_MINUS, ptStart) ;
vtHeight = ptEnd - ptStart ;
double dHeight = vtHeight.Len() ;
// questa altezza dovrebbe coincidere con quella precedentemente calcolata come direzione della linea
vtHeight.Normalize() ;
vCyl.emplace_back( ptStart, vtHeight, dHeight, dRad, dLinTol) ;
#if DRAWCYL
pGeomDB->SetGridFrame( vCyl.back().frCyl) ;
int nIdCrv = ExeCreateCircle( nTempLay, ORIG, dRad, GDB_ID_GRID) ;
ExeCreateSurfTmByExtrusion( nTempLay, {nIdCrv}, Z_AX * dHeight, 0.005, GDB_ID_GRID) ;
pGeomDB->Erase( nIdCrv) ;
#endif
}
}
#if DRAWCYL
pGeomDB->SetGridFrame( GLOB_FRM) ;
#endif
// controllo l'end di ogni linea per verificare se sta nel cilindro definito da uno degli altri tratti
// controllo tutto i punti
bool bErasedSomePart = false ;
bool bCheckStart = false ;
INTINTVECTOR vInters ;
for ( int i = 0 ; i < ssize( vLines) ; ++i) {
Point3d ptStart, ptEnd ;
const ICurveLine* pCL = GetCurveLine( pGeomDB->GetGeoObj( vLines[i].first)) ;
if ( pCL == nullptr)
return false ;
pCL->GetEndPoint( ptEnd) ;
pCL->GetStartPoint( ptStart) ;
// se stanno in uno dei cilindri degli altri tratti della zona concava
bool bToErase = false ;
for ( int j = 0 ; j < ssize( vCyl) ; ++j) {
if ( i == j)
continue ;
bToErase = IsPointInsideCylinder( ptEnd, vCyl[j], dLinTol) ;
bool bStartInsideCyl = false ;
if ( bCheckStart && ! bToErase) {
bStartInsideCyl = IsPointInsideCylinder( ptStart, vCyl[j], dLinTol) ;
bToErase = bToErase || bStartInsideCyl ;
}
if ( bToErase) {
bErasedSomePart = true ;
if ( ! bStartInsideCyl)
bCheckStart = true ;
// se avevo un'interruzione nella zona da modificare, la colmo
if ( ! vInters.empty() && vInters.back().first != vLines[i-1].first) {
// aggiungo tutti i precedenti che mancano
int nLastAdded = i - ( vLines[i].first - vInters.back().first) ;
for ( int h = nLastAdded + 1 ; h < i ; ++h)
vInters.emplace_back( vLines[h].first, h) ;
}
vInters.emplace_back( vLines[i].first,i) ;
if ( ! bStartInsideCyl && i < ssize( vLines) - 1) {
vInters.emplace_back( vLines[i+1].first,i+1) ;
++i ;
}
break ;
}
}
if ( ! bToErase)
bCheckStart = false ;
}
if ( bErasedSomePart) {
// calcolo le intersezioni effettive del primo e ultimo tratto cancellati con i cilindri che li hanno cancellati
// controllo che effettivamente tutti i tratti cancellati siano consecutivi
for ( int i = 1 ; i < ssize( vInters) ; ++i) {
if ( vInters[i].first != vInters[i-1].first + 1)
return false ;
}
for ( int i = 0 ; i < ssize( vInters) ; ++i) {
#if COLOR5AX
pGeomDB->SetMaterial( vInters[i].first, YELLOW) ;
#endif
// cancello i tratti intermedi
if ( i > 0 && i < ssize( vInters) - 1) {
pGeomDB->Erase( vInters[i].first) ;
continue ;
}
// per il primo e ultimo controllo le intersezioni con tutti i cilindri
ICurveLine* pCL = GetCurveLine( pGeomDB->GetGeoObj( vInters[i].first)) ;
Point3d ptStart = pCL->GetStart() ;
Vector3d vtStart ; pCL->GetStartDir( vtStart) ;
double dLen ; pCL->GetLength( dLen) ;
double dUTrim = ( i == 0 ? INFINITO : 0) ;
Point3d ptTrim = P_INVALID ;
for ( int j = 0 ; j < ssize( vCyl) ; ++j) {
if ( vInters[i].second == j)
continue ;
Point3d ptInt1 = P_INVALID, ptInt2 = P_INVALID ;
double dU1, dU2 ;
Vector3d vtN1, vtN2 ;
if ( IntersLineCyl( ptStart, vtStart * dLen, vCyl[j].frCyl, vCyl[j].dH, vCyl[j].dRad, dU1, ptInt1, vtN1, dU2, ptInt2, vtN2)) {
bool bUpdate = ( i == 0 ? dU1 < dUTrim : dU1 > dUTrim) ;
bUpdate = bUpdate && ptInt1.IsValid() && dU1 > 0 && dU1 < 1 ;
bUpdate = bUpdate && vtN1 * vtStart < 0 ;
if ( bUpdate) {
dUTrim = dU1 ;
ptTrim = ptInt1 ;
}
bUpdate = ( i == 0 ? dU2 < dUTrim : dU2 > dUTrim) ;
bUpdate = bUpdate && ptInt2.IsValid() && dU2 > 0 && dU2 < 1 ;
bUpdate = bUpdate && vtN2 * vtStart > 0 ;
if ( bUpdate) {
dUTrim = dU2 ;
ptTrim = ptInt2 ;
}
}
}
if ( ptTrim.IsValid()) {
if ( i == 0) {
#if COLOR5AX
pGeomDB->SetMaterial( vInters[i].first, RED) ;
#endif
pCL->ModifyEnd( ptTrim) ;
double dNewLen ; pCL->GetLength( dNewLen) ;
if ( dNewLen < 0.1) {
int nPrev = pGeomDB->GetPrev( vInters[0].first) ;
pGeomDB->Erase( vInters[0].first) ;
vInters[0].first = nPrev ;
#if COLOR5AX
pGeomDB->SetMaterial( nPrev, RED) ;
#endif
ICurveLine* pCLPrev = GetCurveLine( pGeomDB->GetGeoObj( nPrev)) ;
pCLPrev->ModifyEnd( ptTrim) ;
}
CamData* camData = GetCamData( pGeomDB->GetUserObj( vInters[0].first)) ;
camData->SetEndPoint( ptTrim) ;
}
else {
#if COLOR5AX
pGeomDB->SetMaterial( vInters[i].first, RED) ;
#endif
pCL->ModifyStart( ptTrim) ;
double dNewLen ; pCL->GetLength( dNewLen) ;
if ( dNewLen < 0.1) {
int nNext = pGeomDB->GetNext( vInters[i].first) ;
pGeomDB->Erase( vInters[i].first) ;
vInters[i].first = nNext ;
#if COLOR5AX
pGeomDB->SetMaterial( nNext, RED) ;
#endif
ICurveLine* pCLNext = GetCurveLine( pGeomDB->GetGeoObj( nNext)) ;
pCLNext->ModifyStart( ptTrim) ;
}
}
}
}
// giunto questi due punti
ICurveLine* pCLprev = GetCurveLine( pGeomDB->GetGeoObj( vInters[0].first)) ;
Point3d ptIni = pCLprev->GetEnd() ;
ICurveLine* pCLnext = GetCurveLine( pGeomDB->GetGeoObj( vInters.back().first)) ;
Point3d ptFin = pCLnext->GetStart() ;
const CamData* camDataPrev = GetCamData( pGeomDB->GetUserObj( vInters[0].first)) ;
const CamData* camDataNext = GetCamData( pGeomDB->GetUserObj( vInters.back().first)) ;
Vector3d vtTool = Media( camDataPrev->GetToolDir(), camDataNext->GetToolDir()) ;
Vector3d vtCorr = Media( camDataPrev->GetCorrDir(), camDataNext->GetCorrDir()) ;
Vector3d vtAux = Media( camDataPrev->GetAuxDir(), camDataNext->GetAuxDir()) ;
double dFeed = camDataPrev->GetFeed() ;
int nFlag = camDataPrev->GetFlag() ;
int nFlag2 = camDataPrev->GetFlag2() ;
bool bToolShow = camDataPrev->GetToolShow() ;
AddLinearMove( ptIni, ptFin, pGeomDB, nPathId, vtTool, vtCorr, vtAux, dFeed, nFlag, nFlag2, bToolShow, vInters[0].first) ;
}
nId = vLines.back().first ;
// applico le modifiche calcolate
for ( int i = 0 ; i < ssize( vEditInfo) ; ++i) {
if ( vEditInfo[i].nFlag == EditCrvInfo::NOEDIT)
continue ;
else if ( vEditInfo[i].nFlag == EditCrvInfo::DEL) {
pGeomDB->Erase( nFirstCrvOffset + i) ;
}
else if ( vEditInfo[i].nFlag == EditCrvInfo::EDIT) {
if ( vEditInfo[i].ptStart.IsValid()) {
ICurveLine* pCL = GetCurveLine( pGeomDB->GetGeoObj( nFirstCrvOffset + i)) ;
pCL->ModifyStart( vEditInfo[i].ptStart) ;
}
if ( vEditInfo[i].ptEnd.IsValid()) {
ICurveLine* pCL = GetCurveLine( pGeomDB->GetGeoObj( nFirstCrvOffset + i)) ;
pCL->ModifyEnd( vEditInfo[i].ptEnd) ;
CamData* camData = GetCamData( pGeomDB->GetUserObj( nFirstCrvOffset + i)) ;
camData->SetEndPoint( vEditInfo[i].ptEnd) ;
}
}
nId = m_pMchLua->m_pGeomDB->GetNext( nId) ;
}
// scorro tutto il vettore delle linee di offset e unisco aggiungendo una linea dove ne ho cancellate
for ( int i = 0 ; i < ssize( vEditInfo) - 1 ; ++i) {
if ( vEditInfo[i].nFlag == EditCrvInfo::DEL || ( vEditInfo[i].nFlag == EditCrvInfo::NOEDIT))
continue ;
int nPrevId = nFirstCrvOffset + i ;
int c = i + 1 ;
// scorro finché trovo la successiva modificata
while ( c < ssize( vEditInfo) && vEditInfo[c].nFlag == EditCrvInfo::DEL || vEditInfo[c].nFlag == EditCrvInfo::NOEDIT)
++c ;
if ( vEditInfo[c].nFlag != EditCrvInfo::EDIT)
return GDB_ID_NULL ;
int nNextId = nFirstCrvOffset + c ;
Point3d ptEndCurr, ptStartNext ;
if ( vEditInfo[i].ptEnd.IsValid())
ptEndCurr = vEditInfo[i].ptEnd ;
else
vOffsetCrvs[i].pCrv->GetEndPoint( ptEndCurr) ;
if ( vEditInfo[c].ptStart.IsValid())
ptStartNext = vEditInfo[c].ptStart ;
else
vOffsetCrvs[c].pCrv->GetStartPoint( ptStartNext) ;
if ( ! AreSamePointApprox( ptEndCurr, ptStartNext)) {
// giunto questi due punti
ICurveLine* pCLprev = GetCurveLine( pGeomDB->GetGeoObj( nPrevId)) ;
Point3d ptIni = pCLprev->GetEnd() ;
ICurveLine* pCLnext = GetCurveLine( pGeomDB->GetGeoObj( nNextId)) ;
Point3d ptFin = pCLnext->GetStart() ;
const CamData* camDataPrev = GetCamData( pGeomDB->GetUserObj( nPrevId)) ;
const CamData* camDataNext = GetCamData( pGeomDB->GetUserObj( nNextId)) ;
Vector3d vtTool = Media( camDataPrev->GetToolDir(), camDataNext->GetToolDir()) ;
Vector3d vtCorr = Media( camDataPrev->GetCorrDir(), camDataNext->GetCorrDir()) ;
Vector3d vtAux = Media( camDataPrev->GetAuxDir(), camDataNext->GetAuxDir()) ;
double dFeed = camDataPrev->GetFeed() ;
int nFlag = camDataPrev->GetFlag() ;
int nFlag2 = camDataPrev->GetFlag2() ;
bool bToolShow = camDataPrev->GetToolShow() ;
AddLinearMove( ptIni, ptFin, pGeomDB, nPathId, vtTool, vtCorr, vtAux, dFeed, nFlag, nFlag2, bToolShow, nPrevId) ;
}
i = c ;
}
LuaSetParam( L, bOk) ;