motiv-ground

Übersicht: Python & Blender


Objectives

a

What can be modeled? The most common motif are landscapes with the following objects that we want to create in some cases:

  • Clouds
  • Stones
  • Trees
  • Gras
  • Water
  • Mountains/landscape

Instructions

Tasks:
  1. Change the parameters!
  2. How about wells with water?
  3. How can get/create a snowy mountain?

Example:

How can a script gnereate a mountains like the - yellow and orange parts of the image, what looks like the Uluṟu . Soon we are smarter ...

/use-cases/art/low-poly/landscape.png

Template

Again we are using a class as a starting point.

use-cases/art/low-poly/landscape-skel.py (Source)

#!bpy
"""
Name: 'Landscape-Generator'
Blender: 2.7x
Group: 'Low poly'
Tooltip: 'Part of a Low-Poly-Skripts collection'
"""
import bpy


class Landscape():
    """Create a landscape as low poly"""

    def __init__(self):
        pass

    def setColor(self):
        pass

    def new(self):
        """ constuction of a new landscape """
        pass

    def remove(self):
        """ Delete a landscape or all"""
        pass

if __name__ == "__main__":

    # switch to object mode, if nessasary
    if bpy.ops.object.mode_set.poll():
        bpy.ops.object.mode_set(mode='OBJECT')
    ground = Landscape()

The Ground

We are starting with a plane and increase the number of units to 100x100.

use-cases/art/low-poly/landscape.py (Source)

        """ constuction of a new landscape """
        scn = bpy.context.scene
        bpy.ops.mesh.primitive_plane_add(location=(0, 0, 0))
        obj = bpy.context.object
        obj.scale[0] = 100
        obj.scale[1] = 100
        obj.name = "ground"

A small earsquacke

We divide the ground multiple times and to get some randomness we use the parameter fractal. It is only a small erathquake because we are moving only a few point a little bit.

use-cases/art/low-poly/landscape.py (Source)

        val = 1
        for i in range(1, 5):
            val = val + random.randint(1, 3)
            bpy.ops.mesh.subdivide(fractal=val)

The hill

A smaller part of the ground should be higher and we do this with multiple steps. We using a bmesh to manipulate the koordinates.

use-cases/art/low-poly/landscape.py (Source)

        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.select_all(action='TOGGLE')
        bpy.ops.object.editmode_toggle()
        me = obj.data
        i = random.randint(0, len(me.vertices))
        obj.data.vertices[i].select = True
        bpy.ops.object.mode_set(mode='EDIT')
        for i in range(5):
            bpy.ops.mesh.select_more()

        bm = bmesh.from_edit_mesh(obj.data)
        for vertex in bm.verts:
            if vertex.select:
                vertex.co.z += 11

        bmesh.update_edit_mesh(obj.data)
        bpy.ops.transform.resize(value=(.9, .9, 0))

        for vertex in bm.verts:
            if vertex.select:
                vertex.co.z += 15

        bmesh.update_edit_mesh(obj.data)
        bpy.ops.transform.resize(value=(.8, .8, 0))

The hole script

use-cases/art/low-poly/landscape.py (Source)

#!bpy
"""
Name: 'Landscape-Generator'
Blender: 2.7x
Group: 'Low poly'
Tooltip: 'Part of a Low-Poly-Skripts collection'
"""
import bpy
import random
import bmesh

class Landscape():
    """Create a landscape as low poly"""

    def __init__(self):
        self.top = 0

    def setColor(self, obj, material, color):
        material.diffuse_color = color
        material.specular_hardness = 200
        obj.data.materials.append(material)

    def new_area(self):
        """ constuction of a new landscape """
        scn = bpy.context.scene
        bpy.ops.mesh.primitive_plane_add(location=(0, 0, 0))
        obj = bpy.context.object
        obj.scale[0] = 100
        obj.scale[1] = 100
        obj.name = "ground"
        bpy.ops.object.mode_set(mode='EDIT')
        val = 1
        for i in range(1, 5):
            val = val + random.randint(1, 3)
            bpy.ops.mesh.subdivide(fractal=val)
        bpy.ops.object.mode_set(mode='OBJECT')
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.select_all(action='TOGGLE')
        bpy.ops.object.editmode_toggle()
        me = obj.data
        i = random.randint(0, len(me.vertices))
        obj.data.vertices[i].select = True
        bpy.ops.object.mode_set(mode='EDIT')
        for i in range(5):
            bpy.ops.mesh.select_more()

        bm = bmesh.from_edit_mesh(obj.data)
        for vertex in bm.verts:
            if vertex.select:
                vertex.co.z += 11

        bmesh.update_edit_mesh(obj.data)
        bpy.ops.transform.resize(value=(.9, .9, 0))

        for vertex in bm.verts:
            if vertex.select:
                vertex.co.z += 15

        bmesh.update_edit_mesh(obj.data)
        bpy.ops.transform.resize(value=(.8, .8, 0))

    def remove(self, name=None):
        """ Delete a ground or all"""

        if name:
            bpy.ops.object.select_pattern(pattern=name)
        else:
            bpy.ops.object.select_pattern(pattern="ground*")

        bpy.ops.object.delete()


if __name__ == "__main__":

    # switch to object mode, if nessasary
    if bpy.ops.object.mode_set.poll():
        bpy.ops.object.mode_set(mode='OBJECT')
    ground = Landscape()
    ground.remove()
    ground.new_area()

Comments