Baking Namepair Creator

There were new versions of Substance Painter and Designer released just now, and their bakers now have a new “Match by Sub-Meshes Name” option.

Here is an add-on that will allow you to set up such a pair of names with one click:
https://gum.co/yvadI

https://dl.dropboxusercontent.com/s/v2pxdgjqek6gj2k/shot_150305_174613.png?dl=0

More info on the linked page.

1 Like

Nice, I’ll use it, thanks :wink:

The add-on now takes modifiers into consideration when determining which of the selected objects is the high-poly, and which is the low-poly.
Please redownload and reinstall. Also, report any problems.

i was doing some baking and needed and found this little gem! I got it before and forgot but was reminded when i tried to donate. Anyways I found a small nuance that might be easy for you to fix.


If it took care of that it would be perfect but it gave me issues in SP2 and SD5 without it.
http://i.imgur.com/0p8Jjm4.png
Anyways. This tool is great haha. When the time came this was just the thing I needed haha. Thanks again!

@masterxeon1001

Update:
Added a toggle to Baking Namepair Creator called “Also Rename Datablock”, on by default. This will also rename mesh data, since it seems it’s sometimes used instead of Object name.

Redownloadif you want it, and be sure to report any bugs.

Hope I understood your problem correctly : )

Thanks! Little stuff like this goes a long way.

Possible feature?

  • Selection of multiple _high’s to rename to a single _low eg:

Sword_high.hilt, Sword_high.Rivet1 Sword_high.Pummel -> Sword_low AKA
Sword_high.001,Sword_high.002,Sword_high.003 -> Sword_low

This is with the assumption that any name based baker would ignore characters after the suffix

any change to get this working with blender 2.81 and 2.82?

Did you tried this 2.8 version? https://github.com/PLyczkowski/Baking-Namepair-Creator

1 Like

This seems to work, the gumroad one wasn’t up to date thanks!

Doesn’t seem to work with Blender 3.0

For those interested in a fix for 3.0:

Here is the updated script

##### BEGIN GPL LICENSE BLOCK

This program is free software; you can redistribute it and/or

modify it under the terms of the GNU General Public License

as published by the Free Software Foundation; either version 2

of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.

You should have received a copy of the GNU General Public License

along with this program; if not, write to the Free Software Foundation,

Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

##### END GPL LICENSE BLOCK

Select the lowpoly and highpoly objects, and press the Create Baking Namepair button in the Relations tab. The suffixes _high and _low are added automatically based on the vertex count. The name of the low poly object is used as the new name’s base.

bl_info = {
‘name’: “Baking Namepair Creator”,
‘author’: “Pawel Lyczkowski”,
‘version’: (1, 0, 3),
‘blender’: (2, 80, 0),
‘location’: “View3D > Toolbar > Relations Tab”,
‘description’: “Set’s up a baking namepair.”,
‘warning’: “”,
‘wiki_url’: “”,
‘tracker_url’: “”,
‘category’: ‘Object’
}

import bpy, bmesh
from bpy.types import Operator
import string
import random

class BakingNamepair(bpy.types.Operator):
‘’‘Tooltip’‘’
bl_description = “BakingNamepair”
bl_idname = “object.baking_namepair”
bl_label = “BakingNamepair”
bl_options = { ‘REGISTER’, ‘UNDO’}

@classmethod
def poll(cls, context):
return True

def execute(self, context):

  selected = bpy.context.selected_objects
  depsgraph = bpy.context.evaluated_depsgraph_get()

  high_poly = None
  low_poly = None

  def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
  	return ''.join(random.choice(chars) for _ in range(size))

  if len(selected) == 2:

  	tempmesh1 = bmesh.new()
  	tempmesh1.from_object(selected[0], depsgraph, cage=False, face_normals=True)
  	vertex_count1 = len(tempmesh1.verts)

  	tempmesh2 = bmesh.new()
  	tempmesh2.from_object(selected[1], depsgraph, cage=False, face_normals=True)
  	vertex_count2 = len(tempmesh2.verts)

  	if vertex_count1 != vertex_count2:

  		#The meshes are not the same, set up which is which.

  		if vertex_count1 > vertex_count2:
  			high_poly = selected[0]
  			low_poly= selected[1]
  		else:
  			high_poly = selected[1]
  			low_poly= selected[0]

  		#Set up a random name, if option toggled.

  		if bpy.context.scene.r_generate_random_name:
  			low_poly.name = id_generator()
  			if bpy.context.scene.r_also_rename_datablock:
  				low_poly.data.name = low_poly.name

  		else:

  		#Check if lowpoly doesn't already end in "_low".

  			low_poly_name_len = len(low_poly.name)

  			if low_poly.name[low_poly_name_len - 1] == "w" and low_poly.name[low_poly_name_len - 2] == "o" and low_poly.name[low_poly_name_len - 3] == "l" and low_poly.name[low_poly_name_len - 4] == "_":

  				#It does, remove the "_low".

  				low_poly.name = low_poly.name[:low_poly_name_len - 4]

  		#Check if the names are not yet occupied.

  		high_poly_check = bpy.data.objects.get(low_poly.name + "_high")

  		low_poly_check = bpy.data.objects.get(low_poly.name + "_low")

  		if high_poly_check == None and low_poly_check == None:

  			#They are not, add suffixes.

  			high_poly.name = low_poly.name + "_high"

  			if bpy.context.scene.r_also_rename_datablock:
  				high_poly.data.name = high_poly.name

  			low_poly.name = low_poly.name + "_low"

  			if bpy.context.scene.r_also_rename_datablock:
  				low_poly.data.name = low_poly.name

  			#Hide, if option toggled.

  			if bpy.context.scene.r_hide_after_renaming:
  				selected[0].hide_viewport = True
  				selected[1].hide_viewport = True

  		elif low_poly_check == None and high_poly.name == low_poly.name + "_high":

  			#Only the highpoly is, so add suffix only to the lowpoly.

  			low_poly.name = low_poly.name + "_low"

  			if bpy.context.scene.r_also_rename_datablock:
  				low_poly.data.name = low_poly.name

  			#Hide, if option toggled.

  			if bpy.context.scene.r_hide_after_renaming:
  				selected[0].hide_viewport = True
  				selected[1].hide_viewport = True

  		else:


  			#Low poly name occupied.

  			self.report({'ERROR'}, "One of the names already occupied. Please rename the low poly object.")

  	else:

  		self.report({'ERROR'}, "Same vertex count.")

  	tempmesh1.free
  	tempmesh2.free

  else:

  	self.report({'ERROR'}, "Invalid number of objects selected.")

  return {'FINISHED'}

