# Painted faces of n×n×n cube

Given a 3×3×3 cube made of 27 unit blocks. If the cube is painted, then each of the blocks has 3 of its faces painted, a given block may have 0, 1, 2 , or 3 of its faces painted. I want to mark different colors for them. I came up with the following way, it only works for n=3 and n=4, and coloring only the boundary is better than coloring the whole cube. Do you have a better way? Maybe the mesh based method will be useful.

n = 3;
pts = Tuples[Range[0, n - 1], 3];
pts1 = Tuples[{0, n - 1}, 3];
pts2 = Position[CrossMatrix[All, n {1, 1, 1}], 1] - 1;
pts3 = Complement[pts, pts1, pts2];
Graphics3D[{
Red, Translate[Cuboid[], pts1],
Blue, Translate[Cuboid[], pts2],
Green, Translate[Cuboid[], pts3]
}]


## Updated

• We use GridGraph to get the relations of the connect.
• By using such connect relation, we can collect which surfaces of the cuboids should be colorize.
Clear["Global*"];
n = 5;
g = Graph3D[GridGraph[{n, n, n}],
VertexCoordinates -> Tuples[Range[n], 3]];
colors = {1 -> Blue, 2 -> Green, 3 -> Red, 0 -> Opacity[.5]};
index2normal = {1 -> {0, 0, -1}, 2 -> {0, -1, 0}, 3 -> {1, 0, 0},
4 -> {0, 1, 0}, 5 -> {-1, 0, 0}, 6 -> {0, 0, 1}};
normal2index = Reverse[index2normal, {2}];
normal[i_] := # - (i /. coords) & /@ (AdjacencyList[g, i] /. coords);
draw[i_] :=
Module[{indexs, coidexs, faces},
indexs = normal[i] /. normal2index;
coindexs = Complement[Range[6], indexs];
faces = MeshPrimitives[Cuboid[(i /. coords)/.75], 2];
{Length@coindexs /. colors, faces[[coindexs]], Opacity[.5], White,
faces[[indexs]]}];
Graphics3D[Table[draw[i], {i, VertexList[g]}], Boxed -> False]


A starting point.

Clear["Global*"];
n = 8;
g = Graph3D[GridGraph[{n, n, n}], EdgeStyle -> Transparent];
vd = VertexDegree[g];
rules = {1 -> Magenta, 2 -> Green, 3 -> Red, 4 -> Green, 5 -> Blue,
6 -> Opacity[.5]};
vf2[pt_, name_, bd_] := {EdgeForm[Black], Cuboid[pt - bd, pt + bd]}
size = .5;
HighlightGraph[g,
Table[Style[VertexList[g][[i]], vd[[i]] /. rules], {i,
VertexCount[g]}], EdgeShapeFunction -> "Line",
VertexShapeFunction -> vf2, VertexSize -> size,
VertexCoordinates -> Tuples[Range[n], 3]]


ClearAll[coloredCuboids];

coloredCuboids[m_] :=
Map[{Switch[Count[#, 1 | m], 3, Red, 2, Green, _, Blue], Cuboid @ #} & ] @
Tuples[Range @ m, 3]

Multicolumn[Graphics3D[coloredCuboids[#],
Boxed -> False, ImageSize -> 150, PlotLabel -> #] & /@ Range[12],
4, Appearance -> "Horizontal"]


• Nice work!(+1) How do we color only the outside faces, just like the second row of the picture in the question? Commented Dec 22, 2023 at 13:01

Using Array* functions:

Clear["Global*"];
cubesArray[n_Integer /; n <= 2] := Module[{res},
If[n < 1, res = "\[Wolf]"];
If[n == 1, res = {{{2}}}];
If[n == 2 , res = {{{2, 2}, {2, 2}}, {{2, 2}, {2, 2}}}];
res
]

cubesArray[n_Integer /; n > 2] := Module[{tmid, tupdn, res},
tmid = ConstantArray[ConstantArray[3, {n, n}] //
ReplacePart[#, {{1, 1} -> 1, {1, n} -> 1, {n, 1} -> 1, {n, n} ->
1}] &, n - 2];
tupdn =
ArrayPad[ConstantArray[3, {n - 2, n - 2}], 1, 1] //
ReplacePart[#, {{1, 1} -> 2, {1, n} -> 2, {n, 1} -> 2, {n, n} ->
2}] &;
res = Join[{tupdn}, tmid, {tupdn}]
]


Usage:

ArrayPlot3D[cubesArray[#]
, ColorRules -> {1 -> Green, 2 -> Red, 3 -> Blue}
, Boxed -> False
, PlotLabel -> #
] & /@ Range[1, 11] //
Partition[#, UpTo[4]] & // GraphicsGrid[#, ImageSize -> 600] &


Explanations:

Essentially it is a stack up of 2D matrices in 3D. For example,

cubesArray[4] // Map[MatrixForm]


Since the cubesArray is being built up from the inside out, the first two cases are conveniently added using custom definitions above.

For n>2, there is an array tmid of n-2 slices (matrices) which are Blue colored initially. Green corners are added to each using ReplacePart.

The top and bottom (or more correctly called front and back) slices called tupdn start out with a blue core which is n-2 x n-2. This is ArrayPaded with Green sides, and then the Red corners are added using ReplacePart.

Subsequently, the 3D matrix is put together using the Join` command.