Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create "constructor" constraints. #272

Merged
merged 11 commits into from
Sep 20, 2022
Prev Previous commit
Next Next commit
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...
  • Loading branch information
amrsoll committed Sep 11, 2022
commit ee09f49ec6e2653109ae58a29df2ede2997651e0
52 changes: 27 additions & 25 deletions model/angle.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -12,38 +12,48 @@
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


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)
Expand All @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
41 changes: 35 additions & 6 deletions model/base_constraint.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 []
Expand All @@ -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):
amrsoll marked this conversation as resolved.
Show resolved Hide resolved
return GenericConstraint.is_active(self, *args, **kwargs)
26 changes: 4 additions & 22 deletions model/diameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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:
Expand Down
22 changes: 9 additions & 13 deletions model/distance.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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):
Expand Down