diff --git a/Examples/CameraController/CameraControllerExample.cpp b/Examples/CameraController/CameraControllerExample.cpp
index 060cbefe12c35b9b9b6889eec71df74fb7e613d4..a50bb128bc7b190acb106fd2693cee921faaad19 100644
--- a/Examples/CameraController/CameraControllerExample.cpp
+++ b/Examples/CameraController/CameraControllerExample.cpp
@@ -57,13 +57,13 @@ main()
     std::shared_ptr<HapticDeviceClient> client = server->makeDeviceClient();
 
     // Load Mesh
-    auto                   mesh = MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT "/asianDragon/asianDragon.obj");
-    imstkNew<VisualObject> meshObject("meshObject");
+    auto                  mesh = MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT "/asianDragon/asianDragon.obj");
+    imstkNew<SceneObject> meshObject("meshObject");
     meshObject->setVisualGeometry(mesh);
     scene->addSceneObject(meshObject);
 
-    imstkNew<VisualObject> planeObject("Plane");
-    imstkNew<Plane>        plane(Vec3d(0.0, -2.0, 0.0));
+    imstkNew<SceneObject> planeObject("Plane");
+    imstkNew<Plane>       plane(Vec3d(0.0, -2.0, 0.0));
     plane->setWidth(1000.0);
     planeObject->setVisualGeometry(plane);
     scene->addSceneObject(planeObject);
diff --git a/Examples/CreateEnclosingMesh/CreateEnclosingMesh.cpp b/Examples/CreateEnclosingMesh/CreateEnclosingMesh.cpp
index 875424bbd9d6dc73e4a5f9263d0ebfc052f7ea84..c16e54a1fcc5a7d380368f9843ac21c3f64a0de2 100644
--- a/Examples/CreateEnclosingMesh/CreateEnclosingMesh.cpp
+++ b/Examples/CreateEnclosingMesh/CreateEnclosingMesh.cpp
@@ -53,7 +53,7 @@ main()
         scene->getActiveCamera()->setPosition(0.0, 2.0, 15.0);
 
         // add scene object for surface object
-        imstkNew<VisualObject> surfObj("SurfaceObject");
+        imstkNew<SceneObject> surfObj("SurfaceObject");
 
         auto surfMesh = MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT "/asianDragon/asianDragon.obj");
 
@@ -72,7 +72,7 @@ main()
             GeometryUtils::createTetrahedralMeshCover(surfMesh, nx, ny, nz);
 
         // add scene object for surface object
-        imstkNew<VisualObject>   volObject("VolObj");
+        imstkNew<SceneObject>    volObject("VolObj");
         imstkNew<RenderMaterial> tetMaterial;
         tetMaterial->setDisplayMode(RenderMaterial::DisplayMode::Wireframe);
         tetMaterial->setColor(Color::Teal);
diff --git a/Examples/GeometryProcessing/GeometryProcessingExample.cpp b/Examples/GeometryProcessing/GeometryProcessingExample.cpp
index 2e6b201ab68bd6b64f6bc68d67ed3307f9568267..836a8adc22e5ed7b66f5749180ea343f80a017a0 100644
--- a/Examples/GeometryProcessing/GeometryProcessingExample.cpp
+++ b/Examples/GeometryProcessing/GeometryProcessingExample.cpp
@@ -82,7 +82,7 @@ main()
     reduce->update();
 
     // Create the scene object
