Skip to content

Commit e3ea1d8

Browse files
Add defaults for render classes
1 parent 8d00ecc commit e3ea1d8

File tree

3 files changed

+147
-14
lines changed

3 files changed

+147
-14
lines changed

flow360/component/simulation/outputs/output_render_types.py

Lines changed: 133 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44

55
import pydantic as pd
66

7+
import flow360.component.simulation.units as u
78
from flow360.component.simulation.framework.base_model import Flow360BaseModel
89
from flow360.component.simulation.unit_system import AngleType, LengthType
910
from flow360.component.types import Color, Vector
1011

1112

13+
1214
class StaticCamera(Flow360BaseModel):
1315
position: LengthType.Point = pd.Field(description="Position of the camera in the scene")
1416
target: LengthType.Point = pd.Field(description="Target point of the camera")
15-
up: Optional[Vector] = pd.Field(
16-
default=(0, 1, 0), description="Up vector, if not specified assume Y+"
17-
)
17+
up: Optional[Vector] = pd.Field(default=(0, 1, 0), description="Up vector, if not specified assume Y+")
1818

1919

2020
class Keyframe(Flow360BaseModel):
@@ -47,6 +47,34 @@ class RenderCameraConfig(Flow360BaseModel):
4747
view: AllCameraTypes = pd.Field()
4848
projection: Union[OrthographicProjection, PerspectiveProjection] = pd.Field()
4949

50+
@classmethod
51+
def orthographic(cls, x=1, y=1, z=1, scale=1):
52+
return RenderCameraConfig(
53+
view=StaticCamera(
54+
position=(x * scale, y * scale, z * scale) * u.m,
55+
target=(0, 0, 0) * u.m
56+
),
57+
projection=OrthographicProjection(
58+
width=scale * u.m,
59+
near=0.01 * u.m,
60+
far=50 * scale * u.m
61+
)
62+
)
63+
64+
@classmethod
65+
def perspective(cls, x=1, y=1, z=1, scale=1):
66+
return RenderCameraConfig(
67+
view=StaticCamera(
68+
position=(x * scale, y * scale, z * scale) * u.m,
69+
target=(0, 0, 0) * u.m
70+
),
71+
projection=PerspectiveProjection(
72+
fov=60 * u.deg,
73+
near=0.01 * u.m,
74+
far=50 * scale * u.m
75+
)
76+
)
77+
5078

5179
class AmbientLight(Flow360BaseModel):
5280
intensity: float = pd.Field()
@@ -63,10 +91,24 @@ class RenderLightingConfig(Flow360BaseModel):
6391
directional: DirectionalLight = pd.Field()
6492
ambient: Optional[AmbientLight] = pd.Field(None)
6593

94+
@classmethod
95+
def default(cls):
96+
return RenderLightingConfig(
97+
ambient=AmbientLight(
98+
intensity=0.5,
99+
color=(255, 255, 255)
100+
),
101+
directional=DirectionalLight(
102+
intensity=1.5,
103+
color=(255, 255, 255),
104+
direction=(-1.0, -1.0, -1.0)
105+
)
106+
)
107+
66108

67109
class RenderBackgroundBase(Flow360BaseModel, metaclass=abc.ABCMeta):
68110
type: str = pd.Field(default="", frozen=True)
69-
111+
70112

71113
class SolidBackground(RenderBackgroundBase):
72114
type: str = pd.Field(default="solid", frozen=True)
@@ -75,6 +117,7 @@ class SolidBackground(RenderBackgroundBase):
75117

76118
class SkyboxTexture(str, Enum):
77119
SKY = "sky"
120+
GRADIENT = "gradient"
78121

79122

80123
class SkyboxBackground(RenderBackgroundBase):
@@ -88,6 +131,30 @@ class SkyboxBackground(RenderBackgroundBase):
88131
class RenderEnvironmentConfig(Flow360BaseModel):
89132
background: AllBackgroundTypes = pd.Field()
90133

134+
@classmethod
135+
def simple(cls):
136+
return RenderEnvironmentConfig(
137+
background=SolidBackground(
138+
color=(207, 226, 230)
139+
)
140+
)
141+
142+
@classmethod
143+
def sky(cls):
144+
return RenderEnvironmentConfig(
145+
background=SkyboxBackground(
146+
texture=SkyboxTexture.SKY
147+
)
148+
)
149+
150+
@classmethod
151+
def gradient(cls):
152+
return RenderEnvironmentConfig(
153+
background=SkyboxBackground(
154+
texture=SkyboxTexture.GRADIENT
155+
)
156+
)
157+
91158

92159
class RenderMaterialBase(Flow360BaseModel, metaclass=abc.ABCMeta):
93160
type: str = pd.Field(default="", frozen=True)
@@ -100,6 +167,24 @@ class PBRMaterial(RenderMaterialBase):
100167
f0: Vector = pd.Field(default=(0.03, 0.03, 0.03))
101168
type: str = pd.Field(default="pbr", frozen=True)
102169

170+
@classmethod
171+
def metal(cls, shine=0.5, alpha=1.0):
172+
return PBRMaterial(
173+
color=(255, 255, 255),
174+
alpha=alpha,
175+
roughness=1 - shine,
176+
f0=(0.56, 0.56, 0.56)
177+
)
178+
179+
@classmethod
180+
def plastic(cls, shine=0.5, alpha=1.0):
181+
return PBRMaterial(
182+
color=(255, 255, 255),
183+
alpha=alpha,
184+
roughness=1 - shine,
185+
f0=(0.03, 0.03, 0.03)
186+
)
187+
103188

