00001
00002
00003 #ifndef MODELER_MESHER_HPP
00004 #define MODELER_MESHER_HPP
00005
00006
00007
00008
00009
00010
00011
00012 #include "camera/cameraPinhole.hpp"
00013 #include "fdetect/InterestFeature.hpp"
00014 #include "geom/t3d.hpp"
00015 #include "jmath/jblas.hpp"
00016 #include "kernel/jafarMacro.hpp"
00017 #include "modeler/jfr_export_ply.h"
00018 #include "modeler/jfr_import_ply.h"
00019 #include "modeler/jfr_io_mask.h"
00020 #include "modeler/modelerException.hpp"
00021 #include "modeler/vcgDeclarations.hpp"
00022 #include "modeler/xyzMayBeN.hpp"
00023
00024 #include <vcg/complex/trimesh/update/bounding.h>
00025 #include <vcg/complex/trimesh/update/topology.h>
00026 #include <vcg/complex/trimesh/update/normal.h>
00027 #include <vcg/complex/trimesh/allocate.h>
00028
00029
00030 #include <iostream>
00031 #include <vector>
00032 #include <time.h>
00033
00034
00035 namespace jafar {
00036 namespace modeler {
00040 class Mesher {
00041
00042 public:
00043 enum HandledTypes {XYZ, PLY, UNKNOWN};
00044 private:
00045 void typeFromFileName(const std::string& filename,
00046 HandledTypes& type, std::string& extension)
00047 {
00048 size_t point_position = filename.find_last_of('.');
00049 extension = filename.substr(point_position+1);
00050 if (!extension.compare("xyz") || !extension.compare("XYZ")) {
00051 type = XYZ;
00052 }
00053 else if (!extension.compare("ply") || !extension.compare("PLY"))
00054 type = PLY;
00055 else
00056 type = UNKNOWN;
00057 };
00058
00059 public:
00060 typedef std::vector< fdetect_v2::InterestFeature<fdetect_v2::FloatDescriptor>* > Origines;
00061
00063 JfrMesh mesh;
00065 vcg::tri::Allocator<JfrMesh>::PointerUpdater<JfrMesh::VertexPointer> pu;
00066
00068 Mesher() {};
00070 Mesher(JfrMesh &_mesh) : mesh(_mesh) {};
00074 Mesher(const std::string& filename)
00075 {
00076 std::string extension;
00077 HandledTypes type;
00078 typeFromFileName(filename, type, extension);
00079 switch (type) {
00080 case XYZ :
00081 {
00082 XYZMayBeN points;
00083 points.load(filename);
00084 JfrMesh::VertexIterator v_iter = vcg::tri::Allocator<JfrMesh>::AddVertices(mesh, points.matrix.rows);
00085 JfrMesh::CoordType p, n;
00086 if(points.matrix.cols == 3) {
00087 for (int i = 0; i < points.matrix.rows; ++i, ++v_iter) {
00088 for (int j=0; j < 3; ++j) {
00089 p[j] = points.matrix.at<float>(i,j);
00090 }
00091 v_iter->P() = p;
00092 }
00093 } else {
00094 if (points.matrix.cols == 6){
00095 for (int i = 0; i < points.matrix.rows; ++i, ++v_iter) {
00096 for (int j=0; j < 3; ++j) {
00097 p[j] = points.matrix.at<float>(i,j);
00098 n[j] = points.matrix.at<float>(i,3+j);
00099 }
00100 v_iter->P() = p;
00101 v_iter->N() = n;
00102 }
00103 }
00104 }
00105 }
00106 break;
00107 case PLY :
00108 {
00109 int mask = 0;
00110 if (vcg::tri::io::JfrImporterPLY<JfrMesh>::Open(mesh, filename.c_str(), mask) != 0)
00111 JFR_ERROR(ModelerException,
00112 ModelerException::FILE_READING_ERROR,
00113 "Error reading ply file "<<filename)
00114 }
00115 break;
00116 default:
00117 JFR_ERROR(ModelerException,
00118 ModelerException::WRONG_TYPE,
00119 "Unknown file extension " << extension)
00120 break;
00121 }
00122 }
00126 virtual void run(const float&, const float&, const float&) = 0;
00127
00128
00129
00130
00131
00132 void save(const std::string& file_name, bool save_binary = false) {
00133
00134 int mask = 0;
00135 mask |= vcg::tri::io::JfrMask::IOM_VERTORIGINES;
00136 mask |= vcg::tri::io::JfrMask::IOM_VERTID;
00137 mask |= vcg::tri::io::JfrMask::IOM_CAMERA;
00138 vcg::tri::io::JfrExporterPLY<JfrMesh>::Save(mesh,file_name.c_str(), mask, save_binary);
00139 }
00140
00141
00142
00143
00144
00145
00146 void load(const std::string& file_name, int& mask) {
00147
00148 mask = 0;
00149 vcg::tri::io::JfrImporterPLY<JfrMesh>::Open(mesh,file_name.c_str(), mask);
00150 }
00151
00152 virtual ~Mesher() {};
00154 void setVertices(const std::map<unsigned int, jblas::vec3> &points);
00156 void setVertices(const std::map<unsigned int, jblas::vec3> &points,
00157 const std::map<unsigned int, Mesher::Origines >& origines);
00166 void addVertex(unsigned int id, const JfrMesh::CoordType& v,
00167 unsigned int& internal_id);
00168
00178 void addVertex(unsigned int id, const JfrMesh::CoordType& v,
00179 const std::vector<unsigned int>& origines,
00180 unsigned int& internal_id);
00188 void addVertex(unsigned int id, const JfrMesh::CoordType& v,
00189 const std::vector<unsigned int>& origines);
00190
00192 JfrMesh::VertexPointer pointerFromPos(unsigned int position)
00193 {
00194 return &(mesh.vert[position]);
00195 }
00197 void setShots(const std::map<unsigned int, jblas::vec>& cameras,
00198 const std::map<unsigned int, geom::T3D*>& frames);
00200 void setShots(const jblas::vec& intrinsic,
00201 const std::map<unsigned int, geom::T3D*>& frames);
00202
00204 void addShot(unsigned int id, const jblas::vec& intr, const geom::T3D* extr);
00206 void addFeature(fdetect_v2::InterestFeature<fdetect_v2::FloatDescriptor>* ft)
00207 {
00208 mesh.addFeature(ft);
00209 }
00211 void update()
00212 {
00213 vcg::tri::UpdateBounding<JfrMesh>::Box(mesh);
00214 vcg::tri::UpdateNormals<JfrMesh>::PerFace(mesh);
00215 }
00217 void update(JfrMesh::VertexPointer& vp)
00218 {
00219 if(pu.NeedUpdate()) pu.Update(vp);
00220 }
00222 unsigned int lastShotId()
00223 {
00224 std::map<unsigned int, JfrMesh::Shot>::reverse_iterator last = mesh.shots.rbegin();
00225 return last->first;
00226 }
00227 };
00228
00235 template<typename S>
00236 static void convert(const vcg::Shot<S> &shot, camera::CameraPinhole& camera, geom::T3D* frame)
00237 {
00238 camera.alphaU = double(shot.Intrinsics.PixelSizeMm[0]);
00239 camera.alphaV = double(shot.Intrinsics.PixelSizeMm[1]);
00240 camera.u0 = double(shot.Intrinsics.CenterPx[0] );
00241 camera.v0 = double(shot.Intrinsics.CenterPx[1] );
00242 camera.width = shot.Intrinsics.ViewportPx[0];
00243 camera.height = shot.Intrinsics.ViewportPx[1];
00244
00245 vcg::Matrix44<S> rm = shot.Extrinsics.Rot();
00246 jblas::mat33 r;
00247 r(0,0) = double(rm[0][0]);
00248 r(0,1) = double(rm[0][1]);
00249 r(0,2) = double(rm[0][2]);
00250
00251 r(1,0) = double(rm[1][0]);
00252 r(1,1) = double(rm[1][1]);
00253 r(1,2) = double(rm[1][2]);
00254
00255 r(2,0) = double(rm[2][0]);
00256 r(2,1) = double(rm[2][1]);
00257 r(2,2) = double(rm[2][2]);
00258
00259 vcg::Point3<S> tv = shot.Extrinsics.Tra();
00260 jblas::vec3 t;
00261 t[0] = double(tv[0]);
00262 t[1] = double(tv[1]);
00263 t[2] = double(tv[2]);
00264
00265 frame->set(r,t);
00266 }
00272 template<typename S>
00273 static void convert(const vcg::Shot<S> &shot,
00274 jblas::vec& intrinsics, geom::T3D* extrinsics)
00275 {
00276 intrinsics.resize(6);
00277 intrinsics[0] = double(shot.Intrinsics.ViewportPx[0] );
00278 intrinsics[1] = double(shot.Intrinsics.ViewportPx[1] );
00279 intrinsics[2] = double(shot.Intrinsics.CenterPx[0] );
00280 intrinsics[3] = double(shot.Intrinsics.CenterPx[1] );
00281 intrinsics[4] = double(shot.Intrinsics.PixelSizeMm[0]);
00282 intrinsics[5] = double(shot.Intrinsics.PixelSizeMm[1]);
00283
00284 vcg::Matrix44<S> rm = shot.Extrinsics.Rot();
00285 jblas::mat33 r;
00286 r(0,0) = double(rm[0][0]);
00287 r(0,1) = double(rm[0][1]);
00288 r(0,2) = double(rm[0][2]);
00289
00290 r(1,0) = double(rm[1][0]);
00291 r(1,1) = double(rm[1][1]);
00292 r(1,2) = double(rm[1][2]);
00293
00294 r(2,0) = double(rm[2][0]);
00295 r(2,1) = double(rm[2][1]);
00296 r(2,2) = double(rm[2][2]);
00297
00298 vcg::Point3<S> tv = shot.Extrinsics.Tra();
00299 jblas::vec3 t;
00300 t[0] = double(tv[0]);
00301 t[1] = double(tv[1]);
00302 t[2] = double(tv[2]);
00303
00304 extrinsics->set(r,t);
00305 }
00306
00313 template<typename S>
00314 static void convert(const jblas::vec& intrinsics, const geom::T3D* extrinsics,
00315 vcg::Shot<S> &shot)
00316 {
00317 assert(intrinsics.size() == 6);
00318 shot.Intrinsics.ViewportPx[0] = (int)intrinsics[0];
00319 shot.Intrinsics.ViewportPx[1] = (int)intrinsics[1];
00320 shot.Intrinsics.CenterPx[0] = (S)intrinsics[2];
00321 shot.Intrinsics.CenterPx[1] = (S)intrinsics[3];
00322 shot.Intrinsics.PixelSizeMm[0] = (S)intrinsics[4];
00323 shot.Intrinsics.PixelSizeMm[1] = (S)intrinsics[5];
00324
00325 vcg::Matrix44<S> rm;
00326 jblas::mat33 r = extrinsics->getR();
00327 rm[0][0] = (S)r(0,0);
00328 rm[0][1] = (S)r(0,1);
00329 rm[0][2] = (S)r(0,2);
00330
00331 rm[1][0] = (S)r(1,0);
00332 rm[1][1] = (S)r(1,1);
00333 rm[1][2] = (S)r(1,2);
00334
00335 rm[2][0] = (S)r(2,0);
00336 rm[2][1] = (S)r(2,1);
00337 rm[2][2] = (S)r(2,2);
00338 shot.Extrinsics.Rot() = rm;
00339 vcg::Point3<S> tv;
00340 jblas::vec3 t = extrinsics->getT();
00341 tv[0] = (S)t[0];
00342 tv[1] = (S)t[1];
00343 tv[2] = (S)t[2];
00344 shot.Extrinsics.Tra() = tv;
00345 }
00346
00347 }
00348 }
00349
00350 #endif