mardi 30 décembre 2014

Better design pattern for file exporter that requires blocks of information?

I'm writing a VRML file exporter. Your typical VRML file looks something like I've copied below. Below that, you can find how I'm going about generating each vrml block. The thing is, I feel like I'm going about this all wrong but I can't think of any other way to do it.


Nodes having parent dependencies (transforms have shapes, shapes have appearance and geometry nodes, those have...), and I need to be able to set start and end text for each block. Doing this all via constructors and inheritance feels a bit janky, but creating functions and what not creates additional overhead and looks messy. I guess that's okay if I put it all behind a nice API but I figured I'd ask to see if there's a better OOP approach/design pattern I could be using here.



Transform {
translation 0 0 100
children [
Shape {
appearance Appearance {
texture ImageTexture {
repeatS TRUE
repeatT TRUE
url [
"texture.png"
]
} # end texture

} # end appearance

geometry IndexedFaceSet {
normalPerVertex TRUE
solid TRUE
coord Coordinate {
point [
-5.400000 0.030000 -0.000000,
...
] # end point
} # end coord

texCoord TextureCoordinate {
point [
0.062500 0.086207,
...
] # end point
} # end texCoord


normal Normal {
vector [
0 1 0,
]
} # end normals
coordIndex [
0, 1, 2, -1,
...
] # end coordIndex

texCoordIndex [
0, 1, 2, -1,
...
] # end texCoordIndex
normalIndex [
0, 0, 0, -1,
...
] # end normalIndex
} # end geometry
} # end shape
] # end children
} # end Transform


I've started to build the vrml file using classes like this:



////////////////////////////////////////////////
class Node {
protected:
string start;
string end;
int x;

Node() {}
Node(string _start, string _end)
: start(_start), end(_end) { }
};

////////////////////////////////////////////////
class TransformNode : protected Node {
vector<ShapeNode*> shape;

TransformNode() :
Node("TransformNode {\n\ttranslation 0 0 100\n\t\tchildren[\n",
"\t\t] # end children\n} # end TransformNode \n") { }
};

////////////////////////////////////////////////
struct ShapeNode : Node {
AppearanceNode appearance;
GeometryNode* geometryNode;

ShapeNode();
ShapeNode(string texture, string repeatS, string repeatT, string normalPerVertex, string solid, vector<float> coordinates, vector<int> ind) :
Node("ShapeNode { \n\n", "}\n")
{
appearance.imageTexture.url.textureURL = "\t\t\t\t\"" + texture + "\"\n";
appearance.imageTexture.repeatS = "\t\t\trepeatS " + repeatS + "\n";
appearance.imageTexture.repeatT = "\t\t\trepeatT " + repeatT + "\n";

geometryNode = new GeometryNode(normalPerVertex, solid, coordinates, ind);
}
};
////////////////////////////////////////////////

Aucun commentaire:

Enregistrer un commentaire