diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp index a154ddedc7..1df0672393 100644 --- a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp +++ b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp @@ -1,705 +1,642 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-07-08 11:04:08 +0200 (Mi, 08 Jul 2009) $ Version: $Revision: 18029 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkPlanarFigure.h" #include "mitkGeometry2D.h" #include "mitkProperties.h" #include "algorithm" mitk::PlanarFigure::PlanarFigure() : m_FigurePlaced( false ), - m_HoveringControlPointVisible( false ), - m_SelectedControlPoint( -1 ), - m_Geometry2D( NULL ), - m_PolyLineUpToDate(false), - m_HelperLinesUpToDate(false), - m_FeaturesUpToDate(false), - m_FeaturesMTime( 0 ) -{ - m_ControlPoints = VertexContainerType::New(); - m_HoveringControlPoint = VertexContainerType::New(); - m_PolyLines = VertexContainerVectorType::New(); - m_HelperPolyLines = VertexContainerVectorType::New(); +m_PreviewControlPointVisible( false ), +m_SelectedControlPoint( -1 ), +m_Geometry2D( NULL ), +m_PolyLineUpToDate(false), +m_HelperLinesUpToDate(false), +m_FeaturesUpToDate(false), +m_FeaturesMTime( 0 ) +{ m_HelperPolyLinesToBePainted = BoolContainerType::New(); this->SetProperty( "closed", mitk::BoolProperty::New( false ) ); // Currently only single-time-step geometries are supported this->InitializeTimeSlicedGeometry( 1 ); } mitk::PlanarFigure::~PlanarFigure() { } void mitk::PlanarFigure::SetGeometry2D( mitk::Geometry2D *geometry ) { this->SetGeometry( geometry ); m_Geometry2D = geometry; } const mitk::Geometry2D *mitk::PlanarFigure::GetGeometry2D() const { return m_Geometry2D; } bool mitk::PlanarFigure::IsClosed() const { mitk::BoolProperty* closed = dynamic_cast< mitk::BoolProperty* >( this->GetProperty( "closed" ).GetPointer() ); if ( closed != NULL ) { return closed->GetValue(); } return false; } void mitk::PlanarFigure::PlaceFigure( const mitk::Point2D& point ) { + //m_ControlPoints.clear(); + //m_NumberOfControlPoints = 2; + for ( unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i ) { - m_ControlPoints->InsertElement( i, this->ApplyControlPointConstraints( i, point ) ); - m_NewControlPoints.push_back( point ); + m_ControlPoints.push_back( point ); } m_FigurePlaced = true; m_SelectedControlPoint = 1; } -bool mitk::PlanarFigure::AddControlPoint( const mitk::Point2D& point ) +bool mitk::PlanarFigure::AddControlPoint( const mitk::Point2D& point, int position ) { if ( m_NumberOfControlPoints < this->GetMaximumNumberOfControlPoints() ) { - m_ControlPoints->InsertElement( m_NumberOfControlPoints, - this->ApplyControlPointConstraints( m_NumberOfControlPoints, point ) ); - m_NewControlPoints.push_back( point ); + if ( position == -1 || position > m_NumberOfControlPoints-1 ) + { + m_ControlPoints.push_back( this->ApplyControlPointConstraints( m_NumberOfControlPoints, point ) ); + m_SelectedControlPoint = m_NumberOfControlPoints; + } + else + { + ControlPointListType::iterator iter = m_ControlPoints.begin() + position; + m_ControlPoints.insert( iter, this->ApplyControlPointConstraints( m_NumberOfControlPoints, point ) ); + m_SelectedControlPoint = m_NumberOfControlPoints; + } + + m_PolyLineUpToDate = false; + m_HelperLinesUpToDate = false; + m_FeaturesUpToDate = false; + ++m_NumberOfControlPoints; - ++m_SelectedControlPoint; return true; } else { return false; } } bool mitk::PlanarFigure::SetControlPoint( unsigned int index, const Point2D& point, bool createIfDoesNotExist ) { bool controlPointSetCorrectly = false; if (createIfDoesNotExist) { - m_ControlPoints->InsertElement( index, this->ApplyControlPointConstraints( index, point ) ); - if ( m_NumberOfControlPoints <= index ) { - m_NewControlPoints.push_back( point ); - m_NumberOfControlPoints = index + 1; + m_ControlPoints.push_back( this->ApplyControlPointConstraints( index, point ) ); + m_NumberOfControlPoints++; } else { - m_NewControlPoints.at( index ) = point; + m_ControlPoints.at( index ) = this->ApplyControlPointConstraints( index, point ); } controlPointSetCorrectly = true; } else if ( index < m_NumberOfControlPoints ) { - m_ControlPoints->InsertElement( index, this->ApplyControlPointConstraints( index, point ) ); - m_NewControlPoints.at( index ) = point; + m_ControlPoints.at( index ) = this->ApplyControlPointConstraints( index, point ); controlPointSetCorrectly = true; } - //else - //{ - // return false; - //} + else + { + return false; + } if ( controlPointSetCorrectly ) { m_PolyLineUpToDate = false; m_HelperLinesUpToDate = false; m_FeaturesUpToDate = false; } return controlPointSetCorrectly; } bool mitk::PlanarFigure::SetCurrentControlPoint( const Point2D& point ) { if ( (m_SelectedControlPoint < 0) || (m_SelectedControlPoint >= (int)m_NumberOfControlPoints) ) { return false; } return this->SetControlPoint(m_SelectedControlPoint, point, false); } unsigned int mitk::PlanarFigure::GetNumberOfControlPoints() const { return m_NumberOfControlPoints; } - - bool mitk::PlanarFigure::SelectControlPoint( unsigned int index ) { if ( index < this->GetNumberOfControlPoints() ) { m_SelectedControlPoint = index; return true; } else { return false; } } void mitk::PlanarFigure::DeselectControlPoint() { m_SelectedControlPoint = -1; } -void mitk::PlanarFigure::SetHoveringControlPoint( const Point2D& point ) -{ - if ( m_HoveringControlPoint->Size() == 0 ) - { - m_HoveringControlPoint->InsertElement( 0, point ); - } - else - { - m_HoveringControlPoint->SetElement( 0, point ); - } - m_HoveringControlPointVisible = true; -} - -void mitk::PlanarFigure::ResetHoveringContolPoint() +void mitk::PlanarFigure::SetPreviewControlPoint( const Point2D& point ) { - if ( m_HoveringControlPoint->Size() > 0 ) - { - m_HoveringControlPointVisible = false; - m_HoveringControlPoint->DeleteIndex( 0 ); - } + m_PreviewControlPoint = point; + m_PreviewControlPointVisible = true; } -mitk::PlanarFigure::VertexContainerType::Pointer mitk::PlanarFigure::GetHoveringControlPoint() +void mitk::PlanarFigure::ResetPreviewContolPoint() { - return m_HoveringControlPoint; + m_PreviewControlPointVisible = false; } -bool mitk::PlanarFigure::IsHoveringControlPointVisible() +mitk::Point2D mitk::PlanarFigure::GetPreviewControlPoint() { - return m_HoveringControlPointVisible; + return m_PreviewControlPoint; } - -const mitk::PlanarFigure::VertexContainerType * -mitk::PlanarFigure::GetControlPoints() const +bool mitk::PlanarFigure::IsPreviewControlPointVisible() { - return m_ControlPoints; + return m_PreviewControlPointVisible; } - -mitk::PlanarFigure::VertexContainerType * -mitk::PlanarFigure::GetControlPoints() -{ - return m_ControlPoints; -} - - mitk::Point2D mitk::PlanarFigure::GetControlPoint( unsigned int index ) const { if ( index < m_NumberOfControlPoints ) { - //return m_ControlPoints->ElementAt( index ); - return m_NewControlPoints.at( index ); + return m_ControlPoints.at( index ); } itkExceptionMacro( << "GetControlPoint(): Invalid index!" ); } mitk::Point3D mitk::PlanarFigure::GetWorldControlPoint( unsigned int index ) const { Point3D point3D; if ( (m_Geometry2D != NULL) && (index < m_NumberOfControlPoints) ) { - //m_Geometry2D->Map( m_ControlPoints->ElementAt( index ), point3D ); - m_Geometry2D->Map( m_NewControlPoints.at( index ), point3D ); + m_Geometry2D->Map( m_ControlPoints.at( index ), point3D ); return point3D; } itkExceptionMacro( << "GetWorldControlPoint(): Invalid index!" ); } -mitk::PlanarFigure::PolyLineType +const mitk::PlanarFigure::PolyLineType mitk::PlanarFigure::GetPolyLine(unsigned int index) { mitk::PlanarFigure::PolyLineType polyLine; - if ( m_NewPolyLines.size() > index ) + if ( m_PolyLines.size() > index ) { if ( !m_PolyLineUpToDate ) { this->GeneratePolyLine(); m_PolyLineUpToDate = true; } - polyLine = m_NewPolyLines.at( index ); + polyLine = m_PolyLines.at( index ); } return polyLine; - - //if ( !m_PolyLines->IndexExists( index ) || !m_PolyLineUpToDate ) // (m_PolyLines->ElementAt( index )->GetMTime() < m_ControlPoints->GetMTime()) ) - //{ - // this->GeneratePolyLine(); - // m_PolyLineUpToDate = true; - //} - - //return m_PolyLines->ElementAt( index ); } const mitk::PlanarFigure::PolyLineType mitk::PlanarFigure::GetPolyLine(unsigned int index) const { - return m_NewPolyLines.at( index ); - //return m_PolyLines->ElementAt( index ); + return m_PolyLines.at( index ); } - -//const mitk::PlanarFigure::VertexContainerType * -//mitk::PlanarFigure::GetHelperPolyLine(unsigned int index, double mmPerDisplayUnit, unsigned int displayHeight) -//{ -// if ((m_HelperPolyLines->ElementAt( index )) && !m_HelperLinesUpToDate ) //(m_HelperPolyLines->ElementAt( index )->GetMTime() < m_ControlPoints->GetMTime()) ) -// { -// this->GenerateHelperPolyLine(mmPerDisplayUnit, displayHeight); -// m_HelperLinesUpToDate = true; -// } -// -// return m_HelperPolyLines->ElementAt( index ); -//} +void mitk::PlanarFigure::ClearPolyLines() +{ + for ( int i=0; iGenerateHelperPolyLine(mmPerDisplayUnit, displayHeight); m_HelperLinesUpToDate = true; } - helperPolyLine = m_NewHelperPolyLines.at(index); + helperPolyLine = m_HelperPolyLines.at(index); } return helperPolyLine; +} - //if ((m_HelperPolyLines->ElementAt( index )) && !m_HelperLinesUpToDate ) //(m_HelperPolyLines->ElementAt( index )->GetMTime() < m_ControlPoints->GetMTime()) ) - //{ - // this->GenerateHelperPolyLine(mmPerDisplayUnit, displayHeight); - // m_HelperLinesUpToDate = true; - //} - - //return m_HelperPolyLines->ElementAt( index ); - +void mitk::PlanarFigure::ClearHelperPolyLines() +{ + for ( int i=0; iGetMTime() ) + if ( !m_FeaturesUpToDate ) { this->EvaluateFeaturesInternal(); - + m_FeaturesUpToDate = true; - //m_FeaturesMTime = m_ControlPoints->GetMTime(); } } void mitk::PlanarFigure::UpdateOutputInformation() { // Bounds are NOT calculated here, since the Geometry2D defines a fixed // frame (= bounds) for the planar figure. Superclass::UpdateOutputInformation(); this->GetTimeSlicedGeometry()->UpdateInformation(); } void mitk::PlanarFigure::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::PlanarFigure::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::PlanarFigure::VerifyRequestedRegion() { return true; } void mitk::PlanarFigure::SetRequestedRegion( itk::DataObject * /*data*/ ) { } void mitk::PlanarFigure::ResetNumberOfControlPoints( int numberOfControlPoints ) { m_NumberOfControlPoints = numberOfControlPoints; } mitk::Point2D mitk::PlanarFigure::ApplyControlPointConstraints( unsigned int /*index*/, const Point2D& point ) { if ( m_Geometry2D == NULL ) { return point; } Point2D indexPoint; m_Geometry2D->WorldToIndex( point, indexPoint ); BoundingBox::BoundsArrayType bounds = m_Geometry2D->GetBounds(); if ( indexPoint[0] < bounds[0] ) { indexPoint[0] = bounds[0]; } if ( indexPoint[0] > bounds[1] ) { indexPoint[0] = bounds[1]; } if ( indexPoint[1] < bounds[2] ) { indexPoint[1] = bounds[2]; } if ( indexPoint[1] > bounds[3] ) { indexPoint[1] = bounds[3]; } - + Point2D constrainedPoint; m_Geometry2D->IndexToWorld( indexPoint, constrainedPoint ); return constrainedPoint; } unsigned int mitk::PlanarFigure::AddFeature( const char *featureName, const char *unitName ) { unsigned int index = m_Features.size(); - + Feature newFeature( featureName, unitName ); m_Features.push_back( newFeature ); return index; } void mitk::PlanarFigure::SetFeatureName( unsigned int index, const char *featureName ) { if ( index < m_Features.size() ) { m_Features[index].Name = featureName; } } void mitk::PlanarFigure::SetFeatureUnit( unsigned int index, const char *unitName ) { if ( index < m_Features.size() ) { m_Features[index].Unit = unitName; } } void mitk::PlanarFigure::SetQuantity( unsigned int index, double quantity ) { if ( index < m_Features.size() ) { m_Features[index].Quantity = quantity; } } void mitk::PlanarFigure::ActivateFeature( unsigned int index ) { if ( index < m_Features.size() ) { m_Features[index].Active = true; } } void mitk::PlanarFigure::DeactivateFeature( unsigned int index ) { if ( index < m_Features.size() ) { m_Features[index].Active = false; } } void mitk::PlanarFigure::InitializeTimeSlicedGeometry( unsigned int timeSteps ) { mitk::TimeSlicedGeometry::Pointer timeGeometry = this->GetTimeSlicedGeometry(); mitk::Geometry2D::Pointer geometry2D = mitk::Geometry2D::New(); geometry2D->Initialize(); if ( timeSteps > 1 ) { mitk::ScalarType timeBounds[] = {0.0, 1.0}; geometry2D->SetTimeBounds( timeBounds ); } // The geometry is propagated automatically to all time steps, // if EvenlyTimed is true... timeGeometry->InitializeEvenlyTimed( geometry2D, timeSteps ); } void mitk::PlanarFigure::PrintSelf( std::ostream& os, itk::Indent indent) const { Superclass::PrintSelf( os, indent ); os << indent << this->GetNameOfClass() << ":\n"; - + if (this->IsClosed()) os << indent << "This figure is closed\n"; else os << indent << "This figure is not closed\n"; os << indent << "Minimum number of control points: " << this->GetMinimumNumberOfControlPoints() << std::endl; os << indent << "Maximum number of control points: " << this->GetMaximumNumberOfControlPoints() << std::endl; os << indent << "Current number of control points: " << this->GetNumberOfControlPoints() << std::endl; os << indent << "Control points:" << std::endl; mitk::PlanarFigure::VertexContainerType::ConstIterator it; for ( unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i ) { - os << indent.GetNextIndent() << i << ": " << m_ControlPoints->ElementAt( i ) << std::endl; - os << indent.GetNextIndent() << i << ": " << m_NewControlPoints.at( i ) << std::endl; + //os << indent.GetNextIndent() << i << ": " << m_ControlPoints->ElementAt( i ) << std::endl; + os << indent.GetNextIndent() << i << ": " << m_ControlPoints.at( i ) << std::endl; } os << indent << "Geometry:\n"; this->GetGeometry2D()->Print(os, indent.GetNextIndent()); } unsigned short mitk::PlanarFigure::GetPolyLinesSize() { - if ( !m_PolyLineUpToDate ) //m_PolyLines->GetMTime() < m_ControlPoints->GetMTime() ) + if ( !m_PolyLineUpToDate ) { this->GeneratePolyLine(); m_PolyLineUpToDate = true; } - return m_NewPolyLines.size(); - //return m_PolyLines->size(); + return m_PolyLines.size(); } unsigned short mitk::PlanarFigure::GetHelperPolyLinesSize() { - return m_NewHelperPolyLines.size(); - //return m_HelperPolyLines->size(); + return m_HelperPolyLines.size(); } bool mitk::PlanarFigure::IsHelperToBePainted(unsigned int index) { return m_HelperPolyLinesToBePainted->GetElement( index ); } bool mitk::PlanarFigure::ResetOnPointSelect() { return false; } void mitk::PlanarFigure::RemoveControlPoint( unsigned int index ) { - if ( index > m_NewControlPoints.size() ) + if ( index > m_ControlPoints.size() ) return; - if ( (m_NewControlPoints.size() -1) < this->GetMinimumNumberOfControlPoints() ) + if ( (m_ControlPoints.size() -1) < this->GetMinimumNumberOfControlPoints() ) return; ControlPointListType::iterator iter; - iter = m_NewControlPoints.begin() + index; + iter = m_ControlPoints.begin() + index; - m_NewControlPoints.erase( iter ); + m_ControlPoints.erase( iter ); m_PolyLineUpToDate = false; m_HelperLinesUpToDate = false; m_FeaturesUpToDate = false; - //if ( iter != vector.end() ) - //{ - // m_ControlPoints->erase( iter ); - // m_NumberOfControlPoints--; - //} - - //if ( m_ControlPoints->Size() < m_NumberOfControlPoints ) - //{ - //} + --m_NumberOfControlPoints; } void mitk::PlanarFigure::RemoveLastControlPoint() { - RemoveControlPoint( m_NewControlPoints.size()-1 ); - - //m_ControlPoints->DeleteIndex( this->GetNumberOfControlPoints()-1 ); - //this->ResetNumberOfControlPoints( this->GetNumberOfControlPoints()-1 ); - //this->GeneratePolyLine(); + RemoveControlPoint( m_ControlPoints.size()-1 ); } void mitk::PlanarFigure::DeepCopy(Self::Pointer oldFigure) { //DeepCopy only same types of planar figures //Notice to get typeid polymorph you have to use the *operator if(typeid(*oldFigure) != typeid(*this)) { itkExceptionMacro( << "DeepCopy(): Inconsistent type of source and destination figure!" ); return; } + m_ControlPoints.clear(); + this->ClearPolyLines(); + this->ClearHelperPolyLines(); + // clone base data members SetPropertyList(oldFigure->GetPropertyList()->Clone()); /// deep copy members m_FigurePlaced = oldFigure->m_FigurePlaced; m_SelectedControlPoint = oldFigure->m_SelectedControlPoint; m_FeaturesMTime = oldFigure->m_FeaturesMTime; m_Features = oldFigure->m_Features; m_NumberOfControlPoints = oldFigure->m_NumberOfControlPoints; //copy geometry 2D of planar figure SetGeometry2D((mitk::Geometry2D*)oldFigure->m_Geometry2D->Clone().GetPointer()); - - m_ControlPoints = VertexContainerType::New(); - for(unsigned long index=0; index < oldFigure->m_ControlPoints->Size(); index++) + + for(unsigned long index=0; index < oldFigure->GetNumberOfControlPoints(); index++) { - m_ControlPoints->InsertElement(index, oldFigure->m_ControlPoints->ElementAt( index )); + m_ControlPoints.push_back( oldFigure->GetControlPoint( index )); } //After setting the control points we can generate the polylines this->GeneratePolyLine(); } void mitk::PlanarFigure::SetNumberOfPolyLines( unsigned int numberOfPolyLines ) { - m_NewPolyLines.resize(numberOfPolyLines); + m_PolyLines.resize(numberOfPolyLines); } void mitk::PlanarFigure::SetNumberOfHelperPolyLines( unsigned int numberOfHerlperPolyLines ) { - m_NewHelperPolyLines.resize(numberOfHerlperPolyLines); + m_HelperPolyLines.resize(numberOfHerlperPolyLines); } void mitk::PlanarFigure::AppendPointToPolyLine( unsigned int index, PolyLineElement element ) { - m_NewPolyLines.at( index ).push_back( element ); + m_PolyLines.at( index ).push_back( element ); } void mitk::PlanarFigure::AppendPointToHelperPolyLine( unsigned int index, PolyLineElement element ) { - m_NewHelperPolyLines.at( index ).push_back( element ); -} - - -mitk::PlanarFigure::PolyLineType::const_iterator mitk::PlanarFigure::GetFirstElementOfPolyLine( unsigned int index ) const -{ - return m_NewPolyLines.at( index ).begin(); -} - -mitk::PlanarFigure::PolyLineType::const_iterator mitk::PlanarFigure::GetLastElementOfPolyLine( unsigned int index ) const -{ - return m_NewPolyLines.at( index ).end(); + m_HelperPolyLines.at( index ).push_back( element ); } const mitk::PlanarFigure::PolyLineType mitk::PlanarFigure::GetPolyline( int index ) const { - return m_NewPolyLines.at( index ); + return m_PolyLines.at( index ); } -//ControlPointListType::const_iterator mitk::PlanarFigure::GetSelectedControlPoint() const -//{ -// return m_NewControlPoints.begin(); -//} \ No newline at end of file diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h index 8362a52461..081adc6370 100644 --- a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h +++ b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h @@ -1,385 +1,387 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-05-13 18:06:46 +0200 (Mi, 13 Mai 2009) $ Version: $Revision: 17258 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _MITK_PLANAR_FIGURE_H_ #define _MITK_PLANAR_FIGURE_H_ #include "PlanarFigureExports.h" #include "mitkBaseData.h" #include "mitkCommon.h" #include namespace mitk { class Geometry2D; /** * \brief Base-class for geometric planar (2D) figures, such as * lines, circles, rectangles, polygons, etc. * * \warning Currently does not support time-resolved data handling * * Behavior and appearance of PlanarFigures are controlled by various properties; for a detailed * list of appearance properties see mitk::PlanarFigureMapper2D * * The following properties control general PlanarFigure behavior: * *
    *
  • "selected": true if the planar figure is selected *
  • "planarfigure.ishovering": true if the mouse "hovers" over the planar figure *
  • "planarfigure.iseditable": true if the planar figure can be edited (otherwise, * it can only be picked/selected, but its control points cannot be edited); default is true *
