diff --git a/LuaLibs/AddManData.lua b/LuaLibs/AddManData.lua index 525b6ed..c29aab0 100644 --- a/LuaLibs/AddManData.lua +++ b/LuaLibs/AddManData.lua @@ -34,6 +34,7 @@ SURF_LOOP = "SurfLoop" MIN_LEN = 0.1 MIN_AREA = 0.01 MIN_RIBS_LEN = 2 +MIN_INFILL_LEN = 2 -- Parametri di lavorazione SEC_DEFAULT = "Default" @@ -55,10 +56,6 @@ KEY_TYPE = "Type" KEY_LINK_TYPE = "LinkType" KEY_LINK_PARAM = "LinkParam" KEY_LINK_ZUP = "LinkZup" -KEY_FLOOR_NBR = "FloorCount" -KEY_FLOOR_TYPE = "FloorType" -KEY_CEIL_NBR = "CeilCount" -KEY_CEIL_TYPE = "CeilType" KEY_SPEED = "Speed" KEY_FEED = "Feed" KEY_EXT_FEED = "ExtFeed" @@ -81,7 +78,26 @@ KEY_COASTING_FEED = "CoastingFeed" KEY_WIPE_LEN = "WipeLen" KEY_WIPE_DIR = "WipeDir" KEY_WIPE_FEEDPU = "WipeFeedPu" -KEY_TOOL_DIAM = "ToolDiam" +KEY_TOOL_DIAM = "ToolDiam" + +-- Solid Fill +KEY_FLOOR_NBR = "FloorCount" +KEY_FLOOR_TYPE = "FloorType" +KEY_CEIL_NBR = "CeilCount" +KEY_CEIL_TYPE = "CeilType" +KEY_FILL_TYPE = "FillType" + +-- Infill +KEY_INFILL_TYPE = "InfillType" +KEY_INFILL_DENSITY = "InfillDensity" +KEY_INFILL_OVERLAP = "InfillOverlap" +KEY_INFILL_GRID_OVERLAP = "InfillGridOverlap" +KEY_INFILL_DIR = "InfillDirection" +KEY_INFILL_OFFSET_X = "InfillOffsetX" +KEY_INFILL_OFFSET_Y = "InfillOffsetY" +KEY_INFILL_COASTING = "InfillCoasting" +KEY_INFILL_WIPE = "InfillWipe" +KEY_INFILL_WIPE_DIR = "InfillWipeDir" -- Ribs KEY_RIBS_TYPE = "RibsType" @@ -125,12 +141,18 @@ KEY_EXTRA_SHELL_WIPE = "ExtraShellWipe" KEY_EXTRA_SHELL_WIPE_DIR = "ExtraShellWipeDir" -- Solidi ausiliari +KEY_AUX_SOLIDS_OVERLAP = "AuxSolidsOverlap" KEY_AUX_SOLIDS_INFILL = "AuxSolidsInfill" KEY_AUX_SOLIDS_PRINT_ORDER = "AuxSolidsStrandOrder" -KEY_AUX_SOLIDS_OVERLAP = "AuxSolidsOverlap" KEY_AUX_SOLIDS_LINK_TYPE = "AuxSolidsLinkType" -KEY_AUX_SOLIDS_SP_OFFSET = "AuxSolidsStartPointOffsetOnSlice" KEY_AUX_SOLIDS_LINK_PARAM = "AuxSolidsLinkParam" +KEY_AUX_SOLIDS_SP_OFFSET = "AuxSolidsStartPointOffsetOnSlice" +KEY_AUX_SOLIDS_LP_OFFSET = "AuxSolidsOffsetLeadPoint" +KEY_AUX_SOLIDS_DENSITY = "AuxSolidsDensity" +KEY_AUX_SOLIDS_DIR = "AuxSolidsDirection" +KEY_AUX_SOLIDS_OFFSET_X = "AuxSolidsOffsetX" +KEY_AUX_SOLIDS_OFFSET_Y = "AuxSolidsOffsetY" +KEY_AUX_SOLIDS_GRID_OVERLAP = "AuxSolidsGridOverlap" KEY_AUX_SOLIDS_COASTING_LEN = "AuxSolidsCoastingLen" KEY_AUX_SOLIDS_WIPE_LEN = "AuxSolidsWipeLen" KEY_AUX_SOLIDS_WIPE_DIR = "AuxSolidsWipeDir" @@ -156,7 +178,14 @@ KEY_ASSOCIATED_CRVS = "AssociatedCrvs" KEY_ORIGINAL_SURF = "OriginalSurf" KEY_HAS_SOLIDS = "Solids" KEY_BOX_MIN_Z = "PartBoxMinZ" -KEY_START_POINT = "StartPoint" +KEY_ORIGINAL_START_POINT = "OriginalStartPoint" +KEY_FIRST_SOLID_LAY = "FirstSolidLay" +KEY_LAST_SOLID_LAY = "LastSolidLay" +KEY_ASSOCIATED_TP_CRV = "AssociatedToolPathCrv" +KEY_ASSOCIATED_P_CRV = "AssociatedPathCrv" +KEY_INTERNAL_SRF_LOOP = "InternalSrfLoop" +KEY_PREV_CRV = "PrevCrv" +KEY_NEXT_CRVS = "NextCrvs" SLICING_TYPE = { VERTICAL = 1, @@ -211,10 +240,21 @@ LEAD_TYPE = { ARC = 3, } -INFILL_TYPE = { - NONE = 1, - OFFSET = 2, - ZIGZAG = 3, +FILL_CATEGORY = { + NONE = 0, + SOLID_FILL = 16, + INFILL = 32, +} + +FILL_TYPE = { + NONE = 0, + OFFSET = 16, + ZIGZAG = 17, + LINES = 32, + GRID = 33, + ZIG_ZAG_GRID = 34, + HONEYCOMB = 35, + HONEYCOMB_GRID = 36, } RIB_TYPE = { @@ -293,9 +333,14 @@ SHELL_NBR_CRV = "ShellNbrRegion" SHELL_NBR_SURF = "ShellNbrSurf" AUX_SOLIDS_GRP = "AuxSolids" +AUX_SOLIDS_INFILL_GRP = "InfillAuxSolids" AUX_SOLIDS_CRV = "AuxSolid" +AUX_SOLIDS_INFILL_CRV = "InfillAuxSolid" AUX_SOLIDS_SRF = "SrfAuxSolid" +INFILL_GRP = "Infill" +INFILL_CRV = "InfillCrv" + --------------------------------------------------------------------- -- parametri calcolo tempi, F ed S LAY_TFSCALC = "TFSCalc" diff --git a/LuaLibs/CalcPaths.lua b/LuaLibs/CalcPaths.lua index 9094963..cd42118 100644 --- a/LuaLibs/CalcPaths.lua +++ b/LuaLibs/CalcPaths.lua @@ -27,10 +27,6 @@ local function GetLayerParamsForPathCalc() LayerParams.dLayHeight = EgtGetInfo( s_nPartId, KEY_SLICE_STEP, 'd') LayerParams.nStrandOverlap = EgtGetInfo( s_nPartId, KEY_STRAND_OVERLAP, 'i') or 0 LayerParams.dOffs = EgtGetInfo( s_nPartId, KEY_OFFSET_SLICE, 'd') - LayerParams.nFloorNbr = EgtGetInfo( s_nPartId, KEY_FLOOR_NBR, 'i') or 0 - LayerParams.nFloorType = EgtGetInfo( s_nPartId, KEY_FLOOR_TYPE, 'i') or INFILL_TYPE.ZIGZAG - LayerParams.nCeilNbr = EgtGetInfo( s_nPartId, KEY_CEIL_NBR, 'i') or 0 - LayerParams.nCeilType = EgtGetInfo( s_nPartId, KEY_CEIL_TYPE, 'i') or INFILL_TYPE.ZIGZAG LayerParams.vtSlicing = EgtGetInfo( s_nPartId, KEY_SLICING_DIR, 'v') LayerParams.bPrintInvert = ( EgtGetInfo( s_nPartId, KEY_PRINT_DIRECTION, 'i') == PRINT_DIRECTION.CW) LayerParams.vPrintOrder = EgtGetInfo( s_nPartId, KEY_PRINT_ORDER, 'vi') or { 1, 2, 3, 4, 5, 6, 7, 8} @@ -40,6 +36,14 @@ local function GetLayerParamsForPathCalc() LayerParams.dShellNbrCoasting = EgtGetInfo( s_nPartId, KEY_SHELL_NBR_COASTING, 'd') LayerParams.dShellNbrWipe = EgtGetInfo( s_nPartId, KEY_SHELL_NBR_WIPE, 'd') LayerParams.dShellNbrWipeDir = EgtGetInfo( s_nPartId, KEY_SHELL_NBR_WIPE_DIR, 'd') + -- parametri solid fill + LayerParams.nFloorNbr = EgtGetInfo( s_nPartId, KEY_FLOOR_NBR, 'i') or 0 + LayerParams.nFloorType = EgtGetInfo( s_nPartId, KEY_FLOOR_TYPE, 'i') or FILL_TYPE.OFFSET + LayerParams.nCeilNbr = EgtGetInfo( s_nPartId, KEY_CEIL_NBR, 'i') or 0 + LayerParams.nCeilType = EgtGetInfo( s_nPartId, KEY_CEIL_TYPE, 'i') or FILL_TYPE.OFFSET + -- parametri infill + LayerParams.nInfillOverlap = EgtGetInfo( s_nPartId, KEY_INFILL_OVERLAP, 'i') or 0 + LayerParams.nInfillType = EgtGetInfo( s_nPartId, KEY_INFILL_TYPE, 'i') or FILL_TYPE.NONE -- eventuale modifica dei parametri per gestire correttamente il caso spiral vase if LayerParams.bSpiralVase then @@ -72,11 +76,13 @@ local function UpdateInvertInfo( nId) end ---------------------------------------------------------------------- -local function ComputeSurfOffset( nSrf, nGrpId, dOffs, vtSlicing) +local function ComputeSurfOffset( nSrf, nGrpId, dOffs, vtSlicing, nOffsType) + -- tipologia di offset + if not nOffsType then nOffsType = GDB_OT.FILLET end -- gruppo temporaneo locale local nGrpTmp = EgtGroup( nGrpId, Frame3d( ORIG(), vtSlicing), GDB_RT.GLOB) local nCopySrf = EgtCopyGlob( nSrf, nGrpTmp) or GDB_ID.NULL - local bOk = EgtSurfFrOffset( nCopySrf, dOffs) + local bOk = EgtSurfFrOffset( nCopySrf, dOffs, nOffsType) local bExists = EgtSurfFrChunkCount( nCopySrf) > 0 if not bOk or not bExists then EgtErase( nCopySrf) @@ -167,6 +173,7 @@ local function GetPathsFromSurf( nSrfId, sName, nType, nGrpId, vPtStart) -- se è loop interno lo inverto per averlo orientato in senso antiorario if nInd > 0 then EgtInvertCurve( nCrvId + nInd) + EgtSetInfo( nCrvId + nInd, KEY_INTERNAL_SRF_LOOP, true) end -- verifico soddisfi i requisiti (lunghezza e area) @@ -190,7 +197,8 @@ local function VerifyPath( nCrvId, dStrand, vtSlicing, nGrp) local _, _, dArea = EgtCurveArea( nCrvId) - -- verifico se esiste l'offset (permetto una piccola sovrapposizione) + -- verifico se esiste l'offset ( permetto una piccola sovrapposizione) + -- TODO migliorare il controllo per verificare se sovrapposizione local dAllowedOverlap = 1 local nRes, nCnt = EgtOffsetCurveAdv( nCrvId, - dStrand / 2 + dAllowedOverlap) -- se errore ritento con valore leggermente modificato @@ -211,7 +219,7 @@ local function VerifyPath( nCrvId, dStrand, vtSlicing, nGrp) EgtRelocateGlob( nCrvId, nGrpTmp) local frLoc, dDimX, dDimY = EgtCurveMinAreaRectangleXY( nCrvId) if dDimY < 0.5 then - -- TODO curva generica + -- TODO curva generica local dZ = EgtSP( nCrvId):getZ() -- creo la curva che corrisponde alla sigola passata local ptS = frLoc:getOrigin() - dDimX / 2 * frLoc:getVersX() + dZ * Z_AX() @@ -232,6 +240,21 @@ local function VerifyPath( nCrvId, dStrand, vtSlicing, nGrp) end -- se non è fattibile con unica passata lo cancello if not bSingleStrand then + -- verifico se devo eliminarlo dalle info della curva precedente + local nPrev = EgtGetInfo( nCrvId, KEY_PREV_CRV, 'i') + if nPrev then + local vNext = EgtGetInfo( nPrev, KEY_NEXT_CRVS, 'vi') + if vNext then + for k = 1, #vNext do + if vNext[k] == nCrvId then + table.remove( vNext, k) + break + end + end + EgtSetInfo( nPrev, KEY_NEXT_CRVS, vNext) + end + end + -- cancello EgtErase( nCrvId) return false end @@ -241,128 +264,185 @@ local function VerifyPath( nCrvId, dStrand, vtSlicing, nGrp) end -------------------------------------------------------------------- ---------------------- RIEMPIMENTI PIENI ---------------------------- +------------------------- INFILL ----------------------------------- -------------------------------------------------------------------- -local function AdjustSurfForFloorCeil( nStrandDiff, nSrfTrim, nShellNbrSurfGrp) - - if EgtSurfFrChunkCount( nSrfTrim) == 0 then return end +local function CalcInfillPaths( nLayId, nInfillGrp, LayerParams) - local nSurf = EgtCopyGlob( nSrfTrim, EgtGetParent( nSrfTrim)) + if not nInfillGrp then return end - if nShellNbrSurfGrp then - local nIdx = nStrandDiff - local nShellSurf = EgtGetFirstNameInGroup( nShellNbrSurfGrp, SHELL_NBR_SURF .. tostring( nIdx)) - while nShellSurf do - EgtSurfFrSubtract( nSurf, nShellSurf) - nIdx = nIdx + 1 - nShellSurf = EgtGetFirstNameInGroup( nShellNbrSurfGrp, SHELL_NBR_SURF .. tostring( nIdx)) - end - end + -- recupero le curve di infill + local vIds = EgtGetAllInGroup( nInfillGrp) + if not vIds or #vIds == 0 then return end - return nSurf -end - --------------------------------------------------------------------- -local function ReorderPath( vOldIds, vNewIds) - - if not vNewIds then return end - if #vOldIds == 1 and #vNewIds == 1 then - EgtRelocateGlob( vNewIds[1], vOldIds[1], GDB_IN.AFTER) - return - end - - -- associo ad ogni elemento di vOldIds gli elementi di vNewIds che contiene - local vOrdered = {} - if #vOldIds == 1 then - vOrdered[vOldIds[1]] = vNewIds - else - local nGrp = EgtGetParent( vOldIds[1]) - -- creo le superifici a partire dalle curve in vOldIds - local vOldSurf = {} - for i = 1, #vOldIds do - local nSrf = EgtSurfFlatRegion( nGrp, {vOldIds[i]}) - table.insert( vOldSurf, EgtIf( nSrf, nSrf, GDB_ID.NULL)) - end + -- scorro i gruppi di curve + local vCrvGrps = EgtGetNameInGroup( nLayId, CONTOUR_GRP .. '*') + for i = 1, #vCrvGrps do - for i = 1, #vNewIds do - for j = 1, #vOldSurf do - if vOldSurf[j] ~= GDB_ID.NULL then - if not EgtSurfFrTestExternal( vOldSurf[j], vNewIds[i]) then - if vOrdered[vOldIds[j]] then - table.insert( vOrdered[vOldIds[j]], vNewIds[i]) - else - vOrdered[vOldIds[j]] = {vNewIds[i]} - end - break + -- creo il gruppo per infill + local nInfillPathGrp = EgtGroup( vCrvGrps[i]) + EgtSetName( nInfillPathGrp, INFILL_GRP) + EgtSetStatus( nInfillPathGrp, GDB_ST.OFF) + EgtSetInfo( nInfillPathGrp, KEY_FILL_TYPE, LayerParams.nInfillType) + + -- recupero la superficie con cui fare trim + local nSrf = EgtGetFirstNameInGroup( vCrvGrps[i], TOT_SHELL_TRIM_SURF) + if not nSrf then + -- se non esiste non c'è spazio per infill + EgtOutLog( 'Warning: Infill not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + else + local bOk, bExists, nTrimSrf = ComputeSurfOffset( nSrf, nInfillPathGrp, LayerParams.nInfillOverlap / 100 * LayerParams.dStrand, LayerParams.vtSlicing, GDB_OT.EXTEND) + if not bOk then + -- eseguo trim senza overlap + EgtOutLog( 'Warning: Infill without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + nTrimSrf = EgtCopyGlob( nSrf, nInfillPathGrp) + end + + for i = 1, #vIds do + local nNewId = EgtCopyGlob( vIds[i], nInfillPathGrp) + -- faccio trim con la superficie + local nRes, nCnt = EgtTrimCurveWithRegion( nNewId, nTrimSrf, true, true) + for nId = nRes, nRes + nCnt - 1 do + -- verifico se lunghezza minima + local dLen = EgtCurveLength( nId) + if dLen < MIN_INFILL_LEN then + EgtErase( nId) + else + EgtSetName( nId, INFILL_CRV) + EgtSetInfo( nId, KEY_TYPE, TYPE.INFILL) + EgtSetInfo( nId, KEY_ASSOCIATED_SURF, nTrimSrf) + EgtModifyCurveExtrusion( nId, LayerParams.vtSlicing) end end end + + -- avendo riempito la regione con gli infill, la TotShellTrimSurf non deve esistere + EgtErase( nSrf) end - for i = 1, #vOldSurf do - EgtErase( vOldSurf[i]) + -- se gruppo vuoto lo cancello + if not EgtGetFirstNameInGroup( nInfillPathGrp, INFILL_CRV .. '*') then + EgtErase( nInfillPathGrp) end end - -- riordino - for nParentIdx, vChildren in pairs( vOrdered) do - if #vChildren == 1 then - -- se racchiude solo una curva - EgtRelocateGlob( vChildren[1], nParentIdx, GDB_IN.AFTER) - else - EgtSpInit() - -- se racchiude più curve uso shortest path per ordinarle - for j = 1, #vChildren do - local pt = EgtGP( vChildren[j]) - EgtSpAddPoint( pt:getX(), pt:getY(), pt:getZ(), 0, 0, pt:getX(), pt:getY(), pt:getZ(), 0, 0) + return true +end + +-------------------------------------------------------------------- +------------------------ SOLID FILL -------------------------------- +-------------------------------------------------------------------- +local function AssignChildrenCurves( vParentIds, vChildrenIds, vOrdered) + + if not vParentIds or not vChildrenIds then return end + + if #vParentIds == 1 then + vOrdered[vParentIds[1]] = vChildrenIds + else + -- recupero i centroidi di tutte le curve padre + local vPtCParent = {} + for i = 1, #vParentIds do + table.insert( vPtCParent, EgtGP( vParentIds[i])) + end + + -- associo ad ogni elemento di vParentIds gli elementi di vChildrenIds che ha generato + for i = 1, #vChildrenIds do + -- individuo la curva di vParentIds con il centroiode più vicino + local ptC = EgtGP( vChildrenIds[i]) + local dDistMin = GEO.INFINITO + local nParentId = -1 + for j = 1, #vPtCParent do + local dCurrDist = dist( ptC, vPtCParent[j]) + if dCurrDist < dDistMin - GEO.EPS_SMALL then + dDistMin = dCurrDist + nParentId = vParentIds[j] + end end - local ptS = EgtSP( nParentIdx) - EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, ptS:getX(), ptS:getY(), ptS:getZ(), 0, 0) - local vOrd, _ = EgtSpCalculate( SHP_TY.OPEN) - EgtSpTerminate() - for j = #vOrd, 1, -1 do - EgtRelocateGlob( vChildren[vOrd[j]], nParentIdx, GDB_IN.AFTER) + -- la aggiungo tra i figli della curva di vParentIds trovata + if not vOrdered[nParentId] then + vOrdered[nParentId] = {vChildrenIds[i]} + else + table.insert( vOrdered[nParentId], vChildrenIds[i]) end end end end --------------------------------------------------------------------------- -local function ComputeOffsetInfill( nSrf, dStrand, vtSlicing, sName, nType, vPtStart, nGrp) +local function ReorderPath( vOldIds, vNewIds) - local nChunk = EgtSurfFrChunkCount( nSrf) - if nChunk == 0 then return end + if not vNewIds or not vOldIds then return end + + -- suddivido in base alla tipologia di loop ( esterno o interno) + local tOldIds = {{}, {}} + for i = 1, #vOldIds do + local bIntLoop = EgtGetInfo( vOldIds[i], KEY_INTERNAL_SRF_LOOP, 'b') or false + local nTabInd = EgtIf( bIntLoop, 2, 1) + table.insert( tOldIds[nTabInd], vOldIds[i]) + end + + local tNewIds = {{}, {}} + for i = 1, #vNewIds do + local bIntLoop = EgtGetInfo( vNewIds[i], KEY_INTERNAL_SRF_LOOP, 'b') or false + local nTabInd = EgtIf( bIntLoop, 2, 1) + table.insert( tNewIds[nTabInd], vNewIds[i]) + end + + -- assegno ad ogni curva di vOldIds le curve di vNewIds che ha generato + local vOrdered = {} + AssignChildrenCurves( tOldIds[1], tNewIds[1], vOrdered) -- loop esterni + AssignChildrenCurves( tOldIds[2], tNewIds[2], vOrdered) -- loop interni + + -- assegno le info e riordino + local vNewOrder = {} + local nGrp = EgtGetParent( vNewIds[1]) + for i = 1, #vOldIds do + local vChildrenIds = vOrdered[vOldIds[i]] or {} + EgtSetInfo( vOldIds[i], KEY_NEXT_CRVS, vChildrenIds) + for j = 1, #vChildrenIds do + EgtRelocateGlob( vChildrenIds[j], nGrp, GDB_IN.LAST_SON) + table.insert( vNewOrder, vChildrenIds[j]) + EgtSetInfo( vChildrenIds[j], KEY_PREV_CRV, vOldIds[i]) + end + end + + return vNewOrder +end + +--------------------------------------------------------------------------- +local function ComputeOffsetSolidFill( nSrf, dStrand, vtSlicing, sName, nType, nGrp, vPtStart, vOldIds) + + -- 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) + local bOk = true + local bExists = ( EgtSurfFrChunkCount( nSrf) > 0) - -- estraggo i contorni della superficie - local vOldIds = GetPathsFromSurf( nSrf, sName, nType, nGrp, vPtStart) - local dOffs = - dStrand - local bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrf, nGrp, dOffs, vtSlicing) while bOk and bExists do -- estraggo i contorni local vNewIds = GetPathsFromSurf( nSrfOffs, sName, nType, nGrp, vPtStart) if vNewIds then -- riordino - ReorderPath( vOldIds, vNewIds) + local vNewOrder = ReorderPath( vOldIds, vNewIds) or vNewIds + -- verifico fattibilità local k = 1 - while k <= #vNewIds do - if VerifyPath( vNewIds[k], dStrand, vtSlicing, nGrp) then + 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( vNewIds, k) + table.remove( vNewOrder, k) end end - vOldIds = vNewIds + vOldIds = vNewOrder end - EgtErase( nSrfOffs) -- offset successivo + EgtErase( nSrfOffs) dOffs = dOffs - dStrand bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrf, nGrp, dOffs, vtSlicing) end - end ------------------------------------------------------------------ @@ -374,47 +454,50 @@ local function FindOptimalZigZagDirection( nSrfId, nBorderSurf, dStrand, nGrp, f 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 + table.insert( vAllIds, i) + end + local vCheckIds = {} + + -- se ho superficie che contiene nSrfId ( caso AuxSolid) cerco il lato di lunghezza massima tra quelli a distanza minima dal bordo + if nBorderSurf then + -- recupero i contorni della curva di bordo + local vBorderIds = GetPathsFromSurf( nBorderSurf, 'TmpBorder', 0, nGrpTmp) - -- 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 + local dMinDist = GEO.INFINITO + for i = nId, nId + nCnt - 1 do + + -- 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 + + -- 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 end - - -- 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 + -- se non ho id specifici da controllare considero tutti i lati if #vCheckIds == 0 then vCheckIds = vAllIds end @@ -439,7 +522,7 @@ local function FindOptimalZigZagDirection( nSrfId, nBorderSurf, dStrand, nGrp, f end -------------------------------------------------------------------- -local function ComputeZigZagInfill( nSrf, dStrand, vtSlicing, sName, nType, vPtStart, nGrp, nBorderSurf) +local function ComputeZigZagSolidFill( nSrf, dStrand, vtSlicing, sName, nType, nGrp, nBorderSurf) if EgtSurfFrChunkCount( nSrf) == 0 then return end @@ -462,14 +545,63 @@ local function ComputeZigZagInfill( nSrf, dStrand, vtSlicing, sName, nType, vPtS EgtSetName( j, sName) EgtSetInfo( j, KEY_TYPE, nType) EgtSetInfo( j, KEY_ZIG_ZAG_DIR, vtDir) - EgtSetInfo( j, KEY_ZIG_ZAG_INFILL, 1) + EgtSetInfo( j, KEY_ZIG_ZAG_INFILL, true) EgtModifyCurveExtrusion( j, vtSlicing, GDB_RT.GLOB) table.insert( vIds, j) end end EgtErase( nSrfId) end - +end + +------------------------------------------------------------------ +local function CalcSolidFillPath( nLayId, LayerParams, vPtStart, nFillType) + + -- scorro i gruppi di curve + local vCrvGrps = EgtGetNameInGroup( nLayId, CONTOUR_GRP .. '*') + for i = 1, #vCrvGrps do + + -- creo il gruppo per infill + local nInfillPathGrp = EgtGroup( vCrvGrps[i]) + EgtSetName( nInfillPathGrp, INFILL_GRP) + EgtSetStatus( nInfillPathGrp, GDB_ST.OFF) + EgtSetInfo( nInfillPathGrp, KEY_FILL_TYPE, nFillType) + + -- recupero la superficie da riempire + local nSrf = EgtGetFirstNameInGroup( vCrvGrps[i], TOT_SHELL_TRIM_SURF) + if not nSrf then + -- se non esiste non c'è spazio per solid fill + EgtOutLog( 'Warning: SolidFill not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + else + local bOk, bExists, nSrfToFill = ComputeSurfOffset( nSrf, nInfillPathGrp, LayerParams.nStrandOverlap / 100 * LayerParams.dStrand, LayerParams.vtSlicing) + if not bOk then + -- eseguo trim senza overlap + EgtOutLog( 'Warning: SolidFill without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + nSrfToFill = EgtCopyGlob( nSrf, nInfillPathGrp) + end + + -- distanza tra passate tenendo conto dell'overlap indicato + local dDist = ( 1 - LayerParams.nStrandOverlap / 100) * LayerParams.dStrand + -- inserisco il riempimento + if nFillType == FILL_TYPE.OFFSET then + -- recupero le shell precedenti dal PathGrp + 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) + elseif nFillType == FILL_TYPE.ZIGZAG then + ComputeZigZagSolidFill( nSrfToFill, dDist, LayerParams.vtSlicing, INFILL_CRV, TYPE.INFILL, nInfillPathGrp) + end + + -- avendo riempito la regione, la TotShellTrimSurf non deve esistere + EgtErase( nSrf) + end + + -- se gruppo vuoto lo cancello + if not EgtGetFirstInGroup( nInfillPathGrp) then + EgtErase( nInfillPathGrp) + end + end end -------------------------------------------------------------------- @@ -594,7 +726,7 @@ local function FindAssociatedUserLinkParts( nStartRib, vRibs, vUsed, nGrpTmp, nT end end - return tabUserLink + return tabUserLink end ----------------------------------------------------------------------- @@ -688,7 +820,6 @@ local function AdjustUserLinkRibs( tUserLink, vRibs, vtSlicing, nSrfInt, nSrfExt -- verifico se trovo setti associati ( e quindi definisce UserLink) local nStartRib = EgtGetInfo( vRibs[i], KEY_START_RIB, 'i') - local vSingleRibs = {} local nType = EgtGetInfo( vRibs[i], KEY_RIBS_TYPE, 'i') local nSrfTest = EgtIf( nType == RIB_TYPE.EXTERNAL, nSrfExt, nSrfInt) local tabUserLink = FindAssociatedUserLinkParts( nStartRib, vRibs, vUsed, nGrpTmp, nType, nSrfTest) @@ -2602,17 +2733,57 @@ local function AddExtraZigZag( nSrf, sName, dStrand, vtSlicing, nGrp, nSrfTrim) end +------------------------------------------------------------------- +local function ComputeAuxSolidsGenericInfill( nSrf, dStrand, vtSlicing, sName, nPathGrp, vPtStart, nOrigSurf, nOverlap, nAuxSolidsGrp) + + -- 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 * ( nOverlap / 100 - 0.5) + local bOk, bExists, nSrfTrim = ComputeSurfOffset( nSrf, nPathGrp, dOffs, vtSlicing) + if not bOk then + EgtOutLog( 'Warning: AuxSolid Infill without correct overlap (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + nSrfTrim = EgtCopyGlob( nSrf, nPathGrp) + elseif not bExists then + EgtOutLog( 'Warning: AuxSolid Infill not possibile (layer '.. EgtNumToString( s_nCurrIdx) ..') - CalcPaths') + return + end + + -- recupero gli infill associati + local sNameInfill = AUX_SOLIDS_INFILL_CRV .. tostring( nOrigSurf) + local vInfillIds = EgtGetNameInGroup( nAuxSolidsGrp, sNameInfill .. '*') or {} + + -- eseguo trim con la superficie + for i = 1, #vInfillIds do + local nCrv = EgtCopyGlob( vInfillIds[i], nPathGrp) + local nRes, nCnt = EgtTrimCurveWithRegion( nCrv, nSrfTrim, true, true) + for nId = nRes, nRes + nCnt - 1 do + -- verifico se lunghezza minima + local dLen = EgtCurveLength( nId) + if dLen < MIN_INFILL_LEN then + EgtErase( nId) + else + EgtSetName( nId, sName) + EgtSetInfo( nId, KEY_TYPE, TYPE.INFILL) + EgtSetInfo( nId, KEY_ASSOCIATED_SURF, nSrfTrim) + EgtModifyCurveExtrusion( nId, vtSlicing) + end + end + end +end + -------------------------------------------------------------------- local function CalcAuxSolidsPaths( nSliceGrp, nSolidGrp, LayerParams, vPtStart) -- recupero i solidi ausiliari dividendoli per nome local vSolidIds = {} - local nFirst = EgtGetFirstInGroup( nSolidGrp) + local nFirst = EgtGetFirstNameInGroup( nSolidGrp, AUX_SOLIDS_CRV .. '*') while nFirst do local sName = EgtGetName( nFirst) local vIds = EgtGetNameInGroup( nSolidGrp, sName) table.insert( vSolidIds, vIds) - nFirst = EgtGetNext( vIds[#vIds]) + nFirst = EgtGetNextName( vIds[#vIds], AUX_SOLIDS_CRV .. '*') end -- scorro i gruppi di curve @@ -2640,6 +2811,7 @@ local function CalcAuxSolidsPaths( nSliceGrp, nSolidGrp, LayerParams, vPtStart) -- creo la flat region corrispondente al solido ausiliario local sName = EgtGetName( vSolidIds[i][1]) local nOverlap = EgtGetInfo( vSolidIds[i][1], KEY_AUX_SOLIDS_OVERLAP, 'i') + local nOrigSurf = EgtGetInfo( vSolidIds[i][1], KEY_ORIGINAL_SURF, 'i') local nSrfId = EgtSurfFlatRegion( nSolidPathGrp, vSolidIds[i]) if nSrfId then @@ -2651,21 +2823,29 @@ local function CalcAuxSolidsPaths( nSliceGrp, nSolidGrp, LayerParams, vPtStart) 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') - if nInfillType == INFILL_TYPE.NONE then + + 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, LayerParams.dStrand, nSolidPathGrp, LayerParams.vtSlicing) - elseif nInfillType == INFILL_TYPE.OFFSET then - ComputeOffsetInfill( nFirst + j, LayerParams.dStrand, LayerParams.vtSlicing, sNewName, TYPE.AUX_SOLID, vPtStart, nSolidPathGrp) + + elseif nInfillType == FILL_TYPE.OFFSET then + ComputeOffsetSolidFill( nFirst + j, LayerParams.dStrand, LayerParams.vtSlicing, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, vPtStart) -- 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, vSurfOffs[nOverlap]) + + elseif nInfillType == FILL_TYPE.ZIGZAG then + ComputeZigZagSolidFill( nFirst + j, LayerParams.dStrand, LayerParams.vtSlicing, sNewName, TYPE.AUX_SOLID, nSolidPathGrp, vSurfOffs[nOverlap]) -- aggiungo eventuale passata extra AddExtraZigZag( nFirst + j, sNewName, LayerParams.dStrand, LayerParams.vtSlicing, nSolidPathGrp, vSurfOffs[nOverlap]) -- aggiorno la trim surf UpdateTrimSurfWithAuxSolidsZigZag( nSolidPathGrp, sNewName, nSrfBase, LayerParams.dStrand, nFirst + j) + + else + ComputeAuxSolidsGenericInfill( nFirst + j, LayerParams.dStrand, LayerParams.vtSlicing, sNewName, nSolidPathGrp, vPtStart, nOrigSurf, nOverlap, nSolidGrp) + -- aggiorno la trim surf + UpdateTrimSurfWithAuxSolidsOffset( nFirst + j, nSrfBase, LayerParams.dStrand, nSolidPathGrp, LayerParams.vtSlicing) end end else @@ -2698,6 +2878,9 @@ function CalcPaths.Exec( nPartId) -- recupero i parametri per calcolo dei path local LayerParams = GetLayerParamsForPathCalc() + local nFirstSolidLay = EgtGetInfo( s_nPartId, KEY_FIRST_SOLID_LAY, 'i') or -1 + local nLastSolidLay = EgtGetInfo( s_nPartId, KEY_LAST_SOLID_LAY, 'i') or -1 + -- scorro tutti i suoi layer for nIdx = 1, #vLayIds do @@ -2705,6 +2888,7 @@ function CalcPaths.Exec( nPartId) local nRibsGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], RIBS_GRP) local nAuxSolidsGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], AUX_SOLIDS_GRP) + local nInfillGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], INFILL_GRP) -- regioni con diverso numero di passate local nShellNbrGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], SHELL_NBR_GRP) @@ -2737,6 +2921,7 @@ function CalcPaths.Exec( nPartId) nMaxShellNbrDiff = min( nMaxShellNbrDiff, LayerParams.nShellsNbr) -- parete esterna + local vOldIds local bPrevExists = true local dOffs = - LayerParams.dOffs - 0.5 * LayerParams.dStrand if nMaxShellNbrDiff < LayerParams.nShellsNbr then @@ -2749,7 +2934,7 @@ function CalcPaths.Exec( nPartId) EgtOutLog( 'Warning : ExtOffset not possible (layer '.. EgtNumToString( nIdx) ..') - CalcPaths') else -- se offset riuscito, estraggo i contorni (pareti esterne) - GetPathsFromSurf( nSrfId, SHELL_CRV ..'0', TYPE.OUTER_SHELL, nGrpId, vPtStart) + vOldIds = GetPathsFromSurf( nSrfId, SHELL_CRV ..'0', TYPE.OUTER_SHELL, nGrpId, vPtStart) end bPrevExists = bExists EgtErase( nSrfId) @@ -2761,7 +2946,6 @@ function CalcPaths.Exec( nPartId) table.insert( vPtInnerStart, EgtSP( vOuterShell[i])) end if #vPtInnerStart == 0 then vPtInnerStart = vPtStart end - EgtSetInfo( nCrvGrpId, KEY_START_POINT, vPtInnerStart[1]) -- pareti interne complete for nInd = 1, LayerParams.nShellsNbr - 1 - nMaxShellNbrDiff do @@ -2775,7 +2959,9 @@ function CalcPaths.Exec( nPartId) EgtOutLog( 'Warning : IntOffset ' .. EgtNumToString( nInd) .. ' not possible (layer '.. EgtNumToString( nIdx) ..') - CalcPaths') else -- se offset riuscito, estraggo i contorni ( pareti interne) - GetPathsFromSurf( nSrfId, SHELL_CRV..tostring( nInd), TYPE.INNER_SHELL, nGrpId, vPtInnerStart) + local vNewIds = GetPathsFromSurf( nSrfId, SHELL_CRV..tostring( nInd), TYPE.INNER_SHELL, nGrpId, vPtInnerStart) + ReorderPath( vOldIds, vNewIds) + vOldIds = vNewIds -- se questo offset esiste ma il precedente no, allora il precedente è un errore da segnalare if not bPrevExists then @@ -2814,44 +3000,36 @@ function CalcPaths.Exec( nPartId) if nMaxShellNbrDiff > 0 then CalcExtraShellsPath( nMaxShellNbrDiff, nShellNbrSurfGrp, nCrvGrpId, dOffs, LayerParams, vPtInnerStart) end - - -- gestione eventuale floor/ceil - if nIdx <= LayerParams.nFloorNbr then - local nSurfInfill = AdjustSurfForFloorCeil( LayerParams.nFloorNbr - nIdx + 1, nSrfTrim, nShellNbrSurfGrp) or nSrfTrim - 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, nSurfInfill) - end - EgtErase( nSurfInfill) - elseif nIdx > #vLayIds - LayerParams.nCeilNbr then - local nSurfInfill = AdjustSurfForFloorCeil( LayerParams.nCeilNbr - ( #vLayIds - nIdx), nSrfTrim, nShellNbrSurfGrp) or nSrfTrim - if LayerParams.nCeilType == INFILL_TYPE.OFFSET then - ComputeOffsetInfill( nSurfInfill, LayerParams.dStrand, LayerParams.vtSlicing, INFILL_CRV, TYPE.INFILL, vPtStart, nGrpId) - elseif LayerParams.nCeilType == INFILL_TYPE.ZIGZAG then - ComputeZigZagInfill( nSurfInfill, LayerParams.dStrand, LayerParams.vtSlicing, INFILL_CRV, TYPE.INFILL, vPtStart, nGrpId) - end - EgtErase( nSurfInfill) - end end -- passo al gruppo di contorni successivo nCrvGrpId = EgtGetNextName( nCrvGrpId, CONTOUR_GRP.."*") or GDB_ID.NULL end - if nIdx > LayerParams.nFloorNbr and nIdx <= #vLayIds - LayerParams.nCeilNbr then - - -- sistemo eventuali solidi ausiliari - if nAuxSolidsGrp then - CalcAuxSolidsPaths( vLayIds[nIdx], nAuxSolidsGrp, LayerParams, vPtStart) - end - - -- sistemo eventuali costolature - if nRibsGrp then - CalcRibsPaths( vLayIds[nIdx], nRibsGrp, LayerParams, vPtStart) + -- gestione solidi ausiliari ( se no floor o ceil) + if nAuxSolidsGrp and ( nFirstSolidLay + LayerParams.nFloorNbr <= nIdx and nIdx <= nLastSolidLay - LayerParams.nCeilNbr or LayerParams.nShellsNbr == 0) then + CalcAuxSolidsPaths( vLayIds[nIdx], nAuxSolidsGrp, LayerParams, vPtStart) + end + + -- gestione riempimenti + if LayerParams.nShellsNbr > 0 then + -- infill + if nFirstSolidLay + LayerParams.nFloorNbr <= nIdx and nIdx <= nLastSolidLay - LayerParams.nCeilNbr then + CalcInfillPaths( vLayIds[nIdx], nInfillGrp, LayerParams) + -- floor + elseif nFirstSolidLay <= nIdx and nIdx < nFirstSolidLay + LayerParams.nFloorNbr then + CalcSolidFillPath( vLayIds[nIdx], LayerParams, vPtStart, LayerParams.nFloorType) + -- ceil + elseif nLastSolidLay - LayerParams.nCeilNbr < nIdx and nIdx <= nLastSolidLay then + CalcSolidFillPath( vLayIds[nIdx], LayerParams, vPtStart, LayerParams.nCeilType) end end + -- gestione costolature + if nRibsGrp then + CalcRibsPaths( vLayIds[nIdx], nRibsGrp, LayerParams, vPtStart) + end + if EgtProcessEvents( EgtIf( PRINT, 200, 0) + nIdx / #vLayIds * 100, 0) == 1 then EgtDraw() return false diff --git a/LuaLibs/CalcSlices.lua b/LuaLibs/CalcSlices.lua index 660638b..ce4e54e 100644 --- a/LuaLibs/CalcSlices.lua +++ b/LuaLibs/CalcSlices.lua @@ -14,6 +14,7 @@ local AMD = require( 'AddManData') --------------------------------------------------------------------- local s_nPartId +local s_vErr = {} -- costanti local TOLER = 0.05 @@ -92,70 +93,7 @@ local function ReadParam( nId, sKey, sType, defVal, table) return info end --------------------------------------------------------------------- -local function ExtractRibsLoops( nRibsGrp, nStmId) - - local nLoopGrp = EgtGroup( s_nPartId) - EgtSetName( nLoopGrp, RIBS_LOOP_GRP) - EgtSetStatus( nLoopGrp, GDB_ST.OFF) - - -- recupero tutti i setti - local vIds = EgtGetAllInGroup( nRibsGrp) - for i = 1, #vIds do - -- se trimesh - if EgtGetType( vIds[i]) == GDB_TY.SRF_MESH then - -- trim con il solido - local nCopy = EgtCopyGlob( vIds[i], nLoopGrp) - local nType = ReadParam( vIds[i], KEY_RIBS_TYPE, 'i', RIB_TYPE.INTERNAL) - EgtSurfTmCut( nCopy, nStmId, nType ~= RIB_TYPE.EXTERNAL, false) - -- estraggo i contorni - local nCrv, nCnt = EgtExtractSurfTmLoops( nCopy, nLoopGrp) - if nCrv then - -- assegno nome che permetta di ricondurli alla superficie da cui derivano - for nId = nCrv, nCrv + nCnt - 1 do - EgtSetName( nId, SURF_LOOP .. tostring( vIds[i])) - end - end - end - end -end - --------------------------------------------------------------------- -local function AdjustAuxSolids( nSolidsLay) - - -- gestisce intersezioni fra solidi ausiliari unendoli - local nCurr = EgtGetFirstInGroup( nSolidsLay or GDB_ID.NULL) - if not nCurr then return end - - local nGrpTmp = EgtGroup( nSolidsLay) - while nCurr do - if EgtGetType( nCurr) == GDB_TY.SRF_MESH then - -- verifico se interseca uno dei solidi successivi - local bInters = true -- per entrare nel loop - while bInters do - bInters = false - local nNext = EgtGetNext( nCurr) - while nNext do - if EgtGetType( nNext) == GDB_TY.SRF_MESH then - -- verifico se le due superfici si intersecano - local nFirst = EgtSurfTmSurfTmInters( nCurr, nNext, nGrpTmp) - -- se intersezione unisco i due solidi e ripeto il check - if nFirst then - EgtSurfTmAdd( nCurr, nNext) - EgtErase( nNext) - bInters = true - end - end - nNext = EgtGetNext( nNext) - end - end - end - nCurr = EgtGetNext( nCurr) - end - EgtErase( nGrpTmp) -end - --------------------------------------------------------------------- +----------------------------------------------------------------------- local function GetRibParams( nId) local RibParam = {} @@ -193,166 +131,558 @@ local function GetAuxSolidsParams( nId) local AuxSolidsParam = {} ReadParam( nId, KEY_AUX_SOLIDS_OVERLAP, 'i', 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) + ReadParam( nId, KEY_AUX_SOLIDS_LINK_TYPE, 'i', LINK_TYPE.NONE, AuxSolidsParam) ReadParam( nId, KEY_AUX_SOLIDS_LINK_PARAM, 'd', 0, AuxSolidsParam) ReadParam( nId, KEY_AUX_SOLIDS_SP_OFFSET, 'd', 0, AuxSolidsParam) + ReadParam( nId, KEY_AUX_SOLIDS_LP_OFFSET, 'd', 0, AuxSolidsParam) + ReadParam( nId, KEY_AUX_SOLIDS_DENSITY, 'd', 0, AuxSolidsParam) + ReadParam( nId, KEY_AUX_SOLIDS_DIR, 'd', 0, AuxSolidsParam) + ReadParam( nId, KEY_AUX_SOLIDS_OFFSET_X, 'd', 0, AuxSolidsParam) + ReadParam( nId, KEY_AUX_SOLIDS_OFFSET_Y, 'd', 0, AuxSolidsParam) + ReadParam( nId, KEY_AUX_SOLIDS_GRID_OVERLAP, 'i', 0, AuxSolidsParam) ReadParam( nId, KEY_AUX_SOLIDS_COASTING_LEN, 'd', 0, AuxSolidsParam) ReadParam( nId, KEY_AUX_SOLIDS_WIPE_LEN, 'd', 0, AuxSolidsParam) ReadParam( nId, KEY_AUX_SOLIDS_WIPE_DIR, 'd', 0, AuxSolidsParam) - ReadParam( nId, KEY_AUX_SOLIDS_INFILL, 'i', INFILL_TYPE.NONE, AuxSolidsParam) - ReadParam( nId, KEY_AUX_SOLIDS_PRINT_ORDER, 'i', PRINT_ORDER.EXT_INT, AuxSolidsParam) - ReadParam( nId, KEY_AUX_SOLIDS_LINK_TYPE, 'i', LINK_TYPE.NONE, AuxSolidsParam) - + return AuxSolidsParam end --------------------------------------------------------------------- -local function SlicingExtraObjects( vtSlicing, nLay, nType, sNameGrp, sName, vErr, nStmId) +---------------------------------------------------------------------- +-------------------- SLICING EXTRA OBJECTS --------------------------- +---------------------------------------------------------------------- +local function SliceStm( vIds, nLayId, vtSlicing, nType, sName, sNameGrp, tabParams) - -- recupero gli oggeti di cui fare slicing - local vIds = EgtGetAllInGroup( nLay) if not vIds or #vIds == 0 then return end - -- rimuovo gli indici che non corrispondono a trimesh - local k = 1 - while k <= #vIds do - local nType = EgtGetType( vIds[k]) - if nType ~= GDB_TY.SRF_MESH then - table.remove( vIds, k) - else - k = k + 1 - end - end - if #vIds == 0 then return end - - -- recupero i parametri di ogni oggetto - local tabParams = {} - local vToBeDone = {} - for i = 1, #vIds do - local vParams = {} - local bToBeDone = true - if nType == TYPE.RIB then - vParams = GetRibParams( vIds[i]) - if vParams[ KEY_RIBS_SHELLS_NBR] == 0 then bToBeDone = false end - elseif nType == TYPE.EXTRA_SHELL then - vParams = GetShellNumberParams( vIds[i]) - if vParams[KEY_SHELL_NBR_DIFF] == 0 then bToBeDone = false end - elseif nType == TYPE.AUX_SOLID then - vParams = GetAuxSolidsParams( vIds[i]) - end - table.insert( tabParams, vParams) - table.insert( vToBeDone, bToBeDone) + -- recupero il gruppo dove salvare lo slicing degli oggetti + local nGrp = EgtGetFirstNameInGroup( nLayId, sNameGrp) + if not nGrp then + -- se gruppo non esiste lo creo + nGrp = EgtGroup( nLayId) + EgtSetName( nGrp, sNameGrp) + EgtSetStatus( nGrp, GDB_ST.OFF) end - -- taglio i setti unbounded e limitati con il solido - local vEraseIds = {} - if nType == TYPE.RIB then - local bLimitUnbddRibs = EgtGetInfo( s_nPartId, KEY_LIMIT_UNBDD_RIBS, 'b') or false - if bLimitUnbddRibs then - for i = 1, #vIds do - if vToBeDone[i] then - if tabParams[i][KEY_RIBS_TYPE] == RIB_TYPE.UNBOUNDED then - -- creo copia e la taglio con solido - local nCopy = EgtCopyGlob( vIds[i], EgtGetParent( vIds[i])) - EgtSurfTmCut( nCopy, nStmId, true, true) - -- lo slicing viene fatto sulla copia - vIds[i] = nCopy - table.insert( vEraseIds, nCopy) + -- recupero quota per slicing + local dZ = EgtGetInfo( nLayId, KEY_SLICE_REAL_Z, 'd') + local dDeltaZ = EgtGetInfo( nLayId, KEY_SLICE_DELTAZ, 'd') + local nLayCnt = EgtGetInfo( nLayId, KEY_SLICE_NBR, 'i') + + for i = 1, #vIds do + -- verifico che oggetto sia trimesh + local nTypeObj = EgtGetType( vIds[i]) + if nTypeObj == GDB_TY.SRF_MESH then + -- slicing oggetto + local nNewId, nPntCnt, nCrvCnt, nSrfCnt = EgtPlaneSurfTmInters( ORIG() + ( dZ + dDeltaZ) * vtSlicing, vtSlicing, vIds[i], nGrp, GDB_RT.GLOB, TOLER) + + -- verifico se necessario ricalcolo + local dCorr = 0 + local bOpen = false + if nType ~= TYPE.RIB and nType ~= TYPE.INFILL and nNewId then + for nId = nNewId + nPntCnt, nNewId + nPntCnt + nCrvCnt - 1 do + if not EgtCurveIsClosed( nId) then + bOpen = true + break end end end - end - end - - local nLayId = EgtGetFirstNameInGroup( s_nPartId, SLICE_LAYER .. '*') - while nLayId do - -- recupero quota per slicing - local dZ = EgtGetInfo( nLayId, KEY_SLICE_REAL_Z, 'd') - local dDeltaZ = EgtGetInfo( nLayId, KEY_SLICE_DELTAZ, 'd') - local nLayCnt = EgtGetInfo( nLayId, KEY_SLICE_NBR, 'i') - -- creo gruppo per gli oggetti - local nGrp = EgtGroup( nLayId) - EgtSetName( nGrp, sNameGrp) - EgtSetStatus( nGrp, GDB_ST.OFF) - - for i = 1, #vIds do - if vToBeDone[i] then - -- slicing oggetto - local nNewId, nPntCnt, nCrvCnt, nSrfCnt = EgtPlaneSurfTmInters( ORIG() + ( dZ + dDeltaZ) * vtSlicing, vtSlicing, vIds[i], nGrp, GDB_RT.GLOB, TOLER) - - -- verifico se necessario ricalcolo - local dCorr = 0 - local bOpen = false - if nType ~= TYPE.RIB and nNewId then - for nId = nNewId + nPntCnt, nNewId + nPntCnt + nCrvCnt - 1 do - if not EgtCurveIsClosed( nId) then - bOpen = true - break - end - end + -- eventuale ricalcolo ( se superfici o curve aperte) + if nSrfCnt > 0 or bOpen then + EgtOutLog( 'Warning : recalc at layer '.. EgtNumToString( nLayCnt) .. ' (object)') + -- elimino vecchio risultato + for j = nNewId, nNewId + nPntCnt + nCrvCnt + nSrfCnt - 1 do + EgtErase( j) end + dCorr = 0.01 + nNewId, nPntCnt, nCrvCnt, nSrfCnt = EgtPlaneSurfTmInters( ORIG() + ( dZ + dDeltaZ + dCorr) * vtSlicing, vtSlicing, vIds[i], nGrp, GDB_RT.GLOB, TOLER) + end + + if nNewId then - if nSrfCnt > 0 or bOpen then - EgtOutLog( 'Warning : recalc at layer '.. EgtNumToString( nLayCnt) .. ' (object)') - -- elimino vecchio risultato - for j = nNewId, nNewId + nPntCnt + nCrvCnt + nSrfCnt - 1 do - EgtErase( j) - end - dCorr = 0.01 - nNewId, nPntCnt, nCrvCnt, nSrfCnt = EgtPlaneSurfTmInters( ORIG() + ( dZ + dDeltaZ + dCorr) * vtSlicing, vtSlicing, vIds[i], nGrp, GDB_RT.GLOB, TOLER) + -- rimuovo punti + for nId = nNewId, nNewId + nPntCnt -1 do + EgtErase( nId) end - if nNewId then - - -- rimuovo punti - for nId = nNewId, nNewId + nPntCnt -1 do - EgtErase( nId) - end - - -- concateno le curve - local vChain = {} - for nId = nNewId + nPntCnt, nNewId + nPntCnt + nCrvCnt - 1 do - table.insert( vChain, nId) - end - local nChainId, nCnt = EgtCurveCompoByChain( nGrp, vChain, ORIG(), true, GDB_RT.LOC, BIG_TOLER) - -- rinomino le curve, correggo di DeltaZ e assegno parametri - for nId = nNewId + nPntCnt, nNewId + nPntCnt + nCrvCnt - 1 do - EgtSetName( nId, sName .. tostring( i)) - EgtMove( nId, - ( dDeltaZ + dCorr) * vtSlicing) - EgtSetInfo( nId, KEY_ORIGINAL_SURF, vIds[i]) + -- concateno le curve + local vChain = {} + for nId = nNewId + nPntCnt, nNewId + nPntCnt + nCrvCnt - 1 do + table.insert( vChain, nId) + end + local nChainId, nCnt = EgtCurveCompoByChain( nGrp, vChain, ORIG(), true, GDB_RT.LOC, BIG_TOLER) + -- rinomino le curve, correggo di DeltaZ e assegno parametri + for nId = nNewId + nPntCnt, nNewId + nPntCnt + nCrvCnt - 1 do + EgtSetName( nId, sName .. tostring( i)) + EgtMove( nId, - ( dDeltaZ + dCorr) * vtSlicing) + EgtSetInfo( nId, KEY_ORIGINAL_SURF, vIds[i]) + if tabParams then for sKey, sVal in pairs( tabParams[i]) do EgtSetInfo( nId, sKey, sVal) end - - -- se ho ancora curve aperte, segnalo errore - if nType ~= TYPE.RIB and not EgtCurveIsClosed( nId) then - EgtOutLog( 'Error : hole in object (layer '.. EgtNumToString( nLayCnt) ..') - CalcSlices') - table.insert( vErr, nLayCnt) - end end - -- rimuovo superfici - for nId = nNewId + nPntCnt + nCrvCnt, nNewId + nPntCnt + nCrvCnt + nSrfCnt - 1 do - EgtErase( nId) + -- se ho ancora curve aperte, segnalo errore + if nType ~= TYPE.RIB and nType ~= TYPE.INFILL and not EgtCurveIsClosed( nId) then + EgtOutLog( 'Error : hole in object (layer '.. EgtNumToString( nLayCnt) ..') - CalcSlices') + table.insert( s_vErr, nLayCnt) end end + + -- rimuovo superfici + for nId = nNewId + nPntCnt + nCrvCnt, nNewId + nPntCnt + nCrvCnt + nSrfCnt - 1 do + EgtErase( nId) + end end end + end - -- verifico che il gruppo non sia vuoto - if not EgtGetFirstInGroup( nGrp) then - EgtErase( nGrp) + -- verifico che il gruppo non sia vuoto + if not EgtGetFirstInGroup( nGrp) then + EgtErase( nGrp) + end + +end + +-------------------------------------------------------------------- +local function SlicingExtraObjects( nLay, vtSlicing, nType, sName, sNameGrp, nStmId) + + if not nLay then return end + + -- recupero gli oggetti di cui fare slicing + local vIds = EgtGetAllInGroup( nLay) + if not vIds or #vIds == 0 then return end + + -- recupero i parametri di ogni oggetto e verifico se da considerare per lo slicing + local tabParams = {} + local vSliceIds = {} + for i = 1, #vIds do + -- verifico se trimesh + if EgtGetType( vIds[i]) == GDB_TY.SRF_MESH then + local bToBeDone = true + -- recupero i parametri + local vParams = {} + if nType == TYPE.RIB then + vParams = GetRibParams( vIds[i]) + if vParams[KEY_RIBS_SHELLS_NBR] == 0 then bToBeDone = false end + elseif nType == TYPE.EXTRA_SHELL then + vParams = GetShellNumberParams( vIds[i]) + if vParams[KEY_SHELL_NBR_DIFF] == 0 then bToBeDone = false end + elseif nType == TYPE.AUX_SOLID then + vParams = GetAuxSolidsParams( vIds[i]) + end + -- se da fare lo aggiungo nei vettori + if bToBeDone then + table.insert( tabParams, vParams) + table.insert( vSliceIds, vIds[i]) + end + end + end + + -- taglio i setti unbounded e limitati con il solido + local bLimitUnbddRibs = EgtGetInfo( s_nPartId, KEY_LIMIT_UNBDD_RIBS, 'b') or false + local vEraseIds = {} + if nType == TYPE.RIB and bLimitUnbddRibs then + for i = 1, #vSliceIds do + if tabParams[i][KEY_RIBS_TYPE] == RIB_TYPE.UNBOUNDED then + -- creo copia e la taglio con solido + local nCopy = EgtCopyGlob( vSliceIds[i], EgtGetParent( vSliceIds[i])) + EgtSurfTmCut( nCopy, nStmId, true, true) + -- lo slicing va fatto sulla copia + vSliceIds[i] = nCopy + table.insert( vEraseIds, nCopy) + end end - nLayId = EgtGetNextName( nLayId, SLICE_LAYER .. '*') end - -- rimuovo eventuali copie create per lo slicing + -- per ogni layer calcolo lo slicing degli oggetti + local vLayIds = EgtGetNameInGroup( s_nPartId, SLICE_LAYER .. '*') + for i = 1, #vLayIds do + SliceStm( vSliceIds, vLayIds[i], vtSlicing, nType, sName, sNameGrp, tabParams) + end + + -- rimuovo eventuali oggetti creati per lo slicing for i = 1, #vEraseIds do EgtErase( vEraseIds[i]) end + + return true +end + +------------------------------------------------------------------------ +local function SlicingInfill( nLay, vtSlicing, sName, sNameGrp) + + -- recupero tutte le curve di infill suddivise per direzioni di riferimento + local vInfillGrps = EgtGetAllInGroup( nLay) + local tIds = {} + for i = 1, #vInfillGrps do + local vIds = EgtGetAllInGroup( vInfillGrps[i]) + table.insert( tIds, vIds) + end + local nGrps = #vInfillGrps + + -- recupero quota infill + local ptInfill = EgtSP( tIds[1][1], GDB_ID.ROOT) + local dZInfill = ( ptInfill - ORIG()) * vtSlicing + + local vLayIds = EgtGetNameInGroup( s_nPartId, SLICE_LAYER .. '*') + for i = 1, #vLayIds do + + -- individuo il gruppo di cui fare slicing + local nGrpIdx = ( i - 1) % nGrps + 1 + + -- recupero il gruppo dove salvare gli infill + local nGrp = EgtGetFirstNameInGroup( vLayIds[i], sNameGrp) + if not nGrp then + -- se gruppo non esiste lo creo + nGrp = EgtGroup( vLayIds[i]) + EgtSetName( nGrp, sNameGrp) + EgtSetStatus( nGrp, GDB_ST.OFF) + end + + -- copio le curve di infill e le traslo alla quota dello slicing + local dZ = EgtGetInfo( vLayIds[i], KEY_SLICE_REAL_Z, 'd') + for j = 1, #tIds[nGrpIdx] do + local nCrv = EgtCopyGlob( tIds[nGrpIdx][j], nGrp) + EgtSetName( nCrv, sName .. tostring(j)) + EgtMove( nCrv, (dZ - dZInfill) * vtSlicing, GDB_RT.GLOB) + end + end return true end +---------------------------------------------------------------------- +----------------------------- INFILL --------------------------------- +---------------------------------------------------------------------- +local function CalcLinesInfill( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs, dDist) + + -- box locale + local b3Loc = EgtGetBBoxRef( nStmId, GDB_BB.STANDARD, frLoc) + b3Loc:expand( dOffsStm) + local ptMin = b3Loc:getMin() + local ptMax = b3Loc:getMax() + local dZ = ptMin:getZ() + + local nGrp = EgtGroup( nInfillGrp, frLoc, GDB_RT.GLOB) + + -- calcolo la prima quota a cui tracciare la linea + local dY = ptMin:getY() + vtOffs:getY() % dDist + + -- calcolo le linee + while dY < ptMax:getY() + GEO.EPS_SMALL do + local ptS = Point3d( ptMin:getX(), dY, dZ) + local ptE = Point3d( ptMax:getX(), dY, dZ) + EgtCurveCompoFromPoints( nGrp, {ptS, ptE}) + dY = dY + dDist + end +end + +-------------------------------------------------------------------- +local function CalcSimpleGridInfill( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs, dDist) + + -- box locale + local b3Loc = EgtGetBBoxRef( nStmId, GDB_BB.STANDARD, frLoc) + b3Loc:expand( dOffsStm) + local ptMin = b3Loc:getMin() + local ptMax = b3Loc:getMax() + local dZ = ptMin:getZ() + + -- direzione principale + local nMainGrp = EgtGroup( nInfillGrp, frLoc, GDB_RT.GLOB) + local dY = ptMin:getY() + vtOffs:getY() % dDist + while dY < ptMax:getY() + GEO.EPS_SMALL do + local ptS = Point3d( ptMin:getX(), dY, dZ) + local ptE = Point3d( ptMax:getX(), dY, dZ) + EgtCurveCompoFromPoints( nMainGrp, {ptS, ptE}) + dY = dY + dDist + end + + -- direzione secondaria ( ortogonale alla principale) + local nOtherGrp = EgtGroup( nInfillGrp, frLoc, GDB_RT.GLOB) + local dX = ptMin:getX() + vtOffs:getX() % dDist + while dX < ptMax:getX() + GEO.EPS_SMALL do + local ptS = Point3d( dX, ptMin:getY(), dZ) + local ptE = Point3d( dX, ptMax:getY(), dZ) + EgtCurveCompoFromPoints( nOtherGrp, {ptS, ptE}) + dX = dX + dDist + end +end + +-------------------------------------------------------------------- +local function CompletePatternBaseCrv( nCrvBase, dAng, dDim1, dDim2, dMinY, dMaxY) + + local vtDir1 = VectorFromPolar( 1, dAng) + local vtDir2 = VectorFromPolar( 1, 180 - dAng) + + -- completo la curva base in Y+ + local ptNext = EgtEP( nCrvBase) + while ptNext:getY() < dMaxY do + ptNext = ptNext + dDim1 * vtDir1 + EgtAddCurveCompoLine( nCrvBase, ptNext) + ptNext = ptNext + dDim2 * Y_AX() + EgtAddCurveCompoLine( nCrvBase, ptNext) + ptNext = ptNext + dDim1 * vtDir2 + EgtAddCurveCompoLine( nCrvBase, ptNext) + ptNext = ptNext + dDim2 * Y_AX() + EgtAddCurveCompoLine( nCrvBase, ptNext) + end + + -- completo la curva base in Y- + ptNext = EgtSP( nCrvBase) + while ptNext:getY() > dMinY do + ptNext = ptNext - dDim1 * vtDir2 + EgtAddCurveCompoLine( nCrvBase, ptNext, false) + ptNext = ptNext - dDim2 * Y_AX() + EgtAddCurveCompoLine( nCrvBase, ptNext, false) + ptNext = ptNext - dDim1 * vtDir1 + EgtAddCurveCompoLine( nCrvBase, ptNext, false) + ptNext = ptNext - dDim2 * Y_AX() + EgtAddCurveCompoLine( nCrvBase, ptNext, false) + end + + return nCrvBase +end + +-------------------------------------------------------------------- +local function CalcPatternCrvs( nGrp, nCrvBase, dMinX, dMaxX, dAng, dDim1, dStrand) + + local ptRef = EgtSP( nCrvBase) + local dReflDist = dDim1 * cos( dAng) + dStrand * 0.5 + + -- rifletto la curva base in X+ + local nPrevCrv = nCrvBase + local dXRefl = ptRef:getX() + dReflDist + while dXRefl < dMaxX do + local nCurrCrv = EgtCopyGlob( nPrevCrv, nGrp, GDB_IN.LAST_SON) + -- riflessione + local ptRefl = Point3d( dXRefl, ptRef:getY(), ptRef:getZ()) + EgtMirror( nCurrCrv, ptRefl, X_AX()) + -- aggiorno per iterazione successiva + nPrevCrv = nCurrCrv + dXRefl = dXRefl + dReflDist + 0.5 * dStrand + end + + -- rifletto la curva base in X- + nPrevCrv = nCrvBase + dXRefl = ptRef:getX() - dStrand / 2 + while dXRefl > dMinX do + local nCurrCrv = EgtCopyGlob( nPrevCrv, nGrp, GDB_IN.FIRST_SON) + -- riflessione + local ptRefl = Point3d( dXRefl, ptRef:getY(), ptRef:getZ()) + EgtMirror( nCurrCrv, ptRefl, X_AX()) + -- aggiorno per iterazione successiva + nPrevCrv = nCurrCrv + dXRefl = dXRefl - dReflDist - 0.5 * dStrand + end +end + +-------------------------------------------------------------------- +local function CalcGridFromPattern( nInfillGrp, nStmId, dOffsStm, frRef, vtOffs, dDim1, dDim2, dAng, vSlicesAng, dStrand, vtSlicing) + + -- direzione principale + local frLoc = Frame3d( frRef) + frLoc:rotate( ORIG(), vtSlicing, vSlicesAng[1]) + local nMainGrp = EgtGroup( nInfillGrp, frLoc, GDB_RT.GLOB) + + -- recupero il box del pezzo nel frame della direzione principale + local b3Loc = EgtGetBBoxRef( nStmId, GDB_BB.STANDARD, frLoc) + b3Loc:expand( dOffsStm) + local ptMin = b3Loc:getMin() + local ptMax = b3Loc:getMax() + + -- creo la curva base + vtOffs:locToLoc( frRef, frLoc) + local pt1 = ptMin + vtOffs + local pt2 = pt1 + dDim2 * Y_AX() + local nCrvBase = EgtCurveCompoFromPoints( nMainGrp, {pt1, pt2}) + if not nCrvBase then + -- caso zigzag con nOverlapGrid = 100 ( dDim2 = 0) + local vtDir1 = VectorFromPolar( 1, dAng) + local vtDir2 = VectorFromPolar( 1, 180 - dAng) + pt2 = pt1 + vtDir1 * dDim1 + nCrvBase = EgtCurveCompoFromPoints( nMainGrp, {pt1, pt2}) + pt2 = pt2 + vtDir2 * dDim1 + EgtAddCurveCompoLine( nCrvBase, pt2) + end + CompletePatternBaseCrv( nCrvBase, dAng, dDim1, dDim2, ptMin:getY(), ptMax:getY()) + + -- preparo le altre curve + CalcPatternCrvs( nMainGrp, nCrvBase, ptMin:getX(), ptMax:getX(), dAng, dDim1, dStrand) + + -- calcolo centro di rotazione + local dDimPattern = 2 * dDim2 + 2 * dDim1 * sin( dAng) + local dDimTot = ( EgtEP( nCrvBase):getY() - EgtSP( nCrvBase):getY()) - dDim2 + local dExtra = floor( dDimTot / dDimPattern * 0.5) * dDimPattern + local ptCen = EgtSP( nCrvBase) + ( 3/2 * dDim2 + sin( dAng) * dDim1) * Y_AX() - dStrand * 0.5 * X_AX() + dExtra * Y_AX() + + for i = 2, #vSlicesAng do + + -- calcolo il nuovo riferimento + local frLoc2 = Frame3d( frRef) + frLoc2:rotate( ORIG(), vtSlicing, vSlicesAng[i]) + local nGrp = EgtGroup( nInfillGrp, frLoc2, GDB_RT.GLOB) + + -- calcolo il box del pezzo nel nuovo riferimento + local b3Loc2 = EgtGetBBoxRef( nStmId, GDB_BB.STANDARD, frLoc2) + b3Loc2:expand( dOffsStm) + local ptMin2 = b3Loc2:getMin() + local ptMax2 = b3Loc2:getMax() + + -- creo curva base ruotando la curva base della direzione principale + local nCrvBase2 = EgtCopyGlob( nCrvBase, nMainGrp) + EgtRotate( nCrvBase2, ptCen, Z_AX(), vSlicesAng[i] - vSlicesAng[1]) + EgtRelocateGlob( nCrvBase2, nGrp) + CompletePatternBaseCrv( nCrvBase2, dAng, dDim1, dDim2, ptMin2:getY(), ptMax2:getY()) + + -- preparo le altre curve + CalcPatternCrvs( nGrp, nCrvBase2, ptMin2:getX(), ptMax2:getX(), dAng, dDim1, dStrand) + end + +end + +-------------------------------------------------------------------- +local function CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, nGridOverlap, nStmId, dOffsStm, dStrand, vtSlicing) + + -- frame locale alla direzione dell'infill + local frLoc = Frame3d( ORIG(), vtSlicing) + frLoc:rotate( ORIG(), vtSlicing, dDir) + + -- distanza fra le varie passate + local dDist = 100 / dDensity * dStrand + + -- offset in X e Y + local vtOffs = Vector3d( dOffsX, dOffsY, 0) + vtOffs:toLoc( frLoc) + + -- eventuale correzione di nGridOverlap + if nType ~= FILL_TYPE.LINES and nType ~= FILL_TYPE.GRID and dDensity > 85 then + EgtOutLog( 'Warning: InfillGridOverlap is ignored due to high infill density - CalcSlices') + nGridOverlap = 0 + end + + -- creo le curve di infill + if nType == FILL_TYPE.LINES then + CalcLinesInfill( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs, dDist) + + elseif nType == FILL_TYPE.GRID then + CalcSimpleGridInfill( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs, dDist) + + elseif nType == FILL_TYPE.ZIG_ZAG_GRID then + local dRealStrand = ( 1 - nGridOverlap / 100) * dStrand + local dAng = 45 + local dDim1 = ( dDist - dStrand) * sqrt(2) + local dDim2 = dRealStrand + local vSlicesAng = {-45, 45} + CalcGridFromPattern( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs, dDim1, dDim2, dAng, vSlicesAng, dRealStrand, vtSlicing) + + elseif nType == FILL_TYPE.HONEYCOMB or nType == FILL_TYPE.HONEYCOMB_GRID then + local dRealStrand = ( 1 - nGridOverlap / 100) * dStrand + local dAng = 30 + local dDim1 = ( dDist - dStrand) / cos(30) + local dDim2 = dDim1 + sqrt(3) * dRealStrand + local vSlicesAng = EgtIf( nType == FILL_TYPE.HONEYCOMB, {0}, {0, 60, 120}) + CalcGridFromPattern( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs, dDim1, dDim2, dAng, vSlicesAng, dRealStrand, vtSlicing) + end +end + +-------------------------------------------------------------------- +local function PrepareInfill( nStmId, vtSlicing) + + -- verifco se richiesto infill + local nShells = EgtGetInfo( s_nPartId, KEY_SHELLS_NBR, 'i') + if nShells == 0 then return end + local nType = EgtGetInfo( s_nPartId, KEY_INFILL_TYPE, 'i') or FILL_TYPE.NONE + if nType == FILL_TYPE.NONE then return end + local dDensity = EgtGetInfo( s_nPartId, KEY_INFILL_DENSITY, 'd') or 0 + if dDensity < GEO.EPS_SMALL then return end + + -- recupero i parametri per infill + local dDir = EgtGetInfo( s_nPartId, KEY_INFILL_DIR, 'd') or 0 + local dOffsX = EgtGetInfo( s_nPartId, KEY_INFILL_OFFSET_X, 'd') or 0 + local dOffsY = EgtGetInfo( s_nPartId, KEY_INFILL_OFFSET_Y, 'd') or 0 + local nGridOverlap = EgtGetInfo( s_nPartId, KEY_INFILL_GRID_OVERLAP, 'i') or 0 + local dOffsStm = EgtGetInfo( s_nPartId, KEY_OFFSET_SLICE, 'd') + local dStrand = EgtGetInfo( s_nPartId, KEY_STRAND, 'd') + + -- creo gruppo per infill + local nInfillGrp = EgtGroup( s_nPartId) + EgtSetName( nInfillGrp, INFILL_GRP) + EgtSetStatus( nInfillGrp, GDB_ST.OFF) + + -- calcolo infill + CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, nGridOverlap, nStmId, dOffsStm, dStrand, vtSlicing) + + -- aggiungo allo slicing + SlicingInfill( nInfillGrp, vtSlicing, INFILL_CRV, INFILL_GRP) +end + +---------------------------------------------------------------------- +local function PrepareAuxSolidsInfill( nSolidsLay, vtSlicing) + + local vIds = EgtGetAllInGroup( nSolidsLay) + -- scorro tutti gli AuxSolids + for i = 1, #vIds do + if EgtGetType( vIds[i]) == GDB_TY.SRF_MESH then + -- verifico se da realizzare con infill e non con solidfill + local nType = ReadParam( vIds[i], KEY_AUX_SOLIDS_INFILL, 'i', FILL_TYPE.NONE) + if nType & FILL_CATEGORY.INFILL ~= 0 then + local dDensity = ReadParam( vIds[i], KEY_AUX_SOLIDS_DENSITY, 'd', 0) + if dDensity > GEO.EPS_SMALL then + + -- recupero i parametri per infill + local dDir = ReadParam( vIds[i], KEY_AUX_SOLIDS_DIR, 'd', 0) + local dOffsX = ReadParam( vIds[i], KEY_AUX_SOLIDS_OFFSET_X, 'd', 0) + local dOffsY = ReadParam( vIds[i], KEY_AUX_SOLIDS_OFFSET_Y, 'd', 0) + local nGridOverlap = ReadParam( vIds[i], KEY_AUX_SOLIDS_GRID_OVERLAP, 'i', 0) + local dStrand = EgtGetInfo( s_nPartId, KEY_STRAND, 'd') + + -- creo gruppo associato + local nInfillGrp = EgtGroup( s_nPartId) + EgtSetName( nInfillGrp, AUX_SOLIDS_INFILL_GRP .. tostring( vIds[i])) + EgtSetStatus( nInfillGrp, GDB_ST.OFF) + + -- calcolo infill + CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, nGridOverlap, vIds[i], 0, dStrand, vtSlicing) + + -- aggiungo allo slicing + local sName = AUX_SOLIDS_INFILL_CRV .. tostring( vIds[i]) .. '_' + SlicingInfill( nInfillGrp, vtSlicing, sName, AUX_SOLIDS_GRP) + end + end + end + end +end + +-------------------------------------------------------------------- +local function ExtractRibsLoops( nRibsGrp, nStmId) + + local nLoopGrp = EgtGroup( s_nPartId) + EgtSetName( nLoopGrp, RIBS_LOOP_GRP) + EgtSetStatus( nLoopGrp, GDB_ST.OFF) + + -- recupero tutti i setti + local vIds = EgtGetAllInGroup( nRibsGrp) + for i = 1, #vIds do + -- se trimesh + if EgtGetType( vIds[i]) == GDB_TY.SRF_MESH then + -- trim con il solido + local nCopy = EgtCopyGlob( vIds[i], nLoopGrp) + local nType = ReadParam( vIds[i], KEY_RIBS_TYPE, 'i', RIB_TYPE.INTERNAL) + EgtSurfTmCut( nCopy, nStmId, nType ~= RIB_TYPE.EXTERNAL, false) + -- estraggo i contorni + local nCrv, nCnt = EgtExtractSurfTmLoops( nCopy, nLoopGrp) + if nCrv then + -- assegno nome che permetta di ricondurli alla superficie da cui derivano + for nId = nCrv, nCrv + nCnt - 1 do + EgtSetName( nId, SURF_LOOP .. tostring( vIds[i])) + end + end + end + end +end + --------------------------------------------------------------------- local function ValueInArray( vArr, nValue) for _, val in ipairs( vArr) do @@ -364,7 +694,7 @@ local function ValueInArray( vArr, nValue) end --------------------------------------------------------------------- -local function SlicingNoSolid( nRibsLay, vZSlices, dDeltaZStart, dZmin, frSlicing, vErr) +local function SlicingNoSolid( nRibsLay, vZSlices, dDeltaZStart, dZmin, frSlicing) local vtSlicing = frSlicing:getVersZ() @@ -389,14 +719,14 @@ local function SlicingNoSolid( nRibsLay, vZSlices, dDeltaZStart, dZmin, frSlicin if EgtProcessEvents( EgtIf( PRINT, 100, 0) + 20, 0) == 1 then return false end -- slicing dei setti - SlicingExtraObjects( vtSlicing, nRibsLay, TYPE.RIB, RIBS_GRP, RIBS_CRV, vErr) + SlicingExtraObjects( nRibsLay, vtSlicing, TYPE.RIB, RIBS_CRV, RIBS_GRP) if EgtProcessEvents( EgtIf( PRINT, 100, 0) + 100, 0) == 1 then return false end return true end --------------------------------------------------------------------- -local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicing, vErr) +local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicing) local vtSlicing = frSlicing:getVersZ() @@ -407,6 +737,10 @@ local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicin local vPrevCen = {} local nLayCnt = 1 + local nCounterTot = #vZSlices + 12 + + local nFirstSolidLay -- primo layer che contiene il solido + local nLastSolidLay -- ultimo layer che contiene il solido -- scorro i risultati dello slicing while nLayId do @@ -424,7 +758,7 @@ local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicin local nRecalc = 0 while nId and not bRecalc do local nType = EgtGetType( nId) - if nType == GDB_TY.SRF_MESH then + if nType == GDB_TY.SRF_MESH then bRecalc = true vtRecalc = EgtSurfTmFacetNormVersor( nId, 0) elseif nType == GDB_TY.GEO_POINT then @@ -448,6 +782,13 @@ local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicin local vClosedId = {} local vOpenId = {} nId = EgtGetFirstInGroup( nLayId) + + -- se slicing del solido aggiorno i valori dei layer estremi che lo contengono + if nId then + if not nFirstSolidLay then nFirstSolidLay = nLayCnt end + nLastSolidLay = nLayCnt + end + while nId do if EgtGetType( nId) == GDB_TY.GEO_POINT or EgtGetType( nId) == GDB_TY.SRF_MESH then -- se punto o superficie lo elimino @@ -616,6 +957,10 @@ local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicin EgtSetColor( nId2, 'BLACK') end end + + if #vOpenId > 1 then + EgtOutLog( 'Error : hole in solid (layer '.. EgtNumToString( nLayCnt) ..') - CalcSlices') + end else local bErr = true @@ -632,7 +977,7 @@ local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicin -- se vero errore lo segnalo if bErr then EgtOutLog( 'Error : hole in solid (layer '.. EgtNumToString( nLayCnt) ..') - CalcSlices') - table.insert( vErr, nLayCnt) + table.insert( s_vErr, nLayCnt) -- cambio nome al layer EgtSetName( nLayId, '__' .. SLICE_LAYER .. EgtNumToString( nLayCnt)) else @@ -643,7 +988,7 @@ local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicin end -- passo al layer successivo - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + nLayCnt / ( #vZSlices + 3) * 100, 0) == 1 then + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + nLayCnt / nCounterTot * 100, 0) == 1 then -- elimino i layer non ancora analizzati local nNext = EgtGetNext( nLayId) while nNext do @@ -660,30 +1005,33 @@ local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicin local bSpiralVase = EgtGetInfo( s_nPartId, KEY_SPIRAL_VASE, 'b') or false if not bSpiralVase then + + -- infill + PrepareInfill( nStmId, vtSlicing) + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vZSlices + 3) / nCounterTot * 100, 0) == 1 then return false end + -- costolature local nRibsLay = EgtGetFirstNameInGroup( s_nPartId, LAY_RIBS) - if nRibsLay then - ExtractRibsLoops( nRibsLay, nStmId) - SlicingExtraObjects( vtSlicing, nRibsLay, TYPE.RIB, RIBS_GRP, RIBS_CRV, vErr, nStmId) - end - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vZSlices + 1) / ( #vZSlices + 3) * 100, 0) == 1 then return false end + ExtractRibsLoops( nRibsLay, nStmId) + SlicingExtraObjects( nRibsLay, vtSlicing, TYPE.RIB, RIBS_CRV, RIBS_GRP, nStmId) + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vZSlices + 6) / nCounterTot * 100, 0) == 1 then return false end -- solidi per regioni con diverso numero di passate local nShellNbrLay = EgtGetFirstNameInGroup( s_nPartId, LAY_SHELL_NBR) - if nShellNbrLay then - SlicingExtraObjects( vtSlicing, nShellNbrLay, TYPE.EXTRA_SHELL, SHELL_NBR_GRP, SHELL_NBR_CRV, vErr, nStmId) - end - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vZSlices + 2) / ( #vZSlices + 3) * 100, 0) == 1 then return false end + SlicingExtraObjects( nShellNbrLay, vtSlicing, TYPE.EXTRA_SHELL, SHELL_NBR_CRV, SHELL_NBR_GRP) + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vZSlices + 9) / nCounterTot * 100, 0) == 1 then return false end -- solidi ausiliari local nAuxSolidsLay = EgtGetFirstNameInGroup( s_nPartId, LAY_AUX_SOLIDS) - if nAuxSolidsLay then - AdjustAuxSolids( nAuxSolidsLay) - SlicingExtraObjects( vtSlicing, nAuxSolidsLay, TYPE.AUX_SOLID, AUX_SOLIDS_GRP, AUX_SOLIDS_CRV, vErr, nStmId) - end - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vZSlices + 3) / ( #vZSlices + 3) * 100, 0) == 1 then return false end + SlicingExtraObjects( nAuxSolidsLay, vtSlicing, TYPE.AUX_SOLID, AUX_SOLIDS_CRV, AUX_SOLIDS_GRP) + PrepareAuxSolidsInfill( nAuxSolidsLay, vtSlicing) + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vZSlices + 12) / nCounterTot * 100, 0) == 1 then return false end + end + EgtSetInfo( s_nPartId, KEY_FIRST_SOLID_LAY, nFirstSolidLay) + EgtSetInfo( s_nPartId, KEY_LAST_SOLID_LAY, nLastSolidLay) + return true end @@ -758,19 +1106,18 @@ function CalcSlices.Exec( nPartId, nStmId, HMax) local vZSlices = ComputeZSlices( dSliceStep, dZmin, dDeltaZStart, dZmax) - local vErr = {} local bOk = true if not nStmId then -- caso senza solido e solo setti - bOk = SlicingNoSolid( nRibsLay, vZSlices, dDeltaZStart, dZmin, frSlicing, vErr) + bOk = SlicingNoSolid( nRibsLay, vZSlices, dDeltaZStart, dZmin, frSlicing) else -- caso con solido - bOk = SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicing, vErr) + bOk = SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicing) end -- eventuale segnalazione errori - if bOk and #vErr > 0 then - EgtOutBox( 'Slicing Error on layers :\n' .. table.concat( vErr, ','), 'SlicingCalc') + if bOk and #s_vErr > 0 then + EgtOutBox( 'Slicing Error on layers :\n' .. table.concat( s_vErr, ','), 'SlicingCalc') end return bOk diff --git a/LuaLibs/CalcToolPath.lua b/LuaLibs/CalcToolPath.lua index 9a569e9..93d231b 100644 --- a/LuaLibs/CalcToolPath.lua +++ b/LuaLibs/CalcToolPath.lua @@ -42,7 +42,11 @@ local function GetLayerParamsForToolPathCalc() LayerParams.dWipeDir = EgtGetInfo( s_nPartId, KEY_WIPE_DIR, 'd') or 0.0 LayerParams.vtSlicing = EgtGetInfo( s_nPartId, KEY_SLICING_DIR, 'v') LayerParams.dTDiam = EgtGetInfo( s_nPartId, KEY_TOOL_DIAM, 'd') - + -- parametri infill + LayerParams.dInfillCoasting = EgtGetInfo( s_nPartId, KEY_INFILL_COASTING, 'd') or 0 + LayerParams.dInfillWipe = EgtGetInfo( s_nPartId, KEY_INFILL_WIPE, 'd') or 0 + LayerParams.dInfillWipeDir = EgtGetInfo( s_nPartId, KEY_INFILL_WIPE_DIR, 'd') or 0 + return LayerParams end @@ -132,6 +136,9 @@ local function AddCurvesToToolPath( vEntIds, nTpathGrpId, nOrder, bInvert, vtSli end end + EgtSetInfo( vEntIds[i], KEY_ASSOCIATED_TP_CRV, vIds[nIdx]) + EgtSetInfo( vIds[nIdx], KEY_ASSOCIATED_P_CRV, vEntIds[i]) + EgtModifyCurveExtrusion( vIds[nIdx], vtSlicing, GDB_RT.GLOB) EgtSetColor( vIds[nIdx], EgtStdColor('GRAY')) EgtSetStatus( vIds[nIdx], GDB_ST.ON) @@ -141,42 +148,66 @@ local function AddCurvesToToolPath( vEntIds, nTpathGrpId, nOrder, bInvert, vtSli return vIds end -------------------------------------------------------------------- -local function AddLink( vCrv, nTpathGrpId, nLinkType, dLinkParam, dSPOffs, dStrand, vtSlicing) +------------------------------------------------------------------------- +local function AddStartPointOffsetOnLayer( nCrv, nCrvPrev, dSPOffs, nOrder, dStrand, vtSlicing, dLayH) - if not vCrv or #vCrv == 0 then return end - - local k = 0 - local bPrevClosed = EgtGetInfo( vCrv[1], KEY_CLOSED_CRV, 'b') or false - for i = 2, #vCrv do - -- il link ha senso solo su curve chiuse - local bCurrClosed = EgtCurveIsClosed( vCrv[i]) - if bCurrClosed and bPrevClosed then - -- aggiorno k per calcolo dell'offset - local sPrevName = EgtGetName( vCrv[i-1]) - local sCurrName = EgtGetName( vCrv[i]) - local nType = EgtGetInfo( vCrv[i], KEY_TYPE, 'i') - if sPrevName ~= sCurrName or nType == TYPE.INFILL or nType == TYPE.AUX_SOLID or nType == TYPE.RIB then - k = k + 1 + if not EgtCurveIsClosed( nCrv) then return end + + -- individuo eventuale curva di toolpath precendente da cui prendere il punto di partenza + local nPrev + local vPrevPath = EgtGetInfo( nCrv, EgtIf( nOrder == PRINT_ORDER.EXT_INT, KEY_PREV_CRV, KEY_NEXT_CRVS), 'vi') + if vPrevPath then + local nAssociatedPathCrv = EgtGetInfo( nCrv, KEY_ASSOCIATED_P_CRV, 'i') + for j = 1, #vPrevPath do + -- verifico se gli start point delle path curve sono sufficientemente vicini + if dist( EgtSP( vPrevPath[j], GDB_ID.ROOT), EgtSP( nAssociatedPathCrv, GDB_ID.ROOT)) < dStrand + 100 * GEO.EPS_SMALL then + nPrev = EgtGetInfo( vPrevPath[j], KEY_ASSOCIATED_TP_CRV, 'i') + break end - - -- se nessun raccordo modifico solo lo start point della curva - if nLinkType == LINK_TYPE.NONE then - local dLen = k * dSPOffs - if dSPOffs < 0 then - dLen = EgtCurveLength( vCrv[i]) + dLen - end - local dPar = EgtCurveParamAtLength( vCrv[i], dLen) - if dPar then EgtChangeClosedCurveStart( vCrv[i], dPar) end - - else - -- altrimenti verifico se ha senso creare raccordo - -- local dDist = dist( EgtEP( vCrv[i-1]), EgtSP( vCrv[i])) + end + elseif nCrvPrev then + -- caso ribs chiuse in cui manca info sul precedente/successivo ( TODO da migliorare!) + nPrev = nCrvPrev + end + if not nPrev then return end + + -- recupero punto di partenza originale prima di eventuale OffsetLeadPoint + local ptS = EgtGetInfo( nPrev, KEY_ORIGINAL_START_POINT, 'p') or EgtSP( nPrev, GDB_ID.ROOT) + EgtChangeClosedCurveStartPoint( nCrv, ptS, GDB_RT.GLOB) + local dLen = dSPOffs + if dSPOffs < 0 then + dLen = EgtCurveLength( nCrv) + dLen + end + local dPar = EgtCurveParamAtLength( nCrv, dLen) + if dPar then + EgtChangeClosedCurveStart( nCrv, dPar) + end +end + +------------------------------------------------------------------- +local function AddLink( vCrv, nTpathGrpId, nLinkType, dLinkParam, dSPOffs, dStrand, nOrder, vtSlicing) + + if not vCrv or #vCrv == 0 then return end + + if nLinkType == LINK_TYPE.NONE and abs( dSPOffs) > GEO.EPS_SMALL then + -- se nessun raccordo modifico solo lo start point delle curve + for i = 1, #vCrv do + AddStartPointOffsetOnLayer( vCrv[i], vCrv[i-1], dSPOffs, nOrder, dStrand) + end + + elseif nLinkType ~= LINK_TYPE.NONE then + -- modifico lo start point della prima curva + AddStartPointOffsetOnLayer( vCrv[1], nil, dSPOffs, nOrder, dStrand) + -- creo i raccordi + for i = 2, #vCrv do + -- il link ha senso solo su curva chiusa + if EgtCurveIsClosed( vCrv[i]) then + -- verifico se ha senso creare raccordo local dDist = EgtPointCurveDist( EgtEP( vCrv[i-1]), vCrv[i]) if dDist < dStrand + 10 * GEO.EPS_SMALL then local nLinkId -- modifico lo start point - local dLen = EgtCurveLength( vCrv[i-1]) - EgtIf( k > 1, abs( dSPOffs), 0) + local dLen = EgtCurveLength( vCrv[i-1]) - EgtIf( i > 2, abs( dSPOffs), 0) EgtTrimCurveEndAtLen( vCrv[i-1], dLen) EgtChangeClosedCurveStartPoint( vCrv[i], EgtEP( vCrv[i-1])) @@ -194,17 +225,19 @@ local function AddLink( vCrv, nTpathGrpId, nLinkType, dLinkParam, dSPOffs, dStra EgtRelocateGlob( nLinkId, nTpathGrpId, GDB_IN.LAST_SON) EgtErase( nGrpTmp) end - + if nLinkId then EgtRelocate( nLinkId, vCrv[i], GDB_IN.BEFORE) EgtModifyCurveExtrusion( nLinkId, vtSlicing, GDB_RT.GLOB) EgtSetInfo( nLinkId, KEY_TYPE, TYPE.LINK) EgtSetName( nLinkId, LINK_CRV) end + else + -- se raccordo non sensato perchè curve troppo distanti modifico lo start point + AddStartPointOffsetOnLayer( vCrv[i], vCrv[i-1], dSPOffs, nOrder, dStrand) end end end - bPrevClosed = bCurrClosed end end @@ -216,18 +249,23 @@ local function AddOffsetLeadPoint( vIds, nFirstCopy, dOffsetLP, nLinkType) if abs( dOffsetLP) > GEO.EPS_SMALL then for i = 1, nLast do + -- conservo lo start point originale per AddStartPointOffsetOnLayer + EgtSetInfo( vIds[i], KEY_ORIGINAL_START_POINT, EgtSP( vIds[i], GDB_ID.ROOT)) if dOffsetLP > GEO.EPS_SMALL then -- taglio curva EgtTrimCurveStartAtLen( vIds[i], dOffsetLP) else -- è necessario aggiungere un tratto - local nAddCrv = EgtCopyGlob( EgtIf( i == 1, nFirstCopy, vIds[i]), vIds[1], GDB_IN.AFTER) + local nAddCrv = EgtCopyGlob( EgtIf( i == 1 and nLinkType ~= LINK_TYPE.NONE, nFirstCopy, vIds[i]), vIds[1], GDB_IN.AFTER) EgtTrimCurveStartAtLen( nAddCrv, EgtCurveLength( nAddCrv) - abs( dOffsetLP)) - EgtAddCurveCompoCurve( vIds[i], nAddCrv, true, false) + if not EgtAddCurveCompoCurve( vIds[i], nAddCrv, true, false) then + -- se fallisce cancello il tratto da aggiungere + EgtErase( nAddCrv) + end end end end - + -- elimino curva aux usata per prima shell EgtErase( nFirstCopy) end @@ -322,54 +360,80 @@ local function AddRetraction( nCrvId, vtSlicing, dCoastingLen, dWipeLen, dWipeDi local nCoastingId if dCoastingLen > GEO.EPS_SMALL then nCoastingId = EgtCopyGlob( nCrvId, nCrvId, GDB_IN.AFTER) - local dPar = EgtCurveParamAtLength( nCoastingId, EgtCurveLength( nCoastingId) - dCoastingLen) + local dLenTrim = EgtCurveLength( nCoastingId) - dCoastingLen + dLenTrim = max( dLenTrim, MIN_LEN) + local dPar = EgtCurveParamAtLength( nCoastingId, dLenTrim) if not dPar then - EgtErase( nCoastingId) - nCoastingId = nil - else - EgtTrimCurveStartAtParam( nCoastingId, dPar) - -- aggiorno la curva originale - if dPar > GEO.EPS_SMALL then - EgtTrimCurveEndAtParam( nCrvId, dPar) - else - EgtErase( nCrvId) - end - EgtModifyCurveExtrusion( nCoastingId, vtSlicing, GDB_RT.GLOB) - EgtSetName( nCoastingId, COASTING_CRV) - EgtSetInfo( nCoastingId, KEY_TYPE, TYPE.COASTING) - EgtSetColor( nCoastingId, EgtStdColor('ORANGE')) + dPar = EgtCurveParamAtLength( nCoastingId, MIN_LEN) or 0 end + + EgtTrimCurveStartAtParam( nCoastingId, dPar) + -- aggiorno la curva originale + if dPar > GEO.EPS_SMALL then + EgtTrimCurveEndAtParam( nCrvId, dPar) + else + EgtErase( nCrvId) + end + EgtModifyCurveExtrusion( nCoastingId, vtSlicing, GDB_RT.GLOB) + EgtSetName( nCoastingId, COASTING_CRV) + EgtSetInfo( nCoastingId, KEY_TYPE, TYPE.COASTING) + EgtSetColor( nCoastingId, EgtStdColor('ORANGE')) end - + if dWipeLen > GEO.EPS_SMALL then local nWipeId if bClosed then - -- se era chiusa ( quindi analogo alle shell) + -- se chiusa ( shell, SolidFill di tipo offset, ribs chiusi) nWipeId = nCopyId nCopyId = nil EgtTrimCurveEndAtLen( nWipeId, dWipeLen) else + -- se extra shell, infill, spiral vase o rib che non termina sulla parete + local ptS = EgtEP( nCoastingId or nCrvId, GDB_ID.ROOT) local vtDir = EgtEV( nCoastingId or nCrvId, GDB_ID.ROOT) local dAng = dWipeDir + s_nDefaultWipeAng + -- verifico se necessario cambiare il segno all'angolo local bChangeSign = false + -- riempimento if nType == TYPE.INFILL or nType == TYPE.AUX_SOLID then local vtS = EgtGetInfo( nCrvId, KEY_ZIG_ZAG_DIR, 'v') - local bSameDir = AreSameVectorApprox( vtS, vtDir) - bChangeSign = ( bInverted == bSameDir) + if vtS then + -- solidfill a zigzag + if AreOppositeVectorApprox( vtS, vtDir) then bChangeSign = true end + else + -- riempimento generico ( linee, griglie, nido d'ape) + local nGrpLoc = EgtGroup( EgtGetParent( nCopyId), Frame3d( ORIG(), vtSlicing)) + local nAuxSurf = EgtGetInfo( nCrvId, KEY_ASSOCIATED_SURF, 'i') or GDB_ID.NULL + -- verifico se direzione di default punta verso esterno del solido + local vtDirTest = Vector3d( vtDir) + vtDirTest:rotate( vtSlicing, s_nDefaultWipeAng) + local nCrvTest = EgtCurveCompoFromPoints( nGrpLoc, { ptS + 10 * GEO.EPS_SMALL * vtDirTest, ptS + vtDirTest}, GDB_RT.GLOB) + local nRes = EgtCurveWithRegionClassify( nCrvTest, nAuxSurf) + if nRes ~= GDB_CRC.OUT then + -- se non punta verso esterno provo con la direzione opposta + EgtRotate( nCrvTest, ptS, vtSlicing, 180, GDB_RT.GLOB) + nRes = EgtCurveWithRegionClassify( nCrvTest, nAuxSurf) + if nRes == GDB_CRC.OUT then + bChangeSign = true + end + end + EgtErase( nGrpLoc) + end + -- rib elseif nType == TYPE.RIB then local bInvertStrandOrder = EgtGetInfo( nCrvId, KEY_RIBS_INVERT_STRAND_ORDER, 'b') or false local bInvertDir = EgtGetInfo( nCrvId, KEY_RIBS_INVERT_DIR, 'b') or false bChangeSign = ( bInvertDir ~= bInvertStrandOrder) + -- extra shell elseif nType == TYPE.EXTRA_SHELL or nType == TYPE.EXTRA_OUTER_SHELL then bChangeSign = bInverted end vtDir:rotate( vtSlicing, EgtIf( bChangeSign, - dAng, dAng)) - local ptS = EgtEP( nCoastingId or nCrvId, GDB_ID.ROOT) local ptE = FindWipeEndPoint( ptS, vtDir, dWipeLen, vtSlicing) nWipeId = EgtCurveCompoFromPoints( EgtGetParent( nCoastingId or nCrvId), {ptS, ptE}, GDB_RT.GLOB) EgtModifyCurveExtrusion( nWipeId, vtSlicing, GDB_RT.GLOB) @@ -419,7 +483,7 @@ local function CalcShellsToolPath( vEntIds, nTpathGrpId, LayerParams) local nFirstCopy = EgtCopyGlob( vIds[1], nTpathGrpId) -- necessaria per corretto offset lead point sulla shell esterna -- aggiungo gli opportuni raccordi - AddLink( vIds, nTpathGrpId, LayerParams.nLinkType, LayerParams.dLinkParam, LayerParams.dSPOffs, LayerParams.dStrand, LayerParams.vtSlicing) + AddLink( vIds, nTpathGrpId, LayerParams.nLinkType, LayerParams.dLinkParam, LayerParams.dSPOffs, LayerParams.dStrand, LayerParams.nOrder, LayerParams.vtSlicing) -- offset lead point AddOffsetLeadPoint( vIds, nFirstCopy, LayerParams.dOffsetLP, LayerParams.nLinkType) @@ -500,21 +564,102 @@ local function CalcExtraShellToolPath( vEntIds, nTpathGrpId, LayerParams) end end ---------------------------------------------------------------------- -local function CalcInfillToolPath( vEntIds, nTpathGrpId, LayerParams) +------------------------------------------------------------------------------------ +local function CalcSolidFillToolPath( nInfillGrp, nTpathGrpId, LayerParams) + + local vEntIds = EgtGetNameInGroup( nInfillGrp, INFILL_CRV ..'*') + if not vEntIds or #vEntIds == 0 then return end + local nSolidFillType = EgtGetInfo( nInfillGrp, KEY_FILL_TYPE, 'i') or FILL_TYPE.ZIG_ZAG + + local nOrder = PRINT_ORDER.EXT_INT + local bInvert = false + if nSolidFillType == FILL_TYPE.OFFSET then + -- copio i valori per le shell + nOrder = LayerParams.nOrder + bInvert = LayerParams.bInvert + end - if not vEntIds then return end -- aggiungo le curve nel toolpath - local vIds = AddCurvesToToolPath( vEntIds, nTpathGrpId, LayerParams.nOrder, LayerParams.bInvert, LayerParams.vtSlicing, LayerParams.dLayHeight) + local vIds = AddCurvesToToolPath( vEntIds, nTpathGrpId, nOrder, bInvert, LayerParams.vtSlicing, LayerParams.dLayHeight) - -- aggiungo eventuali link - AddLink( vIds, nTpathGrpId, LayerParams.nLinkType, LayerParams.dLinkParam, LayerParams.dSPOffs, LayerParams.dStrand, LayerParams.vtSlicing) + -- se riempimento ad offset sistemo come nel caso delle shell + if nSolidFillType == FILL_TYPE.OFFSET then + local nFirstCopy = EgtCopyGlob( vIds[1], nTpathGrpId) + -- aggiungo gli opportuni raccordi + AddLink( vIds, nTpathGrpId, LayerParams.nLinkType, LayerParams.dLinkParam, LayerParams.dSPOffs, LayerParams.dStrand, LayerParams.nOrder, LayerParams.vtSlicing) + -- offset lead point + AddOffsetLeadPoint( vIds, nFirstCopy, LayerParams.dOffsetLP, LayerParams.nLinkType) + end -- aggiungo coasting/wipe for i = 1, #vIds do local nNextId = EgtGetNext( vIds[i]) if not nNextId or EgtGetInfo( nNextId, KEY_TYPE, 'i') ~= TYPE.LINK then - AddRetraction( vIds[i], LayerParams.vtSlicing, LayerParams.dCoastingLen, LayerParams.dWipeLen, LayerParams.dWipeDir) + AddRetraction( vIds[i], LayerParams.vtSlicing, LayerParams.dInfillCoasting, LayerParams.dInfillWipe, LayerParams.dInfillWipeDir) + end + end +end + +--------------------------------------------------------------------- +local function CalcInfillToolPath( nInfillGrp, nTpathGrpId, LayerParams) + + local vEntIds = EgtGetNameInGroup( nInfillGrp, INFILL_CRV ..'*') + if not vEntIds or #vEntIds == 0 then return end + + -- aggiungo le curve nel toolpath + local vIds = AddCurvesToToolPath( vEntIds, nTpathGrpId, PRINT_ORDER.EXT_INT, false, LayerParams.vtSlicing, LayerParams.dLayHeight) + + -- aggiungo coasting e wipe + for i = 1, #vIds do + AddRetraction( vIds[i], LayerParams.vtSlicing, LayerParams.dInfillCoasting, LayerParams.dInfillWipe, LayerParams.dInfillWipeDir) + end +end + +-------------------------------------------------------------------------------------- +local function JoinShellsAndSolidFills( nInfillGrp, vShellIds, vExtraShells, LayerParams, tabRibs) + + local nFillType = EgtGetInfo( nInfillGrp, KEY_FILL_TYPE, 'i') or FILL_TYPE.NONE + + if nFillType == FILL_TYPE.OFFSET and vShellIds then + + -- cerco indice di realizzazione dei vari elementi di stampa + local vTypeSequence = {} + for i = 1, #LayerParams.vPrintOrder do + vTypeSequence[LayerParams.vPrintOrder[i]] = i + end + + local nMin = vTypeSequence[PRINT_ELEMENT.SHELL] + local nMax = vTypeSequence[PRINT_ELEMENT.INFILL] + local bShellFirst = true + if nMin > nMax then + nMin, nMax = nMax, nMin + bShellFirst = false + end + + -- verifico se extra shell realizzate tra shell e infill + if vExtraShells and nMin < vTypeSequence[PRINT_ELEMENT.EXTRA_SHELL] and vTypeSequence[PRINT_ELEMENT.EXTRA_SHELL] < nMax then + return + end + + -- verifico se esistono setti esterni o unbounded realizzati tra le shell e gli infill + if #tabRibs[RIB_TYPE.UNBOUNDED] > 0 and nMin < vTypeSequence[PRINT_ELEMENT.RIB_UNBOUNDED] and vTypeSequence[PRINT_ELEMENT.RIB_UNBOUNDED] < nMax then + return + elseif #tabRibs[RIB_TYPE.EXTERNAL] > 0 and nMin < vTypeSequence[PRINT_ELEMENT.RIB_EXTERNAL] and vTypeSequence[PRINT_ELEMENT.RIB_EXTERNAL] < nMax then + return + end + + -- verifico se ordinamento di shell e infill è coerente con PrintOrder + if ( bShellFirst and LayerParams.nOrder == PRINT_ORDER.INT_EXT) or ( not bShellFirst and LayerParams.nOrder == PRINT_ORDER.EXT_INT) then + return + end + + -- aggiungo le curve di infill a quelle di shell + local nPathGrp = EgtGetParent( vShellIds[1]) + local vInfillCrvs = EgtGetNameInGroup( nInfillGrp, INFILL_CRV ..'*') or {} + for k = 1, #vInfillCrvs do + table.insert( vShellIds, vInfillCrvs[k]) + -- le sposto nel PathGrp in modo da non gestirle una seconda volta quando vengono trattati gli infill + EgtRelocateGlob( vInfillCrvs[k], nPathGrp) end end end @@ -524,44 +669,49 @@ local function CalcAuxSolidsToolPath( nAuxSolidsGrp, nAuxSolidsPathGrp, nTpathGr if not nAuxSolidsGrp or not nAuxSolidsPathGrp then return end - -- recupero le curve relative al primo solido ausiliario - local sPrevName = AUX_SOLID_CRV + -- recupero le curve di slicing relative al primo solido ausiliario local nSolidId = EgtGetFirstNameInGroup( nAuxSolidsGrp, AUX_SOLIDS_CRV .. '*') while nSolidId do + -- recupero tutti i percorsi relativi a quel solido local sName = EgtGetName( nSolidId) - if sName ~= sPrevName then - - -- recupero tutti i percorsi relativi a quel solido - local vEntIds = EgtGetNameInGroup( nAuxSolidsPathGrp, sName .. '*') - if vEntIds then - - -- recupero i parametri relativi al solido - local nOrder = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_PRINT_ORDER, 'i') + local vEntIds = EgtGetNameInGroup( nAuxSolidsPathGrp, sName .. '*') + if vEntIds then + + -- recupero i parametri relativi al solido dalla curva di slicing + local nFillType = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_INFILL, 'i') + local nOrder = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_PRINT_ORDER, 'i') + local dCoastingLen = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_COASTING_LEN, 'd') + local dWipeLen = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_WIPE_LEN, 'd') + 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) + + -- aggiungo link e offset lead point + if nFillType == FILL_TYPE.OFFSET or nFillType == FILL_TYPE.NONE 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') - local dCoastingLen = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_COASTING_LEN, 'd') - local dWipeLen = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_WIPE_LEN, 'd') - local dWipeDir = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_WIPE_DIR, 'd') - - -- copio i percorsi nel gruppo toolpath - local vIds = AddCurvesToToolPath( vEntIds, nTpathGrpId, nOrder, LayerParams.bInvert, LayerParams.vtSlicing, LayerParams.dLayHeight) - - -- aggiungo link - AddLink( vIds, nTpathGrpId, nLinkType, dLinkParam, dSPOffset, LayerParams.dStrand, LayerParams.vtSlicing) + local dLPOffset = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_LP_OFFSET, 'd') - -- coasting e wipe - for i = 1, #vIds do - local nNextId = EgtGetNext( vIds[i]) - if not nNextId or EgtGetInfo( nNextId, KEY_TYPE, 'i') ~= TYPE.LINK then - AddRetraction( vIds[i], LayerParams.vtSlicing, dCoastingLen, dWipeLen, dWipeDir) - end + local nFirstCopy = EgtCopyGlob( vIds[1], nTpathGrpId) -- necessaria per avere il corretto offset lead point sulla shell esterna nel caso di link + AddLink( vIds, nTpathGrpId, nLinkType, dLinkParam, dSPOffset, LayerParams.dStrand, nOrder, LayerParams.vtSlicing) + AddOffsetLeadPoint( vIds, nFirstCopy, dLPOffset, nLinkType) + end + + -- coasting e wipe + for i = 1, #vIds do + local nNextId = EgtGetNext( vIds[i]) + if not nNextId or EgtGetInfo( nNextId, KEY_TYPE, 'i') ~= TYPE.LINK then + AddRetraction( vIds[i], LayerParams.vtSlicing, dCoastingLen, dWipeLen, dWipeDir) end end end - sPrevName = sName - nSolidId = EgtGetNextName( nSolidId, AUX_SOLIDS_CRV .. '*') + + -- recupero il solido successivo + local nLastSolidId = EgtGetLastNameInGroup( nAuxSolidsGrp, sName) + nSolidId = EgtGetNextName( nLastSolidId, AUX_SOLIDS_CRV .. '*') end end @@ -1088,10 +1238,14 @@ local function CalcRibsToolPath( vEntIds, nRibsGrp, nTpathGrpId, LayerParams) EgtAddCurveCompoCurve( tabRibs[i][1], nLinkId) -- setto info di curva chiusa per gestire correttamente il wipe EgtSetInfo( tabRibs[i][1], KEY_CLOSED_CRV, 1) - -- modifica dello start point ( considera quello delle shell) + -- modifica dello start point usando lo stesso delle shell local nCrvGrp = EgtGetParent( nTpathGrpId) - local ptStart = EgtGetInfo( nCrvGrp, KEY_START_POINT, 'p') - if ptStart then + local nPathGrp = EgtGetFirstNameInGroup( nCrvGrp, PATH_GRP) + local nFirstShell = EgtGetFirstNameInGroup( nPathGrp, SHELL_CRV .. '*') + if nFirstShell then + -- verifico se già realizzato toolpath corrispondente + local nRefCrv = EgtGetInfo( nFirstShell, KEY_ASSOCIATED_TP_CRV, 'i') or nFirstShell + local ptStart = EgtSP( nFirstShell) EgtChangeClosedCurveStartPoint( tabRibs[i][1], ptStart) end else @@ -1337,37 +1491,50 @@ function CalcToolPath.Exec( nPartId) EgtEmptyGroup( nTpathGrpId) end - -- suddivido i ribs per tipologia + -- recupero gli elementi da stampare + local vShellIds = EgtGetNameInGroup( nPathGrpId, SHELL_CRV .. '*') + local vExtraShellIds = EgtGetNameInGroup( nPathGrpId, EXTRA_SHELL_CRV .. '*') + local nInfillGrp = EgtGetFirstNameInGroup( nCrvGrpId, INFILL_GRP) or GDB_ID.NULL + local nAuxSolidsGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], AUX_SOLIDS_GRP) + local nAuxSolidsPathGrp = EgtGetFirstNameInGroup( nCrvGrpId, AUX_SOLIDS_GRP) local nRibsGrp = EgtGetFirstNameInGroup( nCrvGrpId, RIBS_GRP) + + -- suddivido i ribs per tipologia local tRibs = {{}, {}, {}, {}} local vRibsIds = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*') or {} for i = 1, #vRibsIds do - local nType = EgtGetInfo( vRibsIds[i], KEY_RIBS_TYPE, 'i') or 1 + local nType = EgtGetInfo( vRibsIds[i], KEY_RIBS_TYPE, 'i') or RIB_TYPE.INTERNAL table.insert( tRibs[nType], vRibsIds[i]) end + -- eventuale unione delle shell e dei SolidFills + JoinShellsAndSolidFills( nInfillGrp, vShellIds, vExtraShellIds, LayerParams, tRibs) + -- realizzo le diverse tipologie in base all'ordine selezionato for j = 1, #LayerParams.vPrintOrder do - + + -- shell if LayerParams.vPrintOrder[j] == PRINT_ELEMENT.SHELL then - -- shell - local vShellIds = EgtGetNameInGroup( nPathGrpId, SHELL_CRV .. '*') CalcShellsToolPath( vShellIds, nTpathGrpId, LayerParams) + + -- extra shell elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.EXTRA_SHELL then - -- extra shell - local vExtraShellIds = EgtGetNameInGroup( nPathGrpId, EXTRA_SHELL_CRV .. '*') CalcExtraShellToolPath( vExtraShellIds, nTpathGrpId, LayerParams) + + -- infill elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.INFILL then - -- infill - local vInfillIds = EgtGetNameInGroup( nPathGrpId, INFILL_CRV .. '*') - CalcInfillToolPath( vInfillIds, nTpathGrpId, LayerParams) + local nFillType = EgtGetInfo( nInfillGrp, KEY_FILL_TYPE, 'i') or FILL_TYPE.NONE + if nFillType & FILL_CATEGORY.SOLID_FILL ~= 0 then + CalcSolidFillToolPath( nInfillGrp, nTpathGrpId, LayerParams) + else + CalcInfillToolPath( nInfillGrp, nTpathGrpId, LayerParams) + end + + -- solidi ausiliari elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.AUX_SOLID then - -- solidi ausiliari - local nAuxSolidsGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], AUX_SOLIDS_GRP) - local nAuxSolidsPathGrp = EgtGetFirstNameInGroup( nCrvGrpId, AUX_SOLIDS_GRP) CalcAuxSolidsToolPath( nAuxSolidsGrp, nAuxSolidsPathGrp, nTpathGrpId, LayerParams) - -- costolature + -- costolature elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_UNBOUNDED then CalcRibsToolPath( tRibs[RIB_TYPE.UNBOUNDED], nRibsGrp, nTpathGrpId, LayerParams) elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_INTERNAL then @@ -1377,7 +1544,6 @@ function CalcToolPath.Exec( nPartId) elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_EXTERNAL then CalcRibsToolPath( tRibs[RIB_TYPE.EXTERNAL], nRibsGrp, nTpathGrpId, LayerParams) end - end -- aggiorno il box dei toolpath @@ -1398,7 +1564,6 @@ function CalcToolPath.Exec( nPartId) AddZCorrection( b3Tot, LayerParams) return true - end --------------------------------------------------------------------- diff --git a/LuaLibs/RunSlicing.lua b/LuaLibs/RunSlicing.lua index eebe3bb..9f5c5a6 100644 --- a/LuaLibs/RunSlicing.lua +++ b/LuaLibs/RunSlicing.lua @@ -72,6 +72,13 @@ local function RemoveOldSlices( nPartId) if nRibsLoopsGrp then EgtErase( nRibsLoopsGrp) end + + -- rimuovo eventuali gruppi di infill (anche per aux solids) + local nInfillId = EgtGetFirstNameInGroup( nPartId, INFILL_GRP .. '*') + while nInfillId do + EgtErase( nInfillId) + nInfillId = EgtGetFirstNameInGroup( nPartId, INFILL_GRP .. '*') + end end --------------------------------------------------------------------- diff --git a/Version.lua b/Version.lua index 5d29cde..c1d3202 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.5e2' \ No newline at end of file +VERSION = '2.5e3' \ No newline at end of file