Skip to content

Commit 04601d0

Browse files
Merge branch 'hiaselhans:develop' into cutback2
2 parents b8c5e7a + bc6aa45 commit 04601d0

File tree

22 files changed

+289
-192
lines changed

22 files changed

+289
-192
lines changed

openglider/glider/cell/attachment_point.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
from typing import TYPE_CHECKING, Any
55

66
import euklid
7+
from pydantic import Field
78
from openglider.glider.shape import Shape
89
from openglider.lines.node import Node, NODE_TYPE_ENUM
910
from openglider.utils import table
10-
from openglider.vector.unit import Percentage
11+
from openglider.vector.unit import Length, Percentage
1112

1213
if TYPE_CHECKING:
1314
from openglider.glider.cell.cell import Cell
@@ -21,7 +22,7 @@ class CellAttachmentPoint(Node):
2122
rib_pos: Percentage
2223
node_type: NODE_TYPE_ENUM = Node.NODE_TYPE.UPPER
2324
ballooned: bool=False
24-
offset: float = 0.
25+
offset: Length = Field(default_factory=Length.zero)
2526

2627
def __repr__(self) -> str:
2728
return f"<Attachment point '{self.name}' ({self.rib_pos})>"

openglider/glider/curve.py

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,37 @@
1-
from typing import Any
1+
from typing import Any, ClassVar
22

33
import euklid
44
import enum
55

66
from openglider.glider.shape import Shape
77
from openglider.utils.cache import cached_property
8+
from openglider.utils.dataclass import BaseModel
9+
from openglider.vector.unit import Angle, Length, Percentage, Quantity
810

9-
class FreeCurve:
11+
class CurveBase(BaseModel):
12+
unit: str | None = None
13+
interpolation: euklid.vector.Interpolation
14+
shape: Shape
15+
16+
def to_unit(self, value: float) -> Quantity | float:
17+
if self.unit is None:
18+
return value
19+
20+
if self.unit in Angle.unit_variants or self.unit == Angle.unit:
21+
return Angle(value, unit=self.unit)
22+
if self.unit in Length.unit_variants or self.unit == Length.unit:
23+
return Length(value, unit=self.unit)
24+
if self.unit in Percentage.unit_variants:
25+
return Percentage(value, self.unit)
26+
27+
raise ValueError()
28+
29+
class FreeCurve(CurveBase):
1030
def __init__(self, points: list[euklid.vector.Vector2D], shape: Shape):
11-
self.shape = shape
12-
self.interpolation = euklid.vector.Interpolation(points)
31+
super().__init__(
32+
shape = shape,
33+
interpolation = euklid.vector.Interpolation(points)
34+
)
1335

1436
@property
1537
def controlpoints(self) -> list[euklid.vector.Vector2D]:
@@ -67,11 +89,12 @@ def to_controlpoints(self, points: list[euklid.vector.Vector2D]) -> list[euklid.
6789
def points_2d(self) -> list[euklid.vector.Vector2D]:
6890
return self.to_2d(self.interpolation.nodes)
6991

70-
def get(self, rib_no: int) -> float:
92+
def get(self, rib_no: int) -> float | Quantity:
7193
if rib_no == 0 and self.shape.has_center_cell:
7294
rib_no = 1
7395

74-
return self.interpolation.get_value(rib_no)
96+
value = self.interpolation.get_value(rib_no)
97+
return self.to_unit(value)
7598

7699
def draw(self) -> euklid.vector.PolyLine2D:
77100
x_values = [p[0] for p in self.controlpoints]
@@ -92,11 +115,12 @@ def draw(self) -> euklid.vector.PolyLine2D:
92115
return euklid.vector.PolyLine2D(self.to_2d([euklid.vector.Vector2D([x, self.interpolation.get_value(x)]) for x in x_values_lst]))
93116

94117

95-
class Curve:
96-
upper = False
118+
class Curve(CurveBase):
97119
def __init__(self, points: list[euklid.vector.Vector2D], shape: Shape):
98-
self.interpolation = euklid.vector.Interpolation(points)
99-
self.shape = shape
120+
super().__init__(
121+
interpolation = euklid.vector.Interpolation(points),
122+
shape=shape
123+
)
100124

101125
@property
102126
def controlpoints(self) -> list[euklid.vector.Vector2D]:
@@ -154,16 +178,13 @@ def points_2d(self) -> euklid.vector.PolyLine2D:
154178
self.shape.get_point(*p) for p in self.interpolation.nodes
155179
])
156180

