Proceduralmodellering af bymiljøer - Danmarks Tekniske Universitet
Proceduralmodellering af bymiljøer - Danmarks Tekniske Universitet
Proceduralmodellering af bymiljøer - Danmarks Tekniske Universitet
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
SPECIALE<br />
<strong>Proceduralmodellering</strong> <strong>af</strong><br />
<strong>bymiljøer</strong><br />
Simon Tobiasen | DTU - Informatik<br />
Vejleder: Niels Jørgen Christensen<br />
26. maj 2010
Abstrakt<br />
Dette projekt vil forsøge at belyse området for proceduralmodellering <strong>af</strong> bygninger og <strong>bymiljøer</strong>.<br />
<strong>Proceduralmodellering</strong> bliver anvendt i stadigt bredere omfang inden for film og<br />
computerspilindustrien. Begrebet dækker alle former for modellering <strong>af</strong> geometriske modeller til<br />
brug i computergr<strong>af</strong>ik ved hjælp <strong>af</strong> algoritmer.<br />
På det seneste er det blevet muligt at genere bygninger og hele <strong>bymiljøer</strong> proceduralt. Dette skyldes<br />
især anvendelsen <strong>af</strong> l-systemer og udviklingen <strong>af</strong> de såkaldte shape-grammaer. En shape-grammar er<br />
en grammar, der ikke arbejder på strenge men på former (geometriske figurer), hvilket har vist sig<br />
brugbart i forbindelse med analyse <strong>af</strong> arkitektoniske stilarter. I dette projekt har jeg implementeret<br />
et system til proceduralmodellering <strong>af</strong> huse ved brug <strong>af</strong> shape-grammaer, og som udvidelse <strong>af</strong> dette<br />
har jeg bidraget med en metode til effektiv modellering <strong>af</strong> huses tage, der kan fungere sammen med<br />
de eksisterende metoder.<br />
Min metode bygger på teorien bag polygonens straight-skeleton, der er en topologisk skeletinddeling<br />
der kan bestemmes for alle polygoner. Ud fra brugerinput bygges en lagdeling <strong>af</strong> tagmodellen, og via<br />
polygon-clipping opnås en yderst fleksibel og robust metode til proceduralmodellering <strong>af</strong> tage.<br />
Abstract<br />
This project will aim at making a thorough research in the field of procedural modeling of buildings<br />
and urban environments. Procedural modeling is used increasingly in movies and computer games,<br />
and it is a term that covers all sorts of algorithms, for modeling geometrical objects in computer<br />
graphics.<br />
Lately it has become possible to procedurally generate buildings and urban environments. This is<br />
largely due to the utilization of l-systems and the development of the so called shape grammars. A<br />
shape-grammar is a grammar which does not work with symbol strings, but operates directly on<br />
shapes. These grammars have shown to be useful for analyzing architectural styles. In this project I<br />
have implemented a system for procedural modeling of buildings using shape grammars, and my<br />
contribution has been a method for efficient modeling of building roofs, that works well with the<br />
existing methods.<br />
My method extends on the polygonal straight skeleton, which is a topological skeleton subdivision<br />
that can be applied to all polygons. From user input a layered roof model is constructed, and using<br />
polygon clipping a highly flexible and robust method for procedural modeling of roofs is achieved.<br />
2
Indhold<br />
Abstrakt .......................................................................................................................................................2<br />
Abstract .......................................................................................................................................................2<br />
1 Fordord ................................................................................................................................................5<br />
1.1 Anerkendelser .............................................................................................................................5<br />
2 Indledning .......................................................................................................................................... 6<br />
2.1 Formål ..........................................................................................................................................7<br />
2.2 Afgrænsning ................................................................................................................................7<br />
2.3 Overblik ...................................................................................................................................... 8<br />
3 Baggrund ............................................................................................................................................ 9<br />
3.1 Motivation .................................................................................................................................. 11<br />
3.2 Erhvervelse <strong>af</strong> geometrisk data ................................................................................................. 14<br />
3.3 <strong>Proceduralmodellering</strong> ............................................................................................................ 20<br />
4 Litteraturstudie ................................................................................................................................ 29<br />
4.1 Terminologi .............................................................................................................................. 29<br />
4.2 Relateret arbejde ....................................................................................................................... 35<br />
4.3 Teori .......................................................................................................................................... 68<br />
5 Observationer, analyse og hypotese ................................................................................................ 78<br />
6 Min metode ...................................................................................................................................... 82<br />
6.1 Konstruktion ............................................................................................................................ 82<br />
6.2 Implementering ........................................................................................................................ 97<br />
7 Resultater ........................................................................................................................................ 106<br />
7.1 L-systemer ............................................................................................................................... 106<br />
7.2 Tage ........................................................................................................................................... 112<br />
7.3 Modellering <strong>af</strong> <strong>bymiljøer</strong> .......................................................................................................... 131<br />
8 Diskussion ....................................................................................................................................... 149<br />
8.1 Overblik ................................................................................................................................... 149<br />
8.2 Anvendelsesmuligheder .......................................................................................................... 152<br />
8.3 Fremtidigt arbejde ....................................................................................................................155<br />
9 Konklusion ...................................................................................................................................... 157<br />
10 Bibliogr<strong>af</strong>i .................................................................................................................................... 158<br />
Bilag 1: L-systemer ................................................................................................................................... 161<br />
Fraktal- l-system (L-sys1.txt) ............................................................................................................... 161<br />
3
Egetræ (Tree1.txt) ................................................................................................................................ 161<br />
Fyrtræ 1 (Tree2.txt) .............................................................................................................................. 161<br />
Bøgetræ (Tree3.txt) ............................................................................................................................. 162<br />
Fyrtræ 2 (Tree4.txt) ............................................................................................................................ 162<br />
Bilag 2: CGA-grammaer .......................................................................................................................... 163<br />
Sears Tower (SearsTower.txt)............................................................................................................. 163<br />
Petronas Towers (Petronas.txt) .......................................................................................................... 164<br />
Kontorbygning (OfficeBuilding.txt)................................................................................................... 165<br />
Villa (Mansion.txt) .............................................................................................................................. 168<br />
4
Forord<br />
Denne rapport dokumenterer gennemførelsen <strong>af</strong> et eksamensprojekt ved <strong>Danmarks</strong> <strong>Tekniske</strong><br />
<strong>Universitet</strong>, og er sidste krav for opnåelse <strong>af</strong> civilingeniørgraden.<br />
Eksamensprojektet er blevet udarbejdet hos <strong>af</strong>delingen for Computergr<strong>af</strong>ik ved Institut for<br />
Informatik og Matematisk Modellering, IMM, ved <strong>Danmarks</strong> <strong>Tekniske</strong> <strong>Universitet</strong>, DTU, under<br />
vejledning <strong>af</strong> lektor Niels Jørgen Christensen.<br />
Omfanget <strong>af</strong> dette projekt er svarende til 35 ECTS-point.<br />
Anerkendelser<br />
Først og fremmest vil jeg takke min vejleder Niels Jørgen Christensen for den kyndige vejledning, jeg<br />
har modtaget, ikke blot i forbindelse med dette projekt, men gennem hele mit udannelsesforløb på<br />
DTU. Det har altid været en lærerig fornøjelse, at deltage i kurser eller projekter med Niels Jørgen<br />
som underviser og vejleder.<br />
Dernæst vil jeg takke Bent Dalgaard Larsen for hans hjælp og vejledning i forbindelse med<br />
struktureringen <strong>af</strong> denne rapport, og for inspirerende diskussioner under alle faser i projektet. Jeg vil<br />
i denne forbindelse også takke min arbejdsgiver, Dalux, og Torben Dalgaard Larsen for at huse mig<br />
under dele <strong>af</strong> projektforløbet.<br />
Jeg vil derudover takke Mikkel Hempel for hans store hjælp og vejledning gennem mit studie, og<br />
ikke mindst i forbindelse med dette projekt.<br />
Erik Livermore skal have en særlig tak for samarbejdet under mit studie, og for at hjælpe mig med at<br />
fjerne sprog- og stavefejl i denne rapport.<br />
Til sidst vil jeg takke Anders Rong, Anders Scheel Nielsen, Henrik Münther, Carsten Kjær og Nick<br />
Bruun for deres konstruktive kritik i forbindelse med projektet.<br />
5
1 Indledning<br />
Byer spiller i dag en stor rolle i computerspil og animationsfilm. De fleste mennesker bor og færdes<br />
til dagligt i større byer, og det er kun naturligt, at dette <strong>af</strong>spejler sig i vores medier. Der er derfor et<br />
større behov for realistiske gengivelser <strong>af</strong> <strong>bymiljøer</strong>, hvad enten disse er rekonstruktioner <strong>af</strong> virkelige<br />
byer eller egentlige syntetiske byer. Problemet er, at <strong>bymiljøer</strong> ofte er overordentligt komplekse, og<br />
indeholder hundrede eller tusindvis <strong>af</strong> bygninger, planter eller træer og andet inventar. Derfor er<br />
emnet for dette projekt, efter min mening, et vigtigt forskningsområde.<br />
Gennem tiden er der gjort en række forsøg på at løse dette problem ved hjælp <strong>af</strong><br />
proceduralmodellering.<br />
I artiklen [Müller & Parish, Procedural Modeling of Cites, 2001], præsenteres en metode, der basere<br />
sig på L-systemer, og udvider disse til at kunne modellere vejnet og bygninger. Vejnettene har vist<br />
sig at være brugbare, men for bygningernes vedkommende har det vist sig, at arkitektur ikke<br />
beskrives særligt godt med L-systemers, der er bedre egnet til at gengive modeller der er resultatet <strong>af</strong><br />
en fremvækst over tid. I [Greuter & Parker, Real-time procedural Generation of 'Pseudo Infinite'<br />
Cities, 2003] beskrives et system der kan generer proceduralmodellerede bygninger meget hurtigt,<br />
men uden tilstrækkelig geometrisk detaljering.<br />
I [Müller, Wonka, Haegler, Ulmer, & Van Gool, 2006] beskrives et system til proceduralmodellering<br />
<strong>af</strong> bygninger, der er grammarbaseret. Metoden henter inspiration til sit brugsmønster i teorien om Lsystemer,<br />
men anvender en <strong>af</strong>art <strong>af</strong> de såkaldte shape-grammaer. Systemet har vist sig at være bredt<br />
anvendeligt, og resultaterne er <strong>af</strong> yderst høj kvalitet. Teknologien er forholdsvis ny, og der er stadig<br />
en række problemstillinger, der bør adresseres. En <strong>af</strong> disse er, at metoden ikke håndterer tage på en<br />
tilfredsstilende måde. Jeg vil i løbet <strong>af</strong> denne rapport redegøre for, hvorfor jeg mener, at tage er<br />
centrale i en bygningsmodel, og hvorfor det derfor er relevant at beskæftige sig med dette område.<br />
I [Aichholzer, Aurernhammer, Alberts, & Gärtner, 1995] introduceres begrebet straight-skeleton, der<br />
er en skeletinddeling for polygoner udelukkende bestående <strong>af</strong> rette linjestykker. Det viser sig at<br />
resultatet er velegnet til rejsning <strong>af</strong> tage. Ulempen ved brug <strong>af</strong> denne metode er, at den udelukkende<br />
kan håndtere valmede 1 tage.<br />
Hovedbidraget fra dette projekt er en metode, der på baggrund <strong>af</strong> simple inputparametre kan rejse et<br />
tag fra en bygnings grundplan. Metoden bygger på teorien for straight-skeleton, er yderst fleksibel og<br />
kan bl.a. håndtere alle typiske danske tagtyper. Jeg vil derudover redegøre for hvordan denne<br />
metode, kan integreres med min implementering <strong>af</strong> metoden beskrevet i [Müller, Wonka, Haegler,<br />
Ulmer, & Van Gool, 2006] og på den måde skabe en hidtil uset variation i proceduralgenererede<br />
<strong>bymiljøer</strong>.<br />
Projektet vil altså omhandle proceduralgenerering <strong>af</strong> bygninger, og især kompleksiteten ved<br />
modellering <strong>af</strong> bygningers tage. Dette projekt vil desuden indbefatte en undersøgelse <strong>af</strong> den aktuelle<br />
litteratur inden for det pågældende område. Metoden, der er fremstillet gennem dette projekt, vil<br />
1 Tag der udelukkende har skrå sider. Se Tabel 1, side 31<br />
6
ygge på eksisterende algoritmer, og forbedre disse på områder hvor de ikke giver tilfredsstillende<br />
resultater.<br />
1.1 Formål<br />
Jeg vil nu opridse de mål, jeg vil arbejde imod, og som dette projekt i sidste ende skal bedømmes ud<br />
fra.<br />
Målet med dette projekt vil være, at undersøge området for proceduralmodellering <strong>af</strong> <strong>bymiljøer</strong> og<br />
herefter, at udvikle en metode, der sætter arkitekter, designere, 3d-modellører og ingeniører i stand<br />
til at modellere <strong>bymiljøer</strong> på baggrund <strong>af</strong> en bred vifte <strong>af</strong> inputdata med et minimum forbrug <strong>af</strong> tid.<br />
Dette projekt vil hovedsageligt fokusere på modellering <strong>af</strong> huse, deres facader og specielt deres tage.<br />
For tagenes vedkommende bør metoden kunne håndtere de mest almindelige danske tagtyper. En<br />
mere udførlig gennemgang <strong>af</strong> de tage der er målgruppe for dette projekt, angives i Tabel 1 (side 30).<br />
Derudover skal det være muligt at kombinere disse tagtyper, hvorved man kan modellere typer som<br />
f.eks. et mansardtag med halvvalmet gavl.<br />
Resultatet <strong>af</strong> metoden skal være bygninger der overholder parametriske begrænsninger så som<br />
matrikelskel og bygningshøjde. Der lægges vægt på, at metoden er procedural, hvilket vil sige at<br />
brugeren ikke har fuld kontrol over det endelige resultat. Derimod skal brugeren være i stand til at<br />
modellere arketyper for huse eller facader, og derefter angive hvilke parametre der skal være<br />
tilfældige.<br />
Metoden bør være i stand til at tage input <strong>af</strong> varierende karakter. Jeg forestiller mig følgende<br />
brugerscenarier:<br />
Kort og matrikelstyrelsen (KMS) har opbygget en stor mængde GIS data over Danmark,<br />
heriblandt grundplaner (polygoner) for hver eneste registrerede bygning i landet. Dette er<br />
tilfældet for langt de fleste lande i verden. En arkitekt skal således være i stand til at hente<br />
disse data dækkende et specificeret område, og via metoden ekstrudere bygningerne til 3dmodeller.<br />
Det bør være muligt at angive specifik facade eller tagtype, hvis dette er ønskeligt.<br />
Ved modellering <strong>af</strong> hele byer, skal en designer kunne skitsere vejnettet for byen, hvorefter<br />
metoden sætter ham i stand til at fylde områderne mellem disse med bygninger.<br />
I nogle tilfælde vil designeren have større kontrol over det endelige resultat. Derfor skal<br />
denne være i stand til at forsyne systemet med en bygningsmodel (massemodel), og derefter<br />
angive facade og tagtype.<br />
1.2 Afgrænsning<br />
Dette projekt vil ikke behandle aspekter omhandlende proceduralmodellering <strong>af</strong> byers vejnet. Her vil<br />
jeg henvise til udmærkede resultater i [Chen, Esch, Wonka, Müller, & Zhang, 2008] og [Müller &<br />
Parish, 2001].<br />
En stor del <strong>af</strong> den forskning der foregår i dette område, omhandler rekonstruktion <strong>af</strong> arkitektur fra<br />
billeddata. Målet for denne gren <strong>af</strong> forskningen er, at rekonstruere nøjagtige repræsentationer <strong>af</strong><br />
virkelige byer. Billedanalyse og vision vil ikke være en del <strong>af</strong> dette projekt.<br />
7
1.3 Overblik<br />
Denne rapport skal redegøre for arbejdet i forbindelse med dette eksamensprojekt.<br />
I <strong>af</strong>snit 2, Baggrund, vil jeg gå mere detalje med baggrunden for dette projekt, og derefter beskrive<br />
min motivation for arbejdet.<br />
I <strong>af</strong>snit 3, Litteraturstudie, vil jeg give en fyldestgørende gennemgang <strong>af</strong> den litteratur der allerede<br />
findes for området. Derudover vil jeg undersøge kommercielle systemer, der anvendes i industrien.<br />
Endelig vil jeg gennemgå den relevante teori der vil blive anvendt i dette projekt.<br />
I <strong>af</strong>snit 4, Observationer, analyse og hypotese, vil jeg opridse og konkludere på min gennemgang <strong>af</strong><br />
det relaterede arbejde. Afsnittet skal tjene som bindeled mellem det relaterede arbejde og min egen<br />
metode.<br />
I <strong>af</strong>snit 5, Metode, vil jeg præsentere den metode der er blevet udviklet i løbet <strong>af</strong> dette projekt, og<br />
som er denne rapports bidrag. Jeg vil desuden gennemgå de implementeringsspecifikke<br />
problemstillinger på et mere overordnet plan.<br />
I <strong>af</strong>snit 6, Resultater, vil jeg gennemgå resultaterne der er produceret med min metode. Disse vil,<br />
grundet metodens karakter, hovedsageligt være kvalitative.<br />
Endelig vil jeg i <strong>af</strong>snit 7, Diskussion, diskutere mine resultater og redegøre for metodens anvendelse<br />
og perspektiv.<br />
Til rapporten medfølger en CD, der indeholder kildekode, eksekverbare filer for alle applikationer<br />
produceret under dette projekt, alle artikler refereret i dette projekt og alle figurer og diagrammer<br />
præsenteret i denne rapport. Desuden indeholder CD’en over 250 billeder, der enten er skærmdumps<br />
fra applikationerne eller renderede billeder. Billederne dokumenterer mit arbejde og de resultater jeg<br />
har opnået, og er ordnede i kronologisk rækkefølge. Et overblik over Cd’en findes i filen readme.txt i<br />
roden <strong>af</strong> CD’en. Indholdet kan også findes på www.student.dtu.dk/~s042624/eksamensprojekt/.<br />
Læseren <strong>af</strong> denne rapport forventes at have en grundlæggende forståelse for almindelig teori i<br />
forbindelse med computergr<strong>af</strong>ik, svarende til IMM-kursus 02561 (Computergr<strong>af</strong>ik) og 02566<br />
(Rendering). Derudover er det nødvendigt med grundlæggende viden vedrørende linear-algebra og<br />
beregning på geometrisk data. Endelig er det en fordel hvis læseren har kendskab til 3d modellering<br />
og animation, svarende til kursus 02565. Imidlertid vil mange detaljer i dette projekt blive beskrevet<br />
mere udførligt for at inkludere en bredere læserskare.<br />
8
2 Baggrund<br />
3d computergr<strong>af</strong>ik anvendes i stigende grad inden for film, TV, arkitektur, medicin, simulering,<br />
design, byplanlægning, computerspil og virtual reality. Dette muliggøres især <strong>af</strong> den rivende<br />
udvikling <strong>af</strong> særligt dedikeret accelererende hardware, og i mange tilfælde er visualisering <strong>af</strong><br />
kompleks data i 3d efterhånden helt uundværlig.<br />
Begrebet computergr<strong>af</strong>ik dækker metoder til visualisering <strong>af</strong> data ved alt andet end tekst og lyd.<br />
Oftest indebærer visualisering en projektion <strong>af</strong> geometrisk data fra 3d til 2d. I realtidsrendering<br />
rasteriseres herefter et billede i en punktrepræsentation svarende til skærmens opløsning.<br />
Efterfølgende tildeles overfladen farve, hvilket indebærer en simulering <strong>af</strong> interaktionen mellem lys<br />
og materiale, samt en mere eller mindre realistisk simulering <strong>af</strong> lysets udbredelse i den omgivne<br />
scene hvori objektet befinder sig.<br />
Figur 1: Forsimplet rendering-pipeline. Input er geometrisk data, der transformeres og projiceres til<br />
skærmkoordinatsystemet, hvorefter billedet rasteriseres og shades.<br />
Dette er de nødvendige skridt, men oftest indgår desuden bl.a. dybde-sortering/check, alphablending,<br />
clipping og anti-aliasing-sampling. Den samlede proces kaldes ofte for en renderingpipeline,<br />
og kan kort sammenfattes således: Ind sender man geometrisk data, og ud kommer et<br />
syntetiseret skærmbillede. Dette er i hovedtræk det samme som ved f.eks. rendering med raytracing.<br />
Kvaliteten <strong>af</strong> det producerede billede er <strong>af</strong>hængigt <strong>af</strong> dets endelige opløsning, materiale- og<br />
lys-simuleringens kvalitet, gr<strong>af</strong>ikerens evner og geometriens kompleksitet. Dette projekt vil<br />
omhandle generering og modellering <strong>af</strong> geometrisk data, frem for visualisering.<br />
Udviklingen indenfor gr<strong>af</strong>ikhardware har i de seneste år givet programmører mulighed for at<br />
projicere en større mængde geometri samt sample teksturer et højere antal gange per frame.<br />
Samtidig har man bevæget mod en unified shader-arkitektur, hvor vertex og pixel-shadere <strong>af</strong>vikles på<br />
de samme shader-processings-enheder. Computergr<strong>af</strong>ik er stærkt paralleliserbart, hvilket har<br />
betydet at gr<strong>af</strong>ikkortenes regnekr<strong>af</strong>t er øget markant. For CPU’er taler man om en fordobling i<br />
regnekr<strong>af</strong>t hvert andet år. For gr<strong>af</strong>ikkort er denne trend tre gange så hurtig: En fordobling i GPU’ers<br />
regnekr<strong>af</strong>t for hver 8. måned [Hanrahan, 2005].<br />
Den øgede regnekr<strong>af</strong>t har naturligvis givet mulighed for mere detaljerede eller fotorealistiske<br />
renderinger med en meget høj grad <strong>af</strong> realisme. I dag ser man ofte egentlige approksimationer <strong>af</strong><br />
global illumination i de mest moderne realtids-gr<strong>af</strong>ik-engines.<br />
9
Figur 2: Udviklingen <strong>af</strong> detaljegrad i modeller fra Unreal engine 1(1998), Unreal engine 2 (2002) og Unreal engine 3<br />
(2009). Udover tilføjelsen <strong>af</strong> forskellige effekter, såsom normal-maps, er antallet <strong>af</strong> polygoner i modellen vokset<br />
dramatisk.<br />
Umiddelbart er dette en positiv udvikling for brugere og udviklere <strong>af</strong> applikationer indeholdende<br />
computergr<strong>af</strong>ik. Problemet er dog, at i takt med at hardwaren gør det muligt at tegne stadig mere<br />
imponerende miljøer, stiger forventningerne i samme takt hos brugerne. Hver ny spiludgivelse,<br />
forventes at have højere gr<strong>af</strong>isk kvalitet end de foregående. De seneste gr<strong>af</strong>ikkort fra Nvidia kan<br />
projicere, rasterisere og shade 300 millioner trekanter i sekundet. Med 30 billeder i sekundet kan<br />
scener således indeholde op til 10 millioner trekanter. Ved brug <strong>af</strong> level of detail, occlusion culling og<br />
accelererings strukturer, er muligheden for detaljering derfor overvældende, og det er en stigende<br />
udfordring at producere så omfattende scener <strong>af</strong> en rimelig kvalitet [Greuter & Stewart, 2004].<br />
Den mest almindelige tilgang til denne udfordring er at ansætte flere gr<strong>af</strong>ikere. Problemet er, at<br />
produktiviteten ikke nødvendigvist er proportionel med antallet <strong>af</strong> personer der arbejder på et givent<br />
projekt [Kelly & McCabe, 2007]. Af økonomiske hensyn er denne løsning derfor ikke for alvor<br />
holdbar. I dette projekt vil jeg således undersøge metoder, der kan hjælpe film og<br />
computerspilsproducenter i denne proces.<br />
10
2.1 Motivation<br />
Da spillet Grand Theft Auto IV (Rockstar North) udkom i 2008 var det med sine<br />
produktionsomkostninger på omkring 100 millioner $ (omtrent 550 millioner kr.) det dyreste<br />
computerspil nogensinde produceret [Andreovich, 2008]. Pengene var tjent ind i løbet <strong>af</strong> den<br />
følgende weekend, men spillet er et eksempel på en, for spiludviklere bekymrende udvikling.<br />
Omkostningerne for at udvikle spil der kan markere sig i markedet er i eksplosiv vækst. Ifølge<br />
[Takatsuki, 2007] er gennemsnittet for omkostninger (fraregnet marketing) til udvikling <strong>af</strong> et spil til<br />
Playstation 3, 15 mio$. Det er mere end 10 gange så meget som for spil til Playstation 2, og 20 – 50<br />
gange så meget som for Playstation 1. Til sammenligning kostede pacman (Namco) 100.000 $ at<br />
udvikle i 1982.<br />
mio $<br />
16<br />
14<br />
12<br />
10<br />
8<br />
6<br />
4<br />
2<br />
0<br />
Pacman Ps1 Ps2 Ps3<br />
Figur 3: Udvikling i gennemsnitlige omkostninger for spilproduktion.<br />
Når en sådan udvikling har kunne lade sig gøre og været rentabel, hænger det naturligvis sammen<br />
med at omsætningen i spilindustrien samtidig er vokset markant. Her har spilindustrien for længst<br />
overhalet filmindustrien i USA. Det skyldes i høj grad højere salgstal, men også en stigning i prisen<br />
hos forbrugeren. En præmieretitel koster i USA omkring 60$, og i Danmark er det ikke usædvanligt<br />
at se titler til 500-550 kr. Ifølge [Aberinkulas, 2009] er man her ved at nå smertegrænsen hos<br />
forbrugeren.<br />
En <strong>af</strong> konsekvenserne ved denne udvikling er, at profitmarginen for mange spil bliver stadig mindre.<br />
En udgivelse er dermed forbundet med større risiko for investorer, hvilket fører til, at udviklerne er<br />
mindre villige til at satse på radikalt nytænkende spil. Ofte lukrerer man på såkaldte franchises, som<br />
alene på grund <strong>af</strong> navnet vil have høje salgstal (f.eks. Hitman 1, 2, 3 osv. fra danske IO interactive eller<br />
Fifa spillene fra EA sports). Desuden er de høje omkostninger en alvorlig barriere, for nye udviklere<br />
der ønsker at komme ind på markedet.<br />
Forbes har analyseret spilbranchen og set på omkostningerne i forbindelse med spiludvikling til den<br />
nye generation <strong>af</strong> konsoller [Rosmarin, 2006]:<br />
11
Marketing; 11%<br />
Konsolproducen<br />
ter; 12%<br />
Generelle<br />
udgifter; 1%<br />
Fabrikation og<br />
distribution; 7% Lisens;<br />
5%<br />
Detailhandel;<br />
20%<br />
Overskud;<br />
0,2%<br />
Design og<br />
visuelt indhold;<br />
25%<br />
Programmering<br />
og software; 20%<br />
Figur 4: Gr<strong>af</strong> der viser hvordan pengene fordels når forbrugen har købt et computerspil. Kilde: Forbes<br />
Design og modellering udgør klart den største post på budgettet. Mange spilproducenter har, i stedet<br />
for at udvikle egen software, valgt at benytte 3.-partsprodukter (middleware), som f.eks. gameengines<br />
eller fysik-engines, hvorved softwareposten bliver mere eller mindre fastlåst. Derfor er det<br />
oplagt at forsøge at optimere produktionen <strong>af</strong> visuelt indhold. For at imødekomme publikums<br />
forventninger, må film og spil-studier derfor forbedre deres værktøjer og metoder til fremstilling <strong>af</strong><br />
3d-modeller. Her er proceduralmodellering en oplagt kandidat [Wonka, Wimmer, Sillion, &<br />
Ribarsky, 2003].<br />
2.1.1 Tagmodellering<br />
Når dette projekt især vil fokusere på modellering <strong>af</strong> tage, skyldes det en række observationer jeg har<br />
gjort i forbindelse med mit arbejde hos Dalux. Ved flere lejligheder har vi h<strong>af</strong>t brug for at modellere<br />
tage ud fra meget simple parametre. Først og fremmest er tage en vigtig komponent for bygningens<br />
arkitektoniske fremtoning. Derudover dækker taget ofte en meget stor del <strong>af</strong> bygningens<br />
klimaskærm. Vil man f.eks. beregne boligens samlede varmetab, må man have en rimelig<br />
approksimation <strong>af</strong> tagets geometri, da denne beregning er baseret på det samlede areal.<br />
I web-applikationen energikoncept.dk, der blev udviklet <strong>af</strong> Dalux for SBS, i samarbejde med det<br />
rådgivende ingeniørfirma Cowi, kan almindelige brugere modellere deres ejendom via meget simple<br />
parametre. Først vælges en bygningstype, f.eks. længeejendom eller karré. Herefter vælges tagtype,<br />
f.eks. saddeltag eller valmtag. For disse komponenter angives parametre såsom højde, bredder og<br />
taghældning.<br />
12
Figur 5: Brugerflade fra energikoncept.dk<br />
Når vi kender bygningens form, f.eks. L-formet, kender vi implicit tagets topologi, og vi kan dermed<br />
konstruere tagets geometri. Problemet er at hver kombination <strong>af</strong> tag og hustype kræver sin eget<br />
dedikerede funktion. I energikoncept havde vi 3 hustyper og 3 tagtyper, hvilket resulterede i 9<br />
kombinationsmuligheder. Hvis vi ønsker at tilføje en ny bygningstype, vokser antallet <strong>af</strong><br />
kombinationer svarende til antallet <strong>af</strong> tagtyper, og omvendt. Ydermere er der ofte en stor mængde<br />
specialtilfælde der skal håndteres. F.eks. er gavlens placering i en L-bygning med saddeltag <strong>af</strong>hængig<br />
<strong>af</strong> hvilken længe der er bredest (Figur 6). Lignende problemer ses i udpræget grad, jo mere<br />
kompliceret tagformen er.<br />
Figur 6: Problemet med placering <strong>af</strong> gavl i L-bygninger med længer <strong>af</strong> varienrende bredde.<br />
13
For at holde os inden for en rimelig udviklingstid, har vi derfor hos Dalux valgt at indføre en række<br />
begrænsninger på husenes udformning. F.eks. skal længerne i et L-formet hus altid være lige brede.<br />
Løsningen er helt klart utilfredsstillende:<br />
Kun et begrænset sæt bygningstyper er understøttet. Langt de færreste bygninger falder f.eks.<br />
nøjagtigt under kategorierne i energikoncept (I, L og O).<br />
Koden vokser voldsomt ved indførelse <strong>af</strong> nye typer.<br />
Der indføres uhensigtsmæssige begrænsninger i frihedsgraderne for selv de mest basale<br />
tagtyper.<br />
Den optimale fremgangsmåde må være at finde en generisk tagmodel, der tager vilkårlige bygningers<br />
grundplaner som input, og producerer et tags geometri ud fra få konceptuelt simple parametre.<br />
2.2 Erhvervelse <strong>af</strong> geometrisk data<br />
Inden for computergr<strong>af</strong>ik er geometrisk modellering et lige så komplekst forskningsområde som<br />
rendering <strong>af</strong> disse modeller [Rotenberg, 2005]. Producenter <strong>af</strong> film og computerspil har en række<br />
forskellige muligheder for erhvervelser eller produktion <strong>af</strong> geometriske modeller. Disse metoder har<br />
forskellige anvendelsesmuligheder inden for forskellige domæner, hvor de hver især har specielle<br />
fordele, men de kompenserer samtidig også i nogen grad hinanden.<br />
2.2.1 Interaktive modelleringsværktøjer<br />
Brug <strong>af</strong> software der lader brugeren direkte bearbejde geometrisk data er måske den mest<br />
ligefremme måde at producere geometrisk data. I denne forbindelse dækker området alt fra simple<br />
vektortegneprogrammer, over mere avancerede så som autocad eller store 3d-modellerings-pakker<br />
så som revit eller 3Ds-Max. Et <strong>af</strong> de simpleste og mest udbredte modelleringsværktøjer, de fleste har<br />
stiftet bekendtskab med, er, Microsoft Word der indeholder et simpelt vektortegneprogram.<br />
14
Figur 7: Brugerfladen fra Autodesk Revit Architecture. Ofte er modelleringsværktøjer meget komplekse og<br />
overvældende for nybegyndere.<br />
Udvalget <strong>af</strong> disse systemer er enormt, og variationen i kompleksitet og arbejdsgangen ved brug <strong>af</strong><br />
disse spænder vidt. I mange tilfælde er udgangspunktet en 2d skitsering, f.eks. på baggrund <strong>af</strong> et<br />
fotogr<strong>af</strong>i, der evt. ekstruderes til 3d og forfines. Ofte editeres et mesh enten direkte, eller med<br />
geometriske operationer og transformationer.<br />
Fordelen ved modelleringsværktøjer er, at de giver designeren fuld kontrol over resultatet. Ulempen<br />
er imidlertid, at de mere avancerede systemer efterhånden er meget omfattende og svære at mestre,<br />
hvilket kræver lang uddannelse og øvelse. Desuden er interaktiv modellering meget tids- og<br />
ressourcekrævende.<br />
2.2.2 Scanning<br />
En scanner kan være en laser-, ultralyds-, CT- eller MRI-scanner, der generer rå data i form <strong>af</strong> enten<br />
punktsæt eller skalarfelter (voxels). Herefter genskabes enten geometrien ved marching cubes, eller<br />
topologien ved mesh-rekonstruktion med f.eks. delaunay-triangulering.<br />
Fordelen ved scanning er at man opnår en meget nøjagtig gengivelse <strong>af</strong> et fysisk objekt. Ofte er dette<br />
en forudsætning i forbindelse med anvendelsen <strong>af</strong> modellen. Et eksempel er den danske virksomhed<br />
3shape, der sælger scannere til tandlæger. Udstyret skanner <strong>af</strong>støbninger <strong>af</strong> tænder, hvorefter<br />
medfølgende software kan bruges til, at modellere proteser eller broer der passer nøjagtigt til<br />
15
patientens eksisterende tandsæt. Herefter sendes tegningen til en fabrikant, der producerer protesen<br />
efter 3d geometrien.<br />
Ulempen er, at modellerne ofte er ikke-regulære, åbne og rigide, hvilket begrænser deres anvendelse<br />
i f.eks. underholdningsindustrien. Desuden har modelløren ingen direkte kontrol over det endelige<br />
resultat.<br />
Figur 8: 3d laser-skanner. Objektet roteres på en pedistat i et mørkekammer.<br />
2.2.3 Vision og billedanalyse<br />
Ved stereofotogrammetri er det muligt at skabe 3d modeller fra dybdeinformationen i stereofotos.<br />
Ved at tage billeder fra to forskellige positioner, kan man ud fra oplysninger om kameraets nøjagtige<br />
position, orientering og fotogrammetriske egenskaber, beregne en stråle der starter i kameraets<br />
fokuspunkt og fortsætter gennem billedplanet i en given pixel. Udpeger man det samme punkt i<br />
hvert billede vil strålerne netop krydse hinanden ”under” disse punkter. Vil man kende punktets<br />
virkelige position er det altså et spørgsmål om at finde skæringen mellem de to stråler. Udpegningen<br />
<strong>af</strong> punkter kan automatiseres ved mønstergenkendelse, hvilket genererer et meget stort punktsæt.<br />
Dette sæt kan trianguleres på samme måde som ved f.eks. skanning.<br />
Metoden har traditionelt været anvendt til rekonstruktioner <strong>af</strong> terræn eller hele bymodeller.<br />
Fordelen ved metoden er at man hurtigt, f.eks. ved hjælp <strong>af</strong> fly, kan generere meget store modeller.<br />
Ulempen er, at man umiddelbart kun kan konstruere højdefelter (2d kort med højdedata), derudover<br />
er præcisionen i metoden ofte utilfredsstillende. Dette kan dog forbedres med et højere antal<br />
kameraer, men man er efterhånden gået over til egentlige laserskanninger fra fly, når man vil<br />
producere højdekort.<br />
16
En <strong>af</strong>art <strong>af</strong> metoden kan ses i Microsofts Photosynth, hvor uøvede kan uploade en stak fotos. Herefter<br />
vil programmet generere en punktsky uden at kende kameraets position eller orientering. Denne<br />
punktsky anvendes til præcist at placere billeder i forhold til hinanden, og derved skabe en særlig<br />
tredimensionel oplevelse.<br />
Figur 9: Brugerflade fra microsoft fotosynth.<br />
2.2.4 Proceduralgenerering <strong>af</strong> indhold til film og spil<br />
I computerspillenes ungdom blev proceduralgenerering anvendt for, at overkomme et <strong>af</strong> datidens<br />
store problemer: Computeres meget begrænsede hukommelse. Meget simple algoritmer blev<br />
anvendt til f.eks. at generere spillets baner i real-tid (”on-the-fly”). Dermed kunne man tilbyde langt<br />
større baner end man ellers havde mulighed for. Pseudotilfældige tal blev ofte anvendt, og en<br />
kompleks model kunne dermed repræsenteres ved et enkelt seed til en tilfældig-tal-generator.<br />
Proceduralgenereret indhold i et spil er, alt der ikke er prægenereret <strong>af</strong> en designer eller modellør. I<br />
den bredest tænkelige forstand kan man f.eks. betragte fysiksimulering som procedural genereret<br />
indhold, da det erstatter prægenererede animationer eller scripts. På samme måde finder man ofte<br />
proceduralgenererede animationer, hvilket kan være alt fra rag-dolls, bone-animation, karakterer der<br />
er i stand til at rejse sig fra akavede positioner og animation <strong>af</strong> alle former for bevægelser, såsom at<br />
kunne gå, flyve, køre bil osv. (som set i spillet Spore fra EA games).<br />
Brug <strong>af</strong> stokastiske algoritmer spiller desuden ofte en rolle for selve gameplayet, især for spil der<br />
omhandler udforskning <strong>af</strong> ukendte miljøer, hvor spiloplevelsen er <strong>af</strong>hængig <strong>af</strong>, at man ikke kender<br />
vejen til mål på forhånd. Dermed er hver gennemspilning <strong>af</strong> et spil eller en enkelt bane unik fra gang<br />
17
til gang. Et eksempel på dette er spillet Diablo fra 1997, hvor en underjordisk labyrint genereres<br />
tilfældigt, og missioner (quests) vælges stokastisk fra en pulje <strong>af</strong> mulige opgaver. En simpel version <strong>af</strong><br />
denne type algoritmer der roterer og tilfældigt placerer tiles, kan ses hos [Lang, 2010].<br />
Figur 10: Tilfældigt generert dungeon, bestående <strong>af</strong> 3x3 tiles.<br />
I filmindustrien har man i mange år benyttet computergr<strong>af</strong>ik til at skabe effekter og scener <strong>af</strong> enhver<br />
art. Man bruger normalt offline-rendering hvilket stiller højere krav til detaljegraden, hvorfor<br />
modellører ofte ”snyder”, og indsætter den samme model flere steder i en scene. I virkeligheden<br />
findes der ikke to nøjagtigt ens objekter. I et supermarked vil to dåser tomater f.eks. have forskellige<br />
typer skrammer eller misfarvninger i større eller mindre grad. Sammen med den sterile materialerendering<br />
der ofte anvendes i computergr<strong>af</strong>ik, virker miljøerne derfor alt for perfekte, og dermed<br />
ikke virkelighedstro. Filmen Tron var en <strong>af</strong> de første til at bruge computergr<strong>af</strong>ik i udpræget grad. Ken<br />
Perlin, der arbejdede på filmen nævner, at han selv var utilfreds med filmens ”maskinagtige”<br />
udseende (hvilket inspirerede ham til hans berømte noise-algoritme) [Perlin, 1999]. Derfor benytter<br />
filmindustrien i dag proceduralmodellering til at lave ”uperfekte” modeller.<br />
18
Figur 11: Billede fra filmen Tron fra 1982.<br />
I mange tilfælde er regulariteten for ens objekter tydelig (Figur 12). Selv når objekterne placeres<br />
tilfældigt, med varierende farvenuancer, virker scenen ensartet og kedelig. Dette kan være direkte<br />
ødelæggende for ”virkelighedsopfattelsen” (eller suspension of disbelief) i mange spil. Her er det ikke<br />
længere et spørgsmål om farve eller nuance, men om selve strukturen <strong>af</strong> objektet. Denne effekt er<br />
meget lig opfattelsen <strong>af</strong> teksturer der ”tiler”. I moderne film og computerspil forventer publikum<br />
højere kvalitet, og derfor benytter man f.eks. L-systemer til at proceduralmodellere hele skove, hvor<br />
hvert eneste træ er unikt. I dette projekt vil variationen <strong>af</strong> proceduralmodellerede objekter være et<br />
centralt begreb, der også vil blive taget i betragtning når metoder til proceduralmodellering vurderes<br />
i <strong>af</strong>snit 6 (Resultater).<br />
19
amplitude er defineret ud fra udfaldsrummet for de tilfældige tal. Bølgelængden er <strong>af</strong>standen mellem<br />
punkterne, eller rettere skaleringen <strong>af</strong> feltet.<br />
Figur 13: 1D noise, interpoleret mellem punkter <strong>af</strong> tilfældige tal.<br />
For at opnå en mere interessant funktion kan man addere forskellige noise-funktioner med<br />
forskellige amplituder og bølgelængder. Dette sker i en iterativ proces der gradvist mindsker både<br />
amplitude og bølgelængde, hvor hver iteration kaldes en oktav. Den samlede funktion kaldes ofte<br />
turbulens [Bourke, 2000].<br />
+<br />
Bølgelængde<br />
+<br />
=<br />
+<br />
Figur 14: Summering <strong>af</strong> oktaver <strong>af</strong> noise for et 2D højdekort.<br />
Amplitude<br />
Noise har mange anvendelser, bl.a. til procedurale teksturer, rendering <strong>af</strong> skyer, røg og ildeffekter,<br />
terrængenerering, volumetriske teksturer og rendering <strong>af</strong> f.eks. touchsstreger.<br />
+…<br />
21
Figur 15: Terragen er et program der genererer landskab, vand og skyer, næsten udelukkende ved brug <strong>af</strong> noise.<br />
2.3.2 Fraktaler<br />
En uformel definition på et fraktal er, et irregulært geometrisk objekt, der udviser selvsimilaritet i et<br />
uendeligt antal underinddelinger. Dvs. en figur, hvor man kan blive ved med at zoome ind, og stadig<br />
genfinde den samme overordnede form. Fraktaler genkendes overalt i naturen, f.eks. i: skyer,<br />
snefnug, bjergkæder, lyn, kystlinjer og i planter.<br />
”When each piece of a shape is geometrically similar to the whole, both the shape and the cascade<br />
that generate it are called self-similar.”<br />
-Benoît B. Mandelbrot<br />
Computere er velegnede til syntetisering <strong>af</strong> fraktaler, og f.eks. begrebet rekursivitet <strong>af</strong>spejler i nogen<br />
grad fraktalers selv-similaritet. Derfor er det oplagt at benytte fraktaler til at modellere de<br />
ovenstående fænomener. Man vil sjældent bruge egentlige fraktaler med uendelig detaljering i<br />
proceduralmodellering, men ideer og koncepter kan anvendes og giver gode resultater. Figuren i en<br />
fraktal kan være irregulær og tilfældig. En kystlinje set i et satellitfoto vil f.eks. virke ujævn og takket.<br />
Når vi zoomer ind vil detaljegraden øges, men vi vil fortsat finde ujævnheder magen til dem vi så før.<br />
22
Figur 16: Venstre: Computergenereret udgave <strong>af</strong> Koch’s snefnug-fraktal. Højre: En krydsning mellem broccoli og<br />
blomkål, udviser forbløffende fraktale strukturer.<br />
2.3.3 Generative metoder<br />
For generativ modellering er målet at opbygge et fælles format, der beskriver tredimensionelle<br />
objekter, ikke ved deres geometri såsom punkter, kanter og sider, men ved det sæt <strong>af</strong> operationer<br />
hvorved de er produceret. Disse operationer kan f.eks. være simple transformationer, deformationer,<br />
extruderinger, sweep-operationer og boolske operationer. Operationerne gemmes i et hierarki, der<br />
på den måde beskriver et objekt. Grundelementerne er ofte geometriske primitiver såsom kasser,<br />
kugler eller pyramider.<br />
En fordel ved generativ modellering er, at man kan komprimere meget store modeller til meget små<br />
filer. Filstørrelsen følger ikke nødvendigvis kompleksiteten i modellen. Et eksempel er modelleringen<br />
<strong>af</strong> en katedral med over 7 millioner trekanter, der kun fylder 18 kb generativ kode [Havermann,<br />
2005].<br />
23
Figur 17: Katerdral med 7 millioner trekanter, kan komprimeres til 18 kb via GML.<br />
2.3.4 Grammar-baserede metoder<br />
En formel grammar består <strong>af</strong> et sæt symboler (alfabetet), og et sæt produktionsregler (produktioner)<br />
der kan omskrive strenge formet <strong>af</strong> symboler i alfabetet. En grammar siges at definere et sprog, og<br />
reglerne bestemmer hvilke ord (strenge) der kan genereres i sproget. En grammar fortæller intet om<br />
betydningen <strong>af</strong> ordene der kan formes, kun deres sammensætning.<br />
En grammar der indeholder symbolerne a, b og S kan f.eks. have følgende form.<br />
1. S -> aSb<br />
2. S -> ba<br />
Hver produktion er nummereret. Før pilen angives forgængeren, og efter angives strengen der skal<br />
erstatte denne. Regel 1 sige dermed at S skal erstattes med aSb. Hvis vi starter med startsymbolet S,<br />
kan vi f.eks. vælge regel 1, hvilket vil give os strengen aSb. Herefter kan vi igen erstatte det nye S via<br />
en <strong>af</strong> produktionsreglerne osv.. Denne proces fortsætter indtil strengen ikke længere indeholder et S<br />
(i dette tilfælde når vi har valgt regel 2). Længden <strong>af</strong> den endelige streng er derfor <strong>af</strong>hængig <strong>af</strong><br />
hvornår regel 2 vælges, og sættet <strong>af</strong> mulige strenge er derfor uendeligt:<br />
{ba, abab, aababb aaababbb, …}<br />
S er i dette tilfælde en non-terminal, der per konvention skrives med versal, og a og b er terminaler,<br />
der skrives med små bogstaver. Den resulterende streng efter <strong>af</strong>ledning <strong>af</strong> en regel kaldes under<br />
tiden for den aktuelle konfiguration.<br />
Ofte bruges en grammar, når man vil definere (eller rettere genkende) f.eks. et computersprog,<br />
strukturen <strong>af</strong> kommunikationsbeskeder eller et filformat. Aristid Lindenmayer viste hvordan<br />
24
Figur 19: Eksempel på stokastisk parametrisk L-system.<br />
L-systemer er et meget bredt område, og der findes utallige variationer over syntaksen, f.eks.<br />
kontekstsensitive og åbne L-systemer.<br />
28
3 Litteraturstudie<br />
Dette <strong>af</strong>snit er resultatet <strong>af</strong> mit litteraturstudie. Observationer og metoder beskrevet her, vil blive<br />
anvendt i det videre arbejde med min egen metode. Jeg vil indledningsvis introducere de begreber<br />
der er almindelige i forbindelse med dette område. Dernæst vil jeg beskrive artikler, specifikt<br />
omhandlende det forudgående arbejde i forbindelse med proceduralmodellering <strong>af</strong> <strong>bymiljøer</strong> og<br />
modellering <strong>af</strong> tage. Endeligt vil jeg gennemgå den teori, der vil blive anvendt i mit videre arbejde.<br />
3.1 Terminologi<br />
Dette projekt fokuserer specielt på bygninger, bygningsdele og arkitektur, desuden anvendes<br />
algoritmer, metoder og teori fra geometriens verden. I dette <strong>af</strong>snit vil jeg derfor gennemgå centrale<br />
termer fra disse områder.<br />
3.1.1 Tagtyper<br />
Tage er centrale for dette projekt, derfor følger her benævnelser, for de mest almindelige tagformer i<br />
den vestlige verden. Begreberne er løse og varierer i litteraturen. Jeg har derfor sammenfattet en<br />
mere omfattende oversigt, så misforståelser undgås. Jeg har desuden forsøgt at oversætte mellem<br />
engelsk og dansk, da min prototype vil være på engelsk. Jeg vil for følgende referere til [lsas, 2010]<br />
[bobvila, 2010] [husrådgivning, 2010]<br />
Fladt tag / Flat roof<br />
Det flade tag er det simplest tænkelige tag, og er per definition<br />
parallelt med grundplanet. Et egentligt fladt tag ses sjældent, da<br />
det ikke leder vand væk, hvormed der kan opstå vandskader.<br />
Derfor har taget ofte en meget svag hældning eller <strong>af</strong>runding.<br />
Saddeltag / Gable roof<br />
Et saddeltag har gavle i endesiderne. For et rektangulært hus er der<br />
som oftest tale om de to korteste sider. Et saddeltag er defineret<br />
ved at have lodrette gavle.<br />
Valmet tag / Hip roof<br />
Et valmet tag er et tag hvor alle gavle har en hældning, oftest den<br />
samme som resten <strong>af</strong> taget. Denne tagtype er solid og mere<br />
modstandsdygtig mod kr<strong>af</strong>tig vind end f.eks. saddeltaget.<br />
Halvvalm / Half hip<br />
En halvvalm er en gavl der starter lodret som et saddeltag og<br />
knækker til en valm i toppen. En gavl <strong>af</strong> denne type kan også<br />
benævnes efter, hvor knækket sidder. En gavl der <strong>af</strong>kortes med 1/3<br />
kaldes således ”1/3 dels valm” [husrådgivning, 2010]. Tagetagen er<br />
ofte beboet, og taget kombinerer således fordelene ved valmtage<br />
og saddeltage.<br />
29
Hollandsk gavl / Dutch gable<br />
En hollandsk gavl (eller nedsænket gavl) er omvendt i forhold til<br />
en halvvalm, idet den starter som en valm, men knækker til en<br />
lodret gavl i toppen. Det ses ofte, at de resterende tagflader<br />
knækker til en lavere hældning ved gavlens knæk.<br />
Pyramidetag /Pyramid roof<br />
Pyramiden er et kendt geometrisk objekt, men for tages<br />
vedkommende er der tale om en underkategori <strong>af</strong> den valmede<br />
tagtype, med uniform taghældning anvendt på en kvadratisk<br />
grundplan.<br />
Mansardtag / Mansard roof (Gambrel)<br />
Mansardtaget har sit navn fra arkitekten François Mansard, der<br />
ofte anvendte det i sine byggerier. Taget består <strong>af</strong> en nederste del<br />
med en meget høj, næsten lodret, hældning, der brækker til en<br />
meget lav hældning. Den nederste del huser ofte en beboelig kvist,<br />
og under kvistvinduerne har taget ofte en opskalk eller <strong>af</strong>runding.<br />
På engelsk skelner man ofte mellem et mansardtag og en gembrel,<br />
hvor gambrel har lodrette gavle, og masardtaget har en næsten flad<br />
øverste del. Gambrel har ingen dansk oversættelse (bortset fra det<br />
uformelle ”bedstemor-and-tag”).<br />
Pulttag / Shed<br />
Denne tagtype anvendes ofte for meget smalle bygninger. Ofte<br />
sammenbygges to pulttage, det ene højere end det andet, hvormed<br />
man har mulighed for placering <strong>af</strong> vinduer over det ene tag.<br />
Tabel 1: Oversigt over tagtyper<br />
30
3.1.2 Tagets dele<br />
For taget er der en række fagudtryk der vil blive benyttet i rapporten. Her vil jeg referere til<br />
[husrådgivning, 2010]<br />
Tagrygning / kip Kvist Skotrende Grat<br />
Tagkant /<br />
vindskede<br />
Tagkant / tagfod /<br />
tagskæg<br />
Figur 20: Tagets dele<br />
[denstoredanske, 2009]<br />
Rygningen er den øverste kant på taget, og er ofte dækket <strong>af</strong> et konisk eller vinklet dække. En<br />
tagkant er alle kanter, der ikke er sammenføjninger mellem tagflader. Ved gavle er der ofte en planke<br />
der skærmer undertaget for vind. Denne kaldes en vindskede. De nederste kanter kaldes også for<br />
tagfod, og et udhæng betegnes tagskæg. Konvekse kanter kaldes grat, og konkave kanter kaldes<br />
skotrender. En kvist benævnes ofte ved dens tagtype. I tilfældet i Figur 20 er der tale om en<br />
saddelkvist.<br />
Den nederste del <strong>af</strong> taget (f.eks. de to nederste rækker tagsten) har ofte en lavere hældning end<br />
resten <strong>af</strong> taget. Denne detalje kaldes opskalk, og har som regel udelukkende æstetisk betydning<br />
[denstoredanske, 2009].<br />
31
Figur 21: Opskalk<br />
3.1.3 Polygonen<br />
Polygonen er et grundbegreb i geometrien. En polygon i planet består <strong>af</strong> et sæt punkter, der er<br />
forbundet <strong>af</strong> et sæt kanter. I denne rapport vil vi kalde et punkt i en polygon for en vertex (spids).<br />
For en polygon gælder det altid, at hver vertex er forbundet til nøjagtigt to forskellige andre punkter<br />
gennem en kant. Dermed er en polygon altid en lukket figur, og der er altid nøjagtigt én vertex for<br />
hver kant. Det simpleste polygon er en trekant, og polygoner kan navngives efter antallet <strong>af</strong> kanter.<br />
En refleks-vertex (konkav vertex) er en vertex, hvis indre vinkel er større end π. I det modsatte<br />
tilfælde kaldes punktet under tiden en konveks vertex.<br />
Kant<br />
Vertex<br />
Refleks-vertex<br />
Polygonens indre<br />
Figur 22: Konkavt sekskantet polygon.<br />
Polygonens ydre<br />
3.1.3.1 Klassificering <strong>af</strong> polygoner<br />
Udover navngivning ved antallet <strong>af</strong> kanter klassificeres polygoner i følgende grupper:<br />
32
Konvekst polygon<br />
For hvert punkt i polygonens indre, kan alle andre punkter i<br />
polygonen nås med en ret linje, uden at krydse polygonens<br />
ydre kant. Polygonen indeholder derfor udelukkende<br />
konvekse punkter.<br />
Regulært polygon<br />
Alle kanter og alle vinkler er ens. Disse polygoner er altid<br />
konvekse.<br />
Ikke-konveks<br />
Der findes mindst to punkter i polygonens indre, der ikke<br />
nås med en ret linje, uden at krydse polygonens ydre kant.<br />
Polygonen indeholder mindst én refleks-vertex.<br />
Simpel polygon<br />
Polygonens kant krydser ikke sig selv.<br />
Konkav<br />
En ikke-konveks simpel polygon.<br />
Stjerne-formet<br />
Der findes mindst ét punkt i polygonens indre, hvorfra alle<br />
andre punkter kan nås.<br />
33
Monoton<br />
En polygon siges at være monoton med hensyn til en akse L,<br />
hvis enhver linje ortogonal til L, skærer polygonens ydre kant<br />
højst to gange.<br />
Tabel 2: Klassificering <strong>af</strong> polygoner<br />
34
punkter i S. Diagrammet markerer skillelinjer i planet hvor <strong>af</strong>standen til de nærmeste naboer er ens<br />
(Figur 24).<br />
Figur 24: Eksempel på voronoidiagram. Punkterne er inputsættet og de stiplede linjer er partitionslinjerne for<br />
planet.<br />
Et voronoidiagram for et punktsæt kan betragtes som en gr<strong>af</strong>, og vil udelukkende bestå <strong>af</strong> rette<br />
linjer. Hvis man introducerer andre former, f.eks. kanter og polylinjer, vil diagrammet indeholde<br />
kurver. Medial-aksen mellem et punkt og en kant er f.eks. en parabel:<br />
Figur 25: Medial-aksen mellem punkt og kant<br />
Ved skeltonisering <strong>af</strong> polygoner med medial-akser opstår der således kurvede kanter ved reflexpunkter:<br />
36
Figur 26: Medial-skelet <strong>af</strong> konkavt polygon. Bemærk den kurvede kant i medial-gr<strong>af</strong>en ved polygonens refleksvertex.<br />
Denne opstår som medial mellem det pågældende punkt og de overfor liggende kanter.<br />
Mange gr<strong>af</strong>iske systemer har problemer med at håndtere kurvede kanter, og derfor har man i denne<br />
artikel søgt en metode, der udelukkende producerer gr<strong>af</strong>er med rette kanter. I [Aichholzer &<br />
Aurenhammer, 1996] har man generaliseret metoden til, at håndtere plane retlinede gr<strong>af</strong>er frem for<br />
udelukkende plane retlinede polygoner. Jeg vil udelukkende betragte straight-skeleton for polygoner.<br />
Input til metoden er et sæt kanter G, der sammen udgør et polygon. I voronoidiagrammet har alle<br />
punkter samme euklidiske <strong>af</strong>stand til to eller flere figurer i G. Dette er ikke tilfældet for et straightskeleton.<br />
Hvis man betragter bølgefronter der bevæger sig med samme hastighed fra alle kanter i G,<br />
vinkelret på kanten, vil man opdage at skæringerne mellem disse bølgefronter følger<br />
vinkelhalveringslinjerne mellem de indbyrdes kanter i G (Figur 27).<br />
37
Figur 27: Eksempel på bølgefront-udbredelsen ved et simpelt polygon. De stiplede linjer er bølgefronter ved<br />
forskellige intervaller. De prikkede linjer er vinkelhalveringslinjerne i polygonet.<br />
Som det fremgår <strong>af</strong> Figur 27 følger punkterne i en bølgefronts-polygon vinkelhalveringslinjerne, og<br />
længden <strong>af</strong> kanterne i en bølgefront vil enten øges eller mindskes under udbredelsen. Dette<br />
fortsætter, så længe bølgefronterne ikke ændrer deres indbyrdes topologi. En ændring sker i to<br />
tilfælde (events):<br />
1) Edge event. En bølgefront kollapser til et punkt.<br />
2) Split event. En bølgefront deles når en vinkelhalveringslinje rammer den, og det<br />
tilbageværende areal deles i to.<br />
Figur 28: Venstre: Edge-event. Højre: Split-event.<br />
Som følge <strong>af</strong> en event, er der opstået et nyt forskudt polygon, og dermed et nyt sæt bølgefronter.<br />
Metoden forsætter derefter på samme måde med de nye fronter. Et straight-skeleton S(G) for en gr<strong>af</strong><br />
G kan således defineres som stykker <strong>af</strong> vinkelhalveringslinjer der spores langs alle bølgekanter<br />
38
gennem denne process. Stykkerne <strong>af</strong> vinkelhalveringslinjer kaldes arcs, og deres endepunkter, som<br />
ikke er en del <strong>af</strong> den oprindelige figur G, kaldes knuder. Hver knude er et resultat <strong>af</strong> enten en spiltevent<br />
eller en edge-event. S(G) er unik og entydig for et polygon G.<br />
Figur 29: Straight-skeleton med bølgefronter, for de indadgående vinkelhalveringslinjer i et simpelt polygon.<br />
I artiklen præsenteres en algoritme der gennem udbredelsen <strong>af</strong> bølgefronterne, opretholder en<br />
triangulering <strong>af</strong> den del <strong>af</strong> planet det endnu ikke er nået <strong>af</strong> en bølgefront. Trianguleringen<br />
indeholder udelukkende punkter fra de aktuelle bølgekanter, og opdateres ved hhv. en split-event og<br />
edge-event.<br />
Polygonen i Figur 26 har følgende straight-skeleton:<br />
Figur 30: Venstre: Straight-skeleton for et konkavt polygon. Højre tagmodel rejst fra samme straight-skeleton.<br />
Ligesom voronoidiagrammet kan et straight-skeleton vægtes, ved at lade bølgefronter udbrede sig<br />
med forskellige hastigheder. I artiklen foreslås det derfor, at metoden kan benyttes til rejsning <strong>af</strong><br />
39
tage, over bygningers grundplan. Hvis tidspunktet (t) for en knudes event noteres, kan dette<br />
efterfølgende bruges som punktets højde i den tredje dimension (Figur 23). En bemærkelsesværdig<br />
egenskab ved et tag, rejst fra et straight-skeleton er, at uanset hvor en regndråbe måtte lande på<br />
taget, vil den altid falde nedad mod den kant i G, der definerer den pågældende flade. En tømrer vil<br />
på samme måde forsøge at bygge et tag, der leder vandet væk, så det ikke samler sig i fordybninger.<br />
Derfor er netop et straight-skeleton, særligt velvalgt som tag-modellering-metode.<br />
3.2.2 Automatically Generating Roof Models from Building Footprints<br />
[Laycock & Day, 2003]<br />
I denne artikel beskrives en metode til at rejse tage på bygninger ud fra deres grundplans-polygon.<br />
Metoden er især rettet mod rekonstruktion <strong>af</strong> byer udelukkende fra GIS-data, ved en simpel<br />
ekstrudering <strong>af</strong> grundplanet. Problemet er i den forbindelse, at tagenes geometriske kompleksitet<br />
tidligere har gjort automatisering umulig.<br />
Metoden tager udgangspunkt i grundplanets<br />
straight-skeleton. Ved at finde den projicerede<br />
<strong>af</strong>stand fra hvert punkt i skelettet til deres<br />
oprindelige (nærmeste) kanter i bygningens<br />
grundplan, kan man ud fra en<br />
hældningsparameter (f.eks. 45°) finde punktets<br />
højde, og på den måde rejse et tag fra et straightskeleton<br />
(Figur 31). Samme fremgangsmåde<br />
foreslås <strong>af</strong> [Bélanger, 2000] og [Aichholzer,<br />
Aurernhammer, Alberts, & Gärtner, 1995]. Dette<br />
forudsætter uniform hældning, og muliggøre<br />
dermed kun valmede tage. I artiklen beskrives<br />
derfor en metode til detektering <strong>af</strong> gavlpolygoner i<br />
det valmede tag (simple trekantede polygoner, der<br />
er fremkommet som følge <strong>af</strong> en edge-event). Disse<br />
polygoner rejses til lodret, hvorved et saddeltag kan<br />
konstrueres. Mansardtaget kan findes ved at<br />
skrumpe grundplanet med en given længde, og<br />
Figur 31: Rejsning <strong>af</strong> tag fra bygningens<br />
grundplan<br />
derefter bygge et straight-skeleton fra det oprindelige polygon, sammen med det skrumpede.<br />
Artiklen bemærker, at mange virkelige tage er sammensatte, f.eks. som følge <strong>af</strong> tilbygninger, og der<br />
beskrives en metode til inddeling <strong>af</strong> bygningens grundplan i underområder, der hver især tildeles en<br />
40
tagmodel, og som endeligt flettes sammen til et samlet tag. Metoden virker kun for retvinklede<br />
bygninger, og starter med at splitte bygningen lodret og vandret ved hvert refleks-punkt. For hver<br />
rette linje i skelettet (rygning), indsamles de lokale underinddelinger der ligger inden for rygningens<br />
bounding-box. Der fortages til sidst en set-difference på felterne, hvorved underinddelingernes<br />
integritet sikres.<br />
3.2.3 Towards fully automatic generation of city models<br />
[Brenner, 2000]<br />
Figur 32: Tages kompleksitet. (a) Grundplaner og deres valide tage. (b) Antallet <strong>af</strong> skæringspunkter. (c) Punkter<br />
der ligger inden for grundplanet. (d) Skæringspunkter tilbage efter discrete relaxation. (e) Antallet <strong>af</strong> skridt i<br />
søgning med discrete relaxation. (f) Antal skridt I signing uden discrete relaxation.<br />
I mange konkrete tilfælde har man udover GIS-data desuden luftfotos og scanningsdata, til rådighed<br />
når man vil rekonstruere en by. I denne artikel beskrives en metode, der kombinerer scanningsdata<br />
og GIS-data til at opnå resultater, der ellers ikke er mulige udelukkende ved brug <strong>af</strong> én type data.<br />
Artiklen er i denne sammenhæng relevant, da den bygger på en generalisering <strong>af</strong> begrebet straightskeleton.<br />
Man kan i stedet for at betragte vinkelhalveringslinjer i polygonen, forestille sig et<br />
hældende plan for hver kant i polygonen, hvor kanten ligger i planet, der skråner ind i polygonen<br />
(altså tagfladernes planer). Ved skæring mellem to <strong>af</strong> disse planer findes en kant, og ved skæring<br />
mellem tre eller flere planer findes en vertex. Hvis vi forbinder disse punkter med hinanden via de<br />
fundene kanter på alle tænkelige måder, finder vi et sæt gr<strong>af</strong>er. Antallet <strong>af</strong> resulterende gr<strong>af</strong>er er<br />
<strong>af</strong>hængigt <strong>af</strong> grundplanets kompleksitet, men en stor del <strong>af</strong> de disse er ikke valide tage. De<br />
resterende er valide og én <strong>af</strong> gr<strong>af</strong>erne er polygonens straight-skeleton.<br />
Som det fremgår <strong>af</strong> Figur 32, kan kompleksiteten hurtigt blive meget stor. Derfor reduceres antallet<br />
<strong>af</strong> valide punkter ved en såkaldte discrete relaxation, hvor hvert punkt mærkes (efter om de er<br />
konkave eller konvekse) og iterativt evalueres, opdateres og eventuelt forkastes.<br />
En vigtig betragtning i denne artikel er, at selvom vi kender grundplanet og hældninger tilknyttet<br />
hver kant i dette, er der flere løsninger på tag-problemet udover polygonens straght-skeleton.<br />
Metoden giver ingen bud på hvordan mere komplicerede tage, såsom mansard-taget kan modelleres.<br />
Anvendelsen <strong>af</strong> scanningsdata ligger desuden uden for mit eget projekts rækkevidde.<br />
41
3.2.4 Real-time Procedural Generation of `Pseudo Infnite' Cities<br />
[Greuter & Parker, 2003]<br />
Figur 33 Bymodel syntetiseret i realtid<br />
Greuter og Parker fremlægger i denne artikel en metode til syntese <strong>af</strong> uendeligt store byer i realtid,<br />
især rettet mod computerspil. Argumentet er, at begrænsninger i spillerens bevægelsesfrihed ofte<br />
virker unaturlige og ødelæggende for spiloplevelsen [Greuter & Stewart, 2004].<br />
Gr<strong>af</strong>ikkort renderer udelukkende geometri, der ligger inden for et view-frustum. Hvis scenen<br />
inddeles i kvadrater kan man nøjes med at opretholde geometri der er synligt i et givet øjeblik. Hver<br />
gang et kvadrat indtræder i view-frustum, genberegnes den pågældende bygning ud fra pseudotilfældige<br />
tal. Seeded til de tilfældige tal udledes <strong>af</strong> bygningens position, hvormed der opnås<br />
konsistens i scenen.<br />
Bygningerne består <strong>af</strong> lag <strong>af</strong> grundplaner. Disse grundplaner består <strong>af</strong> sammensatte polygoner, og<br />
ekstruderes med tilfældig længde til bygningsmasser. Processen er iterativ, og starter ved den øverste<br />
etage. Den foregående grundplan bruges som input til den næste iteration, hvor et nyt tilfældigt<br />
polygon sammenlægges med den eksisterende figur (Figur 34). Herefter findes uv-koordinater til<br />
facaderne, så det passer med et helt antal vinduer (hvor ét vinduesfag har uv-koordinater mellem 0<br />
og 1).<br />
En bemærkelsesværdig fordel ved metoden er at den letter presset på båndbredden mellem CPU og<br />
harddisk, da geometrien produceres ”just-in-time”. Dette er i mange tilfælde et betydeligt argument<br />
for proceduralmodellering.<br />
42
Figur 34 Iterativ <strong>af</strong>ledning <strong>af</strong> bygning<br />
3.2.5 Citygen: An Interactive System for Procedural City Generation<br />
[Kelly & McCabe, 2007]<br />
Figur 35: Proceduralmodelleret by.<br />
43
Denne artikel beskriver et system til proceduralmodellering <strong>af</strong> <strong>bymiljøer</strong> inklusiv deres vejnet. Målet<br />
har været at bygge en algoritme der kan <strong>af</strong>vikles i realtid, hvilket muliggøre en interaktiv<br />
modelleringsproces. Genereringsprocessen inddeles i følgende 3 skridt:<br />
1. Overordnede vejnet / hovedveje genereres.<br />
2. Underordnede vejnet / sideveje genereres.<br />
3. Bygninger genereres.<br />
Vejnettet er repræsenteret ved en adjacency-gr<strong>af</strong>, hvor hver knude er et vejkryds, og hver kant en vej.<br />
Brugeren forsyner systemet med knuderne og topologien til hovedvejene. Hovedvejene inddeler<br />
landet i celler, der uddrages fra gr<strong>af</strong>en via en Minimum Cycle Basis (MCB) algoritme. Når en celle er<br />
fundet, bliver den udfyldt med sideveje der bestemmes med udgangspunkt i forskellige<br />
grundmønstre. Der kan tilføjes støj for at give varians eller mere naturlige mønstre.<br />
Generering <strong>af</strong> bygninger foregår i tre underskridt:<br />
1. Celler for sidevejene findes (også via MCB).<br />
2. Cellerne underinddeles til parceller.<br />
3. Bygninger ekstruderes og teksturerers.<br />
Bygningerne ekstruderes direkte fra parcellens grundplan. Afhængigt <strong>af</strong> zonetype vil grundplanet<br />
blive skrumpet, hvorved der er plads til haver og grønne områder. Ved ekstrudering opstår der et<br />
massivt objekt, der altid har fladt tag. For at angive facadedetaljer til objektet, teksturerers det med<br />
facadetekstur og normal-map.<br />
Figur 36: Ekstruderet massiv bygning med facadetekstur.<br />
3.2.6 Rapid modeling of complex building façades<br />
[Finkenzeller & Schmitt, 2006]<br />
44
Figur 37: Modellering <strong>af</strong> bygning, udelukkende baseret på information tilknyttet grundplanet for hver etage.<br />
Denne artikel omhandler modellering <strong>af</strong> bygninger, med særligt fokus på deres facader. Forfatterne<br />
beskriver et system der skal lette arbejdsbyrden for designere under modellering <strong>af</strong> bygninger<br />
markant. Der lægges vægt på, at designeren skal have kontrol over hver del <strong>af</strong> det endelige produkt, i<br />
den udstrækning han måtte ønske det.<br />
Metoden tager udgangspunkt i det faktum, at de fleste bygninger kan opfattes som en stak <strong>af</strong> etager<br />
med hver deres ydre facade. En etage er repræsenteret ved en konveks polygon (grundplan), der igen<br />
kan være sammensat <strong>af</strong> flere underpolygoner kaldet floor plan module (fpm). Hver kant i et fpm er<br />
behæftet med information om dens facade. Designprocessen består således i, at designeren forsyner<br />
systemet med en grundplan, indeholdende facadeinformation, for hver etage. Hver kant kan nu<br />
ekstruderes til en væg og erstattes med geometri. I det konkrete system repræsenteres geometrien i<br />
et LOGO lignende sprog, hvorved det kan tilpasse sig forskellige skaleringer.<br />
Metoden gør desuden brug <strong>af</strong> det faktum at hver etage minder om den foregående. Designeren<br />
behøver derfor udelukkende angive eksplicitte ændringer fra en lavere etage til den næste. Disse<br />
ændringer kan f.eks. være fjernelse eller tilføjelse <strong>af</strong> en fpm eller ændring i facadetypen. Systemet<br />
sørger selv for, at uændret information siver videre fra etage til etage.<br />
Resultatet er en træstruktur der repræsenterer bygningen: Bygningen består <strong>af</strong> et sæt etager, der<br />
hver består <strong>af</strong> et sæt fpm’er, der hver består <strong>af</strong> et sæt kanter og så videre. For den øverste etage<br />
indeholder hver fpm, information om tagtypen. Disse tage rejses, og samles endeligt til et komplet<br />
tag.<br />
3.2.7 Procedural modeling of cities<br />
[Müller & Parish, Procedural Modeling of Cites, 2001]<br />
45
Figur 38: Bymiljø proceduralmodelleret med L-system.<br />
I denne artikel beskrives et system til modellering <strong>af</strong> <strong>bymiljøer</strong> i deres helhed, altså også inklusiv<br />
vejnettet. Systemet består overordnet <strong>af</strong> to dele: Første del genererer, med udgangspunkt i kortdata,<br />
et vejnet i form <strong>af</strong> en gr<strong>af</strong>. Anden del skaber bygninger ud fra de parceller, der udgøres <strong>af</strong> vejnettets<br />
underinddeling <strong>af</strong> landet. Begge dele baserer sig på L-systemer, hvor vejnettet umiddelbart bærer<br />
mest lighed med den traditionelle anvendelse <strong>af</strong> L-systemer, da der her er tale om en slags forgrenet<br />
vækst.<br />
Systemets overordnede struktur, kan sammenfattes i følgende figur:<br />
46
3.2.7.1 Modellering <strong>af</strong> vejnet<br />
Systemet til generering <strong>af</strong> vejnet, tager som input geogr<strong>af</strong>isk data i form <strong>af</strong> billeder. Dette kan f.eks.<br />
være kort der bestemmer:<br />
Parker, hav og områder hvor<br />
veje ikke forekommer.<br />
Terrænhøjde.<br />
Zoner med forskellige<br />
vejmønstre.<br />
Befolkningstæthed.<br />
Input:<br />
Geogr<strong>af</strong>isk billeddata<br />
Generering <strong>af</strong> vejnet<br />
Udvidet L-system<br />
Inddeling i parceller<br />
Subdivision<br />
Generering <strong>af</strong> bygninger<br />
L-system<br />
Generering <strong>af</strong> geometri<br />
L-system parser<br />
Vejnet<br />
Gr<strong>af</strong><br />
Parceller<br />
Polygoner<br />
Bygninger<br />
Streng<br />
Geometri<br />
Polygoner<br />
Figur 39 Overblik over city-engine systemet. Hver fase producerer et output, der anvendes<br />
som input til den næste fase. Det endelige output er en geometrisk model <strong>af</strong> en hel by,<br />
komplet med veje og bygninger.<br />
Modelleringsprocessen består således i at gr<strong>af</strong>ikeren designer kortdata, der herefter bliver sendt til<br />
systemet. Gr<strong>af</strong>ikerens kontrol over den endelige model består i det nævnte kortdata, samt en række<br />
globale parametre.<br />
Systemet baserer sig grundlæggende på et L-system. Ifølge artiklens forfattere er et problem ved<br />
grammarbaserede metoder, at det sjældent er muligt at indføre nye begrænsninger, uden at det får<br />
konsekvenser for hele sættet <strong>af</strong> produktionsregler. Man taler om en kombinatorisk eksplosion, hvor<br />
antallet <strong>af</strong> produktionsregler og deres kompleksitet vokser eksponentielt. For at undgå sådanne<br />
vanskeligheder, har man i dette system valgt at bygge et generisk L-system. Systemet lader de<br />
betydeligste parameterfelter stå tomme, og genererer dermed en såkaldt ideel efterfølger til den<br />
foregående konfiguration. I stedet for at prøve at modificere parametrene i selve<br />
Output<br />
Figur 40 Eksempler på input kort.<br />
47
produktionsreglerne eksporteres dette til eksterne funktioner. På den måde, kan antallet <strong>af</strong><br />
produktionsregler holdes på kun 9, og man opnår derved et mere koncist og overskueligt system.<br />
Evalueringen <strong>af</strong> parametrene opdeles i to på hinanden følgende trin: Indledningsvis rettes<br />
parametrene, så de følger globale tendenser. Efterfølgende rettes vejene ind efter lokale forhold. De<br />
globale tendenser kan f.eks. være, at vejene bevæger sig mod områder med høj befolkningstæthed,<br />
eller bevæger sig i særlige mønstre såsom ringveje eller gittermønstre. De lokale begrænsninger kan<br />
f.eks. være det eksisterende vejnet. I en by er den blinde vej et særsyn. Derfor må l-systemet være<br />
selv-sensitivt. Dette opnås med såkaldt åbent l-system [Prusinkiewicz & Mech, 1996].<br />
Figur 41: Resultatet <strong>af</strong> første fase er en gr<strong>af</strong>repræsentation <strong>af</strong> et syntetiseret vejnet.<br />
3.2.7.2 Modellering <strong>af</strong> bygninger<br />
Fra vejnettet uddrages parcellerne der udgøres <strong>af</strong> området mellem vejene (med least interior angle<br />
metoden). Parcellerne inddeles herefter i mindre byggegrunde, der hver især bebygges med en<br />
proceduralmodelleret bygning.<br />
Modelleringen <strong>af</strong> bygningernes geometri varetages <strong>af</strong> et slags L-system, indeholdende<br />
terminalsymboler der fortolkes som ekstrudering, skalering, translation, og statiske geometriske<br />
objekter såsom tage og antenner. Dette er meget lig en såkaldt shape-grammar [Stiny, 1982].<br />
Desuden er der, som i almindelige L-systemer, særlige push og pop symboler, hvorved man kan<br />
modellere forgreninger. Fremgangsmåden er som følger: som input kommer en bygnings grundplan<br />
der kan have arbitrær form. Denne ekstruderes i en højde, der bestemmes ud fra zone-data i et<br />
inputkort, til et massivt volumen, der bestemmer bygningens begrænsninger. Herefter er det muligt<br />
at fortage operationer på denne form, hvorved bygningens geometriske detaljer kan modelleres. Lsystemets<br />
aksiom er så at sige bygningens grundplan.<br />
48
Figur 42: <strong>Proceduralmodellering</strong> <strong>af</strong> bygning med udgangspunkt i bygningens bounding-volumen (venstre).<br />
Herefter forfines bygningen gradvist via underinddeling <strong>af</strong> de enkelte figurer.<br />
Man kan lade figurerne undergå forskellige transformationer, og lade tilfældige tal bestemme hvilke,<br />
hvorved metoden bliver stokastisk. Fordelen er at bygningerne bliver parametriske, og f.eks. altid<br />
passer til en specifik byggegrund. Som det fremgår <strong>af</strong> Figur 42 forfines bygningen ved hver iteration,<br />
hvorved man har et naturligt LOD hierarki.<br />
Facaderne modelleres via proceduralmodellerede teksturer. I artiklen nævnes følgende observationer<br />
vedr. facader:<br />
Facader består ofte <strong>af</strong> flere kombinerede eller indlejrede gitterstrukturer, hvor cellerne<br />
indeholder f.eks. døre eller vinduer.<br />
Enkelte celler kan have indflydelse på positionen <strong>af</strong> omgivne celler, f.eks. har vinduer over en<br />
dør ofte en <strong>af</strong>vigende størrelse.<br />
Irregulariteter i gitterstrukturen påvirker ofte hele kolonner eller rækker.<br />
I artiklen foreslås en semi-automatisk metode til modellering <strong>af</strong> facader, der baserer sig på indlejrede<br />
gitter strukturer. En 2-dimensionel gitterstruktur findes ved at kombinere to 1-dimensionelle pulsfunktioner<br />
(der enten er 0 eller 1). Et punkt (s,t) i teksturen er aktivt hvis en logisk funktion mellem<br />
de to puls-funktioner evaluerer til 1. Herefter kan farven i punktet evalueres, hvilket kan indebære<br />
evaluering <strong>af</strong> yderligere indlejrede gitre. Ved at lade pulsfunktionerne være skalerbare bliver hele<br />
facaden skalerbar, hvormed en høj facade f.eks. tildeles flere etager.<br />
Figur 43: Venstre: Kombinationen <strong>af</strong> to pulsfunktioner skaber et 2-dimensionelt gitter. Højre: Sammenlægning <strong>af</strong><br />
flere lag <strong>af</strong> gitre.<br />
49
3.2.8 Instant architecture<br />
[Wonka, Wimmer, Sillion, & Ribarsky, 2003]<br />
Figur 44: Fuldautomatisk proceduralmodelleret bymiljø<br />
I denne artikel præsenteres en metode til fuldautomatisk proceduralmodellering <strong>af</strong> bygningers<br />
facader. Metoden er særligt velegnet til rekonstruktion <strong>af</strong> virkelige byer, men kan også bruges til<br />
syntetisering <strong>af</strong> virtuelle. Metoden er inspireret <strong>af</strong> den foregående artikel, men forfatteren påpeger at<br />
bygninger er fundamentalt forskellige fra planters struktur. En bygning formes ikke <strong>af</strong> en<br />
vækstproces, der <strong>af</strong>spejles i L-systemers parallelle natur, men <strong>af</strong> en proces <strong>af</strong> underinddelinger. En<br />
bygning er sammensat <strong>af</strong> en række facader, hver facade består <strong>af</strong> en række etager, hver etage består<br />
<strong>af</strong> en række vinduesgrupper osv..<br />
I stedet for at tage udgangspunkt i teorien om L-systemer anvendes de såkaldte shape-grammaer<br />
[Stiny, 1982]. En shape-grammar opererer ikke på strenge men direkte på former. En form kan f.eks.<br />
være en trekant, og en produktion kan f.eks. omskrive en trekant til to firkanter. En regel kan<br />
desuden translatere, rotere eller skalere en form. Teorien omkring shape-grammar blev først anvendt<br />
<strong>af</strong> arkitekter til at analysere og skabe nye arkitektoniske designs. Ofte benytter man ikke former<br />
direkte i sin grammar, men parametriske symbolrepræsentationer.<br />
50
Figur 45: Shape grammars anvendt til analyse og rekonstruktion <strong>af</strong> Le Corbusier’s cruciform bygninger.<br />
Artiklen beskriver et system kaldet split-grammar, der varetager modellering <strong>af</strong> hele bygningen,<br />
inklusiv dens 3d-struktur. Kernen i systemet er evnen til at splitte former i to eller flere mindre<br />
former. Forskellen fra at splitte i stedet for at transformere en form er, at de efterfølgende former<br />
tilsammen fylder det samme som den foregående. Grammaren bliver på den måde kontekst-sensitiv,<br />
da den er <strong>af</strong>hængig <strong>af</strong> figurens oprindelige størrelse. I forbindelse med et split, arbejder systemet<br />
udelukkende med kasseformer. Ved fortolkningen <strong>af</strong> grammarens terminaler, kan disse kasser<br />
erstattes med hvilken som helst figur.<br />
Figur 46: Eksempel på anvendelse <strong>af</strong> split grammar til generering <strong>af</strong> facade.<br />
51
Systemet indeholder 240 forskellige produktionsregler, der skal kunne beskrive en stor variation i<br />
stilarter. Modelleringen foregår ved at input, enten i form <strong>af</strong> GIS-data, såsom bygningens grundplan,<br />
eller en startform gives til systemet. Parametre tilknyttet inputtet angiver overordnede<br />
designmønstre, f.eks. hvilken arkitektonisk stilart der skal anvendes. Herefter anvendes relevante<br />
produktionsregler på stokastisk vis (de fleste regler sorteres fra på baggrund <strong>af</strong> stilart eller<br />
parametre).<br />
Artiklens forfattere argumenterer for at en fuldstændig tilfældig <strong>af</strong>ledning <strong>af</strong> regler vil ende i kaos,<br />
især med et regelsæt på 240 regler (Figur 47). Der introduceres derfor en ekstra meget simpel<br />
kontrol-grammar, der sørger for, at overordnede designvalg er konsistente gennem hele<br />
modelleringsprocessen. Kontrol-grammaren designes specifikt til den enkelte bygning. Samtidig<br />
sørger et parametertilpasningssystem for, at konsistensen i <strong>af</strong>ledningen sikres. Kandidatregler<br />
udvælges på baggrund <strong>af</strong> kontrol-grammaren, og parametertilpasningssystemet sørger herefter for at<br />
frasortere uegnede regler.<br />
Figur 47: Kaotisk facade som følge <strong>af</strong> ukontrollerede valg <strong>af</strong> produktionsregler.<br />
3.2.9 Procedural modeling of buildings<br />
[Müller, Wonka, Haegler, Ulmer, & Van Gool, 2006]<br />
52
Figur 48: Proceduralmodelleret rekonstruktion <strong>af</strong> den arkeologiske by Pompeii. Genererert på baggrund <strong>af</strong> GISdata.<br />
Denne artikel beskriver et system, kaldet CGA shape grammar, der baserer sig på Instant<br />
Architechture. Artiklens forfattere påpeger en række begrænsninger ved de tidligere metoder:<br />
I [Müller & Parish, 2001] er det muligt at modellere simple bygninger ved at placere og rotere<br />
primitive volumetriske modeller såsom kasser. Til gengæld er metoden ikke egnet til at<br />
generere geometriske detaljer i facaderne, <strong>af</strong> tilstrækkelig høj kvalitet.<br />
I [Wonka, Wimmer, Sillion, & Ribarsky, 2003] er det muligt at generere facader <strong>af</strong><br />
overordentlig høj kvalitet. Derimod er metoden uegnet til håndtering arbitrære bygninger<br />
med komplekse volumetriske modeller. Desuden er det et krav at bygningsmodellerne ikke<br />
må indeholde overlappene facade eller på anden måde degenereret geometri.<br />
Målet med systemet i denne artikel er, at kombinere de bedste egenskaber ved de to ovenstående<br />
metoder. En overordnet betragtning er, at et hus består <strong>af</strong> en massemodel, der er beklædt med en<br />
facade. Metoden skal altså håndtere transitionen fra, at arbejde med massemodellen til at arbejde<br />
med facaden, sømløst.<br />
Artiklen arbejder med begrebet massemodel (mass model), der er den volumetriske grundmodel for<br />
et hus. Massemodellen er bygningens basale form, når man ser bort fra alle facadedetaljer såsom<br />
vinduer, døre, gesimser, søjler eller lignende, og består ofte <strong>af</strong> en komposition <strong>af</strong> primitive<br />
volumetriske figurer. Følgende figur viser variation i massemodellen, mens facaderne er holdt ens:<br />
53
Figur 49: Variation over massemodellen med fastholdt facade.<br />
Med det beskrevne system har en designer mulighed for at modellere en arketype <strong>af</strong> et hus, f.eks. en<br />
typisk kontorbygning. Herefter angives tilfældighedsparametre der giver instanser <strong>af</strong> husene<br />
variation. I meget homogene kvarterer, f.eks. et typisk dansk parcelhuskvarter, vil man nu kunne<br />
fylde alle matrikler med lignende huse. For kvarterer med højere variation bør designeren modellere<br />
flere arketyper, alle med forskellige stilarter og arkitektoniske perioder. Dette er meget lig<br />
arbejdsmønstret for l-systemer, hvor forskellige træsorter modelleres med forskellige l-systemer.<br />
Figur 50: Massemodel <strong>af</strong> bygningen er modelleret ved placering og rotation <strong>af</strong> simple geometriske figurer,<br />
hvorved facader overlapper hinanden. Dette ses tydeligt ved vinduer der er begravede bag andre facader<br />
(venstre). Højre: Facade der er korrigeret for overlap.<br />
Metoden baserer sig, ligesom instant architecture, på shape-grammaer. Denne variant kaldes <strong>af</strong><br />
artiklens forfattere for CGA shape grammar (Computer Graphics Architecture). Definitionen <strong>af</strong> en<br />
form (shape) er udvidet til at indeholde en symbolrepræsentation (navn) der identificerer figuren i<br />
grammaren, figurens geometri og en orienteret boundingbox (scope) der bestemmer figurers<br />
position, størrelse og orientering.<br />
54
Notationen for en produktionsregel har følgende form:<br />
id: predecessor : cond -> successor : prob<br />
Id’et identificerer produktionen, predecessor er en ikke-terminal figur i grammarens alfabet og cond<br />
er produktionens betingelse, der er et boolsk udtryk, der skal evaluere sandt før produktionen kan<br />
anvendes. En predecessor vil som følge <strong>af</strong> at anvende en produktionsregel blive erstattet <strong>af</strong> et eller<br />
flere elementer listet i successor. Reglen vælges blandt andre gyldige regler med sandsynligheden<br />
prob.<br />
For denne metode er der ikke tale om en egentlig erstatning <strong>af</strong> figurer med nye under<br />
omskrivningsprocessen. Derimod sættes predecessor-figurer til inactive efter <strong>af</strong>ledningen med den<br />
pågældende produktion. Dermed opbygges en <strong>af</strong>ledningstræ <strong>af</strong> figurer, hvor de <strong>af</strong>ledte figurer er<br />
børn <strong>af</strong> predecessor. Denne fremgangsmåde kan udnyttes til at skabe automatiske level of detail<br />
niveauer. For at give modelløren bedre kontrol, er det muligt at prioritere reglerne i forhold til<br />
hinanden (med priority kommandoen), hvorved regler <strong>af</strong> højere prioritet altid vil blive anvendt først.<br />
Som i parametriske L-systemer er CGA en parametrisk grammar. I følgende eksempel erstattes<br />
facaden, med navnet fac og parameteren h, med 3 etager med navnet floor og parameteren h/3:<br />
1: fac(height) -><br />
floor(height/3)floor(height /3)floor(height /3)<br />
Et scope er som udgangspunkt et koordinatsystem, hvori figurens geometri er defineret. Et punkt P<br />
repræsenterer koordinatsystemets origo, tre akser X, Y og Z repræsenterer koordinatsystemets<br />
rotation og en størrelsesvektor S angiver systemets skalering. En figurs geometri er derfor defineret i<br />
et model-koordinatsystem i intervallet 0 til 1.<br />
55
Figur 51: Scope er koordinatsystemet hvori en figurs geometri er defineret.<br />
Ligesom i l-systemer kan der fortages operationer på et scope under evalueringen <strong>af</strong><br />
produktionsregler. Disse operationer er definerede ved en række kommandoer: T(tx, ty, tz) er en<br />
translationsvektor der adderes til scopets position P. Rx(vinkel), Ry(vinkel) og Rz(vinkel) roterer hhv.<br />
X, Y eller Z-aksen i koordinatsystemet med den angivne vinkel. S(sx, sy, sz) sætter scopets størrelse til<br />
den angivne vektor. Derudover er der som i L-systemer en push og pop kommando (’[’ og ’]’), der<br />
hhv. gemmer og henter et scope fra en stak. Endelig indføres en kommando I(objId), der indsætter<br />
en model (f.eks. en model <strong>af</strong> et vindue) med navnet objId i scopets koordinatsystem. Disse<br />
kommandoer forårsager ikke nye former eller elementer i konfigurationen, men ændrer kun former i<br />
den konkrete produktionsregel, og kaldes derfor for makroer.<br />
Med de ovennævnte makroer kan massemodellen modelleres direkte i grammaren. F.eks. erstatter<br />
følgende produktionsregel et symbol A med massemodellen i Figur 52.<br />
1: A -> [T(0, 0, 6) S(8, 10, 18) I(”cube”)]<br />
T(6, 0, 0) S(7, 13, 18) I(”cube”)<br />
T(0, 0, 16) S(8, 15, 8) I(”cylinder”)<br />
56
Figur 52: Massemodel der består <strong>af</strong> to kasser og en cylinder. Bemærk hvordan kasser og cylinder genneskære<br />
hinanden.<br />
Ligesom i Instant Architecture har CGA en splitkommando (en makro). Hvis man f.eks. vil splitte en<br />
9 meter høj facade langs y-aksen i tre etager, hver med en højde på 3 meter, bruges kommandoen på<br />
følgende måde:<br />
1: fac : Scope.y == 9 -><br />
Subdiv(”y”, 3, 3, 3){floor | floor | floor}<br />
Figur 53: Resultat som følge <strong>af</strong> split på facade.<br />
Først angives aksen man ønsker at splitte langs, derefter følger angivelsen <strong>af</strong> størrelsen for hvert<br />
split-segment. Der kan angives ligeså mange splits man måtte ønske, når størrelsen blot summerer<br />
til længden <strong>af</strong> den pågældende akse i scopet. Krølleparenteserne indeholder en række <strong>af</strong> symboler<br />
separeret med ’|’, der angiver navnet på figuren i de <strong>af</strong>ledte splitsegmenter. Antallet <strong>af</strong> segmenter i<br />
kommandoen skal svare til antallet <strong>af</strong> figurer i krølleparenteserne. I dette tilfælde vil produktionen<br />
57
kun blive anvendt på facader med højden 9. Dette kontrolleres ved at undersøge figurens<br />
dimensioner i y-aksen i produktionsreglens betingelse.<br />
Artiklens svar på problemet med overgangen fra massemodellering til facademodellering består i et<br />
såkaldt komponentsplit. Ved hjælp <strong>af</strong> den følgende kommando kan vi splitte et objekt i en række<br />
figurer <strong>af</strong> lavere dimesion:<br />
1: a -> Comp(type){ A | B | … | Z }<br />
Typen (type) indikerer hvilket element vi ønsker at splitte figuren i. Hvis vi f.eks. anvender<br />
kommandoen på en 3-dimensionel figur kan dette være enten ”face”, ”edge” eller ”vertex”, svarende til<br />
figurer i hhv. 2, 1 eller 0 dimensioner. Den konkrete definition <strong>af</strong> et objekt <strong>af</strong> lavere dimension, er en<br />
figur hvis scope har størrelsen 0 i en eller flere akser. Det er i den forbindelse værd at bemærke, at vi<br />
kan gå tilbage til tre dimensioner igen, ved at sætte størrelsen til en værdi højere end 0, og på den<br />
måde ekstrudere objekter f.eks. et udhæng i en facade der ekstruderes fra facadeplanet ud i en 3dimensionel<br />
figur. Figur 54 viser resultatet som følge <strong>af</strong> følgende komponentspilt, der opløser en 3dimensionel<br />
figure i dens flader:<br />
1: a-> Comp(”faces”){fac}<br />
Figur 54: Effekten <strong>af</strong> en komponentsplit i sider for en 3-dimensionel figur.<br />
Efter dette split kan vi nu arbejde videre med figurens facader i form <strong>af</strong> figurer, der i dette tilfælde<br />
hedder fac.<br />
Da vi nu arbejder på arbitrære masse-modeller, kan vi ikke vide noget på forhånd om facadens<br />
størrelse. Kommandoen i Figur 53, er f.eks. udelukkende anvendelig på en facade der er nøjagtigt 9<br />
meter høj. Artiklens forfattere indfører derfor en repeat-kommando. F.eks:<br />
1: floor -> Repeat(”X”, 2) {B}<br />
58
Figur 55: Resultat som følge <strong>af</strong> repeat-split på facade.<br />
Den pågældende etage vil dermed blive inddelt et antal blokke (hver med navnet B), svarende til<br />
størrelsen <strong>af</strong> x-aksen i figurens scope delt med 2. Hvis bloklængden ikke går op i figurens længde vil<br />
antallet <strong>af</strong> blokke blive rundet <strong>af</strong> til nærmeste hele tal.<br />
Endelig indføres en relativ parameter, markeret ved et tal efterfulgt <strong>af</strong> er ’r’. En relativ parameter<br />
antager en relativ størrelse i forhold til figurens dimension og andre absolutte parametre:<br />
1: floor -> Subdiv(”X”, 2, 1r, 1r, 2){ A | B | B | A}<br />
I det ovenstående eksempel inddeles etagen i 4 blokke: to A blokke der har en fast størrelse på 2<br />
meter og 2 B blokke der deler det resterende areal ligeligt.<br />
Det er muligt at kombinere split og repeat kommandoer og dermed opnå en meget fleksible<br />
modelleringer. Det følgende eksempel skal illustrere, hvordan en facademodellering kan bevare sin<br />
struktur under varierende dimensioner:<br />
1: floor -><br />
Subdiv(”X”, 3, 1r, 3){ A | Repeat(”X”, 2) { B } | A}<br />
59
Figur 56: Eksempel på facadessplit på facader med forskellige dimensioner.<br />
I det ovenstående eksempel anvendes produktionen på en facade på 8m og en på 13m. Facaderne<br />
deles indledningsvist i 3 stykker, hvor start og slut begge er 3m bredde A-blokke. Det midterste<br />
stykke indeholder et indlejret repeatsplit, der inddeler stykket i så mange B-blokke der er plads til.<br />
Alle A-blokke er 3m, mens B-blokkene varierer i størrelse. I eksemplet til venstre er B-blokken<br />
nøjagtigt 2m, da dette er hvad der er til overs fra A-blokkene. I eksemplet til højre er der 7m til overs<br />
fra A-blokkene. Dette giver 7/2 = 3,5 blokke, hvilket oprundes til 4 blokke <strong>af</strong> hver 1,75 m.<br />
Med split og repeat- kommandoerne kan vi nu modellere en facade. Det følgende er en meget simpel<br />
modellering <strong>af</strong> facaden i Figur 58:<br />
1: fac -> Subdiv(”y”, 4, 1r) { ground | floors }<br />
2: floors -> Repeat(”y”, 3) { floor }<br />
3: floor -> Repeat(”x”, 2) { win }<br />
4: ground -> I(”groundFloor.obj”)<br />
5: win -> I(”winBlock.obj”)<br />
Figur 57: Grammar til specifikation <strong>af</strong> simpel facade.<br />
60
Figur 58: Facades struktur i grove træk. Af hensyn til overskueligheden er win figurerne kun medtagede for den<br />
ene etage.<br />
I det ovenstående tilfælde er underetagen 4 meter høj, de resterende etager er hver ca. 3 meter høje<br />
og vinduesblokkene er 2 meter brede. Input er en facadefigur (et rektangel), med navnet fac, der kan<br />
være arbitrært stor. For at opnå et rimeligt resultat bør den dog mindst være højere end 4, hvilket<br />
burde kontrolleres med et boolsk tjek i den første produktionsregel. Regel 1 splitter facaden i en<br />
underetage og en blok der fylder resten <strong>af</strong> facaden (floors). Regel 2 inddeler denne i så mange etager<br />
der er plads til, og regel 3 inddeler etagerne i så mange vinduesgrupper der er plads til. Endelig<br />
erstattes geometrien i hhv. ground og win med mere detaljeret geometri (regel 4 og 5).<br />
For at korrigere problemet skitseret i Figur 50, indføres en occlusion-query-test, hvorved man i selve<br />
grammaren kan tage højde for eventuelle overlapninger. Følgende eksempel gives i artiklen:<br />
1: tile : Shape.occ(”nonparent”) == ”none” -> window<br />
2: tile : Shape.occ(”nonparent”) == ”part” -> wall<br />
3: tile : Shape.occ(”nonparent”) == ”full” -> ε<br />
Figur 59: Eksempel på typisk brug <strong>af</strong> occlusion-forespørgsler i CGA.<br />
Hvis figuren ikke overlappes indsættes en vinduesfigur, hvis den er delvist overlappet indsættes en<br />
vægfigur og hvis den er fuldt overlappet indsættes den tomme figur (ε). Parameteren (”nonparent”)<br />
er beregnet til at begrænse testen. F.eks. vil en figurs forgængerfigurer i <strong>af</strong>ledningstræet ofte<br />
overlappe, hvilket undgås ved at udelukke disse. Derudover kan der via grammaren indsættes snaplinjer<br />
der kan opfanges <strong>af</strong> omgivelserne, hvorved en mere konsistent indretning <strong>af</strong> facadens struktur<br />
opnås.<br />
61
Modelleringen <strong>af</strong> tage håndteres på forskellige måder, <strong>af</strong>hængigt <strong>af</strong> modelleringsopgavens karakter.<br />
For bygninger der modelleres ved kombination <strong>af</strong> geometriske grundfigurer, indeholder systemet en<br />
række basale parametriske tagformer, meget lig tagene i enegikoncept (<strong>af</strong>snit 2.1.1). I de tilfælde hvor<br />
inputtet er facader, ekstruderet fra en bygnings grundplan (f.eks. GIS-data), bygges en valmet<br />
tagform baseret på et straight-skeleton.<br />
Figur 60: Udvalget <strong>af</strong> grundtagformer i CGA.<br />
Artiklen giver en lang række konkrete modelleringseksempler, der elegant løses med metoden. I<br />
Figur 48 ses byen Pompeii, der via GIS-data-input blev modelleret ud fra 190 CGA produktionsregler.<br />
Metoden er anvendelig til et stort udvalg <strong>af</strong> varierende stilarter, og er anvendt i flere kommercielle<br />
og open-source produkter.<br />
Figur 61: Modelleringseksempler.<br />
62
3.2.10 Procedural Modeling of Structurally-Sound Masonry Buildings<br />
[Whiting, Ochsendorf, & Durand, 2009]<br />
Figur 62: Stenkirke, modelleret under hensyntagen til statiske og strukturelle begrænsninger.<br />
Denne artikel præsenterer et system, der bygger videre på arbejdet i [Müller, Wonka, Haegler,<br />
Ulmer, & Van Gool, 2006]. Forfatterne argumenterer for, at bygninger der ikke er strukturelt stabile<br />
eller korrekt proportionerede, vil have en synlig særpræget og urealistisk fremtoning. Derudover<br />
spiller den fysiske interaktion mellem virtuelle miljøer og brugeren en stadig større rolle i de fleste<br />
applikationer. Dertil har man brug for bygninger der er realistisk modellerede ud fra en fysisk<br />
betragtning, hvorved de under en given påvirkning kollapser på virkelighedstro måder.<br />
Systemet tager et sæt produktionsregler <strong>af</strong> samme form som i [Müller, Wonka, Haegler, Ulmer, &<br />
Van Gool, 2006], hvori en række frie parametre er markerede. Som udgangspunkt modelleres<br />
herefter en bygning, bestående <strong>af</strong> geometriske primitiver. Udover de basale, såsom kasser eller<br />
cylindere som i CGA, er sættet <strong>af</strong> primitiver udvidet med søjler, buer, kupler o.l. Primitiverne er alle<br />
underinddelt i byggeblokke, <strong>af</strong> en passende størrelse.<br />
Den proceduralmodellerede bygning analyseres herefter ved, at betragte på kontaktfladerne mellem<br />
byggeblokkene, og beregne udvekslingen <strong>af</strong> kræfter mellem disse. En byggeblok er i ligevægt, hvis<br />
summen <strong>af</strong> kræfterne er 0. Hvis alle byggeblokke er i ligevægt er bygningen i ligevægt, og vi er<br />
færdige.<br />
63
Hvis bygningen ikke er i ligevægt, beregnes et tal for hvor tæt den er på ligevægt, et nyt sæt frie<br />
parametre findes hvorefter processen starter forfra. De frie parametre vælges med henblik på en<br />
ikke-lineær optimering i parameterrummet. Efter to iterationer har vi, på baggrund <strong>af</strong><br />
ligevægtstallet, en gradient i parameterrummet, og ved at bevæge os langs denne, nærmer vi os ved<br />
hver iteration en optimal konstruktion. De frie parametre kan f.eks. være bygningshøjde,<br />
vægtykkelse, søjletykkelse eller vinduesbredde, og beregningen bliver mere nøjagtig jo finere<br />
granularitet hvormed byggeblokkene er underinddelt.<br />
Artiklens forfattere lægger vægt på, at denne type modellering kun er praktisk mulig netop i<br />
proceduralmodellering. Det er f.eks. de færreste spil-gr<strong>af</strong>ikere, der har indsigt i bygningers statiske<br />
forhold eller en intuitiv fornemmelse for bæredygtige proportioner i f.eks. en stenkirke.<br />
3.2.11 Interactive Visual Editing of Grammars for Procedural Architecture<br />
[Lipp, Wonka, & Wimmer, 2008]<br />
Figur 63: Visuel editering <strong>af</strong> shape-grammars i realtid.<br />
Denne artikel præsenterer et system, der som den forrige artikel også bygger videre på metoden<br />
præsenteret i [Müller, Wonka, Haegler, Ulmer, & Van Gool, 2006]. Et <strong>af</strong> problemerne med metoden<br />
er, at den kræver tekstbaseret editering, samtidigt med, at brugergruppen hovedsageligt er designere<br />
og gr<strong>af</strong>ikere. Tekstbaseret modellering er ofte en uoverkommelig barriere for folk uden baggrund i<br />
datalogi. Et andet problem ved modellering med grammaer er, at designeren kun har kontrol over<br />
meget overordnede designparametre. For<br />
proceduralmodellering er der altid tale<br />
om en <strong>af</strong>vejning mellem udtryksfuldhed<br />
og detaljeret kontrol. Ofte vil der opstå<br />
uhensigtsmæssige designs, der er<br />
problematiske for gr<strong>af</strong>ikeren at håndtere<br />
uden, at introducere et væld <strong>af</strong> nye<br />
produktionsregler i grammaren, hvilket i<br />
sidste ende gør modelleringsprocessen<br />
uoverskuelig. Denne artikel introducerer<br />
et system, der har til formål, at<br />
kombinere styrken ved grammaer med<br />
traditionelle modelleringsmetoder.<br />
Figur 64: Venstre: Et <strong>af</strong>ledt figurhierarki, der svarer til facaden<br />
til højre. Af hensyn til læsbarheden vises kun den anden etage i<br />
figurhierarkiet.<br />
64
Ved modellering med shape-grammaer opbygges en træstruktur; et slags hierarki <strong>af</strong> figurer (Figur<br />
64). Dette hierarki har figurer eller kommandoer som knuder, der hver har forskellige parametre, der<br />
enten er tilfældigt valgte eller bestemt <strong>af</strong> produktionsregler. Ofte ønsker en designer f.eks., at ændre<br />
et bestemt vindues bredde eller højde. En måde at gøre dette på er, at angive de specifikke parametre<br />
for vinduets endeknude i træstrukturen. Problemet er, at hvis grammaen ændres og hierarkiet<br />
<strong>af</strong>ledes på ny, vil denne ændring være tabt, hvilket er et problem for brugbarheden <strong>af</strong> systemet.<br />
Desuden ønsker designere ofte mulighed for at vælge f.eks. hele rækker eller kolonner <strong>af</strong> vinduer i en<br />
facade.<br />
Forfatterne introducerer et system til identifikation <strong>af</strong> enkelte figurer, ud fra deres unikke position i<br />
hierarkiet. Indledningsvis fortages en søgning fra en endeknude til grammaens aksiom (rod). Hver<br />
forgrening fra en knude nummereres <strong>af</strong>hængigt <strong>af</strong> rækkefølgen, og dermed bygges en tupel, der<br />
angiver den nøjagtige vej fra aksiomet til den enkelte figur. På den måde kan en figur altid findes<br />
også efter, at hierarkiet er blevet <strong>af</strong>ledt på ny, og en eventuel ændring kan dermed bibeholdes.<br />
Brugeren har mulighed for at markere enkelte split eller repeat-kommandoer (f.eks. med etage eller<br />
kolonne), hvormed tupelen også kan indeholde semantisk information. Et valg <strong>af</strong> en etage eller en<br />
kolonne kan dermed ske ved at finde figurer der har den ønskede semantiske information.<br />
Systemet har desuden en visuel editor <strong>af</strong> produktionsregler, hvorved en hel bygning kan konstrueres,<br />
uden tekstbaseret editering. Metoden er tilstrækkeligt hurtigt til, at muliggøre interaktiv editering.<br />
3.2.12 Kommercielt software<br />
Udover de i dette <strong>af</strong>snit beskrevne metoder, findes der både kommercielt og open-source software<br />
der er relevant i denne sammenhæng.<br />
3.2.12.1 Autodesk Revit<br />
Revit er et CAD program fra Autodesk. Revit benytter det såkaldte BIM paradigme, der står for<br />
Building Information Modeling. BIM modellering indebærer ofte generering og forvaltning <strong>af</strong><br />
bygningsdata gennem hele bygningens livscyklus. I stedet for at arbejde med rå geometrisk<br />
stregdata, arbejder man i BIM med begreber såsom vægge, vinduer, døre, tage og elektriske<br />
installationer, der tilsammen udgør en komplet bygning. Desuden kan en BIM model holde styr på<br />
bygningselementernes indbyrdes forhold, f.eks. et sæt vægge der sammen danner et rum.<br />
Revit er interessant i denne sammenhæng, da man har mulighed for at modellere tage via en metode<br />
der baserer sig på teorien om polygonens straight-skeleton. Brugeren kan udpege et antal<br />
sammenhængende vægge, sætte hældningsparametre på disse og få systemet til at beregne taget.<br />
Man kan modellere saddeltage ved at sætte gavlene til ikke at have en hældning. Mere komplicerede<br />
tage, f.eks. mansardtaget eller den hollandske gavl kan modelleres som to tage, hvor det nedre er<br />
beskåret og det øvre ekstruderes fra det polygon der opstår i skæringsplanet (Figur 65).<br />
65
Figur 65: Modellering <strong>af</strong> hollandsk gavl i Revit. Den nedre del består <strong>af</strong> et valmet tag og den øvre består <strong>af</strong> et<br />
saddeltag.<br />
3.2.12.2 Procedural inc og speedtree<br />
To gode eksempler på anvendelse <strong>af</strong> proceduralmodellering i industrien er CityEngine fra Procedural<br />
inc. og SpeedTree fra Interactive Data Visualization, Inc..<br />
SpeedTree er et modelleringsværktøj der specifikt er rettet mod proceduralmodellering <strong>af</strong> planter og<br />
plantedele. Systemet er baseret på l-systemer, men brugeren arbejder i et CAD lignende miljø.<br />
Systemet kommer med over 200 forskellige plantearter, der kan proceduralmodelleres ud fra et stort<br />
antal parametre, f.eks. alder, vindpåvirkning eller omgivende geometri. Systemet kan herefter bygge<br />
et vilkårligt antal forskellige træer baseret på den modellerede plante.<br />
Derudover medfølger kode til realtidsvisualisering <strong>af</strong> planterne. Det er muligt at simulere<br />
vindpåvirkning i realtid, og systemet vil automatisk generere LOD modeller og transitioner mellem<br />
disse. Den medfølgende kode kan anvendes til at generere modellerne ved opstart <strong>af</strong> spillet, hvilket<br />
kan medvirke til hurtigere opstartstider.<br />
Systemet har h<strong>af</strong>t stor succes og er efterhånden anvendt i et anseeligt antal spiltitler. En række<br />
game-engines bl.a. UnrealEngine, har inkorporeret SpeedTree direkte i deres modelleringsværktøj.<br />
Desuden findes systemet som plugin til 3Ds Max.<br />
CityEngine minder om SpeedTree, borset fra at systemet er rettet mod proceduralmodellering <strong>af</strong> hele<br />
byer. Procedural inc er et såkaldt spin-off fra ETH Zürich (det tekniske universitet i Zürich),<br />
grundlagt <strong>af</strong> bl.a. Pascal Müller, medforfatter til en række artikler præsenteret i dette <strong>af</strong>snit.<br />
Systemet er tiltænkt brug i byplanlægning, arkitektur, spiludvikling, film-industrien og arkæologi.<br />
Systemet har følgende funktioner:<br />
<strong>Proceduralmodellering</strong> <strong>af</strong> vejnet.<br />
Import <strong>af</strong> eksisterende vejnet (f.eks. fra OpenStreetMap).<br />
Automatisk underinddeling <strong>af</strong> celler fra vejnettet til parceller, der efterfølgende er<br />
udgangspunkt for modellering <strong>af</strong> bygninger.<br />
<strong>Proceduralmodellering</strong> <strong>af</strong> parametriske bygninger via CGA shape-grammar. (Benytter<br />
metoden beskrevet i <strong>af</strong>snit 3.2.9)<br />
Import <strong>af</strong> GIS data, der kan bruges som aksiom i CGA shape grammar.<br />
En by-wizard, der kan skabe hele <strong>bymiljøer</strong> på et øjeblik, ud fra et prædefineret bibliotek <strong>af</strong><br />
template-bygninger.<br />
66
Figur 66: Brugerflade fra Procedural inc's CityEngine.<br />
Systemet har været tilgængeligt siden 2008, og er derfor ikke helt så udbredt som SpeedTree.<br />
Systemet kan eksportere direkte til de største game-engines, og er anvendt <strong>af</strong> en række store<br />
spiludviklingsstudier.<br />
En bemærkelsesværdig tilføjelse i forhold til artiklen [Müller, Wonka, Haegler, Ulmer, & Van Gool,<br />
2006], er måden hvorpå tage håndteres. I den nyeste version <strong>af</strong> systemet fra 2010, er det nu muligt at<br />
anvende såkaldte parametriske tage, der inkluderer valmet tag, saddeltag, pyramidetag og pulttag.<br />
Ifølge vejledningen på systemets hjemmeside 2 , ser syntaksen for parametriske tage således ud:<br />
Lot --> extrude(10) Mass<br />
Mass --> comp(f) { top: Top | all: X }<br />
Top --> roofHip(30, 2) Roof<br />
I dette tilfælde er der tale om et valmet tag med en hældning på 30 o og med udhæng på 2. Resultatet<br />
<strong>af</strong> den ovenstående grammar ser således ud:<br />
2 http://www.procedural.com/<br />
67
Figur 67: Parametrisk tag genereret via CityEngine.<br />
Det er klart at systemet anvender et straight-skeleton på den foregående figurs fod<strong>af</strong>tryk. De <strong>af</strong>ledte<br />
tagflader er hver især en figur, der efterfølgende indsættes i grammaren med navnet Roof, hvorved<br />
systemet kan arbejde videre med disse, og evt. indsætte vinduer eller kviste.<br />
3.3 Teori<br />
I det forrige <strong>af</strong>snit har jeg gennemgået den litteratur, jeg finder relevant for dette projekt. I de<br />
beskrevne artikler er der anvendt generelle metoder fra hele området for computergr<strong>af</strong>ik. I dette<br />
<strong>af</strong>snit vil jeg derfor gennemgå den teori, der vil blive anvendt til udvikling og implementering <strong>af</strong> min<br />
metode.<br />
Nogle <strong>af</strong> metoderne beskrevet i <strong>af</strong>snit 3.2 (Relateret arbejde), kan opfattes som teoretisk<br />
baggrundsviden, men jeg har valgt at introducere dem tidligere, da de er nødvendige for forståelsen<br />
<strong>af</strong> de efterfølgende metoder. Her tænker jeg specielt på <strong>af</strong>snittene 3.2.1 (A Novel Type of Skeleton for<br />
Polygons) og 3.2.9 (Procedural modeling of buildings ). Samtidig vil jeg i metode<strong>af</strong>snittet gå i dybden<br />
med noget <strong>af</strong> den, i den forbindelse relevante, teori. Dette <strong>af</strong>snit vil derfor være forholdsvis<br />
kortfattet.<br />
3.3.1 Den geometriske værktøjskasse<br />
Dette projekt omhandler beregning på geometrisk data, og jeg vil derfor gøre brug <strong>af</strong> den brede vifte<br />
<strong>af</strong> beregningsmetoder der er almindeligt kendte indenfor dette område. Denne viden har jeg tilegnet<br />
mig gennem min udannelse på DTU, og den danner grundlag for den værktøjskasse <strong>af</strong> metoder jeg<br />
har anvendt til, at løse de udfordringer jeg har behandlet i dette projekt. Jeg vil for metoderne i dette<br />
<strong>af</strong>snit referere til [Akenine-Möller, Haines, & Hoffmann, 2008] og [Bærentzen, Anton, Gravesen, &<br />
Aanæs, 2006].<br />
3.3.1.1 Polygonen<br />
Jeg har tidligere diskuteret polygonen og definitionen <strong>af</strong> denne. Her følger en mere anvendelses<br />
orienteret beskrivelse.<br />
68
Fra Jordan Curve Teoremet kan det udledes, at hver stråle startende i et punkt i polygonens indre i en<br />
arbitrær retning vil krydse polygonens kant et ulige antal gange. Modsat gælder det at en stråle fra<br />
ethvert punkt udenfor polygonen i en arbitrær retning vil krydse polygonen 0 eller et lige antal<br />
gange.<br />
Når vi betragter et konkret punkt kan vi vælge en retning, f.eks. vandret, og teste for antallet <strong>af</strong><br />
krydsninger med polygonen. For selvkrydsende polygoner kan denne fremgangsmåde resultere i<br />
flertydigheder:<br />
Figur 70: Lige-ulige test for selvkrydsende polygon.<br />
Hvorvidt dette resultat er korrekt, <strong>af</strong>hænger <strong>af</strong> situationen. I forbindelse med dette projekt spiller<br />
det ingen rolle, da jeg ikke skal tage højde for selvkrydsende polygoner.<br />
3.3.1.2 Det geometriske plan<br />
Et plan er entydigt defineret ved en normal-vektor (n) og en <strong>af</strong>stand langs denne vektors akse fra<br />
koordinatsystemets origo til planets skæring med aksen (d).<br />
71
Et punkt betegnes som udenfor med hensyn til et plan hvis <strong>af</strong>standen projiceret på planets normal er<br />
længere en planets d-parameter.<br />
Figur 73: Klipping <strong>af</strong> et polygon med hensyn til et plan.<br />
Algoritmen er hurtig og robust og jeg vil anvende den ved flere lejligheder i mit projekt, men den<br />
virker ikke for klipping <strong>af</strong> et arbitrært ikke-konvekst polygon mod et andet ikke-konvekst polygon,<br />
kun mod et andet konvekst polygon. I det følgende <strong>af</strong>snit vil jeg bl.a. kort skitsere en sub-optimal<br />
men konceptuelt simpel og robust algoritme til generel polygonklipping.<br />
3.3.1.3 Polygonmesh<br />
Et polygonmesh er et sæt sammenhængende polygoner, der definerer et polyeder i 3d. Ofte defineres<br />
et mesh <strong>af</strong> et sæt punkter og et sæt indekserede flader der angiver topologien mellem punkterne. Et<br />
polygon kan f.eks. være en tagmodel i computergr<strong>af</strong>ik:<br />
74
Figur 74: Et polygonmesh formet som et tag.<br />
I dette projekt vil jeg benytte mig <strong>af</strong> egentlige ikke-konvekse polygoner, men ofte er der tale om<br />
enten et trekants eller firkantsmesh.<br />
En mere fleksibel repræsentation <strong>af</strong> et mesh er den såkaldte half-edge datastruktur [Mantyla, 1988].<br />
Hvor hver kant i meshet repræsenteres <strong>af</strong> et par <strong>af</strong> modsatrettede kanter (half-edge). Strukturen i<br />
dette mesh kan visualiseres således:<br />
Figur 75: Mesh bestående <strong>af</strong> to trekanter og dets half-edge datastruktur. En half-edge er repræsenteret ved<br />
Hver kant kender punktet hvorfra den udspringer (start), punktet hvor den ender (end), sin<br />
modsatte kant (opp) og den flade den tilhører (face). I Figur 75 er det tydeligt hvilken flade hver kant<br />
tilhører, og generelt er de i positiv omløbsretning for deres flade. Derudover har alle kanterne en<br />
75
pointer til den næste kant i deres flade (next). Endelig har en vertex en pointer til én <strong>af</strong> de udgående<br />
kanter (edge), og en flade har en pointer til én <strong>af</strong> sine kanter (edge).<br />
Det elegante ved datastrukturen er, at kanter i et almindeligt mesh ikke er retningsinvariante,<br />
hvilket i denne struktur håndteres ved eksplicit at opretholde to retningsbestemte kanter. Kanten<br />
der deles mellem de to flader i Figur 75, ville i den simple datastruktur have forkert retning i forhold<br />
til omløbsretningen for én <strong>af</strong> fladerne. Den opmærksomme læser vil bemærke, at meshet i Figur 75<br />
har en tredje flade, nemlig den der udgøres <strong>af</strong> de udvendige kanter der løber i negativ<br />
omløbsretning. Disse kanter har en null-pointer til deres flade. Jeg vil senere vise hvordan dette<br />
fænomen kan udnyttes.<br />
Strukturen gør det let at fortage følgende søgninger:<br />
Alle kanter i en flade: Flade edge next next .<br />
Alle punkter i en flade: Samme som for kanter, men kanternes start vertex returneres.<br />
Alle kanter for en vertex: Vertex edge opp next opp next ...<br />
Alle flader forbundet til en vertex: Samme som for kanter, hvor fladen for hver kant noteres.<br />
I det videre arbejde får vi brug for at kunne bestemme alle polygoner der er indeholdt i en hob <strong>af</strong><br />
kanter i et plan. Vi skal altså kunne bygge et half-edge mesh, uden indledningsvis at kende til<br />
datasættets flader. Jeg benytter mig <strong>af</strong> følgende fremgangsmåde:<br />
1. Først finder jeg alle sammenfaldende punkter. For at tage højde for numerisk upræcision<br />
vælger jeg sammenfaldende punkter inden for en meget lille ε-radius (typisk 0,00001).<br />
2. Herefter deler jeg kanter, der hvor de indbyrdes skærer hinanden, og opretter en ny vertex<br />
forbundet til alle fire kanter.<br />
3. Alle duplikerende kanter, eller kanter der forbinder et punkt med sig selv, fjernes.<br />
4. Jeg har nu en simpel gr<strong>af</strong>struktur, uden krydsende kanter, duplikerede kanter eller kanter der<br />
forbinder knuder med sig selv.<br />
5. Jeg kan nu følge kanter til polygoner ved at vælge den mindste indre vinkel (least interior<br />
angle), hver gang jeg når en vertex. Dette fortsætter indtil jeg har besøgt alle kanter i begge<br />
retninger.<br />
6. Jeg har nu et sæt polygoner, og jeg kan vælge at bygge et half-edge mesh <strong>af</strong> disse eller blot<br />
returnere dem.<br />
Den mindste indre vinkel beregnes ved at gennemløbe alle udgående kanter for en vertex, beregner<br />
deres vinkel i forhold til den indkommende kant og vælge den mindste:<br />
76
Figur 76: Mindste indre vinkel for en indkommende kant.<br />
Hver resulterende polygon må kontrolleres for omløbsretning, og netop én polygon vil være negativ.<br />
Denne er netop polygonen der markerer gr<strong>af</strong>ens ydre grænse (samme polygon, som det der opnås<br />
ved et såkaldt boundary walk). Jeg vil ved flere lejligheder have brug for evnen til netop at finde<br />
denne polygon.<br />
De ovenstående betragtninger kan ydermere benyttes til en generel polygonklippings-mekanisme i<br />
2d. Polygonklipping kan betragtes som en sæt-operation på polygoners punktsæt. Inputtet til<br />
algoritmen er en liste <strong>af</strong> polygoner, hvor målet er at finde f.eks. foreningsmængde <strong>af</strong> disse.<br />
Fremgangsmåden er som følger:<br />
1. Opløs sættet <strong>af</strong> polygoner i en simpel gr<strong>af</strong>.<br />
2. Find alle indeholdte polygoner i denne gr<strong>af</strong>.<br />
3. Find et punkt i hver <strong>af</strong> polygonernes indre (f.eks. via æseløre fremgangsmåden).<br />
4. Benyt dette punkt som test for hvilke polygoner i inputsættet der indeholder<br />
resultatpolygonen, og frasorter de der ikke opfylder sæt-operation.<br />
Alle resulterende polygoner sættes sammen ved at finde resultatets ydre grænse (boundary-walk).<br />
77
4 Observationer, analyse og hypotese<br />
I dette <strong>af</strong>snit vil jeg give et overblik over resultaterne <strong>af</strong> mit litteraturstudie, og samtidig uddrage de<br />
centrale hovedpunkter.<br />
<strong>Proceduralmodellering</strong> <strong>af</strong> <strong>bymiljøer</strong> er et område i rivende udvikling, og resultaterne er efterhånden<br />
<strong>af</strong> så høj kvalitet, at industrien har fået øjnene op for fordelene ved teknologien.<br />
Meget overordnet kan man sige, at de forskellige metoder forsøger at finde en balance mellem<br />
designerens kontrol og effektivitet. Groft sagt, jo mere kontrol en designer vil have over<br />
modelleringsprocessen, jo mere tid tager det. Kontrol koster altså tid, og tid koster penge og<br />
ressourcer, der kunne være brugt mere produktivt. Dette varierer naturligvis meget fra metode til<br />
metode. Nogle er bedre til at finde den rette balance, og nogle udnytter gr<strong>af</strong>ikerens tid bedre end<br />
andre. Jeg vurderer at en metode, der fungerer fuldstændig automatisk, kun er anvendelige i meget<br />
begrænsede tilfælde. CityEngine’s wizard er et eksempel på en metode der er fuldautomatisk. Det er<br />
svært at forestille sig en designer, der vil lade sig diktere fuldstændigt <strong>af</strong> et modelleringsværktøj.<br />
Menneskelig intervention i modelleringsprocessen er derfor ikke et problem i denne sammenhæng,<br />
så længe produktiviteten er forholdsvis høj. I sidste ende vejer kvaliteten <strong>af</strong> det endelige resultat<br />
højere.<br />
Alle artikler om proceduralmodellering <strong>af</strong><br />
bygninger, bygger på en eller anden form for<br />
regularitet <strong>af</strong> den arkitektur der kan<br />
udtrykkes. Her er der tale om de forventninger<br />
man har til de værktøjer der gør brug <strong>af</strong><br />
proceduralmodellering. Alle metoderne<br />
forsøger at opstille enten eksplicitte eller<br />
implicitte regler for en bygnings struktur. I<br />
mange tilfælde er der ligefrem tale om et<br />
hierarki: En bygning består <strong>af</strong> en række<br />
bygningsdele, der har en række facader, der<br />
består <strong>af</strong> en række etager, der igen har en<br />
række vinduer osv.. Operahuset i Sydney er et<br />
eksempel på en bygning der i grove træk<br />
falder fuldstændigt uden for denne definition. Dette<br />
er dog et helt særligt specialtilfælde. For langt de<br />
Figur 77: Utzons operahus, Sydneys<br />
karakteristiske vartegn.<br />
fleste bygninger kan man umiddelbart definere begreber såsom facade og etage. Det gælder altså om<br />
at finde fællesnævnere der dækker begrebet arkitektur så bredt som muligt, men stadig kan<br />
defineres <strong>af</strong> simple koncise regler. De resterende specielle bygninger er vartegn (landmarks), hvor vi<br />
må acceptere, at der findes manuelle værktøjer der er bedre egnede, f.eks. i tilfældet for operahuset i<br />
Sydney.<br />
Jeg vurderer, at et rimeligt kvalitetskrav må være, at de genererede bygninger har høj geometrisk<br />
detaljeringsgrad. Bymiljøer i moderne computerspil er ofte detaljeret ned til f.eks. vindueskarme<br />
eller gesimser. Metoden bør derfor kunne modellere facadens geometri, og ikke bare beklæde<br />
78
facaden med en tekstur. Det <strong>af</strong>hænger selvfølgelig <strong>af</strong> modellens tiltænke anvendelse, og derfor bør<br />
metoden automatisk kunne bygge modeller i forskellige levels-of-detail. Af denne grund er<br />
metoderne i [Greuter & Parker, 2003] og [Kelly & McCabe, 2007] udelukkede som udgangspunkt for<br />
mit videre arbejde. Det er muligt at de kan anvendes i særlige sammenhænge, men i det generelle<br />
tilfælde er metoderne forældede. Det er ikke længere tilstrækkeligt blot at teksturere facaderne, også<br />
selvom der anvendes normal-maps.<br />
En række metoder behandler modellering <strong>af</strong> vejnet. Disse er som sagt ikke i fokus for dette projekt,<br />
men metoden bør naturligtvis kunne spille sammen med genererede vejnet eller eksisterende GIS<br />
data, hvilket i øvrigt er tilfældet for alle metoder gennemgået i <strong>af</strong>snit 3.2.<br />
I [Wonka, Wimmer, Sillion, & Ribarsky, 2003] påpeges et problem ved grammaer, anvendt til<br />
modellering <strong>af</strong> facader: Hvis man ikke er påpasselig udvikler stokastiske systemer sig kaotisk. I<br />
artiklen forslås en kontrol-grammar, der skal varetage designvalg gældende for hele bygningen. Der<br />
er igen tale om en <strong>af</strong>vejning mellem metodens udtryksfuldhed (evnen til at generere variation) og<br />
designerens kontrol. Det må konkluderes, at en metode skal have mulighed for kontrol og styring <strong>af</strong><br />
globale designvalg for en bygning, hvad enten disse valg også er et produkt <strong>af</strong> stokastisk proces<br />
(f.eks. en stokastisk kontrol-grammar), eller udtryk for et direkte valg fra brugeren.<br />
En række artikler bygger på arbejdet i [Müller, Wonka, Haegler, Ulmer, & Van Gool, 2006]. Artiklen<br />
præsenterer særdeles flotte resultater, og har fundet anvendelse i industrien. Ved at give udførlige<br />
eksempler for en række almindelige bygningstyper, demonstrerer artiklen hvordan konkrete<br />
problemstillinger kan løses. Metoden er fleksibel, og kan tage en bred vifte <strong>af</strong> inputdata, der gør den<br />
kompatibel med systemer der modellerer vejnet. Dermed er det i sidste ende muligt at generere hele<br />
<strong>bymiljøer</strong>. Metoden gør det desuden muligt for designeren, at bestemme hvilke dele der skal<br />
varetages <strong>af</strong> grammaren, og hvilke dele der skal håndteres <strong>af</strong> traditionelle modelleringsværktøjer.<br />
Dette muliggøres ved hjælp <strong>af</strong> import og indsættelse <strong>af</strong> modeller såsom vinduer direkte i systemet<br />
(via I-kommandoen).<br />
Artiklens forfattere påpeger at modellering <strong>af</strong> bygningens massemodel og facader er to vidt<br />
forskellige processer, der hidtil ikke har kunnet kombineres i en samlet løsning. Via komponentsplittet<br />
gives en meget elegant anvisning på hvordan denne overgang kan håndteres.<br />
Artiklens forfattere har testet systemet på en gr<strong>af</strong>iker, der var i stand til at modellere en by på relativt<br />
kort tid. Problemet er, at gr<strong>af</strong>ikere der ikke har erfaring med programmering, vil have svært ved at<br />
anvende et grammarbaseret system uden grundig vejledning og efterfølgende øvelse. I [Lipp, Wonka,<br />
& Wimmer, 2008] gives et eksempel på en brugerflade der bygges ovenpå CGA, hvormed brugeren<br />
ikke skal tage stilling til den bagvedliggende grammar.<br />
Efter min mening er endnu et <strong>af</strong> problemerne ved CGA, som det er præsenteret i artiklen [Müller,<br />
Wonka, Haegler, Ulmer, & Van Gool, 2006]: Tage håndteres meget dårligt. I den nyeste version <strong>af</strong><br />
CGA-implementeringen i CityEngine kan man benytte parametriske tage, men udvalget <strong>af</strong> tagtyper<br />
er stadig meget begrænset. I modsætning til resten <strong>af</strong> bygningen, der kan modelleres som en<br />
komposition <strong>af</strong> geometriske figurer, er tage en sammenhængende figur der ikke kan repræsenteres<br />
som en samling særskilte objekter. Derfor er simple occlusion-query-test’s ikke tilstrækkelige. I Figur<br />
79
78 ses et tag modelleret med CGA, der tydeligvis er sammensat <strong>af</strong> simple mindre tage. Samtidig er<br />
tage ofte meget komplekse geometriske objekter, hvilket gør manuel modellering kostbar.<br />
Figur 78: Resultat præsenteret i [Müller, Wonka, Haegler, Ulmer, & Van Gool, 2006]. Det ses tydeligt at taget blot<br />
er en komposition <strong>af</strong> meget simple tage, rejst fra kasse-figurer.<br />
I mit videre arbejde har jeg, til trods for de nævnte mangler, valgt at tage udgangspunkt i CGA.<br />
Metoden opfylder mange <strong>af</strong> de krav, der er nævnt i <strong>af</strong>snit 1.1, og en række artikler demonstrerer<br />
hvordan det er muligt at bygge videre på resultaterne, f.eks. ved en overbygning med en gr<strong>af</strong>isk<br />
brugerflade. Det er i metoden desuden muligt at arbejde med facader og deres geometri, og der<br />
sættes ingen grænse for hvor detaljeret en designer kan modellere sine bygninger. Hvis det er ønsket,<br />
er det muligt at arbejde helt ned til enkelte mursten. Dette gør, at metoden også vil kunne bruges i<br />
fremtiden, hvor kravene til modellernes detaljering må forventes at være konstant stigende.<br />
For tagenes vedkommende er det en udbredt opfattelse i litteraturen, at et simpelt straight-skeleton<br />
ikke er tilstrækkeligt til at repræsentere de varierende tagtyper man møder i virkelige huse. I<br />
[Aichholzer & Aurenhammer, 1996] sammenfattes problemet meget godt:<br />
"Even when the slopes of the roof faces are prescribed, a roof is a highly ambiguous object."<br />
Det er klart at et tag ikke er entydigt defineret ved hældningen givet for hver tagflade. Her er der tale<br />
om arkitekters frie kreativitet, der ikke kan forudsiges <strong>af</strong> en computer. Pointen er blot, at metoden<br />
ikke bør være et universelt modelleringsværktøj for alle tænkelige tage. På baggrund <strong>af</strong> eksemplet<br />
med operahuset i Sydney, er det rimeligt at sige, at hvis vi kan modellere en meget stor andel <strong>af</strong> de<br />
mest almindelige tage, vil de resterende særtilfælde kunne håndteres manuelt, ved brug <strong>af</strong> værktøjer<br />
der er bedre egnede til generel mesh-editering.<br />
Det er også klart, at f.eks. mansardtaget ikke kan modelleres på baggrund <strong>af</strong> en hældning specificeret<br />
for hver kant i grundplanet. Her er der behov for mere information fra brugeren. Jeg vurderer at det<br />
er muligt at udbygge metoden til rejsning <strong>af</strong> tage med et straight-skeleton til, at håndtere samtlige<br />
tage i Tabel 1. I mit videre arbejde vil jeg derfor tage udgangspunkt i artiklerne for straight-skeleton<br />
metoden.<br />
80
Med baggrund i de ovenstående observationer har jeg formuleret følgende hypoteser, der vil ligge til<br />
grund for metoden præsenteret i denne rapport.<br />
Nuværende systemer til proceduralmodellering <strong>af</strong> bygninger er uegnede til effektiv<br />
modellering <strong>af</strong> tage.<br />
Det må være muligt at udvikle en model der bygger på et straight-skeleton, men samtidig kan<br />
modellere alle de tagtyper der er nævnt i Tabel 1.<br />
Det må være muligt at inddrage en sådan metode direkte i CGA, og derved opnå en mere<br />
fleksibel mekanisme til ekstrudering <strong>af</strong> tage.<br />
81
5 Metode<br />
I dette <strong>af</strong>snit vil jeg præsentere mit bidrag til teknologien. Mit bidrag er den metode, der er blevet<br />
udviklet i forbindelse med dette projekt. Jeg vil herefter referere til denne metode som min metode.<br />
Metoden er blevet til som resultat <strong>af</strong> min analyse <strong>af</strong> den eksisterende litteratur, og baserer sig på<br />
forudgående arbejde, særligt det der præsenteres i [Müller, Wonka, Haegler, Ulmer, & Van Gool,<br />
2006]. Min foreslåede metode har til formål at lette arbejdet med modellering <strong>af</strong> tage for designere i<br />
forbindelse med proceduralmodellering <strong>af</strong> <strong>bymiljøer</strong>.<br />
Indledningsvist vil jeg give en overordnet beskrivelse <strong>af</strong> metoden, og efterfølgende gå i dybden med<br />
de mest relevante implementeringsspecifikke detaljer.<br />
5.1 Konstruktion<br />
Den eksisterende metode skelner mellem massemodel og facade, hvor taget hører under<br />
massemodellen. Jeg vil udvide denne betragtning til overordnet at skelne mellem følgende<br />
komponenter i et hus: Massemodel, facade og tag. I forhold til tidligere er massemodellen reduceret,<br />
så den nu ikke længere indeholder taget. Dette er, som jeg vil demonstrere senere, praktisk, og<br />
samtidig konceptuelt let forståeligt i forbindelse med modelleringsprocessen. Først bygges en<br />
massemodel, der efterfølgende beklædes med en facade, og endeligt rejses husets tag.<br />
+<br />
Massemodel Facader Tag<br />
+<br />
82
Figur 79: I modellen inddeles et hus i følgende komponenter: Massemodel, facade og tag.<br />
5.1.1 Rejsning <strong>af</strong> tage<br />
Udgangspunktet for min metode er det lagdelte straight-skeleton, der vil blive præsenteret i dette<br />
<strong>af</strong>snit. Oprindelsen til ideen kommer fra måden tage håndteres i Revit Architechture: Et tag kan<br />
rejses ved at angive hældningen for alle kanter i grundplanet, hvilket jeg formoder muliggøres ved et<br />
vægtet straight-skeleton. Brugeren kan herefter skære toppen <strong>af</strong> det rejste tag, hvorved der i<br />
skæringen mellem taget og planet opstår et polygon (Figur 80).<br />
83
Figur 80: I skæringen mellem plan og tag opstår et polygon.<br />
Fra dette polygon kan et nyt tag rejses, med nye parametre, hvormed det er muligt at frembringe en<br />
lang række forskellige tagtyper. Dette er således en slags lagdelt modellering. Da min metode skal<br />
fungere automatisk i forbindelse med proceduralmodellering, er det selvfølgelig ikke praktisk muligt,<br />
at brugeren manuelt skal opsætte klippeplaner, og angive nye hældningsparametre. Målet er, i grove<br />
træk at automatisere lagdelingen, samt finde en måde hvorved en algoritme simpelt kan angive<br />
parametre til en sådan model.<br />
Vi starter med at betragte et straight-skeleton. I [Brenner, 2000] finder vi en helt central observation:<br />
I stedet for at arbejde med vinkelhalveringslinjer i en 2-dimensionel flade, kan vi betragte disse som<br />
skæringer mellem uendelige planer i 3 dimensioner. I stedet for at vi forestiller os bølgefronter der<br />
har udspring i kanterne i polygonet, kan vi forstille os et såkaldt sweep-plan, der bevæger sig opad fra<br />
oprindelsespolygonens plan. Figur 80 <strong>af</strong>billeder et sweep-plan i en given højde over udgangsplanet.<br />
Analogisk til den traditionelle algoritme kan man følge hjørnerne i skæringspolygonen mens sweepplanen<br />
bevæger sig opad, og spore kanterne til et straight-skeleton. Det er klart at man ikke kan<br />
evaluere alle tænkelige positioner <strong>af</strong> sweep-planen, men man kan nøjes med kun at evaluere i eventpunkter.<br />
Et event-punkt opstår i den 3-dimensionelle analogi, ganske enkelt, der hvor 3 eller flere<br />
planer skærer hinanden. Til sidst kan vi foretage en søgning, og udlede alle flader i det endelige tag.<br />
Event-punkterne bliver alle til vertices i tagmodellen.<br />
84
Med min baggrund i computergr<strong>af</strong>ik foreslår jeg, at man betragter et straight-skeleton i 3d som et<br />
clipping-problem. I <strong>af</strong>snit 3.3.1 så vi hvordan et polygon kan klippes (skæres) mht. til en plan.<br />
Derimod er skæring <strong>af</strong> et polygon mht. et andet polygon en kompliceret <strong>af</strong>fære, både i 2d og 3d. I<br />
stedet er det muligt at skære et polygon med et andet polygons udspændte plan, og altså anvende<br />
metoden fra <strong>af</strong>snit 3.3.1. Alle polygoner der udgør de endelige tagflader er plane, hvorved en sådan<br />
skærings-operation altid er mulig.<br />
Figur 81: Skæring <strong>af</strong> to polygoner i 3d ved hinandens udspændte planer.<br />
For et konvekst grundplan er det muligt at rejse et valmet tag, ved at definere et uendeligt stort<br />
kvadratisk polygon for hver tagflade, og efterfølgende klippe disse med alle andre tagfladeplaner<br />
samt til sidst grundplanet. Vi kan naturligvis ikke forstille os en konkret implementering hvori det er<br />
muligt at arbejde med uendeligt store polygoner. Derfor må vi nøjes med relativt store polygoner (jeg<br />
vil senere diskutere konsekvensen <strong>af</strong> dette valg).<br />
I modsætning til konvekse grundplaner er det for ikke-konvekse grundplaner muligt, at der i nogle<br />
tilfælde opstå ikke-konvekse tagflader, hvilket kan ses i eksemplet fra Figur 30:<br />
Figur 82: Den røde tagflade er ikke-konveks, og gennemskæres <strong>af</strong> det blå polygons plan netop langs den blå<br />
stiplede skæringslinje.<br />
85
Ved at klippe en konveks polygon med andre planer er det umuligt at frembringe en ikke-konveks<br />
polygon. I eksemplet i Figur 82 vil det blå polygons plan gennemskære det røde polygon, hvorved<br />
den yderste del <strong>af</strong> tagfladen (den del der ligger på den positive side <strong>af</strong> den blå tagflades plan) vil<br />
mangle. I det generelle tilfælde er det således ikke korrekt at klippe alle polygoner med alle andre<br />
polygoners plan. For at overkomme problemet med konvekse tagflader kan de deles i mindre<br />
stykker. Her kan vi igen benytte analogien til den almindelige fremgangsmåde for straight-skeleton,<br />
og betragte et sweep-plan der gennemløber et antal event-punkter fra grundplanet og opad. I<br />
eksemplet fra Figur 82 er der fire event-punkter (punkter hvor 3 eller flere kanter skærer hinanden).<br />
Hvis man betragter deres højder, kommer de i par <strong>af</strong> to, og sweep-planet vil derfor gennemløbe 3<br />
positioner (inklusiv grundplanen):<br />
Figur 83: Taget i Figur 82 set fra siden. De røde linjer markerer de positioner, sweep-planet gennemløber.<br />
Fra teorien om straight-skeleton ved vi, at de yderste knuder i skelettet altid er knuderne fra<br />
grundplanet. Kanterne forbundet til disse er samtidig altid vinkelhalveringslinjen mellem to nabokanter<br />
i grundplanet. Metoden starter derfor med at skære tagfladerne med planerne fra de to<br />
nabotagflader i grundplanet. Skæringsplanet orienteres ved at betragte krydsproduktet mellem<br />
tagfladernes normal. Dermed kan både refleks-punkter og konvekse punkter i grundplanet<br />
håndteres. Herefter skæres polygonerne med sweep-planet i det første event-punkt, og vi har nu de<br />
nederste dele <strong>af</strong> tagfladerne. Skæringen mellem sweep-planet og tagfladerne danner et nyt polygon,<br />
hvorfra metoden fortsætter på samme måde. Dette gentages indtil skærings polygonen har arealet 0,<br />
hvormed taget er rejst. Bemærk at skæring med et arbitrært plan, der er parallel med grundplanen,<br />
kan resultere i flere nye adskilte polygoner. Denne situation opstår ved split-events.<br />
1 2 3<br />
86
4 5 6<br />
Figur 84: 1) Et meget stort polygon konstrueres for hver kant i grundplanen. 2) Polygonen beskæres med de to<br />
naboplaner. 3) Polygonen beskæres med sweep-planen for det første event-punkt. 4) Det same gøres for de<br />
resterende kanter i grundplanet, hvorved et nyt polygon opstå. 5) Metoden gentages for det nye polygon. 6) De<br />
forskellige lag samles til hele tagflader.<br />
Figur 85: Algoritmen visualiseret i 3d.<br />
Fordelen ved denne fremgangsmåde er, at vi ikke behøver en efterfølgende udledning <strong>af</strong><br />
polygonerne, da disse er en del <strong>af</strong> selve datastrukturen. Derudover er den konceptuelt simpel, og<br />
behøver ingen avancerede datastruktur, og endelig passer metoden perfekt til de videre udvidelser<br />
der vil blive beskrevet i de følgende <strong>af</strong>snit.<br />
I det første skridt konstruerer man et meget stort polygon, hvilket betyder, at metoden indfører<br />
begrænsning i størrelsen <strong>af</strong> tage (<strong>af</strong>hængigt <strong>af</strong> hvor stort dette polygon er). Jeg vil argumentere for, at<br />
denne begrænsning findes i forvejen som resultat <strong>af</strong> begrænset numerisk præcision. Ved alt for store<br />
straight-skeletons bliver præcisionen meget lav, og man risikerer fejl. Det kan diskuteres om en<br />
metode baseret på plan-skæring opretholder en højere numerisk præcision. Algoritmen er derimod<br />
utroligt robust mod eventuel upræcision, hvilket er endnu en stor fordel ved metoden.<br />
87
5.1.2 Lagdelt tagmodel<br />
Den ovenfor beskrevne metode håndterer vægtede tagflader (tagflader med individuel hældning),<br />
ved at konstruere udgangspolygonen med varierende hældning. Metoden kan endda håndtere<br />
enkelte tagflader med en hældning over 90 o , altså sider der skråner udad i forhold til grundplanen.<br />
Et saddeltag kan f.eks. konstrueres ved at sætte hældningen på gavlene til 90 o , men vi kan stadig ikke<br />
konstruere f.eks. et mansardtag.<br />
For at løse dette foreslår jeg en lagdelt tagmodel baseret på straight-skeleton (SSLRM Straight<br />
Skeleton Based Layered Roof Model). Man kan betragte siderne i et mansardtag som en todelt<br />
tagflade der består <strong>af</strong> en nedre del med en høj hældning, der knækker til en tagflade med en lavere<br />
hældning. En opstalt <strong>af</strong> en sådan side ser ud som følger:<br />
Højde = 4; Vinkel = 30 o<br />
Højde = 0; Vinkel = 70 o<br />
Figur 86: Eksempel på opstalt for en side i et mansardtag. Nederste del starter i 0, og har en vinkel på 70 o . Øverste<br />
del starter i højden 4, og har en vinkel på 30 o .<br />
I stedet for at tilknytte en hældning til en kant i grundplanet foreslår jeg at man knytter en opstalt,<br />
hvorved det er muligt at beskrive knæk der måtte optræde i tagsiden. En opstalt er således en liste <strong>af</strong><br />
knæk, der beskriver højden for knækket, samt den efterfølgende vinkel.<br />
88
Figur 87: Mansardtag, konstrueret <strong>af</strong> gavle med lodrette hældninger, og sider med knæk.<br />
En implementering <strong>af</strong> denne metode starter med at finde alle højderne for knæk i den pågældende<br />
model, sorterer disse og eliminerer redundans (flere stop i samme højde). Én fremgangsmåde er, at<br />
bygge det fulde straight-skeleton for den nederste sektion <strong>af</strong> taget. Herefter skæres taget i højden <strong>af</strong><br />
det første knæk, hvorved et nyt polygon opstår, og hvorfra vi kan gentage processen. Det er klart at<br />
denne fremgangsmåde minder meget om processen for konstruktion <strong>af</strong> skelettet ved skæring, der<br />
beskrives i <strong>af</strong>snit 5.1.1. Det er således også muligt at kombinere disse ved, først at finde alle eventpunkter<br />
til et straight-skeleton, og derefter kombinere disse med alle knæk i samlingen <strong>af</strong> opstalter.<br />
Dette giver en samling <strong>af</strong> anvendelige skærings-planer, hvorfra den laveste, der stadig er højere end<br />
sweep-planen vælges.<br />
Når hver ny sektion <strong>af</strong> taget bygges, spørges der hos hver opstalt for at finde hældningen til den<br />
pågældende tagside i den specifikke højde. Derfor føres opstalten videre fra kanterne i én sweepposiotion<br />
til de resulterende kanter i den næste.<br />
Følgende figur illustrerer alle sektioner <strong>af</strong> et mansardtag med halvvalmede gavle:<br />
89
Figur 88: Illustration <strong>af</strong> sektioner i et mansardtag med halvvalmede gavle. Bemærk at der både er skæringsplaner<br />
ved event-punkter samt ved knæk i tagfladen.<br />
5.1.3 Parametriske tage<br />
Det foregående <strong>af</strong>snit beskriver en metode der kan bruges til at modellere en overordentlig stor<br />
variation <strong>af</strong> forskellige tagtyper. Målet er nu, at passe denne model ind i CGA-shape-grammar–<br />
systemet. Dette gøres ved at repræsentere tagene ved den simplest tænkelige parameterisering.<br />
Det første problem vi støder på i denne forbindelse er, at alle sider skal tildeles en opstalt, hvilket er<br />
uegnet til brug i en grammar. Der er ganske enkelt for mange input-parametre at tage stilling til, og<br />
en procedural-metode kan derfor let resultere i kaos. Desuden er det for en brugers vedkommende<br />
upraktisk at skulle angive så stor en mængde inputdata.<br />
Med den nye metode beskrevet i forrige <strong>af</strong>snit kan vi let beskrive disse tage med meget få parametre.<br />
Eksemplet i Figur 86 indeholder et knæk, og kan beskrives ved en tagside der starter i højden 0 med<br />
en hældning på 70 o , der knækker i højden 4 med en efterfølgende hældning på 30 o . Disse parametre<br />
kan samles i et simpelt sæt, der entydigt definerer tagsiden, f.eks:<br />
mansardtag = {0, 70 o , 4, 30 o }<br />
En simpel gavl i et saddeltag kan beskrives ved følgende parametre:<br />
saddelgavl = {0, 90 o }<br />
90
Hvis vi betragter virkelige tage opdager vi, at langt de fleste almindelige tagtyper består gavle og<br />
almindelige sider. Jeg foreslår derfor, at udvide metoden med en overbygning, der forsimpler<br />
beskrivelsen <strong>af</strong> tage, til kun at bestå <strong>af</strong> en gavltype og en tagsidetype.<br />
For at beskrive et tag behøver systemet derfor følgende input parametre: Et sæt kanter i grundplanet,<br />
gavlene i grundplanet, en beskrivelse <strong>af</strong> tagsiderne og en beskrivelse <strong>af</strong> gavlene. Et brugerscenarie<br />
kan dermed se ud som følger: Brugeren skitserer grundplanerne, udpeger gavlene og vælger mellem<br />
forskellige side og gavltyper og endelig sætter hældning og knæk for disse typer.<br />
Figur 89: Kompleks bygning udelukkende modelleret som gavle (venstre: saddelgavl) og almindelige sider<br />
(højre: opskalk).<br />
Det er selvfølgelig klart, at dette er en indskrænkning <strong>af</strong> udtryksfuldheden <strong>af</strong> systemet. En bruger må<br />
begrænse sig til at tænke på et tag som bestående <strong>af</strong> sider og gavle. Jeg vil argumentere for at langt<br />
de fleste tage i rimelig grad kan beskrives på denne måde. Det kan diskuteres om der er behov for 2,<br />
3 eller evt. flere sidetyper. Pointen er overordnet, at vi er nødt til at begrænse frihedsgraderne for<br />
inputdata for samtidig, at begrænse mængden <strong>af</strong> beslutninger der er nødvendige fra brugeren eller<br />
en procedural-algoritme.<br />
Når inputtet er et resultat <strong>af</strong> en procedural metode, kan vi ikke forvente bygningsformer der passer<br />
ind i den nye model for tagmodellering. Et eksempel på et typisk problem for metoder der tager<br />
grundplanet som input, er placering <strong>af</strong> gavle i et simpelt L-formet hus. For denne hustype kan vi<br />
umiddelbart forestille os tre forskellige måder at konstruere gavlene:<br />
91
Figur 90: Eksempler på tre forskellige gavlkonfigurationer for et l-formet hus. Som udgangspunkt er enderne <strong>af</strong><br />
længerne gavle. Den 3. gavl er derimod flertydig: Øverst til venstre: Den smalle længe har midtergavlen. Øverst<br />
til højre: Der er kun gavle i enderne. Nederst: Den bredde længe har midtergavlen.<br />
Da den øst - vestgående længe er bredest, forventer vi intuitivt, at denne må have en gavl i hver ende<br />
(Nederste eksempel i Figur 1). Problemet er: Hvordan udtrykkes dette udelukkende ved hjælp <strong>af</strong><br />
kanterne i grundplanet?<br />
For det første skal den yderste venstre kant i eksemplet fra Figur 90 deles i to, da en tagflade ikke<br />
samtidig kan være lodret og hældende. Således kan vi angive følgende kanter som gavle:<br />
92
Figur 91: Angivelse <strong>af</strong> gavle (røde kanter) i et l-formet huse.<br />
Dermed har vi angivet gavlene i huset, men dette forårsager problemer for udledningen <strong>af</strong> et<br />
straight-skeleton. Problemet er, at de to splittede kanter er parallelle. I en traditionel algoritme for<br />
beregning <strong>af</strong> en skelet-gr<strong>af</strong>, vil man blot kollapse de to parallelle linjer, og altså ignorere det nye<br />
punkt i polygonen (den røde knude i Figur 91). Problemet er at de to kanter, hver i sær indeholder<br />
information, der er vigtig for den endelige definition <strong>af</strong> taget.<br />
Hvis vi forsøger at føde de to parallelle nabokanter til polygon-klippe-algoritmen vil den fejle. De<br />
udledte planer er ikke parallelle, men skæringen mellem dem vil være parallel med kanten i<br />
grundplanet, og dermed ubrugelig. Vi er derfor nødt til at håndtere parallelle nabokanter i<br />
grundplanen.<br />
Når vi betragter taget i Figur 92, opdager vi at det røde område vil blive klippet ud, som følge <strong>af</strong><br />
skæring mellem polygonen fra den røde linje, og planet for den gule tagflade (i det nederste segment<br />
<strong>af</strong> tagfladen).<br />
93
Figur 92: Saddeltag på l-format bygning. Det røde område vil blive klippet fra pga. det gule polygon.<br />
Løsningen på problemet er følgende: Hver gang vi støder på parallelle nabokanter i grundplanet,<br />
indsætter vi et plan (en meget stor polygon) mellem disse, der samtidig er vinkelret på begge<br />
tagfladernes planer. Det gælder nu om at vælge hældningen for dette plan intelligent. Mit forslag er<br />
at vælge den laveste <strong>af</strong> de to hældninger, og orientere denne så den hælder ind i planen med den<br />
højeste hældning. Hvis begge hældninger er lige store sættes den nye plan til lodret.<br />
I eksemplet i Figur 92 vælges altså hældningen fra den skrånende tagflade, der hælder ind i den<br />
lodrette side, hvorved det ønskede resultat opnås.<br />
Processen, med at finde parallelle kanter og indsætte hjælpeplaner, gentages for hver position i<br />
sweep-planet, hvilket giver en yderst robust, effektiv og fleksibel algoritme.<br />
Anvendelsesmulighederne vil blive nærmere belyst i resultat<strong>af</strong>snittet.<br />
5.1.4 Parametriske tage i CGA<br />
Det sidste problem jeg vil behandle er, hvordan vi får tagmodellen ind i CGA-shape-grammarsystemet?<br />
Sproget i dette system har en sammenhængende syntaks, og vi ønsker at bevare<br />
konsistensen, samtidig med, at vi indfører den nye metode til håndtering <strong>af</strong> tage.<br />
Én måde at rejse tage på proceduralmodellerede huse er ved, at tilføje dem ved en postproces, der<br />
tager bygningens massemodel som input. Fra massemodellen kan bygningens grundplan udledes, og<br />
algoritmen kan starte. Problemet ved en postproces er, at taget dermed ikke længere indgår som en<br />
del <strong>af</strong> grammaren. Det er således ikke muligt at tilføje detaljer i tagfladerne, som f.eks. kviste,<br />
skorstene, tagsten eller tagvinduer. Ligesom det for facadernes vedkommende er uacceptabelt ikke<br />
at kunne modellere detaljeret geometri, gælder det samme for tagflader.<br />
Ved at beskrive tage parametrisk er det enkelt at modellere dem i en grammar. Dette kunne f.eks.<br />
være via en makro:<br />
Roof(”mansard”, 70, 3, 30)<br />
94
Her angives et mansardtag med indledende hældning på 70 o , og en øvre sektion med en hældning på<br />
30 o , der starter i højden 3. Dette passer godt ind i det allerede eksisterende system, men vi kan<br />
hurtigt identificere en række problemer. Første problem er, at vi mangler at forsyne algoritmen med<br />
grundplanet. I den ovenstående makro kan man forestille sig, at grundplanet udledes fra den figur<br />
makroen anvendes på. Der er to problemer ved denne fremgangsmåde: For det første indeholder<br />
figurerne, vi hidtil har anvendt, ingen specifikation <strong>af</strong> gavle. For det andet består et hus ofte <strong>af</strong> en<br />
komposition <strong>af</strong> flere figurer, der sammen udgør en samlet massemodel. Den ovenstående makro vil<br />
kun være i stand til at bygge et tag til hver enkelt <strong>af</strong> disse figurer, og dermed ikke en samlet tagmodel<br />
for hele huset. Dette er det samme problem, som beskrevet i Figur 78 på side 80.<br />
Min løsning er, at dele tagmodelleringen i to separate skridt. Først finder vi alle kanter i grundplanet.<br />
Derefter rejser vi taget på baggrund <strong>af</strong> disse kanter. Til at finde kanterne indfører vi et nyt argument<br />
til komponentsplittet, der returnerer alle kanter i grundplanet:<br />
Comp("footprint", 0, 1) {roofEdge}<br />
Parameteren ”footprint” fortæller makroen, at vi ønsker at finde husets grundplan. De efterfølgende<br />
parametre indikerer en vektor der udpeger gavlene i denne grundplan. Resultatet er en række figurer<br />
<strong>af</strong> en særlig kant-type, der indeholder et flag der markerer, hvorvidt de er gavle eller ej. I dette<br />
tilfælde navngives grundplanskanterne ”roofEdge”.<br />
Udpegningen <strong>af</strong> gavle foregår i figurens scope-koordinatsystem. Alle kanter der er nøjagtigt vinkelret<br />
på gavl-vektoren markeres som gavle:<br />
Figur 93: Vektoren angiver gavlene (de røde kanter).<br />
I stedet for at lade tag-makroen operere på forgængerfiguren, tilføjes en ny parameter der fortæller<br />
hvilke kanter i konfigurationen der indgår i tagets grundplan:<br />
Roof(”roofEdge”, ”mansard”, 70, 3, 30)<br />
Roof-kommandoen indsamler alle kanter i samme højde med navnet roofEdge, og anvender disse.<br />
Det er muligt at sikre, at alle kanter er udledt, før man kalder Roof-kommandoen ved, at give<br />
produktionen lavere prioritet. Dermed vil en typisk modellering <strong>af</strong> et tag se ud som følger:<br />
95
Priority: 1<br />
...<br />
top -> roof Comp("footprint", 0, 1) {roofEdge};<br />
Priority: 2<br />
roof -> Roof(”roofEdge”, ”mansard”, 70, 3, 30)<br />
{roofFace | gable};<br />
...<br />
Et typisk brugerscenarie indebærer en massemodel bestående <strong>af</strong> flere separate figurer, f.eks. et hus<br />
med dets forskellige vinger. Hvis vi ønsker at bygge et samlet tag har vi brug for kanterne fra alle<br />
husets grundplaner. Hvis disse figurer overlapper hinanden har vi situationen <strong>af</strong>billedet i Figur 94<br />
(til venstre). Dette input vil ikke umiddelbart kunne anvendes i tagmodellen. For at korrigere<br />
inputdata fortager jeg en sæt-union på alle grundplanernes polygoner. Jeg sørger samtidig for, at<br />
gavle har højere prioritet end ikke-gavle i de tilfælde hvor to eller flere kanter er parallelle og<br />
overlapper hinanden. Dette giver resultatet i Figur 94 til højre. Den opmærksomme læser vil<br />
bemærke, at dette resultat er magen til udgangspunktet Figur 91.<br />
Figur 94: Der fortages en sæt-union på massemodellens overlappende grundplaner (union <strong>af</strong> to polygoner).<br />
I grammaren er der to skridt i <strong>af</strong>ledningen <strong>af</strong> et tag (Comp og Roof), hvilket reflekterer modellen<br />
meget elegant, da den netop behøver to typer inputdata. Efter min mening passer denne<br />
fremgangsmåde meget fint ind i det eksisterende CGA. Desuden benytter vi os <strong>af</strong> makroer og et<br />
udvidet komponentsplit, hvilket ikke bryder med de sædvanlige dogmer i modellering med shapegrammaer.<br />
96
5.2 Implementering<br />
I dette <strong>af</strong>snit vil jeg gå mere i dybden med de implementeringsspecifikke detaljer, i forbindelse med<br />
den metode der er blevet udviklet igennem dette projektforløb. Da kildekoden til prototyperne er<br />
meget omfattende vil jeg, <strong>af</strong> hensyn til læseren, beskrive systemerne i overordnede træk. For flere<br />
detaljer vil jeg henvise til kildekoden der kan findes på den medfølgende CD, eller på adressen:<br />
http://www.student.dtu.dk/~s042624/eksamensprojekt/Source%20code/. En vejledning til <strong>af</strong>vikling<br />
<strong>af</strong> programmerne findes ligeledes på CD’en eller på adressen:<br />
http://www.student.dtu.dk/~s042624/eksamensprojekt/.<br />
Prototypen består <strong>af</strong> 4 forskellige applikationer, der alle er udviklet i .Net og c#. Baggrunden for<br />
dette valg er udelukkende baseret på, at produktiviteten for mit vedkommende er højere i dette<br />
framework og, at jeg samtidig har mulighed for at benytte mig <strong>af</strong> det udmærkede katalog <strong>af</strong><br />
værktøjer der medfølger. Gr<strong>af</strong>ikken er for 3d-applikationernes vedkommende udviklet i Microsofts<br />
XNA 3.1, der er et gr<strong>af</strong>ik bibliotek, der åbner DirectX (9) til .Net-platformen og samtidig tilbyder en<br />
række værktøjer henvendt til 3d-gr<strong>af</strong>ikprogrammører. For 2d-applikationernes vedkommende er<br />
gr<strong>af</strong>ikken udviklet i Microsoft WPF (Windows Precentation Foundation), der er <strong>af</strong>løseren for<br />
winForms.<br />
Prototypen består <strong>af</strong> følgende applikationer:<br />
LSystem3_1: Denne applikation er en<br />
træmodel-generator, der skal<br />
demonstrere min implementering <strong>af</strong> Lsystemerne.<br />
Systemet hedder 3_1 for at<br />
differentiere den fra en tidligere version,<br />
der blev udviklet til XNA 2.0. Som<br />
argument tager applikationen en<br />
reference til en fil indeholdende lsystemet,<br />
samt et tal der indikerer<br />
alderen på de producerede træer.<br />
Applikationen kompilerer l-systemet, og<br />
udleder 5 forskellige træmodeller, der<br />
visualiseres og gemmes i en fil (tree.obj)<br />
<strong>af</strong> typen .obj.<br />
97
RoofBuilder: Denne applikation skal<br />
demonstrere fleksibiliteten <strong>af</strong> min<br />
tagmodelleringsmetode. Brugeren kan,<br />
via en simpel brugerflade, skitsere et<br />
grundplan, angive gavle og vælge<br />
gavltype og tagsidetype. I denne<br />
prototype er det muligt at vælge<br />
mellem: Flad gavl, valmet gavl,<br />
halvvalmet gavl, hollandsk gavl,<br />
saddeltag, mansardtag og opskalket tag.<br />
Endeligt er det muligt for brugeren at<br />
angive parametrene til de respektive<br />
tagtyper.<br />
CGA+: Denne applikation er en<br />
bygningsmodelgenerator, der skal<br />
demonstrere min implementering <strong>af</strong><br />
CGA. Jeg har tilføjet ’+’ i min udgave <strong>af</strong><br />
systemet for at indikere, at dette er en<br />
forbedret version <strong>af</strong> det oprindelige CGA<br />
(med den forbedrede<br />
tagmodelleringsmetode). Som argument<br />
tager applikationen en reference til en<br />
fil indeholdende en CGA-grammar.<br />
Systemet kompilerer denne fil, og<br />
producerer en bygnings-model, der<br />
visualiseres og gemmes i en fil<br />
(model.obj) <strong>af</strong> typen .obj. Hvis det er<br />
ønskeligt kan applikationen også tage<br />
en reference til en fil indeholdende GISdata,<br />
hvormed det er muligt at genere<br />
bygningerne til en hel by.<br />
98
GISDrawer: I denne applikation er det<br />
muligt at skitsere og redigere GIS-data<br />
der kan læses <strong>af</strong> CGA+ -applikationen.<br />
Fra denne applikation er det muligt at<br />
starte CGA+, og evaluere sin GIS-data.<br />
Derudover har programmet et property<br />
systemet, der sørger for, at de relevante<br />
parametre bliver sat i shapegrammaren.<br />
5.2.1 XNAUtil<br />
De ovennævnte applikationer gør alle brug <strong>af</strong> en række hjælpefunktioner, som derfor er samlet i et<br />
fælles assembly: XNAUtil.<br />
Først og fremmest indeholder hjælpebiblioteket en række matematiske hjælpeklasser, der ikke<br />
findes i XNA’s linear-algebra-bibliotek: BoundingBox2D, der er en simpel axis-aligned-boundingbox i<br />
2d, og klasserne Edge2D og Edge3D, der er simple kanter med et start og slutpunkt i hhv. 2d og 3d.<br />
XNA har et forholdsvis veludviklet bibliotek til lineær algebra med 32 bits float præcision. I mit<br />
arbejde med især tagmodelleringsmetoden har det vist sig, at 32 bit ikke er tilstrækkeligt til at opnå<br />
en acceptabel robusthed. Derfor har jeg måtte rekonstruere en betydelig del <strong>af</strong> XNA’s lineær algebrabibliotek<br />
med 64 bit’s (double) præcision. Hjælpeklasserne findes under PrecisionLinAlg i XNAUtil<br />
og indbefatter: Matrix4D, PlaneD, RayD, Vector2D og Vector3D. Navngivningen følger de tilsvarende<br />
metoder i XNA, men med et ’D’, der indikerer double-præcision. Klasserne indeholder i vidt omfang<br />
de samme metoder, som deres analoge klasser i XNA.<br />
I dette projekt har jeg gjort brug <strong>af</strong> en række algoritmer til at finde skæringen mellem forskellige<br />
geometriske objekter. Disse algoritmer er samlet i klassen IntersectionAlgorithms i XNAUtil, og disse<br />
inkluderer:<br />
Linje-linje skæring, mellem to uendeligt lange linjer (LineLineIntersection).<br />
Stråle-plan skæring (RayPlaneIntersection).<br />
Stråle-polygon skæring (RayPolygonIntersection)<br />
Test for sammenfald mellem punkt og polygon i 2d (PointPolygonIntersection).<br />
Afstand mellem punkt og linje, samt <strong>af</strong>standen langs linjen til punktets projektion på linjen<br />
(PointLineIntersection).<br />
Skæringspunkt mellem 3 planer (ThreePlaneIntersection).<br />
Test for separerende akse mellem polygoner i 2d (SeperatingAxis2D)<br />
For algoritmer hvor det har været nødvendigt er de implementeret i både 32 og 64 bits præcision.<br />
Derudover indeholder XNAUtil et hjælpebibliotek til geometriske beregninger, der bl.a. indeholder<br />
funktionerne beskrevet i <strong>af</strong>snit 3.3.1 (Den geometriske værktøjskasse).<br />
99
For de ovennævnte applikationer har jeg h<strong>af</strong>t behov for at kunne rendere den producerede 3dgeometri.<br />
Derfor inkluderer XNAUtil et simpelt render-system (render-engine), der er bygget op<br />
omkring en scene-gr<strong>af</strong> til beskrivelse <strong>af</strong> scenen. Denne gr<strong>af</strong> består <strong>af</strong> en række knuder, der kan<br />
indeholde en liste <strong>af</strong> model-objekter (Renderable), en liste <strong>af</strong> attributter (f.eks. lyskilder eller<br />
materialer) og en liste <strong>af</strong> efterfølgende knuder. Hver knude har desuden en transformation, hvilket<br />
også gælder for alle modeller.<br />
Figur 95: Eksempel på scenegr<strong>af</strong>.<br />
Render-systemet tilbyder følgende værktøjer og effekter:<br />
Rendering <strong>af</strong> modeller med teksturering og per-pixel belysning.<br />
Rendering, med eller uden wire-frame.<br />
Rendering <strong>af</strong> bill-boards med sortering via en simpel 2-pass metode.<br />
Attenuering <strong>af</strong> alfa-værdi for bill-bords, når disse renderes parallelt med kameraet. Denne<br />
effekt er særligt velegnet til rendering <strong>af</strong> grene på træer, da man tydeligt opfatter artefakterne<br />
ved parallel rendering.<br />
Materiale-system.<br />
100
Punkt og retningslyskilder.<br />
Skygger via shadow-map algoritmen.<br />
Screen-space ambient occlusion.<br />
Kamer<strong>af</strong>øring med track-ball.<br />
2D-renderng <strong>af</strong> linjer, cirkler og streger med brede, <strong>af</strong>rundede hjørner og <strong>af</strong>fasede hjørner.<br />
Systemet er bygget op omkring en række HLSL-effekter (High Level Shader Language), dog kan disse<br />
udskiftes fuldstændigt i tilfælde med særlige behov. Dette er muligt, da systemet søger efter<br />
semantiske tags i effektfilerne, hvorved det er i stand til at identificere HLSL-effektens parametre.<br />
Figur 96: Eksempel på rendering med bill-boards, skygge og ambient occlusion.<br />
5.2.2 Coco / r<br />
Både i tilfældene for min implementering <strong>af</strong> L-systemer og CGA-shape-grammaer, har jeg brug for at<br />
bygge parsere der kan <strong>af</strong>kode syntaksen. Det er ikke umiddelbart en triviel opgave at bygge en parser<br />
til et relativt komplekst sprog som f.eks. L-systemer. Til at bygge parsere og compilere findes der<br />
heldigvis en række stærke hjælpeværktøjer, såsom f.eks. yacc/lex. Jeg har valgt at benytte compilergeneratoren<br />
Coco/r. Begrundelsen for dette valg er, at værktøjet bl.a. understøtter c#, det er<br />
forholdsvis simpel og overskueligt og manualer og vejledninger er let tilgængelige og velskrevne<br />
[Mössenböck, 2006]. Jeg vil i den forbindelse nævne, at jeg ikke selv har store erfaringer med<br />
compilerværktøjer, og derfor spiller det sidste argument en væsentlig rolle i mit valg.<br />
101
Coco/r blev oprindeligt udviklet <strong>af</strong> en gruppe på Johannes Kepler <strong>Universitet</strong>et i Linz, og er en<br />
compilergenerator der tager en beskrivelse <strong>af</strong> et sprog i form <strong>af</strong> en EBNF-grammar (Extended Backus-<br />
Naur Form), og producerer en compiler til dette sprog. Compileren er en såkaldt recursive-descent<br />
compiler, der har en metode for hver produktionsregel i sprogdefinitionen, hvorfra den rekursivt kan<br />
kalde andre funktioner der repræsenterer andre produktionsregler. Dette begrænser compileren,<br />
men gør den også attraktiv for uerfarne programmører, der skal løse mere begrænsede<br />
problemstillinger. Kompileren tager desuden en manifestfil, hvor det er muligt at angive konstanter<br />
og inkludere hjælpemetoder. Manifestet bliver brugt som skabelon for den endelige parser.<br />
Sprogbeskrivelsen er delt i to hoveddele: En scanner-specifikation og en parser-specifikation.<br />
Scannerens opgave er at inddele inputfilen i tokens, der benyttes <strong>af</strong> parseren. Scanneren definerer et<br />
antal tegn-sæt, og et antal tokens. En token kan angives via et regular-expression, som f.eks.:<br />
Identifier = letter {letter | digit}.<br />
I Coco/r betyder ’{}’ en gentagelse <strong>af</strong> alle symboler mellem klammerne 0 eller flere gange. Parseren<br />
består i hovedtræk <strong>af</strong> et antal produktionsregler, der beskriver den syntaktiske struktur <strong>af</strong> de ikketerminale<br />
symboler i sproget. Følgende eksempel definerer erklæringen <strong>af</strong> en talkonstant:<br />
ConstantDeclaration =<br />
(<br />
"number" identifier "=" number<br />
)<br />
Parseren arbejder fra venstre mod højre i produktionsreglen (LL-parser), og for hver identificeret<br />
element er det muligt at definere en semantisk handling (et stykke c#-kode, der vil blive sat ind i<br />
parseren). Jeg bruger de semantiske handlinger til at opbygge en data-repræsentation <strong>af</strong> det<br />
kompilerede system i c#.<br />
I begge mine systemer har jeg brug for, at kunne parse algebraiske og boolske udtryk. Følgende<br />
grammar vil identificere et almindeligt algebraisk udtryk, svarende til dem vi finder i f.eks. c#<br />
[Crenshaw, 1988]:<br />
Expression = Term { addop Term }<br />
Term = SignedFactor { mulop Factor }<br />
SignedFactor = [ addop ] Factor<br />
Factor = number | variable | ”(” Expression ”)”<br />
I denne forbindelse indeholder addopp symbolerne ’-’ og ’+’, og mulopp indeholder ’*’ og ’/’.<br />
Boolske udtryk har en tilsvarende form. Med grammaren er det muligt at opbygge et evalueringstræ,<br />
der kan benyttes, hver gang udtrykket skal evalueres. Af hensyn til systemets ydeevne har jeg valgt at<br />
benytte .Net’s runtime-compiler, der kan tage et stykke kode i tekstform, kompilere det og <strong>af</strong>vikle det<br />
mens systemet kører. Jeg har dermed mulighed for at kompilere de algebraiske udtryk og <strong>af</strong>vikle dem<br />
direkte i .Net’s runtime-miljø.<br />
5.2.3 Datastruktur for CGA+<br />
Jeg har defineret CGA som sprog via Coco/r, men uden en datastruktur til at bygge det parsede<br />
system ind i, er vi lige vidt. Datastrukturen for CGA består <strong>af</strong> en række produktionsregler, der med<br />
udgangspunkt i en inputfigur, producerer en række resulterende figurer. Systemet itererer over alle<br />
102
figurer i den aktuelle konfiguration, og vælger passende regler til aktive figurer, hvorved flere figurer<br />
tilføjes konfigurationen. Dette er meget tilsvarende fremgangsmåden for L-systemer bortset fra, at vi<br />
i dette system udvælger aktive figurer en ad gangen, og lader <strong>af</strong>ledningsprocessen løbe, indtil der<br />
ikke er flere aktive figurer i konfigurationen. Man kan sammenligne L-systemer med en bredde-først<br />
<strong>af</strong>ledning, mens CGA er en dybde-først <strong>af</strong>ledning.<br />
Figur 97: Overblik over systemets overordnede design.<br />
En såkaldt makro i CGA foretager operationer på figurer, der resulterer i en eller flere <strong>af</strong>ledte figurer.<br />
En Comp-kommando splitter f.eks. en figur i figurer <strong>af</strong> lavere dimension (f.eks. en kasse der splittes i<br />
flader, kanter eller punkter). Samtidig kan figurer være <strong>af</strong> forskellige typer (f.eks. kasser, kugler eller<br />
cylindre). Dette håndteres i datastrukturen, ved at alle systemer implementerer et fælles interface,<br />
med metoder der reflekterer alle makroer i CGA. Dette kan f.eks. være metoder der bl.a. returnerer<br />
alle flader eller sideflader og en metode der splitter figuren langs en given akse. Det implementerede<br />
system er som sagt en prototype og ikke alle metoder beskrevet i interfacet er implementet i alle<br />
figur-typer.<br />
Jeg har i dette projekt specielt fokuseret på evnen til at kunne ekstrudere et grundplan til en massiv<br />
figur. Derfor har jeg implementeret en figur der defineres <strong>af</strong> et polygon, der kan ekstruderes til en<br />
højde angivet <strong>af</strong> figurens scope-højde. Hver kant bliver i grundplanet til en (firkantet) flade i det<br />
massive polygon, og top og bund <strong>af</strong>sluttes <strong>af</strong> en figur svarende til grundplanet.<br />
103
Figur 98: Femkantet grundplan ekstruderet til massiv figur (defineret indenfor figurens scope).<br />
I min definition <strong>af</strong> sproget for CGA har jeg muliggjort erklæringen <strong>af</strong> talvariable og<br />
tilfældighedsvariable. En talvariabel svarer til almindelige double-variable i andre<br />
programmeringssprog, og erklæringen har følgende syntaks:<br />
number n = 2.1;<br />
En tilfældighedsvariabel returnerer et tilfældigt tal inden for et angivet udfaldsrum, hver gang den<br />
evalueres. En sådan variabel med et udfaldsrum der f.eks. går mellem 0 og 1, kan erklæres som følger:<br />
random r = [0, 1];<br />
Tilfældighedsvariable er meget anvendelige både i L-systemer og CGA, hvis vi ønsker at indføre<br />
variation i vores genererede modeller.<br />
Variablene kan opfattes som globale parametre der definerer globale design-mål for den enkelte<br />
genererede model. Dette kan f.eks. være parametre såsom bygningshøjde, vinduers bredde, antal <strong>af</strong><br />
etager eller taghældning. Der kan også være tale om mere abstrakte begreber, såsom facadetype og<br />
tagtype.<br />
I min implementering har jeg fortaget mindre justeringer i forhold til oplæget fra [Müller, Wonka,<br />
Haegler, Ulmer, & Van Gool, 2006]. Specielt er syntaksen for relative parametre ændret fra at et tal<br />
efterfulgt <strong>af</strong> et ’r’, til at være et tal indledt med en stjerne. Relativparameteren med vægten 1 vil f.eks.<br />
være *1.<br />
Når det gælder fordeling <strong>af</strong> ansvarsområde, vil jeg differentiere imellem grammar og applikation.<br />
Applikationen er programmet der huser grammar-compileren og angiver variablene til grammaren.<br />
104
Grammaren definerer produktionsregler og anvender parametrene til at modellere bygninger og<br />
arkitektur. Jeg kan derfor, på applikationsniveau, trække lod om tagtype, facadetype og sætte globale<br />
design-parametre med stokastiske værdier, inden <strong>af</strong>ledningsprocessen for produktionsreglerne<br />
begynder. Dermed bliver disse parametre gældende for hele bygningen, og vi undgår kaotiske<br />
modeller. Når CGA-grammaren er færdigevalueret, kan jeg på applikationsniveau læse alle figurer,<br />
og sende disse til mit rederingssystem. I den forbindelse kan jeg anvende figurenes navne, som<br />
markør for figurens materiale. F.eks. kan et vindue indeholde underfigurer med navnene glass og<br />
frame, der kan matches med passende materialer.<br />
105
6 Resultater<br />
I dette <strong>af</strong>snit vil jeg præsentere de resultater jeg har opnået i løbet <strong>af</strong> dette projekt. Projektet<br />
spænder vidt, men jeg vil i dette <strong>af</strong>snit hovedsagelig fokusere på modellering <strong>af</strong> tage og <strong>bymiljøer</strong>, og<br />
især på de dele der repræsenterer bidraget fra dette projekt.<br />
Jeg vil redegøre for, at målene fra <strong>af</strong>snit 1.1 er blevet opfyldt. Vurderingen <strong>af</strong> resultaterne vil<br />
hovedsageligt være kvalitativ, da resultatet ikke i væsentlig grad bør måles i metodens hastighed,<br />
men snarere det overordnede visuelle indtryk. Derfor vil der især blive lagt vægt på billedmateriale<br />
som formidler <strong>af</strong> projektets resultater.<br />
For gr<strong>af</strong>ikeren, der er slutbrugeren, er det vigtigt at han/hun har mulighed for at arbejde videre med<br />
modellerne i et <strong>af</strong> de mange eksisterende modelleringsværktøjer. Jeg har derfor inkluderet<br />
eksportfunktioner i mine prototyper, hvorved jeg har mulighed for at vurdere resultaterne i disse<br />
modelleringsværktøjer. For at bedømme hvordan modellerne virkelig tager sig ud, er det vigtigt at de<br />
er renderet med de rette materialer. Derfor har jeg til mange <strong>af</strong> resultatbillederne i det følgende<br />
<strong>af</strong>snit anvendt blender, der er et gratis open-source modelleringsværktøj, som også inkluderer en raytracer<br />
til syntetisering <strong>af</strong> billeder <strong>af</strong> høj kvalitet. Ved hvert billede vil det være angivet, hvorvidt det<br />
er renderet ved ray-tracing eller med min egen realtids-render-engine.<br />
For at teste min implementering <strong>af</strong> CGA systemet, vil jeg i enkelte tilfælde angive tidsmålinger for<br />
genereringsprocessen. Disse er alle målt på en laptop med en Intel Core 2 Duo 2.4 GHz CPU, og er et<br />
gennemsnit <strong>af</strong> 10 forskellige målinger. Det skal nævnes at testen i mange tilfælde er gjort på<br />
stokastiske grammaer hvor antallet <strong>af</strong> polygoner kan variere forholdsvis meget, og hvor de enkelte<br />
målinger derfor også varierer meget.<br />
6.1 L-systemer<br />
Formålet med at bygge en L-systems parser var hovedsageligt, at jeg dermed kunne øve mig i parserværktøjet<br />
på et område, jeg kendte rimeligt godt. Det til trods mener jeg, at resultaterne er blevet<br />
forholdsvis gode, og de proceduralgenerede træer har været velegnede som inventar i sammenhæng<br />
med de genererede <strong>bymiljøer</strong>.<br />
Som udgangspunkt er det muligt at skrive l-systemer i kodefiler i en syntaks, der næsten nøjagtigt<br />
svarer til syntaksen i [Lindenmayer & Prusinkiewicz, 1996]. I bilag 1 medfølger eksempler for<br />
produktionsreglerne for 4 forskellige trætyper. Til fortolkning <strong>af</strong> L-systemer har jeg først og<br />
fremmest implementeret muligheden for parametriske L-systemer, samt de basale symboler, så som<br />
’F’, ’Size’, ’Push’, ’Pop’, ’Roll’, ’Pitch’ og ’Yaw’. Jeg har desuden implementet en fortolker <strong>af</strong> L-systemer,<br />
der som udgangspunkt producerer kegleformede segmenter. Dette giver mulighed for at modellere<br />
forgrenede fraktaler:<br />
106
Figur 99: Forgreningsfraktal, genereret via et l-system. Bemærk hvordan rotation i stammen ikke medfører<br />
huller i modellen.<br />
Af mere avancerede symboler kan nævnes min implementering <strong>af</strong> parametrisk tropisme (’T’),<br />
tilfældig retning (’R’), fastholdt forgrening i forhold til tyngdekr<strong>af</strong>ten (’level’) og endelig muligheden<br />
for varierede udformninger <strong>af</strong> stammer. Disse egenskaber giver mulighed for modellering <strong>af</strong> følgende<br />
træstruktur:<br />
107
Figur 100: Modellering <strong>af</strong> træ via et l-system.<br />
Bemærk hvordan stammen ikke er regulært cylinderformet, og hvordan grenene vrider sig.<br />
Tropismen starter positive (de yderste led <strong>af</strong> grenene) hvor grenen søger opad mod lyset, men<br />
reduceres til negativ efterhånden som længden og vægten <strong>af</strong> grene tynger dem ned. Dette fænomen<br />
kan opserveres i mange virkelige træer:<br />
Figur 101: Grene på dette træ søger tydeligvist opad, mens tyngdekr<strong>af</strong>ten trækker de længste nedad.<br />
108
For at gøre træerne mere håndterbare i forbindelse med rendering, har jeg valgt ikke at generere<br />
hvert eneste blad, men indsætte billboards <strong>af</strong> hele kviste:<br />
Figur 102: Træer med billboards som løv.<br />
Et <strong>af</strong> de vigtigste elementer i rendering <strong>af</strong> trækroner er skygge-effekten indbyrdes mellem bladene. I<br />
Figur 102 ses, hvordan dette giver kronerne volumen.<br />
For stammerne har jeg genereret teksturkoordinater, der gentager sig i et spejlende mønster langs<br />
stammen og grenene:<br />
109
Figur 103: Venstre: Teksturkoordinater langs stammen (rød = x-akse, grøn = y-akse). Højre: træ med tekstureret<br />
stamme.<br />
For at kunne tegne hele skove har jeg desuden brugt L-systemet til at modellere yderligere to<br />
træsorter, et løvtræ og et nåletræ, med mere simpel geometri. Under mit arbejde, fandt jeg at<br />
kileformede billboards var særdeles velegnede som kvist-modeller:<br />
110
Figur 104: Mindre skov <strong>af</strong> tilfældigt genererede træer. Bemærk hvordan screen space ambient occlusion har en<br />
flot effekt netop for træerne.<br />
Jeg har endelig inkluderet en eksportfunktion, hvorved jeg kan visualisere træerne ved hjælp <strong>af</strong> f.eks.<br />
blender:<br />
111
Figur 105: Det endelige resultat for mine L-systems genererede træer, renderet i blender, med skygge og ”korrekt”<br />
ambient occlusion.<br />
6.2 Tage<br />
For tagenes vedkommende har jeg især fokuseret på, at gøre metoden robust, hvorved den skal<br />
kunne klare så varieret indputdata som muligt, uden at producere fejl. Først og fremmest vil jeg<br />
demonstrere, at alle tagtyper, listet i Tabel 1, kan modelleres gennem min metode. I det følgende vil<br />
112
jeg samtidig angive inputdata fra prototypen, hvorved det er muligt at genskabe resultaterne. I det<br />
følgende vises derfor grundplanet for alle tagmodeller, hvor gavlene er markeret med orange.<br />
Til at beskrive tagenes opstalter vil jeg benytte sæt-notationen der blev introduceret i <strong>af</strong>snit 5.1.3.<br />
6.2.1 Typiske tage<br />
Først og fremmest vil jeg gennemgå de tage, der er nævnt i Tabel 1. Det har fra min side været et<br />
eksplicit ønske, at netop disse tagtyper skal kunne modelleres ved brug <strong>af</strong> metoden.<br />
6.2.1.1 Flad tag<br />
Det flade tag er det klart simpleste <strong>af</strong> alle tage, men for min tagmodel kan dette ikke umiddelbart<br />
modelleres. Det flade tag er netop ikke defineret ved en skelet struktur. Dog er det muligt at<br />
konstruere et tilnærmelsesvist fladt tag, via 3 lodrette sider og en side med meget lav hældning. Her<br />
er det værd at bemærke, at virkelige flade tage, også kun er tilnærmelsesvist flade, da vand ellers ikke<br />
vil kunne løbe fra.<br />
Gavl={0m, 90 o }<br />
Side={0m, 0.00001 o }<br />
Figur 106: Modellering <strong>af</strong> flad tag.<br />
6.2.1.2 Saddeltag<br />
Saddeltaget kan modelleres ved to gavle og to almindelige sider:<br />
Gavl={0m, 90 o }<br />
Side={0m, 45 o }<br />
113
Figur 107: Modellering <strong>af</strong> saddeltag.<br />
6.2.1.3 Valmet tag<br />
Det valmede tag kan enten modelleres som et tag uden gavle, eller et tag med gavle, der har samme<br />
hældning som resten <strong>af</strong> siderne:<br />
Gavl={0m, 45 o }<br />
Side={0m, 45 o }<br />
Figur 108: Modellering <strong>af</strong> valmet tag.<br />
6.2.1.4 Halvvalme<br />
I det halvvalmede tag, udskiftes gavlene fra saddeltaget med halvvalmede gavle (inkluderet som<br />
parametertype i prototypen):<br />
Gavl={0m, 90 o , 2m, 45 o }<br />
Side={0m, 45 o }<br />
114
Figur 109: Modellering <strong>af</strong> halvvalmet tag.<br />
6.2.1.5 Hollandsk gavl<br />
Den hollandske gavl modelleres på samme måde som det halvvalmede tag, blot med omvendt<br />
parameterrækkefølge i gavlene (det hældende segment kommer før det lodrette):<br />
Gavl={0m, 45 o , 2.5m, 90 o }<br />
Side={0m, 45 o }<br />
Figur 110: Modellering <strong>af</strong> hollandsk gavl.<br />
6.2.1.6 Pyramide<br />
Pyramiden modelleres med et kvadratisk grundplan, der har uniformt hældende tagflader:<br />
Side={0m, 45 o }<br />
115
Figur 111: Modellering <strong>af</strong> pyramidetag.<br />
6.2.1.7 Mansardtag<br />
Mansardtaget modelleres i grundplanet som saddeltaget, men med mansardsider (inkluderet som<br />
parametertype i prototypen):<br />
Gavl={0m, 90 o }<br />
Side={0m, 75 o , 2m, 45 o }<br />
Figur 112: Modellering <strong>af</strong> mansardtag.<br />
6.2.1.8 Pulttag<br />
Pulttaget kan modelleres med tre lodrette gavle og én hældende gavl:<br />
Gavl={0m, 90 o }<br />
Side={0m, 45 o }<br />
116
Figur 113: Modellering <strong>af</strong> pulttag.<br />
6.2.1.9 Opskalk<br />
Et tag med opskalk modelleres som et mansardtag, blot med omvendt parameterrækkefølge i<br />
siderne.<br />
Gavl={0m, 90 o }<br />
Side={0m, 30 o , 0.5m, 45 o }<br />
Figur 114: Modellering <strong>af</strong> tag med opskalk.<br />
6.2.2 Kombinationer<br />
Jeg har nu vist at metoden kan håndtere de mest almindelige tagtyper (angivet i Tabel 1), der for de<br />
flestes vedkommende er bygget ind i prototypen ved en særlig opstalt. Metoden er dog først rigtigt<br />
generisk, når det er muligt at kombinere forskellige tage. Her følger en række eksempler på<br />
kombinationer <strong>af</strong> de ovenstående typer. Alle er de modellerede over det samme grundplan:<br />
117
Figur 115: T-formet grundplan med 3 endegavle.<br />
Gavl={0m, 90 o , 3m, 45 o }<br />
Side={0m, 75 o , 2.5m, 45 o }<br />
Figur 116: Mansardtag med halvvalm.<br />
118
Gavl={0m, 45 o , 2m, 90 o }<br />
Side={0m, 75 o , 2m, 45 o }<br />
Figur 117: Mansardtag med hollandsk gavl.<br />
Gavl={0m, 90 o , 3m, 45 o }<br />
Side={0m, 30 o , 0.5m, 45 o }<br />
Figur 118: Halvvalmet tag med opskalk.<br />
119
Gavl={0m, 45 o }<br />
Side={0m, 30 o , 0.5m, 45 o }<br />
Figur 119: Valmet tag med opskalk i siderne.<br />
6.2.3 Komplekse grundplaner<br />
Den vigtigste egenskab ved tag-modelleringsmetoden er, at den kan tage alle former for input.<br />
Derfor er den blevet testet grundigt, med meget varierede grundplaner.<br />
Først og fremmest har det været et mål at bygge en modelleringsmetode, der kan håndtere parallelle<br />
nabosider i grundplanet, som samtidigt har forskellige opstalter. Det følgende er et typisk eksempel<br />
på brugen <strong>af</strong> denne effekt:<br />
120
Figur 120: L-formet hus med halvvalmede gavle. Bemærk overgangen mellem gavl og tagside.<br />
Ydermere er det vigtigt for anvendelsen <strong>af</strong> metoden, at den er i stand til at håndtere grundplaner, der<br />
ikke falder under de regulære kategorier, såsom I-, L-, T- eller U-formede huse. De følgende huse vil<br />
derfor alle være umulige at modellere med metoder, der gør brug <strong>af</strong> data for tagets topologi, mens<br />
min metode klarer dem lige så let som alle andre tagtyper. Alle bygningerne er hver især eksempler<br />
på tage, ingen andre metoder kan håndtere direkte:<br />
Figur 121: Mansardtag med 6 halvvalmede gavle.<br />
Figur 122: Tag med parallelle gavle, hvis kant i grundplanen indeholder reflekspunkt.<br />
121
Figur 123: Tag med gavle der ender i hinandens reflekspunkter.<br />
Figur 124: Tag med grundplan der indeholder udbygning. Siderne i udbygningen er alle halvvalmede gavle,<br />
hvorved den fremstår som hævet i niveau.<br />
122
Figur 125: Eksempel på bygning med parallelle lodrette gavle, der har omvendte normaler.<br />
De foregående huse har alle været kasseformede, dvs. udelukkende med 90 o vinkler. For nogle huse<br />
er dette ikke tilfældet. Metoden håndterer alle former for huse med arbitrære vinkler i grundplanet.<br />
Følgende eksempel skal demonstrere metodens robusthed mod et stort antal ikke-vinkelrette kanter:<br />
123
Figur 126: Bygning uden 90 o vinkler i grundplanen.<br />
6.2.4 Robusthed<br />
Indtil nu har vi hovedsageligt kigget på robusthed overfor forskellige typer grundplaner. Derudover<br />
er det <strong>af</strong>gørende at metoden er robust mod varierende hældningsparametre.<br />
Hvis vi igen betragter det L-formede hus med halvvalmede gavle:<br />
124
Figur 127: Tag med halvvalmede gavle. Alle hældninger er 45 o .<br />
I dette tilfælde er alle taghældninger 45 o . Hvis vi reducerer hældningen kun for tagfladen i valmen,<br />
vil <strong>af</strong>standen fra valmens toppunkt til sammenføjningen mellem lægerne blive mindre:<br />
Figur 128: Tag med halvvalmet gavl. Taghældning er 45 o , og hældningen i valmen er 33 o .<br />
125
Hvis vi reducerer hældningen yderligere vil valmens toppunkt og sammenføjningen på et tidspunkt<br />
mødes:<br />
Figur 129: Tag med halvvalmet gavl. Taghældningen er 45 o , og hældningen i valmen er 26,5 o .<br />
Spørgsmålet er nu, hvad der sker når vi reducerer hældningen yderligere. Vil metoden bryde samme,<br />
eller vil den forsøge at finde en eller anden form for løsning:<br />
126
Figur 130: Tag med halvvalmet gavl. Taghældningen er 45 o , og hældningen i valmen er 20 o .<br />
Som det fremgår bryder metoden ikke sammen, men foreslår en løsning. Forløbet i tagenden starter<br />
med, at gavlen har en hældning, der er større end dens parallelle side. På et tidspunkt krydser<br />
valmen sidens plan igen, og i det nye niveau har vi igen to parallelle kanter, men denne gang er<br />
gavlens hældning lavere end sidens. Derfor indsættes en ny tagflade, der nu hælder ind i længen.<br />
Det er klart at denne adfærd, kan være uforudseelig fra en brugers synspunkt. Pointen er at systemet,<br />
trods alt ikke bryder ned. Dette kan være meget fordelagtigt, i de mange tilstande man må forudse<br />
en designer eller en procedural algoritme forventes at udsætte systemet for, især hvis det anvendes<br />
til modellering <strong>af</strong> hele <strong>bymiljøer</strong> med tusindvis <strong>af</strong> forskellige bygninger.<br />
Robustheden kan observeres idet, geometrien i det ovenstående tilfælde er relativt kompleks, og det<br />
er samtidigt langt fra blot et simpelt straight-skeleton.<br />
6.2.5 Fri modellering<br />
Indtil nu har vi for tagenes vedkommende udelukkende anvendt den parametriske model der er<br />
anvendt i prototypen, og hvor modelløren udelukkende kan angive gavle og sider. Denne<br />
fremgangsmåde er tiltænkt proceduralmodelleringsmetoder, og meget simple skitseringer <strong>af</strong> tage.<br />
Den opmærksomme læser har muligvis lagt mærke til, at de foregående <strong>af</strong>bildninger <strong>af</strong> tage, alle har<br />
inkluderet bygningens facader. Disse er i prototypen alle en del <strong>af</strong> selve opstalten i siderne. Metoden<br />
kan således generaliseres til hele bygningen, og ikke blot taget.<br />
Hvis vi ser bort fra forsimplingen, der indebærer begrænsning til blot to forskellige typer tagsider, er<br />
det muligt at modellere mere varierede tagformer og bygninger. I den følgende test har jeg forsøgt at<br />
modellere en kirke i sin helhed, ved brug <strong>af</strong> tre forskellige opstalter:<br />
127
Figur 131: Opstaltsskiteser for kirke. Venstre: Opstalt for siderne i skibet. Midt: Opstalt for kirketårnet. Højre:<br />
Opstalt for gavl i sideskibet.<br />
Disse opstalter kan arrangeres på følgende grundplan:<br />
Figur 132: Grundplanen for en kirke. Blå sider: Tårn. Gule sider: Skibets sider. Grå sider: Sideskibets galve.<br />
Dette resulterer i følgende bygning:<br />
128
Figur 133: Eksempel på modellering <strong>af</strong> en kirke indklusiv vægge og tårn, udelukkende ved brug <strong>af</strong> den lagdelte<br />
tagmodel.<br />
6.2.6 Begrænsninger<br />
Metoden for tagmodellering har enkelte begrænsninger, der her vil blive belyst.<br />
Det første problem vedrører den måde, hvorpå metoden håndterer valget <strong>af</strong> planer der skal<br />
indsættes i tilfælde <strong>af</strong> parallelle kanter i grundplanet. Dette er baseret på et kvalificeret gæt, og i<br />
nogle tilfælde er dette mindre hensigtsmæssigt:<br />
129
Figur 134: L-formet hus med hollandske gavle.<br />
I den ovenstående figur ses et l-formet hus, med hollandske gavle. I dette tilfælde er midtergavlen<br />
nærmest kameraet meget bredere end de resterende gavle. Dette skyldes de to parallelle kanter i<br />
grundplanet, der vil have ens hældning ved tagfoden. Derfor vil der mellem disse blive indsat et<br />
lodret plan, hvorved gavlen ikke, som man måtte forvente, snævres ind mod den øverste del <strong>af</strong> taget.<br />
En anden uhensigtsmæssighed opstår når to umiddelbare <strong>af</strong>snit <strong>af</strong> et hus deler en fælles kant:<br />
Figur 135: Saddeltag på to parallelle længer <strong>af</strong> et hus.<br />
Et straigh skeleton har som sagt den egenskab, at uanset hvor på taget en regndråbe måtte lande, vil<br />
den altid efterfølgende falde nedad, uden at samle sig i render der er parallelle med grundplanet eller<br />
130
fordybninger, hvorfra der kun er opadgående flader. Der vil derfor aldrig kunne dannes en horisontal<br />
kant mellem de to længer i Figur 135, og derfor ser vi den akavede forhøjning i midten <strong>af</strong> taget. Det er<br />
klar at metoden ikke, uden hjælp kan skelne mellem situationen i Figur 135 og den i Figur 136, hvor<br />
forhøjningen virker mere berettiget. Topologien for grundplanerne i de to situationer er netop ens.<br />
Figur 136: Hus med saddeltag.<br />
Forslag til løsning <strong>af</strong> disse problemer, vil blive skitseret i 7.3.<br />
I dette <strong>af</strong>snit har jeg gennemgået et meget begrænset udsnit <strong>af</strong> de forskellige typer tage, der kan<br />
håndteres <strong>af</strong> metoden. På den medfølgende cd, er der en mere omfattende samling <strong>af</strong> billeder, der<br />
demonstrere modellering flere tagtyper.<br />
6.3 Modellering <strong>af</strong> <strong>bymiljøer</strong><br />
I løbet <strong>af</strong> dette projekt har jeg implementeret de væsentligste dele <strong>af</strong> CGA shape grammar som det er<br />
præsenteret i [Müller, Wonka, Haegler, Ulmer, & Van Gool, 2006]. Jeg vil i dette <strong>af</strong>snit præsentere<br />
eksempler på modellering med dette system, samt redegøre for hvordan indførelsen <strong>af</strong> min<br />
parametriske tagmodel forbedrer dette system.<br />
Jeg har ligesom for l-systemerne fulgt anvisningerne til CGA-sprogets syntaks, næsten nøjagtigt som<br />
den er beskrevet i [Müller, Wonka, Haegler, Ulmer, & Van Gool, 2006]. Dermed er det muligt at<br />
beskrive bygninger i en tekstfil, og føde denne til systemet, der kompilerer den og genererer<br />
bygningerne ud fra parametre, givet enten indirekte eller direkte gennem erklæringer i tekstfilen. I<br />
dette <strong>af</strong>snit vil jeg ikke anføre hele grammaer, men kun give eksempelbider. I bilag 2 medfølger alle<br />
gammaerne diskuteret i dette <strong>af</strong>snit, i deres fulde omfang.<br />
131
6.3.1 Massemodellering<br />
Modellering <strong>af</strong> bygninger i CGA starter med en regelbaseret beskrivelse <strong>af</strong> massemodellen. At<br />
beskrive en bygnings sammensatte struktur via produktionsregler kræver en vis indsigt og øvelse (og<br />
naturligvis en vis portion kreativitet). Derfor vil jeg her give eksempler på hvordan systemets store<br />
udtryksfuldhed kan udnyttes.<br />
Figur 137: Petronas tvillingetårnene i Kuala Lumpur i Malaysia. Et <strong>af</strong> verdens højeste bygningsværker.<br />
Det første eksempel er en beskrivelse <strong>af</strong> Petronas Towers, der er et tvilling-højhusbyggeri i Malaysia,<br />
og er blandt verdens højeste bygninger. Eksemplet er beskrevet i [Müller, 2006], og er her udtrykt<br />
gennem i min implementering <strong>af</strong> systemet.<br />
Hvis man betragter grundplanet for disse tårne, opdager vi en bemærkelsesværdig geometrisk<br />
struktur:<br />
132
Grundplanet består <strong>af</strong> to kvadrater, hvor det ene er roteret med 45 o i forhold til det andet. Ved alle<br />
skæringer mellem kvadraterne er der indsat en cirkel. Dette grundplan er let beskrevet via simple<br />
produktionsregler, og kan ekstruderes til et segment i Petronas tårnene. Herefter kan en rekursiv<br />
proces bygge de overliggende og stadigt indsnævrede segmenter, der tilsammen udgør hele<br />
bygningen. Resultatet ses her:<br />
Figur 138: Petronas Towers modelleret via min implementering <strong>af</strong> CGA (renderet i blender).<br />
Hvert <strong>af</strong> tårnene indeholder 140.000 polygoner og genereringen tog ca. 115 millisekunder. Da tårnene<br />
er proceduralgenererede via produktionsregler, kan de reguleres <strong>af</strong> parametre. I dette tilfælde kan<br />
modellen styres via højden og de indbyrdes proportioner og indsnævringer mellem sektionerne:<br />
133
Figur 139: Variationer over Petronas Towers ved brug <strong>af</strong> tre forskellige parametre. (renderet i blender)<br />
Bemærk at højden ikke blot er en skalering, men også har indflydelse antallet <strong>af</strong> etager, antallet <strong>af</strong><br />
sektioner og de indbyrdes proportioner imellem disse.<br />
Det ovenstående eksempel demonstrerer variation opnået ved hjælp <strong>af</strong> parametre. For træer<br />
genereret med L-systemer er det muligt også, at opnå strukturel variation (stokastiske L-systemr).<br />
Strukturel variation kan også bygges ind i CGA-grammaer. I det følgende eksempel vil jeg give et<br />
eksempel på modellering <strong>af</strong> en proceduralgenereret bygning, med en vis grad <strong>af</strong> stokastisk strukturel<br />
variation.<br />
I artiklen der introducerer CGA, er der særligt fokus på modellering <strong>af</strong> typiske moderne højhuse<br />
(sandsynligvis pga. problemerne med modellering <strong>af</strong> tage i f.eks. villaer). I det følgende eksempel har<br />
jeg taget udgangspunkt i Sears Tower, der er en skyskraber i Chicago:<br />
134
Figur 140: Sears Tower i Chicago i USA.<br />
Inspirationen til modelleringen har jeg fundet i følgende skitse over bygningens grundlæggende<br />
arkitektur:<br />
Figur 141: Skitse der beskriver grundplanen i Sears Tower i forskellige etagehøjder.<br />
Som det fremgår, er bygningen inddelt i 9 kvadratiske søjler. Disse søjler har forskellige højder, men<br />
generelt er hjørnesøjlerne lavere end de andre. Nu er spørgsmålet, hvordan beskrives dette forhold i<br />
en CGA-grammar? Min idé er at inddele bygningen i en midtersøjle og parvist forbundene ydersøjler:<br />
135
Figur 142: Inddeling <strong>af</strong> grundplanen i Sears Tower i søjler: 1 centersøjle (5), 4 hjørnesøjler (1, 3, 7 og 9) samt fire<br />
sidesøjler (2, 4, 6 og 8). Sider og hjørner er forbundene parvis (1 – 4, 2 – 3, 7 – 8 og 6 – 9).<br />
Vi kan nu vælge højderne <strong>af</strong> søjlerne stokastisk, og samtidig indføre en simpel begrænsning der<br />
bestemmer, at en hjørnesøjle altid er kortere end dens tilknyttede sidesøjle. Dette giver følgende<br />
resultat:<br />
Figur 143: Sears Tower, modelleret via min implementering <strong>af</strong> CGA (renderet i blender).<br />
Som det fremgår, kan sidesøjlerne være lige så høje eller lavere end midtersøjlen. Dette giver en<br />
opadstræbende struktur med midtersøjlen som et naturligt topspir. Tårnet indeholder 627 polygoner<br />
(facaden er i dette tilfælde blot tekstureret) og genereringen tager ca. 45 millisekunder. Udover<br />
136
muligheden for parametrisk variation, er der for denne bygnings vedkommende også mulighed for<br />
strukturel variation:<br />
Figur 144: Parametriske og strukturelle variationer over Sears Tower (renderet i blender).<br />
Bemærk hvordan søjlerne kan have indbyrdes forskellige højderelationer og, at forskellige sidesøjler<br />
når hele vejen til toppen, samtidig med at bygningen beholder sin overordnede arkitektoniske<br />
udformning.<br />
6.3.2 Anvendelse <strong>af</strong> GIS data<br />
For at kunne rendere hele <strong>bymiljøer</strong> er der behov for at kunne håndtere GIS-data, hvad end dette<br />
måtte være data for eksisterende byer, syntetiseret data eller modelleret data. I forbindelse med min<br />
prototype har jeg derfor bygget et simpelt system, hvori det er muligt for brugeren at importere et<br />
kort, skitsere parcellerne og angive parametre til disse:<br />
137
Figur 145: Skærm-dump fra GIS-applikation.<br />
Herefter kan dette data trækkes ind i CGA-systemet der modellere en bygning for hver parcel med<br />
udgangspunkt i de angivende parametre:<br />
Figur 146: Bymiljø modelleret i CGA og visualiseret i min reder-engine.<br />
138
De ovenstående bygninger er modelleret med samme fremgangsmåde, som den der præsenteres i<br />
[Müller, Wonka, Haegler, Ulmer, & Van Gool, 2006]. Grammaren består <strong>af</strong> kun 5 produktionsregler.<br />
Processen starter ved at ekstrudere parcellen til en massiv figur. Parcellen kan være et arbitrært<br />
polygon. Herefter underinddeles figuren, hvorved der kan skabes sidefløje og dermed I, L og U<br />
formede bygninger.<br />
6.3.3 Facademodellering<br />
Det forrige eksempel er ikke videre tiltalende idet facaderne mangler. Til modelleringen <strong>af</strong><br />
højhusbyggerier har jeg 4 forskellige grundfacadetyper, der vælges stokastisk for hver bygning:<br />
Figur 147: De 4 forskellige grundfacadetyper.<br />
For hver <strong>af</strong> facaderne er der en række parametre der styrer facadens udformning. Det følgende<br />
eksempel viser effekten ændring <strong>af</strong> vinduesbredde og mellemrummet mellem vinduer for den<br />
samme grundtype:<br />
Figur 148: Samme grundfacade med forskellige vinduesbredder.<br />
Som det fremgår virker facaderne væsentligt forskellige, til trods for at de grundlæggende er ens. Ved<br />
at vælge facadetypen stokastisk, samtidig med at vi også vælger facadeparametrene stokastisk, er det<br />
muligt at opnå en meget høj grad <strong>af</strong> variation i bymiljøet. Hundredvis <strong>af</strong> bygninger kan genereres<br />
uden, at byen virker ensformig. Denne variation ville ikke være mulig uden kombinationen <strong>af</strong><br />
parametre og udvalget <strong>af</strong> facader. De følgende billeder viser byen i Figur 146, men denne gang med<br />
stokastiske facader:<br />
139
Figur 149: Proceduralmodelleret bymiljø. (renderet i blender)<br />
140
Figur 150: Proceduralmodelleret bymiljø. (renderet i blender)<br />
Byen indeholder over 855.000 polygoner og genereringen tog ca. 8 sekunder. Tagene har typiske<br />
moderne installationer der er formet <strong>af</strong> bygningens øverste polygoner, der er indsnævrede ved en<br />
indsnævrings funktion og efterfølgende ekstruderet til en stokastisk valgt højde. I det følgende<br />
billede kan detaljegraden observeres fra gadeplan:<br />
141
Figur 151: Proceduralmodelleret bymiljø, set fra gadeplan. (rederet i blender)<br />
I det ovenstående tilfælde er GIS-dataen tegnet ovenpå et eksisterende vejnet fra det centrale San<br />
Francisco. Det er naturligvis også muligt at benytte ikke-eksisterende eller syntetiserede vejnet, og i<br />
det følgende eksempel har jeg f.eks. anvendt DTU’s logo som udgangspunkt:<br />
142
Figur 152: Gis data, tegnet med udgangspunkt i DTU's logo.<br />
143
Figur 153: Bymodel genereret over DTU's logo.<br />
Scenen indeholder ca. 1 million polygoner, og genereringen tog omkrng 15 sekunder.<br />
I min implementering mangler jeg at tage højde for occlusion samtidig med, at jeg ikke kan foretage<br />
snapping til betydende linjer i bygningens struktur [Müller, Wonka, Haegler, Ulmer, & Van Gool,<br />
2006] (se også side 61). I de ovenstående billeder er dette problem knapt synligt, og da der her blot er<br />
tale om en prototype, påvirker det efter min mening ikke indtrykket <strong>af</strong> systemets overordnede<br />
potentiale.<br />
I de næste eksempler vil jeg gå mere i dybden med detaljeringen <strong>af</strong> de enkelte elementer i facaden.<br />
6.3.4 Den lagdelte tagmodel i CGA<br />
Mit hovedbidrag til metoden er indførelsen <strong>af</strong> den parametriske lagdelte tagmodel i CGA shapegrammar.<br />
Jeg vil nu præsentere resultaterne for dette arbejde.<br />
For højhusbyggerier er de parametriske tage sjældent relevante, men for enfamiliehuse er tagene<br />
alt<strong>af</strong>gørende. Jeg har derfor valgt at bygge en grammar for en typisk større villa eller palæ. I dette<br />
tilfælde er husene altid enten 1 eller 2 etager, og består <strong>af</strong> et større centerstykke, hvorfra der er<br />
mulighed for mindre længer i hvert hjørne. Jeg har forsøgt, at inkorporere en større grad <strong>af</strong><br />
detaljering i facadernes arkitektur, hvilket indkluderer: hjørnesøjler, sokkel, gesims,<br />
dannebrogsvinduer, trappe for døren, altan og vindue over døren. For alle detaljers vedkommende<br />
gælder det, at de er en del <strong>af</strong> grammaren og dermed parametriske:<br />
144
Figur 154: Proceduralmodelleret villa. (rederet i blender)<br />
Huset indeholder ca. 20.000 polygoner, genereringen tog 470 millisekunder og grammaren<br />
indeholder 33 produktionsregler og kan findes i fuld udgave i bilag 2.<br />
I grammaren vælges der stokastisk mellem 5 forskellige tage: Mansardtag med 80 og 20 graders<br />
hældning (øvre og nedre), saddeltag med stokastisk hældning mellem 10 og 50 grader, valmet tag<br />
med 30 graders hældning, valmet tag med 40 graders hældning og til sidst 1 /3-valm i 45 grader.<br />
Dette opnås ved følgende stokastiske produktionsregel:<br />
p31: roofTier -> Roof("roofEdge", "mansard", 80, 30, 2, "halfHip", 2, 45)<br />
{roof | gable} : 0.25;<br />
p31: roofTier -> Roof("roofEdge", "sloped", rSlope, "gable")<br />
{roof | gable} : 0.25;<br />
p31: roofTier -> Roof("roofEdge", "sloped", 30, "hip", 30)<br />
{roof | gable} : 0.125;<br />
p31: roofTier -> Roof("roofEdge", "sloped", 40, "hip", 40)<br />
{roof | gable} : 0.125;<br />
p31: roofTier -> Roof("roofEdge", "sloped", 45, "halfHip", *0.66, 45)<br />
{roof | gable} : 0.25;<br />
Hvert <strong>af</strong> tilfældende vælges med hhv. 25%, 25%, 12,5%, 12,5% og 25% chance. Bemærk hvordan den<br />
sidste tagtype opnår en proportionel valm ved at benytte relativ syntaksen (’*’), kendt fra splitmakroen.<br />
145
Her følger et udvalg <strong>af</strong> nogle <strong>af</strong> de forskellige hustyper der er mulige med grammaren:<br />
Figur 155: Udvalg <strong>af</strong> proceduralgenererede villaer. (renderet i blender)<br />
Det er muligt at bringe husene ind i deres rette omgivelser ved at benytte de træer jeg har genereret<br />
via L-systemerne:<br />
Figur 156: Villahus med omgivende have (rederet i blender).<br />
146
I det ovenstående billede er huset og træerne proceduralmodellerede, mens vejene, verandaen,<br />
stakittet og havens komposition er modelleret manuelt.<br />
En vigtig observation for tagenes vedkommende er, at de medvirker til at øge variationen imellem<br />
husene. For kontorbygningernes vedkommende måtte jeg modellere 4 forskellige facadetyper, og<br />
variere disse med stokastiske parametre. For villaerne kan jeg blot skifte tagtyper, og husene får et<br />
markant anderledes arkitektonisk præg. Det følgende eksempel skal illustrere variationen i den<br />
samme grammar, men med stokastisk valgte tagtyper, og varierende facadematerialer. Alle andre<br />
parametre er ens (f.eks. vinduesbredde, vindueshøjde og etagehøjder):<br />
Figur 157: Variation i tage medvirker til overordnet variation i billedet (renderet i blender).<br />
Medvirken til øget mulighed for variation er en <strong>af</strong> de helt store fordele ved en metode, der kan<br />
håndtere mere end blot valmet tag og saddeltag. Hver <strong>af</strong> scenerne ovenfor indeholder mellem 70 og<br />
80 tusinde polygoner.<br />
Til trods for den høje detaljegrad forventer jeg ikke, at en gr<strong>af</strong>iker vil være fuldt tilfreds med<br />
resultatet i alle tilfælde. Derfor er det <strong>af</strong>gørende, at der er mulighed for efterfølgende at forskønne<br />
147
modellen i et traditionelt modelleringsværktøj. I det følgende eksempel har jeg selv forsøgt mig som<br />
modellør:<br />
Figur 158: Proceduralmodelleret bygning, der efterfølgende er redigeret i blender (også renderet i blender).<br />
Her har jeg, udover modellering <strong>af</strong> haven, indsat potteplanter, møbler og en skorsten med røg. Vasen<br />
og bænken er fra turbosquid 3 . Derudover har jeg givet taget en tekstur samt et normal-map, hvis<br />
position er baserede på uv-koordinater beregnet i min implementering <strong>af</strong> CGA.<br />
Jeg vil til slut oplyse om en kendt fejl i systemet. Fejlen opstår når en bygnings grundplan bringes fra<br />
CGA-systemet over i tagmodelleringssystemet. I min implementering <strong>af</strong> CGA arbejder jeg i 32-bits<br />
præcision, mens jeg arbejder i 64-bits præcision under tagmodelleringen. Denne lavere præcision<br />
kan i nogle tilfælde føre til fejlagtigt konstruerede tage. Problemet kan og bør løses ved at anvende<br />
64-bits præcision gennem hele systemet.<br />
3 http://www.turbosquid.com/<br />
148
7 Diskussion<br />
I dette <strong>af</strong>snit vil jeg gennemgå mine resultater og diskutere deres betydning og perspektiver.<br />
7.1 Overblik<br />
Jeg har i dette projekt implementeret et system der kan parse og evaluere CGA-shape-grammaer. Mit<br />
bidrag har først og fremmest været en model for fleksibel modellering <strong>af</strong> tage. Metoden tager<br />
udgangspunkt i et straight skeleton for bygningens grundplan, og bygger en model ved at klippe<br />
tagfladernes polygoner indbyrdes. Hver tagflade lagdeles, hvilket muliggør meget varierede tagtyper.<br />
Metoden kan parametriseres ud fra en simplificeret betragtning over de mest almindelige tagtyper,<br />
ved at antage at taget er bygget op <strong>af</strong> gavle og tagsider. Dermed har jeg været i stand til at indføre<br />
tagene i CGA, i en simpel og koncis syntaks.<br />
Det har været <strong>af</strong> <strong>af</strong>gørende vigtighed for mig, at det, for både L-systemer og CGA-grammaer, er<br />
muligt for brugeren at benytte sig <strong>af</strong> en notation der er meget lig den der er givet i hhv.<br />
[Lindenmayer & Prusinkiewicz, 1996] og [Müller, Wonka, Haegler, Ulmer, & Van Gool, 2006]. Jeg har<br />
set eksempler på systemer hvor grammarene skrives direkte i almindelige programmeringssprog eller<br />
i XML-filer. Det er selvfølgelig implementeringsmæssigt nemmere, men det besværliggør brugen <strong>af</strong><br />
systemet, og gør udforskningen og <strong>af</strong>prøvning <strong>af</strong> systemernes muligheder langsommelig og<br />
vanskelig.<br />
I mine systemer har man en klar og koncis syntaks, der gør arbejdet med grammaerne meget mere<br />
intuitiv og ligetil. Hvis man har arbejdet med grammaer tidligere, vil man have let ved at tage disse<br />
systemer i anvendelse. For en brugers synspunkt er det en fordel, at kunne udtrykke sig direkte i<br />
grammaren og ikke indirekte gennem andre ubeslægtede programmeringssprog.<br />
Et vigtigt formål med dette projekt har været at finde en metode der er i stand til at modellere de<br />
mest almindelige tage. Specifikt har det været et mål at modellere tagene nævnt i Tabel 1. Med<br />
henvisning til resultat<strong>af</strong>snittet mener jeg, at man med rimelighed kan sige at dette mål er nået. Jeg<br />
vil, igen med reference til resultat<strong>af</strong>snittet, ydermere argumentere for, at metoden går videre end<br />
dette, da den er yderst fleksibel og frem for alt generisk i forhold til inputparametre. Man kan altså<br />
føde et arbitrært grundplan til algoritmen, og få systemets kvalificerede gæt på hvordan en given<br />
tagtype vil være udformet.<br />
I <strong>af</strong>snit 4 (Observationer, analyse og hypotese) gav jeg en grundig diskussion <strong>af</strong> den eksisterende<br />
litteratur og de eksisterende metoder. Konklusionen var, at systemer baseret på shape-grammaer er<br />
klart overlegene. I forhold til de andre metoder er shape-grammaer og især CGA-grammaren mere<br />
strukturerede når det gælder definering <strong>af</strong> bygningers ensartede konstruktion og deres indbyrdes<br />
sammenlignelighed, hvilket jeg vil tilskrive metodens arkitektoniske ophav. Jeg forudser, at shapegrammaer<br />
på sigt vil blive anvendt til modellering <strong>af</strong> bygninger, i samme omfang som f.eks. Lsystemer<br />
i dag bliver anvendt til modellering <strong>af</strong> planter og træer.<br />
Modelleringen <strong>af</strong> kirken der blev gennemgået i resultat<strong>af</strong>snittet (side 129) viser metodens<br />
fleksibilitet, og samtidig også i høj grad dens robusthed. Umiddelbart kunne man forledes til at tro,<br />
at tagmodelleringsmetoden dermed kan benyttes til generel modellering <strong>af</strong> bygninger (altså ikke<br />
bare tage). Dette må dog frarådes, da det for langt de færreste bygninger ikke er en triviel opgave at<br />
149
specificere det overordnede udseende, udelukkende ud fra grundplanet. Empire State Building i New<br />
York har f.eks. et kvadratisk grundplan, hvorfra det er umuligt at beskrive alle detaljer for hele<br />
bygningens struktur. Det ovenstående eksempel på modellering <strong>af</strong> en kirke skal udelukkende tjene<br />
som bevis for metodens alsidighed.<br />
Når man vurderer den visuelle fremtoning <strong>af</strong> mine resultater, må man tage i betragtning, at jeg ikke<br />
er gr<strong>af</strong>iker eller modellør. Når det er sagt, vil jeg gerne fremhæve netop den side <strong>af</strong> systemet. CGAsystemets<br />
evne til modellering <strong>af</strong> detaljerede facader, beskrivelse <strong>af</strong> vigtige overordnede design mål<br />
og proportionering <strong>af</strong> facadeelementer er uovertruffen.<br />
I eksemplet med modellering <strong>af</strong> et bymiljø, på baggrund <strong>af</strong> DTU’s logo, blev der skabt en model med<br />
over 1 million polygoner. Man kan diskutere om detaljegraden, i dette tilfælde 1 million polygoner for<br />
et helt bymiljø, lever op til dagens krav til computergr<strong>af</strong>iske scener. Jeg er på ingen måde gr<strong>af</strong>iker, og<br />
mine evner for modelleringsopgaver er således begrænsede. Derfor vil jeg argumentere for, at<br />
systemet i hænderne på en gr<strong>af</strong>iker vil kunne præstere meget bedre resultater. Systemet gør netop<br />
ikke en amatør til gr<strong>af</strong>iker, men hjælper gr<strong>af</strong>ikeren til højere produktivitet. I den forbindelse vil jeg<br />
henvise til hjemmesiden for City Engine 4 , der præsenterer overordentligt flotte resultater med et<br />
system magen til dette.<br />
En anden grund til den forholdsvis begrænsede detaljegrad er, at jeg har undladt at implementere en<br />
importfunktion i mit system. Nogle opgaver, f.eks. vinduer, egner sig bedre til traditionelle<br />
modelleringsværktøjer. Hvis det var muligt at importere højdetaljerede vinduesmodeller direkte ind i<br />
grammaren, der herefter kunne placere disse på facaden, ville en meget høj detaljeringsgrad lettere<br />
kunne opnås.<br />
4 http://www.procedural.com<br />
150
Figur 159: Villa modelleret med CGA-shape-grammar.<br />
Jeg har fået en række positive kommentarer fra kollegaer og gr<strong>af</strong>ikere i forbindelse med mit arbejde.<br />
Især gr<strong>af</strong>ikerne er dog bekymrede over den noget statisk udseende scene for højhusene. Jeg vil i<br />
nogen grad give dem ret, og det er klart at resultatet ikke kan anvendes direkte i en eventuel<br />
produktion. Dertil er kvaliteten for lav. Pointen er igen, at jeg ikke er modellør eller gr<strong>af</strong>iker, og i<br />
hænderne på en dygtig modellør er jeg overbevist om, at resultaterne kan forbedres drastisk.<br />
Derudover er der intet i vejen for, at bruge modellen som udgangspunkt for videre arbejde i et<br />
modelleringssystem. Noget så simpelt som variation <strong>af</strong> f.eks. facadefarven for de forskellige<br />
bygninger vil formodentlig gøre underværker, og samtidig fjerne noget <strong>af</strong> det statiske præg over<br />
scenen.<br />
Jeg har i dette projekt ikke foretaget undersøgelser <strong>af</strong> metodens effektivitet som gr<strong>af</strong>isk værktøj. En<br />
sådan test ville indebære oplæring <strong>af</strong> en gr<strong>af</strong>iker, og derefter analyse <strong>af</strong> dennes arbejde med<br />
metoden. Her vil jeg referere til en lignende undersøgelse i [Müller, Wonka, Haegler, Ulmer, & Van<br />
Gool, 2006]. Jeg vil dog bemærke, at det har været muligt for undertegnede at producere forholdsvis<br />
komplekse, og efter min mening rimeligt overbevisende modeller. Modeller, der pga. deres omfang<br />
og detaljeringsgrad, ville være umulige for mig at producere inden for en fornuftig tidsramme med<br />
almindelige modelleringsværktøjer. Samtidig vil jeg hævde, at det faktum, at kun 4 forskellige<br />
grundfacadetyper, var tilstrækkeligt til at opnå et forholdsvis varieret bymiljø, peger på en høj<br />
effektivitet.<br />
151
En vigtig pointe i forbindelse med proceduralmodellering er evnen til at skabe variation i scenen.<br />
Igennem denne rapport har jeg argumenteret for at tage har stor indflydelse på en bygnings<br />
overordnede arkitektoniske udtryk. Dette er selvfølgelig en subjektiv vurdering, men jeg mener, at<br />
jeg med baggrund i resultaterne præsenteret i <strong>af</strong>snit 6.3.4 kan begrunde denne påstand.<br />
Konklusionen må derfor være, at indførelsen <strong>af</strong> parametriske tage har givet bedre muligheder for<br />
variation <strong>af</strong> bygningerne, hvilket er et uvurderligt værktøj for gr<strong>af</strong>ikere.<br />
I min parametriske tagmodel har jeg valgt at arbejde med to forskellige sidetyper: gavl og almindelig<br />
side. Dette valg har været baseret på den naturlige analogi til den almindelige differentiering mellem<br />
gavle og sider. Det er lettere for uøvede, at forholde sig til hvordan netop taget og gavlene er<br />
udformet, i stedet for et urelateret antal sidetyper deriblandt gavlen. Problemet er, at dette er en<br />
begrænsning <strong>af</strong> udtryksfuldheden for tagmodellen. Det er klart at brugeren ikke bør tage stilling til<br />
alle tagfladerne individuelt, men det bør overvejes om tallet 2 er det mest optimale antal. I eksemplet<br />
med kirken demonstrerede jeg hvordan det er muligt at modellere meget avancerede tagtyper, ved<br />
brug <strong>af</strong> 3 forskellige opstalter. Efterhånden som jeg har fået mere erfaring med systemet hælder jeg<br />
til at tallet 3 nok er mere passende.<br />
Dette projekt dækker bredt, og den samlede mængde <strong>af</strong> kildekode er derfor tilsvarende omfattende.<br />
Især implementeringen <strong>af</strong> CGA-systemet har indebåret en betydelig arbejdsindsats. Dette skyldes i<br />
nogen grad systemets karakter og spændvidde, men det peger samtidigt også på teknologiens<br />
modenhed. Dette <strong>af</strong>spejles således i det faktum, at industrien har taget den kommercielle<br />
implementering <strong>af</strong> CityEngine i brug.<br />
7.2 Anvendelsesmuligheder<br />
For at kunne bedømme anvendelsesmulighederne <strong>af</strong> min metode, må man se den i sammenhæng<br />
med CGA systemet. Mit bidrag skal i den forbindelse anskues som en enkel men vigtig forbedring <strong>af</strong><br />
den allerede eksisterende metode.<br />
7.2.1 Brugerscenarie<br />
Den primære brugergruppe for proceduralmodellering <strong>af</strong> bygninger, er gr<strong>af</strong>ikere.<br />
Gr<strong>af</strong>ikeren starter med at modellere vinduer, døre og andre detaljeobjekter i almindelige<br />
modelleringsværktøjer. Her er der tale om en <strong>af</strong>vejning mellem, hvorvidt man ønsker<br />
parameteriserede eller blot skalerbare detaljer. I nogle situationer er det måske ønskeligt, at<br />
modellere f.eks. vinduer i selve grammaren hvorved bl.a. antallet <strong>af</strong> vinduesfag kan gøres <strong>af</strong>hængig <strong>af</strong><br />
vinduets bredde. I andre situationer, hvor man f.eks. ved at vinduerne alle har samme størrelse, kan<br />
man benytte modelleringsværktøjer og dermed opnå detaljer der ikke er mulige gennem grammaer.<br />
Modelløren kan nu skrive grammaer for det antal forskellige arketyper <strong>af</strong> bygninger, han måtte finde<br />
passende. Processen består i at modellere bygningens form, beklæde den med facader og til sidst<br />
vælge tagformen. Herefter angives hvilke parametre der skal være genstand for tilfældighed, samt<br />
udfaldsrummet for disse. Her er det nødvendigt at være påpasselig, så man ikke risikerer<br />
uhensigtsmæssigheder i grænsetilfælde. Selve modelleringsprocessen involverer opsætning <strong>af</strong> regler<br />
for bygningens udformning, hvilket igen bygger på en analyse <strong>af</strong> bygningens design.<br />
152
Efterfølgende designes et vejnet sammen med GIS-data for de enkelte matrikler, og parametre for de<br />
enkelte bygninger angives. Dette fødes til systemet, der genererer modellen. Denne model kan til<br />
sidst hentes ind i et modelleringsværktøj, og forfines i mere eller mindre grad via traditionelle<br />
metoder.<br />
Jeg har indtil nu ikke diskuteret hvordan kviste og tagvinduer håndteres i systemet. Det er generelt<br />
ikke muligt at beskrive kviste ud fra husets grundplan. Som sagt eksisterer tagfladerne i grammaren<br />
efter tagets konstruktion, og det er derfor muligt at arbejde videre med tagfladen på samme måde<br />
som med alle andre facader. Derfor må kviste betragtes som komponenter i tagfladen, meget lig<br />
måden vinduer i håndteres i facader.<br />
7.2.2 Perspektiv<br />
Som sagt forventer jeg at proceduralmodellering <strong>af</strong> <strong>bymiljøer</strong> vil spille en stor rolle i industrien<br />
fremover. Der findes allerede en kommerciel implementering <strong>af</strong> CGA (City Engine 5 ), der især finder<br />
anvendelse i spilindustrien. For mange computerspil spiller byen en meget vigtig rolle, og det er<br />
forbundet med store omkostninger for spiludviklere at realisere disse byer.<br />
I baggrunds<strong>af</strong>snittet belyste jeg hvordan udviklingen i omkostninger for udvikling <strong>af</strong> visuelt indhold,<br />
spiller en stadigt større rolle i budgetterne for computerspil. Derfor er produkter såsom det<br />
ovennævnte attraktive. Man kan betragte det som et mere effektivt værktøj til produktion <strong>af</strong><br />
bymodeller set i forhold til traditionelle modelleringsværktøjer. Det er på den måde muligt at<br />
mindske omkostningerne for udvikling <strong>af</strong> spil, eller hæve detaljegraden i bymodellen yderligere. Jeg<br />
vil mene at uanset spilindustriens økonomiske tilstand, vil det altid være oplagt for producenter at<br />
foretage effektiviseringer i arbejdsgangene.<br />
På længere sigt kan man forestille sig proceduralmodellering <strong>af</strong> <strong>bymiljøer</strong> anvendt til stokastisk<br />
generering <strong>af</strong> spil-verdner. Dette kan være som del <strong>af</strong> uendeligt store miljøer, eller som<br />
udgangspunkt for et element <strong>af</strong> opdagelse i ukendte verdner der forlænger spiloplevelsen hos<br />
slutbrugeren. Der kan på samme måde også være tale om proceduralmodellering som et egentligt<br />
gameplay-element, som det er set i spillet spore fra EA-games. I den forbindelse kan man f.eks.<br />
forestille sig systemet anvendt i en SimCity lignende simulator. Her kan proceduralmodellering<br />
hjælpe med til, at undgå nøjagtigt ens bygninger der indsættes flere steder i samme by, eller <strong>af</strong>hjælpe<br />
begrænsninger der kun giver mulighed for retvinklede parceller.<br />
Udover spilindustrien kan man forestille sig, at filmindustrien vil kunne få gavn <strong>af</strong> metoden. Her er<br />
kvalitetskravene noget højere, og teknologien skal sandsynligvis forbedres og modnes før man for<br />
alvor vil se metoden blive taget i anvendelse.<br />
Jeg forestiller mig også at byggebranchen og bygningsadministratorer vil kunne anvende værktøjer<br />
der er baserede på metoden. Her tænker jeg især på visualisering <strong>af</strong> GIS-data. Hvis man f.eks. vil<br />
vurdere en projekteret bygnings visuelle indvirkning på omgivelserne, bruger man ofte<br />
computergererede <strong>bymiljøer</strong>. Her er der for det meste tale om geometri, der er ekstruderet direkte<br />
fra GIS-data. I nogle tilfælde er facaderne beklædt med facadetekstur.<br />
5 http://www.procedural.com/<br />
153
Figur 160: Visualisering <strong>af</strong> GIS-data fra Århus. Bemærk hvordan nogle facader er beklædt med tekstur, mens<br />
andre er “nøgne”.<br />
Arbejdet med at indsamle facade-fotos, og rette dem til på figuren kan være omfattende, især hvis<br />
der lægges vægt på kvaliteten. I mange tilfælde vil man med fordel kunne benytte<br />
proceduralgenererede facader på disse bygninger. Her kunne man bygge et sæt <strong>af</strong> typiske<br />
facadetyper, der passer i de konkrete omgivelser, og anvende disse på de enkelte bygninger. Det vil<br />
naturligvis ikke blive en nøjagtig gengivelse, men for en stor del <strong>af</strong> bygningsmassen, vil det ikke<br />
spille en <strong>af</strong>gørende rolle.<br />
7.2.3 Anvendelse <strong>af</strong> tagmodellen<br />
For selve tagmodellen er der udsigt til en mulig snarlig anvendelse i systemer til beregning <strong>af</strong><br />
varmetabet for bygninger. Her er brugergruppen helt almindelige privatpersoner, og der lægges<br />
således vægt på brugervenlighed. Man kan derfor ikke forvente at folk skal modellere deres hjem i 3d<br />
via de sædvanlige modelleringsmetoder, og det er netop i den forbindelse at tagmodellen bliver<br />
relevant.<br />
Ideen er at brugeren først indtaster sin adresse. Herefter kan vi slå bygningen op i Kort og<br />
Matrikelstyrelsens database, hvorfra det er muligt at hente grundplanet som geometrisk polygon.<br />
Det er samtidig muligt at finde information om højden og antallet <strong>af</strong> etager i bygningen, og det er<br />
derfor ligetil at ekstrudere bygningen og få dens massemodel. Herefter bliver brugeren præsenteret<br />
for en række tagtyper. Brugeren vælger den der passer bedst, og angiver tagets parametre (såsom<br />
hældninger). Det eneste der mangler er at brugeren angiver materialetype og indsætter vinduer og<br />
døre. Herefter har man en komplet klimaskærm, hvormed systemet kan fortage varmeberegninger<br />
og give anbefalinger.<br />
Uden en generisk tagmodel har man ikke mulighed for at anvende bygninger fra en GIS-database, da<br />
disse kan have alle slags ukurante former.<br />
154
7.2.4 Proceduralgenerering<br />
Anvendelsen <strong>af</strong> proceduralgenerering i industrien bliver stadig mere udbredt. Ikke bare træer og<br />
huse, men også f.eks. animationer, personer, ansigter eller ansigtsmimik. Generelt kan man sige, at<br />
proceduralgenerering kan anvendes på alle områder, hvor de individuelle modeller deler<br />
overordnede træk med hinanden. Træk der kan kodificeres i enten implicitte eller eksplicitte regler.<br />
Den urolige gr<strong>af</strong>iker vil måske spørge sig selv: ”bliver jeg nu erstattet <strong>af</strong> maskiner?”. Hertil er svaret<br />
klart nej. Det er stadig gr<strong>af</strong>ikeren der har den overordnede vision for det gr<strong>af</strong>iske udtryk.<br />
<strong>Proceduralmodellering</strong> er blot et værktøj for gr<strong>af</strong>ikeren, hvormed denne kan udtrykke sin vision.<br />
Man kan måske også spørge, vil højere effektivitet føre til fyringer blandt gr<strong>af</strong>ikere? Er ingeniørerne<br />
ude på at gøre gr<strong>af</strong>ikerne arbejdsløse? I dette tilfælde er svaret selvfølgelig op til de ledende<br />
spiludviklere, men spilmarkedet er i den grad et konkurrencepræget marked, og der bliver især<br />
konkurreret på imponerende gr<strong>af</strong>ik. Derfor vil frigjorte ressourcer sandsynligvis blive anvendt andre<br />
steder i produktionen <strong>af</strong> det gr<strong>af</strong>iske indhold, eller måske på en større mangfoldighed <strong>af</strong> udgivelser.<br />
7.3 Fremtidigt arbejde<br />
Den foreløbige implementering er blot en prototype. Især brugerfladen er præget <strong>af</strong> at være en<br />
testbænk for selve udviklingen. Derudover mangler jeg en at implementere en række funktioner fra<br />
CGA, heriblandt occlusion-forespørgsler og indsættelse snapping-linjer (hhv. fjernelse <strong>af</strong> usynlige<br />
facadeelementer og indsættelse <strong>af</strong> snapping-linjer, der kan insereres <strong>af</strong> andre regler (se side 61)). Jeg<br />
har måttet udelade disse dele, da jeg har prioriteret implementeringen <strong>af</strong> min egen metode i<br />
systemet. Arbejdet i [Müller, Wonka, Haegler, Ulmer, & Van Gool, 2006] og implementeringen i<br />
CityEngine er resultatet <strong>af</strong> flere års arbejde i forskningsgrupper og i kommercielt øjemed.<br />
Virksomheden bag har fuldtidsudviklere, der arbejder på at forfine systemet. Dette kan jeg ikke<br />
umiddelbart hamle op med, og derfor har jeg valgt, kun at implementere de mest basale funktioner i<br />
systemet. Prototypen skal således blot muliggøre min implementering <strong>af</strong> tagmodelleringsmetoden,<br />
og demonstrere hvordan denne kan anvendes.<br />
Hvis dette system skal bringes i anvendelse er det nødvendigt med en gr<strong>af</strong>isk brugerflade. Til trods<br />
for at jeg benytter mig <strong>af</strong> en grammar syntaks, kan man ikke forvente at ikke-programmeringskyndige<br />
vil kunne gøre brug <strong>af</strong> dette. Man kan groft sagt sige at der er tale om et slags scriptingsprog,<br />
og indlæringskurven er i det perspektiv lig alle andre scripting-sprog [Müller, Wonka,<br />
Haegler, Ulmer, & Van Gool, 2006]. Derfor er det nødvendigt med en visuel editering <strong>af</strong> grammaer.<br />
Her er det oplagt at skele til arbejdet i [Lipp, Wonka, & Wimmer, 2008].<br />
En oplagt kandidat til forbedring <strong>af</strong> systemet er, at kigge på måden gavle vælges. I alle de<br />
brugerscenarier jeg kan forestille mig, ville det være en fordel hvis systemet selv kunne foreslå<br />
placeringen <strong>af</strong> gavle. En idé er, at vælge alle flader der i et straight-skeleton er opstået som følge <strong>af</strong> en<br />
edge-event. Disse flader vil altid være trekantssammenføjninger. Problemet er, at f.eks. en simpel Lformet<br />
bygning kun vil have to gavle, mens man ville forvente at denne har 3 gavle. Jeg foreslår i<br />
stedet en fremgangsmåde der er meget lig den beskrevet i [Laycock & Day, 2003]. Her findes alle<br />
kanter der udgør en rygning i tagmodellen. Disse benyttes som udgangspunkt for at finde en region,<br />
hvor alle kanter i grundplanet der er mere elle mindre vinkelret på rygningen angives som gavle.<br />
155
Et problem der blev identificeret i resultat<strong>af</strong>snittet (6.2.6), omhandler hvordan indsættelse <strong>af</strong><br />
hjælpeplaner håndteres. I min implementering har jeg opsat 3 forskellige kriterier for valg <strong>af</strong><br />
hjælpeplan. Som udgangspunkt er der intet i vejen for at indføre flere kriterier. I den konkrete<br />
problemstilling kan en løsning være at foretage en mere global søgning i grundplanet, hvorved man<br />
vil opdage andre kanter der eventuelt skærer punktet, og hvorfra det nye hjælpeplan kan deduceres.<br />
Arbejdet med stokastiske systemer kan i nogle tilfælde skabe problemer, da man har svært ved at<br />
genskabe specifikke modeller. Derfor bør det være muligt for en designer at låse visse <strong>af</strong> de<br />
stokastiske parametre igennem arbejdsprocessen. Dette underbygger en arbejdsproces hvori det er<br />
muligt at prøve sig frem med forskellige designs.<br />
156
8 Konklusion<br />
I dette projekt er der blevet implementeret en metode til proceduralmodellering <strong>af</strong> bygninger og<br />
<strong>bymiljøer</strong>. Metoden er baseret på de såkaldte shape-grammaer, og giver mulighed for modellering <strong>af</strong><br />
huses massemodel, deres facader og deres tage. Metoden kan tage en simpel form for GIS-data,<br />
hvorved hele <strong>bymiljøer</strong> kan modelleres.<br />
Mit bidrag er en metode til modellering <strong>af</strong> tage, der baserer sig på polygoners straight-skeleton.<br />
Metoden tager som input et sæt <strong>af</strong> opstalter, der beskriver tagets enkelte sider, og benytter husets<br />
grundplan til at opbygge en lagdelt tagmodel. Metoden kan anvendes i sig selv, eller bruges i<br />
forbindelse med proceduralmodellering via shape-grammaer. Dertil har jeg udviklet en shapegrammar<br />
syntaks, hvori det er muligt at beskrive det ønskede tag.<br />
Igennem denne rapport har jeg redegjort for at tage er en betydelig del <strong>af</strong> en bygnings arkitektoniske<br />
fremtoning og dens klimaskærm. Tage er altså vigtige, og hidtidige metoder til<br />
proceduralmodellering har været utilfredsstillende. Jeg mener derfor, at min metode er relevant og<br />
betydningsfuld. Modellering <strong>af</strong> tage har efter min mening været et egentligt problem for de<br />
eksisterende systemer.<br />
I resultat<strong>af</strong>snittet har jeg redegjort for, at metoden er robust og fleksibel. Det er muligt at modellere<br />
et stort udvalg <strong>af</strong> varierende tagtyper. Oven på den fleksible tagmodelleringsmetode har jeg bygget<br />
en forsimplet parametermodel der indskrænker udtryksfuldheden, men samtidig gør metoden<br />
simplere at arbejde med. Dette er <strong>af</strong>gørende for anvendeligheden i forbindelse med<br />
proceduralmodellering. Den forsimplede parametermodel medvirker desuden til, at gøre systemet<br />
lettere tilgængelig for brugere, hvilket bevirker at selve tagmodelleringsmetoden har en bredere vifte<br />
<strong>af</strong> anvendelsesmuligheder, hvilket jeg har belyst i diskussions<strong>af</strong>snittet.<br />
Jeg vil i denne forbindelse særligt fremhæve tagmodelleringmetodens robusthed og fleksibilitet.<br />
Hvis systemet skal bringes i anvendelse <strong>af</strong> en bredere brugerskare, forligger der en del arbejde. Først<br />
og fremmest skal systemet bringes fra en tilstand <strong>af</strong> prototype til et produktionsklart system.<br />
Derefter skal en række centrale elementer fra CGA, der indledningsvist er blevet udeladt,<br />
implementeres, og på længere sigt bør systemet give mulighed for visuel editering <strong>af</strong> regler.<br />
157
9 Bibliogr<strong>af</strong>i<br />
Bemærk at de fleste artikler i denne oversigt kan findes i pdf-format på den medfølgende CD, eller på<br />
adressen: http://www.student.dtu.dk/~s042624/eksamensprojekt/Papers/.<br />
1) Aberinkulas. (3. 8 2009). The Fall and Rise of Game Development Costs. Hentede 19. 2 2010 fra<br />
Gamespot: http://www.gamespot.com/users/Aberinkulas/show_blog_entry.php?topic_id=m-<br />
100-25709882<br />
2) Aichholzer, O., & Aurenhammer, F. (1996). Straight skeleton for General Polygonal Figures in<br />
the Plane.<br />
3) Aichholzer, O., Aurernhammer, F., Alberts, D., & Gärtner, B. (28. 12 1995). A Novel Type of<br />
Skeleton for polygons. Journal of Universal Computer Science vol 1, no. 12 , s. 752-761.<br />
4) Akenine-Möller, T., Haines, E., & Hoffmann, N. (2008). Real-Time Rendering, Third Edition.<br />
Wellesley Massachusetts: A K Peters, Ltd.<br />
5) Andreovich, M. (30. 4 2008). gameindustry.biz. Hentede 19. 2 2010 fra GTA IV: Most<br />
expensive game ever developed?: http://www.gamesindustry.biz/articles/gta-iv-mostexpensive-game-ever-developed<br />
6) Bélanger, D. (2000). Hentede 9. 2 2010 fra Designing Roofs of Buildings:<br />
http://www.sable.mcgill.ca/~dbelan2/roofs/roofs.html#ss<br />
7) bobvila. (2010). Roof Terms and Terminology. Hentede 5. 2 2010 fra bobvila.com:<br />
http://www.bobvila.com/HowTo_Library/Roof_Terms_and_Terminology-Miscellaneous-<br />
A1936.html<br />
8) Bourke, P. (1 2000). Perlin Noise And Turbulence. Hentede 17. 2 2010 fra<br />
http://local.wasp.uwa.edu.au/~pbourke/texture_colour/perlin/<br />
9) Brenner, C. (2000). Towards fully automatic generation of city models. IAPRS, Vol XXXIII,<br />
Amsterdam , s. 85-92.<br />
10) Bærentzen, J. A., Anton, F., Gravesen, J., & Aanæs, H. (2006). Computational Geometry<br />
Processing. Lyngby: <strong>Danmarks</strong> <strong>Tekniske</strong> <strong>Universitet</strong> (DTU).<br />
11) Chen, G., Esch, G., Wonka, P., Müller, P., & Zhang, E. (2008). Interactive Procedural Street<br />
Modeling. Proceedings of SIGGRAPH 2008.<br />
12) Cohn, D. (2. 7 2008). New NVIDIA Quadro FX Series Workstation Graphics Cards Deliver HPC<br />
for Less. Hentede 13. 2 2010 fra Desktop Engineering:<br />
http://www.deskeng.com/articles/aaajxm.htm<br />
13) Crenshaw, J. W. (31. 8 1988). Let's build a compiler! Hentede 21. 4 2010 fra Compilers:<br />
http://compilers.iecc.com/crenshaw/tutor6.txt<br />
158
14) denstoredanske. (02. 02 2009). Den store danske encyklopædi. Hentede 9. 2 2010 fra skalk:<br />
http://www.denstoredanske.dk/Kunst_og_kultur/Arkitektur/Bygningsdele/skalk<br />
15) Finkenzeller, D., & Schmitt, A. (2006). Rapid modeling of complex building façades. Institut<br />
für Betriebs- und Dialogsysteme, Universität Karlsruhe (TH), Germany.<br />
16) Forrest, A. (2003). Future trends in computer graphics: how much is enought? Journal of<br />
Computer Sceience and Technology , s. 531-537.<br />
17) Greuter, S., & Parker, J. (2003). Real-time procedural Generation of 'Pseudo Infinite' Cities.<br />
Graphite 2003, (s. 87-ff). RMIT University, Melbourne, Australien.<br />
18) Greuter, S., & Stewart, N. (2004). Beyond the horizon: Computer-generated, Threedimensional,<br />
Infinite Virtual Worlds without Repetition in Real-time. Image Text and Sound<br />
Conference. RMIT University, Melbourne, Australien.<br />
19) Hanrahan, P. (2005). Why is graphics hardware so fast? Proceedings of the tenth ACM<br />
SIGPLAN symposium on Principles and practice of parallel programming (s. 1-1). Chicago, IL,<br />
USA: ACM.<br />
20) Havermann, S. (2005). Generative Mesh Modeling. Braunschweig: Technischen Universität,<br />
Braunschweig.<br />
21) husrådgivning. (2010). husrådgivning.dk. Hentede 5. 2 2010 fra<br />
http://www.husrådgivning.dk/?download=Det%20hedder%20husets%20dele.pdf<br />
22) Kelly, G., & McCabe, H. (2007). Citygen: An interactive System for Procedural City<br />
Generation.<br />
23) Lang, R. (2010). Dyson's Random Morph Map. Hentede 18. 2 2010 fra 1km1kt:<br />
http://www.1km1kt.net/geomorph/<br />
24) Laycock, R. G., & Day, A. M. (2003). Automatically Generating roof Models from Building<br />
Footprint. University of East Anglia, Norwich.<br />
25) Lindenmayer, A., & Prusinkiewicz, P. (1996). The Algorithmic Beauty of Plants. Springer<br />
Verlag.<br />
26) Lipp, M., Wonka, P., & Wimmer, M. (2008). Interactive Visual Editing of Grammars for<br />
Procedural Architecture. ACM SIGGRAPH, (s. 1-10, vol 27).<br />
27) lsas. (2010). Vælg tagformen til dit hus. Hentede 5. 2 2010 fra Løve Savværk:<br />
http://www.lsas.dk/02_bestil-tagspaer/tagformer.html<br />
28) Mantyla, M. (1988). Introduction to Solid Modeling. NY, USA: WH Freeman & Co. New York.<br />
29) Müller, P. (2. 11 2006). Procedural Reconstruction of Archaeological Sites. Hentede 24. 3 2010<br />
fra Pascals Müllers wiki: http://www.vision.ee.ethz.ch/~pmueller/wiki/Courses/VAST2006<br />
159
30) Müller, P., & Parish, Y. I. (2001). Procedural Modeling of Cites. Proceedings of ACM<br />
SIGGRAPH, (s. 301-308).<br />
31) Müller, P., Wonka, P., Haegler, S., Ulmer, A., & Van Gool, L. (2006). Procedural Modeling of<br />
Buildings. Proceedings of ACM SIGGRAPH, (s. 614-623, vol 25).<br />
32) Mössenböck, H. (2006). The Compiler Generator Coco/r User Manual. Johannes Kepler<br />
University, Linz.<br />
33) Perlin, K. (9. 12 1999). Making Noise. Hentede 18. 2 2010 fra noisemashine:<br />
http://www.noisemachine.com/talk1/<br />
34) Procedural, i. (u.d.). CityEngine Help roofHip. Hentede 6. 3 2010 fra CityEngine:<br />
http://www.procedural.com:8080/help/index.jsp?topic=/com.procedural.cityengine.help/ht<br />
ml/toc.html<br />
35) Procedural, I. (u.d.). Front page. Hentede 30. 3 2010 fra Procedural inv:<br />
http://www.procedural.com/<br />
36) Prusinkiewicz, P., & Mech, R. (1996). Visual Models of Plants Interacting with Their<br />
Environment. Proceedings of the 23rd Annual Conference on Computer Graphics, (s. 397 - 410).<br />
37) Rosmarin, R. (12. 19 2006). Forbes. Hentede 19. 2 2010 fra Why Gears Of War Costs $60:<br />
http://www.forbes.com/2006/12/19/ps3-xbox360-costs-techcx_rr_game06_1219expensivegames.html<br />
38) Rotenberg, S. (2005). Procedural Modeling. Hentede 17. 2 2010 fra<br />
http://graphics.ucsd.edu/courses/cse167_f05/CSE167_18.ppt<br />
39) Stiny, G. (1982). Spatial relations and grammars.<br />
40) Takatsuki, Y. (27. 12 2007). BBC News. Hentede 19. 2 2010 fra Cost headache for game<br />
developers: http://news.bbc.co.uk/2/hi/business/7151961.stm<br />
41) Whiting, E., Ochsendorf, J., & Durand, F. (2009). Procedural Modeling of Structurally-Sound<br />
Masonry Buildings. Proceedings of SIGGRAPH Asia, Article: 112 .<br />
42) Wonka, P., Wimmer, M., Sillion, F., & Ribarsky, W. (2003). Instant Architechture.<br />
Proceedings ACM SIGGRAPH, (s. 669-677).<br />
160
Bilag 1: L-systemer<br />
Fraktal- l-system (L-sys1.txt)<br />
/*Axiom*/<br />
F(3) B(3, 1);<br />
/*Production*/<br />
p2: B(x, y) -> Size(y)Roll(0.2)Pitch(0.2)F(x * 2) Push() C(x * 0.9, y * 0.88)<br />
Pop() Push() D(x * 0.9, y * 0.88) Pop() B(x*0.95, y*0.95);<br />
p3: C(x, y) -> Size(y)Yaw(0.2)Pitch(0.2)F(x)C(x*0.9, y*0.88);<br />
p3: D(x, y) -> Size(y)Yaw(0.2)Pitch(-0.2)F(x)D(x*0.9, y*0.88);<br />
Egetræ (Tree1.txt)<br />
number trunkLengthReduction = 0.9;<br />
number trunkSizeReduction = 0.92;<br />
/*Axiom*/<br />
Size(1.7)F(0)Trunk(1.8, 1.4);<br />
/*Production*/<br />
p1: Trunk(x, y) -> Size(y) R(0.05, 0.05, 0.05) F(x) Roll(1.916) T(0.21)<br />
Trunk(x * trunkLengthReduction, y * trunkSizeReduction) : 0.2;<br />
p2: Trunk(x, y) -> Size(y) R(0.05, 0.05, 0.05) F(x) Push() Pitch(-0.6)<br />
Branch(x * 0.44, y * 0.54) Pop() Pitch(0.00) Roll(1.916)<br />
Trunk(x * trunkLengthReduction, y * trunkSizeReduction) : 0.5;<br />
p3: Trunk(x, y) -> Size(y) R(0.05, 0.05, 0.05) F(x)<br />
Push() Pitch(-0.5) Branch(x * 0.35, y * 0.35) Pop()<br />
Push() Pitch(0.4) Branch(x * 0.35, y * 0.35) Pop()<br />
Pitch(0.00) Roll(1.916)<br />
Trunk(x * trunkLengthReduction, y * trunkSizeReduction) : 0.3;<br />
p4: Branch(x, y) -> Size(y) T(0.2) R(0.2, 0.2, 0.2) F(x)<br />
Branch(x * 0.94, y * 0.94) : 0.9;<br />
p5: Branch(x, y) -> Size(y) T(0.2) R(0.2, 0.2, 0.2) F(x) Push() Level() Yaw(0.7)<br />
Branch(x * 0.85, y * 0.4) Pop() Branch(x * 0.94, y * 0.94) : 0.03;<br />
p6: Branch(x, y) -> Size(y) T(0.2) R(0.2, 0.2, 0.2) F(x) Push() Level()<br />
Yaw(-0.7) Branch(x * 0.85, y * 0.4) Pop()<br />
Branch(x * 0.94, y * 0.94) : 0.03;<br />
p5: Branch(x, y) -> Size(y) T(0.2) R(0.2, 0.2, 0.2) F(x) Push() Level() Yaw(0.7)<br />
Branch(x * 0.85, y * 0.4) O(1) Pop()<br />
Branch(x * 0.94, y * 0.94) : 0.02;<br />
p6: Branch(x, y) -> Size(y) T(0.2) R(0.2, 0.2, 0.2) F(x)<br />
Push() Level() Yaw(-0.7) Branch(x * 0.85, y * 0.4) O(1) Pop()<br />
Branch(x * 0.94, y * 0.94) : 0.02;<br />
p7: T(x) : x -0.07 -> T(x - 0.01);<br />
Fyrtræ 1 (Tree2.txt)<br />
number numDerivations = 20;<br />
number lr = 1.119; /* elongation rate */<br />
number sr = 1.14; /* width increase rate */<br />
/*Axiom*/<br />
Size(0.039)F(0)Trunk(0.2, 0.035);<br />
161
*Production*/<br />
p1: Trunk(x, y) -> Size(y) Roll(1.916) F(x) R(0.02, 0.02, 0.02)<br />
Trunk(x, y) : 0.01;<br />
p1: Trunk(x, y) -> Size(y) Roll(1.916) F(x) R(0.02, 0.02, 0.02)<br />
Push() Pitch(1.2) Size(y * 0.001) F(x * 0.5) Pitch(-0.4) O(0.7) Pop()<br />
Trunk(x, y) : 0.99;<br />
p2: F(x) -> F(x * lr);<br />
p3: Size(x) -> Size(x * sr);<br />
p5: O(x) -> O(x * 1.08);<br />
Bøgetræ (Tree3.txt)<br />
number numDerivations = 10;<br />
number r1 = 0.9; /* contraction ratio for the trunk */<br />
number r2 = 0.66; /* contraction ratio for the branches */<br />
number a0 = 0.7853; /* branching angle for the trunk */<br />
number a2 = 0.7853; /* brnaching angle for the lateral axes */<br />
number d = 2.3998; /* divergence angle */<br />
number wr = 0.707; /* width decrease angle */<br />
/*Axiom*/<br />
A(1.5, 0.2);<br />
p1: A(l, w) -> Size(w) R(0.1, 0.1, 0.1) T(0.1) F(l)<br />
Push() Pitch(a0) B(l * r2, w * wr * 0.5) O(0.5) Pop()<br />
Roll(d) A(l * r1, w * wr);<br />
p2: B(l, w) -> Size(w) R(0.2, 0.2, 0.2) F(l * 0.5) T(0.1)<br />
Push() Yaw(-a2) Level() R(0.1, 0.1, 0.2) CC(l, w, 0) O(0.7) Pop()<br />
C(l * r1, w * wr);<br />
p3: C(l, w) -> Size(w) R(0.2, 0.2, 0.2) F(l * 0.5) T(0.1)<br />
Push() Yaw(a2) Level() R(0.1, 0.1, 0.2) BC(l, w, 0) O(0.7) Pop()<br />
B(l * r1, w * wr);<br />
p4: CC(l, w) -> C(l, w) : 0.4;<br />
p5: BC(l, w) -> B(l, w) : 0.4;<br />
p6: O(x) -> O(x * 1.1);<br />
Fyrtræ 2 (Tree4.txt)<br />
number numDerivations = 20;<br />
number r1 = 0.9; /* contraction ratio for the trunk */<br />
number r2 = 0.66; /* contraction ratio for the branches */<br />
number a0 = 1.5707; /* branching angle for the trunk */<br />
number a2 = 0.7853; /* brnaching angle for the lateral axes */<br />
number d = 2.3998; /* divergence angle */<br />
number wr = 0.707; /* width decrease angle */<br />
/*Axiom*/<br />
A(0.9, 0.2);<br />
p1: A(l, w) -> Size(w) R(0.1, 0.1, 0.1) T(0.1) F(l)<br />
Push() Pitch(a0) B(l * r2, w * wr * 0.5) O(0.5) Pop()<br />
Roll(d) A(l * r1, w * wr);<br />
p2: B(l, w) -> Size(w) R(0.2, 0.2, 0.2) F(l * 0.5) T(-0.05)<br />
Push() Yaw(-a2) Level() R(0.1, 0.1, 0.2) CC(l, w, 0) O(0.7) Pop()<br />
C(l * r1, w * wr);<br />
p3: C(l, w) -> Size(w) R(0.2, 0.2, 0.2) F(l * 0.5) T(-0.05)<br />
Push() Yaw(a2) Level() R(0.1, 0.1, 0.2) BC(l, w, 0) O(0.7) Pop()<br />
162
B(l * r1, w * wr);<br />
p4: CC(l, w) -> C(l, w) : 0.03;<br />
p5: BC(l, w) -> B(l, w) : 0.03;<br />
p6: O(x) -> O(x * 1.02);<br />
Bilag 2: CGA-grammaer<br />
Sears Tower (SearsTower.txt)<br />
HEADER:<br />
//Common<br />
number floorHeight = 0.5; //Number variable declared<br />
number buildingHeight = 25;<br />
number pi = 3.1415926;<br />
//Facade<br />
number marginWidth = 0.1;<br />
random r = [0.5, 1.0]; //Random variable declared<br />
random r2 = [0.3, 0.6]; //Random variable declared<br />
random r3 = [0.6, 0.8]; //Random variable declared<br />
DECLARATION:<br />
PRIORITY 1:<br />
p1: Sears -> S(Scope.Sx, buildingHeight, Scope.Sz)<br />
Push() T((-Scope.Sx / 3.0) * 0.5, 0, (-Scope.Sz / 3.0) * 0.5)<br />
S(Scope.Sx / 3.0, Scope.Sy, Scope.Sz / 3.0) column antenna Pop()<br />
Push() pillars Pop()<br />
Push() Ry(pi*0.5) pillars Pop()<br />
Push() Ry(pi) pillars Pop()<br />
Push() Ry(pi * 1.5) pillars Pop();<br />
p2: pillars -> T((-Scope.Sx / 3.0) * 1.5, 0, (-Scope.Sx / 3.0) * 1.5)<br />
S((Scope.Sx / 3.0) * 2, Scope.Sy, Scope.Sx / 3.0) sidePillar;<br />
p2: sidePillar -> Push() T(Scope.Sx / 2, 0, 0)<br />
S(Scope.Sx / 2, Scope.Sy, Scope.Sz) column antenna Pop()<br />
Push() S(Scope.Sx / 2, Scope.Sy * r2, Scope.Sz) column Pop() : 0.15;<br />
p2: sidePillar -> S(Scope.Sx, Scope.Sy * r3, Scope.Sz)<br />
Push() T(Scope.Sx / 2, 0, 0) S(Scope.Sx / 2, Scope.Sy, Scope.Sz)<br />
column Pop()<br />
Push() S(Scope.Sx / 2, Scope.Sy * r2, Scope.Sz) column Pop() : 0.85;<br />
p4: antenna -> Push() T(Scope.Sx * 0.5, Scope.Sy, Scope.Sz * 0.5)<br />
S(0.2, Scope.Sy * 0.15, 0.2) I("cylinder") Pop();<br />
PRIORITY 2:<br />
p4: column -> Comp("sidefaces") {facade} Comp("topface") {roofMat};<br />
// Facade<br />
p6: facade -> Subdiv("Z", marginWidth, *1, marginWidth)<br />
163
{gray | windowGroup | gray};<br />
p7: windowGroup -> Subdiv("X", marginWidth, *1, marginWidth)<br />
{gray | glassMat | gray};<br />
Petronas Towers (Petronas.txt)<br />
HEADER:<br />
number floorHeight = 0.5;<br />
number buildingHeight = 35;<br />
number heightFallOff = 0.5;<br />
number widthFallOff = 0.6;<br />
number pi = 3.1415926;<br />
number squareHalf = 0.89;<br />
number cylinderSize = 0.2617993877991; //Diameter = pi / 16<br />
random r = [0.5, 1.0];<br />
random r2 = [0.3, 0.6];<br />
random r3 = [0.6, 0.8];<br />
DECLARATION:<br />
PRIORITY 1:<br />
p1: Petronas -> S(Scope.Sx, buildingHeight, Scope.Sz) section row;<br />
p2: row : Scope.Sy > 3 * floorHeight -> T(0, Scope.Sy, 0)<br />
S(Scope.Sx - widthFallOff,<br />
heightFallOff * Scope.Sy,<br />
Scope.Sz - widthFallOff)<br />
section row;<br />
p3: row : Scope.Sy < 3 * floorHeight -> antenna;<br />
p2: section -><br />
Push() T(-Scope.Sx * 0.5, 0, -Scope.Sz * 0.5)<br />
petronasSuperStructure Pop()<br />
Push() Ry(pi * 0.25) T(-Scope.Sx * 0.5, 0, -Scope.Sz * 0.5)<br />
petronasSuperStructure Pop()<br />
Push() Ry(pi * 0.125) buldge Pop()<br />
Push() Ry(pi * 0.375) buldge Pop()<br />
Push() Ry(pi * 0.625) buldge Pop()<br />
Push() Ry(pi * 0.875) buldge Pop();<br />
p3: buldge -><br />
Push() T(Scope.Sx * 0.5, 0, Scope.Sz * 0.5)<br />
T(-Scope.Sx * squareHalf, 0, -Scope.Sz * squareHalf)<br />
petronasCylinder Pop()<br />
Push() T(-Scope.Sx * 0.5, 0, -Scope.Sz * 0.5)<br />
T(Scope.Sx * squareHalf, 0, Scope.Sz * squareHalf)<br />
petronasCylinder Pop();<br />
PRIORITY 2:<br />
p4: petronasSuperStructure -> Subdiv("Y", *1, floorHeight)<br />
{ Repeat("Y", 2 * floorHeight) {<br />
164
I("cube") Subdiv("Y", floorHeight, floorHeight) {gray | glassMat} }<br />
| gray};<br />
p5: petronasCylinder -><br />
Push() S(Scope.Sx * cylinderSize, Scope.Sy, Scope.Sz * cylinderSize)<br />
I("cylinder") cylinder Pop();<br />
p5: cylinder -> Subdiv("Y", *1, floorHeight)<br />
{ Repeat("Y", 2 * floorHeight)<br />
{ Subdiv("Y", floorHeight, floorHeight)<br />
{ T(0, Scope.Sy * 0.5, 0) gray | T(0, Scope.Sy * 0.5, 0) glassMat}<br />
} | T(0, Scope.Sy * 0.5, 0) gray };<br />
p4: antenna -> T(0, Scope.Sy, 0) ball<br />
T(-0.1, 0, -0.1) S(0.2, buildingHeight * 0.3, 0.2) I("cylinder");<br />
p7: ball -> Push() T(-Scope.Sx * 0.0, Scope.Sx * 0.0, -Scope.Sx * 0.0)<br />
S(Scope.Sx * 0.5, Scope.Sz * 0.5, Scope.Sx * 0.5)<br />
I("sphere") gray Pop();<br />
Kontorbygning (OfficeBuilding.txt)<br />
HEADER:<br />
number floorHeight = 1;<br />
number windowHeight = 0.8;<br />
number windowWidth = 0.2;<br />
number sectionMultiplier = 2;<br />
number windowGroupWidth = 2.4;<br />
number doorWidth = 1;<br />
number glassWidth = 0.6;<br />
number frameSize = 0.02;<br />
number roofInset = 0.1;<br />
number overhang = 0.2;<br />
number underhangSize = 0.1;<br />
string facadeType = "type3";<br />
random r1 = [0.25, 0.6];<br />
random r2 = [0.3, 0.9];<br />
random r3 = [0.6, 1.0];<br />
random r4 = [0.2, 0.9];<br />
random r5 = [0.5, 0.7];<br />
random r6 = [0.2, 0.7];<br />
random r7 = [0.1, 0.2];<br />
number buildingHeight = 80;<br />
DECLARATION:<br />
PRIORITY 1:<br />
p1 : lot -> S(*1, buildingHeight * r5, *1)<br />
Subdiv("Z", Scope.Sz * r1, *1)<br />
{ Comp("sidefaces") {facades} Comp("topface") {roof} | sidewings};<br />
p2 : sidewings -> Subdiv("X", Scope.Sx * r2, *1) {sidewing | epsilon}<br />
165
Subdiv("X", *1, Scope.Sx * r2) {epsilon | sidewing};<br />
p3 : sidewing -> Subdiv("Z", Scope.Sz * r3, *1){ Comp("sidefaces") {facades}<br />
Comp("topface") {roof} | epsilon} : 0.5;<br />
p4 : sidewing -> S(*1, Scope.Sy * r4, *1)<br />
Subdiv("Z", Scope.Sz * r3, *1)<br />
{ Comp("sidefaces") {facades} Comp("topface") {roof} | epsilon}<br />
: 0.3;<br />
p5 : sidewing -> epsilon : 0.2;<br />
//Shuffle facade<br />
p6 : facades : facadeType == "type1" -> facades1;<br />
p6 : facades : facadeType == "type2" -> facades2;<br />
p6 : facades : facadeType == "type3" -> facades3;<br />
p6 : facades : facadeType == "type4" -> facades4;<br />
//----------------------Facade 1 ------------------------------------<br />
//Facade<br />
p7 : facades1 : Scope.Sz > floorHeight * 3 -><br />
Subdiv("Z", floorHeight * 1.3, *1, floorHeight * 1.3)<br />
{baseFloor | mid | topFloor};<br />
p7 : facades1 : Scope.Sz > floorHeight -> baseFloor;<br />
p7 : facades1 -> facade;<br />
//Facade elements<br />
p8 : mid : Scope.Sz > floorHeight -> Repeat("X", windowGroupWidth)<br />
{Repeat("Z", floorHeight){ windowGroup }};<br />
p8 : mid -> facade;<br />
p9 : windowGroup -> Subdiv("X", *1, Scope.Sx * windowWidth, *1)<br />
{facade | Subdiv("Z", *0.8, Scope.Sz * windowHeight, *1)<br />
{facade | win | facade} | facade};<br />
p10 : doorGroup -> Subdiv("X", *1, Scope.Sx * 0.8, *1) {facade | door | facade};<br />
p11 : baseFloor : Scope.Sx > doorWidth * 2 -><br />
Subdiv("Z", floorHeight * 1.1, *1){ Subdiv("X", *1, doorWidth, *1)<br />
{innerFrame | doorGroup | innerFrame} | facade} : 0.4;<br />
p11 : baseFloor : Scope.Sx > doorWidth * 2 -><br />
Subdiv("Z", floorHeight * 1.1, *1){ Subdiv("X", doorWidth, *1, *1)<br />
{doorGroup | innerFrame | innerFrame} | facade} : 0.2;<br />
p11 : baseFloor : Scope.Sx > doorWidth * 2 -><br />
Subdiv("Z", floorHeight * 1.1, *1){ Subdiv("X", *1, *1, doorWidth)<br />
{innerFrame | innerFrame | doorGroup} | facade} : 0.2;<br />
p11 : baseFloor -> Subdiv("Z", floorHeight * 1.1, *1){ innerFrame | facade};<br />
p12 : topFloor -> Repeat("X", windowGroupWidth * 2)<br />
{ Subdiv("X", *1, Scope.Sx * (windowWidth + (1 - windowWidth) * 0.5),<br />
*1) {facade | Subdiv("Z", *0.8, Scope.Sz * windowHeight, *1) {facade<br />
| win | facade} | facade} };<br />
//----------------------Facade 2 ------------------------------------<br />
p13 : facades2 : Scope.Sz > 2 * floorHeight -><br />
166
Subdiv("Z", floorHeight * 1.3, *1) {baseFloor2 | mid2};<br />
p13 : facades2 -> baseFloor2;<br />
p14 : mid2 -> Repeat("Z", floorHeight) {floor2};<br />
p15 : floor2 -> Subdiv("Z", underhangSize, *1) {underhangFacade | innerFrame};<br />
p16 : underhangFacade -> T(-underhangSize, 0, 0)<br />
S(Scope.Sx + 2 * underhangSize, underhangSize, Scope.Sz) gray;<br />
p17: baseFloor2 : Scope.Sx > floorHeight * 2 -><br />
Subdiv("X", (Scope.Sx - floorHeight) * r6, floorHeight, *1)<br />
{innerFrame | Subdiv("Z", floorHeight, *1)<br />
{door | innerFrame} | innerFrame};<br />
p17: baseFloor2 -> innerFrame;<br />
//----------------------Facade 3 ------------------------------------<br />
p18 : facades3 : Scope.Sz > 2 * floorHeight -><br />
Subdiv("Z", floorHeight * 1.3, *1) {baseFloor3 | mid3};<br />
p18 : facades3 -> baseFloor3;<br />
p19 : mid3 : Scope.Sx > floorHeight -><br />
Subdiv("X", 0.5 * floorHeight, *1, floorHeight * 0.5)<br />
{facade | midColumn | facade};<br />
p19 : mid3 -> midColumn;<br />
p20 : midColumn : Scope.Sz > floorHeight -> Subdiv("Z", *1, floorHeight * 0.5)<br />
{ Repeat("Z", floorHeight){ winSection } | facade};<br />
p20 : midColumn -> winSection;<br />
p21 : winSection -> Repeat("X", sectionMultiplier * windowWidth) {windowGroup3};<br />
p22 : windowGroup3 -> Subdiv("X", *1, Scope.Sx * windowWidth, *1)<br />
{facade | Subdiv("Z", Scope.Sz * windowHeight, *1) { win | facade} |<br />
facade};<br />
p23: baseFloor3 -> Subdiv("X", floorHeight * 0.5, *1, floorHeight * 0.5)<br />
{facade | winSection | facade};<br />
//------------------------Facaade 4---------------------------------<br />
p24 : facades4 : Scope.Sz > 2 * floorHeight -><br />
Subdiv("Z", floorHeight * 1.3, *1) {baseFloor3 | mid4};<br />
p24 : facades4 -> baseFloor3;<br />
p25 : mid4 : Scope.Sx > floorHeight -><br />
Subdiv("X", 0.5 * floorHeight, *1, floorHeight * 0.5)<br />
{facade | midColumn4 | facade};<br />
p25 : mid4 -> midColumn4;<br />
p26 : midColumn4 : Scope.Sz > floorHeight -><br />
Subdiv("Z", *1, floorHeight * 0.5)<br />
{ Repeat("Z", floorHeight) { windowGroup4 } | facade};<br />
p26 : midColumn4 -> windowGroup4;<br />
p27 : windowGroup4 -> Subdiv("Z", Scope.Sz * windowHeight, *1) { win | facade};<br />
//-------------------- Detail objects ------------------------------<br />
//Window<br />
p28 : win -> T(0, -frameSize * 2, 0) Push()<br />
S(Scope.Sx, frameSize * 2, Scope.Sz) Comp("sidefaces") {facade} Pop()<br />
167
Subdiv("Z", frameSize, *1) {underhang | innerFrame};<br />
p29 : innerFrame -> Repeat("X", glassWidth)<br />
{ Subdiv("X", frameSize, *1, frameSize)<br />
{ windowFrame | Subdiv("Z", frameSize, *1, frameSize)<br />
{windowFrame | glass | windowFrame} | windowFrame}};<br />
p30 : windowFrame -> S(Scope.Sx, frameSize, Scope.Sz) darkGray;<br />
p31 : underhang -> S(Scope.Sx, frameSize * 4, Scope.Sz) darkGray;<br />
//Door<br />
p32 : door -> T(0, -Scope.Sx * 0.02, 0) Push()<br />
S(Scope.Sx, Scope.Sx * 0.02, Scope.Sz) Comp("sidefaces") {facade}<br />
Pop() darkGray;<br />
//Roof<br />
p33 : roof -> darkGray T(Scope.Sx * r6, 0, Scope.Sz * r6)<br />
S(Scope.Sx * r1 * 0.4, 0.5 * r1, Scope.Sz * r1 * 0.4) darkGray : 0.5;<br />
p33 : roof -> darkGray Inset(roofInset)<br />
{ S(Scope.Sx, 1 * r1, Scope.Sz) darkGray } : 1;<br />
Villa (Mansion.txt)<br />
HEADER:<br />
random r1 = [0.2, 0.4];<br />
random r2 = [0.1, 0.3];<br />
random rr = [0.2, 0.4];<br />
randomi rSlope = [10, 50];<br />
number baseHeight = 0.6;<br />
number baseWidth = 0.1;<br />
number cornice = 0.15;<br />
number floorSplit = 0.05;<br />
number frontOutset = 3.5;<br />
random rOutset = [2, 5];<br />
number floorHeight = 3.5;<br />
number numFloors = 2;<br />
number sideColumnWidth = 0.4;<br />
number sideColumnHeight = 0.6;<br />
//Window + doors<br />
number frameSize = 0.07;<br />
number subFrameSize = 0.05;<br />
number windowWidth = 1.5;<br />
number doorWidth = 1;<br />
number doorHeight = 2;<br />
number windowHeight = 1.5;<br />
number groupSpan = 0.8;<br />
number stepHeight = 0.15;<br />
number stepWidth = 0.2;<br />
number bottomFloorRatio = 1.12;<br />
number fenceWidth = 0.1;<br />
number fenceHeight = 0.5;<br />
168
number buildingHeight = 30;<br />
number pi = 3.141592653589;<br />
boolean hasSideColumn = true;<br />
DECLARATION:<br />
PRIORITY 1:<br />
p1 : lot -> S(Scope.Sx, 0, Scope.Sz) Subdiv("Z", Scope.Sz * rr, *1,<br />
Scope.Sz * rr) {frontYard | mid | backYard};<br />
p2 : mid -> S(*1, numFloors * floorHeight, *1) Subdiv("X", Scope.Sx * r2, *1,<br />
Scope.Sz * r2) {garden | house T(0, Scope.Sy + 0, 0) Inset(-cornice)<br />
{ Comp("footprint", 0, 1) {roofEdge} } roofTier | garden} ;<br />
p3 : house -> Comp("sidefaces", 0) {front} Comp("sidefaces", 2) {back}<br />
Comp("sidefaces", 1) {side} Comp("sidefaces", 3) {side} ;<br />
p4: front -> Subdiv("X", *1, Scope.Sx * r1, *1)<br />
{windowFacade | outset | windowFacade} : 0.2;<br />
p4: front -> Subdiv("X", *1, Scope.Sx * r1, *1)<br />
{outset | windowFacade | outset} : 0.2;<br />
p4: front -> Subdiv("X", Scope.Sx * r1, *1) {outset | windowFacade } : 0.2;<br />
p4: front -> Subdiv("X", *1, Scope.Sx * r1) {windowFacade | outset} : 0.2;<br />
p4: front -> /*gray T(0, 4, 0)*/ windowFacade;<br />
p5 : back -> Subdiv("X", *1, Scope.Sx * r1) {windowFacade | balcony} : 0.4;<br />
p5 : back -> Subdiv("X", Scope.Sx * r1, *1) {balcony | windowFacade} : 0.4;<br />
p5 : back -> windowFacade;<br />
p6: side -> windowFacade;<br />
p7 : outset -> S(Scope.Sx, Scope.Sz, frontOutset) Rx(pi * 0.5)<br />
T(0, 0, -frontOutset) Comp("sidefacesEx", 1) {windowFacade}<br />
Comp("topface", 1) { outsetRoof };<br />
p8 : outsetDoor -> S(Scope.Sx, frontOutset, Scope.Sz) Comp("faces") {gray}<br />
Comp("sidefaces", 1) { outsetRoof };<br />
p9: balcony : Scope.Sz > floorHeight * bottomFloorRatio + cornice / 3 +<br />
baseHeight -><br />
Subdiv("Z",<br />
floorHeight * bottomFloorRatio + cornice / 3 + baseHeight, *1)<br />
{ S(Scope.Sx, Scope.Sz, rOutset) Rx(pi * 0.5)<br />
T(0, 0, -Scope.Sz) Comp("sidefaces") {windowFacade} Comp("topface")<br />
{balconyRoof} | balconyDoor} : 0.8;<br />
p9: balcony -> S(Scope.Sx, Scope.Sz, rOutset) Rx(pi * 0.5) T(0, 0, -Scope.Sz)<br />
Comp("sidefacesEx", 1) {windowFacade}<br />
Comp("topface") { outsetRoof } : 1;<br />
p10: balconyDoor -> Subdiv("Z", *1, cornice) {balconyDoorTile | cornice};<br />
p11: balconyRoof -> gray Subdiv("X", fenceWidth, *1, fenceWidth)<br />
{ fence | Subdiv("Z", fenceWidth, *1)<br />
{ Ry(-pi * 0.5) S(Scope.Sz, Scope.Sy, Scope.Sx + fenceWidth)<br />
T(0, 0, -Scope.Sz) fence | eps} | fence};<br />
169
p12: fence -> Repeat("Z", 1){ Push() S(fenceWidth, fenceHeight, fenceWidth) gray<br />
Pop() T(Scope.Sx * 0.5, 0, 0) S(0, fenceHeight, Scope.Sz) gray };<br />
p13: outsetRoof -> Inset(-cornice){ Comp("footprint", 1, 0) {roofEdge}};<br />
p14: windowFacade : Scope.Sx > sideColumnWidth * 2 -><br />
Subdiv("Z", baseHeight, *1, cornice)<br />
{base | Subdiv("X", sideColumnWidth, *1, sideColumnWidth)<br />
{gray column | windowTiles | gray Rz(pi)<br />
T(-Scope.Sx, -floorSplit, 0) column} |cornice};<br />
p14: windowFacade -> Subdiv("Z", baseHeight, *1, cornice)<br />
{base | gray column |cornice};<br />
p15: windowTiles : Scope.Sz > floorHeight * bottomFloorRatio + cornice -><br />
Subdiv("Z", floorHeight * bottomFloorRatio, *1)<br />
{doorWinGroup | topFloor};<br />
p15: windowTiles -> doorWinGroup; //BottomFloor<br />
p16: column : hasSideColumn -> Repeat("Z", sideColumnHeight)<br />
{ T(-floorSplit + 0.001, 0, 0) Push()<br />
S(Scope.Sx + 2 * floorSplit, floorSplit, Scope.Sz * 0.5 - 0.01)<br />
whiteMat Pop() T(0, 0, Scope.Sz * 0.5)<br />
S(Scope.Sx * 0.5 + 2 * floorSplit, floorSplit, Scope.Sz * 0.5 - 0.01)<br />
whiteMat };<br />
p17 : topFloor -> Subdiv("Z", floorSplit, *1){floorSplit | windowGroup};<br />
p18: base -> S(Scope.Sx + 2 * baseWidth, baseWidth, Scope.Sz)<br />
T(-baseWidth + 0.001, 0, 0) whiteMat<br />
S(Scope.Sx + 2 * baseWidth, 2 * baseWidth, Scope.Sz * 0.3333)<br />
T(-baseWidth + 0.001, 0, 0) whiteMat;<br />
p19 : floorSplit -> T(-floorSplit + 0.001, 0, 0)<br />
S(Scope.Sx + 2 * floorSplit, floorSplit, Scope.Sz) whiteMat;<br />
p20 : cornice -> Subdiv("Z", *0.3333, *0.3333, *0.3333)<br />
{ S(Scope.Sx + cornice * 0.6666, cornice *0.3333, Scope.Sz)<br />
T(-cornice * 0.3333 + 0.001, 0, 0) whiteMat |<br />
S(Scope.Sx + cornice * 1.3333, cornice * 0.6666, Scope.Sz)<br />
T(-cornice * 0.6666 + 0.001, 0, 0) Repeat("X", cornice * 2)<br />
{Subdiv("X", *1, *1) {whiteMat |<br />
S(Scope.Sx, cornice * 0.3333, Scope.Sz) whiteMat}} |<br />
S(Scope.Sx + cornice * 2, cornice, Scope.Sz)<br />
T(-cornice + 0.001, 0, 0) whiteMat};<br />
p21: doorWinGroup : Scope.Sx > doorWidth + groupSpan -><br />
Subdiv("X", *1, doorWidth + groupSpan, *1)<br />
{windowGroup | doorTile | windowGroup} : 0.25;<br />
p121: doorWinGroup -> windowGroup;<br />
p22: windowGroup : Scope.Sx > windowWidth + groupSpan -><br />
Repeat("X", groupSpan + windowWidth){ winTile };<br />
p22: windowGroup -> gray;<br />
p23: winTile -> Subdiv("X", *1, windowWidth, *1)<br />
170
{ gray | Subdiv("Z", *1, Scope.Sz * 0.6, *1){gray | win | gray} |<br />
gray };<br />
p24: doorTile -> Subdiv("X", *1, doorWidth, *1)<br />
{gray | Subdiv("Z", doorHeight, 0.1,<br />
(Scope.Sz * 0.8 - doorHeight - 0.1), *1){ stair door | gray |win |<br />
gray} | gray };<br />
p25: balconyDoorTile -> Subdiv("X", *1, doorWidth, *1)<br />
{gray | Subdiv("Z", doorHeight, 0.1,<br />
(Scope.Sz * 0.8 - doorHeight - 0.1), *1)<br />
{ door | gray |win | gray} | gray };<br />
/*-----------Window 1 Crosswin ---------*/<br />
p26: win -> T(0, -frameSize, 0) Subdiv("Z", frameSize, *1, frameSize)<br />
{ S(Scope.Sx, frameSize * 3, Scope.Sz) gray |<br />
Subdiv("X", frameSize, *1, frameSize)<br />
{S(Scope.Sx, frameSize * 2, Scope.Sz) gray | crossWin |<br />
S(Scope.Sx, frameSize * 2, Scope.Sz) gray} |<br />
S(Scope.Sx, frameSize * 2, Scope.Sz) gray};<br />
p27: crossWin -> Subdiv("Z", *2, *1) { Subdiv("X", *1, *1)<br />
{subFrame | subFrame} | Subdiv("X", *1, *1){subFrame | subFrame} };<br />
p28: subFrame -> Subdiv("X", subFrameSize, *1, subFrameSize)<br />
{S(Scope.Sx, subFrameSize, Scope.Sz) gray |<br />
Subdiv("Z", subFrameSize, *1, subFrameSize)<br />
{S(Scope.Sx, subFrameSize, Scope.Sz) gray | glassMat |<br />
S(Scope.Sx, subFrameSize, Scope.Sz) gray} |<br />
S(Scope.Sx, subFrameSize, Scope.Sz) gray};<br />
/*-----------Door ---------*/<br />
p29: stair : Scope.PWy > stepHeight - 0.0001 -><br />
T(-stepWidth, 0, -stepHeight)<br />
S(Scope.Sx + stepWidth * 2, Scope.Sy + stepWidth, stepHeight)<br />
gray stair;<br />
p30: door -> T(0, -frameSize, 0) Subdiv("Z", frameSize, *1, frameSize)<br />
{S(Scope.Sx, frameSize * 3, Scope.Sz) gray |<br />
Subdiv("X", frameSize, *1, frameSize)<br />
{S(Scope.Sx, frameSize * 2, Scope.Sz) gray | brownMat |<br />
S(Scope.Sx, frameSize * 2, Scope.Sz) gray} |<br />
S(Scope.Sx, frameSize * 2, Scope.Sz) gray};<br />
/*------------- Roof ----------------*/<br />
PRIORITY 2:<br />
p31: roofTier -> Roof("roofEdge", "mansard", 80, 30, 2, "halfHip", 2, 45)<br />
{roof | gable} : 0.25;<br />
p31: roofTier -> Roof("roofEdge", "sloped", rSlope, "gable")<br />
{roof | gable} : 0.25;<br />
p31: roofTier -> Roof("roofEdge", "sloped", 30, "hip", 30)<br />
{roof | gable} : 0.125;<br />
p31: roofTier -> Roof("roofEdge", "sloped", 40, "hip", 40)<br />
{roof | gable} : 0.125;<br />
p31: roofTier -> Roof("roofEdge", "sloped", 45, "halfHip", *0.66, 45)<br />
{roof | gable};<br />
p31: roofTier -> Roof("roofEdge", "sloped", 40, "hip", 40) {roof | gable} : 1;<br />
p32: roof -> T(0, -cornice * 0.5, -0.0001)<br />
171
S(Scope.Sx, cornice * 0.5, Scope.Sz) roofMat;<br />
p33: gable -> T(0, -cornice * 0.5, 0) gray;<br />
172