diff --git a/LuaLibs/AddManData.lua b/LuaLibs/AddManData.lua index 934eff9..525b6ed 100644 --- a/LuaLibs/AddManData.lua +++ b/LuaLibs/AddManData.lua @@ -109,6 +109,7 @@ KEY_START_RIB = "StartRib" KEY_ORIGINAL_RIB = "OriginalRib" KEY_LOOP_RIB = "LoopRib" KEY_RIBS_USER_LINK = "RibWithUserLink" +KEY_RIBS_USER_LINK_SAME_SIDE = "RibUserLinkOnSameSide" KEY_RIBS_USER_LINK_CCW = "RibUserLinkCCW" KEY_RIBS_USER_LINK_ORDER = "RibUserLinkOrder" KEY_RIBS_USER_LINK_TOT = "RibsUserLinkParts" @@ -152,6 +153,7 @@ KEY_INVERTED_CRV = "InvertedCrv" KEY_CLOSED_CRV = "ClosedCrv" KEY_ASSOCIATED_SURF = "AssociatedSurf" KEY_ASSOCIATED_CRVS = "AssociatedCrvs" +KEY_ORIGINAL_SURF = "OriginalSurf" KEY_HAS_SOLIDS = "Solids" KEY_BOX_MIN_Z = "PartBoxMinZ" KEY_START_POINT = "StartPoint" @@ -284,6 +286,7 @@ SLICE_ADV_TYPE = { --------------------------------------------------------------------- RIBS_GRP = "Ribs" RIBS_CRV = "Rib" +RIBS_LOOP_GRP = "RibsLoops" SHELL_NBR_GRP = "ShellNbrRegions" SHELL_NBR_CRV = "ShellNbrRegion" diff --git a/LuaLibs/CalcPaths.lua b/LuaLibs/CalcPaths.lua index 0d00fd0..0263858 100644 --- a/LuaLibs/CalcPaths.lua +++ b/LuaLibs/CalcPaths.lua @@ -57,6 +57,14 @@ local function CopyInfo( nSouId, nDestId, sInfo, sType) EgtSetInfo( nDestId, sInfo, info) end +------------------------------------------------------------------- +local function SwapInfo( nId1, nId2, sInfo, sType, sDefVal) + local info1 = EgtGetInfo( nId1, sInfo, sType) or sDefVal + local info2 = EgtGetInfo( nId2, sInfo, sType) or sDefVal + EgtSetInfo( nId1, sInfo, info2) + EgtSetInfo( nId2, sInfo, info1) +end + -------------------------------------------------------------------------------------------- local function UpdateInvertInfo( nId) local bInvert = EgtGetInfo( nId, KEY_INVERTED_CRV, 'b') or false @@ -473,13 +481,35 @@ local function VerifyRibsHoles( vIds, dStrand) 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 + local ptS1 = EgtSP( vIds[i-1]) + local ptE1 = EgtEP( vIds[i-1]) + local ptS2 = EgtSP( vIds[i]) + local ptE2 = EgtEP( vIds[i]) + + local bAdd1 = dist( ptS1, ptE2) < dStrand + 10 * GEO.EPS_SMALL or dist( ptS1, ptS2) < dStrand + 10 * GEO.EPS_SMALL + local bAdd2 = dist( ptE1, ptS2) < dStrand + 10 * GEO.EPS_SMALL or dist( ptE1, ptE2) < dStrand + 10 * GEO.EPS_SMALL + local bInvert = dist( ptE1, ptE2) < dStrand + 10 * GEO.EPS_SMALL or dist( ptS1, ptS2) < dStrand + 10 * GEO.EPS_SMALL + + if bInvert then + EgtInvertCurve( vIds[i]) + end + + if bAdd1 and bAdd2 then + -- se da unire in setto chiuso + bAdd = true + EgtAddCurveCompoLine( vIds[i-1], EgtEP( vIds[i]), false) + EgtAddCurveCompoLine( vIds[i-1], EgtSP( vIds[i])) + EgtAddCurveCompoCurve( vIds[i-1], vIds[i]) + table.remove( vIds, i) -- rimuovo il setto dalla tabella + + elseif bAdd2 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 + + elseif bAdd1 then bAdd = true -- unisco il primo tratto al secondo EgtAddCurveCompoLine( vIds[i], EgtSP( vIds[i-1])) @@ -487,6 +517,7 @@ local function VerifyRibsHoles( vIds, dStrand) table.remove( vIds, i-1) -- rimuovo il setto dalla tabella end end + -- aggiorno per iterazione successiva sPrevName = sCurrName if not bAdd then @@ -496,18 +527,16 @@ local function VerifyRibsHoles( vIds, dStrand) 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 +local function FindRibsUserLinkDirection( nCrv1, nCrv2, vtSlicing) -- 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)) + + -- costruisco la superficie "definita" dal setto di partenza con i primi due setti che lo definiscono + local nGrpTmp = EgtGroup( EgtGetParent( nCrv1)) + local nSrfLoop = EgtCurveCompoFromPoints( nGrpTmp, {EgtEP( nCrv1), EgtSP( nCrv2)}) + EgtAddCurveCompoLine( nSrfLoop, EgtSP( nCrv2) + 100 * EgtSV( nCrv2)) + EgtAddCurveCompoLine( nSrfLoop, EgtEP( nCrv1) - 100 * EgtEV( nCrv1)) EgtCloseCurveCompo( nSrfLoop) local nSurf = EgtSurfFlatRegion( nGrpTmp, {nSrfLoop}) @@ -521,16 +550,372 @@ local function CheckRibUserLink( nCrv, nCnt, vtSlicing) 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) + EgtErase( nGrpTmp) + return bCCW + +end + +----------------------------------------------------------------------- +local function FindAssociatedUserLinkParts( nStartRib, vRibs, vUsed, nGrpTmp, nType, nSrfTest) + + local tabUserLink = {} + + for i = 1, #vRibs do + local nTypeCurr = EgtGetInfo( vRibs[i], KEY_RIBS_TYPE, 'i') + -- verifico che il setto non sia già stato utilizzato in un altro UserLink e sia di tipologia compatibile + if not vUsed[vRibs[i]] and nTypeCurr == nType then + + -- recupero setto di partenza non trimmato + local nStartId = EgtGetInfo( vRibs[i], KEY_START_RIB, 'i') + + -- verifico se interseca nStartRib con un estremo + local dParS = EgtCurveParamAtPoint( nStartRib, EgtSP( nStartId), 100 * GEO.EPS_SMALL) + local dParE = EgtCurveParamAtPoint( nStartRib, EgtEP( nStartId), 100 * GEO.EPS_SMALL) + if dParS and dParE then + -- se entrambi gli estremi non ha senso aggiungerlo a UserLink + elseif dParS or dParE then + -- se solo un estremo verifico se si unisce a UserLink in tratto sensato + local dPar = dParS or dParE + local ptTest = EgtPoint( nGrpTmp, EgtUP( nStartRib, dPar)) + local bExtJoint = EgtSurfFrTestExternal( nSrfTest, ptTest) + if ( nType == RIB_TYPE.EXTERNAL and not bExtJoint) or ( nType ~= RIB_TYPE.EXTERNAL and bExtJoint) then + + -- lo aggiungo alla tabella di UserLink + local tRib = { nId = vRibs[i], bStart = EgtIf( dParS, true, false), bOn = false, dPar = dPar} + table.insert( tabUserLink, tRib) + -- indico che il setto è stato utilizzato + vUsed[vRibs[i]] = 1 + end + end + end + end + + return tabUserLink +end + +----------------------------------------------------------------------- +local function AssignUserLinkInfo( tabUserLink, bCCW, bLoopRib, bSameSide, sName) + + -- ordino per paramentro crescente + table.sort( tabUserLink, function(a,b) return a.dPar < b.dPar end) + + -- aggiorno le info dei tratti di UserLink per tenere conto delle aggiunte + local bUseOppositeCondition = EgtIf( bSameSide, false, true) + for i = 1, #tabUserLink do + local nId = tabUserLink[i].nId + + EgtSetName( nId, sName) + EgtSetInfo( nId, KEY_RIBS_USER_LINK, 1) + EgtSetInfo( nId, KEY_RIBS_USER_LINK_CCW, bCCW) + EgtSetInfo( nId, KEY_LOOP_RIB, bLoopRib) + EgtSetInfo( nId, KEY_RIBS_USER_LINK_SAME_SIDE, bSameSide) + EgtSetInfo( nId, KEY_RIBS_USER_LINK_TOT, #tabUserLink) + + -- riposiziono + if i > 1 then + EgtRelocateGlob( nId, tabUserLink[i-1].nId, GDB_IN.AFTER) + end + + -- ordine + local nPrevOrd = EgtGetInfo( nId, KEY_RIBS_USER_LINK_ORDER, 'i') + local nCurrOrd = i - 1 + EgtSetInfo( nId, KEY_RIBS_USER_LINK_ORDER, nCurrOrd) + + -- orientamento + if tabUserLink[i].bOn then + -- se il tratto apparteneva già a UserLink va invertito se order passa da pari a dispari o viceversa + local bInvert = ( nPrevOrd and nPrevOrd % 2 ~= nCurrOrd % 2) or ( not nPrevOrd and i ~= 1 and i % 2 ~= 0) + if bInvert then + EgtInvertCurve( nId) + UpdateInvertInfo( nId) + end + if not bSameSide then bUseOppositeCondition = not bUseOppositeCondition end + else + -- se tratto aggiunto dipende con quale estremo interseca il setto + local bCondition = ( nCurrOrd % 2 == 0 and tabUserLink[i].bStart) or ( nCurrOrd % 2 ~= 0 and not tabUserLink[i].bStart) + if bUseOppositeCondition ~= bCondition then + EgtInvertCurve( nId) + UpdateInvertInfo( nId) + end + end + end +end + +------------------------------------------------------------------------ +local function AdjustUserLinkRibs( tUserLink, vRibs, vtSlicing, nSrfInt, nSrfExt) + + local nGrpTmp = EgtGroup( EgtGetParent( nSrfInt)) -- gruppo temporaneo per conti + local vUsed = {} -- setti di vRibs utilizzati per UserLink + + -- verifico se posso aggiungere tratti extra agli UserLink già individuati + for nStartRib, vAssociatedRibs in pairs( tUserLink) do + + -- verifico se ho tratti singoli da aggiungere a UserLink definito da nStartRib + local nType = EgtGetInfo( nStartRib, KEY_RIBS_TYPE, 'i') + local nSrfTest = EgtIf( nType == RIB_TYPE.EXTERNAL, nSrfExt, nSrfInt) + local tabUserLink = FindAssociatedUserLinkParts( nStartRib, vRibs, vUsed, nGrpTmp, nType, nSrfTest) + + -- se ho tratti da aggiungere + if #tabUserLink > 0 then + + -- recupero i tratti già individuati su UserLink + for i = 1, #vAssociatedRibs do + local dPar = EgtCurveParamAtPoint( nStartRib, EgtSP( vAssociatedRibs[i]), 100 * GEO.EPS_SMALL) + local tRib = { nId = vAssociatedRibs[i], bStart = true, bOn = true, dPar = dPar} + table.insert( tabUserLink, tRib) + end + + -- recupero alcune info utili relative a UserLink + local bCCW = EgtGetInfo( vAssociatedRibs[1], KEY_RIBS_USER_LINK_CCW, 'b') or false + local bLoopRib = EgtGetInfo( vAssociatedRibs[1], KEY_LOOP_RIB, 'b') or false + local bSameSide = EgtGetInfo( vAssociatedRibs[1], KEY_RIBS_USER_LINK_SAME_SIDE, 'b') or false + local sName = EgtGetName( vAssociatedRibs[1]) + + -- assegno le proprietà + AssignUserLinkInfo( tabUserLink, bCCW, bLoopRib, bSameSide, sName) + end + end + + -- verifico se tra i setti singoli rimasti posso trovare nuovi UserLink + for i = 1, #vRibs do + if not vUsed[vRibs[i]] then + -- indico il corrente come utilizzato per non ricontrollarlo in FindAssociatedUserLinkParts + vUsed[vRibs[i]] = 1 + + -- verifico se trovo setti associati ( e quindi definisce UserLink) + local nStartRib = EgtGetInfo( vRibs[i], KEY_START_RIB, 'i') + local vSingleRibs = {} + local nType = EgtGetInfo( vRibs[i], KEY_RIBS_TYPE, 'i') + local nSrfTest = EgtIf( nType == RIB_TYPE.EXTERNAL, nSrfExt, nSrfInt) + local tabUserLink = FindAssociatedUserLinkParts( nStartRib, vRibs, vUsed, nGrpTmp, nType, nSrfTest) + + if #tabUserLink > 0 then + -- se definisce UserLink aggiungo setto di partenza alla tabella + local dPar = EgtCurveParamAtPoint( nStartRib, EgtSP( vRibs[i]), 100 * GEO.EPS_SMALL) + local tRib = { nId = vRibs[i], bStart = true, bOn = true, dPar = dPar} + table.insert( tabUserLink, tRib) + + -- assegno le info + local bCCW = false -- non posso conoscere a priori il verso del collegamento + local bLoopRib = false + local bSameSide = true + local sName = EgtGetName( vRibs[i]) + AssignUserLinkInfo( tabUserLink, bCCW, bLoopRib, bSameSide, sName) + + -- correggo orientamento del link + bCCW = FindRibsUserLinkDirection( tabUserLink[1].nId, tabUserLink[2].nId, vtSlicing) + for i = 1, #tabUserLink do + local nId = tabUserLink[i].nId + EgtSetInfo( nId, KEY_RIBS_USER_LINK_CCW, bCCW) + end + + else + -- se non è UserLink lo rimuovo dalla tabella dei tratti utilizzati per controllarlo nelle iterazioni successive + vUsed[vRibs[i]] = nil + end + end + end + + EgtErase( nGrpTmp) +end + +------------------------------------------------------------------- +local function FindAssociatedHoledRib( vRibs, nCrv) + -- trovo setto di vRibs che poggia su nCrv + if not nCrv then return end + if not vRibs or #vRibs == 0 then return end + + for i = 1, #vRibs do + -- verifico se ha un estremo sulla curva + local ptS = EgtSP( vRibs[i], GDB_ID.ROOT) + local dParS = EgtCurveParamAtPoint( nCrv, ptS, GEO.EPS_SMALL, GDB_RT.GLOB) + if dParS then + return i, true + else + local ptE = EgtEP( vRibs[i], GDB_ID.ROOT) + local dParE = EgtCurveParamAtPoint( nCrv, ptE, GEO.EPS_SMALL, GDB_RT.GLOB) + if dParE then + return i, false + end + end + end + return +end + +------------------------------------------------------------------- +local function FindHoleCurve( pt, vLoopIds) + -- trovo indice della curva di vLoopIds a cui appartiene pt ( in globale) + for i = 1, #vLoopIds do + local dPar = EgtCurveParamAtPoint( vLoopIds[i], pt, GEO.EPS_SMALL, GDB_RT.GLOB) + if dPar then + return i + end + end + return +end + +------------------------------------------------------------------- +local function ReorderHoledRibs( vRibs, tHoles, bInvertOrder) + + local vUserLink = {} -- vettore con gli id dei tratti di UserLink + local tUserLink = {} -- chiave = setto, valore = true/false se userlink oppure no + for i = 1, #vRibs do + local bUserLink = EgtGetInfo( vRibs[i], KEY_RIBS_USER_LINK, 'b') or false + tUserLink[vRibs[i]] = bUserLink + if bUserLink then + table.insert( vUserLink, vRibs[i]) + end + end + + local nRelocatePosFirst = EgtIf( bInvertOrder, GDB_IN.AFTER, GDB_IN.BEFORE) + local nRelocatePos = EgtIf( bInvertOrder, GDB_IN.BEFORE, GDB_IN.AFTER) + + local nIdx = 1 + while nIdx <= #vUserLink do + + local nTot = EgtGetInfo( vUserLink[nIdx], KEY_RIBS_USER_LINK_TOT, 'i') + local nFirst = vUserLink[nIdx] + local nLast = vUserLink[nIdx + nTot - 1] + if bInvertOrder then + -- i tratti di UserLink saranno ordinati in senso opposto + nFirst, nLast = nLast, nFirst + end + + -- primo tratto di UserLink + local vAssRibs = tHoles[nFirst] or {} + for j = #vAssRibs, 1, -1 do + if not tUserLink[vAssRibs[j]] then + EgtRelocateGlob( vAssRibs[j], nFirst, nRelocatePosFirst) + end + end + + -- altri tratti di UserLink + for k = 1, nTot - 1 do + local nCurrIdx = EgtIf( bInvertOrder, nIdx + nTot - 1 - k, nIdx + k) + local vAssRibs = tHoles[vUserLink[nCurrIdx]] or {} + for j = #vAssRibs, 1, -1 do + if not tUserLink[vAssRibs[j]] then + EgtRelocateGlob( vAssRibs[j], nLast, nRelocatePos) + end + end + end + + -- passo al gruppo di UserLink successivo + nIdx = nIdx + nTot + end + +end + +------------------------------------------------------------------- +local function AdjustHoledRibs( nTrimmedRibsGrp) + + local vRibs = EgtGetAllInGroup( nTrimmedRibsGrp) + if not vRibs then return end + + -- recupero i loop della superficie del setto + local nLoopGrp = EgtGetFirstNameInGroup( s_nPartId, RIBS_LOOP_GRP) + + -- individuo catena di setti che è stata interrotta dagli holes partendo dai setti con user link + local bHoles = false + local tHoles = {} + while #vRibs > 0 do + -- cerco il primo setto di tipo UserLink + local nRefRib + for i = 1, #vRibs do + local bUserLink = EgtGetInfo( vRibs[i], KEY_RIBS_USER_LINK, 'b') or false + if bUserLink then + nRefRib = vRibs[i] + table.remove( vRibs, i) + break + end + end + if not nRefRib then break end + local sName = EgtGetName( nRefRib) + + -- verifico se è limitato da un hole + local nOrigSrfId = EgtGetInfo( nRefRib, KEY_ORIGINAL_SURF, 'i') + local vLoopIds = EgtGetNameInGroup( nLoopGrp, SURF_LOOP .. tostring( nOrigSrfId)) + local ptS = EgtSP( nRefRib, GDB_ID.ROOT) + local ptE = EgtEP( nRefRib, GDB_ID.ROOT) + local nIdx = FindHoleCurve( ptS, vLoopIds) + local bStartOrig = true + if not nIdx then + nIdx = FindHoleCurve( ptE, vLoopIds) + bStartOrig = false + end + if nIdx then + tHoles[nRefRib] = {} + -- trovo tutti i setti associati + local nAssIdx, bStart = FindAssociatedHoledRib( vRibs, vLoopIds[nIdx]) + while nAssIdx do + bHoles = true + local nCurrRib = vRibs[nAssIdx] + local ptRef = EgtIf( bStart, EgtEP( nCurrRib, GDB_ID.ROOT), EgtSP( nCurrRib, GDB_ID.ROOT)) + + local bUserLink = EgtGetInfo( nCurrRib, KEY_RIBS_USER_LINK, 'b') or false + if not bUserLink then + -- se non è coinvolto in altro user link assegno lo stesso orientamento e lo stesso nome + if bStartOrig == bStart then + EgtInvertCurve( nCurrRib) + UpdateInvertInfo( nCurrRib) + end + EgtSetName( nCurrRib, sName) + end + + table.insert( tHoles[nRefRib], nCurrRib) + table.remove( vRibs, nAssIdx) + + -- verifico se con l'altro estermo poggia su hole e trovo setto associato + local nIdx = FindHoleCurve( ptRef, vLoopIds) + nAssIdx, bStart = FindAssociatedHoledRib( vRibs, vLoopIds[nIdx]) + end + end end - EgtErase( nGrpTmp) + -- se no holes esco + if not bHoles then return end + + -- riordino + vRibs = EgtGetAllInGroup( nTrimmedRibsGrp) + local bInvertOrder = EgtGetInfo( vRibs[1], KEY_RIBS_INVERT_STRAND_ORDER, 'b') or false + ReorderHoledRibs( vRibs, tHoles, bInvertOrder) + -- gestione per eventuale InvertDirection + local bInvertDir = EgtGetInfo( vRibs[1], KEY_RIBS_INVERT_DIR, 'b') or false + if bInvertDir then + + for nRib1, vAssRibs in pairs( tHoles) do + local nRib2 = vAssRibs[#vAssRibs] + if nRib2 then + + -- se entrambi coinvolti in UserLink scambio le direzioni + local bUserLink1 = EgtGetInfo( nRib1, KEY_RIBS_USER_LINK, 'b') or false + local bUserLink2 = EgtGetInfo( nRib2, KEY_RIBS_USER_LINK, 'b') or false + if bUserLink1 and bUserLink2 then + local bInvert1 = EgtGetInfo( nRib1, KEY_INVERTED_CRV, 'b') or false + local bInvert2 = EgtGetInfo( nRib2, KEY_INVERTED_CRV, 'b') or false + if bInvert1 ~= bInvert2 then + EgtInvertCurve( nRib1) + UpdateInvertInfo( nRib1) + EgtInvertCurve( nRib2) + UpdateInvertInfo( nRib2) + end + end + + -- scambio le info + SwapInfo( nRib1, nRib2, KEY_RIBS_USER_LINK, 'b', false) + SwapInfo( nRib1, nRib2, KEY_RIBS_USER_LINK_ORDER, 'i', 0) + SwapInfo( nRib1, nRib2, KEY_RIBS_USER_LINK_TOT, 'i', 0) + SwapInfo( nRib1, nRib2, KEY_RIBS_USER_LINK_CCW, 'b', false) + + -- scambio la posizione + local nCopy = EgtCopyGlob( nRib2, nRib2, GDB_IN.AFTER) + EgtRelocateGlob( nRib2, nRib1, GDB_IN.AFTER) + EgtRelocateGlob( nRib1, nCopy, GDB_IN.AFTER) + EgtErase( nCopy) + end + end + end end ------------------------------------------------------------------- @@ -544,16 +929,18 @@ local function TrimRibs( vRibs, nRibsGrp, nSrf, dSrfOffs, vtSlicing) -- trim dei setti local nTrimmedRibsGrp = EgtGroup( nRibsGrp) + local tUserLink = {} -- tratti appartenenti a UserLink + local vSingleRibs = {} -- tratti singoli for i = 1, #vRibs do - local nCopyRib = EgtCopyGlob( vRibs[i], nTrimmedRibsGrp) + -- trim dei setti local nType = EgtGetInfo( vRibs[i], KEY_RIBS_TYPE, 'i') + local nCopyRib = EgtCopyGlob( vRibs[i], nTrimmedRibsGrp) - local nCrv, nCnt + local nCrv, nCnt if nType == RIB_TYPE.INTERNAL or nType == RIB_TYPE.SUPPORT then if EgtSurfFrChunkCount( nSrfInt) == 0 then -- se la superficie non esiste, il setto deve essere cancellato - EgtErase( nCopyRib) - nCrv = GDB_ID.NULL + nCrv = nCopyRib nCnt = 0 else nCrv, nCnt = EgtTrimCurveWithRegion( nCopyRib, nSrfInt, true, true) @@ -578,18 +965,41 @@ local function TrimRibs( vRibs, nRibsGrp, nSrf, dSrfOffs, vtSlicing) nCnt = 1 end - for nId = nCrv, nCrv + nCnt - 1 do - EgtSetInfo( nId, KEY_START_RIB, vRibs[i]) - -- se originale era chiusa ma è stata spezzata dopo il trim è il caso di LoopRib - if EgtCurveIsClosed( vRibs[i]) and nCnt > 1 then - EgtSetInfo( nId, KEY_LOOP_RIB, 1) + if nCnt == 0 then + -- il setto va eliminato + EgtErase( nCrv) + elseif nCnt == 1 then + -- tratto singolo + EgtSetInfo( nCrv, KEY_START_RIB, vRibs[i]) + table.insert( vSingleRibs, nCrv) + EgtSetInfo( vRibs[i], KEY_ASSOCIATED_CRVS, {nCrv}) + else + -- UserLink + tUserLink[vRibs[i]] = {} + local bCCW = FindRibsUserLinkDirection( nCrv, nCrv + 1, vtSlicing) + -- sistemo le info + for j = 0, nCnt - 1 do + EgtSetInfo( nCrv + j, KEY_START_RIB, vRibs[i]) + EgtSetInfo( nCrv + j, KEY_RIBS_USER_LINK, 1) + EgtSetInfo( nCrv + j, KEY_RIBS_USER_LINK_ORDER, j) + EgtSetInfo( nCrv + j, KEY_RIBS_USER_LINK_TOT, nCnt) + EgtSetInfo( nCrv + j, KEY_RIBS_USER_LINK_CCW, bCCW) + -- se setto di partenza è chiuso è LoopRib + if EgtCurveIsClosed( vRibs[i]) then EgtSetInfo( nCrv + j, KEY_LOOP_RIB, 1) end + -- se ho solo due tratti allora il link è realizzato da un solo lato + if nCnt == 2 then EgtSetInfo( nCrv + j, KEY_RIBS_USER_LINK_SAME_SIDE, 1) end + table.insert( tUserLink[vRibs[i]], nCrv + j) end + EgtSetInfo( vRibs[i], KEY_ASSOCIATED_CRVS, tUserLink[vRibs[i]]) end - -- verifico se link definito dall'utente e ne analizzo le proprietà - CheckRibUserLink( nCrv, nCnt, vtSlicing) - end + -- verifico e sistemo UserLink + AdjustUserLinkRibs( tUserLink, vSingleRibs, vtSlicing, nSrfInt, nSrfExt) + + -- verifico se necessari aggiustamenti per holes + AdjustHoledRibs( nTrimmedRibsGrp) + return nTrimmedRibsGrp end @@ -608,7 +1018,6 @@ local function ComputeRibsOrientedOffset( nRibsGrp, dStrand) -- 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 @@ -633,6 +1042,7 @@ local function ComputeRibsOrientedOffset( nRibsGrp, dStrand) end end + local vOffsRib = {} for k = 0, nShellsNbr - 1 do local dOffsCurr = dOffs - k * dStrand local nNewId @@ -648,8 +1058,11 @@ local function ComputeRibsOrientedOffset( nRibsGrp, dStrand) EgtSetInfo( nNewId, KEY_ORIGINAL_RIB, vIds[i]) EgtRelocateGlob( nNewId, nOffsGrp) table.insert( vOffs, nNewId) + table.insert( vOffsRib, nNewId) end end + + EgtSetInfo( vIds[i], KEY_ASSOCIATED_CRVS, vOffsRib) end -- ordinamento @@ -674,7 +1087,7 @@ local function ComputeRibsOrientedOffset( nRibsGrp, dStrand) 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 + if ( nShellsNbr % 2 == 0 and ( not bInvertOrder or nLinkTot % 2 ~= 0)) or ( nShellsNbr % 2 ~= 0 and bInvertOrder) then bInvertCrv = not bInvert end else @@ -754,6 +1167,7 @@ local function VerifyRibsIntersection( nRib1, nRib2, nType1, nType2, nSrf1, nSrf return false end -- se hanno lo stesso nome derivano dalla stessa costolatura quindi non ha senso controllare intersezione + -- ( non vengono gestiti setti che si autointersecano) if EgtGetName( nRib1) == EgtGetName( nRib2) then return false end @@ -902,13 +1316,13 @@ local function AdjustRibsOffsetForIntersection2Shells( nCrv1, nCrv2, LayerParams end -- trim degli offset di nCrv1 - local vOffs1 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv1)) + local vOffs1 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv1)) or {} for i = 1, #vOffs1 do local nId, nCnt = EgtTrimCurveWithRegion( vOffs1[i], nSrf2, false, true) end -- trim degli offset di nCrv2 - local vOffs2 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv2)) + local vOffs2 = EgtGetNameInGroup( nOffsGrp, EgtGetName( nCrv2)) or {} for i = 1, #vOffs2 do local nId, nCnt = EgtTrimCurveWithRegion( vOffs2[i], nSrf1, false, true) end @@ -920,6 +1334,7 @@ end ------------------------------------------------------------------ local function UpdateSplitOrder( nCrv, tInters, nOffsGrp) + local nOrder = EgtGetInfo( nCrv, KEY_SPLIT_ORDER, 'i') or 0 local nNewOrder = nOrder + 1 @@ -1053,6 +1468,8 @@ local function ReorderSplitRibs( vIds, dStrand, bParamInvertOrder) tabRibs[nOrigId] = { vIds[i]} end end + + local tUserLinkSameSide = {} for k, tabVal in pairs( tabRibs) do @@ -1137,33 +1554,47 @@ local function ReorderSplitRibs( vIds, dStrand, bParamInvertOrder) local bUserLink = EgtGetInfo( tAssociatedRibs[1][1], KEY_RIBS_USER_LINK, 'b') or false if bUserLink and nShells % 2 == 0 then + local bSameSide = EgtGetInfo( tAssociatedRibs[1][1], KEY_RIBS_USER_LINK_SAME_SIDE, 'b') or false 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 + if bSameSide and nTotParts > 2 then + -- salvo gli id che andaranno collegati nella tabella tUserLinkSameSide + local sName = EgtGetName( tAssociatedRibs[1][1]) + -- eventuale creazione della voce nella tabella + if not tUserLinkSameSide[sName] then + tUserLinkSameSide[sName] = {} + end + for i = 1, #tAssociatedRibs[1] do + table.insert( tUserLinkSameSide[sName], tAssociatedRibs[1][i]) + end + + else + -- 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 - 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]) + + -- 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 @@ -1171,6 +1602,13 @@ local function ReorderSplitRibs( vIds, dStrand, bParamInvertOrder) end end + for k, vRibs in pairs( tUserLinkSameSide) do + table.sort( vRibs) + for i = 2, #vRibs do + EgtRelocateGlob( vRibs[i], vRibs[i-1], GDB_IN.AFTER) + end + end + end -------------------------------------------------------------------- @@ -1552,7 +1990,7 @@ local function CalcRibsPaths( nSliceGrp, nRibsGrp, LayerParams, vPtStart) 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_SPECIAL_CASE, bSpecialCase) - + -- trim dei setti con le regioni offsettate secondo opportuno overlap local vRibs = EgtGetNameInGroup( nRibsPathGrp, RIBS_CRV ..'*') or {} for i = 1, #vRibs do @@ -2239,7 +2677,7 @@ function CalcPaths.Exec( nPartId) local LayerParams = GetLayerParamsForPathCalc() -- scorro tutti i suoi layer for nIdx = 1, #vLayIds do - + s_nCurrIdx = nIdx local nRibsGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], RIBS_GRP) diff --git a/LuaLibs/CalcSlices.lua b/LuaLibs/CalcSlices.lua index ec59d92..485f291 100644 --- a/LuaLibs/CalcSlices.lua +++ b/LuaLibs/CalcSlices.lua @@ -15,6 +15,13 @@ local AMD = require( 'AddManData') --------------------------------------------------------------------- local s_nPartId +-- costanti +local TOLER = 0.05 +local MID_TOLER = 0.1 +local BIG_TOLER = 2.0 +local MIN_LEN = 20.0 +local MIN_AREA = 25.0 + --------------------------------------------------------------------- local function ComputeZSlices( dSliceStep, dZmin, dDeltaZ, dZmax) @@ -70,6 +77,47 @@ local function ComputeMaxH( vIds, frSlicing, HMax, dSliceStep) return GEO.INFINITO end +-------------------------------------------------------------------- +local function ReadParam( nId, sKey, sType, defVal, table) + -- verifico se info nell'oggetto specifico + local info = EgtGetInfo( nId, sKey, sType) + -- altrimenti recupero info dai parametri generali + if info == nil then info = EgtGetInfo( s_nPartId, sKey, sType) end + -- o assegno valore di default + if info == nil then info = defVal end + + -- se presente, inserisco l'info nella tabella + if table then table[sKey] = info end + + return info +end + +-------------------------------------------------------------------- +local function ExtractRibsLoops( nRibsGrp, nStmId) + + local nLoopGrp = EgtGroup( s_nPartId) + EgtSetName( nLoopGrp, RIBS_LOOP_GRP) + EgtSetStatus( nLoopGrp, GDB_ST.OFF) + + -- recupero tutti i setti + local vIds = EgtGetAllInGroup( nRibsGrp) + for i = 1, #vIds do + -- se trimesh + if EgtGetType( vIds[i]) == GDB_TY.SRF_MESH then + -- trim con il solido + local nCopy = EgtCopyGlob( vIds[i], nLoopGrp) + local nType = ReadParam( vIds[i], KEY_RIBS_TYPE, 'i', RIB_TYPE.INTERNAL) + EgtSurfTmCut( nCopy, nStmId, nType ~= RIB_TYPE.EXTERNAL, false) + -- estraggo i contorni + local nCrv, nCnt = EgtExtractSurfTmLoops( nCopy, nLoopGrp) + -- assegno nome che permetta di ricondurli alla superficie da cui derivano + for nId = nCrv, nCrv + nCnt - 1 do + EgtSetName( nId, SURF_LOOP .. tostring( vIds[i])) + end + end + end +end + -------------------------------------------------------------------- local function AdjustAuxSolids( nSolidsLay) @@ -105,21 +153,6 @@ local function AdjustAuxSolids( nSolidsLay) EgtErase( nGrpTmp) end --------------------------------------------------------------------- -local function ReadParam( nId, sKey, sType, defVal, table) - -- verifico se info nell'oggetto specifico - local info = EgtGetInfo( nId, sKey, sType) - -- altrimenti recupero info dai parametri generali - if info == nil then info = EgtGetInfo( s_nPartId, sKey, sType) end - -- o assegno valore di default - if info == nil then info = defVal end - - -- se presente, inserisco l'info nella tabella - if table then table[sKey] = info end - - return info -end - -------------------------------------------------------------------- local function GetRibParams( nId) @@ -267,24 +300,34 @@ local function SlicingExtraObjects( vtSlicing, nLay, nType, sNameGrp, sName, vEr end if nNewId then + -- rimuovo punti for nId = nNewId, nNewId + nPntCnt -1 do EgtErase( nId) end + -- concateno le curve + local vChain = {} + for nId = nNewId + nPntCnt, nNewId + nPntCnt + nCrvCnt - 1 do + table.insert( vChain, nId) + end + local nChainId, nCnt = EgtCurveCompoByChain( nGrp, vChain, ORIG(), true, GDB_RT.LOC, BIG_TOLER) -- rinomino le curve, correggo di DeltaZ e assegno parametri for nId = nNewId + nPntCnt, nNewId + nPntCnt + nCrvCnt - 1 do EgtSetName( nId, sName .. tostring( i)) EgtMove( nId, - ( dDeltaZ + dCorr) * vtSlicing) + EgtSetInfo( nId, KEY_ORIGINAL_SURF, vIds[i]) for sKey, sVal in pairs( tabParams[i]) do EgtSetInfo( nId, sKey, sVal) end + -- se ho ancora curve aperte, segnalo errore if nType ~= TYPE.RIB and not EgtCurveIsClosed( nId) then EgtOutLog( 'Error : hole in object (layer '.. EgtNumToString( nLayCnt) ..') - CalcSlices') table.insert( vErr, nLayCnt) end end + -- rimuovo superfici for nId = nNewId + nPntCnt + nCrvCnt, nNewId + nPntCnt + nCrvCnt + nSrfCnt - 1 do EgtErase( nId) @@ -352,13 +395,6 @@ end --------------------------------------------------------------------- local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicing, vErr) - - -- costanti - local TOLER = 0.05 - local MID_TOLER = 0.1 - local BIG_TOLER = 2.0 - local MIN_LEN = 20.0 - local MIN_AREA = 25.0 local vtSlicing = frSlicing:getVersZ() @@ -625,6 +661,7 @@ local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicin -- costolature local nRibsLay = EgtGetFirstNameInGroup( s_nPartId, LAY_RIBS) if nRibsLay then + ExtractRibsLoops( nRibsLay, nStmId) SlicingExtraObjects( vtSlicing, nRibsLay, TYPE.RIB, RIBS_GRP, RIBS_CRV, vErr, nStmId) end if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vZSlices + 1) / ( #vZSlices + 3) * 100, 0) == 1 then return false end diff --git a/LuaLibs/CalcToolPath.lua b/LuaLibs/CalcToolPath.lua index eae9490..8e2ae21 100644 --- a/LuaLibs/CalcToolPath.lua +++ b/LuaLibs/CalcToolPath.lua @@ -349,18 +349,25 @@ local function AddRetraction( nCrvId, vtSlicing, dCoastingLen, dWipeLen, dWipeDi nCopyId = nil EgtTrimCurveEndAtLen( nWipeId, dWipeLen) else - -- se extra shell, infill a zigzag, spiral vase o rib che non termina sulla parete local vtDir = EgtEV( nCoastingId or nCrvId, GDB_ID.ROOT) local dAng = dWipeDir + s_nDefaultWipeAng -- verifico se necessario cambiare il segno all'angolo local bChangeSign = false + -- riempimento if nType == TYPE.INFILL or nType == TYPE.AUX_SOLID then local vtS = EgtGetInfo( nCrvId, KEY_ZIG_ZAG_DIR, 'v') local bSameDir = AreSameVectorApprox( vtS, vtDir) bChangeSign = ( bInverted == bSameDir) - else + -- rib + elseif nType == TYPE.RIB then + local bInvertStrandOrder = EgtGetInfo( nCrvId, KEY_RIBS_INVERT_STRAND_ORDER, 'b') or false + local bInvertDir = EgtGetInfo( nCrvId, KEY_RIBS_INVERT_DIR, 'b') or false + bChangeSign = ( bInvertDir ~= bInvertStrandOrder) + -- extra shell + elseif nType == TYPE.EXTRA_SHELL or nType == TYPE.EXTRA_OUTER_SHELL then bChangeSign = bInverted end + vtDir:rotate( vtSlicing, EgtIf( bChangeSign, - dAng, dAng)) local ptS = EgtEP( nCoastingId or nCrvId, GDB_ID.ROOT) local ptE = FindWipeEndPoint( ptS, vtDir, dWipeLen, vtSlicing) @@ -1038,7 +1045,7 @@ local function CalcRibsToolPath( vEntIds, nRibsGrp, nTpathGrpId, LayerParams) else local bLoopRib = EgtGetInfo( tabRibs[i][1], KEY_LOOP_RIB, 'b') or false for j = 1, #tabRibs[i] - 1 do - local bUserLink = EgtGetInfo( tabRibs[i][j], KEY_RIBS_USER_LINK, 'b') or false + local bUserLink = ( EgtGetInfo( tabRibs[i][j], KEY_RIBS_USER_LINK, 'b') or false) and ( EgtGetInfo( tabRibs[i][j+1], KEY_RIBS_USER_LINK, 'b') or false) local nOrig1 = EgtGetInfo( tabRibs[i][j], KEY_ORIGINAL_RIB, 'i') or 0 local nOrig2 = EgtGetInfo( tabRibs[i][j + 1], KEY_ORIGINAL_RIB, 'i') or 0 local nSplitId1 = EgtGetInfo( tabRibs[i][j], KEY_SPLIT_ID, 'i') or 0 diff --git a/LuaLibs/RunSlicing.lua b/LuaLibs/RunSlicing.lua index 6dc72d4..eebe3bb 100644 --- a/LuaLibs/RunSlicing.lua +++ b/LuaLibs/RunSlicing.lua @@ -66,6 +66,12 @@ local function RemoveOldSlices( nPartId) EgtErase( vOldSliceId[i]) end end + + -- rimuovo gruppo con i loop dei setti + local nRibsLoopsGrp = EgtGetFirstNameInGroup( nPartId, RIBS_LOOP_GRP) + if nRibsLoopsGrp then + EgtErase( nRibsLoopsGrp) + end end --------------------------------------------------------------------- diff --git a/Version.lua b/Version.lua index e1aef03..0cbaf3c 100644 --- a/Version.lua +++ b/Version.lua @@ -1,4 +1,4 @@ -- Version.lua by Egaltech s.r.l. 2023/02/28 -- Gestione della versione di 3dPrinting -VERSION = '2.5d1' \ No newline at end of file +VERSION = '2.5d3' \ No newline at end of file