diff --git a/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/DUAL_MESH.PY b/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/DUAL_MESH.PY deleted file mode 100644 index f8ab7fdc..00000000 --- a/◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/DUAL_MESH.PY +++ /dev/null @@ -1,345 +0,0 @@ -# ##### 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 ##### - -# --------------------------------- DUAL MESH -------------------------------- # -# -------------------------------- version 0.3 ------------------------------- # -# # -# Convert a generic mesh to its dual. With open meshes it can get some wired # -# effect on the borders. # -# # -# (c) Alessandro Zomparelli # -# (2017) # -# # -# http://www.co-de-it.com/ # -# # -# ############################################################################ # - - -import bpy -from bpy.types import Operator -from bpy.props import ( - BoolProperty, - 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) - 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) - context.collection.objects.link(ob1) - # fix visualization issue - 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)) - #context.collection.objects.link(ob) - #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' - bpy.ops.object.update_tessellate() - ob.location = ob0.location - ob.matrix_world = ob0.matrix_world - return {'FINISHED'} - - def invoke(self, context, event): - return context.window_manager.invoke_props_dialog(self) - -class dual_mesh(Operator): - bl_idname = "object.dual_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( - items=[('BEAUTY', 'Beauty', - 'Split the quads in nice triangles, slower method'), - ('FIXED', 'Fixed', - 'Split the quads on the 1st and 3rd vertices'), - ('FIXED_ALTERNATE', 'Fixed Alternate', - 'Split the quads on the 2nd and 4th vertices'), - ('SHORTEST_DIAGONAL', 'Shortest Diagonal', - 'Split the quads based on the distance between the vertices') - ], - name="Quad Method", - description="Method for splitting the quads into triangles", - default="FIXED", - options={'LIBRARY_EDITABLE'} - ) - polygon_method : EnumProperty( - items=[ - ('BEAUTY', 'Beauty', 'Arrange the new triangles evenly'), - ('CLIP', 'Clip', - 'Split the polygons with an ear clipping algorithm')], - name="Polygon Method", - description="Method for splitting the polygons into triangles", - default="BEAUTY", - options={'LIBRARY_EDITABLE'} - ) - preserve_borders : BoolProperty( - name="Preserve Borders", - default=True, - description="Preserve original borders" - ) - apply_modifiers : BoolProperty( - name="Apply Modifiers", - default=True, - description="Apply object's modifiers" - ) - - def execute(self, context): - mode = context.mode - if mode == 'EDIT_MESH': - mode = 'EDIT' - act = context.active_object - if mode != 'OBJECT': - sel = [act] - bpy.ops.object.mode_set(mode='OBJECT') - else: - sel = context.selected_objects - doneMeshes = [] - - for ob0 in sel: - if ob0.type != 'MESH': - continue - if ob0.data.name in doneMeshes: - continue - ob = ob0 - mesh_name = ob0.data.name - - # store linked objects - clones = [] - n_users = ob0.data.users - count = 0 - for o in bpy.data.objects: - if o.type != 'MESH': - continue - if o.data.name == mesh_name: - count += 1 - clones.append(o) - if count == n_users: - break - - if self.apply_modifiers: - bpy.ops.object.convert(target='MESH') - ob.data = ob.data.copy() - bpy.ops.object.select_all(action='DESELECT') - ob.select_set(True) - context.view_layer.objects.active = ob0 - bpy.ops.object.mode_set(mode='EDIT') - - # prevent borders erosion - bpy.ops.mesh.select_mode( - use_extend=False, use_expand=False, type='EDGE' - ) - bpy.ops.mesh.select_non_manifold( - extend=False, use_wire=False, use_boundary=True, - use_multi_face=False, use_non_contiguous=False, - use_verts=False - ) - bpy.ops.mesh.extrude_region_move( - MESH_OT_extrude_region={"mirror": False}, - TRANSFORM_OT_translate={"value": (0, 0, 0)} - ) - - bpy.ops.mesh.select_mode( - use_extend=False, use_expand=False, type='VERT', - action='TOGGLE' - ) - bpy.ops.mesh.select_all(action='SELECT') - bpy.ops.mesh.quads_convert_to_tris( - quad_method=self.quad_method, ngon_method=self.polygon_method - ) - bpy.ops.mesh.select_all(action='DESELECT') - bpy.ops.object.mode_set(mode='OBJECT') - bpy.ops.object.modifier_add(type='SUBSURF') - ob.modifiers[-1].name = "dual_mesh_subsurf" - while True: - bpy.ops.object.modifier_move_up(modifier="dual_mesh_subsurf") - if ob.modifiers[0].name == "dual_mesh_subsurf": - break - - 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[-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') - - bpy.ops.mesh.select_non_manifold( - extend=False, use_wire=False, use_boundary=True, - use_multi_face=False, use_non_contiguous=False, use_verts=False) - bpy.ops.mesh.select_more() - - # find boundaries - bpy.ops.object.mode_set(mode='OBJECT') - bound_v = [v.index for v in ob.data.vertices if v.select] - bound_e = [e.index for e in ob.data.edges if e.select] - bound_p = [p.index for p in ob.data.polygons if p.select] - bpy.ops.object.mode_set(mode='EDIT') - - # select quad faces - context.tool_settings.mesh_select_mode = (False, False, True) - bpy.ops.mesh.select_face_by_sides(number=4, extend=False) - - # deselect boundaries - bpy.ops.object.mode_set(mode='OBJECT') - for i in bound_v: - context.active_object.data.vertices[i].select = False - for i in bound_e: - context.active_object.data.edges[i].select = False - for i in bound_p: - context.active_object.data.polygons[i].select = False - - bpy.ops.object.mode_set(mode='EDIT') - - context.tool_settings.mesh_select_mode = (False, False, True) - bpy.ops.mesh.edge_face_add() - context.tool_settings.mesh_select_mode = (True, False, False) - bpy.ops.mesh.select_all(action='DESELECT') - - # delete boundaries - bpy.ops.mesh.select_non_manifold( - extend=False, use_wire=True, use_boundary=True, - use_multi_face=False, use_non_contiguous=False, use_verts=True - ) - bpy.ops.mesh.delete(type='VERT') - - # remove middle vertices - 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 = True - - # dissolve - bpy.ops.mesh.dissolve_verts() - bpy.ops.mesh.select_all(action='DESELECT') - - # remove border faces - if not self.preserve_borders: - bpy.ops.mesh.select_non_manifold( - extend=False, use_wire=False, use_boundary=True, - use_multi_face=False, use_non_contiguous=False, use_verts=False - ) - bpy.ops.mesh.select_more() - bpy.ops.mesh.delete(type='FACE') - - # clean wires - bpy.ops.mesh.select_non_manifold( - extend=False, use_wire=True, use_boundary=False, - use_multi_face=False, use_non_contiguous=False, use_verts=False - ) - bpy.ops.mesh.delete(type='EDGE') - - bpy.ops.object.mode_set(mode='OBJECT') - ob0.data.name = mesh_name - doneMeshes.append(mesh_name) - - for o in clones: - o.data = ob.data - - for o in sel: - o.select_set(True) - - context.view_layer.objects.active = act - bpy.ops.object.mode_set(mode=mode) - - return {'FINISHED'}