Skip to content

Instantly share code, notes, and snippets.

@piXelicidio piXelicidio/FindPairs.ms Secret
Created Jul 3, 2019

Embed
What would you like to do?
function FindPairs EPolyObj =
(
local N = polyop.getNumVerts EPolyObj
local Result = #{} -- Result is a bitArray, will tell non paired (=true) vertices at the end
local t1 = 0
Result.count = N --with N elements
Result = - Result -- inverting makes all elements true.
local UnPairedTag = N+99
local positiveVerts = #()
local negativeVerts = #()
VertsInfo.count = N
--initializing vertInfo
t1 = timeStamp()
for i=1 to N do in coordsys local
(
local v1 = polyop.getVert EPolyObj i
VertsInfo[i] = TVertInfo undefined undefined undefined v1
VertsInfo[i].RightSide = ( v1.x >= 0 ) -- RightSide = positive
if VertsInfo[i].RightSide then ( append PositiveVerts i ) else ( append negativeVerts i )
--Vertices on the "center" Symmetry AXE paired with themselves.
If abs(v1.x) <= Tolerance then
(
VertsInfo[i].PairedWith = i
Result[i]=false
)
--Links
--Find the list of vertices connected via edge, store in LinkedTo bitarray
local MyEdges = polyop.getEdgesUsingVert EPolyObj i
VertsInfo[i].Linkedto = #{}
for k in MyEdges do
(
VertsInfo[i].Linkedto = VertsInfo[i].Linkedto + (polyop.getVertsUsingEdge EPolyObj k )
)
--remove self
VertsInfo[i].Linkedto = VertsInfo[i].Linkedto - #{i}
)
print ("Initializing Verts Info. delay: "+(timeStamp()-t1) as string)
--Finding Pairs by position------------------------------- The standard easy way
print "Finding symmetrical pairs..."
t1 = timeStamp()
proBar.color = [0,255,255]
for i=1 to positiveVerts.count do in coordsys local
(
local v1 = VertsInfo[ positiveVerts[i] ].vPos
for j=1 to negativeVerts.count do
(
local v2 = copy VertsInfo[ negativeVerts[j] ].vPos
v2.x = -v2.x
local d = (distance v1 v2)
if d<=Tolerance then
(
VertsInfo[ positiveVerts[i] ].PairedWith = negativeVerts[j]
VertsInfo[ negativeVerts[j] ].PairedWith = positiveVerts[i]
Result[ positiveVerts[i] ]=false
Result[ negativeVerts[j] ]=false
)
)
proBar.value = (i * 100) / N
)
print ("Done. delay: "+(timeStamp()-t1) as string )
-- Find pairs by links -------------------------- the cool start here -------------- Edge Connections Analysis
local ResultList = result as array
-- ResultList cointatins the vertices that has not pairs yet.
print ("Finding pairs by edge connections. Verts count: "+(ResultList.count as string))
t1 = timeStamp()
--proBar.value = 0
proBar.color = [255, 255, 0]
local NewLinksCount = 0
local UnlinkedPairs = (ResultList.count / 2) +1
if (chkEdgeAnalysis.checked==true) and (ResultList.count != 0) then
do
(
Local FoundNewPairs=0
for r=1 to ResultList.count do in coordsys local
(
local i = ResultList[r]
if VertsInfo[i].PairedWith==undefined then
(
Result[i] = true
local MyCandidate = 0
local MyCandidateNum = 0
for rr=1 to ResultList.count do
(
local j = ResultList[rr] -- to avoid rename all J vars O.o
if i!=j then
(
local RSymLinks = #{}
local RUnpairedLinks = 0
local LSymLinks = #{}
local LUnpairedLinks = 0
--Remap the links using paired Vertice Numbers.
--Side 1
for k in VertsInfo[i].LinkedTo do
(
if VertsInfo[k].PairedWith==undefined then
(
RUnpairedLinks += 1
) else
(
-- collect just the links indices for this side
RSymLinks = RSymLinks + #{ k }
)
)
--Side 2
for k in VertsInfo[j].LinkedTo do
(
if VertsInfo[k].PairedWith==undefined then
(
LUnpairedLinks += 1
) else
(
-- for this side The pairs of the links
LSymLinks = LSymLinks + #{ VertsInfo[k].PairedWith }
)
)
-- And now the moment of "almost" truth!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-- The left vert qualify for pairing???
--Empty links sets, cant prove nothing
if (not RSymLInks.isEmpty) and (not RSymLinks.isEmpty )then
(
-- Testing if two SETS are EQUAL:
if (RSymLinks-LSymLinks).isEmpty and (LSymLinks-RSymLinks).IsEmpty then
(
--but wat about the Unpaired links?
if RUnpairedLinks == LUnpairedLinks then
(
--this is a good candidate!
--lets see if there not already one before...
if MyCandidate==0 then
(
--Nice this is the first (hope only)
MyCandidate=j
MyCandidateNum+= 1
--print ("Candidate! " + (MyCandidate as string) )
) else
(
--no need for more searching there are duplicated "ideal" conditions
--but instead of exiting the loops, lets just count the candidates
MyCandidateNum += 1
)
)
)
)
)
)--For J end
--if One and only One then yeah
if MyCandidateNum == 1 then
(
--We can pair vert I with vert MyCandidate
VertsInfo[i].PairedWith = MyCandidate
VertsInfo[MyCandidate].PairedWith = i
-- Revise the Side of the vertices.
FoundNewPairs += 1
Result[i]=false
Result[MyCandidate]=false
NewLinksCount += 1
--updating progressbar
proBar.value = (100 * NewLinkscount) / UnlinkedPairs
)--if MyCandidateNum == 1
)--if VertsInfo[i].PairedWith==undefined
)--For I end
--print ("Found New Pairs: " + (FoundNewPairs as string))
) while FoundNewPairs!=0
print ("Done. delay: " +(timeStamp()-t1) as string)
print ( "New found: " + (NewLinkscount as string))
print ("Unpaired: " + (UnlinkedPairs as string))
proBar.value = 100;
proBar.color = [0,255,0]
EPolyObj.selectedVerts = Result
Result
) -- FindPairs funciton END
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.