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
+358 -90
View File
@@ -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