luminarycloud 0.20.0__py3-none-any.whl → 0.22.0__py3-none-any.whl
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.
- luminarycloud/__init__.py +5 -1
- luminarycloud/_client/client.py +5 -0
- luminarycloud/_client/http_client.py +10 -8
- luminarycloud/_feature_flag.py +22 -0
- luminarycloud/_helpers/_create_simulation.py +7 -2
- luminarycloud/_helpers/_upload_mesh.py +1 -0
- luminarycloud/_helpers/download.py +3 -1
- luminarycloud/_helpers/pagination.py +62 -0
- luminarycloud/_helpers/proto_decorator.py +13 -5
- luminarycloud/_helpers/upload.py +18 -12
- luminarycloud/_proto/api/v0/luminarycloud/feature_flag/feature_flag_pb2.py +55 -0
- luminarycloud/_proto/api/v0/luminarycloud/feature_flag/feature_flag_pb2.pyi +52 -0
- luminarycloud/_proto/api/v0/luminarycloud/feature_flag/feature_flag_pb2_grpc.py +72 -0
- luminarycloud/_proto/api/v0/luminarycloud/feature_flag/feature_flag_pb2_grpc.pyi +35 -0
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.py +168 -124
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.pyi +133 -4
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.py +66 -0
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.pyi +20 -0
- luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.py +8 -8
- luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.pyi +5 -5
- luminarycloud/_proto/api/v0/luminarycloud/mesh/mesh_pb2.py +74 -73
- luminarycloud/_proto/api/v0/luminarycloud/mesh/mesh_pb2.pyi +17 -3
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.py +33 -20
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.pyi +21 -1
- luminarycloud/_proto/api/v0/luminarycloud/project/project_pb2.py +16 -16
- luminarycloud/_proto/api/v0/luminarycloud/project/project_pb2.pyi +7 -3
- luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2.py +97 -61
- luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2.pyi +72 -3
- luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2_grpc.py +34 -0
- luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2_grpc.pyi +12 -0
- luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2.py +33 -31
- luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2.pyi +23 -2
- luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.py +68 -19
- luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.pyi +98 -0
- luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2_grpc.py +33 -0
- luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2_grpc.pyi +10 -0
- luminarycloud/_proto/assistant/assistant_pb2.py +74 -41
- luminarycloud/_proto/assistant/assistant_pb2.pyi +64 -2
- luminarycloud/_proto/assistant/assistant_pb2_grpc.py +33 -0
- luminarycloud/_proto/assistant/assistant_pb2_grpc.pyi +10 -0
- luminarycloud/_proto/base/base_pb2.py +20 -7
- luminarycloud/_proto/base/base_pb2.pyi +38 -0
- luminarycloud/_proto/cad/shape_pb2.py +39 -19
- luminarycloud/_proto/cad/shape_pb2.pyi +86 -34
- luminarycloud/_proto/cad/transformation_pb2.py +60 -16
- luminarycloud/_proto/cad/transformation_pb2.pyi +138 -32
- luminarycloud/_proto/client/simulation_pb2.py +490 -348
- luminarycloud/_proto/client/simulation_pb2.pyi +570 -8
- luminarycloud/_proto/geometry/geometry_pb2.py +77 -63
- luminarycloud/_proto/geometry/geometry_pb2.pyi +42 -3
- luminarycloud/_proto/hexmesh/hexmesh_pb2.py +24 -18
- luminarycloud/_proto/hexmesh/hexmesh_pb2.pyi +23 -2
- luminarycloud/_proto/inferenceservice/inferenceservice_pb2.py +10 -10
- luminarycloud/_proto/inferenceservice/inferenceservice_pb2.pyi +5 -5
- luminarycloud/_proto/quantity/quantity_options_pb2.py +6 -6
- luminarycloud/_proto/quantity/quantity_options_pb2.pyi +10 -1
- luminarycloud/_proto/quantity/quantity_pb2.py +176 -167
- luminarycloud/_proto/quantity/quantity_pb2.pyi +11 -5
- luminarycloud/enum/__init__.py +1 -0
- luminarycloud/enum/gpu_type.py +2 -0
- luminarycloud/enum/quantity_type.py +9 -0
- luminarycloud/enum/vis_enums.py +23 -3
- luminarycloud/feature_modification.py +45 -35
- luminarycloud/geometry.py +104 -8
- luminarycloud/geometry_version.py +57 -3
- luminarycloud/meshing/mesh_generation_params.py +8 -8
- luminarycloud/params/enum/_enum_wrappers.py +537 -30
- luminarycloud/params/simulation/adaptive_mesh_refinement_.py +4 -0
- luminarycloud/params/simulation/physics/__init__.py +0 -1
- luminarycloud/params/simulation/physics/periodic_pair_.py +12 -31
- luminarycloud/physics_ai/architectures.py +5 -5
- luminarycloud/physics_ai/inference.py +13 -13
- luminarycloud/physics_ai/solution.py +3 -1
- luminarycloud/pipelines/__init__.py +11 -3
- luminarycloud/pipelines/api.py +240 -4
- luminarycloud/pipelines/arguments.py +15 -0
- luminarycloud/pipelines/core.py +113 -96
- luminarycloud/pipelines/{operators.py → stages.py} +96 -39
- luminarycloud/project.py +15 -47
- luminarycloud/simulation.py +66 -3
- luminarycloud/simulation_param.py +0 -9
- luminarycloud/types/matrix3.py +12 -0
- luminarycloud/vis/__init__.py +2 -0
- luminarycloud/vis/interactive_report.py +79 -93
- luminarycloud/vis/report.py +219 -65
- luminarycloud/vis/visualization.py +60 -0
- luminarycloud/volume_selection.py +132 -69
- {luminarycloud-0.20.0.dist-info → luminarycloud-0.22.0.dist-info}/METADATA +1 -1
- {luminarycloud-0.20.0.dist-info → luminarycloud-0.22.0.dist-info}/RECORD +90 -89
- luminarycloud/params/simulation/physics/periodic_pair/__init__.py +0 -2
- luminarycloud/params/simulation/physics/periodic_pair/periodicity_type/__init__.py +0 -2
- luminarycloud/params/simulation/physics/periodic_pair/periodicity_type/rotational_periodicity_.py +0 -31
- luminarycloud/params/simulation/physics/periodic_pair/periodicity_type/translational_periodicity_.py +0 -29
- luminarycloud/params/simulation/physics/periodic_pair/periodicity_type_.py +0 -25
- {luminarycloud-0.20.0.dist-info → luminarycloud-0.22.0.dist-info}/WHEEL +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
@generated by mypy-protobuf. Do not edit manually!
|
|
3
3
|
isort:skip_file
|
|
4
|
-
Copyright
|
|
4
|
+
Copyright 2025 Luminary Cloud, Inc. All Rights Reserved.
|
|
5
5
|
Generated by quantities.py. DO NOT EDIT
|
|
6
6
|
"""
|
|
7
7
|
import builtins
|
|
@@ -34,15 +34,18 @@ class _QuantityTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._E
|
|
|
34
34
|
VOLUME: _QuantityType.ValueType # 30891
|
|
35
35
|
TIME: _QuantityType.ValueType # 20394
|
|
36
36
|
ENERGY: _QuantityType.ValueType # 30269
|
|
37
|
-
|
|
37
|
+
ENTHALPY: _QuantityType.ValueType # 15033
|
|
38
|
+
TOTAL_ENTHALPY: _QuantityType.ValueType # 55281
|
|
39
|
+
ISENTROPIC_ENTHALPY: _QuantityType.ValueType # 53299
|
|
40
|
+
ISENTROPIC_TOTAL_ENTHALPY: _QuantityType.ValueType # 39573
|
|
38
41
|
RADIANS: _QuantityType.ValueType # 61564
|
|
39
42
|
DEGREE: _QuantityType.ValueType # 42822
|
|
40
43
|
POWER: _QuantityType.ValueType # 64408
|
|
41
44
|
POWER_PER_UNIT_VOLUME: _QuantityType.ValueType # 51
|
|
42
45
|
THERMAL_EXPANSION_COEFFICIENT: _QuantityType.ValueType # 16951
|
|
43
46
|
TEMPERATURE: _QuantityType.ValueType # 3
|
|
44
|
-
DENSITY: _QuantityType.ValueType # 1
|
|
45
47
|
PRESSURE: _QuantityType.ValueType # 2
|
|
48
|
+
DENSITY: _QuantityType.ValueType # 1
|
|
46
49
|
VELOCITY: _QuantityType.ValueType # 5
|
|
47
50
|
VELOCITY_MAGNITUDE: _QuantityType.ValueType # 30
|
|
48
51
|
EDDY_VISCOSITY: _QuantityType.ValueType # 4
|
|
@@ -199,15 +202,18 @@ AREA: QuantityType.ValueType # 10
|
|
|
199
202
|
VOLUME: QuantityType.ValueType # 30891
|
|
200
203
|
TIME: QuantityType.ValueType # 20394
|
|
201
204
|
ENERGY: QuantityType.ValueType # 30269
|
|
202
|
-
|
|
205
|
+
ENTHALPY: QuantityType.ValueType # 15033
|
|
206
|
+
TOTAL_ENTHALPY: QuantityType.ValueType # 55281
|
|
207
|
+
ISENTROPIC_ENTHALPY: QuantityType.ValueType # 53299
|
|
208
|
+
ISENTROPIC_TOTAL_ENTHALPY: QuantityType.ValueType # 39573
|
|
203
209
|
RADIANS: QuantityType.ValueType # 61564
|
|
204
210
|
DEGREE: QuantityType.ValueType # 42822
|
|
205
211
|
POWER: QuantityType.ValueType # 64408
|
|
206
212
|
POWER_PER_UNIT_VOLUME: QuantityType.ValueType # 51
|
|
207
213
|
THERMAL_EXPANSION_COEFFICIENT: QuantityType.ValueType # 16951
|
|
208
214
|
TEMPERATURE: QuantityType.ValueType # 3
|
|
209
|
-
DENSITY: QuantityType.ValueType # 1
|
|
210
215
|
PRESSURE: QuantityType.ValueType # 2
|
|
216
|
+
DENSITY: QuantityType.ValueType # 1
|
|
211
217
|
VELOCITY: QuantityType.ValueType # 5
|
|
212
218
|
VELOCITY_MAGNITUDE: QuantityType.ValueType # 30
|
|
213
219
|
EDDY_VISCOSITY: QuantityType.ValueType # 4
|
luminarycloud/enum/__init__.py
CHANGED
luminarycloud/enum/gpu_type.py
CHANGED
|
@@ -10,3 +10,5 @@ class GPUType(IntEnum):
|
|
|
10
10
|
UNSPECIFIED = simulationpb.SimulationOptions.GPU_TYPE_UNSPECIFIED
|
|
11
11
|
V100 = simulationpb.SimulationOptions.GPU_TYPE_V100
|
|
12
12
|
A100 = simulationpb.SimulationOptions.GPU_TYPE_A100
|
|
13
|
+
T4 = simulationpb.SimulationOptions.GPU_TYPE_T4
|
|
14
|
+
H100 = simulationpb.SimulationOptions.GPU_TYPE_H100
|
|
@@ -60,6 +60,10 @@ class QuantityType(IntEnum):
|
|
|
60
60
|
TOTAL_MOMENT_COEFFICIENT
|
|
61
61
|
TOTAL_PRESSURE
|
|
62
62
|
TOTAL_TEMPERATURE
|
|
63
|
+
ENTHALPY
|
|
64
|
+
TOTAL_ENTHALPY
|
|
65
|
+
ISENTROPIC_ENTHALPY
|
|
66
|
+
ISENTROPIC_TOTAL_ENTHALPY
|
|
63
67
|
VELOCITY
|
|
64
68
|
VELOCITY_MAGNITUDE
|
|
65
69
|
VELOCITY_TIME_AVERAGE
|
|
@@ -116,6 +120,10 @@ class QuantityType(IntEnum):
|
|
|
116
120
|
TEMPERATURE = quantitypb.TEMPERATURE
|
|
117
121
|
TOTAL_PRESSURE = quantitypb.TOTAL_PRESSURE
|
|
118
122
|
TOTAL_TEMPERATURE = quantitypb.TOTAL_TEMPERATURE
|
|
123
|
+
ENTHALPY = quantitypb.ENTHALPY
|
|
124
|
+
TOTAL_ENTHALPY = quantitypb.TOTAL_ENTHALPY
|
|
125
|
+
ISENTROPIC_ENTHALPY = quantitypb.ISENTROPIC_ENTHALPY
|
|
126
|
+
ISENTROPIC_TOTAL_ENTHALPY = quantitypb.ISENTROPIC_TOTAL_ENTHALPY
|
|
119
127
|
VELOCITY = quantitypb.VELOCITY
|
|
120
128
|
VELOCITY_MAGNITUDE = quantitypb.VELOCITY_MAGNITUDE
|
|
121
129
|
Y_PLUS = quantitypb.Y_PLUS
|
|
@@ -173,6 +181,7 @@ class QuantityType(IntEnum):
|
|
|
173
181
|
SENSITIVITY = quantitypb.SENSITIVITY
|
|
174
182
|
NORMAL_SENSITIVITY = quantitypb.NORMAL_SENSITIVITY
|
|
175
183
|
SMOOTHED_NORMAL_SENSITIVITY = quantitypb.SMOOTHED_NORMAL_SENSITIVITY
|
|
184
|
+
ENTROPY = quantitypb.ENTROPY
|
|
176
185
|
|
|
177
186
|
# Quantities needed for table upload
|
|
178
187
|
LENGTH = quantitypb.LENGTH
|
luminarycloud/enum/vis_enums.py
CHANGED
|
@@ -15,11 +15,8 @@ class VisQuantity(IntEnum):
|
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
17
|
NONE = quantitypb.INVALID_QUANTITY_TYPE
|
|
18
|
-
ABSOLUTE_PRESSURE = quantitypb.ABSOLUTE_PRESSURE
|
|
19
18
|
PRESSURE = quantitypb.PRESSURE
|
|
20
|
-
DENSITY = quantitypb.DENSITY
|
|
21
19
|
TEMPERATURE = quantitypb.TEMPERATURE
|
|
22
|
-
MACH = quantitypb.MACH
|
|
23
20
|
Q_CRITERION = quantitypb.Q_CRITERION
|
|
24
21
|
VELOCITY = quantitypb.VELOCITY
|
|
25
22
|
WALL_SHEAR_STRESS = quantitypb.WALL_SHEAR_STRESS
|
|
@@ -39,6 +36,10 @@ class VisQuantity(IntEnum):
|
|
|
39
36
|
HEAT_TRANSFER_COEFFICIENT = quantitypb.HEAT_TRANSFER_COEFFICIENT
|
|
40
37
|
GRID_VELOCITY = quantitypb.GRID_VELOCITY
|
|
41
38
|
# Derived fields
|
|
39
|
+
ABSOLUTE_PRESSURE = quantitypb.ABSOLUTE_PRESSURE
|
|
40
|
+
MACH = quantitypb.MACH
|
|
41
|
+
DENSITY = quantitypb.DENSITY
|
|
42
|
+
ENTROPY = quantitypb.ENTROPY
|
|
42
43
|
RELATIVE_VELOCITY = quantitypb.RELATIVE_VELOCITY
|
|
43
44
|
RELATIVE_MACH = quantitypb.RELATIVE_MACH
|
|
44
45
|
PRESSURE_COEFFICIENT = quantitypb.PRESSURE_COEFFICIENT
|
|
@@ -71,6 +72,7 @@ class VisQuantity(IntEnum):
|
|
|
71
72
|
MASS_FLUX_TIME_AVERAGE = quantitypb.MASS_FLUX_TIME_AVERAGE
|
|
72
73
|
Q_CRITERION_TIME_AVERAGE = quantitypb.Q_CRITERION_TIME_AVERAGE
|
|
73
74
|
HEAT_FLUX_TIME_AVERAGE = quantitypb.HEAT_FLUX_TIME_AVERAGE
|
|
75
|
+
DEBUG_QUANTITY = quantitypb.DEBUG_QUANTITY
|
|
74
76
|
|
|
75
77
|
|
|
76
78
|
# Return the text name for the VisQuantity including the units, as it appears in the UI
|
|
@@ -306,3 +308,21 @@ class SceneMode(str, Enum):
|
|
|
306
308
|
INLINE = "inline"
|
|
307
309
|
SIDE_PANEL = "side_panel"
|
|
308
310
|
FULLSCREEN = "fullscreen"
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
class FieldAssociation(IntEnum):
|
|
314
|
+
"""
|
|
315
|
+
An enum to specifiy the association of a field used in the range query.
|
|
316
|
+
|
|
317
|
+
.. warning:: This feature is experimental and may change or be removed in the future.
|
|
318
|
+
|
|
319
|
+
Attributes
|
|
320
|
+
----------
|
|
321
|
+
POINTS
|
|
322
|
+
Field values are associated with the points of the mesh.
|
|
323
|
+
CELLS
|
|
324
|
+
Field values are associated with the cells of the mesh.
|
|
325
|
+
"""
|
|
326
|
+
|
|
327
|
+
POINTS = 0
|
|
328
|
+
CELLS = 1
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Copyright 2025 Luminary Cloud, Inc. All Rights Reserved.
|
|
2
2
|
from enum import Enum, auto
|
|
3
|
-
from typing import Dict, Iterable, List, Optional
|
|
3
|
+
from typing import Dict, Iterable, List, Optional
|
|
4
4
|
from copy import deepcopy
|
|
5
5
|
|
|
6
|
-
from luminarycloud.types.adfloat import _to_ad_proto
|
|
6
|
+
from luminarycloud.types.adfloat import _to_ad_proto
|
|
7
7
|
from ._proto.geometry import geometry_pb2 as gpb
|
|
8
8
|
from .types import Vector3Like
|
|
9
|
-
from .types.vector3 import
|
|
9
|
+
from .types.vector3 import _to_vector3_ad_proto
|
|
10
10
|
from .params.geometry import Shape, Sphere, Cube, Cylinder, Torus, Cone, HalfSphere, Volume
|
|
11
11
|
from google.protobuf.internal.containers import RepeatedScalarFieldContainer
|
|
12
12
|
|
|
@@ -265,6 +265,7 @@ def modify_delete(
|
|
|
265
265
|
def modify_union(
|
|
266
266
|
feature: gpb.Feature,
|
|
267
267
|
volumes: Optional[List[Volume | int]] = None,
|
|
268
|
+
keep: Optional[bool] = None,
|
|
268
269
|
) -> gpb.Modification:
|
|
269
270
|
"""
|
|
270
271
|
Modify a boolean union feature with optional new body IDs.
|
|
@@ -273,6 +274,7 @@ def modify_union(
|
|
|
273
274
|
Args:
|
|
274
275
|
feature: A gpb.Feature object
|
|
275
276
|
volumes: List of volumes or volume IDs to union
|
|
277
|
+
keep: Whether to keep the original bodies
|
|
276
278
|
|
|
277
279
|
Returns:
|
|
278
280
|
A gpb.Modification object
|
|
@@ -287,6 +289,9 @@ def modify_union(
|
|
|
287
289
|
vol_ids = _volumes_to_int_list(volumes)
|
|
288
290
|
_update_repeated_field(boolean_op.reg_union.bodies, vol_ids)
|
|
289
291
|
|
|
292
|
+
if keep is not None:
|
|
293
|
+
boolean_op.reg_union.keep_source_bodies = keep
|
|
294
|
+
|
|
290
295
|
return gpb.Modification(
|
|
291
296
|
mod_type=gpb.Modification.ModificationType.MODIFICATION_TYPE_UPDATE_FEATURE,
|
|
292
297
|
feature=feature_copy,
|
|
@@ -297,6 +302,8 @@ def modify_subtraction(
|
|
|
297
302
|
feature: gpb.Feature,
|
|
298
303
|
volumes: Optional[List[Volume | int]] = None,
|
|
299
304
|
tool_volumes: Optional[List[Volume | int]] = None,
|
|
305
|
+
keep_source_bodies: Optional[bool] = None,
|
|
306
|
+
keep_tool_bodies: Optional[bool] = None,
|
|
300
307
|
propagate_tool_tags: Optional[bool] = None,
|
|
301
308
|
) -> gpb.Modification:
|
|
302
309
|
"""
|
|
@@ -307,6 +314,8 @@ def modify_subtraction(
|
|
|
307
314
|
feature: A gpb.Feature object
|
|
308
315
|
volumes: List of volumes or volume IDs to subtract from
|
|
309
316
|
tool_volumes: List of volumes or volume IDs to use for subtraction
|
|
317
|
+
keep_source_bodies: Whether to keep the original bodies
|
|
318
|
+
keep_tool_bodies: Whether to keep the tool bodies
|
|
310
319
|
propagate_tool_tags: Whether to propagate tool tags
|
|
311
320
|
|
|
312
321
|
Returns:
|
|
@@ -325,6 +334,12 @@ def modify_subtraction(
|
|
|
325
334
|
tool_ids = _volumes_to_int_list(tool_volumes)
|
|
326
335
|
_update_repeated_field(boolean_op.reg_subtraction.tools, tool_ids)
|
|
327
336
|
|
|
337
|
+
if keep_source_bodies is not None:
|
|
338
|
+
boolean_op.reg_subtraction.keep_source_bodies = keep_source_bodies
|
|
339
|
+
|
|
340
|
+
if keep_tool_bodies is not None:
|
|
341
|
+
boolean_op.reg_subtraction.keep_tool_bodies = keep_tool_bodies
|
|
342
|
+
|
|
328
343
|
if propagate_tool_tags is not None:
|
|
329
344
|
boolean_op.reg_subtraction.propagate_tool_tags = propagate_tool_tags
|
|
330
345
|
|
|
@@ -335,7 +350,9 @@ def modify_subtraction(
|
|
|
335
350
|
|
|
336
351
|
|
|
337
352
|
def modify_intersection(
|
|
338
|
-
feature: gpb.Feature,
|
|
353
|
+
feature: gpb.Feature,
|
|
354
|
+
volumes: Optional[List[Volume | int]] = None,
|
|
355
|
+
keep: Optional[bool] = None,
|
|
339
356
|
) -> gpb.Modification:
|
|
340
357
|
"""
|
|
341
358
|
Modify a boolean intersection feature with optional new volumes.
|
|
@@ -344,6 +361,7 @@ def modify_intersection(
|
|
|
344
361
|
Args:
|
|
345
362
|
feature: A gpb.Feature object
|
|
346
363
|
volumes: List of volumes or volume IDs to intersect
|
|
364
|
+
keep: Whether to keep the original bodies
|
|
347
365
|
|
|
348
366
|
Returns:
|
|
349
367
|
A gpb.Modification object
|
|
@@ -358,6 +376,9 @@ def modify_intersection(
|
|
|
358
376
|
vol_ids = _volumes_to_int_list(volumes)
|
|
359
377
|
_update_repeated_field(boolean_op.reg_intersection.bodies, vol_ids)
|
|
360
378
|
|
|
379
|
+
if keep is not None:
|
|
380
|
+
boolean_op.reg_intersection.keep_source_bodies = keep
|
|
381
|
+
|
|
361
382
|
return gpb.Modification(
|
|
362
383
|
mod_type=gpb.Modification.ModificationType.MODIFICATION_TYPE_UPDATE_FEATURE,
|
|
363
384
|
feature=feature_copy,
|
|
@@ -368,6 +389,8 @@ def modify_chop(
|
|
|
368
389
|
feature: gpb.Feature,
|
|
369
390
|
volumes: Optional[List[Volume | int]] = None,
|
|
370
391
|
tool_volumes: Optional[List[Volume | int]] = None,
|
|
392
|
+
keep_source_bodies: Optional[bool] = None,
|
|
393
|
+
keep_tool_bodies: Optional[bool] = None,
|
|
371
394
|
propagate_tool_tags: Optional[bool] = None,
|
|
372
395
|
) -> gpb.Modification:
|
|
373
396
|
"""
|
|
@@ -378,6 +401,8 @@ def modify_chop(
|
|
|
378
401
|
feature: A gpb.Feature object
|
|
379
402
|
volumes: List of volumes or volume IDs to chop
|
|
380
403
|
tool_volumes: List of volumes or volume IDs to use for chopping
|
|
404
|
+
keep_source_bodies: Whether to keep the original bodies
|
|
405
|
+
keep_tool_bodies: Whether to keep the tool bodies
|
|
381
406
|
propagate_tool_tags: Whether to propagate tool tags
|
|
382
407
|
|
|
383
408
|
Returns:
|
|
@@ -397,6 +422,12 @@ def modify_chop(
|
|
|
397
422
|
tool_ids = _volumes_to_int_list(tool_volumes)
|
|
398
423
|
_update_repeated_field(boolean_op.reg_chop.tools, tool_ids)
|
|
399
424
|
|
|
425
|
+
if keep_source_bodies is not None:
|
|
426
|
+
boolean_op.reg_chop.keep_source_bodies = keep_source_bodies
|
|
427
|
+
|
|
428
|
+
if keep_tool_bodies is not None:
|
|
429
|
+
boolean_op.reg_chop.keep_tool_bodies = keep_tool_bodies
|
|
430
|
+
|
|
400
431
|
if propagate_tool_tags is not None:
|
|
401
432
|
boolean_op.reg_chop.propagate_tool_tags = propagate_tool_tags
|
|
402
433
|
|
|
@@ -483,10 +514,7 @@ def modify_translate(
|
|
|
483
514
|
_update_repeated_field(transform_op.body, vol_ids)
|
|
484
515
|
|
|
485
516
|
if displacement is not None:
|
|
486
|
-
|
|
487
|
-
transform_op.translation.vector.x = vec.x
|
|
488
|
-
transform_op.translation.vector.y = vec.y
|
|
489
|
-
transform_op.translation.vector.z = vec.z
|
|
517
|
+
transform_op.translation.vector.CopyFrom(_to_vector3_ad_proto(displacement))
|
|
490
518
|
|
|
491
519
|
if keep is not None:
|
|
492
520
|
transform_op.keep = keep
|
|
@@ -532,19 +560,13 @@ def modify_rotate(
|
|
|
532
560
|
|
|
533
561
|
# Update existing rotation
|
|
534
562
|
if angle is not None:
|
|
535
|
-
transform_op.rotation.angle
|
|
563
|
+
transform_op.rotation.angle.CopyFrom(_to_ad_proto(angle))
|
|
536
564
|
|
|
537
565
|
if axis is not None:
|
|
538
|
-
|
|
539
|
-
transform_op.rotation.arbitrary.direction.x = axis_vec.x
|
|
540
|
-
transform_op.rotation.arbitrary.direction.y = axis_vec.y
|
|
541
|
-
transform_op.rotation.arbitrary.direction.z = axis_vec.z
|
|
566
|
+
transform_op.rotation.arbitrary.direction.CopyFrom(_to_vector3_ad_proto(axis))
|
|
542
567
|
|
|
543
568
|
if origin is not None:
|
|
544
|
-
|
|
545
|
-
transform_op.rotation.arbitrary.origin.x = origin_vec.x
|
|
546
|
-
transform_op.rotation.arbitrary.origin.y = origin_vec.y
|
|
547
|
-
transform_op.rotation.arbitrary.origin.z = origin_vec.z
|
|
569
|
+
transform_op.rotation.arbitrary.origin.CopyFrom(_to_vector3_ad_proto(origin))
|
|
548
570
|
|
|
549
571
|
if keep is not None:
|
|
550
572
|
transform_op.keep = keep
|
|
@@ -587,13 +609,10 @@ def modify_scale(
|
|
|
587
609
|
_update_repeated_field(transform_op.body, vol_ids)
|
|
588
610
|
|
|
589
611
|
if scale_factor is not None:
|
|
590
|
-
transform_op.scaling.isotropic
|
|
612
|
+
transform_op.scaling.isotropic.CopyFrom(_to_ad_proto(scale_factor))
|
|
591
613
|
|
|
592
614
|
if origin is not None:
|
|
593
|
-
|
|
594
|
-
transform_op.scaling.arbitrary.x = origin_vec.x
|
|
595
|
-
transform_op.scaling.arbitrary.y = origin_vec.y
|
|
596
|
-
transform_op.scaling.arbitrary.z = origin_vec.z
|
|
615
|
+
transform_op.scaling.arbitrary.CopyFrom(_to_vector3_ad_proto(origin))
|
|
597
616
|
|
|
598
617
|
if keep is not None:
|
|
599
618
|
transform_op.keep = keep
|
|
@@ -769,10 +788,7 @@ def modify_linear_pattern(
|
|
|
769
788
|
|
|
770
789
|
if direction is not None:
|
|
771
790
|
# Update existing linear pattern direction
|
|
772
|
-
|
|
773
|
-
pattern_op.direction.linear_spacing.vector.x = dir_vec.x
|
|
774
|
-
pattern_op.direction.linear_spacing.vector.y = dir_vec.y
|
|
775
|
-
pattern_op.direction.linear_spacing.vector.z = dir_vec.z
|
|
791
|
+
pattern_op.direction.linear_spacing.vector.CopyFrom(_to_vector3_ad_proto(direction))
|
|
776
792
|
|
|
777
793
|
if quantity is not None:
|
|
778
794
|
pattern_op.direction.quantity = quantity
|
|
@@ -832,19 +848,13 @@ def modify_circular_pattern(
|
|
|
832
848
|
circular = pattern_op.direction.circular_distribution
|
|
833
849
|
|
|
834
850
|
if angle is not None:
|
|
835
|
-
circular.rotation.angle
|
|
851
|
+
circular.rotation.angle.CopyFrom(_to_ad_proto(angle))
|
|
836
852
|
|
|
837
853
|
if axis is not None:
|
|
838
|
-
|
|
839
|
-
circular.rotation.arbitrary.direction.x = axis_vec.x
|
|
840
|
-
circular.rotation.arbitrary.direction.y = axis_vec.y
|
|
841
|
-
circular.rotation.arbitrary.direction.z = axis_vec.z
|
|
854
|
+
circular.rotation.arbitrary.direction.CopyFrom(_to_vector3_ad_proto(axis))
|
|
842
855
|
|
|
843
856
|
if origin is not None:
|
|
844
|
-
|
|
845
|
-
circular.rotation.arbitrary.origin.x = origin_vec.x
|
|
846
|
-
circular.rotation.arbitrary.origin.y = origin_vec.y
|
|
847
|
-
circular.rotation.arbitrary.origin.z = origin_vec.z
|
|
857
|
+
circular.rotation.arbitrary.origin.CopyFrom(_to_vector3_ad_proto(origin))
|
|
848
858
|
|
|
849
859
|
if full_rotation is not None:
|
|
850
860
|
circular.full = full_rotation
|
luminarycloud/geometry.py
CHANGED
|
@@ -29,7 +29,7 @@ from .named_variable_set import NamedVariableSet, get_named_variable_set
|
|
|
29
29
|
|
|
30
30
|
if TYPE_CHECKING:
|
|
31
31
|
from .project import Project
|
|
32
|
-
from .geometry_version import GeometryVersion
|
|
32
|
+
from .geometry_version import GeometryVersion, GeometryVersionIterator
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
@ProtoWrapper(geometrypb.Geometry)
|
|
@@ -84,6 +84,18 @@ class Geometry(ProtoWrapperBase):
|
|
|
84
84
|
res = get_default_client().UpdateGeometry(req)
|
|
85
85
|
self._proto = res.geometry
|
|
86
86
|
|
|
87
|
+
def delete(self) -> None:
|
|
88
|
+
"""
|
|
89
|
+
Delete the geometry.
|
|
90
|
+
|
|
91
|
+
This operation cannot be reverted and all the geometry data will be deleted as part of
|
|
92
|
+
this request.
|
|
93
|
+
"""
|
|
94
|
+
req = geometrypb.DeleteGeometryRequest(
|
|
95
|
+
geometry_id=self.id,
|
|
96
|
+
)
|
|
97
|
+
get_default_client().DeleteGeometry(req)
|
|
98
|
+
|
|
87
99
|
def copy(self, name: str = "") -> "Geometry":
|
|
88
100
|
"""
|
|
89
101
|
Copy the geometry.
|
|
@@ -292,6 +304,46 @@ class Geometry(ProtoWrapperBase):
|
|
|
292
304
|
)
|
|
293
305
|
)
|
|
294
306
|
|
|
307
|
+
def versions(self, unfiltered: bool = False, page_size: int = 50) -> "GeometryVersionIterator":
|
|
308
|
+
"""
|
|
309
|
+
List the geometry versions for this geometry in chronological order, oldest first.
|
|
310
|
+
|
|
311
|
+
By default, this only returns versions that are named OR have an associated Mesh OR are the
|
|
312
|
+
latest version of the geometry. If `unfiltered` is true, this returns all versions.
|
|
313
|
+
|
|
314
|
+
The geometry versions are fetched lazily in batches using pagination to optimize memory
|
|
315
|
+
usage and API calls.
|
|
316
|
+
|
|
317
|
+
Parameters
|
|
318
|
+
----------
|
|
319
|
+
unfiltered : bool, optional
|
|
320
|
+
If True, returns all versions. If False, returns only versions that are named OR have an
|
|
321
|
+
associated Mesh OR are the latest version of the geometry. Defaults to False.
|
|
322
|
+
page_size : int, optional
|
|
323
|
+
Number of geometry versions to fetch per page. Defaults to 50, max is 500.
|
|
324
|
+
|
|
325
|
+
Returns
|
|
326
|
+
-------
|
|
327
|
+
GeometryVersionIterator
|
|
328
|
+
An iterator that yields GeometryVersion objects one at a time.
|
|
329
|
+
|
|
330
|
+
Examples
|
|
331
|
+
--------
|
|
332
|
+
Fetch the versions of this geometry with default filtering applied.
|
|
333
|
+
>>> for version in geometry.versions():
|
|
334
|
+
... print(version.id, version.name)
|
|
335
|
+
|
|
336
|
+
Fetch all versions of the geometry.
|
|
337
|
+
>>> for version in geometry.versions(unfiltered=True):
|
|
338
|
+
... print(version.id, version.name)
|
|
339
|
+
|
|
340
|
+
Build a list of versions of this geometry that have the name "So Important".
|
|
341
|
+
>>> important_versions = [ver for ver in geometry.versions() if ver.name == "So Important"]
|
|
342
|
+
"""
|
|
343
|
+
from .geometry_version import GeometryVersionIterator
|
|
344
|
+
|
|
345
|
+
return GeometryVersionIterator(self.id, unfiltered, page_size)
|
|
346
|
+
|
|
295
347
|
def latest_version(self) -> GeometryVersion:
|
|
296
348
|
"""
|
|
297
349
|
Get the latest version of the geometry.
|
|
@@ -346,7 +398,7 @@ class Geometry(ProtoWrapperBase):
|
|
|
346
398
|
jitter = random.uniform(0.5, 1.5)
|
|
347
399
|
time.sleep(2 + jitter)
|
|
348
400
|
|
|
349
|
-
def create_tag(self, name: str, entities: Sequence[Volume | Surface]) ->
|
|
401
|
+
def create_tag(self, name: str, entities: Sequence[Volume | Surface]) -> Tag:
|
|
350
402
|
"""
|
|
351
403
|
Create a tag in the geometry.
|
|
352
404
|
|
|
@@ -356,6 +408,11 @@ class Geometry(ProtoWrapperBase):
|
|
|
356
408
|
The name of the tag to create.
|
|
357
409
|
entities : list of Volumes or Surfaces
|
|
358
410
|
The Volumes and Surfaces to tag.
|
|
411
|
+
|
|
412
|
+
Returns
|
|
413
|
+
-------
|
|
414
|
+
Tag
|
|
415
|
+
The tag that was created.
|
|
359
416
|
"""
|
|
360
417
|
volume_ids = []
|
|
361
418
|
surface_ids = []
|
|
@@ -367,8 +424,7 @@ class Geometry(ProtoWrapperBase):
|
|
|
367
424
|
else:
|
|
368
425
|
raise TypeError("entities must be of type Volume or Surface")
|
|
369
426
|
|
|
370
|
-
|
|
371
|
-
geometry_id=self.id,
|
|
427
|
+
self._modify(
|
|
372
428
|
modification=gpb.Modification(
|
|
373
429
|
mod_type=gpb.Modification.MODIFICATION_TYPE_CREATE_TAG,
|
|
374
430
|
create_or_update_tag=gpb.CreateOrUpdateTag(
|
|
@@ -378,9 +434,9 @@ class Geometry(ProtoWrapperBase):
|
|
|
378
434
|
),
|
|
379
435
|
),
|
|
380
436
|
)
|
|
381
|
-
|
|
437
|
+
return self._get_tag_by_name(name)
|
|
382
438
|
|
|
383
|
-
def rename_tag(self, old_name: str, new_name: str) ->
|
|
439
|
+
def rename_tag(self, old_name: str, new_name: str) -> Tag:
|
|
384
440
|
"""
|
|
385
441
|
Rename a tag in the geometry.
|
|
386
442
|
|
|
@@ -390,6 +446,11 @@ class Geometry(ProtoWrapperBase):
|
|
|
390
446
|
The name of the tag to rename.
|
|
391
447
|
new_name : str
|
|
392
448
|
The new name for the tag.
|
|
449
|
+
|
|
450
|
+
Returns
|
|
451
|
+
-------
|
|
452
|
+
Tag
|
|
453
|
+
The updated tag.
|
|
393
454
|
"""
|
|
394
455
|
self._modify(
|
|
395
456
|
modification=gpb.Modification(
|
|
@@ -400,8 +461,9 @@ class Geometry(ProtoWrapperBase):
|
|
|
400
461
|
),
|
|
401
462
|
),
|
|
402
463
|
)
|
|
464
|
+
return self._get_tag_by_name(new_name)
|
|
403
465
|
|
|
404
|
-
def untag_entities(self, name: str, entities: Sequence[Volume | Surface]) -> None:
|
|
466
|
+
def untag_entities(self, name: str, entities: Sequence[Volume | Surface]) -> Tag | None:
|
|
405
467
|
"""
|
|
406
468
|
Untag entities from a tag in the geometry.
|
|
407
469
|
|
|
@@ -412,6 +474,11 @@ class Geometry(ProtoWrapperBase):
|
|
|
412
474
|
entities : list of Volumes or Surfaces
|
|
413
475
|
The Volumes and Surfaces to untag. If empty, all entities with the
|
|
414
476
|
tag will be untagged.
|
|
477
|
+
|
|
478
|
+
Returns
|
|
479
|
+
-------
|
|
480
|
+
Tag
|
|
481
|
+
The updated tag.
|
|
415
482
|
"""
|
|
416
483
|
volume_ids = []
|
|
417
484
|
surface_ids = []
|
|
@@ -433,8 +500,12 @@ class Geometry(ProtoWrapperBase):
|
|
|
433
500
|
),
|
|
434
501
|
),
|
|
435
502
|
)
|
|
503
|
+
try:
|
|
504
|
+
return self._get_tag_by_name(name)
|
|
505
|
+
except ValueError:
|
|
506
|
+
return None
|
|
436
507
|
|
|
437
|
-
def update_tag(self, name: str, entities: Sequence[Volume | Surface]) ->
|
|
508
|
+
def update_tag(self, name: str, entities: Sequence[Volume | Surface]) -> Tag:
|
|
438
509
|
"""
|
|
439
510
|
Adds entities to a tag in the geometry.
|
|
440
511
|
|
|
@@ -443,6 +514,11 @@ class Geometry(ProtoWrapperBase):
|
|
|
443
514
|
name : str
|
|
444
515
|
The name of the tag to update.
|
|
445
516
|
entities : list of Volumes or Surfaces
|
|
517
|
+
|
|
518
|
+
Returns
|
|
519
|
+
-------
|
|
520
|
+
Tag
|
|
521
|
+
The updated tag.
|
|
446
522
|
"""
|
|
447
523
|
volume_ids = []
|
|
448
524
|
surface_ids = []
|
|
@@ -464,6 +540,7 @@ class Geometry(ProtoWrapperBase):
|
|
|
464
540
|
),
|
|
465
541
|
),
|
|
466
542
|
)
|
|
543
|
+
return self._get_tag_by_name(name)
|
|
467
544
|
|
|
468
545
|
def list_tags(self) -> list[Tag]:
|
|
469
546
|
"""
|
|
@@ -479,6 +556,25 @@ class Geometry(ProtoWrapperBase):
|
|
|
479
556
|
res: geometrypb.ListTagsResponse = get_default_client().ListTags(req)
|
|
480
557
|
return [Tag(t) for t in res.tags]
|
|
481
558
|
|
|
559
|
+
def _get_tag_by_name(self, name: str) -> Tag:
|
|
560
|
+
"""
|
|
561
|
+
Get a specific tag from the geometry.
|
|
562
|
+
|
|
563
|
+
Parameters
|
|
564
|
+
----------
|
|
565
|
+
name : str
|
|
566
|
+
The name of the tag.
|
|
567
|
+
|
|
568
|
+
Returns
|
|
569
|
+
-------
|
|
570
|
+
Tag
|
|
571
|
+
The tag with the specified name.
|
|
572
|
+
"""
|
|
573
|
+
try:
|
|
574
|
+
return next(filter(lambda t: t.name == name, self.list_tags()))
|
|
575
|
+
except StopIteration:
|
|
576
|
+
raise ValueError(f"Tag '{name}' not found in geometry {self.id}")
|
|
577
|
+
|
|
482
578
|
def list_entities(self) -> tuple[list[Surface], list[Volume]]:
|
|
483
579
|
"""
|
|
484
580
|
List all the entities in the geometry.
|
|
@@ -3,6 +3,7 @@ from datetime import datetime
|
|
|
3
3
|
|
|
4
4
|
from ._client import get_default_client
|
|
5
5
|
from ._helpers._timestamp_to_datetime import timestamp_to_datetime
|
|
6
|
+
from ._helpers.pagination import PaginationIterator
|
|
6
7
|
from ._proto.api.v0.luminarycloud.geometry import geometry_pb2 as geometrypb
|
|
7
8
|
from ._proto.geometry import geometry_pb2 as gpb
|
|
8
9
|
from ._wrapper import ProtoWrapper, ProtoWrapperBase
|
|
@@ -87,7 +88,7 @@ class GeometryVersion(ProtoWrapperBase):
|
|
|
87
88
|
]
|
|
88
89
|
return surfaces, volumes
|
|
89
90
|
|
|
90
|
-
def copy_to_new_geometry(self, name: str = "") -> Geometry:
|
|
91
|
+
def copy_to_new_geometry(self, name: str = "", request_id: str = "") -> Geometry:
|
|
91
92
|
"""
|
|
92
93
|
Copy this GeometryVersion and create a new Geometry containing only that newly copied version.
|
|
93
94
|
|
|
@@ -95,6 +96,11 @@ class GeometryVersion(ProtoWrapperBase):
|
|
|
95
96
|
----------
|
|
96
97
|
name : str, optional
|
|
97
98
|
The name of the new Geometry. If not provided, a default name will be used.
|
|
99
|
+
request_id : str, optional
|
|
100
|
+
A deduplication key, useful for idempotency. The first time copy_to_new_geometry() is
|
|
101
|
+
called with a given request_id, a new geometry will be created. Subsequent calls with
|
|
102
|
+
the same request_id will return the same geometry. If not provided, no deduplication is
|
|
103
|
+
done. Max length: 256 characters.
|
|
98
104
|
|
|
99
105
|
Returns
|
|
100
106
|
-------
|
|
@@ -104,6 +110,7 @@ class GeometryVersion(ProtoWrapperBase):
|
|
|
104
110
|
req = geometrypb.CopyGeometryFromVersionRequest(
|
|
105
111
|
geometry_version_id=self.id,
|
|
106
112
|
name=name,
|
|
113
|
+
request_id=request_id,
|
|
107
114
|
)
|
|
108
115
|
res: geometrypb.CopyGeometryFromVersionResponse = (
|
|
109
116
|
get_default_client().CopyGeometryFromVersion(req)
|
|
@@ -173,14 +180,39 @@ class GeometryVersion(ProtoWrapperBase):
|
|
|
173
180
|
return res.sdk_code
|
|
174
181
|
|
|
175
182
|
|
|
183
|
+
class GeometryVersionIterator(PaginationIterator[GeometryVersion]):
|
|
184
|
+
"""Iterator class for geometry versions that provides length hint."""
|
|
185
|
+
|
|
186
|
+
def __init__(self, geometry_id: str, unfiltered: bool, page_size: int):
|
|
187
|
+
super().__init__(page_size)
|
|
188
|
+
self._geometry_id: str = geometry_id
|
|
189
|
+
self._unfiltered: bool = unfiltered
|
|
190
|
+
|
|
191
|
+
def _fetch_page(
|
|
192
|
+
self, page_size: int, page_token: str
|
|
193
|
+
) -> tuple[list[GeometryVersion], str, int]:
|
|
194
|
+
req = geometrypb.ListGeometryVersionsRequest(
|
|
195
|
+
page_size=page_size,
|
|
196
|
+
page_token=page_token,
|
|
197
|
+
geometry_id=self._geometry_id,
|
|
198
|
+
unfiltered=self._unfiltered,
|
|
199
|
+
)
|
|
200
|
+
res = self._client.ListGeometryVersions(req)
|
|
201
|
+
return (
|
|
202
|
+
[GeometryVersion(gv) for gv in res.geometry_versions],
|
|
203
|
+
res.next_page_token,
|
|
204
|
+
res.total_count,
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
|
|
176
208
|
def get_geometry_version(id: str) -> GeometryVersion:
|
|
177
209
|
"""
|
|
178
|
-
Get a
|
|
210
|
+
Get a geometry version by its ID.
|
|
179
211
|
|
|
180
212
|
Parameters
|
|
181
213
|
----------
|
|
182
214
|
id : str
|
|
183
|
-
|
|
215
|
+
ID of the geometry version to get.
|
|
184
216
|
|
|
185
217
|
Returns
|
|
186
218
|
-------
|
|
@@ -191,3 +223,25 @@ def get_geometry_version(id: str) -> GeometryVersion:
|
|
|
191
223
|
req = geometrypb.GetGeometryVersionRequest(geometry_version_id=id)
|
|
192
224
|
res: geometrypb.GetGeometryVersionResponse = get_default_client().GetGeometryVersion(req)
|
|
193
225
|
return GeometryVersion(res.geometry_version)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def update_geometry_version(id: str, name: str) -> GeometryVersion:
|
|
229
|
+
"""
|
|
230
|
+
Update a geometry version.
|
|
231
|
+
|
|
232
|
+
Parameters
|
|
233
|
+
----------
|
|
234
|
+
id : str
|
|
235
|
+
ID of the geometry version to update.
|
|
236
|
+
name : str
|
|
237
|
+
The new name for the geometry version. Pass an empty string to clear the name.
|
|
238
|
+
|
|
239
|
+
Returns
|
|
240
|
+
-------
|
|
241
|
+
GeometryVersion
|
|
242
|
+
The updated GeometryVersion.
|
|
243
|
+
"""
|
|
244
|
+
|
|
245
|
+
req = geometrypb.UpdateGeometryVersionRequest(geometry_version_id=id, name=name)
|
|
246
|
+
res: geometrypb.UpdateGeometryVersionResponse = get_default_client().UpdateGeometryVersion(req)
|
|
247
|
+
return GeometryVersion(res.geometry_version)
|