Start a new topic
Solved

can't batch process files using paramBlock

Hello ,I am doing a CDB project need to do assign night textures to the building models ,totally 500+ buildings. 

 

 if the day texture named' house.rgb' ,and each night texture named' house_N.rgb', with a '_N' behind.

 

I need to copy UV from layer 0,to layer 3, and assign layer 3 a night texture.

 

 for what reason,the night textures index numbers are not the same. the files are in attachment (sorry seems not allowed me to upload textures!)

 

I writing a script doing these things:

 

1.copy the existing UV ,from layer 0 to layer 3,

 

2.find the texture with '_N'.contained in its texture name, assign it to layer 3.

i can run it for a single file.

 

 

db = mgGetCurrentDb ()
paramBlock0 = mgGetParamBlock ("Select All")
mgExecute ("Select All",paramBlock0)

paramBlock = mgGetParamBlock ("Copy Layer")
#paramBlock2 = mgGetParamBlock ('Delete Layers')
mgParamSet (paramBlock, "Copy From", "Source Layer")
mgParamSet (paramBlock, "Copy Texture", MG_TRUE)
mgParamSet (paramBlock, "Copy UVs", MG_TRUE)
mgParamSet (paramBlock, "Follow Subnodes", MG_FALSE)
mgParamSet (paramBlock, "From Layer", 0)# Run first item
mgParamAppend (paramBlock, "To Layers", 2)# Run the second item
mgExecute ("Copy Layer", paramBlock)
#mgParamAppend (paramBlock2,"Layers To Delete", 3)
#mgExecute ("Delete Layers", paramBlock2)


num = mgGetTextureCount(db)
print num
tex_lst = []
for i in range(0,num):
	tex_lst.append(mgGetTextureName(db,i))
print tex_lst

def GetTexIndex(texName):
	t_index = mgGetTextureIndex(db,texName)
	return t_index

for oneTex in tex_lst:
	findNightTexture(oneTex,GetTexIndex(oneTex))

def findNightTexture(i,i_index):
	if '_N' in i:
		print 'yes'
		paramBlock = mgGetParamBlock ("Modify Attributes")
		mgParamSet (paramBlock, "Nested Record Code", 0)             
		mgParamSet (paramBlock, "Attribute Code", fltLayerTexture2)
		mgParamSet (paramBlock, "Integer Value", i_index)
		mgExecute ("Modify Attributes", paramBlock)
	else:
		print 'no'

 

 but when i try to batch process it using snippet Batch database processor, it can't work with 'paramBlock', not showing error, just doing nothing.

 

is because i am using creator 18, not a pro? or any other alternate way to do it?

 

 

 

many thanks if i can grab more info, cos i dig from this forum page by page find many things ,just beyond my knowledge.

 

 

 

Yingbo ( a WFH mom with 2 young kids!)

 

 

 


flt
flt

You are correct. You cannot use Creator Script in batch mode unless you have Creator Pro. When you call mgExecute, you are using "Creator Script". Creator Script invokes a Creator tool inside of OpenFlight Script. You are not allowed to use Creator Tools on databases that are not open on the desktop. When you use Batch database processor, you are opening OpenFlight files but they are not open on the Creator desktop.


There is an alternative solution. The OpenFlight API installation includes the OpenFlight Script code for the following Creator tools you are using:
Copy Layer (copytexturelayer.py)

Delete Layer (deletetexturelayer.py)


These samples are located at PRESAGIS_OPENFLIGHT_API/samples/scripts/creatortools


Simply replace the calls to mgExecute with the sample code for each of these tools.


Instead of using the Creator Tool "Modify Attributes" simply use mgSetAttList. mgSetAttList is much more versatile and simpler to use in the long run. For example:  

mgSetAttList(rec,  fltLayerTexture2, i_index)

The hardest part will be replacing "Select All". There is no such thing as "selection" outside of Creator (in a db that is not open on the Creator desktop, that is). You'll have to use mgWalk to visit all the polygons instead. In the pre-action walk function, check if the node is a polygon and if it is, do the Copy Layer and mgSetAttList on the rec as shown in this pseudo code.

def DoPolygon (db, parent, rec, userData):
   if (mgGetCode(rec) == fltPolygon):
      # Copy Texture Layer on rec
      # mgSetAttList on rec to set fltLayerTexture2
   return MG_TRUE

