02c399eaa0
- scorporato in Beam e BeamWall.
3358 lines
154 KiB
Lua
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
|