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:
Diffstat (limited to 'add_advanced_objects_menu/add_mesh_aggregate.py')
-rw-r--r--add_advanced_objects_menu/add_mesh_aggregate.py338
1 files changed, 338 insertions, 0 deletions
diff --git a/add_advanced_objects_menu/add_mesh_aggregate.py b/add_advanced_objects_menu/add_mesh_aggregate.py
new file mode 100644
index 00000000..6072cb9c
--- /dev/null
+++ b/add_advanced_objects_menu/add_mesh_aggregate.py
@@ -0,0 +1,338 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# Simple aggregate of particles / meshes
+# Copy the selected objects on the active object
+# Based on the position of the cursor and a defined volume
+# Allows to control growth by using a Build modifier
+
+bl_info = {
+ "name": "Aggregate Mesh",
+ "author": "liero",
+ "version": (0, 0, 5),
+ "blender": (2, 7, 0),
+ "location": "View3D > Tool Shelf",
+ "description": "Adds geometry to a mesh like in DLA aggregators",
+ "category": "Object"}
+
+
+import bpy
+import bmesh
+from random import (
+ choice,
+ gauss,
+ seed,
+ )
+from mathutils import Matrix
+from bpy.props import (
+ BoolProperty,
+ FloatProperty,
+ IntProperty,
+ )
+from bpy.types import Operator
+
+
+def use_random_seed(self):
+ seed(self.rSeed)
+ return
+
+
+def rg(n):
+ return (round(gauss(0, n), 2))
+
+
+def remover(sel=False):
+ bpy.ops.object.editmode_toggle()
+ if sel:
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.remove_doubles(threshold=0.0001)
+ bpy.ops.object.mode_set()
+
+
+class OBJECT_OT_agregate_mesh(Operator):
+ bl_idname = "object.agregate_mesh"
+ bl_label = "Aggregate"
+ bl_description = ("Adds geometry to a mesh like in DLA aggregators\n"
+ "Needs at least two selected Mesh objects")
+ bl_options = {'REGISTER', 'UNDO', 'PRESET'}
+
+ volX = FloatProperty(
+ name="Volume X",
+ min=0.1, max=25,
+ default=3,
+ description="The cloud around cursor"
+ )
+ volY = FloatProperty(
+ name="Volume Y",
+ min=0.1, max=25,
+ default=3,
+ description="The cloud around cursor"
+ )
+ volZ = FloatProperty(
+ name="Volume Z",
+ min=0.1, max=25,
+ default=3,
+ description="The cloud around cursor"
+ )
+ baseSca = FloatProperty(
+ name="Scale",
+ min=0.01, max=5,
+ default=.25,
+ description="Particle Scale"
+ )
+ varSca = FloatProperty(
+ name="Var",
+ min=0, max=1,
+ default=0,
+ description="Particle Scale Variation"
+ )
+ rotX = FloatProperty(
+ name="Rot Var X",
+ min=0, max=2,
+ default=0,
+ description="X Rotation Variation"
+ )
+ rotY = FloatProperty(
+ name="Rot Var Y",
+ min=0, max=2,
+ default=0,
+ description="Y Rotation Variation"
+ )
+ rotZ = FloatProperty(
+ name="Rot Var Z",
+ min=0, max=2,
+ default=1,
+ description="Z Rotation Variation"
+ )
+ rSeed = IntProperty(
+ name="Random seed",
+ min=0, max=999999,
+ default=1,
+ description="Seed to feed random values"
+ )
+ numP = IntProperty(
+ name="Number",
+ min=1,
+ max=9999, soft_max=500,
+ default=50,
+ description="Number of particles"
+ )
+ nor = BoolProperty(
+ name="Normal Oriented",
+ default=False,
+ description="Align Z axis with Faces normals"
+ )
+ cent = BoolProperty(
+ name="Use Face Center",
+ default=False,
+ description="Center on Faces"
+ )
+ track = BoolProperty(
+ name="Cursor Follows",
+ default=False,
+ description="Cursor moves as structure grows / more compact results"
+ )
+ anim = BoolProperty(
+ name="Animatable",
+ default=False,
+ description="Sort faces so you can regrow with Build Modifier, materials are lost"
+ )
+ refresh = BoolProperty(
+ name="Update",
+ default=False
+ )
+ auto_refresh = BoolProperty(
+ name="Auto",
+ description="Auto update spline",
+ default=False
+ )
+
+ def draw(self, context):
+ layout = self.layout
+ col = layout.column(align=True)
+ row = col.row(align=True)
+
+ if self.auto_refresh is False:
+ self.refresh = False
+ elif self.auto_refresh is True:
+ self.refresh = True
+
+ row.prop(self, "auto_refresh", toggle=True, icon="AUTO")
+ row.prop(self, "refresh", toggle=True, icon="FILE_REFRESH")
+
+ col = layout.column(align=True)
+ col.separator()
+
+ col = layout.column(align=True)
+ col.prop(self, "volX", slider=True)
+ col.prop(self, "volY", slider=True)
+ col.prop(self, "volZ", slider=True)
+
+ layout.label(text="Particles:")
+ col = layout.column(align=True)
+ col.prop(self, "baseSca", slider=True)
+ col.prop(self, "varSca", slider=True)
+
+ col = layout.column(align=True)
+ col.prop(self, "rotX", slider=True)
+ col.prop(self, "rotY", slider=True)
+ col.prop(self, "rotZ", slider=True)
+
+ col = layout.column(align=True)
+ col.prop(self, "rSeed", slider=False)
+ col.prop(self, "numP")
+
+ row = layout.row(align=True)
+ row.prop(self, "nor")
+ row.prop(self, "cent")
+
+ row = layout.row(align=True)
+ row.prop(self, "track")
+ row.prop(self, "anim")
+
+ @classmethod
+ def poll(cls, context):
+ return (len(bpy.context.selected_objects) > 1 and
+ bpy.context.object.type == 'MESH')
+
+ def invoke(self, context, event):
+ self.refresh = True
+ return self.execute(context)
+
+ def execute(self, context):
+ if not self.refresh:
+ return {'PASS_THROUGH'}
+
+ scn = bpy.context.scene
+ obj = bpy.context.active_object
+
+ use_random_seed(self)
+
+ mat = Matrix((
+ (1, 0, 0, 0),
+ (0, 1, 0, 0),
+ (0, 0, 1, 0),
+ (0, 0, 0, 1))
+ )
+ if obj.matrix_world != mat:
+ self.report({'WARNING'},
+ "Please, Apply transformations to Active Object first")
+ return{'FINISHED'}
+
+ par = [o for o in bpy.context.selected_objects if o.type == 'MESH' and o != obj]
+ if not par:
+ return{'FINISHED'}
+
+ bpy.ops.object.mode_set()
+ bpy.ops.object.select_all(action='DESELECT')
+ obj.select = True
+ msv = []
+
+ for i in range(len(obj.modifiers)):
+ msv.append(obj.modifiers[i].show_viewport)
+ obj.modifiers[i].show_viewport = False
+
+ cur = scn.cursor_location
+ for i in range(self.numP):
+
+ mes = choice(par).data
+ newobj = bpy.data.objects.new('nuevo', mes)
+ scn.objects.link(newobj)
+ origen = (rg(self.volX) + cur[0], rg(self.volY) + cur[1], rg(self.volZ) + cur[2])
+
+ cpom = obj.closest_point_on_mesh(origen)
+
+ if self.cent:
+ bm = bmesh.new()
+ bm.from_mesh(obj.data)
+ if hasattr(bm.verts, "ensure_lookup_table"):
+ bm.verts.ensure_lookup_table()
+ bm.faces.ensure_lookup_table()
+
+ newobj.location = bm.faces[cpom[3]].calc_center_median()
+
+ bm.free()
+ else:
+ newobj.location = cpom[1]
+
+ if self.nor:
+ newobj.rotation_mode = 'QUATERNION'
+ newobj.rotation_quaternion = cpom[1].to_track_quat('Z', 'Y')
+ newobj.rotation_mode = 'XYZ'
+ newobj.rotation_euler[0] += rg(self.rotX)
+ newobj.rotation_euler[1] += rg(self.rotY)
+ newobj.rotation_euler[2] += rg(self.rotZ)
+ else:
+ newobj.rotation_euler = (rg(self.rotX), rg(self.rotY), rg(self.rotZ))
+
+ newobj.scale = [self.baseSca + self.baseSca * rg(self.varSca)] * 3
+
+ if self.anim:
+ newobj.select = True
+ bpy.ops.object.make_single_user(type='SELECTED_OBJECTS', obdata=True)
+ bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
+
+ bme = bmesh.new()
+ bme.from_mesh(obj.data)
+
+ tmp = bmesh.new()
+ tmp.from_mesh(newobj.data)
+
+ for f in tmp.faces:
+ # z = len(bme.verts)
+ for v in f.verts:
+ bme.verts.new(list(v.co))
+ bme.faces.new(bme.verts[-len(f.verts):])
+
+ bme.to_mesh(obj.data)
+ remover(True)
+ # Note: foo.user_clear() is deprecated use do_unlink=True instead
+ bpy.data.meshes.remove(newobj.data, do_unlink=True)
+
+ else:
+ scn.objects.active = obj
+ newobj.select = True
+ bpy.ops.object.join()
+
+ if self.track:
+ cur = scn.cursor_location = cpom[1]
+
+ for i in range(len(msv)):
+ obj.modifiers[i].show_viewport = msv[i]
+
+ for o in par:
+ o.select = True
+
+ obj.select = True
+
+ if self.auto_refresh is False:
+ self.refresh = False
+
+ return{'FINISHED'}
+
+
+def register():
+ bpy.utils.register_class(OBJECT_OT_agregate_mesh)
+
+
+def unregister():
+ bpy.utils.unregister_class(OBJECT_OT_agregate_mesh)
+
+
+if __name__ == '__main__':
+ register()