Skip to content
Snippets Groups Projects
Commit b35a3cfb authored by Brendon Murphy's avatar Brendon Murphy
Browse files

updated, added cloud types

parent ef71d65d
No related branches found
No related tags found
No related merge requests found
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
bl_addon_info = { bl_addon_info = {
'name': 'Object: Cloud Generator', 'name': 'Object: Cloud Generator',
'author': 'Nick Keeline(nrk)', 'author': 'Nick Keeline(nrk)',
'version': '0.6', 'version': '0.7',
'blender': (2, 5, 3), 'blender': (2, 5, 3),
'location': 'Tool Shelf ', 'location': 'Tool Shelf ',
'description': 'Creates Volumetric Clouds', 'description': 'Creates Volumetric Clouds',
...@@ -42,6 +42,7 @@ Rev 0.3 Fixed bug in degenerate ...@@ -42,6 +42,7 @@ Rev 0.3 Fixed bug in degenerate
Rev 0.4 updated for api change/changed to new apply modifier technique Rev 0.4 updated for api change/changed to new apply modifier technique
Rev 0.5 made particle count equation with radius so radius increases with cloud volume Rev 0.5 made particle count equation with radius so radius increases with cloud volume
Rev 0.6 added poll function to operator, fixing crash with no selected objects Rev 0.6 added poll function to operator, fixing crash with no selected objects
Rev 0.7 added particles option and Type of Cloud wanted selector
""" """
import bpy import bpy
...@@ -153,6 +154,29 @@ def applyScaleRotLoc(scene, obj): ...@@ -153,6 +154,29 @@ def applyScaleRotLoc(scene, obj):
bpy.ops.object.scale_apply() bpy.ops.object.scale_apply()
def totallyDeleteObject(scene, obj):
#To Do this section to be updated when
#Ability to completely delet objects added to blender
# Deselect All
bpy.ops.object.select_all(action='DESELECT')
# Select the object and delete it.
obj.selected = True
scene.objects.active = obj
# Delete all material slots in obj
for i in range(len(obj.material_slots)):
#textureSlots = cloudMaterial.texture_slots
obj.active_material_index = i - 1
bpy.ops.object.material_slot_remove()
#bpy.ops.object.parent_clear(type='CLEAR')
# Delete the Main Object
bpy.ops.object.delete()
#bpy.data.objects.remove(obj)
def makeParent(parentobj, childobj, scene): def makeParent(parentobj, childobj, scene):
applyScaleRotLoc(scene, parentobj) applyScaleRotLoc(scene, parentobj)
...@@ -229,7 +253,6 @@ def degenerateCloud(obj): ...@@ -229,7 +253,6 @@ def degenerateCloud(obj):
return False return False
class View3DPanel(bpy.types.Panel): class View3DPanel(bpy.types.Panel):
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS' bl_region_type = 'TOOLS'
...@@ -241,44 +264,54 @@ class VIEW3D_PT_tools_cloud(View3DPanel): ...@@ -241,44 +264,54 @@ class VIEW3D_PT_tools_cloud(View3DPanel):
def draw(self, context): def draw(self, context):
active_obj = context.active_object active_obj = context.active_object
layout = self.layout
col = layout.column(align=True)
degenerate = degenerateCloud(active_obj) degenerate = degenerateCloud(active_obj)
if active_obj and degenerate: if active_obj and degenerate:
layout = self.layout
col = layout.column(align=True)
col.operator("cloud.generate_cloud", text="DeGenerate") col.operator("cloud.generate_cloud", text="DeGenerate")
elif active_obj is None: elif active_obj is None:
layout = self.layout
col = layout.column(align=True)
col.label(text="Select one or more") col.label(text="Select one or more")
col.label(text="objects to generate") col.label(text="objects to generate")
col.label(text="a cloud.") col.label(text="a cloud.")
elif "CloudMember" in active_obj: elif "CloudMember" in active_obj:
layout = self.layout
col = layout.column(align=True)
col.label(text="Must select") col.label(text="Must select")
col.label(text="bound box") col.label(text="bound box")
elif active_obj and active_obj.type == 'MESH': elif active_obj and active_obj.type == 'MESH':
layout = self.layout
col = layout.column(align=True)
col.operator("cloud.generate_cloud", text="Generate Cloud") col.operator("cloud.generate_cloud", text="Generate Cloud")
col.prop(context.scene, "cloudparticles")
col.prop(context.scene, "cloud_type")
else: else:
layout = self.layout
col = layout.column(align=True)
col.label(text="Select one or more") col.label(text="Select one or more")
col.label(text="objects to generate") col.label(text="objects to generate")
col.label(text="a cloud.") col.label(text="a cloud.")
# col.label(active_obj["CloudMember"])
cloudTypes = []
cloudTypes.append(("0","Stratus","Generate Stratus_foggy Cloud"))
cloudTypes.append(("1","Cumulous","Generate Cumulous_puffy Cloud"))
cloudTypes.append(("2","Cirrus","Generate Cirrus_wispy Cloud"))
#cloudTypes.append(("3","Nimbus","Generate Nimbus Cloud"))
bpy.types.Scene.BoolProperty( attr="cloudparticles",
name="Particles",
description="Generate Cloud as Particle System",
default=False)
bpy.types.Scene.EnumProperty( attr="cloud_type",
name="Type",
description="Select the type of cloud to create with material settings",
items = cloudTypes, default = '0')
class GenerateCloud(bpy.types.Operator): class GenerateCloud(bpy.types.Operator):
bl_idname = "cloud.generate_cloud" bl_idname = "cloud.generate_cloud"
...@@ -322,7 +355,7 @@ class GenerateCloud(bpy.types.Operator): ...@@ -322,7 +355,7 @@ class GenerateCloud(bpy.types.Operator):
cloudMembers = active_object.children cloudMembers = active_object.children
createdObjects = [] createdObjects = []
definitionObjects = [] definitionObjects = []
for member in cloudMembers: for member in cloudMembers:
applyScaleRotLoc(scene, member) applyScaleRotLoc(scene, member)
if (member["CloudMember"] == "CreatedObj"): if (member["CloudMember"] == "CreatedObj"):
...@@ -331,43 +364,25 @@ class GenerateCloud(bpy.types.Operator): ...@@ -331,43 +364,25 @@ class GenerateCloud(bpy.types.Operator):
definitionObjects.append(member) definitionObjects.append(member)
for defObj in definitionObjects: for defObj in definitionObjects:
# @todo check if it wouldn't be better to remove this #Delete cloudmember data from objects
# in the first place (see del() in degenerateCloud)
#totally agree didn't know how before now...thanks! done.
if "CloudMember" in defObj: if "CloudMember" in defObj:
del(defObj["CloudMember"]) del(defObj["CloudMember"])
for createdObj in createdObjects: for createdObj in createdObjects:
# Deselect All totallyDeleteObject(scene, createdObj)
bpy.ops.object.select_all(action='DESELECT')
# Select the object and delete it.
createdObj.selected = True
scene.objects.active = createdObj
bpy.ops.object.delete()
# Delete the main object # Delete the main object
# Deselect All totallyDeleteObject(scene, mainObj)
bpy.ops.object.select_all(action='DESELECT')
# Select the object and delete it.
mainObj.selected = True
scene.objects.active = mainObj
# Delete all material slots in mainObj object
for i in range(len(mainObj.material_slots)):
mainObj.active_material_index = i - 1
bpy.ops.object.material_slot_remove()
# Delete the Main Object
bpy.ops.object.delete()
# Select all of the left over boxes so people can immediately # Select all of the left over boxes so people can immediately
# press generate again if they want. # press generate again if they want.
for eachMember in definitionObjects: for eachMember in definitionObjects:
eachMember.max_draw_type = 'SOLID' eachMember.max_draw_type = 'SOLID'
eachMember.selected = True eachMember.selected = True
scene.objects.active = eachMember #scene.objects.active = eachMember
#TODO Delete this when render bug caused by degenerate is fixed.
self.report({'WARNING'}, "Please save file exit and reenter blender before rendering to clean memory and prevent crash")
else: else:
# Generate Cloud # Generate Cloud
...@@ -456,6 +471,7 @@ class GenerateCloud(bpy.types.Operator): ...@@ -456,6 +471,7 @@ class GenerateCloud(bpy.types.Operator):
cloudParticles.settings.ren_as = 'NONE' cloudParticles.settings.ren_as = 'NONE'
cloudParticles.settings.normal_factor = 0 cloudParticles.settings.normal_factor = 0
cloudParticles.settings.distribution = 'RAND' cloudParticles.settings.distribution = 'RAND'
cloudParticles.settings.physics_type = 'NO'
####################Create Volume Material#################### ####################Create Volume Material####################
# Deselect All # Deselect All
...@@ -466,7 +482,7 @@ class GenerateCloud(bpy.types.Operator): ...@@ -466,7 +482,7 @@ class GenerateCloud(bpy.types.Operator):
scene.objects.active = bounds scene.objects.active = bounds
# Turn bounds object into a box. # Turn bounds object into a box.
makeObjectIntoBoundBox(bounds, .2) makeObjectIntoBoundBox(bounds, .6)
# Delete all material slots in bounds object. # Delete all material slots in bounds object.
for i in range(len(bounds.material_slots)): for i in range(len(bounds.material_slots)):
...@@ -498,7 +514,21 @@ class GenerateCloud(bpy.types.Operator): ...@@ -498,7 +514,21 @@ class GenerateCloud(bpy.types.Operator):
cloudtex.noise_type = 'HARD_NOISE' cloudtex.noise_type = 'HARD_NOISE'
cloudtex.noise_size = 2 cloudtex.noise_size = 2
# Add a texture # Add a force field to the points.
cloudField = bounds.field
cloudField.type = 'TEXTURE'
cloudField.strength = 2
cloudField.texture = cloudtex
# Set time
#for i in range(12):
# scene.current_frame = i
# scene.update()
scene.frame_current = 1
#bpy.ops.ptcache.bake(bake=False)
# Add a Point Density texture
cloudPointDensity = main.textures.new("CloudPointDensity") cloudPointDensity = main.textures.new("CloudPointDensity")
cloudPointDensity.type = 'POINT_DENSITY' cloudPointDensity.type = 'POINT_DENSITY'
cloudMaterial.add_texture(cloudPointDensity, 'ORCO') cloudMaterial.add_texture(cloudPointDensity, 'ORCO')
...@@ -517,12 +547,16 @@ class GenerateCloud(bpy.types.Operator): ...@@ -517,12 +547,16 @@ class GenerateCloud(bpy.types.Operator):
pRampElements = pRamp.elements pRampElements = pRamp.elements
#pRampElements[1].position = .9 #pRampElements[1].position = .9
#pRampElements[1].color = [.18,.18,.18,.8] #pRampElements[1].color = [.18,.18,.18,.8]
bpy.ops.texture.slot_move(type='UP')
# Estimate the number of particles for the size of bounds. # Estimate the number of particles for the size of bounds.
volumeBoundBox = (bounds.dimensions[0] * bounds.dimensions[1]* bounds.dimensions[2]) volumeBoundBox = (bounds.dimensions[0] * bounds.dimensions[1]* bounds.dimensions[2])
numParticles = int((2.4462 * volumeBoundBox + 430.4) * numOfPoints) numParticles = int((2.4462 * volumeBoundBox + 430.4) * numOfPoints)
if numParticles > maxNumOfPoints: if numParticles > maxNumOfPoints:
numParticles = maxNumOfPoints numParticles = maxNumOfPoints
if numParticles < 10000:
numParticles = int(numParticles + 15 * volumeBoundBox)
print(numParticles) print(numParticles)
# Set the number of particles according to the volume # Set the number of particles according to the volume
...@@ -534,82 +568,91 @@ class GenerateCloud(bpy.types.Operator): ...@@ -534,82 +568,91 @@ class GenerateCloud(bpy.types.Operator):
# Set time to 1. # Set time to 1.
scene.frame_current = 1 scene.frame_current = 1
###############Create CloudPnts for putting points in######### if not scene.cloudparticles:
# Create a new object cloudPnts ###############Create CloudPnts for putting points in#########
cloudPnts = addNewObject(scene, "CloudPoints", bounds) # Create a new object cloudPnts
cloudPnts["CloudMember"] = "CreatedObj" cloudPnts = addNewObject(scene, "CloudPoints", bounds)
cloudPnts.max_draw_type = 'WIRE' cloudPnts["CloudMember"] = "CreatedObj"
cloudPnts.restrict_render = True cloudPnts.max_draw_type = 'WIRE'
cloudPnts.restrict_render = True
makeParent(bounds, cloudPnts, scene) makeParent(bounds, cloudPnts, scene)
bpy.ops.object.editmode_toggle() bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='SELECT') bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.delete(type='ALL') bpy.ops.mesh.delete(type='ALL')
meshPnts = cloudPnts.data meshPnts = cloudPnts.data
listCloudParticles = cloudParticles.particles listCloudParticles = cloudParticles.particles
listMeshPnts = [] listMeshPnts = []
for pTicle in listCloudParticles: for pTicle in listCloudParticles:
listMeshPnts.append(pTicle.location) listMeshPnts.append(pTicle.location)
# Must be in object mode fro from_pydata to work. # Must be in object mode fro from_pydata to work.
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
# Add in the mesh data. # Add in the mesh data.
meshPnts.from_pydata(listMeshPnts, [], []) meshPnts.from_pydata(listMeshPnts, [], [])
# Update the mesh. # Update the mesh.
meshPnts.update() meshPnts.update()
# Add a modifier. # Add a modifier.
bpy.ops.object.modifier_add(type='DISPLACE') bpy.ops.object.modifier_add(type='DISPLACE')
cldPntsModifiers = cloudPnts.modifiers cldPntsModifiers = cloudPnts.modifiers
cldPntsModifiers[0].name = "CloudPnts" cldPntsModifiers[0].name = "CloudPnts"
cldPntsModifiers[0].texture = cloudtex cldPntsModifiers[0].texture = cloudtex
cldPntsModifiers[0].texture_coordinates = 'OBJECT' cldPntsModifiers[0].texture_coordinates = 'OBJECT'
cldPntsModifiers[0].texture_coordinate_object = cloud cldPntsModifiers[0].texture_coordinate_object = cloud
cldPntsModifiers[0].strength = -1.4 cldPntsModifiers[0].strength = -1.4
# Apply modifier # Apply modifier
bpy.ops.object.modifier_apply(apply_as='DATA', modifier=cldPntsModifiers[0].name) bpy.ops.object.modifier_apply(apply_as='DATA', modifier=cldPntsModifiers[0].name)
pDensity.pointdensity.point_source = 'OBJECT' pDensity.pointdensity.point_source = 'OBJECT'
pDensity.pointdensity.object = cloudPnts pDensity.pointdensity.object = cloudPnts
# Deselect All # Deselect All
bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_all(action='DESELECT')
# Select the object. # Select the object.
cloud.selected = True cloud.selected = True
scene.objects.active = cloud scene.objects.active = cloud
bpy.ops.object.particle_system_remove() bpy.ops.object.particle_system_remove()
# Deselect All # Deselect All
bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_all(action='DESELECT')
else:
pDensity.pointdensity.point_source = 'PARTICLE_SYSTEM'
pDensity.pointdensity.object = cloud
pDensity.pointdensity.particle_system = cloudParticles
if scene.cloud_type == '1': # Cumulous
print("Cumulous")
mVolume.density_scale = 2.22
pDensity.pointdensity.turbulence_depth = 10
pDensity.pointdensity.turbulence_strength = 6.3
pDensity.pointdensity.turbulence_size = 2.9
pRampElements[1].position = .606
pDensity.pointdensity.radius = pDensity.pointdensity.radius + .1
elif scene.cloud_type == '2': # Cirrus
print("Cirrus")
pDensity.pointdensity.turbulence_strength = 22
mVolume.transmission_color = [3.5, 3.5, 3.5]
mVolume.scattering = .13
# Select the object. # Select the object.
bounds.selected = True bounds.selected = True
scene.objects.active = bounds scene.objects.active = bounds
# Add a force field to the points.
#cloudField = bounds.field
#cloudField.type = 'TEXTURE'
#cloudField.strength = 2
#cloudField.texture = cloudtex
# Set time
#for i in range(12):
# scene.current_frame = i
# scene.update()
#bpy.ops.ptcache.bake_all(bake=False)
return {'FINISHED'} return {'FINISHED'}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment