Не подтверждена Коммит d550a882 создал по автору Ilya V. Portnov's avatar Ilya V. Portnov Зафиксировано автором GitHub
Просмотр файлов

Merge pull request #2545 from nortikin/b28_inset_special_normals

Port " Inset special node: more precise normal calculation" to 2.80
владельцы 57918c61 f8447b4b
...@@ -22,9 +22,10 @@ import bpy ...@@ -22,9 +22,10 @@ import bpy
import mathutils import mathutils
from mathutils import Vector from mathutils import Vector
from bpy.props import FloatProperty, FloatVectorProperty, IntProperty from bpy.props import FloatProperty, FloatVectorProperty, IntProperty, EnumProperty
from sverchok.node_tree import SverchCustomTreeNode from sverchok.node_tree import SverchCustomTreeNode
from sverchok.utils.geom import calc_normal
from sverchok.data_structure import ( from sverchok.data_structure import (
updateNode, Vector_generate, updateNode, Vector_generate,
repeat_last, fullList) repeat_last, fullList)
...@@ -33,7 +34,7 @@ from sverchok.data_structure import ( ...@@ -33,7 +34,7 @@ from sverchok.data_structure import (
''' very non optimal routines. beware. I know this ''' ''' very non optimal routines. beware. I know this '''
def inset_special(vertices, faces, inset_rates, distances, ignores, make_inners): def inset_special(vertices, faces, inset_rates, distances, ignores, make_inners, normal_mode="Fast"):
new_faces = [] new_faces = []
new_ignores = [] new_ignores = []
...@@ -115,7 +116,10 @@ def inset_special(vertices, faces, inset_rates, distances, ignores, make_inners) ...@@ -115,7 +116,10 @@ def inset_special(vertices, faces, inset_rates, distances, ignores, make_inners)
new_verts_prime = [avg_vec.lerp(v, inset_by) for v in verts] new_verts_prime = [avg_vec.lerp(v, inset_by) for v in verts]
if distance: if distance:
local_normal = mathutils.geometry.normal(*new_verts_prime[:3]) if normal_mode == 'Fast':
local_normal = mathutils.geometry.normal(*new_verts_prime[:3])
else:
local_normal = calc_normal(new_verts_prime)
new_verts_prime = [v.lerp(v+local_normal, distance) for v in new_verts_prime] new_verts_prime = [v.lerp(v+local_normal, distance) for v in new_verts_prime]
vertices.extend(new_verts_prime) vertices.extend(new_verts_prime)
...@@ -149,7 +153,12 @@ class SvInsetSpecial(bpy.types.Node, SverchCustomTreeNode): ...@@ -149,7 +153,12 @@ class SvInsetSpecial(bpy.types.Node, SverchCustomTreeNode):
bl_label = 'Inset Special' bl_label = 'Inset Special'
bl_icon = 'OUTLINER_OB_EMPTY' bl_icon = 'OUTLINER_OB_EMPTY'
inset: FloatProperty( normal_modes = [
("Fast", "Fast", "Fast algorithm", 0),
("Exact", "Exact", "Slower, but exact algorithm", 1)
]
inset : FloatProperty(
name='Inset', name='Inset',
description='inset amount', description='inset amount',
default=0.1, update=updateNode) default=0.1, update=updateNode)
...@@ -161,6 +170,12 @@ class SvInsetSpecial(bpy.types.Node, SverchCustomTreeNode): ...@@ -161,6 +170,12 @@ class SvInsetSpecial(bpy.types.Node, SverchCustomTreeNode):
ignore: IntProperty(name='Ignore', description='skip polygons', default=0, update=updateNode) ignore: IntProperty(name='Ignore', description='skip polygons', default=0, update=updateNode)
make_inner: IntProperty(name='Make Inner', description='Make inner polygon', default=1, update=updateNode) make_inner: IntProperty(name='Make Inner', description='Make inner polygon', default=1, update=updateNode)
normal_mode : EnumProperty(name = "Normals",
description = "Normals calculation algorithm",
default = "Fast",
items = normal_modes,
update = updateNode)
# axis = FloatVectorProperty( # axis = FloatVectorProperty(
# name='axis', description='axis relative to normal', # name='axis', description='axis relative to normal',
# default=(0,0,1), update=updateNode) # default=(0,0,1), update=updateNode)
...@@ -180,6 +195,8 @@ class SvInsetSpecial(bpy.types.Node, SverchCustomTreeNode): ...@@ -180,6 +195,8 @@ class SvInsetSpecial(bpy.types.Node, SverchCustomTreeNode):
o.new('SvStringsSocket', 'ignored') o.new('SvStringsSocket', 'ignored')
o.new('SvStringsSocket', 'inset') o.new('SvStringsSocket', 'inset')
def draw_buttons_ext(self, context, layout):
layout.prop(self, "normal_mode")
def process(self): def process(self):
i = self.inputs i = self.inputs
...@@ -221,7 +238,8 @@ class SvInsetSpecial(bpy.types.Node, SverchCustomTreeNode): ...@@ -221,7 +238,8 @@ class SvInsetSpecial(bpy.types.Node, SverchCustomTreeNode):
'inset_rates': inset_rates, 'inset_rates': inset_rates,
'distances': distance_vals, 'distances': distance_vals,
'make_inners': make_inners, 'make_inners': make_inners,
'ignores': ignores 'ignores': ignores,
'normal_mode': self.normal_mode
} }
res = inset_special(**func_args) res = inset_special(**func_args)
......
...@@ -907,6 +907,27 @@ def interpolate_quadratic_bezier(knot1, handle, knot2, resolution): ...@@ -907,6 +907,27 @@ def interpolate_quadratic_bezier(knot1, handle, knot2, resolution):
handle2 = handle + (1.0/3.0) * (knot2 - handle) handle2 = handle + (1.0/3.0) * (knot2 - handle)
return interpolate_bezier(knot1, handle1, handle2, knot2, resolution) return interpolate_bezier(knot1, handle1, handle2, knot2, resolution)
def calc_normal(vertices):
"""
Calculate normal for a face defined by specified vertices.
For tris or quads, mathutils.geometry.normal() is used.
Ngon will be triangulated, and then the average normal of
all resulting tris will be returned.
input: list of 3-tuples or list of mathutils.Vector.
output: mathutils.Vector.
"""
n = len(vertices)
vertices = list(map(mathutils.Vector, vertices))
if n <= 4:
return mathutils.geometry.normal(*vertices)
else:
# Triangluate
triangle_idxs = [[0, k, k+1] for k in range(1, n-1)]
triangles = [[vertices[i] for i in idxs] for idxs in triangle_idxs]
subnormals = [mathutils.geometry.normal(*triangle) for triangle in triangles]
return mathutils.Vector(center(subnormals))
def multiply_vectors(M, vlist): def multiply_vectors(M, vlist):
# (4*4 matrix) X (3*1 vector) # (4*4 matrix) X (3*1 vector)
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать