From ee59b4ac743d8b6109cb54e53a1982b7b401bcde Mon Sep 17 00:00:00 2001 From: SaraP Date: Tue, 31 Jan 2023 15:35:08 +0100 Subject: [PATCH] 3dPrinting : - modifiche nei setti per conservare i link disegnati dall'utente ( prima versione) - aggiunti ingressi/uscite per setti che non iniziano/terminano su shell. --- LuaLibs/AddManData.lua | 22 +- LuaLibs/CalcPaths.lua | 870 +++++++++++++++++++++++++++------------ LuaLibs/CalcSlices.lua | 4 +- LuaLibs/CalcToolPath.lua | 139 +++---- LuaLibs/RunSlicing.lua | 2 +- 5 files changed, 675 insertions(+), 362 deletions(-) diff --git a/LuaLibs/AddManData.lua b/LuaLibs/AddManData.lua index c52b758..20e2e12 100644 --- a/LuaLibs/AddManData.lua +++ b/LuaLibs/AddManData.lua @@ -28,6 +28,8 @@ LINK_CRV = "Link" FRAME_PART = "FramePart" START_GEOM = "Start" TOT_SHELL_TRIM_SURF = "TotalShellSurfForTrim" +TRIM_SURF_LOOP = "TrimSurfLoop" +SURF_LOOP = "SurfLoop" MIN_LEN = 0.1 MIN_AREA = 0.01 @@ -88,7 +90,6 @@ KEY_RIBS_SHELLS_NBR = "RibsStrandCount" KEY_RIBS_LINK = "RibsLink" KEY_RIBS_INVERT_DIR = "RibsInvertDirection" KEY_RIBS_INVERT_ORDER = "RibsInvertOrder" -KEY_RIBS_DO_LINK_FIRST = "RibsDoLinkFirst" KEY_RIBS_LEAD_IN_INVERT = "RibsLeadInInvert" KEY_RIBS_LEAD_IN_LEN = "RibsLeadInLen" KEY_RIBS_LEAD_OUT_INVERT = "RibsLeadOutInvert" @@ -96,11 +97,22 @@ KEY_RIBS_LEAD_OUT_LEN = "RibsLeadOutLen" 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" KEY_RIBS_PRINT_ORDER = "RibsPrintOrder" +KEY_RIBS_INTERS = "RibsHaveIntersections" +KEY_RIBS_SPECIAL_CASE = "RibsSpecialCase" +KEY_SPLIT_ORDER = "SplitOrder" +KEY_SPLIT_AFTER_TRIM = "RibsSplitAfterTrim" +KEY_SPLIT_AFTER_TRIM_ORDER = "RibsSplitAfterTrimOrder" +KEY_SPLIT_AFTER_TRIM_TOT = "RibsSplitAfterTrimTot" +KEY_SPLIT_ID = "SplitId" +KEY_START_RIB = "StartRib" +KEY_ORIGINAL_RIB = "OriginalRib" +KEY_ORIGINAL_RIB_CLOSED = "OriginalRibClosed" +KEY_RIBS_USER_LINK = "RibWithUserLink" +KEY_RIBS_USER_LINK_CCW = "RibUserLinkCCW" +KEY_RIBS_USER_LINK_ORDER = "RibUserLinkOrder" +KEY_RIBS_USER_LINK_TOT = "RibsUserLinkParts" +KEY_RIBS_INVERT_STRAND_ORDER = "RibsInvertStrandOrder" -- Regioni con diverso numero di passate KEY_SHELL_NBR_DIFF = "ShellNbrDifference" diff --git a/LuaLibs/CalcPaths.lua b/LuaLibs/CalcPaths.lua index 1277a93..e62a1df 100644 --- a/LuaLibs/CalcPaths.lua +++ b/LuaLibs/CalcPaths.lua @@ -32,7 +32,6 @@ local function GetLayerParamsForPathCalc() LayerParams.bPrintInvert = ( EgtGetInfo( s_nPartId, KEY_PRINT_DIRECTION, 'i') == PRINT_DIRECTION.CW) -- parametri costolature LayerParams.bRibsInvertOrder = EgtGetInfo( s_nPartId, KEY_RIBS_INVERT_ORDER, 'b') - LayerParams.bRibsDoLinkFirst = EgtGetInfo( s_nPartId, KEY_RIBS_DO_LINK_FIRST, 'b') or false LayerParams.vRibsPrintOrder = EgtGetInfo( s_nPartId, KEY_RIBS_PRINT_ORDER, 'vi') or {3, 1, 4, 2} -- parametri regioni con diverse passate LayerParams.dShellNbrCoasting = EgtGetInfo( s_nPartId, KEY_SHELL_NBR_COASTING, 'd') @@ -55,6 +54,12 @@ local function CopyInfo( nSouId, nDestId, sInfo, sType) EgtSetInfo( nDestId, sInfo, info) end +-------------------------------------------------------------------------------------------- +local function UpdateInvertInfo( nId) + local bInvert = EgtGetInfo( nId, KEY_INVERTED_CRV, 'b') or false + EgtSetInfo( nId, KEY_INVERTED_CRV, not bInvert) +end + ---------------------------------------------------------------------- local function ComputeSurfOffset( nSrf, nGrpId, dOffs, vtSlicing) -- gruppo temporaneo locale @@ -341,7 +346,7 @@ local function ComputeOffsetInfill( nSrf, dStrand, vtSlicing, sName, nType, vPtS local vNewIds = GetPathsFromSurf( nSrfOffs, sName, nType, nGrp, vPtStart) if vNewIds then -- riordino - ReorderPath( vOldIds, vNewIds) + ReorderPath( vOldIds, vNewIds) -- verifico fattibilità local k = 1 while k <= #vNewIds do @@ -432,8 +437,223 @@ local function ComputeZigZagInfill( nSrf, dStrand, vtSlicing, sName, nType, vPtS end -------------------------------------------------------------------- +-------------------------------------------------------------------- --------------------------- RIBS ----------------------------------- +-------------------------------------------------------------------- +local function VerifyRibsHoles( vIds, dStrand) + + local sPrevName = EgtGetName( vIds[1]) + local i = 2 + while i <= #vIds do + + local bAdd = false + local sCurrName = EgtGetName( vIds[i]) + -- se derivano dallo stesso setto verifico se possono essere uniti + if sCurrName == sPrevName then + if dist( EgtEP( vIds[i-1]), EgtSP( vIds[i])) < dStrand + 10 * GEO.EPS_SMALL then + bAdd = true + -- unisco il secondo tratto al primo + EgtAddCurveCompoLine( vIds[i-1], EgtSP( vIds[i])) + EgtAddCurveCompoCurve( vIds[i-1], vIds[i]) + table.remove( vIds, i) -- rimuovo il setto dalla tabella + elseif dist( EgtSP( vIds[i-1]), EgtEP( vIds[i])) < dStrand + 10 * GEO.EPS_SMALL then + bAdd = true + -- unisco il primo tratto al secondo + EgtAddCurveCompoLine( vIds[i], EgtSP( vIds[i-1])) + EgtAddCurveCompoCurve( vIds[i], vIds[i-1]) + table.remove( vIds, i-1) -- rimuovo il setto dalla tabella + end + end + -- aggiorno per iterazione successiva + sPrevName = sCurrName + if not bAdd then + i = i + 1 + end + end +end + +-------------------------------------------------------------------- +local function CheckRibUserLink( nCrv, nCnt, vtSlicing) + + -- se dal trim non ho ottenuto almeno due tratti, non si tratta di UserLink + if nCnt < 2 then return end + + -- stabilisco l'orientamento del link + local bCCW = false + -- costruisco la superficie "definita" dal setto + local nGrpTmp = EgtGroup( EgtGetParent( nCrv)) + local nSrfLoop = EgtCurveCompoFromPoints( nGrpTmp, {EgtEP( nCrv), EgtSP( nCrv + 1)}) + EgtAddCurveCompoLine( nSrfLoop, EgtSP( nCrv + 1) + 100 * EgtSV( nCrv + 1)) + EgtAddCurveCompoLine( nSrfLoop, EgtEP( nCrv) - 100 * EgtEV( nCrv)) + EgtCloseCurveCompo( nSrfLoop) + + local nSurf = EgtSurfFlatRegion( nGrpTmp, {nSrfLoop}) + if not nSurf then return end + -- verifico direzione della normale + local vtN = EgtSurfFrNormVersor( nSurf, GDB_ID.ROOT) + if AreSameVectorApprox( vtN, vtSlicing) then + bCCW = true + end + + -- setto le info + for i = 0, nCnt - 1 do + EgtSetInfo( nCrv + i, KEY_RIBS_USER_LINK, 1) + EgtSetInfo( nCrv + i, KEY_RIBS_USER_LINK_CCW, bCCW) + EgtSetInfo( nCrv + i, KEY_RIBS_USER_LINK_ORDER, i) + EgtSetInfo( nCrv + i, KEY_RIBS_USER_LINK_TOT, nCnt) + end + + EgtErase( nGrpTmp) + +end + +------------------------------------------------------------------- +local function TrimRibs( vRibs, nRibsGrp, nSrf, dSrfOffs, vtSlicing) + + -- costruisco le superfici con cui fare il trim grossolano dei setti + EgtCopyGlob( nSrf, nRibsGrp) + local nSrfInt = EgtCopyGlob( nSrf, nRibsGrp) + local nSrfExt = EgtCopyGlob( nSrf, nRibsGrp) + EgtSurfFrOffset( nSrfInt, dSrfOffs) + EgtSurfFrOffset( nSrfExt, - dSrfOffs) + + -- trim dei setti + local nTrimmedRibsGrp = EgtGroup( nRibsGrp) + for i = 1, #vRibs do + local nCopyRib = EgtCopyGlob( vRibs[i], nTrimmedRibsGrp) + local nType = EgtGetInfo( vRibs[i], KEY_RIBS_TYPE, 'i') + if EgtCurveIsClosed( vRibs[i]) then + EgtSetInfo( nCopyRib, KEY_ORIGINAL_RIB_CLOSED, 1) + end + + local nCrv = nCopyRib + local nCnt = 1 + if nType == RIB_TYPE.INTERNAL or nType == RIB_TYPE.SUPPORT then + nCrv, nCnt = EgtTrimCurveWithRegion( nCopyRib, nSrfInt, true, true) + elseif nType == RIB_TYPE.EXTERNAL then + nCrv, nCnt = EgtTrimCurveWithRegion( nCopyRib, nSrfExt, false, true) + end + + -- se errore nel calcolare trim riprendo il setto originario + if not nCrv then + nCrv = nCopyRib + nCnt = 1 + end + + for nId = nCrv, nCrv + nCnt - 1 do + EgtSetInfo( nId, KEY_START_RIB, vRibs[i]) + end + -- verifico se link definito dall'utente e ne analizzo le proprietà + CheckRibUserLink( nCrv, nCnt, vtSlicing) + + end + + return nTrimmedRibsGrp +end + +-------------------------------------------------------------------- +local function ComputeRibsOrientedOffset( nRibsGrp, dStrand) + + local nOffsGrp = EgtGroup( EgtGetParent( nRibsGrp)) + + local nCurrRib = EgtGetFirstNameInGroup( nRibsGrp, RIBS_CRV .. '*') + while nCurrRib do + + -- recupero tutti i tratti appartenenti a quel setto (hanno lo stesso nome) + local sName = EgtGetName( nCurrRib) + local vIds = EgtGetNameInGroup( nRibsGrp, sName) + + -- recupero i parametri del setto + local bInvert = EgtGetInfo( nCurrRib, KEY_RIBS_INVERT_DIR, 'b') or false + local bInvertOrder = EgtGetInfo( nCurrRib, KEY_RIBS_INVERT_STRAND_ORDER, 'b') or false + + local nShellsNbr = EgtGetInfo( nCurrRib, KEY_RIBS_SHELLS_NBR, 'i') + local dOffs = ( nShellsNbr - 1) * dStrand / 2 + + -- offset di ogni tratto del setto + local vOffs = {} + local bPlusToMinus = false + for i = 1, #vIds do + + local bUserLinked = EgtGetInfo( vIds[i], KEY_RIBS_USER_LINK, 'b') or false + local bCCW = EgtGetInfo( vIds[i], KEY_RIBS_USER_LINK_CCW, 'b') or false + local nLinkOrder = EgtGetInfo( vIds[i], KEY_RIBS_USER_LINK_ORDER, 'i') or 0 + + -- ordine di realizzazione degli offset + if not bUserLinked then + bPlusToMinus = false + else + if nLinkOrder == 0 then + -- determinato dal verso del collegamento + bPlusToMinus = EgtIf( bCCW, true, false) + else + bPlusToMinus = not bPlusToMinus + end + end + + for k = 0, nShellsNbr - 1 do + local nNewId + if bPlusToMinus then + nNewId = EgtOffsetCurveAdv( vIds[i], dOffs - k * dStrand) + else + nNewId = EgtOffsetCurveAdv( vIds[i], - dOffs + k * dStrand) + end + EgtSetName( nNewId, sName) + EgtSetInfo( nNewId, KEY_TYPE, TYPE.RIB) + EgtSetInfo( nNewId, KEY_ORIGINAL_RIB, vIds[i]) + EgtRelocateGlob( nNewId, nOffsGrp) + table.insert( vOffs, nNewId) + end + end + + -- ordinamento + if bInvertOrder then + for i = 1, #vOffs - 1 do + EgtRelocateGlob( vOffs[i], vOffs[#vOffs], GDB_IN.AFTER) + end + -- aggiorno il vettore con gli indici per rispettare nuovo ordinamento + vOffs = EgtGetNameInGroup( nOffsGrp, sName) + end + + -- orientamento + local bInvertCrv = bInvert + for j = 1, #vOffs, nShellsNbr do + + -- stabilisco orientamento del primo tratto del gruppo + local bUserLinked = EgtGetInfo( vOffs[j], KEY_RIBS_USER_LINK, 'b') or false + local nLinkOrder = EgtGetInfo( vOffs[j], KEY_RIBS_USER_LINK_ORDER, 'i') or 0 + local nLinkTot = EgtGetInfo( vOffs[j], KEY_RIBS_USER_LINK_TOT, 'i') or 0 + if not bUserLinked then + bInvertCrv = bInvert + else + if ( not bInvertOrder and nLinkOrder == 0) or ( bInvertOrder and nLinkOrder == nLinkTot - 1) then + bInvertCrv = bInvert + if ( nShellsNbr % 2 == 0 and not bInvertOrder) or ( nShellsNbr % 2 ~= 0 and bInvertOrder) then + bInvertCrv = not bInvert + end + else + if nShellsNbr % 2 == 0 then + bInvertCrv = not bInvertCrv + end + end + end + + -- inversione + for k = 0, nShellsNbr - 1 do + if ( bInvertCrv and k % 2 == 0) or ( not bInvertCrv and k % 2 ~= 0) then + EgtInvertCurve( vOffs[j + k]) + UpdateInvertInfo( vOffs[j + k]) + end + end + end + + -- passo al setto successivo + nCurrRib = EgtGetNextName( vIds[#vIds], RIBS_CRV .. '*') + end + + return nOffsGrp +end + -------------------------------------------------------------------- local function ComputeTrimSurfWithOverlapsForRibs( vIds, nSrfBase, nSrfExt, dOffs, dStrand, nGrp, vtSlicing) @@ -470,7 +690,7 @@ local function ComputeTrimSurfWithOverlapsForRibs( vIds, nSrfBase, nSrfExt, dOff end -------------------------------------------------------------------- -local function VerifyRibsIntersection( nRib1, nRib2, nType1, nType2, nSrf1, nSrf2, dWidth, nGrp, nOffsGrp) +local function VerifyRibsIntersection( nRib1, nRib2, nType1, nType2, nSrf1, nSrf2, dStrand, nGrp, nOffsGrp) -- setti interni/supporto ed esterni non si possono intersecare per definizione if ( ( nType1 == RIB_TYPE.INTERNAL or nType1 == RIB_TYPE.SUPPORT) and nType2 == RIB_TYPE.EXTERNAL) or @@ -483,58 +703,84 @@ local function VerifyRibsIntersection( nRib1, nRib2, nType1, nType2, nSrf1, nSrf end local bInters = false - local ptInt + local bForceCrv1Cut = false -- porto le curve nel gruppo locale local nCrv1 = EgtCopyGlob( nRib1, nGrp) local nCrv2 = EgtCopyGlob( nRib2, nGrp) - -- verifico se si intersecano - ptInt = EgtIP( nCrv1, nCrv2, ORIG(), GDB_ID.ROOT) + -- verifico se si intersecano nel piano XY definito dal gruppo locale + local nId, nCnt = EgtCurveCurveInters( nCrv1, nCrv2, nGrp) - -- se non si intersecano, verifico se si intersecano i loro offset - local bFound = false - if not ptInt then - local vOffs1 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv1)) - local vOffs2 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv2)) + -- se si intersecano verifico se ho intersezioni valide + if nId then + + -- scorro tutte le intersezioni trovate + for i = 0, nCnt - 1 do + local nPtId = nId + i + if EgtGetType( nPtId) ~= GDB_TY.GEO_POINT then + -- se è tratto sovrapposto warining + EgtOutLog( 'Warning : ribs overlapping - CalcPaths') + else + -- verifico se valida + if nType1 == RIB_TYPE.UNBOUNDED and nType2 == RIB_TYPE.UNBOUNDED then + -- nel caso unbounded l'intersezione può essere ovunque + bInters = true + elseif nType1 == RIB_TYPE.EXTERNAL or nType2 == RIB_TYPE.EXTERNAL then + -- l'intersezione deve essere esterna + if nSrf2 and EgtSurfFrTestExternal( nSrf2, nPtId) then bInters = true end + else + -- se uno dei due è interno o supporto l'intersezione deve essere interna + if nSrf1 and not EgtSurfFrTestExternal( nSrf1, nPtId) then bInters = true end + end + + -- se valida verifico se forza il taglio sulla curva 1 + if bInters then + local ptInt = EgtSP( nPtId, GDB_ID.ROOT) + local dPar1 = EgtCurveParamAtPoint( nCrv1, ptInt, GEO.EPS_SMALL, GDB_RT.GLOB) + local dPar2 = EgtCurveParamAtPoint( nCrv2, ptInt, GEO.EPS_SMALL, GDB_RT.GLOB) + local _, dParE1 = EgtCurveDomain( nCrv1) + local _, dParE2 = EgtCurveDomain( nCrv2) + + local bCrv1OnExtr = ( dPar1 < 10 * GEO.EPS_SMALL or abs( dPar1 - dParE1) < 10 * GEO.EPS_SMALL) + local bCrv2OnExtr = ( dPar2 < 10 * GEO.EPS_SMALL or abs( dPar2 - dParE2) < 10 * GEO.EPS_SMALL) + bForceCrv1Cut = ( bCrv1OnExtr and not bCrv2OnExtr) + + if bForceCrv1Cut then + return bInters, bForceCrv1Cut -- true, true + end + end + end + end + + return bInters, bForceCrv1Cut -- true/false, false + + else + -- se non si intersecano, verifico se si intersecano i loro offset + local vOffs1 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv1)) or {} + local vOffs2 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv2)) or {} for i = 1, #vOffs1 do - local nSrfOffs1 = EgtSurfFrFatCurve( nGrp, vOffs1[i], dWidth, false) + local nSrfOffs1 = EgtSurfFrFatCurve( nGrp, vOffs1[i], 0.5 * dStrand, false) if nSrfOffs1 then for j = 1, #vOffs2 do -- verifico se intersezione local nRes = EgtCurveWithRegionClassify( vOffs2[j], nSrfOffs1) if nRes == GDB_CRC.IN or nRes == GDB_CRC.INTERS then - bFound = true + bInters = true break end end - if bFound then break end + if bInters then break end end end - end - -- se intersezione verifico se valida - if ptInt then - local nPtId = EgtPoint( nGrp, ptInt, GDB_RT.GLOB) - if nType1 == RIB_TYPE.UNBOUNDED and nType2 == RIB_TYPE.UNBOUNDED then - -- nel caso unbounded l'intersezione può essere ovunque - bInters = true - elseif nType1 == RIB_TYPE.EXTERNAL or nType2 == RIB_TYPE.EXTERNAL then - -- l'intersezione deve essere esterna - if nSrf2 and EgtSurfFrTestExternal( nSrf2, nPtId) then bInters = true end - else - -- se uno dei due è interno o supporto l'intersezione deve essere interna - if nSrf1 and not EgtSurfFrTestExternal( nSrf1, nPtId) then bInters = true end - end - else - bInters = bFound + return bInters, bForceCrv1Cut -- true, false end - return bInters, ptInt end --------------------------------------------------------------------------------- -- Funzione che sistema le intersezioni fra costolature nel caso generico -local function AdjustRibsOffsetForIntersection( nCrv1, nCrv2, LayerParams, nOffsGrp) +local function AdjustRibsOffsetForIntersection( nCrv1, nCrv2, LayerParams, nOffsGrp, bSaveSurf, nLoopGrp) -- calcolo la superficie della curva principale ( nCrv1) da usare per trim local nShells = EgtGetInfo( nCrv1, KEY_RIBS_SHELLS_NBR, 'i') @@ -562,13 +808,28 @@ local function AdjustRibsOffsetForIntersection( nCrv1, nCrv2, LayerParams, nOffs -- aggiorno ordine di split copiandolo da nCrv2 CopyInfo( nCrv2, vOffs2[i], KEY_SPLIT_ORDER, 'i') for j = nId + nCnt - 1, nId + 1, -1 do - EgtSetInfo( j, KEY_SPLIT_RIB, vOffs2[i]) -- curva da cui deriva CopyInfo( nCrv2, j, KEY_SPLIT_ORDER, 'i') -- ordine di split - EgtRelocateGlob( j, nOffsGrp, GDB_IN.LAST_SON) + EgtRelocateGlob( j, j - 1, GDB_IN.AFTER) end - end - EgtErase( nSrf) + end + -- se necessario salvo i loop da usare per ingressi e uscite + if bSaveSurf then + -- verifico orientamento della superficie per compatibilità ingressi ribs splittati + local vtN = EgtSurfFrNormVersor( nSrf) + if AreSameVectorApprox( vtN, LayerParams.vtSlicing) then + EgtInvertSurf( nSrf) + end + local nChunks = EgtSurfFrChunkCount( nSrf) + for i = 0, nChunks - 1 do + local nRes, nCnt = EgtExtractSurfFrChunkLoops( nSrf, i, nLoopGrp) + for j = nRes, nRes + nCnt - 1 do + EgtSetName( j, SURF_LOOP) + end + end + end + + EgtErase( nSrf) end -------------------------------------------------------------------- @@ -628,9 +889,10 @@ local function UpdateSplitOrder( nCrv, tInters, nOffsGrp) end end --------------------------------------------------------------------- -local function HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPathGrp, bAllTwoStrands, vTypeSequence) +--------------------------------------------------------------------------------- +local function HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPathGrp, nLoopGrp, bAllTwoStrands, vTypeSequence) + local bSpecialCase = false local vRibsIds = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*') -- copio gli offset delle costolature nel RibsPathGrp local nCrvGrp = EgtGetParent( nRibsPathGrp) @@ -639,7 +901,7 @@ local function HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPa EgtCopyGlob( vOffsRib[i], nRibsPathGrp) end - -- creo un gruppo con frame locale per calcolare le intersezioni + -- creo un gruppo con frame locale per calcolare le intersezioni ( è il piano XY locale dove calcolare intersezioni) local frLoc = Frame3d( ORIG(), LayerParams.vtSlicing) local nGrpTmp = EgtGroup( nRibsGrp, frLoc, GDB_RT.GLOB) @@ -671,25 +933,16 @@ local function HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPa for j = i + 1, #vRibsIds do local nType2 = EgtGetInfo( vRibsIds[j], KEY_RIBS_TYPE, 'i') - local bRibInters, ptInt = VerifyRibsIntersection( vRibsIds[i], vRibsIds[j], nType1, nType2, nSrfOffs1, nSrfOffs2, 0.5 * LayerParams.dStrand, nGrpTmp, nOffsGrp) + local bRibInters, bForceCrv1Cut = VerifyRibsIntersection( vRibsIds[i], vRibsIds[j], nType1, nType2, nSrfOffs1, nSrfOffs2, LayerParams.dStrand, nGrpTmp, nOffsGrp) if bRibInters then bInters = true - - local dPar1, dPar2 - if ptInt then - dPar1 = EgtCurveParamAtPoint( vRibsIds[i], ptInt, GEO.EPS_SMALL, GDB_RT.GLOB) - dPar2 = EgtCurveParamAtPoint( vRibsIds[j], ptInt, GEO.EPS_SMALL, GDB_RT.GLOB) - end - local _, dParE1 = EgtCurveDomain( vRibsIds[i]) - local _, dParE2 = EgtCurveDomain( vRibsIds[j]) local nCrv1 = vRibsIds[i] -- curva principale che non viene tagliata local nCrv2 = vRibsIds[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 - local bCrv1OnExtr = dPar1 and ( dPar1 < 10 * GEO.EPS_SMALL or abs( dPar1 - dParE1) < 10 * GEO.EPS_SMALL) - local bCrv2OnExtr = dPar2 and ( dPar2 < 10 * GEO.EPS_SMALL or abs( dPar2 - dParE2) < 10 * GEO.EPS_SMALL) - if ( dPar1 and not dPar2) or ( bCrv1OnExtr and not bCrv2OnExtr) then + + if bForceCrv1Cut then nCrv1, nCrv2 = nCrv2, nCrv1 nSplitOrder1, nSplitOrder2 = nSplitOrder2, nSplitOrder1 else @@ -702,10 +955,13 @@ local function HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPa end -- aggiorno tabella delle intersezioni + local bSaveSurf = false if tInters[nCrv1] then table.insert( tInters[nCrv1], nCrv2) else tInters[nCrv1] = {nCrv2} + -- è la prima volta che nCrv1 viene usata per un trim quindi devo salvare la superficie utilizzata + bSaveSurf = true end -- aggiorno ordine di split @@ -717,8 +973,9 @@ local function HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPa if bAllTwoStrands and ( nType1 == nType2) then -- nel caso di 2 passate e stessa tipologia gestione speciale per creare unico percorso AdjustRibsOffsetForIntersection2Shells( nCrv1, nCrv2, LayerParams, nRibsPathGrp) + bSpecialCase = true else - AdjustRibsOffsetForIntersection( nCrv1, nCrv2, LayerParams, nRibsPathGrp) + AdjustRibsOffsetForIntersection( nCrv1, nCrv2, LayerParams, nRibsPathGrp, bSaveSurf, nLoopGrp) end end end @@ -728,45 +985,207 @@ local function HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPa EgtErase( nSrfOffs2) EgtErase( nGrpTmp) - return bInters -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 + return bInters, bSpecialCase end --------------------------------------------------------------------- --- Funzione che riordina le costolature nel caso generico -local function ReorderRibs( nGrp, bInvertOrder, bDoLinkFirst, dStrand, nMaxNbr, vRibsPrintOrder) +local function ReorderSplitRibs( vIds, dStrand, bParamInvertOrder) + + -- individuo i setti che derivano da uno stesso pezzo di costolatura + local tabRibs = {} + for i = 1, #vIds do + local nOrigId = EgtGetInfo( vIds[i], KEY_ORIGINAL_RIB, 'i') + if tabRibs[nOrigId] then + table.insert( tabRibs[nOrigId], vIds[i]) + else + tabRibs[nOrigId] = { vIds[i]} + end + end + + for k, tabVal in pairs( tabRibs) do + + -- verifico se split dopo intersezione con altro setto + local nSplitOrder = EgtGetInfo( tabVal[1], KEY_SPLIT_ORDER, 'i') or 0 + + -- verifico se split dopo aver fatto il trim con la superficie + local nStartRib = EgtGetInfo( tabVal[1], KEY_START_RIB, 'i') + local bSplitAfterTrim = EgtGetInfo( nStartRib, KEY_SPLIT_AFTER_TRIM, 'b') or false + + if nSplitOrder > 0 or bSplitAfterTrim then + -- caso di setti splittati + local nShells = EgtGetInfo( tabVal[1], KEY_RIBS_SHELLS_NBR, 'i') + if nShells == 1 then + -- non è necessario il riordino, associo splitId diversi ad ogni tratto per gestire correttamente il link nel CalcToolPath + for i = 1, #tabVal do + EgtSetInfo( tabVal[i], KEY_SPLIT_ID, i) + end + + else + -- associo le curve dello split + local tAssociatedRibs = {} + while #tabVal > 0 do + local nCurrId = tabVal[1] + table.remove( tabVal, 1) + table.insert( tAssociatedRibs, { nCurrId}) + local bCurrSplitAfterTrim = EgtGetInfo( nCurrId, KEY_SPLIT_AFTER_TRIM, 'b') or false + while nCurrId do + local ptCurr = EgtMP( nCurrId) + bFound = false + for j = 1, #tabVal do + local dDist1 = EgtPointCurveDist( ptCurr, tabVal[j]) + local dDist2 = EgtPointCurveDist( EgtMP( tabVal[j]), nCurrId) + if dDist1 < dStrand + 10 * GEO.EPS_SMALL or dDist2 < dStrand + 10 * GEO.EPS_SMALL then + + -- verifico nel caso di setti splittati dopo il trim che siano compatibili + local bUserLink = EgtGetInfo( tabVal[j], KEY_RIBS_USER_LINK, 'b') or false + local bSplitAfterTrim = EgtGetInfo( tabVal[j], KEY_SPLIT_AFTER_TRIM, 'b') or false + if bSplitAfterTrim ~= bCurrSplitAfterTrim then + if not bCurrSplitAfterTrim and bSplitAfterTrim then + local nOrd = EgtGetInfo( tabVal[j], KEY_SPLIT_AFTER_TRIM_ORDER, 'i') + if nOrd == 0 then + bFound = true + end + end + if bCurrSplitAfterTrim then + local nOrd = EgtGetInfo( nCurrId, KEY_SPLIT_AFTER_TRIM_ORDER, 'i') + local nTot = EgtGetInfo( nCurrId, KEY_SPLIT_AFTER_TRIM_TOT, 'i') + if nOrd == nTot - 1 then + bFound = true + end + end + else + bFound = true + end + + if bFound then + EgtRelocateGlob( tabVal[j], nCurrId, GDB_IN.AFTER) + nCurrId = tabVal[j] + bCurrSplitAfterTrim = bSplitAfterTrim + table.remove( tabVal, j) + table.insert( tAssociatedRibs[#tAssociatedRibs], nCurrId) + break + end + end + end + + if not bFound then + nCurrId = nil + end + end + end + + -- assegno splitid per gestire correttamente il link nel CalcToolPath + for i = 1, #tAssociatedRibs do + for j = 1, #tAssociatedRibs[i] do + EgtSetInfo( tAssociatedRibs[i][j], KEY_SPLIT_ID, i) + end + end + + -- modifiche per preservare i link definiti dall'utente + local bUserLink = EgtGetInfo( tAssociatedRibs[1][1], KEY_RIBS_USER_LINK, 'b') or false + if bUserLink and nShells % 2 == 0 then + + local nLinkOrder = EgtGetInfo( tAssociatedRibs[1][1], KEY_RIBS_USER_LINK_ORDER, 'i') or 0 + local nTotParts = EgtGetInfo( tAssociatedRibs[1][1], KEY_RIBS_USER_LINK_TOT, 'i') or 1 + local bInvertOrder = EgtGetInfo( tAssociatedRibs[1][1], KEY_RIBS_INVERT_STRAND_ORDER, 'b') or false + + -- ordinamento + if ( nTotParts % 2 == 0 and bInvertOrder and nLinkOrder % 2 ~= 0 ) or + ( nTotParts % 2 == 0 and not bInvertOrder and nLinkOrder % 2 == 0) or + ( nTotParts % 2 ~= 0 and nLinkOrder % 2 == 0) then + local vLastGrp = tAssociatedRibs[#tAssociatedRibs] + local nPrevId = vLastGrp[#vLastGrp] + for i = #tAssociatedRibs - 1, 1, -1 do + for j = 1, #tAssociatedRibs[i] do + local nCurrId = tAssociatedRibs[i][j] + EgtRelocateGlob( nCurrId, nPrevId, GDB_IN.AFTER) + nPrevId = nCurrId + end + end + end + + -- direzione + if ( nTotParts % 2 == 0 and nLinkOrder > 0 and nLinkOrder < nTotParts - 1) or + ( nTotParts % 2 ~= 0 and not bInvertOrder and nLinkOrder > 0) or + ( nTotParts % 2 ~= 0 and bInvertOrder and nLinkOrder < nTotParts - 1) then + local vLastGrp = tAssociatedRibs[#tAssociatedRibs] + for j = 1, #vLastGrp do + EgtInvertCurve( vLastGrp[j]) + UpdateInvertInfo( vLastGrp[j]) + end + end + end + end + end + end + +end + +-------------------------------------------------------------------- +local function ShortestPathForRibs( vRibs, nGrp, bInvertOrder) + + if not vRibs or #vRibs == 0 then return end + + -- divido per gruppi di setti ( i gruppi sono identificati dallo stesso nome) + local tabRibs = {} + local sPrevName = "" + for i = 1, #vRibs do + local sName = EgtGetName( vRibs[i]) + if sName == sPrevName then + table.insert( tabRibs[#tabRibs], vRibs[i]) + else + table.insert( tabRibs, {vRibs[i]}) + end + sPrevName = sName + end + + -- stabilisco l'ordine di realizzazione dei gruppi di setti + local vOrd + if #tabRibs == 1 then + -- se un solo gruppo ordinamento banale + vOrd = {1} + else + -- se più gruppi ordinamento con shortest path + EgtSpInit() + for i = 1, #tabRibs do + local ptS = EgtSP( tabRibs[i][1], GDB_ID.ROOT) + local ptE = EgtEP( tabRibs[i][#tabRibs[i]], GDB_ID.ROOT) + EgtSpAddPoint( ptS:getX(), ptS:getY(), ptS:getZ(), 0, 0, ptE:getX(), ptE:getY(), ptE:getZ(), 0, 0) + end + vOrd = EgtSpCalculate( SHP_TY.OPEN) + EgtSpTerminate() + end + + -- creo il vettore con i setti ordinati + local vIds = {} + local nStart = EgtIf( bInvertOrder, #vOrd, 1) + local nEnd = EgtIf( bInvertOrder, 1, #vOrd) + local nStep = EgtIf( bInvertOrder, -1, 1) + for i = nStart, nEnd, nStep do + local vCurrRibs = tabRibs[vOrd[i]] + for j = 1, #vCurrRibs do + table.insert( vIds, vCurrRibs[j]) + end + end + + EgtRelocateGlob( vIds[1], nGrp, GDB_IN.LAST_SON) + for i = 2, #vIds do + EgtRelocateGlob( vIds[i], vIds[i-1], GDB_IN.AFTER) + end + +end + +-------------------------------------------------------------------- +local function ReorderRibs( nGrp, bInvertOrder, dStrand, vRibsPrintOrder) local vIds = EgtGetNameInGroup( nGrp, RIBS_CRV .. '*') if not vIds or #vIds == 0 then return end + + -- riordino setti splittati + ReorderSplitRibs( vIds, dStrand, bInvertOrder) + + -- aggiorno gli id con il nuovo ordinamento + vIds = EgtGetNameInGroup( nGrp, RIBS_CRV .. '*') -- raggruppo per tipologia local tRibs = {{}, {}, {}, {}} @@ -774,88 +1193,30 @@ local function ReorderRibs( nGrp, bInvertOrder, bDoLinkFirst, dStrand, nMaxNbr, local nType = EgtGetInfo( vIds[i], KEY_RIBS_TYPE, 'i') table.insert( tRibs[nType], vIds[i]) end - - -- riordino ogni tipologia con shortest path - local vSplitRibs = {} + + -- riordino ogni tipologia for i = 1, #vRibsPrintOrder do local nCurrType = vRibsPrintOrder[i] + local vIds = tRibs[nCurrType] + + -- raggruppo in base allo split order local tSplitOrder = {} - local nMax = -1 - -- raggruppo i ribs - for j = 1, #tRibs[nCurrType] do - local nInfoSplit = EgtGetInfo( tRibs[nCurrType][j], KEY_SPLIT_RIB, 'i') - local nShells = EgtGetInfo( tRibs[nCurrType][j], KEY_RIBS_SHELLS_NBR, 'i') - if nInfoSplit and nShells == 1 then - -- se è ottenuto dalla divisione di una costolatura - table.insert( vSplitRibs, tRibs[nCurrType][j]) + local nMaxSplitOrder = 0 + for i = 1, #vIds do + local nSplitOrder = EgtGetInfo( vIds[i], KEY_SPLIT_ORDER, 'i') or 0 + -- eventuale aggiornamento del max split order + if nSplitOrder > nMaxSplitOrder then nMaxSplitOrder = nSplitOrder end + -- inserisco nella tabella + if not tSplitOrder[nSplitOrder] then + tSplitOrder[nSplitOrder]= {vIds[i]} else - -- classifico in base all'ordine di split e al link - local nSplitOrder = EgtGetInfo( tRibs[nCurrType][j], KEY_SPLIT_ORDER, 'i') or 0 - local bLink = EgtGetInfo( tRibs[nCurrType][j], KEY_RIBS_LINK, 'b') or false - if nSplitOrder > nMax then nMax = nSplitOrder end - if not tSplitOrder[nSplitOrder] then - tSplitOrder[nSplitOrder]= {{}, {}} - end - - if bLink then - table.insert( tSplitOrder[nSplitOrder][2], tRibs[nCurrType][j]) - else - table.insert( tSplitOrder[nSplitOrder][1], tRibs[nCurrType][j]) - end + table.insert( tSplitOrder[nSplitOrder], vIds[i]) end end - - local bLinkFirst = bDoLinkFirst - -- riordino ogni ordine di split - for k = 0, nMax do - if tSplitOrder[k] then - ShortestPathForRibs( EgtIf( bLinkFirst, tSplitOrder[k][2], tSplitOrder[k][1]), nGrp, bInvertOrder) - ShortestPathForRibs( EgtIf( bLinkFirst, tSplitOrder[k][1], tSplitOrder[k][2]), nGrp, bInvertOrder) - -- eventuale aggiornamento di bLinkFirst per l'ordine successivo - if not ( ( not bLinkFirst and #tSplitOrder[k][2] == 0) or ( bLinkFirst and #tSplitOrder[k][1] == 0)) then - bLinkFirst = not bLinkFirst - end - end - end - end - - -- sistemo nomi - local kMax = nMaxNbr + 1 - local dTol = 500 * GEO.EPS_SMALL - for i = 1, nMaxNbr do - local vIds = EgtGetNameInGroup( nGrp, RIBS_CRV .. tostring(i)) or {} - for j = 2, #vIds do - local dDistS = EgtPointCurveDist( EgtSP( vIds[j]), vIds[j-1]) - local dDistM = EgtPointCurveDist( EgtMP( vIds[j]), vIds[j-1]) - local dDistE = EgtPointCurveDist( EgtEP( vIds[j]), vIds[j-1]) - if abs( dDistS - dStrand) < dTol or abs( dDistM - dStrand) < dTol or abs( dDistE - dStrand) < dTol then - -- se le costolatura è vicina alla precedente avrà lo stesso nome - EgtSetName( vIds[j], EgtGetName( vIds[j-1])) - EgtRelocateGlob( vIds[j], vIds[j-1], GDB_IN.AFTER) - else - -- se la costolatura dista troppo dalla precedente le cambio il nome - EgtSetName( vIds[j], RIBS_CRV .. tostring( kMax)) - 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)) - -- 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 - 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]) + + -- riordino ogni ordine di split con shortest path + for k = 0, nMaxSplitOrder do + ShortestPathForRibs( tSplitOrder[k], nGrp, bInvertOrder) end end end @@ -910,7 +1271,7 @@ end --------------------------------------------------------------------------------------------- -- Funzione che riordina le costolature nel caso di intersezioni e 2 passate -local function ReorderRibsInters2Shells( nOffsGrp, dStrand, vRibsPrintOrder) +local function ReorderRibsInters2Shells( nOffsGrp, dStrand, vRibsPrintOrder, bInvertOrder) local vOffs = {} local vClosed = {} @@ -1059,10 +1420,18 @@ local function ReorderRibsInters2Shells( nOffsGrp, dStrand, vRibsPrintOrder) local nType = EgtGetInfo( vCrvs[nId], KEY_RIBS_TYPE, 'i') table.insert( tRibs[nType], vCrvs[nId]) end + -- riordino per tipologia for i = 1, #vRibsPrintOrder do nCurrType = vRibsPrintOrder[i] - for j = 1, #tRibs[nCurrType] do + local nStart = EgtIf( bInvertOrder, #tRibs[nCurrType], 1) + local nEnd = EgtIf( bInvertOrder, 1, #tRibs[nCurrType]) + local nStep = EgtIf( bInvertOrder, -1, 1) + for j = nStart, nEnd, nStep do + if bInvertOrder then + -- inverto curve per mantenere concatenamento + EgtInvertCurve( tRibs[nCurrType][j]) + end EgtRelocateGlob( tRibs[nCurrType][j], nOffsGrp, GDB_IN.LAST_SON) end end @@ -1070,34 +1439,6 @@ local function ReorderRibsInters2Shells( nOffsGrp, dStrand, vRibsPrintOrder) end ------------------------------------------------------------------- -local function UpdateRibSplitInfo( nGrp, tIds, tRemoved) - - 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 - -- verifico se va aggiornata ereditandola da rib che sono stati eliminati per vincolo sulla lunghezza - while tRemoved[nInfo] do - nInfo = tRemoved[nInfo] - end - - 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, vPtStart) -- stabilisco ordine di realizzazione delle varie tipologie @@ -1105,41 +1446,22 @@ local function CalcRibsPaths( nSliceGrp, nRibsGrp, LayerParams, nIdx, vPtStart) for i = 1, #LayerParams.vRibsPrintOrder do vTypeSequence[LayerParams.vRibsPrintOrder[i]] = i end - - local vRibs = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*') + + local vOrigRibs = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*') -- verifico se tutte le costolature vengono fatte con 2 passate local bAllTwoStrands = true - for i = 1, #vRibs do - local nStrand = EgtGetInfo( vRibs[i], KEY_RIBS_SHELLS_NBR, 'i') + for i = 1, #vOrigRibs do + local nStrand = EgtGetInfo( vOrigRibs[i], KEY_RIBS_SHELLS_NBR, 'i') if nStrand ~= 2 then bAllTwoStrands = false break end end - local nLast = EgtGetLastNameInGroup( nRibsGrp, RIBS_CRV .. '*') - local sLastName = EgtGetName( nLast) - local nMaxNbr = tonumber( string.sub( sLastName, 4)) + -- verifico se posso ignorare eventuali buchi nei setti + VerifyRibsHoles( vOrigRibs, LayerParams.dStrand) - -- calcolo gli offset - local nOffsGrp = EgtGroup( nRibsGrp) - for i = 1, #vRibs do - local nShellsNbr = EgtGetInfo( vRibs[i], KEY_RIBS_SHELLS_NBR, 'i') - local dOffs = ( nShellsNbr - 1) * LayerParams.dStrand / 2 - for k = 0, nShellsNbr - 1 do - local nNewId = EgtOffsetCurveAdv( vRibs[i], - dOffs + k * LayerParams.dStrand) - EgtSetName( nNewId, EgtGetName( vRibs[i])) - EgtSetInfo( nNewId, KEY_TYPE, TYPE.RIB) - EgtRelocateGlob( nNewId, nOffsGrp) - - if EgtCurveIsClosed( vRibs[i]) then - EgtSetInfo( nNewId, "OriginalClosed", 1) - end - end - end - -- scorro i gruppi di curve - local dOffs = 0.5 * LayerParams.dStrand - LayerParams.dOffs + ( LayerParams.nShellsNbr - 1) * LayerParams.dStrand local nCrvGrp = EgtGetFirstNameInGroup( nSliceGrp, CONTOUR_GRP .. '*') while nCrvGrp do @@ -1153,101 +1475,111 @@ local function CalcRibsPaths( nSliceGrp, nRibsGrp, LayerParams, nIdx, vPtStart) EgtEmptyGroup( nRibsPathGrp) end - -- creo le superfici con cui fare i trim + -- recupero le superfici local nSrfBase = EgtGetFirstNameInGroup( nCrvGrp, TOT_SHELL_TRIM_SURF) local nSrfExt = EgtGetFirstNameInGroup( nCrvGrp, LAYER_SRF) - local tSurfOffs = ComputeTrimSurfWithOverlapsForRibs( vRibs, nSrfBase, nSrfExt, LayerParams.dOffs, LayerParams.dStrand, nRibsPathGrp, LayerParams.vtSlicing) + -- trim grossolano dei setti + local nTrimGrp = TrimRibs( vOrigRibs, nRibsGrp, nSrfExt, LayerParams.dOffs, LayerParams.vtSlicing) + + -- calcolo offset orientati + local nOffsGrp = ComputeRibsOrientedOffset( nTrimGrp, LayerParams.dStrand) + + -- creo le superfici con cui fare i trim corretti + local tSurfOffs = ComputeTrimSurfWithOverlapsForRibs( vOrigRibs, nSrfBase, nSrfExt, LayerParams.dOffs, LayerParams.dStrand, nRibsPathGrp, LayerParams.vtSlicing) + + -- preparo il gruppo con i contorni delle superfici di offset ( necessario per CalcToolPath) + local nLoopGrp = EgtGroup( nRibsPathGrp) + local nSrfId = EgtGetFirstNameInGroup( nRibsPathGrp, TOT_SHELL_TRIM_SURF) + while nSrfId do + local nChunksNbr = EgtSurfFrChunkCount( nSrfId) + for i = 0, nChunksNbr - 1 do + local nRes, nCnt = EgtExtractSurfFrChunkLoops( nSrfId, i, nLoopGrp) + for j = nRes, nRes + nCnt - 1 do + EgtSetName( j, TRIM_SURF_LOOP) + end + end + nSrfId = EgtGetNextName( nSrfId, TOT_SHELL_TRIM_SURF) + end + -- gestisco eventuali intersezioni fra costolature - local bInters = HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPathGrp, bAllTwoStrands, vTypeSequence) + local bInters, bSpecialCase = HandleRibsIntersections( nRibsGrp, LayerParams, nOffsGrp, nRibsPathGrp, nLoopGrp, bAllTwoStrands, vTypeSequence) EgtSetInfo( nRibsPathGrp or GDB_ID.NULL, KEY_RIBS_INTERS, bInters) - EgtSetInfo( nRibsPathGrp or GDB_ID.NULL, KEY_RIBS_TWO_STRANDS, bAllTwoStrands) + EgtSetInfo( nRibsPathGrp or GDB_ID.NULL, KEY_RIBS_SPECIAL_CASE, bSpecialCase) - -- eseguo il trim delle costole con la regione offsettata - local tOldNewIds = {} - local tRemoved = {} - local vOrderedRibs = EgtGetNameInGroup( nRibsPathGrp, RIBS_CRV ..'*') - for i = 1, #vOrderedRibs do + -- trim dei setti con le regioni offsettate secondo opportuno overlap + local vRibs = EgtGetNameInGroup( nRibsPathGrp, RIBS_CRV ..'*') or {} + for i = 1, #vRibs do + local nCrvId = vRibs[i] -- trim con superficie opportuna - local nOverlap = EgtGetInfo( vOrderedRibs[i], KEY_RIBS_OVERLAP, 'i') - local nType = EgtGetInfo( vOrderedRibs[i], KEY_RIBS_TYPE, 'i') + local nOverlap = EgtGetInfo( nCrvId, KEY_RIBS_OVERLAP, 'i') + local nType = EgtGetInfo( nCrvId, 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]) + EgtErase( vRibs[i]) else local nCrv, nCnt if tSurfOffs[nType][nOverlap] == GDB_ID.NULL then -- caso unbounded - nCrv = vOrderedRibs[i] + nCrv = nCrvId nCnt = 1 else - nCrv, nCnt = EgtTrimCurveWithRegion( vOrderedRibs[i], tSurfOffs[nType][nOverlap], EgtIf( nType == RIB_TYPE.INTERNAL or nType == RIB_TYPE.SUPPORT, true, false), false) + nCrv, nCnt = EgtTrimCurveWithRegion( nCrvId, tSurfOffs[nType][nOverlap], EgtIf( nType == RIB_TYPE.INTERNAL or nType == RIB_TYPE.SUPPORT, true, false), false) end - tOldNewIds[ vOrderedRibs[i]] = {} - - -- elimino tratti troppo corti for nInd = 0, nCnt - 1 do + -- verifico vicolo sulla lunghezza local dLen = EgtCurveLength( nCrv + nInd) if dLen < MIN_RIBS_LEN then - -- conservo eventuale info di split - local nSplitRib = EgtGetInfo( nCrv + nInd, KEY_SPLIT_RIB, 'i') - if nSplitRib then - tRemoved[vOrderedRibs[i]] = nSplitRib - end - -- cancello la curva EgtErase( nCrv + nInd) else - table.insert( tOldNewIds[ vOrderedRibs[i]], nCrv + nInd) - local bInvert = false - if not EgtGetInfo( nCrv + nInd, "OriginalClosed", 'b') then - -- 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()) - bInvert = dVal < - GEO.EPS_SMALL - end - local bInvertInfo = EgtGetInfo( nCrv + nInd, KEY_RIBS_INVERT_DIR, 'b') or false - -- inversione della curva - if bInvertInfo ~= bInvert 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, tSurfOffs[nType][nOverlap]) + -- setti chiusi if EgtCurveIsClosed( nCrv + nInd) then EgtSetInfo( nCrv + nInd, KEY_CLOSED_CRV, 1) + + -- ripristino orientamento originale + local bInvertInfo = EgtGetInfo( nCrv + nInd, KEY_RIBS_INVERT_DIR, 'b') or false + local bInverted = EgtGetInfo( nCrv + nInd, KEY_INVERTED_CRV, 'b') or false + if bInvertInfo ~= bInverted then + EgtInvertCurve( nCrv + nInd) + UpdateInvertInfo( nCrv + nInd) + end + ModifyStartPoint( nCrv + nInd, vPtStart) EgtSetInfo( nCrv + nInd, KEY_RIBS_LINK, 0) 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) + -- se dopo trim ho avuto split in più tratti, salvo alcune info + if nCnt > 1 then + local nStartRib = EgtGetInfo( nCrv + nInd, KEY_START_RIB, 'i') + EgtSetInfo( nStartRib, KEY_SPLIT_AFTER_TRIM, 1) + EgtSetInfo( nCrv + nInd, KEY_SPLIT_AFTER_TRIM, 1) + EgtSetInfo( nCrv + nInd, KEY_SPLIT_AFTER_TRIM_ORDER, nInd) + EgtSetInfo( nCrv + nInd, KEY_SPLIT_AFTER_TRIM_TOT, nCnt) end end + end end end - -- aggiorno le info di split con i nuovi id - UpdateRibSplitInfo( nRibsPathGrp, tOldNewIds, tRemoved) - -- riordino le costolature - if bAllTwoStrands and bInters then + if bSpecialCase then -- gestione caso speciale di intersezione e 2 passate - ReorderRibsInters2Shells( nRibsPathGrp, LayerParams.dStrand, LayerParams.vRibsPrintOrder) + ReorderRibsInters2Shells( nRibsPathGrp, LayerParams.dStrand, LayerParams.vRibsPrintOrder, LayerParams.bRibsInvertOrder) else - ReorderRibs( nRibsPathGrp, LayerParams.bRibsInvertOrder, LayerParams.bRibsDoLinkFirst, LayerParams.dStrand, nMaxNbr, LayerParams.vRibsPrintOrder) + ReorderRibs( nRibsPathGrp, LayerParams.bRibsInvertOrder, LayerParams.dStrand, LayerParams.vRibsPrintOrder) end - + if not EgtGetFirstNameInGroup( nRibsPathGrp, RIBS_CRV .. '*') then EgtErase( nRibsPathGrp) end + nCrvGrp = EgtGetNextName( nCrvGrp, CONTOUR_GRP .. '*') end end @@ -1439,7 +1771,7 @@ local function ReorderExtraShells( nPathGrp, dStrand, vPtStart, bPrintInvert) if bPrintInvert then for i = 1, #vIds do EgtInvertCurve( vIds[i]) - EgtSetInfo( vIds[i], KEY_INVERTED_CRV, 1) + UpdateInvertInfo( vIds[i]) end end diff --git a/LuaLibs/CalcSlices.lua b/LuaLibs/CalcSlices.lua index 60295bb..049d8df 100644 --- a/LuaLibs/CalcSlices.lua +++ b/LuaLibs/CalcSlices.lua @@ -96,7 +96,8 @@ end 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 or defVal + if info == nil then info = defVal end + table[sKey] = info end -------------------------------------------------------------------- @@ -115,6 +116,7 @@ local function GetRibParams( nId) ReadParam( nId, KEY_RIBS_OVERLAP, 'i', RibParam) ReadParam( nId, KEY_RIBS_LINK, 'b', RibParam) ReadParam( nId, KEY_RIBS_TYPE, 'i', RibParam, RIB_TYPE.INTERNAL) + ReadParam( nId, KEY_RIBS_INVERT_STRAND_ORDER, 'b', RibParam) return RibParam end diff --git a/LuaLibs/CalcToolPath.lua b/LuaLibs/CalcToolPath.lua index 47b7323..01732cf 100644 --- a/LuaLibs/CalcToolPath.lua +++ b/LuaLibs/CalcToolPath.lua @@ -560,7 +560,7 @@ local function CalcRibsLink( nCurr, nNext, nLoopGrp, dStrand, bForceLink, vtSlic local ptS = EgtEP( nCurr) local ptE = EgtSP( nNext) - local nCrvId = EgtGetFirstInGroup( nLoopGrp) + local nCrvId = EgtGetFirstNameInGroup( nLoopGrp, TRIM_SURF_LOOP) -- recupero la curva di offset su cui calcolare link while nCrvId do local dParS = EgtCurveParamAtPoint( nCrvId, ptS) @@ -607,18 +607,31 @@ local function CalcRibsLink( nCurr, nNext, nLoopGrp, dStrand, bForceLink, vtSlic return end + -- elimino dalle curve di contorno il link appena trovato if bClosed then EgtTrimCurveStartEndAtParam( nCrvId, dParE, dParS) EgtErase( nCopyId) else - EgtTrimCurveEndAtParam( nCrvId, dParS) - EgtTrimCurveStartAtParam( nCopyId, dParE) + if dParS < GEO.EPS_SMALL then + -- forzare la fine della curva nel suo inizio significa cancellarla completamente + EgtErase( nCrvId) + else + EgtTrimCurveEndAtParam( nCrvId, dParS) + end + + local _, dEnd = EgtCurveDomain( nCopyId) + if abs( dParE - dEnd) < GEO.EPS_SMALL then + -- forzare l'inizio della curva nella sua fine significa cancellarla completamente + EgtErase( nCopyId) + else + EgtTrimCurveStartAtParam( nCopyId, dParE) + end end return nLinkId end - nCrvId = EgtGetNext( nCrvId) + nCrvId = EgtGetNextName( nCrvId, TRIM_SURF_LOOP) end -- se non ho trovato un collegamento sul bordo, creo una linea tra ptS e ptE @@ -630,7 +643,7 @@ local function CalcRibsLink( nCurr, nNext, nLoopGrp, dStrand, bForceLink, vtSlic EgtSetName( nLinkId, LINK_CRV) EgtModifyCurveExtrusion( nLinkId, vtSlicing, GDB_RT.GLOB) EgtRelocateGlob( nLinkId, nCurr, GDB_IN.AFTER) - else + else EgtErase( nLinkId) end end @@ -737,7 +750,7 @@ local function FindCorrectRibsLead( dPar, nCrv, nCrvOffs, bLeadInvert, dLeadLen, local bOnlyOneCurve = not bClosed and ( dPar < GEO.EPS_SMALL or abs( dPar - dParEnd) < GEO.EPS_SMALL) local nMainCrv = nCrvOffs -- curva preferita da utilizzare per lead in - local nOtherCrv -- altra possibile curva da ultizzare nel caso nMainCrv non sia adatta + local nOtherCrv -- altra possibile curva da ultizzare nel caso nMainCrv non sia adatta if bClosed then EgtChangeClosedCurveStart( nCrvOffs, dPar) @@ -796,7 +809,7 @@ local function FindCorrectRibsLead( dPar, nCrv, nCrvOffs, bLeadInvert, dLeadLen, end else EgtErase( nLeadId) - bInvert = not bInvert + bInvert = not bInvert return nil end -- aggiorno parametro bInvert @@ -808,7 +821,7 @@ end -------------------------------------------------------------------- local function AddRibsLeadIn( nCrv, nLoopsGrp, dStrand, vtSlicing, nGrpTmp) - + local dLILen = EgtGetInfo( nCrv, KEY_RIBS_LEAD_IN_LEN, 'd') local bLIInvert = EgtGetInfo( nCrv, KEY_RIBS_LEAD_IN_INVERT, 'b') @@ -817,7 +830,7 @@ local function AddRibsLeadIn( nCrv, nLoopsGrp, dStrand, vtSlicing, nGrpTmp) -- recupero la curva di offset su cui calcolare leadin local ptS = EgtSP( nCrv) local nCrvOffs = EgtGetFirstInGroup( nLoopsGrp) - while nCrvOffs do + while nCrvOffs do local dParS = EgtCurveParamAtPoint( nCrvOffs, ptS) if dParS then @@ -947,7 +960,7 @@ local function CalcRibsToolPath( nRibsGrp, nTpathGrpId, LayerParams, dCorrZ) -- aggiungo le costolature nel toolpath local vEntIds = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*') for i = 1, #vEntIds do - -- copio entità nel gruppo toolpath + -- copio entità nel gruppo toolpath local nNewEntId = EgtCopyGlob( vEntIds[i], nTpathGrpId, GDB_IN.LAST_SON) -- correggo posizione in Z ( per essere sicuri di appoggiare sul piano) EgtMove( nNewEntId, dCorrZ * Z_AX(), GDB_RT.GLOB) @@ -957,20 +970,21 @@ local function CalcRibsToolPath( nRibsGrp, nTpathGrpId, LayerParams, dCorrZ) EgtSetColor( nNewEntId, EgtStdColor('MAROON')) end - -- estraggo i contorni di tutte le superfici di offset - local nLoopGrp = EgtGroup( nRibsGrp) - local nSrfId = EgtGetFirstNameInGroup( nRibsGrp, TOT_SHELL_TRIM_SURF) - 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) - end - nSrfId = EgtGetNextName( nSrfId, TOT_SHELL_TRIM_SURF) + -- posiziono alla quota corretta i loop degli offset da utlizzare per link, ingressi e uscite + local nLoopGrp = EgtGetFirstGroupInGroup( nRibsGrp) + local vLoopIds = EgtGetAllInGroup( nLoopGrp) + for i = 1, #vLoopIds do + EgtMove( vLoopIds[i], dCorrZ * Z_AX(), GDB_RT.GLOB) + EgtMove( vLoopIds[i], LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) end + -- posizono alla quota corretta le superfici usate per i trim + local vSrfIds = EgtGetNameInGroup( nRibsGrp, TOT_SHELL_TRIM_SURF) or {} + for i = 1, #vSrfIds do + EgtMove( vSrfIds[i], dCorrZ * Z_AX(), GDB_RT.GLOB) + EgtMove( vSrfIds[i], LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) + end + -- recupero i gruppi delle costolature local tabRibs = {} local nFirst = EgtGetFirstNameInGroup( nTpathGrpId, RIBS_CRV .. '*') @@ -981,82 +995,35 @@ local function CalcRibsToolPath( nRibsGrp, nTpathGrpId, LayerParams, dCorrZ) nFirst = EgtGetNextName( vIds[#vIds], RIBS_CRV .. '*') end - local bInters = EgtGetInfo( nRibsGrp, KEY_RIBS_INTERS, 'b') or false - local bAllTwoStrands = EgtGetInfo( nRibsGrp, KEY_RIBS_TWO_STRANDS, 'b') or false - local bSpecialCase = bInters and bAllTwoStrands - local bSwap = false - - local bInvert = false -- curve già orientate in CalcPaths - if not bSpecialCase then - for i = 1, #tabRibs do - local nInfo = EgtGetInfo( tabRibs[i][1], KEY_SPLIT_RIB, 'i') - local nShellsNbr = EgtGetInfo( tabRibs[i][1], KEY_RIBS_SHELLS_NBR, 'i') - - if i > 1 then - -- verifico se link - local bPrevLink = EgtGetInfo( tabRibs[i-1][1], KEY_RIBS_LINK, 'b') - local bCurrLink = EgtGetInfo( tabRibs[i][1], KEY_RIBS_LINK, 'b') - if bPrevLink and bCurrLink 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 - -- aggiorno bInvert per il gruppo di costolature corrente in modo da essere coerente con il collegamento - local nPrevShellsNbr = EgtGetInfo( tabRibs[i-1][1], KEY_RIBS_SHELLS_NBR, 'i') - if nPrevShellsNbr % 2 == 1 then - bInvert = not bInvert - end - end - else - bInvert = false - end - end - - if nShellsNbr == 1 and nInfo and bInvert then - -- se inverto direzione di costolature divise allora devo invertirne anche l'ordine di realizzazione - bSwap = true - EgtRelocateGlob( tabRibs[i][1], tabRibs[i-1][1], GDB_IN.BEFORE) - end - - -- oriento tutte le passate relative ad una stessa costolatura - if not EgtCurveIsClosed( tabRibs[i][1]) then - for j = 1, #tabRibs[i] do - if ( bInvert and j % 2 == 1) or ( not bInvert and j % 2 == 0) then - EgtInvertCurve( tabRibs[i][j]) - end - end - end - end - end + local bSpecialCase = EgtGetInfo( nRibsGrp, KEY_RIBS_SPECIAL_CASE, 'b') or false -- Link - -- se modifiche nell'ordine ricalcolo i gruppi di costolature - if bSwap then - tabRibs = {} - nFirst = EgtGetFirstNameInGroup( nTpathGrpId, RIBS_CRV .. '*') - while nFirst do - local sName = EgtGetName( nFirst) - local vIds = EgtGetNameInGroup( nTpathGrpId, sName) - table.insert( tabRibs, vIds) - nFirst = EgtGetNextName( vIds[#vIds], RIBS_CRV .. '*') - end - end - -- collego le passate di una stessa costolatura for i = 1, #tabRibs do if EgtCurveIsClosed( tabRibs[i][1]) then AddLink( tabRibs[i], nTpathGrpId, LINK_TYPE.NONE, LayerParams.dLinkParam, LayerParams.dSPOffs, LayerParams.dStrand, LayerParams.vtSlicing) else for j = 1, #tabRibs[i] - 1 do - CalcRibsLink( tabRibs[i][j], tabRibs[i][j + 1], nLoopGrp, LayerParams.dStrand, true, LayerParams.vtSlicing, nGrpTmp) - if not bSpecialCase then - -- creo link fittizio per eliminare tratto corrispondente sulla curva di offset + local nOrig1 = EgtGetInfo( tabRibs[i][j], KEY_ORIGINAL_RIB, 'i') + local nOrig2 = EgtGetInfo( tabRibs[i][j + 1], KEY_ORIGINAL_RIB, 'i') + local nSplitId1 = EgtGetInfo( tabRibs[i][j], KEY_SPLIT_ID, 'i') or 0 + local nSplitId2 = EgtGetInfo( tabRibs[i][j + 1], KEY_SPLIT_ID, 'i') or 0 + local bForceLink = ( nOrig1 == nOrig2 and nSplitId1 == nSplitId2) + + CalcRibsLink( tabRibs[i][j], tabRibs[i][j + 1], nLoopGrp, LayerParams.dStrand, bForceLink, LayerParams.vtSlicing, nGrpTmp) + -- creo link fittizio per eliminare tratto corrispondente sulla curva di offset + if not bSpecialCase and bForceLink then local nFakeLink = CalcRibsLink( tabRibs[i][j + 1], tabRibs[i][j], nLoopGrp, LayerParams.dStrand, false, LayerParams.vtSlicing, nGrpTmp) EgtErase( nFakeLink) end end + + -- verifico se necessario collegamento tra primo e ultimo setto del gruppo + local bOriginalClosed = EgtGetInfo( tabRibs[i][1], KEY_ORIGINAL_RIB_CLOSED, 'b') or false + if bOriginalClosed then + CalcRibsLink( tabRibs[i][#tabRibs[i]], tabRibs[i][1], nLoopGrp, LayerParams.dStrand, false, LayerParams.vtSlicing, nGrpTmp) + end + if bSpecialCase then local nFakeLink = CalcRibsLink( tabRibs[i][#tabRibs[i]], tabRibs[i][1], nLoopGrp, LayerParams.dStrand, false, LayerParams.vtSlicing, nGrpTmp) EgtErase( nFakeLink) diff --git a/LuaLibs/RunSlicing.lua b/LuaLibs/RunSlicing.lua index 8a9087b..caeaf47 100644 --- a/LuaLibs/RunSlicing.lua +++ b/LuaLibs/RunSlicing.lua @@ -155,8 +155,8 @@ local function LoadParams( sFile, nPartId) SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_RIBS_PRINT_ORDER, '3,1,4,2') SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_RIBS_SHELLS_NBR, '0') SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_RIBS_INVERT_DIR, '0') + SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_RIBS_INVERT_STRAND_ORDER, '0') SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_RIBS_INVERT_ORDER, '0') - SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_RIBS_DO_LINK_FIRST, '0') SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_RIBS_LINK, '0') SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_RIBS_LEAD_IN_INVERT, '0') SetParamInfo( sFile, nPartId, SEC_DEFAULT, KEY_RIBS_LEAD_IN_LEN, '0.0')