13 Commits

Author SHA1 Message Date
Nicola Pievani 56370249a4 Merge commit 'b307f76f639b25579817f8901a256d38e751eb68' into develop 2024-12-02 12:11:07 +01:00
Daniele Bariletti b307f76f63 - impostato il check per la rigenerazione della scena solo se i dati sono cambiati
- aggiunti controlli
- accoprato il codice in funzioni
- aggiunti commenti.
2024-12-02 10:41:28 +01:00
Daniele Bariletti 8195c4f39a aggiunta del template per la creazione di un cabinet. 2024-12-02 10:39:03 +01:00
Daniele Bariletti b1d113b63f - corretto bug nella creazione del solido di un pezzo con un foro.
- aggiunta lettura thickness dalle info del part.
2024-12-02 09:42:41 +01:00
Daniele Bariletti 0007832e9b - correzioni varie all'accoppiamento. 2024-11-26 12:21:57 +01:00
Daniele Bariletti f595d03482 - cambiata la variabile globale da CMD a SLD
- attivata la funzionalità da CAM e disattivata per l'uso da OFFICE.
2024-11-26 12:21:27 +01:00
Daniele Bariletti a466488114 OpertaionOnSolid :
- gestione output errori.
- evento importazione.
- accoppiamento automatico di default middle-middle.
| CreateSolid:
- estensione a più feature.
- gestione delle info per gli offset dei riferimenti.
2024-11-20 17:27:22 +01:00
Daniele Bariletti 6de80f9598 aggiunta gestione delle pocket 2024-11-12 17:12:30 +01:00
Daniele Bariletti 6370198a0c - aggiunta la funzione per l'accoppiamento automatico
- piccole correzioni e migliorie.
2024-11-12 17:10:22 +01:00
Daniele Bariletti 10f293b549 - correzioni alla conversione da .NET a LUA
- aggiunte alla gestione della storia
- aggiunte alla gestione della terna
- correzioni varie.
2024-10-22 16:20:12 +02:00
Daniele Bariletti 622cafcfc8 correzioni e aggiunta di funzioni. 2024-10-17 18:11:30 +02:00
Daniele Bariletti de312b7804 aggiunto il file per la gestione delle operazioni sui solidi tutta in lua. 2024-10-14 10:40:06 +02:00
Daniele Bariletti fb92ae324c aggiunta gestione dei loop interni con archi con sideAng ( manca gestione Heel in questi casi) 2024-10-02 10:19:11 +02:00
3 changed files with 1720 additions and 227 deletions
+561
View File
@@ -0,0 +1,561 @@
-- 2024/11/22
-- Template per la creazione di un cabinet
-- Intestazioni
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
EgtAddToPackagePath(EgtGetSourceDir() .. 'LuaLibs\\?.lua')
require( 'EgtCompo')
-- Parametri : dichiarazione e valori standard
-- N.B.: le dimensioni sono comprese di spessori
local CMP = {}
CMP.N1 = 'Altezza' -- altezza
CMP.T1 = 3 -- 0=null, 1=bool, 2=int, 3=len, 4=num, 5=string
CMP.V1 = 400
CMP.N2 = 'Larghezza' -- larghezza
CMP.T2 = 3
CMP.V2 = 600
CMP.N3 = 'Profondità' -- profondità
CMP.T3 = 3
CMP.V3 = 300
CMP.N4 = 'Spessore Top' -- spessore top
CMP.T4 = 3
CMP.V4 = 6
CMP.N5 = 'Spessore Bottom' -- spessore bottom
CMP.T5 = 3
CMP.V5 = 8
CMP.N6 = 'Spessore Left' -- spessore left
CMP.T6 = 3
CMP.V6 = 8
CMP.N7 = 'Spessore Right' -- spessore right
CMP.T7 = 3
CMP.V7 = 65
CMP.N8 = 'Spessore Back' -- spessore back
CMP.T8 = 3
CMP.V8 = 7
CMP.ResetView = false
CMP.DrawSolid = true
CMP.Npar = 8
CMP.Nome = 'Cabinet'
_G.CMP = CMP
CMP.ERR = 0
CMP.MSG = ''
-- Aggiorno con ultimi valori salvati (se presenti)
CMP.DATA = EgtGetSourceDir() .. CMP.Nome ..'.dat'
LoadCompoData()
-- Carico i dati letti da file .dat
local tbOrigVal={}
local function OrigData()
tbOrigVal.v1 = CMP.V1
tbOrigVal.v2 = CMP.V2
tbOrigVal.v3 = CMP.V3
tbOrigVal.v4 = CMP.V4
tbOrigVal.v5 = CMP.V5
tbOrigVal.v6 = CMP.V6
tbOrigVal.v7 = CMP.V7
tbOrigVal.v8 = CMP.V8
end
---
local tbName = {'Bottom', 'Left', 'Right', 'Top', 'Back'}
local sUNICode = os.date( '%y%m%d%H%M%S', os.time()).."_"
-- CREAZIONE Layer di un singolo Part
local function CreatePartLayer(PartName)
-- 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 LIn = EgtGroup(Pz,GDB_RT.LOC) -- layer della figura principale
EgtSetName(LIn,'InLoop')
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')
end
--
-- RESTITUISCE una tabella con gli Id dei layer del part, altrimenti nil
local function 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['InLoop'] = EgtGetFirstNameInGroup(IdPart, 'InLoop')
tbLayer['Region'] = EgtGetFirstNameInGroup(IdPart, 'Region')
tbLayer['Ref'] = EgtGetFirstNameInGroup(IdPart, 'Ref')
tbLayer['Labels'] = EgtGetFirstNameInGroup(IdPart, 'Labels')
tbLayer['Aux'] = EgtGetFirstNameInGroup(IdPart, 'Aux')
return tbLayer
end
--
-- CREAZIONE Layers per ogni Parts indicato in tabella 'tbName' e Layer Dimensions
local function CreateLayers()
for i=1, 5 do
-- Pezzo e Layer
CreatePartLayer(tbName[i])
end
local Pz = EgtGroup(GDB_ID.ROOT,GDB_RT.LOC) -- layer dimensioni e etichette
EgtSetName( Pz, 'Dimensions')
end
--
-- ASSEGNO Info per conoscere le direzioni dei lati
local function SetMachiningInfo(Layer, bInLoop)
-- if not bInLoop then return end
if EgtIsLayer( Layer) then
local LayerName = EgtGetName( Layer)
-- verifico che sia di tipo In o Out, altrimenti ricerco nel Part il layer
if not LayerName == 'OutLoop' or not LayerName == 'InLoop' then
Layer = EgtGetFirstInGroup( Layer)
CMP.ERR = 2
CMP.MSG = CMP.MSG.." In SetMachiningInfo il Layer non è di tipo 'OutLoop' o 'InLoop'."
end
else
CMP.ERR = 3
CMP.MSG = CMP.MSG.." In SetMachiningInfo il Layer non è di tipo 'OutLoop' o 'InLoop'."
end
local nId = EgtGetFirstInGroup(Layer)
local nPrevId = EgtGetLastInGroup(Layer)
local nNextId = EgtGetNext(nId)
local nFirstId = nId
local nEdges = EgtGetGroupObjs(Layer)
for i = 1, nEdges do
-- recupero i dati
local vtCurrS = EgtSV(nId, GDB_RT.GLOB)
local vtPrevS = EgtSV(nPrevId, GDB_RT.GLOB)
local vtNextS = EgtSV(nNextId, GDB_RT.GLOB)
local vtAx = Z_AX()
if bInLoop then vtAx=-vtAx end
local NextAng = GetRotation( vtCurrS, vtNextS, vtAx)
local PrevAng = GetRotation( vtPrevS, 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
--
-- 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)
local function ExplodeAndNameEdges( IdLoop, bInLoop)
local sNameLayer = ''
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 = 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 = 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
while nEdge do
local tbName = EgtNumToString(nCount)
EgtSetName( nEdge, "A"..tbName)
nCount = nCount + 1
nEdge = EgtGetNext(nEdge)
end
-- Ricavo info direzioni
SetMachiningInfo(nLay,bInLoop)
end
--
-- Per disporre i pezzi in piano non sovrappposti (in assemblaggio non serve)
local HorizontalOffset = 0
-- CREAZIONE di un solido, o della sua buca
local function CreatePart_0(IdPart, sName, ptDiagStart, ptDiagEnd, dTh, dOffset, bInLoop)
-- recupero il layer del contorno
local sNameLayer = ''
if bInLoop then
sNameLayer = 'InLoop'
if not ptDiagStart then
ptDiagStart = {1,1,0}
CMP.ERR = 4
CMP.MSG = CMP.MSG.." Manca la definizione del punto iniziale per l'InLoop, di default (1,1,0)."
end
else
sNameLayer = 'OutLoop'
ptDiagStart = ORIG()
end
-- Recupero gli Id dei Layer (che sono vuoti)
local tbLayer = FindLayers( IdPart)
-- Nel Layer OutLoop o InLoop definisco il contorno RETTANGOLO
EgtOutLog(sNameLayer..' '..tostring(tbLayer[sNameLayer]))
local IdLoop = EgtRectangle2P(tbLayer[sNameLayer],ptDiagStart,ptDiagEnd,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 sNameLayer == 'InLoop' then
local IdOutRegion = EgtGetPrev(IdReg)
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) --debug
end
if bInLoop then EgtInvertCurve(IdLoop) end
-- Ricavo i lati da lavorare
ExplodeAndNameEdges( IdLoop)
-- Se sono InLoop non devo settare
if bInLoop then return end
-- definisco spessore pezzo
EgtSetInfo(IdPart, 'Th', dTh)
-- INFO NECESSARIA
EgtSetInfo(IdPart, 'Paired',tostring(IdPart))
-- inserisco le etichette del pezzo
local ptTop = Point3d(ptDiagEnd)/2
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({dOffset,0,0})
--EgtMove(IdPart,vtMove, GDB_RT.GLOB)
HorizontalOffset = HorizontalOffset + Point3d(ptDiagEnd):getX()
end
--
local function CreatePart(tbLayer, sName, IdEntCrv, dTh, dOffset, bInLoop)
-- recupero il layer del contorno
local sNameLayer = ''
if bInLoop then
sNameLayer = 'InLoop'
else
sNameLayer = 'OutLoop'
end
-- recupero l'Id del part
local IdPart = EgtGetParent( tbLayer[sNameLayer])
-- Nel Layer OutLoop o InLoop definisco il contorno RETTANGOLO
EgtOutLog(sNameLayer..' '..tostring(tbLayer[sNameLayer]))
-- Copio nel layer OutLoop/InLoop il contorno
local IdLoop = EgtCopy( IdEntCrv, tbLayer[sNameLayer])
EgtErase(IdEntCrv)
-- Nel Layer Region definisco la regione piana
local IdReg = EgtSurfFlatRegion(tbLayer['Region'],IdLoop)
-- Se InLoop allora faccio la sottrazione con la regione OutRegion
if sNameLayer == 'InLoop' then
local IdOutRegion = EgtGetPrev(IdReg)
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
-- Ricavo i lati da lavorare
ExplodeAndNameEdges( IdLoop)
-- Se sono InLoop non devo settare
if bInLoop then return end
-- definisco spessore pezzo
EgtSetInfo(IdPart, 'Th', dTh)
-- 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({dOffset,0,0})
--EgtMove(IdPart,vtMove, GDB_RT.GLOB)
HorizontalOffset = HorizontalOffset + ptTop:getX()*2
end
--
-- Sposto l'etichetta del nome del Part nel Solido associato
local function 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
local function CreateReference( sNamePart, sNameLayer,sNameEdge, sNameRef, dVar, sDir)
local IdPart = EgtGetFirstNameInGroup(GDB_ID.ROOT, sUNICode..sNamePart)
local tbLayer = 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
local function CreatePointReference( sNamePart, sNameLayer,sNameEdge, sNameRef, nTypePt)
local IdPart = EgtGetFirstNameInGroup(GDB_ID.ROOT, sUNICode..sNamePart)
local tbLayer = 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)
local function SetPairInfo( 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 DrawLineraDimension( 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
local function SetReference()
-- Per accoppiamento Left-Bottom
CreateReference( tbName[1], 'OutLoop', 'A4', 'R1')
-- Per accoppiamento di right su bottom
CreateReference( tbName[1], 'OutLoop', 'A2', 'R2')
-- Per accoppiamento di back su bottom
CreateReference( tbName[1], 'OutLoop', 'A3', 'R3', CMP.SBA, '0,-x,0')
-- setto le info di accoppiamento per il PartLeft
CreateReference( tbName[2], 'OutLoop', 'A2', 'R1', CMP.SL, '0,0,-x')
SetPairInfo( tbName[2], 'R1', tbName[1], 'R1', -1, 90, 1)
-- setto le info per l'accoppiamento del top sul left
CreateReference( tbName[2], 'OutLoop', 'A4', 'R2', CMP.SL, '0,0,-x')
-- setto le info per l'accoppiamento del back sul left
CreateReference( tbName[2], 'OutLoop', 'A3', 'R3', CMP.SL, '0,0,0')
-- setto le info di accoppiamento del PartRight
SetPairInfo( tbName[3], 'R1', tbName[1], 'R2', -1, 90, 2)
CreateReference( tbName[3], 'OutLoop', 'A4', 'R1', CMP.SR, '0,0,-x')
-- setto le info di accoppiamento del PartTop
SetPairInfo( tbName[4], 'R1', tbName[2], 'R2', -1, 90, 1)
CreateReference( tbName[4], 'OutLoop', 'A2', 'R1')
-- setto le info di accoppiamento del PartBack
SetPairInfo( tbName[5], 'R1', tbName[2], 'R3', -1, 90)
CreateReference( tbName[5], 'OutLoop', 'A1', 'R1', CMP.SBA, '0,0,-x')
-- 1° punto di riferimento per la dimensione dell'altezza
CreatePointReference( tbName[1], 'OutLoop', 'A1', 'R4', 0, CMP.SB, '0,0,-x')
-- 2° punto di riferimento per la quota dell'altezza ( e 1° per la lunghezza)
CreatePointReference( tbName[4], 'OutLoop', 'A1', 'R2', 1, CMP.ST, '0,0,-x')
-- 2° riferimento per la lunghezza ( e 1° per la profondità)
CreatePointReference( tbName[4], 'OutLoop', 'A1', 'R3', 0, CMP.ST, '0,0,-x')
-- 2° riferimento per la profondità
CreatePointReference( tbName[4], 'OutLoop', 'A4', 'R4', 0, CMP.ST, '0,0,-x')
end
local function AddDimensions()
local GridFr = Frame3d(ORIG(),GDB_FR.FRONT)
-- la dimensione dell'altezza ( R4 di Bottom e R2 di Top)
DrawLineraDimension( tbName[1], 'R4', tbName[4], 'R2', 'SUA ALTEZZA',GridFr, Point3d(-50,0,0))
--dimensione della lunghezza ( R2 del Top e R3 del Top)
GridFr = Frame3d(ORIG(),GDB_FR.TOP)
DrawLineraDimension( tbName[4], 'R2', tbName[4], 'R3', 'LARGHEZZA',GridFr, Point3d(0,-50,0))
-- dimensione della profondità ( R3 del Top e R4 del Top)
GridFr = Frame3d(ORIG(),GDB_FR.TOP)
DrawLineraDimension( tbName[4], 'R3', tbName[4], 'R4', 'PROFONDITÀ',GridFr, Point3d(50,0,0))
EgtSetGridFrame(GLOB_FRM())
end
-- Confronto i dati del fiel .dat con quelli letti da programma
local 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 CMP_Draw(bPreview)
local bRedraw = IsDataChanged()
if bRedraw then
-- pulisco il file e leggo i dati
EgtNewFile()
HorizontalOffset = 0
CMP.A = CMP.V1 -- altezza
CMP.L = CMP.V2 -- lunghezza
CMP.P = CMP.V3 -- profondità
CMP.ST = CMP.V4 -- spessore top
CMP.SB = CMP.V5 -- spessore bottom
CMP.SL = CMP.V6 -- spessore left
CMP.SR = CMP.V7 -- spessore right
CMP.SBA = CMP.V8 -- spessore back
-- Costruisco i Part per ogni pezzo
CreateLayers()
-- Definisco le dimensioni dei rettangoli per costruire gli OutLoop
local tbDimension={{CMP.L,CMP.P,0},
{CMP.A-(CMP.ST+CMP.SB), CMP.P,0},
{CMP.A-(CMP.ST+CMP.SB), CMP.P,0},
{CMP.L,CMP.P,0},
{CMP.A-(CMP.ST+CMP.SB), CMP.L-(CMP.SL + CMP.SR),0}}
local tbTh={CMP.SB, CMP.SL, CMP.SR, CMP.ST, CMP.SBA}
-- Recupero il primo Part
local nIdP = EgtGetFirstPart()
local nCount = 1
while nIdP do
local sName = EgtGetName(nIdP)
if sName ~= 'Dimensions' and sName ~= 'SOLID' then
-- Recupero tabella Layer del pezzo
local tbLayer = FindLayers( nIdP)
-- Costruisco Layer OutLoop
local IdLoop = EgtRectangle2P(tbLayer['Aux'],{0,0,0}, tbDimension[nCount],GDB_RT.GLOB)
CreatePart(tbLayer, tbName[nCount], IdLoop,tbTh[nCount], HorizontalOffset)
-- Costruisco Layer InLoop
IdLoop = EgtRectangle2P(tbLayer['Aux'],{20,20,0}, {220,220,0},GDB_RT.GLOB)
CreatePart(tbLayer, tbName[nCount], IdLoop, tbTh[nCount], HorizontalOffset, true)
nCount = nCount + 1
end
nIdP = EgtGetNext(nIdP)
end
SetReference()
if CMP.DrawSolid then
local sPath = ""
sPath = EgtGetStringFromIni( "Vein3D", "Vein3D_Dir", "", EgtGetIniFile())
EgtOutLog(''..sPath)
loadfile(sPath ..'\\'.. "CreateSOLID_FromPartsInPark.lua")({AutoRun=true})
RelocateLabels()
loadfile(sPath ..'\\'.. "OperationOnSolid.lua")({AutoRun=true, nVeinCtx=EgtGetContext()})
AddDimensions()
end
-- Se non ci sono errori salvo i dati
if CMP.ERR == 0 then
-- scrivo i parametri nelle info del pezzo !! DA FARE !!
-- WriteCompoDataToPart( Pz, CMP.Nome, CMP.Npar)
-- salvo i parametri come nuovo default
SaveCompoData(CMP.Npar)
OrigData()
end
EgtSaveFile(EgtGetStringFromIni( "Vein3D", "Vein3D_Dir", "", EgtGetIniFile()) ..'\\'.. "FUCK.nge")
end
end
--CMP_Draw()
_G.CMP_Draw = CMP_Draw
+294 -227
View File
@@ -2,7 +2,7 @@
-- |ultima modifica:|
-- |aggiunta gestione di più loop interni|
--ERR == -1 valore di default
--ERR == 1 CMP.CurrId non è valido ( == -1)
--ERR == 1 SLD.CurrId non è valido ( == -1)
--ERR == 0 eseguito senza problemi
-- Intestazioni
@@ -10,20 +10,25 @@ require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
EgtOpenFile( "C:\\EgtData\\OmagOFFICE\\Temp\\debug_buche_sottili.nge")
--EgtOpenFile( "C:\\EgtData\\OmagOFFICE\\Temp\\buca_squadrata.nge")
-- Dati raccolti direttamente dal programma
local CMP = {}
local SLD = {}
--input
CMP.THICK = 20
CMP.CurrId = -1
SLD.THICK = 40
SLD.CurrId = -1
-- output
CMP.CurrPartSolid = -1
CMP.CurrSrfTmId = -1
CMP.ERR = -1
SLD.CurrPartSolid = -1
SLD.CurrSrfTmId = -1
SLD.ERR = -1
_G.CMP = CMP
----- mi preparo a ricevere argomenti
local arg = ...
local bAutoRun = false
if arg then
bAutoRun = arg.AutoRun
end
_G.SLD = SLD
local ColorSTD = 'AQUA'
local ColocERR = 'ORANGE'
@@ -61,11 +66,11 @@ local tbId_RectSurf = {}
local tbId_OutLoop = {}
-- tabella contenente le tabelle dei layer degli InLoop: IdI → lato del contorno
local tbId_InLoop = {}
-- tabella contenente le curve composte del layer OnPath: IdI →
-- tabella contenente le tabelle delle curve composte del layer OnPath: IdI →
local tbId_OnPath = {}
-- tabella contenente i lati del layer Pocket: IdI →
-- tabella contenente le tabelle dei lati del layer Pocket: IdI →
local tbId_Pocket = {}
-- tabella contenente le curve composte del layer FiloTop: IdI →
-- tabella contenente la tabella delle curve composte del layer FiloTop: IdI →
local tbId_FiloTop = {}
-- Id del solido generato
local IdEnt_Part = -1
@@ -81,8 +86,8 @@ local bAlwaysOnTop = true
--local nIdTrimIn = -1
local tbTrimTot = {}
-- Estensioni delle regioni di taglio per SideAngle
local ovX = 100
local ovY = 100
--NB: lo spessore dei pezzi è limitato a 100(o meno, se ci sono dei sideAng), quindi per spessori importanti bisognerebbe modificare il valore di questa dimensione
local DefaultDim = 100
-- valore di tolleranza minimo per estrarre i contorni da una regione
local TollY = 1
local m_bArc = false
@@ -105,7 +110,7 @@ local function ResetAllTabAndVar()
tbId_Pocket = {}
-- tabella contenente le curve composte del layer FiloTop: IdI →
tbId_FiloTop = {}
-- Id del solido generato
-- Id del solido generato
IdEnt_Part = -1
-- Id del solido da sottrarre
IdEnt_SubPart = -1
@@ -150,6 +155,7 @@ local function CreatePartSOLID()
EgtSetName( IdP_SOLID, "SOLID")
EgtSetInfo(IdP_SOLID, "Parent", IdFP)
EgtSetInfo(IdFP, "Child", IdP_SOLID)
EgtSetInfo( IdP_SOLID, "Th", RTh)
IdL_Temp = EgtGroup(IdP_SOLID,GDB_RT.LOC)
EgtSetName( IdL_Temp, "Temp")
IdL_Solid = EgtGroup(IdP_SOLID,GDB_RT.LOC)
@@ -223,36 +229,28 @@ end
----------------------------------------------------------------------------
-- **Carico tabelle** IdL_OutLoop, IdL_InLoop, tbId_OnPath, tbId_Pocket, tbId_FiloTop
----------------------------------------------------------------------------
-- riceve la tablella e il nome del Layer, la tabella e l'ID del layer
-- riceve la tablella e il nome del Layer, riempie la tabella e restituisce l'ID del layer
local function GetIdFromLay( myTab, sLay)
RTh = CMP.THICK
RTh = SLD.THICK
--IdFP = EgtGetFirstPart()
local IdLay = EgtGetFirstNameInGroup( IdFP, sLay)
local tbIdLayTemp = {}
-- salvo l'id solo del primo layer con nome sLay
local IdFirstLay = IdLay
-- questo while su IdLay serve se ho più gruppi con questo nome (serve per InLoop)
-- questo while su IdLay serve se ho più gruppi con questo nome
while IdLay do
local IdS = EgtGetFirstInGroup( IdLay)
while IdS do
local bInsert = false
if EgtGetType( IdS) == GDB_TY.CRV_LINE or EgtGetType( IdS) == GDB_TY.CRV_ARC then
if sLay ~= 'InLoop' then
if EgtGetType( IdS) == GDB_TY.CRV_LINE or EgtGetType( IdS) == GDB_TY.CRV_ARC or EgtGetType( IdS) == GDB_TY.CRV_COMPO then
if sLay == 'OutLoop' then
table.insert( myTab, IdS)
else
elseif sLay == 'InLoop' or sLay == 'Pocket' or sLay == 'FiloTop' or sLay == 'OnPath' then
table.insert( tbIdLayTemp, IdS)
end
bInsert = true
end
if sLay == 'FiloTop' and not bInsert then
table.insert( myTab, IdS)
end
if sLay == 'OnPath' and not bInsert then
table.insert( myTab, IdS)
end
IdS = EgtGetNext( IdS)
end
if sLay == 'InLoop' then
if sLay == 'InLoop' or sLay == 'Pocket' or sLay == 'FiloTop' or sLay == 'OnPath' then
table.insert( myTab, tbIdLayTemp)
tbIdLayTemp = {}
end
@@ -289,14 +287,6 @@ local function CreateSolid()
end
end
-- -- salvo le facce sopra e sotto come flat region
-- local nIdSurfFr1 = EgtSurfFlatRegion( IdL_Faces, tbLoop1)
-- local nIdSurfFr2 = EgtSurfFlatRegion( IdL_Faces, tbLoop2)
-- EgtSetAlpha({nIdSurfFr1,nIdSurfFr2},1)
-- table.insert( tbId_Faces, nIdSurfFr1)
-- table.insert( tbId_Faces, nIdSurfFr2)
-- creo le SurfTm delle facce sopra e sotto
local nIdSurf1 = EgtSurfTmByRegion( IdL_Solid, tbLoop1)
local nIdSurf2 = EgtSurfTmByRegion( IdL_Solid, tbLoop2)
@@ -318,8 +308,8 @@ local function CreateSolid()
EgtErase( tbTrimTot)
tbTrimTot = {nIdTrimTot}
IdEnt_Part = nIdTrimTot
CMP.CurrPartSolid = IdP_SOLID
CMP.CurrSrfTmId = nIdTrimTot
SLD.CurrPartSolid = IdP_SOLID
SLD.CurrSrfTmId = nIdTrimTot
end
--
@@ -329,11 +319,14 @@ end
local function PocketSolid()
-- se sono presenti dei ribassi provvedo a disegnarli
if #tbId_Pocket > 0 then
local IdCompo_Pocket = EgtCurveCompoByChain( IdL_Solid, tbId_Pocket, EgtSP( tbId_Pocket[1]), false)
local IdEnt_Pocket = EgtSurfTmByRegionExtrusion( IdL_Solid, {IdCompo_Pocket}, Z_AX()*(2* RTh))
EgtSurfTmSubtract( IdEnt_Part, IdEnt_Pocket)
EgtErase( {IdEnt_Pocket})
EgtErase( {IdCompo_Pocket})
for i = 1, #tbId_Pocket do
local IdCompo_Pocket, nCrv = EgtCurveCompoByChain( IdL_Solid, tbId_Pocket[i], EgtSP( tbId_Pocket[i][1]), false)
local IdEnt_Pocket = EgtSurfTmByRegionExtrusion( IdL_Solid, {IdCompo_Pocket}, Z_AX()*(2* RTh))
EgtSurfTmSubtract( IdEnt_Part, IdEnt_Pocket)
EgtErase( {IdEnt_Pocket})
EgtErase( {IdCompo_Pocket})
local a = 0
end
end
end
@@ -370,39 +363,40 @@ end
-- genero i tagli singoli
local function OnPathSolid()
for i=1, #tbId_OnPath, 1 do
local nInd = tbId_OnPath[i]
local D = GetDepthOnPath( nInd)
if D > RTh then
CMP.ERR = 1
EgtSetColor( {IdEnt_Part}, ColocERR)
end
-- creo una copia nel Layer "Temp"
local nEntCopy = EgtCopy( nInd, IdL_Temp)
local nId, nNbr = EgtExplodeCurveCompo( nEntCopy)
-- definisco il vettore di spostamento verticale del solido da sottrarre
local vtV = Z_AX()
if nId ~= nil then
for j=0 , nNbr-1, 1 do
local nTempId = nId + j
local vt = EgtSV( nTempId)
vt:rotate(vtV, 90)
if D > 0 or not vt then
local nEntCopy_1 = EgtCopy( nTempId, IdL_Temp)
local nEntCopy_2 = EgtCopy( nTempId, IdL_Temp)
EgtMove( {nEntCopy_2}, vtV*(- D))
local nLine_1 = EgtLine( IdL_Temp, EgtSP( nEntCopy_1, GDB_ID.ROOT ), EgtSP( nEntCopy_2, GDB_ID.ROOT ))
local nLine_2 = EgtLine( IdL_Temp, EgtEP( nEntCopy_1, GDB_ID.ROOT ), EgtEP( nEntCopy_2, GDB_ID.ROOT ))
local nCompo = EgtCurveCompoByChain( IdL_Solid, {nEntCopy_1,nLine_1,nEntCopy_2,nLine_2}, EgtSP( nLine_1), false)
local IdSubSolid = EgtSurfTmByRegionExtrusion( IdL_Solid, {nCompo}, vt*(2))
EgtSurfTmSubtract( IdEnt_Part, IdSubSolid)
EgtErase( {nEntCopy_1,nLine_1,nEntCopy_2,nLine_2, nCompo, IdSubSolid, nTempId})
end
for j=1, #tbId_OnPath[i], 1 do
local nInd = tbId_OnPath[i][j]
local D = GetDepthOnPath( nInd)
if D > RTh then
SLD.ERR = 1
EgtSetColor( {IdEnt_Part}, ColocERR)
end
-- creo una copia nel Layer "Temp"
local nEntCopy = EgtCopy( nInd, IdL_Temp)
local nId, nNbr = EgtExplodeCurveCompo( nEntCopy)
-- definisco il vettore di spostamento verticale del solido da sottrarre
local vtV = Z_AX()
if nId ~= nil then
for j=0 , nNbr-1, 1 do
local nTempId = nId + j
local vt = EgtSV( nTempId)
vt:rotate(vtV, 90)
if D > 0 or not vt then
local nEntCopy_1 = EgtCopy( nTempId, IdL_Temp)
local nEntCopy_2 = EgtCopy( nTempId, IdL_Temp)
EgtMove( {nEntCopy_2}, vtV*(- D))
local nLine_1 = EgtLine( IdL_Temp, EgtSP( nEntCopy_1, GDB_ID.ROOT ), EgtSP( nEntCopy_2, GDB_ID.ROOT ))
local nLine_2 = EgtLine( IdL_Temp, EgtEP( nEntCopy_1, GDB_ID.ROOT ), EgtEP( nEntCopy_2, GDB_ID.ROOT ))
local nCompo = EgtCurveCompoByChain( IdL_Solid, {nEntCopy_1,nLine_1,nEntCopy_2,nLine_2}, EgtSP( nLine_1), false)
local IdSubSolid = EgtSurfTmByRegionExtrusion( IdL_Solid, {nCompo}, vt*(2))
EgtSurfTmSubtract( IdEnt_Part, IdSubSolid)
EgtErase( {nEntCopy_1,nLine_1,nEntCopy_2,nLine_2, nCompo, IdSubSolid, nTempId})
end
end
else
Engraves( nEntCopy)
end
else
Engraves( nEntCopy)
end
end
end
--
@@ -412,14 +406,18 @@ end
----------------------------------------------------------------------------
-- sottraggo al solido il contorno FiloTop
local function FiloTopSolid()
local D = GetDepth( IdL_FiloTop)
if D < 0.1 then
return
local nLay = EgtGetFirstNameInGroup( IdFP, "FiloTop")
for i = 1, #tbId_FiloTop do
local D = GetDepth( nLay)
if D < 0.1 then
return
end
local IdEnt_SurfFiloTop = EgtSurfTmByRegionExtrusion( IdL_Solid, tbId_FiloTop[i], Z_AX()*(- D -1))
EgtMove( {IdEnt_SurfFiloTop}, Z_AX()*1)
EgtSurfTmSubtract( IdEnt_Part, IdEnt_SurfFiloTop)
EgtErase( {IdEnt_SurfFiloTop})
nLay = EgtGetNextName( nLay, "FiloTop")
end
local IdEnt_SurfFiloTop = EgtSurfTmByRegionExtrusion( IdL_Solid, tbId_FiloTop, Z_AX()*(- D -1))
EgtMove( {IdEnt_SurfFiloTop}, Z_AX()*1)
EgtSurfTmSubtract( IdEnt_Part, IdEnt_SurfFiloTop)
EgtErase( {IdEnt_SurfFiloTop})
end
--
@@ -496,6 +494,7 @@ end
-- **Side Ang**
----------------------------------------------------------------------------
local function SideAngSolid( tbLoop, bInLoop)
local tbIdR = {}
local IdS
local Ang = 0
@@ -504,20 +503,21 @@ local function SideAngSolid( tbLoop, bInLoop)
m_bArc = false
local tbArc = {}
local tbLimited = {}
for i=1, #tbLoop, 1 do
IdS = tbLoop[i]
-- recupero i dati SideAng per ogni lato
Ang, Hill = GetAngHill( IdS)
NAng = GetnNextAng( IdS)
if math.abs(NAng) <= 2 then NAng = 0 end
-- PAng = GetnPrevAng( IdS)
-- if math.abs(PAng) <= 2 then PAng = 0 end
-- verifico che il lato presenti un angolo inclinato
--if ( math.abs( Ang) > 0.1 or bInLoop) and ( EgtGetType( IdS) ~= GDB_TY.CRV_ARC and EgtGetType( IdS) ~= GDB_TY.CRV_COMPO) then
if EgtGetType( IdS) == GDB_TY.CRV_ARC then
m_bArc = true
table.insert(tbArc, true)
local ptStart = EgtSP(IdS, GDB_ID.ROOT)
local vtStart = EgtSV( IdS, GDB_ID.ROOT)
local vtEnd = EgtEV( IdS, GDB_ID.ROOT)
if Ang == 0 then
local vtExtr = Z_AX() * RTh
if bAlwaysOnTop then
@@ -527,37 +527,75 @@ local function SideAngSolid( tbLoop, bInLoop)
if bAlwaysOnTop then
EgtInvertSurf( nSurfId)
end
local ptStart = EgtSP(IdS, GDB_ID.ROOT)
local vtStart = EgtSV( IdS, GDB_ID.ROOT)
local vtEnd = EgtEV( IdS, GDB_ID.ROOT)
local tbInfoRot = { nSurfId, ptStart, vtStart, Ang, Hill, NAng, vtEnd}
table.insert(tbIdR,tbInfoRot)
table.insert(tbLimited, false)
else
-- qui resta da gestire il caso con la superficie laterale che è un tronco di cono----
------
-- costruisco la superficie laterale generata dall'arco con una swept lungo l'arco stesso
-- la sezione di cui effetturare lo sweep viene creata trovando il punto di partenza del secondo arco che delimita questa superficie
local dLatMove = RTh * math.tan( math.abs(Ang) * pi / 180)
local vtLatMove = (Z_AX() ^ vtStart)
local vtVertMove = Z_AX() * RTh
if not bInLoop then vtLatMove = vtLatMove * (-1) end
-- devo controllare se il side ang e lo spessore della lastra sono abbastanza da far collassare l'arco in un punto ed eventualmente andare oltre
-- verifico quindi se devo limitare la superficie della sezione di cono
local dRad = EgtArcRadius( IdS)
local bLimited = false
local dArcAng = EgtArcAngCenter( IdS)
local bCheckLimit = (dArcAng > 0 and Ang < 0 ) or ( dArcAng < 0 and Ang > 0)
if bCheckLimit then
if dRad < math.abs(dLatMove) + 0.01 then
vtLatMove = vtLatMove * dRad
vtVertMove = Z_AX() * dRad / math.tan( math.abs(Ang) * pi / 180)
bLimited = true
end
else
vtLatMove = vtLatMove * dLatMove
end
table.insert(tbLimited, bLimited)
if (Ang > 0 and bAlwaysOnTop) or ( Ang < 0 and not bAlwaysOnTop) then
vtLatMove = vtLatMove * ( -1)
end
if bAlwaysOnTop then
vtVertMove = vtVertMove * (-1)
end
local ptSecondArcStart = ptStart + ( vtVertMove + vtLatMove)
local nIdLine = EgtLine(IdL_Temp,ptStart,ptSecondArcStart,GDB_ID.ROOT)
local nPointId = EgtPoint( IdL_Temp, ptSecondArcStart)
local nSurfId = 0
if not bLimited then
nSurfId = EgtSurfTmSwept(IdL_Solid,nIdLine,IdS,Z_AX(),false,0.01,GDB_ID.ROOT)
EgtInvertSurf( nSurfId)
else
local vtAx = Z_AX()
if not bAlwaysOnTop then
vtAx = vtAx * (-1)
end
nSurfId = EgtSurfTmRuled( IdL_Solid, nPointId, IdS)
EgtInvertSurf( nSurfId)
-- nSurfId = EgtSurfTmCone(IdL_Solid,ptSecondArcStart, vtAx, dRad, RTh)
end
EgtErase( nIdLine)
EgtErase( nPointId)
local tbInfoRot = { nSurfId, ptStart, vtStart, Ang, Hill, NAng, vtEnd}
table.insert(tbIdR,tbInfoRot)
end
elseif EgtGetType( IdS) ~= GDB_TY.CRV_COMPO then
table.insert(tbArc, false)
local ptS = EgtSP( IdS, GDB_ID.ROOT)
local vtS = EgtSV( IdS, GDB_ID.ROOT)
local vtE = EgtEV( IdS, GDB_ID.ROOT)
local IdRect = EgtCurveGetFatCurve( IdS, IdL_Temp, 100, true)
if bInLoop then
--EgtInvertCurve( IdRect)
end
local IdRect = EgtCurveGetFatCurve( IdS, IdL_Temp, DefaultDim, true)
local IdSurf = EgtSurfTmByRegion( IdL_Solid, IdRect)
EgtErase( IdRect)
local tbInfoRot = { IdSurf, ptS, vtS, Ang, Hill, NAng, vtE}
table.insert( tbIdR, tbInfoRot)
table.insert(tbLimited, false)
end
end
if m_bArc then
--do return end -- debug
local a = 0
end
-- posiziono i piani calcolati in precedenza e creo i piani di Hill
for i=1, #tbIdR, 1 do
local dTempAng = 90
@@ -579,115 +617,108 @@ local function SideAngSolid( tbLoop, bInLoop)
end
end
if m_bArc then
--do return end -- debug
local a = 0
end
if bInLoop then
local b = 0 -- debug
end
-- **NANG** corrego la dimenione dei piani in funzione dell'angolo che descrivono con il pezzo successivo
for i=1, #tbIdR, 1 do
local Ind_Pre = i
local Ind_Curr = i
local Ind_Nex = i + 1
if i == #tbIdR then
Ind_Nex = 1
end
-- se ho solo una faccia laterale termino ( è un foro descritto da un unico loop circolare)
if Ind_Curr == Ind_Nex then break end
local pt_n, vn_n = EgtSurfTmFacetCenter( tbIdR[Ind_Nex][1], 0)
local pt_p, vn_p = EgtSurfTmFacetCenter( tbIdR[Ind_Pre][1], 0)
local pt_c, vn_c = EgtSurfTmFacetCenter( tbIdR[Ind_Curr][1], 0)
if tbArc[Ind_Nex] then
pt_n = tbIdR[Ind_Nex][2] -- prendo startPoint
vn_n = tbIdR[Ind_Nex][3] -- prendo vtStart
if math.abs( tbIdR[Ind_Pre][6]) > 90 then
if math.abs( tbIdR[Ind_Curr][6]) > 90 then
vn_n = vn_n * (-1)
elseif math.abs( tbIdR[Ind_Pre][6]) > 90 then
vn_n = EgtEV( tbLoop[Ind_Pre], GDB_ID.ROOT) -- prendo l'end del segmento precedente all'arco
elseif math.abs( tbIdR[Ind_Curr][6]) > 90 then
vn_n = EgtEV( tbLoop[Ind_Curr], GDB_ID.ROOT) -- prendo l'end del segmento precedente all'arco
end
end
if tbArc[Ind_Pre] then
pt_p = EgtEP( tbLoop[Ind_Pre], GDB_ID.ROOT) -- prendo endPoint
vn_p = tbIdR[Ind_Pre][7] -- prendo vtEnd
if math.abs( tbIdR[Ind_Pre][6]) < 90 then
vn_p = vn_p * (-1)
elseif math.abs( tbIdR[Ind_Pre][6]) > 90 then
vn_p = tbIdR[Ind_Nex][3] -- prendo lo start del segmento successivo all'arco
if tbArc[Ind_Curr] then
pt_c = EgtEP( tbLoop[Ind_Curr], GDB_ID.ROOT) -- prendo endPoint
vn_c = tbIdR[Ind_Curr][7] -- prendo vtEnd
if math.abs( tbIdR[Ind_Curr][6]) < 90 then
vn_c = vn_c * (-1)
elseif math.abs( tbIdR[Ind_Curr][6]) > 90 then
vn_c = tbIdR[Ind_Nex][3] -- prendo lo start del segmento successivo all'arco
end
end
if (not tbArc[Ind_Nex]) and (not tbArc[Ind_Pre]) then
if ( tbIdR[Ind_Pre][6] < 0) then
if (not tbArc[Ind_Nex]) and (not tbArc[Ind_Curr]) then
if ( tbIdR[Ind_Curr][6] < 0) then
vn_n = vn_n * (-1)
vn_p = vn_p * (-1)
vn_c = vn_c * (-1)
end
end
-- devo tagliare le superfici di taglio con le superfici di taglio
-- gli archi non sono da tagliare
if not tbArc[Ind_Pre] then
EgtCutSurfTmPlane( tbIdR[Ind_Pre][1], pt_n, vn_n, false)
-- gli archi li taglio usando i suoi vettori a inizio e fine curva
if tbArc[Ind_Curr] then
EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], tbIdR[Ind_Curr][2], - tbIdR[Ind_Curr][3], false)
EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], EgtEP(tbLoop[Ind_Curr], GDB_ID.ROOT), tbIdR[Ind_Curr][7], false)
else
EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], pt_n, vn_n, false)
end
if not tbArc[Ind_Nex] then
EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], pt_p, vn_p, false)
end
EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], pt_c, vn_c, false)
end
-- nel caso in cui la superficie generata dall'arco è limitata devo tagliare tra loro anche le superfici precedente e successiva all'arco--------------------------------------------------
if tbLimited[Ind_Curr] then
local Ind_Pre = Ind_Curr > 1 and (Ind_Curr - 1) or #tbLoop
local pt_p, vn_p = EgtSurfTmFacetCenter( tbIdR[Ind_Pre][1], 0)
pt_n, vn_n = EgtSurfTmFacetCenter( tbIdR[Ind_Nex][1], 0)
-- calcolo l'angolo tra le due facce
local dArcAng = EgtArcAngCenter( tbLoop[Ind_Curr])
local dAngSkip = tbIdR[Ind_Pre][6] + tbIdR[Ind_Nex][6] + dArcAng
if dAngSkip < 0 then
vn_p = vn_p * (-1)
vn_n = vn_n * (-1)
end
EgtCutSurfTmPlane( tbIdR[Ind_Pre][1], pt_n, vn_n, false)
EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], pt_p, vn_p, false)
end
--taglio i piani dei talloni con i piani dei talloni ( se non ho un altro tallone allora taglio con la sup di taglio)
local pt_nH, vn_nH
local pt_pH, vn_pH
if tbIdR[Ind_Pre][5] > 0 then
pt_pH, vn_pH = EgtSurfTmFacetCenter( tbIdR[Ind_Pre][9][1], 0)
if ( tbIdR[Ind_Pre][6] < 0) then
vn_pH = vn_pH * (-1)
local pt_cH, vn_cH
if tbIdR[Ind_Curr][5] > 0 then
pt_cH, vn_cH = EgtSurfTmFacetCenter( tbIdR[Ind_Curr][9][1], 0)
if ( tbIdR[Ind_Curr][6] < 0) then
vn_cH = vn_cH * (-1)
end
end
if tbIdR[Ind_Nex][5] > 0 then
pt_nH, vn_nH = EgtSurfTmFacetCenter( tbIdR[Ind_Nex][9][1], 0)
if ( tbIdR[Ind_Pre][6] < 0) then
if ( tbIdR[Ind_Curr][6] < 0) then
vn_nH = vn_nH * (-1)
end
if tbIdR[Ind_Pre][5] > 0 then
EgtCutSurfTmPlane( tbIdR[Ind_Pre][9][1], tbIdR[Ind_Nex][9][2], vn_nH, false)
EgtCutSurfTmPlane( tbIdR[Ind_Nex][9][1], tbIdR[Ind_Pre][9][2], vn_pH, false)
if tbIdR[Ind_Curr][5] > 0 then
EgtCutSurfTmPlane( tbIdR[Ind_Curr][9][1], tbIdR[Ind_Nex][9][2], vn_nH, false)
EgtCutSurfTmPlane( tbIdR[Ind_Nex][9][1], tbIdR[Ind_Curr][9][2], vn_cH, false)
-- se l'angolo con il prossimo lato è positivo, entrambi hanno un hill e gli Ang sono discordi, allora devo anche tagliare gli hill con i piani di taglio e viceversa
--if tbIdR[Ind_Pre][6] > 0 and tbIdR[Ind_Pre][4] * tbIdR[Ind_Nex][4] < 0 then
if tbIdR[Ind_Pre][6] > 0 then -- ho tolto la condizione che gli angoli debbano essere discordi!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
EgtCutSurfTmPlane( tbIdR[Ind_Nex][9][1], pt_p, vn_p, false)
EgtCutSurfTmPlane( tbIdR[Ind_Pre][9][1], pt_n, vn_n, false)
EgtCutSurfTmPlane( tbIdR[Ind_Pre][1], tbIdR[Ind_Nex][9][2], vn_nH, false)
EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], tbIdR[Ind_Pre][9][2], vn_pH, false)
--if tbIdR[Ind_Curr][6] > 0 and tbIdR[Ind_Curr][4] * tbIdR[Ind_Nex][4] < 0 then
if tbIdR[Ind_Curr][6] > 0 then -- ho tolto la condizione che gli angoli debbano essere discordi!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
EgtCutSurfTmPlane( tbIdR[Ind_Nex][9][1], pt_c, vn_c, false)
EgtCutSurfTmPlane( tbIdR[Ind_Curr][9][1], pt_n, vn_n, false)
EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], tbIdR[Ind_Nex][9][2], vn_nH, false)
EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], tbIdR[Ind_Curr][9][2], vn_cH, false)
end
else
EgtCutSurfTmPlane( tbIdR[Ind_Nex][9][1], pt_p, vn_p, false)
EgtCutSurfTmPlane( tbIdR[Ind_Pre][1], tbIdR[Ind_Nex][9][2], vn_nH, false)
EgtCutSurfTmPlane( tbIdR[Ind_Nex][9][1], pt_c, vn_c, false)
EgtCutSurfTmPlane( tbIdR[Ind_Curr][1], tbIdR[Ind_Nex][9][2], vn_nH, false)
end
else
if tbIdR[Ind_Pre][5] > 0 then
EgtCutSurfTmPlane( tbIdR[Ind_Pre][9][1], pt_n, vn_n, false)
EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], tbIdR[Ind_Pre][9][2], vn_pH, false)
if tbIdR[Ind_Curr][5] > 0 then
EgtCutSurfTmPlane( tbIdR[Ind_Curr][9][1], pt_n, vn_n, false)
EgtCutSurfTmPlane( tbIdR[Ind_Nex][1], tbIdR[Ind_Curr][9][2], vn_cH, false)
end
end
end
-- -- se ho archi nei loop creo la superficie laterale dei rispettivi cilindri
-- if m_bArc then
-- local vtExtr = Z_AX() * RTh
-- if bAlwaysOnTop then
-- vtExtr = vtExtr * (-1)
-- end
-- for i=1, #tbLoop, 1 do
-- IdS = tbLoop[i]
-- if EgtGetType( IdS) == GDB_TY.CRV_ARC then
-- local nSurfId = EgtSurfTmByExtrusion(IdL_Solid, IdS, vtExtr)
-- local ptStart = EgtSP(IdS, GDB_ID.ROOT)
-- local tbInfoRot = { nSurfId, ptStart, {0,0,0}, 0, 0, 0}
-- table.insert(tbIdR,tbInfoRot)
-- end
-- end
-- end
--do return end -- debug
-- unisco tutte le superfici laterali
local tbIdTrim = {}
@@ -723,6 +754,41 @@ local function SideAngSolid( tbLoop, bInLoop)
end
--
local function CorrectReference()
local sName = EgtGetName( IdFP)
if sName ~= "SOLID" then
local nLayRef = EgtGetFirstNameInGroup( IdFP, "Ref")
local nRef = EgtGetFirstInGroup(nLayRef)
while nRef do
local var = EgtGetInfo(nRef, "Var")
if var == "Th" then
var = RTh
else
var = EgtGetInfo(nRef, "Var", "i")
end
local dir = EgtGetInfo(nRef, "Dir")
if dir then
local tbDir = EgtSplitString(dir,",")
local vtDir = {}
for _,sDir in pairs(tbDir) do
sDir = sDir:gsub("x", EgtNumToString(var))
table.insert(vtDir, EgtEvalNumExpr(sDir))
end
vtDir = Vector3d(vtDir)
EgtMove(nRef,vtDir, GDB_RT.GLOB)
end
nRef = EgtGetNext(nRef)
end
end
end
local function GetThickness()
local val = EgtGetInfo( IdFP,"Th","d")
if val then
SLD.THICK = val
end
end
----------------------------------------------------------------------------
-- **Wire Frame**
----------------------------------------------------------------------------
@@ -757,21 +823,28 @@ local function ExtractBoundaryAndFaces()
-- EgtSurfTmByTriangles( IdL_Temp, tabMergSurf)
-- EgtErase( tabMergSurf)
-- IdS = EgtGetNext( IdS)
------------------------ gestione archi
----------- gestione archi che non vengono esplosi----------------
nCount = nCount + 1
local bExplode = false
----------- gestione archi che non vengono esplosi----------------
---
local nLoop, nLoopCount = EgtExtractSurfTmFacetLoops( IdS, 0, IdL_Bound)
local ColorApply = 'BLACK'
local tbLoopFlatRegion = {}
for l=nLoop, nLoop + (nLoopCount-1), 1 do
-- ricreo la faccia laterale come flat region e la metto con trasparenza massima
local nIdFace = EgtSurfFlatRegion( IdL_Faces, l)
EgtSetAlpha(nIdFace,1)
table.insert( tbId_Faces, nIdFace)
-- coloro il loop e lo esplodo
-- coloro il loop e lo aggiungo alla tabella per ricreare la flat region
EgtSetColor( l, ColorApply)
table.insert(tbLoopFlatRegion, l)
end
-- ricreo la faccia laterale come flat region e la metto con trasparenza massima
local nIdFace = EgtSurfFlatRegion( IdL_Faces, tbLoopFlatRegion)
EgtSetAlpha(nIdFace,1)
table.insert( tbId_Faces, nIdFace)
for l=nLoop, nLoop + (nLoopCount-1), 1 do
-- esplodo i loop
EgtExplodeCurveCompo( l)
end
local nIdCurr = IdS
@@ -810,7 +883,6 @@ end
----------------------------------------------------------------------------
-- funzione che si occupa di creare il solido finale
local function Draw(bPreview)
--ClearAllSOLID()
CreatePartSOLID()
-- SOLID
IdL_OutLoop = GetIdFromLay( tbId_OutLoop, 'OutLoop')
@@ -819,18 +891,6 @@ local function Draw(bPreview)
IdL_Pocket = GetIdFromLay( tbId_Pocket, 'Pocket')
IdL_FiloTop = GetIdFromLay( tbId_FiloTop, 'FiloTop')
-- local nLoop = EgtGetFirstInGroup(IdL_OutLoop)
-- EgtDeselectAll()
-- while nLoop ~= nil do
-- EgtSelectObj(nLoop)
-- nLoop = EgtGetNext( nLoop)
-- end
-- local nOutLoop = EgtCurveCompoByChain(GDB_ID.CL,{GDB_ID.SEL},EgtEP(nLoop),false,GDB_RT.GRID,0.01)
-- --EgtSetGridFrame({{0,20,25},{0,-1,0},{0,0,1},{-1,0,0}}) -- Ok=1
-- EgtSetGridFrame({EgtMP(nOutLoop),EgtSV(nOutLoop),EgtCurveExtrusion(nOutLoop^EgtSV(nOutLoop),EgtCurveExtrusion(nOutLoop)})
-- EgtErase(nOutLoop)
-- SIDEANG
SideAngSolid( tbId_OutLoop, false)
for i = 1, #tbId_InLoop, 1 do
@@ -845,55 +905,62 @@ local function Draw(bPreview)
---- FILO TOP
FiloTopSolid()
-- -- ONPATH
-- OnPathSolid(
OnPathSolid()
-- WIREFRAME
---- Correzione dei riferimenti
CorrectReference()
--ExtractBoundaryAndFaces()
--EgtSetGridFrame({{0,0,0},{1,0,0},{0,1,0},{0,0,1}})
ExtractBoundaryAndFaces()
end
--
----per uso nell' |omagOFFICE|
--function CMP.Main()
-- IdFP = CMP.CurrId
-- ClearCurrIdSOLID()
-- if IdFP == -1 then
-- CMP.ERR = 1
-- return
-- end
-- RTh = CMP.THICK
-- if RTh == 0 then
-- return
-- end
-- Draw( true)
-- EgtSetStatus( IdFP, GDB_ST.OFF)
-- EgtSaveFile('c:\\EgtData\\OmagOFFICE\\Temp\\Ribasso_0.nge')
-- EgtDraw()
-- CMP.ERR = 0
--end
--per uso nell' |omagOFFICE|
function SLD.Main()
IdFP = SLD.CurrId
ClearCurrIdSOLID()
if IdFP == -1 then
SLD.ERR = 1
return
end
RTh = SLD.THICK
if RTh == 0 then
return
end
GetThickness()
Draw( true)
EgtSetStatus( IdFP, GDB_ST.OFF)
EgtDraw()
SLD.ERR = 0
end
--per uso nell' |omagOFFICE|
--per uso nel |CAM5|
ClearCurrIdSOLID()
RTh = 20
IdFP = EgtGetFirstPart()
local sName = ""
--IdFP = 49389
while IdFP ~= nil and sName ~= "SOLID" do
Draw( true)
EgtSetStatus( IdFP, GDB_ST.OFF)
IdFP = EgtGetNextPart(IdFP)
sName = EgtGetName(IdFP)
--break
--per uso nel |CAM5| (bAutoRun da settare a true)
bAutoRun = true -- debug
if bAutoRun then
ClearCurrIdSOLID()
RTh = SLD.THICK
IdFP = EgtGetFirstPart()
local sName = ""
--IdFP = 49389
while IdFP ~= nil and sName ~= "SOLID" do
-- procedo a costruire il solido solo se sono in un part con un OutLoop
local nLay = EgtGetFirstNameInGroup(IdFP, "OutLoop")
if nLay then
GetThickness()
Draw( true)
EgtSetStatus( IdFP, GDB_ST.OFF)
end
IdFP = EgtGetNextPart(IdFP)
sName = EgtGetName(IdFP)
--break
end
--EgtSaveFile('c:\\EgtData\\OmagOFFICE\\Temp\\buche_sottili_SOLID.nge')
EgtDraw()
--SLD.ERR = 0
end
--EgtSaveFile('c:\\EgtData\\OmagOFFICE\\Temp\\buche_sottili_SOLID.nge')
EgtDraw()
----CMP.ERR = 0
--per uso nel |CAM5|
-----per uso nel |CAM5|
--_G.CMP_Main = CMP_Main
--_G.SLD_Main = SLD_Main
+865
View File
@@ -0,0 +1,865 @@
--24/10/09 ASSEMBLER : File per gestire le operazioni su Part nel VeinMatch3D
-- creato da D.B.
-- Intestazioni
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
-- mi preparo a ricevere argomenti
local arg =...
-- variabile globale
-- setto i valori standard nella tabella di comunicazione col programma
local ASS = {}
-- const da settare al caricamento del file
ASS.nMaxStory = 100 -- lunghezza massima della storia
ASS.bActiveHist = false -- flag che indica se attivare il salvataggio delle operazioni ( per poter usare undo e redo)
-- input
ASS.nPartId = GDB_ID.NULL -- part da accoppiare
ASS.nIdFirstLine = GDB_ID.NULL -- edge del part con cui eseguire l'accoppiamento
ASS.nIdSecondLine = GDB_ID.NULL -- edge di destinazione dell'accoppiamento
ASS.nIdAxs = GDB_ID.NULL -- asse con cui eseguire la rotazione( è una CRV_LINE)
ASS.dAng = 0 -- angolo per la rotazione
ASS.vtAx = V_NULL() -- asse di rotazione
ASS.ptAx = ORIG() -- punto per l'asse di rotazione
ASS.vtMove = V_NULL() -- vettore di traslazione
ASS.vtFirstNorm = V_NULL() -- normale della superficie del part da accoppiare
ASS.vtSecondNorm = V_NULL() -- normale di destinazione dell'accoppiamento
ASS.nVeinCtx = GDB_ID.NULL -- indice del contesto del VeinMatch3D
ASS.nOption = 0 -- intero che indica l'opzione di pairing scelta
ASS.nGroup = 0 -- intero che indica il numero del gruppo da aggiornare per il part nPartToPair
ASS.nPartToPair = GDB_ID.NULL -- id del part di cui si vogliono aggiornare le info di pairing
ASS.sPairList = "" -- lista di accoppiamento
ASS.bSaveHist = true -- flag che indica se salvare nella storia l'operazione eseguita
ASS.bSaveTemp = false -- flag che indica se salvare nella storia temporanea l'operazione eseguita
ASS.nTempToSave = GDB_ID.NULL -- posizione nel vettore temporaneo della trasformazione da salvare
ASS.nTypeTrf = GDB_ID.NULL -- tipo della trasformazione da aggiungere alla storia ( 0: traslazione; 1: rotazione; 2: accoppiamento/disaccoppiamento; 3: import)
-- output
ASS.ERR = 0 -- -1 : valori non settati o sbagliati, -2 : operazione impossibile(es: fuori dall'array), -3 : manca qualcosa nel database (info, pezzi, layer..)
ASS.nTransf = 0 -- numero di operazioni eseguite / numero di operazione nella tabella della storia, aggiornato dopo un Undo o un Redo
ASS.sFunc = "" -- funzione in cui è stato eseguito il return a seguito di un errore
ASS.bRedoPossible = false
-- variabili locali
local vPaired = {}
local ptPair = ORIG()
local GroupCounter = 1 -- ogni volta che viene usato va incrementato di 1
local nTernaId = GDB_ID.NULL
local ptOrigId = ORIG()
-- gestione della storia
-- tbEvent = { Id, vtDir, ptAx, dAngOrId, bWPaired, lPair} -- solo move e rotate possono essere effettuati su pezzi singoli, anche se accoppiati
local Time = 0
local tbStory = {}
-- gestione della storia temporanea
local TempTime = 0
local tbTempStory = {}
-- leggo gli argomenti passati dalla chiamata del file
local bAutoRun = false
if arg then
ASS.nVeinCtx = arg.nVeinCtx
bAutoRun = arg.AutoRun
end
-- rendo la variabile globale
_G.ASS = ASS
function ResetASS()
-- input
ASS.nPartId = GDB_ID.NULL
ASS.nIdFirstLine = GDB_ID.NULL
ASS.nIdSecondLine = GDB_ID.NULL
ASS.nIdAxs = GDB_ID.NULL
ASS.dAng = 0
ASS.vtAx = V_NULL()
ASS.ptAx = ORIG()
ASS.vtMove = V_NULL()
ASS.vtFirstNorm = V_NULL()
ASS.vtSecondNorm = V_NULL()
ASS.nVeinCtx = GDB_ID.NULL
ASS.nOption = 0
ASS.nGroup = 0
ASS.nPartToPair = GDB_ID.NULL
ASS.sPairList = ""
ASS.nTempToSave = GDB_ID.NULL
ASS.nTypeTrf = GDB_ID.NULL
-- output
ASS.ERR = GDB_ID.NULL
ASS.nTransf = 0
end
local function FromStringToINTVECTOR( sIntVectorString)
local vInt = {}
local vsInt = EgtSplitString(sIntVectorString,",")
for sInt in vsInt do
table.insert( vInt, EgtEvalNumExpr(sInt))
end
return vInt
end
local function AddEvent( tbEvent)
if not tbEvent.Id then do return end end
-- se ho già raggiunto il massimo della storia salvabile allora elimino il primo elemento
if Time == ASS.nMaxStory then table.remove(tbStory,1) end
-- se ero avevo già fatto degli undo allora devo cancellare la storia che sto per sovrascrivere
if Time < #tbStory then
local nLastEvent = #tbStory
for nItTime = Time, nLastEvent, 1 do
table.remove(tbStory, Time + 1)
end
end
if Time < ASS.nMaxStory then Time = Time + 1 end
table.insert( tbStory, tbEvent)
return true
end
local function AddTempEvent( tbEvent)
-- se ho già raggiunto il massimo della storia salvabile allora elimino il primo elemento
if TempTime == ASS.nMaxStory then table.remove(tbTempStory,1) end
-- se ero avevo già fatto degli undo allora devo cancellare la storia che sto per sovrascrivere
if TempTime < #tbTempStory then
local nLastEvent = #tbTempStory
for nItTime = TempTime, nLastEvent, 1 do
table.remove(tbTempStory, TempTime + 1)
end
end
if TempTime < ASS.nMaxStory then TempTime = TempTime + 1 end
table.insert( tbTempStory, tbEvent)
end
function ASS.AddEvent()
ASS.sFunc = "ASS.AddEvent"
local tbEvent = {}
local a = tbEvent.nId
if ASS.nTypeTrf == 0 then -- traslazione
if ASS.nPartId == GDB_ID.NULL or AreSameVectorApprox(ASS.vtMove, V_NULL()) then
ASS.ERR = -1
return false
end
tbEvent = {Id = ASS.nPartId, vtDir = ASS.vtMove, ptAx = ORIG(), dAngOrId = 0, bWPaired = true, lPair = {}}
elseif ASS.nTypeTrf == 1 then -- rotazione
if ASS.nPartId == GDB_ID.NULL or AreSameVectorApprox(ASS.vtAx, V_NULL()) or ASS.dAng == nil then
ASS.ERR = -1
return false
end
tbEvent = {Id = ASS.nPartId, vtDir = ASS.vtAx, ptAx = ASS.ptAx, dAngOrId = ASS.dAng, bWPaired = true, lPair = {}}
elseif ASS.nTypeTrf == 2 then -- accoppiamento
if ASS.nPartId == GDB_ID.NULL or ASS.nPartToPair == GDB_ID.NULL then
ASS.ERR = -1
return false
end
tbEvent = {Id = ASS.nPartId, vtDir = V_NULL(), ptAx = ORIG(), dAngOrId = ASS.nPartToPair, bWPaired = true, lPair = FromStringToINTVECTOR(ASS.sPairList)}
elseif ASS.nTypeTrf == 3 then -- importazione oggetto
if ASS.nPartId == GDB_ID.NULL then
ASS.ERR = -1
return false
end
tbEvent = {Id = ASS.nPartId, vtDir = V_NULL(), ptAx = ORIG(), dAngOrId = 0, bWPaired = true, lPair = {}}
else
do return false end
end
local bOk = false
if AddEvent( tbEvent) then bOk = true end
ASS.nTransf = Time
return bOk
end
function ASS.AddEventFromTemp()
ASS.sFunc = "AddEventFromTemp"
if abs(ASS.nTempToSave) > #tbTempStory then
ASS.ERR = -2
return false
end
if ASS.nTempToSave < 0 then ASS.nTempToSave = #tbTempStory + 1 + ASS.nTempToSave end
AddEvent( tbTempStory[ASS.nTempToSave])
return true
end
function ASS.ResetStory()
tbStory = {}
Time = 0
return true
end
function ASS.ResetTempStory()
tbTempStory = {}
TempTime = 0
return true
end
local function ApplyTransf( tbEvent, bForward, bSave, bTemp)
-- tbEvent = { nId, vtDir, ptAx, dAngOrId, bWPaired, lPair}
if tbEvent == nil or bForward == nil or bSave == nil or bTemp == nil or
tbEvent.Id == GDB_ID.NULL or tbEvent.Id == nil or tbEvent.vtDir == nil or
tbEvent.ptAx == nil or tbEvent.dAngOrId == nil then
ASS.ERR = -1
return false
end
ASS.bSaveHist = bSave
-- se ho una traslazione o una rotazione applico la trasformazione a tutto l'accoppiato
if not AreSameVectorExact(V_NULL(), tbEvent.vtDir) then
-- se è un undo allora inverto il vettore
if not bForward then tbEvent.vtDir = Vector3d(tbEvent.vtDir) * (-1) end
if tbEvent.dAngOrId == 0 then
ASS.nTypeTrf = 0 -- setto il tipo di trasformazione che sto facendo (in caso serva al chiamante)
ASS.nPartId = tbEvent.Id
ASS.vtMove = tbEvent.vtDir
ASS.bSaveHist = bSave
ASS.bSaveTemp = bTemp
if tbEvent.bWPaired then
ASS.Move()
else
ASS.MoveSingle()
end
elseif not AreSameVectorExact(V_NULL(), tbEvent.vtDir) then
ASS.nTypeTrf = 1 -- setto il tipo di trasformazione che sto facendo (in caso serva al chiamante)
ASS.nPartId = tbEvent.Id
ASS.vtAx = tbEvent.vtDir
ASS.ptAx = tbEvent.ptAx
ASS.dAng = tbEvent.dAngOrId
ASS.bSaveHist = bSave
ASS.bSaveTemp = bTemp
if tbEvent.bWPaired then
ASS.Rotate()
else
ASS.RotateSingle()
end
end
elseif tbEvent.dAngOrId == 0 then
ASS.nTypeTrf = 3 -- setto il tipo di trasformazione che sto facendo (in caso serva al chiamante)
-- se non sono definiti né l'asse né l'angolo/id di accoppiamento allora è un import
if not bForward then
-- se sto facendo un undo allora elimino il part e il SOLID importati
local nChild = EgtGetInfo(tbEvent.Id, "Child", "i")
EgtErase(nChild)
EgtErase(tbEvent.Id)
end
-- se sto facendo un redo, non faccio nulla
elseif bForward then
ASS.nTypeTrf = 2 -- setto il tipo di trasformazione che sto facendo (in caso serva al chiamante)
-- sto applicando un accoppiamento
-- aggiorno le info dei due part e di tutti i loro associati
ASS.nPartId = tbEvent.Id
ASS.nPartToPair = tbEvent.dAngOrId
if not ASS.UpdatePairInfo() then return false end
else
ASS.nTypeTrf = 2 -- setto il tipo di trasformazione che sto facendo (in caso serva al chiamante)
-- sto applicando un disaccoppiamento
if #tbEvent.lPair == 1 then
ASS.nPartId = tbEvent.dAngOrId
if not ASS.Unpair() then ASS.ERR = -2 return false end
else
-- alla lista dei paired del part selezionato per essere accoppiato tolgo tutti i part che ho aggiunto( part destinatario e suoi eventuali accoppiati)
for n, nIdToUnpair in pairs(tbEvent.lPair) do
-- rimuovo anche le info
ASS.nPartId = tbEvent.Id
ASS.nPartToPair = nIdToUnpair
if not ASS.RemovePairInfo() then return false end
end
local sPairedNew1 = EgtGetInfo( tbEvent.Id, "Paired", "s")
local lPairNew1 = EgtGetInfo(tbEvent.Id, "Paired", "vi")
if lPairNew1 == nil or sPairedNew1 == nil then ASS.ERR = -3 return false end
-- copio la nuova lista dei paired in tutti gli altri paired
for n, nIdPaired in pairs(lPairNew1) do
ASS.nPartId = nIdPaired
ASS.sPairList = sPairedNew1
ASS.nGroup = -1
ASS.UpdatePairInfoSingle()
end
-- se il part corrente era già accoppiato con altri pezzi allora lascio a quell'accoppiato il numero del gruppo che sto spezzando
-- e darò un nuovo numero al destinatario e al suo accoppiato
local bCurrWasSingle = false
if #lPairNew1 == 1 then
bCurrWasSingle = true
ASS.sPairList = sPairedNew1
ASS.nGroup = 0
ASS.UpdatePairInfoSingle()
end
-- alla lista del part destinatario dell'accoppiamento tolgo tutti i part che gli ho aggiunto
for n, nIdPaired in pairs(lPairNew1) do
ASS.nPartId = tbEvent.dAngOrId
ASS.nPartToPair = nIdPaired
if not ASS.RemovePairInfo() then return false end
end
-- assegno un nuovo numero di gruppo al gruppo che ho creato
local sPairedNew2 = EgtGetInfo( tbEvent.dAngOrId, "Paired", "s")
local lPairNew2 = EgtGetInfo( tbEvent.dAngOrId, "Paired", "vi")
local nGroupCode = -1
-- se il curr era single allora mantengo il numero di gruppo per l'assemblato del destinatario
if not bCurrWasSingle then
-- il curr non era single, quindi a lui resta il numero di gruppo
if #lPairNew2 > 1 then
-- anche il destinatario non era single, quindi serve un nuovo numero di gruppo
nGroupCode = GroupCounter
GroupCounter = GroupCounter + 1
else
-- il destinatario era single, quindi rimetto semplicemente a 0 il numero di gruppo
nGroupCode = 0
end
end
-- aggiorno la lista dei part che erano già paired con il part selezionato
for n, nIdPaired in pairs(lPairNew2) do
ASS.nPartId = nIdPaired
ASS.sPairList = sPairedNew2
ASS.nGroup = nGroupCode
ASS.UpdatePairInfoSingle()
end
end
end
return true
end
function ASS.Undo()
ASS.sFunc = "ASS.Undo"
if Time == 0 then do return end end
if Time > #tbStory then Time = #tbStory end
ApplyTransf(tbStory[Time], false, false, false)
Time = Time - 1
ASS.nTransf = Time
ASS.bRedoPossible = true
return true
end
function ASS.Redo()
ASS.sFunc = "ASS.Redo"
if Time >= #tbStory then ASS.bRedoPossible = false return false end
if Time == ASS.nMaxStory then ASS.bRedoPossible = false return false end
ApplyTransf(tbStory[Time + 1], true, false, false)
Time = Time + 1
ASS.nTransf = Time
if Time >= #tbStory then ASS.bRedoPossible = false end
if Time == ASS.nMaxStory then ASS.bRedoPossible = false end
return true
end
function ASS.UndoTemp()
ASS.sFunc = "ASS.UndoTemp"
if TempTime == 0 then do return end end
if TempTime > ASS.nMaxStory then TempTime = ASS.nMaxStory end
ApplyTransf(tbTempStory[TempTime], false, false, false)
TempTime = TempTime - 1
end
function ASS.RedoTemp()
ASS.sFunc = "ASS.RedoTemp"
if TempTime >= #tbTempStory then do return end end
if TempTime == ASS.nMaxStory then do return end end
ApplyTransf(tbTempStory[TempTime + 1], true, false, false)
TempTime = TempTime + 1
end
local function RetrieveSurfNorm( nPartId)
-- recupero la normale della faccia principale del Part a partire dall'id del Part
local nLayR = EgtGetFirstNameInGroup( nPartId, "Region")
local nId = EgtGetFirstInGroup(nLayR)
local nSurfId = GDB_ID.NULL
while nId ~= GDB_ID.NULL do
if EgtGetType( nId) == GDB_TY.SRF_FRGN then
nSurfId = nId
break
end
nId = EgtGetNext(nId)
end
local vtNorm = EgtSurfFrNormVersor(nSurfId, GDB_RT.GLOB)
return vtNorm
end
local function RetrieveParent( nId)
-- recupero il parent dell'oggetto nId
-- se è un oggetto all'interno contenuto in un Part che si chiama SOLID allora recupero il Part
nId = EgtGetParent(EgtGetParent(nId))
local sName = ""
sName = EgtGetName(nId, "s")
if sName == "SOLID" then
nId = EgtGetInfo(nId, "Parent","i")
end
return nId
end
local function RetrievePart( nId)
local sName = EgtGetName(nId)
local nParent = nId
if sName == "SOLID" then
nParent = EgtGetInfo(nId, "Parent","i")
end
return nParent
end
local function RetrievePaired()
vPaired = EgtGetInfo( RetrievePart(ASS.nPartId), "Paired", "vi")
if vPaired == nil then ASS.ERR = -3 return false end
return true
end
local function RetrieveLocAxis()
-- recupero l'id della terna, se esiste
nTernaId = GDB_ID.NULL
nTernaId = EgtGetInfo( ASS.nPartId, "Terna", "i")
if not nTernaId then
return false
else
return true
end
end
local function RetrieveLocOrig()
-- recupero l'origine della terna
if nTernaId == GDB_ID.NULL then do return end end
local LayOrig = EgtGetFirstNameInGroup(nTernaId, "ORIG")
ptOrigId = EgtGetFirstNameInGroup(LayOrig, "ORIG")
end
function ASS.Move()
ASS.sFunc = "ASS.Move"
if AreSameVectorApprox(ASS.vtMove, V_NULL()) then return true end
if ASS.nPartId == nil or ASS.nPartId == GDB_ID.NULL or ASS.vtMove == nil then ASS.ERR = -1 return false end
-- recupero la lista degli accoppiati
if not RetrievePaired() then return false end
if RetrieveLocAxis() then
EgtMove(nTernaId, ASS.vtMove, GDB_RT.GLOB)
end
-- muovo il pezzo e tutti i suoi accoppiati
for n, nId in pairs(vPaired) do
EgtMove( nId, ASS.vtMove, GDB_RT.GLOB)
local nChild = EgtGetInfo( nId, "Child", "i")
EgtMove( nChild, ASS.vtMove, GDB_RT.GLOB)
end
-- se richiesto salvo la storia
if ASS.bActiveHist then
local tbEv = {Id = ASS.nPartId, vtDir = ASS.vtMove, ptAx = ORIG(), dAngOrId = 0, bWPaired = true, lPair = {}}
if ASS.bSaveHist then AddEvent( tbEv) end
if ASS.bSaveTemp then AddTempEvent( tbEv) end
end
return true
end
function ASS.MoveSingle()
ASS.sFunc = "ASS.MoveSingle"
if AreSameVectorApprox(ASS.vtMove, V_NULL()) then return true end
if ASS.nPartId == nil or ASS.nPartId == GDB_ID.NULL or ASS.vtMove == nil then ASS.ERR = -1 return false end
-- muovo il pezzo MA NON i suoi accoppiati
EgtMove( ASS.nPartId, ASS.vtMove, GDB_RT.GLOB)
local nChild = EgtGetInfo( ASS.nPartId, "Child", "i")
EgtMove( nChild, ASS.vtMove, GDB_RT.GLOB)
if RetrieveLocAxis() then
EgtMove(nTernaId, ASS.vtMove, GDB_RT.GLOB)
end
-- se richiesto salvo la storia
if ASS.bActiveHist then
local tbEv = {Id = ASS.nPartId, vtDir = ASS.vtMove, ptAx = ORIG(), dAngOrId = 0, bWPaired = false, lPair = {}}
if ASS.bSaveHist then AddEvent( tbEv) end
if ASS.bSaveTemp then AddTempEvent( tbEv) end
end
return true
end
function ASS.Rotate()
ASS.sFunc = "ASS.Rotate"
if ASS.dAng == 0 then return true end
if ASS.nPartId == nil or ASS.nPartId == GDB_ID.NULL or ASS.ptAx == nil or
AreSameVectorApprox( ASS.vtAx, V_NULL()) then ASS.ERR = -1 return false end
-- recupero la lista degli accoppiati
if not RetrievePaired() then return false end
if RetrieveLocAxis() then
RetrieveLocOrig()
-- muovo la terna
local ptBefore = EgtSP(ptOrigId, GDB_RT.GLOB)
local ptAfterId = EgtCopyGlob(ptOrigId, nTernaId)
EgtRotate( ptAfterId, ASS.ptAx, ASS.vtAx, ASS.dAng, GDB_RT.GLOB, GDB_RT.GLOB)
local vtMove = Point3d(EgtSP( ptAfterId, GDB_RT.GLOB)) - Point3d(ptBefore)
EgtMove( nTernaId, vtMove, GDB_RT.GLOB)
EgtErase(ptAfterId)
end
-- ruoto il pezzo e tutti i suoi accoppiati
for n, nId in pairs(vPaired) do
EgtRotate( nId, ASS.ptAx, ASS.vtAx, ASS.dAng, GDB_RT.GLOB)
local nChild = EgtGetInfo( nId, "Child","i")
EgtRotate( nChild, ASS.ptAx, ASS.vtAx, ASS.dAng, GDB_RT.GLOB)
end
-- se richiesto salvo la storia
if ASS.bActiveHist then
local tbEv = {Id = ASS.nPartId, vtDir = ASS.vtAx, ptAx = ASS.ptAx, dAngOrId = ASS.dAng, bWPaired = true, lPair = {}}
if ASS.bSaveHist then AddEvent( tbEv) end
if ASS.bSaveTemp then AddTempEvent( tbEv) end
end
return true
end
function ASS.RotateSingle()
ASS.sFunc = "ASS.RotateSingle"
if ASS.dAng == 0 then return true end
if RetrieveLocAxis() then
RetrieveLocOrig()
-- muovo la terna
local ptBefore = EgtSP(ptOrigId, GDB_RT.GLOB)
local ptAfterId = EgtCopy(ptOrigId, nTernaId)
EgtRotate( ptAfterId, ASS.ptAx, ASS.vtAx, ASS.dAng, GDB_RT.GLOB)
local vtMove = Point3d(EgtSP( ptAfterId, GDB_RT.GLOB)) - Point3d(ptBefore)
EgtMove( nTernaId, vtMove, GDB_RT.GLOB)
EgtErase(ptAfterId)
end
-- ruoto il pezzo MA NON i suoi accoppiati
EgtRotate( ASS.nPartId, ASS.ptAx, ASS.vtAx, ASS.dAng, GDB_RT.GLOB)
local nChild = EgtGetInfo( ASS.nPartId, "Child","i")
EgtRotate( nChild, ASS.ptAx, ASS.vtAx, ASS.dAng, GDB_RT.GLOB)
-- se richiesto salvo la storia
if ASS.bActiveHist then
local tbEv = {Id = ASS.nPartId, vtDir = ASS.vtMove, ptAx = ASS.ptAx, dAngOrId = ASS.dAng, bWPaired = false, lPair = {}}
if ASS.bSaveHist then AddEvent( tbEv) end
if ASS.bSaveTemp then AddTempEvent( tbEv) end
end
return true
end
function ASS.FlipParallel()
ASS.sFunc = "ASS.FlipParallel"
local vtNorm = V_NULL()
-- recupero la normale della superficie originale
vtNorm = RetrieveSurfNorm( RetrievePart(ASS.nPartId))
if vtNorm == nil or AreSameVectorApprox(vtNorm, V_NULL()) then ASS.ERR = -3 return false end
ASS.ptAx = ptPair
ASS.vtAx = vtNorm
ASS.dAng = 180
if not ASS.Rotate() or not ASS.EdgePair() then return false end
return true
end
function ASS.FlipPerpendicular()
ASS.sFunc = "ASS.FlipPerpendicular"
-- recupero la normale della faccia principale del part del secondo part
local vtNorm = V_NULL()
vtNorm = RetrieveSurfNorm( RetrieveParent(ASS.nIdSecondLine))
if vtNorm == nil or AreSameVectorApprox(vtNorm, V_NULL()) then ASS.ERR = -3 return false end
local vtStartDir = EgtSV(ASS.nIdSecondLine, GDB_RT.GLOB)
local vtAx = vtNorm ^ vtStartDir
if vtAx == nil or AreSameVectorApprox(vtAx, V_NULL()) then ASS.ERR = -2 return false end
-- recupero il punto usato per l'accoppiamento
if ptPair == nil then ASS.ERR = -2 return false end
ASS.ptAx = ptPair
ASS.vtAx = vtAx
ASS.dAng = 180
if not ASS.Rotate() or not ASS.EdgePair() then return false end
return true
end
function ASS.FacePair()
ASS.sFunc = "ASS.FacePair"
-- setto e controllo
EgtSetContext(ASS.nVeinCtx)
if ASS.nPartId == GDB_ID.NULL then ASS.ERR = -1 return false end
if ASS.nIdSecondLine == GDB_ID.NULL then ASS.ERR = -1 return false end
-- recupero gli id dei Part
local nIdToPair = RetrieveParent(ASS.nIdSecondLine)
ASS.nPartId = RetrievePart(ASS.nPartId)
local ptAx = EgtSP(ASS.nIdSecondLine, GDB_RT.GLOB)
local vtAx = Vector3d(EgtSV(ASS.nIdSecondLine, GDB_RT.GLOB))
local vtNorm1 = Vector3d(ASS.vtFirstNorm):isZero() and Vector3d(RetrieveSurfNorm(ASS.nPartId)) or Vector3d(ASS.vtFirstNorm)
local vtNorm2 = Vector3d(ASS.vtSecondNorm):isZero() and Vector3d(RetrieveSurfNorm( nIdToPair)) or Vector3d(ASS.vtSecondNorm)
local dAng = GetAngle( vtNorm1, vtNorm2)
local vtCopy = Vector3d(vtNorm1)
vtCopy:rotate(vtAx, 180 - dAng)
vtCopy = vtCopy * (GDB_ID.NULL)
ASS.ptAx = ptAx
ASS.vtAx = vtAx
if AreSameVectorApprox(vtNorm2, vtCopy) then
ASS.dAng = 180 - dAng
if not ASS.Rotate() then return false end
else
ASS.dAng = -(180 - dAng)
if not ASS.Rotate() then return false end
end
return true
end
function ASS.EdgePair()
ASS.sFunc = "ASS.EdgePair"
-- setto e faccio i controlli
-- resetto il conto di operazioni fatto
ASS.nTransf = 1
EgtSetContext(ASS.nVeinCtx)
if ASS.nPartId == GDB_ID.NULL then ASS.ERR = -1 return false end
if ASS.nIdFirstLine == GDB_ID.NULL then ASS.ERR = -1 return false end
if ASS.nIdSecondLine == GDB_ID.NULL then ASS.ERR = -1 return false end
-- controllo che i due part non siano già accoppiati
-- recupero l'id del secondo part
local nIdToPair = RetrieveParent(ASS.nIdSecondLine)
if nIdToPair == GDB_ID.NULL then ASS.ERR = -1 return false end
ASS.nPartId = RetrievePart(ASS.nPartId)
if ASS.nPartId == GDB_ID.NULL then ASS.ERR = -1 return false end
-- verifico che i due part non siano già accoppiati
local nGroup1 = 0
local nGroup2 = 0
nGroup1 = EgtGetInfo( ASS.nPartId, "GroupCode","i") or 0
nGroup2 = EgtGetInfo( nIdToPair, "GroupCode","i") or 0
if nGroup1 == nGroup2 and nGroup1 ~= 0 then return true end
-- se i due part non erano già associati allora procedo con l'accoppiamento
-- first line
local ptStartF, ptEndF, ptMidF, vtDirF
ptStartF = EgtSP(ASS.nIdFirstLine, GDB_RT.GLOB)
ptEndF = EgtEP(ASS.nIdFirstLine, GDB_RT.GLOB)
ptMidF = EgtMP(ASS.nIdFirstLine, GDB_RT.GLOB)
vtDirF = EgtSV(ASS.nIdFirstLine, GDB_RT.GLOB)
-- second line
local ptStartS, ptEndS, ptMidS, vtDirS
ptStartS = EgtSP(ASS.nIdSecondLine, GDB_RT.GLOB)
ptEndS = EgtEP(ASS.nIdSecondLine, GDB_RT.GLOB)
ptMidS = EgtMP(ASS.nIdSecondLine, GDB_RT.GLOB)
vtDirS = EgtSV(ASS.nIdSecondLine, GDB_RT.GLOB)
local ptIni, ptFin
if ASS.nOption == 0 then
-- Start-Start
ptIni = ptStartF
ptFin = ptStartS
elseif ASS.nOption == 1 then
-- Start-End
ptIni = ptStartF
ptFin = ptEndS
elseif ASS.nOption == 2 then
-- End-Start
ptIni = ptEndF
ptFin = ptStartS
elseif ASS.nOption == 3 then
-- End-End
ptIni = ptEndF
ptFin = ptEndS
elseif ASS.nOption == 4 then
-- Mid-Mid
ptIni = ptMidF
ptFin = ptMidS
end
ptPair = ptFin
-- calcolo il vettore movimento e sposto solid e part
ASS.vtMove = ptFin - ptIni
local dAng = GetAngle(vtDirF, vtDirS)
if not ASS.Move() then return false end
local dTol = 0.001
if dAng < dTol or abs(dAng - 180) < dTol or abs(dAng - 360) < dTol then
--EgtDraw()
return true
end
ASS.nTransf = 2
-- ruoto il solid che sto spostando
local vtAx = Vector3d( vtDirF ^ vtDirS)
ASS.dAng = dAng
ASS.ptAx = ptFin
ASS.vtAx = vtAx
if not ASS.Rotate() then return false end
--EgtDraw()
return true
end
function ASS.Unpair()
ASS.sFunc = "ASS.Unpair"
if ASS.nPartId == nil or ASS.nPartId == GDB_ID.NULL then ASS.ERR = -1 return false end
-- rimuovo le info dal PartCurr e da tutti i suoi Pair
ASS.nPartToPair = ASS.nPartId
if not ASS.RemovePairInfo() then return false end
local nPartCurr = ASS.nPartId
if not RetrievePaired() then return false end
local sPaired = EgtGetInfo(ASS.nPartId, "Paired")
if sPaired == nil then ASS.ERR = -3 return false end
for n, nId in pairs(vPaired) do
ASS.nPartId = nId
ASS.sPairList = sPaired
ASS.nGroup = #vPaired > 1 and GDB_ID.NULL or 0
if not ASS.UpdatePairInfoSingle() then return false end
end
-- resetto le info di pairing del part corrente
ASS.nPartId = nPartCurr
ASS.sPairList = EgtNumToString(nPartCurr)
ASS.nGroup = 0
if not ASS.UpdatePairInfoSingle() then return false end
return true
end
function ASS.RemovePairInfo() --nId As Integer, nIdToUnpair As Integer
-- al part nId tolgo l'accoppiamento con nIdToUnpair
ASS.sFunc = "ASS.RemovePairInfo"
--aggiorno le info
local sPair = EgtGetInfo(ASS.nPartId, "Paired", sPair)
local vsPaired = EgtSplitString(sPair, ",")
local sIdToUnpair = EgtNumToString(ASS.nPartToPair)
if sIdToUnpair == nil or sIdToUnpair == "" or vsPaired == nil or sPair == nil then ASS.ERR = -3 return false end
-- ricostruisco l'informazione paired senza l'Id che ho disaccoppiato
local sNewPaired = ""
for s, sIdPaired in pairs(vsPaired) do
if sIdPaired ~= sIdToUnpair then
if sNewPaired ~= "" then
sNewPaired = sNewPaired .. "," .. sIdPaired
else
sNewPaired = sIdPaired
end
end
end
-- aggiorno le info
local nGroup = #vsPaired > 2 and GDB_ID.NULL or 0
ASS.sPairList = sNewPaired
ASS.nGroup = nGroup
if not ASS.UpdatePairInfoSingle() then return false end
return true
end
function ASS.UpdatePairInfoSingle()
ASS.sFunc = "ASS.UpdatePairInfoSingle"
if ASS.sPairList == nil or ASS.sPairList == "" or ASS.nGroup == nil then ASS.ERR = -1 return false end
EgtSetInfo(ASS.nPartId, "Paired", ASS.sPairList)
if ASS.nGroup ~= GDB_ID.NULL then
EgtSetInfo(ASS.nPartId, "GroupCode", ASS.nGroup)
end
return true
end
function ASS.UpdatePairInfo()
ASS.sFunc = "ASS.UpdatePairInfo"
local nId1 = RetrievePart(ASS.nPartId)
if nId1 == nil or nId1 == GDB_ID.NULL then ASS.ERR = -1 return false end
ASS.nPartId = nId1
-- il secondo id lo recupero dal parent del secondo edge, se presente, altrimenti da nPartToPair
local nId2 = GDB_ID.NULL
if ASS.nIdSecondLine ~= GDB_ID.NULL then
nId2 = RetrieveParent(ASS.nIdSecondLine)
else
nId2 = RetrievePart(ASS.nPartToPair)
end
if nId1 == nil or nId1 == GDB_ID.NULL then ASS.ERR = -1 return false end
ASS.nPartToPair = nId2
-- salvo la lista degli attuali accoppiati del part destinatario dell'accoppiamento
local lPairList = EgtGetInfo( ASS.nPartToPair,"Paired", "vi")
if lPairList == nil then ASS.ERR = -3 return false end
-- verifico se uno o entrambi dei due part sono già in un gruppo
local sPaired1 = ""
sPaired1 = EgtGetInfo(nId1, "Paired")
if sPaired1 == nil then ASS.ERR = -3 return false end
local sPaired2 = ""
sPaired2 = EgtGetInfo(nId2, "Paired")
if sPaired2 == nil then ASS.ERR = -3 return false end
local nGroup = 0
-- se nessuno dei due era in un gruppo creo un nuovo gruppo con questi due part
if sPaired1 == EgtNumToString(nId1) and sPaired2 == EgtNumToString(nId2) then
sPaired1 = sPaired1 .. "," .. sPaired2
nGroup = EgtGetInfo(nId1, "GroupCode","i")
-- se solo il secondo era in un gruppo, al secondo copio gli id del gruppo
elseif sPaired1 == EgtNumToString(nId1) and sPaired2 ~= EgtNumToString(nId2) then
sPaired2 = sPaired2 .. "," .. EgtNumToString(nId1)
sPaired1 = sPaired2
nGroup = EgtGetInfo(nId2, "GroupCode","i")
-- se solo il primo era in un gruppo, al secondo copio gli id del gruppo
elseif sPaired1 ~= EgtNumToString(nId1) and sPaired2 == EgtNumToString(nId2) then
sPaired1 = sPaired1 .. "," .. EgtNumToString(nId2)
nGroup = EgtGetInfo(nId1, "GroupCode","i")
-- se entrambi erano in un gruppo faccio il merge
elseif sPaired1 ~= EgtNumToString(nId1) and sPaired2 ~= EgtNumToString(nId2) then
sPaired1 = sPaired1 .. "," .. sPaired2
local nGroup1 = EgtGetInfo(nId1, "GroupCode","i")
local nGroup2 = EgtGetInfo(nId2, "GroupCode","i")
nGroup = nGroup1 < nGroup2 and nGroup1 or nGroup2
end
if nGroup == 0 or nGroup == nil then
nGroup = GroupCounter
GroupCounter = GroupCounter + 1
end
-- scorro tutti i part associati e aggiorno le loro info
local vPaired_s = EgtSplitString(sPaired1) -- qua devo fare uno split sulle virgole
ASS.sPairList = sPaired1
ASS.nGroup = nGroup
local nPartCurr = ASS.nPartId
for n, sId in pairs(vPaired_s) do
local nId = EgtEvalNumExpr(sId)
ASS.nPartId = nId
if not ASS.UpdatePairInfoSingle() then return false end
end
if ASS.bActiveHist then
ASS.nPartId = nPartCurr
local tbEv = {Id = ASS.nPartId, vtDir = V_NULL(), ptAx = ORIG(), dAngOrId = ASS.nPartToPair, bWPaired = true, lPair = lPairList}
if ASS.bSaveHist then AddEvent( tbEv) end
if ASS.bSaveTemp then AddTempEvent( tbEv) end
end
return true
end
function ASS.PairAll()
ASS.sFunc = "ASS.PairAll"
local nTrasfTot = 0
EgtSetContext(ASS.nVeinCtx)
local nPart = EgtGetFirstPart()
if nPart == nil or nPart == GDB_ID.NULL then ASS.ERR = -3 return false end
while nPart do
local sLineToPair = EgtGetInfo(nPart, "PairToRef")
local sMyLineToPairName = EgtGetInfo( nPart, "PairMyRef")
if sLineToPair then
-- recupero l'id del lato da accoppiare
local sLayName = "Ref"
local nLayRef = EgtGetFirstNameInGroup(nPart, sLayName)
local nMyLineToPair = EgtGetFirstNameInGroup(nLayRef, sMyLineToPairName)
if nMyLineToPair == nil or nMyLineToPair == GDB_ID.NULL then ASS.ERR = -3 return false end
-- spezzo l'informazione per risalire al lato di destionazione dell'accoppiamento
local vToInfo = EgtSplitString(sLineToPair, "_")
local sLineToPairName = vToInfo[3]
local sPartName = vToInfo[1].."_"..vToInfo[2]
local nPartToPair = EgtGetFirstNameInGroup(GDB_ID.ROOT, sPartName)
local nLay = EgtGetFirstNameInGroup(nPartToPair, sLayName)
local nLineToPair = EgtGetFirstNameInGroup(nLay, sLineToPairName)
if nLineToPair == nil or nLineToPair == GDB_ID.NULL then ASS.ERR = -3 return false end
local nSpin = EgtGetInfo(nPart, "PairSpin", "i")
ASS.nPartId = nPart
ASS.nIdFirstLine = nMyLineToPair
ASS.nIdSecondLine = nLineToPair
-- controllo se è settata la modalità di accoppiamento sennò lascio il default middle-middle
local nOption = EgtGetInfo(nPart, "PairMode", "i")
ASS.nOption = nOption and nOption or 4
if not ASS.EdgePair() then return false end
nTrasfTot = ASS.nTransf
-- verifico che lo spin sia rispettato
local vtEdge1 = EgtSV( ASS.nIdFirstLine, GDB_RT.GLOB)
local vtEdge2 = EgtSV( ASS.nIdSecondLine, GDB_RT.GLOB)
if AreSameVectorApprox( vtEdge1, vtEdge2) and nSpin == -1 then
if not ASS.FlipParallel() then return false end
end
-- recupero l'angolo che deve esserci tra le due facce dei part alla fine dell'accoppiamento
local nAngGoal = EgtGetInfo(nPart, "PairAng", "i")
-- calcolo l'angolo attuale tra le due normali e quindi la rotazione che devo applicare per differenza
local vtSurf1 = RetrieveSurfNorm(nPart)
local vtSurf2 = RetrieveSurfNorm(RetrieveParent(ASS.nIdSecondLine))
if vtSurf1 == nil or AreSameVectorApprox( vtSurf1, V_NULL()) or vtSurf2 == nil or AreSameVectorApprox( vtSurf2, V_NULL()) then ASS.ERR = -3 return false end
ASS.vtAx = EgtSV(ASS.nIdSecondLine, GDB_RT.GLOB)
if ASS.vtAx == nil or AreSameVectorApprox(ASS.vtAx, V_NULL()) then ASS.ERR = -1 return false end
local dAngCurr = GetRotation(vtSurf1, vtSurf2, ASS.vtAx)
ASS.dAng = dAngCurr - nAngGoal
ASS.ptAx = EgtSP(ASS.nIdSecondLine, GDB_RT.GLOB)
if not ASS.Rotate() then return false end
nTrasfTot = nTrasfTot + 1
-- aggiorno le info di accoppiamento
ASS.nPartToPair = nPartToPair
if not ASS.UpdatePairInfo() then return false end
nTrasfTot = nTrasfTot + 1
end
nPart = EgtGetNext(nPart)
end
ASS.nTransf = nTrasfTot
return true
end
------ per funzionare con il require
--return ASS
------ per funzionare con il require
------ per funzionare nel CAM5
-- ASS.nVeinCtx = 1
-- ASS.PairAll()
-- EgtDraw()
------ per funzionare nel CAM5
---
if bAutoRun then
ASS.PairAll()
end