Visual definition of procedures for automatic virtual scene generation

02/10/2012
by   Drazen Lucanin, et al.
0

With more and more digital media, especially in the field of virtual reality where detailed and convincing scenes are much required, procedural scene generation is a big helping tool for artists. A problem is that defining scene descriptions through these procedures usually requires a knowledge in formal language grammars, programming theory and manually editing textual files using a strict syntax, making it less intuitive to use. Luckily, graphical user interfaces has made a lot of tasks on computers easier to perform and out of the belief that creating computer programs can also be one of them, visual programming languages (VPLs) have emerged. The goal in VPLs is to shift more work from the programmer to the integrated development environment (IDE), making programming an user-friendlier task. In this thesis, an approach of using a VPL for defining procedures that automatically generate virtual scenes is presented. The methods required to build a VPL are presented, including a novel method of generating readable code in a structured programming language. Also, the methods for achieving basic principles of VPLs will be shown -- suitable visual presentation of information and guiding the programmer in the right direction using constraints. On the other hand, procedural generation methods are presented in the context of visual programming -- adapting the application programming interface (API) of these methods to better serve the user. The main focus will be on the methods for urban modeling, such as building, city layout and details generation with random number generation used to create non-deterministic scenes.

READ FULL TEXT VIEW PDF
POST COMMENT

Comments

There are no comments yet.

Authors

page 1

page 2

page 3

page 4

06/04/2015

Programs as Polypeptides

We describe a visual programming language for defining behaviors manifes...
04/06/2015

Preprint Big City 3D Visual Analysis

This is the preprint version of our paper on EUROGRAPHICS 2015. A big ci...
02/28/2017

SceneSeer: 3D Scene Design with Natural Language

Designing 3D scenes is currently a creative task that requires significa...
12/25/2017

General-Purpose Visual Language and Information System with Case-Studies in Developing Business Applications

Learning computer programming has been always challenging. Since the six...
09/08/2020

Procedural Generation of STEM Quizzes

Electronic quizzes are used extensively for summative and formative asse...
07/17/2018

Merlin: A Language Server for OCaml (Experience Report)

We report on the experience of developing Merlin, a language server for ...
08/12/2020

Procedural Urban Forestry

The placement of vegetation plays a central role in the realism of virtu...
This week in AI

Get the week's most popular data science and artificial intelligence research sent straight to your inbox every Saturday.

1.1 The strengths of visual programming

According to Knuth’s definition in [2], an algorithm has five important features:

  • finiteness – an algorithm has to terminate within a finite amount of time

  • definiteness – every step of the algorithm must be precisely and disambigously defined

  • input – every algorithm needs to have some data given to it as input

  • output – when an algorithm terminates it should provide some data as output

  • effectiveness – an algorithm must effectively perform its task in a minimal amount of time.

The most important feature we will examine in this context is definiteness – the steps of an algorithm have to be well defined, disambiguous. We can infer from this that to implement an algorithm, a computer program also requires definiteness.

In classical programming languages (such as C, defined in [3]) the programmer writes his program down in a textual file, compiles it to machine code and is able to execute it. Textual files can consist of any imaginable text – from Shakespeare’s dramas to random gibberish. Well defined classical programs are a very small subset of text. In classical programming languages, definiteness is checked mostly through programming language syntax (it is also achieved in part through semantic and runtime checks at later stages of program compiling and running, but that will not be discussed here). Syntax is essentially a set of rules that constraint text that qualifies as valid – more details can be found in [4]. The programmer tries to describe an algorithm he has imagined by writing commands in some syntax and getting notifications about their correctness afterwards. Fig. 1.1 illustrates this approach, in which the user manually transforms his logic into syntax. This is in its essence a very black-box approach, i.e. the programmer receives only a posteriori notifications about the program’s definiteness. Of course, there are some features that help in the process, like dynamic type checking or auto-completion which save time, but they do not let the programmer fully forget about the syntax.

Figure 1.1: Classical vs. visual programming work distribution - A diagram showing the distribution of work between the programmer and the IDE in classical and visual programming

In VPLs the programmer does not input text, but uses modern GUI capabilities to drag & drop blocks of commands, connections between them etc. to describe an algorithm. This is by itself a reduction of the possible constructs that can be made by a programmer – only a couple of symbols (defined by the language designer) are available, in contrast to the whole alphabet (and more) in classical programming. The choices a programmer has to make when defining programs are limited to the ones that satisfy the language syntax only. An illustrative way to describe this would be to say that in VPLs the keyboard has been altered to contain only the keys vital to programming (sort of like the old Spectrum computers [5]). Another important aspect is the chance for preeminent notifications – notifying the programmer about the possible constraint breeches (syntactic or semantic errors) while he is still dragging an element in the GUI – possibly saving the time of making a mistake. This way a programmer is guided to satisfy constraints as proposed in [6], unlike syntax errors which just notify the user when he is already breached one. Finally there is the visual overview aspect – unlike classical programs where we have to first focus on specific letters and read them to discover what type of algorithm pattern we’re dealing with, in visual programming we have the ability to recognize certain patterns in a purely visual way (by recognizing circles, squares, lines, colour etc.), leading to an examination of the meaning of some program in a more top-down manner.

All in all, an attempt is made in VPLs to shift more of the work from the programmer to the integrated development environment (IDE). As illustrated in Fig. 1.1, the task of syntax generation is done automatically – allowing the programmer to focus more on the abstract notions of algorithm design.

To summarize, the benefits of this shift are:

  • easy syntax rule obeying – only the freedom of creating programs is given to the programmer

  • a better notification system

    – due to the fact that the IDE has more knowledge about the program and the programmer’s actions at an earlier moment than classical programming IDE

  • visual representation can be easier to grasp

All of these elements could in theory be achieved in an IDE and presented to the user as a rich, context-avare VPL. Such an environment would make the task of programming a user-friendlier experience and help a broader audience of previously end-users to start performing it.

1.2 Introduction to procedural scene modeling

Procedural scene generation or modeling is a way of creating scenes by simply defining a sequence of instructions that manipulate units of small complexity offered by the graphical engine (such as polygons, textures, simple premade objects). When the computer follows this set of instructions the result is a whole virtual scene being created – more complex than the individual units used to compose it.

Procedural modeling is in a way similar to visual programming as it presents the user only with a smaller set of possible decisions and the hard work of processing these decisions and making them compatible with the lower layer (the graphical engine in this case) is performed automatically.

The good aspects of procedural generation are:

  • it saves space – a procedure describing the scene will take much less physical memory than stating the geometrical representations of all the objects which populate it

  • it saves time – which follows quite directly from the first statement, as an artist does not have to manually specify each of the objects that are inside the scene, but instead does that on the meta-level of a procedure.

Possible applications for procedural scene generation can be found in basically any kind of virtual world (computer games, simulations etc.) – to succeed in generating content faster. Another potentially interesting target is dynamical scene creation – a scene could be generated differently each time the user visits it. In the field of computer games, this could add to the game’s replay value or even be used to create experimental games with altered laws of physics.

2.1 Advances in visual programming

In [6] a general overview of the visual programming strengths and weaknesses is examined with a lot of examples of how certain languages cope with these opportunities and challenges. The two interesting concepts are mentioned:

  • static representation – is a graphical notation used to present a program at rest sufficient to understand its meaning

  • effective use of computer display – showing only the information important to the user at that given time, considering the context

These two factors are something important if a VPL is to scale well to a project of a larger scope. By keeping them in mind as guidelines while designing a VPL, one could get closer to the usability classical programming currently offers.

2.1.1 Dataflow VPLs

In functional programming, functions are in focus, i.e. the main flow of the program represents data going through a sequence of functions. The order in which these functions will be executed is only partially controlled by function chaining and other than that the programmer does not concern himself with this matter – the interpreter, a shell that runs the functional program will decide on the order of the independent functions. More about functional programming on the example of LISP can be read in [7].

Hand in hand with the logic of functional programming go dataflow VPLs, which are basically their visualisation. Blocks represent functions and the connections represent “pipes” through which the data flows. Dataflow VPLs are a big group in visual programming. They are described from an abstract level and put into context with functional programming in [8].

Because the input and output interfaces of each block are determined as the domain and codomain sets of a coresponding function, it is possible to precisely determine what sort of data is contained in a certain pipe. This is useful for contextually relevant nottifications (for example suggesting appropriate blocks that the pipe can be connected to), which is a strong advantage of visual programming, as mentioned in [6].

2.1.1.1 Domain-specific dataflow VPLs

Perhaps it is due to these positive features, that dataflow VPLs are especially attractive as domain-specific programming environments, adapted to end-users specialized in some work, without a background in programming. In any case, there exists a great number of domain-specific dataflow VPLs in all kinds of fields of expertise.

LabView [9] and Simulink [10] can be mentioned as very popular representatives of dataflow VPLs. They are mostly aimed for system modeling and development with a strong emphasis on a modular, engineering approach through encapsulation.

Some other examples of domain-specific dataflow VPLs and their domains can be seen in Table 2.1.

Domain VPL
engineering LabView [9], Simulink [10]
data mining, web crawling Rapidminer, Yahoo Pipes [11]
architecture Grasshoper [12]
spatial analysis ProVal 2000 [13]
image analysis Harpia [14]
audio synthesis SynthMaker [15]
visualisation, animation Quartz Composer [16], Toon Boom Animate Pro [17], VSXu [18]
robotics Lego Mindstorms NXT [19]
game creation SourceBinder [20]
Table 2.1: Domain-specific dataflow VPLs - An incomplete list showing some of the dataflow VPLs that exist for certain professional domains.

2.1.2 Flowcharts

As a contrast to dataflow VPLs based on functional programming, there is a family of VPLs visually closer to flowcharts and imperative programming. An example imperative programming language is C [3]. In imperative programming the programmer defines each step of a program as a command and the order of these commands strictly determines the order in which the computer executes them. This command flow can be controlled using mechanisms such as loops or branches. In a flowchart, a visualisation of an imperative program, we may say that it is the ordering, arranging the sequence of commands (blocks) and not the data itself that is the center of focus. The data somehow remains in the background, stored in variables and fetched when needed.

Even though there appears to be more dataflow than flowchart VPLs (probably due to it being more easy to grasp for newcomers – no need to study abstract notions such as variables and flow control), professional programmers tend to use imperative languages more as can be seen in Fig.

2.1 (results taken from [21]) – Python [22]and C [3] as mostly imperative languages have a much bigger user base than LISP [7], which is a functional language. It seems from these statistics that if a VPL is to scale well, be adaptable to bigger projects as defined by Burnett et al. [6], it should be imperative in its basis. Because of this, flowchart VPLs were chosen as the focus in this thesis.

KTechlab [23] is a flowchart VPL used to describe hardware components. Scratch [24] is a good example of a WHILE language flowchart VPL that has taken the role of education through fun and interactive app programming. One drawback in Scratch is that it does not present the user with the source code generated from his flowchart, thus not encouraging gradual transition to classical programming as the user gets more experienced. Alice [25] is another example of an educational VPL that lets the user build interactive graphical applications, while teaching him basic programming concepts.

Figure 2.1: Programming language popularity - The count of monthly commits made in a certain programming language in open source projects during the last decade. Orange is C, purple is Python and green is LISP.

2.2 Advances in procedural scene modeling

Since the idea of being able to generate objects or even whole scenes from simple procedures has always been enticing - both from the memory-saving and the artist-time-saving perspective, there has been a lot of research in this field.

2.2.1 Grammar-based general approach

The most-used approach for procedural modeling is using formal grammars [4], drawing from the same methods used for programming language syntax parsing (the direction is a bit different in procedural modeling, though – sequences of tokens are randomly generated to satisfy the production rules, unlike programming languages, where existing sequences are parsed to determine the order of applied productions).

Two variants exist – L-systems [1], which operate on strings, and shape grammars [26], which operate directly on shapes. The basic idea is the same, though – the user expresses the desired procedure by defining a set of grammar rules – productions from one sequence of tokens to a different sequence of tokens. The user is, therefore, required to know the theory of formal grammars, production rules, syntax etc.

2.2.1.1 L-systems

Using L-systems – an algorithmic, procedural generation method for virtual object generation, real-world objects can be replicated. This method relies on randomly choosing productions in formal string grammars [4] while keeping predefined global constraints satisfied. The resulting strings represent graphical models – they encode them. From these encodings the actual graphical models can be drawn in a scene. The way the user affects end-models is by defining the grammar and the constraints. This method was proposed in [1] for plant modeling.

L-systems were later adapted to building and city generation, as proposed in [27] – they achieved good results, which can be seen in CityEngine, a commercial system for procedural city generation that implements the methods proposed in [27, 28]

2.2.1.2 Shape grammars

A similar approach was developed by Stiny as shape grammars in [26]. This is also a formal grammar-based approach, but it operates directly on shapes, unlike L-systems which operate on strings.

Shape grammars have also, with slight variations, been used for procedural building modeling in [29, 27]

2.2.2 Often-used algorithms

2.2.2.1 Geographical data consideration

A method to make an urban scene more realistic is taking sample geographical data into consideration in the modeling process. This approach was proposed in [28] and is used in CityEngine in a way that the user can provide various colour-coded map images as input, such as:

  • a topographic map

  • a population density map

The maps can then be analysed and the data taken into consideration during the generation process (for example, higher buildings could be built in areas with higher population densities).

2.2.2.2 Road generation

Both in CityEngine [28] and Citygen [30], a parallel growth algorithm has been used for road generation, which allows for natural-looking street networks, while being computationally efficient.

In [30], Kelly also proposes a sampling algorithm with randomness and constraints for mapping roads to terrain in a more natural way, not simply following a straight path. He also proposed several strategies for coping with varying terrain altitudes:

  • minimum elevation

  • minimum elevation difference

  • even elevation difference

The benefits of these methods are the roads which seem to integrate well with the terrain. This results in more convincing scenes for the user.

2.2.2.3 District generation

After generating a road network, the enclosed regions can be used as city cells – areas for buildings and parks, or districts on a wider scale (areas enclosed by bigger roads). A way to detect these regions can be by using the Minimum Cycle Basis algorithm as proposed in [30].

Another approach that might be used for district generation is by using Voroni diagrams, a method of generating natural-looking cells, as explained in [31].

2.2.3 Post-processing of the scene

Some of the tools available for procedural generation of scenes offer a possibility of post-processing the scene – editing it after it has been created. This allows the user to change some details, play with the placement of objects etc. so that the scene can better fit his needs. This is implemented through a what-you-see-is-what-you-get (WYSIWYG) editor of the scene, where the user can move elements around and see what the scene looks like at the same time through real-time rendering.

The CityEngine [28] and Citygen [30] systems offer WYSIWYG editors for urban scenes. In a prototype presented in [32], transformation and merging operators for topology preserving and topology changing transformations based on graph cuts are proposed. Such techniques allow for more intuitive calibration of the final scene through drag-and-drop interaction and are a good combination of procedural and manual modeling of the scene.

3.1 Visual programming goals

In this thesis, the methods required to create a VPL for editing and executing flowcharts with an additional ability to generate classical source code from them will be presented. The goal programming language (in which the code is to be generated) is a structured WHILE language (such as Python [22]), to offer good readability. This would give the user another educational step between Scratch [24] and classical programming, where he would be able to draw a flowchart and generate good quality, readable code from it and execute it. The code readability would let him study and understand the syntax created from his flowcharts.

These methods will be explained on an example of vIDE, a VPL that was built to fulfil the requirements. The motive behind vIDE is to lower the barrier of learning programming for children as well as for other experts who do not know a programming language syntax, but need to implement certain algorithms.

Firstly, a flowchart editor is needed and the problem of synchronizing a graphical representation with a model will be addressed. Secondly, we will cover the problem of generating code in a certain classical programming language from this model.

An interesting aspect of code generation that will be explored is the internal representation of an algorithm in a GOTO manner, the most similar in logic to a flowchart, and its transformation to a WHILE language data structure. GOTO and WHILE languages are formally defined in [34]. In short – GOTO languages use a GOTO instruction to jump anywhere in the program, while WHILE languages have WHILE and IF instructions to conditionally execute a certain block (zero, one or multiple times) thus adding more structure and making the flow more predictable. It will be shown that the transformation from a GOTO language to a WHILE language representation is a very practical way of building a flowchart VPL because of the difference between the VPL conceptual model and the output classical programming language.

3.2 Procedural modeling goals

Unlike CityEngine [28] and similar solutions based on L-systems which rely on editing formal grammars [4], the approach we wish to pursue is to allow the user to define the scene modeling procedure in a program – without going to the meta level of programming language grammars. Diversity can be achieved by simply using random numbers in the program, instead of randomly generating “static” programs (which define scenes deterministically, without any randomness) as is the case with L-systems. This will result in the user having to know only simple programming. He would not need to know the theory of grammars, productions, tokens, final symbols etc. which is required to describe a modeling procedure in CityEngine and other similar systems.

In this thesis, the methods of encapsulating procedural modeling algorithms in a library and exposing them to the user through an application programming interface (API) will be presented. As a proof-of-concept example, an urban scene will be targeted, but similar principles might apply to different scenes as well. The underlying graphics engine used to actually render the scene objects is Ogre [35], an open source graphics rendering engine.

Furthermore, to reach an even broader audience, the programming language that is to be used for defining the scene modeling procedure is to be a visual programming language. The benefit of such a choice is two-way:

  1. procedural modeling is simpler for end-users

  2. vIDE gets a domain, possibly attracting users – similar to the way Scratch [24] can be used to create games and animations to encourage children to learn programming concepts through play

It is also important to take into account that the procedural modeling library is to be used from a visual programming language and design it accordingly. For example, since diagrams take up a lot of space and the screen reel becomes precious in visual programming [6], the commands needed to define the scene modeling procedure should work in a simple form, without any redundancy, but be configurable to specify details if necessary – that would also make concentrating on the meaning of the procedure easier.

3.3 Organisation of the thesis

The thesis will deal separately with the two matters:

  1. the methods of building a VPL, with vIDE as an example

  2. the methods of procedural scene generation and how they can be adapted to visual programming

In Chapter 4 the methods used to create a VPL are presented. In Section 4.1 a system architecture of vIDE will be explained so that certain modules can be referenced later in a more clear way. The problem of diagram-to-model mapping is discussed in Section 4.2. The motives and mechanics behind the GOTO-to-WHILE model-to-model transformation used in vIDE is given in Section 4.3. Finally, the last step of generating code is shortly explained in Section 4.4.

In Chapter 5 the methods of procedural scene generation are covered with a special emphasis on visually defining these procedures. In Section 5.1 the library libprocedural that was developed to implement the proposed methods is presented with its system architecture – the library’s interface (Section 5.1.2) and its communication and deployment alongside the Ogre graphics engine at the back (Section 5.1.3) and vIDE at the front end (Section 5.1.4). Section 5.2 analyses the library’s interface – the philosophy used to design it in accordance with visual programming in mind (Section 5.2.1), and the overview of how one would use it programmatically (Sections 5.2.2 and 5.2.3). The methods used inside the library are presented in Section 5.3.

Chapter 6 presents the results after implementing the methods proposed in the thesis in vIDE and libprocedural. In Section 6.1 we examine the capabilities of vIDE – a simple example of usage, the special cases of constraint satisfaction and a useful feature of knowledge inferring from the model. Section 6.2 introduces the possibilities of what could be created using libprocedural by simply invoking it from a classical programming language and gives a side-by-side comparison of the high-level and low-level interfaces that can be used. Section 6.3 shows the capabilities of libprocedural in combination with vIDE on a series of use-case examples, gradually covering most of the implemented procedural generation methods.

Chapter 7 places the results achieved through vIDE and libprocedural in the context of the initial objectives and related work in visual programming and procedural scene generation and summarizes the advantages and possible improvements of the used techniques.

4.1 System architecture – vIDE

The system architecture of vIDE, the prototype VPL presented in this thesis, is illustrated in Fig. 4.1.

Figure 4.1: vIDE architecture - A graphical overview of the vIDE system architecture

In a very general sense vIDE achieves the basic programming language functions through:

  • a flowchart editor – where the programmer visually defines his logic

  • a launcher (a compiler of sorts) – which transforms the user’s flowchart into source code that can be executed

The first step to achieve this is to allow the user to draw a flowchart. This was implemented using the Eclipse Graphical Modeling Framework (GMF), a framework for creating diagram editors. As seen in Fig. 4.1, an algorithm model is kept in sync with the flowchart that the user draws. GMF does this automatically according to a predefined mapping model). Further information about GMF can be found in [36].

The flowchart can be launched through the GUI when the user is happy with it. This action initiates a transformation of the algorithm model represented in a GOTO language manner to an equivalent WHILE language style representation (this is required because a WHILE representation can not be created by GMF directly from the vIDE flowchart graphical notation – this will be further discussed in Section 4.3).

From the WHILE language data structure, a concrete textual syntax can easily generate code in any programming language that relies on WHILE and IF commands to control the program flow (for example C [3] or Python [37, 22]). In vIDE, a Python syntaxer module is called to generate a Python script as the output program, equivalent to the user’s flowchart.

Once the output program is generated, the user can study the source code to learn its syntax or simply run it and observe the effects of the flowchart he drew.

In the next few sections the vital methods needed to create a VPL able to generate code will be examined using vIDE as an example implementation.

4.2 The flowchart editor – mapping a diagram to a model

In every VPL some sort of diagram editor is needed that can be map a graphical notation to a model. A flowchart editor in vIDE was created using GMF, which uses a nice abstract way of describing the diagram editor. In this part it does not really matter what sort of a diagram we are building (flowcharts are just special types of diagrams). The way GMF works is that it requires several models which define the diagram editor’s behaviour. Using these models, the diagram editor Eclipse plug-in can then be generated. Methods for building the flowchart editor will be given here in relation to the GMF architecture, but these or similar modules would be required to create a diagram editor utilizing any other technology as well.

The models needed to create a diagram editor, that is, their implementations for vIDE through GMF are:

  • A graphical definition – describing the graphical elements that the user will see in his diagram. In vIDE that would be the block, branch and connection elements.

  • A tooling definition – definitions of available tools for drawing the diagram. One tool is defined in vIDE for every graphical element.

  • An Eclipse Modelling Framework (EMF) model – this is basically the goal data structure synchronized with the diagram as the user edits it. In vIDE a simple GOTO-like algorithm data structure is used and its class diagram can be seen in Fig. 4.2.

  • A mapping model – this is the heart of the diagram editor description, it defines how to map elements from the graphical definition to an EMF model. GMF uses this definition to synchronize the diagram and the model automatically. If an algorithm model uses a GOTO representation (as is the case in vIDE), this mapping is pretty straightforward – a block element maps to a block class, branch to branch etc.

Such modular design allows for good control of the resulting diagram editor. By implementing all of the mentioned models, vIDE can provide a working flowchart editor through the Eclipse IDE (with additional benefits that will be examined in Chapter 6).

Figure 4.2: vIDE class diagram - Algorithm EMF model used in vIDE - a GOTO-like data structure generated from the flowchart

4.3 An algorithm for the GOTO-to-WHILE transformation

After an algorithm model has been created, a program could be generated disambiguously. The problem is that the algorithm model is described in a GOTO language manner and we want to generate a program in a WHILE language, motivated by the goals stated in Section 3.1. To solve this, a model-to-model transformation is necessary. First, we will examine the reasons for organizing the data structures in such way more deeply and then the transformation algorithm itself will be given.

4.3.1 Reasons for using a GOTO language

For a representation of algorithms in flowcharts, a GOTO language seems more natural, because of a single connection (or we might say flow) going out of every block.

Other possible graphical representations were explored - with special graphical elements for WHILE and IF commands, but these approaches were dropped, because there would have to be multiple outgoing flows and additional explanations of these elements’ behaviours would be necessary, which would complicate the usage of vIDE.

4.3.2 Reasons for NOT using a GOTO language

It was explained in the last subsection that GOTO is a suitable language for the graphical representation of an algorithm. For the generated programs, on the other hand, WHILE-languages should generally be used instead.

In his open letter, Dijkstra expressed his opinion against using GOTO instructions in programming [38], while Knuth said in [39] that they can be useful at times. Generally, we can conclude that GOTO commands can be used carefully (an example of proper usage of GOTO commands in modern languages are exceptions), but WHILE, IF and similar commands should be used to create structured programs. Structured programs are defined in [39].

