diff options
Diffstat (limited to 'add_advanced_objects_menu/rope_alpha.py')
-rw-r--r-- | add_advanced_objects_menu/rope_alpha.py | 832 |
1 files changed, 832 insertions, 0 deletions
diff --git a/add_advanced_objects_menu/rope_alpha.py b/add_advanced_objects_menu/rope_alpha.py new file mode 100644 index 00000000..904168a1 --- /dev/null +++ b/add_advanced_objects_menu/rope_alpha.py @@ -0,0 +1,832 @@ +# Copyright (c) 2012 Jorge Hernandez - Melendez + +# ##### 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 ##### + +# TODO : prop names into English, add missing tooltips + +bl_info = { + "name": "Rope Creator", + "description": "Dynamic rope (with cloth) creator", + "author": "Jorge Hernandez - Melenedez", + "version": (0, 2, 2), + "blender": (2, 7, 3), + "location": "Left Toolbar > ClothRope", + "warning": "", + "wiki_url": "", + "category": "Add Mesh" +} + + +import bpy +from bpy.types import Operator +from bpy.props import ( + BoolProperty, + FloatProperty, + IntProperty, + ) + + +def desocultar(quien): + if quien == "todo": + for ob in bpy.data.objects: + ob.hide = False + else: + bpy.data.objects[quien].hide = False + + +def deseleccionar_todo(): + bpy.ops.object.select_all(action='DESELECT') + + +def seleccionar_todo(): + bpy.ops.object.select_all(action='SELECT') + + +def salir_de_editmode(): + if bpy.context.mode in ["EDIT", "EDIT_MESH", "EDIT_CURVE"]: + bpy.ops.object.mode_set(mode='OBJECT') + + +# Clear scene: +def reset_scene(): + desocultar("todo") + # playback to the start + bpy.ops.screen.frame_jump(end=False) + try: + salir_de_editmode() + except: + pass + try: + area = bpy.context.area + # expand everything in the outliner to be able to select children + old_type = area.type + area.type = 'OUTLINER' + bpy.ops.outliner.expanded_toggle() + + # restore the original context + area.type = old_type + + seleccionar_todo() + bpy.ops.object.delete(use_global=False) + + except Exception as e: + print("\n[rope_alpha]\nfunction: reset_scene\nError: %s" % e) + + +def entrar_en_editmode(): + if bpy.context.mode == "OBJECT": + bpy.ops.object.mode_set(mode='EDIT') + + +def select_all_in_edit_mode(ob): + if ob.mode != 'EDIT': + entrar_en_editmode() + bpy.ops.mesh.select_all(action="DESELECT") + bpy.context.tool_settings.mesh_select_mode = (True, False, False) + salir_de_editmode() + for v in ob.data.vertices: + if not v.select: + v.select = True + entrar_en_editmode() + + +def deselect_all_in_edit_mode(ob): + if ob.mode != 'EDIT': + entrar_en_editmode() + bpy.ops.mesh.select_all(action="DESELECT") + bpy.context.tool_settings.mesh_select_mode = (True, False, False) + salir_de_editmode() + for v in ob.data.vertices: + if not v.select: + v.select = False + entrar_en_editmode() + + +def which_vertex_are_selected(ob): + for v in ob.data.vertices: + if v.select: + print(str(v.index)) + print("Vertex " + str(v.index) + " is selected") + + +def seleccionar_por_nombre(nombre): + scn = bpy.context.scene + bpy.data.objects[nombre].select = True + + scn.objects.active = bpy.data.objects[nombre] + + +def deseleccionar_por_nombre(nombre): + bpy.data.objects[nombre].select = False + + +def crear_vertices(ob): + ob.data.vertices.add(1) + ob.data.update + + +def borrar_elementos_seleccionados(tipo): + if tipo == "vertices": + bpy.ops.mesh.delete(type='VERT') + + +def obtener_coords_vertex_seleccionados(): + coordenadas_de_vertices = [] + for ob in bpy.context.selected_objects: + if ob.type == 'MESH': + for v in ob.data.vertices: + if v.select: + coordenadas_de_vertices.append([v.co[0], v.co[1], v.co[2]]) + return coordenadas_de_vertices[0] + + +def crear_locator(pos): + bpy.ops.object.empty_add( + type='PLAIN_AXES', radius=1, view_align=False, + location=(pos[0], pos[1], pos[2]), + layers=(True, False, False, False, False, False, False, + False, False, False, False, False, False, False, + False, False, False, False, False, False) + ) + + +def extruir_vertices(longitud, cuantos_segmentos): + bpy.ops.mesh.extrude_region_move( + MESH_OT_extrude_region={"mirror": False}, + TRANSFORM_OT_translate={ + "value": (longitud / cuantos_segmentos, 0, 0), + "constraint_axis": (True, False, False), + "constraint_orientation": 'GLOBAL', "mirror": False, + "proportional": 'DISABLED', "proportional_edit_falloff": 'SMOOTH', + "proportional_size": 1, "snap": False, "snap_target": 'CLOSEST', + "snap_point": (0, 0, 0), "snap_align": False, "snap_normal": (0, 0, 0), + "gpencil_strokes": False, "texture_space": False, + "remove_on_cancel": False, "release_confirm": False + } + ) + + +def select_all_vertex_in_curve_bezier(bc): + for i in range(len(bc.data.splines[0].points)): + bc.data.splines[0].points[i].select = True + + +def deselect_all_vertex_in_curve_bezier(bc): + for i in range(len(bc.data.splines[0].points)): + bc.data.splines[0].points[i].select = False + + +def ocultar_relationships(): + for area in bpy.context.screen.areas: + if area.type == 'VIEW_3D': + area.spaces[0].show_relationship_lines = False + + +class ClothRope(Operator): + bl_idname = "clot.rope" + bl_label = "Rope Cloth" + bl_description = ("Create a new Scene with a Cloth modifier\n" + "Rope Simulation with hooked Helper Objects") + + ropelenght = IntProperty( + name="Rope Length", + description="Length of the generated Rope", + default=5 + ) + ropesegments = IntProperty( + name="Rope Segments", + description="Number of the Rope Segments", + default=5 + ) + qcr = IntProperty( + name="Collision Quality", + description="Rope's Cloth modifier collsion quality", + min=1, max=20, + default=20 + ) + substeps = IntProperty( + name="Rope Substeps", + description="Rope's Cloth modifier quality", + min=4, max=80, + default=50 + ) + resrope = IntProperty( + name="Rope Resolution", + description="Rope's Bevel resolution", + default=5 + ) + radiusrope = FloatProperty( + name="Radius", + description="Rope's Radius", + min=0.04, max=1, + default=0.04 + ) + hide_emptys = BoolProperty( + name="Hide Empties", + description="Hide Helper Objects", + default=False + ) + + def execute(self, context): + # add a new scene + bpy.ops.scene.new(type="NEW") + scene = bpy.context.scene + scene.name = "Test Rope" + seleccionar_todo() + longitud = self.ropelenght + + # For the middle to have x segments between the first and + # last point, must add 1 to the quantity: + cuantos_segmentos = self.ropesegments + 1 + calidad_de_colision = self.qcr + substeps = self.substeps + deseleccionar_todo() + # collect the possible empties that already exist in the data + empties_prev = [obj.name for obj in bpy.data.objects if obj.type == "EMPTY"] + + # create an empty that will be the parent of everything + bpy.ops.object.empty_add( + type='SPHERE', radius=1, view_align=False, location=(0, 0, 0), + layers=(True, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, + False, False, False, False) + ) + ob = bpy.context.selected_objects[0] + ob.name = "Rope" + # .001 and friends + rope_name = ob.name + deseleccionar_todo() + + # create a plane and delete it + bpy.ops.mesh.primitive_plane_add( + radius=1, view_align=False, enter_editmode=False, location=(0, 0, 0), + layers=(True, False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, + False, False, False) + ) + ob = bpy.context.selected_objects[0] + # rename: + ob.name = "cuerda" + # .001 and friends + cuerda_1_name = ob.name + + entrar_en_editmode() # enter edit mode + select_all_in_edit_mode(ob) + + borrar_elementos_seleccionados("vertices") + salir_de_editmode() # leave edit mode + crear_vertices(ob) # create a vertex + + # Creating a Group for the PIN + # Group contains the vertices of the pin and the Group.001 contains the single main line + entrar_en_editmode() # enter edit mode + bpy.ops.object.vertex_group_add() # create a group + select_all_in_edit_mode(ob) + bpy.ops.object.vertex_group_assign() # assign it + + salir_de_editmode() # leave edit mode + ob.vertex_groups[0].name = "Pin" + deseleccionar_todo() + seleccionar_por_nombre(cuerda_1_name) + + # extrude vertices: + for i in range(cuantos_segmentos): + entrar_en_editmode() + extruir_vertices(longitud, cuantos_segmentos) + # delete the PIN group + bpy.ops.object.vertex_group_remove_from() + # get the direction to create the locator on it's position + pos = obtener_coords_vertex_seleccionados() + + salir_de_editmode() # leave edit mode + # create locator at position + crear_locator(pos) + deseleccionar_todo() + seleccionar_por_nombre(cuerda_1_name) + deseleccionar_todo() + + seleccionar_por_nombre(cuerda_1_name) # select the rope + entrar_en_editmode() + + pos = obtener_coords_vertex_seleccionados() # get their positions + salir_de_editmode() + # create the last locator + crear_locator(pos) + deseleccionar_todo() + seleccionar_por_nombre(cuerda_1_name) + entrar_en_editmode() # enter edit mode + bpy.ops.object.vertex_group_add() # Creating Master guide group + select_all_in_edit_mode(ob) + bpy.ops.object.vertex_group_assign() # and assing it + ob.vertex_groups[1].name = "Guide_rope" + + # extrude the Curve so it has a minumum thickness for collide + bpy.ops.mesh.extrude_region_move( + MESH_OT_extrude_region={"mirror": False}, + TRANSFORM_OT_translate={ + "value": (0, 0.005, 0), "constraint_axis": (False, True, False), + "constraint_orientation": 'GLOBAL', "mirror": False, + "proportional": 'DISABLED', "proportional_edit_falloff": 'SMOOTH', + "proportional_size": 1, "snap": False, "snap_target": 'CLOSEST', + "snap_point": (0, 0, 0), "snap_align": False, "snap_normal": (0, 0, 0), + "gpencil_strokes": False, "texture_space": False, + "remove_on_cancel": False, "release_confirm": False + } + ) + bpy.ops.object.vertex_group_remove_from() + deselect_all_in_edit_mode(ob) + salir_de_editmode() + bpy.ops.object.modifier_add(type='CLOTH') + bpy.context.object.modifiers["Cloth"].settings.use_pin_cloth = True + bpy.context.object.modifiers["Cloth"].settings.vertex_group_mass = "Pin" + bpy.context.object.modifiers["Cloth"].collision_settings.collision_quality = calidad_de_colision + bpy.context.object.modifiers["Cloth"].settings.quality = substeps + + # Duplicate to convert into Curve: + # select the vertices that are the part of the Group.001 + seleccionar_por_nombre(cuerda_1_name) + entrar_en_editmode() + bpy.ops.mesh.select_all(action="DESELECT") + bpy.context.tool_settings.mesh_select_mode = (True, False, False) + salir_de_editmode() + gi = ob.vertex_groups["Guide_rope"].index # get group index + + for v in ob.data.vertices: + for g in v.groups: + if g.group == gi: # compare with index in VertexGroupElement + v.select = True + + # now we have to make a table of names of cuerdas to see which one will be new + cuerda_names = [obj.name for obj in bpy.data.objects if "cuerda" in obj.name] + + entrar_en_editmode() + + # we already have the selected guide: + # duplicate it: + bpy.ops.mesh.duplicate_move( + MESH_OT_duplicate={"mode": 1}, + TRANSFORM_OT_translate={ + "value": (0, 0, 0), "constraint_axis": (False, False, False), + "constraint_orientation": 'GLOBAL', "mirror": False, + "proportional": 'DISABLED', "proportional_edit_falloff": 'SMOOTH', + "proportional_size": 1, "snap": False, "snap_target": 'CLOSEST', + "snap_point": (0, 0, 0), "snap_align": False, "snap_normal": (0, 0, 0), + "gpencil_strokes": False, "texture_space": False, + "remove_on_cancel": False, "release_confirm": False + } + ) + # separate the selections: + bpy.ops.mesh.separate(type='SELECTED') + salir_de_editmode() + deseleccionar_todo() + + cuerda_2_name = "cuerda.001" + test = [] + for obj in bpy.data.objects: + if "cuerda" in obj.name and obj.name not in cuerda_names: + cuerda_2_name = obj.name + test.append(obj.name) + + seleccionar_por_nombre(cuerda_2_name) + + # from the newly created curve remove the Cloth: + bpy.ops.object.modifier_remove(modifier="Cloth") + # convert the Curve: + bpy.ops.object.convert(target='CURVE') + + # all Empties that are not previously present + emptys = [] + for eo in bpy.data.objects: + if eo.type == 'EMPTY' and eo.name not in empties_prev: + if eo.name != rope_name: + emptys.append(eo) + + # select and deselect: + bc = bpy.data.objects[cuerda_2_name] + n = 0 + + for e in emptys: + deseleccionar_todo() + seleccionar_por_nombre(e.name) + seleccionar_por_nombre(bc.name) + entrar_en_editmode() + deselect_all_vertex_in_curve_bezier(bc) + bc.data.splines[0].points[n].select = True + bpy.ops.object.hook_add_selob(use_bone=False) + salir_de_editmode() + n = n + 1 + + ob = bpy.data.objects[cuerda_1_name] + n = 0 + + for e in emptys: + deseleccionar_todo() + seleccionar_por_nombre(e.name) + seleccionar_por_nombre(ob.name) + entrar_en_editmode() + bpy.ops.mesh.select_all(action="DESELECT") + bpy.context.tool_settings.mesh_select_mode = (True, False, False) + salir_de_editmode() + + for v in ob.data.vertices: + if v.select: + v.select = False + ob.data.vertices[n].select = True + entrar_en_editmode() + bpy.ops.object.vertex_parent_set() + + salir_de_editmode() + n = n + 1 + + # hide the Empties: + deseleccionar_todo() + + # all parented to the spherical empty: + seleccionar_por_nombre(cuerda_2_name) + seleccionar_por_nombre(cuerda_1_name) + seleccionar_por_nombre(rope_name) + bpy.ops.object.parent_set(type='OBJECT', keep_transform=True) + deseleccionar_todo() + + # do not display the relations + ocultar_relationships() + seleccionar_por_nombre(cuerda_2_name) + + # curved rope settings: + bpy.context.object.data.fill_mode = 'FULL' + bpy.context.object.data.bevel_depth = self.radiusrope + bpy.context.object.data.bevel_resolution = self.resrope + + return {'FINISHED'} + + def invoke(self, context, event): + return context.window_manager.invoke_props_dialog(self, width=350) + + def draw(self, context): + layout = self.layout + box = layout.box() + col = box.column(align=True) + + col.label("Rope settings:") + rowsub0 = col.row() + rowsub0.prop(self, "ropelenght", text="Length") + rowsub0.prop(self, "ropesegments", text="Segments") + rowsub0.prop(self, "radiusrope", text="Radius") + + col.label("Quality Settings:") + col.prop(self, "resrope", text="Resolution curve") + col.prop(self, "qcr", text="Quality Collision") + col.prop(self, "substeps", text="Substeps") + + +class BallRope(Operator): + bl_idname = "ball.rope" + bl_label = "Wrecking Ball" + bl_description = ("Create a new Scene with a Rigid Body simulation of\n" + "Wrecking Ball on a rope") + + # defaults rope ball + ropelenght2 = IntProperty( + name="Rope Length", + description="Length of the Wrecking Ball rope", + default=10 + ) + ropesegments2 = IntProperty( + name="Rope Segments", + description="Number of the Wrecking Ball rope segments", + min=0, max=999, + default=6 + ) + radiuscubes = FloatProperty( + name="Cube Radius", + description="Size of the Linked Cubes helpers", + default=0.5 + ) + radiusrope = FloatProperty( + name="Rope Radius", + description="Radius of the Rope", + default=0.4 + ) + worldsteps = IntProperty( + name="World Steps", + description="Rigid Body Solver world steps per second (update)", + min=60, max=1000, + default=250 + ) + solveriterations = IntProperty( + name="Solver Iterations", + description="How many times the Rigid Body Solver should run", + min=10, max=100, + default=50 + ) + massball = IntProperty( + name="Ball Mass", + description="Mass of the Wrecking Ball", + default=1 + ) + resrope = IntProperty( + name="Resolution", + description="Rope resolution", + default=4 + ) + grados = FloatProperty( + name="Degrees", + description="Angle of the Wrecking Ball compared to the Ground Plane", + default=45 + ) + separacion = FloatProperty( + name="Link Cubes Gap", + description="Space between the Rope's Linked Cubes", + default=0.1 + ) + hidecubes = BoolProperty( + name="Hide Link Cubes", + description="Hide helper geometry for the Rope", + default=False + ) + + def execute(self, context): + world_steps = self.worldsteps + solver_iterations = self.solveriterations + longitud = self.ropelenght2 + + # make a + 2, so the segments will be between the two end points... + segmentos = self.ropesegments2 + 2 + offset_del_suelo = 1 + offset_del_suelo_real = (longitud / 2) + (segmentos / 2) + radio = self.radiuscubes + radiorope = self.radiusrope + masa = self.massball + resolucion = self.resrope + rotrope = self.grados + separation = self.separacion + hidecubeslinks = self.hidecubes + + # add new scene + bpy.ops.scene.new(type="NEW") + scene = bpy.context.scene + scene.name = "Test Ball" + + # collect the possible constraint empties that already exist in the data + constraint_prev = [obj.name for obj in bpy.data.objects if + obj.type == "EMPTY" and "Constraint" in obj.name] + # floor: + bpy.ops.mesh.primitive_cube_add( + radius=1, view_align=False, enter_editmode=False, location=(0, 0, 0), + layers=(True, False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, + False, False, False) + ) + bpy.context.object.scale.x = 10 + longitud + bpy.context.object.scale.y = 10 + longitud + bpy.context.object.scale.z = 0.05 + bpy.context.object.name = "groundplane" + # The secret agents .001, 002 etc. + groundplane_name = bpy.context.object.name + + bpy.ops.rigidbody.objects_add(type='PASSIVE') + + # create the first cube: + cuboslink = [] + n = 0 + for i in range(segmentos): + # if 0 start from 1 + if i == 0: + i = offset_del_suelo + else: # if it is not 0, add one so it doesn't step on the first one starting from 1 + i = i + offset_del_suelo + separacion = longitud * 2 / segmentos # distance between linked cubes + bpy.ops.mesh.primitive_cube_add( + radius=1, view_align=False, enter_editmode=False, + location=(0, 0, i * separacion), + layers=(True, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, + False, False, False, False) + ) + bpy.ops.rigidbody.objects_add(type='ACTIVE') + bpy.context.object.name = "CubeLink" + if n != 0: + bpy.context.object.draw_type = 'WIRE' + bpy.context.object.hide_render = True + n += 1 + bpy.context.object.scale.z = (longitud * 2) / (segmentos * 2) - separation + bpy.context.object.scale.x = radio + bpy.context.object.scale.y = radio + cuboslink.append(bpy.context.object) + + for i in range(len(cuboslink)): + deseleccionar_todo() + if i != len(cuboslink) - 1: + nombre1 = cuboslink[i] + nombre2 = cuboslink[i + 1] + seleccionar_por_nombre(nombre1.name) + seleccionar_por_nombre(nombre2.name) + bpy.ops.rigidbody.connect() + + # select by name + constraint_new = [ + obj.name for obj in bpy.data.objects if + obj.type == "EMPTY" and "Constraint" in obj.name and + obj.name not in constraint_prev + ] + + for names in constraint_new: + seleccionar_por_nombre(names) + + for c in bpy.context.selected_objects: + c.rigid_body_constraint.type = 'POINT' + deseleccionar_todo() + + # create a Bezier curve: + bpy.ops.curve.primitive_bezier_curve_add( + radius=1, view_align=False, enter_editmode=False, location=(0, 0, 0), + layers=(True, False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, False, False, False) + ) + bpy.context.object.name = "Cuerda" + # Blender will automatically append the .001 + # if it is already in data + real_name = bpy.context.object.name + + for i in range(len(cuboslink)): + cubonombre = cuboslink[i].name + seleccionar_por_nombre(cubonombre) + seleccionar_por_nombre(real_name) + x = cuboslink[i].location[0] + y = cuboslink[i].location[1] + z = cuboslink[i].location[2] + + # if it is 0 make it start from 1 as the offset from the ground... + if i == 0: + i = offset_del_suelo + else: # if it is not 0, add one so it doesn't step on the first one starting from 1 + i = i + offset_del_suelo + + salir_de_editmode() + entrar_en_editmode() + + if i == 1: + # select all the vertices and delete them + select_all_vertex_in_curve_bezier(bpy.data.objects[real_name]) + bpy.ops.curve.delete(type='VERT') + # create the first vertex: + bpy.ops.curve.vertex_add(location=(x, y, z)) + else: + # extrude the rest: + bpy.ops.curve.extrude_move( + CURVE_OT_extrude={"mode": 'TRANSLATION'}, + TRANSFORM_OT_translate={ + "value": (0, 0, z / i), + "constraint_axis": (False, False, True), + "constraint_orientation": 'GLOBAL', "mirror": False, + "proportional": 'DISABLED', "proportional_edit_falloff": 'SMOOTH', + "proportional_size": 1, "snap": False, "snap_target": 'CLOSEST', + "snap_point": (0, 0, 0), "snap_align": False, "snap_normal": (0, 0, 0), + "gpencil_strokes": False, "texture_space": False, + "remove_on_cancel": False, "release_confirm": False + } + ) + bpy.ops.object.hook_add_selob(use_bone=False) + salir_de_editmode() + bpy.context.object.data.bevel_resolution = resolucion + deseleccionar_todo() + + # create a sphere ball: + deseleccionar_todo() + seleccionar_por_nombre(cuboslink[0].name) + entrar_en_editmode() + z = cuboslink[0].scale.z + longitud / 2 + bpy.ops.view3d.snap_cursor_to_selected() + bpy.ops.mesh.primitive_uv_sphere_add( + view_align=False, enter_editmode=False, + layers=(True, False, False, False, False, False, False, + False, False, False, False, False, False, False, + False, False, False, False, False, False) + ) + bpy.ops.transform.translate( + value=(0, 0, -z + 2), constraint_axis=(False, False, True), + constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', + proportional_edit_falloff='SMOOTH', proportional_size=1 + ) + bpy.ops.transform.resize( + value=(longitud / 2, longitud / 2, longitud / 2), + constraint_axis=(False, False, False), + constraint_orientation='GLOBAL', + mirror=False, proportional='DISABLED', + proportional_edit_falloff='SMOOTH', proportional_size=1 + ) + deselect_all_in_edit_mode(cuboslink[0]) + salir_de_editmode() + bpy.ops.object.shade_smooth() + bpy.context.object.rigid_body.mass = masa + bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS') + + # move it all up a bit more: + seleccionar_todo() + deseleccionar_por_nombre(groundplane_name) + bpy.ops.transform.translate( + value=(0, 0, offset_del_suelo_real), + constraint_axis=(False, False, True), + constraint_orientation='GLOBAL', mirror=False, + proportional='DISABLED', proportional_edit_falloff='SMOOTH', + proportional_size=1 + ) + + deseleccionar_todo() + seleccionar_por_nombre(cuboslink[-1].name) + bpy.ops.rigidbody.objects_add(type='PASSIVE') + + bpy.context.scene.rigidbody_world.steps_per_second = world_steps + bpy.context.scene.rigidbody_world.solver_iterations = solver_iterations + + # move everything from the top one: + seleccionar_por_nombre(cuboslink[-1].name) + bpy.ops.view3d.snap_cursor_to_selected() + seleccionar_todo() + deseleccionar_por_nombre(groundplane_name) + deseleccionar_por_nombre(cuboslink[-1].name) + bpy.context.space_data.pivot_point = 'CURSOR' + bpy.ops.transform.rotate( + value=rotrope, axis=(1, 0, 0), + constraint_axis=(True, False, False), + constraint_orientation='GLOBAL', + mirror=False, proportional='DISABLED', + proportional_edit_falloff='SMOOTH', + proportional_size=1 + ) + bpy.context.space_data.pivot_point = 'MEDIAN_POINT' + deseleccionar_todo() + + seleccionar_por_nombre(real_name) + bpy.context.object.data.fill_mode = 'FULL' + bpy.context.object.data.bevel_depth = radiorope + for ob in bpy.data.objects: + if ob.name != cuboslink[0].name: + if ob.name.find("CubeLink") >= 0: + deseleccionar_todo() + seleccionar_por_nombre(ob.name) + if hidecubeslinks: + bpy.context.object.hide = True + ocultar_relationships() + deseleccionar_todo() + return {'FINISHED'} + + def invoke(self, context, event): + return context.window_manager.invoke_props_dialog(self, width=350) + + def draw(self, context): + layout = self.layout + box = layout.box() + col = box.column(align=True) + + col.label("Rope settings:") + rowsub0 = col.row() + rowsub0.prop(self, "hidecubes", text="Hide Link Cubes") + + rowsub1 = col.row(align=True) + rowsub1.prop(self, "ropelenght2", text="Length") + rowsub1.prop(self, "ropesegments2", text="Segments") + + rowsub2 = col.row(align=True) + rowsub2.prop(self, "radiuscubes", text="Radius Link Cubes") + rowsub2.prop(self, "radiusrope", text="Radius Rope") + + rowsub3 = col.row(align=True) + rowsub3.prop(self, "grados", text="Degrees") + rowsub3.prop(self, "separacion", text="Separation Link Cubes") + + col.label("Quality Settings:") + col.prop(self, "resrope", text="Resolution Rope") + col.prop(self, "massball", text="Ball Mass") + col.prop(self, "worldsteps", text="World Steps") + col.prop(self, "solveriterations", text="Solver Iterarions") + + +# Register + +def register(): + bpy.utils.register_module(__name__) + + +def unregister(): + bpy.utils.unregister_module(__name__) + + +if __name__ == "__main__": + register() |