157-
def get(self, rib_no: int) -> float:
181+
def get(self, rib_no: int) -> float | Quantity:
158182
if rib_no == 0 and self.shape.has_center_cell:
159183
rib_no = 1
160184

161185
y = self.interpolation.get_value(rib_no)
162186

163-
if self.upper:
164-
y = -y
165-
166-
return y
187+
return self.to_unit(y)
167188

168189
def draw(self) -> euklid.vector.PolyLine2D:
169190
x_values = [p[0] for p in self.controlpoints]
@@ -181,7 +202,19 @@ def draw(self) -> euklid.vector.PolyLine2D:
181202
if end % 1:
182203
x_values_lst.append(end)
183204

184-
points = [self.shape.get_point(x, self.get(x)) for x in x_values_lst]
205+
percentage_lst: list[Percentage | float] = []
206+
for x in x_values_lst:
207+
y = self.get(x)
208+
if not isinstance(y, (Percentage, float)):
209+
raise ValueError()
210+
211+
percentage_lst.append(y)
212+
213+
for p in percentage_lst:
214+
if not isinstance(p, (Percentage, float)):
215+
raise ValueError()
216+
217+
points = [self.shape.get_point(x, y) for x, y in zip(x_values_lst, percentage_lst)]
185218

186219
if start == 1 and self.shape.has_center_cell:
187220
points.insert(0, points[0] * euklid.vector.Vector2D([-1,1]))
@@ -191,8 +224,7 @@ def draw(self) -> euklid.vector.PolyLine2D:
191224

192225

193226
class ShapeCurve(Curve):
194-
195-
def get(self, rib_no: int) -> float:
227+
def get(self, rib_no: int) -> float | Quantity:
196228
if rib_no == 0 and self.shape.has_center_cell:
197229
rib_no = 1
198230

@@ -203,17 +235,11 @@ def get(self, rib_no: int) -> float:
203235
if len(results) != 1:
204236
raise Exception(f"wrong number of cut results: {len(results)}")
205237

206-
return results[0][1]
238+
return self.to_unit(results[0][1])
207239

208240

209241
class ShapeBSplineCurve(ShapeCurve):
210-
curve_cls = euklid.spline.BSplineCurve
211-
212-
def __init__(self, points: list[euklid.vector.Vector2D], shape: Shape, curve_cls: Any=None):
213-
if curve_cls is not None:
214-
self.curve_cls = curve_cls
215-
216-
super().__init__(points, shape)
242+
curve_cls: ClassVar[type] = euklid.spline.BSplineCurve
217243

218244
@cached_property('shape', 'interpolation')
219245
def points_2d(self) -> euklid.vector.PolyLine2D:

openglider/glider/parametric/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import re
22
from typing import Any, ClassVar, Self
33

4+
from packaging.version import Version
45
import euklid
56
import pydantic
67

@@ -121,7 +122,7 @@ class ParametricGliderConfig(ConfigTable):
121122

122123
use_sag: bool = True
123124

124-
version: str = __version__
125+
version: Version = Version(__version__)
125126

126127
@classmethod
127128
def __from_json__(cls, **data: Any) -> Self:

openglider/glider/parametric/export_ods.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,8 @@ def add_curve(name: str, curve: CurveType, column_no: int) -> None:
185185
add_curve("rib_distribution", glider.shape.rib_distribution, 4)
186186
add_curve("arc", glider.arc.curve, 6)
187187
add_curve("aoa", glider.aoa, 8)
188-
add_curve("zrot", glider.zrot, 10)
189-
add_curve("ballooning_merge_curve", glider.ballooning_merge_curve, 12)
190-
add_curve("profile_merge_curve", glider.profile_merge_curve, 14)
188+
add_curve("ballooning_merge_curve", glider.ballooning_merge_curve, 10)
189+
add_curve("profile_merge_curve", glider.profile_merge_curve, 12)
191190

192191
return table
193192

openglider/glider/parametric/fitglider.py

Lines changed: 0 additions & 67 deletions
This file was deleted.

