/*===========================================================================*\ * * * 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. * * * \*===========================================================================*/ #define OVM_PROPERTY_VISUALIZER_CC #ifdef ENABLE_POLYHEDRALMESH_SUPPORT #include #endif #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT #include #endif #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT #include #endif #include "OVMPropertyVisualizer.hh" #include template template QString OVMPropertyVisualizer::getPropertyText_(unsigned int index) { if (PropertyVisualizer::propertyInfo.isCellProp()) { OpenVolumeMesh::CellPropertyT prop = OVMPropertyVisualizer::mesh->template request_cell_property(OVMPropertyVisualizer::propertyInfo.propName()); return PropertyVisualizer::toStr(prop[OpenVolumeMesh::CellHandle(index)]); } else if (PropertyVisualizer::propertyInfo.isFaceProp()) { OpenVolumeMesh::FacePropertyT prop = OVMPropertyVisualizer::mesh->template request_face_property(OVMPropertyVisualizer::propertyInfo.propName()); return PropertyVisualizer::toStr(prop[OpenVolumeMesh::FaceHandle(index)]); } else if (PropertyVisualizer::propertyInfo.isHalffaceProp()) { OpenVolumeMesh::HalfFacePropertyT prop = OVMPropertyVisualizer::mesh->template request_halfface_property(OVMPropertyVisualizer::propertyInfo.propName()); return PropertyVisualizer::toStr(prop[OpenVolumeMesh::HalfFaceHandle(index)]); } else if (PropertyVisualizer::propertyInfo.isEdgeProp()) { OpenVolumeMesh::EdgePropertyT prop = OVMPropertyVisualizer::mesh->template request_edge_property(OVMPropertyVisualizer::propertyInfo.propName()); return PropertyVisualizer::toStr(prop[OpenVolumeMesh::EdgeHandle(index)]); } else if (PropertyVisualizer::propertyInfo.isHalfedgeProp()) { OpenVolumeMesh::HalfEdgePropertyT prop = OVMPropertyVisualizer::mesh->template request_halfedge_property(OVMPropertyVisualizer::propertyInfo.propName()); return PropertyVisualizer::toStr(prop[OpenVolumeMesh::HalfEdgeHandle(index)]); } else //if (propertyInfo.isVertexProp()) { OpenVolumeMesh::VertexPropertyT prop = OVMPropertyVisualizer::mesh->template request_vertex_property(OVMPropertyVisualizer::propertyInfo.propName()); return PropertyVisualizer::toStr(prop[OpenVolumeMesh::VertexHandle(index)]); } } template void OVMPropertyVisualizer::setPropertyFromText(unsigned int index, QString text) { if (propertyInfo.isCellProp()) setCellPropertyFromText(index, text); else if (propertyInfo.isFaceProp()) setFacePropertyFromText(index, text); else if (propertyInfo.isHalffaceProp()) setHalffacePropertyFromText(index, text); else if (propertyInfo.isEdgeProp()) setEdgePropertyFromText(index, text); else if (propertyInfo.isHalfedgeProp()) setHalfedgePropertyFromText(index, text); else //if (propertyInfo.isVertexProp()) setVertexPropertyFromText(index, text); } template int OVMPropertyVisualizer::getEntityCount() { if (propertyInfo.isCellProp()) return mesh->n_cells(); if (propertyInfo.isFaceProp()) return mesh->n_faces(); if (propertyInfo.isHalffaceProp()) return mesh->n_halffaces(); else if (propertyInfo.isEdgeProp()) return mesh->n_edges(); else if (propertyInfo.isHalfedgeProp()) return mesh->n_halfedges(); else //if (propertyInfo.isVertexProp()) return mesh->n_vertices(); } template QString OVMPropertyVisualizer::getHeader() { //Header: headerVersion, numberOfEntities, typeOfEntites, typeOfProperty, propertyName QString header = QObject::tr("1"); //version header.append(QObject::tr(", %1").arg(getEntityCount())); //number of entities header.append(QObject::tr(", %1").arg(propertyInfo.entityType())); //type of entities header.append(", ").append(propertyInfo.friendlyTypeName()); //type of property header.append(", ").append(propertyInfo.propName().c_str()); // name of property return header; } template unsigned int OVMPropertyVisualizer::getClosestPrimitiveId(unsigned int _face, ACG::Vec3d& _hitPoint) { if (propertyInfo.isHalffaceProp()) return getClosestHalffaceId(_face, _hitPoint); else// if (propertyInfo.isHalfedgeProp()) return getClosestHalfedgeId(_face, _hitPoint); } template unsigned int OVMPropertyVisualizer::getClosestHalffaceId(unsigned int _face, ACG::Vec3d& _hitPoint) { ACG::Vec3d direction = PluginFunctions::viewingDirection(); OpenVolumeMesh::HalfFaceHandle hfh = mesh->halfface_handle(OpenVolumeMesh::FaceHandle(_face), 0); OpenVolumeMesh::HalfFaceVertexIter hfv_it = mesh->hfv_iter(hfh); ACG::Vec3d p1 = mesh->vertex(*(hfv_it+0)); ACG::Vec3d p2 = mesh->vertex(*(hfv_it+1)); ACG::Vec3d p3 = mesh->vertex(*(hfv_it+2)); ACG::Vec3d normal = (p2-p1)%(p3-p1); if ((direction | normal) < 0) return hfh.idx(); else return mesh->halfface_handle(OpenVolumeMesh::FaceHandle(_face), 1).idx(); } template unsigned int OVMPropertyVisualizer::getClosestHalfedgeId(unsigned int _face, ACG::Vec3d& _hitPoint) { OpenVolumeMesh::HalfFaceHandle halfface = OpenVolumeMesh::HalfFaceHandle(getClosestHalffaceId(_face, _hitPoint)); OpenVolumeMesh::OpenVolumeMeshFace face = mesh->halfface(halfface); const std::vector & halfedges = face.halfedges(); double min_distance = DBL_MAX; OpenVolumeMesh::HalfEdgeHandle closestHalfEdgeHandle; for (std::vector::const_iterator he_it = halfedges.begin(); he_it != halfedges.end(); ++he_it) { OpenVolumeMesh::OpenVolumeMeshEdge edge = OVMPropertyVisualizer::mesh->halfedge(*he_it); ACG::Vec3d v1 = mesh->vertex(edge.from_vertex()); ACG::Vec3d v2 = mesh->vertex(edge.to_vertex()); ACG::Vec3d p = 0.5 * (v1+v2); double distance = (p-_hitPoint).length(); if (distance < min_distance) { min_distance = distance; closestHalfEdgeHandle = *he_it; } } return closestHalfEdgeHandle.idx(); } template void OVMPropertyVisualizer::visualize(bool _setDrawMode, QWidget* _widget) { QWidget* tmp; if (_widget) { tmp = widget; widget = _widget; } if (propertyInfo.isCellProp()) visualizeCellProp(_setDrawMode); else if (propertyInfo.isFaceProp()) visualizeFaceProp(_setDrawMode); else if (propertyInfo.isHalffaceProp()) visualizeHalffaceProp(_setDrawMode); else if (propertyInfo.isEdgeProp()) visualizeEdgeProp(_setDrawMode); else if (propertyInfo.isHalfedgeProp()) visualizeHalfedgeProp(_setDrawMode); else if (propertyInfo.isVertexProp()) visualizeVertexProp(_setDrawMode); if (_widget) { widget = tmp; } } template void OVMPropertyVisualizer::visualizeFaceProp(bool /*_setDrawMode*/) { emit log(LOGERR, "Visualizing FaceProp not implemented"); } template void OVMPropertyVisualizer::visualizeEdgeProp(bool /*_setDrawMode*/) { emit log(LOGERR, "Visualizing EdgeProp not implemented"); } template void OVMPropertyVisualizer::visualizeHalfedgeProp(bool /*_setDrawMode*/) { emit log(LOGERR, "Visualizing HalfedgeProp not implemented"); } template void OVMPropertyVisualizer::visualizeVertexProp(bool /*_setDrawMode*/) { emit log(LOGERR, "Visualizing VertexProp not implemented"); } template void OVMPropertyVisualizer::visualizeCellProp(bool /*_setDrawMode*/) { emit log(LOGERR, "Visualizing CellProp not implemented"); } template void OVMPropertyVisualizer::visualizeHalffaceProp(bool /*_setDrawMode*/) { emit log(LOGERR, "Visualizing HalffaceProp not implemented"); } template template inline void OVMPropertyVisualizer::duplicateProperty_stage1() { std::string newPropertyName; for (int i = 1;; ++i) { std::ostringstream oss; oss << propertyInfo.propName() << " Copy " << i; newPropertyName = oss.str(); if (propertyInfo.isCellProp()) { if(!mesh->template cell_property_exists(newPropertyName)) break; } else if (propertyInfo.isFaceProp()) { if(!mesh->template face_property_exists(newPropertyName)) break; } else if (propertyInfo.isHalffaceProp()) { if(!mesh->template halfface_property_exists(newPropertyName)) break; } else if (propertyInfo.isEdgeProp()) { if(!mesh->template edge_property_exists(newPropertyName)) break; } else if (propertyInfo.isHalfedgeProp()) { if(!mesh->template halfedge_property_exists(newPropertyName)) break; } else if (propertyInfo.isVertexProp()) { if(!mesh->template vertex_property_exists(newPropertyName)) break; } } if (propertyInfo.isCellProp()) { OpenVolumeMesh::CellPropertyT prop = mesh->template request_cell_property(OVMPropertyVisualizer::propertyInfo.propName()); OpenVolumeMesh::CellPropertyT newProp = mesh->template request_cell_property< PropType >(newPropertyName); mesh->set_persistent(newProp, true); std::for_each(mesh->cells_begin(), mesh->cells_end(), CopyProperty >(newProp, prop, mesh)); } else if (propertyInfo.isFaceProp()) { OpenVolumeMesh::FacePropertyT prop = mesh->template request_face_property(OVMPropertyVisualizer::propertyInfo.propName()); OpenVolumeMesh::FacePropertyT newProp = mesh->template request_face_property< PropType >(newPropertyName); mesh->set_persistent(newProp, true); std::for_each(mesh->faces_begin(), mesh->faces_end(), CopyProperty >(newProp, prop, mesh)); } else if (propertyInfo.isHalffaceProp()) { OpenVolumeMesh::HalfFacePropertyT prop = mesh->template request_halfface_property(OVMPropertyVisualizer::propertyInfo.propName()); OpenVolumeMesh::HalfFacePropertyT newProp = mesh->template request_halfface_property< PropType >(newPropertyName); mesh->set_persistent(newProp, true); std::for_each(mesh->halffaces_begin(), mesh->halffaces_end(), CopyProperty >(newProp, prop, mesh)); } else if (propertyInfo.isEdgeProp()) { OpenVolumeMesh::EdgePropertyT prop = mesh->template request_edge_property(OVMPropertyVisualizer::propertyInfo.propName()); OpenVolumeMesh::EdgePropertyT newProp = mesh->template request_edge_property< PropType >(newPropertyName); mesh->set_persistent(newProp, true); std::for_each(mesh->edges_begin(), mesh->edges_end(), CopyProperty >(newProp, prop, mesh)); } else if (propertyInfo.isHalfedgeProp()) { OpenVolumeMesh::HalfEdgePropertyT prop = mesh->template request_halfedge_property(OVMPropertyVisualizer::propertyInfo.propName()); OpenVolumeMesh::HalfEdgePropertyT newProp = mesh->template request_halfedge_property< PropType >(newPropertyName); mesh->set_persistent(newProp, true); std::for_each(mesh->halfedges_begin(), mesh->halfedges_end(), CopyProperty >(newProp, prop, mesh)); } else if (propertyInfo.isVertexProp()) { OpenVolumeMesh::VertexPropertyT prop = mesh->template request_vertex_property(OVMPropertyVisualizer::propertyInfo.propName()); OpenVolumeMesh::VertexPropertyT newProp = mesh->template request_vertex_property< PropType >(newPropertyName); mesh->set_persistent(newProp, true); std::for_each(mesh->vertices_begin(), mesh->vertices_end(), CopyProperty >(newProp, prop, mesh)); } } template void OVMPropertyVisualizer::clear() { VolumeMeshObject* object; PluginFunctions::getObject(OVMPropertyVisualizer::mObjectID, object); if (propertyInfo.isCellProp()) object->colors().clear_cell_colors(); else if (propertyInfo.isFaceProp()) object->colors().clear_face_colors(); else if (propertyInfo.isHalffaceProp()) object->colors().clear_halfface_colors(); else if (propertyInfo.isEdgeProp()) object->colors().clear_edge_colors(); else if (propertyInfo.isHalfedgeProp()) object->colors().clear_halfedge_colors(); else if (propertyInfo.isVertexProp()) object->colors().clear_vertex_colors(); object->setObjectDrawMode(drawModes.cellsFlatShaded); } template void OVMPropertyVisualizer::setCellPropertyFromText(unsigned int /*index*/, QString /*text*/) { emit log(LOGERR, "Setting CellProp not implemented for this property type"); } template void OVMPropertyVisualizer::setFacePropertyFromText(unsigned int /*index*/, QString /*text*/) { emit log(LOGERR, "Setting FaceProp not implemented for this property type"); } template void OVMPropertyVisualizer::setHalffacePropertyFromText(unsigned int /*index*/, QString /*text*/) { emit log(LOGERR, "Setting HalffaceProp not implemented for this property type"); } template void OVMPropertyVisualizer::setEdgePropertyFromText(unsigned int /*index*/, QString /*text*/) { emit log(LOGERR, "Setting EdgeProp not implemented for this property type"); } template void OVMPropertyVisualizer::setHalfedgePropertyFromText(unsigned int /*index*/, QString /*text*/) { emit log(LOGERR, "Setting HalfedgeProp not implemented for this property type"); } template void OVMPropertyVisualizer::setVertexPropertyFromText(unsigned int /*index*/, QString /*text*/) { emit log(LOGERR, "Setting VertexProp not implemented for this property type"); } template template void OVMPropertyVisualizer::showHistogram(ACG::QtWidgets::QtHistogramWidget *histogramWidget) { using PV = OVMPropertyVisualizer; const std::string &prop_name = PV::propertyInfo.propName(); switch (PropertyVisualizer::propertyInfo.entityType()) { case PropertyInfo::EF_CELL: this->showHistogramT( histogramWidget, PV::mesh->template request_cell_property(prop_name)); break; case PropertyInfo::EF_FACE: this->showHistogramT( histogramWidget, PV::mesh->template request_face_property(prop_name)); break; case PropertyInfo::EF_HALFFACE: this->showHistogramT( histogramWidget, PV::mesh->template request_halfface_property(prop_name)); break; case PropertyInfo::EF_EDGE: this->showHistogramT( histogramWidget, PV::mesh->template request_edge_property(prop_name)); break; case PropertyInfo::EF_HALFEDGE: this->showHistogramT( histogramWidget, PV::mesh->template request_halfedge_property(prop_name)); break; case PropertyInfo::EF_VERTEX: this->showHistogramT( histogramWidget, PV::mesh->template request_vertex_property(prop_name)); break; case PropertyInfo::EF_ANY: assert(false); } }