Gaia/gaia/__init__.py

265 lines
7.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

VERSION = 'prealpha'
import bpy
import bpy_extras
import mathutils
__ENUM_POI_TYPE__ = {
('CASTLE', 'Castle', 'creepy castle', 1),
('RUIN', 'Ruin', 'repressive ruins', 2),
('CITY', 'City', 'callous city', 3),
('VILLAGE', 'Village', 'vengeful village', 4),
('SWAMP', 'Swamp', 'scornful swamp', 5),
}
class GaiaException(Exception):
pass
class GaiaNotActivated(GaiaException):
message = 'Gaia is not activated in this scene!'
# This allows you to right click on a button and link to documentation
def gaia_manual_map():
return (
'https://docs.phryk.net/gaia/latest/index.html', #prefix
( # mappings
('gaia.scene_enable', '#scene_enable'),
('gaia.poi_add', '#poi_add'),
)
)
def gaia_enabled():
if 'gaia_enabled' in bpy.context.scene:
return bpy.context.scene['gaia_enabled'] == VERSION
return False
def gaia_collection(name=None):
"""
returns gaia root collection, or sub-collection if `name` is passed
but only if Gaia is activated in this scene.
"""
root_collection_name = '__gaia__'
if gaia_enabled():
if not 'gaia_collections' in bpy.context.scene:
bpy.context.scene['gaia_collections'] = {}
# check if root Gaia collection exists
if 'root' in bpy.context.scene['gaia_collections'] and bpy.context.scene['gaia_collections']['root'] in bpy.data.collections:
root_collection = bpy.data.collections[bpy.context.scene['gaia_collections']['root']]
else:
# add root Gaia collection if not
root_collection = bpy.data.collections.new(root_collection_name)
bpy.context.scene['gaia_collections']['root'] = root_collection.name
bpy.context.scene.collection.children.link(root_collection)
if name is None:
return root_collection
else:
if name in bpy.context.scene['gaia_collections'] and bpy.context.scene['gaia_collections'][name] in bpy.data.collections:
return bpy.data.collections[bpy.context.scene['gaia_collections'][name]]
else:
collection = bpy.data.collections.new(name)
bpy.context.scene['gaia_collections'][name] = collection.name
root_collection.children.link(collection)
return collection
raise GaiaNotActivated()
def collection_get_recursive(collection, otype=None):
objects = []
for o in collection.objects.values():
#if otype is None or isinstance(o, otype): # since we can't create new bpy.types isinstance is not accurate enough (will match any subclasses, which if passed Object to filter for empties will just not do anything)
if type(o) == otype: # strict (same class) type checking
objects.append(o)
for c in collection.children.values():
objects += collection_get_recursive(c, type=type)
return objects
class SceneEnable(bpy.types.Operator):
bl_idname = "gaia.scene_enable"
bl_label = "Enable Gaia in this scene"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
context.scene['gaia_enabled'] = VERSION
return {'FINISHED'}
class POIAdd(bpy.types.Operator, bpy_extras.object_utils.AddObjectHelper):
"""Create a new Point of Interest"""
bl_idname = "gaia.poi_add"
bl_label = "Add Point of Interest"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
col = gaia_collection('POI')
bpy.ops.object.empty_add(type='SPHERE')
obj = bpy.context.active_object
obj.name = 'New POI'
col.objects.link(obj)
bpy.context.scene.collection.objects.unlink(obj)
return {'FINISHED'}
class POIGraph(bpy.types.Operator):
bl_idname = "gaia.poi_graph"
bl_label = "Build POI graph"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
self.report({'INFO'}, "FNORP")
poicol = gaia_collection('POI')
pois = collection_get_recursive(poicol, otype=bpy.types.Object) # Object means it'll filter for empties
vertices = []
for poi in pois:
self.report({'INFO'}, "POI!")
self.report({'INFO'}, poi.name)
vertices.append(poi.location)
vertices_2d = [mathutils.Vector((vert[0], vert[1])) for vert in vertices]
tri_verts, tri_edges, tri_faces, orig_verts, orig_edges, orig_faces = mathutils.geometry.delaunay_2d_cdt(vertices_2d, [], [], 1, 0.01)
self.report({'INFO'}, f"TRIANGULATION RESULT: {tri_edges}, {tri_faces}")
mesh = bpy.data.meshes.new('POIGraph')
mesh.from_pydata(vertices, tri_edges, tri_faces)
mesh.update()
meshobj = bpy.data.objects.new('POIGraph', mesh)
meshcol = gaia_collection('Meshes')
meshcol.objects.link(meshobj)
return {'FINISHED'}
def poi_add_button(self, context):
self.layout.operator(
POIAdd.bl_idname,
text="Point of Interest",
icon='PLUGIN'
)
def poi_graph_button(self, context):
self.layout.operator(
POIGraph.bl_idname,
text="Generate POI graph",
icon='PLUGIN'
)
class POIPanel(bpy.types.Panel):
bl_idname = "OBJECT_PT_GAIA_POI"
bl_label = "Gaia POI Properties"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
def draw(self, context):
layout = self.layout
if context.active_object.type != 'EMPTY':
row = layout.row()
row.label(text="This is not a Point of Interest.")
else:
row = layout.row()
row.prop(bpy.context.active_object, 'POI_type')
class GaiaPanel(bpy.types.Panel):
bl_idname = "VIEW3D_PT_GAIA"
bl_label = "Gaia"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'Gaia'
def draw(self, context):
layout = self.layout
if not 'gaia_enabled' in bpy.context.scene:
row = layout.row()
row.label(text="Gaia not enabled.")
row = layout.row()
row.operator("gaia.scene_enable")
else: # gaia *is* enabled
if bpy.context.scene['gaia_enabled'] != VERSION:
row = layout.row()
row.label(text="Gaia enabled, but with a different version!")
row = layout.row()
row.label(text=f"Scene is on '{bpy.context.scene['gaia_enabled']}'.")
row = layout.row()
row.label(text=f"We are on '{VERSION}'.")
row = layout.row()
row.operator("gaia.scene_enable")
else:
row = layout.row()
row.label(text="Gaia enabled place step 1 button here")
def register():
bpy.types.Object.POI_type = bpy.props.EnumProperty(name="POI type", items=__ENUM_POI_TYPE__)
bpy.utils.register_class(GaiaPanel)
bpy.utils.register_class(SceneEnable)
bpy.utils.register_class(POIAdd)
bpy.utils.register_class(POIGraph)
bpy.utils.register_class(POIPanel)
bpy.types.VIEW3D_MT_mesh_add.append(poi_add_button)
GaiaPanel.append(poi_graph_button)
bpy.utils.register_manual_map(gaia_manual_map)
def unregister():
bpy.utils.unregister_class(GaiaPanel)
bpy.utils.unregister_class(SceneEnable)
bpy.utils.unregister_class(POIAdd)
bpy.utils.unregister_class(POIGraph)
bpy.utils.unregister_class(POIPanel)
bpy.types.VIEW3D_MT_mesh_add.remove(poi_add_button)
GaiaPanel.remove(poi_graph_button)
bpy.utils.unregister_manual_map(add_object_manual_map)
del(bpy.types.Object.POI_type)
if __name__ == "__main__":
register()