From a49ce81cb0655cf70d705bc052b4128ba514d89e Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Wed, 22 Jan 2020 11:21:22 +0000 Subject: [PATCH] DataBeam : - aggiunte funzioni sperimentali per ScarfJoint (dardo di giove) - in Mortise aggiunta gestione caso passante. --- LuaLibs/BeamExec.lua | 12 +- LuaLibs/ProcessMortise.lua | 168 +++++++++++++++++++++++--- LuaLibs/ProcessScarfJoint.lua | 214 ++++++++++++++++++++++++++++++++++ 3 files changed, 379 insertions(+), 15 deletions(-) create mode 100644 LuaLibs/ProcessScarfJoint.lua diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index ec4a7c2..a7695ad 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -1,8 +1,9 @@ --- BeamExec.lua by Egaltech s.r.l. 2019/11/04 +-- BeamExec.lua by Egaltech s.r.l. 2020/01/21 -- Libreria esecuzione lavorazioni per Travi -- 2019/07/11 Aggiunta gestione stato rotazione di feature per TS3. -- 2019/09/04 Corretto controllo feature di testa e coda con sovramateriale di testa elevato. -- 2019/09/25 Aggiunta gestione StepJoint e StepJointNotch +-- 2020/01/21 Aggiunta gestione ScarfJoint. -- Tabella per definizione modulo local BeamExec = {} @@ -60,6 +61,8 @@ _G.package.loaded.ProcessMark = nil local Mark = require( 'ProcessMark') _G.package.loaded.ProcessText = nil local Text = require( 'ProcessText') +_G.package.loaded.ProcessScarfJoint = nil +local ScarfJoint = require( 'ProcessScarfJoint') _G.package.loaded.ProcessSimpleScarf = nil local Scarf = require( 'ProcessSimpleScarf') _G.package.loaded.ProcessStepJoint = nil @@ -527,6 +530,9 @@ local function ClassifyFeatures( vProc, b3Raw, Stats) elseif Text.Identify( Proc) then bOk, bDown = Text.Classify( Proc) -- se giunto Gerber + elseif ScarfJoint.Identify( Proc) then + bOk, bDown = ScarfJoint.Classify( Proc) + -- se giunto Gerber elseif Scarf.Identify( Proc) then bOk, bDown = Scarf.Classify( Proc) -- se giunto a gradino @@ -674,6 +680,10 @@ local function AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, b3 elseif Text.Identify( Proc) then -- esecuzione testo bOk, sErr = Text.Make( Proc, nPhase, nRawId, nPartId) + -- se giunto Gerber ( 1/2-071-X) + elseif ScarfJoint.Identify( Proc) then + -- esecuzione giunto Gerber + bOk, sErr = ScarfJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se giunto Gerber ( 1/2-070-X) elseif Scarf.Identify( Proc) then -- esecuzione giunto Gerber diff --git a/LuaLibs/ProcessMortise.lua b/LuaLibs/ProcessMortise.lua index af4d4fc..38d9bc6 100644 --- a/LuaLibs/ProcessMortise.lua +++ b/LuaLibs/ProcessMortise.lua @@ -23,16 +23,34 @@ function ProcessMortise.Identify( Proc) end --------------------------------------------------------------------- --- Classificazione della feature +-- Classificazione della feature: decide se la feature è in una posizione che per lavorala +-- deve essere ribaltata o no function ProcessMortise.Classify( Proc) + -- recupero e verifico il percorso supplementare + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero versore estrusione della curva supplementare e non più della superficie + -- perché quest'ultima potrebbe non avere il fondo e dare quindi un risultato non corretto + local vtExtr = EgtCurveExtrusion( AuxId or GDB_ID.NULL, GDB_ID.ROOT) -- recupero i dati della faccia di fondo local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) -- verifico sia una superficie + if not vtExtr then + return false + end if not vtN then return false end - -- verifico se la mortasa è lavorabile solo da sotto - local bDown = ( vtN:getZ() < - 0.1) + local bDown + -- Confronto le 2 direzioni Z dei versori + -- se differiscono allora la faccetta 0 della superficie non è il fondo della mortasa+ + -- e quindi la mortasa è passante + if abs( vtExtr:getZ() - vtN:getZ()) > GEO.EPS_SMALL then + bDown = false + else -- se è chiusa + -- verifico se la mortasa è lavorabile solo da sotto + bDown = ( vtN:getZ() < - 0.1) + end return true, bDown end @@ -41,7 +59,11 @@ end function ProcessMortise.Make( Proc, nPhase, nRawId, nPartId) -- recupero e verifico l'entità curva local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') - if AuxId then AuxId = AuxId + Proc.Id end + local bForceOneSide + local bRevertSide + if AuxId then + AuxId = AuxId + Proc.Id + end if not AuxId or ( EgtGetType( AuxId) & 256) == 0 then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' EgtOutLog( sErr) @@ -53,17 +75,65 @@ function ProcessMortise.Make( Proc, nPhase, nRawId, nPartId) EgtCloseCurveCompo( AuxId) EgtSetInfo( AuxId, 'OPEN', nCount) end + -- recupero versore estrusione della curva supplementare e confronto la direzione Z + -- del versore della componente Z della superficie + local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT) -- recupero i dati del bottom local frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) local ptC = frMor:getOrigin() local vtN = frMor:getVersZ() - EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) - -- verifico che la mortasa non sia orientata verso il basso (limite -5 deg) - if vtN:getZ() < - 0.1 then - local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mortise from bottom impossible' - EgtOutLog( sErr) - return false, sErr + local bNotExistBtm + -- Confronto le 2 direzioni Z dei versori + -- se differiscono allora la faccetta 0 della superficie non è il fondo della mortasa+ + -- e quindi la mortasa è passante + if abs( vtExtr:getZ() - vtN:getZ()) > GEO.EPS_SMALL then + -- creo superficie chiusa + local nFlat = EgtSurfTmByFlatContour( EgtGetParent(AuxId), AuxId, 0.02) + if nFlat then + frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT) + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + -- verifico se copiare la geometria lungo l'asse Z + local b3Aux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frMor) + local bxMax = b3Aux:getMax() + local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor) + local bxMin = b3Mor:getMin() + local dMove = bxMin:getZ()-bxMax:getZ() + -- se il percorso ausiliario è esterno al grezzo, lo riavvicino + if abs( dMove) > GEO.EPS_SMALL then + AuxId = EgtCopyGlob( AuxId, BL.GetAddGroup(nPartId)) + EgtMove( AuxId, Vector3d(0,0,-dMove)) + EgtMove( nFlat, Vector3d(0,0,-dMove)) + frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT) + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + end + -- cancello le prove del misfatto (superficie piana) + EgtErase(nFlat) + -- setto il flag che indica che non c'è il fondo + bNotExistBtm = true + end end + -- scrivo info nel log + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + if not bNotExistBtm then + -- verifico che la mortasa non sia orientata verso il basso (limite -5 deg) + if vtN:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mortise from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + else -- se mortasa passante + -- determino se la mortasa da lavorare sul lato opposto sia di angolo inferiore a quello consentito + if abs(vtN:getZ()) > 0.1 then + bForceOneSide = true + end + -- determino se è meglio lavorare la mortasa nel lato opposto + if vtN:getZ() < -GEO.EPS_SMALL then + bRevertSide = true + end + end + -- determino altezza della mortasa local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor) local dMorH = b3Mor:getDimZ() @@ -97,21 +167,48 @@ function ProcessMortise.Make( Proc, nPhase, nRawId, nPartId) EgtOutLog( sErr) return false, sErr end + -- verifico se invertire versore estrusione geometria + if bRevertSide then + EgtModifyCurveExtrusion( AuxId, -vtExtr, GDB_ID.ROOT) + end -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) -- imposto posizione braccio porta testa if vtN:getY() < GEO.EPS_SMALL then - EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + if bRevertSide then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + end else - EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + if bRevertSide then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + end + local sWarn + local nDepthMin + -- se la mortasa è passante e non è forzata a un solo lato, riduco l'affondamento a metà profondità + if bNotExistBtm and not bForceOneSide then + dMorH = dMorH * 0.5 end -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente - local sWarn if dMorH > dMaxDepth + 10 * GEO.EPS_SMALL then sWarn = 'Warning in mortise : elevation (' .. EgtNumToString( dMorH,1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth,1) .. ')' - EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dMorH) + if not bRevertSide then -- se non ho invertito la direzione di estrusione + nDepthMin = dMaxDepth - EgtIf( bNotExistBtm and not bForceOneSide, dMorH*2, dMorH) + else + nDepthMin = dMaxDepth + end + EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin) dMorH = dMaxDepth EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + else + if bNotExistBtm and not bForceOneSide then -- se mortasa passante setto metà profondità + nDepthMin = -dMorH + EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin) + end end -- imposto elevazione EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMorH, 1) .. ';') @@ -121,6 +218,49 @@ function ProcessMortise.Make( Proc, nPhase, nRawId, nPartId) EgtSetOperationMode( nMchFId, false) return false, sErr end + -- ESPERIMENTO: + -- se non c'è il fondo e la lavorazione non ha lavorato tutta la superficie per limite altezza utensile + -- inserisco una ulteriore lavorazione contraria + if bNotExistBtm and not bForceOneSide and nDepthMin and abs(nDepthMin) > 0 then + -- inserisco la lavorazione di svuotatura opposta + sName = 'Mort_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_Oppo' + nMchFId = EgtAddMachining( sName, sPocketing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + EgtOutLog( sErr) + return false, sErr + end + -- faccio la copia e la metto nel layer dedicato alle geometrie aggiunte + local AuxId_oppo = EgtCopyGlob( AuxId, BL.GetAddGroup(nPartId)) + -- inverto la direzione estrusione di questa + EgtModifyCurveExtrusion( AuxId_oppo, - vtExtr, GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId_oppo, -1}}) + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + end + -- se altezza mortasa differente da altezza massima lavorabile + if abs(dMorH - dMaxDepth) > GEO.EPS_SMALL then + nDepthMin = -dMorH + else -- se sono uguali setto + nDepthMin = -(dMorH - BD.CUT_EXTRA) + end + + -- setto profondità + EgtSetMachiningParam( MCH_MP.DEPTH, -nDepthMin+BD.CUT_EXTRA) + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( (-nDepthMin+BD.CUT_EXTRA), 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, sWarn end diff --git a/LuaLibs/ProcessScarfJoint.lua b/LuaLibs/ProcessScarfJoint.lua new file mode 100644 index 0000000..71bd04e --- /dev/null +++ b/LuaLibs/ProcessScarfJoint.lua @@ -0,0 +1,214 @@ +-- ProcessScarfJoint.lua by Egaltech s.r.l. 2020/01/21 +-- Gestione calcolo giunto Gerber per Travi + +-- Tabella per definizione modulo +local ProcessScarfJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessScarfJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessScarfJoint.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 71) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessScarfJoint.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 and Proc.Box:getDimX() / abs( vtN:getZ()) > BD.MAX_DIM_DICE then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessScarfJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + return true + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getY()) > 0.1 or abs( vtN[i]:getZ()) > 0.1 then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per facce inclinate + local vtRef2 = Vector3d( vtN[vFaceOrd[2]]) + -- eseguo + for i = 1, #vCuts do + local nOrthoOpposite + if i % 2 == 1 then + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + else + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef2) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local vtRef2 = vtN[vFaceOrd[2]] + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[2] - 1) + if DimV <= DimH then + vtRef2 = Vector3d( frHV:getVersY()) + else + vtRef2 = Vector3d( frHV:getVersX()) + end + end + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef2) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessScarfJoint