# Breaking down a 3D model into patches

I have a 3D model, say the Stanford bunny, which is available in Mathematica examples.

 Import[ "http://exampledata.wolfram.com/bunny.noff.gz" ]


Also information such as the 3D coordinate of vertices and the normal at each vertex is available.

Now I'd like to divide the whole thing into $n$, say 10, non overlapping patches. Something like the patches on a football. Patches must contain more or less same number of points, but this is a soft constraint.

I see there is a function FindShortestPath in Mathematica. Maybe that function can help me? Since I am a new user I am not sure how I should approach the problem.

-
FindShortestPath is used for Graphs and I don't see a direct application to 3D graphics. – Sjoerd C. de Vries Jul 1 '13 at 13:06
Perhaps you're thinking of FindClusters, although at the moment I don't see an easy way to apply it. – Michael E2 Jul 1 '13 at 13:17
A vertex connection analysis (resulting in a graph) should be really useful here. – Yves Klett Jul 1 '13 at 13:32
@YvesKlett I agree that vertex analysis should help, specially in cases like here were Polygons, hence connected vertexes, are known. – user5131 Jul 1 '13 at 15:36

This is a bit long for a comment:

The following approach seems to work, but is veeeery slow for the bunny. I am sure there are many ways to speed things up... (especially the Position bit). Before optimizing too much, I present the approach (maybe your data is not as complicated? Or speed is no issue?)

Let

bn= Import[ "http://exampledata.wolfram.com/bunny.noff.gz" ]


then we use FindClusters (see its documentation for e.g. other DistanceFunctions)

fc = FindClusters[bn[[1, 2, 1]], 5];


(fixing 5 clusters). Then (the slow part...)

Graphics3D[{EdgeForm[],
bn[[1, 2]] /.
GraphicsComplex[v_, r__] :>
GraphicsComplex[v, r,
VertexColors -> (
Switch[Position[fc, #][[1, 1]], 1, Red, 2, Blue,
3, Green, 4, Yellow, 5, Pink, _, Black] & /@ v)]}]


where we essentially just check which cluster the vertex is in and choose (using Switch) a color accordingly.

The resulting bunny:

-
Not so bad considering the bunny consists of a meager 69451 polygons ;-) The one downside might be that due to the non-convex shape (and holes) you might get disconnected areas of one color. – Yves Klett Jul 1 '13 at 13:35
True - based on the data, one most probably has to play with the DistanceFunction or Method (of FindClusters) a bit to get the desired effect... since the OP is not very clear about the structure/size of the dataset, I figured I offer a general approach, but thanks for the input! – Pinguin Dirk Jul 1 '13 at 13:41
Not to worry, I like your rainbow bunny :-) – Yves Klett Jul 1 '13 at 13:42
it looks both like a football and scary :) – Pinguin Dirk Jul 1 '13 at 13:50
@YvesKlett Take a look at the last picture stackoverflow.com/a/4464141/353410 – Dr. belisarius Jul 1 '13 at 15:27

If you don't mind a mottled bunny, you can do the partitioning by just choosing the points in order as they appear in the drawing (let Partition do the partitioning).

bn = Import["http://exampledata.wolfram.com/bunny.noff.gz"];
tris = bn[[1, 2, 1]];
poly = bn[[1, 2, 2, 1, 1]];
lenPoly = Length[poly];
n = 10;
part = Partition[poly, Floor[lenPoly/n]];
Graphics3D[{EdgeForm[],
Table[{Hue[i/n], GraphicsComplex[tris, Polygon[part[[i]]]]}, {i, 1, n}]}]


-