ReconstructMe SDK  2.6.43-0
Real-time 3D reconstruction engine
example_reconstructmesdk_bust.cpp

Content

This short example shows how to use ReconstructMe SDK to generate printable busts. It automatically detects when a full camera rotation around the subject is complete and starts post-processing. It post-processes the mesh in a way that the resulting mesh is watertight and directly printable. For this to work, the example makes a couple of assumptions:

The following 3D modell shows a typical bust result.

Note, for best results you should disable sensor exposure auto-correction. Don't do this immediately when the sensor starts, but rather after a couple of frames.

Boost is only used to generate examples and is not necessary for working with this SDK.

#include <boost/test/unit_test.hpp>
#include <math.h>
#include <string.h>
BOOST_AUTO_TEST_SUITE(example_reconstructmesdk)
BOOST_AUTO_TEST_CASE(bust_generation) {
// Create a new context
// Create a license object
reme_error_t e = reme_license_authenticate(c, l, "license.txt.sgn");
// Create options
// Enable colorization
reme_options_set_bool(c, o, "data_integration.use_colors", true);
// Compile for OpenCL device using defaults
// Create a new volume
// Create a new sensor.
reme_sensor_create(c, "openni;mskinect;file", true, &s);
// Use color in rendering volume image
reme_options_set(c, o, "shade_mode", "SHADE_COLORS");
// Create viewer and start reconstruction
reme_viewer_t viewer;
reme_viewer_create_image(c, "This is ReconstructMe SDK", &viewer);
reme_image_t volume, aux;
reme_image_create(c, &volume);
reme_viewer_add_image(c, viewer, aux);
reme_viewer_add_image(c, viewer, volume);
// Perform reconstruction until one complete rotation is performed
float prev_pos[16], cur_pos[16];
float rotation_axis[4] = {0, 0, 1, 0};
reme_sensor_get_position(c, s, prev_pos);
float angle;
float sum_turn_angles = 0.f;
while (fabs(sum_turn_angles) < 2.f * 3.1415f) {
continue;
}
reme_sensor_get_position(c, s, cur_pos);
reme_transform_get_projected_angle(c, rotation_axis, prev_pos, cur_pos, &angle);
sum_turn_angles += angle;
memcpy(prev_pos, cur_pos, 16 * sizeof(float));
}
reme_viewer_update(c, viewer);
}
// Close and destroy the sensor, it is not needed anymore
// Create surface from volume
// Remove small unconnected parts
// Fill holes and make mesh watertight
// Prepare to cut the bottom of the surface
reme_csg_create(c, v, &csg);
// Keep the color volume, but clear the geometric volume.
reme_volume_reset_selectively(c, v, true, false);
// Insert the watertight mesh
// Cut with plane at height -300, parallel to xy.
float cut_plane[4] = {0, 0, 1, -300};
// In case anything is sticking out of the volume (e.g on top), close it now.
// Generate the final mesh.
// Since we cut at height -300 according to the world coordinate system, our lowest point of the mesh
// will be -300. In order to optimize for printing, we'd like to make the lowest coordinate of the mesh to be zero,
// so that the mesh stands on the printer platform.
float transform[16];
transform[11] = 300; // Move mesh in z up by 300 units.
reme_surface_transform(c, m, transform);
// Save mesh
reme_surface_save_to_file(c, m, "test.obj");
// Visualize resulting surface
reme_viewer_t viewer_surface;
reme_viewer_create_surface(c, m, "This is ReconstructMeSDK", &viewer_surface);
reme_viewer_wait(c, viewer_surface);
// Print pending errors
// Make sure to release all memory acquired
}
BOOST_AUTO_TEST_SUITE_END()