mesh_tissue: initial update 2.80

This commit is contained in:
Brendon Murphy 2019-07-01 21:06:16 +10:00
parent fffaf5d275
commit 498d912a9d
Notes: blender-bot 2023-02-14 19:17:41 +01:00
Referenced by commit d142dc2d: mesh_tissue: add comment to object.tessellate.working_on
Referenced by commit 582119a5: mesh_tissue: revert version bump rBA498d912a9d58
Referenced by commit d142dc2d, mesh_tissue: add comment to object.tessellate.working_on
Referenced by commit 582119a5, mesh_tissue: revert version bump rBA498d912a9d58
Referenced by issue #63477, Update Tissue addon 2.8
9 changed files with 5277 additions and 1634 deletions

View File

@ -1,14 +1,38 @@
# Tissue
![cover](http://www.co-de-it.com/wordpress/wp-content/uploads/2015/07/tissue_graphics.jpg)
Tissue - Blender's add-on for computational design by Co-de-iT
http://www.co-de-it.com/wordpress/code/blender-tissue
Latest version (master): https://github.com/alessandro-zomparelli/tissue/archive/master.zip
### Blender 2.79
Releases: https://github.com/alessandro-zomparelli/tissue/releases
Official version (master): https://github.com/alessandro-zomparelli/tissue/archive/master.zip
Installation:
Latest development version (dev1): https://github.com/alessandro-zomparelli/tissue/tree/dev1
(Includes animatable Tessellation)
### Blender 2.80
Latest development version (b280-dev): https://github.com/alessandro-zomparelli/tissue/tree/b280-dev
(Includes animatable Tessellation and Patch method)
### Installation:
1. Start Blender. Open User Preferences, the addons tab
2. Click "install from file" and point Blender at the downloaded zip
3. Activate Tissue add-on from user preferences
3. Save user preferences if you want to have it on at startup.
### Contribute
Please help me keeping Tissue stable and updated, report any issue here: https://github.com/alessandro-zomparelli/tissue/issues
Tissue is free and open-source. I really think that this is the power of Blender and I wanted to give my small contribution to it.
If you like my work and you want to help to continue the development of Tissue, please consider to make a small donation. Any small contribution is really appreciated, thanks! :-D
Alessandro
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ARSDJWXVFZ346)

View File

