-- ProcessCut.lua by Egaltech s.r.l. 2021/03/31 -- Gestione calcolo singoli tagli di lama per Travi -- Tabella per definizione modulo local ProcessCut = {} -- Include require( 'EgtBase') local BL = require( 'BeamLib') local DC = require( 'DiceCut') local LongCut = require( 'ProcessLongCut') EgtOutLog( ' ProcessCut started', 1) -- Dati local BD = require( 'BeamData') local ML = require( 'MachiningLib') --------------------------------------------------------------------- -- Riconoscimento della feature function ProcessCut.Identify( Proc) return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10) end --------------------------------------------------------------------- -- Classificazione della feature function ProcessCut.Classify( Proc, b3Raw) -- se PF con testa da sotto, ammessa qualunque orientazione if BD.C_SIMM and BD.DOWN_HEAD then return true end -- recupero i dati del taglio local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) if vtN:getZ() <= - 0.5 and abs( vtN:getY()) > 0.1 then local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, 0) if DimH > BD.MAX_DIM_DICE then return true, true end end -- verifico se c'è un taglio da sotto e se è nei limiti local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw) local bDownCut = ( vtN:getZ() <= dNzLimDwnUp) if bDownCut then local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, 0) -- confronto anche qua la distanza maggiore della faccia con la massima distanza del DiceCut -- e se il rapporto supera il 2 (implica che genera 3 tagli) dichiaro impossibile la lavorazione if DimH and BD.MAX_DIM_DICE and abs( BD.MAX_DIM_DICE) > 20 * GEO.EPS_SMALL and abs( DimH / BD.MAX_DIM_DICE) > 2 then return true, true end end return true, false end --------------------------------------------------------------------- -- Piano di taglio della feature function ProcessCut.GetCutPlane( Proc) if ProcessCut.Identify( Proc) then return EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) else return nil, nil end end --------------------------------------------------------------------- -- verifica curva per smusso (-1=errore curva, 0=estrusione non va bene, 1=ok) local function VerifyCurveForChamfer( AuxId) if not AuxId then return -2 end if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then return -1 end local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) -- va bene solo se direzione estrusione orizzontale if abs( vtExtr:getZ()) > 0.1 then return 0 end return 1 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 le entità curva associate (max 2) local sVal = EgtGetInfo( Proc.Id, 'AUXID') local vsAuxId = EgtSplitString( sVal) local AuxId, Aux2Id if vsAuxId and #vsAuxId >=1 then AuxId = tonumber( vsAuxId[1]) end if vsAuxId and #vsAuxId >=2 then Aux2Id = tonumber( vsAuxId[2]) end if AuxId then AuxId = AuxId + Proc.Id end if Aux2Id then Aux2Id = Aux2Id + Proc.Id end local nRes = VerifyCurveForChamfer( AuxId) if nRes == 0 and Aux2Id then AuxId = Aux2Id nRes = VerifyCurveForChamfer( AuxId) end if nRes == -2 then return true end if nRes == -1 then local sErr = 'Error : missing profile geometry' EgtOutLog( sErr) return false, sErr end if nRes == 0 then local sWarn = 'Warning : skipped not horizontal chamfer' EgtOutLog( sWarn) return true 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 feature larga come la trave if dWidth < b3Raw:getDimY() - 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 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, sMilling) 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 EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchId, 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, sMilling) 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 EgtApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchId, false) return false, sErr end return true, nil end --------------------------------------------------------------------- -- Aggiornamento ingombro local function UpdateEncumbrance( Proc, vtN, dOvmHead, nRawId, b3Solid, b3Raw) -- eventuale segnalazione ingombro di testa o coda (se non chiamata da altre feature) local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) if ProcessCut.Identify( Proc) and Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then if Proc.Head then local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() if vtN:getZ() > 0.5 then dOffs = dOffs - 0.6 * Proc.Box:getDimX() elseif vtN:getZ() < -0.5 then dOffs = dOffs - 0.2 * Proc.Box:getDimX() elseif ( abs( vtN:getY()) > 0.9 and vtN:getZ() > 0.2) then dOffs = dOffs - 0.3 * Proc.Box:getDimX() end BL.UpdateHCING( nRawId, dOffs) elseif Proc.Tail then local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() if vtN:getZ() > 0.5 then dOffs = dOffs - 0.6 * Proc.Box:getDimX() elseif vtN:getZ() < -0.5 then dOffs = dOffs - 0.2 * Proc.Box:getDimX() elseif ( abs( vtN:getY()) > 0.9 and vtN:getZ() > 0.2) then dOffs = dOffs - 0.3 * Proc.Box:getDimX() end BL.UpdateTCING( nRawId, dOffs) end end end --------------------------------------------------------------------- -- Applicazione della lavorazione con testa da sopra local function MakeFromTop( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut) -- 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 geometrici del taglio local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) -- limiti di taglio (se molto di lato e inclinati sono permessi fino a -45deg) local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw) if not BD.C_SIMM and abs( vtN:getX()) < 0.5 then dNzLimDwnUp = -0.707 end local bDownCut = ( vtN:getZ() <= dNzLimDwnUp) if bFromBottom == nil then bFromBottom = ( b3Solid:getDimX() < BD.LEN_SHORT_PART and vtN:getX() < 0 and vtN:getZ() > 0.25) end -- verifico se da considerare taglio lungo ( non da sotto, inclinato meno di 21.56deg, largo come la trave e abbastanza lungo) local bLongCut = ( not bDownCut and vtN:getZ() > 0.93 and Proc.Box:getDimY() > b3Solid:getDimY() - 10 * GEO.EPS_SMALL and ( Proc.Box:getDimX() > 0.75 * b3Solid:getDimX() or Proc.Box:getDimX() > 1500.000)) -- se taglio lungo e Q04 = 1 allora lancio il processo dell'L10 if bLongCut and EgtGetInfo( Proc.Id, 'Q04', 'i') == 1 then return LongCut.Make( Proc, nPhase, nRawId, nPartId, true) end -- se pezzo ancora attaccato alla trave, per non rovinare quello successivo local bFillAreaPiece local bFillTail if not BL.IsSplittedPartPhase( nPhase) then -- se non da sotto if not bDownCut then bFillAreaPiece = bCustDiceCut -- se true il controllo è già stato fatto dal modulo che ha chiamato il ProcessCut if not bFillAreaPiece then -- se poco inclinata ( inclinazione inferiore a 21.56 deg) if vtN:getZ() > 0.93 then -- si possono far partire i tagli a cubetti dalla testa bFillAreaPiece = bLongCut -- se praticamente verticale di fianco ( inclinazione inferiore a 21.56deg) elseif abs( vtN:getY()) > 0.93 then -- se la faccia occupa tutta la trave in X e Z o occupa sicuramente la faccia in Z e almeno 3/4 della faccia in X e sborda in X, if ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) or ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) and Proc.Box:getDimX() > 0.75 * b3Solid:getDimX())) and abs( Proc.Box:getMin():getZ() - b3Solid:getMin():getZ()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getZ() - b3Solid:getMax():getZ()) < 10*GEO.EPS_SMALL then local sErr = 'Error : Impossible to machine by orientation (on side)' EgtOutLog( sErr) return false, sErr end end end -- se quasi orizzontale ( inclinazione inferiore a 30) if vtN:getZ() > 0.866 then -- se la faccia termina davanti o dietro la trave e arriva in coda e non interessa la faccia inferiore, forzo il taglio a cubetti a partire dal davanti if ( abs( Proc.Box:getMin():getY() - b3Solid:getMin():getY()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getY() - b3Solid:getMax():getY()) < 10*GEO.EPS_SMALL) and abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL and b3Solid:getMin():getZ() < Proc.Box:getMin():getZ() - 100 * GEO.EPS_SMALL then bFillTail = true end -- se verticale quasi completamente di fianco ( inclinazione inferiore a 30) elseif abs( vtN:getY()) > 0.866 then -- se la faccia termina davanti o dietro la trave e arriva in coda e non interessa la faccia inferiore, forzo il taglio a cubetti a partire dal davanti if ( abs( Proc.Box:getMin():getZ() - b3Solid:getMin():getZ()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getZ() - b3Solid:getMax():getZ()) < 10*GEO.EPS_SMALL) and abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL then local sErr = 'Error : Impossible to machine by orientation (on side)' EgtOutLog( sErr) return false, sErr end end end end -- se vero taglio, eventuale inserimento smussi if Proc.Prc == 10 then local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) if not bOkc then return bOkc, sErrC end end -- recupero i dati dell'utensile local dSawDiam = 400 local dSawThick = 2 local dMaxDepth = 0 if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam dSawThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth end end local dMaxVertDepth = dMaxDepth - ( BD.DECR_VERT_CUT or 0) -- determino la direzione di taglio preferenziale local _, dCutH, dCutV = BL.GetFaceHvRefDim( Proc.Id, 0) local bHorizCut = ( dCutV < dMaxVertDepth - BD.CUT_EXTRA and not bDownCut) -- verifico se necessari tagli supplementari EgtOutLog( string.format( 'MaxDepth=%.1f MaxVertDepth=%.1f CutH=%.1f CutV=%.1f', dMaxDepth, dMaxVertDepth, dCutH, dCutV), 3) local vCuts = {} if dCutH > dMaxDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC or dCutV > dMaxVertDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC then local ptExtra, vtExtra local bAutoCalcSurf = true if bFillAreaPiece or bFillTail then local ptMiddle = ( b3Solid:getMin() + b3Solid:getMax()) / 2 ptExtra = Point3d( b3Solid:getMin():getX() + 5*GEO.EPS_SMALL, ptMiddle:getY(), ptMiddle:getZ()) vtExtra = X_AX() bAutoCalcSurf = false end vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxVertDepth - BD.CUT_EXTRA) -- se taglio sborda in coda e non è stato inserito nessun taglio a cubetti, lo rilancio con le dimensioni customizzate if ( bFillTail or bCustDiceCut) and #vCuts == 0 then vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxVertDepth - BD.CUT_EXTRA, Proc.Box:getDimY()) end end -- se il ProcessCut viene lanciato dal ProcessSawCut e non ci sono tagli a cubetti, esco if bCustDiceCut and #vCuts == 0 then return false, -1 end --DC.PrintOrderCut( vCuts) if #vCuts > 0 then -- 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 -- sistemo posizione nel DB e nome local bOrthInv = false 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) if ( i % 2) == 1 then local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) if ( vtN:getY() > 0.707 and vtO:getY() < -0.05) or ( vtN:getY() < -0.707 and vtO:getY() > 0.05) then EgtInvertSurf( vCuts[i][j]) bOrthInv = true end end end end -- eseguo for i = 1, #vCuts do -- determino il modo di tagliare local vtOrthoO local bNoPerpCuts = false if i % 2 == 1 then vtOrthoO = Vector3d( vtN) else local vtO if #vCuts[i-1] > 0 then vtO = EgtSurfTmFacetNormVersor( vCuts[i-1][1], 0, GDB_ID.ROOT) elseif vCuts[i+1] and #vCuts[i+1] > 0 then -- lunghezza faccia nell'eventuale direzione ortogonale local asseX = EgtSurfTmFacetNormVersor( vCuts[i+1][1], 0, GDB_ID.ROOT) local asseY = asseX ^ vtN local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) local b3Fac = EgtGetBBoxRef( vCuts[i][1], GDB_BB.STANDARD, Frame) -- se lunghezza inferiore al limite, accetto la direzione if b3Fac:getDimX() < dMaxDepth - BD.CUT_EXTRA then vtO = asseX else bNoPerpCuts = true end else bNoPerpCuts = true end if vtO then vtOrthoO = Vector3d( vtO) * EgtIf( bOrthInv, -1, 1) else if bHorizCut then vtOrthoO = Z_AX() elseif vtN:getY() > -0.02 then if not Proc.Head then vtOrthoO = -Y_AX() else vtOrthoO = Y_AX() end else vtOrthoO = -Y_AX() end end end -- lavoro la faccia for j = 1, #vCuts[i] do -- se taglio dal basso if bDownCut then -- se strato pari composto da 1 o 2 elementi if ( i % 2) == 0 and #vCuts[i] <= 2 then -- il primo elemento prende la direzione prevista, il secondo quella opposta local vtNewOrthoO = Vector3d( vtOrthoO) local dVzLimDwnUp = dNzLimDwnUp if j ~= 1 then vtNewOrthoO = -vtOrthoO if not BD.C_SIMM then dVzLimDwnUp = -0.707 end end local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtNewOrthoO, dVzLimDwnUp, BD.CUT_EXTRA_MIN, BD.CUT_SIC, 0, 0, nil, b3Raw) if not bOk then return bOk, sErr end end -- tutti gli altri casi vengono saltati -- caso generale else -- in generale sta sollevato di pochissimo local dExtraCut = -0.1 -- se tagli paralleli if ( i % 2) == 0 then -- se non ci sono tagli ortogonali devo affondare if bNoPerpCuts then dExtraCut = BD.CUT_EXTRA -- se altrimenti tagli ortogonali invertiti, devo approfondire dello spessore lama elseif bOrthInv then dExtraCut = dSawThick -- se ultimo taglio, devo affondare elseif j == #vCuts[i] then dExtraCut = BD.CUT_EXTRA end end local dVzLimDwnUp = dNzLimDwnUp if not BD.C_SIMM and vtN:getZ() > 0.707 then dVzLimDwnUp = -0.708 end local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, dVzLimDwnUp, dExtraCut, BD.CUT_SIC, 0, 0, nil, b3Raw) if not bOk then return bOk, sErr end end end end -- altrimenti tagli diretti della faccia else -- lavoro la faccia local vtOrthoO if bFromBottom and dCutV < dMaxVertDepth - BD.CUT_EXTRA and vtN:getZ() > 0 then vtOrthoO = -Z_AX() elseif bHorizCut and ( b3Solid:getDimX() > BD.LEN_SHORT_PART or vtN:getX() > 0) then vtOrthoO = Z_AX() elseif b3Solid:getDimX() < BD.LEN_SHORT_PART and abs( vtN:getY()) > 0.259 and vtN:getZ() > -0.174 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then if Proc.Head then vtOrthoO = X_AX() else vtOrthoO = -X_AX() end elseif vtN:getZ() < dNzLimDwnUp and abs( vtN:getY()) > 0.259 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then if Proc.Head then vtOrthoO = X_AX() else vtOrthoO = -X_AX() end elseif vtN:getY() > -0.02 then if Proc.Head then vtOrthoO = -Y_AX() else vtOrthoO = Y_AX() end else if Proc.Head then vtOrthoO = Y_AX() else vtOrthoO = -Y_AX() end end -- taglio local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, vtOrthoO, dNzLimDwnUp, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) if not bOk then return bOk, sErr end end -- Aggiornamento ingombro UpdateEncumbrance( Proc, vtN, dOvmHead, nRawId, b3Solid, b3Raw) return true end --------------------------------------------------------------------- -- Applicazione della lavorazione con testa da sotto local function MakeFromDown( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead) -- 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 geometrici del taglio local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) -- se vero taglio, eventuale inserimento smussi if Proc.Prc == 10 then local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) if not bOkc then return bOkc, sErrC end end -- recupero i dati dell'utensile local dSawDiam = 400 local dSawThick = 2 local dMaxDepth = 0 if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam dSawThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth end end local dMaxVertDepth = dMaxDepth -- determino la direzione di taglio preferenziale local _, dCutH, dCutV = BL.GetFaceHvRefDim( Proc.Id, 0) local bHorizCut = ( dCutV < dMaxVertDepth - BD.CUT_EXTRA) -- verifico se necessari tagli supplementari EgtOutLog( string.format( 'MaxDepth=%.1f MaxVertDepth=%.1f CutH=%.1f CutV=%.1f', dMaxDepth, dMaxVertDepth, dCutH, dCutV), 3) local vCuts = {} if dCutH > dMaxDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC or dCutV > dMaxVertDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC then local ptExtra, vtExtra local bAutoCalcSurf = true if bFillAreaPiece or bFillTail then local ptMiddle = ( b3Solid:getMin() + b3Solid:getMax()) / 2 ptExtra = Point3d( b3Solid:getMin():getX() + 5*GEO.EPS_SMALL, ptMiddle:getY(), ptMiddle:getZ()) vtExtra = X_AX() bAutoCalcSurf = false end vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxVertDepth - BD.CUT_EXTRA) end --DC.PrintOrderCut( vCuts) if #vCuts > 0 then -- 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 -- sistemo posizione nel DB e nome local bOrthInv = false 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) if ( i % 2) == 1 then local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) if ( vtN:getY() > 0.707 and vtO:getY() < -0.05) or ( vtN:getY() < -0.707 and vtO:getY() > 0.05) then EgtInvertSurf( vCuts[i][j]) bOrthInv = true end end end end -- eseguo for i = 1, #vCuts do -- determino il modo di tagliare local vtOrthoO local bNoPerpCuts = false if i % 2 == 1 then vtOrthoO = Vector3d( vtN) else local vtO if #vCuts[i-1] > 0 then vtO = EgtSurfTmFacetNormVersor( vCuts[i-1][1], 0, GDB_ID.ROOT) elseif vCuts[i+1] and #vCuts[i+1] > 0 then -- lunghezza faccia nell'eventuale direzione ortogonale local asseX = EgtSurfTmFacetNormVersor( vCuts[i+1][1], 0, GDB_ID.ROOT) local asseY = asseX ^ vtN local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) local b3Fac = EgtGetBBoxRef( vCuts[i][1], GDB_BB.STANDARD, Frame) -- se lunghezza inferiore al limite, accetto la direzione if b3Fac:getDimX() < dMaxDepth - BD.CUT_EXTRA then vtO = asseX else bNoPerpCuts = true end else bNoPerpCuts = true end if vtO then vtOrthoO = Vector3d( vtO) * EgtIf( bOrthInv, -1, 1) else if bHorizCut then vtOrthoO = Z_AX() elseif vtN:getY() > -0.02 then if not Proc.Head then vtOrthoO = -Y_AX() else vtOrthoO = Y_AX() end else vtOrthoO = -Y_AX() end end end -- lavoro la faccia for j = 1, #vCuts[i] do -- in generale sta sollevato di pochissimo local dExtraCut = -0.1 -- se tagli paralleli if ( i % 2) == 0 then -- se non ci sono tagli ortogonali devo affondare if bNoPerpCuts then dExtraCut = BD.CUT_EXTRA -- se altrimenti tagli ortogonali invertiti, devo approfondire dello spessore lama elseif bOrthInv then dExtraCut = dSawThick -- se ultimo taglio, devo affondare elseif j == #vCuts[i] then dExtraCut = BD.CUT_EXTRA end end -- taglio (limite Vz Down Up messo a -2 per non farlo mai intervenire) local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, -2, dExtraCut, BD.CUT_SIC, 0, 0, nil, b3Raw) if not bOk then return bOk, sErr end end end -- altrimenti tagli diretti della faccia else -- lavoro la faccia local vtOrthoO if bHorizCut and ( b3Solid:getDimX() > BD.LEN_SHORT_PART or vtN:getX() > 0) then vtOrthoO = Z_AX() elseif b3Solid:getDimX() < BD.LEN_SHORT_PART and abs( vtN:getY()) > 0.259 and vtN:getZ() > -0.174 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then if Proc.Head then vtOrthoO = X_AX() else vtOrthoO = -X_AX() end elseif abs( vtN:getY()) > 0.259 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then if Proc.Head then vtOrthoO = X_AX() else vtOrthoO = -X_AX() end elseif vtN:getY() > -0.02 then if Proc.Head then vtOrthoO = -Y_AX() else vtOrthoO = Y_AX() end else if Proc.Head then vtOrthoO = Y_AX() else vtOrthoO = -Y_AX() end end -- taglio (limite Vz Down Up messo a -2 per non farlo mai intervenire) local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, vtOrthoO, -2, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) if not bOk then return bOk, sErr end end -- Aggiornamento ingombro UpdateEncumbrance( Proc, vtN, dOvmHead, nRawId, b3Solid, b3Raw) return true end --------------------------------------------------------------------- -- Applicazione della lavorazione function ProcessCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut) -- ingombro del grezzo local b3Raw = EgtGetRawPartBBox( nRawId) -- dati geometrici del taglio local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) -- se taglio di testa if Proc.Head then -- se coincide con il taglio di separazione precedente, non va fatto if AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then return true end -- altrimenti taglio di coda else -- se coincide con taglio di separazione, non va fatto if AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then return true end end -- se coincide con un taglio frontale non va fatto if Proc.CutFront then return true end -- abilitazione lavorazione da sotto (testa da sotto e direzione normale sotto -20deg e sbandamento oltre 10deg) local bTopHead = ( BD.DOWN_HEAD and vtN:getZ() > -0.342) local bDownHead = ( BD.DOWN_HEAD and vtN:getZ() < -0.342 and ( abs( vtN:getY()) > 0.174 or b3Raw:getDimY() > 2 * BD.MAX_DIM_HTCUT)) -- recupero la lavorazione local sCutType = EgtIf( Proc.Head, 'HeadSide', 'TailSide') local sCutting = ML.FindCutting( sCutType .. EgtIf( bDownHead, '_H2', '')) if not sCutting and bTopHead then sCutting = ML.FindCutting( sCutType) bDownHead = false end if not sCutting then local sErr = 'Error : cutting not found in library' EgtOutLog( sErr) return false, sErr end -- se taglio con testa da sopra if not bDownHead then return MakeFromTop( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut) else return MakeFromDown( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut) end end --------------------------------------------------------------------- return ProcessCut