Files
StoneSolidGen/TemplateTool.lua
T
Daniele Bariletti 28922eff89 - disattivata l'impostazione per l'esecuzione nel CAM5 per il CreateSolid
- gestione dell'import di piani cucina con un loop interno
- gestione della creazione di un fondello con un pezzo unico o con un pezzo per lato
- correzioni al calcolo del draft angle, creazione del pezzo a partire da misure e angoli e calcolo delle misure del pezzo tenendo conto dei vicini.
2024-12-20 10:00:02 +01:00

658 lines
27 KiB
Lua

-- 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)
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
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)
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)
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 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
tbInfo.dAngBR = 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
tbInfo.dAngBL = 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