3dPrinting :
- migliorie nei riempimenti a zigzag per SolidFill - gestione SolidFill con buchi.
This commit is contained in:
+134
-89
@@ -226,24 +226,6 @@ local function VerifyPath( nCrvId, dStrand, vtSlicing, nGrp)
|
||||
return true
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------
|
||||
local function ComputeTrimSurfWithOverlaps( vIds, nSrfBase, sKeyOverlap, dStrand, nGrp, vtSlicing)
|
||||
|
||||
-- per ogni overlap creo le superfici con cui fare i trim
|
||||
local vSurfOffs = {}
|
||||
for i = 1, #vIds do
|
||||
local nOverlap = EgtGetInfo( vIds[i], sKeyOverlap, 'i')
|
||||
if not vSurfOffs[nOverlap] then
|
||||
local dNewOffs = nOverlap / 100 * dStrand
|
||||
local bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrfBase, nGrp, dNewOffs, vtSlicing)
|
||||
if bOk then
|
||||
vSurfOffs[nOverlap] = nSrfOffs
|
||||
end
|
||||
end
|
||||
end
|
||||
return vSurfOffs
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------
|
||||
--------------------- RIEMPIMENTI PIENI ----------------------------
|
||||
--------------------------------------------------------------------
|
||||
@@ -369,71 +351,109 @@ local function ComputeOffsetInfill( nSrf, dStrand, vtSlicing, sName, nType, vPtS
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function ComputeZigZagInfill( nSrf, dStrand, vtSlicing, sName, nType, vPtStart, nGrp)
|
||||
|
||||
local nChunk = EgtSurfFrChunkCount( nSrf)
|
||||
if nChunk == 0 then return end
|
||||
------------------------------------------------------------------
|
||||
local function FindOptimalZigZagDirection( nSrfId, nBorderSurf, dStrand, nGrp, frLoc)
|
||||
|
||||
local nCopySrf = EgtCopyGlob( nSrf, nGrp)
|
||||
if EgtSurfFrChunkCount( nSrf) == 0 then return end
|
||||
-- come direzione ottimale scelgo quella del lato più vicino al bordo oppure quella del
|
||||
-- lato più lungo nel caso in cui i lati fossero tutti sufficientemente lontani ( distanza > dStrand) dal bordo
|
||||
|
||||
local nFirst, nCnt = EgtExplodeSurf( nCopySrf)
|
||||
local frLoc = Frame3d( ORIG(), vtSlicing)
|
||||
local vIds = {}
|
||||
for nId = nFirst, nFirst + nCnt - 1 do
|
||||
local nGrpTmp = EgtGroup( nGrp, frLoc, GDB_RT.GLOB)
|
||||
|
||||
-- recupero outer curve
|
||||
local nCrvGrpId = EgtGetParent( nGrp)
|
||||
local nOuterCrv = EgtGetFirstNameInGroup( nCrvGrpId, OUTER_CRV)
|
||||
local nCopyOuterCrv = EgtCopyGlob( nOuterCrv, nGrpTmp)
|
||||
local nGrpTmp = EgtGroup( nGrp, frLoc, GDB_RT.GLOB) -- gruppo temporaneo per i conti
|
||||
local dTol = 1 + GEO.EPS_SMALL
|
||||
|
||||
-- recupero i contorni della curva di bordo
|
||||
local vBorderIds = GetPathsFromSurf( nBorderSurf, 'TmpBorder', 0, nGrpTmp)
|
||||
|
||||
-- recupero tutti i lati della superficie da riempire
|
||||
local vCrvIds = GetPathsFromSurf( nSrfId, 'Tmp', 0, nGrpTmp)
|
||||
local nId, nCnt = EgtExplodeCurveCompo( vCrvIds[1])
|
||||
|
||||
-- individuo i lati a distanza minima dal bordo tra cui cercare quello a lunghezza massima
|
||||
local vCheckIds = {}
|
||||
local vAllIds = {}
|
||||
local dMinDist = GEO.INFINITO
|
||||
for i = nId, nId + nCnt - 1 do
|
||||
|
||||
-- cerco il lato più lungo
|
||||
local vCrvIds = GetPathsFromSurf( nId, 'Tmp', nType, nGrpTmp)
|
||||
local dMaxLen = - GEO.INFINITO
|
||||
local dDist = GEO.INFINITO
|
||||
local vtDir
|
||||
|
||||
for j = 1, #vCrvIds do
|
||||
local nId, nCnt = EgtExplodeCurveCompo( vCrvIds[j])
|
||||
|
||||
-- cerco il lato più lungo
|
||||
for k = nId, nId + nCnt - 1 do
|
||||
local dCurrLen = EgtCurveLength( k)
|
||||
if dCurrLen > dMaxLen + GEO.EPS_SMALL then
|
||||
dMaxLen = dCurrLen
|
||||
end
|
||||
end
|
||||
-- tra i lati più lunghi scelgo quello più vicino al bordo
|
||||
for k = nId, nId + nCnt - 1 do
|
||||
local dCurrLen = EgtCurveLength( k)
|
||||
if abs( dMaxLen - dCurrLen) < 10 then
|
||||
local dCurrDist = EgtPointCurveDist( EgtMP( k), nCopyOuterCrv)
|
||||
if dCurrDist < dDist + 10 * GEO.EPS_SMALL then
|
||||
vtDir = EgtSV( k)
|
||||
dDist = dCurrDist
|
||||
end
|
||||
-- trovo la distanza minima dalle curve di bordo
|
||||
local dDist
|
||||
if #vBorderIds == 1 then
|
||||
dDist = EgtPointCurveDist( EgtMP( i), vBorderIds[1])
|
||||
else
|
||||
dDist = GEO.INFINITO
|
||||
for j = 1, #vBorderIds do
|
||||
local dCurrDist = EgtPointCurveDist( EgtMP( i), vBorderIds[j])
|
||||
if dCurrDist < dDist then
|
||||
dDist = dCurrDist
|
||||
end
|
||||
end
|
||||
end
|
||||
EgtErase( nGrpTmp)
|
||||
|
||||
-- se tratto sufficientemente vicino al bordo verifico se a distanza minima ( entro tolleranza dTol)
|
||||
if dDist < dStrand + GEO.EPS_SMALL then
|
||||
if abs( dDist - dMinDist) < dTol then
|
||||
table.insert( vCheckIds, i)
|
||||
elseif dDist < dMinDist - dTol then
|
||||
dMinDist = dDist
|
||||
vCheckIds = {i}
|
||||
end
|
||||
end
|
||||
|
||||
table.insert( vAllIds, i)
|
||||
end
|
||||
|
||||
-- se non ci sono curve sufficientemente vicine al bordo allora cerco il più lungo tra tutti i lati indipendentemente dalla loro distanza dal bordo
|
||||
if #vCheckIds == 0 then
|
||||
vCheckIds = vAllIds
|
||||
end
|
||||
|
||||
-- cerco il lato più lungo tra quelli selezionati
|
||||
local vtDir
|
||||
if #vCheckIds == 1 then
|
||||
vtDir = EgtSV( vCheckIds[1])
|
||||
else
|
||||
local dLen = - GEO.INFINITO
|
||||
for k = 1, #vCheckIds do
|
||||
local dCurrLen = EgtCurveLength( vCheckIds[k])
|
||||
if dCurrLen > dLen + GEO.EPS_SMALL then
|
||||
dLen = dCurrLen
|
||||
vtDir = EgtSV( vCheckIds[k])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
EgtErase( nGrpTmp)
|
||||
return vtDir
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------
|
||||
local function ComputeZigZagInfill( nSrf, dStrand, vtSlicing, sName, nType, vPtStart, nGrp, nBorderSurf)
|
||||
|
||||
if EgtSurfFrChunkCount( nSrf) == 0 then return end
|
||||
|
||||
local nCopySrf = EgtCopyGlob( nSrf, nGrp)
|
||||
local frLoc = Frame3d( ORIG(), vtSlicing)
|
||||
|
||||
-- analizzo tutti i chunk della superifice da riempire
|
||||
local nFirst, nSrfCnt = EgtExplodeSurf( nCopySrf)
|
||||
local vIds = {}
|
||||
for nSrfId = nFirst, nFirst + nSrfCnt - 1 do
|
||||
|
||||
-- trovo la direzione ottimale per la svuotatura in frLoc
|
||||
local vtDir = FindOptimalZigZagDirection( nSrfId, nBorderSurf, dStrand, nGrp, frLoc)
|
||||
local _, _, dAng = SphericalFromVector( vtDir)
|
||||
vtDir:toGlob( frLoc)
|
||||
|
||||
local nInd, nCnt = EgtGetSurfFrZigZagInfill( nId, nGrp, dStrand, dAng, false, false)
|
||||
if not nInd then return end
|
||||
for j = nInd, nInd + nCnt - 1 do
|
||||
EgtSetName( j, sName)
|
||||
EgtSetInfo( j, KEY_TYPE, nType)
|
||||
EgtSetInfo( j, KEY_ZIG_ZAG_DIR, vtDir)
|
||||
EgtSetInfo( j, KEY_ZIG_ZAG_INFILL, 1)
|
||||
EgtModifyCurveExtrusion( j, vtSlicing, GDB_RT.GLOB)
|
||||
table.insert( vIds, j)
|
||||
local nInd, nCnt = EgtGetSurfFrZigZagInfill( nSrfId, nGrp, dStrand, dAng, false, false)
|
||||
if nInd then
|
||||
for j = nInd, nInd + nCnt - 1 do
|
||||
EgtSetName( j, sName)
|
||||
EgtSetInfo( j, KEY_TYPE, nType)
|
||||
EgtSetInfo( j, KEY_ZIG_ZAG_DIR, vtDir)
|
||||
EgtSetInfo( j, KEY_ZIG_ZAG_INFILL, 1)
|
||||
EgtModifyCurveExtrusion( j, vtSlicing, GDB_RT.GLOB)
|
||||
table.insert( vIds, j)
|
||||
end
|
||||
end
|
||||
local vtS = EgtSV( nInd)
|
||||
EgtErase( nId)
|
||||
EgtErase( nSrfId)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1951,6 +1971,25 @@ end
|
||||
--------------------------------------------------------------------
|
||||
------------------ AUX SOLIDS -------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
local function ComputeTrimSurfWithOverlapsForAuxSolids( vIds, nSrfBase, dStrand, nGrp, vtSlicing)
|
||||
|
||||
-- per ogni valore di overlap creo le superfici con cui fare i trim
|
||||
local vSurfOffs = {}
|
||||
for i = 1, #vIds do
|
||||
local nOverlap = EgtGetInfo( vIds[i][1], KEY_AUX_SOLIDS_OVERLAP, 'i')
|
||||
if not vSurfOffs[nOverlap] then
|
||||
local dNewOffs = nOverlap / 100 * dStrand
|
||||
local bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrfBase, nGrp, dNewOffs, vtSlicing)
|
||||
if bOk then
|
||||
vSurfOffs[nOverlap] = nSrfOffs
|
||||
end
|
||||
end
|
||||
end
|
||||
return vSurfOffs
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
local function UpdateTrimSurfWithAuxSolidsOffset( nSrfSolid, nSrfBase, dStrand, nCrvGrp, vtSlicing)
|
||||
|
||||
-- offset della superifice del solido
|
||||
@@ -2033,10 +2072,11 @@ end
|
||||
local function AddExtraZigZag( nSrf, sName, dStrand, vtSlicing, nGrp, nSrfTrim)
|
||||
|
||||
local vIds = EgtGetNameInGroup( nGrp, sName)
|
||||
if not vIds then return end
|
||||
local vtDir = EgtSV( vIds[1], GDB_ID.ROOT)
|
||||
local vtYLoc = vtSlicing ^ vtDir
|
||||
|
||||
local nOuterLoop = EgtExtractSurfFrChunkLoops( nSrf, 0, nGrp)
|
||||
local nOuterLoop, nCnt = EgtExtractSurfFrChunkLoops( nSrf, 0, nGrp)
|
||||
|
||||
for i = 1, #vIds do
|
||||
local _, dParE = EgtCurveDomain( vIds[i])
|
||||
@@ -2045,7 +2085,7 @@ local function AddExtraZigZag( nSrf, sName, dStrand, vtSlicing, nGrp, nSrfTrim)
|
||||
local nExtraCrv = EgtLine( nGrp, ptS, ptE, GDB_RT.GLOB)
|
||||
-- verifico se la linea aggiuntiva serve
|
||||
local dDist = EgtPointCurveDist( EgtMP( nExtraCrv), nOuterLoop)
|
||||
if dDist < dStrand - 1 then
|
||||
if dDist < 0.5 * dStrand - 100 * GEO.EPS_SMALL then
|
||||
-- verifico se si trova nella regione ammissibile
|
||||
if EgtCurveWithRegionClassify( nExtraCrv, nSrfTrim) == GDB_CRC.IN then
|
||||
EgtInvertCurve( nExtraCrv)
|
||||
@@ -2056,14 +2096,24 @@ local function AddExtraZigZag( nSrf, sName, dStrand, vtSlicing, nGrp, nSrfTrim)
|
||||
EgtErase( nExtraCrv)
|
||||
end
|
||||
|
||||
EgtErase( nOuterLoop)
|
||||
for nId = nOuterLoop, nOuterLoop + nCnt - 1 do
|
||||
EgtErase( nId)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------
|
||||
local function CalcAuxSolidsPaths( nSliceGrp, nSolidGrp, LayerParams, vPtStart)
|
||||
|
||||
-- recupero i solidi ausiliari
|
||||
local vSolidIds = EgtGetAllInGroup( nSolidGrp)
|
||||
-- recupero i solidi ausiliari dividendoli per nome
|
||||
local vSolidIds = {}
|
||||
local nFirst = EgtGetFirstInGroup( nSolidGrp)
|
||||
while nFirst do
|
||||
local sName = EgtGetName( nFirst)
|
||||
local vIds = EgtGetNameInGroup( nSolidGrp, sName)
|
||||
table.insert( vSolidIds, vIds)
|
||||
nFirst = EgtGetNext( vIds[#vIds])
|
||||
end
|
||||
|
||||
-- scorro i gruppi di curve
|
||||
local nCrvGrp = EgtGetFirstNameInGroup( nSliceGrp, CONTOUR_GRP .. '*')
|
||||
@@ -2084,12 +2134,12 @@ local function CalcAuxSolidsPaths( nSliceGrp, nSolidGrp, LayerParams, vPtStart)
|
||||
if not nSrfBase then
|
||||
EgtOutLog( 'Warning : AuxSolids not possible (layer '..tostring( nIdx)..') - CalcPaths')
|
||||
else
|
||||
local vSurfOffs = ComputeTrimSurfWithOverlaps( vSolidIds, nSrfBase, KEY_AUX_SOLIDS_OVERLAP, LayerParams.dStrand, nSolidPathGrp, LayerParams.vtSlicing)
|
||||
|
||||
local vSurfOffs = ComputeTrimSurfWithOverlapsForAuxSolids( vSolidIds, nSrfBase, LayerParams.dStrand, nSolidPathGrp, LayerParams.vtSlicing)
|
||||
|
||||
for i = 1, #vSolidIds do
|
||||
-- creo la flat region corrispondente al solido ausiliario
|
||||
local sName = EgtGetName( vSolidIds[i])
|
||||
local nOverlap = EgtGetInfo( vSolidIds[i], KEY_AUX_SOLIDS_OVERLAP, 'i')
|
||||
local sName = EgtGetName( vSolidIds[i][1])
|
||||
local nOverlap = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_OVERLAP, 'i')
|
||||
local nSrfId = EgtSurfFlatRegion( nSolidPathGrp, vSolidIds[i])
|
||||
EgtSetName( nSrfId, AUX_SOLIDS_SRF)
|
||||
-- trim con la superficie di offset
|
||||
@@ -2098,13 +2148,13 @@ local function CalcAuxSolidsPaths( nSliceGrp, nSolidGrp, LayerParams, vPtStart)
|
||||
local nFirst, nCnt = EgtExplodeSurf( nSrfId)
|
||||
for j = 0, nCnt - 1 do
|
||||
local sNewName = sName .. EgtIf( j == 0, '', '_' .. tostring( j))
|
||||
local nInfillType = EgtGetInfo( vSolidIds[i], KEY_AUX_SOLIDS_INFILL, 'i')
|
||||
local nInfillType = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_INFILL, 'i')
|
||||
if nInfillType == INFILL_TYPE.OFFSET then
|
||||
ComputeOffsetInfill( nFirst + j, LayerParams.dStrand, LayerParams.vtSlicing, sNewName, TYPE.AUX_SOLID, vPtStart, nSolidPathGrp)
|
||||
-- aggiorno la trim surf
|
||||
UpdateTrimSurfWithAuxSolidsOffset( nFirst + j, nSrfBase, LayerParams.dStrand, nSolidPathGrp, LayerParams.vtSlicing)
|
||||
else
|
||||
ComputeZigZagInfill( nFirst + j, LayerParams.dStrand, LayerParams.vtSlicing, sNewName, TYPE.AUX_SOLID, vPtStart, nSolidPathGrp)
|
||||
ComputeZigZagInfill( nFirst + j, LayerParams.dStrand, LayerParams.vtSlicing, sNewName, TYPE.AUX_SOLID, vPtStart, nSolidPathGrp, vSurfOffs[nOverlap])
|
||||
-- aggiungo eventuale passata extra
|
||||
AddExtraZigZag( nFirst + j, sNewName, LayerParams.dStrand, LayerParams.vtSlicing, nSolidPathGrp, vSurfOffs[nOverlap])
|
||||
-- aggiorno la trim surf
|
||||
@@ -2112,11 +2162,6 @@ local function CalcAuxSolidsPaths( nSliceGrp, nSolidGrp, LayerParams, vPtStart)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- elimino le superfici utilizzate per il trim
|
||||
for k, v in pairs( vSurfOffs) do
|
||||
EgtErase( v)
|
||||
end
|
||||
end
|
||||
|
||||
-- verifico se il gruppo contine qualcosa
|
||||
@@ -2243,7 +2288,7 @@ function CalcPaths.Exec( nPartId)
|
||||
if LayerParams.nFloorType == INFILL_TYPE.OFFSET then
|
||||
ComputeOffsetInfill( nSurfInfill, LayerParams.dStrand, LayerParams.vtSlicing, INFILL_CRV, TYPE.INFILL, vPtStart, nGrpId)
|
||||
elseif LayerParams.nFloorType == INFILL_TYPE.ZIGZAG then
|
||||
ComputeZigZagInfill( nSurfInfill, LayerParams.dStrand, LayerParams.vtSlicing, INFILL_CRV, TYPE.INFILL, vPtStart, nGrpId)
|
||||
ComputeZigZagInfill( nSurfInfill, LayerParams.dStrand, LayerParams.vtSlicing, INFILL_CRV, TYPE.INFILL, vPtStart, nGrpId, nSurfInfill)
|
||||
end
|
||||
EgtErase( nSurfInfill)
|
||||
elseif nIdx > #vLayIds - LayerParams.nCeilNbr then
|
||||
|
||||
Reference in New Issue
Block a user