Updated all the involved filters to the recent changes to the picking reimplementation.

This commit is contained in:
Paolo Cignoni cignoni 2014-04-08 09:35:37 +00:00
parent 3b7fc88c33
commit bbade83542
6 changed files with 560 additions and 561 deletions

View File

@ -35,29 +35,29 @@
using namespace vcg;
EditHolePlugin::EditHolePlugin()
EditHolePlugin::EditHolePlugin()
:holesModel(NULL),dialogFiller(NULL),holeSorter(NULL),gla(NULL),mesh(NULL),md(NULL),pickedFace(NULL),hasPick(false)
{
}
EditHolePlugin::~EditHolePlugin()
{
if ( dialogFiller !=0 )
{
delete dialogFiller;
delete holesModel;
delete holeSorter;
dialogFiller = 0;
holesModel = 0;
holeSorter = 0;
gla = 0;
mesh = 0;
}
if ( dialogFiller !=0 )
{
delete dialogFiller;
delete holesModel;
delete holeSorter;
dialogFiller = 0;
holesModel = 0;
holeSorter = 0;
gla = 0;
mesh = 0;
}
}
const QString EditHolePlugin::Info()
const QString EditHolePlugin::Info()
{
return tr("Allow fill one or more hole into place");
return tr("Allow fill one or more hole into place");
}
void EditHolePlugin::mouseReleaseEvent(QMouseEvent * /*e*/, MeshModel &/*m*/, GLArea * /*gla*/)
@ -66,12 +66,12 @@ void EditHolePlugin::mouseReleaseEvent(QMouseEvent * /*e*/, MeshModel &/*m*/, GL
void EditHolePlugin::mousePressEvent(QMouseEvent *e, MeshModel &/*m*/, GLArea * /*gla*/)
{
if ( (e->button()==Qt::LeftButton) )
{
cur.setX(e->x());
cur.setY(e->y());
hasPick = true;
}
if ( (e->button()==Qt::LeftButton) )
{
cur.setX(e->x());
cur.setY(e->y());
hasPick = true;
}
}
void EditHolePlugin::mouseMoveEvent(QMouseEvent * /*e*/, MeshModel &/*m*/, GLArea * /*gla*/)
@ -80,165 +80,165 @@ void EditHolePlugin::mouseMoveEvent(QMouseEvent * /*e*/, MeshModel &/*m*/, GLAre
bool EditHolePlugin::StartEdit(MeshDocument &_md, GLArea *gla )
{
this->md = &_md;
if (md->mm() == NULL)
return false;
md->mm()->updateDataMask(MeshModel::MM_FACEFACETOPO);
if ( tri::Clean<CMeshO>::CountNonManifoldEdgeFF(md->mm()->cm) >0)
{
QMessageBox::critical(0, tr("Manifoldness Failure"), QString("Hole's managing requires manifoldness."));
return false; // can't continue, mesh can't be processed
}
this->md = &_md;
if (md->mm() == NULL)
return false;
md->mm()->updateDataMask(MeshModel::MM_FACEFACETOPO);
if ( tri::Clean<CMeshO>::CountNonManifoldEdgeFF(md->mm()->cm) >0)
{
QMessageBox::critical(0, tr("Manifoldness Failure"), QString("Hole's managing requires manifoldness."));
return false; // can't continue, mesh can't be processed
}
// necessario per evitare di avere 2 istanze del filtro se si cambia mesh
// senza chidere il filtro
if(dialogFiller != 0)
//EndEdit(m, gla);
return false;
// necessario per evitare di avere 2 istanze del filtro se si cambia mesh
// senza chidere il filtro
if(dialogFiller != 0)
//EndEdit(m, gla);
return false;
// if plugin restart with another mesh, recomputing of hole is forced
if(mesh != this->md->mm())
{
this->mesh = this->md->mm();
this->gla = gla;
// if plugin restart with another mesh, recomputing of hole is forced
if(mesh != this->md->mm())
{
this->mesh = this->md->mm();
this->gla = gla;
mesh->clearDataMask(MeshModel::MM_FACEMARK);
mesh->updateDataMask(MeshModel::MM_FACEMARK);
}
mesh->clearDataMask(MeshModel::MM_FACEMARK);
mesh->updateDataMask(MeshModel::MM_FACEMARK);
}
bridgeOptSldVal = 50;
dialogFiller=new FillerDialog(gla->window());
dialogFiller->show();
dialogFiller->setAllowedAreas(Qt::NoDockWidgetArea);
bridgeOptSldVal = 50;
dialogFiller=new FillerDialog(gla->window());
dialogFiller->show();
dialogFiller->setAllowedAreas(Qt::NoDockWidgetArea);
connect(dialogFiller->ui.operationTab, SIGNAL(currentChanged(int)), this, SLOT(skipTab(int)) );
connect(dialogFiller->ui.fillButton, SIGNAL(clicked()), this,SLOT(fill()));
connect(dialogFiller->ui.acceptFillBtn, SIGNAL(clicked()), this, SLOT(acceptFill()) );
connect(dialogFiller->ui.cancelFillBtn, SIGNAL(clicked()), this, SLOT(cancelFill()) );
connect(dialogFiller->ui.operationTab, SIGNAL(currentChanged(int)), this, SLOT(skipTab(int)) );
connect(dialogFiller->ui.fillButton, SIGNAL(clicked()), this,SLOT(fill()));
connect(dialogFiller->ui.acceptFillBtn, SIGNAL(clicked()), this, SLOT(acceptFill()) );
connect(dialogFiller->ui.cancelFillBtn, SIGNAL(clicked()), this, SLOT(cancelFill()) );
connect(dialogFiller->ui.manualBridgeBtn, SIGNAL(clicked()), this, SLOT(manualBridge()) );
connect(dialogFiller->ui.autoBridgeBtn, SIGNAL(clicked()), this, SLOT(autoBridge()) );
connect(dialogFiller->ui.nmHoleClosureBtn, SIGNAL(clicked()), this, SLOT(closeNMHoles()) );
connect(dialogFiller->ui.acceptBridgeBtn, SIGNAL(clicked()), this, SLOT(acceptBridges()) );
connect(dialogFiller->ui.clearBridgeBtn, SIGNAL(clicked()), this, SLOT(clearBridge()) );
connect(dialogFiller->ui.selfHoleChkB, SIGNAL(stateChanged(int)), this, SLOT(chekSingleBridgeOpt()) );
connect(dialogFiller->ui.diedralWeightSld, SIGNAL(valueChanged(int)), this, SLOT(updateDWeight(int)));
connect(dialogFiller->ui.bridgeParamSld, SIGNAL(valueChanged(int)), this, SLOT(updateBridgeSldValue(int)));
connect(dialogFiller, SIGNAL(SGN_Closing()),gla,SLOT(endEdit()) );
connect(dialogFiller->ui.holeTree->header(), SIGNAL(sectionCountChanged(int, int)), this, SLOT(resizeViewColumn()) );
if(holesModel != 0)
{
delete holeSorter;
delete holesModel;
}
holesModel = new HoleListModel(mesh);
holesModel->emitPostConstructionSignals();
connect(dialogFiller->ui.manualBridgeBtn, SIGNAL(clicked()), this, SLOT(manualBridge()) );
connect(dialogFiller->ui.autoBridgeBtn, SIGNAL(clicked()), this, SLOT(autoBridge()) );
connect(dialogFiller->ui.nmHoleClosureBtn, SIGNAL(clicked()), this, SLOT(closeNMHoles()) );
connect(dialogFiller->ui.acceptBridgeBtn, SIGNAL(clicked()), this, SLOT(acceptBridges()) );
connect(dialogFiller->ui.clearBridgeBtn, SIGNAL(clicked()), this, SLOT(clearBridge()) );
connect(dialogFiller->ui.selfHoleChkB, SIGNAL(stateChanged(int)), this, SLOT(chekSingleBridgeOpt()) );
connect(dialogFiller->ui.diedralWeightSld, SIGNAL(valueChanged(int)), this, SLOT(updateDWeight(int)));
connect(dialogFiller->ui.bridgeParamSld, SIGNAL(valueChanged(int)), this, SLOT(updateBridgeSldValue(int)));
connect(dialogFiller, SIGNAL(SGN_Closing()),gla,SLOT(endEdit()) );
connect(dialogFiller->ui.holeTree->header(), SIGNAL(sectionCountChanged(int, int)), this, SLOT(resizeViewColumn()) );
if(holesModel != 0)
{
delete holeSorter;
delete holesModel;
}
holesModel = new HoleListModel(mesh);
holesModel->emitPostConstructionSignals();
holesModel->holesManager.autoBridgeCB = new EditHoleAutoBridgingCB(dialogFiller->ui.infoLbl, 800);
connect(holesModel, SIGNAL(SGN_Closing()),gla,SLOT(endEdit()) );
connect(holesModel, SIGNAL(SGN_needUpdateGLA()), this, SLOT(upGlA()) );
connect(holesModel, SIGNAL(SGN_ExistBridge(bool)), dialogFiller, SLOT(SLOT_ExistBridge(bool)) );
holesModel->holesManager.autoBridgeCB = new EditHoleAutoBridgingCB(dialogFiller->ui.infoLbl, 800);
connect(holesModel, SIGNAL(SGN_Closing()),gla,SLOT(endEdit()) );
connect(holesModel, SIGNAL(SGN_needUpdateGLA()), this, SLOT(upGlA()) );
connect(holesModel, SIGNAL(SGN_ExistBridge(bool)), dialogFiller, SLOT(SLOT_ExistBridge(bool)) );
holeSorter = new HoleSorterFilter();
//holeSorter->setSourceModel(holesModel);
//dialogFiller->ui.holeTree->setModel( holeSorter );
dialogFiller->ui.holeTree->setModel(holesModel);
holeSorter = new HoleSorterFilter();
//holeSorter->setSourceModel(holesModel);
//dialogFiller->ui.holeTree->setModel( holeSorter );
dialogFiller->ui.holeTree->setModel(holesModel);
if(holesModel->holesManager.holes.size()==0)
{
QMessageBox::information(0, tr("No holes"), QString("Mesh have no hole to edit."));
//EndEdit(m, gla);
return false;
}
else
{
Decorate(*mesh, gla);
upGlA();
}
return true;
if(holesModel->holesManager.holes.size()==0)
{
QMessageBox::information(0, tr("No holes"), QString("Mesh have no hole to edit."));
//EndEdit(m, gla);
return false;
}
else
{
Decorate(*mesh, gla);
upGlA();
}
return true;
}
void EditHolePlugin::Decorate(MeshModel &m, GLArea * gla)
{
if(holesModel==0)
return;
if(holesModel==0)
return;
glPushMatrix();
glMultMatrix(mesh->cm.Tr);
glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_LINE_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glMultMatrix(mesh->cm.Tr);
glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_LINE_BIT | GL_DEPTH_BUFFER_BIT);
holesModel->drawCompenetratingFaces();
holesModel->drawHoles();
holesModel->drawCompenetratingFaces();
holesModel->drawHoles();
if(hasPick)
{
hasPick = false;
pickedFace =0;
int inverseY = gla->height() - cur.y();
GLPickTri<CMeshO>::PickNearestFace(cur.x(), inverseY, m.cm, pickedFace, 4, 4);
if( pickedFace != 0 )
{
bool oldAbutmentPresence;
switch(holesModel->getState())
{
case HoleListModel::Selection:
if(holesModel->holesManager.IsHoleBorderFace(pickedFace))
holesModel->toggleSelectionHoleFromFace(pickedFace);
break;
case HoleListModel::Filled:
holesModel->toggleAcceptanceHole(pickedFace);
break;
case HoleListModel::ManualBridging:
oldAbutmentPresence = holesModel->PickedAbutment();
if(hasPick)
{
hasPick = false;
pickedFace =0;
int inverseY = gla->height() - cur.y();
GLPickTri<CMeshO>::PickClosestFace(cur.x(), inverseY, m.cm, pickedFace, 4, 4);
if( pickedFace != 0 )
{
bool oldAbutmentPresence;
switch(holesModel->getState())
{
case HoleListModel::Selection:
if(holesModel->holesManager.IsHoleBorderFace(pickedFace))
holesModel->toggleSelectionHoleFromFace(pickedFace);
break;
case HoleListModel::Filled:
holesModel->toggleAcceptanceHole(pickedFace);
break;
case HoleListModel::ManualBridging:
oldAbutmentPresence = holesModel->PickedAbutment();
md->setBusy(true);
holesModel->addBridgeFace(pickedFace, cur.x(), inverseY);
holesModel->addBridgeFace(pickedFace, cur.x(), inverseY);
md->setBusy(false);
if(holesModel->PickedAbutment() != oldAbutmentPresence)
{
if(oldAbutmentPresence == true)
gla->setCursor(QCursor(QPixmap(":/images/bridgeCursor.png", "PNG"), 1, 1));
else
gla->setCursor(QCursor(QPixmap(":/images/bridgeCursor1.png", "PNG"), 1, 1));
}
break;
}
}
}
if(holesModel->PickedAbutment() != oldAbutmentPresence)
{
if(oldAbutmentPresence == true)
gla->setCursor(QCursor(QPixmap(":/images/bridgeCursor.png", "PNG"), 1, 1));
else
gla->setCursor(QCursor(QPixmap(":/images/bridgeCursor1.png", "PNG"), 1, 1));
}
break;
}
}
}
glPopAttrib();
glPopMatrix();
glPopAttrib();
glPopMatrix();
}
void EditHolePlugin::EndEdit(MeshModel &/*m*/, GLArea *gla ){
if(holesModel == 0) // means editing is not started
return;
if(holesModel == 0) // means editing is not started
return;
if(holesModel->getState() == HoleListModel::Filled)
holesModel->acceptFilling(false);
if(holesModel->holesManager.bridges.size()>0)
holesModel->removeBridges();
if(holesModel->getState() == HoleListModel::Filled)
holesModel->acceptFilling(false);
if(holesModel->holesManager.bridges.size()>0)
holesModel->removeBridges();
if ( dialogFiller!=0) {
delete dialogFiller;
delete holesModel;
delete holeSorter;
dialogFiller = 0;
holesModel = 0;
holeSorter = 0;
gla = 0;
mesh = 0;
}
md->mm()->clearDataMask(MeshModel::MM_FACEFACETOPO);
if ( dialogFiller!=0) {
delete dialogFiller;
delete holesModel;
delete holeSorter;
dialogFiller = 0;
holesModel = 0;
holeSorter = 0;
gla = 0;
mesh = 0;
}
md->mm()->clearDataMask(MeshModel::MM_FACEFACETOPO);
}
void EditHolePlugin::upGlA()
{
gla->update();
setInfoLabel();
gla->update();
setInfoLabel();
}
void EditHolePlugin::setInfoLabel()
@ -259,120 +259,120 @@ void EditHolePlugin::setInfoLabel()
void EditHolePlugin::resizeViewColumn()
{
dialogFiller->ui.holeTree->header()->resizeSections(QHeaderView::ResizeToContents);
dialogFiller->ui.holeTree->header()->resizeSections(QHeaderView::ResizeToContents);
}
void EditHolePlugin::updateDWeight(int val)
{
vcg::tri::MinimumWeightEar<CMeshO>::DiedralWeight() = (float)val / 50;
vcg::tri::MinimumWeightEar<CMeshO>::DiedralWeight() = (float)val / 50;
}
void EditHolePlugin::fill()
{
md->setBusy(true);
if(holesModel->getState() == HoleListModel::Filled)
holesModel->acceptFilling(false);
if(holesModel->getState() == HoleListModel::Filled)
holesModel->acceptFilling(false);
if( dialogFiller->ui.trivialRBtn->isChecked())
holesModel->fill( FgtHole<CMeshO>::Trivial);
else if( dialogFiller->ui.minWRBtn->isChecked())
holesModel->fill( FgtHole<CMeshO>::MinimumWeight);
else
holesModel->fill( FgtHole<CMeshO>::SelfIntersection);
if( dialogFiller->ui.trivialRBtn->isChecked())
holesModel->fill( FgtHole<CMeshO>::Trivial);
else if( dialogFiller->ui.minWRBtn->isChecked())
holesModel->fill( FgtHole<CMeshO>::MinimumWeight);
else
holesModel->fill( FgtHole<CMeshO>::SelfIntersection);
md->setBusy(false);
upGlA();
upGlA();
}
void EditHolePlugin::acceptFill()
{
if(holesModel->getState() == HoleListModel::Filled)
{
if(holesModel->getState() == HoleListModel::Filled)
{
md->setBusy(true);
holesModel->acceptFilling(true);
holesModel->acceptFilling(true);
md->setBusy(false);
gla->setWindowModified(true);
}
gla->setWindowModified(true);
}
}
void EditHolePlugin::cancelFill()
{
md->setBusy(true);
if(holesModel->getState() == HoleListModel::Filled)
holesModel->acceptFilling(false);
if(holesModel->getState() == HoleListModel::Filled)
holesModel->acceptFilling(false);
md->setBusy(false);
}
void EditHolePlugin::updateBridgeSldValue(int val)
{
bridgeOptSldVal = val;
bridgeOptSldVal = val;
}
void EditHolePlugin::manualBridge()
{
if(holesModel->getState() != HoleListModel::ManualBridging)
{
holesModel->setStartBridging();
dialogFiller->clickStartBridging();
gla->setCursor(QCursor(QPixmap(":/images/bridgeCursor.png", "PNG"), 1, 1));
}
else
{
holesModel->setEndBridging();
dialogFiller->clickEndBridging();
gla->setCursor(QCursor());
}
gla->update();
if(holesModel->getState() != HoleListModel::ManualBridging)
{
holesModel->setStartBridging();
dialogFiller->clickStartBridging();
gla->setCursor(QCursor(QPixmap(":/images/bridgeCursor.png", "PNG"), 1, 1));
}
else
{
holesModel->setEndBridging();
dialogFiller->clickEndBridging();
gla->setCursor(QCursor());
}
gla->update();
}
void EditHolePlugin::autoBridge()
{
md->setBusy(true);
bool singleHole = dialogFiller->ui.selfHoleChkB->isChecked();
holesModel->autoBridge(singleHole, bridgeOptSldVal*0.0017);
bool singleHole = dialogFiller->ui.selfHoleChkB->isChecked();
holesModel->autoBridge(singleHole, bridgeOptSldVal*0.0017);
md->setBusy(false);
upGlA();
upGlA();
}
void EditHolePlugin::closeNMHoles()
{
md->setBusy(true);
holesModel->closeNonManifolds();
holesModel->closeNonManifolds();
md->setBusy(false);
upGlA();
upGlA();
}
void EditHolePlugin::chekSingleBridgeOpt()
{
dialogFiller->clickSingleHoleBridgeOpt();
dialogFiller->clickSingleHoleBridgeOpt();
}
void EditHolePlugin::acceptBridges()
{
holesModel->acceptBridges();
upGlA();
holesModel->acceptBridges();
upGlA();
}
void EditHolePlugin::clearBridge()
{
md->setBusy(true);
holesModel->removeBridges();
holesModel->removeBridges();
md->setBusy(false);
upGlA();
upGlA();
}
void EditHolePlugin::skipTab(int index)
{
if(holesModel->getState() == HoleListModel::Selection)
return;
if(holesModel->getState() == HoleListModel::Selection)
return;
if(index == 0)
{
holesModel->setEndBridging();
dialogFiller->clickEndBridging();
gla->setCursor(QCursor());
}
else
cancelFill();
if(index == 0)
{
holesModel->setEndBridging();
dialogFiller->clickEndBridging();
gla->setCursor(QCursor());
}
else
cancelFill();
}

View File

@ -416,7 +416,7 @@ void EditPaintPlugin::Decorate(MeshModel &m, GLArea * gla)
{
case COLOR_FILL:
CFaceO * face;
if(GLPickTri<CMeshO>::PickNearestFace(latest_event.gl_position.x(), latest_event.gl_position.y(), m.cm, face, 2, 2))
if(GLPickTri<CMeshO>::PickClosestFace(latest_event.gl_position.x(), latest_event.gl_position.y(), m.cm, face, 2, 2))
{
fill(m, face);
glarea->update();

View File

@ -563,7 +563,7 @@ inline bool getVertexAtMouse(MeshModel &m,CMeshO::VertexPointer& value, QPoint&
//TODO e se i vertici sono stati cancellati? (IsD())
if (vcg::GLPickTri<CMeshO>::PickNearestFace(cursor.x(), cursor.y(), m.cm, fp, 2, 2))
if (vcg::GLPickTri<CMeshO>::PickClosestFace(cursor.x(), cursor.y(), m.cm, fp, 2, 2))
{
QPointF point[3];

View File

@ -22,8 +22,8 @@
****************************************************************************/
/* A class implementing Meshlab's Edit interface that is for picking points in 3D
*
*
*
*
* @author Oscar Barney
*/
@ -46,393 +46,393 @@ using namespace vcg;
EditPickPointsPlugin::EditPickPointsPlugin()
{
//initialize to false so we dont end up collection some weird point in the beginning
registerPoint = false;
moveSelectPoint = false;
pickPointsDialog = 0;
currentModel = 0;
overrideCursorShape = 0;
//initialize to false so we dont end up collection some weird point in the beginning
registerPoint = false;
moveSelectPoint = false;
pickPointsDialog = 0;
currentModel = 0;
overrideCursorShape = 0;
}
//Constants
const QString EditPickPointsPlugin::Info()
const QString EditPickPointsPlugin::Info()
{
return tr("Pick and save 3D points on the mesh");
return tr("Pick and save 3D points on the mesh");
}
//called
void EditPickPointsPlugin::Decorate(MeshModel &mm, GLArea *gla, QPainter *painter)
{
//qDebug() << "Decorate " << mm.fileName.c_str() << " ..." << mm.cm.fn;
if(gla != glArea || mm.cm.fn < 1)
{
//qDebug() << "GLarea is different or no faces!!! ";
return;
}
//make sure we picking points on the right meshes!
if(&mm != currentModel){
//now that were are ending tell the dialog to save any points it has to metadata
pickPointsDialog->savePointsToMetaData();
//set the new mesh model
pickPointsDialog->setCurrentMeshModel(&mm, gla);
currentModel = &mm;
}
//We have to calculate the position here because it doesnt work in the mouseEvent functions for some reason
Point3f pickedPoint;
if (moveSelectPoint && Pick<Point3f>(currentMousePosition.x(),gla->height()-currentMousePosition.y(),pickedPoint)){
/* qDebug("Found point for move %i %i -> %f %f %f",
currentMousePosition.x(),
currentMousePosition.y(),
pickedPoint[0], pickedPoint[1], pickedPoint[2]); */
//let the dialog know that this was the pointed picked incase it wants the information
pickPointsDialog->selectOrMoveThisPoint(pickedPoint);
moveSelectPoint = false;
} else if(registerPoint && Pick<Point3f>(currentMousePosition.x(),gla->height()-currentMousePosition.y(),pickedPoint))
{
/* qDebug("Found point for add %i %i -> %f %f %f",
currentMousePosition.x(),
currentMousePosition.y(),
pickedPoint[0], pickedPoint[1], pickedPoint[2]); */
//find the normal of the face we just clicked
CFaceO *face;
bool result = GLPickTri<CMeshO>::PickNearestFace(currentMousePosition.x(),gla->height()-currentMousePosition.y(),
mm.cm, face);
if(!result){
qDebug() << "find nearest face failed!";
} else
{
CFaceO::NormalType faceNormal = face->N();
//qDebug() << "found face normal: " << faceNormal[0] << faceNormal[1] << faceNormal[2];
//if we didnt find a face then dont add the point because the user was probably
//clicking on another mesh opened inside the glarea
pickPointsDialog->addMoveSelectPoint(pickedPoint, faceNormal);
}
registerPoint = false;
}
//qDebug() << "Decorate " << mm.fileName.c_str() << " ..." << mm.cm.fn;
if(gla != glArea || mm.cm.fn < 1)
{
//qDebug() << "GLarea is different or no faces!!! ";
return;
}
//make sure we picking points on the right meshes!
if(&mm != currentModel){
//now that were are ending tell the dialog to save any points it has to metadata
pickPointsDialog->savePointsToMetaData();
//set the new mesh model
pickPointsDialog->setCurrentMeshModel(&mm, gla);
currentModel = &mm;
}
//We have to calculate the position here because it doesnt work in the mouseEvent functions for some reason
Point3f pickedPoint;
if (moveSelectPoint && Pick<Point3f>(currentMousePosition.x(),gla->height()-currentMousePosition.y(),pickedPoint)){
/* qDebug("Found point for move %i %i -> %f %f %f",
currentMousePosition.x(),
currentMousePosition.y(),
pickedPoint[0], pickedPoint[1], pickedPoint[2]); */
//let the dialog know that this was the pointed picked incase it wants the information
pickPointsDialog->selectOrMoveThisPoint(pickedPoint);
moveSelectPoint = false;
} else if(registerPoint && Pick<Point3f>(currentMousePosition.x(),gla->height()-currentMousePosition.y(),pickedPoint))
{
/* qDebug("Found point for add %i %i -> %f %f %f",
currentMousePosition.x(),
currentMousePosition.y(),
pickedPoint[0], pickedPoint[1], pickedPoint[2]); */
//find the normal of the face we just clicked
CFaceO *face;
bool result = GLPickTri<CMeshO>::PickClosestFace(currentMousePosition.x(),gla->height()-currentMousePosition.y(),
mm.cm, face);
if(!result){
qDebug() << "find nearest face failed!";
} else
{
CFaceO::NormalType faceNormal = face->N();
//qDebug() << "found face normal: " << faceNormal[0] << faceNormal[1] << faceNormal[2];
//if we didnt find a face then dont add the point because the user was probably
//clicking on another mesh opened inside the glarea
pickPointsDialog->addMoveSelectPoint(pickedPoint, faceNormal);
}
registerPoint = false;
}
drawPickedPoints(pickPointsDialog->getPickedPointTreeWidgetItemVector(), mm.cm.bbox, painter);
}
bool EditPickPointsPlugin::StartEdit(MeshModel &mm, GLArea *gla )
{
//qDebug() << "StartEdit Pick Points: " << mm.fileName.c_str() << " ..." << mm.cm.fn;
//if there are no faces then we cant do anything with this plugin
if(mm.cm.fn < 1)
{
if(NULL != pickPointsDialog)
{
pickPointsDialog->hide();
}
//show message
QMessageBox::warning(gla->window(), "Edit Pick Points",
"Sorry, this mesh has no faces on which picked points can sit.",
QMessageBox::Ok, QMessageBox::Ok);
return false;
}
//get the cursor
QCursor *cursor = QApplication::overrideCursor();
if(cursor) overrideCursorShape = cursor->shape();
else overrideCursorShape = Qt::ArrowCursor;
//set this so redraw can use it
glArea = gla;
//Create GUI window if we dont already have one
if(pickPointsDialog == 0)
{
pickPointsDialog = new PickPointsDialog(this, gla->window());
}
currentModel = &mm;
//set the current mesh
pickPointsDialog->setCurrentMeshModel(&mm, gla);
//show the dialog
pickPointsDialog->show();
return true;
//qDebug() << "StartEdit Pick Points: " << mm.fileName.c_str() << " ..." << mm.cm.fn;
//if there are no faces then we cant do anything with this plugin
if(mm.cm.fn < 1)
{
if(NULL != pickPointsDialog)
{
pickPointsDialog->hide();
}
//show message
QMessageBox::warning(gla->window(), "Edit Pick Points",
"Sorry, this mesh has no faces on which picked points can sit.",
QMessageBox::Ok, QMessageBox::Ok);
return false;
}
//get the cursor
QCursor *cursor = QApplication::overrideCursor();
if(cursor) overrideCursorShape = cursor->shape();
else overrideCursorShape = Qt::ArrowCursor;
//set this so redraw can use it
glArea = gla;
//Create GUI window if we dont already have one
if(pickPointsDialog == 0)
{
pickPointsDialog = new PickPointsDialog(this, gla->window());
}
currentModel = &mm;
//set the current mesh
pickPointsDialog->setCurrentMeshModel(&mm, gla);
//show the dialog
pickPointsDialog->show();
return true;
}
void EditPickPointsPlugin::EndEdit(MeshModel &mm, GLArea *gla)
{
//qDebug() << "EndEdit Pick Points: " << mm.fileName.c_str() << " ..." << mm.cm.fn;
// some cleaning at the end.
if(mm.cm.fn > 0)
{
assert(pickPointsDialog);
//now that were are ending tell the dialog to save any points it has to metadata
pickPointsDialog->savePointsToMetaData();
//qDebug() << "EndEdit Pick Points: " << mm.fileName.c_str() << " ..." << mm.cm.fn;
//remove the dialog from the screen
pickPointsDialog->hide();
QApplication::setOverrideCursor( QCursor((Qt::CursorShape)overrideCursorShape) );
this->glArea = 0;
}
// some cleaning at the end.
if(mm.cm.fn > 0)
{
assert(pickPointsDialog);
//now that were are ending tell the dialog to save any points it has to metadata
pickPointsDialog->savePointsToMetaData();
//remove the dialog from the screen
pickPointsDialog->hide();
QApplication::setOverrideCursor( QCursor((Qt::CursorShape)overrideCursorShape) );
this->glArea = 0;
}
}
void EditPickPointsPlugin::mousePressEvent(QMouseEvent *event, MeshModel &mm, GLArea *gla )
{
//qDebug() << "mouse press Pick Points: " << mm.fileName.c_str() << " ...";
//qDebug() << "mouse press Pick Points: " << mm.fileName.c_str() << " ...";
//if there are no faces then we cant do anything with this plugin
if(mm.cm.fn < 1) return;
if(Qt::LeftButton | event->buttons())
{
gla->suspendedEditor = true;
QCoreApplication::sendEvent(gla, event);
gla->suspendedEditor = false;
}
if(Qt::RightButton == event->button() &&
pickPointsDialog->getMode() != PickPointsDialog::ADD_POINT){
currentMousePosition = event->pos();
pickPointsDialog->recordNextPointForUndo();
//set flag that we need to add a new point
moveSelectPoint = true;
}
//if there are no faces then we cant do anything with this plugin
if(mm.cm.fn < 1) return;
if(Qt::LeftButton | event->buttons())
{
gla->suspendedEditor = true;
QCoreApplication::sendEvent(gla, event);
gla->suspendedEditor = false;
}
if(Qt::RightButton == event->button() &&
pickPointsDialog->getMode() != PickPointsDialog::ADD_POINT){
currentMousePosition = event->pos();
pickPointsDialog->recordNextPointForUndo();
//set flag that we need to add a new point
moveSelectPoint = true;
}
}
void EditPickPointsPlugin::mouseMoveEvent(QMouseEvent *event, MeshModel &mm, GLArea *gla )
void EditPickPointsPlugin::mouseMoveEvent(QMouseEvent *event, MeshModel &mm, GLArea *gla )
{
//qDebug() << "mousemove pick Points: " << mm.fileName.c_str() << " ...";
//if there are no faces then we cant do anything with this plugin
if(mm.cm.fn < 1) return;
if(Qt::LeftButton | event->buttons())
{
gla->suspendedEditor = true;
QCoreApplication::sendEvent(gla, event);
gla->suspendedEditor = false;
}
if(Qt::RightButton & event->buttons() &&
pickPointsDialog->getMode() != PickPointsDialog::ADD_POINT){
//qDebug() << "mouse move left button and move mode: ";
currentMousePosition = event->pos();
//set flag that we need to add a new point
registerPoint = true;
}
//qDebug() << "mousemove pick Points: " << mm.fileName.c_str() << " ...";
//if there are no faces then we cant do anything with this plugin
if(mm.cm.fn < 1) return;
if(Qt::LeftButton | event->buttons())
{
gla->suspendedEditor = true;
QCoreApplication::sendEvent(gla, event);
gla->suspendedEditor = false;
}
if(Qt::RightButton & event->buttons() &&
pickPointsDialog->getMode() != PickPointsDialog::ADD_POINT){
//qDebug() << "mouse move left button and move mode: ";
currentMousePosition = event->pos();
//set flag that we need to add a new point
registerPoint = true;
}
}
void EditPickPointsPlugin::mouseReleaseEvent(QMouseEvent *event, MeshModel &mm, GLArea * gla)
{
//qDebug() << "mouseRelease Pick Points: " << mm.fileName.c_str() << " ...";
//if there are no faces then we cant do anything with this plugin
if(mm.cm.fn < 1) return;
if(Qt::LeftButton | event->buttons())
{
gla->suspendedEditor = true;
QCoreApplication::sendEvent(gla, event);
gla->suspendedEditor = false;
}
//only add points for the left button
if(Qt::RightButton == event->button()){
currentMousePosition = event->pos();
//set flag that we need to add a new point
registerPoint = true;
}
//qDebug() << "mouseRelease Pick Points: " << mm.fileName.c_str() << " ...";
//if there are no faces then we cant do anything with this plugin
if(mm.cm.fn < 1) return;
if(Qt::LeftButton | event->buttons())
{
gla->suspendedEditor = true;
QCoreApplication::sendEvent(gla, event);
gla->suspendedEditor = false;
}
//only add points for the left button
if(Qt::RightButton == event->button()){
currentMousePosition = event->pos();
//set flag that we need to add a new point
registerPoint = true;
}
}
void EditPickPointsPlugin::drawPickedPoints(
std::vector<PickedPointTreeWidgetItem*> &pointVector, vcg::Box3f &boundingBox, QPainter *painter)
{
assert(glArea);
vcg::Point3f size = boundingBox.Dim();
//how we scale the object indicating the normal at each selected point
float scaleFactor = (size[0]+size[1]+size[2])/90.0;
assert(glArea);
//qDebug() << "scaleFactor: " << scaleFactor;
glPushAttrib(GL_ALL_ATTRIB_BITS);
// enable color tracking
glEnable(GL_COLOR_MATERIAL);
//draw the things that we always want to show, like the names
glDepthFunc(GL_ALWAYS);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
//set point attributes
glPointSize(4.5);
bool showNormal = pickPointsDialog->showNormal();
bool showPin = pickPointsDialog->drawNormalAsPin();
for(int i = 0; i < pointVector.size(); ++i)
{
PickedPointTreeWidgetItem * item = pointVector[i];
//if the point has been set (it may not be if a template has been loaded)
if(item->isActive()){
Point3f point = item->getPoint();
glColor(Color4b::Blue);
vcg::Point3f size = boundingBox.Dim();
//how we scale the object indicating the normal at each selected point
float scaleFactor = (size[0]+size[1]+size[2])/90.0;
//qDebug() << "scaleFactor: " << scaleFactor;
glPushAttrib(GL_ALL_ATTRIB_BITS);
// enable color tracking
glEnable(GL_COLOR_MATERIAL);
//draw the things that we always want to show, like the names
glDepthFunc(GL_ALWAYS);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
//set point attributes
glPointSize(4.5);
bool showNormal = pickPointsDialog->showNormal();
bool showPin = pickPointsDialog->drawNormalAsPin();
for(int i = 0; i < pointVector.size(); ++i)
{
PickedPointTreeWidgetItem * item = pointVector[i];
//if the point has been set (it may not be if a template has been loaded)
if(item->isActive()){
Point3f point = item->getPoint();
glColor(Color4b::Blue);
glLabel::render(painter,point, QString(item->getName()));
//draw the dot if we arnt showing the normal or showing the normal as a line
if(!showNormal || !showPin)
{
if(item->isSelected() ) glColor(Color4b::Green);
glBegin(GL_POINTS);
glVertex(point);
glEnd();
}
}
}
//draw the dot if we arnt showing the normal or showing the normal as a line
if(!showNormal || !showPin)
{
if(item->isSelected() ) glColor(Color4b::Green);
glBegin(GL_POINTS);
glVertex(point);
glEnd();
}
}
}
//now draw the things that we want drawn if they are not ocluded
//we can see in bright red
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_MODELVIEW);
Point3f yaxis;
yaxis[0] = 0;
yaxis[1] = 1;
yaxis[2] = 0;
for(int i = 0; i < pointVector.size(); ++i)
{
PickedPointTreeWidgetItem * item = pointVector[i];
//if the point has been set (it may not be if a template has been loaded)
if(item->isActive()){
Point3f point = item->getPoint();
if(showNormal)
{
Point3f normal = item->getNormal();
if(showPin)
{
//dot product
float angle = (Angle(normal,yaxis) * 180.0 / PI);
//cross product
Point3f axis = yaxis^normal;
//qDebug() << "angle: " << angle << " x" << axis[0] << " y" << axis[1] << " z" << axis[2];
//bluegreen and a little clear
glColor4f(0.0f, 1.0f, 0.0f, 0.7f);
//glColor(Color4b::Green);
glPushMatrix();
//move the pin to where it needs to be
glTranslatef(point[0], point[1], point[2]);
glRotatef(angle, axis[0], axis[1], axis[2]);
glScalef(0.2*scaleFactor, 1.5*scaleFactor, 0.2*scaleFactor);
glBegin(GL_TRIANGLES);
//front
glNormal3f(0, -1, 1);
glVertex3f(0,0,0);
glVertex3f(1,1,1);
glVertex3f(-1,1,1);
//right
glNormal3f(1, -1, 0);
glVertex3f(0,0,0);
glVertex3f(1,1,-1);
glVertex3f(1,1,1);
//left
glNormal3f(-1, -1, 0);
glVertex3f(0,0,0);
glVertex3f(-1,1,1);
glVertex3f(-1,1,-1);
//back
glNormal3f(0, -1, -1);
glVertex3f(0,0,0);
glVertex3f(-1,1,-1);
glVertex3f(1,1,-1);
//top
//if it is selected color it green
if(item->isSelected() ) glColor4f(0.0f, 0.0f, 1.0f, 0.7f);
glNormal3f(0, 1, 0);
glVertex3f(1,1,1);
glVertex3f(1,1,-1);
glVertex3f(-1,1,-1);
glNormal3f(0, 1, 0);
glVertex3f(1,1,1);
glVertex3f(-1,1,-1);
glVertex3f(-1,1,1);
//change back
if(item->isSelected() ) glColor4f(0.0f, 1.0f, 0.0f, 0.7f);
glEnd();
glPopMatrix();
} else
{
glColor(Color4b::Green);
glBegin(GL_LINES);
glVertex(point);
glVertex(point+(normal*scaleFactor));
glEnd();
}
}
glColor(Color4b::Red);
glArea->renderText(point[0], point[1], point[2], QString(item->getName()) );
}
}
glDisable(GL_BLEND);
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_DEPTH_TEST);
glPopAttrib();
//now draw the things that we want drawn if they are not ocluded
//we can see in bright red
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_MODELVIEW);
Point3f yaxis;
yaxis[0] = 0;
yaxis[1] = 1;
yaxis[2] = 0;
for(int i = 0; i < pointVector.size(); ++i)
{
PickedPointTreeWidgetItem * item = pointVector[i];
//if the point has been set (it may not be if a template has been loaded)
if(item->isActive()){
Point3f point = item->getPoint();
if(showNormal)
{
Point3f normal = item->getNormal();
if(showPin)
{
//dot product
float angle = (Angle(normal,yaxis) * 180.0 / PI);
//cross product
Point3f axis = yaxis^normal;
//qDebug() << "angle: " << angle << " x" << axis[0] << " y" << axis[1] << " z" << axis[2];
//bluegreen and a little clear
glColor4f(0.0f, 1.0f, 0.0f, 0.7f);
//glColor(Color4b::Green);
glPushMatrix();
//move the pin to where it needs to be
glTranslatef(point[0], point[1], point[2]);
glRotatef(angle, axis[0], axis[1], axis[2]);
glScalef(0.2*scaleFactor, 1.5*scaleFactor, 0.2*scaleFactor);
glBegin(GL_TRIANGLES);
//front
glNormal3f(0, -1, 1);
glVertex3f(0,0,0);
glVertex3f(1,1,1);
glVertex3f(-1,1,1);
//right
glNormal3f(1, -1, 0);
glVertex3f(0,0,0);
glVertex3f(1,1,-1);
glVertex3f(1,1,1);
//left
glNormal3f(-1, -1, 0);
glVertex3f(0,0,0);
glVertex3f(-1,1,1);
glVertex3f(-1,1,-1);
//back
glNormal3f(0, -1, -1);
glVertex3f(0,0,0);
glVertex3f(-1,1,-1);
glVertex3f(1,1,-1);
//top
//if it is selected color it green
if(item->isSelected() ) glColor4f(0.0f, 0.0f, 1.0f, 0.7f);
glNormal3f(0, 1, 0);
glVertex3f(1,1,1);
glVertex3f(1,1,-1);
glVertex3f(-1,1,-1);
glNormal3f(0, 1, 0);
glVertex3f(1,1,1);
glVertex3f(-1,1,-1);
glVertex3f(-1,1,1);
//change back
if(item->isSelected() ) glColor4f(0.0f, 1.0f, 0.0f, 0.7f);
glEnd();
glPopMatrix();
} else
{
glColor(Color4b::Green);
glBegin(GL_LINES);
glVertex(point);
glVertex(point+(normal*scaleFactor));
glEnd();
}
}
glColor(Color4b::Red);
glArea->renderText(point[0], point[1], point[2], QString(item->getName()) );
}
}
glDisable(GL_BLEND);
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_DEPTH_TEST);
glPopAttrib();
}

View File

@ -8,7 +8,7 @@
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
@ -45,7 +45,7 @@ EditPointPlugin::EditPointPlugin(int _editType) : editType(_editType) {}
const QString EditPointPlugin::Info() {
return tr("Select a region of the point cloud thought to be in the same connected component.");
}
void EditPointPlugin::Decorate(MeshModel &m, GLArea * gla, QPainter *p)
{
this->RealTimeLog("Point Selection",m.shortName(),
@ -61,13 +61,12 @@ void EditPointPlugin::Decorate(MeshModel &m, GLArea * gla, QPainter *p)
{
glPushMatrix();
glMultMatrix(m.cm.Tr);
vector<CMeshO::VertexPointer> NewSel;
GLPickTri<CMeshO>::PickVert(cur.x(), gla->height() - cur.y(), m.cm, NewSel);
if(NewSel.size() > 0) {
startingVertex = NewSel.front();
CMeshO::VertexPointer newStartingVertex=0;
GLPickTri<CMeshO>::PickClosestVert(cur.x(), gla->height() - cur.y(), m.cm, newStartingVertex);
if(newStartingVertex)
{
startingVertex = newStartingVertex;
tri::ComponentFinder<CMeshO>::Dijkstra(m.cm, *startingVertex, K, this->maxHop, this->NotReachableVector);
ComponentVector.push_back(startingVertex);
}

View File

@ -177,7 +177,7 @@ void EditSelectPlugin::mousePressEvent(QMouseEvent * event, MeshModel &m, GLArea
vector<CMeshO::VertexPointer> NewSelVert;
vector<CMeshO::VertexPointer>::iterator vpi;
GLPickTri<CMeshO>::PickVertSW(mid[0], mid[1], m.cm, NewSelVert, wid[0], wid[1]);
GLPickTri<CMeshO>::PickVert(mid[0], mid[1], m.cm, NewSelVert, wid[0], wid[1]);
glPopMatrix();
tri::UpdateSelection<CMeshO>::VertexClear(m.cm);
@ -200,8 +200,8 @@ void EditSelectPlugin::mousePressEvent(QMouseEvent * event, MeshModel &m, GLArea
}
else
{
if(selectFrontFlag) GLPickTri<CMeshO>::PickFaceVisible(mid[0], mid[1], m.cm, NewSelFace, wid[0], wid[1]);
else GLPickTri<CMeshO>::PickFaceSW(mid[0], mid[1], m.cm, NewSelFace, wid[0], wid[1]);
if(selectFrontFlag) GLPickTri<CMeshO>::PickVisibleFace(mid[0], mid[1], m.cm, NewSelFace, wid[0], wid[1]);
else GLPickTri<CMeshO>::PickFace(mid[0], mid[1], m.cm, NewSelFace, wid[0], wid[1]);
// qDebug("Pickface: rect %i %i - %i %i",mid.x(),mid.y(),wid.x(),wid.y());
// qDebug("Pickface: Got %i on %i",int(NewSelFace.size()),int(m.cm.face.size()));