Perfect, thank you for your help/support, got it working and here is the awesome result…
Maybe you like som platonic Solids as well into your reportoire…
bl_info = {
"name": "Platonic Solids",
"author": ":. ieoie .:",
"version": (1, 0),
"blender": (2, 80, 0),
"location": "View3D > Add > Mesh > New Platonic Solid",
"description": "Adds a new Mesh Object",
"category": "Add Mesh",
}
import bpy
import math
from bpy.types import Operator
from bpy.props import FloatVectorProperty
from bpy_extras.object_utils import AddObjectHelper, object_data_add
from mathutils import Vector
class PlatonicsMenu(bpy.types.Menu):
bl_label = "Platonic Solids"
bl_idname = "OBJECT_MT_my_custom_menu"
def draw(self, context):
layout = self.layout
layout.operator(OBJECT_OT_add_tetrapos.bl_idname,
text="Tetrahedron Positive",
icon='PLUGIN')
layout.operator(OBJECT_OT_add_tetraneg.bl_idname,
text="Tetrahedron Negative",
icon='PLUGIN')
layout.operator(OBJECT_OT_add_tetrastar.bl_idname,
text="Tetrahedron Star",
icon='PLUGIN')
layout.operator(OBJECT_OT_add_octa.bl_idname,
text="Octahedron",
icon='PLUGIN')
layout.operator(OBJECT_OT_add_cube.bl_idname,
text="Cube",
icon='PLUGIN')
layout.operator(OBJECT_OT_add_dodeca.bl_idname,
text="Dodecahedron",
icon='PLUGIN')
layout.operator(OBJECT_OT_add_icosa.bl_idname,
text="Icosahedron",
icon='PLUGIN')
def PlatonicsMenuAdd(self, context):
self.layout.menu(PlatonicsMenu.bl_idname)
def add_tetrapos(self, context):
scale_x = self.scale.x
scale_y = self.scale.y
scale_z = self.scale.z
verts = [
Vector((1 * scale_x, 1 * scale_y, 1 * scale_z)),
Vector((-1 * scale_x, 1 * scale_y, -1 * scale_z)),
Vector((-1 * scale_x, -1 * scale_y, 1 * scale_z)),
Vector((1 * scale_x, -1 * scale_y, -1 * scale_z)),
]
edges = []
faces = [[0, 1, 2], [0, 2, 3], [0, 3, 1], [2, 1, 3]]
mesh = bpy.data.meshes.new(name="obj_TetraPos")
mesh.from_pydata(verts, edges, faces)
# useful for development when the mesh may be invalid.
# mesh.validate(verbose=True)
object_data_add(context, mesh, operator=self)
def add_tetraneg(self, context):
scale_x = self.scale.x
scale_y = self.scale.y
scale_z = self.scale.z
verts = [
Vector((1 * scale_x, 1 * scale_y, -1 * scale_z)),
Vector((-1 * scale_x, 1 * scale_y, 1 * scale_z)),
Vector((1 * scale_x, -1 * scale_y, 1 * scale_z)),
Vector((-1 * scale_x, -1 * scale_y, -1 * scale_z)),
]
edges = []
faces = [[0, 1, 2], [0, 2, 3], [0, 3, 1], [2, 1, 3]]
mesh = bpy.data.meshes.new(name="obj_TetraNeg")
mesh.from_pydata(verts, edges, faces)
# useful for development when the mesh may be invalid.
# mesh.validate(verbose=True)
object_data_add(context, mesh, operator=self)
def add_tetrastar(self, context):
scale_x = self.scale.x
scale_y = self.scale.y
scale_z = self.scale.z
verts = [
Vector((1 * scale_x, 1 * scale_y, 1 * scale_z)),
Vector((-1 * scale_x, 1 * scale_y, -1 * scale_z)),
Vector((-1 * scale_x, -1 * scale_y, 1 * scale_z)),
Vector((1 * scale_x, -1 * scale_y, -1 * scale_z)),
Vector((1 * scale_x, 1 * scale_y, -1 * scale_z)),
Vector((-1 * scale_x, 1 * scale_y, 1 * scale_z)),
Vector((1 * scale_x, -1 * scale_y, 1 * scale_z)),
Vector((-1 * scale_x, -1 * scale_y, -1 * scale_z))
]
edges = []
faces = [[0, 1, 2], [0, 2, 3], [0, 3, 1], [2, 1, 3],
[4, 5, 6], [4, 6, 7], [4, 7, 5], [6, 5, 7]]
mesh = bpy.data.meshes.new(name="obj_TetraStar")
mesh.from_pydata(verts, edges, faces)
# useful for development when the mesh may be invalid.
# mesh.validate(verbose=True)
object_data_add(context, mesh, operator=self)
def add_octahedron(self, context):
scale_x = self.scale.x
scale_y = self.scale.y
scale_z = self.scale.z
verts = [
Vector((0, 0, 1 * scale_z)),
Vector((1 * scale_x, 0, 0)),
Vector((0, 1 * scale_y, 0)),
Vector((-1 * scale_x, 0, 0)),
Vector((0, -1 * scale_y, 0)),
Vector((0, 0, -1 * scale_z)),
]
edges = []
faces = [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1],
[5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]
mesh = bpy.data.meshes.new(name="obj_Octahedron")
mesh.from_pydata(verts, edges, faces)
# useful for development when the mesh may be invalid.
# mesh.validate(verbose=True)
object_data_add(context, mesh, operator=self)
def add_cube(self, context):
scale_x = self.scale.x
scale_y = self.scale.y
scale_z = self.scale.z
verts = [
Vector((1 * scale_x, 1 * scale_y, 1 * scale_z)),
Vector((-1 * scale_x, 1 * scale_y, 1 * scale_z)),
Vector((-1 * scale_x, -1 * scale_y, 1 * scale_z)),
Vector((1 * scale_x, -1 * scale_y, 1 * scale_z)),
Vector((1 * scale_x, 1 * scale_y, -1 * scale_z)),
Vector((-1 * scale_x, 1 * scale_y, -1 * scale_z)),
Vector((-1 * scale_x, -1 * scale_y, -1 * scale_z)),
Vector((1 * scale_x, -1 * scale_y, -1 * scale_z)),
]
edges = []
faces = [[0, 1, 2, 3], [1, 0, 4, 5], [2, 1, 5, 6], [3, 2, 6, 7], [0, 3, 7, 4], [5, 4, 7, 6]]
mesh = bpy.data.meshes.new(name="obj_Cube")
mesh.from_pydata(verts, edges, faces)
# useful for development when the mesh may be invalid.
# mesh.validate(verbose=True)
object_data_add(context, mesh, operator=self)
def add_dodeca(self, context):
scale_x = self.scale.x
scale_y = self.scale.y
scale_z = self.scale.z
sPhi = (math.sqrt(5) - 1.0) * 0.5
lPhi = 1.0 + sPhi
verts = [
# Cube verts
Vector((1 * scale_x, 1 * scale_y, 1 * scale_z)),
Vector((-1 * scale_x, 1 * scale_y, -1 * scale_z)),
Vector((-1 * scale_x, -1 * scale_y, 1 * scale_z)),
Vector((1 * scale_x, -1 * scale_y, -1 * scale_z)),
Vector((1 * scale_x, 1 * scale_y, -1 * scale_z)),
Vector((-1 * scale_x, 1 * scale_y, 1 * scale_z)),
Vector((1 * scale_x, -1 * scale_y, 1 * scale_z)),
Vector((-1 * scale_x, -1 * scale_y, -1 * scale_z)),
# Dodeca verts
Vector((0, lPhi * scale_y, sPhi * scale_z)),
Vector((0, lPhi * scale_y, -sPhi * scale_z)),
Vector((0, -lPhi * scale_y, sPhi * scale_z)),
Vector((0, -lPhi * scale_y, -sPhi * scale_z)),
Vector((sPhi * scale_x, 0, lPhi * scale_z)),
Vector((-sPhi * scale_x, 0, lPhi * scale_z)),
Vector((sPhi * scale_x, 0, -lPhi * scale_z)),
Vector((-sPhi * scale_x, 0, -lPhi * scale_z)),
Vector((lPhi * scale_x, sPhi * scale_y, 0)),
Vector((lPhi * scale_x, -sPhi * scale_y, 0)),
Vector((-lPhi * scale_x, sPhi * scale_y, 0)),
Vector((-lPhi * scale_x, -sPhi * scale_y, 0)),
]
edges = []
faces = [[0, 16, 4, 9, 8], [0, 8, 5, 13, 12], [8, 9, 1, 18, 5], [4, 14, 15, 1, 9],
[5, 18, 19, 2, 13], [1, 15, 7, 19, 18], [7, 15, 14, 3, 11], [2, 19, 7, 11, 10],
[3, 17, 6, 10, 11], [2, 10, 6, 12, 13], [6, 17, 16, 0, 12], [3, 14, 4, 16, 17]]
mesh = bpy.data.meshes.new(name="obj_Dodeca")
mesh.from_pydata(verts, edges, faces)
# useful for development when the mesh may be invalid.
# mesh.validate(verbose=True)
object_data_add(context, mesh, operator=self)
def add_icosa(self, context):
scale_x = self.scale.x
scale_y = self.scale.y
scale_z = self.scale.z
sPhi = (math.sqrt(5) - 1.0) * 0.5
lPhi = 1.0 + sPhi
verts = [
# Icosa verts
Vector((1 * scale_x, lPhi * scale_y, 0)),
Vector((-1 * scale_x, lPhi * scale_y, 0)),
Vector((1 * scale_x, -lPhi * scale_y, 0)),
Vector((-1 * scale_x, -lPhi * scale_y, 0)),
Vector((0, 1 * scale_y, lPhi * scale_z)),
Vector((0, -1 * scale_y, lPhi * scale_z)),
Vector((0, 1 * scale_y, -lPhi * scale_z)),
Vector((0, -1 * scale_y, -lPhi * scale_z)),
Vector((lPhi * scale_x, 0, 1 * scale_z)),
Vector((lPhi * scale_x, 0, -1 * scale_z)),
Vector((-lPhi * scale_x, 0, 1 * scale_z)),
Vector((-lPhi * scale_x, 0, -1 * scale_z)),
]
edges = []
faces = [[0, 6, 1], [0, 1, 4], [4, 5, 8], [4, 10, 5], [2, 5, 3], [2, 3, 7],
[3, 10, 11], [1, 11, 10], [6, 7, 11], [7, 6, 9], [2, 9, 8], [0, 8, 9],
[3, 5, 10], [2, 8, 5], [0, 4, 8], [1, 10, 4], [3, 11, 7], [2, 7, 9],
[0, 9, 6], [1, 6, 11]]
mesh = bpy.data.meshes.new(name="obj_Icosa")
mesh.from_pydata(verts, edges, faces)
# useful for development when the mesh may be invalid.
# mesh.validate(verbose=True)
object_data_add(context, mesh, operator=self)
class OBJECT_OT_add_tetrapos(Operator, AddObjectHelper):
"""Create a new Mesh Object"""
bl_idname = "mesh.add_tetrapos"
bl_label = "Add Mesh Object"
bl_options = {'REGISTER', 'UNDO'}
scale: FloatVectorProperty(
name="scale",
default=(1.0, 1.0, 1.0),
subtype='TRANSLATION',
description="scaling",
)
def execute(self, context):
add_tetrapos(self, context)
return {'FINISHED'}
class OBJECT_OT_add_tetraneg(Operator, AddObjectHelper):
"""Create a new Mesh Object"""
bl_idname = "mesh.add_tetraneg"
bl_label = "Add Mesh Object"
bl_options = {'REGISTER', 'UNDO'}
scale: FloatVectorProperty(
name="scale",
default=(1.0, 1.0, 1.0),
subtype='TRANSLATION',
description="scaling",
)
def execute(self, context):
add_tetraneg(self, context)
return {'FINISHED'}
class OBJECT_OT_add_tetrastar(Operator, AddObjectHelper):
"""Create a new Mesh Object"""
bl_idname = "mesh.add_tetrastar"
bl_label = "Add Mesh Object"
bl_options = {'REGISTER', 'UNDO'}
scale: FloatVectorProperty(
name="scale",
default=(1.0, 1.0, 1.0),
subtype='TRANSLATION',
description="scaling",
)
def execute(self, context):
add_tetrastar(self, context)
return {'FINISHED'}
class OBJECT_OT_add_octa(Operator, AddObjectHelper):
"""Create a new Mesh Object"""
bl_idname = "mesh.add_octahedron"
bl_label = "Add Mesh Object"
bl_options = {'REGISTER', 'UNDO'}
scale: FloatVectorProperty(
name="scale",
default=(1.0, 1.0, 1.0),
subtype='TRANSLATION',
description="scaling",
)
def execute(self, context):
add_octahedron(self, context)
return {'FINISHED'}
class OBJECT_OT_add_cube(Operator, AddObjectHelper):
"""Create a new Mesh Object"""
bl_idname = "mesh.add_cube"
bl_label = "Add Mesh Object"
bl_options = {'REGISTER', 'UNDO'}
scale: FloatVectorProperty(
name="scale",
default=(1.0, 1.0, 1.0),
subtype='TRANSLATION',
description="scaling",
)
def execute(self, context):
add_cube(self, context)
return {'FINISHED'}
class OBJECT_OT_add_dodeca(Operator, AddObjectHelper):
"""Create a new Mesh Object"""
bl_idname = "mesh.add_dodeca"
bl_label = "Add Mesh Object"
bl_options = {'REGISTER', 'UNDO'}
scale: FloatVectorProperty(
name="scale",
default=(1.0, 1.0, 1.0),
subtype='TRANSLATION',
description="scaling",
)
def execute(self, context):
add_dodeca(self, context)
return {'FINISHED'}
class OBJECT_OT_add_icosa(Operator, AddObjectHelper):
"""Create a new Mesh Object"""
bl_idname = "mesh.add_icosa"
bl_label = "Add Mesh Object"
bl_options = {'REGISTER', 'UNDO'}
scale: FloatVectorProperty(
name="scale",
default=(1.0, 1.0, 1.0),
subtype='TRANSLATION',
description="scaling",
)
def execute(self, context):
add_icosa(self, context)
return {'FINISHED'}
# Registration
def register():
bpy.utils.register_class(PlatonicsMenu)
bpy.types.VIEW3D_MT_mesh_add.append(PlatonicsMenuAdd)
bpy.utils.register_class(OBJECT_OT_add_tetrapos)
bpy.utils.register_class(OBJECT_OT_add_tetraneg)
bpy.utils.register_class(OBJECT_OT_add_tetrastar)
bpy.utils.register_class(OBJECT_OT_add_octa)
bpy.utils.register_class(OBJECT_OT_add_cube)
bpy.utils.register_class(OBJECT_OT_add_dodeca)
bpy.utils.register_class(OBJECT_OT_add_icosa)
def unregister():
bpy.utils.unregister_class(PlatonicsMenu)
bpy.types.VIEW3D_MT_mesh_add.remove(PlatonicsMenuAdd)
bpy.utils.unregister_class(OBJECT_OT_add_tetrapos)
bpy.utils.unregister_class(OBJECT_OT_add_tetraneg)
bpy.utils.unregister_class(OBJECT_OT_add_tetrastar)
bpy.utils.unregister_class(OBJECT_OT_add_octa)
bpy.utils.unregister_class(OBJECT_OT_add_cube)
bpy.utils.unregister_class(OBJECT_OT_add_dodeca)
bpy.utils.unregister_class(OBJECT_OT_add_icosa)
if __name__ == "__main__":
register()