]> git.mxchange.org Git - flightgear.git/commitdiff
Blender 2.46 box packer script. Allows to unwrap objects individually, and
authormfranz <mfranz>
Sun, 2 Mar 2008 20:14:13 +0000 (20:14 +0000)
committermfranz <mfranz>
Sun, 2 Mar 2008 20:14:13 +0000 (20:14 +0000)
to pack them onto one square texture. Read instructions in the file.

utils/Modeller/uv_pack.py [new file with mode: 0644]

diff --git a/utils/Modeller/uv_pack.py b/utils/Modeller/uv_pack.py
new file mode 100644 (file)
index 0000000..64fd6c3
--- /dev/null
@@ -0,0 +1,143 @@
+#!BPY
+
+# """
+# Name: 'Pack selected objects on a square'
+# Blender: 245
+# Group: 'UV'
+# Tooltip: 'Pack UV maps of all selected objects onto an empty square texture'
+# """
+
+__author__ = "Melchior FRANZ < mfranz # aon : at >"
+__url__ = "http://members.aon.at/mfranz/flightgear/"
+__version__ = "0.1"
+__bpydoc__ = """\
+Script for mapping multiple objects onto one square texture.
+
+Usage:
+(1) create new square texture in the UV editor
+(2) map all objects individually, choosing the most appropriate technique
+(3) scale each of the mappings to the appropriate size, relative to the
+    other object mappings
+(4) select all objects and switch to edit mode (consider to use
+    Select->Linked->Material or similar methods)
+(5) start this script with UVs->Scripts->Pack objects on a square
+
+    [now the texture image will first be erased, then colored rectangles
+    will appear for each object]
+
+(6) rescale and/or remap objects that you aren't happy with (the
+    relative size of a mapping will be kept)
+
+    [continue with (5) until you like the result]
+
+(7) export UV layout to SVG (UVs->Scripts->Save UV Face Layout)
+"""
+
+MARGIN = 10 # px
+GAP = 10    # px
+
+
+import Blender, math, random
+
+
+class Abort(Exception):
+       def __init__(self, msg):
+               self.msg = msg
+
+
+def pack():
+       image = Blender.Image.GetCurrent()
+       if not image:
+               raise Abort('No texture image selected')
+
+       imagesize = image.getSize()
+       if imagesize[0] != imagesize[1]:
+               Blender.Draw.PupMenu("Warning%t|Image isn't a square!")
+       gap = (float(GAP) / imagesize[0], float(GAP) / imagesize[1])
+       margin = (float(MARGIN) / imagesize[0] - gap[0] * 0.5, float(MARGIN) / imagesize[1] - gap[1] * 0.5)
+
+
+       def drawrect(x0, y0, x1, y1, color = (255, 255, 255, 255)):
+               x0 *= imagesize[0]
+               y0 *= imagesize[1]
+               x1 *= imagesize[0]
+               y1 *= imagesize[1]
+               for u in range(int(x0 + 0.5), int(x1 - 0.5)):
+                       for v in range(int(y0 + 0.5), int(y1 - 0.5)):
+                               image.setPixelI(u, v, color)
+
+       boxes = []
+       meshes = {}
+
+       Blender.Window.DrawProgressBar(0.0, "packing")
+       for o in Blender.Scene.GetCurrent().objects.selected:
+               if o.type != "Mesh":
+                       continue
+
+               mesh = o.getData(mesh = 1)
+               if not mesh.faceUV:
+                       continue
+               if mesh.name in meshes:
+                       #print "dropping duplicate mesh", mesh.name, "of object", o.name
+                       continue
+               meshes[mesh.name] = True
+
+               print "\tobject '%s'" % o.name
+               xmin = ymin = 1000.0
+               xmax = ymax = -1000.0
+               for f in mesh.faces:
+                       for p in f.uv:
+                               xmin = min(xmin, p[0])
+                               xmax = max(xmax, p[0])
+                               ymin = min(ymin, p[1])
+                               ymax = max(ymax, p[1])
+
+               width = xmax - xmin
+               height = ymax - ymin
+               boxes.append([0, 0, width + gap[0], height + gap[1], xmin, ymin, mesh, o.name])
+
+       if not boxes:
+               raise Abort('No mesh objects selected')
+
+
+       boxsize = Blender.Geometry.BoxPack2D(boxes)
+       xscale = (1.0 - 2.0 * margin[0]) / max(boxsize[0], boxsize[1])
+       yscale = (1.0 - 2.0 * margin[1]) / max(boxsize[0], boxsize[1])
+
+       Blender.Window.DrawProgressBar(0.2, "Erasing texture")
+       drawrect(0, 0, 1, 1) # erase texture
+       for box in boxes:
+               xmin = ymin = 1000.0
+               xmax = ymax = -1000.0
+               for f in box[6].faces:
+                       for p in f.uv:
+                               p[0] = (p[0] - box[4] + box[0] + gap[0] * 0.5 + margin[0]) * xscale
+                               p[1] = (p[1] - box[5] + box[1] + gap[1] * 0.5 + margin[1]) * yscale
+
+                               xmin = min(xmin, p[0])
+                               xmax = max(xmax, p[0])
+                               ymin = min(ymin, p[1])
+                               ymax = max(ymax, p[1])
+
+               drawrect(xmin, ymin, xmax, ymax, (random.randint(128, 255), random.randint(128, 255),
+                               random.randint(128, 255), 255))
+       Blender.Window.DrawProgressBar(1.0, "Finished")
+
+
+
+editmode = Blender.Window.EditMode()
+if editmode:
+       Blender.Window.EditMode(0)
+
+try:
+       print "box packing ..."
+       pack()
+       print "done\n"
+except Abort, e:
+       Blender.Draw.PupMenu("Error%t|" + e.msg)
+       print "Error:", e.msg, " -> aborting ...\n"
+
+if editmode:
+       Blender.Window.EditMode(1)
+
+