From 342198ea87ea4f2908db29a2e38ba89fe629d9b3 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 31 Dec 2015 21:07:04 +0100 Subject: [PATCH] + support reading mesh files with colors --- src/Mod/Mesh/App/AppMesh.cpp | 1 + src/Mod/Mesh/App/AppMeshPy.cpp | 32 ++++++++++++- src/Mod/Mesh/App/Core/MeshIO.cpp | 10 +++++ src/Mod/Mesh/App/MeshFeature.cpp | 11 +++++ src/Mod/Mesh/App/MeshFeature.h | 2 + src/Mod/Mesh/Gui/ViewProvider.cpp | 75 ++++++++++++++++++++++++++++--- src/Mod/Mesh/Gui/ViewProvider.h | 5 +++ 7 files changed, 129 insertions(+), 7 deletions(-) diff --git a/src/Mod/Mesh/App/AppMesh.cpp b/src/Mod/Mesh/App/AppMesh.cpp index 4b1ed1cb0a38..c749a3bc8e58 100644 --- a/src/Mod/Mesh/App/AppMesh.cpp +++ b/src/Mod/Mesh/App/AppMesh.cpp @@ -83,6 +83,7 @@ void MeshExport initMesh() Mesh::MeshObject ::init(); Mesh::Feature ::init(); + Mesh::FeatureCustom ::init(); Mesh::FeaturePython ::init(); Mesh::Import ::init(); Mesh::Export ::init(); diff --git a/src/Mod/Mesh/App/AppMeshPy.cpp b/src/Mod/Mesh/App/AppMeshPy.cpp index 83694278c296..d672679c53b7 100644 --- a/src/Mod/Mesh/App/AppMeshPy.cpp +++ b/src/Mod/Mesh/App/AppMeshPy.cpp @@ -83,7 +83,8 @@ static PyObject * open(PyObject *self, PyObject *args) PY_TRY { MeshObject mesh; - if (mesh.load(EncodedName.c_str())) { + MeshCore::Material mat; + if (mesh.load(EncodedName.c_str(), &mat)) { Base::FileInfo file(EncodedName.c_str()); // create new document and add Import feature App::Document *pcDoc = App::GetApplication().newDocument("Unnamed"); @@ -98,6 +99,20 @@ static PyObject * open(PyObject *self, PyObject *args) pcFeature->purgeTouched(); } } + else if (mat.binding == MeshCore::MeshIO::PER_VERTEX && + mat.diffuseColor.size() == mesh.countPoints()) { + FeatureCustom *pcFeature = new FeatureCustom(); + pcFeature->Label.setValue(file.fileNamePure().c_str()); + pcFeature->Mesh.swapMesh(mesh); + App::PropertyColorList* prop = static_cast + (pcFeature->addDynamicProperty("App::PropertyColorList", "VertexColors")); + if (prop) { + prop->setValues(mat.diffuseColor); + } + pcFeature->purgeTouched(); + + pcDoc->addObject(pcFeature, file.fileNamePure().c_str()); + } else { Mesh::Feature *pcFeature = static_cast (pcDoc->addObject("Mesh::Feature", file.fileNamePure().c_str())); @@ -132,6 +147,7 @@ static PyObject * importer(PyObject *self, PyObject *args) } MeshObject mesh; + MeshCore::Material mat; if (mesh.load(EncodedName.c_str())) { Base::FileInfo file(EncodedName.c_str()); unsigned long segmct = mesh.countSegments(); @@ -145,6 +161,20 @@ static PyObject * importer(PyObject *self, PyObject *args) pcFeature->purgeTouched(); } } + else if (mat.binding == MeshCore::MeshIO::PER_VERTEX && + mat.diffuseColor.size() == mesh.countPoints()) { + FeatureCustom *pcFeature = new FeatureCustom(); + pcFeature->Label.setValue(file.fileNamePure().c_str()); + pcFeature->Mesh.swapMesh(mesh); + App::PropertyColorList* prop = static_cast + (pcFeature->addDynamicProperty("App::PropertyColorList", "VertexColors")); + if (prop) { + prop->setValues(mat.diffuseColor); + } + pcFeature->purgeTouched(); + + pcDoc->addObject(pcFeature, file.fileNamePure().c_str()); + } else { Mesh::Feature *pcFeature = static_cast (pcDoc->addObject("Mesh::Feature", file.fileNamePure().c_str())); diff --git a/src/Mod/Mesh/App/Core/MeshIO.cpp b/src/Mod/Mesh/App/Core/MeshIO.cpp index 81b648f9ff60..074fdc870161 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.cpp +++ b/src/Mod/Mesh/App/Core/MeshIO.cpp @@ -720,6 +720,16 @@ bool MeshInput::LoadPLY (std::istream &inp) if (num_z != 1) return false; + for (std::vector >::iterator it = + vertex_props.begin(); it != vertex_props.end(); ++it) { + if (it->first == "diffuse_red") + it->first = "red"; + else if (it->first == "diffuse_green") + it->first = "green"; + else if (it->first == "diffuse_blue") + it->first = "blue"; + } + // check if valid colors are set std::size_t num_r = std::count_if(vertex_props.begin(), vertex_props.end(), std::bind2nd(property, "red")); diff --git a/src/Mod/Mesh/App/MeshFeature.cpp b/src/Mod/Mesh/App/MeshFeature.cpp index 6598f5b96b88..8ef2dbacc572 100644 --- a/src/Mod/Mesh/App/MeshFeature.cpp +++ b/src/Mod/Mesh/App/MeshFeature.cpp @@ -97,6 +97,17 @@ void Feature::onChanged(const App::Property* prop) // --------------------------------------------------------- +namespace App { +/// @cond DOXERR +PROPERTY_SOURCE_TEMPLATE(Mesh::FeatureCustom, Mesh::Feature) +/// @endcond + +// explicit template instantiation +template class MeshExport FeatureCustomT; +} + +// --------------------------------------------------------- + namespace App { /// @cond DOXERR PROPERTY_SOURCE_TEMPLATE(Mesh::FeaturePython, Mesh::Feature) diff --git a/src/Mod/Mesh/App/MeshFeature.h b/src/Mod/Mesh/App/MeshFeature.h index 7a0530be74ec..52c36b503b59 100644 --- a/src/Mod/Mesh/App/MeshFeature.h +++ b/src/Mod/Mesh/App/MeshFeature.h @@ -25,6 +25,7 @@ #define MESH_FEATURE_H #include +#include #include #include "Core/MeshKernel.h" @@ -81,6 +82,7 @@ class MeshExport Feature : public App::GeoFeature virtual PyObject* getPyObject(void); }; +typedef App::FeatureCustomT FeatureCustom; typedef App::FeaturePythonT FeaturePython; } //namespace Mesh diff --git a/src/Mod/Mesh/Gui/ViewProvider.cpp b/src/Mod/Mesh/Gui/ViewProvider.cpp index 3af9e8c5ef1c..21ae3f5146ea 100644 --- a/src/Mod/Mesh/Gui/ViewProvider.cpp +++ b/src/Mod/Mesh/Gui/ViewProvider.cpp @@ -498,6 +498,13 @@ void ViewProviderMesh::attach(App::DocumentObject *pcFeat) addDisplayMaskMode(pcFlatWireRoot, "FlatWireframe"); } +void ViewProviderMesh::updateData(const App::Property* prop) +{ + Gui::ViewProviderGeometryObject::updateData(prop); + //if (prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { + //} +} + QIcon ViewProviderMesh::getIcon() const { #if 1 @@ -531,16 +538,70 @@ QIcon ViewProviderMesh::getIcon() const #endif } +App::PropertyColorList* ViewProviderMesh::getColorProperty() const +{ + if (pcObject) { + std::map Map; + pcObject->getPropertyMap(Map); + for (std::map::iterator it = Map.begin(); it != Map.end(); ++it) { + Base::Type type = it->second->getTypeId(); + if (type == App::PropertyColorList::getClassTypeId()) { + App::PropertyColorList* colors = static_cast(it->second); + return colors; + } + } + } + + return 0; // no such property found +} + +void ViewProviderMesh::tryColorPerVertex() +{ + App::PropertyColorList* colors = getColorProperty(); + if (colors) { + const Mesh::PropertyMeshKernel& meshProp = static_cast(pcObject)->Mesh; + const Mesh::MeshObject& mesh = meshProp.getValue(); + int numPoints = static_cast(mesh.countPoints()); + + if (colors->getSize() == numPoints) { + setColorPerVertex(colors); + } + } +} + +void ViewProviderMesh::setColorPerVertex(const App::PropertyColorList* prop) +{ + pcMatBinding->value = SoMaterialBinding::PER_VERTEX; + const std::vector& val = prop->getValues(); + + pcShapeMaterial->diffuseColor.setNum(val.size()); + SbColor* col = pcShapeMaterial->diffuseColor.startEditing(); + + std::size_t i=0; + for (std::vector::const_iterator it = val.begin(); it != val.end(); ++it) { + col[i++].setValue(it->r, it->g, it->b); + } + + pcShapeMaterial->diffuseColor.finishEditing(); +} + void ViewProviderMesh::setDisplayMode(const char* ModeName) { - if (strcmp("Shaded",ModeName)==0) + if (strcmp("Shaded",ModeName)==0) { setDisplayMaskMode("Flat"); - else if (strcmp("Points",ModeName)==0) + } + else if (strcmp("Points",ModeName)==0) { setDisplayMaskMode("Point"); - else if (strcmp("Flat Lines",ModeName)==0) + } + else if (strcmp("Flat Lines",ModeName)==0) { setDisplayMaskMode("FlatWireframe"); - else if (strcmp("Wireframe",ModeName)==0) + } + else if (strcmp("Wireframe",ModeName)==0) { setDisplayMaskMode("Wireframe"); + } + else if (strcmp("Colors",ModeName)==0) { + tryColorPerVertex(); + } ViewProviderGeometryObject::setDisplayMode(ModeName); } @@ -554,6 +615,8 @@ std::vector ViewProviderMesh::getDisplayModes(void) const StrList.push_back("Wireframe"); StrList.push_back("Flat Lines"); StrList.push_back("Points"); + if (getColorProperty()) + StrList.push_back("Colors"); return StrList; } @@ -1799,7 +1862,7 @@ void ViewProviderIndexedFaceSet::attach(App::DocumentObject *pcFeat) void ViewProviderIndexedFaceSet::updateData(const App::Property* prop) { - Gui::ViewProviderGeometryObject::updateData(prop); + ViewProviderMesh::updateData(prop); if (prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { ViewProviderMeshBuilder builder; builder.createMesh(prop, pcMeshCoord, pcMeshFaces); @@ -1884,7 +1947,7 @@ void ViewProviderMeshObject::attach(App::DocumentObject *pcFeat) void ViewProviderMeshObject::updateData(const App::Property* prop) { - Gui::ViewProviderGeometryObject::updateData(prop); + ViewProviderMesh::updateData(prop); if (prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) { const Mesh::PropertyMeshKernel* mesh = static_cast(prop); this->pcMeshNode->mesh.setValue(mesh->getValuePtr()); diff --git a/src/Mod/Mesh/Gui/ViewProvider.h b/src/Mod/Mesh/Gui/ViewProvider.h index de7655f56464..a25e36165dd2 100644 --- a/src/Mod/Mesh/Gui/ViewProvider.h +++ b/src/Mod/Mesh/Gui/ViewProvider.h @@ -50,6 +50,7 @@ class SbPlane; namespace App { class Color; + class PropertyColorList; } namespace Base { @@ -122,6 +123,7 @@ class MeshGuiExport ViewProviderMesh : public Gui::ViewProviderGeometryObject App::PropertyColor LineColor; virtual void attach(App::DocumentObject *); + virtual void updateData(const App::Property*); virtual bool useNewSelectionModel(void) const {return false;} Gui::SoFCSelection* getHighlightNode() const { return pcHighlight; } virtual QIcon getIcon() const; @@ -173,6 +175,9 @@ class MeshGuiExport ViewProviderMesh : public Gui::ViewProviderGeometryObject void unhighlightSelection(); void highlightComponents(); void setHighlightedComponents(bool); + App::PropertyColorList* getColorProperty() const; + void tryColorPerVertex(); + void setColorPerVertex(const App::PropertyColorList*); virtual SoShape* getShapeNode() const; virtual SoNode* getCoordNode() const;