#include using namespace vcg; inline bool isFront(const QPointF &a,const QPointF &b,const QPointF &c) { return (b.x()-a.x())*(c.y()-a.y())-(b.y()-a.y())*(c.x()-a.x())>0; } inline int isIn(const QPointF &p0,const QPointF &p1,float dx,float dy,float radius,float *dist) { if (p0!=p1) { /** this must be checked first, because of the color decrease tool */ float x2=(p1.x()-p0.x()); float y2=(p1.y()-p0.y()); //double l=sqrt(x2*x2+y2*y2); float l_square=x2*x2+y2*y2; float r=(dx-p0.x())*(p1.x()-p0.x())+(dy-p0.y())*(p1.y()-p0.y()); //r=r/(l*l); r=r/l_square; float px=p0.x()+r*(p1.x()-p0.x()); float py=p0.y()+r*(p1.y()-p0.y()); px=px-dx; py=py-dy; if (r>=0 && r<=1 && (px*px+py*py 1.0f) return false; else { if(pOut) *pOut = LineStart + s * LineDir; return true; } } else { const float s = (-UDotPMinusM - sqrtf(d)) / LineDirSq; if(s < 0.0f || s > 1.0f) return false; else { if(pOut) *pOut = LineStart + s * LineDir; return true; } } } inline bool pointInTriangle(const QPointF &p,const QPointF &a,const QPointF &b,const QPointF &c) { float fab=(p.y()-a.y())*(b.x()-a.x()) - (p.x()-a.x())*(b.y()-a.y()); float fbc=(p.y()-c.y())*(a.x()-c.x()) - (p.x()-c.x())*(a.y()-c.y()); float fca=(p.y()-b.y())*(c.x()-b.x()) - (p.x()-b.x())*(c.y()-b.y()); if (fab*fbc>0 && fbc*fca>0) return true; return false; } inline bool pointInTriangle(const float p_x,const float p_y,const float a_x,const float a_y,const float b_x,const float b_y,const float c_x,const float c_y) { float fab=(p_y-a_y)*(b_x-a_x) - (p_x-a_x)*(b_y-a_y); float fbc=(p_y-c_y)*(a_x-c_x) - (p_x-c_x)*(a_y-c_y); float fca=(p_y-b_y)*(c_x-b_x) - (p_x-b_x)*(c_y-b_y); if (fab*fbc>0 && fbc*fca>0) return true; return false; } inline void getSurroundingFacesVF(CFaceO * fac,int vert_pos,vector *surround) { CVertexO * vert=fac->V(vert_pos); int pos=vert->VFi(); CFaceO * first_fac=vert->VFp(); CFaceO * curr_f=first_fac; do { CFaceO * temp=curr_f->VFp(pos); if (curr_f!=0 && !curr_f->IsD()) { surround->push_back(curr_f); pos=curr_f->VFi(pos); } curr_f=temp; } while (curr_f!=first_fac && curr_f!=0); } void getInternFaces( MeshModel & m, vector *actual, vector * risult, vector * face_risult, GLArea * gla, Penn &pen, QPoint ¤t_point, QPoint &previous_point, GLfloat * pixels, double mvmatrix[16], double projmatrix[16], GLint viewport[4]) { QHash selected; QHash sel_vert; vector::iterator fpi; vector temp_po; if (actual->size()==0) { CMeshO::FaceIterator fi; for(fi=m.cm.face.begin();fi!=m.cm.face.end();++fi) if(!(*fi).IsD()) { temp_po.push_back((&*fi)); } } else for(fpi=actual->begin();fpi!=actual->end();++fpi) { temp_po.push_back(*fpi); } actual->clear(); QPointF mid = QPointF(current_point.x(), gla->curSiz.height() - current_point.y()); QPointF mid_prev = QPointF(previous_point.x(), gla->curSiz.height() - previous_point.y()); QPointF p[3],z[3]; double tx,ty,tz; bool backface=pen.backface; bool invisible=pen.invisible; for (int lauf2=0; lauf2V(lauf)->P()[0],(fac)->V(lauf)->P()[1],(fac)->V(lauf)->P()[2], mvmatrix,projmatrix,viewport,&tx,&ty,&tz)==GL_TRUE) checkable++; if (tz<0 || tz>1) checkable--; p[lauf].setX(tx); p[lauf].setY(ty); //qDebug() << tx << " "<< ty << " "<=0 && tx=0 && tyV(lauf))) { risult->push_back(fac->V(lauf)); sel_vert.insert(fac->V(lauf),fac->V(lauf)); //qDebug() << tx << " " << ty << " " << tz <<" "<< mid<push_back(fac); vector surround; for (int lauf=0; lauf<3; lauf++) getSurroundingFacesVF(fac,lauf,&surround); for (int lauf3=0; lauf3push_back(fac); } } } Color4b toVcgColor(QColor c) { return Color4b(c.red(),c.green(),c.blue(),255); } EditSegment::EditSegment() { actionList << new QAction(QIcon(":/images/editsegment.png"),"Mesh Segmentation", this); pixels = 0; pen.radius = 5; pen.backface = false; pen.invisible = false; pressed = false; meshCut = 0; meshCutDialog = 0; glarea = 0; selectForeground = true; } EditSegment::~EditSegment(){ delete meshCut; } QList EditSegment::actions() const { return actionList; } const QString EditSegment::Info(QAction *action) { if( action->text() != tr("Mesh Segmentation") ) assert (0); return tr("blablabla"); } const PluginInfo &EditSegment::Info() { static PluginInfo ai; ai.Date=tr(__DATE__); ai.Version = tr("0.1"); ai.Author = ("Giorgio Gangemi"); return ai; } void EditSegment::StartEdit(QAction * mode, MeshModel & m, GLArea * parent) { parent->setCursor(QCursor(QPixmap(":/images/editsegment_cursor.png","PNG"),1,1)); if (!meshCut) meshCut = new MeshCutting(&m.cm); if (!meshCutDialog) { meshCutDialog = new MeshCutDialog(parent->window()); meshcut_dock = new QDockWidget(parent->window()); meshcut_dock->setAllowedAreas(Qt::NoDockWidgetArea); meshcut_dock->setWidget(meshCutDialog); QPoint pos = parent->window()->mapToGlobal(QPoint(0,0)); meshcut_dock->setGeometry(-5+pos.x()+parent->window()->width()-meshCutDialog->width(), pos.y(),meshCutDialog->width(),meshCutDialog->height()); meshcut_dock->setFloating(true); QObject::connect(meshCutDialog, SIGNAL(meshCutSignal()),this, SLOT(MeshCutSlot())); QObject::connect(meshCutDialog, SIGNAL(selectForegroundSignal(bool)),this, SLOT(SelectForegroundSlot(bool))); } meshcut_dock->setVisible(true); meshcut_dock->layout()->update(); m.updateDataMask(MeshModel::MM_VERTFACETOPO); m.updateDataMask(MeshModel::MM_FACETOPO); parent->getCurrentRenderMode().colorMode=vcg::GLW::CMPerVert; parent->mm()->ioMask|=MeshModel::IOM_VERTCOLOR; glarea = parent; parent->update(); } void EditSegment::EndEdit (QAction * mode, MeshModel & m, GLArea * parent) { qDebug() << "Mesh Segmentation End Edit" << endl; } void EditSegment::Decorate (QAction * ac, MeshModel & m, GLArea * gla) { updateMatrixes(); QPoint mid=QPoint(current_point.x(),gla->curSiz.height() - current_point.y()); if (first) { first=false; if (pixels!=0) { free(pixels); } pixels=(GLfloat *)malloc(sizeof(GLfloat)*gla->curSiz.width()*gla->curSiz.height()); glReadPixels(0,0,gla->curSiz.width(),gla->curSiz.height(),GL_DEPTH_COMPONENT,GL_FLOAT,pixels); } if (dragging) { dragging = false; DrawXORCircle(m,gla,false); vector newSel; vector faceSel; getInternFaces(m,¤tSelection,&newSel,&faceSel,gla,pen,current_point,previous_point,pixels,mvmatrix,projmatrix,viewport); vector::iterator fpo; bool sel_or_not=(mouse_button_pressed==Qt::LeftButton); for(fpo=faceSel.begin();fpo!=faceSel.end();++fpo) { for (int i=0; i<3; ++i) { if (sel_or_not) { meshCut->Mark((*fpo)->V(i), iF); (*fpo)->V(i)->C() = toVcgColor(meshCutDialog->getForegroundColor()); //(*fpo)->SetS(); } else { //(*fpo)->ClearS(); meshCut->Mark((*fpo)->V(i), iB); (*fpo)->V(i)->C() = toVcgColor(meshCutDialog->getBackgroundColor()); } } } } } void EditSegment::mousePressEvent (QAction *, QMouseEvent *event, MeshModel & m, GLArea * gla){ if (mouse_button_pressed == Qt::RightButton && event->modifiers() == Qt::CTRL) { meshCut->MeshCut(); } else { show_trackball = gla->isTrackBallVisible(); gla->showTrackBall(false); first = true; dragging = true; mouse_button_pressed = event->button(); pressed = true; current_point = event->pos(); previous_point = current_point; } currentSelection.clear(); } void EditSegment::mouseMoveEvent (QAction *, QMouseEvent *event, MeshModel & m, GLArea * gla){ if (!dragging) previous_point = current_point; current_point = event->pos(); dragging = true; gla->update(); } void EditSegment::mouseReleaseEvent (QAction *, QMouseEvent *event, MeshModel & m, GLArea * gla){ gla->showTrackBall(show_trackball); gla->update(); previous_point = current_point; current_point = event->pos(); dragging = false; pressed = false; } void EditSegment::DrawXORCircle(MeshModel &m,GLArea * gla, bool doubleDraw) { int PEZ=18; /** paint the normal circle in pixel-mode */ //if (paintbox->paintType()==1) { glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0,gla->curSiz.width(),gla->curSiz.height(),0,-1,1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glPushAttrib(GL_ENABLE_BIT); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glEnable(GL_COLOR_LOGIC_OP); glLogicOp(GL_XOR); glColor3f(1,1,1); QPoint mid= QPoint(current_point.x(),/*gla->curSiz.height()-*/current_point.y()); if(doubleDraw) { glBegin(GL_LINE_LOOP); for (int lauf=0; laufMeshCut(); meshCut->Colorize(selectForeground); } glarea->update(); } void EditSegment::SelectForegroundSlot(bool value) { selectForeground = value; } Q_EXPORT_PLUGIN(EditSegment)