1 2022-02-07: Blender

1.1 Opgave: Lees data uit CSV

In gebouwen.csv staat informatie over de 400 hoogste gebouwen. Lees dit bestand regel voor regel in en plaats voor elk gebouw een kubus.

 1import csv
 2import bpy
 3
 4
 5# Open een CSV een lees regel voor regel
 6# f = ...
 7# reader = ...
 8# nr = 0
 9# x = 0
10
11for ...
12    # om het debuggen te vereenvoudigen tekenen we enkel de eerste x gebouwen
13    if nr > 10:
14        break
15
16    # plaats hier een cubus per gebouw
17    # bpy.ops.mesh.primitive_cube_add...
18
19
20    # update x zodat de kubussen naast elkaar staan
21    # x = 
_images/build00.png

1.2 Opgave: Grootte kubus

Met behulp van de “size” parameter kunnen we de grootte van de kubus aanpassen. Door deze op 1 in te stellen, vergemakkelijken we latere berekeningen.

 1import csv
 2import bpy
 3
 4
 5# Open een CSV een lees regel voor regel
 6# f = ...
 7# reader = ...
 8# nr = 0
 9# x = 0
10
11for ...
12    # om het debuggen te vereenvoudigen tekenen we enkel de eerste x gebouwen
13    if nr > 10:
14        break
15
16    # plaats hier een cubus per gebouw
17    # we gebruiken nu de size=1 parameter
18    # om de kubus grootte 1 te geven
19    # dit vereenvoudigt 
20    bpy.ops.mesh.primitive_cube_add(
21            size=1, location=(x, ...)
22        )
23
24    # update x zodat de kubussen naast elkaar staan
_images/build01.png

1.3 Opgave: Hoogte kubus

Laat de hoogte overeenkomen met de hoogte van het gebouw. Haal hiervoor de hoogte uit de 5-de kolom van de spreadsheet.

 1import csv
 2import bpy
 3
 4
 5# Open een CSV een lees regel voor regel
 6# f = ...
 7# reader = ...
 8# nr = 0
 9# x = 0
10
11for ...
12    # om het debuggen te vereenvoudigen tekenen we enkel de eerste x gebouwen
13    if nr > 10:
14        break
15
16    # bepaal de hoogte van het gebouw
17    height = ...
18
19    # plaats hier een cubus per gebouw
20    # gebruik parameter scale=(1,1,height) om de hoogte van de kubus aan te passen
21
22    bpy.ops.mesh.primitive_cube_add(
23            size=1, location=(x, ...), scale=...
24        )
25
26    # update x zodat de kubussen naast elkaar staan
_images/build02.png

1.4 Opgave: Correctie z-positie kubus

De onderkant van de kubus komt niet overeen met het grondvlak.

Pas de code aan zodat de kubussen allemaal beginnen op z-positie 0.

Je kan dit oplossen door de z-positie bij het aanmaken van de kubussen aan te passen.

 1import csv
 2import bpy
 3
 4
 5# Open een CSV een lees regel voor regel
 6# f = ...
 7# reader = ...
 8# nr = 0
 9# x = 0
10
11for ...
12    # om het debuggen te vereenvoudigen tekenen we enkel de eerste x gebouwen
13    if nr > 10:
14        break
15
16    # bepaal de hoogte van het gebouw
17    height = ...
18
19    # plaats hier een cubus per gebouw
20    # gebruik parameter scale=(1,1,height) om de hoogte van de kubus aan te passen
21    # pas location aan
22    bpy.ops.mesh.primitive_cube_add(
23            size=1, location=(x, ...), scale=...
24        )
25
26    # update x zodat de kubussen naast elkaar staan
_images/build03.png

1.5 Opgave: Materiaal met basis kleur

Tot nu toe konden we de kleuren van de objecten niet aanpassen.

We voorzien nu de hulp-functie “add_material” waarmee je een materiaal aan een object kunt toevoegen.

