diff --git a/Examples/PBD/PBDCollisionMultipleObjects/PBDCollisionMultipleObjectsExample.cpp b/Examples/PBD/PBDCollisionMultipleObjects/PBDCollisionMultipleObjectsExample.cpp
index 0eae3a916f912be62ac1c07e7590cbd33fe64727..3011315c23af84fe2b9e46340bcb0301380b2fbe 100644
--- a/Examples/PBD/PBDCollisionMultipleObjects/PBDCollisionMultipleObjectsExample.cpp
+++ b/Examples/PBD/PBDCollisionMultipleObjects/PBDCollisionMultipleObjectsExample.cpp
@@ -26,6 +26,7 @@
 #include "imstkObjectInteractionFactory.h"
 #include "imstkOneToOneMap.h"
 #include "imstkPbdModel.h"
+#include "imstkPbdObject.h"
 #include "imstkScene.h"
 #include "imstkSimulationManager.h"
 #include "imstkSurfaceMesh.h"
diff --git a/Examples/PBD/PBDCollisionOneObject/PBDCollisionOneObjectExample.cpp b/Examples/PBD/PBDCollisionOneObject/PBDCollisionOneObjectExample.cpp
index e88fe1ca8ca58cf65e3b762725e68e921ca22f16..0e39f97bf68c5321d47426158c6865ddd86af3b5 100644
--- a/Examples/PBD/PBDCollisionOneObject/PBDCollisionOneObjectExample.cpp
+++ b/Examples/PBD/PBDCollisionOneObject/PBDCollisionOneObjectExample.cpp
@@ -26,6 +26,7 @@
 #include "imstkObjectInteractionFactory.h"
 #include "imstkOneToOneMap.h"
 #include "imstkPbdModel.h"
+#include "imstkPbdObject.h"
 #include "imstkScene.h"
 #include "imstkSimulationManager.h"
 #include "imstkSurfaceMesh.h"
diff --git a/Examples/SPHFluid/SPHFluidExample.hpp b/Examples/SPHFluid/SPHFluidExample.hpp
index bb4315dcf3064e6b65a62a211b1302992161a782..25a0a853c49ac84cb43d95f7b973e283da7eae6a 100644
--- a/Examples/SPHFluid/SPHFluidExample.hpp
+++ b/Examples/SPHFluid/SPHFluidExample.hpp
@@ -32,6 +32,7 @@
 #include "imstkSceneManager.h"
 #include "imstkCamera.h"
 #include "imstkObjectInteractionFactory.h"
+#include "imstkCollisionDetection.h"
 
 #include "Fluid.hpp"
 #include "Solid.hpp"
