9
$\begingroup$

I am trying to export a mesh from some scientific experiment (in MATLAB) and load it in blender for rendering. I'd like to assign per-face colors (as opposed to per-vertex with interpolation over faces), and am willing to use any suggested solution (i.e., any file format, some trick with UV coordinates etc.).

What is the simplest way to go with this?

$\endgroup$
9
$\begingroup$

Short answer:

  • .x3d, an xml based format. Color can be either specified

    • per vertex of face
    • per face ( colorPerVertex='false' )

    When imported via Blender's importer either method get converted to a per vertex per face scheme for the vertex_color layer.

  • Stanford .PLY format. (vertex colours are shared over all faces that use the vertex, only way to get color-per-face with this format is wasteful duplication of each vertex)

or

homegrown code: essentially this code. all you need to write is the part where you map the current polygon.index to a color, so all vertices of that loop are assigned the same colour.

Take a cube.

import bpy

indexed_colors = [
    (1,0,0), (1,1,0), (1,0,1), 
    (0,0,1), (0,1,1), (0,1,0)]

obj = bpy.data.objects['Cube']
mesh = obj.data

# you probably know how to create the color layer..
if not mesh.vertex_colors:
    # creates one 'Col' by default
    obj.data.vertex_colors.new()

color_layer = mesh.vertex_colors['Col']

i = 0
for poly in mesh.polygons:
    # print(poly.loop_indices)
    color = indexed_colors[poly.index]
    for idx in poly.loop_indices:
        # loop = mesh.loops[idx]
        # v = loop.vertex_index
        color_layer.data[i].color = color[:3]
        i +=1

enter image description here

More elaboration on mesh generation is here: How to create a mesh programmatically, without bmesh?

from_pydata (docs link) :

mesh = bpy.data.meshes.new("mesh_name")
mesh.from_pydata(vertices=[], edges=[], faces=[])
mesh.update()

obj = bpy.data.objects.new("obj_name", mesh)

scene = bpy.context.scene
scene.objects.link(obj)

Showing vertex colors


For both methods you still need to configure the Object's material once imported, if you want it to show the vertex_color layer. This configuration is relatively painless but slightly different depending on which render engine you intend to use.

For Cycles you use a node based material, shown here

For Blender's Internal renderer the process is covered here

$\endgroup$
  • $\begingroup$ I am sorry, I am rather new to blender - what do you mean by "short answer: Stanford PLY"? AFAIK the .PLY format doesn't allow for per-face colors. $\endgroup$ – olamundo May 3 '15 at 18:55
  • $\begingroup$ I see what you mean, I exported a cube from blender as .ply and imported it again and in order to preserve per face-vertex colouring it duplicates all vertex data and gets vertex colour per face-vertex that way. It's a bit of a waste. gist.github.com/zeffii/a5c4376b5a2234353d90 (example of a cube). In lieu of a format which lets you specify color per face, it's just as easy to write your own custom format. But i'll keep looking, this bugs me. $\endgroup$ – zeffii May 3 '15 at 19:37
  • $\begingroup$ Found one that does .x3d ! it at least represents colours per vertex more efficiently $\endgroup$ – zeffii May 3 '15 at 20:03
  • 1
    $\begingroup$ Thanks, I went with the .x3d format and so far it is the most flexible format I've used! $\endgroup$ – olamundo May 5 '15 at 7:27
  • $\begingroup$ only way to get color-per-face with this format is wasteful duplication of each vertex: this is not true, actually. You can add something like that in the header: element face #### property uchar red property uchar green property uchar blue property list uchar int vertex_index (sorry for the line breaks), this actually works in software such as Meshlab. $\endgroup$ – Synxis Apr 27 at 13:42
2
$\begingroup$

X3D is interesting indeed. You can subsequently edit the scale of the object in meshlab and use mesh warp algorithms based on xyz in meshlab. it saves x3d per vertex ok if you uncheck normal in the save options.

here is example of simplest x3d per face if you write a parser, i did and it works fine.

[code]

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "http://www.web3d.org/specifications/x3d-3.3.dtd" "">
<X3D>
<Scene>
<Shape>
<IndexedFaceSet colorPerVertex='false' 
colorIndex='1 0 2 3 4 4' 
coordIndex='0 1 2 3 -1 7 6 5 4 -1 0 3 7 4 -1 0 4 5 1 -1 1 5 6 2 -1 2 6 7 3'>
<Coordinate point='
-0.095 -0.115 0.04
 0.095 -0.115 0.04
 0.095 0.115 0.04
 -0.095 0.115 0.04
 -0.095 -0.115 0.00
 0.095 -0.115 0.00
 0.095 0.115 0.00
 -0.095 0.115 0.00'/> 
<Color color='
0.999 0.0 0.0 
0.0 0.94 0.0
0.04 0.095 0.9115 
0.095 -0.85 0.00
0.04 0.095 0.00115 
'/>
</IndexedFaceSet>
</Shape> 
</Scene>
</X3D>

[/code]

$\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.