diff --git a/Source/CollisionHandling/imstkPbdCollisionHandling.cpp b/Source/CollisionHandling/imstkPbdCollisionHandling.cpp
index e101e9b1435b0f4ed24a29bef0fd99eb7f16ee07..92e1b4fd8799e7d55d293791214705f7f22d5e27 100644
--- a/Source/CollisionHandling/imstkPbdCollisionHandling.cpp
+++ b/Source/CollisionHandling/imstkPbdCollisionHandling.cpp
@@ -70,7 +70,7 @@ getVertex(const CollisionElement& elem, const MeshSide& side)
         auto oneToOneMap = dynamic_cast<OneToOneMap*>(side.m_mapPtr);
         if (side.m_mapPtr && oneToOneMap != nullptr)
         {
-            ptId = oneToOneMap->getMapIdx(ptId);
+            ptId = oneToOneMap->getParentVertexId(ptId);
         }
         results[0] = { &side.m_vertices[ptId], side.m_invMasses[ptId], &side.m_velocities[ptId] };
     }
@@ -102,8 +102,8 @@ getEdge(const CollisionElement& elem, const MeshSide& side)
         auto oneToOneMap = dynamic_cast<OneToOneMap*>(side.m_mapPtr);
         if (side.m_mapPtr && oneToOneMap != nullptr)
         {
-            v1 = oneToOneMap->getMapIdx(v1);
-            v2 = oneToOneMap->getMapIdx(v2);
+            v1 = oneToOneMap->getParentVertexId(v1);
+            v2 = oneToOneMap->getParentVertexId(v2);
         }
         results[0] = { &side.m_vertices[v1], side.m_invMasses[v1], &side.m_velocities[v1] };
         results[1] = { &side.m_vertices[v2], side.m_invMasses[v2], &side.m_velocities[v2] };
@@ -138,9 +138,9 @@ getTriangle(const CollisionElement& elem, const MeshSide& side)
         auto oneToOneMap = dynamic_cast<OneToOneMap*>(side.m_mapPtr);
         if (side.m_mapPtr && oneToOneMap != nullptr)
         {
-            v1 = oneToOneMap->getMapIdx(v1);
-            v2 = oneToOneMap->getMapIdx(v2);
-            v3 = oneToOneMap->getMapIdx(v3);
+            v1 = oneToOneMap->getParentVertexId(v1);
+            v2 = oneToOneMap->getParentVertexId(v2);
+            v3 = oneToOneMap->getParentVertexId(v3);
         }
         results[0] = { &side.m_vertices[v1], side.m_invMasses[v1], &side.m_velocities[v1] };
         results[1] = { &side.m_vertices[v2], side.m_invMasses[v2], &side.m_velocities[v2] };
diff --git a/Source/GeometryMappers/CMakeLists.txt b/Source/GeometryMappers/CMakeLists.txt
index 9600114194912dc99a03f8621fcd4e0dd9d24b3f..44d0ea3eeeff662f3ca404938e65f885be8da3b2 100644
--- a/Source/GeometryMappers/CMakeLists.txt
+++ b/Source/GeometryMappers/CMakeLists.txt
@@ -4,7 +4,7 @@
 include(imstkAddLibrary)
 imstk_add_library( GeometryMappers
   DEPENDS
-	Geometry
+	FilteringCore
   )
 
 #-----------------------------------------------------------------------------
diff --git a/Source/GeometryMappers/Testing/imstkOneToOneMapTest.cpp b/Source/GeometryMappers/Testing/imstkOneToOneMapTest.cpp
index 18863fa983d8764f6c4b5323468ca3efa47d7385..efd06ce6fba2690400e607cea9ffa1a892da6030 100644
--- a/Source/GeometryMappers/Testing/imstkOneToOneMapTest.cpp
+++ b/Source/GeometryMappers/Testing/imstkOneToOneMapTest.cpp
@@ -19,14 +19,14 @@
 
 =========================================================================*/
 
-#include "imstkSurfaceMesh.h"
-#include "imstkPointSet.h"
 #include "imstkGeometry.h"
 #include "imstkOneToOneMap.h"
+#include "imstkPointSet.h"
+#include "imstkSphere.h"
+#include "imstkSurfaceMesh.h"
 #include "imstkVecDataArray.h"
 
 #include <gtest/gtest.h>
-#include "imstkSphere.h"
 
 using namespace imstk;
 
@@ -71,16 +71,15 @@ TEST(imstkOneToOneMapTest, SimpleMap)
     OneToOneMap map;
     map.setParentGeometry(parent);
     map.setChildGeometry(child);
-
     map.compute();
 
     for (int i = 0; i < child->getNumVertices(); ++i)
     {
-        EXPECT_EQ(map.getMapIdx(i), i);
+        EXPECT_EQ(map.getParentVertexId(i), i);
     }
 
     parent->translate({ 1.0, 2.0, 3.0 }, Geometry::TransformType::ApplyToData);