@ -33,14 +33,13 @@
bl_info = {
"name": "Tissue",
"author": "Alessandro Zomparelli (Co-de-iT)",
"version": (0, 3, 4),
"blender": (2, 79, 0),
"version": (0, 3, 25),
"blender": (2, 80, 0),
"location": "",
"description": "Tools for Computational Design",
"warning": "",
"wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/"
"Py/Scripts/Mesh/Tissue",
"tracker_url": "https://plus.google.com/u/0/+AlessandroZomparelli/",
"wiki_url": "https://github.com/alessandro-zomparelli/tissue/wiki",
"tracker_url": "https://github.com/alessandro-zomparelli/tissue/issues",
"category": "Mesh"}
@ -51,6 +50,7 @@ if "bpy" in locals():
importlib.reload(dual_mesh)
importlib.reload(lattice)
importlib.reload(uv_to_mesh)
importlib.reload(utils)
else:
from . import tessellate_numpy
@ -58,24 +58,76 @@ else:
from . import dual_mesh
from . import lattice
from . import uv_to_mesh
from . import utils
import bpy
from bpy.props import PointerProperty
from bpy.props import PointerProperty, CollectionProperty, BoolProperty
classes = (
tessellate_numpy.tissue_tessellate_prop,
tessellate_numpy.tessellate,
tessellate_numpy.update_tessellate,
tessellate_numpy.TISSUE_PT_tessellate,
tessellate_numpy.rotate_face,
tessellate_numpy.TISSUE_PT_tessellate_object,
colors_groups_exchanger.face_area_to_vertex_groups,
colors_groups_exchanger.vertex_colors_to_vertex_groups,
colors_groups_exchanger.vertex_group_to_vertex_colors,
colors_groups_exchanger.TISSUE_PT_weight,
colors_groups_exchanger.TISSUE_PT_color,
colors_groups_exchanger.weight_contour_curves,
colors_groups_exchanger.weight_contour_mask,
colors_groups_exchanger.weight_contour_displace,
colors_groups_exchanger.harmonic_weight,
colors_groups_exchanger.edges_deformation,
colors_groups_exchanger.edges_bending,
colors_groups_exchanger.weight_laplacian,
colors_groups_exchanger.reaction_diffusion,
colors_groups_exchanger.start_reaction_diffusion,
colors_groups_exchanger.TISSUE_PT_reaction_diffusion,
colors_groups_exchanger.reset_reaction_diffusion_weight,
colors_groups_exchanger.formula_prop,
colors_groups_exchanger.reaction_diffusion_prop,
colors_groups_exchanger.weight_formula,
colors_groups_exchanger.curvature_to_vertex_groups,
colors_groups_exchanger.weight_formula_wiki,
dual_mesh.dual_mesh,
dual_mesh.dual_mesh_tessellated,
lattice.lattice_along_surface,
uv_to_mesh.uv_to_mesh
)
def register():
bpy.utils.register_module(__name__)
from bpy.utils import register_class
for cls in classes:
bpy.utils.register_class(cls)
#bpy.utils.register_module(__name__)
bpy.types.Object.tissue_tessellate = PointerProperty(
type=tessellate_numpy.tissue_tessellate_prop
)
bpy.types.Object.formula_settings = CollectionProperty(
type=colors_groups_exchanger.formula_prop
)
bpy.types.Object.reaction_diffusion_settings = PointerProperty(
type=colors_groups_exchanger.reaction_diffusion_prop
)
# colors_groups_exchanger
bpy.app.handlers.frame_change_post.append(colors_groups_exchanger.reaction_diffusion_def)
#bpy.app.handlers.frame_change_post.append(tessellate_numpy.anim_tessellate)
def unregister():
tessellate_numpy.unregister()
colors_groups_exchanger.unregister()
dual_mesh.unregister()
lattice.unregister()
uv_to_mesh.unregister()
from bpy.utils import unregister_class
for cls in classes:
bpy.utils.unregister_class(cls)
#tessellate_numpy.unregister()
#colors_groups_exchanger.unregister()
#dual_mesh.unregister()
#lattice.unregister()
#uv_to_mesh.unregister()
del bpy.types.Object.tissue_tessellate

File diff suppressed because it is too large Load Diff

View File

