From 213e6ac6ed6b433d10dd2009435cf4791ef1111c Mon Sep 17 00:00:00 2001 From: SaraP Date: Wed, 26 Oct 2022 16:12:25 +0200 Subject: [PATCH] 3dPrinting : - aggiunte tipologie per ribs ( interni, esterni, illimitati) - migliorie per ordinamento ribs. --- LuaLibs/AddManData.lua | 9 +- LuaLibs/CalcPaths.lua | 483 ++++++++++++++++++++++++++++----------- LuaLibs/CalcSlices.lua | 61 +---- LuaLibs/CalcToolPath.lua | 43 ++-- LuaLibs/RunSlicing.lua | 9 + 5 files changed, 397 insertions(+), 208 deletions(-) diff --git a/LuaLibs/AddManData.lua b/LuaLibs/AddManData.lua index 2c68cb1..8f3134b 100644 --- a/LuaLibs/AddManData.lua +++ b/LuaLibs/AddManData.lua @@ -38,7 +38,6 @@ SEC_DEFAULT = "Default" KEY_PARAMS = "Params" KEY_CALC_SOLIDS = "CalcSolids" KEY_SPIRAL_VASE = "SpiralVase" -KEY_SLICING_45 = "Slicing45" KEY_SLICING_TYPE = "SlicingType" KEY_SLICING_DIR="SlicingDir" KEY_SLICE_STEP = "StrandH" @@ -82,6 +81,7 @@ KEY_WIPE_FEEDPU = "WipeFeedPu" KEY_TOOL_DIAM = "ToolDiam" -- Ribs +KEY_RIBS_TYPE = "RibsType" KEY_RIBS_OVERLAP = "RibsOverlap" KEY_RIBS_SHELLS_NBR = "RibsStrandCount" KEY_RIBS_LINK = "RibsLink" @@ -95,6 +95,7 @@ KEY_RIBS_LEAD_OUT_COASTING = "RibsLeadOutCoasting" KEY_RIBS_LEAD_OUT_WIPE = "RibsLeadOutWipe" KEY_RIBS_LEAD_OUT_WIPE_DIR = "RibsLeadOutWipeDir" KEY_RIBS_INTERS = "RibsHaveIntersections" +KEY_SPLIT_ORDER = "SplitOrder" KEY_SPLIT_RIB = "SplitRib" KEY_RIBS_TWO_STRANDS = "RibsHaveAll2Strands" @@ -181,6 +182,12 @@ INFILL_TYPE = { ZIGZAG = 3, } +RIB_TYPE = { + INTERNAL = 1, + EXTERNAL = 2, + UNBOUNDED = 3, +} + --------------------------------------------------------------------- TABLE = "Table" PART = "Part" diff --git a/LuaLibs/CalcPaths.lua b/LuaLibs/CalcPaths.lua index 17440d3..5948265 100644 --- a/LuaLibs/CalcPaths.lua +++ b/LuaLibs/CalcPaths.lua @@ -43,15 +43,21 @@ local function GetLayerParamsForPathCalc() return LayerParams end +-------------------------------------------------------------------------------------------- +local function CopyInfo( nSouId, nDestId, sInfo, sType) + local info = EgtGetInfo( nSouId, sInfo, sType) + EgtSetInfo( nDestId, sInfo, info) +end + ---------------------------------------------------------------------- local function ComputeSurfOffset( nSrf, nGrpId, dOffs) - local nCopySrf = EgtCopy( nSrf, nGrpId) + local nCopySrf = EgtCopy( nSrf, nGrpId) or GDB_ID.NULL local bOk = EgtSurfFrOffset( nCopySrf, dOffs) local bExists = EgtSurfFrChunkCount( nCopySrf) > 0 if not bOk or not bExists then EgtErase( nCopySrf) - nCopySrf = EgtCopyGlob( nSrf, nGrpId) + nCopySrf = EgtCopyGlob( nSrf, nGrpId) or GDB_ID.NULL bOk = EgtSurfFrOffset( nCopySrf, dOffs + 0.05) bExists = EgtSurfFrChunkCount( nCopySrf) > 0 end @@ -339,7 +345,7 @@ local function ComputeOffsetInfill( nSrf, dStrand, vtSlicing, sName, nType, vPtS EgtErase( nSrfOffs) -- offset successivo dOffs = dOffs - dStrand - bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrf, nGrp, dOffs) + bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrf, nGrp, dOffs) end end @@ -416,6 +422,59 @@ end ------------------------------------------------------------------- --------------------------- RIBS ----------------------------------- -------------------------------------------------------------------- +local function ComputeTrimSurfWithOverlapsForRibs( vIds, nSrfBase, nSrfExt, dOffs, dStrand, nGrp) + + -- per ogni tipologia e overlap creo le superfici con cui fare i trim + local tSurfOffs = {{}, {}, {}} + for i = 1, #vIds do + local nOverlap = EgtGetInfo( vIds[i], KEY_RIBS_OVERLAP, 'i') + local nType = EgtGetInfo( vIds[i], KEY_RIBS_TYPE, 'i') + if not tSurfOffs[nType][nOverlap] then + if nType == RIB_TYPE.INTERNAL then + if nSrfBase then + local dNewOffs = nOverlap / 100 * dStrand + local bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrfBase, nGrp, dNewOffs) + if bOk then + tSurfOffs[nType][nOverlap] = nSrfOffs + end + end + elseif nType == RIB_TYPE.EXTERNAL then + if nSrfExt then + local dNewOffs = dOffs + ( 0.5 - nOverlap / 100) * dStrand + local bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrfExt, nGrp, dNewOffs) + if bOk then + tSurfOffs[nType][nOverlap] = nSrfOffs + EgtSetName( nSrfOffs, TOT_SHELL_TRIM_SURF) + end + end + else + tSurfOffs[nType][nOverlap] = GDB_ID.NULL + end + end + end + return tSurfOffs +end + +-------------------------------------------------------------------- +local function VerifyRibsIntersection( ptInt, nType1, nType2, nSrf1, nSrf2, nGrp) + + local bValid = false + local nPtId = EgtPoint( nGrp, ptInt) + + if nType1 == RIB_TYPE.INTERNAL or nType2 == RIB_TYPE.INTERNAL then + -- l'intersezione deve essere interna + if nSrf1 and not EgtSurfFrTestExternal( nSrf1, nPtId) then bValid = true end + elseif nType1 == RIB_TYPE.EXTERNAL or nType2 == RIB_TYPE.EXTERNAL then + -- l'intersezione deve essere esterna + if nSrf2 and EgtSurfFrTestExternal( nSrf2, nPtId) then bValid = true end + else + bValid = true + end + + return bValid +end + +--------------------------------------------------------------------------------- -- Funzione che sistema le intersezioni fra costolature nel caso generico local function AdjustRibsOffsetForIntersection( nCrv1, nCrv2, LayerParams, nOffsGrp) @@ -426,15 +485,18 @@ local function AdjustRibsOffsetForIntersection( nCrv1, nCrv2, LayerParams, nOffs local nOverlap = min( nOverlap1, nOverlap2) local dOffs = ( nShells - 1) * LayerParams.dStrand / 2 local nSrf = EgtSurfFrFatCurve( nOffsGrp, nCrv1, dOffs + ( 1 - nOverlap / 100) * LayerParams.dStrand, false) - - -- recupero gli offset della curva secondaria ( nCrv2) + if not nSrf then return end + + -- trim degli offset della curva secondaria ( nCrv2) local vOffs2 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv2)) - -- trim degli offset della curva secondaria for i = 1, #vOffs2 do local nId, nCnt = EgtTrimCurveWithRegion( vOffs2[i], nSrf, false, true) EgtChangeId( nId, vOffs2[i]) + -- aggiorno ordine di split copiandolo da nCrv2 + CopyInfo( nCrv2, vOffs2[i], KEY_SPLIT_ORDER, 'i') if nCnt > 1 then - EgtSetInfo( nId + 1, KEY_SPLIT_RIB, vOffs2[i]) + EgtSetInfo( nId + 1, KEY_SPLIT_RIB, vOffs2[i]) -- curva da cui deriva + CopyInfo( nCrv2, nId + 1, KEY_SPLIT_ORDER, 'i') -- ordine di split EgtRelocateGlob( nId + 1, nOffsGrp, GDB_IN.LAST_SON) end end @@ -476,6 +538,30 @@ local function AdjustRibsOffsetForIntersection2Shells( nCrv1, nCrv2, LayerParams end +------------------------------------------------------------------ +local function UpdateSplitOrder( nCrv, tInters, nOffsGrp) + local nOrder = EgtGetInfo( nCrv, KEY_SPLIT_ORDER, 'i') or 0 + local nNewOrder = nOrder + 1 + + -- aggiorno tutte le curve che dipendono da nCrv + if tInters[nCrv] then + for i = 1, #tInters[nCrv] do + local nOldOrder = EgtGetInfo( tInters[nCrv][i], KEY_SPLIT_ORDER, 'i') + if nOldOrder < nNewOrder then + EgtSetInfo( tInters[nCrv][i], KEY_SPLIT_ORDER, nNewOrder) + -- aggiorno i suoi offset + local vOffs = EgtGetNameInGroup( nOffsGrp, EgtGetName( tInters[nCrv][i])) + for j = 1, #vOffs do + EgtSetInfo( vOffs[j], KEY_SPLIT_ORDER, nNewOrder) + end + -- aggiorno eventuali dipendenze + UpdateSplitOrder( tInters[nCrv][i], tInters, nOffsGrp) + end + end + end + +end + -------------------------------------------------------------------- local function HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPathGrp, bAllTwoStrands) @@ -495,45 +581,85 @@ local function HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPa table.insert( vRibsIds, EgtCopyGlob( vOrigRibsIds[i], nGrpTmp)) end - -- calcolo la regione nella quale ha senso considerare l'intersezione - local nSrf = EgtGetFirstNameInGroup( nCrvGrp, TOT_SHELL_TRIM_SURF) - local bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrf, nCrvGrp, 2 * LayerParams.dStrand) - if not bOk or not bExists then - nSrfOffs = EgtCopyGlob( nSrf, nCrvGrp) + -- calcolo le regioni nella quali ha senso considerare l'intersezione + local nSrfOffs1, nSrfOffs2 + local bOk, bExists + local nSrf1 = EgtGetFirstNameInGroup( nCrvGrp, TOT_SHELL_TRIM_SURF) + if nSrf1 then + bOk, bExists, nSrfOffs1 = ComputeSurfOffset( nSrf1, nCrvGrp, 2 * LayerParams.dStrand) + if not bOk or not bExists then + nSrfOffs1 = EgtCopyGlob( nSrf1, nCrvGrp) + end end - + local nSrf2 = EgtGetFirstNameInGroup( nCrvGrp, LAYER_SRF) + if nSrf2 then + bOk, bExists, nSrfOffs2 = ComputeSurfOffset( nSrf2, nCrvGrp, - 2 * LayerParams.dStrand) + if not bOk or not bExists then + nSrfOffs2 = EgtCopyGlob( nSrf2, nCrvGrp) + end + end + local bInters = false local vSplit = {} + local tInters = {} -- tabella che tiene traccia delle intersezioni trovate for i = 1, #vRibsIds do + + local nType1 = EgtGetInfo( vRibsIds[i], KEY_RIBS_TYPE, 'i') -- verifico se interseca uno dei setti successivi for j = i + 1, #vRibsIds do - local ptInt = EgtIP( vRibsIds[i], vRibsIds[j], ORIG()) - if ptInt then + -- verifico se i due setti possono intersecarsi in base alla loro tipologia + local nType2 = EgtGetInfo( vRibsIds[j], KEY_RIBS_TYPE, 'i') + if not ( ( nType1 == RIB_TYPE.INTERNAL and nType2 == RIB_TYPE.EXTERNAL) or ( nType1 == RIB_TYPE.EXTERNAL and nType2 == RIB_TYPE.INTERNAL)) then - -- verifico se l'interserzione si trova nella regione dello slice - local nPtId = EgtPoint( nGrpTmp, ptInt) - if not EgtSurfFrTestExternal( nSrfOffs, nPtId) then - bInters = true + local ptInt = EgtIP( vRibsIds[i], vRibsIds[j], ORIG()) + if ptInt then - local dPar1 = EgtCurveParamAtPoint( vRibsIds[i], ptInt) - local dPar2 = EgtCurveParamAtPoint( vRibsIds[j], ptInt) - local _, dParE1 = EgtCurveDomain( vRibsIds[i]) - local _, dParE2 = EgtCurveDomain( vRibsIds[j]) - - local nCrv1 = vOrigRibsIds[i] -- curva principale che non viene tagliata - local nCrv2 = vOrigRibsIds[j] -- curve secondaria da modificare - if dPar1 < 10 * GEO.EPS_SMALL or abs( dPar1 - dParE1) < 10 * GEO.EPS_SMALL then - nCrv1, nCrv2 = nCrv2, nCrv1 - end - - if bAllTwoStrands then - -- nel caso di 2 passate gestione speciale - AdjustRibsOffsetForIntersection2Shells( nCrv1, nCrv2, LayerParams, nRibsPathGrp) - else - AdjustRibsOffsetForIntersection( nCrv1, nCrv2, LayerParams, nRibsPathGrp) + -- verifico se l'interserzione è valida + if VerifyRibsIntersection( ptInt, nType1, nType2, nSrfOffs1, nSrfOffs2, nGrpTmp) then + bInters = true + + local dPar1 = EgtCurveParamAtPoint( vRibsIds[i], ptInt) + local dPar2 = EgtCurveParamAtPoint( vRibsIds[j], ptInt) + local _, dParE1 = EgtCurveDomain( vRibsIds[i]) + local _, dParE2 = EgtCurveDomain( vRibsIds[j]) + + local nCrv1 = vOrigRibsIds[i] -- curva principale che non viene tagliata + local nCrv2 = vOrigRibsIds[j] -- curve secondaria da modificare + local nSplitOrder1 = EgtGetInfo( nCrv1, KEY_SPLIT_ORDER, 'i') or 0 + local nSplitOrder2 = EgtGetInfo( nCrv2, KEY_SPLIT_ORDER, 'i') or 0 + if dPar1 < 10 * GEO.EPS_SMALL or abs( dPar1 - dParE1) < 10 * GEO.EPS_SMALL then + nCrv1, nCrv2 = nCrv2, nCrv1 + nSplitOrder1, nSplitOrder2 = nSplitOrder2, nSplitOrder1 + else + -- prediligo setto già splittato più volte + if nSplitOrder1 > nSplitOrder2 then + nCrv1, nCrv2 = nCrv2, nCrv1 + nSplitOrder1, nSplitOrder2 = nSplitOrder2, nSplitOrder1 + end + end + + -- aggiorno tabella delle intersezioni + if tInters[nCrv1] then + table.insert( tInters[nCrv1], nCrv2) + else + tInters[nCrv1] = {nCrv2} + end + + -- aggiorno ordine di split + if nSplitOrder2 < nSplitOrder1 + 1 then + EgtSetInfo( nCrv2, KEY_SPLIT_ORDER, nSplitOrder1 + 1) + UpdateSplitOrder( nCrv2, tInters, nRibsPathGrp) + end + + if bAllTwoStrands then + -- nel caso di 2 passate gestione speciale + AdjustRibsOffsetForIntersection2Shells( nCrv1, nCrv2, LayerParams, nRibsPathGrp) + else + AdjustRibsOffsetForIntersection( nCrv1, nCrv2, LayerParams, nRibsPathGrp) + end end + EgtErase( nPtId) end - EgtErase( nPtId) end end end @@ -545,37 +671,80 @@ local function HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPa end -------------------------------------------------------------------- +local function ShortestPathForRibs( vIds, nGrp, bInvertOrder) + + if not vIds or #vIds == 0 then return end + + -- se solo un setto ordinamento banale + if #vIds == 1 then + EgtRelocateGlob( vIds[1], nGrp, GDB_IN.LAST_SON) + return + elseif #vIds == 2 then + EgtRelocateGlob( vIds[1], nGrp, GDB_IN.LAST_SON) + EgtRelocateGlob( vIds[2], vIds[1], EgtIf( bInvertOrder, GDB_IN.BEFORE, GDB_IN.AFTER)) + return + else + -- se più setti ordinamento con shortest path + EgtSpInit() + for i = 1, #vIds do + local pt = EgtMP( vIds[i], GDB_RT.GLOB) + EgtSpAddPoint( pt:getX(), pt:getY(), pt:getZ(), 0, 0, pt:getX(), pt:getY(), pt:getZ(), 0, 0) + end + local vOrd, dLen = EgtSpCalculate( SHP_TY.OPEN) + EgtSpTerminate() + + EgtRelocateGlob( vIds[vOrd[1]], nGrp, GDB_IN.LAST_SON) + for i = 2, #vOrd do + EgtRelocateGlob( vIds[vOrd[i]], vIds[vOrd[i-1]], EgtIf( bInvertOrder, GDB_IN.BEFORE, GDB_IN.AFTER)) + end + end +end + +--------------------------------------------------------------------- -- Funzione che riordina le costolature nel caso generico local function ReorderRibs( nGrp, bInvertOrder, dStrand, nMaxNbr) - EgtSpInit() + -- raggruppo per tipologia + local tRibs = {{}, {}, {}} local vIds = EgtGetNameInGroup( nGrp, RIBS_CRV .. '*') if not vIds or #vIds == 0 then return end - - local vSplitRibs = {} - local vSPRibs = {} for i = 1, #vIds do - local nInfo = EgtGetInfo( vIds[i], KEY_SPLIT_RIB, 'i') - local nShells = EgtGetInfo( vIds[i], KEY_RIBS_SHELLS_NBR, 'i') - -- se è ottenuto dalla divisione di una costolatura non va considerato per il TSP ( viene aggiunto in seguito) - if nInfo and nShells == 1 then - table.insert( vSplitRibs, vIds[i]) - else - local pt = EgtMP( vIds[i], GDB_RT.GLOB) - EgtSpAddPoint( pt:getX(), pt:getY(), pt:getZ(), 0, 0, pt:getX(), pt:getY(), pt:getZ(), 0, 0) - table.insert( vSPRibs, vIds[i]) - end + local nType = EgtGetInfo( vIds[i], KEY_RIBS_TYPE, 'i') + table.insert( tRibs[nType], vIds[i]) end - local vOrd, dLen = EgtSpCalculate( SHP_TY.OPEN) - EgtSpTerminate() - EgtRelocateGlob( vSPRibs[vOrd[1]], nGrp, EgtIf( bInvertOrder, GDB_IN.LAST, GDB_IN.FIRST)) - for i = 2, #vOrd do - EgtRelocateGlob( vSPRibs[vOrd[i]], vSPRibs[vOrd[i-1]], EgtIf( bInvertOrder, GDB_IN.BEFORE, GDB_IN.AFTER)) + -- riordino ogni tipologia con shortest path + local vSplitRibs = {} + for i = 1, 3 do + local tSplitOrder = {} + local nMax = 0 + -- suddivido i ribs in base allo SplitOrder + for j = 1, #tRibs[i] do + local nInfoSplit = EgtGetInfo( tRibs[i][j], KEY_SPLIT_RIB, 'i') + local nShells = EgtGetInfo( tRibs[i][j], KEY_RIBS_SHELLS_NBR, 'i') + if nInfoSplit and nShells == 1 then + -- se è ottenuto dalla divisione di una costolatura + table.insert( vSplitRibs, tRibs[i][j]) + else + -- classifico in base all'ordine di split + local nSplitOrder = EgtGetInfo( tRibs[i][j], KEY_SPLIT_ORDER, 'i') or 0 + if nSplitOrder > nMax then nMax = nSplitOrder end + if tSplitOrder[nSplitOrder] then + table.insert( tSplitOrder[nSplitOrder], tRibs[i][j]) + else + tSplitOrder[nSplitOrder] = {tRibs[i][j]} + end + end + end + + -- riordino ogni ordine di split + for i = 0, nMax do + ShortestPathForRibs( tSplitOrder[i], nGrp, bInvertOrder) + end end -- sistemo nomi - local kMax = nMaxNbr + 1 + local kMax = nMaxNbr + 1 local dTol = 500 * GEO.EPS_SMALL for i = 1, nMaxNbr do local vIds = EgtGetNameInGroup( nGrp, RIBS_CRV .. tostring(i)) or {} @@ -593,29 +762,26 @@ local function ReorderRibs( nGrp, bInvertOrder, dStrand, nMaxNbr) kMax = kMax + 1 end end - end + end -- aggiusto tutte le costolature divise - local tabSplitted = {} for i = 1, #vSplitRibs do local nPrevId = EgtGetInfo( vSplitRibs[i], KEY_SPLIT_RIB, 'i') local bInverted = EgtGetInfo( vSplitRibs[i], KEY_INVERTED_CRV, 'b') or false -- aggiungo come successiva alla costolatura da cui si è generata EgtRelocateGlob( vSplitRibs[i], nPrevId, EgtIf( bInverted, GDB_IN.BEFORE, GDB_IN.AFTER)) + -- se necessario rinomino + if EgtGetName( vSplitRibs[i]) == EgtGetName(nPrevId) then + EgtSetName( vSplitRibs[i], RIBS_CRV .. tostring( kMax)) + kMax = kMax + 1 + end -- correggo le info per gestire correttamente nel calcolo toolpath - if bInverted and not tabSplitted[nPrevId] then + local nPrevInfo = EgtGetInfo( nPrevId, KEY_SPLIT_RIB, 'i') + if bInverted and not nPrevInfo then EgtRemoveInfo( vSplitRibs[i], KEY_SPLIT_RIB) EgtSetInfo( nPrevId, KEY_SPLIT_RIB, vSplitRibs[i]) - tabSplitted[nPrevId] = 1 end end - -end - --------------------------------------------------------------------------------------------- -local function CopyInfo( nSouId, nDestId, sInfo, sType) - local info = EgtGetInfo( nSouId, sInfo, sType) - EgtSetInfo( nDestId, sInfo, info) end -------------------------------------------------------------------------------------------- @@ -642,6 +808,7 @@ local function ReassignInfo( nCrv, nCnt, vOrig) CopyInfo( vOrig[i], nId, KEY_RIBS_LEAD_IN_INVERT, 'b') CopyInfo( vOrig[i], nId, KEY_RIBS_LEAD_IN_LEN, 'd') CopyInfo( vOrig[i], nId, KEY_ASSOCIATED_SURF, 'i') + CopyInfo( vOrig[i], nId, KEY_RIBS_TYPE, 'i') bStart = true end -- verifico se corrisponde al suo end @@ -668,11 +835,16 @@ end local function ReorderRibsInters2Shells( nOffsGrp, dStrand) local vOffs = EgtGetNameInGroup( nOffsGrp, RIBS_CRV .. '*') + local bUnboundedRib = false -- copio le curve originali ( per recuperarne le info) local vCopy = {} for i = 1, #vOffs do local nNewId = EgtCopy( vOffs[i], nOffsGrp) table.insert( vCopy, nNewId) + local nType = EgtGetInfo( nNewId, KEY_RIBS_TYPE, 'i') + if nType == RIB_TYPE.UNBOUNDED then + bUnboundedRib = true + end end -- concateno le curve @@ -777,10 +949,45 @@ local function ReorderRibsInters2Shells( nOffsGrp, dStrand) -- Recupero le info dalle curve originali ReassignInfo( nCrv, nCnt, vCopy) + + -- riordino per tipologia ( prima iterni poi esterni) nel caso senza unbounded + if not bUnboundedRib then + local vCrvs = EgtGetNameInGroup( nOffsGrp, RIBS_CRV .. '*') + for nId = 1, #vCrvs do + local nType = EgtGetInfo( vCrvs[nId], KEY_RIBS_TYPE, 'i') + if nType == RIB_TYPE.EXTERNAL then + EgtRelocateGlob( vCrvs[nId], EgtGetParent( nCrv), GDB_IN.LAST_SON) + end + end + end + +end + +------------------------------------------------------------------- +local function UpdateRibSplitInfo( nGrp, tIds) + + local vIds = EgtGetNameInGroup( nGrp, RIBS_CRV .. '*') + if not vIds then return end + + for i = 1, #vIds do + + -- info SplitRib + local nInfo = EgtGetInfo( vIds[i], KEY_SPLIT_RIB, 'i') + if nInfo then + if tIds[nInfo] and #tIds[nInfo] > 0 then + -- aggiorno info con nuovo id della costolatura da cui deriva + local nLast = #tIds[nInfo] + EgtSetInfo( vIds[i], KEY_SPLIT_RIB, tIds[nInfo][nLast]) + else + -- se la costolatura da cui deriva è stata eliminata, tolgo l'info che le associava + EgtRemoveInfo( vIds[i], KEY_SPLIT_RIB) + end + end + end end -------------------------------------------------------------------- -local function CalcRibsPaths( nSliceGrp, nRibsGrp, LayerParams, nIdx, nMaxStrandDiff) +local function CalcRibsPaths( nSliceGrp, nRibsGrp, LayerParams, nIdx) local vRibs = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*') -- verifico se tutte le costolature vengono fatte con 2 passate @@ -827,80 +1034,78 @@ local function CalcRibsPaths( nSliceGrp, nRibsGrp, LayerParams, nIdx, nMaxStrand -- creo le superfici con cui fare i trim local nSrfBase = EgtGetFirstNameInGroup( nCrvGrp, TOT_SHELL_TRIM_SURF) - if not nSrfBase then - EgtOutLog( 'Warning : Ribs not possible (layer '..tostring( nIdx)..') - CalcPaths') - else - local vSurfOffs = ComputeTrimSurfWithOverlaps( vRibs, nSrfBase, KEY_RIBS_OVERLAP, LayerParams.dStrand, nRibsPathGrp) + local nSrfExt = EgtGetFirstNameInGroup( nCrvGrp, LAYER_SRF) + local tSurfOffs = ComputeTrimSurfWithOverlapsForRibs( vRibs, nSrfBase, nSrfExt, LayerParams.dOffs, LayerParams.dStrand, nRibsPathGrp) + + -- gestisco eventuali intersezioni fra costolature + local bInters = HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPathGrp, bAllTwoStrands) + EgtSetInfo( nRibsPathGrp or GDB_ID.NULL, KEY_RIBS_INTERS, bInters) + EgtSetInfo( nRibsPathGrp or GDB_ID.NULL, KEY_RIBS_TWO_STRANDS, bAllTwoStrands) - -- gestisco eventuali intersezioni fra costolature - local bInters = HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPathGrp, bAllTwoStrands) - EgtSetInfo( nRibsPathGrp or GDB_ID.NULL, KEY_RIBS_INTERS, bInters) - EgtSetInfo( nRibsPathGrp or GDB_ID.NULL, KEY_RIBS_TWO_STRANDS, bAllTwoStrands) - - -- eseguo il trim delle costole con la regione offsettata - local tOldNewIds = {} - local vOrderedRibs = EgtGetNameInGroup( nRibsPathGrp, RIBS_CRV ..'*') - for i = 1, #vOrderedRibs do - -- trim con superficie opportuna - local nOverlap = EgtGetInfo( vOrderedRibs[i], KEY_RIBS_OVERLAP, 'i') - if not vSurfOffs[ nOverlap] then - -- la costolatura non è fattibile - EgtOutLog( 'Warning: Ribs not possibile (layer '..tostring( nIdx)..') - CalcPaths') - EgtErase( vOrderedRibs[i]) + -- eseguo il trim delle costole con la regione offsettata + local tOldNewIds = {} + local vOrderedRibs = EgtGetNameInGroup( nRibsPathGrp, RIBS_CRV ..'*') + for i = 1, #vOrderedRibs do + -- trim con superficie opportuna + local nOverlap = EgtGetInfo( vOrderedRibs[i], KEY_RIBS_OVERLAP, 'i') + local nType = EgtGetInfo( vOrderedRibs[i], KEY_RIBS_TYPE, 'i') + if not tSurfOffs[nType][nOverlap] then + -- la costolatura non è fattibile + EgtOutLog( 'Warning: Ribs not possibile (layer '..tostring( nIdx)..') - CalcPaths') + EgtErase( vOrderedRibs[i]) + else + local nCrv, nCnt + if tSurfOffs[nType][nOverlap] == GDB_ID.NULL then + -- caso unbounded + nCrv = vOrderedRibs[i] + nCnt = 1 else - local nCrv, nCnt = EgtTrimCurveWithRegion( vOrderedRibs[i], vSurfOffs[nOverlap], true, false) - tOldNewIds[ vOrderedRibs[i]] = {} - - -- elimino tratti troppo corti - for nInd = 0, nCnt - 1 do - local dLen = EgtCurveLength( nCrv + nInd) - if dLen < MIN_RIBS_LEN then - EgtErase( nCrv + nInd) - else - table.insert( tOldNewIds[ vOrderedRibs[i]], nCrv + nInd) - - -- controllo la direzione (consideriamo inclinazione solo lungo X) - local vtDir = EgtMV( nCrv + nInd) - local dXl = sqrt( sqr( vtDir:getX()) + sqr( vtDir:getZ())) - local dYl = abs( vtDir:getY()) - local dVal = EgtIf( dXl > dYl - GEO.EPS_SMALL, vtDir:getX(), vtDir:getY()) - local bInvert = dVal < - GEO.EPS_SMALL - -- inversione della curva - local bInvertInfo = EgtGetInfo( nCrv + nInd, KEY_RIBS_INVERT_DIR, 'b') or false - if bInvert ~= bInvertInfo then - EgtInvertCurve( nCrv + nInd) - EgtSetInfo( nCrv + nInd, KEY_INVERTED_CRV, 1) - end - - -- salvo info della superficie di trim associata - EgtSetInfo( nCrv + nInd, KEY_ASSOCIATED_SURF, vSurfOffs[nOverlap]) - - if nInd == 0 then - -- aggiorno la info - local nInfo = EgtGetInfo( nCrv + nInd, KEY_SPLIT_RIB, 'i') - if nInfo then - -- aggiorno info - if #tOldNewIds[nInfo] > 0 then - local nLast = #tOldNewIds[nInfo] - EgtSetInfo( nCrv + nInd, KEY_SPLIT_RIB, tOldNewIds[nInfo][nLast]) - else - -- se la costolatura da cui deriva è stata eliminata, tolgo l'info che le associava - EgtRemoveInfo( nCrv + nInd, KEY_SPLIT_RIB) - end - end - end + nCrv, nCnt = EgtTrimCurveWithRegion( vOrderedRibs[i], tSurfOffs[nType][nOverlap], EgtIf( nType == RIB_TYPE.INTERNAL, true, false), false) + end + + tOldNewIds[ vOrderedRibs[i]] = {} + + -- elimino tratti troppo corti + for nInd = 0, nCnt - 1 do + local dLen = EgtCurveLength( nCrv + nInd) + if dLen < MIN_RIBS_LEN then + EgtErase( nCrv + nInd) + else + table.insert( tOldNewIds[ vOrderedRibs[i]], nCrv + nInd) + + -- controllo la direzione (consideriamo inclinazione solo lungo X) + local vtDir = EgtMV( nCrv + nInd) + local dXl = sqrt( sqr( vtDir:getX()) + sqr( vtDir:getZ())) + local dYl = abs( vtDir:getY()) + local dVal = EgtIf( dXl > dYl - GEO.EPS_SMALL, vtDir:getX(), vtDir:getY()) + local bInvert = dVal < - GEO.EPS_SMALL + -- inversione della curva + local bInvertInfo = EgtGetInfo( nCrv + nInd, KEY_RIBS_INVERT_DIR, 'b') or false + if bInvert ~= bInvertInfo then + EgtInvertCurve( nCrv + nInd) + EgtSetInfo( nCrv + nInd, KEY_INVERTED_CRV, 1) end - end + + -- salvo info della superficie di trim associata + EgtSetInfo( nCrv + nInd, KEY_ASSOCIATED_SURF, tSurfOffs[nType][nOverlap]) + + if nInd > 0 then + EgtRemoveInfo( nCrv + nInd, KEY_SPLIT_RIB) + end + end end end - - -- riordino le costolature - if bAllTwoStrands and bInters then - -- gestione caso speciale di intersezione e 2 passate - ReorderRibsInters2Shells( nRibsPathGrp, LayerParams.dStrand) - else - ReorderRibs( nRibsPathGrp, LayerParams.bRibsInvertOrder, LayerParams.dStrand, nMaxNbr) - end + end + + -- aggiorno le info di split con i nuovi id + UpdateRibSplitInfo( nRibsPathGrp, tOldNewIds) + + -- riordino le costolature + if bAllTwoStrands and bInters then + -- gestione caso speciale di intersezione e 2 passate + ReorderRibsInters2Shells( nRibsPathGrp, LayerParams.dStrand) + else + ReorderRibs( nRibsPathGrp, LayerParams.bRibsInvertOrder, LayerParams.dStrand, nMaxNbr) end if not EgtGetFirstNameInGroup( nRibsPathGrp, RIBS_CRV .. '*') then @@ -972,7 +1177,7 @@ local function ComputeMaxShellNbrDiff( nSrf, nShellNbrSurfGrp) local nShellNbrSrf = EgtGetFirstNameInGroup( nShellNbrSurfGrp, SHELL_NBR_SURF .. tostring( nId)) while nShellNbrSrf do -- se interessa la regione considerata aggiorno il nMaxShellNbrDiff - if not EgtSurfFrTestExternal( nSrf, nShellNbrSrf) then + if not EgtSurfFrTestExternal( nSrf, nShellNbrSrf) then nMaxShellNbrDiff = nId end @@ -1517,7 +1722,7 @@ function CalcPaths.Exec( nPartId) -- sistemo eventuali costolature if nRibsGrp then - CalcRibsPaths( vLayIds[nIdx], nRibsGrp, LayerParams, nIdx, nMaxStrandDiff) + CalcRibsPaths( vLayIds[nIdx], nRibsGrp, LayerParams, nIdx) end end diff --git a/LuaLibs/CalcSlices.lua b/LuaLibs/CalcSlices.lua index 336c12f..0dbcc4f 100644 --- a/LuaLibs/CalcSlices.lua +++ b/LuaLibs/CalcSlices.lua @@ -89,10 +89,10 @@ local function AdjustAuxSolids( nSolidsLay) end -------------------------------------------------------------------- -local function ReadParam( nId, sKey, sType, table) +local function ReadParam( nId, sKey, sType, table, defVal) local info = EgtGetInfo( nId, sKey, sType) if info == nil then info = EgtGetInfo( s_nPartId, sKey, sType) end - table[sKey] = info + table[sKey] = info or defVal end -------------------------------------------------------------------- @@ -108,14 +108,9 @@ local function GetRibParams( nId) ReadParam( nId, KEY_RIBS_LEAD_OUT_COASTING, 'd', RibParam) ReadParam( nId, KEY_RIBS_LEAD_OUT_WIPE, 'd', RibParam) ReadParam( nId, KEY_RIBS_LEAD_OUT_WIPE_DIR, 'd', RibParam) + ReadParam( nId, KEY_RIBS_OVERLAP, 'i', RibParam) - -- overlap può essere diverso tra le varie costolature solo se non sono collegate - local bLink = EgtGetInfo( s_nPartId, KEY_RIBS_LINK, 'b') or false - if bLink then - RibParam[ KEY_RIBS_OVERLAP] = EgtGetInfo( s_nPartId, KEY_RIBS_OVERLAP, 'i') -- parametro generico - else - ReadParam( nId, KEY_RIBS_OVERLAP, 'i', RibParam) -- parametro specifico della costolatura - end + ReadParam( nId, KEY_RIBS_TYPE, 'i', RibParam, RIB_TYPE.INTERNAL) return RibParam end @@ -131,48 +126,9 @@ local function GetAuxSolidsParams( nId) ReadParam( nId, KEY_AUX_SOLIDS_WIPE_LEN, 'd', AuxSolidsParam) ReadParam( nId, KEY_AUX_SOLIDS_WIPE_DIR, 'd', AuxSolidsParam) - local sInfill = EgtGetInfo( nId, KEY_AUX_SOLIDS_INFILL, 's') - if sInfill then - -- se parametro specifico per il solido - if sInfill == 'ZigZag' then - AuxSolidsParam[KEY_AUX_SOLIDS_INFILL] = INFILL_TYPE.ZIGZAG - elseif sInfill == 'Offset' then - AuxSolidsParam[KEY_AUX_SOLIDS_INFILL] = INFILL_TYPE.OFFSET - else - AuxSolidsParam[KEY_AUX_SOLIDS_INFILL] = INFILL_TYPE.NONE - end - else - -- altrimenti recupero il parametro generale dal pezzo - AuxSolidsParam[KEY_AUX_SOLIDS_INFILL] = EgtGetInfo( s_nPartId, KEY_AUX_SOLIDS_INFILL, 'i') - end - - local sPrintOrder = EgtGetInfo( nId, KEY_AUX_SOLIDS_PRINT_ORDER, 's') - if sPrintOrder then - -- se parametro specifico per il solido - if sPrintOrder == 'OutToIn' then - AuxSolidsParam[KEY_AUX_SOLIDS_PRINT_ORDER] = PRINT_ORDER.EXT_INT_INF - else - AuxSolidsParam[KEY_AUX_SOLIDS_PRINT_ORDER] = PRINT_ORDER.INF_INT_EXT - end - else - -- altrimenti recupero il parametro generale dal pezzo - AuxSolidsParam[KEY_AUX_SOLIDS_PRINT_ORDER] = EgtGetInfo( s_nPartId, KEY_AUX_SOLIDS_PRINT_ORDER, 'i') - end - - local sLinkType = EgtGetInfo( nId, KEY_AUX_SOLIDS_LINK_TYPE, 's') - if sLinkType then - -- se parametro specifico per il solido - if sLinkType == 'None' then - AuxSolidsParam[KEY_AUX_SOLIDS_LINK_TYPE] = LINK_TYPE.NONE - elseif sLinkType == 'BiArc' then - AuxSolidsParam[KEY_AUX_SOLIDS_LINK_TYPE] = LINK_TYPE.BIARC - else - AuxSolidsParam[KEY_AUX_SOLIDS_LINK_TYPE] = LINK_TYPE.LINEAR - end - else - -- altrimenti recupero il parametro generale dal pezzo - AuxSolidsParam[KEY_AUX_SOLIDS_LINK_TYPE] = EgtGetInfo( s_nPartId, KEY_AUX_SOLIDS_LINK_TYPE, 'i') - end + ReadParam( nId, KEY_AUX_SOLIDS_INFILL, 'i', AuxSolidsParam) + ReadParam( nId, KEY_AUX_SOLIDS_PRINT_ORDER, 'i', AuxSolidsParam) + ReadParam( nId, KEY_AUX_SOLIDS_LINK_TYPE, 'i', AuxSolidsParam) return AuxSolidsParam end @@ -308,10 +264,9 @@ function CalcSlices.Exec( nPartId, nStmId, HMax) -- recupero la direzione dello slicing local vtSlicing = Z_AX() local nSlicingType = EgtGetInfo( s_nPartId, KEY_SLICING_TYPE, 'i') - local bSlicing45 = EgtGetInfo( s_nPartId, KEY_SLICING_45, 'b') or false -- da rimuovere if nSlicingType == SLICING_TYPE.HORIZONTAL then vtSlicing = X_AX() - elseif nSlicingType == SLICING_TYPE.DEG45 or bSlicing45 then + elseif nSlicingType == SLICING_TYPE.DEG45 then vtSlicing = VectorFromSpherical( 1, 45, 0) end diff --git a/LuaLibs/CalcToolPath.lua b/LuaLibs/CalcToolPath.lua index 4702d87..feb82e5 100644 --- a/LuaLibs/CalcToolPath.lua +++ b/LuaLibs/CalcToolPath.lua @@ -320,24 +320,29 @@ local function VerifyRibsLink( nLinkId, nCurr, nNext, dStrand, nGrpTmp) -- verifico se si trova nella regione ammissibile local nSurfId = EgtGetInfo( nCurr, KEY_ASSOCIATED_SURF, 'i') local nRes = EgtCurveWithRegionClassify( nLinkId, nSurfId) - if nRes == GDB_CRC.OUT or nRes == GDB_CRC.INTERS then - return false + local nType1 = EgtGetInfo( nCurr, KEY_RIBS_TYPE, 'i') + local nType2 = EgtGetInfo( nNext, KEY_RIBS_TYPE, 'i') + if nType1 == RIB_TYPE.INTERNAL and nType2 == RIB_TYPE.INTERNAL then + if nRes == GDB_CRC.OUT or nRes == GDB_CRC.INTERS then + return false + end + elseif nType1 == RIB_TYPE.EXTERNAL and nType2 == RIB_TYPE.EXTERNAL then + if nRes == GDB_CRC.IN or nRes == GDB_CRC.INTERS then + return false + end end - + -- verifico se il link interseca una delle altre costolature local vRibsIds = EgtGetNameInGroup( nGrp, RIBS_CRV .. '*') - local nLinkLoc = EgtCopyGlob( nLinkId, nGrpTmp) + local nLinkSrf = EgtSurfFrFatCurve( nGrpTmp, nLinkId, 0.5 * dStrand, false) or GDB_ID.NULL for i = 1, #vRibsIds do if vRibsIds[i] ~= nCurr and vRibsIds[i] ~= nNext then - local nCrvLoc = EgtCopyGlob( vRibsIds[i], nGrpTmp) - local ptInt = EgtIP( nLinkLoc, nCrvLoc, ORIG()) - if ptInt then + local nRes = EgtCurveWithRegionClassify( vRibsIds[i], nLinkSrf) + if nRes == GDB_CRC.INTERS then return false end end end - - EgtErase( nTotLink) return true end @@ -685,6 +690,8 @@ local function AddRibsLeadOut( nCrv, nTPathGrp, nLoopsGrp, vtSlicing, dStrand, n -- terzo tratto ( diretto verso esterno con ugello chiuso) if dRibsLOWipe > GEO.EPS_SMALL then local dAng = dRibsLOWipeAng + s_nDefaultWipeAng + local nType = EgtGetInfo( nCrv, KEY_RIBS_TYPE, 'i') + if nType == RIB_TYPE.EXTERNAL then dAng = - dAng end vtE:rotate( vtSlicing, EgtIf( bInvert, - dAng, dAng)) local ptFinal = ptE + vtE * dRibsLOWipe -- verifico soddisfi altezza minima per dimensioni utensile @@ -774,10 +781,17 @@ local function CalcRibsToolPath( nCrvGrp, nTpathGrpId, LayerParams, dCorrZ) local nShellsNbr = EgtGetInfo( tabRibs[i][1], KEY_RIBS_SHELLS_NBR, 'i') -- se link aggiorno bInvert per il gruppo di costolature corrente in modo da essere coerente con il collegamento if LayerParams.bRibsLink then - if i > 1 and not nInfo then - local nPrevShellsNbr = EgtGetInfo( tabRibs[i-1][1], KEY_RIBS_SHELLS_NBR, 'i') - if nPrevShellsNbr % 2 == 1 then - bInvert = not bInvert + if i > 1 then + nPrevType = EgtGetInfo( tabRibs[i-1][1], KEY_RIBS_TYPE, 'i') + nCurrType = EgtGetInfo( tabRibs[i][1], KEY_RIBS_TYPE, 'i') + -- se cambio tipologia di setto, l'orientamento della curva è già corretto + if nPrevType ~= nCurrType then + bInvert = false + elseif not nInfo then + local nPrevShellsNbr = EgtGetInfo( tabRibs[i-1][1], KEY_RIBS_SHELLS_NBR, 'i') + if nPrevShellsNbr % 2 == 1 then + bInvert = not bInvert + end end end end @@ -1058,8 +1072,7 @@ function CalcToolPath.Exec( nPartId) local vtMove = Vector3d( 0, 0, dCorrZ) -- se slicing a 45° aggiungo correzione anche in direzione dello slicing local nSlicingType = EgtGetInfo( s_nPartId, KEY_SLICING_TYPE, 'i') or 1 - local bSlicing45 = EgtGetInfo( s_nPartId, KEY_SLICING_45, 'b') or false -- da rimuovere - if nSlicingType == SLICING_TYPE.DEG45 or bSlicing45 then + if nSlicingType == SLICING_TYPE.DEG45 then vtMove = vtMove + LayerParams.dLayHeight / 2 * LayerParams.vtSlicing end local SolidLayId = EgtGetFirstNameInGroup( s_nPartId, PRINT_SOLID) diff --git a/LuaLibs/RunSlicing.lua b/LuaLibs/RunSlicing.lua index ab6baa2..460e8c2 100644 --- a/LuaLibs/RunSlicing.lua +++ b/LuaLibs/RunSlicing.lua @@ -137,6 +137,15 @@ local function LoadParams( sFile, nPartId) SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_WIPE_FEEDPU, '0.9') -- parametri per costolature + local sRibType = EgtGetStringFromIni( SEC_DEFAULT, KEY_RIBS_TYPE, 'Internal', sFile) + if sRibType == 'External' then + EgtSetInfo( nPartId, KEY_RIBS_TYPE, RIB_TYPE.EXTERNAL) + elseif sRibType == 'Unbounded' then + EgtSetInfo( nPartId, KEY_RIBS_TYPE, RIB_TYPE.UNBOUNDED) + else -- 'Internal' + EgtSetInfo( nPartId, KEY_RIBS_TYPE, RIB_TYPE.INTERNAL) + end + SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_RIBS_OVERLAP, '0.0') SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_RIBS_SHELLS_NBR, '0') SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_RIBS_INVERT_DIR, '0')