One of the good sides of structured programming is readability – if a programmer wants to see what was generated from his flowchart, it would be much more readable (not to mention educational) if loops would be interpreted as WHILE commands and normal branches as IF commands (instead of everything mapping to simple GOTO commands).

A WHILE language representation of the flowchart might be useful to have in a data structure for visual purposes as well, because the usage of structured programming would allow features such as graph folding (letting the programmer hide unnecessary nodes manually or let the IDE do it for him using context-aware technologies such as [40]).

Python was chosen for an output programming language in vIDE because of its simplicity and readability, so another practical reason for not generating code using GOTO commands in vIDE in specific is that Python does not have a GOTO command in its language.

4.3.3 Combining the two - the constrained GOTO

When a pure GOTO language representation of an algorithm is stored in a data structure it is clearly a graph – it can contain loops to already executed commands. When an algorithm represented in a structured WHILE programming language is stored it is possible to represent it by a tree – an intuitive example of this is the ability to fold code in environments such as Eclipse [41]. The reason this is possible is that the body of a WHILE loop or an IF body can not jump to any other instruction outside its parent WHILE/IF instruction. Even though it is possible to model WHILEs and IFs using GOTO commands, the GOTO would also allow “forbidden jumps” (for example to the same command), therefore necessitating a graph data structure for the algorithm’s representation.

Since graphs can not generally be represented by trees, to be able to transform a GOTO representation to a WHILE representation, constraints have been introduced in vIDE on the flowcharts that can be drawn in it:

  • loops can only be drawn to go back to the last branch predecessor (of the same branching depth)

  • if a branch is not a loop its children blocks must join at one point (they need to share a common successor) on the same branching depth

Using these two constraints we effectively mask a WHILE language using a GOTO language, without the fear of not being able to convert it to a tree representation.

4.3.4 The transformation algorithm

Once we set the constraints, we can define an algorithm for transforming a constrained GOTO algorithm (illustrated in Fig. 4.2) into a WHILE algorithm.

The GOTO-to-WHILE algorithm is essentially a depth first search (DFS) that recursively processes the nodes of a GOTO algorithm collecting single instructions to blocks and translating branches to WHILE or IF commands using processed node “colouring” (see [42] for DFS and similar graph traversal algorithms).

  while instruction exists do
     if instruction is a block then
        nothing special
     end if
     if instruction is a branch then
        trueChild true child of the branch
        if G2W(trueChild) found processed command then
           translate instruction to WHILE
        end if
        if G2W(trueChild) reached program end then
           translate instruction to IF
        end if
     end if
     mark instruction processed
     instruction next instruction
  end while
Algorithm 1 The GOTO-to-WHILE algorithm

The basic idea can be seen in Algorithm 1. It is meant to be called as G2W(instruction), where the first instruction of the main block of the algorithm should be provided to the initial function call.

Note that G2W(trueChild) represents processing child instructions of a branch in the case of the condition being met – going further in depth recursively on the true side. Also, this is only a sketch of the “interesting” parts of the algorithm. In an actual implementation:

  • All the constraints need to be checked and any breeches communicated to the user.

  • Also, resolving the IF transformation is a bit more complex and requires tracing the condition being false branch as well and fixing the tree afterwards (because at first all the successor instructions would be added to IF as children – an intersection, i.e. the end of the IF instruction, can only be found after tracing the second branch – false).

  • The last omitted aspect is the communication – a lot of information needs to be passed as arguments to recursive function calls or using a stack to identify the true state of the graph.

These details were skipped, since they would complicate the pseudo-code a lot and they can be implemented quite routinely.

4.4 Model-to-code transformation

After we have the algorithm represented in a tree-like structure of a structured WHILE language, the code generation is very simple and consists of:

  1. a DFS through the tree

  2. translating instruction objects to strings in the goal language syntax (Python in vIDE’s example) on a one-to-one mapping basis.

The result of this last procedure is a textual file containing a classical program. This program contains the steps equivalent to the flowchart used to generate it, specified through the goal language syntax. A computer can then execute this program and show the user the outcome of his flowchart.

5.1 System architecture – libprocedural

The idea for implementing procedural generation of scenes is to use an existing graphics engine, Ogre [35], capable of importing models, placing them in a virtual scene etc., add additional higher-level logic on top of the graphics engine for procedural generation and encapsulate it in a library – libprocedural. The user would then get presented with libprocedural’s API for scene modeling, which would be on a higher level of abstraction than Ogre, and would be able to quickly write a definition of a scene – by writing a program which interfaces with libprocedural, i.e. instantiates its objects and calls its methods. Two main qualities are required from the API:

  1. it should be expressive – the user should be able to build complete scenes using them in a relatively small amount of code

  2. the syntax should be clean and simple – since the end goal is to be able to visually define the procedure for scene generation (as described in Section 3.2) and this API will be the exposed in a VPL.

Since vIDE, the goal VPL, generates code in Python from the drawn flowchart, as mentioned in Section 4.1, it would be desireable that the procedural generation library could be accessed from Python as well. The library libprocedural is, on the other hand, programmed in ++ [43] because of:

  • speed and efficiency

  • interfacing with Ogre, the underlying graphics library, also written in ++.

To overcome these challenges, Python bindings were created for the ++ library libprocedural. That way the library can be used from vIDE through Python. This goes in line with one of the already mentioned requirements put on the API – a clean and simple syntax. An additional bonus is that the core logic remains in ++, thus still staying fast 111Python is on a higher level of abstraction than C/++ and is thus slower, which is one of the reasons it is not used as much as C, as can be seen in Fig. 2.1. A rising curve can be seen, though, since Python interpreters and JIT compilers such as PyPy get more efficient and the language gets broader adoption. and being able to delegate the graphics-related work to the Ogre engine.

In order for the library to be accessible from Python, it is built as a shared object (or a dynamically-linked library, in other terms).

For clarity’s sake let us first give a simple description of what libprocedural physically is.

5.1.1 A short description of libprocedural

Because libprocedural’s internal workings are a bit complicated, let’s first try and give a short, down-to-earth description of what it is.

Looking from the filesystem side, libprocedural is a collection of ++ classes – headers (*.h) and implementation (*.cpp) files. Some of the files that are inside this library are:

  • SceneCreator.h

  • SceneCreator.cpp

  • BuildingGenerator.h

  • BuildingGenerator.cpp

  • GlobalData.h

  • GlobalData.cpp

These ++ files are compiled to a shared library, libprocedural – it can be linked by another ++ program at runtime.

The purpose of libprocedural’s classes is to manipulate an Ogre scene – add new models into it. They can be instantiated and their methods called as per the class diagram shown in Fig. 5.2. Mostly they can be operated by creating an instance of a generator class (for example a building generator) and telling it to generate something (e.g. a building) on a location provided through the parameters. One generator class can be used many time. More on the topic of using libprocedural’s API will be said later in Section 5.2.3.

The entry class for the whole library is the SceneCreator class. This class has to be instantiated in an Ogre application and a scene manager object provided to it – this object gets stored by libprocedural in a GlobalData singleton class for later use by other scene-manipulating classes. The SceneCreator has a runProcedure method, which when invoked starts the procedural scene creation process. The scene creation occures according to a file named “build_scene.py" that is required inside the working directory (denominated by a “.” on Unix).

The SceneCreator class doesn’t call other classes (BuildingGenerator etc.) directly. There is a Python layer in the middle of them, acting as an intermediary. The code executed in this Python layer is specified in the build_scene.py file. This extra layer exists so that the procedure that describes how the scene is going to be built isn’t written in ++, but in Python – a higher-level language, offering clearer and simpler syntax.

The library dependencies of libprocedural are as follows:

  • libogre – the library containing the Ogre open source graphics engine

  • libpython – the Python interpreter is required so that the scene description, which is written in Python, can be run

  • libboost_python – the Boost.Python library is built

The file dependencies of libprocedural are:

  • build_scene.py – the steps of the procedure according to which the scene gets created

The build_scene.py can be provided to libprocedural at runtime, it doesn’t have to be compiled with the library. This allows for easy editing of the way the libprocedural creates the scene.

