46 #include "MeshComparePlugin.hh" 52 #include <ACG/Utils/ColorCoder.hh> 54 #include <ACG/Scenegraph/MaterialNode.hh> 55 #include <ACG/QtScenegraph/QtTranslationManipulatorNode.hh> 58 MeshComparePlugin::MeshComparePlugin() :
61 maxNormalDeviation_(-1),
62 maxMeanCurvatureDev_(-1),
63 maxGaussCurvatureDev_(-1)
71 MeshComparePlugin::~MeshComparePlugin()
76 void MeshComparePlugin::initializePlugin()
78 if ( OpenFlipper::Options::gui()) {
81 connect( tool_->compare, SIGNAL(clicked()),
this, SLOT(compareButton()) );
82 connect( tool_->clear, SIGNAL(clicked()),
this, SLOT(slotClear()) );
84 QIcon* toolIcon =
new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"MeshCompare.png");
85 emit addToolbox( tr(
"Mesh Compare") , tool_ , toolIcon);
87 connect(tool_->doClamp,SIGNAL(toggled(
bool)),
this,SLOT(slotClampBox(
bool)));
90 QVBoxLayout* layout =
new QVBoxLayout(tool_->frame);
92 plot_ =
new QwtFunctionPlot(0);
93 plot_->setMinimumHeight(150);
95 layout->addWidget(plot_);
103 void MeshComparePlugin::pluginsInitialized() {
108 emit setSlotDescription(tr(
"compare(int,int)"), tr(
"Compare two meshes. Use lastMaximalDistance() and lastMaximalNormalDeviation() to get the results."),
109 QStringList(tr(
"ObjectId,ObjectId")), QStringList(tr(
"Id of the reference mesh, Id of the comparison mesh")));
110 emit setSlotDescription(tr(
"lastMaximalDistance()"), tr(
"Get the maximal distance between the meshes of the last comparison."),
111 QStringList(tr(
"")), QStringList(tr(
"")));
112 emit setSlotDescription(tr(
"lastMaximalNormalDeviation()"), tr(
"Get the maximal normal deviation in degree between the meshes of the last comparison."),
113 QStringList(tr(
"")), QStringList(tr(
"")));
114 emit setSlotDescription(tr(
"lastMaximalMeanCurvatureDeviation()"), tr(
"Get the maximal mean curvature deviation between the meshes of the last comparison."),
115 QStringList(tr(
"")), QStringList(tr(
"")));
116 emit setSlotDescription(tr(
"lastMaximalGaussCurvatureDeviation()"), tr(
"Get the maximal gauss curvature deviation between the meshes of the last comparison."),
117 QStringList(tr(
"")), QStringList(tr(
"")));
122 bool meanCurvature =
false;
123 emit pluginExists(
"meancurvature" , meanCurvature );
125 if ( OpenFlipper::Options::gui() && !meanCurvature )
126 tool_->meanCurvature->setEnabled(
false);
131 bool gaussCurvature =
false;
132 emit pluginExists(
"gausscurvature" , gaussCurvature );
134 if ( OpenFlipper::Options::gui() && !gaussCurvature )
135 tool_->gaussCurvature->setEnabled(
false);
147 if ( targetObject != 0 ) {
148 emit log(
LOGERR,tr(
"Please select one source and one target mesh to compare! Source will be the reference mesh."));
152 targetObject = (*o_it);
162 if ( sourceObject != 0 ) {
163 emit log(
LOGERR,tr(
"Please select one source and one target mesh to compare! Source will be the reference mesh."));
167 sourceObject = (*o_it);
172 if ( (targetObject != 0) && (sourceObject != 0) ) {
173 compare(sourceObject->
id(),targetObject->
id(), tool_->distance->isChecked() ,
174 tool_->normalAngle->isChecked(),
175 tool_->gaussCurvature->isChecked(),
176 tool_->meanCurvature->isChecked(),
177 tool_->selection->isChecked());
179 emit log(
LOGERR,tr(
"Please select one source and one target mesh to compare! Source will be the reference mesh."));
193 if ( object->
getAdditionalNode(pMatNode,name(),
"MeshCompareDistanceMaterial" ) )
204 if ( o_it->getAdditionalNode(pMatNode,name(),
"MeshCompareDistanceMaterial" ) )
205 o_it->removeAdditionalNode(pMatNode,name(),
"MeshCompareDistanceMaterial");
215 tool_->minVal->setValue(tool_->minValue->text().toDouble());
216 tool_->maxVal->setValue(tool_->maxValue->text().toDouble());
220 void MeshComparePlugin::compare(
int _sourceId,
int _targetId,
bool _computeDist,
bool _computeNormal,
bool _computeGauss ,
bool _computeMean,
bool _selection) {
226 if ( (target == 0 ) || (source == 0) ) {
227 emit log(
LOGERR,tr(
"Please select one source and one target mesh to compare! Source will be the reference mesh."));
228 emit log(
LOGERR,tr(
"Only triangle meshes are currently supported!"));
238 if ( OpenFlipper::Options::gui() ) {
255 pNode->
reserve(refMesh->n_vertices(),refMesh->n_vertices(),refMesh->n_vertices() );
265 bool meanCurvature =
false;
269 if ( _computeMean ) {
270 emit pluginExists(
"meancurvature" , meanCurvature );
272 if ( meanCurvature ) {
278 ((!refMesh->get_property_handle( meanRef ,
"Mean Curvature") ) ||
279 (!compMesh->get_property_handle( meanComp,
"Mean Curvature") ))) {
280 meanCurvature =
false;
287 bool gaussCurvature =
false;
291 if ( _computeGauss ) {
292 emit pluginExists(
"gausscurvature" , gaussCurvature );
294 if ( gaussCurvature ) {
299 if( gaussCurvature &&
300 ((!refMesh->get_property_handle( gaussRef ,
"Gaussian Curvature") ) ||
301 (!compMesh->get_property_handle( gaussComp,
"Gaussian Curvature") ))) {
302 gaussCurvature =
false;
311 maximalDistance_ = -1.0;
312 maxNormalDeviation_ = -1.0;
313 maxMeanCurvatureDev_ = -1.0;
314 maxGaussCurvatureDev_ = -1.0;
318 std::vector<double> distances;
319 std::vector<double> normalAngles;
320 std::vector<double> meanCurvatures;
321 std::vector<double> gaussCurvatures;
324 for (
auto v_it : refMesh->vertices()) {
325 if ( _selection && refMesh->status(v_it).selected() ==
false) {
329 TriMeshObject::OMTriangleBSP::NearestNeighbor nearest = compBSP->
nearest(refMesh->point(v_it));
330 TriMesh::FaceHandle closestFace = nearest.handle;
333 if (nearest.dist > maximalDistance_)
334 maximalDistance_ = nearest.dist;
337 distances.push_back(nearest.dist);
340 TriMesh::CFVIter fv_it = compMesh->cfv_iter(closestFace);
365 if ( _computeNormal) {
368 normal = n0 * projectedPoint[0];
369 normal += n1 * projectedPoint[1];
370 normal += n2 * projectedPoint[2];
374 double normalDeviation = (refMesh->normal(v_it) | normal);
376 if (normalDeviation < -1.0)
377 normalDeviation = -1.0;
378 else if (normalDeviation > 1.0)
379 normalDeviation = 1.0;
381 normalDeviation = 180.0 / M_PI * acos(normalDeviation);
384 normalAngles.push_back(normalDeviation);
386 if (normalDeviation > maxNormalDeviation_)
387 maxNormalDeviation_ = normalDeviation;
393 compMesh->property(meanComp, v1) * projectedPoint[1] +
394 compMesh->property(meanComp, v2) * projectedPoint[2];
396 const double curvatureDev = fabs(refMesh->property(meanRef, v_it) - curvature);
398 meanCurvatures.push_back(curvatureDev);
400 if (curvatureDev > maxMeanCurvatureDev_)
401 maxMeanCurvatureDev_ = curvatureDev;
404 if (gaussCurvature) {
407 compMesh->property(gaussComp, v1) * projectedPoint[1] +
408 compMesh->property(gaussComp, v2) * projectedPoint[2];
410 const double curvatureDev = fabs(refMesh->property(gaussRef, v_it) - curvature);
412 gaussCurvatures.push_back(curvatureDev);
414 if (curvatureDev > maxGaussCurvatureDev_)
415 maxGaussCurvatureDev_ = curvatureDev;
423 tool_->minValue->setText( QString::number(0.0) );
425 if ( tool_->distance->isChecked() ) {
426 visualizeData(distances,maximalDistance_,pNode);
427 }
else if ( tool_->normalAngle->isChecked() ) {
428 visualizeData(normalAngles,maxNormalDeviation_,pNode);
429 }
else if ( tool_->meanCurvature->isChecked() ) {
430 visualizeData(meanCurvatures,maxMeanCurvatureDev_,pNode);
431 }
else if ( tool_->gaussCurvature->isChecked() ) {
432 visualizeData(gaussCurvatures,maxGaussCurvatureDev_,pNode);
443 tool_->maxValue->setText( QString::number(_maxValue) );
448 if ( tool_->doClamp->isChecked() ) {
449 min = tool_->minVal->value();
450 max = std::min(tool_->maxVal->value(),_maxValue);
456 for (
unsigned int i = 0 ; i < _data.size() ; ++i) {
457 _pnode->
add_color(cCoder.color_float4(_data[i]));
461 plot_->setMinMax(min,max);
462 plot_->setFunction( _data );
#define DATA_TRIANGLE_MESH
OMTriangleBSP * requestTriangleBsp()
bool getAdditionalNode(NodeT *&_node, QString _pluginName, QString _nodeName, int _id=0)
get an addition node from the object
void add_color(const ACG::Vec4f &_c)
add color
Kernel::Normal Normal
Normal type.
void reserve(unsigned int _np, unsigned int _nn, unsigned int _nc)
reserve mem for _np points and _nn normals
DrawModes::DrawMode drawMode() const
Return the own draw modes of this node.
QScriptValue callFunction(QString _plugin, QString _functionName, std::vector< QScriptValue > _parameters)
Call a function provided by a plugin getting multiple parameters.
Kernel::Point Point
Coordinate type.
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
void slotObjectUpdated(int _identifier, const UpdateType &_type)
Called when an object gets updated.
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
const QStringList SOURCE_OBJECTS("source")
Iterable object range.
const QStringList ALL_OBJECTS
Iterable object range.
void visualizeData(const std::vector< double > &_data, double _maxValue, ACG::SceneGraph::PointNode *_pnode)
Visualize data.
bool removeAdditionalNode(NodeT *&_node, QString _pluginName, QString _nodeName, int _id=0)
remove an additional node from the object
void slotClampBox(bool _checked)
If the checkbox is changed to be checked, the values in the labels will be written into the spin boxe...
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
void clear()
clear points and normals and colors
QtTranslationManipulatorNode * manipulatorNode()
void add_point(const ACG::Vec3d &_p)
add point
void compareButton()
Triggers comparison of the selected meshes.
void slotClear()
Clears the visualization.
bool baryCoord(const VectorT< Scalar, 3 > &_p, const VectorT< Scalar, 3 > &_u, const VectorT< Scalar, 3 > &_v, const VectorT< Scalar, 3 > &_w, VectorT< Scalar, 3 > &_result)
TriMeshObject * triMeshObject(BaseObjectData *_object)
Cast an BaseObject to a TriMeshObject if possible.
Type for a MeshObject containing a triangle mesh.
Vec::value_type distPointTriangle(const Vec &_p, const Vec &_v0, const Vec &_v1, const Vec &_v2, Vec &_nearestPoint)
distance from point _p to triangle (_v0, _v1, _v2)
bool addAdditionalNode(NodeT *_node, QString _pluginName, QString _nodeName, int _id=0)
add an additional node to the object
unsigned int applyProperties() const
get properties that will be applied (OR'ed ApplyProperties)
const QStringList TARGET_OBJECTS("target")
Iterable object range.
NearestNeighbor nearest(const Point &_p) const
Return handle of the nearest neighbor face.
Kernel::Scalar Scalar
Scalar type.
DrawMode POINTS_COLORED
draw colored, but not lighted points (requires point colors)
ACG::SceneGraph::MaterialNode MaterialNode
Materialnode.
Class for generating nice colors for doubles.
void compare(int _sourceId, int _targetId, bool _computeDist=true, bool _computeNormal=true, bool _computeGauss=true, bool _computeMean=true, bool _selection_=false)
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
void set_point_size(float _sz)
set point size (default: 1.0)