User Tools

Site Tools


Sidebar

Dan's Wiki

DokuWiki Instructions (local) DokuWiki Manual
Site Checker (Orphans Wanted)

Edit Sidebar

blender:pythonorg

This is an old revision of the document!


Python Notes, Used within Blender

To view “Run Script” output, display the console window, descrbied here:

http://wiki.blender.org/index.php/Doc:2.5/Manual/Interface/Window_system/Console_window

When Blender is started on a Windows operating system, the Console Window is first created as a separate window on the desktop. Assuming that the right start-up conditions are met, the main Blender window should also appear and the Console Window will then be toggled off. This is unlike the 2.4x series where the Console Window would remain visible while the main Blender window was open. To display the console in current versions of Blender, go to Help » Toggle System Console.

24/Sep/2011 18:01 http://www.blender.org/documentation/blender_python_api_2_59_0/info_overview.html

bpy.data

  Access to blenders internal data
  Type :	bpy.types.BlendData

Ran this in the console:

>>> bpy.context.selected_objects[0].data.values
<built-in method values of Mesh object at 0x000000000A09C288>

It's possible that the vertexes aren't available. Saw note regarding built-in mesh object.

http://wiki.blender.org/index.php/Doc:2.5/Manual/Introduction/Installing_Blender/DirectoryLayout 24/Sep/2011 21:05

User Scripts Path

The user preferences script path provides a way to set your own directory which is used for scripts as well as the user scripts path. Be sure to create subfolders within this directory which match the structure of blenders scripts directory, startup/, addons/, modules/ etc. because copying scripts directly into this folder will not load them on startup or as addons.

http://blenderartists.org/forum/showthread.php?226024-2.58-Mesh-UVs&highlight=access+to+UV+coordinates

