Коммит 9cd424ad создал по автору rastart's avatar rastart
Просмотр файлов

Merge remote-tracking branch 'upstream/master'

владельцы 1e842ae2 b3cef663
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
bl_info = { bl_info = {
"name": "Sverchok", "name": "Sverchok",
"author": "sverchok-b3d@ya.ru various authors see https://github.com/nortikin/sverchok/graphs/contributors", "author": "sverchok-b3d@ya.ru various authors see https://github.com/nortikin/sverchok/graphs/contributors",
"version": (1, 0, 0), "version": (1, 0, 1),
"blender": (2, 93, 0), "blender": (2, 93, 0),
"location": "Node Editor", "location": "Node Editor",
"category": "Node", "category": "Node",
......
...@@ -1192,9 +1192,11 @@ def extend_blender_class(cls): ...@@ -1192,9 +1192,11 @@ def extend_blender_class(cls):
Take into account that this decorator does not delete anything onto reload event Take into account that this decorator does not delete anything onto reload event
""" """
bl_class = getattr(bpy.types, cls.__name__) bl_class = getattr(bpy.types, cls.__name__)
for base_cls in chain([cls], cls.__bases__[1:]): for base_cls in chain([cls], cls.__bases__):
if hasattr(base_cls, '__annotations__'): # https://docs.python.org/3/howto/annotations.html#accessing-the-annotations-dict-of-an-object-in-python-3-9-and-older
for name, prop in base_cls.__annotations__.items(): # avoiding getting inherited annotations
if '__annotations__' in base_cls.__dict__:
for name, prop in base_cls.__dict__['__annotations__'].items():
setattr(bl_class, name, prop) setattr(bl_class, name, prop)
for key in (key for key in dir(base_cls) if not key.startswith('_')): for key in (key for key in dir(base_cls) if not key.startswith('_')):
setattr(bl_class, key, getattr(base_cls, key)) setattr(bl_class, key, getattr(base_cls, key))
......
Ellipse
=======
Functionality
-------------
The ellipse node creates ellipses given a set of main parameters: major/minor radii, eccentricity, focal length. Additional parameters allow you to tweak the ellipse curve: phase, rotation, scale and x/y exponents.
Super Ellipse formula:
(x/a)^n + (y/b)^m = 1
Different values of the x and y exponents (n and m) generate various shapes such as: asteroid, square/rhombus, circle/ellipse, squircle/rectellipse.
asteroid: 0 < n,m < 1
square/diamond: n/m = 1
circle/ellipse: n/m = 2
squircle/rectellipse: n/m > 2
Inputs
------
All inputs are vectorized and they will accept single or multiple values.
- **Major Radius**
- **Minor Radius** [1]
- **Eccentricity** [2]
- **Focal Length** [3]
- **Num Verts**
- **Phase** [4]
- **Rotation** [4]
- **Scale**
- **Exponent X**
- **Exponent Y**
Notes:
[1] : The Minor Radius is available in **ab** mode
[2] : The Eccentricity is available in **ae** mode
[3] : The Focal Length is available in **ac** mode
[4] : The angles are in DEGREES. The Property Panel has option to set angle units as: RADIANS, DEGREES or UNITIES.
Parameters
----------
The **Mode** parameter allows to select one of the three modes of defining the ellipse: **ab**, **ae** and **ac**.
- In **ab** mode the ellipse is defined by the major radius (a) and minor radius (b).
- In **ae** mode the ellipse is defined by the major radius (a) and the eccentricity (e).
- In **ac** mode the ellipse is defined by the major radius (a) and the focal length (c).
Note: when switching modes the main ellipse parameters for the new mode are derived based on the main parameters of the previous mode as to keep the ellipse the same.
The **Centering** parameter lets you center the ellipse around one of its focal points F1 or F2 or around its center C.
All parameters except **Mode** and **Centering** can take values from the node itself or an external input.
The inputs are "sanitized" to restrict their values to valid domains:
- Major radius (a) and Minor radius (b) are floats with values >= 0.0 and b <= a
- Eccentricity is a float with value in the range [0.0, 1.0]
- Focal Length is a float with value in the range [0.0, a]
- Number of vertices is an integer with value >= 3
- Scale is a float with values >= 0.0
+------------------+--------+---------+------------------------------------------------------------+
| Param | Type | Default | Description |
+==================+========+=========+============================================================+
| **Major Radius** | Float | 1.0 | Major radius of the ellipse |
+------------------+--------+---------+------------------------------------------------------------+
| **Minor Radius** | Float | 0.8 | Minor radius of the ellipse [1] |
+------------------+--------+---------+------------------------------------------------------------+
| **Eccentricity** | Float | 0.6 | Eccentricity of the ellipse [2] |
+------------------+--------+---------+------------------------------------------------------------+
| **Focal Length** | Float | 0.6 | Distance between the center and one of the foci [3] |
+------------------+--------+---------+------------------------------------------------------------+
| **Num Verts** | Int | 36 | Number of vertices in the ellipse |
+------------------+--------+---------+------------------------------------------------------------+
| **Phase** | Float | 0.0 | Phase the vertices along the ellipse around its center [4] |
+------------------+--------+---------+------------------------------------------------------------+
| **Rotation** | Float | 0.0 | Rotate the ellipse around its centering point [4] |
+------------------+--------+---------+------------------------------------------------------------+
| **Scale** | Float | 1.0 | Scale the ellipse radii by this amount. |
+------------------+--------+---------+------------------------------------------------------------+
| **Exponent X** | Float | 2.0 | Exponent modulating the curve X direction. [5] |
+------------------+--------+---------+------------------------------------------------------------+
| **Exponent Y** | Float | 2.0 | Exponent modulating the curve Y direction. [5] |
+------------------+--------+---------+------------------------------------------------------------+
Notes:
[1] : The Minor Radius is available in **ab** mode
[2] : The Eccentricity is available in **ae** mode
[3] : The Focal Length is available in **ac** mode
[4] : Angles are given by default in DEGREES. The Property Panel has option to set angle units as: RADIANS, DEGREES or UNITIES.
[5] : Various combinations of the XY exponents generate different super ellipse curves (e.g. eX = eY = 2 the shape is an ellipse)
Extra Parameters
----------------
A set of extra parameters are available on the property panel.
These parameters do not receive external input.
+------------------+----------+---------+--------------------------------------+
| Extra Param | Type | Default | Description |
+==================+==========+=========+======================================+
| **Angle Units** | Enum | DEGREES | Interprets the angle values based on |
| | RADIANS | | the selected angle units: |
| | DEGREES | | Radians = 0 - 2pi |
| | UNITIES | | Degrees = 0 - 360 |
| | | | Unities = 0 - 1 |
+------------------+----------+---------+--------------------------------------+
Outputs
-------
Outputs will be generated when connected.
**Verts**, **Edges**, **Polys**
These are the vertices, edges and polygons of the ellipse.
**F1**, **F2**
These are the locations of the ellipse foci.
Presets
-------
A set of super ellipse configuration **presets** is available for convenience. Once a preset is selected the super ellipse settings are updated with the preset values and the user can modify the settings to further alter the super ellipse shape.
Note: once a setting is altered (after selecting a preset) the preset selection is cleared from the preset drop-down indicating that the new setting configuration is no longer the one corresponding to the previously selected preset.
+------------------+-----+-----+-----+-----+-----+
| Preset | R | r | eX | eY | N |
+==================+=====+=====+=====+=====+=====+
| **STAR** | 1.0 | 1.0 | 0.3 | 0.3 | 200 |
+------------------+-----+-----+-----+-----+-----+
| **ASTROID** | 1.0 | 1.0 | 0.6 | 0.6 | 200 |
+------------------+-----+-----+-----+-----+-----+
| **DIAMOND** | 1.0 | 0.6 | 1.0 | 1.0 | 100 |
+------------------+-----+-----+-----+-----+-----+
| **EYELENS** | 1.0 | 0.6 | 2.0 | 1.0 | 100 |
+------------------+-----+-----+-----+-----+-----+
| **SQUARE** | 1.0 | 1.0 | 1.0 | 1.0 | 100 |
+------------------+-----+-----+-----+-----+-----+
| **CIRCLE** | 1.0 | 1.0 | 2.0 | 2.0 | 100 |
+------------------+-----+-----+-----+-----+-----+
| **ELLIPSE** | 1.0 | 0.6 | 2.0 | 2.0 | 100 |
+------------------+-----+-----+-----+-----+-----+
| **SQUIRCLE** | 1.0 | 1.0 | 4.0 | 4.0 | 100 |
+------------------+-----+-----+-----+-----+-----+
| **HYPOELLIPSE** | 1.0 | 0.6 | 1.5 | 1.5 | 100 |
+------------------+-----+-----+-----+-----+-----+
| **HYPERELLIPSE** | 1.0 | 0.6 | 2.5 | 2.5 | 100 |
+------------------+-----+-----+-----+-----+-----+
| **RECTELLIPSE** | 1.0 | 0.6 | 4.0 | 4.0 | 100 |
+------------------+-----+-----+-----+-----+-----+
Example of usage
----------------
Reference
---------
https://mathworld.wolfram.com/Superellipse.html
https://en.wikipedia.org/wiki/Superellipse
https://en.wikipedia.org/wiki/Ellipse
...@@ -14,7 +14,7 @@ Generators Extended ...@@ -14,7 +14,7 @@ Generators Extended
regular_solid regular_solid
ring_mk2 ring_mk2
smooth_lines smooth_lines
ellipse_mk2 ellipse_mk3
torus_knot_mk2 torus_knot_mk2
conic_section conic_section
super_ellipsoid super_ellipsoid
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
SvWFCTextureNode SvWFCTextureNode
SvTorusKnotNodeMK2 SvTorusKnotNodeMK2
SvRingNodeMK2 SvRingNodeMK2
SvEllipseNodeMK2 SvEllipseNodeMK3
SvSuperEllipsoidNode SvSuperEllipsoidNode
SvRegularSolid SvRegularSolid
SvConicSectionNode SvConicSectionNode
......
# ##### 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 #####
import bpy
from bpy.props import BoolProperty, IntProperty, FloatProperty, EnumProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import (match_long_repeat, updateNode, get_edge_loop)
from sverchok.utils.sv_transform_helper import AngleUnits, SvAngleHelper
from math import sin, cos, pi, sqrt
centering_items = [("F1", "F1", "Ellipse focal point 1", 1),
("C", "C", "Ellipse center point", 2),
("F2", "F2", "Ellipse focal point 2", 3)]
mode_items = [("AB", "a b", "Major Radius / Minor Radius", 1),
("AE", "a e", "Major Radius / Eccentricity", 2),
("AC", "a c", "Major Radius / Focal Length", 3)]
def sign(x): return 1 if x > 0 else -1 if x < 0 else 0
epsilon = 1e-10 # used to eliminate division by zero
# name : [ major radius, minor radius, x exponent, y exponent, num verts ]
super_presets = {
"_": [0.0, 0.0, 0.0, 0.0, 0],
"STAR": [1.0, 1.0, 0.3, 0.3, 200],
"ASTROID": [1.0, 1.0, 0.6, 0.6, 200],
"DIAMOND": [1.0, 0.6, 1.0, 1.0, 100],
"EYELENS": [1.0, 0.6, 2.0, 1.0, 100],
"SQUARE": [1.0, 1.0, 1.0, 1.0, 100],
"CIRCLE": [1.0, 1.0, 2.0, 2.0, 100],
"ELLIPSE": [1.0, 0.6, 2.0, 2.0, 100],
"SQUIRCLE": [1.0, 1.0, 4.0, 4.0, 100],
"HYPOELLIPSE": [1.0, 0.6, 1.5, 1.5, 100],
"HYPERELLIPSE": [1.0, 0.6, 2.5, 2.5, 100],
"RECTELLIPSE": [1.0, 0.6, 4.0, 4.0, 100],
}
class SvEllipseNodeMK3(bpy.types.Node, SverchCustomTreeNode, SvAngleHelper):
"""
Triggers: Ellipse Super-Ellipse
Tooltip: Generate various types of (super) ellipse shapes
"""
bl_idname = 'SvEllipseNodeMK3'
bl_label = 'Ellipse'
sv_icon = 'SV_ELLIPSE'
def update_mode(self, context):
''' Update the ellipse parameters of the new mode based on previous mode ones '''
if self.mode == self.last_mode:
return
# from to
switch_state = (self.last_mode, self.mode)
a = self.major_radius
e = self.eccentricity
c = self.focal_length
self.updating = True
if switch_state == ("AE", "AB"):
self.minor_radius = a * sqrt(1 - e * e)
elif switch_state == ("AC", "AB"):
c = min(a, c)
self.minor_radius = sqrt(a * a - c * c)
elif switch_state == ("AB", "AE"):
b = min(a, self.minor_radius)
self.eccentricity = sqrt(1 - (b * b) / (a * a))
elif switch_state == ("AC", "AE"):
self.eccentricity = c / a
elif switch_state == ("AB", "AC"):
b = min(a, self.minor_radius)
self.focal_length = sqrt(a * a - b * b)
elif switch_state == ("AE", "AC"):
self.focal_length = a * e
self.updating = False
self.last_mode = self.mode
self.update_sockets()
updateNode(self, context)
def update_ellipse(self, context):
if self.updating:
return
self.presets = "_"
updateNode(self, context)
def update_angles(self, context, au):
''' Update all the angles to preserve their values in the new units '''
self.phase = self.phase * au
self.rotation = self.rotation * au
def update_presets(self, context):
self.updating = True
if self.presets == "_":
self.updating = False
return
a, b, ex, ey, n = super_presets[self.presets.replace(" ", "_")]
self.major_radius = a
self.minor_radius = b
self.num_verts = n
self.phase = 0.0
self.rotation = 0.0
self.scale = 1.0
self.exponent_x = ex
self.exponent_y = ey
self.mode = "AB"
self.last_mode = "AB"
self.centering = "C"
self.updating = False
updateNode(self, context)
preset_items = [(k, k.replace("_", " ").title(), "", "", i) for i, (k, v) in enumerate(sorted(super_presets.items()))]
presets: EnumProperty(
name="Presets", items=preset_items, description="Various presets",
update=update_presets)
centering: EnumProperty(
name="Centering", items=centering_items,
description="Center the ellipse around F1, C or F2",
default="C", update=updateNode)
mode: EnumProperty(
name="Mode", items=mode_items,
description="Ellipse definition mode",
default="AB", update=update_mode)
last_mode: EnumProperty(
name="Last Mode", items=mode_items,
description="Last ellipse definition mode",
default="AB")
major_radius: FloatProperty(
name='Major Radius', description='Ellipse major radius',
default=1.0, min=0.0, update=update_ellipse)
minor_radius: FloatProperty(
name='Minor Radius', description='Ellipse minor radius',
default=0.8, min=0.0, update=update_ellipse)
eccentricity: FloatProperty(
name='Eccentricity', description='Ellipse eccentricity',
default=0.6, min=0.0, max=1.0, update=update_ellipse)
focal_length: FloatProperty(
name='Focal Length', description='Ellipse focal length',
default=0.6, min=0.0, update=update_ellipse)
num_verts: IntProperty(
name='Num Verts', description='Number of vertices in the ellipse',
default=36, min=3, update=updateNode)
phase: FloatProperty(
name='Phase', description='Phase ellipse vertices around the center by this angle amount',
default=0.0, update=SvAngleHelper.update_angle)
rotation: FloatProperty(
name='Rotation', description='Rotate ellipse vertices around the centering point by this angle amount',
default=0.0, update=SvAngleHelper.update_angle)
scale: FloatProperty(
name='Scale', description='Scale ellipse radii by this factor',
default=1.0, min=0.0, update=updateNode)
exponent_x: FloatProperty(
name='Exponent X', description='Exponent X to modulate the ellipse along X direction',
default=2.0, min=0.0, update=updateNode)
exponent_y: FloatProperty(
name='Exponent Y', description='Exponent Y to modulate the ellipse along Y direction',
default=2.0, min=0.0, update=updateNode)
updating: BoolProperty(default=False) # used for disabling update callback
def migrate_from(self, old_node):
''' Migration from old nodes '''
if old_node.bl_idname == "SvEllipseNode":
self.angle_units = AngleUnits.RADIANS
self.last_angle_units = AngleUnits.RADIANS
def sv_init(self, context):
self.width = 160
self.inputs.new('SvStringsSocket', "Major Radius").prop_name = "major_radius"
self.inputs.new('SvStringsSocket', "Minor Radius").prop_name = "minor_radius"
self.inputs.new('SvStringsSocket', "Num Verts").prop_name = "num_verts"
self.inputs.new('SvStringsSocket', "Phase").prop_name = "phase"
self.inputs.new('SvStringsSocket', "Rotation").prop_name = "rotation"
self.inputs.new('SvStringsSocket', "Scale").prop_name = "scale"
self.inputs.new('SvStringsSocket', "Exponent X").prop_name = "exponent_x"
self.inputs.new('SvStringsSocket', "Exponent Y").prop_name = "exponent_y"
self.outputs.new('SvVerticesSocket', "Verts")
self.outputs.new('SvStringsSocket', "Edges")
self.outputs.new('SvStringsSocket', "Polys")
self.outputs.new('SvVerticesSocket', "F1")
self.outputs.new('SvVerticesSocket', "F2")
self.presets = "ELLIPSE"
def draw_buttons(self, context, layout):
if not self.inputs["Exponent X"].is_linked and not self.inputs["Exponent Y"].is_linked:
layout.prop(self, "presets", text="")
col = layout.column(align=True)
row = col.row(align=True)
row.prop(self, "mode", expand=True)
row = col.row(align=True)
row.prop(self, "centering", expand=True)
def draw_buttons_ext(self, context, layout):
self.draw_angle_units_buttons(context, layout)
def update_sockets(self):
if self.mode == "AB":
socket2 = self.inputs[1]
socket2.replace_socket("SvStringsSocket", "Minor Radius").prop_name = "minor_radius"
elif self.mode == "AE":
socket2 = self.inputs[1]
socket2.replace_socket("SvStringsSocket", "Eccentricity").prop_name = "eccentricity"
else: # AC
socket2 = self.inputs[1]
socket2.replace_socket("SvStringsSocket", "Focal Length").prop_name = "focal_length"
def make_ellipse(self, a, b, N, phase, rotation, scale, ex, ey):
'''
Make an Ellipse (verts, edges and polys)
a : major radius of the ellipse
b : minor radius of the ellipse
N : number of vertices in the curve
phase : shift the points along the curve by this angle amount
rotation : rotate the ellipse in plane by this angle amount
scale : scale the major & minor radii by this factor
ex : exponent x (modulates the ellipse along x direction)
ey : exponent y (modulates the ellipse along y direction)
'''
verts = []
edges = []
polys = []
a = a * scale
b = b * scale
if a > b:
dx = sqrt(a * a - b * b)
dy = 0
else:
dx = 0
dy = sqrt(b * b - a * a)
if self.centering == "F1":
cx = -dx
cy = -dy
elif self.centering == "F2":
cx = +dx
cy = +dy
else: # "C"
cx = 0
cy = 0
sins = sin(rotation) # cached for performance
coss = cos(rotation) # cached for performance
# locations of the focal points of the centered and rotated ellipse
f1x = -cx - dx
f1y = -cy - dy
f2x = -cx + dx
f2y = -cy + dy
f1xx = f1x * coss - f1y * sins
f1yy = f1x * sins + f1y * coss
f2xx = f2x * coss - f2y * sins
f2yy = f2x * sins + f2y * coss
f1 = [f1xx, f1yy, 0]
f2 = [f2xx, f2yy, 0]
delta = 2 * pi / N # angle increment (cached for performance)
exx = 2.0 / (ex + epsilon)
eyy = 2.0 / (ey + epsilon)
add_vert = verts.append
for n in range(N):
theta = delta * n + phase
cost = cos(theta)
sint = sin(theta)
x = -cx + a * pow(abs(cost), exx) * sign(cost)
y = -cy + b * pow(abs(sint), eyy) * sign(sint)
# apply in-plane rotation
xx = x * coss - y * sins
yy = x * sins + y * coss
add_vert((xx, yy, 0))
edges = get_edge_loop(N)
polys = [list(range(N))]
return verts, edges, polys, f1, f2
def process(self):
outputs = self.outputs
# return if no outputs are connected
if not any(s.is_linked for s in outputs):
return
# input values lists (single or multi value)
inputs = self.inputs
input_v1 = inputs[0].sv_get()[0] # major radius
input_v2 = inputs[1].sv_get()[0] # minor radius, eccentricity or focal length
input_N = inputs["Num Verts"].sv_get()[0]
input_p = inputs["Phase"].sv_get()[0]
input_r = inputs["Rotation"].sv_get()[0]
input_s = inputs["Scale"].sv_get()[0]
input_ex = inputs["Exponent X"].sv_get()[0]
input_ey = inputs["Exponent Y"].sv_get()[0]
# convert main input parameters to major/minor radii (and sanitize inputs)
if self.mode == "AB":
input_a, input_b = match_long_repeat([input_v1, input_v2])
input_a = list(map(lambda a: max(0.0, a), input_a))
input_b = list(map(lambda a, b: max(0.0, min(a, b)), input_a, input_b))
elif self.mode == "AE":
input_a, input_e = match_long_repeat([input_v1, input_v2])
input_a = list(map(lambda a: max(0.0, a), input_a))
input_e = list(map(lambda e: max(0.0, min(1.0, e)), input_e))
input_b = list(map(lambda a, e: a * sqrt(1 - e * e), input_a, input_e))
else: # "AC"
input_a, input_c = match_long_repeat([input_v1, input_v2])
input_a = list(map(lambda a: max(0.0, a), input_a))
input_c = list(map(lambda a, c: max(0.0, min(a, c)), input_a, input_c))
input_b = list(map(lambda a, c: sqrt(a * a - c * c), input_a, input_c))
# sanitize more inputs
input_N = list(map(lambda n: max(3, int(n)), input_N))
input_s = list(map(lambda s: max(0.0, s), input_s))
input_ex = list(map(lambda e: max(0.0, e), input_ex))
input_ey = list(map(lambda e: max(0.0, e), input_ey))
parameters = match_long_repeat([input_a, input_b, input_N,
input_p, input_r, input_s,
input_ex, input_ey])
# conversion factor from the current angle units to radians
au = self.radians_conversion_factor()
verts_list = []
edges_list = []
polys_list = []
f1_list = []
f2_list = []
for a, b, N, p, r, s, ex, ey in zip(*parameters):
verts, edges, polys, f1, f2 = self.make_ellipse(a, b, N, p * au, r * au, s, ex, ey)
verts_list.append(verts)
edges_list.append(edges)
polys_list.append(polys)
f1_list.append(f1)
f2_list.append(f2)
outputs["Verts"].sv_set(verts_list)
outputs["Edges"].sv_set(edges_list)
outputs["Polys"].sv_set(polys_list)
outputs["F1"].sv_set([f1_list])
outputs["F2"].sv_set([f2_list])
def register():
bpy.utils.register_class(SvEllipseNodeMK3)
def unregister():
bpy.utils.unregister_class(SvEllipseNodeMK3)
...@@ -135,8 +135,21 @@ class SvgDimension(): ...@@ -135,8 +135,21 @@ class SvgDimension():
text_svg += self.text_attributes.draw(document) text_svg += self.text_attributes.draw(document)
text_svg += '>' text_svg += '>'
precision = self.node.decimal_precision precision = self.node.decimal_precision
p_format = "{:10."+str(precision)+"f}" if self.node.units_real == 'Metric':
text_svg += p_format.format((dim_loc_b - dim_loc_a).length) p_format = "{:10."+str(precision)+"f}"
text_svg += p_format.format((dim_loc_b - dim_loc_a).length)
else:
feets = (dim_loc_b - dim_loc_a).length//0.3048
if feets < 2:
inches = ((dim_loc_b - dim_loc_a).length/0.0254)
else:
p_format = "{:10.0f}"
inches = (((dim_loc_b - dim_loc_a).length%0.3048)/0.0254)
text_svg += p_format.format(feets)
text_svg += "ft"
p_format = "{:10."+str(precision)+"f}"
text_svg += p_format.format(inches)
text_svg += "in"
text_svg += f' {self.node.units}' text_svg += f' {self.node.units}'
text_svg += '</text>' text_svg += '</text>'
...@@ -201,6 +214,14 @@ class SvSvgDimensionNode(bpy.types.Node, SverchCustomTreeNode): ...@@ -201,6 +214,14 @@ class SvSvgDimensionNode(bpy.types.Node, SverchCustomTreeNode):
description='units', description='units',
default='', default='',
update=updateNode) update=updateNode)
units_real: EnumProperty(
name='Units_real',
description='Dimentions feets or meters',
items=enum_item_4(['Metric', 'Imperialistic']),
default='Metric',
update=updateNode)
text: StringProperty( text: StringProperty(
name='Text', name='Text',
description='Text', description='Text',
...@@ -231,6 +252,7 @@ class SvSvgDimensionNode(bpy.types.Node, SverchCustomTreeNode): ...@@ -231,6 +252,7 @@ class SvSvgDimensionNode(bpy.types.Node, SverchCustomTreeNode):
layout.prop(self, "line_extension", expand=False) layout.prop(self, "line_extension", expand=False)
layout.prop(self, "decimal_precision", expand=False) layout.prop(self, "decimal_precision", expand=False)
layout.prop(self, "units", expand=False) layout.prop(self, "units", expand=False)
layout.prop(self, "units_real", expand=True)
layout.prop(self, "font_family", expand=False) layout.prop(self, "font_family", expand=False)
if self.font_family == 'user': if self.font_family == 'user':
layout.prop(self, "user_font") layout.prop(self, "user_font")
...@@ -263,3 +285,5 @@ def register(): ...@@ -263,3 +285,5 @@ def register():
def unregister(): def unregister():
bpy.utils.unregister_class(SvSvgDimensionNode) bpy.utils.unregister_class(SvSvgDimensionNode)
if __name__ == '__main__': register()
\ No newline at end of file
...@@ -35,7 +35,7 @@ class SvEllipseNode(bpy.types.Node, SverchCustomTreeNode): ...@@ -35,7 +35,7 @@ class SvEllipseNode(bpy.types.Node, SverchCustomTreeNode):
bl_label = 'Ellipse' bl_label = 'Ellipse'
sv_icon = 'SV_ELLIPSE' sv_icon = 'SV_ELLIPSE'
replacement_nodes = [('SvEllipseNodeMK2', None, None)] replacement_nodes = [('SvEllipseNodeMK3', None, None)]
def update_mode(self, context): def update_mode(self, context):
''' Update the ellipse parameters of the new mode based on previous mode ones''' ''' Update the ellipse parameters of the new mode based on previous mode ones'''
......
...@@ -43,6 +43,8 @@ class SvEllipseNodeMK2(bpy.types.Node, SverchCustomTreeNode, SvAngleHelper): ...@@ -43,6 +43,8 @@ class SvEllipseNodeMK2(bpy.types.Node, SverchCustomTreeNode, SvAngleHelper):
bl_label = 'Ellipse' bl_label = 'Ellipse'
sv_icon = 'SV_ELLIPSE' sv_icon = 'SV_ELLIPSE'
replacement_nodes = [('SvEllipseNodeMK3', None, None)]
def update_mode(self, context): def update_mode(self, context):
''' Update the ellipse parameters of the new mode based on previous mode ones''' ''' Update the ellipse parameters of the new mode based on previous mode ones'''
...@@ -244,7 +246,7 @@ class SvEllipseNodeMK2(bpy.types.Node, SverchCustomTreeNode, SvAngleHelper): ...@@ -244,7 +246,7 @@ class SvEllipseNodeMK2(bpy.types.Node, SverchCustomTreeNode, SvAngleHelper):
theta = delta * n + phase theta = delta * n + phase
x = -cx + a * cos(theta) x = -cx + a * cos(theta)
y = -cy + b * sin(theta) y = -cy + b * sin(theta)
# apply inplane rotation # apply in-plane rotation
xx = x * coss - y * sins xx = x * coss - y * sins
yy = x * sins + y * coss yy = x * sins + y * coss
add_vert((xx, yy, 0)) add_vert((xx, yy, 0))
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
from __future__ import annotations from __future__ import annotations
from collections import Iterable from collections.abc import Iterable
from enum import Enum from enum import Enum
from functools import singledispatch from functools import singledispatch
from itertools import chain from itertools import chain
......
...@@ -19,7 +19,7 @@ It can bring unexpected errors ...@@ -19,7 +19,7 @@ It can bring unexpected errors
from __future__ import annotations from __future__ import annotations
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from collections import Collection from collections.abc import Collection
from functools import wraps from functools import wraps
from itertools import chain from itertools import chain
from typing import Tuple, List, Callable, Union, Type, Iterable, Dict from typing import Tuple, List, Callable, Union, Type, Iterable, Dict
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
</div> </div>
<div id="div2"> <div id="div2">
<span id="file_name">File: "/home/ololo/Documents/BLENDER/SVERCHOK/Blends2.90/svg/Пазлы_Матвей_01.blend.svg"</span> <span id="file_name">File: "/home/ololo/Documents/BLENDER/SVERCHOK/Blends2.90/svg/dimentions_inch.svg"</span>
<button id="PauseButton" onclick="pause_feed()">Pause</button> <button id="PauseButton" onclick="pause_feed()">Pause</button>
<button id="PlayButton"onclick="live_feed = start_feed()">Play</button> <button id="PlayButton"onclick="live_feed = start_feed()">Play</button>
<form id="refresh_slider"> <form id="refresh_slider">
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
<script> <script>
var a=0 var a=0
var paused= false var paused= false
var file_name = "/home/ololo/Documents/BLENDER/SVERCHOK/Blends2.90/svg/Пазлы_Матвей_01.blend.svg" var file_name = "/home/ololo/Documents/BLENDER/SVERCHOK/Blends2.90/svg/dimentions_inch.svg"
function reload_svg(){ function reload_svg(){
<!-- console.log(a) --> <!-- console.log(a) -->
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
from __future__ import annotations from __future__ import annotations
from collections import Mapping from collections.abc import Mapping
from typing import List, Iterable, TypeVar, TYPE_CHECKING, Dict, Any, Generic, Optional, Union from typing import List, Iterable, TypeVar, TYPE_CHECKING, Dict, Any, Generic, Optional, Union
import bpy import bpy
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать