Blenderyard

October 17, 2014

Contour lines as in maps

Filed under: Blender, Freestyle — blenderyard @ 4:40 PM

slices_suzanne_tn

This is a quick proof-of-concept render of contour lines (as in geographical maps) drawn by Freestyle in Blender.  The contour lines are genuine edges in mesh data annotated by Freestyle edge marks.  These edges were auto-generated by a script based on the Intersect mesh-editing command (new in 2.72) to identify contour lines, i.e., cross-section lines with a plane at different heights at a regular interval.

# slices.py

import bpy
import math
from mathutils import Vector

def exec_slices(context, interval):
    print('interval', interval)

    ob = context.active_object
    ob.update_from_editmode()
    print('ob.name', ob.name)

    rad = max(Vector(point).length for point in ob.bound_box)
    print('rad', rad)

    zmin = min(point[2] for point in ob.bound_box)
    zmax = max(point[2] for point in ob.bound_box)
    print('zmin', zmin, 'zmax', zmax)

    imin = int(math.ceil(zmin / interval))
    imax = int(math.floor(zmax / interval))
    zvals = [i * interval for i in range(imin, imax+1)]
    print('zvals', zvals)

    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.object.vertex_group_add()

    rot = Vector((0.0, 0.0, 0.0))
    for z in zvals:
        loc = Vector((0.0, 0.0, z)) + ob.location
        do_slice(rad, loc, rot)

    bpy.ops.object.vertex_group_remove(all=False)
    bpy.ops.object.mode_set(mode='OBJECT')

def do_slice(rad, loc, rot):
    bpy.ops.mesh.primitive_plane_add(radius=rad, location=loc, rotation=rot)

    bpy.ops.object.vertex_group_assign()

    bpy.ops.mesh.intersect()
    bpy.ops.mesh.remove_doubles()
    bpy.ops.mesh.mark_freestyle_edge()
    bpy.ops.mesh.select_all(action='DESELECT')

    bpy.ops.object.vertex_group_select()

    bpy.ops.mesh.delete(type='VERT')

class Slices(bpy.types.Operator):
    """Slices"""
    bl_idname = "object.slices"
    bl_label = "Slices"
    bl_options = {'REGISTER', 'UNDO'}

    interval = bpy.props.FloatProperty(name="Slice Interval", default=1.0, min=0.01, max=100)

    @classmethod
    def poll(cls, context):
        ob = context.active_object
        return ob is not None and ob.type == 'MESH'

    def execute(self, context):
        exec_slices(context, self.interval)
        return {'FINISHED'}

def register():
    bpy.utils.register_class(Slices)

def unregister():
    bpy.utils.unregister_class(Slices)

if __name__ == "__main__":
    register()

    # test call
    bpy.ops.object.slices(interval=0.1)
Advertisements

7 Comments »

  1. hello!

    great look, im trying this cross contour look without luck.

    can you tell me how to use this script? this is exactly what I’m looking for, but I’m a bit lost.
    thanks and best

    Comment by fabian — January 8, 2015 @ 5:10 PM

    • Thanks for your interest in the blog post. The code aims to help you create extra edges that represent contour lines.

      You need to copy the code and paste it in the text editor in Blender. Then select a mesh object and execute the code (e.g., by pressing the “Run Script” button). This will lead to the definition of an operator called Slices. As a side effect, the code execution also causes the insertion of contour edges in the active mesh object.

      After the first execution of the script, you can invoke the script from the spacebar menu in the 3D view window by typing the operator name “Slices”. In this case, you can adjust the interval of slices afterwards through the operator parameter window (at the bottom of the tool shelf in the 3D view).

      HTH,
      T.K.

      Comment by blenderyard — January 11, 2015 @ 5:14 PM

  2. Hi. And thanks for this great script – just what I was looking for! – I noticed one thing though. You have to make sure that the mesh is in Vertex selection mode (go into edit mode, switch to vertex selection, then back to object mode) before running. I did it a couple of times while my mesh was in Face selection – then it does the intersection and creates the new faces but then it does not apply the Freestyle stroke edge annotations to the new edges.

    Thanks again!

    James

    Comment by James Hoyland — February 11, 2015 @ 12:41 AM

    • I was not aware of that pitfall. Thanks for the heads up!

      Comment by blenderyard — February 11, 2015 @ 12:16 PM

  3. Oh! Thank you for code and idea!
    I searching something like this for my drawing robot project:

    Comment by peko — March 12, 2015 @ 11:27 AM

  4. Great script, I’m gonna try it straight away. But before doing so, I’d like to draw your attention to this (allright: my) question on StackExchange: http://blender.stackexchange.com/questions/30542/show-banding-on-object/30548#30548 There, we reach the same effect using the node editor of cycles materials.

    Comment by ideogramprivee — May 29, 2015 @ 2:52 PM

  5. Excellent Script. Is there any way to isolate the individual contours and PRINT them directly in Blender?

    Comment by Steve — August 26, 2015 @ 9:04 PM


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: