-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMondrian2subdivisiongenerator2.py
More file actions
218 lines (210 loc) · 7.5 KB
/
Mondrian2subdivisiongenerator2.py
File metadata and controls
218 lines (210 loc) · 7.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#Mondrian like subdivision generator 2
## Different approach relative the first generator. In this case, using
## an ordering based approach as described in the wiki.
import bpy
import random
global dimx
global dimy
dimx = 1000
dimy = 1300
totalnodes = 15 ## 10 originally
meshName = "Mondrian"
obName = "MondrianObj"
me = bpy.data.meshes.new(meshName)
ob = bpy.data.objects.new(obName, me)
ob.location = bpy.context.scene.cursor_location
bpy.context.scene.objects.link(ob)
def getrand(minv, maxv, randlist):
val = random.randint(minv,maxv)
if val not in randlist:
return val
else:
return getrand(minv,maxv,randlist)
nodes = {}
nodepostoi = {}
randomxlist = []
randomylist = []
for i in range(0,totalnodes):
attr = {}
randposx = getrand(1,dimx-1,randomxlist)
randposy = getrand(1,dimy-1,randomylist)
## randposx = random.randint(0,dimx)
## randposy = random.randint(0,dimy)
attr['position'] = (randposx,randposy)
attr['child1'] = None
attr['childq1'] = None
attr['child2'] = None
attr['childq2'] = None
attr['child3'] = None
attr['childq3'] = None
attr['child4'] = None
attr['childq4'] = None
attr['parent'] = None
attr['parentquadrant'] = None
randomxlist.append(randposx)
randomylist.append(randposy)
nodes[i+1] = attr
nodepostoi[(randposx,randposy)] = i+1
nodeposlist = list(nodepostoi.keys())
## each parent has 4 quadrant branches given by a min max position set
## and a child index branch
## processing node precedent
## Need fast position indexing tree lookup and assignment
## poslookuptree -> ['index'] and poslookuptree -> ['postree']
def findparent(nodepos, poslookuptree, minmaxcoordlist):
## using a minpos, maxpos tuple coordinate identifier
parenti = None
nodeposx, nodeposy = nodepos
print('nodepos: ', nodepos)
i = 0
for minmaxpositions in poslookuptree:
minpos, maxpos = minmaxpositions
minx, miny = minpos
maxx, maxy = maxpos
print('minmaxpositions: ', minmaxpositions)
t1 = nodeposx >= minx
t2 = nodeposx <= maxx
t3 = nodeposy >= miny
t4 = nodeposy <= maxy
if t1 and t2 and t3 and t4:
if poslookuptree[minmaxpositions]['postree'] != None:
minmaxcoordlist.append(minmaxpositions)
poslookupt = poslookuptree[minmaxpositions]['postree']
parenti, i, minmaxcoordlist = findparent(nodepos, poslookupt,
minmaxcoordlist)
return parenti, i, minmaxcoordlist
else:
parenti = poslookuptree[minmaxpositions]['index']
i = poslookuptree[minmaxpositions]['quadrant']
minmaxcoordlist.append(minmaxpositions)
return parenti, i, minmaxcoordlist
##i += 1
return parenti, i, minmaxcoordlist
def setparent(nodepos, poslookuptree, minmaxcoordlist):
if len(minmaxcoordlist) > 1:
mmcoord = minmaxcoordlist[0]
del minmaxcoordlist[0]
poslookuptree2 = poslookuptree[mmcoord]['postree']
setparent(nodepos,poslookuptree2, minmaxcoordlist)
else:
mmcoord = minmaxcoordlist[0]
nodeposx, nodeposy = nodepos
minpos, maxpos = mmcoord
minx, miny = minpos
maxx, maxy = maxpos
q1minpos = (minx, nodeposy)
q1maxpos = (nodeposx, maxy)
q2minpos = nodepos
q2maxpos = maxpos
q3minpos = minpos
q3maxpos = nodepos
q4minpos = (nodeposx, miny)
q4maxpos = (maxx, nodeposy)
q1coord = (q1minpos,q1maxpos)
q2coord = (q2minpos,q2maxpos)
q3coord = (q3minpos,q3maxpos)
q4coord = (q4minpos,q4maxpos)
qlist = [q1coord,q2coord,q3coord,q4coord]
attr = {}
attr['index'] = None
attr['postree'] = None
attr['quadrant'] = None
ptreedict = {}
i = 0
for q in qlist:
attr['quadrant'] = i
ptreedict[q] = attr.copy()
i += 1
poslookuptree[mmcoord]['postree'] = ptreedict
## poslookuptree is a quaternary search tree
poslookuptree = {}
##initialize the position lookup tree
nodepos = nodeposlist[0]
nodeposx, nodeposy = nodeposlist[0]
minpos, maxpos = [(0,0),(dimx,dimy)]
minx, miny = minpos
maxx, maxy = maxpos
q1minpos = (minx, nodeposy)
q1maxpos = (nodeposx, maxy)
q2minpos = nodepos
q2maxpos = maxpos
q3minpos = minpos
q3maxpos = nodepos
q4minpos = (nodeposx, miny)
q4maxpos = (maxx, nodeposy)
q1coord = (q1minpos,q1maxpos)
q2coord = (q2minpos,q2maxpos)
q3coord = (q3minpos,q3maxpos)
q4coord = (q4minpos,q4maxpos)
qlist = [q1coord,q2coord,q3coord,q4coord]
attr = {}
attr['index'] = None
attr['postree'] = None
attr['quadrant'] = None
ptreedict = {}##poslookuptree[mmcoord]['postree']
i = 0
for q in qlist:
attr['quadrant'] = i
ptreedict[q] = attr.copy()
i += 1
nodeposlistc = nodeposlist[0:len(nodeposlist)]
del nodeposlistc[0]
## finish quaternary subdivision assignments
for nodepos in nodeposlistc:
minmaxcoordlist = []
parent, quad, minmaxcoordlist = findparent(nodepos, ptreedict,
minmaxcoordlist)
print('minmaxcoordlist', minmaxcoordlist)
minmaxcoordlistc = minmaxcoordlist[0:len(minmaxcoordlist)]
setparent(nodepos, ptreedict, minmaxcoordlistc)
## if 'postree' node is None then we record the vertices of the quadrant
## we use the quadrant minmax position to construct the 4 vertices to a face
## we also append these if not in the list of vertices to a vertex list
## making note of the position of the vertex in the list we use a vertex
## position to index mapping, or we can do this all at once in the
## the read the tree algorithm
## Will need a quaternary recursive search algorithm that reads the entire
## subdivison tree.
def buildvertsfaces(ptreedict, vertices, faces):
for minmaxpositions in ptreedict:
if ptreedict[minmaxpositions]['postree'] == None:
minpos, maxpos = minmaxpositions
minpostup = (float(minpos[0])/dimy,float(minpos[1])/dimy,0.0)
maxpostup = (float(maxpos[0])/dimy,float(maxpos[1])/dimy,0.0)
minposindex = None
maxposindex = None
pos3index = None
pos2index = None
if minpostup in vertices:
minposindex = vertices.index(minpostup)
else:
vertices.append(minpostup)
minposindex = len(vertices)-1
if maxpostup in vertices:
maxposindex = vertices.index(maxpostup)
else:
vertices.append(maxpostup)
maxposindex = len(vertices)-1
pos2 = (float(minpos[0])/dimy,float(maxpos[1])/dimy,0.0)
pos3 = (float(maxpos[0])/dimy,float(minpos[1])/dimy,0.0)
if pos2 in vertices:
pos2index = vertices.index(pos2)
else:
vertices.append(pos2)
pos2index = len(vertices)-1
if pos3 in vertices:
pos3index = vertices.index(pos3)
else:
vertices.append(pos3)
pos3index = len(vertices)-1
face = (minposindex, pos2index, maxposindex, pos3index)
faces.append(face)
else:
ptreedict2 = ptreedict[minmaxpositions]['postree']
buildvertsfaces(ptreedict2,vertices,faces)
## build vertices and faces
vertices = []
faces = []
buildvertsfaces(ptreedict, vertices, faces)
me.from_pydata(vertices,[],faces)
me.update(calc_edges=True)