void DualGraph::saveGraph(const char *filename) { std::ofstream output(filename); for (NodeIter nit(this); !nit.end(); ++nit) { GraphNode *node = *nit; output << "v " << node->id() << "\n"; } for (EdgeIter eit(this); !eit.end(); ++eit) { GraphEdge *edge = *eit; output << "e " << edge->from()->id() << " " << edge->to()->id() << "\n"; } output.close(); }
// May be overridden by child classes. std::string GraphNode::calculateOutput() { fmt::MemoryWriter output; for (auto input : mInputs) { if (input->link()) { GraphNodeLink *link = input->link(); // spdlog::get("qde")->debug("Node '{}': Input has link: '{}'", mId, link->id()); if (link->source()) { GraphNode *node = dynamic_cast<GraphNode *>(link->source()->parent()); output << node->calculateOutput(); spdlog::get("qde")->debug("Node '{}': Link has source: '{}'", mId, node->id()); } } } return output.str(); }
DualGraph* generateGraph(std::vector<Patch*>& patches) { DualGraph *dualGraph = new DualGraph; std::map<Vertex*, std::vector<Patch*> > ver2patchMap; for (auto p : patches) { GraphNode *node = dualGraph->addNode(); p->graphNode = node; for (auto v : p->vertices) { auto pvec = ver2patchMap[v]; for (size_t i = 0; i < pvec.size(); ++i) { Patch *p0 = pvec[i]; dualGraph->addEdge(p0->graphNode, node); dualGraph->addEdge(node, p0->graphNode); } ver2patchMap[v].push_back(p); } } //well.. let's print out the dualgraph //convert the dual graph to cm //first, the position, each center of the cluster std::ofstream dgfile("dualgraph.cm"); for (auto p : patches) { GraphNode *gnode = p->graphNode; dgfile << "Vertex " << gnode->id() + 1 << " " << p->center[0] << " " << p->center[1] << " " << p->center[2] << "\n"; } for (auto p : patches) { GraphNode *gnode = p->graphNode; for (GraphNode::EdgeIter eit(gnode); !eit.end(); ++eit) { GraphEdge *edge = *eit; if (edge->to()->id() > gnode->id()) { dgfile << "Edge " << edge->from()->id() + 1 << " " << edge->to()->id() + 1 << "\n"; } } } dualGraph->saveMetis("dualgraph.metis"); dgfile.close(); std::vector <std::string> edgestr; std::set<Vertex*> vertices; double total_boundary_length = 0; int boundary_count = 0; for (auto p : patches) { std::set<Vertex*> pvertices; for (auto he : p->boundary) { if (!he->twin()) { total_boundary_length += (he->source()->point() - he->target()->point()).norm(); ++boundary_count; if ( ver2patchMap[he->source()].size() == 1) { //continue; } vertices.insert(he->source()); auto itpair = pvertices.insert(he->source()); if (itpair.second) { p->corners.push_back(he->source()); } if ( ver2patchMap[he->target()].size() == 1) { // continue; } vertices.insert(he->target()); itpair = pvertices.insert(he->target()); if (itpair.second) { p->corners.push_back(he->target()); } } if ( ver2patchMap[he->source()].size() >= 3) { vertices.insert(he->source()); auto itpair = pvertices.insert(he->source()); if (itpair.second) { p->corners.push_back(he->source()); } } if ( ver2patchMap[he->target()].size() >= 3) { vertices.insert(he->target()); auto itpair = pvertices.insert(he->target()); if (itpair.second) { p->corners.push_back(he->target()); } } } } avg_length = total_boundary_length / boundary_count; std::map<Vertex*, int> prevOrder, nowOrder; std::ofstream output("graph.m"); int vid = 1; for (auto v : vertices) { output << "Vertex " << vid << " " << v->point()[0] << " " << v->point()[1] << " " << v->point()[2] << "\n"; prevOrder[v] = v->index(); nowOrder[v] = vid++; } int fid = 0; for (auto p : patches) { output << "Face " << ++fid << " "; for (auto v : p->corners) { output << nowOrder[v] << " "; } output << "\n"; } for (auto v : vertices) { v->index() = prevOrder[v]; } return dualGraph; }