UDIM generation / Rescale UDIM images broken in Blender 3.1
Blender 3.1 changed the way UDIM textures are treated.
When converting to UDIM, the first image is copied to all tiles.
When Rescaling UDIMS, nothing gets rescaled.
When changing the Resolution of UDIMS, even with older files, the resolution is unchanged.
The internal filename now has to have “<UDIM>” instead of the numbers, which probably causes the problems.
Comments (18)
-
-
reporter All my imported figures in 3.0 have UDIM textures. I work with Eevee, so I like to have as few shaders as possible. I usually just have one “dry skin” and one “wet skin” shader for the relevant parts, both using the same UDIM image files.
If you’re having troubles with UDIMs in Blender 3.0, I can make a video showing you my workflow. There are some cases in which I have to manually correct the images, but it’s rare. I did not have any problems with UVs, but you have to make sure that you use the correct uv set. Genesis 8.1 uv has a neck map on tile 1002, Genesis 8.0 uv has not. Use the right uv set for your map, usually the meshes have two sets.
Most of the time, changing textures to UDIM with Diffeomorphic in the older versions works like a charm. What’s especially great is that the resize option also works, so I can have a background character with very low-res textures to save memory on the GPU.
-
After looking into it further it seems the UVs are being destroyed somehow. I also did not “Merge UV’s“ . When I look through the available UV maps in the Object Data properties tab most fo the UV’s are just flat out gone. This is with manually setting the UDIM tiles too. I’m going to do some more experimenting. But I suspect they changed some stuff in 3.1 that is conflicting. AS well that I am an idiot. lol
A screenie just to show what I’m talking about. LIke I said I’m gonna experiment some more.
-
reporter This does not happen on my imports. What is your workflow up to here?
-
That was
Import > Save FIle > Save local Textures > Set UDIM Tiles > Merge Geografts (merge UV’s unchecked) > Set UDIM Tile (Set UDIMs to default for most of the model, Geograpft set to 1008 tile) > Make UDIM Materials
With everything checked because it should all be sorted to the proper tiles. Unless I understood the documentation wrong.Like I said I’m probably doing things I’m not supposed to.
-
reporter What is the first “Set UDIM Tile” for? I understand moving the Geograft to 1008, but the other UVs should already be UDIM?
-
The Face is 1001 and everything follows suit with how the default textures are number.
-
reporter I don’t use “Set UDIM Tile” at all. The UVs are already UDIM. After importing, I use “Make UDIM Materials” for all material zones after selecting the main figure, I don’t Merge the materials and I need no fixing. Most of the time, all textures are UDIM afterwards. I almost never touch the UVs. When working with Geografts, I use a separate UV node in the shader to make sure that the textures work correctly. I merge the materials myself in edit mode.
-
repo owner Set UDIM Tile is typically used to change the tile for geograft materials from 1001 to the torso tile 1002. See https://diffeomorphic.blogspot.com/p/finishing-section-version-16.html.
-
I was going to 1008 because parts of GP use the torso, and other parts use their own texture. Thats why I was doing that. For the most part just setting single principled takes care of what I need anyway. So it really is a non-issue. I was just experimenting. I’ve been kneck deep in Maya crap for school and needed to change it up.
-
I just now realized I last said exactly what you meant. Sorry, been a long week. lol
-
reporter I modified the materials.py so that rescaling and changing the resolution on UDIMs works again. I’m not at the current version, though.
I added a new parameter to getAllTextures and getTreeTextures, because we need different results for rescaling and changing the resolution.
In the actual Blender version, the file path must be xxx_<UDIM> instead of _1001 - that’s why the change is needed.
diff --git a/material.py b/material.py index 8099716..9352e42 100644 --- a/material.py +++ b/material.py @@ -1361,12 +1361,12 @@ class ChangeResolution(): self.filenames.append(fname) - def getAllTextures(self, context): + def getAllTextures(self, context, resolveUDIM): paths = {} for ob in getSelectedMeshes(context): for mat in ob.data.materials: if mat: - self.getTreeTextures(mat.node_tree, paths) + self.getTreeTextures(mat.node_tree, paths, resolveUDIM) for psys in ob.particle_systems: self.getSlotTextures(psys.settings, paths) return paths @@ -1378,7 +1378,7 @@ class ChangeResolution(): paths[mtex.texture.image.filepath] = True - def getTreeTextures(self, tree, paths): + def getTreeTextures(self, tree, paths, resolveUDIM): for node in tree.nodes.values(): if node.type == 'TEX_IMAGE' and node.image: img = node.image @@ -1387,12 +1387,17 @@ class ChangeResolution(): for file1 in os.listdir(folder): fname1,ext1 = os.path.splitext(file1) if fname1[:-4] == basename and ext1 == ext: - path = os.path.join(folder, "%s%s" % (fname1, ext1)) + if bpy.app.version >= (3, 1, 0) and resolveUDIM: + path = os.path.join(folder, "%s%s%s" % (fname1[:-4],'<UDIM>', ext1)) + else: + path = os.path.join(folder, "%s%s" % (fname1, ext1)) paths[path] = True + + else: paths[img.filepath] = True elif node.type == 'GROUP': - self.getTreeTextures(node.node_tree, paths) + self.getTreeTextures(node.node_tree, paths, resolveUDIM) def getTiledPath(self, filepath): @@ -1400,8 +1405,11 @@ class ChangeResolution(): path = bpy.path.reduce_dirs([path])[0] folder = os.path.dirname(path) fname,ext = os.path.splitext(bpy.path.basename(path)) - return folder, fname[:-4], ext - + if fname[-6:] == '<UDIM>': + return folder, fname[:-6], ext + else: + return folder, fname[:-4], ext + def replaceTextures(self, context): for ob in getSelectedMeshes(context): @@ -1441,6 +1449,11 @@ class ChangeResolution(): fname[-5] == "_" and fname[-4:].isdigit()): return "%s%s%s" % (fname[:-10], fname[-5:], ext) + elif (fname[-12:-8] == "-res" and + fname[-8].isdigit() and + fname[-7] == "_" and + fname[-6:] == '<UDIM>'): + return "%s%s%s" % (fname[:-12], fname[-7:], ext) else: return path @@ -1460,7 +1473,10 @@ class ChangeResolution(): newname,newpath = self.getNewPath(path) if img.source == 'TILED': - newname = newname[:-5] + if newname[-6:] == '<UDIM>': + newname = newname[:-7] + else: + newname = newname[:-5] if newpath == img.filepath: return img elif newpath in images.keys(): @@ -1485,7 +1501,7 @@ class ChangeResolution(): def loadNewImage(self, img, newpath): print('Replace "%s" with "%s"' % (img.filepath, newpath)) - if img.source == 'TILED': + if img.source == 'TILED' : folder,basename,ext = self.getTiledPath(newpath) newimg = None print("Tiles:") @@ -1500,9 +1516,13 @@ class ChangeResolution(): newimg.source = 'TILED' tile = img.tiles[0] tile.number = udim + if bpy.app.version >= (3, 1, 0): + path2,ext2 = os.path.splitext(newimg.filepath) + newimg.filepath = "%s%s%s" % (path2[:-4],'<UDIM>',ext2) + newimg.name=basename[:-1] else: newimg.tiles.new(tile_number = udim) - print(' "%s"' % file1) + print(' "%s"' % file1) return newimg else: return bpy.data.images.load(newpath) @@ -1514,6 +1534,8 @@ class ChangeResolution(): newbase = base elif len(base) > 5 and base[-5] == "_" and base[-4:].isdigit(): newbase = ("%s-res%d%s" % (base[:-5], self.steps, base[-5:])) + elif len(base) > 7 and base[-7:] == '_<UDIM>': + newbase = ("%s-res%d%s" % (base[:-7], self.steps, base[-7:])) else: newbase = ("%s-res%d" % (base, self.steps)) newname = bpy.path.basename(newbase) @@ -1542,7 +1564,7 @@ class DAZ_OT_ChangeResolution(DazOperator, ChangeResolution): def run(self, context): self.overwrite = False - paths = self.getAllTextures(context) + paths = self.getAllTextures(context,True) self.getFileNames(paths.keys()) self.replaceTextures(context) @@ -1570,7 +1592,7 @@ class DAZ_OT_ResizeTextures(DazOperator, ImageFile, MultiFile, ChangeResolution) def run(self, context): if self.resizeAll: - paths = self.getAllTextures(context) + paths = self.getAllTextures(context, False) else: paths = self.getMultiFiles(G.theImageExtensions) self.getFileNames(paths)
-
repo owner The patch has been incorporated in the latest commit. I noticed that the behaviour is different now. Before it was enough to do Resize Textures, but now this tool only creates the reduced image files. Change Resolution must be explicitly called to actually replace the textures in the materials. Well, it is not a big deal once you know about it, and it is arguably cleaner if each tool does one thing only.
-
reporter Yes, I should have mentioned this. At least it works.
“Make UDIM” is still broken, though. Maybe I find time for that at the weekend.
By the way, is there a way to update the changes to the source code without restarting Blender?
-
repo owner I use the Blender 2.7x keymap and hit F8 all the time to reload scripts. However, in the default Blender keymap no key appears to be associated with reloading scripts.
-
reporter Found time. This fixes UDIM creation:
diff --git a/udim.py b/udim.py index 09fb650..099374c 100644 --- a/udim.py +++ b/udim.py @@ -134,7 +134,9 @@ class DAZ_OT_UdimizeMaterials(DazPropsOperator, MaterialSelector): img.name = self.makeImageName(basename, atile, img) node.label = basename node.name = basename - + if bpy.app.version >= (3, 1, 0): + path2,ext2 = os.path.splitext(anode.image.filepath) + anode.image.filepath = "%s%s%s" % (path2[:-4],'<UDIM>',ext2) img = anode.image tile0 = img.tiles[0] for udim,mname in udims.items(): @@ -226,6 +228,8 @@ class DAZ_OT_UdimizeMaterials(DazPropsOperator, MaterialSelector): src = bpy.path.reduce_dirs([src])[0] folder = os.path.dirname(src) fname,ext = os.path.splitext(bpy.path.basename(src)) + if fname[-6:] == '<UDIM>': + src = os.path.join(folder, "%s_%d%s" % (fname[-6], 1001+udim, ext)) trg = os.path.join(folder, "%s_%d%s" % (basename, 1001+udim, ext)) if src != trg and not os.path.exists(trg): print("Copy %s\n => %s" % (src, trg))
-
repo owner Implemented in last commit. Thank you for figuring this out for me.
-
- changed status to resolved
- Log in to comment
I’m having huge issues with UDIM’s too, but I think it’s Blender, and not the addon. It’s doing really messy stuff like UDIM tiles are disappearing, and not recognizing uv’s at all.