diff --git a/Source/Scene/imstkObjectInteractionFactory.cpp b/Source/Scene/imstkObjectInteractionFactory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7a120051a7c3b5c0487bdd5f42c9d00039ef8124
--- /dev/null
+++ b/Source/Scene/imstkObjectInteractionFactory.cpp
@@ -0,0 +1,114 @@
+/*=========================================================================
+
+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 "imstkObjectInteractionFactory.h"
+#include "imstkBoneDrillingCH.h"
+#include "imstkCDObjectFactory.h"
+#include "imstkCollidingObject.h"
+#include "imstkCollisionData.h"
+#include "imstkCollisionDetection.h"
+#include "imstkDeformableObject.h"
+#include "imstkLogger.h"
+#include "imstkPbdObject.h"
+#include "imstkPbdObjectCollisionPair.h"
+#include "imstkPenaltyCH.h"
+#include "imstkPickingCH.h"
+#include "imstkSPHCollisionHandling.h"
+#include "imstkSPHObject.h"
+
+namespace imstk
+{
+// Cast type check
+template<typename ObjectType>
+static bool isType(std::shared_ptr<SceneObject> obj)
+{
+    return std::dynamic_pointer_cast<ObjectType>(obj) != nullptr;
+}
+
+std::shared_ptr<ObjectInteractionPair>
+makeObjectInteractionPair(std::shared_ptr<CollidingObject> obj1, std::shared_ptr<CollidingObject> obj2,
+    InteractionType intType, CollisionDetection::Type cdType)
+{
+    std::shared_ptr<ObjectInteractionPair> results = nullptr;
+    if (intType == InteractionType::PbdObjToPbdObjCollision && isType<PbdObject>(obj1) && isType<PbdObject>(obj2))
+    {
+        results = std::make_shared<PbdObjectCollisionPair>(std::dynamic_pointer_cast<PbdObject>(obj1), std::dynamic_pointer_cast<PbdObject>(obj2), cdType);
+    }
+    //else if (intType == InteractionType::PbdObjToCollidingObjCollision && isType<PbdObject>(obj1))
+    //{
+    //    results = std::make_shared<PbdCollidingObjCollisionPair>(
+    //        std::dynamic_pointer_cast<PbdObject>(obj1),
+    //        std::dynamic_pointer_cast<PbdObject>(obj2), cdType);
+    //}
+    else if (intType == InteractionType::SphObjToCollidingObjCollision && isType<SPHObject>(obj1))
+    {
+        // Setup CD, and collision data
+        std::shared_ptr<CollisionData>      colData   = std::make_shared<CollisionData>();
+        std::shared_ptr<CollisionDetection> colDetect = makeCollisionDetectionObject(cdType, obj1->getCollidingGeometry(), obj2->getCollidingGeometry(), colData);
+
+        // Setup the handler
+        std::shared_ptr<SPHCollisionHandling> colHandler =
+            std::make_shared<SPHCollisionHandling>(CollisionHandling::Side::A, colData, std::dynamic_pointer_cast<SPHObject>(obj1));
+
+        results = std::make_shared<CollisionPair>(obj1, obj2, colDetect, colHandler, nullptr);
+    }
+    else if (intType == InteractionType::FemObjToCollidingObjNodalPicking && isType<FeDeformableObject>(obj1))
+    {
+        // Setup CD, and collision data
+        std::shared_ptr<CollisionData>      colData   = std::make_shared<CollisionData>();
+        std::shared_ptr<CollisionDetection> colDetect = makeCollisionDetectionObject(cdType, obj1->getCollidingGeometry(), obj2->getCollidingGeometry(), colData);
+
+        // Setup the handler
+        std::shared_ptr<PickingCH> colHandler =
+            std::make_shared<PickingCH>(CollisionHandling::Side::A, colData, std::dynamic_pointer_cast<FeDeformableObject>(obj1));
+
+        results = std::make_shared<CollisionPair>(obj1, obj2, colDetect, colHandler, nullptr);
+    }
+    else if (intType == InteractionType::FemObjToCollidingObjPenaltyForce && isType<FeDeformableObject>(obj1))
+    {
+        // Setup CD, and collision data
+        std::shared_ptr<CollisionData>      colData   = std::make_shared<CollisionData>();
+        std::shared_ptr<CollisionDetection> colDetect = makeCollisionDetectionObject(cdType, obj1->getCollidingGeometry(), obj2->getCollidingGeometry(), colData);
+
+        // Setup the handler
+        std::shared_ptr<PenaltyCH> colHandler =
+            std::make_shared<PenaltyCH>(CollisionHandling::Side::A, colData, obj1);
+    }
+    else if (intType == InteractionType::FemObjToCollidingObjBoneDrilling && isType<FeDeformableObject>(obj1))
+    {
+        // Setup CD, and collision data
+        std::shared_ptr<CollisionData>      colData   = std::make_shared<CollisionData>();
+        std::shared_ptr<CollisionDetection> colDetect = makeCollisionDetectionObject(cdType, obj1->getCollidingGeometry(), obj2->getCollidingGeometry(), colData);
+
+        // Setup the handler
+        std::shared_ptr<BoneDrillingCH> colHandler =
+            std::make_shared<BoneDrillingCH>(CollisionHandling::Side::A, colData, obj1, obj2);
+
+        results = std::make_shared<CollisionPair>(obj1, obj2, colDetect, colHandler, nullptr);
+    }
+
+    if (results == nullptr)
+    {
+        LOG(WARNING) << "Invalid SceneObjects for requested interaction.";
+    }
+    return results;
+}
+}
\ No newline at end of file
diff --git a/Source/Scene/imstkObjectInteractionFactory.h b/Source/Scene/imstkObjectInteractionFactory.h
index 8ae8a562d1c87c5fe79a99579c78092c2ac9c31e..4fcbb2ec6eb1774b32026e607cb643ebb0095559 100644
--- a/Source/Scene/imstkObjectInteractionFactory.h
+++ b/Source/Scene/imstkObjectInteractionFactory.h
@@ -21,25 +21,13 @@ limitations under the License.
 
 #pragma once
 
-#include "imstkObjectInteractionFactory.h"
-#include "imstkBoneDrillingCH.h"
-#include "imstkCDObjectFactory.h"
-#include "imstkCollidingObject.h"
-#include "imstkCollisionData.h"
 #include "imstkCollisionDetection.h"
-#include "imstkDeformableObject.h"
-#include "imstkLogger.h"
-#include "imstkPbdObject.h"
-#include "imstkPbdObjectCollisionPair.h"
-#include "imstkPenaltyCH.h"
-#include "imstkPickingCH.h"
-#include "imstkSPHCollisionHandling.h"
-#include "imstkSPHObject.h"
-
-#include <memory>
+#include "imstkObjectInteractionPair.h"
 
 namespace imstk
 {
+class CollidingObject;
+
 // Predefined standard/types of interaction from imstk
 enum class InteractionType
 {
@@ -58,104 +46,9 @@ enum class InteractionType
 };
 
 ///
-/// \brief Factory for InteractionPairs
+/// \brief Factory for InteractionPairs, returns nullptr and logs warning if failed
 ///
-template<typename ObjectType1, typename ObjectType2>
 extern std::shared_ptr<ObjectInteractionPair>
-makeObjectInteractionPair(
-    std::shared_ptr<ObjectType1> obj1, std::shared_ptr<ObjectType2> obj2,
-    InteractionType intType, CollisionDetection::Type cdType)
-{
-    std::shared_ptr<ObjectInteractionPair> results = nullptr;
-    if (intType == InteractionType::PbdObjToPbdObjCollision)
-    {
-        if (std::is_base_of<PbdObject, ObjectType1>::value
-            && std::is_base_of<PbdObject, ObjectType2>::value)
-        {
-            results = std::make_shared<PbdObjectCollisionPair>(
-                std::dynamic_pointer_cast<PbdObject>(obj1),
-                std::dynamic_pointer_cast<PbdObject>(obj2), cdType);
-        }
-    }
-    /*else if (intType == InteractionType::PbdObjToCollidingObj_Collision)
-    {
-        if (std::is_base_of<PbdObject, ObjectType1>::value &&
-            std::is_base_of<CollidingObject, ObjectType2>::value)
-        {
-            results = std::make_shared<PbdCollidingObjCollisionPair>(
-                std::dynamic_pointer_cast<PbdObject>(obj1),
-                std::dynamic_pointer_cast<PbdObject>(obj2), cdType);
-        }
-    }*/
-    else if (intType == InteractionType::SphObjToCollidingObjCollision)
-    {
-        if (std::is_base_of<SPHObject, ObjectType1>::value
-            && std::is_base_of<CollidingObject, ObjectType2>::value)
-        {
-            // Setup CD, and collision data
-            std::shared_ptr<CollisionData>      colData   = std::make_shared<CollisionData>();
-            std::shared_ptr<CollisionDetection> colDetect = makeCollisionDetectionObject(cdType, obj1->getCollidingGeometry(), obj2->getCollidingGeometry(), colData);
-
-            // Setup the handler
-            std::shared_ptr<SPHCollisionHandling> colHandler =
-                std::make_shared<SPHCollisionHandling>(CollisionHandling::Side::A, colData, std::dynamic_pointer_cast<SPHObject>(obj1));
-
-            results = std::make_shared<CollisionPair>(obj1, obj2, colDetect, colHandler, nullptr);
-        }
-    }
-    else if (intType == InteractionType::FemObjToCollidingObjNodalPicking)
-    {
-        if (std::is_base_of<FeDeformableObject, ObjectType1>::value
-            && std::is_base_of<CollidingObject, ObjectType2>::value)
-        {
-            // Setup CD, and collision data
-            std::shared_ptr<CollisionData>      colData   = std::make_shared<CollisionData>();
-            std::shared_ptr<CollisionDetection> colDetect = makeCollisionDetectionObject(cdType, obj1->getCollidingGeometry(), obj2->getCollidingGeometry(), colData);
-
-            // Setup the handler
-            std::shared_ptr<PickingCH> colHandler =
-                std::make_shared<PickingCH>(CollisionHandling::Side::A, colData, std::dynamic_pointer_cast<FeDeformableObject>(obj1));
-
-            results = std::make_shared<CollisionPair>(obj1, obj2, colDetect, colHandler, nullptr);
-        }
-    }
-    else if (intType == InteractionType::FemObjToCollidingObjPenaltyForce)
-    {
-        if ((std::is_base_of<CollidingObject, ObjectType1>::value)
-            && std::is_base_of<CollidingObject, ObjectType2>::value)
-        {
-            // Setup CD, and collision data
-            std::shared_ptr<CollisionData>      colData   = std::make_shared<CollisionData>();
-            std::shared_ptr<CollisionDetection> colDetect = makeCollisionDetectionObject(cdType, obj1->getCollidingGeometry(), obj2->getCollidingGeometry(), colData);
-
-            // Setup the handler
-            std::shared_ptr<PenaltyCH> colHandler =
-                std::make_shared<PenaltyCH>(CollisionHandling::Side::A, colData, obj1);
-
-            results = std::make_shared<CollisionPair>(obj1, obj2, colDetect, colHandler, nullptr);
-        }
-    }
-    else if (intType == InteractionType::FemObjToCollidingObjBoneDrilling)
-    {
-        if (std::is_base_of<FeDeformableObject, ObjectType1>::value
-            && std::is_base_of<CollidingObject, ObjectType2>::value)
-        {
-            // Setup CD, and collision data
-            std::shared_ptr<CollisionData>      colData   = std::make_shared<CollisionData>();
-            std::shared_ptr<CollisionDetection> colDetect = makeCollisionDetectionObject(cdType, obj1->getCollidingGeometry(), obj2->getCollidingGeometry(), colData);
-
-            // Setup the handler
-            std::shared_ptr<BoneDrillingCH> colHandler =
-                std::make_shared<BoneDrillingCH>(CollisionHandling::Side::A, colData, obj1, obj2);
-
-            results = std::make_shared<CollisionPair>(obj1, obj2, colDetect, colHandler, nullptr);
-        }
-    }
-
-    if (results == nullptr)
-    {
-        LOG(WARNING) << "Invalid SceneObjects for requested interaction.";
-    }
-    return results;
-}
+makeObjectInteractionPair(std::shared_ptr<CollidingObject> obj1, std::shared_ptr<CollidingObject> obj2,
+    InteractionType intType, CollisionDetection::Type cdType);
 }
\ No newline at end of file