...

mgWalk (db, DoPolygon , None, None, 0)

  


1 person likes this

Hi Steve,

1) After u mentioned, I notice i am using creator 13 API, I install creator 18 API, found a lot new things,Thanks!

2) Copy layer, delete layer, totally dont understand ,sorry...

3) I managed to write a batch script using mgSetAttList, thanks for advice! 

  but the performance very slow. even crash for only process 1 file.

  the file with 6 lods, with highest lod only 1000tris. (As in the attachment)


Was it because i use mgwalk and  prcessOneDb(i follow some example)  in multiple files?

Or need to use ' def __inti__'   in Class?

my script as below

  

db = mgGetCurrentDb()
polygonList = list()
def getTexList(db):
	tex_lst = []
	num = mgGetTextureCount(db)
	for i in range(0,num):
		tex_lst.append(mgGetTextureName(db,i))
	return tex_lst

def GetTexIndex(texName):
	t_index = mgGetTextureIndex(db,texName)
	return t_index

def findNightTexture(tex_name,n_tex_index):
	if 'N.rgb' in tex_name or '_night' in tex_name:
		if polygonList:
			for polyRec in polygonList:
				outs = mgGetAttList(polyRec, fltLayerTexture4)
				print outs[0]
				print outs[1]
				print 'Orignial tex layer index is:-----',outs[2]				
				changeAttr = mgSetAttList(polyRec, fltLayerTexture4,n_tex_index)	
		print 'Yes found a Night Texture'
		print 'n_tex_index',n_tex_index
	else:
		print 'no'
		
def ProcessOneDb(db):
	texture_lst = getTexList(db)
	for oneTex in texture_lst:
		findNightTexture(oneTex,GetTexIndex(oneTex))
	return True			#yb: change from False to True,it works

def AfterWalk (db, parent, rec, userList):    
 	if mgIsCode (rec,fltPolygon):
		userList.append(rec)

	if mgIsCode (rec,fltVertex):		
		outs1 = mgGetAttList (rec, fltVU, fltVV)
		a=outs1[2]
		b=outs1[4]
		mgSetAttList (rec, fltLayerU4,a,fltLayerV4,b)
	return MG_TRUE 

outs = mgPromptDialogFile (None,

        MPFM_OPEN,

        MPFA_FLAGS, MPFF_FILEMUSTEXIST|MPFF_MULTISELECT,

        MPFA_PATTERN, "OpenFlight Files|*.flt",

        MPFA_TITLE, "Select OpenFlight Files to Process" )                                          

status = outs[0]

if (MSTAT_ISOK(status)):

    numFiles = outs[1]

    fileNames = outs[2:len(outs)]

    for fileName in fileNames:

			db = mgOpenDb (fileName)

			mgWalk (db, None,AfterWalk, polygonList, MWALK_VERTEX)
			#ProcessOneFile (db)
			modified = ProcessOneDb(db)
			if (modified):
				mgWriteDb(db)
			mgCloseDb (db)
    print "Finished"
else:
    print "User Canceled" 

 Many thanks!


Yingbo

image

2) Copy layer, delete layer, totally dont understand ,sorry...

Your orignal script was calling 
mgExecute ("Copy Layer", paramBlock)

When you do this mgExecute invokes the Copy Layer tool in Creator. mgExecute won't work in batch without Creator Pro. The OpenFlight API includes sample code which comprises the Copy Layer tool. I was trying to explain that if you need to invoke the Copy Layer tool, you can use the code from that sample instead.


3) I managed to write a batch script using mgSetAttList, thanks for advice!

but the performance very slow. even crash for only process 1 file. 

the file with 6 lods, with highest lod only 1000tris. (As in the attachment)


I don't see anything that is an obvious cause of the crash. 
You are calling "print" quite a lot. That can slow down the script substantially and if you called it enough, you could be overflowing the buffer used to collect the print statements. That might be the source of your crash. Try commenting out the prints. It will definitely run faster. Also if you keep getting a crash on a particular file, I suggest:


  1. open that file in Creator
  2. put the prints back in
  3. run the script on that file open in Creator
  4. the prints may tell you more about why its crashing.

Good luck


1 person likes this
Login to post a comment