00001
00002
00003
00004 #include "mi.H"
00005 #include "patch.H"
00006 #include "stripcb.H"
00007
00008 char header[] =
00009 "#Inventor V2.1 ascii\n"
00010 "\n"
00011 "Separator {\n"
00012 " ShapeHints {\n"
00013 " vertexOrdering COUNTERCLOCKWISE\n"
00014 " faceType CONVEX\n"
00015 " }\n"
00016 " IndexedTriangleStripSet {\n"
00017 " vertexProperty VertexProperty {\n"
00018 "\n";
00019
00020 Cstr_ptr comma(", ");
00021
00022 void
00023 write_verts(const BMESH &mesh, ostream &os)
00024 {
00025 os <<
00026 " vertex [";
00027 const int num = mesh.nverts();
00028 for (int i = 0; i < num; i++) {
00029 CWpt &loc = mesh.bv(i)->loc();
00030 if (i != 0) {
00031 os << " ";
00032 }
00033 os << loc[0] << " " << loc[1] << " " << loc[2];
00034 if (i != num - 1) os << "," << endl;
00035 }
00036 os << "]" << endl;
00037 }
00038
00039 void
00040 init_strips(const BMESH &mesh)
00041 {
00042
00043
00044
00045 ((BMESH &) mesh).make_patch_if_needed();
00046 for (int p = 0; p < mesh.patches().num(); p++) {
00047 mesh.patches()[p]->build_tri_strips();
00048 }
00049
00050 }
00051
00052 class Formatter {
00053 protected:
00054 ostream *_os;
00055 const int _width;
00056 int _pos;
00057 public:
00058 Formatter(ostream *os, int width) : _os(os), _width(width), _pos(0) {}
00059 void write(Cstr_ptr &str) {
00060 if (_pos + (int)str->len() > _width) {
00061 *_os << endl;
00062 _pos = 0;
00063 }
00064 *_os << str;
00065 _pos += str->len();
00066 }
00067 };
00068
00069 class IVNormalIterator : public StripCB {
00070 protected:
00071 Formatter *_form;
00072 public:
00073 IVNormalIterator(Formatter *form) : _form(form) {}
00074
00075 virtual void faceCB(CBvert *, CBface *f) {
00076 CWvec &norm = f->norm();
00077 _form->write(norm[0]);
00078 _form->write(" ");
00079 _form->write(norm[1]);
00080 _form->write(" ");
00081 _form->write(norm[2]);
00082 _form->write(comma);
00083 }
00084 };
00085
00086 void
00087 write_normals(const BMESH &mesh, ostream &os)
00088 {
00089 Formatter out(&os, 77);
00090 out.write(" normal [");
00091 IVNormalIterator iter(&out);
00092 for (int p = 0; p < mesh.patches().num(); p++) {
00093 Patch *patch = mesh.patches()[p];
00094 patch->draw_tri_strips(&iter);
00095 }
00096 os << "]" << endl;
00097 os << " normalBinding PER_FACE" << endl;
00098 }
00099
00100 class IVTriStripIterator : public StripCB {
00101 protected:
00102 ostream *_os;
00103 Formatter *_form;
00104 int _left;
00105
00106 public:
00107 IVTriStripIterator(Formatter *form) : _form(form),_left(0) {}
00108 virtual void begin_faces(TriStrip *str) {
00109 _form->write(str_ptr(str->verts()[0]->index()) + comma);
00110 _form->write(str_ptr(str->verts()[1]->index()) + comma);
00111 _left--;
00112 }
00113 virtual void faceCB(CBvert *v, CBface *) {
00114 _form->write(str_ptr(v->index()) + comma);
00115 }
00116 virtual void end_faces(TriStrip *) {
00117 _form->write(str_ptr("-1"));
00118 if (_left) _form->write(comma);
00119 }
00120 void set_left(int left) { _left = left;}
00121 };
00122
00123 void
00124 write_strips(const BMESH &mesh, ostream &os)
00125 {
00126 const str_ptr intro(" coordIndex [");
00127 Formatter out(&os, 77);
00128 out.write(intro);
00129
00130 IVTriStripIterator iter(&out);
00131
00132
00133 for (int p = 0; p < mesh.patches().num(); p++) {
00134 Patch *patch = mesh.patches()[p];
00135 iter.set_left(patch->num_tri_strips());
00136 patch->draw_tri_strips(&iter);
00137
00138 if (p < mesh.patches().num() - 1) os << ", ";
00139 }
00140 os << "]" << endl;
00141 }
00142
00143 void
00144 write_mesh(const BMESH &mesh, ostream &os)
00145 {
00146 init_strips(mesh);
00147
00148 os << header;
00149 write_verts(mesh, os);
00150 write_normals(mesh, os);
00151 os << " texCoord [ ]" << endl;
00152 os << " orderedRGBA [ ]" << endl;
00153 os << " }" << endl;
00154 os << endl;
00155 write_strips(mesh, os);
00156 os << " }" << endl;
00157 os << "}" << endl;
00158 }
00159
00160 int
00161 main(int argc, char *argv[])
00162 {
00163 if (argc != 1)
00164 {
00165 err_msg("Usage: %s < mesh.sm > mesh.iv", argv[0]);
00166 return 1;
00167 }
00168
00169 BMESHptr mesh = BMESH::read_jot_stream(cin);
00170 if (!mesh || mesh->empty())
00171 return 1;
00172
00173
00174 write_mesh(*mesh, cout);
00175 return 0;
00176 }
00177
00178