static void copy_mesh_contents(struct mesh *copy, struct mesh *original) { int i; copy->geometry_mode = original->geometry_mode; copy->ntriangles = original->ntriangles; copy->nvertices = original->nvertices; copy->nlines = original->nlines; copy->graph_ptr = 0; for (i = 0; i < original->nvertices; i++) copy->v[i] = original->v[i]; for (i = 0; i < original->ntriangles; i++) { int v0, v1, v2; v0 = lookup_vertex(original, original->t[i].v[0]); v1 = lookup_vertex(original, original->t[i].v[1]); v2 = lookup_vertex(original, original->t[i].v[2]); copy->t[i].v[0] = ©->v[v0]; copy->t[i].v[1] = ©->v[v1]; copy->t[i].v[2] = ©->v[v2]; copy->t[i].n = original->t[i].n; copy->t[i].vnormal[0] = original->t[i].vnormal[0]; copy->t[i].vnormal[1] = original->t[i].vnormal[1]; copy->t[i].vnormal[2] = original->t[i].vnormal[2]; } for (i = 0; i < original->nlines; i++) { int v0, v1; v0 = lookup_vertex(original, original->l[i].start); v1 = lookup_vertex(original, original->l[i].end); copy->l[i].start = ©->v[v0]; copy->l[i].end = ©->v[v1]; copy->l[i].flag = original->l[i].flag; copy->l[i].additivity = original->l[i].additivity; copy->l[i].opacity = original->l[i].opacity; copy->l[i].tint_color = original->l[i].tint_color; copy->l[i].time_offset = original->l[i].time_offset; } if (original->tex) memcpy(copy->tex, original->tex, sizeof(*copy->tex) * original->ntriangles * 3); copy->radius = original->radius; if (original->material) { copy->material = malloc(sizeof(*copy->material)); *copy->material = *original->material; } mesh_graph_dev_init(copy); }
void read_poly () { int number; is >> number; // poly number is terminated by colon is >> std::ws; int colon; if ((colon = is.get ()) != ':') format_error ("PolyFileReader::read_poly: expected colon, got %c", colon); // first two vertices int initial_vertex; is >> initial_vertex; // translate POLY vertices into Boundary vertices initial_vertex = lookup_vertex (initial_vertex); int prev_vertex; is >> prev_vertex >> std::ws; prev_vertex = lookup_vertex (prev_vertex); int initial_edge = b->insert_edge (Boundary::INVALID_EDGE, initial_vertex, prev_vertex, Boundary::INVALID_EDGE); int prev_edge = initial_edge; while (is_digit (is.peek ())) { int vertex; is >> vertex >> std::ws; // translate POLY vertices into Boundary vertices vertex = lookup_vertex (vertex); int edge = b->insert_edge (prev_edge, prev_vertex, vertex, Boundary::INVALID_EDGE); prev_vertex = vertex; prev_edge = edge; } is >> std::ws; int closed_indic = is.peek (); if (closed_indic == '<') { // extract '<' character is.get (); // close contour b->insert_edge (prev_edge, prev_vertex, initial_vertex, initial_edge); } else { std::cerr << "WARNING: non-closed contour " << number << ". this is probably not what you want.\n"; } ignore_rest_of_line (); }
/* * M A I N ( ) */ int main (int argc, char **argv) { char *label[2]; /* Labels of edge endpoints */ int ch; /* Command-line character */ int i; int numeric = 0; /* Use vertex indices (vs. labels)? */ long index[2]; /* Indices of edge endpoints */ double weight; /* Edge weight */ bu_rb_tree *dictionary; /* Dictionary of vertices */ struct bridge *bp; /* The current bridge */ struct vertex *up; /* An uncivilized neighbor of vup */ struct vertex *vcp; /* The civilized vertex of bp */ struct vertex *vup; /* The uncivilized vertex of bp */ struct vertex *vertex[2]; /* The current edge */ struct neighbor *neighbor[2]; /* Their neighbors */ struct neighbor *np; /* A neighbor of vup */ int (*po[2])(); /* Priority queue order functions */ while ((ch = bu_getopt(argc, argv, OPT_STRING)) != EOF) switch (ch) { case 'n': numeric = 1; break; case '?': default: print_usage(); bu_exit (ch != '?', NULL); return(0); } /* * Initialize the dictionary */ dictionary = bu_rb_create1("Dictionary of vertices", numeric ? compare_vertex_indices : compare_vertex_labels); bu_rb_uniq_on1(dictionary); /* * Read in the graph */ while (get_edge(stdin, index, label, &weight, numeric)) { for (i = 0; i < 2; ++i) /* For each end of the edge... */ { vertex[i] = lookup_vertex(dictionary, index[i], label[i]); neighbor[i] = mk_neighbor(VERTEX_NULL, weight); BU_LIST_INSERT(&(vertex[i] -> v_neighbors), &(neighbor[i] -> l)); } neighbor[0] -> n_vertex = vertex[1]; neighbor[1] -> n_vertex = vertex[0]; } /* * Initialize the priority queue */ po[PRIOQ_INDEX] = compare_bridge_indices; po[PRIOQ_WEIGHT] = compare_bridge_weights; prioq = bu_rb_create("Priority queue of bridges", 2, po); bu_rb_walk1(dictionary, add_to_prioq, INORDER); if (debug) { print_prioq(); bu_rb_walk1(dictionary, print_vertex, INORDER); } /* * Grow a minimum spanning tree, using Prim's algorithm... * * While there exists a min-weight bridge (to a vertex v) in the queue * Dequeue the bridge * If the weight is finite * Output the bridge * Mark v as civilized * For every uncivilized neighbor u of v * if uv is cheaper than u's current bridge * dequeue u's current bridge * enqueue bridge(uv) */ weight = 0.0; while ((bp = extract_min()) != BRIDGE_NULL) { if (debug) { bu_log("extracted min-weight bridge <x%x>, leaving...\n", bp); print_prioq(); } BU_CKMAG(bp, BRIDGE_MAGIC, "bridge"); vcp = bp -> b_vert_civ; vup = bp -> b_vert_unciv; BU_CKMAG(vup, VERTEX_MAGIC, "vertex"); if (is_finite_bridge(bp)) { BU_CKMAG(vcp, VERTEX_MAGIC, "vertex"); if (numeric) (void) printf("%ld %ld %g\n", vcp -> v_index, vup -> v_index, bp -> b_weight); else (void) printf("%s %s %g\n", vcp -> v_label, vup -> v_label, bp -> b_weight); weight += bp -> b_weight; } free_bridge(bp); vup -> v_civilized = 1; if (debug) { bu_log("Looking for uncivilized neighbors of...\n"); print_vertex((void *) vup, 0); } while (BU_LIST_WHILE(np, neighbor, &(vup -> v_neighbors))) { BU_CKMAG(np, NEIGHBOR_MAGIC, "neighbor"); up = np -> n_vertex; BU_CKMAG(up, VERTEX_MAGIC, "vertex"); if (up -> v_civilized == 0) { BU_CKMAG(up -> v_bridge, BRIDGE_MAGIC, "bridge"); if (compare_weights(np -> n_weight, up -> v_bridge -> b_weight) < 0) { del_from_prioq(up); if (debug) { bu_log("After the deletion of bridge <x%x>...\n", up -> v_bridge); print_prioq(); } up -> v_bridge -> b_vert_civ = vup; up -> v_bridge -> b_weight = np -> n_weight; add_to_prioq((void *) up, 0); if (debug) { bu_log("Reduced bridge <x%x> weight to %g\n", up -> v_bridge, up -> v_bridge -> b_weight); print_prioq(); } } else if (debug) bu_log("bridge <x%x>'s weight of %g stands up\n", up -> v_bridge, up -> v_bridge -> b_weight); } else if (debug) bu_log("Skipping civilized neighbor <x%x>\n", up); BU_LIST_DEQUEUE(&(np -> l)); } } bu_log("MST weight: %g\n", weight); return 0; }