5.1.2 Interfacing between libprocedural and Python

One of the design decisions concerning libprocedural in a framework of visually defining procedures for automatic scene generation was to have a Python interface for the library to make it more suitable to the visual programming context from which it was to be used. Let us first examine how this interfacing is performed, since it determines the architecture of the remaining elements of the library and its usage a lot.

An illustration of this design pattern can be seen inside the module libprocedural in Fig. 5.1. In short – a Python caller ++ object invokes a Python interpreter that runs an arbitrary Python script and this script can in turn access the same libprocedural ++ API again through the Python bindings. It is two-way communication. Let us now break it into smaller pieces and explain them one by one.

5.1.2.1 Python ++

To wrap the ++ classes of our library and make them accessible from Python, Boost.Python, part of the highly renowned Boost [44] ++ library was used after comparing it to some of the other options available222namely SWIG. Boost.Python can be used to wrap a set of ++ classes as a Python module containing equivalent Python classes. One of the benefits of Boost.Python is that it offers good support for some of the trickier ++ constructs such as inheritance, virtual classes/methods, default arguments (which will be important in libprocedural, as will be seen in Section 5.2.1) etc.

A set of classes is chosen to be exposed to Python. In case of libprocedural the classes representing APIs for invoking the abstract methods presented in Section 5.3 and they are shown as a class diagram in Fig. 5.2 (other helper classes exist, of course, but they are used in the implementation only, so the user is not burdened with having them exposed to him and they are not shown in the class diagram either). A description of how these classes are translated to Python is written using the Boost.Python library is required.

5.1.2.2 Automatically creating the bindings

It is possible to manually describe the Python bindings using the Boost.Python ++ library, but this can be tiresome, the description has to be synced to the library itself (if something is changed in the ++ API of the library, the Boost.Python description of the bindings has to be updated) and therefore an error-prone process.

To make this simpler, Py++ [45], a tool tool written in Python, exists for automatically parsing a ++ project and generating the Boost.Python bindings description. It can be invoked from a GUI or (for more fine-grained control) from a Python script. In the end it outputs a *.cpp file with a description of the Boost.Python bindings.

The library project can now be built with the bindings description included and libprocedural can be used from withing a Python interpreter as a module called procedural, as long as there is a procedural.so file (a file link to the original library itself, for example) in the working path.

5.1.2.3 ++ Python

It will be described in more details later that it is also required to be able to call the python interpreter from ++ to execute an arbitrary Python script (the one that gets generated from the user’s flowchart in vIDE).

This is achieved by including libpython – the library containing the implementation of the Python interpreter, in a ++ project (for example in libprocedural). After this, a function in an arbitrary Python script can be called by providing its location through the interpreter’s API.

5.1.3 Ogre – the underlying graphics library

Ogre [35] is one of the most popular open source computer graphics libraries. It is a scene-oriented, flexible 3D engine written in ++ designed for the development of applications utilising hardware-accelerated 3D graphics.

It can be used in a wide variety of domaincs:

  • games

  • simulations

  • business applications

  • anything else requiring 3D graphics

More about Ogre can be read in [46].

Due to its popularity and simplicity, Ogre was used as the underlaying graphics library in libprocedural. The idea is to delegate the scene creation task to libprocedural, that will then populate it with 3D models, using Ogre for their placement and manipulation. Basically, any application that uses Ogre can be extended with libprocedural in the part of the program where a scene has to be drawn. After that, Ogre can be used to further hone certain aspects of the scene and do the rest of the work – add interaction, animation and similar capabilities.

5.1.4 Deployment of libprocedural alongside vIDE

Let us now examine how could libprocedural be deployed in a larger framework – with vIDE as a visual programming GUI and a target Ogre application that needs a procedurally generated scene drawn inside it. Fig. 5.1 sketches the interactions between these components.

Figure 5.1: Deployment of the libprocedural library in a wider context - Components of libprocedural responsible for coupling with an Ogre application (used for rendering the scene) and vIDE (used for visually defining the procedure)
5.1.4.1 Including libprocedural

Let us suppose a user wants to deploy libprocedural in his application. The prerequisite is a target Ogre graphical application (a very simple example will do, such as the Tutorial Framework in [46]). Since libprocedural is a shared object, the inclusion to the Ogre application goes the same as for all the other such libraries – it consists of linking to the libprocedural.so file and the header files. To use the library, the user would then have to:

  1. add the path to the libprocedural ++ header files to his include path and the path to libprocedural.so file to his libraries path (and explicitly include the library itself) when he is compiling his Ogre application

  2. contain the path to the libprocedural.so file in the LD_LIBRARY_PATH environment variable for dynamic linking to work

If the library headers were located in /usr/local/include and the shared object file in /usr/local/lib (standard Unix locations), a GCC compiler command used to build a program that includes vIDE might be:

g++ -I/usr/local/include/procedural main.cpp

and the resulting executable can be run (since /usr/local/lib is already one of the default linker search paths – if it was not, it would be neccessary to add it first using standard BASH commands).

5.1.4.2 Using libprocedural

The library, libprocedural, is written in ++ and at first needs to be accessed from an Ogre application as such, since Ogre is also written in ++. Because the library is a shared object, the Ogre application can simply import it and initiate the creation of the scene via its ++ API. Let us take a look at how would this be achieved…

Once the library is included in the Ogre project, it can be used inside the part of the program where we want the scene to be created. This is achieved by first including the header:

#include "SceneCreator.h"

Once the Ogre application wishes to draw a scene, it can instruct libprocedural to do so and provide it with the Ogre scene manager object, so that it knows where to place the graphical objects it creates – this action is represented as the connection between the Ogre application and libprocedural in Fig. 5.1. The entry class for libprocedural is SceneCreator, as can be seen in Fig. 5.2. The scene manager object is given to a SceneCreator through a constructor and gets stored in libprocedural’s GlobalData singleton class to be accessible at any time and hide this low-level data away from the user. After we have a SceneCreator it is just a matter of calling the main procedure that does – procedural scene generation:

SceneCreator creator(mSceneMgr);
creator.runProcedure();

Note that the scene can additionally be “manually” processed inside the Ogre application at this point – for example shadows or special effects such as fog can be added. All the elements of the scene created by libprocedural can be accessed through the scene manager object and edited if necessary.

It remains to be seen how does the library knows what exactly should it generate…

5.1.4.3 Connecting to the scene description in Python

The program has now entered the ++ libprocedural library. This part of is presented inside the libprocedural module in Fig. 5.1. Now the library needs a description of the scene, so that it knows what and how to place in it. To achieve this, libprocedural loads the build_scene.py file (which is expected to be inside the working directory) and starts a Python interpreter which executes the script.

From now on, the program runs in Python (well, the Python interpreter to be precise, but executes commands specified in the build_scene.py file). The build_scene.py is basically a high-level scene description made using libprocedural’s Python API to call the individual procedural generation modules (such as the building, district and details generator classes, which will be explained later).

5.1.4.4 Placing graphical elements in a scene

In order to be able to invoke this API, the build_scene.py script must load the libprocedural shared object. Note that we are linking it twice – first when the Ogre application created the SceneCreator object and now once again when we want to access the individual procedural modules from Python (BuildingGenerator, DetailsGenerator…) By calling functions available in libprocedural, graphical objects get placed in the scene manager of the Ogre application that started the whole process. The scene manager is the same one that was provided during library initialization333because the object has not been deleted yet – the Ogre application is lower on the call stack and is waiting for libprocedural to finish its generation and stored in a singleton class – so that the user does not get bothered by having to know about it.

The scene description is now used to create the procedural scene. When all of the functions finish, the program control returns to the Ogre applications which started everything.

5.1.4.5 Accessing the scene description from vIDE

It was explained how to generate a scene from a definition stored in the build_scene.py Python script. This script should be situated inside the working directory – from where the Ogre application is executed. In order to create the procedural scene definition visually, a user also needs a vIDE project, aside from the ++ Ogre application project which has libprocedural linked in it. This vIDE project can then be configured to generate a Python script from the flowchart that the user draws and store it inside a build_scene.py file inside the Ogre application folder, When invoked, libprocedural can then access it. This is represented as the arrow build_script.py file traveling from vIDE to libprocedural in Fig. 5.1.

