5
$\begingroup$

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

$\endgroup$
9
$\begingroup$
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

| improve this answer | |
$\endgroup$
  • $\begingroup$ 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? $\endgroup$ – Putterboy Sep 4 '14 at 9:37
  • $\begingroup$ @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... $\endgroup$ – kglr Sep 4 '14 at 9:56
2
$\begingroup$

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

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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