8
$\begingroup$

I have a file containing approximately 900,000 x,y,z data points, each with a list of physical values at that position (temperature, density, chemical composition, etc.)

I have written a Python script to create a mesh and add a vertex at each x,y,z position. Then I added a cube to the scene and added an Emission volume shader that is fed by a Point Density texture. This produces a visualization of the distribution of points. I can write a Python function that converts the physical values to color values.

How can I assign these colors defined at the x,y,z data points to the Emission volume either directly or through the Point Density texture?

$\endgroup$
2
  • $\begingroup$ I've often wondered if there's a way to craft a smoke cache to do this sort of thing.. $\endgroup$
    – ajwood
    Jan 28, 2016 at 15:01
  • 1
    $\begingroup$ I wanted to announce that the latest builds now have an updated Point Density node that can use Vertex Color, Vertex Normal, and Vertex Weight values of a mesh. This functionality was developed after 2.77 was released, but I have been told the new Point Density will be standard in 2.78. $\endgroup$
    – astrogeek
    Mar 28, 2016 at 2:49

1 Answer 1

1
$\begingroup$

The following script will generate a vertex color layer and assign a color for each vertex coordinate. Since you have a data structure with a color assigned to each vertex, and the vertex's coordinate, you can it to assign colors to each vertex.

The code is not straightforward, since the vertex color layer does not assign a single color to each vertex, but rather a color for each mesh loop. A single vertex can be a part of several loops, and thus have several colors. In a cube, for instance, each of the 8 vertices has 3 vertex colors.

This is why the find_loops_by_vert_co function takes in an object and a vertex coordinate, and returns the list of all loop indices that include a vertex with the same coordinate.

When iterating over the vertex coordinates, this function is called and assigns the desired color to each of the relevant loops. I'm using a specific data structure to include coordinate and color data. You'll have to adapt this script to match your own data structure.

import bpy

def find_loops_by_vert_co( o, co ):
    verts = o.data.vertices
    loopsInCo = []
    for poly in o.data.polygons:
        for i in poly.loop_indices:
            vCo = verts[ o.data.loops[ i ].vertex_index ].co[:]
            compare = [ round( e1, 3 ) == round( e2, 3 ) for e1, e2 in zip( vCo, co ) ]
            count   = len( [ e for e in compare if e ] ) == 3
            if count: loopsInCo.append( i )

    return loopsInCo

o = bpy.context.object

# Create a new vertex color layer
o.data.vertex_colors.new('Heat')
heat = o.data.vertex_colors['Heat']

coos2colors = [
    { 'co' : (1.0, 0.9999999403953552, -1.0),                  'color' : ( 0.5, 0.25, 0.25 ) },
    { 'co' : (1.0, -1.0, -1.0),                                'color' : ( 0.1, 0.6,  0.3  ) }, 
    { 'co' : (-1.0000001192092896, -0.9999998211860657, -1.0), 'color' : ( 0.9, 0.1,  0.2  ) },
    { 'co' : (-0.9999996423721313, 1.0000003576278687, -1.0),  'color' : ( 0.5, 0.8,  0.0  ) },
    { 'co' : (1.0000004768371582, 0.999999463558197, 1.0),     'color' : ( 0.4, 0.4,  0.9  ) },
    { 'co' : (0.9999993443489075, -1.0000005960464478, 1.0),   'color' : ( 0.1, 0.1,  0.6  ) },
    { 'co' : (-1.0000003576278687, -0.9999996423721313, 1.0),  'color' : ( 0.5, 0.5,  0.0  ) },
    { 'co' : (-0.9999999403953552, 1.0, 1.0),                  'color' : ( 0.5, 0.25, 0.25 ) }
]

for d in coos2colors:
    co, color = d['co'], d['color']

    vIndices = find_loops_by_vert_co( o, co )
    for vi in vIndices:
        heat.data[ vi ].color = color

You can use the vertex color layer in Cycles by using the Input --> Attribute node and plugging it into an Emission shader's color input.

Heat

$\endgroup$
2
  • $\begingroup$ Thank you for the example code on Vertex Colors. However, I cannot create faces out of the input vertices because the data represents a 3-d point cloud, where each point represents a single sample of the physical values. The vertices are scattered throughout the 3-d volume. If I created a set of faces out of the outermost vertices, it would hide the remaining vertices on the volume's interior. I was specifically looking for a method to color the Point Density texture in the cube object that surrounds the cloud of vertices derived from the data. $\endgroup$
    – astrogeek
    Nov 2, 2015 at 15:01
  • $\begingroup$ Ah, shame. Hope someone here will figure out how generate, read and use a 3D texture for point clouds. $\endgroup$
    – TLousky
    Nov 2, 2015 at 15:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .