pyvale 2025.5.3__cp311-cp311-win_amd64.whl → 2025.7.1__cp311-cp311-win_amd64.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.
Potentially problematic release.
This version of pyvale might be problematic. Click here for more details.
- pyvale/__init__.py +12 -0
- pyvale/blendercalibrationdata.py +3 -1
- pyvale/blenderscene.py +7 -5
- pyvale/blendertools.py +27 -5
- pyvale/camera.py +1 -0
- pyvale/cameradata.py +3 -0
- pyvale/camerasensor.py +147 -0
- pyvale/camerastereo.py +4 -4
- pyvale/cameratools.py +23 -61
- pyvale/cython/rastercyth.c +1657 -1352
- pyvale/cython/rastercyth.cp311-win_amd64.pyd +0 -0
- pyvale/cython/rastercyth.py +71 -26
- pyvale/data/DIC_Challenge_Star_Noise_Def.tiff +0 -0
- pyvale/data/DIC_Challenge_Star_Noise_Ref.tiff +0 -0
- pyvale/data/plate_hole_def0000.tiff +0 -0
- pyvale/data/plate_hole_def0001.tiff +0 -0
- pyvale/data/plate_hole_ref0000.tiff +0 -0
- pyvale/data/plate_rigid_def0000.tiff +0 -0
- pyvale/data/plate_rigid_def0001.tiff +0 -0
- pyvale/data/plate_rigid_ref0000.tiff +0 -0
- pyvale/dataset.py +96 -6
- pyvale/dic/cpp/dicbruteforce.cpp +370 -0
- pyvale/dic/cpp/dicfourier.cpp +648 -0
- pyvale/dic/cpp/dicinterpolator.cpp +559 -0
- pyvale/dic/cpp/dicmain.cpp +215 -0
- pyvale/dic/cpp/dicoptimizer.cpp +675 -0
- pyvale/dic/cpp/dicrg.cpp +137 -0
- pyvale/dic/cpp/dicscanmethod.cpp +677 -0
- pyvale/dic/cpp/dicsmooth.cpp +138 -0
- pyvale/dic/cpp/dicstrain.cpp +383 -0
- pyvale/dic/cpp/dicutil.cpp +563 -0
- pyvale/dic2d.py +164 -0
- pyvale/dic2dcpp.cp311-win_amd64.pyd +0 -0
- pyvale/dicchecks.py +476 -0
- pyvale/dicdataimport.py +247 -0
- pyvale/dicregionofinterest.py +887 -0
- pyvale/dicresults.py +55 -0
- pyvale/dicspecklegenerator.py +238 -0
- pyvale/dicspecklequality.py +305 -0
- pyvale/dicstrain.py +387 -0
- pyvale/dicstrainresults.py +37 -0
- pyvale/errorintegrator.py +10 -8
- pyvale/examples/basics/ex1_1_basicscalars_therm2d.py +124 -113
- pyvale/examples/basics/ex1_2_sensormodel_therm2d.py +124 -132
- pyvale/examples/basics/ex1_3_customsens_therm3d.py +199 -195
- pyvale/examples/basics/ex1_4_basicerrors_therm3d.py +125 -121
- pyvale/examples/basics/ex1_5_fielderrs_therm3d.py +145 -141
- pyvale/examples/basics/ex1_6_caliberrs_therm2d.py +96 -101
- pyvale/examples/basics/ex1_7_spatavg_therm2d.py +109 -105
- pyvale/examples/basics/ex2_1_basicvectors_disp2d.py +92 -91
- pyvale/examples/basics/ex2_2_vectorsens_disp2d.py +96 -90
- pyvale/examples/basics/ex2_3_sensangle_disp2d.py +88 -89
- pyvale/examples/basics/ex2_4_chainfielderrs_disp2d.py +172 -171
- pyvale/examples/basics/ex2_5_vectorfields3d_disp3d.py +88 -86
- pyvale/examples/basics/ex3_1_basictensors_strain2d.py +90 -90
- pyvale/examples/basics/ex3_2_tensorsens2d_strain2d.py +93 -91
- pyvale/examples/basics/ex3_3_tensorsens3d_strain3d.py +172 -160
- pyvale/examples/basics/ex4_1_expsim2d_thermmech2d.py +154 -148
- pyvale/examples/basics/ex4_2_expsim3d_thermmech3d.py +249 -231
- pyvale/examples/dic/ex1_region_of_interest.py +98 -0
- pyvale/examples/dic/ex2_plate_with_hole.py +149 -0
- pyvale/examples/dic/ex3_plate_with_hole_strain.py +93 -0
- pyvale/examples/dic/ex4_dic_blender.py +95 -0
- pyvale/examples/dic/ex5_dic_challenge.py +102 -0
- pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +4 -2
- pyvale/examples/renderblender/ex1_1_blenderscene.py +152 -105
- pyvale/examples/renderblender/ex1_2_blenderdeformed.py +151 -100
- pyvale/examples/renderblender/ex2_1_stereoscene.py +183 -116
- pyvale/examples/renderblender/ex2_2_stereodeformed.py +185 -112
- pyvale/examples/renderblender/ex3_1_blendercalibration.py +164 -109
- pyvale/examples/renderrasterisation/ex_rastenp.py +74 -35
- pyvale/examples/renderrasterisation/ex_rastercyth_oneframe.py +6 -13
- pyvale/examples/renderrasterisation/ex_rastercyth_static_cypara.py +2 -2
- pyvale/examples/renderrasterisation/ex_rastercyth_static_pypara.py +2 -4
- pyvale/imagedef2d.py +3 -2
- pyvale/imagetools.py +137 -0
- pyvale/rastercy.py +34 -4
- pyvale/rasternp.py +300 -276
- pyvale/rasteropts.py +58 -0
- pyvale/renderer.py +47 -0
- pyvale/rendermesh.py +52 -62
- pyvale/renderscene.py +51 -0
- pyvale/sensorarrayfactory.py +2 -2
- pyvale/sensortools.py +19 -35
- pyvale/simcases/case21.i +1 -1
- pyvale/simcases/run_1case.py +8 -0
- pyvale/simtools.py +2 -2
- pyvale/visualsimplotter.py +180 -0
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.1.dist-info}/METADATA +11 -57
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.1.dist-info}/RECORD +93 -56
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.1.dist-info}/WHEEL +1 -1
- pyvale/examples/visualisation/ex1_1_plot_traces.py +0 -102
- pyvale/examples/visualisation/ex2_1_animate_sim.py +0 -89
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.1.dist-info}/licenses/LICENSE +0 -0
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.1.dist-info}/top_level.txt +0 -0
|
@@ -4,117 +4,172 @@
|
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
5
|
# ==============================================================================
|
|
6
6
|
|
|
7
|
+
"""
|
|
8
|
+
Blender example: Rendering calibration images
|
|
9
|
+
---------------------------------------------
|
|
10
|
+
|
|
11
|
+
This example takes you through how to render calibration images for a given DIC
|
|
12
|
+
setup.
|
|
13
|
+
"""
|
|
7
14
|
import numpy as np
|
|
8
15
|
from scipy.spatial.transform import Rotation
|
|
9
16
|
from pathlib import Path
|
|
10
17
|
import pyvale
|
|
11
18
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
19
|
+
# %%
|
|
20
|
+
# Firstly, a save path must be set.
|
|
21
|
+
# In order to do this a base path must be set. Then all the generated files will
|
|
22
|
+
# be saved to a subfolder within this specified base directory
|
|
23
|
+
# (e.g. blenderimages).
|
|
24
|
+
# If no base directory is specified, it will be set as your home directory.
|
|
25
|
+
|
|
26
|
+
base_dir = Path.cwd()
|
|
27
|
+
|
|
28
|
+
# %%
|
|
29
|
+
# Creating the scene
|
|
30
|
+
# ^^^^^^^^^^^^^^^^^^
|
|
31
|
+
# In order to create a DIC setup in Blender, first a scene must be created.
|
|
32
|
+
# A scene is initialised using the `BlenderScene` class. All the subsequent
|
|
33
|
+
# objects and actions necessary are then methods of this class.
|
|
34
|
+
scene = pyvale.BlenderScene()
|
|
35
|
+
|
|
36
|
+
# %%
|
|
37
|
+
# The next thing to add to the scene is the calibration target.
|
|
38
|
+
# This is done by specifing the size of calibration target to add to the scene
|
|
39
|
+
# by passing in an array of (width, height, depth).
|
|
40
|
+
# The calibration target being simulated here is 12 x 9 with 10 mm spacing.
|
|
41
|
+
|
|
42
|
+
target = scene.add_cal_target(target_size=np.array([150, 100, 10]))
|
|
43
|
+
|
|
44
|
+
# %%
|
|
45
|
+
# The cameras can then be initialised. A stereo camera system is defined by a
|
|
46
|
+
# `CameraStereo` object, which contains the intrinsic parameters of both cameras
|
|
47
|
+
# as well as the extrinsic parameters between them.
|
|
48
|
+
# There are two ways to initialise a `CameraStereo` object.
|
|
49
|
+
# One way is to specify the camera parameters separately for each camera, create
|
|
50
|
+
# a `CameraStereo` object, and then add the stereo system using the
|
|
51
|
+
# `add_stereo_system` method.
|
|
52
|
+
# The other method is to use a convenience function, as shown below.
|
|
53
|
+
# This requires you to first initialise one camera. Then you can choose between
|
|
54
|
+
# either a face-on or symmetric stereo system. Then, either of the
|
|
55
|
+
# `symmetric_stereo_cameras` or `faceon_stereo_cameras` functions can be used to
|
|
56
|
+
# initialise a `CameraStereo` object. The only input required to these functions
|
|
57
|
+
# are the camera parameters for the first camera, and the desired stereo angle
|
|
58
|
+
# between the two. The cameras can then be added to the Blender scene using the
|
|
59
|
+
# `add_stereo_system` method.
|
|
60
|
+
cam_data_0 = pyvale.CameraData(pixels_num=np.array([1540, 1040]),
|
|
61
|
+
pixels_size=np.array([0.00345, 0.00345]),
|
|
62
|
+
pos_world=np.array([0, 0, 400]),
|
|
63
|
+
rot_world=Rotation.from_euler("xyz", [0, 0, 0]),
|
|
64
|
+
roi_cent_world=(0, 0, 0),
|
|
65
|
+
focal_length=15.0)
|
|
66
|
+
# Set this to "symmetric" to get a symmetric stereo system or set this to
|
|
67
|
+
# "faceon" to get a face-on stereo system
|
|
68
|
+
stereo_setup = "faceon"
|
|
69
|
+
if stereo_setup == "symmetric":
|
|
70
|
+
stereo_system = pyvale.CameraTools.symmetric_stereo_cameras(
|
|
71
|
+
cam_data_0=cam_data_0,
|
|
72
|
+
stereo_angle=15.0)
|
|
73
|
+
if stereo_setup == "faceon":
|
|
74
|
+
stereo_system = pyvale.CameraTools.faceon_stereo_cameras(
|
|
75
|
+
cam_data_0=cam_data_0,
|
|
76
|
+
stereo_angle=15.0)
|
|
77
|
+
scene.add_stereo_system(stereo_system)
|
|
78
|
+
|
|
79
|
+
# %%
|
|
80
|
+
# Since this scene contains a stereo DIC system, a calibration file will be
|
|
81
|
+
# required to run the images through a DIC engine.
|
|
82
|
+
# A calibration file can be generated directly from the `CameraStereo` object.
|
|
83
|
+
# The calibration file will be saved in `YAML` format. However, if you wish to
|
|
84
|
+
# use MatchID to process the images, `save_calibration_mid` can be used instead
|
|
85
|
+
# to save the calibration in a format readable by MatchID.
|
|
86
|
+
# The calibration file will be saved to a sub-directory of the base directory
|
|
87
|
+
# called "calibration".
|
|
88
|
+
# This calibration file with "perfect" parameters can be used as a comparitive
|
|
89
|
+
# benchmark to the calibration gained from running the calibration files through
|
|
90
|
+
# a DIC engine.
|
|
91
|
+
stereo_system.save_calibration(base_dir)
|
|
92
|
+
|
|
93
|
+
# %%
|
|
94
|
+
# A light can the be added to the scene.
|
|
95
|
+
# Blender offers different light types: Point, Sun, Spot and Area.
|
|
96
|
+
# The light can also be moved and rotated like the camera.
|
|
97
|
+
|
|
98
|
+
light_data = pyvale.BlenderLightData(type=pyvale.BlenderLightType.POINT,
|
|
99
|
+
pos_world=(0, 0, 200),
|
|
100
|
+
rot_world=Rotation.from_euler("xyz",
|
|
101
|
+
[0, 0, 0]),
|
|
102
|
+
energy=1)
|
|
103
|
+
light = scene.add_light(light_data)
|
|
104
|
+
light.location = (0, 0, 210)
|
|
105
|
+
light.rotation_euler = (0, 0, 0) # NOTE: The default is an XYZ Euler angle
|
|
106
|
+
|
|
107
|
+
# %%
|
|
108
|
+
# The calibration target pattern can then be added to the calibration target
|
|
109
|
+
# object.
|
|
110
|
+
# This is added in the same way that a speckle pattern is added to a sample.
|
|
111
|
+
# However, it is important to set the `cal` flag to True, as this means that the
|
|
112
|
+
# calibration target pattern will not be scaled in the same way as a speckle
|
|
113
|
+
# pattern.
|
|
114
|
+
|
|
115
|
+
material_data = pyvale.BlenderMaterialData()
|
|
116
|
+
speckle_path = Path.cwd() / "src/pyvale/data/cal_target.tiff"
|
|
117
|
+
mm_px_resolution = pyvale.CameraTools.calculate_mm_px_resolution(cam_data_0)
|
|
118
|
+
scene.add_speckle(part=target,
|
|
119
|
+
speckle_path=speckle_path,
|
|
120
|
+
mat_data=material_data,
|
|
121
|
+
mm_px_resolution=mm_px_resolution,
|
|
122
|
+
cal=True)
|
|
123
|
+
|
|
124
|
+
# %%
|
|
125
|
+
# Rendering a set of images
|
|
126
|
+
# ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
127
|
+
# Once all the objects have been added to the scene, a set of images can be
|
|
128
|
+
# rendered.Firstly, all the rendering parameters must be set, including
|
|
129
|
+
# parameters such as the number of threads to use.
|
|
130
|
+
|
|
131
|
+
render_data = pyvale.RenderData(cam_data=(stereo_system.cam_data_0,
|
|
132
|
+
stereo_system.cam_data_1),
|
|
133
|
+
base_dir=base_dir)
|
|
134
|
+
|
|
135
|
+
# %%
|
|
136
|
+
# The parameters for the calibration target's movement can then be set. This is
|
|
137
|
+
# done by setting the minimum and maximum angle and plunge limits, as well as
|
|
138
|
+
# the step value that they should be increased by. The x and y limit of the
|
|
139
|
+
# calibration target's movement (from the origin) can also be set if you wish to
|
|
140
|
+
# perform a calibration for a constrained optical setup. If these limits are not
|
|
141
|
+
# passed in they will be initialised from the FOV to cover the whole FOV of the
|
|
142
|
+
# cameras.
|
|
143
|
+
|
|
144
|
+
calibration_data = pyvale.CalibrationData(angle_lims=(-10, 10),
|
|
145
|
+
angle_step=5,
|
|
146
|
+
plunge_lims=(-5, 5),
|
|
147
|
+
plunge_step=5)
|
|
148
|
+
|
|
149
|
+
# %%
|
|
150
|
+
# It is then possible to check the number of calibration images that will be
|
|
151
|
+
# rendered before rendering them. The only input that is needed is the
|
|
152
|
+
# `calibration_data` specified above.
|
|
153
|
+
|
|
154
|
+
number_calibration_images = pyvale.BlenderTools.number_calibration_images(calibration_data)
|
|
155
|
+
print("Number of calibration images to be rendered:", number_calibration_images)
|
|
156
|
+
|
|
157
|
+
# %%
|
|
158
|
+
# The calibration images can then be rendered. This function will move the
|
|
159
|
+
# calibration target according to movement limits set above, and will also move
|
|
160
|
+
# the target rigidly across the FOV of the camera, in order to characterise the
|
|
161
|
+
# entire FOV of the cameras.
|
|
162
|
+
pyvale.BlenderTools.render_calibration_images(render_data,
|
|
163
|
+
calibration_data,
|
|
164
|
+
target)
|
|
165
|
+
|
|
166
|
+
# %%
|
|
167
|
+
# The rendered images will be saved to this filepath:
|
|
168
|
+
|
|
169
|
+
print("Save directory of the images:", (render_data.base_dir / "calimages"))
|
|
170
|
+
|
|
171
|
+
# %%
|
|
172
|
+
# There is also the option to save the scene as a Blender project file.
|
|
173
|
+
# This file can be opened with the Blender GUI to view the scene.
|
|
174
|
+
|
|
175
|
+
pyvale.BlenderTools.save_blender_file(base_dir)
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
# ==============================================================================
|
|
6
6
|
|
|
7
7
|
from pathlib import Path
|
|
8
|
+
import copy
|
|
8
9
|
import time
|
|
9
10
|
import numpy as np
|
|
10
11
|
from scipy.spatial.transform import Rotation
|
|
@@ -27,21 +28,20 @@ import pyvale as pyv
|
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
def main() -> None:
|
|
30
|
-
"""
|
|
31
|
+
"""Basics rasterisation field renderer
|
|
31
32
|
----------------------------------------------------------------------------
|
|
32
|
-
- TODO
|
|
33
33
|
"""
|
|
34
34
|
# This a path to an exodus *.e output file from MOOSE, this can be
|
|
35
35
|
# replaced with a path to your own simulation file
|
|
36
|
-
|
|
37
|
-
sim_path = pyv.DataSet.render_mechanical_3d_path()
|
|
36
|
+
sim_path = Path.home()/"pyvale"/"src"/"pyvale"/"simcases"/"case21_out.e"
|
|
37
|
+
#sim_path = pyv.DataSet.render_mechanical_3d_path()
|
|
38
38
|
|
|
39
39
|
disp_comps = ("disp_x","disp_y","disp_z")
|
|
40
40
|
|
|
41
41
|
sim_data = mh.ExodusReader(sim_path).read_all_sim_data()
|
|
42
42
|
|
|
43
43
|
# Scale m -> mm
|
|
44
|
-
sim_data = pyv.scale_length_units(sim_data,disp_comps
|
|
44
|
+
sim_data = pyv.scale_length_units(1000.0,sim_data,disp_comps)
|
|
45
45
|
|
|
46
46
|
# Extracts the surface mesh from a full 3d simulation for rendering
|
|
47
47
|
render_mesh = pyv.create_render_mesh(sim_data,
|
|
@@ -49,6 +49,18 @@ def main() -> None:
|
|
|
49
49
|
sim_spat_dim=3,
|
|
50
50
|
field_disp_keys=disp_comps)
|
|
51
51
|
|
|
52
|
+
#===========================================================================
|
|
53
|
+
# render_mesh.fields_render = render_mesh.fields_render[:,-2:-1,:]
|
|
54
|
+
# render_mesh.fields_disp = render_mesh.fields_disp[:,-2:-1,:]
|
|
55
|
+
# render_mesh.fields_disp = None
|
|
56
|
+
#===========================================================================
|
|
57
|
+
|
|
58
|
+
meshes = [render_mesh,copy.deepcopy(render_mesh)]
|
|
59
|
+
meshes[1].set_pos(np.array((0.0,12.5,0.0)))
|
|
60
|
+
meshes[1].set_rot(Rotation.from_euler("zyx",(0.0, 0.0, 0.0),degrees=True))
|
|
61
|
+
meshes[1].fields_disp = None
|
|
62
|
+
coords_all = pyv.get_all_coords_world(meshes)
|
|
63
|
+
|
|
52
64
|
print()
|
|
53
65
|
print(80*"-")
|
|
54
66
|
print("MESH DATA:")
|
|
@@ -66,16 +78,15 @@ def main() -> None:
|
|
|
66
78
|
print(80*"-")
|
|
67
79
|
print()
|
|
68
80
|
|
|
69
|
-
|
|
70
81
|
pixel_num = np.array((960,1280))
|
|
71
82
|
pixel_size = np.array((5.3e-3,5.3e-3))
|
|
72
83
|
focal_leng: float = 50
|
|
73
|
-
cam_rot = Rotation.from_euler("zyx",(0.0
|
|
74
|
-
fov_scale_factor: float = 1.
|
|
84
|
+
cam_rot = Rotation.from_euler("zyx",(0.0, 0.0, -30.0),degrees=True)
|
|
85
|
+
fov_scale_factor: float = 1.0
|
|
75
86
|
|
|
76
87
|
(roi_pos_world,
|
|
77
|
-
cam_pos_world) = pyv.CameraTools.
|
|
78
|
-
coords_world=
|
|
88
|
+
cam_pos_world) = pyv.CameraTools.pos_fill_frame(
|
|
89
|
+
coords_world=coords_all,
|
|
79
90
|
pixel_num=pixel_num,
|
|
80
91
|
pixel_size=pixel_size,
|
|
81
92
|
focal_leng=focal_leng,
|
|
@@ -103,51 +114,79 @@ def main() -> None:
|
|
|
103
114
|
print("World to camera matrix:")
|
|
104
115
|
print(cam_data.world_to_cam_mat)
|
|
105
116
|
print(80*"-")
|
|
106
|
-
|
|
117
|
+
|
|
118
|
+
scene = pyv.RenderScene([cam_data,cam_data],meshes)
|
|
119
|
+
|
|
120
|
+
frames_per_camera = (scene.meshes[0].fields_render.shape[1]
|
|
121
|
+
*scene.meshes[0].fields_render.shape[2])
|
|
122
|
+
frames_total = frames_per_camera*len(scene.cameras)
|
|
107
123
|
|
|
108
124
|
print(80*"-")
|
|
109
|
-
|
|
110
|
-
print(f"
|
|
111
|
-
print(f"
|
|
112
|
-
print(
|
|
125
|
+
print("RENDER SCENE:")
|
|
126
|
+
print(f"Cameras #: {len(scene.cameras)}")
|
|
127
|
+
print(f"Meshes #: {len(scene.meshes)}")
|
|
128
|
+
print()
|
|
129
|
+
print(f"Time steps: {scene.meshes[0].fields_render.shape[1]}")
|
|
130
|
+
print(f"Field #: {scene.meshes[0].fields_render.shape[2]}")
|
|
131
|
+
print()
|
|
132
|
+
print(f"Frames per camera: {frames_per_camera}")
|
|
133
|
+
print(f"Frames total: {frames_total}")
|
|
113
134
|
print(80*"-")
|
|
114
135
|
|
|
136
|
+
|
|
137
|
+
#===========================================================================
|
|
115
138
|
print()
|
|
116
139
|
print(80*"=")
|
|
117
|
-
print("
|
|
140
|
+
print("IN MEM: Raster Loop start")
|
|
118
141
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
static_mesh = False
|
|
142
|
+
raster_opts = pyv.RasterOpts(parallel=8)
|
|
143
|
+
renderer = pyv.RasterNumpy(raster_opts)
|
|
122
144
|
|
|
123
145
|
time_start_loop = time.perf_counter()
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
cam_data,render_mesh,save_path,threads_num=8
|
|
127
|
-
)
|
|
128
|
-
else:
|
|
129
|
-
time_start_loop = time.perf_counter()
|
|
130
|
-
images = pyv.RasterNP.raster_deformed_mesh(
|
|
131
|
-
cam_data,render_mesh,save_path,parallel=8
|
|
132
|
-
)
|
|
146
|
+
|
|
147
|
+
images = renderer.render_all(scene)
|
|
133
148
|
|
|
134
149
|
time_end_loop = time.perf_counter()
|
|
135
|
-
|
|
150
|
+
time_inmem = time_end_loop - time_start_loop
|
|
151
|
+
|
|
152
|
+
print(f"{images[0].shape=}")
|
|
153
|
+
print(f"{images[1].shape=}")
|
|
154
|
+
print("IN MEM: Raster Loop End")
|
|
155
|
+
print(80*"=")
|
|
136
156
|
|
|
137
157
|
|
|
138
|
-
print("RASTER LOOP END")
|
|
139
158
|
print(80*"=")
|
|
159
|
+
print("TO DISK: Raster Loop start")
|
|
160
|
+
save_path = Path.cwd()/"pyvale-output"
|
|
161
|
+
if not save_path.is_dir():
|
|
162
|
+
save_path.mkdir(parents=True, exist_ok=True)
|
|
163
|
+
|
|
164
|
+
time_start_loop = time.perf_counter()
|
|
165
|
+
|
|
166
|
+
renderer.render_all_to_disk(scene,save_path)
|
|
167
|
+
|
|
168
|
+
time_end_loop = time.perf_counter()
|
|
169
|
+
time_to_disk = time_end_loop - time_start_loop
|
|
170
|
+
|
|
171
|
+
print("TO DISK: Raster Loop End")
|
|
172
|
+
print(80*"=")
|
|
173
|
+
|
|
174
|
+
|
|
140
175
|
print("PERFORMANCE")
|
|
141
|
-
print(f"Total frames = {
|
|
142
|
-
print(f"Total render time = {
|
|
143
|
-
print(f"Time per frame = {(
|
|
176
|
+
print(f"Total frames = {frames_total}")
|
|
177
|
+
print(f"IN MEM: Total render time = {time_inmem:.4f} s")
|
|
178
|
+
print(f"IN MEM: Time per frame = {(time_inmem/frames_total):.4f} s")
|
|
179
|
+
print(f"TO DISK: Total render time = {time_to_disk:.4f} s")
|
|
180
|
+
print(f"TO DISK: Time per frame = {(time_to_disk/frames_total):.4f} s")
|
|
144
181
|
print(80*"=")
|
|
145
182
|
|
|
183
|
+
|
|
146
184
|
plot_on = True
|
|
147
185
|
if plot_on:
|
|
148
|
-
(fig,ax) = pyv.plot_field_image(images[:,:,-1,0],
|
|
186
|
+
(fig,ax) = pyv.plot_field_image(images[1][:,:,-1,0],
|
|
149
187
|
title_str="Disp. y, [mm]")
|
|
150
|
-
|
|
188
|
+
|
|
189
|
+
plt.show()
|
|
151
190
|
|
|
152
191
|
if __name__ == "__main__":
|
|
153
192
|
main()
|
|
@@ -13,10 +13,6 @@ import pyvale as pyv
|
|
|
13
13
|
import imagebenchmarks as ib
|
|
14
14
|
|
|
15
15
|
def main() -> None:
|
|
16
|
-
"""pyvale example: rasterisation field renderer
|
|
17
|
-
----------------------------------------------------------------------------
|
|
18
|
-
- TODO
|
|
19
|
-
"""
|
|
20
16
|
print()
|
|
21
17
|
print(80*"=")
|
|
22
18
|
print("RASTER CYTHON FILE (should be *.so on Linux):")
|
|
@@ -24,23 +20,20 @@ def main() -> None:
|
|
|
24
20
|
print(80*"=")
|
|
25
21
|
print()
|
|
26
22
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
benchmark = True
|
|
23
|
+
benchmark = False
|
|
30
24
|
if not benchmark:
|
|
31
|
-
|
|
32
25
|
# This a path to an exodus *.e output file from MOOSE, this can be
|
|
33
26
|
# replaced with a path to your own simulation file
|
|
34
27
|
#sim_path = Path.home()/"pyvale"/"src"/"pyvale"/"simcases"/"case26_out.e"
|
|
35
28
|
|
|
36
29
|
sim_path = pyv.DataSet.render_simple_block_path()
|
|
37
|
-
sim_path = pyv.DataSet.render_mechanical_3d_path()
|
|
30
|
+
#sim_path = pyv.DataSet.render_mechanical_3d_path()
|
|
38
31
|
sim_data = mh.ExodusReader(sim_path).read_all_sim_data()
|
|
39
32
|
|
|
40
33
|
disp_comps = ("disp_x","disp_y","disp_z")
|
|
41
34
|
|
|
42
35
|
# Scale m -> mm
|
|
43
|
-
sim_data = pyv.scale_length_units(sim_data,disp_comps
|
|
36
|
+
sim_data = pyv.scale_length_units(1000.0,sim_data,disp_comps)
|
|
44
37
|
|
|
45
38
|
print()
|
|
46
39
|
print(f"{np.max(np.abs(sim_data.node_vars['disp_x']))=}")
|
|
@@ -65,7 +58,7 @@ def main() -> None:
|
|
|
65
58
|
fov_scale_factor: float = 1.1
|
|
66
59
|
|
|
67
60
|
(roi_pos_world,
|
|
68
|
-
cam_pos_world) = pyv.CameraTools.
|
|
61
|
+
cam_pos_world) = pyv.CameraTools.pos_fill_frame(
|
|
69
62
|
coords_world=render_mesh.coords,
|
|
70
63
|
pixel_num=pixel_num,
|
|
71
64
|
pixel_size=pixel_size,
|
|
@@ -151,7 +144,7 @@ def main() -> None:
|
|
|
151
144
|
|
|
152
145
|
(image_buffer,
|
|
153
146
|
depth_buffer,
|
|
154
|
-
elems_in_image) = pyv.rastercyth.
|
|
147
|
+
elems_in_image) = pyv.rastercyth.raster_static_frame(
|
|
155
148
|
render_mesh.coords,
|
|
156
149
|
render_mesh.connectivity,
|
|
157
150
|
fields_render,
|
|
@@ -171,7 +164,7 @@ def main() -> None:
|
|
|
171
164
|
|
|
172
165
|
#===========================================================================
|
|
173
166
|
# PLOTTING
|
|
174
|
-
plot_on =
|
|
167
|
+
plot_on = False
|
|
175
168
|
plot_field = 0
|
|
176
169
|
|
|
177
170
|
# depth_to_plot = np.copy(np.asarray(depth_buffer[:,:,plot_frame]))
|
|
@@ -28,7 +28,7 @@ def main() -> None:
|
|
|
28
28
|
disp_comps = ("disp_x","disp_y","disp_z")
|
|
29
29
|
|
|
30
30
|
# Scale m -> mm
|
|
31
|
-
sim_data = pyv.scale_length_units(sim_data,disp_comps
|
|
31
|
+
sim_data = pyv.scale_length_units(1000.0,sim_data,disp_comps)
|
|
32
32
|
|
|
33
33
|
print()
|
|
34
34
|
print(f"{np.max(np.abs(sim_data.node_vars['disp_x']))=}")
|
|
@@ -66,7 +66,7 @@ def main() -> None:
|
|
|
66
66
|
fov_scale_factor: float = 1.1
|
|
67
67
|
|
|
68
68
|
(roi_pos_world,
|
|
69
|
-
cam_pos_world) = pyv.CameraTools.
|
|
69
|
+
cam_pos_world) = pyv.CameraTools.pos_fill_frame(
|
|
70
70
|
coords_world=render_mesh.coords,
|
|
71
71
|
pixel_num=pixel_num,
|
|
72
72
|
pixel_size=pixel_size,
|
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
5
|
# ==============================================================================
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
7
|
import time
|
|
10
8
|
import numpy as np
|
|
11
9
|
from scipy.spatial.transform import Rotation
|
|
@@ -32,7 +30,7 @@ def main() -> None:
|
|
|
32
30
|
disp_comps = ("disp_x","disp_y","disp_z")
|
|
33
31
|
|
|
34
32
|
# Scale m -> mm
|
|
35
|
-
sim_data = pyv.scale_length_units(sim_data,disp_comps
|
|
33
|
+
sim_data = pyv.scale_length_units(1000.0,sim_data,disp_comps)
|
|
36
34
|
|
|
37
35
|
print()
|
|
38
36
|
print(f"{np.max(np.abs(sim_data.node_vars['disp_x']))=}")
|
|
@@ -70,7 +68,7 @@ def main() -> None:
|
|
|
70
68
|
fov_scale_factor: float = 1.1
|
|
71
69
|
|
|
72
70
|
(roi_pos_world,
|
|
73
|
-
cam_pos_world) = pyv.CameraTools.
|
|
71
|
+
cam_pos_world) = pyv.CameraTools.pos_fill_frame(
|
|
74
72
|
coords_world=render_mesh.coords,
|
|
75
73
|
pixel_num=pixel_num,
|
|
76
74
|
pixel_size=pixel_size,
|
pyvale/imagedef2d.py
CHANGED
|
@@ -20,6 +20,7 @@ from scipy import ndimage
|
|
|
20
20
|
from pyvale.rasternp import edge_function, RasterNP
|
|
21
21
|
from pyvale.cameradata2d import CameraData2D
|
|
22
22
|
from pyvale.cameratools import CameraTools
|
|
23
|
+
from pyvale.imagetools import ImageTools
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
@dataclass(slots=True)
|
|
@@ -436,9 +437,9 @@ class ImageDef2D:
|
|
|
436
437
|
print_on=print_on)
|
|
437
438
|
|
|
438
439
|
save_file = id_opts.save_path / str(f'{id_opts.save_tag}_'+
|
|
439
|
-
f'{
|
|
440
|
+
f'{ImageTools.get_num_str(im_num=ff,width=4)}'+
|
|
440
441
|
'.tiff')
|
|
441
|
-
|
|
442
|
+
ImageTools.save_tiff(save_file,def_image,cam_data.bits)
|
|
442
443
|
|
|
443
444
|
if print_on:
|
|
444
445
|
tocf = time.perf_counter()
|