--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