1 #include "scriptinterface.h"
2 #include "pluginmanager.h"
3 #include "interfaces.h"
4 #include "filterparameter.h"
5 #include "meshmodel.h"
6 #include "mlexception.h"
7 #include "pluginmanager.h"
8 #include "scriptsyntax.h"
9 
parNames(const RichParameterSet & set) const10 QString ScriptAdapterGenerator::parNames(const RichParameterSet& set) const
11 {
12 	QString names;
13 	int ii;
14 	for (ii = 0; ii < (set.paramList.size() - 1); ++ii)
15 		names += set.paramList[ii]->name + ", ";
16 	if (set.paramList.size() != 0)
17 		names += set.paramList[ii]->name;
18 	return names;
19 }
20 
parNames(const QString & filterName,MLXMLPluginInfo & xmlInfo) const21 QString ScriptAdapterGenerator::parNames(const QString& filterName, MLXMLPluginInfo& xmlInfo) const
22 {
23 	QString names;
24 	//the order is important !!!
25 	MLXMLPluginInfo::XMLMapList params = xmlInfo.filterParametersExtendedInfo(filterName);
26 	int ii;
27 	bool optional = false;
28 	QString ariet = xmlInfo.filterAttribute(filterName, MLXMLElNames::filterArity);
29 
30 	bool isSingle = (ariet == MLXMLElNames::singleMeshArity);
31 	QString mid = meshID();
32 	if ((names.isEmpty()) && isSingle && (xmlInfo.filterScriptCode(filterName) == ""))
33 		names = mid;
34 	else
35 		if (isSingle && (xmlInfo.filterScriptCode(filterName) == ""))
36 			names = mid + ", " + names;
37 	for (ii = 0; ii < params.size(); ++ii)
38 	{
39 		bool isImp = (params[ii][MLXMLElNames::paramIsImportant] == "true");
40 		if (names.isEmpty() && isImp)
41 			names += /*params[ii][MLXMLElNames::paramType] + "_" +*/ params[ii][MLXMLElNames::paramName];
42 		else
43 			if (isImp)
44 				names += ", " + /*params[ii][MLXMLElNames::paramType] + "_" + */params[ii][MLXMLElNames::paramName];
45 			else
46 				optional = true;
47 	}
48 	if (optional && !(names.isEmpty()))
49 		names += ", " + optName();
50 	if (optional && names.isEmpty())
51 		names += optName();
52 	return names;
53 }
54 
55 
funCodeGenerator(const QString & filtername,const RichParameterSet & set) const56 QString ScriptAdapterGenerator::funCodeGenerator(const QString&  filtername, const RichParameterSet& set) const
57 {
58 	QString code;
59 	code += "function (" + parNames(set) + ")\n";
60 	code += "{\n";
61 	code += "\tvar tmpRichPar = new IRichParameterSet();\n";
62 	code += "\tif (!_initParameterSet(\"" + filtername + "\",tmpRichPar)) return false;\n";
63 	for (int ii = 0; ii < set.paramList.size(); ++ii)
64 		code += "\ttmpRichPar.set" + set.paramList[ii]->val->typeName() + "(\"" + set.paramList[ii]->name + "\",arguments[" + QString::number(ii) + "]);\n";
65 	code += "\treturn _applyFilter(\"" + filtername + "\",tmpRichPar);\n";
66 	code += "};\n";
67 	return code;
68 }
69 
funCodeGenerator(const QString & filterName,MLXMLPluginInfo & xmlInfo) const70 QString ScriptAdapterGenerator::funCodeGenerator(const QString& filterName, MLXMLPluginInfo& xmlInfo) const
71 {
72 	QString code;
73 	QString names = parNames(filterName, xmlInfo);
74 
75 	code += "function (" + names + ")\n";
76 	code += "{\n";
77 	MLXMLPluginInfo::XMLMapList mplist = xmlInfo.filterParametersExtendedInfo(filterName);
78 	if (names.indexOf(optName()) != -1)
79 	{
80 		QString defValues;
81 		for (int ii = 0; ii < mplist.size(); ++ii)
82 		{
83 			MLXMLPluginInfo::XMLMap mp = mplist[ii];
84 			if (mp[MLXMLElNames::paramIsImportant] == "false")
85 				defValues += mp[MLXMLElNames::paramName] + " : " + mp[MLXMLElNames::paramDefExpr] + ", ";
86 		}
87 		code += "\t" + optName() + " = __mergeOptions(" + optName() + ",{" + defValues + "});\n";
88 	}
89 
90 	code += "\tvar environ = new Env;\n";
91 
92 	QString ariet = xmlInfo.filterAttribute(filterName, MLXMLElNames::filterArity);
93 	bool isSingle = (ariet == MLXMLElNames::singleMeshArity);
94 	//if is singleMeshAriety i have to jump the first argument because is the meshID
95 	int arg = (int)isSingle;
96 	for (int ii = 0; ii < mplist.size(); ++ii)
97 	{
98 		MLXMLPluginInfo::XMLMap mp = mplist[ii];
99 		bool isenum = false;
100 		QString num = QString::number(ii);
101 		QString values = mp[MLXMLElNames::paramType];
102 		if (values.contains(MLXMLElNames::enumType))
103 		{
104 			QRegExp rem(MLXMLElNames::enumType + " \\{");
105 			values.remove(rem);
106 			rem.setPattern("\\}");
107 			values.remove(rem);
108 			MLXMLPluginInfo::XMLMap valuesMap = MLXMLPluginInfo::mapFromString(values, QRegExp("\\|"), QRegExp("\\:"));
109 			code += "\tfunction enumfun_" + num + "()\n\t{\t\n";
110 			for (MLXMLPluginInfo::XMLMap::iterator it = valuesMap.begin(); it != valuesMap.end(); ++it)
111 			{
112 				code += "\t\tthis[\"" + it.key() + "\"] = " + it.value() + ";\n";
113 				code += "\t\tthis[parseInt(" + it.value() + ")] = \"" + it.key() + "\";\n";
114 			}
115 			code += "\t}\n";
116 			code += "\tfunction get_" + num + "(ff,ii)\n\t{\t\n";
117 			code += "\t\tif (typeof(ii) == \"number\") return ff[ff[ii]];\n";
118 			code += "\t\telse if (typeof(ii) == \"string\") return ff[ii];\n";
119 			code += "\t\t\telse return undefined;\n";
120 			code += "\t}\n";
121 
122 			code += "\tvar enumtype_" + num + " = new enumfun_" + num + "();\n";
123 			isenum = true;
124 		}
125 		if (mp[MLXMLElNames::paramIsImportant] == "true")
126 		{
127 			QString argument = "arguments[" + QString::number(arg) + "]";
128 			if (isenum)
129 			{
130 				code += "\tvar argenum_" + num + " = get_" + num + "(enumtype_" + num + "," + argument + ");\n";
131 				code += "\tenviron.insertExpressionBinding(\"" + mp[MLXMLElNames::paramName] + "\",argenum_" + num + ");\n";
132 			}
133 			else
134 				//code += "\tprint(" + argument + ");\n";
135 				code += "\tenviron.insertExpressionBinding(\"" + mp[MLXMLElNames::paramName] + "\"," + argument + ");\n";
136 			++arg;
137 		}
138 		else
139 		{
140 			if (isenum)
141 			{
142 				//code += "\tvar argenum_" + num + " = enumtype_" + num + "[" + argument + "];\n";
143 				code += "\tvar " + mp[MLXMLElNames::paramName] + " = get_" + num + "(enumtype_" + num + "," + optName() + "." + /*mp[MLXMLElNames::paramType] + "_" +*/ mp[MLXMLElNames::paramName] + ");\n";
144 				code += "\tenviron.insertExpressionBinding(\"" + mp[MLXMLElNames::paramName] + "\", " + mp[MLXMLElNames::paramName] + ");\n";
145 			}
146 			else
147 			{
148 				code += "\tvar " + mp[MLXMLElNames::paramName] + " = " + optName() + "." + /*mp[MLXMLElNames::paramType] + "_" +*/ mp[MLXMLElNames::paramName] + ";\n";
149 				code += "\tenviron.insertExpressionBinding(\"" + mp[MLXMLElNames::paramName] + "\", " + mp[MLXMLElNames::paramName] + ");\n";
150 			}
151 		}
152 	}
153 	code += "\tvar environWrap = new EnvWrap(environ);\n";
154 	if (isSingle)
155 	{
156 		code += "\tvar oldInd=" + meshDocVarName() + ".setCurrent(" + meshID() + ");\n";
157 		code += "\tif (oldInd == -1) return false;\n";
158 	}
159 	code += "\tvar result = _applyFilter(\"" + filterName + "\",environWrap);\n";
160 	if (isSingle)
161 		code += "\t" + meshDocVarName() + ".setCurrent(oldInd);\n";
162 	code += "\treturn result;\n";
163 	code += "};\n";
164 	return code;
165 }
166 
167 //const QStringList ScriptAdapterGenerator::javaScriptLibraryFiles()
168 //{
169 //	QStringList res;
170 //	res.push_back(":/script_system/space_math.js");
171 //	return res;
172 //}
173 
mergeOptParamsCodeGenerator() const174 QString ScriptAdapterGenerator::mergeOptParamsCodeGenerator() const
175 {
176 	QString code;
177 	code += "function __mergeOptions(argOptions, defaultOptions)\n{\n";
178 	code += "\tvar ret = { };\n";
179 	code += "\targOptions = argOptions || { };\n";
180 	code += "\tfor (var p in defaultOptions)\n";
181 	code += "\t\tret[p] = argOptions.hasOwnProperty(p) ? argOptions[p] : defaultOptions[p];\n";
182 	code += "\treturn ret;\n}\n";
183 	return code;
184 }
185 
186 
Q_DECLARE_METATYPE(MeshDocument *)187 Q_DECLARE_METATYPE(MeshDocument*)
188 
189 static bool TestCallback(const int, const char*)
190 {
191 	return true;
192 }
193 
194 //QScriptValue PluginInterfaceInit(QScriptContext *context, QScriptEngine *engine, void * param)
195 //{
196 //	QString filterName = context->argument(0).toString();
197 //	PluginManager * pm = reinterpret_cast<PluginManager *>(param);
198 //	QMap<QString, MeshFilterInterface*>::iterator it = pm->stringFilterMap.find(filterName);
199 //	if (it == pm->stringFilterMap.end())
200 //	{
201 //		return false;
202 //	}
203 //
204 //	MeshDocumentSI* md = qscriptvalue_cast<MeshDocumentSI*>(engine->globalObject().property(ScriptAdapterGenerator::meshDocVarName()));
205 //	RichParameterSet* rps = qscriptvalue_cast<RichParameterSet*>(context->argument(1));
206 //
207 //	MeshFilterInterface * mi = it.value();
208 //	QAction act(filterName, NULL);
209 //	mi->initParameterSet(&act, (md->current()->mm), *rps);
210 //
211 //	return true;
212 //}
213 
214 //QScriptValue PluginInterfaceApply(QScriptContext *context, QScriptEngine *engine, void * param)
215 //{
216 //	QString filterName = context->argument(0).toString();
217 //	PluginManager * pm = reinterpret_cast<PluginManager *>(param);
218 //	QMap<QString, MeshFilterInterface*>::iterator it = pm->stringFilterMap.find(filterName);
219 //	if (it == pm->stringFilterMap.end())
220 //	{
221 //		return false;
222 //	}
223 //
224 //	MeshDocumentSI* md = qscriptvalue_cast<MeshDocumentSI*>(engine->globalObject().property(ScriptAdapterGenerator::meshDocVarName()));
225 //	RichParameterSet* rps = qscriptvalue_cast<RichParameterSet*>(context->argument(1));
226 //
227 //	MeshFilterInterface * mi = it.value();
228 //	QAction act(filterName, NULL);
229 //	const bool res = mi->applyFilter(&act, *(md->md), *rps, TestCallback);
230 //
231 //	return res;
232 //}
233 
PluginInterfaceApplyXML(QScriptContext * context,QScriptEngine * engine,void * param)234 QScriptValue PluginInterfaceApplyXML(QScriptContext *context, QScriptEngine *engine, void * param)
235 {
236 	QString filterName = context->argument(0).toString();
237 	PluginManager * pm = reinterpret_cast<PluginManager *>(param);
238 	QMap<QString, MeshLabXMLFilterContainer>::iterator it = pm->stringXMLFilterMap.find(filterName);
239 	if (it == pm->stringXMLFilterMap.end())
240 		return false;
241 
242 	MeshDocumentSI* md = qscriptvalue_cast<MeshDocumentSI*>(engine->globalObject().property(ScriptAdapterGenerator::meshDocVarName()));
243 	EnvWrap* envWrap = qscriptvalue_cast<EnvWrap*>(context->argument(1));
244 
245 	MeshLabFilterInterface * mi = it->filterInterface;
246 	const bool res = mi->applyFilter(filterName, *(md->md), *envWrap, TestCallback);
247 	return QScriptValue(res);
248 }
249 
250 Q_DECLARE_METATYPE(RichParameterSet)
Q_DECLARE_METATYPE(RichParameterSet *)251 Q_DECLARE_METATYPE(RichParameterSet*)
252 
253 QScriptValue IRichParameterSet_prototype_setBool(QScriptContext* c, QScriptEngine* e)
254 {
255 	RichParameterSet* rset = qscriptvalue_cast<RichParameterSet*>(c->thisObject());
256 	QString varname = c->argument(0).toString();
257 	bool val = c->argument(1).toBool();
258 	rset->setValue(varname, BoolValue(val));
259 	return e->undefinedValue();
260 }
261 
IRichParameterSet_prototype_setInt(QScriptContext * c,QScriptEngine * e)262 QScriptValue IRichParameterSet_prototype_setInt(QScriptContext* c, QScriptEngine* e)
263 {
264 	RichParameterSet* rset = qscriptvalue_cast<RichParameterSet*>(c->thisObject());
265 	QString varname = c->argument(0).toString();
266 	int val = c->argument(1).toInt32();
267 	rset->setValue(varname, IntValue(val));
268 	return e->undefinedValue();
269 }
270 
271 
IRichParameterSet_prototype_setAbsPerc(QScriptContext * c,QScriptEngine * e)272 QScriptValue IRichParameterSet_prototype_setAbsPerc(QScriptContext* c, QScriptEngine* e)
273 {
274 	RichParameterSet* rset = qscriptvalue_cast<RichParameterSet*>(c->thisObject());
275 	QString varname = c->argument(0).toString();
276 	float val = (float)c->argument(1).toNumber();
277 	rset->setValue(varname, AbsPercValue(val));
278 	return e->undefinedValue();
279 }
280 
IRichParameterSet_prototype_setFloat(QScriptContext * c,QScriptEngine * e)281 QScriptValue IRichParameterSet_prototype_setFloat(QScriptContext* c, QScriptEngine* e)
282 {
283 	RichParameterSet* rset = qscriptvalue_cast<RichParameterSet*>(c->thisObject());
284 	QString varname = c->argument(0).toString();
285 	float val = (float)c->argument(1).toNumber();
286 	rset->setValue(varname, FloatValue(val));
287 	return e->undefinedValue();
288 }
289 
IRichParameterSet_ctor(QScriptContext *,QScriptEngine * e)290 QScriptValue IRichParameterSet_ctor(QScriptContext* /*c*/, QScriptEngine* e)
291 {
292 	RichParameterSet* p = new RichParameterSet();
293 	QScriptValue res = e->toScriptValue(*p);
294 	//res.setProperty("setBool",e->newFunction(IRichParameterSet_prototype_setBool,2));
295 	//res.setProperty("setInt",e->newFunction(IRichParameterSet_prototype_setInt,2));
296 	return res;
297 }
298 
299 
myprint(QScriptContext * sc,QScriptEngine * se)300 QScriptValue myprint(QScriptContext* sc, QScriptEngine* se)
301 {
302 	QString st = sc->argument(0).toString();
303 	Env* myenv = qobject_cast<Env*>(se);
304 	if (myenv)
305 		myenv->appendOutput(st);
306 	return QScriptValue(se, 0);
307 }
308 
MeshDocumentSI(MeshDocument * doc)309 MeshDocumentSI::MeshDocumentSI(MeshDocument* doc)
310 	:QObject(), md(doc)
311 {
312 }
313 
getMesh(int meshId)314 Q_INVOKABLE MeshModelSI* MeshDocumentSI::getMesh(int meshId)
315 {
316 	MeshModel* model = md->getMesh(meshId);
317 	if (model != NULL)
318 		return new MeshModelSI(*model, this);
319 	else
320 		return NULL;
321 }
322 
current()323 Q_INVOKABLE MeshModelSI* MeshDocumentSI::current()
324 {
325 	MeshModel* model = md->mm();
326 	if (model != NULL)
327 		return new MeshModelSI(*model, this);
328 	else
329 		return NULL;
330 }
331 
currentId()332 Q_INVOKABLE int MeshDocumentSI::currentId()
333 {
334 	MeshModel* model = md->mm();
335 	if (model != NULL)
336 		return model->id();
337 	else
338 		return -1;
339 }
340 
setCurrent(const int meshId)341 Q_INVOKABLE int MeshDocumentSI::setCurrent(const int meshId)
342 {
343 	int id = -1;
344 	if (md->mm() != NULL)
345 		id = md->mm()->id();
346 	if (md->getMesh(meshId) != NULL)
347 	{
348 		md->setCurrentMesh(meshId);
349 		return id;
350 	}
351 	else
352 		return -1;
353 }
354 
operator [](const QString & name)355 Q_INVOKABLE MeshModelSI* MeshDocumentSI::operator[](const QString& name)
356 {
357 	MeshModel* mym = md->getMesh(name);
358 	if (mym != NULL)
359 		return new MeshModelSI(*mym, this);
360 	else
361 		return NULL;
362 }
363 
getMeshByName(const QString & name)364 Q_INVOKABLE MeshModelSI* MeshDocumentSI::getMeshByName(const QString& name)
365 {
366 	return (*this)[name];
367 }
368 
369 
MeshModelSI(MeshModel & meshModel,MeshDocumentSI * parent)370 MeshModelSI::MeshModelSI(MeshModel& meshModel, MeshDocumentSI* parent)
371 	:QObject(parent), mm(meshModel)
372 {
373 
374 }
375 
bboxDiag() const376 Q_INVOKABLE Scalarm MeshModelSI::bboxDiag() const
377 {
378 	return mm.cm.bbox.Diag();
379 }
380 
bboxMin() const381 Q_INVOKABLE QVector<Scalarm> MeshModelSI::bboxMin() const
382 {
383 	return ScriptInterfaceUtilities::vcgPoint3ToVector3(mm.cm.bbox.min);
384 }
385 
bboxMax() const386 Q_INVOKABLE QVector<Scalarm> MeshModelSI::bboxMax() const
387 {
388 	return ScriptInterfaceUtilities::vcgPoint3ToVector3(mm.cm.bbox.max);
389 }
390 
id() const391 Q_INVOKABLE int MeshModelSI::id() const
392 {
393 	return mm.id();
394 }
395 
VCGVertexSI(CMeshO::VertexType & v)396 VCGVertexSI::VCGVertexSI(CMeshO::VertexType& v)
397 	:QObject(), vv(v)
398 {
399 }
400 
v(const int ind)401 Q_INVOKABLE VCGVertexSI* MeshModelSI::v(const int ind)
402 {
403 	unsigned int ii(ind);
404 	if (ii < mm.cm.vert.size())
405 		return new VCGVertexSI(mm.cm.vert[ii]);
406 	else
407 		return NULL;
408 }
409 
shot()410 Q_INVOKABLE ShotSI* MeshModelSI::shot()
411 {
412 	return new ShotSI(mm.cm.shot);
413 }
414 
vn() const415 Q_INVOKABLE int MeshModelSI::vn() const
416 {
417 	return mm.cm.vn;
418 }
419 
fn() const420 Q_INVOKABLE int MeshModelSI::fn() const
421 {
422 	return mm.cm.fn;
423 }
424 
vert()425 Q_INVOKABLE QVector<VCGVertexSI*> MeshModelSI::vert()
426 {
427 	QVector<VCGVertexSI*> v;
428 	for (int ii = 0; ii < mm.cm.vn; ++ii)
429 		v.push_back(new VCGVertexSI(mm.cm.vert[ii]));
430 	return v;
431 }
432 
getVertPosArray()433 Q_INVOKABLE Point3Vector MeshModelSI::getVertPosArray()
434 {
435 	Point3Vector pv;
436 	for (int ii = 0; ii < mm.cm.vn; ++ii)
437 	{
438 		QVector<Scalarm> p;
439 		p << mm.cm.vert[ii].P().X() << mm.cm.vert[ii].P().Y() << mm.cm.vert[ii].P().Z();
440 		pv << p;
441 	}
442 	return pv;
443 }
444 
setVertPosArray(const Point3Vector & pa)445 Q_INVOKABLE void MeshModelSI::setVertPosArray(const Point3Vector& pa)
446 {
447 	for (int ii = 0; ii < mm.cm.vn; ++ii)
448 		mm.cm.vert[ii].P() = Point3m(pa[ii][0], pa[ii][1], pa[ii][2]);
449 }
450 
setVertNormArray(const Point3Vector & na)451 Q_INVOKABLE void MeshModelSI::setVertNormArray(const Point3Vector& na)
452 {
453 	for (int ii = 0; ii < mm.cm.vn; ++ii)
454 		mm.cm.vert[ii].N() = Point3m(na[ii][0], na[ii][1], na[ii][2]);
455 }
456 
getVertNormArray()457 Q_INVOKABLE Point3Vector MeshModelSI::getVertNormArray()
458 {
459 	Point3Vector pv;
460 	for (int ii = 0; ii < mm.cm.vn; ++ii)
461 	{
462 		QVector<Scalarm> p;
463 		p << mm.cm.vert[ii].N().X() << mm.cm.vert[ii].N().Y() << mm.cm.vert[ii].N().Z();
464 		pv << p;
465 	}
466 	return pv;
467 }
468 
469 //Q_INVOKABLE void MeshModelSI::setV( const QVector<VCGVertexSI*>& v )
470 //{
471 //	for(unsigned int ii = 0; ii < mm.cm.vn;++ii)
472 //		mm.cm.vert[ii] = v[ii]->;
473 //}
474 
475 
getP()476 Q_INVOKABLE QVector<Scalarm> VCGVertexSI::getP()
477 {
478 	return ScriptInterfaceUtilities::vcgPoint3ToVector3(vv.P());
479 }
480 
setPC(const Scalarm x,const Scalarm y,const Scalarm z)481 Q_INVOKABLE void VCGVertexSI::setPC(const Scalarm x, const Scalarm y, const Scalarm z)
482 {
483 	vv.P() = Point3m(x, y, z);
484 }
485 
setP(const QVector<Scalarm> & p)486 Q_INVOKABLE void VCGVertexSI::setP(const QVector<Scalarm>& p)
487 {
488 	for (int ii = 0; ii < 3; ++ii)
489 		vv.P()[ii] = p[ii];
490 }
491 
getN()492 Q_INVOKABLE QVector<Scalarm> VCGVertexSI::getN()
493 {
494 	return ScriptInterfaceUtilities::vcgPoint3ToVector3(vv.N());
495 }
496 
setN(const Scalarm x,const Scalarm y,const Scalarm z)497 Q_INVOKABLE void VCGVertexSI::setN(const Scalarm x, const Scalarm y, const Scalarm z)
498 {
499 	vv.N() = Point3m(x, y, z);
500 }
501 
getPoint()502 Q_INVOKABLE VCGPoint3SI VCGVertexSI::getPoint()
503 {
504 	return vv.P();
505 }
506 
setPoint(const VCGPoint3SI & p)507 Q_INVOKABLE void VCGVertexSI::setPoint(const VCGPoint3SI& p)
508 {
509 	vv.P() = p;
510 }
511 
getNormal()512 Q_INVOKABLE VCGPoint3SI VCGVertexSI::getNormal()
513 {
514 	return vv.N();
515 }
516 
setNormal(const VCGPoint3SI & p)517 Q_INVOKABLE void VCGVertexSI::setNormal(const VCGPoint3SI& p)
518 {
519 	vv.N() = p;
520 }
521 
MeshModelScriptInterfaceToScriptValue(QScriptEngine * eng,MeshModelSI * const & in)522 QScriptValue MeshModelScriptInterfaceToScriptValue(QScriptEngine* eng, MeshModelSI* const& in)
523 {
524 	return eng->newQObject(in);
525 }
526 
MeshModelScriptInterfaceFromScriptValue(const QScriptValue & val,MeshModelSI * & out)527 void MeshModelScriptInterfaceFromScriptValue(const QScriptValue& val, MeshModelSI*& out)
528 {
529 	out = qobject_cast<MeshModelSI*>(val.toQObject());
530 }
531 
MeshDocumentScriptInterfaceToScriptValue(QScriptEngine * eng,MeshDocumentSI * const & in)532 QScriptValue MeshDocumentScriptInterfaceToScriptValue(QScriptEngine* eng, MeshDocumentSI* const& in)
533 {
534 	return eng->newQObject(in);
535 }
536 
MeshDocumentScriptInterfaceFromScriptValue(const QScriptValue & val,MeshDocumentSI * & out)537 void MeshDocumentScriptInterfaceFromScriptValue(const QScriptValue& val, MeshDocumentSI*& out)
538 {
539 	out = qobject_cast<MeshDocumentSI*>(val.toQObject());
540 }
541 
542 
VCGVertexScriptInterfaceToScriptValue(QScriptEngine * eng,VCGVertexSI * const & in)543 QScriptValue VCGVertexScriptInterfaceToScriptValue(QScriptEngine* eng, VCGVertexSI* const& in)
544 {
545 	return eng->newQObject(in);
546 }
547 
VCGVertexScriptInterfaceFromScriptValue(const QScriptValue & val,VCGVertexSI * & out)548 void VCGVertexScriptInterfaceFromScriptValue(const QScriptValue& val, VCGVertexSI*& out)
549 {
550 	out = qobject_cast<VCGVertexSI*>(val.toQObject());
551 }
552 
ShotScriptInterfaceToScriptValue(QScriptEngine * eng,ShotSI * const & in)553 QScriptValue ShotScriptInterfaceToScriptValue(QScriptEngine* eng, ShotSI* const& in)
554 {
555 	return eng->newQObject(in);
556 }
557 
ShotScriptInterfaceFromScriptValue(const QScriptValue & val,ShotSI * & out)558 void ShotScriptInterfaceFromScriptValue(const QScriptValue& val, ShotSI*& out)
559 {
560 	out = qobject_cast<ShotSI*>(val.toQObject());
561 }
562 
563 //QScriptValue VCGPoint3fScriptInterfaceToScriptValue( QScriptEngine* eng,VCGPoint3fSI* const& in )
564 //{
565 //	return eng->newQObject(in);
566 //}
567 //
568 //void VCGPoint3fScriptInterfaceFromScriptValue( const QScriptValue& val,VCGPoint3fSI*& out )
569 //{
570 //	out = qobject_cast<VCGPoint3fSI*>(val.toQObject());
571 //}
572 
EnvWrap_ctor(QScriptContext * c,QScriptEngine * e)573 QScriptValue EnvWrap_ctor(QScriptContext* c, QScriptEngine* e)
574 {
575 	Env* env = qscriptvalue_cast<Env*>(c->argument(0));
576 	EnvWrap* p = new EnvWrap(*env);
577 	QScriptValue res = e->toScriptValue(*p);
578 	return res;
579 }
580 
VCGPoint3ScriptInterface_ctor(QScriptContext * c,QScriptEngine * e)581 QScriptValue VCGPoint3ScriptInterface_ctor(QScriptContext *c, QScriptEngine *e)
582 {
583 	VCGPoint3SI* p = new VCGPoint3SI(Scalarm(c->argument(0).toNumber()), Scalarm(c->argument(1).toNumber()), Scalarm(c->argument(2).toNumber()));
584 	QScriptValue res = e->toScriptValue(*p);
585 	return res;
586 }
587 
EnvWrap(Env & envir)588 EnvWrap::EnvWrap(Env& envir)
589 	:env(&envir)
590 {
591 }
592 
evalExp(const QString & nm)593 QScriptValue EnvWrap::evalExp(const QString& nm)
594 {
595 	if (!constStatement(nm))
596 		throw NotConstException(nm);
597 	QScriptValue result = env->evaluate(nm);
598 	QString errmsg = result.toString();
599 	if (result.isError())
600 		throw ValueNotFoundException(nm);
601 	return result;
602 }
603 
evalBool(const QString & nm)604 bool EnvWrap::evalBool(const QString& nm)
605 {
606 	QScriptValue result = evalExp(nm);
607 	if (result.isBool())
608 		return result.toBool();
609 	else
610 		throw ExpressionHasNotThisTypeException("Bool", nm);
611 	return false;
612 }
613 
evalDouble(const QString & nm)614 double EnvWrap::evalDouble(const QString& nm)
615 {
616 	QScriptValue result = evalExp(nm);
617 	if (result.isNumber())
618 		return result.toNumber();
619 	else
620 		throw ExpressionHasNotThisTypeException("Double", nm);
621 	return double();
622 }
623 
evalFloat(const QString & nm)624 float EnvWrap::evalFloat(const QString& nm)
625 {
626 	try
627 	{
628 		double result = evalDouble(nm);
629 		return (float)result;
630 	}
631 	catch (ExpressionHasNotThisTypeException& /*exc*/)
632 	{
633 		throw ExpressionHasNotThisTypeException("Float", nm);
634 	}
635 	return float();
636 }
637 
evalReal(const QString & nm)638 MESHLAB_SCALAR EnvWrap::evalReal(const QString& nm)
639 {
640     try
641     {
642         double result = evalDouble(nm);
643         return (MESHLAB_SCALAR)result;
644     }
645     catch (ExpressionHasNotThisTypeException& /*exc*/)
646     {
647         throw ExpressionHasNotThisTypeException("Real", nm);
648     }
649     return MESHLAB_SCALAR();
650 }
651 
evalInt(const QString & nm)652 int EnvWrap::evalInt(const QString& nm)
653 {
654 	try
655 	{
656 		double result = evalDouble(nm);
657 		return (int)result;
658 	}
659 	catch (ExpressionHasNotThisTypeException&)
660 	{
661 		throw ExpressionHasNotThisTypeException("Int", nm);
662 	}
663 	return int();
664 }
665 
evalVec3(const QString & nm)666 vcg::Point3f EnvWrap::evalVec3(const QString& nm)
667 {
668 	QScriptValue result = evalExp(nm);
669 	QVariant resVar = result.toVariant();
670 	QVariantList resList = resVar.toList();
671 	if (resList.size() == 3)
672 		return vcg::Point3f(resList[0].toReal(), resList[1].toReal(), resList[2].toReal());
673 	else
674 		throw ExpressionHasNotThisTypeException("Vec3", nm);
675 	return vcg::Point3f();
676 }
677 
evalVec3Real(const QString & nm)678 vcg::Point3<MESHLAB_SCALAR> EnvWrap::evalVec3Real(const QString& nm)
679 {
680     QScriptValue result = evalExp(nm);
681     QVariant resVar = result.toVariant();
682     QVariantList resList = resVar.toList();
683     if (resList.size() == 3)
684         return vcg::Point3<MESHLAB_SCALAR>(resList[0].toReal(), resList[1].toReal(), resList[2].toReal());
685     else
686         throw ExpressionHasNotThisTypeException("Vec3", nm);
687     return vcg::Point3<MESHLAB_SCALAR>();
688 }
689 
evalEnum(const QString & nm)690 int EnvWrap::evalEnum(const QString& nm)
691 {
692 	return evalInt(nm);
693 }
694 
evalMesh(const QString & nm)695 MeshModel* EnvWrap::evalMesh(const QString& nm)
696 {
697 	int ii = evalInt(nm);
698 	QScriptValue mdsv = env->globalObject().property(ScriptAdapterGenerator::meshDocVarName());
699 	MeshDocumentSI* mdsi = dynamic_cast<MeshDocumentSI*>(mdsv.toQObject());
700 	if (mdsi != NULL)
701 		return mdsi->md->getMesh(ii);
702 	return NULL;
703 }
704 
evalColor(const QString & nm)705 QColor EnvWrap::evalColor(const QString& nm)
706 {
707 	QScriptValue result = evalExp(nm);
708 	QVariant resVar = result.toVariant();
709 	QVariantList resList = resVar.toList();
710 	int colorComp = resList.size();
711 	if ((colorComp >= 3) && (colorComp <= 4))
712 	{
713 		bool isInt0255 = true;
714 		for (int ii = 0; ii < colorComp; ++ii)
715 		{
716 			bool isScalarInt = false;
717 			int resInt = resList[ii].toInt(&isScalarInt);
718 
719 			if (!isScalarInt)
720 				throw ExpressionHasNotThisTypeException("Color", nm);
721 			else
722 				if ((resInt < 0) || (resInt > 255))
723 					isInt0255 = false;
724 		}
725 		if (isInt0255)
726 		{
727 			if (colorComp == 3)
728 				return QColor(resList[0].toInt(), resList[1].toInt(), resList[2].toInt());
729 			if (colorComp == 4)
730 				return QColor(resList[0].toInt(), resList[1].toInt(), resList[2].toInt(), resList[3].toInt());
731 		}
732 		else
733 			throw ExpressionHasNotThisTypeException("Color", nm);
734 	}
735 	else
736 		throw ExpressionHasNotThisTypeException("Color", nm);
737 	return QColor();
738 }
739 
constStatement(const QString & statement) const740 bool EnvWrap::constStatement(const QString& statement) const
741 {
742 	/*QRegExp exp("\\S+\\s*=\\s*S++;");*/
743 	QRegExp exp("\\S+\\s*=\\s*\\S+;");
744 	int ii = statement.indexOf(exp);
745 	return (ii == -1);
746 }
747 
evalString(const QString & nm)748 QString EnvWrap::evalString(const QString& nm)
749 {
750 	QScriptValue result = evalExp(nm);
751 	return result.toString();
752 }
753 
evalShot(const QString & nm)754 Shotm EnvWrap::evalShot(const QString& nm)
755 {
756 	QScriptValue result = evalExp(nm);
757 	ShotSI* shot = qscriptvalue_cast<ShotSI*>(result);
758 	if (shot != NULL)
759 		return shot->shot;
760 	else
761 		throw ExpressionHasNotThisTypeException("Shotm", nm);
762 	return Shotm();
763 
764 }
765 
766 Q_DECLARE_METATYPE(EnvWrap)
Q_DECLARE_METATYPE(EnvWrap *)767 Q_DECLARE_METATYPE(EnvWrap*)
768 
769 QScriptValue Env_ctor(QScriptContext * /*context*/, QScriptEngine *engine)
770 {
771 	Env * env = new Env();
772 	return engine->newQObject(env, QScriptEngine::ScriptOwnership);
773 }
774 
ShotSI_ctor(QScriptContext * c,QScriptEngine * e)775 QScriptValue ShotSI_ctor(QScriptContext* c, QScriptEngine* e)
776 {
777 	if (c->argumentCount() != 8)
778 		return e->nullValue();
779 	ShotSI* shot = new ShotSI();
780 	QVector<Scalarm> m = qscriptvalue_cast<QVector<Scalarm>>(c->argument(0));
781 	if (m.size() != 16)
782 		return e->nullValue();
783 	QVector<Scalarm> tr = qscriptvalue_cast<QVector<Scalarm>>(c->argument(1));
784 	if (tr.size() != 3)
785 		return e->nullValue();
786 	Scalarm focal(c->argument(2).toNumber());
787 	QVector<Scalarm> pixelsize = qscriptvalue_cast<QVector<Scalarm>>(c->argument(3));
788 	if (pixelsize.size() != 2)
789 		return e->nullValue();
790 	QVector<Scalarm> centerpx = qscriptvalue_cast<QVector<Scalarm>>(c->argument(4));
791 	if (centerpx.size() != 2)
792 		return e->nullValue();
793 	QVector<Scalarm> viewportpx = qscriptvalue_cast<QVector<Scalarm>>(c->argument(5));
794 	if (viewportpx.size() != 2)
795 		return e->nullValue();
796 	QVector<Scalarm> distpx = qscriptvalue_cast<QVector<Scalarm>>(c->argument(6));
797 	if (distpx.size() != 2)
798 		return e->nullValue();
799 	QVector<Scalarm> k = qscriptvalue_cast<QVector<Scalarm>>(c->argument(7));
800 	if (k.size() != 4)
801 		return e->nullValue();
802 	Matrix44m mat = ScriptInterfaceUtilities::vector16ToVcgMatrix44(m);
803 	shot->shot.Extrinsics.SetRot(mat);
804 	Point3m tra = ScriptInterfaceUtilities::vector3ToVcgPoint3(tr);
805 	shot->shot.Extrinsics.SetTra(tra);
806 	shot->shot.Intrinsics.FocalMm = focal;
807 	Point2m pxsize = ScriptInterfaceUtilities::vector2ToVcgPoint2(pixelsize);
808 	shot->shot.Intrinsics.PixelSizeMm = pxsize;
809 	Point2m cent = ScriptInterfaceUtilities::vector2ToVcgPoint2(centerpx);
810 	shot->shot.Intrinsics.CenterPx = cent;
811 	vcg::Point2i vw = ScriptInterfaceUtilities::vector2ToVcgPoint2i(viewportpx);
812 	shot->shot.Intrinsics.ViewportPx = vw;
813 	Point2m d = ScriptInterfaceUtilities::vector2ToVcgPoint2(distpx);
814 	shot->shot.Intrinsics.DistorCenterPx = d;
815 	for (int ii = 0; ii < 4; ++ii)
816 		shot->shot.Intrinsics.k[ii] = k[ii];
817 	return e->newQObject(shot, QScriptEngine::ScriptOwnership);
818 }
819 
ShotSI_defctor(QScriptContext *,QScriptEngine * e)820 QScriptValue ShotSI_defctor(QScriptContext* /*c*/, QScriptEngine* e)
821 {
822 	ShotSI* shot = new ShotSI();
823 	return e->newQObject(shot, QScriptEngine::ScriptOwnership);
824 }
825 
826 
827 
Env()828 Env::Env()
829 	:QScriptEngine()
830 {
831 	qRegisterMetaType<Scalarm>("Scalarm");
832 	qScriptRegisterSequenceMetaType< QVector<Scalarm> >(this);
833 	qScriptRegisterSequenceMetaType<Point3Vector>(this);
834 	qScriptRegisterSequenceMetaType<QVector<VCGVertexSI*> >(this);
835 	qScriptRegisterMetaType(this, MeshModelScriptInterfaceToScriptValue, MeshModelScriptInterfaceFromScriptValue);
836 	qScriptRegisterMetaType(this, VCGVertexScriptInterfaceToScriptValue, VCGVertexScriptInterfaceFromScriptValue);
837 
838 	QScriptValue fun = newFunction(myprint, 1);
839 	globalObject().setProperty("print", fun);
840 
841 	QScriptValue addfun = newFunction(VCGPoint3SI_addV3, 2);
842 	globalObject().setProperty("addV3", addfun);
843 
844 	QScriptValue multfun = newFunction(VCGPoint3SI_multV3S, 2);
845 	globalObject().setProperty("multV3S", multfun);
846 
847 	QScriptValue envwrap_ctor = newFunction(EnvWrap_ctor);
848 	//eng->setDefaultPrototype(qMetaTypeId<EnvWrap>(), envwrap_ctor.property("prototype"));
849 	globalObject().setProperty("EnvWrap", envwrap_ctor);
850 
851 	QScriptValue env_ctor = newFunction(Env_ctor);
852 	QScriptValue metaObject = newQMetaObject(&Env::staticMetaObject, env_ctor);
853 	globalObject().setProperty("Env", metaObject);
854 
855 	QScriptValue point_ctor = newFunction(VCGPoint3ScriptInterface_ctor);
856 	//QScriptValue pointmetaObject = newQMetaObject(&VCGPoint3fSI::staticMetaObject, point_ctor);
857 	setDefaultPrototype(qMetaTypeId<VCGPoint3SI>(), point_ctor.property("prototype"));
858 	globalObject().setProperty("VCGPoint3", point_ctor);
859 	//qScriptRegisterMetaType(this,Point3fToScriptValue,Point3fFromScriptValue);
860 	QScriptValue shot_ctor = newFunction(ShotSI_ctor);
861 	globalObject().setProperty(MLXMLElNames::shotType, shot_ctor);
862 	QScriptValue shot_defctor = newFunction(ShotSI_defctor);
863 	globalObject().setProperty(MLXMLElNames::shotType + "DefCtor", shot_defctor);
864 }
865 
~Env()866 Env::~Env()
867 {
868 	for (int ii = 0; ii < _tobedeleted.size(); ++ii)
869 		delete _tobedeleted[ii];
870 	_tobedeleted.clear();
871 }
872 
insertExpressionBinding(const QString & nm,const QString & exp)873 void Env::insertExpressionBinding(const QString& nm, const QString& exp)
874 {
875 	QString decl(nm + " = " + exp + ";");
876 	if (!nm.contains('.'))
877 		decl = "var " + decl;
878 
879 	QScriptValue res = evaluate(decl);
880 	if (res.isError())
881 		throw JavaScriptException(res.toString());
882 }
883 
insertParamsExpressionBinding(const QString & xmlpluginnamespace,const QString & pluginname,const QString & filtername,const QMap<QString,QString> & parvalmap)884 void Env::insertParamsExpressionBinding(const QString& xmlpluginnamespace, const QString& pluginname, const QString& filtername, const QMap<QString, QString>& parvalmap)
885 {
886 	/****************************************************************************************************************************************************************/
887 	/*the function takes the filter parameters in the map and it generates for each parameter a couple of declarations*/
888 	/*XMLPlugins.PluginName.FilterName.paramname = paramvalue;*/
889 	/*var paramname = XMLPlugins.PluginName.FilterName.paramname;*/
890 	/*WHY NOT JUST var paramname = paramvalue;??????????????????????????????????*/
891 	/*BECAUSE in this way it is possible to avoid problems with the naming of the persistent parameters inside the system register*/
892 	/*without having to call them inside the MeshLab XML file with really long name. In this way persistent parameters and non-persistent ones behave in the same way*/
893 	/*****************************************************************************************************************************************************************/
894 
895 	//XmlPlugins = {};
896 	QString namespaceassignment(" = {};\n");
897 	QString code = xmlpluginnamespace + namespaceassignment;
898 	//XmlPlugins.PluginName = {};
899 	code += xmlpluginnamespace + "." + pluginname + namespaceassignment;
900 	QString completenamespace = xmlpluginnamespace + "." + pluginname + "." + filtername;
901 	//XmlPlugins.PluginName.FilterName = {};
902 	code += completenamespace + namespaceassignment;
903 	for (QMap<QString, QString>::const_iterator cit = parvalmap.begin(); cit != parvalmap.end(); ++cit)
904 	{
905 		//XmlPlugins.PluginName.FilterName.varname
906 		QString vardecl = completenamespace + "." + cit.key();
907 		//XmlPlugins.PluginName.FilterName.varname = value;
908 		code += vardecl + " = " + cit.value() + ";\n";
909 	}
910 
911 	for (QMap<QString, QString>::const_iterator cit = parvalmap.begin(); cit != parvalmap.end(); ++cit)
912 	{
913 		//var varname = XmlPlugins.PluginName.Filtername.varname;
914 		QString decl("var " + cit.key() + " = " + completenamespace + "." + cit.key() + ";\n");
915 		code += decl;
916 	}
917 
918 	QScriptValue res = evaluate(code);
919 	if (res.isError())
920 		throw JavaScriptException(res.toString());
921 }
922 
output()923 QString Env::output()
924 {
925 	return out;
926 }
927 
appendOutput(const QString & output)928 void Env::appendOutput(const QString& output)
929 {
930 	out = out + output;
931 }
932 
loadMLScriptEnv(MeshDocument & md,PluginManager & pm)933 QScriptValue Env::loadMLScriptEnv(MeshDocument& md, PluginManager& pm)
934 {
935 	QString code;
936 	MeshDocumentSI* mi = new MeshDocumentSI(&md);
937 	_tobedeleted << mi;
938 	QScriptValue val = newQObject(mi);
939 	globalObject().setProperty(ScriptAdapterGenerator::meshDocVarName(), val);
940 	JavaScriptLanguage lang;
941 	code += lang.getExternalLibrariesCode();
942 	QScriptValue applyFun = newFunction(PluginInterfaceApplyXML, &pm);
943 	globalObject().setProperty("_applyFilter", applyFun);
944 	//QScriptValue res = env.evaluate(QString(PM.pluginsCode()));
945 	code += pm.pluginsCode();
946 	QScriptValue res = evaluate(code);
947 	return res;
948 }
949 
loadMLScriptEnv(MeshDocument & md,PluginManager & pm,const QMap<QString,QString> & global)950 QScriptValue Env::loadMLScriptEnv(MeshDocument& md, PluginManager& pm, const QMap<QString, QString>& global)
951 {
952 	QScriptValue res = loadMLScriptEnv(md, pm);
953 	if (res.isError())
954 		throw JavaScriptException("A current environment evaluation generated a JavaScript Error: " + res.toString() + "\n");
955 
956 	for (QMap<QString, QString>::const_iterator it = global.begin(); it != global.end(); ++it)
957 		insertExpressionBinding(Env::convertToAMLScriptValidName(it.key()), it.value());
958 	//insertParamsExpressionBinding(xmlpluginnamespace,pluginname, filtername,global);
959 
960 	return res;
961 }
962 
convertToAMLScriptValidName(const QString & name)963 QString Env::convertToAMLScriptValidName(const QString& name)
964 {
965 	QString cp(name);
966 	return cp.replace("::", "_");
967 }
968 
969 
ShotSI(const Shotm & st)970 ShotSI::ShotSI(const Shotm& st)
971 	:shot()
972 {
973 	shot.Intrinsics = st.Intrinsics;
974 	shot.Extrinsics = st.Extrinsics;
975 }
976 
ShotSI()977 ShotSI::ShotSI()
978 	:shot()
979 {
980 
981 }
982 
itSelf()983 Q_INVOKABLE ShotSI* ShotSI::itSelf()
984 {
985 	return this;
986 }
987 
vcgPoint2ToVector2(const Point2m & p)988 QVector<Scalarm> ScriptInterfaceUtilities::vcgPoint2ToVector2(const Point2m &p)
989 {
990 	QVector<Scalarm> vfl(2);
991 	for (int ii = 0; ii < 2; ++ii)
992 		vfl[ii] = p[ii];
993 	return vfl;
994 }
995 
vector2ToVcgPoint2(const QVector<Scalarm> & v)996 Point2m ScriptInterfaceUtilities::vector2ToVcgPoint2(const QVector<Scalarm>& v)
997 {
998 	return Point2m(v[0], v[1]);
999 }
1000 
1001 
vcgPoint3ToVector3(const Point3m & p)1002 QVector<Scalarm> ScriptInterfaceUtilities::vcgPoint3ToVector3(const Point3m& p)
1003 {
1004 	QVector<Scalarm> vfl(3);
1005 	for (int ii = 0; ii < 3; ++ii)
1006 		vfl[ii] = p[ii];
1007 	return vfl;
1008 }
1009 
vector3ToVcgPoint3(const QVector<Scalarm> & v)1010 Point3m ScriptInterfaceUtilities::vector3ToVcgPoint3(const QVector<Scalarm>& v)
1011 {
1012 	return Point3m(v[0], v[1], v[2]);
1013 }
1014 
vcgPoint4ToVector4(const Point4m & p)1015 QVector<Scalarm> ScriptInterfaceUtilities::vcgPoint4ToVector4(const Point4m& p)
1016 {
1017 	QVector<Scalarm> vfl(4);
1018 	for (int ii = 0; ii < 4; ++ii)
1019 		vfl[ii] = p[ii];
1020 	return vfl;
1021 }
1022 
vector4ToVcgPoint4(const QVector<Scalarm> & v)1023 Point4m ScriptInterfaceUtilities::vector4ToVcgPoint4(const QVector<Scalarm>& v)
1024 {
1025 	Point4m p;
1026 	for (int ii = 0; ii < 4; ++ii)
1027 		p[ii] = v[ii];
1028 	return p;
1029 }
1030 
vcgMatrix44ToVector16(const Matrix44m & m)1031 QVector<Scalarm> ScriptInterfaceUtilities::vcgMatrix44ToVector16(const Matrix44m& m)
1032 {
1033 	QVector<Scalarm> vfl(16);
1034 	for (int ii = 0; ii < 16; ++ii)
1035 		vfl[ii] = m[ii / 4][ii % 4];
1036 	return vfl;
1037 }
1038 
vector16ToVcgMatrix44(const QVector<Scalarm> & v)1039 Matrix44m ScriptInterfaceUtilities::vector16ToVcgMatrix44(const QVector<Scalarm>& v)
1040 {
1041 	Matrix44m m;
1042 	for (int ii = 0; ii < 4; ++ii)
1043 		for (int jj = 0; jj < 4; ++jj)
1044 			m[ii][jj] = v[ii * 4 + jj];
1045 	return m;
1046 }
1047 
vector2ToVcgPoint2i(const QVector<Scalarm> & v)1048 vcg::Point2i ScriptInterfaceUtilities::vector2ToVcgPoint2i(const QVector<Scalarm>& v)
1049 {
1050 	vcg::Point2i p;
1051 	for (int ii = 0; ii < 2; ++ii)
1052 		p[ii] = int(v[ii]);
1053 	return p;
1054 }
1055 
1056 
1057 
1058 
1059 
1060 
1061