1 /****************************************************************************
2 * MeshLab                                                           o o     *
3 * A versatile mesh processing toolbox                             o     o   *
4 *                                                                _   O  _   *
5 * Copyright(C) 2005                                                \/)\/    *
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 History
25 $Log: meshedit.cpp,v $
26 ****************************************************************************/
27 
28 #include "edit_align.h"
29 #include <common/GLExtensionsManager.h>
30 #include <meshlab/glarea.h>
31 #include <meshlab/stdpardialog.h>
32 #include <wrap/qt/trackball.h>
33 #include "AlignPairWidget.h"
34 #include "AlignPairDialog.h"
35 #include "align/align_parameter.h"
36 #include <vcg/space/point_matching.h>
37 using namespace vcg;
38 
EditAlignPlugin()39 EditAlignPlugin::EditAlignPlugin()
40 {
41     alignDialog=0;
42     qFont.setFamily("Helvetica");
43     qFont.setPixelSize(10);
44 
45     trackball.center=Point3f(0, 0, 0);
46     trackball.radius= 1;
47 }
48 
Info()49 const QString EditAlignPlugin::Info()
50 {
51     return tr("Allows one to align different layers together.");
52 }
53 
suggestedRenderingData(MeshModel &,MLRenderingData & dt)54 void EditAlignPlugin::suggestedRenderingData(MeshModel & /*m*/, MLRenderingData& dt)
55 {
56 	MLPerViewGLOptions opts;
57 	dt.get(opts);
58 	for (MLRenderingData::PRIMITIVE_MODALITY pr = MLRenderingData::PRIMITIVE_MODALITY(0); pr < MLRenderingData::PR_ARITY; pr = MLRenderingData::next(pr))
59 	{
60 		MLRenderingData::RendAtts atts;
61 		dt.get(pr, atts);
62 
63 		atts[MLRenderingData::ATT_NAMES::ATT_VERTCOLOR] = false;
64 		if (pr == MLRenderingData::PR_SOLID)
65 			atts[MLRenderingData::ATT_NAMES::ATT_FACECOLOR] = false;
66 		dt.set(pr, atts);
67 	}
68 
69 	opts._perpoint_fixed_color_enabled = false;
70 	opts._perwire_fixed_color_enabled = false;
71 	opts._persolid_fixed_color_enabled = false;
72 
73 	opts._perpoint_mesh_color_enabled = true;
74 	opts._perwire_mesh_color_enabled = true;
75 	opts._persolid_mesh_color_enabled = true;
76 
77 	dt.set(opts);
78 
79 	/*switch (mode)
80 	{
81 		case ALIGN_MOVE:
82 		{
83 			_shared->setRenderingDataPerMeshView(m.id(), _gla->context(), dt);
84 			m.visible = false;
85 			break;
86 		}
87 		case ALIGN_IDLE:
88 		{
89 
90 			MLPerViewGLOptions opts;
91 			dt.get(opts);
92 			opts._perbbox_enabled = true;
93 			dt.set(opts);
94 
95 			_shared->setRenderingDataPerMeshView(m.id(), _gla->context(), dt);
96 		}
97 		case ALIGN_INSPECT_ARC:
98 		{
99 			break;
100 		}
101 	}*/
102 }
103 
StartEdit(MeshDocument & md,GLArea * gla,MLSceneGLSharedDataContext * cont)104 bool EditAlignPlugin::StartEdit(MeshDocument& md, GLArea * gla, MLSceneGLSharedDataContext* cont)
105 {
106     _md=&md;
107     _gla= gla;
108 	_shared = cont;
109 
110 	if ((_gla == NULL) || (_shared == NULL) || (md.meshList.size() < 1))
111 		return false;
112 
113 	//mainW->addDockWidget(Qt::LeftDockWidgetArea,alignDialog);
114 	mode = ALIGN_IDLE;
115     int numOfMeshes = _md->meshList.size();
116     meshTree.clear();
117     foreach(MeshModel *mm, _md->meshList)
118     {
119 
120         // assigns random color: if less than 50 meshes, color is truly unique, and the less meshes, the more different they will be
121         // if above 50, truly unique color would geenrate too similar colors, so total number of unique color
122         // is capped to 50 and the color reused, id that are close will have different color anyway
123 		if (mm != NULL)
124 		{
125 			if (numOfMeshes < 50)
126 				mm->cm.C() = Color4b::Scatter(numOfMeshes + 1, mm->id(), .2f, .7f);
127 			else
128 				mm->cm.C() = Color4b::Scatter(51, mm->id() % 50, .2f, .7f);
129 			mm->updateDataMask(MeshModel::MM_COLOR);
130 //			meshTree.nodeList.push_back(new MeshNode(mm));
131             meshTree.nodeMap[mm->id()]=new MeshNode(mm);
132 		}
133     }
134 
135 //for(QMap<int,RenderMode>::iterator it = _gla->rendermodemap.begin();it != _gla->rendermodemap.end();++it)
136 //    it.value().colorMode=GLW::CMPerMesh;
137 
138     _gla->setCursor(QCursor(QPixmap(":/images/cur_align.png"),1,1));
139     if(alignDialog==0)
140     {
141         if (!GLExtensionsManager::initializeGLextensions_notThrowing())
142 			return false;
143 
144         alignDialog=new AlignDialog(_gla->window(),this);
145         connect(alignDialog->ui.meshTreeParamButton,SIGNAL(clicked()),this,SLOT(meshTreeParam()));
146         connect(alignDialog->ui.icpParamButton,SIGNAL(clicked()),this,SLOT(alignParam()));
147 		connect(alignDialog->ui.icpParamDefMMButton, SIGNAL(clicked()), this, SLOT(setAlignParamMM()));
148 		connect(alignDialog->ui.icpParamDefMButton, SIGNAL(clicked()), this, SLOT(setAlignParamM()));
149         connect(alignDialog->ui.icpParamCurrentButton,SIGNAL(clicked()),this,SLOT(alignParamCurrent()));
150         connect(alignDialog->ui.icpButton,SIGNAL(clicked()),this,SLOT(process()));
151         connect(alignDialog->ui.manualAlignButton,SIGNAL(clicked()),this,SLOT(glueManual()));
152         connect(alignDialog->ui.pointBasedAlignButton,SIGNAL(clicked()),this,SLOT(glueByPicking()));
153         connect(alignDialog->ui.glueHereButton,SIGNAL(clicked()),this,SLOT(glueHere()));
154         connect(alignDialog->ui.glueHereAllButton,SIGNAL(clicked()),this,SLOT(glueHereVisible()));
155         connect(alignDialog->ui.recalcButton, SIGNAL(clicked()) , this,  SLOT(recalcCurrentArc() ) );
156         connect(alignDialog->ui.hideRevealButton,  SIGNAL(clicked()) , this,  SLOT(hideRevealGluedMesh() ) );
157         connect(alignDialog, SIGNAL(updateMeshSetVisibilities() ), _gla,SLOT(updateMeshSetVisibilities()));
158         connect(alignDialog->ui.baseMeshButton, SIGNAL(clicked()) , this,  SLOT(setBaseMesh() ) );
159         connect(alignDialog->ui.badArcButton, SIGNAL(clicked()) , this,  SLOT(selectBadArc() ) );
160     }
161 
162     //alignDialog->setCurrentNode(meshTree.find(gla->mm()) );
163     alignDialog->setTree(& meshTree);
164     alignDialog->show();
165     //alignDialog->adjustSize();
166 
167     connect(this, SIGNAL(suspendEditToggle()),_gla,SLOT(suspendEditToggle()) );
168     connect(alignDialog, SIGNAL(closing()),_gla,SLOT(endEdit()) );
169     connect(_md,SIGNAL(currentMeshChanged(int)),alignDialog,SLOT(currentMeshChanged(int)));
170     suspendEditToggle();
171     return true;
172 }
173 
Decorate(MeshModel & mm,GLArea * gla)174 void EditAlignPlugin::Decorate(MeshModel & mm, GLArea * gla)
175 {
176 	glPushAttrib(GL_ALL_ATTRIB_BITS);
177 
178 	_gla = gla;
179 	if (mode == ALIGN_IDLE)
180 	{
181 		MLRenderingData tmp;
182 		MLPerViewGLOptions opts;
183 		tmp.get(opts);
184 		opts._perbbox_enabled = true;
185 		tmp.set(opts);
186 		_shared->drawAllocatedAttributesSubset(mm.id(), _gla->context(), tmp);
187 		if ((alignDialog != NULL) && (alignDialog->currentArc != 0))
188 			DrawArc(alignDialog->currentArc);
189 	}
190 
191 	if (mode == ALIGN_MOVE)
192 	{
193 		MLRenderingData dt;
194 		_shared->getRenderInfoPerMeshView(mm.id(), _gla->context(), dt);
195 		MLPerViewGLOptions opts;
196 		dt.get(opts);
197 		opts._perbbox_enabled = false;
198 		dt.set(opts);
199 
200 		glPushMatrix();
201 		trackball.GetView();
202 		trackball.Apply();
203 		_shared->drawAllocatedAttributesSubset(mm.id(), _gla->context(),dt);
204 		glPopMatrix();
205 	}
206 	glPopAttrib();
207 }
208 
EndEdit(MeshModel &,GLArea *,MLSceneGLSharedDataContext *)209 void EditAlignPlugin::EndEdit(MeshModel &/*m*/, GLArea * /*parent*/, MLSceneGLSharedDataContext* /*cont*/)
210 {
211 
212     // some cleaning at the end.
213     qDebug("EndEdit: cleaning everything");
214     meshTree.clear();
215     delete alignDialog;
216     alignDialog=0;
217 }
218 
hideRevealGluedMesh()219 void EditAlignPlugin::hideRevealGluedMesh()
220 {
221   //    foreach(MeshNode *mn, meshTree.nodeList)
222   for(auto ni=meshTree.nodeMap.begin();ni!=meshTree.nodeMap.end();++ni)
223   {
224     MeshNode *mn=ni->second;
225         if(!mn->glued) mn->m->visible=!(mn->m->visible);
226   }
227     alignDialog->rebuildTree();
228     _gla->update();
229     alignDialog->updateMeshVisibilities();
230 }
231 
setBaseMesh()232 void EditAlignPlugin::setBaseMesh()
233 {
234     Matrix44d oldTr = Matrix44d::Construct(_md->mm()->cm.Tr);
235     Matrix44d inv = Inverse(oldTr);
236     _md->mm()->cm.Tr.SetIdentity();
237 
238     //foreach(MeshNode *mn, meshTree.nodeList)
239     for(auto ni=meshTree.nodeMap.begin();ni!=meshTree.nodeMap.end();++ni)
240     {
241       MeshNode *mn=ni->second;
242       if(mn->glued && (mn->m != _md->mm()) )
243             mn->m->cm.Tr.Import(inv*Matrix44d::Construct(mn->m->cm.Tr));
244     }
245 
246     alignDialog->rebuildTree();
247     _gla->update();
248 }
249 
250 
glueByPicking()251 void EditAlignPlugin::glueByPicking()
252 {
253     if(meshTree.gluedNum()<1)
254     {
255         QMessageBox::warning(0,"Align tool", "Point-based aligning requires at least one glued  mesh");
256         return;
257     }
258 
259     //Matrix44f oldTr = md->mm()->cm.Tr;
260     AlignPairDialog *dd=new AlignPairDialog(_gla,this->alignDialog);
261     dd->aa->initMesh(currentNode(), &meshTree);
262     dd->exec();
263 
264     if(dd->result()==QDialog::Rejected)
265 		return;
266 
267     // i picked points sono in due sistemi di riferimento.
268 
269     std::vector<vcg::Point3f>freePnt = dd->aa->freePickedPointVec;
270     std::vector<vcg::Point3f>gluedPnt= dd->aa->gluedPickedPointVec;
271 
272     if( (freePnt.size() != gluedPnt.size())	|| (freePnt.size()==0) )	{
273         QMessageBox::warning(0,"Align tool", "ERROR: alignment requires the same number of chosen points");
274         return;
275     }
276 
277     Matrix44f res;
278     if ((dd != NULL) && (dd->aa != NULL) && (dd->aa->allowscaling))
279         ComputeSimilarityMatchMatrix(gluedPnt,freePnt,res);
280     else
281         ComputeRigidMatchMatrix(gluedPnt,freePnt,res);
282 
283     //md->mm()->cm.Tr=res;
284 	currentNode()->tr() = currentNode()->tr() * res;
285     QString buf;
286     // for(size_t i=0;i<freePnt.size();++i)
287     //		meshTree.cb(0,qUtf8Printable(buf.sprintf("%f %f %f -- %f %f %f \n",freePnt[i][0],freePnt[i][1],freePnt[i][2],gluedPnt[i][0],gluedPnt[i][1],gluedPnt[i][2])));
288 
289     assert(currentNode()->glued==false);
290 
291     currentNode()->glued=true;
292     alignDialog->rebuildTree();
293     _gla->update();
294 }
295 
296 
glueManual()297 void EditAlignPlugin::glueManual()
298 {
299     assert(currentNode()->glued==false);
300 
301 	if ((_md == NULL) || (_md->mm() == NULL) || (_gla == NULL) || (_gla->mvc() == NULL))
302 		return;
303 
304 	MeshModel *mm=_md->mm();
305 
306 	static QString oldLabelButton;
307     Matrix44f tran,mtran, tmp;
308 
309     switch(mode)
310     {
311 		case ALIGN_IDLE:
312 		{
313 			emit suspendEditToggle();
314 			mode = ALIGN_MOVE;
315 			mm->visible = false;
316 			trackball.Reset();
317 			trackball.center.Import(mm->cm.trBB().Center());
318 			trackball.radius = mm->cm.trBB().Diag() / 2.0;
319 			toggleButtons();
320 			oldLabelButton = alignDialog->ui.manualAlignButton->text();
321 			alignDialog->ui.manualAlignButton->setText("Accept Transformation");
322 			break;
323 		}
324 
325 		case ALIGN_MOVE:  // stop manual alignment and freeze the mesh
326 		{
327 			emit suspendEditToggle();
328 			mode = ALIGN_IDLE;
329 			toggleButtons();
330 			tran.SetTranslate(trackball.center);
331 			mtran.SetTranslate(-trackball.center);
332 			tmp.Import(mm->cm.Tr);
333 			mm->cm.Tr.Import((tran)* trackball.track.Matrix()*(mtran)* tmp);
334 			mm->visible = true;
335 			alignDialog->ui.manualAlignButton->setText(oldLabelButton);
336 			currentNode()->glued = true;
337 			alignDialog->rebuildTree();
338 			break;
339 		}
340 		default : assert("entered in the GlueManual slot in the wrong state"==0);
341 	}
342 
343     _gla->update();
344 }
345 
alignParamCurrent()346 void EditAlignPlugin:: alignParamCurrent()
347 {
348     assert(currentArc());
349 
350     RichParameterSet alignParamSet;
351     QString titleString=QString("Current Arc (%1 -> %2) Alignment Parameters").arg(currentArc()->MovName).arg(currentArc()->FixName);
352     AlignParameter::AlignPairParamToRichParameterSet(currentArc()->ap, alignParamSet);
353 
354     GenericParamDialog ad(alignDialog,&alignParamSet,titleString);
355     ad.setWindowFlags(Qt::Dialog);
356     ad.setWindowModality(Qt::WindowModal);
357     int result=ad.exec();
358     if(result != QDialog::Accepted) return;
359 
360     // Dialog accepted. get back the values
361     AlignParameter::RichParameterSetToAlignPairParam(alignParamSet, currentArc()->ap);
362 }
363 
meshTreeParam()364 void EditAlignPlugin:: meshTreeParam()
365 {
366   RichParameterSet  meshTreeParamSet;
367   AlignParameter::MeshTreeParamToRichParameterSet(defaultMTP, meshTreeParamSet);
368   GenericParamDialog ad(alignDialog,&meshTreeParamSet,"Default Alignment Parameters");
369   ad.setWindowFlags(Qt::Dialog);
370   ad.setWindowModality(Qt::WindowModal);
371   int result=ad.exec();
372   if(result != QDialog::Accepted) return;
373   // Dialog accepted. get back the values
374   AlignParameter::RichParameterSetToMeshTreeParam(meshTreeParamSet, defaultMTP);
375 
376 }
377 
alignParam()378 void EditAlignPlugin:: alignParam()
379 {
380     RichParameterSet alignParamSet;
381     AlignParameter::AlignPairParamToRichParameterSet(defaultAP, alignParamSet);
382     GenericParamDialog ad(alignDialog,&alignParamSet,"Default Alignment Parameters");
383     ad.setWindowFlags(Qt::Dialog);
384     ad.setWindowModality(Qt::WindowModal);
385     int result=ad.exec();
386     if(result != QDialog::Accepted) return;
387     // Dialog accepted. get back the values
388     AlignParameter::RichParameterSetToAlignPairParam(alignParamSet, defaultAP);
389 }
390 
setAlignParamMM()391 void EditAlignPlugin::setAlignParamMM()
392 {
393 	defaultAP.SampleNum = 2000;
394 	defaultAP.MinDistAbs = 10.0;
395 	defaultAP.TrgDistAbs = 0.005;
396 	defaultAP.MaxIterNum = 75;
397 	defaultAP.ReduceFactorPerc = 0.8;
398 	defaultAP.PassHiFilter = 0.75;
399 	defaultAP.MatchMode = AlignPair::Param::MMRigid;
400 	QMessageBox::warning(0, "Align tool", "ICP Default Parameters set for MILLIMETERS");
401 }
402 
setAlignParamM()403 void EditAlignPlugin::setAlignParamM()
404 {
405 	defaultAP.SampleNum = 2000;
406 	defaultAP.MinDistAbs = 0.3;
407 	defaultAP.TrgDistAbs = 0.0005;
408 	defaultAP.MaxIterNum = 75;
409 	defaultAP.ReduceFactorPerc = 0.8;
410 	defaultAP.PassHiFilter = 0.75;
411 	defaultAP.MatchMode = AlignPair::Param::MMRigid;
412 	QMessageBox::warning(0, "Align tool", "ICP Default Parameters set for METERS");
413 }
414 
glueHere()415 void EditAlignPlugin::glueHere()
416 {
417     MeshNode *mn=currentNode();
418     if(mn->glued)
419       meshTree.deleteResult(mn);
420 
421     mn->glued = !mn->glued;
422     alignDialog->rebuildTree();
423 }
424 
glueHereVisible()425 void EditAlignPlugin::glueHereVisible()
426 {
427   for(auto ni=meshTree.nodeMap.begin();ni!=meshTree.nodeMap.end();++ni)
428 //    foreach(MeshNode *mn, meshTree.nodeList)
429       if(ni->second->m->visible) ni->second->glued=true;
430 
431     alignDialog->rebuildTree();
432 }
433 
selectBadArc()434 void EditAlignPlugin::selectBadArc()
435 {
436   float maxErr=0;
437   AlignPair::Result *worseArc=0;
438   for(QList<vcg::AlignPair::Result>::iterator li=meshTree.resultList.begin();li!=meshTree.resultList.end();++li)
439   {
440     if(li->err > maxErr)
441     {
442       maxErr=li->err;
443       worseArc=&*li;
444     }
445   }
446   if(worseArc)
447     alignDialog->setCurrentArc(worseArc);
448 }
449 
450 
process()451 void EditAlignPlugin::process()
452 {
453     if(meshTree.gluedNum()<2)
454     {
455         QMessageBox::warning(0,"Align tool", "ICP Process can only work when at least two layers have been glued");
456         return;
457     }
458     alignDialog->setEnabled(false);
459     meshTree.Process(defaultAP, defaultMTP);
460     alignDialog->rebuildTree();
461     _gla->update();
462     alignDialog->setEnabled(true);
463 }
464 
recalcCurrentArc()465 void EditAlignPlugin::recalcCurrentArc()
466 {
467     assert(currentArc());
468 
469     alignDialog->setEnabled(false);
470     meshTree.ProcessArc(currentArc()->FixName,currentArc()->MovName,*currentArc(),currentArc()->ap);
471     meshTree.ProcessGlobal(currentArc()->ap);
472     AlignPair::Result *recomputedArc = currentArc();
473     alignDialog->rebuildTree();
474     alignDialog->setCurrentArc(recomputedArc);
475     alignDialog->setEnabled(true);
476     _gla->update();
477 }
478 
479 
mousePressEvent(QMouseEvent * e,MeshModel &,GLArea *)480 void EditAlignPlugin::mousePressEvent(QMouseEvent *e, MeshModel &, GLArea * )
481 {
482     if(mode==ALIGN_MOVE)
483     {
484         trackball.MouseDown(e->x(),_gla->height()-e->y(), QT2VCG(e->button(), e->modifiers() ) );
485         _gla->update();
486     }
487 }
488 
mouseMoveEvent(QMouseEvent * e,MeshModel &,GLArea *)489 void EditAlignPlugin::mouseMoveEvent(QMouseEvent *e, MeshModel &, GLArea * )
490 {
491     if(mode==ALIGN_MOVE)
492     {
493         trackball.MouseMove(e->x(),_gla->height()-e->y() );
494         _gla->update();
495     }
496 
497 }
498 
mouseReleaseEvent(QMouseEvent * e,MeshModel &,GLArea *)499 void EditAlignPlugin::mouseReleaseEvent(QMouseEvent * e, MeshModel &/*m*/, GLArea * )
500 {
501     if(mode==ALIGN_MOVE)
502     {
503         trackball.MouseUp(e->x(),_gla->height()-e->y(), QT2VCG(e->button(), e->modifiers() ) );
504         _gla->update();
505     }
506 }
507 
508 
509 // this function toggles on and off all the buttons (according to the "modal" states of the interface),
510 // do not confuse it with the updatebuttons function of the alignDialog class.
toggleButtons()511 void EditAlignPlugin::toggleButtons()
512 {
513     switch(mode)
514     {
515     case	ALIGN_MOVE:
516         alignDialog->ui.manualAlignButton->setEnabled(true);
517 		alignDialog->ui.glueHereButton->setEnabled(false);
518 		alignDialog->ui.glueHereAllButton->setEnabled(false);
519 		alignDialog->ui.pointBasedAlignButton->setEnabled(false);
520 		alignDialog->ui.baseMeshButton->setEnabled(false);
521 		alignDialog->ui.hideRevealButton->setEnabled(false);
522 		alignDialog->ui.icpButton->setEnabled(false);
523 		alignDialog->ui.icpParamButton->setEnabled(false);
524 		alignDialog->ui.icpParamDefMMButton->setEnabled(false);
525 		alignDialog->ui.icpParamDefMButton->setEnabled(false);
526 		alignDialog->ui.meshTreeParamButton->setEnabled(false);
527 		alignDialog->ui.badArcButton->setEnabled(false);
528 		alignDialog->ui.icpParamCurrentButton->setEnabled(false);
529 		alignDialog->ui.recalcButton->setEnabled(false);
530         alignDialog->ui.alignTreeWidget->setEnabled(false);
531 
532         break;
533     case	ALIGN_IDLE:
534         alignDialog->ui.manualAlignButton->setEnabled(true);
535 		alignDialog->ui.glueHereButton->setEnabled(true);
536 		alignDialog->ui.glueHereAllButton->setEnabled(true);
537 		alignDialog->ui.pointBasedAlignButton->setEnabled(true);
538 		alignDialog->ui.baseMeshButton->setEnabled(true);
539 		alignDialog->ui.hideRevealButton->setEnabled(true);
540 		alignDialog->ui.icpButton->setEnabled(true);
541 		alignDialog->ui.icpParamButton->setEnabled(true);
542 		alignDialog->ui.icpParamDefMMButton->setEnabled(true);
543 		alignDialog->ui.icpParamDefMButton->setEnabled(true);
544 		alignDialog->ui.meshTreeParamButton->setEnabled(true);
545 		alignDialog->ui.badArcButton->setEnabled(true);
546 		alignDialog->ui.icpParamCurrentButton->setEnabled(true);
547 		alignDialog->ui.recalcButton->setEnabled(true);
548 		alignDialog->ui.alignTreeWidget->setEnabled(true);
549 		alignDialog->updateButtons();
550         break;
551     }
552 }
553 
DrawArc(vcg::AlignPair::Result * A)554 void EditAlignPlugin::DrawArc(vcg::AlignPair::Result *A )
555 {
556     unsigned int i;
557     AlignPair::Result &r=*A;
558     MeshNode *fix=meshTree.find(r.FixName);
559     MeshNode *mov=meshTree.find(r.MovName);
560     //int mov=FindMesh(r.MovName);
561     double nl=2.0*(*fix).bbox().Diag()/100.0;
562     glPushAttrib(GL_ENABLE_BIT );
563 
564     glDisable(GL_LIGHTING);
565 
566     glPushMatrix();
567     glMultMatrix(fix->tr());
568     glPointSize(5.0f);
569     glColor3f(1,0,0);
570     glBegin(GL_POINTS);
571     for(i=0;i<r.Pfix.size();i++) glVertex(r.Pfix[i]);
572     glEnd();
573     glPointSize(1.0f);
574     //glColor((*fix).mi.c);
575     if(r.Nfix.size()==r.Pfix.size())
576     {
577         glBegin(GL_LINES);
578         for(i=0;i<r.Pfix.size();i++) {
579             glVertex(r.Pfix[i]);
580             glVertex(r.Pfix[i]+r.Nfix[i]*nl);
581         }
582         glEnd();
583     }
584 
585     glPopMatrix();
586     glPushMatrix();
587     glMultMatrix(mov->tr());
588 
589     glPointSize(5.0f);
590     glColor3f(0,0,1);
591     glBegin(GL_POINTS);
592     for(i=0;i<r.Pmov.size();i++) glVertex(r.Pmov[i]);
593     glEnd();
594     glPointSize(1.0f);
595     //glColor((*mov).mi.c);
596     if(r.Nmov.size()==r.Pmov.size())
597     {
598         glBegin(GL_LINES);
599         for(i=0;i<r.Pmov.size();i++) {
600             glVertex(r.Pmov[i]);
601             glVertex(r.Pmov[i]+r.Nmov[i]*nl);
602         }
603         glEnd();
604     }
605     glPopMatrix();
606     /*
607     // Now Draw the histogram
608 
609     int HSize = ViewPort[2]-100;
610     r.H.glDraw(Point4i(20,80,HSize,100),dlFont,r.as.I[0].MinDistAbs,1);
611     */
612     glPopAttrib();
613 
614 }
615 
616 
617 
618