diff --git a/src/Mod/Mesh/App/Core/MeshIO.cpp b/src/Mod/Mesh/App/Core/MeshIO.cpp index 6c7827734..4003e019c 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.cpp +++ b/src/Mod/Mesh/App/Core/MeshIO.cpp @@ -661,7 +661,8 @@ bool MeshInput::LoadPLY (std::istream &inp) return false; // wrong header std::string line, element; - bool xyz_float=false,xyz_double=false,rgb_value=false; + bool xyz_float=false,xyz_double=false; + MeshIO::Binding rgb_value = MeshIO::OVERALL; while (std::getline(inp, line)) { std::istringstream str(line); str.unsetf(std::ios_base::skipws); @@ -738,7 +739,11 @@ bool MeshInput::LoadPLY (std::istream &inp) xyz_double = true; } else if (name == "red") { - rgb_value = true; + rgb_value = MeshIO::PER_VERTEX; + if (_material) { + _material->binding = MeshIO::PER_VERTEX; + _material->diffuseColor.reserve(v_count); + } } } else if (element == "face") { @@ -753,9 +758,38 @@ bool MeshInput::LoadPLY (std::istream &inp) boost::regex rx_p("^([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)\\s*$"); + boost::regex rx_c("^([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([-+]?[0-9]*)\\.?([0-9]+([eE][-+]?[0-9]+)?)" + "\\s+([0-9]{1,3})\\s+([0-9]{1,3})\\s+([0-9]{1,3})\\s*$"); boost::regex rx_f("^\\s*3\\s+([0-9]+)\\s+([0-9]+)\\s+([0-9]+)\\s*$"); boost::cmatch what; Base::Vector3f pt; + + if (rgb_value == MeshIO::PER_VERTEX) { + int r,g,b; + for (std::size_t i = 0; i < v_count && std::getline(inp, line); i++) { + if (boost::regex_match(line.c_str(), what, rx_c)) { + pt.x = (float)std::atof(what[1].first); + pt.y = (float)std::atof(what[4].first); + pt.z = (float)std::atof(what[7].first); + meshPoints.push_back(pt); + if (_material) { + r = std::min(std::atoi(what[10].first),255); + g = std::min(std::atoi(what[11].first),255); + b = std::min(std::atoi(what[12].first),255); + float fr = (float)r/255.0f; + float fg = (float)g/255.0f; + float fb = (float)b/255.0f; + _material->diffuseColor.push_back(App::Color(fr, fg, fb)); + } + } + else { + return false; + } + } + } + else { for (std::size_t i = 0; i < v_count && std::getline(inp, line); i++) { if (boost::regex_match(line.c_str(), what, rx_p)) { pt.x = (float)std::atof(what[1].first); @@ -767,6 +801,7 @@ bool MeshInput::LoadPLY (std::istream &inp) return false; } } + } int f1, f2, f3; for (std::size_t i = 0; i < f_count && std::getline(inp, line); i++) { if (boost::regex_match(line.c_str(), what, rx_f)) { @@ -777,6 +812,7 @@ bool MeshInput::LoadPLY (std::istream &inp) } } } + // binary else { Base::InputStream is(inp); if (format == binary_little_endian) @@ -789,16 +825,31 @@ bool MeshInput::LoadPLY (std::istream &inp) for (std::size_t i = 0; i < v_count; i++) { is >> pt.x >> pt.y >> pt.z; meshPoints.push_back(pt); - if (rgb_value) + if (rgb_value == MeshIO::PER_VERTEX) { is >> r >> g >> b; + if (_material) { + float fr = (float)r/255.0f; + float fg = (float)g/255.0f; + float fb = (float)b/255.0f; + _material->diffuseColor.push_back(App::Color(fr, fg, fb)); + } + } } } else if (xyz_double) { Base::Vector3d pt; for (std::size_t i = 0; i < v_count; i++) { is >> pt.x >> pt.y >> pt.z; - is >> r >> g >> b; meshPoints.push_back(Base::Vector3f((float)pt.x,(float)pt.y,(float)pt.z)); + if (rgb_value == MeshIO::PER_VERTEX) { + is >> r >> g >> b; + if (_material) { + float fr = (float)r/255.0f; + float fg = (float)g/255.0f; + float fb = (float)b/255.0f; + _material->diffuseColor.push_back(App::Color(fr, fg, fb)); + } + } } } unsigned char n; @@ -1428,7 +1479,12 @@ bool MeshOutput::SaveAny(const char* FileName, MeshIO::Format format) const } else if (fileformat == MeshIO::PLY) { // write file - if (!SavePLY(str)) + if (!SaveBinaryPLY(str)) + throw Base::FileException("Export of PLY mesh failed",FileName); + } + else if (fileformat == MeshIO::APLY) { + // write file + if (!SaveAsciiPLY(str)) throw Base::FileException("Export of PLY mesh failed",FileName); } else if (fileformat == MeshIO::IV) { @@ -1646,7 +1702,7 @@ bool MeshOutput::SaveOFF (std::ostream &out) const return true; } -bool MeshOutput::SavePLY (std::ostream &out) const +bool MeshOutput::SaveBinaryPLY (std::ostream &out) const { const MeshPointArray& rPoints = _rclMesh.GetPoints(); const MeshFacetArray& rFacets = _rclMesh.GetFacets(); @@ -1706,6 +1762,81 @@ bool MeshOutput::SavePLY (std::ostream &out) const return true; } +bool MeshOutput::SaveAsciiPLY (std::ostream &out) const +{ + const MeshPointArray& rPoints = _rclMesh.GetPoints(); + const MeshFacetArray& rFacets = _rclMesh.GetFacets(); + std::size_t v_count = rPoints.size(); + std::size_t f_count = rFacets.size(); + if (!out || out.bad() == true) + return false; + + bool saveVertexColor = (_material && _material->binding == MeshIO::PER_VERTEX + && _material->diffuseColor.size() == rPoints.size()); + out << "ply" << std::endl + << "format ascii 1.0" << std::endl + << "comment Created by FreeCAD " << std::endl + << "element vertex " << v_count << std::endl + << "property float32 x" << std::endl + << "property float32 y" << std::endl + << "property float32 z" << std::endl; + if (saveVertexColor) { + out << "property uchar red" << std::endl + << "property uchar green" << std::endl + << "property uchar blue" << std::endl; + } + out << "element face " << f_count << std::endl + << "property list uchar int vertex_index" << std::endl + << "end_header" << std::endl; + + Base::Vector3f pt; + + out.precision(6); + out.setf(std::ios::fixed | std::ios::showpoint); + if (saveVertexColor) { + for (std::size_t i = 0; i < v_count; i++) { + const MeshPoint& p = rPoints[i]; + if (this->apply_transform) { + Base::Vector3f pt = this->_transform * p; + out << pt.x << " " << pt.y << " " << pt.z; + } + else { + out << p.x << " " << p.y << " " << p.z; + } + + const App::Color& c = _material->diffuseColor[i]; + int r = (int)(255.0f * c.r); + int g = (int)(255.0f * c.g); + int b = (int)(255.0f * c.b); + out << " " << r << " " << g << " " << b << std::endl; + } + } + else { + for (std::size_t i = 0; i < v_count; i++) { + const MeshPoint& p = rPoints[i]; + if (this->apply_transform) { + Base::Vector3f pt = this->_transform * p; + out << pt.x << " " << pt.y << " " << pt.z << std::endl; + } + else { + out << p.x << " " << p.y << " " << p.z << std::endl; + } + } + } + + unsigned int n = 3; + int f1, f2, f3; + for (std::size_t i = 0; i < f_count; i++) { + const MeshFacet& f = rFacets[i]; + f1 = (int)f._aulPoints[0]; + f2 = (int)f._aulPoints[1]; + f3 = (int)f._aulPoints[2]; + out << n << " " << f1 << " " << f2 << " " << f3 << std::endl; + } + + return true; +} + bool MeshOutput::SaveMeshNode (std::ostream &rstrOut) { const MeshPointArray& rPoints = _rclMesh.GetPoints(); diff --git a/src/Mod/Mesh/App/Core/MeshIO.h b/src/Mod/Mesh/App/Core/MeshIO.h index e45d9f64e..b439f1bd2 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.h +++ b/src/Mod/Mesh/App/Core/MeshIO.h @@ -51,6 +51,7 @@ namespace MeshIO { WRZ, NAS, PLY, + APLY, PY }; enum Binding { @@ -74,7 +75,10 @@ struct MeshExport Material class MeshExport MeshInput { public: - MeshInput (MeshKernel &rclM): _rclMesh(rclM){}; + MeshInput (MeshKernel &rclM) + : _rclMesh(rclM), _material(0){} + MeshInput (MeshKernel &rclM, Material* m) + : _rclMesh(rclM), _material(m){} virtual ~MeshInput (void) { } /// Loads the file, decided by extension @@ -106,6 +110,7 @@ public: protected: MeshKernel &_rclMesh; /**< reference to mesh data structure */ + Material* _material; }; /** @@ -138,8 +143,10 @@ public: bool SaveOBJ (std::ostream &rstrOut) const; /** Saves the mesh object into an OFF file. */ bool SaveOFF (std::ostream &rstrOut) const; - /** Saves the mesh object into a PLY file. */ - bool SavePLY (std::ostream &rstrOut) const; + /** Saves the mesh object into a binary PLY file. */ + bool SaveBinaryPLY (std::ostream &rstrOut) const; + /** Saves the mesh object into an ASCII PLY file. */ + bool SaveAsciiPLY (std::ostream &rstrOut) const; /** Saves the mesh object into an XML file. */ void SaveXML (Base::Writer &writer) const; /** Saves a node to an OpenInventor file. */ diff --git a/src/Mod/Mesh/App/Mesh.cpp b/src/Mod/Mesh/App/Mesh.cpp index 47f7a57cf..f7b133a11 100644 --- a/src/Mod/Mesh/App/Mesh.cpp +++ b/src/Mod/Mesh/App/Mesh.cpp @@ -311,10 +311,10 @@ void MeshObject::save(std::ostream& out) const _kernel.Write(out); } -bool MeshObject::load(const char* file) +bool MeshObject::load(const char* file, MeshCore::Material* mat) { MeshCore::MeshKernel kernel; - MeshCore::MeshInput aReader(kernel); + MeshCore::MeshInput aReader(kernel, mat); if (!aReader.LoadAny(file)) return false; @@ -631,6 +631,32 @@ void MeshObject::removeComponents(unsigned long count) deletedFacets(removeIndices); } +unsigned long MeshObject::getPointDegree(const std::vector& indices, + std::vector& point_degree) const +{ + const MeshCore::MeshFacetArray& faces = _kernel.GetFacets(); + std::vector pointDeg(_kernel.CountPoints()); + + for (MeshCore::MeshFacetArray::_TConstIterator it = faces.begin(); it != faces.end(); ++it) { + pointDeg[it->_aulPoints[0]]++; + pointDeg[it->_aulPoints[1]]++; + pointDeg[it->_aulPoints[2]]++; + } + + for (std::vector::const_iterator it = indices.begin(); it != indices.end(); ++it) { + const MeshCore::MeshFacet& face = faces[*it]; + pointDeg[face._aulPoints[0]]--; + pointDeg[face._aulPoints[1]]--; + pointDeg[face._aulPoints[2]]--; + } + + unsigned long countInvalids = std::count_if(pointDeg.begin(), pointDeg.end(), + std::bind2nd(std::equal_to(), 0)); + + point_degree = pointDeg; + return countInvalids; +} + void MeshObject::fillupHoles(unsigned long length, int level, MeshCore::AbstractPolygonTriangulator& cTria) { diff --git a/src/Mod/Mesh/App/Mesh.h b/src/Mod/Mesh/App/Mesh.h index aedc0defc..de42bd381 100644 --- a/src/Mod/Mesh/App/Mesh.h +++ b/src/Mod/Mesh/App/Mesh.h @@ -144,7 +144,7 @@ public: void save(const char* file,MeshCore::MeshIO::Format f=MeshCore::MeshIO::Undefined, const MeshCore::Material* mat = 0) const; void save(std::ostream&) const; - bool load(const char* file); + bool load(const char* file, MeshCore::Material* mat = 0); void load(std::istream&); //@} @@ -177,6 +177,14 @@ public: std::vector > getComponents() const; unsigned long countComponents() const; void removeComponents(unsigned long); + /** + * Checks for the given facet indices what will be the degree for each point + * when these facets are removed from the mesh kernel. + * The point degree information is stored in \a point_degree. The return value + * gices the number of points which will have a degree of zero. + */ + unsigned long getPointDegree(const std::vector& facets, + std::vector& point_degree) const; void fillupHoles(unsigned long, int, MeshCore::AbstractPolygonTriangulator&); void offset(float fSize); void offsetSpecial2(float fSize); diff --git a/src/Mod/Mesh/App/MeshFeaturePyImp.cpp b/src/Mod/Mesh/App/MeshFeaturePyImp.cpp index fb0d60dac..b99e5bee1 100644 --- a/src/Mod/Mesh/App/MeshFeaturePyImp.cpp +++ b/src/Mod/Mesh/App/MeshFeaturePyImp.cpp @@ -77,7 +77,10 @@ PyObject* MeshFeaturePy::smooth(PyObject *args) return NULL; PY_TRY { - getFeaturePtr()->Mesh.smooth(iter, d_max); + Mesh::Feature* obj = getFeaturePtr(); + MeshObject* kernel = obj->Mesh.startEditing(); + kernel->smooth(iter, d_max); + obj->Mesh.finishEditing(); } PY_CATCH; Py_Return; @@ -87,7 +90,10 @@ PyObject* MeshFeaturePy::removeNonManifolds(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; - getFeaturePtr()->Mesh.removeNonManifolds(); + Mesh::Feature* obj = getFeaturePtr(); + MeshObject* kernel = obj->Mesh.startEditing(); + kernel->removeNonManifolds(); + obj->Mesh.finishEditing(); Py_Return } @@ -97,7 +103,10 @@ PyObject* MeshFeaturePy::fixIndices(PyObject *args) return NULL; PY_TRY { - getFeaturePtr()->Mesh.validateIndices(); + Mesh::Feature* obj = getFeaturePtr(); + MeshObject* kernel = obj->Mesh.startEditing(); + kernel->validateIndices(); + obj->Mesh.finishEditing(); } PY_CATCH; Py_Return; @@ -109,7 +118,10 @@ PyObject* MeshFeaturePy::fixDegenerations(PyObject *args) return NULL; PY_TRY { - getFeaturePtr()->Mesh.validateDegenerations(); + Mesh::Feature* obj = getFeaturePtr(); + MeshObject* kernel = obj->Mesh.startEditing(); + kernel->validateDegenerations(); + obj->Mesh.finishEditing(); } PY_CATCH; Py_Return; @@ -121,7 +133,10 @@ PyObject* MeshFeaturePy::removeDuplicatedFacets(PyObject *args) return NULL; PY_TRY { - getFeaturePtr()->Mesh.removeDuplicatedFacets(); + Mesh::Feature* obj = getFeaturePtr(); + MeshObject* kernel = obj->Mesh.startEditing(); + kernel->removeDuplicatedFacets(); + obj->Mesh.finishEditing(); } PY_CATCH; Py_Return; @@ -133,7 +148,10 @@ PyObject* MeshFeaturePy::removeDuplicatedPoints(PyObject *args) return NULL; PY_TRY { - getFeaturePtr()->Mesh.removeDuplicatedPoints(); + Mesh::Feature* obj = getFeaturePtr(); + MeshObject* kernel = obj->Mesh.startEditing(); + kernel->removeDuplicatedPoints(); + obj->Mesh.finishEditing(); } PY_CATCH; Py_Return; @@ -144,7 +162,10 @@ PyObject* MeshFeaturePy::fixSelfIntersections(PyObject *args) if (!PyArg_ParseTuple(args, "")) return NULL; try { - getFeaturePtr()->Mesh.removeSelfIntersections(); + Mesh::Feature* obj = getFeaturePtr(); + MeshObject* kernel = obj->Mesh.startEditing(); + kernel->removeSelfIntersections(); + obj->Mesh.finishEditing(); } catch (const Base::Exception& e) { PyErr_SetString(PyExc_Exception, e.what()); @@ -158,7 +179,10 @@ PyObject* MeshFeaturePy::removeFoldsOnSurface(PyObject *args) if (!PyArg_ParseTuple(args, "")) return NULL; try { - getFeaturePtr()->Mesh.removeFoldsOnSurface(); + Mesh::Feature* obj = getFeaturePtr(); + MeshObject* kernel = obj->Mesh.startEditing(); + kernel->removeFoldsOnSurface(); + obj->Mesh.finishEditing(); } catch (const Base::Exception& e) { PyErr_SetString(PyExc_Exception, e.what()); diff --git a/src/Mod/Mesh/App/MeshProperties.cpp b/src/Mod/Mesh/App/MeshProperties.cpp index 3c0b41190..9e68cae10 100644 --- a/src/Mod/Mesh/App/MeshProperties.cpp +++ b/src/Mod/Mesh/App/MeshProperties.cpp @@ -390,20 +390,6 @@ void PropertyMeshKernel::transformGeometry(const Base::Matrix4D &rclMat) hasSetValue(); } -void PropertyMeshKernel::deletePointIndices( const std::vector& inds ) -{ - aboutToSetValue(); - _meshObject->deletePoints(inds); - hasSetValue(); -} - -void PropertyMeshKernel::deleteFacetIndices( const std::vector& inds ) -{ - aboutToSetValue(); - _meshObject->deleteFacets(inds); - hasSetValue(); -} - void PropertyMeshKernel::setPointIndices(const std::vector >& inds) { aboutToSetValue(); @@ -413,99 +399,6 @@ void PropertyMeshKernel::setPointIndices(const std::vector& rFaces, - const std::vector& rPoints) -{ - aboutToSetValue(); - _meshObject->addFacets(rFaces, rPoints); - hasSetValue(); -} - -void PropertyMeshKernel::createSegment(const std::vector& segm) -{ - aboutToSetValue(); - _meshObject->addSegment(segm); - hasSetValue(); -} - -void PropertyMeshKernel::smooth(int iter, float d_max) -{ - aboutToSetValue(); - _meshObject->smooth(iter, d_max); - hasSetValue(); -} - -void PropertyMeshKernel::clear() -{ - // clear the underlying mesh kernel and free any allocated memory - aboutToSetValue(); - _meshObject->clear(); - hasSetValue(); -} - -void PropertyMeshKernel::harmonizeNormals() -{ - aboutToSetValue(); - _meshObject->harmonizeNormals(); - hasSetValue(); -} - -void PropertyMeshKernel::removeNonManifolds() -{ - aboutToSetValue(); - _meshObject->removeNonManifolds(); - hasSetValue(); -} - -void PropertyMeshKernel::validateIndices() -{ - aboutToSetValue(); - _meshObject->validateIndices(); - hasSetValue(); -} - -void PropertyMeshKernel::validateDegenerations() -{ - aboutToSetValue(); - _meshObject->validateDegenerations(); - hasSetValue(); -} - -void PropertyMeshKernel::validateDeformations(float fMaxAngle) -{ - aboutToSetValue(); - _meshObject->validateDeformations(fMaxAngle); - hasSetValue(); -} - -void PropertyMeshKernel::removeDuplicatedFacets() -{ - aboutToSetValue(); - _meshObject->removeDuplicatedFacets(); - hasSetValue(); -} - -void PropertyMeshKernel::removeDuplicatedPoints() -{ - aboutToSetValue(); - _meshObject->removeDuplicatedPoints(); - hasSetValue(); -} - -void PropertyMeshKernel::removeSelfIntersections() -{ - aboutToSetValue(); - _meshObject->removeSelfIntersections(); - hasSetValue(); -} - -void PropertyMeshKernel::removeFoldsOnSurface() -{ - aboutToSetValue(); - _meshObject->removeFoldsOnSurface(); - hasSetValue(); -} - PyObject *PropertyMeshKernel::getPyObject(void) { if (!meshPyObject) { diff --git a/src/Mod/Mesh/App/MeshProperties.h b/src/Mod/Mesh/App/MeshProperties.h index af1cd0f8b..04bfb8dee 100644 --- a/src/Mod/Mesh/App/MeshProperties.h +++ b/src/Mod/Mesh/App/MeshProperties.h @@ -179,27 +179,7 @@ public: void finishEditing(); /// Transform the real mesh data void transformGeometry(const Base::Matrix4D &rclMat); - void deletePointIndices ( const std::vector& ); - void deleteFacetIndices ( const std::vector& ); void setPointIndices( const std::vector >& ); - void append(const std::vector& rFaces, - const std::vector& rPoints); - void createSegment(const std::vector& segm); - void smooth(int iter, float d_max); - void clear(); - //@} - - /** @name Mesh validation */ - //@{ - void harmonizeNormals(); - void validateIndices(); - void validateDeformations(float fMaxAngle); - void validateDegenerations(); - void removeDuplicatedPoints(); - void removeDuplicatedFacets(); - void removeNonManifolds(); - void removeSelfIntersections(); - void removeFoldsOnSurface(); //@} /** @name Python interface */ diff --git a/src/Mod/Mesh/App/MeshPyImp.cpp b/src/Mod/Mesh/App/MeshPyImp.cpp index ace103289..a25e3e2f6 100644 --- a/src/Mod/Mesh/App/MeshPyImp.cpp +++ b/src/Mod/Mesh/App/MeshPyImp.cpp @@ -165,6 +165,7 @@ PyObject* MeshPy::write(PyObject *args) ext["NAS" ] = MeshCore::MeshIO::NAS; ext["BDF" ] = MeshCore::MeshIO::NAS; ext["PLY" ] = MeshCore::MeshIO::PLY; + ext["APLY"] = MeshCore::MeshIO::APLY; ext["PY" ] = MeshCore::MeshIO::PY; if (ext.find(Ext) != ext.end()) format = ext[Ext]; diff --git a/src/Mod/Mesh/Gui/Makefile.am b/src/Mod/Mesh/Gui/Makefile.am index 82cde54ee..7bc944804 100644 --- a/src/Mod/Mesh/Gui/Makefile.am +++ b/src/Mod/Mesh/Gui/Makefile.am @@ -66,7 +66,7 @@ libMeshGui_la_CPPFLAGS = -DMeshExport= -DMeshGuiExport= libMeshGui_la_LIBADD = \ @BOOST_SIGNALS_LIB@ @BOOST_SYSTEM_LIB@ \ - @GL_LIBS@ \ + @GL_LIBS@ @ZIPIOS_LIB@ \ -lFreeCADBase \ -lFreeCADApp \ -lFreeCADGui \ diff --git a/src/Mod/Mesh/Gui/ViewProvider.cpp b/src/Mod/Mesh/Gui/ViewProvider.cpp index db7e99057..d92766190 100644 --- a/src/Mod/Mesh/Gui/ViewProvider.cpp +++ b/src/Mod/Mesh/Gui/ViewProvider.cpp @@ -27,6 +27,8 @@ # include # include # include +# include +# include # include # include # include @@ -44,6 +46,7 @@ # include # include # include +# include #endif /// Here the FreeCAD includes sorted by Base,App,Gui...... @@ -63,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -82,6 +86,7 @@ #include #include #include +#include #include "ViewProvider.h" #include "SoFCIndexedFaceSet.h" @@ -484,6 +489,69 @@ std::vector ViewProviderMesh::getDisplayModes(void) const return StrList; } +bool ViewProviderMesh::exportToVrml(const char* filename, const MeshCore::Material& mat, bool binary) const +{ + SoCoordinate3* coords = new SoCoordinate3(); + SoIndexedFaceSet* faces = new SoIndexedFaceSet(); + ViewProviderMeshBuilder builder; + builder.createMesh(&static_cast(pcObject)->Mesh, coords, faces); + + SoMaterialBinding* binding = new SoMaterialBinding; + SoMaterial* material = new SoMaterial; + + if (mat.diffuseColor.size() == coords->point.getNum()) { + binding->value = SoMaterialBinding::PER_VERTEX_INDEXED; + } + else if (mat.diffuseColor.size() == faces->coordIndex.getNum()/4) { + binding->value = SoMaterialBinding::PER_FACE_INDEXED; + } + + if (mat.diffuseColor.size() > 1) { + material->diffuseColor.setNum(mat.diffuseColor.size()); + SbColor* colors = material->diffuseColor.startEditing(); + for (unsigned int i=0; idiffuseColor.finishEditing(); + } + + SoGroup* group = new SoGroup(); + group->addChild(material); + group->addChild(binding); + group->addChild(new SoTransform()); + group->addChild(coords); + group->addChild(faces); + + SoToVRML2Action tovrml2; + group->ref(); + tovrml2.apply(group); + group->unref(); + SoVRMLGroup *vrmlRoot = tovrml2.getVRML2SceneGraph(); + vrmlRoot->ref(); + std::string buffer = Gui::SoFCDB::writeNodesToString(vrmlRoot); + vrmlRoot->unref(); // release the memory as soon as possible + + Base::FileInfo fi(filename); + if (binary) { + Base::ofstream str(fi, std::ios::out | std::ios::binary); + zipios::GZIPOutputStream gzip(str); + if (gzip) { + gzip << buffer; + gzip.close(); + return true; + } + } + else { + Base::ofstream str(fi, std::ios::out); + if (str) { + str << buffer; + str.close(); + return true; + } + } + + return false; +} + bool ViewProviderMesh::setEdit(int ModNum) { if (ModNum == ViewProvider::Transform) @@ -1045,13 +1113,7 @@ void ViewProviderMesh::cutMesh(const std::vector& picked, // Get the facet indices inside the tool mesh std::vector indices; getFacetsFromPolygon(picked, Viewer, inner, indices); - - // Get the attached mesh property - Mesh::PropertyMeshKernel& meshProp = static_cast(pcObject)->Mesh; - - //Remove the facets from the mesh and open a transaction object for the undo/redo stuff - meshProp.deleteFacetIndices(indices); - pcObject->purgeTouched(); + removeFacets(indices); } void ViewProviderMesh::trimMesh(const std::vector& polygon, @@ -1137,7 +1199,7 @@ void ViewProviderMesh::splitMesh(const MeshCore::MeshKernel& toolMesh, const Bas // Remove the facets from the mesh and create a new one Mesh::MeshObject* kernel = meshProp.getValue().meshFromSegment(indices); - meshProp.deleteFacetIndices(indices); + removeFacets(indices); Mesh::Feature* splitMesh = static_cast(App::GetApplication().getActiveDocument() ->addObject("Mesh::Feature",pcObject->getNameInDocument())); // Note: deletes also kernel @@ -1167,7 +1229,9 @@ void ViewProviderMesh::segmentMesh(const MeshCore::MeshKernel& toolMesh, const B indices = complementary; } - meshProp.createSegment(indices); + Mesh::MeshObject* kernel = meshProp.startEditing(); + kernel->addSegment(indices); + meshProp.finishEditing(); static_cast(pcObject)->purgeTouched(); } @@ -1401,10 +1465,23 @@ void ViewProviderMesh::fillHole(unsigned long uFacet) //add the facets to the mesh and open a transaction object for the undo/redo stuff Gui::Application::Instance->activeDocument()->openCommand("Fill hole"); - fea->Mesh.append(newFacets, newPoints); + Mesh::MeshObject* kernel = fea->Mesh.startEditing(); + kernel->addFacets(newFacets, newPoints); + fea->Mesh.finishEditing(); Gui::Application::Instance->activeDocument()->commitCommand(); } +void ViewProviderMesh::removeFacets(const std::vector& facets) +{ + // Get the attached mesh property + Mesh::PropertyMeshKernel& meshProp = static_cast(pcObject)->Mesh; + Mesh::MeshObject* kernel = meshProp.startEditing(); + //Remove the facets from the mesh and open a transaction object for the undo/redo stuff + kernel->deleteFacets(facets); + meshProp.finishEditing(); + pcObject->purgeTouched(); +} + void ViewProviderMesh::selectFacet(unsigned long facet) { std::vector selection; diff --git a/src/Mod/Mesh/Gui/ViewProvider.h b/src/Mod/Mesh/Gui/ViewProvider.h index ce0de6b8c..3bf180bdd 100644 --- a/src/Mod/Mesh/Gui/ViewProvider.h +++ b/src/Mod/Mesh/Gui/ViewProvider.h @@ -60,6 +60,7 @@ namespace Gui { namespace MeshCore { class MeshKernel; + struct Material; } @@ -122,6 +123,7 @@ public: virtual void setDisplayMode(const char* ModeName); /// returns a list of all possible modes virtual std::vector getDisplayModes(void) const; + bool exportToVrml(const char* filename, const MeshCore::Material&, bool binary=false) const; /** @name Editing */ //@{ @@ -141,6 +143,7 @@ public: std::vector getFacetsOfRegion(const SbViewportRegion&, const SbViewportRegion&, SoCamera*) const; std::vector getVisibleFacetsAfterZoom(const SbBox2s&, const SbViewportRegion&, SoCamera*) const; std::vector getVisibleFacets(const SbViewportRegion&, SoCamera*) const; + virtual void removeFacets(const std::vector&); //@} protected: