Go to the documentation of this file.00001
00005 #include "VrmlWriter.h"
00006
00007
00008 using namespace std;
00009 using namespace boost;
00010 using namespace hrp;
00011
00012
00013
00014 VrmlWriter::TNodeMethodMap VrmlWriter::nodeMethodMap;
00015
00016
00017 std::ostream& operator<<(std::ostream& out, VrmlWriter::TIndent& indent)
00018 {
00019 return out << indent.spaces;
00020 }
00021
00022 inline const char* boolstr(bool v)
00023 {
00024 if(v){
00025 return "TRUE";
00026 } else {
00027 return "FALSE";
00028 }
00029 }
00030
00031 ostream& operator<<(std::ostream& out, SFVec3f& v)
00032 {
00033 return out << v[0] << " " << v[1] << " " << v[2];
00034 }
00035
00036
00037 ostream& operator<<(std::ostream& out, SFVec4f& v)
00038 {
00039 return out << v[0] << " " << v[1] << " " << v[2] << " " << v[3];
00040 }
00041
00042
00043 template <class MFValues> void VrmlWriter::writeMFValues(MFValues values, int numColumn)
00044 {
00045 out << ++indent << "[\n";
00046 ++indent;
00047
00048 out << indent;
00049 int col = 0;
00050 int n = values.size();
00051 for(int i=0; i < n; i++){
00052 out << values[i] << " ";
00053 col++;
00054 if(col == numColumn){
00055 col = 0;
00056 out << "\n";
00057 if(i < n-1){
00058 out << indent;
00059 }
00060 }
00061 }
00062
00063 out << --indent << "]\n";
00064 --indent;
00065 }
00066
00067
00068 void VrmlWriter::writeMFInt32SeparatedByMinusValue(MFInt32& values)
00069 {
00070 out << ++indent << "[\n";
00071 ++indent;
00072
00073 out << indent;
00074 int n = values.size();
00075 for(int i=0; i < n; i++){
00076 out << values[i] << " ";
00077 if(values[i] < 0){
00078 out << "\n";
00079 if(i < n-1){
00080 out << indent;
00081 }
00082 }
00083 }
00084
00085 out << --indent << "]\n";
00086 --indent;
00087 }
00088
00089
00090 VrmlWriter::VrmlWriter(std::ostream& out) : out(out)
00091 {
00092 if(nodeMethodMap.empty()){
00093 registerNodeMethodMap();
00094 }
00095
00096 }
00097
00098
00099 void VrmlWriter::registerNodeMethodMap()
00100 {
00101 registNodeMethod(typeid(VrmlGroup), &VrmlWriter::writeGroupNode);
00102 registNodeMethod(typeid(VrmlTransform), &VrmlWriter::writeTransformNode);
00103 registNodeMethod(typeid(VrmlShape), &VrmlWriter::writeShapeNode);
00104 registNodeMethod(typeid(VrmlIndexedFaceSet), &VrmlWriter::writeIndexedFaceSetNode);
00105 }
00106
00107
00108 VrmlWriterNodeMethod VrmlWriter::getNodeMethod(VrmlNodePtr node)
00109 {
00110 TNodeMethodMap::iterator p = nodeMethodMap.find(typeid(*node).name());
00111 if(p != nodeMethodMap.end()){
00112 return p->second;
00113 } else {
00114 return 0;
00115 }
00116 }
00117
00118 void VrmlWriter::writeHeader()
00119 {
00120 out << "#VRML V2.0 utf8\n";
00121 }
00122
00123
00124 bool VrmlWriter::writeNode(VrmlNodePtr node)
00125 {
00126 indent.clear();
00127 out << "\n";
00128 writeNodeIter(node);
00129 return true;
00130 }
00131
00132
00133 void VrmlWriter::writeNodeIter(VrmlNodePtr node)
00134 {
00135 VrmlWriterNodeMethod method = getNodeMethod(node);
00136 if(method){
00137 (this->*method)(node);
00138 }
00139 }
00140
00141
00142 void VrmlWriter::beginNode(const char* nodename, VrmlNodePtr node)
00143 {
00144 out << indent;
00145 if(node->defName.empty()){
00146 out << nodename << " {\n";
00147 } else {
00148 out << "DEF " << node->defName << " " << nodename << " {\n";
00149 }
00150 ++indent;
00151 }
00152
00153
00154 void VrmlWriter::endNode()
00155 {
00156 out << --indent << "}\n";
00157 }
00158
00159
00160 void VrmlWriter::writeGroupNode(VrmlNodePtr node)
00161 {
00162 VrmlGroupPtr group = static_pointer_cast<VrmlGroup>(node);
00163
00164 beginNode("Group", group);
00165 writeGroupFields(group);
00166 endNode();
00167 }
00168
00169
00170 void VrmlWriter::writeGroupFields(VrmlGroupPtr group)
00171 {
00172 if(group->bboxSize[0] >= 0){
00173 out << indent << "bboxCenter " << group->bboxCenter << "\n";
00174 out << indent << "bboxSize " << group->bboxSize << "\n";
00175 }
00176
00177 if(!group->children.empty()){
00178 out << indent << "children [\n";
00179 ++indent;
00180 for(size_t i=0; i < group->children.size(); i++){
00181 writeNodeIter(group->children[i]);
00182 }
00183 out << --indent << "]\n";
00184 }
00185 }
00186
00187
00188 void VrmlWriter::writeTransformNode(VrmlNodePtr node)
00189 {
00190 VrmlTransformPtr trans = static_pointer_cast<VrmlTransform>(node);
00191
00192 beginNode("Transform", trans);
00193
00194 out << indent << "center " << trans->center << "\n";
00195 out << indent << "rotation " << trans->rotation << "\n";
00196 out << indent << "scale " << trans->scale << "\n";
00197 out << indent << "scaleOrientation " << trans->scaleOrientation << "\n";
00198 out << indent << "translation " << trans->translation << "\n";
00199
00200 writeGroupFields(trans);
00201
00202 endNode();
00203 }
00204
00205
00206 void VrmlWriter::writeShapeNode(VrmlNodePtr node)
00207 {
00208 VrmlShapePtr shape = static_pointer_cast<VrmlShape>(node);
00209
00210 beginNode("Shape", shape);
00211
00212 if(shape->appearance){
00213 out << indent << "appearance\n";
00214 ++indent;
00215 writeAppearanceNode(shape->appearance);
00216 --indent;
00217 }
00218 if(shape->geometry){
00219 out << indent << "geometry\n";
00220 VrmlWriterNodeMethod method = getNodeMethod(shape->geometry);
00221 if(method){
00222 ++indent;
00223 (this->*method)(shape->geometry);
00224 --indent;
00225 }
00226 }
00227
00228 endNode();
00229 }
00230
00231
00232 void VrmlWriter::writeAppearanceNode(VrmlAppearancePtr appearance)
00233 {
00234 beginNode("Appearance", appearance);
00235
00236 if(appearance->material){
00237 out << indent << "material\n";
00238 ++indent;
00239 writeMaterialNode(appearance->material);
00240 --indent;
00241 }
00242
00243 endNode();
00244 }
00245
00246
00247 void VrmlWriter::writeMaterialNode(VrmlMaterialPtr material)
00248 {
00249 beginNode("Material", material);
00250
00251 out << indent << "ambientIntensity " << material->ambientIntensity << "\n";
00252 out << indent << "diffuseColor " << material->diffuseColor << "\n";
00253 out << indent << "emissiveColor " << material->emissiveColor << "\n";
00254 out << indent << "shininess " << material->shininess << "\n";
00255 out << indent << "specularColor " << material->specularColor << "\n";
00256 out << indent << "transparency " << material->transparency << "\n";
00257
00258 endNode();
00259 }
00260
00261
00262 void VrmlWriter::writeIndexedFaceSetNode(VrmlNodePtr node)
00263 {
00264 VrmlIndexedFaceSetPtr faceset = static_pointer_cast<VrmlIndexedFaceSet>(node);
00265
00266 beginNode("IndexedFaceSet", faceset);
00267
00268 if(faceset->coord){
00269 out << indent << "coord\n";
00270 ++indent;
00271 writeCoordinateNode(faceset->coord);
00272 --indent;
00273 }
00274 if(!faceset->coordIndex.empty()){
00275 out << indent << "coordIndex\n";
00276 writeMFInt32SeparatedByMinusValue(faceset->coordIndex);
00277 }
00278
00279 out << indent << "ccw " << boolstr(faceset->ccw) << "\n";
00280 out << indent << "convex " << boolstr(faceset->convex) << "\n";
00281 out << indent << "creaseAngle " << faceset->creaseAngle << "\n";
00282 out << indent << "solid " << boolstr(faceset->solid) << "\n";
00283
00284 endNode();
00285 }
00286
00287
00288 void VrmlWriter::writeCoordinateNode(VrmlCoordinatePtr coord)
00289 {
00290 beginNode("Coordinate", coord);
00291
00292 if(!coord->point.empty()){
00293 out << indent << "point\n";
00294 writeMFValues(coord->point, 1);
00295 }
00296
00297 endNode();
00298 }