diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp index b3af7b5b7b..a72e4c8176 100644 --- a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp +++ b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp @@ -1,525 +1,596 @@ /*========================================================================= 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_FeaturesMTime( 0 ) { m_ControlPoints = VertexContainerType::New(); + m_HoveringControlPoint = VertexContainerType::New(); m_PolyLines = VertexContainerVectorType::New(); m_HelperPolyLines = VertexContainerVectorType::New(); 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 ) { for ( unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i ) { m_ControlPoints->InsertElement( i, this->ApplyControlPointConstraints( i, point ) ); + m_NewControlPoints.push_back( point ); } m_FigurePlaced = true; m_SelectedControlPoint = 1; } bool mitk::PlanarFigure::AddControlPoint( const mitk::Point2D& point ) { if ( m_NumberOfControlPoints < this->GetMaximumNumberOfControlPoints() ) { m_ControlPoints->InsertElement( m_NumberOfControlPoints, this->ApplyControlPointConstraints( m_NumberOfControlPoints, point ) ); + m_NewControlPoints.push_back( point ); ++m_NumberOfControlPoints; ++m_SelectedControlPoint; return true; } else { return false; } } bool mitk::PlanarFigure::SetControlPoint( unsigned int index, const Point2D& point, bool createIfDoesNotExist ) { if (createIfDoesNotExist) { m_ControlPoints->InsertElement( index, this->ApplyControlPointConstraints( index, point ) ); + if ( m_NumberOfControlPoints <= index ) { + m_NewControlPoints.push_back( point ); m_NumberOfControlPoints = index + 1; - } + } + else + { + m_NewControlPoints.at( index ) = point; + } return true; } else if ( index < m_NumberOfControlPoints ) { + m_NewControlPoints.at( index ) = point; m_ControlPoints->InsertElement( index, this->ApplyControlPointConstraints( index, point ) ); return true; } else { return false; } } 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() +{ + if ( m_HoveringControlPoint->Size() > 0 ) + { + m_HoveringControlPointVisible = false; + m_HoveringControlPoint->DeleteIndex( 0 ); + } +} + +mitk::PlanarFigure::VertexContainerType::Pointer mitk::PlanarFigure::GetHoveringControlPoint() +{ + return m_HoveringControlPoint; +} + +bool mitk::PlanarFigure::IsHoveringControlPointVisible() +{ + return m_HoveringControlPointVisible; +} + const mitk::PlanarFigure::VertexContainerType * mitk::PlanarFigure::GetControlPoints() const { return m_ControlPoints; } 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 ); } 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 ); return point3D; } itkExceptionMacro( << "GetWorldControlPoint(): Invalid index!" ); } mitk::PlanarFigure::VertexContainerType * mitk::PlanarFigure::GetPolyLine(unsigned int index) { if ( !m_PolyLines->IndexExists( index ) || (m_PolyLines->ElementAt( index )->GetMTime() < m_ControlPoints->GetMTime()) ) { this->GeneratePolyLine(); } return m_PolyLines->ElementAt( index ); } const mitk::PlanarFigure::VertexContainerType * mitk::PlanarFigure::GetPolyLine(unsigned int index) const { return m_PolyLines->ElementAt( index ); } const mitk::PlanarFigure::VertexContainerType * mitk::PlanarFigure::GetHelperPolyLine(unsigned int index, double mmPerDisplayUnit, unsigned int displayHeight) { if ((m_HelperPolyLines->ElementAt( index )) && (m_HelperPolyLines->ElementAt( index )->GetMTime() < m_ControlPoints->GetMTime()) ) { this->GenerateHelperPolyLine(mmPerDisplayUnit, displayHeight); } return m_HelperPolyLines->ElementAt( index ); } /** \brief Returns the number of features available for this PlanarFigure * (such as, radius, area, ...). */ unsigned int mitk::PlanarFigure::GetNumberOfFeatures() const { return m_Features.size(); } const char *mitk::PlanarFigure::GetFeatureName( unsigned int index ) const { if ( index < m_Features.size() ) { return m_Features[index].Name.c_str(); } else { return NULL; } } const char *mitk::PlanarFigure::GetFeatureUnit( unsigned int index ) const { if ( index < m_Features.size() ) { return m_Features[index].Unit.c_str(); } else { return NULL; } } double mitk::PlanarFigure::GetQuantity( unsigned int index ) const { if ( index < m_Features.size() ) { return m_Features[index].Quantity; } else { return 0.0; } } bool mitk::PlanarFigure::IsFeatureActive( unsigned int index ) const { if ( index < m_Features.size() ) { return m_Features[index].Active; } else { return false; } } void mitk::PlanarFigure::EvaluateFeatures() { if ( m_FeaturesMTime < m_ControlPoints->GetMTime() ) { this->EvaluateFeaturesInternal(); 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 << "Geometry:\n"; this->GetGeometry2D()->Print(os, indent.GetNextIndent()); } unsigned short mitk::PlanarFigure::GetPolyLinesSize() { if ( m_PolyLines->GetMTime() < m_ControlPoints->GetMTime() ) { this->GeneratePolyLine(); } return m_PolyLines->size(); } unsigned short mitk::PlanarFigure::GetHelperPolyLinesSize() { 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_NumberOfControlPoints ) + return; + + if ( (m_NumberOfControlPoints -1) < this->GetMinimumNumberOfControlPoints() ) + return; + + typedef std::vector vectortype; + vectortype vector = m_ControlPoints->CastToSTLContainer(); + vectortype::iterator iter; + + iter = std::find( vector.begin(), vector.end(), vector.at(index) ); + //vector.erase( iter ); + + if ( iter != vector.end() ) + { + m_ControlPoints->erase( iter ); + m_NumberOfControlPoints--; + } + + //if ( m_ControlPoints->Size() < m_NumberOfControlPoints ) + //{ + //} +} + void mitk::PlanarFigure::RemoveLastControlPoint() { m_ControlPoints->DeleteIndex( this->GetNumberOfControlPoints()-1 ); this->ResetNumberOfControlPoints( this->GetNumberOfControlPoints()-1 ); this->GeneratePolyLine(); } 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; } // 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++) { m_ControlPoints->InsertElement(index, oldFigure->m_ControlPoints->ElementAt( index )); } //After setting the control points we can generate the polylines this->GeneratePolyLine(); } diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h index eb1fe85025..e143321a98 100644 --- a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h +++ b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h @@ -1,332 +1,360 @@ /*========================================================================= 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: * * * * * 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 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; } /** \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 Returns the polyline representing the planar figure * (for rendering, measurements, etc.). */ VertexContainerType *GetPolyLine(unsigned int index); /** \brief Returns the polyline representing the planar figure * (for rendering, measurements, etc.). */ const VertexContainerType *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); /** \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; unsigned int m_NumberOfControlPoints; + VertexContainerType::Pointer m_HoveringControlPoint; VertexContainerVectorType::Pointer m_PolyLines; VertexContainerVectorType::Pointer m_HelperPolyLines; BoolContainerType::Pointer m_HelperPolyLinesToBePainted; bool m_FigurePlaced; + bool m_HoveringControlPointVisible; + // Currently selected control point; -1 means no point selected int m_SelectedControlPoint; - 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; + ControlPointListType m_NewControlPoints; + PolyLineType m_NewPolyLine; + // 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_