-    imstkNew<VisualObject> sceneObj("Mesh");
+    imstkNew<SceneObject> sceneObj("Mesh");
     // Create the eroded visual model
     {
         imstkNew<VisualModel>    surfMeshModel(reduce->getOutput());
diff --git a/Examples/GeometryTransforms/GeometryTransformsExample.cpp b/Examples/GeometryTransforms/GeometryTransformsExample.cpp
index b236f7de26905b018624ba100f97d094ab545ea9..26e00363ae1c335765390a7450f380e9f49c3483 100644
--- a/Examples/GeometryTransforms/GeometryTransformsExample.cpp
+++ b/Examples/GeometryTransforms/GeometryTransformsExample.cpp
@@ -70,7 +70,7 @@ main()
     imstkNew<VisualModel> planeVisualModel(planeGeom.get());
     planeVisualModel->setRenderMaterial(planeMaterial);
 
-    imstkNew<VisualObject> planeObj("Plane");
+    imstkNew<SceneObject> planeObj("Plane");
     planeObj->addVisualModel(planeVisualModel);
     scene->addSceneObject(planeObj);
 
@@ -90,7 +90,7 @@ main()
     imstkNew<VisualModel> cubeVisualModel(cubeGeom.get());
     cubeVisualModel->setRenderMaterial(redMaterial);
 
-    imstkNew<VisualObject> cubeObj("Cube");
+    imstkNew<SceneObject> cubeObj("Cube");
     cubeObj->addVisualModel(cubeVisualModel);
     scene->addSceneObject(cubeObj);
 
@@ -105,7 +105,7 @@ main()
     imstkNew<VisualModel> cylVisualModel(cylinderGeom.get());
     cylVisualModel->setRenderMaterial(redMaterial);
 
-    imstkNew<VisualObject> cylObj("Cylinder");
+    imstkNew<SceneObject> cylObj("Cylinder");
     cylObj->addVisualModel(cylVisualModel);
     scene->addSceneObject(cylObj);
 
diff --git a/Examples/Octree/OctreeExample.cpp b/Examples/Octree/OctreeExample.cpp
index 3ada5615836fa62f73d47a0ca9226e8247efb647..d33400aca14456eeb0dc3e253ba72a20efac62a9 100644
--- a/Examples/Octree/OctreeExample.cpp
+++ b/Examples/Octree/OctreeExample.cpp
@@ -54,7 +54,7 @@ static std::pair<std::shared_ptr<VecDataArray<double, 3>>, std::shared_ptr<VecDa
 ///
 /// \brief Read a mesh, create a visual scene object and add to the scene
 ///
-std::shared_ptr<VisualObject>
+std::shared_ptr<SceneObject>
 createMeshObject(const std::string& objectName,
                  const Color&       color)
 {
@@ -74,7 +74,7 @@ createMeshObject(const std::string& objectName,
     material->setLineWidth(1.0);
     visualModel->setRenderMaterial(material);
 
-    imstkNew<VisualObject> visualObject(objectName);
+    imstkNew<SceneObject> visualObject(objectName);
     visualObject->addVisualModel(visualModel);
 
     return visualObject;
diff --git a/Examples/OpenVRController/OpenVRControllerExample.cpp b/Examples/OpenVRController/OpenVRControllerExample.cpp
index 166c86cbc109cf8322502e2d2911061cb48f8b00..a248bbdedc16c6e35f6e1ccbf97cde97e8d43341 100644
--- a/Examples/OpenVRController/OpenVRControllerExample.cpp
+++ b/Examples/OpenVRController/OpenVRControllerExample.cpp
@@ -112,7 +112,7 @@ main()
     scene->addSceneObject(scalpelBlade15);
     scalpelBlade15->getMasterGeometry()->setTranslation(0.2, 1.0, -0.8);
 
-    std::shared_ptr<VisualObject> tableObj = ObjectIO::importSceneObject("Instrument Table",
+    std::shared_ptr<SceneObject> tableObj = ObjectIO::importSceneObject("Instrument Table",
         iMSTK_DATA_ROOT "/Surgical instruments/Instrument Table/Instrument_Table.dae",
         iMSTK_DATA_ROOT "/Surgical instruments/Instrument Table/");
     scene->addSceneObject(tableObj);
diff --git a/Examples/Rendering/RenderingExample.cpp b/Examples/Rendering/RenderingExample.cpp
index 15451e7072bba8005ec3d631598a7270fbddad8d..80b568bc612c138ad20e6bfc95fd10d1b27df65b 100644
--- a/Examples/Rendering/RenderingExample.cpp
+++ b/Examples/Rendering/RenderingExample.cpp
@@ -82,7 +82,7 @@ main()
         imstkNew<VisualModel> surfMeshModel(surfaceMesh);
         surfMeshModel->setRenderMaterial(material);
 
-        imstkNew<VisualObject> headObject("head");
+        imstkNew<SceneObject> headObject("head");
         headObject->addVisualModel(surfMeshModel);
 
         // Head material with textures
diff --git a/Examples/RigidBodyVirtualCoupling/RigidBodyVirtualCouplingExample.cpp b/Examples/RigidBodyVirtualCoupling/RigidBodyVirtualCouplingExample.cpp
index e9e701ae4b8a642d8fb3245ff75bb0f7325d5935..b465fe10376fe53ef788ea137ede69dfeb9d271c 100644
--- a/Examples/RigidBodyVirtualCoupling/RigidBodyVirtualCouplingExample.cpp
+++ b/Examples/RigidBodyVirtualCoupling/RigidBodyVirtualCouplingExample.cpp
@@ -204,7 +204,7 @@ main()
 
     // Create a virtual coupling object
     imstkNew<Sphere>         visualGeom(Vec3d(0.0, 0.0, 0.0), 5.0);
-    imstkNew<VisualObject>   obj("virtualCouplingObject");
+    imstkNew<SceneObject>    obj("virtualCouplingObject");
     imstkNew<RenderMaterial> material;
     imstkNew<VisualModel>    visualModel(visualGeom.get());
     visualModel->setRenderMaterial(material);
diff --git a/Examples/SPHFluid/Solid.hpp b/Examples/SPHFluid/Solid.hpp
index fdeb881c15d92a7140c91363329e2518e1d45940..96eecc54aa2ff500473398b49de31461d1701539 100644
--- a/Examples/SPHFluid/Solid.hpp
+++ b/Examples/SPHFluid/Solid.hpp
@@ -227,7 +227,7 @@ std::vector<std::shared_ptr<CollidingObject>> generateSolidsScene4(const std::sh
   std::vector<std::shared_ptr<CollidingObject>> solids;
 
   {
-    auto surfaceObject = std::make_shared<VisualObject>("SurfaceObj");
+    auto surfaceObject = std::make_shared<SceneObject>("SurfaceObj");
     auto surfMesh = std::dynamic_pointer_cast<SurfaceMesh>(MeshIO::read(iMSTK_DATA_ROOT "/cylinder/cylinder.stl"));
 
     //auto visualModel = std::make_shared<VisualModel>(surfMesh);
diff --git a/Examples/Screenshot/ScreenshotExample.cpp b/Examples/Screenshot/ScreenshotExample.cpp
index 19573f17676c9aaea8d426deb67128938eca049c..3254113c2a0ec7e8a88263935ea27f92205dcc02 100644
--- a/Examples/Screenshot/ScreenshotExample.cpp
+++ b/Examples/Screenshot/ScreenshotExample.cpp
@@ -53,7 +53,7 @@ main()
     // Plane
     imstkNew<Plane> planeGeom;
     planeGeom->setWidth(10.0);
-    imstkNew<VisualObject> planeObj("VisualPlane");
+    imstkNew<SceneObject> planeObj("VisualPlane");
     planeObj->setVisualGeometry(planeGeom);
 
     // Cube
@@ -63,14 +63,14 @@ main()
     // rotates could be replaced by cubeGeom->setOrientationAxis(1,1,1) (normalized inside)
     cubeGeom->rotate(UP_VECTOR, PI_4, Geometry::TransformType::ApplyToData);
     cubeGeom->rotate(RIGHT_VECTOR, PI_4, Geometry::TransformType::ApplyToData);
-    imstkNew<VisualObject> cubeObj("VisualCube");
+    imstkNew<SceneObject> cubeObj("VisualCube");
     cubeObj->setVisualGeometry(cubeGeom);
 
     // Sphere
     imstkNew<Sphere> sphereGeom;
     sphereGeom->setRadius(0.3);
     sphereGeom->setPosition(0.0, 2.0, 0.0);
-    imstkNew<VisualObject> sphereObj("VisualSphere");
+    imstkNew<SceneObject> sphereObj("VisualSphere");
     sphereObj->setVisualGeometry(sphereGeom);
 
     // Light (white)
diff --git a/Examples/VolumeRendering/VolumeRenderingExample.cpp b/Examples/VolumeRendering/VolumeRenderingExample.cpp
index f4941787e1c85d58aff8fa43562257164fda97c9..090974e63dda14b6cfcc9223a1a8d18103ea8259 100644
--- a/Examples/VolumeRendering/VolumeRenderingExample.cpp
+++ b/Examples/VolumeRendering/VolumeRenderingExample.cpp
@@ -51,8 +51,8 @@ main()
     imstkNew<Scene> scene("VolumeRendering");
 
     // Create a visual object in the scene for the volume
-    imstkNew<VisualObject> volumeObj("VisualVolume");
-    auto                   imageData = MeshIO::read<ImageData>(iMSTK_DATA_ROOT "skullVolume.nrrd");
+    imstkNew<SceneObject> volumeObj("VisualVolume");
+    auto                  imageData = MeshIO::read<ImageData>(iMSTK_DATA_ROOT "skullVolume.nrrd");
     volumeObj->setVisualGeometry(imageData);
     scene->addSceneObject(volumeObj);
 
diff --git a/Source/Scene/imstkScene.cpp b/Source/Scene/imstkScene.cpp
index 3d662688dae0c3aa218f22308994ff4d103f4950..0273ba0d4d08ef63bf2b8849ac584c8d4dbade4a 100644
--- a/Source/Scene/imstkScene.cpp
+++ b/Source/Scene/imstkScene.cpp
@@ -123,7 +123,7 @@ Scene::buildTaskGraph()
     for (auto const& it : m_sceneObjectsMap)
     {
         auto sceneObject = it.second;
-        if (sceneObject->getType() == SceneObject::Type::Rigid)
+        if (sceneObject->getTypeName() == "RigidObject")
         {
             rigidBodies.push_back(sceneObject);
         }
diff --git a/Source/SceneEntities/Lights/imstkLight.h b/Source/SceneEntities/Lights/imstkLight.h
index c0e5d65878a4f973642124a9d8dd3343804f189a..c7530305cfd7c16c4ff073a14b92bd7a00534b2a 100644
--- a/Source/SceneEntities/Lights/imstkLight.h
+++ b/Source/SceneEntities/Lights/imstkLight.h
@@ -49,75 +49,76 @@ class Light : public SceneEntity
 public:
     virtual ~Light() override = default;
 
+public:
     ///
     /// \brief Returns the type of light (see imstk::LightType)
     ///
-    LightType getType() const { return m_type; };
+    LightType getType() const { return m_type; }
 
     ///
     /// \brief Set the type of the light
     ///
-    void setType(const LightType& type) { m_type = type; };
+    void setType(const LightType& type) { m_type = type; }
 
     ///
     /// \brief Set the light focal point
     ///
-    virtual void setFocalPoint(const Vec3d& p) { this->setFocalPoint((float)p[0], (float)p[1], (float)p[2]); };
+    virtual void setFocalPoint(const Vec3d& p) { this->setFocalPoint((float)p[0], (float)p[1], (float)p[2]); }
     virtual void setFocalPoint(const float& x, const float& y, const float& z);
     const Vec3f getFocalPoint() const { return m_focalPoint; }
 
     ///
     /// \brief Get the status (On/off) of the light
     ///
-    bool isOn() const { return m_switchState; };
+    bool isOn() const { return m_switchState; }
 
     ///
     /// \brief Switch the light On
     ///
-    void switchOn() { m_switchState = true; };
+    void switchOn() { m_switchState = true; }
 
     ///
     /// \brief Get the status (On/off) of the light
     ///
-    bool isOff() const { return m_switchState; };
+    bool isOff() const { return m_switchState; }
 
     ///
     /// \brief Switch the light Off
     ///
-    void switchOff() { m_switchState = false; };
+    void switchOff() { m_switchState = false; }
 
     ///
     /// \brief Get the light color
     ///
-    const Color getColor() const { return m_color; };
+    const Color getColor() const { return m_color; }
 
     ///
     /// \brief Set the light color
     ///
-    void setColor(const Color& c) { m_color = c; };
+    void setColor(const Color& c) { m_color = c; }
 
     ///
     /// \brief Get the light intensity
     ///
-    float getIntensity() const { return m_intensity; };
+    float getIntensity() const { return m_intensity; }
 
     ///
     /// \brief Set the light intensity. This value is unbounded.
     ///
-    void setIntensity(double intensity) { m_intensity = (float)intensity; };
+    void setIntensity(double intensity) { m_intensity = (float)intensity; }
 
     ///
     /// \brief Get the light name
     ///
-    const std::string& getName() const { return m_name; };
+    const std::string& getName() const { return m_name; }
 
     ///
     /// \brief Set the light name
     ///
-    void setName(std::string name) { m_name = name; };
+    void setName(std::string name) { m_name = name; }
 
 protected:
-    explicit Light(const std::string& name, const LightType& type) : SceneEntity(), m_name(name), m_type(type) {};
+    Light(const std::string& name, const LightType& type) : SceneEntity(), m_name(name), m_type(type) { }
 
     // properties with defaults
     float m_intensity   = 1.;
@@ -142,32 +143,32 @@ protected:
 class DirectionalLight : public Light
 {
 public:
-    ///
-    /// \brief Constructor
-    ///
-    explicit DirectionalLight(const std::string& name) : Light(name, LightType::Directional)
+    DirectionalLight(const std::string& name) : Light(name, LightType::Directional)
     {
-        this->setFocalPoint(-1, -1, -1);
-    };
+        this->setFocalPoint(-1.0f, -1.0f, -1.0f);
+    }
 
     virtual ~DirectionalLight() override = default;
 
+public:
+    virtual const std::string getTypeName() const { return "DirectionalLight"; }
+
     ///
     /// \brief Turn shadows on
     ///
-    void setCastsShadow(bool shadow) { m_castShadow = shadow; };
+    void setCastsShadow(bool shadow) { m_castShadow = shadow; }
 
     ///
     /// \brief Center point for shadow projection
     /// Sets the shadow map center to this position
     ///
-    void setShadowCenter(const Vec3d& center) { m_shadowCenter = center.cast<float>(); };
+    void setShadowCenter(const Vec3d& center) { m_shadowCenter = center.cast<float>(); }
 
     ///
     /// \brief Range for shadows
     /// A smaller range results in a denser shadow map
     ///
-    void setShadowRange(const double range) { m_shadowRange = static_cast<float>(range); };
+    void setShadowRange(const double range) { m_shadowRange = static_cast<float>(range); }
 
     ///
     /// \brief Direction of the light
@@ -179,8 +180,8 @@ protected:
     friend class VulkanRenderer;
 
     bool  m_castShadow     = true;
-    Vec3f m_shadowCenter   = Vec3f(0, 0, 0);
-    float m_shadowRange    = 2.0;
+    Vec3f m_shadowCenter   = Vec3f(0.0f, 0.0f, 0.0f);
+    float m_shadowRange    = 2.0f;
     int   m_shadowMapIndex = -1;
 };
 
@@ -200,10 +201,13 @@ public:
     ///
     /// \brief Constructors
     ///
-    explicit PointLight(const std::string& name, const LightType& type = LightType::Point) : Light(name, type) {};
+    PointLight(const std::string& name, const LightType& type = LightType::Point) : Light(name, type) { }
 
     virtual ~PointLight() override = default;
 
+public:
+    virtual const std::string getTypeName() const { return "PointLight"; }
+
     ///
     /// \brief Get the cone angle
     ///
@@ -212,27 +216,30 @@ public:
     ///
     /// \brief Get the light position
     ///
-    void setConeAngle(const double angle) { m_coneAngle = (float)angle; };
+    void setConeAngle(const double angle) { m_coneAngle = (float)angle; }
 
     ///
     /// \brief Get the light position
     ///
-    const Vec3f getPosition() const { return m_position; };
+    const Vec3f getPosition() const { return m_position; }
 
     ///
     /// \brief Set the light position
     ///
     void setPosition(const Vec3d& p)
     {
-        m_position = Vec3f((float)p[0], (float)p[1], (float)p[2]);
+        m_position = Vec3f(
+            static_cast<float>(p[0]),
+            static_cast<float>(p[1]),
+            static_cast<float>(p[2]));
     };
     void setPosition(const double& x, const double& y, const double& z)
     {
         this->setPosition(Vec3d(x, y, z));
-    };
+    }
 
 protected:
-    Vec3f m_position  = Vec3f(0, 0, 0);
+    Vec3f m_position  = Vec3f(0.0f, 0.0f, 0.0f);
     float m_coneAngle = 179.0f;
 };
 
@@ -249,24 +256,27 @@ public:
     ///
     /// \brief Constructors
     ///
-    explicit SpotLight(const std::string& name) : PointLight(name, LightType::Spot)
+    SpotLight(const std::string& name) : PointLight(name, LightType::Spot)
     {
-        m_coneAngle = 10.;
-    };
+        m_coneAngle = 10.0f;
+    }
 
     virtual ~SpotLight() override = default;
 
+public:
+    virtual const std::string getTypeName() const { return "SpotLight"; }
+
     ///
     /// \brief Get the spotlight angle in degrees
     ///
-    float getSpotAngle() const { return m_spotAngle; };
+    float getSpotAngle() const { return m_spotAngle; }
 
     ///
     /// \brief Set the spotlight angle in degrees
     ///
-    void setSpotAngle(const double& angle) { m_spotAngle = (float)angle; };
+    void setSpotAngle(const double& angle) { m_spotAngle = static_cast<float>(angle); }
 
 protected:
-    float m_spotAngle = 45.;
+    float m_spotAngle = 45.0f;
 };
 } // imstk
\ No newline at end of file
diff --git a/Source/SceneEntities/Loader/imstkVisualObjectImporter.cpp b/Source/SceneEntities/Loader/imstkVisualObjectImporter.cpp
index 51d4875ffceade3c546b648011cac15f0b7be2ad..5a86daf49283ff9249de4957f17e9eed0a325b94 100644
--- a/Source/SceneEntities/Loader/imstkVisualObjectImporter.cpp
+++ b/Source/SceneEntities/Loader/imstkVisualObjectImporter.cpp
@@ -63,7 +63,7 @@ mat4dToAiMat(const Mat4d& m)
     return results;
 }
 
