Compare commits
72 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| adf08876a9 | |||
| 476f214b99 | |||
| eacabb5af7 | |||
| 5c7751aebd | |||
| 6649842c70 | |||
| 27475763a2 | |||
| 3fcca044ed | |||
| 630d28bf5b | |||
| 5e5f3d08c4 | |||
| a773e0156a | |||
| 72e3b7dc8f | |||
| 10592ac612 | |||
| a5d606b225 | |||
| 3ba456f72f | |||
| 608f8da033 | |||
| 08397ae102 | |||
| b7dbc7422c | |||
| 974d1abb41 | |||
| c4697fbd6f | |||
| b79617fbe4 | |||
| e5f1abc47d | |||
| 965c6e8f9e | |||
| d59039eae0 | |||
| a404bf2f9e | |||
| 1cde1c94d9 | |||
| a66054a6c8 | |||
| b77e79d0d0 | |||
| cad57b2fd5 | |||
| 5e503762e5 | |||
| f27000b7bc | |||
| f90dd95880 | |||
| 0497877abb | |||
| b8299df247 | |||
| 4a99f2bdf6 | |||
| 1e86180723 | |||
| f6d6043c0e | |||
| b048e2ebe2 | |||
| fc47bca0f1 | |||
| 0274096f57 | |||
| 983609397e | |||
| 05a8d23f6a | |||
| 40580cdc69 | |||
| f6b2477f2b | |||
| 69db74e30e | |||
| f58004dfeb | |||
| 7c485360de | |||
| 967117cc23 | |||
| 64b2e86a2d | |||
| 89b342a564 | |||
| 117e475de5 | |||
| a7b817b211 | |||
| d8c6a8ad55 | |||
| 9026acd9ca | |||
| 204346326f | |||
| 5d6e4c397d | |||
| 64bde8924d | |||
| cb6115d23f | |||
| 771c1367b1 | |||
| 6092063daa | |||
| 44650c303c | |||
| 69fa0d741d | |||
| 8e55ddda1f | |||
| 7a8fb04ebe | |||
| 77c27d911c | |||
| 3a29f273c9 | |||
| bab5b07bd1 | |||
| 683ae78c65 | |||
| 06d9529b7b | |||
| 922a7ac846 | |||
| a21a3979f1 | |||
| fcbed252e1 | |||
| 28026358b9 |
+3
-1
@@ -390,7 +390,8 @@ if bToProcess then
|
||||
end
|
||||
end
|
||||
-- Assegno lunghezza della barra
|
||||
dBarLen = PARTS[1].b3PartOriginal:getDimX() + 10
|
||||
-- TODO nella ProcessBeams andava in errore con 10mm!!! CONTROLLARE
|
||||
dBarLen = PARTS[1].b3PartOriginal:getDimX() + 20
|
||||
if dBarLen < 2200 then
|
||||
dBarLen = dBarLen + 1800
|
||||
end
|
||||
@@ -492,6 +493,7 @@ if bToProcess then
|
||||
return
|
||||
end
|
||||
|
||||
-- TODO in caso di "GEN_sPiecesLoadingPosition = FULL_PRE_ROTATION" bisogna controllare anche sezione ribaltata di 90°
|
||||
-- Verifico sezione barra non troppo grande
|
||||
if not BeamData.MAX_WIDTH2 or not BeamData.MAX_HEIGHT2 then
|
||||
if ( dRawW > BeamData.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BeamData.MAX_HEIGHT + 10 * GEO.EPS_SMALL) then
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
-- GetWallData.lua by Egaltech s.r.l. 2022/06/28
|
||||
-- Recupero dati da file WallData.lua di macchina
|
||||
|
||||
-- Intestazioni
|
||||
require( 'EgtBase')
|
||||
_ENV = EgtProtectGlobal()
|
||||
EgtEnableDebug( false)
|
||||
|
||||
-- Per test
|
||||
--GWD = {}
|
||||
--GWD.MACHINE = 'Essetre-90480019_MW'
|
||||
|
||||
local sLog = 'GetBeamData : ' .. GWD.MACHINE
|
||||
EgtOutLog( sLog)
|
||||
|
||||
-- Imposto direttorio libreria specializzata per Travi
|
||||
EgtAddToPackagePath( GWD.BASEDIR .. '\\LuaLibs\\?.lua')
|
||||
|
||||
-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi
|
||||
local sMachDir = EgtGetCurrMachineDir()
|
||||
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamDataNew.lua') then
|
||||
GWD.ERR = 12
|
||||
GWD.MSG = 'Error not configured for beam machine : ' .. GWD.MACHINE
|
||||
WriteErrToLogFile( GWD.ERR, GWD.MSG)
|
||||
PostErrView( GWD.ERR, GWD.MSG)
|
||||
return
|
||||
end
|
||||
|
||||
-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
|
||||
EgtRemoveBaseMachineDirFromPackagePath()
|
||||
EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua')
|
||||
|
||||
-- Carico i dati globali
|
||||
_G.package.loaded.BeamData = nil
|
||||
local BD = require( 'BeamDataNew')
|
||||
|
||||
-- Assegno valori di interesse
|
||||
GWD.SIMUL_VIEW_DIR = BD.SIMUL_VIEW_DIR
|
||||
GWD.OVM_MID = BD.OVM_MID
|
||||
|
||||
-- Tutto ok
|
||||
GWD.ERR = 0
|
||||
|
||||
EgtOutLog( ' +++ GetBeamData completed')
|
||||
+406
-223
@@ -153,6 +153,11 @@ function BeamExec.GetToolsFromDB()
|
||||
Tool.nDouble = EgtGetValInNotes( Tool.sUserNotes, 'DOUBLE', 'd')
|
||||
Tool.bIsProfiledTool = not EgtTdbIsCurrToolStandardDraw()
|
||||
|
||||
-- TODO per capire se ToolHolder è flottante bisogna leggere nota TYPE='Float' su ToolHolder. Serve funzione
|
||||
-- info per utensile su ToolHolder flottante
|
||||
Tool.dOverHang = EgtGetValInNotes( Tool.sUserNotes, 'TOOL_OVERHANG', 'd') or 0
|
||||
Tool.bToolOnFloatingTH = Tool.dOverHang > 0
|
||||
|
||||
-- lettura parametri non comuni ( famiglia DRILLBIT non ha parametri specifici)
|
||||
if sToolFamily ~= 'DRILLBIT' then
|
||||
Tool.dThickness = EgtTdbGetCurrToolParam( MCH_TP.THICK)
|
||||
@@ -251,6 +256,27 @@ function BeamExec.GetStrategiesFromJSONinBD( sAISetupConfigName)
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetRotationName( nRotIndex, nInvertIndex)
|
||||
local sRotation = ''
|
||||
|
||||
if nRotIndex == 1 then
|
||||
sRotation = '0'
|
||||
elseif nRotIndex == 2 then
|
||||
sRotation = '90'
|
||||
elseif nRotIndex == 3 then
|
||||
sRotation = '180'
|
||||
elseif nRotIndex == 4 then
|
||||
sRotation = '270'
|
||||
end
|
||||
|
||||
if nInvertIndex > 1 then
|
||||
sRotation = sRotation .. 'INV'
|
||||
end
|
||||
|
||||
return sRotation
|
||||
end
|
||||
|
||||
-- TODO prevedere parametri per preferire carico del pezzo verticale oppure orizzontale?
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione che controlla validità delle combinazioni proposte
|
||||
@@ -356,188 +382,179 @@ function BeamExec.GetAvailableCombinations( PartInfo, bIsFlipRot)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- *** funzioni posizionamento pezzi all'interno della barra ***
|
||||
-- *** Funzioni posizionamento pezzi all'interno della barra***
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, bCreateMachGroup, bIsFlipRot)
|
||||
-- gruppo per geometrie temporanee
|
||||
local idTempGroup = BeamLib.GetTempGroup()
|
||||
function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, bCreateMachGroup, bIsFlipRot )
|
||||
-- 1. Inizializzazione e Default
|
||||
local idTempGroup = BeamLib.GetTempGroup( )
|
||||
|
||||
-- default per nuove costanti qualora non definite
|
||||
BeamData.OVM_BLADE_HBEAM = ( BeamData.OVM_BLADE_HBEAM or 11)
|
||||
BeamData.OVM_CHAIN_HBEAM = ( BeamData.OVM_CHAIN_HBEAM or 8)
|
||||
BeamData.OVM_BLADE_HBEAM = ( BeamData.OVM_BLADE_HBEAM or 11 )
|
||||
BeamData.OVM_CHAIN_HBEAM = ( BeamData.OVM_CHAIN_HBEAM or 8 )
|
||||
|
||||
-- sovramateriale intermedio nullo se non definito
|
||||
dOvmMid = ( dOvmMid or 0)
|
||||
dOvmMid = ( dOvmMid or 5.4 )
|
||||
dOvmHead = ( dOvmHead or 0 )
|
||||
BeamExec.CalcMinUnloadableRaw( dRawW, dRawH )
|
||||
|
||||
-- Determinazione minimo grezzo scaricabile
|
||||
BeamExec.CalcMinUnloadableRaw( dRawW, dRawH)
|
||||
|
||||
-- Creazione nuovo gruppo di lavoro (di default va creato)
|
||||
if bCreateMachGroup == nil then
|
||||
bCreateMachGroup = true
|
||||
end
|
||||
if bCreateMachGroup then
|
||||
local sMgName = EgtGetMachGroupNewName( 'Mach_1')
|
||||
local idNewMg = EgtAddMachGroup( sMgName)
|
||||
if not idNewMg then
|
||||
local sOut = 'Errore nella creazione del gruppo di lavoro ' .. sMgName
|
||||
return false, sOut
|
||||
-- 2. Gestione Gruppo di Lavoro
|
||||
if ( bCreateMachGroup == nil ) then bCreateMachGroup = true end
|
||||
if ( bCreateMachGroup ) then
|
||||
local sMgName = EgtGetMachGroupNewName( 'Mach_1' )
|
||||
local idNewMg = EgtAddMachGroup( sMgName )
|
||||
if ( not idNewMg ) then
|
||||
return false, 'Errore creazione gruppo di lavoro'
|
||||
end
|
||||
end
|
||||
|
||||
-- Impostazione della tavola
|
||||
EgtSetTable( 'Tab')
|
||||
|
||||
-- salvo nota con lunghezza grezzo
|
||||
-- Recupero l'identificativo del gruppo di lavoro corrente
|
||||
local nMGrpId = EgtGetCurrMachGroup()
|
||||
-- Lunghezza della barra
|
||||
local dBarLen = EgtGetInfo( nMGrpId, 'BARLEN', 'd')
|
||||
if not dBarLen then
|
||||
EgtSetInfo( nMGrpId, 'BARLEN', dRawL)
|
||||
-- 3. Configurazione Tavola Macchina
|
||||
EgtSetTable( 'Tab' )
|
||||
local nMGrpId = EgtGetCurrMachGroup( )
|
||||
if ( not EgtGetInfo( nMGrpId, 'BARLEN', 'd' ) ) then
|
||||
EgtSetInfo( nMGrpId, 'BARLEN', dRawL )
|
||||
end
|
||||
|
||||
-- Area tavola
|
||||
local b3Tab = EgtGetTableArea()
|
||||
-- Calcolo posizione estremo TR/BR della tavola rispetto a sua origine in BL
|
||||
local dPosY = EgtIf( BeamData.CENTER_BEAM, ( b3Tab:getDimY() + dRawW * EgtIf( BeamData.RIGHT_LOAD, -1, 1)) / 2, EgtIf( BeamData.RIGHT_LOAD, 0, b3Tab:getDimY()))
|
||||
BeamData.ptOriXR = Point3d( b3Tab:getDimX(), dPosY, 0)
|
||||
BeamData.dPosXR = EgtIf( BeamData.RIGHT_LOAD, MCH_CR.BR, MCH_CR.TR)
|
||||
local b3Tab = EgtGetTableArea( )
|
||||
local dPosY = EgtIf( BeamData.CENTER_BEAM, ( b3Tab:getDimY( ) + dRawW * EgtIf( BeamData.RIGHT_LOAD, -1, 1 ) ) / 2, EgtIf( BeamData.RIGHT_LOAD, 0, b3Tab:getDimY( ) ) )
|
||||
|
||||
BeamData.ptOriXR = Point3d( b3Tab:getDimX( ), dPosY, 0 )
|
||||
BeamData.dPosXR = EgtIf( BeamData.RIGHT_LOAD, MCH_CR.BR, MCH_CR.TR )
|
||||
|
||||
-- Impostazione dell'attrezzaggio di default
|
||||
EgtImportSetup()
|
||||
EgtImportSetup( )
|
||||
|
||||
-- Inserimento dei pezzi con il loro grezzo
|
||||
-- 4. Ciclo di Inserimento Pezzi
|
||||
local nCnt = 0
|
||||
local dLen = dRawL
|
||||
local idPrevRaw, dPrevDelta
|
||||
local dDeltaS = dOvmHead
|
||||
local dDeltaSMin = 0
|
||||
local dDeltaE = BeamData.OVM_MID
|
||||
local dMaxX = 0
|
||||
local idPrevRaw = nil
|
||||
local dNextStartOffset = dOvmHead -- Il primo pezzo applica il sormonto iniziale a destra (testa)
|
||||
|
||||
for i = 1, #PARTS do
|
||||
-- dati del pezzo
|
||||
local b3BoxExact = EgtGetBBoxGlob( PARTS[i].id or GDB_ID.NULL, GDB_BB.EXACT)
|
||||
if b3BoxExact:isEmpty() or PARTS[i].b3PartOriginal:isEmpty() then break end
|
||||
EgtOutLog( 'PartSez=' .. EgtNumToString( b3BoxExact:getDimY(), 1) .. 'x' .. EgtNumToString( b3BoxExact:getDimZ(), 1), 3)
|
||||
-- se sezione compatibile e lunghezza disponibile sufficiente
|
||||
local dPartLen = PARTS[i].b3PartOriginal:getDimX()
|
||||
local dPartWidth = PARTS[i].b3PartOriginal:getDimY()
|
||||
local dPartHeight = PARTS[i].b3PartOriginal:getDimZ()
|
||||
local dNextLen = dLen - EgtIf( i == 1, dDeltaS, 0) - dPartLen - dDeltaE
|
||||
if (( abs( dPartWidth - dRawW) < 100 * GEO.EPS_SMALL and abs( dPartHeight - dRawH) < 100 * GEO.EPS_SMALL) or
|
||||
( abs( dPartHeight - dRawW) < 100 * GEO.EPS_SMALL and abs( dPartWidth - dRawH) < 100 * GEO.EPS_SMALL)) and
|
||||
dNextLen + dDeltaE >= 0 then
|
||||
-- eventuale sovramateriale di testa
|
||||
if i > 1 then
|
||||
if PARTS[i].dPosX then
|
||||
dDeltaS = max( PARTS[i].dPosX - ( dRawL - dLen), dDeltaSMin)
|
||||
else
|
||||
dDeltaS = max( dOvmMid - dDeltaE, 0)
|
||||
end
|
||||
end
|
||||
-- dimensioni del grezzo
|
||||
local dCrawLen = min( dPartLen + dDeltaS + dDeltaE, dLen)
|
||||
local dDelta = dCrawLen - dPartLen - dDeltaS
|
||||
-- creo e posiziono il grezzo
|
||||
PARTS[i].idRaw = EgtAddRawPart( Point3d(0,0,0), dCrawLen, dRawW, dRawH, BeamData.RAWCOL)
|
||||
local CurrentPart = PARTS[i]
|
||||
local b3BoxExact = EgtGetBBoxGlob( CurrentPart.id or GDB_ID.NULL, GDB_BB.EXACT )
|
||||
|
||||
if ( b3BoxExact:isEmpty( ) or CurrentPart.b3PartOriginal:isEmpty( ) ) then break end
|
||||
|
||||
EgtMoveToCornerRawPart( PARTS[i].idRaw, BeamData.ptOriXR, BeamData.dPosXR)
|
||||
EgtMoveRawPart( PARTS[i].idRaw, Vector3d( dLen - dRawL, 0, 0))
|
||||
-- assegno ordine in lavorazione
|
||||
local dPartLen = CurrentPart.b3PartOriginal:getDimX( )
|
||||
local dPartWidth = CurrentPart.b3PartOriginal:getDimY( )
|
||||
local dPartHeight = CurrentPart.b3PartOriginal:getDimZ( )
|
||||
|
||||
local dStartOffset = dNextStartOffset
|
||||
local dEndOffset = dOvmMid
|
||||
|
||||
-- LOGICA LOOK-AHEAD: Analisi del gap reale per la ripartizione specchiata
|
||||
if ( i < #PARTS ) then
|
||||
local dTotalGap = PARTS[i + 1].dPosX - CurrentPart.dPosX - dPartLen
|
||||
if ( dTotalGap > dOvmMid ) then
|
||||
dEndOffset = dOvmMid -- Max 5.4mm sulla coda (lato sinistro del grezzo)
|
||||
dNextStartOffset = dTotalGap - dOvmMid -- Il residuo sulla testa del prossimo (lato destro)
|
||||
else
|
||||
-- Gestione automatica sotto-soglia o compenetrazione geometrica (Nesting Obliquo)
|
||||
dEndOffset = dTotalGap
|
||||
dNextStartOffset = 0
|
||||
end
|
||||
end
|
||||
|
||||
-- MATEMATICA CORRETTA PER X CAD INVERTITA:
|
||||
-- Il grezzo idRaw si estende verso destra. Spostando il pezzo internamente di dEndOffset (dDelta),
|
||||
-- lasciamo dEndOffset a sinistra (coda) e matematicamente dStartOffset a destra (testa).
|
||||
local dCrawLen = dPartLen + dStartOffset + dEndOffset
|
||||
local dDelta = dEndOffset
|
||||
local dStartPos = (CurrentPart.dPosX or 0) - dStartOffset
|
||||
|
||||
local bIsSectionOk = ( ( abs( dPartWidth - dRawW ) < 100 * GEO.EPS_SMALL and abs( dPartHeight - dRawH ) < 100 * GEO.EPS_SMALL ) or
|
||||
( abs( dPartHeight - dRawW ) < 100 * GEO.EPS_SMALL and abs( dPartWidth - dRawH ) < 100 * GEO.EPS_SMALL ) )
|
||||
|
||||
if ( bIsSectionOk and ( dStartPos + dCrawLen <= dRawL + GEO.EPS_SMALL ) ) then
|
||||
|
||||
-- 5. Creazione e Posizionamento del Contenitore RawPart
|
||||
CurrentPart.idRaw = EgtAddRawPart( Point3d( 0, 0, 0 ), dCrawLen, dRawW, dRawH, BeamData.RAWCOL )
|
||||
EgtMoveToCornerRawPart( CurrentPart.idRaw, BeamData.ptOriXR, BeamData.dPosXR )
|
||||
EgtMoveRawPart( CurrentPart.idRaw, Vector3d( -dStartPos, 0, 0 ) )
|
||||
|
||||
-- 6. Configurazione Geometrie Pezzo
|
||||
nCnt = nCnt + 1
|
||||
EgtSetInfo( PARTS[i].idRaw, 'ORD', nCnt)
|
||||
-- creo o pulisco gruppo geometrie aggiuntive
|
||||
if not BeamLib.CreateOrEmptyAddGroup( PARTS[i].id) then
|
||||
local sOut = 'Error creating Additional Group in Part ' .. tostring( PARTS[i].id)
|
||||
return false, sOut
|
||||
EgtSetInfo( CurrentPart.idRaw, 'ORD', nCnt )
|
||||
|
||||
if ( not BeamLib.CreateOrEmptyAddGroup( CurrentPart.id ) ) then
|
||||
return false, 'Error creating Additional Group in Part ' .. tostring( CurrentPart.id )
|
||||
end
|
||||
-- aggiungo faccia per taglio iniziale al pezzo
|
||||
BeamLib.AddPartStartFace( PARTS[i].id, PARTS[i].b3PartOriginal)
|
||||
-- se sovramateriale di testa, lo notifico
|
||||
if dDeltaS > 0.09 then
|
||||
EgtSetInfo( PARTS[i].idRaw, 'HOVM', dDeltaS)
|
||||
if idPrevRaw then
|
||||
EgtSetInfo( idPrevRaw, 'BDST', dDeltaS + dPrevDelta)
|
||||
end
|
||||
end
|
||||
if dDeltaE > 0.09 then
|
||||
EgtSetInfo( PARTS[i].idRaw, 'TOVM', dDeltaE)
|
||||
end
|
||||
-- aggiungo faccia per taglio finale al pezzo
|
||||
BeamLib.AddPartEndFace( PARTS[i].id, PARTS[i].b3PartOriginal)
|
||||
-- inserisco il pezzo nel grezzo
|
||||
EgtDeselectPartObjs( PARTS[i].id)
|
||||
local ptPos = b3BoxExact:getMin() - PARTS[i].b3PartOriginal:getMin() + Vector3d( dDelta, ( dRawW - dPartWidth) / 2, ( dRawH - dPartHeight) / 2)
|
||||
EgtAddPartToRawPart( PARTS[i].id, ptPos, PARTS[i].idRaw)
|
||||
if abs( dPartWidth - dRawW) > 100 * GEO.EPS_SMALL then
|
||||
-- rotazione attorno a centro geometria complessiva del pezzo
|
||||
EgtRotatePartInRawPart( PARTS[i].id, X_AX(), 90)
|
||||
-- correggo per eccentricità solido rispetto a geometria complessiva del pezzo
|
||||
local vtEccOri = PARTS[i].b3PartOriginal:getCenter() - b3BoxExact:getCenter()
|
||||
local vtEccRot = Vector3d( vtEccOri)
|
||||
vtEccRot:rotate( X_AX(), 90)
|
||||
EgtMovePartInRawPart( PARTS[i].id, ( vtEccOri - vtEccRot))
|
||||
end
|
||||
-- aggiorno la lunghezza residua della barra
|
||||
dLen = dLen - dCrawLen
|
||||
-- aggiorno grezzo precedente
|
||||
idPrevRaw = PARTS[i].idRaw
|
||||
dPrevDelta = dDelta
|
||||
PARTS[i].bIsLastPart = ( i == #PARTS)
|
||||
PARTS[i].dDistanceToNextPiece = dDelta
|
||||
PARTS[i].dRestLength = dLen
|
||||
PARTS[i].b3Raw = EgtGetRawPartBBox( PARTS[i].idRaw)
|
||||
PARTS[i].dLength = PARTS[i].b3Raw:getDimX()
|
||||
PARTS[i].dWidth = PARTS[i].b3Raw:getDimY()
|
||||
PARTS[i].dHeight = PARTS[i].b3Raw:getDimZ()
|
||||
PARTS[i].bSquareSection = abs( PARTS[i].dWidth - PARTS[i].dHeight) < 100 * GEO.EPS_SMALL
|
||||
PARTS[i].idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL)
|
||||
PARTS[i].b3Part = EgtGetBBoxGlob( PARTS[i].idBoxTm, GDB_BB.STANDARD)
|
||||
PARTS[i].nIndexInParts = i
|
||||
PARTS[i].SplittingPoints = BeamLib.GetPartSplittingPoints( PARTS[i])
|
||||
PARTS[i].NotClampableLength = { STD = { dHead = 0, dTail = 0}, SIDE = { dHead = 0, dTail = 0}, DOWN = { dHead = 0, dTail = 0}}
|
||||
PARTS[i].dHeadOverMaterial = dDeltaS
|
||||
PARTS[i].sBTLInfo = EgtGetInfo( PARTS[i].id, 'PROJ', 's') or nil
|
||||
|
||||
BeamLib.AddPartStartFace( CurrentPart.id, CurrentPart.b3PartOriginal )
|
||||
BeamLib.AddPartEndFace( CurrentPart.id, CurrentPart.b3PartOriginal )
|
||||
|
||||
PARTS[i].sAISetupConfig = EgtGetInfo( PARTS[i].id, 'AISETUP', 's') or
|
||||
( GENERAL_PARAMETERS.BTL[PARTS[i].sBTLInfo] and GENERAL_PARAMETERS.BTL[PARTS[i].sBTLInfo].sAISetupConfig) or -- i parametri BTL potrebbero non esistere
|
||||
GENERAL_PARAMETERS.PROJECT.sAISetupConfig or nil
|
||||
-- Inserimento con dDelta (lascia lo spazio vuoto a sinistra e spinge il pezzo a destra)
|
||||
EgtDeselectPartObjs( CurrentPart.id )
|
||||
local ptPos = b3BoxExact:getMin( ) - CurrentPart.b3PartOriginal:getMin( ) + Vector3d( dDelta, ( dRawW - dPartWidth ) / 2, ( dRawH - dPartHeight ) / 2 )
|
||||
EgtAddPartToRawPart( CurrentPart.id, ptPos, CurrentPart.idRaw )
|
||||
|
||||
-- si carica configurazione lavorazioni
|
||||
TIMER:startElapsed('Json')
|
||||
BeamExec.GetStrategiesFromJSONinBD( PARTS[i].sAISetupConfig)
|
||||
PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i], GENERAL_PARAMETERS_JSON)
|
||||
TIMER:stopElapsed('Json')
|
||||
PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], bIsFlipRot)
|
||||
PARTS[i].idTempGroup = idTempGroup
|
||||
-- Rotazione sezione se necessaria
|
||||
if ( abs( dPartWidth - dRawW ) > 100 * GEO.EPS_SMALL ) then
|
||||
EgtRotatePartInRawPart( CurrentPart.id, X_AX( ), 90 )
|
||||
local vtEccOri = CurrentPart.b3PartOriginal:getCenter( ) - b3BoxExact:getCenter( )
|
||||
local vtEccRot = Vector3d( vtEccOri )
|
||||
vtEccRot:rotate( X_AX( ), 90 )
|
||||
EgtMovePartInRawPart( CurrentPart.id, ( vtEccOri - vtEccRot ) )
|
||||
end
|
||||
|
||||
-- 7. Popolamento Metadati della Tabella CurrentPart
|
||||
CurrentPart.bIsLastPart = ( i == #PARTS )
|
||||
CurrentPart.dDistanceToNextPiece = dEndOffset
|
||||
CurrentPart.b3Raw = EgtGetRawPartBBox( CurrentPart.idRaw )
|
||||
CurrentPart.dLength = CurrentPart.b3Raw:getDimX( )
|
||||
CurrentPart.dWidth = CurrentPart.b3Raw:getDimY( )
|
||||
CurrentPart.dHeight = CurrentPart.b3Raw:getDimZ( )
|
||||
CurrentPart.bSquareSection = abs( CurrentPart.dWidth - CurrentPart.dHeight ) < 100 * GEO.EPS_SMALL
|
||||
|
||||
CurrentPart.idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( CurrentPart.id, 'Box' ) or GDB_ID.NULL )
|
||||
CurrentPart.b3Part = EgtGetBBoxGlob( CurrentPart.idBoxTm, GDB_BB.STANDARD )
|
||||
CurrentPart.nIndexInParts = i
|
||||
CurrentPart.SplittingPoints = BeamLib.GetPartSplittingPoints( CurrentPart )
|
||||
CurrentPart.NotClampableLength = { STD = { dHead = 0, dTail = 0 }, SIDE = { dHead = 0, dTail = 0 }, DOWN = { dHead = 0, dTail = 0 } }
|
||||
CurrentPart.dHeadOverMaterial = dStartOffset
|
||||
CurrentPart.sBTLInfo = EgtGetInfo( CurrentPart.id, 'PROJ', 's' ) or nil
|
||||
CurrentPart.idTempGroup = idTempGroup
|
||||
|
||||
-- Notifiche al Post-Processor basate sulla nuova scomposizione
|
||||
if ( dStartOffset > 0.09 ) then EgtSetInfo( CurrentPart.idRaw, 'HOVM', dStartOffset ) end
|
||||
if ( dEndOffset > 0.09 ) then EgtSetInfo( CurrentPart.idRaw, 'TOVM', dEndOffset ) end
|
||||
if ( idPrevRaw ) then EgtSetInfo( idPrevRaw, 'BDST', dStartOffset ) end
|
||||
|
||||
-- Caricamento Strategie JSON
|
||||
CurrentPart.sAISetupConfig = EgtGetInfo( CurrentPart.id, 'AISETUP', 's' ) or
|
||||
( GENERAL_PARAMETERS.BTL[CurrentPart.sBTLInfo] and GENERAL_PARAMETERS.BTL[CurrentPart.sBTLInfo].sAISetupConfig ) or
|
||||
GENERAL_PARAMETERS.PROJECT.sAISetupConfig or nil
|
||||
|
||||
TIMER:startElapsed( 'Json' )
|
||||
BeamExec.GetStrategiesFromJSONinBD( CurrentPart.sAISetupConfig )
|
||||
CurrentPart.GeneralParameters = BeamLib.GetPieceGeneralParameters( CurrentPart, GENERAL_PARAMETERS_JSON )
|
||||
TIMER:stopElapsed( 'Json' )
|
||||
|
||||
CurrentPart.CombinationList = BeamExec.GetAvailableCombinations( CurrentPart, bIsFlipRot )
|
||||
|
||||
-- Avanzamento calcolato sulla coordinata reale di fine RawPart (estremità sinistra sulla barra)
|
||||
dMaxX = max( dMaxX, dStartPos + dCrawLen )
|
||||
CurrentPart.dRestLength = dRawL - dMaxX
|
||||
idPrevRaw = CurrentPart.idRaw
|
||||
else
|
||||
local sOut = 'Error: part L(' .. EgtNumToString( dPartLen, 1) .. ') too big for raw part L(' .. EgtNumToString( dLen - 0.1, 1) .. ')'
|
||||
local sOut = 'Error: part L(' .. EgtNumToString( dPartLen, 1 ) .. ') too big for remaining bar space'
|
||||
return false, sOut
|
||||
end
|
||||
-- se rimasto troppo poco grezzo, esco
|
||||
--if Len < BeamData.MinRaw then break end
|
||||
DeltaS = 0
|
||||
end
|
||||
if idPrevRaw then
|
||||
EgtSetInfo( idPrevRaw, 'BDST', 10000)
|
||||
end
|
||||
|
||||
-- Se rimasto materiale aggiungo grezzo dell'avanzo
|
||||
-- TODO valutare se ridurre la dLen minima perchè crea discrepanze tra lunghezza inserita e VMill
|
||||
if dLen > 10 then
|
||||
local idRaw = EgtAddRawPart( Point3d(0,0,0), dLen, dRawW, dRawH, BeamData.RAWCOL)
|
||||
EgtMoveToCornerRawPart( idRaw, BeamData.ptOriXR, BeamData.dPosXR)
|
||||
EgtMoveRawPart( idRaw, Vector3d( dLen - dRawL, 0, 0))
|
||||
-- assegno ordine in lavorazione
|
||||
-- 8. Chiusura Barra e Gestione Avanzo (Rest Material)
|
||||
if ( idPrevRaw ) then EgtSetInfo( idPrevRaw, 'BDST', 10000 ) end
|
||||
|
||||
local dRemaining = dRawL - dMaxX
|
||||
if ( dRemaining > 10 ) then
|
||||
local idRawRest = EgtAddRawPart( Point3d( 0, 0, 0 ), dRemaining, dRawW, dRawH, BeamData.RAWCOL )
|
||||
EgtMoveToCornerRawPart( idRawRest, BeamData.ptOriXR, BeamData.dPosXR )
|
||||
EgtMoveRawPart( idRawRest, Vector3d( -dMaxX, 0, 0 ) )
|
||||
nCnt = nCnt + 1
|
||||
EgtSetInfo( idRaw, 'ORD', nCnt)
|
||||
-- aggiorno distanza dell'ultimo pezzo dall'eventuale grezzo scaricabile
|
||||
if EgtGetRawPartBBox( idRaw):getDimX() < BeamData.dMinRaw then
|
||||
EgtSetInfo( idRawRest, 'ORD', nCnt )
|
||||
|
||||
if ( EgtGetRawPartBBox( idRawRest ):getDimX( ) < BeamData.dMinRaw ) then
|
||||
PARTS[#PARTS].dDistanceToNextPiece = 10000
|
||||
end
|
||||
else
|
||||
PARTS[#PARTS].dDistanceToNextPiece = 10000
|
||||
if ( #PARTS > 0 ) then PARTS[#PARTS].dDistanceToNextPiece = 10000 end
|
||||
end
|
||||
|
||||
return true
|
||||
@@ -781,9 +798,24 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetFeatureInfoAndDependency( vProcSingleRot, Part)
|
||||
-- gruppo per geometrie temporanee
|
||||
local idTempGroup = BeamLib.GetTempGroup()
|
||||
|
||||
local HeadProcOriginal
|
||||
local TailProcOriginal
|
||||
local HeadProc
|
||||
local TailProc
|
||||
|
||||
-- ciclo tutte le feature
|
||||
for i = 1, #vProcSingleRot do
|
||||
local Proc = vProcSingleRot[i]
|
||||
if Proc.Topology.sName == 'HeadCut' then
|
||||
HeadProcOriginal = Proc
|
||||
HeadProcOriginal.bIsOriginalHeadcut = true
|
||||
elseif Proc.Topology.sName == 'TailCut' then
|
||||
TailProcOriginal = Proc
|
||||
TailProcOriginal.bIsOriginalTailcut = true
|
||||
end
|
||||
-- se feature abilitata alla lavorazione
|
||||
if Proc.nFlg ~= 0 then
|
||||
-- controllo la feature con tutte le altre per recuperare le dipendenze
|
||||
@@ -791,6 +823,86 @@ local function GetFeatureInfoAndDependency( vProcSingleRot, Part)
|
||||
local ProcB = vProcSingleRot[j]
|
||||
-- non si controlla la feature con se stessa o se feature disabilitata
|
||||
if i ~= j and ProcB.nFlg ~= 0 then
|
||||
|
||||
local bAreBothTruncatingCuts =
|
||||
( ID.IsCut( Proc) or ID.IsHeadCut( Proc) or ID.IsTailCut( Proc)) and ( ID.IsCut( ProcB) or ID.IsHeadCut( ProcB) or ID.IsTailCut( ProcB))
|
||||
and ( FeatureLib.IsFeatureCuttingEntireSection( Proc.b3Box, Part) and FeatureLib.IsFeatureCuttingEntireSection( ProcB.b3Box, Part))
|
||||
|
||||
-- si trovano i veri tagli di testa e coda e si disattivano gli altri, se necessario
|
||||
if bAreBothTruncatingCuts then
|
||||
-- testa
|
||||
if Proc.Faces[1].vtN:getX() > GEO.EPS_SMALL and ProcB.Faces[1].vtN:getX() > GEO.EPS_SMALL then
|
||||
-- il primo taglio è più verso il centro della trave
|
||||
if ( Proc.b3Box:getMin():getX() < ProcB.b3Box:getMin():getX() - 10 * GEO.EPS_SMALL) then
|
||||
HeadProc = Proc
|
||||
local idProcCopy = EgtCopyGlob( Proc.id, idTempGroup)
|
||||
local idProcBCopy = EgtCopyGlob( ProcB.id, idTempGroup)
|
||||
EgtMove( idProcCopy, - 500 * GEO.EPS_SMALL * Proc.Faces[1].vtN, GDB_RT.GLOB)
|
||||
EgtMove( idProcBCopy, 500 * GEO.EPS_SMALL * ProcB.Faces[1].vtN, GDB_RT.GLOB)
|
||||
-- se i tagli non si intersecano, quello più esterno è da disattivare
|
||||
if not EgtTestSurfaceSurface( idProcCopy, idProcBCopy, GEO.EPS_SMALL) then
|
||||
if not Proc.SlaveProcIndexes then
|
||||
Proc.SlaveProcIndexes = {}
|
||||
end
|
||||
table.insert( Proc.SlaveProcIndexes, j)
|
||||
ProcB.nIndexMasterProc = i
|
||||
ProcB.nFlg = 0
|
||||
end
|
||||
-- il secondo taglio è più verso il centro della trave
|
||||
elseif Proc.b3Box:getMin():getX() >= ProcB.b3Box:getMin():getX() - 10 * GEO.EPS_SMALL then
|
||||
HeadProc = ProcB
|
||||
local idProcCopy = EgtCopyGlob( Proc.id, idTempGroup)
|
||||
local idProcBCopy = EgtCopyGlob( ProcB.id, idTempGroup)
|
||||
EgtMove( idProcBCopy, - 500 * GEO.EPS_SMALL * ProcB.Faces[1].vtN, GDB_RT.GLOB)
|
||||
EgtMove( idProcCopy, 500 * GEO.EPS_SMALL * Proc.Faces[1].vtN, GDB_RT.GLOB)
|
||||
-- se i tagli non si intersecano, quello più esterno è da disattivare
|
||||
if not EgtTestSurfaceSurface( idProcCopy, idProcBCopy, GEO.EPS_SMALL) then
|
||||
if not ProcB.SlaveProcIndexes then
|
||||
ProcB.SlaveProcIndexes = {}
|
||||
end
|
||||
table.insert( ProcB.SlaveProcIndexes, i)
|
||||
Proc.nIndexMasterProc = j
|
||||
Proc.nFlg = 0
|
||||
end
|
||||
end
|
||||
-- coda
|
||||
elseif Proc.Faces[1].vtN:getX() <= GEO.EPS_SMALL and ProcB.Faces[1].vtN:getX() <= GEO.EPS_SMALL then
|
||||
-- il primo taglio è più verso il centro della trave
|
||||
if Proc.b3Box:getMax():getX() > ProcB.b3Box:getMax():getX() + 10 * GEO.EPS_SMALL then
|
||||
TailProc = Proc
|
||||
local idProcCopy = EgtCopyGlob( Proc.id, idTempGroup)
|
||||
local idProcBCopy = EgtCopyGlob( ProcB.id, idTempGroup)
|
||||
EgtMove( idProcCopy, - 500 * GEO.EPS_SMALL * Proc.Faces[1].vtN, GDB_RT.GLOB)
|
||||
EgtMove( idProcBCopy, 500 * GEO.EPS_SMALL * ProcB.Faces[1].vtN, GDB_RT.GLOB)
|
||||
-- se i tagli non si intersecano, quello più esterno è da disattivare
|
||||
if not EgtTestSurfaceSurface( idProcCopy, idProcBCopy, GEO.EPS_SMALL) then
|
||||
if not Proc.SlaveProcIndexes then
|
||||
Proc.SlaveProcIndexes = {}
|
||||
end
|
||||
table.insert( Proc.SlaveProcIndexes, j)
|
||||
ProcB.nIndexMasterProc = i
|
||||
ProcB.nFlg = 0
|
||||
end
|
||||
-- il secondo taglio è più verso il centro della trave
|
||||
elseif Proc.b3Box:getMax():getX() >= ProcB.b3Box:getMax():getX() - 10 * GEO.EPS_SMALL then
|
||||
TailProc = ProcB
|
||||
local idProcCopy = EgtCopyGlob( Proc.id, idTempGroup)
|
||||
local idProcBCopy = EgtCopyGlob( ProcB.id, idTempGroup)
|
||||
EgtMove( idProcBCopy, - 500 * GEO.EPS_SMALL * ProcB.Faces[1].vtN, GDB_RT.GLOB)
|
||||
EgtMove( idProcCopy, 500 * GEO.EPS_SMALL * Proc.Faces[1].vtN, GDB_RT.GLOB)
|
||||
-- se i tagli non si intersecano, quello più esterno è da disattivare
|
||||
if not EgtTestSurfaceSurface( idProcCopy, idProcBCopy, GEO.EPS_SMALL) then
|
||||
if not ProcB.SlaveProcIndexes then
|
||||
ProcB.SlaveProcIndexes = {}
|
||||
end
|
||||
table.insert( ProcB.SlaveProcIndexes, i)
|
||||
Proc.nIndexMasterProc = j
|
||||
Proc.nFlg = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- se entrambi tagli di testa, si tiene sempre il primo ( ma non quello aggiunto dall'automatismo)
|
||||
if ( ID.IsHeadCut( Proc) and not EgtGetInfo( Proc.id, 'HEAD_ADD_CUT', 'i')) and ID.IsHeadCut( ProcB) then
|
||||
if not Proc.SlaveProcIndexes then
|
||||
@@ -828,7 +940,43 @@ local function GetFeatureInfoAndDependency( vProcSingleRot, Part)
|
||||
end
|
||||
end
|
||||
end
|
||||
return vProcSingleRot
|
||||
|
||||
if not HeadProc then
|
||||
HeadProc = HeadProcOriginal
|
||||
end
|
||||
if not TailProc then
|
||||
TailProc = TailProcOriginal
|
||||
end
|
||||
HeadProc.Topology = {}
|
||||
TailProc.Topology = {}
|
||||
HeadProc.Topology.sFamily = 'HeadCut'
|
||||
HeadProc.Topology.sName = 'HeadCut'
|
||||
TailProc.Topology.sFamily = 'TailCut'
|
||||
TailProc.Topology.sName = 'TailCut'
|
||||
HeadProc.AvailableStrategies = GetStrategies( HeadProc, Part.sAISetupConfig)
|
||||
TailProc.AvailableStrategies = GetStrategies( TailProc, Part.sAISetupConfig)
|
||||
-- per nesting, si settano come info gli offset X degli estremi dei tagli
|
||||
local HeadcutInfo = {}
|
||||
local PtSortedHead = BeamLib.GetSortedVertices( HeadProc)
|
||||
if PtSortedHead then
|
||||
HeadcutInfo.OffsetX = {}
|
||||
for i = 1, #PtSortedHead do
|
||||
table.insert( HeadcutInfo.OffsetX, Part.b3Part:getMax():getX() - PtSortedHead[i]:getX())
|
||||
end
|
||||
end
|
||||
local TailcutInfo = {}
|
||||
local PtSortedTail = BeamLib.GetSortedVertices( TailProc)
|
||||
if PtSortedTail then
|
||||
TailcutInfo.OffsetX = {}
|
||||
for i = 1, #PtSortedHead do
|
||||
table.insert( TailcutInfo.OffsetX, Part.b3Part:getMin():getX() - PtSortedTail[i]:getX())
|
||||
end
|
||||
end
|
||||
-- per nesting, si settano come info le normali delle facce di taglio
|
||||
HeadcutInfo.vtN = HeadProc.Faces[1].vtN
|
||||
TailcutInfo.vtN = TailProc.Faces[1].vtN
|
||||
|
||||
return vProcSingleRot, HeadcutInfo, TailcutInfo
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
@@ -983,6 +1131,9 @@ local function CalculateStrategies( vProcSingleRot, Part)
|
||||
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine = 99
|
||||
end
|
||||
|
||||
if not Proc.AvailableStrategies.dAllStrategiesTotalTime then
|
||||
Proc.AvailableStrategies.dAllStrategiesTotalTime = 0
|
||||
end
|
||||
Proc.AvailableStrategies.dAllStrategiesTotalTime = Proc.AvailableStrategies.dAllStrategiesTotalTime + Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine
|
||||
-- se scelta strategia in modalità base o standard, esco subito alla prima che trovo completa
|
||||
if Part.GeneralParameters.GEN_sMachiningStrategy == 'FIRST_IN_LIST' and Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus == 'Complete' then
|
||||
@@ -1192,7 +1343,11 @@ local function CalculateMachinings( vProc, Part, nInitialRotation)
|
||||
local StrategyScriptName = Proc.ChosenStrategy.sStrategyId .. '\\' .. Proc.ChosenStrategy.sStrategyId
|
||||
local StrategyScript = require( StrategyScriptName)
|
||||
-- eseguo la strategia e si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati
|
||||
_, _ = StrategyScript.Make( true, Proc, Part, Proc.ChosenStrategy)
|
||||
local _, Result = StrategyScript.Make( true, Proc, Part, Proc.ChosenStrategy)
|
||||
-- per i tagli di testa e coda, che non hanno girato nel CalculateStrategies, si devono settare i risultati
|
||||
if ID.IsHeadCut( Proc) or ID.IsTailCut( Proc) then
|
||||
Proc.ChosenStrategy.Result = Result
|
||||
end
|
||||
-- se tutte le strategie disponibili non sono applicabili
|
||||
else
|
||||
local nOffsetIndex = EgtIf( Part.bPartInCombiIsInverted, 4, 0)
|
||||
@@ -1244,12 +1399,16 @@ function BeamExec.GetProcessings( PARTS, bIsFlipRot)
|
||||
-- se è prerotazione, oltre al ciclo normale, si devono verificare anche invertiti
|
||||
local bCalcInverted = bIsFlipRot and PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion
|
||||
local nCycles = EgtIf( bCalcInverted, 2, 1)
|
||||
PARTS[nPart].HeadcutInfo = {}
|
||||
PARTS[nPart].TailcutInfo = {}
|
||||
-- per ogni inversione
|
||||
for nInvertIndex = 1, nCycles do
|
||||
-- per ogni rotazione
|
||||
for nRotIndex = 1, 4 do
|
||||
local nOffsetIndex = EgtIf( nInvertIndex == 2, 4, 0)
|
||||
-- le rotazioni sono 1,2,3,4 (0, 90, 180, 270) e 5,6,7,8 (le stesse invertite)
|
||||
local nIndex = nRotIndex + nOffsetIndex
|
||||
local HeadcutInfo, TailcutInfo
|
||||
-- si calcolano le feature solo se la rotazione può essere presa in considerazione
|
||||
if PARTS[nPart].CombinationList.Rotations[nRotIndex] == 1 then
|
||||
-- recupero le feature di lavorazione della trave
|
||||
@@ -1257,11 +1416,23 @@ function BeamExec.GetProcessings( PARTS, bIsFlipRot)
|
||||
|
||||
-- recupero informazioni ausiliarie feature e dipendenze tra feature stesse
|
||||
-- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no
|
||||
vProcRot[nIndex] = GetFeatureInfoAndDependency( vProcRot[nIndex], PARTS[nPart])
|
||||
vProcRot[nIndex], HeadcutInfo, TailcutInfo = GetFeatureInfoAndDependency( vProcRot[nIndex], PARTS[nPart])
|
||||
else
|
||||
-- inserisco una tabella vuota
|
||||
table.insert( vProcRot, {})
|
||||
end
|
||||
if HeadcutInfo then
|
||||
PARTS[nPart].HeadcutInfo[nIndex] = {
|
||||
OffsetX = HeadcutInfo.OffsetX,
|
||||
vtN = HeadcutInfo.vtN
|
||||
}
|
||||
end
|
||||
if TailcutInfo then
|
||||
PARTS[nPart].TailcutInfo[nIndex] = {
|
||||
OffsetX = TailcutInfo.OffsetX,
|
||||
vtN = TailcutInfo.vtN
|
||||
}
|
||||
end
|
||||
-- rotazione pezzo di 90° per volta
|
||||
BeamLib.RotateRawPart( PARTS[nPart], 1)
|
||||
-- aggiorno info pezzo
|
||||
@@ -1491,13 +1662,15 @@ local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bRePro
|
||||
for nProc = 1, #ProcessingsOnPart.Rotation[1] do
|
||||
-- Si controlla sempre la rotazione 1 perchè la dipendenza di una feature da un'altra non dipende dalla rotazione
|
||||
-- se feature disattivata perchè eseguita da master a lei associata dichiaro comunque eseguita
|
||||
if ProcessingsOnPart.Rotation[1][nProc].nFlg == 0 and ProcessingsOnPart.Rotation[1][nProc].nIndexMasterProc then
|
||||
ProcessingsOnPart.Rotation[1][nProc].nIndexRotation = nUnloadPos
|
||||
table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[1][nProc])
|
||||
local ProcOnFirstRotation = ProcessingsOnPart.Rotation[1][nProc]
|
||||
if ProcOnFirstRotation.nFlg == 0 and ProcOnFirstRotation.nIndexMasterProc then
|
||||
ProcOnFirstRotation.nIndexRotation = nUnloadPos
|
||||
table.insert( SingleCombination.Rot0, ProcOnFirstRotation)
|
||||
SingleCombination.nComplete = SingleCombination.nComplete + 1
|
||||
else
|
||||
local nOffsetIndex = EgtIf( SingleCombination.bPartInCombiIsInverted, 4, 0)
|
||||
if not ID.IsHeadCut( ProcessingsOnPart.Rotation[1][nProc]) and not ID.IsTailCut( ProcessingsOnPart.Rotation[1][nProc]) then
|
||||
if not ( ( ID.IsHeadCut( ProcOnFirstRotation) and ProcOnFirstRotation.bIsOriginalHeadcut)
|
||||
or ( ID.IsTailCut( ProcOnFirstRotation) and ProcOnFirstRotation.bIsOriginalTailcut)) then
|
||||
-- ciclo sulle rotazioni
|
||||
local nNextRot = nUnloadPos
|
||||
local ResultsList = {}
|
||||
@@ -1523,34 +1696,40 @@ local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bRePro
|
||||
nNextRot = EgtIf( nNextRot + 1 > 4, nNextRot + 1 - 4, nNextRot + 1)
|
||||
end
|
||||
|
||||
-- se la feature può essere lavorata in almeno una rotazione
|
||||
if #ResultsList > 0 then
|
||||
local Proc, Data = GetProcBestMachRotationFromList( ResultsList, PartInfo)
|
||||
Proc.nIndexRotation = Data.nIndexRotation
|
||||
-- inserisco la Proc nell'apposita lista
|
||||
if Data.nIndexRotation == nUnloadPos then
|
||||
table.insert( SingleCombination.Rot0, Proc)
|
||||
elseif Data.nIndexRotation == nUnloadPos + 1 then
|
||||
table.insert( SingleCombination.Rot90, Proc)
|
||||
bRot90 = true
|
||||
else
|
||||
table.insert( SingleCombination.Rot180, Proc)
|
||||
bRot180 = true
|
||||
end
|
||||
|
||||
SingleCombination.dTotalTimeToMachine = SingleCombination.dTotalTimeToMachine + Data.dTimeToMachine
|
||||
SingleCombination.dTotalQuality = SingleCombination.dTotalQuality + Data.dQuality
|
||||
SingleCombination.dTotalCompletionIndex = SingleCombination.dTotalCompletionIndex + Data.dCompletionIndex
|
||||
SingleCombination.nComplete = SingleCombination.nComplete + EgtIf( Data.bComplete, 1, 0)
|
||||
SingleCombination.nNotComplete = SingleCombination.nNotComplete + EgtIf( Data.bNotComplete, 1, 0)
|
||||
SingleCombination.nNotExecute = SingleCombination.nNotExecute + EgtIf( Data.bNotApplicable, 1, 0)
|
||||
SingleCombination.nIndexInCombinationList = i
|
||||
SingleCombination.nIndexRotation = nUnloadPos
|
||||
-- se la feature può essere lavorata in almeno una rotazione e non è un taglio di testa o coda
|
||||
if ID.IsHeadCut( ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc]) then
|
||||
SingleCombination.nIndexHeadCutInVProc = nProc
|
||||
elseif ID.IsTailCut( ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc]) then
|
||||
SingleCombination.nIndexTailCutInVProc = nProc
|
||||
else
|
||||
ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc].nIndexRotation = nUnloadPos
|
||||
ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc].nFlg = 0
|
||||
table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc])
|
||||
SingleCombination.nNotExecute = SingleCombination.nNotExecute + 1
|
||||
if #ResultsList > 0 then
|
||||
local Proc, Data = GetProcBestMachRotationFromList( ResultsList, PartInfo)
|
||||
Proc.nIndexRotation = Data.nIndexRotation
|
||||
-- inserisco la Proc nell'apposita lista
|
||||
if Data.nIndexRotation == nUnloadPos then
|
||||
table.insert( SingleCombination.Rot0, Proc)
|
||||
elseif Data.nIndexRotation == nUnloadPos + 1 then
|
||||
table.insert( SingleCombination.Rot90, Proc)
|
||||
bRot90 = true
|
||||
else
|
||||
table.insert( SingleCombination.Rot180, Proc)
|
||||
bRot180 = true
|
||||
end
|
||||
|
||||
SingleCombination.dTotalTimeToMachine = SingleCombination.dTotalTimeToMachine + Data.dTimeToMachine
|
||||
SingleCombination.dTotalQuality = SingleCombination.dTotalQuality + Data.dQuality
|
||||
SingleCombination.dTotalCompletionIndex = SingleCombination.dTotalCompletionIndex + Data.dCompletionIndex
|
||||
SingleCombination.nComplete = SingleCombination.nComplete + EgtIf( Data.bComplete, 1, 0)
|
||||
SingleCombination.nNotComplete = SingleCombination.nNotComplete + EgtIf( Data.bNotComplete, 1, 0)
|
||||
SingleCombination.nNotExecute = SingleCombination.nNotExecute + EgtIf( Data.bNotApplicable, 1, 0)
|
||||
SingleCombination.nIndexInCombinationList = i
|
||||
SingleCombination.nIndexRotation = nUnloadPos
|
||||
else
|
||||
ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc].nIndexRotation = nUnloadPos
|
||||
ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc].nFlg = 0
|
||||
table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc])
|
||||
SingleCombination.nNotExecute = SingleCombination.nNotExecute + 1
|
||||
end
|
||||
end
|
||||
else
|
||||
if ID.IsHeadCut( ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc]) then
|
||||
@@ -1665,7 +1844,7 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
|
||||
nPhase = nPhase}
|
||||
table.insert( DB_MACH_APPLIED, MachExtraInfo)
|
||||
else
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
BeamLib.AddPhaseWithRawParts( PARTS, nPart, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
end
|
||||
-- si sposta il pezzo nella posizione originale, di quando è stata fatta la collect. In questo modo tutti i dati calcolati nella collect restano validi.
|
||||
-- Altrimenti bisognava ricalcolare tutto, aumentando tempo di calcolo.
|
||||
@@ -1772,8 +1951,9 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
|
||||
local nInitialPosition = MatrixResult.nInitialPosition
|
||||
-- PREROTAZIONE PEZZO
|
||||
if MatrixResult.nInitialPosition ~= 1 or PARTS[nPart].bPartInCombiIsInverted then
|
||||
-- si toglie il pezzo dal grezzo per poter fare operazioni
|
||||
EgtRemovePartFromRawPart( PARTS[nPart].id)
|
||||
-- si esce dalle lavorazioni e si torna in disegna
|
||||
local nCurrMachGroup = EgtGetCurrMachGroup()
|
||||
EgtResetCurrMachGroup()
|
||||
|
||||
-- salvo situazione precedente su lista BEAM ( scrittura variabili globali per interfaccia)
|
||||
if bIsFlipRot then
|
||||
@@ -1795,11 +1975,8 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
|
||||
EgtRotate( PARTS[nPart].id, ptRot, X_AX(), nRotationDeg, GDB_RT.GLOB)
|
||||
end
|
||||
|
||||
-- si rimette il pezzo nel grezzo
|
||||
EgtAddPartToRawPart( PARTS[nPart].id, {0,0,0}, PARTS[nPart].idRaw)
|
||||
|
||||
-- dico che il pezzo originale è nella posizione iniziale come arriva da BTL ( è stato appena ruotato qui sopra)
|
||||
nInitialPosition = 1
|
||||
-- si riattiva il MachGroup, i pezzi son rimasti dove erano
|
||||
EgtSetCurrMachGroup( nCurrMachGroup)
|
||||
end
|
||||
|
||||
-- salvo sul PART la posizione di partenza che è stata scelta
|
||||
@@ -1825,7 +2002,7 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
|
||||
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
|
||||
nCurrPosition = nRotation
|
||||
EgtSetInfo( idDisp, 'ROT', -2)
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'DOWN')
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS, PARTS[nPart], 'DOWN')
|
||||
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
|
||||
bProcess = bProcess or bTryToReProcess
|
||||
end
|
||||
@@ -1834,7 +2011,7 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
|
||||
if MatrixResult.bSomeFeatureSide then
|
||||
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
|
||||
if MatrixResult.bSomeFeatureDown then
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
|
||||
BeamLib.AddPhaseWithRawParts( PARTS, nPart, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
|
||||
nPhase = EgtGetCurrPhase()
|
||||
idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( idDisp, 'ORD', nOrd)
|
||||
@@ -1853,14 +2030,14 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
|
||||
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
|
||||
nCurrPosition = nRotation
|
||||
EgtSetInfo( idDisp, 'ROT', -1)
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'SIDE')
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS, PARTS[nPart], 'SIDE')
|
||||
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
|
||||
bProcess = bProcess or bTryToReProcess
|
||||
end
|
||||
|
||||
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
|
||||
if MatrixResult.bSomeFeatureDown or MatrixResult.bSomeFeatureSide then
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
|
||||
BeamLib.AddPhaseWithRawParts( PARTS, nPart, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
|
||||
nPhase = EgtGetCurrPhase()
|
||||
idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( idDisp, 'ORD', nOrd)
|
||||
@@ -1879,7 +2056,7 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
|
||||
BeamLib.RotateRawPart( PARTS[nPart], nInitialPosition - 1)
|
||||
|
||||
-- aggiunta lavorazioni in ultima fase
|
||||
_, _, _, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'STD')
|
||||
_, _, _, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS, PARTS[nPart], 'STD')
|
||||
bProcess = bProcess or bTryToReProcess
|
||||
|
||||
-- se bisogna riprocessare, si annulla tutto
|
||||
@@ -1895,8 +2072,6 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
|
||||
if PARTS[nPart].bPartInCombiIsInverted then
|
||||
BeamLib.InvertRawPart( PARTS[nPart], -2)
|
||||
end
|
||||
-- ripristino anche eventuali pre-rotazioni
|
||||
nInitialPosition = nInitialPosition + ( BEAM.PREROTATE90 or 0)
|
||||
-- si ribalta il pezzo in posizione iniziale
|
||||
BeamLib.RotateRawPart( PARTS[nPart], 1 - nInitialPosition)
|
||||
else
|
||||
@@ -1921,7 +2096,7 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
|
||||
-- ===== finiti i pezzi, si scarica il restante =====
|
||||
local idRestPart = EgtGetNextRawPart( PARTS[#PARTS].idRaw)
|
||||
if idRestPart and EgtGetRawPartBBox( idRestPart):getDimX() >= BeamData.dMinRaw then
|
||||
BeamLib.AddPhaseWithRawParts( idRestPart, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
BeamLib.AddPhaseWithRawParts( PARTS, #PARTS + 1, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
local nPhase = EgtGetCurrPhase()
|
||||
local idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( idDisp, 'TYPE', 'REST')
|
||||
@@ -1966,8 +2141,8 @@ end
|
||||
function BeamExec.ProcessAlternatives( PARTS)
|
||||
|
||||
-- inizializzazione variabili globali per interfaccia
|
||||
BEAM.ALTERNATIVESNEST2D = ''
|
||||
BEAM.ALTERNATIVES = ''
|
||||
local Alternatives = {}
|
||||
local AlternativesNest2D = {}
|
||||
|
||||
-- ciclo sui pezzi
|
||||
local BestCombination = {}
|
||||
@@ -2197,7 +2372,7 @@ function BeamExec.ProcessAlternatives( PARTS)
|
||||
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
|
||||
nCurrPosition = nRotation
|
||||
EgtSetInfo( idDisp, 'ROT', -2)
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'DOWN')
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS, PARTS[nPart], 'DOWN')
|
||||
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
|
||||
bProcess = bProcess or bTryToReProcess
|
||||
end
|
||||
@@ -2206,7 +2381,7 @@ function BeamExec.ProcessAlternatives( PARTS)
|
||||
if MatrixResult.bSomeFeatureSide then
|
||||
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
|
||||
if MatrixResult.bSomeFeatureDown then
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
|
||||
BeamLib.AddPhaseWithRawParts( PARTS, nPart, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
|
||||
nPhase = EgtGetCurrPhase()
|
||||
idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( idDisp, 'ORD', nOrd)
|
||||
@@ -2225,14 +2400,14 @@ function BeamExec.ProcessAlternatives( PARTS)
|
||||
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
|
||||
nCurrPosition = nRotation
|
||||
EgtSetInfo( idDisp, 'ROT', -1)
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'SIDE')
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS, PARTS[nPart], 'SIDE')
|
||||
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
|
||||
bProcess = bProcess or bTryToReProcess
|
||||
end
|
||||
|
||||
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
|
||||
if MatrixResult.bSomeFeatureDown or MatrixResult.bSomeFeatureSide then
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
|
||||
BeamLib.AddPhaseWithRawParts( PARTS, nPart, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
|
||||
nPhase = EgtGetCurrPhase()
|
||||
idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( idDisp, 'ORD', nOrd)
|
||||
@@ -2251,7 +2426,7 @@ function BeamExec.ProcessAlternatives( PARTS)
|
||||
BeamLib.RotateRawPart( PARTS[nPart], nInitialPosition - 1)
|
||||
|
||||
-- aggiunta lavorazioni in ultima fase
|
||||
_, _, _, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'STD')
|
||||
_, _, _, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS, PARTS[nPart], 'STD')
|
||||
bProcess = bProcess or bTryToReProcess
|
||||
|
||||
-- se bisogna riprocessare, si annulla tutto
|
||||
@@ -2285,7 +2460,7 @@ function BeamExec.ProcessAlternatives( PARTS)
|
||||
-- ===== finiti i pezzi, si scarica il restante =====
|
||||
local idRestPart = EgtGetNextRawPart( PARTS[#PARTS].idRaw)
|
||||
if idRestPart and EgtGetRawPartBBox( idRestPart):getDimX() >= BeamData.dMinRaw then
|
||||
BeamLib.AddPhaseWithRawParts( idRestPart, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
BeamLib.AddPhaseWithRawParts( PARTS, #PARTS + 1, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
local nPhase = EgtGetCurrPhase()
|
||||
local idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( idDisp, 'TYPE', 'REST')
|
||||
@@ -2296,23 +2471,14 @@ function BeamExec.ProcessAlternatives( PARTS)
|
||||
local bApplOk, _, _ = EgtApplyAllMachinings()
|
||||
-- se non ci sono errori, soluzione alternativa valida: scrittura variabili globali per interfaccia
|
||||
if bApplOk then
|
||||
local Alternatives = {}
|
||||
local sBitIndexCombinationWithInvert = BestCombination.sBitIndexCombination .. EgtIf( BestCombination.bPartInCombiIsInverted, '_INV', '')
|
||||
if TotalCombiToTest[z].bIsNesting2D then
|
||||
if BEAM.ALTERNATIVESNEST2D and BEAM.ALTERNATIVESNEST2D ~= "" then
|
||||
table.insert( Alternatives, BEAM.ALTERNATIVESNEST2D)
|
||||
end
|
||||
table.insert( Alternatives, sBitIndexCombinationWithInvert)
|
||||
BEAM.ALTERNATIVESNEST2D = table.concat( Alternatives, ', ')
|
||||
table.insert( AlternativesNest2D, sBitIndexCombinationWithInvert)
|
||||
else
|
||||
if BEAM.ALTERNATIVES and BEAM.ALTERNATIVES ~= "" then
|
||||
table.insert( Alternatives, BEAM.ALTERNATIVES)
|
||||
end
|
||||
table.insert( Alternatives, sBitIndexCombinationWithInvert)
|
||||
BEAM.ALTERNATIVES = table.concat( Alternatives, ', ')
|
||||
end
|
||||
end
|
||||
-- se ultima combinazione, si esce e non si riporta in posizione inizale. Verrà infatti cancellata
|
||||
-- se ultima combinazione, si esce e non si riporta in posizione iniziale. Verrà infatti cancellata
|
||||
if z == #TotalCombiToTest then break end
|
||||
|
||||
-- si riporta pezzo in posizione iniziale
|
||||
@@ -2326,6 +2492,23 @@ function BeamExec.ProcessAlternatives( PARTS)
|
||||
|
||||
end
|
||||
|
||||
-- passaggio info a interfaccia da scrivere sul pezzo
|
||||
BEAM.INFONGEPART = {}
|
||||
table.insert( BEAM.INFONGEPART, 'INITIALPOSITION=' .. PARTS[nPart].nInitialPosition)
|
||||
for i = 1, #AlternativesNest2D do
|
||||
local sRotation = BeamLib.ConvertBitIndexToRotationIndex( AlternativesNest2D[i])
|
||||
if PARTS[nPart].HeadcutInfo then
|
||||
local sOffsetX = table.concat( PARTS[nPart].HeadcutInfo[sRotation].OffsetX, ',')
|
||||
local sVtN = ( tostring( PARTS[nPart].HeadcutInfo[sRotation].vtN)):gsub("^%(", ""):gsub("%)$", "")
|
||||
table.insert( BEAM.INFONGEPART, 'ALT' .. AlternativesNest2D[i].. '_H' .. '=' .. sOffsetX .. ';' .. sVtN )
|
||||
end
|
||||
if PARTS[nPart].TailcutInfo then
|
||||
local sOffsetX = table.concat( PARTS[nPart].TailcutInfo[sRotation].OffsetX, ',')
|
||||
local sVtN = ( tostring( PARTS[nPart].TailcutInfo[sRotation].vtN)):gsub("^%(", ""):gsub("%)$", "")
|
||||
table.insert( BEAM.INFONGEPART, 'ALT' .. AlternativesNest2D[i] .. '_T' .. '=' .. sOffsetX .. ';' .. sVtN)
|
||||
end
|
||||
end
|
||||
|
||||
-- si cancella eventuale mach group creato per le alternative
|
||||
EgtRemoveMachGroup( nTempMachGroupName)
|
||||
|
||||
|
||||
+157
-14
@@ -161,17 +161,45 @@ function BeamLib.GetPartSplittingPoints( Part)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamLib.AddPhaseWithRawParts( idRaw, OriXR, PosXR, dDeltaSucc)
|
||||
function BeamLib.AddPhaseWithRawParts( PARTS, nPartIndex, OriXR, PosXR, dDeltaSucc)
|
||||
local nPhase = EgtAddPhase()
|
||||
local Part
|
||||
local idRaw
|
||||
-- se l'indice è oltre significa che è l'ultimo grezzo senza pezzi
|
||||
if nPartIndex > #PARTS then
|
||||
idRaw = EgtGetNextRawPart( PARTS[#PARTS].idRaw)
|
||||
else
|
||||
Part = PARTS[nPartIndex]
|
||||
idRaw = Part.idRaw
|
||||
end
|
||||
-- si aprono i limiti tavola per permettere rotazioni di pezzi più larghi della tavola
|
||||
EgtSetTableAreaOffset( 2000, 2000, 2000, 2000)
|
||||
local dRawMove = 0
|
||||
local bIsFirstRaw = true
|
||||
local dPosXFirst = 0
|
||||
while idRaw do
|
||||
local dPosX
|
||||
for i = 1, #PARTS do
|
||||
local CurrentPart = PARTS[i]
|
||||
if CurrentPart.idRaw == idRaw then
|
||||
dPosX = CurrentPart.dPosX
|
||||
if bIsFirstRaw then
|
||||
dPosXFirst = dPosX
|
||||
end
|
||||
break
|
||||
end
|
||||
if i == #PARTS then
|
||||
dPosX = PARTS[i].dPosX + PARTS[i].b3Raw:getDimX()
|
||||
end
|
||||
end
|
||||
if bIsFirstRaw then
|
||||
bIsFirstRaw = false
|
||||
else
|
||||
dRawMove = dDeltaSucc + dPosX - dPosXFirst
|
||||
end
|
||||
EgtKeepRawPart( idRaw)
|
||||
EgtMoveToCornerRawPart( idRaw, OriXR, PosXR)
|
||||
EgtMoveRawPart( idRaw, Vector3d( - dRawMove, 0, 0))
|
||||
if dRawMove == 0 then dRawMove = dRawMove + dDeltaSucc end
|
||||
dRawMove = dRawMove + EgtGetRawPartBBox( idRaw):getDimX()
|
||||
idRaw = EgtGetNextRawPart( idRaw)
|
||||
end
|
||||
-- salvo info nuova fase aggiunta
|
||||
@@ -395,6 +423,24 @@ function BeamLib.GetAddGroup( PartId)
|
||||
return AddGrpId, sMchGrp
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- Funzione prossimo nome MachGroup libero (numero intero)
|
||||
function BeamLib.GetNewMachGroupName()
|
||||
local idMachGroup = EgtGetFirstMachGroup()
|
||||
if not idMachGroup then return 1 end
|
||||
local nMaxMachGroup = 0
|
||||
while idMachGroup do
|
||||
local sMachGroupName = EgtGetMachGroupName( idMachGroup)
|
||||
local nMachGroupName = tonumber( sMachGroupName)
|
||||
if nMachGroupName > nMaxMachGroup then
|
||||
nMaxMachGroup = nMachGroupName
|
||||
end
|
||||
idMachGroup = EgtGetNextMachGroup( idMachGroup)
|
||||
end
|
||||
|
||||
return nMaxMachGroup + 1
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- restituisce le facce della parte interessate dalla feature Proc
|
||||
-- TODO da spostare in FeatureLib???
|
||||
@@ -512,10 +558,69 @@ function BeamLib.GetDirectionFromSCC( nSCC)
|
||||
elseif nSCC == MCH_SCC.ADIR_ZM then
|
||||
vtSCC = -Z_AX()
|
||||
end
|
||||
|
||||
|
||||
return vtSCC
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- Restituisce una tabella con i punti ai vertici della faccia, in globale
|
||||
-- ordinati partendo da quello ai valori minimi degli assi e i successivi secondo rotazione destrorsa X+;
|
||||
-- solo per Proc a 1 faccia
|
||||
function BeamLib.GetSortedVertices( Proc)
|
||||
local PtVerticesSorted = {}
|
||||
|
||||
-- se più di una faccia si esce subito
|
||||
if Proc.nFct > 1 then
|
||||
return
|
||||
end
|
||||
|
||||
local PtVertices = {}
|
||||
local nFirstIndex
|
||||
local dMinYZ = GEO.INFINITO
|
||||
for i = 1, #Proc.Faces[1].Edges do
|
||||
local Edge = Proc.Faces[1].Edges[i]
|
||||
table.insert( PtVertices, Edge.ptStart)
|
||||
if ( Edge.ptStart:getY() + Edge.ptStart:getZ() < dMinYZ) then
|
||||
nFirstIndex = i
|
||||
dMinYZ = Edge.ptStart:getY() + Edge.ptStart:getZ()
|
||||
end
|
||||
end
|
||||
|
||||
table.insert( PtVerticesSorted, PtVertices[nFirstIndex])
|
||||
local nCurrentIndex = nFirstIndex
|
||||
-- faccia che guarda verso X+, ordine ok
|
||||
if Proc.Faces[1].vtN:getX() > GEO.EPS_SMALL then
|
||||
for _ = 1, #PtVertices - 1 do
|
||||
_, nCurrentIndex = BeamLib.GetAdjacentIndices( nCurrentIndex, #PtVertices)
|
||||
table.insert( PtVerticesSorted, PtVertices[nCurrentIndex])
|
||||
end
|
||||
-- faccia che guarda verso X-, ordine da invertire
|
||||
else
|
||||
for _ = 1, #PtVertices - 1 do
|
||||
nCurrentIndex = BeamLib.GetAdjacentIndices( nCurrentIndex, #PtVertices)
|
||||
table.insert( PtVerticesSorted, PtVertices[nCurrentIndex])
|
||||
end
|
||||
end
|
||||
|
||||
return PtVerticesSorted
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- restituisce il precedente e prossimo indice 1-based, tenendo conto del massimo indice
|
||||
function BeamLib.GetAdjacentIndices( nCurrentIndex, nMaxIndex)
|
||||
local nPreviousIndex, nNextIndex
|
||||
|
||||
if ( nCurrentIndex < 1) or ( nCurrentIndex > nMaxIndex) then
|
||||
return
|
||||
end
|
||||
|
||||
-- circular indexing 1-based
|
||||
nPreviousIndex = ((nCurrentIndex - 2 + nMaxIndex) % nMaxIndex) + 1
|
||||
nNextIndex = (nCurrentIndex % nMaxIndex) + 1
|
||||
|
||||
return nPreviousIndex, nNextIndex
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce
|
||||
function BeamLib.Is3EdgesApprox( Proc, idFace, nAddGrpId)
|
||||
@@ -785,17 +890,18 @@ function BeamLib.BinaryToDecimal( dNumber)
|
||||
local sNumberToConvert = tostring( dNumber)
|
||||
local dResult = 0
|
||||
local k = 0
|
||||
|
||||
|
||||
for i = #sNumberToConvert, 1, -1 do
|
||||
k = k + 1
|
||||
local n = string.sub(sNumberToConvert, k, k)
|
||||
dResult = dResult + n*(2^(i-1))
|
||||
local n = string.sub( sNumberToConvert, k, k)
|
||||
dResult = dResult + n * ( 2^( i-1))
|
||||
end
|
||||
|
||||
|
||||
return dResult
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- TODO si può sostituire con funzione EgtNumToBitString
|
||||
function BeamLib.DecimalToBinary( dNumber)
|
||||
local sNumberToConvert = tostring( dNumber)
|
||||
local n = sNumberToConvert
|
||||
@@ -803,12 +909,12 @@ function BeamLib.DecimalToBinary( dNumber)
|
||||
local sResult = ""
|
||||
|
||||
for i = sNumberToConvert, 0, -1 do
|
||||
local q = math.modf(n)
|
||||
n = n/2
|
||||
local b = q%2
|
||||
table.insert(tmp, b)
|
||||
local q = math.modf( n)
|
||||
n = n / 2
|
||||
local b = q % 2
|
||||
table.insert( tmp, b)
|
||||
|
||||
if (q == 1) then
|
||||
if ( q == 1) then
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -816,7 +922,7 @@ function BeamLib.DecimalToBinary( dNumber)
|
||||
for i = #tmp, 1, -1 do
|
||||
sResult = sResult..tmp[i]
|
||||
end
|
||||
|
||||
|
||||
return tonumber( sResult)
|
||||
end
|
||||
|
||||
@@ -830,6 +936,43 @@ function BeamLib.CalculateStringBinaryFormat( dNumber, CharNumber)
|
||||
return NumberString
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamLib.ConvertBitIndexToRotationIndex( sBitIndexCombination)
|
||||
local nRotationIndex
|
||||
|
||||
if sBitIndexCombination == '1000' then
|
||||
return 1
|
||||
elseif sBitIndexCombination == '0100' then
|
||||
return 2
|
||||
elseif sBitIndexCombination == '0010' then
|
||||
return 3
|
||||
elseif sBitIndexCombination == '0001' then
|
||||
return 4
|
||||
elseif sBitIndexCombination == '1000_INV' then
|
||||
return 5
|
||||
elseif sBitIndexCombination == '0100_INV' then
|
||||
return 6
|
||||
elseif sBitIndexCombination == '0010_INV' then
|
||||
return 7
|
||||
elseif sBitIndexCombination == '0001_INV' then
|
||||
return 8
|
||||
end
|
||||
|
||||
return nRotationIndex
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- reindicizza una tabella passata ripartendo dall'indice nStartIndex e mantenendo l'ordine
|
||||
function BeamLib.RotateTableFromIndex( Table, nStartIndex)
|
||||
local RotatedTable = {}
|
||||
|
||||
for i = 1, #Table do
|
||||
RotatedTable[#RotatedTable + 1] = Table[((RotatedTable + i - 2) % #Table) + 1]
|
||||
end
|
||||
|
||||
return RotatedTable
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
--- copia una tabella lua in modo ricorsivo, ossia mantiene indipendenti anche tutte le sottotabelle
|
||||
--- ATTENZIONE: in caso di modifiche vanno gestiti anche i tipi custom; sarebbe meglio metterla nel LuaLibs
|
||||
|
||||
+1
-1
@@ -453,7 +453,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
|
||||
-- se piani non ortogonali, diminuisco la distanza di offset opportunamente
|
||||
local dOffsetParallelOriginal = dOffsetParallel
|
||||
if not bGetOrtoPlanes then
|
||||
local dCoeff = ( vtNMainFace ^ vtNSubordinateFace):len()
|
||||
local dCoeff = max( ( vtNMainFace ^ vtNSubordinateFace):len(), 0.5)
|
||||
dOffsetParallel = dOffsetParallel * dCoeff
|
||||
dOffsetOrthogonal = dOffsetOrthogonal * dCoeff
|
||||
end
|
||||
|
||||
@@ -43,7 +43,7 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- restituisce vero se la feature con box b3Proc taglia l'intera sezione della barra
|
||||
local function IsFeatureCuttingEntireSection( b3Proc, Part)
|
||||
function FeatureLib.IsFeatureCuttingEntireSection( b3Proc, Part)
|
||||
return ( b3Proc:getDimY() > ( Part.b3Part:getDimY() - 500 * GEO.EPS_SMALL) and b3Proc:getDimZ() > ( Part.b3Part:getDimZ() - 500 * GEO.EPS_SMALL))
|
||||
end
|
||||
|
||||
@@ -198,7 +198,7 @@ function FeatureLib.ClassifyTopology( Proc, Part)
|
||||
|
||||
if not Proc.AffectedFaces then Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) end
|
||||
|
||||
local bIsFeatureCuttingEntireSection = IsFeatureCuttingEntireSection( Proc.b3Box, Part)
|
||||
local bIsFeatureCuttingEntireSection = FeatureLib.IsFeatureCuttingEntireSection( Proc.b3Box, Part)
|
||||
local bIsFeatureCuttingEntireLength = IsFeatureCuttingEntireLength( Proc.b3Box, Part)
|
||||
local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc, Part)
|
||||
local vAdj = Proc.AdjacencyMatrix
|
||||
@@ -337,6 +337,9 @@ function FeatureLib.GetAdditionalInfo( Proc, Part)
|
||||
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
|
||||
Proc.Faces = FaceData.GetFacesInfo( Proc, Part)
|
||||
Proc.FeatureInfo, Proc.MainFaces = FeatureLib.GetRafterNotchData( Proc)
|
||||
elseif ( ID.IsScarfJoint( Proc) or ID.IsScarfSimple( Proc)) then
|
||||
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
|
||||
Proc.Faces = FaceData.GetFacesInfo( Proc, Part)
|
||||
end
|
||||
|
||||
return Proc
|
||||
|
||||
+34
-17
@@ -363,16 +363,22 @@ local function TestEngagement( sBladeEngagement, Parameters, OptionalParameters)
|
||||
-- attacco perpendicolare
|
||||
local PerpendicularLeadInOut = LeadInOutLib.CalculateLeadInOut( 'Perpendicular', Parameters, LeadInOutOptionalParameters)
|
||||
-- check extracorsa nei punti di attacco
|
||||
|
||||
PointsOnToolTipCenter = {
|
||||
PreSimulationLib.GetPointOnToolTipCenter( PerpendicularLeadInOut.LeadIn.ptPoint, vtHead, Face.vtN, Edge.vtN, Tool),
|
||||
PreSimulationLib.GetPointOnToolTipCenter( PerpendicularLeadInOut.LeadOut.ptPoint, vtHead, Face.vtN, Edge.vtN, Tool)
|
||||
}
|
||||
local bOutOfStrokePerpendicular = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool)
|
||||
-- se non è in extracorsa si aggiunge come attacco possibile
|
||||
-- attacco perpendicolare non in extracorsa: si verifica se è in collisione
|
||||
if not bOutOfStrokePerpendicular then
|
||||
LeadInOut.Perpendicular = PerpendicularLeadInOut
|
||||
LeadInOut.Perpendicular.bMoveAfterSplit = bMoveAfterSplit
|
||||
CheckCollisionOptionalParameters.PointsToCheck = {}
|
||||
table.insert( CheckCollisionOptionalParameters.PointsToCheck, PerpendicularLeadInOut.LeadIn.ptPoint)
|
||||
table.insert( CheckCollisionOptionalParameters.PointsToCheck, PerpendicularLeadInOut.LeadOut.ptPoint)
|
||||
local bCollisionFoundPerpendicular, bMoveAfterSplitPerpendicular = PreSimulationLib.CheckCollision( sBladeEngagement, CheckCollisionParameters, CheckCollisionOptionalParameters)
|
||||
-- attacco perpendicolare possibile
|
||||
if not bCollisionFoundPerpendicular then
|
||||
LeadInOut.Perpendicular = PerpendicularLeadInOut
|
||||
LeadInOut.Perpendicular.bMoveAfterSplit = bMoveAfterSplitPerpendicular
|
||||
end
|
||||
end
|
||||
-- se c'è almeno un lato chiuso l'unico attacco possibile è il perpendicolare
|
||||
if not ( Edge.bIsStartOpen and Edge.bIsEndOpen) then
|
||||
@@ -468,6 +474,11 @@ end
|
||||
function MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
local ToolInfo = {}
|
||||
|
||||
-- direzione utensile e fipo fresa obbligatori, altrimenti si esce
|
||||
if not ToolSearchParameters.vtToolDirection or not ToolSearchParameters.sMillShape then
|
||||
return ToolInfo
|
||||
end
|
||||
|
||||
local nBestToolIndex
|
||||
local dBestToolResidualDepth = 0
|
||||
for i = 1, #TOOLS do
|
||||
@@ -511,6 +522,18 @@ function MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
bIsToolCompatible = false
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO da sostituire con test collisione come lama
|
||||
local bIsFromBottom = ToolSearchParameters.vtToolDirection:getZ() < - 10 * GEO.EPS_SMALL
|
||||
local bIsFromTop = ToolSearchParameters.vtToolDirection:getZ() > 10 * GEO.EPS_SMALL
|
||||
local bIsSlanted = abs( ToolSearchParameters.vtToolDirection:getY()) > 0.707
|
||||
local bIsOnHeadOrTail = Proc.AffectedFaces.bLeft or Proc.AffectedFaces.bRight
|
||||
if ( ( bIsFromBottom and TOOLS[i].SetupInfo.HeadType.bTop) or ( bIsFromTop and TOOLS[i].SetupInfo.HeadType.bBottom))
|
||||
and ( not bIsSlanted)
|
||||
and ( not bIsOnHeadOrTail) then
|
||||
|
||||
bIsToolCompatible = false
|
||||
end
|
||||
|
||||
-- scelgo il migliore
|
||||
if bIsToolCompatible then
|
||||
@@ -579,13 +602,11 @@ end
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione per cercare utensile tipo LAMA con certe caratteristiche
|
||||
-- TODO da rivedere/completare
|
||||
-- TODO per Engagement serviranno (opzionali) sBlockedAxis e vtAux
|
||||
function MachiningLib.FindBlade( Proc, ToolSearchParameters)
|
||||
local ToolInfo = {}
|
||||
|
||||
-- parametri obbligatori
|
||||
if type( ToolSearchParameters.FaceToMachine) ~= 'table' then
|
||||
error( 'FindBlade : missing face info')
|
||||
end
|
||||
if type( ToolSearchParameters.bAllowTopHead) ~= 'boolean' then
|
||||
error( 'FindBlade : missing top head info')
|
||||
end
|
||||
@@ -607,6 +628,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
|
||||
local bIsDicing = ToolSearchParameters.bIsDicing or false
|
||||
local sRestLengthSideForPreSimulation = ToolSearchParameters.sRestLengthSideForPreSimulation or 'Tail'
|
||||
local bCannotSplitRestLength = ToolSearchParameters.bCannotSplitRestLength or false
|
||||
local bDisableRealElevationCheck = ToolSearchParameters.bDisableRealElevationCheck or false
|
||||
|
||||
local nBestToolIndex
|
||||
local dBestToolResidualDepth = 0
|
||||
@@ -640,7 +662,8 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
|
||||
local BladeEngagementOptionalParameters = {
|
||||
bIsDicing = bIsDicing,
|
||||
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
|
||||
bCannotSplitRestLength = bCannotSplitRestLength
|
||||
bCannotSplitRestLength = bCannotSplitRestLength,
|
||||
bDisableRealElevationCheck = bDisableRealElevationCheck
|
||||
}
|
||||
TIMER:startElapsed( 'GetBladeEngagement')
|
||||
bIsBladeOk, CurrentEngagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters)
|
||||
@@ -649,12 +672,6 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
|
||||
if not bIsBladeOk then
|
||||
bIsToolCompatible = false
|
||||
end
|
||||
|
||||
-- se si ha solo la faccia si può verificare se questa è orientata correttamente
|
||||
elseif FaceToMachine then
|
||||
if MachiningLib.IsFaceZOutOfRange( FaceToMachine.vtN, TOOLS[i]) then
|
||||
bIsToolCompatible = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1158,7 +1175,7 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- funzione per aggiungere una nuova lavorazione
|
||||
function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
|
||||
function MachiningLib.AddOperations( MACHININGS, PARTS, Part, sRotation)
|
||||
local nErr
|
||||
local sErr = ''
|
||||
local bAreAllMachiningApplyOk = true
|
||||
@@ -1426,7 +1443,7 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
|
||||
bSplitExecuted = true
|
||||
MACHININGS.Info.bSplitExecuted = true
|
||||
|
||||
BeamLib.AddPhaseWithRawParts( Part.idRaw, BeamData.ptOriXR, BeamData.dPosXR, BeamData.RAW_OFFSET)
|
||||
BeamLib.AddPhaseWithRawParts( PARTS, Part.nIndexInParts, BeamData.ptOriXR, BeamData.dPosXR, BeamData.RAW_OFFSET)
|
||||
-- se grezzo successivo senza pezzi e finale, va tolto
|
||||
local nNextRawId = EgtGetNextRawPart( Part.idRaw)
|
||||
if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BeamData.dMinRaw then
|
||||
@@ -1443,7 +1460,7 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
|
||||
local idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
|
||||
-- posizione iniziale considerando eventuiali prerotazioni
|
||||
local nRealInitialPosition = Part.nInitialPosition - ( BEAM.PREROTATE90 or 0)
|
||||
local nRealInitialPosition = Part.nInitialPosition
|
||||
if sRotation == 'DOWN' then
|
||||
local nRotation = EgtIf( nRealInitialPosition + 2 > 4, nRealInitialPosition + 2 - 4, nRealInitialPosition + 2) - 1
|
||||
BeamLib.RotateRawPart( Part, nRotation)
|
||||
|
||||
+135
-66
@@ -113,7 +113,7 @@ local function GetToolExitPoint( ptMachining, vtNEdge, vtHead, Tool, bIsDownUp)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- calcolo pivot in riferimento globale, datipunto sull'uscita utensile e direzioni
|
||||
-- calcolo pivot in riferimento globale, dati punto sull'uscita utensile e direzioni
|
||||
local function GetGlobalPivot( ptToolExit, vtC, vtHead, vtMovePivot)
|
||||
|
||||
-- frame solidale all'utensile (lo stesso in cui vtMovePivot è definito)
|
||||
@@ -269,32 +269,70 @@ function PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeometry, vtHead, nSCC
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CheckCollisionPoint( ptToolExitToCheck, vtC, vtHead, PreCollisionData, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, bCheckOnlyRestlength)
|
||||
local function MoveMachineAxesToPosition( ptOnToolTipCenter, vtHead, vtAux)
|
||||
|
||||
local ptPivot = GetGlobalPivot( ptToolExitToCheck, vtC, vtHead, PreCollisionData.vtMovePivot)
|
||||
-- calcolo assi rotativi
|
||||
local bOkAngles, nSolutionsAngles, RotativeAxesValues = EgtGetCalcAnglesEx( vtHead, vtAux)
|
||||
local dRotative1 = RotativeAxesValues[1]
|
||||
local dRotative2 = RotativeAxesValues[2]
|
||||
local dRotative3 = RotativeAxesValues[3]
|
||||
|
||||
-- orientamento del riferimento locale
|
||||
local vtDirectionX = PreCollisionData.Directions.vtDirectionX
|
||||
local vtDirectionY = PreCollisionData.Directions.vtDirectionY
|
||||
local vtDirectionZ = PreCollisionData.Directions.vtDirectionZ
|
||||
if not bOkAngles then
|
||||
error( ' MoveMachineAxesToPosition : error')
|
||||
end
|
||||
|
||||
-- costruzione trimesh a partire dalla curva di collisione
|
||||
-- recupero punti da macchina per costruire trimesh
|
||||
local CollisionCurvePoints = PreCollisionData.Points
|
||||
-- curva di collisione in riferimento locale
|
||||
local idCollisionCurve = EgtCurveCompoFromPoints( Part.idTempGroup, CollisionCurvePoints)
|
||||
-- curva in riferimento globale
|
||||
local frReference = Frame3d( ptPivot, vtDirectionZ, vtDirectionX)
|
||||
EgtTransform( idCollisionCurve, frReference, GDB_RT.GLOB)
|
||||
-- trimesh di collisione
|
||||
local idCollisionSurfTm
|
||||
if PreCollisionData.bSurfTmByRevolve then
|
||||
idCollisionSurfTm = EgtSurfTmByRevolve( Part.idTempGroup, idCollisionCurve, ptPivot, vtDirectionY, true, 0.05, GDB_RT.GLOB)
|
||||
else
|
||||
local vtPreMove = -vtDirectionZ * ( PreCollisionData.dExtrusionDepth / 2)
|
||||
EgtMove( idCollisionCurve, vtPreMove, GDB_RT.GLOB)
|
||||
local vtExtrusion = vtDirectionZ * PreCollisionData.dExtrusionDepth
|
||||
idCollisionSurfTm = EgtSurfTmByRegionExtrusion( Part.idTempGroup, idCollisionCurve, vtExtrusion, 0.05, GDB_RT.GLOB)
|
||||
-- calcolo assi lineari
|
||||
local bOkPositions, _, dLinear1, dLinear2, dLinear3 = EgtGetCalcPositions( ptOnToolTipCenter, dRotative1, dRotative2, dRotative3)
|
||||
|
||||
if not bOkPositions then
|
||||
|
||||
error( ' MoveMachineAxesToPosition : error')
|
||||
end
|
||||
|
||||
local AxesNames = EgtGetAllCurrAxesNames()
|
||||
local dTHome = EgtGetAxisHomePos( AxesNames[1])
|
||||
|
||||
-- spostamento assi in posizione (la T non si sposta perchè si sposta il pezzo)
|
||||
EgtSetAxisPos( AxesNames[2], dLinear2)
|
||||
EgtSetAxisPos( AxesNames[3], dLinear3)
|
||||
EgtSetAxisPos( AxesNames[4], dRotative1)
|
||||
EgtSetAxisPos( AxesNames[5], dRotative2)
|
||||
if dRotative3 then
|
||||
EgtSetAxisPos( AxesNames[6], dRotative3)
|
||||
end
|
||||
|
||||
return dLinear1 - dTHome
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function CheckCollisionPoint( sAxis, ptOnToolTipCenter, vtHead, vtAux, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, bCheckOnlyRestlength)
|
||||
|
||||
-- spostamento assi macchina in posizione
|
||||
local dDeltaXHeadOffset = MoveMachineAxesToPosition( ptOnToolTipCenter, vtHead, vtAux)
|
||||
|
||||
-- si recuperano gli id delle geometrie dell'asse con cui controllare la collisione
|
||||
local idCollisionGroup = EgtGetFirstNameInGroup( EgtGetAxisId( sAxis), 'COLLISION')
|
||||
local idCollisionGroupOther = EgtGetFirstNameInGroup( EgtGetAxisId( sAxis), 'OTHER_COLLISION') or GDB_ID.NULL
|
||||
local CollisionGroupEntitiesId = EgtGetAllInGroup( idCollisionGroup)
|
||||
local CollisionGroupOtherEntitiesId = EgtGetAllInGroup( idCollisionGroupOther)
|
||||
-- si tengono solo gli elementi trimesh
|
||||
local CollisionSurfTmId = {}
|
||||
for i = 1, #CollisionGroupEntitiesId do
|
||||
if EgtGetType( CollisionGroupEntitiesId[i]) == GDB_TY.SRF_MESH then
|
||||
local idCollisionSurfTmCopy = EgtCopyGlob( CollisionGroupEntitiesId[i], Part.idTempGroup)
|
||||
EgtMove( idCollisionSurfTmCopy, Vector3d( dDeltaXHeadOffset, 0, 0), GDB_RT.GLOB)
|
||||
table.insert( CollisionSurfTmId, idCollisionSurfTmCopy)
|
||||
end
|
||||
end
|
||||
-- se presenti geometrie nel gruppo other si aggiungono anche quelle
|
||||
if CollisionGroupOtherEntitiesId and #CollisionGroupOtherEntitiesId > 0 then
|
||||
for i = 1, #CollisionGroupOtherEntitiesId do
|
||||
if EgtGetType( CollisionGroupOtherEntitiesId[i]) == GDB_TY.SRF_MESH then
|
||||
local idCollisionOtherSurfTmCopy = EgtCopyGlob( CollisionGroupOtherEntitiesId[i], Part.idTempGroup)
|
||||
EgtMove( idCollisionOtherSurfTmCopy, Vector3d( dDeltaXHeadOffset, 0, 0), GDB_RT.GLOB)
|
||||
table.insert( CollisionSurfTmId, idCollisionOtherSurfTmCopy)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- check collisione con pezzo
|
||||
@@ -306,16 +344,22 @@ local function CheckCollisionPoint( ptToolExitToCheck, vtC, vtHead, PreCollision
|
||||
local b3CheckCollision = BeamLib.GetPartBoxWithHeadTail( Part, sRestLengthSideForPreSimulation)
|
||||
idCheckCollisionTm = EgtSurfTmBBox( Part.idTempGroup, b3CheckCollision, false, GDB_RT.GLOB)
|
||||
end
|
||||
bCollisionFoundPiece = EgtCDeSolidSolid( idCheckCollisionTm, idCollisionSurfTm, BeamData.COLL_SIC)
|
||||
if not type( bCollisionFoundPiece) == "boolean" then
|
||||
error( 'Presimulation fail')
|
||||
end
|
||||
if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then
|
||||
EgtSetColor( idCollisionSurfTm, RED())
|
||||
for i = 1, #CollisionSurfTmId do
|
||||
bCollisionFoundPiece = EgtCDeSolidSolid( idCheckCollisionTm, CollisionSurfTmId[i], BeamData.COLL_SIC)
|
||||
if not type( bCollisionFoundPiece) == "boolean" then
|
||||
error( 'Presimulation fail')
|
||||
end
|
||||
if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then
|
||||
EgtSetColor( CollisionSurfTmId[i], RED())
|
||||
end
|
||||
if bCollisionFoundPiece then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- se trovata collisione con pezzo è inutile procedere con il grezzo
|
||||
if bCollisionFoundPiece then
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -325,12 +369,17 @@ local function CheckCollisionPoint( ptToolExitToCheck, vtC, vtHead, PreCollision
|
||||
if not ( bCollisionFoundPiece or bCannotSplitRestLength) then
|
||||
local idRestLengthSurfFr = GetRestlengthSurfTm( Part, sRestLengthSideForPreSimulation)
|
||||
if idRestLengthSurfFr then
|
||||
bCollisionFoundRestLength = EgtCDeSolidSolid( idRestLengthSurfFr, idCollisionSurfTm, BeamData.COLL_SIC)
|
||||
if not type( bCollisionFoundRestLength) == "boolean" then
|
||||
error( 'Presimulation fail')
|
||||
end
|
||||
if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then
|
||||
EgtSetColor( idCollisionSurfTm, ORANGE())
|
||||
for i = 1, #CollisionSurfTmId do
|
||||
bCollisionFoundRestLength = EgtCDeSolidSolid( idRestLengthSurfFr, CollisionSurfTmId[i], BeamData.COLL_SIC)
|
||||
if not type( bCollisionFoundRestLength) == "boolean" then
|
||||
error( 'Presimulation fail')
|
||||
end
|
||||
if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then
|
||||
EgtSetColor( CollisionSurfTmId[i], ORANGE())
|
||||
end
|
||||
if bCollisionFoundRestLength then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -355,43 +404,29 @@ local function CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParam
|
||||
local bCheckOnlyRestlength = OptionalParameters.bCheckOnlyRestlength or false
|
||||
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
|
||||
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
|
||||
local vtAux = OptionalParameters.vtAux
|
||||
|
||||
-- se normale faccia non parallela a direzione testa c'è qualcosa che non va
|
||||
if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then
|
||||
error( 'CheckCollisionWithAxis : invalid directions')
|
||||
end
|
||||
|
||||
|
||||
-- punti notevoli della lavorazione in cui fare il check
|
||||
local PointsToCheck = OptionalParameters.PointsToCheck or GetCollisionPointsToCheck( Edge, dDepthToMachine)
|
||||
|
||||
-- punti in centro lama su naso mandrino o aggregato. In base a direzione e punto
|
||||
local bIsDownUp = AreOppositeVectorApprox( vtNFace, vtHead)
|
||||
local ToolExitPoints = {}
|
||||
-- punti sul tip dell'utensile, in centro
|
||||
local PointsOnToolTipCenter = {}
|
||||
for i = 1, #PointsToCheck do
|
||||
ToolExitPoints[i] = GetToolExitPoint( PointsToCheck[i], Edge.vtN, vtHead, Tool, bIsDownUp)
|
||||
PointsOnToolTipCenter[i] = PreSimulationLib.GetPointOnToolTipCenter( PointsToCheck[i], vtHead, vtNFace, Edge.vtN, Tool)
|
||||
end
|
||||
|
||||
-- vtC punta sempre verso il corpo dell'asse C o verso l'aggregato
|
||||
local nSCC = Tool.SetupInfo.GetSCC( Edge.vtN, Edge.vtEdge, vtNFace)
|
||||
local vtSCC = BeamLib.GetDirectionFromSCC( nSCC)
|
||||
local vtC = vtHead ^ Tool.SetupInfo.vtRotationAxisC
|
||||
vtC:normalize()
|
||||
if vtC:isSmall() then
|
||||
vtC = vtSCC
|
||||
elseif vtC * vtSCC < GEO.EPS_SMALL then
|
||||
vtC = -vtC
|
||||
end
|
||||
|
||||
-- punti curva collisione e direzioni check da macchina
|
||||
local PreCollisionData = Tool.SetupInfo.GetPreCollisionData( sAxis, vtC, vtHead)
|
||||
|
||||
local bMoveAfterSplit = false
|
||||
|
||||
-- se almeno in un punto c'è collisione con il pezzo si ritorna collisione
|
||||
-- se non si trova collisione si ritorna se è necessario separare prima di effettuare la lavorazione (ossia non c'è collisione con il pezzo ma c'è con il grezzo restante)
|
||||
for i = 1, #ToolExitPoints do
|
||||
for i = 1, #PointsOnToolTipCenter do
|
||||
|
||||
local bCollisionFoundPiece, bCollisionFoundRestLength = CheckCollisionPoint( ToolExitPoints[i], vtC, vtHead, PreCollisionData, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, bCheckOnlyRestlength)
|
||||
local bCollisionFoundPiece, bCollisionFoundRestLength = CheckCollisionPoint( sAxis, PointsOnToolTipCenter[i], vtHead, vtAux, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, bCheckOnlyRestlength)
|
||||
|
||||
-- se trovata collisione con pezzo è inutile controllare gli altri punti
|
||||
if bCollisionFoundPiece then
|
||||
@@ -413,7 +448,12 @@ end
|
||||
function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, OptionalParameters)
|
||||
|
||||
local bCollisionFound
|
||||
local bMoveAfterSplitZ, bMoveAfterSplitC, bMoveAfterSplitAB
|
||||
local bMoveAfterSplitL3, bMoveAfterSplitR3, bMoveAfterSplitR2, bMoveAfterSplitR1
|
||||
|
||||
-- parametri obbligatori
|
||||
local Edge = Parameters.Edge
|
||||
local vtNFace = Parameters.vtNFace
|
||||
local Tool = Parameters.Tool
|
||||
|
||||
-- parametri opzionali, in parte da far transitare
|
||||
OptionalParameters = OptionalParameters or {}
|
||||
@@ -423,8 +463,12 @@ function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, Optional
|
||||
OptionalParametersCheckCollisionWithAxis.PointsToCheck = OptionalParameters.PointsToCheck or nil
|
||||
OptionalParametersCheckCollisionWithAxis.sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
|
||||
OptionalParametersCheckCollisionWithAxis.bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
|
||||
OptionalParametersCheckCollisionWithAxis.sBlockedAxis = OptionalParameters.sBlockedAxis
|
||||
OptionalParametersCheckCollisionWithAxis.vtAux = OptionalParameters.vtAux
|
||||
|
||||
local sBlockedAxis = OptionalParameters.sBlockedAxis
|
||||
local bIsDicing = OptionalParameters.bIsDicing or false
|
||||
local bDisableRealElevationCheck = OptionalParameters.bDisableRealElevationCheck or false
|
||||
local bCheckOnlyRestlengthForAxisABC = false
|
||||
|
||||
-- se cubetti in modalità standard (no DownUp) gli assi AB e C si controllano solo con grezzo (ci sarebbe collisione con il materiale già rimosso controllando AB e C con pezzo)
|
||||
@@ -432,7 +476,7 @@ function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, Optional
|
||||
bCheckOnlyRestlengthForAxisABC = true
|
||||
-- se l'elevazione reale (rispetto al pezzo + eventuale materiale in testa/coda) è maggiore del massimo materiale è sempre collisione
|
||||
-- TODO rifare con funzione
|
||||
else
|
||||
elseif not bDisableRealElevationCheck then
|
||||
local Edge = Parameters.Edge
|
||||
local vtNFace = Parameters.vtNFace
|
||||
local dDepthToMachine = Parameters.dDepthToMachine
|
||||
@@ -455,21 +499,46 @@ function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, Optional
|
||||
end
|
||||
end
|
||||
|
||||
-- asse Z si controlla sempre
|
||||
bCollisionFound, bMoveAfterSplitZ = CheckCollisionWithAxis( 'Z', Parameters, OptionalParametersCheckCollisionWithAxis)
|
||||
-- SCC
|
||||
local nSCC = Tool.SetupInfo.GetSCC( Edge.vtN, Edge.vtEdge, vtNFace)
|
||||
|
||||
-- assi AB e C: se richiesto si controlla la collisione solo col grezzo
|
||||
-- si settano utensile, SCC e asse bloccato per il controllo collisione
|
||||
local bOkTool = EgtSetCalcTool( Tool.sName, Tool.sHead, Tool.nExit)
|
||||
if not bOkTool then
|
||||
error( 'CheckCollisionWithAxis : cannot set calc tool')
|
||||
end
|
||||
EgtSetCalcSolCh( nSCC)
|
||||
if sBlockedAxis and type( sBlockedAxis) == "string" then
|
||||
local BlockedAxis = EgtSplitString( sBlockedAxis, '=')
|
||||
EgtSetRotAxisBlock( BlockedAxis[1], tonumber( BlockedAxis[2]))
|
||||
end
|
||||
|
||||
-- nomi degli assi con cui controllare la collisione
|
||||
local AxesNames = EgtGetAllCurrAxesNames()
|
||||
local sL3 = AxesNames[3]
|
||||
local sR3 = AxesNames[6]
|
||||
local sR2 = AxesNames[5]
|
||||
local sR1 = AxesNames[4]
|
||||
|
||||
-- ultimo asse lineare prima dei rotativi (solitamente Z) si controlla sempre
|
||||
bCollisionFound, bMoveAfterSplitL3 = CheckCollisionWithAxis( sL3, Parameters, OptionalParametersCheckCollisionWithAxis)
|
||||
|
||||
-- assi rotativi: se richiesto si controlla la collisione solo col grezzo
|
||||
OptionalParametersCheckCollisionWithAxis.bCheckOnlyRestlength = bCheckOnlyRestlengthForAxisABC
|
||||
|
||||
if not bCollisionFound then
|
||||
bCollisionFound, bMoveAfterSplitAB = CheckCollisionWithAxis( 'AB', Parameters, OptionalParametersCheckCollisionWithAxis)
|
||||
if sR3 and not bCollisionFound then
|
||||
bCollisionFound, bMoveAfterSplitR3 = CheckCollisionWithAxis( sR3, Parameters, OptionalParametersCheckCollisionWithAxis)
|
||||
end
|
||||
|
||||
if not bCollisionFound then
|
||||
bCollisionFound, bMoveAfterSplitC = CheckCollisionWithAxis( 'C', Parameters, OptionalParametersCheckCollisionWithAxis)
|
||||
bCollisionFound, bMoveAfterSplitR2 = CheckCollisionWithAxis( sR2, Parameters, OptionalParametersCheckCollisionWithAxis)
|
||||
end
|
||||
|
||||
local bMoveAfterSplit = bMoveAfterSplitZ or bMoveAfterSplitC or bMoveAfterSplitAB
|
||||
if not bCollisionFound then
|
||||
bCollisionFound, bMoveAfterSplitR1 = CheckCollisionWithAxis( sR1, Parameters, OptionalParametersCheckCollisionWithAxis)
|
||||
end
|
||||
|
||||
local bMoveAfterSplit = bMoveAfterSplitL3 or bMoveAfterSplitR3 or bMoveAfterSplitR2 or bMoveAfterSplitR1
|
||||
|
||||
return bCollisionFound, bMoveAfterSplit
|
||||
end
|
||||
|
||||
+623
-404
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,477 @@
|
||||
-- BeamNestProcess.lua by Egaltech s.r.l. 2023/01/15
|
||||
-- Gestione nesting automatico travi
|
||||
-- 2022/10/05 Piccole modifiche per far funzionare correttamente i compilati.
|
||||
-- 2022/10/06 Corretto bug che moltiplicava i pezzi se erano presenti più grezzi della stessa sezione.
|
||||
-- 2023/01/15 Piccole correzioni.
|
||||
|
||||
-- Intestazioni
|
||||
require( 'EgtBase')
|
||||
_ENV = EgtProtectGlobal()
|
||||
EgtEnableDebug( false)
|
||||
|
||||
-- Per test
|
||||
--NEST = {}
|
||||
--NEST.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl'
|
||||
--NEST.MACHINE = 'Essetre-90480019_MW'
|
||||
--NEST.FLAG = 3
|
||||
|
||||
local sLog = ' +++ BeamNestProcess : ' .. NEST.FILE .. ', ' .. NEST.MACHINE .. ', ' .. LEN[1]
|
||||
EgtOutLog( sLog)
|
||||
|
||||
-- flag per abilitare statistiche in log
|
||||
local bLogStat = false
|
||||
|
||||
-- Cancello file di log specifico
|
||||
local sLogFile = EgtChangePathExtension( NEST.FILE, '.txt')
|
||||
EgtEraseFile( sLogFile)
|
||||
|
||||
-- Funzioni per scrittura su file di log specifico
|
||||
local function WriteErrToLogFile( nErr, sMsg, nRot, nCutId, nTaskId)
|
||||
local hFile = io.open( sLogFile, 'a')
|
||||
hFile:write( 'ERR=' .. tostring( nErr) .. '\n')
|
||||
hFile:write( sMsg .. '\n')
|
||||
hFile:write( 'ROT=' .. tostring( nRot or 0) .. '\n')
|
||||
hFile:write( 'CUTID=' .. tostring( nCutId or 0) .. '\n')
|
||||
hFile:write( 'TASKID=' .. tostring( nTaskId or 0) .. '\n')
|
||||
hFile:close()
|
||||
end
|
||||
|
||||
local function WriteTimeToLogFile( dTime)
|
||||
local hFile = io.open( sLogFile, 'a')
|
||||
hFile:write( 'TIME=' .. EgtNumToString( dTime) .. '\n')
|
||||
hFile:close()
|
||||
end
|
||||
|
||||
-- Funzione per gestire visualizzazione dopo errore
|
||||
local function PostErrView( nErr, sMsg)
|
||||
if nErr ~= 0 and ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) then
|
||||
EgtSetView( SCE_VD.ISO_SW, false)
|
||||
EgtZoom( SCE_ZM.ALL)
|
||||
EgtOutBox( sMsg, 'BatchProcess (err=' .. tostring( nErr) .. ')', 'ERRORS')
|
||||
end
|
||||
end
|
||||
|
||||
-- Funzione per gestire visualizzazione dopo warning
|
||||
local function PostWarnView( nWarn, sMsg)
|
||||
if nWarn ~= 0 and ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) then
|
||||
EgtSetView( SCE_VD.ISO_SW, false)
|
||||
EgtZoom( SCE_ZM.ALL)
|
||||
EgtOutBox( sMsg, 'BatchProcess (wrn=' .. tostring( nWarn) .. ')', 'WARNINGS')
|
||||
end
|
||||
end
|
||||
|
||||
-- Funzione per aggiornare dati ausiliari
|
||||
local function UpdateAuxData( sAuxFile)
|
||||
local bModif = false
|
||||
-- Se definito LOAD90, aggiorno
|
||||
local sLoad90 = EgtGetStringFromIni( 'AuxData', 'LOAD90', '', sAuxFile)
|
||||
if sLoad90 ~= '' then
|
||||
local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL
|
||||
EgtSetInfo( BtlInfoId, 'LOAD90', sLoad90)
|
||||
bModif = true
|
||||
end
|
||||
return bModif
|
||||
end
|
||||
|
||||
local function PartsToFill( Parts)
|
||||
local nToFill = 0
|
||||
for i = 1, #Parts do
|
||||
if Parts[i].Cnt > 0 then
|
||||
nToFill = nToFill + Parts[i].Cnt
|
||||
end
|
||||
end
|
||||
return nToFill
|
||||
end
|
||||
|
||||
local function ExecMaximumFilling( Raw, Parts)
|
||||
-- Inizializzo maximum filler
|
||||
EgtMaxFillerStart()
|
||||
-- Inserisco i pezzi
|
||||
for i = 1, #Parts do
|
||||
EgtMaxFillerAddPart( i, Parts[i].Len, Parts[i].DispLen or Parts[i].Len, Parts[i].Cnt or 1)
|
||||
end
|
||||
-- Eseguo l'ottimizzazione
|
||||
EgtMaxFillerCompute( Raw.LenToFill, Raw.StartGap, Raw.MidGap, Raw.EndGap, Raw.SortType)
|
||||
-- Recupero i risultati
|
||||
local nFilledParts, nDiffParts, dTotFillRatio = EgtMaxFillerGetResults()
|
||||
local OneRes = {}
|
||||
for i = 0, nDiffParts - 1 do
|
||||
local nPartId, nCount = EgtMaxFillerGetOneResult( i)
|
||||
table.insert( OneRes, { Id=nPartId, Count=nCount})
|
||||
end
|
||||
--return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Time=dTime, Data=OneRes}
|
||||
return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Data=OneRes}
|
||||
end
|
||||
|
||||
-- Funzione per trovare nome MachGroup
|
||||
local function NewMachGroupName()
|
||||
local nMachGroupId = EgtGetFirstMachGroup()
|
||||
if not nMachGroupId then return 1 end
|
||||
local nMaxMachGroup = 0
|
||||
while nMachGroupId do
|
||||
sMachGroupName = EgtGetMachGroupName(nMachGroupId)
|
||||
local nMachGroupName = tonumber(sMachGroupName)
|
||||
if nMachGroupName > nMaxMachGroup then
|
||||
nMaxMachGroup = nMachGroupName
|
||||
end
|
||||
nMachGroupId = EgtGetNextMachGroup(nMachGroupId)
|
||||
end
|
||||
return nMaxMachGroup + 1
|
||||
end
|
||||
|
||||
local function TotRawCount(Raws)
|
||||
local nTotRaws = 0
|
||||
for RawIndex = 1, #Raws do
|
||||
nTotRaws = nTotRaws + Raws[RawIndex].Count
|
||||
end
|
||||
return nTotRaws
|
||||
end
|
||||
|
||||
local function TotPartLen(Parts)
|
||||
local nTotPartLen = 0
|
||||
for PartIndex = 1, #Parts do
|
||||
nTotPartLen = nTotPartLen + ( Parts[PartIndex].Len * Parts[PartIndex].Cnt)
|
||||
end
|
||||
return nTotPartLen
|
||||
end
|
||||
|
||||
-- Imposto direttorio libreria specializzata per Travi
|
||||
EgtAddToPackagePath( NEST.BASEDIR .. '\\LuaLibs\\?.lua')
|
||||
|
||||
-- Imposto la macchina corrente e verifico sia abilitata per la lavorazione delle Travi
|
||||
EgtSetCurrMachine( NEST.MACHINE)
|
||||
local sMachDir = EgtGetCurrMachineDir()
|
||||
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then
|
||||
NEST.ERR = 12
|
||||
NEST.MSG = 'Error not configured for beam machine : ' .. sMachine
|
||||
WriteErrToLogFile( NEST.ERR, NEST.MSG)
|
||||
PostErrView( NEST.ERR, NEST.MSG)
|
||||
return
|
||||
end
|
||||
|
||||
-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
|
||||
EgtRemoveBaseMachineDirFromPackagePath()
|
||||
EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua')
|
||||
|
||||
-- Inizializzo contatori errori e avvisi
|
||||
local nErrCnt = 0
|
||||
local nWarnCnt = 0
|
||||
|
||||
-- Grezzi
|
||||
local Raws = {}
|
||||
-- creo tabella dei grezzi
|
||||
for nIndex, nLen in pairs( LEN) do
|
||||
Raws[tonumber(nIndex)] = {LenToFill = nLen, StartGap = NEST.STARTOFFSET, MidGap = NEST.OFFSET, EndGap = 0, SortType = -1}
|
||||
end
|
||||
for nIndex, nQty in pairs( QTY) do
|
||||
Raws[tonumber(nIndex)].Count = nQty
|
||||
end
|
||||
-- cerco il grezzo con la lunghezza maggiore, epurata dello start gap
|
||||
local maxRawLenToFillNoStartGap = 0
|
||||
for RawIndex = 1, #Raws do
|
||||
if Raws[RawIndex].Count > 0 then
|
||||
maxRawLenToFillNoStartGap = max( maxRawLenToFillNoStartGap, Raws[RawIndex].LenToFill - Raws[RawIndex].StartGap)
|
||||
end
|
||||
end
|
||||
|
||||
-- Pezzi
|
||||
local Parts = {}
|
||||
-- ciclo su pezzi per aggiungerli al nesting
|
||||
local dTotLen = 0
|
||||
for nPartId, nCount in pairs( PART) do
|
||||
-- recupero lunghezza pezzo
|
||||
local Len = EgtGetInfo( nPartId, "L", 'd')
|
||||
local DispLen = EgtIf( Len <= 1000, 2000, 0) --EgtIf( Len <= 2000, max( 2000, 6000 - Len), 0)
|
||||
-- aggiungo il pezzo solo se ci sta nel grezzo più lungo a disposizione
|
||||
if Len < maxRawLenToFillNoStartGap then
|
||||
for nCntIndex = 1 , nCount do
|
||||
table.insert( Parts, {Id = nPartId, Len = Len, DispLen = DispLen, Cnt = 1})
|
||||
dTotLen = dTotLen + Len
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- lunghezza totale pezzi
|
||||
local dTotPartLen = TotPartLen( Parts)
|
||||
-- calcolo media delle barre necessarie
|
||||
local NeededRawsForType = {}
|
||||
for RawIndex = 1, #Raws do
|
||||
NeededRawsForType[RawIndex] = min( ceil( dTotPartLen / Raws[RawIndex].LenToFill), Raws[RawIndex].Count)
|
||||
end
|
||||
local RawQtySum = 0
|
||||
for NeededRawIndex = 1, #NeededRawsForType do
|
||||
RawQtySum = RawQtySum + NeededRawsForType[NeededRawIndex]
|
||||
end
|
||||
local MediumRawQty = ceil( RawQtySum / #NeededRawsForType)
|
||||
if MediumRawQty > 1 then
|
||||
MediumRawQty = MediumRawQty - 1
|
||||
end
|
||||
|
||||
-- lista dei risultati
|
||||
local ResultList = {}
|
||||
local BestResult = nil
|
||||
local BestResultIndex = nil
|
||||
-- riordino lista pezzi per lunghezza
|
||||
table.sort( Parts, function( B1, B2) return B1.Len < B2.Len end)
|
||||
|
||||
local function NestSolutionByIndex( Index)
|
||||
|
||||
-- creo copia lista raw
|
||||
local TempRaws = {}
|
||||
for TempRawIndex = 1, #Raws do
|
||||
table.insert(TempRaws, {LenToFill = Raws[TempRawIndex].LenToFill, StartGap = Raws[TempRawIndex].StartGap, MidGap = Raws[TempRawIndex].MidGap, EndGap = Raws[TempRawIndex].EndGap, SortType = Raws[TempRawIndex].SortType, Count = Raws[TempRawIndex].Count})
|
||||
end
|
||||
|
||||
-- recupero pezzi corti
|
||||
local ShortList = {}
|
||||
local LongList = {}
|
||||
|
||||
for PartIndex = 1, #Parts do
|
||||
if PartIndex <= Index then
|
||||
table.insert( ShortList, Parts[PartIndex])
|
||||
else
|
||||
table.insert( LongList, Parts[PartIndex])
|
||||
end
|
||||
Parts[PartIndex].Cnt = 1
|
||||
end
|
||||
-- numero di pezzi piccoli per barra
|
||||
local ShortCount = Index
|
||||
local ShortForRaw = floor( ShortCount / MediumRawQty)
|
||||
local ExtraShortForRaw = 0
|
||||
if MediumRawQty > 0 then
|
||||
ExtraShortForRaw = fmod( ShortCount, MediumRawQty)
|
||||
end
|
||||
-- creo lista pezzi corti singoli
|
||||
local SingleShortList = {}
|
||||
for ShortIndex = 1, #ShortList do
|
||||
for ShortCount = 1, ShortList[ShortIndex].Cnt do
|
||||
table.insert( SingleShortList, {Id = ShortList[ShortIndex].Id, Len = ShortList[ShortIndex].Len, DispLen = ShortList[ShortIndex].DispLen, Cnt = 1})
|
||||
end
|
||||
end
|
||||
-- li divido per le barre previste
|
||||
local RawsShortList = {}
|
||||
local RawIndex = 0
|
||||
local ShortRawIndex = 0
|
||||
for ShortIndex = 1, #SingleShortList do
|
||||
if ShortRawIndex > 0 then
|
||||
table.insert( RawsShortList[RawIndex], SingleShortList[ShortIndex])
|
||||
ShortRawIndex = ShortRawIndex - 1
|
||||
else
|
||||
table.insert( RawsShortList, {SingleShortList[ShortIndex]})
|
||||
RawIndex = RawIndex + 1
|
||||
ShortRawIndex = ShortForRaw + EgtIf( RawIndex <= ExtraShortForRaw, 1, 0) - 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Ciclo fino ad esaurimento pezzi o barre
|
||||
local dTotPartInRawLen = 0
|
||||
local nRawTot = 0
|
||||
local dRawTotLen = 0
|
||||
local dTime = 0
|
||||
local nCycle = 1
|
||||
local CurrResult = {}
|
||||
while TotRawCount( TempRaws) > 0 and PartsToFill( Parts) > 0 do
|
||||
|
||||
-- creo lista con pezzi lunghi e pezzi corti di questo Cycle
|
||||
local PartsToNest = {}
|
||||
for PartIndex = 1, #LongList do
|
||||
table.insert( PartsToNest, LongList[PartIndex])
|
||||
end
|
||||
for CycleIndex = 1, #RawsShortList do
|
||||
if CycleIndex <= nCycle then
|
||||
for PartIndex = 1, #RawsShortList[CycleIndex] do
|
||||
table.insert( PartsToNest, RawsShortList[CycleIndex][PartIndex])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- se non ci sono pezzi da nestare, esco
|
||||
if PartsToFill( PartsToNest) <= 0 then
|
||||
break
|
||||
end
|
||||
-- Eseguo ottimizzazione per ogni lunghezza di barra
|
||||
local Results = {}
|
||||
for RawIndex = 1, #TempRaws do
|
||||
if TempRaws[RawIndex].Count > 0 then
|
||||
Results[RawIndex] = ExecMaximumFilling( TempRaws[RawIndex], PartsToNest)
|
||||
else
|
||||
Results[RawIndex] = { FillRatio = 0.001, LenToFill = 1000, DiffParts = 0}
|
||||
end
|
||||
end
|
||||
-- verifico quale e' quella con meno scarto
|
||||
local nMinWasteRawIndex = GDB_ID.NULL
|
||||
local dMinWaste = 100000
|
||||
for ResultIndex = 1, #Results do
|
||||
if Results[ResultIndex] then
|
||||
local dWaste = (1 - Results[ResultIndex].FillRatio) * TempRaws[ResultIndex].LenToFill
|
||||
if Results[ResultIndex].DiffParts > 0 and dWaste < dMinWaste then
|
||||
dMinWaste = dWaste
|
||||
nMinWasteRawIndex = ResultIndex
|
||||
end
|
||||
end
|
||||
end
|
||||
-- verifico se ci sono pezzi
|
||||
if nMinWasteRawIndex > 0 and Results[nMinWasteRawIndex] and Results[nMinWasteRawIndex].DiffParts > 0 then
|
||||
-- riporto barra e pezzi nel risultato corrente
|
||||
local CurrBar = { BarLen = TempRaws[nMinWasteRawIndex].LenToFill, Parts = {}}
|
||||
local CurrX = TempRaws[nMinWasteRawIndex].StartGap
|
||||
local nInfoIndex = 1
|
||||
for i = 1, Results[nMinWasteRawIndex].DiffParts do
|
||||
local PartIndex = Results[nMinWasteRawIndex].Data[i].Id
|
||||
local PartId = PartsToNest[PartIndex].Id
|
||||
local dLen = PartsToNest[PartIndex].Len
|
||||
for j = 1, Results[nMinWasteRawIndex].Data[i].Count do
|
||||
-- creo pezzo copia
|
||||
CurrPart = { Index = nInfoIndex, PartId = PartId, PosX = CurrX}
|
||||
table.insert( CurrBar.Parts, CurrPart)
|
||||
CurrX = CurrX + dLen + TempRaws[nMinWasteRawIndex].MidGap
|
||||
nInfoIndex = nInfoIndex + 1
|
||||
end
|
||||
end
|
||||
table.insert( CurrResult, CurrBar)
|
||||
dTotPartInRawLen = dTotPartInRawLen + ( Results[nMinWasteRawIndex].FillRatio * TempRaws[nMinWasteRawIndex].LenToFill)
|
||||
nRawTot = nRawTot + 1
|
||||
dRawTotLen = dRawTotLen + TempRaws[nMinWasteRawIndex].LenToFill
|
||||
-- Aggiorno per prossima iterazione
|
||||
TempRaws[nMinWasteRawIndex].Count = TempRaws[nMinWasteRawIndex].Count - 1
|
||||
for i = 1, Results[nMinWasteRawIndex].DiffParts do
|
||||
local PartId = Results[nMinWasteRawIndex].Data[i].Id
|
||||
PartsToNest[PartId].Cnt = PartsToNest[PartId].Cnt - Results[nMinWasteRawIndex].Data[i].Count
|
||||
end
|
||||
else
|
||||
-- se non sono riuscito ad inserire alcun pezzo esco dal ciclo perche' non ci sono pezzi inseribili
|
||||
break
|
||||
end
|
||||
nCycle = nCycle + 1
|
||||
end
|
||||
-- riporto risultato in lista
|
||||
ResultList[Index] = dTotPartInRawLen
|
||||
if not BestResult or not BestResultIndex or
|
||||
( dTotPartInRawLen > ResultList[BestResultIndex] + 0.02 or ( abs( dTotPartInRawLen - ResultList[BestResultIndex]) < 0.02 and dRawTotLen < BestResult.RawTotLen - 0.02)) then
|
||||
BestResult = CurrResult
|
||||
BestResult.RawTotLen = dRawTotLen
|
||||
BestResultIndex = Index
|
||||
end
|
||||
end
|
||||
|
||||
local CycleCount = 0
|
||||
|
||||
local MinTime = 10 + pow( 3, ceil( log10( #Parts)) - 1)
|
||||
if bLogStat then EgtOutLog('MinTime: ' .. MinTime ) end
|
||||
local MaxTime = 30 + pow( 7, ceil( log10( #Parts)) - 1)
|
||||
if bLogStat then EgtOutLog('MaxTime: ' .. MaxTime ) end
|
||||
local TargetRatio = 0.98
|
||||
local dTargetRatioLen = TargetRatio * dTotLen
|
||||
if bLogStat then EgtOutLog('TargetRatioLen: ' .. dTargetRatioLen ) end
|
||||
local CurrTime = 0
|
||||
|
||||
local function NestSolutionFromSP( StartingPoint, OscillationStep)
|
||||
-- ciclo sulle possibilita' da un punto di origine con uno step fisso
|
||||
local CurrResultIndex = StartingPoint
|
||||
NestSolutionByIndex( StartingPoint)
|
||||
if OscillationStep == 0 then return end
|
||||
local CycleIndex = 1
|
||||
local nOutOfBoundary = 0
|
||||
while nOutOfBoundary ~= 3 do
|
||||
CurrTime = EgtStopCounter() / 1000
|
||||
if bLogStat then EgtOutLog('CurrTime: ' .. CurrTime ) end
|
||||
if bLogStat then EgtOutLog('BestRatio: ' .. dTotLen / BestResult.RawTotLen ) end
|
||||
-- se e' passato il tempo massimo, o e' passato il tempo minimo, ha inserito tutti i pezzi e la percentuale di utilizzo del materiale e' maggiore della soglia
|
||||
if CurrTime > MaxTime or ( CurrTime > MinTime and ResultList[BestResultIndex] > dTotLen - 0.1 and ( dTotLen / BestResult.RawTotLen ) >= TargetRatio) then
|
||||
if bLogStat then EgtOutLog('Brake') end
|
||||
break
|
||||
end
|
||||
local bCurrOutOfBoundary = false
|
||||
if CurrResultIndex < 0 then
|
||||
bCurrOutOfBoundary = true
|
||||
if nOutOfBoundary == 2 then
|
||||
nOutOfBoundary = 3
|
||||
else
|
||||
nOutOfBoundary = 1
|
||||
end
|
||||
end
|
||||
if CurrResultIndex > #Parts then
|
||||
bCurrOutOfBoundary = true
|
||||
if nOutOfBoundary == 1 then
|
||||
nOutOfBoundary = 3
|
||||
else
|
||||
nOutOfBoundary = 2
|
||||
end
|
||||
end
|
||||
if not bCurrOutOfBoundary and not ResultList[CurrResultIndex] then
|
||||
NestSolutionByIndex( CurrResultIndex)
|
||||
if bLogStat then EgtOutLog('CurrResultIndex: ' .. CurrResultIndex ) end
|
||||
if bLogStat then EgtOutLog('Result: ' .. ResultList[CurrResultIndex]) end
|
||||
CycleCount = CycleCount + 1
|
||||
end
|
||||
CurrResultIndex = StartingPoint + EgtIf( CycleIndex % 2 == 0, (CycleIndex / 2) * OscillationStep, -( ( CycleIndex + 1) / 2) * OscillationStep )
|
||||
CycleIndex = CycleIndex + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- lancio calcolo
|
||||
EgtStartCounter()
|
||||
local StartingResult = floor( #Parts * 0.3)
|
||||
if bLogStat then EgtOutLog('StartingResult: ' .. StartingResult ) end
|
||||
--local Step = floor( #Parts / 10) * floor( log10( #Parts))
|
||||
local nDividendo = pow( 10, floor( log10( #Parts)) - 1)
|
||||
nDividendo = EgtIf( nDividendo ~= 1, nDividendo, 10)
|
||||
local Step = floor( #Parts / nDividendo) * floor( log10( #Parts))
|
||||
if bLogStat then EgtOutLog('Step: ' .. Step ) end
|
||||
NestSolutionFromSP( StartingResult, Step)
|
||||
if Step > 1 then
|
||||
NestSolutionFromSP( StartingResult, 1)
|
||||
end
|
||||
|
||||
-- creo gruppi di lavorazione per risultato
|
||||
for MachGroupIndex = 1, #BestResult do
|
||||
local CurrMachGroup = BestResult[ MachGroupIndex]
|
||||
-- creo gruppo di lavorazione
|
||||
local MachGroupName = NewMachGroupName()
|
||||
nMachGroup = EgtAddMachGroup( MachGroupName)
|
||||
EgtSetInfo( nMachGroup, "BARLEN", CurrMachGroup.BarLen)
|
||||
EgtSetInfo( nMachGroup, "MATERIAL", NEST.MATERIAL)
|
||||
EgtSetInfo( nMachGroup, "AUTONEST", 1)
|
||||
-- scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione
|
||||
EgtSetInfo( nMachGroup, "PRODID", NEST.PRODID)
|
||||
EgtSetInfo( nMachGroup, "PATTID", nMachGroup)
|
||||
-- Disegno i pezzi
|
||||
for i = 1, #CurrMachGroup.Parts do
|
||||
local CurrPart = CurrMachGroup.Parts[ i]
|
||||
-- creo pezzo copia
|
||||
local nPartDuploId = EgtDuploNew( CurrPart.PartId)
|
||||
EgtSetInfo( nMachGroup, "PART" .. CurrPart.Index, nPartDuploId .. "," .. CurrPart.PosX)
|
||||
end
|
||||
end
|
||||
|
||||
-- creo grezzi per ogni gruppo di lavorazione
|
||||
local nRawCnt = 0
|
||||
local nRawTot = ResultList[BestResultIndex]
|
||||
_G.BEAM = {}
|
||||
BEAM.FILE = NEST.FILE
|
||||
BEAM.MACHINE = NEST.MACHINE
|
||||
BEAM.FLAG = 6 -- CREATE_PANEL
|
||||
BEAM.BASEDIR = NEST.BASEDIR
|
||||
nMachGroup = EgtGetFirstMachGroup()
|
||||
while nMachGroup do
|
||||
local nNextMachGroup = EgtGetNextMachGroup( nMachGroup)
|
||||
EgtSetCurrMachGroup( nMachGroup)
|
||||
if EgtGetInfo( nMachGroup, "AUTONEST",'i') == 1 then
|
||||
EgtRemoveInfo( nMachGroup, "AUTONEST")
|
||||
EgtSetInfo( nMachGroup, "UPDATEUI", 1)
|
||||
local bOk, sErr = pcall( dofile, BEAM.BASEDIR .. "\\BatchProcessNew.lua")
|
||||
if not bOk then
|
||||
EgtOutLog( 'Error in BatchProcessNew.lua call (' .. ( sErr or '') ..')')
|
||||
end
|
||||
nRawCnt = nRawCnt + 1
|
||||
-- aggiorno interfaccia
|
||||
EgtProcessEvents( 200 + ( nRawCnt / nRawTot * 100), 0)
|
||||
end
|
||||
nMachGroup = nNextMachGroup
|
||||
end
|
||||
|
||||
EgtResetCurrMachGroup()
|
||||
|
||||
NEST.ERR = 0
|
||||
|
||||
EgtOutLog( ' +++ BeamNestProcess completed')
|
||||
@@ -688,7 +688,7 @@
|
||||
"TopologyList" : [
|
||||
{ "sName": "Feature",
|
||||
"sImage": "ConfigStrategy\\ScarfJoint.png",
|
||||
"StrategyList" : [ ]
|
||||
"StrategyList" : [ { "sStrategyId": "STR0009" }]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -269,6 +269,8 @@ local function GetBestPocketingStrategy( Proc, Part)
|
||||
Milling.idProc = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
|
||||
Milling.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP
|
||||
Milling.bMachAppliedToTunnelFace = true
|
||||
else
|
||||
ToolSearchParameters.vtToolDirection = nil
|
||||
end
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
|
||||
Milling.ToolInfo = {}
|
||||
@@ -278,6 +280,19 @@ local function GetBestPocketingStrategy( Proc, Part)
|
||||
local ParametersMRR = {}
|
||||
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
|
||||
Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
|
||||
-- se la faccia tunnel è troppo piccola non si lavora
|
||||
if Milling.bMachAppliedToTunnelFace then
|
||||
local dLongestEdgeLength = 0
|
||||
for i = 1, #Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges do
|
||||
if Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges[i].dLength > dLongestEdgeLength + 10 * GEO.EPS_SMALL then
|
||||
dLongestEdgeLength = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges[i].dLength
|
||||
end
|
||||
end
|
||||
if dLongestEdgeLength < TOOLS[Milling.ToolInfo.nToolIndex].dDiameter then
|
||||
Milling.bIsApplicable = false
|
||||
ParametersMRR = {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
table.insert( Machining, Milling)
|
||||
@@ -309,6 +324,8 @@ local function GetBestPocketingStrategy( Proc, Part)
|
||||
Milling.idFaceToMachine = Proc.MainFaces.SideFaces[1].id
|
||||
Milling.idProc = Proc.id
|
||||
Milling.dElevation = Proc.MainFaces.SideFaces[1].dElevation
|
||||
else
|
||||
ToolSearchParameters.vtToolDirection = nil
|
||||
end
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
|
||||
Milling.ToolInfo = {}
|
||||
@@ -318,6 +335,19 @@ local function GetBestPocketingStrategy( Proc, Part)
|
||||
local ParametersMRR = {}
|
||||
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
|
||||
Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
|
||||
-- se la faccia tunnel è troppo piccola non si lavora
|
||||
if Milling.bMachAppliedToTunnelFace then
|
||||
local dLongestEdgeLength = 0
|
||||
for i = 1, #Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges do
|
||||
if Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges[i].dLength > dLongestEdgeLength + 10 * GEO.EPS_SMALL then
|
||||
dLongestEdgeLength = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges[i].dLength
|
||||
end
|
||||
end
|
||||
if dLongestEdgeLength < TOOLS[Milling.ToolInfo.nToolIndex].dDiameter then
|
||||
Milling.bIsApplicable = false
|
||||
ParametersMRR = {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
table.insert( Machining, Milling)
|
||||
|
||||
@@ -195,6 +195,17 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Blade.Result = {}
|
||||
Chainsaw.Result = {}
|
||||
|
||||
|
||||
-- se arriva una feature senza MainFaces o MainEdges necessari la strategia non è applicabile
|
||||
-- TODO riuniure a IsTopologyOk?
|
||||
if not Proc.MainFaces
|
||||
or not Proc.MainFaces.LongFaces[1]
|
||||
or not Proc.MainFaces.LongFaces[1].MainEdges then
|
||||
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
if not IsTopologyOk( Proc) then
|
||||
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not implemented'
|
||||
EgtOutLog( sErr)
|
||||
@@ -241,16 +252,6 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
|
||||
end
|
||||
|
||||
-- se arriva una feature senza MainFaces o MainEdges necessari la strategia non è applicabile
|
||||
-- TODO riuniure a IsTopologyOk?
|
||||
if not Proc.MainFaces
|
||||
or not Proc.MainFaces.LongFaces[1]
|
||||
or not Proc.MainFaces.LongFaces[1].MainEdges then
|
||||
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
-- riferimenti locali per leggibilità e performance
|
||||
local LongFace = Proc.MainFaces.LongFaces[1]
|
||||
local OppositeEdge1 = LongFace.MainEdges.OppositeEdges[1]
|
||||
|
||||
@@ -132,6 +132,16 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
bIsSplitFeature = true
|
||||
end
|
||||
|
||||
-- se arriva una feature senza MainFaces o MainEdges necessari la strategia non è applicabile
|
||||
-- TODO riuniure a IsTopologyOk?
|
||||
if not Proc.MainFaces
|
||||
or not Proc.MainFaces.LongFaces[1]
|
||||
or not Proc.MainFaces.LongFaces[1].MainEdges then
|
||||
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
-- altezza tasca
|
||||
local dPocketHeight = 0
|
||||
if Proc.Topology.sFamily == 'Tunnel' then
|
||||
@@ -145,16 +155,6 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
|
||||
end
|
||||
|
||||
-- se arriva una feature senza MainFaces o MainEdges necessari la strategia non è applicabile
|
||||
-- TODO riuniure a IsTopologyOk?
|
||||
if not Proc.MainFaces
|
||||
or not Proc.MainFaces.LongFaces[1]
|
||||
or not Proc.MainFaces.LongFaces[1].MainEdges then
|
||||
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology')
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
-- riferimenti locali per leggibilità e performance
|
||||
local LongFace = Proc.MainFaces.LongFaces[1]
|
||||
local OppositeEdge1 = LongFace.MainEdges.OppositeEdges[1]
|
||||
|
||||
@@ -441,7 +441,7 @@ function STR0007.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
local ptCutC, vtCutN = EgtSurfTmFacetCenter( Proc.id, 1, GDB_ID.ROOT)
|
||||
if ptCutC and vtCutN and AreSameVectorApprox( Proc.FeatureInfo.vtMortiseN, vtCutN) then
|
||||
-- recupero gruppo per geometria addizionale
|
||||
local nAddGrpId = Part.idTempGroup
|
||||
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
|
||||
Strategy.idMortiseCutPlane = EgtSurfTmPlaneInBBox( nAddGrpId, ptCutC, vtCutN, Part.b3Part, GDB_RT.GLOB)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -311,10 +311,7 @@ function STR0008.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
-- si applicano le lavorazioni di svuotatura
|
||||
for i = 1, #Strategy.Machining.Pocketing do
|
||||
if Strategy.Machining.Pocketing[i].bIsApplicable then
|
||||
Pocketing = {}
|
||||
Pocketing.Steps = {}
|
||||
Pocketing.LeadIn = {}
|
||||
Pocketing.nType = MCH_MY.POCKETING
|
||||
Pocketing = MachiningLib.InitMachiningParameters( MCH_MY.POCKETING)
|
||||
Pocketing.nSubType = MCH_POCK_SUB.SPIRALOUT
|
||||
Pocketing.LeadIn.nType = MCH_POCK_LI.ZIGZAG
|
||||
Pocketing.Steps.dStep = TOOLS[Strategy.Machining.Pocketing[i].ToolInfo.nToolIndex].dStep
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"sStrategyId": "STR0009",
|
||||
"sStrategyName": "Mill Heading",
|
||||
"sStrategyName": "ScarfJoint",
|
||||
"ParameterList" : [
|
||||
{
|
||||
"sName": "dDepthChamfer",
|
||||
@@ -13,35 +13,15 @@
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "dOverMaterial",
|
||||
"sNameNge": "OVERMAT",
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Overmaterial",
|
||||
"sDescriptionLong": "",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "bForceStrip",
|
||||
"sNameNge": "FORCE_STRIP",
|
||||
"sName": "bAntiSplint",
|
||||
"sNameNge": "ANTISPLINT",
|
||||
"sValue": "false",
|
||||
"sDescriptionShort": "Force strip",
|
||||
"sDescriptionLong": "Enable the parameter to force the software to leave a strip to sustain the piece",
|
||||
"sDescriptionShort": "Use Anti-Splint strategy",
|
||||
"sDescriptionLong": "The strategy will apply blade cuts on corner to avoid wood splint",
|
||||
"sType": "b",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "dStripWidth",
|
||||
"sNameNge": "STRIP_WIDTH",
|
||||
"sValue": "0",
|
||||
"sDescriptionShort": "Strip width",
|
||||
"sDescriptionLong": "Width of the strip in case if foreseen from the machining",
|
||||
"sType": "d",
|
||||
"sMessageId": " ",
|
||||
"sMinUserLevel": "1"
|
||||
},
|
||||
{
|
||||
"sName": "sMillingList",
|
||||
"sNameNge": "PROFILE_TOOL_LIST",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
-- Strategia: STR0009
|
||||
-- Descrizione
|
||||
-- Fresatura di contorno
|
||||
-- Feature tipo Arco
|
||||
-- Feature tipo ScarfJoint
|
||||
|
||||
|
||||
-- carico librerie
|
||||
@@ -10,156 +9,182 @@ local BeamData = require( 'BeamDataNew')
|
||||
local MachiningLib = require( 'MachiningLib')
|
||||
local FeatureLib = require( 'FeatureLib')
|
||||
-- strategie di base
|
||||
local BladeToWaste = require('BLADETOWASTE')
|
||||
local BladeToWaste = require( 'BLADETOWASTE')
|
||||
local FaceByMill = require( 'FACEBYMILL')
|
||||
local FaceByBlade = require( 'FACEBYBLADE')
|
||||
local AntiSplintOnFace = require( 'ANTISPLINTONFACE')
|
||||
|
||||
-- Tabella per definizione modulo
|
||||
local STR0009 = {}
|
||||
local Strategy = {}
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
-- TODO gestire il caso in cui non si trova l'utensile
|
||||
local function GetArcStrategy( Proc, Part)
|
||||
local Machining = {}
|
||||
local ToolSearchParameters = {}
|
||||
local function GetFacesIdOrder( Proc, Part)
|
||||
local Faces = {}
|
||||
if Proc.nFct == 5 then
|
||||
-- carico gli id delle facce
|
||||
for i = 1, Proc.nFct do
|
||||
Faces[#Faces + 1] = BeamLib.TableCopyDeep( Proc.Faces[i])
|
||||
end
|
||||
elseif Proc.nFct == 4 then
|
||||
local vtN1 = Proc.Faces[1].vtN
|
||||
local vtN2 = Proc.Faces[2].vtN
|
||||
local nIndex = EgtIf( abs( vtN1:getX()) > abs( vtN2:getX()), 1, 2)
|
||||
for i = nIndex, Proc.nFct do
|
||||
Faces[#Faces + 1] = BeamLib.TableCopyDeep( Proc.Faces[i])
|
||||
end
|
||||
-- TODO manca il caso in cui mancano facce 4 e 5
|
||||
else -- Proc.nFct == 3
|
||||
for i = 2, Proc.nFct do
|
||||
Faces[#Faces + 1] = BeamLib.TableCopyDeep( Proc.Faces[i])
|
||||
end
|
||||
end
|
||||
|
||||
-- recupero e verifico l'entità curva
|
||||
local idAux = EgtGetInfo( Proc.id, 'AUXID', 'i')
|
||||
if idAux then idAux = idAux + Proc.id end
|
||||
if not idAux or ( EgtGetType( idAux) & GDB_FY.GEO_CURVE) == 0 then
|
||||
local sErr = 'Error on process ' .. tostring( Proc.id) .. ' missing profile geometry'
|
||||
return Faces
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetEdgeToMachine( ClosingFace, idBottomFace)
|
||||
local EdgeToMachine
|
||||
|
||||
for i = 1, #ClosingFace.Edges do
|
||||
if ClosingFace.Edges[i].idAdjacentFace == idBottomFace then
|
||||
EdgeToMachine = ClosingFace.Edges[i]
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return EdgeToMachine
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GetScarfJointStrategy( Proc, Part)
|
||||
-- ordino le facce in base al loro numero e al parallelismo delle due facce principali
|
||||
-- faccia 0: superficie tappo (*potrebbe non esserci)
|
||||
-- faccia 1: superficie principale di fondo
|
||||
-- faccia 2: superficie opposta alla faccia 1
|
||||
-- faccia 3: superficie principale superiore
|
||||
-- faccia 4: superficie di testa (*potrebbe non esserci)
|
||||
-- creo una tabella unica contenente tutte le lavorazioni
|
||||
local Result = {}
|
||||
local Cutting = { Machinings = {}, Result = {}}
|
||||
local AntiSplints = {}
|
||||
local Pocketing = {}
|
||||
|
||||
Result.dTimeToMachine = 0
|
||||
local Faces = GetFacesIdOrder( Proc)
|
||||
-- taglio su faccia 4
|
||||
if Faces[4] and Faces[4].vtN then
|
||||
-- recupero gruppo per geometria addizionale
|
||||
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
|
||||
-- TODO la nuova faccia creata sulla 4 può tagliare faccia 1. In caso tagliasse faccia 1, bisogna calcolare i cubetti con 2 facce
|
||||
Strategy.idFeatureCutPlane = EgtSurfTmPlaneInBBox( nAddGrpId, Faces[4].ptCenter, Faces[4].vtN, Part.b3Part, GDB_RT.GLOB)
|
||||
Cutting.Machinings, Cutting.Result = BladeToWaste.Make( Strategy.idFeatureCutPlane, Part)
|
||||
if Cutting.Result.sStatus == 'Completed' then
|
||||
Cutting.Machinings.bIsApplicable = true
|
||||
end
|
||||
end
|
||||
|
||||
-- antischeggia facce 1 e 3
|
||||
local bAreAllAntisplintsApplicable = true
|
||||
if Strategy.Parameters.bAntiSplint then
|
||||
AntiSplints = AntiSplintOnFace.Make( Proc, Part, Faces[2])
|
||||
for k = 1, #AntiSplints do
|
||||
if not AntiSplints[k].bIsApplicable then
|
||||
bAreAllAntisplintsApplicable = false
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- svuotatura faccia 2
|
||||
if Faces[2] then
|
||||
local frPock, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.id, Faces[2].id, GDB_ID.ROOT)
|
||||
local ToolSearchParameters = {}
|
||||
ToolSearchParameters.sMillShape = 'STANDARD'
|
||||
ToolSearchParameters.vtToolDirection = Faces[2].vtN
|
||||
ToolSearchParameters.dElevation = abs( ( Faces[2].ptCenter - Faces[4].ptCenter) * Faces[2].vtN)
|
||||
ToolSearchParameters.dMaxToolDiameter = min( dL, dW)
|
||||
ToolSearchParameters.ToolInfo = {}
|
||||
ToolSearchParameters.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
if ToolSearchParameters.ToolInfo.nToolIndex then
|
||||
local Machining = MachiningLib.InitMachiningParameters( MCH_MY.POCKETING)
|
||||
Machining.Geometry = {{ Proc.id, Faces[2].id}}
|
||||
Machining.dElevation = ToolSearchParameters.dElevation
|
||||
Machining.dMaxElev = Machining.dElevation
|
||||
Machining.vtToolDirection = ToolSearchParameters.vtToolDirection
|
||||
Machining.nSubType = MCH_POCK_SUB.SPIRALIN
|
||||
Machining.LeadIn.nType = MCH_POCK_LI.ZIGZAG
|
||||
Machining.Steps.dStep = TOOLS[ToolSearchParameters.ToolInfo.nToolIndex].dStep
|
||||
Machining.Steps.dSideStep = TOOLS[ToolSearchParameters.ToolInfo.nToolIndex].dSideStep
|
||||
Machining.nToolIndex = ToolSearchParameters.ToolInfo.nToolIndex
|
||||
Machining.LeadIn.dTangentDistance = TOOLS[ToolSearchParameters.ToolInfo.nToolIndex].dDiameter / 2
|
||||
Machining.LeadIn.dElevation = TOOLS[ToolSearchParameters.ToolInfo.nToolIndex].dDiameter / 2
|
||||
Machining.sDepth = 0
|
||||
Machining.dResidualDepth = ToolSearchParameters.ToolInfo.dResidualDepth
|
||||
-- TODO vedere se questo parametro con svuotature nuove si può rimuovere
|
||||
Machining.dOpenMinSafe = Strategy.Parameters.dOpenMinSafe
|
||||
Machining.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part)
|
||||
Result.dTimeToMachine = Result.dTimeToMachine + Machining.dTimeToMachine
|
||||
table.insert( Pocketing, Machining)
|
||||
Pocketing.bIsApplicable = true
|
||||
-- se non sono stati fatti i passaggi antischeggia si verifica che le facce siano a 90°, altrimenti serve passaggio con fresa
|
||||
if not Strategy.Parameters.bAntiSplint or not bAreAllAntisplintsApplicable then
|
||||
local dAngleBetweenFaces = Proc.AdjacencyMatrix[1][2] or 0
|
||||
-- si fa passaggio con fresa
|
||||
if dAngleBetweenFaces > -90 then
|
||||
local EdgeToMachine = GetEdgeToMachine( Faces[1], Faces[2].id)
|
||||
local CuttingClosingFace = FaceByBlade.Make( Proc, Part, Faces[1], EdgeToMachine)
|
||||
if CuttingClosingFace.bIsApplicable then
|
||||
table.insert( AntiSplints, CuttingClosingFace)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- se manca taglio principale, feature non eseguibile
|
||||
if not Cutting.Machinings.bIsApplicable then
|
||||
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable'
|
||||
EgtOutLog( sErr)
|
||||
return false, sErr
|
||||
end
|
||||
Proc.idAddAuxGeom = idAux
|
||||
|
||||
-- recupero i dati della curva e del profilo
|
||||
local dDepth = abs( EgtCurveThickness( idAux))
|
||||
local vtExtr = EgtCurveExtrusion( idAux, GDB_RT.GLOB)
|
||||
local bToolInvert = ( vtExtr:getZ() < -0.1)
|
||||
local bIsHorizontal = abs( vtExtr:getZ()) < 10 * GEO.EPS_SMALL
|
||||
local bIsFeatureDown = Proc.AffectedFaces.bBottom and not Proc.AffectedFaces.bTop
|
||||
local bIsFeatureBack = Proc.AffectedFaces.bBack and not Proc.AffectedFaces.bFront
|
||||
local bForceStrip = Strategy.Parameters.bForceStrip
|
||||
local dDimStrip = EgtIf( Strategy.Parameters.dStripWidth < 100 * GEO.EPS_SMALL, nil, Strategy.Parameters.dStripWidth)
|
||||
|
||||
local bExecStrip = false
|
||||
-- se la lavorazione si trova nella parte inferiore o in battuta dietro, il codolo va sempre lasciato
|
||||
if bIsFeatureDown or bIsFeatureBack or bForceStrip then
|
||||
if bIsFeatureDown or bIsFeatureBack then
|
||||
dDimStrip = dDimStrip or max( BeamData.DIM_STRIP or 5, 5)
|
||||
else
|
||||
dDimStrip = dDimStrip or max( BeamData.DIM_STRIP_SMALL or 5, 1)
|
||||
end
|
||||
bExecStrip = true
|
||||
end
|
||||
if not bExecStrip then
|
||||
dDimStrip = 0
|
||||
end
|
||||
|
||||
-- se lavorazione orizzontale
|
||||
if bIsHorizontal then
|
||||
local bDouble
|
||||
local Milling = MachiningLib.InitMachiningParameters( MCH_MY.MILLING)
|
||||
Milling.bIsApplicable = false
|
||||
ToolSearchParameters = {}
|
||||
ToolSearchParameters.sMillShape = 'STANDARD'
|
||||
ToolSearchParameters.dElevation = EgtIf( bExecStrip, ( dDepth - dDimStrip) / 2, dDepth + BeamData.MILL_OVERLAP)
|
||||
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr)
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, 'Milling')
|
||||
Milling.ToolInfo = {}
|
||||
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
-- se posso lavorare in una passata, ma utensile trovato non completa la lavorazione,
|
||||
-- allora provo a cercare utensile con massimo materiale sufficiente per fare le due passate, magari trova un utensile più prestante
|
||||
if Milling.ToolInfo.dResidualDepth > 10 * GEO.EPS_SMALL and not bExecStrip then
|
||||
bDouble = true
|
||||
ToolSearchParameters.dElevation = ( dDepth + BeamData.MILL_OVERLAP) / 2
|
||||
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr)
|
||||
end
|
||||
Milling.bToolInvert = bToolInvert
|
||||
Milling.vtToolDirection = vtExtr
|
||||
|
||||
if bDouble or bExecStrip then
|
||||
if bDouble then
|
||||
Milling.sDepth = ( dDepth + BeamData.MILL_OVERLAP) / 2
|
||||
else
|
||||
Milling.sDepth = ( dDepth - dDimStrip) / 2
|
||||
end
|
||||
table.insert( Machining, Milling)
|
||||
local Milling2 = BeamLib.TableCopyDeep( Milling)
|
||||
table.insert( Machining, Milling2)
|
||||
else
|
||||
Milling.sDepth = dDepth + BeamData.MILL_OVERLAP
|
||||
table.insert( Machining, Milling)
|
||||
end
|
||||
-- se lavorazione verticale
|
||||
Result = FeatureLib.GetStrategyResultNotApplicable( sErr)
|
||||
else
|
||||
-- si cerca utensile 1
|
||||
local Milling = {}
|
||||
Milling.bIsApplicable = false
|
||||
ToolSearchParameters = {}
|
||||
ToolSearchParameters.sMillShape = 'STANDARD'
|
||||
ToolSearchParameters.dElevation = dDepth + BeamData.MILL_OVERLAP
|
||||
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr)
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, 'Milling')
|
||||
Milling.ToolInfo = {}
|
||||
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
-- si cerca utensile 2
|
||||
local Milling2 = {}
|
||||
Milling2.bIsApplicable = false
|
||||
ToolSearchParameters = {}
|
||||
ToolSearchParameters.sMillShape = 'STANDARD'
|
||||
ToolSearchParameters.dElevation = dDepth + BeamData.MILL_OVERLAP
|
||||
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, vtExtr, -vtExtr)
|
||||
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, 'Milling')
|
||||
Milling2.ToolInfo = {}
|
||||
Milling2.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
|
||||
-- se serve codolo
|
||||
if bExecStrip then
|
||||
-- se a disposizione entrambi gli utensili
|
||||
if Milling.ToolInfo.nToolIndex and Milling2.ToolInfo.nToolIndex then
|
||||
table.insert( Machining, Milling)
|
||||
table.insert( Machining, Milling2)
|
||||
-- se disponibile solo primo utensile
|
||||
elseif Milling.ToolInfo.nToolIndex then
|
||||
table.insert( Machining, Milling)
|
||||
-- se disponibile solo secondo utensile
|
||||
elseif Milling2.ToolInfo.nToolIndex then
|
||||
table.insert( Machining, Milling2)
|
||||
-- nessun utensile disponibile
|
||||
local dCompletionPercentage = 100
|
||||
-- completa se svuotatura eseguita e antisplit eseguiti (o non richiesti)
|
||||
if Pocketing.bIsApplicable and ( bAreAllAntisplintsApplicable or not Strategy.Parameters.bAntiSplint) then
|
||||
Result.sStatus = 'Completed'
|
||||
if bAreAllAntisplintsApplicable then
|
||||
Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
|
||||
else
|
||||
-- non si fa nulla
|
||||
Result.dQuality = FeatureLib.GetStrategyQuality( 'STD')
|
||||
end
|
||||
-- altrimenti senza codolo
|
||||
-- altrimenti non completa
|
||||
else
|
||||
-- se utensile 1 esegue completamente
|
||||
if Milling.ToolInfo.nToolIndex and Milling.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
||||
table.insert( Machining, Milling)
|
||||
-- se utensile 2 esegue completamente
|
||||
elseif Milling2.ToolInfo.nToolIndex and Milling2.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
|
||||
table.insert( Machining, Milling2)
|
||||
-- se possono lavorare entrambi
|
||||
elseif Milling.ToolInfo.nToolIndex and Milling2.ToolInfo.nToolIndex then
|
||||
table.insert( Machining, Milling)
|
||||
table.insert( Machining, Milling2)
|
||||
-- se utensile 1 non completo
|
||||
elseif Milling.ToolInfo.nToolIndex then
|
||||
table.insert( Machining, Milling)
|
||||
-- se utensile 2 non completo
|
||||
elseif Milling2.ToolInfo.nToolIndex then
|
||||
table.insert( Machining, Milling2)
|
||||
Result.dQuality = FeatureLib.GetStrategyQuality( 'STD')
|
||||
Result.sStatus = 'Not-Completed'
|
||||
-- se fa solo svuotatura
|
||||
if Pocketing.bIsApplicable then
|
||||
dCompletionPercentage = 90
|
||||
Result.sInfo = 'Anti-Split not executed'
|
||||
elseif Strategy.Parameters.bAntiSplint and bAreAllAntisplintsApplicable then
|
||||
dCompletionPercentage = 75
|
||||
Result.sInfo = 'Pocketing not executed'
|
||||
else
|
||||
dCompletionPercentage = 50
|
||||
Result.sInfo = 'Only the cut has been executed'
|
||||
end
|
||||
end
|
||||
|
||||
Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dCompletionPercentage)
|
||||
end
|
||||
|
||||
-- TODO VOTO DA FARE!!!!
|
||||
Strategy.Result.sStatus = 'Completed'
|
||||
Strategy.Result.dCompletionIndex = 5
|
||||
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo or Machining[2].ToolInfo)
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'MILL')
|
||||
Strategy.Result.sInfo = ''
|
||||
-- creo una tabella unica contenente tutte le lavorazioni
|
||||
local Machinings = {}
|
||||
EgtJoinTables( Machinings, Cutting.Machinings)
|
||||
EgtJoinTables( Machinings, AntiSplints)
|
||||
EgtJoinTables( Machinings, Pocketing)
|
||||
|
||||
return Machining
|
||||
return Machinings, Result
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
@@ -173,79 +198,33 @@ function STR0009.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy.Result = {}
|
||||
|
||||
local bAreAllMachiningsAdded = true
|
||||
local Milling = {}
|
||||
|
||||
Strategy.Machinings = GetArcStrategy( Proc, Part)
|
||||
-- controlli preliminari
|
||||
if Proc.nFct < 3 or Proc.nFct > 5 then
|
||||
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. StrategyLib.Config.sStrategyId .. ' not applicable'
|
||||
EgtOutLog( sErr)
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sErr)
|
||||
return false, Strategy.Result
|
||||
end
|
||||
|
||||
if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then
|
||||
-- eventuali punti di spezzatura
|
||||
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
|
||||
Strategy.Machinings, Strategy.Result = GetScarfJointStrategy( Proc, Part)
|
||||
|
||||
for i = 1, #Strategy.Machinings do
|
||||
|
||||
Strategy.Machinings[i].Geometry = {{ Proc.idAddAuxGeom, -1}}
|
||||
Strategy.Machinings[i].nToolIndex = Strategy.Machinings[i].ToolInfo.nToolIndex
|
||||
Strategy.Machinings[i].nType = MCH_MY.MILLING
|
||||
Strategy.Machinings[i].dStartSafetyLength = 0
|
||||
Strategy.Machinings[i].Steps = {}
|
||||
Strategy.Machinings[i].Steps = MachiningLib.GetMachiningSteps( false, tonumber( Strategy.Machinings[i].sDepth), TOOLS[Strategy.Machinings[i].nToolIndex].dStep)
|
||||
|
||||
-- LeadIn / LeadOut
|
||||
Strategy.Machinings[i].LeadIn = {}
|
||||
Strategy.Machinings[i].LeadOut = {}
|
||||
Strategy.Machinings[i].LeadIn.nType = MCH_MILL_LI.TANGENT
|
||||
Strategy.Machinings[i].LeadOut.nType = MCH_MILL_LI.TANGENT
|
||||
Strategy.Machinings[i].LeadIn.dTangentDistance = TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
Strategy.Machinings[i].LeadIn.dPerpDistance = 0
|
||||
Strategy.Machinings[i].LeadIn.dStartAddLength = 0
|
||||
Strategy.Machinings[i].LeadOut.dTangentDistance = TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
Strategy.Machinings[i].LeadOut.dPerpDistance = 0
|
||||
Strategy.Machinings[i].LeadOut.dEndAddLength = 0
|
||||
|
||||
local dLengthOnX = Proc.b3Box:getDimX()
|
||||
Strategy.bCanMoveAfterSplit = MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part)
|
||||
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
|
||||
Strategy.Machinings[i].sStage = 'AfterTail'
|
||||
end
|
||||
|
||||
-- preparo attacco/uscita in caso di spezzatura arco
|
||||
Strategy.Machinings[i].LeadInForSplit = BeamLib.TableCopyDeep( Strategy.Machinings[i].LeadIn)
|
||||
Strategy.Machinings[i].LeadOutForSplit = BeamLib.TableCopyDeep( Strategy.Machinings[i].LeadOut)
|
||||
Strategy.Machinings[i].LeadInForSplit.nType = MCH_MILL_LI.LINEAR
|
||||
Strategy.Machinings[i].LeadOutForSplit.nType = MCH_MILL_LI.LINEAR
|
||||
Strategy.Machinings[i].LeadInForSplit.dTangentDistance = 0
|
||||
Strategy.Machinings[i].LeadInForSplit.dPerpDistance = TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
Strategy.Machinings[i].LeadOutForSplit.dTangentDistance = 0
|
||||
Strategy.Machinings[i].LeadOutForSplit.dPerpDistance = TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
|
||||
|
||||
-- sistemo il lato e la direzione di lavoro
|
||||
if i == 1 then
|
||||
Strategy.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].bIsCCW, false, true)
|
||||
Strategy.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
|
||||
else
|
||||
Strategy.Machinings[i].bToolInvert = true
|
||||
Strategy.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].bIsCCW, true, false)
|
||||
Strategy.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
|
||||
end
|
||||
Strategy.Machinings[i].ptEdge1 = EgtSP( Proc.idAddAuxGeom, GDB_ID.ROOT)
|
||||
Strategy.Machinings[i].ptEdge2 = EgtEP( Proc.idAddAuxGeom, GDB_ID.ROOT)
|
||||
Strategy.Machinings[i].dEdgeLength = EgtCurveLength( Proc.idAddAuxGeom)
|
||||
Strategy.Machinings[i].vtEdgeDirection = EgtSV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtMV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtEV( Proc.idAddAuxGeom, GDB_ID.ROOT)
|
||||
Strategy.Machinings[i].dLengthOnX = Proc.b3Box:getDimX()
|
||||
|
||||
local MachiningToSplit = {}
|
||||
table.insert( MachiningToSplit, Strategy.Machinings[i])
|
||||
local MachiningResult = MachiningLib.GetSplitMachinings( MachiningToSplit, FeatureSplittingPoints, Part)
|
||||
-- aggiunta lavorazioni
|
||||
if #Strategy.Machinings > 0 then
|
||||
if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then
|
||||
-- aggiunge lavorazione
|
||||
for j = 1, #MachiningResult do
|
||||
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, MachiningResult[j])
|
||||
for j = 1, #Strategy.Machinings do
|
||||
if Proc.AffectedFaces.bLeft then
|
||||
Strategy.Machinings[j].sStage = 'AfterTail'
|
||||
end
|
||||
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machinings[j])
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
bAreAllMachiningsAdded = false
|
||||
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable()
|
||||
end
|
||||
|
||||
|
||||
return bAreAllMachiningsAdded, Strategy.Result
|
||||
end
|
||||
|
||||
|
||||
@@ -215,6 +215,7 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
end
|
||||
|
||||
-- se la lavorazione ostacola il pinzaggio, non posso farla, serve una lavorazioen che lasci il testimone
|
||||
-- TODO Girando il pezzo trova sempre che limitano il pinzaggio se pezzo piccolo!! Il controllo non va bene. Da rifare
|
||||
if MachiningLib.IsFeatureHinderingClamping( Proc, Part) then
|
||||
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. StrategyLib.Config.sStrategyId .. ' not applicable ( Feature hinders clamping)'
|
||||
EgtOutLog( sErr)
|
||||
@@ -253,6 +254,7 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
ToolSearchParameters.vtToolDirection = BottomFace1.vtN
|
||||
ToolSearchParameters.bAllowTopHead = true
|
||||
ToolSearchParameters.bAllowBottomHead = true
|
||||
ToolSearchParameters.sMillShape = 'STANDARD'
|
||||
local ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
local nToolIndex = ToolInfo.nToolIndex
|
||||
|
||||
@@ -391,7 +393,12 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy.Machinings = MachiningLib.GetSplitMachinings( Strategy.Machinings, FeatureSplittingPoints, Part)
|
||||
table.sort( Strategy.Machinings, SortMachiningsBySegment)
|
||||
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( Strategy.Machinings)
|
||||
-- se non ci sono lati chiusi, la qualità è migliore
|
||||
if Proc.Topology.sName == 'Bevel-1-Through' or Proc.Topology.sName == 'DoubleBevel-2-Through' or Proc.Topology.sName == 'Cut-1-Through' then
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
|
||||
else
|
||||
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( Strategy.Machinings)
|
||||
end
|
||||
Strategy.Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Strategy.Machinings)
|
||||
Strategy.Result.dMRR = ( dFeatureVolume / Strategy.Result.dTimeToMachine) / pow( 10, 6)
|
||||
if Strategy.Result.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
|
||||
|
||||
@@ -74,7 +74,7 @@ local function GetDrillingWithMillStrategy( Proc, Part)
|
||||
HalfMilling2.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
|
||||
|
||||
-- se entrambi gli utensili lavorano in modo completo fino alla metà del foro, li sostituisco a qeulli trovati in precedenza
|
||||
if HalfMilling.ToolInfo.dResidualDepth < 0 and HalfMilling2.ToolInfo.dResidualDepth < 0 then
|
||||
if HalfMilling.ToolInfo.dResidualDepth and HalfMilling2.ToolInfo.dResidualDepth and HalfMilling.ToolInfo.dResidualDepth < 0 and HalfMilling2.ToolInfo.dResidualDepth < 0 then
|
||||
if Milling.ToolInfo.nToolIndex ~= HalfMilling.ToolInfo.nToolIndex then
|
||||
Milling.ToolInfo.nToolIndex, Milling.ToolInfo.dResidualDepth = HalfMilling.ToolInfo.nToolIndex, HalfMilling.ToolInfo.dResidualDepth
|
||||
end
|
||||
|
||||
@@ -24,6 +24,8 @@ local function GetSCC( Machining)
|
||||
|
||||
if TOOLS[Machining.nToolIndex].SetupInfo.bToolOnAggregate then
|
||||
nSCC = MCH_SCC.ADIR_NEAR
|
||||
elseif TOOLS[Machining.nToolIndex].SetupInfo.nBlockedSCC then
|
||||
nSCC = TOOLS[Machining.nToolIndex].SetupInfo.nBlockedSCC
|
||||
elseif Machining.vtToolDirection:getY() <= 0 then
|
||||
nSCC = MCH_SCC.ADIR_YM
|
||||
else
|
||||
@@ -96,7 +98,7 @@ function STR0014.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy.Machining.nSCC = GetSCC( Strategy.Machining)
|
||||
|
||||
Strategy.Machining.nType = MCH_MY.MILLING
|
||||
Strategy.Machining.sDepth = EgtClamp( Strategy.Parameters.dMachiningDepth, -1, 5)
|
||||
Strategy.Machining.sDepth = EgtClamp( Strategy.Parameters.dMachiningDepth, -1, TOOLS[Strategy.Machining.nToolIndex].dMaxMaterial)
|
||||
Strategy.Machining.nWorkside = MCH_MILL_WS.CENTER
|
||||
|
||||
-- LeadIn / LeadOut
|
||||
@@ -104,12 +106,24 @@ function STR0014.Make( bAddMachining, Proc, Part, CustomParameters)
|
||||
Strategy.Machining.LeadOut = {}
|
||||
Strategy.Machining.LeadIn.nType = MCH_MILL_LI.NONE
|
||||
Strategy.Machining.LeadOut.nType = MCH_MILL_LI.NONE
|
||||
|
||||
-- se è una penna, si limita la lavorazione per evitare di partire fuori dal grezzo
|
||||
if ToolSearchParameters.sMillShape == 'PEN' then
|
||||
Strategy.Machining.LeadIn.dStartAddLength = -20
|
||||
Strategy.Machining.LeadOut.dEndAddLength = -20
|
||||
end
|
||||
|
||||
-- TODO gestire meglio
|
||||
-- se utensile montato su aggregato flottante
|
||||
if TOOLS[Strategy.Machining.nToolIndex].bToolOnFloatingTH then
|
||||
Strategy.Machining.dMaxElev = Strategy.Parameters.dMachiningDepth
|
||||
Strategy.Machining.dLongitudinalOffset = -5
|
||||
end
|
||||
-- stessi parametri cambia solo al geometria
|
||||
for i = 1, #Proc.FeatureInfo.AdditionalGeometries do
|
||||
local AuxId = Proc.id + Proc.FeatureInfo.AdditionalGeometries[i]
|
||||
Strategy.AuxiliaryData.Clones[i+1] = {}
|
||||
Strategy.AuxiliaryData.Clones[i+1].Geometry = EgtSetMachiningGeometry( {{ AuxId, -1}})
|
||||
Strategy.AuxiliaryData.Clones[i+1].Geometry = {{ AuxId, -1}}
|
||||
end
|
||||
|
||||
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machining, Strategy.AuxiliaryData)
|
||||
|
||||
@@ -8,7 +8,7 @@ STR0005 = 1, 2 o 3 facce. Lama con taglio singolo o cubetti. Se richiesto o nece
|
||||
STR0006 = Tenone. Lama + fresa
|
||||
STR0007 = Mortasa a coda di rondine e mortasa frontale a coda di rondine
|
||||
STR0008 = Svuotatura mortasa (raggiata)
|
||||
STR0009 = !!DEPRECATA!! Sostituita da STR0015. RIUTILIZZABILE!
|
||||
STR0009 = ScarfJoint
|
||||
STR0010 = Fresatura perpendicolare (tipo cut, longcut)
|
||||
STR0011 = Foratura
|
||||
STR0012 = RidgeLap
|
||||
|
||||
@@ -795,6 +795,7 @@ local function CalculateDiceMachinings( vCuts, Parameters)
|
||||
local bReduceBladePath = Parameters.bReduceBladePath
|
||||
local sRestLengthSideForPreSimulation = Parameters.sRestLengthSideForPreSimulation
|
||||
local bCannotSplitRestLength = Parameters.bCannotSplitRestLength
|
||||
local bReduceDiceDepth = Parameters.bReduceDiceDepth
|
||||
|
||||
-- eventuale inversione tagli ortogonali e aggiunta informazioni alla geometria
|
||||
local bAreOrthogonalCutsInverted = false
|
||||
@@ -884,8 +885,13 @@ local function CalculateDiceMachinings( vCuts, Parameters)
|
||||
-- caso standard (tagli perpendicolari o paralleli non accorpabili)
|
||||
if ( not bCanMergeParallelCuts) or ( not bIsDicingOk) then
|
||||
for j = 1, #vCuts[i] do
|
||||
-- in generale sta sollevato di pochissimo
|
||||
local dExtraCut = -0.1
|
||||
-- se abilitato, la lama sta sollevata per non rovinare le facce
|
||||
local dExtraCut
|
||||
if bReduceDiceDepth == false then
|
||||
dExtraCut = 0
|
||||
else
|
||||
dExtraCut = -0.1
|
||||
end
|
||||
-- se tagli paralleli
|
||||
if ( i % 2) == 0 then
|
||||
-- se non ci sono tagli ortogonali devo affondare
|
||||
@@ -914,7 +920,8 @@ local function CalculateDiceMachinings( vCuts, Parameters)
|
||||
dExtendAfterTail = dExtendAfterTail,
|
||||
bIsDicing = true,
|
||||
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
|
||||
bCannotSplitRestLength = bCannotSplitRestLength
|
||||
bCannotSplitRestLength = bCannotSplitRestLength,
|
||||
bDisableRealElevationCheck = ( i % 2) > 0 -- se taglio perpendicolare non si deve mai considerare il materiale precedente
|
||||
}
|
||||
Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade)
|
||||
Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0)
|
||||
@@ -964,10 +971,13 @@ local function CutWithDicing( Proc, Part, OptionalParameters)
|
||||
end
|
||||
end
|
||||
|
||||
-- angolo tra le facce, se più di una
|
||||
local dAngleBetweenFaces = Proc.AdjacencyMatrix[1][2] or 0
|
||||
|
||||
-- scelta lama da sopra o da sotto
|
||||
local sChosenBladeType = ''
|
||||
if not nToolIndex then
|
||||
nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, Face1)
|
||||
nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part)
|
||||
end
|
||||
|
||||
-- se non trovata lama la lavorazione non è fattibile
|
||||
@@ -1008,7 +1018,8 @@ local function CutWithDicing( Proc, Part, OptionalParameters)
|
||||
dExtendAfterTail = dExtendAfterTail,
|
||||
bReduceBladePath = bReduceBladePath,
|
||||
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
|
||||
bCannotSplitRestLength = bCannotSplitRestLength
|
||||
bCannotSplitRestLength = bCannotSplitRestLength,
|
||||
bReduceDiceDepth = ( dAngleBetweenFaces < - 10) -- per facce molto aperte non si riduce l'affondamento della lama nei cubetti (rischio che non si stacchino)
|
||||
}
|
||||
|
||||
bIsDicingOk, Machinings, bMoveAfterSplit = CalculateDiceMachinings( vCuts, Parameters)
|
||||
|
||||
@@ -211,6 +211,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
local bIsDicing = OptionalParameters.bIsDicing or false
|
||||
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
|
||||
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
|
||||
local bDisableRealElevationCheck = OptionalParameters.bDisableRealElevationCheck or false
|
||||
|
||||
-- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato
|
||||
Cutting.dEdgeLength = EdgeToMachine.dLength
|
||||
@@ -231,10 +232,14 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
Tool = TOOLS[Cutting.nToolIndex],
|
||||
dDepthToMachine = dDepthToMachine
|
||||
}
|
||||
if OppositeToolDirectionMode == 'Enabled' then
|
||||
BladeEngagementParameters.Edge = EdgeToMachineOpposite
|
||||
end
|
||||
local BladeEngagementOptionalParameters = {
|
||||
bIsDicing = bIsDicing,
|
||||
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
|
||||
bCannotSplitRestLength = bCannotSplitRestLength
|
||||
bCannotSplitRestLength = bCannotSplitRestLength,
|
||||
bDisableRealElevationCheck = bDisableRealElevationCheck
|
||||
}
|
||||
local Engagement
|
||||
TIMER:startElapsed( 'GetBladeEngagement')
|
||||
@@ -258,6 +263,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
ToolSearchParameters.Part = Part
|
||||
ToolSearchParameters.sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation
|
||||
ToolSearchParameters.bCannotSplitRestLength = bCannotSplitRestLength
|
||||
ToolSearchParameters.bDisableRealElevationCheck = bDisableRealElevationCheck
|
||||
|
||||
local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
|
||||
Cutting.nToolIndex = ToolInfo.nToolIndex
|
||||
@@ -355,7 +361,8 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
local BladeEngagementOptionalParameters = {
|
||||
bIsDicing = bIsDicing,
|
||||
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
|
||||
bCannotSplitRestLength = bCannotSplitRestLength
|
||||
bCannotSplitRestLength = bCannotSplitRestLength,
|
||||
bDisableRealElevationCheck = bDisableRealElevationCheck
|
||||
}
|
||||
TIMER:startElapsed( 'GetBladeEngagement')
|
||||
local bIsApplicableOpposite, EngagementOpposite = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters)
|
||||
@@ -472,7 +479,8 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
|
||||
local BladeEngagementOptionalParameters = {
|
||||
bIsDicing = bIsDicing,
|
||||
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
|
||||
bCannotSplitRestLength = bCannotSplitRestLength
|
||||
bCannotSplitRestLength = bCannotSplitRestLength,
|
||||
bDisableRealElevationCheck = bDisableRealElevationCheck
|
||||
}
|
||||
TIMER:startElapsed( 'GetBladeEngagement')
|
||||
local bIsApplicable, CurrentEngagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters )
|
||||
|
||||
Reference in New Issue
Block a user