Merge branch 'release/2.7l1'

This commit is contained in:
luca.mazzoleni
2025-12-10 10:05:02 +01:00
4 changed files with 759 additions and 4 deletions
+6 -1
View File
@@ -139,6 +139,7 @@ end
---------------------------------------------------------------------
function VerifyMill( Machining, dDepth, sTuuidMstr, dMaxDiam, dMaxTotLen, bH2)
if ( not dDepth or Machining.Tool.MaxMat > dDepth - GEO.EPS_SMALL) and
( Machining.Type ~= 'FloatingAggregate' or abs( Machining.Tool.MaxMat - dDepth) < 100 * GEO.EPS_SMALL) and
( not sTuuidMstr or sTuuidMstr == Machining.Tool.UUID) and
( not dMaxDiam or Machining.Tool.Diameter < dMaxDiam + GEO.EPS_SMALL) and
( not dMaxTotLen or Machining.Tool.TotalLength < dMaxTotLen + GEO.EPS_SMALL) then
@@ -227,7 +228,11 @@ function GetMachinings( MachiningType, sType)
table.insert( validMachinings, Machining)
-- se non è tastatura, recupero dati utensile
if MachiningType ~= MCH_MY.PROBING then
if ( MachiningType == MCH_MY.MILLING) or ( MachiningType == MCH_MY.POCKETING) or ( MachiningType == MCH_MY.DRILLING and EgtStartsWith( sType, 'Pocket')) then
-- caso speciale utensile su aggregato flottante
if MachiningType == MCH_MY.MILLING and sType == 'FloatingAggregate' then
local sNotes = EgtTdbGetCurrToolParam( MCH_TP.USERNOTES)
Machining.Tool.MaxMat = EgtGetValInNotes( sNotes, 'TOOL_OVERHANG', 'd') or -1
elseif ( MachiningType == MCH_MY.MILLING) or ( MachiningType == MCH_MY.POCKETING) or ( MachiningType == MCH_MY.DRILLING and EgtStartsWith( sType, 'Pocket')) then
Machining.Tool.MaxMat = EgtTdbGetCurrToolMaxDepth()
else
Machining.Tool.MaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT)
+747 -2
View File
@@ -129,6 +129,10 @@ EgtOutLog( ' ProcessLapJoint started', 1)
-- Dati
local BD = require( 'BeamData')
local ML = require( 'MachiningLib')
local WHISK_OFFS = 0.1
local WHISK_SAFE = 5
local MIN_LEN_CUT = 30
-- variabili assegnazione parametri Q
local Q_FORCE_BLADE = '' -- i
@@ -147,6 +151,8 @@ local Q_SAW_PLUS_CHAIN = '' -- i
local Q_FORCE_CHAINSAW = '' -- i
local Q_CHAINSAW_FROM_SIDE = '' -- i
local Q_MILL_AS_BLADE_CONVENTIONAL = '' -- i
local Q_CLEAN_CORNER = '' -- 1
local Q_FLOATING_AGGREGATE = '' -- i
-- variabile smussi
local bMadeChamfer
@@ -196,6 +202,8 @@ local function AssignQIdent( Proc)
-- TODO da riportare a Q13 quando è sistemata la gestione del movimento in macchina nell'attacco laterale
Q_CHAINSAW_FROM_SIDE = 'Q999'
Q_MILL_AS_BLADE_CONVENTIONAL = ''
Q_CLEAN_CORNER = ''
Q_FLOATING_AGGREGATE = ''
if ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16 then
Q_FORCE_BLADE = 'Q01' -- i
@@ -223,6 +231,8 @@ local function AssignQIdent( Proc)
Q_ANTISPLINT_TYPE = 'Q06' -- i
Q_DEPTH_CHAMFER = 'Q07' -- d
Q_MILL_AS_BLADE_CONVENTIONAL = 'Q14' -- i
Q_CLEAN_CORNER = '---' -- i
Q_FLOATING_AGGREGATE = 'Q16' -- i
elseif ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 30 then
Q_BLADE_ON_ALONG_FACE = 'Q04' -- i
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32 then
@@ -5900,6 +5910,659 @@ end
--#endregion SawPlusChain
---------------------------------------------------------------------
local function ReorderFacesFromTab( nIdSurf, vFace)
local nFacCnt = EgtSurfTmFacetCount( nIdSurf)
for i = 1, #vFace do
for j = 1, nFacCnt do
-- ottengo punto iniziale e versore della faccia
local ptC, vtN = EgtSurfTmFacetCenter( nIdSurf, (j-1), GDB_ID.ROOT)
-- se versore e posizione coincidono e non corrispondono al numero faccia, faccio lo swap
if AreSameVectorExact( vFace[i].Norm, vtN) and AreSamePointEpsilon( vFace[i].Cen, ptC, 50*GEO.EPS_SMALL) then
if (j-1) ~= vFace[i].Fac then
EgtSurfTmSwapFacets( nIdSurf, vFace[i].Fac, (j-1))
end
break
end
end
end
return nIdSurf
end
---------------------------------------------------------------------
local function CalcInterference( nNewProc, vtExtr, ptCentr, dDiam1, dDiam2,
dTall1, dTall2, dDiam3, dTall3)
local ptCentrGrid1 = ptCentr + ( vtExtr * 0.01)
local frOriTool = Frame3d( ptCentrGrid1, vtExtr)
local bColl1 = EgtTestConeSurface( frOriTool, dDiam1/2, dDiam2/2, dTall1, nNewProc, 0, GDB_RT.GLOB)
if bColl1 then return true end
local ptCentrGrid2 = ptCentr + ( vtExtr * ( dTall1 + 0.01))
frOriTool = Frame3d( ptCentrGrid2, vtExtr)
local bColl2 = EgtTestCylSurface( frOriTool, dDiam2/2, dTall2, nNewProc, 0, GDB_RT.GLOB)
if bColl2 then return true end
local ptCentrGrid3 = ptCentr + ( vtExtr * ( dTall2 + 0.01))
frOriTool = Frame3d( ptCentrGrid3, vtExtr)
local bColl3 = EgtTestCylSurface( frOriTool, dDiam3/2, dTall3, nNewProc, 0, GDB_RT.GLOB)
if bColl3 then return true end
-- restituisco risultato controllo collisioni
return false
end
---------------------------------------------------------------------
local function MakeLocalSurf( ptP1, ptP2, ptP3, nAddGrpId)
-- verifico che i tre punti siano definiti
if not ptP1 or not ptP2 or not ptP3 then
return nil
end
-- creo il contorno
local nLoopId = EgtCurveCompoFromPoints( nAddGrpId, { ptP1, ptP2, ptP3, ptP1}, GDB_RT.GLOB)
if not nLoopId then
return nil
end
-- creo la superfice triangolare (quindi piana)
local nFaceId = EgtSurfTmByFlatContour( nAddGrpId, nLoopId, 0.01)
EgtErase( nLoopId)
if not nFaceId then
return nil
end
-- se normale negativa inverto
local vtN1 = EgtSurfTmFacetNormVersor( nFaceId, 0, GDB_ID.ROOT)
if vtN1:getZ() < -0.01 then
EgtInvertSurf( nFaceId)
end
return nFaceId
end
---------------------------------------------------------------------
local function AddMillCornerMachining( nPartId, nNewProc, nFacInd, tFacAdj, nAddGrpId,
dToolDiam, sMilling, dOffsAng,
dDiam1, dDiam2, dTall1,
dTall2, dDiam3, dTall3, bMakeLocSurf, vFace, vtN)
-- variabili costruzione geometria
local pAuxId = {}
local nAuxId
local ptApPoint
local AuxId
local nNewProcLoc
-- se devo creare superfice locale
if bMakeLocSurf then
-- creo superfice locale o esco
local nSurfToAdd = MakeLocalSurf( tFacAdj[7], tFacAdj[8], tFacAdj[9], nAddGrpId)
if nSurfToAdd then
local nFacCntPre = EgtSurfTmFacetCount( nNewProc.Id)
-- creo copia del percorso principale e gli aggiungo la nuova faccia
nNewProcLoc = EgtCopyGlob( nNewProc.Id, nAddGrpId)
nNewProcLoc = EgtSurfTmBySewing( nAddGrpId, {nNewProcLoc,nSurfToAdd} , true)
-- riordino le facce
nNewProcLoc = ReorderFacesFromTab( nNewProcLoc, vFace)
-- acquisisco il numero della faccia
local nFacCnt = EgtSurfTmFacetCount( nNewProcLoc)
nFacInd = nFacCnt - 1
else
local sErr = 'Cannot make local bottom surface'
EgtOutLog( sErr)
return true, ''
end
else
nNewProcLoc = nNewProc.Id
end
-- prendo il primo versore
local _, vtN1 = EgtSurfTmFacetCenter( nNewProcLoc, nFacInd, GDB_ID.ROOT)
local _, vtN2 = EgtSurfTmFacetCenter( nNewProcLoc, tFacAdj[1], GDB_ID.ROOT)
local _, vtN3 = EgtSurfTmFacetCenter( nNewProcLoc, tFacAdj[2], GDB_ID.ROOT)
-- trovo il punto sulla superfice di riferimento
local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[1], GDB_ID.ROOT)
local _, ptLocP3, ptLocP4, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[2], GDB_ID.ROOT)
-- se ho creato faccia locale su copia superficie, cancella la copia
if bMakeLocSurf then
EgtErase( nNewProcLoc)
end
local nIdIniPoint
local nIdEndPoint
if ptLocP1 and ptLocP2 then
if ( dist( ptLocP1, tFacAdj[4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[4]) < GEO.EPS_SMALL) then
nIdEndPoint = 4
nIdIniPoint = 5
elseif ( dist( ptLocP1, tFacAdj[5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[5]) < GEO.EPS_SMALL) then
nIdEndPoint = 5
nIdIniPoint = 4
end
else
local sErr = 'Error : Impossible insert clean corner from bottom'
return false, sErr
end
-- versore direzione
local vtExtr = tFacAdj[nIdIniPoint] - tFacAdj[nIdEndPoint]
vtExtr:normalize()
-- versore direzione di uscita
local vtExtrExit
-- inserisco le prime tre linee
if nIdIniPoint and nIdEndPoint then
-- se fresatura da sotto salto la lavorazione
if vtExtr:getZ() < BD.DRILL_VZ_MIN then
local sErr = 'Error : Impossible insert clean corner from bottom'
EgtOutLog( sErr)
return false, sErr
end
-- sommo i tre versori per avere una direzione media
vtExtrExit = vtN2 + vtN3
vtExtrExit:normalize()
-- calcolo angolo tilt di 45°
vtExtr = vtExtrExit + vtN
vtExtr:normalize()
local vtCheck = Vector3d(vtExtr)
-- se ho un offset angolare ruoto il percorso
if abs(dOffsAng) > 100 * GEO.EPS_SMALL then
vtCheck:rotate( vtN, dOffsAng)
end
-- controllo se c'è collisione con le facce della superfice
if CalcInterference( nNewProc.Id, vtCheck, tFacAdj[nIdEndPoint], dDiam1, dDiam2,
dTall1, dTall2, dDiam3, dTall3) then
local sErr = 'Collision detect from clean corner tool and surface'
EgtOutLog( sErr)
return true, ''
end
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdIniPoint], tFacAdj[nIdEndPoint], GDB_RT.GLOB)
table.insert( pAuxId, nAuxId)
-- se offset angolare valido e/o negativo creo il baffo precedente
if dOffsAng < ( 100 * GEO.EPS_SMALL) then
-- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro
if dist( tFacAdj[nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then
ptApPoint = ptLocP2
else
ptApPoint = ptLocP1
end
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdEndPoint], ptApPoint, GDB_RT.GLOB)
local dLenTrimExt = dist( tFacAdj[nIdEndPoint], ptApPoint) - (( dToolDiam/2) + 0.2)
-- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta
if dLenTrimExt > 10 * GEO.EPS_SMALL then
EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint, GDB_RT.GLOB)
-- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata
if abs(dOffsAng) > 100 * GEO.EPS_SMALL then
EgtRotate( nAuxId, tFacAdj[nIdEndPoint], vtN, -dOffsAng, GDB_RT.GLOB)
end
-- prendo il nuovo punto finale
ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB)
else
-- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata
if abs(dOffsAng) > 100 * GEO.EPS_SMALL then
EgtRotate( nAuxId, tFacAdj[nIdEndPoint], vtN, -dOffsAng, GDB_RT.GLOB)
end
end
table.insert( pAuxId, nAuxId)
-- creo linea di ritorno
nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[nIdEndPoint], GDB_RT.GLOB)
table.insert( pAuxId, nAuxId)
end
end
-- inserisco le ultime tre linee
-- trovo il secondo punto sulla superfice di riferimento
ptLocP1, ptLocP2 = ptLocP3, ptLocP4
if ptLocP1 and ptLocP2 then
-- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro
if dist( tFacAdj[nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then
ptApPoint = ptLocP2
else
ptApPoint = ptLocP1
end
-- se offset angolare valido e/o negativo creo il baffo precedente
if dOffsAng > -( 100 * GEO.EPS_SMALL) then
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdEndPoint], ptApPoint, GDB_RT.GLOB)
local dLenTrimExt = dist( tFacAdj[nIdEndPoint], ptApPoint) - (( dToolDiam/2) + 0.2)
-- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta
if dLenTrimExt > 10 * GEO.EPS_SMALL then
EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint, GDB_RT.GLOB)
-- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata
if abs(dOffsAng) > 100 * GEO.EPS_SMALL then
EgtRotate( nAuxId, tFacAdj[nIdEndPoint], vtN, -dOffsAng, GDB_RT.GLOB)
end
-- prendo il nuovo punto finale
ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB)
else
-- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata
if abs(dOffsAng) > 100 * GEO.EPS_SMALL then
EgtRotate( nAuxId, tFacAdj[nIdEndPoint], vtN, -dOffsAng, GDB_RT.GLOB)
end
end
table.insert( pAuxId, nAuxId)
-- creo linea di ritorno
nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[nIdEndPoint], GDB_RT.GLOB)
table.insert( pAuxId, nAuxId)
end
-- ultima linea di distacco (5mm in direzione utensile)
local pEnd = tFacAdj[nIdEndPoint] + ( 5 * vtExtr)
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdEndPoint], pEnd, GDB_RT.GLOB)
table.insert( pAuxId, nAuxId)
end
-- trasformo in percorso
if #pAuxId > 0 then
AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true)
EgtSetInfo( AuxId, 'TASKID', nNewProc.TaskId)
EgtSetInfo( AuxId, 'CUTID', nNewProc.CutId)
end
-- se non c'é il percorso do errore
if not AuxId then
local sErr = 'Error : impossible make clean corner path'
EgtOutLog( sErr)
return false, sErr
end
-- modifico versore direzione
EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB)
-- se ho un offset angolare ruoto il percorso
if abs(dOffsAng) > 100 * GEO.EPS_SMALL then
EgtRotate( AuxId, tFacAdj[nIdEndPoint], vtN, dOffsAng, GDB_RT.GLOB)
end
-- inserisco la lavorazione
local sName = 'Clean_' .. ( EgtGetName( nNewProc.Id) or tostring( nNewProc.Id))
local nMchId = EgtAddMachining( sName, sMilling)
if not nMchId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
EgtOutLog( sErr)
return false, sErr
end
EgtSetInfo( nMchId, 'Part', nPartId)
-- aggiungo geometria
EgtSetMachiningGeometry( {{ AuxId, -1}})
-- imposto posizione braccio porta testa
local nSCC = MCH_SCC.ADIR_ZP
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0)
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 4)
-- allungo inizio e fine di 10mm
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10)
-- setto affondamento 0
EgtSetMachiningParam( MCH_MP.DEPTH, 0)
-- forzo lato correzione a centrato
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER)
-- leggo eventuali note esistenti della lavorazione
local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill
sUserNotes = EgtSetValInNotes( sUserNotes, 'VMRS', 0)
-- aggiungo alle note massima elevazione
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( 0.0, 1))
-- scrivo le note della lavorazione
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchId, false)
return false, sErr
else
local _, sWarn = EgtGetMachMgrWarning( 0)
if EgtIsMachiningEmpty() then
EgtSetOperationMode( nMchId, false)
return false, sWarn
end
end
return true, ''
end
---------------------------------------------------------------------
local function AddMillCorner( vFace, Proc, dToolDiam, nAddGrpId, nMasterNewProc, vtN)
local sMilling, dMaxDepth
-- se ripresa angolo con fresa cono 60° con ripresa
-- recupero la lavorazione di fresatura
sMilling, dMaxDepth = ML.FindMilling( 'CleanCorner60')
if not sMilling then
local sErr = 'Error : CleanCorner 60 not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- recupero i dati dell'utensile
local dMillDiam = 20
local dMillTotDiam = 20
local dMillDiamTh = 20
local dToolLength = 20
local dThickTool = 20
local dSideAng = 0
if EgtMdbSetCurrMachining( sMilling) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dMillDiamTh = EgtTdbGetCurrToolThDiam() or dMillDiamTh
dMillTotDiam = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) or dMillTotDiam
dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAng
dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam
dThickTool = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dThickTool
dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth -- qui è la distanza dal portautensile
-- calcolo il secondo diametro del cono
dMillTotDiam = dMillDiam + ( abs(dThickTool) * tan(dSideAng)) * 2
end
end
-- copio la feature nel layer di appoggio
local nNewProc = { CutId = Proc.CutId, TaskId = Proc.TaskId}
if nMasterNewProc then
nNewProc.Id = nMasterNewProc
else
nNewProc.Id = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL
end
local nFacCnt = EgtSurfTmFacetCount( nNewProc.Id)
local nFacInd, dDimMin, dDimMax, dDepth, nSurfInt
local bMakeLocSurf = true
-- verifico se ciclo chiuso
local bClosed = ( abs( vFace[1].AngPrev) > 0.1)
-- ciclo di inserimento delle fresate sulle facce del contorno in esame
local i = 1
-- se faccia finale con fine non lavorato, forzo partenza da prima faccia non tutta saltata (tipo 4)
if bClosed and ( vFace[#vFace].Type == 4 or ( vFace[#vFace].Type & 2) ~= 0) then
while i <= #vFace and vFace[i].Type == 4 do
i = i + 1
end
end
-- se facce tutte da saltare, parto dall'inizio
local bAllType4 = ( i > #vFace)
if bAllType4 or bClosed then i = 1 end
while i <= #vFace do
-- se tutta la faccia o la sua fine senza taglio, inserisco una fresatura
if ( vFace[i].Type & 2) ~= 0 or vFace[i].Type == 4 then
-- variabili costruzione geometria (nFace1, nFace2, tFacAdj)
local nFace1 = vFace[i].Fac
-- ricavo i tre punti per eventuale superficie locale
local ptLoc1, ptLoc2, ptLoc3
-- aggiungo geometria
local j = EgtIf( i < #vFace, i + 1, EgtIf( bClosed, 1, nil))
if not j then return true end
local nFace2 = vFace[j].Fac
-- punto in comune tra le due facce (punto precedente della faccia [j])
ptLoc1 = vFace[j].PPrev
-- punto precedente (punto precedente della faccia [i])
if vFace[i].PPrev then
ptLoc3 = vFace[i].PPrev
else
if abs( vtN:getZ()) > abs( vtN:getY()) then
ptLoc3 = Point3d( vFace[i].Cen:getX(), vFace[i].Cen:getY(), ptLoc1:getZ())
else
ptLoc3 = Point3d( vFace[i].Cen:getX(), ptLoc1:getY(), vFace[i].Cen:getZ())
end
end
-- punto successivo ( precedente della faccia successiva)
local k = EgtIf( j < #vFace, j + 1, EgtIf( bClosed, 1, nil))
-- se è un percorso aperto prendo il punto medio della seconda faccia come punto locale 2
if not k then
if abs( vtN:getZ()) > abs( vtN:getY()) then
ptLoc2 = Point3d( vFace[j].Cen:getX(), vFace[j].Cen:getY(), ptLoc1:getZ())
else
ptLoc2 = Point3d( vFace[j].Cen:getX(), ptLoc1:getY(), vFace[j].Cen:getZ())
end
else
ptLoc2 = vFace[k].PPrev
end
-- ricavo i punti e l'angolo interno
local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( nNewProc.Id, nFace1, nFace2, GDB_ID.ROOT)
-- se punti validi e angolo è interno e non è quasi piatto e >= 90 creo istanza
local tFacAdj = {}
if ptP1 and ptP2 and dAng < 0 and dAng < -6 and dAng > -( 90 + 10 * GEO.EPS_SMALL) then
local dLen = dist( ptP1, ptP2)
tFacAdj = { nFace1, nFace2, dLen, ptP1, ptP2, dAng, ptLoc1, ptLoc2, ptLoc3}
end
-- se ho un elemento creo percorso o percorsi in base al tipo di cono e all'apertura dall'angolo rispetto ai 90°
-- con una tolleranza di 2 gradi
if #tFacAdj > 0 then
if (dAng + 90) > 2 then
local dAngOffs = (dAng + 90) / 2
-- primo taglio
local bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nAddGrpId,
dToolDiam, sMilling, -dAngOffs,
dMillDiam, dMillTotDiam, abs( dThickTool),
dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace, vtN)
if not bOk then return bOk, sErr end
-- secondo taglio
bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nAddGrpId,
dToolDiam, sMilling, dAngOffs,
dMillDiam, dMillTotDiam, abs( dThickTool),
dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace, vtN)
if not bOk then return bOk, sErr end
-- altrimenti ho un solo percorso
else
local bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nAddGrpId,
dToolDiam, sMilling, 0,
dMillDiam, dMillTotDiam, abs( dThickTool),
dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace, vtN)
if not bOk then return bOk, sErr end
end
end
end
-- passo alla successiva
i = i + 1
end
-- cancello la copia della superfice
if nNewProc.Id then
EgtErase( nNewProc.Id)
end
return true
end
---------------------------------------------------------------------
local function GetOtherRegions( nPartId)
local vOthers = {}
local nOtherId = EgtGetFirstPartInRawPart( EgtGetFirstRawPart() or GDB_ID.NULL)
while nOtherId do
local nRegId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nOtherId, 'Outline') or GDB_ID.NULL)
while nRegId do
local vtN = EgtSurfFrNormVersor( nRegId, GDB_ID.ROOT)
if EgtExistsInfo( nRegId, 'REGION') and vtN and AreSameVectorApprox( vtN, Z_AX()) then
local b3Reg = EgtGetBBoxGlob( nRegId, GDB_BB.STANDARD)
if b3Reg then
table.insert( vOthers, { PartId = nOtherId, RegId = nRegId, Box = b3Reg})
end
end
nRegId = EgtGetNext( nRegId)
end
nOtherId = EgtGetNextPartInRawPart( nOtherId)
end
return vOthers
end
---------------------------------------------------------------------
local function GetFacesData( nNewProc, dToolDiam, dToolMaxDepth, dToolThick, nAddGrpId, nPartId, vtNBottom)
local nNumFacet = EgtSurfTmFacetCount( nNewProc)
local vFace = {}
-- recupero i dati di tutte le facce
for i = 1, nNumFacet do
-- indici faccia corrente e precedente
local nFac = i - 1
local nPrecFac
nPrecFac = EgtIf( i == 1, nNumFacet - 1, i - 2)
-- recupero centro e normale della faccia
local ptCen, vtN = EgtSurfTmFacetCenter( nNewProc, nFac, GDB_ID.ROOT)
-- recupero le dimensioni della faccia
local _, dLen, dWidth = BL.GetFaceHvRefDim( nNewProc, nFac)
-- recupero l'angolo con la faccia precedente
local bAdj, ptLocP1, ptLocP2, dAng = EgtSurfTmFacetsContact( nNewProc, nPrecFac, nFac, GDB_ID.ROOT)
-- verifico che l'adiacenza sia veramente con il precedente (percorro con normale a destra)
if bAdj then
if ( vtN ^ ( ptLocP1 - ptCen)) * vtNBottom > 0 then
bAdj = false
end
end
-- salvo i dati
vFace[i] = { Fac = nFac, Cen = ptCen, Norm = vtN, Len = dLen, Width = dWidth, AngPrev = EgtIf( bAdj, dAng, 0)}
if bAdj then
-- se rivolto verso Z
if abs( vtNBottom:getZ()) > abs( vtNBottom:getY()) then
if ptLocP1:getZ() < ptLocP2:getZ() then
vFace[i].PPrev = ptLocP1
else
vFace[i].PPrev = ptLocP2
end
else
if vtNBottom:getY() > 0 then
vFace[i].PPrev = EgtIf( ptLocP1:getY() < ptLocP2:getY(), ptLocP1, ptLocP2)
else
vFace[i].PPrev = EgtIf( ptLocP1:getY() > ptLocP2:getY(), ptLocP1, ptLocP2)
end
end
end
end
-- analizzo le facce
local dMaxWidth = 0
for i = 1, #vFace do
-- aggiorno la massima larghezza
if vFace[i].Width > dMaxWidth then
dMaxWidth = vFace[i].Width
end
-- verifico l'affondamento
local dDepth = BD.CUT_EXTRA
if vFace[i].Width + BD.CUT_EXTRA > dToolMaxDepth then
dDepth = dToolMaxDepth - vFace[i].Width
end
-- lunghezza baffo
local dElev = vFace[i].Width + dDepth
local dWhisk = ( dToolDiam / 2) + WHISK_SAFE
-- determino la lunghezza del taglio passante e il tipo di attacco e uscita
local dLen = vFace[i].Len
local nType = 0
if vFace[i].AngPrev < -0.1 then
nType = nType + 1
end
if vFace[EgtIf( i < nNumFacet, i + 1, 1)].AngPrev < -0.1 then
nType = nType + 2
end
-- se lunghezza non significativa, non va inserito il taglio
if dLen < MIN_LEN_CUT then
nType = 4
end
vFace[i].Depth = dDepth
vFace[i].Whisk = dWhisk
vFace[i].Type = nType
end
-- recupero le regioni degli altri pezzi
local vOthers = GetOtherRegions( nPartId)
-- verifico i baffi sporgenti dei tagli rispetto alle altre regioni
for i = 1, #vFace do
-- verifico il baffo iniziale
if vFace[i].Type ~= 4 and ( vFace[i].Type & 1) == 0 then
-- creo il rettangolo del baffo
local vtOrt = Vector3d( vFace[i].Norm:getX(), vFace[i].Norm:getY(), 0) ; vtOrt:normalize()
local vtDir = Vector3d( vtOrt) ; vtDir:rotate( Z_AX(), -90)
local vtUp = Vector3d( vtDir) ; vtUp:rotate( vFace[i].Norm, -90)
local ptIni = vFace[i].Cen + vFace[i].Width / 2 * vtUp + ( vFace[i].Len / 2 + WHISK_OFFS) * vtDir + WHISK_OFFS * vtOrt
local ptDir = ptIni + ( vFace[i].Whisk - WHISK_OFFS) * vtDir
local ptCross = ptDir + ( dToolThick - WHISK_OFFS) * vtOrt
local WhId = EgtSurfFrRectangle3P( nAddGrpId, ptIni, ptCross, ptDir, GDB_RT.GLOB)
local b3Wh = EgtGetBBoxGlob( WhId or GDB_ID.NULL, GDB_BB.STANDARD)
-- verifico se interferisce con gli altri pezzi
for j = 1, #vOthers do
if OverlapsXY( b3Wh, vOthers[j].Box) then
local nClass = EgtSurfFrChunkSimpleClassify( WhId, 0, vOthers[j].RegId, 0)
if nClass ~= GDB_RC.OUT then
local dLen = vFace[i].Len - vFace[i].Whisk + EgtIf( ( vFace[i].Type & 2) ~= 0, -vFace[i].Whisk, 0)
if dLen >= MIN_LEN_CUT then
vFace[i].Type = vFace[i].Type + 1
else
vFace[i].Type = 4
end
break
end
end
end
EgtErase( WhId)
end
-- verifico il baffo finale
if vFace[i].Type ~= 4 and ( vFace[i].Type & 2) == 0 then
-- creo il rettangolo del baffo
local vtOrt = Vector3d( vFace[i].Norm:getX(), vFace[i].Norm:getY(), 0) ; vtOrt:normalize()
local vtDir = Vector3d( vtOrt) ; vtDir:rotate( Z_AX(), 90)
local vtUp = Vector3d( vtDir) ; vtUp:rotate( vFace[i].Norm, 90)
local ptIni = vFace[i].Cen + vFace[i].Width / 2 * vtUp + ( vFace[i].Len / 2 + WHISK_OFFS) * vtDir + WHISK_OFFS * vtOrt
local ptDir = ptIni + ( vFace[i].Whisk - WHISK_OFFS) * vtDir
local ptCross = ptDir + ( dToolThick - WHISK_OFFS) * vtOrt
local WhId = EgtSurfFrRectangle3P( nAddGrpId, ptIni, ptCross, ptDir, GDB_RT.GLOB)
local b3Wh = EgtGetBBoxGlob( WhId or GDB_ID.NULL, GDB_BB.STANDARD)
-- verifico se interferisce con gli altri pezzi
for j = 1, #vOthers do
if OverlapsXY( b3Wh, vOthers[j].Box) then
local nClass = EgtSurfFrChunkSimpleClassify( WhId, 0, vOthers[j].RegId, 0)
if nClass ~= GDB_RC.OUT then
local dLen = vFace[i].Len - vFace[i].Whisk + EgtIf( ( vFace[i].Type & 1) ~= 0, -vFace[i].Whisk, 0)
if dLen >= MIN_LEN_CUT then
vFace[i].Type = vFace[i].Type + 2
else
vFace[i].Type = 4
end
break
end
end
end
EgtErase( WhId)
end
end
-- eventuali stampe
for i = 1, #vFace do
local Face = vFace[i]
local sOut = 'Face '..tostring( Face.Fac)..' C'..tostring( Face.Cen)..' N'..tostring( Face.Norm)..
' L='..EgtNumToString( Face.Len, 1)..' W='..EgtNumToString( Face.Width, 1)..' Ap='..EgtNumToString( Face.AngPrev, 1)..
' D='..EgtNumToString( Face.Depth, 1)..' B='..EgtNumToString( Face.Whisk, 1)..' T='..tostring( Face.Type)
EgtOutLog( sOut, 3)
end
return vFace, dMaxWidth, nNewProc
end
---------------------------------------------------------------------
local function ReorderFaces( nIdSurf, nNumFacet, vtNBottom)
-- cerco una faccia senza precedenti
local nFirstFac
for i = 1, nNumFacet do
-- centro e normale della faccia
local ptCen, vtN = EgtSurfTmFacetCenter( nIdSurf, i - 1, GDB_ID.ROOT)
-- verifico con le altre facce
local bFoundPrec
for j = 1, nNumFacet do
if j ~= i then
-- verifico se è precedente
local bAdj, ptP1, _, _ = EgtSurfTmFacetsContact( nIdSurf, i - 1, j - 1, GDB_ID.ROOT)
if bAdj and ( vtN ^ ( ptCen - ptP1)) * vtNBottom > 0 then
bFoundPrec = true
break
end
end
end
if not bFoundPrec then
nFirstFac = i
break
end
end
-- se trovata, la metto al primo posto
if nFirstFac and nFirstFac ~= 1 then
EgtSurfTmSwapFacets( nIdSurf, nFirstFac - 1, 0)
end
-- ordino le facce in modo da avere una sequenza ordinata con le normali a destra
for i = 1, nNumFacet - 1 do
-- centro e normale della faccia
local ptCen, vtN = EgtSurfTmFacetCenter( nIdSurf, i - 1, GDB_ID.ROOT)
-- cerco la successiva
for j = i + 1, nNumFacet do
-- verifico se è successiva
local bAdj, ptP1, _, _ = EgtSurfTmFacetsContact( nIdSurf, i - 1, j - 1, GDB_ID.ROOT)
if bAdj and ( vtN ^ ( ptP1 - ptCen)) * vtNBottom > 0 then
EgtSurfTmSwapFacets( nIdSurf, i, j - 1)
break
end
end
end
end
---------------------------------------------------------------------
local function RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFaceToDel, vtN)
-- copio la superfice nel gruppo ausiliario
local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL
EgtSurfTmRemoveFacet( nNewProc, nFaceToDel)
local nNumFacet = EgtSurfTmFacetCount( nNewProc)
ReorderFaces( nNewProc, nNumFacet, vtN)
return nNewProc, nNumFacet
end
---------------------------------------------------------------------
local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, bSinglePart, bPrevBhSideMill, bAllWithEndCap)
if not BD.MAXDIAM_POCK_CORNER then
@@ -6238,8 +6901,77 @@ local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, bSinglePa
if dH * dV < 0.9 * ( bBoxF:getDimX() * bBoxF:getDimY()) and nFacInd2 and dFacElev2 < 1.5 * dFacElev and not ( Proc.Topology == 'Groove' and Proc.Fct == 2) then
bSpecial3faces = true
end
local bPocketFloatingAggregate = false
-- se abilitata lavorazione con aggregato flottante
local sMillingFloatingAggregate
if Proc.Topology == 'Groove' and Proc.Fct == 4 and EgtGetInfo( Proc.Id, Q_FLOATING_AGGREGATE, 'i') == 1 then
-- verifico se è possibile lavorare con utensile su aggregato flottante
sMillingFloatingAggregate = ML.FindMilling( 'FloatingAggregate', dFacElev, nil, min( dH , dV))
if sMillingFloatingAggregate then
if EgtMdbSetCurrMachining( sMillingFloatingAggregate) then
local sTuuidPk = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuidPk) or '') then
local dToolDiameter = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
-- la larghezza della tasca non può superare il doppio del diametro, la lavorazione deve essere fatta con una passata di contornatura
if min( dH , dV) < dToolDiameter * 1.9 then
bPocketFloatingAggregate = true
end
end
end
end
end
-- se posso in effetti fare fresatura con aggregato flottante
if bPocketFloatingAggregate then
-- inserisco la lavorazione di svuotatura
local sName = 'Float_Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
local nMchFId = EgtAddMachining( sName, sMillingFloatingAggregate)
if not nMchFId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sMillingFloatingAggregate
EgtOutLog( sErr)
return false, sErr
end
-- aggiungo geometria
local Geometry = {}
for Index = 1, Proc.Fct do
if nFacInd ~= Index-1 then
table.insert( Geometry, { Proc.Id, Index-1})
end
end
EgtSetMachiningGeometry( Geometry)
-- imposto uso faccia
local nFaceUse = BL.GetNearestParalOpposite( vtN)
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
-- piccolo offser radiale per essere sicuri di lavorare anche con tasca larga come diametro fresa
EgtSetMachiningParam( MCH_MP.OFFSR, -0.01)
-- imposto posizione braccio porta testa
local nSCC = MCH_SCC.NONE
if not BD.C_SIMM then
if AreSameVectorApprox( vtN, Z_AX()) then
nSCC = MCH_SCC.ADIR_YM
elseif abs( vtN:getX()) < 0.1 then
nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
elseif vtN:getY() < GEO.EPS_SMALL then
nSCC = MCH_SCC.ADIR_YP
else
nSCC = MCH_SCC.ADIR_YM
end
end
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- eseguo
if not ML.ApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
-- se riconosciuta gestione 3 facce (limitatamente per ora alla feature 20)
if bSpecial3faces and Proc.Prc == 20 then
elseif bSpecial3faces and Proc.Prc == 20 then
-- se smusso non è esclusivo
if nChamfer < 2 then
-- entrambe le facce non devono essere orientate verso il basso
@@ -7034,6 +7766,7 @@ local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, bSinglePa
end
local nBoreOnCorner = EgtGetInfo( Proc.Id, Q_BORE_ON_CORNER, 'i') or 0
local nContourSmallTool = EgtGetInfo( Proc.Id, Q_CONTOUR_SMALL_TOOL, 'i') or 0
local nCleanCorner = EgtGetInfo( Proc.Id, Q_CLEAN_CORNER, 'i') or 0
-- se abilitato dal parametro Q inserisco foro sullo spigolo
if nBoreOnCorner == 1 then
local bOk, sWarn2
@@ -7063,6 +7796,18 @@ local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, bSinglePa
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
end
end
-- se richiesta pulizia spigoli con fresa a V
if nCleanCorner > 0 then
local dThElev = dToolThDiameter / 2 * sqrt( vtN:getX() * vtN:getX() + vtN:getY() * vtN:getY())
local nNewProc = RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFacInd, vtN)
local vFace, dDepth = GetFacesData( nNewProc, dToolDiameter, dMaxToolMaterial, ( dToolDiameter/2), nAddGrpId, Proc.PartId, vtN)
local bCleanCornerOk, sCleanCornerWarn = AddMillCorner( vFace, Proc, dToolDiameter, nAddGrpId, nNewProc, vtN)
if not bCleanCornerOk then return false, sCleanCornerWarn end
if sCleanCornerWarn then
if not sWarn then sWarn = '' end
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sCleanCornerWarn, sCleanCornerWarn)
end
end
end
end
end
@@ -7540,7 +8285,7 @@ function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead)
end
-- se lunghezza richiede spezzatura
if ( Proc.Box:getDimX() > BD.LONGCUT_MAXLEN) or
( Proc.Box:getDimX() > 0.7 * b3Solid:getDimX() and ( b3Solid:getDimX() > ( BD.LEN_VERY_SHORT_PART or BD.LEN_SHORT_PART))) or
( Proc.Box:getDimX() > 0.7 * b3Solid:getDimX() and ( Proc.DistanceToNextPart > 1000 or Proc.Box:getDimX() > BD.LONGCUT_ENDLEN)) or
( ( nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0) and ( Proc.Box:getDimX() > ( BD.LEN_SHORT_PART or 1000))) then
-- una faccia
if Proc.Fct == 1 then
+5
View File
@@ -1,5 +1,10 @@
==== Beam Update Log ====
Versione 2.7l1 (10/12/2025)
- Added : in LapJoint aggiunta gestione fresatura con aggregato flottante (Q specifica)
- Modif : in LapJoint modfifiche alla lavorazione spigoli su faccia frontale o posteriore
- Modif : in LapJoint lunghe, la spezzatura ora considera se è presente del grezzo dietro
Versione 2.7k1 (25/11/2024)
- Added : in tagli di testa e coda aggiunti smussi con possibilità di raccordare o smussare spigoli
- Added : in Lapjoint aggiunto Q14 per settare lavorazione discorde se longitudinale su faccia sotto
+1 -1
View File
@@ -2,5 +2,5 @@
-- Gestione della versione di Beam
NAME = 'Beam'
VERSION = '2.7k1'
VERSION = '2.7l1'
MIN_EXE = '2.7f2'