geom/src/XAO/XaoExporter.cxx
2013-08-28 15:22:43 +00:00

512 lines
18 KiB
C++

#include <libxml/parser.h>
#include <Utils_SALOME_Exception.hxx>
#include "XaoExporter.hxx"
#include "Xao.hxx"
#include "Geometry.hxx"
#include "Group.hxx"
#include "Field.hxx"
#include "Step.hxx"
#include "BooleanStep.hxx"
#include "IntegerStep.hxx"
#include "DoubleStep.hxx"
#include "StringStep.hxx"
#include "XaoUtils.hxx"
namespace XAO
{
const xmlChar* C_TAG_XAO = (xmlChar*)"XAO";
const xmlChar* C_ATTR_XAO_AUTHOR = (xmlChar*)"author";
const xmlChar* C_ATTR_XAO_VERSION = (xmlChar*)"version";
const xmlChar* C_TAG_GEOMETRY = (xmlChar*)"geometry";
const xmlChar* C_ATTR_GEOMETRY_NAME = (xmlChar*)"name";
const xmlChar* C_TAG_SHAPE = (xmlChar*)"shape";
const xmlChar* C_ATTR_SHAPE_FORMAT = (xmlChar*)"format";
const xmlChar* C_TAG_TOPOLOGY = (xmlChar*)"topology";
const xmlChar* C_TAG_VERTICES = (xmlChar*)"vertices";
const xmlChar* C_TAG_VERTEX = (xmlChar*)"vertex";
const xmlChar* C_TAG_EDGES = (xmlChar*)"edges";
const xmlChar* C_TAG_EDGE = (xmlChar*)"edge";
const xmlChar* C_TAG_FACES = (xmlChar*)"faces";
const xmlChar* C_TAG_FACE = (xmlChar*)"face";
const xmlChar* C_TAG_SOLIDS = (xmlChar*)"solids";
const xmlChar* C_TAG_SOLID = (xmlChar*)"solid";
const xmlChar* C_ATTR_COUNT = (xmlChar*)"count";
const xmlChar* C_ATTR_ELT_INDEX = (xmlChar*)"index";
const xmlChar* C_ATTR_ELT_NAME = (xmlChar*)"name";
const xmlChar* C_ATTR_ELT_REFERENCE = (xmlChar*)"reference";
const xmlChar* C_TAG_GROUPS = (xmlChar*)"groups";
const xmlChar* C_TAG_GROUP = (xmlChar*)"group";
const xmlChar* C_ATTR_GROUP_NAME = (xmlChar*)"name";
const xmlChar* C_ATTR_GROUP_DIM = (xmlChar*)"dimension";
const xmlChar* C_TAG_ELEMENT = (xmlChar*)"element";
const xmlChar* C_ATTR_ELEMENT_INDEX = (xmlChar*)"index";
const xmlChar* C_TAG_VALUE = (xmlChar*)"value";
const xmlChar* C_ATTR_VALUE_COMPONENT = (xmlChar*)"component";
const xmlChar* C_TAG_FIELDS = (xmlChar*)"fields";
const xmlChar* C_TAG_FIELD = (xmlChar*)"field";
const xmlChar* C_ATTR_FIELD_NAME = (xmlChar*)"name";
const xmlChar* C_ATTR_FIELD_TYPE = (xmlChar*)"type";
const xmlChar* C_ATTR_FIELD_DIMENSION = (xmlChar*)"dimension";
const xmlChar* C_TAG_COMPONENTS = (xmlChar*)"components";
const xmlChar* C_TAG_COMPONENT = (xmlChar*)"component";
const xmlChar* C_ATTR_COMPONENT_COLUMN = (xmlChar*)"column";
const xmlChar* C_ATTR_COMPONENT_NAME = (xmlChar*)"name";
const xmlChar* C_TAG_STEPS = (xmlChar*)"steps";
const xmlChar* C_TAG_STEP = (xmlChar*)"step";
const xmlChar* C_ATTR_STEP_NUMBER = (xmlChar*)"number";
const xmlChar* C_ATTR_STEP_STAMP = (xmlChar*)"stamp";
}
using namespace XAO;
const bool XaoExporter::saveToFile(Xao* xaoObject, const std::string& fileName)
{
xmlDocPtr doc = exportXMLDoc(xaoObject);
xmlSaveFormatFileEnc(fileName.c_str(), doc, "UTF-8", 2);
xmlFreeDoc(doc);
return true;
}
const std::string XaoExporter::saveToXml(Xao* xaoObject)
{
xmlDocPtr doc = exportXMLDoc(xaoObject);
xmlChar *xmlbuff;
int buffersize;
xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1);
xmlFreeDoc(doc);
xmlCleanupGlobals();
return (char*)xmlbuff;
}
xmlDocPtr XaoExporter::exportXMLDoc(Xao* xaoObject)
{
// Creating the Xml document
xmlDocPtr masterDocument = xmlNewDoc(BAD_CAST "1.0");
xmlNodePtr xao = xmlNewNode(0, C_TAG_XAO);
xmlDocSetRootElement(masterDocument, xao);
xmlNewProp(xao, C_ATTR_XAO_VERSION, BAD_CAST xaoObject->getVersion().c_str());
xmlNewProp(xao, C_ATTR_XAO_AUTHOR, BAD_CAST xaoObject->getAuthor().c_str());
if (xaoObject->getGeometry() != NULL)
{
exportGeometry(xaoObject->getGeometry(), masterDocument, xao);
}
exportGroups(xaoObject, xao);
exportFields(xaoObject, xao);
return masterDocument;
}
void XaoExporter::exportGeometricElements(Geometry* xaoGeometry,
xmlNodePtr topology, XAO::Dimension dim, const xmlChar* colTag, const xmlChar* eltTag)
{
xmlNodePtr vertices = xmlNewChild(topology, 0, colTag, 0);
xmlNewProp(vertices, C_ATTR_COUNT, BAD_CAST XaoUtils::intToString(xaoGeometry->countVertices()).c_str());
GeometricElementList::iterator it = xaoGeometry->begin(dim);
for (; it != xaoGeometry->end(dim); it++)
{
int index = it->first;
GeometricElement elt = it->second;
xmlNodePtr vertex = xmlNewChild(vertices, 0, eltTag, 0);
xmlNewProp(vertex, C_ATTR_ELT_INDEX, BAD_CAST XaoUtils::intToString(index).c_str());
//xmlNewProp(vertex, C_ATTR_ELT_NAME, BAD_CAST xaoGeometry->getVertexName(i));
//xmlNewProp(vertex, C_ATTR_ELT_REFERENCE, BAD_CAST xaoGeometry->getVertexReference(i));
xmlNewProp(vertex, C_ATTR_ELT_NAME, BAD_CAST elt.getName().c_str());
xmlNewProp(vertex, C_ATTR_ELT_REFERENCE, BAD_CAST elt.getReference().c_str());
}
}
void XaoExporter::exportGeometry(Geometry* xaoGeometry, xmlDocPtr doc, xmlNodePtr xao)
{
// Geometric part
xmlNodePtr geometry = xmlNewChild(xao, 0, C_TAG_GEOMETRY, 0);
xmlNewProp(geometry, C_ATTR_GEOMETRY_NAME, BAD_CAST xaoGeometry->getName().c_str());
xmlNodePtr shape = xmlNewChild(geometry, 0, C_TAG_SHAPE, 0);
xmlNewProp(shape, C_ATTR_SHAPE_FORMAT, BAD_CAST xaoGeometry->getFormat().c_str());
const char* brep = xaoGeometry->getBREP();
xmlNodePtr cdata = xmlNewCDataBlock(doc, BAD_CAST brep, strlen(brep));
xmlAddChild(shape, cdata);
xmlNodePtr topology = xmlNewChild(geometry, 0, C_TAG_TOPOLOGY, 0);
exportGeometricElements(xaoGeometry, topology, XAO::VERTEX, C_TAG_VERTICES, C_TAG_VERTEX);
exportGeometricElements(xaoGeometry, topology, XAO::EDGE, C_TAG_EDGES, C_TAG_EDGE);
exportGeometricElements(xaoGeometry, topology, XAO::FACE, C_TAG_FACES, C_TAG_FACE);
exportGeometricElements(xaoGeometry, topology, XAO::SOLID, C_TAG_SOLIDS, C_TAG_SOLID);
}
void XaoExporter::exportGroups(Xao* xaoObject, xmlNodePtr xao)
{
xmlNodePtr groups = xmlNewChild(xao, 0, C_TAG_GROUPS, 0);
xmlNewProp(groups, C_ATTR_COUNT, BAD_CAST XaoUtils::intToString(xaoObject->countGroups()).c_str());
//for (std::list<Group*>::iterator it = m_groups.begin(); it != m_groups.end(); ++it)
for (int i = 0; i < xaoObject->countGroups(); i++)
{
//Group* grp = (*it);
Group* grp = xaoObject->getGroup(i);
xmlNodePtr group = xmlNewChild(groups, 0, C_TAG_GROUP, 0);
xmlNewProp(group, C_ATTR_GROUP_NAME, BAD_CAST grp->getName().c_str());
xmlNewProp(group, C_ATTR_GROUP_DIM, BAD_CAST XaoUtils::dimensionToString(grp->getDimension()).c_str());
xmlNewProp(group, C_ATTR_COUNT, BAD_CAST XaoUtils::intToString(grp->getCount()).c_str());
for (int j = 0; j < grp->getCount(); j++)
{
xmlNodePtr elt = xmlNewChild(group, 0, C_TAG_ELEMENT, 0);
xmlNewProp(elt, C_ATTR_ELEMENT_INDEX, BAD_CAST XaoUtils::intToString(grp->getElement(j)).c_str());
}
}
}
void XaoExporter::exportFields(Xao* xaoObject, xmlNodePtr xao)
{
xmlNodePtr fields = xmlNewChild(xao, 0, C_TAG_FIELDS, 0);
xmlNewProp(fields, C_ATTR_COUNT, BAD_CAST XaoUtils::intToString(xaoObject->countFields()).c_str());
for (int i = 0; i < xaoObject->countFields(); i++)
{
Field* field = xaoObject->getField(i);
xmlNodePtr nodeField = xmlNewChild(fields, 0, C_TAG_FIELD, 0);
xmlNewProp(nodeField, C_ATTR_FIELD_NAME, BAD_CAST field->getName().c_str());
xmlNewProp(nodeField, C_ATTR_FIELD_TYPE, BAD_CAST XaoUtils::fieldTypeToString(field->getType()).c_str());
xmlNewProp(nodeField, C_ATTR_FIELD_DIMENSION, BAD_CAST XaoUtils::dimensionToString(field->getDimension()).c_str());
int nbComponents = field->countComponents();
xmlNodePtr components = xmlNewChild(nodeField, 0, C_TAG_COMPONENTS, 0);
xmlNewProp(components, C_ATTR_COUNT, BAD_CAST XaoUtils::intToString(nbComponents).c_str());
for (int j = 0; j < nbComponents; j++)
{
xmlNodePtr nodeComponent = xmlNewChild(components, 0, C_TAG_COMPONENT, 0);
xmlNewProp(nodeComponent, C_ATTR_COMPONENT_COLUMN, BAD_CAST XaoUtils::intToString(j).c_str());
xmlNewProp(nodeComponent, C_ATTR_COMPONENT_NAME, BAD_CAST field->getComponentName(j).c_str());
}
int nbSteps = field->countSteps();
xmlNodePtr nodeSteps = xmlNewChild(nodeField, 0, C_TAG_STEPS, 0);
xmlNewProp(nodeSteps, C_ATTR_COUNT, BAD_CAST XaoUtils::intToString(nbSteps).c_str());
//for (int j = 0; j < nbSteps; j++)
for (stepIterator itStep = field->begin(); itStep != field->end(); itStep++)
{
Step* step = *itStep;
exportStep(step, field, nodeSteps);
}
}
}
void XaoExporter::exportStep(Step* step, Field* field, xmlNodePtr nodeSteps)
{
xmlNodePtr nodeStep = xmlNewChild(nodeSteps, 0, C_TAG_STEP, 0);
xmlNewProp(nodeStep, C_ATTR_STEP_NUMBER, BAD_CAST XaoUtils::intToString(step->getStep()).c_str());
if (step->getStamp() >= 0)
{
xmlNewProp(nodeStep, C_ATTR_STEP_STAMP, BAD_CAST XaoUtils::intToString(step->getStamp()).c_str());
}
for(int i = 0; i < step->countElements(); ++i)
{
xmlNodePtr nodeElt = xmlNewChild(nodeStep, 0, C_TAG_ELEMENT, 0);
xmlNewProp(nodeElt, C_ATTR_ELEMENT_INDEX, BAD_CAST XaoUtils::intToString(i).c_str());
for (int j = 0; j < step->countComponents(); ++j)
{
std::string content = step->getStringValue(i, j);
xmlNodePtr nodeValue= xmlNewTextChild(nodeElt, 0, C_TAG_VALUE, BAD_CAST content.c_str());
xmlNewProp(nodeValue, C_ATTR_VALUE_COMPONENT, BAD_CAST XaoUtils::intToString(j).c_str());
}
}
}
const bool XaoExporter::readFromFile(const std::string& fileName, Xao* xaoObject)
{
// parse the file and get the DOM
int options = XML_PARSE_HUGE || XML_PARSE_NOCDATA;
xmlDocPtr doc = xmlReadFile(fileName.c_str(), NULL, options);
if (doc == NULL)
{
throw SALOME_Exception("Cannot read XAO file");
}
parseXMLDoc(doc, xaoObject);
return true;
}
const bool XaoExporter::setXML(const std::string& xml, Xao* xaoObject)
{
int options = XML_PARSE_HUGE || XML_PARSE_NOCDATA;
xmlDocPtr doc = xmlReadDoc(BAD_CAST xml.c_str(), "", NULL, options);
if (doc == NULL)
{
throw SALOME_Exception("Cannot read XAO stream");
}
parseXMLDoc(doc, xaoObject);
return true;
}
void XaoExporter::parseXMLDoc(xmlDocPtr doc, Xao* xaoObject)
{
// Get the root element node
xmlNodePtr root = xmlDocGetRootElement(doc);
if (xmlStrcmp(root->name , C_TAG_XAO) != 0)
throw SALOME_Exception("Cannot read XAO file: invalid format XAO node not found");
parseXaoNode(doc, root, xaoObject);
xmlFreeDoc(doc); // free document
xmlCleanupParser(); // free globals
}
void XaoExporter::parseXaoNode(xmlDocPtr doc, xmlNodePtr xaoNode, Xao* xaoObject)
{
xmlChar* version = xmlGetProp(xaoNode, C_ATTR_XAO_VERSION);
if (version != NULL)
{
xaoObject->setVersion((char*)version);
xmlFree(version);
}
xmlChar* author = xmlGetProp(xaoNode, C_ATTR_XAO_AUTHOR);
if (author != NULL)
{
xaoObject->setAuthor((char*)author);
xmlFree(author);
}
for (xmlNodePtr node = xaoNode->children; node; node = node->next)
{
if (xmlStrcmp(node->name, C_TAG_GEOMETRY) == 0)
parseGeometryNode(doc, node, xaoObject);
else if (xmlStrcmp(node->name, C_TAG_GROUPS) == 0)
parseGroupsNode(node, xaoObject);
}
}
void XaoExporter::parseGeometryNode(xmlDocPtr doc, xmlNodePtr geometryNode, Xao* xaoObject)
{
Geometry* geometry = new Geometry();
xmlChar* name = xmlGetProp(geometryNode, C_ATTR_GEOMETRY_NAME);
if (name != NULL)
{
geometry->setName((char*)name);
xmlFree(name);
}
for (xmlNodePtr node = geometryNode->children; node; node = node->next)
{
if (xmlStrcmp(node->name, C_TAG_SHAPE) == 0)
parseShapeNode(doc, node, geometry);
else if (xmlStrcmp(node->name, C_TAG_TOPOLOGY) == 0)
parseTopologyNode(node, geometry);
}
xaoObject->setGeometry(geometry);
}
void XaoExporter::parseShapeNode(xmlDocPtr doc, xmlNodePtr shapeNode, Geometry* geometry)
{
xmlChar* shapeType = xmlGetProp(shapeNode, C_ATTR_SHAPE_FORMAT);
if (xmlStrcmp(shapeType, (xmlChar*)"BREP") == 0)
{
xmlChar* data = xmlNodeGetContent(shapeNode->children);
if (data == NULL)
throw SALOME_Exception("Missing BREP");
geometry->setShape((char*)data);
xmlFree(data);
}
else
{
throw SALOME_Exception("Shape format not supported");
}
}
void XaoExporter::parseTopologyNode(xmlNodePtr topologyNode, Geometry* geometry)
{
for (xmlNodePtr node = topologyNode->children; node; node = node->next)
{
if (xmlStrcmp(node->name, C_TAG_VERTICES) == 0)
parseVerticesNode(node, geometry);
else if (xmlStrcmp(node->name, C_TAG_EDGES) == 0)
parseEdgesNode(node, geometry);
else if (xmlStrcmp(node->name, C_TAG_FACES) == 0)
parseFacesNode(node, geometry);
else if (xmlStrcmp(node->name, C_TAG_SOLIDS) == 0)
parseSolidsNode(node, geometry);
}
}
void XaoExporter::parseVerticesNode(xmlNodePtr verticesNode, Geometry* geometry)
{
xmlChar* count = xmlGetProp(verticesNode, C_ATTR_COUNT);
if (count == NULL)
throw SALOME_Exception("No count attribute for vertices");
geometry->setCountVertices(atoi((char*)count));
xmlFree(count);
for (xmlNodePtr node = verticesNode->children; node; node = node->next)
{
if (xmlStrcmp(node->name, C_TAG_VERTEX) == 0)
{
xmlChar* index = xmlGetProp(node, C_ATTR_ELT_INDEX);
if (index == NULL)
throw SALOME_Exception("Bad index for vertex");
xmlChar* name = xmlGetProp(node, C_ATTR_ELT_NAME);
if (name == NULL)
name = (xmlChar*)"";
xmlChar* reference = xmlGetProp(node, C_ATTR_ELT_REFERENCE);
if (reference == NULL)
throw SALOME_Exception("Bad reference for vertex");
geometry->setVertex(atoi((char*)index), (char*)name, (char*)reference);
}
}
}
void XaoExporter::parseEdgesNode(xmlNodePtr edgesNode, Geometry* geometry)
{
xmlChar* count = xmlGetProp(edgesNode, C_ATTR_COUNT);
if (count == NULL)
throw SALOME_Exception("No count attribute for edges");
geometry->setCountEdges(atoi((char*)count));
xmlFree(count);
for (xmlNodePtr node = edgesNode->children; node; node = node->next)
{
if (xmlStrcmp(node->name, C_TAG_EDGE) == 0)
{
xmlChar* index = xmlGetProp(node, C_ATTR_ELT_INDEX);
if (index == NULL)
throw SALOME_Exception("Bad index for edge");
xmlChar* name = xmlGetProp(node, C_ATTR_ELT_NAME);
if (name == NULL)
name = (xmlChar*)"";
xmlChar* reference = xmlGetProp(node, C_ATTR_ELT_REFERENCE);
if (reference == NULL)
throw SALOME_Exception("Bad reference for edge");
geometry->setEdge(atoi((char*)index), (char*)name, (char*)reference);
}
}
}
void XaoExporter::parseFacesNode(xmlNodePtr facesNode, Geometry* geometry)
{
xmlChar* count = xmlGetProp(facesNode, C_ATTR_COUNT);
if (count == NULL)
throw SALOME_Exception("No count attribute for faces");
geometry->setCountFaces(atoi((char*)count));
xmlFree(count);
for (xmlNodePtr node = facesNode->children; node; node = node->next)
{
if (xmlStrcmp(node->name, C_TAG_FACE) == 0)
{
xmlChar* index = xmlGetProp(node, C_ATTR_ELT_INDEX);
if (index == NULL)
throw SALOME_Exception("Bad index for face");
xmlChar* name = xmlGetProp(node, C_ATTR_ELT_NAME);
if (name == NULL)
name = (xmlChar*)"";
xmlChar* reference = xmlGetProp(node, C_ATTR_ELT_REFERENCE);
if (reference == NULL)
throw SALOME_Exception("Bad reference for face");
geometry->setFace(atoi((char*)index), (char*)name, (char*)reference);
}
}
}
void XaoExporter::parseSolidsNode(xmlNodePtr solidsNode, Geometry* geometry)
{
xmlChar* count = xmlGetProp(solidsNode, C_ATTR_COUNT);
if (count == NULL)
throw SALOME_Exception("No count attribute for solids");
geometry->setCountSolids(atoi((char*)count));
xmlFree(count);
for (xmlNodePtr node = solidsNode->children; node; node = node->next)
{
if (xmlStrcmp(node->name, C_TAG_SOLID) == 0)
{
xmlChar* index = xmlGetProp(node, C_ATTR_ELT_INDEX);
if (index == NULL)
throw SALOME_Exception("Bad index for solid");
xmlChar* name = xmlGetProp(node, C_ATTR_ELT_NAME);
if (name == NULL)
name = (xmlChar*)"";
xmlChar* reference = xmlGetProp(node, C_ATTR_ELT_REFERENCE);
if (reference == NULL)
throw SALOME_Exception("Bad reference for solid");
geometry->setSolid(atoi((char*)index), (char*)name, (char*)reference);
}
}
}
void XaoExporter::parseGroupsNode(xmlNodePtr groupsNode, Xao* xaoObject)
{
for (xmlNodePtr node = groupsNode->children; node; node = node->next)
{
if (xmlStrcmp(node->name, C_TAG_GROUP) == 0)
{
parseGroupNode(node, xaoObject);
}
}
}
void XaoExporter::parseGroupNode(xmlNodePtr groupNode, Xao* xaoObject)
{
xmlChar* dimension = xmlGetProp(groupNode, C_ATTR_GROUP_DIM);
if (dimension == NULL)
throw SALOME_Exception("Bad dimension for group");
XAO::Dimension dim = XaoUtils::stringToDimension((char*)dimension);
Group* group = xaoObject->addGroup(dim);
xmlFree(dimension);
xmlChar* name = xmlGetProp(groupNode, C_ATTR_GROUP_NAME);
if (name == NULL) name = (xmlChar*)"";
group->setName((char*)name);
xmlFree(name);
for (xmlNodePtr node = groupNode->children; node; node = node->next)
{
if (xmlStrcmp(node->name, C_TAG_ELEMENT) == 0)
{
xmlChar* index = xmlGetProp(node, C_ATTR_ELEMENT_INDEX);
if (index == NULL)
throw SALOME_Exception("Bad index for group element");
group->addElement(atoi((char*)index));
xmlFree(index);
}
}
}