-- CalcToolPath.lua by Egaltech s.r.l. 2022/10/01 -- 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 s_nPartId local s_nDefaultWipeAng = -90 -- angolo = 0° per wipe significa che esce ortogonalmente alla direzione del movimento local s_dHMin --------------------------------------------------------------------- local function GetLayerParamsForToolPathCalc() local LayerParams = {} LayerParams.bSpiralVase = EgtGetInfo( s_nPartId, KEY_SPIRAL_VASE, 'b') or false LayerParams.dStrand = EgtGetInfo( s_nPartId, KEY_STRAND, 'd') LayerParams.dLayHeight = EgtGetInfo( s_nPartId, KEY_SLICE_STEP, 'd') LayerParams.dOffs = EgtGetInfo( s_nPartId, KEY_OFFSET_SLICE, 'd') LayerParams.bInvert = ( EgtGetInfo( s_nPartId, KEY_PRINT_DIRECTION, 'i') == PRINT_DIRECTION.CW) LayerParams.nOrder = EgtGetInfo( s_nPartId, KEY_PRINT_ORDER, 'i') LayerParams.nLinkType = EgtGetInfo( s_nPartId, KEY_LINK_TYPE, 'i') LayerParams.dLinkParam = EgtGetInfo( s_nPartId, KEY_LINK_PARAM, 'd') LayerParams.nLeadInType = EgtGetInfo( s_nPartId, KEY_LEAD_IN_TYPE, 'i') LayerParams.dLeadInTangDist = EgtGetInfo( s_nPartId, KEY_LEAD_IN_TANG_DIST, 'd') LayerParams.dLeadInOrthoDist = EgtGetInfo( s_nPartId, KEY_LEAD_IN_ORTHO_DIST, 'd') LayerParams.nLeadOutType = EgtGetInfo( s_nPartId, KEY_LEAD_OUT_TYPE, 'i') LayerParams.dLeadOutTangDist = EgtGetInfo( s_nPartId, KEY_LEAD_OUT_TANG_DIST, 'd') LayerParams.dLeadOutOrthoDist = EgtGetInfo( s_nPartId, KEY_LEAD_OUT_ORTHO_DIST, 'd') LayerParams.dOffsetLP = EgtGetInfo( s_nPartId, KEY_OFFSET_LEAD_POINT, 'd') LayerParams.dSPOffs = EgtGetInfo( s_nPartId, KEY_SP_OFFSET_ON_SLICE, 'd') LayerParams.dCoastingLen = EgtGetInfo( s_nPartId, KEY_COASTING_LEN, 'd') LayerParams.dWipeLen = EgtGetInfo( s_nPartId, KEY_WIPE_LEN, 'd') LayerParams.dWipeDir = EgtGetInfo( s_nPartId, KEY_WIPE_DIR, 'd') or 0.0 LayerParams.vtSlicing = EgtGetInfo( s_nPartId, KEY_SLICING_DIR, 'v') LayerParams.dTDiam = EgtGetInfo( s_nPartId, KEY_TOOL_DIAM, 'd') return LayerParams end -------------------------------------------------------------------- local function ComputeZCorrection( LayerParams) -- direzione dell'estrusore local vtN = LayerParams.vtSlicing local dNxy = sqrt( vtN:getX() * vtN:getX() + vtN:getY() * vtN:getY()) local dNz = vtN:getZ() -- altezza necessaria per ugello s_dHMin = LayerParams.dTDiam / 2 * dNxy -- correzione per l'offset local dCorr1 = LayerParams.dOffs * dNxy -- correzione per il diametro dell'ugello local dCorr2 = ( LayerParams.dOffs - LayerParams.dStrand / 2 + LayerParams.dTDiam / 2) * dNxy - LayerParams.dLayHeight * dNz -- massimo tra le due return max( dCorr1, dCorr2) end ------------------------------------------------------------------- local function AddLink( vCrv, nTpathGrpId, nLinkType, dLinkParam, dSPOffs, dStrand, vtSlicing) if not vCrv or #vCrv == 0 then return end local k = 0 local bPrevClosed = EgtGetInfo( vCrv[1], KEY_CLOSED_CRV, 'b') or false for i = 2, #vCrv do -- il link ha senso solo su curve chiuse local bCurrClosed = EgtCurveIsClosed( vCrv[i]) if bCurrClosed and bPrevClosed then -- aggiorno k per calcolo dell'offset local sPrevName = EgtGetName( vCrv[i-1]) local sCurrName = EgtGetName( vCrv[i]) local nType = EgtGetInfo( vCrv[i], KEY_TYPE, 'i') if sPrevName ~= sCurrName or nType == TYPE.INFILL or nType == TYPE.AUX_SOLID then k = k + 1 end -- se nessun raccordo modifico solo lo start point della curva if nLinkType == LINK_TYPE.NONE then local dLen = k * dSPOffs if dSPOffs < 0 then dLen = EgtCurveLength( vCrv[i]) + dLen end local dPar = EgtCurveParamAtLength( vCrv[i], dLen) if dPar then EgtChangeClosedCurveStart( vCrv[i], dPar) end else -- altrimenti verifico se ha senso creare raccordo -- local dDist = dist( EgtEP( vCrv[i-1]), EgtSP( vCrv[i])) local dDist = EgtPointCurveDist( EgtEP( vCrv[i-1]), vCrv[i]) if dDist < dStrand + 10 * GEO.EPS_SMALL then local nLinkId -- modifico lo start point local dLen = EgtCurveLength( vCrv[i-1]) - EgtIf( k > 1, abs( dSPOffs), 0) EgtTrimCurveEndAtLen( vCrv[i-1], dLen) EgtChangeClosedCurveStartPoint( vCrv[i], EgtEP( vCrv[i-1])) -- aggiungo il raccordo EgtTrimCurveEndAtLen( vCrv[i-1], EgtCurveLength( vCrv[i-1]) - dLinkParam / 2) EgtTrimCurveStartAtLen( vCrv[i], dLinkParam / 2) if nLinkType == LINK_TYPE.LINEAR then nLinkId = EgtCurveCompoFromPoints( nTpathGrpId, {EgtEP( vCrv[i-1]), EgtSP( vCrv[i])}) elseif nLinkType == LINK_TYPE.BIARC then local frLoc = Frame3d( ORIG(), vtSlicing) local nGrpTmp = EgtGroup( nTpathGrpId, frLoc, GDB_RT.GLOB) local _, _, dAngIni = SphericalFromVector( EgtEV( vCrv[i-1], nGrpTmp)) local _, _, dAngFin = SphericalFromVector( EgtSV( vCrv[i], nGrpTmp)) nLinkId = EgtBiArc( nGrpTmp, EgtEP( vCrv[i-1], nGrpTmp), EgtSP( vCrv[i], nGrpTmp), dAngIni, dAngFin, 0.5) EgtRelocateGlob( nLinkId, nTpathGrpId, GDB_IN.LAST_SON) EgtErase( nGrpTmp) end if nLinkId then EgtRelocate( nLinkId, vCrv[i], GDB_IN.BEFORE) EgtModifyCurveExtrusion( nLinkId, vtSlicing, GDB_RT.GLOB) EgtSetInfo( nLinkId, KEY_TYPE, TYPE.LINK) EgtSetName( nLinkId, LINK_CRV) end end end end bPrevClosed = bCurrClosed end end -------------------------------------------------------------------- local function AddLeadIn( nCrvId, LayerParams, nGrpId) local ptE = EgtSP( nCrvId, GDB_ID.ROOT) local vtTang = EgtSV( nCrvId, GDB_ID.ROOT) 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( LayerParams.vtSlicing, dAng) local ptS = ptE - LayerParams.dLeadInTangDist * vtTang + LayerParams.dLeadInOrthoDist * vtOrtho -- verifico che non affondi nella tavola if ptS:getZ() < s_dHMin + GEO.EPS_SMALL then return end local nLeadInCrv if LayerParams.nLeadInType == LEAD_TYPE.LINEAR then nLeadInCrv = EgtCurveCompoFromPoints( nGrpId, {ptS, ptE}, GDB_RT.GLOB) elseif LayerParams.nLeadInType == LEAD_TYPE.ARC then nLeadInCrv = EgtArc2PV( nGrpId, ptE, ptS, -vtTang, GDB_RT.GLOB) EgtInvertCurve( nLeadInCrv) end if nLeadInCrv then EgtRelocate( nLeadInCrv, nGrpId, GDB_IN.FIRST_SON) EgtModifyCurveExtrusion( nLeadInCrv, LayerParams.vtSlicing, GDB_RT.GLOB) EgtSetInfo( nLeadInCrv, KEY_TYPE, TYPE.LINK) EgtSetName( nLeadInCrv, LEAD_IN_CRV) end end -------------------------------------------------------------------- local function AddLeadOut( nCrvId, LayerParams, nGrpId) local ptS = EgtEP( nCrvId, GDB_ID.ROOT) local vtTang = EgtEV( nCrvId, GDB_ID.ROOT) 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( LayerParams.vtSlicing, dAng) local ptE = ptS + LayerParams.dLeadOutTangDist * vtTang + LayerParams.dLeadOutOrthoDist * vtOrtho local nLeadOutCrv if LayerParams.nLeadOutType == LEAD_TYPE.LINEAR then nLeadOutCrv = EgtCurveCompoFromPoints( nGrpId, {ptS, ptE}, GDB_RT.GLOB) elseif LayerParams.nLeadOutType == LEAD_TYPE.ARC then nLeadOutCrv = EgtArc2PV( nGrpId, ptS, ptE, vtTang, GDB_RT.GLOB) end if nLeadOutCrv then EgtRelocate( nLeadOutCrv, nGrpId, GDB_IN.LAST_SON) EgtModifyCurveExtrusion( nLeadOutCrv, LayerParams.vtSlicing, GDB_RT.GLOB) EgtSetInfo( nLeadOutCrv, KEY_TYPE, TYPE.LINK) EgtSetName( nLeadOutCrv, LEAD_OUT_CRV) end return nLeadOutCrv end -------------------------------------------------------------------- local function AddRetraction( nCrvId, vtSlicing, dCoastingLen, dWipeLen, dWipeDir) -- recupero i parametri per retrazione local nType = EgtGetInfo( nCrvId, KEY_TYPE, 'i') local bClosed = EgtGetInfo( nCrvId, KEY_CLOSED_CRV, 'b') or false local bInverted = EgtGetInfo( nCrvId, KEY_INVERTED_CRV, 'b') or false -- curva ausiliaria per generare correttamente wipe local nCopyId = EgtCopyGlob( nCrvId, nCrvId, GDB_IN.AFTER) EgtCloseCurveCompo( nCopyId) local ptNewStart = EgtEP( nCrvId) EgtChangeClosedCurveStartPoint( nCopyId, ptNewStart) 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) nCoastingId = nil else EgtTrimCurveStartAtParam( nCoastingId, dPar) -- aggiorno la curva originale if dPar > GEO.EPS_SMALL then EgtTrimCurveEndAtParam( nCrvId, dPar) else EgtErase( nCrvId) end EgtModifyCurveExtrusion( nCoastingId, vtSlicing, GDB_RT.GLOB) EgtSetName( nCoastingId, COASTING_CRV) EgtSetInfo( nCoastingId, KEY_TYPE, TYPE.COASTING) EgtSetColor( nCoastingId, EgtStdColor('ORANGE')) end end if dWipeLen > GEO.EPS_SMALL then local nWipeId if bClosed then -- se era chiusa ( quindi analogo alle shell) nWipeId = EgtCopyGlob( nCopyId, nCoastingId or nCrvId, GDB_IN.AFTER) 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 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 bChangeSign = bInverted end vtDir:rotate( vtSlicing, EgtIf( bChangeSign, - dAng, dAng)) local ptS = EgtEP( nCoastingId or nCrvId, GDB_ID.ROOT) local ptE = ptS + vtDir * dWipeLen -- verifico soddisfi altezza minima per dimensioni utensile local k = 1 while ptE:getZ() < s_dHMin + GEO.EPS_SMALL and k < 36 do vtDir:rotate( vtSlicing, EgtIf( bChangeSign, 10, -10)) ptE = ptS + vtDir * dWipeLen k = k + 1 end nWipeId = EgtCurveCompoFromPoints( EgtGetParent( nCrvId), {ptS, ptE}, GDB_RT.GLOB) EgtModifyCurveExtrusion( nWipeId, vtSlicing, GDB_RT.GLOB) EgtRelocateGlob( nWipeId, nCoastingId or nCrvId, GDB_IN.AFTER) end EgtSetName( nWipeId, WIPE_CRV) EgtSetInfo( nWipeId, KEY_TYPE, TYPE.WIPE) EgtSetColor( nWipeId, EgtStdColor('AQUA')) end EgtErase( nCopyId) return nCoastingId end -------------------------------------------------------------------- local function AddRetractionOnLastCrv( nCrvId, nTpathGrpId, LayerParams, dCoastingLen, dWipeLen, dWipeDir) if LayerParams.nLeadOutType == LEAD_TYPE.NONE then AddRetraction( nCrvId, LayerParams.vtSlicing, dCoastingLen, dWipeLen, dWipeDir) else local nLeadOutId = EgtGetLastInGroup( nTpathGrpId) local dLen = EgtCurveLength( nLeadOutId) if dLen > dCoastingLen - 500 * GEO.EPS_SMALL then -- coinvolge solo la curva di lead out local dNewCoastingLen = EgtIf( abs( dCoastingLen - dLen) < 500 * GEO.EPS_SMALL, dLen, dCoastingLen) -- verifico se interamente coinvolta AddRetraction( nLeadOutId, LayerParams.vtSlicing, dNewCoastingLen, dWipeLen, dWipeDir) else -- coinvolge parte dell'ultima shell crv local dNewCoastingLen = dCoastingLen - dLen local nCoastingId = AddRetraction( nCrvId, LayerParams.vtSlicing, dNewCoastingLen, 0.0, dWipeDir) EgtAddCurveCompoCurve( nCoastingId, nLeadOutId) EgtSetInfo( nCoastingId, KEY_CLOSED_CRV, 0) -- wipe AddRetraction( nCoastingId, LayerParams.vtSlicing, 0, dWipeLen, dWipeDir) end end end -------------------------------------------------------------------- local function VerifyRibsLink( nLinkId, nCurr, nNext, dStrand, nGrpTmp) local nGrp = EgtGetParent( nCurr) -- verifico se il link interseca le due curve nell'altro estremo local ptS = EgtSP( nCurr) local ptE = EgtEP( nNext) local dParS = EgtCurveParamAtPoint( nLinkId, ptS) local dParE = EgtCurveParamAtPoint( nLinkId, ptE) if dParS or dParE then return false end -- verifico se si trova nella regione ammissibile local nSurfId = EgtGetInfo( nCurr, KEY_ASSOCIATED_SURF, 'i') local nRes = EgtCurveWithRegionClassify( nLinkId, nSurfId) local nType1 = EgtGetInfo( nCurr, KEY_RIBS_TYPE, 'i') local nType2 = EgtGetInfo( nNext, KEY_RIBS_TYPE, 'i') if nType1 == RIB_TYPE.INTERNAL and nType2 == RIB_TYPE.INTERNAL then if nRes == GDB_CRC.OUT or nRes == GDB_CRC.INTERS then return false end elseif nType1 == RIB_TYPE.EXTERNAL and nType2 == RIB_TYPE.EXTERNAL then if nRes == GDB_CRC.IN or nRes == GDB_CRC.INTERS then return false end end -- verifico se il link interseca una delle altre costolature local vRibsIds = EgtGetNameInGroup( nGrp, RIBS_CRV .. '*') local nLinkSrf = EgtSurfFrFatCurve( nGrpTmp, nLinkId, 0.5 * dStrand, false) or GDB_ID.NULL for i = 1, #vRibsIds do if vRibsIds[i] ~= nCurr and vRibsIds[i] ~= nNext then local nRes = EgtCurveWithRegionClassify( vRibsIds[i], nLinkSrf) if nRes == GDB_CRC.INTERS then return false end end end return true end -------------------------------------------------------------------- local function CalcRibsLink( nCurr, nNext, nLoopGrp, dStrand, bForceLink, vtSlicing, nGrpTmp) local ptS = EgtEP( nCurr) local ptE = EgtSP( nNext) local nCrvId = EgtGetFirstInGroup( nLoopGrp) -- recupero la curva di offset su cui calcolare link while nCrvId do local dParS = EgtCurveParamAtPoint( nCrvId, ptS) local dParE = EgtCurveParamAtPoint( nCrvId, ptE) if dParS and dParE then local bInvert = false local bClosed = EgtCurveIsClosed( nCrvId) if bClosed then -- se la curva è chiusa verifico i due percorsi possibili dParS->dParE e dParE->dParS local nCopyId1 = EgtCopyGlob( nCrvId, nCurr, GDB_IN.AFTER) local nCopyId2 = EgtCopyGlob( nCrvId, nCurr, GDB_IN.AFTER) EgtTrimCurveStartEndAtParam( nCopyId1, dParS, dParE) EgtTrimCurveStartEndAtParam( nCopyId2, dParE, dParS) EgtInvertCurve( nCopyId2) local dLen1 = EgtCurveLength( nCopyId1) local dLen2 = EgtCurveLength( nCopyId2) if dLen1 > dLen2 then bInvert = true dParS, dParE = dParE, dParS end EgtErase( nCopyId1) EgtErase( nCopyId2) end local nCopyId = EgtCopyGlob( nCrvId, nLoopGrp) local nLinkId = EgtCopyGlob( nCrvId, nCurr, GDB_IN.AFTER) if dParS > dParE and not bClosed then bInvert = true dParS, dParE = dParE, dParS end EgtTrimCurveStartEndAtParam( nLinkId, dParS, dParE) EgtSetInfo( nLinkId, KEY_TYPE, TYPE.RIB) if bInvert then EgtInvertCurve( nLinkId) end -- verifico se è valido local bValid = VerifyRibsLink( nLinkId, nCurr, nNext, dStrand, nGrpTmp) if not bValid then EgtErase( nLinkId) EgtErase( nCopyId) return end if bClosed then EgtTrimCurveStartEndAtParam( nCrvId, dParE, dParS) EgtErase( nCopyId) else EgtTrimCurveEndAtParam( nCrvId, dParS) EgtTrimCurveStartAtParam( nCopyId, dParE) end return nLinkId end nCrvId = EgtGetNext( nCrvId) end -- se non ho trovato un collegamento sul bordo, creo una linea tra ptS e ptE if bForceLink then local nLinkId = EgtCurveCompoFromPoints( EgtGetParent( nCurr), {ptS, ptE}) local bValid = VerifyRibsLink( nLinkId, nCurr, nNext, dStrand, nGrpTmp) if bValid then EgtSetInfo( nLinkId, KEY_TYPE, TYPE.RIB) EgtModifyCurveExtrusion( nLinkId, vtSlicing, GDB_RT.GLOB) EgtRelocateGlob( nLinkId, nCurr, GDB_IN.AFTER) else EgtErase( nLinkId) end end end -------------------------------------------------------------------- local function VerifyRibsLead( nId, nRibId, dStrand, bInVsOut, nGrpTmp) local nGrp = EgtGetParent( nRibId) local nLeadId = EgtCopyGlob( nId, nGrp) if bInVsOut then EgtExtendCurveStartByLen( nLeadId, dStrand * 0.5) else EgtExtendCurveEndByLen( nLeadId, dStrand * 0.5) end -- verifico che intersechi solo l'estrmo corretto local pt = EgtIf( bInVsOut, EgtEP( nRibId), EgtSP( nRibId)) local dPar = EgtCurveParamAtPoint( nLeadId, pt) if dPar then EgtErase( nLeadId) return false end local pt1 = EgtIf( bInVsOut, EgtSP( nLeadId), EgtEP( nLeadId)) local pt2 = EgtIf( bInVsOut, EgtEP( nRibId), EgtSP( nRibId)) if dist( pt1, pt2) < dStrand + GEO.EPS_SMALL then EgtErase( nLeadId) return false end local _, dParE = EgtCurveDomain( nLeadId) local vtDir = EgtMV( nRibId) local dParCrv = 1 local dTol = 10 * GEO.EPS_SMALL for dParCrv = 1, dParE do local vtS = EgtUV( nLeadId, dParCrv - 1, 1) local vtE = EgtUV( nLeadId, dParCrv, -1) -- se tratto lineare allineato con la direzione del setto verifico sia sufficientemente lontano if AreSameVectorApprox( vtS, vtE) and ( (vtS - vtDir):sqlen() < dTol * dTol or (vtS + vtDir):sqlen() < dTol * dTol) then local dDist = EgtPointCurveDist( EgtUP( nLeadId, dParCrv - 0.5), nRibId) if dDist < dStrand + GEO.EPS_SMALL then EgtErase( nLeadId) return false end end end -- verifico non intersechi altri setti local vRibsIds = EgtGetNameInGroup( EgtGetParent( nRibId), RIBS_CRV .. '*') local nLeadLoc = EgtCopyGlob( nLeadId, nGrpTmp) for i = 1, #vRibsIds do if vRibsIds[i] ~= nRibId then local nCrvLoc = EgtCopyGlob( vRibsIds[i], nGrpTmp) local ptInt = EgtIP( nLeadLoc, nCrvLoc, ORIG()) if ptInt then EgtErase( nLeadId) return false end end end -- se lead out verifico non si sovrapponga al lead in if not bInVsOut then -- recupero il lead in local nPrev = EgtGetPrev( nRibId) if nPrev and EgtGetName( nPrev) == LEAD_IN_CRV then local nSrfTot = EgtSurfFrFatCurve( EgtGetParent( nLeadId), nPrev, 0.5 * dStrand, false) if nSrfTot then local nRes = EgtCurveWithRegionClassify( nLeadId, nSrfTot) if nRes == GDB_CRC.IN or nRes == GDB_CRC.INTERS then EgtErase( nSrfTot) EgtErase( nLeadId) return false end else nSrfTot = EgtSurfFrFatCurve( EgtGetParent( nLeadId), nLeadId, 0.5 * dStrand, false) if nSrfTot then local nRes = EgtCurveWithRegionClassify( nPrev, nSrfTot) if nRes == GDB_CRC.IN or nRes == GDB_CRC.INTERS then EgtErase( nSrfTot) EgtErase( nLeadId) return false end end end EgtErase( nSrfTot) end end EgtErase( nLeadId) return true end ------------------------------------------------------------------- local function FindCorrectRibsLead( dPar, nCrv, nCrvOffs, bLeadInvert, dLeadLen, dStrand, bInVsOut, nGrpTmp) local nLeadId local bInvert = bLeadInvert -- valore di default è quello settato nel file dei parametri local _, dParEnd = EgtCurveDomain( nCrvOffs) local bClosed = EgtCurveIsClosed( nCrvOffs) 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 if bClosed then EgtChangeClosedCurveStart( nCrvOffs, dPar) nOtherCrv = nCrvOffs elseif not bOnlyOneCurve then nOtherCrv = EgtSplitCurveAtParam( nCrvOffs, dPar) end -- calcolo del parametro bInvert if bOnlyOneCurve then -- invert dipende dall'estremo da cui parte il setto bInvert = abs( dPar - dParEnd) < GEO.EPS_SMALL elseif not bClosed then -- invert può essere legato anche alla lunghezza dei tratti possibili local dLen1 = EgtCurveLength( nMainCrv) local dLen2 = EgtCurveLength( nOtherCrv) if dLen1 > dLeadLen - GEO.EPS_SMALL and dLen2 < dLeadLen - GEO.EPS_SMALL then bInvert = true elseif dLen1 < dLeadLen - GEO.EPS_SMALL and dLen2 > dLeadLen - GEO.EPS_SMALL then bInvert = false end if not bInvert then nMainCrv, nOtherCrv = nOtherCrv, nMainCrv end end -- primo tentativo con la curva favorita nLeadId = EgtCopyGlob( nMainCrv, nCrv, EgtIf( bInVsOut, GDB_IN.BEFORE, GDB_IN.AFTER)) if bInvert then EgtInvertCurve( nLeadId) end EgtTrimCurveEndAtLen( nLeadId, dLeadLen) if bInVsOut then EgtInvertCurve( nLeadId) end if VerifyRibsLead( nLeadId, nCrv, dStrand, bInVsOut, nGrpTmp) then -- se valido aggiorno le curve per prossimi lead in/out if bInvert then EgtTrimCurveEndAtLen( nMainCrv, EgtCurveLength( nCrvOffs) - dLeadLen) else EgtTrimCurveStartAtLen( nMainCrv, dLeadLen) end elseif not nOtherCrv then -- se non è valido e non ho altre curve possibili cancello EgtErase( nLeadId) return nil else -- se non è valido ma ho altra curva possibile, tento con quella EgtErase( nLeadId) nLeadId = EgtCopyGlob( nOtherCrv, nCrv, EgtIf( bInVsOut, GDB_IN.BEFORE, GDB_IN.AFTER)) if not bInvert then EgtInvertCurve( nLeadId) end EgtTrimCurveEndAtLen( nLeadId, dLeadLen) if bInVsOut then EgtInvertCurve( nLeadId) end if VerifyRibsLead( nLeadId, nCrv, dStrand, bInVsOut, nGrpTmp) then if bInvert then EgtTrimCurveStartAtLen( nOtherCrv, dLeadLen) else EgtTrimCurveEndAtLen( nOtherCrv, EgtCurveLength( nCrvOffs) - dLeadLen) end else EgtErase( nLeadId) bInvert = not bInvert return nil end -- aggiorno parametro bInvert bInvert = not bInvert end return nLeadId, bInvert 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') if dLILen < GEO.EPS_SMALL then return end -- recupero la curva di offset su cui calcolare leadin local ptS = EgtSP( nCrv) local nCrvOffs = EgtGetFirstInGroup( nLoopsGrp) while nCrvOffs do local dParS = EgtCurveParamAtPoint( nCrvOffs, ptS) if dParS then local nLeadIn = FindCorrectRibsLead( dParS, nCrv, nCrvOffs, bLIInvert, dLILen, dStrand, true, nGrpTmp) -- se lead in possibile if nLeadIn then EgtModifyCurveExtrusion( nLeadIn, vtSlicing, GDB_RT.GLOB) EgtSetInfo( nLeadIn, KEY_TYPE, TYPE.RIB) EgtSetName( nLeadIn, LEAD_IN_CRV) end return end nCrvOffs = EgtGetNext( nCrvOffs) end end -------------------------------------------------------------------- local function AddRibsLeadOut( nCrv, nTPathGrp, nLoopsGrp, vtSlicing, dStrand, nGrpTmp) local dRibsLOLen = EgtGetInfo( nCrv, KEY_RIBS_LEAD_OUT_LEN, 'd') local dRibsLOCoasting = EgtGetInfo( nCrv, KEY_RIBS_LEAD_OUT_COASTING, 'd') local dRibsLOWipe = EgtGetInfo( nCrv, KEY_RIBS_LEAD_OUT_WIPE, 'd') local dRibsLOWipeAng = EgtGetInfo( nCrv, KEY_RIBS_LEAD_OUT_WIPE_DIR, 'd') local bRibsLOInvert = EgtGetInfo( nCrv, KEY_RIBS_LEAD_OUT_INVERT, 'b') if abs( dRibsLOLen) < GEO.EPS_SMALL and abs( dRibsLOCoasting) < GEO.EPS_SMALL and abs( dRibsLOWipe) < GEO.EPS_SMALL then return end local ptE = EgtEP( nCrv, GDB_ID.ROOT) local vtE = EgtEV( nCrv, GDB_ID.ROOT) -- recupero la curva di offset su cui calcolare lead out local nCrvOffs = EgtGetFirstInGroup( nLoopsGrp) while nCrvOffs do local dParE = EgtCurveParamAtPoint( nCrvOffs, ptE, GEO.EPS_SMALL, GDB_RT.GLOB) if dParE then local nCrvLO local nCoasting local nWipe -- trovo curva opportuna per lead out local nCrvRef, bInvert = FindCorrectRibsLead( dParE, nCrv, nCrvOffs, bRibsLOInvert, dRibsLOLen + dRibsLOCoasting, dStrand, false, nGrpTmp) if nCrvRef then -- verifico se la curva ha lunghezza sufficiente local dLen = EgtCurveLength( nCrvRef) local bSkip = ( dLen - dRibsLOLen - dRibsLOCoasting < - GEO.EPS_SMALL) -- primo tratto ( segue offset con flusso aperto) if dRibsLOLen > GEO.EPS_SMALL and not bSkip then nCrvLO = EgtCopyGlob( nCrvRef, nCrv, GDB_IN.AFTER) EgtTrimCurveEndAtLen( nCrvLO, dRibsLOLen) EgtModifyCurveExtrusion( nCrvLO, vtSlicing, GDB_RT.GLOB) EgtSetInfo( nCrvLO, KEY_TYPE, TYPE.RIB) EgtSetName( nCrvLO, LEAD_OUT_CRV) -- aggiorno ptE e vtE ptE = EgtEP( nCrvLO, GDB_ID.ROOT) vtE = EgtEV( nCrvLO, GDB_ID.ROOT) end -- secondo tratto ( segue offset con flusso chiuso) if dRibsLOCoasting > GEO.EPS_SMALL then nCoasting = EgtCopyGlob( nCrvRef, nCrvLO or nCrv, GDB_IN.AFTER) EgtTrimCurveStartAtLen( nCoasting, dRibsLOLen) EgtTrimCurveEndAtLen( nCoasting, dRibsLOCoasting) EgtModifyCurveExtrusion( nCoasting, vtSlicing, GDB_RT.GLOB) EgtSetName( nCoasting, COASTING_CRV) EgtSetInfo( nCoasting, KEY_TYPE, TYPE.COASTING) EgtSetColor( nCoasting, EgtStdColor('ORANGE')) -- aggiorno ptE e vtE ptE = EgtEP( nCoasting, GDB_ID.ROOT) vtE = EgtEV( nCoasting, GDB_ID.ROOT) end EgtErase( nCrvRef) -- terzo tratto ( diretto verso esterno con ugello chiuso) if dRibsLOWipe > GEO.EPS_SMALL then local dAng = dRibsLOWipeAng + s_nDefaultWipeAng local nType = EgtGetInfo( nCrv, KEY_RIBS_TYPE, 'i') if nType == RIB_TYPE.EXTERNAL then dAng = - dAng end vtE:rotate( vtSlicing, EgtIf( bInvert, - dAng, dAng)) local ptFinal = ptE + vtE * dRibsLOWipe -- verifico soddisfi altezza minima per dimensioni utensile local k = 1 while ptFinal:getZ() < s_dHMin + GEO.EPS_SMALL and k < 36 do vtE:rotate( vtSlicing, EgtIf( bInvert, - 10, 10)) ptFinal = ptE + vtE * dRibsLOWipe k = k + 1 end nWipe = EgtCurveCompoFromPoints( nTPathGrp, { ptE, ptFinal}, GDB_RT.GLOB) EgtModifyCurveExtrusion( nWipe, vtSlicing, GDB_RT.GLOB) EgtRelocateGlob( nWipe, nCoasting or nCrvLO or nCrv, GDB_IN.AFTER) EgtSetName( nWipe, WIPE_CRV) EgtSetInfo( nWipe, KEY_TYPE, TYPE.WIPE) EgtSetColor( nWipe, EgtStdColor('AQUA')) end else -- aggiungo coasting e wipe come sulle shell normali AddRetraction( nCrv, vtSlicing, dRibsLOCoasting, dRibsLOWipe, dRibsLOWipeAng) end return end nCrvOffs = EgtGetNext( nCrvOffs) end -- se non ho trovato curva sul bordo su cui fare il lead out aggiungo coasting e wipe come sulle shell normali AddRetraction( nCrv, vtSlicing, dRibsLOCoasting, dRibsLOWipe, dRibsLOWipeAng) end --------------------------------------------------------------------- local function CalcRibsToolPath( nCrvGrp, nTpathGrpId, LayerParams, dCorrZ) -- gruppo temporaneo con sistema di riferimento locale per conti local frLoc = Frame3d( ORIG(), LayerParams.vtSlicing) local nGrpTmp = EgtGroup( nCrvGrp, frLoc, GDB_RT.GLOB) local nRibsGrp = EgtGetFirstNameInGroup( nCrvGrp, RIBS_GRP) -- aggiungo le costolature nel toolpath local vEntIds = EgtGetNameInGroup( nRibsGrp, RIBS_CRV .. '*') for i = 1, #vEntIds do -- 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) -- mi sposto dell'altezza layer EgtMove( nNewEntId, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) EgtModifyCurveExtrusion( nNewEntId, LayerParams.vtSlicing, GDB_RT.GLOB) -- EgtSetColor( nNewEntId, EgtStdColor('GRAY')) 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) end -- recupero i gruppi delle costolature local tabRibs = {} local 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 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 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 -- 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 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 nFakeLink = CalcRibsLink( tabRibs[i][j + 1], tabRibs[i][j], nLoopGrp, LayerParams.dStrand, false, LayerParams.vtSlicing, nGrpTmp) EgtErase( nFakeLink) end end if bSpecialCase then local nFakeLink = CalcRibsLink( tabRibs[i][#tabRibs[i]], tabRibs[i][1], nLoopGrp, LayerParams.dStrand, false, LayerParams.vtSlicing, nGrpTmp) EgtErase( nFakeLink) end end -- se necessario collego le diverse costolature for i = 1, #tabRibs - 1 do local bLink1 = EgtGetInfo( tabRibs[i][1], KEY_RIBS_LINK, 'b') local bLink2 = EgtGetInfo( tabRibs[i + 1][1], KEY_RIBS_LINK, 'b') if bLink1 and bLink2 then local nCnt = #tabRibs[i] CalcRibsLink( tabRibs[i][nCnt], tabRibs[i + 1][1], nLoopGrp, LayerParams.dStrand, false, LayerParams.vtSlicing, nGrpTmp) end end -- leadin/leadout local nCrvRib = EgtGetFirstNameInGroup( nTpathGrpId, RIBS_CRV .. '*') while nCrvRib do -- verifico se necessario lead in local nPrev = EgtGetPrev( nCrvRib) if not nPrev or EgtGetName( nPrev) then AddRibsLeadIn( nCrvRib, nLoopGrp, LayerParams.dStrand, LayerParams.vtSlicing, nGrpTmp) end -- verifico se necessario lead out local nNext = EgtGetNext( nCrvRib) if not nNext or EgtGetName( nNext) then AddRibsLeadOut( nCrvRib, nTpathGrpId, nLoopGrp, LayerParams.vtSlicing, LayerParams.dStrand, nGrpTmp) end nCrvRib = EgtGetNextName( nCrvRib, RIBS_CRV .. '*') end EgtErase( nGrpTmp) end --------------------------------------------------------------------- local function CalcAuxSolidsToolPath( nAuxSolidsGrp, nAuxSolidsPathGrp, nTpathGrpId, LayerParams, dCorrZ) -- recupero le curve relative al primo solido ausiliario local sPrevName = AUX_SOLID_CRV local nSolidId = EgtGetFirstNameInGroup( nAuxSolidsGrp, AUX_SOLIDS_CRV .. '*') while nSolidId do local sName = EgtGetName( nSolidId) if sName ~= sPrevName then -- recupero tutti i percorsi relativi a quel solido local vEntIds = EgtGetNameInGroup( nAuxSolidsPathGrp, sName .. '*') if vEntIds then -- recupero i parametri relativi al solido local nOrder = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_PRINT_ORDER, 'i') local nLinkType = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_LINK_TYPE, 'i') local dLinkParam = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_LINK_PARAM, 'd') local dSPOffset = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_SP_OFFSET, 'd') local dCoastingLen = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_COASTING_LEN, 'd') local dWipeLen = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_WIPE_LEN, 'd') local dWipeDir = EgtGetInfo( nSolidId, KEY_AUX_SOLIDS_WIPE_DIR, 'd') -- copio i percorsi nel gruppo toolpath local nPrev = EgtGetLastInGroup( nTpathGrpId) for i = 1, #vEntIds do local nNewEnt = EgtCopyGlob( vEntIds[i], nPrev, EgtIf( i == 1 or nOrder == PRINT_ORDER.EXT_INT_INF, GDB_IN.AFTER, GDB_IN.BEFORE)) -- correggo posizione EgtMove( nNewEnt, dCorrZ * Z_AX(), GDB_RT.GLOB) EgtMove( nNewEnt, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) EgtModifyCurveExtrusion( nNewEnt, LayerParams.vtSlicing, GDB_RT.GLOB) EgtSetInfo( nNewEnt, KEY_TYPE, TYPE.AUX_SOLID) if EgtCurveIsClosed( nNewEnt) then EgtSetInfo( nNewEnt, KEY_CLOSED_CRV, 1) -- eventuale inversione curva if LayerParams.bInvert then EgtInvertCurve( nNewEnt) end end nPrev = nNewEnt end local vNewEntIds = EgtGetNameInGroup( nTpathGrpId, sName .. '*') -- Aggiungo link AddLink( vNewEntIds, nTpathGrpId, nLinkType, dLinkParam, dSPOffset, LayerParams.dStrand, LayerParams.vtSlicing) -- Coasting e wipe for i = 1, #vNewEntIds do local nNextId = EgtGetNext( vNewEntIds[i]) or GDB_ID.NULL local nType = EgtGetInfo( nNextId, KEY_TYPE, 'i') if nType ~= TYPE.LINK then AddRetraction( vNewEntIds[i], LayerParams.vtSlicing, dCoastingLen, dWipeLen, dWipeDir) end end end end sPrevName = sName nSolidId = EgtGetNextName( nSolidId, AUX_SOLIDS_CRV .. '*') end end --------------------------------------------------------------------- local function AddSpiralVaseLeadOut( nOldId, LayerParams) if LayerParams.nLeadOutType ~= LEAD_TYPE.NONE then EgtTrimCurveEndAtLen( nOldId, EgtCurveLength( nOldId) - LayerParams.dOffsetLP) local nLeadOut = AddLeadOut( nOldId, LayerParams, EgtGetParent( nOldId)) if nLeadOut then local dDelta = LayerParams.dLayHeight / EgtCurveLength( nOldId) * EgtCurveLength( nLeadOut) EgtSpiralizeCurve( nLeadOut, dDelta) end AddRetractionOnLastCrv( nOldId, EgtGetParent( nOldId), LayerParams, LayerParams.dCoastingLen, LayerParams.dWipeLen, LayerParams.dWipeDir) else AddRetraction( nOldId, LayerParams.vtSlicing, LayerParams.dCoastingLen, LayerParams.dWipeLen, LayerParams.dWipeDir) end end --------------------------------------------------------------------- local function SpiralVase( vLayIds, dCorrZ, LayerParams) local nOldId local bFirst = true local nSlicingType = EgtGetInfo( s_nPartId, KEY_SLICING_TYPE, 'i') -- copio ultimo layer if nSlicingType ~= SLICING_TYPE.DEG45 then local nNewLay = EgtCopyGlob( vLayIds[#vLayIds], vLayIds[#vLayIds], GDB_IN.AFTER) table.insert( vLayIds, nNewLay) 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) end -- ciclo sui layer for nIdx = 1, #vLayIds do -- cerco i gruppi di contorni local vCrvGrpIds = EgtGetNameInGroup( vLayIds[ nIdx], CONTOUR_GRP.."*") if #vCrvGrpIds > 1 then -- se più di un gruppo di curve warning EgtOutLog( 'Warning : in spiral vase mode more than one curve (layer '..tostring( nIdx)..') - CalcToolPath') end for i = 1, #vCrvGrpIds do -- recupero il gruppo dei percorsi local nPathGrpId = EgtGetFirstNameInGroup( vCrvGrpIds[i], 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( vCrvGrpIds[i], TOOLPATH_GRP) if not nTpathGrpId then nTpathGrpId = EgtGroup( vCrvGrpIds[i]) EgtSetName( nTpathGrpId, TOOLPATH_GRP) else EgtEmptyGroup( nTpathGrpId) end -- creo il percorso di lavoro : local nEntId = EgtGetFirstInGroup( nPathGrpId) while nEntId do local nNewEntId = EgtCopyGlob( nEntId, nTpathGrpId, GDB_IN.LAST_SON) -- correggo posizione in Z ( per essere sicuri di appoggiare sul piano) EgtMove( nNewEntId, dCorrZ * Z_AX(), GDB_RT.GLOB) if nSlicingType == SLICING_TYPE.DEG45 then -- eventuale spostamento dell'altezza layer EgtMove( nNewEntId, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) end EgtModifyCurveExtrusion( nNewEntId, LayerParams.vtSlicing, GDB_RT.GLOB) -- eventuale inversione if LayerParams.bInvert then EgtInvertCurve( nNewEntId) EgtSetInfo( nNewEntId, KEY_INVERTED_CRV, 1) end EgtSetColor( nNewEntId, EgtStdColor('GRAY')) -- se primo layer if bFirst and nNewEntId then -- mi sposto dell'altezza layer EgtMove( nNewEntId, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) -- eventuale lead in if LayerParams.nLeadInType ~= LEAD_TYPE.NONE then EgtTrimCurveStartAtLen( nNewEntId, LayerParams.dOffsetLP) AddLeadIn( nNewEntId, LayerParams, nTpathGrpId) end bFirst = false else -- modifico lo start point per collegarlo alla curva precedente local ptOld = EgtEP( nOldId, GDB_ID.ROOT) if dist( EgtSP( nNewEntId, GDB_ID.ROOT), ptOld) < LayerParams.dStrand + 10 then EgtChangeClosedCurveStartPoint( nNewEntId, ptOld, GDB_RT.GLOB) EgtModifyCurveStartPoint( nNewEntId, ptOld, GDB_RT.GLOB) else EgtOutLog( 'Warning : in spiral vase mode no link betweeen toolpaths (layer '..tostring( nIdx)..') - CalcToolPath') -- aggiungo uscita, coasting e wipe sulla curva precedente AddSpiralVaseLeadOut( nOldId, LayerParams) end EgtSpiralizeCurve( nNewEntId, LayerParams.dLayHeight) end nOldId = nNewEntId nEntId = EgtGetNext( nEntId) end end if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / #vLayIds * 100, 0) == 1 then EgtDraw() return end end -- aggiungo uscita, coasting e wipe su ultima curva AddSpiralVaseLeadOut( nOldId, LayerParams) end --------------------------------------------------------------------- function CalcToolPath.Exec( nPartId) s_nPartId = nPartId -- Verifico il pezzo if not s_nPartId then EgtOutBox( 'Error missing part', 'ToolPathCalc') return end -- Recupero i layer da processare local vLayIds = EgtGetNameInGroup( s_nPartId, SLICE_LAYER.."*") if not vLayIds then EgtOutBox( 'Error missing slices', 'ToolPathCalc') return end -- recupero i parametri per calcolo dei toolpath local LayerParams = GetLayerParamsForToolPathCalc() local dCorrZ = ComputeZCorrection( LayerParams) -- se necessario sposto anche il solido di partenza if dCorrZ > 10 * GEO.EPS_SMALL then local vtMove = Vector3d( 0, 0, dCorrZ) -- se slicing a 45° aggiungo correzione anche in direzione dello slicing local nSlicingType = EgtGetInfo( s_nPartId, KEY_SLICING_TYPE, 'i') or 1 if nSlicingType == SLICING_TYPE.DEG45 then vtMove = vtMove + LayerParams.dLayHeight / 2 * LayerParams.vtSlicing end local SolidLayId = EgtGetFirstNameInGroup( s_nPartId, PRINT_SOLID) if SolidLayId then EgtSetInfo( s_nPartId, KEY_MOVED_PART, vtMove) local EntId = EgtGetFirstInGroup( SolidLayId) while EntId do EgtMove( EntId, vtMove) EntId = EgtGetNext( EntId) end end end -- caso spiral vase if LayerParams.bSpiralVase then SpiralVase( vLayIds, dCorrZ, LayerParams) return end -- Ciclo sui layer for nIdx = 1, #vLayIds do -- recupero eventuale gruppo di solidi ausiliari nAuxSolidsGrp = EgtGetFirstNameInGroup( vLayIds[nIdx], AUX_SOLIDS_GRP) -- 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)) -- correggo posizione in Z ( per essere sicuri di appoggiare sul piano) EgtMove( nNewEntId, dCorrZ * Z_AX(), GDB_RT.GLOB) -- mi sposto dell'altezza layer EgtMove( nNewEntId, LayerParams.dLayHeight * LayerParams.vtSlicing, GDB_RT.GLOB) -- eventuale inversione local nType = EgtGetInfo( nNewEntId, KEY_TYPE, 'i') if LayerParams.bInvert then if nType == TYPE.OUTER_SHELL or nType == TYPE.INNER_SHELL or ( nType == TYPE.INFILL and EgtCurveIsClosed( nNewEntId)) then EgtInvertCurve( nNewEntId) EgtSetInfo( nNewEntId, KEY_INVERTED_CRV, 1) end end if EgtCurveIsClosed( nNewEntId) then EgtSetInfo( nNewEntId, KEY_CLOSED_CRV, 1) end EgtModifyCurveExtrusion( nNewEntId, LayerParams.vtSlicing, GDB_RT.GLOB) EgtSetColor( nNewEntId, EgtStdColor('GRAY')) EgtSetStatus( nNewEntId, GDB_ST.ON) nEntId = EgtGetNext( nEntId) end -- aggiungo gli opportuni raccordi sulle shell complete local vIds = EgtGetAllInGroup( nTpathGrpId) AddLink( vIds, nTpathGrpId, LayerParams.nLinkType, LayerParams.dLinkParam, LayerParams.dSPOffs, LayerParams.dStrand, LayerParams.vtSlicing) -- aggiungo gli opportuni raccordi sulle shell con numero diverso di passate local nPrev = EgtGetFirstNameInGroup( nTpathGrpId, EXTRA_SHELL_CRV .. '*') local sPrevName = EgtGetName( nPrev or GDB_ID.NULL) local nCurr = EgtGetNextName( nPrev or GDB_ID.NULL, EXTRA_SHELL_CRV .. '*') while nCurr do local sCurrName = EgtGetName( nCurr) if sCurrName == sPrevName then local ptS = EgtEP( nPrev) local ptE = EgtSP( nCurr) local nLinkId = EgtCurveCompoFromPoints( nTpathGrpId, {ptS, ptE}) if nLinkId then EgtRelocateGlob( nLinkId, nCurr, GDB_IN.BEFORE) EgtModifyCurveExtrusion( nLinkId, LayerParams.vtSlicing, GDB_RT.GLOB) EgtSetInfo( nLinkId, KEY_TYPE, TYPE.LINK) EgtSetName( nLinkId, LINK_CRV) end end sPrevName = sCurrName nPrev = nCurr nCurr = EgtGetNextName( nCurr, EXTRA_SHELL_CRV .. '*') 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 = EgtGetFirstInGroup( nTpathGrpId) if EgtGetName( nId or GDB_ID.NULL) == LEAD_IN_CRV then nId = EgtGetNext( nId) end local nFirstId = nId local nLastId = EgtGetLastInGroup( nTpathGrpId) if EgtGetName( nLastId or GDB_ID.NULL) == LEAD_OUT_CRV then nLastId = EgtGetPrev( nLastId) end while nId do -- recupero i parametri local dCoastingLen, dWipeLen, dWipeDir local nType = EgtGetInfo( nId, KEY_TYPE, 'i') local bClosed = EgtGetInfo( nId, KEY_CLOSED_CRV, 'b') or false if ( nType == TYPE.EXTRA_SHELL or nType == TYPE.EXTRA_OUTER_SHELL) and not bClosed then local bInverted = EgtGetInfo( nId, KEY_INVERTED_CRV, 'b') or false local vCoastLen = EgtGetInfo( nId, KEY_EXTRA_SHELL_COASTING, 'vd') local vWipeLen = EgtGetInfo( nId, KEY_EXTRA_SHELL_WIPE, 'vd') local vWipeDir = EgtGetInfo( nId, KEY_EXTRA_SHELL_WIPE_DIR, 'vd') -- se curva è stata invertita devo prendere le info legate a quello che era il suo punto di inizio, altrimenti prendo le info legate al punto finale dCoastingLen = EgtIf( bInverted, vCoastLen[1], vCoastLen[2]) dWipeLen = EgtIf( bInverted, vWipeLen[1], vWipeLen[2]) dWipeDir = EgtIf( bInverted, vWipeDir[1], vWipeDir[2]) else dCoastingLen = LayerParams.dCoastingLen dWipeLen = LayerParams.dWipeLen dWipeDir = LayerParams.dWipeDir end if nId == nLastId then AddRetractionOnLastCrv( nId, nTpathGrpId, LayerParams, dCoastingLen, dWipeLen, dWipeDir) else local nNextId = EgtGetNext( nId) if EgtGetInfo( nNextId, KEY_TYPE, 'i') ~= TYPE.LINK then -- aggiungo retrazione if nId == nFirstId then AddRetraction( nId, LayerParams.vtSlicing, dCoastingLen, EgtIf( LayerParams.nLeadInType == LEAD_TYPE.NONE, dWipeLen, 0), dWipeDir) else AddRetraction( nId, LayerParams.vtSlicing, dCoastingLen, dWipeLen, dWipeDir) end end end nId = EgtGetNextName( nId, SHELL_CRV .. "*") or EgtGetNextName( nId, EXTRA_SHELL_CRV .. "*") or EgtGetNextName( nId, INFILL_CRV .. '') end -- sistemo i solid ausiliari local nAuxSolidsPathGrp = EgtGetFirstNameInGroup( nCrvGrpId, AUX_SOLIDS_GRP) if nAuxSolidsGrp then CalcAuxSolidsToolPath( nAuxSolidsGrp, nAuxSolidsPathGrp, nTpathGrpId, LayerParams, dCorrZ) end -- sistemo le costolature local nRibsGrp = EgtGetFirstNameInGroup( nCrvGrpId, RIBS_GRP) if nRibsGrp then CalcRibsToolPath( nCrvGrpId, nTpathGrpId, LayerParams, dCorrZ) end --passo al gruppo di contorni successivo nCrvGrpId = EgtGetNextName( nCrvGrpId, CONTOUR_GRP.."*") end if EgtProcessEvents( EgtIf( PRINT, 300, 0) + nIdx / #vLayIds * 100, 0) == 1 then EgtDraw() return end end end --------------------------------------------------------------------- return CalcToolPath