changed architecture of the filter in order to avoid MeshLab crash on startup dues to static declaration of QSoapHttpTransport.

This commit is contained in:
Guido Ranzuglia granzuglia 2011-02-05 10:23:36 +00:00
parent 42986a5629
commit 9be5d49470
4 changed files with 131 additions and 131 deletions

View File

@ -111,7 +111,7 @@ const char *SynthData::steps[] =
};
SynthData::SynthData(ImportSettings &settings, QObject *parent)
: QObject(parent)
: QObject(parent),transport()
{
_coordinateSystems = new QList<CoordinateSystem*>();
_imageMap = new QHash<int,Image>();
@ -122,6 +122,7 @@ SynthData::SynthData(ImportSettings &settings, QObject *parent)
_dataReady = false;
_semaphore = 0;
_imagesToDownloadCount = 0;
connect(&transport, SIGNAL(responseReady()),this, SLOT(readWSresponse()));
}
SynthData::~SynthData()
@ -150,45 +151,44 @@ int SynthData::progressInfo()
return _progress;
}
QtSoapHttpTransport SynthData::transport;
//QtSoapHttpTransport SynthData::transport;
/*
* Contacts the photosynth web service to retrieve informations about
* the synth whose identifier is contained within the given url.
*/
SynthData *SynthData::downloadSynthInfo(ImportSettings &settings, vcg::CallBackPos *cb)
void SynthData::downloadSynthInfo(vcg::CallBackPos *cb)
{
SynthData *synthData = new SynthData(settings);
synthData->_cb = cb;
synthData->_step = WEB_SERVICE;
synthData->_progress = 0;
synthData->_cb(synthData->progressInfo(),synthData->_info.toStdString().data());
if(settings._url.isNull() || settings._url.isEmpty())
_cb = cb;
_step = WEB_SERVICE;
_progress = 0;
_cb(progressInfo(),_info.toStdString().data());
if(_settings._url.isNull() || _settings._url.isEmpty())
{
synthData->_state = WRONG_URL;
synthData->_dataReady = true;
return synthData;
_state = WRONG_URL;
_dataReady = true;
return;
}
if(settings._imageSavePath.isNull())
if(_settings._imageSavePath.isNull())
{
synthData->_state = WRONG_PATH;
synthData->_dataReady = true;
return synthData;
_state = WRONG_PATH;
_dataReady = true;
return ;
}
synthData->_savePath = settings._imageSavePath;
_savePath = _settings._imageSavePath;
//extracts the synth identifier
int i = settings._url.indexOf("cid=",0,Qt::CaseInsensitive);
if(i < 0 || settings._url.length() < i + 40)
int i = _settings._url.indexOf("cid=",0,Qt::CaseInsensitive);
if(i < 0 || _settings._url.length() < i + 40)
{
synthData->_state = WRONG_URL;
synthData->_dataReady = true;
return synthData;
_state = WRONG_URL;
_dataReady = true;
return;
}
QString cid = settings._url.mid(i + 4, 36);
synthData->_collectionID = cid;
QString cid = _settings._url.mid(i + 4, 36);
_collectionID = cid;
QtSoapMessage message;
message.setMethod("GetCollectionData", "http://labs.live.com/");
@ -197,13 +197,11 @@ SynthData *SynthData::downloadSynthInfo(ImportSettings &settings, vcg::CallBackP
transport.setAction("http://labs.live.com/GetCollectionData");
transport.setHost("photosynth.net");
QObject::connect(&transport, SIGNAL(responseReady()), synthData, SLOT(readWSresponse()));
transport.submitRequest(message, "/photosynthws/PhotosynthService.asmx");
synthData->_state = PENDING;
synthData->_progress = 50;
synthData->_cb(synthData->progressInfo(),synthData->_info.toStdString().data());
return synthData;
_state = PENDING;
_progress = 50;
_cb(progressInfo(),_info.toStdString().data());
}
/*

View File

@ -12,7 +12,7 @@
****************************************************************************/
#include "filter_photosynth.h"
#include <QtScript>
//#include <QtScript>
//#define FILTER_PHOTOSYNTH_DEBUG 1
@ -102,104 +102,105 @@ void FilterPhotosynthPlugin::initParameterSet(QAction *action, MeshModel &/*m*/,
// The Real Core Function doing the actual mesh processing.
bool FilterPhotosynthPlugin::applyFilter(QAction */*filter*/, MeshDocument &md, RichParameterSet &par, vcg::CallBackPos *cb)
{
ImportSettings settings(par.getString("synthURL"), par.getInt("clusterID"));
if(par.getBool("saveImages"))
settings._imageSavePath = par.getString("savePath");
SynthData *synthData = SynthData::downloadSynthInfo(settings,cb);
//Hangs on active wait until data are available from the server
while(!synthData->_dataReady)
{
//allows qt main loop to process the events relative to the response from the server,
//triggering the signals that cause the invocation of the slots that process the response
//and set the control variable that stops this active wait.
//Note that a call to the function usleep() causes an infinite loop, because when the process awakes,
//the control remains inside this loop and doesn't reach qt main loop that this way can't process events.
QApplication::processEvents();
cb(synthData->progressInfo(),synthData->_info.toStdString().data());
}
if(!synthData->isValid())
{
this->errorMessage = SynthData::errors[synthData->_state];
delete synthData;
return false;
}
cb(0,"Finishing import...");
QDir imageDir(settings._imageSavePath);
imageDir.cd(synthData->_collectionID);
#ifdef FILTER_PHOTOSYNTH_DEBUG
QFile cameraXMLfile(imageDir.filePath("Cam.txt"));
bool success = true;
if (!cameraXMLfile.open(QIODevice::WriteOnly | QIODevice::Text))
{
success = false;
qWarning() << "Failed to create cam.txt";
}
QTextStream out(&cameraXMLfile);
#endif
//scan coordinate systems list and add a new layer for each one, containing its points
const QList<CoordinateSystem*> *coordinateSystems = synthData->_coordinateSystems;
CoordinateSystem *sys;
int count = coordinateSystems->count();
foreach(sys, *coordinateSystems)
{
cb((int)(sys->_id / count),"Finishing import...");
if(sys->_pointCloud)
{
MeshModel *mm = md.addNewMesh("","coordsys"); // After Adding a mesh to a MeshDocument the new mesh is the current one
Point p;
foreach(p, sys->_pointCloud->_points)
{
tri::Allocator<CMeshO>::AddVertices(mm->cm,1);
mm->cm.vert.back().P() = Point3f(p._x,p._z,-p._y);
mm->cm.vert.back().C() = Color4b(p._r,p._g,p._b,255);
}
//we consider cameras only if the user chooses to download images
if(par.getBool("saveImages"))
{
MeshModel *mm;
if(par.getBool("addCameraLayer"))
//create a new layer where add points representing cameras to
mm = md.addNewMesh("","cameras");
CameraParameters cam;
//scan cameras list for this coordinate system and for each one add a raster with a shot matching the camera
foreach(cam, sys->_cameraParametersList)
{
Shotf s;
s.Extrinsics.SetRot(cam.getRotation());
s.Extrinsics.SetTra(cam.getTranslation());
Image img = synthData->_imageMap->value(cam._imageID);
s.Intrinsics.FocalMm = cam[CameraParameters::FOCAL_LENGTH] * qMax(img._width,img._height);
s.Intrinsics.PixelSizeMm = Point2f(1,1);
s.Intrinsics.ViewportPx = Point2i(img._width,img._height);
s.Intrinsics.CenterPx = Point2f(img._width/2,img._height/2);
#ifdef FILTER_PHOTOSYNTH_DEBUG
if(success)
outputToFile(out, s, img, cam);
#endif
if(par.getBool("addCameraLayer"))
{
//add a point to the cameras layer as a placeholder for the camera
tri::Allocator<CMeshO>::AddVertices(mm->cm,1);
mm->cm.vert.back().P() = cam.getTranslation();
}
//add a new raster
//the same image can be added several times, one for each coordinate system it appears into
//this way the user can choose which point cloud the raster has to align with
RasterModel *rm = md.addNewRaster();
QString imgName = imageDir.filePath(QString("IMG_%1.jpg").arg(img._ID) );
rm->addPlane(new Plane(rm,imgName,QString("")));
rm->shot = s;
rm->setLabel(QString("IMG_%1_%2.jpg").arg(int(img._ID),3,10,QLatin1Char('0')).arg(sys->_id));
}
}
}
}
#ifdef DEGUG
cameraXMLfile.close();
#endif
delete synthData;
ImportSettings settings(par.getString("synthURL"), par.getInt("clusterID"));
if(par.getBool("saveImages"))
settings._imageSavePath = par.getString("savePath");
//SynthData *synthData = SynthData::downloadSynthInfo(settings,cb);
SynthData *synthData = new SynthData(settings);
synthData->downloadSynthInfo(cb);
//Hangs on active wait until data are available from the server
while(!synthData->_dataReady)
{
//allows qt main loop to process the events relative to the response from the server,
//triggering the signals that cause the invocation of the slots that process the response
//and set the control variable that stops this active wait.
//Note that a call to the function usleep() causes an infinite loop, because when the process awakes,
//the control remains inside this loop and doesn't reach qt main loop that this way can't process events.
QApplication::processEvents();
cb(synthData->progressInfo(),synthData->_info.toStdString().data());
}
if(!synthData->isValid())
{
this->errorMessage = SynthData::errors[synthData->_state];
delete synthData;
return false;
}
cb(0,"Finishing import...");
QDir imageDir(settings._imageSavePath);
imageDir.cd(synthData->_collectionID);
#ifdef FILTER_PHOTOSYNTH_DEBUG
QFile cameraXMLfile(imageDir.filePath("Cam.txt"));
bool success = true;
if (!cameraXMLfile.open(QIODevice::WriteOnly | QIODevice::Text))
{
success = false;
qWarning() << "Failed to create cam.txt";
}
QTextStream out(&cameraXMLfile);
#endif
//scan coordinate systems list and add a new layer for each one, containing its points
const QList<CoordinateSystem*> *coordinateSystems = synthData->_coordinateSystems;
CoordinateSystem *sys;
int count = coordinateSystems->count();
foreach(sys, *coordinateSystems)
{
cb((int)(sys->_id / count),"Finishing import...");
if(sys->_pointCloud)
{
MeshModel *mm = md.addNewMesh("","coordsys"); // After Adding a mesh to a MeshDocument the new mesh is the current one
Point p;
foreach(p, sys->_pointCloud->_points)
{
tri::Allocator<CMeshO>::AddVertices(mm->cm,1);
mm->cm.vert.back().P() = Point3f(p._x,p._z,-p._y);
mm->cm.vert.back().C() = Color4b(p._r,p._g,p._b,255);
}
//we consider cameras only if the user chooses to download images
if(par.getBool("saveImages"))
{
MeshModel *mm;
if(par.getBool("addCameraLayer"))
//create a new layer where add points representing cameras to
mm = md.addNewMesh("","cameras");
CameraParameters cam;
//scan cameras list for this coordinate system and for each one add a raster with a shot matching the camera
foreach(cam, sys->_cameraParametersList)
{
Shotf s;
s.Extrinsics.SetRot(cam.getRotation());
s.Extrinsics.SetTra(cam.getTranslation());
Image img = synthData->_imageMap->value(cam._imageID);
s.Intrinsics.FocalMm = cam[CameraParameters::FOCAL_LENGTH] * qMax(img._width,img._height);
s.Intrinsics.PixelSizeMm = Point2f(1,1);
s.Intrinsics.ViewportPx = Point2i(img._width,img._height);
s.Intrinsics.CenterPx = Point2f(img._width/2,img._height/2);
#ifdef FILTER_PHOTOSYNTH_DEBUG
if(success)
outputToFile(out, s, img, cam);
#endif
if(par.getBool("addCameraLayer"))
{
//add a point to the cameras layer as a placeholder for the camera
tri::Allocator<CMeshO>::AddVertices(mm->cm,1);
mm->cm.vert.back().P() = cam.getTranslation();
}
//add a new raster
//the same image can be added several times, one for each coordinate system it appears into
//this way the user can choose which point cloud the raster has to align with
RasterModel *rm = md.addNewRaster();
QString imgName = imageDir.filePath(QString("IMG_%1.jpg").arg(img._ID) );
rm->addPlane(new Plane(rm,imgName,QString("")));
rm->shot = s;
rm->setLabel(QString("IMG_%1_%2.jpg").arg(int(img._ID),3,10,QLatin1Char('0')).arg(sys->_id));
}
}
}
}
#ifdef DEGUG
cameraXMLfile.close();
#endif
delete synthData;
return true;
}

View File

@ -14,8 +14,10 @@
#ifndef FILTER_PHOTOSYNTH_PLUGIN_H
#define FILTER_PHOTOSYNTH_PLUGIN_H
#include <common/interfaces.h>
#include "synthData.h"
class FilterPhotosynthPlugin : public QObject, public MeshFilterInterface
{
Q_OBJECT

View File

@ -136,8 +136,6 @@ class SynthData : public QObject
{
Q_OBJECT
static QtSoapHttpTransport transport;
public:
//contains errors descriptions
static const QString errors[];
@ -177,7 +175,7 @@ public:
bool isValid();
public:
static SynthData *downloadSynthInfo(ImportSettings &settings, vcg::CallBackPos *cb);
void downloadSynthInfo(vcg::CallBackPos *cb);
int progressInfo();
private slots:
@ -229,6 +227,7 @@ private:
int _totalBinFilesCount;
//the images will be saved here
QString _savePath;
QtSoapHttpTransport transport;
};
/*********************