3988809c7e
- nel lead out dei setti corretta la distinzione fra coasting e wipe.
661 lines
27 KiB
Lua
661 lines
27 KiB
Lua
-- CalcToolPath.lua by Egaltech s.r.l. 2022/04/19
|
|
-- 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 function GetLayerParamsForToolPathCalc()
|
|
local LayerParams = {}
|
|
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_PRINT_ORDER, 'i')
|
|
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.vtSlicing = EgtGetInfo( s_nPartId, KEY_SLICING_DIR, 'v')
|
|
LayerParams.dTDiam = EgtGetInfo( s_nPartId, KEY_TOOL_DIAM, 'd')
|
|
-- Parametri costolature
|
|
LayerParams.nRibsShellsNbr = EgtGetInfo( s_nPartId, KEY_RIBS_SHELLS_NBR, 'i')
|
|
LayerParams.bRibsLink = EgtGetInfo( s_nPartId, KEY_RIBS_LINK, 'b')
|
|
LayerParams.bRibsInvert = EgtGetInfo( s_nPartId, KEY_RIBS_INVERT_DIR, 'b')
|
|
LayerParams.bRibsLIInvert = EgtGetInfo( s_nPartId, KEY_RIBS_LEAD_IN_INVERT, 'b')
|
|
LayerParams.dRibsLILen = EgtGetInfo( s_nPartId, KEY_RIBS_LEAD_IN_LEN, 'd')
|
|
LayerParams.bRibsLOInvert = EgtGetInfo( s_nPartId, KEY_RIBS_LEAD_OUT_INVERT, 'b')
|
|
LayerParams.dRibsLOLen = EgtGetInfo( s_nPartId, KEY_RIBS_LEAD_OUT_LEN, 'd')
|
|
LayerParams.dRibsLOCoasting = EgtGetInfo( s_nPartId, KEY_RIBS_LEAD_OUT_COASTING, 'd')
|
|
LayerParams.dRibsLOWipe = EgtGetInfo( s_nPartId, KEY_RIBS_LEAD_OUT_WIPE, 'd')
|
|
LayerParams.dRibsLOWipeAng = EgtGetInfo( s_nPartId, KEY_RIBS_LEAD_OUT_WIPE_DIR, 'd')
|
|
|
|
return LayerParams
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function ComputeZCorrection( LayerParams)
|
|
-- direzione dell'estrusore
|
|
local vtN = LayerParams.vtSlicing
|
|
local dNxy = sqrt( vtN:getX() * vtN:getX() + vtN:getY() * vtN:getY())
|
|
local dNz = vtN:getZ()
|
|
-- correzione per l'offset
|
|
local dCorr1 = LayerParams.dOffs * dNxy
|
|
-- correzione per il diametro dell'ugello
|
|
local dCorr2 = ( LayerParams.dOffs - LayerParams.dStrand / 2 + LayerParams.dTDiam / 2) * dNxy - LayerParams.dLayHeight * dNz
|
|
-- massimo tra le due
|
|
return max( dCorr1, dCorr2)
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AddLeadIn( nCrvId, LayerParams, nGrpId)
|
|
|
|
local ptE = EgtSP( nCrvId)
|
|
local vtTang = EgtSV( nCrvId)
|
|
local vtOrtho = Vector3d( vtTang)
|
|
local dAng = 90
|
|
if ( LayerParams.bInvert and LayerParams.nOrder == PRINT_ORDER.INF_INT_EXT) or
|
|
( not LayerParams.bInvert and LayerParams.nOrder == PRINT_ORDER.EXT_INT_INF) then
|
|
dAng = - 90
|
|
end
|
|
|
|
vtOrtho:rotate( LayerParams.vtSlicing, dAng)
|
|
local ptS = ptE - LayerParams.dLeadInTangDist * vtTang + LayerParams.dLeadInOrthoDist * vtOrtho
|
|
|
|
local nLeadInCrv = GDB_ID.NULL
|
|
if LayerParams.nLeadInType == LEAD_TYPE.LINEAR then
|
|
nLeadInCrv = EgtCurveCompoFromPoints( nGrpId, {ptS, ptE})
|
|
elseif LayerParams.nLeadInType == LEAD_TYPE.ARC then
|
|
nLeadInCrv = EgtArc2PV( nGrpId, ptE, ptS, -vtTang)
|
|
EgtInvertCurve( nLeadInCrv)
|
|
end
|
|
EgtRelocate( nLeadInCrv, nGrpId, GDB_IN.FIRST_SON)
|
|
EgtModifyCurveExtrusion( nLeadInCrv, LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
EgtSetInfo( nLeadInCrv, KEY_TYPE, TYPE.LINK)
|
|
EgtSetName( nLeadInCrv, LEAD_IN_CRV)
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AddLeadOut( nCrvId, LayerParams, nGrpId)
|
|
|
|
local ptS = EgtEP( nCrvId)
|
|
local vtTang = EgtEV( nCrvId)
|
|
local vtOrtho = Vector3d( vtTang)
|
|
local dAng = - 90
|
|
if ( LayerParams.bInvert and LayerParams.nOrder == PRINT_ORDER.INF_INT_EXT) or
|
|
( not LayerParams.bInvert and LayerParams.nOrder == PRINT_ORDER.EXT_INT_INF) then
|
|
dAng = 90
|
|
end
|
|
|
|
vtOrtho:rotate( LayerParams.vtSlicing, dAng)
|
|
local ptE = ptS + LayerParams.dLeadOutTangDist * vtTang + LayerParams.dLeadOutOrthoDist * vtOrtho
|
|
|
|
local nLeadOutCrv = GDB_ID.NULL
|
|
if LayerParams.nLeadOutType == LEAD_TYPE.LINEAR then
|
|
nLeadOutCrv = EgtCurveCompoFromPoints( nGrpId, {ptS, ptE})
|
|
elseif LayerParams.nLeadOutType == LEAD_TYPE.ARC then
|
|
nLeadOutCrv = EgtArc2PV( nGrpId, ptS, ptE, vtTang)
|
|
end
|
|
EgtRelocate( nLeadOutCrv, nGrpId, GDB_IN.LAST_SON)
|
|
EgtModifyCurveExtrusion( nLeadOutCrv, LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
EgtSetInfo( nLeadOutCrv, KEY_TYPE, TYPE.LINK)
|
|
EgtSetName( nLeadOutCrv, LEAD_OUT_CRV)
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AddRetraction( nCrvId, dCoastingLen, dWipeLen)
|
|
|
|
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)
|
|
return
|
|
end
|
|
EgtTrimCurveStartAtParam( nCoastingId, dPar)
|
|
-- aggiorno la curva originale
|
|
if dPar > GEO.EPS_SMALL then
|
|
EgtTrimCurveEndAtParam( nCrvId, dPar)
|
|
else
|
|
EgtErase( nCrvId)
|
|
end
|
|
EgtSetName( nCoastingId, COASTING_CRV)
|
|
EgtSetInfo( nCoastingId, KEY_TYPE, TYPE.COASTING)
|
|
EgtSetColor( nCoastingId, EgtStdColor('ORANGE'))
|
|
end
|
|
|
|
if dWipeLen > GEO.EPS_SMALL then
|
|
local nWipeId = EgtCopyGlob( nCrvId, EgtIf( nCoastingId, nCoastingId, nCrvId), GDB_IN.AFTER)
|
|
EgtTrimCurveEndAtLen( nWipeId, dWipeLen)
|
|
EgtSetName( nWipeId, WIPE_CRV)
|
|
EgtSetInfo( nWipeId, KEY_TYPE, TYPE.WIPE)
|
|
EgtSetColor( nWipeId, EgtStdColor('TEAL'))
|
|
end
|
|
|
|
return nCoastingId
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AddRetractionOnLastCrv( nTpathGrpId, LayerParams)
|
|
|
|
local nCrvId = EgtGetLastNameInGroup( nTpathGrpId, SHELL_CRV .. "*")
|
|
if LayerParams.nLeadOutType == LEAD_TYPE.NONE then
|
|
AddRetraction( nCrvId, LayerParams.dCoastingLen, LayerParams.dWipeLen)
|
|
else
|
|
local nLeadOutId = EgtGetLastInGroup( nTpathGrpId)
|
|
local dLen = EgtCurveLength( nLeadOutId)
|
|
if dLen > LayerParams.dCoastingLen - 500 * GEO.EPS_SMALL then
|
|
-- coinvolge solo la curva di lead out
|
|
local dNewCoastingLen = EgtIf( abs( LayerParams.dCoastingLen - dLen) < 500 * GEO.EPS_SMALL, dLen, LayerParams.dCoastingLen) -- verifico se interamente coinvolta
|
|
AddRetraction( nLeadOutId, dNewCoastingLen, 0.0)
|
|
else
|
|
-- coinvolge parte dell'ultima shell crv
|
|
local dNewCoastingLen = LayerParams.dCoastingLen - dLen
|
|
local nCoastingId = AddRetraction( nCrvId, dNewCoastingLen, 0.0)
|
|
EgtAddCurveCompoCurve( nCoastingId, nLeadOutId)
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function CalcRibsLink( ptS, ptE, nCurr, nLoopGrp, bForceLink)
|
|
|
|
local nCrvId = EgtGetFirstInGroup( nLoopGrp)
|
|
-- recupero la curva di offset su cui calcolare link
|
|
while nCrvId do
|
|
local dParS = EgtCurveParamAtPoint( nCrvId, ptS)
|
|
local dParE = EgtCurveParamAtPoint( nCrvId, ptE)
|
|
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 bInvert then
|
|
bInvert = true
|
|
dParS, dParE = dParE, dParS
|
|
end
|
|
|
|
EgtTrimCurveStartEndAtParam( nLinkId, dParS, dParE)
|
|
EgtSetInfo( nLinkId, KEY_TYPE, TYPE.RIB)
|
|
if bInvert then EgtInvertCurve( nLinkId) end
|
|
|
|
if bClosed then
|
|
EgtTrimCurveStartEndAtParam( nCrvId, dParE, dParS)
|
|
EgtErase( nCopyId)
|
|
else
|
|
EgtTrimCurveEndAtParam( nCrvId, dParS)
|
|
EgtTrimCurveStartAtParam( nCopyId, dParE)
|
|
end
|
|
|
|
return nLinkId
|
|
end
|
|
|
|
nCrvId = EgtGetNext( nCrvId)
|
|
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})
|
|
EgtSetInfo( nLinkId, KEY_TYPE, TYPE.RIB)
|
|
EgtRelocateGlob( nLinkId, nCurr, GDB_IN.AFTER)
|
|
end
|
|
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AddRibsLeadIn( nCrv, nLoopsGrp, LayerParams)
|
|
|
|
if LayerParams.dRibsLILen < 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 nCrvId = EgtCopyGlob( nCrvOffs, nCrv, GDB_IN.BEFORE)
|
|
local bClosed = EgtCurveIsClosed( nCrvId)
|
|
if bClosed then
|
|
EgtChangeClosedCurveStart( nCrvId, dParS)
|
|
dParS = 0
|
|
end
|
|
|
|
-- scelgo il lato da cui fare ingresso
|
|
local _, dEndPar = EgtCurveDomain( nCrvId)
|
|
-- se ho solo un tratto possibile verifico se va invertito
|
|
if abs( dParS - dEndPar) < GEO.EPS_SMALL then
|
|
EgtInvertCurve( nCrvId)
|
|
elseif abs( dParS) > GEO.EPS_SMALL or bClosed then
|
|
-- se ho più tratti possibili scelgo in base al parametro RibsLIInvert
|
|
local nNewId = EgtSplitCurveAtParam( nCrvId, dParS) or EgtCopyGlob( nCrvId, nCrv, GDB_IN.BEFORE)
|
|
if LayerParams.bRibsLIInvert then
|
|
EgtInvertCurve( nCrvId)
|
|
EgtErase( nNewId)
|
|
else
|
|
EgtErase( nCrvId)
|
|
nCrvId = nNewId
|
|
end
|
|
end
|
|
|
|
EgtTrimCurveEndAtLen( nCrvId, LayerParams.dRibsLILen)
|
|
EgtInvertCurve( nCrvId)
|
|
EgtSetInfo( nCrvId, KEY_TYPE, TYPE.RIB)
|
|
EgtSetName( nCrvId, LEAD_IN_CRV)
|
|
return
|
|
end
|
|
|
|
nCrvOffs = EgtGetNext( nCrvOffs)
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------
|
|
local function AddRibsLeadOut( nCrv, nTPathGrp, nLoopsGrp, LayerParams)
|
|
|
|
if abs( LayerParams.dRibsLOLen) < GEO.EPS_SMALL and
|
|
abs( LayerParams.dRibsLOCoasting) < GEO.EPS_SMALL and
|
|
abs( LayerParams.dRibsLOWipe) < GEO.EPS_SMALL then return end
|
|
|
|
local ptE = EgtEP( nCrv)
|
|
-- recupero la curva di offset su cui calcolare lead out
|
|
local nCrvOffs = EgtGetFirstInGroup( nLoopsGrp)
|
|
while nCrvOffs do
|
|
local dParE = EgtCurveParamAtPoint( nCrvOffs, ptE)
|
|
if dParE then
|
|
|
|
local nCrvLO
|
|
local nCoasting
|
|
local nWipe
|
|
local bInvert = false
|
|
|
|
local nCrvRef = EgtCopyGlob( nCrvOffs, nCrv, GDB_IN.AFTER)
|
|
local bClosed = EgtCurveIsClosed( nCrvRef)
|
|
if bClosed then
|
|
EgtChangeClosedCurveStart( nCrvRef, dParE)
|
|
dParE = 0
|
|
end
|
|
|
|
-- scelgo il lato da cui fare uscita
|
|
local _, dEndPar = EgtCurveDomain( nCrvRef)
|
|
-- se ho solo un tratto possibile verifico se va invertito
|
|
if abs( dParE - dEndPar) < GEO.EPS_SMALL then
|
|
EgtInvertCurve( nCrvRef)
|
|
bInvert = true
|
|
elseif abs( dParE) > GEO.EPS_SMALL or bClosed then
|
|
-- se ho più tratti possibili scelgo in base al parametro RibsLOInvert
|
|
bInvert = LayerParams.bRibsLOInvert
|
|
local nNewId = EgtSplitCurveAtParam( nCrvRef, dParE) or EgtCopyGlob( nCrvRef, nCrv, GDB_IN.AFTER)
|
|
if bInvert then
|
|
EgtInvertCurve( nCrvRef)
|
|
EgtErase( nNewId)
|
|
else
|
|
EgtErase( nCrvRef)
|
|
nCrvRef = nNewId
|
|
end
|
|
end
|
|
|
|
local vtE = EgtSV( nCrvRef)
|
|
|
|
-- primo tratto ( segue offset con flusso aperto)
|
|
if LayerParams.dRibsLOLen > GEO.EPS_SMALL then
|
|
nCrvLO = EgtCopyGlob( nCrvRef, nCrv, GDB_IN.AFTER)
|
|
EgtTrimCurveEndAtLen( nCrvLO, LayerParams.dRibsLOLen)
|
|
EgtSetInfo( nCrvLO, KEY_TYPE, TYPE.RIB)
|
|
EgtSetName( nCrvLO, LEAD_OUT_CRV)
|
|
-- aggiorno ptE e vtE
|
|
ptE = EgtEP( nCrvLO)
|
|
vtE = EgtEV( nCrvLO)
|
|
end
|
|
|
|
-- secondo tratto ( segue offset con flusso chiuso)
|
|
if LayerParams.dRibsLOCoasting > GEO.EPS_SMALL then
|
|
nCoasting = EgtCopyGlob( nCrvRef, nCrvLO or nCrv, GDB_IN.AFTER)
|
|
EgtTrimCurveStartAtLen( nCoasting, LayerParams.dRibsLOLen)
|
|
EgtTrimCurveEndAtLen( nCoasting, LayerParams.dRibsLOCoasting)
|
|
|
|
EgtSetName( nCoasting, COASTING_CRV)
|
|
EgtSetInfo( nCoasting, KEY_TYPE, TYPE.COASTING)
|
|
EgtSetColor( nCoasting, EgtStdColor('ORANGE'))
|
|
|
|
-- aggiorno ptE e vtE
|
|
ptE = EgtEP( nCoasting)
|
|
vtE = EgtEV( nCoasting)
|
|
end
|
|
EgtErase( nCrvRef)
|
|
|
|
-- terzo tratto ( diretto verso esterno con ugello chiuso)
|
|
if LayerParams.dRibsLOWipe > GEO.EPS_SMALL then
|
|
local dAng = EgtIf( bInvert, 90, - 90) + LayerParams.dRibsLOWipeAng
|
|
vtE:rotate( LayerParams.vtSlicing, dAng)
|
|
local ptFinal = ptE + vtE * LayerParams.dRibsLOWipe
|
|
nWipe = EgtCurveCompoFromPoints( nTPathGrp, { ptE, ptFinal})
|
|
EgtRelocateGlob( nWipe, nCoasting or nCrvLO or nCrv, GDB_IN.AFTER)
|
|
EgtSetName( nWipe, WIPE_CRV)
|
|
EgtSetInfo( nWipe, KEY_TYPE, TYPE.WIPE)
|
|
EgtSetColor( nWipe, EgtStdColor('TEAL'))
|
|
end
|
|
|
|
return
|
|
end
|
|
|
|
nCrvOffs = EgtGetNext( nCrvOffs)
|
|
end
|
|
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcRibsToolPath( nCrvGrp, nTpathGrpId, LayerParams, dCorrZ)
|
|
|
|
local nRibsGrp = EgtGetFirstNameInGroup( nCrvGrp, RIBS_GRP)
|
|
-- aggiungo le costolature nel toolpath
|
|
local vEntIds = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*')
|
|
for i = 1, #vEntIds do
|
|
-- copio entità nel gruppo toolpath
|
|
local nNewEntId = EgtCopyGlob( vEntIds[i], nTpathGrpId, GDB_IN.LAST_SON)
|
|
-- correggo posizione in Z ( per essere sicuri di appoggiare sul piano)
|
|
EgtMove( nNewEntId, dCorrZ * Z_AX(), GDB_RT.GLOB)
|
|
-- mi sposto dell'altezza layer
|
|
EgtMove( nNewEntId, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
EgtModifyCurveExtrusion( nNewEntId, LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
EgtSetColor( nNewEntId, EgtStdColor('GRAY'))
|
|
end
|
|
|
|
-- estraggo i contorni della superficie di offset
|
|
local nLoopGrp = EgtGroup( nRibsGrp)
|
|
local nSrfId = EgtGetFirstNameInGroup( nRibsGrp, LAYER_SRF)
|
|
local nChunksNbr = EgtSurfFrChunkCount( nSrfId)
|
|
for i = 0, nChunksNbr do
|
|
local nRes, nCnt = EgtExtractSurfFrChunkLoops( nSrfId, i, nLoopGrp)
|
|
if nRes then
|
|
for j = nRes, nRes + nCnt - 1 do
|
|
EgtMove( j, dCorrZ * Z_AX(), GDB_RT.GLOB)
|
|
-- mi sposto dell'altezza layer
|
|
EgtMove( j, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- recupero i gruppi delle costolature
|
|
local tabRibs = {}
|
|
local nFirst = EgtGetFirstNameInGroup( nTpathGrpId, RIBS_CRV .. '*')
|
|
while nFirst do
|
|
local sName = EgtGetName( nFirst)
|
|
local vIds = EgtGetNameInGroup( nTpathGrpId, sName)
|
|
table.insert( tabRibs, vIds)
|
|
nFirst = EgtGetNextName( vIds[#vIds], RIBS_CRV .. '*')
|
|
end
|
|
|
|
-- orientamento delle curve
|
|
local bInvert = LayerParams.bRibsInvert
|
|
for i = 1, #tabRibs do
|
|
-- oriento tutte le passate relative ad una stessa costolatura
|
|
for j = 1, #tabRibs[i] do
|
|
if ( bInvert and j % 2 == 1) or ( not bInvert and j % 2 == 0) then
|
|
EgtInvertCurve( tabRibs[i][j])
|
|
end
|
|
end
|
|
-- aggiorno bInvert per il gruppo di costolature successivo
|
|
if LayerParams.bRibsLink and LayerParams.nRibsShellsNbr % 2 == 1 then
|
|
bInvert = not bInvert
|
|
end
|
|
end
|
|
|
|
-- Link
|
|
-- collego le passate di una stessa costolatura
|
|
for i = 1, #tabRibs do
|
|
for j = 1, #tabRibs[i] - 1 do
|
|
local ptS = EgtEP( tabRibs[i][j])
|
|
local ptE = EgtSP( tabRibs[i][j + 1])
|
|
CalcRibsLink( ptS, ptE, tabRibs[i][j], nLoopGrp, true)
|
|
-- creo link fittizio per eliminare tratto corrispondente sulla curva di offset
|
|
local nFakeLink = CalcRibsLink( EgtSP( tabRibs[i][j]), EgtEP( tabRibs[i][j + 1]), tabRibs[i][j], nLoopGrp, false)
|
|
EgtErase( nFakeLink)
|
|
end
|
|
end
|
|
-- se necessario collego le diverse costolature
|
|
if LayerParams.bRibsLink then
|
|
for i = 1, #tabRibs - 1 do
|
|
local nCnt = #tabRibs[i]
|
|
local ptS = EgtEP( tabRibs[i][nCnt])
|
|
local ptE = EgtSP( tabRibs[i + 1][1])
|
|
CalcRibsLink( ptS, ptE, tabRibs[i][nCnt], nLoopGrp, false)
|
|
end
|
|
end
|
|
|
|
-- leadin/leadout
|
|
local nCrvRib = EgtGetFirstNameInGroup( nTpathGrpId, RIBS_CRV .. '*')
|
|
while nCrvRib do
|
|
-- verifico se necessario lead in
|
|
local nPrev = EgtGetPrev( nCrvRib)
|
|
if not nPrev or EgtGetName( nPrev) then
|
|
AddRibsLeadIn( nCrvRib, nLoopGrp, LayerParams)
|
|
end
|
|
-- verifico se necessario lead out
|
|
local nNext = EgtGetNext( nCrvRib)
|
|
if not nNext or EgtGetName( nNext) then
|
|
AddRibsLeadOut( nCrvRib, nTpathGrpId, nLoopGrp, LayerParams)
|
|
end
|
|
nCrvRib = EgtGetNextName( nCrvRib, RIBS_CRV .. '*')
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function CalcToolPath.Exec( nPartId)
|
|
|
|
s_nPartId = nPartId
|
|
|
|
-- Verifico il pezzo
|
|
if not s_nPartId then
|
|
EgtOutBox( 'Error missing part', 'ToolPathCalc')
|
|
return
|
|
end
|
|
|
|
-- Recupero i layer da processare
|
|
local vLayIds = EgtGetNameInGroup( s_nPartId, SLICE_LAYER.."*")
|
|
if not vLayIds then
|
|
EgtOutBox( 'Error missing slices', 'ToolPathCalc')
|
|
return
|
|
end
|
|
|
|
-- recupero i parametri per calcolo dei toolpath
|
|
local LayerParams = GetLayerParamsForToolPathCalc()
|
|
local dCorrZ = ComputeZCorrection( LayerParams)
|
|
|
|
-- se necessario sposto anche il solido di partenza
|
|
if dCorrZ > 10 * GEO.EPS_SMALL then
|
|
local vtMove = Vector3d( 0, 0, dCorrZ) + LayerParams.dLayHeight / 2 * LayerParams.vtSlicing
|
|
local SolidLayId = EgtGetFirstNameInGroup( s_nPartId, ORIGINAL_SOLID)
|
|
if SolidLayId then
|
|
EgtSetInfo( s_nPartId, KEY_MOVED_PART, vtMove)
|
|
local EntId = EgtGetFirstInGroup( SolidLayId)
|
|
while EntId do
|
|
EgtMove( EntId, vtMove)
|
|
EntId = EgtGetNext( EntId)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- 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
|
|
-- creo il percorso di lavoro :
|
|
-- copio le curve, le ordino, le oriento e le muovo in Z
|
|
local nEntId = EgtGetFirstInGroup( nPathGrpId)
|
|
while nEntId do
|
|
local nNewEntId = EgtCopyGlob( nEntId, nTpathGrpId, EgtIf( LayerParams.nOrder == PRINT_ORDER.INF_INT_EXT, GDB_IN.FIRST_SON, GDB_IN.LAST_SON))
|
|
-- correggo posizione in Z ( per essere sicuri di appoggiare sul piano)
|
|
EgtMove( nNewEntId, dCorrZ * Z_AX(), GDB_RT.GLOB)
|
|
-- mi sposto dell'altezza layer
|
|
EgtMove( nNewEntId, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
if LayerParams.bInvert then
|
|
EgtInvertCurve( nNewEntId)
|
|
end
|
|
EgtModifyCurveExtrusion( nNewEntId, LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
EgtSetColor( nNewEntId, EgtStdColor('GRAY'))
|
|
nEntId = EgtGetNext( nEntId)
|
|
end
|
|
|
|
-- aggiungo gli opportuni raccordi
|
|
local nPrevId = EgtGetFirstInGroup( nTpathGrpId)
|
|
local nCurrId = EgtGetNext( nPrevId or GDB_ID.NULL)
|
|
k = 0
|
|
local nPrevShellNbr
|
|
if nPrevId then nPrevShellNbr = tonumber( EgtGetName( nPrevId):sub(6)) end
|
|
while nCurrId do
|
|
|
|
local nCurrShellNbr = tonumber( EgtGetName( nCurrId):sub(6))
|
|
if nCurrShellNbr ~= nPrevShellNbr then k = k + 1 end
|
|
|
|
-- se nessun raccordo modifico solo lo start point della curva
|
|
if LayerParams.nLinkType == LINK_TYPE.NONE then
|
|
local dLen = k * LayerParams.dSPOffs
|
|
if LayerParams.dSPOffs < 0 then
|
|
dLen = EgtCurveLength( nCurrId) + dLen
|
|
end
|
|
local dPar = EgtCurveParamAtLength( nCurrId, dLen)
|
|
if dPar then EgtChangeClosedCurveStart( nCurrId, dPar) end
|
|
|
|
else
|
|
-- altrimenti verifico se ha senso creare raccordo
|
|
if abs( dist( EgtEP( nPrevId), EgtSP( nCurrId))) < LayerParams.dStrand + 10 then
|
|
local nLinkId
|
|
if k > 1 then
|
|
-- modifico lo start point
|
|
local dLen = EgtCurveLength( nPrevId) - abs( LayerParams.dSPOffs)
|
|
EgtTrimCurveEndAtLen( nPrevId, dLen)
|
|
EgtChangeClosedCurveStartPoint( nCurrId, EgtEP( nPrevId))
|
|
end
|
|
-- aggiungo il raccordo
|
|
EgtTrimCurveEndAtLen( nPrevId, EgtCurveLength( nPrevId) - LayerParams.dLinkParam / 2)
|
|
EgtTrimCurveStartAtLen( nCurrId, LayerParams.dLinkParam / 2)
|
|
if LayerParams.nLinkType == LINK_TYPE.LINEAR then
|
|
nLinkId = EgtCurveCompoFromPoints( nTpathGrpId, {EgtEP( nPrevId), EgtSP( nCurrId)})
|
|
elseif LayerParams.nLinkType == LINK_TYPE.BIARC then
|
|
local frLoc = Frame3d( ORIG(), LayerParams.vtSlicing)
|
|
local nGrpTmp = EgtGroup( nTpathGrpId, frLoc)
|
|
local _, _, dAngIni = SphericalFromVector( EgtEV( nPrevId, nGrpTmp))
|
|
local _, _, dAngFin = SphericalFromVector( EgtSV( nCurrId, nGrpTmp))
|
|
nLinkId = EgtBiArc( nGrpTmp, EgtEP( nPrevId, nGrpTmp), EgtSP( nCurrId, nGrpTmp), dAngIni, dAngFin, 0.5)
|
|
EgtRelocateGlob( nLinkId, nTpathGrpId, GDB_IN.LAST_SON)
|
|
EgtErase( nGrpTmp)
|
|
end
|
|
|
|
if nLinkId then
|
|
EgtRelocate( nLinkId, nCurrId, GDB_IN.BEFORE)
|
|
EgtModifyCurveExtrusion( nLinkId, LayerParams.vtSlicing, GDB_RT.GLOB)
|
|
EgtSetInfo( nLinkId, KEY_TYPE, TYPE.LINK)
|
|
end
|
|
end
|
|
end
|
|
|
|
nPrevShellNbr = nCurrShellNbr
|
|
nPrevId = nCurrId
|
|
nCurrId = EgtGetNext( nCurrId)
|
|
end
|
|
|
|
-- aggiungo leadin/leadout
|
|
local nFirstCurve = EgtGetFirstInGroup( nTpathGrpId)
|
|
if nFirstCurve and LayerParams.nLeadInType ~= LEAD_TYPE.NONE then
|
|
EgtTrimCurveStartAtLen( nFirstCurve, LayerParams.dOffsetLP)
|
|
AddLeadIn( nFirstCurve, LayerParams, nTpathGrpId)
|
|
end
|
|
local nLastCurve = EgtGetLastInGroup( nTpathGrpId)
|
|
if nLastCurve and LayerParams.nLeadOutType ~= LEAD_TYPE.NONE then
|
|
EgtTrimCurveEndAtLen( nLastCurve, EgtCurveLength( nLastCurve) - LayerParams.dOffsetLP)
|
|
AddLeadOut( nLastCurve, LayerParams, nTpathGrpId)
|
|
end
|
|
|
|
-- aggiungo coasting/wipe
|
|
local nId = EgtGetFirstNameInGroup( nTpathGrpId, SHELL_CRV .. "*")
|
|
local nFirstId = nId
|
|
local nLastId = EgtGetLastNameInGroup( nTpathGrpId, SHELL_CRV .. "*")
|
|
while nId do
|
|
if nId == nLastId then
|
|
AddRetractionOnLastCrv( nTpathGrpId, LayerParams)
|
|
else
|
|
local nNextId = EgtGetNext( nId)
|
|
if EgtGetInfo( nNextId, KEY_TYPE, 'i') ~= TYPE.LINK then
|
|
-- aggiungo retrazione
|
|
if nId == nFirstId then
|
|
local dWipeLen = EgtIf( LayerParams.nLeadInType == LEAD_TYPE.NONE, LayerParams.dWipeLen, 0)
|
|
AddRetraction( nId, LayerParams.dCoastingLen, dWipeLen)
|
|
else
|
|
AddRetraction( nId, LayerParams.dCoastingLen, LayerParams.dWipeLen)
|
|
end
|
|
end
|
|
end
|
|
nId = EgtGetNextName( nId, SHELL_CRV .. "*")
|
|
end
|
|
|
|
-- sistemo le costolature
|
|
local nRibsGrp = EgtGetFirstNameInGroup( nCrvGrpId, RIBS_GRP)
|
|
if nRibsGrp then
|
|
CalcRibsToolPath( nCrvGrpId, nTpathGrpId, LayerParams, dCorrZ)
|
|
end
|
|
|
|
--passo al gruppo di contorni successivo
|
|
nCrvGrpId = EgtGetNextName( nCrvGrpId, CONTOUR_GRP.."*")
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return CalcToolPath
|