Commit 549f0bff authored by Sylvain Thery's avatar Sylvain Thery
Browse files

resolve bug of deleted marked darts

parent 09aaaf4e
...@@ -59,6 +59,7 @@ find_package(OpenGL REQUIRED) ...@@ -59,6 +59,7 @@ find_package(OpenGL REQUIRED)
find_package(Boost COMPONENTS regex REQUIRED) find_package(Boost COMPONENTS regex REQUIRED)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
#find_package(LibXml2 REQUIRED) #find_package(LibXml2 REQUIRED)
find_package(TinyXml2 REQUIRED)
find_package(GLEW REQUIRED) find_package(GLEW REQUIRED)
# MESSAGE HERE FOR MORE EASY USER READING # MESSAGE HERE FOR MORE EASY USER READING
...@@ -98,7 +99,7 @@ SET (CGoGN_EXT_INCLUDES ...@@ -98,7 +99,7 @@ SET (CGoGN_EXT_INCLUDES
${OPENGL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}
${GLEW_INCLUDE_DIRS} ${GLEW_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS}
# ${LIBXML2_INCLUDE_DIR} ${TINYXML2_INCLUDE_DIR}
${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
) )
...@@ -108,8 +109,7 @@ SET (CGoGN_EXT_LIBS ...@@ -108,8 +109,7 @@ SET (CGoGN_EXT_LIBS
${OPENGL_LIBRARY} ${OPENGL_LIBRARY}
${GLEW_LIBRARIES} ${GLEW_LIBRARIES}
${ZLIB_LIBRARIES} ${ZLIB_LIBRARIES}
# ${LIBXML2_LIBRARIES} ${TINYXML2_LIBRARY}
tinyxml2
${Boost_REGEX_LIBRARY} ${Boost_REGEX_LIBRARY}
) )
......
...@@ -38,7 +38,6 @@ namespace CGoGN ...@@ -38,7 +38,6 @@ namespace CGoGN
class RegisteredBaseAttribute; class RegisteredBaseAttribute;
class AttributeContainer; class AttributeContainer;
class ContainerBrowser class ContainerBrowser
{ {
public: public:
...@@ -73,6 +72,11 @@ protected: ...@@ -73,6 +72,11 @@ protected:
*/ */
std::vector<AttributeMultiVectorGen*> m_tableAttribs; std::vector<AttributeMultiVectorGen*> m_tableAttribs;
/**
* vector of pointers to AttributeMultiVectors of MarkerBool
*/
std::vector<AttributeMultiVector<MarkerBool>*> m_tableMarkerAttribs;
/** /**
* vector of free indices in the vector of AttributeMultiVectors * vector of free indices in the vector of AttributeMultiVectors
*/ */
...@@ -158,6 +162,10 @@ public: ...@@ -158,6 +162,10 @@ public:
template <typename T> template <typename T>
AttributeMultiVector<T>* addAttribute(const std::string& attribName); AttributeMultiVector<T>* addAttribute(const std::string& attribName);
/// special version for marker
AttributeMultiVector<MarkerBool>* addMarkerAttribute(const std::string& attribName);
/** /**
* add a new attribute to the container * add a new attribute to the container
* @param typeName type of the new attribute in a string * @param typeName type of the new attribute in a string
...@@ -187,6 +195,8 @@ public: ...@@ -187,6 +195,8 @@ public:
template <typename T> template <typename T>
bool removeAttribute(const std::string& attribName); bool removeAttribute(const std::string& attribName);
bool removeMarkerAttribute(const std::string& attribName);
/** /**
* Remove an attribute (destroys data) * Remove an attribute (destroys data)
* @param index index of the attribute to remove * @param index index of the attribute to remove
...@@ -322,6 +332,7 @@ public: ...@@ -322,6 +332,7 @@ public:
*/ */
unsigned int getAttributesNames(std::vector<std::string>& names) const; unsigned int getAttributesNames(std::vector<std::string>& names) const;
/** /**
* fill a vector with attribute type names * fill a vector with attribute type names
* @param types vector of type names * @param types vector of type names
...@@ -329,6 +340,8 @@ public: ...@@ -329,6 +340,8 @@ public:
*/ */
unsigned int getAttributesTypes(std::vector<std::string>& types); unsigned int getAttributesTypes(std::vector<std::string>& types);
std::vector<AttributeMultiVector<MarkerBool>*>& getMarkerAttributes();
/************************************** /**************************************
* CONTAINER MANAGEMENT * * CONTAINER MANAGEMENT *
**************************************/ **************************************/
...@@ -444,6 +457,7 @@ public: ...@@ -444,6 +457,7 @@ public:
AttributeMultiVectorGen* getVirtualDataVector(unsigned int attrIndex); AttributeMultiVectorGen* getVirtualDataVector(unsigned int attrIndex);
/** /**
* get an AttributeMultiVector * get an AttributeMultiVector
* @param attribName name of the attribute * @param attribName name of the attribute
......
...@@ -43,6 +43,11 @@ inline void AttributeContainer::setOrbit(unsigned int orbit) ...@@ -43,6 +43,11 @@ inline void AttributeContainer::setOrbit(unsigned int orbit)
if (m_tableAttribs[i] != NULL) if (m_tableAttribs[i] != NULL)
m_tableAttribs[i]->setOrbit(orbit); m_tableAttribs[i]->setOrbit(orbit);
} }
for(unsigned int i = 0; i < m_tableMarkerAttribs.size(); ++i)
{
m_tableMarkerAttribs[i]->setOrbit(orbit);
}
} }
inline void AttributeContainer::setRegistry(std::map< std::string, RegisteredBaseAttribute* >* re) inline void AttributeContainer::setRegistry(std::map< std::string, RegisteredBaseAttribute* >* re)
...@@ -340,10 +345,9 @@ inline void AttributeContainer::initLine(unsigned int index) ...@@ -340,10 +345,9 @@ inline void AttributeContainer::initLine(unsigned int index)
inline void AttributeContainer::initMarkersOfLine(unsigned int index) inline void AttributeContainer::initMarkersOfLine(unsigned int index)
{ {
for(unsigned int i = 0; i < m_tableAttribs.size(); ++i) for(unsigned int i = 0; i < m_tableMarkerAttribs.size(); ++i)
{ {
if ((m_tableAttribs[i] != NULL) && (m_tableAttribs[i]->isMarkerBool())) m_tableMarkerAttribs[i]->initElt(index);
m_tableAttribs[i]->initElt(index);
} }
} }
...@@ -355,6 +359,12 @@ inline void AttributeContainer::copyLine(unsigned int dstIndex, unsigned int src ...@@ -355,6 +359,12 @@ inline void AttributeContainer::copyLine(unsigned int dstIndex, unsigned int src
if (m_tableAttribs[i] != NULL) if (m_tableAttribs[i] != NULL)
m_tableAttribs[i]->copyElt(dstIndex, srcIndex); m_tableAttribs[i]->copyElt(dstIndex, srcIndex);
} }
for(unsigned int i = 0; i < m_tableMarkerAttribs.size(); ++i)
{
m_tableMarkerAttribs[i]->copyElt(dstIndex, srcIndex);
}
} }
inline void AttributeContainer::refLine(unsigned int index) inline void AttributeContainer::refLine(unsigned int index)
...@@ -490,4 +500,12 @@ inline void AttributeContainer::setData(unsigned int attrIndex, unsigned int elt ...@@ -490,4 +500,12 @@ inline void AttributeContainer::setData(unsigned int attrIndex, unsigned int elt
atm->operator[](eltIndex) = data; atm->operator[](eltIndex) = data;
} }
inline std::vector<AttributeMultiVector<MarkerBool>*>& AttributeContainer::getMarkerAttributes()
{
return m_tableMarkerAttribs;
}
} // namespace CGoGN } // namespace CGoGN
...@@ -211,7 +211,6 @@ inline unsigned int GenericMap::newCell() ...@@ -211,7 +211,6 @@ inline unsigned int GenericMap::newCell()
unsigned int c = m_attribs[ORBIT].insertLine(); unsigned int c = m_attribs[ORBIT].insertLine();
m_attribs[ORBIT].initMarkersOfLine(c); m_attribs[ORBIT].initMarkersOfLine(c);
return c; return c;
// return m_attribs[ORBIT].insertLine();
} }
template <unsigned int ORBIT> template <unsigned int ORBIT>
...@@ -291,7 +290,7 @@ AttributeMultiVector<MarkerBool>* GenericMap::askMarkVector() ...@@ -291,7 +290,7 @@ AttributeMultiVector<MarkerBool>* GenericMap::askMarkVector()
x = x/10; x = x/10;
number[0]= '0'+x%10; number[0]= '0'+x%10;
AttributeMultiVector<MarkerBool>* amv = m_attribs[ORBIT].addAttribute<MarkerBool>("marker_" + orbitName(ORBIT) + number); AttributeMultiVector<MarkerBool>* amv = m_attribs[ORBIT].addMarkerAttribute("marker_" + orbitName(ORBIT) + number);
return amv; return amv;
} }
} }
......
...@@ -49,7 +49,7 @@ inline std::string XMLAttribute(tinyxml2::XMLElement* node, const char* attName) ...@@ -49,7 +49,7 @@ inline std::string XMLAttribute(tinyxml2::XMLElement* node, const char* attName)
const char *ptr = node->Attribute(attName); const char *ptr = node->Attribute(attName);
if (ptr == NULL) if (ptr == NULL)
{ {
CGoGNerr << "Warning attrbute "<< attName << " not found"<< CGoGNendl; CGoGNerr << "Warning attribute "<< attName << " not found"<< CGoGNendl;
return ""; return "";
} }
return std::string(ptr); return std::string(ptr);
......
...@@ -115,6 +115,8 @@ unsigned int AttributeContainer::getAttributesNames(std::vector<std::string>& na ...@@ -115,6 +115,8 @@ unsigned int AttributeContainer::getAttributesNames(std::vector<std::string>& na
return m_nbAttributes ; return m_nbAttributes ;
} }
unsigned int AttributeContainer::getAttributesTypes(std::vector<std::string>& types) unsigned int AttributeContainer::getAttributesTypes(std::vector<std::string>& types)
{ {
types.clear() ; types.clear() ;
...@@ -129,6 +131,7 @@ unsigned int AttributeContainer::getAttributesTypes(std::vector<std::string>& ty ...@@ -129,6 +131,7 @@ unsigned int AttributeContainer::getAttributesTypes(std::vector<std::string>& ty
return m_nbAttributes ; return m_nbAttributes ;
} }
/************************************** /**************************************
* CONTAINER MANAGEMENT * * CONTAINER MANAGEMENT *
**************************************/ **************************************/
...@@ -138,6 +141,7 @@ void AttributeContainer::swap(AttributeContainer& cont) ...@@ -138,6 +141,7 @@ void AttributeContainer::swap(AttributeContainer& cont)
// swap everything but the orbit // swap everything but the orbit
m_tableAttribs.swap(cont.m_tableAttribs); m_tableAttribs.swap(cont.m_tableAttribs);
m_tableMarkerAttribs.swap(cont.m_tableMarkerAttribs);
m_freeIndices.swap(cont.m_freeIndices); m_freeIndices.swap(cont.m_freeIndices);
m_holesBlocks.swap(cont.m_holesBlocks); m_holesBlocks.swap(cont.m_holesBlocks);
m_tableBlocksWithFree.swap(cont.m_tableBlocksWithFree); m_tableBlocksWithFree.swap(cont.m_tableBlocksWithFree);
...@@ -200,10 +204,19 @@ void AttributeContainer::clear(bool removeAttrib) ...@@ -200,10 +204,19 @@ void AttributeContainer::clear(bool removeAttrib)
if ((*it) != NULL) if ((*it) != NULL)
delete (*it); delete (*it);
} }
std::vector<AttributeMultiVectorGen*> amg; std::vector<AttributeMultiVectorGen*> amg;
m_tableAttribs.swap(amg); m_tableAttribs.swap(amg);
// detruit tous les attributs MarkerBool
for (std::vector<AttributeMultiVector<MarkerBool>*>::iterator it = m_tableMarkerAttribs.begin(); it != m_tableMarkerAttribs.end(); ++it)
{
if ((*it) != NULL)
delete (*it);
}
std::vector<AttributeMultiVector<MarkerBool>*> amgb;
m_tableMarkerAttribs.swap(amgb);
std::vector<unsigned int> fi; std::vector<unsigned int> fi;
m_freeIndices.swap(fi); m_freeIndices.swap(fi);
} }
...@@ -211,16 +224,15 @@ void AttributeContainer::clear(bool removeAttrib) ...@@ -211,16 +224,15 @@ void AttributeContainer::clear(bool removeAttrib)
bool AttributeContainer::hasMarkerAttribute() const bool AttributeContainer::hasMarkerAttribute() const
{ {
for (auto it = m_tableAttribs.begin(); it != m_tableAttribs.end(); ++it) // not only size() != 0 because of BoundaryMarkers !
for (auto it = m_tableMarkerAttribs.begin(); it != m_tableMarkerAttribs.end(); ++it)
{ {
if ((*it) != NULL) std::string strMarker = (*it)->getName().substr(0,6);
{ if (strMarker=="marker")
std::string strMarker = (*it)->getName().substr(0,6); return true;
if (strMarker=="marker")
return true;
}
} }
return false; return false;
} }
...@@ -355,6 +367,13 @@ unsigned int AttributeContainer::insertLine() ...@@ -355,6 +367,13 @@ unsigned int AttributeContainer::insertLine()
m_tableAttribs[i]->addBlock(); // add a block to every attribute m_tableAttribs[i]->addBlock(); // add a block to every attribute
} }
for(unsigned int i = 0; i < m_tableMarkerAttribs.size(); ++i)
{
if (m_tableMarkerAttribs[i] != NULL)
m_tableMarkerAttribs[i]->addBlock(); // add a block to every attribute
}
// inc nb of elements // inc nb of elements
++m_size; ++m_size;
...@@ -390,6 +409,11 @@ unsigned int AttributeContainer::insertLine() ...@@ -390,6 +409,11 @@ unsigned int AttributeContainer::insertLine()
if (m_tableAttribs[i] != NULL) if (m_tableAttribs[i] != NULL)
m_tableAttribs[i]->addBlock(); // add a block to every attribute m_tableAttribs[i]->addBlock(); // add a block to every attribute
} }
for(unsigned int i = 0; i < m_tableMarkerAttribs.size(); ++i)
{
if (m_tableMarkerAttribs[i] != NULL)
m_tableMarkerAttribs[i]->addBlock(); // add a block to every attribute
}
} }
} }
...@@ -435,18 +459,22 @@ void AttributeContainer::saveBin(CGoGNostream& fs, unsigned int id) const ...@@ -435,18 +459,22 @@ void AttributeContainer::saveBin(CGoGNostream& fs, unsigned int id) const
std::vector<AttributeMultiVectorGen*> bufferamv; std::vector<AttributeMultiVectorGen*> bufferamv;
bufferamv.reserve(m_tableAttribs.size()); bufferamv.reserve(m_tableAttribs.size());
// for(std::vector<AttributeMultiVectorGen*>::const_iterator it = m_tableAttribs.begin(); it != m_tableAttribs.end(); ++it)
// {
// if (*it != NULL)
// {
// const std::string& attName = (*it)->getName();
// std::string markName = attName.substr(0,7);
// if (markName != "marker_")
// bufferamv.push_back(*it);
// }
// }
for(std::vector<AttributeMultiVectorGen*>::const_iterator it = m_tableAttribs.begin(); it != m_tableAttribs.end(); ++it) for(std::vector<AttributeMultiVectorGen*>::const_iterator it = m_tableAttribs.begin(); it != m_tableAttribs.end(); ++it)
{ {
if (*it != NULL) if (*it != NULL)
{ bufferamv.push_back(*it);
const std::string& attName = (*it)->getName();
std::string markName = attName.substr(0,7);
if (markName != "marker_")
bufferamv.push_back(*it);
}
} }
// en ascii id et les tailles // en ascii id et les tailles
std::vector<unsigned int> bufferui; std::vector<unsigned int> bufferui;
...@@ -456,32 +484,34 @@ void AttributeContainer::saveBin(CGoGNostream& fs, unsigned int id) const ...@@ -456,32 +484,34 @@ void AttributeContainer::saveBin(CGoGNostream& fs, unsigned int id) const
bufferui.push_back(_BLOCKSIZE_); bufferui.push_back(_BLOCKSIZE_);
bufferui.push_back(m_holesBlocks.size()); bufferui.push_back(m_holesBlocks.size());
bufferui.push_back(m_tableBlocksWithFree.size()); bufferui.push_back(m_tableBlocksWithFree.size());
// bufferui.push_back(m_nbAttributes);
bufferui.push_back(bufferamv.size()); bufferui.push_back(bufferamv.size());
bufferui.push_back(m_size); bufferui.push_back(m_size);
bufferui.push_back(m_maxSize); bufferui.push_back(m_maxSize);
bufferui.push_back(m_orbit); bufferui.push_back(m_orbit);
bufferui.push_back(m_nbUnknown); bufferui.push_back(m_nbUnknown);
// count attribute of boundary markers and increase nb of saved attributes
for(std::vector<AttributeMultiVector<MarkerBool>*>::const_iterator it = m_tableMarkerAttribs.begin(); it != m_tableMarkerAttribs.end(); ++it)
{
const std::string& attName = (*it)->getName();
if (attName[0] == 'B') // for BoundaryMark0/1
bufferui[4]++;
}
fs.write(reinterpret_cast<const char*>(&bufferui[0]), bufferui.size()*sizeof(unsigned int)); fs.write(reinterpret_cast<const char*>(&bufferui[0]), bufferui.size()*sizeof(unsigned int));
unsigned int i = 0; unsigned int i = 0;
for(std::vector<AttributeMultiVector<MarkerBool>*>::const_iterator it = m_tableMarkerAttribs.begin(); it != m_tableMarkerAttribs.end(); ++it)
{
const std::string& attName = (*it)->getName();
if (attName[0] == 'B') // for BoundaryMark0/1
(*it)->saveBin(fs, i++);
}
for(std::vector<AttributeMultiVectorGen*>::const_iterator it = bufferamv.begin(); it != bufferamv.end(); ++it) for(std::vector<AttributeMultiVectorGen*>::const_iterator it = bufferamv.begin(); it != bufferamv.end(); ++it)
{ {
if (*it != NULL) (*it)->saveBin(fs, i++);
{
const std::string& attName = (*it)->getName();
std::string markName = attName.substr(0,7);
if (markName != "marker_")
(*it)->saveBin(fs, i++);
}
else
{
CGoGNerr << "PB saving, NULL ptr in m_tableAttribs" << CGoGNendl;
i++;
}
} }
//en binaire les blocks de ref //en binaire les blocks de ref
...@@ -544,9 +574,17 @@ bool AttributeContainer::loadBin(CGoGNistream& fs) ...@@ -544,9 +574,17 @@ bool AttributeContainer::loadBin(CGoGNistream& fs)
} }
else else
{ {
RegisteredBaseAttribute* ra = itAtt->second; if (typeAtt == "MarkerBool")
AttributeMultiVectorGen* amvg = ra->addAttribute(*this, nameAtt); {
amvg->loadBin(fs); assert(j<m_tableMarkerAttribs.size());
m_tableMarkerAttribs[j]->loadBin(fs); // use j because BM are saved first
}
else
{
RegisteredBaseAttribute* ra = itAtt->second;
AttributeMultiVectorGen* amvg = ra->addAttribute(*this, nameAtt);
amvg->loadBin(fs);
}
} }
} }
...@@ -608,31 +646,27 @@ void AttributeContainer::copyFrom(const AttributeContainer& cont) ...@@ -608,31 +646,27 @@ void AttributeContainer::copyFrom(const AttributeContainer& cont)
{ {
if (cont.m_tableAttribs[i] != NULL) if (cont.m_tableAttribs[i] != NULL)
{ {
std::string sub = cont.m_tableAttribs[i]->getName().substr(0, 5); AttributeMultiVectorGen* ptr = cont.m_tableAttribs[i]->new_obj();
if (sub != "Mark_") // Mark leaved by ptr->setName(cont.m_tableAttribs[i]->getName());
{ ptr->setOrbit(cont.m_tableAttribs[i]->getOrbit());
AttributeMultiVectorGen* ptr = cont.m_tableAttribs[i]->new_obj(); ptr->setIndex(m_tableAttribs.size());
ptr->setName(cont.m_tableAttribs[i]->getName()); ptr->setNbBlocks(cont.m_tableAttribs[i]->getNbBlocks());
ptr->setOrbit(cont.m_tableAttribs[i]->getOrbit()); ptr->copy(cont.m_tableAttribs[i]);
ptr->setIndex(m_tableAttribs.size()); m_tableAttribs.push_back(ptr);
ptr->setNbBlocks(cont.m_tableAttribs[i]->getNbBlocks());
ptr->copy(cont.m_tableAttribs[i]);
m_tableAttribs.push_back(ptr);
}
else
{
// get id of thread
const std::string& str = cont.m_tableAttribs[i]->getName();
unsigned int thId = (unsigned int)(str[5]-'0');
if (str.size()==7)
thId = 10*thId + (unsigned int)(sub[6]-'0');
// Mark always at the begin, because called after clear
AttributeMultiVectorGen* ptr = m_tableAttribs[thId];
ptr->setNbBlocks(cont.m_tableAttribs[i]->getNbBlocks());
ptr->copy(cont.m_tableAttribs[i]);
}
} }
} }
sz = cont.m_tableMarkerAttribs.size();
for (unsigned int i = 0; i < sz; ++i)
{
AttributeMultiVector<MarkerBool>* ptr = new AttributeMultiVector<MarkerBool>;
ptr->setTypeName(cont.m_tableMarkerAttribs[i]->getTypeName());
ptr->setName(cont.m_tableMarkerAttribs[i]->getName());
ptr->setOrbit(cont.m_tableMarkerAttribs[i]->getOrbit());
ptr->setIndex(m_tableMarkerAttribs.size());
ptr->setNbBlocks(cont.m_tableMarkerAttribs[i]->getNbBlocks());
ptr->copy(cont.m_tableMarkerAttribs[i]);
m_tableMarkerAttribs.push_back(ptr);
}
} }
void AttributeContainer::dumpCSV() const void AttributeContainer::dumpCSV() const
...@@ -645,6 +679,10 @@ void AttributeContainer::dumpCSV() const ...@@ -645,6 +679,10 @@ void AttributeContainer::dumpCSV() const
CGoGNout << m_tableAttribs[i]->getName() << " ; "; CGoGNout << m_tableAttribs[i]->getName() << " ; ";
} }
} }
for (unsigned int i = 0; i < m_tableMarkerAttribs.size(); ++i)
{
CGoGNout << m_tableMarkerAttribs[i]->getName() << " ; ";
}
CGoGNout << CGoGNendl; CGoGNout << CGoGNendl;
CGoGNout << "Type ; ;"; CGoGNout << "Type ; ;";
for (unsigned int i = 0; i < m_tableAttribs.size(); ++i) for (unsigned int i = 0; i < m_tableAttribs.size(); ++i)
...@@ -654,6 +692,10 @@ void AttributeContainer::dumpCSV() const ...@@ -654,6 +692,10 @@ void AttributeContainer::dumpCSV() const
CGoGNout << m_tableAttribs[i]->getTypeName() << " ; "; CGoGNout << m_tableAttribs[i]->getTypeName() << " ; ";
} }
} }
for (unsigned int i = 0; i < m_tableMarkerAttribs.size(); ++i)
{
CGoGNout << m_tableMarkerAttribs[i]->getTypeName() << " ; ";
}
CGoGNout << CGoGNendl; CGoGNout << CGoGNendl;
CGoGNout << "line ; refs ;"; CGoGNout << "line ; refs ;";
for (unsigned int i = 0; i < m_tableAttribs.size(); ++i) for (unsigned int i = 0; i < m_tableAttribs.size(); ++i)
...@@ -663,6 +705,10 @@ void AttributeContainer::dumpCSV() const ...@@ -663,6 +705,10 @@ void AttributeContainer::dumpCSV() const
CGoGNout << "value;"; CGoGNout << "value;";
} }
} }
for (unsigned int i = 0; i < m_tableMarkerAttribs.size(); ++i)
{
CGoGNout << "value;";
}
CGoGNout << CGoGNendl; CGoGNout << CGoGNendl;
for (unsigned int l=this->begin(); l!= this->end(); this->next(l)) for (unsigned int l=this->begin(); l!= this->end(); this->next(l))
...@@ -676,6 +722,12 @@ void AttributeContainer::dumpCSV() const ...@@ -676,6 +722,12 @@ void AttributeContainer::dumpCSV() const
CGoGNout << " ; "; CGoGNout << " ; ";
} }
} }