Files
StoneSolidGen/OperationOnSolid.lua
T
Daniele Bariletti 6370198a0c - aggiunta la funzione per l'accoppiamento automatico
- piccole correzioni e migliorie.
2024-11-12 17:10:22 +01:00

727 lines
26 KiB
Lua

--24/10/09 ASSEMBLER : File per gestire le operazioni su Part nel VeinMatch3D
-- creato da D.B.
-- Intestazioni
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
-- 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
-- output
ASS.ERR = GDB_ID.NULL
ASS.nTransf = 0 -- numero di operazioni eseguite
-- 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 = {}
-- 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)
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()
local tbEvent = {}
local a = tbEvent.nId
if ASS.nTypeTrf == 0 then -- traslazione
tbEvent = {Id = ASS.nPartId, vtDir = ASS.vtMove, ptAx = ORIG(), dAngOrId = 0, bWPaired = true, lPair = {}}
elseif ASS.nTypeTrf == 1 then -- rotazione
tbEvent = {Id = ASS.nPartId, vtDir = ASS.vtAx, ptAx = ASS.ptAx, dAngOrId = ASS.dAng, bWPaired = true, lPair = {}}
elseif ASS.nTypeTrf == 2 then -- accoppiamento
tbEvent = {Id = ASS.nPartId, vtDir = V_NULL(), ptAx = ORIG(), dAngOrId = ASS.nPartToPair, bWPaired = true, lPair = FromStringToINTVECTOR(ASS.sPairList)}
else
do return end
end
AddEvent( tbEvent)
end
function ASS.AddEventFromTemp()
if abs(ASS.nTempToSave) > #tbTempStory then do return end end
if ASS.nTempToSave < 0 then ASS.nTempToSave = #tbTempStory + 1 + ASS.nTempToSave end
AddEvent( tbTempStory[ASS.nTempToSave])
end
function ASS.ResetStory()
tbStory = {}
Time = 0
end
function ASS.ResetTempStory()
tbTempStory = {}
TempTime = 0
end
local function ApplyTransf( tbEvent, bForward, bSave, bTemp)
-- tbEvent = { Id, vtDir, ptAx, dAngOrId, bWPaired, lPair}
ASS.bSaveHist = bSave
-- se ho una traslazione o una rotazione applico la trasformazione a tutto l'accoppiato
if tbEvent.dAngOrId == 0 or 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.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.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 bForward then
-- sto applicando un accoppiamento
-- aggiorno le info dei due part e di tutti i loro associati
ASS.nPartId = tbEvent.Id
ASS.nPartToPair = tbEvent.dAngOrId
ASS.UpdatePairInfo()
else
-- sto applicando un disaccoppiamento
if #tbEvent.lPair == 1 then
ASS.nPartId = tbEvent.dAngOrId
ASS.Unpair()
else
-- alla lista 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
RemovePairInfo(tbEvent.Id, nIdToUnpair)
end
local sPairedNew1 = EgtGetInfo( tbEvent.Id, "Paired", "s")
local lPairNew1 = EgtGetInfo(tbEvent.Id, "Paired", "vi")
-- copio la nuova lista dei paired in tutti gli altri paired
for n, nIdPaired in pairs(lPairNew1) do
EgtSetInfo(nIdPaired, "Paired", sPairedNew1)
end
-- alla lista del part destinatario dell'accoppiamento tolgo tutti i part che gli ho aggiunto
for n, nIdPaired in pairs(lPairNew1) do
RemovePairInfo(tbEvent.dAngOrId, nIdPaired)
end
-- assegno un nuovo numero di gruppo al gruppo che ho creato
local nGroupCode = GroupCounter
GroupCounter = GroupCounter + 1
local sPairedNew2 = EgtGetInfo( tbEvent.dAngOrId, "Paired", "s")
local lPairNew2 = EgtGetInfo( tbEvent.dAngOrId, "Paired", "vi")
-- aggiorno la lista dei part che erano già paired con il part selezionato
for n, nIdPaired in pairs(lPairNew2) do
EgtSetInfo(nIdPaired, "Paired", sPairedNew2)
EgtSetInfo(nIdPaired, "GroupCode", nGroupCode)
end
end
end
end
function 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
end
function ASS.Redo()
if Time >= #tbStory then do return end end
if Time == ASS.nMaxStory then do return end end
ApplyTransf(tbStory[Time + 1], true, false, false)
Time = Time + 1
end
function 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()
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")
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()
-- recupero la lista degli accoppiati
RetrievePaired()
if RetrieveLocAxis() then
EgtMove(nTernaId, ASS.vtMove)
end
-- muovo il pezzo e tutti i suoi accoppiati
for n, nId in pairs(vPaired) do
EgtMove( nId, ASS.vtMove)
local nChild = EgtGetInfo( nId, "Child", "i")
EgtMove( nChild, ASS.vtMove)
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()
-- muovo il pezzo MA NON i suoi accoppiati
EgtMove( ASS.nPartId, ASS.vtMove)
local nChild = EgtGetInfo( ASS.nPartId, "Child", "i")
EgtMove( nChild, ASS.vtMove)
if RetrieveLocAxis() then
EgtMove(nTernaId, ASS.vtMove)
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()
-- recupero la lista degli accoppiati
RetrievePaired()
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)
local vtMove = Point3d(EgtSP( ptAfterId, GDB_RT.GLOB)) - Point3d(ptBefore)
EgtMove( nTernaId, vtMove)
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)
local nChild = EgtGetInfo( nId, "Child","i")
EgtRotate( nChild, ASS.ptAx, ASS.vtAx, ASS.dAng)
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()
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)
local vtMove = Point3d(EgtSP( ptAfterId, GDB_RT.GLOB)) - Point3d(ptBefore)
EgtMove( nTernaId, vtMove)
EgtErase(ptAfterId)
end
-- ruoto il pezzo MA NON i suoi accoppiati
EgtRotate( ASS.nPartId, ASS.ptAx, ASS.vtAx, ASS.dAng)
local nChild = EgtGetInfo( ASS.nPartId, "Child","i")
EgtRotate( nChild, ASS.ptAx, ASS.vtAx, ASS.dAng)
-- 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()
local vtNorm = V_NULL()
-- recupero la normale della superficie originale
vtNorm = RetrieveSurfNorm( RetrievePart(ASS.nPartId))
local ptMid
--ptMid = EgtMP(ASS.nIdFirstLine, GDB_RT.GLOB)
--ASS.ptAx = ptMid
ASS.ptAx = ptPair
ASS.vtAx = vtNorm
ASS.dAng = 180
ASS.Rotate()
ASS.EdgePair()
return true
end
function ASS.FlipPerpendicular()
-- recupero la normale della faccia principale del part del secondo part
local vtNorm = V_NULL()
vtNorm = RetrieveSurfNorm( RetrieveParent(ASS.nIdSecondLine))
local vtStartDir = EgtSV(ASS.nIdSecondLine, GDB_RT.GLOB)
local vtAx = vtNorm ^ vtStartDir
-- recupero il punto usato per l'accoppiamento
ASS.ptAx = ptPair
ASS.vtAx = vtAx
ASS.dAng = 180
ASS.Rotate()
ASS.EdgePair()
return true
end
function ASS.FacePair()
-- setto e controllo
EgtSetContext(ASS.nVeinCtx)
if ASS.nPartId == GDB_ID.NULL then return false end
if ASS.nIdSecondLine == GDB_ID.NULL then 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
ASS.Rotate()
else
ASS.dAng = -(180 - dAng)
ASS.Rotate()
end
end
function 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 return false end
if ASS.nIdFirstLine == GDB_ID.NULL then return false end
if ASS.nIdSecondLine == GDB_ID.NULL then return false end
-- controllo che i due part non siano già accoppiati
-- recupero l'id del secondo part
local nIdToPair = RetrieveParent(ASS.nIdSecondLine)
ASS.nPartId = RetrievePart(ASS.nPartId)
-- 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 false 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)
ASS.Move()
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
ASS.Rotate()
EgtDraw()
end
function ASS.Unpair()
-- rimuovo le info dal PartCurr e da tutti i suoi Pair
ASS.nPartToPair = ASS.nPartId
ASS.RemovePairInfo()
local nPartCurr = ASS.nPartId
RetrievePaired()
local sPaired = EgtGetInfo(ASS.nPartId, "Paired")
for n, nId in pairs(vPaired) do
ASS.nPartId = nId
ASS.sPairList = sPaired
ASS.nGroup = #vPaired > 1 and GDB_ID.NULL or 0
ASS.UpdatePairInfoSingle()
end
-- resetto le info di pairing del part corrente
ASS.nPartId = nPartCurr
ASS.sPairList = EgtNumToString(nPartCurr)
ASS.nGroup = 0
ASS.UpdatePairInfoSingle()
end
function ASS.RemovePairInfo() --nId As Integer, nIdToUnpair As Integer
-- al part nId tolgo l'accoppiamento con nIdToUnpair
--aggiorno le info
local sPair = EgtGetInfo(ASS.nPartId, "Paired", sPair)
local vsPaired = EgtSplitString(sPair, ",")
local sIdToUnpair = EgtNumToString(ASS.nPartToPair)
-- 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
ASS.UpdatePairInfoSingle()
end
function ASS.UpdatePairInfoSingle()
EgtSetInfo(ASS.nPartId, "Paired", ASS.sPairList)
if ASS.nGroup ~= GDB_ID.NULL then
EgtSetInfo(ASS.nPartId, "GroupCode", ASS.nGroup)
end
end
function ASS.UpdatePairInfo()
local nId1 = RetrievePart(ASS.nPartId)
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
ASS.nPartToPair = nId2
-- salvo la lista degli attuali accoppiati del part destinatario dell'accoppiamento
local lPairList = EgtGetInfo( ASS.nPartToPair,"Paired", "vi")
-- verifico se uno o entrambi dei due part sono già in un gruppo
local sPaired1 = ""
sPaired1 = EgtGetInfo(nId1, "Paired")
local sPaired2 = ""
sPaired2 = EgtGetInfo(nId2, "Paired")
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 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
ASS.UpdatePairInfoSingle()
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
--dofile("D:\\Temp\\marmo\\repeat2.lua")
function ASS.PairAll()
--local sTime = os.date( '%y%m%d%H%M%S', os.time())
EgtSetContext(ASS.nVeinCtx)
local nPart = EgtGetFirstPart()
EgtOutLog(tostring(nPart))
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)
-- 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)
local nSpin = EgtGetInfo(nPart, "PairSpin", "i")
ASS.nPartId = nPart
ASS.nIdFirstLine = nMyLineToPair
ASS.nIdSecondLine = nLineToPair
-- se lo spin è negativo vuol dire che devo accoppiare start del primo con end del secondo
-- sennò start con start
ASS.nOption = (nSpin == -1 and 1 or 0)
ASS.EdgePair()
local ptFirst
local ptSecond
if ASS.nOption == 0 then
--Start-Start
ptFirst = EgtEP( ASS.nIdFirstLine, GDB_RT.GLOB)
ptSecond = EgtEP( ASS.nIdSecondLine, GDB_RT.GLOB)
elseif ASS.nOption == 1 then
--Start-End
ptFirst = EgtEP( ASS.nIdFirstLine, GDB_RT.GLOB)
ptSecond = EgtSP( ASS.nIdSecondLine, GDB_RT.GLOB)
elseif ASS.nOption == 2 then
--End-Start
ptFirst = EgtSP( ASS.nIdFirstLine, GDB_RT.GLOB)
ptSecond = EgtEP( ASS.nIdSecondLine, GDB_RT.GLOB)
elseif ASS.nOption == 3 then
--End-End
ptFirst = EgtSP( ASS.nIdFirstLine, GDB_RT.GLOB)
ptSecond = EgtSP( ASS.nIdSecondLine, GDB_RT.GLOB)
elseif ASS.nOption == 4 then
--Mid-Mid
if nSpin == 1 then
ptFirst = EgtSP( ASS.nIdFirstLine, GDB_RT.GLOB)
ptSecond = EgtSP( ASS.nIdSecondLine, GDB_RT.GLOB)
elseif nSpin == -1 then
ptFirst = EgtSP( ASS.nIdFirstLine, GDB_RT.GLOB)
ptSecond = EgtEP( ASS.nIdSecondLine, GDB_RT.GLOB)
end
end
if not AreSamePointApprox( ptFirst, ptSecond) then
ASS.FlipParallel()
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))
ASS.vtAx = EgtSV(ASS.nIdSecondLine, GDB_RT.GLOB)
local dAngCurr = GetRotation(vtSurf1, vtSurf2, ASS.vtAx)
ASS.dAng = dAngCurr - nAngGoal
ASS.ptAx = EgtSP(ASS.nIdSecondLine, GDB_RT.GLOB)
ASS.Rotate()
-- aggiorno le info di accoppiamento
ASS.nPartToPair = nPartToPair
ASS.UpdatePairInfo()
end
nPart = EgtGetNext(nPart)
end
end