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:
@@ -963,7 +963,8 @@ local function VerifyMultiPlanarStrand()
|
||||
if dDist < dMinStrand - GEO.EPS_SMALL or dDist > dMaxStrand + GEO.EPS_SMALL then
|
||||
EgtOutLog( 'Error on layer ' .. EgtNumToString( i) .. ' : strand height (' .. EgtNumToString( dDist) .. ') outside valid range (' .. EgtNumToString( dMinStrand) ..
|
||||
' - ' .. EgtNumToString( dMaxStrand) .. ')')
|
||||
EgtOutBox( 'Strand height outside valid range', 'Error', 'ERROR')
|
||||
EgtOutBox( 'Strand height value ' .. EgtNumToString( dDist) .. ' in layer ' .. EgtNumToString( i) .. ' is outside valid range (' .. EgtNumToString( dMinStrand) ..
|
||||
' - ' .. EgtNumToString( dMaxStrand) .. ')', 'Error', 'ERROR')
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
+361
-109
@@ -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)
|
||||
|
||||
+358
-90
@@ -16,6 +16,8 @@ local AMD = require( 'AddManData')
|
||||
local s_dTol = 0.1
|
||||
local s_nSimplifiedSection = 0
|
||||
local s_dMultiPlanarH = 0
|
||||
local s_dColorFactor = 0.9
|
||||
local s_nPartId
|
||||
|
||||
---------------------------------------------------------------------
|
||||
local function GetLayerParamsForSolidCalc( nPartId)
|
||||
@@ -106,9 +108,7 @@ local function CreateSpiralVaseCap( nSectId, vtDir, nSolidGrp)
|
||||
local nCapSrf = EgtSurfTmByTriangles( nSolidGrp, vSurfs)
|
||||
|
||||
-- cancello curve di costruzione
|
||||
for i = 1, #vCrvs do
|
||||
EgtErase( vCrvs[i])
|
||||
end
|
||||
EgtErase( vCrvs)
|
||||
EgtErase( nCrvTop)
|
||||
EgtErase( nCrvBottom)
|
||||
|
||||
@@ -187,19 +187,19 @@ local function CreateSpiralVaseSolid( nCrvId, nSolidGrp, vtSlicing, dH, dStrand)
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local nSrfId = EgtSurfTmByTriangles( nSolidGrp, vSurfs)
|
||||
|
||||
|
||||
-- creazione del mezzo disco iniziale
|
||||
local nCap1 = CreateSpiralVaseCap( nSectId, - vtS, nSolidGrp)
|
||||
vSurfs[#vCrvs] = CreateSpiralVaseCap( nSectId, - vtS, nSolidGrp)
|
||||
-- creazione del mezzo disco finale
|
||||
local nCap2 = CreateSpiralVaseCap( nSectE, vtE, nSolidGrp)
|
||||
EgtInvertSurf( nCap2)
|
||||
vSurfs[#vCrvs+1] = CreateSpiralVaseCap( nSectE, vtE, nSolidGrp)
|
||||
EgtInvertSurf( vSurfs[#vCrvs+1])
|
||||
|
||||
local nSolidId = EgtSurfTmByTriangles( nSolidGrp, vSurfs)
|
||||
|
||||
-- cancello le curve usate per la costruzione
|
||||
EgtErase( nGrpTmp)
|
||||
|
||||
return EgtSurfTmByTriangles( nSolidGrp, { nSrfId, nCap1, nCap2})
|
||||
return nSolidId
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
@@ -212,7 +212,7 @@ local function CreateSolid( nCrvId, nSolidGrp, LayerParams, dH, dStrand)
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
local function CreateDirectionArrow( nCrvId, nSolidGrp, vtSlicing, dStrand, nLayer)
|
||||
local function CreateDirectionArrow( nCrvId, nSolidGrp, vtSlicing, dStrand, nSliceNbr)
|
||||
|
||||
local ptS = EgtSP( nCrvId, GDB_RT.GLOB)
|
||||
local vtS = EgtSV( nCrvId, GDB_RT.GLOB)
|
||||
@@ -234,7 +234,7 @@ local function CreateDirectionArrow( nCrvId, nSolidGrp, vtSlicing, dStrand, nLay
|
||||
local nSrf = EgtSurfFlatRegion( nSolidGrp, { nCompo})
|
||||
EgtErase( nCompo)
|
||||
EgtSetColor( nSrf, RED())
|
||||
EgtSetInfo( nSrf, KEY_SLICE_NBR, nLayer)
|
||||
EgtSetInfo( nSrf, KEY_SLICE_NBR, nSliceNbr)
|
||||
EgtSetStatus( nSrf, GDB_ST.OFF)
|
||||
EgtSetMode( nSrf, GDB_MD.HIDDEN)
|
||||
EgtSetName( nSrf, DIR_ARROW)
|
||||
@@ -272,7 +272,57 @@ local function CreateRecursiveSolid( nCrvId, vSurfs, nSolidGrp, LayerParams, dH,
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
local function CreateSolidFromCurve( nCrvId, nSolidGrp, LayerParams, nLayer, dLayerH)
|
||||
local function CalcSolidGuides( nCrvId, dStrand, nSolidGrp)
|
||||
|
||||
-- suddivido la curva in modo opportuno
|
||||
local nCopyId = EgtCopyGlob( nCrvId, nSolidGrp)
|
||||
local nId
|
||||
local nParts = 1
|
||||
local LEN_REF = 100
|
||||
local bZigZagInfill = EgtGetInfo( nCopyId, KEY_ZIG_ZAG_INFILL, 'b') or false
|
||||
if bZigZagInfill then
|
||||
nId, nParts = EgtSplitCurveAtCorners( nCopyId, 80)
|
||||
else
|
||||
local dLen = EgtCurveLength( nCrvId)
|
||||
if dLen > LEN_REF and nType ~= TYPE.LINK and nType ~= TYPE.COASTING then
|
||||
nParts = EgtClamp( floor( dLen / LEN_REF), 1, 10)
|
||||
end
|
||||
nId = EgtSplitCurve( nCopyId, nParts)
|
||||
end
|
||||
|
||||
if not nId then return end
|
||||
|
||||
-- verifico in modo euristico se la curva torna indietro su se stessa come se fossero due shell collegate ( verifico se è presente un sottotratto di lunghezza
|
||||
-- circa pari allo strand non in tangenza con i sottotratti vicini). Nel caso la spezzo per evitare problemi nel calcolo di solidi swept
|
||||
local vGuideIds = {}
|
||||
for nInd = 0, nParts - 1 do
|
||||
local nGuideId = nId + nInd
|
||||
table.insert( vGuideIds, nGuideId)
|
||||
if EgtGetType( nGuideId) == GDB_TY.CRV_COMPO then
|
||||
local _, dE = EgtCurveDomain( nGuideId)
|
||||
for dU = 1, dE - 2 do
|
||||
local dLen = EgtCurveCompoLength( nGuideId, dU)
|
||||
if abs( dLen - dStrand) < 500 * GEO.EPS_SMALL then
|
||||
-- verifico gli angoli
|
||||
local vtPrev = EgtUV( nGuideId, dU, -1, GDB_ID.ROOT)
|
||||
local vtCurrS = EgtUV( nGuideId, dU, 1, GDB_ID.ROOT)
|
||||
local vtCurrE = EgtUV( nGuideId, dU + 1, -1, GDB_ID.ROOT)
|
||||
local vtNext = EgtUV( nGuideId, dU + 1, 1, GDB_ID.ROOT)
|
||||
if vtPrev * vtCurrS < GEO.EPS_SMALL or vtCurrE * vtNext < GEO.EPS_SMALL then
|
||||
local nNewId = EgtSplitCurveAtParam( nGuideId, dU + 0.5)
|
||||
table.insert( vGuideIds, nNewId)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return vGuideIds
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
local function CreateSolidFromCurve( nCrvId, nSolidGrp, LayerParams, nSliceNbr, dLayerH)
|
||||
|
||||
local nType = EgtGetInfo( nCrvId, KEY_TYPE, 'i')
|
||||
if nType == TYPE.WIPE then return true end
|
||||
@@ -294,54 +344,47 @@ local function CreateSolidFromCurve( nCrvId, nSolidGrp, LayerParams, nLayer, dLa
|
||||
Color = EgtStdColor( 'AQUA')
|
||||
end
|
||||
|
||||
if s_nSimplifiedSection == 1 and nSliceNbr % 2 == 0 then
|
||||
Color = Color3d( s_dColorFactor * Color:getRed(), s_dColorFactor * Color:getGreen(), s_dColorFactor * Color:getBlue())
|
||||
end
|
||||
|
||||
-- parametri della passata
|
||||
local dStrand = EgtGetInfo( nCrvId, KEY_CRV_STRAND, 'd') or LayerParams.dStrand
|
||||
local dH = dLayerH or LayerParams.dLayHeight
|
||||
|
||||
local nCopyId = EgtCopyGlob( nCrvId, nSolidGrp)
|
||||
local nId = GDB_ID.NULL
|
||||
local nParts = 1
|
||||
local LEN_REF = 100
|
||||
local bZigZagInfill = EgtGetInfo( nCopyId, KEY_ZIG_ZAG_INFILL, 'b') or false
|
||||
if bZigZagInfill then
|
||||
nId, nParts = EgtSplitCurveAtCorners( nCopyId, 80)
|
||||
else
|
||||
local dLen = EgtCurveLength( nCrvId)
|
||||
if dLen > LEN_REF and nType ~= TYPE.LINK and nType ~= TYPE.COASTING then
|
||||
nParts = EgtClamp( floor( dLen / LEN_REF), 1, 10)
|
||||
end
|
||||
nId = EgtSplitCurve( nCopyId, nParts)
|
||||
end
|
||||
|
||||
|
||||
-- freccia direzionale
|
||||
local sName = EgtGetName( nCrvId)
|
||||
if nType ~= TYPE.COASTING and nType ~= TYPE.LINK and sName ~= LEAD_IN_CRV and sName ~= LEAD_OUT_CRV and sName ~= LINK_CRV then
|
||||
CreateDirectionArrow( nCrvId, nSolidGrp, LayerParams.vtSlicing, dStrand, nLayer)
|
||||
CreateDirectionArrow( nCrvId, nSolidGrp, LayerParams.vtSlicing, dStrand, nSliceNbr)
|
||||
end
|
||||
|
||||
if nId == GDB_ID.NULL then return false end
|
||||
-- spezzo la curva guida in diversi sottotratti per i quali calcolare i solidi
|
||||
local vGuideIds = CalcSolidGuides( nCrvId, dStrand, nSolidGrp)
|
||||
if not vGuideIds then
|
||||
return false
|
||||
end
|
||||
|
||||
local bOk = true
|
||||
for nInd = 0, nParts - 1 do
|
||||
local nGuideId = nId + nInd
|
||||
local nSrfId = CreateSolid( nGuideId, nSolidGrp, LayerParams, dH, dStrand - 5 * GEO.EPS_SMALL)
|
||||
for i = 1, #vGuideIds do
|
||||
local nSrfId = CreateSolid( vGuideIds[i], nSolidGrp, LayerParams, dH, dStrand - 5 * GEO.EPS_SMALL)
|
||||
if not nSrfId then
|
||||
EgtOutLog( 'Warning : CreateSolid failed '.. '(layer '..tostring( nLayer)..', curve '..tostring( nCrvId)..')')
|
||||
EgtOutLog( 'Warning : CreateSolid failed '.. '(layer '..tostring( nSliceNbr)..', curve '..tostring( nCrvId)..')')
|
||||
-- ritento con strand più piccolo
|
||||
nSrfId = CreateSolid( nGuideId, nSolidGrp, LayerParams, dH, dStrand - 50 * GEO.EPS_SMALL)
|
||||
nSrfId = CreateSolid( vGuideIds[i], nSolidGrp, LayerParams, dH, dStrand - 50 * GEO.EPS_SMALL)
|
||||
|
||||
if not nSrfId then
|
||||
EgtOutLog( 'Warning : CreateSolid_1 failed '.. '(layer '..tostring( nLayer)..', curve '..tostring( nCrvId)..')')
|
||||
EgtOutLog( 'Warning : CreateSolid_1 failed '.. '(layer '..tostring( nSliceNbr)..', curve '..tostring( nCrvId)..')')
|
||||
-- se non ultima, provo a spostare l'estremità finale
|
||||
if nInd < nParts - 1 then
|
||||
local nCopyId = EgtCopy( nGuideId + 1, nGuideId, GDB_IN.AFTER)
|
||||
if i < #vGuideIds then
|
||||
local nCopyId = EgtCopy( vGuideIds[i] + 1, vGuideIds[i], GDB_IN.AFTER)
|
||||
if nCopyId then
|
||||
local LEN_TRIM = 10
|
||||
local bOk1 = EgtTrimCurveEndAtLen( nCopyId, LEN_TRIM)
|
||||
local bOk2 = EgtAddCurveCompoCurve( nGuideId, nCopyId)
|
||||
local bOk3 = EgtTrimCurveStartAtLen( nGuideId + 1, LEN_TRIM)
|
||||
nSrfId = CreateSolid( nGuideId, nSolidGrp, LayerParams, dH, dStrand - 5 * GEO.EPS_SMALL)
|
||||
local bOk2 = EgtAddCurveCompoCurve( vGuideIds[i], nCopyId)
|
||||
local bOk3 = EgtTrimCurveStartAtLen( vGuideIds[i] + 1, LEN_TRIM)
|
||||
nSrfId = CreateSolid( vGuideIds[i], nSolidGrp, LayerParams, dH, dStrand - 5 * GEO.EPS_SMALL)
|
||||
if not nSrfId then
|
||||
nSrfId = CreateSolid( nGuideId, nSolidGrp, LayerParams, dH, dStrand - 50 * GEO.EPS_SMALL)
|
||||
nSrfId = CreateSolid( vGuideIds[i], nSolidGrp, LayerParams, dH, dStrand - 50 * GEO.EPS_SMALL)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -351,12 +394,12 @@ local function CreateSolidFromCurve( nCrvId, nSolidGrp, LayerParams, nLayer, dLa
|
||||
if not nSrfId then
|
||||
EgtOutLog( 'Warning : CreateSolid_2 failed')
|
||||
local nGrp = EgtGroup( nSolidGrp, Frame3d( ORIG(), LayerParams.vtSlicing), GDB_RT.GLOB)
|
||||
EgtRelocateGlob( nGuideId, nGrp)
|
||||
EgtApproxCurve( nGuideId, GDB_CA.LINES, 100 * GEO.EPS_SMALL)
|
||||
EgtRelocateGlob( nGuideId, nSolidGrp)
|
||||
EgtRelocateGlob( vGuideIds[i], nGrp)
|
||||
EgtApproxCurve( vGuideIds[i], GDB_CA.LINES, 100 * GEO.EPS_SMALL)
|
||||
EgtRelocateGlob( vGuideIds[i], nSolidGrp)
|
||||
|
||||
local vSurfs = {}
|
||||
local bOk = CreateRecursiveSolid( nGuideId, vSurfs, nSolidGrp, LayerParams, dH, dStrand)
|
||||
local bOk = CreateRecursiveSolid( vGuideIds[i], vSurfs, nSolidGrp, LayerParams, dH, dStrand)
|
||||
if #vSurfs > 0 then
|
||||
nSrfId = EgtSurfTmByTriangles( nSolidGrp, vSurfs)
|
||||
end
|
||||
@@ -370,14 +413,14 @@ local function CreateSolidFromCurve( nCrvId, nSolidGrp, LayerParams, nLayer, dLa
|
||||
if nSrfId then
|
||||
EgtSetColor( nSrfId, Color)
|
||||
EgtSetInfo( nSrfId, KEY_TYPE, nType)
|
||||
EgtSetInfo( nSrfId, KEY_SLICE_NBR, nLayer)
|
||||
EgtSetInfo( nSrfId, KEY_SLICE_NBR, nSliceNbr)
|
||||
else
|
||||
bOk = false
|
||||
EgtOutLog( 'Warning : CreateSolid_Sewing failed')
|
||||
end
|
||||
EgtErase( nGuideId)
|
||||
end
|
||||
|
||||
EgtErase( vGuideIds[i])
|
||||
end
|
||||
|
||||
return bOk
|
||||
end
|
||||
|
||||
@@ -399,6 +442,7 @@ local function CreateMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, nLayerId
|
||||
local nPrevLayerId = EgtGetPrev( nLayerId)
|
||||
local vtSlicingPrev = EgtGetInfo( nPrevLayerId, KEY_SLICE_DIR, 'v')
|
||||
local ptSlicingPrev = EgtGetInfo( nPrevLayerId, KEY_SLICE_POS, 'p') + vtSlicingPrev * LayerParams.dLayHeight
|
||||
local dCosAng = vtSlicingPrev * LayerParams.vtSlicing
|
||||
|
||||
local vSolids = EgtGetAllInGroup( nSolidGrpId)
|
||||
for i = 1, #vSolids do
|
||||
@@ -407,7 +451,7 @@ local function CreateMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, nLayerId
|
||||
local ptVertex = EgtSurfTmGetVertex( vSolids[i], j, GDB_RT.GLOB)
|
||||
-- distanza dal piano di slicing corrente e precedente lungo vtSlicing
|
||||
local dDistCurr = abs( ( ptVertex - ptSlicing) * LayerParams.vtSlicing)
|
||||
local dDistPrev = ( ptVertex - ptSlicingPrev) * vtSlicingPrev / ( vtSlicingPrev * LayerParams.vtSlicing)
|
||||
local dDistPrev = ( ptVertex - ptSlicingPrev) * vtSlicingPrev / dCosAng
|
||||
-- calcolo la nuova posizione sapendo che l'altezza dello strand passa da s_dMultiPlanarH a dNewH
|
||||
local dNewH = dDistCurr + dDistPrev
|
||||
local dDelta = dDistCurr - dDistCurr * dNewH / s_dMultiPlanarH
|
||||
@@ -421,16 +465,16 @@ end
|
||||
---------------------------------------------------------------------
|
||||
local function CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, nLayerId)
|
||||
|
||||
-- 1) le prima curve sono solidi multiplanari standard
|
||||
-- 1) le prime curve sono solidi multiplanari standard
|
||||
for i = 1, #vIds - 1 do
|
||||
CreateMultiPlanarSolids( { vIds[i]}, nSolidGrpId, LayerParams, nLayerId)
|
||||
end
|
||||
|
||||
-- 2) l'ultima è il tratto che si alza fino al layer successivo
|
||||
-- 2) l'ultima curva è il tratto che si alza fino al layer successivo
|
||||
local nGrpTmp = EgtGroup( nSolidGrpId)
|
||||
local dStrand = EgtGetInfo( vIds[#vIds], KEY_CRV_STRAND, 'd') or LayerParams.dStrand
|
||||
-- gruppo temporaneo per conti
|
||||
local nGrpTmp = EgtGroup( nSolidGrpId, Frame3d( ORIG(), LayerParams.vtSlicing, GDB_RT.GLOB))
|
||||
|
||||
|
||||
-- a) calcolo il solido
|
||||
-- appiattisco la curva ( proiezione obliqua sul piano corrente lungo vtSlicing del piano successivo)
|
||||
local nNextLayerId = EgtGetNext( nLayerId)
|
||||
local vtSlicingNext = EgtGetInfo( nNextLayerId, KEY_SLICE_DIR, 'v')
|
||||
@@ -454,7 +498,7 @@ local function CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, Laye
|
||||
vtDir2:rotate( LayerParams.vtSlicing, 90)
|
||||
local nSectE = CreateSection( ptE, vtDir2, dStrand, s_dMultiPlanarH, LayerParams.vtSlicing, nGrpTmp)
|
||||
|
||||
-- creo il solido aperto ( tubo)
|
||||
-- creo le guide per il solido aperto ( tubo)
|
||||
local dMaxDist = ( EgtEP( vIds[#vIds], GDB_ID.ROOT) - ptSlicing) * LayerParams.vtSlicing / ( vtSlicingNext * LayerParams.vtSlicing)
|
||||
local vCrvs = {}
|
||||
local _, dParE = EgtCurveDomain( nSectId)
|
||||
@@ -484,53 +528,264 @@ local function CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, Laye
|
||||
local dMove = ( ptRef - ptS) * LayerParams.vtSlicing
|
||||
EgtMove( vCrvs[i+1], LayerParams.vtSlicing * dMove, GDB_RT.GLOB)
|
||||
end
|
||||
-- creazione delle superfici del tubo
|
||||
local vSurfs = {}
|
||||
for i = 1, #vCrvs - 1 do
|
||||
vSurfs[i] = EgtSurfTmRuled( nGrpTmp, vCrvs[i], vCrvs[i+1], GDB_RUL.MINDIST, s_dTol)
|
||||
if not vSurfs[i] or vSurfs[i] == GDB_ID.NULL then
|
||||
EgtErase( nGrpTmp)
|
||||
return nil
|
||||
return false
|
||||
end
|
||||
end
|
||||
local nSrfId = EgtSurfTmByTriangles( nSolidGrpId, vSurfs)
|
||||
|
||||
-- creazione del mezzo disco iniziale
|
||||
local nCap1 = CreateSpiralVaseCap( nSectId, - EgtSV( vIds[#vIds], GDB_ID.ROOT), nSolidGrpId)
|
||||
-- creazione del mezzo disco finale
|
||||
local nCap2 = CreateSpiralVaseCap( nSectE, EgtEV( vIds[#vIds], GDB_ID.ROOT), nSolidGrpId)
|
||||
EgtInvertSurf( nCap2)
|
||||
|
||||
-- solido finale
|
||||
local nSolidId = EgtSurfTmByTriangles( nSolidGrpId, { nSrfId, nCap1, nCap2})
|
||||
-- creazione del mezzo disco iniziale e finale
|
||||
vSurfs[#vCrvs] = CreateSpiralVaseCap( nSectId, - EgtSV( vIds[#vIds], GDB_ID.ROOT), nSolidGrpId)
|
||||
vSurfs[#vCrvs + 1] = CreateSpiralVaseCap( nSectE, EgtEV( vIds[#vIds], GDB_ID.ROOT), nSolidGrpId)
|
||||
EgtInvertSurf( vSurfs[#vSurfs])
|
||||
local nSolidId = EgtSurfTmByTriangles( nSolidGrpId, vSurfs)
|
||||
|
||||
-- limito il solido al piano di slicing precedente
|
||||
local ptPrev
|
||||
local vtPrev
|
||||
if EgtGetInfo( nLayerId, KEY_SLICE_NBR, 'i') == 1 then
|
||||
ptPrev = ptSlicing - LayerParams.dLayHeight * LayerParams.vtSlicing
|
||||
vtPrev = LayerParams.vtSlicing
|
||||
-- b) deformo il solido per limitarlo al piano di slicing precedente
|
||||
local ptSlicingPrev
|
||||
local vtSlicingPrev
|
||||
local nSliceNbr = EgtGetInfo( nLayerId, KEY_SLICE_NBR, 'i')
|
||||
if nSliceNbr == 1 then
|
||||
vtSlicingPrev = LayerParams.vtSlicing
|
||||
ptSlicingPrev = ptSlicing - LayerParams.dLayHeight * LayerParams.vtSlicing
|
||||
else
|
||||
local nPrevLayId = EgtGetPrev( nLayerId)
|
||||
vtPrev = EgtGetInfo( nPrevLayId, KEY_SLICE_DIR, 'v')
|
||||
ptPrev = EgtGetInfo( nPrevLayId, KEY_SLICE_POS, 'p') + vtPrev * LayerParams.dLayHeight
|
||||
vtSlicingPrev = EgtGetInfo( nPrevLayId, KEY_SLICE_DIR, 'v')
|
||||
ptSlicingPrev = EgtGetInfo( nPrevLayId, KEY_SLICE_POS, 'p') + vtSlicingPrev * LayerParams.dLayHeight
|
||||
end
|
||||
local dCosAng = vtSlicingPrev * LayerParams.vtSlicing
|
||||
|
||||
-- estendo la curva proiettata per gestire correttamente la deformazione dei caps
|
||||
local nProjExtCrv = EgtCopyGlob( nProjCrv, nGrpTmp)
|
||||
EgtExtendCurveStartByLen( nProjExtCrv, dStrand)
|
||||
EgtExtendCurveEndByLen( nProjExtCrv, dStrand)
|
||||
local dLen = EgtCurveLength( nProjCrv)
|
||||
|
||||
local nVertexCnt = EgtSurfTmVertexCount( nSolidId)
|
||||
for j = 0, nVertexCnt - 1 do
|
||||
|
||||
local ptVertex = EgtSurfTmGetVertex( nSolidId, j, GDB_RT.GLOB)
|
||||
local _, ptMinDist = EgtPointCurveDist( ptVertex, vIds[#vIds], GDB_ID.ROOT)
|
||||
local dDistCrv = abs( ( ptVertex - ptMinDist) * LayerParams.vtSlicing)
|
||||
local dDistPlane = ( ptVertex - ptPrev) * vtPrev / ( vtPrev * LayerParams.vtSlicing)
|
||||
|
||||
-- calcolo la distanza dal piano precedente lungo vtSlicing
|
||||
local dDistPrevPlane = ( ptVertex - ptSlicingPrev) * vtSlicingPrev / dCosAng
|
||||
-- calcolo la distanza approssimata dalla curva del toolpath
|
||||
local _, ptMinDist, dMinPar = EgtPointCurveDist( ptVertex, nProjExtCrv, GDB_ID.ROOT)
|
||||
local dCurrLen = EgtCurveLengthAtParam( nProjExtCrv, dMinPar) - dStrand
|
||||
local ptRef = ptMinDist + dMaxDist * dCurrLen / dLen * vtSlicingNext
|
||||
local dDistCrv = ( ptRef - ptVertex) * LayerParams.vtSlicing
|
||||
|
||||
-- calcolo la nuova posizione sapendo che l'altezza dello strand passa da s_dMultiPlanarH a dNewH
|
||||
local dNewH = dDistCrv + dDistPlane
|
||||
local dNewH = dDistCrv + dDistPrevPlane
|
||||
local dDelta = dDistCrv - dDistCrv * dNewH / s_dMultiPlanarH
|
||||
local ptNew = ptVertex + dDelta * LayerParams.vtSlicing
|
||||
EgtSurfTmMoveVertex( nSolidId, j, ptNew, GDB_RT.GLOB, ( j == nVertexCnt - 1))
|
||||
end
|
||||
|
||||
EgtSetColor( nSolidId, EgtStdColor( 'TEAL'))
|
||||
local Color = EgtStdColor( 'TEAL')
|
||||
if s_nSimplifiedSection == 1 and nSliceNbr % 2 == 0 then
|
||||
Color = Color3d( s_dColorFactor * Color:getRed(), s_dColorFactor * Color:getGreen(), s_dColorFactor * Color:getBlue())
|
||||
end
|
||||
EgtSetColor( nSolidId, Color)
|
||||
|
||||
EgtErase( nGrpTmp)
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
local function CreateFullSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, nLayerId)
|
||||
|
||||
local nSliceNbr = EgtGetInfo( nLayerId, KEY_SLICE_NBR, 'i')
|
||||
local ptSlicing = EgtGetInfo( nLayerId, KEY_SLICE_POS, 'p') + LayerParams.dLayHeight * LayerParams.vtSlicing
|
||||
|
||||
-- recupero il piano precedente e il suo toolpath
|
||||
local nPrevLayerId = EgtGetPrev( nLayerId)
|
||||
local vtSlicingPrev = EgtGetInfo( nPrevLayerId, KEY_SLICE_DIR, 'v')
|
||||
local ptSlicingPrev = EgtGetInfo( nPrevLayerId, KEY_SLICE_POS, 'p') + LayerParams.dLayHeight * vtSlicingPrev
|
||||
local dCosAng = vtSlicingPrev * LayerParams.vtSlicing
|
||||
local nPrevCrvGrp = EgtGetFirstNameInGroup( nPrevLayerId, CONTOUR_GRP .. '*')
|
||||
local nPrevTPathGrp = EgtGetFirstNameInGroup( nPrevCrvGrp, TOOLPATH_GRP)
|
||||
local nPrevTPath = EgtGetFirstNameInGroup( nPrevTPathGrp, SHELL_CRV .. '*')
|
||||
|
||||
-- gruppo temporaneo per conti
|
||||
local nGrpTmp = EgtGroup( nSolidGrpId)
|
||||
|
||||
for i = 1, #vIds do
|
||||
local dStrand = EgtGetInfo( vIds[i], KEY_CRV_STRAND, 'd') or LayerParams.dStrand
|
||||
|
||||
-- creo la freccia direzionale
|
||||
CreateDirectionArrow( vIds[i], nSolidGrpId, LayerParams.vtSlicing, dStrand, nSliceNbr)
|
||||
|
||||
-- appiattisco la curva ( proiezione sul piano di slicing)
|
||||
local nProjCrv = EgtCopyGlob( vIds[i], nGrpTmp)
|
||||
EgtProjectCurveOnPlane( nProjCrv, ptSlicing, LayerParams.vtSlicing, GDB_RT.GLOB)
|
||||
local dLen = EgtCurveLength( nProjCrv)
|
||||
|
||||
-- suddivido la curva piana
|
||||
local vGuideIds = CalcSolidGuides( nProjCrv, dStrand, nGrpTmp)
|
||||
local dCumLen = 0
|
||||
for k = 1, #vGuideIds do
|
||||
|
||||
-- calcolo il solido sulla porzione della curva di proiezione
|
||||
local nSolidId = CreateStandardSolid( vGuideIds[k], nSolidGrpId, s_dMultiPlanarH, dStrand)
|
||||
|
||||
-- estendo la guida per gestire al meglio i caps
|
||||
local nCrvRef = EgtCopyGlob( vGuideIds[k], nGrpTmp)
|
||||
EgtExtendCurveStartByLen( nCrvRef, dStrand)
|
||||
EgtExtendCurveEndByLen( nCrvRef, dStrand)
|
||||
|
||||
-- recupero la curva precedente. Se estremi la limito per gestire al meglio la corrispondenza tra i toolpath
|
||||
local nPrevTPathRef = nPrevTPath
|
||||
if k == 1 then
|
||||
nPrevTPathRef = EgtCopyGlob( nPrevTPath, nGrpTmp)
|
||||
EgtTrimCurveEndAtLen( nPrevTPathRef, 0.5 * EgtCurveLength( nPrevTPathRef))
|
||||
elseif k == #vGuideIds then
|
||||
nPrevTPathRef = EgtCopyGlob( nPrevTPath, nGrpTmp)
|
||||
EgtTrimCurveStartAtLen( nPrevTPathRef, 0.5 * EgtCurveLength( nPrevTPathRef))
|
||||
end
|
||||
|
||||
-- deformo i solidi :
|
||||
-- 1) traslazione dei vertici per portarli alla quota corretta del toolpath corrente
|
||||
-- 2) deformazione della sezione in base alla distanza dal toolpath precedente
|
||||
local nVertexCnt = EgtSurfTmVertexCount( nSolidId)
|
||||
for j = 0, nVertexCnt - 1 do
|
||||
local ptVertex = EgtSurfTmGetVertex( nSolidId, j, GDB_RT.GLOB)
|
||||
|
||||
-- ricavo il punto di riferimento sulla proiezione del toolpath
|
||||
local _, ptMinDist, dParMinDist = EgtPointCurveDist( ptVertex, nCrvRef, GDB_ID.ROOT)
|
||||
local dCurrLen = EgtCurveLengthAtParam( nCrvRef, dParMinDist) - dStrand + dCumLen
|
||||
|
||||
-- 1) proietto il punto sul piano corrente e calcolo la traslazione da applicare in base alla distanza dal piano precedente ( analogamente a CalcToolPath)
|
||||
local dDistCrv = ( ptSlicing - ptVertex) * LayerParams.vtSlicing
|
||||
local ptProj = ptVertex + dDistCrv * LayerParams.vtSlicing
|
||||
local dDistPlanePrev = ( ptProj - ptSlicingPrev) * vtSlicingPrev / dCosAng
|
||||
local dDeltaPos
|
||||
if nSliceNbr == 2 and dCurrLen < 0.5 * dLen then
|
||||
dDeltaPos = 0.5 * dDistPlanePrev
|
||||
else
|
||||
dDeltaPos = dDistPlanePrev * ( dLen - dCurrLen) / dLen
|
||||
end
|
||||
|
||||
-- 2) per calcolare la vera altezza del solido calcolo la distanza dal toolpath precedente guardando il punto di riferimento sul percorso corrente
|
||||
local dNewH
|
||||
if nSliceNbr == 2 then
|
||||
-- il primo layer è ad altezza costante quindi è semplice distanza dal piano precedente lungo vtSlicing
|
||||
dNewH = ( ptProj - ptSlicingPrev) * vtSlicingPrev / dCosAng - dDeltaPos
|
||||
else
|
||||
local _, ptMinDistPrev = EgtPointCurveDist( ptMinDist, nPrevTPathRef, GDB_ID.ROOT)
|
||||
local dDistPlanePrev2 = ( ptMinDist - ptSlicingPrev) * vtSlicingPrev / dCosAng
|
||||
local dDeltaPos2
|
||||
if nSliceNbr == 2 and dCurrLen < 0.5 * dLen then
|
||||
dDeltaPos2 = 0.5 * dDistPlanePrev2
|
||||
else
|
||||
dDeltaPos2 = dDistPlanePrev2 * ( dLen - dCurrLen) / dLen
|
||||
end
|
||||
dNewH = ( ptMinDist - ptMinDistPrev) * LayerParams.vtSlicing - dDeltaPos2
|
||||
-- aggiungo un piccolo extra per tener conto che la distanza è stata calcolata sulle curve centrali del solido
|
||||
local dExtra = ( LayerParams.vtSlicing ^ vtSlicingPrev):len() / dCosAng * dStrand * 0.5
|
||||
dNewH = dNewH + dExtra
|
||||
end
|
||||
|
||||
local dDelta = dDistCrv - dDistCrv * dNewH / s_dMultiPlanarH
|
||||
local ptNew = ptVertex + ( dDelta - dDeltaPos) * LayerParams.vtSlicing
|
||||
EgtSurfTmMoveVertex( nSolidId, j, ptNew, GDB_RT.GLOB, ( j == nVertexCnt - 1))
|
||||
end
|
||||
|
||||
-- imposto colore
|
||||
local Color = EgtStdColor( 'TEAL')
|
||||
if s_nSimplifiedSection == 1 and nSliceNbr % 2 == 0 then
|
||||
Color = Color3d( s_dColorFactor * Color:getRed(), s_dColorFactor * Color:getGreen(), s_dColorFactor * Color:getBlue())
|
||||
end
|
||||
EgtSetColor( nSolidId, Color)
|
||||
|
||||
dCumLen = dCumLen + EgtCurveLength( vGuideIds[i])
|
||||
end
|
||||
end
|
||||
|
||||
EgtErase( nGrpTmp)
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
local function CreateFullSpiralVaseMultiPlanarSolidsLastLayer( vIds, nSolidGrpId, LayerParams, nLayerId)
|
||||
-- le curve sono piane quindi i solidi possono essere calcolati nel modo classico
|
||||
-- i solidi della shell sono deformati in base alla distanza dalla curva precedente
|
||||
-- eventuali solidi di lead out e coasting sono calcolati con un valore di altezza costante pari all'ultimo valore di altezza dei solidi della shell
|
||||
|
||||
local nSliceNbr = EgtGetInfo( nLayerId, KEY_SLICE_NBR, 'i')
|
||||
|
||||
local nPrevLayerId = EgtGetPrev( EgtGetPrev( nLayerId))
|
||||
local vtSlicingPrev = EgtGetInfo( nPrevLayerId, KEY_SLICE_DIR, 'v')
|
||||
local ptSlicingPrev = EgtGetInfo( nPrevLayerId, KEY_SLICE_POS, 'p') + vtSlicingPrev * LayerParams.dLayHeight
|
||||
local ptSlicing = EgtGetInfo( nLayerId, KEY_SLICE_POS, 'p') + LayerParams.vtSlicing * LayerParams.dLayHeight
|
||||
local dCosAng = vtSlicingPrev * LayerParams.vtSlicing
|
||||
|
||||
-- 1) curva shell
|
||||
local nGrpTmp = EgtGroup( nSolidGrpId)
|
||||
local dStrand = EgtGetInfo( vIds[1], KEY_CRV_STRAND, 'd') or LayerParams.dStrand
|
||||
local vShellGuides = CalcSolidGuides( vIds[1], dStrand, nGrpTmp)
|
||||
|
||||
local dLen = EgtCurveLength( vIds[1])
|
||||
-- se non c'è lead out alla lunghezza totale della shell devo aggiungere anche quella del coasting
|
||||
if EgtGetInfo( s_nPartId, KEY_LEAD_OUT_TYPE, 'i') == LEAD_TYPE.NONE then
|
||||
dLen = dLen + EgtGetInfo( s_nPartId, KEY_COASTING_LEN, 'd')
|
||||
end
|
||||
local dCumLen = 0
|
||||
|
||||
-- creo la freccia direzionale
|
||||
CreateDirectionArrow( vIds[1], nSolidGrpId, LayerParams.vtSlicing, dStrand, nSliceNbr)
|
||||
|
||||
for i = 1, #vShellGuides do
|
||||
|
||||
-- calcolo il solido associato
|
||||
local nSolidId = CreateStandardSolid( vShellGuides[i], nSolidGrpId, s_dMultiPlanarH, dStrand)
|
||||
|
||||
-- estensione della guida per gestire meglio i caps
|
||||
local nCrvRef = EgtCopyGlob( vShellGuides[i], nGrpTmp)
|
||||
EgtExtendCurveStartByLen( nCrvRef, dStrand)
|
||||
EgtExtendCurveEndByLen( nCrvRef, dStrand)
|
||||
|
||||
-- deformo in base alla distanza dalla curva precedente
|
||||
local nVertexCnt = EgtSurfTmVertexCount( nSolidId)
|
||||
for j = 0, nVertexCnt - 1 do
|
||||
local ptVertex = EgtSurfTmGetVertex( nSolidId, j, GDB_RT.GLOB)
|
||||
|
||||
-- ricavo il punto di riferimento sulla guida
|
||||
local _, _, dParMinDist = EgtPointCurveDist( ptVertex, nCrvRef, GDB_ID.ROOT)
|
||||
local dCurrLen = EgtCurveLengthAtParam( nCrvRef, dParMinDist) - dStrand + dCumLen
|
||||
|
||||
-- calcolo la nuova altezza del solido in base alla distanza dalla curva precedente
|
||||
local dDistCurr = ( ptSlicing - ptVertex) * LayerParams.vtSlicing
|
||||
local ptProj = ptVertex + dDistCurr * LayerParams.vtSlicing
|
||||
local dDistPrev = ( ptProj - ptSlicingPrev) * vtSlicingPrev / dCosAng
|
||||
local dNewH = dDistPrev * ( dLen - dCurrLen) / dLen
|
||||
dNewH = max( dNewH, 500 * GEO.EPS_SMALL)
|
||||
|
||||
-- calcolo la nuova posizione sapendo che l'altezza dello strand passa da s_dMultiPlanarH a dNewH
|
||||
local dDelta = dDistCurr - dDistCurr * dNewH / s_dMultiPlanarH
|
||||
local ptNew = ptVertex + dDelta * LayerParams.vtSlicing
|
||||
EgtSurfTmMoveVertex( nSolidId, j, ptNew, GDB_RT.GLOB, ( j == nVertexCnt - 1))
|
||||
end
|
||||
|
||||
dCumLen = dCumLen + EgtCurveLength( vShellGuides[i])
|
||||
|
||||
-- imposto colore
|
||||
local Color = EgtStdColor( 'TEAL')
|
||||
if s_nSimplifiedSection == 1 and nSliceNbr % 2 == 0 then
|
||||
Color = Color3d( s_dColorFactor * Color:getRed(), s_dColorFactor * Color:getGreen(), s_dColorFactor * Color:getBlue())
|
||||
end
|
||||
EgtSetColor( nSolidId, Color)
|
||||
end
|
||||
|
||||
-- 2) curve di uscita
|
||||
-- calcolo altezza finale del solido shell
|
||||
local ptE = EgtEP( vIds[1], GDB_ID.ROOT)
|
||||
local dH = ( ( ptE - ptSlicingPrev) * vtSlicingPrev / dCosAng) * ( dLen - EgtCurveLength( vIds[1])) / dLen
|
||||
dH = max( dH, 500 * GEO.EPS_SMALL)
|
||||
for i = 2, #vIds do
|
||||
CreateSolidFromCurve( vIds[i], nSolidGrpId, LayerParams, nSliceNbr, dH)
|
||||
end
|
||||
|
||||
EgtErase( nGrpTmp)
|
||||
return true
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------
|
||||
@@ -547,6 +802,7 @@ function RunCalcSolids.Exec()
|
||||
local nPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, PART .. nPartIndex) or EgtGetFirstNameInGroup( GDB_ID.ROOT, PART)
|
||||
while nPartId do
|
||||
|
||||
s_nPartId = nPartId
|
||||
if EgtGetInfo( nPartId, KEY_PART_ON_TABLE, 'b') then
|
||||
-- verifico se necessario calcolare il solido
|
||||
local bCalcSolid = EgtGetInfo( nPartId, KEY_CALC_SOLIDS, 'b') or false
|
||||
@@ -582,7 +838,7 @@ function RunCalcSolids.Exec()
|
||||
-- flag di interruzione perchè trovati solidi già ok
|
||||
local bSolidsOk = false
|
||||
-- indice layer ( per log)
|
||||
local nLayer = EgtGetInfo( vLayIds[ nIdx], KEY_SLICE_NBR, 'i')
|
||||
local nSliceNbr = EgtGetInfo( vLayIds[ nIdx], KEY_SLICE_NBR, 'i')
|
||||
-- scorro tutti i gruppi di contorni
|
||||
local nCrvGrpId = EgtGetFirstNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*") or GDB_ID.NULL
|
||||
while nCrvGrpId ~= GDB_ID.NULL do
|
||||
@@ -603,22 +859,34 @@ function RunCalcSolids.Exec()
|
||||
|
||||
local vIds = EgtGetAllInGroup( nTPathGrpId)
|
||||
|
||||
-- multiplanare
|
||||
-- slicing multiplanare
|
||||
if nSlicingType == SLICING_TYPE.MULTIPLANAR then
|
||||
LayerParams.vtSlicing = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_DIR, 'v')
|
||||
|
||||
if LayerParams.bSpiralVase then
|
||||
local dTransitionLen = EgtGetInfo( nPartId, KEY_SPIRAL_VASE_LEN, 'd') or 0
|
||||
-- a) spiral vase completo ( con transizione in altezza su tutto il layer)
|
||||
if dTransitionLen < GEO.EPS_SMALL then
|
||||
-- TO DO
|
||||
if nIdx == 1 then
|
||||
-- il primo layer va gestito come uno spiral vase con transizione parziale ( curva a quota costante e ultimo tratto che si alza)
|
||||
CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx])
|
||||
elseif nIdx == #vLayIds then
|
||||
-- gestione speciale per lead out e coasting
|
||||
CreateFullSpiralVaseMultiPlanarSolidsLastLayer( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx])
|
||||
else
|
||||
CreateFullSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx])
|
||||
end
|
||||
|
||||
-- b) spiral vase con transizione parziale
|
||||
else
|
||||
if nIdx == #vLayIds then
|
||||
-- ultimo layer non ha tratto finale rialzato quindi è un multiplanare standard
|
||||
-- ultimo layer è un multiplanare standard perchè non ha tratto finale che si alza
|
||||
CreateMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx])
|
||||
else
|
||||
CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx])
|
||||
end
|
||||
end
|
||||
-- c) multiplanare standard
|
||||
else
|
||||
CreateMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx])
|
||||
end
|
||||
@@ -650,13 +918,13 @@ function RunCalcSolids.Exec()
|
||||
|
||||
for i = 1, #vChainedIds do
|
||||
if #vChainedIds[i] == 1 then
|
||||
CreateSolidFromCurve( vChainedIds[i][1], nSolidGrpId, LayerParams, nLayer)
|
||||
CreateSolidFromCurve( vChainedIds[i][1], nSolidGrpId, LayerParams, nSliceNbr)
|
||||
else
|
||||
local nNewCrv = EgtCurveCompo( nSolidGrpId, vChainedIds[i], false)
|
||||
local dStrand = EgtGetInfo( vChainedIds[i][1], KEY_CRV_STRAND, 'd') or LayerParams.dStrand
|
||||
EgtSetInfo( nNewCrv, KEY_CRV_STRAND, dStrand)
|
||||
EgtSetInfo( nNewCrv, KEY_TYPE, TYPE.OUTER_SHELL)
|
||||
CreateSolidFromCurve( nNewCrv, nSolidGrpId, LayerParams, nLayer)
|
||||
CreateSolidFromCurve( nNewCrv, nSolidGrpId, LayerParams, nSliceNbr)
|
||||
EgtErase( nNewCrv)
|
||||
end
|
||||
end
|
||||
@@ -664,7 +932,7 @@ function RunCalcSolids.Exec()
|
||||
-- slicing standard
|
||||
else
|
||||
for i = 1, #vIds do
|
||||
CreateSolidFromCurve( vIds[i], nSolidGrpId, LayerParams, nLayer)
|
||||
CreateSolidFromCurve( vIds[i], nSolidGrpId, LayerParams, nSliceNbr)
|
||||
end
|
||||
end
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user