Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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]  ]

enter image description here

share|improve this question

2 Answers 2

up vote 8 down vote accepted
gr = Import["...\4cubes.obj",  "GraphicsComplex"];

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

enter image description here

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])

enter image description here

To assign specific colors:

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

enter image description here

Update: Dealing with more general polyhedra

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

enter image description here

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]

enter image description here

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

enter image description here

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

enter image description here

share|improve this answer
    
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 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... –  kguler Sep 4 at 9:56
    
Thanks again anyway. –  Putterboy Sep 4 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.

enter image description here

(* 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"}, 
      ControlType -> RadioButtonBar}],
    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"}, 
      ControlType -> RadioButtonBar}],
    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"}, 
      ControlType -> RadioButtonBar}],
    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"}, 
      ControlType -> RadioButtonBar}],
    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"}, 
      ControlType -> RadioButtonBar}],
    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"}, 
      ControlType -> RadioButtonBar}],
    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"}, 
      ControlType -> RadioButtonBar}],
    Spacer[space],
    Control[{{z, vNum2, "Shape 7"}, y, vNum2, 1, 
      Appearance -> "Labeled"}] 
    }  
   }]
 ]

The link for the obj file: Click here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.