-    map.apply();
+    map.update();
     for (int i = 0; i < child->getNumVertices(); ++i)
     {
         EXPECT_TRUE(parent->getVertexPosition(i).isApprox(child->getVertexPosition(i)));
@@ -133,23 +132,22 @@ TEST(imstkOneToOneMapTest, OneToManyMap)
     map.setParentGeometry(parent);
     map.setChildGeometry(child);
     map.setTolerance(1e-8);
-
     map.compute();
 
     for (int i = 0; i < parent->getNumVertices(); ++i)
     {
-        EXPECT_EQ(map.getMapIdx(i), i);
+        EXPECT_EQ(map.getParentVertexId(i), i);
     }
 
-    EXPECT_EQ(map.getMapIdx(8), 2);
+    EXPECT_EQ(map.getParentVertexId(8), 2);
 
-    EXPECT_EQ(map.getMapIdx(9), IMSTK_NO_INDEX);
+    EXPECT_EQ(map.getParentVertexId(9), -1);
 
     parent->translate({ 1.0, 2.0, 3.0 }, Geometry::TransformType::ApplyToData);
-    map.apply();
+    map.update();
     for (int i = 0; i < child->getNumVertices() - 1; ++i)
     {
-        auto j = map.getMapIdx(i);
+        auto j = map.getParentVertexId(i);
         EXPECT_TRUE(child->getVertexPosition(i).isApprox(parent->getVertexPosition(j))) << "For " << i << ", " << j;
     }
 }
diff --git a/Source/GeometryMappers/imstkGeometryMap.cpp b/Source/GeometryMappers/imstkGeometryMap.cpp
index a1d362bbd3205753167f0ea973d8d504db37ca42..a8b46528ccb722c3bfdf0deef43ca7203c6f01fe 100644
--- a/Source/GeometryMappers/imstkGeometryMap.cpp
+++ b/Source/GeometryMappers/imstkGeometryMap.cpp
@@ -20,63 +20,20 @@
 =========================================================================*/
 
 #include "imstkGeometryMap.h"
-#include "imstkLogger.h"
+#include "imstkGeometry.h"
 
 namespace imstk
 {
-void
-GeometryMap::mute()
+GeometryMap::GeometryMap()
 {
-    m_isActive = false;
-}
-
-void
-GeometryMap::activate()
-{
-    m_isActive = true;
-}
-
-void
-GeometryMap::print() const
-{
-    LOG(INFO) << this->getTypeName();
-}
-
-bool
-GeometryMap::isActive() const
-{
-    return m_isActive;
-}
+    // Set 2 ports for each, inputs will be set to outputs
+    setNumInputPorts(2);
 
-void
-GeometryMap::setParentGeometry(std::shared_ptr<Geometry> parent)
-{
-    m_parentGeom = parent;
-}
-
-std::shared_ptr<Geometry>
-GeometryMap::getParentGeometry() const
-{
-    return m_parentGeom;
-}
-
-void
-GeometryMap::setChildGeometry(std::shared_ptr<Geometry> child)
-{
-    m_childGeom = child;
-}
-
-std::shared_ptr<Geometry>
-GeometryMap::getChildGeometry() const
-{
-    return m_childGeom;
-}
-
-void
-GeometryMap::initialize()
-{
-    CHECK(this->isValid()) << "Map is invalid!";
+    // Both inputs required
+    setRequiredInputType<Geometry>(0);
+    setRequiredInputType<Geometry>(1);
 
-    this->compute();
+    // Set 1 output port, the child
+    setNumOutputPorts(1);
 }
-} // namespace imstk
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/Source/GeometryMappers/imstkGeometryMap.h b/Source/GeometryMappers/imstkGeometryMap.h
index 64bb4b19e94e8d45680e1d117952bc3926dfec3e..7896c84c24ea5b19247f233fa9f78fbc14f8b275 100644
--- a/Source/GeometryMappers/imstkGeometryMap.h
+++ b/Source/GeometryMappers/imstkGeometryMap.h
@@ -21,19 +21,21 @@
 
 #pragma once
 
-#include "imstkGeometry.h"
+#include "imstkGeometryAlgorithm.h"
 
 namespace imstk
 {
+class Geometry;
+
 ///
 /// \class GeometryMap
 ///
 /// \brief Base class for any geometric map
 ///
-class GeometryMap
+class GeometryMap : public GeometryAlgorithm
 {
 protected:
-    GeometryMap() : m_isActive(true) { }
+    GeometryMap();
 
 public:
     virtual ~GeometryMap() = default;
@@ -45,65 +47,22 @@ public:
     virtual const std::string getTypeName() const = 0;
 
     ///
-    /// \brief Compute the map
-    ///
+    /// \brief Compute the map, usually called once on startup
+    /// 
     virtual void compute() = 0;
 
-    ///
-    /// \brief Apply the map
-    ///
-    virtual void apply() = 0;
-
-    ///
-    /// \brief Print the map
-    ///
-    virtual void print() const;
-
-    ///
-    /// \brief Deactivate the map
-    ///
-    void mute();
-
-    ///
-    /// \brief Check the validity of the map
-    ///
-    virtual bool isValid() const = 0;
-
-    ///
-    /// \brief Activate the map
-    ///
-    void activate();
-
-    ///
-    /// \brief Returns true if the map is actively applied at runtime, else false.
-    ///
-    bool isActive() const;
-
-    // Accessors
-
     ///
     /// \brief Get/Set parent geometry
     ///@{
-    virtual void setParentGeometry(std::shared_ptr<Geometry> parent);
-    virtual std::shared_ptr<Geometry> getParentGeometry() const;
+    void setParentGeometry(std::shared_ptr<Geometry> parent) { setInput(parent, 0); }
+    std::shared_ptr<Geometry> getParentGeometry() const { return getInput(0); }
     ///@}
 
     ///
     /// \brief Get/Set child geometry
     ///@{
-    virtual void setChildGeometry(std::shared_ptr<Geometry> child);
-    virtual std::shared_ptr<Geometry> getChildGeometry() const;
+    void setChildGeometry(std::shared_ptr<Geometry> child) { setInput(child, 1); }
+    std::shared_ptr<Geometry> getChildGeometry() const { return getInput(1); }
     ///@}
-
-    ///
-    /// \brief Initialize the map
-    ///
-    virtual void initialize();
-
-protected:
-    bool m_isActive;                        ///> true if the map us active at runtime
-
-    std::shared_ptr<Geometry> m_parentGeom; ///> the geometry which dictates the configuration
-    std::shared_ptr<Geometry> m_childGeom;  ///> the geometry which follows the parent
 };
 } // namespace imstk
