User Tools

Site Tools


Sidebar

Dan's Wiki

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

Edit Sidebar

dan:pc:software:blender:uvdistribute

With Blender 2.63, UVDistribute no longer works. Had a couple of people provide helpful Traces.

UVDIstribute:

http://projects.blender.org/tracker/?func=detail&atid=467&aid=29981&group_id=153

Date: 2012-05-30 13:41 Sender: Evgen Zaitsev It sounds like a good script, but again with current version of the Blender 2.63 seems it doesn't work.

Traceback (most recent call last): File “C:\Users\Zexell\Dropbox\blender_scripts\addons_extern\uvDistribute.py”, line 68, in invoke return {self.execute(context)} File “C:\Users\Zexell\Dropbox\blender_scripts\addons_extern\uvDistribute.py”, line 74, in execute uvDistribute(self,context.active_object) File “C:\Users\Zexell\Dropbox\blender_scripts\addons_extern\uvDistribute.py”, line 110, in uvDistribute uvCount = len(uvTexture.data[i].uv) AttributeError: 'MeshTexturePoly' object has no attribute 'uv'

location:<unknown location>:-1

2/Jun/2012 21:58

In the script, the method starts with “context” - need to grab ahold of the same equivalent in Blender, in the Python console.

Need to be in Object Mode mesh = bpy.context.active_object.data uvTexture = mesh.uv_textures[0] uvDataCount = len(uvTexture.data) i = 0 uvCount = len(uvTexture.data[i].uv)

  1. - gives: Traceback (most recent call last): File “<blender_console>”, line 1, in <module> AttributeError: 'MeshTexturePoly' object has no attribute 'uv'

Having trouble finding where the uv values are located.

Clue: http://wiki.blender.org/index.php/Doc:2.6/Manual/Data_System/Data_System

http://www.blender.org/documentation/blender_python_api_2_59_0/contents.html

Mesh.uv_textures[0] which is a UVTextures UVTextures.active which is a MeshTexturePolyLayer MeshTexturePolyLayer.data, which is a MeshTexturePoly MeshTexturePoly.image which is a Image

found: bpy.types.MeshTextureFace.uv, .uv1, 2, 3, 4 sub of: MeshTextureFaceLayer.data sub of Mesh.tessface_uv_textures

On this page:

http://www.blender.org/documentation/blender_python_api_2_63_7/bpy.types.Mesh.html#bpy.types.Mesh.tessface_uv_textures

Has sample code:

import bpy

me = bpy.context.object.data uv_layer = me.uv_layers.active.data

for poly in me.polygons:

  print("Polygon index: %d, length: %d" % (poly.index, poly.loop_total))
  # range is used here to show how the polygons reference loops,
  # for convenience 'poly.loop_indices' can be used instead.
  for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
      print("    Vertex: %d" % me.loops[loop_index].vertex_index)
      print("    UV: %r" % uv_layer[loop_index].uv)

Try:

mesh = bpy.context.active_object.data uv_layer = mesh.uv_layers.active.data uv_layer[0].uv

  1. - gives Vector1)

mesh.uv_layers.active is bpy.types.MeshUVLoopLayer bpy.types.MeshUVLoopLayer.data is bpy_prop_collection of MeshUVLoop MeshUVLoop.uv is float array of 2 items in [-inf, inf], default (0.0, 0.0) MeshUVLoop.select is boolean, default False (not sure if we can set this)

2/Jun/2012 23:09

This page is important:

http://www.blender.org/documentation/blender_python_api_2_63_release/bpy.types.Mesh.html#bpy.types.Mesh.vertices

Shows the sample script above, also talks about vertices and UVs.

5/Jun/2012 20:16

Try looking at the “select” values

me = bpy.context.object.data uv_layer = me.uv_layers.active.data

# Paste the following into the console window

