# Is it possible to assign different colors to parts of an .obj file?

There are four different cubes in an .obj file. After loaded into Mathematica, is it possible to assign four random colors to the cubes?

 (* assuming the .obj file was loaded in the c: root *)
cubes = Import["c:\\4cubes.obj"] ;
Graphics3D[  First[cubes]  ]


-

gr = Import["...\4cubes.obj",  "GraphicsComplex"];

Graphics3D[gr] /. Polygon[x_] :> ({Hue[RandomReal[]], Polygon[#]} & /@ Partition[x, 6])


alltextures = ExampleData /@ ExampleData["ColorTexture"];
alltextures = alltextures /. \$Failed -> Sequence[];
tc = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};

Graphics3D[gr] /. Polygon[x_] :>
({Texture[ImageMultiply[RandomChoice[alltextures], Hue[RandomReal[]]]],
Polygon[#, VertexTextureCoordinates -> Table[tc, {6}]]} & /@
Partition[x, 6])


To assign specific colors:

col = {Red, Blue, Orange, Green};
Graphics3D[gr] /. Polygon[x_] :> ({#, Polygon[#2]} & @@@ Transpose[{col, Partition[x, 6]}])


Update: Dealing with more general polyhedra

grb = Import["...\\4shapes.obj", "GraphicsComplex"];
Graphics3D[grb]


Approach: Form a graph using the polygons as the vertex set. Two polygons are connected if they share one or more vertices. ConnectedComponents of the resulting graph are the polyhedral objects we seek to identify.

Note: We work with Graphics using Normal@grb. An approach using GraphicsComplex failed because the vertex coordinate list has duplicates which prevents working with the indices to identify neighboring polygons.

polygons = Join @@ (Normal[grb] /. HoldPattern[VertexNormals -> _] :> Sequence[]);
polygons = polygons /. Polygon -> Sequence;
edges = DeleteDuplicates[UndirectedEdge @@@
Map[ToString, Select[Subsets[polygons, {2}], Intersection @@ # =!= {} &], {-2}]];
Graph[edges]


connectedcomps = Map[ToExpression, ConnectedComponents[Graph[edges]], {-1}];
Graphics3D[{Hue[RandomReal[]], Polygon[#]} & /@ connectedcomps, Lighting -> "Neutral"]


Graphics3D[({Texture[ImageMultiply[RandomChoice[alltextures], Hue[RandomReal[]]]],
Polygon[#,  VertexTextureCoordinates ->
Table[tc[[;; Max[Length /@ #]]], {Length@#}]]} & /@ connectedcomps),
Lighting -> "Neutral"]


-
Thanks a lot for your detailed answers. I would like to ask one more thing, how to modify your answer to deal with .obj file with different shapes like this? – Putterboy Sep 4 '14 at 9:37
@Putterboy, I was afraid "this" was coming:) Even in the specific case of 4cubes, it was pure luck that the single Polygon in the GraphicsComplex contained the faces in a particular order so that Partition[...,6] gave the cubes we needed. For general shapes, I can't think of any approach that can identify arbitrary collection of shapes in a set of polygons. Great question btw... – kglr Sep 4 '14 at 9:56
Thanks again anyway. – Putterboy Sep 4 '14 at 10:12

I have just figured out a manual way to get the job done, although a bit clumsy, I think it is still worth posting it.

(* assuming the .obj file was loaded in the c: root *)
gr = Import["c:\\4shapes.obj", "GraphicsComplex"]  ;
Clear[a, b, c, d, x, y, z, ca, cb, cc, cd, ce, cf, cg ];
{ca, cb, cc, cd, ce, cf, cg} = {Red, Blue, Yellow, Green, Gray, Cyan, Orange};
space = 5;
verts = gr[[1]];
L1 = (gr[[2]][[1]] /. Polygon -> List)[[1]]  ;
L2 = (gr[[2]][[2]] /. Polygon -> List) [[1]];
vNum1 = Length[L1];
vNum2 = Length[L2];

Manipulate[
Graphics3D[GraphicsComplex[verts, {
If[aB, {ca, Polygon[Take[L1, {1, a}] ]}, {}],
If[bB, {cb, Polygon[Take[L1, {a + 1, b}] ]}, {}],
If[cB, {cc, Polygon[Take[L1, {b + 1 , c }] ]}, {}],
If[dB, {cd, Polygon[Take[L1, {c + 1 , d}] ]}, {}],
If[xB, {ce, Polygon[Take[L2, {1 , x }] ]} , {}] ,
If[yB, {cf, Polygon[Take[L2, {x + 1 , y }] ]} , {}] ,
If[zB, {cg, Polygon[Take[L2, {y + 1 , z }] ]} , {}]
}]],

Grid[{
{
ColorSetter[Dynamic[ca], ImageSize -> {20, 20}],
Control[{{aB, True, ""}, {True -> "show", False -> "hide"},
Spacer[space],
Control[{{a, 2, "Shape 1"}, 1, vNum1, 1, Appearance -> "Labeled"}]
},
{
ColorSetter[Dynamic[cb], ImageSize -> {20, 20}],
Control[{{bB, True, ""}, {True -> "show", False -> "hide"},
Spacer[space],
Control[{{b, a, "Shape 2"}, a, vNum1, 1, Appearance -> "Labeled"}]
},
{
ColorSetter[Dynamic[cc], ImageSize -> {20, 20}],
Control[{{cB, True, ""}, {True -> "show", False -> "hide"},
Spacer[space],
Control[{{c, b, "Shape 3"}, b, vNum1, 1, Appearance -> "Labeled"}]
} ,
{
ColorSetter[Dynamic[cd], ImageSize -> {20, 20}],
Control[{{dB, False, ""}, {True -> "show", False -> "hide"},
Spacer[space],
Control[{{d, c, "Shape 4"}, 1, vNum1, 1, Appearance -> "Labeled"}]
}  ,
{
ColorSetter[Dynamic[ce], ImageSize -> {20, 20}],
Control[{{xB, False, ""}, {True -> "show", False -> "hide"},
Spacer[space],
Control[{{x, 2, "Shape 5"}, 1, vNum2, 1, Appearance -> "Labeled"}]
}  ,
{
ColorSetter[Dynamic[cf], ImageSize -> {20, 20}],
Control[{{yB, False, ""}, {True -> "show", False -> "hide"},
Spacer[space],
Control[{{y, x, "Shape 6"}, x, vNum2, 1, Appearance -> "Labeled"}]
}  ,
{
ColorSetter[Dynamic[cg], ImageSize -> {20, 20}],
Control[{{zB, False, ""}, {True -> "show", False -> "hide"},