diff --git a/LuaLibs/ProcessLapJoint.lua b/LuaLibs/ProcessLapJoint.lua index 17fbf70..fce8ff7 100644 --- a/LuaLibs/ProcessLapJoint.lua +++ b/LuaLibs/ProcessLapJoint.lua @@ -1,4 +1,4 @@ --- ProcessLapJoint.lua by Egaltech s.r.l. 2022/12/12 +-- ProcessLapJoint.lua by Egaltech s.r.l. 2022/12/21 -- Gestione calcolo mezzo-legno per Travi -- 2019/10/08 Agg. gestione OpenPocket. -- 2021/01/24 Con sega a catena ora sempre impostato asse A. @@ -57,6 +57,7 @@ -- 2022/09/27 Aggiunta gestione SCC per svuotature con TURN (solo dopo applicazione lavorazione). -- 2022/10/20 In MakeByChainOrSaw modificato check per trovare la faccia adiacente sul lato più lungo. -- 2022/12/12 Default 1000 per BD.MIN_LEN_LAMELLO. In MachineByMill migliorata ricerca utensile e gestione inversione in funzione del lato di lavoro. +-- 2022/12/21 Sistemata gestione SideMillAsSaw. -- Tabella per definizione modulo local ProcessLapJoint = {} @@ -278,7 +279,7 @@ end local function VerifyChainSaw( Proc, dMinDim, dMaxDim) local bUseChainSaw = false local sMchFind = 'Sawing' - local sSawing = ML.FindSawing(sMchFind) + local sSawing = ML.FindSawing( sMchFind) local dMaxMat = 0 local dSawCornerRad = 0 local dSawThick = 0 @@ -456,6 +457,77 @@ local function VerifyBHSideMill( Proc, bIsU, bIsL, bSinglePart, bPrevBhSideMill) return bUseBHSideMill, bHead, bHeadDir, sMilling, dToolThick, dToolDiam end +--------------------------------------------------------------------- +local function VerifySideMillAsSaw( Proc, nAddGrpId, vtN, dDiam, dFacElev) + -- Verifico sia feature L016, L030, L032, L039 + if not ( Proc.Prc == 16 or Proc.Prc == 30 or Proc.Prc == 32 or Proc.Prc == 39) then + return false + end + -- Verifico sia gola lungo X con 3 facce più eventuali terminali + local nTestId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + local bNewIsU + local nFaces = EgtSurfTmFacetCount( nTestId) + while nFaces >= 3 do + local bDeleteFace + local nInt = 0 + while not bDeleteFace and nInt < nFaces do + nInt = nInt + 1 + local b3Facet = EgtSurfTmGetFacetBBoxGlob( nTestId, nInt-1, GDB_BB.STANDARD) + local vtN = EgtSurfTmFacetNormVersor( nTestId, nInt-1, GDB_ID.ROOT) + -- se dimensione faccia sulla X + if b3Facet:getDimX() < 1 or abs( vtN:getX()) > 0.1 then + EgtSurfTmRemoveFacet( nTestId, nInt-1) + bDeleteFace = true + end + end + nFaces = EgtSurfTmFacetCount( nTestId) + -- se non ho cancellato una faccia faccio il test per forma ad U + if not bDeleteFace then + -- ottengo il numero di facce rimanenti + bNewIsU = ( nFaces == 3 and not TestElleShape3( nTestId, true)) + -- verifico che gola allineata su X + if bNewIsU then + local vtN1 = EgtSurfTmFacetNormVersor( nTestId, 0, GDB_ID.ROOT) + bNewIsU = ( abs( vtN1:getX()) < 0.01) + end + -- esco dal ciclo + break + end + end + -- cancello la copia del percorso + EgtErase( nTestId) + -- eseguo test + if not bNewIsU then + return false + end + -- Verifico sia abbastanza lunga + if not (( Proc.TotBox and Proc.TotBox:getDimX() > ( BD.MIN_LEN_LAMELLO or 1000)) or + ( not Proc.TotBox and Proc.Box:getDimX() > ( BD.MIN_LEN_LAMELLO or 1000))) then + return false + end + -- Recupero la lavorazione + local bDownHead = ( BD.DOWN_HEAD and vtN:getZ() < BD.NZ_MINA) + local sMillingOnSide = ML.FindMilling( 'SideMillAsBlade', nil, nil, nil, nil, not bDownHead, bDownHead) + if not sMillingOnSide then + return false + end + -- Recupero i dati dell'utensile + local dToolDiamOnSide = 0 + local dThickMillOnSide = 0 + local dMaxDepthOnSide = 0 + if EgtMdbSetCurrMachining( sMillingOnSide) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiamOnSide = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiamOnSide + dThickMillOnSide = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dThickMillOnSide + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or dMaxDepthOnSide + end + end + local bSpecialMillOnSide = ( dDiam > dThickMillOnSide - 10 * GEO.EPS_SMALL and dFacElev < dMaxDepthOnSide + 10 * GEO.EPS_SMALL) + -- Restituisco i dati + return bSpecialMillOnSide, sMillingOnSide, dThickMillOnSide, dToolDiamOnSide, dMaxDepthOnSide +end + --------------------------------------------------------------------- local function GetFaceAdj( Proc, nFacInd, dH, dV) @@ -2417,29 +2489,19 @@ end --------------------------------------------------------------------- local function MakeByMillAsSaw( Proc, nPhase, nRawId, nPartId, nFacInd, - rfFac, dH, dV, dElev, bForceUseBlade, + rfFac, dH, dV, dElev, nBottomFace, nAddGrpId, b3Solid, dSawMaxDepth, sMillingOnSide, - dSawDiam, dSawThick) - local bOrthoFaces + dSawDiam, dSawThick, bIgnoreCaps) local sWarn -- ingombro del grezzo local b3Raw = EgtGetRawPartBBox( nRawId) -- ottengo la distanza tra la fine del pezzo e il pezzo successivo local dDistToNextPiece = EgtGetInfo( nRawId, 'BDST', 'd') or 5. - -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa - local nFacInd1, dFacElev1, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, true) - if not nFacInd1 or nFacInd1 < 0 then - if nFacInd1 == -1 then - bOrthoFaces = nFacInd2 - else - local sErr = 'Error : MakeByMillAsSaw could not find reference face' - EgtOutLog( sErr) - return false, sErr - end - end - if bOrthoFaces then - -- ottengo le dimensioni del tunnel - local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = BL.GetTunnelDimension( Proc, nPartId) + -- verifico definizione faccia con il maggior numero di adiacenze + if not nFacInd then + local sErr = 'Error : MakeByMillAsSaw could not find reference face' + EgtOutLog( sErr) + return false, sErr end -- Recupero le facce adiacenti alla principale local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] @@ -2456,10 +2518,15 @@ local function MakeByMillAsSaw( Proc, nPhase, nRawId, nPartId, nFacInd, if vAdj[i] >= 0 then local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) local dLen = dist( ptP1, ptP2) - if dLen > dMaxLen then + if abs( dLen - dMaxLen) < 5 then + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT) + if vtN:getY() > 0.5 or vtN:getZ() > 0.5 then + nFacAdj = vAdj[i] + dMaxLen = dLen + end + elseif dLen > dMaxLen then nFacAdj = vAdj[i] dMaxLen = dLen - EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3) end end end @@ -2469,16 +2536,16 @@ local function MakeByMillAsSaw( Proc, nPhase, nRawId, nPartId, nFacInd, return false, sErr end -- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare - local _, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacAdj, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT) if abs( vtN * rfFac:getVersX()) > abs( vtN * rfFac:getVersY()) then dH, dV = dV, dH end -- Determino se estremi aperti o chiusi - local bOpenStart = false - local bOpenEnd = false + local bOpenStart = bIgnoreCaps + local bOpenEnd = bIgnoreCaps local vtNS, vtNE - -- se non ho la faccia di fondo ( che comporta essere una fessura) verifico se ho lati aperti - if not nBottomFace then + -- se non ho la faccia di fondo ( che comporta essere una fessura) e non da ignorare verifico se ho lati aperti + if not nBottomFace and not bIgnoreCaps then local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) for j = 1, #vAdj2 do @@ -2491,7 +2558,7 @@ local function MakeByMillAsSaw( Proc, nPhase, nRawId, nPartId, nFacInd, bOpenStart = ( vAdj2[i] < 0) -- se è chiusa acquisisco vettore faccia tappo if not bOpenStart and vAdj2[i] >= 0 then - _, vtNS = EgtSurfTmFacetCenter( Proc.Id, vAdj2[i], GDB_ID.ROOT) + vtNS = EgtSurfTmFacetNormVersor( Proc.Id, vAdj2[i], GDB_ID.ROOT) end -- Se non esiste faccia adiacente a lato successivo -> fine aperto local k = EgtIf( j < #vAdj2, j + 1, 1) @@ -2501,66 +2568,65 @@ local function MakeByMillAsSaw( Proc, nPhase, nRawId, nPartId, nFacInd, bOpenEnd = ( vAdj2[k] < 0) -- se è chiusa acquisisco vettore faccia tappo if not bOpenEnd and vAdj2[k] >= 0 then - _, vtNE = EgtSurfTmFacetCenter( Proc.Id, vAdj2[k], GDB_ID.ROOT) + vtNE = EgtSurfTmFacetNormVersor( Proc.Id, vAdj2[k], GDB_ID.ROOT) end end end end - -- Se possibile, lavoro con la lama - if bForceUseBlade then - -- Recupero la lavorazione di lama - local sCutting = sMillingOnSide - -- Calcolo uso faccia - local nFaceUse = BL.GetNearestOrthoOpposite( rfFac:getVersZ()) - local dStartDist = -1 - local dEndDist = -1 - -- calcolo eventuali arretramenti lama + -- Recupero la lavorazione di lama + local sCutting = sMillingOnSide + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite( rfFac:getVersZ()) + local dStartDist = -1 + local dEndDist = -1 + -- calcolo eventuali arretramenti lama + if not bOpenStart then + local dRadius = dSawDiam / 2 + local dCat1 = dRadius - dElev + dStartDist = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1)) + end + if not bOpenEnd then if not bOpenStart then + dEndDist = dStartDist + else local dRadius = dSawDiam / 2 local dCat1 = dRadius - dElev - dStartDist = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1)) - end - if not bOpenEnd then - if not bOpenStart then - dEndDist = dStartDist - else - local dRadius = dSawDiam / 2 - local dCat1 = dRadius - dElev - dEndDist = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1)) - end - end - -- Eseguo i tagli - local nStep = ceil( ( dV - 100 * GEO.EPS_SMALL) / dSawThick) - local dStep = 0 - if nStep > 1 then - dStep = ( dV - dSawThick) / ( nStep - 1) - end - for i = 1, nStep do - local dOffs = ( i - 1) * dStep - --if vtN:getZ() < BD.NZ_MINA then dOffs = dOffs + dSawThick end - local bOk, sErr, nMchId = Fbs.MakeOne( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, dStartDist, dEndDist, nil, b3Raw) - if not bOk then return bOk, sErr end - -- setto l'elevazione - local sNotes = 'MaxElev=' .. EgtNumToString( 0, 1) .. ';' - -- applico elevazione - EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) - -- tolgo eventuale step - EgtSetMachiningParam( MCH_MP.STEP, 0) - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchId, false) - return false, sErr - end - end - -- in base all'elevazione calcolo l'impronta della lama - local dUsedBladeLen = sqrt( ((dSawDiam / 2)*(dSawDiam / 2)) - ( ( (dSawDiam / 2) - dElev) * ( (dSawDiam / 2) - dElev))) - -- controllo direzione taglio e se il minimo della feature sborda in coda - if abs( vtN:getX()) < GEO.EPS_SMALL and abs( b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then - -- do avviso che la lama può sbordare nel pezzo successivo - sWarn = 'Warning on mill side as blade : Cut machining can damage next piece' - EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + dEndDist = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1)) end end + -- Eseguo i tagli + local nStep = ceil( ( dV - 100 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dV - dSawThick) / ( nStep - 1) + end + local dVzLimDwnUp = -0.01 + for i = 1, nStep do + local dOffs = ( i - 1) * dStep + if vtN:getZ() < dVzLimDwnUp then dOffs = dOffs + dSawThick end + local bOk, sErr, nMchId = Fbs.MakeOne( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, dVzLimDwnUp, 0, BD.CUT_SIC, dOffs, dStartDist, dEndDist, nil, b3Raw) + if not bOk then return bOk, sErr end + -- setto l'elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( 0, 1) .. ';' + -- applico elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- tolgo eventuale step + EgtSetMachiningParam( MCH_MP.STEP, 0) + if not ML.ApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + -- in base all'elevazione calcolo l'impronta della lama + local dUsedBladeLen = sqrt( ((dSawDiam / 2)*(dSawDiam / 2)) - ( ( (dSawDiam / 2) - dElev) * ( (dSawDiam / 2) - dElev))) + -- controllo direzione taglio e se il minimo della feature sborda in coda + if abs( vtN:getX()) < GEO.EPS_SMALL and abs( b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then + -- do avviso che la lama può sbordare nel pezzo successivo + sWarn = 'Warning on mill side as blade : Cut machining can damage next piece' + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + return true, sWarn end @@ -4896,101 +4962,19 @@ local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, bSinglePa _, sMyPocketing, dMyTMaxDepth, dMyTDiam = VerifyPocket( Proc, dDiam, dFacElev + dCollSic, dMaxTotLen, sMchFind) bMillDown = false end - --local sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind .. EgtIf( bMillDown, '_H2', ''), dDiam, dFacElev + dCollSic, dMaxTotLen) - --if not sMyPocketing then - -- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind .. EgtIf( bMillDown, '_H2', ''), dDiam, nil, dMaxTotLen) - --end - --if not sMyPocketing and bMillUp then - -- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam, dFacElev + dCollSic) - -- if not sMyPocketing then - -- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam) - -- end - -- bMillDown = false - --end if sMyPocketing and - ( dMyTMaxDepth > dFacElev + dCollSic - 10 * GEO.EPS_SMALL or ( dMyTMaxDepth > 0.8 * dFacElev + dCollSic and not bIsU) or ( bIsL and nUseRoughTool == 0) or + ( dMyTMaxDepth > dFacElev + dCollSic - 10 * GEO.EPS_SMALL or ( dMyTMaxDepth > 0.8 * dFacElev + dCollSic and not bIsU) or + ( bIsL and nUseRoughTool == 0) or ( Proc.Prc == 25 and not bIsU and not bIsL)) then sPocketing = sMyPocketing end if bMillDown then sMchFind = sMchFind ..'_H2' end - -- 2021.09.16 Richiesta di Fabio Squaratti per lavorazione "Lamello": - -- se ho attiva questo tipo di lavorazione (delle fresature) e una di queste feature: L016, L030, L032, L039 - -- verifico se sono compatibili con questa lavorazione forma a U e larga più dell'altezza tagliente e profondità compatibile con - local bSpecialMillOnSide - local dThickMillOnSide = 0 - local sMillingOnSide - local dToolDiamOnSide = 0 - local dMaxDepthOnSide = 0 - if ( Proc.Prc == 16 or Proc.Prc == 30 or Proc.Prc == 32 or Proc.Prc == 39) then - -- verifico se ho una gola con 3 facce ed eventualmente delle facce terminali: - -- faccio una copia della superfice ed elimino le facce che hanno dimensione X < 1 e le facce risultanti devono essere una U - local nTestId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL - if nTestId then - local bNewIsU - local bExit - local nFaces = EgtSurfTmFacetCount( nTestId) - while not bExit and nFaces >= 3 do - local bDeleteFace - local nInt = 0 - while not bDeleteFace and nInt < nFaces do - nInt = nInt + 1 - local b3Facet = EgtSurfTmGetFacetBBoxGlob( nTestId, nInt-1, GDB_BB.STANDARD) - local vtN = EgtSurfTmFacetNormVersor( nTestId, nInt-1, GDB_ID.ROOT) - -- se dimensione faccia sulla X - if b3Facet:getDimX() < 1 or abs( vtN:getX()) > 0.1 then - EgtSurfTmRemoveFacet( nTestId, nInt-1) - bDeleteFace = true - end - end - nFaces = EgtSurfTmFacetCount( nTestId) - -- se non ho cancellato una faccia faccio il test per forma ad U - if not bDeleteFace then - -- ottengo il numero di facce rimanenti - bNewIsU = ( nFaces == 3 and not TestElleShape3( nTestId, true)) - bExit = true - end - end - -- verifico che la componente x della faccia o deve essere nulla - local vtN1 = EgtSurfTmFacetNormVersor( nTestId, 0, GDB_ID.ROOT) - if bNewIsU and abs( vtN1:getX()) > 0.01 then - bNewIsU = false - end - -- cancello la copia del percorso - EgtErase( nTestId) - - if bNewIsU and - (( Proc.TotBox and Proc.TotBox:getDimX() > ( BD.MIN_LEN_LAMELLO or 1000)) or - ( not Proc.TotBox and Proc.Box:getDimX() > ( BD.MIN_LEN_LAMELLO or 1000))) then - -- recupero la lavorazione - local bDownHead = BD.DOWN_HEAD and vtN:getZ() < BD.NZ_MINA - sMillingOnSide = ML.FindMilling( 'SideMillAsBlade_H2', nil, nil, nil, nil, not bDownHead, bDownHead) - - if sMillingOnSide then - -- recupero i dati dell'utensile - local dToolLength = 0 - local sUserNote - if EgtMdbSetCurrMachining( sMillingOnSide) then - local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) - if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then - dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength - dToolDiamOnSide = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiamOnSide - dThickMillOnSide = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dThickMillOnSide - dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or dMaxDepthOnSide - end - end - -- 2021.09.17 Su conferma di Fabio Squaratti, se la gola è più streta dell'utensile o la profondità della gole è maggiore - -- del valore parametro SIDEDEPTH (preso dalle note utente dell'utensile) allora si prosegue come se non fosse abilitata - -- questo tipo di lavorazione SideMillAsBlade - if dDiam > dThickMillOnSide - 10 * GEO.EPS_SMALL and dFacElev < dMaxDepthOnSide + 10 * GEO.EPS_SMALL then - bSpecialMillOnSide = true - -- disabilito eventulae svuotatura - sPocketing = nil - end - end - end - end + -- Verifico se lavorazione "Lamello": + local bSpecialMillOnSide, sMillingOnSide, dThickMillOnSide, dToolDiamOnSide, dMaxDepthOnSide = VerifySideMillAsSaw( Proc, nAddGrpId, vtN, dDiam, dFacElev) + if bSpecialMillOnSide then + sPocketing = nil end -- se feature 16 e forzata lama e forma ad U, annulla la svuotatura if Proc.Prc == 16 and bForceUseBlade and Proc.Fct == 3 and bIsU then @@ -5004,7 +4988,7 @@ local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, bSinglePa local nQAntisplintResult = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') or 0 -- se lavorazione fresa come lama disabilito eventuale antischeggia if bSpecialMillOnSide then nQAntisplintResult = 0 end - -- se non trova una svuotatura adatta + -- se non trovata una svuotatura adatta if not sPocketing then -- se forma a L provo con contornatura if bIsL and not bSpecialMillOnSide and not bForceSideMill then @@ -5019,9 +5003,9 @@ local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, bSinglePa if bSpecialMillOnSide then -- eseguo bOk, sWarn = MakeByMillAsSaw( Proc, nPhase, nRawId, nPartId, nFacInd, - rfFac, dH, dV, dFacElev, bSpecialMillOnSide, + rfFac, dH, dV, dFacElev, nBottomFace, nAddGrpId, b3Solid, dMaxDepthOnSide, sMillingOnSide, - dToolDiamOnSide, dThickMillOnSide) + dToolDiamOnSide, dThickMillOnSide, bAllWithEndCap) if bOk then return true, sWarn end @@ -5471,8 +5455,8 @@ local function MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) -- verifico se applicare gestione speciale delle giunzioni (U diretta come asse X) local bAddEndCap = false local dAddLen = 0 - local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) - if bIsU then + local bIsOpenU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) + if bIsOpenU then local ptC0, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, 2, GDB_ID.ROOT) @@ -5500,7 +5484,6 @@ local function MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) for i = 1, nPart do -- eseguo divisione local AddId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL - EgtSetName( AddId, 'AddPart_' .. tostring( Proc.Id) .. '_' .. tostring( i)) if i > 1 or bAddEndCap then -- definizione del piano local dAdd = EgtIf( i > 1, dAddLen, 0) @@ -5539,6 +5522,7 @@ local function MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) local vtN = X_AX() EgtCutSurfTmPlane( AddId, ptOn, vtN, true, GDB_RT.GLOB) end + EgtSetName( AddId, 'AddPart_' .. tostring( Proc.Id) .. '_' .. tostring( i)) -- eseguo inserimento in modo da ordinare da X+ a X- table.insert( vAddId, 1, AddId) end diff --git a/LuaLibs/ProcessLapJointNew.lua b/LuaLibs/ProcessLapJointNew.lua deleted file mode 100644 index e19ba4b..0000000 --- a/LuaLibs/ProcessLapJointNew.lua +++ /dev/null @@ -1,5166 +0,0 @@ --- ProcessLapJoint.lua by Egaltech s.r.l. 2022/01/28 --- Gestione calcolo mezzo-legno per Travi --- 2019/10/08 Agg. gestione OpenPocket. --- 2021/01/24 Con sega a catena ora sempre impostato asse A. --- 2021/02/03 Corretto riconoscimento feature di coda. --- 2021/02/04 Razionalizzata gestione forzatura lama. Corretta gestione diametro minimo utensile per svuotatura. --- 2021/03/04 Due facce con testa da sotto. --- 2021/03/20 Piccole correzioni. --- 2021/03/22 Modificata gestione caso due facce lunghe come la trave con trave corta. --- 2021/04/13 Modificata gestione fessura U con sega a catena (corta ora ok, lunga ancora da correggere). --- 2021/04/14 Correzioni ribasso a U con fresa da sotto. --- 2021/04/15 Aggiunta gestione massima lunghezza fresa da sotto su svuotature. --- 2021/04/21 Anche feature lunga con due facce con opzione lama ora si taglia con lama. --- 2021/04/23 Corretto caso con antischeggia non inseriti perchè inutili. --- 2021/04/27 Antischeggia solo se feature trasversali. --- 2021/05/12 Semplificata gestione diametro minimo utensile per svuotatura. --- 2021/06/04 Su U passante con faccia perpendicolare aggiunta si forza Pocket. --- 2021/06/11 Su U passante e profonda se non bastano due svuotature su faccia ortogonale si fa anche la faccia di fondo per quanto possibile. --- 2021/06/21 Nel caso precedente si fa la terza svuotatura anche se è possibile fare una sola delle prime due (altra da sotto). --- 2021/06/21 Gestione ripresa spigoli o contorno con fresa più piccola ( diametro < 3/4 utensile svuotatura) attivata da parametro Q. --- 2021/07/02 Migliorie e correzioni su svuotature e pulitura spigoli. --- 2021/07/15 Aggiunti antischeggia con fresa. --- 2021/09/08 Aggiunta gestione parametro Q04 per i tagli di lama lungo facce lunghe (con o senza facce di chiusura) --- 2021/09/21 Aggiunta lavorazione/opzione "lamello" con le feature 16, 30, 32, 39, --- che si attiva abilitando il check al tipo milling: SideMillAsBlade (SideMillAsBlade_2) --- 2021/09/23 Gestione migliorata lavorazioni BH (blockhaus) su macchina fast BH, --- migliorata applicazione lavorazioni BH su feature lunghe lavorte a passi --- 2021/10/06 Ad antischeggia con lama in presenza di testa da sotto aggiunta preferenza a testa da sopra. --- 2021/10/19 Corretta gestione inversione per Tunnel. OpenPocket anche se spezzato ma 1 o 2 facce. Introdotta lunghezza minima per lamello. --- 2021/10/21 Migliorato controllo affondamento utensile in U lavorato da 3 parti (anche da sotto). --- 2021/10/27 Migliorato calcolo asse tunnel o similare. --- 2021/11/02 In svuotatura con lati aperti diametro fresa non superiore al doppio del lato piccolo. --- 2021/11/15 Quando si usa sega a catena uso Q10 come massima elevazione. --- 2021/11/22 Corretta segnalazione warning su foro di L20 e L25. --- 2021/12/17 Lettura parametri Q una volta sola all'inizio. --- 2022/01/13 Estrapolazione da MakeMoreFaces() di MakeTwoFaces() e MakeThreeFaces(), e varie ottimizzazioni. --- 2022/01/19 Cambiata % lunghezza pezzo per spezzatura. Tolta correzione spessore fresa a disco con superficie da lavorare verso Z-. --- 2022/01/26 Migliorato controllo uso testa da sotto nel caso due facce con lama. --- 2022/01/28 Aggiunte funzioni DoClean, DoPocketing, DoHeadChainSaw, DoSideChainSaw e DoHeadCut. - --- Tabella per definizione modulo -local ProcessLapJoint = {} - --- Include -require( 'EgtBase') -local BL = require( 'BeamLib') -local Fbs = require( 'FacesBySaw') -local Cut = require( 'ProcessCut') -local DoubleCut = require( 'ProcessDoubleCut') -local LongCut = require( 'ProcessLongCut') -local Long2Cut = require( 'ProcessLongDoubleCut') - -EgtOutLog( ' ProcessLapJoint started', 1) - --- Dati -local BD = require( 'BeamData') -local ML = require( 'MachiningLib') - --- variabili assegnazione parametri Q -local Q_FORCE_BLADE = nil -- i -local Q_DEPTH_CHAMFER = 0.0 -- d -local Q_MAX_ELEVATION = 0.0 -- d -local Q_ONLY_CHAMFER = 0 -- i -local Q_USE_MILL = 0 -- i -local Q_USE_ROUGH_TOOL = 0 -- i -local Q_USE_ROUGH_TOOL_B90 = 0 -- i -local Q_USE_ROUGH_TOOL_B0 = 0 -- i -local Q_BORE_ON_CORNER = 0 -- i -local Q_CONTOUR_SMALL_TOOL = 0 -- i -local Q_ONLY_CONTOUR = 0 -- i -local Q_SIDE_ROUGH_TOOL = 0 -- i -local Q_ANTISPLINT_TYPE = 0 -- i -local Q_BLADE_ON_ALONG_FACE = 0 -- i - --- variabile smussi -local _bMadeChamfer -local _nChamfer, _dDepthCham, _sErrCham, _bForceUseBlade - --- Settaggi interni -local _bTrySidePocketAtFirst = true -local _nPhase, _nRawId, _nPartId, _dOvmHead -local _b3Raw, _b3Solid -local _nAddGrpId - - ---------------------------------------------------------------------- --- Riconoscimento della feature -function ProcessLapJoint.Identify( Proc) - return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16) or - (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17) or - (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20) or - (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25) or - (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30) or - (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32) or - (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 33) or - (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34) or - ( Proc.Grp == 4 and Proc.Prc == 37) or - ( Proc.Grp == 4 and Proc.Prc == 39) or - ( Proc.Grp == 4 and Proc.Prc == 120)) -end - ---------------------------------------------------------------------- -local function AssignQValues( Proc) - -- reset assegnazione parametri Q - Q_FORCE_BLADE = nil - Q_BLADE_ON_ALONG_FACE = 0 - Q_DEPTH_CHAMFER = 0.0 - Q_ONLY_CHAMFER = 0 - Q_USE_MILL = 0 - Q_USE_ROUGH_TOOL = 0 - Q_USE_ROUGH_TOOL_B90 = 0 - Q_USE_ROUGH_TOOL_B0 = 0 - Q_BORE_ON_CORNER = 0 - Q_CONTOUR_SMALL_TOOL = 0 - Q_ONLY_CONTOUR = 0 - Q_SIDE_ROUGH_TOOL = 0 - Q_ANTISPLINT_TYPE = 0 - Q_MAX_ELEVATION = EgtGetInfo( Proc.Id, 'Q10', 'd') or 0.0 - - if ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16 then - Q_FORCE_BLADE = EgtGetInfo( Proc.Id, 'Q01', 'i') -- can be nil - Q_DEPTH_CHAMFER = EgtGetInfo( Proc.Id, 'Q04', 'd') or 0.0 - Q_ONLY_CHAMFER = EgtGetInfo( Proc.Id, 'Q05', 'i') or 0 - elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17 then - Q_DEPTH_CHAMFER = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0.0 - Q_ONLY_CHAMFER = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0 - elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20 then - Q_DEPTH_CHAMFER = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0.0 - Q_USE_MILL = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0 - Q_USE_ROUGH_TOOL = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0 - Q_USE_ROUGH_TOOL_B90 = EgtGetInfo( Proc.Id, 'Q04', 'i') or 0 - Q_USE_ROUGH_TOOL_B0 = EgtGetInfo( Proc.Id, 'Q05', 'i') or 0 - Q_BORE_ON_CORNER = EgtGetInfo( Proc.Id, 'Q06', 'i') or 0 - elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25 then - Q_BORE_ON_CORNER = EgtGetInfo( Proc.Id, 'Q01', 'i') or 0 - elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then - Q_CONTOUR_SMALL_TOOL = EgtGetInfo( Proc.Id, 'Q01', 'i') or 0 - Q_ONLY_CONTOUR = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0 - Q_SIDE_ROUGH_TOOL = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0 - Q_BLADE_ON_ALONG_FACE = EgtGetInfo( Proc.Id, 'Q04', 'i') or 0 - Q_ANTISPLINT_TYPE = EgtGetInfo( Proc.Id, 'Q06', 'i') or 0 - Q_DEPTH_CHAMFER = EgtGetInfo( Proc.Id, 'Q07', 'd') or 0.0 - elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32 then - Q_SIDE_ROUGH_TOOL = EgtGetInfo( Proc.Id, 'Q01', 'i') or 0 - Q_CONTOUR_SMALL_TOOL = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0 - Q_ANTISPLINT_TYPE = EgtGetInfo( Proc.Id, 'Q06', 'i') or 0 - elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34 then - Q_CONTOUR_SMALL_TOOL = EgtGetInfo( Proc.Id, 'Q01', 'i') or 0 - Q_ANTISPLINT_TYPE = EgtGetInfo( Proc.Id, 'Q06', 'i') or 0 - end -end - ---------------------------------------------------------------------- -local function EvaluateChamfer() - local sErr - -- verifico che lo smusso sia richiesto - local nChamfer = 0 - if Q_DEPTH_CHAMFER > 0 then - nChamfer = 1 - end - -- verifico se posso fare solo lo smusso - if Q_ONLY_CHAMFER == 1 then - if Q_DEPTH_CHAMFER > 0 then - nChamfer = nChamfer + 1 - -- altrimenti se non ho l'affondamento esco - else - sErr = 'Error : no chamfer depth' - EgtOutLog( sErr) - return -1, dDepth, sErr - end - end - -- verifico se devo usare lama invece della sega-catena - -- 2020-03-20 forzata abilitazione uso lama se parametro Q non è presente - -- xxxx-xx-xx tolta la preferenza alla lama in favore della sega-catena per un caso particolare - -- 2021-02-15 re-introdotta la preferenza alla lama se non c'è il parametro Q. Rimane da - -- implementare un ulteriore parametro per poter scegliere di prediligere la sega-catena o no al fine di continuare - -- a cambiare il codice per gestire il caso particolare - local bForceUseBlade = false - if Q_FORCE_BLADE == nil or Q_FORCE_BLADE == 1 then - bForceUseBlade = true - end - - return nChamfer, dDepth, sErr, bForceUseBlade -end - ---------------------------------------------------------------------- -local function InitGlob( Proc, nPhase, nRawId, nPartId, dOvmHead) - if not Proc then - return false, 'Error : Proc is missing' - end - - -- setto a nil la variabile smussi - _bMadeChamfer = nil - _nPhase = nPhase - _nRawId = nRawId - _nPartId = nPartId - _dOvmHead = dOvmHead - - if _nRawId then - -- recupero l'ingombro del grezzo di appartenenza - _b3Raw = EgtGetRawPartBBox( _nRawId) - end - - if not _nPartId then - _nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) - end - - if _nPartId then - -- recupero gruppo per geometria addizionale - _nAddGrpId = BL.GetAddGroup( _nPartId) - -- recupero l'ingombro della trave - _b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( _nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) - else - local sErr = 'Error : part ID not found' - EgtOutLog( sErr) - return false, sErr - end - - if not _b3Solid then - local sErr = 'Error : part box not found' - EgtOutLog( sErr) - return false, sErr - end - - if not _nAddGrpId then - local sErr = 'Error : missing AddGroup' - EgtOutLog( sErr) - return false, sErr - end - - -- leggo i valori dei parametri Q - AssignQValues( Proc) - -- verifico se sono presenti i parametri per la profondità smusso e - -- per eseguire in esclusiva solo lo smusso - _nChamfer, _dDepthCham, _sErrCham, _bForceUseBlade = EvaluateChamfer() - - return true, '' -end - ---------------------------------------------------------------------- -local function UpdateFacet1Data( nProcId, tFData, nFacInd, dFacElev) - if not tFData then - tFData = {} - end - tFData.nFacInd = nFacInd - if dFacElev then - tFData.dFacElev = dFacElev - end - if tFData.nFacInd and tFData.nFacInd > -1 then - tFData.ptC, tFData.vtN = EgtSurfTmFacetCenter( nProcId, tFData.nFacInd, GDB_ID.ROOT) - tFData.rfFac, tFData.dH, tFData.dV = EgtSurfTmFacetMinAreaRectangle( nProcId, tFData.nFacInd, GDB_ID.ROOT) - end - return tFData -end - ---------------------------------------------------------------------- -local function UpdateFacet2Data( nProcId, tFData, nFacInd2, dFacElev2) - if not tFData then - tFData = {} - end - tFData.nFacInd2 = nFacInd2 - if dFacElev2 then - tFData.dFacElev2 = dFacElev2 - end - if tFData.nFacInd2 and tFData.nFacInd2 ~= true and tFData.nFacInd2 > -1 then - tFData.ptC2, tFData.vtN2 = EgtSurfTmFacetCenter( nProcId, tFData.nFacInd2, GDB_ID.ROOT) - tFData.rfFac2, tFData.dH2, tFData.dV2 = EgtSurfTmFacetMinAreaRectangle( nProcId, tFData.nFacInd2, GDB_ID.ROOT) - end - return tFData -end - ---------------------------------------------------------------------- -local function GetFacetsData( nProcId) - local tFData = {} - local nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( nProcId, _nPartId) - if nFacInd then - tFData = UpdateFacet1Data( nProcId, tFData, nFacInd, dFacElev) - tFData = UpdateFacet2Data( nProcId, tFData, nFacInd2, dFacElev2) - if tFData.nFacInd == -1 and tFData.nFacInd2 and tFData.nFacInd2 == true then - tFData.isOrthoFaces = true - end - end - return tFData -end - ---------------------------------------------------------------------- -local function SwapFacetsData( tFData) - if tFData then - tFData.nFacInd, tFData.nFacInd2 = tFData.nFacInd2, tFData.nFacInd - tFData.dFacElev, tFData.dFacElev2 = tFData.dFacElev2, tFData.dFacElev - tFData.ptC, tFData.ptC2 = tFData.ptC2, tFData.ptC - tFData.vtN, tFData.vtN2 = tFData.vtN2, tFData.vtN - tFData.rfFac, tFData.rfFac2 = tFData.rfFac2, tFData.rfFac - tFData.dH, tFData.dH2 = tFData.dH2, tFData.dH - tFData.dV, tFData.dV2 = tFData.dV2, tFData.dV - end - return tFData -end - ---------------------------------------------------------------------- -local function GetToolInfoForMachining( sMachiningName) - if EgtMdbSetCurrMachining( sMachiningName) then - local toolInfo = {} - toolInfo.sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) - if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( toolInfo.sTuuid) or '') then - toolInfo.dLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) - toolInfo.dDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) - toolInfo.dThDiam = EgtTdbGetCurrToolThDiam() - toolInfo.dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) - toolInfo.dMaxDepth = EgtTdbGetCurrToolMaxDepth() - toolInfo.dSideDepth = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') - toolInfo.dCornerRad = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) - toolInfo.dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) - return toolInfo - end - end - return nil -end - ---------------------------------------------------------------------- -local function FormatWarning( sWarn, sWarn2) - if sWarn2 then - if not sWarn then sWarn = '' end - sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2) - end - return sWarn -end - ---------------------------------------------------------------------- --- Restituisce solo gli indici delle facce adiacenti esistenti (no -1) -local function GetValidFacetAdjacencies( nSurfId, nFacet) - local vValidAdj - local vFacAdj = EgtSurfTmFacetAdjacencies( nSurfId, nFacet)[1] - - if vFacAdj then - vValidAdj = {} - for j = 1, #vFacAdj do - if vFacAdj[j] >= 0 then - table.insert( vValidAdj, vFacAdj[j]) - end - end - end - - return vValidAdj -end - ---------------------------------------------------------------------- -local function TestElleShape3( Proc, bNotProc) - local nNumFacet - local nProcId - -- se non passato il Proc vero e proprio - if bNotProc then - nProcId = Proc - nNumFacet = EgtSurfTmFacetCount( nProcId) - else - nProcId = Proc.Id - nNumFacet = Proc.Fct - end - -- valida solo nel caso di tre facce - if nNumFacet ~= 3 then return false end - -- determino se L con una faccia terminale o U con tre facce - local bIsL = true - for i = 1, 3 do - -- conto le facce adiacenti (solo quelle valide) - local vFacAdj = GetValidFacetAdjacencies( nProcId, i - 1) - if #vFacAdj == 1 then - bIsL = false - break - end - end - return bIsL -end - ---------------------------------------------------------------------- -local function TestElleShape4( Proc) - -- valida solo nel caso di quattro facce - if Proc.Fct ~= 4 then return false end - -- determino se L con due facce terminali o O - local nFac3Adj = 0 - local dMinArea3 = GEO.INFINITO * GEO.INFINITO - local dMaxArea2 = 0 - for i = 1, 4 do - -- conto le facce adiacenti (solo quelle valide) - local vFacAdj = GetValidFacetAdjacencies( Proc.Id, i - 1) - local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, i - 1, GDB_ID.ROOT) - local dArea = dH * dV - if #vFacAdj == 2 then - dMaxArea2 = max( dMaxArea2, dArea) - elseif #vFacAdj == 3 then - dMinArea3 = min( dMinArea3, dArea) - nFac3Adj = nFac3Adj + 1 - end - end - if nFac3Adj ~= 2 then return false end - -- verifico se L profonda oppure lunga - if dMinArea3 < 2 * dMaxArea2 then - return 1 - else - return 2 - end -end - ---------------------------------------------------------------------- ---- Test per facce a forma di U o a forma di L -local function TestUL( Proc) - local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) - -- verifico se due facce o L con una o due facce di terminazione - local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2) - - return bIsU, bIsL -end - ---------------------------------------------------------------------- -local function GetIdIniEndPoints( ptP1, ptP2, tFac) - local nIdIniPoint - local nIdEndPoint - if ptP1 and ptP2 then - if dist( ptP1, tFac[4]) < GEO.EPS_SMALL or dist( ptP2, tFac[4]) < GEO.EPS_SMALL then - nIdEndPoint = 4 - nIdIniPoint = 5 - elseif dist( ptP1, tFac[5]) < GEO.EPS_SMALL or dist( ptP2, tFac[5]) < GEO.EPS_SMALL then - nIdEndPoint = 5 - nIdIniPoint = 4 - end - end - return nIdIniPoint, nIdEndPoint -end - ---------------------------------------------------------------------- -local function GetChainSawBlockedAxis( nInd) - if BD.GetChainSawBlockedAxis then - return BD.GetChainSawBlockedAxis( nInd) - else - if nInd == 1 then - return EgtIf( BD.C_SIMM, 'A=90', 'A=0') - else - return EgtIf( BD.C_SIMM, 'A=0', 'A=90') - end - end -end - ---------------------------------------------------------------------- -local function GetChainSawInitAngs( vtN, vtO) - if BD.GetChainSawInitAngs then - return BD.GetChainSawInitAngs( vtN, vtO) - else - if BD.C_SIMM then - if vtN:getY() > 0 then - return 'C=180' - else - return 'C=-180' - end - else - return '' - end - end -end - ---------------------------------------------------------------------- -local function VerifyChainSaw( dMinDim, dMaxDim) - local bUseChainSaw = false - local sMchFind = 'Sawing' - local sSawing = ML.FindSawing( sMchFind) - local dMaxMat = 0 - local dSawCornerRad = 0 - local dSawThick = 0 - local dMaxDepth = 200 - -- se non trova una lavorazione di sawing esco - if not sSawing then - return bUseChainSaw - else - -- recupero i dati dell'utensile - local dToolLength = 0 - local dSawWidth = 75 - local TI = GetToolInfoForMachining( sSawing) - if TI then - dToolLength = TI.dLength or dToolLength - dMaxMat = TI.dMaxMat or dMaxMat - dSawWidth = TI.dDiam or dSawWidth - dSawThick = TI.dThick or dSawThick - dSawCornerRad = TI.dCornerRad or dSawCornerRad - dMaxDepth = TI.dMaxDepth or dMaxDepth - if dSawThick < ( dMinDim + 10 * GEO.EPS_SMALL) and dSawWidth < ( dMaxDim + 10 * GEO.EPS_SMALL) then - bUseChainSaw = true - end - end - end - return bUseChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick, dMaxDepth -end - ---------------------------------------------------------------------- -local function VerifyPocket( dDiam, dDepth, dMaxTotLen, sMchFindMaster, bPocketUp, bPocketDown) - -- tipo di svuotatura - local sMchFind = EgtIf( sMchFindMaster and #sMchFindMaster > 0, sMchFindMaster, 'Pocket') - -- ricerca della svuotatura - local sPocketing - if dDepth then - sPocketing, _, _, bPocketDown = ML.FindPocketing( sMchFind, dDiam, dDepth, dMaxTotLen) or - ML.FindPocketing( sMchFind, dDiam, 0.8 * dDepth, dMaxTotLen) or - ML.FindPocketing( sMchFind, dDiam, 0.6 * dDepth, dMaxTotLen) or - ML.FindPocketing( sMchFind, dDiam, 0.4 * dDepth, dMaxTotLen) or - ML.FindPocketing( sMchFind, dDiam, 0, dMaxTotLen) - else - sPocketing, _, _, bPocketDown = 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 - local TI = GetToolInfoForMachining( sPocketing) - if TI then - dToolDiam = TI.dDiam or dToolDiam - dMaxDepth = TI.dMaxDepth or dMaxDepth - bUsePocketing = true - end - return bUsePocketing, sPocketing, dMaxDepth, dToolDiam, bPocketDown -end - ---------------------------------------------------------------------- -local function VerifyBHSideMill( Proc, bSinglePart, bPrevBhSideMill) - - local bUseBHSideMill = false - local bHead = true - local bHeadDir = true - local sMilling - local dThickTool = 0 - local dToolDiam = 0 - -- 22/09/2021 Su richiesta di Alessandro Sola, si toglie la richiesta di presenza del parametro Q per poter applicare - -- la lavorazione su più features (che non hanno questo parametro Q), quindi questa lavorazione viene verificata se è abilitato il parametro utensile - -- che ovviamente tramite la lavorazione è abbinata alla lista lavorazioni con BHSideMill. - -- Al fine di mantenere il funzionamento precedente (purtroppo non sono stati descritti i motivi del confrontare il parametro Q) - -- si elude il controllo del Q solo se la variabile del Beamdata BD.BH_MACHINE segnala che non è una macchina tipo BH (ha la fresa blockhaus al posto della lama) - - -- se non feature BlockHausHalfLap o non abilitato parametro Q per lavorarlo di fianco esco - if Proc.Prc ~= 37 and Q_SIDE_ROUGH_TOOL == 0 and not BD.BH_MACHINE then - return false - end - -- verifico se U o L - local bIsU, bIsL = TestUL( Proc) - -- verifico se la funzione è lanciata da IsTailFeature o Classify - if bSinglePart == nil then - -- se lunghezza non richiede spezzatura setto la variabile bSinglePart per non fare con fresa BH - -- perchè deve avere almeno 2 facce - if not ( ( Proc.Box:getDimX() > BD.LONGCUT_MAXLEN) or - ( Proc.Box:getDimX() > 0.8 * _b3Solid:getDimX() and Proc.Box:getDimX() > BD.LONGCUT_ENDLEN)) then - bSinglePart = true - end - end - -- ad oggi 22/09/2021 la lavorazione BH non va bene se le facce di chiusura non sono perpendicolari a X, quindi - -- se non sono perpendicolari non si applica la lavorazione BH - if bIsU or bIsL then - local bExit = false - for i = 1, Proc.Fct do - local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) - if abs( vtN:getX()) > 0.001 and abs( vtN:getX()) < 0.999962 then - bExit = true - break - end - end - if bExit then - return false - end - end - - -- se forma a U o L verifico che - -- se U e lunghezza non richiede spezzatura - if ( bIsU or bIsL or ( Proc.Fct == 1 and not bSinglePart)) and Proc.Box:getDimX() <= BD.LONGCUT_MAXLEN then - -- se faccia singola di un passo multiplo e risultato precedente non applicato, riporto il risultato del passo precedente - if ( bIsU or bIsL or ( Proc.Fct == 1 and not bSinglePart)) and bPrevBhSideMill ~= nil and not bPrevBhSideMill then - return false - end - -- recupero la lavorazione - sMilling = ML.FindMilling( 'BHSideMill') - if sMilling then - -- recupero i dati dell'utensile - local dToolLength = 0 - local dMaxDepth = 0 - local TI = GetToolInfoForMachining( sMilling) - if TI then - dToolLength = TI.dLength or dToolLength - dToolDiam = TI.dDiam or dToolDiam - dMaxDepth = TI.dMaxDepth or dMaxDepth - dThickTool = TI.dThick or dThickTool - end - -- verifico se la feature è abbastanza vicino a testa/coda da permettere la lavorazione con questo utensile - if _b3Solid then - local dMinXF = Proc.Box:getMin():getX() - local dMaxXF = Proc.Box:getMax():getX() - local dMinT = _b3Solid:getMin():getX() - local dMaxT = _b3Solid:getMax():getX() - -- determino se è più vicino alla testa o al bordo (con offset per evitare problemi a metà) - bHeadDir = ( dMaxT - dMinXF) < ( dMaxXF - dMinT) + 50 - bHead = bHeadDir - -- determino se è compatibile con il massimo affondamento dell'utensile - -- nota F.M il 22/09/2021: non sarebbe meglio utilizzare lo spessore lama invece della massima lavorazione? - -- questo perchè Alessandro ha settato il parametro Max Material a 80 con spessore lama 42 - -- se invece il Max material viene usato per definire fino a che affondamento (lungo l'asse utensile) - -- può arrivare prima di collidere con la testa allora si può utilizzare il dMaxDepth - bUseBHSideMill = EgtIf( bHead, ( dMaxT - dMinXF), ( dMaxXF - dMinT)) < dMaxDepth - -- se diametro maggiore della testa - if BD.HEAD_DIM_FOR_BH and dToolDiam > BD.HEAD_DIM_FOR_BH then - bHead = true - bUseBHSideMill = true - end - end - end - end - return bUseBHSideMill, bHead, bHeadDir, sMilling, dThickTool, dToolDiam -end - ---------------------------------------------------------------------- -local function GetTunnelDimension( Proc) - -- sono necessarie almeno due facce - if Proc.Fct < 2 then return 0, 0, 0 end - -- recupero centro e normale delle facce - local ptC = {} - local vtN = {} - for i = 1, Proc.Fct do - ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) - end - -- calcolo l'orientamento del tunnel - local vtOrtho - local bAdj = EgtSurfTmFacetsContact( Proc.Id, 0, 1) - if bAdj then - vtOrtho = vtN[1] ^ vtN[2] - else - if Proc.Fct >= 3 then - vtOrtho = vtN[1] ^ vtN[3] - else - return 0, 0, 0 - end - end - -- ottengo il boundingBox e prendo le dimensioni lungo la direzione (Z locale) che rappresenta la profondità della fessura - local frFc = Frame3d( ptC[1], vtOrtho) - local b3BoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc) - local dDepth = b3BoxLoc:getDimZ() - -- centro del bounding box locale - local ptCen = b3BoxLoc:getCenter() - ptCen:toGlob( frFc) - -- creo superficie intermedia - local nSurfInt = EgtSurfTmPlaneInBBox( _nAddGrpId, ptCen, vtOrtho, _b3Solid, GDB_ID.ROOT) - if not nSurfInt then return 0, 0, 0 end - -- ritaglio la superficie con le facce della fessura - for i = 1, Proc.Fct do - EgtCutSurfTmPlane( nSurfInt, ptC[i], -vtN[i], false, GDB_ID.ROOT) - end - local frSurfInt, dDimMax, dDimMin = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT) - -- cerco la faccia con larghezza pari a dimensione massima della fessura - local nLongFaceId = 0 - for i = 1, Proc.Fct do - if abs( vtN[i] * frSurfInt:getVersX()) < 0.5 then - nLongFaceId = i - 1 - break - end - end - return dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt -end - ---------------------------------------------------------------------- -local function GetFaceAdj( Proc, tFData) - -- Recupero le facce adiacenti alla principale (solo quelle esistenti) - local vAdj = GetValidFacetAdjacencies( Proc.Id, tFData.nFacInd) - if not vAdj or #vAdj == 0 then - local sErr = 'Error : main face without adjacencies' - return -1, sErr - end - EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 4) - -- Riordino le dimensioni per avere dH > dV - if tFData.dH < tFData.dV then - tFData.dH, tFData.dV = tFData.dV, tFData.dH - end - -- Cerco una faccia adiacente alla principale sul lato lungo - local nFacAdj - for i = 1, #vAdj do - local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, tFData.nFacInd, vAdj[i], GDB_ID.ROOT) - local dLen = dist( ptP1, ptP2) - if dLen > 0.5 * tFData.dH then - nFacAdj = vAdj[i] - EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, tFData.dH, tFData.dV), 4) - break - end - end - if not nFacAdj then - local sErr = 'Error : main face without long adjacent face' - return -1, sErr - end - return nFacAdj -end - ---------------------------------------------------------------------- -local function CalcCollisionSafety( vtDir) - local dCollSic = 10 * BD.COLL_SIC - if abs( vtDir:getX()) > 0.999 or abs( vtDir:getY()) > 0.999 or abs( vtDir:getZ()) > 0.999 then - dCollSic = 0 - elseif abs( vtDir:getX()) > 0.996 or abs( vtDir:getY()) > 0.996 or abs( vtDir:getZ()) > 0.996 then - dCollSic = 1 * BD.COLL_SIC - elseif abs( vtDir:getX()) > 0.89 or abs( vtDir:getY()) > 0.89 or abs( vtDir:getZ()) > 0.89 then - dCollSic = 2.5 * BD.COLL_SIC - elseif abs( vtDir:getX()) > 0.866 or abs( vtDir:getY()) > 0.866 or abs( vtDir:getZ()) > 0.866 then - dCollSic = 4 * BD.COLL_SIC - elseif abs( vtDir:getX()) > 0.707 or abs( vtDir:getY()) > 0.707 or abs( vtDir:getZ()) > 0.707 then - dCollSic = 5.5 * BD.COLL_SIC - end - return dCollSic -end - ---------------------------------------------------------------------- --- Verifica se feature di testa -function ProcessLapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) - if not InitGlob( Proc) then - return false - end - -- se una sola faccia - if Proc.Fct == 1 then - local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) - if vtN0:getX() > 0.1 then - return true - end - end - -- verifico se è in testa - if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then - return false - end - -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave - if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 * b3Raw:getDimX()) then - return false - end - -- se una o due facce e interessa veramente la testa, allora di testa - if Proc.Fct <= 2 then - if Proc.Box:getMax():getX() > _b3Solid:getMax():getX() - 1. then - return true - elseif Proc.Box:getMax():getX() < _b3Solid:getMax():getX() - 5. then - return false - end - end - local tFData = GetFacetsData( Proc.Id) - -- deve avere la normale principale diretta verso la testa - if tFData.vtN and tFData.vtN:getX() < 0.499 then - return false - elseif Proc.Fct >= 5 then - return true - end - -- deve occupare la maggior parte dell'area - if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then - return true - end - -- non è di testa - return false -end - ---------------------------------------------------------------------- --- Verifica se feature di coda -function ProcessLapJoint.IsTailFeature( Proc, b3Raw) - if not InitGlob( Proc) then - return false - end - -- se una sola faccia - if Proc.Fct == 1 then - local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) - if vtN0:getX() < -0.1 then - return true - end - end - -- se può essere fatto con utensile tipo lama - local bUseBHSideMill, bHead, bHeadDir = VerifyBHSideMill( Proc) - if bUseBHSideMill then - Proc.HeadDir = bHeadDir - return not bHead - end - -- verifico se è in coda - local dEndDist = Proc.Box:getMin():getX() - _b3Solid:getMin():getX() - if dEndDist > BD.MAX_DIST_HTFEA then - return false - end - -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave - if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 * b3Raw:getDimX()) then - return false - end - -- se una o due facce e interessa veramente la coda, allora di coda - if Proc.Fct <= 2 then - if Proc.Box:getMin():getX() < _b3Solid:getMin():getX() + 1. then - return true - elseif Proc.Box:getMin():getX() > _b3Solid:getMin():getX() + 5. then - return false - end - end - local tFData = GetFacetsData( Proc.Id) - -- deve avere la normale principale diretta verso la coda (oppure tunnel) - if tFData.vtN and tFData.vtN:getZ() < BD.NZ_MINA and tFData.nFacInd2 then - tFData = SwapFacetsData( tFData) - end - if not tFData.vtN or tFData.vtN:getX() > -0.001 or dEndDist + tFData.vtN:getX() * tFData.dFacElev > 0 then - return false - else - return true - end -end - ---------------------------------------------------------------------- --- Classificazione della feature -function ProcessLapJoint.Classify( Proc, b3Raw) - if not InitGlob( Proc) then - return false - end - -- se 1 faccia - if Proc.Fct == 1 then - -- dati della faccia - --local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) - -- verifico se è lavorabile solo dal basso - --local bDown = ( vtN:getZ() < BD.NZ_MINA) - --return true, bDown - return true, false - -- se 2 facce - elseif Proc.Fct == 2 then - -- dati delle facce - local vtN = {} - _, vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) - _, vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) - -- verifico se è lavorabile solo dal basso - local bSmall = ( ( Proc.Head or Proc.Tail) and Proc.Box:getDimX() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) or - ( not ( Proc.Head or Proc.Tail) and Proc.Box:getDimY() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) - local bDown = ( vtN[1]:getZ() < BD.NZ_MINB and vtN[2]:getZ() < BD.NZ_MINB) or - ( vtN[1]:getZ() < BD.NZ_MINA and ( vtN[2]:getZ() < -0.1 or not bSmall)) or - ( vtN[2]:getZ() < BD.NZ_MINA and ( vtN[1]:getZ() < -0.1 or not bSmall)) - bDown = ( bDown and not BD.DOWN_HEAD) - return true, bDown - -- se più di 2 facce - else - local bClosedOrthoFaces - local nDeletedFace - local tFData = GetFacetsData( Proc.Id) - if not tFData.nFacInd or tFData.nFacInd < 0 then - if tFData.nFacInd == -1 then - bClosedOrthoFaces = tFData.isOrthoFaces - else - return false - end - end - -- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche - if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then - -- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura - for i = 1, Proc.Fct do - local nNewProc = EgtCopyGlob( Proc.Id, _nAddGrpId) or GDB_ID.NULL - -- elimino una faccia - nDeletedFace = i - 1 - if EgtSurfTmRemoveFacet( nNewProc, nDeletedFace) then - -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa - tFData = GetFacetsData( nNewProc) - if not tFData.nFacInd or tFData.nFacInd < 0 then - if tFData.nFacInd == -1 then - bClosedOrthoFaces = tFData.isOrthoFaces - EgtErase( nNewProc) - break - else - EgtErase( nNewProc) - return false - end - end - -- altrimenti esco - else - EgtErase( nNewProc) - break - end - end - -- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo - if bClosedOrthoFaces then - tFData = UpdateFacet1Data( Proc.Id, tFData, nDeletedFace) - -- rendo nulla la faccia opzionale perchè si tratta di una fessura - tFData = UpdateFacet2Data( Proc.Id, tFData, nil) - bClosedOrthoFaces = false -- non lo setto come tunnel - end - end - -- se facce formano un tunnel e sono ortogonali - if bClosedOrthoFaces then - -- ottengo le dimensioni del tunnel - local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc) - EgtErase( nSurfInt) - -- verifico se può essere fatto con svuotatura - if VerifyPocket( dDimMin) then - return true, false - elseif VerifyChainSaw( dDimMin, dDimMax) then - return true, false - else - return false - end - else - -- se può essere fatto con utensile tipo lama - local bUseBHSideMill, _, _, dMaxMat = VerifyBHSideMill( Proc) --- if bUseBHSideMill and ( dMaxMat <= tFData.dV + 15 * GEO.EPS_SMALL) then - if bUseBHSideMill and ( dMaxMat <= tFData.dH + 15 * GEO.EPS_SMALL) then - return true, false - -- altrimenti controllo se deve essere ruotato con le altre lavorazioni - else - -- dati della faccia - local _, vtN = EgtSurfTmFacetCenter( Proc.Id, tFData.nFacInd, GDB_ID.ROOT) - -- cerco se c'è faccia adiacente sul lato più lungo - local nFaceAdj = GetFaceAdj( Proc, tFData) or -1 - local _, bIsL = TestUL( Proc) - -- verifico se è lavorabile solo dal basso - local bDown = ( vtN:getZ() < BD.NZ_MINA and not BD.DOWN_HEAD) - -- se verso il basso, verifico se utilizzabile seconda faccia - if bDown then - if tFData.nFacInd2 and tFData.dFacElev2 < 2 * tFData.dFacElev then - local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFData.nFacInd2, GDB_ID.ROOT) - bDown = ( vtN2:getZ() < BD.NZ_MINB) - elseif not tFData.nFacInd2 and bIsL and nFaceAdj >= 0 then - local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFaceAdj, GDB_ID.ROOT) - bDown = ( vtN2:getZ() < BD.NZ_MINB) - end - -- verifico se la faccia principale è sottosquadra, ha forma L ed esiste la faccia adiacente - elseif vtN:getZ() < -0.2589 and bIsL and nFaceAdj >= 0 then - -- se il numero di facce > 2 o il box della feature supera una certa distanza dalle teste allora controllo la z della faccia ausiliaria - if Proc.Fct > 2 or ( Proc.Box:getMax():getX() < _b3Solid:getMin():getX() - 150) or ( Proc.Box:getMin():getX() > _b3Solid:getMax():getX() + 150) then - local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFaceAdj, GDB_ID.ROOT) - bDown = ( vtN2:getZ() < BD.NZ_MINB) - end - end - return true, bDown - end - end - end -end - ---------------------------------------------------------------------- --- Lavorazione con fresa ---------------------------------------------------------------------- -local function MakeOneFaceByMill( Proc) - -- verifico il numero di facce della tacca - assert( ( Proc.Fct == 1), 'Error : MakeOneFaceByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') - -- dati della faccia - local _, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) - -- verifico se orientata verso l'alto - local bUp = ( vtN:getZ() >= BD.NZ_MINA) - -- scelta faccia da lavorare - local nFacInd = 0 - -- recupero la lavorazione - local sMilling = ML.FindMilling( 'BirdsMouth') - if not sMilling then - local sErr = 'Error : BirdsMouth not found in library' - EgtOutLog( sErr) - return false, sErr - end - -- inserisco la lavorazione di fresatura - local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - local nMchFId = EgtAddMachining( sName, sMilling) - if not nMchFId then - local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling - EgtOutLog( sErr) - return false, sErr - end - -- aggiungo geometria - EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) - -- imposto uso faccia e lato correzione - if vtN:getX() > 0 then - EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_LEFT, MCH_MILL_FU.PARAL_LEFT)) - else - EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.PARAL_RIGHT)) - end - -- imposto lato di correzione - EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) - if not bUp then EgtSetMachiningParam( MCH_MP.INVERT, true) end - -- imposto posizione braccio porta testa - if vtN:getY() < GEO.EPS_SMALL then - EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) - else - EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) - end - -- dichiaro non si generano sfridi per VMill - EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') - -- eseguo - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - -- eventuale segnalazione ingombro di testa o coda - local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * _b3Raw:getDimZ()) - if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < _b3Raw:getMin():getZ() + dMinHIng then - if Proc.Head then - local dOffs = _b3Solid:getMax():getX() - Proc.Box:getMin():getX() - BL.UpdateHCING( _nRawId, dOffs) - elseif Proc.Tail then - local dOffs = Proc.Box:getMax():getX() - _b3Solid:getMin():getX() - BL.UpdateTCING( _nRawId, dOffs) - end - end - return true -end - ---------------------------------------------------------------------- -local function DoMill( Proc, sName, sMilling, offset, nFacInd, nFac2Ind, vtN) - -- inserisco la lavorazione di fresatura - local nMchFId = EgtAddMachining( sName, sMilling) - if not nMchFId then - local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling - EgtOutLog( sErr) - return false, sErr - end - -- aggiungo geometria - EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) - -- imposto uso faccia e lato correzione - local nFaceUse = BL.GetNearestOrthoOpposite( vtN[nFac2Ind+1]) - EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) - -- imposto lato di correzione - EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) - -- tolgo l'inversione - EgtSetMachiningParam( MCH_MP.INVERT, false) - -- aggiungo offset laterale - if offset then EgtSetMachiningParam( MCH_MP.OFFSR, offset) end - -- imposto posizione braccio porta testa - if vtN[nFacInd+1]:getY() < GEO.EPS_SMALL then - EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) - else - EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) - end - -- dichiaro non si generano sfridi per VMill - EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') - -- eseguo - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - - return true -end - ---------------------------------------------------------------------- -local function MakeTwoFacesByMill( Proc, bDownHead) - -- verifico il numero di facce della tacca - assert( ( Proc.Fct == 2), 'Error : MakeTwoFacesByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') - -- recupero la lavorazione - local sMilling - sMilling = ML.FindMilling( EgtIf( Q_USE_MILL and Q_USE_MILL == 1, 'LongSmallCut', 'BirdsMouth'), nil , nil, nil, nil, not bDownHead, bDownHead) - if not sMilling then - local sErr = 'Error : LongSmallCut & BirdsMouth not found in library' - EgtOutLog( sErr) - return false, sErr - end - -- recupero i dati dell'utensile - local dTDiam = 0 - local TI = GetToolInfoForMachining( sMilling) - if TI then - dTDiam = TI.dDiam or dTDiam - 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) - -- dati medi - local ptM = ( ptC[1] + ptC[2]) / 2 - -- verifico non siano orientate verso il basso - local bFaceOk = {} - bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) - bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB) - if not bDownHead and not bFaceOk[1] and not bFaceOk[2] then - local sErr = 'Error : LapJoint from bottom impossible' - EgtOutLog( sErr) - return false, sErr - end - -- scelta faccia da lavorare - local nFacInd - -- se entrambe possibili - if bFaceOk[1] and bFaceOk[2] then - -- se in testa, scelgo quella orientata verso la testa - if Proc.Head then - if vtN[1]:getX() > vtN[2]:getX() then - nFacInd = 0 - else - nFacInd = 1 - end - -- se altrimenti in coda, scelgo quella orientata verso la coda - elseif Proc.Tail then - if vtN[1]:getX() < vtN[2]:getX() then - nFacInd = 0 - else - nFacInd = 1 - end - -- altrimenti, scelgo quella con la normale più perpendicolare all'asse trave (se uguali, quella verso X+) - else - if abs( abs( vtN[1]:getX()) - abs( vtN[2]:getX())) < GEO.EPS_SMALL then - if ptM:getX() > _b3Raw:getCenter():getX() then - nFacInd = EgtIf( vtN[1]:getX() > vtN[2]:getX(), 0, 1) - else - nFacInd = EgtIf( vtN[1]:getX() < vtN[2]:getX(), 0, 1) - end - else - nFacInd = EgtIf( abs( vtN[1]:getX()) < abs( vtN[2]:getX()), 0, 1) - end - end - elseif bFaceOk[1] then - nFacInd = 0 - else - nFacInd = 1 - end - local nOthInd = 1 - nFacInd - local bOk, sErr, sName - -- se forzato uso fresa controllo se posso fare in una o più passate - if Q_USE_MILL and Q_USE_MILL == 1 then - sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_1' - bOk, sErr = DoMill( Proc, sName, sMilling, dTDiam / 2, nFacInd, nOthInd, vtN) - - if not bOk then return bOk, sErr end - end - sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - bOk, sErr = DoMill( Proc, sName, sMilling, 0, nFacInd, nOthInd, vtN) - if not bOk then return bOk, sErr end - -- eventuale segnalazione ingombro di testa o coda - local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * _b3Raw:getDimZ()) - if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < _b3Raw:getMin():getZ() + dMinHIng then - if Proc.Head then - local dOffs = _b3Solid:getMax():getX() - Proc.Box:getMin():getX() - BL.UpdateHCING( _nRawId, dOffs) - elseif Proc.Tail then - local dOffs = Proc.Box:getMax():getX() - _b3Solid:getMin():getX() - BL.UpdateTCING( _nRawId, dOffs) - elseif Proc.Box:getCenter():getX() > _b3Solid:getCenter():getX() then - local dOffs = _b3Solid:getMax():getX() - Proc.Box:getMin():getX() - local dDist = _b3Solid:getMax():getX() - Proc.Box:getMax():getX() - -- sempre concavo aumento la distanza (rimane una punta...) - dDist = dDist + 10 - BL.UpdateHCING( _nRawId, dOffs, dDist) - end - end - return true -end - ---------------------------------------------------------------------- -local function MakePreCuts( Proc) - -- se interessa l'intera sezione della trave, necessaria sgrossatura - if _nChamfer < 2 and Proc.Box:getDimY() > 0.9 * _b3Raw:getDimY() and Proc.Box:getDimZ() > 0.9 * _b3Raw:getDimZ() then - -- aggiungo sgrossatura e la lavoro - local AddId = EgtSurfTmConvexHullInBBox( _nAddGrpId, Proc.Id, _b3Raw, GDB_RT.GLOB) - if AddId then - EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) - -- applico lavorazione - local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, - Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} - local nCutFacet = EgtSurfTmFacetCount( AddId) - if nCutFacet == 1 then - return Cut.Make( CutProc, _nPhase, _nRawId, _nPartId, _dOvmHead) - elseif nCutFacet == 2 then - return DoubleCut.Make( CutProc, _nPhase, _nRawId, _nPartId, _dOvmHead) - end - end - end - return true -end - ---------------------------------------------------------------------- -local function MakeByMill( Proc, tFData, dCollSic, bSpecialApp, sMillMaster) - -- Cerco una faccia adiacente alla principale sul lato lungo - local nFacAdj, sErr = GetFaceAdj( Proc, tFData) - if nFacAdj < 0 then - EgtOutLog( sErr) - return false, sErr - end - -- Determino se estremi aperti o chiusi e faccia adiacente da aggiungere alla lavorazione - local bOpenStart = false - local bOpenEnd = false - local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] - EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) - local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacAdj, GDB_ID.ROOT) - -- Riordino le dimensioni per avere dH > dV - if dH2 < dV2 then - dH2, dV2 = dV2, dH2 - end - local nFacAdj2 - for j = 1, #vAdj2 do - if vAdj2[j] == tFData.nFacInd then - -- Se non esiste faccia adiacente a lato precedente -> inizio aperto - local i = EgtIf( j > 1, j - 1, #vAdj2) - while vAdj2[i] == tFData.nFacInd do - i = EgtIf( i > 1, i - 1, #vAdj2) - end - bOpenStart = ( vAdj2[i] < 0) - -- Se non esiste faccia adiacente a lato successivo -> fine aperto - local k = EgtIf( j < #vAdj2, j + 1, 1) - while vAdj2[k] == tFData.nFacInd do - k = EgtIf( k < #vAdj2, k + 1, 1) - end - bOpenEnd = ( vAdj2[k] < 0) - end - -- decommentare questa parte per concatenare due facce - --if bSpecialApp and vAdj2[j] >= 0 then - -- local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacAdj, vAdj2[j], GDB_ID.ROOT) - -- local dLen = dist( ptP1, ptP2) - -- if abs( dLen - dV2) < 10 * GEO.EPS_SMALL then - -- nFacAdj2 = vAdj2[j] - -- end - --end - end - -- Recupero la lavorazione di fresa - local sMilling - if bSpecialApp then - sMilling = sMillMaster - else - sMilling = ML.FindMilling( 'LongSmallCut') - if not sMilling then - sErr = 'Error : LongSmallCut not found in library' - EgtOutLog( sErr) - return false, sErr - end - end - -- recupero i dati dell'utensile - local dTDiam = 50 - local dMaxMat = 0 - local TI = GetToolInfoForMachining( sMilling) - if TI then - dTDiam = TI.dDiam or dTDiam - dMaxMat = TI.dMaxMat or dMaxMat - end - -- Se massimo materiale utensile è molto inferiore dell'elevazione non faccio la lavorazione e do un warning - if dMaxMat > 0 and dMaxMat + 15 < tFData.dFacElev + dCollSic then - local sWarn = 'Warning : skipped milling; elevation bigger than max tool depth' - return true, sWarn, dMaxMat - end - -- Calcolo uso faccia - local nFaceUse = BL.GetNearestParalOpposite( tFData.rfFac:getVersZ()) - -- inserisco la lavorazione di fresatura - local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - local nMchFId = EgtAddMachining( sName, sMilling) - if not nMchFId then - sErr = 'Error adding machining ' .. sName .. '-' .. sMilling - EgtOutLog( sErr) - return false, sErr - end - -- aggiungo geometria - if nFacAdj2 then - EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}, { Proc.Id, nFacAdj2}}) - else - EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) - end - -- imposto uso faccia - EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) - -- imposto posizione braccio porta testa - local nSCC = MCH_SCC.ADIR_YM - if tFData.rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then - nSCC = MCH_SCC.ADIR_YP - end - EgtSetMachiningParam( MCH_MP.SCC, nSCC) - -- lato di lavoro e direzione - EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) - EgtSetMachiningParam( MCH_MP.INVERT, true) - -- tipo di attacco e uscita - EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR) - EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.LINEAR) - -- imposto accorciamento iniziale/finale per estremi aperti/chiusi - if bSpecialApp then - -- applico gli allungamenti o accorciamenti considerando che la lavorazione è invertita - if nFacAdj2 then - EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2) - else - EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, dTDiam / 2, - dTDiam / 2)) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, dTDiam / 2, - dTDiam / 2)) - -- confronto la faccia applicata nella lavorazione (faccia adiacente) con la seconda faccia passata nella funzione - -- se corrispondono allora aggiungo una estensione nei lati chiusi pari all'elevazione della stessa faccia corrispondente - if nFacAdj == tFData.nFacInd2 then - if not bOpenStart then - EgtSetMachiningParam( MCH_MP.LOPERP, tFData.dFacElev2) - EgtSetMachiningParam( MCH_MP.LOTANG, 0) - end - if not bOpenEnd then - EgtSetMachiningParam( MCH_MP.LIPERP, tFData.dFacElev2) - EgtSetMachiningParam( MCH_MP.LITANG, 0) - end - end - end - -- applico elevazione - local sNotes = 'MaxElev=' .. EgtNumToString( tFData.dFacElev, 1) .. ';' - EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) - else - EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, 0, - dTDiam / 2)) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, 0, - dTDiam / 2)) - end - -- eseguo - if not ML.ApplyMachining( true, false) then - _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - return true, '', dTDiam -end - ---------------------------------------------------------------------- -local function ChooseCorner( Proc, nFacInd) - -- Recupero le adiacenze della faccia principale - local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] - -- Cerco i corner tra le facce adiacenti alla principale - local tFacAdj = {} - for i = 1, #vAdj do - if vAdj[i] >= 0 then - for j = i + 1, #vAdj do - if vAdj[j] >= 0 then - local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vAdj[i], vAdj[j], GDB_ID.ROOT) - if ptP1 and ptP2 and dAng < 0 then - local dLen = dist( ptP1, ptP2) - table.insert( tFacAdj, { vAdj[i], vAdj[j], dLen, ptP1, ptP2, dAng}) - end - end - end - end - end - -- Tra le linee dei corner determino la più lunga - local dMaxLen = 0 - local nIdLine - for i = 1, #tFacAdj do - if tFacAdj[i][3] > dMaxLen then - nIdLine = i - dMaxLen = tFacAdj[i][3] - end - end - - return dMaxLen, nIdLine, tFacAdj -end - ---------------------------------------------------------------------- -local function ChooseContour( Proc, nFacInd, bVerifyCorner) - -- Recupero le adiacenze della faccia principale - local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] - -- Se richiesto, verifico che ci siano facce adiacenti consecutive (sicuramente con angolo) - if bVerifyCorner then - local bCorner = false - for i = 1, #vAdj do - local j = EgtIf( i > 1, i - 1, #vAdj) - if vAdj[i] >= 0 and vAdj[j] >= 0 then - bCorner = true - break - end - end - if not bCorner then return {} end - end - -- Cerco le facce adiacenti con angolo convesso - local tFacAdjMain = {} - for i = 1, #vAdj do - if vAdj[i] >= 0 then - local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) - if ptP1 and ptP2 and dAng < 0 then - local dLen = dist( ptP1, ptP2) - table.insert( tFacAdjMain, { vAdj[i], dLen, ptP1, ptP2, dAng}) - end - end - end - - return tFacAdjMain -end - ---------------------------------------------------------------------- -local function CheckToInvert( AuxId, bPositive) - -- recupero versore estrusione - local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT) - -- faccio una copia del percorso - local sParnt = EgtGetParent( AuxId) - local nNewEntId = EgtCopyGlob( AuxId, sParnt) - -- chiudo il percorso - if EgtCloseCurveCompo( nNewEntId) then - local vtMPlane, dDist, dArea = EgtCurveArea( nNewEntId) - -- cancello percorso copia - EgtErase( nNewEntId) - if dArea and abs(dArea) > 1 then - local frEnt = EgtGetGlobFrame( AuxId) - if vtMPlane then - vtMPlane:toGlob(frEnt) - if dArea and dArea * ( vtMPlane * vtExtr) < 0 then - if bPositive then - return true - end - elseif dArea and dArea * ( vtMPlane * vtExtr) > 0 then - if not bPositive then - return true - end - end - end - end - else - -- cancello percorso copia - EgtErase(nNewEntId) - end - - return false -end - ---------------------------------------------------------------------- -local function TestPoints( nPathInt, idx, dDiff, pP1, pP2, sAxis) - local pPini = EgtIf( sAxis == 'X', pP1:getX(), EgtIf( sAxis == 'Y', pP1:getY(), pP1:getZ())) - local pPend = EgtIf( sAxis == 'X', pP2:getX(), EgtIf( sAxis == 'Y', pP2:getY(), pP2:getZ())) - local b3SolidMin = EgtIf( sAxis == 'X', _b3Solid:getMin():getX(), EgtIf( sAxis == 'Y', _b3Solid:getMin():getY(), _b3Solid:getMin():getZ())) - local b3SolidMax = EgtIf( sAxis == 'X', _b3Solid:getMax():getX(), EgtIf( sAxis == 'Y', _b3Solid:getMax():getY(), _b3Solid:getMax():getZ())) - if ( abs( pPini - b3SolidMax) < dDiff and abs( pPend - b3SolidMax) < dDiff) or - ( abs( pPini - b3SolidMin) < dDiff and abs( pPend - b3SolidMin) < dDiff) then - -- setto l'entità open - local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' - if #sActInfo > 0 then - EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. idx) - else - EgtSetInfo( nPathInt, 'OPEN', idx) - end - return true - else - return false - end -end - ---------------------------------------------------------------------- -local function SetOpenSide( nPathInt, vtOrtho, nStartPoint) - -- fondo tra loro le curve compatibili - EgtMergeCurvesInCurveCompo( nPathInt) - local nStartIdEnt, nNumEnt = EgtCurveDomain( nPathInt) - local pLastPIni, pLastPEnd - - -- faccio una copia della curva e la esplodo - if nStartIdEnt then - -- prendo i punti - for i = 1, nNumEnt do - local pPini = EgtUP( nPathInt, (i - 1), GDB_RT.GLOB) - local pPend = EgtUP( nPathInt, EgtIf( i == nNumEnt, 0, i), GDB_RT.GLOB) - -- Se normale lungo la Z considero il box in X e Y - if abs( vtOrtho:getZ()) > 0.999 then - -- se corrisponde a X prendo i punti per eventuale modifica del punto di inizio percorso - if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'X') then - pLastPIni = pPini - pLastPEnd = pPend - -- altrimenti se corrisponde a Y prendo i punti per eventuale modifica del punto di inizio percorso - elseif TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Y') then - pLastPIni = pPini - pLastPEnd = pPend - end - -- altrimenti se normale lungo la Y considero il box in X e Z - elseif abs( vtOrtho:getZ()) < 0.001 and abs( vtOrtho:getY()) > 0.999 then - -- se corrisponde a X prendo i punti per eventuale modifica del punto di inizio percorso - if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'X') then - pLastPIni = pPini - pLastPEnd = pPend - -- altrimenti se corrisponde a Z prendo i punti per eventuale modifica del punto di inizio percorso - elseif TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Z') then - pLastPIni = pPini - pLastPEnd = pPend - end - -- caso che non dovrebbe mai capitare ma gestito per completezza - -- altrimenti se normale lungo la X considero il box in Y e Z - elseif abs( vtOrtho:getZ()) < 0.001 and abs( vtOrtho:getX()) > 0.999 then - -- se corrisponde a Y prendo i punti per eventuale modifica del punto di inizio percorso - if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Y') then - pLastPIni = pPini - pLastPEnd = pPend - -- altrimenti se corrisponde a Z prendo i punti per eventuale modifica del punto di inizio percorso - elseif TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Z') then - pLastPIni = pPini - pLastPEnd = pPend - end - -- se asse Z orizzontale verifico se si avvicina piú a Y - elseif abs( vtOrtho:getZ()) < 0.001 then - if abs( vtOrtho:getY()) > 0.75 then - -- se corrisponde a Z prendo i punti per eventuale modifica del punto di inizio percorso - if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Z') then - pLastPIni = pPini - pLastPEnd = pPend - end - end - -- se asse Y a 0 (fresa ne davanti ne dietro) verifico se si avvicina piú a Z+ - elseif abs( vtOrtho:getY()) < 0.001 then - if abs( vtOrtho:getZ()) > 0.75 then - -- se corrisponde a Y prendo i punti per eventuale modifica del punto di inizio percorso - if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Y') then - pLastPIni = pPini - pLastPEnd = pPend - end - end - end - end - -- se devo cambiare il punto di partenza - if nStartPoint then - if pLastPIni and pLastPEnd then - -- calcolo il punto medio con gli ultimi punti utilizzati - local ptPs = ( pLastPIni + pLastPEnd) / 2 - EgtChangeClosedCurveStartPoint( nPathInt, ptPs, GDB_RT.GLOB) - -- se devo eliminare la parte open - if nStartPoint == 2 then - EgtRemoveCurveCompoCurve( nPathInt, true) - EgtRemoveCurveCompoCurve( nPathInt, false) - return true - end - end - end - end - - return false -end - ---------------------------------------------------------------------- -local function DoClean( sName, sMilling, nIdPath, vtN, dMaxElev, dMachDepth, dExtraDepth, dNoLeadsAddLen, dLeadInPerp, - bLeftWorkside, bInvertTool, bInvertDir, bCheckToInvertPath, bSCCEvaluateOppositeVector, bEvaluateAddLeads) - local nMchId = EgtAddMachining( sName, sMilling) - local sMyWarn - if not nMchId then - sMyWarn = 'Warning : impossible add machining ' .. sName .. '-' .. sMilling - return false, sMyWarn - end - -- aggiungo geometria - EgtSetMachiningGeometry( {{ nIdPath, -1}}) - -- imposto lato di lavoro sinistro - if bLeftWorkside then - EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) - end - -- imposto direzione utensile opposta - if bInvertTool then - EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) - end - -- imposto posizione braccio porta testa - local nSCC = MCH_SCC.NONE - if not BD.C_SIMM then - if EgtIf( bSCCEvaluateOppositeVector, AreSameOrOppositeVectorApprox( vtN, Z_AX()), AreSameVectorApprox( vtN, Z_AX())) then - nSCC = MCH_SCC.ADIR_YM - elseif abs( vtN:getX()) < 0.1 then - nSCC = EgtIf( BL.IsPartFinalPhase( _nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) - elseif vtN:getY() < GEO.EPS_SMALL then - nSCC = EgtIf( bInvertDir, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) - else - nSCC = EgtIf( bInvertDir, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP) - end - end - EgtSetMachiningParam( MCH_MP.SCC, nSCC) - -- gestione attacco e uscita - if bEvaluateAddLeads and EgtCurveIsClosed( nIdPath) then - -- attacco e uscita a quarto di cerchio senza allungamenti a inizio e fine - EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.TANGENT) - EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) - EgtSetMachiningParam( MCH_MP.LITANG, 0) - EgtSetMachiningParam( MCH_MP.LIPERP, dLeadInPerp) - EgtSetMachiningParam( MCH_MP.LIELEV, 0) - EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) - else - -- nessun attacco e uscita, allungo inizio e fine di 3/4 del diametro utensile - EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.NONE) - EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) - EgtSetMachiningParam( MCH_MP.STARTADDLEN, dNoLeadsAddLen) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, dNoLeadsAddLen) - end - -- setto massimo affondamento possibile - EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth + dExtraDepth) - -- setto se devo invertire il percorso - if bCheckToInvertPath then - local bInvert = CheckToInvert( nIdPath, true) - EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bInvertDir, not bInvert, bInvert)) - end - -- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione - local sUserNotes = 'VMRS=0;MaxElev=' .. EgtNumToString( ( dMaxElev + dMachDepth), 1) .. ';' - EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) - -- eseguo - if ML.ApplyMachining( true, false) then - _, sMyWarn = EgtGetMachMgrWarning( 0) - if EgtIsMachiningEmpty() then - EgtSetOperationMode( nMchId, false) - end - -- altrimenti lavorazione non applicata - else - _, sMyWarn = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchId, false) - return false, sMyWarn - end - return true, sMyWarn -end - ---------------------------------------------------------------------- -local function MakeRoundCleanCorner( Proc, nFacInd, dDiam, bMillDown, bDoubleSide) - -- recupero la lavorazione senza considerare l'elevazione - local sMilling = ML.FindMilling( 'SmallToolContour', nil, nil, nil, nil, not ( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide) - if not sMilling then - local sMyWarn = 'Warning : SmallToolContour not found in library' - EgtOutLog( sMyWarn) - return true, sMyWarn - end - - -- recupero i dati dell'utensile - local dTDiam = 50 - local dTMaxDepth = 0 - local TI = GetToolInfoForMachining( sMilling) - if TI then - dTDiam = TI.dDiam or dTDiam - dTMaxDepth = TI.dMaxDepth or dTMaxDepth - end - - -- se il diametro trovato non è minore dei 3/4 del diametro utilizzato in precedenza, esco - if dTDiam > ( 0.75 * dDiam) then - local sMyWarn = 'Warning : tool diameter not enough small' - EgtOutLog( sMyWarn) - return true, sMyWarn - end - - -- ottengo gli angoli dove applicare il percorso con fresa più piccola - local _, _, tFacAdj = ChooseCorner( Proc, nFacInd) - -- se non trovato nessun angolo interno valido esco - if #tFacAdj == 0 then - return true - end - - -- recupero la normale della faccia di fondo - local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) - -- se fresatura da sotto salto la lavorazione - if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then - local sErr = 'Error : milling from bottom ' - EgtOutLog( sErr) - return false, sErr - end - - -- ciclo su tutti gli angoli trovati - local sMyWarn = '' - for i = 1, #tFacAdj do - local pAuxId = {} - -- le 2 facce di contatto devono essere perpendicolari e non sottosquadra rispetto alla faccia di fondo - local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][1], GDB_ID.ROOT) - local _, ptP1x, ptP2x, dAngx = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][2], GDB_ID.ROOT) - if dAng >= 0 or dAng < -90 - 10 * GEO.EPS_SMALL or dAngx >= 0 or dAngx < -90 - 10 * GEO.EPS_SMALL then - goto continue - end - -- prendo la lunghezza di adiacenza delle due linee - local dLen1 = dist( ptP1, ptP2) - local dLen2 = dist( ptP1x, ptP2x) - -- cerco il punto tra le 3 facce: nIdEndPoint - local _, nIdEndPoint = GetIdIniEndPoints( ptP1, ptP2, tFacAdj[i]) - -- devo avere un punto comune - if not nIdEndPoint then - goto continue - end - -- calcolo lunghezza minima in base all'angolo tra le due pareti - local dMinDist = ( ( dDiam / 2) / tan( ( 180 + tFacAdj[i][6]) / 2)) + 2 - -- verifico che entrambe le linee siano maggiori delle lunghezza minima - if dLen1 <= dMinDist or dLen2 <= dMinDist then - sMyWarn = 'Warning : impossible make clean corner path' - goto continue - end - -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro - local ptApPoint = EgtIf( dist( tFacAdj[i][nIdEndPoint], ptP1) < 10 * GEO.EPS_SMALL, ptP2, ptP1) - -- prima linea - local nAuxId = EgtLine( _nAddGrpId, ptApPoint, tFacAdj[i][nIdEndPoint], GDB_RT.GLOB) - -- calcolo arretramento - local dTrimDist = dLen1 - dMinDist - -- se arretramento valido - if dTrimDist > 100 * GEO.EPS_SMALL then - EgtTrimExtendCurveByLen( nAuxId , -dTrimDist, ptApPoint, GDB_RT.GLOB) - end - table.insert( pAuxId, nAuxId) - -- se il punto finale corrisponde con il punto comune, uso l'altro - ptApPoint = EgtIf( dist( tFacAdj[i][nIdEndPoint], ptP1x) < 10 * GEO.EPS_SMALL, ptP2x, ptP1x) - -- seconda linea - nAuxId = EgtLine( _nAddGrpId, tFacAdj[i][nIdEndPoint], ptApPoint, GDB_RT.GLOB) - -- calcolo arretramento - dTrimDist = dLen2 - dMinDist - -- se arretramento valido - if dTrimDist > 100 * GEO.EPS_SMALL then - EgtTrimExtendCurveByLen( nAuxId , -dTrimDist, ptApPoint, GDB_RT.GLOB) - end - table.insert( pAuxId, nAuxId) - -- trasformo in percorso - local AuxId - if #pAuxId > 0 then - AuxId = EgtCurveCompo( _nAddGrpId, pAuxId, true) - end - -- deve esserci il percorso - if not AuxId then - sMyWarn = 'Warning : impossible make clean corner path' - goto continue - end - -- modifico versore direzione - EgtModifyCurveExtrusion( AuxId, vtN1, GDB_RT.GLOB) - -- inserisco la lavorazione - local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - local dDepth = 0 - if tFacAdj[i][3] > dTMaxDepth then - dDepth = dTMaxDepth - tFacAdj[i][3] - end - _, sMyWarn = DoClean( sName, sMilling, AuxId, vtN1, tFacAdj[i][3], dDepth, 0, 0, 0, true, false, false, true, true, false) - ::continue:: - end - if #sMyWarn > 0 then - EgtOutLog( sMyWarn) - end - - return true, sMyWarn -end - ---------------------------------------------------------------------- -local function MakeRoundCleanContour( Proc, nFacInd, dDiam, bMillDown, - bDoubleSide, vtOrtho, nPathInt, nSurfInt, - dDepth, bOneShot) - - -- recupero la lavorazione senza considerare l'elevazione perché viene calcolata l'elevazione utile - local sMilling = ML.FindMilling( 'SmallToolContour', nil, nil, nil, nil, not ( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide) - if not sMilling then - local sMyWarn = 'Warning : SmallToolContour not found in library' - EgtOutLog( sMyWarn) - return true, sMyWarn - end - - -- recupero i dati dell'utensile - local dTDiam = 50 - local dTMaxDepth = 0 - local TI = GetToolInfoForMachining( sMilling) - if TI then - dTDiam = TI.dDiam or dTDiam - dTMaxDepth = TI.dMaxDepth or dTMaxDepth - end - - local sMillingDn = ML.FindMilling( 'SmallToolContour', nil, nil, nil, nil, not ( bMillDown and bDoubleSide), bMillDown and bDoubleSide) - if not sMillingDn then - local sMyWarn = 'Warning : Opposite SmallToolContour not found in library' - EgtOutLog( sMyWarn) - return true, sMyWarn - end - -- recupero i dati dell'utensile testa da sotto - local dTDiamDn = 50 - local dTMaxDepthDn = 0 - local TI = GetToolInfoForMachining( sMillingDn) - if TI then - dTDiamDn = TI.dDiam or dTDiamDn - dTMaxDepthDn = TI.dMaxDepth or dTMaxDepthDn - end - - -- se il diametro trovato non è minore dei 3/4 del diametro utilizzato in precedenza, esco - if dTDiam > ( 0.75 * dDiam) then - local sMyWarn = 'Warning : tool diameter not enough small' - EgtOutLog( sMyWarn) - return true, sMyWarn - end - - local vtN1 - local nFirstId, nNumId - local dMaxElev - local dCollSic = 0 - local dExtraDepth = 0 - - -- se non ho la faccia aggiunta - if not nPathInt then - -- cerco gli angoli dove applicare il percorso con fresa piú piccola e i lati in comune - local tFacAdjMain = ChooseContour( Proc, nFacInd, true) - -- se non trovato nessun angolo interno da pulire esco - if #tFacAdjMain == 0 then - return true - end - -- normale alla faccia di fondo - vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) - -- se fresatura da sotto salto la lavorazione - if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then - local sErr = 'Error : milling from bottom' - EgtOutLog( sErr) - return false, sErr - end - -- distanza di sicurezza per evitare collisioni - dCollSic = CalcCollisionSafety( vtN1) - -- elevazione massima della faccia - dMaxElev = BL.GetFaceElevation( Proc.Id, nFacInd, _nPartId) - -- ciclo tutta la tabella - local tPaths = {} - local ptIniPath - local ptMidDist - local dMaxLen = 0 - for i = 1, #tFacAdjMain do - -- le 2 facce di contatto devono essere perpendicolari o non sottosquadra rispetto alla faccia di fondo - local ptP1, ptP2, dAng - ptP1 = tFacAdjMain[i][3] - ptP2 = tFacAdjMain[i][4] - dAng = tFacAdjMain[i][5] - if ( dAng < 0 and dAng >= -90 - 10 * GEO.EPS_SMALL) then - -- creo la linea da P1 a P2 - local nAuxId = EgtLine( _nAddGrpId, ptP1, ptP2, GDB_RT.GLOB) - table.insert( tPaths, nAuxId) - -- prendo la lunghezza massima e il punto medio - if tFacAdjMain[i][2] > dMaxLen then - ptIniPath = ptP1 - dMaxLen = tFacAdjMain[i][2] - ptMidDist = ( ptP1 + ptP2) / 2 - end - end - end - -- costruisco il/i percorso/i - nFirstId, nNumId = EgtCurveCompoByReorder( _nAddGrpId, tPaths, ptIniPath, true, GDB_RT.GLOB) - if nFirstId then - -- se un solo percorso e chiuso cambio il punto di inizio nell'entitá piú lunga - if nNumId == 1 and EgtCurveIsClosed( nFirstId) then - EgtChangeClosedCurveStartPoint( nFirstId, ptMidDist, GDB_RT.GLOB) - end - -- modifico versore direzione - for i = 1, nNumId do - EgtModifyCurveExtrusion( nFirstId + i - 1, vtN1, GDB_RT.GLOB) - end - end - -- alrimenti ho la faccia aggiunta - else - -- assegno il percorso - nFirstId = EgtCopyGlob( nPathInt, _nAddGrpId) - nNumId = 1 - -- distanza di sicurezza per evitare collisioni - dCollSic = CalcCollisionSafety( vtOrtho) - -- calcolo elevazione dalla faccia trasversale aggiunta - local dSurfIntElev = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) - if bDoubleSide then - dMaxElev = dSurfIntElev - else - dMaxElev = dDepth - -- se la precedente svuotatura è stata fatta completamente in una sola volta - -- valuto di nuovo se devo fare due passate o una sola - if bOneShot then - -- se non è possibile svuotare completamente da una sola parte - if dTMaxDepth <= ( dMaxElev + BD.CUT_EXTRA + dCollSic) then - bDoubleSide = true - dMaxElev = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) - else - dExtraDepth = dMaxElev - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) - end - -- altrimenti non è stata fatta completamente calcolo la distanza tra faccia aggiunta e profondità superficie - else - dExtraDepth = dMaxElev - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) - end - end - -- normale alla faccia aggiunta - vtN1 = Vector3d( vtOrtho) - -- imposto i lati aperti - SetOpenSide( nFirstId, vtOrtho, 2) - end - - -- se non trovato il percorso, esco - if not nFirstId then - local sMyWarn = 'Warning : impossible make clean corner path' - EgtOutLog( sMyWarn) - return true, sMyWarn - end - - -- assegno lavorazioni ad ogni percorso - local sMyWarn = '' - local bOk - for i = 1, nNumId do - local nIdPath = nFirstId + i - 1 - local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - local bInvertMach - if nPathInt then - -- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale) - if vtN1:getZ() < BD.NZ_MINA and abs(vtN1:getZ()) >= 0.707 then - bInvertMach = true - -- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti - elseif not bDoubleSide and vtN1:getY() > GEO.EPS_SMALL then - bInvertMach = true - end - end - local dMachDepth = 0 - if ( dMaxElev + dCollSic) > dTMaxDepth then - dMachDepth = dTMaxDepth - ( dMaxElev + dCollSic) - end - bOk, sMyWarn = DoClean( sName, sMilling, nIdPath, vtN1, dMaxElev, dMachDepth, dExtraDepth, 0.75 * dTDiam, 0.5 * dTDiam, true, bInvertMach, bInvertMach, true, true, true) - -- se devo applicare la contornatura anche sul lato opposto - if bOk and bDoubleSide then - if bMillDown then - sMilling = sMillingDn - dTDiam = dTDiamDn - dTMaxDepth = dTMaxDepthDn - end - sName = 'CleanOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - bOk, sMyWarn = DoClean( sName, sMilling, nIdPath, vtN1, dMaxElev, dMachDepth, 0, 0.75 * dTDiam, 0, true, true, true, true, false, false) - end - end - if #sMyWarn > 0 then - EgtOutLog( sMyWarn) - end - - return true, sMyWarn -end - ---------------------------------------------------------------------- -local function MakeRoundCleanCornerOrContour( Proc, nFacInd, dDiam, bMillDown, bDoubleSide, - vtOrtho, nPathInt, nSurfInt, dDepth, bOneShot) - local nFunction = Q_CONTOUR_SMALL_TOOL - -- se modalitá pulitura spigoli e lavorazione di lato forzo a fare il contorno - if nFunction == 2 and nPathInt then - nFunction = 1 - end - -- se richiesta pulitura del contorno - if nFunction == 1 then - return MakeRoundCleanContour( Proc, nFacInd, dDiam, bMillDown, bDoubleSide, - vtOrtho, nPathInt, nSurfInt, dDepth, bOneShot) - -- se richiesta pulitura dei soli corner - elseif nFunction == 2 then - return MakeRoundCleanCorner( Proc, nFacInd, dDiam, bMillDown, bDoubleSide) - -- altri casi non previsti - else - return true - end -end - ---------------------------------------------------------------------- -local function MakeSharpCleanCorner( Proc, nFacInd, dDiam) - local sMyWarn = '' - local pAuxId = {} - local nAuxId - local AuxId - local ptApPoint - local dLenTrimExt - local sMilling - local dMaxDepth = 0 - - -- cerco l'angolo di riferimento dove applicare il percorso di pulitura, altrimenti esco - local _, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) - if #tFacAdj == 0 then - return true - end - -- prendo i versori - local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) - local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT) - local vtN3 = EgtSurfTmFacetNormVersor( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT) - -- trovo il punto sulla superfice di riferimento - local _, ptLocP1, ptLocP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT) - local nIdIniPoint, nIdEndPoint = GetIdIniEndPoints( ptLocP1, ptLocP2, tFacAdj[nIdLine]) - -- versore direzione - local vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint] - vtExtr:normalize() - -- inserisco le prime tre linee - if nIdIniPoint and nIdEndPoint then - -- se fresatura da sotto salto la lavorazione - if vtExtr:getZ() < BD.DRILL_VZ_MIN then - local sErr = 'Error : clean corner milling from bottom impossible' - EgtOutLog( sErr) - return false, sErr - end - -- sommo i tre versori per avre una direzione media - vtExtr = vtN1 + vtN2 + vtN3 - vtExtr:normalize() - -- recupero la lavorazione non calcolando l'elevazione - sMilling = ML.FindMilling( 'CleanCorner', ( 0.5 * dDiam)) - if not sMilling then - local sErr = 'Error : CleanCorner not found in library' - EgtOutLog( sErr) - return false, sErr - end - -- recupero i dati dell'utensile (temporaneo, per compensare errore nella lavorazione) - local TI = GetToolInfoForMachining( sMilling) - if TI then - dMaxDepth = TI.dMaxMat or dMaxDepth - end - -- l'altezza di taglio del tagliente corrisponde al raggio del raccordo che si riesce a coprire - -- quindi confronto l'elevazione con il raggio utensile utilizzato per la svuotatura - if dMaxDepth < ( dDiam * 0.5) - 100 * GEO.EPS_SMALL then - sMyWarn = 'Warning : skip clean corner (the cut heigth is too small to machine the corner radius)' - EgtOutLog( sMyWarn) - return false, sMyWarn - end - nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdIniPoint], tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) - table.insert( pAuxId, nAuxId) - -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro - if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then - ptApPoint = ptLocP2 - else - ptApPoint = ptLocP1 - end - nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB) - dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - ( ( dDiam / 2) + 2) - -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta - if dLenTrimExt > 10 * GEO.EPS_SMALL then - EgtTrimExtendCurveByLen( nAuxId, -dLenTrimExt, ptApPoint, GDB_RT.GLOB) - -- prendo il nuovo punto finale - ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) - end - table.insert( pAuxId, nAuxId) - -- creo linea di ritorno - nAuxId = EgtLine( _nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) - table.insert( pAuxId, nAuxId) - end - -- inserisco le ultime tre linee + uscita discostata rispetto all'ingresso - -- trovo il secondo punto sulla superfice di riferimento - _, ptLocP1, ptLocP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][2], GDB_ID.ROOT) - if ptLocP1 and ptLocP2 then - -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro - if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then - ptApPoint = ptLocP2 - else - ptApPoint = ptLocP1 - end - nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB) - dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - ( ( dDiam / 2) + 2) - -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta - if dLenTrimExt > 10 * GEO.EPS_SMALL then - EgtTrimExtendCurveByLen( nAuxId, -dLenTrimExt, ptApPoint, GDB_RT.GLOB) - -- prendo il nuovo punto finale - ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) - end - table.insert( pAuxId, nAuxId) - -- creo linea di ritorno - nAuxId = EgtLine( _nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) - table.insert( pAuxId, nAuxId) - -- piccolo scostamento di 2mm dall'angolo - nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), GDB_RT.GLOB) - table.insert( pAuxId, nAuxId) - -- ultima linea di risalita - nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), tFacAdj[nIdLine][nIdIniPoint] + ( 2 * vtExtr), GDB_RT.GLOB) - table.insert( pAuxId, nAuxId) - end - -- trasformo in percorso - if #pAuxId > 0 then - AuxId = EgtCurveCompo( _nAddGrpId, pAuxId, true) - end - -- se non c'é il percorso do errore - if not AuxId then - local sErr = 'Error : impossible make clean corner path' - EgtOutLog( sErr) - return false, sErr - end - -- modifico versore direzione - EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) - -- inserisco la lavorazione - local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - local bOk - bOk, sMyWarn = DoClean( sName, sMilling, AuxId, vtN1, dMaxDepth, 0, 0, 10, 0, false, false, true, false, false, false) - if not bOk then - return false, sMyWarn - end - return true, sMyWarn -end - ---------------------------------------------------------------------- -local function MakeDrillOnCorner( Proc, nFacInd, dDiam, bSpecialMach) - local sMyWarn = '' - -- ottengo l'angolo dove applicare il foro - local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) - -- se non trovato nessun angolo interno valido esco - if #tFacAdj == 0 then - return true, sMyWarn - end - -- trovo il punto sulla superfice di riferimento - local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT) - local nIdIniPoint, nIdEndPoint = GetIdIniEndPoints(ptLocP1, ptLocP2, tFacAdj[nIdLine]) - -- inserisco foro - if nIdIniPoint and nIdEndPoint then - local vtExtr - if bSpecialMach then - local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) - local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT) - local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT) - vtExtr = vtN0 + vtN1 + vtN2 - else - -- versore direzione - vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint] - end - vtExtr:normalize() - -- se foratura da sotto salto la lavorazione - if vtExtr:getZ() < BD.DRILL_VZ_MIN then - local sErr = 'Error : drilling from bottom impossible' - EgtOutLog( sErr) - return false, sErr - end - -- recupero la lavorazione - local sDrilling, nType = ML.FindDrilling( dDiam) - if not sDrilling then - local sErr = 'Error : drilling not found in library' - EgtOutLog( sErr) - return false, sErr - end - -- recupero i dati dell'utensile - local dMaxDepth = 20 - local dDiamTool = 20 - local dDiamTh = 35 - local bIsDrilling - local TI = GetToolInfoForMachining( sDrilling) - if TI then - bIsDrilling = ( EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) == MCH_MY.DRILLING) - if bIsDrilling then - dMaxDepth = TI.dMaxMat or dMaxDepth - else - dMaxDepth = TI.dMaxDepth or dMaxDepth - end - dDiamTool = TI.dDiam or dDiamTool - dDiamTh = TI.dThDiam or dDiamTh - end - -- se foro inclinato, limito il massimo affondamento - local CosB = abs( vtExtr:getX()) - if CosB < BD.DRILL_VX_MAX then - local TgA = CosB / sqrt( 1 - CosB * CosB) - dMaxDepth = dMaxDepth - dDiamTh / 2 * TgA - else - dMaxDepth = 0 - end - -- setto griglia - if bSpecialMach then - EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdEndPoint], vtExtr)) - else - EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdIniPoint], vtExtr)) - end - -- creo geometria - local AuxId = EgtCircle( _nAddGrpId, {0, 0, 0}, EgtIf( bIsDrilling, dDiamTool / 2, ( dDiamTool / 2) + 0.1), GDB_RT.GRID) - -- riporto la griglia a globale - EgtSetGridFrame() - -- calcolo spessore - local dDepthBore = dMaxLen - if bSpecialMach then - -- calcolo l'elevazione - local dLenIn, dLedOut = BL.GetPointDirDepth( _nPartId, tFacAdj[nIdLine][nIdEndPoint], vtExtr) - if dLenIn > 0 then - dDepthBore = dLenIn - elseif dLedOut then - dDepthBore = dLedOut - end - EgtModifyCurveThickness( AuxId, dDepthBore) - else - EgtModifyCurveThickness( AuxId, -dMaxLen) - end - -- inserisco la lavorazione - local sName = 'Drill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - local nMchId = EgtAddMachining( sName, sDrilling) - if not nMchId then - local sErr = 'Error adding machining ' .. sName .. '-' .. sDrilling - EgtOutLog( sErr) - return false, sErr - end - -- aggiungo geometria - EgtSetMachiningGeometry( {{ AuxId, -1}}) - -- imposto posizione braccio porta testa - local nSCC = MCH_SCC.ADIR_YM - if vtExtr:getY() > 100 * GEO.EPS_ZERO then - nSCC = MCH_SCC.ADIR_YP - end - EgtSetMachiningParam( MCH_MP.SCC, nSCC) - -- aggiusto l'affondamento - local dDepth - if bSpecialMach then - dDepth = dDepthBore - else - dDepth = dMaxLen - if dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then - sMyWarn = 'Warning in drill : depth (' .. EgtNumToString( dDepth, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' - dDepth = dMaxDepth - EgtOutLog( sMyWarn) - end - end - EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) - -- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione (coincide con affondamento) - local sUserNotes = 'VMRS=0;MaxElev=' .. EgtNumToString( dDepth, 1) .. ';' - EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchId, false) - return false, sErr - else - local _, sWarn = EgtGetMachMgrWarning( 0) - if EgtIsMachiningEmpty() then - EgtSetOperationMode( nMchId, false) - return false, sWarn - else - return true, ( sMyWarn or sWarn) - end - end - end - - return true, sMyWarn -end - ---------------------------------------------------------------------- -local function ErasePathIfNecessary( nPathId, sDeleteByDir, dDiff) - local ptP1 = EgtSP( nPathId, GDB_RT.GLOB) - local ptP2 = EgtEP( nPathId, GDB_RT.GLOB) - if abs( EgtIf( sDeleteByDir == 'X', ( ptP1:getX() - ptP2:getX()), EgtIf( sDeleteByDir == 'Y', ( ptP1:getY() - ptP2:getY()), ( ptP1:getZ() - ptP2:getZ())))) > dDiff then - EgtErase( nPathId) - end -end - ---------------------------------------------------------------------- -local function TestPaths( sDeleteByDir, nStartId, nNumIds, dDiff) - local tPaths = {} - local dMaxVal, dMinVal - for i = 1, nNumIds do - local bInsTab - local nIdx = nStartId + i - 1 - local ptP1 = EgtSP( nIdx, GDB_RT.GLOB) - if ptP1 then - for j = 1, #tPaths do - local dLocalVal = tPaths[j][2] - if abs( EgtIf( sDeleteByDir == 'X', ptP1:getX() - dLocalVal, EgtIf( sDeleteByDir == 'Y', ptP1:getY() - dLocalVal, ptP1:getZ() - dLocalVal))) < dDiff then - local tLocIds = tPaths[j][1] - table.insert( tLocIds, ( nIdx)) - tPaths[j][1] = tLocIds - bInsTab = true - end - end - -- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella - if not bInsTab then - table.insert( tPaths, {{ nIdx}, ptP1:getX()}) - dMaxVal = EgtIf( sDeleteByDir == 'X', _b3Solid:getMax():getX(), EgtIf( sDeleteByDir == 'Y', _b3Solid:getMax():getY(), _b3Solid:getMax():getZ())) - dMinVal = EgtIf( sDeleteByDir == 'X', _b3Solid:getMin():getX(), EgtIf( sDeleteByDir == 'Y', _b3Solid:getMin():getY(), _b3Solid:getMin():getZ())) - end - end - end - - return tPaths, dMaxVal, dMinVal -end - ---------------------------------------------------------------------- -local function ModifyPathExtrusion(tPath, sDeleteByDir, dMaxVal, dDiff) - local ptP1 = EgtSP( tPath, GDB_RT.GLOB) - if abs( EgtIf( sDeleteByDir == 'X', ptP1:getX(), EgtIf( sDeleteByDir == 'Y', ptP1:getY(), ptP1:getZ())) - dMaxVal) < dDiff then - EgtModifyCurveExtrusion( tPath, EgtIf( sDeleteByDir == 'X', X_AX(), EgtIf( sDeleteByDir == 'Y', Y_AX(), Z_AX())), GDB_RT.GLOB) - else - EgtModifyCurveExtrusion( tPath, EgtIf( sDeleteByDir == 'X', -X_AX(), EgtIf( sDeleteByDir == 'Y', -Y_AX(), -Z_AX())), GDB_RT.GLOB) - end -end - ---------------------------------------------------------------------- -local function ExtractExternalPaths( nPathInt, nNumIdAux, vtOrtho) - if nNumIdAux == 1 then - -- fondo tra loro le curve compatibili - EgtMergeCurvesInCurveCompo( nPathInt) - -- esplodo il percorso in modo da avere entià separate per poterle controllare - local nStartId, nNumIds = EgtExplodeCurveCompo( nPathInt) - if nStartId then - local sDeleteByDir - -- Se normale lungo la Z elimino le entità che hanno differenza in Z - if abs(vtOrtho:getZ()) > 0.7 then - sDeleteByDir = 'Z' - -- altrimenti se normale lungo la Y elimino le entità che hanno variazione in Y --- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getY()) > 0.7 then - elseif abs(vtOrtho:getY()) > 0.7 then - sDeleteByDir = 'Y' - -- caso che non dovrebbe mai capitare ma gestito per completezza - -- altrimenti se normale lungo la X elimino le entità che hanno variazione in X --- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getX()) > 0.7 then - elseif abs(vtOrtho:getX()) > 0.7 then - sDeleteByDir = 'X' - end - if sDeleteByDir then - for i = 1, nNumIds do - ErasePathIfNecessary( nStartId + i - 1, sDeleteByDir, 10 * GEO.EPS_SMALL) - end - -- ricreo i vari percorsi - local tPaths, dMaxVal, dMinVal = TestPaths( sDeleteByDir, nStartId, nNumIds, 10 * GEO.EPS_SMALL) - - if tPaths then - local tChamPath = {} - -- elimino quelle che non corrispondono agli estremi - for i = 1, #tPaths do - -- se non corrisponde ai limiti elimino l'elemento - if abs( tPaths[i][2] - dMaxVal) > 10 * GEO.EPS_SMALL and abs( tPaths[i][2] - dMinVal) > 10 * GEO.EPS_SMALL then - tPaths[i] = nil - else - local tNoMatch = {} - local tPathLoc = tPaths[i][1] - local pIniLoc = EgtSP( tPathLoc[1], GDB_RT.GLOB) - local pEndLoc = EgtEP( tPathLoc[1], GDB_RT.GLOB) - -- ciclo sui percorsi per trovare i punti non coincidenti (se percorso non chiuso) - for j = 2, #tPathLoc do - -- prendo i punti del percorso successivo - local pAddIni = EgtSP( tPathLoc[j], GDB_RT.GLOB) - local pAddEnd = EgtEP( tPathLoc[j], GDB_RT.GLOB) - -- se consecutivi - if AreSamePointApprox( pEndLoc, pAddIni) then - pEndLoc = pAddEnd - elseif AreSamePointApprox( pIniLoc, pAddEnd) then - pIniLoc = pAddIni - else - table.insert( tNoMatch, tPathLoc[j]) - end - end - -- controllo eventuali percorsi scartati - for j = 1, #tNoMatch do - -- prendo i punti del percorso successivo - local pAddIni = EgtSP( tNoMatch[j], GDB_RT.GLOB) - local pAddEnd = EgtEP( tNoMatch[j], GDB_RT.GLOB) - -- se consecutivi - if AreSamePointApprox( pEndLoc, pAddIni) then - pEndLoc = pAddEnd - elseif AreSamePointApprox( pIniLoc, pAddEnd) then - pIniLoc = pAddIni - end - end - -- creo concatenamento partendo dal punto iniziale - local nIdLoc = EgtCurveCompoByReorder( _nAddGrpId, tPathLoc, pIniLoc, true) - if nIdLoc then - table.insert( tChamPath, nIdLoc) - end - end - end - for i = 1, #tChamPath do - -- modifico estrusione percorso - ModifyPathExtrusion( tChamPath[i], sDeleteByDir, dMaxVal, 10 * GEO.EPS_SMALL) - end - if #tChamPath == 1 then - return tChamPath[1], 1, nil - elseif #tChamPath == 2 then - return tChamPath[1], 2, tChamPath[2] - else - for i = 1, nNumIds do - EgtErase( nStartId + i - 1) - end - for i = 1, #tChamPath do - EgtErase( tChamPath[i]) - end - end - else - for i = 1, nNumIds do - EgtErase( nStartId + i - 1) - end - end - -- altrimenti cancello tutte le emtità e restituisco nil - else - for i = 1, nNumIds do - EgtErase( nStartId + i - 1) - end - end - end - end - - return nil, 0, nil -end - ---------------------------------------------------------------------- -local function MakeChamfer( Proc, vtOrtho, nSurfInt) - -- Se variabile globale indica che lo smusso è già stato fatto, esco - if _bMadeChamfer then - return 0 - end - _bMadeChamfer = true - local bIs3Faces = Proc.Fct == 3 - -- recupero la lavorazione - local sMilling = ML.FindMilling( 'Mark') - if not sMilling then - local sErr = 'Error : Mark not found in library' - EgtOutLog( sErr) - return -1, sErr - end - -- ottengo le curve di contorno libero - local nAuxId1, nAuxId2, nNumIdAux - if bIs3Faces then --- nAuxId1, _ = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) --- EgtModifyCurveExtrusion( nAuxId1, vtOrtho, GDB_RT.GLOB) --- SetOpenSide( nAuxId1, vtOrtho, b3Solid, nAddGrpId, 1) --- nNumIdAux = 2 - - -- estraggo i percorsi - nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, _nAddGrpId) - -- se percorso creato estraggo solo i percorsi delle facce interessate, non di testa - if nAuxId1 then - nAuxId1, nNumIdAux, nAuxId2 = ExtractExternalPaths( nAuxId1, nNumIdAux, vtOrtho) - end - else - nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, _nAddGrpId) - if not nNumIdAux then nNumIdAux = 0 end - end - - local dExtra = 2 - for i = 1, nNumIdAux do - local AuxId - local vtExtr - if bIs3Faces then - if i == 1 then - AuxId = nAuxId1 - else - -- faccio la copia del percorso --- AuxId = EgtCopyGlob( nAuxId1, nAddGrpId) - AuxId = nAuxId2 - end - if AuxId then - vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) - end - else - AuxId = nAuxId1 + i - 1 - vtExtr, _, _ = EgtCurveArea( AuxId) - end - if vtExtr then - if not bIs3Faces then - local fFrCurve = EgtGetGlobFrame( AuxId) - vtExtr:toGlob( fFrCurve) - end --- if bIs3Faces and i == nNumIdAux then --- vtExtr = -vtExtr --- end - -- Se normale entro certi limiti --- if vtExtr:getZ() > -0.707 and ( abs(vtOrtho:getX()) > 0.99 or abs(vtOrtho:getY()) > 0.99 or abs(vtOrtho:getZ()) > 0.99) then - if vtExtr:getZ() > -0.707 and ( abs(vtExtr:getX()) > 0.99 or abs(vtExtr:getY()) > 0.99 or abs(vtExtr:getZ()) > 0.99) then - -- inserisco la lavorazione - local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) - local nMchId = EgtAddMachining( sNameCh, sMilling) - if not nMchId then - local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sMilling - EgtOutLog( sErr) - return -1, sErr - end - -- modifico estrusione percorso - EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) - -- aggiungo geometria - EgtSetMachiningGeometry( {{ AuxId, -1}}) - -- imposto posizione braccio porta testa - if vtExtr:getY() < GEO.EPS_SMALL then - EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) - else - EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) - end - EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) - -- assegno affondamento e offset radiale --- EgtSetMachiningParam( MCH_MP.DEPTH, _dDepthCham + dExtra - EgtIf( bIs3Faces, (dDepth / 2), 0)) - EgtSetMachiningParam( MCH_MP.DEPTH, _dDepthCham + dExtra) - EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) - -- se opero su 3 facce e sono al secondo e ultimo percorso inverto la lavorazione --- if bIs3Faces and i == nNumIdAux then --- EgtSetMachiningParam( MCH_MP.INVERT, true) --- end - -- eseguo - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchId, false) - return -1, sErr - end - -- se non perpendicolare emetto un warning - -- else - -- sWarn = 'Warning : chamfer skipped because not perpendicular to face or from bottom' - -- EgtOutLog( sWarn) - end - --emetto un warning - -- else - -- sWarn = 'Warning : chamfer skipped because not perpendicular to face' - -- EgtOutLog( sWarn) - end - end - - return 0 -end - ---------------------------------------------------------------------- -local function MakeByMillAsSaw( Proc, tFData, nBottomFace, sMillingOnSide, dSawDiam, dSawThick) - local sWarn - -- ottengo la distanza tra la fine del pezzo e il pezzo successivo - local dDistToNextPiece = EgtGetInfo( _nRawId, 'BDST', 'd') or 5. - -- Recupero le facce adiacenti alla principale (solo quelle esistenti) - local vAdj = GetValidFacetAdjacencies( Proc.Id, tFData.nFacInd) - if not vAdj or #vAdj == 0 then - local sErr = 'Error : main face without adjacencies' - EgtOutLog( sErr) - return false, sErr - end - EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) - -- Cerco una faccia adiacente alla principale sul lato più lungo - local nFacAdj - local dMaxLen = 0 - for i = 1, #vAdj do - local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, tFData.nFacInd, vAdj[i], GDB_ID.ROOT) - local dLen = dist( ptP1, ptP2) - if dLen > dMaxLen then - nFacAdj = vAdj[i] - dMaxLen = dLen - EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, tFData.dH, tFData.dV), 3) - end - end - if not nFacAdj then - local sErr = 'Error : long adjacent face not found' - EgtOutLog( sErr) - return false, sErr - end - -- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare - local _, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacAdj, GDB_ID.ROOT) - if abs( vtN * tFData.rfFac:getVersX()) > abs( vtN * tFData.rfFac:getVersY()) then - tFData.dH, tFData.dV = tFData.dV, tFData.dH - end - -- Determino se estremi aperti o chiusi - local bOpenStart = false - local bOpenEnd = false - -- se non ho la faccia di fondo (che comporta essere una fessura) verifico se ho lati aperti - if not nBottomFace then - local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] - EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) - for j = 1, #vAdj2 do - if vAdj2[j] == tFData.nFacInd then - -- Se non esiste faccia adiacente a lato precedente -> inizio aperto - local i = EgtIf( j > 1, j - 1, #vAdj2) - while vAdj2[i] == tFData.nFacInd do - i = EgtIf( i > 1, i - 1, #vAdj2) - end - bOpenStart = ( vAdj2[i] < 0) - -- Se non esiste faccia adiacente a lato successivo -> fine aperto - local k = EgtIf( j < #vAdj2, j + 1, 1) - while vAdj2[k] == tFData.nFacInd do - k = EgtIf( k < #vAdj2, k + 1, 1) - end - bOpenEnd = ( vAdj2[k] < 0) - end - end - end - -- Se possibile, lavoro con la lama - if _bForceUseBlade then - -- Recupero la lavorazione di lama - local sCutting = sMillingOnSide - -- Calcolo uso faccia - local nFaceUse = BL.GetNearestOrthoOpposite( tFData.rfFac:getVersZ()) - local dStartDist = -1 - local dEndDist = -1 - -- calcolo eventuali arretramenti lama - if not bOpenStart then - local dRadius = dSawDiam / 2 - local dCat1 = dRadius - tFData.dFacElev - dStartDist = sqrt( ( dRadius * dRadius) - ( dCat1 * dCat1)) - end - if not bOpenEnd then - if not bOpenStart then - dEndDist = dStartDist - else - local dRadius = dSawDiam / 2 - local dCat1 = dRadius - tFData.dFacElev - dEndDist = sqrt( ( dRadius * dRadius) - ( dCat1 * dCat1)) - end - end - -- Eseguo i tagli - local nStep = ceil( ( tFData.dV - 10 * GEO.EPS_SMALL) / dSawThick) - local dStep = 0 - if nStep > 1 then - dStep = ( tFData.dV - dSawThick) / ( nStep - 1) - end - for i = 1, nStep do - local dOffs = ( i - 1) * dStep - --if vtN:getZ() < BD.NZ_MINA then dOffs = dOffs + dSawThick end - local bOk, sErr, nMchId = Fbs.MakeOne( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, dStartDist, dEndDist, nil, _b3Raw) - if not bOk then return bOk, sErr end - -- setto l'elevazione - local sNotes = 'MaxElev=' .. EgtNumToString( 0, 1) .. ';' - -- applico elevazione - EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) - -- tolgo eventuale step - EgtSetMachiningParam( MCH_MP.STEP, 0) - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchId, false) - return false, sErr - end - end - -- in base all'elevazione calcolo l'impronta della lama - local dUsedBladeLen = sqrt( ( ( dSawDiam / 2) * ( dSawDiam / 2)) - ( ( ( dSawDiam / 2) - tFData.dFacElev) * ( ( dSawDiam / 2) - tFData.dFacElev))) - -- controllo direzione taglio e se il minimo della feature sborda in coda - if abs( vtN:getX()) < GEO.EPS_SMALL and abs( _b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then - -- do avviso che la lama può sbordare nel pezzo successivo - sWarn = 'Warning on mill side as blade : Cut machining can damage next piece' - EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') - end - end - return true, sWarn -end - ---------------------------------------------------------------------- -local function DoHeadChainSaw( Proc, sName, sSawing, tFData, nFaceUse, nFacAdj, vtN, vtNE, vtNS, dSawWidth, - dOffs, dDistToNextPiece, dMaxDepth, bOpenStart, bOpenEnd) - local nMchFId = EgtAddMachining( sName, sSawing) - if not nMchFId then - local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing - EgtOutLog( sErr) - return false, sErr - end - -- aggiungo geometria - EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) - -- imposto uso faccia - EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) - -- controllo direzione taglio e se il minimo della feature sborda in coda - if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( _b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL then - -- se ho lato partenza aperto e lato uscita chiuso e direzione lato chiuso è negativa, allora controllo uscita lama - if bOpenStart and not bOpenEnd and vtNE:getX() < -0.99 and dDistToNextPiece < ( dSawWidth / 2) then - -- imposto accorciamento iniziale per estremi aperti/chiusi - EgtSetMachiningParam( MCH_MP.STARTADDLEN, dDistToNextPiece - 1 - ( dSawWidth / 2)) - else - -- imposto accorciamento iniziale per estremi aperti/chiusi - EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) - end - -- se ho lato uscita aperto e lato partenza chiuso e direzione lato partenza è negativa, allora controllo uscita lama - if bOpenEnd and not bOpenStart and vtNS:getX() < -0.99 and dDistToNextPiece < ( dSawWidth / 2) then - -- imposto accorciamento finale per estremi aperti/chiusi - EgtSetMachiningParam( MCH_MP.ENDADDLEN, dDistToNextPiece - 1 - ( dSawWidth / 2)) - else - -- imposto accorciamento finale per estremi aperti/chiusi - EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) - end - else - -- imposto accorciamento iniziale/finale per estremi aperti/chiusi - EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) - end - -- imposto angolo 3° asse rot e eventuale angolo suggerito per inizio - EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 1)) - EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, tFData.rfFac:getVersZ())) - -- imposto offset radiale - EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) - -- se necessario, limito l'affondamento - if tFData.dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then - local sWarn = 'Warning in LapJoint : elevation (' .. EgtNumToString( tFData.dFacElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' - local dDepth = dMaxDepth - tFData.dFacElev - EgtOutLog( sWarn) - EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH ' .. EgtNumToString( dDepth, 1)) - end - -- imposto elevazione - local sNotes = 'MaxElev=' .. EgtNumToString( tFData.dFacElev, 2) .. ';' - EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) - -- eseguo - if not ML.ApplyMachining( true, false) then - if EgtGetOutstrokeInfo() then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - -- impostazione alternativa angolo 3° asse rot - EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 2)) - EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, tFData.rfFac:getVersZ())) - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - end - if EgtIsMachiningEmpty() then - local _, sWarn = EgtGetMachMgrWarning( 0) - EgtSetOperationMode( nMchFId, false) - return false, sWarn - end - return true -end - ---------------------------------------------------------------------- -local function DoSideChainSaw( Proc, sName, sSawing, tFData, vtN, vtOrtho, nLongFaceId, - dOffs, dMaxMat, dSawCornerRad, bOpenStart, bOpenEnd) - local nMchFId = EgtAddMachining( sName, sSawing) - if not nMchFId then - local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing - EgtOutLog( sErr) - return false, sErr - end - -- aggiungo geometria - EgtSetMachiningGeometry( {{ Proc.Id, nLongFaceId}}) - -- imposto uso del lato faccia - local nFaceUse - -- se non è un tunnel a 4 facce - if Proc.Fct < 4 then - nFaceUse = BL.GetNearestParalOpposite( tFData.rfFac:getVersZ(), vtN) - -- altrimenti vero tunnel (solo sopra-sotto o davanti-dietro) - else - if abs( vtOrtho:getZ()) >= 0.707 then - nFaceUse = MCH_MILL_FU.PARAL_DOWN - else - nFaceUse = MCH_MILL_FU.PARAL_BACK - end - end - EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) - -- imposto angolo 3° asse rot - EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 1)) - EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho)) - -- imposto offset radiale - EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) - -- se non è un tunnel a 4 facce - if Proc.Fct < 4 then - -- imposto sempre massimo affondamento - local dBoxDepth - if nFaceUse == MCH_MILL_FU.PARAL_LEFT or nFaceUse == MCH_MILL_FU.PARAL_RIGHT then - dBoxDepth = Proc.Box:getDimX() - elseif nFaceUse == MCH_MILL_FU.PARAL_FRONT or nFaceUse == MCH_MILL_FU.PARAL_BACK then - dBoxDepth = Proc.Box:getDimY() - else - dBoxDepth = Proc.Box:getDimZ() - end - EgtSetMachiningParam( MCH_MP.DEPTH, dBoxDepth) - if dBoxDepth > dMaxMat then - local sWarn = 'Warning : elevation bigger than max tool depth' - EgtOutLog( sWarn) - end - -- sistemo inizio e fine - if bOpenStart then EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) end - if bOpenEnd then EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) end - -- altrimenti vero tunnel (solo sopra-sotto o davanti-dietro) - else - -- se possibile aumento l'affondamento pari al raggio corner + 1 - if dMaxMat > ( dDepth + dSawCornerRad + 1) then - EgtSetMachiningParam( MCH_MP.DEPTH, ( dDepth + dSawCornerRad + 1)) - -- se massimo affondamento supera altezza fessura, uso massimo affondamento - elseif dMaxMat > ( dDepth + 1) then - EgtSetMachiningParam( MCH_MP.DEPTH, ( dMaxMat - 1)) - -- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning - elseif dMaxMat < dDepth then - EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat) - local sWarn = 'Warning : elevation bigger than max tool depth' - EgtOutLog( sWarn) - end - end - if Q_MAX_ELEVATION and Q_MAX_ELEVATION > 10 then - local sNotes = 'MaxElev=' .. EgtNumToString( Q_MAX_ELEVATION, 1) .. ';' - EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) - end - -- eseguo - if not ML.ApplyMachining( true, false) then - if EgtGetOutstrokeInfo() then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - -- impostazione alternativa angolo 3° asse rot - EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 2)) - EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho)) - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - end - if EgtIsMachiningEmpty() then - local _, sWarn = EgtGetMachMgrWarning( 0) - EgtSetOperationMode( nMchFId, false) - return false, sWarn - end - return true -end - ---------------------------------------------------------------------- -local function MakeByChainOrSaw( Proc, tFData, dDimMin, dDimMax, vtOrtho, nLongFaceId, - bOrthoFacesMaster, nBottomFace, nSurfInt) - local bIs3Faces = Proc.Fct == 3 - local bOrthoFaces - local sWarn - -- ottengo la distanza tra la fine del pezzo e il pezzo successivo - local dDistToNextPiece = EgtGetInfo( _nRawId, 'BDST', 'd') or 5.4 - if bIs3Faces then - -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa - local nFacInd1, dFacElev1, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, _nPartId, bIs3Faces) - if not nFacInd1 or nFacInd1 < 0 then - if nFacInd1 == -1 then - bOrthoFaces = nFacInd2 - else - local sErr = 'Error : MakeByChainOrSaw could not find reference face' - EgtOutLog( sErr) - return false, sErr - end - end - else - bOrthoFaces = bOrthoFacesMaster - end - - if bOrthoFaces then - -- ottengo le dimensioni del tunnel - dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc) - -- verifico la direzione - -- se devo inserire il chamfer - if _nChamfer > 0 then - local nOk, sErr = MakeChamfer( Proc, vtOrtho, nSurfInt) - if nOk < 0 then return false, sErr end - end - end - -- Recupero le facce adiacenti alla principale (solo quelle esistenti) - local vAdj = GetValidFacetAdjacencies( Proc.Id, tFData.nFacInd) - if not vAdj or #vAdj == 0 then - local sErr = 'Error : main face without adjacencies' - EgtOutLog( sErr) - return false, sErr - end - EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) - -- Cerco una faccia adiacente alla principale sul lato più lungo - local nFacAdj - local dMaxLen = 0 - for i = 1, #vAdj do - local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, tFData.nFacInd, vAdj[i], GDB_ID.ROOT) - local dLen = dist( ptP1, ptP2) - if dLen > dMaxLen then - nFacAdj = vAdj[i] - dMaxLen = dLen - EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, tFData.dH, tFData.dV), 3) - end - end - if not nFacAdj then - local sErr = 'Error : long adjacent face not found' - EgtOutLog( sErr) - return false, sErr - end - -- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare - local _, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacAdj, GDB_ID.ROOT) - if abs( vtN * tFData.rfFac:getVersX()) > abs( vtN * tFData.rfFac:getVersY()) then - tFData.dH, tFData.dV = tFData.dV, tFData.dH - end - -- Determino se estremi aperti o chiusi - local bOpenStart = false - local bOpenEnd = false - local vtNS, vtNE - -- se non ho la faccia di fondo (che comporta essere una fessura) verifico se ho lati aperti - if not nBottomFace then - local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] - EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) - for j = 1, #vAdj2 do - if vAdj2[j] == tFData.nFacInd then - -- Se non esiste faccia adiacente a lato precedente -> inizio aperto - local i = EgtIf( j > 1, j - 1, #vAdj2) - while vAdj2[i] == tFData.nFacInd do - i = EgtIf( i > 1, i - 1, #vAdj2) - end - bOpenStart = ( vAdj2[i] < 0) - -- se è chiusa acquisisco vettore faccia tappo - if not bOpenStart and vAdj2[i] >= 0 then - _, vtNS = EgtSurfTmFacetCenter( Proc.Id, vAdj2[i], GDB_ID.ROOT) - end - -- Se non esiste faccia adiacente a lato successivo -> fine aperto - local k = EgtIf( j < #vAdj2, j + 1, 1) - while vAdj2[k] == tFData.nFacInd do - k = EgtIf( k < #vAdj2, k + 1, 1) - end - bOpenEnd = ( vAdj2[k] < 0) - -- se è chiusa acquisisco vettore faccia tappo - if not bOpenEnd and vAdj2[k] >= 0 then - _, vtNE = EgtSurfTmFacetCenter( Proc.Id, vAdj2[k], GDB_ID.ROOT) - end - end - end - end - -- Recupero il massimo affondamento possibile con la lama - local dSawMaxDepth = 0 - local sCutting = ML.FindCutting( 'HeadSide') - if sCutting then - local TI = GetToolInfoForMachining( sCutting) - if TI then - dSawMaxDepth = TI.dMaxDepth or dSawMaxDepth - end - end - -- se lavorazione sulle teste e altezza trave supera il limite (che causa collisione con la forcella) e direzione taglio lungo la Z - -- e limite profondità BeamData è maggiore del taglio massimo lama, assegno il massimo affondamento pari al limite profondità del BeamData - if bOpenStart and bOpenEnd and _bForceUseBlade and ( Proc.Head or Proc.Tail) and abs( tFData.rfFac:getVersY():getY()) > 0.866 and - _b3Solid:getDimZ() > BD.MIN_DIM_HBEAM and dSawMaxDepth > BD.MAX_DIM_HTCUT_HBEAM then - dSawMaxDepth = BD.MAX_DIM_HTCUT_HBEAM - end - -- Se entrambi gli estremi sono aperti e possibile, lavoro con la lama - if bOpenStart and bOpenEnd and _bForceUseBlade and tFData.dFacElev < dSawMaxDepth + 10 * GEO.EPS_SMALL then - -- Recupero la lavorazione di lama - local sCutting = ML.FindCutting( 'HeadSide') - if not sCutting then - local sErr = 'Error : HeadSide (cutting) not found in library' - EgtOutLog( sErr) - return false, sErr, 'MNF' - end - -- recupero i dati dell'utensile - local dSawDiam = 400 - local dSawThick = 4 - local TI = GetToolInfoForMachining( sCutting) - if TI then - dSawDiam = TI.dDiam or dSawDiam - dSawThick = TI.dThick - end - if dSawThick > tFData.dV + 10 * GEO.EPS_SMALL then - local sErr = 'Error : sawblade too thick' - EgtOutLog( sErr) - return false, sErr - end - -- Calcolo uso faccia - local nFaceUse = BL.GetNearestOrthoOpposite( tFData.rfFac:getVersZ()) - -- Eseguo i tagli - local nStep = ceil( ( tFData.dV - 10 * GEO.EPS_SMALL) / dSawThick) - local dStep = 0 - if nStep > 1 then - dStep = ( tFData.dV - dSawThick) / ( nStep - 1) - end - for i = 1, nStep do - local dOffs = ( i - 1) * dStep - local bOk, sErr = Fbs.MakeOne( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, 0, 0, nil, _b3Raw) - if not bOk then return bOk, sErr end - end - -- in base all'elevazione calcolo l'impronta della lama - local dUsedBladeLen = sqrt( ( ( dSawDiam / 2) * ( dSawDiam / 2)) - ( ( ( dSawDiam / 2) - tFData.dFacElev) * ( ( dSawDiam / 2) - tFData.dFacElev))) - -- controllo direzione taglio e se il minimo della feature sborda in coda - if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( _b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then - -- do avviso che la lama può sbordare nel pezzo successivo - sWarn = 'Warning on saw cut : Cut machining can damage next piece' - EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') - end - -- altrimenti con sega a catena - else - -- Recupero la lavorazione - local sSawing = ML.FindSawing( 'Sawing') - if not sSawing then - local sErr = 'Error : Sawing not found in library' - EgtOutLog( sErr) - return false, sErr, 'MNF' - end - -- Recupero i dati dell'utensile - local dSawWidth = 75 - local dSawThick = 8 - local dMaxDepth = 200 - local TI = GetToolInfoForMachining( sSawing) - if TI then - dSawWidth = TI.dDiam or dSawWidth - dSawThick = TI.dThick or dSawThick - dMaxDepth = TI.dMaxDepth or dMaxDepth - end - if dSawThick > tFData.dV + 10 * GEO.EPS_SMALL then - local sErr = 'Error : chainsaw too thick' - EgtOutLog( sErr) - return false, sErr - end - local bGoFromHead = true - -- se la lunghezza utensile non riesce ad arrivare sul fondo assegno la possibilità di lavorare di testa o di fianco - if tFData.dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then - -- lavora di testa se è un tunnel, lavora di fianco se non è un tunnel - bGoFromHead = not bOrthoFaces - end - -- se continuo a lavorare di testa - if bGoFromHead then - -- Calcolo uso faccia - local nFaceUse = BL.GetNearestParalOpposite( tFData.rfFac:getVersZ()) - -- Calcolo normale faccia adiacente - local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT) - -- Verifico se necessarie più passate - local nStep = ceil( ( tFData.dV - 10 * GEO.EPS_SMALL) / dSawThick) - local dStep = 0 - if nStep > 1 then - dStep = ( tFData.dV - dSawThick) / ( nStep - 1) - end - for i = 1, nStep do - -- Applico la lavorazione con sega a catena a questa faccia - local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) - local dOffs = ( i - 1) * dStep - local bOk, sErr = DoHeadChainSaw( Proc, sName, sSawing, tFData, nFaceUse, nFacAdj, vtN, vtNE, vtNS, dSawWidth, dOffs, dDistToNextPiece, dMaxDepth, bOpenStart, bOpenEnd) - if not bOk then - return false, sErr - end - end - -- altrimenti segacatena di fianco - else - -- verifico se posso farlo con la sega-catena - local bMakeChainSaw, sSawing2, dMaxMat2, dSawCornerRad2, dSawThick2 = VerifyChainSaw( dDimMin, dDimMax) - if bMakeChainSaw then - -- Verifico se necessarie più passate - local nStep = ceil( ( dDimMin - 10 * GEO.EPS_SMALL) / dSawThick2) - local dStep = 0 - if nStep > 1 then - dStep = ( dDimMin - dSawThick2) / ( nStep - 1) - end - for i = 1, nStep do - -- inserisco la lavorazione di sawing - local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) - local dOffs = ( i - 1) * dStep - local bOk, sErr = DoSideChainSaw( Proc, sName, sSawing2, tFData, vtN, vtOrtho, nLongFaceId, dOffs, dMaxMat2, dSawCornerRad2, bOpenStart, bOpenEnd) - if not bOk then - return false, sErr - end - end - end - end - end - return true, sWarn -end - ---------------------------------------------------------------------- -local function MakeAntiSplintBySaw( Proc, nFacet, vtN, nFacInd, bReduceDepth, bMillDown) - -- Recupero la lavorazione di lama - local sCutting = ML.FindCutting( 'HeadSide', not bMillDown, bMillDown) - if not sCutting then - local sErr = 'Error : HeadSide (cutting) not found in library' - EgtOutLog( sErr) - return false, sErr - end - -- valuto l'angolo tra le due facce - local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacet, GDB_ID.ROOT) - local ptPm = (ptP1 + ptP2) / 2 - -- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta l'elevazione della faccia - -- laterale sul punto medio della linea in comune - local frFc = Frame3d( ptPm, vtN) - local b3BoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc) - local dDepth = b3BoxLoc:getDimZ() or 0 - -- recupero i dati dell'utensile - local dSawDiam = 400 - local dSawThick = 0 - local dMaxDepth = 0 - local TI = GetToolInfoForMachining( sCutting) - if TI then - dSawDiam = TI.dDiam or dSawDiam - dSawThick = TI.dThick or dSawThick - dMaxDepth = TI.dMaxDepth or dMaxDepth - end - local dExtraOffs = 0 - -- se profondità superiore al massimo lama modifico elevazione - if dDepth > dMaxDepth then - dExtraOffs = dMaxDepth - dDepth - end - -- se devo ridurre l'affondamento - if bReduceDepth then - local dLimitDepth = 100 - -- se ho ridotto l'affondamento ne riduco ulteriormente l'affondamento (50mm) - if abs( dExtraOffs) > 0 then - if dMaxDepth > dLimitDepth then - dExtraOffs = dLimitDepth - dDepth - end - else - if dDepth > dLimitDepth then - dExtraOffs = dLimitDepth - dDepth - else - dExtraOffs = -( dDepth / 2) - end - end - end - -- eseguo il taglio - local bMadeASbyBld, sWarn, nIdMach = Fbs.MakeOne( Proc.Id, nFacet, sCutting, dSawDiam, vtN, nil, ( -0.5 + dExtraOffs), BD.CUT_SIC, 0, 0, 0, nil, _b3Raw) - if bMadeASbyBld then - sWarn = nil - if abs( dExtraOffs) > 0 then - sWarn = 'Warning : antisplint elevation is bigger than max tool depth' - end - end - return bMadeASbyBld, sWarn, nIdMach, dSawThick, dMaxDepth, dAng -end - ---------------------------------------------------------------------- -local function DoPocketing( sName, sPocketing, sMchFind, vtN, nPathInt, nFaceIdx, nUseRoughTool, dMachDepth, dMaxElev, bInvertTool, bInvertPath, bFaceOrtho, bSCCEvaluateOppositeVector, bSCCYSpecialStrategy) - -- inserisco la lavorazione di svuotatura - local nMchFId = EgtAddMachining( sName, sPocketing) - if not nMchFId then - local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing - EgtOutLog( sErr) - return false, sErr - end - -- aggiungo geometria - EgtSetMachiningGeometry( {{ nPathInt, nFaceIdx}}) - if bInvertTool then - EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) - end - if bFaceOrtho then - -- imposto uso faccia - EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) - end - -- imposto posizione braccio porta testa - local nSCC = MCH_SCC.NONE - if not BD.C_SIMM then - if EgtIf( bSCCEvaluateOppositeVector, AreSameOrOppositeVectorApprox( vtN, Z_AX()), AreSameVectorApprox( vtN, Z_AX())) then - nSCC = MCH_SCC.ADIR_YM - elseif abs( vtN:getX()) < 0.1 then - nSCC = EgtIf( BL.IsPartFinalPhase( _nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) - elseif bSCCYSpecialStrategy then - if vtN:getY() > 0.1 then - nSCC = MCH_SCC.ADIR_YP - else - nSCC = MCH_SCC.ADIR_YM - end - else - if vtN:getY() < GEO.EPS_SMALL then - nSCC = EgtIf( bInvertTool, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) - else - nSCC = EgtIf( bInvertTool, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP) - end - end - end - EgtSetMachiningParam( MCH_MP.SCC, nSCC) - -- se tasca aperta, imposto opportuno attacco - if (sMchFind == 'OpenPocket' and nUseRoughTool == 0) or sMchFind == 'OpenPocket_H2' then - EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) - end - if bInvertPath then - -- inverto il percorso di lavorazione se necessario lavorare sinistro - EgtSetMachiningParam( MCH_MP.INVERT, bInvertPath) - end - if dMachDepth ~= 0 then - -- imposto affondamento - EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) - end - -- imposto elevazione e dichiaro non si generano sfridi per VMill - local sNotes = 'VMRS=0;' - if dMaxElev > 0 then - sNotes = sNotes .. 'MaxElev=' .. EgtNumToString( dMaxElev, 1) .. ';' - end - 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 bOk, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - end - return true, '', nMchFId -end - ---------------------------------------------------------------------- -local function MakePocket( Proc, ptPs, tvtN, nFaceRef, sMchFind, nUseRoughTool, - sMasterPocket, dPrevFaceElev, tDimAndRef, dAng) - -- calcolo l'elevazione dal punto medio - local dElev - local dLenIn, dLedOut = BL.GetPointDirDepth( _nPartId, ptPs, tvtN[2]) - if dLenIn > 0 then - dElev = dLenIn - elseif dLedOut then - dElev = dLedOut - end - local dCollSic = 2 * BD.COLL_SIC - -- calcolo il diametro utensile - local dDiamTool - local dFaceDiamTool - if tDimAndRef then - -- prendo il valore dalle dimensioni minime delle facce - dFaceDiamTool = min( tDimAndRef[2][1], tDimAndRef[2][2]) - end - -- se ho lavorazione precedente ricalcolo grossolanamente l'elevazione - if dPrevFaceElev and dPrevFaceElev > 0 and dAng then - dElev = dElev + ( sqrt( ( dElev * dElev) - ( dPrevFaceElev * dPrevFaceElev)) * sin( dAng)) - elseif dPrevFaceElev and dPrevFaceElev > dElev then - dElev = dPrevFaceElev - end - local sPocketing - if sMasterPocket then - sPocketing = sMasterPocket - else - sPocketing = ML.FindPocketing( sMchFind, dFaceDiamTool, dElev + dCollSic) - end - if not sPocketing then - local sErr = 'Error : ' .. sMchFind .. ' not found in library' - EgtOutLog( sErr) - return false, sErr - end - dDiamTool = 20 - local dMaxDepth = 0 - local sTuuidPk - if EgtMdbSetCurrMachining( sPocketing) then - sTuuidPk = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) - if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuidPk) or '') then - dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) - dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) - end - end - -- se nome svuotatura non è stato ricalcolato, confronto il diametro utensile utilizzato con il minimo faccia e se non sono compatibili esco - if sMasterPocket and dFaceDiamTool and dDiamTool >= dFaceDiamTool then - return false, '', sTuuidPk, dDiamTool, dElev - end - -- inserisco la lavorazione di svuotatura - local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. 'F' .. tostring( nFaceRef) - local dMachDepth = 0 - if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then - dMachDepth = dMaxDepth - dElev - dElev = dMaxDepth - sWarn = 'Warning : elevation bigger than max tool depth' - EgtOutLog( sWarn) - end - local bOk, sWarn, nMchFId = DoPocketing( sName, sPocketing, sMchFind, tvtN[2], Proc.Id, nFaceRef, nUseRoughTool, dMachDepth, dElev, false, false, true, false, true) - if not bOk then - return bOk, sWarn - end - return true, sWarn, sTuuidPk, dDiamTool -end - ---------------------------------------------------------------------- -local function DoHeadCut( Proc, sName, sMilling, nMchFId, dElev, nSideFace, tvtN) - local nMchId = EgtAddMachining( sName, sMilling) - if not nMchId then - local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling - EgtOutLog( sErr) - return false, sErr - end - -- aggiungo geometria - EgtSetMachiningGeometry( {{ Proc.Id, nSideFace}}) - -- imposto uso faccia - local nFaceUse = BL.GetNearestOrthoOpposite( tvtN[1]) - -- aggiusto i parametri - EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) - EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') - EgtSetMachiningParam( MCH_MP.OFFSR, 0) - EgtSetMachiningParam( MCH_MP.INVERT, false) - EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) - -- imposto posizione braccio porta testa - if tvtN[2]:getY() < GEO.EPS_SMALL then - EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) - else - EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) - end - -- imposto elevazione e dichiaro non si generano sfridi per VMill - local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';VMRS=0;' - EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - return true -end - ---------------------------------------------------------------------- -local function MachineByMill( Proc, tvtN, nBaseFace, nSideFace, ptPs, tDimAndRef, - nDiffWidth, nUseRoughTool, dAng, sPocketing, sTuuidPk, dPrevFaceElev) - -- se angolo tra le facce maggiore di 90, inserisco la contornatura o svuotatura del lato più corto - if ( 180 + dAng) > 90.1 then - local sMchFind = 'Pocket' - local dAngLimit = 40 - - -- se feature é larga come trave imposto openpocket - if nDiffWidth == 0 then - sMchFind = 'OpenPocket' - -- altrimenti non è passante disabilito il truciolatore - else - nUseRoughTool = 0 - end - -- calcolo l'angolo dalla verticale dall'angolo tra le due facce, perchè la feature potrebbe essere ruotata sulla Z locale della - -- faccia principale e quindi la componente X del versore della faccia potrebbe dare un valore non coerente - local dDiffFromSqAng = dAng + 90 - -- se l'angolo dalla verticale si discosta di più dell'angolo limite impostato, utilizzo la svuotatura - if cos( dDiffFromSqAng) < cos( dAngLimit) then - -- applico la svuotatura - local bOk, sWarn, sTuuidPk, dDiamTool, dElev = MakePocket( Proc, ptPs, tvtN, nSideFace, sMchFind, nUseRoughTool, sPocketing, dPrevFaceElev, tDimAndRef, dAng) - if not bOk then - if sTuuidPk then - -- recupero la lavorazione - local sMilling = ML.FindMilling( 'Long2Cut', dElev, sTuuidPk) - if not sMilling then - local sErr = 'Error : Long2Cut not found in library' - EgtOutLog( sErr) - return false, sErr - end - -- inserisco la lavorazione - local sName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - bOk, sWarn = DoHeadCut( Proc, sName, sMilling, nMchFId, dElev, nSideFace, tvtN) - if not bOk then - return false, sWarn - end - end - else - return bOk, sWarn - end - -- altrimenti contornatura di fianco - else - local bOpenStart = false - local bOpenEnd = false - if nDiffWidth == 0 then - bOpenStart = true - bOpenEnd = true - else - local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, (nBaseFace))[1] - for j = 1, #vAdj2 do - if vAdj2[j] == nSideFace then - -- Se non esiste faccia adiacente a lato precedente -> inizio aperto - local i = EgtIf( j > 1, j - 1, #vAdj2) - while vAdj2[i] == nSideFace do - i = EgtIf( i > 1, i - 1, #vAdj2) - end - bOpenStart = ( vAdj2[i] < 0) - -- Se non esiste faccia adiacente a lato successivo -> fine aperto - local k = EgtIf( j < #vAdj2, j + 1, 1) - while vAdj2[k] == nSideFace do - k = EgtIf( k < #vAdj2, k + 1, 1) - end - bOpenEnd = ( vAdj2[k] < 0) - end - end - end - local sMilling - if nUseRoughTool > 0 then - sMilling = ML.FindMilling( 'Long2Cut', nil, sTuuidPk) - else - sMilling = ML.FindMilling( 'LongSmallCut', nil, sTuuidPk) - end - if not sMilling then - local sErr = 'Error : Long2Cut & LongSmallCut not found in library' - EgtOutLog( sErr) - return false, sErr - end - -- recupero i dati dell'utensile - local dTDiam = 50 - local TI = GetToolInfoForMachining( sMilling) - if TI then - dTDiam = TI.dDiam or dTDiam - end - -- Calcolo uso faccia - local nFaceUse = BL.GetNearestParalOpposite( tDimAndRef[1][3]:getVersZ()) - -- inserisco la lavorazione di fresatura - local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - local nMchFId = EgtAddMachining( sName, sMilling) - if not nMchFId then - local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling - EgtOutLog( sErr) - return false, sErr - end - -- aggiungo geometria - EgtSetMachiningGeometry( {{ Proc.Id, (nSideFace)}}) - -- imposto uso faccia - EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) - -- setto inversione del percorso - EgtSetMachiningParam( MCH_MP.INVERT, true) - -- setto a 0 eventuali offset - EgtSetMachiningParam( MCH_MP.OFFSR, 0) - -- calcolo elevazione per allungamenti attacchi con fianchi chiusi - local dElev - local dLenIn, dLedOut = BL.GetPointDirDepth( _nPartId, ptPs, tvtN[2]) - if dLenIn > 0 then - dElev = dLenIn - elseif dLedOut then - dElev = dLedOut - end - -- applico gli allungamenti o accorciamenti - if bOpenStart then - EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2) - else - EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dTDiam / 2) - if dElev > 0 then - EgtSetMachiningParam( MCH_MP.LIPERP, dElev) - end - end - if bOpenEnd then - EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2) - else - EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dTDiam / 2) - if dElev > 0 then - EgtSetMachiningParam( MCH_MP.LOPERP, dElev) - end - end - -- eseguo - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - end - end - return true -end - ---------------------------------------------------------------------- -local function GetUShapeWidth( Proc, nFacInd) - -- Recupero le facce adiacenti alla principale (solo quelle esistenti) - local vAdj = GetValidFacetAdjacencies( Proc.Id, nFacInd) - -- se non ho facce adiacenti esco subito - if not vAdj or #vAdj == 0 then return nil end - -- Normale della faccia - local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) - -- Cerco le facce adiacenti alla principale con angolo concavo >= 90 - local dWidth = 0 - for i = 1, #vAdj do - -- verifico l'angolo tra le facce ( esco se angolo compreso < 90) - local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) - if bAdj and dAng < -90 - 20 * GEO.EPS_ANG_SMALL then return nil end - -- larghezza della faccia ortogonalmente alla adiacente - local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT) - local vtX = vtN2 ^ vtN - local frRef = Frame3d( ptC, ptC + 100 * vtX, ptC + 100 * vtN2) - local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, nFacInd, GDB_BB.STANDARD, frRef) - if b3Ref then - dWidth = max( dWidth, b3Ref:getDimY()) - end - end - return dWidth -end - ---------------------------------------------------------------------- -local function MakeByPockets( Proc, bOrthoFacesMaster, bMillDown) - local nFirstMachId - local bOrthoFaces - local sWarn - local sMchFind = 'Pocket' - local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt - local bBadMach = false - local bIs3Faces = Proc.Fct == 3 - - if bIs3Faces then - -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa - local nFacInd, _, nFacInd2, _ = BL.GetFaceWithMostAdj( Proc.Id, _nPartId, bIs3Faces) - if not nFacInd or nFacInd < 0 then - if nFacInd == -1 then - bOrthoFaces = nFacInd2 - else - local sErr = 'Error : MakeByPockets could not find reference face' - EgtOutLog( sErr) - return -1, sErr - end - end - else - bOrthoFaces = bOrthoFacesMaster - end - -- se è un tunnel verifico se è possibile usare la svuotatura - if bOrthoFaces then - -- ottengo le dimensioni del tunnel - dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc) - local nPathInt - -- se devo inserire il chamfer - if _nChamfer > 0 then - local nOk, sErr = MakeChamfer( Proc, vtOrtho, nSurfInt) - if nOk < 0 then return -1, sErr end - end - -- se smusso non è esclusivo - if _nChamfer < 2 then - -- ricalcolo se è lavorabile da sotto - bMillDown = ( BD.DOWN_HEAD == true) - -- verifico se può essere fatto con svuotatura - local bMakePocket, sPocketing, dMaxDepth, dDiamTool = VerifyPocket( dDimMin, dDepth / 2, nil, sMchFind) - local bMakePocketDn, sPocketingDn, dMaxDepthDn - if bMillDown then - bMakePocketDn, sPocketingDn, dMaxDepthDn = VerifyPocket( dDimMin, dDepth / 2, nil, sMchFind .. '_H2', false, 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) - -- se ho 3 facce, ciclo sulle entità del percorso per segnare quelle che sono aperte - if bIs3Faces then - SetOpenSide( nPathInt, vtOrtho) - end - -- variabili per parametri lavorazione - local dMachDepth - local dElev = 0 - local bDoubleSide - local bOneShot - local bComplete = true - -- imposto altezza aggiuntiva di elevazione - local dCollSic = 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 - -- se lavorazione non idonea esco - if bIs3Faces and bBadMach then - local sErr = 'Impossible apply perpendicular pocketing: ' .. sPocketing - return -2, sErr - end - -- inserisco la lavorazione di svuotatura - local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - local bToolInvert = false - -- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale) - if vtOrtho:getZ() < BD.NZ_MINA and abs( vtOrtho:getZ()) >= 0.707 and not BD.DOWN_HEAD then - bToolInvert = 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 - bToolInvert = true - end - -- eseguo svuotatura - local bOk, sErr, nMchFId = DoPocketing( sName, sPocketing, sMchFind, vtOrtho, nPathInt, -1, 0, dMachDepth, dElev, bToolInvert, true, false, true) - if not bOk then - return -1, sErr - end - -- prendo l'id della prima lavorazione inserita - if not nFirstMachId then - nFirstMachId = nMchFId - 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)) - -- eseguo svuotatura in direzione invertita - local bOk, sErr, nMchFId = DoPocketing( sName, sPocketing, sMchFind, vtOrtho, nPathInt, -1, 0, dMachDepth, dElev, true, true, false, false) - if not bOk then - return -1, sErr - end - -- prendo l'id della prima lavorazione inserita - if not nFirstMachId then - nFirstMachId = nMchFId - end - end - -- se non completo e U, cerco di lavorare anche la faccia di fondo (con il massimo affondamento possibile) - if not bComplete and bIs3Faces then - -- recupero la faccia da lavorare - local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, _nPartId) - local vtN - local bPock3rd = false - if nFacInd then - vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) - bPock3rd = ( vtN and ( vtN:getZ() >= BD.NZ_MINA or bMakePocketDn)) - end - if bPock3rd then - -- recupero la distanza di sicurezza aggiuntiva - local dFacCollSic = CalcCollisionSafety( vtN) - -- scelgo se lavorare da sotto - local bFacPocketDn = ( bMakePocketDn and vtN:getZ() < -0.174) - -- calcolo affondamento - local dDepth = 0 - local dActMaxDepth = EgtIf( bFacPocketDn, dMaxDepthDn, dMaxDepth) - if dActMaxDepth < dFacElev + dFacCollSic then - dDepth = dActMaxDepth - dFacElev + dFacCollSic - end - -- inserisco la lavorazione di svuotatura - local sName = EgtIf( bDoubleSide, 'Pock3rd_', 'Pock2nd_') .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - -- eseguo svuotatura - local bOk, sErr, nMchFId = DoPocketing( sName, sPocketing, sMchFind, vtN, Proc.Id, nFacInd, 0, dDepth, 0, false, true, false, true) - if not bOk then - return -1, sErr - end - -- prendo l'id della prima lavorazione inserita - if not nFirstMachId then - nFirstMachId = nMchFId - end - end - end - return 1, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId - end - end - end - - return 0, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId, bOrthoFaces -end - ---------------------------------------------------------------------- -local function ManageAntiSplintBySaw( Proc, bIsU, vtN, nFacInd, sWarn, bMillDown, bReduceDepth) - local bMadeASbyBld = false - local nNumFac = EgtIf( bIsU, 2, 1) - local nPrefSide = 1 -- di preferenza il motore è meglio tenerlo sinistra - -- se a U cerco di ottimizzare il lato di lavoro della lama - if bIsU then - if abs( vtN:getY()) > 0.996 then - nPrefSide = 0 - elseif abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then - -- se X è negativa allora devo tenere il motore a destra - if vtN:getX() < -(10 * GEO.EPS_SMALL) then - nPrefSide = 2 - end - end - end - -- va eseguito sulle facce diverse dalla principale - local nPrevSCC = nil - for nFacet = 0, nNumFac do - if nFacet ~= nFacInd then - -- lavoro - local dSawThick = 0 - local dAng, sWarn2, nIdMach - bMadeASbyBld, sWarn2, nIdMach, dSawThick, dMaxDepth, dAng = MakeAntiSplintBySaw( Proc, nFacet, vtN, nFacInd, bReduceDepth, bMillDown) - if not bMadeASbyBld then return bMadeASbyBld, false, sWarn2 end - sWarn = FormatWarning( sWarn, sWarn2) - -- se antischeggia veramente inserito perchè necessario - if nIdMach then - -- verifico se da invertire - local bInvertMach = false - if bIsU then - if abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then --- if abs( vtN:getZ()) > 0.7 or abs( vtN:getY()) > 0.7 then - -- prendo il vettore normale alla faccia - local ptC, vtNFc = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) - -- se superficie principale parallela al piano XZ - if nPrefSide == 0 then - -- se facce inclinate \\ allora mandrino a destra (per essere verso l'alto) - if vtNFc:getX() * vtNFc:getZ() > 0 then - nPrefSide = 2 - -- altrimenti facce inclinate // quindi mandrino a sinistra (per essere ancora verso l'alto) - else - nPrefSide = 1 - end - end - -- se faccia verso X+ e mandrino verso sinistra - if vtNFc:getX() > 0 and nPrefSide == 1 then - -- se angolo interno e circa -90 - if abs( dAng + 90) < 5 then - bInvertMach = true - end - -- se faccia verso X- e mandrino verso destra - elseif vtNFc:getX() < 0 and nPrefSide == 2 then - -- se angolo interno e circa -90 - if abs( dAng + 90) < 5 then - bInvertMach = true - end - end - end - end - -- eseguo inversione - if bInvertMach then - local bToolInvert = EgtGetMachiningParam( MCH_MP.TOOLINVERT) - local nWS = EgtGetMachiningParam( MCH_MP.WORKSIDE) - local nInvWS = EgtIf( nWS == MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT) - local nFaceUse = EgtGetMachiningParam( MCH_MP.FACEUSE) - local bOrtUp = ( nFaceUse >= MCH_MILL_FU.ORTUP_DOWN and nFaceUse <= MCH_MILL_FU.ORTUP_RIGHT) - if not bOrtUp then - -- assegno i parametri invertiti - EgtSetMachiningParam( MCH_MP.WORKSIDE, nInvWS) - EgtSetMachiningParam( MCH_MP.TOOLINVERT, not bToolInvert) - -- setto l'offset pari allo spessore lama - EgtSetMachiningParam( MCH_MP.OFFSL, -dSawThick) - end - end - -- posizione del braccio : se primo taglio la recupero, altrimenti la imposto - if not nPrevSCC then - nPrevSCC = EgtGetMachiningParam( MCH_MP.SCC) - else - EgtSetMachiningParam( MCH_MP.SCC, nPrevSCC) - end - -- rieseguo - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nIdMach, false) - return false, false, sErr - end - end - end - end - - return bMadeASbyBld, true, sWarn -end - ---------------------------------------------------------------------- -local function MakePathsOnExtremePoints( nIdPath, pPaths, dTDiam) - - local dLength = 2 - if not nIdPath then return pPaths end - - -- prendo i punti iniziali e finali del percorso e i versori direzione - local ptIni = EgtSP( nIdPath, GDB_RT.GLOB) - local ptEnd = EgtEP( nIdPath, GDB_RT.GLOB) - - -- se distanza tra i punti è <= del diametro utensile esco - if dist( ptIni, ptEnd) <= dTDiam then return pPaths end - - -- prendo i versori iniziali e finali - local vtIni = EgtSV( nIdPath, GDB_RT.GLOB) - local vtEnd = EgtEV( nIdPath, GDB_RT.GLOB) - - local ptIniP = ptIni - local ptEndP = ptIniP + (vtIni * dLength) - local nAuxId = EgtLine( _nAddGrpId, ptIniP, ptEndP, GDB_RT.GLOB) - table.insert( pPaths, { nAuxId, 1, ptIniP}) - - ptIniP = ptEnd - ptEndP = ptEnd - ( vtEnd * dLength) - nAuxId = EgtLine( _nAddGrpId, ptIniP, ptEndP, GDB_RT.GLOB) - table.insert( pPaths, { nAuxId, 2, ptIniP}) - - return pPaths -end - ---------------------------------------------------------------------- -local function MakeAntiSplintByMill( Proc, pPaths, nPathInt, vtN1, - bDoubleSide, bOppoSide, sMilling, sMyWarn, - dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId) - - local sMyWarn2 - - -- assegno lavorazioni ad ogni percorso - for i = 1, #pPaths do - local nIdPath = pPaths[i][1] - local nSide = pPaths[i][2] - -- modifico versore direzione - EgtModifyCurveExtrusion( nIdPath, vtN1, GDB_RT.GLOB) - local sName - if bOppoSide then - sName = 'AntiSplintOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - else - sName = 'AntiSplint_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - end - local nMchId = EgtAddMachining( sName, sMilling) - if nMchId then - -- aggiungo geometria - EgtSetMachiningGeometry( {{ nIdPath, -1}}) - if ( bOppoSide and nSide == 1) or ( not bOppoSide and nSide == 2) then - -- imposto lato di lavoro destro - EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) - else - -- imposto lato di lavoro sinistro - EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) - end - local nSCC - if bOppoSide then - -- imposto direzione utensile opposta - EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) - -- imposto posizione braccio porta testa - nSCC = MCH_SCC.ADIR_YM - if not BD.C_SIMM then - if AreSameVectorApprox( vtN1, Z_AX()) then - nSCC = MCH_SCC.ADIR_YM - elseif abs( vtN1:getX()) < 0.1 then - nSCC = EgtIf( BL.IsPartFinalPhase( _nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) - elseif vtN1:getY() < GEO.EPS_SMALL then - nSCC = MCH_SCC.ADIR_YP - else - nSCC = MCH_SCC.ADIR_YM - end - end - else - local bInvertMach = false - if not nPathInt then - -- imposto posizione braccio porta testa - nSCC = MCH_SCC.ADIR_YM - if vtN1:getY() > 100 * GEO.EPS_ZERO then - nSCC = MCH_SCC.ADIR_YP - end - else - -- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale) - if vtN1:getZ() < BD.NZ_MINA and abs(vtN1:getZ()) >= 0.707 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 vtN1:getY() > GEO.EPS_SMALL then - EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) - bInvertMach = true - end - -- imposto posizione braccio porta testa - nSCC = MCH_SCC.NONE - if not BD.C_SIMM then - if AreSameOrOppositeVectorApprox( vtN1, Z_AX()) then - nSCC = MCH_SCC.ADIR_YM - elseif abs( vtN1:getX()) < 0.1 then - nSCC = EgtIf( BL.IsPartFinalPhase( _nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) - elseif vtN1: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 - end - end - EgtSetMachiningParam( MCH_MP.SCC, nSCC) - -- parametri attacco - EgtSetMachiningParam( MCH_MP.LEADINTYPE, 1) - -- allungo inizio - EgtSetMachiningParam( MCH_MP.STARTADDLEN, 2) - EgtSetMachiningParam( MCH_MP.LITANG, 10) - EgtSetMachiningParam( MCH_MP.LIPERP, -5) - -- parametri uscita - EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) - local dMachDepth = 0 - local dExtraElev = 0 - if bDoubleSide then - dExtraElev = BL.GetFaceElevationFromPointDir( Proc.Id, _nPartId, pPaths[i][3], EgtIf( bOppoSide, -vtN1, vtN1)) - dMaxElevMaster - end - local dMaxElev = dMaxElevMaster + dExtraElev - if ( dMaxElev + BD.CUT_EXTRA + dCollSic) > dMaxDepth then - dMachDepth = dMaxDepth - ( dMaxElev + dCollSic) - end - -- setto se devo invertire il percorso - local bInvert = CheckToInvert( nIdPath, true) - if bOppoSide then - EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) - EgtSetMachiningParam( MCH_MP.INVERT, bInvert) - else - EgtSetMachiningParam( MCH_MP.DEPTH, (dMachDepth + dExtraDepth)) - EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bInvertMach, not bInvert, bInvert)) - end - -- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione - local sUserNotes = 'VMRS=0;MaxElev=' .. EgtNumToString( ( dMaxElev + dMachDepth), 1) .. ';' - EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) - -- eseguo - if ML.ApplyMachining( true, false) then - _, sMyWarn2 = EgtGetMachMgrWarning( 0) - if EgtIsMachiningEmpty() then - EgtSetOperationMode( nMchId, false) - else - -- se ho la lavorazione di svuotatura riloco la lavorazione antischeggia prima di questa - if nFirstMachId then - EgtRelocateGlob( nMchId, nFirstMachId, GDB_IN.BEFORE) - end - end - -- altrimenti lavorazione non applicata - else - _, sMyWarn2 = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchId, false) - end - -- altrimenti non è stata inserita lavorazione - else - sMyWarn2 = 'warning adding machining ' .. sName .. '-' .. sMilling - end - end - - if sMyWarn2 and #sMyWarn2 > 0 then - sMyWarn = sMyWarn .. '\n' .. sMyWarn2 - end - return sMyWarn -end - ---------------------------------------------------------------------- -local function ManageAntiSplintByMill( Proc, nFacInd, bMillDown, bDoubleSide, - vtOrtho, nPathInt, nSurfInt, dDepth, - bOneShot, nFirstMachId) - local sMyWarn = '' - local pPaths = {} - local nAuxId - local sMilling - - -- recupero la lavorazione tenendo conto dell'elevazione - local dCheckDepth - if bDoubleSide then - dCheckDepth = 0.5 * dDepth - else - if not nPathInt then - dCheckDepth = BL.GetFaceElevation( Proc.Id, nFacInd) - else - dCheckDepth = dDepth - end - end - sMilling = ML.FindMilling( 'AntiSplintMillCut', dCheckDepth, nil, nil, nil, not ( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide) or - ML.FindMilling( 'AntiSplintMillCut', 2/3 * dCheckDepth, nil, nil, nil, not ( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide) or - ML.FindMilling( 'AntiSplintMillCut', nil, nil, nil, nil, not ( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide) - - if sMilling then - - local vtN1 - local nFirstId, nNumId - local dMaxElevMaster - local dExtraDepth = 0 - local dCollSic - -- recupero i dati dell'utensile - local dTDiam = 50 - local dMaxDepth = 0 - local TI = GetToolInfoForMachining( sMilling) - if TI then - dTDiam = TI.dDiam or dTDiam - dMaxDepth = TI.dMaxDepth or dMaxDepth - end - - -- se non ho la faccia aggiunta - if not nPathInt then - -- ottengo i percorsi da cui estrapolare il percorso di antischeggia - local tFacAdjMain = ChooseContour( Proc, nFacInd, false) - local tPaths = {} - -- se non trovato nessun angolo interno valido esco - if #tFacAdjMain == 0 then - return true, sMyWarn - end - -- prendo il primo versore - _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) - dCollSic = CalcCollisionSafety( vtN1) or 0 - -- se direzione tende verso una delle alle 3 direzioni azzero l'altezza extra - if abs( vtN1:getX()) > 0.7 or abs( vtN1:getY()) > 0.7 or abs( vtN1:getZ()) > 0.7 then dCollSic = 0 end - - -- se fresatura da sotto salto la lavorazione - if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then - local sErr = 'Error : milling from bottom' - EgtOutLog( sErr) - return false, sErr - end - local ptIniPath - local nMaxLen = 0 - dMaxElevMaster = BL.GetFaceElevation( Proc.Id, nFacInd) - -- ciclo tutta la tabella - for i = 1, #tFacAdjMain do - -- le 2 facce di contatto devono essere perpendicolari o non sottosquadra rispetto alla faccia di fondo - local ptP1, ptP2, dAng - ptP1 = tFacAdjMain[i][3] - ptP2 = tFacAdjMain[i][4] - dAng = tFacAdjMain[i][5] - if ( dAng < 0 and 180 + dAng >= 90 - 10 * GEO.EPS_SMALL) then - -- creo la linea da P1 a P2 - nAuxId = EgtLine( _nAddGrpId, ptP1, ptP2, GDB_RT.GLOB) - table.insert( tPaths, nAuxId) - -- prendo la lunghezza massima e il punto iniziale - if tFacAdjMain[i][2] > nMaxLen then - ptIniPath = ptP1 - nMaxLen = tFacAdjMain[i][2] - end - end - end - -- costruisco il/i percorso/i - nFirstId, nNumId = EgtCurveCompoByReorder( _nAddGrpId, tPaths, ptIniPath, true, GDB_RT.GLOB) - local bOkPath = true - for i = 1, nNumId do - local nIdPath = nFirstId + i - 1 - if EgtCurveIsClosed( nIdPath) then - bOkPath = false - end - end - -- se ho un percorso chiuso cancello tutto - if not bOkPath then - for i = 1, nNumId do - local nIdPath = nFirstId + i - 1 - EgtErase(nIdPath) - end - else - -- creo percorsi antisplint dagli estremi dei percorsi di contorno trovati - for i = 1, nNumId do - local nIdPath = nFirstId + i - 1 - pPaths = MakePathsOnExtremePoints( nIdPath, pPaths, dTDiam) - end - end - -- alrimenti ho la faccia aggiunta - else - dCollSic = CalcCollisionSafety( vtOrtho) - nFirstId = EgtCopyGlob( nPathInt, _nAddGrpId) - nNumId = 1 - -- calcolo elevazione dalla faccia trasversale aggiunta - if bDoubleSide then - dMaxElevMaster = 0.5 * dDepth - else - dMaxElevMaster = dDepth - -- se la precedente svuotatura è stata fatta completamente in una sola volta - -- valuto di nuovo se devo fare due passate o una sola - if bOneShot then - -- se non è possibile svuotare completamente da una sola parte - if dMaxDepth <= ( dMaxElevMaster + BD.CUT_EXTRA + dCollSic) then - bDoubleSide = true - dMaxElevMaster = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) - else - dExtraDepth = dMaxElevMaster - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) - end - -- altrimenti non è stata fatta completamente calcolo la distanza tra faccia aggiunta e profondità superficie - else - dExtraDepth = dMaxElevMaster - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) - end - end - vtN1 = Vector3d(vtOrtho) - local bOkPath = SetOpenSide( nFirstId, vtOrtho, 2) - -- se non ho un percorso chiuso estraggo i percorsi - if bOkPath then - -- creo percorsi antisplint dagli estremi dei percorsi di contorno trovati - pPaths = MakePathsOnExtremePoints( nFirstId, pPaths, dTDiam) - end - EgtErase(nFirstId) - end - - if #pPaths > 0 then - sMyWarn = MakeAntiSplintByMill( Proc, pPaths, nPathInt, vtN1, - bDoubleSide, false, sMilling, sMyWarn, - dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId) - if bDoubleSide then - if bMillDown then - local sMillingDn = ML.FindMilling( 'AntiSplintMillCut_H2', dCheckDepth) or - ML.FindMilling( 'AntiSplintMillCut_H2', 2/3 * dCheckDepth) or - ML.FindMilling( 'AntiSplintMillCut_H2') - sMilling = sMillingDn - -- controllo dati lavorazione - local TI = GetToolInfoForMachining( sMilling) - if TI then - dTDiam = TI.dDiam or dTDiam - dMaxDepth = TI.dMaxDepth or dMaxDepth - end - end - -- se lavorazione valida - if sMilling then - sMyWarn = MakeAntiSplintByMill( Proc, pPaths, nPathInt, vtN1, - bDoubleSide, true, sMilling, sMyWarn, - dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId) - else - sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library' - end - end - -- altrimenti non c'è il percorso - else - sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path' - end - -- altrimenti non è stata trovata lavorazione - else - sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library' - end - if #sMyWarn > 0 then - EgtOutLog( sMyWarn) - end - - return true, sMyWarn -end - ---------------------------------------------------------------------- -local function DoSideMill( Proc, sName, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir, bHalf, dV) - local nMchFId = EgtAddMachining( sName, sMilling) - if not nMchFId then - local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling - EgtOutLog( sErr) - return false, sErr - end - sName = EgtGetName( nMchFId) - -- aggiungo geometria - EgtSetMachiningGeometry( {{ Proc.Id, tFData.nFacInd}}) - -- imposto uso del lato faccia - EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHeadDir, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) - -- calcolo step effettivo ed elevazione - local dVcalc = dV - dMaxMat - local dStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMaxMat - local nStep = ceil( dVcalc / dStep) - if tFData.vtN:getZ() < - 0.5 and ( nStep % 2) == 0 then - nStep = nStep + 1 - end - dStep = dVcalc / nStep + 0.1 - EgtSetMachiningParam( MCH_MP.STEP, dStep) - -- imposto elevazione e dichiaro non si generano sfridi per VMill - local sNotes = 'MaxElev=' .. EgtNumToString( dVcalc + dStep, 2) .. ';' - sNotes = sNotes .. 'VMRS=0;' - EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) - -- attacchi e uscite - if tFData.vtN:getZ() > -0.5 then - EgtSetMachiningParam( MCH_MP.LITANG, 0) - EgtSetMachiningParam( MCH_MP.LIPERP, tFData.dFacElev + BD.CUT_SIC) - else - EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + BD.CUT_SIC) - EgtSetMachiningParam( MCH_MP.LIPERP, 0) - EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.LINEAR) - EgtSetMachiningParam( MCH_MP.LOTANG, 0) - EgtSetMachiningParam( MCH_MP.LOPERP, tFData.dFacElev + BD.COLL_SIC) - if bHalf then - EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dH / 2) - end - end - -- tipo passate multiple - local nStepType = EgtIf( ( Proc.HeadDir and tFData.vtN:getY() < -0.5) or ( not Proc.HeadDir and tFData.vtN:getY() > 0.5), MCH_MILL_ST.ONEWAY, MCH_MILL_ST.ZIGZAG) - EgtSetMachiningParam( MCH_MP.STEPTYPE, nStepType) - -- imposto posizione braccio porta testa - local nSCC = EgtIf( ( tFData.vtN:getY() > 0.5 or ( bHeadDir and tFData.vtN:getZ() > 0.5 ) or ( not bHeadDir and tFData.vtN:getZ() < -0.5)), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) - EgtSetMachiningParam( MCH_MP.SCC, nSCC) - -- eseguo - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - -- se divisa in due metà - if bHalf then - local nMchFNId = EgtCopyMachining( sName .. '_2', sName) - if not nMchFNId then - local sErr = 'Error copying machining ' .. sName - EgtOutLog( sErr) - return false, sErr - end - -- inverto direzione e lato di lavoro e direzione ausiliaria - local bInvert = EgtGetMachiningParam( MCH_MP.INVERT) - EgtSetMachiningParam( MCH_MP.INVERT, not bInvert) - local nWorkSide = EgtGetMachiningParam( MCH_MP.WORKSIDE) - EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nWorkSide == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) - EgtSetMachiningParam( MCH_MP.SCC, EgtIf( nSCC == MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)) - -- eseguo - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFNId, false) - return false, sErr - end - end - - return true, '' -end - ---------------------------------------------------------------------- -local function MakeSideMill( Proc, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir) - local dH, dV - -- recupero la larghezza della faccia perpendicolarmente alle altre 2 - local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, EgtIf( tFData.nFacInd == 0, 1, 0), GDB_ID.ROOT) - local vtX = vtN2 ^ tFData.vtN - local frRef = Frame3d( tFData.ptC, tFData.ptC + 100 * vtX, tFData.ptC + 100 * vtN2) - local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, tFData.nFacInd, GDB_BB.STANDARD, frRef) - if b3Ref then - dV = b3Ref:getDimY() - dH = b3Ref:getDimX() - end - -- se lavorazione da sotto e lunga, va divisa in due metà - local bHalf = ( tFData.vtN:getZ() < -0.5 and dH > ( BD.MAX_LEN_BH_FROM_BOTTOM or 200)) - -- inserisco la lavorazione di fresatura - local sName = 'BHMill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) - local nMchFId = EgtAddMachining( sName, sMilling) - local bOk, sErr = DoSideMill( Proc, sName, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir, bHalf, dV) - return bOk, sErr -end - ---------------------------------------------------------------------- -local function MakeSpecialThreeFaces( Proc, tFData) - -- se orientata verso il basso, verifico l'alternativa - if tFData.vtN:getZ() < BD.NZ_MINA and tFData.vtN2:getZ() < BD.NZ_MINA then - local sErr = 'Error : special LapJoint from bottom impossible' - EgtOutLog( sErr) - return false, sErr - end - -- eventuali tagli preliminari - do - local bOk, sErr = MakePreCuts( Proc) - if not bOk then return false, sErr end - end - -- Recupero la lavorazione di fresa - local sMilling = ML.FindMilling( 'LongSmallCut') - if not sMilling then - local sErr = 'Error : LongSmallCut not found in library' - EgtOutLog( sErr) - return false, sErr - end - -- Recupero la lavorazione di svuotatura - local sMchFind = 'Pocket' - -- se forzato uso truciolatore - if Q_USE_ROUGH_TOOL == 1 then - sMchFind = 'OpenPocket' - end - local dDiam = min( tFData.dH, tFData.dV) - local dDiam2 = min( tFData.dH2, tFData.dV2) - local dCollSic = 2 * BD.COLL_SIC - local dCollSic2 = 2 * BD.COLL_SIC - if abs( tFData.vtN:getX()) > 0.7 or abs( tFData.vtN:getY()) > 0.7 or abs( tFData.vtN:getZ()) > 0.7 then dCollSic = 0 end - if abs( tFData.vtN2:getX()) > 0.7 or abs( tFData.vtN2:getY()) > 0.7 or abs( tFData.vtN2:getZ()) > 0.7 then dCollSic2 = 0 end - local sPocketing = ML.FindPocketing( sMchFind, dDiam2, tFData.dFacElev2 + dCollSic2) - local nPockFace = tFData.nFacInd2 - -- se non trova una svuotatura adatta provo ad assegnarla all'altra faccia - if not sPocketing then - dDiam, dDiam2 = dDiam2, dDiam - dCollSic, dCollSic2 = dCollSic2, dCollSic - tFData = SwapFacetsData( tFData) - - -- prendo a riferimento la seconda faccia per la svuotatura - sPocketing = ML.FindPocketing( sMchFind, dDiam2, tFData.dFacElev2 + dCollSic2) - - if not sPocketing then - local sErr = 'Error : ' .. sMchFind .. ' not found in library' - EgtOutLog( sErr) - return false, sErr - end - end - - -- provo con contornatura - local dDiamTool = 20 - -- verifico se forma ad L - local bIsU, bIsL = TestUL( Proc) - if bIsL then - local bOk, sWarn - bOk, sWarn, _ = MakeByMill( Proc, tFData, dCollSic, true, sMilling) - if not bOk then return bOk, sWarn end - else - local sErr = 'Error : Impossible mill special LapJoint' - EgtOutLog( sErr) - return false, sErr - 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 false, sErr - end - - -- aggiungo geometria - EgtSetMachiningGeometry( {{ Proc.Id, nPockFace}}) - -- imposto uso faccia - EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) - -- imposto posizione braccio porta testa - if tFData.vtN:getY() < GEO.EPS_SMALL then - EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) - else - EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) - end - -- se tasca aperta, imposto opportuno attacco - if sMchFind == 'OpenPocket' then - EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) - end - -- imposto elevazione - local sNotes = 'MaxElev=' .. EgtNumToString( tFData.dFacElev2, 1) .. ';' - 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 false, sErr - end - end - - -- se abilitato dal parametro Q inserisco foro sullo spigolo - if Q_BORE_ON_CORNER == 1 then - local bOk, sWarn = MakeDrillOnCorner( Proc, 0, dDiamTool, true) - if not bOk then return false, sWarn end - -- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura - elseif Q_BORE_ON_CORNER == 2 then - local bOk, sWarn = MakeSharpCleanCorner( Proc, 0, dDiamTool) - if not bOk then return false, sWarn end - end - - return true, '' -end - ---------------------------------------------------------------------- -local function MakeByChainsaw( Proc, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId) - -- verifico se posso farlo con la sega-catena - local bMakeChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick = VerifyChainSaw( dDimMin, dDimMax) - - if bMakeChainSaw then - -- Verifico se necessarie più passate - local nStep = ceil( ( dDimMin - 10 * GEO.EPS_SMALL) / dSawThick) - local dStep = 0 - if nStep > 1 then - dStep = ( dDimMin - dSawThick) / ( nStep - 1) - end - for i = 1, nStep do - -- inserisco la lavorazione di sawing - local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) - local nMchFId = EgtAddMachining( sName, sSawing) - if not nMchFId then - local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing - EgtOutLog( sErr) - return false, sErr - end - -- aggiungo geometria - EgtSetMachiningGeometry( {{ Proc.Id, nLongFaceId}}) - -- imposto uso del lato faccia - -- al momento, dato che la fessura è passante da parte a parte, gestisco solo la lavorazione - -- dall'alto e di fronte (da dietro è disabilitata perchè ho exracorsa con la FAST). - -- Questa feature non è applicata su facce di testa e quindi non controllo l'entrata in X - if abs(vtOrtho:getZ()) >= 0.707 then - EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) - else - EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) - end - local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nLongFaceId, GDB_ID.ROOT) - -- imposto angolo 3° asse rot - EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 1)) - EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho)) - -- imposto offset radiale - local dOffs = ( i - 1) * dStep - EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) - -- se possibile aumento l'affondamento pari al raggio corner + 1 - if dMaxMat > (dDepth + dSawCornerRad + 1) then - EgtSetMachiningParam( MCH_MP.DEPTH, (dDepth + dSawCornerRad + 1)) - -- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning - elseif dMaxMat < dDepth then - EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat) - local sWarn = 'Warning : elevation bigger than max tool depth' - EgtOutLog( sWarn) - end - -- eseguo - if not ML.ApplyMachining( true, false) then - if EgtGetOutstrokeInfo() then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 2)) - EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho)) - if not ML.ApplyMachining( true, false) then - local _, sErr = EgtGetLastMachMgrError() - EgtSetOperationMode( nMchFId, false) - return false, sErr - end - end - if EgtIsMachiningEmpty() then - local _, sWarn = EgtGetMachMgrWarning( 0) - EgtSetOperationMode( nMchFId, false) - return false, sWarn - end - end - end - - return true -end - ---------------------------------------------------------------------- -local function MakeSidePocketings( Proc, tFData, dCollSic, bSpecialMillOnSide, - nBottomFace, sMillingOnSide, dToolDiamOnSide, dThickMillOnSide, - bSinglePart, bIsU, bIsL, dDiam, bMillDown, bMillUp, sMchFind, sMchFindBackUp) - local bTryWithBlades = true - local nOk, bOk, sWarn, sStat, sErr, dDimMin, dDimMax, dDepth, vtOrtho, bOrthoFaces, nSurfInt, sPocketing, nLongFaceId - if bSpecialMillOnSide then - -- eseguo - bOk, sWarn = MakeByMillAsSaw( Proc, tFData, nBottomFace, sMillingOnSide, dToolDiamOnSide, dThickMillOnSide) - if bOk then - return 1, true, sWarn - end - end - -- se feature 16 o 17 e se forzata lama provo prima con questa e poi con la fresa - if ( Proc.Prc == 16 or Proc.Prc == 17) and _bForceUseBlade then - -- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame - if bTryWithBlades and _nChamfer < 2 then - -- anche su macchine con testa da sotto, la sega a catena è solo da sopra - if tFData.vtN:getZ() < BD.NZ_MINA and BD.DOWN_HEAD and tFData.nFacInd2 then - tFData = SwapFacetsData( tFData) - end - -- eseguo - bOk, sWarn, sStat = MakeByChainOrSaw( Proc, tFData, dDimMin, dDimMax, vtOrtho, nil, bOrthoFaces, nBottomFace, nSurfInt) - if not bOk then - -- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e - -- se non è possibile allora provo in seguito con lama o segacatena - -- o passare subito dalla lavorazione con lama/sega catena - if Proc.Fct == 3 and bIsU then - -- lavoro con svuotature (singola o doppia contrapposta) - nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, _, _, _, _, _, _, _, _, bOrthoFaces = MakeByPockets( Proc, nil, bMillDown) - -- se lavorazione non idonea (asse della feature troppo inclinato e impossibile lavorare completamente da due parti) - if nOk == -2 then - if not sMchFind then - sMchFind = sMchFindBackUp - end - sPocketing = ML.FindPocketing( sMchFind, dDiam) - if not sPocketing then - local sErr = 'Error : ' .. sMchFind .. ' not found in library' - EgtOutLog( sErr) - return 1, false, sErr - end - elseif nOk < 0 then - return 1, false, sErr - elseif nOk == 0 then - if sStat == 'MNF' then - sPocketing = ML.FindPocketing( sMchFind, dDiam) - if not sPocketing then - local sErr = 'Error : ' .. sMchFind .. ' not found in library' - EgtOutLog( sErr) - return 1, false, sErr - end - else - return 1, bOk, sWarn - end - else - bOk = true - return 1, bOk, sErr - end - else - sPocketing = ML.FindPocketing( sMchFind, dDiam) - if not sPocketing then - local sErr = 'Error : ' .. sMchFind .. ' not found in library' - EgtOutLog( sErr) - return 1, false, sErr - end - end - else - return 1, bOk, sWarn - end - else - -- se devo inserire il chamfer - if ( ( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 2 and bIsL)) and _nChamfer > 0 then - -- ottengo le dimensioni dello pseudotunnel - local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc) - local nOk, sErr = MakeChamfer( Proc, vtOrtho, nSurfInt) - if nOk < 0 then return 1, false, sErr end - end - bOk = true - return 1, bOk, sWarn - end - else - -- se richiesti antischeggia con lama su U trasversale e smusso non esclusivo - -- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa - -- 2021.04.27 esegue antischeggia di lama se forma U o L con feature passante in Y o Z - -- 2021.07.16 Per poter eseguire antischeggia di lama su feature che non sono passanti da faccia a faccia - -- ma che sono su un angolo (coinvolgono 2 facce contigue) è stato modificato il confronto in: - -- esegue antischeggia di lama se forma U o L con feature passante in Y o Z, oppure se feature a furma U e con 3 facce oppore a forma a L e con 2 facce - local bPassThrou = ( Proc.Box:getDimY() > _b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > _b3Raw:getDimZ() - 1) - local bPassEdge = ( ( ( bIsU and Proc.Fct == 3) or ( bIsL and Proc.Fct == 2)) and bSinglePart and Proc.Box:getDimX() < 0.9 * _b3Raw:getDimX()) - if _nChamfer < 2 and Q_ANTISPLINT_TYPE == 1 and ( ( bIsU or bIsL) and ( bPassThrou or bPassEdge)) then - local bOk - local bSawDown = ( bMillDown and not bMillUp) - _, bOk, sWarn = ManageAntiSplintBySaw( Proc, bIsU, tFData.vtN, tFData.nFacInd, sWarn, bSawDown, true) - if not bOk then return 1, false, sWarn end - end - -- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e - -- se non è possibile allora provo in seguito con lama o segacatena - -- o passare subito dalla lavorazione con lama/sega catena - if _bTrySidePocketAtFirst and Proc.Fct == 3 and bIsU then - -- lavoro con svuotature (singola o doppia contrapposta) - local dDiamTool = 100 - local nPathInt, nSurfInt, bOneShot, nFirstMachId, bDoubleSide - nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, dDiamTool, - bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId, bOrthoFaces = MakeByPockets( Proc, nil, bMillDown) - if nOk == -2 then - if not sMchFind then - sMchFind = sMchFindBackUp - end - sPocketing = ML.FindPocketing( sMchFind, dDiam) - if not sPocketing then - local sErr2 = 'Error : ' .. sMchFind .. ' not found in library' - EgtOutLog( sErr2) - return 1, false, sErr2 - end - bTryWithBlades = false - sWarn = sErr - elseif nOk < 0 then - return 1, false, sErr - elseif nOk > 0 then - bTryWithBlades = false - sWarn = sErr - -- se ho antischeggia con fresa le inserisco - if _nChamfer < 2 and Q_ANTISPLINT_TYPE == 2 then - local bOk, sWarn2 = ManageAntiSplintByMill( Proc, tFData.nFacInd, bMillDown, bDoubleSide, vtOrtho, - nPathInt, nSurfInt, dDepth, bOneShot, nFirstMachId) - sWarn = FormatWarning( sWarn, sWarn2) - end - -- se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola - if Q_CONTOUR_SMALL_TOOL > 0 then - local bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, tFData.nFacInd, dDiamTool, bMillDown, - bDoubleSide, vtOrtho, nPathInt, nSurfInt, dDepth, bOneShotm) - if not bOk then return 1, false, sWarn2 end - sWarn = FormatWarning( sWarn, sWarn2) - end - end - bOk = true - end - -- 03/09/2020 da conferma di Fabio Squaratti: Per ora solo sulla feature 016: - -- se ha fallito la fresatura (qua sopra) allora di default (anche se il flag Q della lama è disattivato) prima provo la lama - if Proc.Prc == 16 then - _bForceUseBlade = true - end - -- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame - if bTryWithBlades and _nChamfer < 2 then - -- anche su macchine con testa da sotto, la sega a catena è solo da sopra - if tFData.vtN:getZ() < BD.NZ_MINA and BD.DOWN_HEAD and tFData.nFacInd2 then - tFData = SwapFacetsData( tFData) - end - -- eseguo - bOk, sWarn, sStat = MakeByChainOrSaw( Proc, tFData, dDimMin, dDimMax, vtOrtho, nLongFaceId, bOrthoFaces, nBottomFace, nSurfInt) - if not bOk and sStat == 'MNF' then - _, sPocketing = VerifyPocket( dDiam, tFData.dFacElev + dCollSic, nil, sMchFind, bMillUp, bMillDown) - if sPocketing then - sWarn = '' - else - local sErr2 = 'Error : ' .. sMchFind .. ' not found in library' - EgtOutLog( sErr2) - return 1, false, sErr2 - end - else - -- se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola - if Q_CONTOUR_SMALL_TOOL > 0 then - local bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, tFData.nFacInd, 100, bMillDown) - if not bOk then return 1, false, sWarn2 end - sWarn = FormatWarning( sWarn, sWarn2) - end - return 1, bOk, sWarn - end - -- altrimenti verifico se ho già svuotato dal fianco, se si esco - else - -- se non ho annullato la/le svuotatura/e dal fianco - if nOk ~= -2 then - return 1, bOk, sWarn - end - end - end - - return 0, true, '' -end - ---------------------------------------------------------------------- -local function MakePocketingOrMilling( Proc, tFData, bSinglePart) - -- verifico se forma ad U o L - local bIsU, bIsL = TestUL( Proc) - local bUseOtherFace - -- se orientata verso il basso e non c'è testa da sotto, verifico l'alternativa - if tFData.vtN:getZ() < BD.NZ_MINA and not BD.DOWN_HEAD and tFData.nFacInd2 then - tFData = SwapFacetsData( tFData) - bUseOtherFace = true - end - -- verifico non sia orientata verso il basso o ci sia una testa dal basso - local bFaceDown = ( tFData.vtN:getZ() < BD.NZ_MINA) - if bFaceDown and not BD.DOWN_HEAD then - local sErr = 'Error : LapJoint from bottom impossible' - EgtOutLog( sErr) - return false, sErr - end - -- se forma a L e la componente in X è maggiore di 60° e non in testa allora verifico se posso utilizzare la faccia secondaria - if bIsL and abs( tFData.vtN:getX()) > 0.866 and - ( Proc.Box:getMax():getX() < _b3Solid:getMax():getX() - 10 or tFData.vtN:getX() < 0) and - ( not Proc.Tail or tFData.vtN:getX() > 0) then - -- se non ho scambiato la faccia - if not bUseOtherFace then - if tFData.nFacInd2 then - tFData = SwapFacetsData( tFData) - -- altrimenti cerco la faccia secondaria per adiacenza alla principale - else - -- Cerco una faccia adiacente alla principale sul lato lungo - local nFacAdj, sErr = GetFaceAdj( Proc, tFData) - if nFacAdj < 0 then - EgtOutLog( sErr) - return false, sErr - end - tFData = UpdateFacet1Data( Proc.Id, tFData, nFacAdj) - end - -- altrimenti se ho già cambiato faccia do errore per impossibilità di lavorazione - else - local sErr = 'Error : impossible to machine by side angle too big that cause collision' - EgtOutLog( sErr) - return false, sErr - end - end - -- eventuali tagli preliminari - do - local bOk, sErr = MakePreCuts( Proc) - if not bOk then return false, sErr end - end - -- imposto altezza aggiuntiva di elevazione - local dCollSic = CalcCollisionSafety( tFData.vtN) - -- abilitazione lavorazione da sotto - local bMillUp = ( BD.DOWN_HEAD and tFData.vtN:getZ() > -0.259) - local bMillDown = ( BD.DOWN_HEAD and tFData.vtN:getZ() < 0.342) - -- settaggio voluto da Alessandro/Fabio (per fare angoli con fresa piccola) - local sMchFind = 'Pocket' - local dDiam = min( tFData.dH, tFData.dV) - local bTailOnSide = ( Proc.Box:getMin():getX() - _b3Solid:getMin():getX() < 0.1 and not Proc.Tail) - if ( Proc.Fct == 1) or ( ( Proc.Fct == 2 or Proc.Fct == 3) and bIsL) or ( ( ( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 4 and not bTailOnSide)) and bSinglePart) then - sMchFind = 'OpenPocket' - if bIsU then - dDiam = GetUShapeWidth( Proc, tFData.nFacInd) or dDiam - elseif Proc.Fct == 4 then - -- per rifinire gli angoli premio utensile diam 25 o da BD - dDiam = min( dDiam, BD.MAXDIAM_POCK_CORNER or 30) - elseif Proc.Fct == 3 and bIsL then - -- per rifinire gli angoli premio utensile diam 25 o da BD - dDiam = min( 2 * dDiam, BD.MAXDIAM_POCK_CORNER or 30) - else - dDiam = 2 * dDiam - end - end - sMchFindBackUp = sMchFind - local nUseRoughTool = EgtIf( bSinglePart, 0, 1) - -- 04/08/2020 Se settato parametro uso truciolatore (parametro Q), non si devono prendere altre frese, si da errore (Fabio) - -- Questa opzione si scontra facilmente con altre interpretazioni dello stasso parametro Q (per tornare indietro bNewCheck = false) - local bNewCheck = true - -- se processo 20 e non sto usando il truciolatore - if bNewCheck and Proc.Prc == 20 and nUseRoughTool == 0 then - -- verifico se forzato uso truciolatore - if Q_USE_ROUGH_TOOL and Q_USE_ROUGH_TOOL ~= 0 then - sMchFind = 'OpenPocket' - nUseRoughTool = 1 - end - end - -- 03/12/2020 aggiunto controllo su feature 30 senza uso truciolatore - if bNewCheck and Proc.Prc == 30 and nUseRoughTool == 0 then - -- verifico se forzato uso truciolatore - if Q_SIDE_ROUGH_TOOL and Q_SIDE_ROUGH_TOOL ~= 0 then - sMchFind = 'OpenPocket' - nUseRoughTool = 1 - end - end - -- se processo 20 e non sto usando il truciolatore - if Proc.Prc == 20 and nUseRoughTool == 0 then - if Q_USE_ROUGH_TOOL and Q_USE_ROUGH_TOOL ~= 0 then - sMchFind = 'OpenPocket' - nUseRoughTool = 1 - end - end - -- se da sotto, imposto massima lunghezza secondo la direzione - local dMaxTotLen - if bMillDown and BD.GetBottomToolMaxTotLen then - dMaxTotLen = BD.GetBottomToolMaxTotLen( tFData.vtN) - end - -- ricerca lavorazione - local sPocketing, sMyPocketing, dMyTMaxDepth - _, sMyPocketing, dMyTMaxDepth, _, bMillDown = VerifyPocket( dDiam, tFData.dFacElev + dCollSic, dMaxTotLen, sMchFind .. EgtIf( bMillDown, '_H2', ''), bMillUp, bMillDown) - --local sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind .. EgtIf( bMillDown, '_H2', ''), dDiam, dFacElev + dCollSic, dMaxTotLen) - --if not sMyPocketing then - -- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind .. EgtIf( bMillDown, '_H2', ''), dDiam, nil, dMaxTotLen) - --end - --if not sMyPocketing and bMillUp then - -- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam, dFacElev + dCollSic) - -- if not sMyPocketing then - -- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam) - -- end - -- bMillDown = false - --end - if sMyPocketing and - ( dMyTMaxDepth > tFData.dFacElev + dCollSic - 10 * GEO.EPS_SMALL or ( dMyTMaxDepth > 0.8 * tFData.dFacElev + dCollSic and not bIsU) or ( bIsL and nUseRoughTool == 0)) then - sPocketing = sMyPocketing - end - if bMillDown then - sMchFind = sMchFind .. '_H2' - end - -- 2021.09.16 Richiesta di Fabio Squaratti per lavorazione "Lamello": - -- se ho attiva questo tipo di lavorazione (delle fresature) e una di queste feature: L016, L030, L032, L039 - -- verifico se sono compatibili con questa lavorazione forma a U e larga più dell'altezza tagliente e profondità compatibile con - local bSpecialMillOnSide - local dThickMillOnSide = 0 - local sMillingOnSide - local dToolDiamOnSide = 0 - local dMaxDepthOnSide = 0 - if ( Proc.Prc == 16 or Proc.Prc == 30 or Proc.Prc == 32 or Proc.Prc == 39) then - -- verifico se ho una gola con 3 facce ed eventualmente delle facce terminali: - -- faccio una copia della superfice ed elimino le facce che hanno dimensione X < 1 e le facce risultanti devono essere una U - local nTestId = EgtCopyGlob( Proc.Id, _nAddGrpId) or GDB_ID.NULL - if nTestId then - local bNewIsU - local bExit - local nFaces = EgtSurfTmFacetCount( nTestId) - while not bExit and nFaces >= 3 do - local bDeleteFace - local nInt = 0 - while not bDeleteFace and nInt < nFaces do - nInt = nInt + 1 - local b3Facet = EgtSurfTmGetFacetBBoxGlob( nTestId, nInt - 1, GDB_BB.STANDARD) - local vtNi = EgtSurfTmFacetNormVersor( nTestId, nInt - 1, GDB_ID.ROOT) - -- se dimensione faccia sulla X - if b3Facet:getDimX() < 1 or abs( vtNi:getX()) > 0.1 then - EgtSurfTmRemoveFacet( nTestId, nInt - 1) - bDeleteFace = true - end - end - nFaces = EgtSurfTmFacetCount( nTestId) - -- se non ho cancellato una faccia faccio il test per forma ad U - if not bDeleteFace then - -- ottengo il numero di facce rimanenti - bNewIsU = ( nFaces == 3 and not TestElleShape3( nTestId, true)) - bExit = true - end - end - -- verifico che la componente x della faccia 0 deve essere nulla - local vtN1 = EgtSurfTmFacetNormVersor( nTestId, 0, GDB_ID.ROOT) - if bNewIsU and abs( vtN1:getX()) > 0.01 then - bNewIsU = false - end - -- cancello la copia del percorso - EgtErase( nTestId) - - if bNewIsU and ( not BD.MIN_LEN_LAMELLO or - ( Proc.TotBox and Proc.TotBox:getDimX() > BD.MIN_LEN_LAMELLO) or - ( not Proc.TotBox and Proc.Box:getDimX() > BD.MIN_LEN_LAMELLO)) then - -- recupero la lavorazione - local bDownhead = BD.DOWN_HEAD and tFData.vtN:getZ() < BD.NZ_MINA - sMillingOnSide = ML.FindMilling( 'SideMillAsBlade_H2', nil, nil, nil, nil, not bDownhead, bDownhead) - - if sMillingOnSide then - -- recupero i dati dell'utensile - local dToolLength = 0 - local TI = GetToolInfoForMachining( sMillingOnSide) - if TI then - dToolLength = TI.dLength or dToolLength - dToolDiamOnSide = TI.dDiam or dToolDiamOnSide - dThickMillOnSide = TI.dMaxMat or dThickMillOnSide - dMaxDepthOnSide = TI.dSideDepth or dMaxDepthOnSide - end - -- 2021.09.17 Su conferma di Fabio Squaratti, se la gola è più stretta dell'utensile o la profondità della gole è maggiore - -- del valore parametro SIDEDEPTH (preso dalle note utente dell'utensile) allora si prosegue come se non fosse abilitata - -- questo tipo di lavorazione SideMillAsBlade - if dDiam > dThickMillOnSide - 10 * GEO.EPS_SMALL and tFData.dFacElev < dMaxDepthOnSide + 10 * GEO.EPS_SMALL then - bSpecialMillOnSide = true - -- disabilito eventuale svuotatura - sPocketing = nil - end - end - end - end - end - -- se feature 16 e forzata lama e forma ad U, annulla la svuotatura - if Proc.Prc == 16 and _bForceUseBlade and Proc.Fct == 3 and bIsU then - sPocketing = nil - end - -- se lavorazione fresa come lama disabilito eventuale antischegggia - if bSpecialMillOnSide then Q_ANTISPLINT_TYPE = 0 end - -- se non trova una svuotatura adatta - if not sPocketing then - -- se forma a L provo con contornatura - if bIsL and not bSpecialMillOnSide then - -- se smusso non è esclusivo - if _nChamfer < 2 then - return MakeByMill( Proc, tFData, dCollSic) - end - -- altrimenti, in base alla forma, provo con svuotature di fianco o con la sega a catena o lama - else - local stat, bOk, sWarn = MakeSidePocketings( Proc, tFData, dCollSic, bSpecialMillOnSide, nBottomFace, - sMillingOnSide, dToolDiamOnSide, dThickMillOnSide, bSinglePart, - bIsU, bIsL, dDiam, bMillDown, bMillUp, sMchFind, sMchFindBackUp) - if stat == 1 then - return bOk, sWarn - end - end - else - -- se devo inserire il chamfer - if ( ( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 2 and bIsL)) and _nChamfer > 0 then - -- ottengo le dimensioni dello pseudotunnel - local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc) - local nOk, sErr = MakeChamfer( Proc, vtOrtho, nSurfInt) - if nOk < 0 then return false, sErr end - end - end - -- se richiesti antischeggia con lama su U trasversale e smusso non esclusivo - -- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa - -- 2021.04.27 esegue antischeggia di lama se forma U o L con feature passante in Y o Z - -- 2021.07.16 Per poter eseguire antischeggia di lama su feature che non sono passanti da faccia a faccia - -- ma che sono su un angolo (coinvolgono 2 facce contigue) è stato modificato il confronto in: - -- esegue antischeggia di lama se forma U o L con feature passante in Y o Z, oppure se feature a forma U e con 3 facce oppore a forma a L e con 2 facce - local bMadeASbyBld = false - local bPassThrou = ( Proc.Box:getDimY() > _b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > _b3Raw:getDimZ() - 1) - local bPassEdge = ( ( ( bIsU and Proc.Fct == 3) or ( bIsL and Proc.Fct == 2)) and bSinglePart and Proc.Box:getDimX() < 0.9 * _b3Raw:getDimX()) - if _nChamfer < 2 and Q_ANTISPLINT_TYPE == 1 and ( ( bIsU or bIsL) and ( bPassThrou or bPassEdge)) then - local bOk - local bSawDown = ( bMillDown and not bMillUp) - bMadeASbyBld, bOk, sWarn = ManageAntiSplintBySaw( Proc, bIsU, tFData.vtN, tFData.nFacInd, sWarn, bSawDown) - if not bOk then return false, sWarn end - end - if _nChamfer < 2 and Q_ANTISPLINT_TYPE == 2 then - local bOk, sWarn2 - bOk, sWarn2 = ManageAntiSplintByMill( Proc, tFData.nFacInd, bMillDown) - if not bOk then return false, sWarn2 end - end - -- se smusso non esclusivo - if _nChamfer < 2 then - -- eseguo la svuotatura della faccia principale, mi restituisce id utensile, il diametro utensile per il foro opzionale - local tvtNx = {} - tvtNx[2] = tFData.vtN - local bOk, sWarn2, sTuuidPk, dDiamTool - bOk, sWarn2, sTuuidPk, dDiamTool = MakePocket( Proc, tFData.ptC, tvtNx, tFData.nFacInd, sMchFind, nUseRoughTool, sPocketing, tFData.dFacElev + dCollSic) - if not bOk then return false, sWarn2 end - sWarn = FormatWarning( sWarn, sWarn2) - -- se ho più di 3 facce e non di forma ad U oppure ho 3 facce e di forma ad U - -- e non sono stati inseriti antischeggia di lama - -- controllo se c'è una faccia non ortogonale alla principale e la lavoro con una contornatura o svuotatura - if ( ( Proc.Fct > 3 and not bIsU) or ( Proc.Fct == 3 and bIsU)) and not bMadeASbyBld then - -- Recupero le facce adiacenti alla principale (solo quelle esistenti) - local vAdj = GetValidFacetAdjacencies( Proc.Id, tFData.nFacInd) - if not vAdj or #vAdj == 0 then - local sErr = 'Error : main face without adjacencies' - EgtOutLog( sErr) - return false, sErr - end - -- Cerco una faccia adiacente alla principale con angolo > 90 - local tDimAndRef = {} - tvtNx = {} - tvtNx[1] = tFData.vtN - tDimAndRef[1] = { tFData.dH, tFData.dV, tFData.rfFac} - for i = 1, #vAdj do - local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, tFData.nFacInd, vAdj[i], GDB_ID.ROOT) - if bAdj and dAng < 0 and 180 + dAng > 90.1 then - local rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vAdj[i], GDB_ID.ROOT) - _, tvtNx[2] = EgtSurfTmFacetCenter( Proc.Id, vAdj[i], GDB_ID.ROOT) - tDimAndRef[2] = { dH2, dV2, rfFac2} - local ptPs = ( ptP1 + ptP2) / 2 - local bOk, sWarn2 = MachineByMill( Proc, tvtNx, tFData.nFacInd, vAdj[i], ptPs, tDimAndRef, - EgtIf( Proc.Fct == 3 and bIsU, 0, 2), nUseRoughTool, dAng, sPocketing, sTuuidPk, tFData.dFacElev) - if not bOk then return bOk, sWarn2 end - sWarn = FormatWarning( sWarn, sWarn2) - end - end - end - -- se abilitato dal parametro Q inserisco foro sullo spigolo - if Q_BORE_ON_CORNER == 1 then - local bOk, sWarn2 = MakeDrillOnCorner( Proc, tFData.nFacInd, dDiamTool) - if not bOk then return false, sWarn2 end - sWarn = FormatWarning( sWarn, sWarn2) - -- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura - elseif Q_BORE_ON_CORNER == 2 then - local bOk, sWarn2 = MakeSharpCleanCorner( Proc, tFData.nFacInd, dDiamTool) - if not bOk then return false, sWarn2 end - sWarn = FormatWarning( sWarn, sWarn2) - -- altrimenti se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola - elseif Q_CONTOUR_SMALL_TOOL > 0 then - local bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, tFData.nFacInd, dDiamTool, bMillDown) - if not bOk then return false, sWarn2 end - sWarn = FormatWarning( sWarn, sWarn2) - end - end - - return true, '' -end - ---------------------------------------------------------------------- -local function MakeTwoFaces( Proc, bSinglePart, bPrevBhSideMill) - -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer - -- genero errore e non faccio nulla - if _nChamfer < 0 then - return false, _sErrCham - end - - -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa - local tFData = GetFacetsData( Proc.Id) - if not tFData.nFacInd or tFData.nFacInd < 0 then - local sErr = 'Error : MakeTwoFaces could not find reference face' - EgtOutLog( sErr) - return false, sErr - end - - -- se fattibile con fresa BH di fianco e spessore utensile inferiore alla larghezza faccia - local bMakeBySideMill, _, bHeadDir, sMilling, dMaxMat, dToolDiam = VerifyBHSideMill( Proc, bSinglePart, bPrevBhSideMill) - if bPrevBhSideMill == nil then - bPrevBhSideMill = bMakeBySideMill - end - if bMakeBySideMill and ( dMaxMat <= tFData.dH + 15 * GEO.EPS_SMALL) then - -- se smusso non è esclusivo - if _nChamfer < 2 then - local bOk, sErr = MakeSideMill( Proc, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir) - return bOk, sErr - end - -- altrimenti lavoro con svuotatura - else - local bOk, sErr = MakePocketingOrMilling( Proc, tFData, bSinglePart) - return bOk, sErr - end - - return true, '', bPrevBhSideMill -end - ---------------------------------------------------------------------- -local function MakeThreeFaces( Proc, bSinglePart, bPrevBhSideMill) - -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer - -- genero errore e non faccio nulla - if _nChamfer < 0 then - return false, _sErrCham - end - - -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa - local tFData = GetFacetsData( Proc.Id) - if not tFData.nFacInd or tFData.nFacInd < 0 then - local sErr = 'Error : MakeThreeFaces could not find reference face' - EgtOutLog( sErr) - return false, sErr - end - - -- se fattibile con fresa BH di fianco e spessore utensile inferiore alla larghezza faccia - local bMakeBySideMill, _, bHeadDir, sMilling, dMaxMat, dToolDiam = VerifyBHSideMill( Proc, bSinglePart, bPrevBhSideMill) - if bPrevBhSideMill == nil then - bPrevBhSideMill = bMakeBySideMill - end - --if bMakeBySideMill and ( dMaxMat <= tFData.dV + 15 * GEO.EPS_SMALL) then - if bMakeBySideMill and ( dMaxMat <= tFData.dH + 15 * GEO.EPS_SMALL) then - -- se smusso non è esclusivo - if _nChamfer < 2 then - local bOk, sErr = MakeSideMill( Proc, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir) - return bOk, sErr - end - -- altrimenti lavoro con svuotatura - else - local bSpecial3faces = false - local bBoxF = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, tFData.rfFac) - - if tFData.dH * tFData.dV < 0.9 * ( bBoxF:getDimX() * bBoxF:getDimY()) then - bSpecial3faces = true - end - - -- se riconosciuta gestione special (limitata per ora alla feature 20) - if bSpecial3faces and Proc.Prc == 20 and tFData.nFacInd2 then - -- se smusso non è esclusivo - if _nChamfer < 2 then - local bOk, sErr = MakeSpecialThreeFaces( Proc, tFData) - return bOk, sErr - end - -- altrimenti lavorazione di svuotatura o contornatura - else - local bOk, sErr = MakePocketingOrMilling( Proc, tFData, bSinglePart) - return bOk, sErr - end - end - - return true, '', bPrevBhSideMill -end - ---------------------------------------------------------------------- -local function MakeMoreFaces( Proc, bSinglePart, bPrevBhSideMill) - local bClosedOrthoFaces - -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa - local tFData = GetFacetsData( Proc.Id) - if not tFData.nFacInd or tFData.nFacInd < 0 then - if tFData.nFacInd == -1 then - bClosedOrthoFaces = tFData.isOrthoFaces - else - local sErr = 'Error : MakeMoreFaces could not find reference face' - EgtOutLog( sErr) - return false, sErr - end - end - -- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche - if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then - local nBottomFace - -- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura - for i = 1, Proc.Fct do - local nNewProcId = EgtCopyGlob( Proc.Id, _nAddGrpId) or GDB_ID.NULL - -- elimino una faccia - nBottomFace = i - 1 - if EgtSurfTmRemoveFacet( nNewProcId, nBottomFace) then - -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa - tFData = GetFacetsData( nNewProcId) - if not tFData.nFacInd or tFData.nFacInd < 0 then - if tFData.nFacInd == -1 then - bClosedOrthoFaces = tFData.isOrthoFaces - EgtErase( nNewProcId) - break - else - EgtErase( nNewProcId) - local sErr = 'Error : MakeMoreFaces could not find reference face' - EgtOutLog( sErr) - return false, sErr - end - end - -- altrimenti esco - else - EgtErase( nNewProcId) - break - end - end - -- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo - if bClosedOrthoFaces then - local dFacElev = BL.GetFaceElevation( Proc.Id, nBottomFace) - tFData = UpdateFacet1Data( Proc.Id, tFData, nBottomFace, dFacElev) - -- rendo nulla la faccia opzionale perchè si tratta di una fessura - tFData = UpdateFacet2Data( Proc.Id, tFData, nil) - -- non setto come tunnel - bClosedOrthoFaces = false - end - end - -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer - -- genero errore e non faccio nulla - if _nChamfer < 0 then - return false, _sErrCham - end - -- se è un tunnel provo a vedere se è possibile lavorarlo con la svuotatura o con la sega catena - if bClosedOrthoFaces then - local bTryWithBlades = true - -- lavoro fessura con svuotature (singola o doppia contrapposta) - local nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId = MakeByPockets( Proc, bClosedOrthoFaces) - if nOk < 0 then - return false, sErr - elseif nOk > 0 then - bTryWithBlades = false - end - -- Se la svuotatura precedente non è stata fatta e chamfer non è mutuamente esclusivo provo con la sega-catena - if bTryWithBlades and _nChamfer < 2 then - -- verifico se posso farlo con la sega-catena - local bOk, sErr = MakeByChainsaw( Proc, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId) - if not bOk then - return false, sErr - end - end - -- altrimenti non è una fessura - else - local bOk, sErr = MakePocketingOrMilling( Proc, tFData, bSinglePart) - return bOk, sErr, bPrevBhSideMill - end - - return true, '', bPrevBhSideMill -end - ---------------------------------------------------------------------- -local function MakeLongFaces( Proc, Func) - -- divido in parti lungo X - local vAddId = {} - local nPart = max( ceil( Proc.Box:getDimX() / BD.LONGCUT_MAXLEN), 2) - local dPartLen = Proc.Box:getDimX() / nPart - local Xmin = Proc.Box:getMin():getX() - for i = 1, nPart do - -- eseguo divisione - local AddId = EgtCopyGlob( Proc.Id, _nAddGrpId) or GDB_ID.NULL - EgtSetName( AddId, 'AddPart_' .. tostring( Proc.Id) .. '_' .. tostring( i)) - if i > 1 then - local ptOn = Point3d( Xmin + ( i - 1) * dPartLen, 0, 0) - EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB) - end - if i < nPart then - local ptOn = Point3d( Xmin + i * dPartLen, 0, 0) - EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB) - end - -- eseguo inserimento in modo da ordinare da X+ a X- - table.insert( vAddId, 1, AddId) - end - -- applico le lavorazioni sulle diverse parti - local sWarn - local bPrevBhSideMill - for i = 1, #vAddId do - local b3Box = EgtGetBBoxGlob( vAddId[i], GDB_BB.STANDARD) - local nFct = EgtSurfTmFacetCount( vAddId[i]) - local AddProc = { Id = vAddId[i], Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Box, TotBox = Proc.Box, Fct = nFct, Flg = Proc.Flg} - local bOk, sMyWarn - -- richiamo la funzione necessaria (passata come parametro) - bOk, sMyWarn, bPrevBhSideMill = Func( AddProc, false, bPrevBhSideMill) - if not sWarn then sWarn = sMyWarn end - if not bOk then return bOk, sWarn end - end - return true, sWarn -end - ---------------------------------------------------------------------- -local function TestTwoFacesDownHead( Proc) - -- verifico ci siano due facce - if Proc.Fct ~= 2 then return false end - -- verifico se da lavorare con testa da sotto - local bDownHead = false - if BD.DOWN_HEAD then - 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 vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() - bDownHead = ( vtNm:getZ() < -0.5) - end - return bDownHead -end - ---------------------------------------------------------------------- --- Applicazione della lavorazione ---------------------------------------------------------------------- -function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) - -- inizializzo variabili globali al modulo - local bOk, sErr = InitGlob( Proc, nPhase, nRawId, nPartId, dOvmHead) - if not bOk then - return bOk, sErr - end - -- limiti di fresatura semplice - local MAX_MILL_LIN = 80 - -- se non forzate frese, uso la lama - local bUseBlade = Q_USE_ROUGH_TOOL ~= 1 and Q_USE_MILL ~= 1 - local nForceUseBladeOnNotContinueFace - -- se ho attiva la lama e ho la feature 30, verifico i parametri Q propri della feature - if bUseBlade then - if Proc.Prc == 30 then - nForceUseBladeOnNotContinueFace = Q_BLADE_ON_ALONG_FACE - -- se antischeggia di fresa o abilitato sgrossatore di fianco - if Q_ANTISPLINT_TYPE == 2 or Q_SIDE_ROUGH_TOOL == 1 then - bUseBlade = false - end - -- se ho attiva la lama e ho la feature 32, verifico i parametri Q propri della feature - elseif Proc.Prc == 32 then - -- se antischeggia di fresa o abilitato sgrossatore di fianco - if Q_ANTISPLINT_TYPE == 2 or Q_SIDE_ROUGH_TOOL == 1 then - bUseBlade = false - end - -- se ho attiva la lama e ho la feature 34, verifico i parametri Q propri della feature - elseif Proc.Prc == 34 then - -- se antischeggia di fresa o abilitato sgrossatore di fianco - if Q_ANTISPLINT_TYPE == 2 then - bUseBlade = false - end - end - end - -- se lunghezza richiede spezzatura - if ( Proc.Box:getDimX() > BD.LONGCUT_MAXLEN) or - ( Proc.Box:getDimX() > 0.7 * _b3Solid:getDimX() and Proc.Box:getDimX() > BD.LONGCUT_ENDLEN) then - -- una faccia - if Proc.Fct == 1 then - if bUseBlade and nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then - return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) - else - return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId) - end - -- due facce - elseif Proc.Fct == 2 then - -- verifico se da lavorare con testa da sotto - local bDownHead = TestTwoFacesDownHead( Proc) - -- determino se due facce lunghe oppure una lunga e l'altra terminale - local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD) - local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD) - if abs( b3Fac1:getDimX() - b3Fac2:getDimX()) < 50 then - -- leggo i parametri Q per utilizzare la fresa di fianco e/o lama - return Long2Cut.Make( Proc, _nPhase, _nRawId, _nPartId, Q_ANTISPLINT_TYPE == 1, Q_SIDE_ROUGH_TOOL) - elseif b3Fac1:getDimX() < 1 or b3Fac2:getDimX() < 1 then - -- la faccia 0 deve essere quella lunga - if b3Fac1:getDimX() < 1 then EgtSurfTmSwapFacets( Proc.Id, 0, 1) end - if bUseBlade then - if nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then - return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) - else - return Fbs.MakeTwo( Proc, _nPhase, _nRawId, _nPartId, _dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead) - end - else - return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId) - end - else - if bUseBlade then - return Fbs.MakeTwo( Proc, _nPhase, _nRawId, _nPartId, _dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead) - else - return MakeLongFaces( Proc, MakeTwoFaces) - end - end - -- tre facce - elseif Proc.Fct == 3 then - -- determino se due facce lunghe oppure una lunga e l'altra terminale - local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD) - local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD) - local b3Fac3 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 2, GDB_BB.STANDARD) - local bApplyBladeOnLongNotContinueFace - - if b3Fac1:getDimX() < 1 and b3Fac3:getDimX() < 1 then - -- la faccia 0 deve essere quella lunga - EgtSurfTmSwapFacets( Proc.Id, 0, 1) - bApplyBladeOnLongNotContinueFace = true - elseif b3Fac1:getDimX() < 1 and b3Fac2:getDimX() < 1 then - -- la faccia 0 deve essere quella lunga - EgtSurfTmSwapFacets( Proc.Id, 0, 2) - bApplyBladeOnLongNotContinueFace = true - elseif b3Fac2:getDimX() < 1 and b3Fac3:getDimX() < 1 then - bApplyBladeOnLongNotContinueFace = true - end - - if bApplyBladeOnLongNotContinueFace and bUseBlade and nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then - return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) - else - return MakeLongFaces( Proc, MakeThreeFaces) - end - -- 4 o 5 facce - else - return MakeLongFaces( Proc, MakeMoreFaces) - end - -- altrimenti lavorazione unica - else - -- una faccia - if Proc.Fct == 1 then - -- se piccola, con fresa - if not bUseBlade and ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then - return MakeOneFaceByMill( Proc) - -- altrimenti, con lama - else - return Cut.Make( Proc, _nPhase, _nRawId, _nPartId, _dOvmHead) - end - -- due facce - elseif Proc.Fct == 2 then - -- se praticamente è lunga come la trave - if Proc.Box:getDimX() > 0.8 * _b3Solid:getDimX() then - return Long2Cut.Make( Proc, _nPhase, _nRawId, _nPartId, bUseBlade, Q_SIDE_ROUGH_TOOL) - -- altrimenti - else - -- verifico se da lavorare con testa da sotto - local bDownHead = TestTwoFacesDownHead( Proc) - if BD.DOWN_HEAD then - 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 vtNm = ( vtN[1] + vtN[2]) - vtNm:normalize() - bDownHead = ( vtNm:getZ() < -0.5) - end - -- determino l'angolo tra le facce - local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) - -- se ortogonali e non forzata lama oppure con testa da sotto, con fresa - if ( not bUseBlade or bDownHead) and bAdj and abs( dAng + 90) < 1 then - -- se piccole - if Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN) then - return MakeTwoFacesByMill( Proc, bDownHead) - else - return MakeTwoFaces( Proc, true) - end - -- altrimenti, con lama - else - -- verifico se due facce o L con una o due facce di terminazione - local _, bIsL = TestUL( Proc) - if bIsL and _nChamfer > 0 then - local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc) - local nOk, sErr = MakeChamfer( Proc, vtOrtho, _b3Solid, nSurfInt) - if nOk < 0 then return false, sErr end - end - return Fbs.MakeTwo( Proc, _nPhase, _nRawId, _nPartId, _dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead) - end - end - -- tre facce - elseif Proc.Fct == 3 then - return MakeThreeFaces( Proc, true) - -- 4 o 5 facce - else - return MakeMoreFaces( Proc, true) - end - end -end - ---------------------------------------------------------------------- -return ProcessLapJoint \ No newline at end of file