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 #include "edit_select.h"
25 #include <common/GLExtensionsManager.h>
26 #include <wrap/gl/pick.h>
27 #include <wrap/qt/device_to_logical.h>
28 #include <meshlab/glarea.h>
29 #include <vcg/space/intersection2.h>
30
31
32 using namespace std;
33 using namespace vcg;
34
EditSelectPlugin(int ConnectedMode)35 EditSelectPlugin::EditSelectPlugin(int ConnectedMode) :selectionMode(ConnectedMode) {
36 isDragging = false;
37 }
38
Info()39 QString EditSelectPlugin::Info()
40 {
41 return tr("Interactive selection inside a dragged rectangle in screen space");
42 }
43
suggestedRenderingData(MeshModel &,MLRenderingData & dt)44 void EditSelectPlugin::suggestedRenderingData(MeshModel & /*m*/, MLRenderingData & dt)
45 {
46 MLPerViewGLOptions opts;
47 dt.get(opts);
48 opts._sel_enabled = true;
49
50 if ((selectionMode == SELECT_FACE_MODE) || (selectionMode == SELECT_CONN_MODE))
51 opts._face_sel = true;
52
53 if (selectionMode == SELECT_VERT_MODE)
54 opts._vertex_sel = true;
55
56 if (selectionMode == SELECT_AREA_MODE)
57 {
58 opts._face_sel = true;
59 opts._vertex_sel = true;
60 }
61
62 dt.set(opts);
63 }
64
keyReleaseEvent(QKeyEvent * e,MeshModel & m,GLArea * gla)65 void EditSelectPlugin::keyReleaseEvent(QKeyEvent *e, MeshModel &m, GLArea *gla)
66 {
67 // global "all" commands
68 if (e->key() == Qt::Key_A) // select all
69 {
70 if (areaMode == 0){ // vertices
71 tri::UpdateSelection<CMeshO>::VertexAll(m.cm);
72 gla->updateSelection(m.id(), true, false);
73 }
74 else if (areaMode == 1){ //faces
75 tri::UpdateSelection<CMeshO>::FaceAll(m.cm);
76 gla->updateSelection(m.id(), false, true);
77 }
78 gla->update();
79 e->accept();
80 }
81
82 if (e->key() == Qt::Key_D) // deselect all
83 {
84 if (areaMode == 0){ // vertices
85 tri::UpdateSelection<CMeshO>::VertexClear(m.cm);
86 gla->updateSelection(m.id(), true, false);
87 }
88 else if (areaMode == 1){ //faces
89 tri::UpdateSelection<CMeshO>::FaceClear(m.cm);
90 gla->updateSelection(m.id(), false, true);
91 }
92 gla->update();
93 e->accept();
94 }
95
96 if (e->key() == Qt::Key_I) // invert all
97 {
98 if (areaMode == 0){ // vertices
99 tri::UpdateSelection<CMeshO>::VertexInvert(m.cm);
100 gla->updateSelection(m.id(), true, false);
101 }
102 else if (areaMode == 1){ //faces
103 tri::UpdateSelection<CMeshO>::FaceInvert(m.cm);
104 gla->updateSelection(m.id(), false, true);
105 }
106 gla->update();
107 e->accept();
108 }
109
110
111 if (selectionMode == SELECT_AREA_MODE)
112 {
113 if (e->key() == Qt::Key_T) // toggle pick mode
114 {
115 areaMode = (areaMode + 1) % 2;
116 gla->update();
117 e->accept();
118 }
119
120 if (e->key() == Qt::Key_C) // clear Polyline
121 {
122 selPolyLine.clear();
123 gla->update();
124 e->accept();
125 }
126
127 if (e->key() == Qt::Key_Backspace) // remove last point Polyline
128 {
129 if (selPolyLine.size() > 0)
130 selPolyLine.pop_back();
131 gla->update();
132 e->accept();
133 }
134
135 if (e->key() == Qt::Key_Q) // add to selection
136 {
137 doSelection(m, gla, 0);
138 gla->update();
139 e->accept();
140 }
141
142 if (e->key() == Qt::Key_W) // sub from selection
143 {
144 doSelection(m, gla, 1);
145 gla->update();
146 e->accept();
147 }
148
149 if (e->key() == Qt::Key_E) // invert selection
150 {
151 doSelection(m, gla, 2);
152 gla->update();
153 e->accept();
154 }
155 gla->setCursor(QCursor(QPixmap(":/images/sel_area.png"), 1, 1));
156 }
157 else
158 {
159 gla->setCursor(QCursor(QPixmap(":/images/sel_rect.png"), 1, 1));
160 Qt::KeyboardModifiers mod = QApplication::queryKeyboardModifiers();
161 if(selectionMode == SELECT_VERT_MODE)
162 {
163 if (mod & Qt::ControlModifier)
164 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_plus.png"), 1, 1));
165 else if (mod & Qt::ShiftModifier)
166 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_minus.png"), 1, 1));
167 }
168 else
169 {
170 if (mod & Qt::AltModifier)
171 {
172 if (mod & Qt::ControlModifier)
173 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_plus_eye.png"), 1, 1));
174 else if (mod & Qt::ShiftModifier)
175 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_minus_eye.png"), 1, 1));
176 else
177 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_eye.png"), 1, 1));
178 }
179 else
180 {
181 if (mod & Qt::ControlModifier)
182 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_plus.png"), 1, 1));
183 else if (mod & Qt::ShiftModifier)
184 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_minus.png"), 1, 1));
185 }
186 }
187 }
188
189 }
190
doSelection(MeshModel & m,GLArea * gla,int mode)191 void EditSelectPlugin::doSelection(MeshModel &m, GLArea *gla, int mode)
192 {
193 QImage bufQImg(this->viewpSize[2],this->viewpSize[3],QImage::Format_RGB32);
194 bufQImg.fill(Qt::white);
195 QPainter bufQPainter(&bufQImg);
196 vector<QPointF> qpoints;
197 for(size_t i=0;i<selPolyLine.size();++i)
198 qpoints.push_back(QPointF(selPolyLine[i][0],selPolyLine[i][1]));
199 bufQPainter.setBrush(QBrush(Qt::black));
200 bufQPainter.drawPolygon(&qpoints[0],qpoints.size(), Qt::WindingFill);
201 QRgb blk=QColor(Qt::black).rgb();
202
203
204 static Eigen::Matrix<Scalarm,4,4> LastSelMatrix;
205 static vector<Point3m> projVec;
206 static MeshModel *lastMeshModel=0;
207 if((LastSelMatrix != SelMatrix) || lastMeshModel != &m)
208 {
209 GLPickTri<CMeshO>::FillProjectedVector(m.cm,projVec,this->SelMatrix,this->SelViewport);
210 LastSelMatrix=this->SelMatrix;
211 lastMeshModel=&m;
212 }
213
214 if (areaMode == 0) // vertices
215 {
216 for (size_t vi = 0; vi<m.cm.vert.size(); ++vi) if (!m.cm.vert[vi].IsD())
217 {
218 bool res=false;
219 if ((projVec[vi][2] <= -1.0) || (projVec[vi][2] >= 1.0) ||
220 (projVec[vi][0] <= 0) || (projVec[vi][0] >= this->viewpSize[2]) ||
221 (projVec[vi][1] <= 0) || (projVec[vi][1] >= this->viewpSize[3]))
222 res = false;
223 else
224 {
225 res = (bufQImg.pixel( projVec[vi][0],projVec[vi][1]) == blk);
226 }
227 if (res)
228 switch(mode){
229 case 0: m.cm.vert[vi].SetS(); break;
230 case 1: m.cm.vert[vi].ClearS(); break;
231 case 2: m.cm.vert[vi].IsS() ? m.cm.vert[vi].ClearS() : m.cm.vert[vi].SetS();
232 }
233 }
234 gla->updateSelection(m.id(), true, false);
235 }
236 else if (areaMode == 1) //faces
237 {
238 for (size_t fi = 0; fi < m.cm.face.size(); ++fi) if (!m.cm.face[fi].IsD())
239 {
240 bool res=false;
241 for (int vi = 0; vi < 3 && !res ; vi++)
242 {
243 int vInd=tri::Index(m.cm,m.cm.face[fi].V(vi));
244 if ((projVec[vInd][2] <= -1.0) || (projVec[vInd][2] >= 1.0) ||
245 (projVec[vInd][0] <= 0) || (projVec[vInd][0] >= this->viewpSize[2]) ||
246 (projVec[vInd][1] <= 0) || (projVec[vInd][1] >= this->viewpSize[3]))
247 res = false;
248 else
249 res = (bufQImg.pixel( projVec[vInd][0],projVec[vInd][1]) == blk);
250 }
251
252 if (res) // do the actual selection
253 {
254 switch(mode){
255 case 0: m.cm.face[fi].SetS(); break;
256 case 1: m.cm.face[fi].ClearS(); break;
257 case 2: m.cm.face[fi].IsS() ? m.cm.face[fi].ClearS() : m.cm.face[fi].SetS();
258 }
259 }
260 }
261 gla->updateSelection(m.id(), false, true);
262 }
263
264 }
265
keyPressEvent(QKeyEvent *,MeshModel &,GLArea * gla)266 void EditSelectPlugin::keyPressEvent(QKeyEvent * /*event*/, MeshModel & /*m*/, GLArea *gla)
267 {
268 if (selectionMode == SELECT_AREA_MODE)
269 return;
270
271 gla->setCursor(QCursor(QPixmap(":/images/sel_rect.png"), 1, 1));
272 Qt::KeyboardModifiers mod = QApplication::queryKeyboardModifiers();
273 if(selectionMode == SELECT_VERT_MODE)
274 {
275 if (mod & Qt::ControlModifier)
276 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_plus.png"), 1, 1));
277 else if (mod & Qt::ShiftModifier)
278 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_minus.png"), 1, 1));
279 }
280 else
281 {
282 if (mod & Qt::AltModifier)
283 {
284 if (mod & Qt::ControlModifier)
285 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_plus_eye.png"), 1, 1));
286 else if (mod & Qt::ShiftModifier)
287 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_minus_eye.png"), 1, 1));
288 else
289 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_eye.png"), 1, 1));
290 }
291 else
292 {
293 if (mod & Qt::ControlModifier)
294 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_plus.png"), 1, 1));
295 else if (mod & Qt::ShiftModifier)
296 gla->setCursor(QCursor(QPixmap(":/images/sel_rect_minus.png"), 1, 1));
297 }
298 }
299 }
300
mousePressEvent(QMouseEvent * event,MeshModel & m,GLArea * gla)301 void EditSelectPlugin::mousePressEvent(QMouseEvent * event, MeshModel &m, GLArea *gla)
302 {
303 if (selectionMode == SELECT_AREA_MODE)
304 {
305 selPolyLine.push_back(QTLogicalToOpenGL(gla, event->pos()));
306 return;
307 }
308
309 LastSelVert.clear();
310 LastSelFace.clear();
311
312 if ((event->modifiers() & Qt::ControlModifier) ||
313 (event->modifiers() & Qt::ShiftModifier))
314 {
315 CMeshO::FaceIterator fi;
316 for (fi = m.cm.face.begin(); fi != m.cm.face.end(); ++fi)
317 if (!(*fi).IsD() && (*fi).IsS())
318 LastSelFace.push_back(&*fi);
319
320 CMeshO::VertexIterator vi;
321 for (vi = m.cm.vert.begin(); vi != m.cm.vert.end(); ++vi)
322 if (!(*vi).IsD() && (*vi).IsS())
323 LastSelVert.push_back(&*vi);
324 }
325
326 composingSelMode = SMClear;
327 if (event->modifiers() & Qt::ControlModifier)
328 composingSelMode = SMAdd;
329 else if (event->modifiers() & Qt::ShiftModifier)
330 composingSelMode = SMSub;
331
332 if (event->modifiers() & Qt::AltModifier)
333 selectFrontFlag = true;
334 else
335 selectFrontFlag = false;
336
337 start = QTLogicalToOpenGL(gla, event->pos());
338 cur = start;
339 return;
340 }
341
mouseMoveEvent(QMouseEvent * event,MeshModel &,GLArea * gla)342 void EditSelectPlugin::mouseMoveEvent(QMouseEvent * event, MeshModel & /*m*/, GLArea * gla)
343 {
344 if (selectionMode == SELECT_AREA_MODE)
345 {
346 selPolyLine.back() = QTLogicalToOpenGL(gla, event->pos());
347 }
348 else
349 {
350 prev = cur;
351 cur = QTLogicalToOpenGL(gla, event->pos());
352 isDragging = true;
353 }
354 gla->update();
355
356 // // to avoid too frequent rendering
357 // if(gla->lastRenderingTime() < 200 )
358 // {
359 // }
360 // else{
361 // gla->makeCurrent();
362 // glDrawBuffer(GL_FRONT);
363 // DrawXORRect(gla,true);
364 // glDrawBuffer(GL_BACK);
365 // glFlush();
366 // }
367 }
368
mouseReleaseEvent(QMouseEvent * event,MeshModel &,GLArea * gla)369 void EditSelectPlugin::mouseReleaseEvent(QMouseEvent * event, MeshModel &/*m*/, GLArea * gla)
370 {
371 //gla->update();
372 if (gla == NULL)
373 return;
374
375 gla->updateAllSiblingsGLAreas();
376
377 if (selectionMode == SELECT_AREA_MODE)
378 {
379 selPolyLine.back() = QTLogicalToOpenGL(gla, event->pos());
380 return;
381 }
382
383 prev = cur;
384 cur = QTLogicalToOpenGL(gla, event->pos());
385 isDragging = false;
386 }
387
DrawXORPolyLine(GLArea * gla)388 void EditSelectPlugin::DrawXORPolyLine(GLArea * gla)
389 {
390 if (selPolyLine.size() == 0)
391 return;
392
393 glMatrixMode(GL_PROJECTION);
394 glPushMatrix();
395 glLoadIdentity();
396 glOrtho(0, QTDeviceWidth(gla), 0, QTDeviceHeight(gla), -1, 1);
397 glMatrixMode(GL_MODELVIEW);
398 glPushMatrix();
399 glLoadIdentity();
400 glPushAttrib(GL_ENABLE_BIT);
401 glDisable(GL_DEPTH_TEST);
402 glDisable(GL_LIGHTING);
403 glDisable(GL_TEXTURE_2D);
404 glEnable(GL_COLOR_LOGIC_OP);
405 glLogicOp(GL_XOR);
406 glColor3f(1, 1, 1);
407 glLineStipple(1, 0xAAAA);
408 glEnable(GL_LINE_STIPPLE);
409 glLineWidth(QTLogicalToDevice(gla,1));
410 //draw PolyLine
411 if (selPolyLine.size() == 1)
412 {
413 glBegin(GL_POINTS);
414 glVertex(selPolyLine[0]);
415 }
416 else if (selPolyLine.size() == 2)
417 {
418 glBegin(GL_LINES);
419 glVertex(selPolyLine[0]);
420 glVertex(selPolyLine[1]);
421 }
422 else
423 {
424 glBegin(GL_LINE_LOOP);
425 for (size_t ii = 0; ii < selPolyLine.size(); ii++)
426 glVertex(selPolyLine[ii]);
427 }
428 glEnd();
429
430 glDisable(GL_LOGIC_OP);
431 // Closing 2D
432 glPopAttrib();
433 glPopMatrix(); // restore modelview
434 glMatrixMode(GL_PROJECTION);
435 glPopMatrix();
436 glMatrixMode(GL_MODELVIEW);
437 }
438
DrawXORRect(GLArea * gla,bool doubleDraw)439 void EditSelectPlugin::DrawXORRect(GLArea * gla, bool doubleDraw)
440 {
441 glMatrixMode(GL_PROJECTION);
442 glPushMatrix();
443 glLoadIdentity();
444 glOrtho(0, QTDeviceWidth(gla), 0, QTDeviceHeight(gla), -1, 1);
445 glMatrixMode(GL_MODELVIEW);
446 glPushMatrix();
447 glLoadIdentity();
448 glPushAttrib(GL_ENABLE_BIT);
449 glDisable(GL_DEPTH_TEST);
450 glDisable(GL_LIGHTING);
451 glDisable(GL_TEXTURE_2D);
452 glEnable(GL_COLOR_LOGIC_OP);
453 glLogicOp(GL_XOR);
454 glColor3f(1, 1, 1);
455 if (doubleDraw)
456 {
457 glBegin(GL_LINE_LOOP);
458 glVertex(start);
459 glVertex2f(prev.X(), start.Y());
460 glVertex(prev);
461 glVertex2f(start.X(), prev.Y());
462 glEnd();
463 }
464 glBegin(GL_LINE_LOOP);
465 glVertex(start);
466 glVertex2f(cur.X(), start.Y());
467 glVertex(cur);
468 glVertex2f(start.X(), cur.Y());
469 glEnd();
470 glDisable(GL_LOGIC_OP);
471
472 // Closing 2D
473 glPopAttrib();
474 glPopMatrix(); // restore modelview
475 glMatrixMode(GL_PROJECTION);
476 glPopMatrix();
477 glMatrixMode(GL_MODELVIEW);
478
479 }
480
Decorate(MeshModel & m,GLArea * gla)481 void EditSelectPlugin::Decorate(MeshModel &m, GLArea * gla)
482 {
483 if (selectionMode == SELECT_AREA_MODE)
484 {
485 // get proj data of last rendering
486 glPushMatrix();
487 glMultMatrix(m.cm.Tr);
488 GLPickTri<CMeshO>::glGetMatrixAndViewport(this->SelMatrix, this->SelViewport);
489 glGetDoublev(GL_MODELVIEW_MATRIX, mvMatrix_f);
490 glGetDoublev(GL_PROJECTION_MATRIX, prMatrix_f);
491 glGetIntegerv(GL_VIEWPORT, viewpSize);
492 glPopMatrix();
493
494 // draw current poly
495 DrawXORPolyLine(gla);
496
497 // then, the status
498 QString line1 = "";
499 QString line2 = "";
500 QString line3 = "";
501 QString line4 = "";
502
503 if (areaMode == 0)
504 line1 = "Vertices Selection - T for faces";
505 else if (areaMode == 1)
506 line1 = "Faces Selection - T for vertices";
507
508 line2 = "C to clear polyline, BACKSPACE to remove last point";
509
510 if (selPolyLine.size() < 3)
511 line3 = "cannot select - more points needed";
512 else
513 line3 = "Q to add, W to subtract, E to invert";
514
515 line4 = "<br>A select all, D de-select all, I invert all";
516
517 this->RealTimeLog("Selection from Area", m.shortName(),
518 "%s<br>%s<br>%s<br>%s", line1.toStdString().c_str(), line2.toStdString().c_str(), line3.toStdString().c_str(), line4.toStdString().c_str());
519
520 return;
521 }
522 else
523 {
524 QString line1, line2, line3;
525
526 line1 = "Drag to select";
527 if ((selectionMode == SELECT_FACE_MODE) || (selectionMode == SELECT_CONN_MODE))
528 line2 = "you may hold:<br>- CTRL to add<br>- SHIFT to subtract<br>- ALT to select only visible";
529 else
530 line2 = "you may hold:<br>- CTRL to add<br>- SHIFT to subtract";
531 line3 = "<br>A select all, D de-select all, I invert all";
532
533 this->RealTimeLog("Interactive Selection", m.shortName(), "%s<br>%s<br>%s", line1.toStdString().c_str(), line2.toStdString().c_str(), line3.toStdString().c_str());
534 }
535
536 if (isDragging)
537 {
538 DrawXORRect(gla, false);
539 vector<CMeshO::FacePointer>::iterator fpi;
540 // Starting Sel
541 vector<CMeshO::FacePointer> NewSelFace;
542 Point2f mid = (start + cur) / 2;
543 Point2f wid = vcg::Abs(start - cur);
544
545 glPushMatrix();
546 glMultMatrix(m.cm.Tr);
547 if (selectionMode == SELECT_VERT_MODE)
548 {
549 //m.cm.selvert.clear();
550 vector<CMeshO::VertexPointer> NewSelVert;
551 vector<CMeshO::VertexPointer>::iterator vpi;
552
553 GLPickTri<CMeshO>::PickVert(mid[0], mid[1], m.cm, NewSelVert, wid[0], wid[1]);
554 glPopMatrix();
555 tri::UpdateSelection<CMeshO>::VertexClear(m.cm);
556
557 switch (composingSelMode)
558 {
559 case SMSub: // Subtract mode : The faces in the rect must be de-selected
560 for (vpi = LastSelVert.begin(); vpi != LastSelVert.end(); ++vpi)
561 (*vpi)->SetS();
562 for (vpi = NewSelVert.begin(); vpi != NewSelVert.end(); ++vpi)
563 (*vpi)->ClearS();
564 break;
565 case SMAdd: // Subtract mode : The faces in the rect must be de-selected
566 for (vpi = LastSelVert.begin(); vpi != LastSelVert.end(); ++vpi)
567 (*vpi)->SetS();
568 case SMClear: // Subtract mode : The faces in the rect must be de-selected
569 for (vpi = NewSelVert.begin(); vpi != NewSelVert.end(); ++vpi)
570 (*vpi)->SetS();
571 break;
572 }
573 //for (unsigned int ii = 0; ii < m.cm.VN(); ++ii)
574 //{
575 // CVertexO& vv = m.cm.vert[ii];
576 // if (!vv.IsD() && vv.IsS())
577 // {
578 // m.cm.selvert.push_back(Point3m::Construct(vv.cP()));
579 // ++m.cm.svn;
580 // }
581 //}
582 gla->updateSelection(m.id(), true,false);
583 }
584 else
585 {
586 //m.cm.selface.clear();
587 if (selectFrontFlag) GLPickTri<CMeshO>::PickVisibleFace(mid[0], mid[1], m.cm, NewSelFace, wid[0], wid[1]);
588 else GLPickTri<CMeshO>::PickFace(mid[0], mid[1], m.cm, NewSelFace, wid[0], wid[1]);
589
590 // qDebug("Pickface: rect %i %i - %i %i",mid.x(),mid.y(),wid.x(),wid.y());
591 // qDebug("Pickface: Got %i on %i",int(NewSelFace.size()),int(m.cm.face.size()));
592 glPopMatrix();
593 tri::UpdateSelection<CMeshO>::FaceClear(m.cm);
594 switch (composingSelMode)
595 {
596 case SMSub: // Subtract mode : The faces in the rect must be de-selected
597 if (selectionMode == SELECT_CONN_MODE)
598 {
599 for (fpi = NewSelFace.begin(); fpi != NewSelFace.end(); ++fpi)
600 (*fpi)->SetS();
601 tri::UpdateSelection<CMeshO>::FaceConnectedFF(m.cm);
602 NewSelFace.clear();
603 for (CMeshO::FaceIterator fi = m.cm.face.begin(); fi != m.cm.face.end(); ++fi)
604 if (!(*fi).IsD() && (*fi).IsS()) NewSelFace.push_back(&*fi);
605 }
606 // Normal case: simply deselect what has been selected.
607 for (fpi = LastSelFace.begin(); fpi != LastSelFace.end(); ++fpi)
608 (*fpi)->SetS();
609 for (fpi = NewSelFace.begin(); fpi != NewSelFace.end(); ++fpi)
610 (*fpi)->ClearS();
611 break;
612 case SMAdd:
613 for (fpi = LastSelFace.begin(); fpi != LastSelFace.end(); ++fpi)
614 (*fpi)->SetS();
615 case SMClear:
616 for (fpi = NewSelFace.begin(); fpi != NewSelFace.end(); ++fpi)
617 (*fpi)->SetS();
618 if (selectionMode == SELECT_CONN_MODE)
619 tri::UpdateSelection<CMeshO>::FaceConnectedFF(m.cm);
620 break;
621 }
622 gla->updateSelection(m.id(), false, true);
623 isDragging = false;
624 }
625
626 }
627 }
628
StartEdit(MeshModel & m,GLArea * gla,MLSceneGLSharedDataContext *)629 bool EditSelectPlugin::StartEdit(MeshModel & m, GLArea * gla, MLSceneGLSharedDataContext* /*cont*/)
630 {
631 if (gla == NULL)
632 return false;
633 if (!GLExtensionsManager::initializeGLextensions_notThrowing())
634 return false;
635 gla->setCursor(QCursor(QPixmap(":/images/sel_rect.png"), 1, 1));
636
637 if (selectionMode == SELECT_AREA_MODE)
638 {
639 if (m.cm.fn > 0)
640 areaMode = 1;
641 else
642 areaMode = 0;
643
644 selPolyLine.clear();
645 gla->setCursor(QCursor(QPixmap(":/images/sel_area.png"), 1, 1));
646 }
647
648 if (selectionMode == SELECT_VERT_MODE)
649 areaMode = 0;
650
651 if ((selectionMode == SELECT_FACE_MODE) || (selectionMode == SELECT_CONN_MODE))
652 areaMode = 1;
653
654 if (selectionMode == SELECT_CONN_MODE)
655 m.updateDataMask(MeshModel::MM_FACEFACETOPO);
656 return true;
657 }
658