I was wondering, is there a possible way of selecting an object I create in blender and generating python code from it, so I am able to generate the object via code?
I was wanting to do this for creating my own primitives.
I was wondering, is there a possible way of selecting an object I create in blender and generating python code from it, so I am able to generate the object via code?
I was wanting to do this for creating my own primitives.
Update for 2.8
An update of Mesh to Script Helper Select an object in object mode, run script. Creates make_primitive.py in the textbook. Running the created file creates the primitive.
import bpy
context = bpy.context
ob = context.object
if ob and ob.type == "MESH":
mesh = ob.data
me = ob.data
txt = bpy.data.texts.new("make_primitive.py")
faces = ",\n ".join(f'{p.vertices[:]}' for p in me.polygons)
verts = ",\n ".join(f"{v.co[:]}" for v in me.vertices)
txt.write(f"""import bpy
context = bpy.context
verts = ({verts})
faces = ({faces})
me = bpy.data.meshes.new("{me.name}")
me.from_pydata(verts, [], faces)
ob = bpy.data.objects.new("{ob.name}", me)
context.collection.objects.link(ob)
context.view_layer.objects.active = ob""")
Result after running on default cube. Running the file recreates the primitive object.
import bpy
context = bpy.context
verts = ((-1.0, -1.0, -1.0),
(-1.0, -1.0, 1.0),
(-1.0, 1.0, -1.0),
(-1.0, 1.0, 1.0),
(1.0, -1.0, -1.0),
(1.0, -1.0, 1.0),
(1.0, 1.0, -1.0),
(1.0, 1.0, 1.0))
faces = ((0, 1, 3, 2),
(2, 3, 7, 6),
(6, 7, 5, 4),
(4, 5, 1, 0),
(2, 6, 4, 0),
(7, 3, 1, 5))
me = bpy.data.meshes.new("Cube")
me.from_pydata(verts, [], faces)
ob = bpy.data.objects.new("Cube", me)
context.collection.objects.link(ob)
context.view_layer.objects.active = ob
With the help of the Rigify add-on, this can be achieved. Enable Rigify in the User Preferences -> add-ons section like usual. Then go to Edit Mode and locate the button Encode Mesh Widget to Python to generate the script. The script itself will be put into a Text called widget.py and wrapped into a nice Python function already.
See this little GIF for better (visual) explanation:
From the generated code you can extract the Vertex coordinates, Edge and Face indicies. The rest has to be adapted to your needs. Also take care about indentation levels and Tabs vs. Spaces, the script that Rigify generates uses Spaces for indentation, regardless of what you set as Blenders default. Here is a refactored code example:
import bpy
def create_thing_widget(_name, size):
# -----------------------------------------------------------------------
# these are the vertices, edges and faces that the rigify addon generates
# copy and paste your ones over, and make sure to reduce the indentation
# if you are using Tabs instead of Spaces, also check on that, Rigify
# generates spaces for indentation by default
verts = [(-0.10000000149011612*size, -0.10000000149011612*size, -0.10000000149011612*size), (-0.10000000149011612*size, -0.10000000149011612*size, 0.10000000149011612*size), (-0.10000000149011612*size, 0.10000000149011612*size, -0.10000000149011612*size), (-0.10000000149011612*size, 0.10000000149011612*size, 0.10000000149011612*size), (0.10000000149011612*size, -0.10000000149011612*size, -0.10000000149011612*size), (0.10000000149011612*size, -0.10000000149011612*size, 0.10000000149011612*size), (0.10000000149011612*size, 0.10000000149011612*size, -0.10000000149011612*size), (0.10000000149011612*size, 0.10000000149011612*size, 0.10000000149011612*size), ]
edges = [(2, 0), (0, 1), (1, 3), (3, 2), (6, 2), (3, 7), (7, 6), (4, 6), (7, 5), (5, 4), (0, 4), (5, 1), ]
faces = [(0, 1, 3, 2, ), (2, 3, 7, 6, ), (6, 7, 5, 4, ), (4, 5, 1, 0, ), (2, 6, 4, 0, ), (7, 3, 1, 5, ), ]
# -----------------------------------------------------------------------
# the rest keep like in this example
# here the mesh data is constructed
mesh = bpy.data.meshes.new(_name)
mesh.from_pydata(verts, edges, faces)
mesh.update()
mesh.update()
# now generate an object to hold this data
obj = bpy.data.objects.new(_name, mesh)
# link the object to the scene (it is not visible so far!)
bpy.context.scene.objects.link(obj)
bpy.context.scene.update()
# return the object to the function caller for further stuff
return obj
# call the function
new_mesh = create_thing_widget('test', 1)
Ok so I have the code now, I try to run the widget script thats created, but nothing happens? Do I have to import anything before hand?
– Starius Oct 16 '16 at 06:13You can also look at the Creaprim addon that is made for creating primitives - it reduces the effort for setting up primitives, and each primitive is handled as a mini-addon. http://www.ewocprojects.be/scripts.html