2#include "OrbSLAM/Headers/KeyFrame.h"
3#include "OrbSLAM/Headers/Converter.h"
4#include "PointScanner/Headers/PointContainer.h"
5#include "RasterPointScanner/Headers/ViewportPointSmoother.hpp"
6#include "RasterPointScanner/Headers/PointSmootherBlockFilter.hpp"
7#include "BlockModel/Headers/SegmentedBlockModel.h"
8#include "Design/Headers/GeometryRegistration.h"
9#include "Design/Headers/Geometry.h"
10#include "Design/Headers/Model.h"
11#include "Base/Headers/FileResource.h"
12#include "Base/Headers/Dictionary.h"
13#include <NDEVR/Matrix.h>
16 struct RasterFrameModel :
public Model
18 RasterFrameModel(
const KeyFrame* frame,
const Model& model)
26 template<
class t_po
int_type>
27 RasterFrameModel(
const PointContainer<t_point_type>& points,
const Matrix<fltp08>&
transform,
const KeyFrame* frame,
const Model& model)
41 static constexpr StringView TypeName() {
return "frame_raster"; }
42 template<
class t_block_model_type>
43 void blockFilter(
fltp04 resolution,
uint04 weight_filter)
45 PointContainer<t_block_model_type> points = getPoints();
46 SegmentedBlockModel<t_block_model_type> block_model(resolution,
getBounds().expand(1.1f));
47 block_model.addPoints(points.locations, points.colors, points.weights);
48 block_model.syncRasters();
49 BlockModelCache<t_block_model_type, uint04> cache = block_model.getCache(weight_filter);
50 Matrix<fltp04> location_transform = block_model.blockTransform().template as<fltp04>();
51 points.setSize(cache.geo_add_locations.size());
52 for (
uint04 i = 0; i < cache.geo_add_locations.size(); i++)
54 if constexpr (t_block_model_type::HasOffset())
55 points.locations[i] = location_transform * Vertex<3, fltp04>(cache.geo_add_locations[i].template as<3, fltp04>() + cache.geo_add_info[i].offset());
57 points.locations[i] = location_transform * Vertex<3, fltp04>(cache.geo_add_locations[i].template as<3, fltp04>());
58 points.weights[i] = cache.geo_add_weight[i];
59 points.data[i] = cache.geo_add_info[i].template getAs<t_block_model_type>();
63 template<
class t_po
int_type>
64 PointContainer<t_point_type> getPoints()
const
66 PointContainer<t_point_type> points;
71 points.setSize(pos_iter.size());
73 for (
uint04 i = 0; i < points.size(); ++i)
75 points.locations[i] =
transform * pos_iter[i];
78 if constexpr (t_point_type::HasColor())
79 points.data[i].setColor(color_iter[i]);
80 points.weights[i] = 1U;
84 template<
class t_po
int_type>
85 void setPoints(
const PointContainer<t_point_type>& points)
92 geo.setupVertexTable(points.size()
101 Bounds<3, fltp04> bounds = Constant<Bounds<3, fltp04>>
::Min;
102 for (
uint04 i = 0; i < points.size(); ++i)
104 bounds.addToBounds(points.locations[i]);
106 Vector<3, fltp08> max_scale(2.0 *
cast<fltp08>(Constant<sint02>::Max));
107 Vector<3, fltp04> pos_scale = max_scale.as<3,
fltp04>() / bounds.span();
109 Vector<3, fltp04> offset = bounds.center();
110 for (
uint04 i = 0; i < points.size(); ++i)
112 if (points.weights[i] >= 10)
114 pos_iter.setVertex(valid_idx, pos_scale * (points.locations[i] - offset));
117 if constexpr (t_point_type::HasColor())
118 color_iter.setVertex(valid_idx, points.data[i].color());
123 geo.setVertexCount(valid_idx);
124 geo.updateVertexColumns();
125 geo.updateModifiedTime();
126 geo.setBounds(Bounds<3, fltp08>(Vertex<3,fltp08>(Constant<sint02>::Min), Vertex<3, fltp08>(Constant<sint02>::Max)));
132 if (frame ==
nullptr)
134 TranslatedString
name;
137 name = _t(
"Frame [frame_id]").replace(
"[frame_id]", String(frame->keyframe_id));
141 name = _t(
"Frame [frame_id] (Bad)").replace(
"[frame_id]", String(frame->keyframe_id));
147 const KeyFrame* frame =
nullptr;
148 Matrix<fltp08> ndv_transform;
150 class FramePointScan :
public Model
153 FramePointScan(
const Model& model)
168 static constexpr StringView TypeName() {
return "frame_point_scan"; }
170 void setPointStride(
uint04 point_stride)
172 m_point_stride = point_stride;
174 template<
class t_po
int_type>
175 void add(
const KeyFrame* frame, PointContainer<t_point_type>& points)
177 if (points.locations.size() == 0 || m_last_keyframe ==
nullptr)
179 frame->setDoNotReduce(
true);
180 if (m_last_keyframe !=
nullptr)
182 if (m_last_keyframe->isBad())
185 uint04 original_id = m_last_keyframe->id;
186 m_last_keyframe = frame;
187 while (m_last_keyframe->mPrevKF && m_last_keyframe->mPrevKF->id > original_id)
188 m_last_keyframe = m_last_keyframe->mPrevKF;
191 Matrix<fltp04> inverse_mat = mat.invert().as<
fltp04>();
192 for (Vertex<3, fltp04>& p0 : points.locations)
193 p0 = inverse_mat * p0;
194 RasterFrameModel frame_model(points, mat, m_last_keyframe,
createChild());
195 m_rasters.add(frame_model);
198 m_last_keyframe = frame;
200 bool shouldAddFramePoints(
const KeyFrame* frame)
202 if (frame ==
nullptr)
204 if (m_last_keyframe ==
nullptr)
206 m_last_keyframe = frame;
209 if (frame == m_last_keyframe)
211 if (!m_last_keyframe->isSet())
213 if (frame->isFirstConnection())
215 if (frame->timestamp() - m_last_keyframe->timestamp() < 0.1)
217 Eigen::Vector3f r1 = frame->GetRotation() * Eigen::Vector3f(1.0, 0.0, 0.0);
218 Eigen::Vector3f r2 = m_last_keyframe->GetRotation() * Eigen::Vector3f(1.0, 0.0, 0.0);
219 Eigen::Vector3f d1 = frame->cameraCenter();
220 Eigen::Vector3f d2 = m_last_keyframe->cameraCenter();
221 if ((d1 - d2).norm() < 0.1f && (r1 - r2).norm() < 0.2f)
225 template<
class t_block_filter_type>
226 void blockFilter(
fltp04 resolution,
uint04 weight_filter)
228 for (
uint04 i = 0; i < m_rasters.size(); ++i)
230 m_rasters[i].template blockFilter<t_block_filter_type>(resolution, weight_filter);
235 for (
uint04 i = 0; i < m_rasters.size(); i++)
236 m_rasters[i].updateModel();
240 bool updated =
false;
243 bool needs_update_model =
false;
244 const KeyFrame* frame = m_rasters[i].frame;
246 if (!
equals(m_rasters[i].ndv_transform, new_ndv_mat, 0.000001))
247 needs_update_model =
true;
248 m_rasters[i].ndv_transform = new_ndv_mat;
249 if (!needs_update_model)
250 needs_update_model = frame->isBad() && m_rasters[i].isVisible();
251 if (needs_update_model)
252 m_rasters[i].updateModel();
253 updated |= needs_update_model;
257 template<
class t_po
int_type,
class t_block_model_type>
258 void addAllToBlockModel(ViewportPointSmoother<t_point_type>& smoother
259 , SegmentedBlockModel<t_block_model_type>& block_model
262 if (m_rasters.size() == 0)
264 ProgressInfo progress(_t(
"Optimizing Graph"), log, 0.0f);
266 smoother.setFrameReduction(0U);
267 smoother.setBoundsFilter(
false);
268 smoother.setLockWeights(
true);
269 for (
uint04 i = 0; i < m_rasters.size(); i++)
271 auto& iter = m_rasters[i];
272 if (iter.frame->isBad())
274 Matrix<fltp04> ref_mat = m_rasters[i].ndv_transform.template as<fltp04>();
276 auto points = iter.getPoints<t_point_type>();
277 for (
auto& point : points.locations)
278 point = ref_mat * point;
281 block_model.addPoints(points.locations, points.data, points.weights);
285 progress.setProgress(i, m_rasters.size());
287 progress.setProgress(1.0f);
288 const auto& active = smoother.active();
289 block_model.addPoints(active.locations, active.data, active.weights);
290 const auto& inactive = smoother.inactive();
291 block_model.addPoints(inactive.locations, inactive.data, inactive.weights);
292 smoother.postClearAll();
293 smoother.setBoundsFilter(
false);
295 template<
class t_block_model_type>
296 void registerPoints(SegmentedBlockModel<t_block_model_type>& block_model
297 , GeometryRegistration& reg
299 ,
const void* lock_ptr)
302 WLock lock(lock_ptr);
303 block_model.update<
NDPO::transform>(block_model.getParentTransform().invert()
307 ProgressInfo progress(_t(
"Register"), log);
308 progress.setProgress(0.0f);
309 if (m_rasters.size() < 2)
312 WLock lock(lock_ptr);
315 GeometryRegistrationParameters params;
317 Matrix<fltp04> initial_transform = m_rasters[0].ndv_transform.template as<fltp04>();
318 PointContainer<t_block_model_type> points = m_rasters[0].getPoints<t_block_model_type>();
319 for (
uint04 i = 0; i < points.locations.size(); i++)
320 points.locations[i] = initial_transform * points.locations[i];
321 block_model.addPoints(points.locations, points.data, points.weights);
323 uint04 finished_count = 0;
324 params.update_data_callback = [&](
uint04 i,
uint04 iteration_b, Matrix<fltp08>& mat,
bool finished)
333 progress.setProgress(++finished_count, m_rasters.size() - 1);
336 auto& raster = m_rasters[i + 1];
337 Matrix<fltp04> adjustment = mat.template as<fltp04>();
340 PointContainer<t_block_model_type> points = raster.getPoints<t_block_model_type>();
341 for (
uint04 i = 0; i < points.locations.size(); i++)
342 points.locations[i] = adjustment * points.locations[i];
343 block_model.addPoints(points.locations, points.data, points.weights);
344 block_model.syncRasters();
345 block_model.updateCloudGeometries(10, 0, lock_ptr);
347 params.registration_points.setSize(m_rasters.size() - 1);
348 for (
uint04 i = 0; i < m_rasters.size(); i++)
350 auto& iter = m_rasters[i];
353 if (params.reference.positions.size() == 0)
355 PointContainer<t_block_model_type> points = m_rasters[0].getPoints<t_block_model_type>();
356 params.reference_transform = m_rasters[0].ndv_transform;
357 params.reference.positions = points.locations;
361 PointContainer<t_block_model_type> points = iter.getPoints<t_block_model_type>();
362 params.registration_points[i - 1].positions = points.locations;
363 params.original_transforms.add(m_rasters[i].ndv_transform);
366 reg.runRegistration(params);
367 progress.setProgress(1.0f);
369 WLock lock(lock_ptr);
373 void setMinResolution(
fltp04 min_resolution) { m_min_resolution = min_resolution; }
374 const KeyFrame* lastKeyFrame()
const {
return m_last_keyframe; };
376 Buffer<RasterFrameModel> m_rasters;
377 const KeyFrame* m_last_keyframe =
nullptr;
378 fltp04 m_min_resolution = 0.0f;
379 uint04 m_point_stride = 1U;
static Matrix< fltp04 > ToNDVMat(const Eigen::Matrix< float, 4, 4 > &m)
Converts a 4x4 float Eigen matrix to an NDEVR Matrix.
void set(t_property_type property, const t_type &value)
Sets a property value in the database.
bool is(t_property_type property, const StringView &value) const
Checks whether a string property matches the given StringView value.
bool update(t_property_type property, const t_type &value, const void *lock=nullptr)
Updates a property only if the new value differs from the current value.
@ e_cartesian_3S
3D Cartesian coordinates, short integer.
@ e_color_rgb
RGB color data.
@ e_no_vertex
No vertex data present.
@ e_flat
Flat shading. Shading is done on per-face base, diffuse only. Also known as 'faceted shading'.
@ e_color_channel
Color is taken from the per-vertex color channel.
A core class that represents a node on model hierarchy.
void updateModifiedTime(Time time=Time::SystemTime())
Updates the modified timestamp for this model.
Geometry getGeometry() const
Returns the geometry attached to this model.
Model createChild()
Creates a new child model and appends it to this model's child list.
Geometry createChildGeometry()
Creates a new child geometry for this model.
Matrix< fltp08 > getCompleteTransform() const
Returns the fully composed local-to-global transform matrix for this model.
Bounds< 3, fltp08 > getBounds() const
Returns the local bounding box of this model.
Material createChildMaterial(bool copy_child=false)
Creates a new child material for this model.
The primary namespace for the NDEVR SDK.
@ pixel_thickness
Thickness in pixels for line and point rendering.
@ shading_model
The shading model index used for rendering (see Material::ShadingModel).
@ Position
XYZ position of 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.
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.
double fltp08
Defines an alias representing an 8 byte floating-point number.
@ name
The calculated/translated display name.
static constexpr bool IsInvalid(const Angle< t_type > &value)
Checks whether the given Angle holds an invalid value.
@ name
The display name of the object.
@ transform
A 4x4 transform matrix that maps local coordinates into global space.
@ spacial_visible
Whether the object is visible in the 3D spatial view.
constexpr HSLColor Constant< HSLColor >::Min
The minimum HSLColor constant with saturation, brightness, and alpha at zero.
constexpr bool equals(const LineSegment< t_dims, t_type, t_vertex > &left, const LineSegment< t_dims, t_type, t_vertex > &right, const t_type &epsilon=cast< t_type >(0))
Tests if objects are considered equal.
@ e_KD
Diffuse texture/color channel.
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.