3dPrinting:

- sistemato spiral vase completo nel caso multiplanare
- sistemata correzione in z per caso multiplanare
- migliorie varie nei solidi
- gestione multicolore per solidi con strand semplificato.
This commit is contained in:
SaraP
2026-03-02 09:29:44 +01:00
parent 07b9a60a25
commit 5ad54c18f1
3 changed files with 721 additions and 200 deletions
+361 -109
View File
@@ -70,55 +70,98 @@ local function GetLayerParamsForToolPathCalc()
end
------------------------------------------------------------------
local function ComputeToolPathBox( nTpathGrpId)
-- calcolo il box del toolpath (escludendo i wipe)
local function ComputeToolPathBox( nLayerId)
-- calcolo il box di tutti i toolpath del layer 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)
local vCrvGrpIds = EgtGetNameInGroup( nLayerId, CONTOUR_GRP .. '*')
for i = 1, #vCrvGrpIds do
-- recupero tutti gli elementi del toolpath
local nTPathGrpId = EgtGetFirstNameInGroup( vCrvGrpIds[i], TOOLPATH_GRP)
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
nEntId = EgtGetNext( nEntId)
end
return b3Box
end
------------------------------------------------------------------
local function AddZCorrection( b3Box, LayerParams)
-- nel caso multiplanare non è necessaria alcuna correzione
local function AddZCorrection( LayerParams)
local vLayIds = EgtGetNameInGroup( s_nPartId, SLICE_LAYER.."*")
local nSlicingType = EgtGetInfo( s_nPartId, KEY_SLICING_TYPE, 'i')
-- 1) correzione per il pezzo
local dHBox = EgtGetInfo( s_nPartId, KEY_BOX_MIN_Z, 'i') or 0
local dCorrZ = 0
-- se slicing multiplanare vtSlicing cambia ad ogni layer quindi la correzione deve essere calcolata sul singolo layer
if nSlicingType == SLICING_TYPE.MULTIPLANAR then
return
for i = 1, #vLayIds do
-- calcolo i valori legati a vtSlicing per il layer corrente
local vtSlicing = EgtGetInfo( vLayIds[i], KEY_SLICE_DIR, 'v')
local dNxy = sqrt( vtSlicing:getX() * vtSlicing:getX() + vtSlicing:getY() * vtSlicing:getY())
local dNz = vtSlicing:getZ()
-- altezza necessaria per lo strand non serve perchè l'altezza viene adattata lungo il percorso
-- altezza necessaria per il tool
local dHTool = LayerParams.dTDiam / 2 * dNxy
-- altezza disponibile
local b3Layer = ComputeToolPathBox( vLayIds[i])
local dHDisp = b3Layer:getMin():getZ() - max( dHBox, 0)
local dCurrCorrZ = max( 0, dHTool - dHDisp)
dCorrZ = max( dCorrZ, dCurrCorrZ)
end
-- se slicing standard la correzione può essere calcolata sull'intero pezzo
else
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
-- calcolo il box complessivo dei percorsi
local b3Tot = BBox3d()
for i = 1, #vLayIds do
local b3Curr = ComputeToolPathBox( vLayIds[i])
b3Tot:Add( b3Curr)
end
local dHDisp = b3Tot:getMin():getZ() - max( dHBox, 0)
dCorrZ = max( 0, max( dHStrand, dHTool) - dHDisp)
end
-- applico la correzione al pezzo
if dCorrZ > GEO.EPS_SMALL then
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 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() - max( dHBox, 0)
-- 2) correzione per i wipe
-- altezza minima necessaria per i wipe. Se slicing multiplanare l'altezza minima per il wipe cambia ad ogni layer, altrimenti è un valore comune
local dHMinWipe
if nSlicingType ~= SLICING_TYPE.MULTIPLANAR then
local dNxy = sqrt( LayerParams.vtSlicing:getX() * LayerParams.vtSlicing:getX() + LayerParams.vtSlicing:getY() * LayerParams.vtSlicing:getY())
dHMinWipe = LayerParams.dTDiam / 2 * dNxy + max( dHBox, 0) + s_dHSafeWipe
end
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)
-- correzione per i wipe
-- altezza minima necessaria per i wipe
local dHMinWipe = LayerParams.dTDiam / 2 * dNxy + max( dHBox, 0) + s_dHSafeWipe
local vLayIds = EgtGetNameInGroup( s_nPartId, SLICE_LAYER.."*")
for i = 1, #vLayIds do
if nSlicingType == SLICING_TYPE.MULTIPLANAR then
local vtSlicing = EgtGetInfo( vLayIds[i], KEY_SLICE_DIR, 'v')
local dNxy = sqrt( vtSlicing:getX() * vtSlicing:getX() + vtSlicing:getY() * vtSlicing:getY())
dHMinWipe = LayerParams.dTDiam / 2 * dNxy + max( dHBox, 0) + s_dHSafeWipe
end
local vCrvGrps = EgtGetNameInGroup( vLayIds[i], CONTOUR_GRP.."*")
for j = 1, #vCrvGrps do
local nTPath = EgtGetFirstNameInGroup( vCrvGrps[j], TOOLPATH_GRP)
@@ -369,6 +412,7 @@ end
--------------------------------------------------------------------
local function AddLeadOut( nCrvId, LayerParams, nGrpId)
local vtSlicing = EgtCurveExtrusion( nCrvId, GDB_ID.ROOT)
local ptS = EgtEP( nCrvId, GDB_ID.ROOT)
local vtTang = EgtEV( nCrvId, GDB_ID.ROOT)
local vtOrtho = Vector3d( vtTang)
@@ -378,7 +422,7 @@ local function AddLeadOut( nCrvId, LayerParams, nGrpId)
dAng = 90
end
vtOrtho:rotate( LayerParams.vtSlicing, dAng)
vtOrtho:rotate( vtSlicing, dAng)
local ptE = ptS + LayerParams.dLeadOutTangDist * vtTang + LayerParams.dLeadOutOrthoDist * vtOrtho
local nLeadOutCrv
@@ -390,7 +434,7 @@ local function AddLeadOut( nCrvId, LayerParams, nGrpId)
if nLeadOutCrv then
EgtRelocate( nLeadOutCrv, nCrvId, GDB_IN.AFTER)
EgtModifyCurveExtrusion( nLeadOutCrv, LayerParams.vtSlicing, GDB_RT.GLOB)
EgtModifyCurveExtrusion( nLeadOutCrv, vtSlicing, GDB_RT.GLOB)
EgtSetInfo( nLeadOutCrv, KEY_TYPE, TYPE.LINK)
EgtSetName( nLeadOutCrv, LEAD_OUT_CRV)
EgtSetColor( nLeadOutCrv, EgtStdColor('GRAY'))
@@ -2020,19 +2064,284 @@ local function AddSpiralVaseLeadOut( nOldId, LayerParams)
end
end
---------------------------------------------------------------------
local function SpiralVaseFullMultiPlanar( vLayIds, LayerParams)
-- la differenza in altezza viene distribuita uniformemente lungo tutto il percorso. Tale differenza non è costante per tutti i punti della curva ma varia da punto a punto
-- la continuità tra i layers viene risolta sul layer corrente ( uniformemente su tutto il tratto o solo nella parte iniziale di lunghezza dSpiralVaseInterpLen)
-- gestione speciale per i primi due layers
-- aggiunta passata extra finale piana alla quota dell'ultimo layer
local nOldId, nOldPathId
local nRealLayer = 1
-- ciclo sui layer
for nIdx = 1, #vLayIds do
-- recupero il piano di slicing
local vtSlicing = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_DIR, 'v')
local ptSlicing = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_POS, 'p')
-- cerco i gruppi di contorni
local vCrvGrpIds = EgtGetNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*")
if #vCrvGrpIds > 1 then
-- se più di un gruppo di curve errore
EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nIdx) .. ' has more than one toolpath', 'ToolPathCalc')
return false
end
-- recupero il gruppo dei percorsi
local nPathGrpId = EgtGetFirstNameInGroup( vCrvGrpIds[1], 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[1], TOOLPATH_GRP)
if not nTpathGrpId then
nTpathGrpId = EgtGroup( vCrvGrpIds[1])
EgtSetName( nTpathGrpId, TOOLPATH_GRP)
else
EgtEmptyGroup( nTpathGrpId)
end
-- creo il percorso di lavoro :
local vEntIds = EgtGetAllInGroup( nPathGrpId)
if #vEntIds > 1 then
EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nIdx) .. ' has more than one toolpath', 'ToolPathCalc')
return false
end
local nNewEntId = EgtCopyGlob( vEntIds[1] or GDB_ID.NULL, nTpathGrpId, GDB_IN.LAST_SON)
if nNewEntId then
EgtModifyCurveExtrusion( nNewEntId, vtSlicing, GDB_RT.GLOB)
EgtSetInfo( nNewEntId, KEY_CRV_STRAND, LayerParams.dStrand)
-- eventuale inversione
if LayerParams.bInvert then
EgtInvertCurve( nNewEntId)
EgtSetInfo( nNewEntId, KEY_INVERTED_CRV, 1)
end
EgtSetColor( nNewEntId, EgtStdColor('GRAY'))
-- se primo layer
if nRealLayer == 1 then
-- mi sposto dell'altezza layer
EgtMove( nNewEntId, LayerParams.dLayHeight * vtSlicing, GDB_RT.GLOB)
-- eventuale lead in
if LayerParams.nLeadInType ~= LEAD_TYPE.NONE then
EgtTrimCurveStartAtLen( nNewEntId, LayerParams.dOffsetLP)
local nLeadInCrv = AddLeadIn( nNewEntId, LayerParams, nTpathGrpId)
if nLeadInCrv and LayerParams.bLinearApprox then
EgtApproxCurve( nLeadInCrv, GDB_CA.LINES, LayerParams.dLinearApproxTol)
end
end
else
-- recupero il piano precedente
local vtSlicingPrev = EgtGetInfo( vLayIds[nIdx-1], KEY_SLICE_DIR, 'v')
local ptSlicingPrev = EgtGetInfo( vLayIds[nIdx-1], KEY_SLICE_POS, 'p') + LayerParams.dLayHeight * vtSlicingPrev
local dCosAng = vtSlicing * vtSlicingPrev
-- a) continuità dei percorsi
local ptEPrev = EgtEP( nOldId, GDB_ID.ROOT)
local ptEProj = ptEPrev - ( ptEPrev - ptSlicing) * vtSlicing * vtSlicing
-- tento di creare la continuità spostando il punto ( caso in cui ptEProj poggia su nNewEntId)
EgtChangeClosedCurveStartPoint( nNewEntId, ptEProj, GDB_RT.GLOB)
if not AreSamePointApprox( ptEPrev, EgtSP( nNewEntId, GDB_ID.ROOT)) then
-- se i percorsi non sono in continuità modifico percorso corrente usando come guida la proiezione ortogonale del percorso precedente
-- sul piano corrente ( SpiralizeAlongGuide lavora con curve piane complanari)
local nProjCrv = EgtCopyGlob( nOldPathId, nPathGrpId)
if LayerParams.bInvert then
EgtInvertCurve( nProjCrv)
end
EgtMove( nProjCrv, LayerParams.dLayHeight * vtSlicingPrev, GDB_RT.GLOB)
EgtProjectCurveOnPlane( nProjCrv, ptSlicing, vtSlicing, GDB_RT.GLOB)
EgtChangeClosedCurveStartPoint( nProjCrv, ptEProj, GDB_RT.GLOB)
-- approssimo con tratti lineari imponendo lunghezza massima per migliorare spiralize
EgtApproxCurve( nProjCrv, GDB_CA.SPECIAL_LINES, 0.01, s_dSpiralVaseMaxLen)
EgtApproxCurve( nNewEntId, GDB_CA.SPECIAL_LINES, 0.01, s_dSpiralVaseMaxLen)
-- 1) la differenza va distribuita su tutta la curva
local dLen = EgtCurveLength( nNewEntId)
if LayerParams.dSpiralVaseInterpLen < GEO.EPS_SMALL or LayerParams.dSpiralVaseInterpLen > dLen - GEO.EPS_SMALL then
EgtSpiralizeCurveAlongGuide( nNewEntId, nProjCrv)
-- 2) la differenza va distribuita solo su un sottotratto
else
local dParSplit = EgtCurveParamAtLength( nNewEntId, LayerParams.dSpiralVaseInterpLen)
local nNewEndId2 = EgtSplitCurveAtParam( nNewEntId, dParSplit)
-- trim della curva guida
local _, _, dParMinDist = EgtPointCurveDist( EgtEP( nNewEntId, GDB_ID.ROOT), nProjCrv, GDB_RT.GLOB)
local nGuideId2 = EgtSplitCurveAtParam( nProjCrv, dParMinDist)
EgtErase( nGuideId2)
-- spiralize solo del primo pezzo e riassemblo la curva
EgtSpiralizeCurveAlongGuide( nNewEntId, nProjCrv)
EgtAddCurveCompoCurve( nNewEntId, nNewEndId2)
end
-- forzo il punto
EgtModifyCurveStartPoint( nNewEntId, ptEProj, GDB_RT.GLOB)
EgtErase( nProjCrv)
end
-- b) spostamento verticale : alzo la curva e, per creare una transizione uniforme dal layer precedente, abbasso i suoi punti in modo graduale sul valore della distanza dal
-- dal layer precedente
EgtMove( nNewEntId, LayerParams.dLayHeight * vtSlicing, GDB_RT.GLOB)
-- approssimazione lineare per migliorare il calcolo delle quote
EgtApproxCurve( nNewEntId, GDB_CA.SPECIAL_LINES, 0.01, s_dSpiralVaseMaxLen)
if nRealLayer == 2 then
-- per non collassare sul layer precedente che è piatto alzo la prima metà della curva sempre di 0.5 * Delta
local dLen = EgtCurveLength( nNewEntId)
local dParMid = EgtCurveParamAtLength( nNewEntId, 0.5 * dLen)
EgtAddCurveCompoJoint( nNewEntId, dParMid)
local vDelta = {}
local _, dE = EgtCurveDomain( nNewEntId)
for dU = 0, dE - 1 do
local ptCurr = EgtUP( nNewEntId, dU, GDB_ID.ROOT)
local dDist = ( ( ptCurr - ptSlicingPrev) * vtSlicingPrev) / dCosAng -- distanza dal piano precedente lungo vtSlicing
local dCurrLen = EgtCurveLengthAtParam( nNewEntId, dU)
if dCurrLen < 0.5 * dLen then
vDelta[dU] = - dDist * 0.5
else
vDelta[dU] = - dDist * ( dLen - dCurrLen) / dLen
end
end
EgtModifyCurveStartPoint( nNewEntId, EgtSP( nNewEntId, GDB_ID.ROOT) + vDelta[0] * vtSlicing, GDB_RT.GLOB)
for dU = 1, dE - 1 do
local ptCurr = EgtUP( nNewEntId, dU, GDB_ID.ROOT)
EgtModifyCurveCompoJoint( nNewEntId, dU, ptCurr + vDelta[dU] * vtSlicing, GDB_RT.GLOB)
end
-- alzo l'ultimo tratto del layer precedente con una proiezione ortogonale "graduale" sul piano corrente
-- ricavo il tratto sulla curva precedente da alzare
local dTrimPar = EgtCurveParamAtLength( nOldId, EgtCurveLength( nOldId) - s_dSpralVaseFirstDelta)
local nLastId = EgtSplitCurveAtParam( nOldId, dTrimPar)
EgtApproxCurve( nLastId, GDB_CA.SPECIAL_LINES, 0.01, s_dSpiralVaseMaxLen)
-- alzo in maniera graduale
local _, dEOld = EgtCurveDomain( nLastId)
local vDeltaOld = {}
local dLenOld = EgtCurveLength( nLastId)
for dU = 0, dEOld do
local dCurrLen = EgtCurveLengthAtParam( nLastId, dU)
vDeltaOld[dU] = abs( vDelta[0]) * dCurrLen / dLenOld
end
for dU = 0, dEOld - 1 do
local ptCurr = EgtUP( nLastId, dU, GDB_ID.ROOT)
EgtModifyCurveCompoJoint( nLastId, dU, ptCurr + vDeltaOld[dU] * vtSlicing, GDB_RT.GLOB)
end
EgtModifyCurveEndPoint( nLastId, EgtEP( nLastId, GDB_ID.ROOT) + vDeltaOld[dEOld] * vtSlicing, GDB_RT.GLOB)
-- approssimo
EgtApproxCurve( nLastId, GDB_CA.ARCS, s_dApproxTol)
if LayerParams.bLinearApprox then
EgtApproxCurve( nLastId, GDB_CA.LINES, LayerParams.dLinearApproxTol)
end
EgtModifyCurveEndPoint( nLastId, EgtSP( nNewEntId, GDB_ID.ROOT), GDB_RT.GLOB)
else
local dLen = EgtCurveLength( nNewEntId)
local _, dE = EgtCurveDomain( nNewEntId)
local vDelta = {}
for dU = 0, dE - 1 do
local dCurrLen = EgtCurveLengthAtParam( nNewEntId, dU)
local ptCurr = EgtUP( nNewEntId, dU, GDB_ID.ROOT)
local dDist = ( ( ptCurr - ptSlicingPrev) * vtSlicingPrev) / dCosAng -- distanza dal piano precedente lungo vtSlicing
vDelta[dU] = - dDist * ( dLen - dCurrLen) / dLen
end
EgtModifyCurveStartPoint( nNewEntId, EgtSP( nNewEntId, GDB_ID.ROOT) + vDelta[0] * vtSlicing, GDB_RT.GLOB)
for dU = 1, dE - 1 do
local ptCurr = EgtUP( nNewEntId, dU, GDB_ID.ROOT)
EgtModifyCurveCompoJoint( nNewEntId, dU, ptCurr + vDelta[dU] * vtSlicing, GDB_RT.GLOB)
end
end
-- c) approssimo
local ptS = EgtSP( nNewEntId, GDB_ID.ROOT)
EgtApproxCurve( nNewEntId, GDB_CA.ARCS, s_dApproxTol)
if LayerParams.bLinearApprox then
EgtApproxCurve( nNewEntId, GDB_CA.LINES, LayerParams.dLinearApproxTol)
end
if EgtCurveIsClosed( nNewEntId) then
EgtChangeClosedCurveStartPoint( nNewEntId, ptS, GDB_RT.GLOB)
end
end
local vTPathsCrvs = EgtGetAllInGroup( nTpathGrpId)
nOldId = vTPathsCrvs[#vTPathsCrvs]
nOldPathId = vEntIds[1]
nRealLayer = nRealLayer + 1
end
if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / #vLayIds * 100, 0) == 1 then
EgtDraw()
return false
end
end
-- creo un un layer extra piano alla quota finale
local nLastLay = EgtCopyGlob( vLayIds[#vLayIds], vLayIds[#vLayIds], GDB_IN.AFTER)
-- aggiorno nome e numero slice
local nSliceNbr = EgtGetInfo( nLastLay, KEY_SLICE_NBR, 'i') + 1
EgtSetName( nLastLay, SLICE_LAYER .. EgtNumToString( nSliceNbr))
EgtSetInfo( nLastLay, KEY_SLICE_NBR, nSliceNbr)
-- creo la curva di toolpath alla quota finale
local nCrvGrpId = EgtGetFirstNameInGroup( nLastLay, CONTOUR_GRP.."*")
local nPathGrpId = EgtGetFirstNameInGroup( nCrvGrpId, PATH_GRP)
local nTpathGrpId = EgtGetFirstNameInGroup( nCrvGrpId, TOOLPATH_GRP)
EgtEmptyGroup( nTpathGrpId)
local nId = EgtCopyGlob( EgtGetFirstInGroup( nPathGrpId), nTpathGrpId)
local vtSlicing = EgtGetInfo( nLastLay, KEY_SLICE_DIR, 'v')
EgtMove( nId, LayerParams.dLayHeight * vtSlicing, GDB_RT.GLOB)
local ptS = EgtEP( nOldId, GDB_ID.ROOT)
EgtChangeClosedCurveStartPoint( nId, ptS, GDB_RT.GLOB)
EgtModifyCurveExtrusion( nId, vtSlicing, GDB_RT.GLOB)
EgtSetInfo( nId, KEY_CRV_STRAND, LayerParams.dStrand)
if LayerParams.bInvert then
EgtInvertCurve( nId)
EgtSetInfo( nId, KEY_INVERTED_CRV, 1)
end
EgtSetColor( nId, EgtStdColor('GRAY'))
-- approssimo
EgtApproxCurve( nId, GDB_CA.ARCS, s_dApproxTol)
if LayerParams.bLinearApprox then
EgtApproxCurve( nId, GDB_CA.LINES, LayerParams.dLinearApproxTol)
end
if EgtCurveIsClosed( nId) then
EgtChangeClosedCurveStartPoint( nId, ptS, GDB_RT.GLOB)
end
return true
end
---------------------------------------------------------------------
local function SpiralVaseFull( vLayIds, LayerParams)
-- la differenza in altezza tra due layers viene distribuita uniformemente lungo tutto il percorso
-- la continuità tra i layers viene risolta sul layer corrente ( uniformemente su tutto il tratto o solo nella parte iniziale di lunghezza dSpiralVaseInterpLen)
-- gestione speciale dei primi layers per gestione dell'altezza e feed
-- nel caso di slicing multiplanare viene realizzato un layer extra ( uguale all'ultimo) alla quota finale del pezzo
local nSlicingType = EgtGetInfo( s_nPartId, KEY_SLICING_TYPE, 'i')
if nSlicingType == SLICING_TYPE.MULTIPLANAR then
return SpiralVaseFullMultiPlanar( vLayIds, LayerParams)
end
local nOldId, nOldPathId
local nRealLayer = 1
local nSlicingType = EgtGetInfo( s_nPartId, KEY_SLICING_TYPE, 'i')
-- copio ultimo layer
if nSlicingType ~= SLICING_TYPE.MULTIPLANAR and nSlicingType ~= SLICING_TYPE.DEG45_X and nSlicingType ~= SLICING_TYPE.DEG45_Y then
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)
-- aggiorno nome e numero slice
@@ -2049,10 +2358,6 @@ local function SpiralVaseFull( vLayIds, LayerParams)
-- ciclo sui layer
for nIdx = 1, #vLayIds do
if nSlicingType == SLICING_TYPE.MULTIPLANAR then
LayerParams.vtSlicing = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_DIR, 'v')
end
-- cerco i gruppi di contorni
local vCrvGrpIds = EgtGetNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*")
if #vCrvGrpIds > 1 then
@@ -2246,42 +2551,6 @@ local function SpiralVaseFull( vLayIds, LayerParams)
return false
end
end
-- se slicing multiplanare creo un un layer extra piano alla quota finale
if nSlicingType == SLICING_TYPE.MULTIPLANAR then
local nLastLay = EgtCopyGlob( vLayIds[#vLayIds], vLayIds[#vLayIds], GDB_IN.AFTER)
-- aggiorno nome e numero slice
local nSliceNbr = EgtGetInfo( nLastLay, KEY_SLICE_NBR, 'i') + 1
EgtSetName( nLastLay, SLICE_LAYER .. EgtNumToString( nSliceNbr))
EgtSetInfo( nLastLay, KEY_SLICE_NBR, nSliceNbr)
-- creo la curva di toolpath alla quota finale
local nCrvGrpId = EgtGetFirstNameInGroup( nLastLay, CONTOUR_GRP.."*")
local nPathGrpId = EgtGetFirstNameInGroup( nCrvGrpId, PATH_GRP)
local nTpathGrpId = EgtGetFirstNameInGroup( nCrvGrpId, TOOLPATH_GRP)
EgtEmptyGroup( nTpathGrpId)
local nId = EgtCopyGlob( EgtGetFirstInGroup( nPathGrpId), nTpathGrpId)
local vtSlicing = EgtGetInfo( nLastLay, KEY_SLICE_DIR, 'v')
EgtMove( nId, LayerParams.dLayHeight * vtSlicing, GDB_RT.GLOB)
local ptS = EgtEP( nOldId, GDB_ID.ROOT)
EgtChangeClosedCurveStartPoint( nId, ptS, GDB_RT.GLOB)
EgtModifyCurveExtrusion( nId, LayerParams.vtSlicing, GDB_RT.GLOB)
EgtSetInfo( nId, KEY_CRV_STRAND, LayerParams.dStrand)
if LayerParams.bInvert then
EgtInvertCurve( nId)
EgtSetInfo( nId, KEY_INVERTED_CRV, 1)
end
EgtSetColor( nId, EgtStdColor('GRAY'))
-- approssimo
EgtApproxCurve( nId, GDB_CA.ARCS, s_dApproxTol)
if LayerParams.bLinearApprox then
EgtApproxCurve( nId, GDB_CA.LINES, LayerParams.dLinearApproxTol)
end
if EgtCurveIsClosed( nId) then
EgtChangeClosedCurveStartPoint( nId, ptS, GDB_RT.GLOB)
end
end
return true
end
@@ -2364,10 +2633,10 @@ local function SpiralVasePartialMultiPlanar( vLayIds, LayerParams)
local ptSProj = ptSOld + ( ( ptSOld - ptSlicing) * vtSlicing) * vtSlicing
local ptEProj = ptEOld + ( ( ptEOld - ptSlicing) * vtSlicing) * vtSlicing
-- a) continuità tra i layers
-- modifico il punto iniziale corrente per avvicinarmi il più possibile alla fine del percorso precedente
EgtChangeClosedCurveStartPoint( nNewEntId, ptEProj, GDB_RT.GLOB)
local ptCurrStart = EgtSP( nNewEntId, GDB_ID.ROOT)
-- a) verifico continuità tra i layers
if not AreSamePointApprox( ptEProj, ptCurrStart) then
-- se i percorsi non sono in continuità modifico il tratto finale del percorso precedente in modo da farlo arrivare sul punto di inizio del percorso corrente
-- usando come guida la proiezione obliqua del percorso corrente sul piano precedente ( SpiralizeAlongGuide lavora con curve piane complanari)
@@ -2389,16 +2658,16 @@ local function SpiralVasePartialMultiPlanar( vLayIds, LayerParams)
local dDist = ( pt - ptSlicingPrev) * vtSlicingPrev / ( vtSlicingPrev * vtSlicing)
EgtModifyCurveCompoJoint( nProjCrv, dU, pt - dDist * vtSlicing, GDB_RT.GLOB)
end
-- approssimazione dei tratti per migliorare la qualità dello spiralize
EgtApproxCurve( nProjCrv, GDB_CA.SPECIAL_LINES, 0.01, s_dSpiralVaseMaxLen)
EgtApproxCurve( nOldId, GDB_CA.SPECIAL_LINES, 0.01, s_dSpiralVaseMaxLen)
-- spiralize
EgtInvertCurve( nProjCrv)
EgtInvertCurve( nOldId)
EgtSpiralizeCurveAlongGuide( nOldId, nProjCrv)
EgtInvertCurve( nOldId)
EgtErase( nProjCrv)
end
-- b) proiezione ortogonale graduale sul piano corrente
@@ -2499,11 +2768,7 @@ local function SpiralVasePartial( vLayIds, LayerParams)
-- ciclo sui layer
local nOldId
for nIdx = 1, #vLayIds do
-- if nSlicingType == SLICING_TYPE.MULTIPLANAR then
-- LayerParams.vtSlicing = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_DIR, 'v')
-- end
-- cerco i gruppi di contorni
local vCrvGrpIds = EgtGetNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*")
if #vCrvGrpIds > 1 then
@@ -2654,24 +2919,16 @@ local function SpiralVase( vLayIds, LayerParams)
return false
end
end
-- calcolo il box dei percorsi
local b3Tot = BBox3d()
local nLastTPath
local vLayers = EgtGetNameInGroup( s_nPartId, SLICE_LAYER .. '*')
for i = 1, #vLayers do
local vCrvGrpIds = EgtGetNameInGroup( vLayers[i], CONTOUR_GRP.."*")
local nTpathGrpId = EgtGetFirstNameInGroup( vCrvGrpIds[1], TOOLPATH_GRP)
nLastTPath = EgtGetLastInGroup( nTpathGrpId)
local b3Box = ComputeToolPathBox( nTpathGrpId)
b3Tot:Add( b3Box)
end
-- aggiungo uscita, coasting e wipe su ultima curva
local nLastLayer = EgtGetLastNameInGroup( s_nPartId, SLICE_LAYER .. '*')
local vCrvGrpIds = EgtGetNameInGroup( nLastLayer, CONTOUR_GRP.."*")
local nTpathGrpId = EgtGetFirstNameInGroup( vCrvGrpIds[1], TOOLPATH_GRP)
local nLastTPath = EgtGetLastInGroup( nTpathGrpId)
AddSpiralVaseLeadOut( nLastTPath, LayerParams)
-- correzione in z
AddZCorrection( b3Tot, LayerParams)
AddZCorrection( LayerParams)
return true
end
@@ -2697,7 +2954,6 @@ function CalcToolPath.Exec( nPartId)
return SpiralVase( vLayIds, LayerParams)
end
local b3Tot = BBox3d() -- box dei toolpath
local nLayCnt = 1
-- Ciclo sui layer
for nIdx = 1, #vLayIds do
@@ -2783,10 +3039,6 @@ function CalcToolPath.Exec( nPartId)
end
end
-- aggiorno il box dei toolpath
local b3Box = ComputeToolPathBox( nTpathGrpId)
b3Tot:Add( b3Box)
-- verifico non sia vuoto per aggiornare il numero di layers
if EgtGetFirstInGroup( nTpathGrpId) then
nLayCnt = nIdx
@@ -2812,7 +3064,7 @@ function CalcToolPath.Exec( nPartId)
end
-- correzione in z
AddZCorrection( b3Tot, LayerParams)
AddZCorrection( LayerParams)
-- setto info con numero di layers effettivi
EgtSetInfo( nPartId, KEY_LAYER_CNT, nLayCnt)