#**********************************************************************************************
#pyramidaze.py
# - This script adds a "pyramid" over every selected quoad

# - Open this file in the Blender's text window
# - Select quads (faces that has four vertices, triangles are ingnored)
# - set py_height
# - run script (Alt + P)
# 
# there is nothing special in this script but it shows how to iterate 
# through all faces in selected object, how to get normal and how to add new faces to the mesh.
#
# Feel free to use this script any way you like, I'm sure this is very usefull ;)
#
#Ari Hayrinen 19.12.2005 (ari.hayrinen at gmail.com)
#www.arthis.jyu.fi/blender3d
#
# TODO:
# - GUI for pyramid height
#*************************************************************************************************

import Blender
from Blender import NMesh, Window, Mathutils
from Blender.Mathutils import *

#************************************************************************************************
# this is the height of the pyramid, negative values works too
#************************************************************************************************
py_height = 1

#************************************************************************************************
#functions
#************************************************************************************************

# returns face center
# faceCent is from http://en.wikibooks.org/wiki/Blender_3D:_Blending_Into_Python/Cookbook
def faceCent(f, cent=None):
        x = y = z = 0
        for v in f.v:
                x+=v.co[0]
                y+=v.co[1]
                z+=v.co[2]
        if not cent:
                return Mathutils.Vector([x/len(f.v), y/len(f.v), z/len(f.v)])
        
        # Modify the provided vec
        cent.x = x/len(f.v)
        cent.y = y/len(f.v)
        cent.z = z/len(f.v)

#************************************************************************************************
#main
#************************************************************************************************

# save Editmode state so we can restore it afterwards
editmode = Window.EditMode()
# if user is in editmode, we have to change to objectmode  
if editmode: Window.EditMode(0) 

#get selected object and get mesh data from it
objekti = Blender.Object.GetSelected()	
me = objekti[0].getData()	

# list for new faces
facet = []
# number of vertices in selected mesh
vcounter = len(me.verts) - 1    
# counter so we know where to add new faces
counter = 1    

# let's go through all faces in selected object
for face in me.faces:
    #use only selected quads    
    if face.sel and len(face.v) == 4:

        # get normal and normalize it
        normal = Vector(face.no)
        normal.normalize()
        
        #calculate center of the face
        center = faceCent(face)
        
        #multiple normal with pyramid height and add result to the center of the face
        center.x = center.x + normal[0] * py_height
        center.y = center.y + normal[1] * py_height
        center.z = center.z + normal[2] * py_height
    
        #create 5 vertices
        v=NMesh.Vert(center.x,center.y,center.z)
        me.verts.append(v)
        v=NMesh.Vert(face.v[0].co[0],face.v[0].co[1],face.v[0].co[2])
        me.verts.append(v)
        v=NMesh.Vert(face.v[1].co[0],face.v[1].co[1],face.v[1].co[2])
        me.verts.append(v)
        v=NMesh.Vert(face.v[2].co[0],face.v[2].co[1],face.v[2].co[2])
        me.verts.append(v)
        v=NMesh.Vert(face.v[3].co[0],face.v[3].co[1],face.v[3].co[2])
        me.verts.append(v)
        
        #first triangle
        f=NMesh.Face()
        f.v.append(me.verts[vcounter + counter*5-4])
        f.v.append(me.verts[vcounter + counter*5-3])
        f.v.append(me.verts[vcounter + counter*5-2])  
        facet.append(f)
        
        #second triangle
        f=NMesh.Face()
        f.v.append(me.verts[vcounter + counter*5-4])
        f.v.append(me.verts[vcounter + counter*5-2])
        f.v.append(me.verts[vcounter + counter*5-1])  
        facet.append(f)
        
        #third triangle
        f=NMesh.Face()
        f.v.append(me.verts[vcounter + counter*5-4])
        f.v.append(me.verts[vcounter + counter*5-1])
        f.v.append(me.verts[vcounter + counter*5])  
        facet.append(f)
        
        #fourth triangle
        f=NMesh.Face()
        f.v.append(me.verts[vcounter + counter*5-4])
        f.v.append(me.verts[vcounter + counter*5])
        f.v.append(me.verts[vcounter + counter*5-3])  
        facet.append(f)    
        
        counter +=1
    
#attach faces to the original mesh
for face in facet:
    me.faces.append(face)

# update the real mesh
me.update()

#if user was in edit mode, then we should't change that
if editmode: Window.EditMode(1)

Blender.Redraw()

