/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2012 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLGeom/src/PCLPointCloudObject.cpp ** ** Module : ICLGeom ** ** Authors: Christof Elbrechter, Patrick Nobou ** ** ** ** ** ** Commercial License ** ** ICL can be used commercially, please refer to our website ** ** www.iclcv.org for more details. ** ** ** ** GNU General Public License Usage ** ** Alternatively, this file may be used under the terms of the ** ** GNU General Public License version 3.0 as published by the ** ** Free Software Foundation and appearing in the file LICENSE.GPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the GNU General Public License ** ** version 3.0 requirements will be met: ** ** http://www.gnu.org/copyleft/gpl.html. ** 1** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** *********************************************************************/ #include <ICLGeom/PCLPointCloudObject.h> #include <ICLUtils/StringUtils.h> using namespace icl::utils; using namespace icl::math; using namespace icl::core; namespace icl{ namespace geom{ template<class PCLPointType> int PCLPointCloudObject<PCLPointType>::offset(FeatureType) const{ return -1; } template<class PCLPointType> icl8u* PCLPointCloudObject<PCLPointType>::data() { return (icl8u*)&m_pcl->points[0]; } template<class PCLPointType> inline const icl8u* PCLPointCloudObject<PCLPointType>::data() const { return const_cast<PCLPointCloudObject<PCLPointType>*>(this)->data(); } /// creates a data segment for a given feature type template<class PCLPointType> template<class T, int N, PointCloudObjectBase::FeatureType t> inline DataSegment<T,N> PCLPointCloudObject<PCLPointType>::createSegment() { ICLASSERT_THROW(supports(t),utils::ICLException("the given feature type " + str(t) + " is not supported by this PCLPointCloudObject")); return DataSegment<T,N>((T*)(data()+offset(t)),sizeof(Entry), isOrganized() ? m_pcl->width * m_pcl->height : m_pcl->width, isOrganized() ? m_pcl->width : -1); } template<class PCLPointType> void PCLPointCloudObject<PCLPointType>::deletePCL(){ if(m_ownPCL && m_pcl) delete m_pcl; m_pcl = 0; } template<class PCLPointType> PCLPointCloudObject<PCLPointType>::PCLPointCloudObject(const std::string &filename):m_ownPCL(true){ m_pcl = new pcl::PointCloud<PCLPointType>; if(filename.length()){ if( pcl::io::loadPCDFile<PCLPointType>(filename, *m_pcl) == -1){ throw utils::ICLException("unable to load \"pcl\" point cloud file " + filename); } } } template<class PCLPointType> PCLPointCloudObject<PCLPointType>::PCLPointCloudObject(int width, int height, const PCLPointType &init): m_pcl(new pcl::PointCloud<PCLPointType>(width,height,init)),m_ownPCL(true){ } template<class PCLPointType> PCLPointCloudObject<PCLPointType>::PCLPointCloudObject(const PCLPointCloudObject<PCLPointType> &other) :m_pcl(0),m_ownPCL(true){ *this = other; } template<class PCLPointType> PCLPointCloudObject<PCLPointType> &PCLPointCloudObject<PCLPointType>::operator=(const PCLPointCloudObject<PCLPointType> &other){ deletePCL(); if(!other.isNull()){ setPCL(other.pcl()); } m_metaData = other.m_metaData; return *this; } template<class PCLPointType> PCLPointCloudObject<PCLPointType>::PCLPointCloudObject(const pcl::PointCloud<PCLPointType> &cloud){ setPCL(cloud); } template<class PCLPointType> PCLPointCloudObject<PCLPointType>::PCLPointCloudObject(pcl::PointCloud<PCLPointType> &cloud, bool deepCopy){ setPCL(cloud, deepCopy); } template<class PCLPointType> PCLPointCloudObject<PCLPointType>::~PCLPointCloudObject(){ deletePCL(); } template<class PCLPointType> pcl::PointCloud<PCLPointType> & PCLPointCloudObject<PCLPointType>::pcl() throw (utils::ICLException){ if(isNull()) throw ICLException("PCLPointCloudObject::pcl(): instance is null"); return *m_pcl; } template<class PCLPointType> const pcl::PointCloud<PCLPointType> & PCLPointCloudObject<PCLPointType>::pcl() const throw (utils::ICLException){ return const_cast<PCLPointCloudObject<PCLPointType>*>(this)->pcl(); } template<class PCLPointType> void PCLPointCloudObject<PCLPointType>::setPCL(const pcl::PointCloud<PCLPointType> &pcl){ deletePCL(); m_pcl = new pcl::PointCloud<PCLPointType>; pcl::copyPointCloud(pcl, *m_pcl); m_ownPCL = true; } template<class PCLPointType> void PCLPointCloudObject<PCLPointType>::setPCL(pcl::PointCloud<PCLPointType> &pcl, bool deepCopy){ ICL_DELETE(m_pcl); if(deepCopy){ setPCL(const_cast<const pcl::PointCloud<PCLPointType> &>(pcl)); }else{ m_pcl = &pcl; m_ownPCL = false; } } template<class PCLPointType> bool PCLPointCloudObject<PCLPointType>::supports(FeatureType t) const{ if(isNull()) throw utils::ICLException("PCLPointCloudObject:supports(t): instance is null"); return (offset(t) >= 0); } template<class PCLPointType> bool PCLPointCloudObject<PCLPointType>::isOrganized() const { if(isNull()) throw utils::ICLException("PCLPointCloudObject:isOrganized(): instance is null"); return m_pcl->isOrganized(); } template<class PCLPointType> Size PCLPointCloudObject<PCLPointType>::getSize() const throw (utils::ICLException){ if(isNull()) throw utils::ICLException("PCLPointCloudObject:getSize(): instance is null"); if(!isOrganized()) throw utils::ICLException("PCLPointCloud::getSize(): instance is not 2D-ordered"); return Size(m_pcl->width, m_pcl->height); } template<class PCLPointType> int PCLPointCloudObject<PCLPointType>::getDim() const{ if(isNull()) throw utils::ICLException("PCLPointCloudObject:getDim(): instance is null"); return isOrganized() ? m_pcl->width * m_pcl->height : m_pcl->width; } template<class PCLPointType> void PCLPointCloudObject<PCLPointType>::setSize(const Size &size){ if(getSize() == size) return; *this = PCLPointCloudObject<PCLPointType>(size.width,(size.height == 0) ? -1 : size.height); } template<class PCLPointType> PCLPointCloudObject<PCLPointType> *PCLPointCloudObject<PCLPointType>::copy() const { PCLPointCloudObject<PCLPointType> *p = new PCLPointCloudObject<PCLPointType>(*this); if(supports(Normal)){ // little hack because pcl does in general not support a 4th-normal component DataSegment<float,4> n = p->selectNormal(); for(int i=0;i<n.getDim();++i){ n[i][3] = 1; } } return p; } template<class PCLPointType> bool PCLPointCloudObject<PCLPointType>::isNull() const { return !m_pcl; } template<class PCLPointType> DataSegmentBase PCLPointCloudObject<PCLPointType>::select(const std::string &featureName) { if(isNull()) throw utils::ICLException("PCLPointCloudObject:select(" + featureName + "): instance is null"); if(featureName == "all"){ return DataSegmentBase(data(), sizeof(Entry), getDim(), isOrganized() ? m_pcl->width : -1, depth32f, sizeof(Entry)/sizeof(float)); }else{ return PointCloudObjectBase::error_dyn(featureName); } } /// offset specifications for specific datatypes! template<> int PCLPointCloudObject<pcl::PointXYZ>::offset(PointCloudObjectBase::FeatureType t) const { switch(t){ case XYZ: return 0; default: return -1; } } template<> int PCLPointCloudObject<pcl::PointXYZI>::offset(PointCloudObjectBase::FeatureType t) const { switch(t){ case XYZ: return 0; case Intensity: return 4*sizeof(float); default: return -1; } } template<> int PCLPointCloudObject<pcl::PointXYZL>::offset(PointCloudObjectBase::FeatureType t) const { switch(t){ case XYZ: return 0; case Label: return 4*sizeof(float); default: return -1; } } template<> int PCLPointCloudObject<pcl::PointXYZRGB>::offset(PointCloudObjectBase::FeatureType t) const { switch(t){ case XYZ: return 0; case BGR: return 4*sizeof(float); default: return -1; // case BGRA: case BGRA32s: is not available because an unused alpha value // could mess up the visualization } } template<> int PCLPointCloudObject<pcl::PointXYZRGBA>::offset(PointCloudObjectBase::FeatureType t) const { switch(t){ case XYZ: return 0; case BGR: case BGRA: case BGRA32s: return 4*sizeof(float); default: return -1; } } template<> int PCLPointCloudObject<pcl::PointXYZRGBL>::offset(PointCloudObjectBase::FeatureType t) const { switch(t){ case XYZ: return 0; case BGR: return 4*sizeof(float); // case BGRA: case BGRA32s: (not defined here) case Label: return 5*sizeof(float); default: return -1; } } template<> int PCLPointCloudObject<pcl::InterestPoint>::offset(PointCloudObjectBase::FeatureType t) const { switch(t){ case XYZ: return 0; case Intensity: return 4*sizeof(float); default: return -1; } } template<> int PCLPointCloudObject<pcl::PointXYZRGBNormal>::offset(PointCloudObjectBase::FeatureType t) const { switch(t){ case XYZ: return 0; case BGR: return 8*sizeof(float); // case BGRA: case BGRA32s: (not defined here) case Normal: return 4*sizeof(float); default: return -1; } } template<> int PCLPointCloudObject<pcl::PointXYZINormal>::offset(PointCloudObjectBase::FeatureType t) const { switch(t){ case XYZ: return 0; case Intensity: return 8*sizeof(float); case Normal: return 4*sizeof(float); default: return -1; } } // template<> int PCLPointCloudObject<pcl::PointWithRange>::offset(PointCloudObjectBase::FeatureType t) const { // switch(t){ // case XYZ: return 0; // case Intensity: return 4*sizeof(float); // default: return -1; // } // } // // template<> int PCLPointCloudObject<pcl::InterestPoint>::offset(PointCloudObjectBase::FeatureType t) const { // switch(t){ // case XYZ: return 0; // case Intensity: return 4*sizeof(float); // default: return -1; // } // } // template<> int PCLPointCloudObject<PCLPointType>::offset(PointCloudObjectBase::FeatureType t) const { // // switch(t){ // case XYZ: return 0; // case Intensity: return DataSegmentBase.stride*sizeof(float); // default: return -1; // } // } #define ICL_IMPLEMENT_FUNCTION(T,N,TYPE) \ template<class PCLPointType> \ DataSegment<T,N> PCLPointCloudObject<PCLPointType>::select##TYPE(){ \ return createSegment<T,N,TYPE>(); \ } ICL_IMPLEMENT_FUNCTION(float,1,Intensity) ICL_IMPLEMENT_FUNCTION(icl32s,1,Label) ICL_IMPLEMENT_FUNCTION(icl8u,3,BGR) ICL_IMPLEMENT_FUNCTION(icl8u,4,BGRA) ICL_IMPLEMENT_FUNCTION(icl32s,1,BGRA32s) ICL_IMPLEMENT_FUNCTION(float,3,XYZ); ICL_IMPLEMENT_FUNCTION(float,4,XYZH); ICL_IMPLEMENT_FUNCTION(float,4,Normal); ICL_IMPLEMENT_FUNCTION(float,4,RGBA32f); #undef ICL_IMPLEMENT_FUNCTION #define INSTANTIATE_CLASS(T) template class PCLPointCloudObject<T> INSTANTIATE_CLASS(pcl::PointXYZ); INSTANTIATE_CLASS(pcl::PointXYZI); INSTANTIATE_CLASS(pcl::PointXYZL); INSTANTIATE_CLASS(pcl::PointXYZRGB); INSTANTIATE_CLASS(pcl::PointXYZRGBA); INSTANTIATE_CLASS(pcl::PointXYZRGBL); INSTANTIATE_CLASS(pcl::InterestPoint); INSTANTIATE_CLASS(pcl::PointXYZRGBNormal); INSTANTIATE_CLASS(pcl::PointXYZINormal); #undef INSTANTIATE_CLASS } // namespace geom }