Skip to content

Commit 4edb718

Browse files
javohaLeguark
authored andcommitted
First completely working example of MC
1 parent 4ffe36d commit 4edb718

File tree

2 files changed

+50
-29
lines changed

2 files changed

+50
-29
lines changed

gempy/modules/mesh_extranction/marching_cubes.py

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,31 @@ def set_meshes_with_marching_cubes(model: GeoModel) -> None:
3434

3535
output_lvl0: list[InterpOutput] = model.solutions.octrees_output[0].outputs_centers
3636

37+
# TODO: How to get this properly in gempy
38+
# get a list of indices of the lithological groups
39+
lith_group_indices = []
40+
fault_group_indices = []
41+
index = 0
42+
for i in model.structural_frame.structural_groups:
43+
if i.is_fault:
44+
fault_group_indices.append(index)
45+
else:
46+
lith_group_indices.append(index)
47+
index += 1
48+
49+
# extract scalar field values at surface points
50+
scalar_values = model.solutions.raw_arrays.scalar_field_at_surface_points
51+
52+
# TODO: Here I just get my own masks, cause the gempy masks dont work as expected
53+
masks = []
54+
masks.append(np.ones_like(model.solutions.raw_arrays.scalar_field_matrix[0].reshape(model.grid.regular_grid.resolution),
55+
dtype=bool))
56+
for idx in lith_group_indices:
57+
mask = model.solutions.raw_arrays.scalar_field_matrix[idx].reshape(model.grid.regular_grid.resolution) <= \
58+
scalar_values[idx][-1]
59+
60+
masks.append(mask)
61+
3762
# TODO: Attribute of element.scalar_field was None, changed it to scalar field value of that element
3863
# This should probably be done somewhere else and maybe renamed to scalar_field_value?
3964
# This is just the most basic solution to be clear what I did
@@ -46,33 +71,39 @@ def set_meshes_with_marching_cubes(model: GeoModel) -> None:
4671
element.scalar_field = model.solutions.scalar_field_at_surface_points[counter]
4772
counter += 1
4873

74+
# Trying to use the exiting gempy masks
75+
# masks = []
76+
# masks.append(
77+
# np.ones_like(model.solutions.raw_arrays.scalar_field_matrix[0].reshape(model.grid.regular_grid.resolution),
78+
# dtype=bool))
79+
# for idx in lith_group_indices:
80+
# output_group: InterpOutput = output_lvl0[idx]
81+
# masks.append(output_group.mask_components[8:].reshape(model.grid.regular_grid.resolution))
82+
83+
non_fault_counter = 0
4984
for e, structural_group in enumerate(structural_groups):
5085
if e >= len(output_lvl0):
5186
continue
52-
53-
output_group: InterpOutput = output_lvl0[e]
5487

55-
scalar_field_matrix = output_group.exported_fields_dense_grid.scalar_field
88+
# Outdated?
89+
# output_group: InterpOutput = output_lvl0[e]
90+
# scalar_field_matrix = output_group.exported_fields_dense_grid.scalar_field
5691

57-
# TODO: get the correct mask
58-
# for some reason output_group.mask_components has 8 more entries then necessary
59-
# output_group.mask_components[8:] seems to be correct for plotting when transposed
60-
# at least for the 2D slice plot. But it does not work for the marching cubes
61-
mask = np.invert(output_group.mask_components[8:].reshape(model.grid.regular_grid.resolution).T)
92+
# Specify the correct scalar field, can be removed in the future
93+
scalar_field = model.solutions.raw_arrays.scalar_field_matrix[e].reshape(model.grid.regular_grid.resolution)
6294

63-
# plot slice of mask as sanity check
64-
import matplotlib.pyplot as plt
65-
plt.imshow(mask[:, 5, :])
66-
# set extent to match the model
67-
plt.xlim(0, 40)
68-
plt.ylim(0, 20)
69-
plt.show()
95+
# pick mask depending on whether the structural group is a fault or not
96+
if structural_group.is_fault:
97+
mask = np.ones_like(scalar_field, dtype=bool)
98+
else:
99+
mask = masks[non_fault_counter] # TODO: I need the entry without faults here
100+
non_fault_counter += 1
70101

71102
for element in structural_group.elements:
72103
extract_mesh_for_element(
73104
structural_element=element,
74105
regular_grid=regular_grid,
75-
scalar_field=scalar_field_matrix,
106+
scalar_field=scalar_field,
76107
mask=mask
77108
)
78109

@@ -94,22 +125,12 @@ def extract_mesh_for_element(structural_element: StructuralElement,
94125
mask : np.ndarray, optional
95126
Optional mask to restrict the mesh extraction to specific regions.
96127
"""
97-
# Apply mask if provided
98-
volume = scalar_field.reshape(regular_grid.resolution)
99-
100-
# TODO: We need to pass the mask arrays to the marching cubes to account for discontinuities. The mask array are
101-
# in InterpOutput too if I remember correctly.
102-
103-
# TODO: Do we apply the mask before or add it as an argument to the marching cubes function?
104-
# if mask is not None:
105-
# volume = volume * mask
106-
107128
# Extract mesh using marching cubes
108129
verts, faces, _, _ = measure.marching_cubes(
109-
volume=volume,
130+
volume=scalar_field,
110131
level=structural_element.scalar_field,
111132
spacing=(regular_grid.dx, regular_grid.dy, regular_grid.dz),
112-
mask=None
133+
mask=mask
113134
)
114135

115136
# Adjust vertices to correct coordinates in the model's extent

test/test_modules/test_marching_cubes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ def test_marching_cubes_implementation():
4444
gtv: gpv.GemPyToVista = gpv.plot_3d(
4545
model=model,
4646
show_data=True,
47-
image=True,
47+
image=False,
4848
show=True
4949
)

0 commit comments

Comments
 (0)