-- 2023/05/__ -- |ultima modifica:| -- |aggiunta gestione di più loop interni| --ERR == -1 valore di default --ERR == 1 SLD.CurrId non è valido ( == -1) --ERR == 0 eseguito senza problemi -- Intestazioni require( 'EgtBase') _ENV = EgtProtectGlobal() EgtEnableDebug( false) -- Dati raccolti direttamente dal programma local SLD = {} --input SLD.THICK = 40 SLD.CurrId = -1 -- output SLD.CurrPartSolid = -1 SLD.CurrSrfTmId = -1 SLD.ERR = -1 ----- mi preparo a ricevere argomenti local arg = ... local bAutoRun = false if arg then bAutoRun = arg.AutoRun end _G.SLD = SLD local ColorSTD = 'AQUA' local ColocERR = 'ORANGE' -- Id del primo Part del progetto local IdP_FirstPart = -1 -- Id del layer "OutLoop" local IdL_OutLoop = -1 -- Id del layer "InLoop" local IdL_InLoop = -1 -- Id del layer "OnPath" local IdL_OnPath = -1 -- Id del layer "Pocket" local IdL_Pocket = -1 -- Id del layer "FiloTop" local IdL_FiloTop = -1 -- Id del Part "SOLID" local IdP_SOLID = -1 -- Id dei layer apprtenenti a "SOLID" local IdL_Temp = -1 local IdL_Solid = -1 local IdL_Bound = -1 local IdL_Faces = -1 --[[ tabella contenente: IdSurf → superificie di taglio, ptS → punto in basso a sinistra dalla superificie vtS → direzioned del lato basso della superficie Ang → inclinazione rispetto alla verticale Hill → tallone NAng → direzione agolo orizzontale lato successivo ]]-- local tbId_RectSurf = {} -- tabella contenente i lati del layer OutLoop: IdS → lato del contorno local tbId_OutLoop = {} -- tabella contenente le tabelle dei layer degli InLoop: IdI → lato del contorno local tbId_InLoop = {} -- tabella contenente le tabelle delle curve composte del layer OnPath: IdI → local tbId_OnPath = {} -- tabella contenente le tabelle dei lati del layer Pocket: IdI → local tbId_Pocket = {} -- tabella contenente la tabella delle curve composte del layer FiloTop: IdI → local tbId_FiloTop = {} -- Id del solido generato local IdEnt_Part = -1 -- Id del solido da sottrarre local IdEnt_SubPart = -1 -- Id della facce come Flat Region local tbId_Faces = {} -- Spessore grezzo (Ddefault) local RTh = 30 local bAlwaysOnTop = true --local nIdTrimOut = -1 --local nIdTrimIn = -1 local tbTrimTot = {} -- Estensioni delle regioni di taglio per SideAngle --NB: lo spessore dei pezzi è limitato a 100(o meno, se ci sono dei sideAng), quindi per spessori importanti bisognerebbe modificare il valore di questa dimensione local DefaultDim = 100 -- valore di tolleranza minimo per estrarre i contorni da una regione local TollY = 1 local m_bArc = false ---------------------------------------------------------------------------- -- **Preparo ambiente** Part+Layer ---------------------------------------------------------------------------- -- Reimposto a vuoto il valore delle tabelle, resetto gli Id local function ResetAllTabAndVar() tbId_RectSurf = {} -- tabella contenente i lati del layer OutLoop: IdS → lato del contorno tbId_OutLoop = {} -- tabella contenente i lati del layer InLoop: IdI → lato del contorno tbId_InLoop = {} -- tabella delle superfici laterali ( facce adiacenti già mergiate in un'unica superficie), la prima è quella out, le successive sono quelle in tbId_SurfLat = {} -- tabella contenente le curve composte del layer OnPath: IdI → tbId_OnPath = {} -- tabella contenente i lati del layer Pocket: IdI → tbId_Pocket = {} -- tabella contenente le curve composte del layer FiloTop: IdI → tbId_FiloTop = {} -- Id del solido generato IdEnt_Part = -1 -- Id del solido da sottrarre IdEnt_SubPart = -1 -- -- Id della superficie interna del solido -- nIdTrimIn = -1 -- -- Id dalla superficie esterna del solido -- nIdTrimOut = -1 -- tabella delle superfici per costruire il solido tbTrimTot = {} -- tabella delle superfici laterali tbId_SurfLat = {} -- Id della facce come Flat Region tbId_Faces = {} m_bArc = false end -- Elimino il layer solid del Part selezionato local function ClearCurrIdSOLID() IdP_SOLID = EgtGetFirstPart() while IdP_SOLID do local IdP_SOLID_Next = EgtGetNext( IdP_SOLID) local nIdParent = EgtGetInfo(IdP_SOLID, "Parent", 'i') if EgtGetName( IdP_SOLID) == "SOLID" and nIdParent ~= nil and IdFP == nIdParent then EgtErase( IdP_SOLID) break end IdP_SOLID = IdP_SOLID_Next end end -- --[[ Creazione di un nuovo Part: IdP_SOLID → part "SOLID" IdL_Temp → Layer di destinazione delle superfici di taglio IdL_Solid → Layer di destinazione del solido IdL_Bound → Layer di destinazione delle linee di contorno del solido ]]-- local function CreatePartSOLID() ResetAllTabAndVar() IdP_SOLID = EgtGroup(GDB_ID.ROOT,GDB_RT.LOC) EgtSetName( IdP_SOLID, "SOLID") EgtSetInfo(IdP_SOLID, "Parent", IdFP) EgtSetInfo(IdFP, "Child", IdP_SOLID) EgtSetInfo( IdP_SOLID, "Th", RTh) IdL_Temp = EgtGroup(IdP_SOLID,GDB_RT.LOC) EgtSetName( IdL_Temp, "Temp") IdL_Solid = EgtGroup(IdP_SOLID,GDB_RT.LOC) EgtSetName( IdL_Solid, "Surface") IdL_Bound = EgtGroup(IdP_SOLID,GDB_RT.LOC) EgtSetName( IdL_Bound, "Boundary") IdL_Faces = EgtGroup(IdP_SOLID,GDB_RT.LOC) EgtSetName( IdL_Faces, "Faces") end -- ---------------------------------------------------------------------------- -- **Recupero info dei pezzi** SideAng:Ang, Heel; FiloTop:Depth ---------------------------------------------------------------------------- -- restituisce le info sui lati inclinati local function GetAngHill( nInd) if nInd then local A = EgtGetInfo( nInd, 'OrigSideAng', 'd') local H = EgtGetInfo( nInd, 'Heel', 'd') if A and H then return A, H elseif A and not H then return A, 0 end end return 0,0 end -- -- restituisce l'affondamento del profilo FiloTop local function GetDepth( nInd) if nInd then local D = EgtGetInfo( nInd, 'Depth', 'd') if D then return D end end return 0 end -- -- restituisce l'affondamento del profilo FiloTop local function GetDepthOnPath( nInd) if nInd then D = EgtGetInfo( nInd, 'Depth', 'd') if not D then D = EgtGetInfo( nInd, 'Th', 'd') end if D then return D end end return 5 end -- -- restituisce il valore dell'angolo successivo (se <0 angolo concavo) local function GetnNextAng( nInd) local A = EgtGetInfo( nInd, 'NextAng', 'd') return A end -- -- restituisce il valore dell'angolo precedente (se <0 angolo concavo) local function GetnPrevAng( nInd) local A = EgtGetInfo( nInd, 'PrevAng', 'd') return A end -- ---------------------------------------------------------------------------- -- **Carico tabelle** IdL_OutLoop, IdL_InLoop, tbId_OnPath, tbId_Pocket, tbId_FiloTop ---------------------------------------------------------------------------- -- riceve la tablella e il nome del Layer, riempie la tabella e restituisce l'ID del layer local function GetIdFromLay( myTab, sLay) RTh = SLD.THICK --IdFP = EgtGetFirstPart() local IdLay = EgtGetFirstNameInGroup( IdFP, sLay) local tbIdLayTemp = {} -- salvo l'id solo del primo layer con nome sLay local IdFirstLay = IdLay -- questo while su IdLay serve se ho più gruppi con questo nome while IdLay do local IdS = EgtGetFirstInGroup( IdLay) while IdS do if EgtGetType( IdS) == GDB_TY.CRV_LINE or EgtGetType( IdS) == GDB_TY.CRV_ARC or EgtGetType( IdS) == GDB_TY.CRV_COMPO then if sLay == 'OutLoop' then table.insert( myTab, IdS) elseif sLay == 'InLoop' or sLay == 'Pocket' or sLay == 'FiloTop' or sLay == 'OnPath' then table.insert( tbIdLayTemp, IdS) end end IdS = EgtGetNext( IdS) end if sLay == 'InLoop' or sLay == 'Pocket' or sLay == 'FiloTop' or sLay == 'OnPath' then table.insert( myTab, tbIdLayTemp) tbIdLayTemp = {} end IdLay = EgtGetNextName( IdLay, sLay) end return IdFirstLay end -- ---------------------------------------------------------------------------- -- **Solido di riferimento** IdEnt_Part ---------------------------------------------------------------------------- -- dato il contorno del pezzo local function CreateSolid() local nLoopOut, nCountOut = EgtExtractSurfTmLoops( tbId_SurfLat[1], IdL_Bound) local tbLoop1 ={nLoopOut} local tbLoop2 ={nLoopOut + 1} --local ptSBottom = EgtSP( nLoopOut + 1) local nLoopIn = -1 local nCountIn = 0 if #tbId_SurfLat > 1 then for k = 2, #tbId_SurfLat, 1 do nLoopIn, nCountIn = EgtExtractSurfTmLoops( tbId_SurfLat[k], IdL_Bound) for p=0, nCountIn - 1, 1 do if math.abs(EgtSP( nLoopIn + p):getZ() - EgtSP( nLoopOut):getZ()) < 0.01 then table.insert(tbLoop1, nLoopIn + p) else --math.abs(EgtSP( nLoopIn + p):getZ() - EgtSP( nLoopOut + 1):getZ()) < EPS_SMALL then table.insert(tbLoop2, nLoopIn + p) end end end end -- creo le SurfTm delle facce sopra e sotto local nIdSurf1 = EgtSurfTmByRegion( IdL_Solid, tbLoop1) local nIdSurf2 = EgtSurfTmByRegion( IdL_Solid, tbLoop2) for i = 1, #tbLoop1, 1 do EgtErase( tbLoop1[i]) end for i = 1, #tbLoop2, 1 do EgtErase( tbLoop2[i]) end EgtInvertSurf( {nIdSurf1, nIdSurf2}) tbTrimTot = {nIdSurf1, nIdSurf2} for k = 1, #tbId_SurfLat, 1 do table.insert( tbTrimTot, tbId_SurfLat[k]) end local nIdTrimTot = EgtSurfTmByTriangles( IdL_Solid, tbTrimTot, false) EgtSetColor( nIdTrimTot, ColorSTD) EgtErase( tbTrimTot) tbTrimTot = {nIdTrimTot} IdEnt_Part = nIdTrimTot SLD.CurrPartSolid = IdP_SOLID SLD.CurrSrfTmId = nIdTrimTot end -- ---------------------------------------------------------------------------- -- **Pocket** ---------------------------------------------------------------------------- local function PocketSolid() -- se sono presenti dei ribassi provvedo a disegnarli if #tbId_Pocket > 0 then for i = 1, #tbId_Pocket do local IdCompo_Pocket, nCrv = EgtCurveCompoByChain( IdL_Solid, tbId_Pocket[i], EgtSP( tbId_Pocket[i][1]), false) local IdEnt_Pocket = EgtSurfTmByRegionExtrusion( IdL_Solid, {IdCompo_Pocket}, Z_AX()*(2* RTh)) EgtSurfTmSubtract( IdEnt_Part, IdEnt_Pocket) EgtErase( {IdEnt_Pocket}) EgtErase( {IdCompo_Pocket}) local a = 0 end end end ---------------------------------------------------------------------------- -- **OnPath** ---------------------------------------------------------------------------- local function Engraves( nId) -- se non restituisce nulla allora utlizzo direttamente la copia local vtExtr local vtO nNbr = 1 vtO = EgtSV( nId) vtExtr = Vector3d( vtO[3]/vtO[1], 0, 1) vtExtr:normalize() local D = 10 EgtMove( {nId}, vtExtr*(D)) if D > 0 or not vt then local nEntCopy_1 = EgtCopy( nId, IdL_Temp) local nEntCopy_2 = EgtCopy( nId, IdL_Temp) EgtMove( {nEntCopy_2}, vtExtr*(- D)) local nLine_1 = EgtLine( IdL_Temp, EgtSP( nEntCopy_1, GDB_ID.ROOT ), EgtSP( nEntCopy_2, GDB_ID.ROOT )) local nLine_2 = EgtLine( IdL_Temp, EgtEP( nEntCopy_1, GDB_ID.ROOT ), EgtEP( nEntCopy_2, GDB_ID.ROOT )) local nCompo = EgtCurveCompoByChain( IdL_Solid, {nEntCopy_1,nLine_1,nEntCopy_2,nLine_2}, EgtSP( nLine_1), false) vtExtr:rotate( vtO, 90) local IdSubSolid = EgtSurfTmByRegionExtrusion( IdL_Solid, {nCompo}, vtExtr*(2)) EgtSurfTmSubtract( IdEnt_Part, IdSubSolid) EgtErase( {nEntCopy_1,nLine_1,nEntCopy_2,nLine_2, nCompo, IdSubSolid, nId}) end end -- -- genero i tagli singoli local function OnPathSolid() for i=1, #tbId_OnPath, 1 do for j=1, #tbId_OnPath[i], 1 do local nInd = tbId_OnPath[i][j] local D = GetDepthOnPath( nInd) if D > RTh then SLD.ERR = 1 EgtSetColor( {IdEnt_Part}, ColocERR) end -- creo una copia nel Layer "Temp" local nEntCopy = EgtCopy( nInd, IdL_Temp) local nId, nNbr = EgtExplodeCurveCompo( nEntCopy) -- definisco il vettore di spostamento verticale del solido da sottrarre local vtV = Z_AX() if nId ~= nil then for j=0 , nNbr-1, 1 do local nTempId = nId + j local vt = EgtSV( nTempId) vt:rotate(vtV, 90) if D > 0 or not vt then local nEntCopy_1 = EgtCopy( nTempId, IdL_Temp) local nEntCopy_2 = EgtCopy( nTempId, IdL_Temp) EgtMove( {nEntCopy_2}, vtV*(- D)) local nLine_1 = EgtLine( IdL_Temp, EgtSP( nEntCopy_1, GDB_ID.ROOT ), EgtSP( nEntCopy_2, GDB_ID.ROOT )) local nLine_2 = EgtLine( IdL_Temp, EgtEP( nEntCopy_1, GDB_ID.ROOT ), EgtEP( nEntCopy_2, GDB_ID.ROOT )) local nCompo = EgtCurveCompoByChain( IdL_Solid, {nEntCopy_1,nLine_1,nEntCopy_2,nLine_2}, EgtSP( nLine_1), false) local IdSubSolid = EgtSurfTmByRegionExtrusion( IdL_Solid, {nCompo}, vt*(2)) EgtSurfTmSubtract( IdEnt_Part, IdSubSolid) EgtErase( {nEntCopy_1,nLine_1,nEntCopy_2,nLine_2, nCompo, IdSubSolid, nTempId}) end end else Engraves( nEntCopy) end end end end -- ---------------------------------------------------------------------------- -- **Filo Top** ---------------------------------------------------------------------------- -- sottraggo al solido il contorno FiloTop local function FiloTopSolid() local nLay = EgtGetFirstNameInGroup( IdFP, "FiloTop") for i = 1, #tbId_FiloTop do local D = GetDepth( nLay) if D < 0.1 then return end local IdEnt_SurfFiloTop = EgtSurfTmByRegionExtrusion( IdL_Solid, tbId_FiloTop[i], Z_AX()*(- D -1)) EgtMove( {IdEnt_SurfFiloTop}, Z_AX()*1) EgtSurfTmSubtract( IdEnt_Part, IdEnt_SurfFiloTop) EgtErase( {IdEnt_SurfFiloTop}) nLay = EgtGetNextName( nLay, "FiloTop") end end -- ---------------------------------------------------------------------------- -- HillPlane D ---------------------------------------------------------------------------- local function PlaneShift( nId, Hill) if bAlwaysOnTop then Hill = Hill * (-1) end local vtTrasl = Z_AX() * Hill EgtMove( nId, vtTrasl) end -- ---------------------------------------------------------------------------- -- HillPlane C ---------------------------------------------------------------------------- local function PlaneNoShift( nId) PlaneShift( nId, 0) end -- ---------------------------------------------------------------------------- -- HillPlane A ---------------------------------------------------------------------------- local function HillPlaneAng( nId, ptS, vtS, Ang, Hill) local nIdHill = EgtCopy( nId, IdL_Solid) EgtRotate( nIdHill, ptS, vtS, Ang, GDB_ID.ROOT) local dTrasl if bAlwaysOnTop then if Ang > 0 then dTrasl = ( RTh - Hill) * math.tan( Ang * math.pi / 180) else dTrasl = 0 end else if Ang > 0 then dTrasl = 0 else dTrasl = ( RTh - Hill) * math.tan( -Ang * math.pi / 180) end end local vtTrasl = ( vtS ^ Z_AX()) * dTrasl EgtMove( nIdHill, vtTrasl) if bAlwaysOnTop then if Ang < 0 then PlaneShift( nId, Hill) end else if Ang > 0 then PlaneShift( nId, Hill) end end local pt_a, vn_a = EgtSurfTmFacetCenter( nId, 0) local pt_h, vn_h = EgtSurfTmFacetCenter( nIdHill, 0) EgtCutSurfTmPlane( nIdHill, pt_a, vn_a, false) EgtCutSurfTmPlane( nId, pt_h, vn_h, false) PlaneNoShift( nId) return nIdHill, vtTrasl end -- ------------------------------------------------------------------------------ ---- HillPlane B ------------------------------------------------------------------------------ --local function HillPlaneNegAng( nId, ptS, vtS, Ang, Hill) -- local nIdHill, vtTrasl = HillPlanePosAng( nId, ptS, vtS, Ang, Hill, true) -- return nIdHill, vtTrasl --end ---- ---------------------------------------------------------------------------- -- **Side Ang** ---------------------------------------------------------------------------- local function SideAngSolid( tbLoop, bInLoop) local tbIdR = {} local IdS local Ang = 0 local Hill = 0 local NAng = 0 m_bArc = false local tbArc = {} local tbLimited = {} for i=1, #tbLoop, 1 do IdS = tbLoop[i] -- recupero i dati SideAng per ogni lato Ang, Hill = GetAngHill( IdS) NAng = GetnNextAng( IdS) if math.abs(NAng) <= 2 then NAng = 0 end -- verifico che il lato presenti un angolo inclinato if EgtGetType( IdS) == GDB_TY.CRV_ARC then m_bArc = true table.insert(tbArc, true) local ptStart = EgtSP(IdS, GDB_ID.ROOT) local vtStart = EgtSV( IdS, GDB_ID.ROOT) local vtEnd = EgtEV( IdS, GDB_ID.ROOT) if Ang == 0 then local vtExtr = Z_AX() * RTh if bAlwaysOnTop then vtExtr = vtExtr * (-1) end local nSurfId = EgtSurfTmByExtrusion(IdL_Solid, IdS, vtExtr) if bAlwaysOnTop then EgtInvertSurf( nSurfId) end local tbInfoRot = { nSurfId, ptStart, vtStart, Ang, Hill, NAng, vtEnd} table.insert(tbIdR,tbInfoRot) table.insert(tbLimited, false) else -- costruisco la superficie laterale generata dall'arco con una swept lungo l'arco stesso -- la sezione di cui effetturare lo sweep viene creata trovando il punto di partenza del secondo arco che delimita questa superficie local dLatMove = RTh * math.tan( math.abs(Ang) * pi / 180) local vtLatMove = (Z_AX() ^ vtStart) local vtVertMove = Z_AX() * RTh if not bInLoop then vtLatMove = vtLatMove * (-1) end -- devo controllare se il side ang e lo spessore della lastra sono abbastanza da far collassare l'arco in un punto ed eventualmente andare oltre -- verifico quindi se devo limitare la superficie della sezione di cono local dRad = EgtArcRadius( IdS) local bLimited = false local dArcAng = EgtArcAngCenter( IdS) local bCheckLimit = (dArcAng > 0 and Ang < 0 ) or ( dArcAng < 0 and Ang > 0) if bCheckLimit then if dRad < math.abs(dLatMove) + 0.01 then vtLatMove = vtLatMove * dRad vtVertMove = Z_AX() * dRad / math.tan( math.abs(Ang) * pi / 180) bLimited = true end else vtLatMove = vtLatMove * dLatMove end table.insert(tbLimited, bLimited) if (Ang > 0 and bAlwaysOnTop) or ( Ang < 0 and not bAlwaysOnTop) then vtLatMove = vtLatMove * ( -1) end if bAlwaysOnTop then vtVertMove = vtVertMove * (-1) end local ptSecondArcStart = ptStart + ( vtVertMove + vtLatMove) local nIdLine = EgtLine(IdL_Temp,ptStart,ptSecondArcStart,GDB_ID.ROOT) local nPointId = EgtPoint( IdL_Temp, ptSecondArcStart) local nSurfId = 0 if not bLimited then nSurfId = EgtSurfTmSwept(IdL_Solid,nIdLine,IdS,Z_AX(),false,0.01,GDB_ID.ROOT) EgtInvertSurf( nSurfId) else local vtAx = Z_AX() if not bAlwaysOnTop then vtAx = vtAx * (-1) end nSurfId = EgtSurfTmRuled( IdL_Solid, nPointId, IdS) EgtInvertSurf( nSurfId) -- nSurfId = EgtSurfTmCone(IdL_Solid,ptSecondArcStart, vtAx, dRad, RTh) end EgtErase( nIdLine) EgtErase( nPointId) local tbInfoRot = { nSurfId, ptStart, vtStart, Ang, Hill, NAng, vtEnd} table.insert(tbIdR,tbInfoRot) end elseif EgtGetType( IdS) ~= GDB_TY.CRV_COMPO then table.insert(tbArc, false) local ptS = EgtSP( IdS, GDB_ID.ROOT) local vtS = EgtSV( IdS, GDB_ID.ROOT) local vtE = EgtEV( IdS, GDB_ID.ROOT) local IdRect = EgtCurveGetFatCurve( IdS, IdL_Temp, DefaultDim, true) local IdSurf = EgtSurfTmByRegion( IdL_Solid, IdRect) EgtErase( IdRect) local tbInfoRot = { IdSurf, ptS, vtS, Ang, Hill, NAng, vtE} table.insert( tbIdR, tbInfoRot) table.insert(tbLimited, false) end end -- posiziono i piani calcolati in precedenza e creo i piani di Hill for i=1, #tbIdR, 1 do local dTempAng = 90 if not tbArc[i] then EgtRotate( tbIdR[i][1], tbIdR[i][2], tbIdR[i][3], -tbIdR[i][4] + dTempAng, GDB_ID.ROOT) end -- se ho l'hill lo creo e lo aggiungo alle caratteristiche della faccia if tbIdR[i][4] ~= 0 and tbIdR[i][5] > 0 then if not tbArc[i] then local nIdHill nIdHill, tbIdR[i][8] = HillPlaneAng( tbIdR[i][1], tbIdR[i][2], tbIdR[i][3], tbIdR[i][4], tbIdR[i][5]) -- aggiungo l'hill come elemento separato della faccia di taglio tbIdR[i][9] = { nIdHill, tbIdR[i][2] + tbIdR[i][8], tbIdR[i][3], tbIdR[i][4], tbIdR[i][5], tbIdR[i][6], tbIdR[i][8]} else --- hill da gestire per il caso del lato che è un arco end else tbIdR[i][8] = Vector3d({0,0,0}) end end -- **NANG** corrego la dimenione dei piani in funzione dell'angolo che descrivono con il pezzo successivo for i=1, #tbIdR, 1 do local Ind_Curr = i local Ind_Nex = i + 1 if i == #tbIdR then Ind_Nex = 1 end -- se ho solo una faccia laterale termino ( è un foro descritto da un unico loop circolare) if Ind_Curr == Ind_Nex then break end local pt_n, vn_n = EgtSurfTmFacetCenter( tbIdR[Ind_Nex][1], 0) local pt_c, vn_c = EgtSurfTmFacetCenter( tbIdR[Ind_Curr][1], 0) if tbArc[Ind_Nex] then pt_n = tbIdR[Ind_Nex][2] -- prendo startPoint vn_n = tbIdR[Ind_Nex][3] -- prendo vtStart if math.abs( tbIdR[Ind_Curr][6]) > 90 then vn_n = vn_n * (-1) elseif math.abs( tbIdR[Ind_Curr][6]) > 90 then vn_n = EgtEV( tbLoop[Ind_Curr], GDB_ID.ROOT) -- prendo l'end del segmento precedente all'arco end end if tbArc[Ind_Curr] then pt_c = EgtEP( tbLoop[Ind_Curr], GDB_ID.ROOT) -- prendo endPoint vn_c = tbIdR[Ind_Curr][7] -- prendo vtEnd if math.abs( tbIdR[Ind_Curr][6]) < 90 then vn_c = vn_c * (-1) elseif math.abs( tbIdR[Ind_Curr][6]) > 90 then vn_c = tbIdR[Ind_Nex][3] -- prendo lo start del segmento successivo all'arco end end if (not tbArc[Ind_Nex]) and (not tbArc[Ind_Curr]) then if ( tbIdR[Ind_Curr][6] < 0) then vn_n = vn_n * (-1) vn_c = vn_c * (-1) end end -- devo tagliare le superfici di taglio con le superfici di taglio -- gli archi li taglio usando i suoi vettori a inizio e fine curva if tbArc[Ind_Curr] then EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], tbIdR[Ind_Curr][2], - tbIdR[Ind_Curr][3], false) EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], EgtEP(tbLoop[Ind_Curr], GDB_ID.ROOT), tbIdR[Ind_Curr][7], false) else EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], pt_n, vn_n, false) end if not tbArc[Ind_Nex] then EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], pt_c, vn_c, false) end -- nel caso in cui la superficie generata dall'arco è limitata devo tagliare tra loro anche le superfici precedente e successiva all'arco-------------------------------------------------- if tbLimited[Ind_Curr] then local Ind_Pre = Ind_Curr > 1 and (Ind_Curr - 1) or #tbLoop local pt_p, vn_p = EgtSurfTmFacetCenter( tbIdR[Ind_Pre][1], 0) pt_n, vn_n = EgtSurfTmFacetCenter( tbIdR[Ind_Nex][1], 0) -- calcolo l'angolo tra le due facce local dArcAng = EgtArcAngCenter( tbLoop[Ind_Curr]) local dAngSkip = tbIdR[Ind_Pre][6] + tbIdR[Ind_Nex][6] + dArcAng if dAngSkip < 0 then vn_p = vn_p * (-1) vn_n = vn_n * (-1) end EgtCutSurfTmPlane( tbIdR[Ind_Pre][1], pt_n, vn_n, false) EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], pt_p, vn_p, false) end --taglio i piani dei talloni con i piani dei talloni ( se non ho un altro tallone allora taglio con la sup di taglio) local pt_nH, vn_nH local pt_cH, vn_cH if tbIdR[Ind_Curr][5] > 0 then pt_cH, vn_cH = EgtSurfTmFacetCenter( tbIdR[Ind_Curr][9][1], 0) if ( tbIdR[Ind_Curr][6] < 0) then vn_cH = vn_cH * (-1) end end if tbIdR[Ind_Nex][5] > 0 then pt_nH, vn_nH = EgtSurfTmFacetCenter( tbIdR[Ind_Nex][9][1], 0) if ( tbIdR[Ind_Curr][6] < 0) then vn_nH = vn_nH * (-1) end if tbIdR[Ind_Curr][5] > 0 then EgtCutSurfTmPlane( tbIdR[Ind_Curr][9][1], tbIdR[Ind_Nex][9][2], vn_nH, false) EgtCutSurfTmPlane( tbIdR[Ind_Nex][9][1], tbIdR[Ind_Curr][9][2], vn_cH, false) -- se l'angolo con il prossimo lato è positivo, entrambi hanno un hill e gli Ang sono discordi, allora devo anche tagliare gli hill con i piani di taglio e viceversa --if tbIdR[Ind_Curr][6] > 0 and tbIdR[Ind_Curr][4] * tbIdR[Ind_Nex][4] < 0 then if tbIdR[Ind_Curr][6] > 0 then -- ho tolto la condizione che gli angoli debbano essere discordi!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! EgtCutSurfTmPlane( tbIdR[Ind_Nex][9][1], pt_c, vn_c, false) EgtCutSurfTmPlane( tbIdR[Ind_Curr][9][1], pt_n, vn_n, false) EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], tbIdR[Ind_Nex][9][2], vn_nH, false) EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], tbIdR[Ind_Curr][9][2], vn_cH, false) end else EgtCutSurfTmPlane( tbIdR[Ind_Nex][9][1], pt_c, vn_c, false) EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], tbIdR[Ind_Nex][9][2], vn_nH, false) end else if tbIdR[Ind_Curr][5] > 0 then EgtCutSurfTmPlane( tbIdR[Ind_Curr][9][1], pt_n, vn_n, false) EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], tbIdR[Ind_Curr][9][2], vn_cH, false) end end end -- unisco tutte le superfici laterali local tbIdTrim = {} for i=1, #tbIdR, 1 do if tbIdR[i][1] > -1 then table.insert( tbIdTrim, tbIdR[i][1]) if tbIdR[i][5] > 0 then table.insert( tbIdTrim, tbIdR[i][9][1]) end end end if #tbIdR > 0 then local nIdTrim = EgtSurfTmByTriangles( IdL_Solid, tbIdTrim, true) table.insert( tbId_SurfLat, nIdTrim) -- le trimmo con la superficie superiore e con quella inferiore local ptOrig_t local ptOrig_b if bAlwaysOnTop then ptOrig_t = tbIdR[1][2] ptOrig_b = ptOrig_t + Point3d({0,0,-RTh}) else ptOrig_b = tbIdR[1][2] ptOrig_t = ptOrig_b + Point3d({0,0,RTh}) end EgtCutSurfTmPlane( nIdTrim, ptOrig_b, {0,0,-1}, false, GDB_RT.GLOB) EgtCutSurfTmPlane( nIdTrim, ptOrig_t, {0,0,1}, false, GDB_RT.GLOB) end end -- local function CorrectReference() local sName = EgtGetName( IdFP) if sName ~= "SOLID" then local nLayRef = EgtGetFirstNameInGroup( IdFP, "Ref") local nRef = EgtGetFirstInGroup(nLayRef) while nRef do local var = EgtGetInfo(nRef, "Var") if var == "Th" then var = RTh else var = EgtGetInfo(nRef, "Var", "i") end local dir = EgtGetInfo(nRef, "Dir") if dir then local tbDir = EgtSplitString(dir,",") local vtDir = {} for _,sDir in pairs(tbDir) do sDir = sDir:gsub("x", EgtNumToString(var)) table.insert(vtDir, EgtEvalNumExpr(sDir)) end vtDir = Vector3d(vtDir) EgtMove(nRef,vtDir, GDB_RT.GLOB) end nRef = EgtGetNext(nRef) end end end local function GetThickness() local val = EgtGetInfo( IdFP,"Th","d") if val then SLD.THICK = val end end ---------------------------------------------------------------------------- -- **Wire Frame** ---------------------------------------------------------------------------- local function ExplodSurf( nId) local IdFac, Nbr = EgtExplodeSurf(nId) local i = 0 while IdFac and Nbr > 1 and i < Nbr do ExplodSurf( IdFac) IdFac = IdFac + 1 i = i+1 end return IdFac, Nbr end -- -- estraggo il contorno delle superfici del solido local function ExtractBoundaryAndFaces() local nSurfCopy = EgtCopy( tbTrimTot[1], IdL_Temp) local IdFac, Nbr = ExplodSurf( nSurfCopy) local IdS = EgtGetFirstInGroup( IdL_Temp) local nCount = 0 while IdS ~= nil do ------------------------ gestione archi -- local tabMergSurf = {} -- local _, dX, dY = EgtSurfTmFacetMinAreaRectangle( IdS, 0) -- if dY~=nil and dY > TollY then -- local TempIdSmall = EgtExtractSurfTmFacetLoops( IdS, 0, IdL_Bound) -- else -- table.insert( tabMergSurf, IdS) -- end -- EgtSurfTmByTriangles( IdL_Temp, tabMergSurf) -- EgtErase( tabMergSurf) -- IdS = EgtGetNext( IdS) ------------------------ gestione archi ----------- gestione archi che non vengono esplosi---------------- nCount = nCount + 1 local bExplode = false ----------- gestione archi che non vengono esplosi---------------- --- local nLoop, nLoopCount = EgtExtractSurfTmFacetLoops( IdS, 0, IdL_Bound) local ColorApply = 'BLACK' local tbLoopFlatRegion = {} for l=nLoop, nLoop + (nLoopCount-1), 1 do -- coloro il loop e lo aggiungo alla tabella per ricreare la flat region EgtSetColor( l, ColorApply) table.insert(tbLoopFlatRegion, l) end -- ricreo la faccia laterale come flat region e la metto con trasparenza massima local nIdFace = EgtSurfFlatRegion( IdL_Faces, tbLoopFlatRegion) EgtSetAlpha(nIdFace,1) table.insert( tbId_Faces, nIdFace) for l=nLoop, nLoop + (nLoopCount-1), 1 do -- esplodo i loop EgtExplodeCurveCompo( l) end local nIdCurr = IdS IdS = EgtGetNext( IdS) -- cancello la superficie EgtErase( nIdCurr) end -- cancello le linee doppie sugli edge local IdL = EgtGetFirstInGroup(IdL_Bound) while IdL ~= nil do local ptStart = EgtSP( IdL) local ptEnd = EgtEP( IdL) IdL_b = EgtGetFirstInGroup(IdL_Bound) while IdL_b ~= nil do local ptStart_b = EgtSP( IdL_b) local ptEnd_b = EgtEP( IdL_b) if IdL_b ~= IdL and (AreSamePointApprox(ptStart, ptStart_b) and AreSamePointApprox(ptEnd, ptEnd_b)) or (AreSamePointApprox(ptStart, ptEnd_b) and AreSamePointApprox(ptEnd, ptStart_b)) then local IdL_bNext = IdL_b EgtErase( IdL_b) IdL_b = EgtGetNext( IdL_bNext) else IdL_b = EgtGetNext( IdL_b) end end IdL = EgtGetNext( IdL) end end -- ---------------------------------------------------------------------------- -- |ESEGUO FUNZIONI| ---------------------------------------------------------------------------- -- funzione che si occupa di creare il solido finale local function Draw(bPreview) CreatePartSOLID() -- SOLID IdL_OutLoop = GetIdFromLay( tbId_OutLoop, 'OutLoop') IdL_InLoop = GetIdFromLay( tbId_InLoop, 'InLoop') IdL_OnPath = GetIdFromLay( tbId_OnPath, 'OnPath') IdL_Pocket = GetIdFromLay( tbId_Pocket, 'Pocket') IdL_FiloTop = GetIdFromLay( tbId_FiloTop, 'FiloTop') -- SIDEANG SideAngSolid( tbId_OutLoop, false) for i = 1, #tbId_InLoop, 1 do SideAngSolid( tbId_InLoop[i], true) end CreateSolid() ---- POCKET PocketSolid() ---- FILO TOP FiloTopSolid() -- -- ONPATH OnPathSolid() -- WIREFRAME ---- Correzione dei riferimenti CorrectReference() ExtractBoundaryAndFaces() end -- --per uso nell' |omagOFFICE| function SLD.Main() IdFP = SLD.CurrId ClearCurrIdSOLID() if IdFP == -1 then SLD.ERR = 1 return end RTh = SLD.THICK if RTh == 0 then return end GetThickness() Draw( true) EgtSetStatus( IdFP, GDB_ST.OFF) EgtDraw() SLD.ERR = 0 end --per uso nell' |omagOFFICE| --per uso nel |CAM5| (bAutoRun da settare a true) bAutoRun = true -- debug if bAutoRun then ClearCurrIdSOLID() RTh = SLD.THICK IdFP = EgtGetFirstPart() local sName = "" --IdFP = 49389 while IdFP ~= nil and sName ~= "SOLID" do -- procedo a costruire il solido solo se sono in un part con un OutLoop local nLay = EgtGetFirstNameInGroup(IdFP, "OutLoop") if nLay then GetThickness() Draw( true) EgtSetStatus( IdFP, GDB_ST.OFF) end IdFP = EgtGetNextPart(IdFP) sName = EgtGetName(IdFP) --break end --EgtSaveFile('c:\\EgtData\\OmagOFFICE\\Temp\\buche_sottili_SOLID.nge') EgtDraw() --SLD.ERR = 0 end -----per uso nel |CAM5| --_G.SLD_Main = SLD_Main