Start a new topic

Script to Copy Geometry from Db to Db

I have several flight files that I need to reconfigure. I have a template db with several empty nodes with comments. Is it possible to copy the template db geometry into these files via script? 


1 person has this question

Yes this is fairly easy. The background information that is important to understand is that nodes are tied to their db. They cannot be moved from one db to another. You cannot for instance detach and attach to a different db. The proper way to get nodes from one db into another is using the function mgDuplicateToDb()

image


This functions just like mgDuplicate() but the created copy will be in the correct db. Just like when using mgDuplicate(), you still need to attach the newly created node under the desired parent node.

Do you happen to have a sample of this function, along with the attach step? 

I created an example:


 

# make sure to use forward slash below, or use an escaped back slash '\\'
destPath = 'd:/Scripts/TestFiles/mgDuplicateToDb/destination.flt'
sourcePath = 'd:/Scripts/TestFiles/mgDuplicateToDb/source.flt'


destDb = mgOpenDb (destPath)
mgSetCurrentDb(destDb)

#find the node to attach to in the dest Db
targetRec = mgGetRecByName(destDb, 'gunMount')


sourceDb = mgOpenDb(sourcePath)

#find the node to duplicate in the source Db
gunRec = mgGetRecByName(sourceDb, 'gun')

duplicateGunRec = mgDuplicateToDb(gunRec, destDb)

mgAttach(targetRec, duplicateGunRec)

mgWriteDb(destDb)
mgCloseDb(destDb)
mgCloseDb(sourceDb)

 

Caution:

Note: This function (mgDuplicateToDb) does not resolve palette indices between the source and destination databases.

I have a similar project in mind.  Question - if the destination is a copy (duplicate) of the source, how is it there would be palette indices problems between them?

mgDuplicateToDb only duplicates the node, and it duplicates it exacty as it found it. All the palette indicies remain the same values. So if db1 has brick at index 1, and db2 has grass at index 1 duplicating a node with a brick texture to db2 will turn the texture to grass. The way to fix this is to resolve attributes between the dbs, so the destination db has all the textures of both files and the source db has the same indices for its textures as the destination db. This is a complicated procedure, so we have a Creator tool to do this for you. We also allow this tool to be called via Creator Script. (only scripts run inside of Creator or Creator Console can call Creator Scripts)

1 person likes this

Hi Chris
I ran in your above described texture issue.
What function allows me to do the attribute resolving trick? Is there for sure no way to do this without the Creator/ Creator Console?

The Attribute Resolver tool in creator can be executed via script. Below is an example of a script that finds all xrefs in the scene and runs attribute resolver on them. Your script would have to do something similar, but attribute resolve the new db.


Or a simpler way would be to just loop over the texture palette from the source db and add each texture found to the new db at the correct index.


Attribute Resolver Example: (needs to be updated to work for your situation)

 

class userData:
   pass
	
def FindXrefNodes (db, parent, rec, userData):	
	if mgGetCode (rec) == fltXref:		
		return MG_TRUE
	else:
		return MG_FALSE

db = mgGetCurrentDb ()
mgExecute ("Reread Externals", None)

paramBlock = mgGetParamBlock ("Attribute Resolver")
mgParamSetBool (paramBlock, "Backup Subordinate Files", MG_FALSE)
mgParamSetBool (paramBlock, "Force Texture Mapping Palette into Subordinate Files", MG_FALSE)
mgParamSetBool (paramBlock, "Force Texture Palette into Subordinate Files", MG_FALSE)
mgParamSetBool (paramBlock, "Load Used Subordinate Files", MG_FALSE)
mgParamSetBool (paramBlock, "Remove Unused Texture Mappings", MG_FALSE)
mgParamSetBool (paramBlock, "Remove Unused Textures", MG_FALSE)
mgParamSetBool (paramBlock, "Resolve Color Palette", MG_TRUE)
mgParamSetBool (paramBlock, "Resolve Material Palette", MG_TRUE)
mgParamSetBool (paramBlock, "Resolve Texture Mapping Palette", MG_TRUE)
mgParamSetBool (paramBlock, "Resolve Texture Palette", MG_TRUE)
# mgParamSetString (paramBlock, "Subordinate Files", "")

XrefList = mgFind (db, FindXrefNodes, None, MWALK_MASTERALL)
print XrefList

numLoops = mgGetRecListCount (XrefList)
xrefRec,matrix = mgGetNextRecInList (XrefList)

str = mgGetName (xrefRec)
print "relPath", str
ok, fixedPath = mgGetAbsoluteFilename (db, str)
mgSetName(xrefRec, fixedPath)

print (ok, "fixedOne: ", fixedPath)
if ok:
	mgParamSetString (paramBlock, "Subordinate Files", fixedPath)

for i in range(1, numLoops):
	xrefRec, matrix = mgGetNextRecInList (XrefList)
	str = mgGetName(xrefRec)
	ok, fixedPath = mgGetAbsoluteFilename (db, str)
	mgSetName(xrefRec, fixedPath)
	print (ok, "fixedOne: ", fixedPath)
	if ok:
		mgParamAppendString (paramBlock, "Subordinate Files", fixedPath)

mgExecute ("Attribute Resolver", paramBlock)

mgExecute ("Reread Externals", None)

mgExecute ("Convert Externals", None)

mgExecute ("Select All", None)

paramBlock = mgGetParamBlock ("Make Geometry")
mgParamSetBool (paramBlock, "Preserve DOFs", MG_TRUE)
mgExecute ("Make Geometry", paramBlock)

 

As for doing this without the creator / creator console, the attribute resolution would have to be done manually.


Basically you need to make sure the destination db has all the in use textures/materials/color.... that the source db has and that all of these are at the same index.

This can be done by analyzing the geometry to see what is used for both files, adding missing elements, then changing the palette locations of the items that are in use so they match.


Alternate way would be to change the newly created geometry's indicies so they point to the correct location. This could be simpler for smaller duplicates as you just need to make sure the texture / palette items exist in the new db, find their index and update the geometry.

Login to post a comment