-- CalcSolids.lua by Egaltech s.r.l. 2022/04/19 -- Calcolo percorsi di lavoro per Stampa 3d -- Tabella per definizione modulo local CalcSolids = {} -- Intestazioni require( 'EgtBase') EgtOutLog( ' CalcSolids started', 1) -- Dati local AMD = require( 'AddManData') --------------------------------------------------------------------- local function GetLayerParamsForSolidCalc() local nParamsGrp = EgtGetFirstNameInGroup( GDB_ID.ROOT, PARAMS_GRP) local LayerParams = {} LayerParams.bInvert = EgtGetInfo( nParamsGrp, KEY_PRINT_DIRECTION, 'b') LayerParams.dLayHeight = EgtGetInfo( nParamsGrp, KEY_SLICE_STEP, 'd') LayerParams.dStrand = EgtGetInfo( nParamsGrp, KEY_STRAND, 'd') LayerParams.nOrder = EgtGetInfo( nParamsGrp, KEY_PRINT_ORDER, 'i') LayerParams.vtSlicing = EgtGetInfo( nParamsGrp, KEY_SLICING_DIR, 'v') return LayerParams end --------------------------------------------------------------------- local function CalcSectionParams( dStrand, dH) local dL = dStrand local dLm = dStrand / 10 local dHm = dH / 6 -- recupero offset local nParamsGrp = EgtGetFirstNameInGroup( GDB_ID.ROOT, PARAMS_GRP) --local dOffs = EgtGetInfo( nParamsGrp, KEY_OFFSET_SLICE, 'd') dOffs = 0 if dOffs and dOffs > 0 then -- calcolo area originale local dArea = ( dL * dH) - ( dLm * dHm) local dLM = ( dArea / dH) - ( dLm / 6) if dOffs / 2 <= ( dL - dLM) then dL = dL - dOffs / 2 dLm = dL / 10 dHm = (( dL * dH) - dArea) / dLm else EgtOutLog( 'Strand section not calculated on area. Too much overlap?') end end local dD1 = 0.5 * dL - dLm local dD2 = 0.5 * dL - dD1 local dD3 = dHm local dD4 = dH - 2 * dD3 return dD1, dD2, dD3, dD4 end --------------------------------------------------------------------- local function CreateSection( ptS, vtDir, dStrand, dH, vtSlicing, nSolidGrp) local dD1, dD2, dD3, dD4 = CalcSectionParams( dStrand, dH) local ptA = ptS - dH * vtSlicing + dD1 * vtDir local ptB = ptA + dD2 * vtDir + dD3 *vtSlicing local ptC = ptB + dD4 * vtSlicing local ptD = ptA + dH * vtSlicing local ptE = ptD - 2 * dD1 * vtDir local ptF = ptC - 2 * ( dD1 + dD2) * vtDir local ptG = ptB - 2 * ( dD1 + dD2) * vtDir local ptH = ptA - 2 * dD1 * vtDir local nId = EgtCurveCompoFromPoints( nSolidGrp, {ptA, ptB, ptC, ptD, ptE, ptF, ptG, ptH, ptA}) EgtInvertCurve( nId) return nId end --------------------------------------------------------------------- local function CreateHalfSection( ptS, vtDir, dStrand, dH, vtSlicing, nSolidGrp) local dD1, dD2, dD3, dD4 = CalcSectionParams( dStrand, dH) local ptA = ptS - dH * vtSlicing + dD1 * vtDir local ptB = ptA + dD2 * vtDir + dD3 * vtSlicing local ptC = ptB + dD4 * vtSlicing local ptD = ptA + dH * vtSlicing local nId = EgtCurveCompoFromPoints( nSolidGrp, { ptS - dH * vtSlicing, ptA, ptB, ptC, ptD, ptS}) return nId end -------------------------------------------------------------------- local function CreateSolid( nCrvId, nSolidGrp, dStrand, dH, vtSlicing) -- punti e direzioni all'inizio e fine della curva guida local ptS = EgtSP( nCrvId) local vtS = EgtSV( nCrvId) vtS:rotate( vtSlicing, 90) local ptE = EgtEP( nCrvId) local vtE = EgtEV( nCrvId) vtE:rotate( vtSlicing, -90) -- creazione del solido aperto (tubo) local nSectId = CreateSection( ptS, vtS, dStrand, dH, vtSlicing, nSolidGrp) local nSrfId = EgtSurfTmSwept( nSolidGrp, nSectId, nCrvId, false, 0.1) EgtErase( nSectId) if not nSrfId then return nil end -- creazione del mezzo disco iniziale local nSectS = CreateHalfSection( ptS, vtS, dStrand, dH, vtSlicing, nSolidGrp) local nSrfS = EgtSurfTmByScrewing( nSolidGrp, nSectS, ptS, vtSlicing, 180, 0, false, 0.1) EgtErase( nSectS) if not nSrfS then return nil end -- creazione del mezzo disco finale local nSectE = CreateHalfSection( ptE, vtE, dStrand, dH, vtSlicing, nSolidGrp) local nSrfE = EgtSurfTmByScrewing( nSolidGrp, nSectE, ptE, vtSlicing, 180, 0, false, 0.1) EgtErase( nSectE) if not nSrfE then return nil end -- unione delle tre superfici return EgtSurfTmBySewing( nSolidGrp, { nSrfId, nSrfS, nSrfE}) end --------------------------------------------------------------------- local function CreateSolidFromCurve( nCrvId, nSolidGrp, LayerParams) local nType = EgtGetInfo( nCrvId, KEY_TYPE, 'i') if nType == TYPE.WIPE then return true end -- scelta del colore local Color = EgtStdColor( 'GRAY') if nType == TYPE.OUTER_SHELL then Color = EgtStdColor( 'TEAL') elseif nType == TYPE.INNER_SHELL then Color = EgtStdColor( 'ORANGE') elseif nType == TYPE.LINK then Color = EgtStdColor( 'GRAY') elseif nType == TYPE.INFILL then Color = EgtStdColor( 'YELLOW') elseif nType == TYPE.COASTING then Color = EgtStdColor( 'BLUE') end local nParts = EgtIf( nType == TYPE.LINK or nType == TYPE.COASTING, 1, 10) local nCopyId = EgtCopyGlob( nCrvId, nSolidGrp) local nId = EgtSplitCurve( nCopyId, nParts) local bOk = true for nInd = 0, nParts - 1 do local nGuideId = nId + nInd local nSrfId = CreateSolid( nGuideId, nSolidGrp, LayerParams.dStrand, LayerParams.dLayHeight, LayerParams.vtSlicing) if not nSrfId then -- ritento con sezione leggermente modificata nSrfId = CreateSolid( nGuideId, nSolidGrp, LayerParams.dStrand - 100 * GEO.EPS_SMALL, LayerParams.dLayHeight, LayerParams.vtSlicing) if not nSrfId then nSrfId = CreateSolid( nGuideId, nSolidGrp, LayerParams.dStrand + 100 * GEO.EPS_SMALL, LayerParams.dLayHeight, LayerParams.vtSlicing) if not nSrfId then -- ritento spezzando la curva local nFirstCrv, nCrvNbr = EgtSplitCurveAtCorners( nGuideId, 60) if nFirstCrv then local nSrfIds = {} for nInd2 = 0, nCrvNbr-1 do local nSrfId2 = CreateSolid( nFirstCrv + nInd2, nSolidGrp, LayerParams.dStrand - 100 * GEO.EPS_SMALL, LayerParams.dLayHeight, LayerParams.vtSlicing) EgtErase( nFirstCrv + nInd2) if nSrfId2 then table.insert( nSrfIds, nSrfId2) end end if #nSrfIds == nCrvNbr then nSrfId = EgtSurfTmBySewing( nSolidGrp, nSrfIds) end end end end end if nSrfId then EgtSetColor( nSrfId, Color) EgtSetInfo( nSrfId, KEY_TYPE, nType) else bOk = false end EgtErase( nGuideId) end return bOk end --------------------------------------------------------------------- function CalcSolids.Exec( nPartId) local vLayIds = EgtGetNameInGroup( nPartId, SLICE_LAYER.."*") if not vLayIds then EgtOutBox( 'Error no slice', 'SolidCalc') return end local vErr = {} -- recupero i parametri necessari al calcolo dei solidi local LayerParams = GetLayerParamsForSolidCalc() for nIdx = 1, #vLayIds do -- scorro tutti i gruppi di contorni local nCrvGrpId = EgtGetFirstNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*") or GDB_ID.NULL while nCrvGrpId ~= GDB_ID.NULL do -- recupero il gruppo dei percorsi utensile local nTPathGrpId = EgtGetFirstNameInGroup( nCrvGrpId, TOOLPATH_GRP) or GDB_ID.NULL if nTPathGrpId == GDB_ID.NULL then EgtOutBox( 'Error no tool paths', 'SolidCalc') return end -- recupero il gruppo dei solidi local nSolidGrpId = EgtGetFirstNameInGroup( nCrvGrpId, SOLID_GRP) or GDB_ID.NULL if nSolidGrpId == GDB_ID.NULL then nSolidGrpId = EgtGroup( nCrvGrpId) EgtSetName( nSolidGrpId, SOLID_GRP) else EgtEmptyGroup( nSolidGrpId) end -- scorro le curve del percorso utensile local nId = EgtGetFirstInGroup( nTPathGrpId) while nId do local bOk = CreateSolidFromCurve( nId, nSolidGrpId, LayerParams) if not bOk then table.insert( vErr, nIdx) end nId = EgtGetNext( nId) end -- nascondo ExternCurve del gruppo local vExtCrvs = EgtGetNameInGroup( nCrvGrpId, OUTER_CRV) for nInd = 1, #vExtCrvs do EgtSetStatus( vExtCrvs[nInd], GDB_ST.OFF) end -- processo gli eventi if ( nIdx % 20) == 0 then EgtDraw() if EgtProcessEvents( nIdx / #vLayIds * 100, 0) == 1 then return end end --passo al gruppo di contorni successivo nCrvGrpId = EgtGetNextName( nCrvGrpId, CONTOUR_GRP.."*") or GDB_ID.NULL end EgtDraw() if EgtProcessEvents( nIdx / #vLayIds * 100, 0) == 1 then return end end -- eventuale segnalazione errori -- if #vErr > 0 then -- EgtOutBox( 'Error on layers :\n' .. table.concat( vErr, ','), 'SolidCalc') -- end for i = 1, #vErr do EgtOutLog( 'Error on solid creation (layer ' .. vErr[i] .. ') - SolidCalc') end end --------------------------------------------------------------------- return CalcSolids