-- 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 = nil -- id del part della paretina che si sta costruendo TOOL.nLayLoopParent = nil -- layer contenente il loop da cui si sta creando la paretina (appartenente al parent) TOOL.nLayLoop = nil -- layer dell'outloop del nuovo part in creazione TOOL.nEdgeId = nil -- indice dell'edge che si sta usando per creare la paretina TOOL.nEdge = nil -- numero ordinale (1-based, per poterlo usare direttamente per trovare il lato "A1") per l'edge nel layer del loop TOOL.tbInfo = {} -- tabella contenente tutte le informazioni del part corrente TOOL.nParent = nil -- id del parent TOOL.nPrevId = nil -- id della paretina precedente alla corrente TOOL.nNextId = nil -- id della paretina successiva alla corrente TOOL.nPrev = nil -- numero ordinale della paretina precedente alla corrente TOOL.nNext = nil -- numero ordinale della paretina successiva alla corrente TOOL.dPairAng = nil -- angolo di accoppiamento TOOL.nJunctionType = nil -- tipo di giunzione tra paretine: 1 trim start, 2 trim end, 3 giunzione angolata TOOL.bOnLoop = nil -- flag che indica se la faccia buona è adiacente al lato del parent generatore della paretina corrente TOOL.dAngBR = nil -- angolo BottomRight della faccia buona della paretina corrente TOOL.dSideAngR = nil -- SideAng del lato Right(A2) (il primo lato è il bottom e si procede CCW) TOOL.dAngBL = nil -- angolo BottomLeft della faccia buona della paretina corrente TOOL.dSideAngL = nil -- SideAng del lato Left(A4) (il primo lato è il bottom e si procede CCW) TOOL.dLen = nil -- lunghezza del lato del parent generatore della paretina corrente TOOL.dH = nil -- altezza della faccia buona della paretina corrente TOOL.dTh = nil -- spessore del part corrente TOOL.dThParent = nil -- spessore del parent TOOL.dXOffset = nil -- offset del riferimento -- TOOL.dBeta1 = nil -- TOOL.dBeta2 = nil TOOL.sName = nil -- nome del part corrente, incluso il codice univoco(es: sUNICode.."PartA1") TOOL.bPrev = nil -- booleano che indica se modificare anche la paretina successiva, in conseguenza delle modifica a quella corrente TOOL.bNext = nil -- booleano che indica se modificare anche la paretina precedente, in conseguenza delle modifica a quella corrente TOOL.UUID = nil -- output per la generazione di un nuovo UUID -- info addizionali che potrebbero esserci nella tbInfo TOOL.tbInfo.nIn = nil -- intero che esiste solo se il part è stato costruito a partire da un edge di un InLoop e indica a quale degli InLoop(da contare in ordine all'interno del Parent, 1-based) TOOL.tbInfo.bOutLoop = nil -- booleano che indica se l'edge su cui è stato costruito il part appartiene all'outloop o ad un inloop del Parent TOOL.tbIdLoop = {} -- tabella con gli id del loop su cui sta venendo costruita la paretina ---- creo il codice univoco per l'identificazione dei part --TOOL.sUNICode = os.date( '%y%m%d%H%M%S', os.time()).."_" --local sUNICode = TOOL.sUNICode function TOOL.SaveMePlease() EgtSaveFile('D:\\Temp\\marmo\\Vein3D\\FOO.nge') end function TOOL.GetNewUUID() TOOL.UUID = EgtGetUUID() end local function FindEdges(nLay, tbInfo) -- crea una tabella con gli indici degli elementi nel Layer passato (nLay) e -- trova l'indice del lato tbInfo.nEdgeId, 1 based, restituito in tbInfo.nEdge local tbId = {} local nId = EgtGetFirstInGroup(nLay) local c = 1 while nId do if tbInfo and tbInfo.nEdgeId ~= GDB_ID.NULL and tbInfo.nEdgeId then if nId == tbInfo.nEdgeId then tbInfo.nEdge = c end end table.insert(tbId, nId) nId = EgtGetNext(nId) c = c + 1 end return tbId end local function FillInfoTable() if TOOL.nId then TOOL.tbInfo.nId = TOOL.nId end if TOOL.nEdgeId then TOOL.tbInfo.nEdgeId = TOOL.nEdgeId end if (not TOOL.tbInfo.nLayLoopParent or TOOL.tbInfo.nLayLoopParent == GDB_ID.NULL) and TOOL.nEdgeId and TOOL.nEdgeId ~= GDB_ID.NULL then EgtGetParent( TOOL.nEdgeId) end TOOL.nLayLoopParent = TOOL.tbInfo.nLayLoopParent if TOOL.nParent then TOOL.tbInfo.nParent = TOOL.nParent end if (not TOOL.tbInfo.nParent or TOOL.tbInfo.nParent == GDB_ID.NULL) and TOOL.nEdgeId and TOOL.nEdgeId ~= GDB_ID.NULL then EgtGetParent(EgtGetParent( TOOL.nEdgeId)) end if TOOL.nPrevId then TOOL.tbInfo.nPrevId = TOOL.nPrevId end if TOOL.nNextId then TOOL.tbInfo.nNextId = TOOL.nNextId end if TOOL.nJunctionType then TOOL.tbInfo.nJunctionType = TOOL.nJunctionType end if TOOL.bOnLoop ~= nil then TOOL.tbInfo.bOnLoop = TOOL.bOnLoop end if TOOL.bInsideLoop ~= nil then TOOL.tbInfo.bInsideLoop = TOOL.bInsideLoop end if TOOL.dAngBR then TOOL.tbInfo.dAngBR = TOOL.dAngBR end if TOOL.dSideAngR then TOOL.tbInfo.dSideAngR = TOOL.dSideAngR end if TOOL.dAngBL then TOOL.tbInfo.dAngBL = TOOL.dAngBL end if TOOL.dSideAngL then TOOL.tbInfo.dSideAngL = TOOL.dSideAngL end if TOOL.dLen then TOOL.tbInfo.dLen = TOOL.dLen end if TOOL.dTh then TOOL.tbInfo.dTh = TOOL.dTh end if TOOL.dH then TOOL.tbInfo.dH = TOOL.dH end if TOOL.dPairAng then TOOL.tbInfo.dPairAng = TOOL.dPairAng end if TOOL.bOnLoop then TOOL.tbInfo.bOnLoop = TOOL.bOnLoop end if TOOL.sName then TOOL.tbInfo.sName = TOOL.sName end end local function FillInfoTableFromPart(nPartId) if not nPartId or nPartId == GDB_ID.NULL then return end TOOL.tbInfo.nId = nPartId TOOL.tbInfo.nPrevId = EgtGetFirstNameInGroup(GDB_ID.ROOT, EgtGetInfo(nPartId,"Prev") or "") or GDB_ID.NULL TOOL.tbInfo.nNextId = EgtGetFirstNameInGroup(GDB_ID.ROOT, EgtGetInfo(nPartId,"Next") or "") or GDB_ID.NULL TOOL.tbInfo.nJunctionType = EgtGetInfo(nPartId,"JunctionType", "i") TOOL.tbInfo.dPairAng = EgtGetInfo(nPartId, "PairAng", "d") TOOL.tbInfo.bOnLoop = EgtGetInfo(nPartId,"OnLoop", "b") TOOL.tbInfo.bInsideLoop = EgtGetInfo(nPartId,"InsideLoop", "b") TOOL.tbInfo.dAngBR = EgtGetInfo(nPartId,"AngBR", "d") TOOL.tbInfo.dSideAngR = EgtGetInfo(nPartId,"SideAngR", "d") TOOL.tbInfo.dAngBL = EgtGetInfo(nPartId,"AngBL", "d") TOOL.tbInfo.dSideAngL = EgtGetInfo(nPartId,"SideAngL", "d") TOOL.tbInfo.dLen = EgtGetInfo(nPartId,"Len", "d") TOOL.tbInfo.dH = EgtGetInfo(nPartId,"H", "d") TOOL.tbInfo.dTh = EgtGetInfo(nPartId,"Th", "d") TOOL.tbInfo.nEdge = EgtGetInfo(nPartId, "ParentEdge", "i") TOOL.tbInfo.bOutLoop = EgtGetInfo(nPartId, "FromOutLoop", "b") TOOL.tbInfo.nParent = EgtGetInfo(nPartId, "Parent","i") if TOOL.tbInfo.bOutLoop then TOOL.tbInfo.nLayLoopParent = EgtGetFirstNameInGroup(TOOL.tbInfo.nParent, "OutLoop") else TOOL.tbInfo.nIn = EgtGetInfo(nPartId,"nInLoop", "i") local nLay = EgtGetFirstNameInGroup(TOOL.tbInfo.nParent, "InLoop") if TOOL.tbInfo.nIn then local c = 1 if TOOL.tbInfo.nIn ~=1 then while c ~= TOOL.tbInfo.nIn do nLay = EgtGetNextName(nLay, "InLoop") c = c + 1 end end end TOOL.tbInfo.nLayLoopParent = nLay end TOOL.tbInfo.nEdgeId = EgtGetFirstNameInGroup(TOOL.tbInfo.nLayLoopParent, "A"..TOOL.tbInfo.nEdge) end function TOOL.WriteDataToChildPart(tbInfo) if not tbInfo or not tbInfo.nId then do return end end if tbInfo.nParent then EgtSetInfo(tbInfo.nId, 'Parent', tbInfo.nParent) end if tbInfo.nEdge then EgtSetInfo(tbInfo.nId, 'ParentEdge', tbInfo.nEdge) end if tbInfo.dLen then EgtSetInfo(tbInfo.nId, 'Len', tbInfo.dLen) end if tbInfo.dAngDx then EgtSetInfo(tbInfo.nId, 'AngDx', tbInfo.dAngDx) end if tbInfo.dAgnSx then EgtSetInfo(tbInfo.nId, 'AngSx', tbInfo.dAngSx) end if tbInfo.bOnLoop ~= nil then EgtSetInfo(tbInfo.nId, "OnLoop", tbInfo.bOnLoop) end if tbInfo.bInsideLoop ~= nil then EgtSetInfo(tbInfo.nId, "InsideLoop", tbInfo.bInsideLoop) end if tbInfo.dH then EgtSetInfo(tbInfo.nId, 'H', tbInfo.dH) end if tbInfo.dTh then EgtSetInfo(tbInfo.nId, 'Th', tbInfo.dTh) end if tbInfo.nJunctionType then EgtSetInfo(tbInfo.nId, 'JunctionType', tbInfo.nJunctionType) end if tbInfo.bOutLoop ~= nil then EgtSetInfo(tbInfo.nId, "FromOutLoop", tbInfo.bOutLoop) end if tbInfo.nIn then EgtSetInfo(tbInfo.nId, "nInLoop", tbInfo.nIn) end if tbInfo.nPrevId then EgtSetInfo(tbInfo.nId, "Prev", EgtGetName(tbInfo.nPrevId)) end if tbInfo.nNextId then EgtSetInfo(tbInfo.nId, "Next", EgtGetName(tbInfo.nNextId)) end if tbInfo.dSideAngR then EgtSetInfo(tbInfo.nId, "SideAngR", tbInfo.dSideAngR) end if tbInfo.dSideAngL then EgtSetInfo(tbInfo.nId, "SideAngL", tbInfo.dSideAngL) end end -- CREAZIONE dei Layer di un singolo Part -- I nomi dei layer sono: OutLoop, Region, Ref, Labels, Aux function TOOL.CreatePartLayer(PartName) -- Pezzo e Layer local sUNICode = EgtGetUUID().."_" 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 "..EgtNumToString(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 -- calcolo la normale del loop (per un inloop deve essere concorde con quella di un outloop) local bFlat = false local vtN = V_NULL() local dDist = 0 local tbEdges = {} while nId do table.insert(tbEdges, nId) nId = EgtGetNext(nId) end local nLoop = EgtCurveCompoByChain(Layer, tbEdges, EgtSP(tbEdges[1], GDB_RT.GLOB), false, GDB_RT.GLOB) bFlat, vtN, dDist = EgtCurveIsFlat(nLoop) local vtAx = vtN EgtErase(nLoop) -- riparto dal primo lato e inserisco le info di machining nId = EgtGetFirstInGroup(Layer) 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) --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 -- function TOOL.AddInLoopToPart(nLayLoop) -- nLay è il layer contenente il loop da inserire -- recupero l'Id del part local tbIdEntCrv = FindEdges(nLayLoop) local IdPart = EgtGetParent( nLayLoop) local tbLayer = TOOL.FindLayers(IdPart) -- costruisco il contorno chiuso local IdLoop = EgtCurveCompoByChain( nLayLoop, 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' "..EgtNumToString(IdOutRegion).." e 'InLoop' "..EgtNumToString(IdReg).." non riuscita." end EgtErase(IdReg) end -- elimino il contorno chiuso EgtErase(IdLoop) 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(nLayLoop, tbPart, bIsPlanar) if bIsPlanar == nil then bIsPlanar = false end -- se mancano le variabili di input le recupero dalla tabella generale if not nLayLoop then if TOOL.nLayLoopParent then nLayLoop = TOOL.nLayLoopParent end if TOOL.tbInfo.nLayLoop then nLayLoop = TOOL.tbInfo.nLayLoop end end if not tbPart then tbPart = TOOL.tbInfo end -- recupero l'Id del part local tbIdEntCrv = FindEdges(nLayLoop) local IdPart = EgtGetParent( nLayLoop) local tbLayer = TOOL.FindLayers(IdPart) -- local sPartName = EgtGetName(IdPart) -- local tbPartName = EgtSplitString(sPartName,"_") -- local sName = tbPartName[2] -- costruisco il contorno chiuso local IdLoop = EgtCurveCompoByChain( nLayLoop, tbIdEntCrv, EgtSP(tbIdEntCrv[1],GDB_RT.GLOB), false, GDB_RT.GLOB) -- Nel Layer Region definisco la regione piana local IdReg = EgtSurfFlatRegion(tbLayer['Region'],IdLoop) -- elimino il contorno chiuso EgtErase(IdLoop) -- scrivo nel part le informazioni di costruzione TOOL.WriteDataToChildPart(tbPart) -- INFO NECESSARIA EgtSetInfo(IdPart, 'Paired',EgtNumToString(IdPart)) -- inserisco le etichette del pezzo nel centro della superofocie local ptTop = EgtCP( IdReg, GDB_RT.GLOB) local ptBottom = Point3d( ptTop:getX(), -ptTop:getY(), tbPart.dTh) local tbNamePart = EgtSplitString(tbPart.sName, "_") -- al nome del part tolgo il codice univoco local sNamePart = tbNamePart[2] EgtTextAdv(tbLayer['Labels'], ptTop,0,sNamePart, '', 10, '', 15,1.5,0,GDB_TI.MC) if not bIsPlanar then EgtSetGridFrame(Frame3d(ORIG(),GDB_FR.BOTTOM)) EgtTextAdv(tbLayer['Labels'], ptBottom,0,sNamePart, '', 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 Layer (OutLoop o InLoop), -- Nome dello spigolo, -- Nome della copia riferimento -- Info per spostamento Ref in funzione di una variabile function TOOL.CreateReference( IdPart, sNameLayer,sNameEdge, nIn, dVar, sDir, sPartPairingName) local tbLayer = TOOL.FindLayers( IdPart) --accoppiamento di left su bottom local IdEnt = EgtGetFirstNameInGroup(tbLayer[sNameLayer], sNameEdge) -- se l'edge è in un Inloop e sono presenti più inloop nel Parent allora uso l'indice nIn per scorrere fino all'Inloop giusto if nIn and nIn ~= 1 then local nLay = EgtGetFirstNameInGroup(IdPart, sNameLayer) for i = 1, nIn-1 do nLay = EgtGetNextName(nLay, sNameLayer) end IdEnt = EgtGetFirstNameInGroup(nLay, sNameEdge) end if not IdEnt then TOOL.ERR=6 TOOL.MSG= TOOL.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']) EgtSetInfo(IdRef, "OrigEdge", EgtGetName(IdEnt)) local nNumRef = EgtGetGroupObjs(tbLayer['Ref']) local sNameRef = "R"..EgtNumToString(nNumRef) -- verifico che non esista già un altro ref con questo nome local nIdRefDb= EgtGetFirstNameInGroup( tbLayer['Ref'], sNameRef) while nIdRefDb do nNumRef = nNumRef + 1 sNameRef = "R"..EgtNumToString(nNumRef) nIdRefDb= EgtGetFirstNameInGroup( tbLayer['Ref'], sNameRef) end EgtSetName( IdRef, sNameRef) if dVar and sDir then EgtSetInfo(IdRef, 'Var', dVar) EgtSetInfo(IdRef, 'Dir', sDir) end -- salvo nel riferimento il nome dell'edge da cui discende: A1 se da un outloop, A1_I1 se dal primo Inloop if nIn then sNameEdge = sNameEdge.."_"..EgtNumToString(nIn) end EgtSetInfo(IdRef, "Orig", sNameEdge) -- salvo nel riferimento il nome del part che lo userà per associarsi ad IdPart (questa operazione la faccio solo per il riferimento del part destinatario) if sPartPairingName then EgtSetInfo(IdRef,"PartPairing", sPartPairingName) end -- devo controllare se il part a cui sto aggiungendo il riferimento ha già il solido allora devo applicare l'offset al riferimento! -- (che altrimenti verrebbe fatto alla creazione del solido) local nChild = EgtGetInfo(IdPart, "Child", "i") if nChild then SLD.CurrId = IdPart SLD.CorrectReference() 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, 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( tbInfo, nIdMyRef, sToNamePart, nIdRefDest, nPairSpin) local nPart = tbInfo.nId local sNameMyRef = EgtGetName(nIdMyRef) EgtSetInfo(nPart, "PairMyRef", sNameMyRef) local sNameRefDest = EgtGetName(nIdRefDest) EgtSetInfo(nPart, "PairToRef", sToNamePart..","..sNameRefDest) EgtSetInfo(nPart, "PairSpin", nPairSpin) EgtSetInfo(nPart, "PairAng", tbInfo.dPairAng) EgtSetInfo(nPart, "PairMode", tbInfo.nPairMode) 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, sNamePart1) local nRefBottom = EgtGetFirstNameInGroup(nBottomLay, 'Ref') local nRef = EgtGetFirstNameInGroup(nRefBottom, sNameRef1) local pt1 = EgtSP( nRef, GDB_RT.GRID) local nTopLay = EgtGetFirstNameInGroup(GDB_ID.ROOT, 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: '..EgtNumToString(IdLoop)..';'..EgtNumToString(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(EgtNumToString(dSideAng)..' '.. EgtNumToString(dBeta1).. ' '..EgtNumToString(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 dXOffset1 = 0 local dXOffset2 = 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 dXOffset2 = dDeltaStart -- extend end local dDeltaEnd = dTh1 * tan(90- math.abs(dAngBetween)) dLen1 = dLen1 + dDeltaEnd dXOffset1 = dDeltaEnd elseif nType == 2 then -- trim end local dDeltaEnd = - dTh2 / sin(dAngBetween) dLen1 = dLen1 + dDeltaEnd dXOffset1 = dDeltaEnd -- extend start local dDeltaStart = dTh2 * tan(90- math.abs(dAngBetween)) dLen2 = dLen2 + dDeltaStart dXOffset2 = 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 dXOffset1 = dDelta -- accorcio lo start local dDeltaStart = - dTh2 * tan(90- math.abs(dAngBetween)) dLen2 = dLen2 + dDeltaStart dXOffset2 = 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 dXOffset2 = dDeltaStart -- accorcio l'end local dDeltaEnd = - dTh1 * tan(90- math.abs(dAngBetween)) dLen1 = dLen1 + dDeltaEnd dXOffset1 = dDeltaEnd end end return dLen1, dLen2, dXOffset1, dXOffset2 end function AngleJunction(dAngBetween, dTh1, dTh2, dLen1, dLen2, bOnLoop) -- modifico la lughezza dei lati solo se ho un angolo convesso local dXOffset = 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, dXOffset, dXOffset 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( tbInfo, dLenCorr) -- 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 tbInfo then tbInfo = TOOL.tbInfo end local dLen = tbInfo.dLen local dH = tbInfo.dH local dBeta1 = tbInfo.dAngBL local dBeta2 = tbInfo.dAngBR local nLayOutloop = tbInfo.nLayLoop if not dLenCorr then dLenCorr = 0 else dLen = dLen + dLenCorr tbInfo.dLen = dLen end -- creo i lati del pezzo -- ____ local dProj1 = dH * tan( dBeta1 - 90) -- \ / local dProj2 = dH * tan( dBeta2 - 90) -- \/ -- /\ -- controllo che non ci sia interferenza tra il lato A2 e A4: voglio evitare eventuali clessidre: /__\ -- se una delle due proiezioni, o la loro somma, è più lunga della base inferiore devo ridurre l'altezza del pezzo if abs(dProj1) > dLen or abs(dProj2) > dLen or (abs(dProj1) + abs(dProj2)) > dLen then end local pt1 = ORIG() local pt2 = Point3d(dLen,0,0) local nLine1 = EgtLine( nLayOutloop, pt1, pt2, GDB_RT.GLOB) EgtSetName(nLine1, "A1") local pt3 = Point3d(dLen + dProj2,dH,0) local nLine2 = EgtLine( nLayOutloop, pt2, pt3, GDB_RT.GLOB) EgtSetName(nLine2, "A2") local pt4 = Point3d( -dProj1,dH,0) local nLine3 = EgtLine( nLayOutloop, pt3, pt4, GDB_RT.GLOB) EgtSetName(nLine3, "A3") local nLine4 = EgtLine( nLayOutloop, pt4, pt1, GDB_RT.GLOB) EgtSetName(nLine4, "A4") TOOL.SetMachiningInfo(nLayOutloop) -- setto le info dei side ang if tbInfo.dSideAngL then TOOL.SetSideAng(tbInfo.nLayLoop, 'A2', tbInfo.dSideAngR) end if tbInfo.dSideAngR then TOOL.SetSideAng(tbInfo.nLayLoop, 'A4', tbInfo.dSideAngL) end 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.AddInLoopToPart(nInLoopLay) end function TOOL.CreateParetina(nEdgeId, tbInfo, dPairAngCorr) local tbIdLoopTC = {} -- se ho chiamato la funzione senza passare direttamente gli argomenti li recupero dalla tabella principale if not tbInfo then tbInfo = TOOL.tbInfo tbIdLoopTC = TOOL.tbIdLoop end -- se mancano la tabella degli edge e la posizione ordinale dell'edge, le ricostruisco if (not tbInfo.nEdge and nEdgeId) then tbIdLoopTC = FindEdges(EgtGetParent(nEdgeId), tbInfo) end -- se ho i dati, ma non ho ancora la tabella dei parent edge la recupero dalla tabella generale if #tbIdLoopTC == 0 and tbInfo then tbIdLoopTC = TOOL.tbIdLoop end if #tbIdLoopTC == 0 then return end 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 if not tbInfo.nPrevId then tbInfo.nPrevId = GDB_ID.NULL end local dPairAng = (tbInfo.dPairAng or 0) dPairAng = dPairAng + dPairAngCorr local dPairAngPrev = (EgtGetInfo(tbInfo.nPrevId, 'PairAng', 'd') or 0) + dPairAngCorr if not tbInfo.nNextId then tbInfo.nNextId = GDB_ID.NULL end local dPairAngNext = (EgtGetInfo(tbInfo.nNextId, '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[nPrev]) local dLenNext = EgtCurveLength(tbIdLoopTC[nNext]) local PrevAng, NextAng = GetPrevNextAng(tbIdLoopTC[i]) local dTh = tbInfo.dTh and tbInfo.dTh or EgtGetInfo(tbInfo.nId, 'Th','d') local dThPrev = EgtGetInfo(tbInfo.nPrevId, 'Th','d') or 0 local dThNext = EgtGetInfo(tbInfo.nNextId, 'Th','d') or 0 -- 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 = false if tbInfo.nPrevId~= GDB_ID.NULL then bSameSide = dPairAng * dPairAngPrev > 0 end if bSameSide then local dOffset = 0 if tbInfo.nJunctionType == 3 then local dSideAngDx, _, dBeta_DX = CalcDraftAngle( vtDirPrev, vtDirCurr, dPairAngPrev, dPairAng, PrevAng) --tbInfo.dAngBR = 180 - dBeta_DX tbInfo.dAngBR = dBeta_DX if tbInfo.bOnLoop then dSideAngDx = dSideAngDx * (-1) end if PrevAng < 0 then dSideAngDx = dSideAngDx * (-1) end tbInfo.dSideAngR = dSideAngDx if not tbInfo.bOnLoop then dLenPrev, dLen, _, dOffset = ManageJunction(PrevAng,dThPrev, dTh,tbInfo.nJunctionType, dLenPrev, dLen) if tbInfo.nPairMode == 2 then dXOffset = dXOffset + dOffset end 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, _, dOffset = ManageJunction(PrevAng,dThPrev, dTh,tbInfo.nJunctionType, dLenPrev, dLen) -- setto il sideang da giunzione a T local dSideAngDx = 90 - math.abs(PrevAng) if tbInfo.bOnLoop then dSideAngDx = dSideAngDx * (-1) end tbInfo.dSideAngR = dSideAngDx tbInfo.dAngBR = 90 if tbInfo.nPairMode == 2 then dXOffset = dXOffset + dOffset end 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 tbInfo.dAngBR = 90 -- 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 == 2 then dXOffset = dXOffset + dOffset end if tbInfo.nPairMode == 2 then dXOffset = dXOffset + dOffset end end end -- -- calcolo l'angolo di sformo con il pezzo successivo bSameSide = false if tbInfo.nNextId~= GDB_ID.NULL then bSameSide = dPairAng * dPairAngNext > 0 end if bSameSide then local dOffset = 0 if tbInfo.nJunctionType == 3 then local dSideAngSx, dBeta_SX, _ = CalcDraftAngle( vtDirCurr, vtDirNext, dPairAng, dPairAngNext, NextAng) -- tbInfo.dAngBL = 180 - dBeta_SX tbInfo.dAngBL = dBeta_SX if tbInfo.bOnLoop then dSideAngSx = dSideAngSx * (-1) end if NextAng < 0 then dSideAngSx = dSideAngSx * (-1) end tbInfo.dSideAngL = dSideAngSx if not tbInfo.bOnLoop then dLen, dLenNext, dXOffset, _ = ManageJunction(NextAng, dTh, dThNext, tbInfo.nJunctionType, dLen, dLenNext) if tbInfo.nPairMode == 1 then dXOffset = dXOffset + dOffset end 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, dXOffset, _ = ManageJunction(NextAng, dTh, dThNext, tbInfo.nJunctionType, dLen, dLenNext) -- setto il sideang da giunzione a T local dSideAngSx = 90 - math.abs(NextAng) if tbInfo.bOnLoop then dSideAngSx = dSideAngSx * (-1) end tbInfo.dSideAngL = dSideAngSx tbInfo.dAngBL = 90 if tbInfo.nPairMode == 1 then dXOffset = dXOffset + dOffset end 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 tbInfo.dAngBL = 90 -- 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 == 1 then dXOffset = dXOffset + dOffset end if tbInfo.nPairMode == 1 then dXOffset = dXOffset + dOffset end end end tbInfo.dLen = dLen tbInfo.dXOffset = dXOffset end local function ClearPart(nPartId) local tbLayer = TOOL.FindLayers(nPartId) -- svuoto i layer con gli elementi principali EgtEmptyGroup(tbLayer["OutLoop"]) EgtEmptyGroup(tbLayer["Region"]) EgtEmptyGroup(tbLayer["Ref"]) EgtEmptyGroup(tbLayer["Labels"]) -- rimetto il frame del part nell'origine EgtChangeGroupFrame(nPartId, GLOB_FRM()) -- resetto il gruppo di accoppiati ASS.bActiveHistory = false ASS.nPartId = nPartId ASS.Unpair() ASS.bActiveHistory = true -- cancello il solido local PartSolid = EgtGetInfo(TOOL.tbInfo.nId, "Child") EgtErase(PartSolid) -- resetto l'id del part del solido EgtSetInfo(nPartId, "Child", "") -- cancello il riferimento nel part destinatario local tbPairToRef = EgtGetInfo(nPartId, "PairToRef", "vs") local nPartToRef = EgtGetFirstNameInGroup(GDB_ID.ROOT, tbPairToRef[1]) local tbLayers = TOOL.FindLayers(nPartToRef) local nRef = EgtGetFirstNameInGroup(tbLayers["Ref"], tbPairToRef[2]) EgtErase(nRef) end local function CreateSplitBottomPart(tbInfo, i, tbIdEdges, nPrev, nNext) local Pz_Bottom = GDB_ID.NULL -- devo verificare se la paretina esiste già allora devo distruggerla e ricrearla, sennò la creo da zero -- N.B.: nEdge è riferito all'edge del parent a cui questo part andrà ad accoppiarsi -- mentre i è l'indice dell'edge del loop dei lati A3 dei parent da cui sto creando il fondo local nChildPart = EgtGetFirstNameInGroup(GDB_ID.ROOT, EgtGetInfo(tbInfo.nParent, "A"..tbInfo.nEdge)) if not nChildPart then Pz_Bottom = TOOL.CreatePartLayer('BottomA'..EgtNumToString(i)) tbInfo.sName = EgtGetName(Pz_Bottom) EgtSetInfo(tbInfo.nParent, "A"..tbInfo.nEdge, tbInfo.sName) tbInfo.nPrevId = nPrev or GDB_ID.NULL tbInfo.nNextId = i == #tbIdEdges and nNext or GDB_ID.NULL -- setto le info per la creazione del pezzo di fondo tbInfo.nId = Pz_Bottom tbInfo.nEdgeId = tbIdEdges[i] tbInfo.sDestRefOff = '0,0,-x' tbInfo.sRefOff = '0,0,0' tbInfo.dPairAng = 90 - TOOL.dSlopeAng tbInfo.nPairSpin = -1 tbInfo.nJunctionType = 3 tbInfo.bOnLoop = true tbInfo.bInsideLoop = false -- questo mi richiederà di prendere il complementare del side ang che risulta dal calcDraftAng else -- se esisteva già ripulisco i layer della regione e del loop ed elimino il solido ClearPart(nChildPart) TOOL.tbInfo.nId = nChildPart TOOL.tbInfo.sName = EgtGetName(TOOL.tbInfo.nId) -- recupero l'id di eventuali vicini TOOL.tbInfo.nPrevId = nPrev and nPrev or (EgtGetFirstNameInGroup(GDB_ID.ROOT, EgtGetInfo(TOOL.tbInfo.nId, "Prev")) or GDB_ID.NULL) TOOL.tbInfo.nNextId = nNext and nNext or (EgtGetFirstNameInGroup(GDB_ID.ROOT, EgtGetInfo(TOOL.tbInfo.nId, "Next")) or GDB_ID.NULL) end -- creo il fondo come paretina local tbLayerBottom = TOOL.FindLayers(tbInfo.nId) tbInfo.nLayLoop = tbLayerBottom['OutLoop'] -- nella funzione CreateParetina mi serve che tbInfo.nEdge indichi quale lato del loop ausiliario sta generando il part corrente(e non sia riferito al lato del parent) tbInfo.nEdge = i TOOL.CreateParetina( tbInfo.nEdgeId, tbInfo, 90) -- ripristino il valore di nEdge riferito al Parent tbInfo.nEdge = 3 local dLenCorr = 0 local dThParent = EgtGetInfo(tbInfo.nParent, "Th", "d") if not tbInfo.bInsideLoop then --tbInfo.dSideAngL = - tbInfo.dSideAngL --tbInfo.dSideAngR = - tbInfo.dSideAngR local nParentJunctionType = EgtGetInfo(tbInfo.nParent, "JunctionType","i") if nParentJunctionType == 3 then local dSideAngR = EgtGetInfo(tbInfo.nParent, "SideAngR", "d") local dSideAngL = EgtGetInfo(tbInfo.nParent, "SideAngL", "d") dLenCorr = dThParent*( tan(dSideAngR) + tan(dSideAngL)) tbInfo.nPairMode = 4 elseif nParentJunctionType == 1 then -- devo recuperare lo spessore del pezzo precedente -- se le paretine parent sono inclinate dovrò aggiustare lo spessore local nIdPrev = EgtGetFirstNameInGroup(GDB_ID.ROOT, EgtGetInfo(tbInfo.nParent, "Prev")) local dThPrev = EgtGetInfo(nIdPrev, "Th", "d") dLenCorr = dThPrev tbInfo.sDestRefOff = EgtNumToString(dThPrev)..",0,-x" tbInfo.nPairMode = 2 elseif nParentJunctionType == 2 then -- devo recuperare lo spessore del pezzo successivo -- se le paretine parent sono inclinate dovrò aggiustare lo spessore local nIdNext = EgtGetFirstNameInGroup(GDB_ID.ROOT, EgtGetInfo(tbInfo.nParent, "Next")) local dThNext = EgtGetInfo(nIdNext, "Th", "d") dLenCorr = dThNext tbInfo.sDestRefOff = EgtNumToString(-dThNext)..",0,-x" tbInfo.nPairMode = 1 end end TOOL.CreateAdjustedPart( tbInfo, dLenCorr) TOOL.CreatePart(tbLayerBottom['OutLoop'],tbInfo) -- creo i riferimenti e salvo i parametri del part local nIdToRef = TOOL.CreateReference( tbInfo.nParent, 'OutLoop', 'A3', nil, tbInfo.dTh, tbInfo.sDestRefOff, tbInfo.sName) local nMyRef = TOOL.CreateReference( tbInfo.nId, 'OutLoop', 'A1', nil, 0, tbInfo.sRefOff) local sNamePartDest = EgtGetName(tbInfo.nParent) TOOL.SetPairInfo( tbInfo, nMyRef, sNamePartDest, nIdToRef, -1) -- creo il solido e lo accoppio if SLD then SLD.CurrId = tbInfo.nId SLD.Main() end if ASS then ASS.nVeinCtx = EgtGetContext() ASS.nPartId = tbInfo.nId ASS.PairSingle() end return Pz_Bottom end function TOOL.CreateSplitBottom( tbIdEdges, dOffset) -- raccolgo e/o ricostruisco i dati in input if not tbIdEdges then tbIdEdges = TOOL.tbIdEdges end -- tabella che contiene gli edge da cui voglio creare il fondello -- riordino gli edge in modo che il primo lato sia il lato lungo del rettangolo local dLen1 = EgtCurveLength(tbIdEdges[1]) local dLen2 = EgtCurveLength(tbIdEdges[2]) if dLen1 < dLen2 + GEO.EPS_SMALL then -- sposto il primo elemento in fondo alla tabella table.insert(tbIdEdges, tbIdEdges[1]) table.remove(tbIdEdges, 1) end if not dOffset then if TOOL.dOffset then dOffset = TOOL.dOffset else dOffset = 0 end end local nAuxPart = EgtGroup(GDB_ID.ROOT) local nAuxLay = EgtGroup(nAuxPart) local nLoop = EgtCurveCompoByChain(nAuxLay, tbIdEdges, EgtSP(tbIdEdges[1], GDB_RT.GLOB), false) -- ora che ho gli edge nell'ordine giusto ricostruisco la tabella dei parent local tbIdEdgesOrd = {} for i = 1, #tbIdEdges do local ptStart = EgtUP(nLoop, i - 1, GDB_ID.ROOT) for j = 1, #tbIdEdges do if dist(ptStart, EgtSP(tbIdEdges[j], GDB_ID.ROOT)) < GEO.EPS_SMALL then table.insert(tbIdEdgesOrd, tbIdEdges[j]) break end end end tbIdEdges = tbIdEdgesOrd local tbParent = {} for _, nEdgeId in pairs(tbIdEdges) do table.insert(tbParent, EgtGetParent(EgtGetParent(nEdgeId))) end EgtOffsetCurve(nLoop, -dOffset, GDB_OT.EXTEND) -- N.B.: qui spero che si sia mantenuto il numero di curve e di poter ancora associare le curve di offset con quelle originali e con il relativo part di origine local dOffsetMax = EgtCurveMaxOffset(nLoop) TOOL.tbIdLoop = TOOL.ExplodeAndNameEdges( nLoop, false) -- creo i part con tutte le info local nPrev = GDB_ID.NULL local nFirst = GDB_ID.NULL local tbInfo = TOOL.tbInfo -- da intefaccia devo settare:----------------------------------------------- -- - TOOL.tbIdEdges -- - dOffset -- - dSlopeAng -- - dDiamBore -- - dTh for i = 1, #tbIdEdges do tbInfo.nPrevId = nPrev tbInfo.dTh = TOOL.dTh tbInfo.nParent = tbParent[i] local dThParent = EgtGetInfo(tbInfo.nParent, "Th", "d") or 0 tbInfo.dH = ((dOffsetMax - TOOL.dDiamBore/2) + dThParent) / cos(TOOL.dSlopeAng) tbInfo.nEdge = 3 -- so già che il pezzo che creo si attaccherà al lato A3 del loop della paretina del lavandino local nCurr = CreateSplitBottomPart(tbInfo, i, tbIdEdges, nPrev, nFirst) if i == 1 then nFirst = nCurr end if i == #tbIdEdges then tbInfo.nNextId = nFirst end -- modifico le paretine vicine se serve local nNextId = TOOL.tbInfo.nNextId local Prev_i = i == 1 and #tbIdEdges or (i - 1) local Next_i = i == #tbIdEdges and 1 or (i + 1) if tbInfo.nPrevId and tbInfo.nPrevId ~= GDB_ID.NULL then FillInfoTableFromPart(tbInfo.nPrevId) CreateSplitBottomPart(tbInfo, Prev_i, tbIdEdges, nil, nCurr) -- da modificare gli input per il prev end if nNextId and nNextId ~= GDB_ID.NULL then FillInfoTableFromPart(nNextId) CreateSplitBottomPart(tbInfo, Next_i, tbIdEdges, nCurr, nil) -- da modificare gli input per il next end -- pulisco la tabella con i dati for j, v in ipairs(tbInfo) do tbInfo[j] = nil end nPrev = nCurr end EgtErase(nAuxPart) end local function CountInLoops(nEdgeId) local nLay = EgtGetParent(nEdgeId) local nParent = EgtGetParent(nLay) local nNextLay = EgtGetFirstNameInGroup(nParent, "InLoop") local c = 1 while nNextLay ~= nLay do nNextLay = EgtGetNextName(nNextLay, "InLoop") c = c + 1 end return c end local function UpdateNeighInfo() if not TOOL.nLayLoopParent or TOOL.nLayLoopParent == GDB_ID.NULL then TOOL.nLayLoopParent = EgtGetParent(TOOL.nEdgeId) end local nEdges = EgtGetGroupObjs(TOOL.nLayLoopParent) -- controllo il prev local nPrev = TOOL.tbInfo.nEdge > 1 and TOOL.tbInfo.nEdge - 1 or nEdges -- numero ordinale della paretina precedente alla corrente local sNamePrev = "A"..EgtNumToString(nPrev) -- correggo il nome in caso l'edge appartenga ad un inloop if not TOOL.tbInfo.bOutLoop then sNamePrev = sNamePrev.."_I"..EgtNumToString(TOOL.tbInfo.nIn) end -- in nPrevId salvo già la paretina dello stesso tipo della corrente(alzatina o frontalino) local tbPrev = EgtGetInfo(TOOL.tbInfo.nParent, sNamePrev, "vs") local bSameSide = false if tbPrev then for _, NamePrev in pairs(tbPrev) do sNamePrev = NamePrev TOOL.tbInfo.nPrevId = EgtGetFirstNameInGroup( GDB_ID.ROOT, NamePrev) local dPairAngPrev = EgtGetInfo(TOOL.tbInfo.nPrevId, "PairAng", "d") if dPairAngPrev then bSameSide = TOOL.tbInfo.dPairAng * dPairAngPrev > 0 end if bSameSide then break end end end if not bSameSide then TOOL.tbInfo.nPrevId = GDB_ID.NULL end -- al precedente setto il curr come Next -- al corrente setto il prev if TOOL.tbInfo.nPrevId and TOOL.tbInfo.nPrevId ~= GDB_ID.NULL then EgtSetInfo(TOOL.tbInfo.nPrevId, "Next", TOOL.tbInfo.sName) EgtSetInfo(TOOL.tbInfo.nId, "Prev", sNamePrev) end -- controllo il next local nNext = TOOL.tbInfo.nEdge == nEdges and 1 or (TOOL.tbInfo.nEdge + 1) local sNameNext = "A"..EgtNumToString(nNext) -- correggo il nome in caso l'edge appartenga ad un inloop if not TOOL.tbInfo.bOutLoop then sNameNext = sNameNext.."_I"..EgtNumToString(TOOL.tbInfo.nIn) end -- in nNextId salvo già la paretina dello stesso tipo della corrente(alzatina o frontalino) local tbNext = EgtGetInfo(TOOL.tbInfo.nParent, sNameNext, "vs") bSameSide = false if tbNext then for _, NameNext in pairs(tbNext) do sNameNext = NameNext TOOL.tbInfo.nNextId = EgtGetFirstNameInGroup( GDB_ID.ROOT, NameNext) local dPairAngNext = EgtGetInfo(TOOL.tbInfo.nNextId, "PairAng", "d") if dPairAngNext then bSameSide = TOOL.tbInfo.dPairAng * dPairAngNext > 0 end if bSameSide then break end end end if not bSameSide then TOOL.tbInfo.nNextId = GDB_ID.NULL end -- al successivo setto il curr come Prev -- al corrente setto il next if TOOL.tbInfo.nNextId and TOOL.tbInfo.nNextId ~= GDB_ID.NULL then EgtSetInfo(TOOL.tbInfo.nNextId, "Prev", TOOL.tbInfo.sName) EgtSetInfo(TOOL.tbInfo.nId, "Next", sNameNext) end end function TOOL.CreateParetinaFull(bPrev, bNext, bRecurs) if bPrev == nil then bPrev = TOOL.bPrev end if bNext == nil then bNext = TOOL.bNext end if bRecurs == nil then bRecurs = false end -- se non ho ricevuto input li recupero dalla tabella generale if not TOOL.nEdgeId then return end if not TOOL.tbInfo.nId or not bRecurs then -- recupero tutte le info che mi servono (che vengono messe in TOOL.tbInfo) FillInfoTable() local nPairMode = 4 if TOOL.tbInfo.nJunctionType == 1 then nPairMode = 1 elseif TOOL.tbInfo.nJunctionType == 2 then nPairMode = 2 end TOOL.tbInfo.nPairMode = nPairMode end TOOL.tbInfo.nLayLoopParent= EgtGetParent(TOOL.tbInfo.nEdgeId) TOOL.tbIdLoop = FindEdges(TOOL.tbInfo.nLayLoopParent, TOOL.tbInfo) -- tabella che contiene gli id degli Edge del loop -- determino se il l'edge è di un inloop o di un outloop TOOL.tbInfo.bOutLoop = EgtGetName(EgtGetParent(TOOL.tbInfo.nEdgeId)) == "OutLoop" if not TOOL.tbInfo.bOutLoop then TOOL.tbInfo.nIn = CountInLoops(TOOL.tbInfo.nEdgeId) end -- controllo nelle info del parent se era già stato creato il part associato a quel lato local sEdgeName = EgtGetName(TOOL.tbInfo.nEdgeId) -- se inloop correggo il nome dell'info da A1 a A1_I1, dove I1 indica il primo Inloop if not TOOL.tbInfo.bOutLoop then sEdgeName = sEdgeName.."_I"..EgtNumToString(TOOL.tbInfo.nIn) end if not TOOL.tbInfo.nParent or TOOL.tbInfo.nParent == GDB_ID.NULL then TOOL.tbInfo.nParent = EgtGetParent(EgtGetParent(TOOL.tbInfo.nEdgeId))end local tbChildName = EgtGetInfo(TOOL.tbInfo.nParent, sEdgeName, "vs") local nChildPart = nil local dPairAng = 0 local bFound = false if tbChildName then for _, sChildName in pairs(tbChildName) do nChildPart = EgtGetFirstNameInGroup(GDB_ID.ROOT, sChildName) if nChildPart then dPairAng = EgtGetInfo(nChildPart, "PairAng", "d") or 0 end if math.abs(dPairAng - TOOL.tbInfo.dPairAng) < GEO.EPS_SMALL then bFound = true break end end end if not bFound then nChildPart = nil dPairAng = 0 end if not nChildPart or math.abs(dPairAng - TOOL.tbInfo.dPairAng) > GEO.EPS_SMALL then -- se il part non esiste, lo creo local sPrefix = "Part" local sPartname = sPrefix..sEdgeName TOOL.tbInfo.nId = TOOL.CreatePartLayer(sPartname) sPartname = EgtGetName(TOOL.tbInfo.nId) TOOL.tbInfo.sName = sPartname UpdateNeighInfo() --aggiorno le info dei child nel part parent -- cerco se esiste già un altro part creato su quel lato (CONSIDERO CHE AL PIù SU UN LATO POSSANO COESISTERE UN'ALZATINA E UN FRONTALINO) local sChildFromEdge = EgtGetInfo(TOOL.tbInfo.nParent, sEdgeName) if sChildFromEdge then sChildFromEdge = sChildFromEdge..","..sPartname else sChildFromEdge = sPartname end if TOOL.tbInfo.nParent then EgtSetInfo(TOOL.tbInfo.nParent, sEdgeName, sChildFromEdge) end else -- se esisteva già ripulisco i layer della regione e del loop ed elimino il solido ClearPart(nChildPart) TOOL.tbInfo.nId = nChildPart TOOL.tbInfo.sName = EgtGetName(TOOL.tbInfo.nId) -- recupero l'id di eventuali vicini TOOL.tbInfo.nPrevId = EgtGetFirstNameInGroup(GDB_ID.ROOT, EgtGetInfo(TOOL.tbInfo.nId, "Prev")) or GDB_ID.NULL TOOL.tbInfo.nNextId = EgtGetFirstNameInGroup(GDB_ID.ROOT, EgtGetInfo(TOOL.tbInfo.nId, "Next")) or GDB_ID.NULL end local tbLayers = TOOL.FindLayers(TOOL.tbInfo.nId) TOOL.tbInfo.nLayLoop = tbLayers["OutLoop"] TOOL.CreateParetina() TOOL.CreateAdjustedPart() TOOL.CreatePart() -- creo i riferimenti e salvo i parametri del part local sNamePartDest = EgtGetName(TOOL.tbInfo.nParent) local sEdgeDest = EgtGetName(TOOL.tbInfo.nEdgeId) local sLayEdgeDest = EgtGetName(EgtGetParent(TOOL.tbInfo.nEdgeId)) if TOOL.tbInfo.bOnLoop then -- waterfall TOOL.tbInfo.dSideAngT = TOOL.dPairAng + 90 TOOL.tbInfo.dYOffset = TOOL.tbInfo.dTh * tan(TOOL.tbInfo.dSideAngT) TOOL.tbInfo.sDestRefOff = '0,0,-x' TOOL.tbInfo.sRefOff = '0,'..EgtNumToString(TOOL.tbInfo.dYOffset)..',0' else -- splashtop TOOL.tbInfo.dSideAngT = TOOL.dPairAng - 90 TOOL.tbInfo.dYOffset = TOOL.tbInfo.dTh * tan(TOOL.tbInfo.dSideAngT) TOOL.tbInfo.sDestRefOff = '0,0,0' TOOL.tbInfo.sRefOff = EgtNumToString(TOOL.tbInfo.dXOffset)..','..EgtNumToString(TOOL.tbInfo.dYOffset)..',-x' end TOOL.tbInfo.dThParent = EgtGetInfo(TOOL.tbInfo.nParent, "Th", "d") local nIdRefDest = TOOL.CreateReference( TOOL.tbInfo.nParent, sLayEdgeDest, sEdgeDest, TOOL.tbInfo.nIn, TOOL.tbInfo.dThParent, TOOL.tbInfo.sDestRefOff, TOOL.tbInfo.sName) local nIdMyRef = TOOL.CreateReference( TOOL.tbInfo.nId, 'OutLoop', 'A1', nil,TOOL.tbInfo.dTh, TOOL.tbInfo.sRefOff) TOOL.SetPairInfo( TOOL.tbInfo, nIdMyRef, sNamePartDest, nIdRefDest, -1) -- devo modificare anche la paretina precedente e la successiva -- modifico anche la paretina precedente(se esiste) -- creo il solido e lo accoppio if SLD then SLD.CurrId = TOOL.tbInfo.nId SLD.Main() end if ASS then ASS.nVeinCtx = EgtGetContext() ASS.nPartId = TOOL.tbInfo.nId ASS.PairSingle() end local nNextId = TOOL.tbInfo.nNextId if bPrev and TOOL.tbInfo.nPrevId and TOOL.tbInfo.nPrevId ~= GDB_ID.NULL then FillInfoTableFromPart(TOOL.tbInfo.nPrevId) TOOL.CreateParetinaFull(false, false, true) end -- modifico anche la paretina successiva(se esiste) if bNext and nNextId and nNextId ~= GDB_ID.NULL then FillInfoTableFromPart(nNextId) TOOL.CreateParetinaFull(false, false, true) end TOOL.SaveMePlease() -- pulisco la tabella con i dati TOOL.tbInfo = {} end return TOOL