* * * TODO: Implement local 2D transform (including center of rotation...) * */ class PlanarFigure_EXPORT PlanarFigure : public BaseData { public: mitkClassMacro( PlanarFigure, BaseData ); struct PolyLineElement { PolyLineElement( Point2D point, int index ) : Point( point ), Index( index ) { }; Point2D Point; int Index; - bool IsToBePainted; }; typedef itk::VectorContainer< unsigned long, mitk::Point2D > VertexContainerType; typedef itk::VectorContainer< unsigned long, VertexContainerType::Pointer> VertexContainerVectorType; typedef itk::VectorContainer< unsigned long, bool> BoolContainerType; typedef std::deque< Point2D > ControlPointListType; typedef std::list< PolyLineElement > PolyLineType; /** \brief Sets the 2D geometry on which this figure will be placed. * * In most cases, this is a Geometry already owned by another object, e.g. * describing the slice of the image on which measurements will be * performed. */ virtual void SetGeometry2D( mitk::Geometry2D *geometry ); /** \brief Returns (previously set) 2D geometry of this figure. */ virtual const Geometry2D *GetGeometry2D() const; /** \brief True if the planar figure is closed. * * Default is false. The "closed" boolean property must be set in sub-classes. */ virtual bool IsClosed() const; /** \brief True if the planar figure has been placed (and can be * displayed/interacted with). */ virtual bool IsPlaced() const { return m_FigurePlaced; }; /** \brief Place figure at the given point (in 2D index coordinates) onto * the given 2D geometry. * * By default, the first two control points of the figure are set to the * passed point. Further points can be set via AddControlPoint(), if the * current number of control points is below the maximum number of control * points. * * Can be re-implemented in sub-classes as needed. */ virtual void PlaceFigure( const Point2D& point ); - virtual bool AddControlPoint( const Point2D& point ); + virtual bool AddControlPoint( const Point2D& point, int index = -1 ); virtual bool SetControlPoint( unsigned int index, const Point2D& point, bool createIfDoesNotExist = false); virtual bool SetCurrentControlPoint( const Point2D& point ); /** \brief Returns the current number of 2D control points defining this figure. */ unsigned int GetNumberOfControlPoints() const; /** \brief Returns the minimum number of control points needed to represent * this figure. * * Must be implemented in sub-classes. */ virtual unsigned int GetMinimumNumberOfControlPoints() const = 0; /** \brief Returns the maximum number of control points allowed for * this figure (e.g. 3 for triangles). * * Must be implemented in sub-classes. */ virtual unsigned int GetMaximumNumberOfControlPoints() const = 0; /** \brief Selects currently active control points. */ virtual bool SelectControlPoint( unsigned int index ); /** \brief Deselect control point; no control point active. */ virtual void DeselectControlPoint(); /** \brief Return currently selected control point. */ virtual int GetSelectedControlPoint() const { return m_SelectedControlPoint; } - //ControlPointListType::const_iterator GetSelectedControlPoint() const; - - - /** \brief Returns 2D control points vector. */ - const VertexContainerType *GetControlPoints() const; - - - /** \brief Returns 2D control points vector. */ - VertexContainerType *GetControlPoints(); - - /** \brief Returns specified control point in 2D world coordinates. */ Point2D GetControlPoint( unsigned int index ) const; /** \brief Returns specified control point in world coordinates. */ Point3D GetWorldControlPoint( unsigned int index ) const; + /** \brief defines the number of PolyLines that will be available */ void SetNumberOfPolyLines( unsigned int numberOfPolyLines ); - void SetNumberOfHelperPolyLines( unsigned int numberOfHelperPolyLines ); + /** \brief returns the PolyLine for the given index. */ + const PolyLineType GetPolyline( int index ) const; + + /** \brief Append a point to the PolyLine # index */ void AppendPointToPolyLine( unsigned int index, PolyLineElement element ); + + /** \brief clears the list of PolyLines. Call before re-calculating a new Polyline. */ + void ClearPolyLines(); + + + /** \brief defines the number of HelperPolyLines that will be available */ + void SetNumberOfHelperPolyLines( unsigned int numberOfHelperPolyLines ); + + /** \brief Append a point to the HelperPolyLine # index */ void AppendPointToHelperPolyLine( unsigned int index, PolyLineElement element ); - const PolyLineType GetPolyline( int index ) const; + /** \brief clears the list of HelperPolyLines. Call before re-calculating a new HelperPolyline. */ + void ClearHelperPolyLines(); + - PolyLineType::const_iterator GetFirstElementOfPolyLine( unsigned int index ) const; - PolyLineType::const_iterator GetLastElementOfPolyLine( unsigned int index ) const; /** \brief Returns the polyline representing the planar figure * (for rendering, measurements, etc.). */ - PolyLineType GetPolyLine(unsigned int index); + const PolyLineType GetPolyLine(unsigned int index); /** \brief Returns the polyline representing the planar figure * (for rendering, measurments, etc.). */ const PolyLineType GetPolyLine(unsigned int index) const; /** \brief Returns the polyline that should be drawn the same size at every scale * (for text, angles, etc.). */ - //const VertexContainerType *GetHelperPolyLine(unsigned int index, double mmPerDisplayUnit, unsigned int displayHeight); - - const mitk::PlanarFigure::PolyLineType GetHelperPolyLine( unsigned int index, double mmPerDisplayUnit, unsigned int displayHeight ); + const PolyLineType GetHelperPolyLine( unsigned int index, double mmPerDisplayUnit, unsigned int displayHeight ); + /** \brief Sets the position of the PreviewControlPoint. Automatically sets it visible.*/ + void SetPreviewControlPoint( const Point2D& point ); + + /** \brief Marks the PreviewControlPoint as invisible.*/ + void ResetPreviewContolPoint(); + + /** \brief Returns whether or not the PreviewControlPoint is visible.*/ + bool IsPreviewControlPointVisible(); + + /** \brief Returns the coordinates of the PreviewControlPoint. */ + Point2D GetPreviewControlPoint(); + + + /** \brief Returns the number of features available for this PlanarFigure * (such as, radius, area, ...). */ virtual unsigned int GetNumberOfFeatures() const; /** \brief Returns the name (identifier) of the specified features. */ const char *GetFeatureName( unsigned int index ) const; /** \brief Returns the physical unit of the specified features. */ const char *GetFeatureUnit( unsigned int index ) const; /** Returns quantity of the specified feature (e.g., length, radius, * area, ... ) */ double GetQuantity( unsigned int index ) const; /** \brief Returns true if the feature with the specified index exists and * is active (an inactive feature may e.g. be the area of a non-closed * polygon. */ bool IsFeatureActive( unsigned int index ) const; /** \brief Calculates quantities of all features of this planar figure. */ virtual void EvaluateFeatures(); /** \brief Intherited from parent */ virtual void UpdateOutputInformation(); /** \brief Intherited from parent */ virtual void SetRequestedRegionToLargestPossibleRegion(); /** \brief Intherited from parent */ virtual bool RequestedRegionIsOutsideOfTheBufferedRegion(); /** \brief Intherited from parent */ virtual bool VerifyRequestedRegion(); /** \brief Intherited from parent */ virtual void SetRequestedRegion(itk::DataObject *data); /** \brief Returns the current number of polylines */ virtual unsigned short GetPolyLinesSize(); /** \brief Returns the current number of helperpolylines */ virtual unsigned short GetHelperPolyLinesSize(); /** \brief Returns whether a helper polyline should be painted or not */ virtual bool IsHelperToBePainted(unsigned int index); /** \brief Returns true if the planar figure is reset to "add points" mode * when a point is selected. * * Default return value is false. Subclasses can overwrite this method and * execute any reset / initialization statements required. */ virtual bool ResetOnPointSelect(); virtual void RemoveControlPoint( unsigned int index ); /** \brief Removes last control point */ virtual void RemoveLastControlPoint(); /** \brief Copies contents and state of a figre provided as parameter to the current object. Requires a matching type of both figures. */ void DeepCopy(Self::Pointer oldFigure); - void SetHoveringControlPoint( const Point2D& point ); - void ResetHoveringContolPoint(); - bool IsHoveringControlPointVisible(); - - mitk::PlanarFigure::VertexContainerType::Pointer GetHoveringControlPoint(); - protected: PlanarFigure(); virtual ~PlanarFigure(); /** \brief Set the initial number of control points of the planar figure */ void ResetNumberOfControlPoints( int numberOfControlPoints ); /** \brief Allow sub-classes to apply constraints on control points. * * Sub-classes can define spatial constraints to certain control points by * overwriting this method and returning a constrained point. By default, * the points are constrained by the image bounds. */ virtual Point2D ApplyControlPointConstraints( unsigned int /*index*/, const Point2D& point ); /** Adds feature (e.g., circumference, radius, angle, ...) to feature vector * of a planar figure object and returns integer ID for the feature element. * Should be called in sub-class constructors. */ virtual unsigned int AddFeature( const char *featureName, const char *unitName ); /** Sets the name of the specified feature. INTERNAL METHOD. */ void SetFeatureName( unsigned int index, const char *featureName ); /** Sets the physical unit of the specified feature. INTERNAL METHOD. */ void SetFeatureUnit( unsigned int index, const char *unitName ); /** Sets quantity of the specified feature. INTERNAL METHOD. */ void SetQuantity( unsigned int index, double quantity ); /** Sets the specified feature as active. INTERAL METHOD. */ void ActivateFeature( unsigned int index ); /** Sets the specified feature as active. INTERAL METHOD. */ void DeactivateFeature( unsigned int index ); /** \brief Generates the poly-line representation of the planar figure. * Must be implemented in sub-classes. */ virtual void GeneratePolyLine() = 0; /** \brief Generates the poly-lines that should be drawn the same size regardless of zoom. * Must be implemented in sub-classes. */ virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight) = 0; /** \brief Calculates quantities of all features of this planar figure. * Must be implemented in sub-classes. */ virtual void EvaluateFeaturesInternal() = 0; /** \brief Initializes the TimeSlicedGeometry describing the (time-resolved) * geometry of this figure. Note that each time step holds one Geometry2D. */ virtual void InitializeTimeSlicedGeometry( unsigned int timeSteps = 1 ); virtual void PrintSelf( std::ostream& os, itk::Indent indent ) const; - VertexContainerType::Pointer m_ControlPoints; + ControlPointListType m_ControlPoints; unsigned int m_NumberOfControlPoints; - VertexContainerType::Pointer m_HoveringControlPoint; - - VertexContainerVectorType::Pointer m_PolyLines; - VertexContainerVectorType::Pointer m_HelperPolyLines; - BoolContainerType::Pointer m_HelperPolyLinesToBePainted; + // Currently selected control point; -1 means no point selected + int m_SelectedControlPoint; + std::vector m_PolyLines; + std::vector m_HelperPolyLines; + BoolContainerType::Pointer m_HelperPolyLinesToBePainted; + // this point is used to store the coordiantes an additional 'ControlPoint' that is rendered + // when the mouse cursor is above the figure (and not a control-point) and when the + // property 'planarfigure.isextendable' is set to true + Point2D m_PreviewControlPoint; + bool m_PreviewControlPointVisible; bool m_FigurePlaced; - bool m_HoveringControlPointVisible; - - // Currently selected control point; -1 means no point selected - int m_SelectedControlPoint; - ControlPointListType m_NewControlPoints; - private: struct Feature { Feature( const char *name, const char *unit ) : Name( name ), Unit( unit ), Quantity( 0.0 ), Active( true ) { }; std::string Name; std::string Unit; double Quantity; bool Active; }; Geometry2D *m_Geometry2D; - std::vector m_NewPolyLines; - std::vector m_NewHelperPolyLines; - - bool m_ControlPointsModified; bool m_PolyLineUpToDate; bool m_HelperLinesUpToDate; bool m_FeaturesUpToDate; // Vector of features available for this geometric figure typedef std::vector< Feature > FeatureVectorType; FeatureVectorType m_Features; unsigned long m_FeaturesMTime; }; } // namespace mitk #endif //_MITK_PLANAR_FIGURE_H_