diff --git a/Source/GeometryMappers/imstkIdentityMap.cpp b/Source/GeometryMappers/imstkIdentityMap.cpp
deleted file mode 100644
index 335cb82b703b4da4c4bbbadf17910f5fdfb196d8..0000000000000000000000000000000000000000
--- a/Source/GeometryMappers/imstkIdentityMap.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*=========================================================================
-
-   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 "imstkIdentityMap.h"
-#include "imstkLogger.h"
-
-namespace imstk
-{
-void
-IdentityMap::apply()
-{
-    // Check Map active
-    if (!m_isActive)
-    {
-        LOG(WARNING) << "Identity map is not active";
-        return;
-    }
-
-    // Check geometries
-    CHECK(m_parentGeom != nullptr && m_childGeom != nullptr) << "Identity map is being applied without valid geometries";
-
-    // Set the child mesh configuration to be same as that of parent
-    m_childGeom->setTranslation(m_parentGeom->getTranslation());
-    m_childGeom->setRotation(m_parentGeom->getRotation());
-}
-
-const RigidTransform3d
-IdentityMap::getTransform() const
-{
-    return RigidTransform3d::Identity();
-}
-} // namespace imstk
\ No newline at end of file
diff --git a/Source/GeometryMappers/imstkIdentityMap.h b/Source/GeometryMappers/imstkIdentityMap.h
deleted file mode 100644
index d02783c4b837255de79f736a0f6aaacd5ca28dda..0000000000000000000000000000000000000000
--- a/Source/GeometryMappers/imstkIdentityMap.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*=========================================================================
-
-   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.
-
-=========================================================================*/
-
-#pragma once
-
-#include "imstkGeometryMap.h"
-#include "imstkMacros.h"
-
-namespace imstk
-{
-///
-/// \class IdentityMap
-///
-/// \brief A maps that lets the child follow the parent's position and orientation
-///
-class IdentityMap : public GeometryMap
-{
-public:
-    IdentityMap() { }
-    ~IdentityMap() override = default;
-
-    IMSTK_TYPE_NAME(IdentityMap)
-
-    ///
-    /// \brief Compute the map
-    ///
-    void compute() override {}
-
-    ///
-    /// \brief Apply the map
-    ///
-    void apply() override;
-
-    ///
-    /// \brief Check the validity of the map
-    ///
-    bool isValid() const override { return true; }
-
-    // Accessors
-
-    ///
-    /// \brief DISABLED: Set the transform of the Identity map
-    ///
-    void setTransform(const RigidTransform3d& affineTransform) = delete;
-
-    ///
-    /// \brief Get the transform of Identity map which is an Identity (3x3)
-    ///
-    const RigidTransform3d getTransform() const;
-};
-} // namespace imstk
\ No newline at end of file
diff --git a/Source/GeometryMappers/imstkIsometricMap.cpp b/Source/GeometryMappers/imstkIsometricMap.cpp
index cb1f9752146ebca72c900f8e816d416f65520fce..7dcf58bdafc3f52606fd834f26430e88014c91c1 100644
--- a/Source/GeometryMappers/imstkIsometricMap.cpp
+++ b/Source/GeometryMappers/imstkIsometricMap.cpp
@@ -20,27 +20,14 @@
 =========================================================================*/
 
 #include "imstkIsometricMap.h"
+#include "imstkGeometry.h"
 #include "imstkLogger.h"
 
 namespace imstk
 {
 void
-IsometricMap::apply()
+IsometricMap::requestUpdate()
 {
-    // Check Map active
-    if (!m_isActive)
-    {
-        LOG(WARNING) << "Isometric map is not active";
-        return;
-    }
-
-    // Check geometries
-    if (!m_parentGeom || !m_childGeom)
-    {
-        LOG(WARNING) << "Isometric map is being applied without valid geometries";
-        return;
-    }
-
-    m_childGeom->setTransform(m_parentGeom->getTransform());
+    getChildGeometry()->setTransform(getParentGeometry()->getTransform());
 }
 } // namespace imstk
