30 #include <boost/filesystem.hpp> 49 m_part_name(part_name),
50 m_mesh_path(meshes_group+
"/"+part_name)
52 std::cout <<
timestamp <<
" Try to open file \"" << filename <<
"\"..." << std::endl;
53 if(!
open(filename, open_flag))
55 std::cerr <<
timestamp <<
" Could not open file \"" << filename <<
"\"!" << std::endl;
67 open(filename, open_flag);
126 std::cout <<
timestamp <<
"HDF5IO: loading..." << std::endl;
130 std::cout <<
timestamp <<
" Mesh successfully loaded." << std::endl;
132 std::cout <<
timestamp <<
" Mesh could not be loaded." << std::endl;
138 std::cout <<
timestamp <<
" PointCloud successfully loaded." << std::endl;
140 std::cout <<
timestamp <<
" PointCloud could not be loaded." << std::endl;
149 if(scans.size() == 0)
154 size_t n_points_total = 0;
155 for(
const ScanPtr& scan : scans)
157 n_points_total += scan->points->numPoints();
160 floatArr points(
new float[n_points_total * 3]);
165 for(
int i=0; i<scans.size(); i++)
167 size_t num_points = scans[i]->points->numPoints();
168 floatArr pts = scans[i]->points->getPointArray();
179 *points_raw_it = T * cp;
186 model_ptr->m_pointCloud.reset(
new PointBuffer(points, n_points_total));
193 const std::string mesh_resource_path =
"meshes/" +
m_part_name;
194 const std::string vertices(
"vertices");
195 const std::string indices(
"indices");
197 if(!
exist(mesh_resource_path)){
202 if(!
mesh.exist(vertices) || !
mesh.exist(indices)){
203 std::cout <<
timestamp <<
" The mesh has to contain \"" << vertices
204 <<
"\" and \"" << indices <<
"\"" << std::endl;
205 std::cout <<
timestamp <<
" Return empty model pointer!" << std::endl;
209 std::vector<size_t> vertexDims;
210 std::vector<size_t> faceDims;
213 floatArr vbuffer = getArray<float>(mesh_resource_path, vertices, vertexDims);
214 indexArray ibuffer = getArray<unsigned int>(mesh_resource_path, indices, faceDims);
216 if(vertexDims[0] == 0)
220 if(!model_ptr->m_mesh)
225 model_ptr->m_mesh->setVertices(vbuffer, vertexDims[0]);
227 model_ptr->m_mesh->setFaceIndices(ibuffer, faceDims[0]);
235 bool have_to_init =
false;
237 boost::filesystem::path path(filename);
267 std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
268 std::time_t t_now= std::chrono::system_clock::to_time_t(now);
269 std::string time(ctime(&t_now));
293 std::cout <<
timestamp <<
" Mesh succesfully saved to " << filename << std::endl;
295 std::cout <<
timestamp <<
" Mesh could not saved to " << filename << std::endl;
301 if(!model_ptr->m_mesh)
303 std::cout <<
timestamp <<
" Model does not contain a mesh" << std::endl;
307 const std::string mesh_resource_path =
"meshes/" +
m_part_name;
308 const std::string vertices(
"vertices");
309 const std::string indices(
"indices");
312 if(
exist(mesh_resource_path)){
313 std::cout <<
timestamp <<
" Mesh already exists in file!" << std::endl;
319 if(
mesh.exist(vertices) ||
mesh.exist(indices)){
320 std::cout <<
timestamp <<
" The mesh has to contain \"" << vertices
321 <<
"\" and \"" << indices <<
"\"" << std::endl;
322 std::cout <<
timestamp <<
" Return empty model pointer!" << std::endl;
326 std::vector<size_t> vertexDims = {model_ptr->m_mesh->numVertices(), 3};
327 std::vector<size_t> faceDims = {model_ptr->m_mesh->numFaces(), 3};
329 if(vertexDims[0] == 0)
331 std::cout <<
timestamp <<
" The mesh has 0 vertices" << std::endl;
336 std::cout <<
timestamp <<
" The mesh has 0 faces" << std::endl;
344 model_ptr->m_mesh->getVertices()
347 addArray<unsigned int>(
351 model_ptr->m_mesh->getFaceIndices()
367 if (
exist(groupName))
383 if (g.
exist(datasetName))
385 long long unsigned int width, height, planes;
389 if (!H5IMis_image(g.
getId(), datasetName.c_str()))
394 if (H5IMget_image_info(
395 g.
getId(), datasetName.c_str(), &width, &height,
396 &planes, interlace, &npals) >= 0)
398 if (width && height && planes && npals == 0)
400 ret =
Texture(0, width, height, planes, 1, 1.0);
402 if (H5IMread_image(g.
getId(), datasetName.c_str(), ret.
m_data) < 0)
416 std::string groupName =
"/raw/scans/";
417 std::vector<ScanPtr> ret;
419 if (!
exist(groupName))
427 for (
size_t i = 0; i < num_objects; i++)
432 if (std::sscanf(cur_scan_pos.c_str(),
"position_%5d", &pos_num))
435 ret.push_back(cur_pos);
468 std::vector<std::vector<ScanImage> > ret;
472 std::string groupNamePhotos =
"/raw/photos/";
474 if(!
exist(groupNamePhotos))
484 for (
size_t i = 0; i < num_scans; i++)
490 std::vector<ScanImage> cam_data;
493 for(
size_t j=0; j< num_photos; j++)
496 cam_data.push_back(cam);
499 ret.push_back(cam_data);
514 sprintf(buffer,
"position_%05d", nr);
516 string nr_str(buffer);
517 std::string groupName =
"/raw/scans/" + nr_str;
518 std::string spectralGroupName =
"/annotation/" + nr_str;
521 doubleArr fov = getArray<double>(groupName,
"fov", dummy);
522 doubleArr res = getArray<double>(groupName,
"resolution", dummy);
523 doubleArr pose_estimate = getArray<double>(groupName,
"initialPose", dummy);
524 doubleArr registration = getArray<double>(groupName,
"finalPose", dummy);
525 floatArr bb = getArray<float>(groupName,
"boundingBox", dummy);
531 groupName =
"/preview/" + nr_str;
532 spectralGroupName = groupName;
535 floatArr points = getArray<float>(groupName,
"points", dummy);
541 std::vector<size_t> dim;
542 ucharArr spectral = getArray<unsigned char>(spectralGroupName,
"spectral", dim);
546 ret->points->addUCharChannel(spectral,
"spectral_channels", dim[0], dim[1]);
547 ret->points->addIntAtomic(400,
"spectral_wavelength_min");
548 ret->points->addIntAtomic(400 + 4 * dim[1],
"spectral_wavelength_max");
561 ret->hResolution = res[0];
562 ret->vResolution = res[1];
567 ret->registration =
Transformd(registration.get());
572 ret->poseEstimation =
Transformd(pose_estimate.get());
581 ret->pointsLoaded = load_points;
582 ret->positionNumber = nr;
584 ret->scanRoot = groupName;
598 sprintf(buffer1,
"position_%05d", scan_id);
599 string scan_id_str(buffer1);
601 sprintf(buffer2,
"photo_%05d", img_id);
602 string img_id_str(buffer2);
605 std::string groupName =
"/raw/photos/" + scan_id_str +
"/" + img_id_str;
615 std::cout <<
timestamp <<
"Error getting cam data: " 616 << e.
what() << std::endl;
621 doubleArr intrinsics_arr = getArray<double>(groupName,
"intrinsics", dummy);
622 doubleArr extrinsics_arr = getArray<double>(groupName,
"extrinsics", dummy);
651 sprintf(buffer,
"pose%05d", nr);
652 string nr_str(buffer);
654 std::string groupName =
"/raw_data/" + nr_str;
658 std::vector<size_t> dim;
659 ret = getArray<float>(g, name, dim);
663 throw std::runtime_error(
664 "HDF5IO - getFloatchannelFromRawScan() Error: dim.size() != 2");
687 const char* interlace =
"INTERLACE_PIXEL";
689 if(img.type() == CV_8U)
692 H5IMmake_image_8bit(g.
getId(), datasetName.c_str(), w, h, img.data);
693 }
else if(img.type() == CV_8UC3) {
695 H5IMmake_image_24bit(g.
getId(), datasetName.c_str(), w, h, interlace, img.data);
702 long long unsigned int w,h,planes;
706 H5IMget_image_info(g.
getId(), datasetName.c_str(), &w, &h, &planes, interlace, &npals);
711 img = cv::Mat(h, w, CV_8U);
712 }
else if(planes == 3) {
714 img = cv::Mat(h, w, CV_8UC3);
717 H5IMread_image(g.
getId(), datasetName.c_str(), img.data);
721 std::string name,
int nr,
size_t n,
unsigned w,
floatArr data)
729 std::cout <<
timestamp <<
"Error adding raw scan data: " 730 << e.
what() << std::endl;
734 if(data !=
nullptr && n > 0 && w > 0 &&
m_hdf5_file)
738 sprintf(buffer,
"position_%05d", nr);
739 string nr_str(buffer);
740 std::string groupName =
"/raw/scans/" + nr_str;
741 std::vector<size_t> dim = {n, w};
742 addArray(groupName, name, dim, data);
746 std::cout <<
timestamp <<
"Error adding float channel '" << name
747 <<
"'to raw scan data" << std::endl;
807 std::cout <<
timestamp <<
"Error adding raw scan data: " 808 << e.
what() << std::endl;
815 if(scan->points->numPoints())
819 sprintf(buffer,
"position_%05d", nr);
820 string nr_str(buffer);
823 std::string groupName =
"/raw/scans/" + nr_str;
831 res[0] = scan->hResolution;
832 res[1] = scan->vResolution;
835 float* pose_data =
new float[16];
836 float* reg_data =
new float[16];
838 std::copy(scan->poseEstimation.data(), scan->poseEstimation.data() + 16, pose_data);
839 std::copy(scan->registration.data(), scan->registration.data() + 16, reg_data);
847 auto bb_min = scan->boundingBox.getMin();
848 auto bb_max = scan->boundingBox.getMax();
869 std::vector<size_t> dim = {4,4};
870 std::vector<size_t> scan_dim = {scan->points->numPoints(), 3};
872 addArray(groupName,
"resolution", 2, res);
873 addArray(groupName,
"initialPose", dim, pose_estimate);
874 addArray(groupName,
"finalPose", dim, registration);
875 addArray(groupName,
"boundingBox", 6, bb);
876 addArray(groupName,
"points", scan_dim, scan->points->getPointArray());
885 ucharArr spectral = scan->points->getUCharArray(
"spectral_channels", an, aw);
889 size_t chunk_w = std::min<size_t>(an, 1000000);
890 std::vector<hsize_t> chunk_annotation = {chunk_w, aw};
891 std::vector<size_t> dim_annotation = {an, aw};
892 addArray(
"/annotation/" + nr_str,
"spectral", dim_annotation, chunk_annotation, spectral);
898 std::string previewGroupName =
"/preview/" + nr_str;
902 floatArr points = scan->points->getPointArray();
908 std::vector<size_t> previewDim = {numPreview, 3};
909 addArray(previewGroupName,
"points", previewDim, previewData);
919 std::vector<size_t> previewDim = {numPreview, aw};
920 addArray(previewGroupName,
"spectral", previewDim, previewData);
933 sprintf(buffer1,
"position_%05d", scan_id);
934 string scan_id_str(buffer1);
937 sprintf(buffer2,
"photo_%05d", img_id);
938 string photo_id_str(buffer2);
940 std::string groupName =
"/raw/photos/" + scan_id_str +
"/" + photo_id_str;
950 std::cout <<
timestamp <<
"Error adding raw image data: " 951 << e.
what() << std::endl;
960 doubleArr extrinsics_arr(
new double[16]);
963 std::vector<size_t> dim_4 = {4,4};
964 std::vector<size_t> dim_3 = {3,3};
966 std::vector<hsize_t> chunks;
972 addArray(photo_group,
"intrinsics", dim_4, chunks, intrinsics_arr);
973 addArray(photo_group,
"extrinsics", dim_3, chunks, extrinsics_arr);
986 std::vector<std::string> ret;
988 std::string remainder = groupName;
989 size_t delimiter_pos = 0;
991 while ( (delimiter_pos = remainder.find(
'/', delimiter_pos)) != std::string::npos)
993 if (delimiter_pos > 0)
995 ret.push_back(remainder.substr(0, delimiter_pos));
998 remainder = remainder.substr(delimiter_pos + 1);
1003 if (remainder.size() > 0)
1005 ret.push_back(remainder);
1021 for (
size_t i = 0; i < groupNames.size(); i++)
1023 if (cur_grp.
exist(groupNames[i]))
1025 cur_grp = cur_grp.
getGroup(groupNames[i]);
1035 throw std::runtime_error(
"HDF5IO - getGroup(): Groupname '" 1036 + groupNames[i] +
"' doesn't exist and create flag is false");
1043 <<
"Error in getGroup (with group name '" 1044 << groupName <<
"': " << std::endl;
1045 std::cout << e.
what() << std::endl;
1060 for (
size_t i = 0; i < groupNames.size(); i++)
1063 if (g.
exist(groupNames[i]))
1065 cur_grp = g.
getGroup(groupNames[i]);
1075 throw std::runtime_error(
"HDF5IO - getGroup(): Groupname '" 1076 + groupNames[i] +
"' doesn't exist and create flag is false");
1083 <<
"Error in getGroup (with group name '" 1084 << groupName <<
"': " << std::endl;
1085 std::cout << e.
what() << std::endl;
1101 for (
size_t i = 0; i < groupNames.size(); i++)
1103 if (cur_grp.
exist(groupNames[i]))
1105 if (i < groupNames.size() -1)
1107 cur_grp = cur_grp.
getGroup(groupNames[i]);
1119 <<
"Error in exist (with group name '" 1120 << groupName <<
"': " << std::endl;
1121 std::cout << e.
what() << std::endl;
1133 if (H5Gget_objinfo(grp.
getId(), objName.c_str(),
true, &stats) < 0)
1138 if (stats.type == H5G_GROUP)
1148 std::cout <<
timestamp <<
" No mesh with the part name \"" 1149 <<
m_part_name <<
"\" given in the HDF5 file \"" << std::endl;
1158 if(!mesh_opt)
return boost::none;
1159 auto mesh = mesh_opt.get();
1162 std::cout <<
timestamp <<
" Could not find mesh vertices in the given HDF5 file." << std::endl;
1166 std::vector<size_t >dims;
1174 if(!mesh_opt)
return boost::none;
1175 auto mesh = mesh_opt.get();
1178 std::cout <<
timestamp <<
" Could not find mesh face indices in the given HDF5 file." << std::endl;
1182 std::vector<size_t >dims;
1203 return getChannel<float>(group, name, channel);
1207 return getChannel<unsigned int>(group, name, channel);
1211 return getChannel<unsigned char>(group, name, channel);
1215 return addChannel<float>(group, name, channel);
1219 return addChannel<unsigned int>(group, name, channel);
1223 return addChannel<unsigned char>(group, name, channel);
A class to handle point information with an arbitrarily large number of attribute channels...
void setCompress(bool compress)
bool readPointCloud(ModelPtr model_ptr)
bool deleteDataset(const char *name)
deletes a dataset permanently from the hdf file
void addRawCamData(int scan_id, int img_id, ScanImage &cam_data)
add recorded image referenced to a scan pose
void addArray(std::string groupName, std::string datasetName, unsigned int size, boost::shared_array< T > data)
virtual void save(std::string filename)
Save the loaded elements to the given file.
bool readMesh(ModelPtr model_ptr)
A 4x4 matrix class implementation for use with the provided vertex types.
void setPreviewReductionFactor(const unsigned int factor)
virtual ModelPtr read(std::string filename)
Parse the given file and load supported elements.
static DataSpace From(const ScalarValue &scalar_value)
static const std::string indices_name
static Timestamp timestamp
A global time stamp object for program runtime measurement.
HighFive::File * m_hdf5_file
static const int ReadWrite
Open flag: Read Write access.
Texture getImage(std::string groupName, std::string datasetName)
void addRawDataHeader(std::string description, Matrix4< BaseVector< float >> &referenceFrame)
boost::shared_array< double > doubleArr
const DataPtr dataPtr() const
unsigned int m_previewReductionFactor
size_t getNumberObjects() const
return the number of leaf objects of the node / group
static const int Truncate
Open flag: Truncate a file if already existing.
boost::shared_array< unsigned char > ucharArr
virtual bool addVertices(const FloatChannel &channel_ptr)
Persistence layer interface, Writes the vertices of the mesh to the persistence layer.
std::shared_ptr< Scan > ScanPtr
Shared pointer to scans.
std::vector< ScanPtr > getRawScans(bool load_points=true)
void setUsePreviews(bool use)
UCharChannel::Optional UCharChannelOptional
std::string getObjectName(size_t index) const
return the name of the object with the given index
std::shared_ptr< PointBuffer > PointBufferPtr
A dynamic bounding box class.
void addImage(std::string groupName, std::string name, cv::Mat &img)
Transform< double > Transformd
4x4 double precision transformation matrix
bool isValid() const
isValid
static const int ReadOnly
Open flag: Read only access.
std::vector< std::vector< ScanImage > > getRawCamData(bool load_image_data=true)
bool isGroup(HighFive::Group grp, std::string objName)
virtual bool addIndices(const IndexChannel &channel_ptr)
Persistence layer interface, Writes the face indices of the mesh to the persistence layer...
Channel< float > FloatChannel
boost::shared_array< T > reduceData(boost::shared_array< T > data, size_t dataCount, size_t dataWidth, unsigned int reductionFactor, size_t *reducedDataCount)
bool exist(const std::string &node_name) const
check a dataset or group exists in the current node / group
boost::shared_array< unsigned int > indexArray
const char * what() const override
get the current exception error message
virtual FloatChannelOptional getVertices()
Persistence layer interface, Accesses the vertices of the mesh in the persistence layer...
This class represents a texture.
boost::shared_array< float > floatArr
bool saveMesh(ModelPtr model_ptr)
Group getGroup(const std::string &group_name) const
open an existing group with the name group_name
std::vector< std::string > splitGroupNames(const std::string &groupName)
floatArr getFloatChannelFromRawScan(std::string name, int nr, unsigned int &n, unsigned &w)
FloatChannel::Optional FloatChannelOptional
void addFloatChannelToRawScan(std::string name, int nr, size_t n, unsigned w, floatArr data)
static const std::string vertices_name
std::shared_ptr< Model > ModelPtr
unsigned char * m_data
The texture data.
IndexChannel::Optional IndexChannelOptional
Basic HighFive Exception class.
bool exist(const std::string &groupName)
static const std::string meshes_group
int m_previewReductionFactor
Channel< unsigned int > IndexChannel
virtual IndexChannelOptional getIndices()
Persistence layer interface, Accesses the face indices of the mesh in the persistence layer...
bool getChannel(const std::string group, const std::string name, boost::optional< AttributeChannel< T >> &channel)
void write_base_structure()
The MeshBuffer Mesh representation for I/O modules.
Group createGroup(const std::string &group_name)
create a new group with the name group_name
bool open(std::string filename, int open_flag)
HighFive::Group getGroup(const std::string &groupName, bool create=true)
bool addChannel(const std::string group, const std::string name, const AttributeChannel< T > &channel)
size_t numElements() const
HDF5IO()
Construct a new HDF5IO object. Do not use this. Only used by ModelFactory.
ScanPtr getSingleRawScan(int nr, bool load_points=true)
DataSet createDataSet(const std::string &dataset_name, const DataSpace &space, const DataType &type, const DataSetCreateProps &createProps=DataSetCreateProps(), const DataSetAccessProps &accessProps=DataSetAccessProps())
createDataSet Create a new dataset in the current file of datatype type and of size space ...
cv::Mat image
OpenCV representation.
void addRawScan(int nr, ScanPtr scan)
ScanImage getSingleRawCamData(int scan_id, int img_id, bool load_image_data=true)
boost::optional< HighFive::Group > getMeshGroup(bool create=false)
void setChunkSize(const size_t &size)