d585a45b18
- in Tenoni DT angolo limite per testa sotto portato a +10 gradi - in LapJoint migliorato controllo diametro frese per svuotature, con testa sotto non si controlla vtNz per cambiare faccia, migliorata scelta utensile per svuotatura.
3913 lines
182 KiB
Lua
3913 lines
182 KiB
Lua
-- ProcessLapJoint.lua by Egaltech s.r.l. 2021/03/01
|
|
-- Gestione calcolo mezzo-legno per Travi
|
|
-- 2019/10/08 Agg. gestione OpenPocket.
|
|
-- 2021/01/24 Con sega a catena ora sempre impostato asse A.
|
|
-- 2021/02/03 Corretto riconoscimento feature di coda.
|
|
-- 2021/02/04 Razionalizzata gestione forzatura lama. Corretta gestione diametro minimo utensile per svuotatura.
|
|
|
|
-- 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 Q_FORCE_BLADE = '' -- i
|
|
local Q_DEPTH_CHAMFER = '' -- d
|
|
local Q_ONLY_CHAMFER = '' -- i
|
|
local Q_USE_MILL = '' -- i
|
|
local Q_USE_ROUGH_TOOL = '' -- i
|
|
local Q_USE_ROUGH_TOOL_B90 = '' -- i
|
|
local Q_USE_ROUGH_TOOL_B0 = '' -- i
|
|
local Q_BORE_ON_CORNER = '' -- 1
|
|
local Q_CONTOUR_SMALL_TOOL = '' -- i
|
|
local Q_ONLY_CONTOUR = '' -- i
|
|
local Q_SIDE_ROUGH_TOOL = '' -- i
|
|
local Q_ANTISPLINT_TYPE = '' -- i
|
|
|
|
-- variabile smussi
|
|
local bMadeChamfer
|
|
|
|
-- 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 AssignQIdent( Proc)
|
|
|
|
-- reset assegnazione parametri Q
|
|
Q_FORCE_BLADE = ''
|
|
Q_DEPTH_CHAMFER = ''
|
|
Q_ONLY_CHAMFER = ''
|
|
Q_USE_MILL = ''
|
|
Q_USE_ROUGH_TOOL = ''
|
|
Q_USE_ROUGH_TOOL_B90 = ''
|
|
Q_USE_ROUGH_TOOL_B0 = ''
|
|
Q_BORE_ON_CORNER = ''
|
|
Q_CONTOUR_SMALL_TOOL = ''
|
|
Q_ONLY_CONTOUR = ''
|
|
Q_SIDE_ROUGH_TOOL = ''
|
|
Q_ANTISPLINT_TYPE = ''
|
|
|
|
if ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16 then
|
|
Q_FORCE_BLADE = 'Q01' -- i
|
|
Q_DEPTH_CHAMFER = 'Q04' -- d
|
|
Q_ONLY_CHAMFER = 'Q05' -- i
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17 then
|
|
Q_DEPTH_CHAMFER = 'Q01' -- d
|
|
Q_ONLY_CHAMFER = 'Q02' -- i
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20 then
|
|
Q_DEPTH_CHAMFER = 'Q01' -- d
|
|
Q_USE_MILL = 'Q02' -- i
|
|
Q_USE_ROUGH_TOOL = 'Q03' -- i
|
|
Q_USE_ROUGH_TOOL_B90 = 'Q04' -- i
|
|
Q_USE_ROUGH_TOOL_B0 = 'Q05' -- i
|
|
Q_BORE_ON_CORNER = 'Q06' -- i
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25 then
|
|
Q_BORE_ON_CORNER = 'Q01' -- i
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then
|
|
Q_CONTOUR_SMALL_TOOL = 'Q01' -- i
|
|
Q_ONLY_CONTOUR = 'Q02' -- i
|
|
Q_SIDE_ROUGH_TOOL = 'Q03' -- i
|
|
Q_ANTISPLINT_TYPE = 'Q06' -- i
|
|
Q_DEPTH_CHAMFER = 'Q07' -- d
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32 then
|
|
Q_SIDE_ROUGH_TOOL = 'Q01' -- i
|
|
end
|
|
-- le altre features gestite non hanno parametri Q
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function EvaluateQParam( Proc)
|
|
-- verifico che lo smusso sia richiesto
|
|
local nChamfer = 0
|
|
local dDepth = EgtGetInfo( Proc.Id, Q_DEPTH_CHAMFER, 'd') or 0
|
|
if dDepth > 0 then
|
|
nChamfer = 1
|
|
end
|
|
-- verifico se posso fare solo lo smusso
|
|
if EgtGetInfo( Proc.Id, Q_ONLY_CHAMFER, 'i') == 1 then
|
|
if dDepth > 0 then
|
|
nChamfer = nChamfer + 1
|
|
-- altrimenti se non ho l'affondamento esco
|
|
else
|
|
local sErr = 'Error : no chamfer depth'
|
|
EgtOutLog( sErr)
|
|
return -1, dDepth, sErr
|
|
end
|
|
end
|
|
-- verifico se devo usare lama invece della sega-catena
|
|
-- 2020-03-20 forzata abilitazione uso lama se parametro Q non è presente
|
|
-- xxxx-xx-xx tolta la preferenza alla lama in favore della sega-catena per un caso particolare
|
|
-- 2021-02-15 re-introdotta la preferenza alla lama se non c'è il parametro Q. Rimane da
|
|
-- implementare un ulteriore parametro per poter scegliere di prediligere la sega-catena o no al fine di continuare
|
|
-- a cambiare il codice per gestire il caso particolare
|
|
local bForceUseBlade = false
|
|
if #Q_FORCE_BLADE == 0 or EgtGetInfo( Proc.Id, Q_FORCE_BLADE, 'i') == 1 then
|
|
bForceUseBlade = true
|
|
end
|
|
|
|
return nChamfer, dDepth, sErr, bForceUseBlade
|
|
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 nFac3Adj = 0
|
|
local dMinArea3 = GEO.INFINITO * 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)
|
|
nFac3Adj = nFac3Adj + 1
|
|
end
|
|
end
|
|
if nFac3Adj ~= 2 then return false end
|
|
-- verifico se L profonda oppure lunga
|
|
if dMinArea3 < dMaxArea2 then
|
|
return 1
|
|
else
|
|
return 2
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function VerifyChainSaw( Proc, dMinDim, dMaxDim, vtOrtho)
|
|
local bUseChainSaw = false
|
|
local sMchFind = 'Sawing'
|
|
local sSawing = ML.FindSawing(sMchFind)
|
|
local dMaxMat = 0
|
|
local dSawCornerRad = 0
|
|
local dSawThick = 0
|
|
local dMaxDepth = 200
|
|
-- se non trova una lavorazione di sawing esco
|
|
if not sSawing then
|
|
return bUseChainSaw
|
|
else
|
|
-- recupero i dati dell'utensile
|
|
local dToolLength = 0
|
|
local dSawWidth = 75
|
|
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 + 10 * GEO.EPS_SMALL and dSawWidth < dMaxDim + 10 * GEO.EPS_SMALL then
|
|
bUseChainSaw = true
|
|
end
|
|
end
|
|
end
|
|
return bUseChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick, dMaxDepth
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function 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 feature BlockHausHalfLap e non abilitato parametro Q per lavorarlo di fianco esco
|
|
local nUseSideTool = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0
|
|
if Proc.Prc ~= 37 and nUseSideTool == 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
|
|
local bOppoFace = false
|
|
-- 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
|
|
bOppoFace = true
|
|
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 : missing AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- mi assicuro che la Z del punto utilizzato per creare la superficie 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)
|
|
-- creo superficie intermedia
|
|
local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN2, vtOrtho, b3Solid, GDB_ID.ROOT)
|
|
-- ritaglio la superficie 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 verifico anche con la faccia precedente
|
|
else
|
|
local nFaceToCheck = EgtIf( bOppoFace, nFacCnt-3, nFacCnt-2)
|
|
-- prendo le dimensioni della faccia e poi confronto con il minimo
|
|
_, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFaceToCheck, GDB_ID.ROOT)
|
|
-- se trovato con il minimo, questa seconda faccia non è la più lunga
|
|
if abs(DimH - dDimMin) < GEO.EPS_SMALL or abs(DimV - dDimMin) < GEO.EPS_SMALL then
|
|
nLongIdFace = nFacCnt-1
|
|
else
|
|
nLongIdFace = nFaceToCheck
|
|
end
|
|
end
|
|
if not dDimMax then
|
|
return dDimMin, dDimMax, dDepth, nil, nil
|
|
end
|
|
return dDimMin, dDimMax, dDepth, vtOrtho, nLongIdFace, nSurfInt
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetFaceAdj( Proc, nFacInd, dH, dV, bOutLog)
|
|
|
|
-- Recupero le facce adiacenti alla principale
|
|
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
|
|
if not vAdj or #vAdj == 0 then
|
|
local sErr = 'Error : main face without adjacencies'
|
|
return -1, sErr
|
|
end
|
|
if bOutLog then
|
|
EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3)
|
|
end
|
|
-- 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]
|
|
if bOutLog then
|
|
EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3)
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if not nFacAdj then
|
|
local sErr = 'Error : main face without long adjacent face'
|
|
return -1, sErr
|
|
end
|
|
return nFacAdj
|
|
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 and vtN:getZ() < BD.NZ_MINA and nFacInd2 then
|
|
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
nFacInd, nFacInd2 = nFacInd2, nFacInd
|
|
end
|
|
if vtN and 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
|
|
AssignQIdent( 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
|
|
local dEndDist = Proc.Box:getMin():getX() - b3Raw:getMin():getX()
|
|
if dEndDist > BD.MAX_DIST_HTFEA then
|
|
return false
|
|
end
|
|
-- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave
|
|
if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 * b3Raw:getDimX()) then
|
|
return false
|
|
end
|
|
-- 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 (oppure tunnel)
|
|
local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
if vtN and vtN:getZ() < BD.NZ_MINA and nFacInd2 then
|
|
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
nFacInd, nFacInd2 = nFacInd2, nFacInd
|
|
dElev, dElev2 = dElev2, dElev
|
|
end
|
|
if not vtN or vtN:getX() > -0.001 or dEndDist + vtN:getX() * dElev > 0 then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Classificazione della feature
|
|
function ProcessLapJoint.Classify( Proc, b3Raw)
|
|
-- 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.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) or
|
|
( not ( Proc.Head or Proc.Tail) and Proc.Box:getDimY() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()))
|
|
local bDown = ( vtN[1]:getZ() < BD.NZ_MINB and vtN[2]:getZ() < BD.NZ_MINB) or
|
|
( vtN[1]:getZ() < BD.NZ_MINA and ( vtN[2]:getZ() < -0.1 or not bSmall)) or
|
|
( vtN[2]:getZ() < BD.NZ_MINA and ( vtN[1]:getZ() < -0.1 or not bSmall))
|
|
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 VerifyChainSaw( 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 + 15 * GEO.EPS_SMALL) 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)
|
|
-- cerco se c'è faccia adiacente sul lato più lungo
|
|
local nFaceAdj = GetFaceAdj( Proc, nFacInd, dH, dV) or -1
|
|
local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2)
|
|
-- 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_MINB)
|
|
elseif not nFacInd2 and bIsL and nFaceAdj >= 0 then
|
|
local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFaceAdj, GDB_ID.ROOT)
|
|
bDown = ( vtN2:getZ() < BD.NZ_MINB)
|
|
end
|
|
-- verifico se la faccia principale è sottosquadra, ha forma L e anche la faccia adiacente
|
|
elseif vtN:getZ() < -10 * GEO.EPS_SMALL and bIsL and nFaceAdj >= 0 then
|
|
-- box del pezzo
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
-- se il numero di facce > 2 or il box della feature supera una certa distanza dalle teste allora controllo la z della faccia ausiiaria
|
|
if Proc.Fct > 2 or ( Proc.Box:getMax():getX() < b3Solid:getMin():getX() - 150) or ( Proc.Box:getMin():getX() > b3Solid:getMax():getX() + 150) then
|
|
local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFaceAdj, GDB_ID.ROOT)
|
|
bDown = ( vtN2:getZ() < BD.NZ_MINB)
|
|
end
|
|
end
|
|
return true, bDown
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Lavorazione con fresa
|
|
---------------------------------------------------------------------
|
|
local function MakeOneFaceByMill( Proc, 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 : 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 : BirdsMouth not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- inserisco la lavorazione di fresatura
|
|
local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}})
|
|
-- imposto uso faccia e lato correzione
|
|
if vtN:getX() > 0 then
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_LEFT, MCH_MILL_FU.PARAL_LEFT))
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.PARAL_RIGHT))
|
|
end
|
|
-- imposto lato di correzione
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
if not bUp then EgtSetMachiningParam( MCH_MP.INVERT, true) end
|
|
-- imposto posizione braccio porta testa
|
|
if vtN:getY() < GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
|
|
end
|
|
-- dichiaro non si generano sfridi per VMill
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;')
|
|
-- eseguo
|
|
if not 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 : 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')
|
|
-- predispongo lavorazione
|
|
local sMilling
|
|
-- verifico il parametro Q per uso fresa
|
|
local nUseRM = EgtGetInfo( Proc.Id, Q_USE_MILL, 'i')
|
|
if nUseRM and nUseRM == 1 then
|
|
sMilling = ML.FindMilling( 'LongSmallCut')
|
|
else
|
|
sMilling = ML.FindMilling( 'BirdsMouth')
|
|
end
|
|
-- recupero la lavorazione
|
|
local dTDiam = 0
|
|
if not sMilling then
|
|
local sErr = 'Error : LongSmallCut & BirdsMouth not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
else
|
|
-- recupero i dati dell'utensile
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam
|
|
end
|
|
end
|
|
-- dati delle facce
|
|
local ptC = {}
|
|
local vtN = {}
|
|
ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
|
|
-- dati medi
|
|
local ptM = ( ptC[1] + ptC[2]) / 2
|
|
-- verifico non siano orientate verso il basso
|
|
local bFaceOk = {}
|
|
bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB)
|
|
bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB)
|
|
if not bFaceOk[1] and not bFaceOk[2] then
|
|
local sErr = 'Error : LapJoint from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- scelta faccia da lavorare
|
|
local nFacInd
|
|
-- se entrambe possibili
|
|
if bFaceOk[1] and bFaceOk[2] then
|
|
-- se in testa, scelgo quella orientata verso la testa
|
|
if Proc.Head then
|
|
if vtN[1]:getX() > vtN[2]:getX() then
|
|
nFacInd = 0
|
|
else
|
|
nFacInd = 1
|
|
end
|
|
-- se altrimenti in coda, scelgo quella orientata verso la coda
|
|
elseif Proc.Tail then
|
|
if vtN[1]:getX() < vtN[2]:getX() then
|
|
nFacInd = 0
|
|
else
|
|
nFacInd = 1
|
|
end
|
|
-- altrimenti, scelgo quella con la normale più perpendicolare all'asse trave (se uguali, quella verso X+)
|
|
else
|
|
if abs( abs( vtN[1]:getX()) - abs( vtN[2]:getX())) < GEO.EPS_SMALL then
|
|
if ptM:getX() > b3Raw:getCenter():getX() then
|
|
nFacInd = EgtIf( vtN[1]:getX() > vtN[2]:getX(), 0, 1)
|
|
else
|
|
nFacInd = EgtIf( vtN[1]:getX() < vtN[2]:getX(), 0, 1)
|
|
end
|
|
else
|
|
nFacInd = EgtIf( abs( vtN[1]:getX()) < abs( vtN[2]:getX()), 0, 1)
|
|
end
|
|
end
|
|
elseif bFaceOk[1] then
|
|
nFacInd = 0
|
|
else
|
|
nFacInd = 1
|
|
end
|
|
local nOthInd = 1 - nFacInd
|
|
local sName
|
|
local nMchFId
|
|
local nFaceUse
|
|
-- se forzato uso fresa controllo se posso fare in una o più passate
|
|
if nUseRM and nUseRM == 1 then
|
|
-- prendo la larghezza della faccia
|
|
local _, pPt1, pPt2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nOthInd, GDB_ID.ROOT)
|
|
local dDistPoint = dist( pPt1, pPt2)
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local dWidth = EgtIf( abs( dDistPoint - dH) < abs( dDistPoint - dV), dV, dH)
|
|
-- se larghezza faccia maggiore diametro utensile aggiungo una lavorazione
|
|
if dTDiam > 0 and dWidth > dTDiam then
|
|
-- inserisco la lavorazione di fresatura
|
|
sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_1'
|
|
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
|
|
nFaceUse = BL.GetNearestOrthoOpposite( vtN[nOthInd+1])
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- imposto lato di correzione
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- tolgo l'inversione
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- aggiungo offset laterale
|
|
EgtSetMachiningParam( MCH_MP.OFFSR , (dTDiam/2))
|
|
-- 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
|
|
end
|
|
end
|
|
-- inserisco la lavorazione di fresatura
|
|
sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
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
|
|
nFaceUse = BL.GetNearestOrthoOpposite( vtN[nOthInd+1])
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- imposto lato di correzione
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- tolgo l'inversione
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- 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()
|
|
-- sempre concavo aumento la distanza (rimane una punta...)
|
|
dDist = dDist + 10
|
|
BL.UpdateHCING( nRawId, dOffs, dDist)
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakePreCuts( Proc, nPhase, nRawId, nPartId, dOvmHead, 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 : 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,
|
|
Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId}
|
|
local nCutFacet = EgtSurfTmFacetCount( AddId)
|
|
if nCutFacet == 1 then
|
|
return Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead)
|
|
elseif nCutFacet == 2 then
|
|
return DoubleCut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead)
|
|
end
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dElev, dCollSic, bSpecialApp, sMillMaster, nFacInd2, dFacElev2)
|
|
-- Cerco una faccia adiacente alla principale sul lato lungo
|
|
local nFacAdj, sErr = GetFaceAdj( Proc, nFacInd, dH, dV, true)
|
|
if nFacAdj < 0 then
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Determino se estremi aperti o chiusi e faccia adiacente da aggiungere alla lavorazione
|
|
local bOpenStart = false
|
|
local bOpenEnd = false
|
|
local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1]
|
|
EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3)
|
|
local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacAdj, GDB_ID.ROOT)
|
|
-- Riordino le dimensioni per avere dH > dV
|
|
if dH2 < dV2 then
|
|
dH2, dV2 = dV2, dH2
|
|
end
|
|
local nFacAdj2
|
|
for j = 1, #vAdj2 do
|
|
if vAdj2[j] == 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
|
|
sErr = 'Error : LongSmallCut not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dTDiam = 50
|
|
local dMaxMat = 0
|
|
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 + dCollSic 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
|
|
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
|
|
_, 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 = i+1, #vAdj do
|
|
if vAdj[j] >= 0 then
|
|
local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vAdj[i], vAdj[j], GDB_ID.ROOT)
|
|
if ptP1 and ptP2 and dAng < 0 then
|
|
local dLen = dist( ptP1, ptP2)
|
|
table.insert( tFacAdj, { vAdj[i], vAdj[j], dLen, ptP1, ptP2, dAng})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- tra le linee 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)
|
|
-- se non trovato nessun angolo interno valido esco
|
|
if #tFacAdj == 0 then
|
|
return true, sMyWarn
|
|
end
|
|
-- 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 : 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
|
|
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) 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)
|
|
-- se non trovato nessun angolo valido esco
|
|
if #tFacAdj == 0 then
|
|
return true, sMyWarn
|
|
end
|
|
-- 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)
|
|
-- 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 : clean corner milling from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- sommo i tre versori per avre una direzione media
|
|
vtExtr = vtN1 + vtN2 + vtN3
|
|
vtExtr:normalize()
|
|
-- recupero la lavorazione non calcolando l'elevazione
|
|
sMilling = ML.FindMilling( 'CleanCorner', (dDiam*0.5))
|
|
if not sMilling then
|
|
local sErr = 'Error : CleanCorner not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile ( temporaneo, per compensare errore nella lavorazione)
|
|
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 : 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 + uscita discostata rispetto all'ingresso
|
|
-- trovo il secondo punto sulla superfice di riferimento
|
|
_, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][2], GDB_ID.ROOT)
|
|
if ptLocP1 and ptLocP2 then
|
|
-- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro
|
|
if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then
|
|
ptApPoint = ptLocP2
|
|
else
|
|
ptApPoint = ptLocP1
|
|
end
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB)
|
|
dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - (( dDiam/2) + 2)
|
|
-- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta
|
|
if dLenTrimExt > 10 * GEO.EPS_SMALL then
|
|
EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint , GDB_RT.GLOB)
|
|
-- prendo il nuovo punto finale
|
|
ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB)
|
|
end
|
|
table.insert( pAuxId, nAuxId)
|
|
-- creo linea di ritorno
|
|
nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
-- piccolo scostamento di 2mm dall'angolo
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
-- ultima linea di risalita
|
|
nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), tFacAdj[nIdLine][nIdIniPoint] + ( 2 * vtExtr), GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
end
|
|
-- trasformo in percorso
|
|
if #pAuxId > 0 then
|
|
AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true)
|
|
end
|
|
-- se non c'é il percorso do errore
|
|
if not AuxId then
|
|
local sErr = 'Error : impossible make clean corner path'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- modifico versore direzione
|
|
EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB)
|
|
-- inserisco la lavorazione
|
|
local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local 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)
|
|
-- se non trovato nessun angolo interno valido esco
|
|
if #tFacAdj == 0 then
|
|
return true, sMyWarn
|
|
end
|
|
-- trovo il punto sulla superfice di riferimento
|
|
local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT)
|
|
local nIdIniPoint
|
|
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 : drilling from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero la lavorazione
|
|
local sDrilling, nType = ML.FindDrilling( dDiam)
|
|
if not sDrilling then
|
|
local sErr = 'Error : drilling not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dMaxDepth = 20
|
|
local dDiamTool = 20
|
|
local dDiamTh = 35
|
|
local bIsDrilling
|
|
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)
|
|
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 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 MakeChamfer( Proc, b3FacesUsed, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham)
|
|
|
|
-- Se variabile globale indica che lo smusso è gi stato fatto, esco
|
|
if bMadeChamfer then
|
|
return 0
|
|
end
|
|
bMadeChamfer = true
|
|
-- recupero la lavorazione
|
|
local sMilling = ML.FindMilling( 'Mark')
|
|
if not sMilling then
|
|
local sErr = 'Error : Mark not found in library'
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
-- ottengo le curve di contorno libero
|
|
local nAuxId1, nAuxId2, nNumIdAux
|
|
if 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 : chamfer skipped because not perpendicular to face or from bottom'
|
|
-- EgtOutLog( sWarn)
|
|
end
|
|
--emetto un warning
|
|
-- else
|
|
-- sWarn = 'Warning : chamfer skipped because not perpendicular to face'
|
|
-- EgtOutLog( sWarn)
|
|
end
|
|
end
|
|
|
|
return 0
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd,
|
|
rfFac, dH, dV, dElev, bForceUseBlade,
|
|
dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace,
|
|
bOrthoFacesMaster, nBottomFace, nChamfer, nAddGrpId, b3Solid,
|
|
dDepthCham, b3FacesUsed)
|
|
local bOrthoFaces
|
|
local sWarn
|
|
-- ingombro del grezzo
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
-- ottengo la distanza tra la fine del pezzo e il pezzo successivo
|
|
local dDistToNextPiece = EgtGetInfo( nRawId, 'BDST', 'd') or 5.4
|
|
if b3FacesUsed then
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
local nFacInd1, dFacElev1, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, b3FacesUsed)
|
|
if not nFacInd1 or nFacInd1 < 0 then
|
|
if nFacInd1 == -1 then
|
|
bOrthoFaces = nFacInd2
|
|
else
|
|
local sErr = 'Error : MakeByPockets could not find reference face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
else
|
|
bOrthoFaces = bOrthoFacesMaster
|
|
end
|
|
|
|
if bOrthoFaces then
|
|
-- ottengo le dimensioni del tunnel
|
|
_, _, _, vtOrtho, _, nSurfInt = GetTunnelDimension( Proc, nPartId)
|
|
-- verifico la direzione
|
|
-- se devo inserire il chamfer
|
|
if nChamfer > 0 then
|
|
local nOk, sErr = MakeChamfer( Proc, b3FacesUsed, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham)
|
|
if nOk < 0 then return false, sErr end
|
|
end
|
|
end
|
|
-- Recupero le facce adiacenti alla principale
|
|
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
|
|
if not vAdj or #vAdj == 0 then
|
|
local sErr = 'Error : main face without adjacencies'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3)
|
|
-- Cerco una faccia adiacente alla principale sul lato più lungo
|
|
local nFacAdj
|
|
local dMaxLen = 0
|
|
for i = 1, #vAdj do
|
|
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 : 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
|
|
local vtNS, vtNE
|
|
-- se non ho la faccia di fondo ( che comporta essere una fessura) verifico se ho lati aperti
|
|
if not nBottomFace then
|
|
local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1]
|
|
EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3)
|
|
for j = 1, #vAdj2 do
|
|
if vAdj2[j] == 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 è chiusa acquisisco vettore faccia tappo
|
|
if not bOpenStart and vAdj2[i] >= 0 then
|
|
_, vtNS = EgtSurfTmFacetCenter( Proc.Id, vAdj2[i], GDB_ID.ROOT)
|
|
end
|
|
-- Se non esiste faccia adiacente a lato successivo -> fine aperto
|
|
local k = EgtIf( j < #vAdj2, j + 1, 1)
|
|
while vAdj2[k] == nFacInd do
|
|
k = EgtIf( k < #vAdj2, k + 1, 1)
|
|
end
|
|
bOpenEnd = ( vAdj2[k] < 0)
|
|
-- se è chiusa acquisisco vettore faccia tappo
|
|
if not bOpenEnd and vAdj2[k] >= 0 then
|
|
_, vtNE = EgtSurfTmFacetCenter( Proc.Id, vAdj2[k], GDB_ID.ROOT)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- Recupero il massimo affondamento possibile con la lama
|
|
local dSawMaxDepth = 0
|
|
local sCutting = ML.FindCutting( 'HeadSide')
|
|
if sCutting then
|
|
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 : HeadSide (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 : sawblade too thick'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Calcolo uso faccia
|
|
local nFaceUse = BL.GetNearestOrthoOpposite( rfFac:getVersZ())
|
|
-- 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
|
|
-- in base all'elevazione calcolo l'impronta della lama
|
|
local dUsedBladeLen = sqrt( ((dSawDiam / 2)*(dSawDiam / 2)) - ( ( (dSawDiam / 2) - dElev) * ( (dSawDiam / 2) - dElev)))
|
|
-- controllo direzione taglio e se il minimo della feature sborda in coda
|
|
if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then
|
|
-- do avviso che la lama può sbordare nel pezzo successivo
|
|
sWarn = 'Warning on saw cut : Cut machining can damage next piece'
|
|
EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')')
|
|
end
|
|
-- altrimenti con sega a catena
|
|
else
|
|
-- Recupero la lavorazione
|
|
local sSawing = ML.FindSawing( 'Sawing')
|
|
if not sSawing then
|
|
local sErr = 'Error : Sawing not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr, 'MNF'
|
|
end
|
|
-- Recupero i dati dell'utensile
|
|
local dSawWidth = 75
|
|
local dSawThick = 8
|
|
local dMaxDepth = 200
|
|
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 : 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 normale faccia adiacente
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT)
|
|
-- 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)
|
|
-- controllo direzione taglio e se il minimo della feature sborda in coda
|
|
if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL then
|
|
-- se ho lato partenza aperto e lato uscita chiuso e direzione lato chiuso è negativa, allora controllo uscita lama
|
|
if bOpenStart and not bOpenEnd and vtNE:getX() < -0.99 and dDistToNextPiece < (dSawWidth / 2) then
|
|
-- imposto accorciamento iniziale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dDistToNextPiece - 1 - (dSawWidth / 2))
|
|
else
|
|
-- imposto accorciamento iniziale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2))
|
|
end
|
|
-- se ho lato uscita aperto e lato partenza chiuso e direzione lato partenza è negativa, allora controllo uscita lama
|
|
if bOpenEnd and not bOpenStart and vtNS:getX() < -0.99 and dDistToNextPiece < (dSawWidth / 2) then
|
|
-- imposto accorciamento finale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dDistToNextPiece - 1 - (dSawWidth / 2))
|
|
else
|
|
-- imposto accorciamento finale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2))
|
|
end
|
|
else
|
|
-- imposto accorciamento iniziale/finale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2))
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2))
|
|
end
|
|
-- imposto angolo 3° asse rot
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, EgtIf( BD.C_SIMM, 'A=90', 'A=0'))
|
|
-- 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)
|
|
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
|
|
if EgtGetOutstrokeInfo() then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, EgtIf( BD.C_SIMM, 'A=0', 'A=90'))
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
if 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 = VerifyChainSaw( 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
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, EgtIf( BD.C_SIMM, 'A=90', 'A=0'))
|
|
-- 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 : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
if EgtGetOutstrokeInfo() then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, EgtIf( BD.C_SIMM, 'A=0', 'A=90'))
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
if 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 : HeadSide (cutting) not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dSawDiam = 400
|
|
local dSawThick = 0
|
|
if EgtMdbSetCurrMachining( sCutting) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
|
|
dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick
|
|
end
|
|
end
|
|
-- eseguo il taglio
|
|
local bMadeASbyBld, sWarn, nIdMach = BL.MakeOneFaceBySaw( Proc.Id, nFacet, sCutting, dSawDiam, vtN, nil, -0.5, BD.CUT_SIC, 0, 0, nil, b3Raw)
|
|
return bMadeASbyBld, sWarn, nIdMach, dSawThick
|
|
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 : '..sMchFind..' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
dDiamTool = 20
|
|
local dMaxDepth = 0
|
|
local sTuuidPk
|
|
if EgtMdbSetCurrMachining( sPocketing) then
|
|
sTuuidPk = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuidPk) or '') then
|
|
dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth)
|
|
dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
|
|
end
|
|
end
|
|
-- se nome svuotatura non è stato ricalcolato, confronto il diametro utensile utilizzato con il minimo faccia e se non sono compatibili esco
|
|
if sMasterPocket and dFaceDiamTool and dDiamTool >= dFaceDiamTool then
|
|
return false, '', sTuuidPk, dDiamTool, dElev
|
|
end
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. 'F' .. tostring( nFaceRef)
|
|
local 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
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
if AreSameVectorApprox( tvtN[2], Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( tvtN[2]:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( EgtGetCurrPhase()), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif tvtN[2]:getY() > 0.1 then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
end
|
|
else
|
|
nSCC = MCH_SCC.NONE
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- 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 : 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 = 40
|
|
|
|
-- se feature é larga come trave imposto openpocket
|
|
if nDiffWidth == 0 then
|
|
sMchFind = 'OpenPocket'
|
|
-- altrimenti non è passante disabilito il truciolatore
|
|
else
|
|
nUseRoughTool = 0
|
|
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 = dAng + 90
|
|
-- se l'angolo dalla verticale si discosta di più dell'angolo limite impostato, utilizzo la svuotatura
|
|
if cos( dDiffFromSqAng) < cos( dAngLimit) then
|
|
-- applico la svuotatura
|
|
local bOk, sWarn, sTuuidPk, dDiamTool, dElev = MakePocket( Proc, 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 : Long2Cut 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 : Long2Cut & LongSmallCut 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 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 CheckToolDiamByFaces( Proc, nFacInd, dH, dV, bIsU, bIsL, dElev, nUseRoughTool)
|
|
local dMaxDimFace = max( dH, dV)
|
|
-- verifico che diametro utensile prende con la openpocket con la massima dimensione faccia
|
|
local bUseMaxTool, dMaxDiam
|
|
-- se è forzato l'uso del truciolatore non passo l'altezza di elevazione
|
|
if nUseRoughTool and nUseRoughTool == 1 then
|
|
bUseMaxTool, dMaxDiam = CheckPocketTool( 'OpenPocket', dMaxDimFace)
|
|
else
|
|
bUseMaxTool, dMaxDiam = CheckPocketTool( 'OpenPocket', dMaxDimFace, dElev)
|
|
end
|
|
-- 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
|
|
-- Normale della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- Cerco le facce adiacenti alla principale con angolo concavo >= 90
|
|
local tWidth = {}
|
|
local tExtremPt = {}
|
|
for i = 1, #vAdj do
|
|
if vAdj[i] >= 0 then
|
|
-- verifico l'angolo tra le facce ( esco se angolo compreso < 90)
|
|
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT)
|
|
if bAdj and dAng < -90 - 20 * GEO.EPS_ANG_SMALL then
|
|
return false
|
|
end
|
|
-- larghezza della faccia ortogonalmente alla adiacente
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT)
|
|
local vtX = vtN2 ^ vtN
|
|
local frRef = Frame3d( ptC, ptC + 100 * vtX, ptC + 100 * vtN2)
|
|
local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, nFacInd, GDB_BB.STANDARD, frRef)
|
|
if b3Ref then
|
|
table.insert( tWidth, b3Ref:getDimY())
|
|
table.insert( tExtremPt, { ptP1, ptP2})
|
|
end
|
|
end
|
|
end
|
|
-- se le facce di adiacenza non corrispondono con quelle della forma esco
|
|
if ( bIsU and #tWidth ~= 2) or ( bIsL and #tWidth ~= 1) then
|
|
return false
|
|
end
|
|
local dLargeVal = 0
|
|
for i = 1, #tWidth do
|
|
dLargeVal = max( dLargeVal, tWidth[i])
|
|
end
|
|
-- se facce U verifico se le distanze tra i punti sono minori delle distanze tra le facce
|
|
if bIsU then
|
|
local dLen11 = dist( tExtremPt[1][1], tExtremPt[2][1])
|
|
local dLen12 = dist( tExtremPt[1][1], tExtremPt[2][2])
|
|
local dLen21 = dist( tExtremPt[1][2], tExtremPt[2][1])
|
|
local dLen22 = dist( tExtremPt[1][2], tExtremPt[2][2])
|
|
dLargeVal = min( dLargeVal, dLen11, dLen12, dLen21, dLen22)
|
|
end
|
|
-- se forma a L, raggio inferiore alla dimensione minima e flag uso truciolatore, favorisco il suo utilizzo
|
|
if bIsL and nUseRoughTool == 1 and dMaxDiam / 2 < dLargeVal then
|
|
return dMaxDiam, 'OpenPocket', nUseRoughTool, dMaxDiam
|
|
else
|
|
-- per essere accettabile, il diametro massimo deve essere minore della larghezza della faccia
|
|
if dMaxDiam < dLargeVal + 20 * GEO.EPS_SMALL then
|
|
return dMaxDiam, 'OpenPocket', nUseRoughTool, dMaxDiam
|
|
else
|
|
return false, '', 0, dMaxDiam
|
|
end
|
|
end
|
|
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
|
|
local bBadMach = false
|
|
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 : 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
|
|
local nOk, sErr = MakeChamfer( Proc, b3FacesUsed, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham)
|
|
if nOk < 0 then return -1, sErr 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 : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
-- altrimenti setto il flag per fare la svuotatura da due parti
|
|
else
|
|
-- se l'altezza utensile riesce a lavorare completamente da due parti
|
|
if dMaxMat > (dDepth / 2) then
|
|
dMachDepth = 1
|
|
dElev = (dDepth / 2) + 1
|
|
-- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione
|
|
else
|
|
dMachDepth = dMaxMat - (dDepth / 2)
|
|
dElev = dMaxMat
|
|
-- se sono in questo caso verifico la direzione, se le componenti x,y e z deviano molto
|
|
-- allora considero la lavorazione no idonea perchè potrebbe avere anche delle collisioni
|
|
if abs(vtOrtho:getX()) > 0.5 or abs(vtOrtho:getY()) > 0.5 or abs(vtOrtho:getZ()) > 0.5 then
|
|
bBadMach = true
|
|
end
|
|
end
|
|
bDoubleSide = true
|
|
end
|
|
end
|
|
-- se lavorazione non idonea esco
|
|
if b3FacesUsed and bBadMach then
|
|
local sErr = 'Impossible apply perpendicular pocketing: ' .. sPocketing
|
|
return -2, sErr
|
|
end
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local 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 : 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, dOvmHead, bSinglePart)
|
|
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 : 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 : missing AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local bClosedOrthoFaces
|
|
local nFacInd, dFacElev, nFacInd2, dFacElev2
|
|
local nBottomFace
|
|
local sMchFindBackUp
|
|
-- 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 : 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 : 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)
|
|
-- 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 = VerifyChainSaw( 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)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK)
|
|
end
|
|
-- imposto angolo 3° asse rot
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, EgtIf( BD.C_SIMM, 'A=90', 'A=0'))
|
|
-- 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 : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
-- eseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
if EgtGetOutstrokeInfo() then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, EgtIf( BD.C_SIMM, 'A=0', 'A=90'))
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
if 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 + 15 * GEO.EPS_SMALL) 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 lavorando la faccia principale rimane esclusa molta sezione trasversale complessiva della feature (da box)
|
|
local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local bBoxF = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfFac)
|
|
if dH * dV < 0.9 * ( bBoxF:getDimX() * bBoxF:getDimY()) then
|
|
bSpecial3faces = true
|
|
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 : 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, dOvmHead, 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 : LongSmallCut 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, Q_USE_ROUGH_TOOL, '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 : '..sMchFind..' 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, dCollSic, true, sMilling, nFacInd2, dFacElev2)
|
|
if not bOk then return bOk, sWarn end
|
|
else
|
|
local sErr = 'Error : Impossible mill special LapJoint'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, sPocketing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, 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, Q_BORE_ON_CORNER, '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
|
|
-- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura
|
|
elseif EgtGetInfo( Proc.Id, Q_BORE_ON_CORNER, 'i') == 2 then
|
|
local bOk
|
|
bOk, sWarn = MakeCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, 0, nAddGrpId, dDiamTool)
|
|
if not bOk then return false, sWarn end
|
|
end
|
|
end
|
|
-- altrimenti lavorazione di svuotatura o contornatura
|
|
else
|
|
local bUseOtherFace
|
|
-- se orientata verso il basso e non c'è testa da sotto, verifico l'alternativa
|
|
if vtN:getZ() < BD.NZ_MINA and not BD.DOWN_HEAD and nFacInd2 then
|
|
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
nFacInd, nFacInd2 = nFacInd2, nFacInd
|
|
dFacElev, dFacElev2 = dFacElev2, dFacElev
|
|
bUseOtherFace = true
|
|
end
|
|
-- verifico non sia orientata verso il basso o ci sia una testa dal basso
|
|
local bFaceDown = ( vtN:getZ() < BD.NZ_MINA)
|
|
if bFaceDown and not BD.DOWN_HEAD then
|
|
local sErr = 'Error : LapJoint from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- se forma a L e la componente in X è maggiore di 60° allora verifico se posso utilizzare la faccia secondaria
|
|
if bIsL and abs( vtN:getX()) > 0.866 then
|
|
-- se non ho scambiato la faccia
|
|
if not bUseOtherFace then
|
|
if nFacInd2 then
|
|
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
|
|
nFacInd, nFacInd2 = nFacInd2, nFacInd
|
|
dFacElev, dFacElev2 = dFacElev2, dFacElev
|
|
-- altrimenti cerco la faccia secondaria per adiacenza alla principale
|
|
else
|
|
-- Cerco una faccia adiacente alla principale sul lato lungo
|
|
local nFacAdj, sErr = GetFaceAdj( Proc, nFacInd, dH, dV)
|
|
if nFacAdj < 0 then
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
nFacInd = nFacAdj
|
|
dFacElev = BL.GetFaceElevation( Proc.Id, nFacInd)
|
|
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
end
|
|
-- altrimenti se ho già cambiato faccia do errore per impossibilità di lavorazione
|
|
else
|
|
local sErr = 'Error : impossible to machine by side angle too big that cause collision'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- eventuali tagli preliminari
|
|
do
|
|
local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, nChamfer)
|
|
if not bOk then return false, sErr end
|
|
end
|
|
-- imposto altezza aggiuntiva di elevazione
|
|
local dCollSic = 8 * BD.COLL_SIC
|
|
if abs( vtN:getX()) > 0.996 or abs( vtN:getY()) > 0.996 or abs( vtN:getZ()) > 0.996 then
|
|
dCollSic = 0
|
|
elseif abs( vtN:getX()) > 0.866 or abs( vtN:getY()) > 0.866 or abs( vtN:getZ()) > 0.866 then
|
|
dCollSic = 2 * BD.COLL_SIC
|
|
elseif abs( vtN:getX()) > 0.707 or abs( vtN:getY()) > 0.707 or abs( vtN:getZ()) > 0.707 then
|
|
dCollSic = 5 * BD.COLL_SIC
|
|
end
|
|
-- settaggio voluto da Alessandro
|
|
local sMchFind = EgtIf( bSinglePart, 'Pocket', 'OpenPocket')
|
|
sMchFindBackUp = sMchFind
|
|
local nUseRoughTool = EgtIf( bSinglePart, 0, 1)
|
|
-- fino a che nelle svuotature non si può decidere il punto di inizio faccio delle valutazioni
|
|
-- se ho passi multipli controllo il numero delle facce
|
|
if not bSinglePart then
|
|
-- se ho 3 o più facce allora re-imposto il tipo di svuotatura
|
|
if ( Proc.Fct == 3 and bIsU) or Proc.Fct > 3 then
|
|
sMchFind = 'Pocket'
|
|
end
|
|
end
|
|
local dDiam = min( dH, dV)
|
|
local dDiamMax
|
|
local nUseRT
|
|
-- 04/08/2020 su richiesta di Fabio Squaratti, se settato parametro uso truciolatore (parametro Q), non si devono prendere altre frese,
|
|
-- piuttosto si da errore con il truciolatore.
|
|
-- Sicuramente questa opzione si scontra facilmente con altre interpretazioni dello stasso parametro Q
|
|
-- per tornare comportamento precedente settare bNewCheck = false
|
|
local bNewCheck = true
|
|
-- se processo 20 e non sto usando il truciolatore
|
|
if bNewCheck and Proc.Prc == 20 and nUseRoughTool == 0 then
|
|
-- verifico se forzato uso truciolatore
|
|
nUseRT = EgtGetInfo( Proc.Id, Q_USE_ROUGH_TOOL, 'i')
|
|
if nUseRT and nUseRT ~= 0 then
|
|
sMchFind = 'OpenPocket'
|
|
nUseRoughTool = 1
|
|
end
|
|
end
|
|
-- 03/12/2020 aggiunto controllo su feature 30
|
|
-- se processo 30 e non sto usando il truciolatore
|
|
if bNewCheck and Proc.Prc == 30 and nUseRoughTool == 0 then
|
|
-- verifico se forzato uso truciolatore
|
|
nUseRT = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i')
|
|
if nUseRT and nUseRT ~= 0 then
|
|
sMchFind = 'OpenPocket'
|
|
nUseRoughTool = 1
|
|
end
|
|
end
|
|
-- verifico dalla forma se non posso prendere utensile grande
|
|
if ( Proc.Fct == 3 and bIsU and bSinglePart) or ( Proc.Fct == 2 and bIsL) or Proc.Fct == 1 then
|
|
sMchFindBackUp = sMchFind
|
|
--ottengo un diametro utensile opportuno
|
|
dDiam, sMchFind, nUseRoughTool, dDiamMax = CheckToolDiamByFaces( Proc, nFacInd, dH, dV, bIsU, bIsL, ( dFacElev + dCollSic), nUseRoughTool)
|
|
if not dDiam then
|
|
if nUseRoughTool == 0 then
|
|
sMchFind = 'OpenPocket'
|
|
end
|
|
dDiam = min( dH, dV)
|
|
end
|
|
end
|
|
-- se processo 20 e non sto usando il truciolatore
|
|
if Proc.Prc == 20 and nUseRoughTool == 0 then
|
|
if nUseRT and nUseRT ~= 0 then
|
|
sMchFind = 'OpenPocket'
|
|
nUseRoughTool = 1
|
|
if dDiamMax and Proc.Fct == 2 and bIsL then
|
|
dDiam = dDiamMax
|
|
end
|
|
end
|
|
end
|
|
-- abilitazione lavorazione da sotto
|
|
local bMillUp = ( BD.DOWN_HEAD and vtN:getZ() > -0.259)
|
|
local bMillDown = ( BD.DOWN_HEAD and vtN:getZ() < 0.342)
|
|
--EgtOutLog( 'Mortise Find Diam =' .. EgtNumToString( dDiam))
|
|
-- ricerca lavorazione
|
|
local sPocketing
|
|
local sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind .. EgtIf( bMillDown, '_H2', ''), dDiam, dFacElev + dCollSic)
|
|
if not sMyPocketing then
|
|
sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind .. EgtIf( bMillDown, '_H2', ''), dDiam)
|
|
end
|
|
if not sMyPocketing and bMillUp then
|
|
sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam, dFacElev + dCollSic)
|
|
if not sMyPocketing then
|
|
sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam)
|
|
end
|
|
bMillDown = false
|
|
end
|
|
if sMyPocketing and ( dMyTMaxDepth > 0.8 * dFacElev + dCollSic or ( bIsL and nUseRoughTool == 0)) then
|
|
sPocketing = sMyPocketing
|
|
end
|
|
if bMillDown then
|
|
sMchFind = sMchFind ..'_H2'
|
|
end
|
|
-- se feature 16 o 17 e forzata lama e forma ad U, annulla la svuotatura
|
|
if ( Proc.Prc == 16 or Proc.Prc == 17) and bForceUseBlade and Proc.Fct == 3 and bIsU then
|
|
sPocketing = nil
|
|
end
|
|
-- 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, dCollSic)
|
|
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
|
|
-- se feature 16 o 17 e se forzata lama provo prima con questa e poi con la fresa
|
|
if ( Proc.Prc == 16 or Proc.Prc == 17) and bForceUseBlade then
|
|
-- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame
|
|
if bTryWithBlades and nChamfer < 2 then
|
|
bOk, sWarn, sStat = MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd,
|
|
rfFac, dH, dV, dFacElev, bForceUseBlade,
|
|
dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace,
|
|
bOrthoFaces, nBottomFace, nChamfer, nAddGrpId, b3Solid,
|
|
dDepthCham, true)
|
|
if not bOk then
|
|
-- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e
|
|
-- se non è possibile allora provo in seguito con lama o segacatena
|
|
-- o passare subito dalla lavorazione con lama/sega catena
|
|
if Proc.Fct == 3 and bIsU then
|
|
-- lavoro con svuotature (singola o doppia contrapposta)
|
|
nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMchFind, true, b3Solid)
|
|
-- se lavorazione non idonee ( asse della feature troppo inclinato e impossibile lavorare completamente da due parti)
|
|
if nOk == -2 then
|
|
if not sMchFind then
|
|
sMchFind = sMchFindBackUp
|
|
end
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam)
|
|
if not sPocketing then
|
|
local sErr = 'Error : '..sMchFind..' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
elseif nOk < 0 then
|
|
return false, sErr
|
|
elseif nOk == 0 then
|
|
if sStat == 'MNF' then
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam)
|
|
if not sPocketing then
|
|
local sErr = 'Error : '..sMchFind..' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
else
|
|
return bOk, sWarn
|
|
end
|
|
else
|
|
bOk = true
|
|
return bOk, sErr
|
|
end
|
|
else
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam)
|
|
if not sPocketing then
|
|
local sErr = 'Error : '..sMchFind..' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
else
|
|
return bOk, sWarn
|
|
end
|
|
else
|
|
-- se devo inserire il chamfer
|
|
if ( ( Proc.Fct == 3 and bIsU) or (Proc.Fct == 2 and bIsL)) and nChamfer > 0 then
|
|
-- ottengo le dimensioni dello pseudotunnel
|
|
local _, _, _, vtOrtho, _, nSurfInt = GetTunnelDimension( Proc, nPartId)
|
|
local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham)
|
|
if nOk < 0 then return false, sErr end
|
|
end
|
|
bOk = true
|
|
return bOk, sWarn
|
|
end
|
|
else
|
|
-- 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 == -2 then
|
|
if not sMchFind then
|
|
sMchFind = sMchFindBackUp
|
|
end
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam)
|
|
if not sPocketing then
|
|
local sErr2 = 'Error : '..sMchFind..' not found in library'
|
|
EgtOutLog( sErr2)
|
|
return false, sErr2
|
|
end
|
|
bTryWithBlades = false
|
|
sWarn = sErr
|
|
elseif nOk < 0 then
|
|
return false, sErr
|
|
elseif nOk > 0 then
|
|
bTryWithBlades = false
|
|
sWarn = sErr
|
|
end
|
|
bOk = true
|
|
end
|
|
-- 03/09/2020 da conferma di Fabio Squaratti: Per ora solo sulla feature 016:
|
|
-- se ha fallito la fresatura (qua sopra) allora di defalut ( anche se il flag Q della lama è disattivato) prima provo la lama
|
|
if Proc.Prc == 16 then
|
|
bForceUseBlade = true
|
|
end
|
|
-- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame
|
|
if bTryWithBlades and nChamfer < 2 then
|
|
bOk, sWarn, sStat = MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd,
|
|
rfFac, dH, dV, dFacElev, bForceUseBlade,
|
|
dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace,
|
|
bOrthoFaces, nBottomFace, nChamfer, nAddGrpId, b3Solid,
|
|
dDepthCham)
|
|
if not bOk and sStat == 'MNF' then
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam)
|
|
if not sPocketing then
|
|
local sErr2 = 'Error : '..sMchFind..' not found in library'
|
|
EgtOutLog( sErr2)
|
|
return false, sErr2
|
|
end
|
|
else
|
|
return bOk, sWarn
|
|
end
|
|
-- altrimenti verifico se ho già svuotato dal fianco, se si esco
|
|
else
|
|
-- se non ho annullato la/le svuotatura/e dal fianco
|
|
if nOk ~= -2 then
|
|
return bOk, sWarn
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
-- se devo inserire il chamfer
|
|
if ( ( Proc.Fct == 3 and bIsU) or (Proc.Fct == 2 and bIsL)) and nChamfer > 0 then
|
|
-- ottengo le dimensioni dello pseudotunnel
|
|
local _, _, _, vtOrtho, _, nSurfInt = GetTunnelDimension( Proc, nPartId)
|
|
local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham)
|
|
if nOk < 0 then return false, sErr end
|
|
end
|
|
end
|
|
-- se richiesti antischeggia con lama su U trasversale e smusso non esclusivo
|
|
-- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa
|
|
-- 15.02.2021 esegue antischeggia di lama se forma U o L ma con numero lati verificati oppure forma U o L ma con feature passante in Y o Z
|
|
local bMadeASbyBld = false
|
|
local bPassThrou = ( Proc.Box:getDimY() > b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > b3Raw:getDimZ() - 1)
|
|
if nChamfer < 2 and EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') == 1 and
|
|
( ( ( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 2 and bIsL)) or ( ( bIsU or bIsL) and bPassThrou)) then
|
|
local nNumFac = EgtIf( bIsU, 2, 1)
|
|
local nPrefSide = 1 -- di preferenza il motore è meglio tenerlo sinistra
|
|
-- se a U cerco di ottimizzare il lato di lavoro della lama
|
|
if bIsU then
|
|
if abs( vtN:getY()) > 0.996 then
|
|
nPrefSide = 0
|
|
elseif abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then
|
|
-- elseif abs( vtN:getZ()) > 0.7 or abs( vtN:getY()) > 0.7 then
|
|
-- se X è negativa allora devo tenere il motore a destra
|
|
if vtN:getX() < -(10 * GEO.EPS_SMALL) then
|
|
nPrefSide = 2
|
|
end
|
|
end
|
|
end
|
|
-- va eseguito sulle facce diverse dalla principale
|
|
local nPrevSCC = nil
|
|
for nFacet = 0, nNumFac do
|
|
if nFacet ~= nFacInd then
|
|
-- lavoro
|
|
local dSawThick = 0
|
|
bMadeASbyBld, sWarn, nIdMach, dSawThick = MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw)
|
|
if not bMadeASbyBld then return false, sWarn end
|
|
-- verifico se da invertire
|
|
local bInvertMach = false
|
|
if bIsU then
|
|
if abs(vtN:getZ()) > 0.63 or abs(vtN:getY()) > 0.63 then
|
|
-- if abs(vtN:getZ()) > 0.7 or abs(vtN:getY()) > 0.7 then
|
|
-- prendo il vettore normale alla faccia
|
|
local _, vtNFc = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT)
|
|
-- valuto l'angolo tra le due facce
|
|
local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacet, GDB_ID.ROOT)
|
|
-- se superficie principale parallela al piano XZ
|
|
if nPrefSide == 0 then
|
|
-- se facce inclinate \\ allora mandrino a destra (per essere verso l'alto)
|
|
if vtNFc:getX() * vtNFc:getZ() > 0 then
|
|
nPrefSide = 2
|
|
-- altrimenti facce inclinate // quindi mandrino a sinistra (per essere ancora verso l'alto)
|
|
else
|
|
nPrefSide = 1
|
|
end
|
|
end
|
|
-- se faccia verso X+ e mandrino verso sinistra
|
|
if vtNFc:getX() > 0 and nPrefSide == 1 then
|
|
-- se angolo interno e circa -90
|
|
if abs( dAng + 90) < 5 then
|
|
bInvertMach = true
|
|
end
|
|
-- se faccia verso X- e mandrino verso destra
|
|
elseif vtNFc:getX() < 0 and nPrefSide == 2 then
|
|
-- se angolo interno e circa -90
|
|
if abs( dAng + 90) < 5 then
|
|
bInvertMach = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- eseguo inversione
|
|
if bInvertMach then
|
|
local bToolInvert = EgtGetMachiningParam( MCH_MP.TOOLINVERT)
|
|
local nWS = EgtGetMachiningParam( MCH_MP.WORKSIDE)
|
|
local nInvWS = EgtIf( nWS == MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)
|
|
local nFaceUse = EgtGetMachiningParam( MCH_MP.FACEUSE)
|
|
local bOrtUp = ( nFaceUse >= MCH_MILL_FU.ORTUP_DOWN and nFaceUse <= MCH_MILL_FU.ORTUP_RIGHT)
|
|
if not bOrtUp then
|
|
-- assegno i parametri invertiti
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, nInvWS)
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, not bToolInvert)
|
|
-- setto l'offset pari allo spessore lama
|
|
EgtSetMachiningParam( MCH_MP.OFFSL, -dSawThick)
|
|
end
|
|
end
|
|
-- posizione del braccio : se primo taglio la recupero, altrimenti la imposto
|
|
if not nPrevSCC then
|
|
nPrevSCC = EgtGetMachiningParam( MCH_MP.SCC)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, nPrevSCC)
|
|
end
|
|
-- rieseguo
|
|
if not EgtApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nIdMach, false)
|
|
return false, sErr
|
|
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 + dCollSic)
|
|
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 : 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, Q_BORE_ON_CORNER, '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, Q_BORE_ON_CORNER, '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, Q_CONTOUR_SMALL_TOOL, '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, dOvmHead)
|
|
-- recupero gruppo per geometria addizionale
|
|
local nAddGrpId = BL.GetAddGroup( nPartId)
|
|
if not nAddGrpId then
|
|
local sErr = 'Error : missing AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero l'ingombro del grezzo di appartenenza
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
-- la divido in parti lungo X
|
|
local vAddId = {}
|
|
local nPart = max( ceil( Proc.Box:getDimX() / BD.LONGCUT_MAXLEN), 2)
|
|
local dPartLen = Proc.Box:getDimX() / nPart
|
|
local Xmin = Proc.Box:getMin():getX()
|
|
for i = 1, nPart do
|
|
-- eseguo divisione
|
|
local AddId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL
|
|
EgtSetName( AddId, 'AddPart_' .. tostring( Proc.Id) .. '_' .. tostring( i))
|
|
if i > 1 then
|
|
local ptOn = Point3d( Xmin + ( i - 1) * dPartLen, 0, 0)
|
|
EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB)
|
|
end
|
|
if i < nPart then
|
|
local ptOn = Point3d( Xmin + i * dPartLen, 0, 0)
|
|
EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB)
|
|
end
|
|
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, dOvmHead, 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)
|
|
-- setto a nil la variabile smussi
|
|
bMadeChamfer = nil
|
|
-- 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
|
|
AssignQIdent( Proc)
|
|
-- se non forzate frese, uso la lama
|
|
local bUseBlade = EgtGetInfo( Proc.Id, Q_USE_ROUGH_TOOL, 'i') ~= 1 and EgtGetInfo( Proc.Id, Q_USE_MILL, 'i') ~= 1
|
|
-- se ho attivo la lama e ho la feature 30, verifico i parametri Q propri della feature
|
|
if bUseBlade and Proc.Prc == 30 then
|
|
local nBladeAntisplint = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') or 0
|
|
local nUseRoughToolOnSide = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0
|
|
-- se antischeggia di fresa o abilitato sgrossatore di fianco
|
|
if nBladeAntisplint == 2 or nUseRoughToolOnSide == 1 then
|
|
bUseBlade = false
|
|
end
|
|
end
|
|
-- 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
|
|
-- leggo i parametri Q per utilizzare la fresa di fianco e/o lama
|
|
local nUseSideTool = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0
|
|
local bUseBlade = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') == 1
|
|
return Long2Cut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nUseSideTool)
|
|
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
|
|
if bUseBlade then
|
|
return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide')
|
|
else
|
|
return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
end
|
|
end
|
|
-- tre o più facce
|
|
else
|
|
return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
end
|
|
|
|
-- altrimenti lavorazione unica
|
|
else
|
|
-- una faccia
|
|
if Proc.Fct == 1 then
|
|
-- se piccola, con fresa
|
|
if not bUseBlade and ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then
|
|
return MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId)
|
|
-- altrimenti, con lama
|
|
else
|
|
return Cut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
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)
|
|
-- se ortogonali e non forzata lama, con fresa
|
|
if not bUseBlade and bAdj and abs( dAng + 90) < 1 then
|
|
-- se piccole
|
|
if ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then
|
|
return MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId)
|
|
else
|
|
return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, true)
|
|
end
|
|
-- altrimenti, con lama
|
|
else
|
|
-- verifico se devo fare prima gli amussi
|
|
-- recupero gruppo per geometria addizionale
|
|
local nAddGrpId = BL.GetAddGroup( nPartId)
|
|
if not nAddGrpId then
|
|
local sErr = 'Error : missing AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- 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 : part box not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- 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)
|
|
-- verifico se sono presenti i parametri Q per la profondità smusso e
|
|
-- per eseguire in esclusiva solo lo smusso
|
|
local nChamfer, dDepthCham, sErrCham = EvaluateQParam( Proc)
|
|
if (Proc.Fct == 2 and bIsL) and nChamfer > 0 then
|
|
local _, _, _, vtOrtho, _, nSurfInt = GetTunnelDimension( Proc, nPartId)
|
|
local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham)
|
|
if nOk < 0 then return false, sErr end
|
|
end
|
|
return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide')
|
|
end
|
|
-- tre o più facce
|
|
else
|
|
return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, true)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return ProcessLapJoint
|