\ No newline at end of file
diff --git a/Source/GeometryMappers/imstkIsometricMap.h b/Source/GeometryMappers/imstkIsometricMap.h
index 6bc226cbd4f2937e13d831735d7b6b881f50e251..46109554d3733724aff76723d5cc196287dc7a49 100644
--- a/Source/GeometryMappers/imstkIsometricMap.h
+++ b/Source/GeometryMappers/imstkIsometricMap.h
@@ -34,14 +34,13 @@ namespace imstk
 class IsometricMap : public GeometryMap
 {
 public:
-    IsometricMap() { }
-
-    IsometricMap(std::shared_ptr<Geometry> parent, std::shared_ptr<Geometry> child)
+    IsometricMap() = default;
+    IsometricMap(std::shared_ptr<Geometry> parent,
+        std::shared_ptr<Geometry> child)
     {
         this->setParentGeometry(parent);
         this->setChildGeometry(child);
     }
-
     ~IsometricMap() override = default;
 
     IMSTK_TYPE_NAME(IsometricMap)
@@ -49,19 +48,12 @@ public:
     ///
     /// \brief Compute the map
     ///
-    void compute() override {}
+    void compute() override { }
 
+protected:
     ///
     /// \brief Apply the map
     ///
-    void apply() override;
-
-    ///
-    /// \brief Check the validity of the map
-    ///
-    inline bool isValid() const override
-    {
-        return true;
-    }
+    void requestUpdate() override;
 };
 } // namespace imstk
\ No newline at end of file
diff --git a/Source/GeometryMappers/imstkOneToOneMap.cpp b/Source/GeometryMappers/imstkOneToOneMap.cpp
index da94d4a04aeda346ad765d805bd42cea26e0d3ae..8b7c35ab31c968c18007a875de418df9faf620c0 100644
--- a/Source/GeometryMappers/imstkOneToOneMap.cpp
+++ b/Source/GeometryMappers/imstkOneToOneMap.cpp
@@ -70,9 +70,9 @@ OneToOneMap::computeMap(std::unordered_map<int, int>& tetVertToSurfVertMap)
     auto meshParent = std::dynamic_pointer_cast<PointSet>(getParentGeometry());
     auto meshChild = std::dynamic_pointer_cast<PointSet>(getChildGeometry());
 
-    std::shared_ptr<VecDataArray<double, 3>> parentVerticesPtr = meshParent->getInitialVertexPositions();
+    std::shared_ptr<VecDataArray<double, 3>> parentVerticesPtr = meshParent->getVertexPositions();
     const VecDataArray<double, 3>& parentVertices = *parentVerticesPtr;
-    std::shared_ptr<VecDataArray<double, 3>> childVerticesPtr = meshChild->getInitialVertexPositions();
+    std::shared_ptr<VecDataArray<double, 3>> childVerticesPtr = meshChild->getVertexPositions();
     const VecDataArray<double, 3>& childVertices = *childVerticesPtr;
 
     // For every vertex on the child, find corresponding one on the parent
@@ -146,16 +146,9 @@ OneToOneMap::requestUpdate()
 }
 
 int
-OneToOneMap::getMapIdx(const int idx) const
+OneToOneMap::getParentVertexId(const int childVertexId) const
 {
-    auto citer = m_oneToOneMap.find(idx);
-    if (citer != m_oneToOneMap.end())
-    {
-        return citer->second;
-    }
-    else
-    {
-        return -1;
-    }
+    auto citer = m_oneToOneMap.find(childVertexId);
+    return (citer != m_oneToOneMap.end()) ? citer->second : -1;
 }
 } // namespace imstk
\ No newline at end of file
diff --git a/Source/GeometryMappers/imstkOneToOneMap.h b/Source/GeometryMappers/imstkOneToOneMap.h
index 0fdc4a5b1b79ae22a7e19f446d6249d87f212344..abf12f8c8cef891dedfa5b59bd0705732277b9f2 100644
--- a/Source/GeometryMappers/imstkOneToOneMap.h
+++ b/Source/GeometryMappers/imstkOneToOneMap.h
@@ -17,12 +17,12 @@
 
 #include "imstkGeometryMap.h"
 #include "imstkMacros.h"
