Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mesh_tissue/lattice.py')
-rw-r--r--mesh_tissue/lattice.py334
1 files changed, 208 insertions, 126 deletions
diff --git a/mesh_tissue/lattice.py b/mesh_tissue/lattice.py
index 685d5664..737b4c87 100644
--- a/mesh_tissue/lattice.py
+++ b/mesh_tissue/lattice.py
@@ -15,8 +15,8 @@
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
-#---------------------------- LATTICE ALONG SURFACE ---------------------------#
-#--------------------------------- version 0.3 --------------------------------#
+# --------------------------- LATTICE ALONG SURFACE -------------------------- #
+# -------------------------------- version 0.3 ------------------------------- #
# #
# Automatically generate and assign a lattice that follows the active surface. #
# #
@@ -25,10 +25,7 @@
# #
# http://www.co-de-it.com/ #
# #
-################################################################################
-
-import bpy, bmesh
-from mathutils import Vector, Matrix
+# ############################################################################ #
bl_info = {
"name": "Lattice",
@@ -39,10 +36,19 @@ bl_info = {
"description": "Generate a Lattice based on a grid mesh",
"warning": "",
"wiki_url": "",
- "tracker_url": "",
"category": "Mesh"}
+import bpy
+import bmesh
+from bpy.types import Operator
+from bpy.props import (
+ BoolProperty,
+ FloatProperty,
+ )
+from mathutils import Vector
+
+
def not_in(element, grid):
output = True
for loop in grid:
@@ -51,6 +57,7 @@ def not_in(element, grid):
break
return output
+
def grid_from_mesh(mesh, swap_uv):
bm = bmesh.new()
bm.from_mesh(mesh)
@@ -66,21 +73,27 @@ def grid_from_mesh(mesh, swap_uv):
# storing first point
verts_candidates = []
- if len(faces_grid) == 0: verts_candidates = bm.verts # for first loop check all vertices
- else: verts_candidates = [v for v in bm.faces[faces_grid[-1][0]].verts if not_in(v.index, verts_grid)] # for other loops start form the vertices of the first face the last loop, skipping already used vertices
+ if len(faces_grid) == 0:
+ # for first loop check all vertices
+ verts_candidates = bm.verts
+ else:
+ # for other loops start form the vertices of the first face
+ # the last loop, skipping already used vertices
+ verts_candidates = [v for v in bm.faces[faces_grid[-1][0]].verts if not_in(v.index, verts_grid)]
# check for last loop
is_last = False
for vert in verts_candidates:
- if len(vert.link_faces) == 1: # check if corner vertex
+ if len(vert.link_faces) == 1: # check if corner vertex
vert.select = True
verts_loop.append(vert.index)
is_last = True
break
+
if not is_last:
for vert in verts_candidates:
new_link_faces = [f for f in vert.link_faces if not_in(f.index, faces_grid)]
- if len(new_link_faces) < 2: # check if corner vertex
+ if len(new_link_faces) < 2: # check if corner vertex
vert.select = True
verts_loop.append(vert.index)
break
@@ -92,26 +105,30 @@ def grid_from_mesh(mesh, swap_uv):
id = verts_loop[-1]
link_edges = bm.verts[id].link_edges
# storing second point
- if len(verts_loop) == 1: # only one vertex stored in the loop
- if len(faces_grid) == 0: ### first loop ###
- edge = link_edges[swap_uv] # chose direction
+ if len(verts_loop) == 1: # only one vertex stored in the loop
+ if len(faces_grid) == 0: # first loop #
+ edge = link_edges[swap_uv] # chose direction
for vert in edge.verts:
if vert.index != id:
vert.select = True
- verts_loop.append(vert.index) # new vertex
- edges_loop.append(edge.index) # chosen edge
- faces_loop.append(edge.link_faces[0].index) # only one face
- #edge.link_faces[0].select = True
- else: ### other loops ###
- for edge in bm.faces[faces_grid[-1][0]].edges: # start from the edges of the first face of the last loop
- if bm.verts[verts_loop[0]] in edge.verts and bm.verts[verts_grid[-1][0]] not in edge.verts: # chose an edge starting from the first vertex that is not returning back
+ verts_loop.append(vert.index) # new vertex
+ edges_loop.append(edge.index) # chosen edge
+ faces_loop.append(edge.link_faces[0].index) # only one face
+ # edge.link_faces[0].select = True
+ else: # other loops #
+ # start from the edges of the first face of the last loop
+ for edge in bm.faces[faces_grid[-1][0]].edges:
+ # chose an edge starting from the first vertex that is not returning back
+ if bm.verts[verts_loop[0]] in edge.verts and \
+ bm.verts[verts_grid[-1][0]] not in edge.verts:
for vert in edge.verts:
if vert.index != id:
vert.select = True
verts_loop.append(vert.index)
edges_loop.append(edge.index)
+
for face in edge.link_faces:
- if not_in(face.index,faces_grid):
+ if not_in(face.index, faces_grid):
faces_loop.append(face.index)
# continuing the loop
else:
@@ -121,7 +138,8 @@ def grid_from_mesh(mesh, swap_uv):
if not_in(vert.index, verts_grid) and vert.index not in verts_loop:
if len(faces_loop) > 0:
bm.faces.ensure_lookup_table()
- if vert not in bm.faces[faces_loop[-1]].verts: store_data = True
+ if vert not in bm.faces[faces_loop[-1]].verts:
+ store_data = True
else:
store_data = True
if store_data:
@@ -133,79 +151,108 @@ def grid_from_mesh(mesh, swap_uv):
faces_loop.append(face.index)
break
# ending condition
- if verts_loop[-1] == id or verts_loop[-1] == verts_loop[0]: running_loop = False
+ if verts_loop[-1] == id or verts_loop[-1] == verts_loop[0]:
+ running_loop = False
verts_grid.append(verts_loop)
edges_grid.append(edges_loop)
faces_grid.append(faces_loop)
- if len(faces_loop) == 0: running_grid = False
+
+ if len(faces_loop) == 0:
+ running_grid = False
+
return verts_grid, edges_grid, faces_grid
-class lattice_along_surface(bpy.types.Operator):
+
+class lattice_along_surface(Operator):
bl_idname = "object.lattice_along_surface"
bl_label = "Lattice along Surface"
bl_description = ("Automatically add a Lattice modifier to the selected "
"object, adapting it to the active one.\nThe active "
"object must be a rectangular grid compatible with the "
- "Lattice's topology.")
+ "Lattice's topology")
bl_options = {'REGISTER', 'UNDO'}
- set_parent = bpy.props.BoolProperty(
- name="Set Parent", default=True,
- description="Automatically set the Lattice as parent")
-
- flipNormals = bpy.props.BoolProperty(
- name="Flip Normals", default=False,
- description="Flip normals direction")
-
- swapUV = bpy.props.BoolProperty(
- name="Swap UV", default=False,
- description="Flip grid's U and V")
-
- flipU = bpy.props.BoolProperty(
- name="Flip U", default=False,
- description="Flip grid's U")
-
- flipV = bpy.props.BoolProperty(
- name="Flip V", default=False,
- description="Flip grid's V")
-
- flipW = bpy.props.BoolProperty(
- name="Flip W", default=False,
- description="Flip grid's W")
-
- use_groups = bpy.props.BoolProperty(
- name="Vertex Group", default=False,
- description="Use active Vertex Group for lattice's thickness")
-
- high_quality_lattice = bpy.props.BoolProperty(
- name="High quality", default=True,
- description="Increase the the subdivisions in normal direction for a "
- "more correct result")
-
- hide_lattice = bpy.props.BoolProperty(
- name="Hide Lattice", default=True,
- description="Automatically hide the Lattice object")
-
- scale_x = bpy.props.FloatProperty(
- name="Scale X", default=1, min=0.001,
- max=1, description="Object scale")
-
- scale_y = bpy.props.FloatProperty(
- name="Scale Y", default=1, min=0.001,
- max=1, description="Object scale")
-
- scale_z = bpy.props.FloatProperty(
- name="Scale Z", default=1, min=0.001,
- max=1, description="Object scale")
-
- thickness = bpy.props.FloatProperty(
- name="Thickness", default=1, soft_min=0,
- soft_max=5, description="Lattice thickness")
-
- displace = bpy.props.FloatProperty(
- name="Displace", default=0, soft_min=-1,
- soft_max=1, description="Lattice displace")
+ set_parent = BoolProperty(
+ name="Set Parent",
+ default=True,
+ description="Automatically set the Lattice as parent"
+ )
+ flipNormals = BoolProperty(
+ name="Flip Normals",
+ default=False,
+ description="Flip normals direction"
+ )
+ swapUV = BoolProperty(
+ name="Swap UV",
+ default=False,
+ description="Flip grid's U and V"
+ )
+ flipU = BoolProperty(
+ name="Flip U",
+ default=False,
+ description="Flip grid's U")
+
+ flipV = BoolProperty(
+ name="Flip V",
+ default=False,
+ description="Flip grid's V"
+ )
+ flipW = BoolProperty(
+ name="Flip W",
+ default=False,
+ description="Flip grid's W"
+ )
+ use_groups = BoolProperty(
+ name="Vertex Group",
+ default=False,
+ description="Use active Vertex Group for lattice's thickness"
+ )
+ high_quality_lattice = BoolProperty(
+ name="High quality",
+ default=True,
+ description="Increase the the subdivisions in normal direction for a "
+ "more correct result"
+ )
+ hide_lattice = BoolProperty(
+ name="Hide Lattice",
+ default=True,
+ description="Automatically hide the Lattice object"
+ )
+ scale_x = FloatProperty(
+ name="Scale X",
+ default=1,
+ min=0.001,
+ max=1,
+ description="Object scale"
+ )
+ scale_y = FloatProperty(
+ name="Scale Y", default=1,
+ min=0.001,
+ max=1,
+ description="Object scale"
+ )
+ scale_z = FloatProperty(
+ name="Scale Z",
+ default=1,
+ min=0.001,
+ max=1,
+ description="Object scale"
+ )
+ thickness = FloatProperty(
+ name="Thickness",
+ default=1,
+ soft_min=0,
+ soft_max=5,
+ description="Lattice thickness"
+ )
+ displace = FloatProperty(
+ name="Displace",
+ default=0,
+ soft_min=-1,
+ soft_max=1,
+ description="Lattice displace"
+ )
def draw(self, context):
layout = self.layout
@@ -214,11 +261,13 @@ class lattice_along_surface(bpy.types.Operator):
col.prop(
self, "thickness", text="Thickness", icon='NONE', expand=False,
slider=True, toggle=False, icon_only=False, event=False,
- full_event=False, emboss=True, index=-1)
+ full_event=False, emboss=True, index=-1
+ )
col.prop(
self, "displace", text="Offset", icon='NONE', expand=False,
slider=True, toggle=False, icon_only=False, event=False,
- full_event=False, emboss=True, index=-1)
+ full_event=False, emboss=True, index=-1
+ )
row = col.row()
row.prop(self, "use_groups")
col.separator()
@@ -226,17 +275,19 @@ class lattice_along_surface(bpy.types.Operator):
col.prop(
self, "scale_x", text="U", icon='NONE', expand=False,
slider=True, toggle=False, icon_only=False, event=False,
- full_event=False, emboss=True, index=-1)
+ full_event=False, emboss=True, index=-1
+ )
col.prop(
self, "scale_y", text="V", icon='NONE', expand=False,
slider=True, toggle=False, icon_only=False, event=False,
- full_event=False, emboss=True, index=-1)
- '''
+ full_event=False, emboss=True, index=-1
+ )
+ """
col.prop(
self, "scale_z", text="W", icon='NONE', expand=False,
slider=True, toggle=False, icon_only=False, event=False,
full_event=False, emboss=True, index=-1)
- '''
+ """
col.separator()
col.label(text="Flip:")
row = col.row()
@@ -262,15 +313,17 @@ class lattice_along_surface(bpy.types.Operator):
return {'CANCELLED'}
obj = None
for o in bpy.context.selected_objects:
- if o.name != grid_obj.name and o.type in ('MESH', 'CURVE', \
- 'SURFACE', 'FONT'):
+ if o.name != grid_obj.name and o.type in \
+ ('MESH', 'CURVE', 'SURFACE', 'FONT'):
obj = o
o.select = False
break
try:
obj_dim = obj.dimensions
- obj_me = obj.to_mesh(bpy.context.scene, apply_modifiers=True,
- settings = 'PREVIEW')
+ obj_me = obj.to_mesh(
+ bpy.context.scene, apply_modifiers=True,
+ settings='PREVIEW'
+ )
except:
self.report({'ERROR'}, "The object to deform is not valid. Only "
"Mesh, Curve, Surface and Font objects are allowed.")
@@ -281,16 +334,18 @@ class lattice_along_surface(bpy.types.Operator):
bpy.ops.object.convert(target='MESH')
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
grid_mesh = grid_obj.to_mesh(bpy.context.scene, apply_modifiers=True,
- settings = 'PREVIEW')
- if len(grid_mesh.polygons) > 64*64:
+ settings='PREVIEW')
+
+ if len(grid_mesh.polygons) > 64 * 64:
bpy.ops.object.delete(use_global=False)
bpy.context.scene.objects.active = obj
obj.select = True
self.report({'ERROR'}, "Maximum resolution allowed for Lattice is 64")
return {'CANCELLED'}
+
# CREATING LATTICE
- min = Vector((0,0,0))
- max = Vector((0,0,0))
+ min = Vector((0, 0, 0))
+ max = Vector((0, 0, 0))
first = True
for v in obj_me.vertices:
vert = obj.matrix_world * v.co
@@ -307,17 +362,23 @@ class lattice_along_surface(bpy.types.Operator):
if vert[2] > max[2] or first:
max[2] = vert[2]
first = False
- bb = max-min
- lattice_loc = (max+min)/2
+
+ bb = max - min
+ lattice_loc = (max + min) / 2
bpy.ops.object.add(type='LATTICE', view_align=False,
enter_editmode=False)
lattice = bpy.context.active_object
lattice.location = lattice_loc
- lattice.scale = Vector((bb.x/self.scale_x, bb.y/self.scale_y,
- bb.z/self.scale_z))
- if bb.x == 0: lattice.scale.x = 1
- if bb.y == 0: lattice.scale.y = 1
- if bb.z == 0: lattice.scale.z = 1
+ lattice.scale = Vector((bb.x / self.scale_x, bb.y / self.scale_y,
+ bb.z / self.scale_z))
+
+ if bb.x == 0:
+ lattice.scale.x = 1
+ if bb.y == 0:
+ lattice.scale.y = 1
+ if bb.z == 0:
+ lattice.scale.z = 1
+
bpy.context.scene.objects.active = obj
bpy.ops.object.modifier_add(type='LATTICE')
obj.modifiers[-1].object = lattice
@@ -330,8 +391,10 @@ class lattice_along_surface(bpy.types.Operator):
bpy.ops.object.parent_set(type='LATTICE')
# reading grid structure
- verts_grid, edges_grid, faces_grid = grid_from_mesh(grid_mesh,
- swap_uv=self.swapUV)
+ verts_grid, edges_grid, faces_grid = grid_from_mesh(
+ grid_mesh,
+ swap_uv=self.swapUV
+ )
nu = len(verts_grid)
nv = len(verts_grid[0])
nw = 2
@@ -346,17 +409,27 @@ class lattice_along_surface(bpy.types.Operator):
for w in range(nw):
if self.use_groups:
try:
- displace = grid_obj.vertex_groups.active.weight(verts_grid[i][j])*scale_normal*bb.z
+ displace = grid_obj.vertex_groups.active.weight(
+ verts_grid[i][j]) * scale_normal * bb.z
except:
- displace = scale_normal*bb.z
- else: displace = scale_normal*bb.z
- target_point = (grid_mesh.vertices[verts_grid[i][j]].co + grid_mesh.vertices[verts_grid[i][j]].normal*(w + self.displace/2 - 0.5)*displace) - lattice.location
- if self.flipW: w = 1-w
- if self.flipU: i = nu-i-1
- if self.flipV: j = nv-j-1
- lattice.data.points[i + j*nu + w*nu*nv].co_deform.x = target_point.x / bpy.data.objects[lattice.name].scale.x
- lattice.data.points[i + j*nu + w*nu*nv].co_deform.y = target_point.y / bpy.data.objects[lattice.name].scale.y
- lattice.data.points[i + j*nu + w*nu*nv].co_deform.z = target_point.z / bpy.data.objects[lattice.name].scale.z
+ displace = scale_normal * bb.z
+ else:
+ displace = scale_normal * bb.z
+ target_point = (grid_mesh.vertices[verts_grid[i][j]].co +
+ grid_mesh.vertices[verts_grid[i][j]].normal *
+ (w + self.displace / 2 - 0.5) * displace) - lattice.location
+ if self.flipW:
+ w = 1 - w
+ if self.flipU:
+ i = nu - i - 1
+ if self.flipV:
+ j = nv - j - 1
+ lattice.data.points[i + j * nu + w * nu * nv].co_deform.x = \
+ target_point.x / bpy.data.objects[lattice.name].scale.x
+ lattice.data.points[i + j * nu + w * nu * nv].co_deform.y = \
+ target_point.y / bpy.data.objects[lattice.name].scale.y
+ lattice.data.points[i + j * nu + w * nu * nv].co_deform.z = \
+ target_point.z / bpy.data.objects[lattice.name].scale.z
except:
bpy.ops.object.mode_set(mode='OBJECT')
grid_obj.select = True
@@ -373,9 +446,9 @@ class lattice_along_surface(bpy.types.Operator):
self.report({'ERROR'}, "The grid mesh is not correct")
return {'CANCELLED'}
- #grid_obj.data = old_grid_data
- #print(old_grid_matrix)
- #grid_obj.matrix_world = old_grid_matrix
+ # grid_obj.data = old_grid_data
+ # print(old_grid_matrix)
+ # grid_obj.matrix_world = old_grid_matrix
bpy.ops.object.mode_set(mode='OBJECT')
grid_obj.select = True
@@ -384,13 +457,19 @@ class lattice_along_surface(bpy.types.Operator):
bpy.ops.object.delete(use_global=False)
bpy.context.scene.objects.active = lattice
lattice.select = True
- if self.high_quality_lattice: bpy.context.object.data.points_w = 8
- else: bpy.context.object.data.use_outside = True
+
+ if self.high_quality_lattice:
+ bpy.context.object.data.points_w = 8
+ else:
+ bpy.context.object.data.use_outside = True
+
if self.hide_lattice:
bpy.ops.object.hide_view_set(unselected=False)
+
bpy.context.scene.objects.active = obj
obj.select = True
lattice.select = False
+
if self.flipNormals:
try:
bpy.ops.object.mode_set(mode='EDIT')
@@ -399,34 +478,37 @@ class lattice_along_surface(bpy.types.Operator):
bpy.ops.object.mode_set(mode='OBJECT')
except:
pass
+
return {'FINISHED'}
-'''
+
+"""
class lattice_along_surface_panel(bpy.types.Panel):
bl_label = "Modifiers Tools"
bl_category = "Tools"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
- bl_context = (("objectmode"))
+ bl_context = "objectmode"
def draw(self, context):
layout = self.layout
col = layout.column(align=True)
+
try:
col.operator("object.lattice_along_surface", icon="MOD_LATTICE")
except:
pass
-'''
+"""
def register():
bpy.utils.register_class(lattice_along_surface)
- #bpy.utils.register_class(lattice_along_surface_panel)
+ # bpy.utils.register_class(lattice_along_surface_panel)
def unregister():
bpy.utils.unregister_class(lattice_along_surface)
- #bpy.utils.unregister_class(lattice_along_surface_panel)
+ # bpy.utils.unregister_class(lattice_along_surface_panel)
if __name__ == "__main__":