float ConstantAlgorithmLSHTC::findConstant(InputData* pData, vector<sRates>* pMu, vector<float>* pV) { const int numClasses = pData->getNumClasses(); vector<float> halfWeightsPerClass(numClasses); vector<float> halfEdges(numClasses); findConstantWeightsEdges(pData, halfWeightsPerClass, halfEdges); float halfEdge = 0; for (int l = 0; l < numClasses; ++l) { if (halfEdges[l] > 0) (*pV)[l] = +1; else (*pV)[l] = -1; halfEdge += (*pV)[l] * halfEdges[l]; (*pMu)[l].classIdx = l; (*pMu)[l].rPls = halfWeightsPerClass[l] + (*pV)[l] * halfEdges[l]; (*pMu)[l].rMin = halfWeightsPerClass[l] - (*pV)[l] * halfEdges[l]; (*pMu)[l].rZero = (*pMu)[l].rPls + (*pMu)[l].rMin; // == weightsPerClass[l] } return 2 * halfEdge; } // end of findConstant
void Graph::newEdgeAt(int a, int aPos, int b, int bPos, int abData, int baData) { if (!isEdge(a,b)) { Node &na = node(a), &nb = node(b); na.addNeighbor(b, abData, aPos); if (!halfEdges()) nb.addNeighbor(a, baData, bPos); else ASSERT(baData < 0); } }
void Graph::deleteEdge(int a, int pos) { Node &na = node(a); na.removeIndex(pos); #if 0 { int loc; if (na.hasNeighbor(b, &loc)) { na.removeIndex(loc); if (!halfEdges()) { Node &nb = node(b); if (nb.hasNeighbor(a, &loc)) nb.removeIndex(loc); } } } #endif }
void Graph::deleteNode(int id) { #undef p2 #define p2(a) //pr(a) p2(("Graph::deleteNode %d\n",id)); p2((" graph is \n%s",s() )); Node &n = node(id); p2((" node nTotal=%d\n",n.nTotal() )); // don't remove edges if halfedges is active if (!halfEdges()) { for (int i = n.nTotal() - 1; i >= 0; i--) { Node &m = node(n.edgeDest(i)); p2((" dest node is %s\n",m.s() )); m.removeNeighbor(id); } } nodesRC_.add(id); p2((" after del, graph is \n%s",s() )); }
bool MeshBuilder::buildMesh(const MeshData& data, Mesh& mesh) { std::map<std::pair<int, int>, int> edgeCount; std::map<std::pair<int, int>, HalfEdgeIter> existingHalfEdges; std::map<int, VertexIter> indexToVertex; std::map<HalfEdgeIter, bool> hasFlipEdge; preallocateMeshElements(data, mesh); // insert vertices into mesh and map vertex indices to vertex pointers for (unsigned int i = 0; i < data.positions.size(); i++) { VertexIter vertex = mesh.vertices.insert(mesh.vertices.end(), Vertex()); vertex->position = data.positions[i]; vertex->he = isolated.begin(); indexToVertex[i] = vertex; } // insert uvs into mesh for (unsigned int i = 0; i < data.uvs.size(); i++) { VectorIter uv = mesh.uvs.insert(mesh.uvs.end(), Eigen::Vector3d()); *uv = data.uvs[i]; } // insert normals into mesh for (unsigned int i = 0; i < data.normals.size(); i++) { VectorIter normal = mesh.normals.insert(mesh.normals.end(), Eigen::Vector3d()); *normal = data.normals[i]; } // insert faces into mesh int faceIndex = 0; bool degenerateFaces = false; for (std::vector<std::vector<Index>>::const_iterator f = data.indices.begin(); f != data.indices.end(); f ++) { int n = (int)f->size(); // check if face is degenerate if (n < 3) { std::cerr << "Error: face " << faceIndex << " is degenerate" << std::endl; degenerateFaces = true; continue; } // create face FaceIter newFace = mesh.faces.insert(mesh.faces.end(), Face()); // create a halfedge for each edge of the face std::vector<HalfEdgeIter> halfEdges(n); for (int i = 0; i < n; i++) { halfEdges[i] = mesh.halfEdges.insert(mesh.halfEdges.end(), HalfEdge()); } // initialize the halfedges for (int i = 0; i < n; i++) { // vertex indices int a = (*f)[i].position; int b = (*f)[(i+1)%n].position; // set halfedge attributes halfEdges[i]->next = halfEdges[(i+1)%n]; halfEdges[i]->vertex = indexToVertex[a]; int uv = (*f)[i].uv; if (uv >= 0) halfEdges[i]->uv = data.uvs[uv]; else halfEdges[i]->uv.setZero(); int normal = (*f)[i].normal; if (normal >= 0) halfEdges[i]->normal = data.normals[normal]; else halfEdges[i]->normal.setZero(); halfEdges[i]->onBoundary = false; // keep track of which halfedges have flip edges defined (for deteting boundaries) hasFlipEdge[halfEdges[i]] = false; // point vertex a at the current halfedge indexToVertex[a]->he = halfEdges[i]; // point new face and halfedge to each other halfEdges[i]->face = newFace; newFace->he = halfEdges[i]; // if an edge between a and b has been created in the past, it is the flip edge of the current halfedge if (a > b) std::swap(a, b); if (existingHalfEdges.find(std::pair<int, int>(a, b)) != existingHalfEdges.end()) { halfEdges[i]->flip = existingHalfEdges[std::pair<int, int>(a, b)]; halfEdges[i]->flip->flip = halfEdges[i]; halfEdges[i]->edge = halfEdges[i]->flip->edge; hasFlipEdge[halfEdges[i]] = true; hasFlipEdge[halfEdges[i]->flip] = true; } else { // create an edge and set its halfedge halfEdges[i]->edge = mesh.edges.insert(mesh.edges.end(), Edge()); halfEdges[i]->edge->he = halfEdges[i]; edgeCount[std::pair<int, int>(a, b)] = 0; } // record that halfedge has been created from a to b existingHalfEdges[std::pair<int, int>(a, b)] = halfEdges[i]; // check for nonmanifold edges edgeCount[std::pair<int, int>(a, b)] ++; if (edgeCount[std::pair<int, int>(a, b)] > 2) { std::cerr << "Error: edge " << a << ", " << b << " is non manifold" << std::endl; return false; } } faceIndex++; } if (degenerateFaces) { return false; } // insert extra faces for boundary cycle for (HalfEdgeIter currHe = mesh.halfEdges.begin(); currHe != mesh.halfEdges.end(); currHe++) { // if a halfedge with no flip edge is found, create a new face and link it the corresponding boundary cycle if (!hasFlipEdge[currHe]) { // create face FaceIter newFace = mesh.faces.insert(mesh.faces.end(), Face()); // walk along boundary cycle std::vector<HalfEdgeIter> boundaryCycle; HalfEdgeIter he = currHe; do { // create a new halfedge on the boundary face HalfEdgeIter newHe = mesh.halfEdges.insert(mesh.halfEdges.end(), HalfEdge()); newHe->onBoundary = true; // link the current halfedge in the cycle to its new flip edge he->flip = newHe; // grab the next halfedge along the boundary by finding // the next halfedge around the current vertex that doesn't // have a flip edge defined HalfEdgeIter nextHe = he->next; while (hasFlipEdge[nextHe]) { nextHe = nextHe->flip->next; } // set attritubes for new halfedge newHe->flip = he; newHe->vertex = nextHe->vertex; newHe->edge = he->edge; newHe->face = newFace; newHe->uv = nextHe->uv; // set face's halfedge to boundary halfedge newFace->he = newHe; boundaryCycle.push_back(newHe); // continue walk along cycle he = nextHe; } while (he != currHe); // link the cycle of boundary halfedges together int n = (int)boundaryCycle.size(); for (int i = 0; i < n; i++) { boundaryCycle[i]->next = boundaryCycle[(i+n-1)%n]; hasFlipEdge[boundaryCycle[i]] = true; hasFlipEdge[boundaryCycle[i]->flip] = true; } mesh.boundaries.insert(mesh.boundaries.end(), boundaryCycle[0]); } } indexVertices(mesh); checkIsolatedVertices(mesh); checkNonManifoldVertices(mesh); return true; }