void WingedEdgeBuilder::buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials, const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, const unsigned *tindices, const unsigned nvertices) { WShape *currentShape = _current_wshape; // the current shape begin built vector<WVertex *> triangleVertices; vector<Vec3r> triangleNormals; vector<Vec2r> triangleTexCoords; vector<bool> triangleFaceEdgeMarks; // Each triplet of vertices is considered as an independent triangle for (unsigned int i = 0; i < nvertices / 3; i++) { triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i] / 3]); triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 1] / 3]); triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 2] / 3]); triangleNormals.push_back(Vec3r(normals[nindices[3 * i]], normals[nindices[3 * i] + 1], normals[nindices[3 * i] + 2])); triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 1]], normals[nindices[3 * i + 1] + 1], normals[nindices[3 * i + 1] + 2])); triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 2]], normals[nindices[3 * i + 2] + 1], normals[nindices[3 * i + 2] + 2])); if (texCoords) { triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i]], texCoords[tindices[3 * i] + 1])); triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 1]], texCoords[tindices[3 * i + 1] + 1])); triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 2]], texCoords[tindices[3 * i + 2] + 1])); } triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V1V2) != 0); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V2V3) != 0); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0); } if (mindices) currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[0]); else currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0); }
WShape::WShape(WShape& iBrother) { _Id = iBrother.GetId(); _Name = iBrother._Name; _FrsMaterials = iBrother._FrsMaterials; _meanEdgeSize = iBrother._meanEdgeSize; iBrother.bbox(_min, _max); vector<WVertex *>& vertexList = iBrother.getVertexList(); vector<WVertex *>::iterator v = vertexList.begin(), vend = vertexList.end(); for (; v != vend; ++v) { //WVertex *newVertex = new WVertex(*(*v)); WVertex *newVertex = (*v)->duplicate(); newVertex->setShape(this); AddVertex(newVertex); } vector<WEdge *>& edgeList = iBrother.getEdgeList(); vector<WEdge *>::iterator e = edgeList.begin(), eend = edgeList.end(); for (; e != eend; ++e) { //WEdge *newEdge = new WEdge(*(*e)); WEdge *newEdge = (*e)->duplicate(); AddEdge(newEdge); } vector<WFace *>& faceList = iBrother.GetFaceList(); vector<WFace *>::iterator f = faceList.begin(), fend = faceList.end(); for (; f != fend; ++f) { //WFace *newFace = new WFace(*(*f)); WFace *newFace = (*f)->duplicate(); AddFace(newFace); } // update all pointed addresses thanks to the newly created objects: vend = _VertexList.end(); for (v = _VertexList.begin(); v != vend; ++v) { const vector<WEdge *>& vedgeList = (*v)->GetEdges(); vector<WEdge *> newvedgelist; unsigned int i; for (i = 0; i < vedgeList.size(); i++) { WEdge *current = vedgeList[i]; edgedata *currentvedata = (edgedata *)current->userdata; newvedgelist.push_back(currentvedata->_copy); } (*v)->setEdges(newvedgelist); } eend = _EdgeList.end(); for (e = _EdgeList.begin(); e != eend; ++e) { // update aOedge: WOEdge *aoEdge = (*e)->GetaOEdge(); aoEdge->setaVertex(((vertexdata *)(aoEdge->GetaVertex()->userdata))->_copy); aoEdge->setbVertex(((vertexdata *)(aoEdge->GetbVertex()->userdata))->_copy); if (aoEdge->GetaFace()) aoEdge->setaFace(((facedata *)(aoEdge->GetaFace()->userdata))->_copy); aoEdge->setbFace(((facedata *)(aoEdge->GetbFace()->userdata))->_copy); aoEdge->setOwner(((edgedata *)(aoEdge->GetOwner()->userdata))->_copy); // update bOedge: WOEdge *boEdge = (*e)->GetbOEdge(); if (boEdge) { boEdge->setaVertex(((vertexdata *)(boEdge->GetaVertex()->userdata))->_copy); boEdge->setbVertex(((vertexdata *)(boEdge->GetbVertex()->userdata))->_copy); if (boEdge->GetaFace()) boEdge->setaFace(((facedata *)(boEdge->GetaFace()->userdata))->_copy); boEdge->setbFace(((facedata *)(boEdge->GetbFace()->userdata))->_copy); boEdge->setOwner(((edgedata *)(boEdge->GetOwner()->userdata))->_copy); } } fend = _FaceList.end(); for (f = _FaceList.begin(); f != fend; ++f) { unsigned int i; const vector<WOEdge *>& oedgeList = (*f)->getEdgeList(); vector<WOEdge *> newoedgelist; unsigned int n = oedgeList.size(); for (i = 0; i < n; i++) { WOEdge *current = oedgeList[i]; oedgedata *currentoedata = (oedgedata *)current->userdata; newoedgelist.push_back(currentoedata->_copy); //oedgeList[i] = currentoedata->_copy; //oedgeList[i] = ((oedgedata *)(oedgeList[i]->userdata))->_copy; } (*f)->setEdgeList(newoedgelist); } // Free all memory (arghh!) // Vertex vend = iBrother.getVertexList().end(); for (v = iBrother.getVertexList().begin(); v != vend; ++v) { delete (vertexdata *)((*v)->userdata); (*v)->userdata = NULL; } // Edges and OEdges: eend = iBrother.getEdgeList().end(); for (e = iBrother.getEdgeList().begin(); e != eend; ++e) { delete (edgedata *)((*e)->userdata); (*e)->userdata = NULL; // OEdge a: delete (oedgedata *)((*e)->GetaOEdge()->userdata); (*e)->GetaOEdge()->userdata = NULL; // OEdge b: WOEdge *oedgeb = (*e)->GetbOEdge(); if (oedgeb) { delete (oedgedata *)(oedgeb->userdata); oedgeb->userdata = NULL; } } // Faces fend = iBrother.GetFaceList().end(); for (f = iBrother.GetFaceList().begin(); f != fend; ++f) { delete (facedata *)((*f)->userdata); (*f)->userdata = NULL; } }
bool WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) { unsigned int vsize = ifs.vsize(); unsigned int nsize = ifs.nsize(); //soc unused - unsigned tsize = ifs.tsize(); const real *vertices = ifs.vertices(); const real *normals = ifs.normals(); const real *texCoords = ifs.texCoords(); real *new_vertices; real *new_normals; new_vertices = new real[vsize]; new_normals = new real[nsize]; // transform coordinates from local to world system if (_current_matrix) { transformVertices(vertices, vsize, *_current_matrix, new_vertices); transformNormals(normals, nsize, *_current_matrix, new_normals); } else { memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices)); memcpy(new_normals, normals, nsize * sizeof(*new_normals)); } const IndexedFaceSet::TRIANGLES_STYLE *faceStyle = ifs.trianglesStyle(); vector<FrsMaterial> frs_materials; if (ifs.msize()) { const FrsMaterial *const *mats = ifs.frs_materials(); for (unsigned i = 0; i < ifs.msize(); ++i) frs_materials.push_back(*(mats[i])); shape.setFrsMaterials(frs_materials); } #if 0 const FrsMaterial *mat = (ifs.frs_material()); if (mat) shape.setFrsMaterial(*mat); else if (_current_frs_material) shape.setFrsMaterial(*_current_frs_material); #endif const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks(); // sets the current WShape to shape _current_wshape = &shape; // create a WVertex for each vertex buildWVertices(shape, new_vertices, vsize); const unsigned int *vindices = ifs.vindices(); const unsigned int *nindices = ifs.nindices(); const unsigned int *tindices = NULL; if (ifs.tsize()) { tindices = ifs.tindices(); } const unsigned int *mindices = NULL; if (ifs.msize()) mindices = ifs.mindices(); const unsigned int *numVertexPerFace = ifs.numVertexPerFaces(); const unsigned int numfaces = ifs.numFaces(); for (unsigned int index = 0; index < numfaces; index++) { switch (faceStyle[index]) { case IndexedFaceSet::TRIANGLE_STRIP: buildTriangleStrip(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices, nindices, mindices, tindices, numVertexPerFace[index]); break; case IndexedFaceSet::TRIANGLE_FAN: buildTriangleFan(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices, nindices, mindices, tindices, numVertexPerFace[index]); break; case IndexedFaceSet::TRIANGLES: buildTriangles(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices, nindices, mindices, tindices, numVertexPerFace[index]); break; } vindices += numVertexPerFace[index]; nindices += numVertexPerFace[index]; if (mindices) mindices += numVertexPerFace[index]; if (tindices) tindices += numVertexPerFace[index]; faceEdgeMarks++; } delete[] new_vertices; delete[] new_normals; if (shape.GetFaceList().size() == 0) // this may happen due to degenerate triangles return false; // compute bbox shape.ComputeBBox(); // compute mean edge size: shape.ComputeMeanEdgeSize(); // Parse the built winged-edge shape to update post-flags set<Vec3r> normalsSet; vector<WVertex *>& wvertices = shape.getVertexList(); for (vector<WVertex *>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) { if ((*wv)->isBoundary()) continue; if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.) continue; normalsSet.clear(); WVertex::face_iterator fit = (*wv)->faces_begin(); WVertex::face_iterator fitend = (*wv)->faces_end(); for (; fit != fitend; ++fit) { WFace *face = *fit; normalsSet.insert(face->GetVertexNormal(*wv)); if (normalsSet.size() != 1) { break; } } if (normalsSet.size() != 1) { (*wv)->setSmooth(false); } } // Adds the new WShape to the WingedEdge structure _winged_edge->addWShape(&shape); return true; }
void WingedEdgeBuilder::buildTriangleStrip(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials, const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, const unsigned *tindices, const unsigned nvertices) { unsigned nDoneVertices = 2; // number of vertices already treated unsigned nTriangle = 0; // number of the triangle currently being treated //int nVertex = 0; // vertex number WShape *currentShape = _current_wshape; // the current shape being built vector<WVertex *> triangleVertices; vector<Vec3r> triangleNormals; vector<Vec2r> triangleTexCoords; vector<bool> triangleFaceEdgeMarks; while (nDoneVertices < nvertices) { //clear the vertices list: triangleVertices.clear(); //Then rebuild it: if (0 == nTriangle % 2) { // if nTriangle is even triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]); triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]); triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]); triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1], normals[nindices[nTriangle] + 2])); triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1], normals[nindices[nTriangle + 1] + 2])); triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1], normals[nindices[nTriangle + 2] + 2])); if (texCoords) { triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1])); triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]], texCoords[tindices[nTriangle + 1] + 1])); triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]], texCoords[tindices[nTriangle + 2] + 1])); } } else { // if nTriangle is odd triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]); triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]); triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]); triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1], normals[nindices[nTriangle] + 2])); triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1], normals[nindices[nTriangle + 2] + 2])); triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1], normals[nindices[nTriangle + 1] + 2])); if (texCoords) { triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1])); triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]], texCoords[tindices[nTriangle + 2] + 1])); triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]], texCoords[tindices[nTriangle + 1] + 1])); } } triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::FACE_MARK) != 0); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0); triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0); if (mindices) { currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[nTriangle / 3]); } else { currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0); } nDoneVertices++; // with a strip, each triangle is one vertex more nTriangle++; } }