voxcity 0.5.14__py3-none-any.whl → 0.5.15__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.

Potentially problematic release.


This version of voxcity might be problematic. Click here for more details.

voxcity/exporter/obj.py CHANGED
@@ -3,6 +3,26 @@ Module for exporting voxel data to OBJ format.
3
3
 
4
4
  This module provides functionality for converting voxel arrays and grid data to OBJ files,
5
5
  including color mapping, material generation, and mesh optimization.
6
+
7
+ Key Features:
8
+ - Exports voxel data to industry-standard OBJ format with MTL materials
9
+ - Supports color mapping for visualization
10
+ - Performs greedy meshing for optimized face generation
11
+ - Handles proper face orientation and winding order
12
+ - Supports both regular voxel grids and terrain/elevation data
13
+ - Generates complete OBJ files with materials and textures
14
+
15
+ Main Functions:
16
+ - convert_colormap_indices: Converts arbitrary color indices to sequential ones
17
+ - create_face_vertices: Creates properly oriented face vertices
18
+ - mesh_faces: Performs greedy meshing on voxel layers
19
+ - export_obj: Main function to export voxel data to OBJ
20
+ - grid_to_obj: Converts 2D grid data to OBJ with elevation
21
+
22
+ Dependencies:
23
+ - numpy: For array operations
24
+ - matplotlib: For colormap handling
25
+ - trimesh: For mesh operations
6
26
  """
7
27
 
8
28
  import numpy as np
@@ -17,11 +37,23 @@ def convert_colormap_indices(original_map):
17
37
  """
18
38
  Convert a color map with arbitrary indices to sequential indices starting from 0.
19
39
 
40
+ This function takes a color map with arbitrary integer keys and creates a new map
41
+ with sequential indices starting from 0, maintaining the original color values.
42
+ This is useful for ensuring consistent material indexing in OBJ files.
43
+
20
44
  Args:
21
- original_map (dict): Dictionary with integer keys and RGB color value lists
45
+ original_map (dict): Dictionary with integer keys and RGB color value lists.
46
+ Each value should be a list of 3 integers (0-255) representing RGB colors.
22
47
 
23
48
  Returns:
24
- dict: New color map with sequential indices starting from 0
49
+ dict: New color map with sequential indices starting from 0.
50
+ The values maintain their original RGB color assignments.
51
+
52
+ Example:
53
+ >>> original = {5: [255, 0, 0], 10: [0, 255, 0], 15: [0, 0, 255]}
54
+ >>> new_map = convert_colormap_indices(original)
55
+ >>> print(new_map)
56
+ {0: [255, 0, 0], 1: [0, 255, 0], 2: [0, 0, 255]}
25
57
  """
26
58
  # Sort the original keys to maintain consistent ordering
27
59
  keys = sorted(original_map.keys())
@@ -46,15 +78,29 @@ def convert_colormap_indices(original_map):
46
78
 
47
79
  def create_face_vertices(coords, positive_direction, axis):
48
80
  """
49
- Helper function to create properly oriented face vertices.
81
+ Helper function to create properly oriented face vertices for OBJ export.
82
+
83
+ This function handles the creation of face vertices with correct winding order
84
+ based on the face direction and axis. It accounts for OpenGL coordinate system
85
+ conventions and ensures proper face orientation for rendering.
50
86
 
51
87
  Args:
52
- coords (list): List of vertex coordinates
53
- positive_direction (bool): Whether face points in positive axis direction
54
- axis (str): Axis the face is perpendicular to ('x', 'y', or 'z')
88
+ coords (list): List of 4 vertex coordinates defining the face corners.
89
+ Each coordinate should be a tuple of (x, y, z) values.
90
+ positive_direction (bool): Whether face points in positive axis direction.
91
+ True = face normal points in positive direction along the axis
92
+ False = face normal points in negative direction along the axis
93
+ axis (str): Axis the face is perpendicular to ('x', 'y', or 'z').
94
+ This determines how vertices are ordered for proper face orientation.
55
95
 
56
96
  Returns:
57
- list: Ordered vertex coordinates for the face
97
+ list: Ordered vertex coordinates for the face, arranged to create proper
98
+ face orientation and winding order for rendering.
99
+
100
+ Notes:
101
+ - Y-axis faces need special handling due to OpenGL coordinate system
102
+ - Winding order determines which side of the face is visible
103
+ - Consistent winding order is maintained for X and Z faces
58
104
  """
59
105
  # Y-axis faces need special handling due to OpenGL coordinate system
60
106
  if axis == 'y':
@@ -72,19 +118,41 @@ def create_face_vertices(coords, positive_direction, axis):
72
118
  def mesh_faces(mask, layer_index, axis, positive_direction, normal_idx, voxel_size_m,
73
119
  vertex_dict, vertex_list, faces_per_material, voxel_value_to_material):
74
120
  """
