diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 2a1ce8c..79ad799 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -377,191 +377,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 dResidualLength = dRawL - local idPrevRaw, dPrevDelta - local dStartOffset = dOvmHead - local dEndOffset = 0 -- TODO cosa fare di BD.OVM_MID? usarlo solo se non è nesting obliquo? + 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 dPartLength = PARTS[i].b3PartOriginal:getDimX() - local dPartWidth = PARTS[i].b3PartOriginal:getDimY() - local dPartHeight = PARTS[i].b3PartOriginal:getDimZ() - local dNextResidualLength = dResidualLength - EgtIf( i == 1, dStartOffset, 0) - dPartLength - dEndOffset - 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 ( dNextResidualLength + dEndOffset >= 0) then - -- eventuale sovramateriale di testa - if i > 1 then - if PARTS[i].dPosX then - dStartOffset = PARTS[i].dPosX - ( dRawL - dResidualLength) - if dStartOffset < -GEO.EPS_SMALL then - dResidualLength = dResidualLength - dStartOffset - dStartOffset = 0 - end - else - dStartOffset = max( dOvmMid - dEndOffset, 0) - end - end - -- dimensioni del grezzo - local dCurrentRawLength = min( dPartLength + dStartOffset + dEndOffset, dResidualLength) - local dDelta = dCurrentRawLength - dPartLength - dStartOffset - -- creo e posiziono il grezzo - PARTS[i].idRaw = EgtAddRawPart( Point3d(0,0,0), dCurrentRawLength, 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( dResidualLength - 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 - 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 dStartOffset > 0.09 then - EgtSetInfo( PARTS[i].idRaw, 'HOVM', dStartOffset) - if idPrevRaw then - EgtSetInfo( idPrevRaw, 'BDST', dStartOffset + dPrevDelta) - end - end - if dEndOffset > 0.09 then - EgtSetInfo( PARTS[i].idRaw, 'TOVM', dEndOffset) - 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 - dResidualLength = dResidualLength - dCurrentRawLength - -- aggiorno grezzo precedente - idPrevRaw = PARTS[i].idRaw - dPrevDelta = dDelta - PARTS[i].bIsLastPart = ( i == #PARTS) - PARTS[i].dDistanceToNextPiece = dDelta - PARTS[i].dRestLength = dResidualLength - 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 = dStartOffset - 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( dPartLength, 1) .. ') too big for raw part L(' .. EgtNumToString( dResidualLength - 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 dResidualLength > 10 then - local idRaw = EgtAddRawPart( Point3d(0,0,0), dResidualLength, dRawW, dRawH, BeamData.RAWCOL) - EgtMoveToCornerRawPart( idRaw, BeamData.ptOriXR, BeamData.dPosXR) - EgtMoveRawPart( idRaw, Vector3d( dResidualLength - 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