From 2fb1729cab5ad961e65e118f35e2e1420d1fb065 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 11 Aug 2021 09:07:41 -0300 Subject: Real Snow Updates - make the snow mesh calculation faster (by @drewp) - fix typos in comments - bump version to 1.2 and update authors Resolves T90594 Co-authored-by: Drew Perttula --- real_snow.py | 76 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'real_snow.py') diff --git a/real_snow.py b/real_snow.py index f1091b2d..8f1b9ffd 100644 --- a/real_snow.py +++ b/real_snow.py @@ -19,12 +19,12 @@ bl_info = { "name": "Real Snow", "description": "Generate snow mesh", - "author": "Wolf ", - "version": (1, 1), + "author": "Marco Pavanello, Drew Perttula", + "version": (1, 2), "blender": (2, 83, 0), "location": "View 3D > Properties Panel", - "doc_url": "https://github.com/macio97/Real-Snow", - "tracker_url": "https://github.com/macio97/Real-Snow/issues", + "doc_url": "https://github.com/marcopavanello/real-snow", + "tracker_url": "https://github.com/marcopavanello/real-snow/issues", "support": "COMMUNITY", "category": "Object", } @@ -86,17 +86,17 @@ class SNOW_OT_Create(Operator): height = context.scene.snow.height vertices = context.scene.snow.vertices - # get list of selected objects except non-mesh objects + # Get a list of selected objects, except non-mesh objects input_objects = [obj for obj in context.selected_objects if obj.type == 'MESH'] snow_list = [] - # start UI progress bar + # Start UI progress bar length = len(input_objects) context.window_manager.progress_begin(0, 10) - timer=0 + timer = 0 for obj in input_objects: - # timer + # Timer context.window_manager.progress_update(timer) - # duplicate mesh + # Duplicate mesh bpy.ops.object.select_all(action='DESELECT') obj.select_set(True) context.view_layer.objects.active = obj @@ -113,14 +113,14 @@ class SNOW_OT_Create(Operator): bm_copy = bm_orig.copy() bm_copy.transform(obj.matrix_world) bm_copy.normal_update() - # get faces data + # Get faces data delete_faces(vertices, bm_copy, snow_object) ballobj = add_metaballs(context, height, snow_object) context.view_layer.objects.active = snow_object surface_area = area(snow_object) snow = add_particles(context, surface_area, height, coverage, snow_object, ballobj) add_modifiers(snow) - # place inside collection + # Place inside collection context.view_layer.active_layer_collection = context.view_layer.layer_collection if "Snow" not in context.scene.collection.children: coll = bpy.data.collections.new("Snow") @@ -130,17 +130,17 @@ class SNOW_OT_Create(Operator): coll.objects.link(snow) context.view_layer.layer_collection.collection.objects.unlink(snow) add_material(snow) - # parent with object + # Parent with object snow.parent = obj snow.matrix_parent_inverse = obj.matrix_world.inverted() - # add snow to list + # Add snow to list snow_list.append(snow) - # update progress bar + # Update progress bar timer += 0.1 / length - # select created snow meshes + # Select created snow meshes for s in snow_list: s.select_set(True) - # end progress bar + # End progress bar context.window_manager.progress_end() return {'FINISHED'} @@ -148,7 +148,7 @@ class SNOW_OT_Create(Operator): def add_modifiers(snow): bpy.ops.object.transform_apply(location=False, scale=True, rotation=False) - # decimate the mesh to get rid of some visual artifacts + # Decimate the mesh to get rid of some visual artifacts snow.modifiers.new("Decimate", 'DECIMATE') snow.modifiers["Decimate"].ratio = 0.5 snow.modifiers.new("Subdiv", "SUBSURF") @@ -158,21 +158,21 @@ def add_modifiers(snow): def add_particles(context, surface_area: float, height: float, coverage: float, snow_object: bpy.types.Object, ballobj: bpy.types.Object): - # approximate the number of particles to be emitted - number = int(surface_area*50*(height**-2)*((coverage/100)**2)) + # Approximate the number of particles to be emitted + number = int(surface_area * 50 * (height ** -2) * ((coverage / 100) ** 2)) bpy.ops.object.particle_system_add() particles = snow_object.particle_systems[0] psettings = particles.settings psettings.type = 'HAIR' psettings.render_type = 'OBJECT' - # generate random number for seed + # Generate random number for seed random_seed = random.randint(0, 1000) particles.seed = random_seed - # set particles object + # Set particles object psettings.particle_size = height psettings.instance_object = ballobj psettings.count = number - # convert particles to mesh + # Convert particles to mesh bpy.ops.object.select_all(action='DESELECT') context.view_layer.objects.active = ballobj ballobj.select_set(True) @@ -192,8 +192,8 @@ def add_metaballs(context, height: float, snow_object: bpy.types.Object) -> bpy. ball = bpy.data.metaballs.new(ball_name) ballobj = bpy.data.objects.new(ball_name, ball) bpy.context.scene.collection.objects.link(ballobj) - # these settings have proven to work on a large amount of scenarios - ball.resolution = 0.7*height+0.3 + # These settings have proven to work on a large amount of scenarios + ball.resolution = 0.7 * height + 0.3 ball.threshold = 1.3 element = ball.elements.new() element.radius = 1.5 @@ -203,22 +203,22 @@ def add_metaballs(context, height: float, snow_object: bpy.types.Object) -> bpy. def delete_faces(vertices, bm_copy, snow_object: bpy.types.Object): - # find upper faces + # Find upper faces if vertices: - selected_faces = [face.index for face in bm_copy.faces if face.select] - # based on a certain angle, find all faces not pointing up - down_faces = [face.index for face in bm_copy.faces if Vector((0, 0, -1.0)).angle(face.normal, 4.0) < (math.pi/2.0+0.5)] + selected_faces = set(face.index for face in bm_copy.faces if face.select) + # Based on a certain angle, find all faces not pointing up + down_faces = set(face.index for face in bm_copy.faces if Vector((0, 0, -1.0)).angle(face.normal, 4.0) < (math.pi / 2.0 + 0.5)) bm_copy.free() bpy.ops.mesh.select_all(action='DESELECT') - # select upper faces + # Select upper faces mesh = bmesh.from_edit_mesh(snow_object.data) for face in mesh.faces: if vertices: - if not face.index in selected_faces: + if face.index not in selected_faces: face.select = True if face.index in down_faces: face.select = True - # delete unneccessary faces + # Delete unnecessary faces faces_select = [face for face in mesh.faces if face.select] bmesh.ops.delete(mesh, geom=faces_select, context='FACES_KEEP_BOUNDARY') mesh.free() @@ -236,16 +236,16 @@ def area(obj: bpy.types.Object) -> float: def add_material(obj: bpy.types.Object): mat_name = "Snow" - # if material doesn't exist, create it + # If material doesn't exist, create it if mat_name in bpy.data.materials: bpy.data.materials[mat_name].name = mat_name+".001" mat = bpy.data.materials.new(mat_name) mat.use_nodes = True nodes = mat.node_tree.nodes - # delete all nodes + # Delete all nodes for node in nodes: nodes.remove(node) - # add nodes + # Add nodes output = nodes.new('ShaderNodeOutputMaterial') principled = nodes.new('ShaderNodeBsdfPrincipled') vec_math = nodes.new('ShaderNodeVectorMath') @@ -265,7 +265,7 @@ def add_material(obj: bpy.types.Object): noise3 = nodes.new('ShaderNodeTexNoise') mapping = nodes.new('ShaderNodeMapping') coord = nodes.new('ShaderNodeTexCoord') - # change location + # Change location output.location = (100, 0) principled.location = (-200, 500) vec_math.location = (-400, 400) @@ -285,7 +285,7 @@ def add_material(obj: bpy.types.Object): noise3.location = (-1500, -400) mapping.location = (-1700, 0) coord.location = (-1900, 0) - # change node parameters + # Change node parameters principled.distribution = "MULTI_GGX" principled.subsurface_method = "RANDOM_WALK" principled.inputs[0].default_value[0] = 0.904 @@ -332,7 +332,7 @@ def add_material(obj: bpy.types.Object): mapping.inputs[3].default_value[0] = 12 mapping.inputs[3].default_value[1] = 12 mapping.inputs[3].default_value[2] = 12 - # link nodes + # Link nodes link = mat.node_tree.links link.new(principled.outputs[0], output.inputs[0]) link.new(vec_math.outputs[0], principled.inputs[2]) @@ -355,7 +355,7 @@ def add_material(obj: bpy.types.Object): link.new(mapping.outputs[0], noise2.inputs[0]) link.new(mapping.outputs[0], noise3.inputs[0]) link.new(coord.outputs[3], mapping.inputs[0]) - # set displacement and add material + # Set displacement and add material mat.cycles.displacement_method = "DISPLACEMENT" obj.data.materials.append(mat) -- cgit v1.2.3