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