Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mitkTimeSlicedGeometry.h"
00020
00021 void mitk::TimeSlicedGeometry::UpdateInformation()
00022 {
00023 if(m_TimeSteps==0) return;
00024
00025 unsigned long maxModifiedTime = 0, curModifiedTime;
00026
00027 mitk::ScalarType stmin, stmax;
00028 stmin= ScalarTypeNumericTraits::NonpositiveMin();
00029 stmax= ScalarTypeNumericTraits::max();
00030
00031 TimeBounds timeBounds;
00032 timeBounds[0]=stmax; timeBounds[1]=stmin;
00033
00034 mitk::BoundingBox::Pointer boundingBox=mitk::BoundingBox::New();
00035
00036 mitk::BoundingBox::PointsContainer::Pointer pointscontainer=mitk::BoundingBox::PointsContainer::New();
00037
00038 unsigned int t;
00039
00040 mitk::Geometry3D* geometry3d;
00041 mitk::BoundingBox::ConstPointer nextBoundingBox;
00042 mitk::BoundingBox::PointIdentifier pointid=0;
00043
00044
00045 mitk::ScalarType zeropoint[]={0,0,0,0,0,0};
00046 BoundingBox::BoundsArrayType itkBoundsZero(zeropoint);
00047
00048 for(t=0; t < m_TimeSteps; ++t)
00049 {
00050 geometry3d = GetGeometry3D(t);
00051 assert(geometry3d!=NULL);
00052
00053 curModifiedTime = geometry3d->GetMTime();
00054 if(maxModifiedTime < curModifiedTime)
00055 maxModifiedTime = curModifiedTime;
00056
00057 const TimeBounds & curTimeBounds = geometry3d->GetTimeBounds();
00058 if((curTimeBounds[0] > stmin) && (curTimeBounds[0] < timeBounds[0]))
00059 timeBounds[0] = curTimeBounds[0];
00060 if((curTimeBounds[1] < stmax) && (curTimeBounds[1] > timeBounds[1]))
00061 timeBounds[1] = curTimeBounds[1];
00062
00063 nextBoundingBox = geometry3d->GetBoundingBox();
00064 assert(nextBoundingBox.IsNotNull());
00065
00066
00067 if (nextBoundingBox->GetBounds() == itkBoundsZero)
00068 {
00069 continue;
00070 }
00071
00072 const mitk::BoundingBox::PointsContainer * nextPoints = nextBoundingBox->GetPoints();
00073 if(nextPoints!=NULL)
00074 {
00075 mitk::BoundingBox::PointsContainer::ConstIterator pointsIt = nextPoints->Begin();
00076
00077 while (pointsIt != nextPoints->End() )
00078 {
00079 pointscontainer->InsertElement( pointid++, pointsIt->Value());
00080 ++pointsIt;
00081 }
00082 }
00083 }
00084
00085 if(!(timeBounds[0] < stmax))
00086 {
00087 timeBounds[0] = stmin;
00088 timeBounds[1] = stmax;
00089 }
00090
00091 m_TimeBounds = timeBounds;
00092 assert(timeBounds[0]<=timeBounds[1]);
00093
00094 boundingBox->SetPoints(pointscontainer);
00095
00096 boundingBox->ComputeBoundingBox();
00097
00098 m_BoundingBox = boundingBox;
00099
00100 SetIndexToWorldTransform(GetGeometry3D(0)->GetIndexToWorldTransform());
00101
00102 if(this->GetMTime() < maxModifiedTime)
00103 Modified();
00104 }
00105
00106 mitk::Geometry3D* mitk::TimeSlicedGeometry::GetGeometry3D(int t) const
00107 {
00108 mitk::Geometry3D::Pointer geometry3d = NULL;
00109 if(IsValidTime(t))
00110 {
00111 geometry3d = m_Geometry3Ds[t];
00112
00113
00114
00115 if((m_EvenlyTimed) && (geometry3d.IsNull()))
00116 {
00117 const Geometry3D* firstgeometry=m_Geometry3Ds[0].GetPointer();
00118
00119 assert(firstgeometry != NULL);
00120
00121 mitk::Geometry3D::Pointer requestedgeometry;
00122 requestedgeometry = dynamic_cast<Geometry3D*>(firstgeometry->Clone().GetPointer());
00123 if ( requestedgeometry.IsNull() ) itkExceptionMacro("Geometry is NULL!");
00124
00125 TimeBounds timebounds = requestedgeometry->GetTimeBounds();
00126 if(timebounds[1]<ScalarTypeNumericTraits::max())
00127 {
00128 mitk::ScalarType later = (timebounds[1]-timebounds[0])*t;
00129 timebounds[0]+=later; timebounds[1]+=later;
00130 requestedgeometry->SetTimeBounds(timebounds);
00131 }
00132
00133 geometry3d = requestedgeometry;
00134 m_Geometry3Ds[t] = geometry3d;
00135 }
00136 }
00137 else
00138 return NULL;
00139 return geometry3d;
00140 }
00141
00142 bool mitk::TimeSlicedGeometry::SetGeometry3D(mitk::Geometry3D* geometry3D, int t)
00143 {
00144 if(IsValidTime(t))
00145 {
00146 m_Geometry3Ds[t]=geometry3D;
00147 return true;
00148 }
00149 return false;
00150 }
00151
00152 int mitk::TimeSlicedGeometry::MSToTimeStep(mitk::ScalarType time_in_ms) const
00153 {
00154 if(time_in_ms < m_TimeBounds[0])
00155 return -1;
00156 if(time_in_ms >= m_TimeBounds[1])
00157 return m_TimeSteps;
00158 if(m_EvenlyTimed)
00159 {
00160 if(m_TimeBounds[0] == m_TimeBounds[1])
00161 return 0;
00162 if((m_TimeBounds[0]>ScalarTypeNumericTraits::NonpositiveMin()) && (m_TimeBounds[1]<ScalarTypeNumericTraits::max()))
00163 {
00164 return (int) ceil(((time_in_ms - m_TimeBounds[0])/(m_TimeBounds[1]-m_TimeBounds[0])*m_TimeSteps)-0.5);
00165 }
00166 return 0;
00167 }
00168 else
00169 {
00170 unsigned int t;
00171 for ( t = 0; t < m_TimeSteps; ++t )
00172 {
00173 const TimeBounds& timeBounds = GetGeometry3D( t )->GetTimeBounds();
00174 if( (timeBounds[0] <= time_in_ms) && (time_in_ms <= timeBounds[1]) )
00175 {
00176 return t;
00177 }
00178 }
00179 }
00180 return 0;
00181 }
00182
00183 mitk::ScalarType mitk::TimeSlicedGeometry::TimeStepToMS(int timestep) const
00184 {
00185 if(IsValidTime(timestep)==false)
00186 return ScalarTypeNumericTraits::max();
00187 if(m_EvenlyTimed)
00188 {
00189 if ( timestep == 0 )
00190 return m_TimeBounds[0];
00191 else
00192 {
00193 assert( ! (m_TimeBounds[0] == ScalarTypeNumericTraits::NonpositiveMin() && m_TimeBounds[1] == ScalarTypeNumericTraits::max() ) );
00194 return ((mitk::ScalarType)timestep)/m_TimeSteps*(m_TimeBounds[1]-m_TimeBounds[0])+m_TimeBounds[0];
00195 }
00196 }
00197 else
00198 {
00199 return GetGeometry3D(timestep)->GetTimeBounds()[0];
00200 }
00201 }
00202
00203 int mitk::TimeSlicedGeometry::TimeStepToTimeStep(
00204 const mitk::TimeSlicedGeometry *referenceGeometry, int t) const
00205 {
00206 int timeStep;
00207 if ( referenceGeometry->GetTimeSteps() > 1 )
00208 {
00209
00210 timeStep = this->MSToTimeStep( referenceGeometry->TimeStepToMS( t ) );
00211 }
00212 else
00213 {
00214
00215 timeStep = 0;
00216 }
00217
00218 return timeStep;
00219 }
00220
00221
00222 void mitk::TimeSlicedGeometry::Initialize(unsigned int timeSteps)
00223 {
00224 Geometry3D::Pointer geometry3D = Geometry3D::New();
00225 geometry3D->Initialize();
00226 InitializeEvenlyTimed(geometry3D, timeSteps);
00227 }
00228
00229 void mitk::TimeSlicedGeometry::InitializeEvenlyTimed(mitk::Geometry3D* geometry3D, unsigned int timeSteps)
00230 {
00231 assert(geometry3D!=NULL);
00232
00233 geometry3D->Register();
00234
00235 InitializeEmpty(timeSteps);
00236
00237 AffineTransform3D::Pointer transform = AffineTransform3D::New();
00238 transform->SetMatrix(geometry3D->GetIndexToWorldTransform()->GetMatrix());
00239 transform->SetOffset(geometry3D->GetIndexToWorldTransform()->GetOffset());
00240 SetIndexToWorldTransform(transform);
00241
00242 SetBounds(geometry3D->GetBounds());
00243 SetGeometry3D(geometry3D, 0);
00244 SetEvenlyTimed();
00245
00246 UpdateInformation();
00247
00248 SetFrameOfReferenceID(geometry3D->GetFrameOfReferenceID());
00249 SetImageGeometry(geometry3D->GetImageGeometry());
00250
00251 geometry3D->UnRegister();
00252 }
00253
00254 void mitk::TimeSlicedGeometry::InitializeEmpty(unsigned int timeSteps)
00255 {
00256 m_IndexToWorldTransform = NULL;
00257
00258 Superclass::Initialize();
00259
00260 m_TimeSteps = timeSteps;
00261
00262
00263 Geometry3D::Pointer gnull=NULL;
00264 m_Geometry3Ds.assign(m_TimeSteps, gnull);
00265 }
00266
00267 void mitk::TimeSlicedGeometry::ExpandToNumberOfTimeSteps( unsigned int timeSteps )
00268 {
00269 if( timeSteps <= m_TimeSteps ) return;
00270
00271 if(m_TimeSteps == 1)
00272 {
00273 Geometry3D* g3d = m_Geometry3Ds[0];
00274 const TimeBounds & timeBounds = g3d->GetTimeBounds();
00275 if( (timeBounds[0] == ScalarTypeNumericTraits::NonpositiveMin()) ||
00276 (timeBounds[1]==ScalarTypeNumericTraits::max())
00277 )
00278 {
00279 mitk::ScalarType timeBounds[] = {0.0, 1.0};
00280 m_Geometry3Ds[0]->SetTimeBounds( timeBounds );
00281 }
00282 }
00283
00284
00285 Geometry3D::Pointer gnull=NULL;
00286 m_Geometry3Ds.resize(timeSteps, gnull);
00287
00288 m_TimeSteps = timeSteps;
00289
00290 UpdateInformation();
00291 }
00292
00293 mitk::TimeSlicedGeometry::TimeSlicedGeometry() : m_TimeSteps(0), m_EvenlyTimed(false)
00294 {
00295 }
00296
00297 mitk::TimeSlicedGeometry::~TimeSlicedGeometry()
00298 {
00299
00300 }
00301
00302 void mitk::TimeSlicedGeometry::SetImageGeometry(const bool isAnImageGeometry)
00303 {
00304 Superclass::SetImageGeometry(isAnImageGeometry);
00305
00306 mitk::Geometry3D* geometry3d;
00307 unsigned int t;
00308 for(t=0; t<m_TimeSteps; ++t)
00309 {
00310 geometry3d = m_Geometry3Ds[t];
00311 if(geometry3d!=NULL)
00312 geometry3d->SetImageGeometry(isAnImageGeometry);
00313 }
00314 }
00315
00316 void mitk::TimeSlicedGeometry::SetEvenlyTimed(bool on)
00317 {
00318 m_EvenlyTimed = on;
00319 Modified();
00320 }
00321
00322 bool mitk::TimeSlicedGeometry::IsValidTime(int t) const
00323 {
00324 return (t>=0) && (t< (int)m_TimeSteps);
00325 }
00326
00327 void mitk::TimeSlicedGeometry::CopyTimes(const mitk::TimeSlicedGeometry* timeslicedgeometry, unsigned int t, unsigned int endtimeindex)
00328 {
00329 if(endtimeindex >= timeslicedgeometry->GetTimeSteps())
00330 endtimeindex = timeslicedgeometry->GetTimeSteps()-1;
00331 if(endtimeindex >= this->GetTimeSteps())
00332 endtimeindex = this->GetTimeSteps()-1;
00333 for(; t <= endtimeindex; ++t)
00334 {
00335 mitk::Geometry3D* geometry3d = GetGeometry3D(t);
00336 mitk::Geometry3D* othergeometry3d = timeslicedgeometry->GetGeometry3D(t);
00337 assert((geometry3d!=NULL) && (othergeometry3d!=NULL));
00338
00339 geometry3d->SetTimeBounds(othergeometry3d->GetTimeBounds());
00340
00341 }
00342
00343 UpdateInformation();
00344 }
00345
00346 mitk::AffineGeometryFrame3D::Pointer mitk::TimeSlicedGeometry::Clone() const
00347 {
00348 Self::Pointer newGeometry = Self::New();
00349 newGeometry->Initialize(m_TimeSteps);
00350 InitializeGeometry(newGeometry);
00351 return newGeometry.GetPointer();
00352 }
00353
00354 void mitk::TimeSlicedGeometry::InitializeGeometry(Self * newGeometry) const
00355 {
00356 Superclass::InitializeGeometry(newGeometry);
00357
00358 newGeometry->SetEvenlyTimed(m_EvenlyTimed);
00359
00360 unsigned int t;
00361 for(t=0; t<m_TimeSteps; ++t)
00362 {
00363 if(m_Geometry3Ds[t].IsNull())
00364 {
00365 assert(m_EvenlyTimed);
00366 }
00367 else
00368 {
00369 newGeometry->SetGeometry3D(dynamic_cast<Geometry3D*>(m_Geometry3Ds[t]->Clone().GetPointer()), t);
00370 }
00371 }
00372 }
00373
00374 void mitk::TimeSlicedGeometry::PrintSelf(std::ostream& os, itk::Indent indent) const
00375 {
00376
00377 os << indent << " EvenlyTimed: " << m_EvenlyTimed << std::endl;
00378 os << indent << " TimeSteps: " << m_TimeSteps << std::endl;
00379
00380 os << std::endl;
00381 os << indent << " GetGeometry3D(0): ";
00382 if(GetGeometry3D(0)==NULL)
00383 os << "NULL" << std::endl;
00384 else
00385 GetGeometry3D(0)->Print(os, indent);
00386 }
00387
00388 void mitk::TimeSlicedGeometry::ExecuteOperation(Operation* operation)
00389 {
00390
00391 for (std::vector<Geometry3D::Pointer>::iterator iter = m_Geometry3Ds.begin();
00392 iter != m_Geometry3Ds.end();
00393 ++iter)
00394 {
00395 (*iter)->ExecuteOperation(operation);
00396 }
00397
00398 Geometry3D::ExecuteOperation(operation);
00399
00400 this->Modified();
00401 }
00402