Pages

Wednesday, March 12, 2014

MODIFIER x PYTHON Lattice Modifier

The Love For Lattice


Lattice Modifier in Blender is another interesting modifier that people may or may not use regularly. I think the Lattice deserves a bit more love.

Oh, Lattice, why you so complicated?
NOTE: Lots of modifiers in Blender works amazingly well, although sometimes the magic is a little bit obscured. Unless you read a little bit of documentation.

CIRCULAR RAMP USING LATTICE MODIFIER
The other day, someone asked on Blender Facebook page on how to create a Semi-Circular Ramp for architecture modeling that goes 1/4 Circle. It was an interesting question, so I decided to give an answer.

My first solution is like this:
1. Draw 1/4 Circle.
I am using Poly Circle first, delete 3/4 of the Circle, and then I convert it to actual Curve object in Blender.


We can easily "Extrude" the Curve path to get actual Path, instead of just curve. I tilt the Path 90 degree so that it is more correct.

2. Apply Lattice Modifier to create Ramp.
Now, Lattice Modifier in Blender is a little bit weird because we need to create a Lattice object separately first of all, before we are able to use the Lattice Modifier.


The Lattice itself is free in 3D space. We need to edit the shape inside Edit Mode and tweak the Property under Property Panel. This is done manually to match the bounding box of our object to be influenced.


Once you get the Lattice in place, that is when we can simply reference the Lattice for Lattice Modifier.

We can choose between BSpline, Cardinal, or Linear for the Lattice Modifier to get the effect we want.


The cool thing about Blender Lattice is that we can change the division number of UVW, at any time. Really handly.

CIRCULAR RAMP USING SCREW MODIFIER (EASIER AND SUFFICIENT)
A second solution, perhaps easier way is actually just using Screw Modifier. Probably lest control, but it does a perfect ramp. Except that we probably dont have much control on the Ramp beginning and end.

1. Start by drawing a polygon edge:

2. Then apply Screw Modifier to the edge.
It goes a bit weird at first, but no worries, Modifier is LIVE so we can always tweak and modify the input and getting the right output.

3. Tweak the Screw Modifier
I like using Empty whenever we need "Object" as reference for modifier. So I created an Empty in 3D scene. Adjust the location of Empty and assign it as AxisOb (Axis Object) of Screw Modifier. From here, everything is pretty intuitive.

For the ramp, we just need 90 degree circle, actually. So this will do the job.



This should work and pretty adjustable up to certain extend. And work together with Solidify Modifier if we want thickness on the ramp.



LATTICE AND PYTHON
Now, back to our friend Lattice Deformer...

So, what is wrong with Blender Lattice Deformer? Lattice is an Object that is created separately from the Lattice Deformer. You must create Lattice and then point Lattice Deformer to it.


http://wiki.blender.org/index.php/Doc:2.6/Tutorials/Modifiers/Lattice/Shaping_a_Fork


I think the workflow is a little quirky. Lots of steps required just to setup Lattice Modifier. Why cant the Lattice be confirmed into an Object dimension for example?

Lets try to make the workflow easier using Python.

1. Start with a Cylinder that I have subdivided in height a few times, rotate in arbitrary angle




2. Next, we want Lattice that is confirming our object, which is the Cylinder in our case.

How to do this manually?
We can apply the Dimension as Scale of Lattice and apply Rotation of our object as the Rotation of Lattice. Copy position of our object to Lattice as well, we can simply copy and paste it, but only if our object origin is at center, this is not always true.

Constraint way?
We can use Rotation Constraint. Location Constraint works, but again, only if origin of our object is at the center of origin, otherwise Lattice wont be at the correct place.

Python way?
We can use Python.

My proposition is to create a Python script that does all the steps below to our selected object:
1. Create Lattice Object
2. Confirm Lattice into our object
3. Assign Lattice Deformer
4. Setup the Lattice Deformer

BLENDER SUSHI SCRIPT: Confirm Lattice Object into Selected Object as Lattice Modifier


import bpy


Created by Jimmy Gunawan
Last update: 20130422
Original Source: Blender Sushi

FUNCTION:
Automatically create and confirm Lattice position to selected object as Lattice Modifier.

HOW TO USE:
1. Select a mesh that you like to be Latticed
2. Run the script
3. Select Lattice, go to Edit Mode, deform the object
4. Under Lattice Object Data Property, you also have extra options for Lattice object.



object = bpy.context.active_object
object_name = object.name


# Get Rotation of active object
rotXYZ = object.rotation_euler

# Get Dimension of active object
dimensionXYZ = object.dimensions

# REFERENCE:
# http://blenderscripting.blogspot.com.au/2011/05/blender-25-python-moving-object-origin.html
# https://github.com/davidejones/alternativa3d_tools/issues/1

# Snap Cursor to Active
original_type = bpy.context.area.type
bpy.context.area.type = "VIEW_3D"
bpy.ops.view3d.snap_cursor_to_active()
bpy.context.area.type = original_type

# Save the current location of our object origin
saved_location = bpy.context.scene.cursor_location.copy() # returns a copy of the vector

# Snap origin to geometry center median
bpy.ops.object.origin_set(type=ORIGIN_GEOMETRY, center=MEDIAN)

