00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mitkPointSet.h"
00020 #include "mitkPointOperation.h"
00021 #include "mitkInteractionConst.h"
00022
00023 #include <itkSmartPointerForwardReference.txx>
00024
00025
00026 mitk::PointSet::PointSet()
00027 {
00028 this->InitializeEmpty();
00029 }
00030
00031 mitk::PointSet::~PointSet()
00032 {
00033 this->ClearData();
00034 }
00035
00036 void mitk::PointSet::ClearData()
00037 {
00038 m_PointSetSeries.clear();
00039 Superclass::ClearData();
00040 }
00041
00042 void mitk::PointSet::InitializeEmpty()
00043 {
00044 m_PointSetSeries.resize( 1 );
00045
00046 m_PointSetSeries[0] = DataType::New();
00047 PointDataContainer::Pointer pointData = PointDataContainer::New();
00048 m_PointSetSeries[0]->SetPointData( pointData );
00049 m_CalculateBoundingBox = false;
00050
00051 Superclass::InitializeTimeSlicedGeometry(1);
00052 m_Initialized = true;
00053 }
00054
00055 bool mitk::PointSet::IsEmpty(unsigned int t) const
00056 {
00057 return IsInitialized() && (GetSize(t) == 0);
00058 }
00059
00060 void mitk::PointSet::Expand( unsigned int timeSteps )
00061 {
00062
00063
00064
00065
00066
00067
00068
00069
00070 unsigned int oldSize = m_PointSetSeries.size();
00071
00072 if ( timeSteps > oldSize )
00073 {
00074 Superclass::Expand( timeSteps );
00075
00076 m_PointSetSeries.resize( timeSteps );
00077 for ( unsigned int i = oldSize; i < timeSteps; ++i )
00078 {
00079 m_PointSetSeries[i] = DataType::New();
00080 PointDataContainer::Pointer pointData = PointDataContainer::New();
00081 m_PointSetSeries[i]->SetPointData( pointData );
00082 }
00083
00084
00085 m_CalculateBoundingBox = true;
00086
00087 this->InvokeEvent( PointSetExtendTimeRangeEvent() );
00088 }
00089 }
00090
00091
00092 unsigned int mitk::PointSet::GetPointSetSeriesSize() const
00093 {
00094 return m_PointSetSeries.size();
00095 }
00096
00097
00098 int mitk::PointSet::GetSize( unsigned int t ) const
00099 {
00100 if ( t < m_PointSetSeries.size() )
00101 {
00102 return m_PointSetSeries[t]->GetNumberOfPoints();
00103 }
00104 else
00105 {
00106 return 0;
00107 }
00108 }
00109
00110 mitk::PointSet::DataType::Pointer mitk::PointSet::GetPointSet( int t ) const
00111 {
00112 if ( t < (int)m_PointSetSeries.size() )
00113 {
00114 return m_PointSetSeries[t];
00115 }
00116 else
00117 {
00118 return NULL;
00119 }
00120 }
00121
00122 int mitk::PointSet::SearchPoint( Point3D point, float distance, int t ) const
00123 {
00124 if ( t >= (int)m_PointSetSeries.size() )
00125 {
00126 return -1;
00127 }
00128
00129
00130 PointType out;
00131 out.Fill( 0 );
00132 PointType indexPoint;
00133
00134 this->GetGeometry( t )->WorldToIndex(point, indexPoint);
00135
00136
00137
00138 unsigned int i;
00139 PointsContainer::Iterator it, end;
00140 end = m_PointSetSeries[t]->GetPoints()->End();
00141 int bestIndex = -1;
00142 distance = distance * distance;
00143
00144
00145 if (distance == 0.0)
00146 {
00147 distance = 0.000001;
00148 }
00149
00150 ScalarType bestDist = distance;
00151 ScalarType dist, tmp;
00152
00153 for ( it = m_PointSetSeries[t]->GetPoints()->Begin(), i = 0;
00154 it != end;
00155 ++it, ++i )
00156 {
00157 bool ok = m_PointSetSeries[t]->GetPoints()
00158 ->GetElementIfIndexExists( it->Index(), &out );
00159
00160 if ( !ok )
00161 {
00162 return -1;
00163 }
00164 else if ( indexPoint == out )
00165 {
00166 return it->Index();
00167 }
00168
00169
00170 tmp = out[0] - indexPoint[0]; dist = tmp * tmp;
00171 tmp = out[1] - indexPoint[1]; dist += tmp * tmp;
00172 tmp = out[2] - indexPoint[2]; dist += tmp * tmp;
00173
00174 if ( dist < bestDist )
00175 {
00176 bestIndex = it->Index();
00177 bestDist = dist;
00178 }
00179 }
00180 return bestIndex;
00181 }
00182
00183 mitk::PointSet::PointType
00184 mitk::PointSet::GetPoint( PointIdentifier id, int t ) const
00185 {
00186 PointType out;
00187 out.Fill(0);
00188
00189 if ( (unsigned int) t >= m_PointSetSeries.size() )
00190 {
00191 return out;
00192 }
00193
00194 if ( m_PointSetSeries[t]->GetPoints()->IndexExists(id) )
00195 {
00196 m_PointSetSeries[t]->GetPoint( id, &out );
00197 this->GetGeometry(t)->IndexToWorld( out, out );
00198 return out;
00199 }
00200 else
00201 {
00202 return out;
00203 }
00204 }
00205
00206
00207 bool
00208 mitk::PointSet
00209 ::GetPointIfExists( PointIdentifier id, PointType* point, int t ) const
00210 {
00211 if ( (unsigned int) t >= m_PointSetSeries.size() )
00212 {
00213 return false;
00214 }
00215
00216 if ( m_PointSetSeries[t]->GetPoints()->GetElementIfIndexExists(id, point) )
00217 {
00218 this->GetGeometry( t )->IndexToWorld( *point, *point );
00219 return true;
00220 }
00221 else
00222 {
00223 return false;
00224 }
00225 }
00226
00227
00228 void mitk::PointSet::SetPoint( PointIdentifier id, PointType point, int t )
00229 {
00230
00231 this->Expand( t+1 );
00232
00233 mitk::Point3D indexPoint;
00234 this->GetGeometry( t )->WorldToIndex( point, indexPoint );
00235 m_PointSetSeries[t]->SetPoint( id, indexPoint );
00236 PointDataType defaultPointData;
00237 defaultPointData.id = id;
00238 defaultPointData.selected = false;
00239 defaultPointData.pointSpec = mitk::PTUNDEFINED;
00240
00241 m_PointSetSeries[t]->SetPointData( id, defaultPointData );
00242
00243 m_CalculateBoundingBox = true;
00244 this->Modified();
00245 }
00246
00247
00248 void mitk::PointSet::SetPoint( PointIdentifier id, PointType point, PointSpecificationType spec, int t )
00249 {
00250
00251 this->Expand( t+1 );
00252
00253 mitk::Point3D indexPoint;
00254 this->GetGeometry( t )->WorldToIndex( point, indexPoint );
00255 m_PointSetSeries[t]->SetPoint( id, indexPoint );
00256 PointDataType defaultPointData;
00257 defaultPointData.id = id;
00258 defaultPointData.selected = false;
00259 defaultPointData.pointSpec = spec;
00260 m_PointSetSeries[t]->SetPointData( id, defaultPointData );
00261
00262 m_CalculateBoundingBox = true;
00263 this->Modified();
00264 }
00265
00266
00267 void mitk::PointSet::InsertPoint( PointIdentifier id, PointType point, int t )
00268 {
00269 if ( (unsigned int) t < m_PointSetSeries.size() )
00270 {
00271 mitk::Point3D indexPoint;
00272 mitk::Geometry3D* tempGeometry = this->GetGeometry( t );
00273 if (tempGeometry == NULL)
00274 {
00275 MITK_INFO<< __FILE__ << ", l." << __LINE__ << ": GetGeometry of "<< t <<" returned NULL!" << std::endl;
00276 return;
00277 }
00278 tempGeometry->WorldToIndex( point, indexPoint );
00279 m_PointSetSeries[t]->GetPoints()->InsertElement( id, indexPoint );
00280 PointDataType defaultPointData;
00281 defaultPointData.id = id;
00282 defaultPointData.selected = false;
00283 defaultPointData.pointSpec = mitk::PTUNDEFINED;
00284 m_PointSetSeries[t]->GetPointData()->InsertElement(id, defaultPointData);
00285
00286
00287 m_CalculateBoundingBox = true;
00288 this->Modified();
00289 }
00290 }
00291
00292
00293 void mitk::PointSet::InsertPoint( PointIdentifier id, PointType point, PointSpecificationType spec, int t )
00294 {
00295 if ( (unsigned int) t < m_PointSetSeries.size() )
00296 {
00297 mitk::Point3D indexPoint;
00298 mitk::Geometry3D* tempGeometry = this->GetGeometry( t );
00299 if (tempGeometry == NULL)
00300 {
00301 MITK_INFO<< __FILE__ << ", l." << __LINE__ << ": GetGeometry of "<< t <<" returned NULL!" << std::endl;
00302 return;
00303 }
00304 tempGeometry->WorldToIndex( point, indexPoint );
00305 m_PointSetSeries[t]->GetPoints()->InsertElement( id, indexPoint );
00306 PointDataType defaultPointData;
00307 defaultPointData.id = id;
00308 defaultPointData.selected = false;
00309 defaultPointData.pointSpec = spec;
00310 m_PointSetSeries[t]->GetPointData()->InsertElement(id, defaultPointData);
00311
00312
00313 m_CalculateBoundingBox = true;
00314 this->Modified();
00315 }
00316 }
00317
00318
00319 bool mitk::PointSet::SwapPointPosition( PointIdentifier id, bool moveUpwards, int t )
00320 {
00321 if(IndexExists(id, t) )
00322 {
00323 PointType point = GetPoint(id,t);
00324
00325 if(moveUpwards)
00326 {
00327 if(IndexExists(id-1,t))
00328 {
00329 InsertPoint(id, GetPoint(id - 1, t), t);
00330 InsertPoint(id-1,point,t);
00331 this->Modified();
00332 return true;
00333 }
00334 }
00335 else
00336 {
00337 if(IndexExists(id+1,t))
00338 {
00339 InsertPoint(id, GetPoint(id + 1, t), t);
00340 InsertPoint(id+1,point,t);
00341 this->Modified();
00342 return true;
00343 }
00344 }
00345 }
00346 return false;
00347 }
00348
00349 bool mitk::PointSet::IndexExists( int position, int t ) const
00350 {
00351 if ( (unsigned int) t < m_PointSetSeries.size() )
00352 {
00353 return m_PointSetSeries[t]->GetPoints()->IndexExists( position );
00354 }
00355 else
00356 {
00357 return false;
00358 }
00359 }
00360
00361 bool mitk::PointSet::GetSelectInfo( int position, int t ) const
00362 {
00363 if ( this->IndexExists( position, t ) )
00364 {
00365 PointDataType pointData = { 0, false, PTUNDEFINED };
00366 m_PointSetSeries[t]->GetPointData( position, &pointData );
00367 return pointData.selected;
00368 }
00369 else
00370 {
00371 return false;
00372 }
00373 }
00374
00375
00376 void mitk::PointSet::SetSelectInfo( int position, bool selected, int t )
00377 {
00378 if ( this->IndexExists( position, t ) )
00379 {
00380
00381 ScalarType timeInMS = this->GetTimeSlicedGeometry()->TimeStepToMS( t );
00382
00383
00384 Point3D point = this->GetPoint( position, t );
00385
00386 PointOperation* op;
00387 if (selected)
00388 {
00389 op = new mitk::PointOperation(OpSELECTPOINT, timeInMS, point, position );
00390 }
00391 else
00392 {
00393 op = new mitk::PointOperation(OpDESELECTPOINT, timeInMS, point, position );
00394 }
00395
00396 this->ExecuteOperation( op );
00397 }
00398 }
00399
00400 mitk::PointSpecificationType mitk::PointSet::GetSpecificationTypeInfo( int position, int t ) const
00401 {
00402 if ( this->IndexExists( position, t ) )
00403 {
00404 PointDataType pointData = { 0, false, PTUNDEFINED };
00405 m_PointSetSeries[t]->GetPointData( position, &pointData );
00406 return pointData.pointSpec;
00407 }
00408 else
00409 {
00410 return PTUNDEFINED;
00411 }
00412 }
00413
00414 int mitk::PointSet::GetNumberOfSelected( int t ) const
00415 {
00416 if ( (unsigned int) t >= m_PointSetSeries.size() )
00417 {
00418 return 0;
00419 }
00420
00421 int numberOfSelected = 0;
00422 PointDataIterator it;
00423 for ( it = m_PointSetSeries[t]->GetPointData()->Begin();
00424 it != m_PointSetSeries[t]->GetPointData()->End();
00425 it++ )
00426 {
00427 if (it->Value().selected == true)
00428 {
00429 ++numberOfSelected;
00430 }
00431 }
00432
00433 return numberOfSelected;
00434 }
00435
00436
00437 int mitk::PointSet::SearchSelectedPoint( int t ) const
00438 {
00439 if ( (unsigned int) t >= m_PointSetSeries.size() )
00440 {
00441 return -1;
00442 }
00443
00444 PointDataIterator it;
00445 for ( it = m_PointSetSeries[t]->GetPointData()->Begin();
00446 it != m_PointSetSeries[t]->GetPointData()->End();
00447 it++ )
00448 {
00449 if ( it->Value().selected == true )
00450 {
00451 return it->Index();
00452 }
00453 }
00454 return -1;
00455 }
00456
00457 void mitk::PointSet::ExecuteOperation( Operation* operation )
00458 {
00459 int timeStep = -1;
00460
00461 mitkCheckOperationTypeMacro(PointOperation, operation, pointOp);
00462
00463 if ( pointOp )
00464 {
00465 timeStep = this->GetTimeSlicedGeometry()
00466 ->MSToTimeStep( pointOp->GetTimeInMS() );
00467 }
00468
00469 if ( timeStep < 0 )
00470 {
00471 MITK_ERROR << "Time step (" << timeStep << ") outside of PointSet time bounds" << std::endl;
00472 return;
00473 }
00474
00475 switch (operation->GetOperationType())
00476 {
00477 case OpNOTHING:
00478 break;
00479
00480 case OpINSERT:
00481 {
00482 int position = pointOp->GetIndex();
00483
00484 PointType pt;
00485 pt.CastFrom(pointOp->GetPoint());
00486
00487
00488 mitk::Geometry3D* geometry = this->GetGeometry( timeStep );
00489 if (geometry == NULL)
00490 {
00491 MITK_INFO<<"GetGeometry returned NULL!\n";
00492 return;
00493 }
00494 geometry->WorldToIndex(pt, pt);
00495
00496 m_PointSetSeries[timeStep]->GetPoints()->InsertElement(position, pt);
00497
00498 PointDataType pointData =
00499 {
00500 pointOp->GetIndex(),
00501 pointOp->GetSelected(),
00502 pointOp->GetPointType()
00503 };
00504
00505 m_PointSetSeries[timeStep]->GetPointData()
00506 ->InsertElement(position, pointData);
00507
00508 this->Modified();
00509
00510
00511 m_CalculateBoundingBox = true;
00512
00513 this->InvokeEvent( PointSetAddEvent() );
00514 this->OnPointSetChange();
00515 }
00516 break;
00517
00518 case OpMOVE:
00519 {
00520 PointType pt;
00521 pt.CastFrom(pointOp->GetPoint());
00522
00523
00524 this->GetGeometry( timeStep )->WorldToIndex(pt, pt);
00525
00526
00527 m_PointSetSeries[timeStep]->SetPoint(pointOp->GetIndex(), pt);
00528
00529
00530
00531 PointDataType pointData;
00532 if ( !m_PointSetSeries[timeStep]->GetPointData( pointOp->GetIndex(), &pointData ) )
00533 {
00534 m_PointSetSeries[timeStep]->SetPointData( pointOp->GetIndex(), pointData );
00535 }
00536
00537 this->OnPointSetChange();
00538
00539 this->Modified();
00540
00541
00542 m_CalculateBoundingBox = true;
00543
00544 this->InvokeEvent( PointSetMoveEvent() );
00545 }
00546 break;
00547
00548 case OpREMOVE:
00549 {
00550 m_PointSetSeries[timeStep]->GetPoints()->DeleteIndex((unsigned)pointOp->GetIndex());
00551 m_PointSetSeries[timeStep]->GetPointData()->DeleteIndex((unsigned)pointOp->GetIndex());
00552
00553 this->OnPointSetChange();
00554
00555 this->Modified();
00556
00557 m_CalculateBoundingBox = true;
00558
00559 this->InvokeEvent( PointSetRemoveEvent() );
00560 }
00561 break;
00562
00563 case OpSELECTPOINT:
00564 {
00565 PointDataType pointData = {0, false, PTUNDEFINED};
00566 m_PointSetSeries[timeStep]->GetPointData(pointOp->GetIndex(), &pointData);
00567 pointData.selected = true;
00568 m_PointSetSeries[timeStep]->SetPointData(pointOp->GetIndex(), pointData);
00569 this->Modified();
00570 }
00571 break;
00572
00573 case OpDESELECTPOINT:
00574 {
00575 PointDataType pointData = {0, false, PTUNDEFINED};
00576 m_PointSetSeries[timeStep]->GetPointData(pointOp->GetIndex(), &pointData);
00577 pointData.selected = false;
00578 m_PointSetSeries[timeStep]->SetPointData(pointOp->GetIndex(), pointData);
00579 this->Modified();
00580 }
00581 break;
00582
00583 case OpSETPOINTTYPE:
00584 {
00585 PointDataType pointData = {0, false, PTUNDEFINED};
00586 m_PointSetSeries[timeStep]->GetPointData(pointOp->GetIndex(), &pointData);
00587 pointData.pointSpec = pointOp->GetPointType();
00588 m_PointSetSeries[timeStep]->SetPointData(pointOp->GetIndex(), pointData);
00589 this->Modified();
00590 }
00591 break;
00592
00593 case OpMOVEPOINTUP:
00594 {
00595 PointIdentifier currentID = pointOp->GetIndex();
00596
00597 PointsContainer::STLContainerType points = m_PointSetSeries[timeStep]->GetPoints()->CastToSTLContainer();
00598 PointsContainer::STLContainerType::iterator it = points.find(currentID);
00599 if (it == points.end())
00600 break;
00601 if (it == points.begin())
00602 break;
00603
00604
00605 --it;
00606 PointIdentifier prevID = it->first;
00607 if (this->SwapPointContents(prevID, currentID, timeStep) == true)
00608 this->Modified();
00609 }
00610 break;
00611 case OpMOVEPOINTDOWN:
00612 {
00613 PointIdentifier currentID = pointOp->GetIndex();
00614
00615 PointsContainer::STLContainerType points = m_PointSetSeries[timeStep]->GetPoints()->CastToSTLContainer();
00616 PointsContainer::STLContainerType::iterator it = points.find(currentID);
00617 if (it == points.end())
00618 break;
00619 ++it;
00620 if (it == points.end())
00621 break;
00622
00623
00624 PointIdentifier nextID = it->first;
00625 if (this->SwapPointContents(nextID, currentID, timeStep) == true)
00626 this->Modified();
00627 }
00628 break;
00629
00630 default:
00631 itkWarningMacro("mitkPointSet could not understrand the operation. Please check!");
00632 break;
00633 }
00634
00635
00636
00637
00638
00639 mitk::OperationEndEvent endevent(operation);
00640 ((const itk::Object*)this)->InvokeEvent(endevent);
00641
00642
00643
00644
00645 }
00646
00647
00648 void mitk::PointSet::UpdateOutputInformation()
00649 {
00650 if ( this->GetSource( ) )
00651 {
00652 this->GetSource( )->UpdateOutputInformation( );
00653 }
00654
00655
00656
00657
00658
00659 mitk::TimeSlicedGeometry* timeGeometry = GetTimeSlicedGeometry();
00660 if ( timeGeometry->GetTimeSteps() != m_PointSetSeries.size() )
00661 {
00662 itkExceptionMacro(<<"timeGeometry->GetTimeSteps() != m_PointSetSeries.size() -- use Initialize(timeSteps) with correct number of timeSteps!");
00663 }
00664
00665
00666 mitk::ScalarType nullpoint[]={0,0,0,0,0,0};
00667 BoundingBox::BoundsArrayType itkBoundsNull(nullpoint);
00668
00669
00670
00671
00672
00673 if (m_CalculateBoundingBox)
00674 {
00675 for ( unsigned int i = 0 ; i < m_PointSetSeries.size() ; ++i )
00676 {
00677 const DataType::BoundingBoxType *bb = m_PointSetSeries[i]->GetBoundingBox();
00678 BoundingBox::BoundsArrayType itkBounds = bb->GetBounds();
00679
00680 if ( m_PointSetSeries[i].IsNull() || (m_PointSetSeries[i]->GetNumberOfPoints() == 0)
00681 || (itkBounds == itkBoundsNull) )
00682 {
00683 itkBounds = itkBoundsNull;
00684 continue;
00685 }
00686
00687
00688 for ( unsigned int j = 0; j < 3; ++j )
00689 {
00690 if ( itkBounds[j*2+1] - itkBounds[j*2] < 1.0 )
00691 {
00692 BoundingBox::CoordRepType center =
00693 (itkBounds[j*2] + itkBounds[j*2+1]) / 2.0;
00694 itkBounds[j*2] = center - 0.5;
00695 itkBounds[j*2+1] = center + 0.5;
00696 }
00697 }
00698 this->GetGeometry(i)->SetBounds(itkBounds);
00699 }
00700 m_CalculateBoundingBox = false;
00701 }
00702 this->GetTimeSlicedGeometry()->UpdateInformation();
00703 }
00704
00705 void mitk::PointSet::SetRequestedRegionToLargestPossibleRegion()
00706 {
00707 }
00708
00709 bool mitk::PointSet::RequestedRegionIsOutsideOfTheBufferedRegion()
00710 {
00711 return false;
00712 }
00713
00714 bool mitk::PointSet::VerifyRequestedRegion()
00715 {
00716 return true;
00717 }
00718
00719 void mitk::PointSet::SetRequestedRegion( itk::DataObject * )
00720 {
00721 }
00722
00723
00724 void mitk::PointSet::PrintSelf( std::ostream& os, itk::Indent indent ) const
00725 {
00726 Superclass::PrintSelf(os, indent);
00727
00728 os << indent << "Number timesteps: " << m_PointSetSeries.size() << "\n";
00729 unsigned int i = 0;
00730 for (PointSetSeries::const_iterator it = m_PointSetSeries.begin(); it != m_PointSetSeries.end(); ++it)
00731 {
00732 os << indent << "Timestep " << i++ << ": \n";
00733 MeshType::Pointer ps = *it;
00734 itk::Indent nextIndent = indent.GetNextIndent();
00735 ps->Print(os, nextIndent);
00736 MeshType::PointsContainer* points = ps->GetPoints();
00737 MeshType::PointDataContainer* datas = ps->GetPointData();
00738 MeshType::PointDataContainer::Iterator dataIterator = datas->Begin();
00739 for (MeshType::PointsContainer::Iterator pointIterator = points->Begin();
00740 pointIterator != points->End();
00741 ++pointIterator, ++dataIterator)
00742 {
00743 os << nextIndent << "Point " << pointIterator->Index() << ": [";
00744 os << pointIterator->Value().GetElement(0);
00745 for (unsigned int i = 1; i < PointType::GetPointDimension(); ++i)
00746 {
00747 os << ", " << pointIterator->Value().GetElement(i);
00748 }
00749 os << "]";
00750 os << ", selected: " << dataIterator->Value().selected << ", point spec: " << dataIterator->Value().pointSpec << "\n";
00751 }
00752 }
00753 }
00754
00755 bool mitk::PointSet::SwapPointContents(PointIdentifier id1, PointIdentifier id2, int timeStep)
00756 {
00757
00758 PointType p1;
00759 if (m_PointSetSeries[timeStep]->GetPoint(id1, &p1) == false)
00760 return false;
00761 PointDataType data1;
00762 if (m_PointSetSeries[timeStep]->GetPointData(id1, &data1) == false)
00763 return false;
00764 PointType p2;
00765 if (m_PointSetSeries[timeStep]->GetPoint(id2, &p2) == false)
00766 return false;
00767 PointDataType data2;
00768 if (m_PointSetSeries[timeStep]->GetPointData(id2, &data2) == false)
00769 return false;
00770
00771 m_PointSetSeries[timeStep]->SetPoint(id1, p2);
00772 m_PointSetSeries[timeStep]->SetPointData(id1, data2);
00773 m_PointSetSeries[timeStep]->SetPoint(id2, p1);
00774 m_PointSetSeries[timeStep]->SetPointData(id2, data1);
00775 return true;
00776 }