]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/WorkspaceIO.cxx
c23852a8ff72675c3dae95e48102bf12dc9c55be
[cpPlugins.git] / lib / cpPlugins / WorkspaceIO.cxx
1 #include <cpPlugins/Workspace.h>
2 #include <tinyxml/tinyxml2.h>
3
4 // -------------------------------------------------------------------------
5 std::string cpPlugins::Workspace::
6 LoadWorkspace( const std::string& fname )
7 {
8   tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( );
9   doc->LoadFile( fname.c_str( ) );
10   tinyxml2::XMLElement* root = doc->RootElement( );
11   if( root == NULL )
12     return( "cpPlugins::Workspace: No valid file" );
13   if( std::string( root->Value( ) ) != "cpPlugins_Workspace" )
14     return( "cpPlugins::Workspace: No valid workspace" );
15   std::stringstream err;
16
17   // Read filters
18   tinyxml2::XMLElement* filter = root->FirstChildElement( "filter" );
19   while( filter != NULL )
20   {
21     const char* category_value = filter->Attribute( "category" );
22     const char* class_value = filter->Attribute( "class" );
23     const char* name_value = filter->Attribute( "name" );
24     float viewX = float( 0 ), viewY = float( 0 );
25     filter->QueryFloatAttribute( "ViewX", &viewX );
26     filter->QueryFloatAttribute( "ViewY", &viewY );
27     if( class_value != NULL && name_value != NULL )
28     {
29       if( this->CreateFilter( category_value, class_value, name_value ) )
30       {
31         auto new_filter = this->GetFilter( name_value );
32         new_filter->SetViewCoords( viewX, viewY );
33
34         // Read parameters
35         auto parameters = new_filter->GetParameters( );
36         parameters->FromXML( filter );
37       }
38       else
39         err
40           << "No valid class \"" << class_value << "\" with name \""
41           << name_value << "\"" << std::endl;
42     }
43     else
44       err << "Incomplete data." << std::endl;
45     filter = filter->NextSiblingElement( "filter" );
46
47   } // elihw
48
49   // Read connections
50   tinyxml2::XMLElement* connection = root->FirstChildElement( "connection" );
51   while( connection != NULL )
52   {
53     tinyxml2::XMLElement* orig = connection->FirstChildElement( "origin" );
54     tinyxml2::XMLElement* dest = connection->FirstChildElement( "destination" );
55     if( orig != NULL && dest != NULL )
56     {
57       const char* orig_filter = orig->Attribute( "filter" );
58       const char* dest_filter = dest->Attribute( "filter" );
59       const char* orig_name = orig->Attribute( "name" );
60       const char* dest_name = dest->Attribute( "name" );
61       if(
62         orig_filter != NULL && dest_filter != NULL &&
63         orig_name != NULL && dest_name != NULL
64         )
65         this->Connect( orig_filter, dest_filter, orig_name, dest_name );
66
67     } // fi
68     connection = connection->NextSiblingElement( "connection" );
69
70   } // elihw
71
72   // Read exposed inputs
73   tinyxml2::XMLElement* port = root->FirstChildElement( "exposed_input_port" );
74   while( port != NULL )
75   {
76     this->ExposeInputPort(
77       port->Attribute( "port_name" ),
78       port->Attribute( "filter" ),
79       port->Attribute( "filter_port_name" )
80       );
81     port = port->NextSiblingElement( "exposed_input_port" );
82
83   } // elihw
84
85   // Read exposed outputs
86   port = root->FirstChildElement( "exposed_output_port" );
87   while( port != NULL )
88   {
89     this->ExposeOutputPort(
90       port->Attribute( "port_name" ),
91       port->Attribute( "filter" ),
92       port->Attribute( "filter_port_name" )
93       );
94     port = port->NextSiblingElement( "exposed_output_port" );
95
96   } // elihw
97
98   // Finish and return
99   delete doc;
100   return( err.str( ) );
101 }
102
103 // -------------------------------------------------------------------------
104 std::string cpPlugins::Workspace::
105 SaveWorkspace( const std::string& fname ) const
106 {
107   std::stringstream err;
108   tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( );
109   tinyxml2::XMLElement* root = doc->NewElement( "cpPlugins_Workspace" );
110
111   // Save vertices
112   auto vIt = this->m_Graph->BeginVertices( );
113   for( ; vIt != this->m_Graph->EndVertices( ); ++vIt )
114   {
115     auto filter = dynamic_cast< ProcessObject* >( vIt->second.GetPointer( ) );
116     auto data = dynamic_cast< DataObject* >( vIt->second.GetPointer( ) );
117     if( filter != NULL )
118     {
119       tinyxml2::XMLElement* e = doc->NewElement( "filter" );
120       e->SetAttribute( "category", filter->GetClassCategory( ) );
121       e->SetAttribute( "class", filter->GetClassName( ) );
122       e->SetAttribute( "name", vIt->first.c_str( ) );
123       e->SetAttribute( "ViewX", filter->GetViewX( ) );
124       e->SetAttribute( "ViewY", filter->GetViewY( ) );
125
126       auto params = filter->GetParameters( );
127       params->ToXML( doc, e );
128       root->LinkEndChild( e );
129     }
130     else if( data != NULL )
131     {
132       // TODO
133     } // fi
134
135   } // rof
136
137   // Save connections
138   auto mIt = this->m_Graph->BeginEdgesRows( );
139   for( ; mIt != this->m_Graph->EndEdgesRows( ); ++mIt )
140   {
141     auto rIt = mIt->second.begin( );
142     for( ; rIt != mIt->second.end( ); ++rIt )
143     {
144       auto eIt = rIt->second.begin( );
145       for( ; eIt != rIt->second.end( ); ++eIt )
146       {
147         tinyxml2::XMLElement* conn = doc->NewElement( "connection" );
148         tinyxml2::XMLElement* orig = doc->NewElement( "origin" );
149         tinyxml2::XMLElement* dest = doc->NewElement( "destination" );
150         orig->SetAttribute( "filter", mIt->first.c_str( ) );
151         orig->SetAttribute( "name", eIt->first.c_str( ) );
152         dest->SetAttribute( "filter", rIt->first.c_str( ) );
153         dest->SetAttribute( "name", eIt->second.c_str( ) );
154
155         conn->LinkEndChild( orig );
156         conn->LinkEndChild( dest );
157         root->LinkEndChild( conn );
158
159       } // rof
160
161     } // rof
162
163   } // rof
164
165   // Save exposed ports
166   auto eipIt = this->m_ExposedInputPorts.begin( );
167   for( ; eipIt != this->m_ExposedInputPorts.end( ); ++eipIt )
168   {
169     tinyxml2::XMLElement* port = doc->NewElement( "exposed_input_port" );
170     port->SetAttribute( "port_name", eipIt->first.c_str( ) );
171     port->SetAttribute( "filter", eipIt->second.first.c_str( ) );
172     port->SetAttribute( "filter_port_name", eipIt->second.second.c_str( ) );
173     root->LinkEndChild( port );
174
175   } // rof
176
177   auto eopIt = this->m_ExposedOutputPorts.begin( );
178   for( ; eopIt != this->m_ExposedOutputPorts.end( ); ++eopIt )
179   {
180     tinyxml2::XMLElement* port = doc->NewElement( "exposed_output_port" );
181     port->SetAttribute( "port_name", eopIt->first.c_str( ) );
182     port->SetAttribute( "filter", eopIt->second.first.c_str( ) );
183     port->SetAttribute( "filter_port_name", eopIt->second.second.c_str( ) );
184     root->LinkEndChild( port );
185
186   } // rof
187
188   // Physical write and return
189   doc->LinkEndChild( root );
190   doc->SaveFile( fname.c_str( ) );
191   delete doc;
192   return( err.str( ) );
193 }
194
195 // eof - $RCSfile$