-- 2024/11/22 -- Template per la creazione di un cabinet -- Intestazioni require( 'EgtBase') _ENV = EgtProtectGlobal() EgtEnableDebug( false) ------------------------------------------------------------------------------------------------------------------------- -- FUNZIONI BASE PER GENERARE I COMPO SOLID INIZIO ------------------------------------------------------------------------------------------------------------------------- local TOOL = {} _G.TOOL = TOOL function TOOL.SaveMePlease() EgtSaveFile('D:\\Temp\\marmo\\Vein3D\\FUCK.nge') end -- CREAZIONE dei Layer di un singolo Part -- I nomi dei layer sono: OutLoop, Region, Ref, Labels, Aux function TOOL.CreatePartLayer(PartName, sUNICode) -- Pezzo e Layer local Pz = EgtGroup(GDB_ID.ROOT,GDB_RT.LOC) -- pezzo EgtSetName( Pz, sUNICode..PartName) local LOut = EgtGroup(Pz,GDB_RT.LOC) -- layer della figura principale EgtSetName(LOut,'OutLoop') local LReg = EgtGroup(Pz,GDB_RT.LOC) -- layer regione EgtSetName(LReg,'Region') local LRef = EgtGroup(Pz,GDB_RT.LOC) -- layer riferimenti EgtSetName(LRef,'Ref') EgtSetStatus( LRef, GDB_ST.OFF) local LLabel= EgtGroup(Pz,GDB_RT.LOC) -- layer etichette EgtSetName(LLabel,'Labels') local LAux= EgtGroup(Pz,GDB_RT.LOC) -- layer etichette EgtSetName(LAux,'Aux') EgtOutLog(' Creo Part: '..sUNICode..PartName) --SaveMePlease() return Pz end -- -- RESTITUISCE una tabella con gli Id dei layer costruiti nella funzione CreatePartLayer part, -- Se il nome del Part non esiste restituice nil function TOOL.FindLayers( IdPart) if not EgtIsPart( IdPart) then CMP.ERR = 1 CMP.MSG = CMP.MSG.." In FindLayers 'IdPart' non è un Part" return nil end local tbLayer = {} tbLayer['OutLoop'] = EgtGetFirstNameInGroup(IdPart, 'OutLoop') tbLayer['Region'] = EgtGetFirstNameInGroup(IdPart, 'Region') tbLayer['Ref'] = EgtGetFirstNameInGroup(IdPart, 'Ref') tbLayer['Labels'] = EgtGetFirstNameInGroup(IdPart, 'Labels') tbLayer['Aux'] = EgtGetFirstNameInGroup(IdPart, 'Aux') local nInLoopLay = EgtGetFirstNameInGroup(IdPart, 'InLoop') if nInLoopLay then tbLayer['InLoop'] = nInLoopLay end return tbLayer end -- -- ASSEGNO Info per conoscere le direzioni dei lati function TOOL.SetMachiningInfo(Layer, bInLoop) -- if not bInLoop then return end if EgtIsLayer( Layer) then local LayerName = EgtGetName( Layer) -- verifico che sia di tipo In o Out, altrimenti ricerco nel Part il layer if not LayerName == 'OutLoop' or not LayerName == 'InLoop' then Layer = EgtGetFirstInGroup( Layer) CMP.ERR = 2 CMP.MSG = CMP.MSG.." In SetMachiningInfo il Layer non è di tipo 'OutLoop' o 'InLoop'." end else CMP.ERR = 3 CMP.MSG = CMP.MSG.." In SetMachiningInfo il Layer non è di tipo 'OutLoop' o 'InLoop'." end local nId = EgtGetFirstInGroup(Layer) local nPrevId = EgtGetLastInGroup(Layer) local nNextId = EgtGetNext(nId) local nFirstId = nId local nEdges = EgtGetGroupObjs(Layer) if nEdges == 1 then EgtSetInfo(nId, 'PrevAng', 0) EgtSetInfo(nId, 'NextAng', 0) return end for i = 1, nEdges do -- recupero i dati local vtCurrS = EgtSV(nId, GDB_RT.GLOB) local vtPrevE = EgtEV(nPrevId, GDB_RT.GLOB) local vtCurrE = EgtEV(nId, GDB_RT.GLOB) local vtNextS = EgtSV(nNextId, GDB_RT.GLOB) local vtAx = Z_AX() if bInLoop then vtAx=-vtAx end local NextAng = GetRotation( vtCurrE, vtNextS, vtAx) local PrevAng = GetRotation( vtPrevE, vtCurrS, vtAx) -- scrivo le info EgtSetInfo(nId, 'PrevAng', PrevAng) EgtSetInfo(nId, 'NextAng', NextAng) -- aggiorno gli id nPrevId = nId nId = nNextId nNextId = EgtGetNext(nNextId) if nNextId == nil then nNextId = nFirstId end end end -- -- DEVO RICEVERE SOLO UN CONTORNO!! Da semplificare -- Dato un contorno ricavo i lati nel Layer di appartenenza del contorno -- altrimenti se Part ricavo i lati nel loop specificato (Default=OutLoop o InLoop) function TOOL.ExplodeAndNameEdges( IdLoop, bInLoop) local sNameLayer = '' if bInLoop == nil then bInLoop = false end if bInLoop then sNameLayer = 'InLoop' else sNameLayer = 'OutLoop' end if not IdLoop or IdLoop == -1 then end -- Se l'Id è un Part if EgtIsPart( IdLoop) then local tbLayer = TOOL.FindLayers( IdLoop) if tbLayer then IdLoop = EgtGetFirstInGroup( tbLayer[sNameLayer]) end end -- Se l'Id è un Layer if EgtIsLayer( IdLoop) then local LayerName = EgtGetName( IdLoop) -- verifico che sia di tipo In o Out, altrimenti ricerco nel Part il layer if LayerName == sNameLayer then IdLoop = EgtGetFirstInGroup( IdLoop) else local tbLayer = TOOL.FindLayers( EgtGetParent(IdLoop)) if tbLayer then IdLoop = EgtGetFirstInGroup( tbLayer[sNameLayer]) end end end local nLay = EgtGetParent(IdLoop) local nEdge, nTotEdges = EgtExplodeCurveCompo(IdLoop) local nCount = 1 local tbIdLoop = {} while nEdge do local tbName = EgtNumToString(nCount) EgtSetName( nEdge, "A"..tbName) nCount = nCount + 1 table.insert( tbIdLoop, nEdge) nEdge = EgtGetNext(nEdge) end -- Ricavo info direzioni TOOL.SetMachiningInfo(nLay,bInLoop) return tbIdLoop end -- -- CREAZIONE LAyer per le dimensioni function TOOL.CreateDimensionLayer() local Pz = EgtGroup(GDB_ID.ROOT,GDB_RT.LOC) -- layer dimensioni e etichette EgtSetName( Pz, 'Dimensions') end -- -- Per disporre i pezzi in piano non sovrappposti (in assemblaggio non serve) local HorizontalOffset = 0 -- Creazione del part assegnato un contorno esploso: -- tbLayer : tabella dei layer (FindLayers dato il Part) -- sName : nome da assegnare in grafica -- tbIdEntCrv: tabella delle entità che costituiscono il contorno (da ExplodeAndNameEdges) -- dTh : spessore pezzo -- dOffset : per messa in piano dei pezzi (0 se non si usa) -- bInLoop : tipo di contorno function TOOL.CreatePart(tbLayer, sName, tbIdEntCrv, dTh, bInLoop) -- recupero il layer del contorno local IdCurrLayer = EgtGetParent( tbIdEntCrv[1]) -- recupero l'Id del part local IdPart = EgtGetParent( IdCurrLayer) -- costruisco il contorno chiuso local IdLoop = EgtCurveCompoByChain( IdCurrLayer, tbIdEntCrv, EgtSP(tbIdEntCrv[1],GDB_RT.GLOB), false, GDB_RT.GLOB) -- Nel Layer Region definisco la regione piana local IdReg = EgtSurfFlatRegion(tbLayer['Region'],IdLoop) -- Se InLoop allora faccio la sottrazione con la regione OutRegion if bInLoop then local IdOutRegion = EgtGetPrev(IdReg) local vtNorm1 = EgtSurfFrNormVersor(IdOutRegion) local vtNorm2 = EgtSurfFrNormVersor(IdReg) if AreOppositeVectorApprox( vtNorm1, vtNorm2) then EgtInvertSurf(IdReg) end if not EgtSurfFrSubtract( IdOutRegion,IdReg) then CMP.ERR = 5 CMP.MSG = CMP.MSG.." Sottrazione tra superficie 'OutLoop' "..tostring(IdOutRegion).." e 'InLoop' "..tostring(IdReg).." non riuscita." end EgtErase(IdReg) end -- if bInLoop then EgtInvertCurve(IdLoop) end -- elimino il contorno chiuso EgtErase(IdLoop) -- Se sono InLoop non devo settare if bInLoop then for i = 1, #tbIdEntCrv do EgtInvertCurve(tbIdEntCrv[i]) end return end -- definisco spessore pezzo if dTh then EgtSetInfo(IdPart, 'Th', dTh) end -- INFO NECESSARIA EgtSetInfo(IdPart, 'Paired',tostring(IdPart)) -- inserisco le etichette del pezzo nel centro della superofocie local ptTop = EgtCP( IdReg, GDB_RT.GLOB) local ptBottom = Point3d( ptTop:getX(), -ptTop:getY(), dTh) EgtTextAdv(tbLayer['Labels'], ptTop,0,sName, '', 10, '', 15,1.5,0,GDB_TI.MC) if CMP.DrawSolid then EgtSetGridFrame(Frame3d(ORIG(),GDB_FR.BOTTOM)) EgtTextAdv(tbLayer['Labels'], ptBottom,0,sName, '', 10, '', 15,1.5,0,GDB_TI.MC, GDB_RT.GRID) EgtSetGridFrame(Frame3d(ORIG(),GDB_FR.TOP)) end -- dispongo il pezzo in piano local vtMove = Vector3d({HorizontalOffset,0,0}) --EgtMove(IdPart,vtMove, GDB_RT.GLOB) HorizontalOffset = HorizontalOffset + ptTop:getX() + 10 end -- -- Sposto l'etichetta del nome del Part nel Solido associato function TOOL.RelocateLabels() local nPartId = EgtGetFirstPart() while nPartId do local nChild = EgtGetInfo(nPartId, 'Child','i') if nChild then local nLaySource = EgtGetFirstNameInGroup(nPartId, 'Labels') if nLaySource then EgtRelocateGlob( nLaySource, nChild) end end nPartId = EgtGetNext(nPartId) end end -- -- Crea una copia dello spigolo e lo salva nel layer Ref -- Nome del part (da tbName[1]), -- Nome del Layer (OutLoop o InLoop), -- Nome dello spigolo, -- Nome della copia riferimento -- Info per spostamento Ref in funzione di una variabile function TOOL.CreateReference( sUNICode, sNamePart, sNameLayer,sNameEdge, sNameRef, dVar, sDir) local IdPart = EgtGetFirstNameInGroup(GDB_ID.ROOT, sUNICode..sNamePart) local tbLayer = TOOL.FindLayers( IdPart) --accoppiamento di left su bottom local IdEnt = EgtGetFirstNameInGroup(tbLayer[sNameLayer], sNameEdge) if not IdEnt then CMP.ERR=6 CMP.MSG= CMP.MSG..' Non esiste il lato '..sNameEdge..' nel layer '..sNameLayer..' del part '..sNamePart return end -- creo la copia dello spigolo come riferimento local IdRef = EgtCopy( IdEnt, tbLayer['Ref']) EgtSetName( IdRef, sNameRef) if dVar and sDir then EgtSetInfo(IdRef, 'Var', dVar) EgtSetInfo(IdRef, 'Dir', sDir) end return IdRef end -- -- Crea una copia dello del punto dello spigolo e lo salva nel layer Ref -- Nome del part (da tbName[1]), -- Nome del Layer (OutLoop o InLoop), -- Nome dello spigolo, -- Nome della copia punto -- Tipo di punto: 0/nil START, 1 END, 2 MID function TOOL.CreatePointReference( sNamePart, sNameLayer,sNameEdge, sNameRef, nTypePt) local IdPart = EgtGetFirstNameInGroup(GDB_ID.ROOT, sUNICode..sNamePart) local tbLayer = TOOL.FindLayers( IdPart) --accoppiamento di left su bottom local IdEnt = EgtGetFirstNameInGroup(tbLayer[sNameLayer], sNameEdge) if not IdEnt then CMP.ERR=6 CMP.MSG= CMP.MSG..' Non esiste il lato '..sNameEdge..' nel layer '..sNameLayer..' del part '..sNamePart return end local pt = EgtSP(IdEnt, GDB_RT.GLOB) if nTypePt == 1 then pt = EgtEP(IdEnt, GDB_RT.GLOB) elseif nTypePt == 2 then pt = EgtMP(IdEnt, GDB_RT.GLOB) end local IdPtRef = EgtPoint( tbLayer['Ref'], pt, GDB_RT.GLOB) EgtSetName(IdPtRef, sNameRef) return IdPtRef end -- -- Accoppia lato a riferimento -- Nome del pezzo da accoppiare -- Nome del riferimento da usare -- Nome del pezzo destinatario dell'accoppiamento -- Nome del riferimento da usare come destinatario dell'accoppiamento -- Concordanza del verso dei due spigoli -- Angolo relativo tra i due pezzi: porta la normale della regione del pezzo corrente a coincidere -- con la normale della regione del pezzo destinatario; il segno è riferito al verso del riferimento del part destinatario -- Modalità di accoppiamento tra gli spigoli (0: start-start, 1:start-end, 2: end-start, 3: end-end, 4: mid-mid) function TOOL.SetPairInfo( sUNICode, sMyNamePart, sNameMyRef, sToNamePart, sNameToRef, nPairSpin, dPairAng, nPairMode) local nPart = EgtGetFirstNameInGroup(GDB_ID.ROOT, sUNICode..sMyNamePart) EgtSetInfo(nPart, "PairMyRef", sNameMyRef) EgtSetInfo(nPart, "PairToRef", sUNICode..sToNamePart.."_"..sNameToRef) EgtSetInfo(nPart, "PairSpin", nPairSpin) EgtSetInfo(nPart, "PairAng", dPairAng) if nPairMode then EgtSetInfo(nPart, "PairMode", nPairMode) end end -- Disegna la quota lineare -- Nome del part in cui trovare il primo punto di riferimento -- Nome del punto riferimento nel part indicato sopra -- Nome del part in cui trovare il secondo punto di riferimento -- Nome del punto riferimento nel part indicato sopra -- Nome/valore stringa da scrivere nella dimensione -- Frame del piano su cui disegnare la quotatura -- Offset etichetta rispetto al punto medio local function DrawLinearDimension( sNamePart1, sNameRef1, sNamePart2, sNameRef2, sNameDimension, GridFrame, ptOffset) EgtSetGridFrame(GridFrame) local nDimLay = EgtGetFirstNameInGroup(GDB_ID.ROOT, 'Dimensions') local nBottomLay = EgtGetFirstNameInGroup(GDB_ID.ROOT, sUNICode..sNamePart1) local nRefBottom = EgtGetFirstNameInGroup(nBottomLay, 'Ref') local nRef = EgtGetFirstNameInGroup(nRefBottom, sNameRef1) local pt1 = EgtSP( nRef, GDB_RT.GRID) local nTopLay = EgtGetFirstNameInGroup(GDB_ID.ROOT, sUNICode..sNamePart2) local nRefTop = EgtGetFirstNameInGroup(nTopLay, 'Ref') nRef = EgtGetFirstNameInGroup(nRefTop, sNameRef2) local pt2 = EgtSP( nRef, GDB_RT.GRID) local ptMid = (pt1 + pt2) / 2 + ptOffset local nDim = EgtAlignedDimension( nDimLay, pt1, pt2, ptMid, sNameDimension, GDB_RT.GRID) EgtSetColor( nDim, EgtStdColor( 'YELLOW')) EgtRelocate(nDim, GDB_RT.GRID) EgtSetName(nDim, sNameDimension) end -- ------------------------------------------------------------------------------------------------------------------------- -- FUNZIONI BASE PER GENERARE I COMPO SOLID FINE ------------------------------------------------------------------------------------------------------------------------- -- ------------------------------------------------------------------------------------------------------------------------- -- -- CREAZIONE/IMPORTAZIONE Loop INIZIO -- ------------------------------------------------------------------------------------------------------------------------- -- -- Importa un contorno chiuso da file nge -- function ImportOutLoop( tbLayer, sNameFileNGE) -- local OutLayer = tbLayer['OutLoop'] -- if not EgtInsertFile( sNameFileNGE) then -- EgtOutLog(' IMPORTAZIONE FALLITA: '..sNameFileNGE) -- end -- -- recupero ultimo Part -- local LastPart = EgtGetLastPart() -- local FstLayerInLstPart = EgtGetFirstGroupInGroup( LastPart) -- local IdLoop = EgtGetFirstInGroup( FstLayerInLstPart) -- if not EgtRelocateGlob( IdLoop, OutLayer) then -- EgtOutLog(' RELOCATE AFLLITA MISERAMENTE: '..tostring(IdLoop)..';'..tostring(OutLayer)) -- end -- EgtErase(LastPart) -- local tbIdLoop = ExplodeAndNameEdges( IdLoop) -- EgtSetInfo(tbIdLoop[1],'AF',1) -- EgtSetInfo(tbIdLoop[2],'AF',2) -- EgtSetInfo(tbIdLoop[3],'AF',2) -- EgtSetInfo(tbIdLoop[4],'AF',2) -- EgtSetInfo(tbIdLoop[5],'AF',2) -- EgtSetInfo(tbIdLoop[6],'AF',2) -- EgtSetInfo(tbIdLoop[7],'AF',1) -- --SaveMePlease() -- -- definizione SideAng -- -- EgtSetInfo( tbIdLoop[1], 'OrigSideAng', 45) -- return tbIdLoop -- end -- -- function TOOL.AddLoopToLayer(nLay, tbIdLoop, dOffset, bInvert, bInLoop) -- local tbLoop = {} -- for i = 1, #tbIdLoop do -- local nNewId = EgtCopyGlob(tbIdLoop[i], nLay) -- if bInvert then EgtInvertCurve(nNewId) end -- table.insert(tbLoop, nNewId) -- end -- TOOL.SetMachiningInfo(nLay, bInLoop) --return tbLoop local nNewLoop = EgtCurveCompoByChain(nLay, tbIdLoop, EgtSP(tbIdLoop[1], GDB_RT.GLOB), false) if bInvert then EgtInvertCurve(nNewLoop) end if dOffset > 0 then EgtOffsetCurve(nNewLoop, dOffset, GDB_OT.EXTEND) end local tbNewLoop = TOOL.ExplodeAndNameEdges( nNewLoop, bInLoop) return tbNewLoop end -- ------------------------------------------------------------------------------------------------------------------------- -- -- CREAZIONE/IMPORTAZIONE Loop FINE -- ------------------------------------------------------------------------------------------------------------------------- -- -- Restituisce l'angolo precedente e successivo dell'aentità passata local function GetPrevNextAng(IdEnt) local PrevAng = EgtGetInfo(IdEnt,'PrevAng','d') or 0 local NextAng = EgtGetInfo(IdEnt,'NextAng','d') or 0 return PrevAng, NextAng end -- Confronto i dati del file.dat con quelli letti da programma function IsDataChanged() local bOk = false if not tbOrigVal.v1 then return true end if math.abs(CMP.V1 - tbOrigVal.v1) > 0.5 then bOk = bOk or true end if math.abs(CMP.V2 - tbOrigVal.v2) > 0.5 then bOk = bOk or true end if math.abs(CMP.V3 - tbOrigVal.v3) > 0.5 then bOk = bOk or true end if math.abs(CMP.V4 - tbOrigVal.v4) > 0.5 then bOk = bOk or true end if math.abs(CMP.V5 - tbOrigVal.v5) > 0.5 then bOk = bOk or true end if math.abs(CMP.V6 - tbOrigVal.v6) > 0.5 then bOk = bOk or true end if math.abs(CMP.V7 - tbOrigVal.v7) > 0.5 then bOk = bOk or true end if math.abs(CMP.V8 - tbOrigVal.v8) > 0.5 then bOk = bOk or true end return bOk end function CalcDraftAngle( vtDir1, vtDir2, dPairAng1, dPairAng2, dAngBetween) -- vengono restituiti il SideAng ( calcolato dall'angolo in 3d), i due nuovi angoli di forma per i due pezzi -- dBeta1 è riferito al pezzo 1 e dBeta2 è riferito al pezzo 2 local dAngTilt1 = dPairAng1 - 90 local dAngTilt2 = dPairAng2 - 90 local vtN1 = Vector3d({0,100,0}) local vtN2 = Vector3d({0,100,0}) vtN1:rotate(X_AX(),dAngTilt1) vtN2:rotate(X_AX(), dAngTilt2) vtN2:rotate(Z_AX(), dAngBetween) local vtPerp = vtN1 ^ vtN2 local vtInters1 = vtN1 ^ vtPerp local vtInters2 = vtPerp ^ vtN2 --local dAng3d = GetRotation(vtInters1, vtInters2, vtPerp) local dAng3d = GetAngle(vtInters1, vtInters2) local dBeta1 = GetAngle( vtDir1, vtPerp) local dBeta2 = GetAngle( vtDir2, vtPerp) local dSideAng = (180 - dAng3d) / 2 return dSideAng, dBeta1, dBeta2 end function TJunction(dAngBetween, dTh1, dTh2, nType, dLen1, dLen2, bOnLoop) -- restituisce le lunghezze L1 e L2 adattate in base al tipo di giunzione -- nType == 1 -> TrimStart ( del Part2) -- nType == 2 -> TrimEnd ( del Part1) local dXOffset = 0 if not bOnLoop then bOnLoop = false end if dAngBetween > 0 then if nType == 1 then -- trim start local dDeltaStart = - dTh1 / sin(dAngBetween) dLen2 = dLen2 + dDeltaStart dXOffset = dDeltaStart -- extend end dLen1 = dLen1 + dTh1 * tan(90- math.abs(dAngBetween)) elseif nType == 2 then -- trim end dLen1 = dLen1 - dTh2 / sin(dAngBetween) -- extend start local dDeltaStart = dTh2 * tan(90- math.abs(dAngBetween)) dLen2 = dLen2 + dDeltaStart dXOffset = dDeltaStart end else -- qui sto estendendo le lunghezze, infatti gli angoli sono nergativi e quindi anche il loro seno if nType == 1 then -- il trim start diventa un extend end local dDelta = - dTh2 / sin(dAngBetween) if not bOnLoop then dDelta = dDelta - dTh1 * tan(90 - math.abs(dAngBetween)) end dLen1 = dLen1 + dDelta -- accorcio lo start local dDeltaStart = - dTh2 * tan(90- math.abs(dAngBetween)) dLen2 = dLen2 + dDeltaStart dXOffset = dDeltaStart elseif nType == 2 then -- il trim end diventa un extend start local dDeltaStart = - dTh1 / sin(dAngBetween) if not bOnLoop then dDeltaStart = dDeltaStart - dTh2 * tan(90 - math.abs(dAngBetween)) end dLen2 = dLen2 + dDeltaStart dXOffset = math.abs(dDeltaStart) -- accorcio l'end dLen1 = dLen1 - dTh1 * tan(90- math.abs(dAngBetween)) end end return dLen1, dLen2, dXOffset end function AngleJunction(dAngBetween, dTh1, dTh2, dLen1, dLen2, bOnLoop) -- modifico la lughezza dei lati solo se ho un angolo convesso local dXOffest = 0 if not bOnLoop then local dDelta1 = dTh2 / sin( dAngBetween) local dDelta2 = dTh1 / sin( dAngBetween) if dAngBetween > 0 then dLen1 = dLen1 - dDelta1 dLen2 = dLen2 - dDelta2 else dLen1 = dLen1 + dDelta1 dLen2 = dLen2 + dDelta2 end end return dLen1, dLen2, dXOffest end function ManageJunction(dAngBetween, dTh1, dTh2, nType, dLen1, dLen2, bOnLoop) --nJunctionType -- 1 TrimStart, 2 TrimEnd, 3Ang if nType == 1 or nType == 2 then return TJunction(dAngBetween, dTh1, dTh2, nType, dLen1, dLen2, bOnLoop) elseif nType == 3 then return AngleJunction(dAngBetween, dTh1, dTh2, dLen1, dLen2, bOnLoop) end end function TOOL.CreateAdjustedPart( nLayOutloop, dLen, dH, dBeta1, dBeta2) -- genero la regione piana del rettangolo deformato : -- dLen è la lunghezza del lato su cui si va ad agganciare il pezzo che sto creando, quindi è un dato fisso -- bisogna calcolare gli altri tre lati del quadrilatero -- dProj1 dProj2 -- __|_____________________________|__ -- \ / | -- \ beta1 beta2 / |dH -- \ /___________dLen__________\ / | -- beta 1 e beta 2 sono gli angoli alla base -- dLen1 e dLen2 sono le proiezioni delle diagonali sulla base maggiore -- beta 1 e beta 2 possono essere < 90 e quindi potrei avere anche un trapezio ribaltato, oppure un quasi parallelogramma if dBeta1 == nil then dBeta1 = 90 end if dBeta2 == nil then dBeta2 = 90 end local dProj1 = dH * tan( dBeta1 - 90) local dProj2 = dH * tan( dBeta2 - 90) local pt1 = ORIG() local pt2 = Point3d(dLen,0,0) local nLine1 = EgtLine( nLayOutloop, pt1, pt2) EgtSetName(nLine1, "A1") local pt3 = Point3d(dLen + dProj2,dH,0) local nLine2 = EgtLine( nLayOutloop, pt2, pt3) EgtSetName(nLine2, "A2") local pt4 = Point3d( dProj1,dH,0) local nLine3 = EgtLine( nLayOutloop, pt3, pt4) EgtSetName(nLine3, "A3") local nLine4 = EgtLine( nLayOutloop, pt4, pt1) EgtSetName(nLine4, "A4") TOOL.SetMachiningInfo(nLayOutloop, false) return {nLine1, nLine2, nLine3, nLine4} end function TOOL.SetSideAng(nLay, sEdgeName, dAng) local nEdge = EgtGetFirstNameInGroup( nLay, sEdgeName) EgtSetInfo( nEdge, 'SideAng', dAng) EgtSetInfo( nEdge, 'OrigSideAng', dAng) end -- ptCenter sono le coordinate del centro del foro rispetto all'angolo in basso a sinistra function TOOL.CreateCircularHole(nPart, ptCenter, dDiam) local nInLoopLay = EgtGroup(nPart) EgtSetName(nInLoopLay, 'InLoop') local HoleId = EgtCircle( nInLoopLay, ptCenter, dDiam, GDB_RT.GLOB) TOOL.SetMachiningInfo(nInLoopLay, true) TOOL.CreatePart(TOOL.FindLayers(nPart),nil,{HoleId},nil,true) end function TOOL.CreateParetina(i, tbIdLoopTC, tbInfo) local nPrev = i > 1 and i - 1 or #tbIdLoopTC local nNext = i < #tbIdLoopTC and i + 1 or 1 local dPairAngPrev = EgtGetInfo(tbInfo.nPrev, 'PairAng', 'd') or 0 local dPairAngNext = EgtGetInfo(tbInfo.nNext, 'PairAng', 'd') or 0 local dPairAng = EgtGetInfo(tbInfo.nId, 'PairAng', 'd') or 0 local vtDirCurr = EgtSV( tbIdLoopTC[i], GDB_RT.GLOB) local vtDirNext = EgtSV( tbIdLoopTC[nNext], GDB_RT.GLOB) local vtDirPrev = EgtEV( tbIdLoopTC[nPrev], GDB_RT.GLOB) local dLen = EgtCurveLength(tbIdLoopTC[i]) local dLenPrev = EgtCurveLength(tbIdLoopTC[#tbIdLoopTC]) local dLenNext = EgtCurveLength(tbIdLoopTC[nNext]) local PAng, NAng = GetPrevNextAng(tbIdLoopTC[i]) local dTh = EgtGetInfo(tbInfo.nId, 'dTh','d') -- calcolo l'angolo di sformo con il pezzo precedente local dXOffset = 0 -- se i due pezzi hanno angoli di accoppiamento discordi allora uno sta sotto e uno sta sopra local bSameSide = dPairAng * dPairAngPrev > 0 if bSameSide then if tbInfo.nJunctionType == 3 then local dSideAng_4, _, dBeta_DX = CalcDraftAngle( vtDirPrev, vtDirCurr, dPairAngPrev, dPairAng, PAng) tbInfo.dAngBR = 180 - dBeta_DX if tbInfo.bOnLoop then dSideAng_4 = dSideAng_4 * (-1) end if PAng < 0 then dSideAng_4 = dSideAng_4 * (-1) end tbInfo.dSideAngR = dSideAng_4 if not tbInfo.bOnLoop then dLenPrev, dLen, dXOffset = ManageJunction(PAng,dTh, dTh,tbInfo.nJunctionType, dLenPrev, dLen) end else -- se ho una giunzione a T allora devo aggiustare la lunghezza dei pezzi sia che la faccia sia On, sia che sia Off dLenPrev, dLen, dXOffset = ManageJunction(PAng,dTh, dTh,tbInfo.nJunctionType, dLenPrev, dLen) -- setto il sideang da giunzione a T -- setto il sideang da giunzione a T local dSideAng_4 = 90 - math.abs(PAng) if tbInfo.bOnLoop then dSideAng_4 = dSideAng_4 * (-1) end tbInfo.dSideAngR = dSideAng_4 end else -- setto il sideAng da giunzione a T (che va bene anche se la giunzione è angolata ma senza pezzo precedente) local dSideAng = PAng < 0 and (90 + PAng) or 90-PAng if tbInfo.bOnLoop then dSideAng = dSideAng * (-1) end tbInfo.dSideAngR = dSideAng -- visto che il pezzo precedente non è dallo stesso lato allora corrego l'estensione del pezzo corrente (in funzione del suo spessore) if not tbInfo.bOnLoop then local dOffset = dTh * tan( 90 - PAng) dLen = dLen + dOffset if tbInfo.nJunctionType == 1 then dXOffset = dXOffset + dOffset end end end -- -- calcolo l'angolo di sformo con il pezzo successivo bSameSide = dPairAng * dPairAngNext > 0 if bSameSide then if tbInfo.nJunctionType == 3 then local dSideAng_2, dBeta_SX, __ = CalcDraftAngle( vtDirCurr, vtDirNext, dPairAng, dPairAngNext, NAng) tbInfo.dAngBL = 180 - dBeta_SX if tbInfo.bOnLoop then dSideAng_2 = dSideAng_2 * (-1) end if NAng < 0 then dSideAng_2 = dSideAng_2 * (-1) end tbInfo.dSideAngL = dSideAng_2 if not tbInfo.bOnLoop then dLen, dLenNext = ManageJunction(NAng, dTh, dTh, tbInfo.nJunctionType, dLen, dLenNext) end else -- se ho una giunzione a T allora devo aggiustare la lunghezza dei pezzi sia che la faccia sia On, sia che sia Off dLen, dLenNext = ManageJunction(NAng, dTh, dTh, tbInfo.nJunctionType, dLen, dLenNext) -- setto il sideang da giunzione a T local dSideAng_2 = 90 - math.abs(NAng) if tbInfo.bOnLoop then dSideAng_2 = dSideAng_2 * (-1) end tbInfo.dSideAngL = dSideAng_2 end else -- setto il sideAng da giunzione a T (che va bene anche se la giunzione è angolata ma senza pezzo successivo) local dSideAng = NAng < 0 and (90 + NAng) or 90-NAng if tbInfo.bOnLoop then dSideAng = dSideAng * (-1) end tbInfo.dSideAngL = dSideAng -- visto che il pezzo successivo non è dallo stesso lato allora correggo l'estensione del pezzo corrente (in funzione del suo spessore) if not tbInfo.bOnLoop then local dOffset = dTh * tan( 90 - NAng) dLen = dLen + dOffset if tbInfo.nJunctionType == 2 then dXOffset = dXOffset + dOffset end end end tbInfo.dLen = dLen tbInfo.dXOffset = dXOffset end return TOOL