1 /* 2 * The following code is slightly based on the C# application 3 * SynthExport (http://synthexport.codeplex.com/) by Christoph Hausner 4 */ 5 6 #ifndef SYNTHDATA_H 7 #define SYNTHDATA_H 8 9 #include <QString> 10 #include <QScriptValue> 11 #include <QtSoapHttpTransport> 12 #include <assert.h> 13 #include <common/interfaces.h> 14 #include <QMutex> 15 16 using namespace vcg; 17 18 typedef struct Point 19 { 20 float _x; 21 float _y; 22 float _z; 23 uchar _r; 24 uchar _g; 25 uchar _b; 26 } Point; 27 28 typedef struct Image 29 { 30 int _ID; 31 int _width; 32 int _height; 33 int _exifWidth; 34 int _exifHeight; 35 QString _url; 36 QString _localPath; 37 int _shouldBeDownloaded; //tells how many times this image has to be downloaded, a value of zero means that this image won't be downloaded 38 } Image; 39 40 class CameraParameters 41 { 42 public: 43 enum Field 44 { 45 FIRST = 0, 46 POS_X = FIRST, 47 POS_Y, 48 POS_Z, 49 ROT_X, 50 ROT_Y, 51 ROT_Z, 52 ASPECT_RATIO, 53 FOCAL_LENGTH, //apparently the value provided by photosynth is: ccd_dimension_in_mm / focal_length_in_mm 54 LAST = FOCAL_LENGTH 55 }; 56 CameraParameters()57 CameraParameters() : _ccdWidth(0), _focalLength(0), _pixelSizeMm(0) {} 58 Point3m getTranslation(); 59 Matrix44m getRotation(); 60 61 //use this to access camera parameters values taken from photosynth json, using enum Field values as argument 62 inline qreal &operator [] (const int i) 63 { 64 assert(i >= 0 && i < 8); 65 return _fields[i]; 66 } 67 68 int _camID; 69 int _imageID; //the image whose this object represents the camera that took the shot 70 qreal _fields[8]; //contains position, rotation, aspect ratio, photosynth focal length, in the order of enum Field as taken from photosynth json 71 qreal _distortionRadius1; //from photosynth json 72 qreal _distortionRadius2; //from photosynth json 73 //intrinsics 74 float _ccdWidth; //taken from image exif data, or (when missing in exif) computed using image resolution in pixel and in dpi 75 float _focalLength; //estimated using _fields[8] and _ccdWidth 76 float _pixelSizeMm; //estimated using _ccdWidth and image resolution in pixel or, when the first is missing, with image resolution in dpi 77 }; 78 79 /* 80 * Represents a set of points 81 */ 82 class PointCloud : public QObject 83 { 84 public: 85 PointCloud(int coordSysID, int binFileCount, QObject *parent = 0); 86 87 public: 88 //the coordinate system id within the synth which this set belongs to 89 int _coordinateSystem; 90 //this is the n parameter in the points_m_n.bin files containing the synth point clounds 91 //and tells how many files this cloud is split into 92 int _binFileCount; 93 int _numberOfPoints; 94 QList<Point> _points; 95 }; 96 97 /* 98 * Represents an independent cluster of points within the synth, 99 * it is identified by an ID, contains a point cloud and 100 * has its own camera parameters 101 */ 102 class CoordinateSystem : public QObject 103 { 104 public: 105 CoordinateSystem(int id, QObject *parent = 0); 106 107 public: 108 //this is the m parameter in the points_m_n.bin files containing the synth point clounds 109 int _id; 110 bool _shouldBeImported; 111 PointCloud *_pointCloud; 112 QList<CameraParameters> _cameraParametersList; 113 }; 114 115 /* 116 * Represents the options of the import process 117 */ 118 class ImportSettings 119 { 120 public: ImportSettings()121 ImportSettings() { }; 122 ImportSettings(QString url, int clusterID, QString imageSavePath = QString("")); 123 124 public: 125 //the synth url 126 QString _url; 127 //specifies which coordinate system (cluster of point) has to be imported, -1 means all 128 int _clusterID; 129 //specifies the path where the images have to be saved to; if it is equal to the empty string, images won't be downloaded 130 QString _imageSavePath; 131 }; 132 133 /* 134 * Represents a Synth 135 */ 136 class SynthData : public QObject 137 { 138 Q_OBJECT 139 140 public: 141 //contains errors descriptions 142 static const QString errors[]; 143 //contains the strings used by cb() funcion 144 static const char *steps[]; 145 146 enum Error 147 { 148 WRONG_URL = 0, 149 WRONG_PATH, 150 WEBSERVICE_ERROR, 151 NEGATIVE_RESPONSE, 152 UNEXPECTED_RESPONSE, 153 WRONG_COLLECTION_TYPE, 154 JSON_PARSING, 155 EMPTY, 156 READING_BIN_DATA, 157 BIN_DATA_FORMAT, 158 CREATE_DIR, 159 SAVE_IMG, 160 SYNTH_NO_ERROR, 161 PENDING 162 }; 163 164 enum Step 165 { 166 WEB_SERVICE = 0, 167 DOWNLOAD_JSON, 168 PARSE_JSON, 169 DOWNLOAD_BIN, 170 LOADING_BIN, 171 DOWNLOAD_IMG 172 }; 173 174 SynthData(ImportSettings &settings, QObject *parent = 0); 175 ~SynthData(); 176 bool isValid(); 177 178 public: 179 void downloadSynthInfo(vcg::CallBackPos *cb); 180 int progressInfo(); 181 182 private slots: 183 void readWSresponse(const QtSoapMessage &response); 184 void parseJsonString(QNetworkReply *httpResponse); 185 void loadBinFile(QNetworkReply *httpResponse); 186 void saveImages(QNetworkReply *httpResponse); 187 188 private: 189 void parseImageMap(QScriptValue &map); 190 void downloadJsonData(QString jsonURL); 191 void downloadBinFiles(); 192 void downloadImages(); 193 bool checkAndSetState(bool condition, Error errorCode, QNetworkReply *httpResponse = 0); 194 void setState(Error errorCode, QNetworkReply *httpResponse = 0); 195 196 public: 197 //this is the cid parameter taken from the url used to access the synth on photosynth.net 198 QString _collectionID; 199 //the base url of the binary files points_m_n.bin containing point clouds data 200 QString _collectionRoot; 201 //Each coordinate system is a different cluster of point in the synth 202 QList<CoordinateSystem*> *_coordinateSystems; 203 //a dictionary mapping images id to image representation 204 QHash<int,Image> *_imageMap; 205 //tells if this synth is valid, or if errors were encountered during the import process 206 Error _state; 207 //tells the action the filter is performing during import process 208 Step _step; 209 //tells the progress (in percentage) of the step being executed 210 int _progress; 211 //during processing this string is set accordingly to the step is being executed 212 QString _info; 213 //when a SynthData is instantiated _dataReady == false 214 //until the data are downloaded from photosynth server 215 bool _dataReady; 216 ///Number of images of this synth 217 int _numImages; 218 int _imagesToDownloadCount; 219 //the callback function to inform the user about the progress of the filter 220 vcg::CallBackPos *_cb; 221 //contains import options 222 ImportSettings _settings; 223 QMutex _mutex; 224 225 private: 226 //used to count how many responses to bin files requests have been processed 227 //when _semaphore reaches 0 _dataReady can be set to true 228 //used also to count how many responses to images requests have been processed 229 //when _semaphore reaches _numImages, all images have been downloaded 230 int _semaphore; 231 int _totalBinFilesCount; 232 //the images will be saved here 233 QString _savePath; 234 }; 235 236 /********************* 237 * Utility functions * 238 *********************/ 239 240 int readCompressedInt(QIODevice *device, bool &error); 241 float readBigEndianSingle(QIODevice *device, bool &error); 242 unsigned short readBigEndianUInt16(QIODevice *device, bool &error); 243 void printPoint(Point *p); 244 245 #endif // SYNTHDATA_H 246