@@ -22,36 +22,106 @@ def set_meshes_with_marching_cubes(model: GeoModel) -> None:
22
22
If the model solutions do not contain dense grid data.
23
23
"""
24
24
# Verify that solutions contain dense grid data
25
- if ( model .solutions is None or
26
- model .solutions . block_solution_type != RawArraysSolution . BlockSolutionType . DENSE_GRID ) :
25
+ solution_not_having_dense : bool = model .solutions . block_solution_type != RawArraysSolution . BlockSolutionType . DENSE_GRID
26
+ if model .solutions is None or solution_not_having_dense :
27
27
raise ValueError ("Model solutions must contain dense grid data for mesh extraction." )
28
-
28
+
29
29
regular_grid : RegularGrid = model .grid .regular_grid
30
30
structural_groups : list [StructuralGroup ] = model .structural_frame .structural_groups
31
-
31
+
32
32
if not model .solutions .octrees_output or not model .solutions .octrees_output [0 ].outputs_centers :
33
33
raise ValueError ("No interpolation outputs available for mesh extraction." )
34
-
34
+
35
35
output_lvl0 : list [InterpOutput ] = model .solutions .octrees_output [0 ].outputs_centers
36
36
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
37
70
for e , structural_group in enumerate (structural_groups ):
38
71
if e >= len (output_lvl0 ):
39
72
continue
40
-
41
- output_group : InterpOutput = output_lvl0 [e ]
42
- scalar_field_matrix = output_group .exported_fields_dense_grid .scalar_field
43
-
73
+
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 )
84
+ else :
85
+ mask = masks [non_fault_counter ] # TODO: I need the entry without faults here
86
+ non_fault_counter += 1
87
+
44
88
for element in structural_group .elements :
45
89
extract_mesh_for_element (
46
90
structural_element = element ,
47
91
regular_grid = regular_grid ,
48
- scalar_field = scalar_field_matrix
92
+ scalar_field = scalar_field ,
93
+ mask = mask
49
94
)
50
95
51
96
52
- def extract_mesh_for_element (structural_element : StructuralElement ,
53
- regular_grid : RegularGrid ,
54
- scalar_field : np .ndarray ,
97
+ # TODO: This should be set somewhere else
98
+ def _set_scalar_field_to_element (model , output_lvl0 , structural_groups ):
99
+ counter = 0
100
+ for e , structural_group in enumerate (structural_groups ):
101
+ if e >= len (output_lvl0 ):
102
+ continue
103
+
104
+ for element in structural_group .elements :
105
+ element .scalar_field = model .solutions .scalar_field_at_surface_points [counter ]
106
+ counter += 1
107
+
108
+
109
+ # TODO: This should be set somewhere else
110
+ def _get_masking_arrays (lith_group_indices , model , scalar_values ):
111
+ masks = []
112
+ masks .append (np .ones_like (model .solutions .raw_arrays .scalar_field_matrix [0 ].reshape (model .grid .regular_grid .resolution ),
113
+ dtype = bool ))
114
+ for idx in lith_group_indices :
115
+ mask = model .solutions .raw_arrays .scalar_field_matrix [idx ].reshape (model .grid .regular_grid .resolution ) <= \
116
+ scalar_values [idx ][- 1 ]
117
+
118
+ masks .append (mask )
119
+ return masks
120
+
121
+
122
+ def extract_mesh_for_element (structural_element : StructuralElement ,
123
+ regular_grid : RegularGrid ,
124
+ scalar_field : np .ndarray ,
55
125
mask : Optional [np .ndarray ] = None ) -> None :
56
126
"""Extract a mesh for a single structural element using marching cubes.
57
127
@@ -66,23 +136,19 @@ def extract_mesh_for_element(structural_element: StructuralElement,
66
136
mask : np.ndarray, optional
67
137
Optional mask to restrict the mesh extraction to specific regions.
68
138
"""
69
- # Apply mask if provided
70
- volume = scalar_field .reshape (regular_grid .resolution )
71
- if mask is not None :
72
- volume = volume * mask
73
-
74
139
# Extract mesh using marching cubes
75
140
verts , faces , _ , _ = measure .marching_cubes (
76
- volume = volume ,
141
+ volume = scalar_field ,
77
142
level = structural_element .scalar_field ,
78
- spacing = (regular_grid .dx , regular_grid .dy , regular_grid .dz )
143
+ spacing = (regular_grid .dx , regular_grid .dy , regular_grid .dz ),
144
+ mask = mask
79
145
)
80
-
146
+
81
147
# Adjust vertices to correct coordinates in the model's extent
82
148
verts = (verts + [regular_grid .extent [0 ],
83
149
regular_grid .extent [2 ],
84
150
regular_grid .extent [4 ]])
85
151
86
152
# Store mesh in the structural element
87
153
structural_element .vertices = verts
88
- structural_element .edges = faces
154
+ structural_element .edges = faces
0 commit comments