From d2c1d9a25a4562b0a7cf08bb90be5c3e656fad1b Mon Sep 17 00:00:00 2001 From: SaraP Date: Thu, 18 Jun 2026 08:57:26 +0200 Subject: [PATCH] 3dPrinting : - in presenza di floor e spiral vase separata gestione dei primi layers con floor ( fatti con ripartenze) da quelli senza floor ( fatti in spiral vase) - correzioni varie per floor e lead in. --- LuaLibs/CalcPaths.lua | 13 ++- LuaLibs/CalcToolPath.lua | 220 +++++++++++++++++++++++--------------- LuaLibs/RunCalcSolids.lua | 37 +++---- 3 files changed, 154 insertions(+), 116 deletions(-) diff --git a/LuaLibs/CalcPaths.lua b/LuaLibs/CalcPaths.lua index 0417107..f3bd40c 100644 --- a/LuaLibs/CalcPaths.lua +++ b/LuaLibs/CalcPaths.lua @@ -55,7 +55,6 @@ local function GetLayerParamsForPathCalc() -- eventuale modifica dei parametri per gestire correttamente il caso spiral vase if LayerParams.bSpiralVase then - LayerParams.nFloorNbr = 0 LayerParams.nCeilNbr = 0 end @@ -4475,20 +4474,20 @@ function CalcPaths.Exec( nPartId) end -- 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 + if nAuxSolidsGrp and LayerParams.nFloorNbr < nIdx and nIdx <= nLastSolidLay - LayerParams.nCeilNbr 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 + if nIdx <= LayerParams.nFloorNbr then CalcSolidFillPath( vLayIds[nIdx], LayerParams, vPtStart, LayerParams.nFloorType) + -- infill + elseif nIdx <= nLastSolidLay - LayerParams.nCeilNbr then + CalcInfillPaths( vLayIds[nIdx], nInfillGrp, LayerParams) -- ceil - elseif nLastSolidLay - LayerParams.nCeilNbr < nIdx and nIdx <= nLastSolidLay then + else CalcSolidFillPath( vLayIds[nIdx], LayerParams, vPtStart, LayerParams.nCeilType) end end diff --git a/LuaLibs/CalcToolPath.lua b/LuaLibs/CalcToolPath.lua index 881fb77..eec40b4 100644 --- a/LuaLibs/CalcToolPath.lua +++ b/LuaLibs/CalcToolPath.lua @@ -51,6 +51,7 @@ local function GetLayerParamsForToolPathCalc() LayerParams.vtSlicing = EgtGetInfo( s_nPartId, KEY_SLICE_DIR, 'v') LayerParams.dTDiam = EgtGetInfo( s_nPartId, KEY_TOOL_DIAM, 'd') -- parametri infill + LayerParams.nFloorNbr = EgtGetInfo( s_nPartId, KEY_FLOOR_NBR, 'i') or 0 LayerParams.dInfillStrand = EgtGetInfo( s_nPartId, KEY_INFILL_STRAND, 'd') or LayerParams.dStrand if LayerParams.dInfillStrand < GEO.EPS_SMALL then LayerParams.dInfillStrand = LayerParams.dStrand end LayerParams.bInfillLink = EgtGetInfo( s_nPartId, KEY_INFILL_LINK, 'b') or false @@ -259,25 +260,29 @@ local function AddStartPointOffsetOnLayer( nCrv, nCrvPrev, dSPOffs, nOrder, vtSl if not EgtCurveIsClosed( nCrv) then return end - local dStrand = EgtGetInfo( nCrv, KEY_CRV_STRAND, 'd') -- 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') - local nPrevFirst = EgtGetInfo( vPrevPath[1], KEY_ASSOCIATED_TP_CRV, 'i') - local dOtherStrand = EgtGetInfo( nPrevFirst, KEY_CRV_STRAND, 'd') + local dStrand = EgtGetInfo( nCrv, KEY_CRV_STRAND, 'd') 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 + dOtherStrand) * 0.5 + 100 * GEO.EPS_SMALL then - nPrev = EgtGetInfo( vPrevPath[j], KEY_ASSOCIATED_TP_CRV, 'i') - break + -- verifico se è stato realizzato + local nPrevTPath = EgtGetInfo( vPrevPath[j], KEY_ASSOCIATED_TP_CRV, 'i') + if nPrevTPath then + local dPrevStrand = EgtGetInfo( nPrevTPath, KEY_CRV_STRAND, 'd') + -- 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 + dPrevStrand) * 0.5 + 100 * GEO.EPS_SMALL then + nPrev = nPrevTPath + break + end end end - elseif nCrvPrev then - -- caso ribs chiuse in cui manca info sul precedente/successivo ( TODO da migliorare!) + end + if not nPrev then nPrev = nCrvPrev end + if not nPrev then return end -- recupero punto di partenza originale prima di eventuale OffsetLeadPoint @@ -300,7 +305,8 @@ local function AddLink( vCrv, nTpathGrpId, nLinkType, dLinkParam, dSPOffs, nOrde 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[1], nil, dSPOffs, nOrder) + for i = 2, #vCrv do AddStartPointOffsetOnLayer( vCrv[i], vCrv[i-1], dSPOffs, nOrder) end @@ -611,7 +617,7 @@ local function AddRetractionOnLastCrv( nCrvId, nTpathGrpId, LayerParams, dCoasti end --------------------------------------------------------------------- -local function CalcShellsToolPath( vEntIds, nTpathGrpId, bFirst, LayerParams) +local function CalcShellsToolPath( vEntIds, nTpathGrpId, bFirst, bFirstElementOnLayer, LayerParams) if not vEntIds or #vEntIds == 0 then return end @@ -638,7 +644,7 @@ local function CalcShellsToolPath( vEntIds, nTpathGrpId, bFirst, LayerParams) AddOffsetLeadPoint( vIds, nFirstCopy, LayerParams.dOffsetLP, LayerParams.nLinkType) -- aggiungo leadin/leadout - if LayerParams.nLeadInType ~= LEAD_TYPE.NONE then + if bFirstElementOnLayer and LayerParams.nLeadInType ~= LEAD_TYPE.NONE then if bFirst or not LayerParams.bSingleLeadIn then AddLeadIn( vIds[1], LayerParams, nTpathGrpId) end @@ -1002,11 +1008,14 @@ local function CalcSolidFillToolPath( nInfillGrp, nTpathGrpId, LayerParams) AddOffsetLeadPoint( vIds, nFirstCopy, LayerParams.dOffsetLP, LayerParams.nLinkType) end - -- aggiungo coasting/wipe + -- aggiungo coasting/wipe con i parametri della shell se di tipo offset o con quelli di infill se di tipo zigzag + local dCoasting = EgtIf( nSolidFillType == FILL_TYPE.OFFSET, LayerParams.dCoastingLen, LayerParams.dInfillCoasting) + local dWipe = EgtIf( nSolidFillType == FILL_TYPE.OFFSET, LayerParams.dWipeLen, LayerParams.dInfillWipe) + local dWipeDir = EgtIf( nSolidFillType == FILL_TYPE.OFFSET, LayerParams.dWipeDir, LayerParams.dInfillWipeDir) 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.dInfillCoasting, LayerParams.dInfillWipe, LayerParams.dInfillWipeDir) + AddRetraction( vIds[i], dCoasting, dWipe, dWipeDir) end end end @@ -2145,6 +2154,8 @@ local function SpiralVaseFullMultiPlanar( vLayIds, LayerParams) -- ciclo sui layer for nIdx = 1, #vLayIds do + local nSliceNbr = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_NBR, 'i') + -- recupero il piano di slicing local vtSlicing = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_DIR, 'v') local ptSlicing = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_POS, 'p') @@ -2153,7 +2164,7 @@ local function SpiralVaseFullMultiPlanar( vLayIds, LayerParams) local vCrvGrpIds = EgtGetNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*") if #vCrvGrpIds > 1 then -- se più di un gruppo di curve errore - EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nIdx) .. ' has more than one toolpath', 'ToolPathCalc') + EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nSliceNbr) .. ' has more than one toolpath', 'ToolPathCalc') return false end @@ -2178,7 +2189,7 @@ local function SpiralVaseFullMultiPlanar( vLayIds, LayerParams) -- creo il percorso di lavoro : local vEntIds = EgtGetAllInGroup( nPathGrpId) if #vEntIds > 1 then - EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nIdx) .. ' has more than one toolpath', 'ToolPathCalc') + EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nSliceNbr) .. ' has more than one toolpath', 'ToolPathCalc') return false end @@ -2201,10 +2212,12 @@ local function SpiralVaseFullMultiPlanar( vLayIds, LayerParams) -- eventuale lead in if LayerParams.nLeadInType ~= LEAD_TYPE.NONE then - EgtTrimCurveStartAtLen( nNewEntId, LayerParams.dOffsetLP) - local nLeadInCrv = AddLeadIn( nNewEntId, LayerParams, nTpathGrpId) - if nLeadInCrv and LayerParams.bLinearApprox then - EgtApproxCurve( nLeadInCrv, GDB_CA.LINES, LayerParams.dLinearApproxTol) + if not LayerParams.bSingleLeadIn or LayerParams.nFloorNbr == 0 then + EgtTrimCurveStartAtLen( nNewEntId, LayerParams.dOffsetLP) + local nLeadInCrv = AddLeadIn( nNewEntId, LayerParams, nTpathGrpId) + if nLeadInCrv and LayerParams.bLinearApprox then + EgtApproxCurve( nLeadInCrv, GDB_CA.LINES, LayerParams.dLinearApproxTol) + end end end @@ -2351,7 +2364,7 @@ local function SpiralVaseFullMultiPlanar( vLayIds, LayerParams) nRealLayer = nRealLayer + 1 end - if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / #vLayIds * 100, 0) == 1 then + if EgtProcessEvents( EgtIf( PRINT, 300, 0) + ( nIdx + LayerParams.nFloorNbr) / ( #vLayIds + LayerParams.nFloorNbr) * 100, 0) == 1 then EgtDraw() return false end @@ -2409,28 +2422,28 @@ local function SpiralVaseFull( vLayIds, LayerParams) local nRealLayer = 1 -- copio ultimo layer - if nSlicingType ~= SLICING_TYPE.DEG45_X and nSlicingType ~= SLICING_TYPE.DEG45_Y then - local nNewLay = EgtCopyGlob( vLayIds[#vLayIds], vLayIds[#vLayIds], GDB_IN.AFTER) - table.insert( vLayIds, nNewLay) - -- aggiorno nome e numero slice - local nSliceNbr = EgtGetInfo( nNewLay, KEY_SLICE_NBR, 'i') + 1 - EgtSetName( nNewLay, SLICE_LAYER .. EgtNumToString( nSliceNbr)) - EgtSetInfo( nNewLay, KEY_SLICE_NBR, nSliceNbr) - -- porto alla nuova quota - EgtMove( nNewLay, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) - local ptSlice = EgtGetInfo( nNewLay, KEY_SLICE_POS, 'p') - ptSlice = ptSlice + LayerParams.dLayHeight * LayerParams.vtSlicing - EgtSetInfo( nNewLay, KEY_SLICE_POS, ptSlice) - end + local nNewLay = EgtCopyGlob( vLayIds[#vLayIds], vLayIds[#vLayIds], GDB_IN.AFTER) + table.insert( vLayIds, nNewLay) + -- aggiorno nome e numero slice + local nSliceNbr = EgtGetInfo( nNewLay, KEY_SLICE_NBR, 'i') + 1 + EgtSetName( nNewLay, SLICE_LAYER .. EgtNumToString( nSliceNbr)) + EgtSetInfo( nNewLay, KEY_SLICE_NBR, nSliceNbr) + -- porto alla nuova quota + EgtMove( nNewLay, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) + local ptSlice = EgtGetInfo( nNewLay, KEY_SLICE_POS, 'p') + ptSlice = ptSlice + LayerParams.dLayHeight * LayerParams.vtSlicing + EgtSetInfo( nNewLay, KEY_SLICE_POS, ptSlice) -- ciclo sui layer for nIdx = 1, #vLayIds do + local nSliceNbr = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_NBR, 'i') + -- cerco i gruppi di contorni local vCrvGrpIds = EgtGetNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*") if #vCrvGrpIds > 1 then -- se più di un gruppo di curve warning - EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nIdx) .. ' has more than one toolpath', 'ToolPathCalc') + EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nSliceNbr) .. ' has more than one toolpath', 'ToolPathCalc') return false end @@ -2455,19 +2468,12 @@ local function SpiralVaseFull( vLayIds, LayerParams) -- creo il percorso di lavoro : local vEntIds = EgtGetAllInGroup( nPathGrpId) if #vEntIds > 1 then - EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nIdx) .. ' has more than one toolpath', 'ToolPathCalc') + EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nSliceNbr) .. ' has more than one toolpath', 'ToolPathCalc') return false end local nNewEntId = EgtCopyGlob( vEntIds[1] or GDB_ID.NULL, nTpathGrpId, GDB_IN.LAST_SON) if nNewEntId then - - local vtMove = V_NULL() - -- eventuale spostamento dell'altezza layer - if nSlicingType == SLICING_TYPE.DEG45_X or nSlicingType == SLICING_TYPE.DEG45_Y then - vtMove = LayerParams.dLayHeight * LayerParams.vtSlicing - EgtMove( nNewEntId, vtMove, GDB_RT.GLOB) - end EgtModifyCurveExtrusion( nNewEntId, LayerParams.vtSlicing, GDB_RT.GLOB) EgtSetInfo( nNewEntId, KEY_CRV_STRAND, LayerParams.dStrand) @@ -2495,10 +2501,12 @@ local function SpiralVaseFull( vLayIds, LayerParams) -- eventuale lead in if LayerParams.nLeadInType ~= LEAD_TYPE.NONE then - EgtTrimCurveStartAtLen( nNewEntId, LayerParams.dOffsetLP) - local nLeadInCrv = AddLeadIn( nNewEntId, LayerParams, nTpathGrpId) - if nLeadInCrv and LayerParams.bLinearApprox then - EgtApproxCurve( nLeadInCrv, GDB_CA.LINES, LayerParams.dLinearApproxTol) + if not LayerParams.bSingleLeadIn or LayerParams.nFloorNbr == 0 then + EgtTrimCurveStartAtLen( nNewEntId, LayerParams.dOffsetLP) + local nLeadInCrv = AddLeadIn( nNewEntId, LayerParams, nTpathGrpId) + if nLeadInCrv and LayerParams.bLinearApprox then + EgtApproxCurve( nLeadInCrv, GDB_CA.LINES, LayerParams.dLinearApproxTol) + end end end else @@ -2515,7 +2523,7 @@ local function SpiralVaseFull( vLayIds, LayerParams) -- recupero la curva da usare come guida local nGuideId = EgtCopyGlob( nOldPathId, nPathGrpId) -- la rendo coerente con il toolpath - EgtMove( nGuideId, vtMove + LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) + EgtMove( nGuideId, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) if LayerParams.bInvert then EgtInvertCurve( nGuideId) end @@ -2614,7 +2622,7 @@ local function SpiralVaseFull( vLayIds, LayerParams) nRealLayer = nRealLayer + 1 end - if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / #vLayIds * 100, 0) == 1 then + if EgtProcessEvents( EgtIf( PRINT, 300, 0) + ( nIdx + LayerParams.nFloorNbr) / ( #vLayIds + LayerParams.nFloorNbr) * 100, 0) == 1 then EgtDraw() return false end @@ -2643,6 +2651,8 @@ local function SpiralVasePartialMultiPlanar( vLayIds, LayerParams) -- ciclo sui layer local nOldId for nIdx = 1, #vLayIds do + + local nSliceNbr = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_NBR, 'i') -- piano di slicing local vtSlicing = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_DIR, 'v') @@ -2652,7 +2662,7 @@ local function SpiralVasePartialMultiPlanar( vLayIds, LayerParams) local vCrvGrpIds = EgtGetNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*") if #vCrvGrpIds > 1 then -- se più di un gruppo di curve errore - EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nIdx) .. ' has more than one toolpath', 'ToolPathCalc') + EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nSliceNbr) .. ' has more than one toolpath', 'ToolPathCalc') return false end @@ -2677,7 +2687,7 @@ local function SpiralVasePartialMultiPlanar( vLayIds, LayerParams) -- creo il percorso di lavoro local vEntIds = EgtGetAllInGroup( nPathGrpId) if #vEntIds > 1 then - EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nIdx) .. ' has more than one toolpath', 'ToolPathCalc') + EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nSliceNbr) .. ' has more than one toolpath', 'ToolPathCalc') return false end @@ -2782,10 +2792,12 @@ local function SpiralVasePartialMultiPlanar( vLayIds, LayerParams) if bFirst then bFirst = false if LayerParams.nLeadInType ~= LEAD_TYPE.NONE then - EgtTrimCurveStartAtLen( nNewEntId, LayerParams.dOffsetLP) - local nLeadInCrv = AddLeadIn( nNewEntId, LayerParams, nTpathGrpId) - if nLeadInCrv and LayerParams.bLinearApprox then - EgtApproxCurve( nLeadInCrv, GDB_CA.LINES, LayerParams.dLinearApproxTol) + if not LayerParams.bSingleLeadIn or LayerParams.nFloorNbr == 0 then + EgtTrimCurveStartAtLen( nNewEntId, LayerParams.dOffsetLP) + local nLeadInCrv = AddLeadIn( nNewEntId, LayerParams, nTpathGrpId) + if nLeadInCrv and LayerParams.bLinearApprox then + EgtApproxCurve( nLeadInCrv, GDB_CA.LINES, LayerParams.dLinearApproxTol) + end end end end @@ -2802,7 +2814,7 @@ local function SpiralVasePartialMultiPlanar( vLayIds, LayerParams) end end - if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / #vLayIds * 100, 0) == 1 then + if EgtProcessEvents( EgtIf( PRINT, 300, 0) + ( nIdx + LayerParams.nFloorNbr) / ( #vLayIds + LayerParams.nFloorNbr) * 100, 0) == 1 then EgtDraw() return false end @@ -2837,11 +2849,13 @@ local function SpiralVasePartial( vLayIds, LayerParams) local nOldId for nIdx = 1, #vLayIds do + local nSliceNbr = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_NBR, 'i') + -- cerco i gruppi di contorni local vCrvGrpIds = EgtGetNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*") if #vCrvGrpIds > 1 then -- se più di un gruppo di curve errore - EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nIdx) .. ' has more than one toolpath', 'ToolPathCalc') + EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nSliceNbr) .. ' has more than one toolpath', 'ToolPathCalc') return false end @@ -2866,7 +2880,7 @@ local function SpiralVasePartial( vLayIds, LayerParams) -- creo il percorso di lavoro local vEntIds = EgtGetAllInGroup( nPathGrpId) if #vEntIds > 1 then - EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nIdx) .. ' has more than one toolpath', 'ToolPathCalc') + EgtOutBox( 'Error in spiral vase : layer ' .. tostring( nSliceNbr) .. ' has more than one toolpath', 'ToolPathCalc') return false end @@ -2942,10 +2956,12 @@ local function SpiralVasePartial( vLayIds, LayerParams) if bFirst then bFirst = false if LayerParams.nLeadInType ~= LEAD_TYPE.NONE then - EgtTrimCurveStartAtLen( nNewEntId, LayerParams.dOffsetLP) - local nLeadInCrv = AddLeadIn( nNewEntId, LayerParams, nTpathGrpId) - if nLeadInCrv and LayerParams.bLinearApprox then - EgtApproxCurve( nLeadInCrv, GDB_CA.LINES, LayerParams.dLinearApproxTol) + if not LayerParams.bSingleLeadIn or LayerParams.nFloorNbr == 0 then + EgtTrimCurveStartAtLen( nNewEntId, LayerParams.dOffsetLP) + local nLeadInCrv = AddLeadIn( nNewEntId, LayerParams, nTpathGrpId) + if nLeadInCrv and LayerParams.bLinearApprox then + EgtApproxCurve( nLeadInCrv, GDB_CA.LINES, LayerParams.dLinearApproxTol) + end end end end @@ -2962,7 +2978,7 @@ local function SpiralVasePartial( vLayIds, LayerParams) end end - if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / #vLayIds * 100, 0) == 1 then + if EgtProcessEvents( EgtIf( PRINT, 300, 0) + ( nIdx + LayerParams.nFloorNbr) / ( #vLayIds + LayerParams.nFloorNbr) * 100, 0) == 1 then EgtDraw() return false end @@ -3000,9 +3016,8 @@ local function SpiralVase( vLayIds, LayerParams) end nLastLayer = EgtGetPrevName( nLastLayer, SLICE_LAYER .. '*') end - - -- correzione in z - AddZCorrection( LayerParams) + local nLastSliceNbr = EgtGetInfo( nLastLayer, KEY_SLICE_NBR, 'i') + EgtSetInfo( s_nPartId, KEY_LAYER_CNT, nLastSliceNbr) return true end @@ -3012,25 +3027,35 @@ function CalcToolPath.Exec( nPartId) s_nPartId = nPartId - -- Recupero i layer da processare + -- recupero i parametri per calcolo dei toolpath + local LayerParams = GetLayerParamsForToolPathCalc() + local nSlicingType = EgtGetInfo( s_nPartId, KEY_SLICING_TYPE, 'i') + local bFirst = true + + -- recupero i layer da processare local vLayIds = EgtGetNameInGroup( s_nPartId, SLICE_LAYER.."*") if not vLayIds or #vLayIds == 0 then EgtOutBox( 'Error missing slices', 'ToolPathCalc') return true end - -- recupero i parametri per calcolo dei toolpath - local LayerParams = GetLayerParamsForToolPathCalc() - local nSlicingType = EgtGetInfo( s_nPartId, KEY_SLICING_TYPE, 'i') - local bFirst = true - - -- caso spiral vase + -- se spiral vase divido i layer da realizzare in spirale da quelli da realizzare in modo classico con ripartenze ( sono i primi layers con riempimento) + local vSpiralVaseIds = {} if LayerParams.bSpiralVase then - return SpiralVase( vLayIds, LayerParams) + if LayerParams.nFloorNbr > 0 then + for i = LayerParams.nFloorNbr + 1, #vLayIds do + table.insert( vSpiralVaseIds, vLayIds[i]) + vLayIds[i] = nil + end + else + vSpiralVaseIds = vLayIds + vLayIds = {} + end end + + -- a) layer standard local nLayCnt = 1 - -- Ciclo sui layer for nIdx = 1, #vLayIds do s_nCurrIdx = nIdx @@ -3061,7 +3086,7 @@ function CalcToolPath.Exec( nPartId) -- recupero gli elementi da stampare local vShellIds = EgtGetNameInGroup( nPathGrpId, SHELL_CRV .. '*') - local vExtraShellIds = EgtGetNameInGroup( nPathGrpId, EXTRA_SHELL_CRV .. '*') + local vExtraShellIds = EgtGetNameInGroup( nPathGrpId, EXTRA_SHELL_CRV .. '*') or {} 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) @@ -3079,38 +3104,47 @@ function CalcToolPath.Exec( nPartId) JoinShellsAndSolidFills( nInfillGrp, vShellIds, vExtraShellIds, LayerParams, tRibs) -- realizzo le diverse tipologie in base all'ordine selezionato + local bFirstEntOnLayer = true for j = 1, #LayerParams.vPrintOrder do -- shell if LayerParams.vPrintOrder[j] == PRINT_ELEMENT.SHELL then - CalcShellsToolPath( vShellIds, nTpathGrpId, bFirst, LayerParams) + CalcShellsToolPath( vShellIds, nTpathGrpId, bFirst, bFirstEntOnLayer, LayerParams) + bFirstEntOnLayer = false -- extra shell - elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.EXTRA_SHELL then + elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.EXTRA_SHELL and #vExtraShellIds > 0 then CalcExtraShellToolPath( vExtraShellIds, nTpathGrpId, LayerParams) + bFirstEntOnLayer = false -- infill - elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.INFILL then + elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.INFILL and nInfillGrp then 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 + bFirstEntOnLayer = false -- solidi ausiliari - elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.AUX_SOLID then + elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.AUX_SOLID and nAuxSolidsGrp then CalcAuxSolidsToolPath( nAuxSolidsGrp, nAuxSolidsPathGrp, nTpathGrpId, LayerParams) + bFirstEntOnLayer = false -- costolature - elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_UNBOUNDED then + elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_UNBOUNDED and #tRibs[RIB_TYPE.UNBOUNDED] > 0 then CalcRibsToolPath( tRibs[RIB_TYPE.UNBOUNDED], nRibsGrp, nTpathGrpId, LayerParams) - elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_INTERNAL then + bFirstEntOnLayer = false + elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_INTERNAL and #tRibs[RIB_TYPE.INTERNAL] > 0 then CalcRibsToolPath( tRibs[RIB_TYPE.INTERNAL], nRibsGrp, nTpathGrpId, LayerParams) - elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_SUPPORT then + bFirstEntOnLayer = false + elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_SUPPORT and #tRibs[RIB_TYPE.SUPPORT] > 0 then CalcRibsToolPath( tRibs[RIB_TYPE.SUPPORT], nRibsGrp, nTpathGrpId, LayerParams) - elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_EXTERNAL then + bFirstEntOnLayer = false + elseif LayerParams.vPrintOrder[j] == PRINT_ELEMENT.RIB_EXTERNAL and #tRibs[RIB_TYPE.EXTERNAL] > 0 then CalcRibsToolPath( tRibs[RIB_TYPE.EXTERNAL], nRibsGrp, nTpathGrpId, LayerParams) + bFirstEntOnLayer = false end end @@ -3136,18 +3170,26 @@ function CalcToolPath.Exec( nPartId) nCrvGrpId = EgtGetNextName( nCrvGrpId, CONTOUR_GRP.."*") end - if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / #vLayIds * 100, 0) == 1 then + if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / ( #vLayIds + #vSpiralVaseIds) * 100, 0) == 1 then EgtDraw() return end end + + -- b) layer in spiral vase + if LayerParams.bSpiralVase then + SpiralVase( vSpiralVaseIds, LayerParams) + end + + -- setto info con numero di layers effettivi ( se spiral calcolato nella funzione) + if not LayerParams.bSpiralVase then + EgtSetInfo( nPartId, KEY_LAYER_CNT, nLayCnt) + end + -- correzione in z AddZCorrection( LayerParams) - - -- setto info con numero di layers effettivi - EgtSetInfo( nPartId, KEY_LAYER_CNT, nLayCnt) - + return true end diff --git a/LuaLibs/RunCalcSolids.lua b/LuaLibs/RunCalcSolids.lua index 3124640..c54ab5a 100644 --- a/LuaLibs/RunCalcSolids.lua +++ b/LuaLibs/RunCalcSolids.lua @@ -27,6 +27,7 @@ local function GetLayerParamsForSolidCalc( nPartId) LayerParams.vtSlicing = EgtGetInfo( nPartId, KEY_SLICE_DIR, 'v') or EgtGetInfo( nPartId, 'SlicingDir', 'v') LayerParams.dStrand = EgtGetInfo( nPartId, KEY_STRAND, 'd') LayerParams.vtCorr = EgtGetInfo( nPartId, KEY_MOVED_PART2, 'v') or V_NULL() + LayerParams.nFloorNbr = EgtGetInfo( s_nPartId, KEY_FLOOR_NBR, 'i') or 0 return LayerParams end @@ -448,20 +449,20 @@ end local function CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, nLayerId, bFirst) -- 1) le prime curve sono solidi multiplanari standard - for i = 1, #vIds - 1 do - CreateMultiPlanarSolids( { vIds[i]}, nSolidGrpId, LayerParams, nLayerId, bFirst) - end + local nLastId = vIds[#vIds] + vIds[#vIds] = nil + CreateMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, nLayerId, bFirst) -- 2) l'ultima curva è il tratto che si alza fino al layer successivo local nGrpTmp = EgtGroup( nSolidGrpId) - local dStrand = EgtGetInfo( vIds[#vIds], KEY_CRV_STRAND, 'd') or LayerParams.dStrand + local dStrand = EgtGetInfo( nLastId, KEY_CRV_STRAND, 'd') or LayerParams.dStrand -- a) calcolo il solido -- appiattisco la curva ( proiezione obliqua sul piano corrente lungo vtSlicing del piano successivo) local nNextLayerId = EgtGetNext( nLayerId) local vtSlicingNext = EgtGetInfo( nNextLayerId, KEY_SLICE_DIR, 'v') local ptSlicing = EgtGetInfo( nLayerId, KEY_SLICE_POS, 'p') + LayerParams.dLayHeight * LayerParams.vtSlicing + LayerParams.vtCorr - local nProjCrv = EgtCopyGlob( vIds[#vIds], nGrpTmp) + local nProjCrv = EgtCopyGlob( nLastId, nGrpTmp) local _, dE = EgtCurveDomain( nProjCrv) for dU = 0, dE do local ptCurr = EgtUP( nProjCrv, dU, GDB_ID.ROOT) @@ -470,8 +471,8 @@ local function CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, Laye end -- calcolo la sezione iniziale - local ptS = EgtSP( vIds[#vIds], GDB_ID.ROOT) - local ptE = EgtEP( vIds[#vIds], GDB_ID.ROOT) + local ptS = EgtSP( nLastId, GDB_ID.ROOT) + local ptE = EgtEP( nLastId, GDB_ID.ROOT) local vtDir = EgtSV( nProjCrv, GDB_ID.ROOT) vtDir:rotate( LayerParams.vtSlicing, 90) local nSectId = CreateSection( ptS, vtDir, dStrand, s_dMultiPlanarH, LayerParams.vtSlicing, nGrpTmp) @@ -481,7 +482,7 @@ local function CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, Laye local nSectE = CreateSection( ptE, vtDir2, dStrand, s_dMultiPlanarH, LayerParams.vtSlicing, nGrpTmp) -- creo le guide per il solido aperto ( tubo) - local dMaxDist = ( EgtEP( vIds[#vIds], GDB_ID.ROOT) - ptSlicing) * LayerParams.vtSlicing / ( vtSlicingNext * LayerParams.vtSlicing) + local dMaxDist = ( EgtEP( nLastId, GDB_ID.ROOT) - ptSlicing) * LayerParams.vtSlicing / ( vtSlicingNext * LayerParams.vtSlicing) local vCrvs = {} local _, dParE = EgtCurveDomain( nSectId) for i = 0, dParE do @@ -520,8 +521,8 @@ local function CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, Laye end end -- creazione del mezzo disco iniziale e finale - vSurfs[#vCrvs] = CreateSpiralVaseCap( nSectId, - EgtSV( vIds[#vIds], GDB_ID.ROOT), nSolidGrpId) - vSurfs[#vCrvs + 1] = CreateSpiralVaseCap( nSectE, EgtEV( vIds[#vIds], GDB_ID.ROOT), nSolidGrpId) + vSurfs[#vCrvs] = CreateSpiralVaseCap( nSectId, - EgtSV( nLastId, GDB_ID.ROOT), nSolidGrpId) + vSurfs[#vCrvs + 1] = CreateSpiralVaseCap( nSectE, EgtEV( nLastId, GDB_ID.ROOT), nSolidGrpId) EgtInvertSurf( vSurfs[#vSurfs]) local nSolidId = EgtSurfTmByTriangles( nSolidGrpId, vSurfs) @@ -642,7 +643,7 @@ local function CreateFullSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerPa local ptProj = ptVertex + dDistCrv * LayerParams.vtSlicing local dDistPlanePrev = ( ptProj - ptSlicingPrev) * vtSlicingPrev / dCosAng local dDeltaPos - if nSliceNbr == 2 and dCurrLen < 0.5 * dLen then + if nSliceNbr == 2 + LayerParams.nFloorNbr and dCurrLen < 0.5 * dLen then dDeltaPos = 0.5 * dDistPlanePrev else dDeltaPos = dDistPlanePrev * ( dLen - dCurrLen) / dLen @@ -650,18 +651,13 @@ local function CreateFullSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerPa -- 2) per calcolare la vera altezza del solido calcolo la distanza dal toolpath precedente guardando il punto di riferimento sul percorso corrente local dNewH - if nSliceNbr == 2 then + if nSliceNbr == 2 + LayerParams.nFloorNbr then -- il primo layer è ad altezza costante quindi è semplice distanza dal piano precedente lungo vtSlicing dNewH = ( ptProj - ptSlicingPrev) * vtSlicingPrev / dCosAng - dDeltaPos else local _, ptMinDistPrev = EgtPointCurveDist( ptMinDist, nPrevTPathRef, GDB_ID.ROOT) local dDistPlanePrev2 = ( ptMinDist - ptSlicingPrev) * vtSlicingPrev / dCosAng - local dDeltaPos2 - if nSliceNbr == 2 and dCurrLen < 0.5 * dLen then - dDeltaPos2 = 0.5 * dDistPlanePrev2 - else - dDeltaPos2 = dDistPlanePrev2 * ( dLen - dCurrLen) / dLen - end + local dDeltaPos2 = dDistPlanePrev2 * ( dLen - dCurrLen) / dLen dNewH = ( ptMinDist - ptMinDistPrev) * LayerParams.vtSlicing - dDeltaPos2 -- aggiungo un piccolo extra per tener conto che la distanza è stata calcolata sulle curve centrali del solido local dExtra = ( LayerParams.vtSlicing ^ vtSlicingPrev):len() / dCosAng * dStrand * 0.5 @@ -847,11 +843,11 @@ function RunCalcSolids.Exec() if nSlicingType == SLICING_TYPE.MULTIPLANAR or nSlicingType == SLICING_TYPE.MULTIPLANAR_DEG45 or nSlicingType == SLICING_TYPE.MULTIPLANAR_HOR then LayerParams.vtSlicing = EgtGetInfo( vLayIds[nIdx], KEY_SLICE_DIR, 'v') - if LayerParams.bSpiralVase then + if LayerParams.bSpiralVase and nIdx > LayerParams.nFloorNbr then local dTransitionLen = EgtGetInfo( nPartId, KEY_SPIRAL_VASE_LEN, 'd') or 0 -- a) spiral vase completo ( con transizione in altezza su tutto il layer) if dTransitionLen < GEO.EPS_SMALL then - if bFirst then + if nIdx == LayerParams.nFloorNbr + 1 then -- il primo layer va gestito come uno spiral vase con transizione parziale ( curva a quota costante e ultimo tratto che si alza) CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx], bFirst) elseif nIdx == #vLayIds then @@ -870,6 +866,7 @@ function RunCalcSolids.Exec() CreatePartialSpiralVaseMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx], bFirst) end end + -- c) multiplanare standard else CreateMultiPlanarSolids( vIds, nSolidGrpId, LayerParams, vLayIds[nIdx], bFirst)