/* Copyright (c) 1997-2007 Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany) http://www.math.tu-berlin.de/polymake, mailto:polymake@math.tu-berlin.de This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version: http://www.gnu.org/licenses/gpl.txt. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ #ident "$Project: polymake $$Id: se_interactive.cc 7579 2007-01-22 11:34:46Z gawrilow $" #include #include #include #include #include #include #include namespace polymake { namespace graph { namespace { enum { opt_read_edge_weights=SpringEmbedder::opt_next, opt_seed, opt_max_iter, opt_step }; template bool parse(SimpleGeometryParser& p, std::basic_istream& is, SpringEmbedderWindow& W) { ListMatrix< Vector > points(0,3); char command; while ((command=p.get_command(is)) != 0) { switch (command) { case 'n': { // get the name: n break; } case 'p': { // get a point: p points /= p.get_point().second; break; } case 's': { // get a parameter: s std::string param; double value; p.line >> param >> value; W.set_param(param,value); break; } case 'f': { // get a facet: f ... W.set_facet(p.get_facet()); break; } case 'x': { // end of packet sent if (W.get_param("restart") != 0) { //reinit all! W.reset(); } else if (points.rows() != 0) { W.start_points(rows(points).begin()); } W.adjust_params(); return true; } default: throw std::runtime_error("SimpleGeometryParser: unknown command: " + command); } } return false; } } // end unnamed namespace void se_interactive(Poly& p, const char* graph_section, std::socketstream& javaview, const argv_option *options) { SpringEmbedder SE(options); SimpleGeometryParser parser; std::string line, geom_name; if (!getline(javaview,line)) return; if (line.substr(0,5) == "read ") geom_name=line.substr(5); if (options[SpringEmbedder::opt_skip_node_attr]) { if (options[opt_read_edge_weights]) { p.give(graph_section) >> ignore_node_attrs(SE.G); } else { p.give(graph_section) >> ignore_attrs(SE.G); } } else { if (options[opt_read_edge_weights]) { p.give(graph_section) >> ignore_node_attrs(SE.G); } else { p.give(graph_section) >> ignore_attrs(SE.G); } } SE.adjust_edge_lengths(options[opt_read_edge_weights]); if (options[SpringEmbedder::opt_z_ordering]) SE.set_z_ordering(p, options); unsigned long seed = options[opt_seed] ? std::atol(options[opt_seed]) : random_seed(); int max_iter=options[opt_max_iter] ? std::atoi(options[opt_max_iter]) : 10000; SpringEmbedderWindow se_window(SE,max_iter,seed); if (options[opt_step]) { se_window.set_param("step",std::atof(options[opt_step])); se_window.set_param("continue",1); se_window.compute_points(0); parser.print_short(javaview,geom_name,se_window); } do { int count = 0; if (se_window.get_param("step") != 0) { int iter = (int)se_window.get_param("step"); if (se_window.get_param("max_iter") != 0) { max_iter = (int)se_window.get_param("max_iter"); } while ( !se_window.compute_points(iter) && count <= max_iter ) { count += iter; usleep((int)se_window.get_param("delay")*1000); parser.print_short(javaview, geom_name, se_window); if (!parse(parser,javaview,se_window)) { return; } if (se_window.get_param("continue") == 0) { break; } } se_window.set_param("continue",0); parser.print_short(javaview, geom_name, se_window); } else if (se_window.get_param("restart") != 0) { se_window.set_param("restart",0); se_window.compute_points(0); parser.print_short(javaview, geom_name, se_window); } else { count = max_iter; if (! se_window.compute_points(max_iter)) { cerr << "WARNING: spring_embedder not converged after " << max_iter << " iterations" << endl; } parser.print_short(javaview,geom_name, se_window); } } while (parse(parser,javaview,se_window)); } } } using namespace polymake; /** @file se_interactive * * Driver for interactive graph visualization * * @synopsis se_interactive * [ -z-ordering -read-edge-weights -seed -max-iterations ] * [ {-scale,-balance,-viscosity,-inertion,-eps,-z-factor} ... ] * */ int main(int argc, const char *argv[]) { argv_option options[]={ { "-viscosity", true }, { "-inertion", true }, { "-eps", true }, { "-scale", true }, { "-balance", true }, { "-z-ordering", true }, { "-z-factor", true }, { "-skip-node-attr", false }, { "-read-edge-weights", false }, { "-seed", true }, { "-max-iterations", true }, { "-step", true } }; if (!extract_options(argc,argv,3,options) || argc < 4) { cerr << "usage: " << argv[0] << " [ -z-ordering
-read-edge-weights -skip-node-attr -seed -max-iterations {-eps,-scale,-balance,-viscosity,-inertion,-z-factor,-step} ... ]" << endl; return 1; } try { Poly p(argv[1], ios::in | ios::out); std::socketstream javaview(argv[3]); graph::se_interactive(p, argv[2], javaview, options); } catch (const std::exception& e) { cerr << e.what() << endl; return 1; } return 0; } // Local Variables: // c-basic-offset:3 // End: