void context_created(generic_renderer<scene::view>&) override { // Set up the scene model so that everything is visible. const auto scene_data = model_.project.get_scene_data(); auto triangles = scene_data.get_triangles(); auto vertices = util::map_to_vector(begin(scene_data.get_vertices()), end(scene_data.get_vertices()), wayverb::core::to_vec3{}); // Get scene data in correct format. // This command will be run on the graphics thread, so it // must be thread safe. view_.high_priority_command([ t = std::move(triangles), v = std::move(vertices), vs = model_.scene.get_view_state(), pm = model_.scene.get_projection_matrix() ](auto& r) { r.set_scene(t.data(), t.size(), v.data(), v.size()); r.set_view_state(vs); r.set_projection_matrix(pm); r.set_emphasis_colour( {AngularLookAndFeel::emphasis.getFloatRed(), AngularLookAndFeel::emphasis.getFloatGreen(), AngularLookAndFeel::emphasis.getFloatBlue()}); // TODO we might need to set other state here too. }); }
auto load_scene(const std::string& name) { // Attempt to load from file path. wayverb::core::scene_data_loader loader{name}; const auto scene_data = loader.get_scene_data(); if (!scene_data) { throw std::runtime_error{"Failed to load scene."}; } return wayverb::core::make_scene_data( scene_data->get_triangles(), scene_data->get_vertices(), util::aligned::vector< wayverb::core::surface<wayverb::core::simulation_bands>>( scene_data->get_surfaces().size(), wayverb::core::surface<wayverb::core::simulation_bands>{})); }
static qboolean load_iqm_meshes (model_t *mod, const iqmheader *hdr, byte *buffer) { iqm_t *iqm = (iqm_t *) mod->aliashdr; iqmtriangle *tris; iqmmesh *meshes; iqmjoint *joints; uint32_t i; if (!load_iqm_vertex_arrays (mod, hdr, buffer)) return false; if (!(tris = get_triangles (hdr, buffer))) return false; iqm->num_elements = hdr->num_triangles * 3; iqm->elements = malloc (hdr->num_triangles * 3 * sizeof (uint16_t)); for (i = 0; i < hdr->num_triangles; i++) VectorCopy (tris[i].vertex, iqm->elements + i * 3); if (!(meshes = get_meshes (hdr, buffer))) return false; iqm->num_meshes = hdr->num_meshes; iqm->meshes = malloc (hdr->num_meshes * sizeof (iqmmesh)); memcpy (iqm->meshes, meshes, hdr->num_meshes * sizeof (iqmmesh)); if (!(joints = get_joints (hdr, buffer))) return false; iqm->num_joints = hdr->num_joints; iqm->joints = malloc (iqm->num_joints * sizeof (iqmjoint)); iqm->baseframe = malloc (iqm->num_joints * sizeof (mat4_t)); iqm->inverse_baseframe = malloc (iqm->num_joints * sizeof (mat4_t)); memcpy (iqm->joints, joints, iqm->num_joints * sizeof (iqmjoint)); for (i = 0; i < hdr->num_joints; i++) { iqmjoint *j = &iqm->joints[i]; mat4_t *bf = &iqm->baseframe[i]; mat4_t *ibf = &iqm->inverse_baseframe[i]; quat_t t; float ilen; ilen = 1.0 / sqrt(QDotProduct (j->rotate, j->rotate)); QuatScale (j->rotate, ilen, t); Mat4Init (t, j->scale, j->translate, *bf); Mat4Inverse (*bf, *ibf); if (j->parent >= 0) { Mat4Mult (iqm->baseframe[j->parent], *bf, *bf); Mat4Mult (*ibf, iqm->inverse_baseframe[j->parent], *ibf); } } return true; }
/* Create new migration edge and grow mesh recursively around it */ static void mesh_from_edge(MIGRATION *edge) { MIGRATION *ej0, *ej1; RBFNODE *tvert[2]; if (edge == NULL) return; /* triangle on either side? */ get_triangles(tvert, edge); if (tvert[0] == NULL) { /* grow mesh on right */ tvert[0] = find_chull_vert(edge->rbfv[0], edge->rbfv[1]); if (tvert[0] != NULL) { if (tvert[0]->ord > edge->rbfv[0]->ord) ej0 = create_migration(edge->rbfv[0], tvert[0]); else ej0 = create_migration(tvert[0], edge->rbfv[0]); if (tvert[0]->ord > edge->rbfv[1]->ord) ej1 = create_migration(edge->rbfv[1], tvert[0]); else ej1 = create_migration(tvert[0], edge->rbfv[1]); mesh_from_edge(ej0); mesh_from_edge(ej1); return; } } if (tvert[1] == NULL) { /* grow mesh on left */ tvert[1] = find_chull_vert(edge->rbfv[1], edge->rbfv[0]); if (tvert[1] != NULL) { if (tvert[1]->ord > edge->rbfv[0]->ord) ej0 = create_migration(edge->rbfv[0], tvert[1]); else ej0 = create_migration(tvert[1], edge->rbfv[0]); if (tvert[1]->ord > edge->rbfv[1]->ord) ej1 = create_migration(edge->rbfv[1], tvert[1]); else ej1 = create_migration(tvert[1], edge->rbfv[1]); mesh_from_edge(ej0); mesh_from_edge(ej1); } } }
/* Check if prospective vertex would create overlapping triangle */ static int overlaps_tri(const RBFNODE *bv0, const RBFNODE *bv1, const RBFNODE *pv) { const MIGRATION *ej; RBFNODE *vother[2]; int im_rev; /* find shared edge in mesh */ for (ej = pv->ejl; ej != NULL; ej = nextedge(pv,ej)) { const RBFNODE *tv = opp_rbf(pv,ej); if (tv == bv0) { im_rev = is_rev_tri(ej->rbfv[0]->invec, ej->rbfv[1]->invec, bv1->invec); break; } if (tv == bv1) { im_rev = is_rev_tri(ej->rbfv[0]->invec, ej->rbfv[1]->invec, bv0->invec); break; } } if (!get_triangles(vother, ej)) /* triangle on same side? */ return(0); return(vother[im_rev] != NULL); }
void Polyhedron_demo_kernel_plugin::on_actionKernel_triggered() { const Scene_interface::Item_id index = scene->mainSelectionIndex(); Scene_polyhedron_item* item = qobject_cast<Scene_polyhedron_item*>(scene->item(index)); if(item) { Polyhedron* pMesh = item->polyhedron(); typedef CGAL::Exact_integer ET; // choose exact integral type typedef Polyhedron_kernel<Kernel,ET> Polyhedron_kernel; // get triangles from polyhedron std::list<Triangle> triangles; get_triangles(*pMesh,std::back_inserter(triangles)); // solve LP std::cout << "Solve linear program..."; Polyhedron_kernel kernel; if(!kernel.solve(triangles.begin(),triangles.end())) { std::cout << "done (empty kernel)" << std::endl; QMessageBox::information(mw, tr("Empty kernel"), tr("The kernel of the polyhedron \"%1\" is empty."). arg(item->name())); QApplication::restoreOverrideCursor(); return; } std::cout << "done" << std::endl; // add kernel as new polyhedron Polyhedron *pKernel = new Polyhedron; // get inside point Point inside_point = kernel.inside_point(); Vector translate = inside_point - CGAL::ORIGIN; // compute dual of translated polyhedron w.r.t. inside point. std::cout << "Compute dual of translated polyhedron..."; std::list<Point> dual_points; std::list<Triangle>::iterator it; for(it = triangles.begin(); it != triangles.end(); it++) { const Triangle& triangle = *it; const Point p0 = triangle[0] - translate; const Point p1 = triangle[1] - translate; const Point p2 = triangle[2] - translate; Plane plane(p0,p1,p2); Vector normal = plane.orthogonal_vector(); normal = normal / std::sqrt(normal*normal); // compute distance to origin (do not use plane.d()) FT distance_to_origin = std::sqrt(CGAL::squared_distance(Point(CGAL::ORIGIN),plane)); Point dual_point = CGAL::ORIGIN + normal / distance_to_origin; dual_points.push_back(dual_point); } std::cout << "ok" << std::endl; // compute convex hull in dual space std::cout << "convex hull in dual space..."; Polyhedron convex_hull; CGAL::convex_hull_3(dual_points.begin(),dual_points.end(),convex_hull); std::cout << "ok" << std::endl; // dualize and translate back to get final kernel Dualizer<Polyhedron,Kernel> dualizer; dualizer.run(convex_hull,*pKernel); ::translate<Polyhedron,Kernel>(*pKernel,translate); pKernel->inside_out(); Scene_polyhedron_item* new_item = new Scene_polyhedron_item(pKernel); new_item->setName(tr("%1 (kernel)").arg(item->name())); new_item->setColor(Qt::magenta); new_item->setRenderingMode(item->renderingMode()); scene->addItem(new_item); item->setRenderingMode(Wireframe); scene->itemChanged(item); QApplication::restoreOverrideCursor(); } }