forked from hlorus/CAD_Sketcher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
diameter.py
123 lines (98 loc) · 3.77 KB
/
diameter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import logging
import math
from bpy.types import PropertyGroup
from bpy.props import BoolProperty, FloatProperty
from bpy.utils import register_classes_factory
from mathutils import Vector, Matrix
from ..solver import Solver
from ..global_data import WpReq
from ..utilities.view import location_3d_to_region_2d
from ..utilities.math import range_2pi, pol2cart
from .base_constraint import DimensionalConstraint
from .utilities import slvs_entity_pointer
from .categories import CURVE
from ..utilities.solver import update_system_cb
logger = logging.getLogger(__name__)
class SlvsDiameter(DimensionalConstraint, PropertyGroup):
"""Sets the diameter of an arc or a circle."""
def use_radius_getter(self):
return self.get("setting", self.bl_rna.properties["setting"].default)
def use_radius_setter(self, setting):
old_setting = self.get("setting", self.bl_rna.properties["setting"].default)
self["setting"] = setting
distance = None
if old_setting and not setting:
distance = self.value * 2
elif not old_setting and setting:
distance = self.value / 2
if distance is not None:
# Avoid triggering the property's update callback
self["value"] = distance
@property
def label(self):
return "Radius" if self.setting else "Diameter"
value: FloatProperty(
name="Size",
subtype="DISTANCE",
unit="LENGTH",
get=DimensionalConstraint._get_value,
set=DimensionalConstraint._set_value,
update=update_system_cb,
)
setting: BoolProperty(
name="Use Radius", get=use_radius_getter, set=use_radius_setter
)
leader_angle: FloatProperty(name="Leader Angle", default=45, subtype="ANGLE")
draw_offset: FloatProperty(name="Draw Offset", default=0)
type = "DIAMETER"
signature = (CURVE,)
props = ("value",)
@property
def diameter(self):
value = self.value
if self.setting:
return value * 2
return value
@property
def radius(self):
value = self.value
if self.setting:
return value
return value / 2
def needs_wp(self):
return WpReq.OPTIONAL
def create_slvs_data(self, solvesys, group=Solver.group_fixed):
return solvesys.addDiameter(self.diameter, self.entity1.py_data, group=group)
def _get_init_value(self, setting):
value = self.entity1.radius
if not setting:
return value * 2
return value
def init_props(self, **kwargs):
setting = kwargs.get("setting", self.setting)
value = kwargs.get("value", self._get_init_value(setting))
return {"value": value, "setting": setting}
def matrix_basis(self):
if self.sketch_i == -1:
return Matrix()
sketch = self.sketch
origin = self.entity1.ct.co
rotation = range_2pi(math.radians(self.leader_angle))
mat_local = Matrix.Translation(origin.to_3d())
return sketch.wp.matrix_basis @ mat_local
def text_inside(self):
return self.draw_offset < self.radius
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
rv3d = context.space_data.region_3d
offset = self.draw_offset
coords = pol2cart(offset, self.leader_angle)
coords2 = self.matrix_basis() @ Vector((coords[0], coords[1], 0.0))
return location_3d_to_region_2d(region, rv3d, coords2)
slvs_entity_pointer(SlvsDiameter, "entity1")
slvs_entity_pointer(SlvsDiameter, "sketch")
register, unregister = register_classes_factory((SlvsDiameter,))