Hi All,
I am looking for a way to join all objects in a group into a single mesh object in 2.49.
What is the best way to do this?
Hi All,
I am looking for a way to join all objects in a group into a single mesh object in 2.49.
What is the best way to do this?
bump - I am seeking to do this too…
I came up with this for a start. However, it does not capture the animation state at all, only meshes in their base form.
USAGE:
Create a bunch of mesh objects and add them to a group named “Group”
Run the script and you will have a single object with the meshes in the group all joined together.
NOTE: There is a 16 slot material limit using this approach. So if you join meshes whose total material count exceed 16 slots, some material loss will occur.
import Blender
from Blender import *
############################################################################
# Debug code goes first because all functions that follow may use it.
############################################################################
PREFIX = "--:"
CONSOLE_PREFIX = ""
DEBUG = True
def toConsole(passedItem):
global DEBUG, CONSOLE_PREFIX
if DEBUG == True:
print (CONSOLE_PREFIX + passedItem)
############################################################################
# Code for returning objects or meshes.
############################################################################
def fetchIfObject (passedObjectName):
# NOTE: Returns the object even if it is unlinked to the scene.
try:
tempObj = Blender.Object.Get(passedObjectName)
return tempObj
except:
return None
def createBlankObject(passedName,passedScene):
toConsole("createAPEObject [" + passedName + "].")
meshName = "me_" + passedName
ob = Object.New("Mesh",passedName)
tempMesh = Blender.Mesh.New()
tempMesh.name = meshName
ob.link(tempMesh)
passedScene.link(ob)
return ob
def returnMeshFromGroup (passedGroupName):
#Return a single mesh that is made up of all mesh based objects in a given group name.
result = None
localScene = Scene.GetCurrent()
tempName = "ape_OK_TO_DELETE"
obTempLinker = fetchIfObject(tempName)
if obTempLinker == None:
obTempLinker = createBlankObject(tempName,localScene)
toConsole("returnMeshFromGroup: Creating new linking object [" + tempName + "].")
else:
#It already exists, but it may be linked to an existing mesh, we want a blank mesh.
me = Blender.Mesh.New()
me.name = "me_blank_mesh"
me.update()
obTempLinker.link(me) #Without actually linking the mesh to the object, it never appears in the DG.
toConsole("returnMeshFromGroup: Linking in blank mesh named [" + me.name + "].")
#Retest.
if obTempLinker != None:
joinList = []
tempGroup= Group.Get(passedGroupName) # Get the group.
tempGroupCount = len(tempGroup.objects) # Get the count of the group.
if tempGroupCount > 0:
#Scan the group for mesh based objects.
for ob in list(tempGroup.objects): # Convert to a list before looping.
if ob.type == 'Mesh':
#This object can be joined to our local tempObject.
joinList.append(ob)
l = len(joinList)
if l > 0:
#Try to join all the meshes into one object.
obTempLinker.join(joinList)
result = Blender.Mesh.New()
result.getFromObject(obTempLinker) #Get the mesh with modifiers applied to the passed object.
else:
toConsole("returnMeshFromGroup: FAILED to detect any mesh based object in group [" + passedGroupName + "].")
else:
toConsole("returnMeshFromGroup: No objects in group [" + passedGroupName + "].")
else:
toConsole("returnMeshFromGroup: FAILED to create linking object [" + tempName + "].")
return result
############################################################################
# Program starts here.
############################################################################
me = returnMeshFromGroup("Group")
if me != None:
toConsole("Linked Mesh Name Is:" + me.name)
else:
toConsole("Failed!")
Ok,
Here is a solution that will return the current animated state of a group as a single mesh object.
USAGE: Same as above.
import Blender
from Blender import *
############################################################################
# Debug code goes first because all functions that follow may use it.
############################################################################
PREFIX = "--:"
CONSOLE_PREFIX = ""
DEBUG = True
def toConsole(passedItem):
global DEBUG, CONSOLE_PREFIX
if DEBUG == True:
print (CONSOLE_PREFIX + passedItem)
############################################################################
# Code for managing various internal names and string schema.
############################################################################
def returnShortName(passedName):
#Return a short portion of the name of the parent.
try:
result = passedName[(len(passedName)-10):] #Get the last 10 characters of the passed name.
except:
result = None
return result
def returnMiniName(passedName):
#Return a short portion of the name of the parent.
try:
result = passedName[(len(passedName)-4):] #Get the last 4 characters of the passed name.
except:
result = None
return result
def returnNameForNumber(passedFrame):
frame_number = str(passedFrame)
l = len(frame_number)
post_fix = frame_number
if l == 1:
post_fix = "000" + frame_number
if l == 2:
post_fix = "00" + frame_number
if l == 3:
post_fix = "0" + frame_number
return post_fix
def returnMeshFrameName (passedName,passedNumber):
try:
result = "me_" + returnBoundName(passedName) + "_f"+ returnNameForNumber(passedNumber)
except:
result = "me_" + str(passedNumber)
return result
############################################################################
# Code for returning objects or meshes.
############################################################################
def fetchIfObject (passedObjectName):
# NOTE: Returns the object even if it is unlinked to the scene.
try:
tempObj = Blender.Object.Get(passedObjectName)
return tempObj
except:
return None
def createBlankObject(passedName,passedScene):
toConsole("createAPEObject [" + passedName + "].")
meshName = "me_" + passedName
ob = Object.New("Mesh",passedName)
tempMesh = Blender.Mesh.New()
tempMesh.name = meshName
ob.link(tempMesh)
passedScene.link(ob)
return ob
def returnMeshApplied(passedObject,passedFrame):
if passedObject != None:
#Create a new one.
name = returnMeshFrameName(passedObject.name,passedFrame)
me = Blender.Mesh.New()
me.getFromObject(passedObject) #Get the mesh with modifiers applied to the passed object.
me.transform(passedObject.matrix) #Apply the current matrix for this frame to the mesh.
me.name = name
me.update()
return me
else:
toConsole("returnMeshApplied: Recieved none object.")
return None
def returnMeshFromGroup (passedGroupName):
#Return a single mesh that is made up of all mesh based objects in a given group name.
result = None
localScene = Scene.GetCurrent()
this_frame = Blender.Get('curframe')
tempName = "ape_OK_TO_DELETE"
obTempLinker = fetchIfObject(tempName)
if obTempLinker == None:
obTempLinker = createBlankObject(tempName,localScene)
toConsole("returnMeshFromGroup: Creating new linking object [" + tempName + "].")
else:
#It already exists, but it may be linked to an existing mesh, we want a blank mesh.
me = Blender.Mesh.New()
me.name = "me_blank_mesh"
me.update()
obTempLinker.link(me) #Without actually linking the mesh to the object, it never appears in the DG.
toConsole("returnMeshFromGroup: Linking in blank mesh named [" + me.name + "].")
#Retest.
if obTempLinker != None:
joinList = []
unLinkList = []
tempGroup= Group.Get(passedGroupName) # Get the group.
tempGroupCount = len(tempGroup.objects) # Get the count of the group.
if tempGroupCount > 0:
#Scan the group for mesh based objects.
c = 1
for ob in list(tempGroup.objects): # Convert to a list before looping.
if ob.type == 'Mesh':
#This object can be joined to our local tempObject.
me = returnMeshApplied(ob,this_frame) #Get the current state of the mesh, on this frame, with modifiers and animation applied.
if me != None:
#Create a new object with name based upon groupname, object name and index position in group.
tempName = "ape_" + returnShortName(passedGroupName) + "_" + returnMiniName(ob.name) + "_i" +returnNameForNumber(c)
obLoopTemp = createBlankObject(tempName,localScene)
obLoopTemp.link(me)
joinList.append(obLoopTemp)
unLinkList.append(obLoopTemp)
else:
#Static object.
joinList.append(ob)
c = c + 1
l = len(joinList)
if l > 0:
#Try to join all the meshes into one object.
obTempLinker.join(joinList)
me = Blender.Mesh.New()
me.getFromObject(obTempLinker) #Get the mesh with modifiers applied to the passed object.
#If there are any object in the unlink list, lets unlink them from the scene.
for ob in unLinkList:
localScene.objects.unlink(ob)
return me
else:
toConsole("returnMeshFromGroup: FAILED to detect any mesh based object in group [" + passedGroupName + "].")
else:
toConsole("returnMeshFromGroup: No objects in group [" + passedGroupName + "].")
else:
toConsole("returnMeshFromGroup: FAILED to create linking object [" + tempName + "].")
return result
############################################################################
# Program starts here.
############################################################################
me = returnMeshFromGroup("Group")
if me != None:
toConsole("Linked Mesh Name Is:" + me.name)
else:
toConsole("Failed!")