@@ -182,12 +182,26 @@ struct MultiResGridFractionalOp
182182 template <typename GridType>
183183 void operator ()(const GridType& grid)
184184 {
185+ using TreeT = typename GridType::TreeType;
185186 if ( level <= 0 .0f ) {
186187 outputGrid = typename GridType::Ptr ( new GridType (grid) );
187188 } else {
188189 const size_t levels = openvdb::math::Ceil (level) + 1 ;
189- using TreeT = typename GridType::TreeType;
190- openvdb::tools::MultiResGrid<TreeT> mrg ( levels, grid );
190+ const GridType* gridPtr = &grid;
191+ #if OPENVDB_ABI_VERSION_NUMBER >= 7 // Grid::copyReplacingMetadata() only available in ABI>=7
192+ // if grid already has MultiResGrid_Level metadata with type int64, remove it
193+ typename GridType::ConstPtr newGridPtr;
194+ auto meta = grid.template getMetadata <openvdb::Int64Metadata>(" MultiResGrid_Level" );
195+ if (meta) {
196+ // deep copy meta map and remove element
197+ openvdb::MetaMap metaMap (static_cast <const openvdb::MetaMap&>(grid));
198+ metaMap.removeMeta (" MultiResGrid_Level" );
199+ // the tree and transform are shared with the input grid, but meta map is different
200+ newGridPtr = grid.copyReplacingMetadata (metaMap);
201+ gridPtr = newGridPtr.get ();
202+ }
203+ #endif
204+ openvdb::tools::MultiResGrid<TreeT> mrg ( levels, *gridPtr );
191205 outputGrid = mrg.template createGrid <Order>( level );
192206 }
193207 }
@@ -205,10 +219,24 @@ struct MultiResGridRangeOp
205219 template <typename GridType>
206220 void operator ()(const GridType& grid)
207221 {
222+ using TreeT = typename GridType::TreeType;
208223 if ( end > 0 .0f ) {
209224 const size_t levels = openvdb::math::Ceil (end) + 1 ;
210- using TreeT = typename GridType::TreeType;
211- openvdb::tools::MultiResGrid<TreeT> mrg ( levels, grid );
225+ const GridType* gridPtr = &grid;
226+ #if OPENVDB_ABI_VERSION_NUMBER >= 7 // Grid::copyReplacingMetadata() only available in ABI>=7
227+ // if grid already has MultiResGrid_Level metadata with type int64, remove it
228+ typename GridType::ConstPtr newGridPtr;
229+ auto meta = grid.template getMetadata <openvdb::Int64Metadata>(" MultiResGrid_Level" );
230+ if (meta) {
231+ // deep copy meta map and remove element
232+ openvdb::MetaMap metaMap (static_cast <const openvdb::MetaMap&>(grid));
233+ metaMap.removeMeta (" MultiResGrid_Level" );
234+ // the tree and transform are shared with the input grid, but meta map is different
235+ newGridPtr = grid.copyReplacingMetadata (metaMap);
236+ gridPtr = newGridPtr.get ();
237+ }
238+ #endif
239+ openvdb::tools::MultiResGrid<TreeT> mrg ( levels, *gridPtr );
212240
213241 // inclusive range
214242 for (float level = start; !(level > end); level += step) {
@@ -231,7 +259,21 @@ struct MultiResGridIntegerOp
231259 void operator ()(const GridType& grid)
232260 {
233261 using TreeT = typename GridType::TreeType;
234- openvdb::tools::MultiResGrid<TreeT> mrg ( levels, grid );
262+ const GridType* gridPtr = &grid;
263+ #if OPENVDB_ABI_VERSION_NUMBER >= 7 // Grid::copyReplacingMetadata() only available in ABI>=7
264+ // if grid already has MultiResGrid_Level metadata with type float, remove it
265+ typename GridType::ConstPtr newGridPtr;
266+ auto meta = grid.template getMetadata <openvdb::FloatMetadata>(" MultiResGrid_Level" );
267+ if (meta) {
268+ // deep copy meta map and remove element
269+ openvdb::MetaMap metaMap (static_cast <const openvdb::MetaMap&>(grid));
270+ metaMap.removeMeta (" MultiResGrid_Level" );
271+ // the tree and transform are shared with the input grid, but meta map is different
272+ newGridPtr = grid.copyReplacingMetadata (metaMap);
273+ gridPtr = newGridPtr.get ();
274+ }
275+ #endif
276+ openvdb::tools::MultiResGrid<TreeT> mrg ( levels, *gridPtr );
235277 outputGrids = mrg.grids ();
236278 }
237279 const size_t levels;
0 commit comments