Skip to content

Commit fd3ce56

Browse files
committed
[ENH] Refactor marching cubes mesh extraction logic
Simplified and clarified the mesh extraction code by removing outdated comments, unused methods, and redundant handling of masks. Added proper mask reshaping and updated marching_cubes function parameters for improved reliability and efficiency. Adjusted test cases accordingly.
1 parent 07c88cd commit fd3ce56

File tree

2 files changed

+12
-75
lines changed

2 files changed

+12
-75
lines changed

gempy/modules/mesh_extranction/marching_cubes.py

Lines changed: 11 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -34,92 +34,27 @@ 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 = _get_masking_arrays(lith_group_indices, model, scalar_values)
54-
55-
# TODO: Attribute of element.scalar_field was None, changed it to scalar field value of that element
56-
# This should probably be done somewhere else and maybe renamed to scalar_field_value?
57-
# This is just the most basic solution to be clear what I did
58-
# _set_scalar_field_to_element(model, output_lvl0, structural_groups)
59-
60-
# Trying to use the exiting gempy masks
61-
# masks = []
62-
# masks.append(
63-
# np.ones_like(model.solutions.raw_arrays.scalar_field_matrix[0].reshape(model.grid.regular_grid.resolution),
64-
# dtype=bool))
65-
# for idx in lith_group_indices:
66-
# output_group: InterpOutput = output_lvl0[idx]
67-
# masks.append(output_group.mask_components[8:].reshape(model.grid.regular_grid.resolution))
68-
69-
non_fault_counter = 0
7037
for e, structural_group in enumerate(structural_groups):
7138
if e >= len(output_lvl0):
7239
continue
7340

74-
# Outdated?
75-
# output_group: InterpOutput = output_lvl0[e]
76-
# scalar_field_matrix = output_group.exported_fields_dense_grid.scalar_field
77-
78-
# Specify the correct scalar field, can be removed in the future
79-
scalar_field = model.solutions.raw_arrays.scalar_field_matrix[e].reshape(model.grid.regular_grid.resolution)
80-
81-
# pick mask depending on whether the structural group is a fault or not
82-
if structural_group.is_fault:
83-
mask = np.ones_like(scalar_field, dtype=bool)
41+
output_group: InterpOutput = output_lvl0[e]
42+
scalar_field_matrix = output_group.exported_fields_dense_grid.scalar_field
43+
if structural_group.is_fault is False:
44+
slice_: slice = output_group.grid.dense_grid_slice
45+
mask = output_group.combined_scalar_field.squeezed_mask_array[slice_]
8446
else:
85-
mask = masks[non_fault_counter] # TODO: I need the entry without faults here
86-
non_fault_counter += 1
47+
mask = np.ones_like(scalar_field_matrix, dtype=bool)
8748

8849
for element in structural_group.elements:
8950
extract_mesh_for_element(
9051
structural_element=element,
9152
regular_grid=regular_grid,
92-
scalar_field=scalar_field,
53+
scalar_field=scalar_field_matrix,
9354
mask=mask
9455
)
9556

9657

97-
# TODO: This should be set somewhere else
98-
def _set_scalar_field_to_element(model, output_lvl0, structural_groups):
99-
element: StructuralElement
100-
counter = 0
101-
for e, structural_group in enumerate(structural_groups):
102-
if e >= len(output_lvl0):
103-
continue
104-
105-
for element in structural_group.elements:
106-
element.scalar_field_at_interface = model.solutions.scalar_field_at_surface_points[counter]
107-
counter += 1
108-
109-
110-
# TODO: This should be set somewhere else
111-
def _get_masking_arrays(lith_group_indices, model, scalar_values):
112-
masks = []
113-
masks.append(np.ones_like(model.solutions.raw_arrays.scalar_field_matrix[0].reshape(model.grid.regular_grid.resolution),
114-
dtype=bool))
115-
for idx in lith_group_indices:
116-
mask = model.solutions.raw_arrays.scalar_field_matrix[idx].reshape(model.grid.regular_grid.resolution) <= \
117-
scalar_values[idx][-1]
118-
119-
masks.append(mask)
120-
return masks
121-
122-
12358
def extract_mesh_for_element(structural_element: StructuralElement,
12459
regular_grid: RegularGrid,
12560
scalar_field: np.ndarray,
@@ -139,10 +74,12 @@ def extract_mesh_for_element(structural_element: StructuralElement,
13974
"""
14075
# Extract mesh using marching cubes
14176
verts, faces, _, _ = measure.marching_cubes(
142-
volume=scalar_field,
77+
volume=scalar_field.reshape(regular_grid.resolution),
14378
level=structural_element.scalar_field_at_interface,
14479
spacing=(regular_grid.dx, regular_grid.dy, regular_grid.dz),
145-
mask=mask
80+
mask=mask.reshape(regular_grid.resolution) if mask is not None else None,
81+
allow_degenerate=False,
82+
method="lewiner"
14683
)
14784

14885
# 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
@@ -52,6 +52,6 @@ def test_marching_cubes_implementation():
5252
gtv: gpv.GemPyToVista = gpv.plot_3d(
5353
model=model,
5454
show_data=True,
55-
image=True,
55+
image=False,
5656
show=True
5757
)

0 commit comments

Comments
 (0)