Shapeworks Studio  2.1
Shape analysis software suite
itkPSMParticleSystem.h
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef __itkPSMParticleSystem_h
19 #define __itkPSMParticleSystem_h
20 
21 #include "itkDataObject.h"
22 #include "itkObjectFactory.h"
23 #include "itkPoint.h"
24 #include "itkWeakPointer.h"
25 #include "itkPSMAttribute.h"
26 #include "itkPSMDomain.h"
27 #include "vnl/vnl_matrix_fixed.h"
28 #include "vnl/vnl_vector_fixed.h"
29 #include "itkPSMContainer.h"
30 #include "itkPSMEvents.h"
31 #include "itkCommand.h"
32 #include "itkEventObject.h"
33 #include "itkPSMNeighborhood.h"
34 #include "vnl/vnl_inverse.h"
35 #include "vnl/vnl_det.h"
36 #include <map>
37 #include <vector>
38 
39 namespace itk
40 {
67 template <unsigned int VDimension>
68 class ITK_EXPORT PSMParticleSystem : public DataObject
69 {
70 public:
73  typedef DataObject Superclass;
74  typedef SmartPointer<Self> Pointer;
75  typedef SmartPointer<const Self> ConstPointer;
76  typedef WeakPointer<const Self> ConstWeakPointer;
77 
79  itkNewMacro(Self);
80 
82  itkTypeMacro(PSMParticleSystem, DataObject);
83 
85  itkStaticConstMacro(Dimension, unsigned int, VDimension);
86 
89 
92 
96 
99 
100  typedef typename NeighborhoodType::PointVectorType PointVectorType;
101 
104  typedef vnl_matrix_fixed<double, VDimension +1, VDimension +1> TransformType;
105  typedef vnl_vector_fixed<double, VDimension> VectorType;
106 
118  void RegisterAttribute( PSMAttribute<VDimension> *);
119 
125  {
126  for (unsigned int d = 0; d < this->GetNumberOfDomains(); d++)
127  {
128  for (unsigned int p = 0; p < this->GetNumberOfParticles(d); p++)
129  {
130  this->SetPosition(this->GetPosition(p,d), p, d);
131  }
132  }
133  }
134 
136  unsigned long int GetNumberOfParticles(unsigned int d = 0) const
137  { return m_Positions[d]->GetSize(); }
138 
151  const PointType &AddPosition( const PointType &, unsigned int d=0, int threadId=0);
152  const PointType &SetPosition( const PointType &, unsigned long int k, unsigned int d=0, int threadId=0);
153 
154  // inline const PointType &SetTransformedPosition(const PointType &p,
155  // unsigned long int k, unsigned int d=0, int threadId=0)
156  // {
157  // this->SetPosition( this->TransformPoint(p, m_InverseTransform[d]), k, d, threadId );
158  // }
159 
160  void RemovePosition(unsigned long int k, unsigned int d=0, int threadId=0);
161 
169  PointType &GetPosition(unsigned long int k, unsigned int d=0)
170  { return m_Positions[d]->operator[](k); }
171  const PointType &GetPosition(unsigned long int k, unsigned int d=0) const
172  { return m_Positions[d]->operator[](k); }
173  PointType GetTransformedPosition(unsigned long int k, unsigned int d=0) const
174  { return this->TransformPoint(m_Positions[d]->operator[](k),
175  m_Transforms[d] * m_PrefixTransforms[d]); }
176 
182  void SplitAllParticles(double epsilon, int threadId=0);
183  void SplitAllParticlesInDomain(const vnl_vector_fixed<double, VDimension> &,
184  double epsilon, unsigned int d=0, int threadId=0);
185  void SplitParticle(double epsilon, unsigned int idx, unsigned int d=0, int threadId=0);
186 
188  void SetNeighborhood(unsigned int, NeighborhoodType *, int threadId=0);
189  void SetNeighborhood(NeighborhoodType *n, int threadId=0)
190  { this->SetNeighborhood(0, n, threadId); }
191  typename NeighborhoodType::ConstPointer GetNeighborhood(unsigned int k) const
192  { return m_Neighborhoods[k]; }
193 
200  inline PointVectorType FindNeighborhoodPoints(const PointType &p,
201  double r, unsigned int d = 0) const
202  {
203  return m_Neighborhoods[d]->FindNeighborhoodPoints(p, r);
204  }
205  inline PointVectorType FindNeighborhoodPoints(const PointType &p,
206  std::vector<double> &w,
207  double r, unsigned int d = 0) const
208  {
209  return m_Neighborhoods[d]->FindNeighborhoodPointsWithWeights(p,w,r);
210  }
211  inline PointVectorType FindNeighborhoodPoints(unsigned int idx,
212  double r, unsigned int d = 0) const
213  {
214  return m_Neighborhoods[d]->FindNeighborhoodPoints(this->GetPosition(idx,d), r);
215  }
216  inline PointVectorType FindNeighborhoodPoints(unsigned int idx,
217  std::vector<double> &w,
218  double r, unsigned int d = 0) const
219  {
220  return m_Neighborhoods[d]->FindNeighborhoodPointsWithWeights(this->GetPosition(idx,d),w, r);
221  }
222 
223  // inline int FindNeighborhoodPoints(const PointType &p, double r, PointVectorType &vec, unsigned int d = 0) const
224  // { return m_Neighborhoods[d]->FindNeighborhoodPoints(p, r, vec); }
225 
226  // PointVectorType FindTransformedNeighborhoodPoints(const PointType &p, double r, unsigned int d = 0) const
227  // {
228  // PointVectorType ans = m_Neighborhoods[d]
229  // ->FindNeighborhoodPoints(this->TransformPoint(p, InverseTransform[d]), r);
230  // for (unsigned int i = 0; i < ans.size(); i++)
231  // {
232  // ans.Point[i] = this->TransformPoint(ans.Point[i], m_Transform[d]);
233  // }
234  // return ans;
235  // }
236 
241  void AddDomain( DomainType *, int threadId =0);
242 
245  typename std::vector< typename DomainType::Pointer >::const_iterator GetDomainsBegin() const
246  { return m_Domains.begin(); }
247 
250  typename std::vector< typename DomainType::Pointer >::const_iterator GetDomainsEnd() const
251  { return m_Domains.end(); }
252 
254  DomainType * GetDomain(unsigned int i)
255  { return m_Domains[i].GetPointer(); }
256 
258  DomainType * GetDomain()
259  {return m_Domains[0].GetPointer(); }
260 
262  const DomainType *GetDomain(unsigned int i) const
263  { return m_Domains[i].GetPointer(); }
264 
266  const DomainType *GetDomain() const
267  {return m_Domains[0].GetPointer(); }
268 
270  unsigned int GetNumberOfDomains() const
271  { return m_Domains.size(); }
272 
280  void SetTransform(unsigned int i, const TransformType &, int threadId=0);
281  void SetTransform(const TransformType &p, int threadId=0)
282  { this->SetTransform(0, p, threadId); }
283  void SetPrefixTransform(unsigned int i, const TransformType &, int threadId=0);
284  void SetPrefixTransform(const TransformType &p, int threadId=0)
285  { this->SetPrefixTransform(0, p, threadId); }
286 
289  typename std::vector< TransformType >::const_iterator
290  GetTransformsBegin() const { return m_Transforms.begin(); }
291 
294  typename std::vector< TransformType >::const_iterator
295  GetTransformsEnd() const { return m_Transforms.end(); }
296 
298  const TransformType &GetTransform(unsigned int i) const
299  { return m_Transforms[i]; }
300 
302  const TransformType &GetTransform() const
303  {return m_Transforms[0]; }
304 
306  TransformType GetTransform(unsigned int i)
307  { return m_Transforms[i]; }
308 
310  TransformType GetTransform()
311  {return m_Transforms[0]; }
312 
314  const TransformType &GetPrefixTransform(unsigned int i) const
315  { return m_PrefixTransforms[i]; }
316 
318  const TransformType &GetPrefixTransform() const
319  {return m_PrefixTransforms[0]; }
320 
322  TransformType GetPrefixTransform(unsigned int i)
323  { return m_PrefixTransforms[i]; }
324 
326  TransformType GetPrefixTransform()
327  {return m_PrefixTransforms[0]; }
328 
331  typename std::vector< TransformType >::const_iterator
333  { return m_InverseTransforms.begin(); }
334 
337  typename std::vector< TransformType >::const_iterator
339  { return m_InverseTransforms.end(); }
340 
342  const TransformType &GetInverseTransform(unsigned int i) const
343  { return m_InverseTransforms[i]; }
344 
346  const TransformType &GetInverseTransform() const
347  {return m_InverseTransforms[0]; }
348 
350  const TransformType &GetInversePrefixTransform(unsigned int i) const
351  { return m_InversePrefixTransforms[i]; }
352 
354  const TransformType &GetInversePrefixTransform() const
355  {return m_InversePrefixTransforms[0]; }
356 
358  const std::vector<typename PointContainerType::Pointer> & GetPositions() const
359  { return m_Positions; }
360  const typename PointContainerType::Pointer & GetPositions(unsigned int d) const
361  { return m_Positions[d]; }
362 
365  void AddPositionList(const std::vector<PointType> &, unsigned int d, int threadId = 0);
366 
370  PointType TransformPoint(const PointType &, const TransformType &) const;
371 
374  VectorType TransformVector(const VectorType &, const TransformType &) const;
375 
377  inline TransformType InvertTransform(const TransformType &T) const
378  {
379  double det = vnl_det(T);
380  // Check if the inverse can be calculated. If not, set the inverse
381  // to identity.
382  if (det == 0)
383  {
384  TransformType identity;
385  identity.set_identity();
386  return identity;
387  }
388  else
389  {
390  // Note, vnl_inverse is optimized for small matrices 1x1 - 4x4
391  return vnl_inverse(T);
392  }
393  }
394 
397  void FlagDomain(unsigned int i)
398  { m_DomainFlags[i] = true; }
399  void UnflagDomain(unsigned int i)
400  { m_DomainFlags[i] = false; }
401  bool GetDomainFlag(unsigned int i) const
402  { return m_DomainFlags[i]; }
403  // bool &GetDomainFlag(unsigned int i)
404  // { return m_DomainFlags[i]; }
405  const std::vector<bool> &GetDomainFlags() const
406  { return m_DomainFlags; }
407  void SetDomainFlags()
408  { for (unsigned int i = 0; i < m_DomainFlags.size(); i++) { m_DomainFlags[i] = true; } }
409  void ResetDomainFlags()
410  { for (unsigned int i = 0; i < m_DomainFlags.size(); i++) { m_DomainFlags[i] = false; } }
411 
412 
418  void SetFixedParticleFlag(unsigned int i)
419  { if (i < m_FixedParticleFlags.size()) m_FixedParticleFlags[i] = true; }
420  void ResetFixedParticleFlag(unsigned int i)
421  { if (i < m_FixedParticleFlags.size()) m_FixedParticleFlags[i] = false;}
422  bool GetFixedParticleFlag(unsigned int i) const
423  {
424  if (i < m_FixedParticleFlags.size()) return m_FixedParticleFlags[i];
425  else return false;
426  }
427  void ResetFixedParticleFlags()
428  {
429  for (unsigned int i = 0; i < m_FixedParticleFlags.size(); i++)
430  { m_FixedParticleFlags[i] = false; }
431  }
432 
433 protected:
435  void PrintSelf(std::ostream& os, Indent indent) const;
436  virtual ~PSMParticleSystem() {};
437 
440  void SetNumberOfDomains( unsigned int );
441 
444  typename std::vector< typename DomainType::Pointer >::iterator GetDomainsBegin()
445  { return m_Domains.begin(); }
446 
449  typename std::vector< typename DomainType::Pointer >::iterator GetDomainsEnd()
450  { return m_Domains.end(); }
451 
454  typename std::vector< TransformType >::iterator GetTransformsBegin()
455  { return m_Transforms.begin(); }
456 
459  typename std::vector< TransformType >::iterator GetTransformsEnd()
460  { return m_Transforms.end(); }
461 
464  typename std::vector< TransformType >::iterator
466  { return m_InverseTransforms.begin(); }
467 
470  typename std::vector< TransformType >::iterator
472  { return m_InverseTransforms.end(); }
473 
475  TransformType &GetInverseTransform(unsigned int i)
476  { return m_InverseTransforms[i]; }
477 
479  TransformType &GetInverseTransform()
480  {return m_InverseTransforms[0]; }
481 
483  TransformType &GetInversePrefixTransform(unsigned int i)
484  { return m_InversePrefixTransforms[i]; }
485 
487  TransformType &GetInversePrefixTransform()
488  {return m_InversePrefixTransforms[0]; }
489 
490 private:
491  PSMParticleSystem(const Self&); //purposely not implemented
492  void operator=(const Self&); //purposely not implemented
493 
496  std::vector<typename PointContainerType::Pointer> m_Positions;
497 
499  std::vector< typename DomainType::Pointer > m_Domains;
500 
502  std::vector< typename NeighborhoodType::Pointer > m_Neighborhoods;
503 
505  std::vector< TransformType > m_Transforms;
506 
508  std::vector< TransformType > m_InverseTransforms;
509 
511  std::vector< TransformType > m_PrefixTransforms;
512 
514  std::vector< TransformType > m_InversePrefixTransforms;
515 
517  std::vector< unsigned long int> m_IndexCounters;
518 
523  std::vector<bool> m_DomainFlags;
524 
527  std::vector<bool> m_FixedParticleFlags;
528 };
529 
530 } // end namespace itk
531 
532 #ifndef ITK_MANUAL_INSTANTIATION
533 #include "itkPSMParticleSystem.hxx"
534 #endif
535 
536 #endif
unsigned int GetNumberOfDomains() const
const TransformType & GetTransform() const
TransformType InvertTransform(const TransformType &T) const
std::vector< typename DomainType::Pointer >::iterator GetDomainsBegin()
const TransformType & GetInverseTransform() const
const TransformType & GetInverseTransform(unsigned int i) const
std::vector< TransformType >::const_iterator GetTransformsBegin() const
TransformType & GetInversePrefixTransform(unsigned int i)
const TransformType & GetPrefixTransform() const
PSMNeighborhood< VDimension > NeighborhoodType
TransformType GetPrefixTransform()
const DomainType * GetDomain(unsigned int i) const
PointType & GetPosition(unsigned long int k, unsigned int d=0)
std::vector< TransformType >::const_iterator GetInverseTransformsBegin() const
TransformType GetTransform(unsigned int i)
TransformType & GetInverseTransform(unsigned int i)
const DomainType * GetDomain() const
std::vector< TransformType >::const_iterator GetInverseTransformsEnd() const
void FlagDomain(unsigned int i)
std::vector< TransformType >::iterator GetInverseTransformsBegin()
unsigned long int GetNumberOfParticles(unsigned int d=0) const
Point< double, VDimension > PointType
TransformType & GetInverseTransform()
std::vector< typename DomainType::Pointer >::const_iterator GetDomainsEnd() const
std::vector< typename DomainType::Pointer >::iterator GetDomainsEnd()
std::vector< TransformType >::iterator GetTransformsBegin()
const TransformType & GetInversePrefixTransform(unsigned int i) const
A facade class that manages interactions with a particle system.
const TransformType & GetTransform(unsigned int i) const
const TransformType & GetPrefixTransform(unsigned int i) const
TransformType & GetInversePrefixTransform()
Base class for defining the domain in which a particle system exists.
Definition: itkPSMDomain.h:48
DomainType * GetDomain(unsigned int i)
std::vector< typename DomainType::Pointer >::const_iterator GetDomainsBegin() const
Base class for PSMParticleSystem attribute classes.
std::vector< PSMPointIndexPair< VDimension > > PointVectorType
A container class that holds particle position information for the PSMParticleSystem class...
TransformType GetPrefixTransform(unsigned int i)
PointVectorType FindNeighborhoodPoints(const PointType &p, double r, unsigned int d=0) const
PSMDomain< VDimension > DomainType
std::vector< TransformType >::iterator GetInverseTransformsEnd()
void SetFixedParticleFlag(unsigned int i)
std::vector< TransformType >::const_iterator GetTransformsEnd() const
const TransformType & GetInversePrefixTransform() const
const std::vector< typename PointContainerType::Pointer > & GetPositions() const
PSMContainer< PointType > PointContainerType
std::vector< TransformType >::iterator GetTransformsEnd()
vnl_matrix_fixed< double, VDimension+1, VDimension+1 > TransformType