Feedback

What's your question?

By: Asked

How do I create a uniform distribution of points on a 3d mesh?

Hi,

I would like to know algorithms or open source api that would generate n uniform points on a 3d mesh. Preferably if this can be achieved using Maya's api then it would be great.

Prashant

Add comment viewed 1,322 times Latest activity 10 months ago

NN comments
or Cancel

6 answers

  • 2

hradec [ Editor ]

I think you can easily do that with cortex-vfx!

they got a gpu hair render example that actually uses the UniformRandomPointDistributionOp() to create points for the hair generation:

http://code.google.com/p/cortex-vfx/wiki/GpuShaderHairExample

have a look at "generateHair()" method...

You can build cortex in Linux and OSX easily.. Windows is a bit more difficult! (I think I'm the only one who actually did built it in windows! )

you can import cortex into mayas python, and convert a maya shape node to a cortex meshprimitive on the fly, and do the points generation! ;)

Hradec

NN comments
bård
-

Please do tell how to compile cortex on windows. It would be very helpful!

or Cancel
  • 1

jonathan wills

A couple interesting papers:

http://graphics.uni-konstanz.de/publikationen/2009/capacityconstrainedpointdistributions/website/

http://johanneskopf.de/publications/blue_noise/

I know of a simplified implementation of the 'capacity constrained method' that has been extended to polygon meshes but unfortunately is not open source.

The open source VFX framework Cortex has a PointRepulsion operator:

http://code.google.com/p/cortex-vfx/source/browse/trunk/src/IECore/PointRepulsionOp.cpp

This pretty much implements Turk's reaction-diffusion point repulsion in Andrew's post and explained in more detail in Julian's post.

Cheers,
Jonathan

NN comments
julian
-

that link about capacity constraints is cool! – I never had the hexagon problem they talk about. Maybe something to do with only considering 5 neighbors, or perhaps because the surfaces were always irregular. But the other issue they solve – maintaining the mapped density – I always found to be a problem as the points tend to just keep spreading.

or Cancel
  • 0

andrew marshall [ Editor ]

I'm assuming here when you say 'uniform' you mean 'random from a uniform distribution'.

Unfortunately I don't have access to the Maya API, but one common approach is iterative point repulsion, as described by Greg Turk in the paper "Generating textures on arbitrary surfaces using reaction-diffusion".

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.113.8621

Essentially, the approach is to generate random points in each triangle ( See Turk's 'Generating Random Points in Triangles' from Graphics Gems ), with probability weighted by the triangle area. Then move each point iteratively until the required distribution is achieved.

It may be worth investigating the open source CGAL library ( no jokes, Bournemouth people ), but make sure the license is compatible with your particular usage.

http://www.cgal.org/

or Cancel
  • 0

julian [ Admin ]

I had this problem while writing a feather system - here's the method I used.

First, generate a random distribution of points on each triangle - like Andrew says, weighted by area.

Then, to relax the points so they are evenly spaced on the surface, do a 2 step process.

  1. Iterate over the points moving each point (in world space) a small distance away from its closest neighbors.
  2. Snap all the points back to the closest point on the surface

Repeat those 2 steps until you are happy with the distribution. The points are well distributed when each point is surrounded by its neighbors at equal distances, and at that stage the repulsive force from each neighbor will nearly cancel out for a given point. So - as you iterate through the points, accumulate the magnitudes of those repulsion vectors and if the average is below a user defined threshold, stop refining.

It can be expensive to run those relax-and-snap steps several times because finding the closest neighbors means every point potentially considers every other point. You can use a kdTree to speed things up there. Also, finding the closest point on the mesh is slow for many tests by brute force. In my system I used another kdTree to store the triangles and that sped things up quite a bit, but its trickier than making a kdTree for points.

As an alternative to all that work, it might be worth looking at nParticles because they have some built in system to spread points evenly, and they can also be constrained to a surface. In this tutorial by Duncan Brinsmead he talks about attracting fluid nParticles to a glass surface, so that setup could theoretically be used to distribute points on a surface.

One of the problems I came up against (that will probably also be an issue with nParticles) was that for thin surfaces (like a birds wing) the repulsion algorithm was considering points on the other side of the wing. It would make the distribution very uneven on the surface as it was mainly trying to even things out in worldspace and those points on the other side were still close in worldspace. So I added in a test to make sure that only points on triangles with normals within some threshold angle would be considered.

EDIT Here's some code - I tried to make it self contained.

There's no Makefile because I use a different build system. Have a look at the file target.yml to see what maya libs are needed.

Once you have everything compiled open the scene test1.ma (from the examples folder.) It should look like this:

I'll add some better commenting and tidy up a bit as soon as I get time.

NN comments
vfxoverflow_191
-

Generating n points is not difficult point spreading out uniformly is bit difficult. I am writing a fur generation system and it’s actually a stand alone app. The app is on planning stage. It would be great if you can share some of your code.

julian
-

no prob – I’ll let you know when its online

or Cancel