-- 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 TOOL.nId = GDB_ID.NULL TOOL.nLay = GDB_ID.NULL TOOL.nEdgeId = GDB_ID.NULL TOOL.tbInfo = {} TOOL.nPrev = -1 TOOL.nNext = -1 TOOL.nJunctionType = -1 TOOL.bOnLoop = nil TOOL.dAngBR = nil TOOL.dSideAngR = nil TOOL.dAngBL = nil TOOL.dSideAngL = nil TOOL.dLen = nil TOOL.dH = nil TOOL.dXOffset = nil TOOL.dBeta1 = nil TOOL.dBeta2 = nil function TOOL.SaveMePlease() EgtSaveFile('D:\\Temp\\marmo\\Vein3D\\FOO.nge') end local function FindEdges(nLay) local tbId = {} local nId = EgtGetFirstInGroup(nLay) while nId do table.insert(tbId, nId) nId = EgtGetNext(nId) end return tbId end local function FillInfoTable() TOOL.tbInfo.nPrev = TOOL.nPrev TOOL.tbInfo.nNext = TOOL.nNext TOOL.tbInfo.nJunctionType = TOOL.nJunctionType TOOL.tbInfo.bOnLoop = TOOL.bOnLoop TOOL.tbInfo.dAngBR = TOOL.dAngBR TOOL.tbInfo.dSideAngR = TOOL.dSideAngR TOOL.tbInfo.dAngBL = TOOL.dAngBL TOOL.tbInfo.dSideAngL = TOOL.dSideAngL TOOL.tbInfo.dLen = TOOL.dLen TOOL.tbInfo.dH = TOOL.dH TOOL.tbInfo.dBeta1 = TOOL.dBeta1 TOOL.tbInfo.dBeta2 = TOOL.dBeta2 end function TOOL.WriteDataToChildPart(nParent, nPart, nEdge, dLen, dAngDx, dAngSx, dH, dTh, dBeta1, dBeta2) if not nPart then do return end end if nParent then EgtSetInfo(nParent,"A"..tostring(nEdge), nPart) end if nParent then EgtSetInfo(nPart, 'Parent', nParent) end if nEdge then EgtSetInfo(nPart, 'ParentEdge', nEdge) end if dLen then EgtSetInfo(nPart, 'Len', dLen) end if dAngDx then EgtSetInfo(nPart, 'dAngDx', dAngDx) end if dAgnSx then EgtSetInfo(nPart, 'dAngSx', dAngSx) end if dH then EgtSetInfo(nPart, 'dH', dH) end if dTh then EgtSetInfo(nPart, 'dTh', dTh) end if dBeta1 then EgtSetInfo(nPart, 'dBeta1', dBeta1) end if dBeta2 then EgtSetInfo(nPart, 'dBeta2', dBeta2) end 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) 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 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) 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 --local bInvertCurve = false if bInLoop then local IdOutRegion = EgtGetPrev(IdReg) local vtNorm1 = EgtSurfFrNormVersor(IdOutRegion) local vtNorm2 = EgtSurfFrNormVersor(IdReg) if AreOppositeVectorApprox( vtNorm1, vtNorm2) then EgtInvertSurf(IdReg) --bInvertCurve = true 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 --if bInvertCurve then -- for i = 1, #tbIdEntCrv do -- EgtInvertCurve(tbIdEntCrv[i]) -- end --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 = 180 - dPairAng1 local dAngTilt2 = 180 - dPairAng2 local vtN1 = Vector3d({0,0,100}) local vtN2 = Vector3d({0,0,100}) vtN1:rotate(vtDir1, dAngTilt1) vtN2:rotate(vtDir2, 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) if (dPairAng2 > 90 and dBeta1 > 90) or (dPairAng2 < 90 and dBeta1 < 90) then dBeta1 = 180 - dBeta1 end local dBeta2 = GetAngle( vtDir2, vtPerp) if (dPairAng1 > 90 and dBeta2 > 90) or (dPairAng1 < 90 and dBeta2 < 90) then dBeta2 = 180 - dBeta2 end local dSideAng = 0 dSideAng = (180 - dAng3d) / 2 --debug EgtOutLog(tostring(dSideAng)..' '.. tostring(dBeta1).. ' '..tostring(dBeta2)) --debug 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 -- recupero eventuali input mancanti dalla tabella generale if not dLen then dLen = TOOL.dLen end if not dH then dH = TOOL.dH end if not dBeta1 then dBeta1 = TOOL.dBeta1 end if not dBeta2 then dBeta2 = TOOL.dBeta2 end -- creo i lati del pezzo 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) 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) TOOL.CreatePart(TOOL.FindLayers(nPart),nil,{HoleId},nil,true) end --function TOOL.CreateParetina(i, tbIdLoopTC, tbInfo, dPairAngCorr) function TOOL.CreateParetina(nEdgeId, tbInfo, dPairAngCorr) -- se non ho ricevuto input li recupero dalla tabella generale if not nEdgeId then nEdgeId = TOOL.nEdgeId end if not tbInfo then FillInfoTable() tbInfo = TOOL.tbInfo end local nLay = EgtGetParent(nEdgeId) local tbIdLoopTC = FindEdges(nLay) -- tabella che contiene gli id degli Edge del loop -- local nId = EgtGetFirstInGroup(nLay) local i = tbInfo.nEdge -- posizione del lato nel layer del loop if dPairAngCorr == nil then dPairAngCorr = 0 end 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) + dPairAngCorr local dPairAngNext = (EgtGetInfo(tbInfo.nNext, 'PairAng', 'd') or 0) + dPairAngCorr local dPairAng = (EgtGetInfo(tbInfo.nId, 'PairAng', 'd') or 0) + dPairAngCorr 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 PrevAng, NextAng = 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, PrevAng) --tbInfo.dAngBR = 180 - dBeta_DX tbInfo.dAngBR = dBeta_DX if tbInfo.bOnLoop then dSideAng_4 = dSideAng_4 * (-1) end if PrevAng < 0 then dSideAng_4 = dSideAng_4 * (-1) end tbInfo.dSideAngR = dSideAng_4 if not tbInfo.bOnLoop then dLenPrev, dLen, dXOffset = ManageJunction(PrevAng,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(PrevAng,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(PrevAng) 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 = PrevAng < 0 and (90 + PrevAng) or 90-PrevAng 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 - PrevAng) 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, NextAng) -- tbInfo.dAngBL = 180 - dBeta_SX tbInfo.dAngBL = dBeta_SX if tbInfo.bOnLoop then dSideAng_2 = dSideAng_2 * (-1) end if NextAng < 0 then dSideAng_2 = dSideAng_2 * (-1) end tbInfo.dSideAngL = dSideAng_2 if not tbInfo.bOnLoop then dLen, dLenNext = ManageJunction(NextAng, 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(NextAng, dTh, dTh, tbInfo.nJunctionType, dLen, dLenNext) -- setto il sideang da giunzione a T local dSideAng_2 = 90 - math.abs(NextAng) 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 = NextAng < 0 and (90 + NextAng) or 90-NextAng 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 - NextAng) dLen = dLen + dOffset if tbInfo.nJunctionType == 2 then dXOffset = dXOffset + dOffset end end end tbInfo.dLen = dLen tbInfo.dXOffset = dXOffset end function TOOL.CreateParetinaFull() -- devo modificare anche la paretina precedente e la successiva TOOL.CreateParetina() end return TOOL