-- CalcToolPath.lua by Egaltech s.r.l. 2022/04/19 -- Calcolo percorsi di lavoro per Stampa 3d -- Tabella per definizione modulo local CalcToolPath = {} -- Intestazioni require( 'EgtBase') EgtOutLog( ' CalcToolPath started', 1) -- Dati local AMD = require( 'AddManData') --------------------------------------------------------------------- local function GetLayerParamsForToolPathCalc() local nParamsGrp = EgtGetFirstNameInGroup( GDB_ID.ROOT, PARAMS_GRP) local LayerParams = {} LayerParams.dStrand = EgtGetInfo( nParamsGrp, KEY_STRAND, 'd') LayerParams.dLayHeight = EgtGetInfo( nParamsGrp, KEY_SLICE_STEP, 'd') LayerParams.bInvert = ( EgtGetInfo( nParamsGrp, KEY_PRINT_DIRECTION, 'i') == PRINT_DIRECTION.CW) LayerParams.nOrder = EgtGetInfo( nParamsGrp, KEY_PRINT_ORDER, 'i') LayerParams.nLinkType = EgtGetInfo( nParamsGrp, KEY_LINK_TYPE, 'i') LayerParams.dLinkParam = EgtGetInfo( nParamsGrp, KEY_LINK_PARAM, 'd') LayerParams.nLeadInType = EgtGetInfo( nParamsGrp, KEY_LEAD_IN_TYPE, 'i') LayerParams.dLeadInTangDist = EgtGetInfo( nParamsGrp, KEY_LEAD_IN_TANG_DIST, 'd') LayerParams.dLeadInOrthoDist = EgtGetInfo( nParamsGrp, KEY_LEAD_IN_ORTHO_DIST, 'd') LayerParams.nLeadOutType = EgtGetInfo( nParamsGrp, KEY_LEAD_OUT_TYPE, 'i') LayerParams.dLeadOutTangDist = EgtGetInfo( nParamsGrp, KEY_LEAD_OUT_TANG_DIST, 'd') LayerParams.dLeadOutOrthoDist = EgtGetInfo( nParamsGrp, KEY_LEAD_OUT_ORTHO_DIST, 'd') LayerParams.dOffsetLP = EgtGetInfo( nParamsGrp, KEY_OFFSET_LEAD_POINT, 'd') LayerParams.dSPOffs = EgtGetInfo( nParamsGrp, KEY_SP_OFFSET_ON_SLICE, 'd') LayerParams.dCoastingLen = EgtGetInfo( nParamsGrp, KEY_COASTING_LEN, 'd') LayerParams.dWipeLen = EgtGetInfo( nParamsGrp, KEY_WIPE_LEN, 'd') return LayerParams end -------------------------------------------------------------------- local function AddLeadIn( nCrvId, LayerParams, nGrpId) local ptE = EgtSP( nCrvId) local vtTang = EgtSV( nCrvId) local vtOrtho = Vector3d( vtTang) local dAng = 90 if ( LayerParams.bInvert and LayerParams.nOrder == PRINT_ORDER.INF_INT_EXT) or ( not LayerParams.bInvert and LayerParams.nOrder == PRINT_ORDER.EXT_INT_INF) then dAng = - 90 end vtOrtho:rotate( Z_AX(), dAng) local ptS = ptE - LayerParams.dLeadInTangDist * vtTang + LayerParams.dLeadInOrthoDist * vtOrtho -- impongo che la coordinata z dei due punti sia la stessa ptS = Point3d( ptS:getX(), ptS:getY(), ptE:getZ()) local nLeadInCrv = GDB_ID.NULL if LayerParams.nLeadInType == LEAD_TYPE.LINEAR then nLeadInCrv = EgtLine( nGrpId, ptS, ptE) elseif LayerParams.nLeadInType == LEAD_TYPE.ARC then local _, _, dAngIni = SphericalFromVector( vtTang) nLeadInCrv = EgtArc2PD( nGrpId, ptE, ptS, 180 + dAngIni) EgtInvertCurve( nLeadInCrv) end EgtRelocate( nLeadInCrv, nGrpId, GDB_IN.FIRST_SON) EgtModifyCurveExtrusion( nLeadInCrv, Z_AX(), GDB_RT.GLOB) EgtSetInfo( nLeadInCrv, KEY_TYPE, TYPE.LINK) EgtSetColor( nLeadInCrv, EgtStdColor('GRAY')) end -------------------------------------------------------------------- local function AddLeadOut( nCrvId, LayerParams, nGrpId) local ptS = EgtEP( nCrvId) local vtTang = EgtEV( nCrvId) local vtOrtho = Vector3d( vtTang) local dAng = - 90 if ( LayerParams.bInvert and LayerParams.nOrder == PRINT_ORDER.INF_INT_EXT) or ( not LayerParams.bInvert and LayerParams.nOrder == PRINT_ORDER.EXT_INT_INF) then dAng = 90 end vtOrtho:rotate( Z_AX(), dAng) local ptE = ptS + LayerParams.dLeadOutTangDist * vtTang + LayerParams.dLeadOutOrthoDist * vtOrtho -- impongo che la coordinata z dei due punti sia la stessa ptE = Point3d( ptE:getX(), ptE:getY(), ptS:getZ()) local nLeadOutCrv = GDB_ID.NULL if LayerParams.nLeadOutType == LEAD_TYPE.LINEAR then nLeadOutCrv = EgtLine( nGrpId, ptS, ptE) elseif LayerParams.nLeadOutType == LEAD_TYPE.ARC then local _, _, dAngIni = SphericalFromVector( vtTang) nLeadOutCrv = EgtArc2PD( nGrpId, ptS, ptE, dAngIni) end EgtRelocate( nLeadOutCrv, nGrpId, GDB_IN.LAST_SON) EgtModifyCurveExtrusion( nLeadOutCrv, Z_AX(), GDB_RT.GLOB) EgtSetInfo( nLeadOutCrv, KEY_TYPE, TYPE.LINK) EgtSetColor( nLeadOutCrv, EgtStdColor('GRAY')) end -------------------------------------------------------------------- local function AddRetraction( nCrvId, dCoastingLen, dWipeLen) local nCoastingId if dCoastingLen > GEO.EPS_SMALL then nCoastingId = EgtCopyGlob( nCrvId, nCrvId, GDB_IN.AFTER) local dPar = EgtCurveParamAtLength( nCoastingId, EgtCurveLength( nCoastingId) - dCoastingLen) if not dPar then EgtErase( nCoastingId) return end EgtTrimCurveStartAtParam( nCoastingId, dPar) -- aggiorno la curva originale if dPar > GEO.EPS_SMALL then EgtTrimCurveEndAtParam( nCrvId, dPar) else EgtErase( nCrvId) end EgtSetName( nCoastingId, COASTING_CRV) EgtSetInfo( nCoastingId, KEY_TYPE, TYPE.COASTING) EgtSetColor( nCoastingId, EgtStdColor('ORANGE')) end if dWipeLen > GEO.EPS_SMALL then local nWipeId = EgtCopyGlob( nCrvId, EgtIf( nCoastingId, nCoastingId, nCrvId), GDB_IN.AFTER) EgtTrimCurveEndAtLen( nWipeId, dWipeLen) EgtSetName( nWipeId, WIPE_CRV) EgtSetInfo( nWipeId, KEY_TYPE, TYPE.WIPE) EgtSetColor( nWipeId, EgtStdColor('TEAL')) end return nCoastingId end -------------------------------------------------------------------- local function AddRetractionOnLastCrv( nTpathGrpId, LayerParams) local nCrvId = EgtGetLastNameInGroup( nTpathGrpId, SHELL_CRV .. "*") if LayerParams.nLeadOutType == LEAD_TYPE.NONE then AddRetraction( nCrvId, LayerParams.dCoastingLen, LayerParams.dWipeLen) else local nLeadOutId = EgtGetLastInGroup( nTpathGrpId) local dLen = EgtCurveLength( nLeadOutId) if dLen > LayerParams.dCoastingLen - 500 * GEO.EPS_SMALL then -- coinvolge solo la curva di lead out local dNewCoastingLen = EgtIf( abs( LayerParams.dCoastingLen - dLen) < 500 * GEO.EPS_SMALL, dLen, LayerParams.dCoastingLen) -- verifico se interamente coinvolta AddRetraction( nLeadOutId, dNewCoastingLen, 0.0) else -- coinvolge parte dell'ultima shell crv local dNewCoastingLen = LayerParams.dCoastingLen - dLen local nCoastingId = AddRetraction( nCrvId, dNewCoastingLen, 0.0) EgtAddCurveCompoCurve( nCoastingId, nLeadOutId) end end end --------------------------------------------------------------------- function CalcToolPath.Exec( nPartId) -- Verifico il pezzo if not nPartId then EgtOutBox( 'Error missing part', 'ToolPathCalc') return end -- Recupero i layer da processare local vLayIds = EgtGetNameInGroup( nPartId, SLICE_LAYER.."*") if not vLayIds then EgtOutBox( 'Error missing slices', 'ToolPathCalc') return end -- Ciclo sui layer for nIdx = 1, #vLayIds do -- recupero i parametri relativi al layer local LayerParams = GetLayerParamsForToolPathCalc() -- scorro tutti i gruppi di contorni local nCrvGrpId = EgtGetFirstNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*") while nCrvGrpId do -- recupero il gruppo dei percorsi local nPathGrpId = EgtGetFirstNameInGroup( nCrvGrpId, PATH_GRP) if not nPathGrpId then EgtOutBox( 'Error missing paths', 'ToolPathCalc') return else EgtSetStatus( nPathGrpId, GDB_ST.OFF) end -- recupero il gruppo dei percorsi utensile local nTpathGrpId = EgtGetFirstNameInGroup( nCrvGrpId, TOOLPATH_GRP) if not nTpathGrpId then nTpathGrpId = EgtGroup( nCrvGrpId) EgtSetName( nTpathGrpId, TOOLPATH_GRP) else EgtEmptyGroup( nTpathGrpId) end -- creo il percorso di lavoro : -- copio le curve, le ordino, le oriento e le muovo in Z local nEntId = EgtGetFirstInGroup( nPathGrpId) while nEntId do local nNewEntId = EgtCopyGlob( nEntId, nTpathGrpId, EgtIf( LayerParams.nOrder == PRINT_ORDER.INF_INT_EXT, GDB_IN.FIRST_SON, GDB_IN.LAST_SON)) EgtMove( nNewEntId, Vector3d( 0, 0, LayerParams.dLayHeight), GDB_RT.GLOB) if LayerParams.bInvert then EgtInvertCurve( nNewEntId) end EgtModifyCurveExtrusion( nNewEntId, Z_AX(), GDB_RT.GLOB) EgtSetColor( nNewEntId, EgtStdColor('GRAY')) nEntId = EgtGetNext( nEntId) end -- aggiungo gli opportuni raccordi local nPrevId = EgtGetFirstInGroup( nTpathGrpId) local nCurrId = EgtGetNext( nPrevId or GDB_ID.NULL) k = 0 local nPrevShellNbr if nPrevId then nPrevShellNbr = tonumber( EgtGetName( nPrevId):sub(6)) end while nCurrId do local nCurrShellNbr = tonumber( EgtGetName( nCurrId):sub(6)) if nCurrShellNbr ~= nPrevShellNbr then k = k + 1 end -- se nessun raccordo modifico solo lo start point della curva if LayerParams.nLinkType == LINK_TYPE.NONE then local dLen = k * LayerParams.dSPOffs if LayerParams.dSPOffs < 0 then dLen = EgtCurveLength( nCurrId) + dLen end local dPar = EgtCurveParamAtLength( nCurrId, dLen) if dPar then EgtChangeClosedCurveStart( nCurrId, dPar) end else -- altrimenti verifico se ha senso creare raccordo if abs( dist( EgtEP( nPrevId), EgtSP( nCurrId))) < LayerParams.dStrand + 10 then local nLinkId if k > 1 then -- modifico lo start point local dLen = EgtCurveLength( nPrevId) - abs( LayerParams.dSPOffs) EgtTrimCurveEndAtLen( nPrevId, dLen) EgtChangeClosedCurveStartPoint( nCurrId, EgtEP( nPrevId)) end -- aggiungo il raccordo EgtTrimCurveEndAtLen( nPrevId, EgtCurveLength( nPrevId) - LayerParams.dLinkParam / 2) EgtTrimCurveStartAtLen( nCurrId, LayerParams.dLinkParam / 2) if LayerParams.nLinkType == LINK_TYPE.LINEAR then nLinkId = EgtLine( nTpathGrpId, EgtEP( nPrevId), EgtSP( nCurrId)) elseif LayerParams.nLinkType == LINK_TYPE.BIARC then local _, _, dAngIni = SphericalFromVector( EgtEV( nPrevId)) local _, _, dAngFin = SphericalFromVector( EgtSV( nCurrId)) nLinkId = EgtBiArc( nTpathGrpId, EgtEP( nPrevId), EgtSP( nCurrId), dAngIni, dAngFin, 0.5) end if nLinkId then EgtRelocate( nLinkId, nCurrId, GDB_IN.BEFORE) EgtSetColor( nLinkId, EgtStdColor('GRAY')) EgtModifyCurveExtrusion( nLinkId, Z_AX(), GDB_RT.GLOB) EgtSetInfo( nLinkId, KEY_TYPE, TYPE.LINK) end end end nPrevShellNbr = nCurrShellNbr nPrevId = nCurrId nCurrId = EgtGetNext( nCurrId) end -- aggiungo leadin/leadout local nFirstCurve = EgtGetFirstInGroup( nTpathGrpId) if nFirstCurve and LayerParams.nLeadInType ~= LEAD_TYPE.NONE then EgtTrimCurveStartAtLen( nFirstCurve, LayerParams.dOffsetLP) AddLeadIn( nFirstCurve, LayerParams, nTpathGrpId) end local nLastCurve = EgtGetLastInGroup( nTpathGrpId) if nLastCurve and LayerParams.nLeadOutType ~= LEAD_TYPE.NONE then EgtTrimCurveEndAtLen( nLastCurve, EgtCurveLength( nLastCurve) - LayerParams.dOffsetLP) AddLeadOut( nLastCurve, LayerParams, nTpathGrpId) end -- aggiungo coasting/wipe local nId = EgtGetFirstNameInGroup( nTpathGrpId, SHELL_CRV .. "*") local nFirstId = nId local nLastId = EgtGetLastNameInGroup( nTpathGrpId, SHELL_CRV .. "*") while nId do if nId == nLastId then AddRetractionOnLastCrv( nTpathGrpId, LayerParams) else local nNextId = EgtGetNext( nId) if EgtGetInfo( nNextId, KEY_TYPE, 'i') ~= TYPE.LINK then -- aggiungo retrazione if nId == nFirstId then local dWipeLen = EgtIf( LayerParams.nLeadInType == LEAD_TYPE.NONE, LayerParams.dWipeLen, 0) AddRetraction( nId, LayerParams.dCoastingLen, dWipeLen) else AddRetraction( nId, LayerParams.dCoastingLen, LayerParams.dWipeLen) end end end nId = EgtGetNextName( nId, SHELL_CRV .. "*") end --passo al gruppo di contorni successivo nCrvGrpId = EgtGetNextName( nCrvGrpId, CONTOUR_GRP.."*") end end end --------------------------------------------------------------------- return CalcToolPath