iMSTK
Interactive Medical Simulation Toolkit
imstkPointSetToCylinderCD.cpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkPointSetToCylinderCD.h"
8 #include "imstkCylinder.h"
9 #include "imstkCollisionData.h"
10 #include "imstkCollisionUtils.h"
11 #include "imstkParallelUtils.h"
12 #include "imstkPointSet.h"
13 #include "imstkVecDataArray.h"
14 
15 namespace imstk
16 {
17 PointSetToCylinderCD::PointSetToCylinderCD()
18 {
19  setRequiredInputType<PointSet>(0);
20  setRequiredInputType<Cylinder>(1);
21 }
22 
23 void
25  std::shared_ptr<Geometry> geomA,
26  std::shared_ptr<Geometry> geomB,
27  std::vector<CollisionElement>& elementsA,
28  std::vector<CollisionElement>& elementsB)
29 {
30  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomA);
31  std::shared_ptr<Cylinder> cylinder = std::dynamic_pointer_cast<Cylinder>(geomB);
32 
33  const Vec3d cylinderPos = cylinder->getPosition();
34  const Vec3d cylinderAxis = cylinder->getOrientation().toRotationMatrix().col(1);
35  const double cylinderLength = cylinder->getLength();
36  const double cylinderRadius = cylinder->getRadius();
37 
38  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
39  const VecDataArray<double, 3>& vertices = *vertexData;
41  ParallelUtils::parallelFor(vertices.size(),
42  [&](const int idx)
43  {
44  Vec3d cylinderContactPt;
45  Vec3d cylinderContactNormal, pointContactNormal;
46  double depth;
47  if (CollisionUtils::testCylinderToPoint(
48  cylinderPos, cylinderAxis, cylinderLength, cylinderRadius,
49  vertices[idx],
50  cylinderContactPt, cylinderContactNormal, pointContactNormal, depth))
51  {
53  elemA.dir = pointContactNormal; // Direction to resolve pointset point
54  elemA.ptIndex = idx;
55  elemA.penetrationDepth = depth;
56 
58  elemB.dir = cylinderContactNormal; // Direction to resolve cylinder
59  elemB.pt = cylinderContactPt; // Contact point on surface of cylinder
60  elemB.penetrationDepth = depth;
61 
62  lock.lock();
63  elementsA.push_back(elemA);
64  elementsB.push_back(elemB);
65  lock.unlock();
66  }
67  }, vertices.size() > 100);
68 }
69 
70 void
72  std::shared_ptr<Geometry> geomA,
73  std::shared_ptr<Geometry> geomB,
74  std::vector<CollisionElement>& elementsA)
75 {
76  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomA);
77  std::shared_ptr<Cylinder> cylinder = std::dynamic_pointer_cast<Cylinder>(geomB);
78 
79  const Vec3d cylinderPos = cylinder->getPosition();
80  const Vec3d cylinderAxis = cylinder->getOrientation().toRotationMatrix().col(1);
81  const double cylinderLength = cylinder->getLength();
82  const double cylinderRadius = cylinder->getRadius();
83 
84  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
85  const VecDataArray<double, 3>& vertices = *vertexData;
87  ParallelUtils::parallelFor(vertices.size(),
88  [&](const int idx)
89  {
90  Vec3d cylinderContactPt;
91  Vec3d cylinderContactNormal, pointContactNormal;
92  double depth;
93  if (CollisionUtils::testCylinderToPoint(
94  cylinderPos, cylinderAxis, cylinderLength, cylinderRadius,
95  vertices[idx],
96  cylinderContactPt, cylinderContactNormal, pointContactNormal, depth))
97  {
99  elemA.dir = pointContactNormal; // Direction to resolve pointset point
100  elemA.ptIndex = idx;
101  elemA.penetrationDepth = depth;
102 
103  lock.lock();
104  elementsA.push_back(elemA);
105  lock.unlock();
106  }
107  }, vertices.size() > 100);
108 }
109 
110 void
112  std::shared_ptr<Geometry> geomA,
113  std::shared_ptr<Geometry> geomB,
114  std::vector<CollisionElement>& elementsB)
115 {
116  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomA);
117  std::shared_ptr<Cylinder> cylinder = std::dynamic_pointer_cast<Cylinder>(geomB);
118 
119  const Vec3d cylinderPos = cylinder->getPosition();
120  const Vec3d cylinderAxis = cylinder->getOrientation().toRotationMatrix().col(1);
121  const double cylinderLength = cylinder->getLength();
122  const double cylinderRadius = cylinder->getRadius();
123 
124  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
125  const VecDataArray<double, 3>& vertices = *vertexData;
127  ParallelUtils::parallelFor(vertices.size(),
128  [&](const int idx)
129  {
130  Vec3d cylinderContactPt;
131  Vec3d cylinderContactNormal, pointContactNormal;
132  double depth;
133  if (CollisionUtils::testCylinderToPoint(
134  cylinderPos, cylinderAxis, cylinderLength, cylinderRadius,
135  vertices[idx],
136  cylinderContactPt, cylinderContactNormal, pointContactNormal, depth))
137  {
138  PointDirectionElement elemB;
139  elemB.dir = cylinderContactNormal; // Direction to resolve cylinder
140  elemB.pt = cylinderContactPt; // Contact point on surface of cylinder
141  elemB.penetrationDepth = depth;
142 
143  lock.lock();
144  elementsB.push_back(elemB);
145  lock.unlock();
146  }
147  }, vertices.size() > 100);
148 }
149 } // namespace imstk
The SpinLock class.
Definition: imstkSpinLock.h:20
void unlock()
End a thread-safe region.
Definition: imstkSpinLock.h:53
Base class for all geometries represented by discrete points and elements The pointsets follow a pipe...
Definition: imstkPointSet.h:25
Cylinder geometry, default configuration is at origin with length running up the y axes...
Definition: imstkCylinder.h:19
Vec3d getPosition(DataType type=DataType::PostTransform)
Get the local or global position (post transformed)
Compound Geometry.
virtual void computeCollisionDataAB(std::shared_ptr< Geometry > geomA, std::shared_ptr< Geometry > geomB, std::vector< CollisionElement > &elementsA, std::vector< CollisionElement > &elementsB) override
Compute collision data for AB simultaneously.
void lock()
Start a thread-safe region, where only one thread can execute at a time until a call to the unlock fu...
Definition: imstkSpinLock.h:45
virtual void computeCollisionDataA(std::shared_ptr< Geometry > geomA, std::shared_ptr< Geometry > geomB, std::vector< CollisionElement > &elementsA) override
Compute collision data for side A.
virtual void computeCollisionDataB(std::shared_ptr< Geometry > geomA, std::shared_ptr< Geometry > geomB, std::vector< CollisionElement > &elementsB) override
Compute collision data for side B.
Direclty gives a point-direction contact as its collision data, point given by index.
Direclty gives a point-direction contact as its collision data.