-std::shared_ptr<VisualObject>
+std::shared_ptr<SceneObject>
 ObjectIO::importSceneObject(
     const std::string& objName,
     const std::string& modelFilePath,
@@ -82,7 +82,7 @@ ObjectIO::importSceneObject(
         return nullptr;
     }
 
-    auto visualObject = std::make_shared<VisualObject>(objName);
+    auto visualObject = std::make_shared<SceneObject>(objName);
 
     // Import mesh(es) and apply some clean-up operations
     Assimp::Importer importer;
diff --git a/Source/SceneEntities/Loader/imstkVisualObjectImporter.h b/Source/SceneEntities/Loader/imstkVisualObjectImporter.h
index d99b1313e6004b5708ff8856246fac20380295aa..96a6beaccff5af498c1a26fdf087f8811bd73518 100644
--- a/Source/SceneEntities/Loader/imstkVisualObjectImporter.h
+++ b/Source/SceneEntities/Loader/imstkVisualObjectImporter.h
@@ -24,7 +24,7 @@
 #include "imstkTexture.h"
 #include "imstkMath.h"
 
-class aiMaterial;
+struct aiMaterial;
 
 namespace imstk
 {
diff --git a/Source/SceneEntities/Objects/imstkAnimationObject.h b/Source/SceneEntities/Objects/imstkAnimationObject.h
index 06e178e1560449dbf3359ab22a1671f4eac31565..3c9cc47d6c035fc67402c68a3b8bd1ecde399774 100644
--- a/Source/SceneEntities/Objects/imstkAnimationObject.h
+++ b/Source/SceneEntities/Objects/imstkAnimationObject.h
@@ -34,18 +34,11 @@ class AnimationModel;
 class AnimationObject : public SceneObject
 {
 public:
-    ///
-    /// \brief Constructor
-    ///
-    explicit AnimationObject(const std::string& name) : SceneObject(name)
-    {
-        m_type = Type::Animation;
-    }
+    AnimationObject(const std::string& name) : SceneObject(name) { }
+    virtual ~AnimationObject() override = default;
 
-    ///
-    /// \brief Default destructor
-    ///
-    virtual ~AnimationObject() = default;
+public:
+    virtual const std::string getTypeName() const override { return "AnimationObject"; }
 
     ///
     /// \brief Set/get animation model
diff --git a/Source/SceneEntities/Objects/imstkCollidingObject.h b/Source/SceneEntities/Objects/imstkCollidingObject.h
index a757fabb195ee5584fac7b3508c259cb881047ed..93edaba09e48104634486fe991b659e4a51a20ea 100644
--- a/Source/SceneEntities/Objects/imstkCollidingObject.h
+++ b/Source/SceneEntities/Objects/imstkCollidingObject.h
@@ -29,23 +29,20 @@ namespace imstk
 class Geometry;
 class GeometryMap;
 
-/// \brief TODO
+///
+/// \class CollidingObject
+///
+/// \brief A SceneObject with a geometry for collision
+///
 class CollidingObject : public SceneObject
 {
 public:
-    ///
-    /// \brief
-    ///
-    explicit CollidingObject(const std::string& name) : SceneObject(name)
-    {
-        m_type = Type::Colliding;
-    }
-
-    ///
-    /// \brief
-    ///
+    CollidingObject(const std::string& name) : SceneObject(name) { }
     virtual ~CollidingObject() override = default;
 
+public:
+    virtual const std::string getTypeName() const override { return "CollidingObject"; }
+
     ///
     /// \brief
     ///
diff --git a/Source/SceneEntities/Objects/imstkDynamicObject.h b/Source/SceneEntities/Objects/imstkDynamicObject.h
index a08060780349f008bbdf4ddeb0be55c845416fb6..062c060a7ef7ef0331f707f795c23c7de46d26a3 100644
--- a/Source/SceneEntities/Objects/imstkDynamicObject.h
+++ b/Source/SceneEntities/Objects/imstkDynamicObject.h
@@ -40,7 +40,7 @@ public:
     ///
     /// \brief Destructor
     ///
-    virtual ~DynamicObject() = default;
+    virtual ~DynamicObject() override = default;
 
     ///
     /// \brief Set/Get the geometry used for Physics computations
@@ -103,11 +103,10 @@ protected:
     virtual void initGraphEdges(std::shared_ptr<TaskNode> source, std::shared_ptr<TaskNode> sink) override;
 
 protected:
-
     ///
     /// \brief Constructor
     ///
-    explicit DynamicObject(const std::string& name) : CollidingObject(name) {}
+    DynamicObject(const std::string& name) : CollidingObject(name) { }
 
     std::shared_ptr<AbstractDynamicalModel> m_dynamicalModel = nullptr; ///> Dynamical model
     std::shared_ptr<Geometry> m_physicsGeometry = nullptr;              ///> Geometry used for Physics
diff --git a/Source/SceneEntities/Objects/imstkFeDeformableObject.h b/Source/SceneEntities/Objects/imstkFeDeformableObject.h
index 1cef4ac8e665a9428d971e9ed5862bde9eadfdcd..774364587ef468a53838eea83c3cf43b3a6416d3 100644
--- a/Source/SceneEntities/Objects/imstkFeDeformableObject.h
+++ b/Source/SceneEntities/Objects/imstkFeDeformableObject.h
@@ -36,12 +36,12 @@ class FEMDeformableBodyModel;
 class FeDeformableObject : public DynamicObject
 {
 public:
-    explicit FeDeformableObject(const std::string& name) : DynamicObject(name) { m_type = Type::FEMDeformable; }
-    FeDeformableObject() = delete;
-
-    ~FeDeformableObject() = default;
+    FeDeformableObject(const std::string& name) : DynamicObject(name) { }
+    virtual ~FeDeformableObject() override = default;
 
 public:
+    virtual const std::string getTypeName() const override { return "FeDeformableObject"; }
+
     ///
     /// \brief Initialize the deformable object
     ///
diff --git a/Source/SceneEntities/Objects/imstkLevelSetDeformableObject.h b/Source/SceneEntities/Objects/imstkLevelSetDeformableObject.h
index e8aa41d18c77ae15f1571f3311cb3e639573b62e..2b3de0e2db41016fc0acc2280541f969976022b6 100644
--- a/Source/SceneEntities/Objects/imstkLevelSetDeformableObject.h
+++ b/Source/SceneEntities/Objects/imstkLevelSetDeformableObject.h
@@ -36,16 +36,12 @@ class LevelSetModel;
 class LevelSetDeformableObject : public DynamicObject
 {
 public:
-    explicit LevelSetDeformableObject(const std::string& name) : DynamicObject(name)
-    {
-        m_type = SceneObject::Type::LevelSetDeformable;
-    }
-
-    LevelSetDeformableObject() = delete;
-
+    LevelSetDeformableObject(const std::string& name) : DynamicObject(name) { }
     virtual ~LevelSetDeformableObject() override = default;
 
 public:
+    virtual const std::string getTypeName() const override { return "LevelSetDeformableObject"; }
+
     ///
     /// \biref Get the Pbd model of the object
     ///
diff --git a/Source/SceneEntities/Objects/imstkPbdObject.h b/Source/SceneEntities/Objects/imstkPbdObject.h
index d48cae4ca3d4a3e5983e5463ce2ff082d27236ca..ce682c388ae2c89e501c7d1f0ceb87b5319196b3 100644
--- a/Source/SceneEntities/Objects/imstkPbdObject.h
+++ b/Source/SceneEntities/Objects/imstkPbdObject.h
@@ -36,16 +36,12 @@ class PbdModel;
 class PbdObject : public DynamicObject
 {
 public:
-    explicit PbdObject(const std::string& name) : DynamicObject(name)
-    {
-        m_type = SceneObject::Type::Pbd;
-    }
-
-    PbdObject() = delete;
-
+    PbdObject(const std::string& name) : DynamicObject(name) { }
     virtual ~PbdObject() override = default;
 
 public:
+    virtual const std::string getTypeName() const override { return "PbdObject"; }
+
     ///
     /// \biref Get the Pbd model of the object
     ///
diff --git a/Source/SceneEntities/Objects/imstkRigidObject.h b/Source/SceneEntities/Objects/imstkRigidObject.h
index 8383495bfedcfbefe83a11972d1962be37cf6b32..83ca3c85fbb556cdc2bb5ce7e844ab76a415af19 100644
--- a/Source/SceneEntities/Objects/imstkRigidObject.h
+++ b/Source/SceneEntities/Objects/imstkRigidObject.h
@@ -35,14 +35,12 @@ class RigidBodyModel;
 class RigidObject : public DynamicObject
 {
 public:
-    explicit RigidObject(const std::string& name) : DynamicObject(name)
-    {
-        m_type = Type::Rigid;
-    }
-
-    virtual ~RigidObject() = default;
+    RigidObject(const std::string& name) : DynamicObject(name) { }
+    virtual ~RigidObject() override = default;
 
 public:
+    virtual const std::string getTypeName() const override { return "RigidObject"; }
+
     ///
     /// \brief Initialize the rigid scene object
     ///
@@ -53,6 +51,9 @@ public:
     ///
     void addForce(const Vec3d& force, const Vec3d& pos, bool wakeup = true);
 
+    ///
+    /// \brief Get the model governing the rigid dynamics of this object
+    ///
     std::shared_ptr<RigidBodyModel> getRigidBodyModel();
 
 protected:
diff --git a/Source/SceneEntities/Objects/imstkRigidObject2.h b/Source/SceneEntities/Objects/imstkRigidObject2.h
index 1a65255404a033e587fdc74827046cbc1dc70909..9cd786ba784586d92672dfc976fad3ae0b8bb571 100644
--- a/Source/SceneEntities/Objects/imstkRigidObject2.h
+++ b/Source/SceneEntities/Objects/imstkRigidObject2.h
@@ -26,6 +26,7 @@
 namespace imstk
 {
 class PointSet;
+
 namespace expiremental
 {
 class RigidBodyModel2;
@@ -39,14 +40,12 @@ struct RigidBody;
 class RigidObject2 : public DynamicObject
 {
 public:
-    explicit RigidObject2(const std::string& name) : DynamicObject(name)
-    {
-        m_type = Type::Rigid2;
-    }
-
-    virtual ~RigidObject2() = default;
+    RigidObject2(const std::string& name) : DynamicObject(name) { }
+    virtual ~RigidObject2() override = default;
 
 public:
+    virtual const std::string getTypeName() const override { return "RigidObject2"; }
+
     ///
     /// \brief Initialize the rigid scene object
     ///
diff --git a/Source/SceneEntities/Objects/imstkSPHObject.cpp b/Source/SceneEntities/Objects/imstkSPHObject.cpp
index 33f8d209ceb32460d9a088582fee12ed2666ab74..a8771baad9fc1ddf7edf537e20ab592004c0965c 100644
--- a/Source/SceneEntities/Objects/imstkSPHObject.cpp
+++ b/Source/SceneEntities/Objects/imstkSPHObject.cpp
@@ -24,18 +24,6 @@
 
 namespace imstk
 {
-SPHObject::SPHObject(const std::string& name) : DynamicObject(name)
-{
-    this->m_type = Type::SPH;
-}
-
-std::shared_ptr<SPHModel>
-SPHObject::getDynamicalSPHModel()
-{
-    m_SPHModel = std::dynamic_pointer_cast<SPHModel>(m_dynamicalModel);
-    return m_SPHModel;
-}
-
 bool
 SPHObject::initialize()
 {
diff --git a/Source/SceneEntities/Objects/imstkSPHObject.h b/Source/SceneEntities/Objects/imstkSPHObject.h
index 99d71291f0787dbe80a2dc293dbdfd4d2ef55977..89882e32779f482d21dbb5744cc9288eee0ea38e 100644
--- a/Source/SceneEntities/Objects/imstkSPHObject.h
+++ b/Source/SceneEntities/Objects/imstkSPHObject.h
@@ -36,18 +36,17 @@ class SPHModel;
 class SPHObject : public DynamicObject
 {
 public:
-    explicit SPHObject(const std::string& name);
-
+    SPHObject(const std::string& name) : DynamicObject(name) { }
     virtual ~SPHObject() override = default;
 
 public:
+    virtual const std::string getTypeName() const override { return "SPHObject"; }
+
     ///
-    /// \brief Get the SPH model of the object
+    /// \brief Get the model governing the SPH fluid dynamics of this object
     ///
     std::shared_ptr<SPHModel> getSPHModel();
 
-    std::shared_ptr<SPHModel> getDynamicalSPHModel();
-
     ///
     /// \brief Initialize the SPH scene object
     ///
diff --git a/Source/SceneEntities/Objects/imstkSceneObject.cpp b/Source/SceneEntities/Objects/imstkSceneObject.cpp
index 128322bfd0a08d1562581f086d5ce9c7a6093b04..d2863ea9371cd4e919519da776f62f04d6bb2505 100644
--- a/Source/SceneEntities/Objects/imstkSceneObject.cpp
+++ b/Source/SceneEntities/Objects/imstkSceneObject.cpp
@@ -28,9 +28,10 @@
 
 namespace imstk
 {
-SceneObject::SceneObject(const std::string& name) : SceneEntity(),
-    m_type(Type::Visual), m_name(name),
-    m_taskGraph(std::make_shared<TaskGraph>("SceneObject_" + name + "_Source", "SceneObject_" + name + "_Sink"))
+SceneObject::SceneObject(const std::string& name) : SceneEntity(), m_name(name),
+    m_taskGraph(std::make_shared<TaskGraph>(
+        "SceneObject_" + name + "_Source",
+        "SceneObject_" + name + "_Sink"))
 {
     m_updateNode = m_taskGraph->addFunction("SceneObject_" + name + "_Update", std::bind(&SceneObject::update, this));
     m_updateGeometryNode = m_taskGraph->addFunction("SceneObject_" + name + "_UpdateGeometry", std::bind(&SceneObject::updateGeometries, this));
diff --git a/Source/SceneEntities/Objects/imstkSceneObject.h b/Source/SceneEntities/Objects/imstkSceneObject.h
index 0d058681bac5c43aa3a297d87b8931838644b4d5..5591abe961b6030a37e7d7450f286685fa5ee3b8 100644
--- a/Source/SceneEntities/Objects/imstkSceneObject.h
+++ b/Source/SceneEntities/Objects/imstkSceneObject.h
@@ -24,7 +24,6 @@
 #include "imstkSceneEntity.h"
 
 #include <memory>
-#include <string>
 #include <vector>
 
 namespace imstk
@@ -44,36 +43,14 @@ class TaskNode;
 class SceneObject : public SceneEntity
 {
 public:
-    enum class Type
-    {
-        Visual,
-        Animation,
-        Colliding,
-        Rigid,
-        Rigid2,
-        FEMDeformable,
-        ReducedFEMDeformable,
-        Pbd,
-        SPH,
-        Physiology,
-        LevelSetDeformable
-    };
-
-    ///
-    /// \brief Constructor
-    ///
-    explicit SceneObject(const std::string& name);
-
-    ///
-    /// \brief Destructor
-    ///
+    SceneObject(const std::string& name);
     virtual ~SceneObject() override = default;
 
 public:
     ///
     /// \brief Get the type of the object
     ///
-    const Type& getType() const { return m_type; }
+    virtual const std::string getTypeName() const { return "SceneObject"; }
 
     ///
     /// \brief Get the computational graph
@@ -157,7 +134,6 @@ protected:
     virtual void initGraphEdges(std::shared_ptr<TaskNode> source, std::shared_ptr<TaskNode> sink);
 
 protected:
-    Type m_type;                                              ///> Type of the scene object
     std::string m_name;                                       ///> Custom name of the scene object
     std::vector<std::shared_ptr<VisualModel>> m_visualModels; ///> Visual objects for rendering
     std::shared_ptr<TaskGraph> m_taskGraph = nullptr;         ///> Computational Graph
@@ -167,6 +143,4 @@ private:
     std::shared_ptr<TaskNode> m_updateNode = nullptr;
     std::shared_ptr<TaskNode> m_updateGeometryNode = nullptr;
 };
-
-using VisualObject = SceneObject;
 } // imstk
diff --git a/Source/SceneEntities/imstkSceneEntity.h b/Source/SceneEntities/imstkSceneEntity.h
index 625737f212c6c71082960648362b767437fee8a3..9b6179a8445440508035a98625af24ffc0006e52 100644
--- a/Source/SceneEntities/imstkSceneEntity.h
+++ b/Source/SceneEntities/imstkSceneEntity.h
@@ -22,6 +22,7 @@
 #pragma once
 
 #include <atomic>
+#include <string>
 
 namespace imstk
 {
@@ -36,16 +37,16 @@ class SceneEntity
 public:
     virtual ~SceneEntity() = default;
 
+public:
     ///
     /// \brief Get ID (ALWAYS query the ID in your code, DO NOT hardcode it)
     /// \returns ID of entity
     ///
     EntityID getID() const;
 
+    virtual const std::string getTypeName() const = 0;
+
 protected:
-    ///
-    /// \brief Constructor
-    ///
     SceneEntity();
 
     // Not the best design pattern
diff --git a/Source/apiUtilities/imstkAPIUtilities.cpp b/Source/apiUtilities/imstkAPIUtilities.cpp
index bd9c113fcaada05241541e8d534a3f0789b02616..c3642136038b77c8231bb7e53adfdaa4cec8ecc2 100644
--- a/Source/apiUtilities/imstkAPIUtilities.cpp
+++ b/Source/apiUtilities/imstkAPIUtilities.cpp
@@ -47,7 +47,7 @@ namespace apiutils
 ///
 /// \brief Create a analytical visual scene object that and add it to the scene
 ///
-std::shared_ptr<VisualObject>
+std::shared_ptr<SceneObject>
 createVisualAnalyticalSceneObject(Geometry::Type         type,
                                   std::shared_ptr<Scene> scene,
                                   const std::string&     objName,
@@ -88,7 +88,7 @@ createVisualAnalyticalSceneObject(Geometry::Type         type,
     geom->scale(scale, Geometry::TransformType::ApplyToData);
     geom->translate(t, Geometry::TransformType::ApplyToData);
 
-    auto sceneObj = std::make_shared<VisualObject>(objName);
+    auto sceneObj = std::make_shared<SceneObject>(objName);
     sceneObj->setVisualGeometry(geom);
     scene->addSceneObject(sceneObj);
 
@@ -154,7 +154,7 @@ createAndAddVisualSceneObject(std::shared_ptr<Scene> scene,
     auto SurfaceMesh = std::dynamic_pointer_cast<imstk::SurfaceMesh>(mesh);
 
     // Create object and add to scene
-    auto meshSceneObject = std::make_shared<VisualObject>("meshObject");
+    auto meshSceneObject = std::make_shared<SceneObject>("meshObject");
     meshSceneObject->setVisualGeometry(SurfaceMesh);
     meshSceneObject->setName(objectName);
     scene->addSceneObject(meshSceneObject);