1 // g2o - General Graph Optimization 2 // Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard 3 // All rights reserved. 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright notice, 10 // this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above copyright 12 // notice, this list of conditions and the following disclaimer in the 13 // documentation and/or other materials provided with the distribution. 14 // 15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 16 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 18 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27 #include "hyper_graph_action.h" 28 #include "optimizable_graph.h" 29 #include "cache.h" 30 #include "g2o/stuff/macros.h" 31 32 33 #include <iostream> 34 #include <list> 35 36 namespace g2o { 37 using namespace std; 38 39 HyperGraphActionLibrary* HyperGraphActionLibrary::actionLibInstance = 0; 40 ~Parameters()41 HyperGraphAction::Parameters::~Parameters() 42 { 43 } 44 ParametersIteration(int iter)45 HyperGraphAction::ParametersIteration::ParametersIteration(int iter) : 46 HyperGraphAction::Parameters(), 47 iteration(iter) 48 { 49 } 50 ~HyperGraphAction()51 HyperGraphAction::~HyperGraphAction() 52 { 53 } 54 operator ()(const HyperGraph *,Parameters *)55 HyperGraphAction* HyperGraphAction::operator()(const HyperGraph*, Parameters*) 56 { 57 return nullptr; 58 } 59 ~Parameters()60 HyperGraphElementAction::Parameters::~Parameters() 61 { 62 } 63 HyperGraphElementAction(const std::string & typeName_)64 HyperGraphElementAction::HyperGraphElementAction(const std::string& typeName_) : _typeName(typeName_) {} 65 setTypeName(const std::string & typeName_)66 void HyperGraphElementAction::setTypeName(const std::string& typeName_) 67 { 68 _typeName = typeName_; 69 } 70 71 operator ()(HyperGraph::HyperGraphElement *,HyperGraphElementAction::Parameters *)72 HyperGraphElementAction* HyperGraphElementAction::operator()(HyperGraph::HyperGraphElement* , HyperGraphElementAction::Parameters* ) 73 { 74 return nullptr; 75 } 76 operator ()(const HyperGraph::HyperGraphElement *,HyperGraphElementAction::Parameters *)77 HyperGraphElementAction* HyperGraphElementAction::operator()(const HyperGraph::HyperGraphElement* , HyperGraphElementAction::Parameters* ) 78 { 79 return nullptr; 80 } 81 ~HyperGraphElementAction()82 HyperGraphElementAction::~HyperGraphElementAction() 83 { 84 } 85 HyperGraphElementActionCollection(const std::string & name_)86 HyperGraphElementActionCollection::HyperGraphElementActionCollection(const std::string& name_) 87 { 88 _name = name_; 89 } 90 ~HyperGraphElementActionCollection()91 HyperGraphElementActionCollection::~HyperGraphElementActionCollection() 92 { 93 for (ActionMap::iterator it = _actionMap.begin(); it != _actionMap.end(); ++it) { 94 delete it->second; 95 } 96 } 97 operator ()(HyperGraph::HyperGraphElement * element,HyperGraphElementAction::Parameters * params)98 HyperGraphElementAction* HyperGraphElementActionCollection::operator()(HyperGraph::HyperGraphElement* element, HyperGraphElementAction::Parameters* params) 99 { 100 ActionMap::iterator it=_actionMap.find(typeid(*element).name()); 101 //cerr << typeid(*element).name() << endl; 102 if (it==_actionMap.end()) 103 return nullptr; 104 HyperGraphElementAction* action=it->second; 105 return (*action)(element, params); 106 } 107 operator ()(const HyperGraph::HyperGraphElement * element,HyperGraphElementAction::Parameters * params)108 HyperGraphElementAction* HyperGraphElementActionCollection::operator()(const HyperGraph::HyperGraphElement* element, HyperGraphElementAction::Parameters* params) 109 { 110 ActionMap::iterator it=_actionMap.find(typeid(*element).name()); 111 if (it==_actionMap.end()) 112 return nullptr; 113 HyperGraphElementAction* action=it->second; 114 return (*action)(element, params); 115 } 116 registerAction(HyperGraphElementAction * action)117 bool HyperGraphElementActionCollection::registerAction(HyperGraphElementAction* action) 118 { 119 # ifdef G2O_DEBUG_ACTIONLIB 120 cerr << __PRETTY_FUNCTION__ << " " << action->name() << " " << action->typeName() << endl; 121 # endif 122 if (action->name()!=name()){ 123 cerr << __PRETTY_FUNCTION__ << ": invalid attempt to register an action in a collection with a different name " << name() << " " << action->name() << endl; 124 } 125 _actionMap.insert(make_pair ( action->typeName(), action) ); 126 return true; 127 } 128 unregisterAction(HyperGraphElementAction * action)129 bool HyperGraphElementActionCollection::unregisterAction(HyperGraphElementAction* action) 130 { 131 for (HyperGraphElementAction::ActionMap::iterator it=_actionMap.begin(); it != _actionMap.end(); ++it) { 132 if (it->second == action){ 133 _actionMap.erase(it); 134 return true; 135 } 136 } 137 return false; 138 } 139 HyperGraphActionLibrary()140 HyperGraphActionLibrary::HyperGraphActionLibrary() 141 { 142 } 143 instance()144 HyperGraphActionLibrary* HyperGraphActionLibrary::instance() 145 { 146 if (actionLibInstance == 0) { 147 actionLibInstance = new HyperGraphActionLibrary; 148 } 149 return actionLibInstance; 150 } 151 destroy()152 void HyperGraphActionLibrary::destroy() 153 { 154 delete actionLibInstance; 155 actionLibInstance = 0; 156 } 157 ~HyperGraphActionLibrary()158 HyperGraphActionLibrary::~HyperGraphActionLibrary() 159 { 160 // memory is freed by Proxy 161 //for (HyperGraphElementAction::ActionMap::iterator it = _actionMap.begin(); it != _actionMap.end(); ++it) { 162 //delete it->second; 163 //} 164 } 165 actionByName(const std::string & name)166 HyperGraphElementAction* HyperGraphActionLibrary::actionByName(const std::string& name) 167 { 168 HyperGraphElementAction::ActionMap::iterator it=_actionMap.find(name); 169 if (it!=_actionMap.end()) 170 return it->second; 171 return nullptr; 172 } 173 registerAction(HyperGraphElementAction * action)174 bool HyperGraphActionLibrary::registerAction(HyperGraphElementAction* action) 175 { 176 HyperGraphElementAction* oldAction = actionByName(action->name()); 177 HyperGraphElementActionCollection* collection = 0; 178 if (oldAction) { 179 collection = dynamic_cast<HyperGraphElementActionCollection*>(oldAction); 180 if (! collection) { 181 cerr << __PRETTY_FUNCTION__ << ": fatal error, a collection is not at the first level in the library" << endl; 182 return false; 183 } 184 } 185 if (! collection) { 186 #ifdef G2O_DEBUG_ACTIONLIB 187 cerr << __PRETTY_FUNCTION__ << ": creating collection for \"" << action->name() << "\"" << endl; 188 #endif 189 collection = new HyperGraphElementActionCollection(action->name()); 190 _actionMap.insert(make_pair(action->name(), collection)); 191 } 192 return collection->registerAction(action); 193 } 194 unregisterAction(HyperGraphElementAction * action)195 bool HyperGraphActionLibrary::unregisterAction(HyperGraphElementAction* action) 196 { 197 list<HyperGraphElementActionCollection*> collectionDeleteList; 198 199 // Search all the collections and delete the registered actions; if a collection becomes empty, schedule it for deletion; note that we can't delete the collections as we go because this will screw up the state of the iterators 200 for (HyperGraphElementAction::ActionMap::iterator it=_actionMap.begin(); it != _actionMap.end(); ++it) { 201 HyperGraphElementActionCollection* collection = dynamic_cast<HyperGraphElementActionCollection*> (it->second); 202 if (collection != 0) { 203 collection->unregisterAction(action); 204 if (collection->actionMap().size() == 0) { 205 collectionDeleteList.push_back(collection); 206 } 207 } 208 } 209 210 // Delete any empty action collections 211 for (list<HyperGraphElementActionCollection*>::iterator itc = collectionDeleteList.begin(); itc != collectionDeleteList.end(); ++itc) { 212 //cout << "Deleting collection " << (*itc)->name() << endl; 213 _actionMap.erase((*itc)->name()); 214 } 215 216 return true; 217 } 218 219 WriteGnuplotAction(const std::string & typeName_)220 WriteGnuplotAction::WriteGnuplotAction(const std::string& typeName_) 221 : HyperGraphElementAction(typeName_) 222 { 223 _name="writeGnuplot"; 224 } 225 Parameters()226 DrawAction::Parameters::Parameters(){ 227 } 228 DrawAction(const std::string & typeName_)229 DrawAction::DrawAction(const std::string& typeName_) 230 : HyperGraphElementAction(typeName_) 231 { 232 _name="draw"; 233 _previousParams = (Parameters*)0x42; 234 refreshPropertyPtrs(0); 235 _cacheDrawActions = 0; 236 } 237 refreshPropertyPtrs(HyperGraphElementAction::Parameters * params_)238 bool DrawAction::refreshPropertyPtrs(HyperGraphElementAction::Parameters* params_){ 239 if (_previousParams == params_) 240 return false; 241 DrawAction::Parameters* p=dynamic_cast<DrawAction::Parameters*>(params_); 242 if (! p){ 243 _previousParams = 0; 244 _show = 0; 245 _showId = 0; 246 } else { 247 _previousParams = p; 248 _show = p->makeProperty<BoolProperty>(_typeName+"::SHOW", true); 249 _showId = p->makeProperty<BoolProperty>(_typeName+"::SHOW_ID", false); 250 } 251 return true; 252 } 253 initializeDrawActionsCache()254 void DrawAction::initializeDrawActionsCache() { 255 if (! _cacheDrawActions){ 256 _cacheDrawActions = HyperGraphActionLibrary::instance()->actionByName("draw"); 257 } 258 } 259 drawCache(CacheContainer * caches,HyperGraphElementAction::Parameters * params_)260 void DrawAction::drawCache(CacheContainer* caches, HyperGraphElementAction::Parameters* params_) { 261 if (caches){ 262 for (CacheContainer::iterator it=caches->begin(); it!=caches->end(); ++it){ 263 Cache* c = it->second; 264 (*_cacheDrawActions)(c, params_); 265 } 266 } 267 } 268 drawUserData(HyperGraph::Data * data,HyperGraphElementAction::Parameters * params_)269 void DrawAction::drawUserData(HyperGraph::Data* data, HyperGraphElementAction::Parameters* params_){ 270 while (data && _cacheDrawActions ){ 271 (*_cacheDrawActions)(data, params_); 272 data=data->next(); 273 } 274 } 275 applyAction(HyperGraph * graph,HyperGraphElementAction * action,HyperGraphElementAction::Parameters * params,const std::string & typeName)276 void applyAction(HyperGraph* graph, HyperGraphElementAction* action, HyperGraphElementAction::Parameters* params, const std::string& typeName) 277 { 278 for (HyperGraph::VertexIDMap::iterator it=graph->vertices().begin(); 279 it!=graph->vertices().end(); ++it){ 280 auto& aux = *it->second; 281 if ( typeName.empty() || typeid(aux).name()==typeName){ 282 (*action)(it->second, params); 283 } 284 } 285 for (HyperGraph::EdgeSet::iterator it=graph->edges().begin(); 286 it!=graph->edges().end(); ++it){ 287 auto& aux = **it; 288 if ( typeName.empty() || typeid(aux).name()==typeName) 289 (*action)(*it, params); 290 } 291 } 292 293 } // end namespace 294