Коммит 2f8cd663 создал по автору Durman's avatar Durman
Просмотр файлов

Merge remote-tracking branch 'origin/master' into sv_get_bottleneck

# Conflicts:
#	core/main_tree_handler.py
владельцы a8b43255 f7537fba
......@@ -8,4 +8,5 @@ Contributing to sverchok
contribute_small_things
contribute_general
add_new_node
node_api
testing
\ Нет новой строки в конце файла
Это отличие свёрнуто
......@@ -64,6 +64,9 @@ you make them visible on the ui by doing::
def ui(self, context, layout):
layout.prop(self, 'custom_enum', expand=True)
layout.prop(self, 'custom_enum_2', expand=True)
pass
When adding a custom UI drawing function (as above) it's sometimes necessary to add an explicit ``pass`` or ``return`` "terminator" statement at the end, this is down to a bug i've not had time to track down yet. If you get unexplainable/illogical python errors with a `def ui`, then add a "terminator".
in your code you might use them this way::
......
Simple Text
===========
Functionality
-------------
This node can be used to pass a single string into the Node Tree, through a Text socket.
.. image:: https://user-images.githubusercontent.com/619340/169515003-bb510280-686b-407d-a7a4-af1d8a633e56.png
Stethoscope
===========
*destination after Beta: basic data*
Functionality
-------------
......
......@@ -15,3 +15,4 @@ Text
stethoscope_v28
gtext
string_tools
simple_text
......@@ -629,6 +629,7 @@
SvGTextNode
---
SvStringsToolsNode
SvSimpleTextNode
## BPY Data
SvGetPropNode
......
"""
>in verts_in v
>in edges_in s
out verts_out v
out edges_out s
out faces_out s
"""
import bmesh
bool_parameters = dict(
use_beauty=True,
use_dissolve=True
)
# pass input into this node from Component Analyzer (in Edges mode and is_boundary)
# (geom) -> Component Analyzer -> Snlite -> VD
for verts, edges in zip(verts_in, edges_in):
bm = bmesh_from_pydata(verts, edges, [])
bmesh.ops.triangle_fill(bm, edges=bm.edges[:], **bool_parameters)
v, e, f = pydata_from_bmesh(bm)
_ = [verts_out.append(v), edges_out.append(e), faces_out.append(f)]
"""
>in filepath FP
out verts v
"""
# more elaborate example is found here (includes applying transforms)
#
# https://gist.github.com/zeffii/2fdd78613801e5e137874136b1773781
#
import ast
import re
import xml.etree.ElementTree as ET
# input path will probably be wrapped using [[ ]],
# therefore use [0][0] to extract the path string
file_path = filepath[0][0]
with open(file_path) as ofile:
file_string = re.sub("inkscape:", '', ofile.read())
root = ET.fromstring(file_string)
for item in root.findall("g"):
for inner_item in item.findall("g"):
a = inner_item.get("transform")
print(a)
for polygon in inner_item.findall("polygon"):
# print(polygon.get("points"))
new_verts = ast.literal_eval(polygon.get("points").replace(" ", ",")) # flat
coords_2d = np.array(new_verts).reshape((-1, 2)) # 2d vectors
coords_3d = np.hstack((coords_2d, np.zeros((coords_2d.shape[0], 1)))) # 3d vectors
verts.append(coords_3d.tolist()) # tolist is optional if downstream nodes can handle np arrays
......@@ -174,19 +174,20 @@ class ListJoinNode(bpy.types.Node, SverchCustomTreeNode):
if len(self.outputs) > 0:
multi_socket(self, min=1)
self.set_output_socketype([sock.other.bl_idname for sock in self.inputs if sock.links and sock.other])
self.set_output_socketype([sock.other.bl_idname for sock in self.inputs if sock.is_linked and sock.other])
def process(self):
if not self.outputs['data'].links:
if not self.outputs['data'].is_linked:
return
slots = []
for socket in self.inputs:
if socket.is_linked and socket.links:
if socket.is_linked:
slots.append(socket.sv_get(deepcopy=False))
if len(slots) == 0:
if not slots:
return
if self.match_and_join:
match_func = list_match_func[self.list_match]
if self.mix_check:
......@@ -230,9 +231,8 @@ class ListJoinNode(bpy.types.Node, SverchCustomTreeNode):
mixing = "M" if self.mix_check else ""
wrapping = "W" if self.wrap_check and not self.numpy_mode else ""
numpy_m = "NP " if self.numpy_mode else ""
level = str(self.JoinLevel)
fstr = " Lv={0} {1}{2}{3}".format(level, numpy_m, mixing, wrapping)
return self.name + fstr
return f"{self.name} Lv={self.JoinLevel} {numpy_m}{mixing}{wrapping}"
def register():
......
......@@ -217,8 +217,8 @@ class SvMatrixTrackToNode(bpy.types.Node, SverchCustomTreeNode):
matrix_list, x_list, y_list, z_list = self.matrix_track_to(match_long_repeat(par), mT, mU, orthogonalize, gates)
m_add(matrix_list)
x_add([x_list])
y_add(y_list)
z_add(z_list)
y_add([y_list])
z_add([z_list])
outputs["Matrix"].sv_set(matrix_lists)
outputs["X"].sv_set(x_lists)
......
......@@ -148,16 +148,16 @@ class SvNumberNode(Show3DProperties, DraftMode, bpy.types.Node, SverchCustomTree
if not self.inputs[0].links:
value = getattr(self, prop_name)
if kind == 'float':
label = 'Float: ' + str(round(value, 3))
label = f"Float: {value:.3f}"
else:
label = 'Int: ' + str(value)
label = f"Int: {value}"
else:
label = kind.title()
else:
label = self.label or self.name
if self.id_data.sv_draft:
label = "[D] " + label
label = f"[D] {label}"
return label
......
......@@ -496,13 +496,17 @@ class SvScriptNodeLite(bpy.types.Node, SverchCustomTreeNode):
for socket_name in requirements:
if self.inputs.get(socket_name):
obtained_data = self.inputs[socket_name].sv_get(default=None)
# print(f"{obtained_data} from {socket_name}")
if obtained_data is None:
continue
try:
if obtained_data and obtained_data[0]:
required_count += 1
except:
if obtained_data:
if isinstance(obtained_data[0], np.ndarray) and obtained_data[0].any():
required_count += 1
continue
if obtained_data[0]:
required_count += 1
except Exception as err:
# print("ending early 2", err)
...
requirements_met = required_count == len(requirements)
......
import bpy
import sverchok
class SvSimpleTextNode(bpy.types.Node, sverchok.node_tree.SverchCustomTreeNode):
"""
Triggers: Text string
Tooltip: simple text
"""
bl_idname = 'SvSimpleTextNode'
bl_label = 'Simple Text'
bl_icon = 'FILE_TEXT'
def sv_init(self, context):
item = self.outputs.new('SvTextSocket', "Text")
item.custom_draw = "draw_output"
def draw_output(self, socket, context, layout):
row = layout.row(align=True)
row.prop(socket, "default_property", text="")
def process(self):
text_socket = self.outputs[0]
text_socket.sv_set([[text_socket.default_property]])
classes = [SvSimpleTextNode]
register, unregister = bpy.utils.register_classes_factory(classes)
......@@ -66,7 +66,8 @@ def find_all_slice(text, chars, start, end):
return out
def number_to_string(data, precision):
return ("{:." + str(precision) + "f}").format(float(data))
precision = max(0, precision) # can't have negative, and abs() might be confusing
return f"{float(data):.{precision}f}"
func_dict = {
"---------------OPS" : "#---------------------------------------------------#",
......@@ -239,11 +240,14 @@ class SvStringsToolsNode(bpy.types.Node, SverchCustomTreeNode):
socket_info = func_dict.get(self.current_op)[2]
if self.sockets_signature == socket_info:
return
t_inputs, t_outputs = socket_info.split(' ')
old_inputs, old_outputs = self.sockets_signature.split(' ')
self.sockets_signature = socket_info
for s in range(len(self.inputs[1:])):
self.inputs.remove(self.inputs[-1])
for idx, s in enumerate(t_inputs[1:]):
if s=="t":
socket = self.inputs.new('SvTextSocket', 'Text 2')
......@@ -257,16 +261,17 @@ class SvStringsToolsNode(bpy.types.Node, SverchCustomTreeNode):
elif s=="s":
socket = self.inputs.new('SvStringsSocket', 'Number')
socket.prop_name = 'xi_'
elif s=="n":
socket = self.inputs.new('SvStringsSocket', 'Number 2')
socket.prop_name = 'yi_'
socket.custom_draw = 'draw_prop_socket'
socket.label = socket.name
elif s=="b":
socket = self.inputs.new('SvTextSocket', 'Keep Breaks')
socket.prop_name = 'keep_brakes'
# all sockets will receive custom_draw
socket.custom_draw = 'draw_prop_socket'
if len(data)>4:
print(data[4], idx)
socket.label = data[4][idx]
......
......@@ -145,6 +145,7 @@ class SvPolylineViewerNode(SvViewerNode, bpy.types.Node, SverchCustomTreeNode):
row = row.row()
row.scale_x = 0.5
row.prop(self, 'close', toggle=True)
row.prop(self, "preview_resolution_u")
def draw_object_props(self, socket, context, layout):
row = layout.row(align=True)
......
......@@ -206,7 +206,12 @@ class CubicSpline(Spline):
if is_cyclic:
#print(describe_data_shape(vertices))
locs = np.array(vertices[-4:] + vertices + vertices[:4])
if len(vertices) == 3:
va, vb, vc = vertices[0], vertices[1], vertices[2]
locs = np.array([vc, va, vb, vc, va, vb, vc, va, vb, vc, va])
else:
locs = np.array(vertices[-4:] + vertices + vertices[:4])
if tknots is None:
if metric is None:
raise Exception("CubicSpline: either tknots or metric must be specified")
......
......@@ -8,6 +8,7 @@
import math
import random
import numpy as np
def interp_v3_v3v3(a, b, t=0.5):
"""
......@@ -166,6 +167,35 @@ def random_pt_between(v1, v2, v3):
return sum_v3_v3l([v1, A, B])
def ccw_angle(v1, v2, normal):
"""
you want to know the counter-clockwise angle between 3 vertices.
v1
/
/
v0
\
\
v2
input: # all must be numpy arrays
input: v1, v2 # are vectors positioned in respect to an origin (v0)
input: normal # this determines the direction of ccw. (relative to which axis)
output: angle in radians
https://uk.mathworks.com/matlabcentral/answers/461410
'how-to-get-direction-for-3d-angles-between-2-vectors'
if v0 is not already at [0, 0, 0] then you must translate the v1 and v2 locations first.
ccw_angle(v1-v0, v2-v0, normal)
"""
ang = np.arctan2(np.linalg.norm(np.cross(v1, v2)), np.dot(v1, v2))
if np.dot(np.cross(v1, v2), normal) < 0:
ang = 2*np.pi - ang
return ang
def mul_v3_f1v3(a, v):
return a*v[0], a*v[1], a*v[2]
......@@ -186,3 +216,4 @@ def sum_v3_v3l(lvtx):
vy += v[1]
vz += v[2]
return vx, vy, vz
......@@ -18,7 +18,7 @@ from sverchok.ui import bgl_callback_nodeview as nvBGL2
from sverchok.utils.modules.shader_utils import ShaderLib2D
# todo the module should be rewritten according new update system
# https://github.com/nortikin/sverchok/commit/c0ef777acef561a5e9cd308ec05c1382b9006de8
display_dict = {} # 'sverchok': None}
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать