subsurface-terra 2025.1.0rc15__py3-none-any.whl → 2025.1.0rc17__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. subsurface/__init__.py +31 -31
  2. subsurface/_version.py +34 -21
  3. subsurface/api/__init__.py +13 -13
  4. subsurface/api/interfaces/__init__.py +3 -3
  5. subsurface/api/interfaces/stream.py +136 -136
  6. subsurface/api/reader/read_wells.py +78 -78
  7. subsurface/core/geological_formats/boreholes/_combine_trajectories.py +117 -117
  8. subsurface/core/geological_formats/boreholes/_map_attrs_to_survey.py +236 -234
  9. subsurface/core/geological_formats/boreholes/_survey_to_unstruct.py +163 -163
  10. subsurface/core/geological_formats/boreholes/boreholes.py +140 -140
  11. subsurface/core/geological_formats/boreholes/collars.py +26 -26
  12. subsurface/core/geological_formats/boreholes/survey.py +86 -86
  13. subsurface/core/geological_formats/fault.py +47 -47
  14. subsurface/core/reader_helpers/reader_unstruct.py +11 -11
  15. subsurface/core/reader_helpers/readers_data.py +130 -130
  16. subsurface/core/reader_helpers/readers_wells.py +13 -13
  17. subsurface/core/structs/__init__.py +3 -3
  18. subsurface/core/structs/base_structures/__init__.py +2 -2
  19. subsurface/core/structs/base_structures/_aux.py +69 -0
  20. subsurface/core/structs/base_structures/_liquid_earth_mesh.py +121 -121
  21. subsurface/core/structs/base_structures/_unstructured_data_constructor.py +70 -70
  22. subsurface/core/structs/base_structures/base_structures_enum.py +6 -6
  23. subsurface/core/structs/base_structures/structured_data.py +282 -282
  24. subsurface/core/structs/base_structures/unstructured_data.py +338 -319
  25. subsurface/core/structs/structured_elements/octree_mesh.py +10 -10
  26. subsurface/core/structs/structured_elements/structured_grid.py +59 -59
  27. subsurface/core/structs/structured_elements/structured_mesh.py +9 -9
  28. subsurface/core/structs/unstructured_elements/__init__.py +3 -3
  29. subsurface/core/structs/unstructured_elements/line_set.py +72 -72
  30. subsurface/core/structs/unstructured_elements/point_set.py +43 -43
  31. subsurface/core/structs/unstructured_elements/tetrahedron_mesh.py +35 -35
  32. subsurface/core/structs/unstructured_elements/triangular_surface.py +62 -62
  33. subsurface/core/utils/utils_core.py +38 -38
  34. subsurface/modules/reader/__init__.py +13 -13
  35. subsurface/modules/reader/faults/faults.py +80 -80
  36. subsurface/modules/reader/from_binary.py +46 -46
  37. subsurface/modules/reader/mesh/_GOCAD_mesh.py +82 -82
  38. subsurface/modules/reader/mesh/_trimesh_reader.py +447 -447
  39. subsurface/modules/reader/mesh/csv_mesh_reader.py +53 -53
  40. subsurface/modules/reader/mesh/dxf_reader.py +177 -177
  41. subsurface/modules/reader/mesh/glb_reader.py +30 -30
  42. subsurface/modules/reader/mesh/mx_reader.py +232 -232
  43. subsurface/modules/reader/mesh/obj_reader.py +53 -53
  44. subsurface/modules/reader/mesh/omf_mesh_reader.py +43 -43
  45. subsurface/modules/reader/mesh/surface_reader.py +56 -56
  46. subsurface/modules/reader/mesh/surfaces_api.py +41 -41
  47. subsurface/modules/reader/profiles/__init__.py +3 -3
  48. subsurface/modules/reader/profiles/profiles_core.py +197 -197
  49. subsurface/modules/reader/read_netcdf.py +38 -38
  50. subsurface/modules/reader/topography/__init__.py +7 -7
  51. subsurface/modules/reader/topography/topo_core.py +100 -100
  52. subsurface/modules/reader/volume/read_grav3d.py +447 -428
  53. subsurface/modules/reader/volume/read_volume.py +327 -230
  54. subsurface/modules/reader/volume/segy_reader.py +105 -105
  55. subsurface/modules/reader/volume/seismic.py +173 -173
  56. subsurface/modules/reader/volume/volume_utils.py +43 -43
  57. subsurface/modules/reader/wells/DEP/__init__.py +43 -43
  58. subsurface/modules/reader/wells/DEP/_well_files_reader.py +167 -167
  59. subsurface/modules/reader/wells/DEP/_wells_api.py +61 -61
  60. subsurface/modules/reader/wells/DEP/_welly_reader.py +180 -180
  61. subsurface/modules/reader/wells/DEP/pandas_to_welly.py +212 -212
  62. subsurface/modules/reader/wells/_read_to_df.py +57 -57
  63. subsurface/modules/reader/wells/read_borehole_interface.py +148 -148
  64. subsurface/modules/reader/wells/wells_utils.py +68 -68
  65. subsurface/modules/tools/mocking_aux.py +104 -104
  66. subsurface/modules/visualization/__init__.py +2 -2
  67. subsurface/modules/visualization/to_pyvista.py +320 -320
  68. subsurface/modules/writer/to_binary.py +12 -12
  69. subsurface/modules/writer/to_rex/common.py +78 -78
  70. subsurface/modules/writer/to_rex/data_struct.py +74 -74
  71. subsurface/modules/writer/to_rex/gempy_to_rexfile.py +791 -791
  72. subsurface/modules/writer/to_rex/material_encoder.py +44 -44
  73. subsurface/modules/writer/to_rex/mesh_encoder.py +152 -152
  74. subsurface/modules/writer/to_rex/to_rex.py +115 -115
  75. subsurface/modules/writer/to_rex/utils.py +15 -15
  76. subsurface/optional_requirements.py +116 -116
  77. {subsurface_terra-2025.1.0rc15.dist-info → subsurface_terra-2025.1.0rc17.dist-info}/METADATA +194 -194
  78. subsurface_terra-2025.1.0rc17.dist-info/RECORD +99 -0
  79. {subsurface_terra-2025.1.0rc15.dist-info → subsurface_terra-2025.1.0rc17.dist-info}/WHEEL +1 -1
  80. {subsurface_terra-2025.1.0rc15.dist-info → subsurface_terra-2025.1.0rc17.dist-info}/licenses/LICENSE +203 -203
  81. subsurface_terra-2025.1.0rc15.dist-info/RECORD +0 -98
  82. {subsurface_terra-2025.1.0rc15.dist-info → subsurface_terra-2025.1.0rc17.dist-info}/top_level.txt +0 -0
@@ -1,53 +1,53 @@
1
- from typing import Union, Callable
2
-
3
- import numpy as np
4
- import pandas as pd
5
-
6
-
7
- def mesh_csv_to_vertex(path_to_file: str, columns_map: Union[None, Callable, dict, pd.Series] = None,
8
- **reader_kwargs) -> np.ndarray:
9
- data = pd.read_csv(path_to_file, **reader_kwargs)
10
- if columns_map is not None: map_columns_names(columns_map, data)
11
- return get_vertices_from_df(data)
12
-
13
-
14
- def mesh_csv_to_cells(path_to_file: str, columns_map: Union[None, Callable, dict, pd.Series] = None,
15
- **reader_kwargs) -> np.ndarray:
16
- data = pd.read_csv(path_to_file, **reader_kwargs)
17
- if columns_map is not None: map_columns_names(columns_map, data)
18
- return get_cells_from_df(data)
19
-
20
-
21
- def mesh_csv_to_attributes(path_to_file: str,
22
- columns_map: Union[None, Callable, dict, pd.Series] = None,
23
- **reader_kwargs) -> pd.DataFrame:
24
- data = pd.read_csv(path_to_file, **reader_kwargs)
25
- if columns_map is not None:
26
- map_columns_names(columns_map, data)
27
- return data
28
-
29
-
30
- def get_cells_from_df(data):
31
- try:
32
- cells = data[['e1', 'e2', 'e3']].dropna().astype('int').values
33
- except KeyError:
34
- raise KeyError('Columns e1, e2, and e3 must be present in the data set. Use'
35
- 'columns_map to map other names')
36
- return cells
37
-
38
-
39
- def get_vertices_from_df(data):
40
- try:
41
- vertex = data[['x', 'y', 'z']].values
42
- except KeyError:
43
- raise KeyError('Columns x, y, and z must be present in the data set. Use'
44
- 'columns_map to map other names')
45
- return vertex
46
-
47
-
48
- def map_columns_names(columns_map: Union[Callable, dict, pd.Series], data: pd.DataFrame):
49
- data.columns = data.columns.map(columns_map)
50
- if data.columns.isin(['x', 'y', 'z']).any() is False:
51
- raise AttributeError('At least x, y, z must be passed to `columns_map`')
52
-
53
- return data.columns
1
+ from typing import Union, Callable
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+
6
+
7
+ def mesh_csv_to_vertex(path_to_file: str, columns_map: Union[None, Callable, dict, pd.Series] = None,
8
+ **reader_kwargs) -> np.ndarray:
9
+ data = pd.read_csv(path_to_file, **reader_kwargs)
10
+ if columns_map is not None: map_columns_names(columns_map, data)
11
+ return get_vertices_from_df(data)
12
+
13
+
14
+ def mesh_csv_to_cells(path_to_file: str, columns_map: Union[None, Callable, dict, pd.Series] = None,
15
+ **reader_kwargs) -> np.ndarray:
16
+ data = pd.read_csv(path_to_file, **reader_kwargs)
17
+ if columns_map is not None: map_columns_names(columns_map, data)
18
+ return get_cells_from_df(data)
19
+
20
+
21
+ def mesh_csv_to_attributes(path_to_file: str,
22
+ columns_map: Union[None, Callable, dict, pd.Series] = None,
23
+ **reader_kwargs) -> pd.DataFrame:
24
+ data = pd.read_csv(path_to_file, **reader_kwargs)
25
+ if columns_map is not None:
26
+ map_columns_names(columns_map, data)
27
+ return data
28
+
29
+
30
+ def get_cells_from_df(data):
31
+ try:
32
+ cells = data[['e1', 'e2', 'e3']].dropna().astype('int').values
33
+ except KeyError:
34
+ raise KeyError('Columns e1, e2, and e3 must be present in the data set. Use'
35
+ 'columns_map to map other names')
36
+ return cells
37
+
38
+
39
+ def get_vertices_from_df(data):
40
+ try:
41
+ vertex = data[['x', 'y', 'z']].values
42
+ except KeyError:
43
+ raise KeyError('Columns x, y, and z must be present in the data set. Use'
44
+ 'columns_map to map other names')
45
+ return vertex
46
+
47
+
48
+ def map_columns_names(columns_map: Union[Callable, dict, pd.Series], data: pd.DataFrame):
49
+ data.columns = data.columns.map(columns_map)
50
+ if data.columns.isin(['x', 'y', 'z']).any() is False:
51
+ raise AttributeError('At least x, y, z must be passed to `columns_map`')
52
+
53
+ return data.columns
@@ -1,177 +1,177 @@
1
- import pathlib
2
- import warnings
3
- from enum import Flag
4
- from typing import TextIO, Union
5
-
6
- import numpy as np
7
-
8
- from .... import optional_requirements
9
-
10
-
11
- class DXFEntityType(Flag):
12
- """Decides which entity types should be extracted."""
13
- FACE3D = 2 ** 0 # Extract only 3DFACE
14
- POLYLINE = 2 ** 1 # Extract only POLYLINE
15
- ALL = FACE3D | POLYLINE # Extract all entity types
16
-
17
-
18
- def dxf_from_file_to_vertex(
19
- file_path: Union[str, pathlib.Path],
20
- entity_type: DXFEntityType = DXFEntityType.ALL,
21
- ) -> np.ndarray:
22
- """
23
- Extract vertices from a DXF file, according to the chosen entity_type.
24
-
25
- :param file_path: Path to the DXF file.
26
- :param entity_type: Controls which entity types to extract.
27
- :return: Unique vertex array [N, 3].
28
- """
29
- ezdxf = optional_requirements.require_ezdxf()
30
- dataset = ezdxf.readfile(file_path)
31
- return _extract_vertices_from_dataset(dataset, entity_type)
32
-
33
-
34
- def dxf_from_stream_to_vertex(
35
- stream: TextIO,
36
- entity_type: DXFEntityType = DXFEntityType.ALL,
37
- ) -> np.ndarray:
38
- """
39
- Extract vertices from a DXF stream, according to the chosen entity_type.
40
-
41
- :param stream: A file-like object containing the DXF data.
42
- :param entity_type: Controls which entity types to extract.
43
- :return: Unique vertex array [N, 3].
44
- """
45
- ezdxf = optional_requirements.require_ezdxf()
46
- dataset = ezdxf.read(stream)
47
- return _extract_vertices_from_dataset(dataset, entity_type)
48
-
49
-
50
- def dxf_file_to_unstruct_input(
51
- file: Union[str, pathlib.Path],
52
- ) -> tuple[np.ndarray, np.ndarray, np.ndarray, dict]:
53
- """
54
- Extract unstructured-mesh-like data (vertex, cells, cell_attr_int, cell_attr_map)
55
- from a DXF file using only 3DFACE entities.
56
-
57
- :param file: Path to the DXF file.
58
- :return: (vertex, cells, cell_attr_int, cell_attr_map)
59
- """
60
- ezdxf = optional_requirements.require_ezdxf()
61
- dataset = ezdxf.readfile(file)
62
- vertex, cells, cell_attr_int, cell_attr_map = _dxf_dataset_to_unstruct_input(dataset)
63
-
64
- if vertex.size == 0:
65
- raise ValueError("The DXF file does not contain any 3DFACE entities.")
66
-
67
- return vertex, cells, cell_attr_int, cell_attr_map
68
-
69
-
70
- def dxf_stream_to_unstruct_input(
71
- stream: TextIO,
72
- ) -> tuple[np.ndarray, np.ndarray, np.ndarray, dict]:
73
- """
74
- Extract unstructured-mesh-like data (vertex, cells, cell_attr_int, cell_attr_map)
75
- from a DXF stream using only 3DFACE entities.
76
-
77
- :param stream: A file-like object containing the DXF data.
78
- :return: (vertex, cells, cell_attr_int, cell_attr_map)
79
- """
80
- ezdxf = optional_requirements.require_ezdxf()
81
- dataset = ezdxf.read(stream)
82
- return _dxf_dataset_to_unstruct_input(dataset)
83
-
84
-
85
- def _extract_vertices_from_dataset(
86
- dataset,
87
- entity_type: DXFEntityType = DXFEntityType.ALL
88
- ) -> np.ndarray:
89
- """
90
- Collect unique vertices from the dataset's modelspace.
91
- The entity_type flag dictates which entities are extracted.
92
- """
93
- vertices = []
94
-
95
- for e in dataset.modelspace():
96
- match e.dxftype():
97
- # 3DFACE
98
- case "3DFACE" if DXFEntityType.FACE3D in entity_type:
99
- # A 3DFACE entity typically has three corners: e[0], e[1], e[2]
100
- # Sometimes it can have a fourth corner e[3], which might be equal to e[2].
101
- # Adjust accordingly if needed:
102
- vertices.extend([e[0], e[1], e[2]])
103
- # If you'd like to handle the potential 4th corner,
104
- # you could do: vertices.append(e[3]) if e[3] != e[2] else None
105
-
106
- # POLYLINE
107
- case "POLYLINE" if DXFEntityType.POLYLINE in entity_type:
108
- for v in e.vertices:
109
- x, y, z = v.dxf.location.xyz
110
- vertices.append([x, y, z])
111
-
112
- # Other / unsupported
113
- case _:
114
- # If it doesn't match the chosen entity type(s), we skip or warn.
115
- # But if you'd prefer to only warn when an entity isn't recognized at all,
116
- # you can do so here:
117
- warnings.warn(f"Entity type '{e.dxftype()}' not extracted (flag: {entity_type}).")
118
- continue
119
-
120
- # Convert to numpy array and ensure uniqueness
121
- vertices = np.array(vertices)
122
- if vertices.size == 0:
123
- return vertices
124
- return np.unique(vertices, axis=0)
125
-
126
-
127
- def _dxf_dataset_to_unstruct_input(dataset: 'ezdxf.drawing.Drawing') -> tuple[np.ndarray, np.ndarray, np.ndarray, dict]:
128
- """
129
- Build unstructured-mesh-like data from 3DFACE entities in a dataset:
130
- - vertex coordinates
131
- - connectivity in 'cells' array
132
- - cell attributes in both integer-coded and mapping (string->int) forms
133
-
134
- """
135
- """
136
- Build unstructured-mesh-like data from 3DFACE entities in a dataset:
137
- - vertex coordinates
138
- - connectivity in 'cells' array
139
- - cell attributes in both integer-coded and mapping (string->int) forms
140
-
141
- Returns (cell_attr_int, cell_attr_map, cells, vertex).
142
- """
143
-
144
- def _map_cell_attr_strings_to_integers(cell_attr):
145
- """
146
- Map string layer names (or other string attributes) to integer IDs, starting from 1.
147
- """
148
- unique_values = np.unique(cell_attr)
149
- sorted_unique_values = sorted(unique_values)
150
-
151
- # Create mapping from string values to integers (start at 1, 2, 3, ...)
152
- value_to_int_mapping = {
153
- str(value): index + 1 for index, value in enumerate(sorted_unique_values)
154
- }
155
-
156
- cell_attr_int = np.array([value_to_int_mapping[value] for value in cell_attr])
157
- return cell_attr_int, value_to_int_mapping
158
-
159
- vertex_list = []
160
- cell_attr = []
161
-
162
- for e in dataset.modelspace():
163
- match e.dxftype():
164
- case "3DFACE":
165
- # Typically 3 corners, but can have 4th corner repeated
166
- vertex_list.extend([e[0], e[1], e[2]])
167
- cell_attr.append(e.dxf.get("layer"))
168
- case _:
169
- # We ignore other entities in unstructured input
170
- continue
171
-
172
- vertices = np.array(vertex_list)
173
- # For each triple (3DFACE), build a cell (triangle)
174
- cells = np.arange(0, vertices.shape[0]).reshape(-1, 3)
175
-
176
- cell_attr_int, cell_attr_map = _map_cell_attr_strings_to_integers(cell_attr)
177
- return vertices, cells, cell_attr_int, cell_attr_map
1
+ import pathlib
2
+ import warnings
3
+ from enum import Flag
4
+ from typing import TextIO, Union
5
+
6
+ import numpy as np
7
+
8
+ from .... import optional_requirements
9
+
10
+
11
+ class DXFEntityType(Flag):
12
+ """Decides which entity types should be extracted."""
13
+ FACE3D = 2 ** 0 # Extract only 3DFACE
14
+ POLYLINE = 2 ** 1 # Extract only POLYLINE
15
+ ALL = FACE3D | POLYLINE # Extract all entity types
16
+
17
+
18
+ def dxf_from_file_to_vertex(
19
+ file_path: Union[str, pathlib.Path],
20
+ entity_type: DXFEntityType = DXFEntityType.ALL,
21
+ ) -> np.ndarray:
22
+ """
23
+ Extract vertices from a DXF file, according to the chosen entity_type.
24
+
25
+ :param file_path: Path to the DXF file.
26
+ :param entity_type: Controls which entity types to extract.
27
+ :return: Unique vertex array [N, 3].
28
+ """
29
+ ezdxf = optional_requirements.require_ezdxf()
30
+ dataset = ezdxf.readfile(file_path)
31
+ return _extract_vertices_from_dataset(dataset, entity_type)
32
+
33
+
34
+ def dxf_from_stream_to_vertex(
35
+ stream: TextIO,
36
+ entity_type: DXFEntityType = DXFEntityType.ALL,
37
+ ) -> np.ndarray:
38
+ """
39
+ Extract vertices from a DXF stream, according to the chosen entity_type.
40
+
41
+ :param stream: A file-like object containing the DXF data.
42
+ :param entity_type: Controls which entity types to extract.
43
+ :return: Unique vertex array [N, 3].
44
+ """
45
+ ezdxf = optional_requirements.require_ezdxf()
46
+ dataset = ezdxf.read(stream)
47
+ return _extract_vertices_from_dataset(dataset, entity_type)
48
+
49
+
50
+ def dxf_file_to_unstruct_input(
51
+ file: Union[str, pathlib.Path],
52
+ ) -> tuple[np.ndarray, np.ndarray, np.ndarray, dict]:
53
+ """
54
+ Extract unstructured-mesh-like data (vertex, cells, cell_attr_int, cell_attr_map)
55
+ from a DXF file using only 3DFACE entities.
56
+
57
+ :param file: Path to the DXF file.
58
+ :return: (vertex, cells, cell_attr_int, cell_attr_map)
59
+ """
60
+ ezdxf = optional_requirements.require_ezdxf()
61
+ dataset = ezdxf.readfile(file)
62
+ vertex, cells, cell_attr_int, cell_attr_map = _dxf_dataset_to_unstruct_input(dataset)
63
+
64
+ if vertex.size == 0:
65
+ raise ValueError("The DXF file does not contain any 3DFACE entities.")
66
+
67
+ return vertex, cells, cell_attr_int, cell_attr_map
68
+
69
+
70
+ def dxf_stream_to_unstruct_input(
71
+ stream: TextIO,
72
+ ) -> tuple[np.ndarray, np.ndarray, np.ndarray, dict]:
73
+ """
74
+ Extract unstructured-mesh-like data (vertex, cells, cell_attr_int, cell_attr_map)
75
+ from a DXF stream using only 3DFACE entities.
76
+
77
+ :param stream: A file-like object containing the DXF data.
78
+ :return: (vertex, cells, cell_attr_int, cell_attr_map)
79
+ """
80
+ ezdxf = optional_requirements.require_ezdxf()
81
+ dataset = ezdxf.read(stream)
82
+ return _dxf_dataset_to_unstruct_input(dataset)
83
+
84
+
85
+ def _extract_vertices_from_dataset(
86
+ dataset,
87
+ entity_type: DXFEntityType = DXFEntityType.ALL
88
+ ) -> np.ndarray:
89
+ """
90
+ Collect unique vertices from the dataset's modelspace.
91
+ The entity_type flag dictates which entities are extracted.
92
+ """
93
+ vertices = []
94
+
95
+ for e in dataset.modelspace():
96
+ match e.dxftype():
97
+ # 3DFACE
98
+ case "3DFACE" if DXFEntityType.FACE3D in entity_type:
99
+ # A 3DFACE entity typically has three corners: e[0], e[1], e[2]
100
+ # Sometimes it can have a fourth corner e[3], which might be equal to e[2].
101
+ # Adjust accordingly if needed:
102
+ vertices.extend([e[0], e[1], e[2]])
103
+ # If you'd like to handle the potential 4th corner,
104
+ # you could do: vertices.append(e[3]) if e[3] != e[2] else None
105
+
106
+ # POLYLINE
107
+ case "POLYLINE" if DXFEntityType.POLYLINE in entity_type:
108
+ for v in e.vertices:
109
+ x, y, z = v.dxf.location.xyz
110
+ vertices.append([x, y, z])
111
+
112
+ # Other / unsupported
113
+ case _:
114
+ # If it doesn't match the chosen entity type(s), we skip or warn.
115
+ # But if you'd prefer to only warn when an entity isn't recognized at all,
116
+ # you can do so here:
117
+ warnings.warn(f"Entity type '{e.dxftype()}' not extracted (flag: {entity_type}).")
118
+ continue
119
+
120
+ # Convert to numpy array and ensure uniqueness
121
+ vertices = np.array(vertices)
122
+ if vertices.size == 0:
123
+ return vertices
124
+ return np.unique(vertices, axis=0)
125
+
126
+
127
+ def _dxf_dataset_to_unstruct_input(dataset: 'ezdxf.drawing.Drawing') -> tuple[np.ndarray, np.ndarray, np.ndarray, dict]:
128
+ """
129
+ Build unstructured-mesh-like data from 3DFACE entities in a dataset:
130
+ - vertex coordinates
131
+ - connectivity in 'cells' array
132
+ - cell attributes in both integer-coded and mapping (string->int) forms
133
+
134
+ """
135
+ """
136
+ Build unstructured-mesh-like data from 3DFACE entities in a dataset:
137
+ - vertex coordinates
138
+ - connectivity in 'cells' array
139
+ - cell attributes in both integer-coded and mapping (string->int) forms
140
+
141
+ Returns (cell_attr_int, cell_attr_map, cells, vertex).
142
+ """
143
+
144
+ def _map_cell_attr_strings_to_integers(cell_attr):
145
+ """
146
+ Map string layer names (or other string attributes) to integer IDs, starting from 1.
147
+ """
148
+ unique_values = np.unique(cell_attr)
149
+ sorted_unique_values = sorted(unique_values)
150
+
151
+ # Create mapping from string values to integers (start at 1, 2, 3, ...)
152
+ value_to_int_mapping = {
153
+ str(value): index + 1 for index, value in enumerate(sorted_unique_values)
154
+ }
155
+
156
+ cell_attr_int = np.array([value_to_int_mapping[value] for value in cell_attr])
157
+ return cell_attr_int, value_to_int_mapping
158
+
159
+ vertex_list = []
160
+ cell_attr = []
161
+
162
+ for e in dataset.modelspace():
163
+ match e.dxftype():
164
+ case "3DFACE":
165
+ # Typically 3 corners, but can have 4th corner repeated
166
+ vertex_list.extend([e[0], e[1], e[2]])
167
+ cell_attr.append(e.dxf.get("layer"))
168
+ case _:
169
+ # We ignore other entities in unstructured input
170
+ continue
171
+
172
+ vertices = np.array(vertex_list)
173
+ # For each triple (3DFACE), build a cell (triangle)
174
+ cells = np.arange(0, vertices.shape[0]).reshape(-1, 3)
175
+
176
+ cell_attr_int, cell_attr_map = _map_cell_attr_strings_to_integers(cell_attr)
177
+ return vertices, cells, cell_attr_int, cell_attr_map
@@ -1,30 +1,30 @@
1
- import io
2
- from typing import Union
3
-
4
- from ....core.structs import TriSurf
5
- from ._trimesh_reader import load_with_trimesh, trimesh_to_unstruct, TriMeshTransformations
6
-
7
-
8
- def load_gltf_with_trimesh(path_to_glb: Union[str | io.BytesIO], coordinate_system: TriMeshTransformations) -> TriSurf:
9
- """
10
- load_obj_with_trimesh(path_to_glb, plot=False)
11
-
12
- Loads a 3D object file in .glb format using trimesh, processes it, and converts it into
13
- a subsurface TriSurf object for further analysis or usage. Optionally, it allows
14
- plotting the loaded object.
15
-
16
- Parameters
17
- ----------
18
- path_to_glb : str
19
- Path to the .glb file containing the 3D object.
20
- plot : bool, optional
21
- A flag indicating whether the loaded 3D object should be plotted. Defaults to False.
22
-
23
- Returns
24
- -------
25
- subsurface.TriSurf
26
- A TriSurf object representing the processed 3D surface geometry.
27
- """
28
- trimesh = load_with_trimesh(path_to_glb, file_type="glb", coordinate_system=coordinate_system, plot=False)
29
- trisurf = trimesh_to_unstruct(trimesh)
30
- return trisurf
1
+ import io
2
+ from typing import Union
3
+
4
+ from ....core.structs import TriSurf
5
+ from ._trimesh_reader import load_with_trimesh, trimesh_to_unstruct, TriMeshTransformations
6
+
7
+
8
+ def load_gltf_with_trimesh(path_to_glb: Union[str | io.BytesIO], coordinate_system: TriMeshTransformations) -> TriSurf:
9
+ """
10
+ load_obj_with_trimesh(path_to_glb, plot=False)
11
+
12
+ Loads a 3D object file in .glb format using trimesh, processes it, and converts it into
13
+ a subsurface TriSurf object for further analysis or usage. Optionally, it allows
14
+ plotting the loaded object.
15
+
16
+ Parameters
17
+ ----------
18
+ path_to_glb : str
19
+ Path to the .glb file containing the 3D object.
20
+ plot : bool, optional
21
+ A flag indicating whether the loaded 3D object should be plotted. Defaults to False.
22
+
23
+ Returns
24
+ -------
25
+ subsurface.TriSurf
26
+ A TriSurf object representing the processed 3D surface geometry.
27
+ """
28
+ trimesh = load_with_trimesh(path_to_glb, file_type="glb", coordinate_system=coordinate_system, plot=False)
29
+ trisurf = trimesh_to_unstruct(trimesh)
30
+ return trisurf