163 class BlockModelRaster :
public BlockLookupNode<t_size, uint04>
169 inline BlockModelRaster<t_point_type, t_size, t_weight_type>& operator[](
uint04 index)
171 uint04 size = m_safe_rasters.size();
173 return m_safe_rasters[index];
175 return m_edit_rasters[index - size];
177 inline const BlockModelRaster<t_point_type, t_size, t_weight_type>& operator[](
uint04 index)
const
179 uint04 size = m_safe_rasters.size();
181 return m_safe_rasters[index];
183 return m_edit_rasters[index - size];
188 m_safe_rasters.ensureCapacity(t_size * t_size * t_size);
189 m_edit_rasters.ensureCapacity(t_size * t_size);
193 m_safe_rasters.clear();
194 m_edit_rasters.clear();
196 inline void add(
const BlockModelRaster<t_point_type, t_size, t_weight_type>& value)
198 if (m_safe_rasters.capacity() > m_safe_rasters.size())
199 m_safe_rasters.add(value);
201 m_edit_rasters.add(value);
205 if (m_edit_rasters.size() == 0)
208 m_adding_cache =
true;
210 m_safe_rasters.ensureCapacity(((m_safe_rasters.size() * 3) / 2) + 4U * m_edit_rasters.size());
211 m_adding_cache =
false;
212 uint04 safe_initial_size = m_safe_rasters.size();
213 uint04 available_space = m_safe_rasters.capacity() - safe_initial_size;
214 if (available_space == 0)
217 m_safe_rasters.template addSpace<false>(add_size);
218 for (
uint04 i = 0; i < add_size; i++)
219 m_safe_rasters[safe_initial_size + i] = m_edit_rasters[i];
220 m_edit_rasters.removeIndices(0, add_size);
222 inline uint04 size()
const
224 return m_safe_rasters.size() + m_edit_rasters.size();
226 inline uint04 safeSize()
const
228 return m_safe_rasters.size();
230 inline bool requestUsingSafe(
bool using_safe)
237 m_using_safe =
false;
241 m_using_safe = using_safe;
244 inline void forceUsingSafe()
254 PrimitiveBuffer<BlockModelRaster<t_point_type, t_size, t_weight_type>> m_safe_rasters;
255 PrimitiveBuffer<BlockModelRaster<t_point_type, t_size, t_weight_type>> m_edit_rasters;
256 volatile bool m_adding_cache =
false;
257 volatile bool m_using_safe =
false;
259 struct SurfacingCache
261 SurfacingCache(GeometrySurfacingParameters& parameters,
const RasterBuffer& rasters)
262 : grid(t_size, t_size, t_size)
264 , parameters(parameters)
268 MC33<t_point_type> mc33;
269 GeometrySurfacingParameters& parameters;
270 const RasterBuffer& rasters;
271 t_weight_type weight_cutoff;
275 RasterNode(BlockModelRaster<t_point_type, t_size, t_weight_type>& geo,
uint04 initial_reserve_count)
277 , vertex_index(initial_reserve_count)
279 inline void updateColorAverage(
const RGBColor color,
uint08 weight)
281 raster.updateColorAverage(vertex_index, color, weight);
283 BlockModelRaster<t_point_type, t_size, t_weight_type>& raster;
289 for (
uint04 i = 0; i < Size(); i++)
290 weight_information[i] = t_weight_type(0U);
296 inline void updateColorAverage(
uint04 index,
const t_point_type color)
298 if (weight_information[index] == 0)
300 else if (weight_information[index] >= (Constant<t_weight_type>::Max >> 8))
302 node_information[index] += color;
303 weight_information[index]++;
306 inline void updateColorAverage(
uint04 index,
const t_point_type color, t_weight_type weight)
310 if (weight_information[index] == 0)
312 t_weight_type new_weight = weight_information[index] + weight;
313 if (new_weight > (Constant<t_weight_type>::Max >> 8))
315 node_information[index] = combine(node_information[index], weight_information[index], color, weight);
316 weight_information[index] = new_weight;
319 inline void addWeight(
uint04 index, t_weight_type weight)
321 if (weight_information[index] == 0)
323 weight_information[index] += weight;
326 inline void subtractWeight(
uint04 index, t_weight_type weight)
328 if (weight_information[index] == 0)
330 weight_information[index] =
getMin(weight_information[index], weight);
331 if (weight_information[index] == 0)
335 inline void removeIndex(
uint04 index)
337 if (weight_information[index] == 0)
339 node_information[index] = t_point_type();
340 weight_information[index] = t_weight_type(0U);
344 inline void clearAll()
346 for (
uint04 i = 0; i < Size(); i++)
348 weight_information[i] = t_weight_type(0U);
349 node_information[i] = t_point_type();
354 inline t_point_type colorAt(
uint04 index)
const
356 return node_information[index];
358 template<
class t_special_weight_type>
359 inline void getWeightAndColor(
uint04 x,
uint04 y,
uint04 z,
const RasterBuffer& rasters, t_point_type& color, t_special_weight_type& value)
362 const uint04 index = BlockLookupNode<t_size, uint04>::ConvertToIndex(index_offset);
363 t_weight_type weight(0U);
371 if (
IsValid(corner_tri_neighbor))
373 weight = rasters[corner_tri_neighbor].weight_information[index];
374 point = rasters[corner_tri_neighbor].node_information[index];
379 if (
IsValid(corner_neighbors[Z]))
381 weight = rasters[corner_neighbors[Z]].weight_information[index];
382 point = rasters[corner_neighbors[Z]].node_information[index];
386 else if (z >= t_size)
388 if (
IsValid(corner_neighbors[Y]))
390 weight = rasters[corner_neighbors[Y]].weight_information[index];
391 point = rasters[corner_neighbors[Y]].node_information[index];
396 if (
IsValid(upper_neighbors[X]))
398 weight = rasters[upper_neighbors[X]].weight_information[index];
399 point = rasters[upper_neighbors[X]].node_information[index];
403 else if (y >= t_size)
407 if (
IsValid(corner_neighbors[X]))
409 weight = rasters[corner_neighbors[X]].weight_information[index];
410 point = rasters[corner_neighbors[X]].node_information[index];
415 if (
IsValid(upper_neighbors[Y]))
417 weight = rasters[upper_neighbors[Y]].weight_information[index];
418 point = rasters[upper_neighbors[Y]].node_information[index];
422 else if (z >= t_size)
424 if (
IsValid(upper_neighbors[Z]))
426 weight = rasters[upper_neighbors[Z]].weight_information[index];
427 point = rasters[upper_neighbors[Z]].node_information[index];
432 weight = weight_information[index];
433 point = node_information[index];
437 color = t_point_type();
438 value = t_special_weight_type(0);
443 value = t_special_weight_type(weight);
446 inline void calculateTriangulation(SurfacingCache& cache)
448 if (point_count == 0)
450 for (
uint04 z = 0; z < t_size; z++)
452 for (
uint04 y = 0; y < t_size; y++)
454 for (
uint04 x = 0; x < t_size; x++)
456 const uint04 index = BlockLookupNode<t_size, uint04>::ConvertToIndex(x, y, z);
457 cache.grid.nodes[x][y][z] = node_information[index];
461 getWeightAndColor(t_size, y, z, cache.rasters, cache.grid.nodes[t_size][y][z], cache.grid.values[t_size][y][z]);
463 for (
uint04 x = 0; x < t_size + 1; x++)
464 getWeightAndColor(x, t_size, z, cache.rasters, cache.grid.nodes[x][t_size][z], cache.grid.values[x][t_size][z]);
466 for (
uint04 y = 0; y < t_size + 1; y++)
468 for (
uint04 x = 0; x < t_size + 1; x++)
470 getWeightAndColor(x, y, t_size, cache.rasters, cache.grid.nodes[x][y][t_size], cache.grid.values[x][y][t_size]);
473 for (
uint04 i = 0; i < 2; i++)
475 for (
uint04 z = 0; z < t_size + 1; z++)
477 for (
uint04 y = 0; y < t_size + 1; y++)
479 for (
uint04 x = 0; x < t_size + 1; x++)
481 if (cache.grid.values[x][y][z] == 0)
483 if (z < t_size && cache.grid.values[x][y][z + 1] != 0)
485 cache.grid.nodes[x][y][z] = cache.grid.nodes[x][y][z + 1];
487 else if (y < t_size && cache.grid.values[x][y + 1][z] != 0)
489 cache.grid.nodes[x][y][z] = cache.grid.nodes[x][y + 1][z];
491 else if (x < t_size && cache.grid.values[x + 1][y][z] != 0)
493 cache.grid.nodes[x][y][z] = cache.grid.nodes[x + 1][y][z];
495 else if (z > 0 && cache.grid.values[x][y][z - 1] != 0)
497 cache.grid.nodes[x][y][z] = cache.grid.nodes[x][y][z - 1];
499 else if (y > 0 && cache.grid.values[x][y - 1][z] != 0)
501 cache.grid.nodes[x][y][z] = cache.grid.nodes[x][y - 1][z];
503 else if (x > 0 && cache.grid.values[x - 1][y][z] != 0)
505 cache.grid.nodes[x][y][z] = cache.grid.nodes[x - 1][y][z];
514 CubeTriangulation::calculate_isosurface(cache.mc33,
cast<fltp04>(cache.weight_cutoff) - 0.1f);
516 uint04 vertex_offset = cache.parameters.surface_positions.size();
517 cache.parameters.surface_positions.template addSpace<true>(cache.mc33.nV);
519 if constexpr (t_point_type::HasColor())
520 cache.parameters.surface_colors.template addSpace<true>(cache.mc33.nV);
523 for (
uint04 i = 0; i < cache.mc33.nV; i++)
525 Vertex<3, fltp04> location_offset(cache.mc33.V[i][2], cache.mc33.V[i][1], cache.mc33.V[i][0]);
526 if constexpr (t_point_type::HasColor())
527 cache.parameters.surface_colors[i + vertex_offset] = cache.mc33.C[i].color();
528 cache.parameters.surface_positions[i + vertex_offset] = location_f + location_offset;
529 if constexpr (t_point_type::HasOffset())
530 cache.parameters.surface_positions[i + vertex_offset] += cache.mc33.C[i].offset();
533 uint04 tri_offset = cache.parameters.surface_triangles.size();
534 cache.parameters.surface_triangles.template addSpace<true>(cache.mc33.nT);
535 for (
uint04 i = 0; i < cache.mc33.nT; i++)
537 Vector<3, uint04> tri(cache.mc33.T[i][0], cache.mc33.T[i][1], cache.mc33.T[i][2]);
539 tri += vertex_offset;
542 cache.parameters.surface_triangles[i + tri_offset] = tri;
547 BlockLookupNode<t_size, t_weight_type>::indices[BlockLookupNode<t_size, uint04>::ConvertToIndex(x, y, z)] > 0;
549 template<
bool t_set_indices>
552 if (point_count == 0)
556 for (
uint04 i = 0; i < Size(); i++)
558 if (weight_information[i] >= cache.weight_cutoff)
560 if constexpr (t_set_indices)
561 BlockLookupNode<t_size, t_weight_type>::indices[i] = cache.geo_add_locations.size();
562 cache.geo_add_locations.add((location + BlockLookupNode<t_size, uint04>::ConvertFromIndex(i)));
563 cache.geo_add_info.add(node_information[i]);
564 cache.geo_add_weight.add(weight_information[i]);
570 if (!is_dirty || point_count == 0)
572 for (
uint04 i = 0; i < Size(); i++)
574 if (weight_information[i] >= cache.weight_cutoff)
576 if (
IsInvalid(BlockLookupNode<t_size, t_weight_type>::indices[i]))
578 BlockLookupNode<t_size, t_weight_type>::indices[i] = cache.geo_vertex_add_offset + cache.geo_add_locations.size();
579 cache.geo_add_locations.add((location + BlockLookupNode<t_size, uint04>::ConvertFromIndex(i)));
580 cache.geo_add_info.add(node_information[i]);
581 cache.geo_add_weight.add(weight_information[i]);
588 if (point_count == 0)
590 switch (filter.classifyToFilter(bounds()))
592 case IntersectionTypes::e_outside:
594 case IntersectionTypes::e_inside:
597 for (
uint04 i = 0; i < Size(); i++)
599 if (weight_information[i] > 0)
601 Vector<3, uint04> vertex_location = (BlockLookupNode<t_size, uint04>::ConvertFromIndex(i) + location);
602 filter.onFiltered(vertex_location, node_information[i], weight_information[i]);
603 node_information[i] = t_point_type();
611 case IntersectionTypes::e_mixed:
613 for (
uint04 i = 0; i < Size(); i++)
615 if (weight_information[i] > 0)
617 Vector<3, uint04> vertex_location = (BlockLookupNode<t_size, uint04>::ConvertFromIndex(i) + location);
618 if (filter.shouldFilter(vertex_location, node_information[i], weight_information[i]))
620 filter.onFiltered(vertex_location, node_information[i], weight_information[i]);
621 node_information[i] = t_point_type();
635 if (!is_dirty ||
IsInvalid(cache.geo_vertex_offset))
642 for (
uint04 i = 0; i < Size(); i++)
644 const uint04 vert_index = BlockLookupNode<t_size, uint04>::indices[i] + cache.geo_vertex_offset;
645 if (weight_information[i] >= cache.weight_cutoff)
650 if constexpr (t_point_type::HasOffset())
652 Vector<3, fltp04> position = (location + BlockLookupNode<t_size, uint04>::ConvertFromIndex(i)).
template as<3, fltp04>() + node_information[i].offset();
653 if (position != cache.position_column.template get<
Vector<3, fltp04>>(vert_index))
655 cache.position_column.
set(vert_index, position);
656 cache.position_update_bounds.
addToBounds(vert_index);
659 if constexpr (t_point_type::HasColor())
661 RGBColor color = node_information[i].color();
662 if (color != cache.color_column.template get<RGBColor>(vert_index))
664 cache.color_column.
set(vert_index, color);
668 if constexpr (t_point_type::HasNormal())
670 Ray<3, fltp04> normal = node_information[i].normal();
671 if (normal != cache.normal_column.template get<Ray<3, fltp04>>(vert_index))
673 cache.normal_column.
set(vert_index, normal);
674 cache.normal_update_bounds.
addToBounds(vert_index);
678 if (weight != cache.weight_column.template get<fltp04>(vert_index))
680 cache.weight_column.
set(vert_index, weight);
681 cache.weight_update_bounds.
addToBounds(vert_index);
683 if (0 != cache.flag_column.template get<uint01>(vert_index))
685 cache.flag_column.
set(vert_index, 0U);
691 if (filtered_flag !=
BitFlag(cache.flag_column.template get<uint01>(vert_index)))
693 cache.flag_column.
set(vert_index, filtered_flag);
699 constexpr static uint04 Size() {
return t_size * t_size * t_size; }
700 t_point_type node_information[t_size * t_size * t_size];
701 t_weight_type weight_information[t_size * t_size * t_size];
706 uint04 corner_tri_neighbor = Constant<uint04>::Invalid;
707 bool is_dirty =
false;