Skip to content

Commit f34b3cd

Browse files
committed
updates scripts
1 parent 73ecf94 commit f34b3cd

File tree

3 files changed

+272
-39
lines changed

3 files changed

+272
-39
lines changed

utils/Visualization/Blender/python_blender/plot_with_blender.py

Lines changed: 112 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,29 @@
6969
mesh_scale_factor = 1.0
7070
mesh_origin = [0.0,0.0,0.0]
7171

72+
# vertical exaggeration factor
73+
vertical_exaggeration = None
74+
7275
## sea-level plane
7376
use_sea_level_plane = True
7477

7578
## transparent sea-level plane
7679
use_transparent_sea_level_plane = False
7780

81+
# shallow coast lines can lead to z-buffering issues with the sea-level plane.
82+
# as a work-around, one can try to add a boolean modifier to cut the plane with the main mesh object.
83+
# this might however lead to other issues... left here to give a try.
84+
add_sea_level_plane_modifier = False
85+
86+
# shifts point above/below sea-level slightly up/down to get a sharper and steeper coastline for sea-level plane
87+
sea_level_separation = None
88+
7889
# baseline shift for buildings (to move above SPECFEM mesh)
7990
shift_building_baseline = 0.0 # 0.0==no-shift default, or e.g. --shift-building-baseline=0.0005
8091

92+
# location labels (white or black)
93+
location_labels_color = (0.05,0.05,0.05,1) # white (0.9,0.9,0.9,1), black (0.05,0.05,0.05,1)
94+
8195
# rendering output
8296
suppress_renderer_output = False
8397

@@ -486,6 +500,40 @@ def setup_color_table(colormap, data_min, data_max):
486500
[0.5, 0.0, 0.0 ], # X+ : darkred
487501
]
488502

503+
elif colormap == 14:
504+
# custom shakeUSGSblack
505+
# starts with darker gray than the default USGS
506+
print(" color map: shakeUSGSblack")
507+
colors_rgb = [
508+
[0.15, 0.15, 0.15], # black
509+
[0.3, 0.3, 0.35],
510+
[0.77, 0.81, 1.0 ], # II-III : light purple
511+
[0.5, 1.0, 0.98], # IV: turquoise
512+
[0.5, 1.0, 0.54], # V : green
513+
[1.0, 0.98, 0.0 ], # VI : yellow
514+
[1.0, 0.77, 0.0 ], # VII : orange
515+
[0.99, 0.52, 0.0 ], # VIII: darkorange
516+
[0.98, 0.0, 0.0 ], # IX : red
517+
[0.5, 0.0, 0.0 ], # X+ : darkred
518+
]
519+
520+
elif colormap == 15:
521+
# custom shake
522+
# starts with dark colors than more light
523+
print(" color map: shakeDark")
524+
colors_rgb = [
525+
[0.15, 0.15, 0.15], # black
526+
[0.3, 0.3, 0.35], #
527+
[0.5, 0.5, 0.7], # II-III
528+
[0.75, 0.75, 0.75], # IV
529+
[1.0, 1.0, 1.0], # V white
530+
[1.0, 0.98, 0.0 ], # VI yellow
531+
[1.0, 0.77, 0.0 ], # VII orange
532+
[0.99, 0.52, 0.0 ], # VIII darkorange
533+
[0.98, 0.0, 0.0 ], # IX red
534+
[0.7, 0.0, 0.0 ], # X+ darkred
535+
]
536+
489537
else:
490538
print("Warning: colormap with type {} is not supported, exiting...".format(colormap))
491539
sys.exit(1)
@@ -513,6 +561,7 @@ def setup_color_table(colormap, data_min, data_max):
513561

514562
def convert_vtk_to_obj(vtk_file: str="", colormap: int=0, color_max=None) -> str:
515563
global mesh_scale_factor,mesh_origin
564+
global vertical_exaggeration,sea_level_separation
516565

