This plugin serves two purposes:
- Transform meshes with seams into clothsim-ready sewing patterns, for easy iteration.
- Export the resulting sewing patterns for printing and sewing irl.
Version 0.7 brings with it remeshing, based on the Boundary Aligned Remesh plugin.
This means that even with very uneven geometry, your resulting sewing pattern with have nice, even triangular geometry. This is important for simulation.
A quick how to:
-
Add seams to the mesh you wish to turn into a sewing pattern.
Use the knife tool to add additional cuts for seams if needed. -
Go to
Object > Seams to Sewing Pattern > Seams to Sewing Pattern
-
Choose
Remesh
if you want, and set your target number of triangles.
A small countdown appears next to the cursor. -
Go to
Object > Seams to Sewing Pattern > Quick Clothsim
to quickly setup a clothsim modifier with the standard parameters. -
Simulate, and watch your mesh assemble!
Development now happens on Gitlab. If you can contribute anything, feel free to do so!
SeamsToSewingPattern.zip (version 0.9, for Blender 2.8 and 2.9) (15.3 KB)
Changelog
v 0.7
Hooray, remeshing!
v 0.6
Script is neatly broken up into different parts, and now supports exporting sewing patterns to SVG
v 0.5:
Long (non-square-ish) UV islands would appear offset when unfolded.
This is now fixed.
v 0.4:
Should now work with both blender 2.8 and 2.9
v 0.3:
Added a āprogress barā to avoid annoyance
v 0.2:
Actually a plugin you can install via a zip
v 0.1:
Initial version of a script
Old versions
v 0.6:
SeamsToSewingPattern.zip (version 0.6, for Blender 2.8 and 2.9) (6.0 KB)
v 0.5:
SeamsToSewingPattern.zip (version 0.5, for Blender 2.8 and 2.9) (2.7 KB)
v 0.4:
SeamsToSewingPattern.zip (version 0.4, for Blender 2.8 and 2.9) (2.7 KB)
v 0.3:
SeamsToSewingPattern.zip (version 0.3, for Blender 2.8) (2.1 KB)
v 0.2:
SeamsToSewingPattern.zip (version 0.2, for Blender 2.8) (2.0 KB)
v 0.1:
Hereās the first iteration of a script I wrote that turns a mesh, with seams, into a sewing pattern that can be used for cloth sim.
This is especially handy for creating stuffed animals / shaped balloons
Version 0.1 is super dumb, and has no error handling.
Your input should be a mesh with UV seams. It will create a sewing pattern from a UV layout, and then put it back roughly where the original geometry was.
It will also create sewing lines, which you can use in your clothsim to stitch them together,
import bpy
import bmesh
import mathutils
import math
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
obj = bpy.context.edit_object
me = obj.data
bpy.ops.mesh.select_mode(type="EDGE")
# select all seams
bm = bmesh.from_edit_mesh(me)
for e in bm.edges:
if e.seam:
e.select = True
bpy.ops.mesh.bevel(vertex_only=False, offset=0.001)
bpy.ops.mesh.delete(type='ONLY_FACE')
bpy.ops.mesh.select_mode(type="FACE")
faceGroups = []
# isolate all face islands, and UV unwrap each island
faces = set(bm.faces[:])
while faces:
bpy.ops.mesh.select_all(action='DESELECT')
face = faces.pop()
face.select = True
bpy.ops.mesh.select_linked()
selected_faces = {f for f in faces if f.select}
selected_faces.add(face) # this or bm.faces above?
faceGroups.append(selected_faces)
faces -= selected_faces
bpy.ops.uv.unwrap()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.uv.select_all(action='SELECT')
bmesh.update_edit_mesh(me, False)
uv_layer = bm.loops.layers.uv.active
for g in faceGroups:
previous_area = 0
bpy.ops.mesh.select_mode(type='FACE')
bpy.ops.mesh.select_all(action='DESELECT')
average_position = mathutils.Vector((0,0,0))
facenum = 0
average_normal = mathutils.Vector((0,0,0))
# calculate the area, average position, and average normal
for f in g:
f.select = True
previous_area += f.calc_area()
average_position += f.calc_center_median()
average_normal += f.normal
facenum += 1
average_normal.normalize()
average_position /= facenum
average_tangent = mathutils.Vector((0,0,0))
average_bitangent = mathutils.Vector((0,0,0))
# calculate a rough tangent and a bitangent
for face in g:
for loop in face.loops:
uv = loop[uv_layer].uv
delta = loop.vert.co - average_position
average_tangent += delta * (uv.x - 0.5)
average_bitangent += delta * (uv.y - 0.5)
# reorient the tangent and bitangent
average_normal = average_normal.normalized()
average_tangent = average_tangent.normalized()
average_bitangent = average_bitangent.normalized()
halfvector = average_bitangent + average_tangent
halfvector /= 2
halfvector.normalize()
#straighten out half vector
halfvector = average_normal.cross(halfvector)
halfvector = average_normal.cross(halfvector)
cw = mathutils.Matrix.Rotation(math.radians(45.0), 4, average_normal)
ccw = mathutils.Matrix.Rotation(math.radians(-45.0), 4, average_normal)
average_tangent = mathutils.Vector(halfvector)
average_tangent.rotate(ccw)
average_bitangent = mathutils.Vector(halfvector)
average_bitangent.rotate(cw)
# offset each face island by their UV value, using the tangent and bitangent
for face in g:
for loop in face.loops:
uv = loop[uv_layer].uv
vert = loop.vert
pos = mathutils.Vector((0,0,0))
pos += average_position
pos += average_tangent * -(uv.x - 0.5)
pos += average_bitangent * -(uv.y - 0.5)
pos += average_normal * 0.3 #arbitrary - should probably depend on object scale?
vert.co = pos;
bmesh.update_edit_mesh(me, False)
#resize to match previous area
new_area = sum(f.calc_area() for f in g)
area_ratio = previous_area / new_area
area_ratio = math.sqrt(area_ratio)
bpy.ops.transform.resize(value=(area_ratio, area_ratio, area_ratio))
# done
bmesh.update_edit_mesh(me, False)
bpy.ops.mesh.select_all(action='SELECT')
Have fun with this first version, let me know if you make something with it!
Todo
Feature | State | Remarks |
---|---|---|
Align islands to average face tangent and bitangent | Done | So that they appear upright in place |
Notify the user of progress | Done | |
Make it zip-installable | Done | |
Align islands to the center | Done | strange UV shapes can appear offset |
Export Sewing Pattern | in progress | Similar to the Export UVās plugin |
Add options menu | Todo | |
Create a temporary UV channel the process | todo | It overrides the active one for now |
Make it an option to check stretching beforehand | nth | |
Retopologize UV islands | Done | maybe using the ātriangleā library |
Twist seams | nth | offset each sewing edge by 1 or 2 to twist the part a bit, for realism |