bpy.context.active_object.data.uv_textures[0].data[0] (can't be in edit mode)

….I run a count through the number of vertices in the mesh. The current count number is passed to a routine as the index number of a vertex. The routine iterates through the faces of the mesh. When the vertex number is found in one of the face vertices, the appropriate uv is retrieved, and the routine exits, returning the uv. …

uvs = {}

for f, uv in zip(mesh.faces, mesh.uv_textures.active.data):
	for j, v in enumerate(f.vertices):
		uvs[v] = uv.uv_raw[2*j:2*j + 2]

http://www.celsiusgs.com/blog/?p=102

>>> len(bpy.data.meshes["Mesh.001"].vertices)
1053

bpy.data.meshes["Mesh.001"]
doesn't have .uv
Has "NUT" exporter which also exports UVs, albeit in his own format:
from: http://www.devmaster.net/forums/showthread.php?t=17915
 
Run in text window, click "Run Script". Make sure the mesh is not in edit mode:
 
import bpy
file = open('/tmp/temp.txt', 'w')
mesh = bpy.data.meshes["Mesh.001"]
for uvTexture in mesh.uv_textures:
   file.write("\t\t\t<uv count=\"%d\">" % len(uvTexture.data))
   uvDataCount = len(uvTexture.data)
   for i in range(uvDataCount):
      # UV per face index, not per vertex
      if i > 0:
         file.write(' ')
         uvCount = len(uvTexture.data[i].uv)
         for j in range(uvCount):
                 if j > 0:
                    file.write(" ")
                    file.write("%f %f" % (uvTexture.data[i].uv[j][0], uvTexture.data[i].uv[j][1]))
                    file.write("</uv>\n")
 
file.close()

To run example, do a File→Export→NUT format, and look at the result.

27/Sep/2011 23:24


Make a script to change one UV coordinate:

import bpy
mesh = bpy.data.meshes["Mesh.001"]

mesh.uv_textures[0].data[0].uv[0][0] = mesh.uv_textures[0].data[0].uv[0][0] - .1
.. moved x coordinate of first UV a little to the left.

This works.

Need to make an algorithm to straighten the curve.

Some thoughts.

  • form a virtual line that goes through points. Straighten those points. Mark them moved, repeat.
  • Hard to determine the corner points, to do the line above.
  • The UVs will be evenly spaced that are together for straightening. May be able to use this fact

to determine those points that are together for straightening.

  • May need to investigate to see if there is a line between UVs that can be used to get neighbor.

import bpy
file = open('/tmp/temp.txt', 'w')
mesh = bpy.data.meshes["Mesh.001"]
# for one UV "island," there should only be one mesh.uv_textures
for uvTexture in mesh.uv_textures:
   file.write("\t\t\t<uv count=\"%d\">" % len(uvTexture.data))
   uvDataCount = len(uvTexture.data)
   for i in range(uvDataCount):
      # UV per face index, not per vertex
      if i > 0:
         file.write(' ')
         uvCount = len(uvTexture.data[i].uv)
         for j in range(uvCount):
                 if j > 0:
                    file.write(" ")
                    file.write("%f %f" % (uvTexture.data[i].uv[j][0], uvTexture.data[i].uv[j][1]))
                    file.write("</uv>\n")
 
file.close()
# For spiralWrapTestBA.blend, following data shows up
import bpy
mesh = bpy.data.meshes["Mesh.001"]
len(mesh.uv_textures)
# prints 1
len(mesh.uv_textures[0].data)
# prints 960
# now, lets check to see 
import bpy
mesh = bpy.data.meshes["Mesh.001"]
print ("Mess quantity", len(mesh.uv_textures))
print ("data quantity in Mesh 0:", len(mesh.uv_textures[0].data))
for i in range(20):
  if i > 0:
     print ("uvCount in data", i, len(mesh.uv_textures[0].data[i].uv))
# each shows 4

Lets look more closely at the array content:

import bpy
file = open('/tmp/temp.txt', 'w')
mesh = bpy.data.meshes["Mesh.001"]
# for one UV "island," there should only be one mesh.uv_textures
for uvTexture in mesh.uv_textures:
   file.write("\t\t\t<uv count=\"%d\">" % len(uvTexture.data))
   uvDataCount = len(uvTexture.data)
   file.write("uvDataCount: %d\n" % uvDataCount);
   for i in range(uvDataCount):
      # UV per face index, not per vertex
      if i >= 0:
        file.write("  for uvDataCount (i value) %d\n" % i);
        uvCount = len(uvTexture.data[i].uv)
        for j in range(uvCount):
            if j >= 0:
                file.write("  for uvCount (j value) %d\n" % j);
                file.write(" ")
                file.write("%f %f" % (uvTexture.data[i].uv[j][0], uvTexture.data[i].uv[j][1]))
                file.write("</uv>\n")
 
file.close()
 
def 

It looks like a lot of the data is repeated. Need to store muliple occurrences so that when the UVs are moved, we move all of them together.

absorb uvs into a usable datastructure: (works)

import bpy
file = open('/tmp/temp.txt', 'w')
mesh = bpy.data.meshes["Mesh.001"]
# Creating a blank dictionary
d = {}
# for one UV "island," there should only be one mesh.uv_textures
for uvTexture in mesh.uv_textures:
   uvDataCount = len(uvTexture.data)
   for i in range(uvDataCount):
      # UV per face index, not per vertex
      if i >= 0:
        uvCount = len(uvTexture.data[i].uv)
        for j in range(uvCount):
            if j >= 0:
                myU = uvTexture.data[i].uv[j][0]
                myV = uvTexture.data[i].uv[j][1]
                tuv = myU, myV
                if not tuv in d:
                        # create new UV record
                        d[tuv] = []
                # add blender indices that had those UV values
                tcoord = i, j
                d[tuv].append(tcoord)
 
# Now, write to file to see if it worked
for k in d.keys():
 
   sf = ''
   for t3 in d[k]:
        sf += "(%i, %i) " % (t3[0], t3[1])
 
   file.write(" " + ("%f, %f" % (k[0], k[1])) + ": " + sf + "\n")
file.close()

To see if this will work, read in UVs, multiply each by 1.2, and see if it works

import bpy
mesh = bpy.data.meshes["Mesh.001"]
# Creating a blank dictionary
d = {}
# for one UV "island," there should only be one mesh.uv_textures
for uvTexture in mesh.uv_textures:
   uvDataCount = len(uvTexture.data)
   for i in range(uvDataCount):
      # UV per face index, not per vertex
      if i >= 0:
        uvCount = len(uvTexture.data[i].uv)
        for j in range(uvCount):
            if j >= 0:
                myU = uvTexture.data[i].uv[j][0]
                myV = uvTexture.data[i].uv[j][1]
                tuv = myU, myV
                if not tuv in d:
                        # create new UV record
                        d[tuv] = []
                # add blender indices that had those UV values
                tcoord = i, j
                d[tuv].append(tcoord)
 
 
# at this point, each record in d looks like this:
# (2.5, 3.2), [(1, 5), (2, 9), (13, 19)]
# where there is a UV coordinate tuple as a key, and an
# array of tuples, representing the i, j locations in the array above
# where these tuplies are found
 
# Now, write back to initial array locations
for k in d.keys():
   for t3 in d[k]:
      uvTexture.data[t3[0]].uv[t3[1]][0] = k[0] * 1.2
      uvTexture.data[t3[0]].uv[t3[1]][1] = k[1] * 1.2
 
# Worked! 3/Oct/2011 21:07

# Moving on, let's do some calculations

def slope(tup1, tup2):
  if (abs(tup1[0] - tup2[0]) < .001):
     return 1000
  return ((tup1[1] - tup2[1])/(tup1[0] - tup2[0]))




import bpy
mesh = bpy.data.meshes["Mesh.001"]
# Creating a blank dictionary
d = {}
# for one UV "island," there should only be one mesh.uv_textures
for uvTexture in mesh.uv_textures:
   uvDataCount = len(uvTexture.data)
   for i in range(uvDataCount):
      # UV per face index, not per vertex
      if i >= 0:
        uvCount = len(uvTexture.data[i].uv)
        for j in range(uvCount):
            if j >= 0:
                myU = uvTexture.data[i].uv[j][0]
                myV = uvTexture.data[i].uv[j][1]
                tuv = myU, myV
                if not tuv in d:
                        # create new UV record
                        d[tuv] = []
                # add blender indices that had those UV values
                tcoord = i, j
                d[tuv].append(tcoord)


# at this point, each record in d looks like this:
# (2.5, 3.2), [(1, 5), (2, 9), (13, 19)]
# where there is a UV coordinate tuple as a key, and an
# array of tuples, representing the i, j locations in the array above
# where these tuplies are found

# Now, write back to initial array locations
#for k in d.keys():
#   for t3 in d[k]:
#      uvTexture.data[t3[0]].uv[t3[1]][0] = k[0] * 1.2
#      uvTexture.data[t3[0]].uv[t3[1]][1] = k[1] * 1.2

# Determine center point for x and y directions

minx = 0
maxx = 0
miny = 0
maxy = 0

for k in d.keys():
   if minx == 0 or k[0] < minx:
        minx = k[0]
   if maxx == 0 or k[0] > maxx:
        maxx = k[0]
   if miny == 0 or k[1] < miny:
        miny = k[1]
   if maxy == 0 or k[1] > maxy:
        maxy = k[1]

centerx = (minx + maxx) / 2
centery = (miny + maxy) / 2

print ("minx: ", minx)
print ("maxx: ", maxx)
print ("miny: ", miny)
print ("maxy: ", maxy)
print ("centerx: ", centerx)
print ("centery: ", centery)

# this will hold the new locations
newloc = {}

# later, loop starting here
# find the upper-left most point that isn't in newloc

# start off with lower-right
upperleftUnmarked = maxx, miny
for k in d.keys():
   if k in newloc:
       continue
   if k == upperleftUnmarked:
       continue
   distSq = (k[1] - maxy) * (k[1] - maxy) + (k[0] - minx) * (k[0] - minx)
   if distSq < (upperleftUnmarked[1] - maxy) * (upperleftUnmarked[1] - maxy) + (upperleftUnmarked[0] - minx) * (upperleftUnmarked[0] - minx):
      upperleftUnmarked = k
# upperleftUnmarked now has upperleft most non-newloc marked point

# Find the highest-sloped point from here
highslope = 0, 0
for k in d.keys():
   if k in newloc:
       continue
   if k == upperleftUnmarked:
       continue
   if (highslope[0] == 0 and highslope[1] == 0) \
or slope(k, upperleftUnmarked) > slope(highslope, upperleftUnmarked) \
or (slope(k, upperleftUnmarked) == slope(highslope, upperleftUnmarked) \
and (upperleftUnmarked[1] - k[1]) > (upperleftUnmarked[1] - highslope[1])):
         highslope = k

print ('upperleftUnmarked: ', upperleftUnmarked)
print ('highslope: ', highslope)
blender/pythonorg.1446675864.txt.gz · Last modified: 2015/11/04 22:24 by dwheele