Once this is done, the user interacts with vIDE, creating blocks of code and branches, connecting them the way he likes, and once he runs it generates the Python script directly inside the Ogre application project, rewriting its old contents. Following this, the Ogre application can be started to examine the resulting scene that the user defined – by editing the flowchart.

The place where Python interface comes in is inside individual blocks and branches – where the user writes individual commans. Instead of being forced to write in ++ where he would need more commands, complex syntax, memory management etc., the user simply writes commands in Python that corespond to libprocedural’s Python API.

5.2 The library’s API

The library’s exposed classes and the programming entry point – the SceneCreator class (that was already explained in Section 5.1.4), can be seen in Fig. 5.2.

This API can be used directly in ++ or from Python, by importing the procedural Python module (see Section 5.1.4).

5.2.1 Simple by default, configurable when necessary

…was the main philosophy behind the design of individual classes that were to act as an interface to libprocedural.

This was mainly achieved by using default argument values for methods so that the user is only obliged to enter the essential ones at first, but is allowed to configure the others if he wishes to do so – keeping it simple, while retaining expressiveness.

To show this on an example – the generate method of a building generator takes only the location of a building as the necessary input (the X and Y coordinates of the building center). The user can, if he wishes to, add additional arguments such as the building height, width…

5.2.2 The classes exposed to Python

All the classes shown in Fig. 5.2 are exposed to Python, except for the SceneCreator (highlighted in the diagram, it was added since it is the entry point for an application that wants to use the library and it may therefore concern a potential user). Furthermore, they are exposed to vIDE through Python for the visual definition task – when a user is drawing his flowchart in vIDE, he can use the exposed classes inside the blocks.

Figure 5.2: A class diagram of the libprocedural API - All the important classes in libprocedural that are used as an API for procedural generation of certain parts of the scene and the “starter” SceneCreator class

5.2.3 Analysis of the API

Let us give a quick run-down of the API. Only the interface will be discussed – more detailed description of what happens inside the classes can be found in Section 5.3

5.2.3.1 Creating the city layout

The CityLayout class can be used to create districts in a city. Currently, only a Manhattan-like layout can be generated. The optional arguments to the constructor are the number of districts to create and the district diameter. After initialization, the user has to call the generate method first.

Following this the user can iterate over the district list using get_district_list() and use the district objects’ boundary vertices (iterating over them too, analogously) to place objects (for example buildings, trees…) relative to them.

5.2.3.2 Adding buildings

Buildings can be added by instantiating a BuildingGenerator and then calling the generate method. Like mentioned in Section 5.2.1, this method has the location as the obligatory arguments and the height, width etc. can optionally be specified.

Note that BuildingGenerator is a virtual class, instead one of its two subclasses – a premade and a procedural building, must be created instead. The difference between how these two types of buildings are created will be discussed in Section 5.3.

5.2.3.3 Adding details

Again, a DetailsGenerator has to be instantiated. The main method this time is place and it takes the name of the element to be placed and the location.

5.2.3.4 Adding randomness

A Randomness class exists to make all the procedurally generated content more natural. After the class is first instantiated, a random number generator is seeded. An optional argument is the scatter factor, which defaults to 0.1 or , explained later. The same instance can be used from then on. A couple of methods exist here that can be used in all the other modules to make scenes a bit more undeterministic:

  • interval(a, b) – returns a random decimal number between a and b

  • discreteInterval(a, b) – same as above, but rounds the number

  • around(x) – returns a random decimal number between and , or in other words if scatter is 0.1 we get a value

  • flipCoin() – returns true or false with a chance

By using one of these methods, values which would normally be constant and deterministict will be different everytime a program is executed. This is how a user can achieve randomness in his procedureal scene description.

5.3 Methods used for procedural generation

The methods presented here can be used to fulfill the proof-of-concept domain that was set on procedural generation as part of this research – urban modeling.

Techniques on how to deal with the low-level graphical objects that are to be used as “bricks” are proposed, along with some concrete algorithms (for city layout generation and procedural building generation). Aditionally, a method of achieving randomness is presented that results in more convincing scenes and poses a creativity tool for defining unpredictable, non-repeating scenes that change on every encounter.

5.3.1 Premade building blocks

In order to create a procedural scene of some complexity, basic building blocks are needed. In an extreme case, they might be basic graphical primitives, but generating an urban scene using only them would not be an easy task.

The approach presented here is to use certain premade elements and then be able to combine them. These elements are meshes and textures created in Blender [47], a 3D modeling program. They are on various levels of complexity, depending on what is required by certain method.

Generating premade buildings and details basically imports complete meshes made in Blender and allows the user to place them on desired locations and scale them. This is useful in creating a model of a city fast.

A bit more low-level approach is used with procedural buildings. Procedural buildings import only textures created in Blender of various elements that can be found on a building:

  • doors

  • windows

  • walls

  • the roof

Subsequently, procedural buildings will compose basic graphical primitives such as rectangles to put together a form of a building and map textures to appropriate places.

5.3.2 Building generation

Buildings form the most noticeable aspect of the city so let us first go over how they can be generated.

5.3.2.1 Premade building generation

As mentioned previously, premade buildings simply import Blender models and place them on a certain location. It is possible to scale them a bit, but in extreme cases this distorts their appearance (windows and doors get streched and skewed along with the building itself).

A collection of premade buildings is available and each time a building is generated, one of the models is chosen at random and placed inside the scene so that it seems more convincing.

5.3.2.2 Procedural building generation

As already mentioned, procedural buildings load only textures from a preexisting source. The model itself is built dynamically (using the Ogre API).

  
  
  while  do
     
     generate four rectangles on locations appropriate for walls
     map wall and window textures to the rectangles
     if  then
        map door texture to one rectangle
     end if
  end while
  generate the roof rectangle
  map the roof texture to the rectangle
Algorithm 2 The procedural building generation algorithm

The input parameters are the location of the building, its width and its height. The rough steps of the procedure for building generation are shown in Algorithm 2.

The algorithm calculates the number of floors from the building height (and rounded using the appropriately-named mathematical floor function) and builds each floor separately to fit the building base. A floor is generated by putting together walls (3D polygons) on adequate locations and mapping wall textures to them. Afterwards, window, door (only on the ground floor) and roof textures are added.

This results in buildings which scale much better to different dimensions, because the model is constructed in a way that perserves the dimensions of basic elements (doors, windows, floors) – as it should be.

5.3.3 Randomness methods

The methods behind the Randomness module are pretty straightforward, using standard random number generation on a computer and will not be discussed specifically, beyond what is already said in Section 5.2.3.4.

It is important to note the consequence of having a randomness module in procedural generation – this means that the scene will be different every time it gets generated. This might influence simple things such as the appearance of individual buildings, but it could also make a huge impact on the whole scene – different procedures altogether could be used, depending on the outcome of a single flipCoin method. This leaves a lot of room for creativity by enabling the development of unpredictable, dynamical applications.

5.3.4 City layout generation

The first step when scaling the city to larger proportions would be to calculate some sort of a geometrical frame in which to place smaller entities. That way the whole area could be subdivided into smaller portions – districts.

These districts are basically polygons that occupy a certain area of the 2D space. They are represented as a list of Vertices that form their boundary. A sketch of a layout can be seen in Fig. 5.3 – it can be seen how various objects, such as buildings, roads, pavements etc. can be placed using boundary vertices as relative position markers.

Districts also contain semantical information – for example they can be asked how far away they are from the city center. This kind of information would be useful to create different kind of procedurally generated content inside different districts, depending on their global position. For example higher buildings could be placed closer to the center.

Figure 5.3: Sketch of a district layout - Boundary verteces of a district layout used for relative placement of other objects in the scene (buildings, roads, details …)
  
  
  
  
  
  
  
  while i numDistrictX do
     
     
     
     
     
     
     
  end while
  
  while i numDistrictX do
     
     
     while j numDistrictY do
        
        
        
        
        
        create new district with vertices
     end while
  end while
Algorithm 3 The procedural Manhattan-like layout generation

Districts are generated as a Manhattan-like grid of rectangules varying in size. The only minor obstacle is that they must fit together perfectly – every two adjacent districts must have have the shared side of equal length. If we are provided with inputs: numDistrictsX and numDistrictsY, as the desired number of districts on the horizontal and vertical axis and districtDiameter, quite obviously, as the desired district diameter (height or width), the layout can be generated as shown in Algorithm 3.