for poly in me.polygons:

  print("Polygon index: %d, length: %d" % (poly.index, poly.loop_total))
  # range is used here to show how the polygons reference loops,
  # for convenience 'poly.loop_indices' can be used instead.
  for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
      if uv_layer[loop_index].select:
          print("    Vertex: %d" % me.loops[loop_index].vertex_index)
          print("    UV: %r" % uv_layer[loop_index].uv)
          selectVal = ("False", "True")[uv_layer[loop_index].select]
          print("      select: %r" % selectVal)

— worked!

# Now let's try to make a change, maybe by adding .2 to the selected Y coordinates

me = bpy.context.object.data uv_layer = me.uv_layers.active.data for poly in me.polygons:

  print("Polygon index: %d, length: %d" % (poly.index, poly.loop_total))
  # range is used here to show how the polygons reference loops,
  # for convenience 'poly.loop_indices' can be used instead.
  for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
      if uv_layer[loop_index].select:
          print("    Vertex: %d" % me.loops[loop_index].vertex_index)
          print("    UV: %r" % uv_layer[loop_index].uv)
          selectVal = ("False", "True")[uv_layer[loop_index].select]
          print("      select: %r" % selectVal)
          myVec = uv_layer[loop_index].uv
          myVec[1] = myVec[1] + 0.2
          uv_layer[loop_index].uv = myVec
          print("        -- New Vector %r" % myVec)

— Hmm, this “uv_layer[loop_index].uv = myVec” made Blender blow up, maybe because the me= and uv_layer lines were missing

5/Jun/2012 20:52

# This worked:

me = bpy.context.object.data uv_layer = me.uv_layers.active.data selectedCount = 0 for poly in me.polygons:

  # print("Polygon index: %d, length: %d" % (poly.index, poly.loop_total))
  # range is used here to show how the polygons reference loops,
  # for convenience 'poly.loop_indices' can be used instead.
  for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
      if uv_layer[loop_index].select:
          selectedCount += 1
          print("    Vertex: %d" % me.loops[loop_index].vertex_index)
          print("    UV: %r" % uv_layer[loop_index].uv)
          selectVal = ("False", "True")[uv_layer[loop_index].select]
          print("      select: %r" % selectVal)
          myVec = uv_layer[loop_index].uv
          myVec[1] = myVec[1] + 0.05
          uv_layer[loop_index].uv = myVec
          print("        -- New Vector %r" % myVec)

print (“Selected UVs %f” % selectedCount)

Using this as a starting point, completed the work: 7/Jun/2012 22:47

In the process, discovered that there was a bug. If points had the same Y coordinate, the UVs would be placed in a incorrect position, because

In the following, added “if not y in yOrdDict” because otherwise, we will keep only the highest index, and the quantity of elements is thrown off, throwing off the new position calculation:

  for y in sortedY:
      if not y in yOrdDict:
          yOrdDict[y] = i
          i = i + 1

RIght now, everything is working except with my complex test case, if not all of the planes are selected in the 3D window, the UVs are not moved. However the code above moves them. Not sure why.

Getting this: 2012-06-09 19:56:41,582 INFO Distinct selected UV point count 724.000000 out of 2075.000000 selected and 485.000000 NOT selected

 then after processing:

2012-06-09 19:56:42,171 INFO UVs distributed 2075.000000 out of 2075.000000 selected and 485.000000 unselected

then I select everything in the 3D window, and I get this:

2012-06-09 19:57:37,618 INFO uv_layer: bpy.data.meshes['Plane.001'].uv_layers[“UVMap”].data 2012-06-09 19:57:37,732 INFO Distinct selected UV point count 64.000000 out of 127.000000 selected and 2433.000000 NOT selected

 then after processing:

2012-06-09 19:57:37,775 INFO UVs distributed 127.000000 out of 127.000000 selected and 2433.000000 unselected

9/Jun/2012 19:48

Hi Dan,

Thanks for providing me with your script. One question though, I am getting a error that says I need to select 3uv's. What does that mean. I am select the whole uv map.