517566
# Path to your .vtu file
518567
print("converting vtk file: ",vtk_file)
@@ -611,15 +660,35 @@ def convert_vtk_to_obj(vtk_file: str="", colormap: int=0, color_max=None) -> str
611660
print(" scale factor :",mesh_scale_factor)
612661
print("")
613662

663+
if vertical_exaggeration != None:
664+
print(" using vertical exaggeration factor: ",vertical_exaggeration)
665+
print("")
666+
667+
if sea_level_separation != None:
668+
print(" using sea-level separation shift: ",sea_level_separation)
669+
print("")
670+
614671
# creates an array to store scaled points
615672
scaled_points = vtk.vtkPoints()
616673

617674
# Loop through each point, scale its coordinates, and add it to the new points array
618675
for i in range(num_points):
619676
# translation by origin
620677
point = np.array(points.GetPoint(i)) - mesh_origin
678+
621679
# uniform scaling
622680
scaled_point = point * mesh_scale_factor
681+
682+
# vertical exaggeration
683+
if vertical_exaggeration != None:
684+
scaled_point[2] = scaled_point[2] * vertical_exaggeration
685+
686+
# shift points above/below sea-level
687+
if sea_level_separation != None:
688+
# shift points above
689+
if scaled_point[2] > 0.0: scaled_point[2] += sea_level_separation
690+
if scaled_point[2] < 0.0: scaled_point[2] -= sea_level_separation
691+
623692
# stores updated points
624693
scaled_points.InsertNextPoint(scaled_point)
625694

@@ -1501,7 +1570,7 @@ def add_plane() -> None:
15011570
"""
15021571
adds a plane at sea-level
15031572
"""
1504-
global use_sea_level_plane,use_transparent_sea_level_plane
1573+
global use_sea_level_plane,use_transparent_sea_level_plane,add_sea_level_plane_modifier
15051574
global close_up_view
15061575

15071576
# checks if anything to do
@@ -1539,6 +1608,31 @@ def add_plane() -> None:
15391608
else:
15401609
mat.diffuse_color = (0.135, 0.135, 0.135, 1) # gray for better contrast
15411610

1611+
# adds the Boolean modifier
1612+
if add_sea_level_plane_modifier:
1613+
print(" adding sea-level plane - modifier using difference")
1614+
boolean_modifier = plane_object.modifiers.new(name="Boolean", type='BOOLEAN')
1615+
1616+
# Set the operation type
1617+
boolean_modifier.operation = 'DIFFERENCE'
1618+
1619+
# Set the operand object if provided
1620+
mesh_object = bpy.data.objects['output']
1621+
if mesh_object:
1622+
boolean_modifier.object = mesh_object
1623+
else:
1624+
print(" Warning: mesh object 'output' not found.")
1625+
1626+
# Set the solver type
1627+
boolean_modifier.solver = 'FAST' # 'FAST' or 'EXACT'
1628+
1629+
# some further optimizations for the exact solver
1630+
if boolean_modifier.solver == 'EXACT':
1631+
#boolean_modifier.use_self = True # self-intersection
1632+
#boolean_modifier.use_hole_tolerant = True # better results when more tolerant, but slower
1633+
pass
1634+
print(" modifier added")
1635+
15421636
plane_object.data.materials.append(mat)
15431637

15441638

@@ -1606,7 +1700,8 @@ def add_location_labels(locations_file: str="") -> None:
16061700
"""
16071701
adds locations defined in file
16081702
"""
1609-
global centered_view
1703+
global centered_view,use_white_location_labels
1704+
global location_labels_color
16101705

