/******************************************************************************* * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * version 0.1 * * Copyright (C) 2009-2011, IGG Team, LSIIT, University of Strasbourg * * * * This library is free software; you can redistribute it and/or modify it * * under the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation; either version 2.1 of the License, or (at your * * option) any later version. * * * * This library is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * * for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this library; if not, write to the Free Software Foundation, * * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * * * Web site: http://cgogn.u-strasbg.fr/ * * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ #include "Topology/generic/genericmap.h" #include "Topology/generic/attributeHandler.h" #include "Topology/generic/dartmarker.h" #include "Geometry/vector_gen.h" #include "Geometry/matrix.h" #include "Container/registered.h" namespace CGoGN { std::map* GenericMap::m_attributes_registry_map = NULL ; GenericMap::GenericMap() : m_nbThreads(1) { if(m_attributes_registry_map == NULL) m_attributes_registry_map = new std::map ; // register all known types registerAttribute("Dart"); registerAttribute("Mark"); registerAttribute("long"); registerAttribute("int"); registerAttribute("short"); registerAttribute("char"); registerAttribute("unsigned long"); registerAttribute("unsigned int"); registerAttribute("unsigned short"); registerAttribute("unsigned char"); registerAttribute(Geom::Vec2f::CGoGNnameOfType()); registerAttribute(Geom::Vec3f::CGoGNnameOfType()); registerAttribute(Geom::Vec4f::CGoGNnameOfType()); registerAttribute(Geom::Vec2d::CGoGNnameOfType()); registerAttribute(Geom::Vec3d::CGoGNnameOfType()); registerAttribute(Geom::Vec4d::CGoGNnameOfType()); registerAttribute(Geom::Matrix33f::CGoGNnameOfType()); registerAttribute(Geom::Matrix44f::CGoGNnameOfType()); registerAttribute(Geom::Matrix33d::CGoGNnameOfType()); registerAttribute(Geom::Matrix44d::CGoGNnameOfType()); for(unsigned int i = 0; i < NB_ORBITS; ++i) { m_attribs[i].setOrbit(i) ; m_attribs[i].setRegistry(m_attributes_registry_map) ; m_embeddings[i] = NULL ; for(unsigned int j = 0; j < NB_THREAD; ++j) { m_marksets[i][j].clear() ; m_markTables[i][j] = NULL ; } } // get & lock marker for boundary m_boundaryMarker = m_marksets[DART][0].getNewMark(); } GenericMap::~GenericMap() { // release marker for boundary m_marksets[DART][0].releaseMark(m_boundaryMarker); for(unsigned int i = 0; i < NB_ORBITS; ++i) { if(isOrbitEmbedded(i)) m_attribs[i].clear(true) ; } if(m_attributes_registry_map) { delete m_attributes_registry_map; m_attributes_registry_map = NULL; } } void GenericMap::clear(bool removeAttrib) { if (removeAttrib) { for(unsigned int i = 0; i < NB_ORBITS; ++i) { m_attribs[i].clear(true) ; m_embeddings[i] = NULL ; for(unsigned int j = 0; j < NB_THREAD; ++j) { if (i != DART) // keep Marker reservation for DartMarker m_marksets[i][j].clear() ; m_markTables[i][j] = NULL ; } } for(std::multimap::iterator it = attributeHandlers.begin(); it != attributeHandlers.end(); ++it) (*it).second->setInvalid() ; attributeHandlers.clear() ; } else { for(unsigned int i = 0; i < NB_ORBITS; ++i) { m_attribs[i].clear(false) ; } } } /**************************************** * EMBEDDING MANAGEMENT * ****************************************/ void GenericMap::setDartEmbedding(unsigned int orbit, Dart d, unsigned int emb) { assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded"); unsigned int old = getEmbedding(orbit, d); // if same emb nothing to do if (old == emb) return; // if different then unref the old emb if (old != EMBNULL) { if(m_attribs[orbit].unrefLine(old)) { for (unsigned int t = 0; t < m_nbThreads; ++t) m_markTables[orbit][t]->operator[](old).clear(); } } // ref the new emb if (emb != EMBNULL) m_attribs[orbit].refLine(emb); // affect the embedding to the dart (*m_embeddings[orbit])[d.index] = emb ; } /**************************************** * ATTRIBUTES MANAGEMENT * ****************************************/ void GenericMap::initOrbitEmbedding(unsigned int orbit, bool realloc) { assert(isOrbitEmbedded(orbit) || !"Invalid parameter: orbit not embedded") ; DartMarker mark(*this) ; for(Dart d = begin(); d != end(); next(d)) { if(!mark.isMarked(d)) { mark.markOrbit(orbit, d) ; if(realloc || getEmbedding(orbit, d) == EMBNULL) embedNewCell(orbit, d) ; } } } template bool GenericMap::registerAttribute(const std::string &nameType) { RegisteredBaseAttribute* ra = new RegisteredAttribute; if (ra == NULL) { CGoGNerr << "Erreur enregistrement attribut" << CGoGNendl; return false; } ra->setTypeName(nameType); m_attributes_registry_map->insert(std::pair(nameType,ra)); return true; } /**************************************** * THREAD MANAGEMENT * ****************************************/ void GenericMap::addThreadMarker(unsigned int nb) { unsigned int th ; for (unsigned int j = 0; j < nb; ++j) { th = m_nbThreads ; m_nbThreads++ ; for (unsigned int i = 0; i < NB_ORBITS; ++i) { if (isOrbitEmbedded(i)) { std::stringstream ss ; ss << "Mark_"<< th ; AttributeContainer& cellCont = m_attribs[i] ; AttributeMultiVector* amvMark = cellCont.addAttribute(ss.str()) ; m_markTables[i][th] = amvMark ; } } } } unsigned int GenericMap::getNbThreadMarkers() { return m_nbThreads; } void GenericMap::removeThreadMarker(unsigned int nb) { unsigned int th = 0; while ((m_nbThreads > 1) && (nb > 0)) { th = --m_nbThreads ; --nb; for (unsigned int i = 0; i < NB_ORBITS; ++i) { if (isOrbitEmbedded(i)) { std::stringstream ss ; ss << "Mark_"<< th ; AttributeContainer& cellCont = m_attribs[i] ; cellCont.removeAttribute(ss.str()) ; m_markTables[i][th] = NULL ; } } } } /**************************************** * SAVE & LOAD * ****************************************/ void GenericMap::update_m_emb_afterLoad() { // get container of dart orbit AttributeContainer& cont = m_attribs[DART] ; // get the list of attributes std::vector listeNames; cont.getAttributesNames(listeNames); // check if there are EMB_X attributes for (unsigned int i = 0; i < listeNames.size(); ++i) { std::string sub = listeNames[i].substr(0,listeNames[i].size()-1); if (sub == "EMB_") { unsigned int orb = listeNames[i][4]-'0'; // easy atoi computation for one char; AttributeMultiVector* amv = cont.getDataVector(i); m_embeddings[orb] = amv ; CGoGNout << "Ajoute m_emb[" << orb << "] : " << i << CGoGNendl; } } } bool GenericMap::saveMapXml(const std::string& filename, bool compress) { xmlTextWriterPtr writer = xmlNewTextWriterFilename(filename.c_str(), 0); xmlTextWriterStartDocument(writer,NULL,NULL,NULL); // Entete int rc = xmlTextWriterStartElement(writer, BAD_CAST "CGoGN_Map"); rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST this->mapTypeName().c_str()); rc = xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "nb_max_orbits","%u",NB_ORBITS); // save m_attribs for (unsigned int i=0; iname),(char*)"CGoGN_Map")!=0) if (!chechXmlNode(map_node,"CGoGN_Map")) { CGoGNerr << "Wrong xml format: Root node != CGoGN_Map"<< CGoGNendl; return false; } // check the file type xmlChar *prop = xmlGetProp(map_node, BAD_CAST "type"); CGoGNout << "Loading "<< prop <<" xml file"<< CGoGNendl; // check the nb max orbits prop = xmlGetProp(map_node, BAD_CAST "nb_max_orbits"); unsigned int nbo = atoi((char*)prop); if (nbo != NB_ORBITS) { CGoGNerr << "Wrong nb max orbits in xml map"<< CGoGNendl; return false; } /*********************************************** * load attributs ************************************************/ for (xmlNode* cur_node = map_node->children; cur_node; cur_node = cur_node->next) { // for each attribute // if (strcmp((char*)(cur_node->name),(char*)"Attributes_Container")==0) if (chechXmlNode(cur_node, "Attributes_Container")) { CGoGNout << "LOAD ATTRIBUT"<< CGoGNendl; // get the orbit id unsigned int id = AttributeContainer::getIdXmlNode(cur_node); // and load container unsigned int nba = m_attribs[id].getNbAttributes(); CGoGNout << "attribut "<& amv = contDart.getDataVector(i) ; // // std::string orbitname = name.substr(4, name.size()-4); // std::istringstream iss(orbitname); // unsigned int orbit; // iss >> orbit; // // m_embeddings[orbit] = &amv ; // } // } // // update_m_emb_afterLoad(); /*********************************************** * load Orbit_MarkerSet & BoundaryMarker ************************************************/ xmlNode* cur_node = map_node->children; bool read1=false; bool read2=false; while (!(read1 || read2) && cur_node)// scan nodes to find the one with right name { // if (strcmp((char*)(cur_node->name),(char*)"Orbit_MarkerSet") == 0) if (chechXmlNode(cur_node, "Orbit_MarkerSet")) { for (xmlNode* mark_node = cur_node->children; mark_node; mark_node = mark_node->next) { xmlChar* prop = xmlGetProp(mark_node, BAD_CAST "orbit"); unsigned int orb = atoi((char*)prop); prop = xmlGetProp(mark_node, BAD_CAST "val"); unsigned int val = atoi((char*)prop); m_marksets[orb][0].setMarkVal(val); } read1 =true; } else { // if (strcmp((char*)(cur_node->name),(char*)"Boundary_Marker") == 0) CGoGNout << "Orbit_MarkerSet"<next; } if (!(read1 && read2)) { CGoGNerr <<"Error reading Marker in xml node"<(buff+64); *buffi = NB_ORBITS; fs.write(reinterpret_cast(buff), 256); delete buff; // save m_attribs for (unsigned int i=0; i buffer; buffer.reserve(NB_ORBITS+1); for (unsigned int i=0; i(&(buffer[0])), buffer.size()*sizeof(unsigned int)); return true; } bool GenericMap::loadMapBin(const std::string& filename) { CGoGNistream fs(filename.c_str(), std::ios::in|std::ios::binary); if (!fs) { CGoGNerr << "Unable to open file for loading" << CGoGNendl; return false; } // entete char* buff = new char[256]; fs.read(reinterpret_cast(buff), 256); std::string buff_str(buff); // Check file type if (buff_str != "CGoGN_Map") { CGoGNerr<< "Wrong binary file format"<< CGoGNendl; return false; } // Check map type buff_str = std::string(buff+32); CGoGNout << "Map type file = "<< buff_str<< CGoGNendl; std::string localType = this->mapTypeName(); localType = localType.substr(0,localType.size()-1); std::string fileType = buff_str.substr(0,buff_str.size()-1); if (fileType != localType) { CGoGNerr << "Not possible to load "<< fileType<< " into "<< localType << " object"<(buff+64); unsigned int nbo = *ptr_nbo; if (nbo != NB_ORBITS) { CGoGNerr << "Wrond max orbit number in file" << CGoGNendl; return false; } // load attrib container for (unsigned int i=0; i buffer; buffer.resize(NB_ORBITS); fs.read(reinterpret_cast(&(buffer[0])), (NB_ORBITS+1)*sizeof(unsigned int)); for (unsigned int i=0; i listeNames; cont.getAttributesNames(listeNames); for (std::vector::iterator it=listeNames.begin(); it!=listeNames.end(); ++it) std::cout<< " " << *it << std::endl; std::cout << "-------------------------"<< std::endl; } std::cout << "m_embeddings: "<operator[](d.index).setMark(m_boundaryMarker); } void GenericMap::boundaryUnmark(Dart d) { m_markTables[DART][0]->operator[](d.index).unsetMark(m_boundaryMarker); } bool GenericMap::isBoundaryMarked(Dart d) { return m_markTables[DART][0]->operator[](d.index).testMark(m_boundaryMarker); } void GenericMap::boundaryMarkOrbit(unsigned int orbit, Dart d) { FunctorMark fm(*this, m_boundaryMarker, m_markTables[DART][0]) ; foreach_dart_of_orbit(orbit, d, fm, 0) ; } void GenericMap::boundaryUnmarkOrbit(unsigned int orbit, Dart d) { FunctorUnmark fm(*this, m_boundaryMarker, m_markTables[DART][0]) ; foreach_dart_of_orbit(orbit, d, fm, 0) ; } void GenericMap::boundaryUnmarkAll() { AttributeContainer& cont = getAttributeContainer(DART) ; for (unsigned int i = cont.begin(); i != cont.end(); cont.next(i)) m_markTables[DART][0]->operator[](i).unsetMark(m_boundaryMarker); } } // namespace CGoGN