diff options
-rw-r--r-- | release/scripts/op/object.py | 71 | ||||
-rw-r--r-- | release/scripts/ui/space_view3d.py | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 10 |
3 files changed, 77 insertions, 5 deletions
diff --git a/release/scripts/op/object.py b/release/scripts/op/object.py index 6fb15f1504c..5d84c0f1222 100644 --- a/release/scripts/op/object.py +++ b/release/scripts/op/object.py @@ -379,11 +379,78 @@ class JoinUVs(bpy.types.Operator): self._main(context) return {'FINISHED'} -if __name__ == "__main__": - bpy.ops.uv.simple_operator() +class MakeDupliFace(bpy.types.Operator): + '''Make linked objects into dupli-faces''' + bl_idname = "object.make_dupli_face" + bl_label = "Make DupliFace" + + def poll(self, context): + obj = context.active_object + return (obj and obj.type == 'MESH') + + def _main(self, context): + from Mathutils import Vector + from math import sqrt + + SCALE_FAC = 0.01 + offset = 0.5 * SCALE_FAC + base_tri = Vector(-offset, -offset, 0.0), Vector(-offset, offset, 0.0), Vector(offset, offset, 0.0), Vector(offset, -offset, 0.0) + + def matrix_to_quat(matrix): + # scale = matrix.median_scale + trans = matrix.translation_part() + rot = matrix.rotation_part() # also contains scale + + return [(rot * b) + trans for b in base_tri] + scene = bpy.context.scene + linked = {} + for obj in bpy.context.selected_objects: + data = obj.data + if data: + linked.setdefault(data, []).append(obj) + + for data, objects in linked.items(): + face_verts = [axis for obj in objects for v in matrix_to_quat(obj.matrix) for axis in v] + faces = list(range(int(len(face_verts) / 3))) + + mesh = bpy.data.meshes.new(data.name + "_dupli") + + mesh.add_geometry(int(len(face_verts) / 3), 0, int(len(face_verts) / (4 * 3))) + mesh.verts.foreach_set("co", face_verts) + mesh.faces.foreach_set("verts_raw", faces) + mesh.update() # generates edge data + + # pick an object to use + obj = objects[0] + + ob_new = bpy.data.objects.new(mesh.name, 'MESH') + ob_new.data = mesh + base = scene.objects.link(ob_new) + base.layers[:] = obj.layers + + ob_inst = bpy.data.objects.new(data.name, obj.type) + ob_inst.data = data + base = scene.objects.link(ob_inst) + base.layers[:] = obj.layers + + for obj in objects: + scene.objects.unlink(obj) + + ob_new.dupli_type = 'FACES' + ob_inst.parent = ob_new + ob_new.use_dupli_faces_scale = True + ob_new.dupli_faces_scale = 1.0 / SCALE_FAC + + def execute(self, context): + self._main(context) + return {'FINISHED'} + +# if __name__ == "__main__": +# bpy.ops.uv.simple_operator() bpy.types.register(SelectPattern) bpy.types.register(SubdivisionSet) bpy.types.register(ShapeTransfer) bpy.types.register(JoinUVs) +bpy.types.register(MakeDupliFace) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index 880ab51b87f..b6a8af8debe 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -659,6 +659,7 @@ class VIEW3D_MT_object(bpy.types.Menu): layout.operator("object.delete", text="Delete...") layout.operator("object.proxy_make", text="Make Proxy...") layout.menu("VIEW3D_MT_make_links", text="Make Links...") + layout.operator("object.make_dupli_face", text="Make Dupliface...") layout.operator_menu_enum("object.make_local", "type", text="Make Local...") layout.menu("VIEW3D_MT_make_single_user") diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index f61bf8590eb..7a4f8a4cdad 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -130,18 +130,18 @@ static PointerRNA rna_Scene_objects_get(CollectionPropertyIterator *iter) return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((Base*)internal->link)->object); } -static void rna_Scene_link_object(Scene *scene, ReportList *reports, Object *ob) +static Base *rna_Scene_link_object(Scene *scene, ReportList *reports, Object *ob) { Base *base; if (ob->type != OB_EMPTY && ob->data==NULL) { BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not an Empty type and has no Object Data set."); - return; + return NULL; } if (object_in_scene(ob, scene)) { BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is already in scene \"%s\".", ob->id.name+2, scene->id.name+2); - return; + return NULL; } base= scene_add_base(scene, ob); @@ -152,6 +152,8 @@ static void rna_Scene_link_object(Scene *scene, ReportList *reports, Object *ob) ob->recalc |= OB_RECALC; DAG_scene_sort(scene); + + return base; } static void rna_Scene_unlink_object(Scene *scene, bContext *C, ReportList *reports, Object *ob) @@ -2530,6 +2532,8 @@ static void rna_def_scene_objects(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); parm= RNA_def_pointer(func, "object", "Object", "", "Object to add to scene."); RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "base", "ObjectBase", "", "The newly created base."); + RNA_def_function_return(func, parm); func= RNA_def_function(srna, "unlink", "rna_Scene_unlink_object"); RNA_def_function_ui_description(func, "Unlink object from scene."); |