pyroll-core 3.0.0.post3__tar.gz → 3.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/PKG-INFO +7 -7
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/hatch.toml +3 -3
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyproject.toml +6 -4
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/__init__.py +5 -3
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/config.py +20 -17
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/spline.py +33 -43
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/repr.py +14 -7
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll/hookimpls.py +15 -6
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/__init__.py +0 -5
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/profile.py +6 -1
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/rotator/hookimpls.py +7 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/sequence/sequence.py +5 -5
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/shapes.py +55 -12
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/transport/hookimpls/transport.py +1 -1
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/.gitignore +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/LICENSE +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/README.md +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/disk_elements/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/disk_elements/disk_element_unit.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/disk_elements/hookimpls.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/base.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/boxes/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/boxes/box.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/boxes/constricted_box.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/boxes/upset_box.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/diamonds/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/diamonds/diamond.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/diamonds/gothic.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/diamonds/square.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/equivalent_ripped_groove.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/flat.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/generic_elongation.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/generic_elongation_solvers.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/hexagonal.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/circular_oval.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/constricted_circular_oval.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/constricted_swedish_oval.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/flat_oval.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/oval_3radii.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/oval_3radii_flanked.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/swedish_oval.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/upset_oval.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/rounds/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/rounds/false_round.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/rounds/round.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/hooks.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/log.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/profile/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/profile/hookimpls.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/profile/profile.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll/roll.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/base.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/deformation_unit.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/base_roll_pass.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/deformation_unit.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/disk_element.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/helpers.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/roll.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/symmetric_roll_pass.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/three_roll_pass.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/two_roll_pass.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/symmetric_roll_pass.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/three_roll_pass.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/two_roll_pass.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/rotator/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/rotator/rotator.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/sequence/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/sequence/hookimpls.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/transport/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/transport/cooling_pipe.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/transport/hookimpls/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/transport/hookimpls/cooling_pipe.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/transport/transport.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/unit/__init__.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/unit/hookimpls.py +0 -0
- {pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/unit/unit.py +0 -0
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pyroll-core
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.1
|
|
4
4
|
Summary: PyRoll rolling simulation framework - core library.
|
|
5
5
|
Project-URL: Homepage, https://pyroll-project.github.io
|
|
6
6
|
Project-URL: Repository, https://github.com/pyroll-project/pyroll-core
|
|
7
7
|
Project-URL: Documentation, https://pyroll.readthedocs.io/en/latest
|
|
8
8
|
Author-email: Max Weiner <max.weiner@imf.tu-freiberg.de>, Christoph Renzing <christoph.renzing@imf.tu-freiberg.de>, Matthias Schmidtchen <matthias.schmidtchen@imf.tu-freiberg.de>, Max Stirl <max.stirl@imf.tu-freiberg.de>
|
|
9
|
-
License
|
|
10
|
-
License-File: LICENSE
|
|
9
|
+
License: BSD-3-Clause
|
|
11
10
|
Classifier: Development Status :: 5 - Production/Stable
|
|
12
11
|
Classifier: Framework :: Hatch
|
|
13
12
|
Classifier: Framework :: IPython
|
|
@@ -25,10 +24,11 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
25
24
|
Classifier: Programming Language :: Python :: 3.11
|
|
26
25
|
Classifier: Topic :: Scientific/Engineering
|
|
27
26
|
Requires-Python: >=3.9
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
|
|
27
|
+
Requires-Dist: numpy~=2.0
|
|
28
|
+
Requires-Dist: scipy~=1.13
|
|
29
|
+
Requires-Dist: shapely<3.0,>=2.0.6
|
|
30
|
+
Provides-Extra: dxf
|
|
31
|
+
Requires-Dist: ezdxf-shapely~=1.0; extra == 'dxf'
|
|
32
32
|
Provides-Extra: matplotlib
|
|
33
33
|
Requires-Dist: matplotlib~=3.7; extra == 'matplotlib'
|
|
34
34
|
Provides-Extra: plot
|
|
@@ -11,16 +11,16 @@ path = ".venv"
|
|
|
11
11
|
dependencies = [
|
|
12
12
|
"ipython ~= 8.0",
|
|
13
13
|
"pytest ~= 7.0",
|
|
14
|
-
"pyroll-report ~=
|
|
14
|
+
"pyroll-report ~= 3.0",
|
|
15
15
|
"jupyter",
|
|
16
16
|
]
|
|
17
|
-
features = ["plotly", "matplotlib"]
|
|
17
|
+
features = ["plotly", "matplotlib", "dxf"]
|
|
18
18
|
|
|
19
19
|
[envs.test]
|
|
20
20
|
path = ""
|
|
21
21
|
dependencies = [
|
|
22
22
|
"pytest ~= 7.0",
|
|
23
|
-
"pyroll-report ~=
|
|
23
|
+
"pyroll-report ~= 3.0",
|
|
24
24
|
]
|
|
25
25
|
|
|
26
26
|
[[envs.test.matrix]]
|
|
@@ -34,10 +34,9 @@ classifiers = [
|
|
|
34
34
|
requires-python = ">=3.9"
|
|
35
35
|
|
|
36
36
|
dependencies = [
|
|
37
|
-
"numpy ~=
|
|
38
|
-
"scipy ~= 1.
|
|
39
|
-
"shapely
|
|
40
|
-
"ezdxf"
|
|
37
|
+
"numpy ~= 2.0",
|
|
38
|
+
"scipy ~= 1.13",
|
|
39
|
+
"shapely >= 2.0.6, <3.0",
|
|
41
40
|
]
|
|
42
41
|
|
|
43
42
|
dynamic = ["version"]
|
|
@@ -53,6 +52,9 @@ plotly = [
|
|
|
53
52
|
"plotly ~= 5.18",
|
|
54
53
|
"pandas ~= 2.0",
|
|
55
54
|
]
|
|
55
|
+
dxf = [
|
|
56
|
+
"ezdxf-shapely ~= 1.0",
|
|
57
|
+
]
|
|
56
58
|
|
|
57
59
|
[project.urls]
|
|
58
60
|
Homepage = "https://pyroll-project.github.io"
|
|
@@ -2,7 +2,8 @@ from . import shapes as _
|
|
|
2
2
|
|
|
3
3
|
from .grooves import *
|
|
4
4
|
from .transport import Transport, CoolingPipe
|
|
5
|
-
from .roll_pass import BaseRollPass,
|
|
5
|
+
from .roll_pass import BaseRollPass, DeformationUnit, ThreeRollPass, SymmetricRollPass, TwoRollPass
|
|
6
|
+
from .roll_pass import TwoRollPass as RollPass
|
|
6
7
|
from .unit import Unit
|
|
7
8
|
from .roll import Roll
|
|
8
9
|
from .profile import *
|
|
@@ -10,9 +11,9 @@ from .rotator import Rotator
|
|
|
10
11
|
from .sequence import PassSequence
|
|
11
12
|
from .hooks import Hook, HookHost, HookFunction, root_hooks
|
|
12
13
|
from .disk_elements import DiskElementUnit
|
|
13
|
-
from .config import Config, config
|
|
14
|
+
from .config import Config, config, PlottingBackend
|
|
14
15
|
|
|
15
|
-
VERSION = "3.0.
|
|
16
|
+
VERSION = "3.0.1"
|
|
16
17
|
|
|
17
18
|
root_hooks.extend(
|
|
18
19
|
[
|
|
@@ -31,6 +32,7 @@ root_hooks.extend(
|
|
|
31
32
|
BaseRollPass.OutProfile.filling_error,
|
|
32
33
|
BaseRollPass.OutProfile.cross_section_error,
|
|
33
34
|
BaseRollPass.OutProfile.velocity,
|
|
35
|
+
BaseRollPass.InProfile.velocity,
|
|
34
36
|
PassSequence.log_elongation,
|
|
35
37
|
BaseRollPass.OutProfile.technologically_orientated_cross_section,
|
|
36
38
|
BaseRollPass.technologically_orientated_contour_lines,
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import os
|
|
2
|
+
from enum import Enum
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
from typing import Optional, Iterable, Mapping, Any, Callable
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class ConfigValue:
|
|
7
8
|
"""Helper descriptor for storing configuration values, able to determine the value from explictly set values,
|
|
8
|
-
|
|
9
|
+
environment variables and default values."""
|
|
9
10
|
|
|
10
11
|
def __init__(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
self,
|
|
13
|
+
default,
|
|
14
|
+
*,
|
|
15
|
+
env_var: Optional[str] = None,
|
|
16
|
+
env_var_prefix: Optional[str] = None,
|
|
17
|
+
parser: Optional[Callable[[str], Any]] = None,
|
|
17
18
|
):
|
|
18
19
|
self.default = default
|
|
19
20
|
self.type = type(default)
|
|
@@ -26,7 +27,7 @@ class ConfigValue:
|
|
|
26
27
|
self.owner = owner
|
|
27
28
|
self.name = name
|
|
28
29
|
if not self._env_var_prefix:
|
|
29
|
-
self._env_var_prefix = self.owner.__module__.upper().replace(
|
|
30
|
+
self._env_var_prefix = self.owner.__module__.upper().replace(".", "_")
|
|
30
31
|
|
|
31
32
|
@property
|
|
32
33
|
def env_var(self):
|
|
@@ -83,11 +84,7 @@ class ConfigValue:
|
|
|
83
84
|
class ConfigMeta(type):
|
|
84
85
|
def to_dict(cls):
|
|
85
86
|
"""Return the config values of this class as dict."""
|
|
86
|
-
return {
|
|
87
|
-
n: v
|
|
88
|
-
for n, v in type(cls).__dict__.items()
|
|
89
|
-
if isinstance(v, ConfigValue)
|
|
90
|
-
}
|
|
87
|
+
return {n: v for n, v in type(cls).__dict__.items() if isinstance(v, ConfigValue)}
|
|
91
88
|
|
|
92
89
|
def update(cls, d: dict[str, Any]):
|
|
93
90
|
"""
|
|
@@ -138,10 +135,7 @@ def config(env_var_prefix):
|
|
|
138
135
|
else:
|
|
139
136
|
# noinspection PyProtectedMember
|
|
140
137
|
meta_dict[n] = ConfigValue(
|
|
141
|
-
default=v.default,
|
|
142
|
-
env_var_prefix=env_var_prefix,
|
|
143
|
-
env_var=v._env_var,
|
|
144
|
-
parser=v.parser
|
|
138
|
+
default=v.default, env_var_prefix=env_var_prefix, env_var=v._env_var, parser=v.parser
|
|
145
139
|
)
|
|
146
140
|
|
|
147
141
|
meta = type(cls.__name__ + "Meta", (ConfigMeta,), meta_dict)
|
|
@@ -151,9 +145,15 @@ def config(env_var_prefix):
|
|
|
151
145
|
return dec
|
|
152
146
|
|
|
153
147
|
|
|
148
|
+
class PlottingBackend(Enum):
|
|
149
|
+
PLOTLY = 1
|
|
150
|
+
MATPLOTLIB = 2
|
|
151
|
+
|
|
152
|
+
|
|
154
153
|
@config("PYROLL_CORE")
|
|
155
154
|
class Config:
|
|
156
155
|
"""Configuration class for ``pyroll.core``."""
|
|
156
|
+
|
|
157
157
|
ROLL_PASS_AUTO_ROTATION = True
|
|
158
158
|
"""Whether to enable automatic rotation of incoming profiles in roll passes by default."""
|
|
159
159
|
|
|
@@ -199,3 +199,6 @@ class Config:
|
|
|
199
199
|
|
|
200
200
|
PLOT_RESOLUTION = 100
|
|
201
201
|
"""Resolution of plots in dots per inches (dpi)."""
|
|
202
|
+
|
|
203
|
+
PREFERRED_PLOTTING_BACKEND = PlottingBackend.PLOTLY
|
|
204
|
+
"""Sets the preferred plotting backend to use when both matplotlib and plotly are installed."""
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
import scipy.interpolate
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from ezdxf import readfile
|
|
5
4
|
from shapely.geometry import Polygon, LineString
|
|
6
5
|
from typing import Union, Tuple, Iterable, Optional
|
|
7
6
|
|
|
@@ -12,10 +11,10 @@ class SplineGroove(GrooveBase):
|
|
|
12
11
|
"""Represents a groove defined by a linear spline contour."""
|
|
13
12
|
|
|
14
13
|
def __init__(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
self,
|
|
15
|
+
contour_points: Union[Iterable[Tuple[float, float]], np.ndarray],
|
|
16
|
+
classifiers: Iterable[str],
|
|
17
|
+
usable_width: Optional[float] = None,
|
|
19
18
|
):
|
|
20
19
|
"""
|
|
21
20
|
:param contour_points: an iterable of contour points to be used for the spline
|
|
@@ -34,9 +33,11 @@ class SplineGroove(GrooveBase):
|
|
|
34
33
|
raise ValueError("first and last element of contour_points should have y coordinate equal to 0")
|
|
35
34
|
|
|
36
35
|
# strip boundary
|
|
37
|
-
contour_points = contour_points[
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
contour_points = contour_points[
|
|
37
|
+
np.logical_not(
|
|
38
|
+
(np.isclose(np.roll(contour_points[:, 1], 1), 0)) & (np.isclose(np.roll(contour_points[:, 1], -1), 0))
|
|
39
|
+
)
|
|
40
|
+
]
|
|
40
41
|
|
|
41
42
|
# shift center to 0,0
|
|
42
43
|
contour_points[:, 0] -= np.mean(contour_points[:, 0])
|
|
@@ -56,8 +57,7 @@ class SplineGroove(GrooveBase):
|
|
|
56
57
|
self._depth = np.max(contour_points[:, 1])
|
|
57
58
|
|
|
58
59
|
self._local_depth = scipy.interpolate.interp1d(
|
|
59
|
-
contour_points[:, 0], contour_points[:, 1],
|
|
60
|
-
fill_value="extrapolate"
|
|
60
|
+
contour_points[:, 0], contour_points[:, 1], fill_value="extrapolate"
|
|
61
61
|
)
|
|
62
62
|
self._classifiers = tuple(classifiers)
|
|
63
63
|
|
|
@@ -93,46 +93,36 @@ class SplineGroove(GrooveBase):
|
|
|
93
93
|
return self._local_depth(z)
|
|
94
94
|
|
|
95
95
|
@classmethod
|
|
96
|
-
def from_dxf_drawing(
|
|
97
|
-
|
|
96
|
+
def from_dxf_drawing(
|
|
97
|
+
cls,
|
|
98
|
+
filepath: Path,
|
|
99
|
+
classifiers: Iterable[str],
|
|
100
|
+
usable_width: Optional[float] = None,
|
|
101
|
+
arc_degrees_per_segment: float = 0.5,
|
|
102
|
+
spline_delta: float = 0.1,
|
|
103
|
+
dxf_query: str = '* [layer=="0"]',
|
|
104
|
+
) -> "SplineGroove":
|
|
98
105
|
"""
|
|
99
106
|
Creates a spline groove with a given contour line as defined inside the .dxf drawing.
|
|
100
107
|
|
|
101
108
|
:param filepath: the filepath to the drawing
|
|
102
109
|
:param classifiers: an iterable of string keys used as type classifiers
|
|
103
110
|
:param usable_width: the usable width to assume for this instance, if None, the maximum width will be used
|
|
104
|
-
:param
|
|
111
|
+
:param arc_degrees_per_segment: discretization width in degrees for arcs and circles
|
|
112
|
+
:param dxf_query: query to filter the wanted geometries out of the dxf, see the ezdxf docs for details
|
|
105
113
|
"""
|
|
106
114
|
|
|
107
|
-
|
|
108
|
-
|
|
115
|
+
try:
|
|
116
|
+
from ezdxf import readfile
|
|
117
|
+
from ezdxf_shapely import convert_all, line_merge
|
|
118
|
+
except ImportError as e:
|
|
119
|
+
raise RuntimeError("ezdxf-shapely is required for DXF import, you may install it with the dxf extra") from e
|
|
120
|
+
from shapely.affinity import translate
|
|
109
121
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
122
|
+
dxf_doc = readfile(filepath)
|
|
123
|
+
msp = dxf_doc.modelspace().query(dxf_query)
|
|
124
|
+
geoms = convert_all(msp, spline_delta=spline_delta, degrees_per_segment=arc_degrees_per_segment)
|
|
125
|
+
geom = line_merge(geoms)
|
|
126
|
+
geom = translate(geom, -geom.centroid.x, -geom.bounds[1])
|
|
115
127
|
|
|
116
|
-
|
|
117
|
-
center = (entity.dxf.center[0], entity.dxf.center[1])
|
|
118
|
-
radius = entity.dxf.radius
|
|
119
|
-
start_angle = np.radians(entity.dxf.start_angle)
|
|
120
|
-
end_angle = np.radians(entity.dxf.end_angle)
|
|
121
|
-
|
|
122
|
-
arc_points = [
|
|
123
|
-
(
|
|
124
|
-
center[0] + radius * np.cos(start_angle + (end_angle - start_angle) * i / arc_discretization),
|
|
125
|
-
center[1] + radius * np.sin(start_angle + (end_angle - start_angle) * i / arc_discretization),
|
|
126
|
-
)
|
|
127
|
-
for i in range(arc_discretization + 1)
|
|
128
|
-
]
|
|
129
|
-
points.extend(arc_points)
|
|
130
|
-
|
|
131
|
-
points.sort(key=lambda p: p[0])
|
|
132
|
-
|
|
133
|
-
distance_to_y_0 = -points[0][1]
|
|
134
|
-
|
|
135
|
-
shifted_points = [(x, y + distance_to_y_0) for x, y in points]
|
|
136
|
-
shifted_points.sort(key=lambda p: p[0])
|
|
137
|
-
|
|
138
|
-
return SplineGroove(contour_points=shifted_points, classifiers=classifiers, usable_width=usable_width)
|
|
128
|
+
return SplineGroove(contour_points=geom.coords, classifiers=classifiers, usable_width=usable_width)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import html
|
|
2
2
|
from abc import ABC, abstractmethod
|
|
3
3
|
from io import StringIO
|
|
4
|
-
|
|
5
|
-
from .
|
|
4
|
+
|
|
5
|
+
from .config import Config, PlottingBackend
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class ReprMixin(ABC):
|
|
@@ -49,11 +49,18 @@ class ReprMixin(ABC):
|
|
|
49
49
|
|
|
50
50
|
:returns: either a plotly or matplotlib figure object
|
|
51
51
|
"""
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
if Config.PREFERRED_PLOTTING_BACKEND == PlottingBackend.PLOTLY:
|
|
53
|
+
try:
|
|
54
|
+
return self.plot_plotly()
|
|
55
|
+
except (NotImplementedError, ImportError):
|
|
56
|
+
return self.plot_matplotlib()
|
|
57
|
+
elif Config.PREFERRED_PLOTTING_BACKEND == PlottingBackend.MATPLOTLIB:
|
|
58
|
+
try:
|
|
59
|
+
return self.plot_matplotlib()
|
|
60
|
+
except (NotImplementedError, ImportError):
|
|
61
|
+
return self.plot_plotly()
|
|
62
|
+
|
|
63
|
+
raise ValueError("Invalid value given for 'Config.PREFERRED_PLOTTING_BACKEND'. Value must be a member of the pyroll.core.PlottingBackend enumeration.")
|
|
57
64
|
|
|
58
65
|
def __str__(self):
|
|
59
66
|
return type(self).__qualname__
|
|
@@ -25,18 +25,27 @@ def roll_power(self: Roll):
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
@Roll.working_velocity
|
|
28
|
-
def working_velocity(self: Roll):
|
|
29
|
-
|
|
28
|
+
def working_velocity(self: Roll, cycle):
|
|
29
|
+
if not cycle:
|
|
30
|
+
return self.rotational_frequency * self.working_radius * 2 * np.pi
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
@Roll.surface_velocity
|
|
33
|
-
def surface_velocity(self: Roll):
|
|
34
|
-
|
|
34
|
+
def surface_velocity(self: Roll, cycle):
|
|
35
|
+
if not cycle:
|
|
36
|
+
return self.rotational_frequency * self.nominal_radius * 2 * np.pi
|
|
35
37
|
|
|
36
38
|
|
|
37
39
|
@Roll.rotational_frequency
|
|
38
|
-
def rotational_frequency(self: Roll):
|
|
39
|
-
|
|
40
|
+
def rotational_frequency(self: Roll, cycle):
|
|
41
|
+
if not cycle:
|
|
42
|
+
return self.surface_velocity / (2 * np.pi * self.nominal_radius)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@Roll.rotational_frequency
|
|
46
|
+
def rotational_frequency(self: Roll, cycle):
|
|
47
|
+
if not cycle:
|
|
48
|
+
return self.working_velocity / (2 * np.pi * self.working_radius)
|
|
40
49
|
|
|
41
50
|
|
|
42
51
|
@Roll.width
|
|
@@ -88,6 +88,11 @@ def classifiers(self: BaseRollPass.OutProfile):
|
|
|
88
88
|
return set(self.roll_pass.classifiers)
|
|
89
89
|
|
|
90
90
|
|
|
91
|
+
@BaseRollPass.InProfile.velocity
|
|
92
|
+
def in_velocity(self: BaseRollPass.InProfile):
|
|
93
|
+
return self.roll_pass.out_profile.velocity * self.unit.out_profile.cross_section.area / self.cross_section.area
|
|
94
|
+
|
|
95
|
+
|
|
91
96
|
@BaseRollPass.OutProfile.velocity
|
|
92
|
-
def
|
|
97
|
+
def out_velocity(self: BaseRollPass.OutProfile):
|
|
93
98
|
return self.roll_pass.velocity
|
|
@@ -52,6 +52,13 @@ def box_diamond_45(self: Rotator):
|
|
|
52
52
|
return 45
|
|
53
53
|
|
|
54
54
|
|
|
55
|
+
@Rotator.rotation
|
|
56
|
+
def flat_flat_0(self: Rotator):
|
|
57
|
+
if "3fold" not in self.next_roll_pass.classifiers:
|
|
58
|
+
if "flat" in self.in_profile.classifiers and "flat" in self.next_roll_pass.classifiers:
|
|
59
|
+
return 0
|
|
60
|
+
|
|
61
|
+
|
|
55
62
|
@Rotator.rotation
|
|
56
63
|
def box_flat_0(self: Rotator):
|
|
57
64
|
if "box" in self.in_profile.classifiers and "flat" in self.next_roll_pass.classifiers:
|
|
@@ -4,7 +4,7 @@ from collections.abc import Sequence
|
|
|
4
4
|
from typing import overload, List, cast
|
|
5
5
|
|
|
6
6
|
from ..unit import Unit
|
|
7
|
-
from ..roll_pass import
|
|
7
|
+
from ..roll_pass import BaseRollPass
|
|
8
8
|
from ..transport import Transport
|
|
9
9
|
from ..hooks import Hook
|
|
10
10
|
|
|
@@ -104,9 +104,9 @@ class PassSequence(Unit, Sequence[Unit]):
|
|
|
104
104
|
return list(self._subunits)
|
|
105
105
|
|
|
106
106
|
@property
|
|
107
|
-
def roll_passes(self) -> List[
|
|
107
|
+
def roll_passes(self) -> List[BaseRollPass]:
|
|
108
108
|
"""Returns a list of all roll passes in this sequence."""
|
|
109
|
-
return list(u for u in self._subunits if isinstance(u,
|
|
109
|
+
return list(u for u in self._subunits if isinstance(u, BaseRollPass))
|
|
110
110
|
|
|
111
111
|
@property
|
|
112
112
|
def transports(self) -> List[Transport]:
|
|
@@ -135,7 +135,7 @@ class PassSequence(Unit, Sequence[Unit]):
|
|
|
135
135
|
for i in range(len(cross_sections_areas) - 2, -1, -1):
|
|
136
136
|
velocities[i] = velocities[i + 1] * cross_sections_areas[i + 1] / cross_sections_areas[i]
|
|
137
137
|
|
|
138
|
-
def set_velocities_to_roll_passes(roll_passes: List[
|
|
138
|
+
def set_velocities_to_roll_passes(roll_passes: List[BaseRollPass], velocities: np.ndarray[float]):
|
|
139
139
|
for roll_pass, velocity in zip(roll_passes, velocities):
|
|
140
140
|
roll_pass.velocity = velocity
|
|
141
141
|
|
|
@@ -179,7 +179,7 @@ class PassSequence(Unit, Sequence[Unit]):
|
|
|
179
179
|
for i in range(1, len(usable_cross_section_areas)):
|
|
180
180
|
velocities[i] = velocities[i - 1] * cross_sections_areas[i - 1] / cross_sections_areas[i]
|
|
181
181
|
|
|
182
|
-
def set_velocities_to_roll_passes(roll_passes: List[
|
|
182
|
+
def set_velocities_to_roll_passes(roll_passes: List[BaseRollPass], velocities: np.ndarray[float]):
|
|
183
183
|
for roll_pass, velocity in zip(roll_passes, velocities):
|
|
184
184
|
roll_pass.velocity = velocity
|
|
185
185
|
|
|
@@ -91,23 +91,21 @@ def multi_polygon_plot_matplotlib(self: MultiPolygon):
|
|
|
91
91
|
ax.set_aspect("equal", "datalim")
|
|
92
92
|
ax.grid(lw=0.5)
|
|
93
93
|
|
|
94
|
-
for g
|
|
95
|
-
ax.plot(*g.boundary.xy
|
|
96
|
-
ax.fill(*g.boundary.xy, alpha=0.5, color=
|
|
94
|
+
for g in self.geoms:
|
|
95
|
+
l = ax.plot(*g.boundary.xy)
|
|
96
|
+
ax.fill(*g.boundary.xy, alpha=0.5, color=l[0].get_color())
|
|
97
97
|
return fig
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
def multi_polygon_plot_plotly(self: MultiPolygon):
|
|
101
101
|
import plotly.graph_objects as pgo
|
|
102
|
-
from pandas import DataFrame
|
|
103
102
|
|
|
104
103
|
fig = pgo.Figure()
|
|
105
104
|
|
|
106
105
|
for g in self.geoms:
|
|
107
|
-
fig.add_trace(pgo.
|
|
108
|
-
x=
|
|
109
|
-
y=
|
|
110
|
-
labels={"y": "y", "x": "z"},
|
|
106
|
+
fig.add_trace(pgo.Line(
|
|
107
|
+
x=np.array(g.boundary.xy[0]),
|
|
108
|
+
y=np.array(g.boundary.xy[1]),
|
|
111
109
|
))
|
|
112
110
|
|
|
113
111
|
fig.update_traces(
|
|
@@ -116,9 +114,12 @@ def multi_polygon_plot_plotly(self: MultiPolygon):
|
|
|
116
114
|
|
|
117
115
|
fig.update_yaxes(
|
|
118
116
|
scaleanchor="x",
|
|
119
|
-
scaleratio=1
|
|
117
|
+
scaleratio=1,
|
|
118
|
+
title="y"
|
|
120
119
|
)
|
|
121
120
|
|
|
121
|
+
fig.update_xaxes(title="z")
|
|
122
|
+
|
|
122
123
|
return fig
|
|
123
124
|
|
|
124
125
|
|
|
@@ -134,7 +135,7 @@ def line_string_plot_matplotlib(self: LineString):
|
|
|
134
135
|
ax.set_aspect("equal", "datalim")
|
|
135
136
|
ax.grid(lw=0.5)
|
|
136
137
|
|
|
137
|
-
ax.plot(*self.xy
|
|
138
|
+
ax.plot(*self.xy)
|
|
138
139
|
return fig
|
|
139
140
|
|
|
140
141
|
|
|
@@ -147,8 +148,6 @@ def line_string_plot_plotly(self: LineString):
|
|
|
147
148
|
labels={"y": "y", "x": "z"},
|
|
148
149
|
)
|
|
149
150
|
|
|
150
|
-
fig.update_traces(line_color="black")
|
|
151
|
-
|
|
152
151
|
fig.update_yaxes(
|
|
153
152
|
scaleanchor="x",
|
|
154
153
|
scaleratio=1
|
|
@@ -157,6 +156,45 @@ def line_string_plot_plotly(self: LineString):
|
|
|
157
156
|
return fig
|
|
158
157
|
|
|
159
158
|
|
|
159
|
+
def multi_line_string_plot_matplotlib(self: MultiLineString):
|
|
160
|
+
import matplotlib.pyplot as plt
|
|
161
|
+
|
|
162
|
+
fig: plt.Figure = plt.figure()
|
|
163
|
+
ax: plt.Axes = fig.subplots()
|
|
164
|
+
|
|
165
|
+
ax.set_ylabel("y")
|
|
166
|
+
ax.set_xlabel("z")
|
|
167
|
+
|
|
168
|
+
ax.set_aspect("equal", "datalim")
|
|
169
|
+
ax.grid(lw=0.5)
|
|
170
|
+
|
|
171
|
+
for g in self.geoms:
|
|
172
|
+
ax.plot(*g.xy)
|
|
173
|
+
return fig
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def multi_line_string_plot_plotly(self: MultiLineString):
|
|
177
|
+
import plotly.graph_objects as pgo
|
|
178
|
+
|
|
179
|
+
fig = pgo.Figure()
|
|
180
|
+
|
|
181
|
+
for g in self.geoms:
|
|
182
|
+
fig.add_trace(pgo.Line(
|
|
183
|
+
x=np.array(g.xy[0]),
|
|
184
|
+
y=np.array(g.xy[1]),
|
|
185
|
+
))
|
|
186
|
+
|
|
187
|
+
fig.update_yaxes(
|
|
188
|
+
scaleanchor="x",
|
|
189
|
+
scaleratio=1,
|
|
190
|
+
title="y"
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
fig.update_xaxes(title="z")
|
|
194
|
+
|
|
195
|
+
return fig
|
|
196
|
+
|
|
197
|
+
|
|
160
198
|
for cls in [
|
|
161
199
|
LineString,
|
|
162
200
|
MultiLineString,
|
|
@@ -203,6 +241,11 @@ LineString._plot_matplotlib_ = line_string_plot_matplotlib
|
|
|
203
241
|
# noinspection PyProtectedMember
|
|
204
242
|
LineString._plot_plotly_ = line_string_plot_plotly
|
|
205
243
|
|
|
244
|
+
# noinspection PyProtectedMember
|
|
245
|
+
MultiLineString._plot_matplotlib_ = multi_line_string_plot_matplotlib
|
|
246
|
+
# noinspection PyProtectedMember
|
|
247
|
+
MultiLineString._plot_plotly_ = multi_line_string_plot_plotly
|
|
248
|
+
|
|
206
249
|
_RECTANGLE_CORNERS = np.asarray(
|
|
207
250
|
[
|
|
208
251
|
(-0.5, -0.5),
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/disk_elements/disk_element_unit.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/equivalent_ripped_groove.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/generic_elongation_solvers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/constricted_circular_oval.py
RENAMED
|
File without changes
|
{pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/constricted_swedish_oval.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/oval_3radii_flanked.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/base_roll_pass.py
RENAMED
|
File without changes
|
{pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/deformation_unit.py
RENAMED
|
File without changes
|
{pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/disk_element.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/symmetric_roll_pass.py
RENAMED
|
File without changes
|
{pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/three_roll_pass.py
RENAMED
|
File without changes
|
{pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/two_roll_pass.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyroll_core-3.0.0.post3 → pyroll_core-3.0.1}/pyroll/core/transport/hookimpls/cooling_pipe.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|