diff --git a/LuaLibs/AddManData.lua b/LuaLibs/AddManData.lua index a002037..ff0e1c0 100644 --- a/LuaLibs/AddManData.lua +++ b/LuaLibs/AddManData.lua @@ -146,6 +146,7 @@ KEY_EXTRA_SHELL_WIPE_DIR = "ExtraShellWipeDir" -- Solidi ausiliari KEY_AUX_SOLIDS_STRAND = "AuxSolidsStrandW" +KEY_AUX_SOLIDS_SHELLS_NBR = "AuxSolidsStrandCount" KEY_AUX_SOLIDS_OVERLAP = "AuxSolidsOverlap" KEY_AUX_SOLIDS_INFILL = "AuxSolidsInfill" KEY_AUX_SOLIDS_PRINT_ORDER = "AuxSolidsStrandOrder" diff --git a/LuaLibs/CalcPaths.lua b/LuaLibs/CalcPaths.lua index f591dfb..da8f8f1 100644 --- a/LuaLibs/CalcPaths.lua +++ b/LuaLibs/CalcPaths.lua @@ -321,7 +321,7 @@ local function CalcInfillPaths( nLayId, nInfillGrp, LayerParams) if bNoOverlap then EgtOutLog( 'Warning : Infill without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') end - + for i = 1, #vIds do local nNewId = EgtCopyGlob( vIds[i], nInfillPathGrp) -- eventuale inversione della curva per link @@ -442,39 +442,50 @@ local function ReorderPath( vOldIds, vNewIds) end --------------------------------------------------------------------------- -local function ComputeOffsetSolidFill( nSrf, dStrand, vtSlicing, sName, nType, nGrp, vPtStart, vOldIds) +local function ComputeOffsetShells( nSrf, dStrand, vtSlicing, sName, nType, nGrp, vPtStart, vOldIds, nMaxShells) + if nSrf == GDB_ID.NULL then return true end + if not nMaxShells then nMaxShells = GEO.INFINITO end + if nMaxShells == 0 then return true end + -- nSrf è già la prima superficie da cui estrarre i bordi, quindi il primo offset non va fatto local dOffs = 0 local nSrfOffs = EgtCopyGlob( nSrf, nGrp) - while nSrfOffs and nSrfOffs ~= GDB_ID.NULL do + for i = 1, nMaxShells do -- estraggo i contorni local vNewIds = GetPathsFromSurf( nSrfOffs, sName, nType, nGrp, vPtStart) if vNewIds then -- riordino local vNewOrder = ReorderPath( vOldIds, vNewIds) or vNewIds - - -- verifico fattibilità - local k = 1 - while k <= #vNewOrder do - if VerifyPath( vNewOrder[k], dStrand, vtSlicing, nGrp) then - k = k + 1 - else - -- se non è fattibile lo rimuovo dalla table per non ritrovarlo nello step successivo - table.remove( vNewOrder, k) - end - end vOldIds = vNewOrder + else + return false + end + + EgtErase( nSrfOffs) + + -- se sei già all'ultima shell richiesta non è necessario calcolare offset successivo + if i == nMaxShells then + return true end -- offset successivo - EgtErase( nSrfOffs) dOffs = dOffs - dStrand nSrfOffs = ComputeSurfOffset( nSrf, nGrp, dOffs) + if not nSrfOffs then + -- errore nel calcolo della superficie + return false + elseif nSrfOffs == GDB_ID.NULL then + -- spazio esaurito, termino la funzione + return true + end end + + return true end + ------------------------------------------------------------------ local function FindOptimalZigZagDirection( nSrfId, nBorderSurf, dStrand, nGrp, frLoc) @@ -554,7 +565,7 @@ end -------------------------------------------------------------------- local function ComputeZigZagSolidFill( nSrf, dStrand, vtSlicing, sName, nType, nGrp, nBorderSurf) - if EgtSurfFrChunkCount( nSrf) == 0 then return end + if nSrf == GDB_ID.NULL then return end local nCopySrf = EgtCopyGlob( nSrf, nGrp) local frLoc = Frame3d( ORIG(), vtSlicing) @@ -624,7 +635,10 @@ local function CalcSolidFillPath( nLayId, LayerParams, vPtStart, nFillType) local nPathGrp = EgtGetFirstNameInGroup( vCrvGrps[i], PATH_GRP) local nLast = EgtGetLastNameInGroup( nPathGrp, SHELL_CRV .. '*') or EgtGetLastNameInGroup( nPathGrp, EXTRA_SHELL_CRV .. '*') local vOldIds = EgtGetNameInGroup( nPathGrp, EgtGetName( nLast)) - ComputeOffsetSolidFill( nSrfToFill, dDist, LayerParams.vtSlicing, INFILL_CRV, TYPE.INFILL, nInfillPathGrp, vPtStart, vOldIds) + if not ComputeOffsetShells( nSrfToFill, dDist, LayerParams.vtSlicing, INFILL_CRV, TYPE.INFILL, nInfillPathGrp, vPtStart, vOldIds) then + EgtOutLog( 'Error : creation of SolidFill failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + table.insert( s_vErr, 'layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of SolidFill failed') + end elseif nFillType == FILL_TYPE.ZIGZAG then ComputeZigZagSolidFill( nSrfToFill, dDist, LayerParams.vtSlicing, INFILL_CRV, TYPE.INFILL, nInfillPathGrp) end @@ -2411,6 +2425,8 @@ local function CreateShellNbrSurfaces( nGrp, nShellsNbr) EgtSetInfo( nSrfId, KEY_ASSOCIATED_CRVS, vCrvIds) end end + + return nSrfGrp end -------------------------------------------------------------------- @@ -2422,7 +2438,7 @@ local function ComputeMaxShellNbrDiff( nSrf, nShellNbrSurfGrp) local nShellNbrSrf = EgtGetFirstNameInGroup( nShellNbrSurfGrp, SHELL_NBR_SURF .. tostring( nId)) while nShellNbrSrf do -- se interessa la regione considerata aggiorno il nMaxShellNbrDiff - if not EgtSurfFrTestExternal( nSrf, nShellNbrSrf) then + if not EgtSurfFrTestExternal( nSrf, nShellNbrSrf) then nMaxShellNbrDiff = nId end @@ -2834,22 +2850,21 @@ local function UpdateTrimSurfWithAuxSolidsZigZag( nAuxSolidsGrp, sName, nSrfBase local nSrfFatCrv = EgtSurfFrFatCurve( nGrpTmp, vCrvs[i], dStrand * 0.5 + 10 * GEO.EPS_SMALL, false) local nOffsP = EgtExtractSurfFrChunkLoops( nSrfFatCrv, 0, nGrpTmp) local nFirst, nCnt = EgtExplodeCurveCompo( nOffsP, nGrpTmp) - + -- cerco tratti lineari orientati ortogonalmente alla direzione di svuotatura local nRes = EgtCurveCompo( nGrpTmp, {nFirst}) local nInd = nFirst + 1 while nInd < nFirst + nCnt do local vtCurrDir = EgtSV( nInd) local nType = EgtGetType( nInd) - - -- se è linea ortognale alla direzione della svuotatura la approssimo - if nType == GDB_TY.CRV_LINE and abs( vtDir * vtCurrDir) < 10 * GEO.EPS_SMALL then + -- se è linea ortogonale alla direzione della svuotatura la approssimo + if nType == GDB_TY.CRV_LINE and abs( vtDir * vtCurrDir) < 0.1 then -- cerco ultima curva con lo stesso orientamento local nLastValidId = nInd local nInd2 = nInd + 1 while nInd2 < nFirst + nCnt do - nType = EgtGetType( nInd2) - if nType == GDB_TY.CRV_LINE then + local nType2 = EgtGetType( nInd2) + if nType2 == GDB_TY.CRV_LINE and not AreSameOrOppositeVectorApprox( EgtSV( nInd2), vtDir) then if AreSameVectorApprox( EgtSV( nInd2), vtCurrDir) then nLastValidId = nInd2 else @@ -2925,28 +2940,8 @@ end ------------------------------------------------------------------- local function ComputeAuxSolidsGenericInfill( nSrf, dStrand, vtSlicing, sName, nPathGrp, vPtStart, nOrigSurf, dOverlap, nAuxSolidsGrp, bLink) - - -- estraggo i contorni della superficie ( perimetro) - GetPathsFromSurf( nSrf, sName, TYPE.AUX_SOLID, nPathGrp, vPtStart) - - -- preparo la superficie con cui fare trim degli infill - local dOffs = dStrand * ( 1 - dOverlap / 100) - local nSrfTrim = ComputeSurfOffset( nSrf, nPathGrp, - dOffs) - if not nSrfTrim then - -- tento senza overlap - nSrfTrim = ComputeSurfOffset( nSrf, nPathGrp, - dStrand) - if not nSrfTrim then - -- errore - EgtOutLog( 'Error : creation of AuxSolid Infill region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - table.insert( s_vErr, 'layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid infill region failed') - return - else - EgtOutLog( 'Warning : AuxSolid Infill without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - end - elseif nSrfTrim == GDB_ID.NULL then - EgtOutLog( 'Warning : AuxSolid Infill not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') - return - end + + if nSrf == GDB_ID.NULL then return end -- recupero gli infill associati local sNameInfill = AUX_SOLIDS_INFILL_CRV .. tostring( nOrigSurf) @@ -2961,7 +2956,7 @@ local function ComputeAuxSolidsGenericInfill( nSrf, dStrand, vtSlicing, sName, n UpdateInvertInfo( nCrv) end - local nRes, nCnt = EgtTrimCurveWithRegion( nCrv, nSrfTrim, true, true) + local nRes, nCnt = EgtTrimCurveWithRegion( nCrv, nSrf, true, true) for nId = nRes, nRes + nCnt - 1 do -- verifico se lunghezza minima local dLen = EgtCurveLength( nId) @@ -2970,7 +2965,7 @@ local function ComputeAuxSolidsGenericInfill( nSrf, dStrand, vtSlicing, sName, n else EgtSetName( nId, sName) EgtSetInfo( nId, KEY_TYPE, TYPE.INFILL) - EgtSetInfo( nId, KEY_ASSOCIATED_SURF, nSrfTrim) + EgtSetInfo( nId, KEY_ASSOCIATED_SURF, nSrf) EgtModifyCurveExtrusion( nId, vtSlicing) end end @@ -3016,9 +3011,15 @@ local function CalcAuxSolidsPaths( nSliceGrp, nSolidGrp, LayerParams, vPtStart) local dStrand = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_STRAND, 'd') local dOverlap = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_OVERLAP, 'd') local nOrigSurf = EgtGetInfo( vSolidIds[i][1], KEY_ORIGINAL_SURF, 'i') + local nInfillType = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_INFILL, 'i') local bInfillLink = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_INFILL_LINK, 'b') - local nSrfId = EgtSurfFlatRegion( nSolidPathGrp, vSolidIds[i]) + local nShells = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_SHELLS_NBR, 'i') + if nInfillType == FILL_TYPE.OFFSET then + -- realizzo le shells insieme al riempimento + nShells = 0 + end + local nSrfId = EgtSurfFlatRegion( nSolidPathGrp, vSolidIds[i]) if nSrfId then EgtSetName( nSrfId, AUX_SOLIDS_SRF) -- calcolo superficie con cui fare trim @@ -3039,31 +3040,54 @@ 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][1], KEY_AUX_SOLIDS_INFILL, 'i') + + -- calcolo shells + if not ComputeOffsetShells( nFirst + j, dStrand, LayerParams.vtSlicing, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, vPtStart, nil, nShells) then + EgtOutLog( 'Error : creation of AuxSolid shells failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + table.insert( s_vErr, 'layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid shells failed') + end - if nInfillType == FILL_TYPE.NONE then - -- estraggo i contorni della superficie ( serve solo perimetro) - GetPathsFromSurf( nFirst + j, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, vPtStart) - -- aggiorno la trim surf - UpdateTrimSurfWithAuxSolidsOffset( nFirst + j, nSrfBase, dStrand, nSolidPathGrp) - - elseif nInfillType == FILL_TYPE.OFFSET then - ComputeOffsetSolidFill( nFirst + j, dStrand, LayerParams.vtSlicing, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, vPtStart) - -- aggiorno la trim surf - UpdateTrimSurfWithAuxSolidsOffset( nFirst + j, nSrfBase, dStrand, nSolidPathGrp) - - elseif nInfillType == FILL_TYPE.ZIGZAG then - ComputeZigZagSolidFill( nFirst + j, dStrand, LayerParams.vtSlicing, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, nTrimSurf) - -- aggiungo eventuale passata extra - AddExtraZigZag( nFirst + j, sNewName, dStrand, LayerParams.vtSlicing, nSolidPathGrp, nTrimSurf) - -- aggiorno la trim surf - UpdateTrimSurfWithAuxSolidsZigZag( nSolidPathGrp, sNewName, nSrfBase, dStrand, nFirst + j) - + -- calcolo la superficie per il riempimento + local nSrfFill + if nShells > 0 then + local dOffs = ( nShells - dOverlap / 100) * dStrand + nSrfFill = ComputeSurfOffset( nFirst + j, nSolidPathGrp, - dOffs) + if not nSrfFill then + EgtOutLog( 'Error : creation of AuxSolid infill region failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + table.insert( s_vErr, 'layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid infill region failed') + elseif nSrfFill == GDB_ID.NULL then + EgtOutLog( 'Warning : AuxSolids infill not possible (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + end + else + -- la superficie per il riempimento è la surf del solido + nSrfFill = nFirst + j + end + + -- riempimento + if nInfillType == FILL_TYPE.OFFSET then + -- recupero le shells + if not ComputeOffsetShells( nSrfFill, dStrand, LayerParams.vtSlicing, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, vPtStart) then + EgtOutLog( 'Error : creation of AuxSolid offset infill failed (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + table.insert( s_vErr, 'layer ' .. EgtNumToString( s_nCurrIdx) .. ' : creation of AuxSolid offset infill failed') + end + elseif nInfillType == FILL_TYPE.ZIGZAG then + ComputeZigZagSolidFill( nSrfFill, dStrand, LayerParams.vtSlicing, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, EgtIf( nShells == 0, nTrimSurf, nil)) + if nShells == 0 then + -- aggiungo eventuale passata extra + AddExtraZigZag( nSrfFill, sNewName, dStrand, LayerParams.vtSlicing, nSolidPathGrp, nTrimSurf) + end + elseif nInfillType ~= FILL_TYPE.NONE then + ComputeAuxSolidsGenericInfill( nSrfFill, dStrand, LayerParams.vtSlicing, sNewName, nSolidPathGrp, vPtStart, nOrigSurf, dOverlap, nSolidGrp, bInfillLink) + end + + -- aggiorno la superficie di trim con il solido ausiliario + if nShells == 0 and nInfillType == FILL_TYPE.ZIGZAG then + -- gestione speciale perchè non è detto che le passate corrispondano esattamente al solido + UpdateTrimSurfWithAuxSolidsZigZag( nSolidPathGrp, sNewName, nSrfBase, dStrand, nFirst + j) else - ComputeAuxSolidsGenericInfill( nFirst + j, dStrand, LayerParams.vtSlicing, sNewName, nSolidPathGrp, vPtStart, nOrigSurf, dOverlap, nSolidGrp, bInfillLink) - -- aggiorno la trim surf UpdateTrimSurfWithAuxSolidsOffset( nFirst + j, nSrfBase, dStrand, nSolidPathGrp) end + end end else @@ -3110,9 +3134,7 @@ function CalcPaths.Exec( nPartId) -- regioni con diverso numero di passate local nShellNbrGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], SHELL_NBR_GRP) - local nMaxShell = max( LayerParams.nShellsNbr, LayerParams.nFloorNbr, LayerParams.nCeilNbr) - CreateShellNbrSurfaces( nShellNbrGrp, nMaxShell) - local nShellNbrSurfGrp = EgtGetFirstGroupInGroup( nShellNbrGrp or GDB_ID.NULL) + local nShellNbrSurfGrp = CreateShellNbrSurfaces( nShellNbrGrp, LayerParams.nShellsNbr) -- recupero gli start point per il layer local vPtStart = GetLayerStartPoint( vLayIds[nIdx], LayerParams.vtSlicing) @@ -3265,4 +3287,4 @@ function CalcPaths.Exec( nPartId) end --------------------------------------------------------------------- -return CalcPaths +return CalcPaths \ No newline at end of file diff --git a/LuaLibs/CalcSlices.lua b/LuaLibs/CalcSlices.lua index 959f229..6e819e3 100644 --- a/LuaLibs/CalcSlices.lua +++ b/LuaLibs/CalcSlices.lua @@ -133,6 +133,7 @@ local function GetAuxSolidsParams( nId) local AuxSolidsParam = {} ReadParam( nId, KEY_AUX_SOLIDS_STRAND, 'd', s_dStrand, AuxSolidsParam) + ReadParam( nId, KEY_AUX_SOLIDS_SHELLS_NBR, 'i', 0, AuxSolidsParam) ReadParam( nId, KEY_AUX_SOLIDS_OVERLAP, 'd', 0, AuxSolidsParam) ReadParam( nId, KEY_AUX_SOLIDS_INFILL, 'i', FILL_TYPE.NONE, AuxSolidsParam) ReadParam( nId, KEY_AUX_SOLIDS_PRINT_ORDER, 'i', PRINT_ORDER.EXT_INT, AuxSolidsParam) diff --git a/LuaLibs/CalcToolPath.lua b/LuaLibs/CalcToolPath.lua index 9987634..5be7b9d 100644 --- a/LuaLibs/CalcToolPath.lua +++ b/LuaLibs/CalcToolPath.lua @@ -670,6 +670,7 @@ local function VerifyInfillLink( nLinkId, nCurr, nNext, vIds, dStrand, nGrpTmp) if nCnt > 1 then return false end -- verifico se tratti lineari paralleli al setto sono sufficientemente lontani + local dMinDist = dStrand * 0.5 local nLinkLoc = EgtCopyGlob( nLinkId, nGrpTmp) local _, dParELink = EgtCurveDomain( nLinkLoc) local nCurrLoc = EgtCopyGlob( nCurr, nGrpTmp) @@ -684,7 +685,7 @@ local function VerifyInfillLink( nLinkId, nCurr, nNext, vIds, dStrand, nGrpTmp) -- verifico distanza local nCrvTest = EgtCurveCompoFromPoints( nGrpTmp, { EgtUP( nCurrLoc, dPar-1), EgtUP( nCurrLoc, dPar)}) local dDist = EgtPointCurveDist( EgtUP( nLinkLoc, dParCrv - 0.5), nCrvTest) - if dDist < dStrand * 0.5 + GEO.EPS_SMALL then + if dDist < dMinDist + GEO.EPS_SMALL then return false end end @@ -703,7 +704,7 @@ local function VerifyInfillLink( nLinkId, nCurr, nNext, vIds, dStrand, nGrpTmp) -- verifico distanza local nCrvTest = EgtCurveCompoFromPoints( nGrpTmp, { EgtUP( nCurrLoc, dPar), EgtUP( nCurrLoc, dPar + 1)}) local dDist = EgtPointCurveDist( EgtUP( nLinkLoc, dParCrv - 0.5), nNextLoc) - if dDist < dStrand * 0.5 + GEO.EPS_SMALL then + if dDist < dMinDist + GEO.EPS_SMALL then return false end end @@ -955,14 +956,14 @@ local function CalcAuxSolidsToolPath( nAuxSolidsGrp, nAuxSolidsPathGrp, nTpathGr local dWipeDir = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_WIPE_DIR, 'd') -- copio i percorsi nel gruppo toolpath - local vIds = AddCurvesToToolPath( vEntIds, nTpathGrpId, EgtIf( nFillType == FILL_TYPE.OFFSET, nOrder, PRINT_ORDER.EXT_INT), LayerParams.bInvert, LayerParams.vtSlicing, LayerParams.dLayHeight) + local vIds = AddCurvesToToolPath( vEntIds, nTpathGrpId, nOrder, LayerParams.bInvert, LayerParams.vtSlicing, LayerParams.dLayHeight) -- assegno strand for i = 1, #vIds do EgtSetInfo( vIds[i], KEY_CRV_STRAND, dStrand) end - -- aggiungo link e offset lead point + -- distinguo le shell dal riempimento local vShells = {} local vInfill = {} for i = 1, #vIds do @@ -975,7 +976,8 @@ local function CalcAuxSolidsToolPath( nAuxSolidsGrp, nAuxSolidsPathGrp, nTpathGr end end - if nFillType == FILL_TYPE.OFFSET or nFillType == FILL_TYPE.NONE then + -- aggiungo link e offset lead point sulle shell + if #vShells > 0 then local nLinkType = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_LINK_TYPE, 'i') local dLinkParam = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_LINK_PARAM, 'd') local dSPOffset = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_SP_OFFSET, 'd') @@ -984,9 +986,11 @@ local function CalcAuxSolidsToolPath( nAuxSolidsGrp, nAuxSolidsPathGrp, nTpathGr local nFirstCopy = EgtCopyGlob( vShells[1], nTpathGrpId) -- necessaria per avere il corretto offset lead point sulla shell esterna nel caso di link AddLink( vShells, nTpathGrpId, nLinkType, dLinkParam, dSPOffset, nOrder, LayerParams.vtSlicing) AddOffsetLeadPoint( vShells, nFirstCopy, dLPOffset, nLinkType) - - elseif nFillType & FILL_CATEGORY.INFILL ~= 0 then - local bInfillLink = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_INFILL, 'b') + end + + -- aggiungo eventuale link su infill + if nFillType & FILL_CATEGORY.INFILL ~= 0 then + local bInfillLink = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_INFILL_LINK, 'b') if bInfillLink then CalcInfillLink( vInfill, nAuxSolidsPathGrp, dStrand, LayerParams) end diff --git a/Version.lua b/Version.lua index f000a69..409ea78 100644 --- a/Version.lua +++ b/Version.lua @@ -1,4 +1,4 @@ -- Version.lua by Egaltech s.r.l. 2023/02/28 -- Gestione della versione di 3dPrinting -VERSION = '2.5f2' \ No newline at end of file +VERSION = '2.5g1' \ No newline at end of file