00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mitkPlanarFigureReader.h"
00020
00021 #include "mitkPlanarAngle.h"
00022 #include "mitkPlanarCircle.h"
00023 #include "mitkPlanarLine.h"
00024 #include "mitkPlanarArrow.h"
00025 #include "mitkPlanarCross.h"
00026 #include "mitkPlanarFourPointAngle.h"
00027 #include "mitkPlanarPolygon.h"
00028 #include "mitkPlanarRectangle.h"
00029 #include "mitkPlaneGeometry.h"
00030
00031 #include "mitkBasePropertyDeserializer.h"
00032
00033 #include <tinyxml.h>
00034 #include <itksys/SystemTools.hxx>
00035
00036
00037 mitk::PlanarFigureReader::PlanarFigureReader() : PlanarFigureSource(), FileReader(),
00038 m_FileName(""), m_FilePrefix(""), m_FilePattern(""), m_Success(false)
00039 {
00040 this->SetNumberOfRequiredOutputs(1);
00041 this->SetNumberOfOutputs(1);
00042 this->SetNthOutput(0, this->MakeOutput(0));
00043
00044
00045
00046
00047
00048 }
00049
00050
00051 mitk::PlanarFigureReader::~PlanarFigureReader()
00052 {}
00053
00054
00055 mitk::PlanarFigureSource::DataObjectPointer mitk::PlanarFigureReader::MakeOutput ( unsigned int )
00056 {
00057 return static_cast<itk::DataObject*>(PlanarCircle::New().GetPointer());
00058 }
00059
00060
00061 void mitk::PlanarFigureReader::GenerateData()
00062 {
00063 m_Success = false;
00064 this->SetNumberOfOutputs(0);
00065
00066 if (m_FileName.empty())
00067 {
00068 itkWarningMacro( << "Sorry, filename has not been set!" );
00069 return;
00070 }
00071 if (this->CanReadFile( m_FileName.c_str()) == false)
00072 {
00073 itkWarningMacro( << "Sorry, can't read file " << m_FileName << "!" );
00074 return;
00075 }
00076
00077 TiXmlDocument document( m_FileName);
00078 if (!document.LoadFile())
00079 {
00080 MITK_ERROR << "Could not open/read/parse " << m_FileName << ". TinyXML reports: '" << document.ErrorDesc() << "'. "
00081 << "The error occurred in row " << document.ErrorRow() << ", column " << document.ErrorCol() << ".";
00082 return;
00083 }
00084 int fileVersion = 1;
00085 TiXmlElement* versionObject = document.FirstChildElement("Version");
00086 if (versionObject != NULL)
00087 {
00088 if ( versionObject->QueryIntAttribute( "FileVersion", &fileVersion ) != TIXML_SUCCESS )
00089 {
00090 MITK_WARN << m_FileName << " does not contain version information! Trying version 1 format." << std::endl;
00091 }
00092 }
00093 else
00094 {
00095 MITK_WARN << m_FileName << " does not contain version information! Trying version 1 format." << std::endl;
00096 }
00097 if (fileVersion != 1)
00098 {
00099 MITK_WARN << "File version > 1 is not supported by this reader.";
00100 return;
00101 }
00102
00103
00104 for( TiXmlElement* pfElement = document.FirstChildElement("PlanarFigure");
00105 pfElement != NULL;
00106 pfElement = pfElement->NextSiblingElement("PlanarFigure") )
00107 {
00108 if (pfElement == NULL)
00109 continue;
00110
00111 std::string type = pfElement->Attribute("type");
00112
00113 mitk::PlanarFigure::Pointer planarFigure = NULL;
00114 if (type == "PlanarAngle")
00115 {
00116 planarFigure = mitk::PlanarAngle::New();
00117 }
00118 else if (type == "PlanarCircle")
00119 {
00120 planarFigure = mitk::PlanarCircle::New();
00121 }
00122 else if (type == "PlanarCross")
00123 {
00124 planarFigure = mitk::PlanarCross::New();
00125 }
00126 else if (type == "PlanarFourPointAngle")
00127 {
00128 planarFigure = mitk::PlanarFourPointAngle::New();
00129 }
00130 else if (type == "PlanarLine")
00131 {
00132 planarFigure = mitk::PlanarLine::New();
00133 }
00134 else if (type == "PlanarPolygon")
00135 {
00136 planarFigure = mitk::PlanarPolygon::New();
00137 }
00138 else if (type == "PlanarRectangle")
00139 {
00140 planarFigure = mitk::PlanarRectangle::New();
00141 }
00142 else if (type == "PlanarArrow")
00143 {
00144 planarFigure = mitk::PlanarArrow::New();
00145 }
00146 else
00147 {
00148
00149 MITK_WARN << "encountered unknown planar figure type '" << type << "'. Skipping this element.";
00150 continue;
00151 }
00152
00153
00154
00155 for( TiXmlElement* propertyElement = pfElement->FirstChildElement("property");
00156 propertyElement != NULL;
00157 propertyElement = propertyElement->NextSiblingElement("property") )
00158 {
00159 const char* keya = propertyElement->Attribute("key");
00160 std::string key( keya ? keya : "");
00161
00162 const char* typea = propertyElement->Attribute("type");
00163 std::string type( typea ? typea : "");
00164
00165
00166 std::stringstream propertyDeserializerClassName;
00167 propertyDeserializerClassName << type << "Deserializer";
00168
00169 std::list<itk::LightObject::Pointer> readers =
00170 itk::ObjectFactoryBase::CreateAllInstance(propertyDeserializerClassName.str().c_str());
00171 if (readers.size() < 1)
00172 {
00173 MITK_ERROR << "No property reader found for " << type;
00174 }
00175 if (readers.size() > 1)
00176 {
00177 MITK_WARN << "Multiple property readers found for " << type << ". Using arbitrary first one.";
00178 }
00179
00180 for ( std::list<itk::LightObject::Pointer>::iterator iter = readers.begin();
00181 iter != readers.end();
00182 ++iter )
00183 {
00184 if (BasePropertyDeserializer* reader = dynamic_cast<BasePropertyDeserializer*>( iter->GetPointer() ) )
00185 {
00186 BaseProperty::Pointer property = reader->Deserialize( propertyElement->FirstChildElement() );
00187 if (property.IsNotNull())
00188 {
00189 planarFigure->GetPropertyList()->ReplaceProperty(key, property);
00190 }
00191 else
00192 {
00193 MITK_ERROR << "There were errors while loading property '" << key << "' of type " << type << ". Your data may be corrupted";
00194 }
00195 break;
00196 }
00197 }
00198 }
00199
00200
00201
00202 TiXmlElement* geoElement = pfElement->FirstChildElement("Geometry");
00203 if (geoElement != NULL)
00204 {
00205 try
00206 {
00207
00208 mitk::PlaneGeometry::Pointer planeGeo = mitk::PlaneGeometry::New();
00209
00210
00211 DoubleList transformList = this->GetDoubleAttributeListFromXMLNode( geoElement->FirstChildElement( "transformParam" ), "param", 12 );
00212
00213 typedef mitk::AffineGeometryFrame3D::TransformType TransformType;
00214 TransformType::ParametersType parameters;
00215 parameters.SetSize( 12 );
00216
00217 unsigned int i;
00218 DoubleList::iterator it;
00219 for ( it = transformList.begin(), i = 0;
00220 it != transformList.end();
00221 ++it, ++i )
00222 {
00223 parameters.SetElement( i, *it );
00224 }
00225
00226 typedef mitk::AffineGeometryFrame3D::TransformType TransformType;
00227 TransformType::Pointer affineGeometry = TransformType::New();
00228 affineGeometry->SetParameters( parameters );
00229 planeGeo->SetIndexToWorldTransform( affineGeometry );
00230
00231
00232
00233 DoubleList boundsList = this->GetDoubleAttributeListFromXMLNode( geoElement->FirstChildElement( "boundsParam" ), "bound", 6 );
00234
00235 typedef mitk::Geometry3D::BoundsArrayType BoundsArrayType;
00236
00237 BoundsArrayType bounds;
00238 for ( it = boundsList.begin(), i = 0;
00239 it != boundsList.end();
00240 ++it, ++i )
00241 {
00242 bounds[i] = *it;
00243 }
00244
00245 planeGeo->SetBounds( bounds );
00246
00247
00248
00249 Vector3D spacing = this->GetVectorFromXMLNode(geoElement->FirstChildElement("Spacing"));
00250 planeGeo->SetSpacing( spacing );
00251
00252 Point3D origin = this->GetPointFromXMLNode(geoElement->FirstChildElement("Origin"));
00253 planeGeo->SetOrigin( origin );
00254 planarFigure->SetGeometry2D(planeGeo);
00255 }
00256 catch (...)
00257 {
00258 }
00259 }
00260 TiXmlElement* cpElement = pfElement->FirstChildElement("ControlPoints");
00261 bool first = true;
00262 if (cpElement != NULL)
00263 for( TiXmlElement* vertElement = cpElement->FirstChildElement("Vertex"); vertElement != NULL; vertElement = vertElement->NextSiblingElement("Vertex"))
00264 {
00265 if (vertElement == NULL)
00266 continue;
00267 int id = 0;
00268 mitk::Point2D::ValueType x = 0.0;
00269 mitk::Point2D::ValueType y = 0.0;
00270 if (vertElement->QueryIntAttribute("id", &id) == TIXML_WRONG_TYPE)
00271 return;
00272 if (vertElement->QueryFloatAttribute("x", &x) == TIXML_WRONG_TYPE)
00273 return;
00274 if (vertElement->QueryFloatAttribute("y", &y) == TIXML_WRONG_TYPE)
00275 return;
00276 Point2D p;
00277 p.SetElement(0, x);
00278 p.SetElement(1, y);
00279 if (first == true)
00280 {
00281 planarFigure->PlaceFigure(p);
00282 first = false;
00283 }
00284 planarFigure->SetControlPoint(id, p, true);
00285 }
00286
00287
00288 planarFigure->EvaluateFeatures();
00289
00290
00291 planarFigure->DeselectControlPoint();
00292
00293
00294 this->SetNthOutput( this->GetNumberOfOutputs(), planarFigure );
00295 }
00296 m_Success = true;
00297 }
00298
00299 mitk::Point3D mitk::PlanarFigureReader::GetPointFromXMLNode(TiXmlElement* e)
00300 {
00301 if (e == NULL)
00302 throw std::invalid_argument("node invalid");
00303 mitk::Point3D point;
00304 mitk::ScalarType p(-1.0);
00305 if (e->QueryFloatAttribute("x", &p) == TIXML_WRONG_TYPE)
00306 throw std::invalid_argument("node malformatted");
00307 point.SetElement(0, p);
00308 if (e->QueryFloatAttribute("y", &p) == TIXML_WRONG_TYPE)
00309 throw std::invalid_argument("node malformatted");
00310 point.SetElement(1, p);
00311 if (e->QueryFloatAttribute("z", &p) == TIXML_WRONG_TYPE)
00312 throw std::invalid_argument("node malformatted");
00313 point.SetElement(2, p);
00314 return point;
00315 }
00316
00317
00318 mitk::Vector3D mitk::PlanarFigureReader::GetVectorFromXMLNode(TiXmlElement* e)
00319 {
00320 if (e == NULL)
00321 throw std::invalid_argument("node invalid");
00322 mitk::Vector3D vector;
00323 mitk::ScalarType p(-1.0);
00324 if (e->QueryFloatAttribute("x", &p) == TIXML_WRONG_TYPE)
00325 throw std::invalid_argument("node malformatted");
00326 vector.SetElement(0, p);
00327 if (e->QueryFloatAttribute("y", &p) == TIXML_WRONG_TYPE)
00328 throw std::invalid_argument("node malformatted");
00329 vector.SetElement(1, p);
00330 if (e->QueryFloatAttribute("z", &p) == TIXML_WRONG_TYPE)
00331 throw std::invalid_argument("node malformatted");
00332 vector.SetElement(2, p);
00333 return vector;
00334 }
00335
00336 mitk::PlanarFigureReader::DoubleList
00337 mitk::PlanarFigureReader::GetDoubleAttributeListFromXMLNode(TiXmlElement* e, const char *attributeNameBase, unsigned int count)
00338 {
00339 DoubleList list;
00340
00341 if (e == NULL)
00342 throw std::invalid_argument("node invalid");
00343
00344 for ( unsigned int i = 0; i < count; ++i )
00345 {
00346 mitk::ScalarType p(-1.0);
00347 std::stringstream attributeName;
00348 attributeName << attributeNameBase << i;
00349
00350 if (e->QueryFloatAttribute( attributeName.str().c_str(), &p ) == TIXML_WRONG_TYPE)
00351 throw std::invalid_argument("node malformatted");
00352 list.push_back( p );
00353 }
00354
00355
00356 return list;
00357 }
00358
00359 void mitk::PlanarFigureReader::GenerateOutputInformation()
00360 {
00361 }
00362
00363 int mitk::PlanarFigureReader::CanReadFile ( const char *name )
00364 {
00365 if (std::string(name).empty())
00366 return false;
00367
00368 return (itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameLastExtension(name)) == ".pf");
00369
00370
00371
00372
00373
00374 }
00375
00376 bool mitk::PlanarFigureReader::CanReadFile(const std::string filename, const std::string, const std::string)
00377 {
00378 if (filename.empty())
00379 return false;
00380
00381 return (itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameLastExtension(filename)) == ".pf");
00382
00383
00384
00385
00386
00387 }
00388
00389 void mitk::PlanarFigureReader::ResizeOutputs( const unsigned int& num )
00390 {
00391 unsigned int prevNum = this->GetNumberOfOutputs();
00392 this->SetNumberOfOutputs( num );
00393 for ( unsigned int i = prevNum; i < num; ++i )
00394 {
00395 this->SetNthOutput( i, this->MakeOutput( i ).GetPointer() );
00396 }
00397 }