diff --git a/Core/BaseMesh.cpp b/Core/BaseMesh.cpp new file mode 100644 index 0000000000000000000000000000000000000000..163bbc37354af797930529a8635079ca3b9d19bb --- /dev/null +++ b/Core/BaseMesh.cpp @@ -0,0 +1,145 @@ +// This file is part of the SimMedTK project. +// Copyright (c) Center for Modeling, Simulation, and Imaging in Medicine, +// Rensselaer Polytechnic Institute +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//--------------------------------------------------------------------------- +// +// Authors: +// +// Contact: +//--------------------------------------------------------------------------- + +#include "Core/BaseMesh.h" +#include "Core/CollisionConfig.h" + +namespace Core { + +/// +/// \brief Texture management structure +/// +struct BaseMesh::TextureAttachment +{ + TextureAttachment() : + textureId(-1), + textureName(""), + textureFileName("") + { + } + + // Texture id + int textureId; + + // Texture internal name + std::string textureName; + + // Texture filename + std::string textureFileName; + + // True if the texture co-ordinate is available + bool isTextureCoordAvailable; +}; + +BaseMesh::BaseMesh() : collisionGroup(nullptr), log(nullptr) +{ + +} +void BaseMesh::assignTexture( const int textureId ) +{ + if(textureId < 1) + { + return; + } + + auto attachment = std::make_shared<TextureAttachment>(); + attachment->textureId = textureId; + + this->textures.push_back(attachment); +} +void BaseMesh::assignTexture(const std::string &newTextureFileName, + const std::string &referenceName) +{ + auto it = std::find_if(std::begin(textures), std::end(textures), + [referenceName](std::shared_ptr<Core::BaseMesh::TextureAttachment> &t) + { + if(t->textureName != referenceName) + return false; + return true; + }); + // If there is a texture with same name, then ignore this one. + if(it != std::end(textures)) + { + return; + } + else + { + auto attachment = std::make_shared<TextureAttachment>(); + attachment->textureName = referenceName; + attachment->textureFileName = newTextureFileName; + this->textures.push_back(attachment); + } +} +bool BaseMesh::isMeshTextured() const +{ + return this->textures.size() > 0; +} +void BaseMesh::updateOriginalVertsWithCurrent() +{ + this->origVerts = this->vertices; +} +const std::vector<core::Vec3d>& BaseMesh::getVertices() const +{ + return this->vertices; +} +std::vector<core::Vec3d>& BaseMesh::getVertices() +{ + return this->vertices; +} +std::size_t BaseMesh::getNumberOfVertices() const +{ + return this->vertices.size(); +} +std::shared_ptr< CollisionGroup > BaseMesh::getCollisionGroup() const +{ + return this->collisionGroup; +} +Eigen::AlignedBox3d BaseMesh::getBoundingBox() const +{ + return this->aabb; +} +std::size_t BaseMesh::getRenderingId() const +{ + return this->renderingID; +} +std::string BaseMesh::getTextureFileName(const size_t i) const +{ + return textures[i]->textureFileName; +} +const std::vector<core::Vec2f, + Eigen::aligned_allocator<core::Vec2f>> & +BaseMesh::getTextureCoordinates() const +{ + return this->textureCoord; +} +const std::vector< std::shared_ptr< BaseMesh::TextureAttachment > > & +BaseMesh::getTextures() const +{ + return this->textures; +} +const int& BaseMesh::getTextureId(size_t i) const +{ + return this->textures[i]->textureId; +} + +} diff --git a/Core/BaseMesh.h b/Core/BaseMesh.h new file mode 100644 index 0000000000000000000000000000000000000000..481155591656ce74d47bda0771270a91474e90ae --- /dev/null +++ b/Core/BaseMesh.h @@ -0,0 +1,177 @@ +// This file is part of the SimMedTK project. +// Copyright (c) Center for Modeling, Simulation, and Imaging in Medicine, +// Rensselaer Polytechnic Institute +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//--------------------------------------------------------------------------- +// +// Authors: +// +// Contact: +//--------------------------------------------------------------------------- + +#ifndef BASEMESH_H +#define BASEMESH_H + +// Eigen includes +#include <Eigen/Geometry> + +#include "Core/CoreClass.h" +#include "Core/Vector.h" + +class CollisionGroup; +class ErrorLog; + +namespace Core { + +/// +/// +/// \brief Base class for all meshes used in the simulation. +/// +/// \see \SurfaceMesh and \VolumeMesh +/// +class BaseMesh: public CoreClass +{ +public: + struct TextureAttachment; + + /// + /// \brief designates what purpose/scenario the mesh is used for + /// + enum class MeshType + { + Deformable, + DeformableCutable, + RigidCutable, + Rigid + }; + + /// + /// \brief designates input mesh file type + /// + enum class MeshFileType + { + None, + Obj, + ThreeDS, + Volume, + Vtk + }; + + /// + /// \brief constructor + /// + BaseMesh(); + /// + /// \brief Stores the texture locally. It assumes that the texture has been + /// already added to the \TextureManager + /// + void assignTexture(const int p_textureId); + + /// + /// \brief assign the texture + /// + void assignTexture(const std::string& newTextureFileName, const std::string& referenceName); + + /// + /// \brief Copy vertices into origVerts the original texture vertices with the current + /// + void updateOriginalVertsWithCurrent(); + + /// + /// \brief query if the mesh has textures available for rendering + /// + bool isMeshTextured() const; + + /// + /// \brief Returns vertices coordinates + /// + const std::vector<core::Vec3d> &getVertices() const; + std::vector<core::Vec3d> &getVertices(); + + /// + /// \brief Get the total number of vertices + /// + size_t getNumberOfVertices() const; + + /// + /// \brief Return the collision group this mesh belongs to. + /// + std::shared_ptr<CollisionGroup> getCollisionGroup() const; + + /// + /// \brief Returns the bounding box for this mesh. + /// + Eigen::AlignedBox3d getBoundingBox() const; + + /// + /// \brief Returns the bounding box for this mesh. + /// + size_t getRenderingId() const; + + /// + /// \brief Returns the the name of ith texture. + /// + std::string getTextureFileName(const size_t i) const; + + /// + /// \brief Returns the texture coordinates array. + /// + const std::vector<core::Vec2f, + Eigen::aligned_allocator<core::Vec2f>> + &getTextureCoordinates() const; + std::vector<core::Vec2f, + Eigen::aligned_allocator<core::Vec2f>> + &getTextureCoordinates(); + + /// + /// \brief Returns the bounding box for this mesh. + /// + const std::vector<std::shared_ptr<TextureAttachment>> &getTextures() const; + + /// + /// \brief Returns the bounding box for this mesh. + /// + const int &getTextureId(size_t i) const; + +private: + // Data arrays - Vertices only + // vertices co-ordinate data at time t + std::vector<core::Vec3d> vertices; + + // vertices co-ordinate data at time t=0 + std::vector<core::Vec3d> origVerts; + + // Collision group this mesh belongs to. + std::shared_ptr<CollisionGroup> collisionGroup; + + // Logger + std::shared_ptr<ErrorLog> log; + + // Bounding Box + Eigen::AlignedBox3d aabb; + + // Render identification, only used in \StylusRenderDelegate. + size_t renderingID; + + // Textures attached to this mesh. + std::vector<std::shared_ptr<TextureAttachment>> textures; + + // Texture coordinates + std::vector<core::Vec2f, + Eigen::aligned_allocator<core::Vec2f>> textureCoord; +}; + +}// namespace Core +#endif // diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index 4e7ea648ff191c469525baca687f9d01fd4f7086..254d18bcb255b8cbf9c0f8df8ab59acf59358d67 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -26,6 +26,7 @@ simmedtk_add_library(Core Timer.cpp UnifiedId.cpp ViewerBase.cpp + BaseMesh.cpp PUBLIC_HEADERS CollisionConfig.h CollisionDetection.h @@ -56,6 +57,7 @@ simmedtk_add_library(Core Synchronization.h ViewerBase.h WorkerThread.h + BaseMesh.h ) target_link_libraries(Core diff --git a/Mesh/Mesh.cpp b/Mesh/Mesh.cpp index d3b9183f598db8181266d00621dd96933d894116..45577dad23a6bdde1b57146324304e65e35545f3 100644 --- a/Mesh/Mesh.cpp +++ b/Mesh/Mesh.cpp @@ -49,7 +49,6 @@ void BaseMesh::updateOriginalVertsWithCurrent() /// \brief constructor Mesh::Mesh() { - texCoord = 0; triNormals = 0; vertNormals = 0; triTangents = 0; @@ -57,7 +56,6 @@ Mesh::Mesh() nbrTriangles = 0; nbrTexCoordForTrainglesOBJ = 0; type = core::ClassType::Mesh; - isTextureCoordAvailable = false; tangentChannel = false; auto delegate = Factory<VtkRenderDelegate>::createConcreteClass( "MeshRenderDelegate"); @@ -150,34 +148,35 @@ void CalculateTangentArray(int vertexCount, const core::Vec3d *vertex, /// \brief calucate the triangle tangents void Mesh::calcTriangleTangents() { - int t; // First calculate the triangle tangents + auto vertexArray = this->getVertices(); + auto texCoordArray = this->getTextureCoordinates(); for (t = 0; t < nbrTriangles; t++) { Triangle *tmpTri = &triangles[t]; - core::Vec3d *v0 = &vertices[tmpTri->vert[0]]; - core::Vec3d *v1 = &vertices[tmpTri->vert[1]]; - core::Vec3d *v2 = &vertices[tmpTri->vert[2]]; - TexCoord *t0 = &texCoord[tmpTri->vert[0]]; - TexCoord *t1 = &texCoord[tmpTri->vert[1]]; - TexCoord *t2 = &texCoord[tmpTri->vert[2]]; + auto &v0 = vertexArray[triangles[t].vert[0]]; + auto &v1 = vertexArray[triangles[t].vert[1]]; + auto &v2 = vertexArray[triangles[t].vert[2]]; + auto &t0 = texCoordArray[triangles[t].vert[0]]; + auto &t1 = texCoordArray[triangles[t].vert[1]]; + auto &t2 = texCoordArray[triangles[t].vert[2]]; if (this->meshFileType == BaseMesh::MeshFileType::ThreeDS) { - calculateTangent(*v2, *v1, *v0, *t2, *t1, *t0, triTangents[t]); + triTangents[t] = calculateTangent(v2, v1, v0, t2, t1, t0); } else if (this->meshFileType == BaseMesh::MeshFileType::Obj) { - calculateTangent_test(*v0, *v1, *v2, *t0, *t1, *t2, triTangents[t]); + triTangents[t] = calculateTangent_test(v0, v1, v2, t0, t1, t2); } } //calculate the vertex normals if (this->meshFileType == BaseMesh::MeshFileType::ThreeDS || this->meshFileType == BaseMesh::MeshFileType::Obj) { - for (int v = 0; v < nbrVertices; v++) + for (int v = 0, end = vertexArray.size(); v < end; ++v) { vertTangents[v][0] = vertTangents[v][1] = vertTangents[v][2] = 0; @@ -194,9 +193,9 @@ void Mesh::calcTriangleTangents() } /// \brief calucate the triangle tangent for rendering purposes -void Mesh::calculateTangent(core::Vec3d& p1, core::Vec3d& p2, core::Vec3d& p3, TexCoord& t1, TexCoord& t2, TexCoord& t3, core::Vec3d& t) +core::Vec3d Mesh::calculateTangent(core::Vec3d& p1, core::Vec3d& p2, core::Vec3d& p3, TexCoord& t1, TexCoord& t2, TexCoord& t3) { - + core::Vec3d tangent; core::Vec3d v1; core::Vec3d v2; @@ -211,17 +210,18 @@ void Mesh::calculateTangent(core::Vec3d& p1, core::Vec3d& p2, core::Vec3d& p3, T float bb1 = t2.v - t1.v; float bb2 = t3.v - t1.v; - t[0] = bb2 * v1[0] - bb1 * v2[0]; - t[1] = bb2 * v1[1] - bb1 * v2[1]; - t[2] = bb2 * v1[2] - bb1 * v2[2]; + tangent[0] = bb2 * v1[0] - bb1 * v2[0]; + tangent[1] = bb2 * v1[1] - bb1 * v2[1]; + tangent[2] = bb2 * v1[2] - bb1 * v2[2]; - t.normalize(); + return tangent.normalized(); } /// \brief -void Mesh::calculateTangent_test(core::Vec3d& p1, core::Vec3d& p2, core::Vec3d& p3, TexCoord& t1, TexCoord& t2, TexCoord& t3, core::Vec3d& t) +core::Vec3d Mesh::calculateTangent_test(core::Vec3d& p1, core::Vec3d& p2, core::Vec3d& p3, TexCoord& t1, TexCoord& t2, TexCoord& t3) { + core::Vec3d tangent; core::Vec3d v1; core::Vec3d v2; @@ -239,9 +239,9 @@ void Mesh::calculateTangent_test(core::Vec3d& p1, core::Vec3d& p2, core::Vec3d& float bb1 = t2.v - t1.v; float bb2 = t3.v - t1.v; float r = 1.0F / (tt1 * bb2 - tt2 * bb1); - t[0] = (bb2 * v1[0] - bb1 * v2[0]) * r; - t[1] = (bb2 * v1[1] - bb1 * v2[1]) * r; - t[2] = (bb2 * v1[2] - bb1 * v2[2]) * r; + tangent = (bb2*v1 - bb1*v2)*r; + + return tangent; } /// \brief calculates the normal of the vertex diff --git a/Mesh/Mesh.h b/Mesh/Mesh.h index 61fb5ffedd7b364614ddb50852ae5f98491e12d4..ec0ce1d2b7af2aa18563b7ccc7dc78ca3b04d2a4 100644 --- a/Mesh/Mesh.h +++ b/Mesh/Mesh.h @@ -29,6 +29,7 @@ // SimMedTK includes #include "Core/Config.h" +#include "Core/BaseMesh.h" #include "Core/CoreClass.h" #include "Core/ErrorLog.h" #include "Core/Vector.h" @@ -122,7 +123,7 @@ public: /// \brief: this is a generic Mesh class from which surface and volume meshes are inherited /// Note: this class cannot exist on its own -class Mesh: public BaseMesh +class Mesh: public Core::BaseMesh { public: /// \brief constructor diff --git a/Rendering/OpenGLRenderer.cpp b/Rendering/OpenGLRenderer.cpp index c5a7a54d68c68fafde9e8e7ca7c8a42065b381a1..db812daeb06a7cebbdf6a77b375523eea9609c18 100644 --- a/Rendering/OpenGLRenderer.cpp +++ b/Rendering/OpenGLRenderer.cpp @@ -203,21 +203,22 @@ void OpenGLRenderer::drawSurfaceMeshTriangles( } glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_DOUBLE, 0, p_surfaceMesh->vertices.data()); + glVertexPointer(3, GL_DOUBLE, 0, p_surfaceMesh->getVertices().data()); glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_DOUBLE, 0, p_surfaceMesh->vertNormals); + auto &meshTextures = p_surfaceMesh->getTextures(); if (p_surfaceMesh->getRenderDetail()->getRenderType() & SIMMEDTK_RENDER_TEXTURE) { if (p_surfaceMesh->getRenderDelegate()->isTargetTextured()) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, p_surfaceMesh->texCoord); + glTexCoordPointer(2, GL_FLOAT, 0, p_surfaceMesh->getTextureCoordinates().data()->data()); - for (size_t t = 0; t < p_surfaceMesh->textureIds.size(); t++) + for (size_t t = 0, end = meshTextures.size(); t < end; ++t) { glActiveTexture(GL_TEXTURE0 + t); - TextureManager::activateTexture(p_surfaceMesh->textureIds[t].textureId); + TextureManager::activateTexture(p_surfaceMesh->getTextureId(t)); } } } @@ -266,7 +267,7 @@ void OpenGLRenderer::drawSurfaceMeshTriangles( { glDisable(GL_LIGHTING); glColor3fv(renderDetail->getHighLightColor().toGLColor()); - glDrawArrays(GL_POINTS, 0, p_surfaceMesh->nbrVertices); + glDrawArrays(GL_POINTS, 0, p_surfaceMesh->getNumberOfVertices()); glEnable(GL_LIGHTING); } @@ -284,10 +285,10 @@ void OpenGLRenderer::drawSurfaceMeshTriangles( { glDisableClientState(GL_TEXTURE_COORD_ARRAY); - for (size_t t = 0; t < p_surfaceMesh->textureIds.size(); t++) + for (size_t t = 0, end = meshTextures.size(); t < end; ++t) { glActiveTexture(GL_TEXTURE0 + t); - TextureManager::disableTexture(p_surfaceMesh->textureIds[t].textureId); + TextureManager::disableTexture(p_surfaceMesh->getTextureId(t)); } } } @@ -304,7 +305,6 @@ void OpenGLRenderer::drawSurfaceMeshTriangles( void OpenGLRenderer::drawNormals(std::shared_ptr<Mesh> p_mesh, Color p_color, float length) { - glDisable(GL_LIGHTING); glColor3fv(reinterpret_cast<GLfloat*>(&p_color)); core::Vec3d baryCenter; @@ -312,16 +312,17 @@ void OpenGLRenderer::drawNormals(std::shared_ptr<Mesh> p_mesh, Color p_color, fl glBegin(GL_LINES); - for (int i = 0; i < p_mesh->nbrVertices; i++) + auto &vertices = p_mesh->getVertices(); + for (int i = 0, end = vertices.size(); i < end; i++) { - glVertex3dv(p_mesh->vertices[i].data()); - tmp = p_mesh->vertices[i] + p_mesh->vertNormals[i] * length; + glVertex3dv(vertices[i].data()); + tmp = vertices[i] + p_mesh->vertNormals[i] * length; glVertex3dv(tmp.data()); } for (int i = 0; i < p_mesh->nbrTriangles; i++) { - baryCenter = p_mesh->vertices[p_mesh->triangles[i].vert[0]] + p_mesh->vertices[p_mesh->triangles[i].vert[1]] + p_mesh->vertices[p_mesh->triangles[i].vert[2]] ; + baryCenter = vertices[p_mesh->triangles[i].vert[0]] + vertices[p_mesh->triangles[i].vert[1]] + vertices[p_mesh->triangles[i].vert[2]]; baryCenter = baryCenter / 3.0; glVertex3dv(baryCenter.data()); tmp = baryCenter + p_mesh->triNormals[i] * length; @@ -335,13 +336,11 @@ void OpenGLRenderer::drawNormals(std::shared_ptr<Mesh> p_mesh, Color p_color, fl void OpenGLRenderer::beginTriangles() { - glBegin(GL_TRIANGLES); } void OpenGLRenderer::drawTriangle(core::Vec3d &p_1, core::Vec3d &p_2, core::Vec3d &p_3) { - glVertex3dv(p_1.data()); glVertex3dv(p_2.data()); glVertex3dv(p_3.data()); @@ -349,13 +348,11 @@ void OpenGLRenderer::drawTriangle(core::Vec3d &p_1, core::Vec3d &p_2, core::Vec3 void OpenGLRenderer::endTriangles() { - glEnd(); } void OpenGLRenderer::draw(AABB &aabb, Color p_color) { - glPushAttrib(GL_LIGHTING_BIT); glDisable(GL_LIGHTING); diff --git a/Rendering/VAO.cpp b/Rendering/VAO.cpp index 17618d38ede940aea9e1fb0cebffb156cb026d2b..dc346dd70a3da8afef602a4d2401114763be3d4e 100644 --- a/Rendering/VAO.cpp +++ b/Rendering/VAO.cpp @@ -240,27 +240,30 @@ bool VAO::setBufferDataFromMesh( Mesh *p_mesh, std::shared_ptr<Shader> p_shader, shader = p_shader; } + auto totalNumberOfVertices = p_mesh->getNumberOfVertices(); + auto vertices = p_mesh->getVertices(); + bufferInfo[totalNbrBuffers].arrayBufferType = SMVBO_POS; - bufferInfo[totalNbrBuffers].size = sizeof( core::Vec3d ) * p_mesh->nbrVertices; - bufferInfo[totalNbrBuffers].attribPointer = p_mesh->vertices.data(); - bufferInfo[totalNbrBuffers].nbrElements = p_mesh->nbrVertices; + bufferInfo[totalNbrBuffers].size = sizeof( core::Vec3d ) * totalNumberOfVertices; + bufferInfo[totalNbrBuffers].attribPointer = vertices.data(); + bufferInfo[totalNbrBuffers].nbrElements = totalNumberOfVertices; bufferInfo[totalNbrBuffers].attributeIndex = totalNbrBuffers; bufferInfo[totalNbrBuffers].shaderAttribName = p_POSITIONShaderName; totalNbrBuffers++; bufferInfo[totalNbrBuffers].arrayBufferType = SMVBO_NORMALS; - bufferInfo[totalNbrBuffers].size = sizeof( core::Vec3d ) * p_mesh->nbrVertices; + bufferInfo[totalNbrBuffers].size = sizeof( core::Vec3d ) * totalNumberOfVertices; bufferInfo[totalNbrBuffers].attribPointer = p_mesh->vertNormals; - bufferInfo[totalNbrBuffers].nbrElements = p_mesh->nbrVertices; + bufferInfo[totalNbrBuffers].nbrElements = totalNumberOfVertices; bufferInfo[totalNbrBuffers].attributeIndex = totalNbrBuffers; bufferInfo[totalNbrBuffers].shaderAttribName = p_NORMALShaderName; totalNbrBuffers++; ///texture coord is for each vertex bufferInfo[totalNbrBuffers].arrayBufferType = SMVBO_TEXTURECOORDS; - bufferInfo[totalNbrBuffers].size = sizeof( TexCoord ) * p_mesh->nbrVertices; - bufferInfo[totalNbrBuffers].attribPointer = p_mesh->texCoord; - bufferInfo[totalNbrBuffers].nbrElements = p_mesh->nbrVertices; + bufferInfo[totalNbrBuffers].size = sizeof( TexCoord ) * totalNumberOfVertices; + bufferInfo[totalNbrBuffers].attribPointer = p_mesh->getTextureCoordinates().data()->data(); + bufferInfo[totalNbrBuffers].nbrElements = totalNumberOfVertices; bufferInfo[totalNbrBuffers].attributeIndex = totalNbrBuffers; bufferInfo[totalNbrBuffers].shaderAttribName = p_TEXTURECOORDShaderName; totalNbrBuffers++; @@ -268,9 +271,9 @@ bool VAO::setBufferDataFromMesh( Mesh *p_mesh, std::shared_ptr<Shader> p_shader, if ( p_mesh->tangentChannel ) { bufferInfo[totalNbrBuffers].arrayBufferType = SMVBO_TANGENTS; - bufferInfo[totalNbrBuffers].size = sizeof( core::Vec3d ) * p_mesh->nbrVertices; + bufferInfo[totalNbrBuffers].size = sizeof( core::Vec3d ) * totalNumberOfVertices; bufferInfo[totalNbrBuffers].attribPointer = p_mesh->vertTangents; - bufferInfo[totalNbrBuffers].nbrElements = p_mesh->nbrVertices; + bufferInfo[totalNbrBuffers].nbrElements = totalNumberOfVertices; bufferInfo[totalNbrBuffers].attributeIndex = totalNbrBuffers; bufferInfo[totalNbrBuffers].shaderAttribName = p_TANGENTSName; totalNbrBuffers++; diff --git a/VtkRendering/UnitTests/VtkViewerSpec.cpp b/VtkRendering/UnitTests/VtkViewerSpec.cpp index 9c2b431135933dd2fd8b088e948d9eeb8b915f22..530c4d697722106048ea24c81983d9df977fd80f 100644 --- a/VtkRendering/UnitTests/VtkViewerSpec.cpp +++ b/VtkRendering/UnitTests/VtkViewerSpec.cpp @@ -49,6 +49,7 @@ go_bandit([](){ it("renders mesh", []() { auto mesh = makeSurfaceMesh(); +// mesh->getRenderDetail()->renderType |= SIMMEDTK_RENDER_NORMALS; auto viewer = std::make_shared<VtkViewer>(); // auto scene = std::make_shared<Scene>(); diff --git a/VtkRendering/VtkMeshRenderDelegate.cpp b/VtkRendering/VtkMeshRenderDelegate.cpp index 71ce9cc626d393a513edb72da304077b55f6fb4e..2e35c4d7dd58371c80d04039a263cc4dcf82504f 100644 --- a/VtkRendering/VtkMeshRenderDelegate.cpp +++ b/VtkRendering/VtkMeshRenderDelegate.cpp @@ -39,9 +39,13 @@ #include <vtkDataSetMapper.h> #include <vtkPolyDataMapper.h> #include <vtkPoints.h> +#include <vtkPointData.h> #include <vtkCellArray.h> #include <vtkGeometryFilter.h> #include <vtkPolyDataNormals.h> +#include <vtkJPEGReader.h> +#include <vtkFloatArray.h> +#include <vtkTexture.h> class MeshRenderDelegate : public VtkRenderDelegate @@ -91,13 +95,36 @@ void MeshRenderDelegate::initDraw() unstructuredMesh->SetPoints(vertices.GetPointer()); unstructuredMesh->SetCells(VTK_TRIANGLE,triangles.GetPointer()); - if (geom->getRenderDetail()->renderType & SIMMEDTK_RENDER_NORMALS) + vtkSmartPointer<vtkTexture> texture; + if(mesh->isMeshTextured()) + { + vtkNew<vtkJPEGReader> jpegReader; + jpegReader->SetFileName(mesh->getTextureFileName(0).c_str()); + + texture = vtkTexture::New(); + texture->SetInputConnection(jpegReader->GetOutputPort()); + + vtkNew<vtkFloatArray> textureCoordinates; + textureCoordinates->SetNumberOfComponents(3); + textureCoordinates->SetName("TextureCoordinates"); + + auto texCoords = mesh->getTextureCoordinates(0); + for(auto &coord : texCoords) + { + float tuple[3] = {coord[0],coord[1],0.0}; + textureCoordinates->InsertNextTuple(tuple); + } + unstructuredMesh->GetPointData()->SetTCoords(textureCoordinates); + } + + if (mesh->getRenderDetail()->renderType & SIMMEDTK_RENDER_NORMALS) { vtkSmartPointer<vtkGeometryFilter> geometry = vtkGeometryFilter::New(); geometry->SetInputData(unstructuredMesh.GetPointer()); vtkSmartPointer<vtkPolyDataNormals> normals = vtkPolyDataNormals::New(); normals->SetInputConnection(geometry->GetOutputPort()); + normals->ComputeCellNormalsOn(); mapper = vtkPolyDataMapper::New(); mapper->SetInputConnection(normals->GetOutputPort()); @@ -108,6 +135,10 @@ void MeshRenderDelegate::initDraw() mapper->SetInputDataObject(unstructuredMesh.GetPointer()); } + if(texture.GetPointer()) + { + actor->SetTexture(texture); + } actor->SetMapper(mapper); }