-- ProcessDoubleCut.lua by Egaltech s.r.l. 2023/03/22 -- Gestione calcolo doppi tagli di lama per Travi -- 2022/08/29 Implementata la fresatura dal lato per tagli problematici per PF1250. -- 2023/03/22 Eliminata SetOpenSide locale, si usa quella di libreria. -- 2023/12/07 Correzione in Classify in scelta ribaltamento trave quando si è in condizioni downUp -- Tabella per definizione modulo local ProcessDoubleCut = {} -- Include require( 'EgtBase') local BL = require( 'BeamLib') local Fbs = require( 'FacesBySaw') local DC = require( 'DiceCut') local Cut = require( 'ProcessCut') EgtOutLog( ' ProcessDoubleCut started', 1) -- Dati local BD = require( 'BeamData') local ML = require( 'MachiningLib') --------------------------------------------------------------------- -- Riconoscimento della feature function ProcessDoubleCut.Identify( Proc) return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 11) end --------------------------------------------------------------------- -- Classificazione della feature function ProcessDoubleCut.Classify( Proc, b3Raw) --se una faccia, uso la classificazione dei tagli singoli if Proc.Fct == 1 then return Cut.Classify( Proc, b3Raw) end -- se PF con testa da sotto o TURN, ammessa qualunque orientazione if ( BD.C_SIMM and BD.DOWN_HEAD) or BD.TURN then return true end -- determino se convesso o concavo local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) local bConvex = ( not bAdj or ( dAng > 0)) -- se convesso if bConvex then -- recupero i dati di ogni singola faccia for i = 1, 2 do local nFac = i - 1 local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFac, GDB_ID.ROOT) if ( vtN:getZ() <= - 0.5 and abs( vtN:getY()) > 0.1) or ( vtN:getZ() <= - 0.174 and abs( vtN:getY()) > 0.866) then -- calcolo la massima estensione orizzontale lineare della faccia local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, nFac, b3Raw) -- confronto questa estensione con la massima dimensione del DiceCut (impossibile lavorare se maggiore) if DimH > BD.MAX_DIM_DICE and DimV > BD.MAX_DIM_DICE then return true, true end end local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw, vtN) local bDownCut = ( vtN:getZ() <= dNzLimDwnUp) if bDownCut then -- recupero i dati della lama local sCutType = EgtIf( Proc.Head, 'HeadSide', 'TailSide') local sCutting = ML.FindCutting( sCutType, true, false) local dMaxDepth = 0 local dMaxMat = 0 if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat end end -- calcolo l'ingombro orizzontale della faccia local _, DimH = BL.GetFaceHvRefDim( Proc.Id, nFac) -- confronto questo ingombro con il doppio della massima dimensione del DiceCut (impossibile lavorare sotto da sopra se più di 2 tagli oppure se tipo PF, taglio inclinato in Y e non taglio singolo orizzontale) if DimH > 2 * BD.MAX_DIM_DICE or ( BD.C_SIMM and abs( vtN:getY()) > 0.1 and dMaxMat < DimH + BD.CUT_EXTRA) then return true, true end end end return true, false -- altrimenti concavo, verifico le normali delle facce per tagli da sotto else local ptC = {} local vtN = {} ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) local vtX = vtN[1] ^ vtN[2] ; vtX:normalize() local vtY = { vtX ^ vtN[1], - vtX ^ vtN[2]} for i = 1, 2 do local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw, vtN[i], vtY[i]) local bDownCut = ( vtN[i]:getZ() <= dNzLimDwnUp) if bDownCut then -- dimensione della faccia perpendicolarmente alla linea di intersezione tra le facce local frRef = Frame3d( ptC[i], ptC[i] + 100 * vtX, ptC[i] + 100 * vtY[i]) local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, i-1, GDB_BB.STANDARD, frRef) -- dimensione dell'altra faccia perpendicolarmente alla linea di intersezione tra le facce local frRef2 = Frame3d( ptC[3-i], ptC[3-i] + 100 * vtX, ptC[3-i] + 100 * vtY[3-1]) local b3Ref2 = EgtSurfTmGetFacetBBoxRef( Proc.Id, 2-i, GDB_BB.STANDARD, frRef2) -- se faccia grande if b3Ref:getDimY() > BD.MAX_DIM_DICE then -- se altra faccia piccola if b3Ref2:getDimY() < BD.MAX_DIM_DICE then return true, true else return false end end end end return true, false end end --------------------------------------------------------------------- -- lavorazione smussi local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) -- verifico che lo smusso sia richiesto local dDepth = EgtGetInfo( Proc.Id, 'Q06', 'd') or 0 if dDepth < 0.1 then return true end -- ingombro del grezzo local b3Raw = EgtGetRawPartBBox( nRawId) -- recupero e verifico l'entità curva associata local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') if AuxId then AuxId = AuxId + Proc.Id end if not AuxId then return true end if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then local sErr = 'Error : missing profile geometry' EgtOutLog( sErr) return false, sErr end -- recupero i dati della curva e del profilo local dWidth = abs( EgtCurveThickness( AuxId)) local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) -- eseguo lo smusso solo se direzione orizzontale o anche testa da sotto (non propago la segnalazione a TS3) local bVert = ( abs( vtExtr:getZ()) > 0.1) if bVert and not BD.DOWN_HEAD then local sWarn = 'Warning : skipped not horizontal chamfer' EgtOutLog( sWarn) return true end -- eseguo lo smusso solo se feature larga come la trave if ( not bVert and dWidth < b3Raw:getDimY() - 1) or ( bVert and dWidth < b3Raw:getDimZ() - 1) then local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' EgtOutLog( sWarn) return true, sWarn end local dExtra = 2 -- recupero la lavorazione local sMilling = ML.FindMilling( 'Mark') if not sMilling then local sErr = 'Error : milling (Mark) not found in library' EgtOutLog( sErr) return false, sErr end local sMillingDw = ML.FindMilling( 'Mark_H2', nil, nil, nil, nil, false, true) if bVert and not sMillingDw then local sErr = 'Error : milling (Mark_H2) not found in library' EgtOutLog( sErr) return false, sErr end -- Inserisco la lavorazione del lato standard local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMch1Id = EgtAddMachining( sName1, EgtIf( not bVert or vtExtr:getZ() > 0.1, sMilling, sMillingDw)) if not nMch1Id then local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) -- assegno affondamento e offset radiale EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) -- assegno lato di lavoro EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) -- eseguo if not ML.ApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMch1Id, false) return false, sErr end -- Inserisco la lavorazione del lato opposto local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMch2Id = EgtAddMachining( sName2, EgtIf( not bVert or vtExtr:getZ() < -0.1, sMilling, sMillingDw)) if not nMch2Id then local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) -- inverto direzione utensile EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) -- assegno affondamento e offset radiale EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) -- assegno lato di lavoro EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) -- eseguo if not ML.ApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMch2Id, false) return false, sErr end return true end --------------------------------------------------------------------- local function VerifyPocket( Proc, dDiam, dDepth, dMaxTotLen, sMchFindMaster, bPocketDown) -- tipo di svuotatura local sMchFind = EgtIf( sMchFindMaster and #sMchFindMaster > 0, sMchFindMaster, 'Pocket') -- ricerca della svuotatura local sPocketing if dDepth then sPocketing = ML.FindPocketing( sMchFind, dDiam, dDepth, dMaxTotLen, not bPocketDown, bPocketDown) or ML.FindPocketing( sMchFind, dDiam, 0.8 * dDepth, dMaxTotLen, not bPocketDown, bPocketDown) or ML.FindPocketing( sMchFind, dDiam, 0.6 * dDepth, dMaxTotLen, not bPocketDown, bPocketDown) or ML.FindPocketing( sMchFind, dDiam, 0.4 * dDepth, dMaxTotLen, not bPocketDown, bPocketDown) or ML.FindPocketing( sMchFind, dDiam, 0, dMaxTotLen) else sPocketing = ML.FindPocketing( sMchFind, dDiam, 0, dMaxTotLen) end if not sPocketing then return false end -- recupero i dati dell'utensile local bUsePocketing = false local dMaxDepth = 0 local dToolDiam = 0 if EgtMdbSetCurrMachining( sPocketing) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth end bUsePocketing = true end return bUsePocketing, sPocketing, dMaxDepth, dToolDiam end --------------------------------------------------------------------- local function MakeBySidePocket( Proc, nPhase, nRawId, nPartId, nAddGrpId, b3Solid) local nFirstMachId local sWarn local sMchFind = 'OpenPocket' local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt local bBadMach = false -- ottengo le dimensioni del tunnel dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = BL.GetTunnelDimension( Proc, nPartId) -- posso utilizzare utensile con diametro doppio della dimensione minima dDimMin = min( 2 * dDimMin, BD.MAXDIAM_POCK_CORNER) local nPathInt -- verifico se è presente la testa da sotto e se è necessario usarla bMillDown = ( BD.DOWN_HEAD == true and abs( vtOrtho:getZ()) >= 0.707) -- cerco l'utensile di svuotatura per la testa sopra local bMakePocket, sPocketing, dMaxDepth, dDiamTool = VerifyPocket( Proc, dDimMin, dDepth / 2, nil, sMchFind) local bMakePocketDn, sPocketingDn, dMaxDepthDn, dDiamToolDn -- cerco anche l'utensile per la testa sotto, nel caso servisse if bMillDown then bMakePocketDn, sPocketingDn, dMaxDepthDn, dDiamToolDn = VerifyPocket( Proc, dDimMin, dDepth / 2, nil, sMchFind, true) -- se è negativo inverto il versore e la faccia if vtOrtho:getZ() < 0 then vtOrtho = -vtOrtho EgtInvertSurf( nSurfInt) end end if bMakePocket then -- gestione svuotatura da un solo lato o anche dal lato opposto (se non verticale) -- estraggo il contorno dalla superfice per evitare i problemi con la svuotatura -- e assegno l'estrusione nPathInt = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) EgtModifyCurveExtrusion( nPathInt, vtOrtho, GDB_RT.GLOB) BL.SetOpenSide( nPathInt, b3Solid) -- variabili per parametri lavorazione local dMachDepth local dElev = 0 local bDoubleSide local bOneShot local bComplete = true -- imposto altezza aggiuntiva di elevazione local dCollSic = BL.CalcCollisionSafety( vtOrtho) -- se possibile svuotare completamente da una sola parte if dMaxDepth > ( dDepth + BD.CUT_EXTRA + dCollSic) then dMachDepth = ( dDepth / 2) + BD.CUT_EXTRA dElev = dDepth + BD.CUT_EXTRA bOneShot = true else -- se direzione verso la verticale setto max affondamento possibile ed -- emetto messaggio di warning perché non lavorabile interamente if abs( vtOrtho:getZ()) >= 0.707 and not BD.DOWN_HEAD then dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic dElev = dMaxDepth sWarn = 'Warning : elevation bigger than max tool depth' EgtOutLog( sWarn) bComplete = false -- altrimenti setto il flag per fare la svuotatura da due parti else -- se l'altezza utensile riesce a lavorare completamente da due parti if dMaxDepth > ( dDepth / 2) + dCollSic + BD.CUT_EXTRA_MIN then dMachDepth = BD.CUT_EXTRA_MIN dElev = ( dDepth / 2) + BD.CUT_EXTRA_MIN -- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione else dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic dElev = dMaxDepth -- se molto inclinato rispetto alla normale della faccia di riferimento, lavorazione non idonea per probabili collisioni local vtRef = Y_AX() if abs( vtOrtho:getX()) > abs( vtOrtho:getY()) and abs( vtOrtho:getX()) > abs( vtOrtho:getZ()) then vtRef = X_AX() elseif abs( vtOrtho:getZ()) > abs( vtOrtho:getX()) and abs( vtOrtho:getZ()) > abs( vtOrtho:getY()) then vtRef = Z_AX() end if abs( vtOrtho * vtRef) < 0.5 then bBadMach = true end end bDoubleSide = true end end -- inserisco la lavorazione di svuotatura local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMchFId = EgtAddMachining( sName, sPocketing) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing EgtOutLog( sErr) return -1, sErr end -- prendo l'id della prima lavorazione inserita if not nFirstMachId then nFirstMachId = nMchFId end -- aggiungo geometria EgtSetMachiningGeometry( {{ nPathInt, -1}}) -- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale) local bInvertMach if vtOrtho:getZ() < BD.NZ_MINA and abs(vtOrtho:getZ()) >= 0.707 and not BD.DOWN_HEAD then EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) bInvertMach = true -- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti elseif not bDoubleSide and vtOrtho:getY() > GEO.EPS_SMALL and not ( -(vtOrtho:getZ()) < BD.NZ_MINA) then EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) bInvertMach = true end -- imposto posizione braccio porta testa local nSCC = MCH_SCC.NONE if not BD.C_SIMM then if AreSameOrOppositeVectorApprox( vtOrtho, Z_AX()) then nSCC = MCH_SCC.ADIR_YM elseif abs( vtOrtho:getX()) < 0.1 then nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) elseif vtOrtho:getY() < GEO.EPS_SMALL then nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) else nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP) end end EgtSetMachiningParam( MCH_MP.SCC, nSCC) EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) -- inverto il percorso di lavorazione per lavorare sinistro EgtSetMachiningParam( MCH_MP.INVERT, true) -- imposto affondamento EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) -- imposto elevazione e dichiaro non si generano sfridi per VMill local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' sNotes = sNotes .. 'VMRS=0;' EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) -- eseguo if not ML.ApplyMachining( true, false) then -- provo ad allargare leggermente la tasca EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) if not ML.ApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return -1, sErr end end -- se posso applicare la svuotatura sul lato opposto if bDoubleSide then -- se ho la lavorazione da sotto ricalcolo in base a questa lavorazione if bMakePocketDn then -- sPocketing = sPocketingDn -- dMaxDepth = dMaxDepthDn -- dDiamTool = dDiamToolDn -- se l'altezza utensile riesce a lavorare completamente da due parti if dMaxDepthDn > ( dDepth / 2) + dCollSic + BD.CUT_EXTRA_MIN then dMachDepth = BD.CUT_EXTRA_MIN dElev = ( dDepth / 2) + BD.CUT_EXTRA_MIN -- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione else dMachDepth = dMaxDepthDn - ( dDepth / 2) - dCollSic dElev = dMaxDepthDn bComplete = false sWarn = 'Warning : elevation bigger than max tool depth' EgtOutLog( sWarn) end else -- se anche lavorando dal lato opposto non riesco a svuotare completamente la fessura -- setto i parametri affondamento ed emetto warning if dMaxDepth < ( dDepth / 2) + BD.CUT_EXTRA + dCollSic then dMachDepth = dMaxDepth - (dDepth / 2) - dCollSic dElev = dMaxDepth bComplete = false sWarn = 'Warning : elevation bigger than max tool depth' EgtOutLog( sWarn) end end -- inserisco la lavorazione di svuotatura local sName = 'PockOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMchFId = EgtAddMachining( sName, EgtIf( bMakePocketDn, sPocketingDn, sPocketing)) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. EgtIf( bMakePocketDn, sPocketingDn, sPocketing) EgtOutLog( sErr) return -1, sErr end -- prendo l'id della prima lavorazione inserita if not nFirstMachId then nFirstMachId = nMchFId end -- aggiungo geometria EgtSetMachiningGeometry( {{ nPathInt, -1}}) -- imposto direzione utensile opposta EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) -- imposto posizione braccio porta testa local nSCC = MCH_SCC.NONE if not BD.C_SIMM then if AreSameVectorApprox( vtOrtho, Z_AX()) then nSCC = MCH_SCC.ADIR_YM elseif abs( vtOrtho:getX()) < 0.1 then nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) elseif vtOrtho:getY() < GEO.EPS_SMALL then nSCC = MCH_SCC.ADIR_YP else nSCC = MCH_SCC.ADIR_YM end end EgtSetMachiningParam( MCH_MP.SCC, nSCC) EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) -- inverto il percorso di lavorazione per lavorare sinistro EgtSetMachiningParam( MCH_MP.INVERT, true) -- imposo affondamento EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) -- imposto elevazione e dichiaro non si generano sfridi per VMill local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' sNotes = sNotes .. 'VMRS=0;' EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) -- eseguo if not ML.ApplyMachining( true, false) then -- provo ad allargare leggermente la tasca EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) if not ML.ApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return -1, sErr end end end return 1, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId end return 0, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId, bOrthoFaces end --------------------------------------------------------------------- -- Applicazione della lavorazione function ProcessDoubleCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) -- se singola faccia, passo a quella lavorazione if Proc.Fct == 1 then return Cut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, nil, nil, bForced, b3Raw, sNotes, dOvmTail, true) end -- ingombro del grezzo 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 : part box not found' EgtOutLog( sErr) return false, sErr end -- dati delle facce local ptC = {} local vtN = {} ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) -- normale media per capire se taglio di testa o di coda local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() local bHead = ( vtNm:getX() > 0) -- angolo diedro per stabilire se taglio convesso local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) local bConvex = true local bOnY = true local ptPs = ( ptC[1] + ptC[2]) / 2 if bAdj then local vtDir = ptP1 - ptP2 ; vtDir:normalize() bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) ptPs = ( ptP1 + ptP2) / 2 bConvex = ( dAng > 0) end -- determino quale faccia è più grande local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0) local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1) local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2) local nSmaInd = 3 - nBigInd -- inserimento smussi local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) if not bOkc then return bOkc, sErrC end -- recupero gruppo per geometria addizionale local nAddGrpId = BL.GetAddGroup( nPartId) if not nAddGrpId then local sErr = 'Error : missing AddGroup' EgtOutLog( sErr) return false, sErr end -- se convesso, lo tratto come due tagli singoli if bConvex then -- lavoro per prima la faccia più diretta in alto local vOrd = { 1, 2} if vtN[2]:getZ() > vtN[1]:getZ() then vOrd = { 2, 1} end -- creo piano di taglio coincidente con la prima faccia e lo lavoro local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[1]], vtN[vOrd[1]], b3Solid, GDB_RT.GLOB) if AddId then EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) EgtSetInfo( AddId, 'TASKID', Proc.TaskId) local b3Add = EgtGetBBoxGlob( AddId, GDB_BB.STANDARD) -- applico lavorazione local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Add, Fct = 1, Flg = Proc.Flg, Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId, PartId = Proc.PartId} CutProc.AffectedFaces = BL.GetProcessAffectedFaces( CutProc) local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead, nil, nil, bForced, b3Raw, sNotes, dOvmTail, true) if not bOk then return bOk, sErr end end -- creo piano di taglio coincidente con la seconda faccia e lo lavoro AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[2]], vtN[vOrd[2]], b3Solid, GDB_RT.GLOB) if AddId then EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) EgtSetInfo( AddId, 'TASKID', Proc.TaskId) local b3Add = EgtGetBBoxGlob( AddId, GDB_BB.STANDARD) -- applico lavorazione local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Add, Fct = 1, Flg = Proc.Flg, Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId, PartId = Proc.PartId} CutProc.AffectedFaces = BL.GetProcessAffectedFaces( CutProc) local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead, nil, nil, bForced, b3Raw, sNotes, dOvmTail, true) if not bOk then return bOk, sErr end end -- altrimenti concavo else -- eseguo local sCutType = EgtIf( bHead, 'HeadSide', 'TailSide') local bDownHead = ( BD.DOWN_HEAD and vtNm:getZ() < BD.NZ_MINB) -- per tutte le macchine tranne la Fast, controllo se ci sono tagli troppo inclinati e troppo profondi per la lama -- in tal caso richiamo la lavorazione con fresa dal lato if BD.C_SIMM and not bDownHead then local sCutting = ML.FindCutting( sCutType, nil, bDownHead) if not sCutting then local sErr = 'Error : cutting not found in library' EgtOutLog( sErr) return false, sErr end local dMaxDepth = 0 if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth end end local _, _, dDimV1 = BL.GetFaceHvRefDim( Proc.Id, 0, b3Raw) local _, _, dDimV2 = BL.GetFaceHvRefDim( Proc.Id, 1, b3Raw) local bFace1TooLongForBlade, bFace2TooLongForBlade = ( dDimV1 >= dMaxDepth), ( dDimV2 >= dMaxDepth) local dFace1Ang, dFace2Ang = vtN[1]:getZ(), vtN[2]:getZ() if bFace1TooLongForBlade and dFace1Ang < ( BD.CUT_VZ_MIN or -0.484) or bFace2TooLongForBlade and dFace2Ang < ( BD.CUT_VZ_MIN or -0.484) then local bOk, sErr = MakeBySidePocket( Proc, nPhase, nRawId, nPartId, nAddGrpId, b3Solid) return bOk, sErr end end local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, sCutType, false, bDownHead) if not bOk then return bOk, sErr end -- segnalazione ingombro di testa o coda if Proc.Head then -- intersezioni con linee a metà altezza appena dentro dal davanti e dal dietro local ptRef = b3Raw:getCenter() - 0.5 * b3Raw:getDimX() * X_AX() local ptL1 = ptRef - ( 0.5 * b3Raw:getDimY() - 0.1) * Y_AX() local ptL2 = ptRef + ( 0.5 * b3Raw:getDimY() - 0.1) * Y_AX() local bInt1, IntTy1, IntPar1 = EgtLineSurfTmInters( ptL1, X_AX(), Proc.Id, GDB_ID.ROOT) local bInt2, IntTy2, IntPar2 = EgtLineSurfTmInters( ptL2, X_AX(), Proc.Id, GDB_ID.ROOT) local dMinPar = b3Raw:getDimX() if IntPar1 and #IntPar1 > 0 then dMinPar = min( dMinPar, IntPar1[1]) end if IntPar2 and #IntPar2 > 0 then dMinPar = min( dMinPar, IntPar2[1]) end local dOffs = b3Raw:getDimX() - dMinPar BL.UpdateHCING( nRawId, dOffs) elseif Proc.Tail then -- accetto approssimazione più grezza local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() if vtNm:getZ() > 0.5 then dOffs = 0.4 * dOffs elseif abs( vtNm:getZ()) > 0.35 then dOffs = 0.75 * dOffs end BL.UpdateTCING( nRawId, dOffs) end end return true end --------------------------------------------------------------------- return ProcessDoubleCut