1 /****************************************************************************
2 * MeshLab                                                           o o     *
3 * A versatile mesh processing toolbox                             o     o   *
4 *                                                                _   O  _   *
5 * Copyright(C) 2005-2008                                           \/)\/    *
6 * Visual Computing Lab                                            /\/|      *
7 * ISTI - Italian National Research Council                           |      *
8 *                                                                    \      *
9 * All rights reserved.                                                      *
10 *                                                                           *
11 * This program is free software; you can redistribute it and/or modify      *
12 * it under the terms of the GNU General Public License as published by      *
13 * the Free Software Foundation; either version 2 of the License, or         *
14 * (at your option) any later version.                                       *
15 *                                                                           *
16 * This program is distributed in the hope that it will be useful,           *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
20 * for more details.                                                         *
21 *                                                                           *
22 ****************************************************************************/
23 
24 #ifndef MESHLAB_INTERFACES_H
25 #define MESHLAB_INTERFACES_H
26 //#include <GL/glew.h>
27 
28 #include "filterparameter.h"
29 #include "GLLogStream.h"
30 //#include "meshmodel.h"
31 #include "scriptinterface.h"
32 #include "xmlfilterinfo.h"
33 
34 #include <QtCore>
35 #include <QApplication>
36 #include <QAction>
37 #include <QGLContext>
38 #include <QGLFormat>
39 #include <QMessageBox>
40 #include <QTabletEvent>
41 #include <QDebug>
42 
43 
44 class QWidget;
45 class QGLWidget;
46 class QString;
47 class QVariant;
48 class QMouseEvent;
49 class QTreeWidgetItem;
50 class MeshModel;
51 class RenderMode;
52 class GLArea;
53 class GLAreaReg;
54 class QScriptEngine;
55 
56 class MeshModel;
57 
58 /** The MainWindowInterface class defines just the executeFilter() callback function
59 that is invoked by the standard parameter input dialog.
60 It is used as base class of the MainWindow.
61 */
62 class MainWindowInterface
63 {
64 public:
65 	virtual void executeFilter(QAction *, RichParameterSet &, bool = false) {}
66 	//parexpval is a string map containing the parameter expression values set in the filter's dialog.
67 	//These parameter expression values will be evaluated when the filter will start.
68 	virtual void executeFilter(MeshLabXMLFilterContainer*, const QMap<QString, QString>&, bool = false) {}
69 	//virtual void executeFilter(MeshLabXMLFilterContainer*,Env& envcode , bool  isPreview = false) {}
70 
71 	//virtual void getCurrentPersistentParsMap(QMap<QString, QString>&) const {}
72 };
73 
74 /** \brief The MeshLabInterface class is the base of all the plugin interfaces.
75 
76 The main idea common to all the framework is that each plugin export a set of actions,
77 internally each action is associated to a FilterIDType, and for each action a name and a formatted INFO is defined.
78 
79 For coding easyness ID are more practical (you can use them in switches).
80 Using action on the other hand is practical because it simplify their management in menus/toolbars and it allows to define icons and other things in a automatic way.
81 Moreover ID are UNSAFE (different plugin can have same id) so they should be used only INTERNALLY
82 
83 \todo There is inconsistency in the usage of ID and actions for retrieving particular filters. Remove.
84 
85 */
86 class MeshLabInterface
87 {
88 public:
89 	/** the type used to identify plugin actions; there is a one-to-one relation between an ID and an Action.
90 	\todo To be renamed as ActionIDType
91 	*/
92 
MeshLabInterface()93 	MeshLabInterface() :log(0) {}
~MeshLabInterface()94 	virtual ~MeshLabInterface() {}
95 private:
96 	GLLogStream *log;
97 public:
98 
99 	/// Standard stuff that usually should not be redefined.
setLog(GLLogStream * log)100 	void setLog(GLLogStream *log) { this->log = log; }
101 
102 	// This function must be used to communicate useful information collected in the parsing/saving of the files.
103 	// NEVER EVER use a msgbox to say something to the user.
104 	template <typename... Ts>
Log(const char * f,Ts &&...ts)105 	void Log(const char * f, Ts&&... ts )
106 	{
107 		if(log != nullptr)
108 		{
109 			log->Logf(GLLogStream::FILTER, f, std::forward<Ts>(ts)...);
110 		}
111 	}
112 
Log(const char * s)113 	void Log(const char * s)
114 	{
115 		if(log != nullptr)
116 		{
117 			log->Log(GLLogStream::FILTER, s);
118 		}
119 	}
120 
Log(const std::string & s)121 	void Log(const std::string& s)
122 	{
123 		if(log != nullptr)
124 		{
125 			log->Log(GLLogStream::FILTER, s);
126 		}
127 	}
128 
129 	template <typename... Ts>
Log(GLLogStream::Levels Level,const char * f,Ts &&...ts)130 	void Log(GLLogStream::Levels Level, const char * f, Ts&&... ts )
131 	{
132 		if(log != nullptr)
133 		{
134 			log->Logf(Level, f, std::forward<Ts>(ts)...);
135 		}
136 	}
137 
Log(GLLogStream::Levels level,const char * s)138 	void Log(GLLogStream::Levels level, const char * s)
139 	{
140 		if(log != nullptr)
141 		{
142 			log->Log(level, s);
143 		}
144 	}
145 
Log(GLLogStream::Levels level,const std::string & s)146 	void Log(GLLogStream::Levels  level, const std::string& s)
147 	{
148 		if(log != nullptr)
149 		{
150 			log->Log(level, s);
151 		}
152 	}
153 
RealTimeLog(QString Id,const QString & meshName,const char * f)154 	void RealTimeLog(QString Id, const QString &meshName, const char * f)
155 	{
156 		if(log != nullptr)
157 		{
158 			log->RealTimeLog(Id, meshName, f);
159 		}
160 	}
161 
162 	template <typename... Ts>
RealTimeLog(QString Id,const QString & meshName,const char * f,Ts &&...ts)163 	void RealTimeLog(QString Id, const QString &meshName, const char * f, Ts&&... ts )
164 	{
165 		if(log != nullptr)
166 		{
167 			log->RealTimeLogf(Id, meshName, f, std::forward<Ts>(ts)...);
168 		}
169 	}
170 };
171 
172 class MeshCommonInterface : public MeshLabInterface
173 {
174 public:
175 	typedef int FilterIDType;
MeshCommonInterface()176 	MeshCommonInterface() {}
~MeshCommonInterface()177 	virtual ~MeshCommonInterface() {}
178 
pluginName(void)179 	virtual QString pluginName(void) const { return ""; }
180 
181 	/** \brief This function is called by the framework, for each plugin that has global parameters (e.g. \ref MeshDecorateInterface) at the start of the application.
182 	The rationale is to allow to each plugin to have a list of global persistent parameters that can be changed from the meshlab itself and whose value is persistent between different meshlab invocations.
183 	A typical example is the background color.
184 
185 	For the global parameters the following rules apply:
186 
187 	\li there is a <b>hardwired</b> default value: a safe consistent value that is directly coded into the plugin and to which the user can always revert if needed.
188 	\li there is a <b>saved</b> value: a value that is stored into a persistent location into the user space (registry/home/library) and it is presented as default value of the parameter at each MeshLab invocation.
189 	\li there is a <b>current</b> value: a value that is currently used, different for each document instance and that is not stored permanently.
190 
191 	The plugin use the current value to draw its decoration.
192 	at startup the current value is always silently initialized to the saved value.
193 	User can revert current value to the saved values and to the hardwired values.
194 	In the dialog for each parameter some buttons should be present:
195 
196 	\li apply: use the currently edited parameter value without saving it anywhere. After the closure of the document these values will be lost.
197 	\li load:  load from the saved values
198 	\li save:  save to a permanent location the current value (to the registry),
199 	\li reset:  revert to the hardwired values
200 
201 	If your plugins/action has no GlobalParameter, do nothing.
202 	The RichParameterSet comes to the StartDecorate already initialized with the values stored on the permanent storage.
203 	At the start up the initGlobalParameterSet function is called with an empty RichParameterSet (to collect the default values)
204 	If a filter wants to save some permanent stuff should set the permanent default values.
205 	*/
initGlobalParameterSet(QAction *,RichParameterSet &)206 	virtual void initGlobalParameterSet(QAction * /*format*/, RichParameterSet & /*globalparam*/) {}
207 };
208 /** \brief The MeshIOInterface is the base class for all the single mesh loading plugins.
209 */
210 class MeshIOInterface : public MeshCommonInterface
211 {
212 public:
213 	class Format
214 	{
215 	public:
Format(QString description,QString ex)216 		Format(QString description, QString ex) : description(description) { extensions << ex; }
217 		QString description;
218 		QStringList extensions;
219 	};
220 
MeshIOInterface()221 	MeshIOInterface() : MeshCommonInterface() {  }
~MeshIOInterface()222 	virtual ~MeshIOInterface() {}
223 
224 	virtual QList<Format> importFormats() const = 0;
225 	virtual QList<Format> exportFormats() const = 0;
226 
227 	// This function is called to initialize the list of additional parameters that a OPENING filter could require
228 	// it is called by the framework BEFORE the actual mesh loading to perform to determine how parse the input file
229 	// The instanced parameters are then passed to the open at the loading time.
230 	// Typical example of use to decide what subportion of a mesh you have to load.
231 	// If you do not need any additional processing simply do not override this and ignore the parameterSet in the open
initPreOpenParameter(const QString &,const QString &,RichParameterSet &)232 	virtual void initPreOpenParameter(const QString &/*format*/, const QString &/*fileName*/, RichParameterSet & /*par*/) {}
233 
234 	// This function is called to initialize the list of additional parameters that a OPENING filter could require
235 	// it is called by the framework AFTER the mesh is already loaded to perform more or less standard processing on the mesh.
236 	// typical example: unifying vertices in stl models.
237 	// If you do not need any additional processing do nothing.
initOpenParameter(const QString &,MeshModel &,RichParameterSet &)238 	virtual void initOpenParameter(const QString &/*format*/, MeshModel &/*m*/, RichParameterSet & /*par*/) {}
239 
240 	// This is the corresponding function that is called after the mesh is loaded with the initialized parameters
applyOpenParameter(const QString &,MeshModel &,const RichParameterSet &)241 	virtual void applyOpenParameter(const QString &/*format*/, MeshModel &/*m*/, const RichParameterSet &/*par*/) {}
242 
243 	// This function is called to initialize the list of additional parameters that a SAVING filter could require
244 	// it is called by the framework after the mesh is loaded to perform more or less standard processing on the mesh.
245 	// typical example: ascii or binary format for ply or stl
246 	// If you do not need any additional parameter simply do nothing.
initSaveParameter(const QString &,MeshModel &,RichParameterSet &)247 	virtual void initSaveParameter(const QString &/*format*/, MeshModel &/*m*/, RichParameterSet & /*par*/) {}
248 
249 
250 	virtual void GetExportMaskCapability(QString &format, int &capability, int &defaultBits) const = 0;
251 
252 	/// callback used to actually load a mesh from a file
253 	virtual bool open(
254 		const QString &format,					/// the extension of the format e.g. "PLY"
255 		const QString &fileName,				/// The name of the file to be opened
256 		MeshModel &m,										/// The mesh that is filled with the file content
257 		int &mask,											/// a bit mask that will be filled reporting what kind of data we have found in the file (per vertex color, texture coords etc)
258 		const RichParameterSet & par,	/// The parameters that have been set up in the initPreOpenParameter()
259 		vcg::CallBackPos *cb = 0,					/// standard callback for reporting progress in the loading
260 		QWidget *parent = 0) = 0;						/// you should not use this...
261 
262 	virtual bool save(
263 		const QString &format, // the extension of the format e.g. "PLY"
264 		const QString &fileName,
265 		MeshModel &m,
266 		const int mask,       // a bit mask indicating what kind of the data present in the mesh should be saved (e.g. you could not want to save normals in ply files)
267 		const RichParameterSet & par,
268 		vcg::CallBackPos *cb = 0,
269 		QWidget *parent = 0) = 0;
270 
271 	/// This function is invoked by the framework when the import/export plugin fails to give some info to the user about the failure
272 	/// io plugins should avoid using QMessageBox for reporting errors.
273 	/// Failure should put some meaningful information inside the errorMessage string.
errorMsg()274 	virtual QString &errorMsg() { return this->errorMessage; }
clearErrorString()275 	void clearErrorString() { errorMessage.clear(); }
276 
277 	// this string is used to pass back to the framework error messages in case of failure of a filter apply.
278 	// NEVER EVER use a msgbox to say something to the user.
279 	QString errorMessage;
280 
281 };
282 
283 /**
284 \brief The MeshFilterInterface class provide the interface of the filter plugins.
285 
286 */
287 class MeshFilterInterface : public MeshCommonInterface
288 {
289 public:
290 	/** The FilterClass enum represents the set of keywords that must be used to categorize a filter.
291 	Each filter can belong to one or more filtering class, or-ed together.
292 	*/
293 	enum FilterClass
294 	{
295 		Generic        = 0x00000, /*!< Should be avoided if possible. */  //
296 		Selection      = 0x00001, /*!<  select or de-select something, basic operation on selections (like deleting)*/
297 		Cleaning       = 0x00002, /*!<  Filters that can be used to clean meshes (duplicated vertices etc)*/
298 		Remeshing      = 0x00004, /*!<  Simplification, Refinement, Reconstruction and mesh optimization*/
299 		FaceColoring   = 0x00008,
300 		VertexColoring = 0x00010,
301 		MeshColoring   = 0x00020,
302 		MeshCreation   = 0x00040,
303 		Smoothing      = 0x00080, /*!<  Stuff that does not change the topology, but just the vertex positions*/
304 		Quality        = 0x00100,
305 		Layer          = 0x00200, /*!<  Layers, attributes */
306 		RasterLayer    = 0x00400, /*!<  Raster Layers, attributes */
307 		Normal         = 0x00800, /*!<  Normal, Curvature, orientation (rotations and transformations fall here)*/
308 		Sampling       = 0x01000,
309 		Texture        = 0x02000,
310 		RangeMap       = 0x04000, /*!<  filters specific for range map processing*/
311 		PointSet       = 0x08000,
312 		Measure        = 0x10000, /*!<  Filters that compute measures and information on meshes.*/
313 		Polygonal      = 0x20000, /*!<  Filters that works on polygonal and quad meshes.*/
314 		Camera         = 0x40000  /*!<  Filters that works on shot of mesh and raster.*/
315 	};
316 
317 
318 
MeshFilterInterface()319 	MeshFilterInterface() : MeshCommonInterface(), glContext(NULL)
320 	{
321 	}
~MeshFilterInterface()322 	virtual ~MeshFilterInterface() {}
323 
324 
325 	/** The very short string (a few words) describing each filtering action
326 	// This string is used also to define the menu entry
327 	*/
328 	virtual QString filterName(FilterIDType) const = 0;
329 
330 	/** The long, formatted string describing each filtering action.
331 	// This string is printed in the top of the parameter window
332 	// so it should be at least one or two paragraphs long. The more the better.
333 	// you can use simple html formatting tags (like "<br>" "<b>" and "<i>") to improve readability.
334 	// This string is used in the 'About plugin' dialog and by meshlabserver to create the filter list wiki page and the doxygen documentation of the filters.
335 	// Here is the place where you should put you bibliographic references in a form like this:
336 	<br>
337 	See: <br />
338 	<i>Luiz Velho, Denis Zorin </i><br/>
339 	<b>"4-8 Subdivision"</b><br/>
340 	CAGD, volume 18, Issue 5, Pages 397-427.<br/>
341 	<br>
342 	e.g. italic for authors, bold for title (quoted) and plain for bib ref.
343 	*/
344 	virtual QString filterInfo(FilterIDType filter) const = 0;
345 
346 	/** The FilterClass describes in which generic class of filters it fits.
347 	// This choice affect the submenu in which each filter will be placed
348 	// For example filters that perform an action only on the selection will be placed in the Selection Class
349 	*/
getClass(QAction *)350 	virtual FilterClass getClass(QAction *) { return MeshFilterInterface::Generic; }
351 
352 	/**
353 	The filters can have some additional requirements on the mesh capabiliteis.
354 	// For example if a filters requires Face-Face Adjacency you should re-implement
355 	// this function making it returns MeshModel::MM_FACEFACETOPO.
356 	// The framework will ensure that the mesh has the requirements satisfied before invoking the applyFilter function
357 	//
358 	// Furthermore, requirements are checked just before the invocation of a filter. If your filter
359 	// outputs a never used before mesh property (e.g. face colors), it will be allocated by a call
360 	// to MeshModel::updateDataMask(...)
361 	*/
getRequirements(QAction *)362 	virtual int getRequirements(QAction *) { return MeshModel::MM_NONE; }
363 
364 	/** The FilterPrecondition mask is used to explicitate what kind of data a filter really needs to be applied.
365 	// For example algorithms that compute per face quality have as precondition the existence of faces
366 	// (but quality per face is not a precondition, because quality per face is created by these algorithms)
367 	// on the other hand an algorithm that deletes faces according to the stored quality has both FaceQuality
368 	// and Face as precondition.
369 	// These conditions do NOT include computed properties like borderFlags, manifoldness or watertightness.
370 	// They are also used to grayout menus un-appliable entries.
371 	*/
getPreConditions(QAction *)372 	virtual int getPreConditions(QAction *) const { return MeshModel::MM_NONE; }
373 
374 	/** Function used by the framework to get info about the mesh properties changed by the filter.
375 	// It is widely used by the meshlab's preview system.
376 	//TO BE REPLACED WITH = 0
377 	*/
postCondition(QAction *)378 	virtual int postCondition(QAction*) const { return MeshModel::MM_ALL; }
379 
380 	/** \brief applies the selected filter with the already stabilished parameters
381 	* This function is called by the framework after getting values for the parameters specified in the \ref InitParameterSet
382 	* NO GUI interaction should be done here. No dialog asking, no messagebox errors.
383 	* Think that his function will also be called by the commandline framework.
384 	* If you want report errors, use the \ref errorMsg() string. It will displayed in case of filters returning false.
385 	* When implementing your applyFilter, you should use the cb function to report to the framework the current state of the processing.
386 	* During your (long) processing you should call from time to time cb(perc,descriptiveString), where perc is an int (0..100)
387 	* saying what you are doing and at what point of the computation you currently are.
388 	* \sa errorMsg
389 	* \sa initParameterSet
390 	*/
391 	virtual bool applyFilter(QAction *   filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos *cb) = 0;
392 
393 	/** \brief tests if a filter is applicable to a mesh.
394 	This function is a handy wrapper used by the framework for the \a getPreConditions callback;
395 	For instance a colorize by quality filter cannot be applied to a mesh without per-vertex-quality.
396 	On failure (returning false) the function fills the MissingItems list with strings describing the missing items.
397 	*/
398 	bool isFilterApplicable(QAction *act, const MeshModel& m, QStringList &MissingItems) const;
399 
400 
401 	enum FILTER_ARITY { NONE = 0, SINGLE_MESH = 1, FIXED = 2, VARIABLE = 3, UNKNOWN_ARITY = 4 };
402 
403 	/** \brief this function informs the MeshLab core on how many meshes the filter will work on.
404 	Valid value:
405 	- SINGLE_MESH: the filter works just on the current mesh
406 	- FIXED: the number (and the names) of the meshes involved in the filter computation is determined by the parameters selected in the filter's parameters form
407 	- VARIABLE: the filter works on a not predetermined number of meshes. The meshes involved are typically selected by the user checking on the correspondent layer on the layer dialog
408 	*/
409 	virtual FILTER_ARITY filterArity(QAction *act) const = 0;
410 
411 	// This function is called to initialized the list of parameters.
412 	// it is always called. If a filter does not need parameter it leave it empty and the framework
413 	// will not create a dialog (unless for previewing)
initParameterSet(QAction *,MeshModel &,RichParameterSet &)414 	virtual void initParameterSet(QAction *, MeshModel &/*m*/, RichParameterSet & /*par*/) {}
initParameterSet(QAction * filter,MeshDocument & md,RichParameterSet & par)415 	virtual void initParameterSet(QAction *filter, MeshDocument &md, RichParameterSet &par)
416 	{
417 		initParameterSet(filter, *(md.mm()), par);
418 	}
419 
420 	/** \brief is invoked by the framework when the applyFilter fails to give some info to the user about the filter failure
421 	* Filters \b must never use QMessageBox for reporting errors.
422 	* Failing filters should put some meaningful information inside the errorMessage string and return false with the \ref applyFilter
423 	*/
errorMsg()424 	const QString &errorMsg() { return this->errorMessage; }
filterInfo(QAction * a)425 	virtual QString filterInfo(QAction *a) const { return this->filterInfo(ID(a)); }
filterName(QAction * a)426 	virtual QString filterName(QAction *a) const { return this->filterName(ID(a)); }
filterScriptFunctionName(FilterIDType)427 	virtual QString filterScriptFunctionName(FilterIDType /*filterID*/) { return ""; }
428 
ID(QAction * a)429 	virtual FilterIDType ID(QAction *a) const
430 	{
431 	QString aa=a->text();
432 		foreach(FilterIDType tt, types())
433 			if (a->text() == this->filterName(tt)) return tt;
434 		aa.replace("&","");
435 		foreach(FilterIDType tt, types())
436 			if (aa == this->filterName(tt)) return tt;
437 
438 		qDebug("unable to find the id corresponding to action  '%s'", qUtf8Printable(a->text()));
439 		assert(0);
440 		return -1;
441 	}
442 
AC(FilterIDType filterID)443 	virtual QAction *AC(FilterIDType filterID)
444 	{
445 		QString idName = this->filterName(filterID);
446 		return AC(idName);
447 	}
448 
AC(QString idName)449 	virtual QAction *AC(QString idName)
450 	{
451 	QString i=idName;
452 		foreach(QAction *tt, actionList)
453 			if (idName == tt->text()) return tt;
454 		i.replace("&","");
455 		foreach(QAction *tt, actionList)
456 			if (i == tt->text()) return tt;
457 
458 		qDebug("unable to find the action corresponding to action  '%s'", qUtf8Printable(idName));
459 		assert(0);
460 		return 0;
461 	}
462 
actions()463 	virtual QList<QAction *> actions() const { return actionList; }
types()464 	virtual QList<FilterIDType> types() const { return typeList; }
465 
466 	/** Generate the mask of attributes would be created IF the MeshFilterInterface filt would has been called on MeshModel mm
467 	BE CAREFUL! this function does NOT change in anyway the state of the MeshModel!!!! **/
468 	int previewOnCreatedAttributes(QAction* act, const MeshModel& mm);
469 	QString generatedScriptCode;
470 
471 	MLPluginGLContext* glContext;
472 protected:
473 	// Each plugins exposes a set of filtering possibilities.
474 	// Each filtering procedure corresponds to a single QAction with a corresponding FilterIDType id.
475 	//
476 
477 	// The list of actions exported by the plugin. Each actions strictly corresponds to
478 	QList <QAction *> actionList;
479 
480 	QList <FilterIDType> typeList;
481 
482 	// this string is used to pass back to the framework error messages in case of failure of a filter apply.
483 	QString errorMessage;
484 };
485 
486 
487 /**
488 Used to customized the rendering process.
489 Rendering plugins are now responsible of the rendering of the whole MeshDocument and not only of a single MeshModel.
490 
491 The Render function is called in with the ModelView and Projection Matrices already set up, screen cleared and background drawn.
492 After the Render call the MeshLab frawework draw on the opengl context other decorations and the trackball, so it there is the
493 requirement for a rendering plugin is that it should leave the z-buffer in a coherent state.
494 
495 The typical rendering loop of a Render plugin is something like, :
496 
497 <your own opengl setup>
498 
499 foreach(MeshModel * mp, meshDoc.meshList)
500 {
501 if(mp->visible) mp->Render(rm.drawMode,rm.colorMode,rm.textureMode);
502 }
503 
504 */
505 
506 class MeshRenderInterface : public MeshCommonInterface
507 {
508 public:
MeshRenderInterface()509 	MeshRenderInterface() :MeshCommonInterface() {}
~MeshRenderInterface()510 	virtual ~MeshRenderInterface() {}
511 
Init(QAction *,MeshDocument &,MLSceneGLSharedDataContext::PerMeshRenderingDataMap &,GLArea *)512 	virtual void Init(QAction *, MeshDocument &, MLSceneGLSharedDataContext::PerMeshRenderingDataMap& /*mp*/, GLArea *) {}
513 	virtual void Render(QAction *, MeshDocument &, MLSceneGLSharedDataContext::PerMeshRenderingDataMap& mp, GLArea *) = 0;
Finalize(QAction *,MeshDocument *,GLArea *)514 	virtual void Finalize(QAction *, MeshDocument *, GLArea *) {}
515 	virtual bool isSupported() = 0;
516 	virtual QList<QAction *> actions() = 0;
517 };
518 /**
519 MeshDecorateInterface is the base class of all <b> decorators </b>
520 Decorators are 'read-only' visualization aids that helps to show some data about a document.
521 Decorators can make some permesh precomputation but the rendering has to be efficient.
522 Decorators should save the additional data into per-mesh attribute.
523 
524 
525 There are two classes of Decorations
526 - PerMesh
527 - PerDocument
528 
529 PerMesh Decorators are associated to each mesh/view
530 Some example of PerDocument Decorations
531 - backgrounds
532 - trackball icon
533 - axis
534 - shadows
535 - screen space Ambient occlusion (think it as a generic 'darkner')
536 
537 Some example of PerMesh Decorations
538 - coloring of selected vertex/face
539 - displaying of normals/curvature directions
540 - display of specific tagging
541 */
542 
543 class MeshDecorateInterface : public MeshCommonInterface
544 {
545 public:
546 
547 	/** The DecorationClass enum represents the set of keywords that must be used to categorize a filter.
548 	Each filter can belong to one or more filtering class, or-ed together.
549 	*/
550 	enum DecorationClass
551 	{
552 		Generic = 0x00000, /*!< Should be avoided if possible. */  //
553 		PerMesh = 0x00001, /*!<  Decoration that are applied on a single mesh */
554 		PerDocument = 0x00002, /*!<  Decoration that are applied on a single mesh */
555 		PreRendering = 0x00004, /*!<  Decoration that are applied <i>before</i> the rendering of the document/mesh */
556 		PostRendering = 0x00008  /*!<  Decoration that are applied <i>after</i> the rendering of the document/mesh */
557 	};
558 
MeshDecorateInterface()559 	MeshDecorateInterface() : MeshCommonInterface() {}
~MeshDecorateInterface()560 	virtual ~MeshDecorateInterface() {}
561 	/** The very short string (a few words) describing each filtering action
562 	// This string is used also to define the menu entry
563 	*/
564 	virtual QString decorationName(FilterIDType) const = 0;
565 	virtual QString decorationInfo(FilterIDType) const = 0;
566 
decorationName(QAction * a)567 	virtual QString decorationName(QAction *a) const { return decorationName(ID(a)); }
decorationInfo(QAction * a)568 	virtual QString decorationInfo(QAction *a) const { return decorationInfo(ID(a)); }
569 
570 
startDecorate(QAction *,MeshDocument &,RichParameterSet *,GLArea *)571 	virtual bool startDecorate(QAction *, MeshDocument &, RichParameterSet *, GLArea *) { return false; }
startDecorate(QAction *,MeshModel &,RichParameterSet *,GLArea *)572 	virtual bool startDecorate(QAction *, MeshModel &, RichParameterSet *, GLArea *) { return false; }
573 	virtual void decorateMesh(QAction *, MeshModel &, RichParameterSet *, GLArea *, QPainter *, GLLogStream &) = 0;
574 	virtual void decorateDoc(QAction *, MeshDocument &, RichParameterSet *, GLArea *, QPainter *, GLLogStream &) = 0;
endDecorate(QAction *,MeshModel &,RichParameterSet *,GLArea *)575 	virtual void endDecorate(QAction *, MeshModel &, RichParameterSet *, GLArea *) {}
endDecorate(QAction *,MeshDocument &,RichParameterSet *,GLArea *)576 	virtual void endDecorate(QAction *, MeshDocument &, RichParameterSet *, GLArea *) {}
577 
578 	/** \brief tests if a decoration is applicable to a mesh.
579 	* used only for PerMesh Decorators.
580 	For instance curvature cannot be shown on a mesh without curvature.
581 	On failure (returning false) the function fills the MissingItems list with strings describing the missing items.
582 	It is invoked only for decoration of \i PerMesh class;
583 	*/
isDecorationApplicable(QAction *,const MeshModel &,QString &)584 	virtual bool isDecorationApplicable(QAction *, const MeshModel&, QString&) const { return true; }
585 
586 	virtual int getDecorationClass(QAction *) const = 0;
587 
actions()588 	virtual QList<QAction *> actions() const { return actionList; }
types()589 	virtual QList<FilterIDType> types() const { return typeList; }
590 protected:
591 	QList <QAction *> actionList;
592 	QList <FilterIDType> typeList;
ID(QAction * a)593 	virtual FilterIDType ID(QAction *a) const
594 	{
595 		QString aa=a->text();
596 		foreach(FilterIDType tt, types())
597 			if (a->text() == this->decorationName(tt)) return tt;
598 		aa.replace("&","");
599 		foreach(FilterIDType tt, types())
600 			if (aa == this->decorationName(tt)) return tt;
601 
602 		qDebug("unable to find the id corresponding to action  '%s'", qUtf8Printable(a->text()));
603 		assert(0);
604 		return -1;
605 	}
ID(QString name)606 	virtual FilterIDType ID(QString name) const
607 	{
608 		QString n = name;
609 		foreach(FilterIDType tt, types())
610 			if (name == this->decorationName(tt)) return tt;
611 		n.replace("&","");
612 		foreach(FilterIDType tt, types())
613 			if (n == this->decorationName(tt)) return tt;
614 
615 		qDebug("unable to find the id corresponding to action  '%s'", qUtf8Printable(name));
616 		assert(0);
617 		return -1;
618 	}
619 public:
action(QString name)620 	virtual QAction *action(QString name) const
621 	{
622 		QString n = name;
623 		foreach(QAction *tt, actions())
624 			if (name == this->decorationName(ID(tt))) return tt;
625 		n.replace("&","");
626 		foreach(QAction *tt, actions())
627 			if (n == this->decorationName(ID(tt))) return tt;
628 
629 		qDebug("unable to find the id corresponding to action  '%s'", qUtf8Printable(name));
630 		return 0;
631 	}
632 };
633 
634 
635 /*
636 Editing Interface
637 Used to provide tools that needs some kind of interaction with the mesh.
638 Editing tools are exclusive (only one at a time) and can grab the mouse events and customize the rendering process.
639 */
640 
641 class MeshEditInterface : public MeshCommonInterface
642 {
643 public:
MeshEditInterface()644 	MeshEditInterface() : MeshCommonInterface() {}
~MeshEditInterface()645 	virtual ~MeshEditInterface() {}
646 
647 	//should return a sentence describing what the editing tool does
648 	static const QString Info();
649 
suggestedRenderingData(MeshModel &,MLRenderingData &)650 	virtual void suggestedRenderingData(MeshModel &/*m*/, MLRenderingData& /*dt*/) {}
651 
652 	// Called when the user press the first time the button
StartEdit(MeshModel &,GLArea *,MLSceneGLSharedDataContext *)653 	virtual bool StartEdit(MeshModel &/*m*/, GLArea * /*parent*/, MLSceneGLSharedDataContext* /*cont*/) { return true; }
StartEdit(MeshDocument & md,GLArea * parent,MLSceneGLSharedDataContext * cont)654 	virtual bool StartEdit(MeshDocument &md, GLArea *parent, MLSceneGLSharedDataContext* cont)
655 	{
656 		//assert(NULL != md.mm());
657 		if (md.mm() != NULL)
658 			return (StartEdit(*(md.mm()), parent, cont));
659 		else return false;
660 	}
661 	// Called when the user press the second time the button
EndEdit(MeshModel &,GLArea *,MLSceneGLSharedDataContext *)662 	virtual void EndEdit(MeshModel &/*m*/, GLArea * /*parent*/, MLSceneGLSharedDataContext* /*cont*/) {}
EndEdit(MeshDocument &,GLArea *,MLSceneGLSharedDataContext *)663 	virtual void EndEdit(MeshDocument &/*m*/, GLArea * /*parent*/, MLSceneGLSharedDataContext* /*cont*/) {}
664 
665 	// There are two classes of editing tools, the one that works on a single layer at a time
666 	// and the ones that works on all layers and have to manage in a correct way the action of changing the current layer.
667 	// For the edit tools that works ona single layer changing the layer means the restart of the edit tool.
isSingleMeshEdit()668 	virtual bool isSingleMeshEdit() const { return true; }
669 
670 	// Called when the user changes the selected layer
671 	//by default it calls end edit with the layer that was selected and start with the new layer that is
672 	//selected.  This ensures that plugins who don't support layers do not get sent pointers to meshes
673 	//they are not expecting.
674 	// If your editing plugins is not singleMesh you MUST reimplement this to correctly handle the change of layer.
LayerChanged(MeshDocument & md,MeshModel & oldMeshModel,GLArea * parent,MLSceneGLSharedDataContext * cont)675 	virtual void LayerChanged(MeshDocument &md, MeshModel &oldMeshModel, GLArea *parent, MLSceneGLSharedDataContext* cont)
676 	{
677 		assert(this->isSingleMeshEdit());
678 		EndEdit(oldMeshModel, parent, cont);
679 		StartEdit(md, parent, cont);
680 	}
681 
Decorate(MeshModel & m,GLArea * parent,QPainter *)682 	virtual void Decorate(MeshModel &m, GLArea *parent, QPainter * /*p*/) { Decorate(m, parent); }
Decorate(MeshModel &,GLArea *)683 	virtual void Decorate(MeshModel &/*m*/, GLArea * /*parent*/) {}
684 
685 	virtual void mousePressEvent(QMouseEvent *event, MeshModel &/*m*/, GLArea *) = 0;
686 	virtual void mouseMoveEvent(QMouseEvent *event, MeshModel &/*m*/, GLArea *) = 0;
687 	virtual void mouseReleaseEvent(QMouseEvent *event, MeshModel &/*m*/, GLArea *) = 0;
keyReleaseEvent(QKeyEvent *,MeshModel &,GLArea *)688 	virtual void keyReleaseEvent(QKeyEvent *, MeshModel &/*m*/, GLArea *) {}
keyPressEvent(QKeyEvent *,MeshModel &,GLArea *)689 	virtual void keyPressEvent(QKeyEvent *, MeshModel &/*m*/, GLArea *) {}
wheelEvent(QWheelEvent *,MeshModel &,GLArea *)690 	virtual void wheelEvent(QWheelEvent*, MeshModel &/*m*/, GLArea *) {}
tabletEvent(QTabletEvent * e,MeshModel &,GLArea *)691 	virtual void tabletEvent(QTabletEvent * e, MeshModel &/*m*/, GLArea *) { e->ignore(); }
692 };
693 
694 
695 /** MeshEditInterfaceFactory
696 \short The MeshEditInterfaceFactory class is a <i>factory</i> is used to generate a object for each starting of an editing filter.
697 
698 This is needed because editing filters have a internal state, so if you want to have an editing tool for two different documents you have to instance two objects.
699 This class is used by the framework to generate an independent MeshEditInterface for each document.
700 */
701 class MeshEditInterfaceFactory
702 {
703 public:
~MeshEditInterfaceFactory()704 	virtual ~MeshEditInterfaceFactory() {}
705 
706 	//gets a list of actions available from this plugin
707 	virtual QList<QAction *> actions() const = 0;
708 
709 	//get the edit tool for the given action
710 	virtual MeshEditInterface* getMeshEditInterface(QAction *) = 0;
711 
712 	//get the description for the given action
713 	virtual QString getEditToolDescription(QAction *) = 0;
714 
715 };
716 
717 
718 
719 /**************************************************************************************************************************************************************/
720 /*The new class of filter defined through XML file*/
721 
722 typedef bool SignalCallBack();
723 
724 class MeshLabFilterInterface : public QObject, public MeshLabInterface
725 {
726 	Q_OBJECT
727 public:
728 	MeshLabFilterInterface();
~MeshLabFilterInterface()729 	virtual ~MeshLabFilterInterface() {}
730 
731 	MLPluginGLContext* glContext;
732 
733 	static void initConvertingMap(QMap<QString, MeshModel::MeshElement>& convertingMap);
734 	static void initConvertingCategoryMap(QMap<QString, MeshFilterInterface::FilterClass>& convertingMap);
735 	static bool arePreCondsValid(const int filterPreConds, const MeshModel& m, QStringList &MissingItems);
736 	static int convertStringListToMeshElementEnum(const QStringList& stringListEnum);
737 	static int convertStringListToCategoryEnum(const QStringList& stringListEnum);
738 	virtual bool applyFilter(const QString& filterName, MeshDocument& md, EnvWrap& env, vcg::CallBackPos* cb) = 0;
errorMsg()739 	const QString &errorMsg() { return this->errorMessage; }
740 	public slots:
setInterrupt(const bool & inter)741 	inline void setInterrupt(const bool& inter) { intteruptreq = inter; };
742 
743 protected:
744 	////This function has two different aims:
745 	////1) should be invoked by filters in order to request a redraw of a subset of meshes and/or rasters inside the MeshDocument.
746 	////2) like a synchronization point where the filter can safely stop is execution.
747 	////if filter has not a pending interrupt request a render state update request will be sent to the framework.
748 	////return value: true if the request has been sent, false otherwise (filter has an interrupt request).
749 
750 	//bool sendUpdateRequest(const MeshDocument& md,);
751 
752 	//QList<int> meshestobeupdated;
753 	//int meshmaskattributestobeupdated;
754 	//QList<int> rasterstobeupdated;
755 	//int rastermaskattributestobeupdated;
756 
757 	// this string is used to pass back to the framework error messages in case of failure of a filter apply.
758 	QString errorMessage;
759 	bool intteruptreq;
760 signals:
761 	void renderingDataRequested(int);
762 	void updateDecorators(int);
763 };
764 
765 #if (QT_VERSION  >= 0x050000)
766 #define MESHLAB_PLUGIN_IID_EXPORTER(x) Q_PLUGIN_METADATA(IID x)
767 #define MESHLAB_PLUGIN_NAME_EXPORTER(x)
768 #else
769 #define MESHLAB_PLUGIN_IID_EXPORTER(x)
770 #define MESHLAB_PLUGIN_NAME_EXPORTER(x) Q_EXPORT_PLUGIN(x)
771 #endif
772 
773 
774 
775 #define MESH_IO_INTERFACE_IID "vcg.meshlab.MeshIOInterface/1.0"
776 #define MESH_FILTER_INTERFACE_IID  "vcg.meshlab.MeshFilterInterface/1.0"
777 #define MESHLAB_FILTER_INTERFACE_IID  "vcg.meshlab.MeshLabFilterInterface/1.0"
778 #define MESH_RENDER_INTERFACE_IID  "vcg.meshlab.MeshRenderInterface/1.0"
779 #define MESH_DECORATE_INTERFACE_IID  "vcg.meshlab.MeshDecorateInterface/1.0"
780 #define MESH_EDIT_INTERFACE_IID  "vcg.meshlab.MeshEditInterface/1.0"
781 #define MESH_EDIT_INTERFACE_FACTORY_IID  "vcg.meshlab.MeshEditInterfaceFactory/1.0"
782 
783 Q_DECLARE_INTERFACE(MeshIOInterface, MESH_IO_INTERFACE_IID)
784 Q_DECLARE_INTERFACE(MeshFilterInterface, MESH_FILTER_INTERFACE_IID)
785 Q_DECLARE_INTERFACE(MeshLabFilterInterface, MESHLAB_FILTER_INTERFACE_IID)
786 Q_DECLARE_INTERFACE(MeshRenderInterface, MESH_RENDER_INTERFACE_IID)
787 Q_DECLARE_INTERFACE(MeshDecorateInterface, MESH_DECORATE_INTERFACE_IID)
788 Q_DECLARE_INTERFACE(MeshEditInterface, MESH_EDIT_INTERFACE_IID)
789 Q_DECLARE_INTERFACE(MeshEditInterfaceFactory, MESH_EDIT_INTERFACE_FACTORY_IID)
790 
791 #endif
792