5656
5757Example::
5858
59- from gridData import OpenVDB
60- vdb_field = OpenVDB.field('density')
61- vdb_field.populate(grid, origin, delta )
62- vdb_field.write('output .vdb' )
59+ from gridData import Grid
60+
61+ g = Grid("data.dx" )
62+ g.export("data .vdb" )
6363
6464
6565Classes and functions
6868"""
6969
7070import numpy
71+ import warnings
7172
7273try :
7374 import openvdb as vdb
@@ -90,8 +91,9 @@ class OpenVDBField(object):
9091 -------
9192 Create a field and write it::
9293
93- vdb_field = OpenVDB.field('density')
94- vdb_field.populate(grid, origin, delta)
94+ import gridData.OpenVDB as OpenVDB
95+
96+ vdb_field = OpenVDB.OpenVDBField('density')
9597 vdb_field.write('output.vdb')
9698
9799 Or use directly from Grid::
@@ -101,7 +103,15 @@ class OpenVDBField(object):
101103
102104 """
103105
104- def __init__ (self , grid , origin , delta , name = "density" , tolerance = 1e-10 ):
106+ def __init__ (
107+ self ,
108+ grid = None ,
109+ origin = None ,
110+ delta = None ,
111+ name = "density" ,
112+ tolerance = None ,
113+ metadata = None ,
114+ ):
105115 """Initialize an OpenVDB field.
106116
107117 Parameters
@@ -114,9 +124,11 @@ def __init__(self, grid, origin, delta, name="density", tolerance=1e-10):
114124 Grid spacing (can be 1D array or diagonal matrix)
115125 name : str
116126 Name of the grid (will be visible in Blender), default 'density'
117- tolerance : float
127+ tolerance : float (optional)
118128 Values below this tolerance are treated as background (sparse),
119- default 1e-10
129+ default None
130+ metadata : dict (optional)
131+ Additional metadata to embed in the VDB file.
120132
121133 Raises
122134 ------
@@ -134,7 +146,17 @@ def __init__(self, grid, origin, delta, name="density", tolerance=1e-10):
134146 )
135147 self .name = name
136148 self .tolerance = tolerance
137- self ._populate (grid , origin , delta )
149+ if metadata is not None :
150+ self .metadata = metadata
151+ else :
152+ self .metadata = {}
153+
154+ if grid is not None :
155+ self ._populate (grid , origin , delta )
156+ else :
157+ self .grid = None
158+ self .origin = None
159+ self .delta = None
138160
139161 def _populate (self , grid , origin , delta ):
140162 """Populate the field with grid data.
@@ -155,12 +177,11 @@ def _populate(self, grid, origin, delta):
155177 non-orthorhombic cell
156178
157179 """
158- grid = numpy .asarray (grid )
180+ self . grid = numpy .asarray (grid )
159181 if grid .ndim != 3 :
160182 raise ValueError (f"OpenVDB only supports 3D grids, got { grid .ndim } D" )
161183
162- self .grid = grid .astype (numpy .float32 )
163- self .grid = numpy .ascontiguousarray (self .grid , dtype = numpy .float32 )
184+ self .grid = numpy .ascontiguousarray (self .grid )
164185
165186 self .origin = numpy .asarray (origin )
166187
@@ -193,16 +214,42 @@ def write(self, filename):
193214 filename : str
194215 Output filename (should end in .vdb)
195216
217+ Notes
218+ -----
219+ Limitations in OpenVDB can lead to loss of precision. If the input
220+ data is not of type float32, it will be converted to FloatGrid which is float32.
221+
196222 """
197223
198- vdb_grid = vdb .FloatGrid ()
224+ if self .grid .dtype == numpy .bool_ or self .grid .dtype == bool :
225+ vdb_grid = vdb .BoolGrid ()
226+ use_tolerance = False
227+
228+ else :
229+ vdb_grid = vdb .FloatGrid ()
230+ if self .tolerance == None or self .tolerance == 0 :
231+ use_tolerance = False
232+ else :
233+ use_tolerance = True
234+
199235 vdb_grid .name = self .name
200236
201237 vdb_grid .transform = vdb .createLinearTransform ()
202238 vdb_grid .transform .preScale (self .delta .tolist ())
203239 vdb_grid .transform .postTranslate (self .origin .tolist ())
204240
205- vdb_grid .copyFromArray (self .grid , tolerance = self .tolerance )
206- vdb_grid .prune ()
241+ if self .metadata :
242+ for key , val in self .metadata .items ():
243+ try :
244+ vdb_grid [key ] = val
245+ except (TypeError , ValueError ) as e :
246+ warnings .warn (f"Could not set metadata '{ key } ': { e } " , UserWarning )
247+
248+ if use_tolerance :
249+ vdb_grid .copyFromArray (self .grid , tolerance = self .tolerance )
250+ vdb_grid .prune ()
251+ else :
252+ vdb_grid .copyFromArray (self .grid )
253+ vdb_grid .prune (tolerance = False )
207254
208255 vdb .write (filename , grids = [vdb_grid ])
0 commit comments