void DFS(int idx) { if(idx == 4) { toCheck(); return; } for(int i = 1; i <= 6; i++) { A[idx] = i; DFS(idx+1); } }
int main(int argc, char *argv[]) { char *filename; if (argc > 1) filename = argv[1]; else filename = strdup("mallas/mask2.off"); try { /////////////////////////////////////////////////////////////////////// //Read a mesh and write a mesh EdgeMesh mesh1; cout << "Loading file " << filename << endl; mesh1.readFileOFF(filename, false); cout << "Num vertex: " << mesh1.numVertex() << "\nNum triangles: " << mesh1.numTriangles() << "\nUnreferenced vertex: " << mesh1.checkUnreferencedVertex() << endl; /////////////////////////////////////////////////////////////////////// //Compute the list of edges //TODO 2.1: //Implement the body of the EdgeMesh::updateEdgeLists() method //Buscamos las aristas frontera mesh1.updateEdgeLists(); cout << mesh1.externalEdges.size() << " boundary edges" << endl; cout << mesh1.internalEdges.size() << " internal edges" << endl; //Write external boundary if (mesh1.externalEdges.size() != 0) { cout << "Edges in the boundary:" << endl; for (auto itt = mesh1.externalEdges.begin(); itt != mesh1.externalEdges.end(); ++itt) cout << "[" << itt->a << "->" << itt->b << "] "; cout << endl; //Vector to store the distance from a vertex to the nearest vertex in the boundary std::vector<float> boundDist(mesh1.numVertex(), INFINITY); //TODO 2.2: //Compute the distance from each vertex to the boundary (measured along edges) //and store it in the boundDist vector //Calculamos las distancias entre los vértices que comparten aristas internas //y los vecinos de cada uno mesh1.updateNeighbours(); //Fijamos la distancia de los vértices de la frontera a 0 for (int i = 0; i < mesh1.externalEdges.size(); i++) boundDist[mesh1.externalEdges[i].a] = 0; vector<bool> toCheck(mesh1.numVertex(), false); //Indica los vértices a chequear bool flag = false; //Indica si se ha encontrado un camino más óptimo para un vértice float dist; //distancia int checking = -1; //índice de l vértice que se está chequeando int count = 0; //Número de vértices a chequear int neigh; //vecino //Rellenamos la lista de vértices a calcular o chequear for (int i = 0; i < mesh1.numVertex(); i++) { if (boundDist[i] == INFINITY) { toCheck[i] = true; count++; } } //Calculamos las distancias while (count > 0) //Mientras queden vértices por chequear { //Buscamos el siguiente vértice a chequear do { checking++; if (checking >= mesh1.numVertex()) checking = 0; } while (!toCheck[checking]); //Calculamos la distancia desde cada vecino si es posible (no está a infinita distancia de la frontera) for (int i = 0; i < mesh1.neighbours[checking].size(); i++) { neigh = mesh1.neighbours[checking][i]; if (mesh1.internalDistances[checking][neigh] != INFINITY && boundDist[neigh] != INFINITY) { dist = mesh1.internalDistances[checking][neigh] + boundDist[neigh]; if (dist < boundDist[checking]) { boundDist[checking] = dist; flag = true; } } } if (boundDist[checking] != INFINITY) { if (flag) //Si se ha encontrado un camino más óptimo { for (int i = 0; i < mesh1.neighbours[checking].size(); i++) { neigh = mesh1.neighbours[checking][i]; if ((mesh1.internalDistances[checking][neigh] != INFINITY) && !toCheck[neigh] && boundDist[neigh]>0) { toCheck[neigh] = true; count++; } } flag = false; } toCheck[checking] = false; count--; } } //END TODO 2.2 //Search the max distance to boundary float maxDistance = *(std::max_element(boundDist.begin(), boundDist.end())); cout << "maxDistance: " << maxDistance << endl; //Dump distances to boundary if (boundDist.size() < 20) { cout << "Distances to boundary: " << endl; //Dump distances to boundary for (size_t i = 0; i < boundDist.size(); i++) { cout << "vertex: " << i << " distance: " << boundDist[i] << endl; } cout << endl; } //TODO 2.3: //Create a colorMesh where the color of each vertex show the distance to boundary //To create colors, use the function setTemperature(1.0-boundDist[i]/maxDistance) //Save to file named "output_boundary.obj" //Visualize it with meshlab ColorMesh colorMesh; cout << "\n\n"; cout << "Loading file " << filename << endl; colorMesh.readFileOFF(filename); for (size_t i = 0; i < colorMesh.numVertex(); i++) { colorMesh.colors[i].setTemperature(1.0 - boundDist[i] / maxDistance); } string objFilename = "output_boundary.obj"; cout << "Saving output to " << objFilename << endl; colorMesh.writeFileOBJ(objFilename); //Visualize the .obj file with an external viewer #ifdef WIN32 string viewcmd = "C:/MeshLab/meshlab_32.exe"; #else string viewcmd = "meshlab"; #endif string cmd = viewcmd + " " + objFilename; cout << "Executing external command: " << cmd << endl; system(cmd.c_str()); //END TODO 2.3 } } catch (const string &str) { std::cerr << "EXCEPTION: " << str << std::endl; } catch (const char *str) { std::cerr << "EXCEPTION: " << str << std::endl; } catch (std::exception& e) { std::cerr << "EXCEPTION: " << e.what() << std::endl; } catch (...) { std::cerr << "EXCEPTION (unknow)" << std::endl; } #ifdef WIN32 cout << "Press Return to end the program" << endl; std::cin.get(); #else #endif return 0; }
/** * @brief Checks the selected predecessor of the exit node of @c cfg. * * @return @c true if the next exit node's predecessor should be checked, @c * false otherwise. If @c false is returned, it means that no variables * from storedGlobalVars can be marked as 'never modified'. * * This function checks that every variable from @c storedGlobalVars is * retrieved its original value before the node exits. */ bool OptimFuncInfoCFGTraversal::checkExitNodesPredecessor(ShPtr<CFG::Node> node) { if (node == cfg->getEntryNode()) { // We have reached the entry node. return false; } auto currStmtRIter = node->stmt_rbegin(); ASSERT_MSG(currStmtRIter != node->stmt_rend(), "encountered an empty node"); ShPtr<Statement> currStmt = *currStmtRIter; // Before every return, there should be a sequence // // globalVar1 = localVar1 // globalVar2 = localVar1 // ... // // where globalVarX is a key in storedGlobalVars and localVarsX is the // corresponding value. // // If some global variable before a return statement is not retrieved // its original value, then this variable cannot be marked as 'never // modified'. // Check whether there is a statement to be skipped. We currently skip // just return statements. // TODO Skip also other statements? if (isa<ReturnStmt>(currStmt) && ++currStmtRIter != node->stmt_rend()) { currStmt = *currStmtRIter; } // Check all variables from storedGlobalVars. VarToVarMap toCheck(storedGlobalVars); while (currStmtRIter != node->stmt_rend() && isa<AssignStmt>(currStmt)) { ShPtr<AssignStmt> assignStmt = cast<AssignStmt>(currStmt); ShPtr<Variable> lhs(cast<Variable>(assignStmt->getLhs())); ShPtr<Expression> rhs(assignStmt->getRhs()); // If the left-hand side is not a variable or there are some // function calls or dereferences, stop the check. ShPtr<ValueData> rhsData(va->getValueData(rhs)); if (!lhs || rhsData->hasCalls() || rhsData->hasDerefs()) { break; } // Check whether the statement is of the form globalVar = localVar, // where globalVar is a variable from toCheck and localVar its // corresponding local variable. auto lhsFoundIter = toCheck.find(lhs); if (lhsFoundIter != toCheck.end() && lhsFoundIter->second == rhs) { toCheck.erase(lhsFoundIter); } // Move to the "next" (i.e. previous) statement (if any). if (++currStmtRIter != node->stmt_rend()) { currStmt = *currStmtRIter; } } // If toCheck contains some variables at this moment, they cannot be // marked as 'never modified'. for (const auto &p : toCheck) { storedGlobalVars.erase(p.first); } // The checking should continue only if there are still some variables that // can possibly be marked as 'never modified'. return !storedGlobalVars.empty(); }