104189
class ColorKey(Flow360BaseModel):
105190
color: Color = pd.Field(default=[255, 255, 255])
@@ -110,10 +195,53 @@ class FieldMaterial(RenderMaterialBase):
110195
alpha: float = pd.Field(default=1)
111196
output_field: str = pd.Field(default="")
112197
min: float = pd.Field(default=0)
113-
max: float = pd.Field(default=0)
198+
max: float = pd.Field(default=1)
114199
colormap: List[ColorKey] = pd.Field()
115200
type: str = pd.Field(default="field", frozen=True)
116201

202+
@classmethod
203+
def greyscale(cls, field, min=0, max=1, alpha=1):
204+
return FieldMaterial(
205+
alpha=alpha,
206+
output_field=field,
207+
min=min,
208+
max=max,
209+
colormap = [
210+
ColorKey(color=(0, 0, 0), value=0),
211+
ColorKey(color=(255, 255, 255), value=1.0)
212+
]
213+
)
214+
215+
@classmethod
216+
def hot_cold(cls, field, min=0, max=1, alpha=1):
217+
return FieldMaterial(
218+
alpha=alpha,
219+
output_field=field,
220+
min=min,
221+
max=max,
222+
colormap = [
223+
ColorKey(color=(0, 0, 255), value=0),
224+
ColorKey(color=(255, 255, 255), value=0.5),
225+
ColorKey(color=(255, 0, 0), value=1.0)
226+
]
227+
)
228+
229+
@classmethod
230+
def rainbow(cls, field, min=0, max=1, alpha=1):
231+
return FieldMaterial(
232+
alpha=alpha,
233+
output_field=field,
234+
min=min,
235+
max=max,
236+
colormap = [
237+
ColorKey(color=(0, 0, 255), value=0),
238+
ColorKey(color=(0, 255, 255), value=0.25),
239+
ColorKey(color=(0, 255, 0), value=0.5),
240+
ColorKey(color=(255, 255, 0), value=0.75),
241+
ColorKey(color=(255, 0, 0), value=1.0)
242+
]
243+
)
244+
117245

118246
AllMaterialTypes = Union[PBRMaterial, FieldMaterial]
119247

flow360/component/simulation/outputs/outputs.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -712,13 +712,11 @@ class RenderOutput(_AnimationSettings):
712712
description="List of output variables. Including "
713713
":ref:`universal output variables<UniversalVariablesV2>` and :class:`UserDefinedField`."
714714
)
715-
camera: RenderCameraConfig = pd.Field(description="Camera settings")
716-
lighting: RenderLightingConfig = pd.Field(description="Lighting settings")
717-
environment: RenderEnvironmentConfig = pd.Field(description="Environment settings")
715+
camera: RenderCameraConfig = pd.Field(description="Camera settings", default_factory=RenderCameraConfig.orthographic)
716+
lighting: RenderLightingConfig = pd.Field(description="Lighting settings", default_factory=RenderLightingConfig.default)
717+
environment: RenderEnvironmentConfig = pd.Field(description="Environment settings", default_factory=RenderEnvironmentConfig.simple)
718718
materials: RenderMaterialConfig = pd.Field(description="Material settings")
719-
transform: Optional[Transform] = pd.Field(
720-
None, description="Optional model transform to apply to all entities"
721-
)
719+
transform: Optional[Transform] = pd.Field(None, description="Optional model transform to apply to all entities")
722720
output_type: Literal["RenderOutput"] = pd.Field("RenderOutput", frozen=True)
723721

724722

flow360/component/simulation/translator/solver_translator.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,8 @@ def translate_isosurface_output(
579579
def translate_render_output(
580580
input_params: SimulationParams,
581581
output_params: list,
582-
injection_function
582+
isosurface_injection_function,
583+
slice_injection_function
583584
):
584585
"""Translate render output settings."""
585586

@@ -605,7 +606,7 @@ def translate_render_output(
605606
RenderOutput,
606607
translation_func=translate_output_fields,
607608
to_list=False,
608-
entity_injection_func=injection_function,
609+
entity_injection_func=isosurface_injection_function,
609610
entity_type_to_include=Isosurface,
610611
entity_list_attribute_name="isosurfaces",
611612
entity_injection_input_params=input_params,
@@ -622,6 +623,7 @@ def translate_render_output(
622623
RenderOutput,
623624
translation_func=translate_output_fields,
624625
to_list=False,
626+
entity_injection_func=slice_injection_function,
625627
entity_type_to_include=Slice,
626628
),
627629
"camera": remove_units_in_dict(camera),
@@ -1002,7 +1004,12 @@ def translate_output(input_params: SimulationParams, translated: dict):
10021004

10031005
##:: Step6: Get translated["renderOutput"]
10041006
if has_instance_in_list(outputs, RenderOutput):
1005-
translated["renderOutput"] = translate_render_output(input_params, outputs, inject_isosurface_info)
1007+
translated["renderOutput"] = translate_render_output(
1008+
input_params,
1009+
outputs,
1010+
inject_isosurface_info,
1011+
inject_slice_info
1012+
)
10061013

10071014
##:: Step7: Get translated["monitorOutput"]
10081015
probe_output = {}

0 commit comments

Comments
 (0)