Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/Tools/VRMLConverter/vrmllib/src/indexed_face_set.cpp @ 6

Last change on this file since 6 was 6, checked in by anonymous, 17 years ago

=…

File size: 3.8 KB
Line 
1#include <vrmllib/nodes.h>
2
3#include <map>
4#include <stdexcept>
5
6namespace vrmllib {
7namespace bits {
8
9struct index_set {
10        index_set() : geom(0), tex(0), norm(0), col(0) {}
11        int geom;
12        int tex;
13        int norm;
14        int col;
15};
16
17bool operator<(const index_set &a, const index_set &b)
18{
19        if (a.geom < b.geom) return true;
20        if (a.geom > b.geom) return false;
21        if (a.tex < b.tex) return true;
22        if (a.tex > b.tex) return false;
23        if (a.norm < b.norm) return true;
24        if (a.norm > b.norm) return false;
25        return a.col < b.col;
26}
27
28} // namespace bits
29
30using namespace bits;
31
32using std::vector;
33using std::map;
34using std::runtime_error;
35
36void IndexedFaceSet::geometry(vector<unsigned> &triangles,
37                vector<vec3> &geometry, vector<vec3> &normals,
38                vector<vec2> &texcoords, vector<col3> &colors) const
39{
40        std::map<index_set, unsigned> index_map;
41        vector<index_set> final_indices;
42
43        Coordinate *coord = dynamic_cast<Coordinate *>(this->coord);
44        if (!coord) throw runtime_error("no coordinates for indexed face set");
45
46        TextureCoordinate *texCoord =
47                dynamic_cast<TextureCoordinate *>(this->texCoord);
48        Normal *normal = dynamic_cast<Normal *>(this->normal);
49        Color *color = dynamic_cast<Color *>(this->color);
50
51        int colcase = 0;
52        if (color) {
53                colcase += colorIndex.empty() ? 2 : 1;
54                colcase += colorPerVertex ? 2 : 0;
55        }
56        int normcase = 0;
57        if (normal) {
58                normcase += normalIndex.empty() ? 2 : 1;
59                normcase += normalPerVertex ? 2 : 0;
60        }
61
62        // map vrml index tuples to vertices and output indices
63        triangles.clear();
64        int facenum = 0, num_in_face = 0;
65        for (unsigned i=0; i!=coordIndex.size(); ++i) {
66                if (coordIndex[i] == -1) {
67                        if (num_in_face != 3)
68                                throw runtime_error(
69                                        "polygon is not a triangle");
70                        num_in_face = 0;
71                        ++facenum;
72                        continue;
73                } else
74                        ++num_in_face;
75
76                index_set is;
77                is.geom = coordIndex[i];
78                if (texCoord) {
79                        if (!texCoordIndex.empty())
80                                is.tex = texCoordIndex[i];
81                        else
82                                is.tex = coordIndex[i];
83                }
84                switch (colcase) {
85                case 1: // !perVertex, !colorIndex.empty
86                        is.col = colorIndex[facenum];
87                        break;
88                case 2: // !perVertex, colorIndex.empty
89                        is.col = facenum;
90                        break;
91                case 3: // perVertex, !colorIndex.empty
92                        is.col = colorIndex[i];
93                        break;
94                case 4: // perVertex, colorIndex.empty
95                        is.col = coordIndex[i];
96                        break;
97                };
98                switch (normcase) {
99                case 1: // !perVertex, !normalIndex.empty
100                        is.norm = normalIndex[facenum];
101                        break;
102                case 2: // !perVertex, normalIndex.empty
103                        is.norm = facenum;
104                        break;
105                case 3: // perVertex, !normalIndex.empty
106                        is.norm = normalIndex[i];
107                        break;
108                case 4: // perVertex, normalIndex.empty
109                        is.norm = coordIndex[i];
110                        break;
111                };
112
113                if (final_indices.empty()) {
114                        index_map[is] = 0;
115                        final_indices.push_back(is);
116                        triangles.push_back(0);
117                } else {
118                        map<index_set, unsigned>::iterator i
119                                = index_map.find(is);
120                        if (i == index_map.end()) {
121                                index_map[is] = final_indices.size();
122                                triangles.push_back(final_indices.size());
123                                final_indices.push_back(is);
124                        } else
125                                triangles.push_back(i->second);
126                }
127        }
128
129        // generate attributes
130        geometry.resize(final_indices.size());
131        for (unsigned i=0; i!=final_indices.size(); ++i)
132                geometry[i] = coord->point[final_indices[i].geom];
133        if (normal) {
134                normals.resize(final_indices.size());
135                for (unsigned i=0; i!=final_indices.size(); ++i)
136                        normals[i] = normal->vector[final_indices[i].norm];
137        } else
138                normals.clear();
139        if (texCoord) {
140                texcoords.resize(final_indices.size());
141                for (unsigned i=0; i!=final_indices.size(); ++i)
142                        texcoords[i] = texCoord->point[final_indices[i].tex];
143        } else
144                texcoords.clear();
145        if (color) {
146                colors.resize(final_indices.size());
147                for (unsigned i=0; i!=final_indices.size(); ++i)
148                        colors[i] = color->color[final_indices[i].col];
149        } else
150                colors.clear();
151
152        // convert to ccw
153        if (!ccw)
154                for (unsigned i=0; i!=triangles.size(); i+=3)
155                        std::swap(triangles[i+1], triangles[i+2]);
156}
157
158} // namespace vrmllib
Note: See TracBrowser for help on using the repository browser.