I have a mesh (points, triangles and color per vertex) The point cloud is dense enough so this texture representation is good. now I would like to simpify the mesh without distroying the render quality (and without moving to texture mapping)
Ideas? So far I've removed vertexes based on some huristic (color and normal similarity to neighbors) and then trying to make a triangulation (ball pivot) with meshlab. That's working ok.
any better ideas?
Thanks
High quality mesh simplification is unfortunately not an easy task and you will need a good algorithm to decide which vertices can be removed without decreasing quality too much.
Some established algorithms exist already and are published online, e.g.:
"New Quadric Metric for Simplifying Meshes with Appearance
Attributes" of Hugues Hoppe
"Simplifying Surfaces with Color and Texture using Quadric Error Metrics" of Michael Garland et al.
Related
I have a program that visualizes triangular meshes and allows the users to draw on the meshes using a pen. I want to have a "snapping" mode in my system. The snapping mode performs drawing corrections for the user in the sense that the user-drawn lines are snapped to the nearest edge (or the silhouette) of that part of the mesh.
I'm looking for an algorithm that compute the edges visible on the mesh from a given point of view. By edges, I'm referring to the outlines of the shape: corner points and the lines between them (similar to the definition of an edge in computer vision/image processing -- such as Canny edges).
So far I've thought of two approaches for this:
Edge detection: so far I've only found this paper. Their method is understandable, yet the implementation is not trivial (due to tensor computations and some ambiguity in their explanations). The problem with this approach is that it produces "edge strength values" which is a value in the range [0, 1] for every vertex. The value of 1 indicates an edge vertex with a high confidence. This introduces extra thresholding parameters in the system which I'd rather not have. Their output looks like this (range [0, 1] scaled to [0, 65535]):
Rendering or non-photorealistic methods such as the one asked in this question or this paper. They seem to be able to create the silhouette that I'm after as can be seen below:
I'm not a graphics expert and as of yet I don't know whether their methods can be used for computation of the feature lines rather than rendering.
I was wondering if anybody has any ideas about a good algorithm for what I want to do. Since the system is very interactive, the performance is important. The snapping feature does not have to be enabled all the time (therefore, if the method is computationally expensive, some delay in when "snapping enabled" mode is toggled can be tolerated while the algorithm is computing the edges.) Also, if you know of any implementation (preferably open source), I'd be grateful if you could share it with me.
There are two types of edges that you want to detect:
silhouette edges are viewpoint dependent, they correspond to the places where the line of sight tangents the surfaces. With a triangulated model, they are easy to determine, as they are shared by a front-facing triangle and a back-facing one.
"angular" edges are viewpoint independent and formed by a discontinuity in the tangent plane direction. As a triangulated model has itself this kind of discontinuity, there is no exact criterion to find them. Just set a threshold on the angle formed by two triangles. This threshold must be such that smooth patches do not trigger.
By this approach, you will find the wanted edges in 3D.
This is not enough, as part of them are hidden by other surfaces. You have the option of integrating them as edges in the 3D model and letting the rendering engine do its job, or, if you have the courage, to implement an hidden lines removal algorithm. (The wikipedia link is a little terse.)
Since posting the question, something else came into my head. Since 2D edge detection is a very well-studied problem, one way of tackling the problem is performing 2D edge detection on the projection image of the mesh.
In other words, given a specific view of the mesh, one could generate a 2D image. A 2D edge detection algorithm (such as Canny edge detector) could then be run on the 2D image and the results can be back-projected to 3D to determine the silhouettes of the mesh in question. One possible advantage of this is simplicity!
Edit (2017):
Even though I moved away from this, I returned to this problem again for a different purpose. To anybody else looking into this problem: there is a paper that talks about various contours from meshes that's worth reading (the paper is "Suggestive Contours for Conveying Shape" by DeCarlo et al.).
Working implementation of the methods discussed in the paper are available here.
I am attempting to use Three.js to morph one geometry into another. Here's what I've done so far (see http://stemkoski.github.io/Three.js/Morph-Geometries.html for a live example).
I am attempting to morph from a small polyhedron to a larger cube (both triangulated and centered at the origin). The animating is done via shaders. Each vertex on the smaller polyhedron has two associated attributes, its final position and its final UV coordinate. To calculate the final position of each vertex, I raycasted from the origin through each vertex of the smaller polyhedron and found the point of intersection with the larger cube. To calculate the final UV value, I used barycentric coordinates and the UV values at the vertices of the intersected face of the larger cube.
That led to a not awful but not great first attempt. Since (usually) none of the vertices of the larger cube were the final position of any of the vertices of the smaller polyhedron, big chunks of the surface of the cube were missing. So next I refined the smaller polyhedron by adding more vertices as follows: for each vertex of the larger cube, I raycasted toward the origin, and where each ray intersected a face of the smaller polyhedron, I removed that triangular face and added the point of intersection and three smaller faces to replace it. Now the morph is better (this is the live example linked to above), but the morph still does not fill out the entire volume of the cube.
My best guess is that in addition to projecting the vertices of the larger cube onto the smaller polyhedron, I also need to project the edges -- if A and B are vertices connected by an edge on the larger cube, then the projections of these vertices on the smaller polyhedron should also be connected by an edge. But then, of course it is possible that the projected edge will cross over multiple pre-existing triangles in the mesh of the smaller polyhedron, requiring multiple new vertices be added, retriangularization, etc. It seems that what I actually need is an algorithm to calculate a common refinement of two triangular meshes. Does anyone know of such an algorithm and/or examples (with code) of morphing (between two meshes with different triangularizations) as described above?
As it turns out, this is an intricate question. In the technical literature, the algorithm I am interested in is sometimes called the "map overlay algorithm"; the mesh I am constructing is sometimes called the "supermesh".
Some useful works I have been reading about this problem include:
Morphing of Meshes: The State of the Art and Concept.
PhD. Thesis by Jindrich Parus
http://herakles.zcu.cz/~skala/MSc/Diploma_Data/REP_2005_Parus_Jindrich.pdf
(chapter 4 especially helpful)
Computational Geometry: Algorithms and Applications (book)
Mark de Berg et al
(chapter 2 especially helpful)
Shape Transformation for Polyhedral Objects (article)
Computer Graphics, 26, 2, July 1992
by James R. Kent et al
http://www.cs.uoi.gr/~fudos/morphing/structural-morphing.pdf
I have started writing a series of demos to build up the machinery needed to implement the algorithms discussed in the literature referenced above to solve my original question. So far, these include:
Spherical projection of a mesh # http://stemkoski.github.io/Three.js/Sphere-Project.html
Topological data structure of a THREE.Geometry # http://stemkoski.github.io/Three.js/Topology-Data.html
There is still more work to be done; I will update this answer periodically as I make additional progress, and still hope that others have information to contribute!
I have a 3D Cartesian cube. For each point in this cube there is a corresponding density value. When the density changes suddenly it means that there is a cavity. Now to find the cavity I calculate the gradient at each point in the cube. This gives me a point cloud on the surface of the cavity. I would now like to mesh the surface of the cavity given the point cloud.
Unfortunately I don't have any experience with surface reconstruction and was wondering if someone can recommend a suitable algorithm which will produce a closed surface of the cavity?
The cube is quite big so a point cloud of the surface of a cavity can easily be 500.000 points or more. I have read this post: robust algorithm for surface reconstruction from 3D point cloud? which I find useful. However it seems that the problem I am facing is simpler, given that:
The coordinates of the points are always integer
The point distribution is even
The distance from one point to its closest neighbour is either 1, sqrt(2) or sqrt(3)
You probably want the marching cubes algorithm.
The Marching Cubes algorithm will do exactly what you want. For a working implementation (using Three.js for rendering the graphics), check out:
http://stemkoski.github.com/Three.js/Marching-Cubes.html
For more details on the theory, I think the best article is the website:
http://paulbourke.net/geometry/polygonise/
I am trying to make a quadrilateral mesh from a surface mesh (which is mostly triangular) generated by Mathematica. I am not looking for high quality mesher but a simple work around algorithm. I use GMSH for doing it externally. We can make use of Mathematic's CAD import capabilities to generate 3D geometries that are understood by the Mathematica kernel.
We can see the imported Geometry3D objects and the plots of number of sides in each polygons they consist of. It become visible that the polygons that form the mesh are not always triangles.
Name3D=RandomChoice[ExampleData["Geometry3D"][[All,2]],6];
AllPic=
Table[
Vertex=ExampleData[{"Geometry3D",Name3D[[i]]},"VertexData"];
Polygons=ExampleData[{"Geometry3D",Name3D[[i]]},"PolygonData"];
GraphicsGrid[
{{ListPlot[#,Frame-> True,PlotLabel->Name3D[[i]] ]&#(Length[#]&/#Polygons),
Graphics3D[GraphicsComplex[Vertex,Polygon[Polygons]],Boxed-> False]}}
,ImageSize-> 300,Spacings-> {0,0}],
{i,1,Length#Name3D}];
GraphicsGrid[Partition[AllPic,2],Spacings-> {0,0}]
Now what I am looking for is an algorithm to form a quadrilateral mesh from that polygon information available to MMA. Any easy solution is very much welcome. By easy solution I mean which is not going to work in a very general setting (where mesh constitutes of polygons with sides more than 5 or 6) and which might be quite inefficient compared to commercial software. But one can see that there are not many quadrilateral surface mesh generator available other than few expensive commercial one.
BR
this will produce quads regardless of the input topology:
insert one vertex in the center of each face
insert one vertex at the midpoint of each edge
insert edges connecting each face's center vertex with it's edges' midpoint vertices
I have a set of 3d points that approximate a surface. Each point, however, are subject to some error. Furthermore, the set of points contain a lot more points than is actually needed to represent the underlying surface.
What I am looking for is an algorithm to create a new (much smaller) set of points representing a simplified, smoother version of the surface (pardon for not having a better definition than "simplified, smoother"). The underlying surface is not a mathematical one so I'm not hoping to fit the data set to some mathematical function.
Instead of dealing with it as a point cloud, I would recommend triangulating a mesh using Delaunay triangulation: http://en.wikipedia.org/wiki/Delaunay_triangulation
Then decimate the mesh. You can research decimation algorithms, but you can get pretty good quick and dirty results with an algorithm that just merges adjacent tris that have similar normals.
I think you are looking for 'Level of detail' algorithms.
A simple one to implement is to break your volume (surface) into some number of sub-volumes. From the points in each sub-volume, choose a representative point (such as the one closest to center, or the closest to the average, or the average etc). use these points to redraw your surface.
You can tweak the number of sub-volumes to increase/decrease detail on the fly.
I'd approach this by looking for vertices (points) that contribute little to the curvature of the surface. Find all the sides emerging from each vertex and take the dot products of pairs (?) of them. The points representing very shallow "hills" will subtend huge angles (near 180 degrees) and have small dot products.
Those vertices with the smallest numbers would then be candidates for removal. The vertices around them will then form a plane.
Or something like that.
Google for Hugues Hoppe and his "surface reconstruction" work.
Surface reconstruction is used to find a meshed surface to fit the point cloud; however, this method yields lots of triangles. You can then apply mesh a reduction technique to reduce the polygon count in a way to minimize error. As an example, you can look at OpenMesh's decimation methods.
OpenMesh
Hugues Hoppe
There exist several different techniques for point-based surface model simplification, including:
clustering;
particle simulation;
iterative simplification.
See the survey:
M. Pauly, M. Gross, and L. P. Kobbelt. Efficient simplification of point-
sampled surfaces. In Proceedings of the conference on Visualization’02,
pages 163–170, Washington, DC, 2002. IEEE.
unless you parametrise your surface in some way i'm not sure how you can decide which points carry similar information (and can thus be thrown away).
i guess you can choose a bunch of points at random to get rid of, but that doesn't sound like what you want to do.
maybe points near each other (for some definition of 'near') can be considered to contain similar information, and so reduced to single representatives for each such group.
could you give some more details?
It's simpler to simplify a point cloud without the constraints of mesh triangles and indices.
smoothing and simplification are different tasks though. To simplify the cloud you should first get rid of noise artefacts by making a profile of the kind of noise that you have, it's frequency and directional caracteristics and do a noise profile compared type reduction. good normal vectors are helfpul for that.
here is a document about 5-6 simplifications using delauney, voronoi, and k nearest neighbour maths:
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.10.9640&rep=rep1&type=pdf
A later version from 2008:
http://www.wseas.us/e-library/transactions/research/2008/30-705.pdf
here is a recent c++ version:
https://github.com/tudelft3d/masbcpp/blob/master/src/simplify.cpp