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:
authormeta-androcto <meta.androcto1@gmail.com>2019-05-24 09:03:30 +0300
committermeta-androcto <meta.androcto1@gmail.com>2019-05-24 09:03:30 +0300
commit9e99e90f08c985cb764ecb3a7bba6ff534d4d874 (patch)
tree1e415d32af5aac63399250bf15eeaad97684751d /mesh_extra_tools/mesh_filletplus.py
parent01d80b8f602f392d975255d5fef97dcab2e0589b (diff)
mesh_extra_tools: move to contrib: T63750
Diffstat (limited to 'mesh_extra_tools/mesh_filletplus.py')
-rw-r--r--mesh_extra_tools/mesh_filletplus.py412
1 files changed, 0 insertions, 412 deletions
diff --git a/mesh_extra_tools/mesh_filletplus.py b/mesh_extra_tools/mesh_filletplus.py
deleted file mode 100644
index a54eba7b..00000000
--- a/mesh_extra_tools/mesh_filletplus.py
+++ /dev/null
@@ -1,412 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# ##### END 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 #####
-
-bl_info = {
- "name": "FilletPlus",
- "author": "Gert De Roost - original by zmj100",
- "version": (0, 4, 3),
- "blender": (2, 61, 0),
- "location": "View3D > Tool Shelf",
- "description": "",
- "warning": "",
- "wiki_url": "",
- "category": "Mesh"}
-
-
-import bpy
-from bpy.props import (
- FloatProperty,
- IntProperty,
- BoolProperty,
- )
-from bpy.types import Operator
-import bmesh
-from mathutils import Matrix
-from math import (
- cos, pi, sin,
- degrees, tan,
- )
-
-
-def list_clear_(l):
- if l:
- del l[:]
- return l
-
-
-def get_adj_v_(list_):
- tmp = {}
- for i in list_:
- try:
- tmp[i[0]].append(i[1])
- except KeyError:
- tmp[i[0]] = [i[1]]
- try:
- tmp[i[1]].append(i[0])
- except KeyError:
- tmp[i[1]] = [i[0]]
- return tmp
-
-
-class f_buf():
- # one of the angles was not 0 or 180
- check = False
-
-
-def fillets(list_0, startv, vertlist, face, adj, n, out, flip, radius):
- try:
- dict_0 = get_adj_v_(list_0)
- list_1 = [[dict_0[i][0], i, dict_0[i][1]] for i in dict_0 if (len(dict_0[i]) == 2)][0]
- list_3 = []
- for elem in list_1:
- list_3.append(bm.verts[elem])
- list_2 = []
-
- p_ = list_3[1]
- p = (list_3[1].co).copy()
- p1 = (list_3[0].co).copy()
- p2 = (list_3[2].co).copy()
-
- vec1 = p - p1
- vec2 = p - p2
-
- ang = vec1.angle(vec2, any)
- check_angle = round(degrees(ang))
-
- if check_angle == 180 or check_angle == 0.0:
- return False
- else:
- f_buf.check = True
-
- opp = adj
-
- if radius is False:
- h = adj * (1 / cos(ang * 0.5))
- adj_ = adj
- elif radius is True:
- h = opp / sin(ang * 0.5)
- adj_ = opp / tan(ang * 0.5)
-
- p3 = p - (vec1.normalized() * adj_)
- p4 = p - (vec2.normalized() * adj_)
- rp = p - ((p - ((p3 + p4) * 0.5)).normalized() * h)
-
- vec3 = rp - p3
- vec4 = rp - p4
-
- axis = vec1.cross(vec2)
-
- if out is False:
- if flip is False:
- rot_ang = vec3.angle(vec4)
- elif flip is True:
- rot_ang = vec1.angle(vec2)
- elif out is True:
- rot_ang = (2 * pi) - vec1.angle(vec2)
-
- for j in range(n + 1):
- new_angle = rot_ang * j / n
- mtrx = Matrix.Rotation(new_angle, 3, axis)
- if out is False:
- if flip is False:
- tmp = p4 - rp
- tmp1 = mtrx * tmp
- tmp2 = tmp1 + rp
- elif flip is True:
- p3 = p - (vec1.normalized() * opp)
- tmp = p3 - p
- tmp1 = mtrx * tmp
- tmp2 = tmp1 + p
- elif out is True:
- p4 = p - (vec2.normalized() * opp)
- tmp = p4 - p
- tmp1 = mtrx * tmp
- tmp2 = tmp1 + p
-
- v = bm.verts.new(tmp2)
- list_2.append(v)
-
- if flip is True:
- list_3[1:2] = list_2
- else:
- list_2.reverse()
- list_3[1:2] = list_2
-
- list_clear_(list_2)
-
- n1 = len(list_3)
-
- for t in range(n1 - 1):
- bm.edges.new([list_3[t], list_3[(t + 1) % n1]])
-
- v = bm.verts.new(p)
- bm.edges.new([v, p_])
-
- bm.edges.ensure_lookup_table()
-
- if face is not None:
- for l in face.loops:
- if l.vert == list_3[0]:
- startl = l
- break
- vertlist2 = []
-
- if startl.link_loop_next.vert == startv:
- l = startl.link_loop_prev
- while len(vertlist) > 0:
- vertlist2.insert(0, l.vert)
- vertlist.pop(vertlist.index(l.vert))
- l = l.link_loop_prev
- else:
- l = startl.link_loop_next
- while len(vertlist) > 0:
- vertlist2.insert(0, l.vert)
- vertlist.pop(vertlist.index(l.vert))
- l = l.link_loop_next
-
- for v in list_3:
- vertlist2.append(v)
- bm.faces.new(vertlist2)
- if startv.is_valid:
- bm.verts.remove(startv)
- else:
- print("\n[Function fillets Error]\n"
- "Starting vertex (startv var) couldn't be removed\n")
- return False
- bm.verts.ensure_lookup_table()
- bm.edges.ensure_lookup_table()
- bm.faces.ensure_lookup_table()
- list_3[1].select = 1
- list_3[-2].select = 1
- bm.edges.get([list_3[0], list_3[1]]).select = 1
- bm.edges.get([list_3[-1], list_3[-2]]).select = 1
- bm.verts.index_update()
- bm.edges.index_update()
- bm.faces.index_update()
-
- me.update(calc_edges=True, calc_loop_triangles=True)
- bmesh.ops.recalc_face_normals(bm, faces=bm.faces)
-
- except Exception as e:
- print("\n[Function fillets Error]\n{}\n".format(e))
- return False
-
-
-def do_filletplus(self, pair):
- is_finished = True
- try:
- startv = None
- global inaction
- global flip
- list_0 = [list([e.verts[0].index, e.verts[1].index]) for e in pair]
-
- vertset = set([])
- bm.verts.ensure_lookup_table()
- bm.edges.ensure_lookup_table()
- bm.faces.ensure_lookup_table()
- vertset.add(bm.verts[list_0[0][0]])
- vertset.add(bm.verts[list_0[0][1]])
- vertset.add(bm.verts[list_0[1][0]])
- vertset.add(bm.verts[list_0[1][1]])
-
- v1, v2, v3 = vertset
-
- if len(list_0) != 2:
- self.report({'WARNING'}, "Two adjacent edges must be selected")
- is_finished = False
- else:
- inaction = 1
- vertlist = []
- found = 0
- for f in v1.link_faces:
- if v2 in f.verts and v3 in f.verts:
- found = 1
- if not found:
- for v in [v1, v2, v3]:
- if v.index in list_0[0] and v.index in list_0[1]:
- startv = v
- face = None
- else:
- for f in v1.link_faces:
- if v2 in f.verts and v3 in f.verts:
- for v in f.verts:
- if not(v in vertset):
- vertlist.append(v)
- if (v in vertset and v.link_loops[0].link_loop_prev.vert in vertset and
- v.link_loops[0].link_loop_next.vert in vertset):
- startv = v
- face = f
- if out is True:
- flip = False
- if startv:
- fills = fillets(list_0, startv, vertlist, face, adj, n, out, flip, radius)
- if not fills:
- is_finished = False
- else:
- is_finished = False
- except Exception as e:
- print("\n[Function do_filletplus Error]\n{}\n".format(e))
- is_finished = False
- return is_finished
-
-
-def check_is_not_coplanar(bm_data):
- from mathutils import Vector
- check = False
- angles, norm_angle = 0, 0
- z_vec = Vector((0, 0, 1))
- try:
- bm_data.faces.ensure_lookup_table()
-
- for f in bm_data.faces:
- norm_angle = f.normal.angle(z_vec)
- if angles == 0:
- angles = norm_angle
- if angles != norm_angle:
- check = True
- break
- except Exception as e:
- print("\n[Function check_is_not_coplanar Error]\n{}\n".format(e))
- check = True
- return check
-
-
-# Operator
-
-class MESH_OT_fillet_plus(Operator):
- bl_idname = "mesh.fillet_plus"
- bl_label = "Fillet Plus"
- bl_description = ("Fillet adjoining edges\n"
- "Note: Works on a mesh whose all faces share the same normal")
- bl_options = {"REGISTER", "UNDO"}
-
- adj: FloatProperty(
- name="",
- description="Size of the filleted corners",
- default=0.1,
- min=0.00001, max=100.0,
- step=1,
- precision=3
- )
- n: IntProperty(
- name="",
- description="Subdivision of the filleted corners",
- default=3,
- min=1, max=50,
- step=1
- )
- out: BoolProperty(
- name="Outside",
- description="Fillet towards outside",
- default=False
- )
- flip: BoolProperty(
- name="Flip",
- description="Flip the direction of the Fillet\n"
- "Only available if Outside option is not active",
- default=False
- )
- radius: BoolProperty(
- name="Radius",
- description="Use radius for the size of the filleted corners",
- default=False
- )
-
- @classmethod
- def poll(cls, context):
- obj = context.active_object
- return (obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH')
-
- def draw(self, context):
- layout = self.layout
-
- if f_buf.check is False:
- layout.label(text="Angle is equal to 0 or 180", icon="INFO")
- layout.label(text="Can not fillet", icon="BLANK1")
- else:
- layout.prop(self, "radius")
- if self.radius is True:
- layout.label(text="Radius:")
- elif self.radius is False:
- layout.label(text="Distance:")
- layout.prop(self, "adj")
- layout.label(text="Number of sides:")
- layout.prop(self, "n")
-
- if self.n > 1:
- row = layout.row(align=False)
- row.prop(self, "out")
- if self.out is False:
- row.prop(self, "flip")
-
- def execute(self, context):
- global inaction
- global bm, me, adj, n, out, flip, radius
-
- adj = self.adj
- n = self.n
- out = self.out
- flip = self.flip
- radius = self.radius
-
- inaction = 0
- f_buf.check = False
-
- ob_act = context.active_object
- try:
- me = ob_act.data
- bm = bmesh.from_edit_mesh(me)
- warn_obj = bool(check_is_not_coplanar(bm))
- if warn_obj is False:
- tempset = set([])
- bm.verts.ensure_lookup_table()
- bm.edges.ensure_lookup_table()
- bm.faces.ensure_lookup_table()
- for v in bm.verts:
- if v.select and v.is_boundary:
- tempset.add(v)
- for v in tempset:
- edgeset = set([])
- for e in v.link_edges:
- if e.select and e.is_boundary:
- edgeset.add(e)
- if len(edgeset) == 2:
- is_finished = do_filletplus(self, edgeset)
- if not is_finished:
- break
-
- if inaction == 1:
- bpy.ops.mesh.select_all(action="DESELECT")
- for v in bm.verts:
- if len(v.link_edges) == 0:
- bm.verts.remove(v)
- bpy.ops.object.editmode_toggle()
- bpy.ops.object.editmode_toggle()
- else:
- self.report({'WARNING'}, "Filletplus operation could not be performed")
- return {'CANCELLED'}
- else:
- self.report({'WARNING'}, "Mesh is not a coplanar surface. Operation cancelled")
- return {'CANCELLED'}
- except:
- self.report({'WARNING'}, "Filletplus operation could not be performed")
- return {'CANCELLED'}
-
- return {'FINISHED'}