In the first loop of the algorithm we generate “lines” parallel to the X and Y axes at roughly uniform distances (using the around method of the randomness module explained in Section 5.2.3 to get a bit more natural impression) and store their positions in two lists. In the second part, we go through all the (future) districts in a double loop. Inside the loop we instantiate four vertices on the appropriate positions (“two down, two up”) and create a district from them.

5.3.5 Details placement

Similarly to premade buildings, details are simply imported to the scene as premade models and placed. The collection of models can be expanded by creating new ones in Blender [47].

Some of the available models are:

  • trees

  • bus stations

  • bicycle stands

  • sign posts

  • benches

  • poles

Adding these objects to the scene creates convincing scenes, as they appear to be populated by everyday objects. Similarly to buildings, these objects could also be procedurally generated to ensure better scaling, memory preservation etc.

6.1 Visual programming capabilities

As a result of implementing all the presented methods, vIDE was built – a VPL that can be installed as an Eclipse plug-in and used to draw flowcharts and generate Python code from them. In this section its capabilities will be examined.

6.1.1 An example of vIDE usage – code generation

The example of the Euclid’s algorithm drawn as a flowchart in vIDE is shown in Fig. 6.1.

Figure 6.1: Euclid’s flowchart - A flowchart of the Euclid’s algorithm drawn in vIDE

From this flowchart the user can launch the code generation and a Python script is generated, equivalent to the algorithm defined in the flowchart:

m=6
n=2
r = m % n
while r != 0:
    m = n
    n = r
    r = m % n
print "Greatestcommondivisoris:"
print n

The branch in the flowchart was recognized by the GOTO-to-WHILE transformation algorithm to be a loop (because an instruction was pointing to its predecessor; note that a constraint was not breeched because it is the last branch) so a WHILE instruction in Python was generated.

6.1.2 Constraint satisfaction in vIDE

An example of automatic constraint satisfaction checking is implemented in vIDE, so that the user is not allowed to make a mistake in the first place. For example the user ca not connect a block to itself (a circular connection - it would result in an infinite loop), because the environment will not let him “drop” a connection on that position. This was implemented using the Object Constraint Language (OCL) [48], a language for constraint definition which is integrated with GMF in a way that the checks are done in real time – presenting the user with the currently relevant information.

The constraints defined in Section 4.3.3) will notify the user about a constraint breech only when he launches the flowchart-to-code transformation. This was not implemented in OCL, but in Java (because the check requires recursive function calls, which to our knowledge is not possible in OCL), as a part of the GOTO-to-WHILE transformation, so the notifications are not real-time.

6.1.3 Knowledge inferring in vIDE

One of the nice features of GMF is that it infers knowledge from the EMF model created to describe the diagram editor.

Figure 6.2: Branch deduction - Connection creation wth deduction (excess choices are trimmed)

An example in vIDE is that creating a connection from a branch for the first time asks the user whether it is the true or the false case, but when a true case is already present, the system deduces that there is no need in show this choice to the user as seen in Fig. 6.2, resulting in only the semantically relevant information presented.

6.2 Programmatically defining scenes with libprocedural

The procedural methods presented in this thesis and implemented in the libprocedural library can be used from a classical programming language as well as from a visual programming language. This section will cover the programatical approach – using libprocedural from ++ natively and from Python through the library’s Python interface as presented in Section 5.2.

First, the native ++ usage will be examined. Next, the same procedure specified in Python will be presented. By using these two different library interfaces in the goal of achieving the same behaviour, a good comparison between the user-friendliness of the two variations – native ++ and high-level Python, can be derived.

6.2.1 Native usage of libprocedural

To use libprocedural natively, one would have to merely import the library and instead of running the runProcedure method simply use the various classes that are offered in it and that were described in Section 5.2.3. All the code would go into a client Ogre application that uses the library when it needs to build a scene.

Let us say that we want to build a scene with a small number of physically separated districts and place buildings in a grid inside each of them. The ++ code required to achieve this would state:

SceneCreator creator(mSceneMgr);
ManhattanLayout layout(9,2000);
layout.generate();
// scene parameters
float buildingDistance = 200;
float boundaryOffset = 300;
Randomizer randomizer(0.2);
PremadeBuildingGenerator building;
int i = 0;
while (i<layout.get_district_list().size()){
        // accessing data
        District district = layout.get_district_list().at(i);
        Vertex v1 = district.boundaryVerteces[0];
        Vertex v2 = district.boundaryVerteces[1];
        Vertex v4 = district.boundaryVerteces[3];
        float buildingX = v1.x + boundaryOffset;
        // moving on the X axis
        while (buildingX<v2.x-boundaryOffset){
                float buildingY = v1.y+boundaryOffset;
                // moving on the Y axis
                while (buildingY < v4.y-boundaryOffset){
                        building.generate(buildingX, buildingY,
                                randomizer.interval(50,100),
                                randomizer.interval(40,50));
                        buildingY +=
                                randomizer.around(
                                buildingDistance);
                }
                buildingX +=
                        randomizer.around(
                        buildingDistance);
        }
   ++i;
}

The SceneCreator was created with an Ogre scene manager and after that the classes were normally instantiated using ++ syntax. First a Manhattan layout was generated, then a couple of global city parameters were set (the distance between two buildings, distance from the district boundary, a randomizer scatter factor etc.)

Figure 6.3: Generated scene defined programmatically - This scene was procedurally created from a program that uses libprocedural.

The next step is to iterate over all the districts and inside each district we move from one corner of the district’s rectangular area to the other in two dimensions – on the X and on the Y axis (using a double while-loop), with a district offset value so that there is some space left between adjacent districts. Buildings are generated inside the innermost while-loop at a predefined density (buildingDistance). The loop conditions check whether the boundary of the district was reached.

The outcome of running the program can be seen in Fig. 6.3. The scene is viewed from above so that separate districts could be discerned. A distance between clusters of building is defined by a district offset parameter and the space between any two adjacent buildings is defined by the building distance parameter.

6.2.2 Using libprocedural from Python

To use libprocedural from Python, the library has to be imported like before and the runProcedure method called. Additionally, like explained in Section 5.1.4, a build_scene.py Python script has to be provided. This time the procedure for building the scene is stated in this Python script and it uses the API described in Section 5.2.3, but from Python. Only the code to start the procedure would go into a client Ogre application that uses the library when it needs to build a scene (see Section 5.1.4). The rest of it gets delegated to the Python script and that’s why only this script is of interest in this scenario.

If we were to build the same scene as in the last section – a small number of physically separated districts with buildings in a grid inside each of them. The Python code in build_scene.py required to achieve this would state:

from procedural import *
layout = ManhattanLayout(9,2000)
layout.generate()
# scene parameters
buildingDistance = 200
boundaryOffset = 300
randomizer = Randomizer(0.2)
building = PremadeBuildingGenerator()
i =0
while (i<len(layout.get_district_list())):
    # accessing data
    district = layout.get_district_list()[i]
    v1 = district.boundaryVerteces[0]
    v2 = district.boundaryVerteces[1]
    v4 = district.boundaryVerteces[3]
    buildingX = v1.x + boundaryOffset;
    # moving on the X axis
    while (buildingX<v2.x-boundaryOffset):
        buildingY = v1.y+boundaryOffset
        # moving on the Y axis
        while (buildingY < v4.y-boundaryOffset):
            building.generate(buildingX, buildingY,\
                                  randomizer.interval(50,100),\
                                  randomizer.interval(40,50))
            buildingY += randomizer.around(buildingDistance)
        buildingX += randomizer.around(buildingDistance)
    i = i + 1

The Python script got the program control when a SceneCreator object with an Ogre scene manager already exists and is accessible, so we can start dealing with the semantics of placing scene elements right away. A Manhattan layout is generated, then a couple of global city parameters are set – note that their type doesn’t need to be explicitly declared, it is inferred from the constant used to initialize them. We iterate over all the districts and place buildings inside its area relative to its boundary vertices.

After running this procedure, the exact same scene (if we disregard the non-determinism factor coming from the use of the randomness module) gets created as the one shown in Fig. 6.3. The ++ and the Python programs described above achieve the same results.

