Files
DataBeam/LuaLibs/ProcessLapJoint.lua
T
Dario Sassi 02c399eaa0 DataBeam :
- scorporato in Beam e BeamWall.
2020-04-09 08:00:11 +00:00

3358 lines
154 KiB
Lua

-- ProcessLapJoint.lua by Egaltech s.r.l. 2020/04/06
-- Gestione calcolo mezzo-legno per Travi
-- 2019/10/08 Agg. gestione OpenPocket.
-- Tabella per definizione modulo
local ProcessLapJoint = {}
-- Include
require( 'EgtBase')
local BL = require( 'BeamLib')
local Cut = require( 'ProcessCut')
local DoubleCut = require( 'ProcessDoubleCut')
local LongCut = require( 'ProcessLongCut')
local Long2Cut = require( 'ProcessLongDoubleCut')
local Fbs = require( 'FacesBySaw')
EgtOutLog( ' ProcessLapJoint 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
-- Settaggi interni
local bTrySidePocketAtFirst = true
---------------------------------------------------------------------
-- 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 delle variabili assegnazione parametri Q
sForceUseBlade = ''
sDepthChamferMill = ''
sPreemptiveChamfer = ''
sUseMill = ''
sUseRoughTool = ''
sUseRoughToolWithBAxis90 = ''
sUseRoughToolWithBAxis0 = ''
sInsertBoreOnCorner = ''
sMakeContourWithSmallTool = ''
sMakeOnlyContourOrFullPocket = ''
sMakeBySideRoughTool = ''
sAntisplintMode = ''
if ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16 then
sForceUseBlade = 'Q01' -- i
sDepthChamferMill = 'Q04' -- d
sPreemptiveChamfer = 'Q05' -- i
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17 then
sDepthChamferMill = 'Q01' -- d
sPreemptiveChamfer = 'Q02' -- i
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20 then
sDepthChamferMill = 'Q01' -- d
sUseMill = 'Q02' -- i
sUseRoughTool = 'Q03' -- i
sUseRoughToolWithBAxis90 = 'Q04' -- i
sUseRoughToolWithBAxis0 = 'Q05' -- i
sInsertBoreOnCorner = 'Q06' -- i
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25 then
sInsertBoreOnCorner = 'Q01' -- i
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then
sMakeContourWithSmallTool = 'Q01' -- i
sMakeOnlyContourOrFullPocket = 'Q02' -- i
sMakeBySideRoughTool = 'Q03' -- i
sAntisplintMode = 'Q06' -- i
sDepthChamferMill = 'Q07' -- d
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32 then
sMakeBySideRoughTool = 'Q01' -- i
end
-- le altre features gestite non hanno parametri Q nei parametri globali
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
---------------------------------------------------------------------
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 bIsL = false
local dMinArea3 = GEO.INFINITO
local dMaxArea2 = 0
for i = 1, 4 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
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, i - 1, GDB_ID.ROOT)
local dArea = dH * dV
if nCount == 2 then
dMaxArea2 = max( dMaxArea2, dArea)
elseif nCount == 3 then
dMinArea3 = min( dMinArea3, dArea)
bIsL = true
end
end
if not bIsL then return false end
-- verifico se L profona oppure lunga
if dMinArea3 < dMaxArea2 then
return 1
else
return 2
end
end
---------------------------------------------------------------------
local function VerifySawChain( Proc, dMinDim, dMaxDim, vtOrtho)
local bUseSawChain = 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 bUseSawChain
else
-- recupero i dati dell'utensile
local dToolLength = 0
local dSawWidth = 75
if EgtMdbSetCurrMachining( sSawing) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth
dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick
dSawCornerRad = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) or dSawCornerRad
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
end
if dSawThick <= dMinDim and dSawWidth <= dMaxDim then
bUseSawChain = true
end
end
end
return bUseSawChain, sSawing, dMaxMat, dSawCornerRad, dSawThick, dMaxDepth
end
---------------------------------------------------------------------
local function VerifyIfPocket( Proc, dDiam, vtOrtho, sMchFindMaster)
local bUsePocketing = false
local sMchFind = 'Pocket'
if sMchFindMaster and #sMchFindMaster > 0 then
sMchFind = sMchFindMaster
end
-- local dCollSic = 2 * BD.COLL_SIC
-- if abs( vtOrtho:getX()) > 0.996 or abs( vtOrtho:getY()) > 0.996 or abs( vtOrtho:getZ()) > 0.996 then dCollSic = BD.COLL_SIC end
local sPocketing = ML.FindPocketing( sMchFind, dDiam)
local dMaxMat = 0
-- se non trova una svuotatura adatta
if not sPocketing then
return bUsePocketing
else
-- recupero i dati dell'utensile
if EgtMdbSetCurrMachining( sPocketing) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
end
bUsePocketing = true
end
end
return bUsePocketing, sPocketing, dMaxMat
end
---------------------------------------------------------------------
local function VerifyIfByBHSideMill( Proc)
local bUseBHSideMill = false
local bHead = true
local sMilling
local dMaxMat = 10
-- se non abilitato parametro Q per lavorarlo di fianco esco
local nUseSideTol = EgtGetInfo( Proc.Id, sMakeBySideRoughTool, 'i') or 0
if nUseSideTol == 0 then
return false
end
-- verifico se U
local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc))
-- se U e lunghezza non richiede spezzatura
if bIsU and Proc.Box:getDimX() <= BD.LONGCUT_MAXLEN then
-- recupero la lavorazione
sMilling = ML.FindMilling( 'BHSideMill')
if sMilling then
-- recupero i dati dell'utensile
local dToolLength = 0
local dMaxDepth = 0
if EgtMdbSetCurrMachining( sMilling) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
end
end
-- verifico se la feature è abbastanza vicino a testa/coda da permettere la lavorazione con questo utensile
-- recupero l'ingombro della trave
local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL)
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
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
bHead = ( dMaxT - dMinXF) < ( dMaxXF - dMinT)
-- determino se è compatibile con il massimo affondamento dell'utensile
bUseBHSideMill = EgtIf( bHead, (dMaxT - dMinXF), (dMaxXF - dMinT)) < dMaxDepth
end
end
end
return bUseBHSideMill, bHead, sMilling, dMaxMat
end
---------------------------------------------------------------------
local function GetTunnelDimension( Proc, nPartId)
-- ottengo i versori delle 4 facce e ottengo l'orientamento del tunnel
-- recupero il numero di facce
local nFacCnt = EgtSurfTmFacetCount( Proc.Id)
-- recupero l'ingombro della trave
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
-- variabili dimensioni fessura e id faccia lunga
local dDimMin
local dDimMax
local nLongIdFace = 0
-- ottengo il versore ortogonale
local ptN1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
local vtOrtho = vtN1 ^ vtN2
if vtOrtho:isSmall() then
_, vtN2 = EgtSurfTmFacetCenter( Proc.Id, 2, GDB_ID.ROOT)
vtOrtho = vtN1 ^ vtN2
end
-- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta la profondità della fessura
local frFc = Frame3d( ptN1, vtOrtho) ;
local bBoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc)
local dDepth = bBoxLoc:getDimZ()
-- 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
-- mi assicuro che la Z del punto utilizzato per creare la superfic sia alla Z media del bounding box locale
local ptN2 = Point3d(ptN1)
ptN2:toLoc(frFc)
ptN2 = Point3d( ptN2:getX(), ptN2:getY(), ( bBoxLoc:getMin():getZ() + bBoxLoc:getMax():getZ())/2)
ptN2:toGlob(frFc)
-- creeo superfice intermedia
local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN2, vtOrtho, b3Solid, GDB_ID.ROOT)
-- ritaglio la superfici con le facce della fessura
for i = 1, nFacCnt do
local ptN, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT)
EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT)
end
local _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT)
dDimMin = min( DimH, DimV)
dDimMax = max( DimH, DimV)
_, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacCnt-1, GDB_ID.ROOT)
-- se faccia pari alla larghezza fessura
if abs(DimH - dDimMax) < GEO.EPS_SMALL or abs(DimV - dDimMax) < GEO.EPS_SMALL then
nLongIdFace = nFacCnt-1
-- altrimenti faccia pari allo spessore fessura
else
nLongIdFace = nFacCnt-2
end
if not dDimMax then
return dDimMin, dDimMax, dDepth, nil, nil
end
return dDimMin, dDimMax, dDepth, vtOrtho, nLongIdFace, nSurfInt
end
---------------------------------------------------------------------
-- Verifica se feature di testa
function ProcessLapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH)
-- 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 ora è sicuramente di testa
if Proc.Fct <= 2 then
return true
end
-- deve avere la normale principale diretta verso la testa
local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL)
local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
if vtN:getZ() < BD.NZ_MINA and nFacInd2 then
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
nFacInd, nFacInd2 = nFacInd2, nFacInd
end
if 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)
-- 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
-- in base al tipo di feature attribuisco il significato dei parametri Q
AssignQValues( Proc)
-- se può essere fatto con utensile tipo lama
local bUseBHSideMill, bHead = VerifyIfByBHSideMill( Proc)
if bUseBHSideMill then
return not bHead
end
-- verifico se è in coda
if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + 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
-- recupero identificativo del pezzo
local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL)
-- se due facce e interessa veramente la coda, allora di coda
if Proc.Fct <= 2 then
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
if Proc.Box:getMin():getX() < b3Solid:getMin():getX() + 1. then
return true
end
end
-- deve avere la normale principale diretta verso la coda
local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
if vtN:getZ() < BD.NZ_MINA and nFacInd2 then
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
nFacInd, nFacInd2 = nFacInd2, nFacInd
end
if vtN:getX() > -0.499 then
return false
else
return true
end
end
---------------------------------------------------------------------
-- Classificazione della feature
function ProcessLapJoint.Classify( Proc)
-- 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 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)
-- verifico se è lavorabile solo dal basso
local bSmall = ( ( Proc.Head or Proc.Tail) and Proc.Box:getDimX() < BD.MAX_LEN_RIDGELAP_FROM_BOTTOM) or
( not ( Proc.Head or Proc.Tail) and Proc.Box:getDimY() < BD.MAX_LEN_RIDGELAP_FROM_BOTTOM)
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))
return true, bDown
-- se più di 2 facce
else
local bClosedOrthoFaces
local nDeletedface
-- recupero la faccia con il maggior numero di adiacenze e minor elevazione
local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL)
local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
if not nFacInd or nFacInd < 0 then
if nFacInd == -1 then
bClosedOrthoFaces = nFacInd2
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
-- recupero gruppo per geometria addizionale
local nAddGrpId = BL.GetAddGroup( nPartId)
if not nAddGrpId then
return false
end
-- 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
nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( nNewProc, nPartId)
if not nFacInd or nFacInd < 0 then
if nFacInd == -1 then
bClosedOrthoFaces = nFacInd2
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
nFacInd = nDeletedface
-- rendo nulla la faccia opzionale perchè si tratta di una fessura
nFacInd2 = nil
dElev = BL.GetFaceElevation( Proc.Id, nFacInd)
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, nLundIdFace, nSurfInt = GetTunnelDimension( Proc, nPartId)
EgtErase(nSurfInt)
-- verifico se può essere fatto con svuotatura
if VerifyIfPocket( Proc, dDimMin, vtOrtho) then
return true, false
elseif VerifySawChain( Proc, dDimMin, dDimMax, vtOrtho) then
return true, false
else
return false
end
else
local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
-- se può essere fatto con utensile tipo lama
local bUseBHSideMill, _, _, dMaxMat = VerifyIfByBHSideMill( Proc)
if bUseBHSideMill and ( dMaxMat <= dV) then
return true, false
-- altrimenti controllo se deve essere ruotato con le altre lavorazioni
else
-- dati della faccia
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
-- verifico se è lavorabile solo dal basso
local bDown = ( vtN:getZ() < BD.NZ_MINA)
-- se verso il basso, verifico se utilizzabile seconda faccia
if bDown then
if nFacInd2 and dElev2 < 2 * dElev then
local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
bDown = ( vtN2:getZ() < BD.NZ_MINA)
end
end
return true, bDown
end
end
end
end
---------------------------------------------------------------------
-- Lavorazione con fresa
---------------------------------------------------------------------
local function MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId)
-- recupero l'ingombro del grezzo di appartenenza
local b3Raw = EgtGetRawPartBBox( nRawId)
-- recupero l'ingombro della trave
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') 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 il numero di facce della tacca
assert( ( Proc.Fct == 1), 'Error : MakeOneFaceByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces')
-- dati della faccia
local ptC, 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 on process ' .. tostring( Proc.Id) .. ' milling 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 EgtApplyMachining( 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 MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId)
-- recupero l'ingombro del grezzo di appartenenza
local b3Raw = EgtGetRawPartBBox( nRawId)
-- recupero l'ingombro della trave
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') 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 il numero di facce della tacca
assert( ( Proc.Fct == 2), 'Error : MakeTwoFacesByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces')
-- 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 bFaceOk[1] and not bFaceOk[2] then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' 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
-- recupero la lavorazione
local sMilling = ML.FindMilling( 'BirdsMouth')
if not sMilling then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling 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
local nFaceUse = BL.GetNearestOrthoOpposite( vtN[nOthInd+1])
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
-- imposto lato di correzione
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
-- 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 EgtApplyMachining( 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)
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()
BL.UpdateHCING( nRawId, dOffs, dDist)
end
end
return true
end
---------------------------------------------------------------------
local function MakePreCuts( Proc, nPhase, nRawId, nPartId, b3Raw, nChamfer)
-- 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
-- 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
-- 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}
local nCutFacet = EgtSurfTmFacetCount( AddId)
if nCutFacet == 1 then
return Cut.Make( CutProc, nPhase, nRawId, nPartId, 0)
elseif nCutFacet == 2 then
return DoubleCut.Make( CutProc, nPhase, nRawId, nPartId, 0)
end
end
end
return true
end
---------------------------------------------------------------------
local function MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dElev, bSpecialApp, sMillMaster, nFacInd2, dFacElev2)
-- Recupero le facce adiacenti alla principale
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
if not vAdj or #vAdj == 0 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' main face without adjacencies'
EgtOutLog( sErr)
return false, sErr
end
EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3)
-- Riordino le dimensioni per avere dH > dV
if dH < dV then
dH, dV = dV, dH
end
-- Cerco una faccia adiacente alla principale sul lato lungo
local nFacAdj
for i = 1, #vAdj do
if vAdj[i] >= 0 then
local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT)
local dLen = dist( ptP1, ptP2)
if dLen > 0.5 * dH then
nFacAdj = vAdj[i]
EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3)
break
end
end
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, ' ,'))
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] == nFacInd then
-- Se non esiste faccia adiacente a lato precedente -> inizio aperto
local i = EgtIf( j > 1, j - 1, #vAdj2)
while vAdj2[i] == 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] == 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
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library'
EgtOutLog( sErr)
return false, sErr
end
end
-- recupero i dati dell'utensile
local dTDiam = 50
local dMaxMat = 0
if EgtMdbSetCurrMachining( sMilling) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
end
end
-- Se massimo materiale utensile è molto inferiore dell'elevazione non faccio la lavorazione e do un warning
if dMaxMat > 0 and dMaxMat + 15 < dElev then
sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' ,skipped milling; elevation bigger than max tool depth'
return true, sWarn, dMaxMat
end
-- Calcolo uso faccia
local nFaceUse = BL.GetNearestParalOpposite( 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
local 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 rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then
nSCC = MCH_SCC.ADIR_YP
end
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- 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 == nFacInd2 then
if not bOpenStart then
EgtSetMachiningParam( MCH_MP.LOPERP, dFacElev2)
end
if not bOpenEnd then
EgtSetMachiningParam( MCH_MP.LIPERP, dFacElev2)
end
end
end
-- applico elevazione
local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 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 EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
return true, '', dTDiam
end
---------------------------------------------------------------------
local function ChooseCorner( Proc, nFacInd)
-- Recupero le facce adiacenti alla principale
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
local tFacAdj = {}
for i = 1, #vAdj do
if vAdj[i] >= 0 then
for j = 1, #vAdj do
if vAdj[j] >= 0 and j ~= i then
local bInsert = true
for k = 1, #tFacAdj do
local nFace1 = tFacAdj[k][1]
local nFace2 = tFacAdj[k][2]
if ( nFace1 == vAdj[i] and nFace2 == vAdj[j]) or
( nFace1 == vAdj[j] and nFace2 == vAdj[i]) then
bInsert = false
end
end
if bInsert then
local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vAdj[i], vAdj[j], GDB_ID.ROOT)
if ptP1 and ptP2 then
local dLen = dist( ptP1, ptP2)
table.insert( tFacAdj, { vAdj[i], vAdj[j], dLen, ptP1, ptP2, dAng})
end
end
end
end
end
end
-- tra le linee prendo quella 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 MakeContourCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam)
local sMyWarn = ''
local pAuxId = {}
local nAuxId
local AuxId
local ptApPoint
local sMilling
local dTrimDist
local dCollSic = BD.COLL_SIC
-- ottengo gli angoli dove applicare il percorso con fresa più piccola
local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd)
-- prendo il primo versore
local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
-- 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 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling from bottom '
EgtOutLog( sErr)
return false, sErr
end
-- ciclo su tutti gli angoli trovati
for i = 1, #tFacAdj do
sMyWarn = ''
-- le 2 facce di contatto devono essere perpendicolari o non sottossquadra rispetto alla faccia di fondo
-- e ra le due facce deve esserci un angolo interno
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 and 180 + dAng >= 90 - 10 * GEO.EPS_SMALL) and ( dAngx < 0 and 180 + dAngx >= 90 - 10 * GEO.EPS_SMALL) and ( tFacAdj[i][6] < 0) then
-- 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 nIdIniPoint
local nIdEndPoint
if ptP1 and ptP2 then
if ( dist( ptP1, tFacAdj[i][4]) < GEO.EPS_SMALL) or ( dist( ptP2, tFacAdj[i][4]) < GEO.EPS_SMALL) then
nIdEndPoint = 4
nIdIniPoint = 5
elseif ( dist( ptP1, tFacAdj[i][5]) < GEO.EPS_SMALL) or ( dist( ptP2, tFacAdj[i][5]) < GEO.EPS_SMALL) then
nIdEndPoint = 5
nIdIniPoint = 4
end
end
-- se ho il punto comune
if nIdEndPoint then
-- recupero la lavorazione con elevazione pari all'altezza trovata
sMilling = ML.FindMilling( 'LongSmallCut', tFacAdj[i][3] + dCollSic)
if sMilling then
-- recupero i dati dell'utensile
local dTDiam = 50
local dMaxMat = 0
if EgtMdbSetCurrMachining( sMilling) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
end
-- se il diametro trovato è minore della metà del diametro utilizzato in precendenza
if dTDiam < ( dDiam / 2) then
-- calcolo lunghezza minima in base all'angolo tra le due pareti
local dMinDist = (( dDiam / 2) / tan( ( 180 + tFacAdj[i][6]) / 2)) + 2
-- se entrambe le linee sono maggiori delle lunghezza minima proseguo
if dLen1 >= dMinDist and dLen2 >= dMinDist then
-- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro
if dist( tFacAdj[i][nIdEndPoint], ptP1) < 10 * GEO.EPS_SMALL then
ptApPoint = ptP2
else
ptApPoint = ptP1
end
-- prima linea
nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[i][nIdEndPoint], GDB_RT.GLOB)
-- calcolo arretramento
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
if dist( tFacAdj[i][nIdEndPoint], ptP1x) < 10 * GEO.EPS_SMALL then
ptApPoint = ptP2x
else
ptApPoint = ptP1x
end
-- 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
if #pAuxId > 0 then
AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true)
end
-- se c'è il percorso
if AuxId then
-- modifico versore direzione
EgtModifyCurveExtrusion( AuxId, vtN1, GDB_RT.GLOB)
-- inserisco la lavorazione
local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
local nMchId = EgtAddMachining( sName, sMilling)
if nMchId then
-- aggiungo geometria
EgtSetMachiningGeometry( {{ AuxId, -1}})
-- imposto posizione braccio porta testa
local nSCC = MCH_SCC.ADIR_YM
if vtN1:getY() > 100 * GEO.EPS_ZERO then
nSCC = MCH_SCC.ADIR_YP
end
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0)
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 4)
-- allungo inizio e fine di 0mm
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0)
-- setto affondamento 0
EgtSetMachiningParam( MCH_MP.DEPTH, 0)
-- setto non inversione del percorso
EgtSetMachiningParam( MCH_MP.INVERT, false)
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill
local sUserNotes = 'VMRS=0;'
-- aggiungo alle note massima elevazione
sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( tFacAdj[i][3], 1) .. ';'
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
if EgtApplyMachining( true, false) then
_, sMyWarn = EgtGetMachMgrWarning( 0)
if EgtIsMachiningEmpty() then
EgtSetOperationMode( nMchId, false)
end
-- altrimenti lavorazione non applicata
else
_, sMyWarn = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchId, false)
end
-- altrimenti non è ctata inserita lavorazione
else
sMyWarn = 'warning adding machining ' .. sName .. '-' .. sMilling
end
-- altrimenti non c'è il percorso
else
sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path'
end
-- altrimenti
else
sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path'
end
-- altrimenti diametro trovato è simile a quello già utilizzato
-- else
-- sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' smaller tool not found'
end
-- altrimenti non è stata trovata lavorazione
else
sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library'
end
-- altrimenti non è stato trovato il punto comune
-- else
-- sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path'
end
-- altrimenti pareti sottosquadra o angolo aperto
-- else
-- sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path'
end
if #sMyWarn > 0 then
EgtOutLog( sMyWarn)
end
end
return true, sMyWarn
end
---------------------------------------------------------------------
local function MakeCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam)
local sMyWarn
local pAuxId = {}
local nAuxId
local AuxId
local ptApPoint
local dLenTrimExt
local sMilling
local dMaxDepth = 0
-- ottengo l'angolo di riferimento dove applicare il percorso di pulitura
local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd)
-- prendo il primo versore
local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT)
local _, vtN3 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT)
if not tFacAdj then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry not found for clean corner'
EgtOutLog( sErr)
return false, sErr
end
-- trovo il punto sulla superfice di riferimento
local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT)
local nIdIniPoint
local nIdEndPoint
if ptLocP1 and ptLocP2 then
if ( dist( ptLocP1, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) then
nIdEndPoint = 4
nIdIniPoint = 5
elseif ( dist( ptLocP1, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) then
nIdEndPoint = 5
nIdIniPoint = 4
end
end
-- 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 on process ' .. tostring( Proc.Id) .. ' clean corner milling from bottom impossible'
EgtOutLog( sErr)
return false, sErrLX
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', (dDiam*0.5))
if not sMilling then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- recupero i dati dell'utensile ( temporaneo, per compensare errore nella lavorazione)
if EgtMdbSetCurrMachining( sMilling) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) 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 on process ' .. tostring( Proc.Id) .. ' skip clean corner: the cut heigth is smaller 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
-- 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)
-- ultima linea di risalita
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], tFacAdj[nIdLine][nIdIniPoint], 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 on process ' .. tostring( Proc.Id) .. ' 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 nMchId = EgtAddMachining( sName, sMilling)
if not nMchId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
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)
EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0)
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 4)
-- allungo inizio e fine di 10mm
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10)
-- setto affondamento 0
EgtSetMachiningParam( MCH_MP.DEPTH, 0)
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill
local sUserNotes = 'VMRS=0;'
-- aggiungo alle note massima elevazione
sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dMaxDepth, 1) .. ';'
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
if not EgtApplyMachining( 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
return true, sMyWarn
end
---------------------------------------------------------------------
local function MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam, bSpecialMach)
local sMyWarn
-- ottengo l'angolo dove applicare il foro
local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd)
if not tFacAdj then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry not found for drilling'
EgtOutLog( sErr)
return false, sErr
end
-- trovo il punto sulla superfice di riferimento
local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT)
local nIdIniPoint
local nIdEndPoint
if ptLocP1 and ptLocP2 then
if ( dist( ptLocP1, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) then
nIdEndPoint = 4
nIdIniPoint = 5
elseif ( dist( ptLocP1, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) then
nIdEndPoint = 5
nIdIniPoint = 4
end
end
-- 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 on process ' .. tostring( Proc.Id) .. ' 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 on process ' .. tostring( Proc.Id) .. ' 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
if EgtMdbSetCurrMachining( sDrilling) then
bIsDrilling = ( EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) == MCH_MY.DRILLING)
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
if bIsDrilling then
dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth
else
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
end
dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
dDiamTh = EgtTdbGetCurrToolThDiam()
end
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 .. ' (process ' .. tostring( Proc.Id) .. ')')
end
end
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill
local sUserNotes = 'VMRS=0;'
-- aggiungo alle note massima elevazione (coincide con affondamento)
sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dDepth, 1) .. ';'
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
if not EgtApplyMachining( 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 MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dElev, bForceUseBlade, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces, nBottomFace)
local sWarn
-- Recupero le facce adiacenti alla principale
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
if not vAdj or #vAdj == 0 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' 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
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
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
if not nFacAdj then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' 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 * rfFac:getVersX()) > abs( vtN * rfFac:getVersY()) then
dH, dV = dV, 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] == nFacInd then
-- Se non esiste faccia adiacente a lato precedente -> inizio aperto
local i = EgtIf( j > 1, j - 1, #vAdj2)
while vAdj2[i] == 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] == nFacInd do
k = EgtIf( k < #vAdj2, k + 1, 1)
end
bOpenEnd = ( vAdj2[k] < 0)
end
end
end
-- Recupero il massimo affondamento possibile con la lama
local dSawMaxDepth = 0
local sCutting = ML.FindCutting( 'HeadSide')
if sCutting then
if EgtMdbSetCurrMachining( sCutting) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dSawMaxDepth = EgtTdbGetCurrToolMaxDepth() or dSawMaxDepth
end
end
end
-- Se entrambi gli estremi sono aperti e possibile, lavoro con la lama
if bOpenStart and bOpenEnd and bForceUseBlade and dElev < dSawMaxDepth + 10 * GEO.EPS_SMALL then
-- Recupero la lavorazione di lama
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, 'MNF'
end
-- recupero i dati dell'utensile
local dSawDiam = 400
local dSawThick = 4
if EgtMdbSetCurrMachining( sCutting) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick
end
end
if dSawThick > dV + 10 * GEO.EPS_SMALL then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' sawblade too thick'
EgtOutLog( sErr)
return false, sErr
end
-- Calcolo uso faccia
local nFaceUse = BL.GetNearestOrthoOpposite( rfFac:getVersZ())
-- ingombro del grezzo
local b3Raw = EgtGetRawPartBBox( nRawId)
-- Eseguo i tagli
local nStep = ceil( ( dV - 10 * 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
local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, 0, nil, b3Raw)
if not bOk then return bOk, sErr end
end
-- altrimenti con sega a catena
else
-- Recupero la lavorazione
local sSawing = ML.FindSawing( 'Sawing')
if not sSawing then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chainsawing 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
if EgtMdbSetCurrMachining( sSawing) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth
dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
end
end
if dSawThick > dV + 10 * GEO.EPS_SMALL then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' 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 dElev > 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( rfFac:getVersZ())
-- Calcolo angolo 3° asse rot (da direz. utensile)
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT)
local ptP1, ptP2 = EgtSurfTmFacetOppositeSide( Proc.Id, nFacAdj, rfFac:getVersZ(), GDB_ID.ROOT)
local vtT = vtN ^ (ptP2 - ptP1)
vtT:normalize()
local d3RotAng = EgtIf( abs( vtT:getZ()) < 0.1, 0, 90)
-- Verifico se necessarie più passate
local nStep = ceil( ( dV - 10 * GEO.EPS_SMALL) / dSawThick)
local dStep = 0
if nStep > 1 then
dStep = ( 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 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)
-- 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))
-- imposto angolo 3° asse rot
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, 'A=' .. EgtNumToString( d3RotAng))
-- imposto offset radiale
local dOffs = ( i - 1) * dStep
EgtSetMachiningParam( MCH_MP.OFFSR, dOffs)
-- se necessario, limito l'affondamento
if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then
sWarn = 'Warning in LapJoint : elevation (' .. EgtNumToString( dElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')'
dDepth = dMaxDepth - dElev
EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')')
EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH '..EgtNumToString( dDepth, 1))
end
-- imposto elevazione
local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 2) .. ';'
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
elseif EgtIsMachiningEmpty() then
_, sWarn = EgtGetMachMgrWarning( 0)
EgtSetOperationMode( nMchFId, false)
return false, sWarn
end
end
-- altrimenti segacatena di fianco
else
-- verifico se posso farlo con la sega-catena
local bMakeChainSaw, sSawing2, dMaxMat2, dSawCornerRad2, dSawThick2 = VerifySawChain( Proc, dDimMin, dDimMax, vtOrtho)
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 nMchFId = EgtAddMachining( sName, sSawing2)
if not nMchFId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing2
EgtOutLog( sErr)
return false, sErr
end
-- aggiungo geometria
EgtSetMachiningGeometry( {{ Proc.Id, nLundIdFace}})
-- 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)
--elseif abs(vtOrtho:getZ()) < 0.707 and abs(vtOrtho:getY()) > 0.707 then
else
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK)
--elseif abs(vtOrtho:getZ()) <= 0.707 and vtOrtho:getY() < -0.707 then
-- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT)
--elseif abs(vtOrtho:getZ()) < 0.707 and vtOrtho:getX() > 0.707 then
-- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT)
--else
-- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT)
end
-- imposto offset radiale
local dOffs = ( i - 1) * dStep
EgtSetMachiningParam( MCH_MP.OFFSR, dOffs)
-- se possibile aumento l'affondamento pari al raggio corner + 1
if dMaxMat2 > (dDepth + dSawCornerRad2 + 1) then
EgtSetMachiningParam( MCH_MP.DEPTH, (dDepth + dSawCornerRad2 + 1))
-- se massimo affondamento supera altezza fessura, uso massimo affondamento
elseif dMaxMat2 > (dDepth + 1) then
EgtSetMachiningParam( MCH_MP.DEPTH, (dMaxMat2 - 1))
-- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning
elseif dMaxMat2 < dDepth then
EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat2)
sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth'
EgtOutLog( sWarn)
end
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
elseif EgtIsMachiningEmpty() then
_, sWarn = EgtGetMachMgrWarning( 0)
EgtSetOperationMode( nMchFId, false)
return false, sWarn
end
end
end
end
end
return true, sWarn
end
---------------------------------------------------------------------
local function MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw)
-- Recupero la lavorazione di lama
local sCutting = ML.FindCutting( 'HeadSide')
if not sCutting then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- recupero i dati dell'utensile
local dSawDiam = 400
if EgtMdbSetCurrMachining( sCutting) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
end
end
-- eseguo il taglio
return BL.MakeOneFaceBySaw( Proc.Id, nFacet, sCutting, dSawDiam, vtN, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw)
end
---------------------------------------------------------------------
local function EvaluateQParam( Proc, nRawId, bMakeVertCham, sDephtCham, sOnlyCham, sUseBlade)
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
-- verifico se posso fare solo lo smusso
if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then
if dDepth > 0 then
nChamfer = nChamfer + 1
-- altrimenti se non ho l'affondamento esco
else
sErr = 'Error on process ' .. tostring( Proc.Id) .. ' 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
if #sUseBlade == 0 or EgtGetInfo( Proc.Id, sUseBlade, 'i') == 1 then
bForceUseBlade = true
end
return nChamfer, dDepth, sErr, bForceUseBlade
end
---------------------------------------------------------------------
local function MakePocket( Proc, nPartId, 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 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 = 'Pock_' .. ( 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
-- se tasca aperta e non lavorata col truciolatore, imposto opportuno attacco
if sMchFind == 'OpenPocket' and nUseRoughTool == 0 then
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
end
-- 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 MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, tvtN, nBaseFace, nSideFace, ptPs, tDimAndRef,
b3Raw, nDiffWidth, nUseRoughTool, dAng, sPocketing, sTuuidPk, dPrevFaceElev)
local sMchFind = 'Pocket'
local dAngLimit = 30
-- se feature é larga come trave imposto openpocket
if nDiffWidth == 0 then
sMchFind = 'OpenPocket'
-- altrimenti non è passante disabilito il truciolatore e amplio il limite angolare
-- per la differenza di lunghezza tra il truciolatore e la fresa più lunga
else
nUseRoughTool = 0
dAngLimit = 40
end
-- se angolo tra le facce maggiore di 90, inserisco la contornatura o svuotatura del lato più corto
if ( 180 + dAng) > 90.1 then
-- 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 = 180 + dAng - 90
-- se la normale della faccia corta si discosta dalla trave di più dell'angolo selezionato utilizzo la svutatura altrimenti la contornatura
-- if abs( tvtN[2]:getX()) < cos(dAngLimit) then -- se si discosta di più del valore impostato applico svuotatura
-- se l'angolo dalla verticale si discosta di più dell'angolo limite impostato, utilizzo la svuotatura
if cos( dDiffFromSqAng) < cos(dAngLimit) then -- se si discosta di più del valore impostato applico svuotatura
-- applico la svuotatura
local bOk, sWarn, sTuuidPk, dDiamTool, dElev = MakePocket( Proc, nPartId, ptPs, tvtN, nSideFace, sMchFind, nUseRoughTool, sPocketing, dPrevFaceElev, tDimAndRef, dAng)
if not bOk then
-- se ho id utensile e diametro è perchè non ha fatto svuotatura perchè la faccia è più stretta del diametro utensile
-- e provo ad inserire singola passata di testa
if sTuuidPk and dDiamTool then
-- recupero la lavorazione
local sMilling = ML.FindMilling( 'Long2Cut', dElev, sTuuidPk)
if not sMilling then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- inserisco la lavorazione
local sName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
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) .. ';'
sNotes = sNotes .. 'VMRS=0;'
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
else
return false, sWarn
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 on process ' .. tostring( Proc.Id) .. ' milling not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- recupero i dati dell'utensile
local dTDiam = 50
if EgtMdbSetCurrMachining( sMilling) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam
end
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 EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
end
end
return true
end
---------------------------------------------------------------------
local function SetOpenSide( nPathInt, vtOrtho, b3Solid, nAddGrpId, bStartPoint)
-- 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
if ( abs( pPini:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL) or
( abs( pPini:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL) then
-- setto l'entità open
local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or ''
if #sActInfo > 0 then
EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1))
else
EgtSetInfo( nPathInt, 'OPEN', (i-1))
end
-- prendo i punti per eventuale modifica del punto di inizio percorso
pLastPIni = pPini
pLastPEnd = pPend
-- altrimenti se corrisponde a Y
elseif ( abs( pPini:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL) or
( abs( pPini:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL) then
-- setto l'entità open
local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or ''
if #sActInfo > 0 then
EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1))
else
EgtSetInfo( nPathInt, 'OPEN', (i-1))
end
-- prendo i punti per eventuale modifica del punto di inizio percorso
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
if ( abs( pPini:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL) or
( abs( pPini:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL) then
-- setto l'entità open
local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or ''
if #sActInfo > 0 then
EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1))
else
EgtSetInfo( nPathInt, 'OPEN', (i-1))
end
-- prendo i punti per eventuale modifica del punto di inizio percorso
pLastPIni = pPini
pLastPEnd = pPend
-- altrimenti se corrisponde a Z
elseif ( abs( pPini:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL) or
( abs( pPini:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL) then
-- setto l'entità open
local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or ''
if #sActInfo > 0 then
EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1))
else
EgtSetInfo( nPathInt, 'OPEN', (i-1))
end
-- prendo i punti per eventuale modifica del punto di inizio percorso
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
if ( abs( pPini:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL) or
( abs( pPini:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL) then
-- setto l'entità open
local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or ''
if #sActInfo > 0 then
EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1))
else
EgtSetInfo( nPathInt, 'OPEN', (i-1))
end
-- prendo i punti per eventuale modifica del punto di inizio percorso
pLastPIni = pPini
pLastPEnd = pPend
-- altrimenti se corrisponde a Z
elseif ( abs( pPini:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL) or
( abs( pPini:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL) then
-- setto l'entità open
local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or ''
if #sActInfo > 0 then
EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1))
else
EgtSetInfo( nPathInt, 'OPEN', (i-1))
end
-- prendo i punti per eventuale modifica del punto di inizio percorso
pLastPIni = pPini
pLastPEnd = pPend
end
end
end
-- se devo cambiare il punto di partenza
if bStartPoint and pLastPIni and pLastPEnd then
-- calcolo il punto medio con gli ultimi punti utilizzati
local ptPs = ( pLastPIni + pLastPEnd) / 2
EgtChangeClosedCurveStartPoint( nPathInt, ptPs, GDB_RT.GLOB)
end
end
end
---------------------------------------------------------------------
local function ExtractExternalPaths( nPathInt, nNumIdAux, vtOrtho, b3Solid, nAddGrpId)
local nAuxId1, nAuxId2
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
local ptP1 = EgtSP( ( nStartId + i - 1), GDB_RT.GLOB)
local ptP2 = EgtEP( ( nStartId + i - 1), GDB_RT.GLOB)
if sDeleteByDir == 'Z' then
-- se hanno variazione in Z cancello l'entità
if abs( ptP1:getZ() - ptP2:getZ()) > 10 * GEO.EPS_SMALL then
EgtErase( nStartId + i - 1)
end
elseif sDeleteByDir == 'Y' then
-- se hanno variazione in Y cancello l'entità
if abs( ptP1:getY() - ptP2:getY()) > 10 * GEO.EPS_SMALL then
EgtErase( nStartId + i - 1)
end
elseif sDeleteByDir == 'X' then
-- se hanno variazione in X cancello l'entità
if abs( ptP1:getX() - ptP2:getX()) > 10 * GEO.EPS_SMALL then
EgtErase( nStartId + i - 1)
end
end
end
-- ricreo i vari percorsi
local dLocalVal
local tPaths = {}
local nNumPaths
local dMaxVal
local dMinVal
for i = 1, nNumIds do
local ptP1 = EgtSP( ( nStartId + i - 1), GDB_RT.GLOB)
if ptP1 then
if sDeleteByDir == 'Z' then
local bInsTab
for j = 1, #tPaths do
local dLocalVal = tPaths[j][2]
if abs( ptP1:getZ() - dLocalVal) < 10 * GEO.EPS_SMALL then
local tLocIds = tPaths[j][1]
table.insert( tLocIds, ( nStartId + i - 1))
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, {{( nStartId + i - 1)}, ptP1:getZ()})
dMaxVal = b3Solid:getMax():getZ()
dMinVal = b3Solid:getMin():getZ()
end
elseif sDeleteByDir == 'Y' then
local bInsTab
for j = 1, #tPaths do
local dLocalVal = tPaths[j][2]
if abs( ptP1:getY() - dLocalVal) < 10 * GEO.EPS_SMALL then
local tLocIds = tPaths[j][1]
table.insert( tLocIds, ( nStartId + i - 1))
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, {{( nStartId + i - 1)}, ptP1:getY()})
dMaxVal = b3Solid:getMax():getY()
dMinVal = b3Solid:getMin():getY()
end
elseif sDeleteByDir == 'X' then
local bInsTab
for j = 1, #tPaths do
local dLocalVal = tPaths[j][2]
if abs( ptP1:getX() - dLocalVal) < 10 * GEO.EPS_SMALL then
local tLocIds = tPaths[j][1]
table.insert( tLocIds, ( nStartId + i - 1))
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, {{( nStartId + i - 1)}, ptP1:getX()})
dMaxVal = b3Solid:getMax():getX()
dMinVal = b3Solid:getMin():getX()
end
end
end
end
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
end
end
for i = 1, #tPaths do
if tPaths[i] then
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
local ptP1 = EgtSP( tChamPath[i], GDB_RT.GLOB)
-- modifico estrusione percorso
if sDeleteByDir == 'Z' then
if abs(ptP1:getZ() - dMaxVal) < 10 * GEO.EPS_SMALL then
EgtModifyCurveExtrusion( tChamPath[i], Z_AX(), GDB_RT.GLOB)
else
EgtModifyCurveExtrusion( tChamPath[i], -Z_AX(), GDB_RT.GLOB)
end
elseif sDeleteByDir == 'Y' then
if abs(ptP1:getY() - dMaxVal) < 10 * GEO.EPS_SMALL then
EgtModifyCurveExtrusion( tChamPath[i], Y_AX(), GDB_RT.GLOB)
else
EgtModifyCurveExtrusion( tChamPath[i], -Y_AX(), GDB_RT.GLOB)
end
elseif sDeleteByDir == 'X' then
if abs(ptP1:getX() - dMaxVal) < 10 * GEO.EPS_SMALL then
EgtModifyCurveExtrusion( tChamPath[i], X_AX(), GDB_RT.GLOB)
else
EgtModifyCurveExtrusion( tChamPath[i], -X_AX(), GDB_RT.GLOB)
end
end
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 CheckPocketTool( sMchFind, dDiam, dElev)
local sPocketing = ML.FindPocketing( sMchFind, dDiam, dElev)
if sPocketing then
-- recupero i dati dell'utensile
local dTDiam = 50
if EgtMdbSetCurrMachining( sPocketing) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam
return true, dTDiam
end
end
return false
end
---------------------------------------------------------------------
local function CheckDiamToolByFaces( Proc, nFacInd, dH, dV, bIsU, bIsL, dElev)
local bUSAngle
local dDiam = min( dH, dV)
local dMaxLenFace = max( dH, dV)
-- verifico che diametro utensile prende con la openpocket con la massima dimensione faccia
local bUseMaxTool, dMaxDiam = CheckPocketTool( 'OpenPocket', dMaxLenFace, dElev)
-- se non trovato utensile esco
if not bUseMaxTool then
return false
end
-- Recupero le facce adiacenti alla principale
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
-- se non ho facce adiacenti esco subito
if not vAdj or #vAdj == 0 then
return false
end
-- Cerco le facce adiacenti alla principale con angolo >= 90
local nFacAdj
local tDistAdj = {}
for i = 1, #vAdj do
if vAdj[i] >= 0 then
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT)
-- se adiacenza e angolo >= 90
if bAdj and dAng < 0 and 180 + dAng > 90 - 20 * GEO.EPS_SMALL then
table.insert( tDistAdj, dist( ptP1, ptP2))
elseif bAdj and dAng < 0 and 180 + dAng < 90 - 20 * GEO.EPS_SMALL then
-- se trovato angolo sottosquadra esco subito
return false
end
end
end
-- se le facce di adiacenza non corrispondono con quelle della forma esco
if ( bIsU and #tDistAdj ~= 2) or ( bIsL and #tDistAdj ~= 1) then
return false
end
local bUseMaxDist = true
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
end
end
if bUseMaxDist then
return dMaxDiam, 'OpenPocket', 1
end
return false
end
---------------------------------------------------------------------
local function MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMchFindMaster, b3FacesUsed, b3Solid, bOrthoFacesMaster)
local bOrthoFaces
local sWarn
local sMchFind = 'Pocket'
local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt
if sMchFindMaster and #sMchFindMaster > 0 then
sMchFind = sMchFindMaster
end
if b3FacesUsed then
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
local nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, b3FacesUsed)
if not nFacInd or nFacInd < 0 then
if nFacInd == -1 then
bOrthoFaces = nFacInd2
else
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MakeByPockets could not find reference face'
EgtOutLog( sErr)
return -1, sErr
end
end
else
bOrthoFaces = bOrthoFacesMaster
end
-- se è un tunnel provo a vedere se è possibile lavorarlo con la svuotatura
if bOrthoFaces then
-- ottengo le dimensioni del tunnel
dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = GetTunnelDimension( Proc, nPartId)
-- verifico la direzione
-- se devo inserire il chamfer
if nChamfer > 0 then
-- recupero la lavorazione
local sMilling = ML.FindMilling( 'Mark')
if not sMilling then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chamfer not found in library'
EgtOutLog( sErr)
return -1, sErr
end
-- ottengo le curve di contorno libero
local nAuxId1, nAuxId2, nNumIdAux
if b3FacesUsed then
-- nAuxId1, _ = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId)
-- EgtModifyCurveExtrusion( nAuxId1, vtOrtho, GDB_RT.GLOB)
-- SetOpenSide( nAuxId1, vtOrtho, b3Solid, nAddGrpId, true)
-- 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, b3Solid, nAddGrpId)
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 b3FacesUsed 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 b3FacesUsed then
local fFrCurve = EgtGetGlobFrame( AuxId)
vtExtr:toGlob( fFrCurve)
end
-- if b3FacesUsed 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( b3FacesUsed, (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 b3FacesUsed and i == nNumIdAux then
-- EgtSetMachiningParam( MCH_MP.INVERT, true)
-- end
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchId, false)
return -1, sErr
end
-- se non perpendicolare emetto un warning
-- else
-- sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : chamfer skipped because not perpendicular to face or from bottom'
-- EgtOutLog( sWarn)
end
--emetto un warning
-- else
-- sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : chamfer skipped because not perpendicular to face'
-- EgtOutLog( sWarn)
end
end
end
-- se smusso non è esclusivo
if nChamfer < 2 then
-- verifico se può essere fatto con svuotatura
local bMakePocket, sPocketing, dMaxMat = VerifyIfPocket( Proc, dDimMin, vtOrtho, sMchFind)
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
local nPathInt, _ = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId)
EgtModifyCurveExtrusion( nPathInt, vtOrtho, GDB_RT.GLOB)
-- se ho 3 facce, ciclo sulle entià del percorso per segnare quelle che sono aperte
if b3FacesUsed then
SetOpenSide( nPathInt, vtOrtho, b3Solid, nAddGrpId)
end
-- variabili per parametri lavorazione
local dMachDepth
local dElev = 0
local bDoubleSide
-- se possibile svuotare completamente da una sola parte
if dMaxMat > ( dDepth + 2) then
dMachDepth = (dDepth / 2) + 2
dElev = dDepth
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 then
dMachDepth = dMaxMat - (dDepth / 2)
dElev = dMaxMat
sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth'
EgtOutLog( sWarn)
-- altrimenti setto il flag per fare la svuotatura da due parti
else
if dMaxMat > (dDepth / 2) then
dMachDepth = 1
dElev = (dDepth / 2) + 1
else
dMachDepth = dMaxMat - (dDepth / 2)
dElev = dMaxMat
end
bDoubleSide = true
end
end
-- inserisco la lavorazione di svuotatura
local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
local nMchFId = EgtAddMachining( sName, sPocketing)
if not nMchFId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing
EgtOutLog( sErr)
return -1, sErr
end
-- aggiungo geometria
EgtSetMachiningGeometry( {{ nPathInt, -1}})
-- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale)
local bInvertMach
if vtOrtho:getZ() < BD.NZ_MINA and abs(vtOrtho:getZ()) >= 0.707 then
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
bInvertMach = true
-- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti
elseif not bDoubleSide and vtOrtho:getY() > GEO.EPS_SMALL then
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
bInvertMach = true
end
-- imposto posizione braccio porta testa
if vtOrtho:getY() < GEO.EPS_SMALL then
if bInvertMach then
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
else
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
end
else
if bInvertMach then
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
else
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
end
end
-- se tasca aperta, imposto opportuno attacco
if sMchFind == 'OpenPocket' then
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
end
-- inverto il percorso di lavorazione per lavorare sinistro
EgtSetMachiningParam( MCH_MP.INVERT, true)
-- imposto affondamento
EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth)
-- imposto elevazione e dichiaro non si generano sfridi per VMill
local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';'
sNotes = sNotes .. 'VMRS=0;'
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
-- eseguo
if not 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 -1, sErr
end
end
-- se posso applicare la svuotatura sul lato opposto
if bDoubleSide then
-- se anche lavorando dal lato opposto non riesco a svuotare completamente la fessura
-- setto i parametri affondamento ed emetto warning
if dMaxMat*2 < dDepth then
dMachDepth = dMaxMat - (dDepth / 2)
dElev = dMaxMat
sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth'
EgtOutLog( sWarn)
end
-- inserisco la lavorazione di svuotatura
local sName = 'PockOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
local nMchFId = EgtAddMachining( sName, sPocketing)
if not nMchFId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing
EgtOutLog( sErr)
return -1, sErr
end
-- aggiungo geometria
EgtSetMachiningGeometry( {{ nPathInt, -1}})
-- imposto direzione utensile opposta
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
-- imposto posizione braccio porta testa
if vtOrtho:getY() < GEO.EPS_SMALL then
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
else
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
end
-- se tasca aperta, imposto opportuno attacco
if sMchFind == 'OpenPocket' then
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
end
-- inverto il percorso di lavorazione per lavorare sinistro
EgtSetMachiningParam( MCH_MP.INVERT, true)
-- imposo affondamento
EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth)
-- imposto elevazione e dichiaro non si generano sfridi per VMill
local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';'
sNotes = sNotes .. 'VMRS=0;'
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
-- eseguo
if not 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 -1, sErr
end
end
end
return 1, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace
end
end
end
return 0, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces
end
---------------------------------------------------------------------
local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, bSingle_part)
local sWarn
-- recupero l'ingombro del grezzo di appartenenza
local b3Raw = EgtGetRawPartBBox( nRawId)
-- recupero l'ingombro della trave
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') 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
-- 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
local bClosedOrthoFaces
local nFacInd, dFacElev, nFacInd2, dFacElev2
local nBottomFace
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
if not nFacInd or nFacInd < 0 then
if nFacInd == -1 then
bClosedOrthoFaces = nFacInd2
else
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' 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
-- 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
nBottomFace = i-1
if EgtSurfTmRemoveFacet( nNewProc, nBottomFace) then
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( nNewProc, nPartId)
if not nFacInd or nFacInd < 0 then
if nFacInd == -1 then
bClosedOrthoFaces = nFacInd2
EgtErase( nNewProc)
break
else
EgtErase( nNewProc)
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MakeMoreFaces could not find reference face'
EgtOutLog( sErr)
return false, sErr
end
end
-- altrimenti esco
else
EgtErase( nNewProc)
break
end
end
-- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo
if bClosedOrthoFaces then
nFacInd = nBottomFace
-- rendo nulla la faccia opzionale perchè si tratta di una fessura
nFacInd2 = nil
dFacElev = BL.GetFaceElevation( Proc.Id, nFacInd)
bClosedOrthoFaces = false -- non setto come tunnel
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, bForceUseBlade = EvaluateQParam( Proc, nRawId, 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
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, nLundIdFace = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, 'Pocket', false, b3Solid, 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 bMakeChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick = VerifySawChain( Proc, dDimMin, dDimMax, vtOrtho)
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, nLundIdFace}})
-- 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)
--elseif abs(vtOrtho:getZ()) < 0.707 and abs(vtOrtho:getY()) > 0.707 then
else
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK)
--elseif abs(vtOrtho:getZ()) <= 0.707 and vtOrtho:getY() < -0.707 then
-- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT)
--elseif abs(vtOrtho:getZ()) < 0.707 and vtOrtho:getX() > 0.707 then
-- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT)
--else
-- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT)
end
-- 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)
sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth'
EgtOutLog( sWarn)
end
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
elseif EgtIsMachiningEmpty() then
_, sWarn = EgtGetMachMgrWarning( 0)
EgtSetOperationMode( nMchFId, false)
return false, sWarn
end
end
end
end
-- altrimenti non è una fessura
else
-- 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) or TestElleShape4( Proc) == 2)
-- se fattibile con fresa BH di fianco e spessore utensile inferiore alla larghezza faccia
local bMakeBySideMill, bHead, sMilling, dMaxMat = VerifyIfByBHSideMill( Proc)
if bMakeBySideMill and ( dMaxMat <= dV) then
-- se smusso non è esclusivo
if nChamfer < 2 then
-- inserisco la lavorazione di fresatura
local sName = 'BHMill_' .. ( 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 del lato faccia
EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, 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)
dStep = dVcalc / nStep
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)
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
end
-- altrimenti lavoro con svuotatura
else
local bSpecial3faces = false
-- verifico se sono nel caso in cui la faccia esclusa ha elevazione più alta
if not bIsU and bIsL and Proc.Fct <= 3 and nFacInd ~= 0 and nFacInd2 ~= 0 then
-- if not bIsU and bIsL and Proc.Fct <= 3 then
-- verifico se l'elevazione della faccia esclusa è maggiore dell'elevazione delle altre due facce
local nFaceMaxElev = 0
if Proc.Fct == 3 then
for i = 1, Proc.Fct do
if (i-1) ~= nFacInd and (i-1) ~= nFacInd2 then
nFaceMaxElev = (i-1)
end
end
end
local rfFac0 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFaceMaxElev, GDB_ID.ROOT)
-- ottengo il box con la normale della faccia 0
local bBoxF0 = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfFac0)
local dElevF0 = bBoxF0:getDimZ()
-- se effettivamente l'elevazione della faccia esclusa è maggiore delle altre elevazioni segno il flag per le 3 facce speciali
if dElevF0 > dFacElev and dElevF0 > dFacElev2 then
bSpecial3faces = true
end
end
-- se riconosciuta gestione 3 facce
-- e limitata per ora alla feature 20
if bSpecial3faces and Proc.Prc == 20 then
-- se smusso non è esclusivo
if nChamfer < 2 then
-- entrambe le facce non devono essere orientate verso il basso
local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
-- se orientata verso il basso, verifico l'alternativa
if vtN:getZ() < BD.NZ_MINA and vtN2:getZ() < BD.NZ_MINA then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' special LapJoint from bottom impossible'
EgtOutLog( sErr)
return false, sErr
end
rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd2, GDB_ID.ROOT)
-- eventuali tagli preliminari
do
local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, b3Raw, nChamfer)
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 on process ' .. tostring( Proc.Id) .. ' milling not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- Recupero la lavorazione di svuotatura
local sMchFind = 'Pocket'
-- se forzato uso truciolatore
if EgtGetInfo( Proc.Id, sUseRoughTool, 'i') == 1 then
sMchFind = 'OpenPocket'
end
local dDiam = min( dH, dV)
local dDiam2 = min( dH2, dV2)
local dCollSic = 2 * BD.COLL_SIC
local dCollSic2 = 2 * BD.COLL_SIC
if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end
if abs( vtN2:getX()) > 0.7 or abs( vtN2:getY()) > 0.7 or abs( vtN2:getZ()) > 0.7 then dCollSic2 = 0 end
local sPocketing = ML.FindPocketing( sMchFind, dDiam2, dFacElev2 + dCollSic2)
-- se non trova una svuotatura adatta provo ad assegnarla all'altra faccia
if not sPocketing then
dDiam, dDiam2 = dDiam2, dDiam
dCollSic, dCollSic2 = dCollSic2, dCollSic
nFacInd, nFacInd2 = nFacInd2, nFacInd
dH, dH2 = dH2, dH
dV, dV2 = dV2, dV
dFacElev, dFacElev2 = dFacElev2, dFacElev
rfFac, rfFac2 = rfFac2, rfFac
vtN, vtN2 = vtN2, vtN
sPocketing = ML.FindPocketing( sMchFind, dDiam2, dFacElev2 + dCollSic2)
if not sPocketing then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' pocketing not found in library'
EgtOutLog( sErr)
return false, sErr
end
end
-- provo con contornatura
local dDiamTool = 20
if bIsL then
local bOk, sErr
bOk, sWarn, dDiamTool = MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev, true, sMilling, nFacInd2, dFacElev2)
if not bOk then return bOk, sWarn end
else
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' 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, nFacInd2}})
-- imposto uso faccia
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT)
-- 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
-- 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( dFacElev2, 1) .. ';'
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
-- eseguo
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
-- se abilitato dal parametro Q inserisco foro sullo spigolo
if EgtGetInfo( Proc.Id, sInsertBoreOnCorner, 'i') == 1 then
local bOk
bOk, sWarn = MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, 0, nAddGrpId, dDiamTool, true)
if not bOk then return false, sWarn end
end
end
-- altrimenti lavorazione di svuotatura o contornatura
else
-- se orientata verso il basso, verifico l'alternativa
if vtN:getZ() < BD.NZ_MINA and nFacInd2 then
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
nFacInd, nFacInd2 = nFacInd2, nFacInd
dFacElev, dFacElev2 = dFacElev2, dFacElev
end
rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
-- verifico non sia orientata verso il basso
local bFaceOk = ( vtN:getZ() >= BD.NZ_MINA)
if not bFaceOk then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' LapJoint from bottom impossible'
EgtOutLog( sErr)
return false, sErr
end
-- eventuali tagli preliminari
do
local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, b3Raw, nChamfer)
if not bOk then return false, sErr end
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 nUseRoughTool = 0
local sMchFind = 'Pocket'
local dDiam
-- se processo 20 vedo se ho truciolatore abilitato
if Proc.Prc == 20 then
-- se forzato uso truciolatore altrimenti prosegue con fresa più piccola
if EgtGetInfo( Proc.Id, sUseRoughTool, 'i') == 1 then
sMchFind = 'OpenPocket'
nUseRoughTool = 1
end
dDiam = min( dH, dV)
else
-- Da disposizini di Alessandro, se feature lavorata in singolo passo uso fresa
if bSingle_part then
-- disabilito il truciolatore
sMchFind = 'Pocket'
nUseRoughTool = 0
-- verifico dalla forma se posso prendere utensile più grande
if ( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 2 and bIsL) then
--verifico dimensioni facce adiacenti
dDiam, sMchFind, nUseRoughTool = CheckDiamToolByFaces( Proc, nFacInd, dH, dV, bIsU, bIsL, ( dFacElev + dCollSic))
if not dDiam then
dDiam = min( dH, dV)
sMchFind = 'Pocket'
nUseRoughTool = 0
end
else
dDiam = min( dH, dV)
end
-- altrimenti le lavorata in passo multiplo
else
-- abilito il truciolatore
sMchFind = 'OpenPocket'
nUseRoughTool = 1
-- verifico dalla forma se posso prendere utensile più grande
if ( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 2 and bIsL) or ( Proc.Fct == 1 and not bIsU and not bIsL) then
--verifico dimensioni facce adiacenti
dDiam, sMchFind, nUseRoughTool = CheckDiamToolByFaces( Proc, nFacInd, dH, dV, bIsU, bIsL, ( dFacElev + dCollSic))
if not dDiam then
dDiam = min( dH, dV)
sMchFind = 'Pocket'
nUseRoughTool = 0
end
else
dDiam = min( dH, dV)
end
end
end
--EgtOutLog( 'Mortise Find Diam =' .. EgtNumToString( dDiam))
local sPocketing = ML.FindPocketing( sMchFind, dDiam, dFacElev + dCollSic)
-- se non trova una svuotatura adatta
if not sPocketing then
-- se forma a L provo con contornatura
if bIsL then
-- se smusso non è esclusivo
if nChamfer < 2 then
return MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev)
end
-- altrimenti, in base alla forma, provo con svuotature di fianco o con la sega a catena o lama
else
local bTryWithBlades = true
local nOk, bOk, sStat, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces
-- 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)
nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMchFind, true, b3Solid)
if nOk < 0 then
return false, sErr
elseif nOk > 0 then
bTryWithBlades = false
end
bOk = true
end
-- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame
if bTryWithBlades and nChamfer < 2 then
bOk, sWarn, sStat = MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev, bForceUseBlade, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces, nBottomFace)
if not bOk and sStat == 'MNF' then
sPocketing = ML.FindPocketing( sMchFind, dDiam)
if not sPocketing then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' pocketing not found in library'
EgtOutLog( sErr)
return false, sErr
end
else
return bOk, sWarn
end
-- altrimenti ho già svuotato dal fianco, esco
else
return bOk, sWarn
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
local bMadeASbyBld = false
if nChamfer < 2 and EgtGetInfo( Proc.Id, sAntisplintMode, 'i') == 1 and ( bIsU or bIsL) and
( Proc.Box:getDimY() > b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > b3Raw:getDimZ() - 1) then
local nNumFac = EgtIf( bIsU, 2, 1)
-- va eseguito sulle facce diverse dalla principale
for nFacet = 0, nNumFac do
if nFacet ~= nFacInd then
bMadeASbyBld, sWarn = MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw)
if not bMadeASbyBld then return false, sWarn end
end
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] = vtN
local bOk
bOk, sWarn, sTuuidPk, dDiamTool = MakePocket( Proc, nPartId, ptC, tvtNx, nFacInd, sMchFind, nUseRoughTool, sPocketing, dFacElev)
if not bOk then return false, sWarn end
-- 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
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
if not vAdj or #vAdj == 0 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' main face without adjacencies'
EgtOutLog( sErr)
return false, sErr
end
-- Cerco una faccia adiacente alla principale con angolo > 90
local nFacAdj
local tDimAndRef = {}
tvtNx = {}
tvtNx[1] = vtN
tDimAndRef[1] = {dH, dV, rfFac}
for i = 1, #vAdj do
if vAdj[i] >= 0 then
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 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
bOk, sWarn = MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, tvtNx, nFacInd, vAdj[i], ptPs, tDimAndRef,
b3Raw, EgtIf( ( Proc.Fct == 3 and bIsU), 0, 2), nUseRoughTool, dAng, sPocketing, sTuuidPk, dFacElev)
if not bOk then return bOk, sWarn end
end
end
end
end
-- se abilitato dal parametro Q inserisco foro sullo spigolo
if EgtGetInfo( Proc.Id, sInsertBoreOnCorner, 'i') == 1 then
local bOk
bOk, sWarn = MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool)
if not bOk then return false, sWarn end
-- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura
elseif EgtGetInfo( Proc.Id, sInsertBoreOnCorner, 'i') == 2 then
local bOk
bOk, sWarn = MakeCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool)
if not bOk then return false, sWarn end
-- altrimenti se abilitato dal parametro Q inserisco contorno con fresa più piccola
elseif EgtGetInfo( Proc.Id, sMakeContourWithSmallTool, 'i') == 1 then
local bOk
bOk, sWarn = MakeContourCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool)
if not bOk then return false, sWarn end
end
end
end
end
end
return true, sWarn
end
---------------------------------------------------------------------
local function MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId)
-- 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'ingombro del grezzo di appartenenza
local b3Raw = EgtGetRawPartBBox( nRawId)
-- la divido in parti lungo X
local vAddId = {}
local nPart = ceil( Proc.Box:getDimX() / BD.LONGCUT_MAXLEN)
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
table.insert( vAddId, AddId)
end
-- applico le lavorazioni sulle diverse parti
local sWarn
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, Fct = nFct, Flg = Proc.Flg}
local bOk, sMyWarn = MakeMoreFaces( AddProc, nPhase, nRawId, nPartId, false)
if not sWarn then sWarn = sMyWarn end
if not bOk then return bOk, sWarn end
end
return true, sWarn
end
---------------------------------------------------------------------
-- Applicazione della lavorazione
---------------------------------------------------------------------
function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead)
-- limiti di fresatura semplice
local MAX_MILL_LIN = 80
-- 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)
-- se lunghezza richiede spezzatura
if Proc.Box:getDimX() > BD.LONGCUT_MAXLEN then
-- una faccia
if Proc.Fct == 1 then
return LongCut.Make( Proc, nPhase, nRawId, nPartId)
-- due facce
elseif Proc.Fct == 2 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)
if abs( b3Fac1:getDimX() - b3Fac2:getDimX()) < 50 then
return Long2Cut.Make( Proc, nPhase, nRawId, nPartId)
elseif b3Fac1:getDimX() < 1 then
-- la faccia 0 deve essere quella lunga
EgtSurfTmSwapFacets( Proc.Id, 0, 1)
return LongCut.Make( Proc, nPhase, nRawId, nPartId)
elseif b3Fac2:getDimX() < 1 then
return LongCut.Make( Proc, nPhase, nRawId, nPartId)
else
return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId)
end
-- tre o più facce
else
return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId)
end
-- altrimenti lavorazione unica
else
-- una faccia
if Proc.Fct == 1 then
local bForcedBlade = EgtGetInfo( Proc.Id, sUseRoughTool, 'i') ~= 1
-- se piccola, con fresa
if not bForcedBlade 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, nPhase, nRawId, nPartId)
-- altrimenti, con lama
else
return Cut.Make( Proc, nPhase, nRawId, nPartId, 0)
end
-- due facce
elseif Proc.Fct == 2 then
-- determino l'angolo tra le facce
local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT)
local bForcedBlade = EgtGetInfo( Proc.Id, sUseRoughTool, 'i') ~= 1
-- se ortogonali e piccole, con fresa
if not bForcedBlade and bAdj and abs( dAng + 90) < 1 and
( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then
return MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId)
-- altrimenti, con lama
else
return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide')
end
-- tre o più facce
else
return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, true)
end
end
end
---------------------------------------------------------------------
return ProcessLapJoint