void compositor_background_modified(GF_Node *node) { M_Background *bck = (M_Background *)node; BackgroundStack *st = (BackgroundStack *) gf_node_get_private(node); if (!st) return; if (!gf_sg_vrml_field_equal(&bck->skyColor, &st->sky_col, GF_SG_VRML_MFCOLOR) || !gf_sg_vrml_field_equal(&bck->skyAngle, &st->sky_ang, GF_SG_VRML_MFFLOAT) ) { if (st->sky_mesh) mesh_free(st->sky_mesh); st->sky_mesh = NULL; gf_sg_vrml_field_copy(&st->sky_col, &bck->skyColor, GF_SG_VRML_MFCOLOR); gf_sg_vrml_field_copy(&st->sky_ang, &bck->skyAngle, GF_SG_VRML_MFFLOAT); } if (!gf_sg_vrml_field_equal(&bck->groundColor, &st->ground_col, GF_SG_VRML_MFCOLOR) || !gf_sg_vrml_field_equal(&bck->groundAngle, &st->ground_ang, GF_SG_VRML_MFFLOAT) ) { if (st->ground_mesh) mesh_free(st->ground_mesh); st->ground_mesh = NULL; gf_sg_vrml_field_copy(&st->ground_col, &bck->groundColor, GF_SG_VRML_MFCOLOR); gf_sg_vrml_field_copy(&st->ground_ang, &bck->groundAngle, GF_SG_VRML_MFFLOAT); } back_check_gf_sc_texture_change(&st->txh_front, &bck->frontUrl); back_check_gf_sc_texture_change(&st->txh_back, &bck->backUrl); back_check_gf_sc_texture_change(&st->txh_top, &bck->topUrl); back_check_gf_sc_texture_change(&st->txh_bottom, &bck->bottomUrl); back_check_gf_sc_texture_change(&st->txh_left, &bck->leftUrl); back_check_gf_sc_texture_change(&st->txh_right, &bck->rightUrl); gf_sc_invalidate(st->compositor, NULL); }
static void DestroyBackground(GF_Node *node) { BackgroundStack *ptr = (BackgroundStack *) gf_node_get_private(node); PreDestroyBindable(node, ptr->reg_stacks); gf_list_del(ptr->reg_stacks); if (ptr->sky_mesh) mesh_free(ptr->sky_mesh); if (ptr->ground_mesh) mesh_free(ptr->ground_mesh); gf_sg_vrml_mf_reset(&ptr->ground_ang, GF_SG_VRML_MFFLOAT); gf_sg_vrml_mf_reset(&ptr->sky_ang, GF_SG_VRML_MFFLOAT); gf_sg_vrml_mf_reset(&ptr->ground_col, GF_SG_VRML_MFCOLOR); gf_sg_vrml_mf_reset(&ptr->sky_col, GF_SG_VRML_MFCOLOR); mesh_free(ptr->front_mesh); mesh_free(ptr->back_mesh); mesh_free(ptr->top_mesh); mesh_free(ptr->bottom_mesh); mesh_free(ptr->left_mesh); mesh_free(ptr->right_mesh); gf_sc_texture_destroy(&ptr->txh_front); gf_sc_texture_destroy(&ptr->txh_back); gf_sc_texture_destroy(&ptr->txh_top); gf_sc_texture_destroy(&ptr->txh_bottom); gf_sc_texture_destroy(&ptr->txh_left); gf_sc_texture_destroy(&ptr->txh_right); gf_free(ptr); }
int main( int argc, char *argv[] ) { gdouble max_area = 0.0001; gdouble min_angle = RADIANS(15.0); guint niter = 10; Polygon *p = polygon_create_box( 0.0, 0.0, 1.0, 1.0 ); /* Polygon *p = polygon_create_island(); */ /* Polygon *p = polygon_create_A(); */ /* ELEMENT QUALITY SMOOTHING */ Mesh * mesh = mesh_triangulate_polygon( p ); mesh_make_cdt_by_edge_flipping( mesh ); polygon_free( p ); mesh_refine( mesh, RUPPERT_REFINEMENT, max_area, min_angle ); mesh_relax( mesh ); mesh_smooth( mesh, ELEMENT_QUALITY_SMOOTHING, niter, max_area ); mesh_relax( mesh ); mesh_smooth( mesh, ELEMENT_QUALITY_SMOOTHING, niter, max_area ); mesh_save_to_eps( "mesh.eps", mesh ); mesh_save_to_obj( "mesh.obj", mesh ); mesh_free( mesh ); return EXIT_SUCCESS; }
static void tet_test(void) { mesh* m; point pts[4]; ment v[4]; ment e; unsigned i; double V; double A[4]; double s; m = mesh_new(); pts[0] = point_new(-1, 0, -1.0 / my_sqrt(2)); pts[1] = point_new( 1, 0, -1.0 / my_sqrt(2)); pts[2] = point_new( 0,-1, 1.0 / my_sqrt(2)); pts[3] = point_new( 0, 1, 1.0 / my_sqrt(2)); for (i = 0; i < 4; ++i) v[i] = ment_new(m, VERTEX, 0); for (i = 0; i < 4; ++i) mesh_set_point(m, v[i], pts[i]); e = ment_new(m, TET, v); V = tet_volume(ment_tet(m, e)); debug("volume: %e\n", V); s = 0; for (i = 0; i < 4; ++i) { mesh_down(m, e, TRIANGLE, i, v); A[i] = triangle_area(verts_triangle(m, v)); debug("area: %e\n", A[i]); s += A[i] * A[i]; } s /= 4; s = my_pow(s, 3.0 / 4.0); debug("condition bound: %.10e\n", V / s); debug("quality: %e\n", ment_quality(m, e)); mesh_free(m); }
static void tri_test(void) { mesh* m; point pts[3]; ment v[3]; ment e; unsigned i; double A; double l[3]; double s; m = mesh_new(); pts[0] = point_new(-1,0,0); pts[1] = point_new( 1,0,0); pts[2] = point_new( 0,my_sqrt(3),0); for (i = 0; i < 3; ++i) v[i] = ment_new(m, VERTEX, 0); for (i = 0; i < 3; ++i) mesh_set_point(m, v[i], pts[i]); e = ment_new(m, TRIANGLE, v); A = triangle_area(ment_triangle(m, e)); debug("area: %e\n", A); s = 0; for (i = 0; i < 3; ++i) { mesh_down(m, e, EDGE, i, v); l[i] = line_len(verts_line(m, v)); debug("length: %e\n", l[i]); s += l[i] * l[i]; } s /= 3; debug("condition bound: %e\n", A / s); debug("quality: %e\n", ment_quality(m, e)); mesh_free(m); }
void softif_destroy(struct net_device *soft_iface) { debugfs_del_meshif(soft_iface); sysfs_del_meshif(soft_iface); mesh_free(soft_iface); unregister_netdevice(soft_iface); }
struct mesh *mesh_fabricate_planetary_ring(float ir, float or) { struct mesh *m; int i; m = malloc(sizeof(*m)); if (!m) return m; memset(m, 0, sizeof(*m)); m->nvertices = 360; m->ntriangles = m->nvertices; m->t = malloc(sizeof(*m->t) * m->ntriangles); if (!m->t) goto bail; memset(m->t, 0, sizeof(*m->t) * m->ntriangles); m->v = malloc(sizeof(*m->v) * m->nvertices); if (!m->v) goto bail; memset(m->v, 0, sizeof(*m->v) * m->nvertices); m->l = NULL; m->geometry_mode = MESH_GEOMETRY_TRIANGLES; /* set up vertices */ for (i = 0; i < m->nvertices; i += 2) { const float angle = ((2 * M_PI) * i) / m->nvertices; m->v[i].x = cos(angle) * ir; m->v[i].y = sin(angle) * ir; m->v[i].z = 0.0; m->v[i + 1].x = cos(angle) * or; m->v[i + 1].y = sin(angle) * or; m->v[i + 1].z = 0.0; } /* set up triangles */ for (i = 0; i < m->nvertices; i += 2) { struct vertex *v1, *v2, *v3, *v4; v1 = &m->v[i % m->nvertices]; v2 = &m->v[(i + 1) % m->nvertices]; v3 = &m->v[(i + 2) % m->nvertices]; v4 = &m->v[(i + 3) % m->nvertices]; m->t[i].v[0] = v3; m->t[i].v[1] = v2; m->t[i].v[2] = v1; m->t[i + 1].v[0] = v2; m->t[i + 1].v[1] = v3; m->t[i + 1].v[2] = v4; /* FIXME: set coplanar flags */ } m->radius = mesh_compute_radius(m); mesh_set_flat_shading_vertex_normals(m); mesh_uv_map_planetary_ring(m); return m; bail: mesh_free(m); return NULL; }
int main(int argc, char** argv) { cairo_surface_t *sfc; cairo_t *ctx; int x, y; struct timespec ts = {0, 500000000}; int running; x = y = 0; sfc = cairo_create_x11_surface(&x, &y); ctx = cairo_create(sfc); cairo_set_antialias(ctx, CAIRO_ANTIALIAS_NONE); mesh_t* m = mesh_create(x, y); for (running = 1; running;) { cairo_push_group(ctx); cairo_set_source_rgb(ctx, 0.1, 0.1, 0.1); cairo_paint(ctx); mesh_draw(ctx, m); cairo_pop_group_to_source(ctx); cairo_paint(ctx); cairo_surface_flush(sfc); int event=0; switch (event=cairo_check_event(sfc, 0)) { case 0xff53: // right cursor break; case 0xff51: // left cursor break; case 0xff1b: // Esc case -1: // left mouse button running = 0; break; } nanosleep(&ts, NULL); } mesh_free(m); cairo_destroy(ctx); cairo_close_x11_surface(sfc); return 0; }
int test_node( int argc, char *argv[] ) { Node *n = node_new( 1.1, 2.5 ); g_return_val_if_fail( NODE_POSITION(n)->x == 1.1, 1 ); g_return_val_if_fail( NODE_POSITION(n)->y == 2.5, 1 ); g_return_val_if_fail( node_is_isolated( n ), 1 ); g_return_val_if_fail( node_is_at_boundary( n ) == NULL, 1 ); g_return_val_if_fail( node_degree( n ) == 0, 1 ); node_free( n ); Mesh *mesh = mesh_new(); Node *n1 = mesh_add_node( mesh, 0.0, 0.0 ); Node *n2 = mesh_add_node( mesh, 1.0, 0.0 ); Node *n3 = mesh_add_node( mesh, 1.0, 1.0 ); Node *n4 = mesh_add_node( mesh, 0.0, 1.0 ); Node *n5 = mesh_add_node( mesh, 0.5, 0.5 ); Edge *e1 = mesh_add_edge( mesh, n1, n2 ); Edge *e2 = mesh_add_edge( mesh, n2, n3 ); Edge *e3 = mesh_add_edge( mesh, n3, n4 ); Edge *e4 = mesh_add_edge( mesh, n4, n1 ); Edge *e5 = mesh_add_edge( mesh, n5, n1 ); Edge *e6 = mesh_add_edge( mesh, n5, n2 ); Edge *e7 = mesh_add_edge( mesh, n5, n3 ); Edge *e8 = mesh_add_edge( mesh, n5, n4 ); mesh_add_element( mesh, &e1->he[0], &e6->he[1], &e5->he[0] ); mesh_add_element( mesh, &e2->he[0], &e7->he[1], &e6->he[0] ); mesh_add_element( mesh, &e3->he[0], &e8->he[1], &e7->he[0] ); mesh_add_element( mesh, &e4->he[0], &e5->he[1], &e8->he[0] ); g_return_val_if_fail( ! node_is_isolated( n1 ), 1 ); g_return_val_if_fail( node_is_at_boundary( n1 ) == &e4->he[1], 1 ); g_return_val_if_fail( node_degree( n1 ) == 3, 1 ); g_return_val_if_fail( ! node_is_isolated( n2 ), 1 ); g_return_val_if_fail( node_is_at_boundary( n2 ) == &e1->he[1], 1 ); g_return_val_if_fail( node_degree( n2 ) == 3, 1 ); g_return_val_if_fail( ! node_is_isolated( n3 ), 1 ); g_return_val_if_fail( node_is_at_boundary( n3 ) == &e2->he[1], 1 ); g_return_val_if_fail( node_degree( n3 ) == 3, 1 ); g_return_val_if_fail( ! node_is_isolated( n4 ), 1 ); g_return_val_if_fail( node_is_at_boundary( n4 ) == &e3->he[1], 1 ); g_return_val_if_fail( node_degree( n4 ) == 3, 1 ); g_return_val_if_fail( ! node_is_isolated( n5 ), 1 ); g_return_val_if_fail( node_is_at_boundary( n5 ) == NULL, 1 ); g_return_val_if_fail( node_degree( n5 ) == 4, 1 ); mesh_free( mesh ); return 0; }
static void clean_paths(FSStack *stack) { /*delete all path objects*/ while (gf_list_count(stack->items)) { FSItem *it = gf_list_get(stack->items, 0); gf_list_rem(stack->items, 0); if (it->path) gf_path_del(it->path); #ifndef GPAC_DISABLE_3D if (it->mesh) mesh_free(it->mesh); #endif gf_free(it); } }
static void ball_mesh_free(void) { if (mesh == NULL) return; --mesh_ref_count; if (mesh_ref_count == 0) { mesh_free(mesh); mesh = NULL; } }
static void test_repartition_uniform_mesh_of_size(void** state, int nx, int ny, int nz) { int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); // Create an nx x ny x nz uniform mesh. real_t dx = 1.0/MAX(MAX(1.0/nx, 1.0/ny), 1.0/nz); bbox_t bbox = {.x1 = 0.0, .x2 = nx*dx, .y1 = 0.0, .y2 = ny*dx, .z1 = 0.0, .z2 = nz*dx}; mesh_t* mesh = create_uniform_mesh(MPI_COMM_WORLD, nx, ny, nz, &bbox); mesh_verify_topology(mesh, polymec_error); // Repartition it. exchanger_t* migrator = repartition_mesh(&mesh, NULL, 0.05); exchanger_verify(migrator, polymec_error); exchanger_free(migrator); // Since the mesh is uniform, we can check the properties of each cell. for (int c = 0; c < mesh->num_cells; ++c) { assert_int_equal(6, mesh_cell_num_faces(mesh, c)); real_t V = dx * dx * dx; printf("%d: V[%d] = %g, should be %g\n", rank, c, mesh->cell_volumes[c], V); assert_true(fabs(mesh->cell_volumes[c] - V)/V < 1e-14); } // We can also check the properties of each face. for (int f = 0; f < mesh->num_faces; ++f) { assert_int_equal(4, mesh_face_num_edges(mesh, f)); assert_int_equal(4, mesh_face_num_nodes(mesh, f)); real_t A = dx * dx; assert_true(fabs(mesh->face_areas[f] - A)/A < 1e-14); } // Check the resulting exchanger. exchanger_verify(mesh_exchanger(mesh), polymec_error); // Plot it. double r[mesh->num_cells]; for (int c = 0; c < mesh->num_cells; ++c) r[c] = 1.0*rank; char prefix[FILENAME_MAX]; snprintf(prefix, FILENAME_MAX, "%dx%dx%d_uniform_mesh_repartition", nx, ny, nz); silo_file_t* silo = silo_file_new(mesh->comm, prefix, prefix, 1, 0, 0, 0.0); silo_file_write_mesh(silo, "mesh", mesh); silo_file_write_scalar_cell_field(silo, "rank", "mesh", r, NULL); silo_file_close(silo); // Clean up. mesh_free(mesh); }
void test_mesh() { struct MeshConfig *conf; /* int i; */ conf = mesh_new( 2.4e-3, 5e-3, 0, 3e-3, 0.79e-3, 2.2 ); mesh_free(conf); }
mesh_t mesh_new(uint32_t prime) { mesh_t mesh; // make sure we've initialized if(e3x_init(NULL)) return LOG_ERROR("e3x init failed"); if(!(mesh = malloc(sizeof (struct mesh_struct)))) return NULL; memset(mesh, 0, sizeof(struct mesh_struct)); mesh->index = xht_new(prime?prime:MAXPRIME); if(!mesh->index) return mesh_free(mesh); LOG_INFO("mesh created version %d.%d.%d",TELEHASH_VERSION_MAJOR,TELEHASH_VERSION_MINOR,TELEHASH_VERSION_PATCH); return mesh; }
struct mesh *mesh_unit_icosphere(int subdivisions) { struct mesh *m = mesh_unit_icosohedron(); struct mesh *m2, *m3; if (!m) return NULL; /* note mesh_subdivide_icosphere will free m */ m2 = mesh_subdivide_icosphere(m, subdivisions); /* m2 will be over-allocated, duplicating will clean up the overallocation */ m3 = mesh_duplicate(m2); mesh_free(m2); mesh_set_spherical_vertex_normals(m3); return m3; }
void test_cubed_cylindrical_shell_mesh(void** state, real_t r, real_t R, real_t L) { // Create a cubed cylindrcal shell mesh. mesh_t* mesh = create_cubed_cylindrical_shell_mesh(MPI_COMM_WORLD, 10, 20, r, R, L, "r1", "r2", "bottom", "top"); assert_true(mesh_verify_topology(mesh, polymec_error)); assert_int_equal(8000, mesh->num_cells); char name[FILENAME_MAX]; snprintf(name, FILENAME_MAX, "cubed_cylindrical_shell_r=%g,R=%g,L=%g", r, R, L); silo_file_t* silo = silo_file_new(MPI_COMM_WORLD, name, "", 1, 0, 0, 0.0); silo_file_write_mesh(silo, "mesh", mesh); silo_file_close(silo); // Clean up. mesh_free(mesh); }
static struct mesh *allocate_mesh_for_copy(int ntriangles, int nvertices, int nlines, int with_texture) { struct mesh *copy; copy = malloc(sizeof(*copy)); if (!copy) goto bail; memset(copy, 0, sizeof(*copy)); copy->t = NULL; copy->v = NULL; copy->l = NULL; copy->tex = NULL; copy->material = NULL; if (ntriangles) { copy->t = malloc(sizeof(*copy->t) * ntriangles); if (!copy->t) goto bail; memset(copy->t, 0, sizeof(*copy->t) * ntriangles); } if (nvertices) { copy->v = malloc(sizeof(*copy->v) * nvertices); if (!copy->v) goto bail; memset(copy->v, 0, sizeof(*copy->v) * nvertices); } if (nlines) { copy->l = malloc(sizeof(*copy->l) * nlines); if (!copy->l) goto bail; memset(copy->l, 0, sizeof(*copy->l) * nlines); } if (with_texture) { copy->tex = malloc(sizeof(*copy->tex) * ntriangles * 3); if (!copy->tex) goto bail; memset(copy->tex, 0, sizeof(*copy->tex) * ntriangles * 3); } copy->graph_ptr = 0; return copy; bail: mesh_free(copy); return NULL; }
int test_collapse_edge( int argc, char *argv[] ) { Mesh * mesh = mesh_new(); Node *n1 = mesh_add_node( mesh, 0.0, 2.0 ); Node *n2 = mesh_add_node( mesh, 0.0, 1.0 ); Node *n3 = mesh_add_node( mesh, 0.0, -1.0 ); Node *n4 = mesh_add_node( mesh, -1.0, -2.0 ); Node *n5 = mesh_add_node( mesh, -1.0, 0.0 ); Node *n6 = mesh_add_node( mesh, 1.0, 0.0 ); Node *n7 = mesh_add_node( mesh, 11.0, 10.0 ); Edge *e1 = mesh_add_edge( mesh, n1, n2 ); Edge *e2 = mesh_add_edge( mesh, n2, n6 ); Edge *e3 = mesh_add_edge( mesh, n1, n6 ); Edge *e4 = mesh_add_edge( mesh, n2, n5 ); Edge *e5 = mesh_add_edge( mesh, n1, n5 ); Edge *e6 = mesh_add_edge( mesh, n3, n5 ); Edge *e7 = mesh_add_edge( mesh, n3, n6 ); Edge *e8 = mesh_add_edge( mesh, n3, n4 ); Edge *e9 = mesh_add_edge( mesh, n4, n5 ); Edge *e10 = mesh_add_edge( mesh, n4, n7 ); Edge *e11 = mesh_add_edge( mesh, n2, n3 ); Edge *e12 = mesh_add_edge( mesh, n3, n7 ); Edge *e13 = mesh_add_edge( mesh, n6, n7 ); mesh_add_element( mesh, &e5->he[0], &e4->he[1], &e1->he[1] ); mesh_add_element( mesh, &e1->he[0], &e2->he[0], &e3->he[1] ); mesh_add_element( mesh, &e4->he[0], &e6->he[1], &e11->he[1] ); mesh_add_element( mesh, &e2->he[1], &e11->he[0], &e7->he[0] ); mesh_add_element( mesh, &e6->he[0], &e9->he[1], &e8->he[1] ); mesh_add_element( mesh, &e8->he[0], &e10->he[0], &e12->he[1] ); mesh_add_element( mesh, &e12->he[0], &e13->he[1], &e7->he[1] ); mesh_save_to_eps( "test_collapse_edge_1.eps", mesh ); mesh_collapse_edge( mesh, e11 ); mesh_save_to_eps( "test_collapse_edge_2.eps", mesh ); mesh_free( mesh ); return 0; }
int test_refine( int argc, char *argv[] ) { /* Polygon *p = polygon_create_box( 0.0, 0.0, 1.0, 1.0 ); */ Polygon *p = polygon_create_island(); Mesh *mesh = mesh_triangulate_polygon( p ); mesh_save_to_eps( "test_refine_1.eps", mesh ); polygon_free( p ); mesh_make_cdt_by_edge_flipping( mesh ); mesh_save_to_eps( "test_refine_2.eps", mesh ); mesh_refine( mesh, RUPPERT_REFINEMENT, 0.0007, RADIANS(30) ); mesh_save_to_eps( "test_refine_3.eps", mesh ); mesh_save_to_ply( "test_refine_3.ply", mesh ); mesh_save_to_poly( "test_refine_3.poly", mesh ); mesh_save_to_obj( "test_refine_3.obj", mesh ); mesh_save_to_off( "test_refine_3.off", mesh ); mesh_free( mesh ); return EXIT_SUCCESS; }
static void DestroyBackground2D(GF_Node *node) { Background2DStack *stack = (Background2DStack *) gf_node_get_private(node); PreDestroyBindable(node, stack->reg_stacks); gf_list_del(stack->reg_stacks); while (gf_list_count(stack->status_stack)) { BackgroundStatus *status = (BackgroundStatus *)gf_list_get(stack->status_stack, 0); gf_list_rem(stack->status_stack, 0); gf_free(status); } gf_list_del(stack->status_stack); drawable_del(stack->drawable); gf_sc_texture_destroy(&stack->txh); #ifndef GPAC_DISABLE_3D if (stack->mesh) mesh_free(stack->mesh); #endif gf_free(stack); }
void test_cubed_cylinder_mesh(void** state, real_t R, real_t L, real_t l, bool curved) { // Create a cubed cylinder mesh with a square center block. mesh_t* mesh = create_cubed_cylinder_mesh(MPI_COMM_WORLD, 10, 20, R, L, l, curved, "R", "bottom", "top"); assert_true(mesh_verify_topology(mesh, polymec_error)); // assert_int_equal(5000, mesh->num_cells); assert_true(mesh->comm == MPI_COMM_WORLD); char name[FILENAME_MAX]; if (curved) snprintf(name, FILENAME_MAX, "cubed_circular_cylinder_R=%g,L=%g,l=%g", R, L, l); else snprintf(name, FILENAME_MAX, "cubed_cylinder_R=%g,L=%g,l=%g", R, L, l); silo_file_t* silo = silo_file_new(MPI_COMM_WORLD, name, "", 1, 0, 0, 0.0); silo_file_write_mesh(silo, "mesh", mesh); silo_file_close(silo); // Clean up. mesh_free(mesh); }
static struct mesh *mesh_subdivide_icosphere(struct mesh *m, int subdivisions) { struct mesh *m2; int i, ntris = m->ntriangles; if (subdivisions == 0) return m; /* Allocate space for the new, bigger mesh */ m2 = allocate_mesh_for_copy(m->ntriangles * 4, m->nvertices + m->ntriangles * 3, 0, 0); if (!m2) return NULL; copy_mesh_contents(m2, m); mesh_free(m); for (i = 0; i < ntris; i++) subdivide_triangle(m2, i); normalize_sphere(m2); mesh_set_spherical_vertex_normals(m2); return mesh_subdivide_icosphere(m2, subdivisions - 1); }
int main (int argc, char *argv[]) { if (argc != 10) { fprintf(stderr, "Format: ./mpg num0 num1 ... num8\n"); exit(1); } /* select seed for rand() */ srand(time(NULL)); int num[9]; /* number of positions in each subrectangular */ int i; for (i = 0; i < 9; i++) { num[i] = atoi(argv[i+1]); } Mesh mesh; double xp[4] = {0, 167, 333, 500}; double yp[4] = {0, 167, 333, 500}; mesh_new(&mesh, 4, xp, 4, yp); int id = 0; for (i = 0; i < 9; i++) { rand_pos_n_id_in_rect(id, num[i], &mesh.rect[i], 1000, NULL, 1); id += num[i]; } mesh_free(&mesh); return 0; }
Bool c2d_gl_draw_bitmap(GF_VisualManager *visual, GF_TraverseState *tr_state, DrawableContext *ctx, GF_ColorKey *col_key) { u8 alpha = GF_COL_A(ctx->aspect.fill_color); if (ctx->transform.m[1] || ctx->transform.m[3]) return 0; visual_3d_set_state(visual, V3D_STATE_LIGHT, 0); visual_3d_enable_antialias(visual, 0); if (alpha && (alpha != 0xFF)) { visual_3d_set_material_2d_argb(visual, ctx->aspect.fill_color); gf_sc_texture_set_blend_mode(ctx->aspect.fill_texture, TX_MODULATE); } else if (gf_sc_texture_is_transparent(ctx->aspect.fill_texture)) { gf_sc_texture_set_blend_mode(ctx->aspect.fill_texture, TX_REPLACE); } else { visual_3d_set_state(visual, V3D_STATE_BLEND, 0); } /*ignore texture transform for bitmap*/ tr_state->mesh_num_textures = gf_sc_texture_enable(ctx->aspect.fill_texture, tr_state->appear ? ((M_Appearance *)tr_state->appear)->textureTransform : NULL); if (tr_state->mesh_num_textures) { SFVec2f size, orig; GF_Mesh *mesh; size.x = ctx->bi->unclip.width; size.y = ctx->bi->unclip.height; orig.x = ctx->bi->unclip.x + INT2FIX(visual->compositor->vp_width)/2; orig.y = INT2FIX(visual->compositor->vp_height)/2 - ctx->bi->unclip.y + ctx->bi->unclip.height; mesh = new_mesh(); mesh_new_rectangle(mesh, size, &orig, 1); visual_3d_mesh_paint(tr_state, mesh); mesh_free(mesh); gf_sc_texture_disable(ctx->aspect.fill_texture); tr_state->mesh_num_textures = 0; return 1; } return 0; }
static void span_test(void) { meshDouble_t mesh1, mesh2; spanSet_t spans1, spans2; reg_t reg = { {-1, -6, 11}, {3, 12, 12}, 0 }, domain; reg.pos1[0] *= mc_have_x; // Shrinks reg along degenerated axises. reg.pos1[1] *= mc_have_y; reg.pos1[2] *= mc_have_z; reg.pos2[0] *= mc_have_x; reg.pos2[1] *= mc_have_y; reg.pos2[2] *= mc_have_z; mesh_allocate(mcast_mesh(&mesh1), reg.pos1[0], reg.pos1[1], reg.pos1[2], reg.pos2[0], reg.pos2[1], reg.pos2[2], "testSpan:mesh1", mc_double); mesh_allocate(mcast_mesh(&mesh2), reg.pos1[0] - 1, reg.pos1[1] - 3, reg.pos1[2], reg.pos2[0], reg.pos2[1], reg.pos2[2] + 3, "testSpan:mesh2", mc_double); msg_send("Testing span coverage generator..."); mf_mesh_dumpInfo(&mesh1); mf_mesh_dumpInfo(&mesh2); for(int i = reg.pos1[0]; i <= reg.pos2[0]; ++i) // Randomizes content of the meshes. for(int j = reg.pos1[1]; j <= reg.pos2[1]; ++j) for(int k = reg.pos1[2]; k <= reg.pos2[2]; ++k) { mv_f(&mesh1, i, j, k) = rand(); mv_f(&mesh2, i, j, k) = rand(); } dumpGeom("Testing copy of mesh using region ", ®); domain.pos1[0] = mesh1.imin; domain.pos1[1] = mesh1.jmin; domain.pos1[2] = mesh1.kmin; domain.pos2[0] = mesh1.imax; domain.pos2[1] = mesh1.jmax; domain.pos2[2] = mesh1.kmax; span_init(&domain, ®, &spans1, mf_mesh_sizeofNode(&mesh1)); domain.pos1[0] = mesh2.imin; domain.pos1[1] = mesh2.jmin; domain.pos1[2] = mesh2.kmin; domain.pos2[0] = mesh2.imax; domain.pos2[1] = mesh2.jmax; domain.pos2[2] = mesh2.kmax; span_init(&domain, ®, &spans2, mf_mesh_sizeofNode(&mesh2)); while(!span_allTouched(&spans1)) { long int offset; char buffer[1024]; long int size = span_iterate(&spans1, 1024, &offset); // Gets span and packs it. msg_send("pack: %ld(%ld bytes)", offset, size); memcpy(buffer, ((char *) mesh1.storage) + offset, size); int pos = 0; // Puts unrolled data back to place. do{ int s = span_iterate(&spans2, size - pos, &offset); memcpy(((char *) mesh2.storage) + offset, buffer + pos, s); msg_send("unpack: %ld(%ld bytes) from %d", offset, s, pos); pos += s; } while(size > pos); } for(int i = reg.pos1[0]; i <= reg.pos2[0]; ++i) // Randomizes content of the meshes. for(int j = reg.pos1[1]; j <= reg.pos2[1]; ++j) for(int k = reg.pos1[2]; k <= reg.pos2[2]; ++k) { /* msg_send ("(%02d, %02d, %02d): %ld -> %ld", i, j, k, (long int)(mf_mesh_bytePointer(&mesh1, i, j, k) - (char*)mesh1.origin), (long int)(mf_mesh_bytePointer(&mesh2, i, j, k) - (char*)mesh2.origin));*/ msg_send ("(%02d, %02d, %02d): %+e -> %+e (%+e)", i, j, k, mv_f(&mesh1, i, j, k), mv_f(&mesh2, i, j, k), mv_f(&mesh1, i, j, k) - mv_f(&mesh2, i, j, k)); } mesh_free(mcast_mesh(&mesh1)); mesh_free(mcast_mesh(&mesh2)); }
void test_partition_linear_mesh(void** state) { // Create a 100x1x1 uniform mesh. int nx = 100, ny = 1, nz = 1; real_t dx = 1.0/nx; bbox_t bbox = {.x1 = 0.0, .x2 = 1.0, .y1 = 0.0, .y2 = dx, .z1 = 0.0, .z2 = dx}; mesh_t* mesh = create_uniform_mesh(MPI_COMM_SELF, nx, ny, nz, &bbox); // Partition it. exchanger_t* distributor = partition_mesh(&mesh, MPI_COMM_WORLD, NULL, 0.05); exchanger_verify(distributor, polymec_error); exchanger_free(distributor); // Check the ghost cells. int rank, nprocs; MPI_Comm_rank(mesh->comm, &rank); MPI_Comm_size(mesh->comm, &nprocs); if (nprocs > 1) { exchanger_t* ex = mesh_exchanger(mesh); int pos = 0, proc, *indices, num_indices; int num_sends = 0, num_receives = 0; while (exchanger_next_send(ex, &pos, &proc, &indices, &num_indices)) num_sends += num_indices; pos = 0; while (exchanger_next_receive(ex, &pos, &proc, &indices, &num_indices)) num_receives += num_indices; assert_true((mesh->num_ghost_cells == 1) || (mesh->num_ghost_cells == 2)); assert_true(num_sends == mesh->num_ghost_cells); assert_true(num_receives == mesh->num_ghost_cells); } else assert_int_equal(0, mesh->num_ghost_cells); // Check the geometry of the mesh. int cell_volumes_are_ok = 1; for (int c = 0; c < mesh->num_cells; ++c) { if (fabs(mesh->cell_volumes[c] - dx*dx*dx) > 1e-12) { cell_volumes_are_ok = 0; break; } } int face_areas_are_ok = 1; for (int f = 0; f < mesh->num_faces; ++f) { if (fabs(mesh->face_areas[f] - dx*dx) > 1e-12) { face_areas_are_ok = 0; break; } } MPI_Allreduce(&cell_volumes_are_ok, &cell_volumes_are_ok, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); MPI_Allreduce(&face_areas_are_ok, &cell_volumes_are_ok, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); assert_true(cell_volumes_are_ok); assert_true(face_areas_are_ok); // Check the resulting exchanger. exchanger_verify(mesh_exchanger(mesh), polymec_error); // Plot it. real_t p[mesh->num_cells]; for (int c = 0; c < mesh->num_cells; ++c) p[c] = 1.0*rank; silo_file_t* silo = silo_file_new(mesh->comm, "linear_mesh_partition", "linear_mesh_partition", 1, 0, 0, 0.0); silo_file_write_mesh(silo, "mesh", mesh); silo_field_metadata_t* p_metadata = silo_field_metadata_new(); silo_field_metadata_set_label(p_metadata, "P"); silo_field_metadata_set_conserved(p_metadata, false); silo_file_write_scalar_cell_field(silo, "rank", "mesh", p, p_metadata); silo_file_close(silo); // Clean up. mesh_free(mesh); // Superficially check that the file is okay. int num_files, num_procs; assert_true(silo_file_query("linear_mesh_partition", "linear_mesh_partition", &num_files, &num_procs, NULL)); assert_int_equal(1, num_files); assert_int_equal(nprocs, num_procs); } void test_partition_slab_mesh(void** state) { // Create a 50x50x1 uniform mesh. int nx = 50, ny = 50, nz = 1; real_t dx = 1.0/nx; bbox_t bbox = {.x1 = 0.0, .x2 = 1.0, .y1 = 0.0, .y2 = 1.0, .z1 = 0.0, .z2 = dx}; mesh_t* mesh = create_uniform_mesh(MPI_COMM_SELF, nx, ny, nz, &bbox); // Partition it. exchanger_t* distributor = partition_mesh(&mesh, MPI_COMM_WORLD, NULL, 0.05); exchanger_free(distributor); // Check the geometry of the mesh. int cell_volumes_are_ok = 1; for (int c = 0; c < mesh->num_cells; ++c) { if (fabs(mesh->cell_volumes[c] - dx*dx*dx) > 1e-12) { cell_volumes_are_ok = 0; break; } } int face_areas_are_ok = 1; for (int f = 0; f < mesh->num_faces; ++f) { if (fabs(mesh->face_areas[f] - dx*dx) > 1e-12) { face_areas_are_ok = 0; break; } } MPI_Allreduce(&cell_volumes_are_ok, &cell_volumes_are_ok, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); MPI_Allreduce(&face_areas_are_ok, &cell_volumes_are_ok, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); assert_true(cell_volumes_are_ok); assert_true(face_areas_are_ok); // Plot it. int nprocs, rank; MPI_Comm_size(mesh->comm, &nprocs); MPI_Comm_rank(mesh->comm, &rank); real_t p[mesh->num_cells]; for (int c = 0; c < mesh->num_cells; ++c) p[c] = 1.0*rank; silo_file_t* silo = silo_file_new(mesh->comm, "slab_mesh_partition", "slab_mesh_partition", 1, 0, 0, 0.0); silo_file_write_mesh(silo, "mesh", mesh); silo_file_write_scalar_cell_field(silo, "rank", "mesh", p, NULL); silo_file_close(silo); // Clean up. mesh_free(mesh); // Superficially check that the file is okay. int num_files, num_procs; assert_true(silo_file_query("slab_mesh_partition", "slab_mesh_partition", &num_files, &num_procs, NULL)); assert_int_equal(1, num_files); assert_int_equal(nprocs, num_procs); } void test_partition_box_mesh(void** state) { // Create a 20x20x20 uniform mesh. int nx = 20, ny = 20, nz = 20; bbox_t bbox = {.x1 = 0.0, .x2 = 1.0, .y1 = 0.0, .y2 = 1.0, .z1 = 0.0, .z2 = 1.0}; mesh_t* mesh = create_uniform_mesh(MPI_COMM_SELF, nx, ny, nz, &bbox); // Partition it. exchanger_t* distributor = partition_mesh(&mesh, MPI_COMM_WORLD, NULL, 0.05); exchanger_free(distributor); // Check the geometry of the mesh. real_t dx = 1.0/nx; int cell_volumes_are_ok = 1; for (int c = 0; c < mesh->num_cells; ++c) { if (fabs(mesh->cell_volumes[c] - dx*dx*dx) > 1e-12) { cell_volumes_are_ok = 0; break; } } int face_areas_are_ok = 1; for (int f = 0; f < mesh->num_faces; ++f) { if (fabs(mesh->face_areas[f] - dx*dx) > 1e-12) { face_areas_are_ok = 0; break; } } MPI_Allreduce(&cell_volumes_are_ok, &cell_volumes_are_ok, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); MPI_Allreduce(&face_areas_are_ok, &cell_volumes_are_ok, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); assert_true(cell_volumes_are_ok); assert_true(face_areas_are_ok); // Plot it. int nprocs, rank; MPI_Comm_size(mesh->comm, &nprocs); MPI_Comm_rank(mesh->comm, &rank); double p[mesh->num_cells]; for (int c = 0; c < mesh->num_cells; ++c) p[c] = 1.0*rank; silo_file_t* silo = silo_file_new(mesh->comm, "box_mesh_partition", "box_mesh_partition", 1, 0, 0, 0.0); silo_file_write_mesh(silo, "mesh", mesh); silo_file_write_scalar_cell_field(silo, "rank", "mesh", p, NULL); silo_file_close(silo); // Clean up. mesh_free(mesh); // Superficially check that the file is okay. int num_files, num_procs; assert_true(silo_file_query("box_mesh_partition", "box_mesh_partition", &num_files, &num_procs, NULL)); assert_int_equal(1, num_files); assert_int_equal(nprocs, num_procs); } int main(int argc, char* argv[]) { polymec_init(argc, argv); const struct CMUnitTest tests[] = { cmocka_unit_test(test_partition_linear_mesh), cmocka_unit_test(test_partition_slab_mesh), cmocka_unit_test(test_partition_box_mesh) }; return cmocka_run_group_tests(tests, NULL, NULL); }
/* See: http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html */ struct mesh *mesh_unit_icosohedron(void) { const double tau = (1.0 + sqrt(5.0)) / 2.0; const double scale = 1.0 / sqrt(1.0 + tau * tau); struct mesh *m; m = malloc(sizeof(*m)); if (!m) return m; memset(m, 0, sizeof(*m)); m->nvertices = 12; m->ntriangles = 20; m->t = malloc(sizeof(*m->t) * m->ntriangles); if (!m->t) goto bail; memset(m->t, 0, sizeof(*m->t) * m->ntriangles); m->v = malloc(sizeof(*m->v) * m->nvertices); if (!m->v) goto bail; memset(m->v, 0, sizeof(*m->v) * m->nvertices); m->tex = 0; /* m->tex = malloc(sizeof(*m->tex) * m->ntriangles * 3); if (!m->tex) goto bail; memset(m->tex, 0, sizeof(*m->tex) * m->ntriangles * 3); */ m->l = NULL; m->geometry_mode = MESH_GEOMETRY_TRIANGLES; m->v[0].x = scale * -1.0; m->v[0].y = scale * tau; m->v[0].z = scale * 0.0; m->v[1].x = scale * 1.0; m->v[1].y = scale * tau; m->v[1].z = scale * 0.0; m->v[2].x = scale * -1.0; m->v[2].y = scale * -tau; m->v[2].z = scale * 0.0; m->v[3].x = scale * 1.0; m->v[3].y = scale * -tau; m->v[3].z = scale * 0.0; m->v[4].x = scale * 0.0; m->v[4].y = scale * -1.0; m->v[4].z = scale * tau; m->v[5].x = scale * 0.0; m->v[5].y = scale * 1.0; m->v[5].z = scale * tau; m->v[6].x = scale * 0.0; m->v[6].y = scale * -1.0; m->v[6].z = scale * -tau; m->v[7].x = scale * 0.0; m->v[7].y = scale * 1.0; m->v[7].z = scale * -tau; m->v[8].x = scale * tau; m->v[8].y = scale * 0.0; m->v[8].z = scale * -1.0; m->v[9].x = scale * tau; m->v[9].y = scale * 0.0; m->v[9].z = scale * 1.0; m->v[10].x = scale * -tau; m->v[10].y = scale * 0.0; m->v[10].z = scale * -1.0; m->v[11].x = scale * -tau; m->v[11].y = scale * 0.0; m->v[11].z = scale * 1.0; m->t[0].v[0] = &m->v[0]; m->t[0].v[1] = &m->v[11]; m->t[0].v[2] = &m->v[5]; m->t[1].v[0] = &m->v[0]; m->t[1].v[1] = &m->v[5]; m->t[1].v[2] = &m->v[1]; m->t[2].v[0] = &m->v[0]; m->t[2].v[1] = &m->v[1]; m->t[2].v[2] = &m->v[7]; m->t[3].v[0] = &m->v[0]; m->t[3].v[1] = &m->v[7]; m->t[3].v[2] = &m->v[10]; m->t[4].v[0] = &m->v[0]; m->t[4].v[1] = &m->v[10]; m->t[4].v[2] = &m->v[11]; m->t[5].v[0] = &m->v[1]; m->t[5].v[1] = &m->v[5]; m->t[5].v[2] = &m->v[9]; m->t[6].v[0] = &m->v[5]; m->t[6].v[1] = &m->v[11]; m->t[6].v[2] = &m->v[4]; m->t[7].v[0] = &m->v[11]; m->t[7].v[1] = &m->v[10]; m->t[7].v[2] = &m->v[2]; m->t[8].v[0] = &m->v[10]; m->t[8].v[1] = &m->v[7]; m->t[8].v[2] = &m->v[6]; m->t[9].v[0] = &m->v[7]; m->t[9].v[1] = &m->v[1]; m->t[9].v[2] = &m->v[8]; m->t[10].v[0] = &m->v[3]; m->t[10].v[1] = &m->v[9]; m->t[10].v[2] = &m->v[4]; m->t[11].v[0] = &m->v[3]; m->t[11].v[1] = &m->v[4]; m->t[11].v[2] = &m->v[2]; m->t[12].v[0] = &m->v[3]; m->t[12].v[1] = &m->v[2]; m->t[12].v[2] = &m->v[6]; m->t[13].v[0] = &m->v[3]; m->t[13].v[1] = &m->v[6]; m->t[13].v[2] = &m->v[8]; m->t[14].v[0] = &m->v[3]; m->t[14].v[1] = &m->v[8]; m->t[14].v[2] = &m->v[9]; m->t[15].v[0] = &m->v[4]; m->t[15].v[1] = &m->v[9]; m->t[15].v[2] = &m->v[5]; m->t[16].v[0] = &m->v[2]; m->t[16].v[1] = &m->v[4]; m->t[16].v[2] = &m->v[11]; m->t[17].v[0] = &m->v[6]; m->t[17].v[1] = &m->v[2]; m->t[17].v[2] = &m->v[10]; m->t[18].v[0] = &m->v[8]; m->t[18].v[1] = &m->v[6]; m->t[18].v[2] = &m->v[7]; m->t[19].v[0] = &m->v[9]; m->t[19].v[1] = &m->v[8]; m->t[19].v[2] = &m->v[1]; m->radius = mesh_compute_radius(m); mesh_set_flat_shading_vertex_normals(m); mesh_graph_dev_init(m); return m; bail: mesh_free(m); return NULL; }
struct mesh *mesh_fabricate_billboard(float cx, float cy, float width, float height) { struct mesh *m; m = malloc(sizeof(*m)); if (!m) return m; memset(m, 0, sizeof(*m)); m->nvertices = 4; m->ntriangles = 2; m->t = malloc(sizeof(*m->t) * m->ntriangles); if (!m->t) goto bail; memset(m->t, 0, sizeof(*m->t) * m->ntriangles); m->v = malloc(sizeof(*m->v) * m->nvertices); if (!m->v) goto bail; memset(m->v, 0, sizeof(*m->v) * m->nvertices); m->tex = malloc(sizeof(*m->tex) * m->ntriangles * 3); if (!m->tex) goto bail; memset(m->tex, 0, sizeof(*m->tex) * m->ntriangles * 3); m->l = NULL; m->geometry_mode = MESH_GEOMETRY_TRIANGLES; m->v[0].x = -width / 2.0f + cx; m->v[0].y = height / 2.0f + cy; m->v[0].z = 0; m->v[1].x = width / 2.0f + cx; m->v[1].y = height / 2.0f + cy; m->v[1].z = 0; m->v[2].x = width / 2.0f + cx; m->v[2].y = -height / 2.0f + cy; m->v[2].z = 0; m->v[3].x = -width / 2.0f + cx; m->v[3].y = -height / 2.0f + cy; m->v[3].z = 0; m->t[0].v[0] = &m->v[0]; m->t[0].v[1] = &m->v[2]; m->t[0].v[2] = &m->v[1]; m->t[0].flag = TRIANGLE_0_1_COPLANAR; mesh_set_triangle_texture_coords(m, 0, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f); m->t[1].v[0] = &m->v[0]; m->t[1].v[1] = &m->v[3]; m->t[1].v[2] = &m->v[2]; m->t[1].flag = TRIANGLE_0_2_COPLANAR; mesh_set_triangle_texture_coords(m, 1, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f); m->radius = mesh_compute_radius(m); mesh_set_flat_shading_vertex_normals(m); mesh_graph_dev_init(m); return m; bail: mesh_free(m); return NULL; }
/* mesh_fabricate_crossbeam fabricates a mesh like so, out of 8 triangles: * 0 * |\ * | \ * | \ * 4______| \__5 * \ \ \ \ * \ \ |3 \ * \ \ | \ * \ 1 \ | \ * \_____\|_____\6 * 7 \ | * \ | * \ | * \| * 2 * centered on origin, length axis parallel to x axis. * length is the distance betwee 0 and 3, above, and * radius is the distance between the center of the cross * beam and 2,6,7,3 and 0,4,5,1. * * 8 triangles are needed because we need to prevent backface * culling, so we wind one set of tris one way, and the other, * the other. */ struct mesh *mesh_fabricate_crossbeam(float length, float radius) { struct mesh *m; m = malloc(sizeof(*m)); if (!m) return m; memset(m, 0, sizeof(*m)); m->nvertices = 8; m->ntriangles = 8; m->t = malloc(sizeof(*m->t) * m->ntriangles); if (!m->t) goto bail; memset(m->t, 0, sizeof(*m->t) * m->ntriangles); m->v = malloc(sizeof(*m->v) * m->nvertices); if (!m->v) goto bail; memset(m->v, 0, sizeof(*m->v) * m->nvertices); m->tex = malloc(sizeof(*m->tex) * m->ntriangles * 3); if (!m->tex) goto bail; memset(m->tex, 0, sizeof(*m->tex) * m->ntriangles * 3); m->l = NULL; m->geometry_mode = MESH_GEOMETRY_TRIANGLES; m->v[0].x = -length / 2.0f; m->v[0].y = radius; m->v[0].z = 0.0f; m->v[1].x = -length / 2.0f; m->v[1].y = -radius; m->v[1].z = 0.0f; m->v[2].x = length / 2.0f; m->v[2].y = -radius; m->v[2].z = 0.0f; m->v[3].x = length / 2.0f; m->v[3].y = radius; m->v[3].z = 0.0f; m->v[4].x = -length / 2.0f; m->v[4].y = 0.0f; m->v[4].z = radius; m->v[5].x = -length / 2.0f; m->v[5].y = 0.0f; m->v[5].z = -radius; m->v[6].x = length / 2.0f; m->v[6].y = 0.0f; m->v[6].z = -radius; m->v[7].x = length / 2.0f; m->v[7].y = 0.0f; m->v[7].z = radius; m->t[0].v[0] = &m->v[0]; m->t[0].v[1] = &m->v[1]; m->t[0].v[2] = &m->v[2]; mesh_set_triangle_texture_coords(m, 0, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); m->t[1].v[0] = &m->v[2]; m->t[1].v[1] = &m->v[3]; m->t[1].v[2] = &m->v[0]; mesh_set_triangle_texture_coords(m, 1, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f); m->t[2].v[0] = &m->v[4]; m->t[2].v[1] = &m->v[5]; m->t[2].v[2] = &m->v[6]; mesh_set_triangle_texture_coords(m, 2, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f); m->t[3].v[0] = &m->v[6]; m->t[3].v[1] = &m->v[7]; m->t[3].v[2] = &m->v[4]; mesh_set_triangle_texture_coords(m, 3, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f); m->t[4].v[0] = &m->v[2]; m->t[4].v[1] = &m->v[1]; m->t[4].v[2] = &m->v[0]; mesh_set_triangle_texture_coords(m, 4, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f); m->t[5].v[0] = &m->v[0]; m->t[5].v[1] = &m->v[3]; m->t[5].v[2] = &m->v[2]; mesh_set_triangle_texture_coords(m, 5, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f); m->t[6].v[0] = &m->v[6]; m->t[6].v[1] = &m->v[5]; m->t[6].v[2] = &m->v[4]; mesh_set_triangle_texture_coords(m, 6, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); m->t[7].v[0] = &m->v[4]; m->t[7].v[1] = &m->v[7]; m->t[7].v[2] = &m->v[6]; mesh_set_triangle_texture_coords(m, 7, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f); mesh_compute_radius(m); mesh_set_flat_shading_vertex_normals(m); mesh_graph_dev_init(m); return m; bail: mesh_free(m); return NULL; }
struct mesh *init_thrust_mesh(int streaks, double h, double r1, double r2) { struct mesh *my_mesh = malloc(sizeof(*my_mesh)); if (!my_mesh) return my_mesh; memset(my_mesh, 0, sizeof(*my_mesh)); my_mesh->geometry_mode = MESH_GEOMETRY_PARTICLE_ANIMATION; my_mesh->nlines = streaks * 50; my_mesh->nvertices = my_mesh->nlines * 2; my_mesh->ntriangles = 0; my_mesh->t = 0; my_mesh->v = malloc(sizeof(*my_mesh->v) * my_mesh->nvertices); my_mesh->l = malloc(sizeof(*my_mesh->l) * my_mesh->nlines); my_mesh->tex = 0; my_mesh->radius = h; my_mesh->graph_ptr = 0; int maxparticle = streaks; struct particle particles[maxparticle]; int i; for (i = 0; i < maxparticle; i++) create_particle(h, r1, particles, i); int line_index = 0; while (1) { int one_is_active = 0; for (i = 0; i < maxparticle; i++) { if (!particles[i].active) continue; float x1 = particles[i].xpos; float y1 = particles[i].ypos; float z1 = particles[i].zpos; evolve_particle(h, particles, i); if (particles[i].lifetime < 0) { particles[i].active = 0; continue; } one_is_active = 1; float x2 = particles[i].xpos; float y2 = particles[i].ypos; float z2 = particles[i].zpos; int v_index = line_index * 2; my_mesh->v[v_index + 0].x = x1; my_mesh->v[v_index + 0].y = y1; my_mesh->v[v_index + 0].z = z1; my_mesh->v[v_index + 1].x = x2; my_mesh->v[v_index + 1].y = y2; my_mesh->v[v_index + 1].z = z2; my_mesh->l[line_index].start = &my_mesh->v[v_index + 0]; my_mesh->l[line_index].end = &my_mesh->v[v_index + 1]; my_mesh->l[line_index].flag = 0; my_mesh->l[line_index].additivity = 1.0; my_mesh->l[line_index].opacity = particles[i].lifetime; my_mesh->l[line_index].tint_color.red = 1.0; my_mesh->l[line_index].tint_color.green = 1.0; my_mesh->l[line_index].tint_color.blue = 1.0; my_mesh->l[line_index].time_offset = particles[i].offset; line_index++; if (line_index >= my_mesh->nlines) { one_is_active = 0; break; } } if (!one_is_active) break; } my_mesh->nlines = line_index; my_mesh->nvertices = line_index * 2; struct mesh *optimized_mesh = mesh_duplicate(my_mesh); mesh_free(my_mesh); return optimized_mesh; }