3dPrinting :

- sistemato spiral vase con transizione nel caso multiplanare
- calcolo solidi nel caso multiplanare ( standard e spiral vase con transizione)
- sistemato esportatore icrx per multiplanar.
This commit is contained in:
SaraP
2026-02-20 11:35:00 +01:00
parent cad4045171
commit 33048785f9
3 changed files with 427 additions and 58 deletions
+207 -17
View File
@@ -401,9 +401,10 @@ local function AddLeadOut( nCrvId, LayerParams, nGrpId)
end
--------------------------------------------------------------------
local function AddRetraction( nCrvId, vtSlicing, dCoastingLen, dWipeLen, dWipeDir)
local function AddRetraction( nCrvId, dCoastingLen, dWipeLen, dWipeDir)
-- recupero i parametri per retrazione
local vtSlicing = EgtCurveExtrusion( nCrvId, GDB_ID.ROOT)
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
@@ -534,22 +535,22 @@ end
local function AddRetractionOnLastCrv( nCrvId, nTpathGrpId, LayerParams, dCoastingLen, dWipeLen, dWipeDir)
if LayerParams.nLeadOutType == LEAD_TYPE.NONE then
AddRetraction( nCrvId, LayerParams.vtSlicing, dCoastingLen, dWipeLen, dWipeDir)
AddRetraction( nCrvId, 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)
AddRetraction( nLeadOutId, dNewCoastingLen, dWipeLen, dWipeDir)
else
-- coinvolge parte dell'ultima shell crv
local dNewCoastingLen = dCoastingLen - dLen
local nCoastingId = AddRetraction( nCrvId, LayerParams.vtSlicing, dNewCoastingLen, 0.0, dWipeDir)
local nCoastingId = AddRetraction( nCrvId, dNewCoastingLen, 0.0, dWipeDir)
EgtAddCurveCompoCurve( nCoastingId, nLeadOutId)
EgtSetInfo( nCoastingId, KEY_CLOSED_CRV, 0)
-- wipe
AddRetraction( nCoastingId, LayerParams.vtSlicing, 0, dWipeLen, dWipeDir)
AddRetraction( nCoastingId, 0, dWipeLen, dWipeDir)
end
end
end
@@ -594,7 +595,7 @@ local function CalcShellsToolPath( vEntIds, nTpathGrpId, LayerParams)
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)
AddRetraction( vIds[i], LayerParams.dCoastingLen, LayerParams.dWipeLen, LayerParams.dWipeDir)
end
end
-- sull'ultima curva gestione speciale per eventuale lead out
@@ -678,7 +679,7 @@ local function CalcExtraShellToolPath( vEntIds, nTpathGrpId, LayerParams)
dWipeDir = LayerParams.dWipeDir
end
AddRetraction( vIds[i], LayerParams.vtSlicing, dCoastingLen, dWipeLen, dWipeDir)
AddRetraction( vIds[i], dCoastingLen, dWipeLen, dWipeDir)
end
end
end
@@ -905,7 +906,7 @@ local function CalcInfillToolPath( nInfillGrp, nTpathGrpId, LayerParams)
for i = 1, #vIds do
local nNext = EgtGetNext( vIds[i])
if not nNext or EgtGetName( nNext) ~= LINK_CRV then
AddRetraction( vIds[i], LayerParams.vtSlicing, LayerParams.dInfillCoasting, LayerParams.dInfillWipe, LayerParams.dInfillWipeDir)
AddRetraction( vIds[i], LayerParams.dInfillCoasting, LayerParams.dInfillWipe, LayerParams.dInfillWipeDir)
end
end
end
@@ -948,7 +949,7 @@ local function CalcSolidFillToolPath( nInfillGrp, nTpathGrpId, LayerParams)
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.dInfillCoasting, LayerParams.dInfillWipe, LayerParams.dInfillWipeDir)
AddRetraction( vIds[i], LayerParams.dInfillCoasting, LayerParams.dInfillWipe, LayerParams.dInfillWipeDir)
end
end
end
@@ -1071,7 +1072,7 @@ local function CalcAuxSolidsToolPath( nAuxSolidsGrp, nAuxSolidsPathGrp, nTpathGr
for i = 1, #vIds do
local nNextId = EgtGetNext( vIds[i])
if not nNextId or EgtGetName( nNextId) ~= LINK_CRV then
AddRetraction( vIds[i], LayerParams.vtSlicing, dCoastingLen, dWipeLen, dWipeDir)
AddRetraction( vIds[i], dCoastingLen, dWipeLen, dWipeDir)
end
end
end
@@ -1757,7 +1758,7 @@ local function AddRibsLeadOut( nCrv, nLoopsGrp, vtSlicing, nGrpTmp, bForceNoSoli
-- se setto chiuso applico la stessa uscita delle shell
if EgtCurveIsClosed( nCrv) then
return AddRetraction( nCrv, vtSlicing, dRibsLOCoasting, dRibsLOWipe, dRibsLOWipeAng)
return AddRetraction( nCrv, dRibsLOCoasting, dRibsLOWipe, dRibsLOWipeAng)
end
local ptE = EgtEP( nCrv, GDB_ID.ROOT)
@@ -1844,7 +1845,7 @@ local function AddRibsLeadOut( nCrv, nLoopsGrp, vtSlicing, nGrpTmp, bForceNoSoli
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)
AddRetraction( nCrv, dRibsLOCoasting, dRibsLOWipe, dRibsLOWipeAng)
end
@@ -2015,7 +2016,7 @@ local function AddSpiralVaseLeadOut( nOldId, LayerParams)
end
AddRetractionOnLastCrv( nOldId, EgtGetParent( nOldId), LayerParams, LayerParams.dCoastingLen, LayerParams.dWipeLen, LayerParams.dWipeDir)
else
AddRetraction( nOldId, LayerParams.vtSlicing, LayerParams.dCoastingLen, LayerParams.dWipeLen, LayerParams.dWipeDir)
AddRetraction( nOldId, LayerParams.dCoastingLen, LayerParams.dWipeLen, LayerParams.dWipeDir)
end
end
@@ -2286,12 +2287,201 @@ local function SpiralVaseFull( vLayIds, LayerParams)
end
---------------------------------------------------------------------
local function SpiralVasePartial( vLayIds, LayerParams)
local function SpiralVasePartialMultiPlanar( vLayIds, LayerParams)
-- la differenza in altezza tra due layers viene distribuita solo lungo il tratto finale di lunghezza dSpiralVaseLen
-- la continuità tra i layers viene risolta sul tratto finale del layer percedente
local bFirst = true
-- individuo l'ultimo layer ( alcuni potrebbero essere vuoti)
local nLastLay = 1
for nIdx = #vLayIds, 1, -1 do
local nCrvGrp = EgtGetFirstNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*")
local nPathGrpId = EgtGetFirstNameInGroup( nCrvGrp, PATH_GRP) or GDB_ID_NULL
if EgtGetGroupObjs( nPathGrpId) > 0 then
nLastLay = nIdx
break
end
end
-- ciclo sui layer
local nOldId
for nIdx = 1, #vLayIds do
-- 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 false
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)
if LayerParams.bInvert then
EgtInvertCurve( nNewEntId)
EgtSetInfo( nNewEntId, KEY_INVERTED_CRV, 1)
end
EgtSetColor( nNewEntId, EgtStdColor('GRAY'))
-- sistemo il tratto finale del percorso precedente
if not bFirst then
local ptSOld = EgtSP( nOldId, GDB_ID.ROOT)
local ptEOld = EgtEP( nOldId, GDB_ID.ROOT)
-- proiezione ortogonale dei punti sul piano di slicing corrente
local ptSProj = ptSOld + ( ( ptSOld - ptSlicing) * vtSlicing) * vtSlicing
local ptEProj = ptEOld + ( ( ptEOld - ptSlicing) * vtSlicing) * vtSlicing
-- 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)
local nProjCrv = EgtCopyGlob( vEntIds[1], nPathGrpId)
-- conservo solo il sottotratto corrispondente a nOldId
local _, _, dStartGuide = EgtPointCurveDist( ptSProj, nProjCrv, GDB_ID.ROOT)
local _, _, dEndGuide = EgtPointCurveDist( ptEProj, nProjCrv, GDB_ID.ROOT)
EgtTrimCurveStartEndAtParam( nProjCrv, dStartGuide, dEndGuide)
-- proiezione sul piano precedente ( ptSlicingPrev, vtSlicingPrev) lungo vtSlicing
local vtSlicingPrev = EgtGetInfo( vLayIds[nIdx-1], KEY_SLICE_DIR, 'v')
local ptSlicingPrev = EgtGetInfo( vLayIds[nIdx-1], KEY_SLICE_POS, 'p') + LayerParams.dLayHeight * vtSlicingPrev
local _, dE = EgtCurveDomain( nProjCrv)
for dU = 0, dE do
local pt = EgtUP( nProjCrv, dU, GDB_ID.ROOT)
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)
end
-- b) proiezione ortogonale graduale sul piano corrente
-- delta che va applicato ( è la distanza ortogonale del punto finale di nOldId dal piano del toolpath corrente)
local dDist = ( EgtEP( nOldId, GDB_ID.ROOT) - ( ptSlicing + LayerParams.dLayHeight * vtSlicing)) * vtSlicing
EgtApproxCurve( nOldId, GDB_CA.SPECIAL_LINES, 0.01, s_dSpiralVaseMaxLen)
local _, dE = EgtCurveDomain( nOldId)
local vDelta = {}
local dLen = EgtCurveLength( nOldId)
for dU = 0, dE do
local dCurrLen = EgtCurveLengthAtParam( nOldId, dU)
vDelta[dU] = abs( dDist) * dCurrLen / dLen
end
for dU = 0, dE do
local ptCurr = EgtUP( nOldId, dU, GDB_ID.ROOT)
EgtModifyCurveCompoJoint( nOldId, dU, ptCurr + vDelta[dU] * vtSlicing, GDB_RT.GLOB)
end
-- c) approssimazione della curva
EgtApproxCurve( nOldId, GDB_CA.ARCS, s_dApproxTol)
if LayerParams.bLinearApprox then
EgtApproxCurve( nOldId, GDB_CA.LINES, LayerParams.dLinearApproxTol)
end
-- forzo punti per garantire continuità
EgtModifyCurveStartPoint( nOldId, ptSOld, GDB_RT.GLOB)
EgtModifyCurveEndPoint( nOldId, ptCurrStart + LayerParams.dLayHeight * vtSlicing, GDB_RT.GLOB)
end
-- spostamento dell'altezza layer
local vtMove = LayerParams.dLayHeight * vtSlicing
EgtMove( nNewEntId, vtMove, GDB_RT.GLOB)
EgtCopyGlob( nNewEntId, nPathGrpId)
-- approssimazione
if LayerParams.bLinearApprox then
local ptS = EgtSP( nNewEntId, GDB_ID.ROOT)
EgtApproxCurve( nNewEntId, GDB_CA.LINES, LayerParams.dLinearApproxTol)
if EgtCurveIsClosed( nNewEntId) then
EgtChangeClosedCurveStartPoint( nNewEntId, ptS, GDB_RT.GLOB)
end
end
-- eventuale lead in
if bFirst then
bFirst = false
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
end
-- separo l'ultimo tratto che farà da collegamento con il layer successivo
if nIdx ~= nLastLay then
local dTrimLen = EgtCurveLength( nNewEntId) - LayerParams.dSpiralVaseLen
if dTrimLen < GEO.EPS_SMALL then
-- se lunghezza di trim maggiore delle dimensioni forzo un valore accettabile
dTrimLen = 0.5 * EgtCurveLength( nNewEntId)
end
local dTrimPar = EgtCurveParamAtLength( nNewEntId, dTrimLen)
nOldId = EgtSplitCurveAtParam( nNewEntId, dTrimPar)
end
end
if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / #vLayIds * 100, 0) == 1 then
EgtDraw()
return false
end
end
return true
end
---------------------------------------------------------------------
local function SpiralVasePartial( vLayIds, LayerParams)
-- la differenza in altezza tra due layers viene distribuita solo lungo il tratto finale di lunghezza dSpiralVaseLen
-- la continuità tra i layers viene risolta sul tratto finale del layer percedente
local nSlicingType = EgtGetInfo( s_nPartId, KEY_SLICING_TYPE, 'i')
if nSlicingType == SLICING_TYPE.MULTIPLANAR then
return SpiralVasePartialMultiPlanar( vLayIds, LayerParams)
end
local bFirst = true
-- individuo l'ultimo layer ( alcuni potrebbero essere vuoti)
local nLastLay = 1
for nIdx = #vLayIds, 1, -1 do
@@ -2307,9 +2497,9 @@ local function SpiralVasePartial( vLayIds, LayerParams)
local nOldId
for nIdx = 1, #vLayIds do
if nSlicingType == SLICING_TYPE.MULTIPLANAR then
LayerParams.vtSlicing = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_DIR, 'v')
end
-- 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.."*")