/*===========================================================================*\ * * * OpenFlipper * * Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen * * www.openflipper.org * * * *---------------------------------------------------------------------------* * This file is part of OpenFlipper. * * * * OpenFlipper is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 3 of * * the License, or (at your option) any later version with the * * following exceptions: * * * * If other files instantiate templates or use macros * * or inline functions from this file, or you compile this file and * * link it with other files to produce an executable, this file does * * not by itself cause the resulting executable to be covered by the * * GNU Lesser General Public License. This exception does not however * * invalidate any other reasons why the executable file might be * * covered by the GNU Lesser General Public License. * * * * OpenFlipper is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Lesser General Public License for more details. * * * * You should have received a copy of the GNU LesserGeneral Public * * License along with OpenFlipper. If not, * * see . * * * \*===========================================================================*/ /*===========================================================================*\ * * * $Revision: 83 $ * * $Author: moebius $ * * $Date: 2009-02-27 17:31:45 +0100 (Fr, 27. Feb 2009) $ * * * \*===========================================================================*/ #include "InfoPlugin.hh" #include #include #include //------------------------------------------------------------------------------ /** \brief set the descriptions for scripting slots * */ void InfoPlugin::setDescriptions(){ emit setSlotDescription("vertexCount(int)",tr("get total number of vertices for a given object"), QStringList(tr("objectID")), QStringList(tr("id of an object"))); emit setSlotDescription("edgeCount(int)",tr("get total number of edges for a given object"), QStringList(tr("objectID")), QStringList(tr("id of an object"))); emit setSlotDescription("faceCount(int)",tr("get total number of faces for a given object"), QStringList(tr("objectID")), QStringList(tr("id of an object"))); emit setSlotDescription("boundaryCount(int)",tr("get number of boundaries for a given object"), QStringList(tr("objectID")), QStringList(tr("id of an object"))); emit setSlotDescription("componentCount(int)",tr("get number of components for a given object"), QStringList(tr("objectID")), QStringList(tr("id of an object"))); emit setSlotDescription("genus(int)",tr("get the genus of a given object"), QStringList(tr("objectID")), QStringList(tr("id of an object"))); emit setSlotDescription("cog(int)",tr("get the center of gravity for a given object"), QStringList(tr("objectID")), QStringList(tr("id of an object"))); emit setSlotDescription("boundingBoxMin(int)",tr("get minimum point of the axis-aligned bounding box"), QStringList(tr("objectID")), QStringList(tr("id of an object"))); emit setSlotDescription("boundingBoxMax(int)",tr("get maximum point of the axis-aligned bounding box"), QStringList(tr("objectID")), QStringList(tr("id of an object"))); emit setSlotDescription("boundingBoxSize(int)",tr("get the size of the axis-aligned bounding box"), QStringList(tr("objectID")), QStringList(tr("id of an object"))); emit setSlotDescription("edgeLength(int,int)",tr("Get the length of an edge"), QString(tr("ObjectId,EdgeHandle")).split(","), QString(tr("id of the object, handle of an edge")).split(",")); emit setSlotDescription("faceArea(int,int)",tr("Get the area of a face"), QString(tr("ObjectId,FaceHandle")).split(","), QString(tr("id of the object, handle of a face")).split(",")); emit setSlotDescription("aspectRatio(int,int)",tr("Get the aspect ratio of a face"), QString(tr("ObjectId,FaceHandle")).split(","), QString(tr("id of the object, handle of a face")).split(",")); emit setSlotDescription("vertexValence(int,int)",tr("Get the valence of a vertex"), QString(tr("ObjectId,VertexHandle")).split(","), QString(tr("id of the object, handle of a vertex")).split(",")); emit setSlotDescription("minEdgeLength(int)",tr("Get the minimal edge length of an object"), QStringList(tr("ObjectId")), QStringList(tr("id of the object"))); emit setSlotDescription("maxEdgeLength(int)",tr("Get the maximal edge length of an object"), QStringList(tr("ObjectId")), QStringList(tr("id of the object"))); emit setSlotDescription("meanEdgeLength(int)",tr("Get the mean edge length of an object"), QStringList(tr("ObjectId")), QStringList(tr("id of the object"))); } //------------------------------------------------------------------------------ /** \brief get total number of vertices for a given object * * @param _id object id * @return number of vertices or -1 if an error occured */ int InfoPlugin::vertexCount(int _id) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return -1; if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return -1; } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } return mesh->n_vertices(); } else { PolyMesh* mesh = PluginFunctions::polyMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } return mesh->n_vertices(); } } //------------------------------------------------------------------------------ /** \brief get total number of edges for a given object * * @param _id object id * @return number of edges or -1 if an error occured */ int InfoPlugin::edgeCount(int _id) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return -1; if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return -1; } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } return mesh->n_edges(); } else { PolyMesh* mesh = PluginFunctions::polyMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } return mesh->n_edges(); } } //------------------------------------------------------------------------------ /** \brief get total number of faces for a given object * * @param _id object id * @return number of faces or -1 if an error occured */ int InfoPlugin::faceCount(int _id) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return -1; if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return -1; } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } return mesh->n_faces(); } else { PolyMesh* mesh = PluginFunctions::polyMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } return mesh->n_faces(); } } //------------------------------------------------------------------------------ /** \brief get the number of boundaries for a given object * * @param _id object id * @return number of boundaries or -1 if an error occured */ int InfoPlugin::boundaryCount(int _id) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return -1; if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return -1; } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } return MeshInfo::boundaryCount(mesh); } else { PolyMesh* mesh = PluginFunctions::polyMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } return MeshInfo::boundaryCount(mesh); } } //------------------------------------------------------------------------------ /** \brief get the number of components for a given object * * @param _id object id * @return number of components or -1 if an error occured */ int InfoPlugin::componentCount(int _id) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return -1; if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return -1; } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } return MeshInfo::componentCount(mesh); } else { PolyMesh* mesh = PluginFunctions::polyMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } return MeshInfo::componentCount(mesh); } } //------------------------------------------------------------------------------ /** \brief get the genus of the given object * * @param _id id of an object * @return the genus */ int InfoPlugin::genus(int _id) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return -1; if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return -1; } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } ///TODO this formula only works for closed objects: fix it return (1 - (mesh->n_vertices() - mesh->n_edges() + mesh->n_faces() ) / 2); } else { PolyMesh* mesh = PluginFunctions::polyMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } return (1 - (mesh->n_vertices() - mesh->n_edges() + mesh->n_faces() ) / 2); } } //------------------------------------------------------------------------------ /** \brief get the center of gravity * * @param _id id of an object * @return the center of gravity */ Vector InfoPlugin::cog(int _id) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return Vector(); if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return Vector(); } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return Vector(); } return MeshInfo::cog(*mesh); } else { PolyMesh* mesh = PluginFunctions::polyMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return Vector(); } return MeshInfo::cog(*mesh); } } //------------------------------------------------------------------------------ /** \brief get minimum point of the (axis aligned) bounding box * * @param _id id of an object * @return minimum point of the bounding box */ Vector InfoPlugin::boundingBoxMin(int _id) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return Vector(); if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return Vector(); } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return Vector(); } ACG::Vec3d min; ACG::Vec3d max; MeshInfo::getBoundingBox(*mesh, min, max); return min; } else { PolyMesh* mesh = PluginFunctions::polyMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return Vector(); } ACG::Vec3d min; ACG::Vec3d max; MeshInfo::getBoundingBox(*mesh, min, max); return min; } } //------------------------------------------------------------------------------ /** \brief get maximum point of the (axis aligned) bounding box * * @param _id id of an object * @return maximum point of the bounding box */ Vector InfoPlugin::boundingBoxMax(int _id) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return Vector(); if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return Vector(); } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return Vector(); } ACG::Vec3d min; ACG::Vec3d max; MeshInfo::getBoundingBox(*mesh, min, max); return max; } else { PolyMesh* mesh = PluginFunctions::polyMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return Vector(); } ACG::Vec3d min; ACG::Vec3d max; MeshInfo::getBoundingBox(*mesh, min, max); return max; } } //------------------------------------------------------------------------------ /** \brief get the size of the (axis aligned) bounding box * * @param _id id of an object * @return size of the bounding box */ Vector InfoPlugin::boundingBoxSize(int _id) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return Vector(); if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return Vector(); } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return Vector(); } ACG::Vec3d min; ACG::Vec3d max; MeshInfo::getBoundingBox(*mesh, min, max); return (max - min); } else { PolyMesh* mesh = PluginFunctions::polyMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return Vector(); } ACG::Vec3d min; ACG::Vec3d max; MeshInfo::getBoundingBox(*mesh, min, max); return (max - min); } } //------------------------------------------------------------------------------ /** \brief get the length of an edge * * @param _id id of an object * @param _edgeHandle edge handle * @return edge length or -1 if an error occured */ double InfoPlugin::edgeLength(int _id, int _edgeHandle) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return -1.0; if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return -1.0; } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1.0; } TriMesh::EdgeHandle eh( _edgeHandle ); if ( !eh.is_valid() ) { emit log(LOGERR,tr("Unable to get edge handle")); return -1.0; } TriMesh::HalfedgeHandle hh = mesh->halfedge_handle( eh, 0 ); TriMesh::Point p0 = mesh->point( mesh->from_vertex_handle(hh) ); TriMesh::Point p1 = mesh->point( mesh->to_vertex_handle(hh) ); return (p0 - p1).norm(); } else { PolyMesh* mesh = PluginFunctions::polyMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1.0; } PolyMesh::EdgeHandle eh( _edgeHandle ); if ( !eh.is_valid() ) { emit log(LOGERR,tr("Unable to get edge handle")); return -1.0; } PolyMesh::HalfedgeHandle hh = mesh->halfedge_handle( eh, 0 ); PolyMesh::Point p0 = mesh->point( mesh->from_vertex_handle(hh) ); PolyMesh::Point p1 = mesh->point( mesh->to_vertex_handle(hh) ); return (p0 - p1).norm(); } } //------------------------------------------------------------------------------ /** \brief get the area of a face * * @param _id id of an object * @param _faceHandle face handle * @return face area or -1 if an error occured */ double InfoPlugin::faceArea(int _id, int _faceHandle) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return -1.0; if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return -1.0; } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1.0; } TriMesh::FaceHandle fh( _faceHandle ); if ( !fh.is_valid() ) { emit log(LOGERR,tr("Unable to get face handle")); return -1.0; } TriMesh::FaceVertexIter fv_it = mesh->fv_iter(fh); TriMesh::Point v0 = mesh->point( fv_it.handle() ); ++fv_it; TriMesh::Point v1 = mesh->point( fv_it.handle() ); ++fv_it; TriMesh::Point v2 = mesh->point( fv_it.handle() ); return ACG::Geometry::triangleArea( v0, v1, v2 ); } else { PolyMesh* mesh = PluginFunctions::polyMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1.0; } PolyMesh::FaceHandle fh( _faceHandle ); if ( !fh.is_valid() ) { emit log(LOGERR,tr("Unable to get face handle")); return -1.0; } PolyMesh::FaceVertexIter fv_it; std::vector< PolyMesh::Point > vertices; for (fv_it = mesh->fv_iter(fh); fv_it; ++fv_it) vertices.push_back( mesh->point( fv_it.handle() ) ); ///TODO implement polygonArea emit log(LOGERR,tr("Not implemented yet")); return -1.0; // return ACG::Geometry::polygonArea( vertices ); } } //------------------------------------------------------------------------------ /** \brief get the aspect ratio of a face * * @param _id id of an object * @param _faceHandle face handle * @return aspect ratio or -1 if an error occured */ double InfoPlugin::aspectRatio(int _id, int _faceHandle) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return -1.0; if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return -1.0; } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1.0; } TriMesh::FaceHandle fh( _faceHandle ); if ( !fh.is_valid() ) { emit log(LOGERR,tr("Unable to get face handle")); return -1.0; } TriMesh::FaceVertexIter fv_it = mesh->fv_iter(fh); TriMesh::Point v0 = mesh->point( fv_it.handle() ); ++fv_it; TriMesh::Point v1 = mesh->point( fv_it.handle() ); ++fv_it; TriMesh::Point v2 = mesh->point( fv_it.handle() ); return ACG::Geometry::aspectRatio( v0, v1, v2 ); } else { emit log(LOGERR,tr("Aspect ratio can only be calculated for triangle meshes")); return -1.0; } } //------------------------------------------------------------------------------ /** \brief get vertex valence * * @param _id id of an object * @param _vertexHandle vertex handle * @return vertex valence or -1 if an error occured */ int InfoPlugin::vertexValence (int _id, int _vertexHandle) { BaseObjectData* object; if ( ! PluginFunctions::getObject(_id,object) ) return -1; if ( object == 0){ emit log(LOGERR, tr("Unable to get object")); return -1; } if ( object->dataType(DATA_TRIANGLE_MESH) ) { TriMesh* mesh = PluginFunctions::triMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } TriMesh::VertexHandle vh( _vertexHandle ); if ( !vh.is_valid() ) { emit log(LOGERR,tr("Unable to get vertex handle")); return -1; } //check valence int valence = 0; TriMesh::VertexVertexIter vv_it; for (vv_it=mesh->vv_iter( vh ); vv_it; ++vv_it) valence++; return valence; } else { PolyMesh* mesh = PluginFunctions::polyMesh(object); if ( mesh == 0 ) { emit log(LOGERR, tr("Unable to get mesh")); return -1; } PolyMesh::VertexHandle vh( _vertexHandle ); if ( !vh.is_valid() ) { emit log(LOGERR,tr("Unable to get vertex handle")); return -1; } //check valence int valence = 0; PolyMesh::VertexVertexIter vv_it; for (vv_it=mesh->vv_iter( vh ); vv_it; ++vv_it) valence++; return valence; } } //------------------------------------------------------------------------------ /** \brief get minimal edge length for a given object * * @param _id object id * @return minimal edge length or -1 if an error occured */ double InfoPlugin::minEdgeLength(int _id) { double min, max, mean; if (getEdgeLengths (_id, min, max, mean)) return min; else return -1; } //------------------------------------------------------------------------------ /** \brief get maximal edge length for a given object * * @param _id object id * @return maximal edge length or -1 if an error occured */ double InfoPlugin::maxEdgeLength(int _id) { double min, max, mean; if (getEdgeLengths (_id, min, max, mean)) return max; else return -1; } //------------------------------------------------------------------------------ /** \brief get the mean edge length for a given object * * @param _id object id * @return mean edge length or -1 if an error occured */ double InfoPlugin::meanEdgeLength(int _id) { double min, max, mean; if (getEdgeLengths (_id, min, max, mean)) return mean; else return -1; }