16111706
# checks if anything to do
16121707
if len(locations_file) == 0: return
@@ -1735,7 +1830,7 @@ def add_location_labels(locations_file: str="") -> None:
17351830
# Set text material
17361831
text_material = bpy.data.materials.new(name="TextMaterial")
17371832
text_material.use_nodes = True
1738-
text_material.node_tree.nodes["Principled BSDF"].inputs["Base Color"].default_value = (0.05, 0.05, 0.05, 1)
1833+
text_material.node_tree.nodes["Principled BSDF"].inputs["Base Color"].default_value = location_labels_color
17391834
text_material.node_tree.nodes["Principled BSDF"].inputs["Alpha"].default_value = 1 # transparency
17401835
text_material.node_tree.nodes["Principled BSDF"].inputs["Specular"].default_value = 0 # Reduce shine
17411836
text_material.shadow_method = 'NONE' # Blender 3.x
@@ -2207,10 +2302,10 @@ def plot_with_blender(vtk_file: str="", image_title: str="", colormap: int=0, co
22072302

22082303

22092304
def usage() -> None:
2210-
print("usage: ./plot_with_blender.py [--vtk_file=file] [--title=my_mesh_name] [--colormap=val] [--color-max=val]")
2305+
print("usage: ./plot_with_blender.py [--vtk_file=file] [--title=my_mesh_name] [--colormap=val] [--color-max=val] [--vertical-exaggeration=val]")
22112306
print(" [--buildings=file] [--shift-buildings=val]")
22122307
print(" [--locations=file] [--utm-zone=ZoneNumber]")
2213-
print(" [--no-sea-level] [--transparent-sea-level]")
2308+
print(" [--no-sea-level] [--transparent-sea-level] [--sea-level-separation=val]")
22142309
print(" [--centered] [--closeup] [--small] [--anim]")
22152310
print(" [--with-cycles/--no-cycles] [--suppress]")
22162311
print(" [--help]")
@@ -2222,13 +2317,16 @@ def usage() -> None:
22222317
print(" 10==shakeGreen /11==shakeRed /12==shakeUSGS /13==shakeUSGSgray")
22232318
print(" (default is shakeUSGSgray for shakemaps)")
22242319
print(" --color-max - fixes maximum value of colormap for moviedata to val, e.g., 1.e-7)")
2320+
print(" --vertical-exaggeration - factor to scales vertical dimension")
22252321
print("")
22262322
print(" --buildings - mesh file (.ply) with buildings to visualize for the area")
22272323
print(" --shift-buildings - moves buildings up, e.g., a factor 0.0005 (default is no shift==0.0)")
22282324
print(" --locations - file with location labels (using a format: #name #lat #lon)")
2325+
print(" --white-labels - use white text for location labels")
22292326
print(" --utm_zone - use specified UTM zone number (1-60) with (+) for Northern (-) for Southern hemisphere (e.g., -58)")
22302327
print(" --no-sea-level - turns off sea-level plane")
22312328
print(" --transparent-sea-level - turns on transparency for sea-level plane")
2329+
print(" --sea-level-separation - shift factor to move up/down points at sea-level for better sea-level separation")
22322330
print("")
22332331
print(" --centered - centered camera view (looking from top straight down)")
22342332
print(" --closeup - sets camera view closer to center of model")
@@ -2247,6 +2345,8 @@ def usage() -> None:
22472345
image_title = ""
22482346
color_max = None
22492347
colormap = -1
2348+
vertical_exaggeration = None
2349+
sea_level_separation_shift = None
22502350
buildings_file = ""
22512351
locations_file = ""
22522352
animation = False
@@ -2293,6 +2393,8 @@ def usage() -> None:
22932393
use_sea_level_plane = False
22942394
elif "--transparent-sea-level" in arg:
22952395
use_transparent_sea_level_plane = True
2396+
elif "--sea-level-separation=" in arg:
2397+
sea_level_separation = float(arg.split('=')[1])
22962398
elif "--vtk_file=" in arg:
22972399
vtk_file = arg.split('=')[1]
22982400
elif "--background-dark" in arg:
@@ -2303,12 +2405,15 @@ def usage() -> None:
23032405
world_background_color = (0,0,0,1) # black world background
23042406
elif "--locations=" in arg:
23052407
locations_file = arg.split('=')[1]
2408+
elif "--white-labels" in arg:
2409+
location_labels_color = (0.9,0.9,0.9,1) # white location labels
23062410
elif "--utm_zone=" in arg:
2307-
str_val = arg.split('=')[1]
2308-
utm_zone = int(str_val)
2411+
utm_zone = int(arg.split('=')[1])
23092412
if abs(utm_zone) < 1 or utm_zone > 60:
23102413
print(f"Invalid UTM zone entered: {utm_zone} - Please use zones from +/- [1,60]")
23112414
sys.exit(1)
2415+
elif "--vertical-exaggeration=" in arg:
2416+
vertical_exaggeration = float(arg.split('=')[1])
23122417
elif i >= 8:
23132418
print("argument not recognized: ",arg)
23142419

utils/scripts/run_convert_IRIS_EMC_netCDF_2_tomo.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,14 @@ def geo2utm(lon,lat,zone):
237237
PI = math.pi
238238
degrad = PI/180.0
239239
raddeg = 180.0/PI
240-
semimaj = 6378206.4
241-
semimin = 6356583.8
240+
241+
# Clarke 1866
242+
#semimaj = 6378206.4
243+
#semimin = 6356583.8
244+
# WGS84 (World Geodetic System 1984) - default
245+
semimaj = 6378137.0
246+
semimin = 6356752.314245
247+
242248
scfa = 0.9996
243249

244250
# some extracts about UTM:
@@ -1196,16 +1202,26 @@ def netCDF_2_tomo(input_file,UTM_zone=None,mesh_area=None,maximum_depth=None):
11961202
if 'geospatial_lat_min' in global_vars:
11971203
model_lat_min = model_data.geospatial_lat_min
11981204
model_lat_max = model_data.geospatial_lat_max
1205+
if isinstance(model_lat_min,str): model_lat_min = float(model_lat_min)
1206+
if isinstance(model_lat_max,str): model_lat_max = float(model_lat_max)
1207+
11991208
if model_data.geospatial_lat_resolution:
12001209
model_dlat = model_data.geospatial_lat_resolution
1210+
if isinstance(model_dlat,str): model_dlat = float(model_dlat)
12011211

12021212
model_lon_min = model_data.geospatial_lon_min
12031213
model_lon_max = model_data.geospatial_lon_max
1214+
if isinstance(model_lon_min,str): model_lon_min = float(model_lon_min)
1215+
if isinstance(model_lon_max,str): model_lon_max = float(model_lon_max)
1216+
12041217
if model_data.geospatial_lon_resolution:
12051218
model_dlon = model_data.geospatial_lon_resolution
1219+
if isinstance(model_dlon,str): model_dlon = float(model_dlon)
12061220

12071221
model_depth_min = model_data.geospatial_vertical_min
12081222
model_depth_max = model_data.geospatial_vertical_max
1223+
if isinstance(model_depth_min,str): model_depth_min = float(model_depth_min)
1224+
if isinstance(model_depth_max,str): model_depth_max = float(model_depth_max)
12091225

12101226
print(" model range:")
12111227
print(" lon min/max = {} / {}".format(model_lon_min,model_lon_max))
@@ -1608,11 +1624,11 @@ def netCDF_2_tomo(input_file,UTM_zone=None,mesh_area=None,maximum_depth=None):
16081624

16091625
# file output requires density in kg/m^3
16101626
# determines scaling factor
1611-
if model_data.variables[var_name_rho].units in ["g.cm-3","g/cm3"]:
1627+
if model_data.variables[var_name_rho].units in ["g.cm-3","g/cm3","g/cm^3"]:
16121628
# given in g/cm^3 -> kg/m^3
16131629
# rho [kg/m^3] = rho * 1000 [g/cm^3]
16141630
unit_scale = 1000
1615-
elif model_data.variables[var_name_rho].units in ["kg.cm-3","kg/cm3"]:
1631+
elif model_data.variables[var_name_rho].units in ["kg.cm-3","kg/cm3","kg/cm^3"]:
16161632
# given in kg/cm^3 -> kg/m^3
16171633
# rho [kg/m^3] = rho * 1000000 [kg/cm^3]
16181634
unit_scale = 1000000

0 commit comments

Comments
 (0)