luminarycloud 0.15.5__py3-none-any.whl → 0.16.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/_helpers/__init__.py +1 -0
- luminarycloud/_helpers/_code_representation.py +18 -3
- luminarycloud/_helpers/download.py +67 -1
- luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.py +9 -9
- luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.pyi +7 -4
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.py +45 -21
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.pyi +65 -0
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2_grpc.py +34 -0
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2_grpc.pyi +12 -0
- luminarycloud/_proto/api/v0/luminarycloud/thirdpartyintegration/onshape/onshape_pb2.py +194 -7
- luminarycloud/_proto/api/v0/luminarycloud/thirdpartyintegration/onshape/onshape_pb2.pyi +403 -1
- luminarycloud/_proto/api/v0/luminarycloud/thirdpartyintegration/onshape/onshape_pb2_grpc.py +171 -0
- luminarycloud/_proto/api/v0/luminarycloud/thirdpartyintegration/onshape/onshape_pb2_grpc.pyi +64 -0
- luminarycloud/_proto/api/v0/luminarycloud/upload/upload_pb2.py +4 -2
- luminarycloud/_proto/api/v0/luminarycloud/upload/upload_pb2_grpc.py +34 -0
- luminarycloud/_proto/api/v0/luminarycloud/upload/upload_pb2_grpc.pyi +12 -0
- luminarycloud/_proto/assistant/assistant_pb2.py +82 -61
- luminarycloud/_proto/assistant/assistant_pb2.pyi +40 -0
- luminarycloud/_proto/assistant/assistant_pb2_grpc.py +34 -0
- luminarycloud/_proto/assistant/assistant_pb2_grpc.pyi +12 -0
- luminarycloud/_proto/base/base_pb2.py +7 -6
- luminarycloud/_proto/base/base_pb2.pyi +4 -0
- luminarycloud/_proto/client/simulation_pb2.py +188 -186
- luminarycloud/_proto/client/simulation_pb2.pyi +10 -2
- luminarycloud/_proto/geometry/geometry_pb2.py +62 -62
- luminarycloud/_proto/geometry/geometry_pb2.pyi +5 -1
- luminarycloud/_proto/inferenceservice/inferenceservice_pb2.py +11 -11
- luminarycloud/_proto/inferenceservice/inferenceservice_pb2.pyi +12 -4
- luminarycloud/_proto/quantity/quantity_pb2.py +11 -2
- luminarycloud/_proto/quantity/quantity_pb2.pyi +6 -0
- luminarycloud/_proto/table/table_pb2.pyi +4 -2
- luminarycloud/_proto/upload/upload_pb2.py +27 -7
- luminarycloud/_proto/upload/upload_pb2.pyi +31 -0
- luminarycloud/enum/quantity_type.py +15 -0
- luminarycloud/mesh.py +8 -1
- luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation/robust_startup/__init__.py +1 -0
- luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation/robust_startup/robust_startup_auto_.py +30 -0
- luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation/robust_startup/robust_startup_on_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation_.py +6 -2
- luminarycloud/params/simulation/physics/fluid/solution_controls_fluid_.py +4 -0
- luminarycloud/physics_ai/__init__.py +4 -0
- luminarycloud/physics_ai/inference.py +140 -4
- luminarycloud/physics_ai/solution.py +60 -0
- luminarycloud/tables.py +6 -8
- luminarycloud/vis/data_extraction.py +4 -5
- luminarycloud/vis/display.py +26 -11
- luminarycloud/vis/filters.py +98 -65
- luminarycloud/vis/primitives.py +3 -2
- luminarycloud/vis/visualization.py +197 -40
- {luminarycloud-0.15.5.dist-info → luminarycloud-0.16.0.dist-info}/METADATA +1 -1
- {luminarycloud-0.15.5.dist-info → luminarycloud-0.16.0.dist-info}/RECORD +52 -50
- {luminarycloud-0.15.5.dist-info → luminarycloud-0.16.0.dist-info}/WHEEL +0 -0
luminarycloud/vis/filters.py
CHANGED
|
@@ -15,9 +15,10 @@ from .display import Field, DisplayAttributes
|
|
|
15
15
|
from typing import List, Any, cast
|
|
16
16
|
from .primitives import Box, Plane
|
|
17
17
|
from .vis_util import generate_id
|
|
18
|
+
from .._helpers._code_representation import CodeRepr
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
class Filter(ABC):
|
|
21
|
+
class Filter(ABC, CodeRepr):
|
|
21
22
|
"""
|
|
22
23
|
This is the base class for all filters. Each derived filter class
|
|
23
24
|
is responsible for providing a _to_proto method to convert to a filter
|
|
@@ -95,7 +96,7 @@ class Slice(Filter):
|
|
|
95
96
|
Specifies this filter's appearance.
|
|
96
97
|
"""
|
|
97
98
|
|
|
98
|
-
def __init__(self, name: str) -> None:
|
|
99
|
+
def __init__(self, name: str = "") -> None:
|
|
99
100
|
super().__init__(generate_id("slice-"))
|
|
100
101
|
self._plane = Plane()
|
|
101
102
|
self._project_vectors: bool = False
|
|
@@ -166,7 +167,7 @@ class Isosurface(Filter):
|
|
|
166
167
|
Specifies this filter's appearance.
|
|
167
168
|
"""
|
|
168
169
|
|
|
169
|
-
def __init__(self, name: str) -> None:
|
|
170
|
+
def __init__(self, name: str = "") -> None:
|
|
170
171
|
super().__init__(generate_id("contour-"))
|
|
171
172
|
self.isovalues: List[float] = []
|
|
172
173
|
self.field: Field = Field()
|
|
@@ -233,11 +234,9 @@ class PlaneClip(Filter):
|
|
|
233
234
|
are removed. Default: False
|
|
234
235
|
"""
|
|
235
236
|
|
|
236
|
-
def __init__(self, name: str) -> None:
|
|
237
|
+
def __init__(self, name: str = "") -> None:
|
|
237
238
|
super().__init__(generate_id("planeClip-"))
|
|
238
239
|
self._plane: Plane = Plane()
|
|
239
|
-
# TODO(matt): We could make this a prop to that is unsettable. Or we could
|
|
240
|
-
# not use ids and force that the filter names are unique.
|
|
241
240
|
self.name = name
|
|
242
241
|
self.inverted: bool = False
|
|
243
242
|
|
|
@@ -296,7 +295,7 @@ class BoxClip(Filter):
|
|
|
296
295
|
Default : False
|
|
297
296
|
"""
|
|
298
297
|
|
|
299
|
-
def __init__(self, name: str) -> None:
|
|
298
|
+
def __init__(self, name: str = "") -> None:
|
|
300
299
|
super().__init__(generate_id("boxClip-"))
|
|
301
300
|
self._box: Box = Box()
|
|
302
301
|
self.name = name
|
|
@@ -358,17 +357,11 @@ class VectorGlyphs(Filter):
|
|
|
358
357
|
|
|
359
358
|
"""
|
|
360
359
|
|
|
361
|
-
def __init__(self, name: str) -> None:
|
|
360
|
+
def __init__(self, name: str = "") -> None:
|
|
362
361
|
super().__init__(generate_id("vector-"))
|
|
363
362
|
self.name: str = name
|
|
364
|
-
# TODO(matt): we should be able to help set some reasonable defaults bases
|
|
365
|
-
# on the mesh size (i.e., number of points) and bounds (the default glyph size).
|
|
366
|
-
# The scene has accesss to this theoretically. Perhaps the scene class can be used
|
|
367
|
-
# as a factory.
|
|
368
363
|
self._sampling_rate: int = 500
|
|
369
|
-
self.
|
|
370
|
-
# TODO(matt): we should only allow vectors somehow
|
|
371
|
-
self.field.quantity = VisQuantity.VELOCITY
|
|
364
|
+
self.quantity: VisQuantity = VisQuantity.VELOCITY
|
|
372
365
|
|
|
373
366
|
@property
|
|
374
367
|
def sampling_rate(self) -> int:
|
|
@@ -403,11 +396,11 @@ class FixedSizeVectorGlyphs(VectorGlyphs):
|
|
|
403
396
|
The size in world units (meters) of the glyphs.
|
|
404
397
|
display_attrs (DisplayAttributes)
|
|
405
398
|
Specifies this filters appearance.
|
|
406
|
-
|
|
399
|
+
quantity: VisQuantity
|
|
407
400
|
The vector field to use for glyph generation. Default: Velocity
|
|
408
401
|
"""
|
|
409
402
|
|
|
410
|
-
def __init__(self, name: str) -> None:
|
|
403
|
+
def __init__(self, name: str = "") -> None:
|
|
411
404
|
super().__init__(name)
|
|
412
405
|
self.size: float = 1.0
|
|
413
406
|
|
|
@@ -418,10 +411,10 @@ class FixedSizeVectorGlyphs(VectorGlyphs):
|
|
|
418
411
|
vis_filter.glyph.fixed_size_glyphs = self.size
|
|
419
412
|
vis_filter.glyph.n_glyphs = self.sampling_rate
|
|
420
413
|
vis_filter.glyph.sampling_mode = vis_pb2.GLYPH_SAMPLING_MODE_EVERY_NTH
|
|
421
|
-
if not quantity_type._is_vector(self.
|
|
414
|
+
if not quantity_type._is_vector(self.quantity):
|
|
422
415
|
raise ValueError("FixedSizeVectorGlyphs: field must be a vector type")
|
|
423
|
-
vis_filter.glyph.field.quantity_typ = self.
|
|
424
|
-
vis_filter.glyph.field.component =
|
|
416
|
+
vis_filter.glyph.field.quantity_typ = self.quantity.value
|
|
417
|
+
vis_filter.glyph.field.component = vis_pb2.Field.COMPONENT_UNSPECIFIED
|
|
425
418
|
return vis_filter
|
|
426
419
|
|
|
427
420
|
def _from_proto(self, filter: vis_pb2.Filter) -> None:
|
|
@@ -436,8 +429,7 @@ class FixedSizeVectorGlyphs(VectorGlyphs):
|
|
|
436
429
|
self.n_glyphs = filter.glyph.n_glyphs
|
|
437
430
|
self.size = filter.glyph.fixed_size_glyphs
|
|
438
431
|
self.sampling_rate = filter.glyph.n_glyphs
|
|
439
|
-
self.
|
|
440
|
-
self.field.component = FieldComponent(filter.glyph.field.component)
|
|
432
|
+
self.quantity = VisQuantity(filter.glyph.field.quantity_typ)
|
|
441
433
|
|
|
442
434
|
|
|
443
435
|
class ScaledVectorGlyphs(VectorGlyphs):
|
|
@@ -464,11 +456,11 @@ class ScaledVectorGlyphs(VectorGlyphs):
|
|
|
464
456
|
0.5 and the scale is 2 then the resulting world space size is 1 meter. Default: 1.
|
|
465
457
|
display_attrs (DisplayAttributes)
|
|
466
458
|
Specifies this filters appearance.
|
|
467
|
-
|
|
459
|
+
quantity: VisQuantity
|
|
468
460
|
The vector field to use for glyph generation. Default: Velocity
|
|
469
461
|
"""
|
|
470
462
|
|
|
471
|
-
def __init__(self, name: str) -> None:
|
|
463
|
+
def __init__(self, name: str = "") -> None:
|
|
472
464
|
super().__init__(name)
|
|
473
465
|
self.scale: float = 1.0
|
|
474
466
|
|
|
@@ -479,10 +471,10 @@ class ScaledVectorGlyphs(VectorGlyphs):
|
|
|
479
471
|
vis_filter.glyph.glyph_scale_size = self.scale
|
|
480
472
|
vis_filter.glyph.n_glyphs = self.sampling_rate
|
|
481
473
|
vis_filter.glyph.sampling_mode = vis_pb2.GLYPH_SAMPLING_MODE_EVERY_NTH
|
|
482
|
-
if not quantity_type._is_vector(self.
|
|
474
|
+
if not quantity_type._is_vector(self.quantity):
|
|
483
475
|
raise ValueError("ScaledVectorGyph: field must be a vector type")
|
|
484
|
-
vis_filter.glyph.field.quantity_typ = self.
|
|
485
|
-
vis_filter.glyph.field.component =
|
|
476
|
+
vis_filter.glyph.field.quantity_typ = self.quantity.value
|
|
477
|
+
vis_filter.glyph.field.component = vis_pb2.Field.COMPONENT_UNSPECIFIED
|
|
486
478
|
return vis_filter
|
|
487
479
|
|
|
488
480
|
def _from_proto(self, filter: vis_pb2.Filter) -> None:
|
|
@@ -497,8 +489,7 @@ class ScaledVectorGlyphs(VectorGlyphs):
|
|
|
497
489
|
self.n_glyphs = filter.glyph.n_glyphs
|
|
498
490
|
self.scale = filter.glyph.glyph_scale_size
|
|
499
491
|
self.sampling_rate = filter.glyph.n_glyphs
|
|
500
|
-
self.
|
|
501
|
-
self.field.component = FieldComponent(filter.glyph.field.component)
|
|
492
|
+
self.quantity = VisQuantity(filter.glyph.field.quantity_typ)
|
|
502
493
|
|
|
503
494
|
|
|
504
495
|
class Threshold(Filter):
|
|
@@ -533,7 +524,7 @@ class Threshold(Filter):
|
|
|
533
524
|
Specifies this filter's appearance.
|
|
534
525
|
"""
|
|
535
526
|
|
|
536
|
-
def __init__(self, name: str) -> None:
|
|
527
|
+
def __init__(self, name: str = "") -> None:
|
|
537
528
|
super().__init__(generate_id("threshold-"))
|
|
538
529
|
self.field: Field = Field()
|
|
539
530
|
self.min_value: float = 0.0
|
|
@@ -610,14 +601,13 @@ class Streamlines(Filter):
|
|
|
610
601
|
Specifies this filter's appearance.
|
|
611
602
|
"""
|
|
612
603
|
|
|
613
|
-
def __init__(self, name: str) -> None:
|
|
604
|
+
def __init__(self, name: str = "") -> None:
|
|
614
605
|
super().__init__(generate_id("streamlines-"))
|
|
615
606
|
self.name: str = name
|
|
616
607
|
self.n_streamlines: int = 100
|
|
617
608
|
self.max_length: float = 10
|
|
618
609
|
self.direction: StreamlineDirection = StreamlineDirection.FORWARD
|
|
619
|
-
self.
|
|
620
|
-
self.field.quantity = VisQuantity.VELOCITY
|
|
610
|
+
self.quantity: VisQuantity = VisQuantity.VELOCITY
|
|
621
611
|
|
|
622
612
|
|
|
623
613
|
class RakeStreamlines(Streamlines):
|
|
@@ -640,7 +630,7 @@ class RakeStreamlines(Streamlines):
|
|
|
640
630
|
The number of seed particles to place on the rake. Default: 100
|
|
641
631
|
max_length: float
|
|
642
632
|
The maximum path length of the particle in meters. Default: 10
|
|
643
|
-
|
|
633
|
+
quantity: VisQuantity
|
|
644
634
|
The vector field to used for the particle advection. Default: Velocity
|
|
645
635
|
start: Vector3Like
|
|
646
636
|
The start point of the rake. Default: [0,0,0].
|
|
@@ -652,10 +642,10 @@ class RakeStreamlines(Streamlines):
|
|
|
652
642
|
Specifies this filter's appearance.
|
|
653
643
|
"""
|
|
654
644
|
|
|
655
|
-
def __init__(self, name: str) -> None:
|
|
645
|
+
def __init__(self, name: str = "") -> None:
|
|
656
646
|
super().__init__(name)
|
|
657
|
-
self.start: Vector3Like =
|
|
658
|
-
self.end: Vector3Like =
|
|
647
|
+
self.start: Vector3Like = Vector3(x=0, y=0, z=0)
|
|
648
|
+
self.end: Vector3Like = Vector3(x=1, y=0, z=0)
|
|
659
649
|
|
|
660
650
|
def _to_proto(self) -> vis_pb2.Filter:
|
|
661
651
|
# Type checking
|
|
@@ -663,8 +653,8 @@ class RakeStreamlines(Streamlines):
|
|
|
663
653
|
raise TypeError(f"Expected 'int', got {type(self.n_streamlines).__name__}")
|
|
664
654
|
if not isinstance(self.max_length, (float, int)):
|
|
665
655
|
raise TypeError(f"Expected 'float or int', got {type(self.max_length).__name__}")
|
|
666
|
-
if not isinstance(self.
|
|
667
|
-
raise TypeError(f"Expected '
|
|
656
|
+
if not isinstance(self.quantity, VisQuantity):
|
|
657
|
+
raise TypeError(f"Expected 'VisQuantity', got {type(self.quantity).__name__}")
|
|
668
658
|
|
|
669
659
|
vis_filter = vis_pb2.Filter()
|
|
670
660
|
vis_filter.id = self.id
|
|
@@ -673,9 +663,9 @@ class RakeStreamlines(Streamlines):
|
|
|
673
663
|
vis_filter.streamlines.max_length = self.max_length
|
|
674
664
|
vis_filter.streamlines.rake.start.CopyFrom(_to_vector3(self.start)._to_proto())
|
|
675
665
|
vis_filter.streamlines.rake.end.CopyFrom(_to_vector3(self.end)._to_proto())
|
|
676
|
-
if not quantity_type._is_vector(self.
|
|
666
|
+
if not quantity_type._is_vector(self.quantity):
|
|
677
667
|
raise ValueError("RakeStreamlines: field must be a vector type")
|
|
678
|
-
vis_filter.streamlines.field.quantity_typ = self.
|
|
668
|
+
vis_filter.streamlines.field.quantity_typ = self.quantity.value
|
|
679
669
|
return vis_filter
|
|
680
670
|
|
|
681
671
|
def _from_proto(self, filter: vis_pb2.Filter) -> None:
|
|
@@ -694,7 +684,7 @@ class RakeStreamlines(Streamlines):
|
|
|
694
684
|
self.start._from_proto(filter.streamlines.rake.start)
|
|
695
685
|
self.end = Vector3()
|
|
696
686
|
self.end._from_proto(filter.streamlines.rake.end)
|
|
697
|
-
self.
|
|
687
|
+
self.quantity = VisQuantity(filter.streamlines.field.quantity_typ)
|
|
698
688
|
|
|
699
689
|
|
|
700
690
|
class SurfaceStreamlines(Streamlines):
|
|
@@ -741,7 +731,7 @@ class SurfaceStreamlines(Streamlines):
|
|
|
741
731
|
particles further into the volume based on the surface normal. Default: 0.0
|
|
742
732
|
max_length: float
|
|
743
733
|
The maximum path length of the particle in meters. Default: 10
|
|
744
|
-
|
|
734
|
+
quantity: VisQuantity
|
|
745
735
|
The vector field to used for the particle advection. Default: Velocity
|
|
746
736
|
name : str
|
|
747
737
|
A user provided name for the filter.
|
|
@@ -749,7 +739,7 @@ class SurfaceStreamlines(Streamlines):
|
|
|
749
739
|
Specifies this filter's appearance.
|
|
750
740
|
"""
|
|
751
741
|
|
|
752
|
-
def __init__(self, name: str) -> None:
|
|
742
|
+
def __init__(self, name: str = "") -> None:
|
|
753
743
|
super().__init__(name)
|
|
754
744
|
self.offset: float = 0.0
|
|
755
745
|
self._surface_names: List[str] = []
|
|
@@ -783,8 +773,8 @@ class SurfaceStreamlines(Streamlines):
|
|
|
783
773
|
raise TypeError(f"Expected 'float or int', got {type(self.max_length).__name__}")
|
|
784
774
|
if not isinstance(self.offset, (float, int)):
|
|
785
775
|
raise TypeError(f"Expected 'float or int', got {type(self.offset).__name__}")
|
|
786
|
-
if not isinstance(self.
|
|
787
|
-
raise TypeError(f"Expected '
|
|
776
|
+
if not isinstance(self.quantity, VisQuantity):
|
|
777
|
+
raise TypeError(f"Expected 'VisQuantity', got {type(self.quantity).__name__}")
|
|
788
778
|
if not isinstance(self.mode, SurfaceStreamlineMode):
|
|
789
779
|
raise TypeError(f"Expected 'SurfaceStreamlinesMode', got {type(self.mode).__name__}")
|
|
790
780
|
|
|
@@ -796,12 +786,12 @@ class SurfaceStreamlines(Streamlines):
|
|
|
796
786
|
project = False
|
|
797
787
|
# Prevent common mistakes that cause confusion.
|
|
798
788
|
if self.mode == SurfaceStreamlineMode.ADVECT_ON_SURFACE:
|
|
799
|
-
if self.
|
|
789
|
+
if self.quantity == VisQuantity.VELOCITY:
|
|
800
790
|
raise ValueError(
|
|
801
791
|
"SurfacesStreamines: velocity is 0 on surfaces and will produce no data"
|
|
802
792
|
)
|
|
803
793
|
project = True
|
|
804
|
-
elif self.
|
|
794
|
+
elif self.quantity == VisQuantity.WALL_SHEAR_STRESS:
|
|
805
795
|
raise ValueError(
|
|
806
796
|
"SurfacesStreamines: wall shear stress is 0 in the volume and will produce no data "
|
|
807
797
|
)
|
|
@@ -811,10 +801,9 @@ class SurfaceStreamlines(Streamlines):
|
|
|
811
801
|
raise ValueError("SurfaceStreamlines: need at least one surfaces specified.")
|
|
812
802
|
for id in self._surface_names:
|
|
813
803
|
vis_filter.streamlines.surface.surface_names.append(id)
|
|
814
|
-
if not quantity_type._is_vector(self.
|
|
815
|
-
raise ValueError("SurfaceStreamlines:
|
|
816
|
-
vis_filter.streamlines.field.
|
|
817
|
-
vis_filter.streamlines.field.quantity_typ = self.field.quantity.value
|
|
804
|
+
if not quantity_type._is_vector(self.quantity):
|
|
805
|
+
raise ValueError("SurfaceStreamlines: quantity must be a vector type")
|
|
806
|
+
vis_filter.streamlines.field.quantity_typ = self.quantity.value
|
|
818
807
|
return vis_filter
|
|
819
808
|
|
|
820
809
|
def _from_proto(self, filter: vis_pb2.Filter) -> None:
|
|
@@ -831,7 +820,15 @@ class SurfaceStreamlines(Streamlines):
|
|
|
831
820
|
self._surface_names.clear()
|
|
832
821
|
for s in filter.streamlines.surface.surface_names:
|
|
833
822
|
self._surface_names.append(s)
|
|
834
|
-
self.
|
|
823
|
+
self.quantity = VisQuantity(filter.streamlines.field.quantity_typ)
|
|
824
|
+
|
|
825
|
+
def _to_code(self, hide_defaults: bool = True, use_tmp_objs: bool = True) -> str:
|
|
826
|
+
code = super()._to_code(hide_defaults=hide_defaults)
|
|
827
|
+
# We need to explicity write the code for the surfaces since its
|
|
828
|
+
# technically a private variable.
|
|
829
|
+
for s in self._surface_names:
|
|
830
|
+
code += f".add_surface('{s}')\n"
|
|
831
|
+
return code
|
|
835
832
|
|
|
836
833
|
|
|
837
834
|
class SurfaceLIC(Filter):
|
|
@@ -855,7 +852,7 @@ class SurfaceLIC(Filter):
|
|
|
855
852
|
|
|
856
853
|
Attributes:
|
|
857
854
|
-----------
|
|
858
|
-
|
|
855
|
+
quantity: VisQuantity
|
|
859
856
|
Specifies the field used to advect particles for the surface LIC.
|
|
860
857
|
Default: WALL_SHEER_STRESS
|
|
861
858
|
contrast: float
|
|
@@ -864,13 +861,12 @@ class SurfaceLIC(Filter):
|
|
|
864
861
|
higher values mean more contrast. Default: 1
|
|
865
862
|
"""
|
|
866
863
|
|
|
867
|
-
def __init__(self, name: str) -> None:
|
|
864
|
+
def __init__(self, name: str = "") -> None:
|
|
868
865
|
super().__init__(generate_id("surface-lic-"))
|
|
869
866
|
self.name = name
|
|
870
867
|
self.contrast: float = 1.0
|
|
871
868
|
self._surface_names: List[str] = []
|
|
872
|
-
self.
|
|
873
|
-
self.field.quantity = VisQuantity.WALL_SHEAR_STRESS
|
|
869
|
+
self.quantity: VisQuantity = VisQuantity.WALL_SHEAR_STRESS
|
|
874
870
|
|
|
875
871
|
def add_surface(self, id: str) -> None:
|
|
876
872
|
"""
|
|
@@ -898,9 +894,9 @@ class SurfaceLIC(Filter):
|
|
|
898
894
|
vis_filter.name = self.name
|
|
899
895
|
# Prevent common mistakes that cause confusion. The only current option
|
|
900
896
|
# is to be on a surface, so no velocity.
|
|
901
|
-
if not isinstance(self.
|
|
902
|
-
raise TypeError(f"Expected '
|
|
903
|
-
if self.
|
|
897
|
+
if not isinstance(self.quantity, VisQuantity):
|
|
898
|
+
raise TypeError(f"Expected 'VisQuantity', got {type(self.quantity).__name__}")
|
|
899
|
+
if self.quantity == VisQuantity.VELOCITY:
|
|
904
900
|
raise ValueError("SurfaceLIC: velocity is 0 on surfaces and will produce no data")
|
|
905
901
|
if not isinstance(self.contrast, (int, float)):
|
|
906
902
|
raise TypeError(f"Expected 'int or float', got {type(self.contrast).__name__}")
|
|
@@ -914,7 +910,7 @@ class SurfaceLIC(Filter):
|
|
|
914
910
|
geometry = vis_pb2.SurfaceLICGeomtery()
|
|
915
911
|
vis_filter.surface_lic.geometry.CopyFrom(geometry)
|
|
916
912
|
|
|
917
|
-
vis_filter.surface_lic.field.quantity_typ = self.
|
|
913
|
+
vis_filter.surface_lic.field.quantity_typ = self.quantity.value
|
|
918
914
|
vis_filter.surface_lic.contrast = self.contrast
|
|
919
915
|
return vis_filter
|
|
920
916
|
|
|
@@ -932,7 +928,44 @@ class SurfaceLIC(Filter):
|
|
|
932
928
|
self._surface_names = []
|
|
933
929
|
for s in filter.surface_lic.geometry.surface_names:
|
|
934
930
|
self._surface_names.append(s)
|
|
935
|
-
if not quantity_type._is_vector(self.
|
|
936
|
-
raise ValueError("SurfaceLIC:
|
|
937
|
-
self.
|
|
938
|
-
|
|
931
|
+
if not quantity_type._is_vector(self.quantity):
|
|
932
|
+
raise ValueError("SurfaceLIC: quantity must be a vector type")
|
|
933
|
+
self.quantity = VisQuantity(filter.surface_lic.field.quantity_typ)
|
|
934
|
+
|
|
935
|
+
def _to_code(self, hide_defaults: bool = True, use_tmp_objs: bool = True) -> str:
|
|
936
|
+
code = super()._to_code(hide_defaults=hide_defaults)
|
|
937
|
+
# We need to explicity write the code for the surfaces since its
|
|
938
|
+
# technically a private variable.
|
|
939
|
+
for s in self._surface_names:
|
|
940
|
+
code += f".add_surface('{s}')\n"
|
|
941
|
+
return code
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
def _filter_to_obj_name(filter: Filter) -> str:
|
|
945
|
+
"""
|
|
946
|
+
Helper function to convert a filter to a code object name used in code gen.
|
|
947
|
+
"""
|
|
948
|
+
if not isinstance(filter, Filter):
|
|
949
|
+
raise TypeError(f"Expected 'Filter', got {type(filter).__name__}")
|
|
950
|
+
if isinstance(filter, Slice):
|
|
951
|
+
return "slice"
|
|
952
|
+
elif isinstance(filter, Isosurface):
|
|
953
|
+
return "isosurface"
|
|
954
|
+
elif isinstance(filter, PlaneClip):
|
|
955
|
+
return "plane_clip"
|
|
956
|
+
elif isinstance(filter, BoxClip):
|
|
957
|
+
return "box_clip"
|
|
958
|
+
elif isinstance(filter, FixedSizeVectorGlyphs):
|
|
959
|
+
return "fixed_size_vector_glyphs"
|
|
960
|
+
elif isinstance(filter, ScaledVectorGlyphs):
|
|
961
|
+
return "scaled_vector_glyphs"
|
|
962
|
+
elif isinstance(filter, Threshold):
|
|
963
|
+
return "threshold"
|
|
964
|
+
elif isinstance(filter, RakeStreamlines):
|
|
965
|
+
return "rake_streamlines"
|
|
966
|
+
elif isinstance(filter, SurfaceStreamlines):
|
|
967
|
+
return "surface_streamlines"
|
|
968
|
+
elif isinstance(filter, SurfaceLIC):
|
|
969
|
+
return "surface_lic"
|
|
970
|
+
else:
|
|
971
|
+
raise TypeError(f"Unknown filter type: {type(filter).__name__}")
|
luminarycloud/vis/primitives.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# Copyright 2023-2024 Luminary Cloud, Inc. All Rights Reserved.
|
|
2
2
|
import dataclasses as dc
|
|
3
3
|
from luminarycloud.types import Vector3, Vector3Like
|
|
4
|
+
from .._helpers._code_representation import CodeRepr
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
@dc.dataclass
|
|
7
|
-
class Plane:
|
|
8
|
+
class Plane(CodeRepr):
|
|
8
9
|
"""
|
|
9
10
|
This class defines a plane.
|
|
10
11
|
|
|
@@ -19,7 +20,7 @@ class Plane:
|
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
@dc.dataclass
|
|
22
|
-
class Box:
|
|
23
|
+
class Box(CodeRepr):
|
|
23
24
|
"""
|
|
24
25
|
This class defines a box used for filter such as box clip.
|
|
25
26
|
|