6.2.3 Comparison of different interfaces

Since the two programs presented above for programmatically defining a scene yield the same output shown in Fig. 6.3, they are good subject for the comparison of the two languages and how they could be used to present libprocedural’s capabilities to the user.

The logic of both the Python and the ++ program is very similar, only with Python offering a visibly simpler syntax. The whole Python program is a bit shorter, due to these facts:

  • it doesn’t require variable type declaration

  • it doesn’t require special block delimiters, such as {}, which are used in ++

  • the district list and the boundary vertices list elements are all accessed using the [] delimiter

  • Python’s len() function can be used to count the numbers of elements in data structures

Most of these facts mostly come from a different programming language syntax and phylosophy employed in Python. Apart from the block delimiters, all of these aspects of a programming language would be visible to the user of the coresponding interface in a visual programming language as well.

6.3 Visual procedural modeling capabilities

In this section it will be shown how one could create a scene by using vIDE’s methods of visual programming (presented in Section 4) in combination with the methods of procedural modeling offered through libprocedural’s Python interface (as detailed in Section 5). First, a very simple example flowchart shall be given, onto which more complexity will gradually be added. Each time, the usage of an additional module will be presented.

Figure 6.4: Building generation flowchart - This flowchart will generate two buildings – one procedural and one premade.

The scene creation procedure is defined in vIDE and the resulting Python script generated and used by a simple Ogre application that uses libprocedural and the provided script to build the scene. The sky and the terrain are added manually in the Ogre application for completeness, but all other graphical objects in the scene come from libprocedural, following the procedure specified in a vIDE flowchart.

6.3.1 Creating a building

To compare the outcomes of creating a procedural and a premade building a flowchart for vIDE was drawn, as shown in Fig. 6.4. It is a fairly simple example, where the procedural module is imported and two different building generators are instantiated and used.

Figure 6.5: Generated scene with a procedural and a premade building - The procedural building (left) was composed from basic elements dynamically. The premade building (right) is a preloaded mesh scaled to fit the required size

The resulting scene can be seen in Fig. 6.5. The procedural building is composed dynamically by putting together walls and smaller textures as building blocks, while the premade building is a scaled mesh of a model previously created in Blender. It can be seen that the windows on the premade building are distorted, due to the stretching of the model, while the procedural building simply adds new floors when a higher building is required.

Figure 6.6: Details generation flowchart - This flowchart will add a row of trees to the scene – using a loop, and a billboard.

6.3.2 Adding details

The next step is to add some additional details to the scene. The flowchart from Fig. 6.4 was edited to add these details. The changes to the flowchart are shown in Fig. 6.6. The new procedure creates a DetailsGenerator object and uses it to place a row of trees in the scene (using the VPL’s loop pattern) and a billboard.

Figure 6.7: Generated scene with details - A row of trees and a billboard were added.

The resulting scene can be seen in Fig. 6.7. It can be seen that exactly 10 trees are created, as is defined in the flowchart through the loop condition. The coordinates of the trees are altered each time in the body of the loop using the expression , which results in a shift between every two trees in the scene.

6.3.3 Generating a city layout

An elegant way to enlarge the scene is by generating a Manhattan-like grid layout and then getting to the lower level of decorating a single district. We edit the previously explained flowchart from Fig. 6.6 to get a flowchart shown in Fig. 6.8. Basically, a 100-district layout is generate and we iterate through all of these districts using a loop. Inside the loop body the district’s center is calculated and a single premade building placed here. Additionally, two trees are added to the edge of the district.

Figure 6.8: Districts generation flowchart - This flowchart specifies the creation of a Manhattan-like layout and the placement of buildings and trees inside of each of the districts.

Fig. 6.9 shows the outcome of this procedure. A two-dimensional city is created with trees in the midst of it.

Figure 6.9: Generated scene utilizing a layout - Buildings and trees are placed relatively to an imaginary grid.

6.3.4 Achieving non-determinism

What is making the last scene, shown in Fig. 6.9 unconvincing is the way all the buildings and trees seem uniform, which seldom occurs in the real world. To fix this, randomness-inducing methods are added in the flowchart shown in Fig. 6.10. Not much was added here – simply an instance of the randomness class is used at certain places where exact values are used to describe objects (such as building heights, positions, tree heights…) and its interval and around methods (described in Section 5.3.3) are used to scatter them a bit.

Figure 6.10: Randomness-invoking flowchart

- This flowchart causes some unpredictability by setting building heights and locations and tree heights to random variables within a specified interval.

The outcome can be seen in Fig. 6.11 and the improvement is evident over the deterministict scene shown in Fig. 6.9, even though the change in the flowchart was not that big.

Figure 6.11: A generated city with randomly-sized buldings - This screenshot shows a city where buildings and trees look a bit more natural, as they are not all of the same height and the buildings are not positioned in a grid so strictly.

7.1 Visual programming

The proposed methods for building a VPL capable of flowchart editing and code generation have been shown to work on the example of vIDE. The VPL can be used for drawing and executing flowcharts comparable to [24], while also giving the user the novel ability of generating clear, readable Python code, achieving the goals set in Section 3.1. This is important, because it allows the users to grasp programming language syntax more easily and move to more complex, classical programming later (if needed). Such an application could find a lot of use in lowering the programming entry barrier and would be important for:

  • didactic purposes – teaching programming in an interactive and visual way

  • ease of usage – making programming more accessible to people of other professions

Features such as knowledge inferring, described in Section 6.1.3, provide a great way of leveraging advanced GUI capabilities to provide a better programming environment. This goes in line with the general guidelines for creating VPLs stated in [6] and could be considered as a visual programming equivalent of context aware systems such as Mylyn [40].

Constraint definition using OCL enables real-time notifications. This seems to be a good way to utilize the advantages of VPLs – namely a chance for preeminent notifications, as described in Section 1.1. One of the problems is checking more complex constraints. Perhaps iterative transformation to the WHILE language model while the flowchart is being drawn would allow for more lively notifications.

7.2 Procedural modeling through visual programming

The presented visual programming language was successfully used in the domain of procedural generation using a set of methods exposed to the user through an API, fulfilling the goals stated in Section 3.2.

A proof-of-concept solution for the scenario of modeling urban scenes was presented and it offers:

  • building generation – procedurally assembled and premade in Blender[47]

  • details placement – various objects can be added, such as trees, billboards, traffic signs, bus stops…

  • city layout generation – a Manhattan-like grid can be calculated, enabling arrangement of objects relative to it

  • randomness – all the parameters can be specified through intervals, rough values and random parts of the procedure could be executed even, resulting in more non-deterministic and interesting scenes

The flowcharts and resulting scenes presented in Section 6.3 show that the methods of visual programming and procedural generation can be used together to quite satisfying results – especially considering the relatively small number of procedural generation methods utilized here in comparison to the very complex systems described in [28, 30, 29, 27].

The procedural generation methods were designed in a way to suit the context of visual programming by masking the implementation complexity with a high-level interface of a scripting language Python [22] that gets presented inisde the VPL. In Section 6.2 a side-by-side comparison shows that the usage of the library’s native interface would burden the user with having to write more text inside a visual program to achieve the same functionality and we can therefore conclude that creating a high-level interface is a good choice.

The user’s expressiveness in describing the scene was maximized, while not sacrificing simplicity by using interface design patterns such as default arguments. This keeps true to the initial goals by using the “Simple by default, configurable when necessary” philosophy as described in Section 5.2.1. The user initially only has to provide the basic parameters, but is able to fine-hone his design later, which contributes to application scalability in the sense described in [6].

The approach presented in this thesis might be found useful for:

  • rapid creation of content for entertainment purposes

  • benchmarking graphical engines such as Ogre [46]

  • education motivated by easy creation of interactive content, somewhere in the line of Scratch [24] and Alice [25].

A potential for experimental interactive applications is touched upon through the non-deterministic scene definitions discussed in Section 5.3.3. The scene can be different every time it gets generated. These dynamically built scenes could offer e.g. different experience when playing a computer game for the second time, or even when entering the same virtual room for the second time.

These and similar applications could greatly benefit from being able to visually describe procedures for automatic scene generation, using the methods presented here.

References