def build(self, buildRequest):
t = time.time()
guide = bpy.data.objects[self.settings["guideMesh"]]
data = guide.data
wrld = guide.matrix_world
if self.totalArea is None:
self.totalArea = sum(p.area for p in data.polygons)
positions = []
for n in range(self.settings["noToPlace"]):
remaining = random.random() * self.totalArea
index = 0
while remaining > 0:
remaining -= data.polygons[index].area
if remaining <= 0:
a = data.vertices[data.polygons[index].vertices[0]].co
b = data.vertices[data.polygons[index].vertices[1]].co
c = data.vertices[data.polygons[index].vertices[2]].co
r1 = math.sqrt(random.random())
r2 = random.random()
pos = (1 - r1) * a + (r1 * (1 - r2)) * b + (r1 * r2) * c
if self.settings["overwritePosition"]:
pos = wrld * pos
else:
pos.rotate(mathutils.Euler(buildRequest.rot))
pos *= buildRequest.scale
pos = buildRequest.pos + pos
positions.append(pos)
index += 1
if self.settings["relax"]:
sce = bpy.context.scene
gnd = sce.objects[self.settings["guideMesh"]]
if self.bvhtree is None:
self.bvhtree = BVHTree.FromObject(gnd, sce)
radius = self.settings["relaxRadius"]
for i in range(self.settings["relaxIterations"]):
kd = KDTree(len(positions))
for n, p in enumerate(positions):
kd.insert(p, n)
kd.balance()
for n, p in enumerate(positions):
adjust = Vector()
localPoints = kd.find_range(p, radius * 2)
for (co, ind, dist) in localPoints:
if ind != n:
v = p - co
if v.length > 0:
adjust += v * \
((2 * radius - v.length) / v.length)
if len(localPoints) > 0:
adjPos = positions[n] + adjust / len(localPoints)
positions[n] = self.bvhtree.find_nearest(adjPos)[0]
cm_timings.placement["TemplateMESHPOSITIONING"] += time.time() - t
cm_timings.placementNum["TemplateMESHPOSITIONING"] += 1
for newPos in positions:
newBuildRequest = buildRequest.copy()
newBuildRequest.pos = newPos
self.inputs["Template"].build(newBuildRequest)
评论列表
文章目录