From 9d493812d9db6253dd33406aeaf2d1c1e9364a9b Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Thu, 13 Jun 2024 10:27:19 +0200 Subject: [PATCH 01/10] - Creazione directoy per CAM Auto - Creata Process, selezione pezzi manuale (NON FUNZIONANTE) --- CAMAuto/ProcessWin.lua | 214 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 CAMAuto/ProcessWin.lua diff --git a/CAMAuto/ProcessWin.lua b/CAMAuto/ProcessWin.lua new file mode 100644 index 0000000..365b7af --- /dev/null +++ b/CAMAuto/ProcessWin.lua @@ -0,0 +1,214 @@ +-- Process.lua by Egalware s.r.l. 2024/06/13 +-- Gestione calcolo disposizione e lavorazioni per serramenti +-- Si opera sulla macchina corrente +-- 2024/06/13 PRIMA VERSIONE + + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( true) + +-- TODO da cancellare quando verrà passato automaticamente da programma +local WIN = {} +WIN.BASEDIR = 'C:\\EgtData\\EgwWindowLua\\CAMAuto' + +-- Imposto direttorio libreria specializzata per serramenti +EgtAddToPackagePath( WIN.BASEDIR .. '\\LuaLibs\\?.lua') +-- Imposto direttorio strategie. N.B. Le strategie dovranno essere caricate con il nome del direttorio padre +EgtAddToPackagePath( WIN.BASEDIR .. '\\Strategies\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not sMachDir then + EgtOutBox( 'Errore nel caricamento della macchina corrente', 'Lavora Serramenti', 'ERROR') + return +end +if not EgtExistsFile( sMachDir .. '\\Window\\WinData.lua') then + EgtOutBox( 'La macchina corrente non è configurata per lavorare serramenti', 'Lavora Serramenti', 'ERROR') + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Window\\?.lua') + +-- Segnalazione avvio +EgtOutLog( '*** Window Process Start ***', 1) + +-- Carico le librerie +_G.package.loaded.WinExec = nil + +-- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente +-- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento. +-- Infatti difficile ci siano 9999 strategie. +-- reset strategie caricate come librerie +for i = 1, 99 do + local IdSTRTemp = EgtReplaceString( tostring( i/10000, 4), '0.', '') + local sLibraryToReload = "STR" .. IdSTRTemp .. "\\STR" .. IdSTRTemp + local sLibraryConfigToReload = sLibraryToReload .. "Config" + if _G.package.loaded[sLibraryToReload] then + _G.package.loaded[sLibraryToReload] = nil + end + if _G.package.loaded[sLibraryConfigToReload] then + _G.package.loaded[sLibraryConfigToReload] = nil + end +end + +local WinExec = require( 'WinExec') + +-- Variabili globali +PARTS = {} + +------------------------------------------------------------------------------------------------------------- +-- *** Recupero i pezzi da processare *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessInputData() + -- Recupero le travi selezionate + local nId = EgtGetFirstSelectedObj() + while nId do + local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) + if nPartId then + local bFound = false + for i = 1, #PARTS do + if PARTS[i].id == nPartId then + bFound = true + break + end + end + if not bFound then + table.insert( PARTS, { nInd = #PARTS + 1, id = nPartId, sName = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + end + end + nId = EgtGetNextSelectedObj() + end + if #PARTS == 0 then + EgtOutBox( 'Non sono state selezionati pezzi', 'Lavora Pezzi', 'ERROR') + return false + else + local sOut = '' + for i = 1, #PARTS do + sOut = sOut .. PARTS[i].sName .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Pezzi selezionati : ' .. sOut, 1) + end + + EgtDeselectAll() + + return true +end + +------------------------------------------------------------------------------------------------------------- +local function GetDataConfig() + -- recupero utensili dal magazzino + WinExec.GetToolsFromDB() + + -- TODO da gestire eventuali errori bloccanti + return true +end + +------------------------------------------------------------------------------------------------------------- +local function GetDispOffsetFromNotes( nPieceIndex) + local bAllOffsetsAreOk = false + local DispOffset = {} + DispOffset.Phase1 = {} + DispOffset.Phase2 = {} + + DispOffset.Phase1.dOffsetY = EgtGetInfo( PIECES[nPieceIndex].id, 'OFFY_1', 'd') + DispOffset.Phase1.dOffsetZ = EgtGetInfo( PIECES[nPieceIndex].id, 'OFFZ_1', 'd') + DispOffset.Phase2.dOffsetY = EgtGetInfo( PIECES[nPieceIndex].id, 'OFFY_2', 'd') + DispOffset.Phase2.dOffsetZ = EgtGetInfo( PIECES[nPieceIndex].id, 'OFFZ_2', 'd') + + -- controllo se tutti gli offset sono settati + if DispOffset.Phase1.dOffsetY and DispOffset.Phase1.dOffsetZ and DispOffset.Phase2.dOffsetY and DispOffset.Phase2.dOffsetZ then + bAllOffsetsAreOk = true + end + + return bAllOffsetsAreOk +end + +------------------------------------------------------------------------------------------------------------- +local function GetDispOffsetFromInput( nPieceIndex) + -- assegno alle stringhe i valori letti, in modo che vengano proposti quelli nel dialogo + local sOffYPh1 = EgtIf( PIECES[nPieceIndex].DispOffset.Phase1.dOffsetY, tostring( PIECES[nPieceIndex].DispOffset.Phase1.dOffsetY), tostring( PIECES[nPieceIndex].dWidth / 2)) + local sOffZPh1 = EgtIf( PIECES[nPieceIndex].DispOffset.Phase1.dOffsetZ, tostring( PIECES[nPieceIndex].DispOffset.Phase1.dOffsetZ), '0') + local sOffYPh2 = EgtIf( PIECES[nPieceIndex].DispOffset.Phase2.dOffsetY, tostring( PIECES[nPieceIndex].DispOffset.Phase2.dOffsetY), tostring( PIECES[nPieceIndex].dWidth / 2)) + local sOffZPh2 = EgtIf( PIECES[nPieceIndex].DispOffset.Phase2.dOffsetZ, tostring( PIECES[nPieceIndex].DispOffset.Phase2.dOffsetZ), '0') + + + local vInp = EgtDialogBox( 'Dati di disposizione pezzo: ' .. PIECES[nPieceIndex].sName, + {'Sporgenza laterale FASE1', sOffYPh1}, {'Posizione Z FASE1', sOffZPh1}, + {'Sporgenza laterale FASE2', sOffYPh2}, {'Posizione Z FASE2', sOffZPh2}) + if not vInp or #vInp == 0 then + return false + end + + -- salvo input nei valori che utilizzerò dopo + PIECES[nPieceIndex].DispOffset.Phase1.dOffsetY = tonumber( vInp[1]) + PIECES[nPieceIndex].DispOffset.Phase1.dOffsetZ = tonumber( vInp[2]) + PIECES[nPieceIndex].DispOffset.Phase2.dOffsetY = tonumber( vInp[3]) + PIECES[nPieceIndex].DispOffset.Phase2.dOffsetZ = tonumber( vInp[4]) + + return true +end + +--------------------------------------------------------------------- +-- Crea il grezzo che verrà messo in macchina +--------------------------------------------------------------------- +local function CreateRawPart( PIECES) + +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle travi nel grezzo *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessPieces() + + -- verifico che i pezzi selezionati siano compatibili con la macchina + WinData.VerifyPieces( PIECES) + + -- si crea il grezzo + CreateRawPart( PIECES) + + -- recupero offset per posizionamento + for i = 1, #PIECES do + local bInsertedAllOffs = GetDispOffsetFromNotes( i) + -- se non sono settati nelle note, li chiedo + if not bInsertedAllOffs then + bInsertedAllOffs = GetDispOffsetFromInput( i) + end + -- se non sono stati inseriti o c'è stato un errore esco subito + if not bInsertedAllOffs then + return false + end + end + + -- si dispongono i pezzi sulla tavola + WinData.DisposePiecesOnTable( PIECES) + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessFeatures() + local bOk, Stats = WinExec.ProcessFeatures( PARTS) + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Esecuzione *** +------------------------------------------------------------------------------------------------------------- +if not MyProcessInputData() then return end + +if not MyProcessPieces() then return end + +if not GetDataConfig() then return end + +-- Abilito Vmill +EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + +if not MyProcessFeatures() then return end From 7d571bff399d103bd326f649ec9ab3fabbae42f5 Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Thu, 13 Jun 2024 12:32:23 +0200 Subject: [PATCH 02/10] - Creazione WinExec (derivazione da progetto Beam) - Funzione allineamento pezzo - Funzione aggiunta sovramateriale pezzo - Altre modifiche minori --- .vscode/settings.json | 3 +- CAMAuto/LuaLibs/WinExec.lua | 742 ++++++++++++++++++++++++++++++++++++ CAMAuto/ProcessWin.lua | 101 ++++- 3 files changed, 825 insertions(+), 21 deletions(-) create mode 100644 CAMAuto/LuaLibs/WinExec.lua diff --git a/.vscode/settings.json b/.vscode/settings.json index a4b88aa..5452152 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -108,7 +108,8 @@ "EgtFrame", "EgtReplaceString", "EgtCircle", - "EgtArc2PV" + "EgtArc2PV", + "EgtTdbSetCurrTool" ], "Lua.diagnostics.disable": [ "empty-block" diff --git a/CAMAuto/LuaLibs/WinExec.lua b/CAMAuto/LuaLibs/WinExec.lua new file mode 100644 index 0000000..b975612 --- /dev/null +++ b/CAMAuto/LuaLibs/WinExec.lua @@ -0,0 +1,742 @@ +-- WinExec.lua by Egalware s.r.l. 2024/06/13 +-- Libreria esecuzione lavorazioni per Serramenti + +-- Tabella per definizione modulo +local WinExec = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali +local WinData = require( 'WinData') + +EgtOutLog( ' WinExec started', 1) +EgtMdbSave() + +------------------------------------------------------------------------------------------------------------- +-- *** variabili globali *** +------------------------------------------------------------------------------------------------------------- +TOOLS = nil +STRATEGIES = nil +MACHININGS = nil + +------------------------------------------------------------------------------------------------------------- +-- *** COSTANTI *** TODO -> DA SPOSTARE IN BEAMDATA??? +------------------------------------------------------------------------------------------------------------- +TH_DIAMETER_HSK63 = 63 +TH_LENGTH_HSK63 = 75 +SIDEANGLE_DOVETAIL = 15 + +------------------------------------------------------------------------------------------------------------- +-- *** funzioni di base *** +------------------------------------------------------------------------------------------------------------- +local function GetToolTypeNameFromToolTypeID( dToolTypeID) + if dToolTypeID == MCH_TY.DRILL_STD then + return 'DRILL_STD', 'DRILLBIT' + elseif dToolTypeID == MCH_TY.DRILL_LONG then + return 'DRILL_LONG', 'DRILLBIT' + elseif dToolTypeID == MCH_TY.SAW_STD then + return 'SAW_STD', 'SAWBLADE' + elseif dToolTypeID == MCH_TY.SAW_FLAT then + return 'SAW_FLAT', 'SAWBLADE' + elseif dToolTypeID == MCH_TY.MILL_STD then + return 'MILL_STD', 'MILL' + elseif dToolTypeID == MCH_TY.MILL_NOTIP then + return 'MILL_NOTIP', 'MILL' + elseif dToolTypeID == MCH_TY.MORTISE_STD then + return 'MORTISE_STD', 'MORTISE' + else + return nil + end +end + +------------------------------------------------------------------------------------------------------------- +local function IsToolOk( Tool) + -- controllo che i dati necessari siano impostati + if Tool.dMaxMaterial and Tool.dDiameter and Tool.dLength and Tool.sHead and Tool.sUUID then + -- se DRILLBIT non ho altri dati + if Tool.sFamily == 'DRILLBIT' then + return true + -- altrimenti controllo dati aggiuntivi altre famiglie di utensili + elseif Tool.sFamily == 'MORTISE' then + if Tool.dCornerRadius then + return true + end + else + if Tool.dThickness then + return true + end + end + end + + return false +end + +------------------------------------------------------------------------------------------------------------- +function WinExec.GetToolsFromDB() + +-- TODO gli utensili profilati devono essere messi in una lista a parte ad accesso diretto TOOLS['Prof1'] in modo da non dover scorrere la lista +-- dato che saranno molti e l'applicazione sarà diretta. Non serve ciclarli + + + -- creo lista globale utensili disponibili + TOOLS = {} + -- lista appoggio utensile + local Tool = {} + + -- recupero tutti gli utensili : punte a forare, lame, frese e motoseghe + Tool.sName = EgtTdbGetFirstTool( MCH_TF.DRILLBIT + MCH_TF.SAWBLADE + MCH_TF.MILL + MCH_TF.MORTISE) + while Tool.sName ~= '' do + -- imposto utensile come corrente per recuperarne i dati + EgtTdbSetCurrTool( Tool.sName) + + -- verifico se utensile disponibile in attrezzaggio attuale e che abbia un tipo ben definito + local bToolLoadedOnSetup, sToolTCPos = EgtFindToolInCurrSetup( Tool.sName) + local nToolTypeId = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + local sToolType, sToolFamily = GetToolTypeNameFromToolTypeID( nToolTypeId) + + -- se verifica condizioni minime, recupero tutti gli altri dati + if bToolLoadedOnSetup and sToolType then + -- TODO Tool.AName -> da rimuovere perchè non serve. Per il momento lo manteniamo solo perchè è più facile vedere e interpretare la lista utensili nella watch di zerobrane + -- Nell'utilizzo, si legge sempre il Tool.Name + Tool.AName = Tool.sName + Tool.sTcPos = sToolTCPos + Tool.sFamily = sToolFamily + Tool.sType = sToolType + Tool.nTypeId = nToolTypeId + Tool.dMaxMaterial = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + Tool.dDiameter = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + Tool.dLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) + Tool.dSpeed = EgtTdbGetCurrToolParam( MCH_TP.SPEED) + Tool.bIsCCW = Tool.dSpeed < 0 + Tool.Feeds = {} + Tool.Feeds.dFeed = EgtTdbGetCurrToolParam( MCH_TP.FEED) + Tool.Feeds.dStartFeed = EgtTdbGetCurrToolParam( MCH_TP.STARTFEED) + Tool.Feeds.dEndFeed = EgtTdbGetCurrToolParam( MCH_TP.ENDFEED) + Tool.Feeds.dTipFeed = EgtTdbGetCurrToolParam( MCH_TP.TIPFEED) + -- TODO serve funzione in BeamData che data la posizione dell'utensile e della testa, capisca il montaggio (testa sopra - testa sotto - aggregato - ecc...) + Tool.sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + Tool.SetupInfo = {} + Tool.SetupInfo = BeamData.GetSetupInfo( Tool.sHead) + Tool.sUUID = EgtTdbGetCurrToolParam( MCH_TP.UUID) + Tool.sUserNotes = EgtTdbGetCurrToolParam( MCH_TP.USERNOTES) + Tool.dMaxDepth = EgtTdbGetCurrToolMaxDepth() or Tool.dMaxMaterial + Tool.ToolHolder = {} + Tool.ToolHolder.dDiameter = EgtTdbGetCurrToolThDiam() or TH_DIAMETER_HSK63 -- diametro standard HSK63 + Tool.ToolHolder.dLength = EgtTdbGetCurrToolThLength() or TH_LENGTH_HSK63 -- lunghezza standard HSK63 + -- parametri scritti nelle note + Tool.nDouble = EgtGetValInNotes( Tool.sUserNotes, 'DOUBLE') + + -- lettura parametri non comuni ( famiglia DRILLBIT non ha parametri specifici) + if sToolFamily ~= 'DRILLBIT' then + Tool.dThickness = EgtTdbGetCurrToolParam( MCH_TP.THICK) + Tool.dLongitudinalOffset = EgtTdbGetCurrToolParam( MCH_TP.LONOFFSET) + Tool.dRadialOffset = EgtTdbGetCurrToolParam( MCH_TP.RADOFFSET) + -- recupero parametri propri delle frese + if sToolFamily == 'MILL' then + Tool.dStemDiameter = EgtTdbGetCurrToolParam( MCH_TP.STEMDIAM) or Tool.ToolHolder.dDiameter -- se non settato, considero diametro come ToolHolder + Tool.dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or 0 + -- verifico che parametri siano compatibili con una fresa a coda di rondine ( angolo di fianco standard Coda di rondine -> 15°) + Tool.bIsDoveTail = Tool.Type == 'MILL_NOTIP' and abs( abs( Tool.dSideAngle) - SIDEANGLE_DOVETAIL) < 1 + -- verifico che sia una fresa tipo T-Mill o BlockHaus + Tool.dSideDepth = EgtGetValInNotes( Tool.sUserNotes, 'SIDEDEPTH') or 0 -- se non settato nell'utensile, dico che non ha massimo affondamento laterale + Tool.bIsTMill = Tool.dSideDepth > 0 + Tool.dStep = EgtGetValInNotes( Tool.sUserNotes, 'STEP') or ( Tool.dMaxMaterial / 3) -- se non settato nell'utensile, considero metà del tagliente + Tool.dSideStep = EgtGetValInNotes( Tool.sUserNotes, 'SIDESTEP') or floor( Tool.dDiameter / 3) -- se non settato nell'utensile, considero metà del diametro + Tool.bIsPen = abs( Tool.dSpeed) < 5 + -- recupero parametri propri delle lame + elseif sToolFamily == 'SAWBLADE' then + Tool.bIsUsedForLongCut = EgtGetValInNotes( Tool.sUserNotes, 'LONGCUT') == 1 or false -- false coem valore di default + Tool.dStep = EgtGetValInNotes( Tool.sUserNotes, 'STEP') or Tool.dThickness -- se non settato nell'utensile, considero lo spessore lama + Tool.dSideStep = EgtGetValInNotes( Tool.sUserNotes, 'SIDESTEP') or Tool.dMaxMaterial -- se non settato nell'utensile, considero un quarto del diametro + -- recupero parametri propri delle motoseghe + elseif sToolFamily == 'MORTISE' then + Tool.dDistance = EgtTdbGetCurrToolParam( MCH_TP.DIST) or 90 -- 90mm dimensione standard aggregato catena + Tool.bIsMortise = EgtGetValInNotes( Tool.sUserNotes, 'MORTISE') == 1 + Tool.bIsChainSaw = not Tool.bIsMortise + Tool.dStep = EgtGetValInNotes( Tool.sUserNotes, 'STEP') or floor( Tool.dMaxMaterial / 3) -- se non settato nell'utensile, considero un terzo della lunghezza + Tool.dSideStep = EgtGetValInNotes( Tool.sUserNotes, 'SIDESTEP') or ( Tool.dThickness - 1) -- se non settato nell'utensile, considero spessore catena meno 1mm di sicurezza + Tool.dCornerRadius = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) + Tool.dWidth = Tool.dDiameter + end + end + + -- se tutti i dati necessari sono disponibili, inserisco utensile nella lista globale degli utensili disponibili + if IsToolOk( Tool) then + table.insert( TOOLS, Tool) + -- altrimenti scrivo nel log che l'utensile non è conforme + else + EgtOutLog( '*** ' .. Tool.sName .. ' : NOT-COMPLIANT ***', 1) + end + + -- reset dati + Tool = {} + end + + -- recupero utensile successivo ( punte a forare, lame, frese e motoseghe) + Tool.sName = EgtTdbGetNextTool( MCH_TF.DRILLBIT + MCH_TF.SAWBLADE + MCH_TF.MILL + MCH_TF.MORTISE) + end +end + + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle travi *** +------------------------------------------------------------------------------------------------------------- + +local function GetStrategiesFromGlobalList( Proc) + -- cerco tra le feature + for i = 1, #STRATEGIES.Features do + -- se trovo la feature + if Proc.nPrc == STRATEGIES.Features[i].nPrc and Proc.nGrp == STRATEGIES.Features[i].nGrp then + -- cerco tra le topologie + for j = 1, #STRATEGIES.Features[i].Topologies do + -- se trovo la topologia + if Proc.Topology.sName == STRATEGIES.Features[i].Topologies[j].sName then + -- ritorno le strategie disponibili per la feature che sto analizzando + return STRATEGIES.Features[i].Topologies[j].Strategies + end + end + end + end + return nil +end + +------------------------------------------------------------------------------------------------------------- +local function GetStrategies( Proc) + local AvailableStrategiesForProc = nil + -- se la lista STRATEGIES è stata letta da JSON (quindi non è vuota), ritorno le strategie possibili + if STRATEGIES and #STRATEGIES.Features > 0 then + AvailableStrategiesForProc = GetStrategiesFromGlobalList( Proc) + end + -- se non ho trovato strategie disponibili nel JSON, o se JSON non presente, lancio script che setta le strategie in modo statico, come definito con cliente + if not AvailableStrategiesForProc then + AvailableStrategiesForProc = BCS.GetStrategiesFromBasicCustomerStrategies( Proc) + end + return AvailableStrategiesForProc +end + +------------------------------------------------------------------------------------------------------------- +local function GetFeatureForcedStrategy( Proc) + -- cerco nelle note se è stata forzata una strategia specifica + local sStrategyId = EgtGetInfo( Proc.id, 'STRATEGY', 's') + + -- se è presente la strategia forzata + if sStrategyId then + -- eseguo file config con i parametri di default + local StrategyData = require( sStrategyId .. '\\' .. sStrategyId .. 'Config') + + -- se ID strategia non esiste oppure ID letto in NGE è differente da quello letto nella strategia, esco subito + if not StrategyData or StrategyData.sStrategyId ~= sStrategyId then + return nil + end + + -- salvo che questa strategia è stata forzata, e che quindi ho già letto il file config con i parametri di default + -- quando si calcolerà la lavorazione non servirà leggere/riverificare i parametri di default + StrategyData.bForcedStrategy = true + + -- cerco e aggiorno i parametri come sono settati nel processing + for i = 1, #StrategyData.Parameters do + local sParameterToRead = StrategyData.sStrategyId .. '_' .. StrategyData.Parameters[i].sName + ForcedParameterForProc = EgtGetInfo( Proc.id, sParameterToRead, 's') + -- se ho trovato il valore, lo sovrascrivo al default + if ForcedParameterForProc then + StrategyData.Parameters[i].sValue = ForcedParameterForProc + end + end + + -- ritorno la lista strategia con parametri + local StrategyToProc = {} + table.insert( StrategyToProc, StrategyData) + return StrategyToProc + end + return nil +end + +------------------------------------------------------------------------------------------------------------- +local function CollectFeatures( Part) + -- recupero le feature + local vProc = {} + local LayerId = {} + LayerId[1] = BeamLib.GetAddGroup( Part.id) + LayerId[2] = EgtGetFirstNameInGroup( Part.id or GDB_ID.NULL, 'Processings') + for nInd = 1, 2 do + local ProcId = EgtGetFirstInGroup( LayerId[nInd] or GDB_ID.NULL) + while ProcId do + local nEntType = EgtGetType( ProcId) + if nEntType == GDB_TY.SRF_MESH or nEntType == GDB_TY.EXT_TEXT or + nEntType == GDB_TY.CRV_LINE or nEntType == GDB_TY.CRV_ARC or nEntType == GDB_TY.CRV_BEZ or nEntType == GDB_TY.CRV_COMPO then + local nGrp = EgtGetInfo( ProcId, 'GRP', 'i') + local nPrc = EgtGetInfo( ProcId, 'PRC', 'i') + local nDo = EgtGetInfo( ProcId, 'DO', 'i') or 1 + if nGrp and nPrc and nDo == 1 then + local Proc = {} + Proc.idPart = Part.id + Proc.id = ProcId + -- id della feature btl ( se non presente info, si prende id dell'entità geometrica) + Proc.idFeature = EgtGetInfo( Proc.id, 'PRID', 's') or Proc.id + Proc.nGrp = nGrp + Proc.nPrc = nPrc + Proc.nFlg = 1 + Proc.nFct = EgtSurfTmFacetCount( ProcId) or 0 + Proc.idCut = EgtGetInfo( EgtGetParent( EgtGetParent( ProcId)), 'CUTID', 'i') or 0 + Proc.idTask = EgtGetInfo( ProcId, 'TASKID', 'i') or 0 + Proc.b3Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD) + EgtOutLog( '------Feature ' .. Proc.idFeature .. '------') + -- se esiste la geometria + if Proc.b3Box and not Proc.b3Box:isEmpty() then + -- TODO fare una funzione per recuperare i dati delle feature che non passano dal calcolo della topologia? + -- se foro calcolo altri dati + if ID.IsDrilling( Proc) then + -- assegno diametro e facce di ingresso e uscita (dati tabelle sempre per riferimento) + Proc.dDiam, Proc.dLen, Proc.nFcs, Proc.nFce = FeatureData.GetDrillingData( Proc) + end + -- informazioni facce e topologia + Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) + -- calcolo topologia solo se necessario, altrimenti si sfruttano le informazioni della feature BTL + Proc.Topology = {} + if FeatureData.NeedTopologyFeature( Proc) then + Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc) + Proc.Faces = FaceData.GetFacesInfo( Proc, Part) + Proc.Topology = FeatureData.ClassifyTopology( Proc, Part) + else + Proc.Topology.sFamily = 'FEATURE' + Proc.Topology.sName = 'FEATURE' + end + -- se topologia feature riconosciuta, oppure da non calcolare perchè il riconoscimento topologico è basato sulla feature stessa + if Proc.Topology.sName ~= 'NOT_IMPLEMENTED' then + Proc.MainFaces = FaceData.GetMainFaces( Proc, Part) + -- se la processing ha una strategia forzata, riporto tutto nella proc + local vForcedStrategy = GetFeatureForcedStrategy( Proc) + if vForcedStrategy then + Proc.AvailableStrategies = vForcedStrategy + -- altrimenti cerco tra le strategie disponibili + else + Proc.AvailableStrategies = GetStrategies( Proc) + end + -- se ci sono strategie disponibili, aggiungo a lista delle feature da lavorare + if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then + table.insert( vProc, Proc) + -- altrimenti errore (non ci sono strategie per lavorare la topologia riconosciuta) + else + EgtOutLog( ' Feature ' .. tostring( Proc.idFeature) .. ' : NO available strategies') + end + -- altrimenti errore (serviva riconoscimento topologico, ma non è stato possibile farlo) + else + EgtOutLog( ' Feature ' .. tostring( Proc.idFeature) .. ' : NO available strategies') + end + else + Proc.nFlg = 0 + table.insert( vProc, Proc) + EgtOutLog( ' Feature ' .. tostring( Proc.idFeature) .. ' is empty (no geometry)') + end + end + end + ProcId = EgtGetNext( ProcId) + end + end + return vProc +end + +------------------------------------------------------------------------------------------------------------- +local function GetFeatureInfoAndDependency( vProcSingleRot, Part) + -- ciclo tutte le feature + for i = 1, #vProcSingleRot do + local Proc = vProcSingleRot[i] + -- controllo la feature con tutte le altre per recuperare le dipendenze + for j = 1, #vProcSingleRot do + -- non si controlla la feature con se stessa + if i ~= j then + local ProcB = vProcSingleRot[j] + -- verifico se feature tipo LapJoint è attraversata da almeno un foro + if ( Proc.Topology.sFamily == 'Pocket' or Proc.Topology.sFamily == 'Tunnel' or Proc.Topology.sFamily == 'Groove' or ID.IsMortise( Proc)) and + ID.IsDrilling( ProcB) and Overlaps( Proc.b3Box, ProcB.b3Box) then + Proc.bPassedByHole = true + end + -- verifiche per specchiature + if BeamData.DOWN_HEAD or BeamData.TWO_EQUAL_HEADS then + -- forature + if BeamData.DOUBLE_HEAD_DRILLING and ID.IsDrilling( Proc) and ID.IsDrilling( ProcB) and not Proc.Mirror then + if AreDrillingsMirrored( Proc, ProcB, Part) then + Proc.Mirror = ProcB + end + end + end + end + end + end + return vProcSingleRot +end + +------------------------------------------------------------------------------------------------------------- +local function RunStrategyLibraries( sStrategyId) + local StrategyConfigName = sStrategyId .. '\\' .. sStrategyId .. 'Config' + local StrategyConfigPath = BEAM.BASEDIR .. '\\Strategies\\' .. StrategyConfigName .. '.lua' + local StrategyScriptName = sStrategyId .. '\\' .. sStrategyId + local StrategyScriptPath = BEAM.BASEDIR .. '\\Strategies\\' .. StrategyScriptName .. '.lua' + local StrategyLib = {} + if EgtExistsFile( StrategyConfigPath) and EgtExistsFile( StrategyScriptPath) then + StrategyLib.Config = require( StrategyConfigName) + -- eseguo file script strategia + StrategyLib.Script = require( StrategyScriptName) + return StrategyLib + else + return {} + end +end + +------------------------------------------------------------------------------------------------------------- +-- ritorna l'indice della strategia migliore, tra le due passate +local function GetIndexBestStrategyFromComparison( AvailableStrategies, nIndex1, nIndex2) + local dChosenIndex = 0 + -- controllo indici + if nIndex1 == 0 and nIndex2 == 0 then + dChosenIndex = 0 + elseif nIndex1 == 0 then + -- basta che sia applicabile + if AvailableStrategies[nIndex2].Result and ( AvailableStrategies[nIndex2].Result.sStatus == 'Completed' or AvailableStrategies[nIndex2].Result.sStatus == 'Not-Completed') then + dChosenIndex = nIndex2 + end + elseif nIndex2 == 0 then + -- basta che sia applicabile + if AvailableStrategies[nIndex1].Result and ( AvailableStrategies[nIndex1].Result.sStatus == 'Completed' or AvailableStrategies[nIndex1].Result.sStatus == 'Not-Completed') then + dChosenIndex = nIndex1 + end + elseif not AvailableStrategies[nIndex1].Result or not AvailableStrategies[nIndex2].Result then + dChosenIndex = 0 + elseif ( AvailableStrategies[nIndex1].Result.sStatus == 'Completed' and AvailableStrategies[nIndex2].Result.sStatus ~= 'Completed') or + ( AvailableStrategies[nIndex1].Result.sStatus == 'Not-Completed' and AvailableStrategies[nIndex2].Result.sStatus == 'Not-Applicable') then + dChosenIndex = nIndex1 + elseif ( AvailableStrategies[nIndex2].Result.sStatus == 'Completed' and AvailableStrategies[nIndex1].Result.sStatus ~= 'Completed') or + ( AvailableStrategies[nIndex2].Result.sStatus == 'Not-Completed' and AvailableStrategies[nIndex1].Result.sStatus == 'Not-Applicable') then + dChosenIndex = nIndex2 + else + -- se le due strategie hanno stesso stato e sono entrambe applicabili (quindi entrambe complete o entrambe non-complete) + if AvailableStrategies[nIndex1].Result.sStatus ~= 'Not-Applicable' and AvailableStrategies[nIndex2].Result.sStatus ~= 'Not-Applicable' and + AvailableStrategies[nIndex1].Result.sStatus == AvailableStrategies[nIndex2].Result.sStatus then + local dCompositeRatingStrategy1 = AvailableStrategies[nIndex1].Result.nQuality * AvailableStrategies[nIndex1].Result.nCompletionIndex * AvailableStrategies[nIndex1].Result.dMRR + local dCompositeRatingStrategy2 = AvailableStrategies[nIndex2].Result.nQuality * AvailableStrategies[nIndex2].Result.nCompletionIndex * AvailableStrategies[nIndex2].Result.dMRR + -- si predilige strategia con rating composito più alto + if dCompositeRatingStrategy1 > dCompositeRatingStrategy2 then + dChosenIndex = nIndex1 + elseif dCompositeRatingStrategy2 > dCompositeRatingStrategy1 then + dChosenIndex = nIndex2 + -- altrimenti si prende la strategia con indice più basso + else + dChosenIndex = EgtIf( nIndex1 < nIndex2, nIndex1, nIndex2) + end + end + end + return dChosenIndex +end + +------------------------------------------------------------------------------------------------------------- +-- funzione che processa tutte le feature sul pezzo e trova la miglior strategia di lavorazione tra quelle disponibili +local function GetBestStrategy( vProcSingleRot, Part) + -- per ogni feature + for i = 1, #vProcSingleRot do + -- processo tutte le feature attive + local Proc = vProcSingleRot[i] + if Proc.nFlg ~= 0 then + -- controllo se ci sono strategie disponibili + if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then + local nIndexBestStrategy = 0 + -- ciclo tutte le strategie della feature + for nIndexCurrentStrategy = 1, #Proc.AvailableStrategies do + -- eseguo file config con i parametri di default + local CurrentStrategy = {} + CurrentStrategy = RunStrategyLibraries( Proc.AvailableStrategies[nIndexCurrentStrategy].sStrategyId) + -- controllo che le librerie siano state effettivamente caricate + if CurrentStrategy.Config and CurrentStrategy.Script then + local bStrategyOk + -- eseguo la strategia solo come calcolo fattibilità e voto. Non si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati + _, Proc.AvailableStrategies[nIndexCurrentStrategy].Result = CurrentStrategy.Script.Make( false, Proc, Part, Proc.AvailableStrategies[nIndexCurrentStrategy].Parameters) + -- scelgo la migliore strategia tra le due + nIndexBestStrategy = GetIndexBestStrategyFromComparison( Proc.AvailableStrategies, nIndexCurrentStrategy, nIndexBestStrategy) + + -- se scelta strategia standard, esco subito alla prima che trovo completa + -- TODO serve paraemtro da Beam&Wall ( oppure da confirgurazione) !!!!!!!! + if BEAM.GetFirstCompletedStrategy and nIndexBestStrategy > 0 then + if Proc.AvailableStrategies[nIndexBestStrategy].Result.sStatus == 'Complete' then + break + end + end + + -- se non trovo i file della strategia, scrivo che non è più disponibile + else + Proc.AvailableStrategies[nIndexCurrentStrategy].Result = {} + Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sInfo = 'Strategy not found' + end + end + -- salvo sulla proc la migliore strategia + if nIndexBestStrategy ~= 0 then + Proc.ChosenStrategy = Proc.AvailableStrategies[nIndexBestStrategy] + end + end + end + end + return vProcSingleRot +end + +------------------------------------------------------------------------------------------------------------- +-- Ordina le feature in base a fase di lavorazione +-- 1) Head : ( intestatura) +-- 2) Standard : ( lavorazioni standard che non impattano sulal coda) +-- 3) AdvanceTail : ( lavorazioni che richiedono taglio di separazione, ma che devono essere fatte prima perchè il taglio di separazione farebbe cadere il pezzo) +-- 4) Split : ( taglio di separazione) +-- 5) Tail : ( lavorazioni di coda, fatte dopo il taglio di separazione) +local function OrderFeatures( vProc) + local vProcToSort = vProc + -- funzione di confronto. TRUE = B1 prima di B2. FALSE = B2 prima di B1 + local function CompareFeatures( B1, B2) + -- se secondo disabilitato, va lasciato dopo + if B1.nFlg ~= 0 and B2.nFlg == 0 then + return true + -- se entrambi disabilitati seguo l'Id + elseif B1.nFlg == 0 and B2.nFlg == 0 then + return ( B1.id < B2.id) + -- se in rotazioni diverse, si mette in ordine di rotazioni + elseif B1.nRot ~= B2.nRot then + return ( B1.nRot < B2.nRot) + -- se primo è taglio di testa, va prima degli altri casi + elseif B1.Head and ( B2.Standard or B2.AdvanceTail or B2.Split or B2.Tail) then + return true + -- se primo è taglio standard, va prima degli altri casi + elseif B1.Standard and ( B2.AdvanceTail or B2.Split or B2.Tail) then + return true + -- se primo è taglio di testa anticipata, va prima degli altri casi + elseif B1.AdvanceTail and ( B2.Split or B2.Tail) then + return true + -- se primo è taglio di separazione, va prima delle lavorazioni di coda + elseif B1.Split and B2.Tail then + return true + -- se da lavorare in stessa fase pezzo + elseif B1.Head == B2.Head or B1.Standard == B2.Standard or B1.AdvanceTail == B2.AdvanceTail or B1.Split == B2.Split or B1.Tail == B2.Tail then + -- confronto standard + if abs( B1.b3Box:getCenter():getX() - B2.b3Box:getCenter():getX()) > 0.4 * ( B1.b3Box:getDimX() + B2.b3Box:getDimX()) then + return B1.b3Box:getCenter():getX() > B2.b3Box:getCenter():getX() + elseif abs( B1.b3Box:getCenter():getY() - B2.b3Box:getCenter():getY()) > 0.2 * ( B1.b3Box:getDimY() + B2.b3Box:getDimY()) then + return B1.b3Box:getCenter():getY() > B2.b3Box:getCenter():getY() + elseif abs( B1.b3Box:getCenter():getZ() - B2.b3Box:getCenter():getZ()) > 0.1 * ( B1.b3Box:getDimZ() + B2.b3Box:getDimZ()) then + return B1.b3Box:getCenter():getZ() > B2.b3Box:getCenter():getZ() + end + -- altrimenti si inverte + else + return false + end + end + + -- test della funzione di ordinamento + if EgtGetDebugLevel() >= 3 then + EgtOutLog( ' CompareFeatures Test ') + local bCompTest = true + for i = 1, #vProcToSort do + for j = i + 1, #vProcToSort do + local bComp1 = CompareFeatures( vProcToSort[i], vProcToSort[j]) + local bComp2 = CompareFeatures( vProcToSort[j], vProcToSort[i]) + if bComp1 == bComp2 then + bCompTest = false + EgtOutLog( string.format( ' ProcId : %d vs %d --> ERROR', vProcToSort[i].id, vProcToSort[j].id)) + end + end + end + if bCompTest then + EgtOutLog( ' ALL OK') + end + end + + -- eseguo ordinamento + table.sort( vProcToSort, CompareFeatures) + + return vProcToSort +end + +------------------------------------------------------------------------------------------------------------- +-- esegue le strategie migliori che ha precedentemente scelto +local function CalculateMachinings( vProc, Part) + local bAreAllApplyOk = true + MACHININGS = {} + -- applico le strategie scelte + for i = 1, #vProc do + -- processo tutte le feature attive applicando le lavorazioni + local Proc = vProc[i] + if Proc.nFlg ~= 0 and Proc.ChosenStrategy then + -- carico file script strategia (non serve verificare presenza del file perchè già fatto durante scelta strategia) + 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 + bAreAllApplyOk, _ = StrategyScript.Make( true, Proc, Part, Proc.ChosenStrategy.Parameters) + end + end + return vProc +end + +------------------------------------------------------------------------------------------------------------- +local function PrintFeatures( vProc, Part) + EgtOutLog( ' RawBox=' .. tostring( Part.RawBox)) + for i = 1, #vProc do + local Proc = vProc[i] + local sOut = string.format( ' Id=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Down=%s Side=%s Head=%s Tail=%s Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s TopoName=%s', + Proc.id, Proc.nGrp, Proc.nPrc, Proc.idTask, Proc.idCut, + Proc.nFlg, EgtIf( Proc.bDown, 'T', 'F'), EgtIf( Proc.bSide, 'T', 'F'), + EgtIf( Proc.bHead, 'T', 'F'), EgtIf( Proc.bTail, 'T', EgtIf( Proc.bAdvTail, 'A', 'F')), + Proc.nFcs, Proc.nFce, Proc.dDiam, Proc.nFct, tostring( Proc.b3Box), Proc.Topology.sName or '') + -- info speciali per Block Haus Half Lap + if Proc.nPrc == 37 then + local sSpec = string.format( ' N=%s Hd=%s', tostring( Proc.vtN or V_NULL()), EgtIf( Proc.bHeadDir, 'T', 'F')) + sOut = sOut .. sSpec + end + EgtOutLog( sOut) + end +end + +------------------------------------------------------------------------------------------------------------- +function WinExec.ProcessFeatures( PARTS) + -- ciclo sui pezzi + local nTotErr = 0 + local Stats = {} + local nOrd = 1 + local Part = {} + + for nPart = 1, #PARTS do + if not PARTS[nPart].id and PARTS[nPart].b3Raw:getDimX() < BeamData.dMinRaw then break end + + -- per ogni rotazione, calcolo come lavorare le feature per decidere posizionamento iniziale e in che rotazione verranno lavorate le singole feature + local vProcRot = {} + -- lista contenente le feature da eseguire + local vProc = {} + + +-- TODO da rimuovere o lasciare solo per debug +if EgtGetDebugLevel() >= 3 then + EgtStartCounter() +end + + + -- TODO Il numero di rotazioni da calcolare deve dipendere dalle impostazionei del cliente. Per adesso si calcolano tutte e 4, ma può essere ottimizzato + for dRotIndex = 1, 4 do + + -- recupero le feature di lavorazione della trave + table.insert( vProcRot, CollectFeatures( PARTS[nPart])) + + -- recupero informazioni ausiliarie feature e dipendenze tra feature stesse + -- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no + vProcRot[dRotIndex] = GetFeatureInfoAndDependency( vProcRot[dRotIndex], PARTS[nPart]) + + -- sceglie la strategia migliore tra quelle disponibili ( presenti nella tabella vProcRot[dRotIndex].AvailableStrategies) + vProcRot[dRotIndex] = GetBestStrategy( vProcRot[dRotIndex], PARTS[nPart]) + + -- ruoto il grezzo per calcolare la fattibilità delle lavorazioni nella prossima rotazione + -- vettore movimento grezzi per rotazione di 90deg ogni step + local dDeltaYZ = PARTS[nPart].b3Raw:getDimY() - PARTS[nPart].b3Raw:getDimZ() + local vtMove = Vector3d( 0, dDeltaYZ / 2 * EgtIf( BeamData.RIGHT_LOAD, -1, 1), dDeltaYZ / 2) + local bPreMove = ( dDeltaYZ < 0) + -- ruoto le travi della fase corrente + if bPreMove then + EgtMoveRawPart( PARTS[nPart].idRaw, vtMove) + end + EgtRotateRawPart( PARTS[nPart].idRaw, X_AX(), EgtIf( BeamData.RIGHT_LOAD, -90, 90)) + if not bPreMove then + EgtMoveRawPart( PARTS[nPart].idRaw, vtMove) + end + -- aggiorno info pezzo + PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw) + PARTS[nPart].b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + end + + +-- TODO da rimuovere o lasciare solo per debug +if EgtGetDebugLevel() >= 3 then + local timeCollect = EgtStopCounter() + timeCollect = timeCollect + 0 + EgtOutBox( timeCollect, 'Collect calculation time') + EgtStartCounter() +end + + + -- TODO decidere come lavorare ogni feature in base alla matrice delle rotazioni + -- la matrice delle rotazioni deve già salvare sulla proc la strategia da utilizzare + -- Conviene salvarsi tutti i dati fino alla lavorazione e il ciclo di applicazione va ad applicare senza calcolare? + + -- aggiungo la fase, se non è la prima + if nOrd == 1 then + EgtSetCurrPhase( 1) + else + BeamLib.AddPhaseWithRawParts( PARTS[nPart], BeamData.ptOriXR, BeamData.dPosXR, 0) + end + local nPhase = EgtGetCurrPhase() + local nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', EgtIf( PARTS[nPart].id, 'START', 'REST')) + EgtSetInfo( nDispId, 'ORD', nOrd) + EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( PARTS[nPart].idRaw) .. ' Part=' .. tostring( PARTS[nPart].id) .. ' ***', 1) + + -- debug + if EgtGetDebugLevel() >= 1 then + PrintFeatures( vProc, PARTS[nPart]) + end + EgtOutLog( ' *** AddMachinings ***', 1) + + -- TODO PROVVISORIO in attesa di scelta lavorazione in fase opportuna + vProc = vProcRot[1] + + -- ordino le features + vProc = OrderFeatures( vProc) + + -- TODO da fare + MACHININGS = {} + -- esegue le strategie migliori che ha precedentemente scelto e salva le lavorazioni nella lista globale + CalculateMachinings( vProc, PARTS[nPart]) + + -- TODO riordinare lavorazioni ottimizzando cambio utensile/spezzone ecc..., mantenendo dipendenze definite prima + -- ordino le lavorazioni + -- OrderMachining( vProc, PARTS[nPart]) + + -- aggiunge effettivamente le lavorazioni + MachiningLib.AddOperations( vProc, PARTS[nPart]) + + +-- TODO da rimuovere o lasciare solo per debug +if EgtGetDebugLevel() >= 3 then + local timeMachining = EgtStopCounter() + timeMachining = timeMachining + 0 + EgtOutBox( timeMachining, 'Machining calculation time') +end + + + EgtOutLog( ' *** End AddMachinings ***', 1) + -- passo al grezzo successivo + nOrd = nOrd + 1 + end + + -- Aggiornamento finale di tutto + EgtSetCurrPhase( 1) + local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings() + -- eventuale ricalcolo per macchine tipo PF (ma tengo warning del primo calcolo) + if EgtExistsInfo( EgtGetCurrMachGroup(), 'RECALC') then + EgtOutLog( ' **** RECALC ****') + bApplOk, sApplErrors, _ = EgtApplyAllMachinings() + EgtRemoveInfo( EgtGetCurrMachGroup(), 'RECALC') + end + if not bApplOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {nErr = 1, sMsg=sApplErrors, nRot=0, idCut=0, idTask=0}) + elseif sApplWarns and #sApplWarns > 0 then + local vLine = EgtSplitString( sApplWarns, '\r\n') + for i = 1, #vLine do + local nPos = vLine[i]:find( '(WRN', 1, true) + if nPos then + local sData = vLine[i]:sub( nPos + 1, -2) + local vVal = EgtSplitString( sData, ',') + local nWarn = EgtGetVal( vVal[1] or '', 'WRN', 'i') + local nCutId = EgtGetVal( vVal[2] or '', 'CUTID', 'i') + if nWarn and nCutId then + table.insert( Stats, { nErr=-nWarn, sMsg=vLine[i], nRot=0, idCut=nCutId, idTask=0}) + end + end + end + end + + return ( nTotErr == 0), Stats +end + +------------------------------------------------------------------------------------------------------------- +return WinExec diff --git a/CAMAuto/ProcessWin.lua b/CAMAuto/ProcessWin.lua index 365b7af..af90998 100644 --- a/CAMAuto/ProcessWin.lua +++ b/CAMAuto/ProcessWin.lua @@ -60,6 +60,31 @@ local WinExec = require( 'WinExec') -- Variabili globali PARTS = {} +-- Colore del grezzo +local ColA = Color3d( 255, 165, 0, 30) + +--------------------------------------------------------------------- +-- Crea il grezzo che verrà messo in macchina +--------------------------------------------------------------------- +local function AlignPieces( PARTS) + for i = 1, #PARTS do + -- TODO allinea X a globale, ma bisognerebbe tenere in considerazione l'orientamento pezzi che vuole la macchina + local dRotX, dRotY, dRotZ = GetFixedAxesRotABCFromFrame( PARTS[i].idFrame) + + local ptOrigFrame = getOrigin( PARTS[i].idFrame) + + if dRotX ~= 0 then + EgtRotate( PARTS[i].id, ptOrigFrame, X_AX(), dRotX) + end + if dRotY ~= 0 then + EgtRotate( PARTS[i].id, ptOrigFrame, Y_AX(), dRotY) + end + if dRotZ ~= 0 then + EgtRotate( PARTS[i].id, ptOrigFrame, Z_AX(), dRotZ) + end + end +end + ------------------------------------------------------------------------------------------------------------- -- *** Recupero i pezzi da processare *** ------------------------------------------------------------------------------------------------------------- @@ -86,8 +111,17 @@ local function MyProcessInputData() EgtOutBox( 'Non sono state selezionati pezzi', 'Lavora Pezzi', 'ERROR') return false else + -- allineo i pezzi per come se li aspetta la macchina + AlignPieces() + -- recupero tutte le dimensioni necessarie local sOut = '' for i = 1, #PARTS do + PARTS[i].idSolid = EgtGetFirstNameInGroup( PARTS[i].id, 'Solid') + PARTS[i].idFrame = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Geo'), 'Frame') + PARTS[i].b3Solid = EgtGetBBoxGlob( PARTS[i].idSolid or GDB_ID.NULL, GDB_BB.STANDARD) + PARTS[i].dLength = PARTS[1].b3Solid:getDimX() + PARTS[i].dWidth = PARTS[1].b3Solid:getDimY() + PARTS[i].dHeight = PARTS[1].b3Solid:getDimZ() sOut = sOut .. PARTS[i].sName .. ', ' end sOut = sOut:sub( 1, -3) @@ -115,10 +149,12 @@ local function GetDispOffsetFromNotes( nPieceIndex) DispOffset.Phase1 = {} DispOffset.Phase2 = {} - DispOffset.Phase1.dOffsetY = EgtGetInfo( PIECES[nPieceIndex].id, 'OFFY_1', 'd') - DispOffset.Phase1.dOffsetZ = EgtGetInfo( PIECES[nPieceIndex].id, 'OFFZ_1', 'd') - DispOffset.Phase2.dOffsetY = EgtGetInfo( PIECES[nPieceIndex].id, 'OFFY_2', 'd') - DispOffset.Phase2.dOffsetZ = EgtGetInfo( PIECES[nPieceIndex].id, 'OFFZ_2', 'd') + DispOffset.Phase1.dOffsetX = 0 -- dovrà essere calcolato in base alle lavorazioni + DispOffset.Phase1.dOffsetY = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFY_1', 'd') + DispOffset.Phase1.dOffsetZ = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFZ_1', 'd') + DispOffset.Phase2.dOffsetX = 0 -- dovrà essere calcolato in base alle lavorazioni + DispOffset.Phase2.dOffsetY = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFY_2', 'd') + DispOffset.Phase2.dOffsetZ = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFZ_2', 'd') -- controllo se tutti gli offset sono settati if DispOffset.Phase1.dOffsetY and DispOffset.Phase1.dOffsetZ and DispOffset.Phase2.dOffsetY and DispOffset.Phase2.dOffsetZ then @@ -131,13 +167,13 @@ end ------------------------------------------------------------------------------------------------------------- local function GetDispOffsetFromInput( nPieceIndex) -- assegno alle stringhe i valori letti, in modo che vengano proposti quelli nel dialogo - local sOffYPh1 = EgtIf( PIECES[nPieceIndex].DispOffset.Phase1.dOffsetY, tostring( PIECES[nPieceIndex].DispOffset.Phase1.dOffsetY), tostring( PIECES[nPieceIndex].dWidth / 2)) - local sOffZPh1 = EgtIf( PIECES[nPieceIndex].DispOffset.Phase1.dOffsetZ, tostring( PIECES[nPieceIndex].DispOffset.Phase1.dOffsetZ), '0') - local sOffYPh2 = EgtIf( PIECES[nPieceIndex].DispOffset.Phase2.dOffsetY, tostring( PIECES[nPieceIndex].DispOffset.Phase2.dOffsetY), tostring( PIECES[nPieceIndex].dWidth / 2)) - local sOffZPh2 = EgtIf( PIECES[nPieceIndex].DispOffset.Phase2.dOffsetZ, tostring( PIECES[nPieceIndex].DispOffset.Phase2.dOffsetZ), '0') + local sOffYPh1 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY, tostring( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY), tostring( PARTS[nPieceIndex].dWidth / 2)) + local sOffZPh1 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetZ, tostring( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetZ), '0') + local sOffYPh2 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY, tostring( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY), tostring( PARTS[nPieceIndex].dWidth / 2)) + local sOffZPh2 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetZ, tostring( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetZ), '0') - local vInp = EgtDialogBox( 'Dati di disposizione pezzo: ' .. PIECES[nPieceIndex].sName, + local vInp = EgtDialogBox( 'Dati di disposizione pezzo: ' .. PARTS[nPieceIndex].sName, {'Sporgenza laterale FASE1', sOffYPh1}, {'Posizione Z FASE1', sOffZPh1}, {'Sporgenza laterale FASE2', sOffYPh2}, {'Posizione Z FASE2', sOffZPh2}) if not vInp or #vInp == 0 then @@ -145,10 +181,10 @@ local function GetDispOffsetFromInput( nPieceIndex) end -- salvo input nei valori che utilizzerò dopo - PIECES[nPieceIndex].DispOffset.Phase1.dOffsetY = tonumber( vInp[1]) - PIECES[nPieceIndex].DispOffset.Phase1.dOffsetZ = tonumber( vInp[2]) - PIECES[nPieceIndex].DispOffset.Phase2.dOffsetY = tonumber( vInp[3]) - PIECES[nPieceIndex].DispOffset.Phase2.dOffsetZ = tonumber( vInp[4]) + PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY = tonumber( vInp[1]) + PARTS[nPieceIndex].DispOffset.Phase1.dOffsetZ = tonumber( vInp[2]) + PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY = tonumber( vInp[3]) + PARTS[nPieceIndex].DispOffset.Phase2.dOffsetZ = tonumber( vInp[4]) return true end @@ -156,23 +192,48 @@ end --------------------------------------------------------------------- -- Crea il grezzo che verrà messo in macchina --------------------------------------------------------------------- -local function CreateRawPart( PIECES) - +local function AddOverMaterialToRaw( PARTS) + for i = 1, #PARTS do + PARTS[i].RawOffset = {} + -- recupero le info + PARTS[i].RawOffset.dOverMatIn = EgtGetInfo( PARTS[i].id, 'OVERMAT_IN', 'd') or 5 + PARTS[i].RawOffset.dOverMatOut = EgtGetInfo( PARTS[i].id, 'OVERMAT_OUT', 'd') or 5 + PARTS[i].RawOffset.dOverMatLeft = EgtGetInfo( PARTS[i].id, 'OVERMAT_LEFT', 'd') or 5 + PARTS[i].RawOffset.dOverMatRight = EgtGetInfo( PARTS[i].id, 'OVERMAT_RIGHT', 'd') or 5 + -- aggiungo sovramateriale + local dLength = PARTS[i].dLength + PARTS[i].RawOffset.dOverMatIn + PARTS[i].RawOffset.dOverMatOut + local dWidth = PARTS[i].dWidth + PARTS[i].RawOffset.dOverMatLeft + PARTS[i].RawOffset.dOverMatRight + local dHeight = PARTS[i].dHeight -- altezza non ha sovramteriale + EgtModifyRawPartSize( PARTS[i].idRaw, dLength, dWidth, dHeight) + end end +--------------------------------------------------------------------- +-- Crea il grezzo che verrà messo in macchina +--------------------------------------------------------------------- +local function CreateRaws( PARTS) + for i = 1, #PARTS do + PARTS[i].idRaw = EgtAddRawPartWithPart( PARTS[i].id, PARTS[i].idSolid, 0, ColA) + end +end + + ------------------------------------------------------------------------------------------------------------- -- *** Inserimento delle travi nel grezzo *** ------------------------------------------------------------------------------------------------------------- local function MyProcessPieces() -- verifico che i pezzi selezionati siano compatibili con la macchina - WinData.VerifyPieces( PIECES) + WinData.VerifyPieces( PARTS) -- si crea il grezzo - CreateRawPart( PIECES) + CreateRaws( PARTS) + + -- aggiunta sovramateriale + AddOverMaterialToRaw( PARTS) -- recupero offset per posizionamento - for i = 1, #PIECES do + for i = 1, #PARTS do local bInsertedAllOffs = GetDispOffsetFromNotes( i) -- se non sono settati nelle note, li chiedo if not bInsertedAllOffs then @@ -185,7 +246,7 @@ local function MyProcessPieces() end -- si dispongono i pezzi sulla tavola - WinData.DisposePiecesOnTable( PIECES) + WinData.DisposePiecesOnTable( PARTS) return true end @@ -194,7 +255,7 @@ end -- *** Inserimento delle lavorazioni *** ------------------------------------------------------------------------------------------------------------- local function MyProcessFeatures() - local bOk, Stats = WinExec.ProcessFeatures( PARTS) + --local bOk = WinExec.ProcessFeatures( PARTS) return true end From 7f9e7621f5f895c0e564865bdca9731dc53c4271 Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Fri, 14 Jun 2024 11:32:16 +0200 Subject: [PATCH 03/10] - migliorato flusso automatismo - aggiunta chiamata alla WinLib --- CAMAuto/LuaLibs/WinLib.lua | 15 ++++ CAMAuto/ProcessWin.lua | 138 ++++++++++++++++++++++--------------- 2 files changed, 97 insertions(+), 56 deletions(-) create mode 100644 CAMAuto/LuaLibs/WinLib.lua diff --git a/CAMAuto/LuaLibs/WinLib.lua b/CAMAuto/LuaLibs/WinLib.lua new file mode 100644 index 0000000..17a21f1 --- /dev/null +++ b/CAMAuto/LuaLibs/WinLib.lua @@ -0,0 +1,15 @@ +-- WinLib.lua by Egalware s.r.l. 2024/06/14 +-- Libreria globale per Serramenti + +-- Tabella per definizione modulo +local WinLib = {} + +-- Include +require( 'EgtBase') +local WinData = require( 'WinData') + +EgtOutLog( ' WinLib started', 1) + + +------------------------------------------------------------------------------------------------------------- +return WinLib \ No newline at end of file diff --git a/CAMAuto/ProcessWin.lua b/CAMAuto/ProcessWin.lua index af90998..8bb8285 100644 --- a/CAMAuto/ProcessWin.lua +++ b/CAMAuto/ProcessWin.lua @@ -37,7 +37,9 @@ EgtAddToPackagePath( sMachDir .. '\\Window\\?.lua') EgtOutLog( '*** Window Process Start ***', 1) -- Carico le librerie +_G.package.loaded.WinData = nil _G.package.loaded.WinExec = nil +_G.package.loaded.WinLib = nil -- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente -- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento. @@ -56,6 +58,10 @@ for i = 1, 99 do end local WinExec = require( 'WinExec') +local WinExec = require( 'WinLib') + +-- Carico i dati globali +local WinData = require( 'WinData') -- Variabili globali PARTS = {} @@ -63,28 +69,6 @@ PARTS = {} -- Colore del grezzo local ColA = Color3d( 255, 165, 0, 30) ---------------------------------------------------------------------- --- Crea il grezzo che verrà messo in macchina ---------------------------------------------------------------------- -local function AlignPieces( PARTS) - for i = 1, #PARTS do - -- TODO allinea X a globale, ma bisognerebbe tenere in considerazione l'orientamento pezzi che vuole la macchina - local dRotX, dRotY, dRotZ = GetFixedAxesRotABCFromFrame( PARTS[i].idFrame) - - local ptOrigFrame = getOrigin( PARTS[i].idFrame) - - if dRotX ~= 0 then - EgtRotate( PARTS[i].id, ptOrigFrame, X_AX(), dRotX) - end - if dRotY ~= 0 then - EgtRotate( PARTS[i].id, ptOrigFrame, Y_AX(), dRotY) - end - if dRotZ ~= 0 then - EgtRotate( PARTS[i].id, ptOrigFrame, Z_AX(), dRotZ) - end - end -end - ------------------------------------------------------------------------------------------------------------- -- *** Recupero i pezzi da processare *** ------------------------------------------------------------------------------------------------------------- @@ -111,17 +95,12 @@ local function MyProcessInputData() EgtOutBox( 'Non sono state selezionati pezzi', 'Lavora Pezzi', 'ERROR') return false else - -- allineo i pezzi per come se li aspetta la macchina - AlignPieces() -- recupero tutte le dimensioni necessarie local sOut = '' for i = 1, #PARTS do - PARTS[i].idSolid = EgtGetFirstNameInGroup( PARTS[i].id, 'Solid') - PARTS[i].idFrame = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Geo'), 'Frame') - PARTS[i].b3Solid = EgtGetBBoxGlob( PARTS[i].idSolid or GDB_ID.NULL, GDB_BB.STANDARD) - PARTS[i].dLength = PARTS[1].b3Solid:getDimX() - PARTS[i].dWidth = PARTS[1].b3Solid:getDimY() - PARTS[i].dHeight = PARTS[1].b3Solid:getDimZ() + PARTS[i].b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Solid') or GDB_ID.NULL, GDB_BB.STANDARD) + PARTS[i].b3FinishedPiece = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Geo') or GDB_ID.NULL, GDB_BB.STANDARD) + PARTS[i].frame = EgtFR( EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Geo'), 'Frame')) sOut = sOut .. PARTS[i].sName .. ', ' end sOut = sOut:sub( 1, -3) @@ -145,19 +124,17 @@ end ------------------------------------------------------------------------------------------------------------- local function GetDispOffsetFromNotes( nPieceIndex) local bAllOffsetsAreOk = false - local DispOffset = {} - DispOffset.Phase1 = {} - DispOffset.Phase2 = {} - DispOffset.Phase1.dOffsetX = 0 -- dovrà essere calcolato in base alle lavorazioni - DispOffset.Phase1.dOffsetY = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFY_1', 'd') - DispOffset.Phase1.dOffsetZ = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFZ_1', 'd') - DispOffset.Phase2.dOffsetX = 0 -- dovrà essere calcolato in base alle lavorazioni - DispOffset.Phase2.dOffsetY = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFY_2', 'd') - DispOffset.Phase2.dOffsetZ = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFZ_2', 'd') + PARTS[nPieceIndex].DispOffset.Phase1.dOffsetX = 0 -- dovrà essere calcolato in base alle lavorazioni + PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFY_1', 'd') + PARTS[nPieceIndex].DispOffset.Phase1.dOffsetZ = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFZ_1', 'd') + PARTS[nPieceIndex].DispOffset.Phase2.dOffsetX = 0 -- dovrà essere calcolato in base alle lavorazioni + PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFY_2', 'd') + PARTS[nPieceIndex].DispOffset.Phase2.dOffsetZ = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFZ_2', 'd') - -- controllo se tutti gli offset sono settati - if DispOffset.Phase1.dOffsetY and DispOffset.Phase1.dOffsetZ and DispOffset.Phase2.dOffsetY and DispOffset.Phase2.dOffsetZ then + -- controllo se tutti gli offset siano settati + if PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY and PARTS[nPieceIndex].DispOffset.Phase1.dOffsetZ and + PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY and PARTS[nPieceIndex].DispOffset.Phase2.dOffsetZ then bAllOffsetsAreOk = true end @@ -167,12 +144,11 @@ end ------------------------------------------------------------------------------------------------------------- local function GetDispOffsetFromInput( nPieceIndex) -- assegno alle stringhe i valori letti, in modo che vengano proposti quelli nel dialogo - local sOffYPh1 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY, tostring( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY), tostring( PARTS[nPieceIndex].dWidth / 2)) + local sOffYPh1 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY, tostring( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY), tostring( PARTS[nPieceIndex].dPartWidth / 2)) local sOffZPh1 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetZ, tostring( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetZ), '0') - local sOffYPh2 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY, tostring( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY), tostring( PARTS[nPieceIndex].dWidth / 2)) + local sOffYPh2 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY, tostring( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY), tostring( PARTS[nPieceIndex].dPartWidth / 2)) local sOffZPh2 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetZ, tostring( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetZ), '0') - local vInp = EgtDialogBox( 'Dati di disposizione pezzo: ' .. PARTS[nPieceIndex].sName, {'Sporgenza laterale FASE1', sOffYPh1}, {'Posizione Z FASE1', sOffZPh1}, {'Sporgenza laterale FASE2', sOffYPh2}, {'Posizione Z FASE2', sOffZPh2}) @@ -194,17 +170,41 @@ end --------------------------------------------------------------------- local function AddOverMaterialToRaw( PARTS) for i = 1, #PARTS do + + -- prima di aggiungere sovramateriale al grezzo, calcolo dimensioni del finito + local b3FinishedPart = EgtGetBBoxGlob( PARTS[i].idRaw or GDB_ID.NULL, GDB_BB.STANDARD) + PARTS[i].b3FinishedPart = b3FinishedPart + PARTS[i].dPartLength = PARTS[i].b3FinishedPart:getDimX() + PARTS[i].dPartWidth = PARTS[i].b3FinishedPart:getDimY() + PARTS[i].dPartHeight = PARTS[i].b3FinishedPart:getDimZ() + + -- recupero e aggiungo offset PARTS[i].RawOffset = {} - -- recupero le info + -- recupero info sovramateriale PARTS[i].RawOffset.dOverMatIn = EgtGetInfo( PARTS[i].id, 'OVERMAT_IN', 'd') or 5 PARTS[i].RawOffset.dOverMatOut = EgtGetInfo( PARTS[i].id, 'OVERMAT_OUT', 'd') or 5 PARTS[i].RawOffset.dOverMatLeft = EgtGetInfo( PARTS[i].id, 'OVERMAT_LEFT', 'd') or 5 PARTS[i].RawOffset.dOverMatRight = EgtGetInfo( PARTS[i].id, 'OVERMAT_RIGHT', 'd') or 5 - -- aggiungo sovramateriale - local dLength = PARTS[i].dLength + PARTS[i].RawOffset.dOverMatIn + PARTS[i].RawOffset.dOverMatOut - local dWidth = PARTS[i].dWidth + PARTS[i].RawOffset.dOverMatLeft + PARTS[i].RawOffset.dOverMatRight - local dHeight = PARTS[i].dHeight -- altezza non ha sovramteriale - EgtModifyRawPartSize( PARTS[i].idRaw, dLength, dWidth, dHeight) + + PARTS[i].dRawLength = PARTS[i].RawOffset.dOverMatLeft + PARTS[i].dPartLength + PARTS[i].RawOffset.dOverMatRight + PARTS[i].dRawWidth = PARTS[i].RawOffset.dOverMatOut + PARTS[i].dPartWidth + PARTS[i].RawOffset.dOverMatIn + PARTS[i].dRawHeight = PARTS[i].dPartHeight + + EgtDraw() --TODO rimuovere + + EgtModifyRawPartSize( PARTS[i].idRaw, PARTS[i].dRawLength, PARTS[i].dRawWidth, PARTS[i].dRawHeight) + EgtDraw() --TODO rimuovere + + local vtMove = Vector3d( PARTS[i].RawOffset.dOverMatLeft, PARTS[i].RawOffset.dOverMatOut, 0) + EgtMovePartInRawPart( PARTS[i].id, vtMove) + + EgtDraw() --TODO rimuovere + + -- TODO da controllare, se ruotato di 180° bisognerebbe prendere dOverMatIn. Lo stesso per la X + PARTS[i].OffsetPartToRaw = {} + PARTS[i].OffsetPartToRaw.X = PARTS[i].RawOffset.dOverMatLeft + PARTS[i].OffsetPartToRaw.Y = PARTS[i].RawOffset.dOverMatOut + end end @@ -213,27 +213,53 @@ end --------------------------------------------------------------------- local function CreateRaws( PARTS) for i = 1, #PARTS do - PARTS[i].idRaw = EgtAddRawPartWithPart( PARTS[i].id, PARTS[i].idSolid, 0, ColA) + -- si crea il grezzo nell'origine del pezzo + PARTS[i].idRaw = EgtAddRawPartWithPart( PARTS[i].id, EgtGetFirstNameInGroup( PARTS[i].id, 'Geo'), 0, ColA) end 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 + local sMachGroupName = EgtGetMachGroupName(nMachGroupId) + local nMachGroupName = tonumber(sMachGroupName) + if nMachGroupName > nMaxMachGroup then + nMaxMachGroup = nMachGroupName + end + nMachGroupId = EgtGetNextMachGroup(nMachGroupId) + end + return nMaxMachGroup + 1 +end ------------------------------------------------------------------------------------------------------------- -- *** Inserimento delle travi nel grezzo *** ------------------------------------------------------------------------------------------------------------- local function MyProcessPieces() - -- verifico che i pezzi selezionati siano compatibili con la macchina - WinData.VerifyPieces( PARTS) + -- creo macchinata + local MachGroupName = NewMachGroupName() + local nMachGroup = EgtAddMachGroup( MachGroupName) -- si crea il grezzo CreateRaws( PARTS) - -- aggiunta sovramateriale + -- allineo i pezzi come orientamento richiesto dalla macchina + WinData.AlignRawsToTable( PARTS) + + -- aggiungo sovramateriale ai grezzi AddOverMaterialToRaw( PARTS) -- recupero offset per posizionamento for i = 1, #PARTS do + PARTS[i].DispOffset = {} + PARTS[i].DispOffset.Phase1 = {} + PARTS[i].DispOffset.Phase2 = {} + local bInsertedAllOffs = GetDispOffsetFromNotes( i) -- se non sono settati nelle note, li chiedo if not bInsertedAllOffs then @@ -246,7 +272,7 @@ local function MyProcessPieces() end -- si dispongono i pezzi sulla tavola - WinData.DisposePiecesOnTable( PARTS) + WinData.Disposition( PARTS) return true end From 51ac46ca73eb41f4f65233d10538cf927f399b36 Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Fri, 14 Jun 2024 15:55:53 +0200 Subject: [PATCH 04/10] - Corretto posizionamento pezzi in tavola --- CAMAuto/ProcessWin.lua | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/CAMAuto/ProcessWin.lua b/CAMAuto/ProcessWin.lua index 8bb8285..4a4eb6c 100644 --- a/CAMAuto/ProcessWin.lua +++ b/CAMAuto/ProcessWin.lua @@ -58,7 +58,7 @@ for i = 1, 99 do end local WinExec = require( 'WinExec') -local WinExec = require( 'WinLib') +local WinLib = require( 'WinLib') -- Carico i dati globali local WinData = require( 'WinData') @@ -115,7 +115,7 @@ end ------------------------------------------------------------------------------------------------------------- local function GetDataConfig() -- recupero utensili dal magazzino - WinExec.GetToolsFromDB() + -- WinExec.GetToolsFromDB() -- TODO da gestire eventuali errori bloccanti return true @@ -172,7 +172,7 @@ local function AddOverMaterialToRaw( PARTS) for i = 1, #PARTS do -- prima di aggiungere sovramateriale al grezzo, calcolo dimensioni del finito - local b3FinishedPart = EgtGetBBoxGlob( PARTS[i].idRaw or GDB_ID.NULL, GDB_BB.STANDARD) + local b3FinishedPart = EgtGetBBoxGlob( PARTS[i].id or GDB_ID.NULL, GDB_BB.STANDARD) PARTS[i].b3FinishedPart = b3FinishedPart PARTS[i].dPartLength = PARTS[i].b3FinishedPart:getDimX() PARTS[i].dPartWidth = PARTS[i].b3FinishedPart:getDimY() @@ -190,21 +190,15 @@ local function AddOverMaterialToRaw( PARTS) PARTS[i].dRawWidth = PARTS[i].RawOffset.dOverMatOut + PARTS[i].dPartWidth + PARTS[i].RawOffset.dOverMatIn PARTS[i].dRawHeight = PARTS[i].dPartHeight - EgtDraw() --TODO rimuovere - - EgtModifyRawPartSize( PARTS[i].idRaw, PARTS[i].dRawLength, PARTS[i].dRawWidth, PARTS[i].dRawHeight) - EgtDraw() --TODO rimuovere + EgtModifyRawPartSize( PARTS[i].idRaw, PARTS[i].dRawLength, PARTS[i].dRawWidth, PARTS[i].dPartHeight) local vtMove = Vector3d( PARTS[i].RawOffset.dOverMatLeft, PARTS[i].RawOffset.dOverMatOut, 0) EgtMovePartInRawPart( PARTS[i].id, vtMove) - EgtDraw() --TODO rimuovere - -- TODO da controllare, se ruotato di 180° bisognerebbe prendere dOverMatIn. Lo stesso per la X PARTS[i].OffsetPartToRaw = {} PARTS[i].OffsetPartToRaw.X = PARTS[i].RawOffset.dOverMatLeft PARTS[i].OffsetPartToRaw.Y = PARTS[i].RawOffset.dOverMatOut - end end @@ -213,8 +207,9 @@ end --------------------------------------------------------------------- local function CreateRaws( PARTS) for i = 1, #PARTS do - -- si crea il grezzo nell'origine del pezzo - PARTS[i].idRaw = EgtAddRawPartWithPart( PARTS[i].id, EgtGetFirstNameInGroup( PARTS[i].id, 'Geo'), 0, ColA) + -- si crea un grezzo "finto" (un cubo da 100mm) nell'origine del pezzo, verrà poi dimensionato uan volta adeguato con i vari sovramateriali + PARTS[i].idRaw = EgtAddRawPart( PARTS[i].frame:getOrigin(), 100, 100, 100, ColA) + EgtAddPartToRawPart( PARTS[i].id, ORIG(), PARTS[i].idRaw) end end From 1c00c1224b5c2f855efa40e7a21228de1ed78985 Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Mon, 17 Jun 2024 17:09:43 +0200 Subject: [PATCH 05/10] =?UTF-8?q?-=20Crazione=20strategie=20di=20lavorazio?= =?UTF-8?q?ne=20(per=20ora=20=C3=A8=20una=20per=20tipo)=20-=20Rimosso=20da?= =?UTF-8?q?=20WinExec=20gestione=20strategie=20derivata=20da=20Beam=20-=20?= =?UTF-8?q?Pulita=20Collect=20da=20parametri=20provenienti=20da=20BTL=20-?= =?UTF-8?q?=20ProcessFeature=20semplitifacta.=20Non=20contempla=20rotazion?= =?UTF-8?q?i/ribaltamenti=20del=20pezzo=20-=20Aggiunta=20libreria=20delle?= =?UTF-8?q?=20lavorazioni=20-=20Aggiunta=20libreria=20identit=C3=A0=20di?= =?UTF-8?q?=20una=20lavorazione=20-=20Aggiunta=20libreria=20recupero=20inf?= =?UTF-8?q?ormazioni=20feature=20-=20AlignRawsToTable=20spostata=20in=20Pr?= =?UTF-8?q?ocessWin=20(prima=20era=20nella=20macchina)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CAMAuto/LuaLibs/FeatureData.lua | 44 +++ CAMAuto/LuaLibs/Identity.lua | 36 +++ CAMAuto/LuaLibs/MachiningLib.lua | 391 +++++++++++++++++++++++++ CAMAuto/LuaLibs/WinExec.lua | 472 ++++--------------------------- CAMAuto/LuaLibs/WinLib.lua | 14 + CAMAuto/ProcessWin.lua | 35 ++- CAMAuto/Strategies/Cutting.lua | 17 ++ CAMAuto/Strategies/Drillin.lua | 17 ++ CAMAuto/Strategies/Milling.lua | 17 ++ CAMAuto/Strategies/Pocketing.lua | 17 ++ CAMAuto/Strategies/Profiling.lua | 38 +++ 11 files changed, 679 insertions(+), 419 deletions(-) create mode 100644 CAMAuto/LuaLibs/FeatureData.lua create mode 100644 CAMAuto/LuaLibs/Identity.lua create mode 100644 CAMAuto/LuaLibs/MachiningLib.lua create mode 100644 CAMAuto/Strategies/Cutting.lua create mode 100644 CAMAuto/Strategies/Drillin.lua create mode 100644 CAMAuto/Strategies/Milling.lua create mode 100644 CAMAuto/Strategies/Pocketing.lua create mode 100644 CAMAuto/Strategies/Profiling.lua diff --git a/CAMAuto/LuaLibs/FeatureData.lua b/CAMAuto/LuaLibs/FeatureData.lua new file mode 100644 index 0000000..7907e0f --- /dev/null +++ b/CAMAuto/LuaLibs/FeatureData.lua @@ -0,0 +1,44 @@ +-- FeatureData.lua by Egalware s.r.l. 2024/06/18 +-- Libreria lettura o calcolo dati e proprietà della feature + +-- Tabella per definizione modulo +local FeatureData = {} + +-- Carico i dati globali +local WinData = require( 'WinData') + +------------------------------------------------------------------------------------------------------------- +-- Recupero dati foro +function FeatureData.GetDrillingData( Proc) + local bOk, ptCentre, vtDir, dRadius = EgtCurveIsACircle( Proc.id) + + Proc.dDiam = dRadius * 2 + Proc.dLen = abs( EgtCurveThickness( Proc.id)) or 0 + Proc.ptCentre = ptCentre + Proc.vtDir = vtDir + + return Proc +end + +------------------------------------------------------------------------------------------------------------- +-- Recupero dati profilatura +function FeatureData.GetProfilingData( Proc) + -- recupero utensili + Proc.nToolsToUse = EgtGetInfo( Proc.id, 'NTOOLS', 'i') or 0 + Proc.Tools = {} + for t = 1, Proc.nToolsToUse do + local Data = {} + Data.sName = EgtGetInfo( Proc.id, 'TOOL_NAME_' .. tostring(t), 's') or 0 + Data.dRadialOvermat = EgtGetInfo( Proc.id, 'OFFR_' .. tostring(t), 'd') or 0 + Data.dLongitudinalOvermat = EgtGetInfo( Proc.id, 'OFFL_' .. tostring(t), 'd') or 0 + Data.sSide = EgtGetInfo( Proc.id, 'N', 's') or 0 + table.insert( Proc.Tools, Data) + end + + Proc.ProfileType = EgtGetInfo( Proc.id, 'ProfileType', 's') or '' + return Proc +end + +------------------------------------------------------------------------------------------------------------- + +return FeatureData \ No newline at end of file diff --git a/CAMAuto/LuaLibs/Identity.lua b/CAMAuto/LuaLibs/Identity.lua new file mode 100644 index 0000000..8955f9c --- /dev/null +++ b/CAMAuto/LuaLibs/Identity.lua @@ -0,0 +1,36 @@ +-- Identity.lua by Egalware s.r.l. 2024/06/18 +-- Libreria Riconoscimento della feature + +-- Tabella per definizione modulo +local Identity = {} + +--------------------------------------------------------------------- +------------------------ STANDARD FEATURES ------------------------ +--------------------------------------------------------------------- +-- Feature : Drilling +function Identity.IsDrilling( Proc) + return Proc.sType == 'Hole' +end +--------------------------------------------------------------------- +-- Feature : Cutting +function Identity.IsCutting( Proc) + return Proc.sType == 'Cut' +end +--------------------------------------------------------------------- +-- Feature : Milling +function Identity.IsMilling( Proc) + return Proc.sType == 'Milling' +end +--------------------------------------------------------------------- +-- Feature : Pocketing +function Identity.IsPocketing( Proc) + return Proc.sType == 'Pocket' +end +--------------------------------------------------------------------- +-- Feature : Profiling +function Identity.IsProfiling( Proc) + return Proc.sType == 'Profiling' +end + +--------------------------------------------------------------------- +return Identity diff --git a/CAMAuto/LuaLibs/MachiningLib.lua b/CAMAuto/LuaLibs/MachiningLib.lua new file mode 100644 index 0000000..f39f4cd --- /dev/null +++ b/CAMAuto/LuaLibs/MachiningLib.lua @@ -0,0 +1,391 @@ +-- MachiningLib.lua by Egalware s.r.l. 2024/06/17 +-- Libreria ricerca lavorazioni per serramenti + +-- Tabella per definizione modulo +local MachiningLib = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali +local BeamData = require( 'BeamData') + +EgtOutLog( ' MachiningLib started', 1) + +--------------------------------------------------------------------- +-- TODO da considerare solo angolo 2D?? +local function GetToolEntryAngle( Proc, vtTool) + local Angle = {} + + local dSinAngle = -10 * GEO.EPS_SMALL + local vtNorm + if Proc.AffectedFaces.bTop then + vtNorm = Z_AX() + dSinAngle = max( dSinAngle, vtTool * vtNorm) + end + if Proc.AffectedFaces.bBottom then + vtNorm = -Z_AX() + dSinAngle = max( dSinAngle, vtTool * vtNorm) + end + if Proc.AffectedFaces.bFront then + vtNorm = -Y_AX() + dSinAngle = max( dSinAngle, vtTool * vtNorm) + end + if Proc.AffectedFaces.bBack then + vtNorm = Y_AX() + dSinAngle = max( dSinAngle, vtTool * vtNorm) + end + if Proc.AffectedFaces.bLeft then + vtNorm = -X_AX() + dSinAngle = max( dSinAngle, vtTool * vtNorm) + end + if Proc.AffectedFaces.bRight then + vtNorm = X_AX() + dSinAngle = max( dSinAngle, vtTool * vtNorm) + end + + local dCosAngle = sqrt( 1 - sqr( dSinAngle)) + local dAngle = acos( dCosAngle) + local dTanAngle + if dAngle ~= 0 and dAngle ~= 90 then + dTanAngle = sqrt( 1 - dCosAngle * dCosAngle) / dCosAngle + end + + Angle.dValue = dAngle + Angle.dSin = dSinAngle + Angle.dCos = dCosAngle + Angle.dTan = dTanAngle + + return Angle + end + + ------------------------------------------------------------------------------------------------------------- +-- funzione per cercare utensile tipo FRESA con certe caratteristiche +function MachiningLib.FindMill( Proc, ToolSearchParameters) + local ToolInfo = {} + + local nBestToolIndex + local dBestToolResidualDepth = 0 + for i = 1, #TOOLS do + -- prima verifico che utensile sia compatibile + local bIsToolCompatible = true + if ToolSearchParameters.sName and ToolSearchParameters.sName ~= TOOLS[i].sName then + bIsToolCompatible = false + elseif ToolSearchParameters.dMaxToolDiameter and TOOLS[i].dDiameter > ToolSearchParameters.dMaxToolDiameter then + bIsToolCompatible = false + elseif ToolSearchParameters.sMillShape and ToolSearchParameters.sMillShape == 'STANDARD' and ( TOOLS[i].dSideAngle ~= 0 or TOOLS[i].bIsPen) then + bIsToolCompatible = false + elseif ToolSearchParameters.sMillShape and ToolSearchParameters.sMillShape == 'DOVETAIL' and not TOOLS[i].bIsDoveTail then + bIsToolCompatible = false + elseif ToolSearchParameters.sMillShape and ToolSearchParameters.sMillShape == 'TSHAPEMILL' and not TOOLS[i].bIsTMill then + bIsToolCompatible = false + elseif ToolSearchParameters.sMillShape and ToolSearchParameters.sMillShape == 'PEN' and not TOOLS[i].bIsPen then + bIsToolCompatible = false + elseif ToolSearchParameters.sType and TOOLS[i].sType ~= ToolSearchParameters.sType then + -- se sto cercando una fresa che non può lavorare di testa, quelle che lavorano di testa sono comunque ammesse + if TOOLS[i].sType == 'MILL_STD' and ToolSearchParameters.sType == 'MILL_NOTIP' then + bIsToolCompatible = true + else + bIsToolCompatible = false + end + end + + -- scelgo il migliore + if bIsToolCompatible then + -- calcolo riduzione del massimo materiale utilizzabile + local ToolEntryAngle = GetToolEntryAngle( Proc, ToolSearchParameters.vtToolDirection) + -- se ToolHolder più grande dell'utensile, il primo oggetto in collisione è il ToolHolder. Altrimenti il motore. + local dDimObjToCheck = EgtIf( TOOLS[i].ToolHolder.dDiameter > TOOLS[i].dDiameter, TOOLS[i].ToolHolder.dDiameter, BeamData.C_SIMM_ENC) + local dCurrentMaxMatReduction = BeamData.COLL_SIC or 5 + + -- TODO implementare le funzioni di Tool Collision Avoidance (vedi wiki e FacesBysaw -> CalcLeadInOutPerpGeom) + -- TODO considerare anche il caso in cui lo stelo sia più grande del diametro utensile + -- TODO nei confronti tra valori gestire tolleranze + -- calcolo riduzione per non toccare con ToolHolder / Motore + if ToolEntryAngle.dValue > 0 and ToolEntryAngle.dValue < 90 then + dCurrentMaxMatReduction = dCurrentMaxMatReduction / ToolEntryAngle.dSin + ( ( dDimObjToCheck - TOOLS[i].dDiameter) / 2) / ToolEntryAngle.dTan + end + -- dCurrMachReduction = negativo -> limitare, positivo -> mm extra disponibili + local dCurrentResidualDepth = ToolSearchParameters.dElevation + dCurrentMaxMatReduction - TOOLS[i].dMaxDepth + + -- se non ancora trovato, oppure se completo e il migliore fino ad ora non è completo: corrente è il migliore + if not nBestToolIndex or ( dBestToolResidualDepth > 0 and dCurrentResidualDepth <= 0) then + nBestToolIndex = i + dBestToolResidualDepth = dCurrentResidualDepth + -- altrimenti scelgo il migliore + else + -- se entrambi completi + if dBestToolResidualDepth <= 0 and dCurrentResidualDepth <= 0 then + -- se il migliore era su aggregato e corrente montanto direttamente, prediligo utensile montato direttamente + if not TOOLS[i].SetupInfo.bToolOnAggregate and TOOLS[i].SetupInfo.bToolOnAggregate then + nBestToolIndex = i + dBestToolResidualDepth = dCurrentResidualDepth + -- se hanno stesso montaggio + elseif TOOLS[i].SetupInfo.bToolOnAggregate == TOOLS[nBestToolIndex].SetupInfo.bToolOnAggregate then + -- scelgo utensile con indice di bontà utensile calcolato come: lunghezza / massimo materiale / diametro + if ( TOOLS[i].dLength / TOOLS[i].dMaxMaterial) / TOOLS[i].dDiameter < ( TOOLS[nBestToolIndex].dLength / TOOLS[nBestToolIndex].dMaxMaterial) / TOOLS[nBestToolIndex].dDiameter then + nBestToolIndex = i + dBestToolResidualDepth = dCurrentResidualDepth + end + end + -- se entrambi incompleti + elseif dBestToolResidualDepth > 0 and dCurrentResidualDepth > 0 then + --scelgo quello che lavora di più + if dCurrentResidualDepth < dBestToolResidualDepth then + nBestToolIndex = i + dBestToolResidualDepth = dCurrentResidualDepth + end + end + end + end + end + + ToolInfo.nToolIndex = nBestToolIndex + ToolInfo.dResidualDepth = dBestToolResidualDepth + + return ToolInfo +end + +------------------------------------------------------------------------------------------------------------- +-- funzione per cercare utensile tipo LAMA con certe caratteristiche +-- TODO da completare +function MachiningLib.FindBlade( Proc, ToolSearchParameters) + local ToolInfo = {} + + -- parametri opzionali + ToolSearchParameters.dElevation = ToolSearchParameters.dElevation or 0 + ToolSearchParameters.bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false + + local nBestToolIndex + for i = 1, #TOOLS do + local bIsToolCompatible = false + + -- TODO per il momento si prende la prima lama. Da completare + if TOOLS[i].sFamily == 'SAWBLADE' then + bIsToolCompatible = true + end + + if bIsToolCompatible then + nBestToolIndex = i + break + end + end + + ToolInfo.nToolIndex = nBestToolIndex + + return ToolInfo +end + +------------------------------------------------------------------------------------------------------------- +-- funzione per cercare utensile tipo PUNTA A FORARE con certe caratteristiche +-- TODO da fare +function MachiningLib.FindDrill() +end + +------------------------------------------------------------------------------------------------------------- +-- salva in lista globale la lavorazione appena calcolata +function MachiningLib.AddNewMachining( ProcToAdd, MachiningToAdd) + -- Controllo parametri obbligatori + if not MachiningToAdd.nType or not MachiningToAdd.nToolIndex or not MachiningToAdd.Geometry or not ProcToAdd.id then + return false + end + + -- Drilling + if MachiningToAdd.nType == MCH_MY.DRILLING then + MachiningToAdd.sTypeName = 'Drill_' + -- Milling + elseif MachiningToAdd.nType == MCH_MY.MILLING then + -- se utensile lama + if TOOLS[MachiningToAdd.nToolIndex].sFamily == 'SAWBLADE' then + MachiningToAdd.sTypeName = 'Cut_' + else + MachiningToAdd.sTypeName = 'Mill_' + end + -- Pocketing + elseif MachiningToAdd.nType == MCH_MY.POCKETING then + MachiningToAdd.sTypeName = 'Pocket_' + -- Mortising + elseif MachiningToAdd.nType == MCH_MY.MORTISING then + MachiningToAdd.sTypeName = 'ChSaw_' + end + -- se nome non definito, assegno alla lavorazioen un nome standard + if not MachiningToAdd.sOperationName then + MachiningToAdd.sOperationName = MachiningToAdd.sTypeName .. ( EgtGetName( ProcToAdd.id) or tostring( ProcToAdd.id)) .. '_' .. tostring( MachiningToAdd.Geometry[1][2]) + end + if not MachiningToAdd.sToolName then + MachiningToAdd.sToolName = TOOLS[MachiningToAdd.nToolIndex].sName + end + local Machining = {} + Machining.Proc = ProcToAdd + Machining.Machining = MachiningToAdd + table.insert( MACHININGS, Machining) + return true +end + +------------------------------------------------------------------------------------------------------------- +-- funzione per aggiungere una nuova lavorazione +function MachiningLib.AddOperations( vProc, Part) + local nErr + local sErr = '' + local bAreAllMachiningApplyOk = true + + for i = 1, #MACHININGS do + -- creazione lavorazione + local nOperationId = EgtCreateMachining( MACHININGS[i].Machining.sOperationName, MACHININGS[i].Machining.nType, MACHININGS[i].Machining.sToolName) + + if nOperationId then + -- impostazione geometria + EgtSetMachiningGeometry( MACHININGS[i].Machining.Geometry) + + -- impostazione parametri lavorazione + if MACHININGS[i].Machining.sDepth then + EgtSetMachiningParam( MCH_MP.DEPTH_STR, MACHININGS[i].Machining.sDepth) + end + if MACHININGS[i].Machining.bInvert then + EgtSetMachiningParam( MCH_MP.INVERT, MACHININGS[i].Machining.bInvert) + end + if MACHININGS[i].Machining.nWorkside then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MACHININGS[i].Machining.nWorkside) + end + if MACHININGS[i].Machining.nFaceuse then + EgtSetMachiningParam( MCH_MP.FACEUSE, MACHININGS[i].Machining.nFaceuse) + end + if MACHININGS[i].Machining.nSCC then + EgtSetMachiningParam( MCH_MP.SCC, MACHININGS[i].Machining.nSCC) + end + if MACHININGS[i].Machining.bToolInvert then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, MACHININGS[i].Machining.bToolInvert) + end + if MACHININGS[i].Machining.sBlockedAxis then + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, MACHININGS[i].Machining.sBlockedAxis) + end + if MACHININGS[i].Machining.sInitialAngles then + EgtSetMachiningParam( MCH_MP.INITANGS, MACHININGS[i].Machining.sInitialAngles) + end + if MACHININGS[i].Machining.nHeadSide then + EgtSetMachiningParam( MCH_MP.HEADSIDE, MACHININGS[i].Machining.nHeadSide) + end + if MACHININGS[i].Machining.nSubType then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MACHININGS[i].Machining.nSubType) + end + if MACHININGS[i].Machining.dOverlap then + EgtSetMachiningParam( MCH_MP.OVERL, MACHININGS[i].Machining.dOverlap) + end + + -- step + if MACHININGS[i].Machining.Steps then + if MACHININGS[i].Machining.Steps.dStepType then + EgtSetMachiningParam( MCH_MP.STEPTYPE, MACHININGS[i].Machining.Steps.dStepType) + end + if MACHININGS[i].Machining.Steps.dStep then + EgtSetMachiningParam( MCH_MP.STEP, MACHININGS[i].Machining.Steps.dStep) + end + if MACHININGS[i].Machining.Steps.dSideStep then + EgtSetMachiningParam( MCH_MP.SIDESTEP, MACHININGS[i].Machining.Steps.dSideStep) + end + end + + if MACHININGS[i].Machining.dStartPos then + EgtSetMachiningParam( MCH_MP.STARTPOS, MACHININGS[i].Machining.dStartPos) + end + if MACHININGS[i].Machining.dReturnPos then + EgtSetMachiningParam( MCH_MP.RETURNPOS, MACHININGS[i].Machining.dReturnPos) + end + + if MACHININGS[i].Machining.dRadialOffset then + EgtSetMachiningParam( MCH_MP.OFFSR, MACHININGS[i].Machining.dRadialOffset) + end + if MACHININGS[i].Machining.dLongitudinalOffset then + EgtSetMachiningParam( MCH_MP.OFFSL, MACHININGS[i].Machining.dLongitudinalOffset) + end + + -- paraemtri attacco + if MACHININGS[i].Machining.LeadIn then + if MACHININGS[i].Machining.LeadIn.nType then + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MACHININGS[i].Machining.LeadIn.nType) + end + if MACHININGS[i].Machining.LeadIn.dStartAddLength then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, MACHININGS[i].Machining.LeadIn.dStartAddLength) + end + if MACHININGS[i].Machining.LeadIn.dTangentDistance then + EgtSetMachiningParam( MCH_MP.LITANG, MACHININGS[i].Machining.LeadIn.dTangentDistance) + end + if MACHININGS[i].Machining.LeadIn.dPerpDistance then + EgtSetMachiningParam( MCH_MP.LIPERP, MACHININGS[i].Machining.LeadIn.dPerpDistance) + end + if MACHININGS[i].Machining.LeadIn.dElevation then + EgtSetMachiningParam( MCH_MP.LIELEV, MACHININGS[i].Machining.LeadIn.dElevation) + end + if MACHININGS[i].Machining.LeadIn.dCompLength then + EgtSetMachiningParam( MCH_MP.LICOMPLEN, MACHININGS[i].Machining.LeadIn.dCompLength) + end + end + -- parametri uscita + if MACHININGS[i].Machining.LeadOut then + if MACHININGS[i].Machining.LeadOut.nType then + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MACHININGS[i].Machining.LeadOut.nType) + end + if MACHININGS[i].Machining.LeadOut.dEndAddLength then + EgtSetMachiningParam( MCH_MP.ENDADDLEN, MACHININGS[i].Machining.LeadOut.dEndAddLength) + end + if MACHININGS[i].Machining.LeadOut.dTangentDistance then + EgtSetMachiningParam( MCH_MP.LOTANG, MACHININGS[i].Machining.LeadOut.dTangentDistance) + end + if MACHININGS[i].Machining.LeadOut.dPerpDistance then + EgtSetMachiningParam( MCH_MP.LOPERP, MACHININGS[i].Machining.LeadOut.dPerpDistance) + end + if MACHININGS[i].Machining.LeadOut.dElevation then + EgtSetMachiningParam( MCH_MP.LOELEV, MACHININGS[i].Machining.LeadOut.dElevation) + end + if MACHININGS[i].Machining.LeadOut.dCompLength then + EgtSetMachiningParam( MCH_MP.LOCOMPLEN, MACHININGS[i].Machining.LeadOut.dCompLength) + end + end + + if MACHININGS[i].Machining.dStartSlowLen then + EgtSetMachiningParam( MCH_MP.STARTSLOWLEN, MACHININGS[i].Machining.dStartSlowLen) + end + if MACHININGS[i].Machining.dEndSlowLen then + EgtSetMachiningParam( MCH_MP.ENDSLOWLEN, MACHININGS[i].Machining.dEndSlowLen) + end + if MACHININGS[i].Machining.dThrouAddLen then + EgtSetMachiningParam( MCH_MP.THROUADDLEN, MACHININGS[i].Machining.dThrouAddLen) + end + + -- parametri da settare nelle note di sistema + -- TODO da decidere quali sono le note da salvare qui. Probabilmente tutte quelle relative all'ordine delle lavorazioni + local sSystemNotes = EgtGetMachiningParam( MCH_MP.SYSNOTES) + --if MACHININGS[i].Machining.nMachiningOrder then + -- sSystemNotes = EgtSetValInNotes( sSystemNotes, 'MachiningOrder', MACHININGS[i].Machining.nMachiningOrder) + --end + EgtSetMachiningParam( MCH_MP.SYSNOTES, sSystemNotes) + + -- parametri da settare nelle note utente + local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + if MACHININGS[i].Machining.dMaxElev then + sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', MACHININGS[i].Machining.dMaxElev) + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + + local bIsApplyOk = MachiningLib.ApplyMachining( true, false) + if not bIsApplyOk then + bAreAllMachiningApplyOk = false + nErr, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nOperationId, false) + end + else + return false, 'UNEXPECTED ERROR: Error on creating machining' + end + + end + return bAreAllMachiningApplyOk, sErr +end + +------------------------------------------------------------------------------------------------------------- +function MachiningLib.ApplyMachining( bRecalc, bApplyPost) + local bResult = EgtApplyMachining( bRecalc, bApplyPost) + return bResult +end + +------------------------------------------------------------------------------------------------------------- +return MachiningLib diff --git a/CAMAuto/LuaLibs/WinExec.lua b/CAMAuto/LuaLibs/WinExec.lua index b975612..c79d716 100644 --- a/CAMAuto/LuaLibs/WinExec.lua +++ b/CAMAuto/LuaLibs/WinExec.lua @@ -9,6 +9,9 @@ require( 'EgtBase') -- Carico i dati globali local WinData = require( 'WinData') +local WinLib = require( 'WinLib') +local ID = require( 'Identity') +local FeatureData = require( 'FeatureData') EgtOutLog( ' WinExec started', 1) EgtMdbSave() @@ -17,7 +20,6 @@ EgtMdbSave() -- *** variabili globali *** ------------------------------------------------------------------------------------------------------------- TOOLS = nil -STRATEGIES = nil MACHININGS = nil ------------------------------------------------------------------------------------------------------------- @@ -183,81 +185,11 @@ end -- *** Inserimento delle lavorazioni nelle travi *** ------------------------------------------------------------------------------------------------------------- -local function GetStrategiesFromGlobalList( Proc) - -- cerco tra le feature - for i = 1, #STRATEGIES.Features do - -- se trovo la feature - if Proc.nPrc == STRATEGIES.Features[i].nPrc and Proc.nGrp == STRATEGIES.Features[i].nGrp then - -- cerco tra le topologie - for j = 1, #STRATEGIES.Features[i].Topologies do - -- se trovo la topologia - if Proc.Topology.sName == STRATEGIES.Features[i].Topologies[j].sName then - -- ritorno le strategie disponibili per la feature che sto analizzando - return STRATEGIES.Features[i].Topologies[j].Strategies - end - end - end - end - return nil -end - -------------------------------------------------------------------------------------------------------------- -local function GetStrategies( Proc) - local AvailableStrategiesForProc = nil - -- se la lista STRATEGIES è stata letta da JSON (quindi non è vuota), ritorno le strategie possibili - if STRATEGIES and #STRATEGIES.Features > 0 then - AvailableStrategiesForProc = GetStrategiesFromGlobalList( Proc) - end - -- se non ho trovato strategie disponibili nel JSON, o se JSON non presente, lancio script che setta le strategie in modo statico, come definito con cliente - if not AvailableStrategiesForProc then - AvailableStrategiesForProc = BCS.GetStrategiesFromBasicCustomerStrategies( Proc) - end - return AvailableStrategiesForProc -end - -------------------------------------------------------------------------------------------------------------- -local function GetFeatureForcedStrategy( Proc) - -- cerco nelle note se è stata forzata una strategia specifica - local sStrategyId = EgtGetInfo( Proc.id, 'STRATEGY', 's') - - -- se è presente la strategia forzata - if sStrategyId then - -- eseguo file config con i parametri di default - local StrategyData = require( sStrategyId .. '\\' .. sStrategyId .. 'Config') - - -- se ID strategia non esiste oppure ID letto in NGE è differente da quello letto nella strategia, esco subito - if not StrategyData or StrategyData.sStrategyId ~= sStrategyId then - return nil - end - - -- salvo che questa strategia è stata forzata, e che quindi ho già letto il file config con i parametri di default - -- quando si calcolerà la lavorazione non servirà leggere/riverificare i parametri di default - StrategyData.bForcedStrategy = true - - -- cerco e aggiorno i parametri come sono settati nel processing - for i = 1, #StrategyData.Parameters do - local sParameterToRead = StrategyData.sStrategyId .. '_' .. StrategyData.Parameters[i].sName - ForcedParameterForProc = EgtGetInfo( Proc.id, sParameterToRead, 's') - -- se ho trovato il valore, lo sovrascrivo al default - if ForcedParameterForProc then - StrategyData.Parameters[i].sValue = ForcedParameterForProc - end - end - - -- ritorno la lista strategia con parametri - local StrategyToProc = {} - table.insert( StrategyToProc, StrategyData) - return StrategyToProc - end - return nil -end - -------------------------------------------------------------------------------------------------------------- local function CollectFeatures( Part) -- recupero le feature local vProc = {} local LayerId = {} - LayerId[1] = BeamLib.GetAddGroup( Part.id) + LayerId[1] = WinLib.GetAddGroup( Part.id) LayerId[2] = EgtGetFirstNameInGroup( Part.id or GDB_ID.NULL, 'Processings') for nInd = 1, 2 do local ProcId = EgtGetFirstInGroup( LayerId[nInd] or GDB_ID.NULL) @@ -265,65 +197,40 @@ local function CollectFeatures( Part) local nEntType = EgtGetType( ProcId) if nEntType == GDB_TY.SRF_MESH or nEntType == GDB_TY.EXT_TEXT or nEntType == GDB_TY.CRV_LINE or nEntType == GDB_TY.CRV_ARC or nEntType == GDB_TY.CRV_BEZ or nEntType == GDB_TY.CRV_COMPO then - local nGrp = EgtGetInfo( ProcId, 'GRP', 'i') - local nPrc = EgtGetInfo( ProcId, 'PRC', 'i') + local sType = EgtGetInfo( ProcId, 'FEATURE_TYPE', 's') local nDo = EgtGetInfo( ProcId, 'DO', 'i') or 1 - if nGrp and nPrc and nDo == 1 then + if sType and nDo == 1 then local Proc = {} Proc.idPart = Part.id Proc.id = ProcId - -- id della feature btl ( se non presente info, si prende id dell'entità geometrica) - Proc.idFeature = EgtGetInfo( Proc.id, 'PRID', 's') or Proc.id - Proc.nGrp = nGrp - Proc.nPrc = nPrc Proc.nFlg = 1 - Proc.nFct = EgtSurfTmFacetCount( ProcId) or 0 - Proc.idCut = EgtGetInfo( EgtGetParent( EgtGetParent( ProcId)), 'CUTID', 'i') or 0 - Proc.idTask = EgtGetInfo( ProcId, 'TASKID', 'i') or 0 + Proc.sType = sType Proc.b3Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD) - EgtOutLog( '------Feature ' .. Proc.idFeature .. '------') + Proc.nPhase = EgtGetInfo( ProcId, 'PHASE', 'i') or nil + -- se esiste la geometria if Proc.b3Box and not Proc.b3Box:isEmpty() then - -- TODO fare una funzione per recuperare i dati delle feature che non passano dal calcolo della topologia? - -- se foro calcolo altri dati + -- calcolo dati specifici per tipologia di feature / lavorazione + -- se foro if ID.IsDrilling( Proc) then - -- assegno diametro e facce di ingresso e uscita (dati tabelle sempre per riferimento) - Proc.dDiam, Proc.dLen, Proc.nFcs, Proc.nFce = FeatureData.GetDrillingData( Proc) + Proc = FeatureData.GetDrillingData( Proc) end - -- informazioni facce e topologia - Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) - -- calcolo topologia solo se necessario, altrimenti si sfruttano le informazioni della feature BTL - Proc.Topology = {} - if FeatureData.NeedTopologyFeature( Proc) then - Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc) - Proc.Faces = FaceData.GetFacesInfo( Proc, Part) - Proc.Topology = FeatureData.ClassifyTopology( Proc, Part) - else - Proc.Topology.sFamily = 'FEATURE' - Proc.Topology.sName = 'FEATURE' + -- se taglio + if ID.IsCutting( Proc) then end - -- se topologia feature riconosciuta, oppure da non calcolare perchè il riconoscimento topologico è basato sulla feature stessa - if Proc.Topology.sName ~= 'NOT_IMPLEMENTED' then - Proc.MainFaces = FaceData.GetMainFaces( Proc, Part) - -- se la processing ha una strategia forzata, riporto tutto nella proc - local vForcedStrategy = GetFeatureForcedStrategy( Proc) - if vForcedStrategy then - Proc.AvailableStrategies = vForcedStrategy - -- altrimenti cerco tra le strategie disponibili - else - Proc.AvailableStrategies = GetStrategies( Proc) - end - -- se ci sono strategie disponibili, aggiungo a lista delle feature da lavorare - if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then - table.insert( vProc, Proc) - -- altrimenti errore (non ci sono strategie per lavorare la topologia riconosciuta) - else - EgtOutLog( ' Feature ' .. tostring( Proc.idFeature) .. ' : NO available strategies') - end - -- altrimenti errore (serviva riconoscimento topologico, ma non è stato possibile farlo) - else - EgtOutLog( ' Feature ' .. tostring( Proc.idFeature) .. ' : NO available strategies') + -- se fresatura + if ID.IsMilling( Proc) then end + -- se svuotatura + if ID.IsPocketing( Proc) then + end + -- se profilatura + if ID.IsProfiling( Proc) then + Proc = FeatureData.GetProfilingData( Proc) + end + + -- inserisco feature in lista + table.insert( vProc, Proc) else Proc.nFlg = 0 table.insert( vProc, Proc) @@ -338,152 +245,30 @@ local function CollectFeatures( Part) end ------------------------------------------------------------------------------------------------------------- -local function GetFeatureInfoAndDependency( vProcSingleRot, Part) +local function GetFeatureInfoAndDependency( vProc, Part) -- ciclo tutte le feature - for i = 1, #vProcSingleRot do - local Proc = vProcSingleRot[i] + for i = 1, #vProc do + local Proc = vProc[i] -- controllo la feature con tutte le altre per recuperare le dipendenze - for j = 1, #vProcSingleRot do + for j = 1, #vProc do -- non si controlla la feature con se stessa if i ~= j then - local ProcB = vProcSingleRot[j] - -- verifico se feature tipo LapJoint è attraversata da almeno un foro - if ( Proc.Topology.sFamily == 'Pocket' or Proc.Topology.sFamily == 'Tunnel' or Proc.Topology.sFamily == 'Groove' or ID.IsMortise( Proc)) and - ID.IsDrilling( ProcB) and Overlaps( Proc.b3Box, ProcB.b3Box) then - Proc.bPassedByHole = true - end - -- verifiche per specchiature - if BeamData.DOWN_HEAD or BeamData.TWO_EQUAL_HEADS then - -- forature - if BeamData.DOUBLE_HEAD_DRILLING and ID.IsDrilling( Proc) and ID.IsDrilling( ProcB) and not Proc.Mirror then - if AreDrillingsMirrored( Proc, ProcB, Part) then - Proc.Mirror = ProcB - end - end - end + local ProcB = vProc[j] end end end - return vProcSingleRot -end - -------------------------------------------------------------------------------------------------------------- -local function RunStrategyLibraries( sStrategyId) - local StrategyConfigName = sStrategyId .. '\\' .. sStrategyId .. 'Config' - local StrategyConfigPath = BEAM.BASEDIR .. '\\Strategies\\' .. StrategyConfigName .. '.lua' - local StrategyScriptName = sStrategyId .. '\\' .. sStrategyId - local StrategyScriptPath = BEAM.BASEDIR .. '\\Strategies\\' .. StrategyScriptName .. '.lua' - local StrategyLib = {} - if EgtExistsFile( StrategyConfigPath) and EgtExistsFile( StrategyScriptPath) then - StrategyLib.Config = require( StrategyConfigName) - -- eseguo file script strategia - StrategyLib.Script = require( StrategyScriptName) - return StrategyLib - else - return {} - end -end - -------------------------------------------------------------------------------------------------------------- --- ritorna l'indice della strategia migliore, tra le due passate -local function GetIndexBestStrategyFromComparison( AvailableStrategies, nIndex1, nIndex2) - local dChosenIndex = 0 - -- controllo indici - if nIndex1 == 0 and nIndex2 == 0 then - dChosenIndex = 0 - elseif nIndex1 == 0 then - -- basta che sia applicabile - if AvailableStrategies[nIndex2].Result and ( AvailableStrategies[nIndex2].Result.sStatus == 'Completed' or AvailableStrategies[nIndex2].Result.sStatus == 'Not-Completed') then - dChosenIndex = nIndex2 - end - elseif nIndex2 == 0 then - -- basta che sia applicabile - if AvailableStrategies[nIndex1].Result and ( AvailableStrategies[nIndex1].Result.sStatus == 'Completed' or AvailableStrategies[nIndex1].Result.sStatus == 'Not-Completed') then - dChosenIndex = nIndex1 - end - elseif not AvailableStrategies[nIndex1].Result or not AvailableStrategies[nIndex2].Result then - dChosenIndex = 0 - elseif ( AvailableStrategies[nIndex1].Result.sStatus == 'Completed' and AvailableStrategies[nIndex2].Result.sStatus ~= 'Completed') or - ( AvailableStrategies[nIndex1].Result.sStatus == 'Not-Completed' and AvailableStrategies[nIndex2].Result.sStatus == 'Not-Applicable') then - dChosenIndex = nIndex1 - elseif ( AvailableStrategies[nIndex2].Result.sStatus == 'Completed' and AvailableStrategies[nIndex1].Result.sStatus ~= 'Completed') or - ( AvailableStrategies[nIndex2].Result.sStatus == 'Not-Completed' and AvailableStrategies[nIndex1].Result.sStatus == 'Not-Applicable') then - dChosenIndex = nIndex2 - else - -- se le due strategie hanno stesso stato e sono entrambe applicabili (quindi entrambe complete o entrambe non-complete) - if AvailableStrategies[nIndex1].Result.sStatus ~= 'Not-Applicable' and AvailableStrategies[nIndex2].Result.sStatus ~= 'Not-Applicable' and - AvailableStrategies[nIndex1].Result.sStatus == AvailableStrategies[nIndex2].Result.sStatus then - local dCompositeRatingStrategy1 = AvailableStrategies[nIndex1].Result.nQuality * AvailableStrategies[nIndex1].Result.nCompletionIndex * AvailableStrategies[nIndex1].Result.dMRR - local dCompositeRatingStrategy2 = AvailableStrategies[nIndex2].Result.nQuality * AvailableStrategies[nIndex2].Result.nCompletionIndex * AvailableStrategies[nIndex2].Result.dMRR - -- si predilige strategia con rating composito più alto - if dCompositeRatingStrategy1 > dCompositeRatingStrategy2 then - dChosenIndex = nIndex1 - elseif dCompositeRatingStrategy2 > dCompositeRatingStrategy1 then - dChosenIndex = nIndex2 - -- altrimenti si prende la strategia con indice più basso - else - dChosenIndex = EgtIf( nIndex1 < nIndex2, nIndex1, nIndex2) - end - end - end - return dChosenIndex -end - -------------------------------------------------------------------------------------------------------------- --- funzione che processa tutte le feature sul pezzo e trova la miglior strategia di lavorazione tra quelle disponibili -local function GetBestStrategy( vProcSingleRot, Part) - -- per ogni feature - for i = 1, #vProcSingleRot do - -- processo tutte le feature attive - local Proc = vProcSingleRot[i] - if Proc.nFlg ~= 0 then - -- controllo se ci sono strategie disponibili - if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then - local nIndexBestStrategy = 0 - -- ciclo tutte le strategie della feature - for nIndexCurrentStrategy = 1, #Proc.AvailableStrategies do - -- eseguo file config con i parametri di default - local CurrentStrategy = {} - CurrentStrategy = RunStrategyLibraries( Proc.AvailableStrategies[nIndexCurrentStrategy].sStrategyId) - -- controllo che le librerie siano state effettivamente caricate - if CurrentStrategy.Config and CurrentStrategy.Script then - local bStrategyOk - -- eseguo la strategia solo come calcolo fattibilità e voto. Non si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati - _, Proc.AvailableStrategies[nIndexCurrentStrategy].Result = CurrentStrategy.Script.Make( false, Proc, Part, Proc.AvailableStrategies[nIndexCurrentStrategy].Parameters) - -- scelgo la migliore strategia tra le due - nIndexBestStrategy = GetIndexBestStrategyFromComparison( Proc.AvailableStrategies, nIndexCurrentStrategy, nIndexBestStrategy) - - -- se scelta strategia standard, esco subito alla prima che trovo completa - -- TODO serve paraemtro da Beam&Wall ( oppure da confirgurazione) !!!!!!!! - if BEAM.GetFirstCompletedStrategy and nIndexBestStrategy > 0 then - if Proc.AvailableStrategies[nIndexBestStrategy].Result.sStatus == 'Complete' then - break - end - end - - -- se non trovo i file della strategia, scrivo che non è più disponibile - else - Proc.AvailableStrategies[nIndexCurrentStrategy].Result = {} - Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sInfo = 'Strategy not found' - end - end - -- salvo sulla proc la migliore strategia - if nIndexBestStrategy ~= 0 then - Proc.ChosenStrategy = Proc.AvailableStrategies[nIndexBestStrategy] - end - end - end - end - return vProcSingleRot + return vProc end ------------------------------------------------------------------------------------------------------------- -- Ordina le feature in base a fase di lavorazione --- 1) Head : ( intestatura) --- 2) Standard : ( lavorazioni standard che non impattano sulal coda) --- 3) AdvanceTail : ( lavorazioni che richiedono taglio di separazione, ma che devono essere fatte prima perchè il taglio di separazione farebbe cadere il pezzo) --- 4) Split : ( taglio di separazione) --- 5) Tail : ( lavorazioni di coda, fatte dopo il taglio di separazione) +-- L'ordine è indicativamente: +-- 1) Fori +-- 2) Scassi serratura/maniglia +-- 3) Profili testa +-- 4) Profili Lati +-- 5) Incontri/scontri +-- TODO Ordinamento da fare local function OrderFeatures( vProc) local vProcToSort = vProc -- funzione di confronto. TRUE = B1 prima di B2. FALSE = B2 prima di B1 @@ -494,31 +279,10 @@ local function OrderFeatures( vProc) -- se entrambi disabilitati seguo l'Id elseif B1.nFlg == 0 and B2.nFlg == 0 then return ( B1.id < B2.id) - -- se in rotazioni diverse, si mette in ordine di rotazioni - elseif B1.nRot ~= B2.nRot then - return ( B1.nRot < B2.nRot) - -- se primo è taglio di testa, va prima degli altri casi - elseif B1.Head and ( B2.Standard or B2.AdvanceTail or B2.Split or B2.Tail) then + elseif B1.nPhase and B2.nPhase and B1.nPhase < B2.nPhase then return true - -- se primo è taglio standard, va prima degli altri casi - elseif B1.Standard and ( B2.AdvanceTail or B2.Split or B2.Tail) then + elseif B1.nPhase and B2.nPhase and B2.nPhase < B1.nPhase then return true - -- se primo è taglio di testa anticipata, va prima degli altri casi - elseif B1.AdvanceTail and ( B2.Split or B2.Tail) then - return true - -- se primo è taglio di separazione, va prima delle lavorazioni di coda - elseif B1.Split and B2.Tail then - return true - -- se da lavorare in stessa fase pezzo - elseif B1.Head == B2.Head or B1.Standard == B2.Standard or B1.AdvanceTail == B2.AdvanceTail or B1.Split == B2.Split or B1.Tail == B2.Tail then - -- confronto standard - if abs( B1.b3Box:getCenter():getX() - B2.b3Box:getCenter():getX()) > 0.4 * ( B1.b3Box:getDimX() + B2.b3Box:getDimX()) then - return B1.b3Box:getCenter():getX() > B2.b3Box:getCenter():getX() - elseif abs( B1.b3Box:getCenter():getY() - B2.b3Box:getCenter():getY()) > 0.2 * ( B1.b3Box:getDimY() + B2.b3Box:getDimY()) then - return B1.b3Box:getCenter():getY() > B2.b3Box:getCenter():getY() - elseif abs( B1.b3Box:getCenter():getZ() - B2.b3Box:getCenter():getZ()) > 0.1 * ( B1.b3Box:getDimZ() + B2.b3Box:getDimZ()) then - return B1.b3Box:getCenter():getZ() > B2.b3Box:getCenter():getZ() - end -- altrimenti si inverte else return false @@ -551,23 +315,10 @@ local function OrderFeatures( vProc) end ------------------------------------------------------------------------------------------------------------- --- esegue le strategie migliori che ha precedentemente scelto -local function CalculateMachinings( vProc, Part) - local bAreAllApplyOk = true - MACHININGS = {} - -- applico le strategie scelte - for i = 1, #vProc do - -- processo tutte le feature attive applicando le lavorazioni - local Proc = vProc[i] - if Proc.nFlg ~= 0 and Proc.ChosenStrategy then - -- carico file script strategia (non serve verificare presenza del file perchè già fatto durante scelta strategia) - 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 - bAreAllApplyOk, _ = StrategyScript.Make( true, Proc, Part, Proc.ChosenStrategy.Parameters) - end - end - return vProc +-- applica le lavorazioni +local function AddMachinings( Proc, Part) + -- TODO applicare lavorazioni!! + return Proc end ------------------------------------------------------------------------------------------------------------- @@ -575,16 +326,7 @@ local function PrintFeatures( vProc, Part) EgtOutLog( ' RawBox=' .. tostring( Part.RawBox)) for i = 1, #vProc do local Proc = vProc[i] - local sOut = string.format( ' Id=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Down=%s Side=%s Head=%s Tail=%s Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s TopoName=%s', - Proc.id, Proc.nGrp, Proc.nPrc, Proc.idTask, Proc.idCut, - Proc.nFlg, EgtIf( Proc.bDown, 'T', 'F'), EgtIf( Proc.bSide, 'T', 'F'), - EgtIf( Proc.bHead, 'T', 'F'), EgtIf( Proc.bTail, 'T', EgtIf( Proc.bAdvTail, 'A', 'F')), - Proc.nFcs, Proc.nFce, Proc.dDiam, Proc.nFct, tostring( Proc.b3Box), Proc.Topology.sName or '') - -- info speciali per Block Haus Half Lap - if Proc.nPrc == 37 then - local sSpec = string.format( ' N=%s Hd=%s', tostring( Proc.vtN or V_NULL()), EgtIf( Proc.bHeadDir, 'T', 'F')) - sOut = sOut .. sSpec - end + local sOut = string.format( 'Id=%3d Flg=%2d Type=%s', Proc.id, Proc.nFlg, Proc.sType) EgtOutLog( sOut) end end @@ -598,109 +340,29 @@ function WinExec.ProcessFeatures( PARTS) local Part = {} for nPart = 1, #PARTS do - if not PARTS[nPart].id and PARTS[nPart].b3Raw:getDimX() < BeamData.dMinRaw then break end - - -- per ogni rotazione, calcolo come lavorare le feature per decidere posizionamento iniziale e in che rotazione verranno lavorate le singole feature - local vProcRot = {} -- lista contenente le feature da eseguire local vProc = {} + + -- recupero le feature di lavorazione della trave + vProc = CollectFeatures( PARTS[nPart]) - --- TODO da rimuovere o lasciare solo per debug -if EgtGetDebugLevel() >= 3 then - EgtStartCounter() -end - - - -- TODO Il numero di rotazioni da calcolare deve dipendere dalle impostazionei del cliente. Per adesso si calcolano tutte e 4, ma può essere ottimizzato - for dRotIndex = 1, 4 do - - -- recupero le feature di lavorazione della trave - table.insert( vProcRot, CollectFeatures( PARTS[nPart])) - - -- recupero informazioni ausiliarie feature e dipendenze tra feature stesse - -- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no - vProcRot[dRotIndex] = GetFeatureInfoAndDependency( vProcRot[dRotIndex], PARTS[nPart]) - - -- sceglie la strategia migliore tra quelle disponibili ( presenti nella tabella vProcRot[dRotIndex].AvailableStrategies) - vProcRot[dRotIndex] = GetBestStrategy( vProcRot[dRotIndex], PARTS[nPart]) - - -- ruoto il grezzo per calcolare la fattibilità delle lavorazioni nella prossima rotazione - -- vettore movimento grezzi per rotazione di 90deg ogni step - local dDeltaYZ = PARTS[nPart].b3Raw:getDimY() - PARTS[nPart].b3Raw:getDimZ() - local vtMove = Vector3d( 0, dDeltaYZ / 2 * EgtIf( BeamData.RIGHT_LOAD, -1, 1), dDeltaYZ / 2) - local bPreMove = ( dDeltaYZ < 0) - -- ruoto le travi della fase corrente - if bPreMove then - EgtMoveRawPart( PARTS[nPart].idRaw, vtMove) - end - EgtRotateRawPart( PARTS[nPart].idRaw, X_AX(), EgtIf( BeamData.RIGHT_LOAD, -90, 90)) - if not bPreMove then - EgtMoveRawPart( PARTS[nPart].idRaw, vtMove) - end - -- aggiorno info pezzo - PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw) - PARTS[nPart].b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) - end - - --- TODO da rimuovere o lasciare solo per debug -if EgtGetDebugLevel() >= 3 then - local timeCollect = EgtStopCounter() - timeCollect = timeCollect + 0 - EgtOutBox( timeCollect, 'Collect calculation time') - EgtStartCounter() -end - - - -- TODO decidere come lavorare ogni feature in base alla matrice delle rotazioni - -- la matrice delle rotazioni deve già salvare sulla proc la strategia da utilizzare - -- Conviene salvarsi tutti i dati fino alla lavorazione e il ciclo di applicazione va ad applicare senza calcolare? - - -- aggiungo la fase, se non è la prima - if nOrd == 1 then - EgtSetCurrPhase( 1) - else - BeamLib.AddPhaseWithRawParts( PARTS[nPart], BeamData.ptOriXR, BeamData.dPosXR, 0) - end - local nPhase = EgtGetCurrPhase() - local nDispId = EgtGetPhaseDisposition( nPhase) - EgtSetInfo( nDispId, 'TYPE', EgtIf( PARTS[nPart].id, 'START', 'REST')) - EgtSetInfo( nDispId, 'ORD', nOrd) - EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( PARTS[nPart].idRaw) .. ' Part=' .. tostring( PARTS[nPart].id) .. ' ***', 1) + -- recupero informazioni ausiliarie feature e dipendenze tra feature stesse + vProc = GetFeatureInfoAndDependency( vProc, PARTS[nPart]) -- debug if EgtGetDebugLevel() >= 1 then PrintFeatures( vProc, PARTS[nPart]) end - EgtOutLog( ' *** AddMachinings ***', 1) - - -- TODO PROVVISORIO in attesa di scelta lavorazione in fase opportuna - vProc = vProcRot[1] -- ordino le features vProc = OrderFeatures( vProc) - -- TODO da fare - MACHININGS = {} - -- esegue le strategie migliori che ha precedentemente scelto e salva le lavorazioni nella lista globale - CalculateMachinings( vProc, PARTS[nPart]) - - -- TODO riordinare lavorazioni ottimizzando cambio utensile/spezzone ecc..., mantenendo dipendenze definite prima - -- ordino le lavorazioni - -- OrderMachining( vProc, PARTS[nPart]) - - -- aggiunge effettivamente le lavorazioni - MachiningLib.AddOperations( vProc, PARTS[nPart]) - - --- TODO da rimuovere o lasciare solo per debug -if EgtGetDebugLevel() >= 3 then - local timeMachining = EgtStopCounter() - timeMachining = timeMachining + 0 - EgtOutBox( timeMachining, 'Machining calculation time') -end + EgtOutLog( ' *** AddMachinings ***', 1) + for i = 1, #vProc do + -- aggiunge le lavorazioni + AddMachinings( vProc[i], PARTS[nPart]) + end EgtOutLog( ' *** End AddMachinings ***', 1) -- passo al grezzo successivo @@ -710,29 +372,9 @@ end -- Aggiornamento finale di tutto EgtSetCurrPhase( 1) local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings() - -- eventuale ricalcolo per macchine tipo PF (ma tengo warning del primo calcolo) - if EgtExistsInfo( EgtGetCurrMachGroup(), 'RECALC') then - EgtOutLog( ' **** RECALC ****') - bApplOk, sApplErrors, _ = EgtApplyAllMachinings() - EgtRemoveInfo( EgtGetCurrMachGroup(), 'RECALC') - end if not bApplOk then nTotErr = nTotErr + 1 - table.insert( Stats, {nErr = 1, sMsg=sApplErrors, nRot=0, idCut=0, idTask=0}) - elseif sApplWarns and #sApplWarns > 0 then - local vLine = EgtSplitString( sApplWarns, '\r\n') - for i = 1, #vLine do - local nPos = vLine[i]:find( '(WRN', 1, true) - if nPos then - local sData = vLine[i]:sub( nPos + 1, -2) - local vVal = EgtSplitString( sData, ',') - local nWarn = EgtGetVal( vVal[1] or '', 'WRN', 'i') - local nCutId = EgtGetVal( vVal[2] or '', 'CUTID', 'i') - if nWarn and nCutId then - table.insert( Stats, { nErr=-nWarn, sMsg=vLine[i], nRot=0, idCut=nCutId, idTask=0}) - end - end - end + table.insert( Stats, {nErr = 1, sMsg=sApplErrors}) end return ( nTotErr == 0), Stats diff --git a/CAMAuto/LuaLibs/WinLib.lua b/CAMAuto/LuaLibs/WinLib.lua index 17a21f1..04b370e 100644 --- a/CAMAuto/LuaLibs/WinLib.lua +++ b/CAMAuto/LuaLibs/WinLib.lua @@ -10,6 +10,20 @@ local WinData = require( 'WinData') EgtOutLog( ' WinLib started', 1) +------------------------------------------------------------------------------------------------------------- +function WinLib.GetAddGroup( PartId) + -- recupero il nome del gruppo di lavoro corrente + local sMchGrp = EgtGetMachGroupName( EgtGetCurrMachGroup() or GDB_ID.NULL) + if not sMchGrp then + return nil, nil + end + + -- cerco il gruppo aggiuntivo omonimo nel pezzo e se esiste lo restituisco + local AddGrpId = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, sMchGrp) + + -- restituisco Id e Nome + return AddGrpId, sMchGrp +end ------------------------------------------------------------------------------------------------------------- return WinLib \ No newline at end of file diff --git a/CAMAuto/ProcessWin.lua b/CAMAuto/ProcessWin.lua index 4a4eb6c..88be58f 100644 --- a/CAMAuto/ProcessWin.lua +++ b/CAMAuto/ProcessWin.lua @@ -40,6 +40,7 @@ EgtOutLog( '*** Window Process Start ***', 1) _G.package.loaded.WinData = nil _G.package.loaded.WinExec = nil _G.package.loaded.WinLib = nil +_G.package.loaded.FeatureData = nil -- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente -- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento. @@ -212,7 +213,33 @@ local function CreateRaws( PARTS) EgtAddPartToRawPart( PARTS[i].id, ORIG(), PARTS[i].idRaw) end end - + +--------------------------------------------------------------------- +-- Allinea i pezzi in base a come devono essere disposti sulla tavola +--------------------------------------------------------------------- +-- TODO in questa fase bisogna già sapere qual è la prima fase e posizionare il pezzo di conseguenza +-- TODO (bassa priorità) adesso allinea sempre in X, ma bisognerebbe farlo in base ad un parametro in WINDATA che dice come si dispongono in macchina +local function AlignRawsToTable( PARTS) + for i = 1, #PARTS do + -- allineo il pezzo all'interno del grezzo + local dRotX, dRotY, dRotZ = GetFixedAxesRotABCFromFrame( PARTS[i].frame) + + -- se devo ruotare + if dRotZ ~= 0 then + EgtRotatePartInRawPart( PARTS[i].id, Z_AX(), -dRotZ) + -- sposto punto in basso a sinistra del pezzo sul punto in basso a sinistra del grezzo + local dPartPosX = EgtGetBBoxGlob( PARTS[i].id, GDB_BB.STANDARD):getMin():getX() + local dPartPosY = EgtGetBBoxGlob( PARTS[i].id, GDB_BB.STANDARD):getMin():getY() + local dRawPosX = EgtGetRawPartBBox( PARTS[i].idRaw):getMin():getX() + local dRawPosY = EgtGetRawPartBBox( PARTS[i].idRaw):getMin():getY() + local vtMove = Vector3d( dRawPosX - dPartPosX, dRawPosY - dPartPosY, 0) + EgtMovePartInRawPart( PARTS[i].id, vtMove) + end + + end + return true +end + ------------------------------------------------------------------------------------------------------------- -- *** Funzione per trovare nome MachGroup *** ------------------------------------------------------------------------------------------------------------- @@ -244,7 +271,7 @@ local function MyProcessPieces() CreateRaws( PARTS) -- allineo i pezzi come orientamento richiesto dalla macchina - WinData.AlignRawsToTable( PARTS) + AlignRawsToTable( PARTS) -- aggiungo sovramateriale ai grezzi AddOverMaterialToRaw( PARTS) @@ -267,7 +294,7 @@ local function MyProcessPieces() end -- si dispongono i pezzi sulla tavola - WinData.Disposition( PARTS) + WinData.ExecDisposition( PARTS) return true end @@ -276,7 +303,7 @@ end -- *** Inserimento delle lavorazioni *** ------------------------------------------------------------------------------------------------------------- local function MyProcessFeatures() - --local bOk = WinExec.ProcessFeatures( PARTS) + local bOk = WinExec.ProcessFeatures( PARTS) return true end diff --git a/CAMAuto/Strategies/Cutting.lua b/CAMAuto/Strategies/Cutting.lua new file mode 100644 index 0000000..9e6ac0b --- /dev/null +++ b/CAMAuto/Strategies/Cutting.lua @@ -0,0 +1,17 @@ +-- Cutting.lua by Egalware s.r.l. 2024/06/13 +-- Libreria esecuzione lavorazioni per Serramenti -> Lavorazione di taglio + +-- Tabella per definizione modulo +local Cutting = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali +local WinData = require( 'WinData') + +EgtOutLog( ' Cutting started', 1) +EgtMdbSave() + +------------------------------------------------------------------------------------------------------------- +return Cutting \ No newline at end of file diff --git a/CAMAuto/Strategies/Drillin.lua b/CAMAuto/Strategies/Drillin.lua new file mode 100644 index 0000000..6e0ed03 --- /dev/null +++ b/CAMAuto/Strategies/Drillin.lua @@ -0,0 +1,17 @@ +-- Drilling.lua by Egalware s.r.l. 2024/06/13 +-- Libreria esecuzione lavorazioni per Serramenti -> Lavorazione di foratura + +-- Tabella per definizione modulo +local Drilling = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali +local WinData = require( 'WinData') + +EgtOutLog( ' Drilling started', 1) +EgtMdbSave() + +------------------------------------------------------------------------------------------------------------- +return Drilling \ No newline at end of file diff --git a/CAMAuto/Strategies/Milling.lua b/CAMAuto/Strategies/Milling.lua new file mode 100644 index 0000000..cb06794 --- /dev/null +++ b/CAMAuto/Strategies/Milling.lua @@ -0,0 +1,17 @@ +-- Milling.lua by Egalware s.r.l. 2024/06/13 +-- Libreria esecuzione lavorazioni per Serramenti -> Lavorazione di fresatura + +-- Tabella per definizione modulo +local Milling = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali +local WinData = require( 'WinData') + +EgtOutLog( ' Milling started', 1) +EgtMdbSave() + +------------------------------------------------------------------------------------------------------------- +return Milling \ No newline at end of file diff --git a/CAMAuto/Strategies/Pocketing.lua b/CAMAuto/Strategies/Pocketing.lua new file mode 100644 index 0000000..944794d --- /dev/null +++ b/CAMAuto/Strategies/Pocketing.lua @@ -0,0 +1,17 @@ +-- Pocketing.lua by Egalware s.r.l. 2024/06/13 +-- Libreria esecuzione lavorazioni per Serramenti -> Lavorazione di svuotatura + +-- Tabella per definizione modulo +local Pocketing = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali +local WinData = require( 'WinData') + +EgtOutLog( ' Pocketing started', 1) +EgtMdbSave() + +------------------------------------------------------------------------------------------------------------- +return Pocketing \ No newline at end of file diff --git a/CAMAuto/Strategies/Profiling.lua b/CAMAuto/Strategies/Profiling.lua new file mode 100644 index 0000000..268cce1 --- /dev/null +++ b/CAMAuto/Strategies/Profiling.lua @@ -0,0 +1,38 @@ +-- Profiling.lua by Egalware s.r.l. 2024/06/13 +-- Libreria esecuzione lavorazioni per Serramenti -> Lavorazione di profilatura + +-- Tabella per definizione modulo +local Profiling = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali +local WinData = require( 'WinData') + +EgtOutLog( ' Profiling started', 1) +EgtMdbSave() + +------------------------------------------------------------------------------------------------------------- +function Profiling.Make( Proc, Part) + local Machining = {} + Machining.LeadIn = {} + Machining.LeadOut = {} + Machining.Steps = {} + + Machining.sDepth = 0 + Machining.dRadialOffset = Proc.dRadialOffset + Machining.dLongitudinalOffset = Proc.dLongitudinalOffset + Machining.Steps.dSideStep = TOOLS[nIndexTool].dSideStep + + Machining.LeadIn.nType = MCH_MILL_LI.TANGENT + Machining.LeadIn.dTangentDistance = TOOLS[nIndexTool].dDiameter + Machining.LeadIn.dPerpDistance = TOOLS[nIndexTool].dDiameter + Machining.LeadOut.nType = MCH_MILL_LI.TANGENT + Machining.LeadOut.dTangentDistance = TOOLS[nIndexTool].dDiameter + Machining.LeadOut.dPerpDistance = 0 + +end + +------------------------------------------------------------------------------------------------------------- +return Profiling \ No newline at end of file From cc3ac6e1868587948f3dbd9f0ebbb675ab10fbf3 Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Thu, 20 Jun 2024 08:36:46 +0200 Subject: [PATCH 06/10] - Prima versione lavorazione Profiling - aggiunta funzione GetAffectedFaces per calcolo facce di riferimento - Lettura DB Utensili (da sistemare) - Gestione multipezzo in raccolta e lavorazione feature - Piccole correzioni varie --- CAMAuto/LuaLibs/FeatureData.lua | 25 ++++- CAMAuto/LuaLibs/MachiningLib.lua | 68 ++------------ CAMAuto/LuaLibs/WinExec.lua | 92 ++++++++++++++----- CAMAuto/LuaLibs/WinLib.lua | 28 ++++++ CAMAuto/ProcessWin.lua | 7 +- CAMAuto/Strategies/Cutting.lua | 5 + .../Strategies/{Drillin.lua => Drilling.lua} | 5 + CAMAuto/Strategies/Milling.lua | 5 + CAMAuto/Strategies/Pocketing.lua | 5 + CAMAuto/Strategies/Profiling.lua | 46 +++++++--- 10 files changed, 187 insertions(+), 99 deletions(-) rename CAMAuto/Strategies/{Drillin.lua => Drilling.lua} (72%) diff --git a/CAMAuto/LuaLibs/FeatureData.lua b/CAMAuto/LuaLibs/FeatureData.lua index 7907e0f..5f757a3 100644 --- a/CAMAuto/LuaLibs/FeatureData.lua +++ b/CAMAuto/LuaLibs/FeatureData.lua @@ -20,6 +20,27 @@ function FeatureData.GetDrillingData( Proc) return Proc end +------------------------------------------------------------------------------------------------------------- +-- Recupero dati taglio +function FeatureData.GetCuttingData( Proc) + + return Proc +end + +------------------------------------------------------------------------------------------------------------- +-- Recupero dati foro +function FeatureData.GetPocketingData( Proc) + + return Proc +end + +------------------------------------------------------------------------------------------------------------- +-- Recupero dati foro +function FeatureData.GetMillingData( Proc) + + return Proc +end + ------------------------------------------------------------------------------------------------------------- -- Recupero dati profilatura function FeatureData.GetProfilingData( Proc) @@ -29,8 +50,8 @@ function FeatureData.GetProfilingData( Proc) for t = 1, Proc.nToolsToUse do local Data = {} Data.sName = EgtGetInfo( Proc.id, 'TOOL_NAME_' .. tostring(t), 's') or 0 - Data.dRadialOvermat = EgtGetInfo( Proc.id, 'OFFR_' .. tostring(t), 'd') or 0 - Data.dLongitudinalOvermat = EgtGetInfo( Proc.id, 'OFFL_' .. tostring(t), 'd') or 0 + Data.dRadialOffset = EgtGetInfo( Proc.id, 'OFFR_' .. tostring(t), 'd') or 0 + Data.dLongitudinalOffset = EgtGetInfo( Proc.id, 'OFFL_' .. tostring(t), 'd') or 0 Data.sSide = EgtGetInfo( Proc.id, 'N', 's') or 0 table.insert( Proc.Tools, Data) end diff --git a/CAMAuto/LuaLibs/MachiningLib.lua b/CAMAuto/LuaLibs/MachiningLib.lua index f39f4cd..fbb61ef 100644 --- a/CAMAuto/LuaLibs/MachiningLib.lua +++ b/CAMAuto/LuaLibs/MachiningLib.lua @@ -8,57 +8,10 @@ local MachiningLib = {} require( 'EgtBase') -- Carico i dati globali -local BeamData = require( 'BeamData') +local WinData = require( 'WinData') EgtOutLog( ' MachiningLib started', 1) ---------------------------------------------------------------------- --- TODO da considerare solo angolo 2D?? -local function GetToolEntryAngle( Proc, vtTool) - local Angle = {} - - local dSinAngle = -10 * GEO.EPS_SMALL - local vtNorm - if Proc.AffectedFaces.bTop then - vtNorm = Z_AX() - dSinAngle = max( dSinAngle, vtTool * vtNorm) - end - if Proc.AffectedFaces.bBottom then - vtNorm = -Z_AX() - dSinAngle = max( dSinAngle, vtTool * vtNorm) - end - if Proc.AffectedFaces.bFront then - vtNorm = -Y_AX() - dSinAngle = max( dSinAngle, vtTool * vtNorm) - end - if Proc.AffectedFaces.bBack then - vtNorm = Y_AX() - dSinAngle = max( dSinAngle, vtTool * vtNorm) - end - if Proc.AffectedFaces.bLeft then - vtNorm = -X_AX() - dSinAngle = max( dSinAngle, vtTool * vtNorm) - end - if Proc.AffectedFaces.bRight then - vtNorm = X_AX() - dSinAngle = max( dSinAngle, vtTool * vtNorm) - end - - local dCosAngle = sqrt( 1 - sqr( dSinAngle)) - local dAngle = acos( dCosAngle) - local dTanAngle - if dAngle ~= 0 and dAngle ~= 90 then - dTanAngle = sqrt( 1 - dCosAngle * dCosAngle) / dCosAngle - end - - Angle.dValue = dAngle - Angle.dSin = dSinAngle - Angle.dCos = dCosAngle - Angle.dTan = dTanAngle - - return Angle - end - ------------------------------------------------------------------------------------------------------------- -- funzione per cercare utensile tipo FRESA con certe caratteristiche function MachiningLib.FindMill( Proc, ToolSearchParameters) @@ -92,19 +45,10 @@ function MachiningLib.FindMill( Proc, ToolSearchParameters) -- scelgo il migliore if bIsToolCompatible then - -- calcolo riduzione del massimo materiale utilizzabile - local ToolEntryAngle = GetToolEntryAngle( Proc, ToolSearchParameters.vtToolDirection) -- se ToolHolder più grande dell'utensile, il primo oggetto in collisione è il ToolHolder. Altrimenti il motore. - local dDimObjToCheck = EgtIf( TOOLS[i].ToolHolder.dDiameter > TOOLS[i].dDiameter, TOOLS[i].ToolHolder.dDiameter, BeamData.C_SIMM_ENC) - local dCurrentMaxMatReduction = BeamData.COLL_SIC or 5 + local dDimObjToCheck = EgtIf( TOOLS[i].ToolHolder.dDiameter > TOOLS[i].dDiameter, TOOLS[i].ToolHolder.dDiameter, WinData.C_SIMM_ENC) + local dCurrentMaxMatReduction = WinData.COLL_SIC or 5 - -- TODO implementare le funzioni di Tool Collision Avoidance (vedi wiki e FacesBysaw -> CalcLeadInOutPerpGeom) - -- TODO considerare anche il caso in cui lo stelo sia più grande del diametro utensile - -- TODO nei confronti tra valori gestire tolleranze - -- calcolo riduzione per non toccare con ToolHolder / Motore - if ToolEntryAngle.dValue > 0 and ToolEntryAngle.dValue < 90 then - dCurrentMaxMatReduction = dCurrentMaxMatReduction / ToolEntryAngle.dSin + ( ( dDimObjToCheck - TOOLS[i].dDiameter) / 2) / ToolEntryAngle.dTan - end -- dCurrMachReduction = negativo -> limitare, positivo -> mm extra disponibili local dCurrentResidualDepth = ToolSearchParameters.dElevation + dCurrentMaxMatReduction - TOOLS[i].dMaxDepth @@ -210,7 +154,7 @@ function MachiningLib.AddNewMachining( ProcToAdd, MachiningToAdd) end -- se nome non definito, assegno alla lavorazioen un nome standard if not MachiningToAdd.sOperationName then - MachiningToAdd.sOperationName = MachiningToAdd.sTypeName .. ( EgtGetName( ProcToAdd.id) or tostring( ProcToAdd.id)) .. '_' .. tostring( MachiningToAdd.Geometry[1][2]) + MachiningToAdd.sOperationName = MachiningToAdd.sTypeName .. ( EgtGetName( ProcToAdd.id) or tostring( ProcToAdd.id)) -- TODO serve scrivere faccia? -->> .. '_' .. tostring( MachiningToAdd.Geometry[1][2]) end if not MachiningToAdd.sToolName then MachiningToAdd.sToolName = TOOLS[MachiningToAdd.nToolIndex].sName @@ -244,8 +188,8 @@ function MachiningLib.AddOperations( vProc, Part) if MACHININGS[i].Machining.bInvert then EgtSetMachiningParam( MCH_MP.INVERT, MACHININGS[i].Machining.bInvert) end - if MACHININGS[i].Machining.nWorkside then - EgtSetMachiningParam( MCH_MP.WORKSIDE, MACHININGS[i].Machining.nWorkside) + if MACHININGS[i].Machining.nWorkSide then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MACHININGS[i].Machining.nWorkSide) end if MACHININGS[i].Machining.nFaceuse then EgtSetMachiningParam( MCH_MP.FACEUSE, MACHININGS[i].Machining.nFaceuse) diff --git a/CAMAuto/LuaLibs/WinExec.lua b/CAMAuto/LuaLibs/WinExec.lua index c79d716..cc90529 100644 --- a/CAMAuto/LuaLibs/WinExec.lua +++ b/CAMAuto/LuaLibs/WinExec.lua @@ -12,6 +12,20 @@ local WinData = require( 'WinData') local WinLib = require( 'WinLib') local ID = require( 'Identity') local FeatureData = require( 'FeatureData') +local MachiningLib = require( 'MachiningLib') + +-- carico librerie di lavorazione +_G.package.loaded.Drilling = nil +_G.package.loaded.Cutting = nil +_G.package.loaded.Pocketing = nil +_G.package.loaded.Milling = nil +_G.package.loaded.Profiling = nil +local Drilling = require( 'Drilling') +local Cutting = require( 'Cutting') +local Pocketing = require( 'Pocketing') +local Milling = require( 'Milling') +local Profiling = require( 'Profiling') + EgtOutLog( ' WinExec started', 1) EgtMdbSave() @@ -23,7 +37,7 @@ TOOLS = nil MACHININGS = nil ------------------------------------------------------------------------------------------------------------- --- *** COSTANTI *** TODO -> DA SPOSTARE IN BEAMDATA??? +-- *** COSTANTI *** TODO -> DA SPOSTARE IN WINDATA??? ------------------------------------------------------------------------------------------------------------- TH_DIAMETER_HSK63 = 63 TH_LENGTH_HSK63 = 75 @@ -116,10 +130,10 @@ function WinExec.GetToolsFromDB() Tool.Feeds.dStartFeed = EgtTdbGetCurrToolParam( MCH_TP.STARTFEED) Tool.Feeds.dEndFeed = EgtTdbGetCurrToolParam( MCH_TP.ENDFEED) Tool.Feeds.dTipFeed = EgtTdbGetCurrToolParam( MCH_TP.TIPFEED) - -- TODO serve funzione in BeamData che data la posizione dell'utensile e della testa, capisca il montaggio (testa sopra - testa sotto - aggregato - ecc...) + -- TODO serve funzione in WinData che data la posizione dell'utensile e della testa, capisca il montaggio (testa sopra - testa sotto - aggregato - ecc...) Tool.sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) Tool.SetupInfo = {} - Tool.SetupInfo = BeamData.GetSetupInfo( Tool.sHead) + Tool.SetupInfo = WinData.GetSetupInfo( Tool.sHead) Tool.sUUID = EgtTdbGetCurrToolParam( MCH_TP.UUID) Tool.sUserNotes = EgtTdbGetCurrToolParam( MCH_TP.USERNOTES) Tool.dMaxDepth = EgtTdbGetCurrToolMaxDepth() or Tool.dMaxMaterial @@ -187,7 +201,7 @@ end local function CollectFeatures( Part) -- recupero le feature - local vProc = {} + local vPartProc = {} local LayerId = {} LayerId[1] = WinLib.GetAddGroup( Part.id) LayerId[2] = EgtGetFirstNameInGroup( Part.id or GDB_ID.NULL, 'Processings') @@ -207,6 +221,8 @@ local function CollectFeatures( Part) Proc.sType = sType Proc.b3Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD) Proc.nPhase = EgtGetInfo( ProcId, 'PHASE', 'i') or nil + -- informazioni facce + Proc.AffectedFaces = WinLib.GetAffectedFaces( Proc, Part) -- se esiste la geometria if Proc.b3Box and not Proc.b3Box:isEmpty() then @@ -217,12 +233,15 @@ local function CollectFeatures( Part) end -- se taglio if ID.IsCutting( Proc) then + Proc = FeatureData.GetCuttingData( Proc) end -- se fresatura if ID.IsMilling( Proc) then + Proc = FeatureData.GetMillingData( Proc) end -- se svuotatura if ID.IsPocketing( Proc) then + Proc = FeatureData.GetPocketingData( Proc) end -- se profilatura if ID.IsProfiling( Proc) then @@ -230,10 +249,10 @@ local function CollectFeatures( Part) end -- inserisco feature in lista - table.insert( vProc, Proc) + table.insert( vPartProc, Proc) else Proc.nFlg = 0 - table.insert( vProc, Proc) + table.insert( vPartProc, Proc) EgtOutLog( ' Feature ' .. tostring( Proc.idFeature) .. ' is empty (no geometry)') end end @@ -241,7 +260,7 @@ local function CollectFeatures( Part) ProcId = EgtGetNext( ProcId) end end - return vProc + return vPartProc end ------------------------------------------------------------------------------------------------------------- @@ -260,6 +279,10 @@ local function GetFeatureInfoAndDependency( vProc, Part) return vProc end +------------------------------------------------------------------------------------------------------------- +local function OrderMachining( vProc, PARTS) +end + ------------------------------------------------------------------------------------------------------------- -- Ordina le feature in base a fase di lavorazione -- L'ordine è indicativamente: @@ -276,9 +299,6 @@ local function OrderFeatures( vProc) -- se secondo disabilitato, va lasciato dopo if B1.nFlg ~= 0 and B2.nFlg == 0 then return true - -- se entrambi disabilitati seguo l'Id - elseif B1.nFlg == 0 and B2.nFlg == 0 then - return ( B1.id < B2.id) elseif B1.nPhase and B2.nPhase and B1.nPhase < B2.nPhase then return true elseif B1.nPhase and B2.nPhase and B2.nPhase < B1.nPhase then @@ -316,9 +336,31 @@ end ------------------------------------------------------------------------------------------------------------- -- applica le lavorazioni -local function AddMachinings( Proc, Part) - -- TODO applicare lavorazioni!! - return Proc +local function AddMachinings( ProcPart, Part) + local bMachiningOk = true + for nFeatureIndex = 1, #ProcPart do + local Proc = ProcPart[nFeatureIndex] + if ID.IsDrilling( Proc) then + bMachiningOk = Drilling.Make( Proc, Part) + end + -- se taglio + if ID.IsCutting( Proc) then + bMachiningOk = Cutting.Make( Proc, Part) + end + -- se fresatura + if ID.IsMilling( Proc) then + bMachiningOk = Milling.Make( Proc, Part) + end + -- se svuotatura + if ID.IsPocketing( Proc) then + bMachiningOk = Pocketing.Make( Proc, Part) + end + -- se profilatura + if ID.IsProfiling( Proc) then + bMachiningOk = Profiling.Make( Proc, Part) + end + end + return bMachiningOk end ------------------------------------------------------------------------------------------------------------- @@ -339,36 +381,42 @@ function WinExec.ProcessFeatures( PARTS) local nOrd = 1 local Part = {} + local vProc = {} for nPart = 1, #PARTS do -- lista contenente le feature da eseguire - local vProc = {} -- recupero le feature di lavorazione della trave - vProc = CollectFeatures( PARTS[nPart]) + table.insert( vProc, CollectFeatures( PARTS[nPart])) -- recupero informazioni ausiliarie feature e dipendenze tra feature stesse - vProc = GetFeatureInfoAndDependency( vProc, PARTS[nPart]) + vProc[nPart] = GetFeatureInfoAndDependency( vProc[nPart], PARTS[nPart]) -- debug if EgtGetDebugLevel() >= 1 then - PrintFeatures( vProc, PARTS[nPart]) + PrintFeatures( vProc[nPart], PARTS[nPart]) end -- ordino le features - vProc = OrderFeatures( vProc) + vProc[nPart] = OrderFeatures( vProc[nPart]) EgtOutLog( ' *** AddMachinings ***', 1) - for i = 1, #vProc do - -- aggiunge le lavorazioni - AddMachinings( vProc[i], PARTS[nPart]) - end + -- TODO da fare + MACHININGS = {} + -- esegue le strategie migliori che ha precedentemente scelto e salva le lavorazioni nella lista globale + AddMachinings( vProc[nPart], PARTS[nPart]) + EgtOutLog( ' *** End AddMachinings ***', 1) -- passo al grezzo successivo nOrd = nOrd + 1 end + OrderMachining( vProc, PARTS) + + -- aggiunge effettivamente le lavorazioni + MachiningLib.AddOperations( vProc, PARTS) + -- Aggiornamento finale di tutto EgtSetCurrPhase( 1) local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings() diff --git a/CAMAuto/LuaLibs/WinLib.lua b/CAMAuto/LuaLibs/WinLib.lua index 04b370e..6957512 100644 --- a/CAMAuto/LuaLibs/WinLib.lua +++ b/CAMAuto/LuaLibs/WinLib.lua @@ -10,6 +10,34 @@ local WinData = require( 'WinData') EgtOutLog( ' WinLib started', 1) +------------------------------------------------------------------------------------------------------------- +-- restituisce le facce della parte interessate dalla feature Proc +function WinLib.GetAffectedFaces( Proc, Part) + local vtFacesAffected = { bTop = false, bBottom = false, bFront = false, bBack = false, bLeft = false, bRight = false} + if Proc.b3Box and not Proc.b3Box:isEmpty() then + if Proc.b3Box:getMax():getZ() > Part.b3Solid:getMax():getZ() - 500 * GEO.EPS_SMALL then + vtFacesAffected.bTop = true + end + if Proc.b3Box:getMin():getZ() < Part.b3Solid:getMin():getZ() + 500 * GEO.EPS_SMALL then + vtFacesAffected.bBottom = true + end + if Proc.b3Box:getMin():getY() < Part.b3Solid:getMin():getY() + 500 * GEO.EPS_SMALL then + vtFacesAffected.bFront = true + end + if Proc.b3Box:getMax():getY() > Part.b3Solid:getMax():getY() - 500 * GEO.EPS_SMALL then + vtFacesAffected.bBack = true + end + if Proc.b3Box:getMin():getX() < Part.b3Solid:getMin():getX() + 500 * GEO.EPS_SMALL then + vtFacesAffected.bLeft = true + end + if Proc.b3Box:getMax():getX() > Part.b3Solid:getMax():getX() - 500 * GEO.EPS_SMALL then + vtFacesAffected.bRight = true + end + end + + return vtFacesAffected +end + ------------------------------------------------------------------------------------------------------------- function WinLib.GetAddGroup( PartId) -- recupero il nome del gruppo di lavoro corrente diff --git a/CAMAuto/ProcessWin.lua b/CAMAuto/ProcessWin.lua index 88be58f..c8c2aa8 100644 --- a/CAMAuto/ProcessWin.lua +++ b/CAMAuto/ProcessWin.lua @@ -41,6 +41,7 @@ _G.package.loaded.WinData = nil _G.package.loaded.WinExec = nil _G.package.loaded.WinLib = nil _G.package.loaded.FeatureData = nil +_G.package.loaded.MachiningLib = nil -- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente -- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento. @@ -116,7 +117,7 @@ end ------------------------------------------------------------------------------------------------------------- local function GetDataConfig() -- recupero utensili dal magazzino - -- WinExec.GetToolsFromDB() + WinExec.GetToolsFromDB() -- TODO da gestire eventuali errori bloccanti return true @@ -296,6 +297,10 @@ local function MyProcessPieces() -- si dispongono i pezzi sulla tavola WinData.ExecDisposition( PARTS) + -- Impostazione dell'attrezzaggio di default + -- TODO se lascio il campo vuoto non mi carica il default!!!!!!! + local bOk = EgtImportSetup( 'CIAO') + return true end diff --git a/CAMAuto/Strategies/Cutting.lua b/CAMAuto/Strategies/Cutting.lua index 9e6ac0b..ceb4d3d 100644 --- a/CAMAuto/Strategies/Cutting.lua +++ b/CAMAuto/Strategies/Cutting.lua @@ -13,5 +13,10 @@ local WinData = require( 'WinData') EgtOutLog( ' Cutting started', 1) EgtMdbSave() +------------------------------------------------------------------------------------------------------------- +function Cutting.Make( Proc, Part) + return true +end + ------------------------------------------------------------------------------------------------------------- return Cutting \ No newline at end of file diff --git a/CAMAuto/Strategies/Drillin.lua b/CAMAuto/Strategies/Drilling.lua similarity index 72% rename from CAMAuto/Strategies/Drillin.lua rename to CAMAuto/Strategies/Drilling.lua index 6e0ed03..8aaf024 100644 --- a/CAMAuto/Strategies/Drillin.lua +++ b/CAMAuto/Strategies/Drilling.lua @@ -13,5 +13,10 @@ local WinData = require( 'WinData') EgtOutLog( ' Drilling started', 1) EgtMdbSave() +------------------------------------------------------------------------------------------------------------- +function Drilling.Make( Proc, Part) + return true +end + ------------------------------------------------------------------------------------------------------------- return Drilling \ No newline at end of file diff --git a/CAMAuto/Strategies/Milling.lua b/CAMAuto/Strategies/Milling.lua index cb06794..b1dfe09 100644 --- a/CAMAuto/Strategies/Milling.lua +++ b/CAMAuto/Strategies/Milling.lua @@ -13,5 +13,10 @@ local WinData = require( 'WinData') EgtOutLog( ' Milling started', 1) EgtMdbSave() +------------------------------------------------------------------------------------------------------------- +function Milling.Make( Proc, Part) + return true +end + ------------------------------------------------------------------------------------------------------------- return Milling \ No newline at end of file diff --git a/CAMAuto/Strategies/Pocketing.lua b/CAMAuto/Strategies/Pocketing.lua index 944794d..1759916 100644 --- a/CAMAuto/Strategies/Pocketing.lua +++ b/CAMAuto/Strategies/Pocketing.lua @@ -13,5 +13,10 @@ local WinData = require( 'WinData') EgtOutLog( ' Pocketing started', 1) EgtMdbSave() +------------------------------------------------------------------------------------------------------------- +function Pocketing.Make( Proc, Part) + return true +end + ------------------------------------------------------------------------------------------------------------- return Pocketing \ No newline at end of file diff --git a/CAMAuto/Strategies/Profiling.lua b/CAMAuto/Strategies/Profiling.lua index 268cce1..ea7d97f 100644 --- a/CAMAuto/Strategies/Profiling.lua +++ b/CAMAuto/Strategies/Profiling.lua @@ -9,29 +9,51 @@ require( 'EgtBase') -- Carico i dati globali local WinData = require( 'WinData') +local MachiningLib = require( 'MachiningLib') EgtOutLog( ' Profiling started', 1) EgtMdbSave() ------------------------------------------------------------------------------------------------------------- function Profiling.Make( Proc, Part) + local ToolInfo = {} local Machining = {} Machining.LeadIn = {} Machining.LeadOut = {} Machining.Steps = {} - Machining.sDepth = 0 - Machining.dRadialOffset = Proc.dRadialOffset - Machining.dLongitudinalOffset = Proc.dLongitudinalOffset - Machining.Steps.dSideStep = TOOLS[nIndexTool].dSideStep - - Machining.LeadIn.nType = MCH_MILL_LI.TANGENT - Machining.LeadIn.dTangentDistance = TOOLS[nIndexTool].dDiameter - Machining.LeadIn.dPerpDistance = TOOLS[nIndexTool].dDiameter - Machining.LeadOut.nType = MCH_MILL_LI.TANGENT - Machining.LeadOut.dTangentDistance = TOOLS[nIndexTool].dDiameter - Machining.LeadOut.dPerpDistance = 0 - + -- se so che utensili utilizzare, associazione diretta + if Proc.nToolsToUse then + for i = 1, Proc.nToolsToUse do + local ToolSearchParameters = {} + ToolSearchParameters.sName = Proc.Tools[i].sName + ToolSearchParameters.dElevation = 0 + ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) + -- se trovato utensile + if ToolInfo.nToolIndex then + Machining.nType = MCH_MY.MILLING + Machining.nWorkSide = MCH_MILL_WS.RIGHT + Machining.nToolIndex = ToolInfo.nToolIndex + Machining.sDepth = 0 + Machining.dRadialOffset = Proc.Tools[i].dRadialOffset + Machining.dLongitudinalOffset = Proc.Tools[i].dLongitudinalOffset + Machining.LeadIn.nType = MCH_MILL_LI.TANGENT + Machining.LeadIn.dTangentDistance = TOOLS[ToolInfo.nToolIndex].dDiameter + Machining.LeadIn.dPerpDistance = TOOLS[ToolInfo.nToolIndex].dDiameter + Machining.LeadOut.nType = MCH_MILL_LO.TANGENT + Machining.LeadOut.dTangentDistance = TOOLS[ToolInfo.nToolIndex].dDiameter + Machining.LeadOut.dPerpDistance = 0 + Machining.Geometry = Proc.id + MachiningLib.AddNewMachining( Proc, Machining) + else + return false, 'Tool not found' + end + end + -- altrimenti cerco tra quelli disponibili + else + ; --per il momento non serve. Le info sull'utensile arrivano sempre + end + return true end ------------------------------------------------------------------------------------------------------------- From 66869aa0d87ff0ca99c6b646a4b5013de0ed1198 Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Thu, 20 Jun 2024 16:52:11 +0200 Subject: [PATCH 07/10] - Ridefinito flusso automatismo - Aggiunta gestion AuxInfo per gestire ordine lavorazioni - Piccole migliorie varie --- .vscode/settings.json | 12 +- CAMAuto/LuaLibs/MachiningLib.lua | 303 ++++++++++++++++--------------- CAMAuto/LuaLibs/WinExec.lua | 174 +++++++++--------- CAMAuto/ProcessWin.lua | 3 +- CAMAuto/Strategies/Profiling.lua | 12 +- 5 files changed, 265 insertions(+), 239 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index afdd2c3..1cd0e3e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -114,7 +114,17 @@ "EgtSurfTmIntersect", "GDB_IN", "GEO", - "dist" + "dist", + "EgtSetMachiningParam", + "EgtCreateMachining", + "EgtSetMachiningGeometry", + "EgtGetMachiningParam", + "EgtGetLastMachMgrError", + "EgtSetOperationMode", + "EgtApplyMachining", + "EgtSetCurrPhase", + "EgtApplyAllMachinings", + "EgtGetDebugLevel" ], "Lua.diagnostics.disable": [ "empty-block" diff --git a/CAMAuto/LuaLibs/MachiningLib.lua b/CAMAuto/LuaLibs/MachiningLib.lua index fbb61ef..106c215 100644 --- a/CAMAuto/LuaLibs/MachiningLib.lua +++ b/CAMAuto/LuaLibs/MachiningLib.lua @@ -45,8 +45,6 @@ function MachiningLib.FindMill( Proc, ToolSearchParameters) -- scelgo il migliore if bIsToolCompatible then - -- se ToolHolder più grande dell'utensile, il primo oggetto in collisione è il ToolHolder. Altrimenti il motore. - local dDimObjToCheck = EgtIf( TOOLS[i].ToolHolder.dDiameter > TOOLS[i].dDiameter, TOOLS[i].ToolHolder.dDiameter, WinData.C_SIMM_ENC) local dCurrentMaxMatReduction = WinData.COLL_SIC or 5 -- dCurrMachReduction = negativo -> limitare, positivo -> mm extra disponibili @@ -126,9 +124,18 @@ end function MachiningLib.FindDrill() end +------------------------------------------------------------------------------------------------------------- +-- funzione per cercare utensile tipo PUNTA A FORARE con certe caratteristiche +function MachiningLib.GetPhaseMach( Proc) + local nPhase + if Proc.nPhase then + nPhase = Proc.nPhase + end + return nPhase +end ------------------------------------------------------------------------------------------------------------- -- salva in lista globale la lavorazione appena calcolata -function MachiningLib.AddNewMachining( ProcToAdd, MachiningToAdd) +function MachiningLib.AddNewMachining( ProcToAdd, MachiningToAdd, AuxInfoToAdd) -- Controllo parametri obbligatori if not MachiningToAdd.nType or not MachiningToAdd.nToolIndex or not MachiningToAdd.Geometry or not ProcToAdd.id then return false @@ -162,167 +169,165 @@ function MachiningLib.AddNewMachining( ProcToAdd, MachiningToAdd) local Machining = {} Machining.Proc = ProcToAdd Machining.Machining = MachiningToAdd + Machining.AuxInfo = AuxInfoToAdd table.insert( MACHININGS, Machining) return true end ------------------------------------------------------------------------------------------------------------- -- funzione per aggiungere una nuova lavorazione -function MachiningLib.AddOperations( vProc, Part) +function MachiningLib.AddOperation( OperationToInsert) local nErr local sErr = '' local bAreAllMachiningApplyOk = true - for i = 1, #MACHININGS do - -- creazione lavorazione - local nOperationId = EgtCreateMachining( MACHININGS[i].Machining.sOperationName, MACHININGS[i].Machining.nType, MACHININGS[i].Machining.sToolName) + -- creazione lavorazione + local nOperationId = EgtCreateMachining( OperationToInsert.Machining.sOperationName, OperationToInsert.Machining.nType, OperationToInsert.Machining.sToolName) - if nOperationId then - -- impostazione geometria - EgtSetMachiningGeometry( MACHININGS[i].Machining.Geometry) + if nOperationId then + -- impostazione geometria + EgtSetMachiningGeometry( OperationToInsert.Machining.Geometry) - -- impostazione parametri lavorazione - if MACHININGS[i].Machining.sDepth then - EgtSetMachiningParam( MCH_MP.DEPTH_STR, MACHININGS[i].Machining.sDepth) - end - if MACHININGS[i].Machining.bInvert then - EgtSetMachiningParam( MCH_MP.INVERT, MACHININGS[i].Machining.bInvert) - end - if MACHININGS[i].Machining.nWorkSide then - EgtSetMachiningParam( MCH_MP.WORKSIDE, MACHININGS[i].Machining.nWorkSide) - end - if MACHININGS[i].Machining.nFaceuse then - EgtSetMachiningParam( MCH_MP.FACEUSE, MACHININGS[i].Machining.nFaceuse) - end - if MACHININGS[i].Machining.nSCC then - EgtSetMachiningParam( MCH_MP.SCC, MACHININGS[i].Machining.nSCC) - end - if MACHININGS[i].Machining.bToolInvert then - EgtSetMachiningParam( MCH_MP.TOOLINVERT, MACHININGS[i].Machining.bToolInvert) - end - if MACHININGS[i].Machining.sBlockedAxis then - EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, MACHININGS[i].Machining.sBlockedAxis) - end - if MACHININGS[i].Machining.sInitialAngles then - EgtSetMachiningParam( MCH_MP.INITANGS, MACHININGS[i].Machining.sInitialAngles) - end - if MACHININGS[i].Machining.nHeadSide then - EgtSetMachiningParam( MCH_MP.HEADSIDE, MACHININGS[i].Machining.nHeadSide) - end - if MACHININGS[i].Machining.nSubType then - EgtSetMachiningParam( MCH_MP.SUBTYPE, MACHININGS[i].Machining.nSubType) - end - if MACHININGS[i].Machining.dOverlap then - EgtSetMachiningParam( MCH_MP.OVERL, MACHININGS[i].Machining.dOverlap) - end - - -- step - if MACHININGS[i].Machining.Steps then - if MACHININGS[i].Machining.Steps.dStepType then - EgtSetMachiningParam( MCH_MP.STEPTYPE, MACHININGS[i].Machining.Steps.dStepType) - end - if MACHININGS[i].Machining.Steps.dStep then - EgtSetMachiningParam( MCH_MP.STEP, MACHININGS[i].Machining.Steps.dStep) - end - if MACHININGS[i].Machining.Steps.dSideStep then - EgtSetMachiningParam( MCH_MP.SIDESTEP, MACHININGS[i].Machining.Steps.dSideStep) - end - end - - if MACHININGS[i].Machining.dStartPos then - EgtSetMachiningParam( MCH_MP.STARTPOS, MACHININGS[i].Machining.dStartPos) - end - if MACHININGS[i].Machining.dReturnPos then - EgtSetMachiningParam( MCH_MP.RETURNPOS, MACHININGS[i].Machining.dReturnPos) - end - - if MACHININGS[i].Machining.dRadialOffset then - EgtSetMachiningParam( MCH_MP.OFFSR, MACHININGS[i].Machining.dRadialOffset) - end - if MACHININGS[i].Machining.dLongitudinalOffset then - EgtSetMachiningParam( MCH_MP.OFFSL, MACHININGS[i].Machining.dLongitudinalOffset) - end - - -- paraemtri attacco - if MACHININGS[i].Machining.LeadIn then - if MACHININGS[i].Machining.LeadIn.nType then - EgtSetMachiningParam( MCH_MP.LEADINTYPE, MACHININGS[i].Machining.LeadIn.nType) - end - if MACHININGS[i].Machining.LeadIn.dStartAddLength then - EgtSetMachiningParam( MCH_MP.STARTADDLEN, MACHININGS[i].Machining.LeadIn.dStartAddLength) - end - if MACHININGS[i].Machining.LeadIn.dTangentDistance then - EgtSetMachiningParam( MCH_MP.LITANG, MACHININGS[i].Machining.LeadIn.dTangentDistance) - end - if MACHININGS[i].Machining.LeadIn.dPerpDistance then - EgtSetMachiningParam( MCH_MP.LIPERP, MACHININGS[i].Machining.LeadIn.dPerpDistance) - end - if MACHININGS[i].Machining.LeadIn.dElevation then - EgtSetMachiningParam( MCH_MP.LIELEV, MACHININGS[i].Machining.LeadIn.dElevation) - end - if MACHININGS[i].Machining.LeadIn.dCompLength then - EgtSetMachiningParam( MCH_MP.LICOMPLEN, MACHININGS[i].Machining.LeadIn.dCompLength) - end - end - -- parametri uscita - if MACHININGS[i].Machining.LeadOut then - if MACHININGS[i].Machining.LeadOut.nType then - EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MACHININGS[i].Machining.LeadOut.nType) - end - if MACHININGS[i].Machining.LeadOut.dEndAddLength then - EgtSetMachiningParam( MCH_MP.ENDADDLEN, MACHININGS[i].Machining.LeadOut.dEndAddLength) - end - if MACHININGS[i].Machining.LeadOut.dTangentDistance then - EgtSetMachiningParam( MCH_MP.LOTANG, MACHININGS[i].Machining.LeadOut.dTangentDistance) - end - if MACHININGS[i].Machining.LeadOut.dPerpDistance then - EgtSetMachiningParam( MCH_MP.LOPERP, MACHININGS[i].Machining.LeadOut.dPerpDistance) - end - if MACHININGS[i].Machining.LeadOut.dElevation then - EgtSetMachiningParam( MCH_MP.LOELEV, MACHININGS[i].Machining.LeadOut.dElevation) - end - if MACHININGS[i].Machining.LeadOut.dCompLength then - EgtSetMachiningParam( MCH_MP.LOCOMPLEN, MACHININGS[i].Machining.LeadOut.dCompLength) - end - end - - if MACHININGS[i].Machining.dStartSlowLen then - EgtSetMachiningParam( MCH_MP.STARTSLOWLEN, MACHININGS[i].Machining.dStartSlowLen) - end - if MACHININGS[i].Machining.dEndSlowLen then - EgtSetMachiningParam( MCH_MP.ENDSLOWLEN, MACHININGS[i].Machining.dEndSlowLen) - end - if MACHININGS[i].Machining.dThrouAddLen then - EgtSetMachiningParam( MCH_MP.THROUADDLEN, MACHININGS[i].Machining.dThrouAddLen) - end - - -- parametri da settare nelle note di sistema - -- TODO da decidere quali sono le note da salvare qui. Probabilmente tutte quelle relative all'ordine delle lavorazioni - local sSystemNotes = EgtGetMachiningParam( MCH_MP.SYSNOTES) - --if MACHININGS[i].Machining.nMachiningOrder then - -- sSystemNotes = EgtSetValInNotes( sSystemNotes, 'MachiningOrder', MACHININGS[i].Machining.nMachiningOrder) - --end - EgtSetMachiningParam( MCH_MP.SYSNOTES, sSystemNotes) - - -- parametri da settare nelle note utente - local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) - if MACHININGS[i].Machining.dMaxElev then - sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', MACHININGS[i].Machining.dMaxElev) - end - EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) - - local bIsApplyOk = MachiningLib.ApplyMachining( true, false) - if not bIsApplyOk then - bAreAllMachiningApplyOk = false - nErr, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nOperationId, false) - end - else - return false, 'UNEXPECTED ERROR: Error on creating machining' + -- impostazione parametri lavorazione + if OperationToInsert.Machining.sDepth then + EgtSetMachiningParam( MCH_MP.DEPTH_STR, OperationToInsert.Machining.sDepth) + end + if OperationToInsert.Machining.bInvert then + EgtSetMachiningParam( MCH_MP.INVERT, OperationToInsert.Machining.bInvert) + end + if OperationToInsert.Machining.nWorkSide then + EgtSetMachiningParam( MCH_MP.WORKSIDE, OperationToInsert.Machining.nWorkSide) + end + if OperationToInsert.Machining.nFaceuse then + EgtSetMachiningParam( MCH_MP.FACEUSE, OperationToInsert.Machining.nFaceuse) + end + if OperationToInsert.Machining.nSCC then + EgtSetMachiningParam( MCH_MP.SCC, OperationToInsert.Machining.nSCC) + end + if OperationToInsert.Machining.bToolInvert then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, OperationToInsert.Machining.bToolInvert) + end + if OperationToInsert.Machining.sBlockedAxis then + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, OperationToInsert.Machining.sBlockedAxis) + end + if OperationToInsert.Machining.sInitialAngles then + EgtSetMachiningParam( MCH_MP.INITANGS, OperationToInsert.Machining.sInitialAngles) + end + if OperationToInsert.Machining.nHeadSide then + EgtSetMachiningParam( MCH_MP.HEADSIDE, OperationToInsert.Machining.nHeadSide) + end + if OperationToInsert.Machining.nSubType then + EgtSetMachiningParam( MCH_MP.SUBTYPE, OperationToInsert.Machining.nSubType) + end + if OperationToInsert.Machining.dOverlap then + EgtSetMachiningParam( MCH_MP.OVERL, OperationToInsert.Machining.dOverlap) end + -- step + if OperationToInsert.Machining.Steps then + if OperationToInsert.Machining.Steps.dStepType then + EgtSetMachiningParam( MCH_MP.STEPTYPE, OperationToInsert.Machining.Steps.dStepType) + end + if OperationToInsert.Machining.Steps.dStep then + EgtSetMachiningParam( MCH_MP.STEP, OperationToInsert.Machining.Steps.dStep) + end + if OperationToInsert.Machining.Steps.dSideStep then + EgtSetMachiningParam( MCH_MP.SIDESTEP, OperationToInsert.Machining.Steps.dSideStep) + end + end + + if OperationToInsert.Machining.dStartPos then + EgtSetMachiningParam( MCH_MP.STARTPOS, OperationToInsert.Machining.dStartPos) + end + if OperationToInsert.Machining.dReturnPos then + EgtSetMachiningParam( MCH_MP.RETURNPOS, OperationToInsert.Machining.dReturnPos) + end + + if OperationToInsert.Machining.dRadialOffset then + EgtSetMachiningParam( MCH_MP.OFFSR, OperationToInsert.Machining.dRadialOffset) + end + if OperationToInsert.Machining.dLongitudinalOffset then + EgtSetMachiningParam( MCH_MP.OFFSL, OperationToInsert.Machining.dLongitudinalOffset) + end + + -- paraemtri attacco + if OperationToInsert.Machining.LeadIn then + if OperationToInsert.Machining.LeadIn.nType then + EgtSetMachiningParam( MCH_MP.LEADINTYPE, OperationToInsert.Machining.LeadIn.nType) + end + if OperationToInsert.Machining.LeadIn.dStartAddLength then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, OperationToInsert.Machining.LeadIn.dStartAddLength) + end + if OperationToInsert.Machining.LeadIn.dTangentDistance then + EgtSetMachiningParam( MCH_MP.LITANG, OperationToInsert.Machining.LeadIn.dTangentDistance) + end + if OperationToInsert.Machining.LeadIn.dPerpDistance then + EgtSetMachiningParam( MCH_MP.LIPERP, OperationToInsert.Machining.LeadIn.dPerpDistance) + end + if OperationToInsert.Machining.LeadIn.dElevation then + EgtSetMachiningParam( MCH_MP.LIELEV, OperationToInsert.Machining.LeadIn.dElevation) + end + if OperationToInsert.Machining.LeadIn.dCompLength then + EgtSetMachiningParam( MCH_MP.LICOMPLEN, OperationToInsert.Machining.LeadIn.dCompLength) + end + end + -- parametri uscita + if OperationToInsert.Machining.LeadOut then + if OperationToInsert.Machining.LeadOut.nType then + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, OperationToInsert.Machining.LeadOut.nType) + end + if OperationToInsert.Machining.LeadOut.dEndAddLength then + EgtSetMachiningParam( MCH_MP.ENDADDLEN, OperationToInsert.Machining.LeadOut.dEndAddLength) + end + if OperationToInsert.Machining.LeadOut.dTangentDistance then + EgtSetMachiningParam( MCH_MP.LOTANG, OperationToInsert.Machining.LeadOut.dTangentDistance) + end + if OperationToInsert.Machining.LeadOut.dPerpDistance then + EgtSetMachiningParam( MCH_MP.LOPERP, OperationToInsert.Machining.LeadOut.dPerpDistance) + end + if OperationToInsert.Machining.LeadOut.dElevation then + EgtSetMachiningParam( MCH_MP.LOELEV, OperationToInsert.Machining.LeadOut.dElevation) + end + if OperationToInsert.Machining.LeadOut.dCompLength then + EgtSetMachiningParam( MCH_MP.LOCOMPLEN, OperationToInsert.Machining.LeadOut.dCompLength) + end + end + + if OperationToInsert.Machining.dStartSlowLen then + EgtSetMachiningParam( MCH_MP.STARTSLOWLEN, OperationToInsert.Machining.dStartSlowLen) + end + if OperationToInsert.Machining.dEndSlowLen then + EgtSetMachiningParam( MCH_MP.ENDSLOWLEN, OperationToInsert.Machining.dEndSlowLen) + end + if OperationToInsert.Machining.dThrouAddLen then + EgtSetMachiningParam( MCH_MP.THROUADDLEN, OperationToInsert.Machining.dThrouAddLen) + end + + -- parametri da settare nelle note di sistema + -- TODO da decidere quali sono le note da salvare qui. Probabilmente tutte quelle relative all'ordine delle lavorazioni + local sSystemNotes = EgtGetMachiningParam( MCH_MP.SYSNOTES) + --if OperationToInsert.Machining.nMachiningOrder then + -- sSystemNotes = EgtSetValInNotes( sSystemNotes, 'MachiningOrder', OperationToInsert.Machining.nMachiningOrder) + --end + EgtSetMachiningParam( MCH_MP.SYSNOTES, sSystemNotes) + + -- parametri da settare nelle note utente + local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + if OperationToInsert.Machining.dMaxElev then + sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', OperationToInsert.Machining.dMaxElev) + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + + local bIsApplyOk = MachiningLib.ApplyMachining( true, false) + if not bIsApplyOk then + bAreAllMachiningApplyOk = false + nErr, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nOperationId, false) + end + return bIsApplyOk, sErr + else + return false, 'UNEXPECTED ERROR: Error on creating machining' end - return bAreAllMachiningApplyOk, sErr end ------------------------------------------------------------------------------------------------------------- diff --git a/CAMAuto/LuaLibs/WinExec.lua b/CAMAuto/LuaLibs/WinExec.lua index cc90529..7e32ba1 100644 --- a/CAMAuto/LuaLibs/WinExec.lua +++ b/CAMAuto/LuaLibs/WinExec.lua @@ -199,9 +199,8 @@ end -- *** Inserimento delle lavorazioni nelle travi *** ------------------------------------------------------------------------------------------------------------- -local function CollectFeatures( Part) +local function CollectFeatures( vProc, Part) -- recupero le feature - local vPartProc = {} local LayerId = {} LayerId[1] = WinLib.GetAddGroup( Part.id) LayerId[2] = EgtGetFirstNameInGroup( Part.id or GDB_ID.NULL, 'Processings') @@ -249,10 +248,10 @@ local function CollectFeatures( Part) end -- inserisco feature in lista - table.insert( vPartProc, Proc) + table.insert( vProc, Proc) else Proc.nFlg = 0 - table.insert( vPartProc, Proc) + table.insert( vProc, Proc) EgtOutLog( ' Feature ' .. tostring( Proc.idFeature) .. ' is empty (no geometry)') end end @@ -260,7 +259,7 @@ local function CollectFeatures( Part) ProcId = EgtGetNext( ProcId) end end - return vPartProc + return vProc end ------------------------------------------------------------------------------------------------------------- @@ -279,10 +278,6 @@ local function GetFeatureInfoAndDependency( vProc, Part) return vProc end -------------------------------------------------------------------------------------------------------------- -local function OrderMachining( vProc, PARTS) -end - ------------------------------------------------------------------------------------------------------------- -- Ordina le feature in base a fase di lavorazione -- L'ordine è indicativamente: @@ -292,54 +287,57 @@ end -- 4) Profili Lati -- 5) Incontri/scontri -- TODO Ordinamento da fare -local function OrderFeatures( vProc) - local vProcToSort = vProc - -- funzione di confronto. TRUE = B1 prima di B2. FALSE = B2 prima di B1 - local function CompareFeatures( B1, B2) - -- se secondo disabilitato, va lasciato dopo - if B1.nFlg ~= 0 and B2.nFlg == 0 then - return true - elseif B1.nPhase and B2.nPhase and B1.nPhase < B2.nPhase then - return true - elseif B1.nPhase and B2.nPhase and B2.nPhase < B1.nPhase then - return true - -- altrimenti si inverte - else - return false - end - end +local function OrderMachining( MACHININGS) - -- test della funzione di ordinamento - if EgtGetDebugLevel() >= 3 then - EgtOutLog( ' CompareFeatures Test ') - local bCompTest = true - for i = 1, #vProcToSort do - for j = i + 1, #vProcToSort do - local bComp1 = CompareFeatures( vProcToSort[i], vProcToSort[j]) - local bComp2 = CompareFeatures( vProcToSort[j], vProcToSort[i]) - if bComp1 == bComp2 then - bCompTest = false - EgtOutLog( string.format( ' ProcId : %d vs %d --> ERROR', vProcToSort[i].id, vProcToSort[j].id)) - end - end - end - if bCompTest then - EgtOutLog( ' ALL OK') - end - end - -- eseguo ordinamento - table.sort( vProcToSort, CompareFeatures) + -- local vProcToSort = vProc + -- -- funzione di confronto. TRUE = B1 prima di B2. FALSE = B2 prima di B1 + -- local function CompareFeatures( B1, B2) + -- -- se secondo disabilitato, va lasciato dopo + -- if B1.nFlg ~= 0 and B2.nFlg == 0 then + -- return true + -- elseif B1.nPhase and B2.nPhase and B1.nPhase < B2.nPhase then + -- return true + -- elseif B1.nPhase and B2.nPhase and B2.nPhase < B1.nPhase then + -- return true + -- -- altrimenti si inverte + -- else + -- return false + -- end + -- end - return vProcToSort + -- -- test della funzione di ordinamento + -- if EgtGetDebugLevel() >= 3 then + -- EgtOutLog( ' CompareFeatures Test ') + -- local bCompTest = true + -- for i = 1, #vProcToSort do + -- for j = i + 1, #vProcToSort do + -- local bComp1 = CompareFeatures( vProcToSort[i], vProcToSort[j]) + -- local bComp2 = CompareFeatures( vProcToSort[j], vProcToSort[i]) + -- if bComp1 == bComp2 then + -- bCompTest = false + -- EgtOutLog( string.format( ' ProcId : %d vs %d --> ERROR', vProcToSort[i].id, vProcToSort[j].id)) + -- end + -- end + -- end + -- if bCompTest then + -- EgtOutLog( ' ALL OK') + -- end + -- end + + -- -- eseguo ordinamento + -- table.sort( vProcToSort, CompareFeatures) + + return true end ------------------------------------------------------------------------------------------------------------- -- applica le lavorazioni -local function AddMachinings( ProcPart, Part) +local function AddMachinings( vProc, PARTS) local bMachiningOk = true - for nFeatureIndex = 1, #ProcPart do - local Proc = ProcPart[nFeatureIndex] + for nFeatureIndex = 1, #vProc do + local Proc = vProc[nFeatureIndex] + local Part = PARTS[vProc[nFeatureIndex].nIndexPiece] if ID.IsDrilling( Proc) then bMachiningOk = Drilling.Make( Proc, Part) end @@ -364,8 +362,12 @@ local function AddMachinings( ProcPart, Part) end ------------------------------------------------------------------------------------------------------------- -local function PrintFeatures( vProc, Part) - EgtOutLog( ' RawBox=' .. tostring( Part.RawBox)) +local function PrintFeatures( vProc, PARTS) + EgtOutLog( ' === PARTS ====') + for i = 1, #PARTS do + EgtOutLog( ' RawBox(' .. tostring( i) .. ') =' .. tostring( PARTS[i].RawBox)) + end + EgtOutLog( ' === FEATURES ====') for i = 1, #vProc do local Proc = vProc[i] local sOut = string.format( 'Id=%3d Flg=%2d Type=%s', Proc.id, Proc.nFlg, Proc.sType) @@ -378,45 +380,51 @@ function WinExec.ProcessFeatures( PARTS) -- ciclo sui pezzi local nTotErr = 0 local Stats = {} - local nOrd = 1 - local Part = {} - local vProc = {} + MACHININGS = {} + + -- si recuperano tutte le feature di tutti i pezzi in una lista unica for nPart = 1, #PARTS do - -- lista contenente le feature da eseguire - -- recupero le feature di lavorazione della trave - table.insert( vProc, CollectFeatures( PARTS[nPart])) - + vProc = CollectFeatures( vProc, PARTS[nPart]) + -- recupero informazioni ausiliarie feature e dipendenze tra feature stesse - vProc[nPart] = GetFeatureInfoAndDependency( vProc[nPart], PARTS[nPart]) - - -- debug - if EgtGetDebugLevel() >= 1 then - PrintFeatures( vProc[nPart], PARTS[nPart]) - end - - -- ordino le features - vProc[nPart] = OrderFeatures( vProc[nPart]) - - EgtOutLog( ' *** AddMachinings ***', 1) - - -- TODO da fare - MACHININGS = {} - -- esegue le strategie migliori che ha precedentemente scelto e salva le lavorazioni nella lista globale - AddMachinings( vProc[nPart], PARTS[nPart]) - - - EgtOutLog( ' *** End AddMachinings ***', 1) - -- passo al grezzo successivo - nOrd = nOrd + 1 + vProc = GetFeatureInfoAndDependency( vProc, PARTS[nPart]) end - OrderMachining( vProc, PARTS) + -- debug + if EgtGetDebugLevel() >= 1 then + PrintFeatures( vProc, PARTS) + end + + EgtOutLog( ' *** AddMachinings ***', 1) + + -- esegue le lavorazioni e le salva in lista + AddMachinings( vProc, PARTS) + + -- ordina le lavorazioni + OrderMachining( MACHININGS) + + -- scrivo lavorazioni prima fase + EgtSetCurrPhase( 1) + for i = 1, #MACHININGS do + if MACHININGS[i].AuxInfo.nPhase == 1 then + -- aggiunge effettivamente la lavorazione + MachiningLib.AddOperation( MACHININGS[i]) + end + end + + -- scrivo lavorazioni prima fase + EgtSetCurrPhase( 2) + for i = 1, #MACHININGS do + if MACHININGS[i].AuxInfo.nPhase == 2 then + -- aggiunge effettivamente la lavorazione + MachiningLib.AddOperation( MACHININGS[i]) + end + end + + EgtOutLog( ' *** End AddMachinings ***', 1) - -- aggiunge effettivamente le lavorazioni - MachiningLib.AddOperations( vProc, PARTS) - -- Aggiornamento finale di tutto EgtSetCurrPhase( 1) local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings() diff --git a/CAMAuto/ProcessWin.lua b/CAMAuto/ProcessWin.lua index c8c2aa8..fe9f67f 100644 --- a/CAMAuto/ProcessWin.lua +++ b/CAMAuto/ProcessWin.lua @@ -102,7 +102,8 @@ local function MyProcessInputData() for i = 1, #PARTS do PARTS[i].b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Solid') or GDB_ID.NULL, GDB_BB.STANDARD) PARTS[i].b3FinishedPiece = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Geo') or GDB_ID.NULL, GDB_BB.STANDARD) - PARTS[i].frame = EgtFR( EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Geo'), 'Frame')) + local idFrame = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Geo'), 'AuxFrame') or EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Geo'), 'Frame') + PARTS[i].frame = EgtFR( idFrame) sOut = sOut .. PARTS[i].sName .. ', ' end sOut = sOut:sub( 1, -3) diff --git a/CAMAuto/Strategies/Profiling.lua b/CAMAuto/Strategies/Profiling.lua index ea7d97f..6d913c3 100644 --- a/CAMAuto/Strategies/Profiling.lua +++ b/CAMAuto/Strategies/Profiling.lua @@ -17,14 +17,15 @@ EgtMdbSave() ------------------------------------------------------------------------------------------------------------- function Profiling.Make( Proc, Part) local ToolInfo = {} - local Machining = {} - Machining.LeadIn = {} - Machining.LeadOut = {} - Machining.Steps = {} -- se so che utensili utilizzare, associazione diretta if Proc.nToolsToUse then for i = 1, Proc.nToolsToUse do + local Machining = {} + local AuxInfo = {} + Machining.LeadIn = {} + Machining.LeadOut = {} + Machining.Steps = {} local ToolSearchParameters = {} ToolSearchParameters.sName = Proc.Tools[i].sName ToolSearchParameters.dElevation = 0 @@ -44,7 +45,8 @@ function Profiling.Make( Proc, Part) Machining.LeadOut.dTangentDistance = TOOLS[ToolInfo.nToolIndex].dDiameter Machining.LeadOut.dPerpDistance = 0 Machining.Geometry = Proc.id - MachiningLib.AddNewMachining( Proc, Machining) + AuxInfo.nPhase = MachiningLib.GetPhaseMach( Proc) + MachiningLib.AddNewMachining( Proc, Machining, AuxInfo) else return false, 'Tool not found' end From 93e1a56e296053a97a36abb19da0654ab8378d3d Mon Sep 17 00:00:00 2001 From: SaraP Date: Fri, 21 Jun 2024 15:06:41 +0200 Subject: [PATCH 08/10] - corretta la direzione dei fori. --- Profiles/WinLib/WinCalculate.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Profiles/WinLib/WinCalculate.lua b/Profiles/WinLib/WinCalculate.lua index 0562310..c7ab79b 100644 --- a/Profiles/WinLib/WinCalculate.lua +++ b/Profiles/WinLib/WinCalculate.lua @@ -1118,8 +1118,8 @@ local function AddStartDowels( nOutlineId, nPrevOutlineId, nProfileLayerId, nDow EgtTransform( nDowelId, frOrig, GDB_RT.GLOB) EgtTransform( nDowelId, frDest, GDB_RT.GLOB) EgtMove( nDowelId, dStart * vtRef) - EgtModifyCurveExtrusion( nDowelId, vtRef) - EgtModifyCurveThickness( nDowelId, dEnd - dStart) + EgtModifyCurveExtrusion( nDowelId, - vtRef) + EgtModifyCurveThickness( nDowelId, - ( dEnd - dStart)) -- setto info di lavorazione EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE) @@ -1192,8 +1192,8 @@ local function AddStartDowels( nOutlineId, nPrevOutlineId, nProfileLayerId, nDow EgtTransform( nDowelId, frOrig) EgtTransform( nDowelId, frDest) EgtMove( nDowelId, vtRef * dStart) - EgtModifyCurveExtrusion( nDowelId, vtRef) - EgtModifyCurveThickness( nDowelId, dEnd - dStart) + EgtModifyCurveExtrusion( nDowelId, - vtRef) + EgtModifyCurveThickness( nDowelId, - ( dEnd - dStart)) -- setto info di lavorazione EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE) @@ -1258,8 +1258,8 @@ local function AddEndDowels( nOutlineId, nEndOutlineId, nProfileLayerId, nDowelL EgtTransform( nDowelId, frOrig) EgtTransform( nDowelId, frDest) EgtMove( nDowelId, - vtRef * dStart) - EgtModifyCurveExtrusion( nDowelId, - vtRef) - EgtModifyCurveThickness( nDowelId, dEnd - dStart) + EgtModifyCurveExtrusion( nDowelId, vtRef) + EgtModifyCurveThickness( nDowelId, - ( dEnd - dStart)) -- setto info di lavorazione EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE) @@ -1331,8 +1331,8 @@ local function AddEndDowels( nOutlineId, nEndOutlineId, nProfileLayerId, nDowelL EgtTransform( nDowelId, frOrig, GDB_RT.GLOB) EgtTransform( nDowelId, frDest, GDB_RT.GLOB) EgtMove( nDowelId, - vtRef * dStart) - EgtModifyCurveExtrusion( nDowelId, - vtRef) - EgtModifyCurveThickness( nDowelId, dEnd - dStart) + EgtModifyCurveExtrusion( nDowelId, vtRef) + EgtModifyCurveThickness( nDowelId, - ( dEnd - dStart)) -- setto info di lavorazione EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE) @@ -1447,8 +1447,8 @@ local function CalSplitDowel( nSplitLayerId, nOutlineId, nProfileType, nPartId) -- posiziono il dowel e gli assegno estrusione e spessore EgtMove( nDowelId, vtDowelDir * dStart) - EgtModifyCurveExtrusion( nDowelId, vtDowelDir) - EgtModifyCurveThickness( nDowelId, dEnd - dStart) + EgtModifyCurveExtrusion( nDowelId, - vtDowelDir) + EgtModifyCurveThickness( nDowelId, - ( dEnd - dStart)) -- setto info di lavorazione EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE) From 28e38b0441650745773f9bcf1e8fcffc162ce9d4 Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Fri, 21 Jun 2024 17:15:37 +0200 Subject: [PATCH 09/10] - Lavorazione profili nella fase opportuna - Migliorie varie --- .vscode/settings.json | 13 ++++++- CAMAuto/LuaLibs/FeatureData.lua | 8 ++-- CAMAuto/LuaLibs/Identity.lua | 14 +++++++ CAMAuto/LuaLibs/MachiningLib.lua | 24 +++++++++++- CAMAuto/LuaLibs/WinExec.lua | 64 +++++++++++++++++++++++++------ CAMAuto/ProcessWin.lua | 66 ++++++++++++++------------------ 6 files changed, 135 insertions(+), 54 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 1cd0e3e..f1ae223 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -124,7 +124,18 @@ "EgtApplyMachining", "EgtSetCurrPhase", "EgtApplyAllMachinings", - "EgtGetDebugLevel" + "EgtGetDebugLevel", + "EgtTdbGetCurrToolParam", + "EgtTdbGetCurrToolThDiam", + "EgtTdbGetCurrToolMaxDepth", + "EgtTdbGetCurrToolThLength", + "EgtFindToolInCurrSetup", + "EgtTdbGetFirstTool", + "EgtTdbGetNextTool", + "EgtMdbSave", + "EgtMoveRawPart", + "EgtCurveThickness", + "EgtSetCurrMachining" ], "Lua.diagnostics.disable": [ "empty-block" diff --git a/CAMAuto/LuaLibs/FeatureData.lua b/CAMAuto/LuaLibs/FeatureData.lua index 5f757a3..3c831a2 100644 --- a/CAMAuto/LuaLibs/FeatureData.lua +++ b/CAMAuto/LuaLibs/FeatureData.lua @@ -37,7 +37,7 @@ end ------------------------------------------------------------------------------------------------------------- -- Recupero dati foro function FeatureData.GetMillingData( Proc) - + return Proc end @@ -46,16 +46,18 @@ end function FeatureData.GetProfilingData( Proc) -- recupero utensili Proc.nToolsToUse = EgtGetInfo( Proc.id, 'NTOOLS', 'i') or 0 + Proc.sEntityName = EgtGetInfo( Proc.id, 'N', 's') or nil + Proc.bHeadProfile = Proc.sEntityName == 'Left' or Proc.sEntityName == 'Right' + Proc.bSideProfile = Proc.sEntityName == 'In' or Proc.sEntityName == 'Out' Proc.Tools = {} for t = 1, Proc.nToolsToUse do local Data = {} Data.sName = EgtGetInfo( Proc.id, 'TOOL_NAME_' .. tostring(t), 's') or 0 Data.dRadialOffset = EgtGetInfo( Proc.id, 'OFFR_' .. tostring(t), 'd') or 0 Data.dLongitudinalOffset = EgtGetInfo( Proc.id, 'OFFL_' .. tostring(t), 'd') or 0 - Data.sSide = EgtGetInfo( Proc.id, 'N', 's') or 0 table.insert( Proc.Tools, Data) end - + Proc.ProfileType = EgtGetInfo( Proc.id, 'ProfileType', 's') or '' return Proc end diff --git a/CAMAuto/LuaLibs/Identity.lua b/CAMAuto/LuaLibs/Identity.lua index 8955f9c..5437b11 100644 --- a/CAMAuto/LuaLibs/Identity.lua +++ b/CAMAuto/LuaLibs/Identity.lua @@ -32,5 +32,19 @@ function Identity.IsProfiling( Proc) return Proc.sType == 'Profiling' end +--------------------------------------------------------------------- +----------------------------- PIECES ------------------------------ +--------------------------------------------------------------------- +function Identity.GetPieceIndexPart( PARTS, idGeom) + local nIndexPart + for i = 1, #PARTS do + if PARTS[i].id == idGeom then + nIndexPart = i + break + end + end + return nIndexPart +end + --------------------------------------------------------------------- return Identity diff --git a/CAMAuto/LuaLibs/MachiningLib.lua b/CAMAuto/LuaLibs/MachiningLib.lua index 106c215..133519d 100644 --- a/CAMAuto/LuaLibs/MachiningLib.lua +++ b/CAMAuto/LuaLibs/MachiningLib.lua @@ -9,6 +9,7 @@ require( 'EgtBase') -- Carico i dati globali local WinData = require( 'WinData') +local ID = require( 'Identity') EgtOutLog( ' MachiningLib started', 1) @@ -125,14 +126,24 @@ function MachiningLib.FindDrill() end ------------------------------------------------------------------------------------------------------------- --- funzione per cercare utensile tipo PUNTA A FORARE con certe caratteristiche +-- funzione che ritorna fase di lavoro function MachiningLib.GetPhaseMach( Proc) local nPhase + -- se info già calcolata if Proc.nPhase then nPhase = Proc.nPhase + -- altrimenti si calcola il comportamento standard + else + if Proc.sEntityName == 'Left' or Proc.sEntityName == 'Out' then + nPhase = 1 + end + if Proc.sEntityName == 'Right' or Proc.sEntityName == 'In' then + nPhase = 2 + end end return nPhase end + ------------------------------------------------------------------------------------------------------------- -- salva in lista globale la lavorazione appena calcolata function MachiningLib.AddNewMachining( ProcToAdd, MachiningToAdd, AuxInfoToAdd) @@ -183,6 +194,7 @@ function MachiningLib.AddOperation( OperationToInsert) -- creazione lavorazione local nOperationId = EgtCreateMachining( OperationToInsert.Machining.sOperationName, OperationToInsert.Machining.nType, OperationToInsert.Machining.sToolName) + EgtSetCurrMachining( nOperationId) if nOperationId then -- impostazione geometria @@ -318,13 +330,21 @@ function MachiningLib.AddOperation( OperationToInsert) end EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + local b3MachEncumbrance = nil local bIsApplyOk = MachiningLib.ApplyMachining( true, false) if not bIsApplyOk then bAreAllMachiningApplyOk = false nErr, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nOperationId, false) + else + local nClId = EgtGetFirstNameInGroup( nOperationId, 'CL') + local ptMin = EgtGetInfo( nClId, 'MMIN', 'p') + local ptMax = EgtGetInfo( nClId, 'MMAX', 'p') + -- box percorso lavorazione + b3MachEncumbrance = BBox3d( ptMin, ptMax) end - return bIsApplyOk, sErr + + return bIsApplyOk, sErr, b3MachEncumbrance else return false, 'UNEXPECTED ERROR: Error on creating machining' end diff --git a/CAMAuto/LuaLibs/WinExec.lua b/CAMAuto/LuaLibs/WinExec.lua index 7e32ba1..786f8c8 100644 --- a/CAMAuto/LuaLibs/WinExec.lua +++ b/CAMAuto/LuaLibs/WinExec.lua @@ -272,6 +272,9 @@ local function GetFeatureInfoAndDependency( vProc, Part) -- non si controlla la feature con se stessa if i ~= j then local ProcB = vProc[j] + -- TODO dipendenze da controllare : + -- * gruppo di forature con aggregato 2/3 uscite + -- * Se 'Left' e 'Out' hanno stesso profilo, vanno concatenati (anche 'Right' se consentito dalle dimensioni) end end end @@ -281,12 +284,14 @@ end ------------------------------------------------------------------------------------------------------------- -- Ordina le feature in base a fase di lavorazione -- L'ordine è indicativamente: --- 1) Fori --- 2) Scassi serratura/maniglia --- 3) Profili testa --- 4) Profili Lati --- 5) Incontri/scontri +-- 1) Tagli di testa +-- 2) Fori +-- 3) Scassi serratura/maniglia +-- 4) Profili testa +-- 5) Profili longitudinali +-- 6) Incontri/scontri -- TODO Ordinamento da fare + local function OrderMachining( MACHININGS) @@ -375,6 +380,11 @@ local function PrintFeatures( vProc, PARTS) end end +------------------------------------------------------------------------------------------------------------- +local function CheckAndMovePawPart( nIdRawToMove, vtMove) + EgtMoveRawPart( nIdRawToMove, vtMove) +end + ------------------------------------------------------------------------------------------------------------- function WinExec.ProcessFeatures( PARTS) -- ciclo sui pezzi @@ -387,8 +397,8 @@ function WinExec.ProcessFeatures( PARTS) for nPart = 1, #PARTS do -- recupero le feature di lavorazione della trave vProc = CollectFeatures( vProc, PARTS[nPart]) - - -- recupero informazioni ausiliarie feature e dipendenze tra feature stesse + + -- recupero informazioni ausiliarie feature e dipendenze tra feature dello stesso pezzo vProc = GetFeatureInfoAndDependency( vProc, PARTS[nPart]) end @@ -409,17 +419,49 @@ function WinExec.ProcessFeatures( PARTS) EgtSetCurrPhase( 1) for i = 1, #MACHININGS do if MACHININGS[i].AuxInfo.nPhase == 1 then - -- aggiunge effettivamente la lavorazione - MachiningLib.AddOperation( MACHININGS[i]) + -- aggiunge effettivamente la lavorazione e restituisce gli ingombri + local bIsApplyOk, sErr, b3MachEncumbrance = MachiningLib.AddOperation( MACHININGS[i]) -- TODO ingombro lavorazione mi restituisce dati sbagliati. C'è un riferimento? + -- se feature di testa, sposto testa in base a ingombro lavorazione + if MACHININGS[i].Proc.bHeadProfile and b3MachEncumbrance then + local nIndexPart = ID.GetPieceIndexPart( PARTS, MACHININGS[i].Proc.idPart) + PARTS[nIndexPart].DispOffsets.Phase1.dOffsetX = b3MachEncumbrance:getMax():getX() - PARTS[nIndexPart].b3FinishedPart:getMin():getX() + 5 + end end end - -- scrivo lavorazioni prima fase + -- TODO lo spostamento, oltre a controllare le collisioni con il profilo di testa, deve anche considerare il pinzaggio del pezzo nel suo insieme? + -- Es.: basterebbe aggiungere un offset di 50mm per la testa, ma se metto 60mm, posso utilizzare una morsa in più che altrimenti avrei dovuto togliere per una collisione con una svuotatura + + -- sposto pezzo per permettere pinzaggio migliore e non aver colisione in testa + for i = 1, #PARTS do + -- TODO Sbaglia a calcolare ingombro!! + --local vtMove = Vector3d( - PARTS[nIndexPart].DispOffsets.Phase1.dOffsetX, - PARTS[nIndexPart].DispOffsets.Phase1.dOffsetY, PARTS[nIndexPart].DispOffsets.Phase1.dOffsetZ) + local vtMove = Vector3d( -60, 0, 0) + if vtMove ~= V_NULL() then + CheckAndMovePawPart( PARTS[i].idRaw, vtMove) + end + end + + -- scrivo lavorazioni seconda fase EgtSetCurrPhase( 2) for i = 1, #MACHININGS do if MACHININGS[i].AuxInfo.nPhase == 2 then -- aggiunge effettivamente la lavorazione - MachiningLib.AddOperation( MACHININGS[i]) + local bIsApplyOk, sErr, b3MachEncumbrance = MachiningLib.AddOperation( MACHININGS[i]) -- TODO ingombro lavorazione mi restituisce dati sbagliati. C'è un riferimento? + -- se feature di testa, sposto testa in base a ingombro lavorazione + if MACHININGS[i].Proc.bHeadProfile and b3MachEncumbrance then + local nIndexPart = ID.GetPieceIndexPart( PARTS, MACHININGS[i].Proc.idPart) + PARTS[nIndexPart].DispOffsets.Phase1.dOffsetX = PARTS[nIndexPart].b3FinishedPart:getMax():getX() - b3MachEncumbrance:getMin():getX() + 5 + end + end + end + -- sposto pezzo per permettere pinzaggio migliore e non aver colisione in testa + for i = 1, #PARTS do + -- TODO Sbaglia a calcolare ingombro!! + -- local vtMove = Vector3d( PARTS[nIndexPart].DispOffsets.Phase2.dOffsetX, PARTS[nIndexPart].DispOffsets.Phase2.dOffsetY, PARTS[nIndexPart].DispOffsets.Phase2.dOffsetZ) + local vtMove = Vector3d( 60, 0, 0) + if vtMove ~= V_NULL() then + CheckAndMovePawPart( PARTS[i].idRaw, vtMove) end end diff --git a/CAMAuto/ProcessWin.lua b/CAMAuto/ProcessWin.lua index fe9f67f..848e826 100644 --- a/CAMAuto/ProcessWin.lua +++ b/CAMAuto/ProcessWin.lua @@ -43,24 +43,7 @@ _G.package.loaded.WinLib = nil _G.package.loaded.FeatureData = nil _G.package.loaded.MachiningLib = nil --- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente --- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento. --- Infatti difficile ci siano 9999 strategie. --- reset strategie caricate come librerie -for i = 1, 99 do - local IdSTRTemp = EgtReplaceString( tostring( i/10000, 4), '0.', '') - local sLibraryToReload = "STR" .. IdSTRTemp .. "\\STR" .. IdSTRTemp - local sLibraryConfigToReload = sLibraryToReload .. "Config" - if _G.package.loaded[sLibraryToReload] then - _G.package.loaded[sLibraryToReload] = nil - end - if _G.package.loaded[sLibraryConfigToReload] then - _G.package.loaded[sLibraryConfigToReload] = nil - end -end - local WinExec = require( 'WinExec') -local WinLib = require( 'WinLib') -- Carico i dati globali local WinData = require( 'WinData') @@ -101,7 +84,7 @@ local function MyProcessInputData() local sOut = '' for i = 1, #PARTS do PARTS[i].b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Solid') or GDB_ID.NULL, GDB_BB.STANDARD) - PARTS[i].b3FinishedPiece = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Geo') or GDB_ID.NULL, GDB_BB.STANDARD) + PARTS[i].b3FinishedPart = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[i].id, 'Geo') or GDB_ID.NULL, GDB_BB.STANDARD) local idFrame = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Geo'), 'AuxFrame') or EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Geo'), 'Frame') PARTS[i].frame = EgtFR( idFrame) sOut = sOut .. PARTS[i].sName .. ', ' @@ -124,20 +107,28 @@ local function GetDataConfig() return true end +------------------------------------------------------------------------------------------------------------- +local function UpdateRawPosition( PARTS) + for i = 1, #PARTS do + PARTS[i].b3FinishedPart = EgtGetBBoxGlob( PARTS[i].id or GDB_ID.NULL, GDB_BB.STANDARD) + PARTS[i].b3RawPart = EgtGetBBoxGlob( PARTS[i].idRaw or GDB_ID.NULL, GDB_BB.STANDARD) + end +end + ------------------------------------------------------------------------------------------------------------- local function GetDispOffsetFromNotes( nPieceIndex) local bAllOffsetsAreOk = false - PARTS[nPieceIndex].DispOffset.Phase1.dOffsetX = 0 -- dovrà essere calcolato in base alle lavorazioni - PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFY_1', 'd') - PARTS[nPieceIndex].DispOffset.Phase1.dOffsetZ = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFZ_1', 'd') - PARTS[nPieceIndex].DispOffset.Phase2.dOffsetX = 0 -- dovrà essere calcolato in base alle lavorazioni - PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFY_2', 'd') - PARTS[nPieceIndex].DispOffset.Phase2.dOffsetZ = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFZ_2', 'd') + PARTS[nPieceIndex].DispOffsets.Phase1.dOffsetX = 0 -- dovrà essere calcolato in base alle lavorazioni + PARTS[nPieceIndex].DispOffsets.Phase1.dOffsetY = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFY_1', 'd') + PARTS[nPieceIndex].DispOffsets.Phase1.dOffsetZ = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFZ_1', 'd') + PARTS[nPieceIndex].DispOffsets.Phase2.dOffsetX = 0 -- dovrà essere calcolato in base alle lavorazioni + PARTS[nPieceIndex].DispOffsets.Phase2.dOffsetY = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFY_2', 'd') + PARTS[nPieceIndex].DispOffsets.Phase2.dOffsetZ = EgtGetInfo( PARTS[nPieceIndex].id, 'OFFZ_2', 'd') -- controllo se tutti gli offset siano settati - if PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY and PARTS[nPieceIndex].DispOffset.Phase1.dOffsetZ and - PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY and PARTS[nPieceIndex].DispOffset.Phase2.dOffsetZ then + if PARTS[nPieceIndex].DispOffsets.Phase1.dOffsetY and PARTS[nPieceIndex].DispOffsets.Phase1.dOffsetZ and + PARTS[nPieceIndex].DispOffsets.Phase2.dOffsetY and PARTS[nPieceIndex].DispOffsets.Phase2.dOffsetZ then bAllOffsetsAreOk = true end @@ -147,10 +138,10 @@ end ------------------------------------------------------------------------------------------------------------- local function GetDispOffsetFromInput( nPieceIndex) -- assegno alle stringhe i valori letti, in modo che vengano proposti quelli nel dialogo - local sOffYPh1 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY, tostring( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY), tostring( PARTS[nPieceIndex].dPartWidth / 2)) - local sOffZPh1 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetZ, tostring( PARTS[nPieceIndex].DispOffset.Phase1.dOffsetZ), '0') - local sOffYPh2 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY, tostring( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY), tostring( PARTS[nPieceIndex].dPartWidth / 2)) - local sOffZPh2 = EgtIf( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetZ, tostring( PARTS[nPieceIndex].DispOffset.Phase2.dOffsetZ), '0') + local sOffYPh1 = EgtIf( PARTS[nPieceIndex].DispOffsets.Phase1.dOffsetY, tostring( PARTS[nPieceIndex].DispOffsets.Phase1.dOffsetY), tostring( PARTS[nPieceIndex].dPartWidth / 2)) + local sOffZPh1 = EgtIf( PARTS[nPieceIndex].DispOffsets.Phase1.dOffsetZ, tostring( PARTS[nPieceIndex].DispOffsets.Phase1.dOffsetZ), '0') + local sOffYPh2 = EgtIf( PARTS[nPieceIndex].DispOffsets.Phase2.dOffsetY, tostring( PARTS[nPieceIndex].DispOffsets.Phase2.dOffsetY), tostring( PARTS[nPieceIndex].dPartWidth / 2)) + local sOffZPh2 = EgtIf( PARTS[nPieceIndex].DispOffsets.Phase2.dOffsetZ, tostring( PARTS[nPieceIndex].DispOffsets.Phase2.dOffsetZ), '0') local vInp = EgtDialogBox( 'Dati di disposizione pezzo: ' .. PARTS[nPieceIndex].sName, {'Sporgenza laterale FASE1', sOffYPh1}, {'Posizione Z FASE1', sOffZPh1}, @@ -160,10 +151,10 @@ local function GetDispOffsetFromInput( nPieceIndex) end -- salvo input nei valori che utilizzerò dopo - PARTS[nPieceIndex].DispOffset.Phase1.dOffsetY = tonumber( vInp[1]) - PARTS[nPieceIndex].DispOffset.Phase1.dOffsetZ = tonumber( vInp[2]) - PARTS[nPieceIndex].DispOffset.Phase2.dOffsetY = tonumber( vInp[3]) - PARTS[nPieceIndex].DispOffset.Phase2.dOffsetZ = tonumber( vInp[4]) + PARTS[nPieceIndex].DispOffsets.Phase1.dOffsetY = tonumber( vInp[1]) + PARTS[nPieceIndex].DispOffsets.Phase1.dOffsetZ = tonumber( vInp[2]) + PARTS[nPieceIndex].DispOffsets.Phase2.dOffsetY = tonumber( vInp[3]) + PARTS[nPieceIndex].DispOffsets.Phase2.dOffsetZ = tonumber( vInp[4]) return true end @@ -280,9 +271,9 @@ local function MyProcessPieces() -- recupero offset per posizionamento for i = 1, #PARTS do - PARTS[i].DispOffset = {} - PARTS[i].DispOffset.Phase1 = {} - PARTS[i].DispOffset.Phase2 = {} + PARTS[i].DispOffsets = {} + PARTS[i].DispOffsets.Phase1 = {} + PARTS[i].DispOffsets.Phase2 = {} local bInsertedAllOffs = GetDispOffsetFromNotes( i) -- se non sono settati nelle note, li chiedo @@ -297,6 +288,7 @@ local function MyProcessPieces() -- si dispongono i pezzi sulla tavola WinData.ExecDisposition( PARTS) + UpdateRawPosition( PARTS) -- Impostazione dell'attrezzaggio di default -- TODO se lascio il campo vuoto non mi carica il default!!!!!!! From a72a2d906958d326b811a0d20fa7db882cbb1137 Mon Sep 17 00:00:00 2001 From: SaraP Date: Tue, 25 Jun 2024 16:48:52 +0200 Subject: [PATCH 10/10] - aggiunte funzioni per creare telai con forme non rettangolari - modifiche varie per gestire correttamente le nuove forme (prima versione). --- Profiles/Main.lua | 142 +++--- Profiles/WinConst.lua | 11 + Profiles/WinLib/WinCalculate.lua | 698 ++++++++++++++------------- Profiles/WinLib/WinCreate.lua | 265 +++++++--- Profiles/WinLib/WinManageProject.lua | 9 +- Profiles/WinProject.lua | 2 +- 6 files changed, 657 insertions(+), 470 deletions(-) diff --git a/Profiles/Main.lua b/Profiles/Main.lua index d13a35a..ea215d8 100644 --- a/Profiles/Main.lua +++ b/Profiles/Main.lua @@ -57,9 +57,17 @@ EgtNewFile() -- importo profilo prescelto WinCreate.ImportProfile( sProfilePath) --- creo telaio rettangolare +-- creo telaio generico local FrameJointType = WIN_JNT.FULL_H -local nFrameId = WinCreate.CreateFrame( WindowWidth, WindowHeight, FrameJointType, FrameJointType, FrameJointType, FrameJointType) + +local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPE.RECT, FrameJointType, FrameJointType, FrameJointType, FrameJointType, WindowWidth, WindowHeight) +-- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPE.CHAMFER_SIDE, FrameJointType, FrameJointType, FrameJointType, FrameJointType, WindowWidth, WindowHeight, WindowHeight + 500) +-- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPE.CHAMFER_SIDE, FrameJointType, FrameJointType, FrameJointType, FrameJointType, WindowWidth, WindowHeight + 500, WindowHeight) +-- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPE.CHAMFER, FrameJointType, FrameJointType, FrameJointType, FrameJointType, WindowWidth, WindowHeight, WindowHeight + 500) +-- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPE.ROUND_ARC, FrameJointType, FrameJointType, FrameJointType, FrameJointType, WindowWidth, WindowHeight) +-- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPE.SEGMENTAL_ARC, FrameJointType, FrameJointType, FrameJointType, FrameJointType, WindowWidth, WindowHeight, WindowHeight + 100) +-- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPE.POINTED_ARC, FrameJointType, FrameJointType, FrameJointType, FrameJointType, WindowWidth, WindowHeight, WindowHeight + 600) +-- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPE.TRG, FrameJointType, FrameJointType, WIN_JNT.ANGLED, WIN_JNT.ANGLED, WindowWidth, WindowHeight, 0) -- -- creo telaio generico -- local nDrawFramePartId = EgtGroup( GDB_ID.ROOT) @@ -71,23 +79,23 @@ local nFrameId = WinCreate.CreateFrame( WindowWidth, WindowHeight, FrameJointTyp -- --local nFrameTopId = EgtLine( nDrawFrameLayerId, Point3d( WindowWidth, WindowHeight, 0), Point3d( 0, WindowHeight, 0)) -- local nFrameLeftId = EgtLine( nDrawFrameLayerId, Point3d( 0, WindowHeight, 0), Point3d( 0, 0, 0)) -- local FrameJointType = WIN_JNT.ANGLED --- local nFrameId = WinCreate.CreateGenFrame( nFrameBottomId, nFrameRightId, nFrameTopId, nFrameLeftId, FrameJointType, FrameJointType, FrameJointType, FrameJointType) +-- local nFrameId = WinCreate.CreateGenFrame( {nFrameBottomId, nFrameRightId, nFrameTopId, nFrameLeftId}, FrameJointType, FrameJointType, FrameJointType, FrameJointType) ------------------------ Finestra vetro fisso ------------------------ --- -- aggiungo zoccolo --- WinCreate.AddBottomRail( nFrameId) --- -- aggiungo vetro --- local nFillId = WinCreate.AddFill( nFrameId, WIN_FILLTYPES.GLASS) +-- aggiungo zoccolo +WinCreate.AddBottomRail( nFrameId) +-- aggiungo vetro +local nFillId = WinCreate.AddFill( nFrameId, WIN_FILLTYPES.GLASS) ------------------------ Finestra vetro fisso con divisione orizzontale ------------------------ -- -- aggiungo zoccolo -- WinCreate.AddBottomRail( nFrameId) - +-- -- -- definisco prima divisione -- local nArea1Id, nArea2Id = WinCreate.AddSplit( nFrameId, WIN_SPLITORIENTATION.HORIZONTAL, WIN_MEASURE.ABSOLUT, WindowHeight / 2) - +-- -- -- aggiungo vetri -- local nFill1Id = WinCreate.AddFill( nArea1Id, WIN_FILLTYPES.GLASS) -- local nFill2Id = WinCreate.AddFill( nArea2Id, WIN_FILLTYPES.GLASS) @@ -96,10 +104,10 @@ local nFrameId = WinCreate.CreateFrame( WindowWidth, WindowHeight, FrameJointTyp -- -- aggiungo zoccolo -- WinCreate.AddBottomRail( nFrameId) - +-- -- -- definisco prima divisione -- local nArea1Id, nArea2Id = WinCreate.AddSplit( nFrameId, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 2) - +-- -- -- aggiungo vetri -- local nFill1Id = WinCreate.AddFill( nArea1Id, WIN_FILLTYPES.GLASS) -- local nFill2Id = WinCreate.AddFill( nArea2Id, WIN_FILLTYPES.GLASS) @@ -108,36 +116,36 @@ local nFrameId = WinCreate.CreateFrame( WindowWidth, WindowHeight, FrameJointTyp -- -- aggiungo zoccolo -- WinCreate.AddBottomRail( nFrameId) - +-- -- -- definisco divisioni -- local nArea1Id, nArea2Id = WinCreate.AddSplit( nFrameId, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 2) -- local nArea11Id, nArea12Id = WinCreate.AddSplit( nArea1Id, WIN_SPLITORIENTATION.HORIZONTAL, WIN_MEASURE.ABSOLUT, WindowHeight / 2) -- local nArea21Id, nArea22Id = WinCreate.AddSplit( nArea2Id, WIN_SPLITORIENTATION.HORIZONTAL, WIN_MEASURE.ABSOLUT, WindowHeight / 2) - +-- -- -- aggiungo vetri -- local nFill1Id = WinCreate.AddFill( nArea11Id, WIN_FILLTYPES.GLASS) -- local nFill2Id = WinCreate.AddFill( nArea12Id, WIN_FILLTYPES.GLASS) -- local nFill3Id = WinCreate.AddFill( nArea21Id, WIN_FILLTYPES.GLASS) -- local nFill4Id = WinCreate.AddFill( nArea22Id, WIN_FILLTYPES.GLASS) --- ------------------------ Finestra anta singola ------------------------ +------------------------ Finestra anta singola ------------------------ --- aggiungo anta -local SashJointType = WIN_JNT.FULL_V -local nSashId = WinCreate.AddSash( nFrameId, SashJointType, SashJointType, SashJointType, SashJointType) - --- aggiungo vetro -local nFillId = WinCreate.AddFill( nSashId, WIN_FILLTYPES.GLASS) +-- -- aggiungo anta +-- local SashJointType = WIN_JNT.FULL_V +-- local nSashId = WinCreate.AddSash( nFrameId, SashJointType, SashJointType, SashJointType, SashJointType) +-- +-- -- aggiungo vetro +-- local nFillId = WinCreate.AddFill( nSashId, WIN_FILLTYPES.GLASS) ------------------------ Finestra anta singola con divisione orizzontale ------------------------ -- -- aggiungo anta -- local SashJointType = WIN_JNT.FULL_V -- local nSashId = WinCreate.AddSash( nFrameId, SashJointType, SashJointType, SashJointType, SashJointType) - +-- -- -- definisco prima divisione -- local nArea1Id, nArea2Id = WinCreate.AddSplit( nSashId, WIN_SPLITORIENTATION.HORIZONTAL, WIN_MEASURE.ABSOLUT, WindowHeight / 3) - +-- -- -- aggiungo vetri -- local nFill1Id = WinCreate.AddFill( nArea1Id, WIN_FILLTYPES.GLASS) -- local nFill2Id = WinCreate.AddFill( nArea2Id, WIN_FILLTYPES.GLASS) @@ -147,10 +155,10 @@ local nFillId = WinCreate.AddFill( nSashId, WIN_FILLTYPES.GLASS) -- -- aggiungo anta -- local SashJointType = WIN_JNT.FULL_V -- local nSashId = WinCreate.AddSash( nFrameId, SashJointType, SashJointType, SashJointType, SashJointType) - +-- -- -- definisco prima divisione -- local nArea1Id, nArea2Id = WinCreate.AddSplit( nSashId, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 2) - +-- -- -- aggiungo vetri -- local nFill1Id = WinCreate.AddFill( nArea1Id, WIN_FILLTYPES.GLASS) -- local nFill2Id = WinCreate.AddFill( nArea2Id, WIN_FILLTYPES.GLASS) @@ -160,12 +168,12 @@ local nFillId = WinCreate.AddFill( nSashId, WIN_FILLTYPES.GLASS) -- -- aggiungo anta -- local SashJointType = WIN_JNT.FULL_V -- local nSashId = WinCreate.AddSash( nFrameId, SashJointType, SashJointType, SashJointType, SashJointType) - +-- -- -- definisco divisioni -- local nArea1Id, nArea2Id = WinCreate.AddSplit( nSashId, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 2) -- local nArea11Id, nArea12Id = WinCreate.AddSplit( nArea1Id, WIN_SPLITORIENTATION.HORIZONTAL, WIN_MEASURE.ABSOLUT, WindowHeight / 2) -- local nArea21Id, nArea22Id = WinCreate.AddSplit( nArea2Id, WIN_SPLITORIENTATION.HORIZONTAL, WIN_MEASURE.ABSOLUT, WindowHeight / 2) - +-- -- -- aggiungo vetri -- local nFill1Id = WinCreate.AddFill( nArea11Id, WIN_FILLTYPES.GLASS) -- local nFill2Id = WinCreate.AddFill( nArea12Id, WIN_FILLTYPES.GLASS) @@ -198,17 +206,17 @@ local nFillId = WinCreate.AddFill( nSashId, WIN_FILLTYPES.GLASS) -- -- definisco prima divisione -- local nArea1Id, nArea2Id = WinCreate.AddSplit( nFrameId, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 2) - +-- -- -- aggiungo prima anta -- local SashJointType = WIN_JNT.FULL_V -- local nSash1Id = WinCreate.AddSash( nArea1Id, SashJointType, SashJointType, SashJointType, SashJointType) - +-- -- -- aggiungo vetro -- local nFill1Id = WinCreate.AddFill( nSash1Id, WIN_FILLTYPES.GLASS) - +-- -- -- aggiungo seconda anta -- local nSash2Id = WinCreate.AddSash( nArea2Id, SashJointType, SashJointType, SashJointType, SashJointType) - +-- -- -- aggiungo vetro -- local nFill2Id = WinCreate.AddFill( nSash2Id, WIN_FILLTYPES.GLASS) @@ -216,17 +224,17 @@ local nFillId = WinCreate.AddFill( nSashId, WIN_FILLTYPES.GLASS) -- -- definisco prima divisione -- local nArea1Id, nArea2Id = WinCreate.AddSplit( nFrameId, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 2, _, WIN_SPLITTYPES.FRENCH) - +-- -- -- aggiungo prima anta -- local SashJointType = WIN_JNT.FULL_V -- local nSash1Id = WinCreate.AddSash( nArea1Id, SashJointType, SashJointType, SashJointType, SashJointType, WIN_SASHTYPES.INACTIVE) - +-- -- -- aggiungo vetro -- local nFill1Id = WinCreate.AddFill( nSash1Id, WIN_FILLTYPES.GLASS) - +-- -- -- aggiungo seconda anta -- local nSash2Id = WinCreate.AddSash( nArea2Id, SashJointType, SashJointType, SashJointType, SashJointType, WIN_SASHTYPES.ACTIVE) - +-- -- -- aggiungo vetro -- local nFill2Id = WinCreate.AddFill( nSash2Id, WIN_FILLTYPES.GLASS) @@ -251,27 +259,27 @@ local nFillId = WinCreate.AddFill( nSashId, WIN_FILLTYPES.GLASS) ------------------------ Finestra tripla anta con montanti verticali ------------------------ -- -- definisco prima divisione --- local nArea1Id, nArea2Id = WinCreate.AddSplit( nFrameId, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 3) - +-- local nArea1Id, nArea0Id = WinCreate.AddSplit( nFrameId, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 3) +-- -- -- definisco seconda divisione --- local nArea2Id, nArea3Id = WinCreate.AddSplit( nArea2Id, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 3) - +-- local nArea2Id, nArea3Id = WinCreate.AddSplit( nArea0Id, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 3) +-- -- -- aggiungo prima anta -- local SashJointType = WIN_JNT.FULL_V -- local nSash1Id = WinCreate.AddSash( nArea1Id, SashJointType, SashJointType, SashJointType, SashJointType) - +-- -- -- aggiungo vetro -- local nFill1Id = WinCreate.AddFill( nSash1Id, WIN_FILLTYPES.GLASS) - +-- -- -- aggiungo seconda anta -- local nSash2Id = WinCreate.AddSash( nArea2Id, SashJointType, SashJointType, SashJointType, SashJointType) - +-- -- -- aggiungo vetro -- local nFill2Id = WinCreate.AddFill( nSash2Id, WIN_FILLTYPES.GLASS) - +-- -- -- aggiungo terza anta -- local nSash3Id = WinCreate.AddSash( nArea3Id, SashJointType, SashJointType, SashJointType, SashJointType) - +-- -- -- aggiungo vetro -- local nFill3Id = WinCreate.AddFill( nSash3Id, WIN_FILLTYPES.GLASS) @@ -307,27 +315,27 @@ local nFillId = WinCreate.AddFill( nSashId, WIN_FILLTYPES.GLASS) ------------------------ Finestra tripla anta con montante verticale e ante battente e ricevente ------------------------ -- -- definisco prima divisione --- local nArea1Id, nArea2Id = WinCreate.AddSplit( nFrameId, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 3) - +-- local nArea1Id, nArea0Id = WinCreate.AddSplit( nFrameId, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 3) +-- -- -- definisco seconda divisione --- local nArea2Id, nArea3Id = WinCreate.AddSplit( nArea2Id, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 3, _, WIN_SPLITTYPES.FRENCH) - +-- local nArea2Id, nArea3Id = WinCreate.AddSplit( nArea0Id, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 3, _, WIN_SPLITTYPES.FRENCH) +-- -- -- aggiungo prima anta -- local SashJointType = WIN_JNT.FULL_V -- local nSash1Id = WinCreate.AddSash( nArea1Id, SashJointType, SashJointType, SashJointType, SashJointType) - +-- -- -- aggiungo vetro -- local nFill1Id = WinCreate.AddFill( nSash1Id, WIN_FILLTYPES.GLASS) - +-- -- -- aggiungo seconda anta -- local nSash2Id = WinCreate.AddSash( nArea2Id, SashJointType, SashJointType, SashJointType, SashJointType, WIN_SASHTYPES.INACTIVE) - +-- -- -- aggiungo vetro -- local nFill2Id = WinCreate.AddFill( nSash2Id, WIN_FILLTYPES.GLASS) - +-- -- -- aggiungo terza anta -- local nSash3Id = WinCreate.AddSash( nArea3Id, SashJointType, SashJointType, SashJointType, SashJointType, WIN_SASHTYPES.ACTIVE) - +-- -- -- aggiungo vetro -- local nFill3Id = WinCreate.AddFill( nSash3Id, WIN_FILLTYPES.GLASS) @@ -335,26 +343,26 @@ local nFillId = WinCreate.AddFill( nSashId, WIN_FILLTYPES.GLASS) -- -- definisco prima divisione -- local nArea1Id, nArea2Id = WinCreate.AddSplit( nFrameId, WIN_SPLITORIENTATION.HORIZONTAL, WIN_MEASURE.ABSOLUT, WindowHeight / 3) - +-- -- -- definisco seconda divisione -- local nArea2Id, nArea3Id = WinCreate.AddSplit( nArea2Id, WIN_SPLITORIENTATION.HORIZONTAL, WIN_MEASURE.ABSOLUT, WindowHeight / 3) - +-- -- -- aggiungo prima anta -- local SashJointType = WIN_JNT.FULL_V -- local nSash1Id = WinCreate.AddSash( nArea1Id, SashJointType, SashJointType, SashJointType, SashJointType) - +-- -- -- aggiungo vetro -- local nFill1Id = WinCreate.AddFill( nSash1Id, WIN_FILLTYPES.GLASS) - +-- -- -- aggiungo seconda anta -- local nSash2Id = WinCreate.AddSash( nArea2Id, SashJointType, SashJointType, SashJointType, SashJointType) - +-- -- -- aggiungo vetro -- local nFill2Id = WinCreate.AddFill( nSash2Id, WIN_FILLTYPES.GLASS) - +-- -- -- aggiungo terza anta -- local nSash3Id = WinCreate.AddSash( nArea3Id, SashJointType, SashJointType, SashJointType, SashJointType) - +-- -- -- aggiungo vetro -- local nFill3Id = WinCreate.AddFill( nSash3Id, WIN_FILLTYPES.GLASS) @@ -461,39 +469,39 @@ local nFillId = WinCreate.AddFill( nSashId, WIN_FILLTYPES.GLASS) -- -- definisco divisione orizzontale -- local nArea1Id, nArea2Id = WinCreate.AddSplit( nFrameId, WIN_SPLITORIENTATION.HORIZONTAL, WIN_MEASURE.ABSOLUT, WindowHeight / 2) - +-- -- -- definisco divisioni verticali -- local nArea11Id, nArea12Id = WinCreate.AddSplit( nArea1Id, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 3) -- local nArea12Id, nArea13Id = WinCreate.AddSplit( nArea12Id, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 3) -- local nArea21Id, nArea23Id = WinCreate.AddSplit( nArea2Id, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 3) --- local nArea21Id, nArea22Id = WinCreate.AddSplit( nArea21Id, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 3) - +-- local nArea22Id, nArea23Id = WinCreate.AddSplit( nArea23Id, WIN_SPLITORIENTATION.VERTICAL, WIN_MEASURE.ABSOLUT, WindowWidth / 3) +-- -- -- aggiungo prima anta -- local SashJointType = WIN_JNT.FULL_V -- local nSash1Id = WinCreate.AddSash( nArea11Id, SashJointType, SashJointType, SashJointType, SashJointType) -- -- aggiungo vetro -- local nFill1Id = WinCreate.AddFill( nSash1Id, WIN_FILLTYPES.GLASS) - +-- -- -- aggiungo seconda anta -- local nSash2Id = WinCreate.AddSash( nArea12Id, SashJointType, SashJointType, SashJointType, SashJointType) -- -- aggiungo vetro -- local nFill2Id = WinCreate.AddFill( nSash2Id, WIN_FILLTYPES.GLASS) - +-- -- -- aggiungo terza anta -- local nSash3Id = WinCreate.AddSash( nArea13Id, SashJointType, SashJointType, SashJointType, SashJointType) -- -- aggiungo vetro -- local nFill3Id = WinCreate.AddFill( nSash3Id, WIN_FILLTYPES.GLASS) - +-- -- -- aggiungo quarta anta -- local nSash4Id = WinCreate.AddSash( nArea21Id, SashJointType, SashJointType, SashJointType, SashJointType) -- -- aggiungo vetro -- local nFill4Id = WinCreate.AddFill( nSash4Id, WIN_FILLTYPES.GLASS) - +-- -- -- aggiungo quinta anta -- local nSash5Id = WinCreate.AddSash( nArea22Id, SashJointType, SashJointType, SashJointType, SashJointType) -- -- aggiungo vetro -- local nFill5Id = WinCreate.AddFill( nSash5Id, WIN_FILLTYPES.GLASS) - +-- -- -- aggiungo sesta anta -- local nSash6Id = WinCreate.AddSash( nArea23Id, SashJointType, SashJointType, SashJointType, SashJointType) -- -- aggiungo vetro diff --git a/Profiles/WinConst.lua b/Profiles/WinConst.lua index 0ff97e1..78a130c 100644 --- a/Profiles/WinConst.lua +++ b/Profiles/WinConst.lua @@ -18,6 +18,17 @@ local WinConst = {} ------------------------------------------- PARAMETERS ------------------------------------------- +-- tipi di telaio +WIN_FRAME_TYPE = { + RECT = 1, + CHAMFER_SIDE = 2, + CHAMFER = 3, + ROUND_ARC = 4, + SEGMENTAL_ARC = 5, + POINTED_ARC = 6, + TRIANGLE = 7, +} + -- Tipi di giunzioni (joint) WIN_JNT = { ANGLED = 1, diff --git a/Profiles/WinLib/WinCalculate.lua b/Profiles/WinLib/WinCalculate.lua index c7ab79b..c73607c 100644 --- a/Profiles/WinLib/WinCalculate.lua +++ b/Profiles/WinLib/WinCalculate.lua @@ -35,13 +35,59 @@ local function CopyInfo( nDest, nSou, sInfo) EgtSetInfo( nDest, sInfo, sVal) end +--------------------------------------------------------------------- +-- funzione che trova punto di intersezione fra due curve eventualmente estendendole +local function FindIntersectionPoint( nCrv1, nCrv2) + local ptRef = EgtSP( nCrv1) + local ptInt = EgtIP( nCrv1, nCrv2, ptRef) + if not ptInt then + -- se entrambe linee + if EgtGetType( nCrv1) == GDB_TY.CRV_LINE and EgtGetType( nCrv2) == GDB_TY.CRV_LINE then + EgtExtendCurveStartByLen( nCrv1, 10000) + EgtExtendCurveEndByLen( nCrv1, 10000) + EgtExtendCurveStartByLen( nCrv2, 10000) + EgtExtendCurveEndByLen( nCrv2, 10000) + ptInt = EgtIP( nCrv1, nCrv2, ptRef) + + -- se entrambi archi + elseif EgtGetType( nCrv1) == GDB_TY.CRV_ARC and EgtGetType( nCrv2) == GDB_TY.CRV_ARC then + -- TO DO. Al momento non ci sono esempi di questo tipo + + -- se arco e linea + else + local nLine = EgtIf( EgtGetType( nCrv1) == GDB_TY.CRV_LINE, nCrv1, nCrv2) + local nArc = EgtIf( nLine == nCrv1, nCrv2, nCrv1) + -- tento di trovare intersezione prolungando la linea + EgtExtendCurveStartByLen( nLine, 10000) + EgtExtendCurveEndByLen( nLine, 10000) + ptInt = EgtIP( nArc, nLine, ptRef) + if not ptInt then + -- creo circonferenza corrispondente all'arco + local nCircle = EgtCircle( GDB_ID.ROOT, EgtCP( nArc), EgtArcRadius( nArc)) + -- trovo l'intersezione tra retta e circonferenza + local ptDist = EgtIf( nArc == nCrv2, EgtEP( nArc), EgtSP( nArc)) + local _, ptRef = EgtPointCurveDist( ptDist, nLine) + ptInt = EgtIP( nCircle, nLine, ptRef) + EgtErase( nCircle) + -- allungo l'arco per arrivare al punto di intersezione + if nArc == nCrv2 then + EgtModifyCurveEndPoint( nArc, ptInt) + else + EgtModifyCurveStartPoint( nArc, ptInt) + end + end + end + end + + return ptInt +end + --------------------------------------------------------------------- -- funzione che dato un gruppo contenente curve ordinate che creano una curva chiusa, -- ne estende/taglia i contorni per ottenere una curva chiusa continua local function TrimAndOrientOrderedCurveLayer( nLayerId) local IntersCurveList = {} local LastCurveInters - local ptInters local nCurveId = EgtGetFirstInGroup( nLayerId) -- ciclo sui segmenti per ottenere lista intersezioni while nCurveId do @@ -49,15 +95,7 @@ local function TrimAndOrientOrderedCurveLayer( nLayerId) if not nPrevId then nPrevId = EgtGetLastInGroup( nLayerId) end - ptInters = EgtIP( nCurveId, nPrevId, EgtSP( nCurveId)) - if not ptInters then - local dDist = dist( EgtEP( nPrevId), EgtSP( nCurveId)) - EgtExtendCurveStartByLen( nCurveId, 2 * dDist) - EgtExtendCurveEndByLen( nCurveId, 2 * dDist) - EgtExtendCurveStartByLen( nPrevId, 2 * dDist) - EgtExtendCurveEndByLen( nPrevId, 2 * dDist) - ptInters = EgtIP( nCurveId, nPrevId, EgtSP( nCurveId)) - end + local ptInters = FindIntersectionPoint( nCurveId, nPrevId) if LastCurveInters then LastCurveInters.EndInters = Point3d( ptInters) end @@ -67,11 +105,12 @@ local function TrimAndOrientOrderedCurveLayer( nLayerId) nCurveId = EgtGetNext( nCurveId) end IntersCurveList[#IntersCurveList].EndInters = IntersCurveList[1].StartInters + -- ciclo per tagliare ed orientare for nIntersCurveIndex = 1, #IntersCurveList do local CurveInters = IntersCurveList[nIntersCurveIndex] - local dStartParam = EgtCurveParamAtPoint( CurveInters.CurveId, CurveInters.StartInters) - local dEndParam = EgtCurveParamAtPoint( CurveInters.CurveId, CurveInters.EndInters) + local dStartParam = EgtCurveParamAtPoint( CurveInters.CurveId, CurveInters.StartInters, 100 * GEO.EPS_SMALL) + local dEndParam = EgtCurveParamAtPoint( CurveInters.CurveId, CurveInters.EndInters, 100 * GEO.EPS_SMALL) EgtTrimCurveStartEndAtParam( CurveInters.CurveId, min( dStartParam, dEndParam), max( dStartParam, dEndParam)) if dStartParam > dEndParam then EgtInvertCurve( CurveInters.CurveId) @@ -91,7 +130,7 @@ local function TrimSplitWithOutline( nSplitId) nOutlineId = EgtGetInfo( nEndIntersId, WIN_COPY, 'i') local ptEndInters = EgtIP( nSplitId, nOutlineId, EgtSP( nSplitId)) local dEndInters = EgtCurveParamAtPoint( nSplitId, ptEndInters) - EgtTrimCurveEndAtParam( nSplitId, dEndInters) + EgtTrimCurveEndAtParam( nSplitId, dEndInters) end --------------------------------------------------------------------- @@ -727,69 +766,54 @@ local function GetOutlineProfileType( nOutlineId, bBottomRail) end --------------------------------------------------------------------- --- funzione che recupera l'outline precedente e successivo +-- funzione che recupera gli outline precedenti e successivi local function GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId) - local nPrevOutlineId - local nNextOutlineId + local vPrevOutlineId = {} + local vNextOutlineId = {} if nProfileType == WIN_PRF.SPLIT then - -- se split individuo l'outline associato al base outline che lo taglia - local nPrevBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'i') - nPrevOutlineId = EgtGetInfo( nPrevBaseOutlineId, WIN_COPY, 'i') - local nNextBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'i') - nNextOutlineId = EgtGetInfo( nNextBaseOutlineId, WIN_COPY, 'i') + -- se split recupero tutte le curve di base outline che lo tagliano + local vPrevBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'vi') + for i = 1, #vPrevBaseOutlineId do + -- recupero l'outline associato al base outline che lo taglia + table.insert( vPrevOutlineId, EgtGetInfo( vPrevBaseOutlineId[i], WIN_COPY, 'i')) + end + local vNextBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'vi') + for i = 1, #vNextBaseOutlineId do + table.insert( vNextOutlineId, EgtGetInfo( vNextBaseOutlineId[i], WIN_COPY, 'i')) + end else - nPrevOutlineId = EgtGetPrev( nOutlineId) - if not nPrevOutlineId then - nPrevOutlineId = EgtGetLastInGroup( nOutlineLayerId) - end - nNextOutlineId = EgtGetNext( nOutlineId) - if not nNextOutlineId then - nNextOutlineId = EgtGetFirstInGroup( nOutlineLayerId) - end + vPrevOutlineId = { EgtGetPrev( nOutlineId) or EgtGetLastInGroup( nOutlineLayerId)} + vNextOutlineId = { EgtGetNext( nOutlineId) or EgtGetFirstInGroup( nOutlineLayerId)} end - return nPrevOutlineId, nNextOutlineId + return vPrevOutlineId, vNextOutlineId end --------------------------------------------------------------------- -- funzione che restituisce il tipo di controprofilo dell'outline adiacente -local function GetProfileCtrIn( nProfileType, nPrevOutlineId, nOutlineId, nPrevProfileId) +local function GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId) local sPrevCtrIn = WIN_CTRIN - -- gestione particolare nel caso di split su split - if nProfileType == WIN_PRF.SPLIT then - -- recupero il base outline del prev e verifico se deriva da uno split + -- gestione particolare del caso di profilo di split + if not EgtGetFirstNameInGroup( nPrevProfileId, sPrevCtrIn) then + -- recupero la curva di base outline da cui deriva il precedente local nPrevSouId = EgtGetInfo( nPrevOutlineId, WIN_COPY, 'i') local sPrevSouName repeat nPrevSouId = EgtGetInfo( nPrevSouId, WIN_SOU, 'i') sPrevSouName = EgtGetName( nPrevSouId or GDB_ID.NULL) until not nPrevSouId or sPrevSouName == WIN_SPLIT - if sPrevSouName == WIN_SPLIT then - -- verifico da che lato sono dello split - local dOutlineDist, _, dSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nPrevSouId, Z_AX()) - -- recupero box dei controprofili rispetto al loro sistema di riferimento - local nSectionFrameId = EgtGetFirstNameInGroup( nPrevProfileId, WIN_SECTIONFRAME) - local frSectionFrame = EgtFR( nSectionFrameId, GDB_ID.ROOT) - local dMinDist = GEO.INFINITO - -- confronto distanze dei controprofili rispetto a distanza dell'outline per trovare il controprofilo piu' vicino - local nMinCtrInId - local nCtrInId = EgtGetFirstNameInGroup( nPrevProfileId, WIN_CTRIN .. '*') - while nCtrInId do - local b3CtrIn = EgtGetBBoxRef( nCtrInId, GDB_BB.STANDARD, frSectionFrame) - local dCtrInDist = abs( ( dSide * dOutlineDist) - b3CtrIn:getCenter():getX()) - if dCtrInDist < dMinDist then - dMinDist = dCtrInDist - nMinCtrInId = nCtrInId - end - nCtrInId = EgtGetNextName( nCtrInId, WIN_CTRIN .. '*') - end - if nMinCtrInId then - sPrevCtrIn = EgtGetName( nMinCtrInId) - end + + -- verifico da quale lato si trova la curva per decidere quale controprofilo considerare + local _, _, dSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nPrevSouId, Z_AX()) + if dSide == 1 then + sPrevCtrIn = WIN_CTRIN .. '1' -- dx + else + sPrevCtrIn = WIN_CTRIN .. '2' -- sx end end + return sPrevCtrIn end @@ -822,32 +846,39 @@ end --------------------------------------------------------------------- -- funzione che crea il gruppo con i profili di un pezzo -local function CalcFrameProfiles( nPartId, nOutlineId, nPrevOutlineId, nNextOutlineId, nProfileType) +local function CalcFrameProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nProfileType) -- creo gruppo per i profili local nProfileLayerId = EgtGroup( nPartId) EgtSetName( nProfileLayerId, WIN_PROFILE) EgtSetStatus( nProfileLayerId, GDB_ST.OFF) - -- recupero profili e controprofili - local nOrigMainProfileId = GetOutlineProfileId( nOutlineId, nProfileType == WIN_PRF.BOTTOMRAIL) - -- se il tipo corrente è split il pezzo va tagliato con il bottomrail, altrimenti con il bottom - local nOrigStartProfileId = GetOutlineProfileId( nPrevOutlineId, nProfileType == WIN_PRF.SPLIT) - local nOrigEndProfileId = GetOutlineProfileId( nNextOutlineId, nProfileType == WIN_PRF.SPLIT) - -- creo copie di profilo e controprofili + -- recupero profilo principale e ne creo copia + local nOrigMainProfileId = GetOutlineProfileId( nOutlineId, nProfileType == WIN_PRF.BOTTOMRAIL) local nMainProfileId = EgtCopy( nOrigMainProfileId, nProfileLayerId) local sMainProfileType = EgtGetName( nMainProfileId) EgtSetInfo( nMainProfileId, WIN_PRF_TYPE, sMainProfileType) EgtSetName( nMainProfileId, WIN_PRF_MAIN) - local nStartProfileId = EgtCopy( nOrigStartProfileId, nProfileLayerId) - local sStartProfileType = EgtGetName( nStartProfileId) - EgtSetInfo( nStartProfileId, WIN_PRF_TYPE, sStartProfileType) - EgtSetName( nStartProfileId, WIN_PRF_START) - local nEndProfileId = EgtCopy( nOrigEndProfileId, nProfileLayerId) - local sEndProfileType = EgtGetName( nEndProfileId) - EgtSetInfo( nEndProfileId, WIN_PRF_TYPE, sEndProfileType) - EgtSetName( nEndProfileId, WIN_PRF_END) + -- recupero controprofili start e ne creo copia + for i = 1, #vPrevOutlineId do + -- se il tipo corrente è split il pezzo va tagliato con il bottomrail, altrimenti con il bottom + local nOrigStartProfileId = GetOutlineProfileId( vPrevOutlineId[i], nProfileType == WIN_PRF.SPLIT) + local nStartProfileId = EgtCopy( nOrigStartProfileId, nProfileLayerId) + local sStartProfileType = EgtGetName( nStartProfileId) + EgtSetInfo( nStartProfileId, WIN_PRF_TYPE, sStartProfileType) + EgtSetName( nStartProfileId, WIN_PRF_START) + end + + -- recupero controprofili end e ne creo copia + for i = 1, #vNextOutlineId do + local nOrigEndProfileId = GetOutlineProfileId( vNextOutlineId[i], nProfileType == WIN_PRF.SPLIT) + local nEndProfileId = EgtCopy( nOrigEndProfileId, nProfileLayerId) + local sEndProfileType = EgtGetName( nEndProfileId) + EgtSetInfo( nEndProfileId, WIN_PRF_TYPE, sEndProfileType) + EgtSetName( nEndProfileId, WIN_PRF_END) + end + -- recupero le info di pinzaggio dal profilo di estrusione CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFY_1) CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFZ_1) @@ -875,7 +906,7 @@ end --------------------------------------------------------------------- -- funzione che crea le curve del geo -local function CreateFrameGeo( nOutlineId, nPrevOutlineId, nNextOutlineId, nStartPartJointType, nEndPartJointType, nProfileType, nGeoLayerId, nProfileLayerId) +local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId) local nCurrProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) local nCurrProfileRefId = EgtGetFirstNameInGroup( nCurrProfileId, WIN_REF) @@ -901,68 +932,69 @@ local function CreateFrameGeo( nOutlineId, nPrevOutlineId, nNextOutlineId, nStar local nSemiProfileIn = EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '2') EgtSetInfo( nCurrOffsetId, WIN_SEMI_PROFILE, nSemiProfileIn) - -- curva left - local nPrevCurveId - local nPrevSemiProfile - if nStartPartJointType == WIN_PART_JNT.ANGLED then - -- calcolo la bisettrice - local vtMedia = ( ( EgtSV( nOutlineId) - EgtEV( nPrevOutlineId)) / 2) - if not vtMedia:normalize() then - vtMedia = EgtSV( nOutlineId) - vtMedia:rotate( Z_AX(), 90) - end - nPrevCurveId = EgtLinePVL( nGeoLayerId, EgtSP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX()) - EgtInvertCurve( nPrevCurveId) - else - nPrevCurveId = EgtCopy( nPrevOutlineId, nGeoLayerId) - local nPrevProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START) - if nStartPartJointType == WIN_PART_JNT.SHORT then - local sCtrIn = GetProfileCtrIn( nProfileType, nPrevOutlineId, nOutlineId, nPrevProfileId) - local dPrevCPDelta = GetDeltaProfile( nPrevProfileId, sCtrIn) - EgtOffsetCurve( nPrevCurveId, - dPrevCPDelta) - EgtSetInfo( nGeoLayerId, WIN_STARTCPDELTA, dPrevCPDelta) - -- ricavo il semiprofilo associato - nPrevSemiProfile = EgtGetFirstNameInGroup( nPrevProfileId, sCtrIn) + -- curve left + for i = 1, #vPrevOutlineId do + local nPrevCurveId + local nPrevSemiProfile + if nStartPartJointType == WIN_PART_JNT.ANGLED then + -- calcolo la bisettrice + local vtMedia = ( ( EgtSV( nOutlineId) - EgtEV( vPrevOutlineId[i])) / 2) + if not vtMedia:normalize() then + vtMedia = EgtSV( nOutlineId) + vtMedia:rotate( Z_AX(), 90) + end + nPrevCurveId = EgtLinePVL( nGeoLayerId, EgtSP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX()) + EgtInvertCurve( nPrevCurveId) else - nPrevSemiProfile = EgtGetFirstNameInGroup( nPrevProfileId, WIN_OUT) + nPrevCurveId = EgtCopy( vPrevOutlineId[i], nGeoLayerId) + local nPrevProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START) + if nStartPartJointType == WIN_PART_JNT.SHORT then + local sCtrIn = GetProfileCtrIn( vPrevOutlineId[i], nOutlineId, nPrevProfileId) + local dPrevCPDelta = GetDeltaProfile( nPrevProfileId, sCtrIn) + EgtOffsetCurve( nPrevCurveId, - dPrevCPDelta) + EgtSetInfo( nGeoLayerId, WIN_STARTCPDELTA, dPrevCPDelta) + -- ricavo il semiprofilo associato + nPrevSemiProfile = EgtGetFirstNameInGroup( nPrevProfileId, sCtrIn) + else + nPrevSemiProfile = EgtGetFirstNameInGroup( nPrevProfileId, WIN_OUT) + end end + EgtSetName( nPrevCurveId, WIN_GEO_LEFT) + EgtSetInfo( nPrevCurveId, WIN_SEMI_PROFILE, nPrevSemiProfile) + EgtRelocateGlob( nPrevCurveId, nGeoLayerId, GDB_IN.LAST_SON) end - EgtSetName( nPrevCurveId, WIN_GEO_LEFT) - EgtSetInfo( nPrevCurveId, WIN_SEMI_PROFILE, nPrevSemiProfile) - -- curva right - local nNextCurveId - local nNextSemiProfile - if nEndPartJointType == WIN_PART_JNT.ANGLED then - -- calcolo la bisettrice - local vtMedia = ( ( EgtSV( nNextOutlineId) - EgtEV( nOutlineId)) / 2) - if not vtMedia:normalize() then - vtMedia = EgtEV( nOutlineId) - vtMedia:rotate(Z_AX(), 90) - end - nNextCurveId = EgtLinePVL( nGeoLayerId, EgtEP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX()) - else - nNextCurveId = EgtCopy( nNextOutlineId, nGeoLayerId) - local nNextProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_END) - if nEndPartJointType == WIN_PART_JNT.SHORT then - local sCtrIn = GetProfileCtrIn( nProfileType, nNextOutlineId, nOutlineId, nNextProfileId) - local dNextCPDelta = GetDeltaProfile( nNextProfileId, sCtrIn) - EgtOffsetCurve( nNextCurveId, - dNextCPDelta) - EgtSetInfo( nGeoLayerId, WIN_ENDCPDELTA, dNextCPDelta) - -- ricavo il semiprofilo associato - nNextSemiProfile = EgtGetFirstNameInGroup( nNextProfileId, sCtrIn) + -- curve right + for i = 1, #vNextOutlineId do + local nNextCurveId + local nNextSemiProfile + if nEndPartJointType == WIN_PART_JNT.ANGLED then + -- calcolo la bisettrice + local vtMedia = ( ( EgtSV( vNextOutlineId[i]) - EgtEV( nOutlineId)) / 2) + if not vtMedia:normalize() then + vtMedia = EgtEV( nOutlineId) + vtMedia:rotate(Z_AX(), 90) + end + nNextCurveId = EgtLinePVL( nGeoLayerId, EgtEP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX()) else - nNextSemiProfile = EgtGetFirstNameInGroup( nNextProfileId, WIN_OUT) + nNextCurveId = EgtCopy( vNextOutlineId[i], nGeoLayerId) + local nNextProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_END) + if nEndPartJointType == WIN_PART_JNT.SHORT then + local sCtrIn = GetProfileCtrIn( vNextOutlineId[i], nOutlineId, nNextProfileId) + local dNextCPDelta = GetDeltaProfile( nNextProfileId, sCtrIn) + EgtOffsetCurve( nNextCurveId, - dNextCPDelta) + EgtSetInfo( nGeoLayerId, WIN_ENDCPDELTA, dNextCPDelta) + -- ricavo il semiprofilo associato + nNextSemiProfile = EgtGetFirstNameInGroup( nNextProfileId, sCtrIn) + else + nNextSemiProfile = EgtGetFirstNameInGroup( nNextProfileId, WIN_OUT) + end end + EgtSetName( nNextCurveId, WIN_GEO_RIGHT) + EgtSetInfo( nNextCurveId, WIN_SEMI_PROFILE, nNextSemiProfile) + EgtRelocateGlob( nNextCurveId, nCurrOffsetId, GDB_IN.BEFORE) end - EgtSetName( nNextCurveId, WIN_GEO_RIGHT) - EgtSetInfo( nNextCurveId, WIN_SEMI_PROFILE, nNextSemiProfile) - - -- riordino le curve per eseguire correttamente il trim - EgtRelocateGlob( nNextCurveId, nCurrCurveId, GDB_IN.AFTER) - EgtRelocateGlob( nCurrOffsetId, nNextCurveId, GDB_IN.AFTER) - EgtRelocateGlob( nPrevCurveId, nCurrOffsetId, GDB_IN.AFTER) - + -- trim delle curve TrimAndOrientOrderedCurveLayer( nGeoLayerId) @@ -1017,8 +1049,8 @@ local function CalcFrameGeo( nPartId, nOutlineId, nOutlineLayerId, nProfileType) local nGeoLayerId = EgtGroup( nPartId) EgtSetName( nGeoLayerId, WIN_GEO) - -- recupero outline precedente e successivo - local nPrevOutlineId, nNextOutlineId = GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId) + -- recupero outline precedenti e successivi ( solo nel caso di split possono essere più di uno) + local vPrevOutlineId, vNextOutlineId = GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId) -- recupero il tipo di giunzioni local nStartJointType @@ -1033,19 +1065,20 @@ local function CalcFrameGeo( nPartId, nOutlineId, nOutlineLayerId, nProfileType) nStartJointType = EgtGetInfo( nOutlineLayerId, WIN_JOINT_TL, 'i') nEndJointType = EgtGetInfo( nOutlineLayerId, WIN_JOINT_BL, 'i') elseif nProfileType == WIN_PRF.RIGHT then - -- recupero tipo di giunzioni nStartJointType = EgtGetInfo( nOutlineLayerId, WIN_JOINT_BR, 'i') nEndJointType = EgtGetInfo( nOutlineLayerId, WIN_JOINT_TR, 'i') else -- nei casi di profilo BottomRail e Split non serve settare dei valori per StartJointType ed EndJointType perchè -- in CalcPartJointType la loro giunzione viene settata a short end - -- se pezzo non e' split, giunzione diversa da bisettrice ed arco a tutto sesto forzo il tipo a bisettrice - if nProfileType ~= WIN_PRF.SPLIT and nStartJointType ~= WIN_JNT.ANGLED and AreSameVectorApprox( EgtEV( nPrevOutlineId), EgtSV( nOutlineId)) then - nStartJointType = WIN_JNT.ANGLED + -- se pezzo non e' split, giunzione diversa da bisettrice e arco a tutto sesto oppure elementi entrambi top, forzo il tipo a bisettrice + if nProfileType ~= WIN_PRF.SPLIT and nStartJointType ~= WIN_JNT.ANGLED and + ( AreSameVectorApprox( EgtEV( vPrevOutlineId[1]), EgtSV( nOutlineId)) or EgtGetName( nOutlineId) == EgtGetName( vPrevOutlineId[1])) then + nStartJointType = WIN_JNT.ANGLED end - if nProfileType ~= WIN_PRF.SPLIT and nEndJointType ~= WIN_JNT.ANGLED and AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( nNextOutlineId)) then - nEndJointType = WIN_JNT.ANGLED + if nProfileType ~= WIN_PRF.SPLIT and nEndJointType ~= WIN_JNT.ANGLED and + ( AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( vNextOutlineId[1])) or EgtGetName( nOutlineId) == EgtGetName( vNextOutlineId[1])) then + nEndJointType = WIN_JNT.ANGLED end -- calcolo il tipo di giunzione per la parte @@ -1057,10 +1090,10 @@ local function CalcFrameGeo( nPartId, nOutlineId, nOutlineLayerId, nProfileType) EgtSetInfo( nOutlineId, WIN_ENDJOINT, nEndPartJointType) -- creo il gruppo con i profili del pezzo - local nProfileLayerId = CalcFrameProfiles( nPartId, nOutlineId, nPrevOutlineId, nNextOutlineId, nProfileType) + local nProfileLayerId = CalcFrameProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nProfileType) -- creo lati dell'outline - local nGeoOutId = CreateFrameGeo( nOutlineId, nPrevOutlineId, nNextOutlineId, nStartPartJointType, nEndPartJointType, nProfileType, nGeoLayerId, nProfileLayerId) + local nGeoOutId = CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId) -- calcolo le lavorazioni associate ai profili CalcProfilingProcessings( nPartId, nGeoLayerId) @@ -1512,7 +1545,7 @@ end local function CalcFrameDowels( nPartId, nOutlineId, nOutlineLayerId, nProfileType) -- creo fori per spine su Start ed End - local nPrevOutlineId, nNextOutlineId = GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId) + local vPrevOutlineId, vNextOutlineId = GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId) local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) local nProcLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC) local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) @@ -1521,8 +1554,12 @@ local function CalcFrameDowels( nPartId, nOutlineId, nOutlineLayerId, nProfileTy local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) nMainExtrusionId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN) end - AddStartDowels( nOutlineId, nPrevOutlineId, nProfileLayerId, nProcLayerId, nGeoLayerId, nMainExtrusionId) - AddEndDowels( nOutlineId, nNextOutlineId, nProfileLayerId, nProcLayerId, nGeoLayerId, nMainExtrusionId) + for i = 1, #vPrevOutlineId do + AddStartDowels( nOutlineId, vPrevOutlineId[i], nProfileLayerId, nProcLayerId, nGeoLayerId, nMainExtrusionId) + end + for i = 1, #vNextOutlineId do + AddEndDowels( nOutlineId, vNextOutlineId[i], nProfileLayerId, nProcLayerId, nGeoLayerId, nMainExtrusionId) + end -- split dowels AddSplitDowels( nOutlineId, nOutlineLayerId, nPartId, nProfileType) @@ -1533,40 +1570,46 @@ end ---------------------------------- SOLIDO ---------------------------------------- ---------------------------------------------------------------------------------- -- funzione che recupera tipo di inizio e fine pezzo -local function CalcStartEndProfileType( nProfileType, nOutlineId, nStartProfileId, nEndProfileId) +local function CalcStartEndProfileType( nProfileType, nOutlineId, vStartProfileId, vEndProfileId) - local sStartProfileType - local sEndProfileType - local StartJointType = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i') - if StartJointType == WIN_PART_JNT.ANGLED then - sStartProfileType = WIN_MINIZINKEN - elseif StartJointType == WIN_PART_JNT.SHORT then - sStartProfileType = WIN_CTRINOFST - elseif StartJointType == WIN_PART_JNT.FULL then - sStartProfileType = WIN_OUTOFST - end - - local EndJointType = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i') - if EndJointType == WIN_PART_JNT.ANGLED then - sEndProfileType = WIN_MINIZINKEN - elseif EndJointType == WIN_PART_JNT.SHORT then - sEndProfileType = WIN_CTRINOFST - elseif EndJointType == WIN_PART_JNT.FULL then - sEndProfileType = WIN_OUTOFST - end + local vsStartProfileType = {} + local vsEndProfileType = {} if nProfileType == WIN_PRF.SPLIT then - local nStartBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'i') - local nStartId = EgtGetInfo( nStartBaseOutlineId, WIN_COPY, 'i') - local nEndBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'i') - local nEndId = EgtGetInfo( nEndBaseOutlineId, WIN_COPY, 'i') - sStartProfileType = GetProfileCtrIn( nProfileType, nStartId, nOutlineId, nStartProfileId) - sEndProfileType = GetProfileCtrIn( nProfileType, nEndId, nOutlineId, nEndProfileId) - sStartProfileType = WIN_OFST .. sStartProfileType - sEndProfileType = WIN_OFST .. sEndProfileType + local vStartBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'vi') + for i = 1, #vStartBaseOutlineId do + local nStartId = EgtGetInfo( vStartBaseOutlineId[i], WIN_COPY, 'i') + local sStartProfileType = GetProfileCtrIn( nStartId, nOutlineId, vStartProfileId[i]) + table.insert( vsStartProfileType, WIN_OFST .. sStartProfileType) + end + local vEndBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'vi') + for i = 1, #vEndBaseOutlineId do + local nEndId = EgtGetInfo( vEndBaseOutlineId[i], WIN_COPY, 'i') + local sEndProfileType = GetProfileCtrIn( nEndId, nOutlineId, vEndProfileId[i]) + table.insert( vsEndProfileType, WIN_OFST .. sEndProfileType) + end + + else + local StartJointType = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i') + if StartJointType == WIN_PART_JNT.ANGLED then + vsStartProfileType = { WIN_MINIZINKEN} + elseif StartJointType == WIN_PART_JNT.SHORT then + vsStartProfileType = { WIN_CTRINOFST} + elseif StartJointType == WIN_PART_JNT.FULL then + vsStartProfileType = { WIN_OUTOFST} + end + + local EndJointType = EgtGetInfo( nOutlineId, WIN_ENDJOINT, 'i') + if EndJointType == WIN_PART_JNT.ANGLED then + vsEndProfileType = { WIN_MINIZINKEN} + elseif EndJointType == WIN_PART_JNT.SHORT then + vsEndProfileType = { WIN_CTRINOFST} + elseif EndJointType == WIN_PART_JNT.FULL then + vsEndProfileType = { WIN_OUTOFST} + end end - - return sStartProfileType, sEndProfileType + + return vsStartProfileType, vsEndProfileType end --------------------------------------------------------------------- @@ -1583,18 +1626,26 @@ local function CalcFrameSolid( nPartId, nOutlineId, nGeoId, nProfileType) -- recupero profili e controprofili local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) - local nStartProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START) - local nEndProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_END) + local vStartProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START) + local vEndProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END) -- recupero geo local nGeoLayerId = EgtGetParent( nGeoId) - local nPrevGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_LEFT) - local nNextGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) + local vPrevGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) + local vNextGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) -- recupero BBox e larghezza del geo local dGeoWidth = EgtGetInfo( nGeoId, WIN_GEOWIDTH, 'd') -- recupero i controprofili in base al tipo di giunzioni - local sStartProfileType, sEndProfileType = CalcStartEndProfileType( nProfileType, nOutlineId, nStartProfileId, nEndProfileId) + local vsStartProfileType, vsEndProfileType = CalcStartEndProfileType( nProfileType, nOutlineId, vStartProfileId, vEndProfileId) + + -- verifico se outline è split interno ad area di split per controlli su inversione del profilo + local bSplitInsideSplitArea = false + if nProfileType == WIN_PRF.SPLIT then + local nAreaId = EgtGetParent( EgtGetParent( nOutlineId)) + local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + bSplitInsideSplitArea = ( nAreaType == WIN_AREATYPES.SPLIT) + end -- a) MAIN EXTRUSION -- creo guida Main @@ -1622,132 +1673,128 @@ local function CalcFrameSolid( nPartId, nOutlineId, nGeoId, nProfileType) -- b) START PROFILE - -- posiziono il profilo Start - local nRefStartProfileId = EgtGetFirstNameInGroup( nStartProfileId, WIN_REF) - local b3RefStartProfile = EgtGetBBoxGlob(nRefStartProfileId, GDB_BB.STANDARD) - local dStartDelta = EgtGetInfo( nGeoLayerId, WIN_STARTCPDELTA, 'd') or 0 - -- creo guida per estrusione - local nStartGuideId = EgtCopy( nPrevGeoId, nSolidLayerId) - EgtExtendCurveStartByLen( nStartGuideId, 2 * dGeoWidth) - EgtExtendCurveEndByLen( nStartGuideId, 2 * dGeoWidth) - -- recupero frame del profilo - local nStartProfileFrameId = EgtGetFirstNameInGroup( nStartProfileId, WIN_SECTIONFRAME) - local frStartProfile = EgtFR( nStartProfileFrameId) - -- lo sposto se controprofilo - frStartProfile:move( - frStartProfile:getVersX() * dStartDelta) - frStartProfile:invert() - -- lo applico a tutte le geometrie del profilo - EgtTransform( EgtGetAllInGroup( nStartProfileId), frStartProfile) - -- assegno come riferimento del profilo il punto start dell'outline - EgtChangeGroupFrame( nStartProfileId, Frame3d( EgtSP( nStartGuideId), - EgtSV( nStartGuideId))) - - -- verifico se outline è split interno ad area di split per controlli su inversione del profilo - local bSplitInsideSplitArea = false - if nProfileType == WIN_PRF.SPLIT then - local nAreaId = EgtGetParent( EgtGetParent( nOutlineId)) - local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') - bSplitInsideSplitArea = ( nAreaType == WIN_AREATYPES.SPLIT) - end - - if bSplitInsideSplitArea then - -- verifico se il suo start deriva da uno split - local nStartId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'i') - local nStartSouId = nStartId - local sStartSouName - repeat - nStartSouId = EgtGetInfo( nStartSouId, WIN_SOU, 'i') - sStartSouName = EgtGetName( nStartSouId or GDB_ID.NULL) - until not nStartSouId or sStartSouName == WIN_SPLIT - if sStartSouName == WIN_SPLIT then - -- recupero vettore tangente nel punto medio della curva di contorno - local ptMidStart = EgtMP( nStartId) - local vtMidStart = EgtMV( nStartId) - -- recupero vettore tangente nello stesso punto della curva split originale - local dMidStartOnStartSou = EgtCurveParamAtPoint( nStartSouId, ptMidStart) - local vtMidStartSou = EgtUV( nStartSouId, dMidStartOnStartSou, -1) - -- se i due vettori non sono orientati nella stessa direzione - if not AreSameVectorApprox( vtMidStart, vtMidStartSou) then - -- ruoto di 180 gradi il profilo - local frStartProfileS = EgtFR( nStartProfileFrameId, GDB_ID.ROOT) - EgtRotate( nStartProfileId, frStartProfileS:getOrigin(), frStartProfileS:getVersY(), 180, GDB_RT.GLOB) + for i = 1, #vPrevGeoId do + -- posiziono il profilo Start + local nRefStartProfileId = EgtGetFirstNameInGroup( vStartProfileId[i], WIN_REF) + local b3RefStartProfile = EgtGetBBoxGlob( nRefStartProfileId, GDB_BB.STANDARD) + local dStartDelta = EgtGetInfo( nGeoLayerId, WIN_STARTCPDELTA, 'd') or 0 + -- creo guida per estrusione + local nStartGuideId = EgtCopy( vPrevGeoId[i], nSolidLayerId) + EgtExtendCurveStartByLen( nStartGuideId, 2 * dGeoWidth) + EgtExtendCurveEndByLen( nStartGuideId, 2 * dGeoWidth) + -- recupero frame del profilo + local nStartProfileFrameId = EgtGetFirstNameInGroup( vStartProfileId[i], WIN_SECTIONFRAME) + local frStartProfile = EgtFR( nStartProfileFrameId) + -- lo sposto se controprofilo + frStartProfile:move( - frStartProfile:getVersX() * dStartDelta) + frStartProfile:invert() + -- lo applico a tutte le geometrie del profilo + EgtTransform( EgtGetAllInGroup( vStartProfileId[i]), frStartProfile) + -- assegno come riferimento del profilo il punto start dell'outline + EgtChangeGroupFrame( vStartProfileId[i], Frame3d( EgtSP( nStartGuideId), - EgtSV( nStartGuideId))) + + if bSplitInsideSplitArea then + -- verifico se il suo start deriva da uno split + local nStartId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'i') + local nStartSouId = nStartId + local sStartSouName + repeat + nStartSouId = EgtGetInfo( nStartSouId, WIN_SOU, 'i') + sStartSouName = EgtGetName( nStartSouId or GDB_ID.NULL) + until not nStartSouId or sStartSouName == WIN_SPLIT + if sStartSouName == WIN_SPLIT then + -- recupero vettore tangente nel punto medio della curva di contorno + local ptMidStart = EgtMP( nStartId) + local vtMidStart = EgtMV( nStartId) + -- recupero vettore tangente nello stesso punto della curva split originale + local dMidStartOnStartSou = EgtCurveParamAtPoint( nStartSouId, ptMidStart) + local vtMidStartSou = EgtUV( nStartSouId, dMidStartOnStartSou, -1) + -- se i due vettori non sono orientati nella stessa direzione + if not AreSameVectorApprox( vtMidStart, vtMidStartSou) then + -- ruoto di 180 gradi il profilo + local frStartProfileS = EgtFR( nStartProfileFrameId, GDB_ID.ROOT) + EgtRotate( vStartProfileId[i], frStartProfileS:getOrigin(), frStartProfileS:getVersY(), 180, GDB_RT.GLOB) + end end end + + -- recupero outline del profilo Start e lo estrudo + local nOutStartProfileId + if vsStartProfileType[i] == WIN_MINIZINKEN then + nOutStartProfileId = EgtLine( vStartProfileId[i], EgtSP( vPrevGeoId[i]), EgtSP( vPrevGeoId[i]) - Z_AX() * b3RefStartProfile:getDimY(), GDB_RT.GLOB) + EgtInvertCurve( nOutStartProfileId) + else + nOutStartProfileId = EgtGetFirstNameInGroup( vStartProfileId[i], vsStartProfileType[i]) + end + local nStartExtrusionId = EgtSurfTmSwept( nSolidLayerId, nOutStartProfileId, nStartGuideId, false, WIN_SURF_APPROX) + -- eseguo intersezione per ottenere un solido unico + -- ( tagliare le due superfici con EgtSurfTmCut e poi unirle potrebbe creare piccoli buchi legati alle diverse approssimazioni) + EgtSurfTmIntersect( nMainExtrusionId, nStartExtrusionId) + EgtErase( nStartExtrusionId) + EgtErase( nStartGuideId) end - -- recupero outline del profilo Start e lo estrudo - local nOutStartProfileId - if sStartProfileType == WIN_MINIZINKEN then - nOutStartProfileId = EgtLine( nStartProfileId, EgtSP( nPrevGeoId), EgtSP( nPrevGeoId) - Z_AX() * b3RefStartProfile:getDimY(), GDB_RT.GLOB) - EgtInvertCurve( nOutStartProfileId) - else - nOutStartProfileId = EgtGetFirstNameInGroup( nStartProfileId, sStartProfileType) - end - local nStartExtrusionId = EgtSurfTmSwept( nSolidLayerId, nOutStartProfileId, nStartGuideId, false, WIN_SURF_APPROX) - -- eseguo intersezione per ottenere un solido unico - -- ( tagliare le due superfici con EgtSurfTmCut e poi unirle potrebbe creare piccoli buchi legati alle diverse approssimazioni) - EgtSurfTmIntersect( nMainExtrusionId, nStartExtrusionId) - EgtErase( nStartExtrusionId) - EgtErase( nStartGuideId) - -- c) END PROFILE - -- posiziono il profilo End - local nRefEndProfileId = EgtGetFirstNameInGroup( nEndProfileId, WIN_REF) - local b3RefEndProfile = EgtGetBBoxGlob(nRefEndProfileId, GDB_BB.STANDARD) - local dEndDelta = EgtGetInfo( nGeoLayerId, WIN_ENDCPDELTA, 'd') or 0 - -- creo guida per estrusione - local nEndGuideId = EgtCopy( nNextGeoId, nSolidLayerId) - EgtExtendCurveStartByLen( nEndGuideId, 2 * dGeoWidth) - EgtExtendCurveEndByLen( nEndGuideId, 2 * dGeoWidth) - -- recupero frame del profilo - local nEndProfileFrameId = EgtGetFirstNameInGroup( nEndProfileId, WIN_SECTIONFRAME) - local frEndProfile = EgtFR( nEndProfileFrameId) - frEndProfile:move( - frEndProfile:getVersX() * dEndDelta) - frEndProfile:invert() - -- lo applico a tutte le geometrie del profilo - EgtTransform( EgtGetAllInGroup( nEndProfileId), frEndProfile) - -- assegno come riferimento del profilo il punto start dell'outline - EgtChangeGroupFrame( nEndProfileId, Frame3d( EgtSP( nEndGuideId), - EgtSV( nEndGuideId))) - - -- verifico se necessario ruotare di 180 gradi il profilo - if bSplitInsideSplitArea then - -- verifico se end deriva da split - local nEndId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'i') - local nEndSouId = nEndId - local sEndSouName - repeat - nEndSouId = EgtGetInfo( nEndSouId, WIN_SOU) - sEndSouName = EgtGetName( nEndSouId or GDB_ID.NULL) - until not nEndSouId or sEndSouName == WIN_SPLIT - if sEndSouName == WIN_SPLIT then - -- recupero vettore tangente nel punto medio della curva di contorno - local ptMidEnd = EgtMP( nEndId) - local vtMidEnd = EgtMV( nEndId) - -- recupero vettore tangente nello stesso punto della curva split originale - local dMidStartOnEndSou = EgtCurveParamAtPoint( nEndSouId, ptMidEnd) - local vtMidEndSou = EgtUV( nEndSouId, dMidStartOnEndSou, -1) - -- se i due vettori non sono orientati nella stessa direzione - if not AreSameVectorApprox( vtMidEnd, vtMidEndSou) then - -- ruoto di 180 gradi il profilo - local frEndProfileS = EgtFR( nEndProfileFrameId, GDB_ID.ROOT) - EgtRotate( nEndProfileId, frEndProfileS:getOrigin(), frEndProfileS:getVersY(), 180, GDB_RT.GLOB) + for i = 1, #vNextGeoId do + -- posiziono il profilo End + local nRefEndProfileId = EgtGetFirstNameInGroup( vEndProfileId[i], WIN_REF) + local b3RefEndProfile = EgtGetBBoxGlob( nRefEndProfileId, GDB_BB.STANDARD) + local dEndDelta = EgtGetInfo( nGeoLayerId, WIN_ENDCPDELTA, 'd') or 0 + -- creo guida per estrusione + local nEndGuideId = EgtCopy( vNextGeoId[i], nSolidLayerId) + EgtExtendCurveStartByLen( nEndGuideId, 2 * dGeoWidth) + EgtExtendCurveEndByLen( nEndGuideId, 2 * dGeoWidth) + -- recupero frame del profilo + local nEndProfileFrameId = EgtGetFirstNameInGroup( vEndProfileId[i], WIN_SECTIONFRAME) + local frEndProfile = EgtFR( nEndProfileFrameId) + frEndProfile:move( - frEndProfile:getVersX() * dEndDelta) + frEndProfile:invert() + -- lo applico a tutte le geometrie del profilo + EgtTransform( EgtGetAllInGroup( vEndProfileId[i]), frEndProfile) + -- assegno come riferimento del profilo il punto start dell'outline + EgtChangeGroupFrame( vEndProfileId[i], Frame3d( EgtSP( nEndGuideId), - EgtSV( nEndGuideId))) + + -- verifico se necessario ruotare di 180 gradi il profilo + if bSplitInsideSplitArea then + -- verifico se end deriva da split + local nEndId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'i') + local nEndSouId = nEndId + local sEndSouName + repeat + nEndSouId = EgtGetInfo( nEndSouId, WIN_SOU) + sEndSouName = EgtGetName( nEndSouId or GDB_ID.NULL) + until not nEndSouId or sEndSouName == WIN_SPLIT + if sEndSouName == WIN_SPLIT then + -- recupero vettore tangente nel punto medio della curva di contorno + local ptMidEnd = EgtMP( nEndId) + local vtMidEnd = EgtMV( nEndId) + -- recupero vettore tangente nello stesso punto della curva split originale + local dMidStartOnEndSou = EgtCurveParamAtPoint( nEndSouId, ptMidEnd) + local vtMidEndSou = EgtUV( nEndSouId, dMidStartOnEndSou, -1) + -- se i due vettori non sono orientati nella stessa direzione + if not AreSameVectorApprox( vtMidEnd, vtMidEndSou) then + -- ruoto di 180 gradi il profilo + local frEndProfileS = EgtFR( nEndProfileFrameId, GDB_ID.ROOT) + EgtRotate( vEndProfileId[i], frEndProfileS:getOrigin(), frEndProfileS:getVersY(), 180, GDB_RT.GLOB) + end end end + + -- recupero outline del profilo End e lo estrudo + local nOutEndProfileId + if vsEndProfileType[i] == WIN_MINIZINKEN then + nOutEndProfileId = EgtLine( vEndProfileId[i], EgtSP( vNextGeoId[i]), EgtSP( vNextGeoId[i]) - Z_AX() * b3RefEndProfile:getDimY(), GDB_RT.GLOB) + EgtInvertCurve( nOutEndProfileId) + else + nOutEndProfileId = EgtGetFirstNameInGroup( vEndProfileId[i], vsEndProfileType[i]) + end + local nEndExtrusionId = EgtSurfTmSwept( nSolidLayerId, nOutEndProfileId, nEndGuideId, false, WIN_SURF_APPROX) + -- eseguo intersezione per ottenere un solido unico + EgtSurfTmIntersect( nMainExtrusionId, nEndExtrusionId) + EgtErase( nEndExtrusionId) + EgtErase( nEndGuideId) end - - -- recupero outline del profilo End e lo estrudo - local nOutEndProfileId - if sEndProfileType == WIN_MINIZINKEN then - nOutEndProfileId = EgtLine( nEndProfileId, EgtSP( nNextGeoId), EgtSP( nNextGeoId) - Z_AX() * b3RefEndProfile:getDimY(), GDB_RT.GLOB) - EgtInvertCurve( nOutEndProfileId) - else - nOutEndProfileId = EgtGetFirstNameInGroup( nEndProfileId, sEndProfileType) - end - local nEndExtrusionId = EgtSurfTmSwept( nSolidLayerId, nOutEndProfileId, nEndGuideId, false, WIN_SURF_APPROX) - -- eseguo intersezione per ottenere un solido unico - EgtSurfTmIntersect( nMainExtrusionId, nEndExtrusionId) - EgtErase( nEndExtrusionId) - EgtErase( nEndGuideId) end @@ -1807,7 +1854,6 @@ local function CreatePartFromOutline( nAreaLayerId, nOutlineId, bBottomRail) -- calcolo i fori per le spine CalcFrameDowels( nPartId, nOutlineId, nOutlineLayerId, nProfileType) - -- b) Fill elseif nAreaType == WIN_AREATYPES.FILL then -- imposto nome del pezzo @@ -1837,30 +1883,29 @@ end ---------------------------- STRIP ---------------------------------- --------------------------------------------------------------------- -- funzione che restitutisce lo Strip piu' vicino -local function GetStripNearestToOutline( nProfileId, nOutlineId) - -- recupero strip - local ptStartOutline = EgtMP( nOutlineId) - local vtStartOutline = EgtSV( nOutlineId) - local nStartStripId = EgtGetFirstNameInGroup( nProfileId, WIN_STRIP) - if not nStartStripId then - local nStripMinDistId - local dMinDistance - local nStripId = EgtGetFirstNameInGroup( nProfileId, WIN_STRIP .. '*') - while nStripId do - local b3Strip = EgtGetBBoxGlob( nStripId, GDB_BB.STANDARD) - -- calcolo il vettore distanza - local vtDistance = b3Strip:getCenter() - ptStartOutline - -- ne ricavo la componente nella stessa direzione dell'outline - local dDistance = abs( vtDistance * vtStartOutline) - if not dMinDistance or dDistance < dMinDistance then - dMinDistance = dDistance - nStripMinDistId = nStripId - end - nStripId = EgtGetNextName( nStripId, WIN_STRIP .. '*') +-- ( analoga a GetProfileCtrIn) +local function GetStripNearestToOutline( nPrevProfileId, nPrevOutlineId, nOutlineId) + local nStripId = EgtGetFirstNameInGroup( nPrevProfileId, WIN_STRIP) + -- gestione particolare del caso di profilo di split + if not nStripId then + -- recupero la curva di base outline da cui deriva il precedente + local nPrevSouId = EgtGetInfo( nPrevOutlineId, WIN_COPY, 'i') + local sPrevSouName + repeat + nPrevSouId = EgtGetInfo( nPrevSouId, WIN_SOU, 'i') + sPrevSouName = EgtGetName( nPrevSouId or GDB_ID.NULL) + until not nPrevSouId or sPrevSouName == WIN_SPLIT + + -- verifico da quale lato si trova la curva per decidere quale controprofilo considerare + local _, _, dSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nPrevSouId, Z_AX()) + if dSide == 1 then + nStripId = EgtGetFirstNameInGroup( nPrevProfileId, WIN_STRIP .. '1') -- dx + else + nStripId = EgtGetFirstNameInGroup( nPrevProfileId, WIN_STRIP .. '2') -- sx end - nStartStripId = nStripMinDistId end - return nStartStripId + + return nStripId end --------------------------------------------------------------------- @@ -1885,7 +1930,7 @@ local function CreateStripGuideLines( nOutlineId, nStripId, nProfileId, nSolidLa EgtOffsetCurve( nStripMaxOffsetId, dMainStripMaxDelta) return nStripMinOffsetId, nStripMaxOffsetId - + end --------------------------------------------------------------------- @@ -1924,7 +1969,10 @@ local function CreateStripFromOutline( nAreaId, nOutlineId) -- recupero gli outline precedente e successivo ( non serve utilizzare un WIN_PRF accurato perchè conta solo sia diverso da split) local nOutlineLayerId = EgtGetParent( nOutlineId) - local nPrevOutlineId, nNextOutlineId = GetPrevNextOutline( WIN_PRF.NULL, nOutlineId, nOutlineLayerId) + local vPrevOutlineId, vNextOutlineId = GetPrevNextOutline( WIN_PRF.NULL, nOutlineId, nOutlineLayerId) + local nPrevOutlineId = vPrevOutlineId[1] + local nNextOutlineId = vNextOutlineId[1] + -- recupero i pezzi precedente e successivo, prendendo eventualmente quelli di bottomrail local nPrevPartId = FindAssociatedPart( nPrevOutlineId) local nNextPartId = FindAssociatedPart( nNextOutlineId) @@ -1940,20 +1988,20 @@ local function CreateStripFromOutline( nAreaId, nOutlineId) -- recupero guida Main local nGuideId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_MAINGUIDE) -- recupero strip piu' vicino a prev outline - local nMainStripId = GetStripNearestToOutline( nMainProfileId, nPrevOutlineId) + local nMainStripId = GetStripNearestToOutline( nMainProfileId, nOutlineId, nPrevOutlineId) -- estrudo MainStrip local nMainStripExtrusionId = EgtSurfTmSwept( nSolidLayerId, nMainStripId, nGuideId, false, WIN_SURF_APPROX) EgtSetName( nMainStripExtrusionId, WIN_SRF_STRIP) -- b) taglio con start -- recupero strip dello start piu' vicino ad outline - local nStartStripId = GetStripNearestToOutline( nStartProfileId, nOutlineId) + local nStartStripId = GetStripNearestToOutline( nStartProfileId, nPrevOutlineId, nOutlineId) -- disegno guida start per lo strip trovando le intersezioni degli outline minimi e massimi tra MainStrip e StartStrip local nMainStripMinOffsetId, nMainStripMaxOffsetId = CreateStripGuideLines( nOutlineId, nMainStripId, nMainProfileId, nSolidLayerId) local nStartStripMinOffsetId, nStartStripMaxOffsetId = CreateStripGuideLines( nPrevOutlineId, nStartStripId, nStartProfileId, nSolidLayerId) - local ptStripMinStart = EgtIP( nMainStripMinOffsetId, nStartStripMinOffsetId, EgtSP( nMainStripMinOffsetId)) - local ptStripMaxStart = EgtIP( nMainStripMaxOffsetId, nStartStripMaxOffsetId, EgtSP( nMainStripMaxOffsetId)) + local ptStripMinStart = FindIntersectionPoint( nMainStripMinOffsetId, nStartStripMinOffsetId) + local ptStripMaxStart = FindIntersectionPoint( nMainStripMaxOffsetId, nStartStripMaxOffsetId) local nStartStripGuideId = EgtLine( nSolidLayerId, ptStripMinStart, ptStripMaxStart) EgtExtendCurveStartByLen( nStartStripGuideId, 10) EgtExtendCurveEndByLen( nStartStripGuideId, 10) @@ -1972,12 +2020,12 @@ local function CreateStripFromOutline( nAreaId, nOutlineId) -- c) taglio con end -- recupero strip piu' vicino ad outline - local nEndStripId = GetStripNearestToOutline( nEndProfileId, nOutlineId) + local nEndStripId = GetStripNearestToOutline( nEndProfileId, nNextOutlineId, nOutlineId) -- disegno guida end per lo strip trovando le intersezioni degli outline minimi e massimi tra MainStrip ed EndStrip local nEndStripMinOffsetId, nEndStripMaxOffsetId = CreateStripGuideLines( nNextOutlineId, nEndStripId, nEndProfileId, nSolidLayerId) - local ptStripMinEnd = EgtIP( nMainStripMinOffsetId, nEndStripMinOffsetId, EgtSP( nMainStripMinOffsetId)) - local ptStripMaxEnd = EgtIP( nMainStripMaxOffsetId, nEndStripMaxOffsetId, EgtSP( nMainStripMaxOffsetId)) + local ptStripMinEnd = FindIntersectionPoint( nMainStripMinOffsetId, nEndStripMinOffsetId) + local ptStripMaxEnd = FindIntersectionPoint( nMainStripMaxOffsetId, nEndStripMaxOffsetId) local nEndStripGuideId = EgtLine( nSolidLayerId, ptStripMinEnd, ptStripMaxEnd) EgtExtendCurveStartByLen( nEndStripGuideId, 10) EgtExtendCurveEndByLen( nEndStripGuideId, 10) @@ -2069,7 +2117,7 @@ local function CalculateAreaParts( nAreaId) end end end - + -- disegno area di selezione per programma local nSelectionLayerId = EgtGroup( nAreaId) EgtSetName( nSelectionLayerId, WIN_SELECTION) diff --git a/Profiles/WinLib/WinCreate.lua b/Profiles/WinLib/WinCreate.lua index 50aa5db..3de3894 100644 --- a/Profiles/WinLib/WinCreate.lua +++ b/Profiles/WinLib/WinCreate.lua @@ -59,73 +59,141 @@ function WinCreate.ImportProfile( sProfilePath) return true end --- funzione che crea il buco rettangolare per la finestra -function WinCreate.CreateFrame( dWidth, dHeight, nJointBL, nJointBR, nJointTR, nJointTL) +---------------------------------------------------------------------------------- +------------------------------------- TELAIO ------------------------------------- +---------------------------------------------------------------------------------- +-- funzione che crea il buco per la finestra a partire da curve generiche +-- TO DO rendere i joints un vettore con un numero variabile a seconda del tipo di finestra +function WinCreate.CreateGenFrame( vFrameCrvs, nJointBL, nJointBR, nJointTL, nJointTR) -- creo gruppo per telaio local nFrameAreaId = EgtGroup( GDB_ID.ROOT) EgtSetName( nFrameAreaId, WIN_AREA .. '(' .. WIN_FRAME .. ')') -- imposto il tipo EgtSetInfo( nFrameAreaId, WIN_AREATYPE, WIN_AREATYPES.FRAME) + -- creo il gruppo con le curve di outline local nAreaOutlineLayerId = EgtGroup( nFrameAreaId) EgtSetName( nAreaOutlineLayerId, WIN_AREAOUTLINE) - EgtSetStatus( nAreaOutlineLayerId, GDB_ST.OFF) - -- disegno outline - local nFrameBottomId = EgtLine( nAreaOutlineLayerId, Point3d( 0, 0, 0), Point3d( dWidth, 0, 0)) - EgtSetName( nFrameBottomId, WIN_BOTTOM) - local nFrameRightId = EgtLine( nAreaOutlineLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dHeight, 0)) - EgtSetName( nFrameRightId, WIN_RIGHT) - local nFrameTopId = EgtLine( nAreaOutlineLayerId, Point3d( dWidth, dHeight, 0), Point3d( 0, dHeight, 0)) - EgtSetName( nFrameTopId, WIN_TOP) - local nFrameLeftId = EgtLine( nAreaOutlineLayerId, Point3d( 0, dHeight, 0), Point3d( 0, 0, 0)) - EgtSetName( nFrameLeftId, WIN_LEFT) + for i = 1, #vFrameCrvs do + EgtRelocateGlob( vFrameCrvs[i], nAreaOutlineLayerId) + end -- imposto tipo giunzioni EgtSetInfo( nAreaOutlineLayerId, WIN_JOINT_BL, nJointBL) EgtSetInfo( nAreaOutlineLayerId, WIN_JOINT_BR, nJointBR) EgtSetInfo( nAreaOutlineLayerId, WIN_JOINT_TL, nJointTL) EgtSetInfo( nAreaOutlineLayerId, WIN_JOINT_TR, nJointTR) - return nFrameAreaId + + return nFrameAreaId end --- funzione che crea il buco per la finestra -function WinCreate.CreateGenFrame( nFrameBottomId, nFrameRightId, nFrameTopId, nFrameLeftId, nJointBL, nJointBR, nJointTR, nJointTL) - -- creo gruppo per telaio - local nFrameAreaId = EgtGroup( GDB_ID.ROOT) - EgtSetName( nFrameAreaId, WIN_AREA .. '(' .. WIN_FRAME .. ')') - -- imposto il tipo - EgtSetInfo( nFrameAreaId, WIN_AREATYPE, WIN_AREATYPES.FRAME) - local nAreaOutlineLayerId = EgtGroup( nFrameAreaId) - EgtSetName( nAreaOutlineLayerId, WIN_AREAOUTLINE) + +---------------------------------------------------------------------------------- +-- funzione che crea le curve che definiscono il telaio in base alla geometria richiesta +local function CreateFrameCurves( nLayerId, nType, dWidth, dHeight, dVal) + + if nType == WIN_FRAME_TYPE.RECT then + -- telaio rettangolare + local nFrameBottomId = EgtLine( nLayerId, Point3d( 0, 0, 0), Point3d( dWidth, 0, 0)) + EgtSetName( nFrameBottomId, WIN_BOTTOM) + local nFrameRightId = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dHeight, 0)) + EgtSetName( nFrameRightId, WIN_RIGHT) + local nFrameTopId = EgtLine( nLayerId, Point3d( dWidth, dHeight, 0), Point3d( 0, dHeight, 0)) + EgtSetName( nFrameTopId, WIN_TOP) + local nFrameLeftId = EgtLine( nLayerId, Point3d( 0, dHeight, 0), Point3d( 0, 0, 0)) + EgtSetName( nFrameLeftId, WIN_LEFT) + + elseif nType == WIN_FRAME_TYPE.CHAMFER_SIDE then + -- dHeight è l'altezza del lato sx, dVal è l'altezza del lato dx + local nFrameBottomId = EgtLine( nLayerId, Point3d( 0, 0, 0), Point3d( dWidth, 0, 0)) + EgtSetName( nFrameBottomId, WIN_BOTTOM) + local nFrameRightId = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dVal, 0)) + EgtSetName( nFrameRightId, WIN_RIGHT) + local nFrameTopId = EgtLine( nLayerId, Point3d( dWidth, dVal, 0), Point3d( 0, dHeight, 0)) + EgtSetName( nFrameTopId, WIN_TOP) + local nFrameLeftId = EgtLine( nLayerId, Point3d( 0, dHeight, 0), Point3d( 0, 0, 0)) + EgtSetName( nFrameLeftId, WIN_LEFT) + + + elseif nType == WIN_FRAME_TYPE.CHAMFER then + -- dHeight è l'altezza dei lati verticali, dVal è l'altezza complessiva della finestra + local nFrameBottomId = EgtLine( nLayerId, Point3d( 0, 0, 0), Point3d( dWidth, 0, 0)) + EgtSetName( nFrameBottomId, WIN_BOTTOM) + local nFrameRightId = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dHeight, 0)) + EgtSetName( nFrameRightId, WIN_RIGHT) + local nFrameTop1Id = EgtLine( nLayerId, Point3d( dWidth, dHeight, 0), Point3d( dWidth / 2, dVal, 0)) + local nFrameTop2Id = EgtLine( nLayerId, Point3d( dWidth / 2, dVal, 0), Point3d( 0, dHeight, 0)) + EgtSetName( nFrameTop1Id, WIN_TOP) + EgtSetName( nFrameTop2Id, WIN_TOP) + local nFrameLeftId = EgtLine( nLayerId, Point3d( 0, dHeight, 0), Point3d( 0, 0, 0)) + EgtSetName( nFrameLeftId, WIN_LEFT) + + elseif nType == WIN_FRAME_TYPE.ROUND_ARC then + -- arco a tutto sesto + local nFrameBottomId = EgtLine( nLayerId, Point3d( 0, 0, 0), Point3d( dWidth, 0, 0)) + EgtSetName( nFrameBottomId, WIN_BOTTOM) + local nFrameRightId = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dHeight - 0.5 * dWidth, 0)) + EgtSetName( nFrameRightId, WIN_RIGHT) + local nFrameTopId = EgtArcCPA( nLayerId, Point3d( 0.5 * dWidth, dHeight - 0.5 * dWidth, 0), Point3d( dWidth, dHeight - 0.5 * dWidth, 0), 180, 0) + EgtSetName( nFrameTopId, WIN_TOP) + local nFrameLeftId = EgtLine( nLayerId, Point3d( 0, dHeight - 0.5 * dWidth, 0), Point3d( 0, 0, 0)) + EgtSetName( nFrameLeftId, WIN_LEFT) + + elseif nType == WIN_FRAME_TYPE.SEGMENTAL_ARC then + -- arco ribassato + -- dHeight è l'altezza dei lati verticali, dVal è l'altezza complessiva della finestra + local nFrameBottomId = EgtLine( nLayerId, Point3d( 0, 0, 0), Point3d( dWidth, 0, 0)) + EgtSetName( nFrameBottomId, WIN_BOTTOM) + local nFrameRightId = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dHeight, 0)) + EgtSetName( nFrameRightId, WIN_RIGHT) + local nFrameTopId = EgtArc3P( nLayerId, Point3d( dWidth, dHeight, 0), Point3d( 0.5 * dWidth, dVal, 0), Point3d( 0, dHeight, 0)) + EgtSetName( nFrameTopId, WIN_TOP) + local nFrameLeftId = EgtLine( nLayerId, Point3d( 0, dHeight, 0), Point3d( 0, 0, 0)) + EgtSetName( nFrameLeftId, WIN_LEFT) + + elseif nType == WIN_FRAME_TYPE.POINTED_ARC then + -- arco a tutto sesto + -- dHeight è l'altezza dei lati verticali, dVal è l'altezza complessiva della finestra + -- verifico che le due altezze abbiano valori sensati per realizzare i due archi + if dVal - dHeight < 0.5 * dWidth then + return + end + local nFrameBottomId = EgtLine( nLayerId, Point3d( 0, 0, 0), Point3d( dWidth, 0, 0)) + EgtSetName( nFrameBottomId, WIN_BOTTOM) + local nFrameRightId = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dHeight, 0)) + EgtSetName( nFrameRightId, WIN_RIGHT) + local nFrameTop1Id = EgtArc2PV( nLayerId, Point3d( dWidth, dHeight, 0), Point3d( 0.5 * dWidth, dVal, 0), Y_AX()) + EgtSetName( nFrameTop1Id, WIN_TOP) + local nFrameTop2Id = EgtArc2PV( nLayerId, Point3d( 0, dHeight, 0), Point3d( 0.5 * dWidth, dVal, 0), Y_AX()) + EgtInvertCurve( nFrameTop2Id) + EgtSetName( nFrameTop2Id, WIN_TOP) + local nFrameLeftId = EgtLine( nLayerId, Point3d( 0, dHeight, 0), Point3d( 0, 0, 0)) + EgtSetName( nFrameLeftId, WIN_LEFT) + + elseif nType == WIN_FRAME_TYPE.TRG then + local nFrameBottomId = EgtLine( nLayerId, Point3d( 0, 0, 0), Point3d( dWidth, 0, 0)) + EgtSetName( nFrameBottomId, WIN_BOTTOM) + local nFrameRightId = EgtLine( nLayerId, Point3d( dWidth, 0, 0), Point3d( dVal, dHeight, 0)) + EgtSetName( nFrameRightId, WIN_RIGHT) + local nFrameLeftId = EgtLine( nLayerId, Point3d( dVal, dHeight, 0), Point3d( 0, 0, 0)) + EgtSetName( nFrameLeftId, WIN_LEFT) + end +end + +---------------------------------------------------------------------------------- +-- funzione che crea il telaio a partire da una specifica geometria ( rettangolo, chamfer...) +function WinCreate.CreateFrame( nType, nJointBL, nJointBR, nJointTL, nJointTR, dWidth, dHeight, dHeight2) + + -- creo un gruppo temporaneo per le curve di outline + local nTmpLay = EgtGroup( GDB_ID.ROOT) -- disegno outline - EgtRelocateGlob( nFrameBottomId, nAreaOutlineLayerId) - EgtSetName( nFrameBottomId, WIN_BOTTOM) - EgtRelocateGlob( nFrameRightId, nAreaOutlineLayerId) - EgtSetName( nFrameRightId, WIN_RIGHT) - EgtRelocateGlob( nFrameTopId, nAreaOutlineLayerId) - EgtSetName( nFrameTopId, WIN_TOP) - EgtRelocateGlob( nFrameLeftId, nAreaOutlineLayerId) - EgtSetName( nFrameLeftId, WIN_LEFT) - -- imposto tipo giunzioni - EgtSetInfo( nAreaOutlineLayerId, WIN_JOINT_BL, nJointBL) - EgtSetInfo( nAreaOutlineLayerId, WIN_JOINT_BR, nJointBR) - EgtSetInfo( nAreaOutlineLayerId, WIN_JOINT_TL, nJointTL) - EgtSetInfo( nAreaOutlineLayerId, WIN_JOINT_TR, nJointTR) + CreateFrameCurves( nTmpLay, nType, dWidth, dHeight, dHeight2) + local nFrameAreaId = WinCreate.CreateGenFrame( EgtGetAllInGroup( nTmpLay), nJointBL, nJointBR, nJointTL, nJointTR) + EgtErase( nTmpLay) + return nFrameAreaId end --- -- funzione che crea il telaio a partire dal buco --- function WinCreate.CreateFrameOnHole( nHoleLayerId, dWidth, dHeight) --- local nAreaOutlineLayerId = EgtGroup( nHoleLayerId) --- EgtSetName( nAreaOutlineLayerId, WIN_OUTLINE) --- -- disegno outline --- local nHoleBottomId = EgtLine( nAreaOutlineLayerId, Point3d( 0, 0, 0), Point3d( dWidth, 0, 0)) --- EgtSetName( nHoleBottomId, WIN_BOTTOM) --- local nHoleRightId = EgtLine( nAreaOutlineLayerId, Point3d( dWidth, 0, 0), Point3d( dWidth, dHeight, 0)) --- EgtSetName( nHoleRightId, WIN_RIGHT) --- local nHoleTopId = EgtLine( nAreaOutlineLayerId, Point3d( dWidth, dHeight, 0), Point3d( 0, dHeight, 0)) --- EgtSetName( nHoleTopId, WIN_TOP) --- local nHoleLeftId = EgtLine( nAreaOutlineLayerId, Point3d( 0, dHeight, 0), Point3d( 0, 0, 0)) --- EgtSetName( nHoleLeftId, WIN_LEFT) --- end - +---------------------------------------------------------------------------------- +-------------------------------------- ANTA -------------------------------------- +---------------------------------------------------------------------------------- -- funzione che aggiunge una anta function WinCreate.AddSash( nAreaId, nJointBL, nJointBR, nJointTR, nJointTL, nSashType) -- creo nuova area @@ -158,6 +226,9 @@ function WinCreate.AddSash( nAreaId, nJointBL, nJointBR, nJointTR, nJointTL, nSa return nSashAreaId end +---------------------------------------------------------------------------------- +-------------------------------------- FILL -------------------------------------- +---------------------------------------------------------------------------------- -- funzione che aggiunge un riempimento function WinCreate.AddFill( nAreaId, FillType) -- creo nuova area @@ -176,32 +247,29 @@ function WinCreate.AddFill( nAreaId, FillType) EgtSetInfo( nOutlineId, WIN_SOU, nAreaOutlineId) EgtRemoveInfo( nOutlineId, WIN_CHILD) AddInfo( nAreaOutlineId, WIN_CHILD, nOutlineId) - EgtRemoveInfo( nAreaOutlineLayerId, WIN_JOINT_BL) - EgtRemoveInfo( nAreaOutlineLayerId, WIN_JOINT_BR) - EgtRemoveInfo( nAreaOutlineLayerId, WIN_JOINT_TL) - EgtRemoveInfo( nAreaOutlineLayerId, WIN_JOINT_TR) nAreaOutlineId = EgtGetNext( nAreaOutlineId) end + -- rimuovo eventuali info di giunzioni + EgtRemoveInfo( nAreaOutlineLayerId, WIN_JOINT_BL) + EgtRemoveInfo( nAreaOutlineLayerId, WIN_JOINT_BR) + EgtRemoveInfo( nAreaOutlineLayerId, WIN_JOINT_TL) + EgtRemoveInfo( nAreaOutlineLayerId, WIN_JOINT_TR) -- imposto tipo di fill EgtSetInfo( nFillAreaId, WIN_FILLTYPE, FillType) return nFillAreaId end +---------------------------------------------------------------------------------- +------------------------------------- SPLIT -------------------------------------- +---------------------------------------------------------------------------------- -- funzione che crea un taglio split -function WinCreate.AddSplit( nAreaLayerId, SplitType, MeasureType, nPosition, nProportion, nSplitType) +function WinCreate.AddSplit( nAreaLayerId, SplitType, MeasureType, nPosition, nProportion, nSplitType) -- creo layer temporaneo per split local nTempSplitLayerId = EgtGroup( nAreaLayerId) EgtSetName( nTempSplitLayerId, WIN_TEMPSPLIT) -- recupero contorno area precedente local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_AREAOUTLINE) local b3OutlineLayer = EgtGetBBox( nOutlineLayerId, GDB_BB.STANDARD) - local OutlineIds = {} - local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId) - while nOutlineId do - local sName = EgtGetName( nOutlineId) - table.insert( OutlineIds, nOutlineId) - nOutlineId = EgtGetNext( nOutlineId) - end local nTotSplitId if SplitType == WIN_SPLITORIENTATION.VERTICAL then -- creo linea @@ -232,6 +300,7 @@ function WinCreate.AddSplit( nAreaLayerId, SplitType, MeasureType, nPosition, n return nArea1Id, nArea2Id end +---------------------------------------------------------------------------------- -- funzione che crea tagli split multipli function WinCreate.AddSplits( nAreaLayerId, SplitType, MeasureType, PositionList, nProportion, nSplitType) local AreaList = {} @@ -285,6 +354,7 @@ function WinCreate.AddSplits( nAreaLayerId, SplitType, MeasureType, PositionList return AreaList end +---------------------------------------------------------------------------------- -- funzione che crea un taglio split da una curva generica function WinCreate.AddGenSplit( nAreaLayerId, nSplitId, nSplitType) -- se area nulla diventa di tipo split @@ -320,8 +390,8 @@ function WinCreate.AddGenSplit( nAreaLayerId, nSplitId, nSplitType) local EndInters for nIndex = 1, #OutlineInters do local CurrOutInters = OutlineInters[nIndex] - CurrOutInters.StartDistance = (CurrOutInters.IntersPoint - ptStartSplit):sqlen() - CurrOutInters.EndDistance = (CurrOutInters.IntersPoint - ptEndSplit):sqlen() + CurrOutInters.StartDistance = dist( CurrOutInters.IntersPoint, ptStartSplit) + CurrOutInters.EndDistance = dist( CurrOutInters.IntersPoint, ptEndSplit) if not StartInters or CurrOutInters.StartDistance < StartInters.StartDistance then StartInters = CurrOutInters end @@ -334,8 +404,36 @@ function WinCreate.AddGenSplit( nAreaLayerId, nSplitId, nSplitType) EgtTrimCurveStartAtParam( nSplitId, dStartSplitInters) local dEndSplitInters = EgtCurveParamAtPoint( nSplitId, EndInters.IntersPoint) EgtTrimCurveEndAtParam( nSplitId, dEndSplitInters) - EgtSetInfo( nSplitId, WIN_SPLIT_STARTINTERS, StartInters.Id) - EgtSetInfo( nSplitId, WIN_SPLIT_ENDINTERS, EndInters.Id) + + -- sistemo le info di intersezione + local dPar1 = EgtCurveParamAtPoint( StartInters.Id, StartInters.IntersPoint, 100 * GEO.EPS_SMALL) + local _, dParE1 = EgtCurveDomain( StartInters.Id) + if dPar1 < GEO.EPS_SMALL then + -- intersezione coinvolge anche curva precedente + local nOther = EgtGetPrev( StartInters.Id) or EgtGetLastInGroup( nOutlineLayerId) + EgtSetInfo( nSplitId, WIN_SPLIT_STARTINTERS, { nOther, StartInters.Id}) + elseif abs( dPar1 - dParE1) < GEO.EPS_SMALL then + -- intersezione coinvolge anche curva successiva + local nOther = EgtGetNext( StartInters.Id) or EgtGetFirstInGroup( nOutlineLayerId) + EgtSetInfo( nSplitId, WIN_SPLIT_STARTINTERS, { StartInters.Id, nOther}) + else + EgtSetInfo( nSplitId, WIN_SPLIT_STARTINTERS, { StartInters.Id}) + end + + local dPar2 = EgtCurveParamAtPoint( EndInters.Id, EndInters.IntersPoint, 100 * GEO.EPS_SMALL) + local _, dParE2 = EgtCurveDomain( EndInters.Id) + if dPar2 < GEO.EPS_SMALL then + -- intersezione coinvolge anche curva precedente + local nOther = EgtGetPrev( EndInters.Id) or EgtGetLastInGroup( nOutlineLayerId) + EgtSetInfo( nSplitId, WIN_SPLIT_ENDINTERS, { nOther, EndInters.Id}) + elseif abs( dPar2 - dParE2) < GEO.EPS_SMALL then + -- intersezione coinvolge anche curva successiva + local nOther = EgtGetNext( EndInters.Id) or EgtGetFirstInGroup( nOutlineLayerId) + EgtSetInfo( nSplitId, WIN_SPLIT_ENDINTERS, { EndInters.Id, nOther}) + else + EgtSetInfo( nSplitId, WIN_SPLIT_ENDINTERS, { EndInters.Id}) + end + -- assegno nome profilo EgtSetName( nSplitId, WIN_SPLIT) -- creo aree @@ -356,6 +454,7 @@ function WinCreate.AddGenSplit( nAreaLayerId, nSplitId, nSplitType) return nArea1Id, nArea2Id end +---------------------------------------------------------------------------------- -- funzione che crea tagli split da curve generiche function WinCreate.AddGenSplits( nAreaLayerId, SplitList) for nIndex = 1, #SplitList do @@ -363,6 +462,7 @@ function WinCreate.AddGenSplits( nAreaLayerId, SplitList) end end +---------------------------------------------------------------------------------- -- funzione che crea le aree da un taglio split function WinCreate.CreateAreaFromSplit( nAreaLayerId, nSplitId) -- creo layer per le due aree @@ -386,13 +486,18 @@ function WinCreate.CreateAreaFromSplit( nAreaLayerId, nSplitId) if ptInters then if nInters == 0 then -- trovato primo punto di intersezione - inizio area 2 - nInters = 1 - local nCopyId = EgtCopy( nOutlineId, nArea2OutlineLayerId) - EgtSetInfo( nCopyId, WIN_SOU, nOutlineId) - EgtRemoveInfo( nCopyId, WIN_CHILD) - AddInfo( nOutlineId, WIN_CHILD, nCopyId) - local dStartIntersParam = EgtCurveParamAtPoint( nCopyId, ptInters) - EgtTrimCurveStartAtParam( nCopyId, dStartIntersParam) + local dStartIntersParam = EgtCurveParamAtPoint( nOutlineId, ptInters) + local _, dParE = EgtCurveDomain( nOutlineId) + if abs( dStartIntersParam - dParE) < GEO.EPS_SMALL then + -- se intersezione nel punto finale della curva la ignoro, la ritroverò analizzando l'outline successivo + else + nInters = 1 + local nCopyId = EgtCopy( nOutlineId, nArea2OutlineLayerId) + EgtSetInfo( nCopyId, WIN_SOU, nOutlineId) + EgtRemoveInfo( nCopyId, WIN_CHILD) + AddInfo( nOutlineId, WIN_CHILD, nCopyId) + EgtTrimCurveStartAtParam( nCopyId, dStartIntersParam) + end elseif nInters == 1 then -- trovato secondo punto di intersezione - fine area 2 nInters = 2 @@ -423,6 +528,11 @@ function WinCreate.CreateAreaFromSplit( nAreaLayerId, nSplitId) EgtSetName( nSplitCopyId, WIN_LEFT) end -- inizio area 1 + local _, dEnd = EgtCurveDomain( nOutlineId) + if abs( dEndIntersParam - dEnd) < GEO.EPS_SMALL then + -- l'intersezione è sul punto finale della curva di outline, quindi è la curva successiva che dà inizio all'area 1 + nOutlineId = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( nOutlineLayerId) + end nCopyId = EgtCopy( nOutlineId, nArea1OutlineLayerId) EgtSetInfo( nCopyId, WIN_SOU, nOutlineId) EgtRemoveInfo( nCopyId, WIN_CHILD) @@ -495,10 +605,12 @@ function WinCreate.CreateAreaFromSplit( nAreaLayerId, nSplitId) nFirstInAreaId = EgtGetFirstInGroup( nArea2OutlineLayerId) sFirstInAreaName = EgtGetName( nFirstInAreaId) end - -- error('qqq') return nArea1Id, nArea2Id end +---------------------------------------------------------------------------------- +---------------------------------- BOTTOMRAIL ------------------------------------ +---------------------------------------------------------------------------------- -- funzione che aggiunge uno zoccolo function WinCreate.AddBottomRail( nAreaId) local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') @@ -510,8 +622,11 @@ function WinCreate.AddBottomRail( nAreaId) end end +---------------------------------------------------------------------------------- +---------------------------------- FERRAMENTA ------------------------------------ +---------------------------------------------------------------------------------- function WinCreate.AddHardware( nFrameId, sFavourite) - EgtSetInfo( nFrameId, WIN_HDW_FAVOURITE, sFavourite ) + EgtSetInfo( nFrameId, WIN_HDW_FAVOURITE, sFavourite) end --------------------------------------------------------------------- diff --git a/Profiles/WinLib/WinManageProject.lua b/Profiles/WinLib/WinManageProject.lua index ab4c0b2..208c809 100644 --- a/Profiles/WinLib/WinManageProject.lua +++ b/Profiles/WinLib/WinManageProject.lua @@ -160,11 +160,15 @@ local function ConvertTableToGeometry( AreaTable, nAreaId) ConvertCurveTableToEntity( nDrawFrameLayerId, CurrCurve) end local nFrameBottomId = EgtGetFirstInGroup(nDrawFrameLayerId) + EgtSetName( nFrameBottomId, WIN_BOTTOM) local nFrameRightId = EgtGetNext(nFrameBottomId) + EgtSetName( nFrameRightId, WIN_RIGHT) local nFrameTopId = EgtGetNext(nFrameRightId) + EgtSetName( nFrameTopId, WIN_TOP) local nFrameLeftId = EgtGetNext(nFrameTopId) + EgtSetName( nFrameLeftId, WIN_LEFT) -- creo frame - nAreaId = WinCreate.CreateGenFrame( nFrameBottomId, nFrameRightId, nFrameTopId, nFrameLeftId, AreaTable[JWD_JOINT][JWD_JOINT_BL], AreaTable[JWD_JOINT][JWD_JOINT_BR], AreaTable[JWD_JOINT][JWD_JOINT_TR], AreaTable[JWD_JOINT][JWD_JOINT_TL]) + nAreaId = WinCreate.CreateGenFrame( {nFrameBottomId, nFrameRightId, nFrameTopId, nFrameLeftId}, AreaTable[JWD_JOINT][JWD_JOINT_BL], AreaTable[JWD_JOINT][JWD_JOINT_BR], AreaTable[JWD_JOINT][JWD_JOINT_TR], AreaTable[JWD_JOINT][JWD_JOINT_TL]) -- elimino contorno frame EgtErase( nDrawFramePartId) -- se BottomRail @@ -185,7 +189,8 @@ local function ConvertTableToGeometry( AreaTable, nAreaId) EgtSetName( nDrawFramePartId, 'DrawFrame') local nDrawFrameLayerId = EgtGroup( nDrawFramePartId) ConvertCurveTableToEntity( nDrawFrameLayerId, AreaTable[JWD_SPLIT][1]) - local nArea1Id, nArea2Id = WinCreate.AddGenSplit( nAreaId, EgtGetFirstInGroup(nDrawFrameLayerId)) --, nSplitType) + local nArea1Id, nArea2Id = WinCreate.AddGenSplit( nAreaId, EgtGetFirstInGroup(nDrawFrameLayerId), AreaTable["SplitType"]) + -- local nArea1Id, nArea2Id = WinCreate.AddGenSplit( nAreaId, EgtGetFirstInGroup(nDrawFrameLayerId)) EgtErase(nDrawFramePartId) ConvertTableToGeometry( AreaTable[JWD_AREA .. 1], nArea1Id) ConvertTableToGeometry( AreaTable[JWD_AREA .. 2], nArea2Id) diff --git a/Profiles/WinProject.lua b/Profiles/WinProject.lua index f8d1cea..296cadf 100644 --- a/Profiles/WinProject.lua +++ b/Profiles/WinProject.lua @@ -43,7 +43,7 @@ end _G.WinCreate_ImportProfile = WinCreate_ImportProfile local function WinCreate_CreateFrame() - WDG.AREAID = WinCreate.CreateFrame(WDG.WIDTH, WDG.HEIGHT, WDG.JOINTBL, WDG.JOINTBR, WDG.JOINTTR, WDG.JOINTTL) + WDG.AREAID = WinCreate.CreateFrame(WDG.FRAMETYPE, WDG.JOINTBL, WDG.JOINTBR, WDG.JOINTTR, WDG.JOINTTL, WDG.WIDTH, WDG.HEIGHT, WDG.HEIGHT2) end _G.WinCreate_CreateFrame = WinCreate_CreateFrame