iMSTK
Interactive Medical Simulation Toolkit
imstkBurnable.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 "imstkAbstractCellMesh.h"
8 #include "imstkBurnable.h"
9 #include "imstkCellMesh.h"
10 #include "imstkParallelUtils.h"
11 #include "imstkPbdConstraint.h"
12 #include "imstkPbdConstraintContainer.h"
13 #include "imstkPbdModel.h"
14 #include "imstkPbdObject.h"
15 #include "imstkPbdObjectCellRemoval.h"
16 #include "imstkPbdSolver.h"
17 #include "imstkTaskGraph.h"
18 #include "imstkTaskNode.h"
19 
20 namespace imstk
21 {
22 Burnable::Burnable(const std::string& name) : SceneBehaviour(false, name)
23 {
24 }
25 
26 void
28 {
29  m_burnableObject = std::dynamic_pointer_cast<PbdObject>(getEntity().lock());
30 
31  CHECK(m_burnableObject != nullptr) << "Burnable requires a input PBD object,"
32  "please add it on creation";
33 
34  if (!m_trackOnly)
35  {
36  // Create cell remover for removing torn cells
37  m_cellRemover = std::make_shared<PbdObjectCellRemoval>(m_burnableObject, m_updateType);
38  }
39 
40  // Allocate memory for mesh state and initialize values
41  auto cellMesh = std::dynamic_pointer_cast<AbstractCellMesh>(m_burnableObject->getPhysicsGeometry());
42  int numCells = cellMesh->getNumCells();
43 
44  m_burnDamagePtr = std::make_shared<DataArray<double>>(numCells);
45  m_burnVisualPtr = std::make_shared<DataArray<double>>(numCells);
46  // Initialize to zero
47  for (int i = 0; i < numCells; i++)
48  {
49  m_burnDamagePtr->at(i) = 0.0;
50  m_burnVisualPtr->at(i) = 0.0;
51  }
52 
53  cellMesh->setCellAttribute("BurnDamage", m_burnDamagePtr);
54  cellMesh->setCellAttribute("BurnVisual", m_burnVisualPtr);
55 }
56 
57 // Check state of mesh and delete cells that are burned away
58 void
59 Burnable::visualUpdate(const double& dt)
60 {
61  if (m_trackOnly)
62  {
63  return;
64  }
65 
66  // Check that the cellConstraintMap exists, if not make it
67  if (m_burnableObject->getPbdBody()->cellConstraintMap.empty())
68  {
69  m_burnableObject->computeCellConstraintMap();
70  }
71 
72  // Get body id
73  auto pbdBody = m_burnableObject->getPbdBody();
74 
75  // Mesh data
76  auto cellMesh = std::dynamic_pointer_cast<AbstractCellMesh>(m_burnableObject->getPhysicsGeometry());
77  auto cellVerts = std::dynamic_pointer_cast<DataArray<int>>(cellMesh->getAbstractCells()); // underlying 1D array
78  const int vertsPerCell = cellMesh->getAbstractCells()->getNumberOfComponents();
79 
80  // Mesh state data
81  auto burnStatePtr = std::dynamic_pointer_cast<DataArray<double>>(cellMesh->getCellAttribute("BurnDamage"));
82  DataArray<double>& burnState = *burnStatePtr;
83 
84  // Check if the cell is burned and remove if so
86  ParallelUtils::parallelFor(cellMesh->getNumCells(),
87  [&](const int cellId)
88  {
89  if (burnState[cellId] >= 1.0)
90  {
91  lock.lock();
92  m_cellRemover->removeCellOnApply(cellId);
93  pbdBody->cellConstraintMap.erase(cellId);
94  burnState[cellId] = 0.0;
95  lock.unlock();
96  }
97  }, cellMesh->getNumCells() > 50);
98 
99  m_cellRemover->apply();
100 }
101 } // namespace imstk
The SpinLock class.
Definition: imstkSpinLock.h:20
void unlock()
End a thread-safe region.
Definition: imstkSpinLock.h:53
virtual int getNumberOfComponents() const override
Returns the number of components.
Compound Geometry.
std::weak_ptr< Entity > getEntity() const
Get parent entity.
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
Base class for scene objects that move and/or deform under position based dynamics formulation...
void init() override
Initialize the component, called at a later time after all component construction is complete...
Simple dynamic array implementation that also supports event posting and viewing/facade.
Provides non templated base for cell based meshes.