1 # ###### BEGIN GPL LICENSE BLOCK ######
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # If you have Internet access, you can find the license text at
14 # http://www.gnu.org/licenses/gpl.txt,
15 # if not, write to the Free Software Foundation,
16 # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 # ###### END GPL LICENCE BLOCK ######
22 CreaPrim does what it says. I takes the active object and turns it into an
23 Add Mesh addon. When you enable this, your custom object will be added to the
29 Go to User Preferences->Addons and enable the CreaPrim addon in the Object
30 section. The addon will show up in the 3dview properties panel.
32 First select your object or objects.
33 The name (in panel) will be set to the active object name.
34 Select "Apply transform" if you want transforms to be applied to the selected
35 objects. Modifiers will taken into account. You can always change this.
36 Just hit the button and the selected objects will be saved in your addons folder
37 as an Add Mesh addon with the name "add_mesh_XXXX.py" with XXXX being your
38 object name. The addon will show up in User Preferences->Addons in the
39 Add Mesh section. Enable this addon et voila, your new custom primitive will
40 now show up in the Add Mesh menu.
42 REMARK - dont need to be admin anymore - saves to user scripts dir
44 ALSO - dont forget to Apply rotation and scale to have your object
50 "author": "Gert De Roost",
51 "version": (0, 3, 11),
52 "blender": (2, 80, 0),
53 "location": "View3D > Object Tools",
54 "description": "Create primitive addon",
55 "warning": "under construction",
57 "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
72 is_faces
= bool(len(me
.polygons
) > 0)
76 class CreaPrim(bpy
.types
.Operator
):
77 bl_idname
= "object.creaprim"
79 bl_description
= "Create a primitive add-on"
80 bl_options
= {"REGISTER"}
83 def poll(cls
, context
):
84 obj
= context
.active_object
85 return (obj
and obj
.type == 'MESH' and context
.mode
== 'OBJECT')
87 def invoke(self
, context
, event
):
89 global oldname
, groupname
, message
91 scn
= bpy
.context
.scene
94 for selobj
in bpy
.context
.scene
.objects
:
95 if selobj
.select_get() and test_data(selobj
) is True:
96 objlist
.append(selobj
)
99 self
.report({'WARNING'},
100 "Please select Mesh objects containing Polygons. Operation Cancelled")
104 direc
= bpy
.utils
.script_paths()[1]
107 direc
= bpy
.utils
.script_paths()[0]
111 groupname
= scn
.Creaprim_Name
112 groupname
= groupname
.replace(".", "")
113 addondir
= direc
+ os
.sep
+ "addons" + os
.sep
+ "add_mesh_" + groupname
+ os
.sep
114 if not os
.path
.exists(addondir
):
115 os
.makedirs(addondir
)
117 groupname
= scn
.Creaprim_Name
118 print(bpy
.utils
.script_paths())
119 addondir
= direc
+ os
.sep
+ "addons" + os
.sep
121 if not os
.path
.exists(addondir
):
122 os
.makedirs(addondir
)
124 actobj
= context
.view_layer
.objects
.active
127 for selobj
in objlist
:
128 if len(objlist
) == 1:
129 objname
= scn
.Creaprim_Name
130 objname
= objname
.replace(" ", "_")
132 objname
= selobj
.name
133 objname
= objname
.replace(".", "")
134 objname
= objname
.replace(" ", "_")
135 namelist
.append(objname
)
136 mesh
= selobj
.to_mesh(preserve_all_data_layers
=False, depsgraph
=None)
137 oldname
= selobj
.name
138 context
.view_layer
.objects
.active
= selobj
140 if scn
.Creaprim_Apply
:
141 bpy
.ops
.object.transform_apply(location
=False, rotation
=True, scale
=True)
142 txt
= do_creaprim(self
, mesh
, objname
, addondir
)
149 oldname
= actobj
.name
150 context
.view_layer
.objects
.active
= actobj
153 makeinit(txtlist
, namelist
, groupname
, addondir
)
154 bpy
.ops
.preferences
.addon_enable(module
="add_mesh_" + groupname
)
156 bpy
.ops
.preferences
.addon_enable(module
="add_mesh_" + str.lower(objname
))
159 message
= "Add Mesh addon " + groupname
+ " saved to user scripts directory."
161 message
= "Add Mesh addon " + groupname
+ " saved to main scripts directory."
162 bpy
.ops
.creaprim
.message('INVOKE_DEFAULT')
167 class MessageOperator(bpy
.types
.Operator
):
168 bl_idname
= "creaprim.message"
171 def invoke(self
, context
, event
):
172 wm
= context
.window_manager
173 return wm
.invoke_popup(self
, width
=500)
175 def draw(self
, context
):
181 row
.label(text
='', icon
="PLUGIN")
185 def panel_func(self
, context
):
189 scn
= bpy
.context
.scene
191 self
.layout
.label(text
="CreaPrim:")
192 self
.layout
.operator("object.creaprim", text
="Create primitive", icon
='PLUGIN')
193 self
.layout
.prop(scn
, "Creaprim_Name")
194 self
.layout
.prop(scn
, "Creaprim_Apply")
204 bpy
.utils
.register_class(cls
)
205 #bpy.utils.register_module(__name__)
206 bpy
.types
.Scene
.Creaprim_Name
= bpy
.props
.StringProperty(
208 description
="Name for the primitive",
211 bpy
.types
.Scene
.Creaprim_Apply
= bpy
.props
.BoolProperty(
212 name
="Apply transform",
213 description
="Apply transform to selected objects",
216 #bpy.types.VIEW3D_PT_tools_object.append(panel_func)
217 bpy
.types
.OBJECT_PT_context_object
.append(panel_func
)
218 #bpy.app.handlers.scene_update_post.append(setname)
219 bpy
.app
.handlers
.depsgraph_update_post
.append(setname
)
223 #bpy.utils.unregister_module(__name__)
224 for cls
in reversed(classes
):
225 bpy
.utils
.unregister_class(cls
)
226 #bpy.types.VIEW3D_PT_tools_object.remove(panel_func)
227 bpy
.types
.OBJECT_PT_context_object
.remove(panel_func
)
228 #bpy.app.handlers.scene_update_post.remove(setname)
229 bpy
.app
.handlers
.depsgraph_update_post
.remove(setname
)
230 del bpy
.types
.Scene
.Creaprim_Name
231 del bpy
.types
.Scene
.Creaprim_Apply
234 if __name__
== "__main__":
238 def do_creaprim(self
, mesh
, objname
, addondir
):
242 objname
= objname
.replace(".", "")
243 objname
= objname
.replace(" ", "_")
248 txt
= bpy
.data
.texts
[str.lower("add_mesh_" + objname
) + ".py"]
251 txt
= bpy
.data
.texts
.new("add_mesh_" + str.lower(objname
) + ".py")
254 strlist
.append("# Script autogenerated by object_creaprim.py")
256 strlist
.append("bl_info = {\n")
257 strlist
.append(" \"name\": \"" + objname
+ "\",\n")
258 strlist
.append(" \"author\": \"Gert De Roost\",\n")
259 strlist
.append(" \"version\": (1, 0, 0),\n")
260 strlist
.append(" \"blender\": (2, 80, 0),\n")
261 strlist
.append(" \"location\": \"Add > Mesh\",\n")
262 strlist
.append(" \"description\": \"Create " + objname
+ " primitive\",\n")
263 strlist
.append(" \"warning\": \"\",\n")
264 strlist
.append(" \"doc_url\": \"\",\n")
265 strlist
.append(" \"tracker_url\": \"\",\n")
266 strlist
.append(" \"category\": \"Add Mesh\"}\n")
269 strlist
.append("import bpy\n")
270 strlist
.append("import bmesh\n")
271 strlist
.append("import math\n")
272 strlist
.append("from mathutils import *\n")
275 strlist
.append("class " + objname
+ "(bpy.types.Operator):\n")
276 strlist
.append(" bl_idname = \"mesh." + str.lower(objname
) + "\"\n")
277 strlist
.append(" bl_label = \"" + objname
+ "\"\n")
278 strlist
.append(" bl_options = {\'REGISTER\', \'UNDO\'}\n")
279 strlist
.append(" bl_description = \"add " + objname
+ " primitive\"\n")
281 strlist
.append(" def invoke(self, context, event):\n")
283 strlist
.append(" mesh = bpy.data.meshes.new(name=\"" + objname
+ "\")\n")
284 strlist
.append(" obj = bpy.data.objects.new(name=\"" + objname
+ "\", object_data=mesh)\n")
285 strlist
.append(" collection = bpy.context.collection\n")
286 strlist
.append(" scene = bpy.context.scene\n")
287 strlist
.append(" collection.objects.link(obj)\n")
288 strlist
.append(" obj.location = scene.cursor.location\n")
289 strlist
.append(" bm = bmesh.new()\n")
290 strlist
.append(" bm.from_mesh(mesh)\n")
292 strlist
.append(" idxlist = []\n")
294 strlist
.append(" vertlist = [")
299 strlist
.append(str(v
.co
[:]))
300 strlist
.append("]\n")
301 strlist
.append(" for co in vertlist:\n")
302 strlist
.append(" v = bm.verts.new(co)\n")
303 strlist
.append(" bm.verts.index_update()\n")
304 strlist
.append(" idxlist.append(v.index)\n")
306 strlist
.append(" edgelist = [")
311 strlist
.append("[" + str(e
.verts
[0].index
) + ", " + str(e
.verts
[1].index
) + "]")
312 strlist
.append("]\n")
313 strlist
.append(" for verts in edgelist:\n")
314 strlist
.append(" try:\n")
315 strlist
.append(" bm.edges.new((bm.verts[verts[0]], bm.verts[verts[1]]))\n")
316 strlist
.append(" except:\n")
317 strlist
.append(" pass\n")
319 strlist
.append(" facelist = [(")
322 strlist
.append(", (")
328 strlist
.append(str(v
.index
))
331 strlist
.append("]\n")
332 strlist
.append(" bm.verts.ensure_lookup_table()\n")
333 strlist
.append(" for verts in facelist:\n")
334 strlist
.append(" vlist = []\n")
335 strlist
.append(" for idx in verts:\n")
336 strlist
.append(" vlist.append(bm.verts[idxlist[idx]])\n")
337 strlist
.append(" try:\n")
338 strlist
.append(" bm.faces.new(vlist)\n")
339 strlist
.append(" except:\n")
340 strlist
.append(" pass\n")
342 strlist
.append(" bm.to_mesh(mesh)\n")
343 strlist
.append(" mesh.update()\n")
344 strlist
.append(" bm.free()\n")
345 strlist
.append(" obj.rotation_quaternion = (Matrix.Rotation(math.radians(90), 3, \'X\').to_quaternion())\n")
347 strlist
.append(" return {\'FINISHED\'}\n")
351 strlist
.append("def menu_item(self, context):\n")
352 strlist
.append(" self.layout.operator(" + objname
+ ".bl_idname, text=\"" + objname
+ "\", icon=\"PLUGIN\")\n")
355 strlist
.append("def register():\n")
356 strlist
.append(" bpy.utils.register_class(__name__)\n")
357 strlist
.append(" bpy.types.VIEW3D_MT_mesh_add.append(menu_item)\n")
360 strlist
.append("def unregister():\n")
361 strlist
.append(" bpy.utils.unregister_class(__name__)\n")
362 strlist
.append(" bpy.types.VIEW3D_MT_mesh_add.remove(menu_item)\n")
365 strlist
.append("if __name__ == \"__main__\":\n")
366 strlist
.append(" register()\n")
367 endstring
= ''.join(strlist
)
371 fileobj
= open(addondir
+ "add_mesh_" + str.lower(objname
) + ".py", "w")
373 message
= "Permission problem - cant write file - run Blender as Administrator!"
374 bpy
.ops
.creaprim
.message('INVOKE_DEFAULT')
377 fileobj
.write(endstring
)
385 def makeinit(txtlist
, namelist
, groupname
, addondir
):
390 txt
= bpy
.data
.texts
["__init__.py"]
393 txt
= bpy
.data
.texts
.new("__init__.py")
396 strlist
.append("# Script autogenerated by object_creaprim.py")
398 strlist
.append("bl_info = {\n")
399 strlist
.append(" \"name\": \"" + groupname
+ "\",\n")
400 strlist
.append(" \"author\": \"Gert De Roost\",\n")
401 strlist
.append(" \"version\": (1, 0, 0),\n")
402 strlist
.append(" \"blender\": (2, 65, 0),\n")
403 strlist
.append(" \"location\": \"Add > Mesh\",\n")
404 strlist
.append(" \"description\": \"Create " + groupname
+ " primitive group\",\n")
405 strlist
.append(" \"warning\": \"\",\n")
406 strlist
.append(" \"doc_url\": \"\",\n")
407 strlist
.append(" \"tracker_url\": \"\",\n")
408 strlist
.append(" \"category\": \"Add Mesh\"}\n")
411 strlist
.append("if \"bpy\" in locals():\n")
412 strlist
.append(" import importlib\n")
415 name
= txt
.name
.replace(".py", "")
416 addonlist
.append(name
)
417 for name
in addonlist
:
418 strlist
.append(" importlib.reload(" + name
+ ")\n")
419 strlist
.append("else:\n")
420 for name
in addonlist
:
421 strlist
.append(" from . import " + name
+ "\n")
424 strlist
.append("import bpy\n")
427 strlist
.append("class VIEW3D_MT_mesh_" + str.lower(groupname
) + "_add(bpy.types.Menu):\n")
428 strlist
.append(" bl_idname = \"VIEW3D_MT_mesh_" + str.lower(groupname
) + "_add\"\n")
429 strlist
.append(" bl_label = \"" + groupname
+ "\"\n")
431 strlist
.append(" def draw(self, context):\n")
432 strlist
.append(" layout = self.layout\n")
434 for name
in namelist
:
435 strlist
.append(" layout.operator(\"mesh." + str.lower(name
) + "\", text=\"" + name
+ "\")\n")
438 strlist
.append("def menu_item(self, context):\n")
439 strlist
.append(" self.layout.menu(\"VIEW3D_MT_mesh_" + str.lower(groupname
) + "_add\", icon=\"PLUGIN\")\n")
442 strlist
.append("def register():\n")
443 strlist
.append(" bpy.utils.register_module(__name__)\n")
444 strlist
.append(" bpy.types.VIEW3D_MT_mesh_add.append(menu_item)\n")
447 strlist
.append("def unregister():\n")
448 strlist
.append(" bpy.utils.unregister_module(__name__)\n")
449 strlist
.append(" bpy.types.VIEW3D_MT_mesh_add.remove(menu_item)\n")
452 strlist
.append("if __name__ == \"__main__\":\n")
453 strlist
.append(" register()\n")
454 endstring
= ''.join(strlist
)
458 fileobj
= open(addondir
+ "__init__.py", "w")
460 message
= "Permission problem - cant write file - run Blender as Administrator!"
461 bpy
.ops
.creaprim
.message('INVOKE_DEFAULT')
464 fileobj
.write(endstring
)
468 @bpy.app
.handlers
.persistent
471 scn
= bpy
.context
.scene
472 oldname
= scn
.Creaprim_Name
474 if bpy
.context
.active_object
and bpy
.context
.active_object
.name
!= oldname
:
476 scn
.Creaprim_Name
= bpy
.context
.active_object
.name