Skip to content
Snippets Groups Projects
Commit 8038da14 authored by Alexis Girault's avatar Alexis Girault
Browse files

ENH: Add Mesh & SurfaceMesh classes

parent 34fe4979
No related branches found
No related tags found
No related merge requests found
......@@ -35,6 +35,10 @@ using Vec2d = Eigen::Vector2d;
using Vec3f = Eigen::Vector3f;
using Vec3d = Eigen::Vector3d;
// 4D vector
using Vec4f = Eigen::Vector4f;
using Vec4d = Eigen::Vector4d;
// Dynamic size vector
using VecNf = Eigen::VectorXf;
using VecNd = Eigen::VectorXd;
......
......@@ -8,11 +8,15 @@ imstk_add_library( Geometry
imstkPlane.h
imstkSphere.h
imstkCube.h
imstkMesh.h
imstkSurfaceMesh.h
CPP_FILES
imstkGeometry.cpp
imstkPlane.cpp
imstkSphere.cpp
imstkCube.cpp
imstkMesh.cpp
imstkSurfaceMesh.cpp
LIBRARIES
Core
)
......
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& 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.txt
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.
=========================================================================*/
#include "imstkMesh.h"
namespace imstk {
const std::vector<Vec3d>&
Mesh::getInitialVertexPositions() const
{
return m_initialVertexPositions;
}
void
Mesh::setInitialVertexPositions(const std::vector<Vec3d>& vertices)
{
m_initialVertexPositions = vertices;
}
const std::vector<Vec3d>&
Mesh::getVertexPositions() const
{
return m_vertexPositions;
}
void
Mesh::setVertexPositions(const std::vector<Vec3d>& vertices)
{
m_vertexPositions = vertices;
}
const std::vector<Vec3d>&
Mesh::getVertexDeformations() const
{
return m_vertexDeformations;
}
void
Mesh::setVertexDeformations(const std::vector<Vec3d>& diff)
{
m_vertexDeformations = diff;
}
}
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& 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.txt
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.
=========================================================================*/
#ifndef imstkMesh_h
#define imstkMesh_h
#include "imstkGeometry.h"
namespace imstk {
class Mesh : public Geometry
{
public:
~Mesh() = default;
const std::vector<Vec3d>& getInitialVertexPositions() const;
void setInitialVertexPositions(const std::vector<Vec3d>& vertices);
const std::vector<Vec3d>& getVertexPositions() const;
void setVertexPositions(const std::vector<Vec3d>& vertices);
const std::vector<Vec3d>& getVertexDeformations() const;
void setVertexDeformations(const std::vector<Vec3d>& diff);
protected:
Mesh(GeometryType type) : Geometry(type, ORIGIN, Quatd()) {}
// Orientation * Scaling * initialVertexPositions
// + Position
// + vertexDeformations
// = vertexPositions
std::vector<Vec3d> m_initialVertexPositions;
std::vector<Vec3d> m_vertexPositions;
std::vector<Vec3d> m_vertexDeformations;
};
}
#endif // ifndef imstkMesh_h
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& 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.txt
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.
=========================================================================*/
#include "imstkSurfaceMesh.h"
namespace imstk {
void
SurfaceMesh::computeVertexNeighborTriangles()
{
m_vertexNeighborTriangles.resize(m_vertexPositions.size());
size_t triangleId = 0;
for (const auto& t : m_triangleVertices)
{
m_vertexNeighborTriangles.at(t.at(0)).insert(triangleId);
m_vertexNeighborTriangles.at(t.at(1)).insert(triangleId);
m_vertexNeighborTriangles.at(t.at(2)).insert(triangleId);
triangleId++;
}
}
void
SurfaceMesh::computeVertexNeighborVertices()
{
m_vertexNeighborVertices.resize(m_vertexPositions.size());
if (!m_vertexNeighborTriangles.size())
{
this->computeVertexNeighborTriangles();
}
for (size_t vertexId = 0; vertexId < m_vertexNeighborVertices.size(); ++vertexId)
{
for (const size_t& triangleId : m_vertexNeighborTriangles.at(vertexId))
{
for (const size_t& vertexId2 : m_triangleVertices.at(triangleId))
{
if (vertexId2 != vertexId)
{
m_vertexNeighborVertices.at(vertexId).insert(vertexId2);
}
}
}
}
}
void
SurfaceMesh::computeTriangleNormals()
{
m_triangleNormals.resize(m_triangleVertices.size());
for (size_t triangleId = 0; triangleId < m_triangleNormals.size(); ++triangleId)
{
const auto& t = m_triangleVertices.at(triangleId);
const auto& p0 = m_vertexPositions.at(t.at(0));
const auto& p1 = m_vertexPositions.at(t.at(1));
const auto& p2 = m_vertexPositions.at(t.at(2));
m_triangleNormals.at(triangleId) = ((p1 - p0).cross(p2 - p0)).normalized();
}
}
void
SurfaceMesh::computeVertexNormals()
{
m_vertexNormals.resize(m_vertexPositions.size());
if (!m_vertexNeighborTriangles.size())
{
this->computeVertexNeighborTriangles();
}
if (!m_triangleNormals.size())
{
this->computeTriangleNormals();
}
for (size_t vertexId = 0; vertexId < m_vertexNormals.size(); ++vertexId)
{
for (const size_t& triangleId : m_vertexNeighborTriangles.at(vertexId))
{
m_vertexNormals.at(vertexId) += m_triangleNormals.at(triangleId);
}
m_vertexNormals.at(vertexId).normalize();
}
}
void
SurfaceMesh::computeVertexTangents()
{
/*
Derived from
Lengyel, Eric. "Computing Tangent Space Basis Vectors for an Arbitrary
Mesh".
Terathon Software 3D Graphics Library, 2001.
[url]http://www.terathon.com/code/tangent.html[/url]
*/
std::vector<Vec3d> tan1, tan2;
tan1.resize(m_vertexPositions.size());
tan2.resize(m_vertexPositions.size());
for (const auto& triangle : m_triangleVertices)
{
const size_t& id0 = triangle.at(0);
const size_t& id1 = triangle.at(1);
const size_t& id2 = triangle.at(2);
const Vec3d& p0 = m_vertexPositions.at(id0);
const Vec3d& p1 = m_vertexPositions.at(id1);
const Vec3d& p2 = m_vertexPositions.at(id2);
const Vec2f& uv0 = m_textureCoordinates.at(id0);
const Vec2f& uv1 = m_textureCoordinates.at(id1);
const Vec2f& uv2 = m_textureCoordinates.at(id2);
Vec3d P1 = p1 - p0;
Vec3d P2 = p2 - p0;
double u1 = uv1[0] - uv0[0];
double u2 = uv2[0] - uv0[0];
double v1 = uv1[1] - uv0[1];
double v2 = uv2[1] - uv0[1];
double div = u1 * v2 - u2 * v1;
double r = (div = 0.0f) ? 0.0f : (1.0f / div);
Vec3d u_dir = (v2 * P1 - v1 * P2) * r;
Vec3d v_dir = (u2 * P1 - u1 * P2) * r;
tan1.at(id0) += u_dir;
tan1.at(id1) += u_dir;
tan1.at(id2) += u_dir;
tan2.at(id0) += v_dir;
tan2.at(id1) += v_dir;
tan2.at(id2) += v_dir;
}
m_vertexTangents.resize(m_vertexPositions.size());
for (size_t vertexId = 0; vertexId < m_vertexTangents.size(); ++vertexId)
{
const Vec3d& n = m_vertexNormals.at(vertexId);
const Vec3d& t1 = tan1.at(0);
const Vec3d& t2 = tan2.at(0);
// Gram-Schmidt orthogonalize
Vec3d tangente = (t1 - n * n.dot(t1));
tangente.normalize();
m_vertexTangents.at(vertexId)[0] = tangente[0];
m_vertexTangents.at(vertexId)[1] = tangente[1];
m_vertexTangents.at(vertexId)[2] = tangente[2];
// Calculate handedness
m_vertexTangents.at(vertexId)[3] = ((n.cross(t1)).dot(t2) < 0.0f) ? -1.0f : 1.0f;
}
}
const std::vector<SurfaceMesh::TriangleArray>&
SurfaceMesh::getTriangleVertices() const
{
return m_triangleVertices;
}
void
SurfaceMesh::setTriangleVertices(const std::vector<TriangleArray>& triangles)
{
m_triangleVertices = triangles;
}
const std::vector<Vec2f>&
SurfaceMesh::getTextureCoordinates() const
{
return m_textureCoordinates;
}
void
SurfaceMesh::setTextureCoordinates(const std::vector<Vec2f>& coords)
{
m_textureCoordinates = coords;
}
const std::vector<Vec3d>&
SurfaceMesh::getTriangleNormals() const
{
return m_triangleNormals;
}
const Vec3d&
SurfaceMesh::getTriangleNormal(size_t i) const
{
return m_triangleNormals.at(i);
}
const std::vector<Vec3d>&
SurfaceMesh::getVertexNormals() const
{
return m_vertexNormals;
}
const Vec3d&
SurfaceMesh::getVertexNormal(size_t i) const
{
return m_vertexNormals.at(i);
}
const std::vector<Vec4d>&
SurfaceMesh::getVertexTangents() const
{
return m_vertexTangents;
}
const Vec4d&
SurfaceMesh::getVertexTangent(size_t i) const
{
return m_vertexTangents.at(i);
}
}
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& 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.txt
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.
=========================================================================*/
#ifndef imstkSurfaceMesh_h
#define imstkSurfaceMesh_h
#include <set>
#include "imstkMesh.h"
namespace imstk {
class SurfaceMesh : public Mesh
{
using TriangleArray = std::array<size_t, 3>;
using NeighborsType = std::set<size_t>;
public:
SurfaceMesh() : Mesh(GeometryType::SurfaceMesh) {}
~SurfaceMesh() = default;
void computeVertexNeighborTriangles();
void computeVertexNeighborVertices();
void computeTriangleNormals();
void computeVertexNormals();
void computeVertexTangents();
void setTriangleVertices(
const std::vector<TriangleArray>& triangles);
void setTextureCoordinates(const std::vector<Vec2f>& coords);
const std::vector<TriangleArray>& getTriangleVertices() const;
const std::vector<Vec2f> & getTextureCoordinates() const;
const std::vector<Vec3d> & getTriangleNormals() const;
const Vec3d & getTriangleNormal(size_t i) const;
const std::vector<Vec3d>& getVertexNormals() const;
const Vec3d & getVertexNormal(size_t i) const;
const std::vector<Vec4d>& getVertexTangents() const;
const Vec4d & getVertexTangent(size_t i) const;
protected:
std::vector<TriangleArray> m_triangleVertices;
std::vector<Vec2f> m_textureCoordinates;
std::vector<NeighborsType> m_vertexNeighborTriangles;
std::vector<NeighborsType> m_vertexNeighborVertices;
std::vector<Vec3d> m_triangleNormals;
std::vector<Vec3d> m_vertexNormals;
std::vector<Vec4d> m_vertexTangents;
};
}
#endif // ifndef imstkSurfaceMesh_h
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment