2#include "BlockModel/Headers/BlockModelRaster.h"
3#include "NDEVRSurfacing/Headers/GeometrySurfacing.h"
4#include "Design/Headers/GeometrySelectionOptimizer.h"
5#include "Design/Headers/Material.h"
6#include "Base/Headers/Translator.h"
7#include "Base/Headers/ObjectInfo.h"
14 template<
class t_po
int_type, u
int04 t_depth, u
int04 t_size,
class t_weight_type>
21 m_lookup_nodes.ensureCapacity(t_size * t_size);
30 uint04 index = m_root_lookup.get(zone_index);
32 return Constant<uint04>::Invalid;
33 for (
uint04 i = 1; i < t_depth - 1; i++)
36 zone_index = ConvertToZoneIndex(zone, i);
37 index = node.get(zone_index);
39 return Constant<uint04>::Invalid;
47 uint04 index = m_root_lookup.get(zone_index);
50 index = m_lookup_nodes.size();
52 m_root_lookup.set(zone_index, index);
54 for (
uint04 i = 1; i < t_depth - 1; i++)
57 zone_index = ConvertToZoneIndex(zone, i);
58 index = node.get(zone_index);
63 index = m_rasters.size();
64 node.set(zone_index, index);
66 updateAdjacentList(index, location);
70 index = m_lookup_nodes.size();
71 node.set(zone_index, index);
80 if constexpr (t_size == 8)
82 for (
uint01 n = 0; n < 3; n++)
83 location[n] = (location[n] >> (3 * ((t_depth - 1) - i))) & (7U);
87 location = (location % (s_factor_table[i + 1]) / s_factor_table[i]);
93 return m_rasters[getRasterIndex(location)];
97 const uint04 size = points.size();
99 uint04 raster_index = Constant<uint04>::Invalid;
105 for (
uint04 i = 0; i < size; i++)
108 if (!(block_location < t_size))
110 raster_index = getRasterIndex(points[i]);
111 raster_location = m_rasters[raster_index].location;
112 block_location = points[i] - raster_location;
114 uint04 index = BlockLookupNode<t_size, uint04>::ConvertToIndex(block_location);
115 m_rasters[raster_index].updateColorAverage(index, colors[i]);
118 for (
uint04 i = 0; i < size; i++)
120 uint04 raster_index = getRasterIndex(points[i]);
121 uint04 index = BlockLookupNode<t_size, uint04>::ConvertToIndex(points[i] - m_rasters[raster_index].location);
122 m_rasters[raster_index].updateColorAverage(index, colors[i], weight);
128 const uint04 size = points.size();
130 uint04 raster_index = Constant<uint04>::Invalid;
131 for (
uint04 i = 0; i < size; i++)
134 if (!(block_location < t_size))
136 raster_index = getRasterIndex(points[i]);
137 raster_location = m_rasters[raster_index].location;
138 block_location = points[i] - raster_location;
140 uint04 index = BlockLookupNode<t_size, uint04>::ConvertToIndex(block_location);
141 m_rasters[raster_index].updateColorAverage(index, colors[i], weights[i]);
146 const uint04 size = points.size();
147 for (
uint04 i = 0; i < size; i++)
149 uint04 raster_index = getRasterIndex(points[i]);
150 uint04 index = BlockLookupNode<t_size, uint04>::ConvertToIndex(points[i] - m_rasters[raster_index].location);
151 m_rasters[raster_index].addWeight(index, weight);
154 inline void addPoint(
const Vector<3, uint04>& point,
const t_point_type& color, t_weight_type weight)
noexcept
156 uint04 raster_index = getRasterIndex(point);
157 uint04 index = BlockLookupNode<t_size, uint04>::ConvertToIndex(point - m_rasters[raster_index].location);
158 m_rasters[raster_index].updateColorAverage(index, color, weight);
160 inline void addWeight(
const Vector<3, uint04>& point, t_weight_type weight)
noexcept
162 uint04 raster_index = getRasterIndex(point);
163 uint04 index = BlockLookupNode<t_size, uint04>::ConvertToIndex(point - m_rasters[raster_index].location);
164 m_rasters[raster_index].addWeight(index, weight);
166 inline void subtractWeight(
const Vector<3, uint04>& point, t_weight_type weight)
noexcept
168 uint04 raster_index = getRasterIndex(point);
169 uint04 index = BlockLookupNode<t_size, uint04>::ConvertToIndex(point - m_rasters[raster_index].location);
170 m_rasters[raster_index].subtractWeight(index, weight);
175 m_lookup_nodes.clear();
176 m_root_lookup.clear();
177 m_clear_geometry =
true;
181 uint04 raster_size = m_rasters.safeSize();
182 for (
uint04 i = 0; i < raster_size; i++)
184 m_is_dirty |= m_rasters[i].filterGeometries(filter);
189 uint04 raster_size = m_rasters.safeSize();
190 for (
uint04 i = 0; i < raster_size; i++)
191 m_rasters[i].collectAllPositions<false>(cache);
197 if (!m_rasters.requestUsingSafe(
true))
200 uint04 raster_size = m_rasters.safeSize();
201 if (m_clear_geometry)
203 WLock lock(cache.lock_ptr);
204 cache.geo.clearVerticesAndPrimitives();
205 cache.geo_vertex_offset = 0U;
206 cache.geo_vertex_add_offset = 0U;
207 for (
uint04 i = 0; i < raster_size; i++)
208 m_rasters[i].
template collectAllPositions<true>(cache);
212 for (
uint04 i = 0; i < raster_size; i++)
213 m_rasters[i].collectNewPositions(cache);
215 bool updated =
false;
216 if (cache.geo_add_locations.size() > 0)
218 m_rasters.requestUsingSafe(
false);
219 WLock lock(cache.lock_ptr);
220 uint04 old_size = cache.geo.vertexCount();
221 if (old_size == 0 && cache.geo_add_locations.size() == 0)
223 cache.geo.addVertices(cache.geo_add_locations.size());
224 cache.geo_vertex_offset = cache.geo.vertexOffset();
225 const uint04 vertex_offset = old_size + cache.geo_vertex_offset;
226 for (
uint04 i = 0; i < cache.geo_add_locations.size(); i++)
228 uint04 index = vertex_offset + i;
229 if constexpr (t_point_type::HasOffset())
230 cache.position_column.set(index, cache.geo_add_locations[i].template as<3, fltp04>() + cache.geo_add_info[i].offset());
232 cache.position_column.set(index, cache.geo_add_locations[i]);
233 if constexpr (t_point_type::HasNormal())
234 cache.normal_column.set(index, cache.geo_add_info[i].normal());
235 if constexpr (t_point_type::HasColor())
236 cache.color_column.set(index, cache.geo_add_info[i].color());
237 cache.flag_column.set(index, 0U);
238 cache.weight_column.set(index, cache.geo_add_weight[i]);
241 if constexpr (t_point_type::HasNormal())
243 if constexpr (t_point_type::HasColor())
248 m_rasters.forceUsingSafe();
250 if (m_clear_geometry)
252 m_clear_geometry =
false;
255 for (
uint04 i = 0; i < raster_size; i++)
256 m_rasters[i].updateGeometryVertices(cache);
257 m_rasters.requestUsingSafe(
false);
258 updated |= cache.flag_update_bounds.
validate();
259 updated |= cache.color_update_bounds.
validate();
260 updated |= cache.normal_update_bounds.
validate();
261 updated |= cache.position_update_bounds.
validate();
262 updated |= cache.weight_update_bounds.
validate();
265 WLock lock(cache.lock_ptr);
267 if (cache.position_update_bounds.
validate())
269 if (cache.flag_update_bounds.
validate())
271 if (cache.color_update_bounds.
validate())
273 if (cache.weight_update_bounds.
validate())
275 if (cache.normal_update_bounds.
validate())
278 cache.geo.updateModifiedTime(update_time);
287 inline void calculateTriangulation(GeometrySurfacingParameters& parameters,
uint04 weight_cutoff)
noexcept
289 ProgressInfo progress(_t(
"Calculating Triangles"), parameters.log, 0.0f);
290 typename BlockModelRaster<t_point_type, t_size, t_weight_type>::SurfacingCache cache(parameters, m_rasters);
291 cache.weight_cutoff = weight_cutoff;
292 for (
uint04 i = 0; i < m_rasters.size(); i++)
294 m_rasters[i].calculateTriangulation(cache);
296 progress.setProgress(
cast<fltp04>(i) / m_rasters.size());
299 inline void syncRasters()
301 this->m_rasters.sync();
302 this->m_is_dirty =
true;
305 template<
bool t_positive>
312 if (zone[depth][dim] < t_size - 1)
317 zone[depth][dim] = 0;
324 if (zone[depth][dim] > 0)
329 zone[depth][dim] = t_size - 1;
338 for (
uint04 dim = 0; dim < 3; dim++)
342 ComputeNeighborZone<true>(new_zone, dim);
343 value.upper_neighbors[dim] = rasterAt(new_zone);
344 ComputeNeighborZone<true>(new_zone, (dim + 1) % 3);
345 value.corner_neighbors[(dim + 2) % 3] = rasterAt(new_zone);
348 ComputeNeighborZone<true>(new_zone, (dim + 2) % 3);
349 value.corner_tri_neighbor = rasterAt(new_zone);
353 ComputeNeighborZone<false>(new_zone, dim);
354 uint04 neigbor_index = rasterAt(new_zone);
356 m_rasters[neigbor_index].upper_neighbors[dim] = index;
357 ComputeNeighborZone<false>(new_zone, (dim + 1) % 3);
358 neigbor_index = rasterAt(new_zone);
360 m_rasters[neigbor_index].corner_neighbors[(dim + 2) % 3] = index;
363 ComputeNeighborZone<false>(new_zone, (dim + 2) % 3);
364 neigbor_index = rasterAt(new_zone);
366 m_rasters[neigbor_index].corner_tri_neighbor = index;
374 for (
uint01 dim = 0; dim < 3; dim++)
378 new_zone[dim] += t_size;
379 value.upper_neighbors[dim] = rasterAt(new_zone);
380 new_zone[(dim + 1) % 3] += t_size;
381 value.corner_neighbors[(dim + 2) % 3] = rasterAt(new_zone);
384 new_zone[(dim + 2) % 3] += t_size;
385 value.corner_tri_neighbor = rasterAt(new_zone);
389 new_zone[dim] -= t_size;
390 uint04 neigbor_index = rasterAt(new_zone);
392 m_rasters[neigbor_index].upper_neighbors[dim] = index;
393 new_zone[(dim + 1) % 3] -= t_size;
394 neigbor_index = rasterAt(new_zone);
396 m_rasters[neigbor_index].corner_neighbors[(dim + 2) % 3] = index;
399 new_zone[(dim + 2) % 3] -= t_size;
400 neigbor_index = rasterAt(new_zone);
402 m_rasters[neigbor_index].corner_tri_neighbor = index;
414 static_assert(t_depth >= 1,
"Must have depth");
416 typename BlockModelRaster<t_point_type, t_size, t_weight_type>::RasterBuffer m_rasters;
420 static constexpr uint04 s_factor_table[8] =
422 cipow(t_size, t_depth - 0 - 1)
423 ,
cipow(t_size, t_depth - 1 - 1)
424 ,
cipow(t_size, t_depth - 2 - 1)
425 ,
cipow(t_size, t_depth - 3 - 1)
426 ,
cipow(t_size, t_depth - 4 - 1)
427 ,
cipow(t_size, t_depth - 5 - 1)
428 ,
cipow(t_size, t_depth - 6 - 1)
429 ,
cipow(t_size, t_depth - 7 - 1)
440 bool m_is_dirty =
false;
441 bool m_clear_geometry =
false;
447 template<
class t_po
int_type>
448 class SegmentedBlockModel :
public Model
453 , m_grid_span4(grid_span)
454 , m_inverse_grid_span4(1.0f / grid_span)
457 initBlockBackend(bounds);
462 , m_grid_span4(grid_span)
463 , m_inverse_grid_span4(1.0f / grid_span)
466 initBlockBackend(bounds);
477 ~SegmentedBlockModel() {};
478 static constexpr StringView TypeName() {
return "segmented_block_model"; }
485 grid_points.setSize(
size);
486 grid_weights.setSize(
size);
489 grid_points[i] = convertPoint(points[i]);
490 if constexpr (t_point_type::HasOffset())
491 colors[i].setOffset(points[i].as<3, fltp04>() - grid_points[i].as<3, fltp04>());
494 addPoints(grid_points, colors, grid_weights);
500 grid_points.setSize(
size);
503 if constexpr (!t_point_type::HasOffset())
505 grid_points[i] = convertPoint(points[i]);
509 grid_points[i] = convertPointAndLeaveOffset(points[i]);
510 colors[i].setOffset(points[i]);
513 addPoints(grid_points, colors, weights);
515 template<
class t_other_type>
520 grid_points.setSize(
size);
522 converted_points.setSize(colors.size());
525 converted_points[i] = colors[i].template getAs<t_point_type>();
526 if constexpr (t_point_type::HasOffset())
529 grid_points[i] = convertPointAndLeaveOffset(p0);
530 converted_points[i].setOffset(p0);
534 grid_points[i] = convertPoint(points[i]);
537 addPoints(grid_points, converted_points, weights);
543 grid_points.setSize(
size);
546 if constexpr (t_point_type::HasOffset())
548 grid_points[i] = convertPointAndLeaveOffset(points[i]);
549 colors[i].setOffset(points[i]);
553 grid_points[i] = convertPoint(points[i]);
562 grid_points.setSize(
size);
565 if constexpr (t_point_type::HasOffset())
567 grid_points[i] = convertPointAndLeaveOffset(points[i]);
568 colors[i].setOffset(points[i]);
572 grid_points[i] = convertPoint(points[i]);
577 template<
class t_other_type>
582 grid_points.setSize(
size);
584 converted_points.setSize(colors.size());
588 for (
uint01 n = 0; n < 6; n++)
589 converted_points[i][n] = colors[i][n];
590 if constexpr (!t_point_type::HasOffset())
592 grid_points[i] = convertPointAndLeaveOffset(points[i]);
593 converted_points[i].setOffset(points[i]);
597 grid_points[i] = convertPoint(points[i]);
600 addPoints(grid_points, converted_points,
cast<uint04>(weight));
606 case 2: b2.addPoints(points, colors, weight);
break;
607 case 3: b3.addPoints(points, colors, weight);
break;
608 case 4: b4.addPoints(points, colors, weight);
break;
609 case 5: b5.addPoints(points, colors, weight);
break;
610 case 6: b6.addPoints(points, colors, weight);
break;
617 case 2: b2.addPoints(points, colors, weights);
break;
618 case 3: b3.addPoints(points, colors, weights);
break;
619 case 4: b4.addPoints(points, colors, weights);
break;
620 case 5: b5.addPoints(points, colors, weights);
break;
621 case 6: b6.addPoints(points, colors, weights);
break;
628 case 2: b2.addPoints(points, weight);
break;
629 case 3: b3.addPoints(points, weight);
break;
630 case 4: b4.addPoints(points, weight);
break;
631 case 5: b5.addPoints(points, weight);
break;
632 case 6: b6.addPoints(points, weight);
break;
639 case 2: b2.addWeight(point, weight);
break;
640 case 3: b3.addWeight(point, weight);
break;
641 case 4: b4.addWeight(point, weight);
break;
642 case 5: b5.addWeight(point, weight);
break;
643 case 6: b6.addWeight(point, weight);
break;
650 case 2: b2.filterGeometries(filter);
break;
651 case 3: b3.filterGeometries(filter);
break;
652 case 4: b4.filterGeometries(filter);
break;
653 case 5: b5.filterGeometries(filter);
break;
654 case 6: b6.filterGeometries(filter);
break;
661 case 2: b2.clearAll();
break;
662 case 3: b3.clearAll();
break;
663 case 4: b4.clearAll();
break;
664 case 5: b5.clearAll();
break;
665 case 6: b6.clearAll();
break;
670 addPoint(convertPoint(point), color, weight);
674 addPoint(convertPoint(point), weight);
678 return ((point * m_inverse_grid_span4) + m_point_offset4).as<3,
uint04>();
682 return ((point * m_inverse_grid_span4) + m_point_offset4).as<3,
fltp04>();
688 point = loc - loc_a.
as<3,
fltp04>();
695 point = loc - loc_a.
as<3,
fltp08>();
700 return ((point * m_inverse_grid_span8) + m_point_offset8).as<3,
uint04>();
704 return Matrix<fltp08>::ScalerMatrix(m_grid_span8).offset(-m_point_offset8);
714 case 2: b2.addPoint(point, color, weight);
break;
715 case 3: b3.addPoint(point, color, weight);
break;
716 case 4: b4.addPoint(point, color, weight);
break;
717 case 5: b5.addPoint(point, color, weight);
break;
718 case 6: b6.addPoint(point, color, weight);
break;
725 case 2: this->b2.syncRasters();
break;
726 case 3: this->b3.syncRasters();
break;
727 case 4: this->b4.syncRasters();
break;
728 case 5: this->b5.syncRasters();
break;
729 case 6: this->b6.syncRasters();
break;
736 void calculateTriangulation(GeometrySurfacingParameters& parameters,
uint04 weight_cutoff)
noexcept
740 case 2: b2.calculateTriangulation(parameters, weight_cutoff);
break;
741 case 3: b3.calculateTriangulation(parameters, weight_cutoff);
break;
742 case 4: b4.calculateTriangulation(parameters, weight_cutoff);
break;
743 case 5: b5.calculateTriangulation(parameters, weight_cutoff);
break;
744 case 6: b6.calculateTriangulation(parameters, weight_cutoff);
break;
748 position = (position - m_point_offset4) * m_grid_span4;
754 cache.weight_max_capacity = max_alpha_cutoff;
757 case 2: b2.getCache(cache);
break;
758 case 3: b3.getCache(cache);
break;
759 case 4: b4.getCache(cache);
break;
760 case 5: b5.getCache(cache);
break;
761 case 6: b6.getCache(cache);
break;
765 void updateCloudGeometries(
uint04 weight_cuttoff,
uint04 max_alpha_cutoff,
const void* lock_ptr)
noexcept
770 cache.weight_max_capacity = max_alpha_cutoff;
773 case 2: b2.updateGeometries(cache);
break;
774 case 3: b3.updateGeometries(cache);
break;
775 case 4: b4.updateGeometries(cache);
break;
776 case 5: b5.updateGeometries(cache);
break;
777 case 6: b6.updateGeometries(cache);
break;
780 void updateSurfaceGeometries(
uint04 weight_cutoff,
bool merge_vertices,
const void* lock_ptr)
noexcept
782 GeometrySurfacingParameters parameters;
783 parameters.include_colors =
true;
786 case 2: b2.calculateTriangulation(parameters, weight_cutoff);
break;
787 case 3: b3.calculateTriangulation(parameters, weight_cutoff);
break;
788 case 4: b4.calculateTriangulation(parameters, weight_cutoff);
break;
789 case 5: b5.calculateTriangulation(parameters, weight_cutoff);
break;
790 case 6: b6.calculateTriangulation(parameters, weight_cutoff);
break;
792 WLock lock(lock_ptr);
810 for (
uint04 i = 0; i < parameters.surface_triangles.size(); i++)
851 void finishUpdatingModel(
const void* lock_ptr)
855 WLock lock(lock_ptr);
856 geo.set(NDPG::e_no_auto_tree_creation,
false);
857 geo.updateModifiedTime();
858 geo.invalidateBounds();
870 fltp04 max = bounds.span().dimensionalValue<MAX>();
873 if (grid_node_count < 8 * 8)
876 bm_center = (SegmentedBlockModelBase<t_point_type, 2, s_node_size, uint02>::Size() / 2U).
template as<3, fltp04>();
879 else if (grid_node_count < 8 * 8 * 8)
882 bm_center = (SegmentedBlockModelBase<t_point_type, 3, s_node_size, uint02>::Size() / 2U).
template as<3, fltp04>();
885 else if (grid_node_count < 8 * 8 * 8 * 8)
888 bm_center = (SegmentedBlockModelBase<t_point_type, 4, s_node_size, uint02>::Size() / 2U).
template as<3, fltp04>();
891 else if (grid_node_count < 8 * 8 * 8 * 8 * 8)
894 bm_center = (SegmentedBlockModelBase<t_point_type, 5, s_node_size, uint02>::Size() / 2U).
template as<3, fltp04>();
897 else if (grid_node_count < 8 * 8 * 8 * 8 * 8 * 8)
900 bm_center = (SegmentedBlockModelBase<t_point_type, 6, s_node_size, uint02>::Size() / 2U).
template as<3, fltp04>();
903 m_point_offset4 = (bm_center - (bounds.center() * m_inverse_grid_span4));
904 m_point_offset8 = m_point_offset4.as<3,
fltp08>();
906 m_inverse_grid_span8 =
cast<fltp08>(m_inverse_grid_span4);
916 geo.
set<
NDPO::transform>(Matrix<fltp08>::ScalerMatrix(m_grid_span8).offset(-m_point_offset8));
929 static constexpr uint04 s_node_size = 8;
941 fltp04 m_inverse_grid_span4;
943 fltp08 m_inverse_grid_span8;
948 class ColorNode :
public Vector<3, uint01>
953 ColorNode(RGBColor color)
954 : Vector<3,
uint01>(color[X], color[Y], color[Z])
956 ColorNode(Vector<3, uint01> color)
957 : Vector<3,
uint01>(color[X], color[Y], color[Z])
959 RGBColor color()
const
961 return RGBColor((*
this)[X], (*
this)[Y], (*
this)[Z]);
963 Vector<3, fltp04> normal()
const
965 return Constant<Vector<3, fltp04>>
::Invalid;
967 Vector<3, fltp04> offset()
const
969 return Constant< Vector<3, fltp04>>
::Invalid;
971 void setNormal(Vector<3, fltp04> normal)
975 void setColor(
const RGBColor& color)
977 (*this)[X] = color[X];
978 (*this)[Y] = color[Y];
979 (*this)[Z] = color[Z];
981 void setOffset(Vector<3, fltp04> offset)
985 static constexpr bool HasColor() {
return true; }
986 static constexpr bool HasNormal() {
return false; }
987 static constexpr bool HasOffset() {
return false; }
989 template<
class t_weight_type>
990 ColorNode combine(
const ColorNode& a,
const t_weight_type& a_weight,
const ColorNode& b,
const t_weight_type& b_weight)
993 a.
as<3, t_weight_type>() * a_weight
994 + b.as<3, t_weight_type>() * b_weight;
995 return ColorNode((new_type / (a_weight + b_weight)).
template as<3, uint01>());
1000 static const uint01 Dimensions = 0;
1001 static const bool Vector =
true;
1002 static const bool Buffer =
true;
1003 static const bool Primitive =
true;
1004 static const bool Pointer =
false;
1005 static const bool Unsigned =
false;
1006 static const bool Float =
false;
1007 static const bool Integer =
false;
1008 static const bool Number =
false;
1009 static const bool Enum =
false;
1010 static const bool String =
true;
1011 static const bool Color =
false;
1012 static const bool Boolean =
false;
1013 static constexpr ObjectInfo<uint01, false, false> VectorSub() {
return ObjectInfo<uint01, false, false>(); }
1015 class ColorNormalNode :
public Vector<6, uint01>
1020 ColorNormalNode(Vector<3, fltp04> normal, RGBColor color)
1021 : Vector<6,
uint01>(color[X], color[Y], color[Z],
cast<
uint01>(127.0f + normal[X] * 127.0f),
cast<
uint01>(127.0f + normal[Y] * 127.0f),
cast<
uint01>(127.0f + normal[Z] * 127.0f))
1023 ColorNormalNode(Vector<6, uint01> value)
1024 : Vector<6,
uint01>(value)
1026 RGBColor color()
const
1028 return RGBColor((*
this)[X], (*
this)[Y], (*
this)[Z]);
1030 Vector<3, fltp04> normal()
const
1034 Vector<3, fltp04> offset()
const {
return Constant< Vector<3, fltp04>>
::Invalid; }
1035 void setNormal(Vector<3, fltp04> normal)
1037 (*this)[3] =
cast<uint01>(127.0f + normal[X] * 127.0f);
1038 (*this)[4] =
cast<uint01>(127.0f + normal[Y] * 127.0f);
1039 (*this)[5] =
cast<uint01>(127.0f + normal[Z] * 127.0f);
1041 void setColor(
const RGBColor& color)
1043 (*this)[X] = color[X];
1044 (*this)[Y] = color[Y];
1045 (*this)[Z] = color[Z];
1047 void setOffset(Vector<3, fltp04> offset)
1051 template<
class t_other_type>
1052 t_other_type getAs()
const
1055 memcpy(&node,
this,
sizeof(t_other_type));
1059 static constexpr bool HasColor() {
return true; }
1060 static constexpr bool HasNormal() {
return true; }
1061 static constexpr bool HasOffset() {
return false; }
1063 template<
class t_weight_type>
1064 ColorNormalNode combine(
const ColorNormalNode& a,
const t_weight_type& a_weight,
const ColorNormalNode& b,
const t_weight_type& b_weight)
1067 a.as<6, t_weight_type>() * a_weight
1068 + b.as<6, t_weight_type>() * b_weight;
1069 return ColorNormalNode((new_type / (a_weight + b_weight)).
template as<6, uint01>());
1072 struct ObjectInfo<ColorNormalNode, false, true>
1074 static const uint01 Dimensions = 6;
1075 static const bool Vector =
true;
1076 static const bool Buffer =
true;
1077 static const bool Primitive =
true;
1078 static const bool Pointer =
false;
1079 static const bool Unsigned =
false;
1080 static const bool Float =
false;
1081 static const bool Integer =
false;
1082 static const bool Number =
false;
1083 static const bool Enum =
false;
1084 static const bool String =
true;
1085 static const bool Color =
false;
1086 static const bool Boolean =
false;
1087 static constexpr ObjectInfo<uint01, false, false> VectorSub() {
return ObjectInfo<uint01, false, false>(); }
1090 class ColorNormalOffsetNode :
public Vector<9, uint01>
1093 ColorNormalOffsetNode()
1095 ColorNormalOffsetNode(Vector<3, fltp04> offset, ColorNormalNode node)
1097 for (
uint01 i = 0; i < 6; i++)
1098 (*
this)[i] = node[i];
1101 ColorNormalOffsetNode(Vector<3, fltp04> offset, Vector<3, fltp04> normal, RGBColor color)
1103 (*this)[0] = color[X];
1104 (*this)[1] = color[Y];
1105 (*this)[2] = color[Z];
1109 ColorNormalOffsetNode(Vector<9, uint01> value)
1110 : Vector<9,
uint01>(value)
1112 ColorNormalOffsetNode(Vector<9, fltp04> value)
1114 for(
uint01 i = 0; i < 3; i++)
1115 value[i] =
clip(value[i], 0.0f, 255.0f);
1116 for (
uint01 i = 3; i < 6; i++)
1117 value[i] =
clip(value[i], 0.0f, 254.0f);
1118 for (
uint01 i = 6; i < 9; i++)
1119 value[i] =
clip(value[i], 0.0f, 255.0f);
1120 (*this) = value.as<
uint01>();
1122 ColorNormalOffsetNode(Vector<9, uint04> value)
1124 for (
uint01 i = 0; i < 3; i++)
1125 value[i] =
clip(value[i], 0U, 255U);
1126 for (
uint01 i = 3; i < 6; i++)
1127 value[i] =
clip(value[i], 0U, 254U);
1128 for (
uint01 i = 6; i < 9; i++)
1129 value[i] =
clip(value[i], 0U, 255U);
1130 (*this) = value.as<
uint01>();
1132 template<
class t_other_type>
1133 t_other_type getAs()
const
1135 return t_other_type();
1138 ColorNormalNode getAs()
const
1142 RGBColor color()
const
1144 return RGBColor((*
this)[X], (*
this)[Y], (*
this)[Z]);
1146 Vector<3, fltp04> normal()
const
1150 Vector<3, fltp04> offset()
const
1154 void setNormal(Vector<3, fltp04> normal)
1156 (*this)[3] =
cast<uint01>(127.0f + normal[X] * 127.0f);
1157 (*this)[4] =
cast<uint01>(127.0f + normal[Y] * 127.0f);
1158 (*this)[5] =
cast<uint01>(127.0f + normal[Z] * 127.0f);
1160 void setOffset(Vector<3, fltp04> offset)
1166 void setColor(RGBColor color)
1168 (*this)[X] = color[X];
1169 (*this)[Y] = color[Y];
1170 (*this)[Z] = color[Z];
1172 static constexpr bool HasColor() {
return true; }
1173 static constexpr bool HasNormal() {
return true; }
1174 static constexpr bool HasOffset() {
return true; }
1176 template<
class t_weight_type>
1177 ColorNormalOffsetNode combine(
const ColorNormalOffsetNode& a,
const t_weight_type& a_weight,
const ColorNormalOffsetNode& b,
const t_weight_type& b_weight)
1180 a.as<t_weight_type>() * a_weight
1181 + b.as<t_weight_type>() * b_weight;
1182 return ColorNormalOffsetNode((new_type / (a_weight + b_weight)));
1185 struct ObjectInfo<ColorNormalOffsetNode, false, true>
1187 static const uint01 Dimensions = 9;
1188 static const bool Vector =
true;
1189 static const bool Buffer =
true;
1190 static const bool Primitive =
true;
1191 static const bool Pointer =
false;
1192 static const bool Unsigned =
false;
1193 static const bool Float =
false;
1194 static const bool Integer =
false;
1195 static const bool Number =
false;
1196 static const bool Enum =
false;
1197 static const bool String =
true;
1198 static const bool Color =
false;
1199 static const bool Boolean =
false;
1200 static constexpr ObjectInfo<uint01, false, false> VectorSub() {
return ObjectInfo<uint01, false, false>(); }
1203 class ColorOffsetNode :
public Vector<6, uint01>
1208 ColorOffsetNode(Vector<3, fltp04> offset, ColorNormalNode node)
1210 for (
uint01 i = 0; i < 6; i++)
1211 (*
this)[i] = node[i];
1214 ColorOffsetNode(Vector<3, fltp04> offset, RGBColor color)
1216 (*this)[0] = color[X];
1217 (*this)[1] = color[Y];
1218 (*this)[2] = color[Z];
1221 ColorOffsetNode(Vector<6, uint01> value)
1222 : Vector<6,
uint01>(value)
1224 ColorOffsetNode(Vector<6, fltp04> value)
1226 for (
uint01 i = 0; i < 3; i++)
1227 value[i] =
clip(value[i], 0.0f, 255.0f);
1228 for (
uint01 i = 3; i < 6; i++)
1229 value[i] =
clip(value[i], 0.0f, 255.0f);
1230 (*this) = value.as<
uint01>();
1232 ColorOffsetNode(Vector<6, uint04> value)
1234 for (
uint01 i = 0; i < 3; i++)
1235 value[i] =
clip(value[i], 0U, 255U);
1236 for (
uint01 i = 3; i < 6; i++)
1237 value[i] =
clip(value[i], 0U, 255U);
1238 (*this) = value.as<
uint01>();
1240 RGBColor color()
const
1242 return RGBColor((*
this)[X], (*
this)[Y], (*
this)[Z]);
1244 Vector<3, fltp04> normal()
const
1246 return Constant<Vector<3, fltp04>>
::Invalid;
1248 Vector<3, fltp04> offset()
const
1252 void setNormal(Vector<3, fltp04> normal)
1256 void setOffset(Vector<3, fltp04> offset)
1262 static constexpr bool HasColor() {
return true; }
1263 static constexpr bool HasNormal() {
return false; }
1264 static constexpr bool HasOffset() {
return true; }
1266 template<
class t_weight_type>
1267 ColorOffsetNode combine(
const ColorOffsetNode& a,
const t_weight_type& a_weight,
const ColorOffsetNode& b,
const t_weight_type& b_weight)
1270 a.as<t_weight_type>() * a_weight
1271 + b.as<t_weight_type>() * b_weight;
1272 return ColorOffsetNode((new_type / (a_weight + b_weight)));
1275 struct ObjectInfo<ColorOffsetNode, false, true>
1277 static const uint01 Dimensions = 6;
1278 static const bool Vector =
true;
1279 static const bool Buffer =
true;
1280 static const bool Primitive =
true;
1281 static const bool Pointer =
false;
1282 static const bool Unsigned =
false;
1283 static const bool Float =
false;
1284 static const bool Integer =
false;
1285 static const bool Number =
false;
1286 static const bool Enum =
false;
1287 static const bool String =
true;
1288 static const bool Color =
false;
1289 static const bool Boolean =
false;
1290 static constexpr ObjectInfo<uint01, false, false> VectorSub() {
return ObjectInfo<uint01, false, false>(); }
Abstract cache interface for filtering block model raster data based on spatial criteria.
A single raster tile of a block model, storing point data, weights, and surfacing support.
A specification of upper and lower bounds in N-dimensions.
constexpr bool validate() const
Validates this object.
constexpr Ray< t_dims, t_type > span() const
The side lengths of these bounds.
The equivelent of std::vector but with a bit more control.
void set(t_property_type property, const t_type &value)
Sets a property value in the database.
bool isValid() const
Checks whether this design object has a valid index into the database.
bool is(t_property_type property, const StringView &value) const
Checks whether a string property matches the given StringView value.
A core class within the model hierarchy containing vertex-based data (Usually 3D data) within a set c...
void updateVertexColumns(bool invalidate_bounds=true, bool erase_kd_tree=true)
Notifies the system that all vertex columns have been modified.
@ e_cartesian_3F
3D Cartesian coordinates, single-precision float.
@ e_color_rgb
RGB color data.
@ e_no_vertex
No vertex data present.
void updateModifiedTime(Time time=Time::SystemTime())
Updates the modified timestamp for this geometry.
void updatePrimitiveColumns(bool remove_tree=true)
Notifies the system that all primitive columns have been modified.
void setupVertexTable(uint04 vertex_size, VertexMode position, VertexMode normal=VertexMode::e_no_vertex, VertexMode color=VertexMode::e_no_vertex, VertexMode texture=VertexMode::e_no_vertex, VertexMode tangent=VertexMode::e_no_vertex, VertexMode bitangent=VertexMode::e_no_vertex, VertexMode bones=VertexMode::e_no_vertex)
Configures the vertex table with the specified modes for standard properties.
void autoCalculateIndices(PrimitiveProperty property, const void *lock=nullptr, const Matrix< fltp08 > &transform=Matrix< fltp08 >(1.0), LogPtr log=LogPtr())
Automatically calculates primitive indices (e.g.
void setPrimitive(PrimitiveProperty property, uint04 index, t_type index_value)
Sets a single primitive index value.
void clearVerticesAndPrimitives()
Removes all vertex and primitive data from this geometry.
void setVertices(VertexProperty property, const Buffer< t_type > &vertices, uint04 offset=0)
Sets a standard vertex property for multiple vertices from a buffer.
uint04 createVertexProperty(const StringView &property_name)
Creates a new custom vertex property column with a compile-time type.
void removeDuplicateVertices(fltp08 epsilon, const void *lock, LogPtr log=LogPtr())
Removes vertices that are within epsilon distance of each other.
void setGeometryType(GeometryType geometry_type)
Sets the geometry type identifier.
void setPrimitiveRange(PrimitiveProperty mode, uint04 start, uint04 primitive_count)
Sets the start offset and count for a primitive property range.
void setVertexCount(uint04 size, bool deallocate_if_possible=true)
Sets the total vertex count, resizing vertex data columns.
Container responsible for storing and setting the appearance of a Model or Geometry within the NDEVR ...
@ e_flat
Flat shading. Shading is done on per-face base, diffuse only. Also known as 'faceted shading'.
void updateModifiedTime(const Time &time=Time::SystemTime())
Updates the material's modification timestamp.
@ e_color_channel
Color is taken from the per-vertex color channel.
void setUVMode(UVType uv_index, const UVMode &type)
Sets the UV mapping mode for the specified UV channel.
Templated logic for doing matrix multiplication.
void updateModifiedTime(Time time=Time::SystemTime())
Updates the modified timestamp for this model.
Vector< 3, fltp08 > size() const
Returns the size (extents) of the model's bounding box.
Geometry getGeometry() const
Returns the geometry attached to this model.
void invalidateBounds()
Invalidates all cached bounding boxes, forcing recalculation on next access.
Geometry createChildGeometry()
Creates a new child geometry for this model.
void setMaterial(const Material &material)
Assigns a material to this model.
Model()
Default constructor. Creates an uninitialized Model.
Material getMaterial() const
Returns the material assigned to this model.
Model getChild(uint04 child) const
Returns the child model at the given child slot index.
Material createChildMaterial(bool copy_child=false)
Creates a new child material for this model.
Used with InfoPipe to signal that the system will be using progress.
Hierarchical spatial index for block model rasters using a multi-level lookup tree.
The core String View class for the NDEVR API.
Represents a timestamp with utilities for manipulation and conversion.
static Time SystemTime()
Retrieves the current system time which is a combination of std::chrono::steady_clock to ensure smoot...
A fixed-size array with N dimensions used as the basis for geometric and mathematical types.
constexpr decltype(auto) as() const
Returns the vector as a new time of vector.
A point in N-dimensional space, used primarily for spatial location information.
Used to lock a particular variable for writing.
The primary namespace for the NDEVR SDK.
@ smooth_normals
Whether vertex normals are smoothed across faces.
@ pixel_thickness
Thickness in pixels for line and point rendering.
@ shading_model
The shading model index used for rendering (see Material::ShadingModel).
@ two_sided
Whether the material is rendered on both sides of a face.
@ fixed_bounding_box
A user-defined fixed bounding box override for this model.
@ Position
XYZ position of the vertex.
@ Normal
Surface normal vector at the vertex.
@ Color
Per-vertex RGBA color.
float fltp04
Defines an alias representing a 4 byte floating-point number Bit layout is as follows: -Sign: 1 bit a...
static constexpr bool IsValid(const Angle< t_type > &value)
Checks whether the given Angle holds a valid value.
constexpr HSLColor Constant< HSLColor >::Invalid
The invalid HSLColor constant with all components set to invalid.
uint64_t uint08
-Defines an alias representing an 8 byte, unsigned integer
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
@ e_points
Point cloud or discrete points.
@ e_triangles
Triangle meshes.
double fltp08
Defines an alias representing an 8 byte floating-point number.
@ name
The calculated/translated display name.
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
static constexpr bool IsInvalid(const Angle< t_type > &value)
Checks whether the given Angle holds an invalid value.
@ bounding_box
The axis-aligned bounding box of the object in local space.
@ transform
A 4x4 transform matrix that maps local coordinates into global space.
@ Outline
Line-based outline rendering of primitives.
@ Solid
Solid filled rendering of primitives.
constexpr uint04 cipow(uint04 num, uint04 pow)
Compile-time integer power function.
@ e_KD
Diffuse texture/color channel.
@ no_auto_tree_creation
Whether automatic spatial tree creation is disabled.
constexpr t_type clip(const t_type &value, const t_type &lower_bound, const t_type &upper_bound)
Clips the value given so that that the returned value falls between upper and lower bound.
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
A fixed-size 3D lookup table mapping spatial indices to flat array positions in a block model.
Cache for collecting block model vertex positions, colors, and weights during batch updates.
Extended cache that links block model data to actual Geometry columns for GPU upload.
Defines for a given type (such as sint04, fltp08, UUID, etc) a maximum, minimum, and reserved 'invali...
Information about the object.
Stores the state and results of an indexed geometry selection operation.
Records changes to a table or column noting the bounds of the data adjusted.
@ e_update
An existing row range was modified in place.