Metadata-Version: 2.1
Name: procedural-buildings
Version: 1.0.1
Summary: Tools for the procedural modelling of buildings
Home-page: https://github.com/JUST0M/procedural-buildings
Author: Tom Mason
Author-email: tommasonuk@yahoo.co.uk
License: UNKNOWN
Description: # Procedural Generation of Buildings
        
        Welcome to my third year university project on the procedural generation of buildings!
        
        There are two main goals for this project:
        * Design a grammar language that can be used to describe buildings with sets of procedural rules, which can then be transformed into a 3D models
        * Given an example set of 3D buildings, attempt to reverse engineer a grammar from the given buildings, which could then be used to create more buidings similar to the examples
        
        To discover how I achieved the above, I encourage you to read (or perhaps just flick through!) my [project report](https://github.com/JUST0M/procedural-buildings/blob/master/doc/project_report.pdf). The report also teaches you how to write your own grammars and demonstrates some of my own architectural creations.
        
        If you want to have a go at writing your own grammars and generating your own buildings, read on!
        
        ## Installation (using Pip)
        
        This project is packaged and available on [PyPi](https://pypi.org/project/procedural-buildings) and can be installed (or updated) with the following:
        
        ```
        python -m pip install --upgrade procedural-buildings
        ```
        
        ## Basic usage
        
        ### Writing your first grammar
        
        If you want to learn the ins and outs of writing a grammar, read [my report](https://github.com/JUST0M/procedural-buildings/blob/master/doc/project_report.pdf). Here we'll learn by example and leave the rest to intuition!
        A grammar is **run** on an initial **scope** (a 3D bounding box) and consists of a set of rules, one of which is a **start rule**. By default, the start rule is `plot` but you can specify a different name if you'd prefer. The following grammar takes the initial scope and splits it in half along the x-axis into two cuboids:
        
        ```
        plot --> split(x){~1 : I(rect) | ~1 : I(rect)}
        
        ```
        
        Save the above to a new file called `split_grammar` (make sure to include a newline at the end as above). We can then generate a `.obj` file from the grammar using the following on the command line:
        
        ```
        python -m procedural_buildings -i split_grammar -o split.obj
        ```
        
        This will create a 3D model in `split.obj`. Open this in your favourite 3D model viewer (I recommend [Blender](https://www.blender.org/)), noting that the positive z-axis corresponds to upward and the positive y-axis corresponds to foward. Blender lets you specify these axis directions when you import an object. You should see a 10x10x10 cube which is cut in half along the x-axis. To change the initial scope (which defaults to the 10x10x10 cube you see), use the `-s` (or `--start-scope`) option. To see a full list of options, use `-h`:
        
        ```
        python -m procedural_buildings -i split_grammar -o split.obj -s 2,2,0,10,5,20
        ```
        
        Play around with different start scopes and check out the results.
        
        ### Creating a house
        Now lets look at a slightly more interesting example - a house with a garage. Copy the following grammar into a new file called `house_grammar`. Once again, don't forget the newline (I really ought to change that "feature"!):
        
        ```
        plot --> split(x){~2 : house | ~1 : garage}
        house --> split(z){~2 : I(rect) | ~1 : I(triangle)}
        garage --> split(z){~1 : I(rect) | ~2 : nil}
        
        ```
        
        Now generate the buildings with:
        ```
        python -m procedural_buildings -i house_grammar -o house.obj
        ```
        
        Take a look at `house.obj` and try and understand how it's been generated by the grammar we wrote. Play around with some numbers in the grammar to see how it affects the result.
        
        As a final example, let's adapt `house_grammar` so it has some randomness. Copy the below into a new file called `house2_grammar`:
        
        ```
        plot --> split(x){~2 : house | ~1 : garage} : 0.5
        plot --> split(x){~1 : garage | ~2 : house} : 0.5
        house --> split(z){~2 : I(rect) | ~1 : I(triangle)}
        garage --> split(z){~(rand(0.75,1.25)) : I(rect) | ~2 : nil}
        
        ```
        
        See if you can figure out what the result will look like then generate a building:
        ```
        python -m procedural_buildings -i house2_grammar -o house2.obj
        ```
        
        Notice that if you run the above command a few times, the result will be different each time.
        
        To generate many buildings from our grammar, we can use the following options:
        * `-n` (or `--num_buildings`) (default 1) specifies the number of buildings to generate from the grammar
        * `-d` (or `--separation`) (default 10) specifies the distance between buldings.
        * `-f` (of `--file_per_obj`) specifies whether to use a separate file for each building. In this case the `-d` option will be ignored and the given output file name will be used as the file prefix to use for the output files.
        
        Let's create 10 buildings each 2 units apart. We'll stick to one output file for now:
        ```
        python -m procedural_buildings -i house2_grammar -o house2.obj -n 10 -d 2
        ```
        
        ### How about backwards?
        
        To create a grammar from a given buildings, we can use the `-r` (or `--reverse`) flag. Now, our input file is the `.obj` file and the output is a grammar file. Let's try and reverse engineer the grammar we used to create the first house:
        
        ```
        python -m procedural_buildings -i house.obj -o house_engineered_grammar -r
        ```
        
        Take a look at `house_engineered_grammar` and you should see its equivalence to the original `house_grammar`.
        
        Now lets try and engineer a grammar from mutliple example buildings. First create 10 example buildings using `house2_grammar`. We'll put them in separate files this time by using the `-f` flag. The output file name `example` will be used as the prefix for the 10 output files so we'll get `example0.obj`, `example1.obj`, ... , `example9`:
        
        ```
        python -m procedural_buildings -i house2_grammar -o example -n 10 -f
        ```
        
        Now we can create a grammar from the example buildings. Create a new file called `examples` and enter the file names of the example buildings:
        ```
        example0.obj
        example1.obj
        example2.obj
        example3.obj
        example4.obj
        example5.obj
        example6.obj
        example7.obj
        example8.obj
        example9.obj
        ```
        
        Now, create a grammar from the buildings. The input file will be the file containing the file names (it knows it's a list of file names rather than a single object input by checking for a `.obj` extension):
        ```
        python -m procedural_buildings -i examples -o house2_engineered_grammar -r
        ```
        
        Take a look at the engineered grammar. You should be able to see the similarity to the original `house2_grammar`.
        We can now use our engineered grammar to create more buildings. Note that we'll have to specify that the start rule for this grammar is `rule0`:
        
        ```
        python -m procedural_buildings -i house2_engineered_grammar -o more_houses.obj -n 10 -R rule0
        ```
        
        You've now generated 10 buildings similar to the 10 examples.
        
        To see some more complex examples, check out [my report](https://github.com/JUST0M/procedural-buildings/blob/master/doc/project_report.pdf) or create your own buildings!
        
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.6
Description-Content-Type: text/markdown
