Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlijenstina <lijenstina@gmail.com>2017-07-28 15:36:13 +0300
committerlijenstina <lijenstina@gmail.com>2017-07-28 15:36:13 +0300
commit0df67a49cb39b8a028722f3d4167da72c30510c0 (patch)
treed765faf283da7e3727506ec651b7940d20741c99
parent89f470d0cac3057c1365738caf1fdc258a468679 (diff)
Cloud Generator: Cleanup, use do_unlink instead
Bumped version to 1.0.1 Pep8 cleanup Use do_unlink istead of scene.objects.unlink Add some report messages Remove some commented out code Update wiki link, remove redundant tracker_info Note: possibly needs some more testing
-rw-r--r--object_cloud_gen.py475
1 files changed, 223 insertions, 252 deletions
diff --git a/object_cloud_gen.py b/object_cloud_gen.py
index cac4cd5d..1e138cf6 100644
--- a/object_cloud_gen.py
+++ b/object_cloud_gen.py
@@ -21,115 +21,119 @@
bl_info = {
"name": "Cloud Generator",
"author": "Nick Keeline(nrk)",
- "version": (1, 0),
- "blender": (2, 77, 0),
+ "version": (1, 0, 1),
+ "blender": (2, 78, 5),
"location": "Tool Shelf > Create Tab",
"description": "Creates Volumetric Clouds",
- "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
"Scripts/Object/Cloud_Gen",
- "tracker_url" : "https://developer.blender.org/maniphest/project/3/type/Bug/",
"category": "Object",
}
import bpy
-from bpy.props import BoolProperty, EnumProperty
-from bpy.types import Operator, Panel
+from bpy.props import (
+ BoolProperty,
+ EnumProperty,
+ )
+from bpy.types import (
+ Operator,
+ Panel,
+ )
+
# For Cycles Render we create node groups or if it already exists we return it.
def CreateNodeGroup(Type):
-# Look for NodeTree if it already exists return it
-
+ # Look for NodeTree if it already exists return it
CreateGroup = True
for Group in bpy.data.node_groups:
if Group.name == Type:
CreateGroup = False
NodeGroup = Group
- if CreateGroup == True:
- NodeGroup = bpy.data.node_groups.new(name=Type,type="ShaderNodeTree")
+ if CreateGroup is True:
+ NodeGroup = bpy.data.node_groups.new(name=Type, type="ShaderNodeTree")
NodeGroup.name = Type
NodeGroup.bl_label = Type
NodeGroup.nodes.clear()
-# Create a bunch of nodes and group them based on input to the def
-# Function type
+ # Create a bunch of nodes and group them based on input to the def
+ # Function type
if Type == 'CloudGen_VolumeProperties':
AddAddAndEmission = NodeGroup.nodes.new('ShaderNodeAddShader')
- AddAddAndEmission.location = [300,395]
+ AddAddAndEmission.location = [300, 395]
AddAbsorptionAndScatter = NodeGroup.nodes.new('ShaderNodeAddShader')
- AddAbsorptionAndScatter.location = [0,395]
+ AddAbsorptionAndScatter.location = [0, 395]
VolumeAbsorption = NodeGroup.nodes.new('ShaderNodeVolumeAbsorption')
- VolumeAbsorption.location = [-300,395]
+ VolumeAbsorption.location = [-300, 395]
VolumeScatter = NodeGroup.nodes.new('ShaderNodeVolumeScatter')
- VolumeScatter.location = [-300,0]
+ VolumeScatter.location = [-300, 0]
VolumeEmission = NodeGroup.nodes.new('ShaderNodeEmission')
- VolumeEmission.location = [-300,-300]
+ VolumeEmission.location = [-300, -300]
MathAbsorptionMultiply = NodeGroup.nodes.new('ShaderNodeMath')
- MathAbsorptionMultiply.location = [-750,395]
+ MathAbsorptionMultiply.location = [-750, 395]
MathAbsorptionMultiply.operation = 'MULTIPLY'
MathScatterMultiply = NodeGroup.nodes.new('ShaderNodeMath')
- MathScatterMultiply.location = [-750,0]
+ MathScatterMultiply.location = [-750, 0]
MathScatterMultiply.operation = 'MULTIPLY'
MathEmissionMultiply = NodeGroup.nodes.new('ShaderNodeMath')
- MathEmissionMultiply.location = [-750,-300]
+ MathEmissionMultiply.location = [-750, -300]
MathEmissionMultiply.operation = 'MULTIPLY'
MathBrightnessMultiply = NodeGroup.nodes.new('ShaderNodeMath')
- MathBrightnessMultiply.location = [-1200,0]
+ MathBrightnessMultiply.location = [-1200, 0]
MathBrightnessMultiply.operation = 'MULTIPLY'
MathGreaterThan = NodeGroup.nodes.new('ShaderNodeMath')
- MathGreaterThan.location = [-1200,600]
+ MathGreaterThan.location = [-1200, 600]
MathGreaterThan.operation = 'GREATER_THAN'
MathGreaterThan.inputs[1].default_value = 0
- NodeGroup.links.new(AddAddAndEmission.inputs[0],AddAbsorptionAndScatter.outputs[0])
- NodeGroup.links.new(AddAddAndEmission.inputs[1],VolumeEmission.outputs[0])
- NodeGroup.links.new(AddAbsorptionAndScatter.inputs[0],VolumeAbsorption.outputs[0])
- NodeGroup.links.new(AddAbsorptionAndScatter.inputs[1],VolumeScatter.outputs[0])
- NodeGroup.links.new(VolumeAbsorption.inputs[1],MathAbsorptionMultiply.outputs[0])
- NodeGroup.links.new(VolumeScatter.inputs[1],MathScatterMultiply.outputs[0])
- NodeGroup.links.new(VolumeEmission.inputs[1],MathEmissionMultiply.outputs[0])
- NodeGroup.links.new(MathAbsorptionMultiply.inputs[0],MathGreaterThan.outputs[0])
- NodeGroup.links.new(MathScatterMultiply.inputs[0],MathGreaterThan.outputs[0])
- NodeGroup.links.new(MathEmissionMultiply.inputs[0],MathGreaterThan.outputs[0])
- NodeGroup.links.new(VolumeAbsorption.inputs[0],MathBrightnessMultiply.outputs[0])
-
-# Create and Link In/Out to Group Node
-# Outputs
+ NodeGroup.links.new(AddAddAndEmission.inputs[0], AddAbsorptionAndScatter.outputs[0])
+ NodeGroup.links.new(AddAddAndEmission.inputs[1], VolumeEmission.outputs[0])
+ NodeGroup.links.new(AddAbsorptionAndScatter.inputs[0], VolumeAbsorption.outputs[0])
+ NodeGroup.links.new(AddAbsorptionAndScatter.inputs[1], VolumeScatter.outputs[0])
+ NodeGroup.links.new(VolumeAbsorption.inputs[1], MathAbsorptionMultiply.outputs[0])
+ NodeGroup.links.new(VolumeScatter.inputs[1], MathScatterMultiply.outputs[0])
+ NodeGroup.links.new(VolumeEmission.inputs[1], MathEmissionMultiply.outputs[0])
+ NodeGroup.links.new(MathAbsorptionMultiply.inputs[0], MathGreaterThan.outputs[0])
+ NodeGroup.links.new(MathScatterMultiply.inputs[0], MathGreaterThan.outputs[0])
+ NodeGroup.links.new(MathEmissionMultiply.inputs[0], MathGreaterThan.outputs[0])
+ NodeGroup.links.new(VolumeAbsorption.inputs[0], MathBrightnessMultiply.outputs[0])
+
+ # Create and Link In/Out to Group Node
+ # Outputs
group_outputs = NodeGroup.nodes.new('NodeGroupOutput')
- group_outputs.location = (600,395)
- NodeGroup.outputs.new('NodeSocketShader','shader_out')
- NodeGroup.links.new(AddAddAndEmission.outputs[0],group_outputs.inputs['shader_out'])
+ group_outputs.location = (600, 395)
+ NodeGroup.outputs.new('NodeSocketShader', 'shader_out')
+ NodeGroup.links.new(AddAddAndEmission.outputs[0], group_outputs.inputs['shader_out'])
-# Inputs
+ # Inputs
group_inputs = NodeGroup.nodes.new('NodeGroupInput')
- group_inputs.location = (-1500,-300)
- NodeGroup.inputs.new('NodeSocketFloat','Density')
- NodeGroup.inputs.new('NodeSocketFloat','Absorption Multiply')
- NodeGroup.inputs.new('NodeSocketColor','Absorption Color')
- NodeGroup.inputs.new('NodeSocketFloat','Scatter Multiply')
- NodeGroup.inputs.new('NodeSocketColor','Scatter Color')
- NodeGroup.inputs.new('NodeSocketFloat','Emission Amount')
- NodeGroup.inputs.new('NodeSocketFloat','Cloud Brightness')
-
- NodeGroup.links.new(group_inputs.outputs['Density'],MathGreaterThan.inputs[0])
- NodeGroup.links.new(group_inputs.outputs['Absorption Multiply'],MathAbsorptionMultiply.inputs[1])
- NodeGroup.links.new(group_inputs.outputs['Absorption Color'],MathBrightnessMultiply.inputs[0])
- NodeGroup.links.new(group_inputs.outputs['Scatter Multiply'],MathScatterMultiply.inputs[1])
- NodeGroup.links.new(group_inputs.outputs['Scatter Color'],VolumeScatter.inputs[0])
- NodeGroup.links.new(group_inputs.outputs['Emission Amount'],MathEmissionMultiply.inputs[1])
- NodeGroup.links.new(group_inputs.outputs['Cloud Brightness'],MathBrightnessMultiply.inputs[1])
-
+ group_inputs.location = (-1500, -300)
+ NodeGroup.inputs.new('NodeSocketFloat', 'Density')
+ NodeGroup.inputs.new('NodeSocketFloat', 'Absorption Multiply')
+ NodeGroup.inputs.new('NodeSocketColor', 'Absorption Color')
+ NodeGroup.inputs.new('NodeSocketFloat', 'Scatter Multiply')
+ NodeGroup.inputs.new('NodeSocketColor', 'Scatter Color')
+ NodeGroup.inputs.new('NodeSocketFloat', 'Emission Amount')
+ NodeGroup.inputs.new('NodeSocketFloat', 'Cloud Brightness')
+
+ NodeGroup.links.new(group_inputs.outputs['Density'], MathGreaterThan.inputs[0])
+ NodeGroup.links.new(group_inputs.outputs['Absorption Multiply'], MathAbsorptionMultiply.inputs[1])
+ NodeGroup.links.new(group_inputs.outputs['Absorption Color'], MathBrightnessMultiply.inputs[0])
+ NodeGroup.links.new(group_inputs.outputs['Scatter Multiply'], MathScatterMultiply.inputs[1])
+ NodeGroup.links.new(group_inputs.outputs['Scatter Color'], VolumeScatter.inputs[0])
+ NodeGroup.links.new(group_inputs.outputs['Emission Amount'], MathEmissionMultiply.inputs[1])
+ NodeGroup.links.new(group_inputs.outputs['Cloud Brightness'], MathBrightnessMultiply.inputs[1])
if Type == 'CloudGen_TextureProperties':
MathAdd = NodeGroup.nodes.new('ShaderNodeMath')
- MathAdd.location = [-200,0]
+ MathAdd.location = [-200, 0]
MathAdd.operation = 'ADD'
MathDensityMultiply = NodeGroup.nodes.new('ShaderNodeMath')
- MathDensityMultiply.location = [-390,0]
+ MathDensityMultiply.location = [-390, 0]
MathDensityMultiply.operation = 'MULTIPLY'
PointDensityRamp = NodeGroup.nodes.new('ShaderNodeValToRGB')
- PointDensityRamp.location = [-675,-250]
+ PointDensityRamp.location = [-675, -250]
PointRamp = PointDensityRamp.color_ramp
PElements = PointRamp.elements
PElements[0].position = 0.418
@@ -137,7 +141,7 @@ def CreateNodeGroup(Type):
PElements[1].position = 0.773
PElements[1].color = 1, 1, 1, 1
CloudRamp = NodeGroup.nodes.new('ShaderNodeValToRGB')
- CloudRamp.location = [-675,0]
+ CloudRamp.location = [-675, 0]
CRamp = CloudRamp.color_ramp
CElements = CRamp.elements
CElements[0].position = 0.527
@@ -145,36 +149,36 @@ def CreateNodeGroup(Type):
CElements[1].position = 0.759
CElements[1].color = 1, 1, 1, 1
NoiseTex = NodeGroup.nodes.new('ShaderNodeTexNoise')
- NoiseTex.location = [-940,0]
+ NoiseTex.location = [-940, 0]
NoiseTex.inputs['Detail'].default_value = 4
TexCoord = NodeGroup.nodes.new('ShaderNodeTexCoord')
- TexCoord.location = [-1250,0]
-
+ TexCoord.location = [-1250, 0]
- NodeGroup.links.new(MathAdd.inputs[0],MathDensityMultiply.outputs[0])
- NodeGroup.links.new(MathAdd.inputs[1],PointDensityRamp.outputs[0])
- NodeGroup.links.new(MathDensityMultiply.inputs[0],CloudRamp.outputs[0])
- NodeGroup.links.new(CloudRamp.inputs[0],NoiseTex.outputs[0])
- NodeGroup.links.new(NoiseTex.inputs[0],TexCoord.outputs[3])
+ NodeGroup.links.new(MathAdd.inputs[0], MathDensityMultiply.outputs[0])
+ NodeGroup.links.new(MathAdd.inputs[1], PointDensityRamp.outputs[0])
+ NodeGroup.links.new(MathDensityMultiply.inputs[0], CloudRamp.outputs[0])
+ NodeGroup.links.new(CloudRamp.inputs[0], NoiseTex.outputs[0])
+ NodeGroup.links.new(NoiseTex.inputs[0], TexCoord.outputs[3])
-# Create and Link In/Out to Group Nodes
-# Outputs
+ # Create and Link In/Out to Group Nodes
+ # Outputs
group_outputs = NodeGroup.nodes.new('NodeGroupOutput')
- group_outputs.location = (0,0)
- NodeGroup.outputs.new('NodeSocketFloat','Density W_CloudTex')
- NodeGroup.links.new(MathAdd.outputs[0],group_outputs.inputs['Density W_CloudTex'])
+ group_outputs.location = (0, 0)
+ NodeGroup.outputs.new('NodeSocketFloat', 'Density W_CloudTex')
+ NodeGroup.links.new(MathAdd.outputs[0], group_outputs.inputs['Density W_CloudTex'])
-# Inputs
+ # Inputs
group_inputs = NodeGroup.nodes.new('NodeGroupInput')
- group_inputs.location = (-1250,-300)
- NodeGroup.inputs.new('NodeSocketFloat','Scale')
- NodeGroup.inputs.new('NodeSocketFloat','Point Density In')
- NodeGroup.links.new(group_inputs.outputs['Scale'],NoiseTex.inputs['Scale'])
- NodeGroup.links.new(group_inputs.outputs['Point Density In'],MathDensityMultiply.inputs[1])
- NodeGroup.links.new(group_inputs.outputs['Point Density In'],PointDensityRamp.inputs[0])
+ group_inputs.location = (-1250, -300)
+ NodeGroup.inputs.new('NodeSocketFloat', 'Scale')
+ NodeGroup.inputs.new('NodeSocketFloat', 'Point Density In')
+ NodeGroup.links.new(group_inputs.outputs['Scale'], NoiseTex.inputs['Scale'])
+ NodeGroup.links.new(group_inputs.outputs['Point Density In'], MathDensityMultiply.inputs[1])
+ NodeGroup.links.new(group_inputs.outputs['Point Density In'], PointDensityRamp.inputs[0])
return NodeGroup
+
# This routine takes an object and deletes all of the geometry in it
# and adds a bounding box to it.
# It will add or subtract the bound box size by the variable sizeDifference.
@@ -202,13 +206,13 @@ def maxAndMinVerts(scene, object):
mesh = getMeshandPutinEditMode(scene, object)
verts = mesh.vertices
- #Set the max and min verts to the first vertex on the list
+ # Set the max and min verts to the first vertex on the list
maxVert = [verts[0].co[0], verts[0].co[1], verts[0].co[2]]
minVert = [verts[0].co[0], verts[0].co[1], verts[0].co[2]]
- #Create Max and Min Vertex array for the outer corners of the box
+ # Create Max and Min Vertex array for the outer corners of the box
for vert in verts:
- #Max vertex
+ # Max vertex
if vert.co[0] > maxVert[0]:
maxVert[0] = vert.co[0]
if vert.co[1] > maxVert[1]:
@@ -216,7 +220,7 @@ def maxAndMinVerts(scene, object):
if vert.co[2] > maxVert[2]:
maxVert[2] = vert.co[2]
- #Min Vertex
+ # Min Vertex
if vert.co[0] < minVert[0]:
minVert[0] = vert.co[0]
if vert.co[1] < minVert[1]:
@@ -227,35 +231,34 @@ def maxAndMinVerts(scene, object):
return [maxVert, minVert]
-def makeObjectIntoBoundBox(scene, object, sizeDifference, takeFromObject):
-
+def makeObjectIntoBoundBox(scene, objects, sizeDifference, takeFromObject):
# Let's find the max and min of the reference object,
# it can be the same as the destination object
[maxVert, minVert] = maxAndMinVerts(scene, takeFromObject)
- #get objects mesh
- mesh = getMeshandPutinEditMode(scene, object)
+ # get objects mesh
+ mesh = getMeshandPutinEditMode(scene, objects)
- #Add the size difference to the max size of the box
+ # Add the size difference to the max size of the box
maxVert[0] = maxVert[0] + sizeDifference
maxVert[1] = maxVert[1] + sizeDifference
maxVert[2] = maxVert[2] + sizeDifference
- #subtract the size difference to the min size of the box
+ # subtract the size difference to the min size of the box
minVert[0] = minVert[0] - sizeDifference
minVert[1] = minVert[1] - sizeDifference
minVert[2] = minVert[2] - sizeDifference
- #Create arrays of verts and faces to be added to the mesh
+ # Create arrays of verts and faces to be added to the mesh
addVerts = []
- #X high loop
+ # X high loop
addVerts.append([maxVert[0], maxVert[1], maxVert[2]])
addVerts.append([maxVert[0], maxVert[1], minVert[2]])
addVerts.append([maxVert[0], minVert[1], minVert[2]])
addVerts.append([maxVert[0], minVert[1], maxVert[2]])
- #x low loop
+ # X low loop
addVerts.append([minVert[0], maxVert[1], maxVert[2]])
addVerts.append([minVert[0], maxVert[1], minVert[2]])
addVerts.append([minVert[0], minVert[1], minVert[2]])
@@ -283,6 +286,7 @@ def makeObjectIntoBoundBox(scene, object, sizeDifference, takeFromObject):
# Add the mesh data.
mesh.from_pydata(addVerts, [], addFaces)
+ mesh.validate()
# Update the mesh
mesh.update()
@@ -300,30 +304,25 @@ def applyScaleRotLoc(scene, obj):
def totallyDeleteObject(scene, obj):
- scene.objects.unlink(obj)
- bpy.data.objects.remove(obj)
+ bpy.data.objects.remove(obj, do_unlink=True)
def makeParent(parentobj, childobj, scene):
-
applyScaleRotLoc(scene, parentobj)
applyScaleRotLoc(scene, childobj)
childobj.parent = parentobj
def addNewObject(scene, name, copyobj):
-
- # Create new mesh
- mesh = bpy.data.meshes.new(name)
-
- # Create a new object.
- ob_new = bpy.data.objects.new(name, mesh)
+ # avoid creating not needed meshes pro forme
+ # Create a new object
tempme = copyobj.data
- ob_new.data = tempme.copy()
+ ob_new_data = tempme.copy()
+ ob_new = bpy.data.objects.new(name, ob_new_data)
ob_new.scale = copyobj.scale
ob_new.location = copyobj.location
- # Link new object to the given scene and select it.
+ # Link new object to the given scene and select it
scene.objects.link(ob_new)
ob_new.select = True
@@ -333,23 +332,24 @@ def addNewObject(scene, name, copyobj):
def getpdensitytexture(object):
for mslot in object.material_slots:
- mat = mslot.material
- for tslot in mat.texture_slots:
- if tslot != 'NoneType':
- tex = tslot.texture
- if tex.type == 'POINT_DENSITY':
- if tex.point_density.point_source == 'PARTICLE_SYSTEM':
- return tex
-
-
-def removeParticleSystemFromObj(scene, object):
-
+ # Material slot can be empty
+ mat = getattr(mslot, "material", None)
+ if mat:
+ for tslot in mat.texture_slots:
+ if tslot != 'NoneType':
+ tex = tslot.texture
+ if tex.type == 'POINT_DENSITY':
+ if tex.point_density.point_source == 'PARTICLE_SYSTEM':
+ return tex
+
+
+def removeParticleSystemFromObj(scene, obj):
# Deselect All
bpy.ops.object.select_all(action='DESELECT')
- # Select the object.
- object.select = True
- scene.objects.active = object
+ # Select the object
+ obj.select = True
+ scene.objects.active = obj
bpy.ops.object.particle_system_remove()
@@ -358,15 +358,14 @@ def removeParticleSystemFromObj(scene, object):
def convertParticlesToMesh(scene, particlesobj, destobj, replacemesh):
-
- # Select the Destination object.
+ # Select the Destination object
destobj.select = True
scene.objects.active = destobj
- #Go to Edit Mode
+ # Go to Edit Mode
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
- #Delete everything in mesh if replace true
+ # Delete everything in mesh if replace is true
if replacemesh:
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.delete(type='VERT')
@@ -379,13 +378,14 @@ def convertParticlesToMesh(scene, particlesobj, destobj, replacemesh):
for pTicle in listCloudParticles:
listMeshPnts.append(pTicle.location)
- # Must be in object mode for from_pydata to work.
+ # Must be in object mode for from_pydata to work
bpy.ops.object.mode_set(mode='OBJECT')
- # Add in the mesh data.
+ # Add in the mesh data
meshPnts.from_pydata(listMeshPnts, [], [])
- # Update the mesh.
+ # Update and Validate the mesh
+ meshPnts.validate()
meshPnts.update()
@@ -421,8 +421,10 @@ def getActionToDo(obj):
if not obj or obj.type != 'MESH':
return 'NOT_OBJ_DO_NOTHING'
+
elif obj is None:
return 'NO_SELECTION_DO_NOTHING'
+
elif "CloudMember" in obj:
if obj["CloudMember"] is not None:
if obj["CloudMember"] == "MainObj":
@@ -431,8 +433,10 @@ def getActionToDo(obj):
return 'CLOUD_CONVERT_TO_MESH'
else:
return 'CLOUD_DO_NOTHING'
+
elif obj.type == 'MESH':
return 'GENERATE'
+
else:
return 'DO_NOTHING'
@@ -473,35 +477,32 @@ class VIEW3D_PT_tools_cloud(Panel):
col.prop(context.scene, "cloud_type")
col.prop(context.scene, "cloudsmoothing")
else:
- col.label(text="Select one or more")
- col.label(text="objects to generate")
- col.label(text="a cloud")
+ col.label(text="Select one or more", icon="INFO")
+ col.label(text="objects to generate", icon="BLANK1")
+ col.label(text="a cloud", icon="BLANK1")
class GenerateCloud(Operator):
- """Create a Cloud,Undo Cloud, or convert to Mesh Cloud depending on selection"""
bl_idname = "cloud.generate_cloud"
bl_label = "Generate Cloud"
- bl_register = True
- bl_undo = True
+ bl_description = ("Create a Cloud, Undo a Cloud, or convert to "
+ "Mesh Cloud depending on selection\n"
+ "Needs an Active Mesh Object")
+ bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
- if not context.active_object:
- return False
- else:
- return (context.active_object.type == 'MESH')
+ obj = context.active_object
+ return (obj and obj.type == 'MESH')
def execute(self, context):
# Prevent unsupported Execution in Local View modes
space_data = bpy.context.space_data
if True in space_data.layers_local_view:
- self.report({'INFO'}, 'Global Perspective modes only unable to continue.')
- return {'FINISHED'}
-
- # Make variable that is the current .blend file main data blocks
- blend_data = context.blend_data
+ self.report({'INFO'},
+ "Works with Global Perspective modes only. Operation Cancelled")
+ return {'CANCELLLED'}
# Make variable that is the active object selected by user
active_object = context.active_object
@@ -527,8 +528,6 @@ class GenerateCloud(Operator):
scattering = 2.5
pointDensityRadiusFactor = .37
densityScale = 1.5
- noiseScale = 1
-
# What should we do?
WhatToDo = getActionToDo(active_object)
@@ -540,9 +539,9 @@ class GenerateCloud(Operator):
bpy.ops.object.hide_view_clear()
cloudMembers = active_object.children
-
createdObjects = []
definitionObjects = []
+
for member in cloudMembers:
applyScaleRotLoc(scene, member)
if member["CloudMember"] == "CreatedObj":
@@ -562,19 +561,18 @@ class GenerateCloud(Operator):
totallyDeleteObject(scene, mainObj)
# 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:
eachMember.draw_type = 'SOLID'
eachMember.select = True
eachMember.hide_render = False
elif WhatToDo == 'CLOUD_CONVERT_TO_MESH':
-
cloudParticles = active_object.particle_systems.active
bounds = active_object.parent
- ###############Create CloudPnts for putting points in#########
+ # Create CloudPnts for putting points in #
# Create a new object cloudPnts
cloudPnts = addNewObject(scene, "CloudPoints", bounds)
cloudPnts["CloudMember"] = "CreatedObj"
@@ -582,38 +580,37 @@ class GenerateCloud(Operator):
cloudPnts.hide_render = True
makeParent(bounds, cloudPnts, scene)
-
convertParticlesToMesh(scene, cloudParticles, cloudPnts, True)
-
removeParticleSystemFromObj(scene, active_object)
pDensity = getpdensitytexture(bounds)
pDensity.point_density.point_source = 'OBJECT'
pDensity.point_density.object = cloudPnts
- #Let's resize the bound box to be more accurate.
+ # Let's resize the bound box to be more accurate
how_much_bigger = pDensity.point_density.radius
makeObjectIntoBoundBox(scene, bounds, how_much_bigger, cloudPnts)
else:
# Generate Cloud
- ###############Create Combined Object bounds##################
- # Make a list of all Selected objects.
+ # Create Combined Object bounds #
+ # Make a list of all Selected objects
selectedObjects = bpy.context.selected_objects
if not selectedObjects:
selectedObjects = [bpy.context.active_object]
# Create a new object bounds
- bounds = addNewObject(scene,
- "CloudBounds",
- selectedObjects[0])
+ bounds = addNewObject(
+ scene, "CloudBounds",
+ selectedObjects[0]
+ )
bounds.draw_type = 'BOUNDS'
bounds.hide_render = False
# Just add a Definition Property designating this
- # as the blend_data object.
+ # as the blend_data object
bounds["CloudMember"] = "MainObj"
# Since we used iteration 0 to copy with object we
@@ -621,7 +618,7 @@ class GenerateCloud(Operator):
firstObject = selectedObjects[0]
del selectedObjects[0]
- # Apply location Rotation and Scale to all objects involved.
+ # Apply location Rotation and Scale to all objects involved
applyScaleRotLoc(scene, bounds)
for each in selectedObjects:
applyScaleRotLoc(scene, each)
@@ -629,23 +626,23 @@ class GenerateCloud(Operator):
# Let's combine all of them together.
combineObjects(scene, bounds, selectedObjects)
- # Let's add some property info to the objects.
+ # Let's add some property info to the objects
for selObj in selectedObjects:
- selObj["CloudMember"] = "DefinitioinObj"
- selObj.name = "DefinitioinObj"
+ selObj["CloudMember"] = "DefinitionObj"
+ selObj.name = "DefinitionObj"
selObj.draw_type = 'WIRE'
selObj.hide_render = True
selObj.hide = True
makeParent(bounds, selObj, scene)
# Do the same to the 1. object since it is no longer in list.
- firstObject["CloudMember"] = "DefinitioinObj"
- firstObject.name = "DefinitioinObj"
+ firstObject["CloudMember"] = "DefinitionObj"
+ firstObject.name = "DefinitionObj"
firstObject.draw_type = 'WIRE'
firstObject.hide_render = True
makeParent(bounds, firstObject, scene)
- ###############Create Cloud for putting Cloud Mesh############
+ # Create Cloud for putting Cloud Mesh #
# Create a new object cloud.
cloud = addNewObject(scene, "CloudMesh", bounds)
cloud["CloudMember"] = "CreatedObj"
@@ -657,24 +654,23 @@ class GenerateCloud(Operator):
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='SELECT')
- #Don't subdivide object or smooth if smoothing box not checked.
+ # Don't subdivide object or smooth if smoothing box not checked.
if scene.cloudsmoothing:
bpy.ops.mesh.subdivide(number_cuts=2, fractal=0, smoothness=1)
- # bpy.ops.object.transform_apply(location=True)
bpy.ops.mesh.vertices_smooth(repeat=20)
bpy.ops.mesh.tris_convert_to_quads()
bpy.ops.mesh.faces_shade_smooth()
bpy.ops.object.editmode_toggle()
- ###############Create Particles in cloud obj##################
+ # Create Particles in cloud obj #
- # Set time to 0.
+ # Set time to 0
scene.frame_current = 0
- # Add a new particle system.
+ # Add a new particle system
bpy.ops.object.particle_system_add()
- #Particle settings setting it up!
+ # Particle settings setting it up!
cloudParticles = cloud.particle_systems.active
cloudParticles.name = "CloudParticles"
cloudParticles.settings.frame_start = 0
@@ -687,11 +683,11 @@ class GenerateCloud(Operator):
cloudParticles.settings.physics_type = 'NEWTON'
cloudParticles.settings.normal_factor = 0
- #Gravity does not effect the particle system
+ # Gravity does not affect the particle system
eWeights = cloudParticles.settings.effector_weights
eWeights.gravity = 0
- ####################Create Volume Material####################
+ # Create Volume Material #
# Deselect All
bpy.ops.object.select_all(action='DESELECT')
@@ -699,23 +695,23 @@ class GenerateCloud(Operator):
bounds.select = True
scene.objects.active = bounds
- # Turn bounds object into a box. Use itself as a reference.
+ # Turn bounds object into a box. Use itself as a reference
makeObjectIntoBoundBox(scene, bounds, 1.0, bounds)
- # Delete all material slots in bounds object.
+ # Delete all material slots in bounds object
for i in range(len(bounds.material_slots)):
bounds.active_material_index = i - 1
bpy.ops.object.material_slot_remove()
- # Add a new material.
- cloudMaterial = blend_data.materials.new("CloudMaterial")
+ # Add a new material
+ cloudMaterial = bpy.data.materials.new("CloudMaterial")
bpy.ops.object.material_slot_add()
bounds.material_slots[0].material = cloudMaterial
# Set time
scene.frame_current = 1
- #Set Up Material for Blender Internal
+ # Set Up Material for Blender Internal
if bpy.context.scene.render.engine == 'BLENDER_RENDER':
# Set Up the Cloud Material
cloudMaterial.name = "CloudMaterial"
@@ -731,7 +727,7 @@ class GenerateCloud(Operator):
# Add a texture
# vMaterialTextureSlots = cloudMaterial.texture_slots # UNUSED
- cloudtex = blend_data.textures.new("CloudTex", type='CLOUDS')
+ cloudtex = bpy.data.textures.new("CloudTex", type='CLOUDS')
cloudtex.noise_type = 'HARD_NOISE'
cloudtex.noise_scale = 2
mtex = cloudMaterial.texture_slots.add()
@@ -743,7 +739,7 @@ class GenerateCloud(Operator):
scene.frame_current = 1
# Add a Point Density texture
- pDensity = blend_data.textures.new("CloudPointDensity", 'POINT_DENSITY')
+ pDensity = bpy.data.textures.new("CloudPointDensity", 'POINT_DENSITY')
mtex = cloudMaterial.texture_slots.add()
mtex.texture = pDensity
@@ -759,21 +755,20 @@ class GenerateCloud(Operator):
pDensity.use_color_ramp = True
pRamp = pDensity.color_ramp
- #pRamp.use_interpolation = 'LINEAR'
+ # pRamp.use_interpolation = 'LINEAR'
pRampElements = pRamp.elements
- #pRampElements[1].position = .9
- #pRampElements[1].color = 0.18, 0.18, 0.18, 0.8
+ # pRampElements[1].position = .9
+ # pRampElements[1].color = 0.18, 0.18, 0.18, 0.8
bpy.ops.texture.slot_move(type='UP')
- #Set Up Material for Cycles Engine
+ # Set Up Material for Cycles Engine
elif bpy.context.scene.render.engine == 'CYCLES':
VolumePropertiesGroup = CreateNodeGroup('CloudGen_VolumeProperties')
CloudTexPropertiesGroup = CreateNodeGroup('CloudGen_TextureProperties')
cloudMaterial.name = "CloudMaterial"
# Add a texture
- # vMaterialTextureSlots = cloudMaterial.texture_slots # UNUSED
- cloudtex = blend_data.textures.new("CloudTex", type='CLOUDS')
+ cloudtex = bpy.data.textures.new("CloudTex", type='CLOUDS')
cloudtex.noise_type = 'HARD_NOISE'
cloudtex.noise_scale = 2
@@ -783,46 +778,30 @@ class GenerateCloud(Operator):
cloudMatNodes.clear()
outputNode = cloudMatNodes.new('ShaderNodeOutputMaterial')
- outputNode.location = (200,300)
+ outputNode.location = (200, 300)
tranparentNode = cloudMatNodes.new('ShaderNodeBsdfTransparent')
- tranparentNode.location = (0,300)
+ tranparentNode.location = (0, 300)
volumeGroup = cloudMatNodes.new("ShaderNodeGroup")
volumeGroup.node_tree = VolumePropertiesGroup
- volumeGroup.location = (0,150)
+ volumeGroup.location = (0, 150)
cloudTexGroup = cloudMatNodes.new("ShaderNodeGroup")
cloudTexGroup.node_tree = CloudTexPropertiesGroup
- cloudTexGroup.location = (-200,150)
+ cloudTexGroup.location = (-200, 150)
PointDensityNode = cloudMatNodes.new("ShaderNodeTexPointDensity")
- PointDensityNode.location = (-400,150)
+ PointDensityNode.location = (-400, 150)
PointDensityNode.resolution = 100
PointDensityNode.space = 'OBJECT'
PointDensityNode.interpolation = 'Linear'
-# PointDensityNode.color_source = 'CONSTANT'
-
- cloudTree.links.new(outputNode.inputs[0],tranparentNode.outputs[0])
- cloudTree.links.new(outputNode.inputs[1],volumeGroup.outputs[0])
- cloudTree.links.new(volumeGroup.inputs[0],cloudTexGroup.outputs[0])
- cloudTree.links.new(cloudTexGroup.inputs[1],PointDensityNode.outputs[1])
-
- #PointDensityNode.point_source = 'PARTICLE_SYSTEM'
- #VolumePropsNode = cloudMatNodes.new(VolumePropertiesGroup)
- #VolumePropsNode.location = (-200,0)
-
-
- #tree = bpy.data.materials['CloudMaterial'].node_tree
- #group = bpy.data.groups.data.node_groups['CloudGen_VolumeProperties']
- #newgroup = tree.nodes.new("ShaderNodeGroup")
- #newgroup.node_tree = bpy.data.node_groups['CloudGen_VolumeProperties']
- #ramp = tree.nodes.new('ShaderNodeValToRGB')
- #cramp = ramp.color_ramp
+ # PointDensityNode.color_source = 'CONSTANT'
- #mport bpy
- #obj = bpy.data.objects['CloudBounds']
- #(obj.dimensions[0] * obj.dimensions[1] * obj.dimensions[2])
+ cloudTree.links.new(outputNode.inputs[0], tranparentNode.outputs[0])
+ cloudTree.links.new(outputNode.inputs[1], volumeGroup.outputs[0])
+ cloudTree.links.new(volumeGroup.inputs[0], cloudTexGroup.outputs[0])
+ cloudTree.links.new(cloudTexGroup.inputs[1], PointDensityNode.outputs[1])
# Estimate the number of particles for the size of bounds.
volumeBoundBox = (bounds.dimensions[0] * bounds.dimensions[1] * bounds.dimensions[2])
@@ -831,10 +810,8 @@ class GenerateCloud(Operator):
numParticles = maxNumOfPoints
if numParticles < 10000:
numParticles = int(numParticles + 15 * volumeBoundBox)
- print(numParticles)
- # Set the number of particles according to the volume
- # of bounds.
+ # Set the number of particles according to the volume of bounds
cloudParticles.settings.count = numParticles
PDensityRadius = (.00013764 * volumeBoundBox + .3989) * pointDensityRadiusFactor
@@ -855,7 +832,7 @@ class GenerateCloud(Operator):
scene.frame_current = 1
if not scene.cloudparticles:
- ###############Create CloudPnts for putting points in#########
+ # Create CloudPnts for putting points in #
# Create a new object cloudPnts
cloudPnts = addNewObject(scene, "CloudPoints", bounds)
cloudPnts["CloudMember"] = "CreatedObj"
@@ -863,7 +840,6 @@ class GenerateCloud(Operator):
cloudPnts.hide_render = True
makeParent(bounds, cloudPnts, scene)
-
convertParticlesToMesh(scene, cloudParticles, cloudPnts, True)
# Add a modifier.
@@ -890,7 +866,6 @@ class GenerateCloud(Operator):
removeParticleSystemFromObj(scene, cloud)
else:
-
if bpy.context.scene.render.engine == 'BLENDER_RENDER':
pDensity.point_density.point_source = 'PARTICLE_SYSTEM'
pDensity.point_density.object = cloud
@@ -902,7 +877,6 @@ class GenerateCloud(Operator):
if bpy.context.scene.render.engine == 'BLENDER_RENDER':
if scene.cloud_type == '1': # Cumulous
- print("Cumulous")
mVolume.density_scale = 2.22
pDensity.point_density.turbulence_depth = 10
pDensity.point_density.turbulence_strength = 6.3
@@ -911,13 +885,11 @@ class GenerateCloud(Operator):
pDensity.point_density.radius = pDensity.point_density.radius + 0.1
elif scene.cloud_type == '2': # Cirrus
- print("Cirrus")
pDensity.point_density.turbulence_strength = 22
mVolume.transmission_color = 3.5, 3.5, 3.5
mVolume.scattering = 0.13
elif scene.cloud_type == '3': # Explosion
- print("Explosion")
mVolume.emission = 1.42
mtex.use_rgb_to_intensity = False
pRampElements[0].position = 0.825
@@ -932,30 +904,20 @@ class GenerateCloud(Operator):
pRampElement3 = pRampElements.new(0.669)
pRampElement3.color = 0.0, 0.0, 0.040, 1
-
elif bpy.context.scene.render.engine == 'CYCLES':
volumeGroup.inputs['Absorption Multiply'].default_value = 50
volumeGroup.inputs['Absorption Color'].default_value = (1.0, 1.0, 1.0, 1.0)
- volumeGroup.inputs['Scatter Multiply'].default_value = 30
+ volumeGroup.inputs['Scatter Multiply'].default_value = 30
volumeGroup.inputs['Scatter Color'].default_value = (.58, .58, .58, 1.0)
volumeGroup.inputs['Emission Amount'].default_value = .1
- volumeGroup.inputs['Cloud Brightness'].default_value = 1.3
- noiseCloudScale = volumeBoundBox*(-.001973)+5.1216
+ volumeGroup.inputs['Cloud Brightness'].default_value = 1.3
+ noiseCloudScale = volumeBoundBox * (-.001973) + 5.1216
if noiseCloudScale < .05:
noiseCloudScale = .05
- cloudTexGroup.inputs['Scale'].default_value = noiseCloudScale
-
- if scene.cloud_type == '1': # Cumulous
- print("Cumulous")
-
- elif scene.cloud_type == '2': # Cirrus
- print("Cirrus")
+ cloudTexGroup.inputs['Scale'].default_value = noiseCloudScale
- elif scene.cloud_type == '3': # Explosion
- print("Explosion")
-
- #to cloud to view in cycles in render mode we need to hide geometry meshes...
+ # to cloud to view in cycles in render mode we need to hide geometry meshes...
firstObject.hide = True
cloud.hide = True
@@ -963,15 +925,22 @@ class GenerateCloud(Operator):
bounds.select = True
scene.objects.active = bounds
- #Let's resize the bound box to be more accurate.
+ # Let's resize the bound box to be more accurate.
how_much_bigger = PDensityRadius + 0.1
- #If it's a particle cloud use cloud mesh if otherwise use point mesh
+ # If it's a particle cloud use cloud mesh if otherwise use point mesh
if not scene.cloudparticles:
makeObjectIntoBoundBox(scene, bounds, how_much_bigger, cloudPnts)
else:
makeObjectIntoBoundBox(scene, bounds, how_much_bigger, cloud)
+ cloud_string = "Cumulous" if scene.cloud_type == '1' else "Cirrus" if \
+ scene.cloud_type == '2' else "Stratus" if \
+ scene.cloud_type == '0' else "Explosion"
+
+ self.report({'INFO'},
+ "Created the cloud of type {}".format(cloud_string))
+
return {'FINISHED'}
@@ -979,30 +948,32 @@ def register():
bpy.utils.register_module(__name__)
bpy.types.Scene.cloudparticles = BoolProperty(
- name="Particles",
- description="Generate Cloud as Particle System",
- default=False)
-
+ name="Particles",
+ description="Generate Cloud as Particle System",
+ default=False
+ )
bpy.types.Scene.cloudsmoothing = BoolProperty(
- name="Smoothing",
- description="Smooth Resultant Geometry From Gen Cloud Operation",
- default=True)
-
+ name="Smoothing",
+ description="Smooth Resultant Geometry From Gen Cloud Operation",
+ default=True
+ )
bpy.types.Scene.cloud_type = EnumProperty(
- name="Type",
- description="Select the type of cloud to create with material settings",
- items=[("0", "Stratus", "Generate Stratus_foggy Cloud"),
- ("1", "Cumulous", "Generate Cumulous_puffy Cloud"),
- ("2", "Cirrus", "Generate Cirrus_wispy Cloud"),
- ("3", "Explosion", "Generate Explosion"),
- ],
- default='0')
+ name="Type",
+ description="Select the type of cloud to create with material settings",
+ items=[("0", "Stratus", "Generate Stratus (foggy) Cloud"),
+ ("1", "Cumulous", "Generate Cumulous (puffy) Cloud"),
+ ("2", "Cirrus", "Generate Cirrus (wispy) Cloud"),
+ ("3", "Explosion", "Generate Explosion"),
+ ],
+ default='0'
+ )
def unregister():
bpy.utils.unregister_module(__name__)
del bpy.types.Scene.cloudparticles
+ del bpy.types.Scene.cloudsmoothing
del bpy.types.Scene.cloud_type