diff --git a/LuaLibs/AddManData.lua b/LuaLibs/AddManData.lua index 40f31ef..ced5da4 100644 --- a/LuaLibs/AddManData.lua +++ b/LuaLibs/AddManData.lua @@ -48,8 +48,6 @@ KEY_SPIRAL_VASE = "SpiralVase" KEY_SPIRAL_VASE_LEN = 'SpiralVaseLen' KEY_SPIRAL_VASE_INTERP_LEN = 'SpiralVaseInterpLen' KEY_SLICING_TYPE = "SlicingType" -KEY_SLICE_DIR = "SliceDir" -KEY_SLICE_POS = "SlicePos" KEY_SLICE_STEP = "StrandH" KEY_SHELLS_NBR = "StrandCount" KEY_STRAND = "StrandW" @@ -190,9 +188,9 @@ KEY_LINEAR_TOL = 'LinearTol' KEY_MAX_H = "SlicingHeight" KEY_MAX_SLICES_NBR = "MaxSlicesNumber" KEY_SLICE_NBR = "SliceNbr" -KEY_SLICE_Z = "SliceZ" +KEY_SLICE_DIR = "SliceDir" +KEY_SLICE_POS = "SlicePos" KEY_SLICE_DELTAZ = "DeltaZ" -KEY_SLICE_REAL_Z = "SliceRealZ" KEY_ZIG_ZAG_INFILL = "ZigZagInfill" KEY_ZIG_ZAG_DIR = "ZigZagDir" KEY_INVERTED_CRV = "InvertedCrv" diff --git a/LuaLibs/CalcPaths.lua b/LuaLibs/CalcPaths.lua index 606ba22..359eb2f 100644 --- a/LuaLibs/CalcPaths.lua +++ b/LuaLibs/CalcPaths.lua @@ -116,19 +116,13 @@ end --------------------------------------------------------------------- local function GetLayerStartPoint( nLayId) - - -- recupero quota layer - local dZ = EgtGetInfo( nLayId, KEY_SLICE_REAL_Z, 'd') - local dDeltaZ = EgtGetInfo( nLayId, KEY_SLICE_DELTAZ, 'd') - local frSlicing = Frame3d( ORIG(), s_vtSlicing) - local ptOn = Point3d( 0, 0, dZ + dDeltaZ) - ptOn:toGlob( frSlicing) - + -- gruppo temporaneo dove salvo i risultati local nGrpTmp = EgtGroup( nLayId) local vPtStart = {} local nMachStartGrp = EgtGetFirstNameInGroup( s_nPartId, LAY_MACH_START) + local ptOn = EgtGetInfo( nLayId, KEY_SLICE_POS, 'p') local nStartId = EgtGetFirstInGroup( nMachStartGrp) while nStartId do local nType = EgtGetType( nStartId) diff --git a/LuaLibs/CalcSlices.lua b/LuaLibs/CalcSlices.lua index 605ae87..cec45bf 100644 --- a/LuaLibs/CalcSlices.lua +++ b/LuaLibs/CalcSlices.lua @@ -23,33 +23,70 @@ local MID_TOLER = 0.1 local BIG_TOLER = 2.0 local MIN_LEN = 20.0 local MIN_AREA = 25.0 +local DELTAZ = 10 * GEO.EPS_SMALL + --------------------------------------------------------------------- -local function ComputeZSlices( dSliceStep, dZmin, dDeltaZ, dZmax) +local function ComputeSlicingData( vIds, vtSlicing, dSliceStep, dMaxH, nMaxSlicesNbr) + -- la direzione di slicing è vtSlicing per tutti gli slices + -- i valori di slicing sono le distanze dall'origine dei piani di slicing misurate in direzione vtSlicing - -- verifico se è impostato un numero massimo di slices - local nMaxSlicesNbr = EgtGetInfo( s_nPartId, KEY_MAX_SLICES_NBR, 'i') or 0 - if nMaxSlicesNbr == 0 then - nMaxSlicesNbr = GEO.INFINITO -- da gestire come caso illimitato + local vSlicingDir = { vtSlicing} + -- ricavo le z a cui calcolare gli slices + local frSlicing = Frame3d( ORIG(), vtSlicing) + local b3Box = BBox3d() + for i = 1, #vIds do + local b3Tmp = EgtGetBBoxRef( vIds[i], GDB_BB.STANDARD, frSlicing) + b3Box:Add( b3Tmp) end - + local dZmin = b3Box:getMin():getZ() + local dZmax = min( b3Box:getMax():getZ(), dMaxH) + local nCnt = 1 - local ptSlices = { dZmin + dDeltaZ} + local vZSlices = { dZmin + DELTAZ} local dPosZ = dZmin + dSliceStep while dPosZ < dZmax and nCnt < nMaxSlicesNbr do - table.insert( ptSlices, dPosZ) + table.insert( vZSlices, dPosZ) dPosZ = dPosZ + dSliceStep nCnt = nCnt + 1 - end - return ptSlices + end + return vZSlices, vSlicingDir end +--------------------------------------------------------------------- +local function ComputeMultiplanarSlicingData( dSliceStep, nMaxSlicesNbr) + -- le direzioni e i valori di slicing sono le normali e i punti che definiscono i piani di slicing e vengono calcolati sulla curva "Spine" + + -- recupero la curva guida + local nAuxLayId = EgtGetFirstNameInGroup( s_nPartId, LAY_AUX) + local nSpineId = EgtGetFirstNameInGroup( nAuxLayId or GDB_ID.NULL, SPINE_CURVE) + if not nSpineId or ( EgtGetType( nSpineId) & GDB_FY.GEO_CURVE) == 0 then + return nil + end + + local vSlicingDir = {} + local vSlicingPnt = {} + -- ciclo sulla curva + local nCnt = 0 + local dCrvLen = EgtCurveLength( nSpineId) + for i = 0, nMaxSlicesNbr - 1 do + local dCurrLen = i * dSliceStep + if dCurrLen > dCrvLen then + break + end + local dU = EgtCurveParamAtLength( nSpineId, dCurrLen) + vSlicingDir[i+1] = EgtUV( nSpineId, dU, -1, GDB_ID.ROOT) + vSlicingPnt[i+1] = EgtUP( nSpineId, dU, GDB_ID.ROOT) + end + + return vSlicingPnt, vSlicingDir +end -------------------------------------------------------------------- -local function ComputeMaxH( vIds, frSlicing, dSliceStep) +local function ComputeMaxH( vIds, vtSlicing, dSliceStep) local HMax = EgtGetInfo( s_nPartId, KEY_MAX_H, 'd') or GEO.INFINITO if HMax < GEO.EPS_SMALL then - HMax = GEO.INFINITO + return GEO.INFINITO end -- calcolo il box globale @@ -60,14 +97,16 @@ local function ComputeMaxH( vIds, frSlicing, dSliceStep) end EgtSetInfo( s_nPartId, KEY_BOX_MIN_Z, b3BoxGlob:getMin():getZ()) - if b3BoxGlob:getMax():getZ() < b3BoxGlob:getMin():getZ() + HMax + GEO.EPS_SMALL then + -- se il pezzo non è più alto della quota massima, posso ignorarla + if b3BoxGlob:getMax():getZ() < HMax + GEO.EPS_SMALL then return GEO.INFINITO end - if AreSameVectorApprox( frSlicing:getVersZ(), Z_AX()) then + if AreSameVectorApprox( vtSlicing, Z_AX()) then + -- se slicing verticale o multiplanare l'altezza è quella letta return HMax - else - -- se slicing inclinato + else + -- se slicing inclinato calcolo l'altezza massima rispetto alle quote di slicing local nGrpTmp = EgtGroup( s_nPartId) for i = 1, #vIds do EgtPlaneSurfTmInters( Point3d( 0, 0, HMax), Z_AX(), vIds[i], nGrpTmp, GDB_RT.GLOB) @@ -81,8 +120,9 @@ local function ComputeMaxH( vIds, frSlicing, dSliceStep) local ptMax = b3Box:getMax() -- la quota dell'ultimo slice è più bassa di dSliceStep rispetto alla quota dell'ultimo toolpath -- ( andrebbe anche considerata dCorrZ) - ptMin = ptMin - dSliceStep * frSlicing:getVersZ() - ptMax = ptMax - dSliceStep * frSlicing:getVersZ() + ptMin = ptMin - dSliceStep * vtSlicing + ptMax = ptMax - dSliceStep * vtSlicing + local frSlicing = Frame3d( ORIG(), vtSlicing) ptMin:toLoc( frSlicing) ptMax:toLoc( frSlicing) @@ -92,7 +132,9 @@ local function ComputeMaxH( vIds, frSlicing, dSliceStep) return GEO.INFINITO end --------------------------------------------------------------------- +---------------------------------------------------------------------- +-------------------- SLICING EXTRA OBJECTS --------------------------- +---------------------------------------------------------------------- local function ReadParam( nId, sKey, sType, defVal, table) -- verifico se info nell'oggetto specifico local info = EgtGetInfo( nId, sKey, sType) @@ -177,13 +219,12 @@ local function GetAuxSolidsParams( nId) return AuxSolidsParam end ----------------------------------------------------------------------- --------------------- SLICING EXTRA OBJECTS --------------------------- ----------------------------------------------------------------------- -local function SliceStm( vIds, nLayId, vtSlicing, nType, sName, sNameGrp, tabParams) +-------------------------------------------------------------------- +local function SliceStm( vIds, nLayId, vtSlicing, ptSlicing, nType, sName, sNameGrp, tabParams) if not vIds or #vIds == 0 then return end + local nLayCnt = EgtGetInfo( nLayId, KEY_SLICE_NBR, 'i') -- recupero il gruppo dove salvare lo slicing degli oggetti local nGrp = EgtGetFirstNameInGroup( nLayId, sNameGrp) if not nGrp then @@ -192,22 +233,17 @@ local function SliceStm( vIds, nLayId, vtSlicing, nType, sName, sNameGrp, tabPar EgtSetName( nGrp, sNameGrp) EgtSetStatus( nGrp, GDB_ST.OFF) end - + -- recupero quota per slicing - local dZ = EgtGetInfo( nLayId, KEY_SLICE_REAL_Z, 'd') local dDeltaZ = EgtGetInfo( nLayId, KEY_SLICE_DELTAZ, 'd') - local nLayCnt = EgtGetInfo( nLayId, KEY_SLICE_NBR, 'i') - - -- gruppo temporaneo per approx curve - local frloc = Frame3d( ORIG(), vtSlicing) - local nGrpTmp = EgtGroup( nLayId, frloc, GDB_RT.GLOB) + local ptOn = ptSlicing + dDeltaZ * vtSlicing for i = 1, #vIds do -- verifico che oggetto sia trimesh local nTypeObj = EgtGetType( vIds[i]) if nTypeObj == GDB_TY.SRF_MESH then -- slicing oggetto - local nNewId, nPntCnt, nCrvCnt, nSrfCnt = EgtPlaneSurfTmInters( ORIG() + ( dZ + dDeltaZ) * vtSlicing, vtSlicing, vIds[i], nGrp, GDB_RT.GLOB, TOLER) + local nNewId, nPntCnt, nCrvCnt, nSrfCnt = EgtPlaneSurfTmInters( ptOn, vtSlicing, vIds[i], nGrp, GDB_RT.GLOB, TOLER) -- verifico se necessario ricalcolo local dCorr = 0 @@ -228,7 +264,7 @@ local function SliceStm( vIds, nLayId, vtSlicing, nType, sName, sNameGrp, tabPar EgtErase( j) end dCorr = 0.01 - nNewId, nPntCnt, nCrvCnt, nSrfCnt = EgtPlaneSurfTmInters( ORIG() + ( dZ + dDeltaZ + dCorr) * vtSlicing, vtSlicing, vIds[i], nGrp, GDB_RT.GLOB, TOLER) + nNewId, nPntCnt, nCrvCnt, nSrfCnt = EgtPlaneSurfTmInters( ptOn + dCorr * vtSlicing, vtSlicing, vIds[i], nGrp, GDB_RT.GLOB, TOLER) end if nNewId then @@ -260,9 +296,7 @@ local function SliceStm( vIds, nLayId, vtSlicing, nType, sName, sNameGrp, tabPar end end EgtModifyCurveExtrusion( nId, vtSlicing, GDB_RT.GLOB) - EgtRelocateGlob( nId, nGrpTmp) EgtApproxCurve( nId, GDB_CA.ARCS, MID_TOLER) - EgtRelocateGlob( nId, nGrp) -- se ho ancora curve aperte, segnalo errore if nType ~= TYPE.RIB and nType ~= TYPE.INFILL and not EgtCurveIsClosed( nId) then @@ -282,12 +316,14 @@ local function SliceStm( vIds, nLayId, vtSlicing, nType, sName, sNameGrp, tabPar -- verifico che il gruppo non sia vuoto if not EgtGetFirstInGroup( nGrp) then EgtErase( nGrp) + nGrp = nil end - EgtErase( nGrpTmp) + + return nGrp end -------------------------------------------------------------------- -local function SlicingExtraObjects( nLay, vtSlicing, nType, sName, sNameGrp, nStmId) +local function SlicingExtraObjects( nLay, nType, sName, sNameGrp, nStmId) if not nLay then return end @@ -340,19 +376,20 @@ local function SlicingExtraObjects( nLay, vtSlicing, nType, sName, sNameGrp, nSt -- per ogni layer calcolo lo slicing degli oggetti local vLayIds = EgtGetNameInGroup( s_nPartId, SLICE_LAYER .. '*') for i = 1, #vLayIds do - SliceStm( vSliceIds, vLayIds[i], vtSlicing, nType, sName, sNameGrp, tabParams) + -- ricavo piano di slicing + local ptSlicing = EgtGetInfo( vLayIds[i], KEY_SLICE_POS, 'p') + local vtSlicing = EgtGetInfo( vLayIds[i], KEY_SLICE_DIR, 'v') + SliceStm( vSliceIds, vLayIds[i], vtSlicing, ptSlicing, nType, sName, sNameGrp, tabParams) end -- rimuovo eventuali oggetti creati per lo slicing - for i = 1, #vEraseIds do - EgtErase( vEraseIds[i]) - end + EgtErase( vEraseIds) return true end ------------------------------------------------------------------------ -local function SlicingInfill( nLay, vtSlicing, sName, sNameGrp) +local function SlicingInfill( nLay, sName, sNameGrp) -- recupero tutte le curve di infill suddivise per direzioni di riferimento local vInfillGrps = EgtGetAllInGroup( nLay) @@ -362,10 +399,6 @@ local function SlicingInfill( nLay, vtSlicing, sName, sNameGrp) table.insert( tIds, vIds) end local nGrps = #vInfillGrps - - -- recupero quota infill - local ptInfill = EgtSP( tIds[1][1], GDB_ID.ROOT) - local dZInfill = ( ptInfill - ORIG()) * vtSlicing local vLayIds = EgtGetNameInGroup( s_nPartId, SLICE_LAYER .. '*') for i = 1, #vLayIds do @@ -373,21 +406,14 @@ local function SlicingInfill( nLay, vtSlicing, sName, sNameGrp) -- individuo il gruppo di cui fare slicing local nGrpIdx = ( i - 1) % nGrps + 1 - -- recupero il gruppo dove salvare gli infill - local nGrp = EgtGetFirstNameInGroup( vLayIds[i], sNameGrp) - if not nGrp then - -- se gruppo non esiste lo creo - nGrp = EgtGroup( vLayIds[i]) - EgtSetName( nGrp, sNameGrp) - EgtSetStatus( nGrp, GDB_ST.OFF) - end - - -- copio le curve di infill e le traslo alla quota dello slicing - local dZ = EgtGetInfo( vLayIds[i], KEY_SLICE_REAL_Z, 'd') - for j = 1, #tIds[nGrpIdx] do - local nCrv = EgtCopyGlob( tIds[nGrpIdx][j], nGrp) - EgtSetName( nCrv, sName .. tostring(j)) - EgtMove( nCrv, (dZ - dZInfill) * vtSlicing, GDB_RT.GLOB) + -- recupero i dati di slicing + local ptSlicing = EgtGetInfo( vLayIds[i], KEY_SLICE_POS, 'p') + local vtSlicing = EgtGetInfo( vLayIds[i], KEY_SLICE_DIR, 'v') + local nResultLay = SliceStm( tIds[nGrpIdx], vLayIds[i], vtSlicing, ptSlicing, TYPE.INFILL, sName, sNameGrp) + -- sistemo i nomi delle curve + local vInfillCrvs = EgtGetAllInGroup( nResultLay) + for j = 1, #vInfillCrvs do + EgtSetName( vInfillCrvs[j], sName .. tostring(j)) end end @@ -548,7 +574,7 @@ local function CalcGridFromPattern( nInfillGrp, nStmId, dOffsStm, frRef, vtOffs, EgtAddCurveCompoLine( nCrvBase, pt2) end CompletePatternBaseCrv( nCrvBase, dAng, dDim1, dDim2, ptMin:getY(), ptMax:getY()) - + -- preparo le altre curve CalcPatternCrvs( nMainGrp, nCrvBase, ptMin:getX(), ptMax:getX(), dAng, dDim1, dStrand) @@ -586,7 +612,7 @@ end -------------------------------------------------------------------- local function CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, dGridOverlap, nStmId, dOffsStm, dStrand, vtSlicing) - -- frame locale alla direzione dell'infill + -- frame locale alla direzione dell'infill local frLoc = Frame3d( ORIG(), vtSlicing) frLoc:rotate( ORIG(), vtSlicing, dDir) @@ -626,6 +652,21 @@ local function CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, dG local vSlicesAng = EgtIf( nType == FILL_TYPE.HONEYCOMB, {0}, {0, 60, 120}) CalcGridFromPattern( nInfillGrp, nStmId, dOffsStm, frLoc, vtOffs, dDim1, dDim2, dAng, vSlicesAng, dRealStrand, vtSlicing) end + + -- calcolo le superifici a partire dalle curve ( nei casi standard è semplice estrusione) + local vGrps = EgtGetAllInGroup( nInfillGrp) + local vCrvs = {} + for i = 1, #vGrps do + EgtJoinTables( vCrvs, EgtGetAllInGroup( vGrps[i])) + end + local nLastLay = EgtGetLastNameInGroup( s_nPartId, SLICE_LAYER .. '*') + local ptLast = EgtGetInfo( nLastLay, KEY_SLICE_POS, 'p') + local dZ = ( ptLast - ORIG()) * vtSlicing + for i = 1, #vCrvs do + EgtSurfTmByExtrusion( EgtGetParent( vCrvs[i]), vCrvs[i], ( dZ + 100) * vtSlicing, GDB_RT.GLOB) + end + EgtErase( vCrvs) + end -------------------------------------------------------------------- @@ -660,7 +701,7 @@ local function PrepareInfill( nStmId, vtSlicing) CalcInfill( nInfillGrp, nType, dDensity, dDir, dOffsX, dOffsY, dGridOverlap, nStmId, dOffsStm, dStrand, vtSlicing) -- aggiungo allo slicing - SlicingInfill( nInfillGrp, vtSlicing, INFILL_CRV, INFILL_GRP) + SlicingInfill( nInfillGrp, INFILL_CRV, INFILL_GRP) end ---------------------------------------------------------------------- @@ -697,7 +738,7 @@ local function PrepareAuxSolidsInfill( nSolidsLay, vtSlicing) -- aggiungo allo slicing local sName = AUX_SOLIDS_INFILL_CRV .. tostring( vIds[i]) .. '_' - SlicingInfill( nInfillGrp, vtSlicing, sName, AUX_SOLIDS_GRP) + SlicingInfill( nInfillGrp, sName, AUX_SOLIDS_GRP) end end end @@ -743,93 +784,118 @@ local function ValueInArray( vArr, nValue) end --------------------------------------------------------------------- -local function SlicingNoSolid( nRibsLay, vZSlices, dDeltaZStart, dZmin, frSlicing) - - local vtSlicing = frSlicing:getVersZ() - +local function SlicingNoSolid( nRibsLay, nSlicingType, dMaxH, dSliceStep, vSlicingVal, vSlicingDir) + -- contatore per il calcolo delle intersezioni if EgtProcessEvents( 100, 0) == 1 then return false end - -- creo i layer dello slicing - for i = 1, #vZSlices do - local nLayGrp = EgtGroup( s_nPartId) - EgtSetName( nLayGrp, SLICE_LAYER .. tostring( i)) - - local dDeltaZ = EgtIf( i == 1, dDeltaZStart, 0) - local dPosZ = vZSlices[i]- dDeltaZ - EgtSetInfo( nLayGrp, KEY_SLICE_Z, dPosZ - dZmin) - EgtSetInfo( nLayGrp, KEY_SLICE_REAL_Z, dPosZ) - EgtSetInfo( nLayGrp, KEY_SLICE_DELTAZ, dDeltaZ) - EgtSetInfo( nLayGrp, KEY_SLICE_NBR, i) - - local nGrpCrv = EgtGroup( nLayGrp) - EgtSetName( nGrpCrv, CONTOUR_GRP .. EgtNumToString( 0)) + -- recupero i setti di cui fare lo slicing e i parametri associati + local vRibIds = EgtGetAllInGroup( nRibsLay) + local tabParams = {} + local vIds = {} + for i = 1, #vRibIds do + if EgtGetType( vRibIds[i]) == GDB_TY.SRF_MESH then + local vParams = GetRibParams( vRibIds[i]) + if vParams[KEY_RIBS_SHELLS_NBR] > 0 then + table.insert( tabParams, vParams) + table.insert( vIds, vRibIds[i]) + end + end + end + + -- creo i layer dello slicing + for i = 1, #vSlicingVal do + -- creo layer e gruppo dei contorni + local nLayId = EgtGroup( s_nPartId) + EgtSetName( nLayId, SLICE_LAYER .. tostring( i)) + EgtSetInfo( nLayId, KEY_SLICE_NBR, i) + local nCrvLayId = EgtGroup( nLayId) + EgtSetName( nCrvLayId, CONTOUR_GRP .. EgtNumToString( 0)) + + -- recupero i dati del piano di slicing + local dDeltaZ = EgtIf( i == 1, DELTAZ, 0) + local ptSlicing + local vtSlicing + if nSlicingType == SLICING_TYPE.MULTIPLANAR then + vtSlicing = vtSlicing[i] + ptSlicing = vSlicingVal[i] + else + vtSlicing = vSlicingDir[1] + ptSlicing = ORIG() + ( vSlicingVal[i] - dDeltaZ) * vtSlicing + end + EgtSetInfo( nLayId, KEY_SLICE_POS, ptSlicing) + EgtSetInfo( nLayId, KEY_SLICE_DIR, vtSlicing) + EgtSetInfo( nLayId, KEY_SLICE_DELTAZ, dDeltaZ) + + -- slicing dei setti + local nResultLay = SliceStm( vIds, nLayId, vtSlicing, ptSlicing, TYPE.RIB, RIBS_CRV, RIBS_GRP, tabParams) + + -- se slicing multplanare verifico altezza massima + if nSlicingType == SLICING_TYPE.MULTIPLANAR and dMaxH < GEO.INFINITO then + local b3Box = EgtGetBBoxGlob( nResultLay, GDB_BB.STANDARD) + local ptMax = b3Box:getMax() + dSliceStep * vtSlicing + if ptMax:getZ() > dMaxH + GEO.EPS_SMALL then + EgtErase( nLayId) + break + end + end + + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + i / #vSlicingVal * 100, 0) == 1 then return false end end - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + 20, 0) == 1 then return false end - - -- slicing dei setti - SlicingExtraObjects( nRibsLay, vtSlicing, TYPE.RIB, RIBS_CRV, RIBS_GRP) - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + 100, 0) == 1 then return false end return true end --------------------------------------------------------------------- -local function MultiPlanarSlicing( nStmId) +local function MultiPlanarSlicing( nStmId, dMaxH, vSlicingDir, vSlicingPnt) - -- recupero la curva guida - local nAuxLayId = EgtGetFirstNameInGroup( s_nPartId, LAY_AUX) - local nSpineId = EgtGetFirstNameInGroup( nAuxLayId or GDB_ID.NULL, SPINE_CURVE) - if not nSpineId or ( EgtGetType( nSpineId) & GDB_FY.GEO_CURVE) == 0 then - return nil - end - -- step lungo la curva local dSliceStep = EgtGetInfo( s_nPartId, KEY_SLICE_STEP, 'd') - -- massimo numero di layer da generare - local nMaxSlicesNbr = EgtGetInfo( s_nPartId, KEY_MAX_SLICES_NBR, 'i') or 0 - if nMaxSlicesNbr == 0 then - nMaxSlicesNbr = GEO.INFINITO -- da gestire come caso illimitato - end - -- ciclo sulla curva + -- ciclo sui piani di slicing calcolati local nFirstGrpId - local dCrvLen = EgtCurveLength( nSpineId) - for i = 0, nMaxSlicesNbr - 1 do - local dCurrLen = max( i * dSliceStep, 10 * GEO.EPS_SMALL) - if dCurrLen > dCrvLen then - break + local nCnt = 0 + for i = 1, #vSlicingPnt do + local vtN = vSlicingDir[i] + local ptOn = vSlicingPnt[i] + -- correzione per layer iniziale + if i == 1 then + ptOn = ptOn + DELTAZ * vtN end - local dU = EgtCurveParamAtLength( nSpineId, dCurrLen) - local ptOn = EgtUP( nSpineId, dU, GDB_ID.ROOT) - local vtN = EgtUV( nSpineId, dU, -1, GDB_ID.ROOT) + local nGrpId = EgtGroup( s_nPartId) if not nFirstGrpId then nFirstGrpId = nGrpId end local nEntId = EgtPlaneSurfTmInters( ptOn, vtN, nStmId, nGrpId, GDB_RT.GLOB, TOLER) - EgtSetInfo( nGrpId, KEY_SLICE_DIR, vtN) - EgtSetInfo( nGrpId, KEY_SLICE_POS, ptOn) + -- eventuale verifica con altezza massima + if dMaxH < GEO.INFINITO then + local b3Box = EgtGetBBoxGlob( nGrpId, GDB_BB.STANDARD) + local ptMax = b3Box:getMax() + dSliceStep * vtN + if ptMax:getZ() > dMaxH + GEO.EPS_SMALL then + EgtErase( nGrpId) + break + end + end + nCnt = i + 1 end - return nFirstGrpId + return nFirstGrpId, nCnt end --------------------------------------------------------------------- -local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicing, nSlicingType) +local function SlicingWithSolid( nStmId, nSlicingType, dMaxH, vSlicingVal, vSlicingDir) - local vtSlicing = frSlicing:getVersZ() - -- calcolo delle intersezioni if EgtProcessEvents( 1, 0) == 1 then return false end - local nLayId + local nLayId, nCnt if nSlicingType ~= SLICING_TYPE.MULTIPLANAR then - nLayId = EgtParPlanesSurfTmInters( ORIG(), vtSlicing, vZSlices, nStmId, s_nPartId, GDB_RT.GLOB, TOLER) + nLayId, nCnt = EgtParPlanesSurfTmInters( ORIG(), vSlicingDir[1], vSlicingVal, nStmId, s_nPartId, GDB_RT.GLOB, TOLER) else - nLayId = MultiPlanarSlicing( nStmId) + nLayId, nCnt = MultiPlanarSlicing( nStmId, dMaxH, vSlicingDir, vSlicingVal) end if EgtProcessEvents( 100, 0) == 1 then return false end local vPrevCen = {} local nLayCnt = 1 - local nCounterTot = #vZSlices + 12 + local nCounterTot = nCnt + 12 local nFirstSolidLay -- primo layer che contiene il solido local nLastSolidLay -- ultimo layer che contiene il solido @@ -837,16 +903,25 @@ local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicin -- scorro i risultati dello slicing while nLayId do - local dDeltaZ = EgtIf( nLayCnt == 1, dDeltaZStart, 0) - local dPosZ = vZSlices[nLayCnt]- dDeltaZ - EgtSetInfo( nLayId, KEY_SLICE_Z, dPosZ - dZmin) - EgtSetInfo( nLayId, KEY_SLICE_REAL_Z, dPosZ) EgtSetInfo( nLayId, KEY_SLICE_NBR, nLayCnt) - + + -- ricavo punto e direzione del piano di slicing + local dDeltaZ = EgtIf( nLayCnt == 1, DELTAZ, 0) + local ptSlicing + local vtSlicing if nSlicingType == SLICING_TYPE.MULTIPLANAR then - vtSlicing = EgtGetInfo( nLayId, KEY_SLICE_DIR, 'v') + -- nel caso multiplanare sono i dati di slicing + vtSlicing = vSlicingDir[nLayCnt] + ptSlicing = vSlicingVal[nLayCnt] + else + -- nel caso standard la direzione è è l'unico elemento del vettore direzioni ( visto che è comune a tutti i piani) mentre i valori sono le distanze dai piani da quello + -- posto nell'origine + vtSlicing = vSlicingDir[1] + ptSlicing = ORIG() + ( vSlicingVal[nLayCnt] - dDeltaZ) * vtSlicing end - + EgtSetInfo( nLayId, KEY_SLICE_POS, ptSlicing) + EgtSetInfo( nLayId, KEY_SLICE_DIR, vtSlicing) + -- verifico se necessario ricalcolo local nId = EgtGetLastInGroup( nLayId) local bRecalc = not nId @@ -867,9 +942,10 @@ local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicin if bRecalc then nRecalc = nRecalc + 1 EgtEmptyGroup( nLayId) - dDeltaZ = dDeltaZ + EgtIf( vtRecalc and vtRecalc:getZ() > 0, -0.01, 0.01) + dDeltaZ = dDeltaZ + EgtIf( vtRecalc and vtRecalc:getZ() > 0, - DELTAZ, DELTAZ) -- eseguo il ricalcolo solo a quella quota - EgtPlaneSurfTmInters( ORIG() + ( dPosZ + dDeltaZ) * vtSlicing, vtSlicing, nStmId, nLayId, GDB_RT.GLOB, TOLER) + local ptOn = ptSlicing + dDeltaZ * vtSlicing + EgtPlaneSurfTmInters( ptOn, vtSlicing, nStmId, nLayId, GDB_RT.GLOB, TOLER) EgtOutLog( 'Warning : recalc at layer '.. EgtNumToString( nLayCnt)) end EgtSetInfo( nLayId, KEY_SLICE_DELTAZ, dDeltaZ) @@ -1100,27 +1176,29 @@ local function SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicin -- costolature local nRibsLay = EgtGetFirstNameInGroup( s_nPartId, LAY_RIBS) ExtractRibsLoops( nRibsLay, nStmId) - SlicingExtraObjects( nRibsLay, vtSlicing, TYPE.RIB, RIBS_CRV, RIBS_GRP, nStmId) - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vZSlices + 3) / nCounterTot * 100, 0) == 1 then return false end + SlicingExtraObjects( nRibsLay, TYPE.RIB, RIBS_CRV, RIBS_GRP, nStmId) + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( nCnt + 3) / nCounterTot * 100, 0) == 1 then return false end local bSpiralVase = EgtGetInfo( s_nPartId, KEY_SPIRAL_VASE, 'b') or false if not bSpiralVase then - -- infill - PrepareInfill( nStmId, vtSlicing) - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vZSlices + 6) / nCounterTot * 100, 0) == 1 then return false end + if nSlicingType ~= SLICING_TYPE.MULTIPLANAR then + PrepareInfill( nStmId, vSlicingDir[1]) + end + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( nCnt + 6) / nCounterTot * 100, 0) == 1 then return false end -- solidi per regioni con diverso numero di passate local nShellNbrLay = EgtGetFirstNameInGroup( s_nPartId, LAY_SHELL_NBR) - SlicingExtraObjects( nShellNbrLay, vtSlicing, TYPE.EXTRA_SHELL, SHELL_NBR_CRV, SHELL_NBR_GRP) - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vZSlices + 9) / nCounterTot * 100, 0) == 1 then return false end + SlicingExtraObjects( nShellNbrLay, TYPE.EXTRA_SHELL, SHELL_NBR_CRV, SHELL_NBR_GRP) + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( nCnt + 9) / nCounterTot * 100, 0) == 1 then return false end -- solidi ausiliari local nAuxSolidsLay = EgtGetFirstNameInGroup( s_nPartId, LAY_AUX_SOLIDS) - SlicingExtraObjects( nAuxSolidsLay, vtSlicing, TYPE.AUX_SOLID, AUX_SOLIDS_CRV, AUX_SOLIDS_GRP) - PrepareAuxSolidsInfill( nAuxSolidsLay, vtSlicing) - if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( #vZSlices + 12) / nCounterTot * 100, 0) == 1 then return false end - + SlicingExtraObjects( nAuxSolidsLay, TYPE.AUX_SOLID, AUX_SOLIDS_CRV, AUX_SOLIDS_GRP) + if nSlicingType ~= SLICING_TYPE.MULTIPLANAR then + PrepareAuxSolidsInfill( nAuxSolidsLay, vSlicingDir[1]) + end + if EgtProcessEvents( EgtIf( PRINT, 100, 0) + ( nCnt + 12) / nCounterTot * 100, 0) == 1 then return false end end EgtSetInfo( s_nPartId, KEY_FIRST_SOLID_LAY, nFirstSolidLay) @@ -1155,7 +1233,18 @@ function CalcSlices.Exec( nPartId, nStmId) end EgtSetInfo( s_nPartId, KEY_SLICE_DIR, vtSlicing) - local frSlicing = Frame3d( ORIG(), vtSlicing) + + -- recupero parametri di slicing + local dSliceStep = EgtGetInfo( s_nPartId, KEY_SLICE_STEP, 'd') or 10000 + if dSliceStep < GEO.EPS_SMALL then + EgtOutLog( 'Warning : SliceStep is 0') + return + end + s_dStrand = EgtGetInfo( s_nPartId, KEY_STRAND, 'd') + local nMaxSlicesNbr = EgtGetInfo( s_nPartId, KEY_MAX_SLICES_NBR, 'i') or 0 + if nMaxSlicesNbr == 0 then + nMaxSlicesNbr = GEO.INFINITO -- da gestire come caso illimitato + end -- recupero la superficie ed eventuali setti esterni/unbounded da usare come riferimenti per quote slicing local vRefIds = {} @@ -1163,6 +1252,10 @@ function CalcSlices.Exec( nPartId, nStmId) local nRibsLay = EgtGetFirstNameInGroup( s_nPartId, LAY_RIBS) local vRibsIds = EgtGetAllInGroup( nRibsLay) local bLimitUnbddRibs = EgtGetInfo( s_nPartId, KEY_LIMIT_UNBDD_RIBS, 'b') or false + if bLimitUnbddRibs and not nStmId then + EgtOutBox( "No solid to limit unbounded ribs!", 'Error', 'ERROR') + return + end for i = 1, #vRibsIds do if EgtGetType( vRibsIds[i]) == GDB_TY.SRF_MESH then local nType = ReadParam( vRibsIds[i], KEY_RIBS_TYPE, 'i', RIB_TYPE.INTERNAL) @@ -1171,55 +1264,29 @@ function CalcSlices.Exec( nPartId, nStmId) end end end - - if bLimitUnbddRibs and not nStmId then - EgtOutBox( "No solid to limit unbounded ribs!", 'Error', 'ERROR') - return - end - - -- recupero il box - local b3Box = BBox3d() - for i = 1, #vRefIds do - local b3Tmp = EgtGetBBoxRef( vRefIds[i], GDB_BB.STANDARD, frSlicing) - b3Box:Add( b3Tmp) - end - if not b3Box or b3Box:isEmpty() then + if #vRefIds == 0 then EgtOutBox( "No part to be sliced!", 'Error', 'ERROR') return end - - -- Parametri di slicing - local dSliceStep = EgtGetInfo( s_nPartId, KEY_SLICE_STEP, 'd') or 10000 - if dSliceStep < GEO.EPS_SMALL then - EgtOutLog( 'Warning : SliceStep is 0') - return - end - s_dStrand = EgtGetInfo( s_nPartId, KEY_STRAND, 'd') - local dZmin = b3Box:getMin():getZ() - local dZmax = b3Box:getMax():getZ() - local dMaxH = ComputeMaxH( vRefIds, frSlicing, dSliceStep) - dZmax = min( dZmax, dMaxH) + -- calcolo i dati dello slicing + local dMaxH = ComputeMaxH( vRefIds, vtSlicing, dSliceStep) + local vSlicingVal = {} + local vSlicingDir = {} + if nSlicingType == SLICING_TYPE.MULTIPLANAR then + vSlicingVal, vSlicingDir = ComputeMultiplanarSlicingData( dSliceStep, nMaxSlicesNbr) + else + vSlicingVal, vSlicingDir = ComputeSlicingData( vRefIds, vtSlicing, dSliceStep, dMaxH, nMaxSlicesNbr) + end -- Eseguo slicing - local nLayCnt = 1 - local nRecalc = 0 - local dDeltaZStart = 0.2 - - -- !!! Modifica provvisoria per MultiPlanar !!! - if nSlicingType == SLICING_TYPE.MULTIPLANAR then - dZmax = 2000 - end - - local vZSlices = ComputeZSlices( dSliceStep, dZmin, dDeltaZStart, dZmax) - local bOk = true if not nStmId then -- caso senza solido e solo setti - bOk = SlicingNoSolid( nRibsLay, vZSlices, dDeltaZStart, dZmin, frSlicing) + bOk = SlicingNoSolid( nRibsLay, nSlicingType, dMaxH, dSliceStep, vSlicingVal, vSlicingDir) else -- caso con solido - bOk = SlicingWithSolid( nStmId, vZSlices, dDeltaZStart, dZmin, frSlicing, nSlicingType) + bOk = SlicingWithSolid( nStmId, nSlicingType, dMaxH, vSlicingVal, vSlicingDir) end -- eventuale segnalazione errori diff --git a/LuaLibs/CalcToolPath.lua b/LuaLibs/CalcToolPath.lua index ef804e3..edc052f 100644 --- a/LuaLibs/CalcToolPath.lua +++ b/LuaLibs/CalcToolPath.lua @@ -2024,23 +2024,25 @@ local function SpiralVaseFull( vLayIds, LayerParams) -- la differenza in altezza tra due layers viene distribuita uniformemente lungo tutto il percorso -- la continuità tra i layers viene risolta sul layer corrente ( uniformemente su tutto il tratto o solo nella parte iniziale di lunghezza dSpiralVaseInterpLen) -- gestione speciale dei primi layers per gestione dell'altezza e feed + -- nel caso di slicing multiplanare viene realizzato un layer extra ( uguale all'ultimo) alla quota finale del pezzo local nOldId, nOldPathId local nRealLayer = 1 local nSlicingType = EgtGetInfo( s_nPartId, KEY_SLICING_TYPE, 'i') -- copio ultimo layer - if nSlicingType ~= SLICING_TYPE.DEG45_X and nSlicingType ~= SLICING_TYPE.DEG45_Y then + if nSlicingType ~= SLICING_TYPE.MULTIPLANAR and nSlicingType ~= SLICING_TYPE.DEG45_X and nSlicingType ~= SLICING_TYPE.DEG45_Y then local nNewLay = EgtCopyGlob( vLayIds[#vLayIds], vLayIds[#vLayIds], GDB_IN.AFTER) table.insert( vLayIds, nNewLay) + -- aggiorno nome e numero slice + local nSliceNbr = EgtGetInfo( nNewLay, KEY_SLICE_NBR, 'i') + 1 + EgtSetName( nNewLay, SLICE_LAYER .. EgtNumToString( nSliceNbr)) + EgtSetInfo( nNewLay, KEY_SLICE_NBR, nSliceNbr) + -- porto alla nuova quota EgtMove( nNewLay, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) - -- aggiorno nome e info - local sOldIdx = string.sub( EgtGetName( vLayIds[#vLayIds]), 6) - local nNewIdx = tonumber( sOldIdx) + 1 - EgtSetName( nNewLay, SLICE_LAYER .. EgtNumToString( nNewIdx)) - EgtSetInfo( nNewLay, KEY_SLICE_NBR, nNewIdx) - local dZOld = EgtGetInfo( vLayIds[#vLayIds], KEY_SLICE_Z, 'd') or 0 - EgtSetInfo( nNewLay, KEY_SLICE_Z, dZOld + LayerParams.dLayHeight) + local ptSlice = EgtGetInfo( nNewLay, KEY_SLICE_POS, 'p') + ptSlice = ptSlice + LayerParams.dLayHeight * LayerParams.vtSlicing + EgtSetInfo( nNewLay, KEY_SLICE_POS, ptSlice) end -- ciclo sui layer @@ -2237,12 +2239,48 @@ local function SpiralVaseFull( vLayIds, LayerParams) nRealLayer = nRealLayer + 1 end - + if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / #vLayIds * 100, 0) == 1 then EgtDraw() return false end end + + -- se slicing multiplanare creo un un layer extra piano alla quota finale + if nSlicingType == SLICING_TYPE.MULTIPLANAR then + local nLastLay = EgtCopyGlob( vLayIds[#vLayIds], vLayIds[#vLayIds], GDB_IN.AFTER) + -- aggiorno nome e numero slice + local nSliceNbr = EgtGetInfo( nLastLay, KEY_SLICE_NBR, 'i') + 1 + EgtSetName( nLastLay, SLICE_LAYER .. EgtNumToString( nSliceNbr)) + EgtSetInfo( nLastLay, KEY_SLICE_NBR, nSliceNbr) + -- creo la curva di toolpath alla quota finale + local nCrvGrpId = EgtGetFirstNameInGroup( nLastLay, CONTOUR_GRP.."*") + local nPathGrpId = EgtGetFirstNameInGroup( nCrvGrpId, PATH_GRP) + local nTpathGrpId = EgtGetFirstNameInGroup( nCrvGrpId, TOOLPATH_GRP) + EgtEmptyGroup( nTpathGrpId) + local nId = EgtCopyGlob( EgtGetFirstInGroup( nPathGrpId), nTpathGrpId) + local vtSlicing = EgtGetInfo( nLastLay, KEY_SLICE_DIR, 'v') + EgtMove( nId, LayerParams.dLayHeight * vtSlicing, GDB_RT.GLOB) + + local ptS = EgtEP( nOldId, GDB_ID.ROOT) + EgtChangeClosedCurveStartPoint( nId, ptS, GDB_RT.GLOB) + EgtModifyCurveExtrusion( nId, LayerParams.vtSlicing, GDB_RT.GLOB) + EgtSetInfo( nId, KEY_CRV_STRAND, LayerParams.dStrand) + if LayerParams.bInvert then + EgtInvertCurve( nId) + EgtSetInfo( nId, KEY_INVERTED_CRV, 1) + end + EgtSetColor( nId, EgtStdColor('GRAY')) + + -- approssimo + EgtApproxCurve( nId, GDB_CA.ARCS, s_dApproxTol) + if LayerParams.bLinearApprox then + EgtApproxCurve( nId, GDB_CA.LINES, LayerParams.dLinearApproxTol) + end + if EgtCurveIsClosed( nId) then + EgtChangeClosedCurveStartPoint( nId, ptS, GDB_RT.GLOB) + end + end return true end @@ -2427,8 +2465,9 @@ local function SpiralVase( vLayIds, LayerParams) -- calcolo il box dei percorsi local b3Tot = BBox3d() local nLastTPath - for i = 1, #vLayIds do - local vCrvGrpIds = EgtGetNameInGroup( vLayIds[i], CONTOUR_GRP.."*") + local vLayers = EgtGetNameInGroup( s_nPartId, SLICE_LAYER .. '*') + for i = 1, #vLayers do + local vCrvGrpIds = EgtGetNameInGroup( vLayers[i], CONTOUR_GRP.."*") local nTpathGrpId = EgtGetFirstNameInGroup( vCrvGrpIds[1], TOOLPATH_GRP) nLastTPath = EgtGetLastInGroup( nTpathGrpId) local b3Box = ComputeToolPathBox( nTpathGrpId)