iMSTK
Interactive Medical Simulation Toolkit
imstkPointSetToPlaneCD.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 "imstkPointSetToPlaneCD.h"
8 #include "imstkCollisionData.h"
9 #include "imstkCollisionUtils.h"
10 #include "imstkParallelUtils.h"
11 #include "imstkPlane.h"
12 #include "imstkPointSet.h"
13 #include "imstkVecDataArray.h"
14 
15 namespace imstk
16 {
17 PointSetToPlaneCD::PointSetToPlaneCD()
18 {
19  setRequiredInputType<PointSet>(0);
20  setRequiredInputType<Plane>(1);
21 
22  // By default plane cd is not generated
23  setGenerateCD(true, false);
24 }
25 
26 void
28  std::shared_ptr<Geometry> geomA,
29  std::shared_ptr<Geometry> geomB,
30  std::vector<CollisionElement>& elementsA,
31  std::vector<CollisionElement>& elementsB)
32 {
33  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomA);
34  std::shared_ptr<Plane> plane = std::dynamic_pointer_cast<Plane>(geomB);
35 
36  const Vec3d planePt = plane->getPosition();
37  const Vec3d planeNormal = plane->getNormal();
38 
39  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
40  const VecDataArray<double, 3>& vertices = *vertexData;
42  ParallelUtils::parallelFor(static_cast<unsigned int>(vertices.size()),
43  [&](const unsigned int idx)
44  {
45  Vec3d contactPt, contactNormal;
46  double depth;
47 
48  if (CollisionUtils::testPlaneToPoint(
49  planePt, planeNormal, vertices[idx],
50  contactPt, contactNormal, depth))
51  {
53  elemA.dir = planeNormal; // Direction to resolve pointset point to
54  elemA.ptIndex = idx; // Point on pointset
55  elemA.penetrationDepth = depth;
56 
58  elemB.dir = -planeNormal; // Direction to resolve plane
59  elemB.pt = vertices[idx] + planeNormal * depth; // Point on plane
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<Plane> plane = std::dynamic_pointer_cast<Plane>(geomB);
78 
79  const Vec3d planePt = plane->getPosition();
80  const Vec3d planeNormal = plane->getNormal();
81 
82  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
83  const VecDataArray<double, 3>& vertices = *vertexData;
85  ParallelUtils::parallelFor(static_cast<unsigned int>(vertices.size()),
86  [&](const unsigned int idx)
87  {
88  Vec3d contactPt, contactNormal;
89  double depth;
90 
91  if (CollisionUtils::testPlaneToPoint(
92  planePt, planeNormal, vertices[idx],
93  contactPt, contactNormal, depth))
94  {
96  elemA.dir = planeNormal; // Direction to resolve pointset point
97  elemA.ptIndex = idx;
98  elemA.penetrationDepth = depth;
99 
100  lock.lock();
101  elementsA.push_back(elemA);
102  lock.unlock();
103  }
104  }, vertices.size() > 100);
105 }
106 
107 void
109  std::shared_ptr<Geometry> geomA,
110  std::shared_ptr<Geometry> geomB,
111  std::vector<CollisionElement>& elementsB)
112 {
113  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomA);
114  std::shared_ptr<Plane> plane = std::dynamic_pointer_cast<Plane>(geomB);
115 
116  const Vec3d planePt = plane->getPosition();
117  const Vec3d planeNormal = plane->getNormal();
118 
119  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
120  const VecDataArray<double, 3>& vertices = *vertexData;
122  ParallelUtils::parallelFor(static_cast<unsigned int>(vertices.size()),
123  [&](const unsigned int idx)
124  {
125  Vec3d contactPt, contactNormal;
126  double depth;
127 
128  if (CollisionUtils::testPlaneToPoint(
129  planePt, planeNormal, vertices[idx],
130  contactPt, contactNormal, depth))
131  {
132  PointDirectionElement elemB;
133  elemB.dir = -planeNormal; // Direction to resolve plane
134  elemB.pt = vertices[idx] + planeNormal * depth; // Point on plane
135  elemB.penetrationDepth = depth;
136 
137  lock.lock();
138  elementsB.push_back(elemB);
139  lock.unlock();
140  }
141  }, vertices.size() > 100);
142 }
143 } // 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
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 computeCollisionDataB(std::shared_ptr< Geometry > geomA, std::shared_ptr< Geometry > geomB, std::vector< CollisionElement > &elementsB) override
Compute collision data for side B.
void setGenerateCD(const bool generateA, const bool generateB)
If generateA is false, CD data will not be generated for input0,A Similarly, if generateB is false...
Vec3d getPosition(DataType type=DataType::PostTransform)
Get the local or global position (post transformed)
Represents and infinite plane, width can be used for visual purposes.
Definition: imstkPlane.h:19
Compound Geometry.
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
Direclty gives a point-direction contact as its collision data, point given by index.
void computeCollisionDataA(std::shared_ptr< Geometry > geomA, std::shared_ptr< Geometry > geomB, std::vector< CollisionElement > &elementsA) override
Compute collision data for side A.
Direclty gives a point-direction contact as its collision data.