int lineClip (osuVertex &v0, osuVertex &v1,double a, double b,double c,double d0, double d1) { osuVertex newv0, newv1; int in0,in1; /* are v0 or v1 in the proper half-space */ int status = 1; in0 = (a * v0.x + b * v0.y + c * v0.z + d0 > 0); in1 = (a * v1.x + b * v1.y + c * v1.z + d1 > 0); if (in0 && in1) { //do nothing, I'll return v0 and v1 } else if (!in0 && in1) { create_vertex(v0, v1, newv0, a, b, c,d0); vertex_copy(v0, newv0); } else if (in0 && !in1) { create_vertex(v0, v1, newv1, a, b, c,d1); vertex_copy(v1, newv1); } else { /* both are not in, so we add no vertices to the clipped line*/ status = 0; } in0 = in1; return(status); }
/*! Creates a new vertex. */ long Patch::create_vertex() { long id; if (m_unusedVertexIds.empty()) { id = m_vertices.size(); } else { id = m_unusedVertexIds.front(); m_unusedVertexIds.pop_front(); } return create_vertex(id); }
void read_vertices (char filename [255]) /* reads the vertices from the specified file to the global variable G_Vertices and */ /* sets G_n and G_d */ /* The file must contain the vertices in the following polyhedra format of Avis and */ /* Fukuda: */ /* comments */ /* begin */ /* number of vertices n dimension + 1 type of coordinates */ /* 1 v1 */ /* ... */ /* 1 vn */ /* end or any other text (is ignored) */ { FILE *f; int i, j; T_Vertex *v; char data_type_string [255]; int data_type; G_Vertices = create_empty_set (); f = open_read (filename); fscanf (f, "%i %i %s ", &G_n, &G_d, data_type_string); G_d --; data_type = determine_data_type (data_type_string); if (data_type == RATIONAL_T) { fprintf (stderr, "\n***** WARNING: The vertex file is of rational type; the "); fprintf (stderr, "vertex coordinates\nwill be transformed to floating point "); fprintf (stderr, "values.\n"); } for (i = 0; i < G_n; i++) { v = create_vertex (); fscanf (f, "%*i "); /* skips the entry one */ v -> no = i; /* this assures v to be added at the end of the list */ if (data_type == REAL_T) for (j = 0; j < G_d; j++) fscanf (f, "%lg ", &(v -> coords [j])); else for (j = 0; j < G_d; j++) fread_rational_value (f, &(v -> coords [j])); add_element (&G_Vertices, v); }; fclose (f); }
/*glut keyboard function*/ void keyboard(unsigned char key, int x, int y) { switch (key) { case 0x1B: case'q': case 'Q': exit(0); break; case 'n': case 'N': create_vertex(); break; case 'h': case 'H': printarr(); break; case 'c': case 'C': quick_hull(); break; case 't': case 'T': quickHull_Top(allPoints[findMin()],allPoints[findMax()]); break; case 'b': case 'B': quickHull_Bottom(allPoints[findMin()],allPoints[findMax()]); break; case 'p': case 'P': quick_hull_peel(); break; case 'k': case 'K': display_hull(); break; case 'r': case 'R': reset(); break; } }//keyboard
// edit_item: When the edit item key is pressed // ----------------------------------------- >> void edit_item() { if (edit_mode == 0) { create_vertex(); return; } if (hilight_item == -1 && !selection()) return; if (edit_mode == 1) open_line_edit(); if (edit_mode == 2) open_sector_edit(); if (edit_mode == 3) open_thing_edit(); }
// keys_edit: Keys for the 2d editor // ------------------------------ >> void keys_edit() { if (!map.opened) return; // Scroll up if (binds.pressed("view_up")) { yoff += ((MAJOR_UNIT / (int)zoom)) + 1; force_map_redraw(true, true); } // Scroll down if (binds.pressed("view_down")) { yoff -= ((MAJOR_UNIT / (int)zoom)) + 1; force_map_redraw(true, true); } // Scroll left if (binds.pressed("view_left")) { xoff += ((MAJOR_UNIT / (int)zoom)) + 1; force_map_redraw(true, true); } // Scroll right if (binds.pressed("view_right")) { xoff -= ((MAJOR_UNIT / (int)zoom)) + 1; force_map_redraw(true, true); } // Zoom in if (binds.pressed("view_zoomin")) view_zoom(true); // Zoom out if (binds.pressed("view_zoomout")) view_zoom(false); // Center view on mouse if (binds.pressed("view_mousecenter")) { xoff = -m_x(mouse.x) / MAJOR_UNIT; yoff = -m_y(mouse.y) / MAJOR_UNIT; force_map_redraw(true, true); } // Set offsets to 0, 0 if (binds.pressed("view_origin")) { xoff = yoff = 0; force_map_redraw(true, true); } // Vertices mode if (binds.pressed("mode_vertices")) change_edit_mode(0); // Linedefs mode if (binds.pressed("mode_linedefs")) change_edit_mode(1); // Sectors mode if (binds.pressed("mode_sectors")) change_edit_mode(2); // Things mode if (binds.pressed("mode_things")) change_edit_mode(3); // Change mode if (binds.pressed("mode_change")) cycle_edit_mode(); // Increase grid size if (binds.pressed("view_increasegrid")) { increase_grid(); force_map_redraw(false, true); } // Decrease grid size if (binds.pressed("view_decreasegrid")) { decrease_grid(); force_map_redraw(false, true); } // Clear selection if (binds.pressed("edit_clearselection")) { clear_selection(); force_map_redraw(true); } // Delete item if (binds.pressed("edit_deleteitem")) { if (edit_mode == 0) delete_vertex(); if (edit_mode == 1) delete_line(); if (edit_mode == 2) delete_sector(); if (edit_mode == 3) delete_thing(); force_map_redraw(true); } // Create item if (binds.pressed("edit_createitem")) { if (edit_mode == 0) { if (!selection()) create_vertex(); else create_lines(false); force_map_redraw(true); return; } if (edit_mode == 1) { if (selection()) create_sector(); force_map_redraw(true); return; } if (edit_mode == 3) { create_thing(); force_map_redraw(true); return; } binds.clear("edit_createitem"); } // Sector height quick changes (8 units) if (binds.pressed("sector_upfloor8")) { if (edit_mode == 2) sector_changeheight(true, 8); } if (binds.pressed("sector_downfloor8")) { if (edit_mode == 2) sector_changeheight(true, -8); } if (binds.pressed("sector_upceil8")) { if (edit_mode == 2) sector_changeheight(false, 8); } if (binds.pressed("sector_downceil8")) { if (edit_mode == 2) sector_changeheight(false, -8); } if (binds.pressed("sector_upboth8")) { if (edit_mode == 2) { sector_changeheight(true, 8); sector_changeheight(false, 8); } } if (binds.pressed("sector_downboth8")) { if (edit_mode == 2) { sector_changeheight(true, -8); sector_changeheight(false, -8); } } // Sector height quick changes (1 unit) if (binds.pressed("sector_upfloor")) { if (edit_mode == 2) sector_changeheight(true, 1); } if (binds.pressed("sector_downfloor")) { if (edit_mode == 2) sector_changeheight(true, -1); } if (binds.pressed("sector_upceil")) { if (edit_mode == 2) sector_changeheight(false, 1); } if (binds.pressed("sector_downceil")) { if (edit_mode == 2) sector_changeheight(false, -1); } if (binds.pressed("sector_upboth")) { if (edit_mode == 2) { sector_changeheight(true, 1); sector_changeheight(false, 1); } } if (binds.pressed("sector_downboth")) { if (edit_mode == 2) { sector_changeheight(true, -1); sector_changeheight(false, -1); } } // Flip line if (binds.pressed("line_flip")) { if (edit_mode == 1) line_flip(true, false); force_map_redraw(true); } // Swap line sides if (binds.pressed("line_swapsides")) { if (edit_mode == 1) line_flip(false, true); force_map_redraw(true); } // Flip both line direction and sides if (binds.pressed("line_flipboth")) { if (edit_mode == 1) line_flip(true, true); force_map_redraw(true); } // Begin line draw if (binds.pressed("line_begindraw")) { if (!line_draw) line_draw = true; binds.clear("line_begindraw"); } // Begin rectangle draw if (binds.pressed("line_begindraw_rect")) { if (!line_draw) { line_draw = true; sel_box.set(mouse.x, mouse.y, mouse.x, mouse.y); } binds.clear("line_begindraw_rect"); } // Undo if (binds.pressed("edit_undo")) { undo(); clear_selection(); hilight_item = -1; force_map_redraw(true, true); //map_changelevel(3); map.change_level(MC_NODE_REBUILD); binds.clear("edit_undo"); } // Edit item if (binds.pressed("edit_edititem")) { edit_item(); binds.clear("edit_edititem"); } // Merge sectors if (binds.pressed("sector_merge")) { sector_merge(false); binds.clear("sector_merge"); } // Join sectors if (binds.pressed("sector_join")) { sector_merge(true); binds.clear("sector_join"); } if (binds.pressed("view_3dmode")) { binds.clear("view_3dmode"); binds.clear("3d_exit"); start_3d_mode(); } if (binds.pressed("open_console")) { binds.clear("open_console"); popup_console(); } if (binds.pressed("copy")) { binds.clear("copy"); clipboard.Copy(); } if (binds.pressed("paste")) { binds.clear("paste"); paste_mode = true; clear_selection(); } if (binds.pressed("cancel_paste")) { binds.clear("cancel_paste"); paste_mode = false; force_map_redraw(true, false); } }
void Vectorizer::process_solution(MeshFunction* xsln, int xitem, MeshFunction* ysln, int yitem, double eps) { // sanity check if (xsln == NULL || ysln == NULL) error("One of the solutions is NULL in Vectorizer:process_solution()."); lock_data(); TimePeriod cpu_time; // initialization this->xsln = xsln; this->ysln = ysln; this->xitem = xitem; this->yitem = yitem; this->eps = eps; nv = nt = ne = nd = 0; del_slot = -1; Mesh* meshes[2] = { xsln->get_mesh(), ysln->get_mesh() }; if (meshes[0] == NULL || meshes[1] == NULL) { error("One of the meshes is NULL in Vectorizer:process_solution()."); } Transformable* fns[2] = { xsln, ysln }; Traverse trav; // estimate the required number of vertices and triangles // (based on the assumption that the linear mesh will be // about four-times finer than the original mesh). int nn = meshes[0]->get_num_elements() + meshes[1]->get_num_elements(); int ev = std::max(32 * nn, 10000); int et = std::max(64 * nn, 20000); int ee = std::max(24 * nn, 7500); int ed = ee; lin_init_array(verts, double4, cv, ev); lin_init_array(tris, int3, ct, et); lin_init_array(edges, int3, ce, ee); lin_init_array(dashes, int2, cd, ed); info = (int4*) malloc(sizeof(int4) * cv); // initialize the hash table int size = 0x1000; while (size*2 < cv) size *= 2; hash_table = (int*) malloc(sizeof(int) * size); memset(hash_table, 0xff, sizeof(int) * size); mask = size-1; // select the linearization quadrature Quad2D *old_quad_x, *old_quad_y; old_quad_x = xsln->get_quad_2d(); old_quad_y = ysln->get_quad_2d(); xsln->set_quad_2d((Quad2D*) &quad_lin); ysln->set_quad_2d((Quad2D*) &quad_lin); if (!xitem) error("Parameter 'xitem' cannot be zero."); if (!yitem) error("Parameter 'yitem' cannot be zero."); get_gv_a_b(xitem, xia, xib); get_gv_a_b(yitem, yia, yib); if (xib >= 6) error("Invalid value of paremeter 'xitem'."); if (yib >= 6) error("Invalid value of paremeter 'yitem'."); max = 1e-10; trav.begin(2, meshes, fns); Element** e; while ((e = trav.get_next_state(NULL, NULL)) != NULL) { xsln->set_quad_order(0, xitem); ysln->set_quad_order(0, yitem); scalar* xval = xsln->get_values(xia, xib); scalar* yval = ysln->get_values(yia, yib); for (unsigned int i = 0; i < e[0]->nvert; i++) { double fx = getvalx(i); double fy = getvaly(i); if (fabs(sqrt(fx*fx + fy*fy)) > max) max = fabs(sqrt(fx*fx + fy*fy)); } } trav.finish(); trav.begin(2, meshes, fns); // process all elements of the mesh while ((e = trav.get_next_state(NULL, NULL)) != NULL) { xsln->set_quad_order(0, xitem); ysln->set_quad_order(0, yitem); scalar* xval = xsln->get_values(xia, xib); scalar* yval = ysln->get_values(yia, yib); double* x = xsln->get_refmap()->get_phys_x(0); double* y = ysln->get_refmap()->get_phys_y(0); int iv[4]; for (unsigned int i = 0; i < e[0]->nvert; i++) { double fx = getvalx(i); double fy = getvaly(i); iv[i] = create_vertex(x[i], y[i], fx, fy); } // we won't bother calculating physical coordinates from the refmap if this is not a curved element curved = (e[0]->cm != NULL); // recur to sub-elements if (e[0]->is_triangle()) process_triangle(iv[0], iv[1], iv[2], 0, NULL, NULL, NULL, NULL, NULL); else process_quad(iv[0], iv[1], iv[2], iv[3], 0, NULL, NULL, NULL, NULL, NULL); // process edges and dashes (bold line for edge in both meshes, dashed line for edge in one of the meshes) Trf* xctm = xsln->get_ctm(); Trf* yctm = ysln->get_ctm(); double r[4] = { -1.0, 1.0, 1.0, -1.0 }; double ref[4][2] = { {-1.0,-1.0}, {1.0,-1.0}, {1.0,1.0}, {-1.0,1.0} }; for (unsigned int i = 0; i < e[0]->nvert; i++) { bool bold = false; double px = ref[i][0]; double py = ref[i][1]; // for odd edges (1, 3) we check x coordinate after ctm transformation, if it's the same (1 or -1) in both meshes => bold if (i & 1) { if ((xctm->m[0]*px + xctm->t[0] == r[i]) && (yctm->m[0]*px + yctm->t[0] == r[i])) bold = true; } // for even edges (0, 4) we check y coordinate after ctm transformation, if it's the same (-1 or 1) in both meshes => bold else { if ((xctm->m[1]*py + xctm->t[1] == r[i]) && (yctm->m[1]*py + yctm->t[1] == r[i])) bold = true; } int j = e[0]->next_vert(i); // we draw a line only if both edges lies on the boundary or if the line is from left top to right bottom if (((e[0]->en[i]->bnd) && (e[1]->en[i]->bnd)) || (verts[iv[i]][1] < verts[iv[j]][1]) || (verts[iv[i]][1] == verts[iv[j]][1] && verts[iv[i]][0] < verts[iv[j]][0])) { if (bold) process_edge(iv[i], iv[j], e[0]->en[i]->marker); else process_dash(iv[i], iv[j]); } } } trav.finish(); find_min_max(); verbose("Vectorizer created %d verts and %d tris in %0.3g s", nv, nt, cpu_time.tick().last()); //if (verbose_mode) print_hash_stats(); unlock_data(); // select old quadratrues xsln->set_quad_2d(old_quad_x); ysln->set_quad_2d(old_quad_y); // clean up ::free(hash_table); ::free(info); }