Thanks,

Brian


Making some diagnostics:

me = bpy.context.object.data uv_layer = me.uv_layers.active.data selectedCount = 0 for poly in me.polygons:

  print("Polygon index: %d, length: %d" % (poly.index, poly.loop_total))

– …

  Polygon index: 637, length: 4
  Polygon index: 638, length: 4
  Polygon index: 639, length: 4

me = bpy.context.object.data uv_layer = me.uv_layers.active.data selectedCount = 0 unselectedCount = 0 selectedPoly = 0 unselectedPoly = 0 for poly in me.polygons:

  # print("Polygon index: %d, length: %d" % (poly.index, poly.loop_total))
  # range is used here to show how the polygons reference loops,
  # for convenience 'poly.loop_indices' can be used instead.
  if poly.select:
      selectedPoly += 1
  else:
      unselectedPoly += 1
  for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
      if uv_layer[loop_index].select:
          selectedCount += 1
      else:
          unselectedCount += 1

print (“Selected UVs %d, unselected UVs %d, selected poly %d, unselected poly %d” % (selectedCount, unselectedCount, selectedPoly, unselectedPoly))


Selected UVs 1929, unselected UVs 631, selected poly 159, unselected poly 481

but the selected UVs should be at most a 2-digit number in my example Maybe I can just use the selected polys

for obj in bpy.data.objects:

  print(obj.name)

p = bpy.data.objects[“Plane”]

type(p)

  1. - <class 'bpy_types.Mesh'>

me = bpy.context.object.data uv_layer = me.uv_layers.active.data selectedCount = 0 unselectedCount = 0 selectedPoly = 0 unselectedPoly = 0 for poly in me.polygons:

  # print("Polygon index: %d, length: %d" % (poly.index, poly.loop_total))
  # range is used here to show how the polygons reference loops,
  # for convenience 'poly.loop_indices' can be used instead.
  if poly.select:
      selectedPoly += 1
  else:
      unselectedPoly += 1
  if poly.select:
      for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
          if uv_layer[loop_index].select:
              selectedCount += 1
          else:
              unselectedCount += 1

print (“Selected UVs %d, unselected UVs %d, selected poly %d, unselected poly %d” % (selectedCount, unselectedCount, selectedPoly, unselectedPoly))


Fixed problem by putting “if poly.select:” ahead of the loop iteration. Apparently I was incorrectly looping through polygons that weren't selected. Also had to change the code that checks to see if anything is selected. I had copied something looking to see if the “edges” were selected, but this didn't seem to work any more.

15/Jun/2012 8:59

To make revisions and test them:

Make changes to UVDistribute.py in Eclipse CPP. In blender, find the “Addon” by using File→User Preferences→Addons→Mesh, click the triangle, and remove it. Then in the same window, use “Install Addon..” and select the UVDistribute.py file. (A shortcut to do this is to click “Documents”, then .., then pythonWorkspace/UVRighter/src/uvDistribute.py) Then remember to click the check box on the newly added Addon, so that it will show up in Blender.

15/Jun/2012 9:03


To test it

Create Bezier Curve, pull upwards away from X-axis, bend it into a shallow “hill”. Tip it at about 4 degrees so that subsequent wraps overlap. Set origin to 3D cursor, which should be at the global origin. Apply screw modifier, Axis: X, Screw 3, Angle 720, Steps 50, apply This makes a mesh shaped roughly like the handle wrap Go into “UV Editing” view, select all, do Mesh-Unwrap. Should see uneven unwrap displayed. Select a row of vertices (Alt click). Select UVs→Weld/Align→UVDistribute All of the vertices will become evenly distributed

31/Dec/2012 12:34

1)
0.8570523262023926, 0.4703197479248047
dan/pc/software/blender/uvdistribute.txt · Last modified: 2015/04/02 02:19 (external edit)