Newer
Older
cList = splitList(aList, 0)
oList = splitList(aList, 1)
Omin, Omax = getLowHigh(oList)
if Omin == Omax:
Omax += notZero
Omin -= notZero
PdL = []
E = notZero
minL = [Omin for q in range(len(oList))]
maxL = [Omax for q in range(len(oList))]
uNL = [uN for q in range(len(oList))]
E = sum(map(fslg_e13, oList, minL, maxL, uNL))
EL = [E for q in range(len(oList))]
mp = map(fslg_e12, oList, minL, maxL, uNL, EL)
for m in mp:
PdL.append(m)
return PdL
def updatePointCharges(p, cList, eList=[]):
# In: pNew - new growth cell
# cList - old candidate sites, eList -SAME
# Out: list of new charge at candidate sites
r1 = 1 / 2 # (FSLG - Eqn. 10)
nOiL = []
for oi in range(len(cList)):
o = cList[oi][1]
c = cList[oi][0]
iOe = 0
rit = dist(c[0], c[1], c[2], p[0], p[1], p[2])
iOe += (1 - (r1 / rit))
Oit = o + iOe
nOiL.append((c, Oit))
return nOiL
def initialPointCharges(pList, cList, eList=[]):
# In: p -CHARGED CELL (XYZ), cList -candidate sites (XYZ, POT, PROB)
# Out: cList -with potential calculated
r1 = 1 / 2 # (FSLG - Eqn. 10)
npList = []
for p in pList:
npList.append(((p[0], p[1], p[2]), 1.0))
for e in eList:
npList.append(((e[0], e[1], e[2]), e[3]))
OiL = []
for i in cList:
Oi = 0
for j in npList:
if i != j[0]:
rij = dist(i[0], i[1], i[2], j[0][0], j[0][1], j[0][2])
Oi += (1 - (r1 / rij)) * j[1] # charge influence
OiL.append(((i[0], i[1], i[2]), Oi))
return OiL
def getCandidateSites(aList, iList=[]):
# In: aList -(X,Y,Z) of charged cell sites, iList - insulator sites
# Out: candidate list of growth sites [(X,Y,Z)]
cList = []
for c in aList:
tempList = getStencil3D_26(c[0], c[1], c[2])
for t in tempList:
if t not in aList and t not in iList:
cList.append(t)
ncList = deDupe(cList)
return ncList
# Setup functions
def setupObjects():
winmgr = bpy.context.scene.advanced_objects1
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
oOB = bpy.data.objects.new('ELorigin', None)
oOB.location = ((0, 0, 10))
bpy.context.scene.objects.link(oOB)
gOB = bpy.data.objects.new('ELground', None)
gOB.empty_draw_type = 'ARROWS'
bpy.context.scene.objects.link(gOB)
cME = makeMeshCube(1)
cOB = bpy.data.objects.new('ELcloud', cME)
cOB.location = ((-2, 8, 12))
cOB.hide_render = True
bpy.context.scene.objects.link(cOB)
iME = makeMeshCube(1)
for v in iME.vertices:
xyl = 6.5
zl = .5
v.co[0] = v.co[0] * xyl
v.co[1] = v.co[1] * xyl
v.co[2] = v.co[2] * zl
iOB = bpy.data.objects.new('ELinsulator', iME)
iOB.location = ((0, 0, 5))
iOB.hide_render = True
bpy.context.scene.objects.link(iOB)
try:
winmgr.OOB = 'ELorigin'
winmgr.GOB = 'ELground'
winmgr.COB = 'ELcloud'
winmgr.IOB = 'ELinsulator'
except:
pass
def checkSettings():
check = True
winmgr = bpy.context.scene.advanced_objects1
if winmgr.OOB == "":
message = "Error: no origin object selected"
if winmgr.GROUNDBOOL and winmgr.GOB == "":
message = "Error: no ground object selected"
if winmgr.CLOUDBOOL and winmgr.COB == "":
message = "Error: no cloud object selected"
if winmgr.IBOOL and winmgr.IOB == "":
message = "Error: no insulator object selected"
if check is False:
debug_prints(func="checkSettings", text=message)
# return state and the message for the operator report
return check, message
# Main
winmgr = bpy.context.scene.advanced_objects1
# fast simulation of laplacian growth
debug_prints(func="FSLG",
text="Go go gadget: fast simulation of laplacian growth")
tc1 = time.clock()
TSTEPS = winmgr.TSTEPS
obORIGIN = bpy.context.scene.objects[winmgr.OOB]
obGROUND = bpy.context.scene.objects[winmgr.GOB]
winmgr.ORIGIN = obORIGIN.location
winmgr.GROUNDZ = int((obGROUND.location[2] - winmgr.ORIGIN[2]) / winmgr.GSCALE)
# 1) insert intial charge(s) point (uses verts if mesh)
if obORIGIN.type == 'MESH':
debug_prints(
func="FSLG",
text="Origin object is mesh, 'voxelizing' intial charges from verts"
)
cgrid = voxelByVertex(obORIGIN, winmgr.GSCALE)
debug_prints(
func="FSLG",
text="Cannot classify stroke from vert origins yet, no multi-mesh output"
)
winmgr.VMMESH = False
winmgr.VSMESH = True
# ground charge cell / insulator lists (echargelist/iclist)
eChargeList = []
icList = []
if winmgr.GROUNDBOOL:
eChargeList = fakeGroundChargePlane(winmgr.GROUNDZ, winmgr.GROUNDC)
if winmgr.CLOUDBOOL:
debug_prints(
func="FSLG",
text="'Voxelizing' cloud object (could take some time)"
)
obCLOUD = bpy.context.scene.objects[winmgr.COB]
eChargeListQ = voxelByRays(obCLOUD, winmgr.ORIGIN, winmgr.GSCALE)
eChargeList = addCharges(eChargeListQ, winmgr.CLOUDC)
debug_prints(
func="FSLG",
text="cloud object cell count", var=len(eChargeList)
)
debug_prints(
func="FSLG",
text="'Voxelizing' insulator object (could take some time)"
)
obINSULATOR = bpy.context.scene.objects[winmgr.IOB]
icList = voxelByRays(obINSULATOR, winmgr.ORIGIN, winmgr.GSCALE)
debug_prints(
func="FSLG",
text="Insulator object cell count", var=len(icList)
)
# 2) locate candidate sites around charge
cSites = getCandidateSites(cgrid, icList)
# 3) calc potential at each site (eqn. 10)
cSites = initialPointCharges(cgrid, cSites, eChargeList)
ts = 1
while ts <= TSTEPS:
# 1) select new growth site (eqn. 12)
# get probabilities at candidate sites
gProbs = getGrowthProbability(winmgr.BIGVAR, cSites)
# choose new growth site based on probabilities
gSitei = weightedRandomChoice(gProbs)
gsite = cSites[gSitei][0]
# 2) add new point charge at growth site
# add new growth cell to grid
# remove new growth cell from candidate sites
cSites.remove(cSites[gSitei])
# 3) update potential at candidate sites (eqn. 11)
cSites = updatePointCharges(gsite, cSites, eChargeList)
# 4) add new candidates surrounding growth site
# get candidate 'stencil'
ncSitesT = getCandidateSites([gsite], icList)
# remove candidates already in candidate list or charge grid
ncSites = []
cSplit = splitList(cSites, 0)
for cn in ncSitesT:
if cn not in cSplit and cn not in cgrid:
ncSites.append((cn, 0))
# 5) calc potential at new candidate sites (eqn. 10)
ncSplit = splitList(ncSites, 0)
ncSites = initialPointCharges(cgrid, ncSplit, eChargeList)
# add new candidate sites to candidate list
for ncs in ncSites:
cSites.append(ncs)
# iteration complete
istr1 = ':::T-STEP: ' + str(ts) + '/' + str(TSTEPS)
istr12 = ' | GROUNDZ: ' + str(winmgr.GROUNDZ) + ' | '
istr2 = 'CANDS: ' + str(len(cSites)) + ' | '
istr3 = 'GSITE: ' + str(gsite)
debug_prints(
func="FSLG",
text="Iteration complete",
var=istr1 + istr12 + istr2 + istr3
)
# early termination for ground/cloud strike
if winmgr.GROUNDBOOL:
if gsite[2] == winmgr.GROUNDZ:
ts = TSTEPS + 1
debug_prints(
func="FSLG",
text="Early termination due to groundstrike"
)
if winmgr.CLOUDBOOL:
if gsite in splitListCo(eChargeList):
ts = TSTEPS + 1
debug_prints(
func="FSLG",
text="Early termination due to cloudstrike"
)
continue
tc2 = time.clock()
tcRUN = tc2 - tc1
debug_prints(
func="FSLG",
text="Laplacian growth loop completed",
var=str(len(cgrid)) + " / " + str(tcRUN)[0:5] + " Seconds"
)
debug_prints(func="FSLG", text="Visualizing data")
reportSTRING = getReportString(tcRUN)
# Visualize array
visualizeArray(
cgrid, obORIGIN, winmgr.GSCALE,
winmgr.VMMESH, winmgr.VSMESH,
winmgr.VCUBE, winmgr.VVOX, reportSTRING
)
debug_prints(func="FSLG", text="COMPLETE")
class runFSLGLoopOperator(Operator):
bl_idname = "object.runfslg_operator"
bl_label = "run FSLG Loop Operator"
bl_description = "By The Mighty Hammer Of Thor!!!"
def execute(self, context):
# tuple - state, report text
is_conditions, message = checkSettings()
if is_conditions:
self.report({'WARNING'}, message + " Operation Cancelled")
return {'CANCELLED'}
return {'FINISHED'}
class setupObjectsOperator(Operator):
bl_idname = "object.setup_objects_operator"
bl_label = "Setup Objects Operator"
bl_description = "Create origin/ground/cloud/insulator objects"
def execute(self, context):
setupObjects()
return {'FINISHED'}
class OBJECT_PT_fslg(Panel):
bl_label = "Laplacian Lightning"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_context = "objectmode"
bl_category = "Create"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
winmgr = context.scene.advanced_objects1
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
col = layout.column(align=True)
col.prop(winmgr, "TSTEPS")
col.prop(winmgr, "GSCALE")
col.prop(winmgr, "BIGVAR")
col = layout.column()
col.operator("object.setup_objects_operator", text="Create Setup objects")
col.label("Origin object")
col.prop_search(winmgr, "OOB", context.scene, "objects")
box = layout.box()
col = box.column()
col.prop(winmgr, "GROUNDBOOL")
if winmgr.GROUNDBOOL:
col.prop_search(winmgr, "GOB", context.scene, "objects")
col.prop(winmgr, "GROUNDC")
box = layout.box()
col = box.column()
col.prop(winmgr, "CLOUDBOOL")
if winmgr.CLOUDBOOL:
col.prop_search(winmgr, "COB", context.scene, "objects")
col.prop(winmgr, "CLOUDC")
box = layout.box()
col = box.column()
col.prop(winmgr, "IBOOL")
if winmgr.IBOOL:
col.prop_search(winmgr, "IOB", context.scene, "objects")
col = layout.column()
col.operator("object.runfslg_operator",
text="Generate Lightning", icon="RNDCURVE")
row = layout.row(align=True)
row.prop(winmgr, "VMMESH", toggle=True)
row.prop(winmgr, "VSMESH", toggle=True)
row.prop(winmgr, "VCUBE", toggle=True)
def getReportString(rtime):
winmgr = bpy.context.scene.advanced_objects1
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
rSTRING1 = 't:' + str(winmgr.TSTEPS) + ',sc:' + str(winmgr.GSCALE)[0:4] + ',uv:' + str(winmgr.BIGVAR)[0:4] + ','
rSTRING2 = 'ori:' + str(winmgr. ORIGIN[0]) + '/' + str(winmgr. ORIGIN[1]) + '/' + str(winmgr. ORIGIN[2]) + ','
rSTRING3 = 'gz:' + str(winmgr.GROUNDZ) + ',gc:' + str(winmgr.GROUNDC) + ',rtime:' + str(int(rtime))
return rSTRING1 + rSTRING2 + rSTRING3
def addReportProp(ob, str):
bpy.types.Object.FSLG_REPORT = bpy.props.StringProperty(
name='fslg_report', default='')
ob.FSLG_REPORT = str
def register():
bpy.utils.register_class(runFSLGLoopOperator)
bpy.utils.register_class(setupObjectsOperator)
bpy.utils.register_class(OBJECT_PT_fslg)
def unregister():
bpy.utils.unregister_class(runFSLGLoopOperator)
bpy.utils.unregister_class(setupObjectsOperator)
bpy.utils.unregister_class(OBJECT_PT_fslg)
if __name__ == "__main__":
register()
pass
# Benchmarks Function
debug_prints(func="BENCH", text="BEGIN BENCHMARK")
# make a big list
tsize = 25
tlist = []
for x in range(tsize):
for y in range(tsize):
for z in range(tsize):
tlist.append((x, y, z))
tlist.append((x, y, z))
# function to test
bt1 = time.clock()
bt2 = time.clock()
btRUNb = bt2 - bt1
btRUNa = bt1 - bt0
debug_prints(func="BENCH", text="SETUP TIME", var=btRUNa)
debug_prints(func="BENCH", text="BENCHMARK TIME", var=btRUNb)
debug_print_vars(
"\n[BENCH]\n",
"GRIDSIZE: ", tsize, ' - ', tsize * tsize * tsize
)