Select Git revision
MeshObjectSelectionPlugin.cc
-
Edwin Özdemir authoredEdwin Özdemir authored
MeshObjectSelectionPlugin.cc 101.68 KiB
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openflipper.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenFlipper. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
\*===========================================================================*/
#include "MeshObjectSelectionPlugin.hh"
#include "widgets/ParameterWidget.hh"
#include <MeshTools/MeshSelectionT.hh>
//#include <QDesktopWidget>
#include <QColorDialog>
#include <QInputDialog>
#include <QHBoxLayout>
#include <QLabel>
// Primitive type icons
#define VERTEX_TYPE "selection_vertex.png"
#define EDGE_TYPE "selection_edge.png"
#define HEDGE_TYPE "selection_halfedge.png"
#define FACE_TYPE "selection_face.png"
// =======================================
// Define operations
// =======================================
// General:
#define G_CLEAR_HANDLE "Clear Handle Region"
#define G_CLEAR_MODEL "Clear Modeling Region"
#define G_CONVERT "Convert Selection"
// Vertices:
#define V_SELECT_ALL "Select All Vertices"
#define V_CLEAR "Clear Vertex Selection"
#define V_INVERT "Invert Vertex Selection"
#define V_BOUNDARY "Select Boundary Vertices"
#define V_SHRINK "Shrink Vertex Selection"
#define V_GROW "Grow Vertex Selection"
#define V_DELETE "Delete selected Vertices"
#define V_COLORIZE "Colorize selected Vertices"
#define V_COPYSELECTION "Create mesh from Vertex Selection"
#define V_HANDLE "Set to Handle Region"
#define V_MODELING "Set to Modeling Region"
#define V_LOAD_FLIPPER "Load Flipper Selection"
// Edges
#define E_SELECT_ALL "Select All Edges"
#define E_CLEAR "Clear Edge Selection"
#define E_INVERT "Invert Edge Selection"
#define E_DELETE "Delete selected Edges"
#define E_BOUNDARY "Select Boundary Edges"
#define E_COLORIZE "Colorize selected Edges"
#define E_COPYSELECTION "Create mesh from Edge Selection"
#define E_TRACE_PATH "Trace Edge Path"
// Halfedges
#define HE_SELECT_ALL "Select All Halfedges"
#define HE_CLEAR "Clear Halfedge Selection"
#define HE_INVERT "Invert Halfedge Selection"
#define HE_BOUNDARY "Select Boundary Halfedges"
#define HE_COLORIZE "Colorize selected Halfedges"
// Faces
#define F_SELECT_ALL "Select All Faces"
#define F_CLEAR "Clear Face Selection"
#define F_INVERT "Invert Face Selection"
#define F_DELETE "Delete selected Faces"
#define F_BOUNDARY "Select Boundary Faces"
#define F_SHRINK "Shrink Face Selection"
#define F_GROW "Grow Face Selection"
#define F_COLORIZE "Colorize selected Faces"
#define F_COPYSELECTION "Create mesh from Face Selection"
//Colorize
#define C_SELECTIONCOLOR "Selection Color"
#define C_FEATURECOLOR "Feature Color"
#define C_HANDLECOLOR "Handle Color"
#define C_AREACOLOR "Area Color"
/// Default constructor
MeshObjectSelectionPlugin::MeshObjectSelectionPlugin() :
vertexType_(0),
edgeType_(0),
halfedgeType_(0),
faceType_(0),
allSupportedTypes_(0u),
conversionDialog_(0),
parameterWidget_(nullptr),
colorButtonSelection_(0),
colorButtonArea_(0),
colorButtonHandle_(0),
colorButtonFeature_(0),
dihedral_angle_threshold_(0.0),
max_angle_( 2*M_PI)
{
}
MeshObjectSelectionPlugin::~MeshObjectSelectionPlugin() {
delete conversionDialog_;
delete parameterWidget_;
}
void MeshObjectSelectionPlugin::initializePlugin() {
// Tell core about all scriptable slots
updateSlotDescriptions();
// Create conversion dialog
if(!OpenFlipper::Options::nogui()) {
conversionDialog_ = new ConversionDialog(0);
conversionDialog_->hide();
connect(conversionDialog_->convertButton, SIGNAL(clicked()), this, SLOT(conversionRequested()));
// Fill in combo boxes
conversionDialog_->convertFromBox->addItems(
QString("Vertex Selection;Edge Selection;Halfedge Selection;Face Selection;" \
"Feature Vertices;Feature Edges;Feature Faces;Handle Region;Modeling Region").split(";"));
conversionDialog_->convertToBox->addItems(
QString("Vertex Selection;Edge Selection;Halfedge Selection;Face Selection;" \
"Feature Vertices;Feature Edges;Feature Faces;Handle Region;Modeling Region").split(";"));
parameterWidget_ = new ParameterWidget(nullptr);
}
}
void MeshObjectSelectionPlugin::pluginsInitialized() {
// Create new selection environment for mesh objects
// and register mesh types tri- and polymeshes for
// the environment.
QString iconPath = OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator();
emit addSelectionEnvironment("Mesh Object Selections", "Select mesh object primitives such as vertices, (half-)edges and faces.",
iconPath + "selections.png", environmentHandle_);
// Register mesh object types
emit registerType(environmentHandle_, DATA_POLY_MESH);
emit registerType(environmentHandle_, DATA_TRIANGLE_MESH);
// Register mesh primitive types
emit addPrimitiveType(environmentHandle_, "Select Vertices", iconPath + VERTEX_TYPE, vertexType_);
emit addPrimitiveType(environmentHandle_, "Select Edges", iconPath + EDGE_TYPE, edgeType_);
emit addPrimitiveType(environmentHandle_, "Select Halfedges", iconPath + HEDGE_TYPE, halfedgeType_);
emit addPrimitiveType(environmentHandle_, "Select Faces", iconPath + FACE_TYPE, faceType_);
// Combine all supported types
allSupportedTypes_ = (vertexType_ | edgeType_ | halfedgeType_ | faceType_);
// Determine, which selection modes are requested
emit showToggleSelectionMode(environmentHandle_, true, allSupportedTypes_);
emit showSphereSelectionMode(environmentHandle_, true, allSupportedTypes_);
emit showLassoSelectionMode(environmentHandle_, true, allSupportedTypes_);
emit showVolumeLassoSelectionMode(environmentHandle_, true, allSupportedTypes_);
emit showFloodFillSelectionMode(environmentHandle_, true, allSupportedTypes_);
emit showComponentsSelectionMode(environmentHandle_, true, allSupportedTypes_);
emit showClosestBoundarySelectionMode(environmentHandle_, true, allSupportedTypes_);
// Define general operations
QStringList generalOperations;
generalOperations.append(G_CLEAR_HANDLE);
generalOperations.append(G_CLEAR_MODEL);
generalOperations.append(G_CONVERT);
// Define vertex operations
QStringList vertexOperations;
vertexOperations.append(V_SELECT_ALL);
vertexOperations.append(V_CLEAR);
vertexOperations.append(V_INVERT);
vertexOperations.append(V_BOUNDARY);
vertexOperations.append(V_SHRINK);
vertexOperations.append(V_GROW);
vertexOperations.append(V_DELETE);
vertexOperations.append(V_COLORIZE);
vertexOperations.append(V_COPYSELECTION);
vertexOperations.append(V_HANDLE);
vertexOperations.append(V_MODELING);
vertexOperations.append(V_LOAD_FLIPPER);
// Define edge operations
QStringList edgeOperations;
edgeOperations.append(E_SELECT_ALL);
edgeOperations.append(E_CLEAR);
edgeOperations.append(E_INVERT);
edgeOperations.append(E_DELETE);
edgeOperations.append(E_BOUNDARY);
edgeOperations.append(E_COLORIZE);
edgeOperations.append(E_COPYSELECTION);
edgeOperations.append(E_TRACE_PATH);
// Define halfedge operations
QStringList hedgeOperations;
hedgeOperations.append(HE_SELECT_ALL);
hedgeOperations.append(HE_CLEAR);
hedgeOperations.append(HE_INVERT);
hedgeOperations.append(HE_BOUNDARY);
hedgeOperations.append(HE_COLORIZE);
// Define face operations
QStringList faceOperations;
faceOperations.append(F_SELECT_ALL);
faceOperations.append(F_CLEAR);
faceOperations.append(F_INVERT);
faceOperations.append(F_DELETE);
faceOperations.append(F_BOUNDARY);
faceOperations.append(F_SHRINK);
faceOperations.append(F_GROW);
faceOperations.append(F_COLORIZE);
faceOperations.append(F_COPYSELECTION);
// Define colorize operations
QStringList colorOperations;
colorOperations.append(C_SELECTIONCOLOR);
colorOperations.append(C_FEATURECOLOR);
colorOperations.append(C_AREACOLOR);
colorOperations.append(C_HANDLECOLOR);
emit addSelectionOperations(environmentHandle_, generalOperations, "Selection Operations");
emit addSelectionOperations(environmentHandle_, vertexOperations, "Vertex Operations", vertexType_);
emit addSelectionOperations(environmentHandle_, edgeOperations, "Edge Operations", edgeType_);
emit addSelectionOperations(environmentHandle_, hedgeOperations, "Halfedge Operations", halfedgeType_);
emit addSelectionOperations(environmentHandle_, faceOperations, "Face Operations", faceType_);
emit addSelectionOperations(environmentHandle_, colorOperations, "Highlight Operations");
if(!OpenFlipper::Options::nogui())
emit addSelectionParameters(environmentHandle_, parameterWidget_, "Selection Parameters");
// Register key shortcuts:
// Select (a)ll
emit registerKeyShortcut(Qt::Key_A, Qt::ControlModifier);
// (C)lear selection (Only current selection)
emit registerKeyShortcut(Qt::Key_C, Qt::NoModifier);
// (C)lear all selections
emit registerKeyShortcut(Qt::Key_C, Qt::ShiftModifier);
// (I)nvert selection
emit registerKeyShortcut(Qt::Key_I, Qt::NoModifier);
// Delete selected entities
emit registerKeyShortcut(Qt::Key_Delete, Qt::NoModifier);
// Select a vertex by ID
emit registerKeyShortcut(Qt::Key_V, Qt::NoModifier);
// Select a halfedge by ID
emit registerKeyShortcut(Qt::Key_H, Qt::NoModifier);
// Select a edge by ID
emit registerKeyShortcut(Qt::Key_E, Qt::NoModifier);
// Select a face by ID
emit registerKeyShortcut(Qt::Key_F, Qt::NoModifier);
// load default Color values
std::string statusStr = OpenFlipperQSettings().value("SelectionMeshObject/StatusColor",QString()).toString().toStdString();
std::string handleStr = OpenFlipperQSettings().value("SelectionMeshObject/HandleColor",QString()).toString().toStdString();
std::string featureStr = OpenFlipperQSettings().value("SelectionMeshObject/FeatureColor",QString()).toString().toStdString();
std::string areaStr = OpenFlipperQSettings().value("SelectionMeshObject/AreaColor",QString()).toString().toStdString();
if (statusStr.empty() || handleStr.empty() || featureStr.empty() || areaStr.empty())
{
setDefaultColorValues();
}
else
{
std::stringstream sstream;
sstream.str(statusStr);
sstream >> statusColor_;
sstream.str("");
sstream.clear();
sstream.str(handleStr);
sstream >> handleColor_;
sstream.str("");
sstream.clear();
sstream.str(featureStr);
sstream >> featureColor_;
sstream.str("");
sstream.clear();
sstream.str(areaStr);
sstream >> areaColor_;
updateColorValues(); //update GUI
}
}
void MeshObjectSelectionPlugin::updateSlotDescriptions() {
emit setSlotDescription("selectVertices(int,IdList)", tr("Select the specified vertices"),
QString("objectId,vertexList").split(","), QString("Id of object,List of vertices").split(","));
emit setSlotDescription("unselectVertices(int,IdList)", tr("Unselect the specified vertices"),
QString("objectId,vertexList").split(","), QString("Id of object,List of vertices").split(","));
emit setSlotDescription("selectAllVertices(int)", tr("Select all vertices of an object"),
QStringList("objectId"), QStringList("Id of object"));
emit setSlotDescription("clearVertexSelection(int)", tr("Clear vertex selection of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("invertVertexSelection(int)", tr("Invert vertex selection of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("selectBoundaryVertices(int)", tr("Select all boundary vertices of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("selectClosestBoundaryVertices(int,int)", tr("Select boundary vertices closest to a specific vertex"),
QString("objectId,vertexId").split(","), QString("Id of an object,Id of closest vertex").split(","));
emit setSlotDescription("shrinkVertexSelection(int)", tr("Shrink vertex selection by outer selection ring"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("growVertexSelection(int)", tr("Grow vertex selection by an-ring of selection"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("deleteVertexSelection(int)", tr("Delete selected vertices"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("createMeshFromVertexSelection(int)", tr("Take vertex selection and create a new mesh from it"),
QString("objectId").split(","), QString("Id of an object where the selection should be used to create a new mesh").split(","));
emit setSlotDescription("selectVerticesByValue(int,QString,bool,double)", tr("Select vertices based on the value of their component"),
QString("objectId,component,greater,value").split(","),
QString("Id of an object where the selection should be used to create a new mesh,component specification: \"x\" or \"y\" or \"z\" ,true: select vertex if component greater than value; false: select if component less than value ,value to test").split(","));
emit setSlotDescription("colorizeVertexSelection(int,int,int,int)", tr("Colorize the selected vertices"),
QString("objectId,r,g,b").split(","), QString("Id of an object,Red,Green,Blue").split(","));
emit setSlotDescription("selectHandleVertices(int,IdList)", tr("Add specified vertices to handle area"),
QString("objectId,vertexList").split(","), QString("Id of an object,List of vertices").split(","));
emit setSlotDescription("unselectHandleVertices(int,IdList)", tr("Remove specified vertices from handle area"),
QString("objectId,vertexList").split(","), QString("Id of an object,List of vertices").split(","));
emit setSlotDescription("clearHandleVertices(int)", tr("Clear handle area"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("setAllHandleVertices(int)", tr("Add all vertices of an object to handle area"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("selectModelingVertices(int,IdList)", tr("Add specified vertices to modeling area"),
QString("objectId,vertexList").split(","), QString("Id of an object,List of vertices").split(","));
emit setSlotDescription("unselectModelingVertices(int,IdList)", tr("Remove specified vertices to modeling area"),
QString("objectId,vertexList").split(","), QString("Id of an object,List of vertices").split(","));
emit setSlotDescription("clearModelingVertices(int)", tr("Clear modeling area"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("setAllModelingVertices(int)", tr("Add al vertices of an object to modeling area"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("loadSelection(int,QString)", tr("Load selection from selection file"),
QString("objectId,filename").split(","), QString("Id of an object,Selection file").split(","));
emit setSlotDescription("loadFlipperModelingSelection(int,QString)", tr("Load selection from Flipper selection file"),
QString("objectId,filename").split(","), QString("Id of an object,Flipper selection file").split(","));
emit setSlotDescription("saveFlipperModelingSelection(int,QString)", tr("Save selection into Flipper selection file"),
QString("objectId,filename").split(","), QString("Id of an object,Flipper selection file").split(","));
emit setSlotDescription("selectEdges(int,IdList)", tr("Select the specified edges"),
QString("objectId,edgeList").split(","), QString("Id of an object,List of edges").split(","));
emit setSlotDescription("unselectEdges(int,IdList)", tr("Unselect the specified edges"),
QString("objectId,edgeList").split(","), QString("Id of an object,List of edges").split(","));
emit setSlotDescription("selectAllEdges(int)", tr("Select all edges of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("invertEdgeSelection(int)", tr("Invert edge selection of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("clearEdgeSelection(int)", tr("Clear edge selection of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("selectBoundaryEdges(int)", tr("Select all boundary edges of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("colorizeEdgeSelection(int,int,int,int)", tr("Colorize the selected edges"),
QString("objectId,r,g,b").split(","), QString("Id of an object,Red,Green,Blue").split(","));
emit setSlotDescription("createMeshFromEdgeSelection(int)", tr("Take edge selection and create a new mesh from it"),
QString("objectId").split(","), QString("Id of an object where the selection should be used to create a new mesh").split(","));
emit setSlotDescription("selectHalfedges(int,IdList)", tr("Select the specified halfedges"),
QString("objectId,halfedgeList").split(","), QString("Id of an object,List of halfedges").split(","));
emit setSlotDescription("unselectHalfedges(int,IdList)", tr("Unselect the specified halfedges"),
QString("objectId,halfedgeList").split(","), QString("Id of an object,List of halfedges").split(","));
emit setSlotDescription("selectAllHalfedges(int)", tr("Select all halfedges of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("invertHalfedgeSelection(int)", tr("Invert halfedge selection of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("clearHalfedgeSelection(int)", tr("Clear halfedge selection of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("selectBoundaryHalfedges(int)", tr("Select all boundary halfedges of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("colorizeHalfedgeSelection(int,int,int,int)", tr("Colorize the selected halfedges"),
QString("objectId,r,g,b").split(","), QString("Id of an object,Red,Green,Blue").split(","));
emit setSlotDescription("selectFaces(int,IdList)", tr("Select the specified faces"),
QString("objectId,faceList").split(","), QString("Id of an object,List of faces").split(","));
emit setSlotDescription("unselectFaces(int,IdList)", tr("Unselect the specified faces"),
QString("objectId,faceList").split(","), QString("Id of an object,List of faces").split(","));
emit setSlotDescription("selectAllFaces(int)", tr("Select all vertices of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("clearFaceSelection(int)", tr("Clear face selection of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("invertFaceSelection(int)", tr("Invert face selection of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("selectBoundaryFaces(int)", tr("Select all boundary faces of an object"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("shrinkFaceSelection(int)", tr("Shrink face selection by outer face ring of selection"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("growFaceSelection(int)", tr("Grow face selection by an-ring of faces around selection"),
QStringList("objectId"), QStringList("Id of an object"));
emit setSlotDescription("colorizeFaceSelection(int,int,int,int)", tr("Colorize the selected faces"),
QString("objectId,r,g,b").split(","), QString("Id of an object,Red,Green,Blue").split(","));
emit setSlotDescription("createMeshFromFaceSelection(int)", tr("Take face selection and create a new mesh from it"),
QString("objectId").split(","), QString("Id of an object where the selection should be used to create a new mesh").split(","));
QString conversionStrings = tr(" Possible strings:\n"
"- Vertex/Edge/Halfedge/Face Selection\n"
"- Model/Handle Region\n"
"- Feature Vertices/Edges/Faces");
emit setSlotDescription("convertSelection(int,QString,QString,bool)", tr("Convert the selection on given object. Conversion must be given as strings.")+conversionStrings ,
QString("objectId,from,to,deselect").split(","), QString("Id of an object,string of selection which will be converted,resulting selection or area,deselect selection after conversion").split(","));
emit setSlotDescription("conversion(QString,QString,bool)", tr("Convert selection on all target Objects.")+conversionStrings,
QString("from,to,deselect").split(","), QString("string of selection which will be converted,resulting selection region or feature,deselect selection after conversion").split(","));
emit setSlotDescription("convertEdgesToVertexPairs(int,IdList)", tr("Convert edge ids to vertex pair ids. Returns vertex Idlist."),
QString("objectId, edgeIds").split(","), QString("Id of an object, Ids of edges").split(","));
emit setSlotDescription("convertHalfedgesToVertexPairs(int,IdList)", tr("Convert halfedge ids to vertex pair ids. Returns vertex Idlist."),
QString("objectId, halfedgeIds").split(","), QString("Id of an object, Ids of halfedges").split(","));
emit setSlotDescription("convertVertexPairsToHalfedges(int,IdList)", tr("Convert vertex pair ids to halfedge ids. Returns halfedge Idlist."),
QString("objectId, vertexIds").split(","), QString("Id of an object, Ids of paired vertices").split(","));
emit setSlotDescription("convertVertexPairsToEdges(int,IdList)", tr("Convert vertex pair ids to edge ids. Returns edge Idlist."),
QString("objectId, vertexIds").split(","), QString("Id of an object, Ids of paired vertices").split(","));
}
void MeshObjectSelectionPlugin::slotSelectionOperation(QString _operation) {
SelectionInterface::PrimitiveType type = 0u;
emit getActivePrimitiveType(type);
if((type & allSupportedTypes_) == 0)
return;
// Test if operation should be applied to target objects only
bool targetsOnly = false;
emit targetObjectsOnly(targetsOnly);
PluginFunctions::IteratorRestriction restriction =
(targetsOnly ? PluginFunctions::TARGET_OBJECTS : PluginFunctions::ALL_OBJECTS);
if(_operation == G_CLEAR_HANDLE) {
// Clear handle region
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
clearHandleVertices(o_it->id());
}
} else if(_operation == G_CLEAR_MODEL) {
// Clear modeling region
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
clearModelingVertices(o_it->id());
}
} else if(_operation == G_CONVERT) {
// Convert vertex selection
if(!OpenFlipper::Options::nogui())
conversionDialog_->show();
} else if(_operation == V_SELECT_ALL) {
// Select all vertices
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
selectAllVertices(o_it->id());
}
} else if(_operation == V_CLEAR) {
// Clear vertex selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
clearVertexSelection(o_it->id());
}
} else if(_operation == V_INVERT) {
// Invert vertex selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
invertVertexSelection(o_it->id());
}
} else if(_operation == V_BOUNDARY) {
// Select boundary vertices
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
selectBoundaryVertices(o_it->id());
}
} else if(_operation == V_SHRINK) {
// Shrink vertex selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
shrinkVertexSelection(o_it->id());
}
} else if(_operation == V_GROW) {
// Grow vertex selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
growVertexSelection(o_it->id());
}
} else if(_operation == V_DELETE) {
// Delete vertex selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()){
deleteVertexSelection(o_it->id());
emit updatedObject(o_it->id(), UPDATE_GEOMETRY);
emit createBackup(o_it->id(), "Delete Vertices", UPDATE_GEOMETRY);
}
}
} else if(_operation == V_COLORIZE) {
// Colorize vertex selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
setColorForSelection(o_it->id(), vertexType_);
}
}
} else if(_operation == V_COPYSELECTION) {
// Copy vertex selection
std::vector<int> objects;
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
objects.push_back(o_it->id());
}
}
for ( unsigned int i = 0 ; i < objects.size() ; ++i)
createMeshFromSelection(objects[i],vertexType_);
} else if(_operation == V_HANDLE) {
// Set vertex selection to be handle region
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
std::vector<int> ids = getVertexSelection(o_it->id());
selectHandleVertices(o_it->id(), ids);
clearVertexSelection(o_it->id());
}
}
} else if(_operation == V_MODELING) {
// Set vertex selection to be modeling
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
std::vector<int> ids = getVertexSelection(o_it->id());
selectModelingVertices(o_it->id(), ids);
clearVertexSelection(o_it->id());
}
}
} else if(_operation == V_LOAD_FLIPPER) {
// Load Flipper selection file
QString fileName = QFileDialog::getOpenFileName(0,
tr("Open Flipper Selection File"), OpenFlipper::Options::dataDirStr(),
tr("Flipper Selection Files (*.sel)"));
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
loadFlipperModelingSelection(o_it->id(), fileName);
}
}
} else if(_operation == E_SELECT_ALL) {
// Select all edges
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
selectAllEdges(o_it->id());
}
} else if(_operation == E_CLEAR) {
// Clear edge selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
clearEdgeSelection(o_it->id());
}
} else if(_operation == E_INVERT) {
// Invert edge selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
invertEdgeSelection(o_it->id());
}
} else if(_operation == E_DELETE) {
// Delete edge selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
deleteEdgeSelection(o_it->id());
}
} else if(_operation == E_BOUNDARY) {
// Select boundary edges
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
selectBoundaryEdges(o_it->id());
}
} else if(_operation == E_COLORIZE) {
// Colorize edge selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
setColorForSelection(o_it->id(), edgeType_);
}
}
} else if(_operation == E_COPYSELECTION) {
// Copy edge selection
std::vector<int> objects;
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
objects.push_back(o_it->id());
}
}
for ( unsigned int i = 0 ; i < objects.size() ; ++i)
createMeshFromSelection(objects[i],edgeType_);
} else if (_operation == E_TRACE_PATH) {
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
traceEdgePath(o_it->id(), .9);
}
}
} else if(_operation == HE_SELECT_ALL) {
// Select all edges
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
selectAllHalfedges(o_it->id());
}
} else if(_operation == HE_CLEAR) {
// Clear edge selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
clearHalfedgeSelection(o_it->id());
}
} else if(_operation == HE_INVERT) {
// Invert edge selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
invertHalfedgeSelection(o_it->id());
}
} else if(_operation == HE_BOUNDARY) {
// Select boundary edges
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
selectBoundaryHalfedges(o_it->id());
}
} else if(_operation == HE_COLORIZE) {
// Colorize halfedge selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
setColorForSelection(o_it->id(), halfedgeType_);
}
}
} else if(_operation == F_SELECT_ALL) {
// Select all faces
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
selectAllFaces(o_it->id());
}
} else if(_operation == F_CLEAR) {
// Clear face selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
clearFaceSelection(o_it->id());
}
} else if(_operation == F_INVERT) {
// Invert face selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
invertFaceSelection(o_it->id());
}
} else if(_operation == F_DELETE) {
// Delete face selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
deleteFaceSelection(o_it->id());
}
} else if(_operation == F_BOUNDARY) {
// Select boundary faces
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
selectBoundaryFaces(o_it->id());
}
} else if(_operation == F_SHRINK) {
// Shrink face selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
shrinkFaceSelection(o_it->id());
}
} else if(_operation == F_GROW) {
// Grow face selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible())
growFaceSelection(o_it->id());
}
} else if(_operation == F_COLORIZE) {
// Colorize face selection
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
setColorForSelection(o_it->id(), faceType_);
}
}
} else if(_operation == F_COPYSELECTION) {
// Copy face selection
std::vector<int> objects;
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_ALL));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
objects.push_back(o_it->id());
}
}
for ( unsigned int i = 0 ; i < objects.size() ; ++i)
createMeshFromSelection(objects[i],faceType_);
} else if(_operation == C_SELECTIONCOLOR) {
QColor newColor = QColorDialog::getColor(QColor::fromRgbF(statusColor_[0],statusColor_[1],statusColor_[2],statusColor_[3]), 0, "Pick Color", QColorDialog::ShowAlphaChannel);
if (newColor.isValid())
{
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
PolyMeshObject* poly = 0;
PluginFunctions::getObject(o_it->id(),poly);
poly->setSelectionColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
}
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_TRIANGLE_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
TriMeshObject* tri = 0;
PluginFunctions::getObject(o_it->id(),tri);
tri->setSelectionColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
}
emit updateView();
}
}else if(_operation == C_FEATURECOLOR) {
QColor newColor = QColorDialog::getColor(QColor::fromRgbF(featureColor_[0],featureColor_[1],featureColor_[2],featureColor_[3]), 0, "Pick Color", QColorDialog::ShowAlphaChannel);
if (newColor.isValid())
{
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
PolyMeshObject* poly = 0;
PluginFunctions::getObject(o_it->id(),poly);
poly->setFeatureColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
}
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_TRIANGLE_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
TriMeshObject* tri = 0;
PluginFunctions::getObject(o_it->id(),tri);
tri->setFeatureColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
}
emit updateView();
}
}else if(_operation == C_HANDLECOLOR) {
QColor newColor = QColorDialog::getColor(QColor::fromRgbF(handleColor_[0],handleColor_[1],handleColor_[2],handleColor_[3]), 0, "Pick Color", QColorDialog::ShowAlphaChannel);
if (newColor.isValid())
{
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
PolyMeshObject* poly = 0;
PluginFunctions::getObject(o_it->id(),poly);
poly->setHandleColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
}
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_TRIANGLE_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
TriMeshObject* tri = 0;
PluginFunctions::getObject(o_it->id(),tri);
tri->setHandleColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
}
emit updateView();
}
}else if(_operation == C_AREACOLOR) {
QColor newColor = QColorDialog::getColor(QColor::fromRgbF(areaColor_[0],areaColor_[1],areaColor_[2],areaColor_[3]), 0, "Pick Color", QColorDialog::ShowAlphaChannel);
if (newColor.isValid())
{
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
PolyMeshObject* poly = 0;
PluginFunctions::getObject(o_it->id(),poly);
poly->setAreaColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
}
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_TRIANGLE_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
TriMeshObject* tri = 0;
PluginFunctions::getObject(o_it->id(),tri);
tri->setAreaColor(ACG::Vec4f(newColor.redF(),newColor.greenF(),newColor.blueF(),newColor.alphaF()));
}
emit updateView();
}
}
}
void MeshObjectSelectionPlugin::setColorForSelection(const int _objectId, const PrimitiveType _primitiveTypes) {
QColor c = QColorDialog::getColor(Qt::red, 0, tr("Choose color"),QColorDialog::ShowAlphaChannel);
if(c.isValid()) {
if(_primitiveTypes & vertexType_) {
// Vertex colorization
colorizeVertexSelection(_objectId, c.red(), c.green(), c.blue(), c.alpha());
} else if (_primitiveTypes & edgeType_) {
// Edge colorization
colorizeEdgeSelection(_objectId, c.red(), c.green(), c.blue(), c.alpha());
} else if (_primitiveTypes & halfedgeType_) {
// Edge colorization
colorizeHalfedgeSelection(_objectId, c.red(), c.green(), c.blue(), c.alpha());
} else if (_primitiveTypes & faceType_) {
// Edge colorization
colorizeFaceSelection(_objectId, c.red(), c.green(), c.blue(), c.alpha());
}
}
}
void MeshObjectSelectionPlugin::conversionRequested() {
conversionDialog_->hide();
QString from = conversionDialog_->convertFromBox->currentText();
QString to = conversionDialog_->convertToBox->currentText();
if(from == to) return;
bool deselect = true;
if(!OpenFlipper::Options::nogui()) {
deselect = conversionDialog_->deselect->isChecked();
}
conversion(from, to, deselect);
}
void MeshObjectSelectionPlugin::convertSelection(const int& _objectId ,const QString& _from, const QString& _to, bool _deselect) {
BaseObject* object = 0;
PluginFunctions::getObject(_objectId,object);
if ( object == 0 ) {
emit log(LOGERR,"Object not found in convertSelection");
return;
}
if(_from == "Vertex Selection") {
if (_to == "Edge Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertVertexToEdgeSelection(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertVertexToEdgeSelection(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Halfedge Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertVertexToHalfedgeSelection(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertVertexToHalfedgeSelection(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Face Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertVertexToFaceSelection(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertVertexToFaceSelection(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Feature Vertices") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertVertexSelectionToFeatureVertices(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertVertexSelectionToFeatureVertices(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Handle Region") {
selectHandleVertices(_objectId, getVertexSelection(_objectId));
} else if (_to == "Modeling Region") {
selectModelingVertices(_objectId, getVertexSelection(_objectId));
}
if(_deselect) {
clearVertexSelection(_objectId);
}
} else if (_from == "Edge Selection") {
if(_to == "Vertex Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertEdgeToVertexSelection(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertEdgeToVertexSelection(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Halfedge Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertEdgeToHalfedgeSelection(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertEdgeToHalfedgeSelection(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Face Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertEdgeToFaceSelection(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertEdgeToFaceSelection(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Feature Edges") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertEdgeSelectionToFeatureEdges(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertEdgeSelectionToFeatureEdges(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Handle Region") {
if(object->dataType() == DATA_TRIANGLE_MESH) {
TriMesh* mesh = PluginFunctions::triMesh(_objectId);
std::vector<int> ids;
for(auto e_it : mesh->edges()) {
if(mesh->status(e_it).selected()) {
ids.push_back(e_it.h0().to().idx());
ids.push_back(e_it.h1().to().idx());
}
}
selectHandleVertices(_objectId, ids);
} else if(object->dataType() == DATA_POLY_MESH) {
PolyMesh* mesh = PluginFunctions::polyMesh(_objectId);
std::vector<int> ids;
for(auto e_it : mesh->edges()) {
if(mesh->status(e_it).selected()) {
ids.push_back(e_it.h0().to().idx());
ids.push_back(e_it.h1().to().idx());
}
}
selectHandleVertices(_objectId, ids);
}
} else if (_to == "Modeling Region") {
if(object->dataType() == DATA_TRIANGLE_MESH) {
TriMesh* mesh = PluginFunctions::triMesh(_objectId);
std::vector<int> ids;
for(auto e_it : mesh->edges()) {
if(mesh->status(e_it).selected()) {
ids.push_back(e_it.h0().to().idx());
ids.push_back(e_it.h1().to().idx());
}
}
selectModelingVertices(_objectId, ids);
} else if(object->dataType() == DATA_POLY_MESH) {
PolyMesh* mesh = PluginFunctions::polyMesh(_objectId);
std::vector<int> ids;
for(auto e_it : mesh->edges()) {
if(mesh->status(e_it).selected()) {
ids.push_back(e_it.h0().to().idx());
ids.push_back(e_it.h1().to().idx());
}
}
selectModelingVertices(_objectId, ids);
}
}
if(_deselect) {
clearEdgeSelection(_objectId);
}
} else if (_from == "Halfedge Selection") {
if(_to == "Vertex Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertHalfedgeToVertexSelection(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertHalfedgeToVertexSelection(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Edge Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertHalfedgeToEdgeSelection(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertHalfedgeToEdgeSelection(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Face Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertHalfedgeToFaceSelection(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertHalfedgeToFaceSelection(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Handle Region") {
if(object->dataType() == DATA_TRIANGLE_MESH) {
TriMesh* mesh = PluginFunctions::triMesh(_objectId);
std::vector<int> ids;
for(auto h_it : mesh->halfedges()) {
if(mesh->status(h_it).selected()) {
ids.push_back(h_it.to().idx());
ids.push_back(h_it.from().idx());
}
}
selectHandleVertices(_objectId, ids);
} else if(object->dataType() == DATA_POLY_MESH) {
PolyMesh* mesh = PluginFunctions::polyMesh(_objectId);
std::vector<int> ids;
for(auto h_it : mesh->halfedges()) {
if(mesh->status(h_it).selected()) {
ids.push_back(h_it.to().idx());
ids.push_back(h_it.from().idx());
}
}
selectHandleVertices(_objectId, ids);
}
} else if (_to == "Modeling Region") {
if(object->dataType() == DATA_TRIANGLE_MESH) {
TriMesh* mesh = PluginFunctions::triMesh(_objectId);
std::vector<int> ids;
for(auto h_it : mesh->halfedges()) {
if(mesh->status(h_it).selected()) {
ids.push_back(h_it.to().idx());
ids.push_back(h_it.from().idx());
}
}
selectModelingVertices(_objectId, ids);
} else if(object->dataType() == DATA_POLY_MESH) {
PolyMesh* mesh = PluginFunctions::polyMesh(_objectId);
std::vector<int> ids;
for(auto h_it : mesh->halfedges()) {
if(mesh->status(h_it).selected()) {
ids.push_back(h_it.to().idx());
ids.push_back(h_it.from().idx());
}
}
selectModelingVertices(_objectId, ids);
}
}
if(_deselect) {
clearHalfedgeSelection(_objectId);
}
} else if (_from == "Face Selection") {
if(_to == "Vertex Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertFaceToVertexSelection(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertFaceToVertexSelection(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Edge Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertFaceToEdgeSelection(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertFaceToEdgeSelection(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Feature Faces") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertFaceSelectionToFeatureFaces(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertFaceSelectionToFeatureFaces(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Halfedge Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertFaceToHalfedgeSelection(PluginFunctions::triMesh(_objectId));
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertFaceToHalfedgeSelection(PluginFunctions::polyMesh(_objectId));
} else if (_to == "Handle Region") {
if(object->dataType() == DATA_TRIANGLE_MESH) {
TriMesh* mesh = PluginFunctions::triMesh(_objectId);
std::vector<int> ids;
for(auto f_it : mesh->faces()) {
if(mesh->status(f_it).selected()) {
for(auto fv_it : f_it.vertices()) {
ids.push_back(fv_it.idx());
}
}
}
selectHandleVertices(_objectId, ids);
} else if(object->dataType() == DATA_POLY_MESH) {
PolyMesh* mesh = PluginFunctions::polyMesh(_objectId);
std::vector<int> ids;
for(auto f_it : mesh->faces()) {
if(mesh->status(f_it).selected()) {
for(auto fv_it : f_it.vertices()) {
ids.push_back(fv_it.idx());
}
}
}
selectHandleVertices(_objectId, ids);
}
} else if (_to == "Modeling Region") {
if(object->dataType() == DATA_TRIANGLE_MESH) {
TriMesh* mesh = PluginFunctions::triMesh(_objectId);
std::vector<int> ids;
for(auto f_it : mesh->faces()) {
if(mesh->status(f_it).selected()) {
for(auto fv_it : f_it.vertices()) {
ids.push_back(fv_it.idx());
}
}
}
selectModelingVertices(_objectId, ids);
} else if(object->dataType() == DATA_POLY_MESH) {
PolyMesh* mesh = PluginFunctions::polyMesh(_objectId);
std::vector<int> ids;
for(auto f_it : mesh->faces()) {
if(mesh->status(f_it).selected()) {
for(auto fv_it : f_it.vertices()) {
ids.push_back(fv_it.idx());
}
}
}
selectModelingVertices(_objectId, ids);
}
}
if(_deselect) {
clearFaceSelection(_objectId);
}
} else if (_from == "Feature Vertices") {
if (_to == "Vertex Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH) {
MeshSelection::convertFeatureVerticesToVertexSelection(PluginFunctions::triMesh(_objectId));
if (_deselect) {
MeshSelection::clearFeatureVertices(PluginFunctions::triMesh(_objectId));
}
} else if(object->dataType() == DATA_POLY_MESH) {
MeshSelection::convertFeatureVerticesToVertexSelection(PluginFunctions::polyMesh(_objectId));
if (_deselect) {
MeshSelection::clearFeatureVertices(PluginFunctions::polyMesh(_objectId));
}
}
}
} else if (_from == "Feature Edges") {
if (_to == "Edge Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH) {
MeshSelection::convertFeatureEdgesToEdgeSelection(PluginFunctions::triMesh(_objectId));
if (_deselect) {
MeshSelection::clearFeatureEdges(PluginFunctions::triMesh(_objectId));
}
} else if(object->dataType() == DATA_POLY_MESH) {
MeshSelection::convertFeatureEdgesToEdgeSelection(PluginFunctions::polyMesh(_objectId));
if (_deselect) {
MeshSelection::clearFeatureEdges(PluginFunctions::polyMesh(_objectId));
}
}
}
} else if (_from == "Feature Faces") {
if (_to == "Face Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH) {
MeshSelection::convertFeatureFacesToFaceSelection(PluginFunctions::triMesh(_objectId));
if (_deselect) {
MeshSelection::clearFeatureFaces(PluginFunctions::triMesh(_objectId));
}
} else if(object->dataType() == DATA_POLY_MESH) {
MeshSelection::convertFeatureFacesToFaceSelection(PluginFunctions::polyMesh(_objectId));
if (_deselect) {
MeshSelection::clearFeatureFaces(PluginFunctions::polyMesh(_objectId));
}
}
}
} else if (_from == "Handle Region") {
std::vector<int> ids = getHandleVertices(_objectId);
if(_to == "Vertex Selection") {
selectVertices(_objectId, ids);
} else if (_to == "Edge Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertVertexToEdgeSelection(PluginFunctions::triMesh(_objectId), ids);
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertVertexToEdgeSelection(PluginFunctions::polyMesh(_objectId), ids);
} else if (_to == "Halfedge Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertVertexToHalfedgeSelection(PluginFunctions::triMesh(_objectId), ids);
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertVertexToHalfedgeSelection(PluginFunctions::polyMesh(_objectId), ids);
} else if (_to == "Face Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertVertexToFaceSelection(PluginFunctions::triMesh(_objectId), ids);
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertVertexToFaceSelection(PluginFunctions::polyMesh(_objectId), ids);
} else if (_to == "Modeling Region") {
selectModelingVertices(_objectId, ids);
}
if(_deselect) {
clearHandleVertices(_objectId);
}
} else if (_from == "Modeling Region") {
std::vector<int> ids = getModelingVertices(_objectId);
if(_to == "Vertex Selection") {
selectVertices(_objectId, ids);
} else if (_to == "Edge Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertVertexToEdgeSelection(PluginFunctions::triMesh(_objectId), ids);
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertVertexToEdgeSelection(PluginFunctions::polyMesh(_objectId), ids);
} else if (_to == "Halfedge Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertVertexToHalfedgeSelection(PluginFunctions::triMesh(_objectId), ids);
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertVertexToHalfedgeSelection(PluginFunctions::polyMesh(_objectId), ids);
} else if (_to == "Face Selection") {
if(object->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertVertexToFaceSelection(PluginFunctions::triMesh(_objectId), ids);
else if(object->dataType() == DATA_POLY_MESH)
MeshSelection::convertVertexToFaceSelection(PluginFunctions::polyMesh(_objectId), ids);
} else if (_to == "Handle Region") {
selectHandleVertices(_objectId, ids);
}
if(_deselect) {
clearModelingVertices(_objectId);
}
}
emit updatedObject(_objectId, UPDATE_SELECTION);
}
void MeshObjectSelectionPlugin::conversion(const QString& _from, const QString& _to, bool _deselect) {
for (PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS, DataType(DATA_TRIANGLE_MESH | DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
convertSelection(o_it->id(),_from,_to,_deselect);
emit createBackup(o_it->id(), "Selection Conversion", UPDATE_SELECTION);
}
}
void MeshObjectSelectionPlugin::slotToggleSelection(QMouseEvent* _event, SelectionInterface::PrimitiveType _currentType, bool _deselect) {
// Return if none of the currently active types is handled by this plugin
if((_currentType & allSupportedTypes_) == 0) return;
size_t node_idx, target_idx;
ACG::Vec3d hit_point;
// First of all, pick anything to find all possible objects
if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING,
_event->pos(), node_idx, target_idx, &hit_point)) {
BaseObjectData* object(0);
PluginFunctions::getPickedObject(node_idx, object);
if(!object) return;
if (object->dataType() == DATA_TRIANGLE_MESH) {
// Pick triangle meshes
if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(),node_idx, target_idx, &hit_point)) {
if (object->dataType(DATA_TRIANGLE_MESH)) {
toggleMeshSelection(object->id(), PluginFunctions::triMesh(object), target_idx, hit_point, _currentType);
}
} else {
// Pick point cloud
TriMesh* mesh = PluginFunctions::triMesh(object);
if (mesh->n_vertices() && !mesh->n_faces()) {
if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_VERTEX, _event->pos(), node_idx, target_idx, &hit_point)) {
TriMesh::VertexHandle vh = mesh->vertex_handle(target_idx);
mesh->status(vh).set_selected(!mesh->status(vh).selected());
if (mesh->status(vh).selected())
emit scriptInfo("selectVertices(ObjectId(" + QString::number(object->id()) + ") , [" + QString::number(vh.idx()) + "])");
else
emit scriptInfo("unselectVertices(ObjectId(" + QString::number(object->id()) + ") , [" + QString::number(vh.idx()) + "])");
emit updatedObject(object->id(), UPDATE_SELECTION_VERTICES);
}
}
}
} else if (object->dataType() == DATA_POLY_MESH) {
// Pick poly meshes
if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(),node_idx, target_idx, &hit_point)) {
if (object->dataType(DATA_POLY_MESH)) {
toggleMeshSelection(object->id(), PluginFunctions::polyMesh(object), target_idx, hit_point, _currentType);
}
}
}
emit updatedObject(object->id(), UPDATE_SELECTION);
emit createBackup(object->id(), "Toggle Selection", UPDATE_SELECTION);
}
}
void MeshObjectSelectionPlugin::slotLassoSelection(QMouseEvent* _event, PrimitiveType _currentType, bool _deselect) {
// Return if none of the currently active types is handled by this plugin
if((_currentType & allSupportedTypes_) == 0) return;
if(_event->type() == QEvent::MouseButtonPress) {
// Add picked point
lasso_2Dpoints_.push_back(_event->pos());
return;
} else if(_event->type() == QEvent::MouseButtonDblClick) {
// Finish surface lasso selection
if (lasso_2Dpoints_.size() > 2) {
QRegion region(lasso_2Dpoints_);
lassoSelect(region, _currentType, _deselect);
}
// Clear points
lasso_2Dpoints_.clear();
}
}
void MeshObjectSelectionPlugin::slotVolumeLassoSelection(QMouseEvent* _event, PrimitiveType _currentType, bool _deselect) {
// Return if none of the currently active types is handled by this plugin
if((_currentType & allSupportedTypes_) == 0) return;
if(_event->type() == QEvent::MouseButtonPress) {
// Add point on viewing plane to selection polygon
volumeLassoPoints_.append(_event->pos());
return;
} else if(_event->type() == QEvent::MouseButtonDblClick) {
ACG::GLState &state = PluginFunctions::viewerProperties().glState();
bool updateGL = state.updateGL();
state.set_updateGL (false);
QPolygon p(volumeLassoPoints_);
QRegion region = QRegion(p);
SelectVolumeAction action(region, this, _currentType, _deselect, state);
ACG::SceneGraph::traverse (PluginFunctions::getRootNode(), action);
state.set_updateGL(updateGL);
// Clear lasso points
volumeLassoPoints_.clear();
}
}
void MeshObjectSelectionPlugin::slotSphereSelection(QMouseEvent* _event, double _radius, PrimitiveType _currentType, bool _deselect) {
// Return if none of the currently active types is handled by this plugin
if((_currentType & allSupportedTypes_) == 0) return;
size_t node_idx, target_idx;
ACG::Vec3d hit_point;
if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(), node_idx, target_idx, &hit_point)) {
BaseObjectData* object = 0;
if (PluginFunctions::getPickedObject(node_idx, object)) {
if (object->picked(node_idx) && object->dataType(DATA_TRIANGLE_MESH)) {
paintSphereSelection(PluginFunctions::triMesh(object), object->id(), target_idx, hit_point, _radius, _currentType, _deselect);
} else if (object->picked(node_idx) && object->dataType(DATA_POLY_MESH)) {
paintSphereSelection(PluginFunctions::polyMesh(object), object->id(), target_idx, hit_point, _radius, _currentType, _deselect);
}
emit updatedObject(object->id(), UPDATE_SELECTION);
if ( _event->type() == QEvent::MouseButtonRelease )
emit createBackup(object->id(), "Sphere Selection", UPDATE_SELECTION);
}
}
}
void MeshObjectSelectionPlugin::slotClosestBoundarySelection(QMouseEvent* _event, PrimitiveType _currentType, bool _deselect) {
// Return if none of the currently active types is handled by this plugin
if((_currentType & allSupportedTypes_) == 0) return;
size_t node_idx, target_idx;
ACG::Vec3d hit_point;
if(PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos() ,node_idx, target_idx, &hit_point)) {
BaseObjectData* object = 0;
if(PluginFunctions::getPickedObject(node_idx, object)) {
if(object->dataType(DATA_TRIANGLE_MESH)) {
TriMesh* m = PluginFunctions::triMesh(object);
TriMesh::VertexHandle vh = *(m->fv_iter(m->face_handle(target_idx)));
closestBoundarySelection(m, vh.idx(), _currentType, _deselect);
emit updatedObject(object->id(), UPDATE_SELECTION);
emit createBackup(object->id(), "Boundary Selection", UPDATE_SELECTION);
} else if(object->dataType(DATA_POLY_MESH)) {
PolyMesh* m = PluginFunctions::polyMesh(object);
PolyMesh::VertexHandle vh = *(m->fv_iter(m->face_handle(target_idx)));
closestBoundarySelection(m, vh.idx(), _currentType, _deselect);
emit updatedObject(object->id(), UPDATE_SELECTION);
emit createBackup(object->id(), "Boundary Selection", UPDATE_SELECTION);
}
emit updateView();
}
}
}
void MeshObjectSelectionPlugin::slotFloodFillSelection(QMouseEvent* _event, PrimitiveType _currentType, bool _deselect) {
// Return if none of the currently active types is handled by this plugin
if((_currentType & allSupportedTypes_) == 0) return;
size_t node_idx, target_idx;
ACG::Vec3d hit_point;
if(!OpenFlipper::Options::nogui())
max_angle_ = parameterWidget_->maxAngle->value();
// pick Anything to find all possible objects
if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING,
_event->pos(), node_idx, target_idx, &hit_point)) {
BaseObjectData* object = 0;
if(PluginFunctions::getPickedObject(node_idx, object)) {
// TRIANGLE MESHES
if(object->dataType() == DATA_TRIANGLE_MESH) {
if(PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(), node_idx, target_idx, &hit_point)) {
if(PluginFunctions::getPickedObject(node_idx, object)) {
if(object->dataType(DATA_TRIANGLE_MESH)) {
floodFillSelection(
PluginFunctions::triMesh(object),
object->id(), target_idx, max_angle_,
_currentType, _deselect);
emit updatedObject(object->id(), UPDATE_SELECTION);
emit createBackup(object->id(), "FloodFill Selection", UPDATE_SELECTION);
}
}
}
// POLY MESHES
} else if(object->dataType() == DATA_POLY_MESH) {
if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(), node_idx, target_idx, &hit_point)) {
if(PluginFunctions::getPickedObject(node_idx, object) ) {
if(object->dataType(DATA_POLY_MESH)) {
floodFillSelection(
PluginFunctions::polyMesh(object),
object->id(), target_idx, max_angle_,
_currentType, _deselect);
emit updatedObject(object->id(), UPDATE_SELECTION);
emit createBackup(object->id(), "FloodFill Selection", UPDATE_SELECTION);
}
}
}
}
else {
emit log(LOGERR,tr("floodFillSelection: Unsupported dataType"));
}
}
}
}
void MeshObjectSelectionPlugin::slotComponentsSelection(QMouseEvent* _event, SelectionInterface::PrimitiveType _currentType, bool _deselect) {
// Return if none of the currently active types is handled by this plugin
if((_currentType & allSupportedTypes_) == 0) return;
size_t node_idx, target_idx;
ACG::Vec3d hit_point;
// First of all, pick anything to find all possible objects
if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING,
_event->pos(), node_idx, target_idx, &hit_point)) {
BaseObjectData* object(0);
PluginFunctions::getPickedObject(node_idx, object);
if(!object) return;
if (object->dataType() == DATA_TRIANGLE_MESH) {
// Pick triangle meshes
if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(),node_idx, target_idx, &hit_point)) {
if (object->dataType(DATA_TRIANGLE_MESH)) {
componentsMeshSelection(PluginFunctions::triMesh(object),
object->id(), target_idx, hit_point, _currentType);
}
}
} else if (object->dataType() == DATA_POLY_MESH) {
// Pick poly meshes
if (PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_FACE, _event->pos(),node_idx, target_idx, &hit_point)) {
if (object->dataType(DATA_POLY_MESH)) {
componentsMeshSelection(PluginFunctions::polyMesh(object),
object->id(), target_idx, hit_point, _currentType);
}
}
}
emit updatedObject(object->id(), UPDATE_SELECTION);
emit createBackup(object->id(), "Connected Components Selection", UPDATE_SELECTION);
}
}
void MeshObjectSelectionPlugin::slotIndexSelection(int _key)
{
bool targetsOnly = false;
emit targetObjectsOnly(targetsOnly);
PluginFunctions::IteratorRestriction restriction =
(targetsOnly ? PluginFunctions::TARGET_OBJECTS : PluginFunctions::ALL_OBJECTS);
int visible_objects = 0;
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_TRIANGLE_MESH | DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it)
{
if (o_it->visible()) {
++visible_objects;
}
}
bool fly = visible_objects == 1; // only fly to selection if a single object is processed
int idx;
switch (_key)
{
case Qt::Key_V:
idx = QInputDialog::getInt(nullptr, tr("Vertex to mark"), tr("Vertex idx:"), -1);
break;
case Qt::Key_H:
idx = QInputDialog::getInt(nullptr, tr("Halfedge to mark"), tr("Halfedge idx:"), -1);
break;
case Qt::Key_E:
idx = QInputDialog::getInt(nullptr, tr("Edge to mark"), tr("Edge idx:"), -1);
break;
case Qt::Key_F:
idx = QInputDialog::getInt(nullptr, tr("Face to mark"), tr("Face idx:"), -1);
break;
default:
idx = -1;
}
if (idx < 0)
return;
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_TRIANGLE_MESH | DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
bool selected_something = false;
if (o_it->visible()) {
if(_key == Qt::Key_V)
selected_something = selectVertex(o_it->id(), idx, fly);
if(_key == Qt::Key_H)
selected_something = selectHalfedge(o_it->id(), idx, fly);
if(_key == Qt::Key_E)
selected_something = selectEdge(o_it->id(), idx, fly);
if(_key == Qt::Key_F)
selected_something = selectFace(o_it->id(), idx, fly);
}
if (selected_something)
{
emit updatedObject(o_it->id(), UPDATE_SELECTION);
emit createBackup(o_it->id(), "Select Element", UPDATE_SELECTION);
}
}
}
void MeshObjectSelectionPlugin::loadSelection(int _objId, const QString& _filename) {
// Load ini file
INIFile file;
if(!file.connect(_filename, false)) {
emit log(LOGERR, QString("Could not read file '%1'!").arg(_filename));
return;
}
// Load selection from file
loadIniFile(file, _objId);
}
void MeshObjectSelectionPlugin::loadIniFile(INIFile& _ini, int _id) {
BaseObjectData* object = 0;
if (!PluginFunctions::getObject(_id,object)) {
emit log(LOGERR,tr("Cannot find object for id ") + QString::number(_id) + tr(" in saveFile") );
return;
}
std::vector<int> ids;
bool invert = false;
bool updated_selection = false;
bool updated_modeling_regions = false;
QString sectionName = object->name();
if (_ini.get_entry(ids, sectionName ,"ModelingRegion")) {
invert = false;
_ini.get_entry(invert, sectionName, "InvertModeling");
if (invert) {
setAllModelingVertices(object->id());
unselectModelingVertices(object->id() , ids);
} else {
clearModelingVertices(object->id());
selectModelingVertices(object->id(), ids);
}
if(object->dataType(DATA_TRIANGLE_MESH)) {
update_regions(PluginFunctions::triMesh(object));
}
if(object->dataType(DATA_POLY_MESH)) {
update_regions(PluginFunctions::polyMesh(object));
}
updated_modeling_regions = true;
}
if(_ini.get_entry(ids, sectionName, "HandleRegion")) {
invert = false;
_ini.get_entry(invert, sectionName, "InvertHandle");
if(invert) {
setAllHandleVertices(object->id());
unselectHandleVertices(object->id(), ids);
} else {
clearHandleVertices(object->id());
selectHandleVertices(object->id(), ids);
}
if (object->dataType(DATA_TRIANGLE_MESH)) {
update_regions(PluginFunctions::triMesh(object));
}
if(object->dataType(DATA_POLY_MESH)) {
update_regions(PluginFunctions::polyMesh(object));
}
updated_modeling_regions = true;
}
if(_ini.get_entry(ids, sectionName, "VertexSelection")) {
invert = false;
_ini.get_entry(invert, sectionName, "InvertVertexSelection");
if(invert) {
selectAllVertices(object->id());
unselectVertices(object->id(),ids);
} else {
clearVertexSelection(object->id());
selectVertices(object->id(),ids);
}
updated_selection = true;
}
if(_ini.get_entry(ids, sectionName, "EdgeSelection")) {
invert = false;
_ini.get_entry(invert, sectionName, "InvertEdgeSelection");
ids = convertVertexPairsToEdges(_id, ids);
if(invert) {
selectAllEdges(object->id());
unselectEdges(object->id(),ids);
} else {
clearEdgeSelection(object->id());
selectEdges(object->id(),ids);
}
updated_selection = true;
}
if(_ini.get_entry(ids, sectionName, "FaceSelection")) {
invert = false;
_ini.get_entry(invert, sectionName, "InvertFaceSelection");
if(invert) {
selectAllFaces(object->id());
unselectFaces(object->id(),ids);
} else {
clearFaceSelection(object->id());
selectFaces(object->id(),ids);
}
updated_selection = true;
}
if(updated_modeling_regions) {
emit updatedObject(object->id(), UPDATE_ALL);
emit updateView();
} else if(updated_selection) {
emit updatedObject(object->id(), UPDATE_SELECTION);
emit updateView();
}
if ( updated_modeling_regions || updated_selection )
emit createBackup(object->id(), "Load Selection", UPDATE_SELECTION);
}
void MeshObjectSelectionPlugin::saveIniFile(INIFile& _ini, int _id) {
BaseObjectData* object = 0;
if ( !PluginFunctions::getObject(_id,object) ) {
emit log(LOGERR,tr("Cannot find object for id ") + QString::number(_id) + tr(" in saveFile") );
return;
}
// The objects section should already exist
QString sectionName = object->name();
if(!_ini.section_exists(sectionName)) {
emit log(LOGERR,tr("Cannot find object section id ") + QString::number(_id) + tr(" in saveFile") );
return;
}
_ini.add_entry(sectionName, "VertexSelection", getVertexSelection(object->id()));
_ini.add_entry(sectionName, "EdgeSelection", convertEdgesToVertexPairs(_id, getEdgeSelection(object->id())));
if(object->dataType(DATA_POLY_MESH ) || object->dataType( DATA_TRIANGLE_MESH)) {
_ini.add_entry(sectionName, "FaceSelection", getFaceSelection(object->id()));
_ini.add_entry(sectionName, "HandleRegion", getHandleVertices(object->id()));
_ini.add_entry(sectionName, "ModelingRegion", getModelingVertices(object->id()));
}
}
void MeshObjectSelectionPlugin::slotLoadSelection(const INIFile& _file) {
// Iterate over all mesh objects in the scene and save
// the selections for all supported entity types
for (PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS, DataType(DATA_TRIANGLE_MESH | DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
// Read section for each object
// Append object name to section identifier
QString section = QString("MeshObjectSelection") + "//" + o_it->name();
if(!_file.section_exists(section)) {
continue;
}
std::vector<int> ids;
// Load vertex selection:
_file.get_entry(ids, section, "VertexSelection");
selectVertices(o_it->id(), ids);
ids.clear();
// Load edge selection:
_file.get_entry(ids, section, "EdgeSelection");
selectEdges(o_it->id(), convertVertexPairsToEdges(o_it->id(), ids));
ids.clear();
// Load halfedge selection:
_file.get_entry(ids, section, "HalfedgeSelection");
selectHalfedges(o_it->id(), convertVertexPairsToHalfedges(o_it->id(), ids));
ids.clear();
// Load face selection:
_file.get_entry(ids, section, "FaceSelection");
selectFaces(o_it->id(), ids);
ids.clear();
// Load handle region:
_file.get_entry(ids, section, "HandleRegion");
selectHandleVertices(o_it->id(), ids);
ids.clear();
// Load modeling region:
_file.get_entry(ids, section, "ModelingRegion");
selectModelingVertices(o_it->id(), ids);
ids.clear();
emit updatedObject(o_it->id(), UPDATE_SELECTION);
emit createBackup(o_it->id(), "Load Selection", UPDATE_SELECTION);
}
}
void MeshObjectSelectionPlugin::slotSaveSelection(INIFile& _file) {
// Iterate over all mesh objects in the scene and save
// the selections for all supported entity types
for (PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS, DataType(DATA_TRIANGLE_MESH | DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
// Create section for each object
// Append object name to section identifier
QString section = QString("MeshObjectSelection") + "//" + o_it->name();
// Store vertex selection:
_file.add_entry(section, "VertexSelection", getVertexSelection(o_it->id()));
// Store edge selection:
_file.add_entry(section, "EdgeSelection", convertEdgesToVertexPairs(o_it->id(), getEdgeSelection(o_it->id())));
// Store halfedge selection:
_file.add_entry(section, "HalfedgeSelection", convertHalfedgesToVertexPairs(o_it->id(), getHalfedgeSelection(o_it->id())));
// Store face selection:
_file.add_entry(section, "FaceSelection", getFaceSelection(o_it->id()));
// Store handle region:
_file.add_entry(section, "HandleRegion", getHandleVertices(o_it->id()));
// Store modeling region:
_file.add_entry(section, "ModelingRegion", getModelingVertices(o_it->id()));
}
}
void MeshObjectSelectionPlugin::slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers) {
if (((_key == Qt::Key_V) || (_key == Qt::Key_H) || (_key == Qt::Key_E) || (_key == Qt::Key_F)) && _modifiers == Qt::NoModifier)
slotIndexSelection(_key);
SelectionInterface::PrimitiveType type = 0u;
emit getActivePrimitiveType(type);
if((type & allSupportedTypes_) == 0)
{
// No supported type is active
return;
}
bool targetsOnly = false;
emit targetObjectsOnly(targetsOnly);
PluginFunctions::IteratorRestriction restriction =
(targetsOnly ? PluginFunctions::TARGET_OBJECTS : PluginFunctions::ALL_OBJECTS);
if(_key == Qt::Key_A && _modifiers == Qt::ControlModifier) {
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_TRIANGLE_MESH | DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
if(type & vertexType_)
selectAllVertices(o_it->id());
if(type & edgeType_)
selectAllEdges(o_it->id());
if(type & halfedgeType_)
selectAllHalfedges(o_it->id());
if(type & faceType_)
selectAllFaces(o_it->id());
}
emit updatedObject(o_it->id(), UPDATE_SELECTION);
emit createBackup(o_it->id(), "Select All", UPDATE_SELECTION);
}
} else if (_key == Qt::Key_C && ( _modifiers == Qt::NoModifier || _modifiers == Qt::ShiftModifier) ) {
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_TRIANGLE_MESH | DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
if ( _modifiers == Qt::NoModifier ) {
if( type & vertexType_ )
clearVertexSelection(o_it->id());
if(type & edgeType_)
clearEdgeSelection(o_it->id());
if(type & halfedgeType_)
clearHalfedgeSelection(o_it->id());
if(type & faceType_)
clearFaceSelection(o_it->id());
} else { // Shift -> Clear All
clearVertexSelection(o_it->id());
clearEdgeSelection(o_it->id());
clearHalfedgeSelection(o_it->id());
clearFaceSelection(o_it->id());
}
emit updatedObject(o_it->id(), UPDATE_SELECTION);
emit createBackup(o_it->id(), "Clear Selection", UPDATE_SELECTION);
}
}
} else if(_key == Qt::Key_I && _modifiers == Qt::NoModifier) {
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_TRIANGLE_MESH | DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
if(type & vertexType_)
invertVertexSelection(o_it->id());
if(type & edgeType_)
invertEdgeSelection(o_it->id());
if(type & halfedgeType_)
invertHalfedgeSelection(o_it->id());
if(type & faceType_)
invertFaceSelection(o_it->id());
}
emit updatedObject(o_it->id(), UPDATE_SELECTION);
emit createBackup(o_it->id(), "Invert Selection", UPDATE_SELECTION);
}
} else if (_key == Qt::Key_Delete && _modifiers == Qt::NoModifier) {
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_TRIANGLE_MESH | DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
// Delete all selected primitives
if(type & vertexType_)
deleteVertexSelection(o_it->id());
if(type & edgeType_)
deleteEdgeSelection(o_it->id());
if(type & faceType_)
deleteFaceSelection(o_it->id());
}
emit updatedObject(o_it->id(), UPDATE_TOPOLOGY);
emit createBackup(o_it->id(), "Delete Selection", UPDATE_TOPOLOGY);
}
}
}
void MeshObjectSelectionPlugin::slotMouseWheelEvent(QWheelEvent* event, std::string const& mode) {
// Get currently active primitive type
SelectionInterface::PrimitiveType type = 0u;
emit getActivePrimitiveType(type);
// Only handle supported primitive types
if((type & allSupportedTypes_) == 0) {
// No supported type is active
return;
}
// Decide, if all or only target objects should be handled
bool targetsOnly = false;
emit targetObjectsOnly(targetsOnly);
PluginFunctions::IteratorRestriction restriction =
(targetsOnly ? PluginFunctions::TARGET_OBJECTS : PluginFunctions::ALL_OBJECTS);
if(event->modifiers() == Qt::ShiftModifier) {
if (event->angleDelta().y() > 0) {
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_TRIANGLE_MESH | DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
if(type & vertexType_)
growVertexSelection(o_it->id());
if(type & faceType_)
growFaceSelection(o_it->id());
}
emit updatedObject(o_it->id(), UPDATE_SELECTION);
emit createBackup(o_it->id(), "Grow Selection", UPDATE_SELECTION);
}
} else {
for (PluginFunctions::ObjectIterator o_it(restriction, DataType(DATA_TRIANGLE_MESH | DATA_POLY_MESH));
o_it != PluginFunctions::objectsEnd(); ++o_it) {
if (o_it->visible()) {
if(type & vertexType_)
shrinkVertexSelection(o_it->id());
if(type & faceType_)
shrinkFaceSelection(o_it->id());
}
emit updatedObject(o_it->id(), UPDATE_SELECTION);
emit createBackup(o_it->id(), "Shrink Selection", UPDATE_SELECTION);
}
}
}
}
void MeshObjectSelectionPlugin::lassoSelect(QRegion& _region,
PrimitiveType _primitiveType,
bool _deselection) {
// <object id, primitive id>
QList <QPair<size_t, size_t> > list;
if(_primitiveType & vertexType_) {
PluginFunctions::scenegraphRegionPick(ACG::SceneGraph::PICK_FRONT_VERTEX, _region, list);
std::set<int> alreadySelectedObjects;
for(int i = 0; i < list.size(); ++i) {
if(alreadySelectedObjects.count(list[i].first) != 0)
continue;
BaseObjectData* bod = 0;
PluginFunctions::getPickedObject(list[i].first, bod);
if(bod && (bod->dataType() == DATA_TRIANGLE_MESH || bod->dataType() == DATA_POLY_MESH)) {
IdList elements;
for(int j = 0; j < list.size(); ++j) {
if(list[j].first == list[i].first) {
elements.push_back(list[j].second);
}
}
if (!_deselection)
selectVertices(bod->id(), elements);
else
unselectVertices(bod->id(), elements);
alreadySelectedObjects.insert(list[i].first);
emit updatedObject(bod->id(), UPDATE_SELECTION);
emit createBackup(bod->id(), "Lasso Selection", UPDATE_SELECTION);
}
}
}
if(_primitiveType & edgeType_) {
PluginFunctions::scenegraphRegionPick(ACG::SceneGraph::PICK_FRONT_EDGE, _region, list);
std::set<int> alreadySelectedObjects;
for(int i = 0; i < list.size(); ++i) {
if(alreadySelectedObjects.count(list[i].first) != 0)
continue;
BaseObjectData* bod = 0;
PluginFunctions::getPickedObject(list[i].first, bod);
if(bod && (bod->dataType() == DATA_TRIANGLE_MESH || bod->dataType() == DATA_POLY_MESH)) {
IdList elements;
for(int j = 0; j < list.size(); ++j) {
if(list[j].first == list[i].first) {
elements.push_back(list[j].second);
}
}
if (!_deselection)
selectEdges(bod->id(), elements, dihedral_angle_threshold_);
else
unselectEdges(bod->id(), elements);
alreadySelectedObjects.insert(list[i].first);
emit updatedObject(bod->id(), UPDATE_SELECTION);
emit createBackup(bod->id(), "Lasso Selection", UPDATE_SELECTION);
}
}
}
if(_primitiveType & halfedgeType_) {
PluginFunctions::scenegraphRegionPick(ACG::SceneGraph::PICK_FRONT_EDGE, _region, list);
std::set<int> alreadySelectedObjects;
for(int i = 0; i < list.size(); ++i) {
if(alreadySelectedObjects.count(list[i].first) != 0)
continue;
BaseObjectData* bod = 0;
PluginFunctions::getPickedObject(list[i].first, bod);
if(bod && (bod->dataType() == DATA_TRIANGLE_MESH || bod->dataType() == DATA_POLY_MESH)) {
IdList elements;
for(int j = 0; j < list.size(); ++j) {
if(list[j].first == list[i].first) {
elements.push_back(list[j].second);
}
}
IdList oldEdgeSelection = getEdgeSelection(bod->id());
clearEdgeSelection(bod->id());
if (!_deselection)
{
//on selection: select picked edges, convert to halfedge selection
update_dihedral_angle_threshold_from_ui();
selectEdges(bod->id(), elements, dihedral_angle_threshold_);
}
else
{
//on deselection: get current Halfedge Selection, unselect edge, convert back
if(bod->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertHalfedgeToEdgeSelection(PluginFunctions::triMesh(bod));
else if(bod->dataType() == DATA_POLY_MESH)
MeshSelection::convertHalfedgeToEdgeSelection(PluginFunctions::polyMesh(bod));
clearHalfedgeSelection(bod->id());
unselectEdges(bod->id(), elements);
}
if(bod->dataType() == DATA_TRIANGLE_MESH)
MeshSelection::convertEdgeToHalfedgeSelection(PluginFunctions::triMesh(bod));
else if(bod->dataType() == DATA_POLY_MESH)
MeshSelection::convertEdgeToHalfedgeSelection(PluginFunctions::polyMesh(bod));
clearEdgeSelection(bod->id());
selectEdges(bod->id(), oldEdgeSelection);
alreadySelectedObjects.insert(list[i].first);
emit updatedObject(bod->id(), UPDATE_SELECTION);
emit createBackup(bod->id(), "Lasso Selection", UPDATE_SELECTION);
}
}
}
if(_primitiveType & faceType_) {
PluginFunctions::scenegraphRegionPick(ACG::SceneGraph::PICK_FACE, _region, list);
std::set<int> alreadySelectedObjects;
for(int i = 0; i < list.size(); ++i) {
if(alreadySelectedObjects.count(list[i].first) != 0)
continue;
BaseObjectData* bod = 0;
PluginFunctions::getPickedObject(list[i].first, bod);
if(bod && (bod->dataType() == DATA_TRIANGLE_MESH || bod->dataType() == DATA_POLY_MESH)) {
IdList elements;
for(int j = 0; j < list.size(); ++j) {
if(list[j].first == list[i].first) {
elements.push_back(list[j].second);
}
}
if (!_deselection)
selectFaces(bod->id(), elements);
else
unselectFaces(bod->id(), elements);
alreadySelectedObjects.insert(list[i].first);
emit updatedObject(bod->id(), UPDATE_SELECTION);
emit createBackup(bod->id(), "Lasso Selection", UPDATE_SELECTION);
}
}
}
}
/// Traverse the scenegraph and call the selection function for all mesh nodes
bool SelectVolumeAction::operator()(BaseNode* _node) {
BaseObjectData* object = 0;
if(PluginFunctions::getPickedObject(_node->id(), object)) {
bool selected = false;
if (object->dataType(DATA_TRIANGLE_MESH)) {
TriMesh* m = PluginFunctions::triMesh(object);
selected = plugin_->volumeSelection(m, object->id(), state_, ®ion_, type_, deselection_);
} else if(object->dataType(DATA_POLY_MESH)) {
PolyMesh* m = PluginFunctions::polyMesh(object);
selected = plugin_->volumeSelection(m, object->id(), state_, ®ion_, type_, deselection_);
}
if (selected){
emit plugin_->updatedObject(object->id(), UPDATE_SELECTION);
emit plugin_->createBackup( object->id(), "Lasso Selection", UPDATE_SELECTION);
}
}
return true;
}
/// Create a mesh containing the selection of the given mesh
int MeshObjectSelectionPlugin::createMeshFromSelection(int _objectId, PrimitiveType _primitiveType)
{
// get object
BaseObjectData *obj = 0;
PluginFunctions::getObject(_objectId, obj);
if (obj == 0) {
emit log(LOGERR, tr("Unable to get object"));
return -1;
}
if (obj->dataType(DATA_TRIANGLE_MESH)) {
TriMesh* mesh = PluginFunctions::triMesh(obj);
if (mesh == 0) {
emit log(LOGERR, tr("Unable to get mesh"));
return -1;
}
//add an empty mesh
int id = -1;
emit addEmptyObject(DATA_TRIANGLE_MESH, id);
if (id == -1) {
emit log(LOGERR, tr("Unable to add empty object"));
return -1;
}
BaseObjectData *newObj;
PluginFunctions::getObject(id, newObj);
TriMesh* newMesh = PluginFunctions::triMesh(newObj);
if (newMesh == 0) {
emit log(LOGERR, tr("Unable to get mesh"));
return -1;
}
//fill the empty mesh with the selection
createMeshFromSelection(*mesh, *newMesh,_primitiveType);
emit updatedObject(id, UPDATE_ALL);
return id;
} else if (obj->dataType(DATA_POLY_MESH)) {
PolyMesh* mesh = PluginFunctions::polyMesh(obj);
if (mesh == 0) {
emit log(LOGERR, tr("Unable to get mesh"));
return -1;
}
//add an empty mesh
int id;
emit addEmptyObject(DATA_POLY_MESH, id);
if (id == -1) {
emit log(LOGERR, tr("Unable to add empty object"));
return -1;
}
BaseObjectData *newObj;
PluginFunctions::getObject(id, newObj);
PolyMesh* newMesh = PluginFunctions::polyMesh(newObj);
if (newMesh == 0) {
emit log(LOGERR, tr("Unable to get mesh"));
return -1;
}
//fill the empty mesh with the selection
createMeshFromSelection(*mesh, *newMesh,_primitiveType);
emit updatedObject(id, UPDATE_ALL);
return id;
} else {
emit log(LOGERR, tr("DataType not supported"));
return -1;
}
}
void MeshObjectSelectionPlugin::updateColorValues()
{
// apply color values to the gui
if (OpenFlipper::Options::gui())
{
colorButtonSelection_->setColor(QColor::fromRgbF(statusColor_[0],statusColor_[1],statusColor_[2],statusColor_[3]));
colorButtonHandle_->setColor(QColor::fromRgbF(handleColor_[0], handleColor_[1], handleColor_[2], handleColor_[3]));
colorButtonArea_->setColor(QColor::fromRgbF(areaColor_[0],areaColor_[1],areaColor_[2],areaColor_[3]));
colorButtonFeature_->setColor(QColor::fromRgbF(featureColor_[0],featureColor_[1],featureColor_[2],featureColor_[3]));
}
// save new color values
std::stringstream sstream;
sstream << statusColor_;
OpenFlipperQSettings().setValue("SelectionMeshObject/StatusColor",QString(sstream.str().c_str()));
sstream.str("");
sstream.clear();
sstream << handleColor_;
OpenFlipperQSettings().setValue("SelectionMeshObject/HandleColor",QString(sstream.str().c_str()));
sstream.str("");
sstream.clear();
sstream << areaColor_;
OpenFlipperQSettings().setValue("SelectionMeshObject/AreaColor",QString(sstream.str().c_str()));
sstream.str("");
sstream.clear();
sstream << featureColor_;
OpenFlipperQSettings().setValue("SelectionMeshObject/FeatureColor",QString(sstream.str().c_str()));
}
void MeshObjectSelectionPlugin::setDefaultColorValues()
{
statusColor_ = ACG::Vec4f(1.0f,0.0f,0.0f,1.0f);
areaColor_ = ACG::Vec4f(0.4f, 0.4f, 1.0f, 1.0f);
handleColor_ = ACG::Vec4f(0.2f, 1.0f, 0.2f, 1.0f);
featureColor_ = ACG::Vec4f(1.0f, 0.2f, 1.0f, 1.0f);
updateColorValues();
}
bool MeshObjectSelectionPlugin::initializeOptionsWidget(QWidget*& _widget)
{
_widget = new QWidget();
QVBoxLayout* vLayout = new QVBoxLayout();
QHBoxLayout* hLayout = new QHBoxLayout();
hLayout->addWidget(new QLabel("Select default colors for newly created objects. Does not affect already created objects."));
vLayout->addLayout(hLayout);
hLayout = new QHBoxLayout();
colorButtonSelection_ = new QtColorChooserButton();
hLayout->addWidget(new QLabel("Selection Color: "));
hLayout->addWidget(colorButtonSelection_);
vLayout->addLayout(hLayout);
hLayout = new QHBoxLayout();
colorButtonHandle_ = new QtColorChooserButton();
hLayout->addWidget(new QLabel("Handle Color: "));
hLayout->addWidget(colorButtonHandle_);
vLayout->addLayout(hLayout);
hLayout = new QHBoxLayout();
colorButtonFeature_ = new QtColorChooserButton();
hLayout->addWidget(new QLabel("Feature Color: "));
hLayout->addWidget(colorButtonFeature_);
vLayout->addLayout(hLayout);
hLayout = new QHBoxLayout();
colorButtonArea_= new QtColorChooserButton();
hLayout->addWidget(new QLabel("Area Color: "));
hLayout->addWidget(colorButtonArea_);
vLayout->addLayout(hLayout);
hLayout = new QHBoxLayout();
QPushButton* restoreDefault = new QPushButton();
connect(restoreDefault, SIGNAL(clicked()), this, SLOT(setDefaultColorValues()));
restoreDefault->setText("Restore Default");
hLayout->addWidget(restoreDefault);
hLayout->addStretch();
vLayout->addLayout(hLayout);
_widget->setLayout(vLayout);
return true;
}
void MeshObjectSelectionPlugin::applyOptions()
{
statusColor_ = ACG::Vec4f(colorButtonSelection_->color().redF(),colorButtonSelection_->color().greenF(),colorButtonSelection_->color().blueF(),1.f);
areaColor_ = ACG::Vec4f(colorButtonArea_->color().redF(),colorButtonArea_->color().greenF(),colorButtonArea_->color().blueF(),1.f);
handleColor_ = ACG::Vec4f(colorButtonHandle_->color().redF(),colorButtonHandle_->color().greenF(),colorButtonHandle_->color().blueF(),1.f);
featureColor_ = ACG::Vec4f(colorButtonFeature_->color().redF(),colorButtonFeature_->color().greenF(),colorButtonFeature_->color().blueF(),1.f);
updateColorValues();
}
void MeshObjectSelectionPlugin::addedEmptyObject(int _id )
{
if (OpenFlipper::Options::nogui())
return;
PolyMeshObject* polyObj = 0;
TriMeshObject* triObj = 0;
triObj = PluginFunctions::triMeshObject(_id);
polyObj = PluginFunctions::polyMeshObject(_id);
if (triObj)
{
triObj->setSelectionColor(statusColor_);
triObj->setHandleColor(handleColor_);
triObj->setAreaColor(areaColor_);
triObj->setFeatureColor(featureColor_);
}else if (polyObj)
{
polyObj->setSelectionColor(statusColor_);
polyObj->setHandleColor(handleColor_);
polyObj->setAreaColor(areaColor_);
polyObj->setFeatureColor(featureColor_);
}
}
void MeshObjectSelectionPlugin::set_dihedral_angle_threshold(const double _a)
{
dihedral_angle_threshold_ = OpenMesh::deg_to_rad(_a);
}
double MeshObjectSelectionPlugin::get_dihedral_angle_threshold()
{
return dihedral_angle_threshold_;
}
void MeshObjectSelectionPlugin::set_max_angle(const double _a)
{
max_angle_ = _a;
}
double MeshObjectSelectionPlugin::get_max_angle()
{
return max_angle_;
}
void MeshObjectSelectionPlugin::update_dihedral_angle_threshold_from_ui()
{
set_dihedral_angle_threshold( parameterWidget_->minDihedralAngle->value());
}