Zorg ervoor dat de kubussen een materiaal hebben.

 1import csv
 2import bpy
 3
 4
 5def add_material(obj, material_name, color):
 6    """Maak of herbruik een materiaal
 7    
 8    obj: object waaraan het materiaal toegekend dient te worden
 9    material_name: naam voor het materiaal
10    color: basis kleur, RGB-tuple
11
12    Onderstaand voorbeeld maakt een materiaal met naam "rood",
13    en kent hieraan de "base color" (1,0,0) toe. Dit is een tuple
14    dat een RGB-kleur voorstelt, met de rood component op 1 en 
15    de andere componenten op 0. Dus, puur rood.
16    > add_material(obj, "rood", (1,0,0))
17    """
18    material = bpy.data.materials.get(material_name)
19    if material is None:
20        material = bpy.data.materials.new(material_name)
21    material.use_nodes = True
22    principled_bsdf = material.node_tree.nodes["Principled BSDF"]
23    if principled_bsdf is not None:
24        principled_bsdf.inputs[0].default_value = (*color, 1)
25    obj.active_material = material
26
27
28# Open een CSV een lees regel voor regel
29# f = ...
30# reader = ...
31# nr = 0
32# x = 0
33
34for ...
35    # om het debuggen te vereenvoudigen tekenen we enkel de eerste x gebouwen
36    if nr > 10:
37        break
38
39    # bepaal de hoogte van het gebouw
40    height = ...
41
42    # plaats hier een cubus per gebouw
43    # gebruik parameter scale=(1,1,height) om de hoogte van de kubus aan te passen
44    # pas location aan
45    bpy.ops.mesh.primitive_cube_add(
46            size=1, location=(x, ...), scale=...
47        )
48
49    # gebruik een variabele om naar het actieve object te verwijzen
50    obj = bpy.context.object
51
52    # Voeg hier een materiaal aan je kubus toe, zodat je kubus een basis
53    # kleur heeft. De kleuren druk je uit als RGB tuple, dus (rood, groen, blauw)
54    # add_material(obj, ...)
55
56    # update x zodat de kubussen naast elkaar staan
_images/build032.png

1.6 Opgave: Materiaal met roughness

We voorzien nu een nieuwe hulpfunctie add_material die buiten de basiskleur ook twee andere materiaaleigenschappen laat aanpassen.

Zorg ervoor dat de kubussen een materiaal hebben dat goud voorstelt.

 1import csv
 2import bpy
 3
 4
 5def add_material(obj, material_name, color, roughness=1.0, metallic=0):
 6    """Maak of herbruik een materiaal
 7    
 8    obj: object waaraan het materiaal toegekend dient te worden
 9    material_name: naam voor het materiaal
10    color: basis kleur, RGB-tuple
11    roughness: lagere waarden geven meer spiegeling
12    metallic: voor een metaal gebruik je waarde 1
13
14    Onderstaand voorbeeld maakt een materiaal met naam "rood",
15    en kent hieraan de "base color" (1,0,0) toe. Dit is een tuple
16    dat een RGB-kleur voorstelt, met de rood component op 1 en 
17    de andere componenten op 0. Dus, puur rood.
18    > add_material(obj, "rood", (1,0,0))
19    """
20    material = bpy.data.materials.get(material_name)
21    if material is None:
22        material = bpy.data.materials.new(material_name)
23    material.use_nodes = True
24    principled_bsdf = material.node_tree.nodes["Principled BSDF"]
25    if principled_bsdf is not None:
26        principled_bsdf.inputs[0].default_value = (*color, 1)
27        principled_bsdf.inputs[6].default_value = metallic
28        principled_bsdf.inputs[9].default_value = roughness
29    obj.active_material = material
30
31
32# Open een CSV een lees regel voor regel
33# f = ...
34# reader = ...
35# nr = 0
36# x = 0
37
38for ...
39    # om het debuggen te vereenvoudigen tekenen we enkel de eerste x gebouwen
40    if nr > 10:
41        break
42
43    # bepaal de hoogte van het gebouw
44    height = ...
45
46    # plaats hier een cubus per gebouw
47    # gebruik parameter scale=(1,1,height) om de hoogte van de kubus aan te passen
48    # pas location aan
49    bpy.ops.mesh.primitive_cube_add(
50            size=1, location=(x, ...), scale=...
51        )
52
53    # gebruik een variabele om naar het actieve object te verwijzen
54    obj = bpy.context.object
55
56    # Voeg hier een materiaal aan je kubus toe, zodat je kubus een basis
57    # kleur heeft. De kleuren druk je uit als RGB tuple, dus (rood, groen, blauw).
58    # Geef verder als roughness, 0.2 op, en zet metallic op 1.
59    # Gebruik als kleur bijvoorbeeld de volgende waardes:
60    # - rood: 0.83
61    # - groen: 0.68
62    # - blauw: 0.22
63    # add_material(obj, ...)
64
65    # update x zodat de kubussen naast elkaar staan
_images/build033.png

1.7 Opgave: Animeren van de hoogte van de kubus

 1import csv
 2import bpy
 3
 4
 5# Open een CSV een lees regel voor regel
 6# f = ...
 7# reader = ...
 8# nr = 0
 9# x = 0
10
11for ...
12    # om het debuggen te vereenvoudigen tekenen we enkel de eerste x gebouwen
13    if nr > 10:
14        break
15
16    # bepaal de hoogte van het gebouw
17    height = ...
18
19    # plaats hier een cubus per gebouw
20    # we gebruiken parameter scale=(1,1,1) om de hoogte van de kubus
21    # in te stellen op de standaardgrootte
22    # pas location aan
23    bpy.ops.mesh.primitive_cube_add(
24            size=1, location=(x, ...), scale=...
25        )
26
27    # makkelijkere toegang tot het actieve object
28    obj = bpy.context.object
29
30    # voeg een keyframe toe op frame 1 voor de huidige "scale" (is nu (1,1,1))
31    # obj.keyframe_insert...
32
33    # voeg een keyframe toe op frame 48 voor de juiste "scale" (is nu (1,1,height))
34    # obj.scale = 
35    # obj.keyframe_insert...
36
37    # update x zodat de kubussen naast elkaar staan
_images/build04.webm

1.8 Opgave: Correctie z-positie kubus bij animatie

 1import csv
 2import bpy
 3
 4
 5# Open een CSV een lees regel voor regel
 6# f = ...
 7# reader = ...
 8# nr = 0
 9# x = 0
10
11for ...
12    # om het debuggen te vereenvoudigen tekenen we enkel de eerste x gebouwen
13    if nr > 10:
14        break
15
16    # bepaal de hoogte van het gebouw
17    height = ...
18
19    # plaats hier een cubus per gebouw
20    # we gebruiken parameter scale=(1,1,1) om de hoogte van de kubus
21    # in te stellen op de standaardgrootte
22    # pas location aan
23    bpy.ops.mesh.primitive_cube_add(
24            size=1, location=(x, ...), scale=...
25        )
26
27    # makkelijkere toegang tot het actieve object
28    obj = bpy.context.object
29
30    # voeg een keyframe toe op frame 1 voor de huidige "scale" (is nu (1,1,1))
31    # obj.keyframe_insert...
32    # voeg nog keyframe toe op frame 1 voor de huidige "location"
33    # obj.keyframe_insert...
34
35    # voeg een keyframe toe op frame 48 voor de juiste "scale" (is nu (1,1,height))
36    # obj.scale = 
37    # obj.keyframe_insert...
38    # voeg een keyframe toe op frame 48 voor de juiste "location"
39
40    # update x zodat de kubussen naast elkaar staan
_images/build05.webm