02fe05d5e1
- corretto errore nel calcolo del lead out per setti.
1408 lines
58 KiB
Lua
1408 lines
58 KiB
Lua
-- CalcToolPath.lua by Egaltech s.r.l. 2022/12/20
|
|
-- Calcolo percorsi di lavoro per Stampa 3d
|
|
|
|
-- Tabella per definizione modulo
|
|
local CalcToolPath = {}
|
|
|
|
-- Intestazioni
|
|
require( 'EgtBase')
|
|
|
|
EgtOutLog( ' CalcToolPath started', 1)
|
|
|
|
-- Dati
|
|
local AMD = require( 'AddManData')
|
|
|
|
---------------------------------------------------------------------
|
|
local s_nPartId
|
|
local s_nDefaultWipeAng = -90 -- angolo = 0° per wipe significa che esce ortogonalmente alla direzione del movimento
|
|
local s_dHMin
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetLayerParamsForToolPathCalc()
|
|
local LayerParams = {}
|
|
LayerParams.bSpiralVase = EgtGetInfo( s_nPartId, KEY_SPIRAL_VASE, 'b') or false
|
|
LayerParams.dStrand = EgtGetInfo( s_nPartId, KEY_STRAND, 'd')
|
|
LayerParams.dLayHeight = EgtGetInfo( s_nPartId, KEY_SLICE_STEP, 'd')
|
|
LayerParams.dOffs = EgtGetInfo( s_nPartId, KEY_OFFSET_SLICE, 'd')
|
|
LayerParams.bInvert = ( EgtGetInfo( s_nPartId, KEY_PRINT_DIRECTION, 'i') == PRINT_DIRECTION.CW)
|
|
LayerParams.nOrder = EgtGetInfo( s_nPartId, KEY_STRAND_ORDER, 'i')
|
|
LayerParams.vPrintOrder = EgtGetInfo( s_nPartId, KEY_PRINT_ORDER, 'vi') or { 1, 2, 3, 4, 5, 6, 7, 8}
|
|
LayerParams.nLinkType = EgtGetInfo( s_nPartId, KEY_LINK_TYPE, 'i')
|
|
LayerParams.dLinkParam = EgtGetInfo( s_nPartId, KEY_LINK_PARAM, 'd')
|
|
LayerParams.nLeadInType = EgtGetInfo( s_nPartId, KEY_LEAD_IN_TYPE, 'i')
|
|
LayerParams.dLeadInTangDist = EgtGetInfo( s_nPartId, KEY_LEAD_IN_TANG_DIST, 'd')
|
|
LayerParams.dLeadInOrthoDist = EgtGetInfo( s_nPartId, KEY_LEAD_IN_ORTHO_DIST, 'd')
|
|
LayerParams.nLeadOutType = EgtGetInfo( s_nPartId, KEY_LEAD_OUT_TYPE, 'i')
|
|
LayerParams.dLeadOutTangDist = EgtGetInfo( s_nPartId, KEY_LEAD_OUT_TANG_DIST, 'd')
|
|
LayerParams.dLeadOutOrthoDist = EgtGetInfo( s_nPartId, KEY_LEAD_OUT_ORTHO_DIST, 'd')
|
|
LayerParams.dOffsetLP = EgtGetInfo( s_nPartId, KEY_OFFSET_LEAD_POINT, 'd')
|
|
LayerParams.dSPOffs = EgtGetInfo( s_nPartId, KEY_SP_OFFSET_ON_SLICE, 'd')
|
|
LayerParams.dCoastingLen = EgtGetInfo( s_nPartId, KEY_COASTING_LEN, 'd')
|
|
LayerParams.dWipeLen = EgtGetInfo( s_nPartId, KEY_WIPE_LEN, 'd')
|
|
LayerParams.dWipeDir = EgtGetInfo( s_nPartId, KEY_WIPE_DIR, 'd') or 0.0
|
|
LayerParams.vtSlicing = EgtGetInfo( s_nPartId, KEY_SLICING_DIR, 'v')
|
|
LayerParams.dTDiam = EgtGetInfo( s_nPartId, KEY_TOOL_DIAM, 'd')
|
|
|
|
return LayerParams
|
|
end
|
|
|
|
------------------------------------------------------------------
|
|
local function ComputeToolPathBox( nTpathGrpId)
|
|
|
|
-- calcolo il box del toolpath (escludendo i wipe)
|
|
local b3Box = BBox3d()
|
|
local nEntId = EgtGetFirstInGroup( nTpathGrpId)
|
|
while nEntId do
|
|
if EgtGetInfo( nEntId, KEY_TYPE, 'i') ~= TYPE.WIPE then
|
|
local b3Ent = EgtGetBBoxGlob( nEntId, GDB_BB.STANDARD)
|
|
b3Box:Add( b3Ent)
|
|
end
|
|
nEntId = EgtGetNext( nEntId)
|
|
end
|
|
|
|
return b3Box
|
|
end
|
|
|
|
------------------------------------------------------------------
|
|
local function AddZCorrection( b3Box, LayerParams)
|
|
|
|
local dNxy = sqrt( LayerParams.vtSlicing:getX() * LayerParams.vtSlicing:getX() + LayerParams.vtSlicing:getY() * LayerParams.vtSlicing:getY())
|
|
local dNz = LayerParams.vtSlicing:getZ()
|
|
-- altezza necessaria per lo strand
|
|
local dHStrand = 0.5 * LayerParams.dStrand * dNxy + LayerParams.dLayHeight * dNz
|
|
-- altezza necessaria per il tool
|
|
local dHTool = LayerParams.dTDiam / 2 * dNxy
|
|
-- altezza disponibile
|
|
local dHBox = EgtGetInfo( s_nPartId, KEY_BOX_MIN_Z, 'i') or 0
|
|
local dHDisp = b3Box:getMin():getZ() - dHBox
|
|
|
|
local dCorrZ = max( 0, max( dHStrand, dHTool) - dHDisp)
|
|
|
|
-- applico la correzione al pezzo
|
|
local vtMove = dCorrZ * Z_AX()
|
|
EgtMove( s_nPartId, vtMove, GDB_RT.GLOB)
|
|
EgtSetInfo( s_nPartId, KEY_MOVED_PART2, vtMove)
|
|
-- correggo la posizione del riferimento
|
|
local nFrameId = EgtGetFirstNameInGroup( s_nPartId, LAY_FRAME)
|
|
EgtMove( nFrameId, - vtMove, GDB_RT.GLOB)
|
|
|
|
end
|
|
|
|
------------------------------------------------------------------
|
|
local function FindWipeEndPoint( ptS, vtDir, dLen, vtSlicing)
|
|
|
|
local ptE = ptS + vtDir * dLen
|
|
-- verifico soddisfi altezza minima per non entrare nella tavola
|
|
local k = 1
|
|
while ptE:getZ() < s_dHMin + GEO.EPS_SMALL and k < 36 do
|
|
vtDir:rotate( vtSlicing, 10)
|
|
ptE = ptS + vtDir * dLen
|
|
k = k + 1
|
|
end
|
|
|
|
return ptE
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
local function AddCurvesToToolPath( vEntIds, nTpathGrpId, nOrder, bInvert, vtSlicing, dLayHeight)
|
|
|
|
local vIds = {} -- vettore con gli id ordinati delle curve nel gruppo dei ToolPath
|
|
|
|
local nStart = EgtIf( nOrder == PRINT_ORDER.EXT_INT, 1, #vEntIds)
|
|
local nEnd = EgtIf( nOrder == PRINT_ORDER.EXT_INT, #vEntIds, 1)
|
|
local nStep = EgtIf( nOrder == PRINT_ORDER.EXT_INT, 1, -1)
|
|
local nIdx = 1
|
|
for i = nStart, nEnd, nStep do
|
|
-- copio nel gruppo toolpath
|
|
if i == nStart then
|
|
vIds[nIdx] = EgtCopyGlob( vEntIds[i], nTpathGrpId, GDB_IN.LAST_SON)
|
|
else
|
|
vIds[nIdx] = EgtCopyGlob( vEntIds[i], vIds[nIdx-1], GDB_IN.AFTER)
|
|
end
|
|
|
|
-- mi sposto dell'altezza layer
|
|
EgtMove( vIds[nIdx], dLayHeight * vtSlicing, GDB_RT.GLOB)
|
|
|
|
if EgtCurveIsClosed( vIds[nIdx]) then
|
|
EgtSetInfo( vIds[nIdx], KEY_CLOSED_CRV, 1)
|
|
-- eventuale inversione
|
|
if bInvert then
|
|
EgtInvertCurve( vIds[nIdx])
|
|
EgtSetInfo( vIds[nIdx], KEY_INVERTED_CRV, 1)
|
|
end
|
|
end
|
|
|
|
EgtModifyCurveExtrusion( vIds[nIdx], vtSlicing, GDB_RT.GLOB)
|
|
EgtSetColor( vIds[nIdx], EgtStdColor('GRAY'))
|
|
EgtSetStatus( vIds[nIdx], GDB_ST.ON)
|
|
nIdx = nIdx + 1
|
|
end
|
|
|
|
return vIds
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
local function AddLink( vCrv, nTpathGrpId, nLinkType, dLinkParam, dSPOffs, dStrand, vtSlicing)
|
|
|
|
if not vCrv or #vCrv == 0 then return end
|
|
|
|
local k = 0
|
|
local bPrevClosed = EgtGetInfo( vCrv[1], KEY_CLOSED_CRV, 'b') or false
|
|
for i = 2, #vCrv do
|
|
-- il link ha senso solo su curve chiuse
|
|
local bCurrClosed = EgtCurveIsClosed( vCrv[i])
|
|
if bCurrClosed and bPrevClosed then
|
|
-- aggiorno k per calcolo dell'offset
|
|
local sPrevName = EgtGetName( vCrv[i-1])
|
|
local sCurrName = EgtGetName( vCrv[i])
|
|
local nType = EgtGetInfo( vCrv[i], KEY_TYPE, 'i')
|
|
if sPrevName ~= sCurrName or nType == TYPE.INFILL or nType == TYPE.AUX_SOLID or nType == TYPE.RIB then
|
|
k = k + 1
|
|
end
|
|
|
|
-- se nessun raccordo modifico solo lo start point della curva
|
|
if nLinkType == LINK_TYPE.NONE then
|
|
local dLen = k * dSPOffs
|
|
if dSPOffs < 0 then
|
|
dLen = EgtCurveLength( vCrv[i]) + dLen
|
|
end
|
|
local dPar = EgtCurveParamAtLength( vCrv[i], dLen)
|
|
if dPar then EgtChangeClosedCurveStart( vCrv[i], dPar) end
|
|
|
|
else
|
|
-- altrimenti verifico se ha senso creare raccordo
|
|
-- local dDist = dist( EgtEP( vCrv[i-1]), EgtSP( vCrv[i]))
|
|
local dDist = EgtPointCurveDist( EgtEP( vCrv[i-1]), vCrv[i])
|
|
if dDist < dStrand + 10 * GEO.EPS_SMALL then
|
|
local nLinkId
|
|
-- modifico lo start point
|
|
local dLen = EgtCurveLength( vCrv[i-1]) - EgtIf( k > 1, abs( dSPOffs), 0)
|
|
EgtTrimCurveEndAtLen( vCrv[i-1], dLen)
|
|
EgtChangeClosedCurveStartPoint( vCrv[i], EgtEP( vCrv[i-1]))
|
|
|
|
-- aggiungo il raccordo
|
|
EgtTrimCurveEndAtLen( vCrv[i-1], EgtCurveLength( vCrv[i-1]) - dLinkParam / 2)
|
|
EgtTrimCurveStartAtLen( vCrv[i], dLinkParam / 2)
|
|
if nLinkType == LINK_TYPE.LINEAR then
|
|
nLinkId = EgtCurveCompoFromPoints( nTpathGrpId, {EgtEP( vCrv[i-1]), EgtSP( vCrv[i])})
|
|
elseif nLinkType == LINK_TYPE.BIARC then
|
|
local frLoc = Frame3d( ORIG(), vtSlicing)
|
|
local nGrpTmp = EgtGroup( nTpathGrpId, frLoc, GDB_RT.GLOB)
|
|
local _, _, dAngIni = SphericalFromVector( EgtEV( vCrv[i-1], nGrpTmp))
|
|
local _, _, dAngFin = SphericalFromVector( EgtSV( vCrv[i], nGrpTmp))
|
|
nLinkId = EgtBiArc( nGrpTmp, EgtEP( vCrv[i-1], nGrpTmp), EgtSP( vCrv[i], nGrpTmp), dAngIni, dAngFin, 0.5)
|
|
EgtRelocateGlob( nLinkId, nTpathGrpId, GDB_IN.LAST_SON)
|
|
EgtErase( nGrpTmp)
|
|
end
|
|
|
|
if nLinkId then
|
|
EgtRelocate( nLinkId, vCrv[i], GDB_IN.BEFORE)
|
|
EgtModifyCurveExtrusion( nLinkId, vtSlicing, GDB_RT.GLOB)
|
|
EgtSetInfo( nLinkId, KEY_TYPE, TYPE.LINK)
|
|
EgtSetName( nLinkId, LINK_CRV)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
bPrevClosed = bCurrClosed
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AddOffsetLeadPoint( vIds, nFirstCopy, dOffsetLP, nLinkType)
|
|
|
|
-- se link va fatto solo sulla shell esterna
|
|
local nLast = EgtIf( nLinkType == LINK_TYPE.NONE, #vIds, 1)
|
|
|
|
if abs( dOffsetLP) > GEO.EPS_SMALL then
|
|
for i = 1, nLast do
|
|
if dOffsetLP > GEO.EPS_SMALL then
|
|
-- taglio curva
|
|
EgtTrimCurveStartAtLen( vIds[i], dOffsetLP)
|
|
else
|
|
-- è necessario aggiungere un tratto
|
|
local nAddCrv = EgtCopyGlob( EgtIf( i == 1, nFirstCopy, vIds[i]), vIds[1], GDB_IN.AFTER)
|
|
EgtTrimCurveStartAtLen( nAddCrv, EgtCurveLength( nAddCrv) - abs( dOffsetLP))
|
|
EgtAddCurveCompoCurve( vIds[i], nAddCrv, true, false)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- elimino curva aux usata per prima shell
|
|
EgtErase( nFirstCopy)
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AddLeadIn( nCrvId, LayerParams, nGrpId)
|
|
|
|
local ptE = EgtSP( nCrvId, GDB_ID.ROOT)
|
|
local vtTang = EgtSV( nCrvId, GDB_ID.ROOT)
|
|
local vtOrtho = Vector3d( vtTang)
|
|
local dAng = 90
|
|
if ( LayerParams.bInvert and LayerParams.nOrder == PRINT_ORDER.INT_EXT) or
|
|
( not LayerParams.bInvert and LayerParams.nOrder == PRINT_ORDER.EXT_INT) then
|
|
dAng = - 90
|
|
end
|
|
|
|
vtOrtho:rotate( LayerParams.vtSlicing, dAng)
|
|
local ptS = ptE - LayerParams.dLeadInTangDist * vtTang + LayerParams.dLeadInOrthoDist * vtOrtho
|
|
-- verifico che non affondi nella tavola
|
|
if ptS:getZ() < s_dHMin + GEO.EPS_SMALL then return end
|
|
|
|
local nLeadInCrv
|
|
if LayerParams.nLeadInType == LEAD_TYPE.LINEAR then
|
|
nLeadInCrv = EgtCurveCompoFromPoints( nGrpId, {ptS, ptE}, GDB_RT.GLOB)
|
|
elseif LayerParams.nLeadInType == LEAD_TYPE.ARC then
|
|
nLeadInCrv = EgtArc2PV( nGrpId, ptE, ptS, -vtTang, GDB_RT.GLOB)
|
|
EgtInvertCurve( nLeadInCrv)
|
|
end
|
|
|
|
if nLeadInCrv then
|
|
EgtRelocate( nLeadInCrv, nCrvId, GDB_IN.BEFORE)
|
|
EgtModifyCurveExtrusion( nLeadInCrv, LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
EgtSetInfo( nLeadInCrv, KEY_TYPE, TYPE.LINK)
|
|
EgtSetName( nLeadInCrv, LEAD_IN_CRV)
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AddLeadOut( nCrvId, LayerParams, nGrpId)
|
|
|
|
local ptS = EgtEP( nCrvId, GDB_ID.ROOT)
|
|
local vtTang = EgtEV( nCrvId, GDB_ID.ROOT)
|
|
local vtOrtho = Vector3d( vtTang)
|
|
local dAng = - 90
|
|
if ( LayerParams.bInvert and LayerParams.nOrder == PRINT_ORDER.INT_EXT) or
|
|
( not LayerParams.bInvert and LayerParams.nOrder == PRINT_ORDER.EXT_INT) then
|
|
dAng = 90
|
|
end
|
|
|
|
vtOrtho:rotate( LayerParams.vtSlicing, dAng)
|
|
local ptE = ptS + LayerParams.dLeadOutTangDist * vtTang + LayerParams.dLeadOutOrthoDist * vtOrtho
|
|
|
|
local nLeadOutCrv
|
|
if LayerParams.nLeadOutType == LEAD_TYPE.LINEAR then
|
|
nLeadOutCrv = EgtCurveCompoFromPoints( nGrpId, {ptS, ptE}, GDB_RT.GLOB)
|
|
elseif LayerParams.nLeadOutType == LEAD_TYPE.ARC then
|
|
nLeadOutCrv = EgtArc2PV( nGrpId, ptS, ptE, vtTang, GDB_RT.GLOB)
|
|
end
|
|
|
|
if nLeadOutCrv then
|
|
EgtRelocate( nLeadOutCrv, nCrvId, GDB_IN.AFTER)
|
|
EgtModifyCurveExtrusion( nLeadOutCrv, LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
EgtSetInfo( nLeadOutCrv, KEY_TYPE, TYPE.LINK)
|
|
EgtSetName( nLeadOutCrv, LEAD_OUT_CRV)
|
|
end
|
|
return nLeadOutCrv
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AddRetraction( nCrvId, vtSlicing, dCoastingLen, dWipeLen, dWipeDir)
|
|
|
|
-- recupero i parametri per retrazione
|
|
local nType = EgtGetInfo( nCrvId, KEY_TYPE, 'i')
|
|
local bClosed = EgtGetInfo( nCrvId, KEY_CLOSED_CRV, 'b') or false
|
|
local bInverted = EgtGetInfo( nCrvId, KEY_INVERTED_CRV, 'b') or false
|
|
|
|
-- curva ausiliaria per generare correttamente wipe
|
|
local nCopyId = EgtCopyGlob( nCrvId, nCrvId, GDB_IN.AFTER)
|
|
if not EgtCurveIsClosed( nCopyId) then
|
|
local ptNewStart = EgtEP( nCrvId)
|
|
local dPar = EgtCurveParamAtPoint( nCopyId, ptNewStart)
|
|
local _, dParE = EgtCurveDomain( nCopyId)
|
|
if abs( dPar - dParE) < GEO.EPS_SMALL then
|
|
EgtCloseCurveCompo( nCopyId)
|
|
EgtChangeClosedCurveStartPoint( nCopyId, ptNewStart)
|
|
else
|
|
-- caso con sovrapposizione
|
|
EgtTrimCurveStartAtParam( nCopyId, dPar)
|
|
end
|
|
end
|
|
|
|
local nCoastingId
|
|
if dCoastingLen > GEO.EPS_SMALL then
|
|
nCoastingId = EgtCopyGlob( nCrvId, nCrvId, GDB_IN.AFTER)
|
|
local dPar = EgtCurveParamAtLength( nCoastingId, EgtCurveLength( nCoastingId) - dCoastingLen)
|
|
if not dPar then
|
|
EgtErase( nCoastingId)
|
|
nCoastingId = nil
|
|
else
|
|
EgtTrimCurveStartAtParam( nCoastingId, dPar)
|
|
-- aggiorno la curva originale
|
|
if dPar > GEO.EPS_SMALL then
|
|
EgtTrimCurveEndAtParam( nCrvId, dPar)
|
|
else
|
|
EgtErase( nCrvId)
|
|
end
|
|
EgtModifyCurveExtrusion( nCoastingId, vtSlicing, GDB_RT.GLOB)
|
|
EgtSetName( nCoastingId, COASTING_CRV)
|
|
EgtSetInfo( nCoastingId, KEY_TYPE, TYPE.COASTING)
|
|
EgtSetColor( nCoastingId, EgtStdColor('ORANGE'))
|
|
end
|
|
end
|
|
|
|
if dWipeLen > GEO.EPS_SMALL then
|
|
local nWipeId
|
|
if bClosed then
|
|
-- se era chiusa ( quindi analogo alle shell)
|
|
nWipeId = nCopyId
|
|
nCopyId = nil
|
|
EgtTrimCurveEndAtLen( nWipeId, dWipeLen)
|
|
else
|
|
local vtDir = EgtEV( nCoastingId or nCrvId, GDB_ID.ROOT)
|
|
local dAng = dWipeDir + s_nDefaultWipeAng
|
|
-- verifico se necessario cambiare il segno all'angolo
|
|
local bChangeSign = false
|
|
-- riempimento
|
|
if nType == TYPE.INFILL or nType == TYPE.AUX_SOLID then
|
|
local vtS = EgtGetInfo( nCrvId, KEY_ZIG_ZAG_DIR, 'v')
|
|
local bSameDir = AreSameVectorApprox( vtS, vtDir)
|
|
bChangeSign = ( bInverted == bSameDir)
|
|
-- rib
|
|
elseif nType == TYPE.RIB then
|
|
local bInvertStrandOrder = EgtGetInfo( nCrvId, KEY_RIBS_INVERT_STRAND_ORDER, 'b') or false
|
|
local bInvertDir = EgtGetInfo( nCrvId, KEY_RIBS_INVERT_DIR, 'b') or false
|
|
bChangeSign = ( bInvertDir ~= bInvertStrandOrder)
|
|
-- extra shell
|
|
elseif nType == TYPE.EXTRA_SHELL or nType == TYPE.EXTRA_OUTER_SHELL then
|
|
bChangeSign = bInverted
|
|
end
|
|
|
|
vtDir:rotate( vtSlicing, EgtIf( bChangeSign, - dAng, dAng))
|
|
local ptS = EgtEP( nCoastingId or nCrvId, GDB_ID.ROOT)
|
|
local ptE = FindWipeEndPoint( ptS, vtDir, dWipeLen, vtSlicing)
|
|
nWipeId = EgtCurveCompoFromPoints( EgtGetParent( nCoastingId or nCrvId), {ptS, ptE}, GDB_RT.GLOB)
|
|
EgtModifyCurveExtrusion( nWipeId, vtSlicing, GDB_RT.GLOB)
|
|
EgtRelocateGlob( nWipeId, nCoastingId or nCrvId, GDB_IN.AFTER)
|
|
end
|
|
|
|
EgtSetName( nWipeId, WIPE_CRV)
|
|
EgtSetInfo( nWipeId, KEY_TYPE, TYPE.WIPE)
|
|
EgtSetColor( nWipeId, EgtStdColor('AQUA'))
|
|
end
|
|
|
|
if nCopyId then EgtErase( nCopyId) end
|
|
return nCoastingId
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AddRetractionOnLastCrv( nCrvId, nTpathGrpId, LayerParams, dCoastingLen, dWipeLen, dWipeDir)
|
|
|
|
if LayerParams.nLeadOutType == LEAD_TYPE.NONE then
|
|
AddRetraction( nCrvId, LayerParams.vtSlicing, dCoastingLen, dWipeLen, dWipeDir)
|
|
else
|
|
local nLeadOutId = EgtGetLastInGroup( nTpathGrpId)
|
|
local dLen = EgtCurveLength( nLeadOutId)
|
|
if dLen > dCoastingLen - 500 * GEO.EPS_SMALL then
|
|
-- coinvolge solo la curva di lead out
|
|
local dNewCoastingLen = EgtIf( abs( dCoastingLen - dLen) < 500 * GEO.EPS_SMALL, dLen, dCoastingLen) -- verifico se interamente coinvolta
|
|
AddRetraction( nLeadOutId, LayerParams.vtSlicing, dNewCoastingLen, dWipeLen, dWipeDir)
|
|
else
|
|
-- coinvolge parte dell'ultima shell crv
|
|
local dNewCoastingLen = dCoastingLen - dLen
|
|
local nCoastingId = AddRetraction( nCrvId, LayerParams.vtSlicing, dNewCoastingLen, 0.0, dWipeDir)
|
|
EgtAddCurveCompoCurve( nCoastingId, nLeadOutId)
|
|
EgtSetInfo( nCoastingId, KEY_CLOSED_CRV, 0)
|
|
-- wipe
|
|
AddRetraction( nCoastingId, LayerParams.vtSlicing, 0, dWipeLen, dWipeDir)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcShellsToolPath( vEntIds, nTpathGrpId, LayerParams)
|
|
|
|
if not vEntIds then return end
|
|
|
|
-- aggiungo le curve nel toolpath
|
|
local vIds = AddCurvesToToolPath( vEntIds, nTpathGrpId, LayerParams.nOrder, LayerParams.bInvert, LayerParams.vtSlicing, LayerParams.dLayHeight)
|
|
local nFirstCopy = EgtCopyGlob( vIds[1], nTpathGrpId) -- necessaria per corretto offset lead point sulla shell esterna
|
|
|
|
-- aggiungo gli opportuni raccordi
|
|
AddLink( vIds, nTpathGrpId, LayerParams.nLinkType, LayerParams.dLinkParam, LayerParams.dSPOffs, LayerParams.dStrand, LayerParams.vtSlicing)
|
|
|
|
-- offset lead point
|
|
AddOffsetLeadPoint( vIds, nFirstCopy, LayerParams.dOffsetLP, LayerParams.nLinkType)
|
|
|
|
-- aggiungo leadin/leadout
|
|
if LayerParams.nLeadInType ~= LEAD_TYPE.NONE then
|
|
AddLeadIn( vIds[1], LayerParams, nTpathGrpId)
|
|
end
|
|
if LayerParams.nLeadOutType ~= LEAD_TYPE.NONE then
|
|
EgtTrimCurveEndAtLen( vIds[#vIds], EgtCurveLength( vIds[#vIds]) - LayerParams.dOffsetLP)
|
|
AddLeadOut( vIds[#vIds], LayerParams, nTpathGrpId)
|
|
end
|
|
|
|
-- aggiungo coasting/wipe
|
|
for i = 1, #vIds - 1 do
|
|
local nNextId = EgtGetNext( vIds[i])
|
|
if EgtGetInfo( nNextId, KEY_TYPE, 'i') ~= TYPE.LINK then
|
|
AddRetraction( vIds[i], LayerParams.vtSlicing, LayerParams.dCoastingLen, LayerParams.dWipeLen, LayerParams.dWipeDir)
|
|
end
|
|
end
|
|
-- sull'ultima curva gestione speciale per eventuale lead out
|
|
AddRetractionOnLastCrv( vIds[#vIds], nTpathGrpId, LayerParams, LayerParams.dCoastingLen, LayerParams.dWipeLen, LayerParams.dWipeDir)
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcExtraShellToolPath( vEntIds, nTpathGrpId, LayerParams)
|
|
|
|
if not vEntIds then return end
|
|
-- aggiungo le curve nel toolpath
|
|
local vIds = AddCurvesToToolPath( vEntIds, nTpathGrpId, PRINT_ORDER.EXT_INT, false, LayerParams.vtSlicing, LayerParams.dLayHeight)
|
|
|
|
-- aggiungo gli opportuni raccordi
|
|
local sPrevName = EgtGetName( vIds[1])
|
|
for i = 2, #vIds do
|
|
local sCurrName = EgtGetName( vIds[i])
|
|
-- se hanno lo stesso nome vanno collegate
|
|
if sCurrName == sPrevName then
|
|
local ptS = EgtEP( vIds[i-1])
|
|
local ptE = EgtSP( vIds[i])
|
|
local nLinkId = EgtCurveCompoFromPoints( nTpathGrpId, {ptS, ptE})
|
|
if nLinkId then
|
|
EgtRelocateGlob( nLinkId, vIds[i], GDB_IN.BEFORE)
|
|
EgtModifyCurveExtrusion( nLinkId, LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
EgtSetInfo( nLinkId, KEY_TYPE, TYPE.LINK)
|
|
EgtSetName( nLinkId, LINK_CRV)
|
|
end
|
|
end
|
|
sPrevName = sCurrName
|
|
end
|
|
|
|
-- aggiungo coasting/wipe
|
|
for i = 1, #vIds do
|
|
-- verifico non sia collegato al successivo tramite link
|
|
local nNextId = EgtGetNext( vIds[i])
|
|
if not nNextId or EgtGetInfo( nNextId, KEY_TYPE, 'i') ~= TYPE.LINK then
|
|
-- recupero i parametri
|
|
local dCoastingLen, dWipeLen, dWipeDir
|
|
local bClosed = EgtGetInfo( vIds[i], KEY_CLOSED_CRV, 'b') or false
|
|
if not bClosed then
|
|
local bInverted = EgtGetInfo( vIds[i], KEY_INVERTED_CRV, 'b') or false
|
|
local vCoastLen = EgtGetInfo( vIds[i], KEY_EXTRA_SHELL_COASTING, 'vd')
|
|
local vWipeLen = EgtGetInfo( vIds[i], KEY_EXTRA_SHELL_WIPE, 'vd')
|
|
local vWipeDir = EgtGetInfo( vIds[i], KEY_EXTRA_SHELL_WIPE_DIR, 'vd')
|
|
-- se curva è stata invertita devo prendere le info legate a quello che era il suo punto di inizio, altrimenti prendo le info legate al punto finale
|
|
dCoastingLen = EgtIf( bInverted, vCoastLen[1], vCoastLen[2])
|
|
dWipeLen = EgtIf( bInverted, vWipeLen[1], vWipeLen[2])
|
|
dWipeDir = EgtIf( bInverted, vWipeDir[1], vWipeDir[2])
|
|
else
|
|
-- se chiusa considero i parametri delle shell complete
|
|
dCoastingLen = LayerParams.dCoastingLen
|
|
dWipeLen = LayerParams.dWipeLen
|
|
dWipeDir = LayerParams.dWipeDir
|
|
end
|
|
|
|
AddRetraction( vIds[i], LayerParams.vtSlicing, dCoastingLen, dWipeLen, dWipeDir)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcInfillToolPath( vEntIds, nTpathGrpId, LayerParams)
|
|
|
|
if not vEntIds then return end
|
|
-- aggiungo le curve nel toolpath
|
|
local vIds = AddCurvesToToolPath( vEntIds, nTpathGrpId, LayerParams.nOrder, LayerParams.bInvert, LayerParams.vtSlicing, LayerParams.dLayHeight)
|
|
|
|
-- aggiungo eventuali link
|
|
AddLink( vIds, nTpathGrpId, LayerParams.nLinkType, LayerParams.dLinkParam, LayerParams.dSPOffs, LayerParams.dStrand, LayerParams.vtSlicing)
|
|
|
|
-- aggiungo coasting/wipe
|
|
for i = 1, #vIds do
|
|
local nNextId = EgtGetNext( vIds[i])
|
|
if not nNextId or EgtGetInfo( nNextId, KEY_TYPE, 'i') ~= TYPE.LINK then
|
|
AddRetraction( vIds[i], LayerParams.vtSlicing, LayerParams.dCoastingLen, LayerParams.dWipeLen, LayerParams.dWipeDir)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcAuxSolidsToolPath( nAuxSolidsGrp, nAuxSolidsPathGrp, nTpathGrpId, LayerParams)
|
|
|
|
if not nAuxSolidsGrp or not nAuxSolidsPathGrp then return end
|
|
|
|
-- recupero le curve relative al primo solido ausiliario
|
|
local sPrevName = AUX_SOLID_CRV
|
|
local nSolidId = EgtGetFirstNameInGroup( nAuxSolidsGrp, AUX_SOLIDS_CRV .. '*')
|
|
while nSolidId do
|
|
|
|
local sName = EgtGetName( nSolidId)
|
|
if sName ~= sPrevName then
|
|
|
|
-- recupero tutti i percorsi relativi a quel solido
|
|
local vEntIds = EgtGetNameInGroup( nAuxSolidsPathGrp, sName .. '*')
|
|
if vEntIds then
|
|
|
|
-- recupero i parametri relativi al solido
|
|
local nOrder = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_PRINT_ORDER, 'i')
|
|
local nLinkType = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_LINK_TYPE, 'i')
|
|
local dLinkParam = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_LINK_PARAM, 'd')
|
|
local dSPOffset = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_SP_OFFSET, 'd')
|
|
local dCoastingLen = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_COASTING_LEN, 'd')
|
|
local dWipeLen = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_WIPE_LEN, 'd')
|
|
local dWipeDir = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_WIPE_DIR, 'd')
|
|
|
|
-- copio i percorsi nel gruppo toolpath
|
|
local vIds = AddCurvesToToolPath( vEntIds, nTpathGrpId, nOrder, LayerParams.bInvert, LayerParams.vtSlicing, LayerParams.dLayHeight)
|
|
|
|
-- aggiungo link
|
|
AddLink( vIds, nTpathGrpId, nLinkType, dLinkParam, dSPOffset, LayerParams.dStrand, LayerParams.vtSlicing)
|
|
|
|
-- coasting e wipe
|
|
for i = 1, #vIds do
|
|
local nNextId = EgtGetNext( vIds[i])
|
|
if not nNextId or EgtGetInfo( nNextId, KEY_TYPE, 'i') ~= TYPE.LINK then
|
|
AddRetraction( vIds[i], LayerParams.vtSlicing, dCoastingLen, dWipeLen, dWipeDir)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
sPrevName = sName
|
|
nSolidId = EgtGetNextName( nSolidId, AUX_SOLIDS_CRV .. '*')
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
--------------------------- RIBS -----------------------------------
|
|
--------------------------------------------------------------------
|
|
local function VerifyRibsLink( nLinkId, nCurr, nNext, dStrand, nGrpTmp)
|
|
|
|
local nGrp = EgtGetParent( nCurr)
|
|
|
|
-- verifico se il link interseca le due curve nell'altro estremo
|
|
local ptS = EgtSP( nCurr)
|
|
local ptE = EgtEP( nNext)
|
|
local dParS = EgtCurveParamAtPoint( nLinkId, ptS)
|
|
local dParE = EgtCurveParamAtPoint( nLinkId, ptE)
|
|
if nCurr ~= nNext and ( dParS or dParE) then
|
|
return false
|
|
end
|
|
|
|
-- verifico se si trova nella regione ammissibile
|
|
local nSurfId = EgtGetInfo( nCurr, KEY_ASSOCIATED_SURF, 'i')
|
|
local nRes = EgtCurveWithRegionClassify( nLinkId, nSurfId)
|
|
local nType1 = EgtGetInfo( nCurr, KEY_RIBS_TYPE, 'i')
|
|
local nType2 = EgtGetInfo( nNext, KEY_RIBS_TYPE, 'i')
|
|
if ( nType1 == RIB_TYPE.INTERNAL or nType1 == RIB_TYPE.SUPPORT) and ( nType2 == RIB_TYPE.INTERNAL or nType2 == RIB_TYPE.SUPPORT) then
|
|
if nRes == GDB_CRC.OUT or nRes == GDB_CRC.INTERS then
|
|
return false
|
|
end
|
|
elseif nType1 == RIB_TYPE.EXTERNAL and nType2 == RIB_TYPE.EXTERNAL then
|
|
if nRes == GDB_CRC.IN or nRes == GDB_CRC.INTERS then
|
|
return false
|
|
end
|
|
end
|
|
|
|
-- verifico se il link interseca una delle altre costolature
|
|
local vRibsIds = EgtGetNameInGroup( nGrp, RIBS_CRV .. '*')
|
|
local nLinkSrf = EgtSurfFrFatCurve( nGrpTmp, nLinkId, 0.5 * dStrand, false) or GDB_ID.NULL
|
|
for i = 1, #vRibsIds do
|
|
if vRibsIds[i] ~= nCurr and vRibsIds[i] ~= nNext then
|
|
local nRes = EgtCurveWithRegionClassify( vRibsIds[i], nLinkSrf)
|
|
if nRes == GDB_CRC.INTERS then
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function CalcRibsLink( nCurr, nNext, nLoopGrp, dStrand, bForceLink, vtSlicing, nGrpTmp)
|
|
|
|
local ptS = EgtEP( nCurr)
|
|
local ptE = EgtSP( nNext)
|
|
|
|
local nCrvId = EgtGetFirstNameInGroup( nLoopGrp, TRIM_SURF_LOOP)
|
|
-- recupero la curva di offset su cui calcolare link
|
|
while nCrvId do
|
|
local dParS = EgtCurveParamAtPoint( nCrvId, ptS, 10 * GEO.EPS_SMALL)
|
|
local dParE = EgtCurveParamAtPoint( nCrvId, ptE, 10 * GEO.EPS_SMALL)
|
|
if dParS and dParE then
|
|
local bInvert = false
|
|
local bClosed = EgtCurveIsClosed( nCrvId)
|
|
if bClosed then
|
|
-- se la curva è chiusa verifico i due percorsi possibili dParS->dParE e dParE->dParS
|
|
local nCopyId1 = EgtCopyGlob( nCrvId, nCurr, GDB_IN.AFTER)
|
|
local nCopyId2 = EgtCopyGlob( nCrvId, nCurr, GDB_IN.AFTER)
|
|
EgtTrimCurveStartEndAtParam( nCopyId1, dParS, dParE)
|
|
EgtTrimCurveStartEndAtParam( nCopyId2, dParE, dParS)
|
|
EgtInvertCurve( nCopyId2)
|
|
|
|
local dLen1 = EgtCurveLength( nCopyId1)
|
|
local dLen2 = EgtCurveLength( nCopyId2)
|
|
if dLen1 > dLen2 then
|
|
bInvert = true
|
|
dParS, dParE = dParE, dParS
|
|
end
|
|
EgtErase( nCopyId1)
|
|
EgtErase( nCopyId2)
|
|
end
|
|
|
|
local nCopyId = EgtCopyGlob( nCrvId, nLoopGrp)
|
|
local nLinkId = EgtCopyGlob( nCrvId, nCurr, GDB_IN.AFTER)
|
|
|
|
if dParS > dParE and not bClosed then
|
|
bInvert = true
|
|
dParS, dParE = dParE, dParS
|
|
end
|
|
|
|
EgtTrimCurveStartEndAtParam( nLinkId, dParS, dParE)
|
|
EgtSetInfo( nLinkId, KEY_TYPE, TYPE.RIB)
|
|
EgtSetName( nLinkId, LINK_CRV)
|
|
EgtModifyCurveExtrusion( nLinkId, vtSlicing, GDB_RT.GLOB)
|
|
if bInvert then EgtInvertCurve( nLinkId) end
|
|
-- verifico se è valido
|
|
local bValid = VerifyRibsLink( nLinkId, nCurr, nNext, dStrand, nGrpTmp)
|
|
if not bValid then
|
|
EgtErase( nLinkId)
|
|
EgtErase( nCopyId)
|
|
return
|
|
end
|
|
|
|
-- elimino dalle curve di contorno il link appena trovato
|
|
if bClosed then
|
|
EgtTrimCurveStartEndAtParam( nCrvId, dParE, dParS)
|
|
EgtErase( nCopyId)
|
|
else
|
|
if dParS < GEO.EPS_SMALL then
|
|
-- forzare la fine della curva nel suo inizio significa cancellarla completamente
|
|
EgtErase( nCrvId)
|
|
else
|
|
EgtTrimCurveEndAtParam( nCrvId, dParS)
|
|
end
|
|
|
|
local _, dEnd = EgtCurveDomain( nCopyId)
|
|
if abs( dParE - dEnd) < GEO.EPS_SMALL then
|
|
-- forzare l'inizio della curva nella sua fine significa cancellarla completamente
|
|
EgtErase( nCopyId)
|
|
else
|
|
EgtTrimCurveStartAtParam( nCopyId, dParE)
|
|
end
|
|
end
|
|
|
|
return nLinkId
|
|
end
|
|
|
|
nCrvId = EgtGetNextName( nCrvId, TRIM_SURF_LOOP)
|
|
end
|
|
|
|
-- se non ho trovato un collegamento sul bordo, creo una linea tra ptS e ptE
|
|
if bForceLink then
|
|
local nLinkId = EgtCurveCompoFromPoints( EgtGetParent( nCurr), {ptS, ptE})
|
|
local bValid = VerifyRibsLink( nLinkId, nCurr, nNext, dStrand, nGrpTmp)
|
|
if bValid then
|
|
EgtSetInfo( nLinkId, KEY_TYPE, TYPE.RIB)
|
|
EgtSetName( nLinkId, LINK_CRV)
|
|
EgtModifyCurveExtrusion( nLinkId, vtSlicing, GDB_RT.GLOB)
|
|
EgtRelocateGlob( nLinkId, nCurr, GDB_IN.AFTER)
|
|
else
|
|
EgtErase( nLinkId)
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function VerifyRibsLead( nId, nRibId, dStrand, bInVsOut, nGrpTmp)
|
|
|
|
local nGrp = EgtGetParent( nRibId)
|
|
local nLeadId = EgtCopyGlob( nId, nGrp)
|
|
if bInVsOut then
|
|
EgtExtendCurveStartByLen( nLeadId, dStrand * 0.5)
|
|
else
|
|
EgtExtendCurveEndByLen( nLeadId, dStrand * 0.5)
|
|
end
|
|
|
|
-- verifico che intersechi solo l'estremo corretto
|
|
if not EgtCurveIsClosed( nRibId) then
|
|
local pt = EgtIf( bInVsOut, EgtEP( nRibId), EgtSP( nRibId))
|
|
local dPar = EgtCurveParamAtPoint( nLeadId, pt)
|
|
if dPar then
|
|
EgtErase( nLeadId)
|
|
return false
|
|
end
|
|
end
|
|
|
|
local pt1 = EgtIf( bInVsOut, EgtSP( nLeadId), EgtEP( nLeadId))
|
|
local pt2 = EgtIf( bInVsOut, EgtEP( nRibId), EgtSP( nRibId))
|
|
if dist( pt1, pt2) < dStrand + GEO.EPS_SMALL then
|
|
EgtErase( nLeadId)
|
|
return false
|
|
end
|
|
|
|
local _, dParE = EgtCurveDomain( nLeadId)
|
|
local vtDir = EgtMV( nRibId)
|
|
local dParCrv = 1
|
|
local dTol = 10 * GEO.EPS_SMALL
|
|
for dParCrv = 1, dParE do
|
|
local vtS = EgtUV( nLeadId, dParCrv - 1, 1)
|
|
local vtE = EgtUV( nLeadId, dParCrv, -1)
|
|
-- se tratto lineare allineato con la direzione del setto verifico sia sufficientemente lontano
|
|
if AreSameVectorApprox( vtS, vtE) and ( (vtS - vtDir):sqlen() < dTol * dTol or (vtS + vtDir):sqlen() < dTol * dTol) then
|
|
local dDist = EgtPointCurveDist( EgtUP( nLeadId, dParCrv - 0.5), nRibId)
|
|
if dDist < dStrand + GEO.EPS_SMALL then
|
|
EgtErase( nLeadId)
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
|
|
-- verifico non intersechi altri setti
|
|
local vRibsIds = EgtGetNameInGroup( EgtGetParent( nRibId), RIBS_CRV .. '*')
|
|
local nLeadLoc = EgtCopyGlob( nLeadId, nGrpTmp)
|
|
for i = 1, #vRibsIds do
|
|
if vRibsIds[i] ~= nRibId then
|
|
local nCrvLoc = EgtCopyGlob( vRibsIds[i], nGrpTmp)
|
|
local ptInt = EgtIP( nLeadLoc, nCrvLoc, ORIG())
|
|
if ptInt then
|
|
EgtErase( nLeadId)
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se lead out verifico non si sovrapponga al lead in
|
|
if not bInVsOut then
|
|
-- recupero il lead in
|
|
local nPrev = EgtGetPrev( nRibId)
|
|
if nPrev and EgtGetName( nPrev) == LEAD_IN_CRV then
|
|
-- il caso critico è quando hanno direzioni opposte
|
|
local vtSPrev = EgtSV( nPrev, GDB_ID.ROOT)
|
|
local vtSCurr = EgtSV( nLeadId, GDB_ID.ROOT)
|
|
if AreOppositeVectorApprox( vtSPrev, vtSCurr) then
|
|
local nSrfTot = EgtSurfFrFatCurve( EgtGetParent( nLeadId), nPrev, 0.5 * dStrand, false)
|
|
if nSrfTot then
|
|
local nRes = EgtCurveWithRegionClassify( nLeadId, nSrfTot)
|
|
if nRes == GDB_CRC.IN or nRes == GDB_CRC.INTERS then
|
|
EgtErase( nSrfTot)
|
|
EgtErase( nLeadId)
|
|
return false
|
|
end
|
|
else
|
|
nSrfTot = EgtSurfFrFatCurve( EgtGetParent( nLeadId), nLeadId, 0.5 * dStrand, false)
|
|
if nSrfTot then
|
|
local nRes = EgtCurveWithRegionClassify( nPrev, nSrfTot)
|
|
if nRes == GDB_CRC.IN or nRes == GDB_CRC.INTERS then
|
|
EgtErase( nSrfTot)
|
|
EgtErase( nLeadId)
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
EgtErase( nSrfTot)
|
|
end
|
|
end
|
|
end
|
|
|
|
EgtErase( nLeadId)
|
|
return true
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
local function FindCorrectRibsLead( dPar, nCrv, nCrvOffs, bLeadInvert, dLeadLen, dStrand, bInVsOut, nGrpTmp)
|
|
|
|
local nLeadId
|
|
local bInvert = bLeadInvert -- valore di default è quello settato nel file dei parametri
|
|
|
|
local _, dParEnd = EgtCurveDomain( nCrvOffs)
|
|
local bClosed = EgtCurveIsClosed( nCrvOffs)
|
|
local bOnlyOneCurve = not bClosed and ( dPar < GEO.EPS_SMALL or abs( dPar - dParEnd) < GEO.EPS_SMALL)
|
|
|
|
local nMainCrv = nCrvOffs -- curva preferita da utilizzare per lead in
|
|
local nOtherCrv -- altra possibile curva da ultizzare nel caso nMainCrv non sia adatta
|
|
|
|
if bClosed then
|
|
EgtChangeClosedCurveStart( nCrvOffs, dPar)
|
|
nOtherCrv = nCrvOffs
|
|
elseif not bOnlyOneCurve then
|
|
nOtherCrv = EgtSplitCurveAtParam( nCrvOffs, dPar)
|
|
end
|
|
|
|
-- calcolo del parametro bInvert
|
|
if bOnlyOneCurve then
|
|
-- invert dipende dall'estremo da cui parte il setto
|
|
bInvert = abs( dPar - dParEnd) < GEO.EPS_SMALL
|
|
elseif not bClosed then
|
|
-- invert può essere legato anche alla lunghezza dei tratti possibili
|
|
local dLen1 = EgtCurveLength( nMainCrv)
|
|
local dLen2 = EgtCurveLength( nOtherCrv)
|
|
if dLen1 > dLeadLen - GEO.EPS_SMALL and dLen2 < dLeadLen - GEO.EPS_SMALL then
|
|
bInvert = true
|
|
elseif dLen1 < dLeadLen - GEO.EPS_SMALL and dLen2 > dLeadLen - GEO.EPS_SMALL then
|
|
bInvert = false
|
|
end
|
|
|
|
if not bInvert then
|
|
nMainCrv, nOtherCrv = nOtherCrv, nMainCrv
|
|
end
|
|
end
|
|
|
|
-- primo tentativo con la curva favorita
|
|
nLeadId = EgtCopyGlob( nMainCrv, nCrv, EgtIf( bInVsOut, GDB_IN.BEFORE, GDB_IN.AFTER))
|
|
if bInvert then EgtInvertCurve( nLeadId) end
|
|
EgtTrimCurveEndAtLen( nLeadId, dLeadLen)
|
|
if bInVsOut then EgtInvertCurve( nLeadId) end
|
|
if VerifyRibsLead( nLeadId, nCrv, dStrand, bInVsOut, nGrpTmp) then
|
|
-- se valido aggiorno le curve per prossimi lead in/out
|
|
if bInvert then
|
|
EgtTrimCurveEndAtLen( nMainCrv, EgtCurveLength( nCrvOffs) - dLeadLen)
|
|
else
|
|
EgtTrimCurveStartAtLen( nMainCrv, dLeadLen)
|
|
end
|
|
elseif not nOtherCrv then
|
|
-- se non è valido e non ho altre curve possibili cancello
|
|
EgtErase( nLeadId)
|
|
return nil
|
|
else
|
|
-- se non è valido ma ho altra curva possibile, tento con quella
|
|
EgtErase( nLeadId)
|
|
nLeadId = EgtCopyGlob( nOtherCrv, nCrv, EgtIf( bInVsOut, GDB_IN.BEFORE, GDB_IN.AFTER))
|
|
if not bInvert then EgtInvertCurve( nLeadId) end
|
|
EgtTrimCurveEndAtLen( nLeadId, dLeadLen)
|
|
if bInVsOut then EgtInvertCurve( nLeadId) end
|
|
if VerifyRibsLead( nLeadId, nCrv, dStrand, bInVsOut, nGrpTmp) then
|
|
if bInvert then
|
|
EgtTrimCurveStartAtLen( nOtherCrv, dLeadLen)
|
|
else
|
|
EgtTrimCurveEndAtLen( nOtherCrv, EgtCurveLength( nCrvOffs) - dLeadLen)
|
|
end
|
|
else
|
|
EgtErase( nLeadId)
|
|
bInvert = not bInvert
|
|
return nil
|
|
end
|
|
-- aggiorno parametro bInvert
|
|
bInvert = not bInvert
|
|
end
|
|
|
|
return nLeadId, bInvert
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AddRibsLeadIn( nCrv, nLoopsGrp, dStrand, vtSlicing, nGrpTmp)
|
|
|
|
local dLILen = EgtGetInfo( nCrv, KEY_RIBS_LEAD_IN_LEN, 'd')
|
|
local bLIInvert = EgtGetInfo( nCrv, KEY_RIBS_LEAD_IN_INVERT, 'b')
|
|
|
|
if dLILen < GEO.EPS_SMALL then return end
|
|
|
|
-- recupero la curva di offset su cui calcolare leadin
|
|
local ptS = EgtSP( nCrv)
|
|
local nCrvOffs = EgtGetFirstInGroup( nLoopsGrp)
|
|
while nCrvOffs do
|
|
local dParS = EgtCurveParamAtPoint( nCrvOffs, ptS)
|
|
if dParS then
|
|
|
|
local nLeadIn = FindCorrectRibsLead( dParS, nCrv, nCrvOffs, bLIInvert, dLILen, dStrand, true, nGrpTmp)
|
|
-- se lead in possibile
|
|
if nLeadIn then
|
|
EgtModifyCurveExtrusion( nLeadIn, vtSlicing, GDB_RT.GLOB)
|
|
EgtSetInfo( nLeadIn, KEY_TYPE, TYPE.RIB)
|
|
EgtSetName( nLeadIn, LEAD_IN_CRV)
|
|
end
|
|
return
|
|
end
|
|
|
|
nCrvOffs = EgtGetNext( nCrvOffs)
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AddRibsLeadOut( nCrv, nTPathGrp, nLoopsGrp, vtSlicing, dStrand, nGrpTmp, bForceNoBorder)
|
|
|
|
local dRibsLOLen = EgtGetInfo( nCrv, KEY_RIBS_LEAD_OUT_LEN, 'd')
|
|
local dRibsLOCoasting = EgtGetInfo( nCrv, KEY_RIBS_LEAD_OUT_COASTING, 'd')
|
|
local dRibsLOWipe = EgtGetInfo( nCrv, KEY_RIBS_LEAD_OUT_WIPE, 'd')
|
|
local dRibsLOWipeAng = EgtGetInfo( nCrv, KEY_RIBS_LEAD_OUT_WIPE_DIR, 'd')
|
|
local bRibsLOInvert = EgtGetInfo( nCrv, KEY_RIBS_LEAD_OUT_INVERT, 'b')
|
|
|
|
if abs( dRibsLOLen) < GEO.EPS_SMALL and
|
|
abs( dRibsLOCoasting) < GEO.EPS_SMALL and
|
|
abs( dRibsLOWipe) < GEO.EPS_SMALL then return end
|
|
|
|
-- se setto chiuso oppure non deve stare sul bordo (rib unbounded) applico la stessa uscita delle shell
|
|
if EgtCurveIsClosed( nCrv) or bForceNoBorder then
|
|
return AddRetraction( nCrv, vtSlicing, dRibsLOCoasting, dRibsLOWipe, dRibsLOWipeAng)
|
|
end
|
|
|
|
local ptE = EgtEP( nCrv, GDB_ID.ROOT)
|
|
local vtE = EgtEV( nCrv, GDB_ID.ROOT)
|
|
|
|
-- recupero la curva di offset su cui calcolare lead out
|
|
local nCrvOffs = EgtGetFirstInGroup( nLoopsGrp)
|
|
while nCrvOffs do
|
|
local dParE = EgtCurveParamAtPoint( nCrvOffs, ptE, GEO.EPS_SMALL, GDB_RT.GLOB)
|
|
if dParE then
|
|
|
|
local nCrvLO
|
|
local nCoasting
|
|
local nWipe
|
|
|
|
-- trovo curva opportuna per lead out
|
|
local nCrvRef, bInvert = FindCorrectRibsLead( dParE, nCrv, nCrvOffs, bRibsLOInvert, dRibsLOLen + dRibsLOCoasting, dStrand, false, nGrpTmp)
|
|
|
|
if nCrvRef then
|
|
-- verifico se la curva ha lunghezza sufficiente
|
|
local dLen = EgtCurveLength( nCrvRef)
|
|
local bSkip = ( dLen - dRibsLOLen - dRibsLOCoasting < - GEO.EPS_SMALL)
|
|
|
|
-- primo tratto ( segue offset con flusso aperto)
|
|
if dRibsLOLen > GEO.EPS_SMALL and not bSkip then
|
|
nCrvLO = EgtCopyGlob( nCrvRef, nCrv, GDB_IN.AFTER)
|
|
EgtTrimCurveEndAtLen( nCrvLO, dRibsLOLen)
|
|
EgtModifyCurveExtrusion( nCrvLO, vtSlicing, GDB_RT.GLOB)
|
|
EgtSetInfo( nCrvLO, KEY_TYPE, TYPE.RIB)
|
|
EgtSetName( nCrvLO, LEAD_OUT_CRV)
|
|
-- aggiorno ptE e vtE
|
|
ptE = EgtEP( nCrvLO, GDB_ID.ROOT)
|
|
vtE = EgtEV( nCrvLO, GDB_ID.ROOT)
|
|
end
|
|
|
|
-- secondo tratto ( segue offset con flusso chiuso)
|
|
if dRibsLOCoasting > GEO.EPS_SMALL then
|
|
nCoasting = EgtCopyGlob( nCrvRef, nCrvLO or nCrv, GDB_IN.AFTER)
|
|
EgtTrimCurveStartAtLen( nCoasting, dRibsLOLen)
|
|
EgtTrimCurveEndAtLen( nCoasting, dRibsLOCoasting)
|
|
EgtModifyCurveExtrusion( nCoasting, vtSlicing, GDB_RT.GLOB)
|
|
|
|
EgtSetName( nCoasting, COASTING_CRV)
|
|
EgtSetInfo( nCoasting, KEY_TYPE, TYPE.COASTING)
|
|
EgtSetColor( nCoasting, EgtStdColor('ORANGE'))
|
|
|
|
-- aggiorno ptE e vtE
|
|
ptE = EgtEP( nCoasting, GDB_ID.ROOT)
|
|
vtE = EgtEV( nCoasting, GDB_ID.ROOT)
|
|
end
|
|
EgtErase( nCrvRef)
|
|
|
|
-- terzo tratto ( diretto verso esterno con ugello chiuso)
|
|
if dRibsLOWipe > GEO.EPS_SMALL then
|
|
local dAng = dRibsLOWipeAng + s_nDefaultWipeAng
|
|
local nType = EgtGetInfo( nCrv, KEY_RIBS_TYPE, 'i')
|
|
if nType == RIB_TYPE.EXTERNAL then dAng = - dAng end
|
|
vtE:rotate( vtSlicing, EgtIf( bInvert, - dAng, dAng))
|
|
local ptFinal = FindWipeEndPoint( ptE, vtE, dRibsLOWipe, vtSlicing)
|
|
nWipe = EgtCurveCompoFromPoints( nTPathGrp, { ptE, ptFinal}, GDB_RT.GLOB)
|
|
EgtModifyCurveExtrusion( nWipe, vtSlicing, GDB_RT.GLOB)
|
|
EgtRelocateGlob( nWipe, nCoasting or nCrvLO or nCrv, GDB_IN.AFTER)
|
|
EgtSetName( nWipe, WIPE_CRV)
|
|
EgtSetInfo( nWipe, KEY_TYPE, TYPE.WIPE)
|
|
EgtSetColor( nWipe, EgtStdColor('AQUA'))
|
|
end
|
|
else
|
|
-- aggiungo coasting e wipe come sulle shell normali
|
|
AddRetraction( nCrv, vtSlicing, dRibsLOCoasting, dRibsLOWipe, dRibsLOWipeAng)
|
|
end
|
|
return
|
|
end
|
|
|
|
nCrvOffs = EgtGetNext( nCrvOffs)
|
|
end
|
|
|
|
-- se non ho trovato curva sul bordo su cui fare il lead out aggiungo coasting e wipe come sulle shell normali
|
|
AddRetraction( nCrv, vtSlicing, dRibsLOCoasting, dRibsLOWipe, dRibsLOWipeAng)
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcRibsToolPath( vEntIds, nRibsGrp, nTpathGrpId, LayerParams)
|
|
|
|
if not vEntIds or #vEntIds == 0 then return end
|
|
|
|
-- gruppo temporaneo con sistema di riferimento locale per conti
|
|
local frLoc = Frame3d( ORIG(), LayerParams.vtSlicing)
|
|
local nGrpTmp = EgtGroup( nRibsGrp, frLoc, GDB_RT.GLOB)
|
|
|
|
-- aggiungo le costolature nel toolpath
|
|
local nNewFirstEnt
|
|
for i = 1, #vEntIds do
|
|
-- copio entità nel gruppo toolpath
|
|
local nNewEntId = EgtCopyGlob( vEntIds[i], nTpathGrpId, GDB_IN.LAST_SON)
|
|
-- mi sposto dell'altezza layer
|
|
EgtMove( nNewEntId, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
EgtModifyCurveExtrusion( nNewEntId, LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
EgtSetColor( nNewEntId, EgtStdColor('MAROON'))
|
|
if i == 1 then nNewFirstEnt = nNewEntId end
|
|
end
|
|
|
|
-- recupero i gruppi delle costolature
|
|
local tabRibs = {}
|
|
local nFirst = nNewFirstEnt
|
|
while nFirst do
|
|
local sName = EgtGetName( nFirst)
|
|
local vIds = EgtGetNameInGroup( nTpathGrpId, sName)
|
|
table.insert( tabRibs, vIds)
|
|
nFirst = EgtGetNextName( vIds[#vIds], RIBS_CRV .. '*')
|
|
end
|
|
|
|
local bSpecialCase = EgtGetInfo( nRibsGrp, KEY_RIBS_SPECIAL_CASE, 'b') or false
|
|
|
|
-- Link
|
|
local nLoopGrp = EgtGetFirstGroupInGroup( nRibsGrp)
|
|
-- collego le passate di una stessa costolatura
|
|
for i = 1, #tabRibs do
|
|
if EgtCurveIsClosed( tabRibs[i][1]) then
|
|
AddLink( tabRibs[i], nTpathGrpId, LINK_TYPE.NONE, LayerParams.dLinkParam, LayerParams.dSPOffs, LayerParams.dStrand, LayerParams.vtSlicing)
|
|
else
|
|
local bLoopRib = EgtGetInfo( tabRibs[i][1], KEY_LOOP_RIB, 'b') or false
|
|
for j = 1, #tabRibs[i] - 1 do
|
|
local bUserLink = ( EgtGetInfo( tabRibs[i][j], KEY_RIBS_USER_LINK, 'b') or false) and ( EgtGetInfo( tabRibs[i][j+1], KEY_RIBS_USER_LINK, 'b') or false)
|
|
local nOrig1 = EgtGetInfo( tabRibs[i][j], KEY_ORIGINAL_RIB, 'i') or 0
|
|
local nOrig2 = EgtGetInfo( tabRibs[i][j + 1], KEY_ORIGINAL_RIB, 'i') or 0
|
|
local nSplitId1 = EgtGetInfo( tabRibs[i][j], KEY_SPLIT_ID, 'i') or 0
|
|
local nSplitId2 = EgtGetInfo( tabRibs[i][j + 1], KEY_SPLIT_ID, 'i') or 0
|
|
local bForceLink = ( nOrig1 == nOrig2)
|
|
|
|
if ( nOrig1 ~= nOrig2 and bUserLink) or ( nSplitId1 == nSplitId2 and nOrig1 == nOrig2) then
|
|
local nLinkId = CalcRibsLink( tabRibs[i][j], tabRibs[i][j + 1], nLoopGrp, LayerParams.dStrand, bForceLink, LayerParams.vtSlicing, nGrpTmp)
|
|
-- creo link fittizio per eliminare tratto corrispondente sulla curva di offset
|
|
if not bSpecialCase and bForceLink then
|
|
local nFakeLink = CalcRibsLink( tabRibs[i][j + 1], tabRibs[i][j], nLoopGrp, LayerParams.dStrand, false, LayerParams.vtSlicing, nGrpTmp)
|
|
EgtErase( nFakeLink)
|
|
end
|
|
|
|
-- se LoopRib congiungo i setti in unico percorso
|
|
if bLoopRib and nLinkId then
|
|
EgtAddCurveCompoCurve( tabRibs[i][j], nLinkId)
|
|
EgtAddCurveCompoCurve( tabRibs[i][j], tabRibs[i][j + 1])
|
|
tabRibs[i][j+1] = tabRibs[i][j] -- aggiorno id nel vettore dei setti per gestire correttamente la curva allo step successivo
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se LoopRib aggiungo collegamento tra primo e ultimo setto del gruppo
|
|
if bLoopRib then
|
|
local nTotCrv = #tabRibs[i]
|
|
local nLinkId = CalcRibsLink( tabRibs[i][nTotCrv], tabRibs[i][1], nLoopGrp, LayerParams.dStrand, false, LayerParams.vtSlicing, nGrpTmp)
|
|
if nLinkId then
|
|
-- se curva unica
|
|
if tabRibs[i][nTotCrv] == tabRibs[i][1] then
|
|
EgtAddCurveCompoCurve( tabRibs[i][1], nLinkId)
|
|
-- setto info di curva chiusa per gestire correttamente il wipe
|
|
EgtSetInfo( tabRibs[i][1], KEY_CLOSED_CRV, 1)
|
|
-- modifica dello start point ( considera quello delle shell)
|
|
local nCrvGrp = EgtGetParent( nTpathGrpId)
|
|
local ptStart = EgtGetInfo( nCrvGrp, KEY_START_POINT, 'p')
|
|
if ptStart then
|
|
EgtChangeClosedCurveStartPoint( tabRibs[i][1], ptStart)
|
|
end
|
|
else
|
|
EgtAddCurveCompoCurve( tabRibs[i][1], nLinkId, true, false)
|
|
EgtAddCurveCompoCurve( tabRibs[i][1], tabRibs[i][nTotCrv], true, false)
|
|
tabRibs[i][nTotCrv] = tabRibs[i][1]
|
|
end
|
|
end
|
|
end
|
|
|
|
if bSpecialCase then
|
|
local nFakeLink = CalcRibsLink( tabRibs[i][#tabRibs[i]], tabRibs[i][1], nLoopGrp, LayerParams.dStrand, false, LayerParams.vtSlicing, nGrpTmp)
|
|
EgtErase( nFakeLink)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se necessario collego le diverse costolature
|
|
for i = 1, #tabRibs - 1 do
|
|
local bLink1 = EgtGetInfo( tabRibs[i][1], KEY_RIBS_LINK, 'b')
|
|
local bLink2 = EgtGetInfo( tabRibs[i + 1][1], KEY_RIBS_LINK, 'b')
|
|
if bLink1 and bLink2 then
|
|
local nCnt = #tabRibs[i]
|
|
CalcRibsLink( tabRibs[i][nCnt], tabRibs[i + 1][1], nLoopGrp, LayerParams.dStrand, false, LayerParams.vtSlicing, nGrpTmp)
|
|
end
|
|
end
|
|
|
|
-- leadin/leadout
|
|
local bForceNoBorder = false
|
|
local nType = EgtGetInfo( vEntIds[1], KEY_RIBS_TYPE, 'i')
|
|
if nType == RIB_TYPE.UNBOUNDED then
|
|
bForceNoBorder = true
|
|
end
|
|
local nCrvRib = nNewFirstEnt
|
|
while nCrvRib do
|
|
-- verifico se necessario lead in
|
|
local nPrev = EgtGetPrev( nCrvRib)
|
|
if ( not nPrev or EgtGetName( nPrev) ~= LINK_CRV) and not bForceNoBorder then
|
|
AddRibsLeadIn( nCrvRib, nLoopGrp, LayerParams.dStrand, LayerParams.vtSlicing, nGrpTmp)
|
|
end
|
|
-- verifico se necessario lead out
|
|
local nNext = EgtGetNext( nCrvRib)
|
|
if not nNext or EgtGetName( nNext) ~= LINK_CRV then
|
|
AddRibsLeadOut( nCrvRib, nTpathGrpId, nLoopGrp, LayerParams.vtSlicing, LayerParams.dStrand, nGrpTmp, bForceNoBorder)
|
|
end
|
|
nCrvRib = EgtGetNextName( nCrvRib, RIBS_CRV .. '*')
|
|
end
|
|
|
|
EgtErase( nGrpTmp)
|
|
|
|
end
|
|
|
|
-------------------------------------------------------------------
|
|
------------------------- SPIRAL VASE ------------------------------
|
|
--------------------------------------------------------------------
|
|
local function AddSpiralVaseLeadOut( nOldId, LayerParams)
|
|
|
|
if LayerParams.nLeadOutType ~= LEAD_TYPE.NONE then
|
|
EgtTrimCurveEndAtLen( nOldId, EgtCurveLength( nOldId) - LayerParams.dOffsetLP)
|
|
local nLeadOut = AddLeadOut( nOldId, LayerParams, EgtGetParent( nOldId))
|
|
if nLeadOut then
|
|
local dDelta = LayerParams.dLayHeight / EgtCurveLength( nOldId) * EgtCurveLength( nLeadOut)
|
|
EgtSpiralizeCurveAlongExtrusion( nLeadOut, dDelta)
|
|
end
|
|
AddRetractionOnLastCrv( nOldId, EgtGetParent( nOldId), LayerParams, LayerParams.dCoastingLen, LayerParams.dWipeLen, LayerParams.dWipeDir)
|
|
else
|
|
AddRetraction( nOldId, LayerParams.vtSlicing, LayerParams.dCoastingLen, LayerParams.dWipeLen, LayerParams.dWipeDir)
|
|
end
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function SpiralVase( vLayIds, LayerParams)
|
|
|
|
local nOldId, nOldPathId
|
|
local bFirst = true
|
|
local nSlicingType = EgtGetInfo( s_nPartId, KEY_SLICING_TYPE, 'i')
|
|
|
|
-- copio ultimo layer
|
|
if nSlicingType ~= SLICING_TYPE.DEG45_X and nSlicingType ~= SLICING_TYPE.DEG45_Y then
|
|
local nNewLay = EgtCopyGlob( vLayIds[#vLayIds], vLayIds[#vLayIds], GDB_IN.AFTER)
|
|
table.insert( vLayIds, nNewLay)
|
|
EgtMove( nNewLay, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
-- aggiorno nome e info
|
|
local sOldIdx = string.sub( EgtGetName( vLayIds[#vLayIds]), 6)
|
|
local nNewIdx = tonumber( sOldIdx) + 1
|
|
EgtSetName( nNewLay, SLICE_LAYER .. EgtNumToString( nNewIdx))
|
|
EgtSetInfo( nNewLay, KEY_SLICE_NBR, nNewIdx)
|
|
local dZOld = EgtGetInfo( vLayIds[#vLayIds], KEY_SLICE_Z, 'd') or 0
|
|
EgtSetInfo( nNewLay, KEY_SLICE_Z, dZOld + LayerParams.dLayHeight)
|
|
end
|
|
|
|
local b3Tot = BBox3d()
|
|
-- ciclo sui layer
|
|
for nIdx = 1, #vLayIds do
|
|
|
|
-- cerco i gruppi di contorni
|
|
local vCrvGrpIds = EgtGetNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*")
|
|
if #vCrvGrpIds > 1 then
|
|
-- se più di un gruppo di curve warning
|
|
EgtOutLog( 'Warning : in spiral vase mode more than one curve (layer '..tostring( nIdx)..') - CalcToolPath')
|
|
end
|
|
|
|
for i = 1, #vCrvGrpIds do
|
|
-- recupero il gruppo dei percorsi
|
|
local nPathGrpId = EgtGetFirstNameInGroup( vCrvGrpIds[i], PATH_GRP)
|
|
if not nPathGrpId then
|
|
EgtOutBox( 'Error missing paths', 'ToolPathCalc')
|
|
return
|
|
else
|
|
EgtSetStatus( nPathGrpId, GDB_ST.OFF)
|
|
end
|
|
|
|
-- recupero il gruppo dei percorsi utensile
|
|
local nTpathGrpId = EgtGetFirstNameInGroup( vCrvGrpIds[i], TOOLPATH_GRP)
|
|
if not nTpathGrpId then
|
|
nTpathGrpId = EgtGroup( vCrvGrpIds[i])
|
|
EgtSetName( nTpathGrpId, TOOLPATH_GRP)
|
|
else
|
|
EgtEmptyGroup( nTpathGrpId)
|
|
end
|
|
|
|
-- creo il percorso di lavoro :
|
|
local nEntId = EgtGetFirstInGroup( nPathGrpId)
|
|
while nEntId do
|
|
local nNewEntId = EgtCopyGlob( nEntId, nTpathGrpId, GDB_IN.LAST_SON)
|
|
|
|
local vtMove = V_NULL()
|
|
-- eventuale spostamento dell'altezza layer
|
|
if nSlicingType == SLICING_TYPE.DEG45_X or nSlicingType == SLICING_TYPE.DEG45_Y then
|
|
vtMove = LayerParams.dLayHeight * LayerParams.vtSlicing
|
|
EgtMove( nNewEntId, vtMove, GDB_RT.GLOB)
|
|
end
|
|
|
|
EgtModifyCurveExtrusion( nNewEntId, LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
-- eventuale inversione
|
|
if LayerParams.bInvert then
|
|
EgtInvertCurve( nNewEntId)
|
|
EgtSetInfo( nNewEntId, KEY_INVERTED_CRV, 1)
|
|
end
|
|
EgtSetColor( nNewEntId, EgtStdColor('GRAY'))
|
|
|
|
-- se primo layer
|
|
if bFirst and nNewEntId then
|
|
-- mi sposto dell'altezza layer
|
|
EgtMove( nNewEntId, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
-- eventuale lead in
|
|
if LayerParams.nLeadInType ~= LEAD_TYPE.NONE then
|
|
EgtTrimCurveStartAtLen( nNewEntId, LayerParams.dOffsetLP)
|
|
AddLeadIn( nNewEntId, LayerParams, nTpathGrpId)
|
|
end
|
|
bFirst = false
|
|
else
|
|
local ptOld = EgtEP( nOldId, GDB_ID.ROOT)
|
|
local ptNew = EgtSP( nNewEntId, GDB_ID.ROOT)
|
|
if dist( ptNew, ptOld) < LayerParams.dStrand then
|
|
-- se i punti sono vicini ma non coincidenti modifico la curva per avere transizione più uniforme
|
|
if not AreSamePointApprox( ptOld, ptNew) then
|
|
-- recupero la curva da usare come guida
|
|
local nGuideId = EgtCopyGlob( nOldPathId, nTpathGrpId)
|
|
-- la porto alla stessa quota del toolpath
|
|
EgtMove( nGuideId, vtMove + LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
EgtChangeClosedCurveStartPoint( nGuideId, ptOld, GDB_RT.GLOB)
|
|
|
|
EgtSpiralizeCurveAlongGuide( nNewEntId, nGuideId)
|
|
EgtErase( nGuideId)
|
|
end
|
|
else
|
|
EgtOutLog( 'Warning : in spiral vase mode no link betweeen toolpaths (layer '..tostring( nIdx)..') - CalcToolPath')
|
|
-- aggiungo uscita, coasting e wipe sulla curva precedente
|
|
AddSpiralVaseLeadOut( nOldId, LayerParams)
|
|
end
|
|
EgtSpiralizeCurveAlongExtrusion( nNewEntId, LayerParams.dLayHeight)
|
|
end
|
|
|
|
nOldPathId = nEntId
|
|
nOldId = nNewEntId
|
|
nEntId = EgtGetNext( nEntId)
|
|
end
|
|
|
|
-- aggiorno il box dei toolpath
|
|
local b3Box = ComputeToolPathBox( nTpathGrpId)
|
|
b3Tot:Add( b3Box)
|
|
|
|
end
|
|
|
|
if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / #vLayIds * 100, 0) == 1 then
|
|
EgtDraw()
|
|
return false
|
|
end
|
|
end
|
|
|
|
-- aggiungo uscita, coasting e wipe su ultima curva
|
|
AddSpiralVaseLeadOut( nOldId, LayerParams)
|
|
|
|
-- correzione in z
|
|
AddZCorrection( b3Tot, LayerParams)
|
|
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function CalcToolPath.Exec( nPartId)
|
|
|
|
s_nPartId = nPartId
|
|
|
|
-- Recupero i layer da processare
|
|
local vLayIds = EgtGetNameInGroup( s_nPartId, SLICE_LAYER.."*")
|
|
if not vLayIds then
|
|
EgtOutBox( 'Error missing slices', 'ToolPathCalc')
|
|
return true
|
|
end
|
|
|
|
-- recupero i parametri per calcolo dei toolpath
|
|
local LayerParams = GetLayerParamsForToolPathCalc()
|
|
|
|
-- altezza necessaria per correzione wipe
|
|
local dNxy = sqrt( LayerParams.vtSlicing:getX() * LayerParams.vtSlicing:getX() + LayerParams.vtSlicing:getY() * LayerParams.vtSlicing:getY())
|
|
local dHBox = EgtGetInfo( s_nPartId, KEY_BOX_MIN_Z, 'i') or 0
|
|
s_dHMin = LayerParams.dTDiam / 2 * dNxy + dHBox
|
|
|
|
-- caso spiral vase
|
|
if LayerParams.bSpiralVase then
|
|
return SpiralVase( vLayIds, LayerParams)
|
|
end
|
|
|
|
local b3Tot = BBox3d() -- box dei toolpath
|
|
|
|
-- Ciclo sui layer
|
|
for nIdx = 1, #vLayIds do
|
|
|
|
-- scorro tutti i gruppi di contorni
|
|
local nCrvGrpId = EgtGetFirstNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*")
|
|
while nCrvGrpId do
|
|
-- recupero il gruppo dei percorsi
|
|
local nPathGrpId = EgtGetFirstNameInGroup( nCrvGrpId, PATH_GRP)
|
|
if not nPathGrpId then
|
|
EgtOutBox( 'Error missing paths', 'ToolPathCalc')
|
|
return
|
|
else
|
|
EgtSetStatus( nPathGrpId, GDB_ST.OFF)
|
|
end
|
|
-- recupero il gruppo dei percorsi utensile
|
|
local nTpathGrpId = EgtGetFirstNameInGroup( nCrvGrpId, TOOLPATH_GRP)
|
|
if not nTpathGrpId then
|
|
nTpathGrpId = EgtGroup( nCrvGrpId)
|
|
EgtSetName( nTpathGrpId, TOOLPATH_GRP)
|
|
else
|
|
EgtEmptyGroup( nTpathGrpId)
|
|
end
|
|
|
|
-- suddivido i ribs per tipologia
|
|
local nRibsGrp = EgtGetFirstNameInGroup( nCrvGrpId, RIBS_GRP)
|
|
local tRibs = {{}, {}, {}, {}}
|
|
local vRibsIds = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*') or {}
|
|
for i = 1, #vRibsIds do
|
|
local nType = EgtGetInfo( vRibsIds[i], KEY_RIBS_TYPE, 'i') or 1
|
|
table.insert( tRibs[nType], vRibsIds[i])
|
|
end
|
|
|
|
-- realizzo le diverse tipologie in base all'ordine selezionato
|
|
for j = 1, #LayerParams.vPrintOrder do
|
|
|
|
if LayerParams.vPrintOrder[j] == PRINT_ELEMENT.SHELL then
|
|
-- shell
|
|
local vShellIds = EgtGetNameInGroup( nPathGrpId, SHELL_CRV .. '*')
|
|
CalcShellsToolPath( vShellIds, nTpathGrpId, LayerParams)
|
|
elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.EXTRA_SHELL then
|
|
-- extra shell
|
|
local vExtraShellIds = EgtGetNameInGroup( nPathGrpId, EXTRA_SHELL_CRV .. '*')
|
|
CalcExtraShellToolPath( vExtraShellIds, nTpathGrpId, LayerParams)
|
|
elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.INFILL then
|
|
-- infill
|
|
local vInfillIds = EgtGetNameInGroup( nPathGrpId, INFILL_CRV .. '*')
|
|
CalcInfillToolPath( vInfillIds, nTpathGrpId, LayerParams)
|
|
elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.AUX_SOLID then
|
|
-- solidi ausiliari
|
|
local nAuxSolidsGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], AUX_SOLIDS_GRP)
|
|
local nAuxSolidsPathGrp = EgtGetFirstNameInGroup( nCrvGrpId, AUX_SOLIDS_GRP)
|
|
CalcAuxSolidsToolPath( nAuxSolidsGrp, nAuxSolidsPathGrp, nTpathGrpId, LayerParams)
|
|
|
|
-- costolature
|
|
elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_UNBOUNDED then
|
|
CalcRibsToolPath( tRibs[RIB_TYPE.UNBOUNDED], nRibsGrp, nTpathGrpId, LayerParams)
|
|
elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_INTERNAL then
|
|
CalcRibsToolPath( tRibs[RIB_TYPE.INTERNAL], nRibsGrp, nTpathGrpId, LayerParams)
|
|
elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_SUPPORT then
|
|
CalcRibsToolPath( tRibs[RIB_TYPE.SUPPORT], nRibsGrp, nTpathGrpId, LayerParams)
|
|
elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_EXTERNAL then
|
|
CalcRibsToolPath( tRibs[RIB_TYPE.EXTERNAL], nRibsGrp, nTpathGrpId, LayerParams)
|
|
end
|
|
|
|
end
|
|
|
|
-- aggiorno il box dei toolpath
|
|
local b3Box = ComputeToolPathBox( nTpathGrpId)
|
|
b3Tot:Add( b3Box)
|
|
|
|
-- passo al gruppo di contorni successivo
|
|
nCrvGrpId = EgtGetNextName( nCrvGrpId, CONTOUR_GRP.."*")
|
|
end
|
|
|
|
if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / #vLayIds * 100, 0) == 1 then
|
|
EgtDraw()
|
|
return
|
|
end
|
|
end
|
|
|
|
-- correzione in z
|
|
AddZCorrection( b3Tot, LayerParams)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return CalcToolPath
|