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() );
178 emit log(
LOGERR,tr(
"Please select one source and one target mesh to compare! Source will be the reference mesh."));
192 if ( object->
getAdditionalNode(pMatNode,name(),
"MeshCompareDistanceMaterial" ) )
203 if ( o_it->getAdditionalNode(pMatNode,name(),
"MeshCompareDistanceMaterial" ) )
204 o_it->removeAdditionalNode(pMatNode,name(),
"MeshCompareDistanceMaterial");
214 tool_->minVal->setValue(tool_->minValue->text().toDouble());
215 tool_->maxVal->setValue(tool_->maxValue->text().toDouble());
219 void MeshComparePlugin::compare(
int _sourceId,
int _targetId,
bool _computeDist,
bool _computeNormal,
bool _computeGauss ,
bool _computeMean) {
225 if ( (target == 0 ) || (source == 0) ) {
226 emit log(
LOGERR,tr(
"Please select one source and one target mesh to compare! Source will be the reference mesh."));
227 emit log(
LOGERR,tr(
"Only triangle meshes are currently supported!"));
237 if ( OpenFlipper::Options::gui() ) {
254 pNode->
reserve(refMesh->n_vertices(),refMesh->n_vertices(),refMesh->n_vertices() );
264 bool meanCurvature =
false;
268 if ( _computeMean ) {
269 emit pluginExists(
"meancurvature" , meanCurvature );
271 if ( meanCurvature ) {
277 ((!refMesh->get_property_handle( meanRef ,
"Mean Curvature") ) ||
278 (!compMesh->get_property_handle( meanComp,
"Mean Curvature") ))) {
279 meanCurvature =
false;
286 bool gaussCurvature =
false;
290 if ( _computeGauss ) {
291 emit pluginExists(
"gausscurvature" , gaussCurvature );
293 if ( gaussCurvature ) {
298 if( gaussCurvature &&
299 ((!refMesh->get_property_handle( gaussRef ,
"Gaussian Curvature") ) ||
300 (!compMesh->get_property_handle( gaussComp,
"Gaussian Curvature") ))) {
301 gaussCurvature =
false;
310 maximalDistance_ = -1.0;
311 maxNormalDeviation_ = -1.0;
312 maxMeanCurvatureDev_ = -1.0;
313 maxGaussCurvatureDev_ = -1.0;
317 std::vector<double> distances;
318 std::vector<double> normalAngles;
319 std::vector<double> meanCurvatures;
320 std::vector<double> gaussCurvatures;
322 for ( TriMesh::VertexIter v_it = refMesh->vertices_begin() ; v_it != refMesh->vertices_end(); ++ v_it) {
324 TriMeshObject::OMTriangleBSP::NearestNeighbor nearest = compBSP->
nearest(refMesh->point(*v_it));
325 TriMesh::FaceHandle closestFace = nearest.handle;
328 if (nearest.dist > maximalDistance_)
329 maximalDistance_ = nearest.dist;
332 distances.push_back(nearest.dist);
335 TriMesh::CFVIter fv_it = compMesh->cfv_iter(closestFace);
360 if ( _computeNormal) {
363 normal = n0 * projectedPoint[0];
364 normal += n1 * projectedPoint[1];
365 normal += n2 * projectedPoint[2];
369 double normalDeviation = (refMesh->normal(*v_it) | normal);
371 if (normalDeviation < -1.0)
372 normalDeviation = -1.0;
373 else if (normalDeviation > 1.0)
374 normalDeviation = 1.0;
376 normalDeviation = 180.0 / M_PI * acos(normalDeviation);
379 normalAngles.push_back(normalDeviation);
381 if (normalDeviation > maxNormalDeviation_)
382 maxNormalDeviation_ = normalDeviation;
388 compMesh->property(meanComp, v1) * projectedPoint[1] +
389 compMesh->property(meanComp, v2) * projectedPoint[2];
391 const double curvatureDev = fabs(refMesh->property(meanRef, *v_it) - curvature);
393 meanCurvatures.push_back(curvatureDev);
395 if (curvatureDev > maxMeanCurvatureDev_)
396 maxMeanCurvatureDev_ = curvatureDev;
399 if (gaussCurvature) {
402 compMesh->property(gaussComp, v1) * projectedPoint[1] +
403 compMesh->property(gaussComp, v2) * projectedPoint[2];
405 const double curvatureDev = fabs(refMesh->property(gaussRef, *v_it) - curvature);
407 gaussCurvatures.push_back(curvatureDev);
409 if (curvatureDev > maxGaussCurvatureDev_)
410 maxGaussCurvatureDev_ = curvatureDev;
418 tool_->minValue->setText( QString::number(0.0) );
420 if ( tool_->distance->isChecked() ) {
421 visualizeData(distances,maximalDistance_,pNode);
422 }
else if ( tool_->normalAngle->isChecked() ) {
423 visualizeData(normalAngles,maxNormalDeviation_,pNode);
424 }
else if ( tool_->meanCurvature->isChecked() ) {
425 visualizeData(meanCurvatures,maxMeanCurvatureDev_,pNode);
426 }
else if ( tool_->gaussCurvature->isChecked() ) {
427 visualizeData(gaussCurvatures,maxGaussCurvatureDev_,pNode);
438 tool_->maxValue->setText( QString::number(_maxValue) );
443 if ( tool_->doClamp->isChecked() ) {
444 min = tool_->minVal->value();
445 max = std::min(tool_->maxVal->value(),_maxValue);
451 for (
unsigned int i = 0 ; i < _data.size() ; ++i) {
452 _pnode->
add_color(cCoder.color_float4(_data[i]));
456 plot_->setMinMax(min,max);
457 plot_->setFunction( _data );
void add_point(const ACG::Vec3d &_p)
add point
ACG::SceneGraph::MaterialNode MaterialNode
Materialnode.
void slotObjectUpdated(int _identifier, const UpdateType &_type)
Called when an object gets updated.
void clear()
clear points and normals and colors
void compare(int _sourceId, int _targetId, bool _computeDist=true, bool _computeNormal=true, bool _computeGauss=true, bool _computeMean=true)
Kernel::Point Point
Coordinate type.
NearestNeighbor nearest(const Point &_p) const
Return handle of the nearest neighbor face.
DrawMode POINTS_COLORED
draw colored, but not lighted points (requires point colors)
const QStringList SOURCE_OBJECTS("source")
Iterable object range.
OMTriangleBSP * requestTriangleBsp()
DrawModes::DrawMode drawMode() const
Return the own draw modes of this node.
bool getAdditionalNode(NodeT *&_node, QString _pluginName, QString _nodeName, int _id=0)
get an addition node from the object
Kernel::Scalar Scalar
Scalar type.
void visualizeData(const std::vector< double > &_data, double _maxValue, ACG::SceneGraph::PointNode *_pnode)
Visualize data.
const QStringList TARGET_OBJECTS("target")
Iterable object range.
TriMeshObject * triMeshObject(BaseObjectData *_object)
Cast an BaseObject to a TriMeshObject if possible.
QScriptValue callFunction(QString _plugin, QString _functionName, std::vector< QScriptValue > _parameters)
Call a function provided by a plugin getting multiple parameters.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
const QStringList ALL_OBJECTS
Iterable object range.
bool addAdditionalNode(NodeT *_node, QString _pluginName, QString _nodeName, int _id=0)
add an additional node to the object
void add_color(const ACG::Vec4f &_c)
add color
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
Type for a MeshObject containing a triangle mesh.
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...
Kernel::Normal Normal
Normal type.
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)
void slotClear()
Clears the visualization.
void compareButton()
Triggers comparison of the selected meshes.
unsigned int applyProperties() const
get properties that will be applied (OR'ed ApplyProperties)
Class for generating nice colors for doubles.
void set_point_size(float _sz)
set point size (default: 1.0)
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
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)
void reserve(unsigned int _np, unsigned int _nn, unsigned int _nc)
reserve mem for _np points and _nn normals
#define DATA_TRIANGLE_MESH
QtTranslationManipulatorNode * manipulatorNode()