mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-13 08:09:39 +00:00
moved MeshDocument class
This commit is contained in:
parent
bb025370c5
commit
05369f1668
@ -1,5 +1,5 @@
|
||||
#include "rich_parameter.h"
|
||||
#include "../mesh_data_structures/mesh_model.h"
|
||||
#include "../mesh_data_structures/mesh_document.h"
|
||||
|
||||
/**** RichParameter Class ****/
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#include "value.h"
|
||||
|
||||
#include "../mesh_data_structures/mesh_model.h"
|
||||
#include "../mesh_data_structures/mesh_document.h"
|
||||
|
||||
void BoolValue::fillToXMLElement(QDomElement& element) const
|
||||
{
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
#include <QTabletEvent>
|
||||
|
||||
#include "plugin_interface.h"
|
||||
#include "../mesh_data_structures/mesh_model.h"
|
||||
#include "../mesh_data_structures/mesh_document.h"
|
||||
|
||||
|
||||
class GLArea;
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
#define MESHLAB_FILTER_PLUGIN_INTERFACE_H
|
||||
|
||||
#include "plugin_interface.h"
|
||||
#include "../mesh_data_structures/mesh_model.h"
|
||||
#include "../mesh_data_structures/mesh_document.h"
|
||||
|
||||
/**
|
||||
\brief The MeshFilterInterface class provide the interface of the filter plugins.
|
||||
|
||||
@ -23,3 +23,286 @@
|
||||
|
||||
#include "mesh_document.h"
|
||||
|
||||
template <class LayerElement>
|
||||
QString NameDisambiguator(QList<LayerElement*> &elemList, QString meshLabel )
|
||||
{
|
||||
QString newName=std::move(meshLabel);
|
||||
typename QList<LayerElement*>::iterator mmi;
|
||||
|
||||
for(mmi=elemList.begin(); mmi!=elemList.end(); ++mmi)
|
||||
{
|
||||
if((*mmi)->label() == newName) // if duplicated name found
|
||||
{
|
||||
QFileInfo fi((*mmi)->label());
|
||||
QString baseName = fi.baseName(); // all characters in the file up to the first '.' Eg "/tmp/archive.tar.gz" -> "archive"
|
||||
QString suffix = fi.suffix();
|
||||
bool ok;
|
||||
|
||||
// if name ends with a number between parenthesis (XXX),
|
||||
// it was himself a duplicated name, and we need to
|
||||
// just increase the number between parenthesis
|
||||
int numDisamb;
|
||||
int startDisamb;
|
||||
int endDisamb;
|
||||
|
||||
startDisamb = baseName.lastIndexOf("(");
|
||||
endDisamb = baseName.lastIndexOf(")");
|
||||
if((startDisamb!=-1)&&(endDisamb!=-1))
|
||||
numDisamb = (baseName.mid((startDisamb+1),(endDisamb-startDisamb-1))).toInt(&ok);
|
||||
else
|
||||
numDisamb = 0;
|
||||
|
||||
if(startDisamb!=-1)
|
||||
newName = baseName.left(startDisamb)+ "(" + QString::number(numDisamb+1) + ")";
|
||||
else
|
||||
newName = baseName + "(" + QString::number(numDisamb+1) + ")";
|
||||
|
||||
if (suffix != QString(""))
|
||||
newName = newName + "." + suffix;
|
||||
|
||||
// now recurse to see if the new name is free
|
||||
newName = NameDisambiguator(elemList, newName);
|
||||
}
|
||||
}
|
||||
return newName;
|
||||
}
|
||||
|
||||
MeshDocument::MeshDocument()
|
||||
{
|
||||
meshIdCounter=0;
|
||||
rasterIdCounter=0;
|
||||
currentMesh = nullptr;
|
||||
currentRaster = nullptr;
|
||||
busy=false;
|
||||
}
|
||||
|
||||
//deletes each meshModel
|
||||
MeshDocument::~MeshDocument()
|
||||
{
|
||||
foreach(MeshModel *mmp, meshList)
|
||||
delete mmp;
|
||||
foreach(RasterModel* rmp,rasterList)
|
||||
delete rmp;
|
||||
}
|
||||
|
||||
void MeshDocument::clear()
|
||||
{
|
||||
for(MeshModel *mmp : meshList)
|
||||
delete mmp;
|
||||
meshList.clear();
|
||||
|
||||
for(RasterModel* rmp :rasterList)
|
||||
delete rmp;
|
||||
rasterList.clear();
|
||||
|
||||
meshIdCounter=0;
|
||||
rasterIdCounter=0;
|
||||
currentMesh = nullptr;
|
||||
currentRaster = nullptr;
|
||||
busy=false;
|
||||
filterHistory.clear();
|
||||
fullPathFilename = "";
|
||||
documentLabel = "";
|
||||
meshDocStateData().clear();
|
||||
}
|
||||
|
||||
const MeshModel* MeshDocument::getMesh(int id) const
|
||||
{
|
||||
for (const MeshModel* m : meshList)
|
||||
if (m->id() == id)
|
||||
return m;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//returns the mesh ata given position in the list
|
||||
MeshModel* MeshDocument::getMesh(int id)
|
||||
{
|
||||
for (MeshModel* m : meshList)
|
||||
if (m->id() == id)
|
||||
return m;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const MeshModel* MeshDocument::getMesh(const QString& name) const
|
||||
{
|
||||
for (const MeshModel* m : meshList)
|
||||
if (m->shortName() == name)
|
||||
return m;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MeshModel* MeshDocument::getMesh(const QString& name)
|
||||
{
|
||||
for (MeshModel* m : meshList)
|
||||
if (m->shortName() == name)
|
||||
return m;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const MeshModel* MeshDocument::getMeshByFullName(const QString& pathName) const
|
||||
{
|
||||
for (const MeshModel* m : meshList)
|
||||
if (m->fullName() == pathName)
|
||||
return m;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MeshModel* MeshDocument::getMeshByFullName(const QString& pathName)
|
||||
{
|
||||
for (MeshModel* m : meshList)
|
||||
if (m->fullName() == pathName)
|
||||
return m;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void MeshDocument::setCurrentMesh(int new_curr_id)
|
||||
{
|
||||
if(new_curr_id<0)
|
||||
{
|
||||
currentMesh=0;
|
||||
return;
|
||||
}
|
||||
currentMesh = getMesh(new_curr_id);
|
||||
emit currentMeshChanged(new_curr_id);
|
||||
assert(currentMesh);
|
||||
}
|
||||
|
||||
//returns the raster at a given position in the list
|
||||
RasterModel *MeshDocument::getRaster(int i)
|
||||
{
|
||||
foreach(RasterModel *rmp, rasterList)
|
||||
{
|
||||
if(rmp->id() == i) return rmp;
|
||||
}
|
||||
//assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//if i is <0 it means that no currentRaster is set
|
||||
void MeshDocument::setCurrentRaster( int new_curr_id)
|
||||
{
|
||||
if(new_curr_id<0)
|
||||
{
|
||||
currentRaster=0;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(RasterModel *rmp, rasterList)
|
||||
{
|
||||
if(rmp->id() == new_curr_id)
|
||||
{
|
||||
currentRaster = rmp;
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void MeshDocument::requestUpdatingPerMeshDecorators(int mesh_id)
|
||||
{
|
||||
emit updateDecorators(mesh_id);
|
||||
}
|
||||
|
||||
MeshModel * MeshDocument::addNewMesh(QString fullPath, QString label, bool setAsCurrent)
|
||||
{
|
||||
QString newlabel = NameDisambiguator(this->meshList,std::move(label));
|
||||
|
||||
if(!fullPath.isEmpty())
|
||||
{
|
||||
QFileInfo fi(fullPath);
|
||||
fullPath = fi.absoluteFilePath();
|
||||
}
|
||||
|
||||
MeshModel *newMesh = new MeshModel(this,fullPath,newlabel);
|
||||
meshList.push_back(newMesh);
|
||||
|
||||
if(setAsCurrent)
|
||||
this->setCurrentMesh(newMesh->id());
|
||||
|
||||
emit meshSetChanged();
|
||||
emit meshAdded(newMesh->id());
|
||||
return newMesh;
|
||||
}
|
||||
|
||||
MeshModel * MeshDocument::addOrGetMesh(QString fullPath, const QString& label, bool setAsCurrent)
|
||||
{
|
||||
MeshModel *newMesh = getMesh(label);
|
||||
if(newMesh) {
|
||||
if(setAsCurrent)
|
||||
this->setCurrentMesh(newMesh->id());
|
||||
return newMesh;
|
||||
}
|
||||
return addNewMesh(std::move(fullPath),label,setAsCurrent);
|
||||
}
|
||||
|
||||
bool MeshDocument::delMesh(MeshModel *mmToDel)
|
||||
{
|
||||
if(!meshList.removeOne(mmToDel))
|
||||
return false;
|
||||
if((currentMesh == mmToDel) && (!meshList.empty()))
|
||||
setCurrentMesh(this->meshList.at(0)->id());
|
||||
else if (meshList.empty())
|
||||
setCurrentMesh(-1);
|
||||
|
||||
int index = mmToDel->id();
|
||||
delete mmToDel;
|
||||
|
||||
emit meshSetChanged();
|
||||
emit meshRemoved(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
RasterModel * MeshDocument::addNewRaster(/*QString fullPathFilename*/)
|
||||
{
|
||||
QFileInfo info(fullPathFilename);
|
||||
QString newLabel=info.fileName();
|
||||
QString newName = NameDisambiguator(this->rasterList, newLabel);
|
||||
|
||||
RasterModel *newRaster=new RasterModel(this, newLabel);
|
||||
rasterList.push_back(newRaster);
|
||||
|
||||
//Add new plane
|
||||
//Plane *plane = new Plane(newRaster, fullPathFilename, QString());
|
||||
//newRaster->addPlane(plane);
|
||||
|
||||
this->setCurrentRaster(newRaster->id());
|
||||
|
||||
emit rasterSetChanged();
|
||||
return newRaster;
|
||||
}
|
||||
|
||||
bool MeshDocument::delRaster(RasterModel *rasterToDel)
|
||||
{
|
||||
QMutableListIterator<RasterModel *> i(rasterList);
|
||||
|
||||
while (i.hasNext())
|
||||
{
|
||||
RasterModel *r = i.next();
|
||||
|
||||
if (r==rasterToDel)
|
||||
{
|
||||
i.remove();
|
||||
delete rasterToDel;
|
||||
}
|
||||
}
|
||||
|
||||
if(currentRaster == rasterToDel)
|
||||
{
|
||||
if (!rasterList.empty())
|
||||
setCurrentRaster(rasterList.at(0)->id());
|
||||
else
|
||||
setCurrentRaster(-1);
|
||||
}
|
||||
emit rasterSetChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MeshDocument::hasBeenModified()
|
||||
{
|
||||
foreach(MeshModel *m, meshList)
|
||||
if(m->meshModified()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -21,9 +21,218 @@
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MESHDOCUMENT_H
|
||||
#define MESHDOCUMENT_H
|
||||
#ifndef MESH_DOCUMENT_H
|
||||
#define MESH_DOCUMENT_H
|
||||
|
||||
#include "mesh_model.h"
|
||||
|
||||
class MeshDocument : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
MeshDocument();
|
||||
|
||||
//deletes each meshModel
|
||||
~MeshDocument();
|
||||
|
||||
void clear();
|
||||
|
||||
///returns the mesh with the given unique id
|
||||
const MeshModel* getMesh(int id) const;
|
||||
MeshModel *getMesh(int id);
|
||||
const MeshModel *getMesh(const QString& name) const;
|
||||
MeshModel *getMesh(const QString& name);
|
||||
const MeshModel *getMeshByFullName(const QString& pathName) const;
|
||||
MeshModel *getMeshByFullName(const QString& pathName);
|
||||
|
||||
//set the current mesh to be the one with the given ID
|
||||
void setCurrentMesh( int new_curr_id );
|
||||
|
||||
void setVisible(int meshId, bool val);
|
||||
|
||||
/// returns the raster with the given unique id
|
||||
RasterModel *getRaster(int i);
|
||||
|
||||
//set the current raster to be the one with the given ID
|
||||
void setCurrentRaster( int new_curr_id );
|
||||
void setCurrent(MeshModel *newCur) { setCurrentMesh(newCur->id());}
|
||||
void setCurrent(RasterModel *newCur) { setCurrentRaster(newCur->id());}
|
||||
|
||||
/// methods to access the set of Meshes in a ordered fashion.
|
||||
MeshModel *nextVisibleMesh(MeshModel *_m = NULL)
|
||||
{
|
||||
MeshModel *newM = nextMesh(_m);
|
||||
if(newM==0)
|
||||
return newM;
|
||||
|
||||
if(newM->isVisible())
|
||||
return newM;
|
||||
else
|
||||
return nextVisibleMesh(newM);
|
||||
}
|
||||
|
||||
MeshModel *nextMesh(MeshModel *_m = NULL)
|
||||
{
|
||||
if(_m==0 && meshList.size()>0)
|
||||
return meshList.at(0);
|
||||
for (int i = 0; i < meshList.size(); ++i) {
|
||||
if (meshList.at(i) == _m)
|
||||
{
|
||||
if(i+1 < meshList.size())
|
||||
return meshList.at(i+1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/// methods to access the set of Meshes in a ordered fashion.
|
||||
RasterModel *nextRaster(RasterModel *_rm = NULL) {
|
||||
for (int i = 0; i < rasterList.size(); ++i) {
|
||||
if (rasterList.at(i) == _rm)
|
||||
{
|
||||
if(i+1 < rasterList.size())
|
||||
return rasterList.at(i+1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
MeshModel* mm() {
|
||||
return currentMesh;
|
||||
}
|
||||
|
||||
const MeshModel* mm() const {
|
||||
return currentMesh;
|
||||
}
|
||||
|
||||
//Could return 0 if no raster has been selected
|
||||
RasterModel *rm(){
|
||||
return currentRaster;
|
||||
}
|
||||
|
||||
/// The very important member:
|
||||
/// The list of MeshModels.
|
||||
QList<MeshModel *> meshList;
|
||||
/// The list of the raster models of the project
|
||||
QList<RasterModel *> rasterList;
|
||||
int newMeshId() {return meshIdCounter++;}
|
||||
int newRasterId() {return rasterIdCounter++;}
|
||||
|
||||
//functions to update the document entities (meshes and/or rasters) during the filters execution
|
||||
//WARNING! please note that if you have to update both meshes and rasters calling updateRenderState function it's far more efficient
|
||||
//than calling in sequence updateRenderRasterStateMeshes and updateRenderStateRasters. Use them only if you have to update only rasters or only meshes.
|
||||
/*void updateRenderState(const QList<int>& mm,const int meshupdatemask,const QList<int>& rm,const int rasterupdatemask);
|
||||
|
||||
void updateRenderStateMeshes(const QList<int>& mm,const int meshupdatemask);
|
||||
void updateRenderStateRasters(const QList<int>& rm,const int rasterupdatemask);*/
|
||||
void requestUpdatingPerMeshDecorators(int mesh_id);
|
||||
|
||||
private:
|
||||
int meshIdCounter;
|
||||
int rasterIdCounter;
|
||||
|
||||
/**
|
||||
All the files referred in a document are relative to the folder containing the project file.
|
||||
this is the full path to the document.
|
||||
*/
|
||||
QString fullPathFilename;
|
||||
|
||||
//it is the label of the document. it should only be something like Project_n (a temporary name for a new empty document) or the fullPathFilename.
|
||||
QString documentLabel;
|
||||
|
||||
MeshDocumentStateData mdstate;
|
||||
public:
|
||||
|
||||
inline MeshDocumentStateData& meshDocStateData() { return mdstate; }
|
||||
void setDocLabel(const QString& docLb) {documentLabel = docLb;}
|
||||
QString docLabel() const {return documentLabel;}
|
||||
QString pathName() const {QFileInfo fi(fullPathFilename); return fi.absolutePath();}
|
||||
void setFileName(const QString& newFileName) {fullPathFilename = newFileName;}
|
||||
GLLogStream Log;
|
||||
FilterScript filterHistory;
|
||||
QStringList xmlhistory;
|
||||
|
||||
int size() const {return meshList.size();}
|
||||
bool isBusy() { return busy;} // used in processing. To disable access to the mesh by the rendering thread
|
||||
void setBusy(bool _busy)
|
||||
{
|
||||
/*if(busy && _busy==false)
|
||||
{
|
||||
emit meshDocumentModified();
|
||||
}*/
|
||||
busy=_busy;
|
||||
}
|
||||
|
||||
private:
|
||||
bool busy;
|
||||
|
||||
public:
|
||||
///add a new mesh with the given name
|
||||
MeshModel *addNewMesh(QString fullPath, QString Label, bool setAsCurrent=true);
|
||||
MeshModel *addOrGetMesh(QString fullPath, const QString& Label, bool setAsCurrent=true);
|
||||
|
||||
|
||||
///remove the mesh from the list and delete it from memory
|
||||
bool delMesh(MeshModel *mmToDel);
|
||||
|
||||
///add a new raster model
|
||||
RasterModel *addNewRaster(/*QString rasterName*/);
|
||||
|
||||
///remove the raster from the list and delete it from memory
|
||||
bool delRaster(RasterModel *rasterToDel);
|
||||
|
||||
int vn() /// Sum of all the vertices of all the meshes
|
||||
{
|
||||
int tot=0;
|
||||
foreach(MeshModel *mmp, meshList)
|
||||
tot+= mmp->cm.vn;
|
||||
return tot;
|
||||
}
|
||||
int fn() {
|
||||
int tot=0;
|
||||
foreach(MeshModel *mmp, meshList)
|
||||
tot+= mmp->cm.fn;
|
||||
return tot;
|
||||
}
|
||||
|
||||
Box3m bbox()
|
||||
{
|
||||
Box3m FullBBox;
|
||||
foreach(MeshModel * mp, meshList)
|
||||
FullBBox.Add(mp->cm.Tr,mp->cm.bbox);
|
||||
return FullBBox;
|
||||
}
|
||||
|
||||
bool hasBeenModified();
|
||||
|
||||
private:
|
||||
MeshModel *currentMesh;
|
||||
//the current raster model
|
||||
RasterModel* currentRaster;
|
||||
|
||||
signals:
|
||||
///whenever the current mesh is changed (e.g. the user click on a different mesh)
|
||||
// this signal will send out with the index of the newest mesh
|
||||
void currentMeshChanged(int index);
|
||||
|
||||
/// whenever the document (or even a single mesh) is modified by a filter
|
||||
void meshDocumentModified();
|
||||
|
||||
///whenever the meshList is changed
|
||||
void meshSetChanged();
|
||||
|
||||
void meshAdded(int index);
|
||||
void meshRemoved(int index);
|
||||
|
||||
///whenever the rasterList is changed
|
||||
void rasterSetChanged();
|
||||
|
||||
//this signal is emitted when a filter request to update the mesh in the renderingState
|
||||
void documentUpdated();
|
||||
void updateDecorators(int mesh_id);
|
||||
|
||||
};// end class MeshDocument
|
||||
|
||||
|
||||
|
||||
#endif // MESHDOCUMENT_H
|
||||
#endif // MESH_DOCUMENT_H
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include <QFileInfo>
|
||||
|
||||
#include "mesh_model.h"
|
||||
#include "mesh_document.h"
|
||||
|
||||
#include <wrap/gl/math.h>
|
||||
|
||||
@ -35,348 +36,6 @@
|
||||
|
||||
using namespace vcg;
|
||||
|
||||
MeshDocument::MeshDocument()
|
||||
{
|
||||
meshIdCounter=0;
|
||||
rasterIdCounter=0;
|
||||
currentMesh = nullptr;
|
||||
currentRaster = nullptr;
|
||||
busy=false;
|
||||
}
|
||||
|
||||
//deletes each meshModel
|
||||
MeshDocument::~MeshDocument()
|
||||
{
|
||||
foreach(MeshModel *mmp, meshList)
|
||||
delete mmp;
|
||||
foreach(RasterModel* rmp,rasterList)
|
||||
delete rmp;
|
||||
}
|
||||
|
||||
void MeshDocument::clear()
|
||||
{
|
||||
for(MeshModel *mmp : meshList)
|
||||
delete mmp;
|
||||
meshList.clear();
|
||||
|
||||
for(RasterModel* rmp :rasterList)
|
||||
delete rmp;
|
||||
rasterList.clear();
|
||||
|
||||
meshIdCounter=0;
|
||||
rasterIdCounter=0;
|
||||
currentMesh = nullptr;
|
||||
currentRaster = nullptr;
|
||||
busy=false;
|
||||
filterHistory.clear();
|
||||
fullPathFilename = "";
|
||||
documentLabel = "";
|
||||
meshDocStateData().clear();
|
||||
}
|
||||
|
||||
const MeshModel* MeshDocument::getMesh(int id) const
|
||||
{
|
||||
for (const MeshModel* m : meshList)
|
||||
if (m->id() == id)
|
||||
return m;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//returns the mesh ata given position in the list
|
||||
MeshModel* MeshDocument::getMesh(int id)
|
||||
{
|
||||
for (MeshModel* m : meshList)
|
||||
if (m->id() == id)
|
||||
return m;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const MeshModel* MeshDocument::getMesh(const QString& name) const
|
||||
{
|
||||
for (const MeshModel* m : meshList)
|
||||
if (m->shortName() == name)
|
||||
return m;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MeshModel* MeshDocument::getMesh(const QString& name)
|
||||
{
|
||||
for (MeshModel* m : meshList)
|
||||
if (m->shortName() == name)
|
||||
return m;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const MeshModel* MeshDocument::getMeshByFullName(const QString& pathName) const
|
||||
{
|
||||
for (const MeshModel* m : meshList)
|
||||
if (m->fullName() == pathName)
|
||||
return m;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MeshModel* MeshDocument::getMeshByFullName(const QString& pathName)
|
||||
{
|
||||
for (MeshModel* m : meshList)
|
||||
if (m->fullName() == pathName)
|
||||
return m;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void MeshDocument::setCurrentMesh(int new_curr_id)
|
||||
{
|
||||
if(new_curr_id<0)
|
||||
{
|
||||
currentMesh=0;
|
||||
return;
|
||||
}
|
||||
currentMesh = getMesh(new_curr_id);
|
||||
emit currentMeshChanged(new_curr_id);
|
||||
assert(currentMesh);
|
||||
}
|
||||
|
||||
//returns the raster at a given position in the list
|
||||
RasterModel *MeshDocument::getRaster(int i)
|
||||
{
|
||||
foreach(RasterModel *rmp, rasterList)
|
||||
{
|
||||
if(rmp->id() == i) return rmp;
|
||||
}
|
||||
//assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//if i is <0 it means that no currentRaster is set
|
||||
void MeshDocument::setCurrentRaster( int new_curr_id)
|
||||
{
|
||||
if(new_curr_id<0)
|
||||
{
|
||||
currentRaster=0;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(RasterModel *rmp, rasterList)
|
||||
{
|
||||
if(rmp->id() == new_curr_id)
|
||||
{
|
||||
currentRaster = rmp;
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void MeshDocument::requestUpdatingPerMeshDecorators(int mesh_id)
|
||||
{
|
||||
emit updateDecorators(mesh_id);
|
||||
}
|
||||
|
||||
template <class LayerElement>
|
||||
QString NameDisambiguator(QList<LayerElement*> &elemList, QString meshLabel )
|
||||
{
|
||||
QString newName=std::move(meshLabel);
|
||||
typename QList<LayerElement*>::iterator mmi;
|
||||
|
||||
for(mmi=elemList.begin(); mmi!=elemList.end(); ++mmi)
|
||||
{
|
||||
if((*mmi)->label() == newName) // if duplicated name found
|
||||
{
|
||||
QFileInfo fi((*mmi)->label());
|
||||
QString baseName = fi.baseName(); // all characters in the file up to the first '.' Eg "/tmp/archive.tar.gz" -> "archive"
|
||||
QString suffix = fi.suffix();
|
||||
bool ok;
|
||||
|
||||
// if name ends with a number between parenthesis (XXX),
|
||||
// it was himself a duplicated name, and we need to
|
||||
// just increase the number between parenthesis
|
||||
int numDisamb;
|
||||
int startDisamb;
|
||||
int endDisamb;
|
||||
|
||||
startDisamb = baseName.lastIndexOf("(");
|
||||
endDisamb = baseName.lastIndexOf(")");
|
||||
if((startDisamb!=-1)&&(endDisamb!=-1))
|
||||
numDisamb = (baseName.mid((startDisamb+1),(endDisamb-startDisamb-1))).toInt(&ok);
|
||||
else
|
||||
numDisamb = 0;
|
||||
|
||||
if(startDisamb!=-1)
|
||||
newName = baseName.left(startDisamb)+ "(" + QString::number(numDisamb+1) + ")";
|
||||
else
|
||||
newName = baseName + "(" + QString::number(numDisamb+1) + ")";
|
||||
|
||||
if (suffix != QString(""))
|
||||
newName = newName + "." + suffix;
|
||||
|
||||
// now recurse to see if the new name is free
|
||||
newName = NameDisambiguator(elemList, newName);
|
||||
}
|
||||
}
|
||||
return newName;
|
||||
}
|
||||
|
||||
|
||||
MeshModel * MeshDocument::addNewMesh(QString fullPath, QString label, bool setAsCurrent)
|
||||
{
|
||||
QString newlabel = NameDisambiguator(this->meshList,std::move(label));
|
||||
|
||||
if(!fullPath.isEmpty())
|
||||
{
|
||||
QFileInfo fi(fullPath);
|
||||
fullPath = fi.absoluteFilePath();
|
||||
}
|
||||
|
||||
MeshModel *newMesh = new MeshModel(this,fullPath,newlabel);
|
||||
meshList.push_back(newMesh);
|
||||
|
||||
if(setAsCurrent)
|
||||
this->setCurrentMesh(newMesh->id());
|
||||
|
||||
emit meshSetChanged();
|
||||
emit meshAdded(newMesh->id());
|
||||
return newMesh;
|
||||
}
|
||||
|
||||
MeshModel * MeshDocument::addOrGetMesh(QString fullPath, const QString& label, bool setAsCurrent)
|
||||
{
|
||||
MeshModel *newMesh = getMesh(label);
|
||||
if(newMesh) {
|
||||
if(setAsCurrent)
|
||||
this->setCurrentMesh(newMesh->id());
|
||||
return newMesh;
|
||||
}
|
||||
return addNewMesh(std::move(fullPath),label,setAsCurrent);
|
||||
}
|
||||
|
||||
bool MeshDocument::delMesh(MeshModel *mmToDel)
|
||||
{
|
||||
if(!meshList.removeOne(mmToDel))
|
||||
return false;
|
||||
if((currentMesh == mmToDel) && (!meshList.empty()))
|
||||
setCurrentMesh(this->meshList.at(0)->id());
|
||||
else if (meshList.empty())
|
||||
setCurrentMesh(-1);
|
||||
|
||||
int index = mmToDel->id();
|
||||
delete mmToDel;
|
||||
|
||||
emit meshSetChanged();
|
||||
emit meshRemoved(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
RasterModel * MeshDocument::addNewRaster(/*QString fullPathFilename*/)
|
||||
{
|
||||
QFileInfo info(fullPathFilename);
|
||||
QString newLabel=info.fileName();
|
||||
QString newName = NameDisambiguator(this->rasterList, newLabel);
|
||||
|
||||
RasterModel *newRaster=new RasterModel(this, newLabel);
|
||||
rasterList.push_back(newRaster);
|
||||
|
||||
//Add new plane
|
||||
//Plane *plane = new Plane(newRaster, fullPathFilename, QString());
|
||||
//newRaster->addPlane(plane);
|
||||
|
||||
this->setCurrentRaster(newRaster->id());
|
||||
|
||||
emit rasterSetChanged();
|
||||
return newRaster;
|
||||
}
|
||||
|
||||
bool MeshDocument::delRaster(RasterModel *rasterToDel)
|
||||
{
|
||||
QMutableListIterator<RasterModel *> i(rasterList);
|
||||
|
||||
while (i.hasNext())
|
||||
{
|
||||
RasterModel *r = i.next();
|
||||
|
||||
if (r==rasterToDel)
|
||||
{
|
||||
i.remove();
|
||||
delete rasterToDel;
|
||||
}
|
||||
}
|
||||
|
||||
if(currentRaster == rasterToDel)
|
||||
{
|
||||
if (!rasterList.empty())
|
||||
setCurrentRaster(rasterList.at(0)->id());
|
||||
else
|
||||
setCurrentRaster(-1);
|
||||
}
|
||||
emit rasterSetChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MeshDocument::hasBeenModified()
|
||||
{
|
||||
foreach(MeshModel *m, meshList)
|
||||
if(m->meshModified()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//void MeshDocument::updateRenderStateMeshes(const QList<int>& mm,const int meshupdatemask)
|
||||
//{
|
||||
// static QTime currTime = QTime::currentTime();
|
||||
// if(currTime.elapsed()< 100)
|
||||
// return;
|
||||
// for (QList<int>::const_iterator mit = mm.begin();mit != mm.end();++mit)
|
||||
// {
|
||||
// MeshModel* mesh = getMesh(*mit);
|
||||
// if (mesh != NULL)
|
||||
// mesh->bor.update(mesh->cm,meshupdatemask);
|
||||
// }
|
||||
// if ((mm.size() > 0) && (meshupdatemask != MeshModel::MM_NONE))
|
||||
// emit documentUpdated();
|
||||
// currTime.start();
|
||||
//}
|
||||
|
||||
//void MeshDocument::updateRenderStateRasters(const QList<int>& rm,const int rasterupdatemask)
|
||||
//{
|
||||
// static QTime currTime = QTime::currentTime();
|
||||
// if(currTime.elapsed()< 100)
|
||||
// return;
|
||||
// for (QList<int>::const_iterator rit = rm.begin();rit != rm.end();++rit)
|
||||
// {
|
||||
// RasterModel* raster = getRaster(*rit);
|
||||
//
|
||||
// /**********READD*****/
|
||||
// /* if (raster != NULL)
|
||||
// renderState().update(raster->id(),*raster,rasterupdatemask);*/
|
||||
// /********************/
|
||||
// }
|
||||
// if ((rm.size() > 0) && (rasterupdatemask != RasterModel::RM_NONE))
|
||||
// emit documentUpdated();
|
||||
// currTime.start();
|
||||
//}
|
||||
//
|
||||
//void MeshDocument::updateRenderState(const QList<int>& mm,const int meshupdatemask,const QList<int>& rm,const int rasterupdatemask)
|
||||
//{
|
||||
// static QTime currTime = QTime::currentTime();
|
||||
// if(currTime.elapsed()< 100)
|
||||
// return;
|
||||
// /* for (QList<int>::const_iterator mit = mm.begin();mit != mm.end();++mit)
|
||||
// {
|
||||
// MeshModel* mesh = getMesh(*mit);
|
||||
// if (mesh != NULL)
|
||||
// renderState().update(mesh->id(),mesh->cm,meshupdatemask);
|
||||
// }
|
||||
// for (QList<int>::const_iterator rit = rm.begin();rit != rm.end();++rit)
|
||||
// {
|
||||
// RasterModel* raster = getRaster(*rit);
|
||||
// if (raster != NULL)
|
||||
// renderState().update(raster->id(),*raster,rasterupdatemask);
|
||||
// }*/
|
||||
// if (((mm.size() > 0) && (meshupdatemask != MeshModel::MM_NONE)) || (rm.size() > 0 && (rasterupdatemask != RasterModel::RM_NONE)))
|
||||
// emit documentUpdated();
|
||||
// currTime.start();
|
||||
//}
|
||||
|
||||
|
||||
void MeshModel::Clear()
|
||||
{
|
||||
setMeshModified(false);
|
||||
|
||||
@ -472,213 +472,6 @@ private:
|
||||
QMap<int, MeshModelStateData> _existingmeshesbeforeoperation;
|
||||
};
|
||||
|
||||
class MeshDocument : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
MeshDocument();
|
||||
|
||||
//deletes each meshModel
|
||||
~MeshDocument();
|
||||
|
||||
void clear();
|
||||
|
||||
///returns the mesh with the given unique id
|
||||
const MeshModel* getMesh(int id) const;
|
||||
MeshModel *getMesh(int id);
|
||||
const MeshModel *getMesh(const QString& name) const;
|
||||
MeshModel *getMesh(const QString& name);
|
||||
const MeshModel *getMeshByFullName(const QString& pathName) const;
|
||||
MeshModel *getMeshByFullName(const QString& pathName);
|
||||
|
||||
//set the current mesh to be the one with the given ID
|
||||
void setCurrentMesh( int new_curr_id );
|
||||
|
||||
void setVisible(int meshId, bool val);
|
||||
|
||||
/// returns the raster with the given unique id
|
||||
RasterModel *getRaster(int i);
|
||||
|
||||
//set the current raster to be the one with the given ID
|
||||
void setCurrentRaster( int new_curr_id );
|
||||
void setCurrent(MeshModel *newCur) { setCurrentMesh(newCur->id());}
|
||||
void setCurrent(RasterModel *newCur) { setCurrentRaster(newCur->id());}
|
||||
|
||||
/// methods to access the set of Meshes in a ordered fashion.
|
||||
MeshModel *nextVisibleMesh(MeshModel *_m = NULL)
|
||||
{
|
||||
MeshModel *newM = nextMesh(_m);
|
||||
if(newM==0)
|
||||
return newM;
|
||||
|
||||
if(newM->isVisible())
|
||||
return newM;
|
||||
else
|
||||
return nextVisibleMesh(newM);
|
||||
}
|
||||
|
||||
MeshModel *nextMesh(MeshModel *_m = NULL)
|
||||
{
|
||||
if(_m==0 && meshList.size()>0)
|
||||
return meshList.at(0);
|
||||
for (int i = 0; i < meshList.size(); ++i) {
|
||||
if (meshList.at(i) == _m)
|
||||
{
|
||||
if(i+1 < meshList.size())
|
||||
return meshList.at(i+1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/// methods to access the set of Meshes in a ordered fashion.
|
||||
RasterModel *nextRaster(RasterModel *_rm = NULL) {
|
||||
for (int i = 0; i < rasterList.size(); ++i) {
|
||||
if (rasterList.at(i) == _rm)
|
||||
{
|
||||
if(i+1 < rasterList.size())
|
||||
return rasterList.at(i+1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
MeshModel* mm() {
|
||||
return currentMesh;
|
||||
}
|
||||
|
||||
const MeshModel* mm() const {
|
||||
return currentMesh;
|
||||
}
|
||||
|
||||
//Could return 0 if no raster has been selected
|
||||
RasterModel *rm(){
|
||||
return currentRaster;
|
||||
}
|
||||
|
||||
/// The very important member:
|
||||
/// The list of MeshModels.
|
||||
QList<MeshModel *> meshList;
|
||||
/// The list of the raster models of the project
|
||||
QList<RasterModel *> rasterList;
|
||||
int newMeshId() {return meshIdCounter++;}
|
||||
int newRasterId() {return rasterIdCounter++;}
|
||||
|
||||
//functions to update the document entities (meshes and/or rasters) during the filters execution
|
||||
//WARNING! please note that if you have to update both meshes and rasters calling updateRenderState function it's far more efficient
|
||||
//than calling in sequence updateRenderRasterStateMeshes and updateRenderStateRasters. Use them only if you have to update only rasters or only meshes.
|
||||
/*void updateRenderState(const QList<int>& mm,const int meshupdatemask,const QList<int>& rm,const int rasterupdatemask);
|
||||
|
||||
void updateRenderStateMeshes(const QList<int>& mm,const int meshupdatemask);
|
||||
void updateRenderStateRasters(const QList<int>& rm,const int rasterupdatemask);*/
|
||||
void requestUpdatingPerMeshDecorators(int mesh_id);
|
||||
|
||||
private:
|
||||
int meshIdCounter;
|
||||
int rasterIdCounter;
|
||||
|
||||
/**
|
||||
All the files referred in a document are relative to the folder containing the project file.
|
||||
this is the full path to the document.
|
||||
*/
|
||||
QString fullPathFilename;
|
||||
|
||||
//it is the label of the document. it should only be something like Project_n (a temporary name for a new empty document) or the fullPathFilename.
|
||||
QString documentLabel;
|
||||
|
||||
MeshDocumentStateData mdstate;
|
||||
public:
|
||||
|
||||
inline MeshDocumentStateData& meshDocStateData() { return mdstate; }
|
||||
void setDocLabel(const QString& docLb) {documentLabel = docLb;}
|
||||
QString docLabel() const {return documentLabel;}
|
||||
QString pathName() const {QFileInfo fi(fullPathFilename); return fi.absolutePath();}
|
||||
void setFileName(const QString& newFileName) {fullPathFilename = newFileName;}
|
||||
GLLogStream Log;
|
||||
FilterScript filterHistory;
|
||||
QStringList xmlhistory;
|
||||
|
||||
int size() const {return meshList.size();}
|
||||
bool isBusy() { return busy;} // used in processing. To disable access to the mesh by the rendering thread
|
||||
void setBusy(bool _busy)
|
||||
{
|
||||
/*if(busy && _busy==false)
|
||||
{
|
||||
emit meshDocumentModified();
|
||||
}*/
|
||||
busy=_busy;
|
||||
}
|
||||
|
||||
private:
|
||||
bool busy;
|
||||
|
||||
public:
|
||||
///add a new mesh with the given name
|
||||
MeshModel *addNewMesh(QString fullPath, QString Label, bool setAsCurrent=true);
|
||||
MeshModel *addOrGetMesh(QString fullPath, const QString& Label, bool setAsCurrent=true);
|
||||
|
||||
|
||||
///remove the mesh from the list and delete it from memory
|
||||
bool delMesh(MeshModel *mmToDel);
|
||||
|
||||
///add a new raster model
|
||||
RasterModel *addNewRaster(/*QString rasterName*/);
|
||||
|
||||
///remove the raster from the list and delete it from memory
|
||||
bool delRaster(RasterModel *rasterToDel);
|
||||
|
||||
int vn() /// Sum of all the vertices of all the meshes
|
||||
{
|
||||
int tot=0;
|
||||
foreach(MeshModel *mmp, meshList)
|
||||
tot+= mmp->cm.vn;
|
||||
return tot;
|
||||
}
|
||||
int fn() {
|
||||
int tot=0;
|
||||
foreach(MeshModel *mmp, meshList)
|
||||
tot+= mmp->cm.fn;
|
||||
return tot;
|
||||
}
|
||||
|
||||
Box3m bbox()
|
||||
{
|
||||
Box3m FullBBox;
|
||||
foreach(MeshModel * mp, meshList)
|
||||
FullBBox.Add(mp->cm.Tr,mp->cm.bbox);
|
||||
return FullBBox;
|
||||
}
|
||||
|
||||
bool hasBeenModified();
|
||||
|
||||
private:
|
||||
MeshModel *currentMesh;
|
||||
//the current raster model
|
||||
RasterModel* currentRaster;
|
||||
|
||||
signals:
|
||||
///whenever the current mesh is changed (e.g. the user click on a different mesh)
|
||||
// this signal will send out with the index of the newest mesh
|
||||
void currentMeshChanged(int index);
|
||||
|
||||
/// whenever the document (or even a single mesh) is modified by a filter
|
||||
void meshDocumentModified();
|
||||
|
||||
///whenever the meshList is changed
|
||||
void meshSetChanged();
|
||||
|
||||
void meshAdded(int index);
|
||||
void meshRemoved(int index);
|
||||
|
||||
///whenever the rasterList is changed
|
||||
void rasterSetChanged();
|
||||
|
||||
//this signal is emitted when a filter request to update the mesh in the renderingState
|
||||
void documentUpdated();
|
||||
void updateDecorators(int mesh_id);
|
||||
|
||||
};// end class MeshDocument
|
||||
|
||||
/*
|
||||
A class designed to save partial aspects of the state of a mesh, such as vertex colors, current selections, vertex positions
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#include <QMessageBox>
|
||||
#include <QtXml>
|
||||
|
||||
#include "mesh_data_structures/mesh_model.h"
|
||||
#include "mesh_data_structures/mesh_document.h"
|
||||
#include<QImageReader>
|
||||
#include "meshlabdocumentbundler.h"
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <QDomDocument>
|
||||
|
||||
#include "ml_shared_data_context.h"
|
||||
#include "mesh_data_structures/mesh_model.h"
|
||||
#include "mesh_data_structures/mesh_document.h"
|
||||
#include<map>
|
||||
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <vector>
|
||||
#include <QThread>
|
||||
|
||||
#include "mesh_data_structures/mesh_model.h"
|
||||
#include "mesh_data_structures/mesh_document.h"
|
||||
|
||||
MLSceneGLSharedDataContext::MLSceneGLSharedDataContext(MeshDocument& md,vcg::QtThreadSafeMemoryInfo& gpumeminfo,bool highprecision,size_t perbatchtriangles, size_t minfacespersmoothrendering)
|
||||
:QGLWidget(),_md(md),_gpumeminfo(gpumeminfo),_perbatchtriangles(perbatchtriangles), _minfacessmoothrendering(minfacespersmoothrendering),_highprecision(highprecision)
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
#include <QSplitter>
|
||||
#include <QSplitterHandle>
|
||||
|
||||
#include <common/mesh_data_structures/mesh_model.h>
|
||||
#include <common/mesh_data_structures/mesh_document.h>
|
||||
#include <common/ml_shared_data_context.h>
|
||||
|
||||
// Class list
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
#include <QClipboard>
|
||||
#include <QFileDialog>
|
||||
#include <QApplication>
|
||||
#include <common/mesh_data_structures/mesh_model.h>
|
||||
#include <common/mesh_data_structures/mesh_document.h>
|
||||
|
||||
/******************************************/
|
||||
// MeshLabWidget Implementation
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QFile>
|
||||
#include <common/mesh_data_structures/mesh_model.h>
|
||||
#include <common/mesh_data_structures/mesh_document.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace vcg;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user