#!BPY
"""
Name: 'Cityscape1'
Blender: 248
Group: 'Add'
Tip: 'Create cityscape mesh.'
"""

#re-release by meta androcto from 2007
#re-release add gpl 2009 by meta-androcto
# ***** BEGIN GPL LICENSE BLOCK ***** 
# 
# This program is free software; you can redistribute it and/or 
# modify it under the terms of the GNU General Public License 
# as published by the Free Software Foundation; either version 2 
# of the License, or (at your option) any later version. 
# 
# This program is distributed in the hope that it will be useful, 
# but WITHOUT ANY WARRANTY; without even the implied warranty of 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
# GNU General Public License for more details. 
# 
# You should have received a copy of the GNU General Public License 
# along with this program; if not, write to the Free Software Foundation, 
# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
# 
# ***** END GPL LICENCE BLOCK ***** 
#
# -------------------------------------------------------------------------- 
#CITYSCAPE V1.0
#by TaZany and Tedi
#feel free to use this for any purposes, including adding
#or changing any parts of it.
#Please contact either TaZany or Tedi (elysiun.com screen-
#names) for information, problems, or if u have developed
#a newer version,
#Thanks
#http://blenderartists.org/forum/showthread.php?t=28262&highlight=cityscape
#Parts of this script are based on the demo script from the
#Blender 2.3x Manual
#
#Description:
#This script currently generates blocks of varying size that
#can be used to simulate a city. It can also produce 
#individual "buildings" of parameters that you set.
#Currently, the actual buildings are unrealistic, 
#but future versions will hopefully produce better results.
########################################## 
import Blender 
from Blender import NMesh, Object, Scene 
from Blender.Draw import* 
from Blender.BGL import* 
from random import random 

#building parameters 
T_height = Create(5) 
T_width = Create(1) 
T_depth = Create(1) 
T_buildnum = Create(5) 
#events 
EVENT_NOEVENT = 1 
EVENT_DRAW = 2 
EVENT_RAND = 3 
EVENT_CITY = 4 
EVENT_EXIT = 5 
scene = Scene.GetCurrent() 

######################################## 
#creating the building 
######################################## 
def Building (h, w, d, x, y): 
   #create the mesh 
   mesh = NMesh.New('Block') 
   #create vertices 
   verts = [(0.0, 0.0, 0.0), (w, 0.0, 0.0), (0.0, d, 0.0), (w, d, 0.0),  
             (0.0, 0.0, h), (w, 0.0, h), (w, d, h), (0.0, d, h)] 

   for vco in verts: 
      mesh.verts.append(NMesh.Vert (vco[0], vco[1], vco[2])) 

   #mesh the vertices 
   m = [[0, 1, 3, 2], [4, 5, 6, 7], [0, 2, 7, 4], 
          [7, 6, 3, 2], [0, 1, 5, 4], [5, 6, 3, 1]] 

   for i in m: 
      f = NMesh.Face() 
      [f.v.append(mesh.verts[j]) for j in i] 
      mesh.faces.append(f) 

   #creates new object 
   block = Object.New ('Mesh', 'Block') 
   scene.link(block) 
   block.link(mesh) 
   block.setLocation (x, y, 0) 

############################################ 
#city stuff 
############################################ 
#generate buildings along xy axis 
def City1 (): 
   #generate buildings 
   for n in range(T_buildnum.val): 
      for k in range(T_buildnum.val): 
         #calculate and pass xy location 
         lx = 2 * n * T_width.val 
         ly = 2 * k * T_width.val 
         Building (T_height.val, T_width.val, T_depth.val, lx, ly) 

def City2 (): 
   #get all blocks in list 
   city = [] 
   [city.append(o) for o in Object.Get() if o.getName()[:5] == 'Block'] 

   #traverse city blocks 
   for cb in city: 
      #randomize 
      r = [random(), random(), random()] 

      for i in [0, 1, 2]: 
         if r[i] < 0.7: r[i] += 1 

      cb.setSize(r) 

############################################ 
#drawing gui 
############################################ 
def draw (): 
   global T_height 
   global T_width 
   global T_depth 
   global T_buildnum 
   global EVENT_NOEVENT, EVENT_DRAW, EVENT_RAND, EVENT_EXIT 
   #title 
   glClearColor (0.7, 0.7, 0.7, 1.0) 
   glClear(GL_COLOR_BUFFER_BIT) 
   glColor3f (0.1, 0.1, 0.1) 
   glRasterPos2d (10, 170) 
   Text("CityScape v1.0")
   #gui buttons 
   glRasterPos2d (10, 150) 
   
   T_height = Number ("Height: ", EVENT_NOEVENT, 10, 125, 210, 18, T_height.val, 1, 60, "Height of building"); 
   T_width = Number ("Width: ", EVENT_NOEVENT, 10, 105, 210, 18, T_width.val, 1, 10, "w of building"); 
   T_depth = Number ("Depth: ", EVENT_NOEVENT, 10, 85, 210, 18, T_depth.val, 1, 10, "Depth of building"); 
   T_buildnum = Number ("X and Y size of city: ", EVENT_NOEVENT, 10, 65, 210, 18, T_buildnum.val, 2, 1000, "Number of buildings"); 
   T_citygen = Button ("Generate City", EVENT_CITY, 10, 40, 210, 22, "generate city"); 
   #draw and exit buttons 
   Button ("Draw", EVENT_DRAW, 10, 20, 70, 18) 
   Button ("Rand", EVENT_RAND, 80, 20, 70, 18) 
   Button ("Exit", EVENT_EXIT, 150, 20, 70, 18) 

################################################## 
#handling events 
################################################## 
def event (evt, val): 
   if (evt == QKEY and not val): 
      Exit() 

def bevent (evt): 
   global T_height 
   global T_width 
   global T_depth 
   global T_citygen 
   global T_buildnum 
   global EVENT_NOEVENT, EVENT_DRAW, EVENT_EXIT, EVENT_RAND, EVENT_CITY 

   #gui events 
   if (evt == EVENT_EXIT): 
      Exit() 

   elif (evt == EVENT_RAND): 
      City2() 

   elif (evt == EVENT_DRAW): 
      Building (T_height.val, T_width.val, T_depth.val, 0, 0) 

   if (evt == EVENT_CITY): 
      City1() 

   Blender.Redraw() 

Register (draw, event, bevent) 