+#include "imstkMath.h"
 #include "imstkTypes.h"
 
 namespace imstk
 {
 template<typename T, int N> class VecDataArray;
-class PointSet;
 
 ///
 /// \class OneToOneMap
@@ -33,15 +33,10 @@ class PointSet;
 class OneToOneMap : public GeometryMap
 {
 public:
-    OneToOneMap() : GeometryMap() {}
+    OneToOneMap();
     OneToOneMap(
         std::shared_ptr<Geometry> parent,
-        std::shared_ptr<Geometry> child)
-    {
-        this->setParentGeometry(parent);
-        this->setChildGeometry(child);
-    }
-
+        std::shared_ptr<Geometry> child);
     ~OneToOneMap() override = default;
 
     IMSTK_TYPE_NAME(OneToOneMap)
@@ -52,41 +47,21 @@ public:
     void compute() override;
 
     ///
-    /// \brief Check the validity of the map
-    ///
-    bool isValid() const override;
+    /// \brief Compute tet vertex id to surf vertex id map
+    /// 
+    void computeMap(std::unordered_map<int, int>& tetVertToSurfVertMap);
 
     ///
     /// \brief Sets the one-to-one correspondence directly
     ///
     void setMap(const std::unordered_map<int, int>& sourceMap);
 
-    ///
-    /// \brief Apply (if active) the tetra-triangle mesh map
-    ///
-    void apply() override;
-
-    ///
-    /// \brief Print the map
-    ///
-    void print() const override;
-
-    ///
-    /// \brief Set the geometry that dictates the map
-    ///
-    void setParentGeometry(std::shared_ptr<Geometry> parent) override;
-
-    ///
-    /// \brief Set the geometry that follows the parent
-    ///
-    void setChildGeometry(std::shared_ptr<Geometry> child) override;
-
     ///
     /// \brief Get the mapped/corresponding parent index, given a child index.
     /// returns -1 if no correspondence found.
     /// \param index on the child geometry
     ///
-    int getMapIdx(const int idx) const;
+    int getParentVertexId(const int childVertexId) const;
 
     ///
     /// \brief Set/Get the tolerance. The distance to consider
@@ -94,7 +69,7 @@ public:
     ///@{
     void setTolerance(const double tolerance) { m_epsilon = tolerance; }
     double getTolerance() const { return m_epsilon; }
-///@}
+    ///@}
 
 protected:
     ///
@@ -102,6 +77,12 @@ protected:
     ///
     int findMatchingVertex(const VecDataArray<double, 3>& parentMesh, const Vec3d& p);
 
+    ///
+    /// \brief Apply (if active) the tetra-triangle mesh map
+    ///
+    void requestUpdate() override;
+
+public:
     // A map and vector are maintained. The vector for parallel processing, the map for fast lookup
     std::unordered_map<int, int>     m_oneToOneMap;       ///> One to one mapping data
     std::vector<std::pair<int, int>> m_oneToOneMapVector; ///> One to one mapping data
diff --git a/Source/GeometryMappers/imstkTetraTriangleMap.cpp b/Source/GeometryMappers/imstkTetraTriangleMap.cpp
index 01f5682e163b2b1f35b59e509fab34d37a2dbc57..79c67ebb136897d9aaf694273dbb8915068584fc 100644
--- a/Source/GeometryMappers/imstkTetraTriangleMap.cpp
+++ b/Source/GeometryMappers/imstkTetraTriangleMap.cpp
@@ -22,21 +22,38 @@
 #include "imstkTetraTriangleMap.h"
 #include "imstkLogger.h"
 #include "imstkParallelUtils.h"
-#include "imstkSurfaceMesh.h"
 #include "imstkTetrahedralMesh.h"
 #include "imstkVecDataArray.h"
 
 namespace imstk
 {
-void
-TetraTriangleMap::compute()
+TetraTriangleMap::TetraTriangleMap() : m_boundingBoxAvailable(false)
+{
+    setRequiredInputType<TetrahedralMesh>(0);
+    setRequiredInputType<PointSet>(1);
+}
+TetraTriangleMap::TetraTriangleMap(
+    std::shared_ptr<Geometry> parent,
+    std::shared_ptr<Geometry> child)
+    : m_boundingBoxAvailable(false)
 {
-    CHECK(m_parentGeom && m_childGeom) << "TetraTriangle map is being applied without valid geometries";
+    setRequiredInputType<TetrahedralMesh>(0);
+    setRequiredInputType<PointSet>(1);
 
-    auto tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(m_parentGeom);
-    auto triMesh = std::dynamic_pointer_cast<SurfaceMesh>(m_childGeom);
+    setParentGeometry(parent);
+    setChildGeometry(child);
+}
 
-    CHECK(tetMesh && triMesh) << "Fail to cast from geometry to meshes";
+void
+TetraTriangleMap::compute()
+{
+    if (!areInputsValid())
+    {
+        LOG(WARNING) << "TetraTriangleMap failed to run, inputs not satisfied";
+        return;
+    }
+    auto tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(getParentGeometry());
+    auto triMesh = std::dynamic_pointer_cast<PointSet>(getChildGeometry());
 
     m_verticesEnclosingTetraId.clear();
     m_verticesWeights.clear();
@@ -51,7 +68,9 @@ TetraTriangleMap::compute()
         updateBoundingBox();
     }
 
-    ParallelUtils::parallelFor(triMesh->getNumVertices(), [&](const size_t vertexIdx) {
+    ParallelUtils::parallelFor(triMesh->getNumVertices(),
+        [&](const int vertexIdx)
+        {
             if (!bValid) // If map is invalid, no need to check further
             {
                 return;
@@ -59,12 +78,12 @@ TetraTriangleMap::compute()
             const Vec3d& surfVertPos = triMesh->getVertexPosition(vertexIdx);
 
             // Find the enclosing or closest tetrahedron
-            size_t closestTetId = findEnclosingTetrahedron(surfVertPos);
-            if (closestTetId == std::numeric_limits<size_t>::max())
+            int closestTetId = findEnclosingTetrahedron(surfVertPos);
+            if (closestTetId == IMSTK_INT_MAX)
             {
                 closestTetId = findClosestTetrahedron(surfVertPos);
             }
-            if (closestTetId == std::numeric_limits<size_t>::max())
+            if (closestTetId == IMSTK_INT_MAX)
             {
                 LOG(WARNING) << "Could not find closest tetrahedron";
                 bValid = false;
@@ -87,27 +106,18 @@ TetraTriangleMap::compute()
 }
 
 void
-TetraTriangleMap::apply()
+TetraTriangleMap::requestUpdate()
 {
-    // Check if map is active
-    if (!m_isActive)
-    {
-        LOG(WARNING) << "TetraTriangle map is not active";
-        return;
-    }
-
-    // Check geometries
-    CHECK(m_parentGeom && m_childGeom) << "TetraTriangle map is being applied without valid  geometries";
-
-    auto tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(m_parentGeom);
-    auto triMesh = std::dynamic_pointer_cast<SurfaceMesh>(m_childGeom);
-
-    CHECK(m_parentGeom != nullptr && m_childGeom != nullptr) << "Fail to cast from geometry to meshes";
+    auto tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(getParentGeometry());
+    auto pointSet = std::dynamic_pointer_cast<PointSet>(getChildGeometry());
 
     VecDataArray<double, 3>& vertices = *m_childVerts;
-    ParallelUtils::parallelFor(triMesh->getNumVertices(), [&](const size_t vertexId) {
-            const Vec4i& tetVerts = tetMesh->getTetrahedronIndices(m_verticesEnclosingTetraId[vertexId]);
-            const auto& weights   = m_verticesWeights[vertexId];
+    ParallelUtils::parallelFor(pointSet->getNumVertices(),
+        [&](const int vertexId)
+        {
+            const Vec4i& tetVerts =
+                tetMesh->getTetrahedronIndices(m_verticesEnclosingTetraId[vertexId]);
+            const Vec4d& weights = m_verticesWeights[vertexId];
 
             vertices[vertexId] = tetMesh->getVertexPosition(tetVerts[0]) * weights[0] +
                                  tetMesh->getVertexPosition(tetVerts[1]) * weights[1] +
@@ -115,85 +125,28 @@ TetraTriangleMap::apply()
                                  tetMesh->getVertexPosition(tetVerts[3]) * weights[3];
         });
 
-    triMesh->postModified();
-}
-
-void
-TetraTriangleMap::print() const
-{
-    // Print Type
-    GeometryMap::print();
+    pointSet->postModified();
 
-    // Print vertices and weight info
-    LOG(INFO) << "Vertex (<vertNum>): Tetrahedra: <TetNum> - Weights: (w1, w2, w3, w4)\n";
-    for (size_t vertexId = 0; vertexId < m_verticesEnclosingTetraId.size(); ++vertexId)
-    {
-        LOG(INFO) << "Vertex (" << vertexId << "):"
-                  << "\tTetrahedra: " << m_verticesEnclosingTetraId.at(vertexId) << " - Weights: "
-                  << "(" << m_verticesWeights.at(vertexId)[0] << ", "
-                  << m_verticesWeights.at(vertexId)[1] << ", " << m_verticesWeights.at(vertexId)[2]
-                  << ", " << m_verticesWeights.at(vertexId)[3] << ")";
-    }
+    setOutput(pointSet);
 }
 
-bool
-TetraTriangleMap::isValid() const
-{
-    auto meshParent = std::dynamic_pointer_cast<TetrahedralMesh>(m_parentGeom);
-    CHECK(m_parentGeom != nullptr) << "Fail to cast parent Geometry to TetrahedralMesh";
-
-    size_t            totalElementsParent = static_cast<size_t>(meshParent->getNumTetrahedra());
-    std::atomic<bool> bOK{ true };
-
-    ParallelUtils::parallelFor(m_verticesEnclosingTetraId.size(), [&](const size_t tetId) {
-            if (!bOK) // If map is invalid, no need to check further
-            {
-                return;
-            }
-            if (!(m_verticesEnclosingTetraId[tetId] < totalElementsParent))
-            {
-                bOK = false;
-            }
-        });
-
-    return bOK;
-}
-
-void
-TetraTriangleMap::setParentGeometry(std::shared_ptr<Geometry> parent)
-{
-    CHECK(parent != nullptr) << "The parent geometry provided is nullptr";
-    CHECK(std::dynamic_pointer_cast<TetrahedralMesh>(parent) != nullptr) <<
-        "The parent geometry provided is not TetrahedralMesh";
-    GeometryMap::setParentGeometry(parent);
-}
-
-void
-TetraTriangleMap::setChildGeometry(std::shared_ptr<Geometry> child)
-{
-    CHECK(child != nullptr) << "The child geometry provided is nullptr";
-    CHECK(std::dynamic_pointer_cast<SurfaceMesh>(child) != nullptr) <<
-        "The child geometry provided is not SurfaceMesh";
-    GeometryMap::setChildGeometry(child);
-}
-
-size_t
+int
 TetraTriangleMap::findClosestTetrahedron(const Vec3d& pos) const
 {
-    auto   tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(m_parentGeom);
-    double closestDistanceSqr = MAX_D;
-    size_t closestTetrahedron = std::numeric_limits<size_t>::max();
-    Vec3d  center(0, 0, 0);
+    auto   tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(getParentGeometry());
+    double closestDistanceSqr = IMSTK_DOUBLE_MAX;
+    int closestTetrahedron = IMSTK_INT_MAX;
+    Vec3d center(0.0, 0.0, 0.0);
 
-    for (int tetId = 0; tetId < tetMesh->getNumTetrahedra(); ++tetId)
+    for (int tetId = 0; tetId < tetMesh->getNumTetrahedra(); tetId++)
     {
         center = Vec3d::Zero();
         const Vec4i& vert = tetMesh->getTetrahedronIndices(tetId);
-        for (size_t i = 0; i < 4; ++i)
+        for (int i = 0; i < 4; i++)
         {
             center += tetMesh->getInitialVertexPosition(vert[i]);
         }
-        center = center / 4.;
+        center = center / 4.0;
 
         const double distSqr = (pos - center).squaredNorm();
         if (distSqr < closestDistanceSqr)
@@ -206,15 +159,15 @@ TetraTriangleMap::findClosestTetrahedron(const Vec3d& pos) const
     return closestTetrahedron;
 }
 
-size_t
+int
 TetraTriangleMap::findEnclosingTetrahedron(const Vec3d& pos) const
 {
-    auto   tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(m_parentGeom);
-    size_t enclosingTetrahedron = std::numeric_limits<size_t>::max();
+    auto   tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(getParentGeometry());
+    int enclosingTetrahedron = IMSTK_INT_MAX;
 
-    for (int idx = 0; idx < tetMesh->getNumTetrahedra(); ++idx)
+    for (int idx = 0; idx < tetMesh->getNumTetrahedra(); idx++)
     {
-        bool inBox = (pos[0] >= m_bBoxMin[idx][0] && pos[0] <= m_bBoxMax[idx][0])
+        const bool inBox = (pos[0] >= m_bBoxMin[idx][0] && pos[0] <= m_bBoxMax[idx][0])
                      && (pos[1] >= m_bBoxMin[idx][1] && pos[1] <= m_bBoxMax[idx][1])
                      && (pos[2] >= m_bBoxMin[idx][2] && pos[2] <= m_bBoxMax[idx][2]);
 
@@ -226,7 +179,6 @@ TetraTriangleMap::findEnclosingTetrahedron(const Vec3d& pos) const
         }
 
         const Vec4d weights = tetMesh->computeBarycentricWeights(idx, pos);
-
         if (weights[0] >= 0 && weights[1] >= 0 && weights[2] >= 0 && weights[3] >= 0)
         {
             enclosingTetrahedron = idx;
@@ -240,12 +192,13 @@ TetraTriangleMap::findEnclosingTetrahedron(const Vec3d& pos) const
 void
 TetraTriangleMap::updateBoundingBox()
 {
-    /// \todo use parallelFor
-    auto tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(m_parentGeom);
+    auto tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(getParentGeometry());
     m_bBoxMin.resize(tetMesh->getNumTetrahedra());
     m_bBoxMax.resize(tetMesh->getNumTetrahedra());
 
-    ParallelUtils::parallelFor(tetMesh->getNumTetrahedra(), [&](const size_t tid) {
+    ParallelUtils::parallelFor(tetMesh->getNumTetrahedra(),
+        [&](const int tid)
+        {
             tetMesh->computeTetrahedronBoundingBox(tid, m_bBoxMin[tid], m_bBoxMax[tid]);
         });
 
diff --git a/Source/GeometryMappers/imstkTetraTriangleMap.h b/Source/GeometryMappers/imstkTetraTriangleMap.h
index 4e9d47d02feb97ea13447faa30bcaff9276b0a20..2ef707e0703d9646060c6fb3998b1446368f8f68 100644
--- a/Source/GeometryMappers/imstkTetraTriangleMap.h
+++ b/Source/GeometryMappers/imstkTetraTriangleMap.h
@@ -23,6 +23,7 @@
 
 #include "imstkGeometryMap.h"
 #include "imstkMacros.h"
+#include "imstkMath.h"
 
 namespace imstk
 {
@@ -31,22 +32,17 @@ template<typename T, int N> class VecDataArray;
 ///
 /// \class TetraTriangleMap
 ///
-/// \brief Computes and applies the triangle-tetrahedra map. The parent mesh is the
-///  tetrahedral mesh and the child is the surface triangular mesh.
+/// \brief Computes and applies the PointSet-Tetrahedra map. Vertices of the
+/// child geometry are deformed according to the deformation of the tetrahedron
+/// they are located in. If they are not within one, nearest tet is used.
 ///
 class TetraTriangleMap : public GeometryMap
 {
 public:
-    TetraTriangleMap() : m_boundingBoxAvailable(false) { }
+    TetraTriangleMap();
     TetraTriangleMap(
         std::shared_ptr<Geometry> parent,
-        std::shared_ptr<Geometry> child)
-        : m_boundingBoxAvailable(false)
-    {
-        this->setParentGeometry(parent);
-        this->setChildGeometry(child);
-    }
-
+        std::shared_ptr<Geometry> child);
     ~TetraTriangleMap() override = default;
 
     IMSTK_TYPE_NAME(TetraTriangleMap)
@@ -56,36 +52,16 @@ public:
     ///
     void compute() override;
 
+protected:
     ///
     /// \brief Apply (if active) the tetra-triangle mesh map
     ///
-    void apply() override;
-
-    ///
-    /// \brief Print the map
-    ///
-    void print() const override;
-
-    ///
-    /// \brief Check the validity of the map
-    ///
-    bool isValid() const override;
+    void requestUpdate() override;
 
-    ///
-    /// \brief Set the geometry that dictates the map
-    ///
-    void setParentGeometry(std::shared_ptr<Geometry> parent) override;
-
-    ///
-    /// \brief Set the geometry that follows the parent
-    ///
-    void setChildGeometry(std::shared_ptr<Geometry> child) override;
-
-protected:
     ///
     /// \brief Find the tetrahedron that encloses a given point in 3D space
     ///
-    size_t findEnclosingTetrahedron(const Vec3d& pos) const;
+    int findEnclosingTetrahedron(const Vec3d& pos) const;
 
     ///
     /// \brief Update bounding box of each tetrahedra of the mesh
@@ -96,11 +72,12 @@ protected:
     /// \brief Find the closest tetrahedron based on the distance to their centroids for a given
     /// point in 3D space
     ///
-    size_t findClosestTetrahedron(const Vec3d& pos) const;
+    int findClosestTetrahedron(const Vec3d& pos) const;
 
+protected:
     std::vector<Vec4d> m_verticesWeights;           ///> weights
 
-    std::vector<size_t> m_verticesEnclosingTetraId; ///> Enclosing tetrahedra to interpolate the weights upon
+    std::vector<int> m_verticesEnclosingTetraId; ///> Enclosing tetrahedra to interpolate the weights upon
 
     std::vector<Vec3d> m_bBoxMin;
     std::vector<Vec3d> m_bBoxMax;
diff --git a/Source/SceneEntities/Objects/imstkCollidingObject.cpp b/Source/SceneEntities/Objects/imstkCollidingObject.cpp
index 0c6ad615f4f9c4194600dbde8c49a030700a02a1..9cb3d9fd96b3dda43aeb91390db0bf86401821a7 100644
--- a/Source/SceneEntities/Objects/imstkCollidingObject.cpp
+++ b/Source/SceneEntities/Objects/imstkCollidingObject.cpp
@@ -20,6 +20,7 @@
 =========================================================================*/
 
 #include "imstkCollidingObject.h"
+#include "imstkGeometry.h"
 #include "imstkGeometryMap.h"
 
 namespace imstk
@@ -34,7 +35,7 @@ CollidingObject::initialize()
 
     if (m_collidingToVisualMap)
     {
-        m_collidingToVisualMap->initialize();
+        m_collidingToVisualMap->compute();
     }
 
     return true;
@@ -69,7 +70,7 @@ CollidingObject::updateGeometries()
 {
     if (m_collidingToVisualMap)
     {
-        m_collidingToVisualMap->apply();
+        m_collidingToVisualMap->update();
         m_collidingToVisualMap->getChildGeometry()->postModified();
     }
     SceneObject::updateGeometries();
diff --git a/Source/SceneEntities/Objects/imstkDynamicObject.cpp b/Source/SceneEntities/Objects/imstkDynamicObject.cpp
index d4c1da38f46cc1501c6fd5337d4b6ae2e6ef22dc..adb1d5d42f23bf8957f8d25e49ec03116bfddc82 100644
--- a/Source/SceneEntities/Objects/imstkDynamicObject.cpp
+++ b/Source/SceneEntities/Objects/imstkDynamicObject.cpp
@@ -49,7 +49,7 @@ DynamicObject::updateGeometries()
     {
         if (m_physicsToVisualGeomMap)
         {
-            m_physicsToVisualGeomMap->apply();
+            m_physicsToVisualGeomMap->update();
             m_physicsToVisualGeomMap->getChildGeometry()->postModified();
         }
     }
@@ -66,7 +66,7 @@ DynamicObject::updatePhysicsGeometry()
 
     if (m_physicsToCollidingGeomMap)
     {
-        m_physicsToCollidingGeomMap->apply();
+        m_physicsToCollidingGeomMap->update();
         m_physicsToCollidingGeomMap->getChildGeometry()->postModified();
     }
 
@@ -83,12 +83,12 @@ DynamicObject::initialize()
     {
         if (m_physicsToCollidingGeomMap)
         {
-            m_physicsToCollidingGeomMap->initialize();
+            m_physicsToCollidingGeomMap->compute();
         }
 
         if (m_physicsToVisualGeomMap)
         {
-            m_physicsToVisualGeomMap->initialize();
+            m_physicsToVisualGeomMap->compute();
         }
 
         return m_dynamicalModel->initialize();