Libs/Optimize/ParticleSystem.h
Namespaces
| Name | 
|---|
| shapeworks  User usage reporting (telemetry)  | 
Classes
| Name | |
|---|---|
| class | shapeworks::ParticleSystem  A facade class managing interactions with a particle system.  | 
Source code
#pragma once
#include <map>
#include <random>
#include <vector>
#include "Libs/Optimize/Container/GenericContainer.h"
#include "Libs/Optimize/Domain/ParticleDomain.h"
#include "Libs/Optimize/Neighborhood/ParticleNeighborhood.h"
#include "Observer.h"
#include "ParticleEvents.h"
#include "itkCommand.h"
#include "itkDataObject.h"
#include "itkEventObject.h"
#include "itkObjectFactory.h"
#include "itkPoint.h"
#include "itkWeakPointer.h"
#include "vnl/vnl_inverse.h"
#include "vnl/vnl_matrix_fixed.h"
#include "vnl/vnl_vector_fixed.h"
namespace shapeworks {
class ParticleSystem : public itk::DataObject {
 public:
  static constexpr int VDimension = 3;
  typedef ParticleSystem Self;
  typedef DataObject Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;
  typedef itk::WeakPointer<const Self> ConstWeakPointer;
  itkNewMacro(Self);
  itkTypeMacro(ParticleSystem, itk::DataObject);
  itkStaticConstMacro(Dimension, unsigned int, VDimension);
  using DomainType = shapeworks::ParticleDomain;
  typedef itk::Point<double, VDimension> PointType;
  typedef ParticleNeighborhood NeighborhoodType;
  typedef GenericContainer<PointType> PointContainerType;
  typedef NeighborhoodType::PointVectorType PointVectorType;
  //  typedef Transform<double, VDimension, VDimension> TransformType;
  typedef vnl_matrix_fixed<double, VDimension + 1, VDimension + 1> TransformType;
  typedef vnl_vector_fixed<double, VDimension> VectorType;
  typedef vnl_matrix<double> VnlMatrixType;
  void RegisterObserver(Observer *attr);
  void SynchronizePositions() {
    for (unsigned int d = 0; d < this->GetNumberOfDomains(); d++) {
      for (unsigned int p = 0; p < this->GetNumberOfParticles(d); p++) {
        this->SetPosition(this->GetPosition(p, d), p, d);
      }
    }
  }
  unsigned long int GetNumberOfParticles(unsigned int d = 0) const { return m_Positions[d]->GetSize(); }
  const PointType &AddPosition(const PointType &, unsigned int d = 0);
  const PointType &SetPosition(const PointType &, unsigned long int k, unsigned int d = 0);
  void RemovePosition(unsigned long int k, unsigned int d = 0);
  PointType &GetPosition(unsigned long int k, unsigned int d = 0) { return m_Positions[d]->operator[](k); }
  const PointType &GetPosition(unsigned long int k, unsigned int d = 0) const { return m_Positions[d]->operator[](k); }
  PointType GetTransformedPosition(unsigned long int k, unsigned int d = 0) const {
    return this->TransformPoint(m_Positions[d]->operator[](k), m_Transforms[d] * m_PrefixTransforms[d]);
  }
  PointType GetPrefixTransformedPosition(unsigned long int k, unsigned int d = 0) const {
    return this->TransformPoint(m_Positions[d]->operator[](k), m_PrefixTransforms[d]);
  }
  void SplitAllParticles(double epsilon);
  void SplitParticle(double epsilon, unsigned int idx, unsigned int d = 0);
  void AdvancedAllParticleSplitting(double epsilon, unsigned int domains_per_shape, unsigned int dom_to_process);
  // Debug function
  void PrintParticleSystem();
  void SetNeighborhood(unsigned int, NeighborhoodType *);
  void SetNeighborhood(NeighborhoodType *n) { this->SetNeighborhood(0, n); }
  NeighborhoodType::ConstPointer GetNeighborhood(unsigned int k) const { return m_Neighborhoods[k]; }
  inline PointVectorType FindNeighborhoodPoints(const PointType &p, int idx, double r, unsigned int d = 0) const {
    return m_Neighborhoods[d]->FindNeighborhoodPoints(p, idx, r);
  }
  inline PointVectorType FindNeighborhoodPoints(const PointType &p, int idx, std::vector<double> &w,
                                                std::vector<double> &distances, double r, unsigned int d = 0) const {
    return m_Neighborhoods[d]->FindNeighborhoodPoints(p, idx, w, distances, r);
  }
  inline PointVectorType FindNeighborhoodPoints(const PointType &p, int idx, std::vector<double> &w, double r,
                                                unsigned int d = 0) const {
    return m_Neighborhoods[d]->FindNeighborhoodPoints(p, idx, w, r);
  }
  inline PointVectorType FindNeighborhoodPoints(unsigned int idx, double r, unsigned int d = 0) const {
    return m_Neighborhoods[d]->FindNeighborhoodPoints(this->GetPosition(idx, d), idx, r);
  }
  inline PointVectorType FindNeighborhoodPoints(unsigned int idx, std::vector<double> &w,
                                                std::vector<double> &distances, double r, unsigned int d = 0) const {
    return m_Neighborhoods[d]->FindNeighborhoodPoints(this->GetPosition(idx, d), idx, w, distances, r);
  }
  inline PointVectorType FindNeighborhoodPoints(unsigned int idx, std::vector<double> &w, double r,
                                                unsigned int d = 0) const {
    return m_Neighborhoods[d]->FindNeighborhoodPoints(this->GetPosition(idx, d), idx, w, r);
  }
  //  inline int FindNeighborhoodPoints(const PointType &p,  double r, PointVectorType &vec, unsigned int d = 0) const
  //  {  return m_Neighborhoods[d]->FindNeighborhoodPoints(p, r, vec); }
  //   PointVectorType FindTransformedNeighborhoodPoints(const PointType &p, double r, unsigned int d = 0) const
  //   {
  //     PointVectorType ans = m_Neighborhoods[d]
  //       ->FindNeighborhoodPoints(this->TransformPoint(p, InverseTransform[d]), r);
  //     for (unsigned int i = 0; i < ans.size(); i++)
  //       {
  //       ans.Point[i] = this->TransformPoint(ans.Point[i], m_Transform[d]);
  //       }
  //     return ans;
  //   }
  void AddDomain(DomainType::Pointer input);
  std::vector<DomainType::Pointer>::const_iterator GetDomainsBegin() const { return m_Domains.begin(); }
  std::vector<DomainType::Pointer>::const_iterator GetDomainsEnd() const { return m_Domains.end(); }
  DomainType *get_domain(unsigned int i) { return m_Domains[i].get(); }
  DomainType *get_domain() { return m_Domains[0].get(); }
  const DomainType *get_domain(unsigned int i) const { return m_Domains[i].get(); }
  const DomainType *get_domain() const { return m_Domains[0].get(); }
  unsigned int GetNumberOfDomains() const { return m_Domains.size(); }
  void SetTransform(unsigned int i, const TransformType &);
  void SetTransform(const TransformType &p) { this->SetTransform(0, p); }
  void SetPrefixTransform(unsigned int i, const TransformType &);
  void SetPrefixTransform(const TransformType &p) { this->SetPrefixTransform(0, p); }
  std::vector<TransformType>::const_iterator GetTransformsBegin() const { return m_Transforms.begin(); }
  std::vector<TransformType>::const_iterator GetTransformsEnd() const { return m_Transforms.end(); }
  const TransformType &GetTransform(unsigned int i) const { return m_Transforms[i]; }
  const TransformType &GetTransform() const { return m_Transforms[0]; }
  TransformType GetTransform(unsigned int i) { return m_Transforms[i]; }
  TransformType GetTransform() { return m_Transforms[0]; }
  const TransformType &GetPrefixTransform(unsigned int i) const { return m_PrefixTransforms[i]; }
  const TransformType &GetPrefixTransform() const { return m_PrefixTransforms[0]; }
  TransformType GetPrefixTransform(unsigned int i) { return m_PrefixTransforms[i]; }
  TransformType GetPrefixTransform() { return m_PrefixTransforms[0]; }
  std::vector<TransformType>::const_iterator GetInverseTransformsBegin() const { return m_InverseTransforms.begin(); }
  std::vector<TransformType>::const_iterator GetInverseTransformsEnd() const { return m_InverseTransforms.end(); }
  const TransformType &GetInverseTransform(unsigned int i) const { return m_InverseTransforms[i]; }
  const TransformType &GetInverseTransform() const { return m_InverseTransforms[0]; }
  const TransformType &GetInversePrefixTransform(unsigned int i) const { return m_InversePrefixTransforms[i]; }
  const TransformType &GetInversePrefixTransform() const { return m_InversePrefixTransforms[0]; }
  const std::vector<PointContainerType::Pointer> &GetPositions() const { return m_Positions; }
  const PointContainerType::Pointer &GetPositions(unsigned int d) const { return m_Positions[d]; }
  void AddPositionList(const std::vector<PointType> &, unsigned int d = 0);
  PointType TransformPoint(const PointType &, const TransformType &) const;
  VectorType TransformVector(const VectorType &, const TransformType &) const;
  VnlMatrixType TransformNormalDerivative(const VnlMatrixType &, const TransformType &) const;
  inline TransformType InvertTransform(const TransformType &T) const {
    // Note, vnl_inverse is optimized for small matrices 1x1 - 4x4
    return vnl_inverse(T);
  }
  void FlagDomain(unsigned int i) {
    // ensure large enough
    while (i >= this->m_DomainFlags.size()) {
      m_DomainFlags.push_back(false);
    }
    // set the flag
    m_DomainFlags[i] = true;
  }
  void UnflagDomain(unsigned int i) { m_DomainFlags[i] = false; }
  bool GetDomainFlag(unsigned int i) const {
    if (i >= m_DomainFlags.size()) {
      // not set
      return false;
    }
    return m_DomainFlags[i];
  }
  const std::vector<bool> &GetDomainFlags() const { return m_DomainFlags; }
  void SetDomainFlags() {
    for (unsigned int i = 0; i < m_DomainFlags.size(); i++) {
      m_DomainFlags[i] = true;
    }
  }
  void ResetDomainFlags() {
    for (unsigned int i = 0; i < m_DomainFlags.size(); i++) {
      m_DomainFlags[i] = false;
    }
  }
  void SetFixedParticleFlag(unsigned int d, unsigned int i) { m_FixedParticleFlags[d][i] = true; }
  void ResetFixedParticleFlag(unsigned int d, unsigned int i) { m_FixedParticleFlags[d][i] = false; }
  bool GetFixedParticleFlag(unsigned int d, unsigned int i) const { return m_FixedParticleFlags[d][i]; }
  void ResetFixedParticleFlags() {
    for (unsigned d = 0; d < m_FixedParticleFlags.size(); d++) {
      for (unsigned int i = 0; i < m_FixedParticleFlags[d].size(); i++) m_FixedParticleFlags[d][i] = false;
    }
  }
  void SetDomainsPerShape(unsigned int num) {
    m_DomainsPerShape = num;
    m_FixedParticleFlags.resize(m_DomainsPerShape);
  }
  unsigned int GetDomainsPerShape() const { return m_DomainsPerShape; }
  void SetNumberOfDomains(unsigned int);
  // Returns the maximum distance between nearest neighbors in domain dom
  double ComputeMaxDistNearestNeighbors(size_t dom);
  void SetFieldAttributes(const std::vector<std::string> &field_attributes) { m_FieldAttributes = field_attributes; }
  const std::vector<std::string> &GetFieldAttributes() const { return m_FieldAttributes; }
 protected:
  ParticleSystem();
  void PrintSelf(std::ostream &os, itk::Indent indent) const;
  virtual ~ParticleSystem(){};
  TransformType &GetInverseTransform(unsigned int i) { return m_InverseTransforms[i]; }
  TransformType &GetInverseTransform() { return m_InverseTransforms[0]; }
  TransformType &GetInversePrefixTransform(unsigned int i) { return m_InversePrefixTransforms[i]; }
  TransformType &GetInversePrefixTransform() { return m_InversePrefixTransforms[0]; }
 private:
  ParticleSystem(const Self &);  // purposely not implemented
  void operator=(const Self &);  // purposely not implemented
  std::vector<PointContainerType::Pointer> m_Positions;
  std::vector<DomainType::Pointer> m_Domains;
  unsigned int m_DomainsPerShape;
  std::vector<NeighborhoodType::Pointer> m_Neighborhoods;
  std::vector<TransformType> m_Transforms;
  std::vector<TransformType> m_InverseTransforms;
  std::vector<TransformType> m_PrefixTransforms;
  std::vector<TransformType> m_InversePrefixTransforms;
  std::vector<unsigned long int> m_IndexCounters;
  std::vector<bool> m_DomainFlags;
  std::vector<std::vector<bool>> m_FixedParticleFlags;
  std::vector<std::string> m_FieldAttributes;
  std::mt19937 m_rand{42};
};
}  // end namespace shapeworks
Updated on 2024-03-17 at 12:58:44 -0600