openglider/glider/parametric/glider.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from openglider.glider.glider import Glider
1919
from openglider.glider.parametric.arc import ArcCurve
2020
from openglider.glider.parametric.export_ods import export_ods_2d
21-
from openglider.glider.parametric.fitglider import fit_glider_3d
2221
from openglider.glider.parametric.import_ods import import_ods_2d
2322
from openglider.glider.parametric.shape import ParametricShape
2423
from openglider.glider.parametric.table import GliderTables
@@ -29,7 +28,7 @@
2928
from openglider.utils.distribution import Distribution
3029
from openglider.utils.table import Table
3130
from openglider.utils.types import CurveType, SymmetricCurveType
32-
from openglider.vector.unit import Percentage
31+
from openglider.vector.unit import Percentage, Quantity
3332

3433
if TYPE_CHECKING:
3534
from openglider.glider.curve import GliderCurveType
@@ -54,7 +53,6 @@ class ParametricGlider:
5453
speed: float
5554
glide: float
5655
tables: GliderTables = Field(default_factory=lambda: GliderTables())
57-
zrot: SymmetricCurveType = Field(default_factory=lambda: euklid.spline.SymmetricBSplineCurve([[0,0],[1,0]]))
5856

5957
num_interpolate: int=30
6058
num_profile: int | None=None
@@ -227,10 +225,6 @@ def apply_diagonals(self, glider: Glider) -> None:
227225
for strap_no, strap in enumerate(cell.diagonals):
228226
strap.name = "c{}{}{}".format(cell_no+1, "s", strap_no)
229227

230-
@classmethod
231-
def fit_glider_3d(cls, glider: Glider, numpoints: int=3) -> ParametricGlider:
232-
return fit_glider_3d(cls, glider, numpoints)
233-
234228
def get_aoa(self, interpolation_num: int | None=None) -> list[float]:
235229
aoa_interpolation = euklid.vector.Interpolation(self.aoa.get_sequence(interpolation_num or self.num_interpolate).nodes)
236230

@@ -283,8 +277,8 @@ def resolvers(self) -> list[Parser]:
283277
parsers = []
284278
curves=self.get_curves()
285279

286-
def resolver_factory(rib_no: int) -> Callable[[str], float]:
287-
def resolve(name: str) -> float:
280+
def resolver_factory(rib_no: int) -> Callable[[str], float | Quantity]:
281+
def resolve(name: str) -> float | Quantity:
288282
if name not in curves:
289283
raise ValueError(
290284
f"could not resolve name '{name}' "+
@@ -391,7 +385,6 @@ def get_glider_3d(self, glider: Glider=None, num: int=50, num_profile: int | Non
391385
shape_ribs = self.shape.ribs
392386

393387
aoa_values = self.get_aoa()
394-
zrot_int = euklid.vector.Interpolation(self.zrot.get_sequence(num).nodes)
395388

396389
arc_pos = self.arc.get_arc_positions(x_values).tolist()
397390
rib_angles = self.arc.get_rib_angles(x_values)
@@ -426,16 +419,18 @@ def get_glider_3d(self, glider: Glider=None, num: int=50, num_profile: int | Non
426419
}
427420
data.update(self.tables.rib_modifiers.get_rib_args(rib_no, resolvers=resolvers))
428421

422+
rotation = self.tables.rib_modifiers.get_rotation(rib_no, resolvers=resolvers)
423+
429424
rib = Rib(
430425
profile_2d=profile,
431426
pos=startpoint,
432427
chord=chord,
433428
arcang=rib_angles[rib_no],
434-
xrot=self.tables.rib_modifiers.get_xrot(rib_no),
429+
xrot=rotation.x,
435430
offset=self.tables.rib_modifiers.get_offset(rib_no, resolvers=resolvers),
436431
glide=self.glide,
437432
aoa_absolute=aoa_values[rib_no],
438-
zrot=zrot_int.get_value(abs(x_value)),
433+
zrot=rotation.z,
439434
holes=this_rib_holes,
440435
rigidfoils=this_rigid_foils,
441436
name=f"rib{rib_no}",
@@ -573,5 +568,4 @@ def rescale(curve: CurveType) -> None:
573568
rescale(self.ballooning_merge_curve)
574569
rescale(self.profile_merge_curve)
575570
rescale(self.aoa)
576-
rescale(self.zrot)
577571
self.arc.rescale(self.shape.rib_x_values)

0 commit comments

Comments
 (0)