11import copy
2- from typing import List
3-
2+ import numpy as np
3+ import os
44import pytest
5+ from typing import List
56
6- from gempy_engine .API .interp_single ._interp_scalar_field import _evaluate_sys_eq
7- from gempy_engine .API .interp_single . _interp_single_feature import input_preprocess
7+ import gempy_engine .API .interp_single .interp_features as interp
8+ from gempy_engine .API .dual_contouring . _dual_contouring import compute_dual_contouring
89from gempy_engine .API .interp_single ._multi_scalar_field_manager import interpolate_all_fields
10+ from gempy_engine .API .interp_single .interp_features import interpolate_n_octree_levels , interpolate_and_segment
911from gempy_engine .API .model .model_api import compute_model
1012from gempy_engine .config import AvailableBackends
1113from gempy_engine .core .backend_tensor import BackendTensor
14+ from gempy_engine .core .data import InterpolationOptions
15+ from gempy_engine .core .data .dual_contouring_data import DualContouringData
16+ from gempy_engine .core .data .dual_contouring_mesh import DualContouringMesh
1217from gempy_engine .core .data .engine_grid import EngineGrid , RegularGrid
13- import numpy as np
14- import os
15-
16- import gempy_engine .API .interp_single .interp_features as interp
17-
18- from gempy_engine .API .dual_contouring ._dual_contouring import compute_dual_contouring
1918from gempy_engine .core .data .input_data_descriptor import InputDataDescriptor
20- from gempy_engine .modules .activator .activator_interface import activate_formation_block
21- from gempy_engine .core .data .internal_structs import SolverInput
22-
23- from gempy_engine .core .data .solutions import Solutions
24- from gempy_engine .core .data .dual_contouring_mesh import DualContouringMesh
25- from gempy_engine .core .data .dual_contouring_data import DualContouringData
26- from gempy_engine .core .data .octree_level import OctreeLevel
2719from gempy_engine .core .data .interp_output import InterpOutput
2820from gempy_engine .core .data .interpolation_input import InterpolationInput
29- from gempy_engine .API .interp_single .interp_features import interpolate_n_octree_levels , interpolate_and_segment
21+ from gempy_engine .core .data .octree_level import OctreeLevel
22+ from gempy_engine .core .data .solutions import Solutions
3023from gempy_engine .modules .dual_contouring .dual_contouring_interface import QEF , find_intersection_on_edge , triangulate_dual_contouring
3124from gempy_engine .modules .octrees_topology .octrees_topology_interface import get_regular_grid_value_for_level
3225from gempy_engine .plugins .plotting import helper_functions_pyvista
4134 plot_pyvista = False
4235
4336
44- # pytest ignore
45-
46- # pytestmark = pytest.mark.skip("old _dual_contouring.triangulate_dual_contour has been deprecated. Also"
47- # "output corners have been deprecated and it is intead a subgrid. Updating"
48- # "this tests are a lot of work and for now dual contouring is tested in a"
49- # "higher level test.")
50-
51-
5237def _grab_xyz_edges (last_octree_level : OctreeLevel ) -> tuple :
5338 corners = last_octree_level .outputs_centers [0 ]
5439 # First find xyz on edges:
@@ -75,30 +60,12 @@ def test_compute_dual_contouring_api(simple_model, simple_grid_3d_octree):
7560
7661 last_octree_level : OctreeLevel = octree_list [- 1 ]
7762
78- # corners = last_octree_level.outputs_corners[0]
79- # # First find xyz on edges:
80- # xyz, edges = find_intersection_on_edge(
81- # _xyz_corners=last_octree_level.grid_corners.values,
82- # scalar_field_on_corners=corners.exported_fields.scalar_field,
83- # scalar_at_sp=corners.scalar_field_at_sp,
84- # masking=None
85- # )
86- # result = xyz, edges
87- # intersection_xyz, valid_edges = result
88-
8963 intersection_xyz , valid_edges = _grab_xyz_edges (last_octree_level )
90- interpolation_input .set_temp_grid (EngineGrid .from_xyz_coords (intersection_xyz ))
91-
92-
93- output_on_edges : List [InterpOutput ] = interpolate_all_fields (interpolation_input , options , data_shape )
94-
95- dc_data = DualContouringData (
96- xyz_on_edge = intersection_xyz ,
97- valid_edges = valid_edges ,
98- xyz_on_centers = last_octree_level .grid_centers .values ,
99- dxdydz = last_octree_level .grid_centers .octree_dxdydz ,
100- exported_fields_on_edges = output_on_edges [0 ].exported_fields ,
101- n_surfaces_to_export = data_shape .tensors_structure .n_surfaces
64+ dc_data = _gen_dc_data (
65+ octree_level = last_octree_level ,
66+ interpolation_input = interpolation_input ,
67+ data_shape = data_shape ,
68+ options = options ,
10269 )
10370
10471 gradients = dc_data .gradients
@@ -126,6 +93,25 @@ def test_compute_dual_contouring_api(simple_model, simple_grid_3d_octree):
12693 # endregion
12794
12895
96+ def _gen_dc_data (octree_level : OctreeLevel , interpolation_input : InterpolationInput ,
97+ options : InterpolationOptions , data_shape : InputDataDescriptor ) -> DualContouringData :
98+ intersection_xyz , valid_edges = _grab_xyz_edges (octree_level )
99+
100+ interpolation_input .set_temp_grid (EngineGrid .from_xyz_coords (intersection_xyz ))
101+
102+ output_on_edges : List [InterpOutput ] = interpolate_all_fields (interpolation_input , options , data_shape )
103+
104+ dc_data = DualContouringData (
105+ xyz_on_edge = intersection_xyz ,
106+ valid_edges = valid_edges ,
107+ xyz_on_centers = octree_level .grid_centers .octree_grid .values ,
108+ dxdydz = octree_level .grid_centers .octree_dxdydz ,
109+ exported_fields_on_edges = output_on_edges [0 ].exported_fields ,
110+ n_surfaces_to_export = data_shape .tensors_structure .n_surfaces
111+ )
112+ return dc_data
113+
114+
129115@pytest .mark .skipif (BackendTensor .engine_backend != AvailableBackends .numpy , reason = "Only numpy supported" )
130116def test_compute_mesh_extraction_fancy_triangulation (simple_model , simple_grid_3d_octree ):
131117 from gempy_engine .modules .dual_contouring .fancy_triangulation import get_left_right_array , triangulate
@@ -154,29 +140,40 @@ def _simple_grid_3d_octree_regular():
154140
155141 octree_level_for_surface : OctreeLevel = octree_list [options .number_octree_levels_surface - 1 ]
156142
157- corners = octree_level_for_surface .outputs_corners [0 ]
158- # First find xyz on edges:
159- xyz , edges = find_intersection_on_edge (
160- _xyz_corners = octree_level_for_surface .grid_corners .values ,
161- scalar_field_on_corners = corners .exported_fields .scalar_field ,
162- scalar_at_sp = corners .scalar_field_at_sp ,
163- masking = None
164- )
165- result = xyz , edges
166- intersection_xyz , valid_edges = result
143+ # corners = octree_level_for_surface.outputs_corners[0]
144+ # # First find xyz on edges:
145+ # xyz, edges = find_intersection_on_edge(
146+ # _xyz_corners=octree_level_for_surface.grid_corners.values,
147+ # scalar_field_on_corners=corners.exported_fields.scalar_field,
148+ # scalar_at_sp=corners.scalar_field_at_sp,
149+ # masking=None
150+ # )
151+ # result = xyz, edges
152+ # intersection_xyz, valid_edges = result
153+ #
154+ # last_octree_level: OctreeLevel = octree_list[-1]
155+ # intersection_xyz, valid_edges = _grab_xyz_edges(octree_level_for_surface)
156+ # interpolation_input.set_temp_grid(EngineGrid.from_xyz_coords(intersection_xyz))
157+ #
158+ # output_on_edges: List[InterpOutput] = interpolate_all_fields(interpolation_input, options, data_shape)
159+ #
160+ # dc_data = DualContouringData(
161+ # xyz_on_edge=intersection_xyz,
162+ # valid_edges=valid_edges,
163+ # xyz_on_centers=octree_level_for_surface.grid_centers.values,
164+ # dxdydz=octree_level_for_surface.grid_centers.octree_dxdydz,
165+ # exported_fields_on_edges=output_on_edges[0].exported_fields,
166+ # n_surfaces_to_export=data_shape.tensors_structure.n_surfaces
167+ # )
167168
168- interpolation_input .set_temp_grid (EngineGrid .from_xyz_coords (intersection_xyz ))
169- output_on_edges : List [InterpOutput ] = interpolate_all_fields (interpolation_input , options , data_shape )
169+ # dc_data = _gen_dc_data(data_shape, interpolation_input, intersection_xyz, last_octree_level, options, valid_edges)
170170
171- dc_data = DualContouringData (
172- xyz_on_edge = intersection_xyz ,
173- valid_edges = valid_edges ,
174- xyz_on_centers = octree_level_for_surface .grid_centers .values ,
175- dxdydz = octree_level_for_surface .grid_centers .octree_dxdydz ,
176- exported_fields_on_edges = output_on_edges [0 ].exported_fields ,
177- n_surfaces_to_export = data_shape .tensors_structure .n_surfaces
171+ dc_data = _gen_dc_data (
172+ octree_level = octree_level_for_surface ,
173+ interpolation_input = interpolation_input ,
174+ data_shape = data_shape ,
175+ options = options ,
178176 )
179-
180177 dc_meshes : List [DualContouringMesh ] = compute_dual_contouring (dc_data )
181178 dc_data = dc_meshes [0 ].dc_data
182179 valid_voxels = dc_data .valid_voxels
@@ -334,7 +331,7 @@ def test_find_edges_intersection_step_by_step(simple_model, simple_grid_3d_octre
334331 options .number_octree_levels = 5
335332 options .number_octree_levels_surface = 5
336333 options .compute_scalar_gradient = True
337-
334+
338335 octree_list = interpolate_n_octree_levels (interpolation_input , options , data_shape )
339336
340337 last_octree_level : OctreeLevel = octree_list [- 1 ]
@@ -659,15 +656,6 @@ def _plot_pyvista(last_octree_level, octree_list, simple_model, ids, grid_0_cent
659656 ):
660657 p = pv .Plotter ()
661658
662- # Plot Actual mesh (from marching cubes)
663- if plot_marching_cubes :
664- output_1_centers = last_octree_level .output_centers
665- resolution = [20 , 20 , 20 ]
666- mesh = _compute_actual_mesh (simple_model , ids , grid_0_centers , resolution ,
667- output_1_centers .scalar_field_at_sp , output_1_centers .weights )
668-
669- p .add_mesh (mesh , opacity = .8 , silhouette = True )
670-
671659 # Plot Regular grid Octree
672660 regular_grid_values = octree_list [n ].grid_centers .octree_grid .values_vtk_format
673661 regular_grid_scalar = get_regular_grid_value_for_level (octree_list , n )
@@ -711,40 +699,3 @@ def _plot_pyvista(last_octree_level, octree_list, simple_model, ids, grid_0_cent
711699 p .add_axes ()
712700 p .show ()
713701
714-
715- def _compute_actual_mesh (simple_model , ids , grid , resolution , scalar_at_surface_points , weights ):
716- raise NotImplementedError ("This is broken since a while" )
717- interpolation_input = simple_model [0 ]
718- options = simple_model [1 ]
719- shape : InputDataDescriptor = simple_model [2 ]
720-
721- from gempy_engine .core .data .engine_grid import EngineGrid , RegularGrid
722-
723- # region interpolate high res grid
724- grid_high_res :EngineGrid = EngineGrid .from_regular_grid (RegularGrid ([0.25 , .75 , 0.25 , .75 , 0.25 , .75 ], resolution ))
725- interpolation_input .grid = grid_high_res
726- input1 : SolverInput = input_preprocess (shape .tensors_structure , interpolation_input )
727- exported_fields_high_res = _evaluate_sys_eq (input1 , weights , options )
728-
729- exported_fields_high_res .set_structure_values (
730- reference_sp_position = shape .tensors_structure .reference_sp_position ,
731- slice_feature = interpolation_input .slice_feature ,
732- grid_size = interpolation_input .grid .len_all_grids )
733-
734- res = activate_formation_block (exported_fields_high_res , ids , sigmoid_slope = 50000 )
735- result = res , exported_fields_high_res , grid_high_res .octree_dxdydz
736- values_block_high_res , scalar_high_res , dxdydz = result
737- # endregion
738-
739- from skimage .measure import marching_cubes
740- import pyvista as pv
741- spacing = np .array (dxdydz )/ 8
742- vert , edges , _ , _ = marching_cubes (
743- volume = (scalar_high_res .scalar_field [:- 8 ].reshape (resolution )),
744- level = scalar_at_surface_points [0 ],
745- spacing = spacing
746- )
747- loc_0 = np .array ([0.25 , .25 , .25 ]) + np .array (spacing ) / 2
748- vert += np .array (loc_0 ).reshape (1 , 3 )
749- mesh = pv .PolyData (vert , np .insert (edges , 0 , 3 , axis = 1 ).ravel ())
750- return mesh
0 commit comments