class OpToggleRenamed(bpy.types.Operator):
bl_idname = “object.toggle_viewport_renamed_objects”
bl_label = “Hide(/Unhide) all renamed High/Low poly objects”
bl_description = “Hide/Unhide all renamed High/Low poly objects in selected collections”
bl_options = {‘INTERNAL’, ‘UNDO’}

group : bpy.props.EnumProperty(items = {
(‘HIGH’, “High polys”, “High”),
(‘LOW’, “Low polys”, “Low”),
(‘ALL’, “All renamed”, “All”),
})
action : bpy.props.EnumProperty(items = {
(‘SHOW’, “Show”, “Show”),
(‘HIDE’, “Hide”, “Hide”)
})

def execute(self, context):
if self.group == ‘HIGH’:
suffixes = “_high”
elif self.group == ‘LOW’:
suffixes = “_low”
else:
suffixes = (“_low”, “_high”)

  for obj in bpy.data.objects:
  	if not obj.name.endswith(suffixes):
  		continue
  	if self.action == 'SHOW':
  		obj.hide_viewport = False
  	else:
  		obj.hide_viewport = True
  return {'FINISHED'}

class addButtonsInObjectMode(bpy.types.Panel):
bl_idname = “RELATIONS_PT_baking_namepair_objectmode”
bl_space_type = ‘VIEW_3D’
bl_region_type = ‘UI’

bl_label = “Baking Namepair”
bl_context = “objectmode”

def draw(self, context):
layout = self.layout

  # col = layout.column(align=True)

  layout.operator("object.baking_namepair", text="Create Baking Namepair")

  layout.prop(context.scene, "r_generate_random_name", text="Generate Random Name")
  layout.prop(context.scene, "r_hide_after_renaming", text="Hide After Renaming")
  layout.prop(context.scene, "r_also_rename_datablock", text="Also Rename Datablock")

  self._draw_toggle_viewport(context, 'HIGH', layout)
  self._draw_toggle_viewport(context, 'LOW', layout)
  self._draw_toggle_viewport(context, 'ALL', layout)

def _draw_toggle_viewport(self, context, group, layout):
row = layout.row()
row.label(text=group.lower())
op = row.operator(“object.toggle_viewport_renamed_objects”, text=“SHOW”)
op.group = group
op.action = ‘SHOW’
op = row.operator(“object.toggle_viewport_renamed_objects”, text=“HIDE”)
op.group = group
op.action = ‘HIDE’

def register():
bpy.types.Scene.r_generate_random_name = bpy.props.BoolProperty(default= False)
bpy.types.Scene.r_hide_after_renaming = bpy.props.BoolProperty(default= False)
bpy.types.Scene.r_also_rename_datablock = bpy.props.BoolProperty(default= True)

bpy.utils.register_class(BakingNamepair)
bpy.utils.register_class(OpToggleRenamed)
bpy.utils.register_class(addButtonsInObjectMode)

def unregister():
bpy.utils.unregister_class(BakingNamepair)
bpy.utils.unregister_class(OpToggleRenamed)
bpy.utils.unregister_class(addButtonsInObjectMode)

if name == “main”:
register()

can you post the updated .py file of it? Not sure what to do with the wall of code

2 Likes

Doesn’t work in my case, could you update .py?

1 Like

bumb anyone able to make this addon work blender 3.0? And share .py file?

Here’s a version for Blender 3.0 - https://raw.githubusercontent.com/PLyczkowski/Baking-Namepair-Creator/master/baking_namepair_creator_3_0.py

(The add-on’s panel is in the ‘Bake’ category now)

3 Likes

Thank you this addon is a MUST HAVE in game development it saves tons of time, lets keep it alive!

Awesome! Love you <3

Fix commited for py changes in 3.1.2. https://raw.githubusercontent.com/PLyczkowski/Baking-Namepair-Creator/master/baking_namepair_creator_3_0.py

3 Likes

Hello there sir, i got question about this awesome addon. Is it possible to add automatic detection pairs of low and high meshes? Someting like perform AABB bounding box intersection between meshes?