iMSTK
Interactive Medical Simulation Toolkit
imstkCollisionDataDebugModel.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 "imstkCollisionDataDebugModel.h"
8 #include "imstkLineMesh.h"
9 #include "imstkSurfaceMesh.h"
10 #include "imstkVecDataArray.h"
11 
12 namespace imstk
13 {
14 void
15 CollisionDataDebugModel::addCollisionElement(std::shared_ptr<PointSet> pointSet, const CollisionElement& elem)
16 {
18  VecDataArray<double, 3>& vertices = dummy;
19  if (pointSet != nullptr)
20  {
21  vertices = *pointSet->getVertexPositions();
22  }
23  if (elem.m_type == CollisionElementType::CellIndex)
24  {
25  const int idCount = elem.m_element.m_CellIndexElement.idCount;
26  const CellTypeId type = elem.m_element.m_CellIndexElement.cellType;
27  if (type == IMSTK_VERTEX)
28  {
29  addPoint(vertices[elem.m_element.m_CellIndexElement.ids[0]]);
30  }
31  else if (type == IMSTK_EDGE)
32  {
33  Vec2i cell;
34  if (idCount == 1)
35  {
36  auto indices = std::dynamic_pointer_cast<LineMesh>(pointSet)->getCells();
37  cell = (*indices)[elem.m_element.m_CellIndexElement.ids[0]];
38  }
39  else
40  {
41  cell = Vec2i(
42  elem.m_element.m_CellIndexElement.ids[0],
43  elem.m_element.m_CellIndexElement.ids[1]);
44  }
45  addLine(vertices[cell[0]], vertices[cell[1]]);
46  }
47  else if (type == IMSTK_TRIANGLE)
48  {
49  Vec3i cell;
50  if (idCount == 1)
51  {
52  auto indices = std::dynamic_pointer_cast<SurfaceMesh>(pointSet)->getCells();
53  cell = (*indices)[elem.m_element.m_CellIndexElement.ids[0]];
54  }
55  else
56  {
57  cell = Vec3i(
58  elem.m_element.m_CellIndexElement.ids[0],
59  elem.m_element.m_CellIndexElement.ids[1],
60  elem.m_element.m_CellIndexElement.ids[2]);
61  }
62  addTriangle(vertices[cell[0]], vertices[cell[1]], vertices[cell[2]]);
63  }
64  // No visualizations for tetrahedrons
65  }
66  else if (elem.m_type == CollisionElementType::CellVertex)
67  {
68  const int vertexCount = elem.m_element.m_CellVertexElement.size;
69  if (vertexCount == 1)
70  {
71  addPoint(elem.m_element.m_CellVertexElement.pts[0]);
72  }
73  else if (vertexCount == 2)
74  {
75  addLine(
76  elem.m_element.m_CellVertexElement.pts[0],
77  elem.m_element.m_CellVertexElement.pts[1]);
78  }
79  else if (vertexCount == 3)
80  {
82  elem.m_element.m_CellVertexElement.pts[0],
83  elem.m_element.m_CellVertexElement.pts[1],
84  elem.m_element.m_CellVertexElement.pts[2]);
85  }
86  // No visualizations for tetrahedrons
87  }
88  else if (elem.m_type == CollisionElementType::PointIndexDirection)
89  {
90  addPoint(vertices[elem.m_element.m_PointIndexDirectionElement.ptIndex]);
91  addArrow(vertices[elem.m_element.m_PointIndexDirectionElement.ptIndex],
92  vertices[elem.m_element.m_PointIndexDirectionElement.ptIndex] +
93  elem.m_element.m_PointIndexDirectionElement.dir * elem.m_element.m_PointIndexDirectionElement.penetrationDepth);
94  }
95  else if (elem.m_type == CollisionElementType::PointDirection)
96  {
97  addPoint(elem.m_element.m_PointDirectionElement.pt);
98  addArrow(elem.m_element.m_PointDirectionElement.pt,
99  elem.m_element.m_PointDirectionElement.pt +
100  elem.m_element.m_PointDirectionElement.dir * elem.m_element.m_PointDirectionElement.penetrationDepth);
101  }
102 }
103 
104 void
106 {
107  if (elem.m_type == CollisionElementType::CellVertex)
108  {
109  const int vertexCount = elem.m_element.m_CellVertexElement.size;
110  printf(" CellVertexElement\n");
111  printf(" # Vertices: %d\n", vertexCount);
112  for (int i = 0; i < vertexCount; i++)
113  {
114  printf(" ptIndex: (%f, %f, %f)\n",
115  elem.m_element.m_CellVertexElement.pts[i][0],
116  elem.m_element.m_CellVertexElement.pts[i][1],
117  elem.m_element.m_CellVertexElement.pts[i][2]);
118  }
119  }
120  else if (elem.m_type == CollisionElementType::CellIndex)
121  {
122  printf(" CellIndexElement\n");
123  printf(" Cell Type: %d\n", elem.m_element.m_CellIndexElement.cellType);
124  printf(" # ids: %d\n", elem.m_element.m_CellIndexElement.idCount);
125  for (int i = 0; i < elem.m_element.m_CellIndexElement.idCount; i++)
126  {
127  printf(" Cell Index: %d\n", elem.m_element.m_CellIndexElement.ids[i]);
128  }
129  }
130  else if (elem.m_type == CollisionElementType::PointDirection)
131  {
132  printf(" PointDirectionElement\n");
133  printf(" pt: (%f, %f, %f)\n",
134  elem.m_element.m_PointDirectionElement.pt[0],
135  elem.m_element.m_PointDirectionElement.pt[1],
136  elem.m_element.m_PointDirectionElement.pt[2]);
137  printf(" dir: (%f, %f, %f)\n",
138  elem.m_element.m_PointDirectionElement.dir[0],
139  elem.m_element.m_PointDirectionElement.dir[1],
140  elem.m_element.m_PointDirectionElement.dir[2]);
141  printf(" penetrationDepth: %f\n", elem.m_element.m_PointDirectionElement.penetrationDepth);
142  }
143  else if (elem.m_type == CollisionElementType::PointIndexDirection)
144  {
145  printf(" PointIndexDirectionElement\n");
146  printf(" ptIndex: %d\n", elem.m_element.m_PointIndexDirectionElement.ptIndex);
147  printf(" dir: (%f, %f, %f)\n",
148  elem.m_element.m_PointIndexDirectionElement.dir[0],
149  elem.m_element.m_PointIndexDirectionElement.dir[1],
150  elem.m_element.m_PointIndexDirectionElement.dir[2]);
151  printf(" penetrationDepth: %f\n", elem.m_element.m_PointIndexDirectionElement.penetrationDepth);
152  }
153 }
154 
155 void
157 {
158  if (m_cdData == nullptr)
159  {
160  return;
161  }
162 
163  if (m_printContacts)
164  {
165  printf("# A Contacts: %d\n", static_cast<int>(m_cdData->elementsA.size()));
166  printf("# B Contacts: %d\n", static_cast<int>(m_cdData->elementsB.size()));
167  }
168 
169  // Clear the debug object geometry
170  if (m_frameCounter >= m_clearRate)
171  {
172  clear();
173  m_frameCounter = 0;
174  }
175 
176  std::shared_ptr<PointSet> pointSetA = std::dynamic_pointer_cast<PointSet>(m_cdData->geomA);
177  for (int i = 0; i < static_cast<int>(m_cdData->elementsA.size()); i++)
178  {
179  const CollisionElement& elem = m_cdData->elementsA[i];
180  addCollisionElement(pointSetA, elem);
181  if (m_printContacts)
182  {
183  printf("Contact A %d\n", i);
184  printContactInfo(elem);
185  }
186  }
187  std::shared_ptr<PointSet> pointSetB = std::dynamic_pointer_cast<PointSet>(m_cdData->geomB);
188  for (int i = 0; i < static_cast<int>(m_cdData->elementsB.size()); i++)
189  {
190  const CollisionElement& elem = m_cdData->elementsB[i];
191  addCollisionElement(pointSetB, elem);
192  if (m_printContacts)
193  {
194  printf("Contact B %d\n", i);
195  printContactInfo(elem);
196  }
197  }
198 
199  if (m_countEmptyFrames)
200  {
201  m_frameCounter++;
202  }
203  else
204  {
205  if ((m_cdData->elementsA.size() > 0 || m_cdData->elementsB.size() > 0))
206  {
207  m_frameCounter++;
208  }
209  }
210 }
211 } // namespace imstk
Base class for all geometries represented by discrete points and elements The pointsets follow a pipe...
Definition: imstkPointSet.h:25
void addTriangle(const Vec3d &a, const Vec3d &b, const Vec3d &c)
Adds a triangle to the debug triangles with default color.
void debugUpdate()
Updates visual representation to the current cd (we don&#39;t use the built in update as its useful to ca...
void addPoint(const Vec3d &a)
Adds a point to the debug points.
Compound Geometry.
void addLine(const Vec3d &a, const Vec3d &b)
Adds a line to the debug lines with default color.
Union of collision elements. We use a union to avoid polymorphism. There may be many elements and acc...
void addCollisionElement(std::shared_ptr< PointSet > pointSet, const CollisionElement &elem)
Append visual representation to the debug meshes for the given contact and geometry.
Base class for all volume mesh types.
Definition: imstkLineMesh.h:18
Represents a set of triangles & vertices via an array of Vec3d double vertices & Vec3i integer indice...
void addArrow(const Vec3d &start, const Vec3d &end)
Adds an arrow to the debug arrows.
void printContactInfo(const CollisionElement &elem)
Print the contact information.
void clear()
Clears all primitives.