I have been working on building a script that takes some data and creates a pipe that applies a color according to it's particular stress value. I made up using fake line work in sketchup and created a video of the pipe showing what I am trying to achieve but I need to apply the proper csv values and make the colours a gradient.

I've been using a csv (abridged version in link)


I know how to get the data out, manipulate it and read from csv's- but what I'm stuck on is how Blender inputs the code to make a polyline- ( and eventually I was going to use the bevel with a circle to make a pipe:

bpy.ops.curve.primitive_bezier_circle_add(view_align=False, enter_editmode=False, location=(-2.50775, -0.363986, -0.330775), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False)) )

But I have not got that far yet...

I'm trying to work what the best way to show the pipe is. do I run it through the lon/lat coord found here:

Convert CSV Latitude longtitude to Blender coordinates

I also want to know how I can make my code create a 'KP' number in text per segment and color each KP point as a color from the csv where value from 0 to 100

Proposed color gradient below going from 0 green, 30 yellow, 60 orange, 100 red

if not too much to ask...

Also, create a mesh under the pipe from the csv the 'adj starboard depth' & adj port depth' and use the bottom 'type' column to render if it is sand, rock or clay on the mesh

Here is my code that I have cobbled together using several bits here and there:

import bpy, bmesh, csv, os, math
from bmesh.types import BMFace as BMFace
from mathutils import Vector, Matrix
from math import radians, sqrt ,tan ,cos , sin, atan ,pi

numline =1

# a method to make, scale and rotate text objects into place
def makeathing(coords, scale, lat, long,):
    rotation = (radians(lat - 270), pi, radians(long - 90))
    bpy.ops.object.text_add(location=(coords), rotation=(rotation))
    ob = bpy.context.object
    # set object properties here
    ob.data.body = "{:.1f}".format(float(scale))

    ob.rotation_mode = 'YXZ'
    ob.data.size = .5
    ob.data.extrude = 0.002

#method to make colors 
def colors (): 
    global redcolor
    redcolor = bpy.data.materials.new("red")
    redcolor.diffuse_color = (1.0, 0.0, 0.0)
    global greencolor
    greencolor = bpy.data.materials.new("green")
    greemcolor.diffuse_color = (0.0, 1.0, 0.0)
    global yellowcolor
    yellowcolor =bpy.data.materials.new("yellow")
    yellowcolor.diffuse_color = (1.0, 1.0, 0.0)
    global orangecolor
    orangecolor =bpy.data.materials.new("orange")
    orangecolor.diffuse_color = (1.0, 0.64705882, 0.0)

# a method to turn 3D polar coordinates into 3D cartesian coordinates
def latlonger(lat_deg, lon_deg):
    lat = float(lat_deg)
    lon = float(lon_deg)
    # see: http://www.mathworks.de/help/toolbox/aeroblks/llatoecefposition.html
    alt = 0.01
    rad = 2                                     # radius of sphere in BUs
    f  = 0.0                                    # flattening
    ls = atan((1 - f)**2 * tan(lat))  # lambda
    x = rad * cos(lat) * cos(lon) + alt * cos(lat) * cos(lon)
    y = rad * cos(lat) * sin(lon) + alt * cos(lat) * sin(lon)
    z = rad * sin(lat) + alt * sin(lat)
    return (x, y, z)

# taken from earthquakes code  NB: no code has executed yet, we're just setting up functions 4 l8r

blendPath = bpy.path.abspath("//") # path to the blendfile because my .csv is in the same directory- save the blender file before running
fileName = "survey.csv" #name of the spans survey data

path = blendPath + fileName 
file = open(path, newline='')
reader = csv.reader(file)

header = next(reader)
pipeloc = [] #create a dict for pipe location lattitude, longitude, bottom of pipe
for row in reader:
    #row =[KP, lat, lon, a, bp, b, z, typ, fat]
    KP = float(row[0]) #kp is the number of pipe length that is unique to that particular section of pipe
    lat= float(row[1]) #lattitude
    lon= float(row[2]) #longitude
    a= float(row[3]) #a is the Adj port depth
    bp= float(row[4]) #bp bottom of pipe - have not got a radius but want to add on in future
    b= float(row[5]) #b is the Adj Starboard depth
    z= float(row[6]) #z is the water depth
    typ= str(row[7]) #so this is the type of bottom sand, clay or rock still need to work on this 
    fat= float(row[8]) #create a float number for the fatigue value
    pipeloc.append([lat,lon,bp]) #pipe location x,y,z coords

So my question is where to from here?

  1. Should I run my long lat through the "def latlonger"? or how should I use my coords (- they dont really have to be in real life space...I'm simply just displaying the pipe.) What's the best way to do it?

  2. What is the best way to organise my data so I can make a polyline?

  3. How can I add the bevel command to my code? or should I use circles and join them?

  4. How can I add a gradient color to the pipe according to the 'KP' stress number(fat)

  5. Can you model the mesh for the ground applying a material to it at the same time?

Any help -I would be most grateful even if you could point me to some links... I've looked at the following:

Make a 3D tube with a Bézier curve?

How to create an oblique circle of points with Python?

python script that reads text file containing coordinates and creates a path/curve for object to follow

Thanks Sam


Your Answer

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

Browse other questions tagged or ask your own question.