Skip to content

Commit

Permalink
Merge pull request #3 from panzi/master
Browse files Browse the repository at this point in the history
added GUI, use os.path.join and create release ZIP
  • Loading branch information
a1studmuffin committed Jun 19, 2016
2 parents 5cfe8a8 + a522b65 commit 8ed543a
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 24 deletions.
4 changes: 4 additions & 0 deletions .gitignore
@@ -0,0 +1,4 @@
.*
__pycache__
*~
*.zip
7 changes: 4 additions & 3 deletions README.md
Expand Up @@ -7,9 +7,10 @@ A Blender script to procedurally generate 3D spaceships from a random seed.
Usage
-----
* Install Blender: http://blender.org/download/
* Open a *Text Editor* view
* Press *Alt + O*, or go to *Text > Open Text Block* and open `spaceship_generator.py`
* Press *Alt + P* or click *Run script*
* Download newest `add_mesh_SpaceshipGenerator.zip` from releases
* Under File > User Preferences... > Add-ons > Install From File... open the downloaded ZIP file
* Under File > User Preferences... > Add-ons enable this script (search for "spaceship")
* Add a spaceship in the 3D View under Add > Mesh > Spaceship

How it works
------------
Expand Down
68 changes: 68 additions & 0 deletions __init__.py
@@ -0,0 +1,68 @@
bl_info = {
"name": "Spaceship Generator",
"author": "Michael Davies",
"version": (1, 0, 0),
"blender": (2, 76, 0),
"location": "View3D > Add > Mesh",
"description": "Procedurally generate 3D spaceships from a random seed.",
"wiki_url": "https://github.com/a1studmuffin/SpaceshipGenerator/blob/master/README.md",
"tracker_url": "https://github.com/a1studmuffin/SpaceshipGenerator/issues",
"category": "Add Mesh"
}

if "bpy" in locals():
# reload logic (magic)
import importlib
importlib.reload(spaceship_generator)
else:
from add_mesh_SpaceshipGenerator import spaceship_generator

import bpy
from bpy.props import StringProperty, BoolProperty, IntProperty
from bpy.types import Operator

class GenerateSpaceship(Operator):
"""Procedurally generate 3D spaceships from a random seed."""
bl_idname = "mesh.generate_spaceship"
bl_label = "Spaceship"
bl_options = {'REGISTER', 'UNDO'}

random_seed = StringProperty(default='', name='Seed')
num_hull_segments_min = IntProperty (default=3, min=0, soft_max=16, name='Min. Hull Segments')
num_hull_segments_max = IntProperty (default=6, min=0, soft_max=16, name='Max. Hull Segments')
create_asymmetry_segments = BoolProperty(default=True, name='Create Asymmetry Segments')
num_asymmetry_segments_min = IntProperty (default=1, min=1, soft_max=16, name='Min. Asymmetry Segments')
num_asymmetry_segments_max = IntProperty (default=5, min=1, soft_max=16, name='Max. Asymmetry Segments')
create_face_detail = BoolProperty(default=True, name='Create Face Detail')
allow_horizontal_symmetry = BoolProperty(default=True, name='Allow Horizontal Symmetry')
allow_vertical_symmetry = BoolProperty(default=False, name='Allow Vertical Symmetry')
apply_bevel_modifier = BoolProperty(default=True, name='Apply Bevel Modifier')
assign_materials = BoolProperty(default=True, name='Assign Materials')

def execute(self, context):
spaceship_generator.generate_spaceship(
self.random_seed,
self.num_asymmetry_segments_min,
self.num_asymmetry_segments_max,
self.create_asymmetry_segments,
self.num_asymmetry_segments_min,
self.num_asymmetry_segments_max,
self.create_face_detail,
self.allow_horizontal_symmetry,
self.allow_vertical_symmetry,
self.apply_bevel_modifier)
return {'FINISHED'}

def menu_func(self, context):
self.layout.operator(GenerateSpaceship.bl_idname, text="Spaceship")

def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_mesh_add.append(menu_func)

def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_mesh_add.remove(menu_func)

if __name__ == "__main__":
register()
17 changes: 17 additions & 0 deletions build.py
@@ -0,0 +1,17 @@
#!/usr/bin/env python

from os.path import abspath, dirname, join as pjoin
import zipfile

SRC_DIR = dirname(abspath(__file__))

with zipfile.ZipFile('add_mesh_SpaceshipGenerator.zip', 'w', zipfile.ZIP_DEFLATED) as arch:
for filename in [
'__init__.py',
'spaceship_generator.py',
'textures/hull_normal.png',
'textures/hull_lights_emit.png',
'textures/hull_lights_diffuse.png']:
arch.write(pjoin(SRC_DIR, filename), 'add_mesh_SpaceshipGenerator/'+filename)

print('created file: add_mesh_SpaceshipGenerator.zip')
38 changes: 17 additions & 21 deletions spaceship_generator.py
Expand Up @@ -10,6 +10,7 @@

import sys
import os
import os.path
import bpy
import bmesh
import datetime
Expand All @@ -19,6 +20,11 @@
from enum import IntEnum
from colorsys import hls_to_rgb

DIR = os.path.dirname(os.path.abspath(__file__))

def resource_path(*path_components):
return os.path.join(DIR, *path_components)

# Deletes all existing spaceships and unused materials from the scene
def reset_scene():
for item in bpy.data.objects:
Expand Down Expand Up @@ -395,35 +401,25 @@ class Material(IntEnum):
# Returns the texture.
img_cache = {}
def create_texture(name, tex_type, filename, use_alpha=True):
global img_cache
img = None
if filename in img_cache:
# Image has been cached already, so just use that.
img = img_cache[filename]
img = img_cache[(filename, use_alpha)]
else:
# We haven't cached this asset yet, so load it from disk.

# Figure out the script path depending on our context (command-line or in-editor)
script_path = bpy.context.space_data.text.filepath if bpy.context.space_data else __file__

# Get the folder the script lives in. If it lives in a .blend file, strip that off too.
script_folder = os.path.split(os.path.realpath(script_path))[0]
if script_folder.endswith('.blend'):
script_folder = os.path.split(script_folder)[0]

filepath = os.path.join(script_folder, filename)
try:
img = bpy.data.images.load(filepath)
img = bpy.data.images.load(filename)
except:
raise NameError("Cannot load image %s" % filepath)
raise IOError("Cannot load image: %s" % filename)

img.use_alpha = use_alpha
img.pack()

# Cache the asset
img_cache[filename] = img
img_cache[(filename, use_alpha)] = img

# Create and return a new texture using img
tex = bpy.data.textures.new(name, tex_type)
tex.image = img
tex.image.use_alpha = use_alpha
return tex

# Adds a hull normal map texture slot to a material.
Expand Down Expand Up @@ -455,7 +451,7 @@ def create_materials():

# Load up the hull normal map
hull_normal_colortex = create_texture(
'ColorTex', 'IMAGE', 'textures\\hull_normal.png')
'ColorTex', 'IMAGE', resource_path('textures', 'hull_normal.png'))
hull_normal_colortex.use_normal_map = True

# Build the hull texture
Expand All @@ -469,7 +465,7 @@ def create_materials():
# Add a diffuse layer that sets the window color
mtex = mat.texture_slots.add()
mtex.texture = create_texture(
'ColorTex', 'IMAGE', 'textures\\hull_lights_diffuse.png')
'ColorTex', 'IMAGE', resource_path('textures', 'hull_lights_diffuse.png'))
mtex.texture_coords = 'GLOBAL'
mtex.mapping = 'CUBE'
mtex.blend_type = 'ADD'
Expand All @@ -480,7 +476,7 @@ def create_materials():
# Add an emissive layer that lights up the windows
mtex = mat.texture_slots.add()
mtex.texture = create_texture(
'ColorTex', 'IMAGE', 'textures\\hull_lights_emit.png', False)
'ColorTex', 'IMAGE', resource_path('textures', 'hull_lights_emit.png'), False)
mtex.texture_coords = 'GLOBAL'
mtex.mapping = 'CUBE'
mtex.use_map_emit = True
Expand Down Expand Up @@ -805,7 +801,7 @@ def generate_spaceship(random_seed='',
# Render the scene to disk
script_path = bpy.context.space_data.text.filepath if bpy.context.space_data else __file__
folder = output_path if output_path else os.path.split(os.path.realpath(script_path))[0]
filename = 'renders\\' + timestamp + '\\' + timestamp + '_' + str(frame).zfill(5) + '.png'
filename = os.path.join('renders', timestamp, timestamp + '_' + str(frame).zfill(5) + '.png')
bpy.data.scenes['Scene'].render.filepath = os.path.join(folder, filename)
print('Rendering frame ' + str(frame) + '...')
bpy.ops.render.render(write_still=True)
Expand Down

0 comments on commit 8ed543a

Please sign in to comment.