@ -32,8 +32,8 @@
bl_info = {
"name": "Dual Mesh",
"author": "Alessandro Zomparelli (Co-de-iT)",
"version": (0, 3),
"blender": (2, 78, 0),
"version": (0, 4),
"blender": (2, 8, 0),
"location": "",
"description": "Convert a generic mesh to its dual",
"warning": "",
@ -47,15 +47,105 @@ from bpy.props import (
EnumProperty,
)
import bmesh
from .utils import *
class dual_mesh_tessellated(Operator):
bl_idname = "object.dual_mesh_tessellated"
bl_label = "Dual Mesh"
bl_description = ("Generate a polygonal mesh using Tessellate. (Non-destructive)")
bl_options = {'REGISTER', 'UNDO'}
apply_modifiers : BoolProperty(
name="Apply Modifiers",
default=True,
description="Apply object's modifiers"
)
source_faces : EnumProperty(
items=[
('QUAD', 'Quad Faces', ''),
('TRI', 'Triangles', '')],
name="Source Faces",
description="Source polygons",
default="QUAD",
options={'LIBRARY_EDITABLE'}
)
def execute(self, context):
auto_layer_collection()
ob0 = context.object
name1 = "DualMesh_{}_Component".format(self.source_faces)
# Generate component
if self.source_faces == 'QUAD':
verts = [(0.0, 0.0, 0.0), (0.0, 0.5, 0.0),
(0.0, 1.0, 0.0), (0.5, 1.0, 0.0),
(1.0, 1.0, 0.0), (1.0, 0.5, 0.0),
(1.0, 0.0, 0.0), (0.5, 0.0, 0.0),
(1/3, 1/3, 0.0), (2/3, 2/3, 0.0)]
edges = [(0,1), (1,2), (2,3), (3,4), (4,5), (5,6), (6,7),
(7,0), (1,8), (8,7), (3,9), (9,5), (8,9)]
faces = [(7,8,1,0), (8,9,3,2,1), (9,5,4,3), (9,8,7,6,5)]
else:
verts = [(0.0,0.0,0.0), (0.5,0.0,0.0), (1.0,0.0,0.0), (0.0,1.0,0.0), (0.5,1.0,0.0), (1.0,1.0,0.0)]
edges = [(0,1), (1,2), (2,5), (5,4), (4,3), (3,0), (1,4)]
faces = [(0,1,4,3), (1,2,5,4)]
# check pre-existing component
try:
_verts = [0]*len(verts)*3
__verts = [c for co in verts for c in co]
ob1 = bpy.data.objects[name1]
ob1.data.vertices.foreach_get("co",_verts)
for a, b in zip(_verts, __verts):
if abs(a-b) > 0.0001:
raise ValueError
except:
me = bpy.data.meshes.new("Dual-Mesh") # add a new mesh
me.from_pydata(verts, edges, faces)
me.update(calc_edges=True, calc_edges_loose=True, calc_loop_triangles=True)
if self.source_faces == 'QUAD': n_seams = 8
else: n_seams = 6
for i in range(n_seams): me.edges[i].use_seam = True
ob1 = bpy.data.objects.new(name1, me)
bpy.context.collection.objects.link(ob1)
# fix visualization issue
bpy.context.view_layer.objects.active = ob1
ob1.select_set(True)
bpy.ops.object.editmode_toggle()
bpy.ops.object.editmode_toggle()
ob1.select_set(False)
# hide component
ob1.hide_select = True
ob1.hide_render = True
ob1.hide_viewport = True
ob = convert_object_to_mesh(ob0,False,False)
ob.name = 'DualMesh'
#ob = bpy.data.objects.new("DualMesh", convert_object_to_mesh(ob0,False,False))
#bpy.context.collection.objects.link(ob)
#bpy.context.view_layer.objects.active = ob
#ob.select_set(True)
ob.tissue_tessellate.component = ob1
ob.tissue_tessellate.generator = ob0
ob.tissue_tessellate.gen_modifiers = self.apply_modifiers
ob.tissue_tessellate.merge = True
ob.tissue_tessellate.bool_dissolve_seams = True
if self.source_faces == 'TRI': ob.tissue_tessellate.fill_mode = 'FAN'
print(ob1)
print(ob0)
print(bpy.context.object)
bpy.ops.object.update_tessellate()
ob.location = ob0.location
ob.matrix_world = ob0.matrix_world
return {'FINISHED'}
class dual_mesh(Operator):
bl_idname = "object.dual_mesh"
bl_label = "Dual Mesh"
bl_description = ("Convert a generic mesh into a polygonal mesh")
bl_label = "Convert to Dual Mesh"
bl_description = ("Convert a generic mesh into a polygonal mesh. (Destructive)")
bl_options = {'REGISTER', 'UNDO'}
quad_method: EnumProperty(
quad_method : EnumProperty(
items=[('BEAUTY', 'Beauty',
'Split the quads in nice triangles, slower method'),
('FIXED', 'Fixed',
@ -70,7 +160,7 @@ class dual_mesh(Operator):
default="FIXED",
options={'LIBRARY_EDITABLE'}
)
polygon_method: EnumProperty(
polygon_method : EnumProperty(
items=[
('BEAUTY', 'Beauty', 'Arrange the new triangles evenly'),
('CLIP', 'Clip',
@ -80,12 +170,12 @@ class dual_mesh(Operator):
default="BEAUTY",
options={'LIBRARY_EDITABLE'}
)
preserve_borders: BoolProperty(
preserve_borders : BoolProperty(
name="Preserve Borders",
default=True,
description="Preserve original borders"
)
apply_modifiers: BoolProperty(
apply_modifiers : BoolProperty(
name="Apply Modifiers",
default=True,
description="Apply object's modifiers"
@ -103,16 +193,6 @@ class dual_mesh(Operator):
sel = bpy.context.selected_objects
doneMeshes = []
'''
if self.new_object:
bpy.ops.object.duplicate_move()
for i in range(len(sel)):
bpy.context.selected_objects[i].name = sel[i].name + "_dual"
if sel[i] == act:
bpy.context.scene.objects.active = bpy.context.selected_objects[i]
sel = bpy.context.selected_objects
'''
for ob0 in sel:
if ob0.type != 'MESH':
continue
@ -153,16 +233,7 @@ class dual_mesh(Operator):
)
bpy.ops.mesh.extrude_region_move(
MESH_OT_extrude_region={"mirror": False},
TRANSFORM_OT_translate={"value": (0, 0, 0),
"constraint_axis": (False, False, False),
"orient_type": '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), "gpencil_strokes": False,
"texture_space": False, "remove_on_cancel": False,
"release_confirm": False}
TRANSFORM_OT_translate={"value": (0, 0, 0)}
)
bpy.ops.mesh.select_mode(
@ -185,19 +256,21 @@ class dual_mesh(Operator):
bpy.ops.object.modifier_apply(
apply_as='DATA', modifier='dual_mesh_subsurf'
)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
verts = ob.data.vertices
bpy.ops.object.mode_set(mode='OBJECT')
verts[0].select = True
verts[-1].select = True
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_more(use_face_step=False)
bpy.ops.mesh.select_similar(
type='EDGE', compare='EQUAL', threshold=0.01)
bpy.ops.mesh.select_all(action='INVERT')
bpy.ops.mesh.dissolve_verts()
bpy.ops.mesh.select_all(action='DESELECT')
@ -244,7 +317,7 @@ class dual_mesh(Operator):
bm = bmesh.from_edit_mesh(ob.data)
for v in bm.verts:
if len(v.link_edges) == 2 and len(v.link_faces) < 3:
v.select_set(True)
v.select = True
# dissolve
bpy.ops.mesh.dissolve_verts()
@ -280,36 +353,3 @@ class dual_mesh(Operator):
bpy.ops.object.mode_set(mode=mode)
return {'FINISHED'}
"""
class dual_mesh_panel(bpy.types.Panel):
bl_label = "Dual Mesh"
bl_category = "Tools"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_context = "objectmode"
def draw(self, context):
layout = self.layout
col = layout.column(align=True)
try:
if bpy.context.active_object.type == 'MESH':
col.operator("object.dual_mesh")
except:
pass
"""
def register():
bpy.utils.register_class(dual_mesh)
# bpy.utils.register_class(dual_mesh_panel)
def unregister():
bpy.utils.unregister_class(dual_mesh)
# bpy.utils.unregister_class(dual_mesh_panel)
if __name__ == "__main__":
register()

View File

@ -31,7 +31,7 @@ bl_info = {
"name": "Lattice",
"author": "Alessandro Zomparelli (Co-de-iT)",
"version": (0, 3),
"blender": (2, 78, 0),
"blender": (2, 7, 8),
"location": "",
"description": "Generate a Lattice based on a grid mesh",
"warning": "",
@ -42,12 +42,11 @@ bl_info = {
import bpy
import bmesh
from bpy.types import Operator
from bpy.props import (
BoolProperty,
FloatProperty,
)
from bpy.props import (BoolProperty, StringProperty, FloatProperty)
from mathutils import Vector
from .utils import *
def not_in(element, grid):
output = True
@ -173,86 +172,93 @@ class lattice_along_surface(Operator):
"Lattice's topology")
bl_options = {'REGISTER', 'UNDO'}
set_parent: BoolProperty(
set_parent : BoolProperty(
name="Set Parent",
default=True,
description="Automatically set the Lattice as parent"
)
flipNormals: BoolProperty(
flipNormals : BoolProperty(
name="Flip Normals",
default=False,
description="Flip normals direction"
)
swapUV: BoolProperty(
swapUV : BoolProperty(
name="Swap UV",
default=False,
description="Flip grid's U and V"
)
flipU: BoolProperty(
flipU : BoolProperty(
name="Flip U",
default=False,
description="Flip grid's U")
flipV: BoolProperty(
flipV : BoolProperty(
name="Flip V",
default=False,
description="Flip grid's V"
)
flipW: BoolProperty(
flipW : BoolProperty(
name="Flip W",
default=False,
description="Flip grid's W"
)
use_groups: BoolProperty(
use_groups : BoolProperty(
name="Vertex Group",
default=False,
description="Use active Vertex Group for lattice's thickness"
)
high_quality_lattice: BoolProperty(
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(
hide_lattice : BoolProperty(
name="Hide Lattice",
default=True,
description="Automatically hide the Lattice object"
)
scale_x: FloatProperty(
scale_x : FloatProperty(
name="Scale X",
default=1,
min=0.001,
max=1,
description="Object scale"
)
scale_y: FloatProperty(
scale_y : FloatProperty(
name="Scale Y", default=1,
min=0.001,
max=1,
description="Object scale"
)
scale_z: FloatProperty(
scale_z : FloatProperty(
name="Scale Z",
default=1,
min=0.001,
max=1,
description="Object scale"
)
thickness: FloatProperty(
thickness : FloatProperty(
name="Thickness",
default=1,
soft_min=0,
soft_max=5,
description="Lattice thickness"
)
displace: FloatProperty(
displace : FloatProperty(
name="Displace",
default=0,
soft_min=-1,
soft_max=1,
description="Lattice displace"
)
grid_object = ""
source_object = ""
@classmethod
def poll(cls, context):
try: return bpy.context.object.mode == 'OBJECT'
except: return False
def draw(self, context):
layout = self.layout
@ -282,12 +288,6 @@ class lattice_along_surface(Operator):
slider=True, toggle=False, icon_only=False, event=False,
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()
@ -303,39 +303,48 @@ class lattice_along_surface(Operator):
col.prop(self, "set_parent")
def execute(self, context):
if len(bpy.context.selected_objects) != 2:
self.report({'ERROR'}, "Please, select two objects")
return {'CANCELLED'}
depsgraph = context.evaluated_depsgraph_get()
grid_obj = bpy.context.active_object
if grid_obj.type not in ('MESH', 'CURVE', 'SURFACE'):
self.report({'ERROR'}, "The surface object is not valid. Only Mesh,"
"Curve and Surface objects are allowed.")
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'):
obj = o
o.select_set(False)
break
obj_eval = obj.evaluated_get(depsgraph)
try:
obj_dim = obj.dimensions
obj_me = obj_eval.to_mesh()
except:
self.report({'ERROR'}, "The object to deform is not valid. Only "
"Mesh, Curve, Surface and Font objects are allowed.")
return {'CANCELLED'}
if self.source_object == self.grid_object == "" or True:
if len(bpy.context.selected_objects) != 2:
self.report({'ERROR'}, "Please, select two objects")
return {'CANCELLED'}
grid_obj = bpy.context.object
if grid_obj.type not in ('MESH', 'CURVE', 'SURFACE'):
self.report({'ERROR'}, "The surface object is not valid. Only Mesh,"
"Curve and Surface objects are allowed.")
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'):
obj = o
o.select_set(False)
break
try:
obj_dim = obj.dimensions
obj_me = simple_to_mesh(obj)#obj.to_mesh(bpy.context.depsgraph, apply_modifiers=True)
except:
self.report({'ERROR'}, "The object to deform is not valid. Only "
"Mesh, Curve, Surface and Font objects are allowed.")
return {'CANCELLED'}
self.grid_object = grid_obj.name
self.source_object = obj.name
else:
grid_obj = bpy.data.objects[self.grid_object]
obj = bpy.data.objects[self.source_object]
obj_me = simple_to_mesh(obj)# obj.to_mesh(bpy.context.depsgraph, apply_modifiers=True)
for o in bpy.context.selected_objects: o.select_set(False)
grid_obj.select_set(True)
bpy.context.view_layer.objects.active = grid_obj
bpy.ops.object.duplicate_move()
grid_obj = bpy.context.active_object
bpy.ops.object.convert(target='MESH')
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
grid_mesh = grid_obj.evaluated_get(depsgraph).to_mesh()
temp_grid_obj = grid_obj.copy()
temp_grid_obj.data = simple_to_mesh(grid_obj)
grid_mesh = temp_grid_obj.data
for v in grid_mesh.vertices:
v.co = grid_obj.matrix_world @ v.co
grid_mesh.calc_normals()
if len(grid_mesh.polygons) > 64 * 64:
bpy.ops.object.delete(use_global=False)
bpy.data.objects.remove(temp_grid_obj)
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
self.report({'ERROR'}, "Maximum resolution allowed for Lattice is 64")
@ -346,7 +355,8 @@ class lattice_along_surface(Operator):
max = Vector((0, 0, 0))
first = True
for v in obj_me.vertices:
vert = obj.matrix_world * v.co
v0 = v.co.copy()
vert = obj.matrix_world @ v0
if vert[0] < min[0] or first:
min[0] = vert[0]
if vert[1] < min[1] or first:
@ -361,12 +371,10 @@ class lattice_along_surface(Operator):
max[2] = vert[2]
first = False
obj_eval.to_mesh_clear()
bb = max - min
print(bb)
lattice_loc = (max + min) / 2
bpy.ops.object.add(type='LATTICE', align='WORLD',
enter_editmode=False)
bpy.ops.object.add(type='LATTICE')
lattice = bpy.context.active_object
lattice.location = lattice_loc
lattice.scale = Vector((bb.x / self.scale_x, bb.y / self.scale_y,
@ -409,10 +417,10 @@ class lattice_along_surface(Operator):
for w in range(nw):
if self.use_groups:
try:
displace = grid_obj.vertex_groups.active.weight(
displace = temp_grid_obj.vertex_groups.active.weight(
verts_grid[i][j]) * scale_normal * bb.z
except:
displace = scale_normal * bb.z
displace = 0#scale_normal * bb.z
else:
displace = scale_normal * bb.z
target_point = (grid_mesh.vertices[verts_grid[i][j]].co +
@ -424,15 +432,17 @@ class lattice_along_surface(Operator):
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_set(True)
temp_grid_obj.select_set(True)
lattice.select_set(True)
obj.select_set(False)
bpy.ops.object.delete(use_global=False)
@ -446,15 +456,11 @@ class lattice_along_surface(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
bpy.ops.object.mode_set(mode='OBJECT')
grid_obj.select_set(True)
lattice.select_set(False)
#grid_obj.select_set(True)
#lattice.select_set(False)
obj.select_set(False)
bpy.ops.object.delete(use_global=False)
#bpy.ops.object.delete(use_global=False)
bpy.context.view_layer.objects.active = lattice
lattice.select_set(True)
@ -478,38 +484,7 @@ class lattice_along_surface(Operator):
bpy.ops.object.mode_set(mode='OBJECT')
except:
pass
bpy.data.meshes.remove(grid_mesh)
bpy.data.meshes.remove(obj_me)
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"
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)
def unregister():
bpy.utils.unregister_class(lattice_along_surface)
# bpy.utils.unregister_class(lattice_along_surface_panel)
if __name__ == "__main__":
register()

View File

@ -0,0 +1,40 @@
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
from numba import jit
import numpy as np
@jit
def numba_reaction_diffusion(n_verts, a, b, diff_a, diff_b, f, k, dt, id0, id1, time_steps):
for i in range(time_steps):
lap_a = np.zeros(n_verts)
lap_b = np.zeros(n_verts)
lap_a0 = a[id1] - a[id0] # laplacian increment for first vertex of each edge
lap_b0 = b[id1] - b[id0] # laplacian increment for first vertex of each edge
for i, j, la0, lb0 in zip(id0,id1,lap_a0,lap_b0):
lap_a[i] += la0
lap_b[i] += lb0
lap_a[j] -= la0
lap_b[j] -= lb0
ab2 = a*b**2
#a += eval("(diff_a*lap_a - ab2 + f*(1-a))*dt")
#b += eval("(diff_b*lap_b + ab2 - (k+f)*b)*dt")
a += (diff_a*lap_a - ab2 + f*(1-a))*dt
b += (diff_b*lap_b + ab2 - (k+f)*b)*dt
return a, b

File diff suppressed because it is too large Load Diff

110
mesh_tissue/utils.py Normal file
View File

@ -0,0 +1,110 @@
import bpy
#Recursivly transverse layer_collection for a particular name
def recurLayerCollection(layerColl, collName):
found = None
if (layerColl.name == collName):
return layerColl
for layer in layerColl.children:
found = recurLayerCollection(layer, collName)
if found:
return found
def auto_layer_collection():
# automatically change active layer collection
layer = bpy.context.view_layer.active_layer_collection
layer_collection = bpy.context.view_layer.layer_collection
if layer.hide_viewport or layer.collection.hide_viewport:
collections = bpy.context.object.users_collection
for c in collections:
lc = recurLayerCollection(layer_collection, c.name)
if not c.hide_viewport and not lc.hide_viewport:
bpy.context.view_layer.active_layer_collection = lc
def lerp(a, b, t):
return a + (b - a) * t
def _lerp2(v1, v2, v3, v4, v):
v12 = v1.lerp(v2,v.x) # + (v2 - v1) * v.x
v34 = v3.lerp(v4,v.x) # + (v4 - v3) * v.x
return v12.lerp(v34, v.y)# + (v34 - v12) * v.y
def lerp2(v1, v2, v3, v4, v):
v12 = v1 + (v2 - v1) * v.x
v34 = v3 + (v4 - v3) * v.x
return v12 + (v34 - v12) * v.y
def lerp3(v1, v2, v3, v4, v):
loc = lerp2(v1.co, v2.co, v3.co, v4.co, v)
nor = lerp2(v1.normal, v2.normal, v3.normal, v4.normal, v)
nor.normalize()
return loc + nor * v.z
def _convert_object_to_mesh(ob, apply_modifiers=True, preserve_status=True):
if not apply_modifiers:
mod_visibility = [m.show_viewport for m in ob.modifiers]
for m in ob.modifiers:
m.show_viewport = False
if preserve_status:
# store status
mode = bpy.context.object.mode
selected = bpy.context.selected_objects
active = bpy.context.object
# change status
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT')
new_ob = ob.copy()
new_ob.data = ob.data.copy()
bpy.context.collection.objects.link(new_ob)
bpy.context.view_layer.objects.active = new_ob
new_ob.select_set(True)
bpy.ops.object.convert(target='MESH')
if preserve_status:
# restore status
bpy.ops.object.select_all(action='DESELECT')
for o in selected: o.select_set(True)
bpy.context.view_layer.objects.active = active
bpy.ops.object.mode_set(mode=mode)
if not apply_modifiers:
for m,vis in zip(ob.modifiers,mod_visibility):
m.show_viewport = vis
return new_ob
def convert_object_to_mesh(ob, apply_modifiers=True, preserve_status=True):
if not ob.name: return None
if ob.type != 'MESH':
if not apply_modifiers:
mod_visibility = [m.show_viewport for m in ob.modifiers]
for m in ob.modifiers: m.show_viewport = False
#ob.modifiers.update()
#dg = bpy.context.evaluated_depsgraph_get()
#ob_eval = ob.evaluated_get(dg)
#me = bpy.data.meshes.new_from_object(ob_eval, preserve_all_data_layers=True, depsgraph=dg)
me = simple_to_mesh(ob)
new_ob = bpy.data.objects.new(ob.data.name, me)
new_ob.location, new_ob.matrix_world = ob.location, ob.matrix_world
if not apply_modifiers:
for m,vis in zip(ob.modifiers,mod_visibility): m.show_viewport = vis
else:
if apply_modifiers:
new_ob = ob.copy()
new_ob.data = simple_to_mesh(ob)
else:
new_ob = ob.copy()
new_ob.data = ob.data.copy()
new_ob.modifiers.clear()
bpy.context.collection.objects.link(new_ob)
if preserve_status:
new_ob.select_set(False)
else:
for o in bpy.context.view_layer.objects: o.select_set(False)
new_ob.select_set(True)
bpy.context.view_layer.objects.active = new_ob
return new_ob
def simple_to_mesh(ob):
dg = bpy.context.evaluated_depsgraph_get()
ob_eval = ob.evaluated_get(dg)
me = bpy.data.meshes.new_from_object(ob_eval, preserve_all_data_layers=True, depsgraph=dg)
me.calc_normals()
return me

View File

@ -32,7 +32,7 @@ bl_info = {
"name": "UV to Mesh",
"author": "Alessandro Zomparelli (Co-de-iT)",
"version": (0, 1, 1),
"blender": (2, 79, 0),
"blender": (2, 7, 9),
"location": "",
"description": "Create a new Mesh based on active UV",
"warning": "",
@ -53,22 +53,22 @@ class uv_to_mesh(Operator):
bl_description = ("Create a new Mesh based on active UV")
bl_options = {'REGISTER', 'UNDO'}
apply_modifiers: BoolProperty(
apply_modifiers : BoolProperty(
name="Apply Modifiers",
default=False,
description="Apply object's modifiers"
)
vertex_groups: BoolProperty(
vertex_groups : BoolProperty(
name="Keep Vertex Groups",
default=False,
description="Transfer all the Vertex Groups"
)
materials: BoolProperty(
materials : BoolProperty(
name="Keep Materials",
default=True,
description="Transfer all the Materials"
)
auto_scale: BoolProperty(
auto_scale : BoolProperty(
name="Resize",
default=True,
description="Scale the new object in order to preserve the average surface area"
@ -76,7 +76,7 @@ class uv_to_mesh(Operator):
def execute(self, context):
bpy.ops.object.mode_set(mode='OBJECT')
for o in bpy.data.objects:
for o in bpy.data.objects and bpy.context.view_layer.objects:
o.select_set(False)
bpy.context.object.select_set(True)
@ -85,11 +85,7 @@ class uv_to_mesh(Operator):
bpy.ops.object.convert(target='MESH')
ob0 = bpy.context.object
if self.apply_modifiers:
depsgraph = context.evaluated_depsgraph_get()
me0 = bpy.data.meshes.new_from_object(ob0.evaluated_get(depsgraph))
else:
me0 = bpy.data.new_from_meshed(ob0)
me0 = ob0.to_mesh(bpy.context.depsgraph, apply_modifiers=self.apply_modifiers)
area = 0
verts = []
@ -122,8 +118,8 @@ class uv_to_mesh(Operator):
# Link object to scene and make active
scn = bpy.context.scene
scn.objects.link(ob)
scn.objects.active = ob
bpy.context.collection.objects.link(ob)
bpy.context.view_layer.objects.active = ob
ob.select_set(True)
# Create mesh from given verts, faces.
@ -144,7 +140,7 @@ class uv_to_mesh(Operator):
try:
for group in ob0.vertex_groups:
index = group.index
ob.vertex_groups.new(name=group.name)
ob.vertex_groups.new(group.name)
for p in me0.polygons:
for vert, loop in zip(p.vertices, p.loop_indices):
ob.vertex_groups[index].add([loop], group.weight(vert), "ADD")
@ -183,15 +179,3 @@ class uv_to_mesh(Operator):
bpy.context.view_layer.objects.active = ob
return {'FINISHED'}
def register():
bpy.utils.register_class(uv_to_mesh)
def unregister():
bpy.utils.unregister_class(uv_to_mesh)
if __name__ == "__main__":
register()