# Snap Cursor to Active Again
original_type = bpy.context.area.type
bpy.context.area.type = "VIEW_3D"
bpy.ops.view3d.snap_cursor_to_active()
bpy.context.area.type = original_type

# Get Current Origin
center_location = bpy.context.scene.cursor_location.copy()

# Put Cursor Back At Original Location of Object Origin
bpy.context.scene.cursor_location = saved_location

# Set the origin on the current object to the 3dcursor location
bpy.ops.object.origin_set(type=ORIGIN_CURSOR)

# Add and place our Lattice
bpy.ops.object.add(type=LATTICE, view_align=False, enter_editmode=False, location=center_location, rotation=rotXYZ)

# Get Our Lattice
lattice = bpy.context.active_object
lattice_name = lattice.name

# Scale Lattice to Dimension of Object
lattice.scale = dimensionXYZ

# Return our object as active
bpy.context.scene.objects.active = bpy.data.objects[object_name]

# Apply Lattice Modifier
bpy.ops.object.modifier_add(type=LATTICE)
bpy.data.objects[object_name].modifiers["Lattice"].object = bpy.data.objects[lattice_name]



NOTE: For object that is "Flat", one of the Lattice axis becoming ZERO and you probably need to turn the Scale back to 1 and making one of Lattice UVW axis to value of 1. You dont want zero value in Lattice object scale, otherwise, you will not be able to Translate perpendicularly in that axis.

With that script above, hopefully, you can now use Lattice Modifier more often for your modeling needs with no sweat.

Lattice is now easy.
HOOK IT (CTRL+H):
Ever "Points" of Lattice can actually be hooked (go to Edit Mode, select Point and CTRL+H), just like mesh "Vertices" can be hooked. This will give the ability for animator to animate Lattice Points in Object Mode.

BLENDER SUSHI SCRIPT: Hook every Lattice Points (All or Outside Only)


import bpy

object = bpy.context.active_object
object_name = object.name
points = bpy.context.active_object.data.points

# Deselect and select all points (that are visible)
bpy.ops.object.mode_set(mode = EDIT)
bpy.ops.lattice.select_all(action = SELECT)

# Need to do this refresh to get rid of Inside points if needed
if (bpy.context.object.data.use_outside):
bpy.context.object.data.use_outside = False
bpy.context.object.data.use_outside = True

# Get List of Points
selected_points = []
selected_points = [points[i] for i in range(len(points)) if points[i].select == True]

# Create Hook for every specified Points
for point in selected_points:
#bpy.ops.object.mode_set(mode = EDIT)
bpy.ops.lattice.select_all(action = DESELECT)
point.select = True
#bpy.ops.object.mode_set(mode = EDIT)
bpy.ops.object.hook_add_newob()

# Switch ack to Object mode and deselect all
bpy.ops.object.mode_set(mode = OBJECT)
bpy.ops.object.select_all(action=DESELECT)









BLENDER SUSHI SCRIPT: Hook every Mesh Vertices (BONUS)


import bpy

object = bpy.context.active_object
object_name = object.name
vertices = bpy.context.active_object.data.vertices

for i in range(len (vertices)):

bpy.ops.object.mode_set(mode = OBJECT)
bpy.context.scene.objects.active = bpy.data.objects[object_name]

# Deselect everything
bpy.ops.object.mode_set(mode = EDIT)
bpy.ops.mesh.select_all(action = DESELECT)

bpy.ops.object.mode_set(mode = OBJECT)

# Select one vertex iteratively
vertices[i].select = True
bpy.ops.object.mode_set(mode = EDIT)
bpy.ops.object.hook_add_newob()
vertices[i].select = False

# bpy.ops.object.mode_set(mode = EDIT)
#bpy.ops.transform.translate(value=(-0.145401, 0.411997, 0.196826), constraint_axis=(False, False, False), constraint_orientation=GLOBAL, mirror=False, proportional=DISABLED, proportional_edit_falloff=SMOOTH, proportional_size=1, snap=False, snap_target=CLOSEST, snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), texture_space=False, release_confirm=False)


# Deselect everything
#bpy.ops.object.mode_set(mode = EDIT)
#bpy.ops.mesh.select_all(action = DESELECT)






Are you hooked by Lattice yet?


EVEN AWESOMER: SOFT IT
Apply Soft Body into Lattice and apply Force to it. Such as Turbulance maybe?

Instance procedural jiggle distortion Lattice thing:
Suzanne inside Distortion Lattice
EVEN MORE AWESOME: BULLET IT (?) OR PARTICLE IT?
In theory, one can probably create some kind of setup that is using Blender Bullet Physics hooked into Lattice that deform the object.

I might be wrong. But deep thinking in term of Points component and having Points ability to deform thing may result in something interesting.

Maybe its not really a job for Lattice, more like a hacky stuff. Anyways, I leave that for one day, just a note to self.

UPDATE 20130505:
See also:
http://blenderartists.org/forum/showthread.php?290925-Easy-Lattice-editing-addon-you-are-going-to-like-the-way-you-lattice

Related Posts by Categories

0 comments:

Post a Comment