75
- Performs greedy meshing on the given mask and adds faces to the faces_per_material dictionary.
121
+ Performs greedy meshing on a 2D mask layer and adds optimized faces to the mesh.
122
+
123
+ This function implements a greedy meshing algorithm to combine adjacent voxels
124
+ into larger faces, reducing the total number of faces in the final mesh while
125
+ maintaining visual accuracy. It processes each layer of voxels and generates
126
+ optimized faces with proper materials and orientations.
76
127
 
77
128
  Args:
78
- mask (ndarray): 2D boolean array indicating voxel presence
79
- layer_index (int): Index of current layer being processed
80
- axis (str): Axis perpendicular to faces being generated ('x', 'y', or 'z')
81
- positive_direction (bool): Whether faces point in positive axis direction
82
- normal_idx (int): Index of normal vector to use for faces
83
- voxel_size_m (float): Size of each voxel in meters
84
- vertex_dict (dict): Dictionary mapping vertex coordinates to indices
85
- vertex_list (list): List of unique vertex coordinates
86
- faces_per_material (dict): Dictionary collecting faces by material
87
- voxel_value_to_material (dict): Mapping from voxel values to material names
129
+ mask (ndarray): 2D boolean array indicating voxel presence.
130
+ Non-zero values indicate voxel presence, zero indicates empty space.
131
+ layer_index (int): Index of current layer being processed.
132
+ Used to position faces in 3D space.
133
+ axis (str): Axis perpendicular to faces being generated ('x', 'y', or 'z').
134
+ Determines how coordinates are generated for the faces.
135
+ positive_direction (bool): Whether faces point in positive axis direction.
136
+ Affects face normal orientation.
137
+ normal_idx (int): Index of normal vector to use for faces.
138
+ References pre-defined normal vectors in the OBJ file.
139
+ voxel_size_m (float): Size of each voxel in meters.
140
+ Used to scale coordinates to real-world units.
141
+ vertex_dict (dict): Dictionary mapping vertex coordinates to indices.
142
+ Used to avoid duplicate vertices in the mesh.
143
+ vertex_list (list): List of unique vertex coordinates.
144
+ Stores all vertices used in the mesh.
145
+ faces_per_material (dict): Dictionary collecting faces by material.
146
+ Keys are material names, values are lists of face definitions.
147
+ voxel_value_to_material (dict): Mapping from voxel values to material names.
148
+ Used to assign materials to faces based on voxel values.
149
+
150
+ Notes:
151
+ - Uses greedy meshing to combine adjacent same-value voxels
152
+ - Handles coordinate system conversion for proper orientation
153
+ - Maintains consistent face winding order for rendering
154
+ - Optimizes mesh by reusing vertices and combining faces
155
+ - Supports different coordinate systems for each axis
88
156
  """
89
157
 
90
158
  voxel_size = voxel_size_m
@@ -200,15 +268,44 @@ def mesh_faces(mask, layer_index, axis, positive_direction, normal_idx, voxel_si
200
268
 
201
269
  def export_obj(array, output_dir, file_name, voxel_size, voxel_color_map=None):
202
270
  """
203
- Export a voxel array to OBJ format with corrected face orientations.
271
+ Export a voxel array to OBJ format with materials and proper face orientations.
272
+
273
+ This function converts a 3D voxel array into a complete OBJ file with materials,
274
+ performing mesh optimization and ensuring proper face orientations. It generates
275
+ both OBJ and MTL files with all necessary components for rendering.
204
276
 
205
277
  Args:
206
- array (ndarray): 3D numpy array containing voxel values
207
- output_dir (str): Directory to save the OBJ and MTL files
208
- file_name (str): Base name for the output files
209
- voxel_size (float): Size of each voxel in meters
278
+ array (ndarray): 3D numpy array containing voxel values.
279
+ Non-zero values indicate voxel presence and material type.
280
+ output_dir (str): Directory to save the OBJ and MTL files.
281
+ Will be created if it doesn't exist.
282
+ file_name (str): Base name for the output files.
283
+ Will be used for both .obj and .mtl files.
284
+ voxel_size (float): Size of each voxel in meters.
285
+ Used to scale the model to real-world units.
210
286
  voxel_color_map (dict, optional): Dictionary mapping voxel values to RGB colors.
