From 7b8ee800c07c8e0336f69c199efd7a5bf13d1f5c Mon Sep 17 00:00:00 2001 From: SaraP Date: Tue, 6 Sep 2022 09:59:35 +0200 Subject: [PATCH] 3dPrinting : - prima gestione solidi ausiliari ( solo riempimenti pieni) - gestione floor/ceil - modifiche progress bar. --- LuaLibs/AddManData.lua | 34 +- LuaLibs/CalcPaths.lua | 678 +++++++++++++++++++++++++------- LuaLibs/CalcSlices.lua | 164 ++++++-- LuaLibs/CalcSolids.lua | 30 +- LuaLibs/CalcToolPath.lua | 245 +++++++++--- LuaLibs/RunSliceAdvancement.lua | 10 +- LuaLibs/RunSlicePalette.lua | 4 +- LuaLibs/RunSlicing.lua | 50 +++ 8 files changed, 970 insertions(+), 245 deletions(-) diff --git a/LuaLibs/AddManData.lua b/LuaLibs/AddManData.lua index 1838197..93185ce 100644 --- a/LuaLibs/AddManData.lua +++ b/LuaLibs/AddManData.lua @@ -49,6 +49,9 @@ 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" @@ -91,11 +94,20 @@ KEY_RIBS_TWO_STRANDS = "RibsHaveAll2Strands" -- Regioni con diverso numero di passate KEY_SHELL_NBR_DIFF = "ShellNbrDifference" -KEY_INVERTED_CURVE = "CurveIsInverted" KEY_SHELL_NBR_COASTING = "ShellNbrCoasting" KEY_SHELL_NBR_WIPE = "ShellNbrWipe" KEY_SHELL_NBR_WIPE_DIR = "ShellNbrWipeDir" -KEY_CLOSED_EXTRA_SHELL = "ExtraShellIsClosed" + +-- Solidi ausiliari +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_COASTING_LEN = "AuxSolidsCoastingLen" +KEY_AUX_SOLIDS_WIPE_LEN = "AuxSolidsWipeLen" +KEY_AUX_SOLIDS_WIPE_DIR = "AuxSolidsWipeDir" -- Parametri di macchina SEC_3DPRINTING = "3dPrinting" @@ -107,12 +119,17 @@ KEY_SLICE_NBR = "SliceNbr" KEY_SLICE_Z = "SliceZ" KEY_SLICE_DELTAZ = "DeltaZ" KEY_SLICE_REAL_Z = "SliceRealZ" +KEY_ZIG_ZAG_INFILL = "ZigZagInfill" +KEY_ZIG_ZAG_DIR = "ZigZagDir" +KEY_INVERTED_CRV = "InvertedCrv" +KEY_CLOSED_CRV = "ClosedCrv" +KEY_ASSOCIATED_SURF = "AssociatedSurf" TYPE = { OUTER_SHELL = 1, INNER_SHELL = 2, - EXTRA_SHELL = 3, - INFILL = 4, + INFILL = 3, + EXTRA_SHELL = 4, LINK = 5, COASTING = 6, WIPE = 7, @@ -142,6 +159,11 @@ LEAD_TYPE = { ARC = 3, } +INFILL_TYPE = { + NONE = 1, + OFFSET = 2, + ZIGZAG = 3, +} --------------------------------------------------------------------- TABLE = "Table" @@ -208,6 +230,10 @@ RIBS_CRV = "Rib" SHELL_NBR_GRP = "ShellNbrRegions" SHELL_NBR_CRV = "ShellNbrRegion" +AUX_SOLIDS_GRP = "AuxSolids" +AUX_SOLIDS_CRV = "AuxSolid" +AUX_SOLIDS_SRF = "SrfAuxSolid" + --------------------------------------------------------------------- -- parametri calcolo tempi, F ed S LAY_TFSCALC = "TFSCalc" diff --git a/LuaLibs/CalcPaths.lua b/LuaLibs/CalcPaths.lua index cb3f0c5..76e91c0 100644 --- a/LuaLibs/CalcPaths.lua +++ b/LuaLibs/CalcPaths.lua @@ -23,6 +23,9 @@ local function GetLayerParamsForPathCalc() LayerParams.dStrand = EgtGetInfo( s_nPartId, KEY_STRAND, 'd') LayerParams.dOffs = EgtGetInfo( s_nPartId, KEY_OFFSET_SLICE, 'd') LayerParams.nFloorNbr = EgtGetInfo( s_nPartId, KEY_FLOOR_NBR, 'i') + LayerParams.nFloorType = EgtGetInfo( s_nPartId, KEY_FLOOR_TYPE, 'i') + LayerParams.nCeilNbr = EgtGetInfo( s_nPartId, KEY_CEIL_NBR, 'i') + LayerParams.nCeilType = EgtGetInfo( s_nPartId, KEY_CEIL_TYPE, 'i') LayerParams.vtSlicing = EgtGetInfo( s_nPartId, KEY_SLICING_DIR, 'v') LayerParams.bPrintInvert = ( EgtGetInfo( s_nPartId, KEY_PRINT_DIRECTION, 'i') == PRINT_DIRECTION.CW) -- parametri costolature @@ -97,15 +100,13 @@ local function ModifyStartPoint( nCrvId, vPtStart) end end EgtChangeClosedCurveStartPoint( nCrvId, vPtStart[nMinIdx]) - else - -- se non ci sono start point disponibili prendo l'origine - EgtChangeClosedCurveStartPoint( nCrvId, Point3d( 0, 0, 0), GDB_RT.GLOB) end end --------------------------------------------------------------------- local function GetPathsFromSurf( nSrfId, sName, nType, nGrpId, vPtStart) + local vIds = {} local nChunks = EgtSurfFrChunkCount( nSrfId) for nC = 0, nChunks - 1 do -- estraggo i contorni @@ -127,38 +128,263 @@ local function GetPathsFromSurf( nSrfId, sName, nType, nGrpId, vPtStart) return end + table.insert( vIds, nCrvId + nInd) ModifyStartPoint( nCrvId + nInd, vPtStart) end end + + return vIds +end + +---------------------------------------------------------------------- +local function VerifyPath( nCrvId, dStrand, vtSlicing, nGrp) + + local _, _, dArea = EgtCurveArea( nCrvId) + + -- verifico se esiste l'offset (permetto una piccola sovrapposizione) + local dAllowedOverlap = 1 + local nRes, nCnt = EgtOffsetCurveAdv( nCrvId, - dStrand / 2 + dAllowedOverlap) + -- se errore ritento con valore leggermente modificato + if not nRes then + nRes, nCnt = EgtOffsetCurveAdv( nCrvId, - dStrand / 2 + 0.05) + if not nRes then return false end + end + for j = nRes, nRes + nCnt - 1 do + EgtErase( j) + end + + if nRes == GDB_ID.NULL or not dArea or dArea < GEO.EPS_SMALL then + -- verifico se fattibile con una sola passata + -- TODO da sistemare con medial axis per curva generica + local bSingleStrand = false + if EgtCurveIsClosed( nCrvId) then + local nGrpTmp = EgtGroup( nGrp, Frame3d( ORIG(), vtSlicing)) + EgtRelocateGlob( nCrvId, nGrpTmp) + local frLoc, dDimX, dDimY = EgtCurveMinAreaRectangleXY( nCrvId) + if dDimY < 0.5 then + -- 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() + local ptE = frLoc:getOrigin() + dDimX / 2 * frLoc:getVersX() + dZ * Z_AX() + if dist( ptS, ptE) > 5 then + local nId = EgtCurveCompoFromPoints( nGrpTmp, { ptS, ptE}) + local sName = EgtGetName( nCrvId) + if sName then EgtSetName( nId, sName) end + local nType = EgtGetInfo( nCrvId, KEY_TYPE, 'i') + if nType then EgtSetInfo( nId, KEY_TYPE, nType) end + EgtErase( nCrvId) + EgtChangeId( nId, nCrvId) + bSingleStrand = true + end + end + EgtRelocateGlob( nCrvId, nGrp, GDB_IN.LAST_SON) + EgtErase( nGrpTmp) + end + -- se non è fattibile con unica passata lo cancello + if not bSingleStrand then + EgtErase( nCrvId) + return false + end + end + + return true +end + +------------------------------------------------------------------- +local function ComputeTrimSurfWithOverlaps( vIds, nSrfBase, sKeyOverlap, dStrand, nGrp) + + -- per ogni overlap creo le superfici con cui fare i trim + local vSurfOffs = {} + for i = 1, #vIds do + local nOverlap = EgtGetInfo( vIds[i], sKeyOverlap, 'i') + if not vSurfOffs[nOverlap] then + local dNewOffs = nOverlap / 100 * dStrand + local bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrfBase, nGrp, dNewOffs) + if bOk then + vSurfOffs[nOverlap] = nSrfOffs + end + end + end + return vSurfOffs +end + +-------------------------------------------------------------------- +--------------------- RIEMPIMENTI PIENI ---------------------------- +-------------------------------------------------------------------- +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 + + 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 + end + end + end + end + + for i = 1, #vOldSurf do + EgtErase( vOldSurf[i]) + 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 = EgtCP( vChildren[j]) + EgtSpAddPoint( pt:getX(), pt:getY(), pt:getZ(), 0, 0, pt:getX(), pt:getY(), pt:getZ(), 0, 0) + 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) + end + end + end end --------------------------------------------------------------------- -local function AddFloor( nSrfId, nGrpId, LayerParams, nFloorNbr) +--------------------------------------------------------------------------- +local function ComputeOffsetInfill( nSrf, dStrand, vtSlicing, sName, nType, vPtStart, nGrp) - -- local nSrfCopy = EgtCopyGlob( nSrfId, nGrpId) - -- local dOffs = 0.5 * LayerParams.dStrand - LayerParams.dOffs + LayerParams.nShellsNbr * LayerParams.dStrand - -- local dAng = 0 - -- - -- if EgtSurfFrOffset( nSrfCopy, - dOffs) and EgtSurfFrChunkCount( nSrfCopy) > 0 then - -- local nCrvId, nCnt = EgtGetSurfFrZigZagInfill( nSrfCopy, nGrpId, LayerParams.dStrand + 10 * GEO.EPS_SMALL, dAng, false, false) - -- for nInd = 0, nCnt - 1 do - -- local dLen = EgtCurveLength( nCrvId + nInd) - -- if dLen < MIN_LEN then - -- EgtErase( nCrvId + nInd) - -- else - -- EgtSetName( nCrvId + nInd, INFILL_CRV) - -- EgtSetInfo( nCrvId + nInd, KEY_TYPE, TYPE.INFILL) - -- end - -- end - -- EgtErase( nSrfCopy) - -- end + local nChunk = EgtSurfFrChunkCount( nSrf) + if nChunk == 0 then return end + + -- estraggo i contorni della superficie + local vOldIds = GetPathsFromSurf( nSrf, sName, nType, nGrp, vPtStart) + local dOffs = - dStrand + local bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrf, nGrp, dOffs) + while bOk and bExists do + -- estraggo i contorni + local vNewIds = GetPathsFromSurf( nSrfOffs, sName, nType, nGrp, vPtStart) + if vNewIds then + -- riordino + ReorderPath( vOldIds, vNewIds) + -- verifico fattibilità + local k = 1 + while k <= #vNewIds do + if VerifyPath( vNewIds[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) + end + end + vOldIds = vNewIds + end + + EgtErase( nSrfOffs) + -- offset successivo + dOffs = dOffs - dStrand + bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrf, nGrp, dOffs) + end end - ------------------------------------------------------------------- ---------------------------- RIBS ----------------------------------- --------------------------------------------------------------------- +-------------------------------------------------------------------------------- +local function ComputeZigZagInfill( nSrf, dStrand, vtSlicing, sName, nType, vPtStart, nGrp) + local nChunk = EgtSurfFrChunkCount( nSrf) + if nChunk == 0 then return end + + local nCopySrf = EgtCopyGlob( nSrf, nGrp) + if EgtSurfFrChunkCount( nSrf) == 0 then return end + + local nFirst, nCnt = EgtExplodeSurf( nCopySrf) + local frLoc = Frame3d( ORIG(), vtSlicing) + local vIds = {} + for nId = nFirst, nFirst + nCnt - 1 do + local nGrpTmp = EgtGroup( nGrp, frLoc) + + -- recupero outer curve + local nCrvGrpId = EgtGetParent( nGrp) + local nOuterCrv = EgtGetFirstNameInGroup( nCrvGrpId, OUTER_CRV) + local nCopyOuterCrv = EgtCopyGlob( nOuterCrv, nGrpTmp) + + -- cerco il lato più lungo + local vCrvIds = GetPathsFromSurf( nId, 'Tmp', nType, nGrpTmp) + local dMaxLen = - GEO.INFINITO + local dDist = GEO.INFINITO + local vtDir + + for j = 1, #vCrvIds do + local nId, nCnt = EgtExplodeCurveCompo( vCrvIds[j]) + + -- cerco il lato più lungo + for k = nId, nId + nCnt - 1 do + local dCurrLen = EgtCurveLength( k) + if dCurrLen > dMaxLen + GEO.EPS_SMALL then + dMaxLen = dCurrLen + end + end + -- tra i lati più lunghi scelgo quello più vicino al bordo + for k = nId, nId + nCnt - 1 do + local dCurrLen = EgtCurveLength( k) + if abs( dMaxLen - dCurrLen) < 10 then + local dCurrDist = EgtPointCurveDist( EgtMP( k), nCopyOuterCrv) + if dCurrDist < dDist + 10 * GEO.EPS_SMALL then + vtDir = EgtSV( k) + dDist = dCurrDist + end + end + end + end + EgtErase( nGrpTmp) + + local _, _, dAng = SphericalFromVector( vtDir) + vtDir:toGlob( frLoc) + + local nInd, nCnt = EgtGetSurfFrZigZagInfill( nId, nGrp, dStrand, dAng, false, false) + if not nInd then return end + for j = nInd, nInd + nCnt - 1 do + EgtSetName( j, sName) + EgtSetInfo( j, KEY_TYPE, nType) + EgtSetInfo( j, KEY_ZIG_ZAG_DIR, vtDir) + EgtSetInfo( j, KEY_ZIG_ZAG_INFILL, 1) + EgtModifyCurveExtrusion( j, vtSlicing) + table.insert( vIds, j) + end + local vtS = EgtSV( nInd) + EgtErase( nId) + end + +end + +------------------------------------------------------------------- +--------------------------- RIBS ----------------------------------- -------------------------------------------------------------------- local function TrimRibsOffset( nCrv, nOffs1, nOffs2, nOffsGrp, bIn) @@ -269,26 +495,22 @@ end -------------------------------------------------------------------- local function HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPathGrp, bAllTwoStrands) - + local nCrvGrp = EgtGetParent( nRibsPathGrp) - local nSrf = EgtGetFirstInGroup( nCrvGrp) - - local vRibsIds = {} - local vOrigRibs = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*') - local nTrimmedRibsGrp = EgtGroup( nRibsPathGrp) - for i = 1, #vOrigRibs do - local nCopyId = EgtCopyGlob( vOrigRibs[i], nTrimmedRibsGrp) - local nCrv, nCnt = EgtTrimCurveWithRegion( nCopyId, nSrf, true, false) - for j = nCrv, nCrv + nCnt - 1 do - table.insert( vRibsIds, j) - end - -- copio i suoi offset nel RibsPathGrp - local vOffsRib = EgtGetNameInGroup( nOffsGrp, EgtGetName( vOrigRibs[i])) - for i = 1, #vOffsRib do - EgtCopyGlob( vOffsRib[i], nRibsPathGrp) - end + -- copio gli offset delle costolature nel RibsPathGrp + local vOffsRib = EgtGetAllInGroup( nOffsGrp) + for i = 1, #vOffsRib do + EgtCopyGlob( vOffsRib[i], nRibsPathGrp) 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) + end + + local vRibsIds = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*') local bInters = false local vSplit = {} for i = 1, #vRibsIds do @@ -296,32 +518,38 @@ local function HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPa for j = i + 1, #vRibsIds do local ptInt = EgtIP( vRibsIds[i], vRibsIds[j], ORIG()) if ptInt 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 bIn = abs( dPar1 - dParE1) < 50 * GEO.EPS_SMALL or abs( dPar2 - dParE2) < 50 * GEO.EPS_SMALL - local nCrv1 = vRibsIds[i] -- curva principale che non viene tagliata - local nCrv2 = vRibsIds[j] -- curve secondaria da modificare - if dPar1 < 50 * GEO.EPS_SMALL or abs( dPar1 - dParE1) < 50 * GEO.EPS_SMALL then - nCrv1, nCrv2 = nCrv2, nCrv1 - end - - if bAllTwoStrands then - -- nel caso di 2 passate gestione speciale - AdjustRibsOffsetForIntersection2Shells( nCrv1, nCrv2, LayerParams, nRibsPathGrp, bIn) - else - AdjustRibsOffsetForIntersection( nCrv1, nCrv2, LayerParams, nRibsPathGrp, bIn) + -- verifico se l'interserzione si trova nella regione dello slice + local nPtId = EgtPoint( nRibsPathGrp, ptInt) + if not EgtSurfFrTestExternal( nSrfOffs, nPtId) 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 bIn = abs( dPar1 - dParE1) < 50 * GEO.EPS_SMALL or abs( dPar2 - dParE2) < 50 * GEO.EPS_SMALL + local nCrv1 = vRibsIds[i] -- curva principale che non viene tagliata + local nCrv2 = vRibsIds[j] -- curve secondaria da modificare + if dPar1 < 50 * GEO.EPS_SMALL or abs( dPar1 - dParE1) < 50 * GEO.EPS_SMALL then + nCrv1, nCrv2 = nCrv2, nCrv1 + end + + if bAllTwoStrands then + -- nel caso di 2 passate gestione speciale + AdjustRibsOffsetForIntersection2Shells( nCrv1, nCrv2, LayerParams, nRibsPathGrp, bIn) + else + AdjustRibsOffsetForIntersection( nCrv1, nCrv2, LayerParams, nRibsPathGrp, bIn) + end end + EgtErase( nPtId) end end end - EgtErase( nTrimmedRibsGrp) - + EgtErase( nSrfOffs) + return bInters end @@ -355,13 +583,6 @@ local function ReorderRibs( nGrp, bInvertOrder, dStrand, nMaxNbr) EgtRelocateGlob( vSPRibs[vOrd[i]], vSPRibs[vOrd[i-1]], EgtIf( bInvertOrder, GDB_IN.BEFORE, GDB_IN.AFTER)) end - -- aggiusto tutte le costolature divise - for i = 1, #vSplitRibs do - local nPrevId = EgtGetInfo( vSplitRibs[i], KEY_SPLIT_RIB, 'i') - -- aggiungo come successiva alla costolatura da cui si è generata - EgtRelocateGlob( vSplitRibs[i], nPrevId, GDB_IN.AFTER) - end - -- sistemo nomi local kMax = nMaxNbr + 1 for i = 1, nMaxNbr do @@ -379,7 +600,21 @@ local function ReorderRibs( nGrp, bInvertOrder, dStrand, nMaxNbr) kMax = kMax + 1 end end + end + + -- aggiusto tutte le costolature divise + 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)) + -- correggo le info per gestire correttamente nel calcolo toolpath + if bInverted then + EgtRemoveInfo( vSplitRibs[i], KEY_SPLIT_RIB) + EgtSetInfo( nPrevId, KEY_SPLIT_RIB, vSplitRibs[i]) + end end + end -------------------------------------------------------------------------------------------- @@ -410,7 +645,8 @@ local function ReassignInfo( nCrv, nCnt, vOrig) -- verifico se corrisponde al suo start if AreSamePointApprox( ptS, ptSOrig) or AreSamePointApprox( ptS, ptEOrig) then 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_RIBS_LEAD_IN_LEN, 'd') + CopyInfo( vOrig[i], nId, KEY_ASSOCIATED_SURF, 'i') bStart = true end -- verifico se corrisponde al suo end @@ -593,18 +829,8 @@ local function CalcRibsPaths( nSliceGrp, nRibsGrp, LayerParams, nIdx, nMaxStrand local nSrfBase = EgtGetFirstNameInGroup( nCrvGrp, TOT_SHELL_TRIM_SURF) if not nSrfBase then EgtOutLog( 'Warning : Ribs not possible (layer '..tostring( nIdx)..') - CalcPaths') - else - local vSurfOffs = {} - for i = 1, #vRibs do - local nOverlap = EgtGetInfo( vRibs[i], KEY_RIBS_OVERLAP, 'i') - if not vSurfOffs[nOverlap] then - local dNewOffs = nOverlap / 100 * LayerParams.dStrand - local bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrfBase, nRibsPathGrp, dNewOffs) - if bOk then - vSurfOffs[nOverlap] = nSrfOffs - end - end - end + else + local vSurfOffs = ComputeTrimSurfWithOverlaps( vRibs, nSrfBase, KEY_RIBS_OVERLAP, LayerParams.dStrand, nRibsPathGrp) -- gestisco eventuali intersezioni fra costolature local bInters = HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPathGrp, bAllTwoStrands) @@ -624,7 +850,7 @@ local function CalcRibsPaths( nSliceGrp, nRibsGrp, LayerParams, nIdx, nMaxStrand 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) @@ -638,8 +864,12 @@ local function CalcRibsPaths( nSliceGrp, nRibsGrp, LayerParams, nIdx, nMaxStrand local dVal = EgtIf( abs( vtDir:getX()) > abs( vtDir:getY()) - GEO.EPS_SMALL, vtDir:getX(), vtDir:getY()) if dVal < - GEO.EPS_SMALL 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') @@ -658,7 +888,7 @@ local function CalcRibsPaths( nSliceGrp, nRibsGrp, LayerParams, nIdx, nMaxStrand end end end - + -- riordino le costolature if bAllTwoStrands and bInters then -- gestione caso speciale di intersezione e 2 passate @@ -793,7 +1023,7 @@ local function ReorderExtraShells( nPathGrp, dStrand, vPtStart, bPrintInvert) if bPrintInvert then for i = 1, #vIds do EgtInvertCurve( vIds[i]) - EgtSetInfo( vIds[i], KEY_INVERTED_CURVE, 1) + EgtSetInfo( vIds[i], KEY_INVERTED_CRV, 1) end end @@ -812,7 +1042,6 @@ local function ReorderExtraShells( nPathGrp, dStrand, vPtStart, bPrintInvert) -- se curva è chiusa if EgtCurveIsClosed( nCurrCrv) then ModifyStartPoint( nCurrCrv, vPtStart) - EgtSetInfo( nCurrCrv, KEY_CLOSED_EXTRA_SHELL, 1) -- setto a nil per ripartire subito con curva successiva nCurrCrv = nil end @@ -840,12 +1069,12 @@ local function ReorderExtraShells( nPathGrp, dStrand, vPtStart, bPrintInvert) if dist( ptE, ptECurr) < 1.5 * dStrand then -- congiungo end-end EgtInvertCurve( vIds[j]) - EgtSetInfo( vIds[j], KEY_INVERTED_CURVE, EgtIf( bPrintInvert, 0, 1)) + EgtSetInfo( vIds[j], KEY_INVERTED_CRV, EgtIf( bPrintInvert, 0, 1)) bLink = true elseif nCnt == 0 and dist( ptS, ptSCurr) < 1.5 * dStrand then -- congiungo start-start EgtInvertCurve( nCurrCrv) - EgtSetInfo( nCurrCrv, KEY_INVERTED_CURVE, EgtIf( bPrintInvert, 0, 1)) + EgtSetInfo( nCurrCrv, KEY_INVERTED_CRV, EgtIf( bPrintInvert, 0, 1)) bLink = true end @@ -872,45 +1101,6 @@ local function ReorderExtraShells( nPathGrp, dStrand, vPtStart, bPrintInvert) end end --------------------------------------------------------------------- -local function VerifyExtraShellPath( nCrv, nGrpId, vtSlicing, dStrand) - - -- verifico se è fattibile controllando se esiste offset - local nOffs, nCnt = EgtOffsetCurveAdv( nCrv, - 0.5 * dStrand) - if not nOffs or nOffs == GDB_ID.NULL then - return false - end - for i = nOffs, nOffs + nCnt - 1 do - EgtErase( i) - end - - -- controllo se è fattibile con una sola passata - if EgtCurveIsClosed( nCrv) then - local nGrpTmp = EgtGroup( nGrpId, Frame3d( ORIG(), vtSlicing)) - EgtRelocateGlob( nCrv, nGrpTmp) - local dArea = EgtCurveAreaXY( nCrv) - if dArea < 10 * GEO.EPS_SMALL then - -- TODO curva generica - local frLoc, dDimX, dDimY = EgtCurveMinAreaRectangleXY( nCrv) - if dDimY < 10 * GEO.EPS_SMALL then - local dZ = EgtSP( nCrv):getZ() - -- creo la curva che corrisponde alla sigola passata - local ptS = frLoc:getOrigin() - dDimX / 2 * frLoc:getVersX() + dZ * Z_AX() - local ptE = frLoc:getOrigin() + dDimX / 2 * frLoc:getVersX() + dZ * Z_AX() - if dist( ptS, ptE) > 5 then - local nId = EgtCurveCompoFromPoints( nGrpTmp, { ptS, ptE}) - EgtErase( nCrv) - EgtChangeId( nId, nCrv) - end - end - end - EgtRelocateGlob( nCrv, nGrpId, GDB_IN.LAST_SON) - EgtErase( nGrpTmp) - end - - return true -end - -------------------------------------------------------------------- local function CalcExtraShellsPath( nMaxShellNbrDiff, nShellNbrGrp, nCrvGrpId, dOffs, LayerParams, nIdx, vPtStart) @@ -951,9 +1141,12 @@ local function CalcExtraShellsPath( nMaxShellNbrDiff, nShellNbrGrp, nCrvGrpId, d if nCrv and nCnt ~= 0 then for nId = nCrv, nCrv + nCnt - 1 do local dLen = EgtCurveLength( nId) - local bValid = VerifyExtraShellPath( nId, nGrpId, LayerParams.vtSlicing, LayerParams.dStrand) + local bValid = true + if EgtCurveIsClosed( nId) then + bValid = VerifyPath( nId, LayerParams.dStrand, LayerParams.vtSlicing, nGrpId) + end -- verifico se soddisfa vincolo sulla lunghezza - if dLen > MIN_LEN and bValid then + if dLen > MIN_LEN and bValid then EgtModifyCurveExtrusion( nId, LayerParams.vtSlicing) EgtSetName( nId, EXTRA_SHELL_CRV .. tostring( nMaxShellNbrDiff - nInd + 1)) EgtSetInfo( nId, KEY_TYPE, TYPE.EXTRA_SHELL) @@ -987,6 +1180,187 @@ local function CalcExtraShellsPath( nMaxShellNbrDiff, nShellNbrGrp, nCrvGrpId, d end +-------------------------------------------------------------------- +------------------ AUX SOLIDS ------------------------------------- +-------------------------------------------------------------------- +local function UpdateTrimSurfWithAuxSolidsOffset( nSrfSolid, nSrfBase, dStrand, nCrvGrp) + + -- offset della superifice del solido + local bOk, bExists, nSrfOffs = ComputeSurfOffset( nSrfSolid, nCrvGrp, dStrand) + if nSrfOffs then + EgtSurfFrSubtract( nSrfBase, nSrfOffs) + EgtErase( nSrfOffs) + end +end + +-------------------------------------------------------------------- +local function UpdateTrimSurfWithAuxSolidsZigZag( nAuxSolidsGrp, sName, nSrfBase, dStrand, nSrf) + + local nGrpTmp = EgtGroup( nAuxSolidsGrp) -- gruppo temporaneo per conti + + -- recupero le curve associate + local vCrvs = EgtGetNameInGroup( nAuxSolidsGrp, sName) + for i = 1, #vCrvs do + + local vtDir = EgtSV( vCrvs[i]) + -- costruisco percorso associato + local nCopyCrv = EgtCopyGlob( vCrvs[i], nGrpTmp) + local nCopy2 = EgtCopyGlob( vCrvs[i], nGrpTmp) + EgtInvertCurve( nCopy2) + EgtAddCurveCompoCurve( nCopyCrv, nCopy2) + local nOffsP = EgtOffsetCurveAdv( nCopyCrv, dStrand, GDB_OT.FILLET) + local nFirst, nCnt = EgtExplodeCurveCompo( nOffsP, nGrpTmp) + + -- cerco tratti lineari orientati ortogonalmente alla direzione di svuotatura + local nRes = EgtCurveCompo( nGrpTmp, {nFirst}) + local nInd = nFirst + 1 + while nInd < nFirst + nCnt do + local vtCurrDir = EgtSV( nInd) + local nType = EgtGetType( nInd) + + -- se è linea ortognale alla direzione della svuotatura la approssimo + if nType == GDB_TY.CRV_LINE and abs( vtDir * vtCurrDir) < 10 * GEO.EPS_SMALL then + -- cerco ultima curva con lo stesso orientamento + local nLastValidId = nInd + local nInd2 = nInd + 1 + while nInd2 < nFirst + nCnt do + nType = EgtGetType( nInd2) + if nType == GDB_TY.CRV_LINE then + if AreSameVectorApprox( EgtSV( nInd2), vtCurrDir) then + nLastValidId = nInd2 + else + break + end + end + nInd2 = nInd2 + 1 + end + + -- aggiungo l'approssimazione lineare + EgtAddCurveCompoLine( nRes, EgtEP( nLastValidId)) + -- setto l'indice per ripartire correttamente dopo l'approssimazione + nInd = nLastValidId + + else + -- se arco o linea inclinata, aggiungo direttamente al percorso + EgtAddCurveCompoCurve( nRes, nInd) + end + + nInd = nInd + 1 + end + + -- utilizzo la curva per creare superficie + local nSrfZigZag = EgtSurfFlatRegion( nGrpTmp, {nRes}) + if nSrfZigZag then + EgtSurfFrSubtract( nSrfBase, nSrfZigZag) + else + EgtSurfFrSubtract( nSrfBase, nSrf) + end + + end + EgtErase( nGrpTmp) + +end + +------------------------------------------------------------------- +local function AddExtraZigZag( nSrf, sName, dStrand, vtSlicing, nGrp, nSrfTrim) + + local vIds = EgtGetNameInGroup( nGrp, sName) + local vtDir = EgtSV( vIds[1]) + local vtYLoc = vtSlicing ^ vtDir + + local nOuterLoop = EgtExtractSurfFrChunkLoops( nSrf, 0, nGrp) + + for i = 1, #vIds do + local _, dParE = EgtCurveDomain( vIds[i]) + local ptS = EgtUP( vIds[i], dParE - 1) + dStrand * vtYLoc + local ptE = EgtEP( vIds[i]) + dStrand * vtYLoc + local nExtraCrv = EgtLine( nGrp, ptS, ptE) + -- verifico se la linea aggiuntiva serve + local dDist = EgtPointCurveDist( EgtMP( nExtraCrv), nOuterLoop) + if dDist < dStrand - 1 then + -- verifico se si trova nella regione ammissibile + if EgtCurveWithRegionClassify( nExtraCrv, nSrfTrim) == GDB_CRC.IN then + EgtInvertCurve( nExtraCrv) + EgtAddCurveCompoLine( vIds[i], ptE) + EgtAddCurveCompoCurve( vIds[i], nExtraCrv) + end + end + EgtErase( nExtraCrv) + end + + EgtErase( nOuterLoop) +end + +-------------------------------------------------------------------- +local function CalcAuxSolidsPaths( nSliceGrp, nSolidGrp, LayerParams, vPtStart) + + -- recupero i solidi ausiliari + local vSolidIds = EgtGetAllInGroup( nSolidGrp) + + -- scorro i gruppi di curve + local nCrvGrp = EgtGetFirstNameInGroup( nSliceGrp, CONTOUR_GRP .. '*') + while nCrvGrp do + + -- creo o svuoto il gruppo per i solidi ausiliari + local nSolidPathGrp = EgtGetFirstNameInGroup( nCrvGrp, AUX_SOLIDS_GRP) + if not nSolidPathGrp then + nSolidPathGrp = EgtGroup( nCrvGrp) + EgtSetName( nSolidPathGrp, AUX_SOLIDS_GRP) + EgtSetStatus( nSolidPathGrp, GDB_ST.OFF) + else + EgtEmptyGroup( nSolidPathGrp) + end + + -- creo le superfici con cui fare i trim + local nSrfBase = EgtGetFirstNameInGroup( nCrvGrp, TOT_SHELL_TRIM_SURF) + if not nSrfBase then + EgtOutLog( 'Warning : AuxSolids not possible (layer '..tostring( nIdx)..') - CalcPaths') + else + local vSurfOffs = ComputeTrimSurfWithOverlaps( vSolidIds, nSrfBase, KEY_AUX_SOLIDS_OVERLAP, LayerParams.dStrand, nSolidPathGrp) + + for i = 1, #vSolidIds do + -- creo la flat region corrispondente al solido ausiliario + local sName = EgtGetName( vSolidIds[i]) + local nOverlap = EgtGetInfo( vSolidIds[i], KEY_AUX_SOLIDS_OVERLAP, 'i') + local nSrfId = EgtSurfFlatRegion( nSolidPathGrp, vSolidIds[i]) + EgtSetName( nSrfId, AUX_SOLIDS_SRF) + -- trim con la superficie di offset + EgtSurfFrIntersect( nSrfId, vSurfOffs[nOverlap]) + + local nFirst, nCnt = EgtExplodeSurf( nSrfId) + for j = 0, nCnt - 1 do + local sNewName = sName .. EgtIf( j == 0, '', '_' .. tostring( j)) + local nInfillType = EgtGetInfo( vSolidIds[i], KEY_AUX_SOLIDS_INFILL, 'i') + if nInfillType == INFILL_TYPE.OFFSET then + ComputeOffsetInfill( nFirst + j, LayerParams.dStrand, LayerParams.vtSlicing, sNewName, TYPE.AUX_SOLID, vPtStart, nSolidPathGrp) + -- aggiorno la trim surf + UpdateTrimSurfWithAuxSolidsOffset( nFirst + j, nSrfBase, LayerParams.dStrand, nSolidPathGrp) + else + ComputeZigZagInfill( nFirst + j, LayerParams.dStrand, LayerParams.vtSlicing, sNewName, TYPE.AUX_SOLID, vPtStart, nSolidPathGrp) + -- 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) + end + end + end + + -- elimino le superfici utilizzate per il trim + for k, v in pairs( vSurfOffs) do + EgtErase( v) + end + end + + -- verifico se il gruppo contine qualcosa + if not EgtGetFirstNameInGroup( nSolidPathGrp, AUX_SOLIDS_CRV .. '*') then + EgtErase( nSolidPathGrp) + end + + -- passo al gruppo di contorni successivo + nCrvGrp = EgtGetNextName( nCrvGrp, CONTOUR_GRP .. '*') + end +end + --------------------------------------------------------------------- function CalcPaths.Exec( nPartId) @@ -1004,6 +1378,7 @@ function CalcPaths.Exec( nPartId) for nIdx = 1, #vLayIds do local nRibsGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], RIBS_GRP) + local nAuxSolidsGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], AUX_SOLIDS_GRP) -- regioni con diverso numero di passate local nShellNbrGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], SHELL_NBR_GRP) @@ -1032,7 +1407,7 @@ function CalcPaths.Exec( nPartId) end -- recupero la superficie ottenuta dallo slicing - local nSrf = EgtGetFirstNameInGroup( nCrvGrpId, LAYER_SRF) + local nSrf = EgtGetFirstNameInGroup( nCrvGrpId, LAYER_SRF) if nSrf then -- parete esterna @@ -1044,10 +1419,15 @@ function CalcPaths.Exec( nPartId) EgtOutLog( 'Warning : ExtOffset not possible (layer '..tostring( nIdx)..') - CalcPaths') else -- se offset riuscito, estraggo i contorni (pareti esterne) - GetPathsFromSurf( nSrfId, SHELL_CRV..'0', TYPE.OUTER_SHELL, nGrpId, vPtStart) + GetPathsFromSurf( nSrfId, SHELL_CRV ..'0', TYPE.OUTER_SHELL, nGrpId, vPtStart) end EgtErase( nSrfId) + local vPtInnerStart = {} + local vOuterShell = EgtGetNameInGroup( nGrpId, SHELL_CRV .. '0') or {} + for i = 1, #vOuterShell do + table.insert( vPtInnerStart, EgtSP( vOuterShell[i])) + end -- pareti interne complete local nMaxShellNbrDiff = ComputeMaxShellNbrDiff( nSrf, nShellNbrSurfGrp) for nInd = 1, LayerParams.nShellsNbr - 1 - nMaxShellNbrDiff do @@ -1060,7 +1440,7 @@ function CalcPaths.Exec( nPartId) EgtOutLog( 'Warning : IntOffset not possible (layer '..tostring( nIdx)..') - CalcPaths') else -- se offset riuscito, estraggo i contorni ( pareti interne) - GetPathsFromSurf( nSrfId, SHELL_CRV..tostring( nInd), TYPE.INNER_SHELL, nGrpId, vPtStart) + GetPathsFromSurf( nSrfId, SHELL_CRV..tostring( nInd), TYPE.INNER_SHELL, nGrpId, vPtInnerStart) end EgtErase( nSrfId) end @@ -1076,25 +1456,43 @@ function CalcPaths.Exec( nPartId) -- eventuali pareti interne coinvolte dal diverso numero di passate if nMaxShellNbrDiff > 0 then - CalcExtraShellsPath( nMaxShellNbrDiff, nShellNbrSurfGrp, nCrvGrpId, dOffs, LayerParams, nIdx, vPtStart) + CalcExtraShellsPath( nMaxShellNbrDiff, nShellNbrSurfGrp, nCrvGrpId, dOffs, LayerParams, nIdx, vPtInnerStart) end - -- gestione eventuale floor + -- gestione eventuale floor/ceil if nIdx <= LayerParams.nFloorNbr then - AddFloor( nSrf, nGrpId, LayerParams, nIdx) + if LayerParams.nFloorType == INFILL_TYPE.OFFSET then + ComputeOffsetInfill( nSrfTrim, LayerParams.dStrand, LayerParams.vtSlicing, INFILL_CRV, TYPE.INFILL, vPtStart, nGrpId) + elseif LayerParams.nFloorType == INFILL_TYPE.ZIGZAG then + ComputeZigZagInfill( nSrfTrim, LayerParams.dStrand, LayerParams.vtSlicing, INFILL_CRV, TYPE.INFILL, vPtStart, nGrpId) + end + elseif nIdx > #vLayIds - LayerParams.nCeilNbr then + if LayerParams.nCeilType == INFILL_TYPE.OFFSET then + ComputeOffsetInfill( nSrfTrim, LayerParams.dStrand, LayerParams.vtSlicing, INFILL_CRV, TYPE.INFILL, vPtStart, nGrpId) + elseif LayerParams.nCeilType == INFILL_TYPE.ZIGZAG then + ComputeZigZagInfill( nSrfTrim, LayerParams.dStrand, LayerParams.vtSlicing, INFILL_CRV, TYPE.INFILL, vPtStart, nGrpId) + end 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, nIdx, nMaxStrandDiff) + -- sistemo eventuali costolature + if nRibsGrp then + CalcRibsPaths( vLayIds[nIdx], nRibsGrp, LayerParams, nIdx, nMaxStrandDiff) + end end - if EgtProcessEvents( nIdx / #vLayIds * 100, 0) == 1 then + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + nIdx / #vLayIds * 100, 0) == 1 then EgtDraw() return end diff --git a/LuaLibs/CalcSlices.lua b/LuaLibs/CalcSlices.lua index 99446fc..326ae09 100644 --- a/LuaLibs/CalcSlices.lua +++ b/LuaLibs/CalcSlices.lua @@ -54,15 +54,38 @@ local function ComputeMaxH( nStmId, frSlicing, HMax) end -------------------------------------------------------------------- -local function AdjustRibs( nRibsLay) +local function AdjustAuxSolids( nSolidsLay) --- -- recupero le superfici che definiscono le nervature --- local vRibsIds = EgtGetAllInGroup( nRibsLay or GDB_ID.NULL) --- if not vRibsIds or #vRibsIds == 0 then return end --- -- sistemo la direzione normale dei piani --- for i = 1, #vRibsIds do --- -- TODO se curva estrudi in z --- end + -- 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 -------------------------------------------------------------------- @@ -87,22 +110,91 @@ local function GetRibParams( nId) -- 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 + if bLink then RibParam[ KEY_RIBS_OVERLAP] = EgtGetInfo( s_nPartId, KEY_RIBS_OVERLAP, 'i') -- parametro generico - else + else ReadParam( nId, KEY_RIBS_OVERLAP, 'i', RibParam) -- parametro specifico della costolatura end return RibParam end +-------------------------------------------------------------------- +local function GetAuxSolidsParams( nId) + + local AuxSolidsParam = {} + ReadParam( nId, KEY_AUX_SOLIDS_OVERLAP, 'i', AuxSolidsParam) + ReadParam( nId, KEY_AUX_SOLIDS_LINK_PARAM, 'd', AuxSolidsParam) + ReadParam( nId, KEY_AUX_SOLIDS_SP_OFFSET, 'd', AuxSolidsParam) + ReadParam( nId, KEY_AUX_SOLIDS_COASTING_LEN, 'd', AuxSolidsParam) + 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 + + return AuxSolidsParam +end + -------------------------------------------------------------------- local function SlicingExtraObjects( vtSlicing, nLay, nType, sNameGrp, sName) -- 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 = {} @@ -115,9 +207,12 @@ local function SlicingExtraObjects( vtSlicing, nLay, nType, sNameGrp, sName) elseif nType == TYPE.EXTRA_SHELL then vParams[KEY_SHELL_NBR_DIFF] = EgtGetInfo( vIds[i], KEY_SHELL_NBR_DIFF, 'i') or EgtGetInfo( s_nPartId, KEY_SHELL_NBR_DIFF, 'i') if vParams[KEY_SHELL_NBR_DIFF] == 0 then bToBeDone = false end + elseif nType == TYPE.AUX_SOLID then + vParams = GetAuxSolidsParams( vIds[i]) + if vParams[KEY_AUX_SOLIDS_INFILL] == INFILL_TYPE.NONE then bToBeDone = false end end table.insert( tabParams, vParams) - table.insert( vToBeDone, bToBeDone) + table.insert( vToBeDone, bToBeDone) end local nLayId = EgtGetFirstNameInGroup( s_nPartId, SLICE_LAYER .. '*') @@ -131,24 +226,36 @@ local function SlicingExtraObjects( vtSlicing, nLay, nType, sNameGrp, sName) EgtSetStatus( nGrp, GDB_ST.OFF) for i = 1, #vIds do - if EgtGetType( vIds[i]) == GDB_TY.SRF_MESH and vToBeDone[i] then + 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 ( potrebbe servire per solidi ausiliari) + local dCorr = 0 + if nSrfCnt > 0 then + -- 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 - -- rimuovo punti + -- rimuovo punti for nId = nNewId, nNewId + nPntCnt -1 do EgtErase( nId) end -- 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 * vtSlicing) + EgtMove( nId, - ( dDeltaZ + dCorr) * vtSlicing) for sKey, sVal in pairs( tabParams[i]) do EgtSetInfo( nId, sKey, sVal) end end -- rimuovo superfici - for nId = nNewId + nPntCnt + nCrvCnt, nNewId + nPntCnt + nCrvCnt + nSrfCnt -1 do + for nId = nNewId + nPntCnt + nCrvCnt, nNewId + nPntCnt + nCrvCnt + nSrfCnt - 1 do EgtErase( nId) end end @@ -221,7 +328,7 @@ function CalcSlices.Exec( nPartId, nStmId, HMax) local nLayId = EgtParPlanesSurfTmInters( ORIG(), vtSlicing, vZSlices, nStmId, nPartId, GDB_RT.GLOB, TOLER) local vErr = {} local vPrevCen = {} - -- scorro i risultati dello slicing + -- scorro i risultati dello slicing while nLayId do local dDeltaZ = EgtIf( nLayCnt == 1, dDeltaZStart, 0) @@ -427,7 +534,11 @@ function CalcSlices.Exec( nPartId, nStmId, HMax) table.insert( vErr, nLayCnt) end - -- passo al layer successivo + -- passo al layer successivo + if EgtProcessEvents( nLayCnt / ( #vZSlices + 3) * 100, 0) == 1 then + EgtDraw() + return + end nLayCnt = nLayCnt + 1 nLayId = EgtGetNext( nLayId) end @@ -435,20 +546,29 @@ function CalcSlices.Exec( nPartId, nStmId, HMax) -- costolature local nRibsLay = EgtGetFirstNameInGroup( s_nPartId, LAY_RIBS) if nRibsLay then - AdjustRibs( nRibsLay) - SlicingExtraObjects( vtSlicing, nRibsLay, TYPE.RIB, RIBS_GRP, RIBS_CRV) + SlicingExtraObjects( vtSlicing, nRibsLay, TYPE.RIB, RIBS_GRP, RIBS_CRV) end + if EgtProcessEvents( ( #vZSlices + 1) / ( #vZSlices + 3) * 100, 0) == 1 then return end -- solidi per regioni con diverso numero di passate - local nShellNbrLay = EgtGetFirstNameInGroup( s_nPartId, LAY_SHELL_NBR) + local nShellNbrLay = EgtGetFirstNameInGroup( s_nPartId, LAY_SHELL_NBR) if nShellNbrLay then SlicingExtraObjects( vtSlicing, nShellNbrLay, TYPE.EXTRA_SHELL, SHELL_NBR_GRP, SHELL_NBR_CRV) end + if EgtProcessEvents( ( #vZSlices + 2) / ( #vZSlices + 3) * 100, 0) == 1 then return 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) + end + if EgtProcessEvents( ( #vZSlices + 3) / ( #vZSlices + 3) * 100, 0) == 1 then return end -- eventuale segnalazione errori if #vErr > 0 then EgtOutBox( 'Slicing Error on layers :\n' .. table.concat( vErr, ','), 'SlicingCalc') - end + end end --------------------------------------------------------------------- diff --git a/LuaLibs/CalcSolids.lua b/LuaLibs/CalcSolids.lua index 5d0211e..b806d55 100644 --- a/LuaLibs/CalcSolids.lua +++ b/LuaLibs/CalcSolids.lua @@ -136,18 +136,26 @@ local function CreateSolidFromCurve( nCrvId, nSolidGrp, LayerParams) Color = EgtStdColor( 'LIME') elseif nType == TYPE.RIB then Color = EgtStdColor( 'OLIVE') - end - - local nParts = 1 - local LEN_REF = 100 - local dLen = EgtCurveLength( nCrvId) - if dLen > LEN_REF and nType ~= TYPE.LINK and nType ~= TYPE.COASTING then - nParts = EgtClamp( floor( dLen / LEN_REF), 1, 10) + elseif nType == TYPE.AUX_SOLID then + Color = EgtStdColor( 'AQUA') end local nCopyId = EgtCopyGlob( nCrvId, nSolidGrp) - local nId = EgtSplitCurve( nCopyId, nParts) - if not nId then return false end + local nId = GDB_ID.NULL + local nParts = 1 + local LEN_REF = 100 + local bZigZagInfill = EgtGetInfo( nCopyId, KEY_ZIG_ZAG_INFILL, 'b') or false + if bZigZagInfill then + nId, nParts = EgtSplitCurveAtCorners( nCopyId, 80) + else + local dLen = EgtCurveLength( nCrvId) + if dLen > LEN_REF and nType ~= TYPE.LINK and nType ~= TYPE.COASTING then + nParts = EgtClamp( floor( dLen / LEN_REF), 1, 10) + end + nId = EgtSplitCurve( nCopyId, nParts) + end + + if nId == GDB_ID.NULL then return false end local bOk = true for nInd = 0, nParts - 1 do local nGuideId = nId + nInd @@ -259,7 +267,7 @@ function CalcSolids.Exec( nPartId) nCrvGrpId = EgtGetNextName( nCrvGrpId, CONTOUR_GRP.."*") or GDB_ID.NULL end EgtDraw() - if EgtProcessEvents( nIdx / #vLayIds * 100, 0) == 1 then + if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / #vLayIds * 100, 0) == 1 then return end end @@ -269,7 +277,7 @@ function CalcSolids.Exec( nPartId) -- EgtOutBox( 'Error on layers :\n' .. table.concat( vErr, ','), 'SolidCalc') -- end - for i = 1, #vErr do + for i = 1, #vErr do EgtOutLog( 'Error on solid creation (layer ' .. vErr[i] .. ') - SolidCalc') end diff --git a/LuaLibs/CalcToolPath.lua b/LuaLibs/CalcToolPath.lua index 69d05c2..339cb64 100644 --- a/LuaLibs/CalcToolPath.lua +++ b/LuaLibs/CalcToolPath.lua @@ -14,6 +14,7 @@ local AMD = require( 'AddManData') --------------------------------------------------------------------- local s_nPartId +local s_nDefaultWipeAng = -90 -- angolo = 0° per wipe significa che esce ortogonalmente alla direzione del movimento --------------------------------------------------------------------- local function GetLayerParamsForToolPathCalc() @@ -64,32 +65,36 @@ end ------------------------------------------------------------------- local function AddLink( vCrv, nTpathGrpId, nLinkType, dLinkParam, dSPOffs, dStrand, vtSlicing) - if not vCrv or #vCrv == 0 then return end - + 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 - - -- link ha senso solo se la curva corrente è chiusa (eviti extra shell aperte) - if EgtCurveIsClosed( vCrv[i]) then - + -- 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]) - if sPrevName ~= sCurrName then k = k + 1 end + local nType = EgtGetInfo( vCrv[i], KEY_TYPE, 'i') + if sPrevName ~= sCurrName or nType == TYPE.INFILL or nType == TYPE.AUX_SOLID then + k = k + 1 + end -- se nessun raccordo modifico solo lo start point della curva if nLinkType == LINK_TYPE.NONE then - local dLen = k * dSPOffs + 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])) - if dDist < dStrand + 10 then + -- local dDist = dist( EgtEP( vCrv[i-1]), EgtSP( vCrv[i])) + local dDist = EgtPointCurveDist( EgtEP( vCrv[i-1]), vCrv[i]) + if dDist < dStrand + 2 then local nLinkId if k > 1 then -- modifico lo start point @@ -111,7 +116,7 @@ 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) @@ -120,6 +125,7 @@ local function AddLink( vCrv, nTpathGrpId, nLinkType, dLinkParam, dSPOffs, dStra end end end + bPrevClosed = bCurrClosed end end @@ -179,16 +185,12 @@ local function AddLeadOut( nCrvId, LayerParams, nGrpId) end -------------------------------------------------------------------- -local function AddRetraction( nCrvId, LayerParams, dCoastingLen, dWipeLen) +local function AddRetraction( nCrvId, LayerParams, dCoastingLen, dWipeLen, dWipeDir) -- recupero i parametri per retrazione local nType = EgtGetInfo( nCrvId, KEY_TYPE, 'i') - local bClosedExtraShell = EgtGetInfo( nCrvId, KEY_CLOSED_EXTRA_SHELL, 'b') or false - local dWipeDir = EgtIf( nType == TYPE.EXTRA_SHELL, LayerParams.dShellNbrWipeDir, 0) - if nType == TYPE.EXTRA_SHELL and not bClosedExtraShell then - dWipeLen = LayerParams.dShellNbrWipe - dCoastingLen = LayerParams.dShellNbrCoasting - end + local bClosed = EgtGetInfo( nCrvId, KEY_CLOSED_CRV, 'b') or false + local bInverted = EgtGetInfo( nCrvId, KEY_INVERTED_CRV, 'b') or false -- curva ausiliaria per generare correttamente wipe local nCopyId = EgtCopyGlob( nCrvId, nCrvId, GDB_IN.AFTER) @@ -200,7 +202,7 @@ local function AddRetraction( nCrvId, LayerParams, dCoastingLen, dWipeLen) if dCoastingLen > GEO.EPS_SMALL then nCoastingId = EgtCopyGlob( nCrvId, nCrvId, GDB_IN.AFTER) local dPar = EgtCurveParamAtLength( nCoastingId, EgtCurveLength( nCoastingId) - dCoastingLen) - if not dPar then + if not dPar then EgtErase( nCoastingId) nCoastingId = nil else @@ -218,18 +220,26 @@ local function AddRetraction( nCrvId, LayerParams, dCoastingLen, dWipeLen) end if dWipeLen > GEO.EPS_SMALL then - -- se shell - local nWipeId - if nType == TYPE.OUTER_SHELL or nType == TYPE.INNER_SHELL or bClosedExtraShell then - -- se shell o extra shell chiusa + local nWipeId + if bClosed then + -- se era chiusa ( quindi analogo alle shell) nWipeId = EgtCopyGlob( nCopyId, nCoastingId or nCrvId, GDB_IN.AFTER) EgtTrimCurveEndAtLen( nWipeId, dWipeLen) + else - -- se extra shell - local bInverted = EgtGetInfo( nCrvId, KEY_INVERTED_CURVE, 'b') or false + -- se extra shell o infill a zigzag local vtDir = EgtEV( nCoastingId or nCrvId) - local dAng = dWipeDir - 90 - vtDir:rotate( LayerParams.vtSlicing, EgtIf( bInverted, - dAng, dAng)) + local dAng = dWipeDir + s_nDefaultWipeAng + -- verifico se necessario cambiare il segno all'angolo + local bChangeSign = false + if nType == TYPE.EXTRA_SHELL then + bChangeSign = bInverted + else + local vtS = EgtGetInfo( nCrvId, KEY_ZIG_ZAG_DIR, 'v') + local bSameDir = AreSameVectorApprox( vtS, vtDir) + bChangeSign = ( bInverted == bSameDir) + end + vtDir:rotate( LayerParams.vtSlicing, EgtIf( bChangeSign, - dAng, dAng)) local ptS = EgtEP( nCoastingId or nCrvId) local ptE = ptS + vtDir * dWipeLen nWipeId = EgtCurveCompoFromPoints( EgtGetParent( nCrvId), {ptS, ptE}) @@ -246,21 +256,21 @@ local function AddRetraction( nCrvId, LayerParams, dCoastingLen, dWipeLen) end -------------------------------------------------------------------- -local function AddRetractionOnLastCrv( nCrvId, nTpathGrpId, LayerParams) +local function AddRetractionOnLastCrv( nCrvId, nTpathGrpId, LayerParams, dCoastingLen, dWipeLen, dWipeDir) if LayerParams.nLeadOutType == LEAD_TYPE.NONE then - AddRetraction( nCrvId, LayerParams, LayerParams.dCoastingLen, LayerParams.dWipeLen) + AddRetraction( nCrvId, LayerParams, dCoastingLen, dWipeLen, dWipeDir) else local nLeadOutId = EgtGetLastInGroup( nTpathGrpId) local dLen = EgtCurveLength( nLeadOutId) - if dLen > LayerParams.dCoastingLen - 500 * GEO.EPS_SMALL then + if dLen > dCoastingLen - 500 * GEO.EPS_SMALL then -- coinvolge solo la curva di lead out - local dNewCoastingLen = EgtIf( abs( LayerParams.dCoastingLen - dLen) < 500 * GEO.EPS_SMALL, dLen, LayerParams.dCoastingLen) -- verifico se interamente coinvolta - AddRetraction( nLeadOutId, LayerParams, dNewCoastingLen, 0.0) + local dNewCoastingLen = EgtIf( abs( dCoastingLen - dLen) < 500 * GEO.EPS_SMALL, dLen, dCoastingLen) -- verifico se interamente coinvolta + AddRetraction( nLeadOutId, LayerParams, dNewCoastingLen, 0.0, dWipeDir) else -- coinvolge parte dell'ultima shell crv - local dNewCoastingLen = LayerParams.dCoastingLen - dLen - local nCoastingId = AddRetraction( nCrvId, LayerParams, dNewCoastingLen, 0.0) + local dNewCoastingLen = dCoastingLen - dLen + local nCoastingId = AddRetraction( nCrvId, LayerParams, dNewCoastingLen, 0.0, dWipeDir) EgtAddCurveCompoCurve( nCoastingId, nLeadOutId) end end @@ -271,6 +281,22 @@ local function VerifyRibsLink( nLinkId, nCurr, nNext, dStrand) local nGrp = EgtGetParent( nCurr) + -- verifico se il link interseca le due curve nell'altro estremo + local ptS = EgtSP( nCurr) + local ptE = EgtEP( nNext) + local dParS = EgtCurveParamAtPoint( nLinkId, ptS) + local dParE = EgtCurveParamAtPoint( nLinkId, ptE) + if dParS or dParE then + return false + end + + -- 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 + end + -- regione occupata dal link local nTotLink = EgtCopyGlob( nLinkId, nGrp) local nCopy = EgtCopyGlob( nLinkId, nGrp) @@ -280,8 +306,8 @@ local function VerifyRibsLink( nLinkId, nCurr, nNext, dStrand) if not nOffs or nOffs == GDB_ID.NULL then nOffs = nTotLink end - - -- verifico se il link interseca una delle altre costolature + + -- verifico se il link interseca una delle altre costolature local vRibsIds = EgtGetNameInGroup( nGrp, RIBS_CRV .. '*') for i = 1, #vRibsIds do if vRibsIds[i] ~= nCurr and vRibsIds[i] ~= nNext then @@ -368,8 +394,13 @@ local function CalcRibsLink( nCurr, nNext, nLoopGrp, dStrand, bForceLink) -- se non ho trovato un collegamento sul bordo, creo una linea tra ptS e ptE if bForceLink then local nLinkId = EgtCurveCompoFromPoints( EgtGetParent( nCurr), {ptS, ptE}) - EgtSetInfo( nLinkId, KEY_TYPE, TYPE.RIB) - EgtRelocateGlob( nLinkId, nCurr, GDB_IN.AFTER) + local bValid = VerifyRibsLink( nLinkId, nCurr, nNext, dStrand) + if bValid then + EgtSetInfo( nLinkId, KEY_TYPE, TYPE.RIB) + EgtRelocateGlob( nLinkId, nCurr, GDB_IN.AFTER) + else + EgtErase( nLinkId) + end end end @@ -526,7 +557,7 @@ local function AddRibsLeadOut( nCrv, nTPathGrp, nLoopsGrp, vtSlicing) -- terzo tratto ( diretto verso esterno con ugello chiuso) if dRibsLOWipe > GEO.EPS_SMALL then - local dAng = dRibsLOWipeAng - 90 + local dAng = dRibsLOWipeAng + s_nDefaultWipeAng vtE:rotate( vtSlicing, EgtIf( bInvert, - dAng, dAng)) local ptFinal = ptE + vtE * dRibsLOWipe nWipe = EgtCurveCompoFromPoints( nTPathGrp, { ptE, ptFinal}) @@ -564,17 +595,13 @@ local function CalcRibsToolPath( nCrvGrp, nTpathGrpId, LayerParams, dCorrZ) -- estraggo i contorni di tutte le superfici di offset local nLoopGrp = EgtGroup( nRibsGrp) local nSrfId = EgtGetFirstNameInGroup( nRibsGrp, TOT_SHELL_TRIM_SURF) - while nSrfId do + while nSrfId do + EgtMove( nSrfId, dCorrZ * Z_AX(), GDB_RT.GLOB) + -- mi sposto dell'altezza layer + EgtMove( nSrfId, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) local nChunksNbr = EgtSurfFrChunkCount( nSrfId) for i = 0, nChunksNbr do - local nRes, nCnt = EgtExtractSurfFrChunkLoops( nSrfId, i, nLoopGrp) - if nRes then - for j = nRes, nRes + nCnt - 1 do - EgtMove( j, dCorrZ * Z_AX(), GDB_RT.GLOB) - -- mi sposto dell'altezza layer - EgtMove( j, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) - end - end + local nRes, nCnt = EgtExtractSurfFrChunkLoops( nSrfId, i, nLoopGrp) end nSrfId = EgtGetNextName( nSrfId, TOT_SHELL_TRIM_SURF) end @@ -679,6 +706,72 @@ local function CalcRibsToolPath( nCrvGrp, nTpathGrpId, LayerParams, dCorrZ) end end +--------------------------------------------------------------------- +local function CalcAuxSolidsToolPath( nAuxSolidsGrp, nAuxSolidsPathGrp, nTpathGrpId, LayerParams, dCorrZ) + + -- recupero le curve relative al primo solido ausiliario + local sPrevName = AUX_SOLID_CRV + local nSolidId = EgtGetFirstNameInGroup( nAuxSolidsGrp, AUX_SOLIDS_CRV .. '*') + while nSolidId do + + 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 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 nPrev = EgtGetLastInGroup( nTpathGrpId) + for i = 1, #vEntIds do + local nNewEnt = EgtCopyGlob( vEntIds[i], nPrev, EgtIf( i == 1 or nOrder == PRINT_ORDER.EXT_INT_INF, GDB_IN.AFTER, GDB_IN.BEFORE)) + + -- correggo posizione + EgtMove( nNewEnt, dCorrZ * Z_AX(), GDB_RT.GLOB) + EgtMove( nNewEnt, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) + EgtModifyCurveExtrusion( nNewEnt, LayerParams.vtSlicing, GDB_RT.GLOB) + EgtSetInfo( nNewEnt, KEY_TYPE, TYPE.AUX_SOLID) + + if EgtCurveIsClosed( nNewEnt) then + EgtSetInfo( nNewEnt, KEY_CLOSED_CRV, 1) + -- eventuale inversione curva + if LayerParams.bInvert then + EgtInvertCurve( nNewEnt) + end + end + + nPrev = nNewEnt + end + + local vNewEntIds = EgtGetNameInGroup( nTpathGrpId, sName .. '*') + + -- Aggiungo link + AddLink( vNewEntIds, nTpathGrpId, nLinkType, dLinkParam, dSPOffset, LayerParams.dStrand, LayerParams.vtSlicing) + + -- Coasting e wipe + for i = 1, #vNewEntIds do + local nNextId = EgtGetNext( vNewEntIds[i]) or GDB_ID.NULL + local nType = EgtGetInfo( nNextId, KEY_TYPE, 'i') + if nType ~= TYPE.LINK then + AddRetraction( vNewEntIds[i], LayerParams, dCoastingLen, dWipeLen, dWipeDir) + end + end + end + end + sPrevName = sName + nSolidId = EgtGetNextName( nSolidId, AUX_SOLIDS_CRV .. '*') + end +end + --------------------------------------------------------------------- function CalcToolPath.Exec( nPartId) @@ -718,6 +811,8 @@ function CalcToolPath.Exec( nPartId) -- Ciclo sui layer for nIdx = 1, #vLayIds do + -- recupero eventuale gruppo di solidi ausiliari + nAuxSolidsGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], AUX_SOLIDS_GRP) -- scorro tutti i gruppi di contorni local nCrvGrpId = EgtGetFirstNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*") while nCrvGrpId do @@ -748,23 +843,27 @@ function CalcToolPath.Exec( nPartId) EgtMove( nNewEntId, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) -- eventuale inversione local nType = EgtGetInfo( nNewEntId, KEY_TYPE, 'i') - if nType ~= TYPE.EXTRA_SHELL and LayerParams.bInvert then - EgtInvertCurve( nNewEntId) + if LayerParams.bInvert then + if nType == TYPE.OUTER_SHELL or nType == TYPE.INNER_SHELL or ( nType == TYPE.INFILL and EgtCurveIsClosed( nNewEntId)) then + EgtInvertCurve( nNewEntId) + EgtSetInfo( nNewEntId, KEY_INVERTED_CRV, 1) + end end + + if EgtCurveIsClosed( nNewEntId) then + EgtSetInfo( nNewEntId, KEY_CLOSED_CRV, 1) + end + EgtModifyCurveExtrusion( nNewEntId, LayerParams.vtSlicing, GDB_RT.GLOB) EgtSetColor( nNewEntId, EgtStdColor('GRAY')) nEntId = EgtGetNext( nEntId) end -- aggiungo gli opportuni raccordi sulle shell complete - local vIds = EgtGetNameInGroup( nTpathGrpId, SHELL_CRV .. '*') - local vIdsExtra = EgtGetNameInGroup( nTpathGrpId, EXTRA_SHELL_CRV .. '*') or {} - for i = 1, #vIdsExtra do - table.insert( vIds, vIdsExtra[i]) - end + local vIds = EgtGetAllInGroup( nTpathGrpId) AddLink( vIds, nTpathGrpId, LayerParams.nLinkType, LayerParams.dLinkParam, LayerParams.dSPOffs, LayerParams.dStrand, LayerParams.vtSlicing) - -- aggiungo gli opportuni raccondi sulle shell con numero diverso di passate + -- aggiungo gli opportuni raccordi sulle shell con numero diverso di passate local nPrev = EgtGetFirstNameInGroup( nTpathGrpId, EXTRA_SHELL_CRV .. '*') local sPrevName = EgtGetName( nPrev or GDB_ID.NULL) local nCurr = EgtGetNextName( nPrev or GDB_ID.NULL, EXTRA_SHELL_CRV .. '*') @@ -795,27 +894,40 @@ function CalcToolPath.Exec( nPartId) end -- aggiungo coasting/wipe - local nId = EgtGetFirstNameInGroup( nTpathGrpId, SHELL_CRV .. "*") + local nId = EgtGetFirstInGroup( nTpathGrpId) + if EgtGetName( nId or GDB_ID.NULL) == LEAD_IN_CRV then nId = EgtGetNext( nId) end local nFirstId = nId - local nLastId = EgtGetLastNameInGroup( nTpathGrpId, EXTRA_SHELL_CRV .. "*") or EgtGetLastNameInGroup( nTpathGrpId, SHELL_CRV .. "*") + local nLastId = EgtGetLastInGroup( nTpathGrpId) + if EgtGetName( nLastId or GDB_ID.NULL) == LEAD_OUT_CRV then nLastId = EgtGetPrev( nLastId) end while nId do + -- recupero i parametri + local nType = EgtGetInfo( nId, KEY_TYPE, 'i') + local bClosed = EgtGetInfo( nId, KEY_CLOSED_CRV, 'b') or false + local dCoastingLen = EgtIf( nType == TYPE.EXTRA_SHELL and not bClosed, LayerParams.dShellNbrCoasting, LayerParams.dCoastingLen) + local dWipeLen = EgtIf( nType == TYPE.EXTRA_SHELL and not bClosed, LayerParams.dShellNbrWipe, LayerParams.dWipeLen) + local dWipeDir = EgtIf( nType == TYPE.EXTRA_SHELL and not bClosed, LayerParams.dShellNbrWipeDir, 0) + if nId == nLastId then - AddRetractionOnLastCrv( nId, nTpathGrpId, LayerParams) + AddRetractionOnLastCrv( nId, nTpathGrpId, LayerParams, dCoastingLen, dWipeLen, dWipeDir) else local nNextId = EgtGetNext( nId) if EgtGetInfo( nNextId, KEY_TYPE, 'i') ~= TYPE.LINK then -- aggiungo retrazione if nId == nFirstId then - local dWipeLen = EgtIf( LayerParams.nLeadInType == LEAD_TYPE.NONE, LayerParams.dWipeLen, 0) - AddRetraction( nId, LayerParams, LayerParams.dCoastingLen, dWipeLen) + AddRetraction( nId, LayerParams, dCoastingLen, EgtIf( LayerParams.nLeadInType == LEAD_TYPE.NONE, dWipeLen, 0), dWipeDir) else - AddRetraction( nId, LayerParams, LayerParams.dCoastingLen, LayerParams.dWipeLen) + AddRetraction( nId, LayerParams, dCoastingLen, dWipeLen, dWipeDir) end end end - nId = EgtGetNextName( nId, SHELL_CRV .. "*") or EgtGetNextName( nId, EXTRA_SHELL_CRV .. "*") + nId = EgtGetNextName( nId, SHELL_CRV .. "*") or EgtGetNextName( nId, EXTRA_SHELL_CRV .. "*") or EgtGetNextName( nId, INFILL_CRV .. '') end + -- sistemo i solid ausiliari + local nAuxSolidsPathGrp = EgtGetFirstNameInGroup( nCrvGrpId, AUX_SOLIDS_GRP) + if nAuxSolidsGrp then + CalcAuxSolidsToolPath( nAuxSolidsGrp, nAuxSolidsPathGrp, nTpathGrpId, LayerParams, dCorrZ) + end -- sistemo le costolature local nRibsGrp = EgtGetFirstNameInGroup( nCrvGrpId, RIBS_GRP) if nRibsGrp then @@ -825,6 +937,11 @@ function CalcToolPath.Exec( nPartId) --passo al gruppo di contorni successivo nCrvGrpId = EgtGetNextName( nCrvGrpId, CONTOUR_GRP.."*") end + + if EgtProcessEvents( EgtIf( PRINT, 200, 0) + nIdx / #vLayIds * 100, 0) == 1 then + EgtDraw() + return + end end end diff --git a/LuaLibs/RunSliceAdvancement.lua b/LuaLibs/RunSliceAdvancement.lua index 4ed9479..89b52d0 100644 --- a/LuaLibs/RunSliceAdvancement.lua +++ b/LuaLibs/RunSliceAdvancement.lua @@ -133,13 +133,19 @@ function RunSliceAdvancement.Exec() nSegmentQty = #ShellList[1] SegmentList = ShellList[1] ToHideList = ShellList[2] + for i = 1, #ShellList[3] do + ToHideList[#ToHideList + 1] = ShellList[3][i] + end elseif nAdvancementType == SLICE_ADV_TYPE.INNER then nSegmentQty = #ShellList[2] SegmentList = ShellList[2] ToHideList = ShellList[1] + for i = 1, #ShellList[3] do + ToHideList[#ToHideList + 1] = ShellList[3][i] + end elseif nAdvancementType == SLICE_ADV_TYPE.INFILL then - nSegmentQty = 1 - SegmentList = {} + nSegmentQty = #ShellList[3] + SegmentList = ShellList[3] ToHideList = ShellList[1] for i = 1, #ShellList[2] do ToHideList[#ToHideList + 1] = ShellList[2][i] diff --git a/LuaLibs/RunSlicePalette.lua b/LuaLibs/RunSlicePalette.lua index 6cb02a2..d088bea 100644 --- a/LuaLibs/RunSlicePalette.lua +++ b/LuaLibs/RunSlicePalette.lua @@ -31,10 +31,10 @@ function RunSlicePalette.UpdateColors( nPaletteType) local Color = EgtStdColor( 'GRAY') if nPaletteType == PALETTE_TYPE.IN_OUT then local nType = EgtGetInfo( nSurfId, KEY_TYPE, 'i') - if not nType or nType < TYPE.OUTER_SHELL or nType > TYPE.RIB then nType = nOldType end + if not nType or nType < TYPE.OUTER_SHELL or nType > TYPE.AUX_SOLID then nType = nOldType end nOldType = nType -- scelta del colore - if nType == TYPE.OUTER_SHELL then + if nType == TYPE.OUTER_SHELL then Color = EgtStdColor( 'TEAL') elseif nType == TYPE.INNER_SHELL or nType == TYPE.EXTRA_SHELL then Color = EgtStdColor( 'ORANGE') diff --git a/LuaLibs/RunSlicing.lua b/LuaLibs/RunSlicing.lua index 7dfe3f7..a123abe 100644 --- a/LuaLibs/RunSlicing.lua +++ b/LuaLibs/RunSlicing.lua @@ -68,7 +68,22 @@ local function LoadParams( sFile, nPartId) SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_SP_OFFSET_ON_SLICE, '0.0') SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_LINK_PARAM, '0') SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_LINK_ZUP, '0') + SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_FLOOR_NBR, '0') + local sFloorInfill = EgtGetStringFromIni( SEC_DEFAULT, KEY_FLOOR_TYPE, 'Offset', sFile) + if sFloorInfill == 'ZigZag' then + EgtSetInfo( nPartId, KEY_FLOOR_TYPE, INFILL_TYPE.ZIGZAG) + else + EgtSetInfo( nPartId, KEY_FLOOR_TYPE, INFILL_TYPE.OFFSET) + end + SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_CEIL_NBR, '0') + local sCeilInfill = EgtGetStringFromIni( SEC_DEFAULT, KEY_CEIL_TYPE, 'Offset', sFile) + if sCeilInfill == 'ZigZag' then + EgtSetInfo( nPartId, KEY_CEIL_TYPE, INFILL_TYPE.ZIGZAG) + else + EgtSetInfo( nPartId, KEY_CEIL_TYPE, INFILL_TYPE.OFFSET) + end + SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_SPEED, '0.0') SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_FEED, '0.0') SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_EXT_FEED, '0.0') @@ -128,6 +143,39 @@ local function LoadParams( sFile, nPartId) SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_SHELL_NBR_WIPE, '0.0') SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_SHELL_NBR_WIPE_DIR, '0.0') + -- parametri per solidi ausiliari + SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_AUX_SOLIDS_OVERLAP, '0') + + local sAuxSolidsInfill = EgtGetStringFromIni( SEC_DEFAULT, KEY_AUX_SOLIDS_INFILL, 'None', sFile) + if sAuxSolidsInfill == 'ZigZag' then + EgtSetInfo( nPartId, KEY_AUX_SOLIDS_INFILL, INFILL_TYPE.ZIGZAG) + elseif sAuxSolidsInfill == 'Offset' then + EgtSetInfo( nPartId, KEY_AUX_SOLIDS_INFILL, INFILL_TYPE.OFFSET) + else + EgtSetInfo( nPartId, KEY_AUX_SOLIDS_INFILL, INFILL_TYPE.NONE) + end + + local sAuxSolidsStrandOrder = EgtGetStringFromIni( SEC_DEFAULT, KEY_AUX_SOLIDS_PRINT_ORDER, 'InToOut', sFile) + if sAuxSolidsStrandOrder == 'OutToIn' then + EgtSetInfo( nPartId, KEY_AUX_SOLIDS_PRINT_ORDER, PRINT_ORDER.EXT_INT_INF) + else -- 'InToOut' + EgtSetInfo( nPartId, KEY_AUX_SOLIDS_PRINT_ORDER, PRINT_ORDER.INF_INT_EXT) + end + + local sAuxSolidsLinkType = EgtGetStringFromIni( SEC_DEFAULT, KEY_AUX_SOLIDS_LINK_TYPE, 'None', sFile) + if sAuxSolidsLinkType == 'None' then + EgtSetInfo( nPartId, KEY_AUX_SOLIDS_LINK_TYPE, LINK_TYPE.NONE) + elseif sAuxSolidsLinkType == 'BiArc' then + EgtSetInfo( nPartId, KEY_AUX_SOLIDS_LINK_TYPE, LINK_TYPE.BIARC) + else -- 'Linear' + EgtSetInfo( nPartId, KEY_AUX_SOLIDS_LINK_TYPE, LINK_TYPE.LINEAR) + end + + SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_AUX_SOLIDS_LINK_PARAM, '0.0') + SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_AUX_SOLIDS_SP_OFFSET, '0.0') + SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_AUX_SOLIDS_COASTING_LEN, '0.0') + SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_AUX_SOLIDS_WIPE_LEN, '0.0') + SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_AUX_SOLIDS_WIPE_DIR, '0.0') end --------------------------------------------------------------------- @@ -206,6 +254,7 @@ function RunSlicing.Exec() end local nRibsLayId = EgtGetFirstNameInGroup( nPartId, LAY_RIBS) local nShellNbrLay = EgtGetFirstNameInGroup( nPartId, LAY_SHELL_NBR) + local nAuxSolidsLay = EgtGetFirstNameInGroup( nPartId, LAY_AUX_SOLIDS) local nStartLayId = EgtGetFirstNameInGroup( nPartId, LAY_MACH_START) local sParamFile @@ -265,6 +314,7 @@ function RunSlicing.Exec() EgtSetStatus( nSolidLayId, GDB_ST.OFF) EgtSetStatus( nRibsLayId or GDB_ID.NULL, GDB_ST.OFF) EgtSetStatus( nShellNbrLay or GDB_ID.NULL, GDB_ST.OFF) + EgtSetStatus( nAuxSolidsLay or GDB_ID.NULL, GDB_ST.OFF) EgtSetStatus( nStartLayId or GDB_ID.NULL, GDB_ST.OFF) EgtDraw()