diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index ec1df78..1179294 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -7,6 +7,7 @@ -- 2020/02/10 Aggiunta gestione FrenchRidgeLap -- 2020/02/11 Aggiunta gestione BlockHausFront -- 2020/04/02 Fori di testa dal basso non danno errore e fanno ribaltare la trave. +-- 2020/04/07 Aggiunta gestione TyroleanDovetail -- Tabella per definizione modulo local BeamExec = {} @@ -58,6 +59,8 @@ _G.package.loaded.ProcessFrenchRidgeLap = nil local FrenchRidgeLap = require( 'ProcessFrenchRidgeLap') _G.package.loaded.ProcessBlockHausFront = nil local BlockHausFront = require( 'ProcessBlockHausFront') +_G.package.loaded.ProcessTyroleanDovetail = nil +local TyroleanDovetail = require( 'ProcessTyroleanDovetail') _G.package.loaded.ProcessTenon = nil local Tenon = require( 'ProcessTenon') _G.package.loaded.ProcessMortise = nil @@ -521,8 +524,8 @@ local function ClassifyFeatures( vProc, b3Raw, Stats) -- se mezzo-legno di testa elseif RidgeLap.Identify( Proc) then bOk, bDown = RidgeLap.Classify( Proc) - -- se fessura, fessura frontale, tacca, tacca cantonale, mezzo-legno, scanalatura-battuta, - -- mezzolegno tipo chalet-tavoa di chiusura, rivestimento, mezzolegno chalet, tasca, taglio a triangolo + -- se scanalatura, scanalatura frontale, tacca, tacca cantonale, mezzo-legno, scanalatura-battuta, + -- mezzolegno tipo chalet-tavola di chiusura, rivestimento, mezzolegno chalet, tasca, taglio triangolato elseif LapJoint.Identify( Proc) then bOk, bDown = LapJoint.Classify( Proc) -- se foratura @@ -538,6 +541,9 @@ local function ClassifyFeatures( vProc, b3Raw, Stats) -- se block house front elseif BlockHausFront.Identify( Proc) then bOk, bDown = BlockHausFront.Classify( Proc) + -- se incastro tirolo + elseif TyroleanDovetail.Identify( Proc) then + bOk, bDown = TyroleanDovetail.Classify( Proc) -- se mortasa (anche frontale) elseif Mortise.Identify( Proc) then bOk, bDown = Mortise.Classify( Proc) @@ -672,8 +678,9 @@ local function AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, b3 elseif RidgeLap.Identify( Proc) then -- esecuzione mezzo-legno di testa bOk, sErr = RidgeLap.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) - -- se mezzo-legno ( 3/4-030-X) o scanalatura ( 3/4-016-X) o tacca ( 3/4-020-X) - -- o block house ( 4-037-X) + -- se fessura ( 3/4-016-X) o se fessura frontale ( 3/4-017-X) o se tacca ( 3/4-020-X) o se tacca cantonale ( 3/4-025-X) + -- o se mezzo-legno ( 3/4-030-X) o se scanalatura/battuta ( 3/4-032-X) o se mezzo legno tipo chalet/tavola di chiusura ( 3/4-033-X) + -- o se rivestimento ( 3/4-034-X) o se mezzolegno chalet ( 4-037-X) o se tasca ( 4-039-X) o se taglio triangolato ( 4-120-X) elseif LapJoint.Identify( Proc) then -- esecuzione mezzo-legno o scanalatura bOk, sErr = LapJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) @@ -693,6 +700,9 @@ local function AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, b3 elseif BlockHausFront.Identify( Proc) then -- esecuzione giunzione francese bOk, sErr = BlockHausFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se incastro tirolo ( 1/2/3/4-136-X) + elseif TyroleanDovetail.Identify( Proc) then + bOk, sErr = TyroleanDovetail.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se tenone ( 1/2-050-X) elseif Tenon.Identify( Proc) then -- esecuzione tenone diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua index e85a50d..d66b097 100644 --- a/LuaLibs/BeamLib.lua +++ b/LuaLibs/BeamLib.lua @@ -1,4 +1,4 @@ --- BeamLib.lua by Egaltech s.r.l. 2020/04/04 +-- BeamLib.lua by Egaltech s.r.l. 2020/04/14 -- Libreria globale per Travi -- Tabella per definizione modulo @@ -359,9 +359,18 @@ function BeamLib.GetFaceElevation( nSurfId, nFac, nPartId) end --------------------------------------------------------------------- -function BeamLib.GetFaceWithMostAdj( nSurfId, nPartId, bCompare3Fc) +function BeamLib.GetFaceWithMostAdj( nSurfId, nPartId, bCompare3Fc, dSinAngleUSquare) -- recupero il numero di facce local nFacCnt = EgtSurfTmFacetCount( nSurfId) + local dSinAngUsq + local bNotCheckUsq + if not dSinAngleUSquare then + dSinAngUsq = -0.05 + elseif dSinAngleUSquare == -2 then + bNotCheckUsq = true + else + dSinAngUsq = dSinAngleUSquare + end -- recupero le normali delle facce local vvtN = {} for i = 1, nFacCnt do @@ -383,7 +392,7 @@ function BeamLib.GetFaceWithMostAdj( nSurfId, nPartId, bCompare3Fc) end end vAdj[i] = nCount - -- ne determino eventuale sottosquadra (- 3deg) e ortogonalità + -- ne determino eventuale sottosquadra ( dal valore passato o - 3deg) e ortogonalità local bUcut = false local bOrto = false for j = 1, #vFacAdj do @@ -391,7 +400,7 @@ function BeamLib.GetFaceWithMostAdj( nSurfId, nPartId, bCompare3Fc) local vtN = vvtN[i] local vtN2 = vvtN[vFacAdj[j]+1] local dResV = vtN * vtN2 - if dResV < -0.05 then + if not bNotCheckUsq and dResV < dSinAngUsq - GEO.EPS_SMALL then bUcut = true elseif abs(dResV) < GEO.EPS_SMALL then bOrtho = true diff --git a/LuaLibs/ProcessLapJoint.lua b/LuaLibs/ProcessLapJoint.lua index 56a7a67..acf2a16 100644 --- a/LuaLibs/ProcessLapJoint.lua +++ b/LuaLibs/ProcessLapJoint.lua @@ -1,4 +1,4 @@ --- ProcessLapJoint.lua by Egaltech s.r.l. 2020/04/07 +-- ProcessLapJoint.lua by Egaltech s.r.l. 2020/04/09 -- Gestione calcolo mezzo-legno per Travi -- 2019/10/08 Agg. gestione OpenPocket. @@ -1727,7 +1727,7 @@ local function MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw) end --------------------------------------------------------------------- -local function EvaluateQParam( Proc, nRawId, bMakeVertCham, sDephtCham, sOnlyCham, sUseBlade) +local function EvaluateQParam( Proc, bMakeVertCham, sDephtCham, sOnlyCham, sUseBlade) local nChamfer = 0 local bForceUseBlade = false local sErr @@ -2403,13 +2403,28 @@ local function CheckDiamToolByFaces( Proc, nFacInd, dH, dV, bIsU, bIsL, dElev) return false end local bUseMaxDist = true + local dLargeVal + local dDelta = 100000 for i = 1, #tDistAdj do - -- se trovo una lunghezza di adiacenza sul lato lungo e diametro minimo inferiore di quello massimo trovato - -- setto di non utilizzare il diametro massimo - if tDistAdj[i] > dMaxLenFace - 20 * GEO.EPS_SMALL and dDiam < dMaxDiam + 10 * GEO.EPS_SMALL then - bUseMaxDist = false + local dDeltadH = abs( tDistAdj[i] - dH) + local dDeltadV = abs( tDistAdj[i] - dV) + if dDeltadH < dDeltadV then + if dDeltadH < dDelta + 10 * GEO.EPS_SMALL then + dDelta = dDeltadH + dLargeVal = dV + end + else + if dDeltadV < dDelta + 10 * GEO.EPS_SMALL then + dDelta = dDeltadV + dLargeVal = dH + end end end + -- se diametro massimo inferiore della larghezza faccia + -- setto di non utilizzare il diametro massimo + if dMaxDiam > dLargeVal + 20 * GEO.EPS_SMALL then + bUseMaxDist = false + end if bUseMaxDist then return dMaxDiam, 'OpenPocket', 1 end @@ -2779,7 +2794,7 @@ local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, bSingle_part) end -- verifico se sono presenti i parametri Q per la profondità smusso e -- per eseguire in esclusiva solo lo smusso - local nChamfer, dDepthCham, sErrCham, bForceUseBlade = EvaluateQParam( Proc, nRawId, false, sDepthChamferMill, sPreemptiveChamfer, sForceUseBlade) + local nChamfer, dDepthCham, sErrCham, bForceUseBlade = EvaluateQParam( Proc, false, sDepthChamferMill, sPreemptiveChamfer, sForceUseBlade) -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer -- genero errore e non faccio nulla if nChamfer < 0 then diff --git a/LuaLibs/ProcessTyroleanDovetail.lua b/LuaLibs/ProcessTyroleanDovetail.lua new file mode 100644 index 0000000..9ae7f2a --- /dev/null +++ b/LuaLibs/ProcessTyroleanDovetail.lua @@ -0,0 +1,831 @@ +-- ProcessTyroleanDovetail.lua by Egaltech s.r.l. 2020/04/14 +-- Gestione calcolo giunzione tirolese + +-- Tabella per definizione modulo +local ProcessTyroleanDovetail = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTyroleanDovetail started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sForceUseBlade = '' -- i +local sDepthChamferMill = '' -- d +local sPreemptiveChamfer = '' -- i +local sUseMill = '' -- i +local sUseRoughTool = '' -- i +local sUseRoughToolWithBAxis90 = '' -- i +local sUseRoughToolWithBAxis0 = '' -- i +local sInsertBoreOnCorner = '' -- 1 +local sMakeContourWithSmallTool = '' -- i +local sMakeOnlyContourOrFullPocket = '' -- i +local sMakeBySideRoughTool = '' -- i +local sAntisplintMode = '' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessTyroleanDovetail.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 136) +end + +--------------------------------------------------------------------- +local function AssignQValues( Proc) + + -- reset delle variabili assegnazione parametri Q + sForceUseBlade = '' + sDepthChamferMill = '' + sPreemptiveChamfer = '' + sUseMill = '' + sUseRoughTool = '' + sUseRoughToolWithBAxis90 = '' + sUseRoughToolWithBAxis0 = '' + sInsertBoreOnCorner = '' + sMakeContourWithSmallTool = '' + sMakeOnlyContourOrFullPocket = '' + sMakeBySideRoughTool = '' + sAntisplintMode = '' + + if Proc.Prc == 136 then + sDepthChamferMill = 'Q01' -- d + end +end + +--------------------------------------------------------------------- +local function TestElleShape3( Proc) + -- valida solo nel caso di tre facce + if Proc.Fct ~= 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 + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + if nCount == 1 then + bIsL = false + break + end + end + return bIsL +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessTyroleanDovetail.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + local nFlatFaceNeg + local bDown = false + -- individuo se c'è faccia rastremata verso Z- + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < -1 + GEO.EPS_SMALL then + nFlatFaceNeg = i-1 + break + end + end + -- se trovata faccia rastremata rivolta verso Z- + -- verifico se lunghezza faccia piatta è compatibile con il taglio di lama + if FlatFaceNeg then + -- se ho 3 facce sicuramente è gruppo 3 o 4, setto il ribaltamento senza ulteriori controlli + if nFacetCnt == 3 then + bDown = true + -- altrimenti faccio controllo di lavorabilità da sotto e setto eventuale ribaltamento + -- ( può essere gruppi 1 o 2, oppure gruppo 3 o 4 ma spostati verso le teste) + else + -- prendo le dimensioni della faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFlatFaceNeg, GDB_ID.ROOT) + local nOtherFace = EgtIf( nFlatFaceNeg == 0, nFlatFaceNeg + 1, nFlatFaceNeg - 1) + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFlatFaceNeg, nOtherFace, GDB_ID.ROOT) + local dDist = dist( ptP1, ptP2) + local dLenface + -- se non sono uguali prendo la dimensione diversa dalla lunghezza di adiacenza + if abs( dDist - dH) < 10 * GEO.EPS_SMALL then + dLenface = dV + else + dLenface = dH + end + -- se lunghezza faccia maggiore di taglio lama da sotto setto il ribaltamento + if dLenface > BD.MAX_LEN_RIDGELAP_FROM_BOTTOM - 10 * GEO.EPS_SMALL then + bDown = true + end + -- se angolo tra le facce è maggiore di 90 non è raggiungibile dalla lama setto il ribaltamento + if dAng < 0 and dAng > -90 + 5 * GEO.EPS_SMALL then + bDown = true + end + end + -- altrimenti controllo la componente in Z delle facce + else + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- altrimenti se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, + -- considerazioni: al momento non è possibile sapere se ci sono due rastremature o una quindi se è rivolta verso il basso + -- viene dato errore, altrimenti si potrebbe imporre la rotazione di 180 (ovviamente con una sola rastrematura rivolta verso il basso) + if abs(vtN:getZ()) > abs(vtN:getX()) and abs(vtN:getZ()) > abs(vtN:getY()) and vtN:getZ() < -0.5 then + return false + end + end + end + return true, bDown +end + +--------------------------------------------------------------------- +local function EvaluateQParam( Proc, sDephtCham) + local nChamfer = 0 + local bForceUseBlade = false + local sErr + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + + return nChamfer, dDepth +end + +--------------------------------------------------------------------- +local function MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- recupero la geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- ordino le facce (1=faccia ausiliaria, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + local dMinZedFace = 1 + for i = 1, nFacetCnt do + if abs( vtN[i]:getX()) < dMinZedFace then + dMinZedFace = abs( vtN[i]:getX()) + vFaceOrd[3] = i + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead + if vtN[vFaceOrd[2]] then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + else + if AuxId then + local vtNx = EgtSurfTmFacetNormVersor( AuxId, 0, GDB_ID.ROOT) + bHead = ( vtNx:getX() > 0) + end + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- cerco se nelle note del layer c'è già la nota che indica che l'aux è già stato lavorato + local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), 'b') + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, Head = Proc.Head, Tail = Proc.Tail} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then + dTrim = 0 + else + dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + end + local dFinalExtraTrim = 0.1 + local dMiddleExtraTrim = 0.3 + local dNullExtraTrim = 0 + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + local dExtraTrim = 0 + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo + -- cioè non i tagli intermedi, aggiungo extratrim minimo + if ( ( i == (#vCuts-1)) or ( i == #vCuts)) and j == #vCuts[i] then + dExtraTrim = dFinalExtraTrim + -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim + elseif i < (#vCuts-1) or (i == #vCuts) then + dExtraTrim = dNullExtraTrim + -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim + else + dExtraTrim = dMiddleExtraTrim + end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -(dTrim+dExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, Head = Proc.Head, Tail = Proc.Tail} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head and AuxId then + local dHCI = 00 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + -- altrimenti di fianco + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail and AuxId then + local dTCI = 0 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + -- altrimenti di fianco + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--[[ +--------------------------------------------------------------------- +local function MakePocket( Proc, nPartId, ptPs, tvtN, nFaceRef, sMchFind, sMasterPocket, dPrevFaceElev, sPrefixName, 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 on process ' .. tostring( Proc.Id) .. ' pocketing 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 = sPrefixName .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. 'F' .. tostring( nFaceRef) + 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, (nFaceRef)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- 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 opportuno attacco + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn +-- if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then +-- EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dElev) +-- dElev = dMaxDepth +-- sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth' +-- EgtOutLog( sWarn) +-- end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, sWarn, sTuuidPk, dDiamTool +end +]]-- + +--------------------------------------------------------------------- +local function MakeMillCut( Proc, i, j, k, sMilling, nFacInd, pPPnt, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep) + local sWarn = '' + -- inserisco la lavorazione di fresatura + -- per evitare nomi lavorazioni coincidenti, concateno anche il Proc.Id se il nome (del Proc.Id) è presente + local s2ndName = EgtGetName( Proc.Id) or '' + local sName = 'MillTCone_' .. ( EgtIf( #s2ndName > 0, s2ndName, tostring( Proc.Id))) .. ( EgtIf( #s2ndName > 0, '_' .. tostring( Proc.Id), '')) .. '_' .. tostring(i) .. '_' .. tostring(j) + local kStep = k or 0 + if kStep > 0 then + sName = sName .. '_' .. tostring(k) + end + 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, nFacInd}}) + -- imposto uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite( pPPnt[j][1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + if kStep % 2 == 1 then + -- imposto lato destro + EgtSetMachiningParam( MCH_MP.WORKSIDE, 2) + -- imposto inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + -- imposto lato sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + -- tolgo inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + -- imposto affondamento in base al passo del ciclo + EgtSetMachiningParam( MCH_MP.DEPTH, dOffs) + --imposto passo 0 + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- imposto offset radiale in base all'angolo tra le due facce e alla posizione in Z + il passo laterale + dOffrRad = dOffrRad + dAddOffsRad + -- per le passate intermedie aggiungo un delta sull'offset radiale perchè c'è già il taglio di lama precedente + EgtSetMachiningParam( MCH_MP.OFFSR, dOffrRad + EgtIf( ( i < nStep) and ( kStep < 1), 0.5, 0)) + -- imposto offset longotudinale a 0 + EgtSetMachiningParam( MCH_MP.OFFSL, 0) + -- imposto gli attacchi + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, ( dToolDiam * 0.75)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( dToolDiam * 0.75)) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill solo in ultima passata in Z locale + local sUserNotes + if i < nStep then + sUserNotes = 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + else + sUserNotes = 'VMRS=0;' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + _, sWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + + local sWarn = '' + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- recupero l'angolo di spoglia dell'utensile a tronco di cono + -- recupero la lavorazione + local sMchFind = 'ProfTCone' + local sMilling = ML.FindMilling( sMchFind) + if not sMilling then + local sErr = 'Milling not found in library : Error on TyroleanDovetail ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 100 + local dMaxMat = 50 + local dSideAngle = 0 + local dStepmach = 0 + local bUCutMax + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle + -- ottengo il passo della lavorazione + dStepmach = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) + end + end + if dStepmach <= 0.1 then + dStepmach = dMaxMat * 0.5 + end + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, sin(dSideAngle)) + if not nFacInd or nFacInd < 0 then + -- provo eliminando i sottosquadra + nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, -2) + if not nFacInd or nFacInd < 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MakeMachByMill could not find reference face' + EgtOutLog( sErr) + return false, sErr + else + bUCutMax = true + end + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sErrCham = EvaluateQParam( Proc, sDepthChamferMill) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico se U + 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)) + -- faccio tagli di lama come antischeggia sulle altre 2 facce + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN:getY(), vtN:getZ()) + vtRef:normalize() + local pPPnt = {} + -- ciclo inserimento tagli antischeggia sulle facce + for i = 1, nFacetCnt do + if (i-1) ~= nFacInd then + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, (i-1), GDB_ID.ROOT) + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT) + if dAng then + pPPnt[i] = { vtN2, dAng, dist( ptP1, ptP2)} + end + if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then + dTrim = 0 + else + dTrim = ((dToolThick* vtN) * vtN2 * vtN2):len() + end + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, (i-1), sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + 1), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + -- creo percorsi di lavorazione +-- local nCountSkipStep = 0 +-- local nMaxSkippedStep = 0 + local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dStepmach) + local dStep = dFacElev / nStep + local dLargeVal + local nLenSideMax + for i = 1, nStep do + local dOffs = ( i * dStep) - dFacElev + if i == nStep then dOffs = 0 end + local dOffsSide = 0 + local dDelta = 100000 + for j = 1, nFacetCnt do + if (j-1) ~= nFacInd then + local dParzElev = dOffs + -- calcolo la larghezza (solo 1 volta) + if i == 1 then + -- se ho un sottosquadra maggiore dell'angolo di spoglia utensile + if bUCutMax and ( 90 + pPPnt[j][2]) < dSideAngle then + dParzElev = dFacElev + end + local dDeltadH = abs( pPPnt[j][3] - dH) + local dDeltadV = abs( pPPnt[j][3] - dV) + if dDeltadH < dDeltadV then + if dDeltadH < dDelta + 10 * GEO.EPS_SMALL then + dDelta = dDeltadH + dLargeVal = dV + nLenSideMax = j + end + else + if dDeltadV < dDelta + 10 * GEO.EPS_SMALL then + dDelta = dDeltadV + dLargeVal = dH + nLenSideMax = j + end + end + end + -- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo) + dOffsSide = dOffsSide + ( tan( 90 + pPPnt[j][2]) * dParzElev) + end + end + -- se la larghezza è più grande dell'utensile allora posso lavorare il passo + if ( dLargeVal - dOffsSide) >= dToolDiam then + -- resetto il contatore skip +-- nCountSkipStep = 0 + for j = 1, nFacetCnt do + if (j-1) ~= nFacInd then + -- calcolo l'offset radiale in base all'affondamento + local dOffrRad = ( tan( 90 + pPPnt[j][2]) * dOffs) + if bUCutMax and ( 90 + pPPnt[j][2]) < dSideAngle then + dOffrRad = -( tan( 90 + pPPnt[j][2]) * dFacElev) + end + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, nFacInd, pPPnt, rfFac, dOffs, dOffrRad, 0, nStep, dToolDiam, dStep) + if not bOk then + return false, sErr + else + sWarn = sErr + end + -- se lato lavorato è il più lungo e la larghezza cava consente passi interni + if j == nLenSideMax and ( dLargeVal - dOffsSide) > 2*dToolDiam then + local nStepSide = ceil( ( ( dLargeVal - dOffsSide - ( 2 * dToolDiam)) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5) + local dStepSide = ( dLargeVal - dOffsSide - ( 2 * dToolDiam)) / nStepSide + for k = 1, nStepSide do + local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0) + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling, nFacInd, pPPnt, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep) + if not bOk then + return false, sErr + else + sWarn = sErr + end + end + end + end + end + -- altrimenti passo saltato esco con errore + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' + EgtOutLog( sErr) + return false, sErr + end + end + + -- se ho saltato più di un passo invalido le lavorazioni +-- if nMaxSkippedStep >= 2 or ( nStep >= nMaxSkippedStep and nMaxSkippedStep >= 1) then +-- local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' +-- EgtOutLog( sErr) +-- return false, sErr +-- end + + -- recupero la lavorazione + --local dCollSic = 2 * BD.COLL_SIC + --if abs( vtN:getX()) > 0.996 or abs( vtN:getY()) > 0.996 or abs( vtN:getZ()) > 0.996 then dCollSic = 0 end + --local dDiam = min( dH, dV) + --sMchFind = 'OpenPocketTCone' + --local sPocketing = ML.FindPocketing( sMchFind, dDiam, dFacElev + dCollSic) + ---- se non trova una svuotatura adatta emetto un warning + --if not sPocketing then + -- local sWarn = 'Warning on process ' .. tostring( Proc.Id) .. ' not found any pocket or tool' + -- EgtOutLog( sErr) + -- return false, sErr + --end + ---- eseguo la svuotatura della faccia principale + --local tvtNx = {} + --tvtNx[2] = vtN + --local bOk, sWarn = MakePocket( Proc, nPartId, ptC, tvtNx, nFacInd, sMchFind, sPocketing, dFacElev, 'PockTCone') + --if not bOk then return false, sWarn end + return true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessTyroleanDovetail.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + -- se ho due facce allora è di testa + if nFacetCnt == 2 then + return MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + else + return MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + end + + return true +end + +--------------------------------------------------------------------- +return ProcessTyroleanDovetail