211
- If None, uses default color map.
287
+ If None, uses default color map. Colors should be RGB lists (0-255).
288
+
289
+ Notes:
290
+ - Generates optimized mesh using greedy meshing
291
+ - Creates complete OBJ file with vertices, normals, and faces
292
+ - Generates MTL file with material definitions
293
+ - Handles proper face orientation and winding order
294
+ - Supports color mapping for visualization
295
+ - Uses consistent coordinate system throughout
296
+
297
+ File Format Details:
298
+ OBJ file contains:
299
+ - Vertex coordinates (v)
300
+ - Normal vectors (vn)
301
+ - Material references (usemtl)
302
+ - Face definitions (f)
303
+
304
+ MTL file contains:
305
+ - Material names and colors
306
+ - Ambient, diffuse, and specular properties
307
+ - Transparency settings
308
+ - Illumination model definitions
212
309
  """
213
310
  if voxel_color_map is None:
214
311
  voxel_color_map = get_voxel_color_map()
@@ -367,19 +464,45 @@ def grid_to_obj(value_array_ori, dem_array_ori, output_dir, file_name, cell_size
367
464
  """
368
465
  Converts a 2D array of values and a corresponding DEM array to an OBJ file
369
466
  with specified colormap, transparency, and value range.
370
-
467
+
468
+ This function creates a 3D visualization of 2D grid data by using elevation
469
+ data and color mapping. It's particularly useful for visualizing terrain data,
470
+ analysis results, or any 2D data that should be displayed with elevation.
471
+
371
472
  Args:
372
- value_array_ori (ndarray): 2D array of values to visualize
373
- dem_array_ori (ndarray): 2D array of DEM values corresponding to value_array
374
- output_dir (str): Directory to save the OBJ and MTL files
375
- file_name (str): Base name for the output files
376
- cell_size (float): Size of each cell in the grid (e.g., in meters)
377
- offset (float): Elevation offset added after quantization
378
- colormap_name (str, optional): Name of the Matplotlib colormap to use. Defaults to 'viridis'
379
- num_colors (int, optional): Number of discrete colors to use from the colormap. Defaults to 256
380
- alpha (float, optional): Transparency value between 0.0 (transparent) and 1.0 (opaque). Defaults to 1.0
381
- vmin (float, optional): Minimum value for colormap normalization. If None, uses data minimum
382
- vmax (float, optional): Maximum value for colormap normalization. If None, uses data maximum
473
+ value_array_ori (ndarray): 2D array of values to visualize.
474
+ These values will be mapped to colors using the specified colormap.
475
+ dem_array_ori (ndarray): 2D array of DEM values corresponding to value_array.
476
+ Provides elevation data for the 3D visualization.
477
+ output_dir (str): Directory to save the OBJ and MTL files.
478
+ Will be created if it doesn't exist.
479
+ file_name (str): Base name for the output files.
480
+ Used for both .obj and .mtl files.
481
+ cell_size (float): Size of each cell in the grid (e.g., in meters).
482
+ Used to scale the model to real-world units.
483
+ offset (float): Elevation offset added after quantization.
484
+ Useful for adjusting the base height of the model.
485
+ colormap_name (str, optional): Name of the Matplotlib colormap to use.
486
+ Defaults to 'viridis'. Must be a valid Matplotlib colormap name.
487
+ num_colors (int, optional): Number of discrete colors to use from the colormap.
488
+ Defaults to 256. Higher values give smoother color transitions.
489
+ alpha (float, optional): Transparency value between 0.0 (transparent) and 1.0 (opaque).
490
+ Defaults to 1.0 (fully opaque).
491
+ vmin (float, optional): Minimum value for colormap normalization.
492
+ If None, uses data minimum. Used to control color mapping range.
493
+ vmax (float, optional): Maximum value for colormap normalization.
494
+ If None, uses data maximum. Used to control color mapping range.
495
+
496
+ Notes:
497
+ - Automatically handles NaN values in input arrays
498
+ - Creates triangulated mesh for proper rendering
499
+ - Supports transparency and color mapping
500
+ - Generates complete OBJ and MTL files
501
+ - Maintains consistent coordinate system
502
+ - Optimizes mesh generation for large grids
503
+
504
+ Raises:
505
+ ValueError: If vmin equals vmax or if colormap_name is invalid
383
506
  """
384
507
  # Validate input arrays
385
508
  if value_array_ori.shape != dem_array_ori.shape: