From 836eab1fbb39127830dfbf73ea5156eec5e5d7dd Mon Sep 17 00:00:00 2001 From: alexloss Date: Wed, 24 Aug 2022 17:12:46 +0200 Subject: [PATCH 01/11] No slvs data when constraint is a contructor. --- model/base_constraint.py | 7 +++++++ solver.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/model/base_constraint.py b/model/base_constraint.py index 8f3c27fd..46050442 100644 --- a/model/base_constraint.py +++ b/model/base_constraint.py @@ -25,6 +25,7 @@ def _name_setter(self, new_name): name: StringProperty(name="Name", get=_name_getter, set=_name_setter) failed: BoolProperty(name="Failed") visible: BoolProperty(name="Visible", default=True, update=functions.update_cb) + is_reference: BoolProperty(name="Construction") signature = () props = () @@ -150,6 +151,7 @@ def draw_props(self, layout: UILayout): # General props layout.separator() layout.prop(self, "visible") + layout.prop(self, "is_reference") # Specific props layout.separator() @@ -173,3 +175,8 @@ def index(self): def placements(self): """Return the entities where the constraint should be displayed""" return [] + + def py_data(self, solvesys: Solver, **kwargs): + if self.is_reference: + return [] + return self.create_slvs_data(solvesys, **kwargs) diff --git a/solver.py b/solver.py index 40ae059d..662f0de3 100644 --- a/solver.py +++ b/solver.py @@ -122,7 +122,7 @@ def _get_msg_entities(): # Store a index-constraint mapping from collections.abc import Iterable - indices = c.create_slvs_data(self.solvesys, group=group) + indices = c.py_data(self.solvesys, group=group) self._store_constraint_indices( c, indices if isinstance(indices, Iterable) else (indices,) ) From 3fcb9e5067a307a7becd5a185d71c03e73dec298 Mon Sep 17 00:00:00 2001 From: amrsoll Date: Sat, 3 Sep 2022 11:53:17 +0200 Subject: [PATCH 02/11] Add new color to ref measurement. --- base/theme.py | 22 +++++++++++++++++ gizmos.py | 65 ++++++++++++++++++++++++++++++++++----------------- 2 files changed, 65 insertions(+), 22 deletions(-) diff --git a/base/theme.py b/base/theme.py index 54a9c904..1f5180bd 100644 --- a/base/theme.py +++ b/base/theme.py @@ -109,6 +109,27 @@ class ThemeSettingsConstraint(PropertyGroup): max=1.0, update=update, ) + + reference: FloatVectorProperty( + name="Reference Measurement", + subtype="COLOR", + default=(0.5, 0.5, 1.0, 0.7), + size=4, + min=0.0, + max=1.0, + update=update, + ) + + reference_highlight: FloatVectorProperty( + name="Reference Highlight", + subtype="COLOR", + default=(0.6, 0.6, 1.0, 0.95), + size=4, + min=0.0, + max=1.0, + update=update, + ) + text: FloatVectorProperty( name="Text", subtype="COLOR", @@ -118,6 +139,7 @@ class ThemeSettingsConstraint(PropertyGroup): max=1.0, update=update, ) + text_highlight: FloatVectorProperty( name="Text Highlight", subtype="COLOR", diff --git a/gizmos.py b/gizmos.py index 88522fce..54ef31d9 100644 --- a/gizmos.py +++ b/gizmos.py @@ -5,6 +5,7 @@ import math from bpy.types import Gizmo, GizmoGroup +from enum import Enum, auto from mathutils import Vector, Matrix from mathutils.geometry import intersect_point_line @@ -75,6 +76,33 @@ def context_mode_check(context, widget_group): GIZMO_OFFSET = Vector((10.0, 10.0)) GIZMO_GENERIC_SIZE = 5 +class Color(Enum): + Default = auto() + Failed = auto() + Reference = auto() + +def get_color(color_type: Color, highlit: bool): + c_theme = functions.get_prefs().theme_settings.constraint + theme_match = { + # (type, highlit): color + (Color.Default, False): c_theme.default, + (Color.Default, True): c_theme.highlight, + (Color.Failed, False): c_theme.failed, + (Color.Failed, True): c_theme.failed_highlight, + (Color.Reference, False): c_theme.reference, + (Color.Reference, True): c_theme.reference_highlight, + } + return theme_match[(color_type, highlit)] + +def get_constraint_color_type(constraint: class_defines.GenericConstraint): + if constraint.failed: + return Color.Failed + if constraint.is_reference: + return Color.Reference + else: + return Color.Default + + class ConstraintGizmo: def _get_constraint(self, context): @@ -82,26 +110,20 @@ def _get_constraint(self, context): self.type, self.index ) - def _set_colors(self, context, constraint): - """Overwrite default color when gizmo is highlighted""" - + def get_constraint_color(self, constraint: class_defines.GenericConstraint): theme = functions.get_prefs().theme_settings is_highlight = ( constraint == global_data.highlight_constraint or self.is_highlight ) - failed = constraint.failed + col = get_constraint_color_type(constraint) + return get_color(col, is_highlight) - if is_highlight: - col = ( - theme.constraint.failed_highlight - if failed - else theme.constraint.highlight - ) - else: - col = theme.constraint.failed if failed else theme.constraint.default + def _set_colors(self, context, constraint: class_defines.GenericConstraint): + """Overwrite default color when gizmo is highlighted""" - self.color = col[:3] - return col + color_setting = self.get_constraint_color(constraint) + self.color = color_setting[:3] + return color_setting class VIEW3D_GT_slvs_constraint(ConstraintGizmo, Gizmo): @@ -697,13 +719,12 @@ def constraints_mapping(context): return entities, constraints -def set_gizmo_colors(gz, failed): +def set_gizmo_colors(gz, constraint): theme = functions.get_prefs().theme_settings - color = theme.constraint.failed if failed else theme.constraint.default - color_highlight = ( - theme.constraint.failed_highlight if failed else theme.constraint.highlight - ) - + color_type = get_constraint_color_type(constraint) + color = get_color(color_type, highlit=False) + color_highlight = get_color(color_type, highlit=True) + gz.color = color[0:-1] gz.alpha = color[-1] gz.color_highlight = color_highlight[0:-1] @@ -725,7 +746,7 @@ def setup(self, context): gz = self.gizmos.new(self.gizmo_type) gz.index = context.scene.sketcher.constraints.get_index(c) - set_gizmo_colors(gz, c.failed) + set_gizmo_colors(gz, c) gz.use_draw_modal = True gz.target_set_prop("offset", c, "draw_offset") @@ -831,7 +852,7 @@ def setup(self, context): gz.offset = offset gz.scale_basis = scale - set_gizmo_colors(gz, c.failed) + set_gizmo_colors(gz, c) gz.use_draw_modal = True From a8b506755173b5cfaad54cf93cd10b880f2c25b8 Mon Sep 17 00:00:00 2001 From: amrsoll Date: Sun, 4 Sep 2022 14:04:22 +0200 Subject: [PATCH 03/11] Make diameter constraint update --- gizmos.py | 8 ++++---- model/base_constraint.py | 3 ++- model/diameter.py | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/gizmos.py b/gizmos.py index 54ef31d9..af32fa9a 100644 --- a/gizmos.py +++ b/gizmos.py @@ -10,7 +10,7 @@ from mathutils.geometry import intersect_point_line from . import functions, global_data, icon_manager -from .model.types import SlvsDistance, SlvsAngle, SlvsDiameter +from .model.types import SlvsDistance, SlvsAngle, SlvsDiameter, GenericConstraint from .declarations import GizmoGroups, Gizmos, Operators from .draw_handler import ensure_selection_texture from .utilities.constants import HALF_TURN, QUARTER_TURN @@ -94,7 +94,7 @@ def get_color(color_type: Color, highlit: bool): } return theme_match[(color_type, highlit)] -def get_constraint_color_type(constraint: class_defines.GenericConstraint): +def get_constraint_color_type(constraint: GenericConstraint): if constraint.failed: return Color.Failed if constraint.is_reference: @@ -110,7 +110,7 @@ def _get_constraint(self, context): self.type, self.index ) - def get_constraint_color(self, constraint: class_defines.GenericConstraint): + def get_constraint_color(self, constraint: GenericConstraint): theme = functions.get_prefs().theme_settings is_highlight = ( constraint == global_data.highlight_constraint or self.is_highlight @@ -118,7 +118,7 @@ def get_constraint_color(self, constraint: class_defines.GenericConstraint): col = get_constraint_color_type(constraint) return get_color(col, is_highlight) - def _set_colors(self, context, constraint: class_defines.GenericConstraint): + def _set_colors(self, context, constraint: GenericConstraint): """Overwrite default color when gizmo is highlighted""" color_setting = self.get_constraint_color(constraint) diff --git a/model/base_constraint.py b/model/base_constraint.py index 46050442..7d6703c3 100644 --- a/model/base_constraint.py +++ b/model/base_constraint.py @@ -5,7 +5,7 @@ from bpy.types import UILayout from .. import functions -from ..solver import solve_system +from ..solver import solve_system, Solver from ..global_data import WpReq from ..utilities import preferences from ..declarations import Operators @@ -28,6 +28,7 @@ def _name_setter(self, new_name): is_reference: BoolProperty(name="Construction") signature = () props = () + dirty: BoolProperty(name="Needs updating", default=False) def needs_wp(args): return WpReq.OPTIONAL diff --git a/model/diameter.py b/model/diameter.py index 477beccb..52e07fed 100644 --- a/model/diameter.py +++ b/model/diameter.py @@ -42,11 +42,26 @@ def use_radius_setter(self, setting): def label(self): return "Radius" if self.setting else "Diameter" + def __set_value(self, val: float): + self["value"] = val + self.dirty= True + + def __get_value(self): + if self.dirty: + return self["value"] + elif self.setting: + return self.entity1.radius + else: + return self.entity1.radius *2 + value: FloatProperty( name="Size", subtype="DISTANCE", unit="LENGTH", + get=__get_value, + set=__set_value, update=GenericConstraint.update_system_cb, + # is_readonly=is_reference, ) setting: BoolProperty( name="Use Radius", get=use_radius_getter, set=use_radius_setter @@ -108,6 +123,10 @@ def update_draw_offset(self, pos, ui_scale): def draw_props(self, layout): sub = super().draw_props(layout) + # self.bl_rna.properties.get('value').is_readonly = True + # Traceback (most recent call last): + # File "", line 1, in + # AttributeError: bpy_struct: attribute "is_readonly" from "FloatProperty" is read-only sub.prop(self, "value") From 9873c84a8fe696fff71e9737a3aee7f2e9fc1328 Mon Sep 17 00:00:00 2001 From: amrsoll Date: Thu, 8 Sep 2022 11:48:59 +0200 Subject: [PATCH 04/11] Prevent users from modifying reference values. --- gizmos.py | 5 +++-- model/angle.py | 6 ------ model/base_constraint.py | 30 +++++++++++++++++++++++++++--- model/diameter.py | 19 +++---------------- model/distance.py | 2 -- model/types.py | 2 +- ui.py | 2 +- 7 files changed, 35 insertions(+), 31 deletions(-) diff --git a/gizmos.py b/gizmos.py index af32fa9a..ff76d7b7 100644 --- a/gizmos.py +++ b/gizmos.py @@ -10,7 +10,7 @@ from mathutils.geometry import intersect_point_line from . import functions, global_data, icon_manager -from .model.types import SlvsDistance, SlvsAngle, SlvsDiameter, GenericConstraint +from .model.types import SlvsDistance, SlvsAngle, SlvsDiameter, GenericConstraint, DimensionalConstraint from .declarations import GizmoGroups, Gizmos, Operators from .draw_handler import ensure_selection_texture from .utilities.constants import HALF_TURN, QUARTER_TURN @@ -97,7 +97,8 @@ def get_color(color_type: Color, highlit: bool): def get_constraint_color_type(constraint: GenericConstraint): if constraint.failed: return Color.Failed - if constraint.is_reference: + elif isinstance(constraint, DimensionalConstraint) and \ + constraint.is_reference: return Color.Reference else: return Color.Default diff --git a/model/angle.py b/model/angle.py index 5998bb8f..7a7352f2 100644 --- a/model/angle.py +++ b/model/angle.py @@ -144,12 +144,6 @@ def update_draw_offset(self, pos, ui_scale): self.draw_offset = math.copysign(pos.length / ui_scale, pos.x) self.draw_outset = math.atan(pos.y / pos.x) - def draw_props(self, layout): - sub = super().draw_props(layout) - sub.prop(self, "value") - sub.prop(self, "setting") - return sub - def value_placement(self, context): """location to display the constraint value""" region = context.region diff --git a/model/base_constraint.py b/model/base_constraint.py index 7d6703c3..f6609f6f 100644 --- a/model/base_constraint.py +++ b/model/base_constraint.py @@ -2,6 +2,7 @@ from typing import List from bpy.props import StringProperty, BoolProperty +import bpy.types from bpy.types import UILayout from .. import functions @@ -25,7 +26,6 @@ def _name_setter(self, new_name): name: StringProperty(name="Name", get=_name_getter, set=_name_setter) failed: BoolProperty(name="Failed") visible: BoolProperty(name="Visible", default=True, update=functions.update_cb) - is_reference: BoolProperty(name="Construction") signature = () props = () dirty: BoolProperty(name="Needs updating", default=False) @@ -152,7 +152,6 @@ def draw_props(self, layout: UILayout): # General props layout.separator() layout.prop(self, "visible") - layout.prop(self, "is_reference") # Specific props layout.separator() @@ -176,8 +175,33 @@ def index(self): def placements(self): """Return the entities where the constraint should be displayed""" return [] - + + def create_slvs_data(self, solvesys: Solver, **kwargs): + raise NotImplementedError() + + def py_data(self, solvesys: Solver, **kwargs): + return self.create_slvs_data(solvesys, **kwargs) + +class DimensionalConstraint(GenericConstraint): + + def make_readonly(self, context: bpy.types.Context): + print("here we are") + return None + + is_reference: BoolProperty( + name="Only measure", + default=False, + ) + def py_data(self, solvesys: Solver, **kwargs): if self.is_reference: return [] return self.create_slvs_data(solvesys, **kwargs) + + def draw_props(self, layout: UILayout): + sub = GenericConstraint.draw_props(self, layout) + sub.prop(self, "is_reference") + return sub.column() + + def is_active(self, *args, **kwargs): + return GenericConstraint.is_active(self, *args, **kwargs) \ No newline at end of file diff --git a/model/diameter.py b/model/diameter.py index 52e07fed..e311c671 100644 --- a/model/diameter.py +++ b/model/diameter.py @@ -10,7 +10,7 @@ from ..solver import Solver from ..global_data import WpReq from ..functions import location_3d_to_region_2d -from .base_constraint import GenericConstraint +from .base_constraint import DimensionalConstraint from .utilities import slvs_entity_pointer from .categories import CURVE @@ -18,7 +18,7 @@ logger = logging.getLogger(__name__) -class SlvsDiameter(GenericConstraint, PropertyGroup): +class SlvsDiameter(DimensionalConstraint, PropertyGroup): """Sets the diameter of an arc or a circle.""" def use_radius_getter(self): @@ -60,8 +60,7 @@ def __get_value(self): unit="LENGTH", get=__get_value, set=__set_value, - update=GenericConstraint.update_system_cb, - # is_readonly=is_reference, + update=DimensionalConstraint.update_system_cb, ) setting: BoolProperty( name="Use Radius", get=use_radius_getter, set=use_radius_setter @@ -121,18 +120,6 @@ def update_draw_offset(self, pos, ui_scale): self.draw_offset = pos.length self.leader_angle = math.atan2(pos.y, pos.x) - def draw_props(self, layout): - sub = super().draw_props(layout) - # self.bl_rna.properties.get('value').is_readonly = True - # Traceback (most recent call last): - # File "", line 1, in - # AttributeError: bpy_struct: attribute "is_readonly" from "FloatProperty" is read-only - - sub.prop(self, "value") - - row = sub.row() - row.prop(self, "setting") - return sub def value_placement(self, context): """location to display the constraint value""" diff --git a/model/distance.py b/model/distance.py index a707a163..a1d6a5a0 100644 --- a/model/distance.py +++ b/model/distance.py @@ -329,8 +329,6 @@ def update_draw_offset(self, pos, ui_scale): def draw_props(self, layout): sub = super().draw_props(layout) - sub.prop(self, "value") - row = sub.row() row.enabled = self.use_flipping() row.prop(self, "flip") diff --git a/model/types.py b/model/types.py index b8c320ea..35487f24 100644 --- a/model/types.py +++ b/model/types.py @@ -13,7 +13,7 @@ from .circle import SlvsCircle from .group_entities import SlvsEntities -from .base_constraint import GenericConstraint +from .base_constraint import GenericConstraint, DimensionalConstraint from .distance import SlvsDistance from .angle import SlvsAngle from .diameter import SlvsDiameter diff --git a/ui.py b/ui.py index 93a59fdc..fab59a21 100644 --- a/ui.py +++ b/ui.py @@ -335,7 +335,7 @@ def draw(self, context: Context): sketch = context.scene.sketcher.active_sketch for c in context.scene.sketcher.constraints.dimensional: - if not c.is_active(sketch): + if not c.is_active(sketch) or c.is_reference: continue draw_constraint_listitem(context, col, c) From ee09f49ec6e2653109ae58a29df2ede2997651e0 Mon Sep 17 00:00:00 2001 From: amrsoll Date: Thu, 8 Sep 2022 13:58:32 +0200 Subject: [PATCH 05/11] All DimensionalConstraints can become is_reference - Also kinda changes role of init_props -> assign_init_props - Store values as the same logic value, i.e. always stores the radius or the direct angle etc... --- model/angle.py | 52 +++++++++++++++++++++------------------- model/base_constraint.py | 41 ++++++++++++++++++++++++++----- model/diameter.py | 26 ++++---------------- model/distance.py | 22 +++++++---------- 4 files changed, 75 insertions(+), 66 deletions(-) diff --git a/model/angle.py b/model/angle.py index 7a7352f2..82dc930d 100644 --- a/model/angle.py +++ b/model/angle.py @@ -1,7 +1,7 @@ import logging import math -from bpy.types import PropertyGroup +from bpy.types import PropertyGroup, Context from bpy.props import BoolProperty, FloatProperty from bpy.utils import register_classes_factory from mathutils import Vector, Matrix @@ -12,7 +12,7 @@ from ..solver import Solver from ..global_data import WpReq from ..functions import location_3d_to_region_2d -from .base_constraint import GenericConstraint +from .base_constraint import DimensionalConstraint from .line_2d import SlvsLine2D from .utilities import slvs_entity_pointer @@ -20,30 +20,40 @@ logger = logging.getLogger(__name__) -class SlvsAngle(GenericConstraint, PropertyGroup): +class SlvsAngle(DimensionalConstraint, PropertyGroup): """Sets the angle between two lines, applies in 2D only. The constraint's setting can be used to to constrain the supplementary angle. """ - def invert_angle_getter(self): - return self.get("setting", self.bl_rna.properties["setting"].default) + def _set_value(self, value): + DimensionalConstraint._set_value(self, HALF_TURN - value if self.setting else value) - def invert_angle_setter(self, setting): - self["value"] = HALF_TURN - self.value - self["setting"] = setting + def assign_init_props(self, context: Context=None): + # Updating self.setting will create recursion loop + self.value, _ = self.init_props() + line1, line2 = self.entity1, self.entity2 + origin = functions.get_line_intersection( + *functions.line_abc_form(line1.p1.co, line1.p2.co), + *functions.line_abc_form(line2.p1.co, line2.p2.co), + ) + dist = max( + (line1.midpoint() - origin).length, (line2.midpoint() - origin).length, 0.5 + ) + self.draw_offset = dist if not setting else -dist label = "Angle" value: FloatProperty( name=label, subtype="ANGLE", unit="ROTATION", - update=GenericConstraint.update_system_cb, + update=DimensionalConstraint.update_system_cb, + get=DimensionalConstraint._get_value, + set=_set_value, ) setting: BoolProperty( name="Measure supplementary angle", - get=invert_angle_getter, - set=invert_angle_setter, + update=assign_init_props, ) draw_offset: FloatProperty(name="Draw Offset", default=1) draw_outset: FloatProperty(name="Draw Outset", default=0) @@ -54,6 +64,9 @@ def invert_angle_setter(self, setting): def needs_wp(self): return WpReq.NOT_FREE + def to_displayed_value(self, value): + return HALF_TURN - value if self.setting else value + def create_slvs_data(self, solvesys, group=Solver.group_fixed): kwargs = { "group": group, @@ -120,22 +133,11 @@ def init_props(self, **kwargs): and distance to dimension text (draw_offset) """ - line1, line2 = self.entity1, self.entity2 - vec1, vec2 = line1.direction_vec(), line2.direction_vec() + vec1, vec2 = self.entity1.direction_vec(), self.entity2.direction_vec() angle = self._get_angle(vec1, vec2) - setting = angle > 90 - if not setting: - angle = 180 - angle - origin = functions.get_line_intersection( - *functions.line_abc_form(line1.p1.co, line1.p2.co), - *functions.line_abc_form(line2.p1.co, line2.p2.co), - ) - dist = max( - (line1.midpoint() - origin).length, (line2.midpoint() - origin).length, 0.5 - ) - self.draw_offset = dist if not setting else -dist - return math.radians(angle), setting + return math.radians(angle), self.setting + def text_inside(self): return abs(self.draw_outset) < (self.value / 2) diff --git a/model/base_constraint.py b/model/base_constraint.py index f6609f6f..0e602a67 100644 --- a/model/base_constraint.py +++ b/model/base_constraint.py @@ -3,7 +3,7 @@ from bpy.props import StringProperty, BoolProperty import bpy.types -from bpy.types import UILayout +from bpy.types import UILayout, Property, Context from .. import functions from ..solver import solve_system, Solver @@ -28,7 +28,6 @@ def _name_setter(self, new_name): visible: BoolProperty(name="Visible", default=True, update=functions.update_cb) signature = () props = () - dirty: BoolProperty(name="Needs updating", default=False) def needs_wp(args): return WpReq.OPTIONAL @@ -184,15 +183,36 @@ def py_data(self, solvesys: Solver, **kwargs): class DimensionalConstraint(GenericConstraint): - def make_readonly(self, context: bpy.types.Context): - print("here we are") - return None + value: Property + setting: BoolProperty + + def _set_value(self, val: float): + self["value"] = val + + def _get_value(self): + if self.is_reference: + val, _ = self.init_props() + return self.to_displayed_value(val) + if not self.get("value"): + self.assign_init_props() + return self["value"] + + def assign_init_props(self, context: Context=None): + # self.value, self.setting = self.init_props() + self.value, _ = self.init_props() is_reference: BoolProperty( name="Only measure", default=False, + update=assign_init_props, ) + def init_props(self): + raise NotImplementedError() + + def to_displayed_value(self, value): + return value + def py_data(self, solvesys: Solver, **kwargs): if self.is_reference: return [] @@ -201,7 +221,16 @@ def py_data(self, solvesys: Solver, **kwargs): def draw_props(self, layout: UILayout): sub = GenericConstraint.draw_props(self, layout) sub.prop(self, "is_reference") - return sub.column() + if hasattr(self, "value"): + col = sub.column() + # Could not find a way to have the property "readonly", + # so we disable user input instead + col.prop(self, "value") + col.enabled=not self.is_reference + if hasattr(self, "setting"): + row = sub.row() + row.prop(self, "setting") + return sub def is_active(self, *args, **kwargs): return GenericConstraint.is_active(self, *args, **kwargs) \ No newline at end of file diff --git a/model/diameter.py b/model/diameter.py index e311c671..4c70a1e8 100644 --- a/model/diameter.py +++ b/model/diameter.py @@ -42,24 +42,12 @@ def use_radius_setter(self, setting): def label(self): return "Radius" if self.setting else "Diameter" - def __set_value(self, val: float): - self["value"] = val - self.dirty= True - - def __get_value(self): - if self.dirty: - return self["value"] - elif self.setting: - return self.entity1.radius - else: - return self.entity1.radius *2 - value: FloatProperty( name="Size", subtype="DISTANCE", unit="LENGTH", - get=__get_value, - set=__set_value, + get=DimensionalConstraint._get_value, + set=DimensionalConstraint._set_value, update=DimensionalConstraint.update_system_cb, ) setting: BoolProperty( @@ -92,17 +80,11 @@ def create_slvs_data(self, solvesys, group=Solver.group_fixed): return solvesys.addDiameter(self.diameter, self.entity1.py_data, group=group) def init_props(self, **kwargs): - # Get operators setting value - setting = kwargs.get("setting") value = self.entity1.radius - if setting is None and self.entity1.bl_rna.name == "SlvsArc": - self["setting"] = True - - if not setting: + if not self.setting: value = value * 2 - - return value, None + return value, self.setting def matrix_basis(self): if self.sketch_i == -1: diff --git a/model/distance.py b/model/distance.py index a1d6a5a0..83c5a624 100644 --- a/model/distance.py +++ b/model/distance.py @@ -12,7 +12,7 @@ from ..utilities import preferences from ..global_data import WpReq from ..functions import location_3d_to_region_2d -from .base_constraint import GenericConstraint +from .base_constraint import DimensionalConstraint from .utilities import slvs_entity_pointer from .categories import POINT, LINE, POINT2D, CURVE @@ -43,29 +43,26 @@ def get_side_of_line(line_start, line_end, point): ] -class SlvsDistance(GenericConstraint, PropertyGroup): +class SlvsDistance(DimensionalConstraint, PropertyGroup): """Sets the distance between a point and some other entity (point/line/Workplane).""" - def get_distance_value(self): - return self.get("value", self.rna_type.properties["value"].default) - - def set_distance_value(self, value): - self["value"] = abs(value) + def _set_value(self, value): + DimensionalConstraint._set_value(self, abs(value)) label = "Distance" value: FloatProperty( name=label, subtype="DISTANCE", unit="LENGTH", - update=GenericConstraint.update_system_cb, - get=get_distance_value, - set=set_distance_value, + update=DimensionalConstraint.update_system_cb, + get=DimensionalConstraint._get_value, + set=_set_value, ) - flip: BoolProperty(name="Flip", update=GenericConstraint.update_system_cb) + flip: BoolProperty(name="Flip", update=DimensionalConstraint.update_system_cb) align: EnumProperty( name="Align", items=align_items, - update=GenericConstraint.update_system_cb, + update=DimensionalConstraint.update_system_cb, ) draw_offset: FloatProperty(name="Draw Offset", default=0.3) draw_outset: FloatProperty(name="Draw Outset", default=0.0) @@ -316,7 +313,6 @@ def init_props(self, **kwargs): value = abs(value) self.flip = not self.flip - self.value = value return value, None def text_inside(self, ui_scale): From 45325da174345e4dc01ab46cde953c86fe32df66 Mon Sep 17 00:00:00 2001 From: amrsoll Date: Thu, 8 Sep 2022 13:58:44 +0200 Subject: [PATCH 06/11] Small refactor for gizmos --- gizmos.py | 27 +++++++++++---------------- model/angle.py | 2 +- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/gizmos.py b/gizmos.py index ff76d7b7..744c20de 100644 --- a/gizmos.py +++ b/gizmos.py @@ -75,11 +75,13 @@ def context_mode_check(context, widget_group): GIZMO_OFFSET = Vector((10.0, 10.0)) GIZMO_GENERIC_SIZE = 5 +FONT_ID = 0 class Color(Enum): Default = auto() Failed = auto() Reference = auto() + Text = auto() def get_color(color_type: Color, highlit: bool): c_theme = functions.get_prefs().theme_settings.constraint @@ -91,6 +93,8 @@ def get_color(color_type: Color, highlit: bool): (Color.Failed, True): c_theme.failed_highlight, (Color.Reference, False): c_theme.reference, (Color.Reference, True): c_theme.reference_highlight, + (Color.Text, False): c_theme.text, + (Color.Text, True): c_theme.text_highlight, } return theme_match[(color_type, highlit)] @@ -104,7 +108,6 @@ def get_constraint_color_type(constraint: GenericConstraint): return Color.Default - class ConstraintGizmo: def _get_constraint(self, context): return context.scene.sketcher.constraints.get_from_type_index( @@ -112,7 +115,6 @@ def _get_constraint(self, context): ) def get_constraint_color(self, constraint: GenericConstraint): - theme = functions.get_prefs().theme_settings is_highlight = ( constraint == global_data.highlight_constraint or self.is_highlight ) @@ -227,21 +229,14 @@ def draw(self, context): if not constr.visible or not hasattr(constr, "value_placement"): return - prefs = functions.get_prefs() - theme = prefs.theme_settings - color = ( - theme.constraint.text_highlight - if self.is_highlight - else theme.constraint.text - ) + color = get_color(Color.Text, self.is_highlight) text = _get_formatted_value(context, constr) - font_id = 0 dpi = context.preferences.system.dpi - text_size = prefs.text_size + text_size = functions.get_prefs().text_size - blf.color(font_id, *color) - blf.size(font_id, text_size, dpi) - self.width, self.height = blf.dimensions(font_id, text) + blf.color(FONT_ID, *color) + blf.size(FONT_ID, text_size, dpi) + self.width, self.height = blf.dimensions(FONT_ID, text) margin = text_size / 4 @@ -252,8 +247,8 @@ def draw(self, context): pos.to_3d() ) # Update Matrix for selection - blf.position(font_id, pos[0] - self.width / 2, pos[1] + margin, 0) - blf.draw(font_id, text) + blf.position(FONT_ID, pos[0] - self.width / 2, pos[1] + margin, 0) + blf.draw(FONT_ID, text) def setup(self): self.width = 0 diff --git a/model/angle.py b/model/angle.py index 82dc930d..b693311e 100644 --- a/model/angle.py +++ b/model/angle.py @@ -40,7 +40,7 @@ def assign_init_props(self, context: Context=None): dist = max( (line1.midpoint() - origin).length, (line2.midpoint() - origin).length, 0.5 ) - self.draw_offset = dist if not setting else -dist + self.draw_offset = dist if not self.setting else -dist label = "Angle" value: FloatProperty( From bb294b12c3aa7690433d4668e79ea144a1dd7b73 Mon Sep 17 00:00:00 2001 From: amrsoll Date: Sun, 11 Sep 2022 10:16:02 +0200 Subject: [PATCH 07/11] Restore reference constraints in the menu. --- ui.py | 67 +++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/ui.py b/ui.py index fab59a21..2da0a2b1 100644 --- a/ui.py +++ b/ui.py @@ -1,14 +1,23 @@ import bpy -from bpy.types import Panel, Menu, UIList, Context, UILayout +from bpy.types import Panel, Menu, UIList, Context, UILayout, PropertyGroup from . import functions from .declarations import Menus, Operators, Panels, ConstraintOperators from .stateful_operator.constants import Operators as StatefulOperators - +from .model.types import GenericConstraint, DimensionalConstraint class VIEW3D_UL_sketches(UIList): + """Creates UI list of available Sketches""" def draw_item( - self, context, layout, data, item, icon, active_data, active_propname, index=0 + self, + context: Context, + layout: UILayout, + data: PropertyGroup, + item: PropertyGroup, + icon: int, + active_data: PropertyGroup, + active_propname: str, + index: int=0 ): if self.layout_type in {"DEFAULT", "COMPACT"}: if item: @@ -70,6 +79,7 @@ class VIEW3D_PT_sketcher_base(Panel): class VIEW3D_PT_sketcher(VIEW3D_PT_sketcher_base): + """Menu for selecting the sketch you want to enter into""" bl_label = "Sketcher" bl_idname = Panels.Sketcher @@ -82,6 +92,7 @@ def draw(self, context: Context): layout.use_property_decorate = False if sketch: + # Sketch is selected, show info about the sketch itself row = layout.row() row.alignment = "CENTER" row.scale_y = 1.2 @@ -123,6 +134,7 @@ def draw(self, context: Context): ).index = sketch.slvs_index else: + # No active Sketch , show list of available sketches layout.template_list( "VIEW3D_UL_sketches", "", @@ -134,6 +146,7 @@ def draw(self, context: Context): class VIEW3D_PT_sketcher_debug(VIEW3D_PT_sketcher_base): + """Debug Menu""" bl_label = "Debug Settings" bl_idname = Panels.SketcherDebugPanel @@ -160,6 +173,7 @@ def poll(cls, context: Context): class VIEW3D_PT_sketcher_add_constraints(VIEW3D_PT_sketcher_base): + """Add Constraint Menu: List of buttons with the constraint you want to create.""" bl_label = "Add Constraints" bl_idname = Panels.SketcherAddContraint bl_options = {"DEFAULT_CLOSED"} @@ -173,6 +187,10 @@ def draw(self, context: Context): class VIEW3D_PT_sketcher_entities(VIEW3D_PT_sketcher_base): + """ + Entities Menu: List of entities in the sketch. + Interactive + """ bl_label = "Entities" bl_idname = Panels.SketcherEntities bl_options = {"DEFAULT_CLOSED"} @@ -255,15 +273,21 @@ def draw(self, context: Context): col.separator() -def draw_constraint_listitem(context, layout, constraint): +def draw_constraint_listitem( + context: Context, + layout: UILayout, + constraint: GenericConstraint +): + """Creates a single row inside the ``layout`` describing the ``constraint``.""" index = context.scene.sketcher.constraints.get_index(constraint) row = layout.row() + left_sub = row.row(align=True) + # Left part - sub = row.row(align=True) - sub.alignment = "LEFT" + left_sub.alignment = "LEFT" - sub.prop( + left_sub.prop( constraint, "visible", icon_only=True, @@ -272,28 +296,31 @@ def draw_constraint_listitem(context, layout, constraint): ) # Failed hint - sub.label( + left_sub.label( text="", icon=("ERROR" if constraint.failed else "CHECKMARK"), ) + # Label + left_sub.prop(constraint, "name", text="") # Middle Part - sub = row.row() - sub.alignment = "LEFT" + center_sub = row.row() + center_sub.alignment = "LEFT" - # Label - sub.prop(constraint, "name", text="") # Dimensional Constraint Values for constraint_prop in constraint.props: - sub.prop(constraint, constraint_prop, text="") + center_sub.prop(constraint, constraint_prop, text="") + + # Disable interaction with element if it is "readonly" + center_sub.enabled = isinstance(constraint, DimensionalConstraint) and constraint.is_reference # Right part - sub = row.row() - sub.alignment = "RIGHT" + right_sub = row.row() + right_sub.alignment = "RIGHT" # Context menu, shows constraint name - props = sub.operator( + props = right_sub.operator( Operators.ContextMenu, text="", icon="OUTLINER_DATA_GP_LAYER", emboss=False ) props.type = constraint.type @@ -303,7 +330,7 @@ def draw_constraint_listitem(context, layout, constraint): props.highlight_members = True # Delete operator - props = sub.operator( + props = right_sub.operator( Operators.DeleteConstraint, text="", icon="X", @@ -316,6 +343,10 @@ def draw_constraint_listitem(context, layout, constraint): class VIEW3D_PT_sketcher_constraints(VIEW3D_PT_sketcher_base): + """ + Constraints Menu: List of entities in the sketch. + Interactive + """ bl_label = "Constraints" bl_idname = Panels.SketcherContraints bl_options = {"DEFAULT_CLOSED"} @@ -335,7 +366,7 @@ def draw(self, context: Context): sketch = context.scene.sketcher.active_sketch for c in context.scene.sketcher.constraints.dimensional: - if not c.is_active(sketch) or c.is_reference: + if not c.is_active(sketch): continue draw_constraint_listitem(context, col, c) From 1750912525c80c7b53851fe427090f519e97df94 Mon Sep 17 00:00:00 2001 From: amrsoll Date: Sun, 11 Sep 2022 14:42:28 +0200 Subject: [PATCH 08/11] Fix color assignment bug for gizmos. --- model/base_constraint.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/model/base_constraint.py b/model/base_constraint.py index 0e602a67..3a839822 100644 --- a/model/base_constraint.py +++ b/model/base_constraint.py @@ -201,10 +201,15 @@ def assign_init_props(self, context: Context=None): # self.value, self.setting = self.init_props() self.value, _ = self.init_props() + def refresh_constraint(self, context: Context=None): + self.assign_init_props() + # Refresh the gizmos as we are changing the colors. + functions.refresh(context) + is_reference: BoolProperty( name="Only measure", default=False, - update=assign_init_props, + update=refresh_constraint, ) def init_props(self): From 7a840311d698b26479648d8513dc2a9982eebd03 Mon Sep 17 00:00:00 2001 From: amrsoll Date: Sun, 11 Sep 2022 15:34:43 +0200 Subject: [PATCH 09/11] Linting --- gizmos.py | 16 ++++++++++++---- model/angle.py | 7 ++++--- model/base_constraint.py | 11 ++++++----- model/diameter.py | 1 - ui.py | 32 ++++++++++++++++++++++---------- 5 files changed, 44 insertions(+), 23 deletions(-) diff --git a/gizmos.py b/gizmos.py index 744c20de..5950e232 100644 --- a/gizmos.py +++ b/gizmos.py @@ -10,7 +10,13 @@ from mathutils.geometry import intersect_point_line from . import functions, global_data, icon_manager -from .model.types import SlvsDistance, SlvsAngle, SlvsDiameter, GenericConstraint, DimensionalConstraint +from .model.types import ( + SlvsDistance, + SlvsAngle, + SlvsDiameter, + GenericConstraint, + DimensionalConstraint, +) from .declarations import GizmoGroups, Gizmos, Operators from .draw_handler import ensure_selection_texture from .utilities.constants import HALF_TURN, QUARTER_TURN @@ -77,12 +83,14 @@ def context_mode_check(context, widget_group): GIZMO_GENERIC_SIZE = 5 FONT_ID = 0 + class Color(Enum): Default = auto() Failed = auto() Reference = auto() Text = auto() + def get_color(color_type: Color, highlit: bool): c_theme = functions.get_prefs().theme_settings.constraint theme_match = { @@ -98,11 +106,11 @@ def get_color(color_type: Color, highlit: bool): } return theme_match[(color_type, highlit)] + def get_constraint_color_type(constraint: GenericConstraint): if constraint.failed: return Color.Failed - elif isinstance(constraint, DimensionalConstraint) and \ - constraint.is_reference: + elif isinstance(constraint, DimensionalConstraint) and constraint.is_reference: return Color.Reference else: return Color.Default @@ -720,7 +728,7 @@ def set_gizmo_colors(gz, constraint): color_type = get_constraint_color_type(constraint) color = get_color(color_type, highlit=False) color_highlight = get_color(color_type, highlit=True) - + gz.color = color[0:-1] gz.alpha = color[-1] gz.color_highlight = color_highlight[0:-1] diff --git a/model/angle.py b/model/angle.py index b693311e..e6d026ee 100644 --- a/model/angle.py +++ b/model/angle.py @@ -27,9 +27,11 @@ class SlvsAngle(DimensionalConstraint, PropertyGroup): """ def _set_value(self, value): - DimensionalConstraint._set_value(self, HALF_TURN - value if self.setting else value) + DimensionalConstraint._set_value( + self, HALF_TURN - value if self.setting else value + ) - def assign_init_props(self, context: Context=None): + def assign_init_props(self, context: Context = None): # Updating self.setting will create recursion loop self.value, _ = self.init_props() line1, line2 = self.entity1, self.entity2 @@ -138,7 +140,6 @@ def init_props(self, **kwargs): return math.radians(angle), self.setting - def text_inside(self): return abs(self.draw_outset) < (self.value / 2) diff --git a/model/base_constraint.py b/model/base_constraint.py index 3a839822..91b786c6 100644 --- a/model/base_constraint.py +++ b/model/base_constraint.py @@ -181,6 +181,7 @@ def create_slvs_data(self, solvesys: Solver, **kwargs): def py_data(self, solvesys: Solver, **kwargs): return self.create_slvs_data(solvesys, **kwargs) + class DimensionalConstraint(GenericConstraint): value: Property @@ -197,11 +198,11 @@ def _get_value(self): self.assign_init_props() return self["value"] - def assign_init_props(self, context: Context=None): + def assign_init_props(self, context: Context = None): # self.value, self.setting = self.init_props() self.value, _ = self.init_props() - def refresh_constraint(self, context: Context=None): + def refresh_constraint(self, context: Context = None): self.assign_init_props() # Refresh the gizmos as we are changing the colors. functions.refresh(context) @@ -231,11 +232,11 @@ def draw_props(self, layout: UILayout): # Could not find a way to have the property "readonly", # so we disable user input instead col.prop(self, "value") - col.enabled=not self.is_reference + col.enabled = not self.is_reference if hasattr(self, "setting"): row = sub.row() row.prop(self, "setting") return sub - + def is_active(self, *args, **kwargs): - return GenericConstraint.is_active(self, *args, **kwargs) \ No newline at end of file + return GenericConstraint.is_active(self, *args, **kwargs) diff --git a/model/diameter.py b/model/diameter.py index 4c70a1e8..61104c18 100644 --- a/model/diameter.py +++ b/model/diameter.py @@ -102,7 +102,6 @@ def update_draw_offset(self, pos, ui_scale): self.draw_offset = pos.length self.leader_angle = math.atan2(pos.y, pos.x) - def value_placement(self, context): """location to display the constraint value""" region = context.region diff --git a/ui.py b/ui.py index 2da0a2b1..a002dd26 100644 --- a/ui.py +++ b/ui.py @@ -6,18 +6,20 @@ from .stateful_operator.constants import Operators as StatefulOperators from .model.types import GenericConstraint, DimensionalConstraint + class VIEW3D_UL_sketches(UIList): """Creates UI list of available Sketches""" + def draw_item( - self, - context: Context, + self, + context: Context, layout: UILayout, data: PropertyGroup, item: PropertyGroup, icon: int, active_data: PropertyGroup, active_propname: str, - index: int=0 + index: int = 0, ): if self.layout_type in {"DEFAULT", "COMPACT"}: if item: @@ -80,6 +82,7 @@ class VIEW3D_PT_sketcher_base(Panel): class VIEW3D_PT_sketcher(VIEW3D_PT_sketcher_base): """Menu for selecting the sketch you want to enter into""" + bl_label = "Sketcher" bl_idname = Panels.Sketcher @@ -147,6 +150,7 @@ def draw(self, context: Context): class VIEW3D_PT_sketcher_debug(VIEW3D_PT_sketcher_base): """Debug Menu""" + bl_label = "Debug Settings" bl_idname = Panels.SketcherDebugPanel @@ -173,7 +177,11 @@ def poll(cls, context: Context): class VIEW3D_PT_sketcher_add_constraints(VIEW3D_PT_sketcher_base): - """Add Constraint Menu: List of buttons with the constraint you want to create.""" + """ + Add Constraint Menu: List of buttons with the constraint you want + to create. + """ + bl_label = "Add Constraints" bl_idname = Panels.SketcherAddContraint bl_options = {"DEFAULT_CLOSED"} @@ -191,6 +199,7 @@ class VIEW3D_PT_sketcher_entities(VIEW3D_PT_sketcher_base): Entities Menu: List of entities in the sketch. Interactive """ + bl_label = "Entities" bl_idname = Panels.SketcherEntities bl_options = {"DEFAULT_CLOSED"} @@ -274,11 +283,12 @@ def draw(self, context: Context): def draw_constraint_listitem( - context: Context, - layout: UILayout, - constraint: GenericConstraint + context: Context, layout: UILayout, constraint: GenericConstraint ): - """Creates a single row inside the ``layout`` describing the ``constraint``.""" + """ + Creates a single row inside the ``layout`` describing + the ``constraint``. + """ index = context.scene.sketcher.constraints.get_index(constraint) row = layout.row() @@ -307,13 +317,14 @@ def draw_constraint_listitem( center_sub = row.row() center_sub.alignment = "LEFT" - # Dimensional Constraint Values for constraint_prop in constraint.props: center_sub.prop(constraint, constraint_prop, text="") # Disable interaction with element if it is "readonly" - center_sub.enabled = isinstance(constraint, DimensionalConstraint) and constraint.is_reference + center_sub.enabled = ( + isinstance(constraint, DimensionalConstraint) and constraint.is_reference + ) # Right part right_sub = row.row() @@ -347,6 +358,7 @@ class VIEW3D_PT_sketcher_constraints(VIEW3D_PT_sketcher_base): Constraints Menu: List of entities in the sketch. Interactive """ + bl_label = "Constraints" bl_idname = Panels.SketcherContraints bl_options = {"DEFAULT_CLOSED"} From dc9a8fcac38e053b258ace60fdbaa3b9f7359fb3 Mon Sep 17 00:00:00 2001 From: amrsoll Date: Mon, 12 Sep 2022 21:18:25 +0200 Subject: [PATCH 10/11] Fixes from review. --- model/base_constraint.py | 3 --- ui.py | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/model/base_constraint.py b/model/base_constraint.py index 91b786c6..39a56044 100644 --- a/model/base_constraint.py +++ b/model/base_constraint.py @@ -237,6 +237,3 @@ def draw_props(self, layout: UILayout): row = sub.row() row.prop(self, "setting") return sub - - def is_active(self, *args, **kwargs): - return GenericConstraint.is_active(self, *args, **kwargs) diff --git a/ui.py b/ui.py index a002dd26..abee05df 100644 --- a/ui.py +++ b/ui.py @@ -322,7 +322,7 @@ def draw_constraint_listitem( center_sub.prop(constraint, constraint_prop, text="") # Disable interaction with element if it is "readonly" - center_sub.enabled = ( + center_sub.enabled = not ( isinstance(constraint, DimensionalConstraint) and constraint.is_reference ) From 5bd293d440013d7bdb3ad91ab0871949c9537b45 Mon Sep 17 00:00:00 2001 From: amrsoll Date: Mon, 12 Sep 2022 21:55:33 +0200 Subject: [PATCH 11/11] Test: re-enable UI elements + conditional setter. --- model/angle.py | 9 +++++---- model/base_constraint.py | 14 +++++++++++--- model/distance.py | 6 +++--- ui.py | 8 ++++---- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/model/angle.py b/model/angle.py index e6d026ee..7fe9ae74 100644 --- a/model/angle.py +++ b/model/angle.py @@ -26,14 +26,15 @@ class SlvsAngle(DimensionalConstraint, PropertyGroup): The constraint's setting can be used to to constrain the supplementary angle. """ - def _set_value(self, value): - DimensionalConstraint._set_value( + def _set_value_force(self, value): + DimensionalConstraint._set_value_force( self, HALF_TURN - value if self.setting else value ) def assign_init_props(self, context: Context = None): # Updating self.setting will create recursion loop - self.value, _ = self.init_props() + _value, _ = self.init_props() + self._set_value_force(_value) line1, line2 = self.entity1, self.entity2 origin = functions.get_line_intersection( *functions.line_abc_form(line1.p1.co, line1.p2.co), @@ -51,7 +52,7 @@ def assign_init_props(self, context: Context = None): unit="ROTATION", update=DimensionalConstraint.update_system_cb, get=DimensionalConstraint._get_value, - set=_set_value, + set=DimensionalConstraint._set_value, ) setting: BoolProperty( name="Measure supplementary angle", diff --git a/model/base_constraint.py b/model/base_constraint.py index 39a56044..45b95e34 100644 --- a/model/base_constraint.py +++ b/model/base_constraint.py @@ -188,6 +188,13 @@ class DimensionalConstraint(GenericConstraint): setting: BoolProperty def _set_value(self, val: float): + # NOTE: function signature _set_value(self, val: float, force=False) + # will fail when bpy tries to register the value property. + # See `_set_value_force()` + if not self.is_reference: + self._set_value_force(val) + + def _set_value_force(self, val: float): self["value"] = val def _get_value(self): @@ -200,9 +207,10 @@ def _get_value(self): def assign_init_props(self, context: Context = None): # self.value, self.setting = self.init_props() - self.value, _ = self.init_props() + _value, _ = self.init_props() + self._set_value_force(_value) - def refresh_constraint(self, context: Context = None): + def on_reference_checked(self, context: Context = None): self.assign_init_props() # Refresh the gizmos as we are changing the colors. functions.refresh(context) @@ -210,7 +218,7 @@ def refresh_constraint(self, context: Context = None): is_reference: BoolProperty( name="Only measure", default=False, - update=refresh_constraint, + update=on_reference_checked, ) def init_props(self): diff --git a/model/distance.py b/model/distance.py index 83c5a624..791f95f2 100644 --- a/model/distance.py +++ b/model/distance.py @@ -46,8 +46,8 @@ def get_side_of_line(line_start, line_end, point): class SlvsDistance(DimensionalConstraint, PropertyGroup): """Sets the distance between a point and some other entity (point/line/Workplane).""" - def _set_value(self, value): - DimensionalConstraint._set_value(self, abs(value)) + def _set_value_force(self, value): + DimensionalConstraint._set_value_force(self, abs(value)) label = "Distance" value: FloatProperty( @@ -56,7 +56,7 @@ def _set_value(self, value): unit="LENGTH", update=DimensionalConstraint.update_system_cb, get=DimensionalConstraint._get_value, - set=_set_value, + set=DimensionalConstraint._set_value, ) flip: BoolProperty(name="Flip", update=DimensionalConstraint.update_system_cb) align: EnumProperty( diff --git a/ui.py b/ui.py index abee05df..e83acc61 100644 --- a/ui.py +++ b/ui.py @@ -321,10 +321,10 @@ def draw_constraint_listitem( for constraint_prop in constraint.props: center_sub.prop(constraint, constraint_prop, text="") - # Disable interaction with element if it is "readonly" - center_sub.enabled = not ( - isinstance(constraint, DimensionalConstraint) and constraint.is_reference - ) + # # Disable interaction with element if it is "readonly" + # center_sub.enabled = not ( + # isinstance(constraint, DimensionalConstraint) and constraint.is_reference + # ) # Right part right_sub = row.row()