Start a new topic

Python scripting: Get all texture layers?

Original Post by: shawnallen Mon Jul 18 21:02:33 2016


Looking at egtexture1 and eggetattr2, these both access texture layers individually. My goal is to check all polys for texture, and if the poly is textured, check what layers are in use. I want to do something with polys that are using more than fltLayerTexture1.


Is there any shortcut to determine/access all texture layers in use for a given polygon, other than checking each one? To avoid this:

if (rec, fltLayerTexture1):

PRINT_FIELD (rec, fltLayerTexture1)

elif (rec, fltLayerTexture2):

PRINT_FIELD (rec, fltLayerTexture2)

elif (rec, fltLayerTexture3):

PRINT_FIELD (rec, fltLayerTexture3)

elif (rec, fltLayerTexture4):

PRINT_FIELD (rec, fltLayerTexture4)

elif (rec, fltLayerTexture5):

PRINT_FIELD (rec, fltLayerTexture5)

elif (rec, fltLayerTexture6):

PRINT_FIELD (rec, fltLayerTexture6)

elif (rec, fltLayerTexture7):

PRINT_FIELD (rec, fltLayerTexture7)


This snippet currently lives under the PrintMTexture function in (a copy of)

eggetattr2 and it apparently breaks the mgWalk visiting all polygons, since

I only get one poly (code in attached zip).


Thx


Original Post by: SteveThompson Mon Jul 18 21:46:14 2016


Is there any shortcut to determine/access all texture layers in use for a given polygon, other than checking each one?


The following is the most simple way to check if a polygon has texture applied to the different layers. i.e. There is no shortcut that can make this any easier. You have to ask the polygon about each layer separately and check the results layer by layer.

def CheckPolygonForTexture (db, parent, rec, i):

code = mgGetCode(rec)

if (code == fltPolygon or code == fltMesh):

numAttr, \

code0, index0, \

code1, index1, \

code2, index2, \

code3, index3, \

code4, index4, \

code5, index5, \

code6, index6, \

code7, index7 = \

mgGetAttList(rec, \

fltPolyTexture, \

fltLayerTexture1, \

fltLayerTexture2, \

fltLayerTexture3, \

fltLayerTexture4, \

fltLayerTexture5, \

fltLayerTexture6, \

fltLayerTexture7)

if (numAttr is 8):

print mgGetName(rec),":"

if (index0 > -1):

print " Layer 0 is defined"

if (index1 > -1):

print " Layer 1 is defined"

if (index2 > -1):

print " Layer 2 is defined"

if (index3 > -1):

print " Layer 3 is defined"

if (index4 > -1):

print " Layer 4 is defined"

if (index5 > -1):

print " Layer 5 is defined"

if (index6 > -1):

print " Layer 6 is defined"

if (index7 > -1):

print " Layer 7 is defined"

return MG_TRUE


db = mgGetCurrentDb ()


mgWalk (db, CheckPolygonForTexture, None, None, MWALK_ON)

Original Post by: shawnallen Mon Jul 18 21:47:36 2016


Whoa - thanks Steve!!


Sorry - I'd like to put this into a standalone script, but it doesn't work. I integrated the function right after:

from mgapilib import *


def CheckPolygonForTexture (rec, i):


And the call is:

mgWalk (db, CheckPolygonForTexture, None, None, MWALK_ON)


My output:

E:\Nads\ProjectData\Tiles\comm\4ln_4way_comm_01>python d:\Presagis\Suite14\OpenFlight_API\samples\scripts/sa_egwalk1.py test3.flt

I: OpenFlight API version 14.0.0.

I: Loading plugin <OpenFlight Data Dictionary> from <D:/Presagis/Suite14/OpenFlight_API/bin/release/fltdata.dll>...

I: Site <FLTDATA> registered for plugin <OpenFlight Data Dictionary>.

I: Plugin <OpenFlight Data Dictionary> loaded.


Opening database: test3.flt


Db file open.


Here's the relevant bit (as far as I know anyhow!):


# initialize the OpenFlight API

# always call mgInit BEFORE any other OpenFlight API calls

#

mgInit (None, None)


# open database

print "\nOpening database: ", sys.argv[1], "\n"

db = mgOpenDb (sys.argv[1])

if db == None:

msgbuf = mgGetLastError ()

print msgbuf, "\n"

mgExit ()

return

print 'Db file open.\n'


mgWalk (db, CheckPolygonForTexture, None, None, MWALK_ON)


# close the database

ok = mgCloseDb (db)

if ok == MG_FALSE:

print "Error closing database\n"


# always call mgExit() AFTER all OpenFlight API calls

mgExit()


main()


Obviously something important got lost in the translation...

Original Post by: shawnallen Tue Jul 19 13:51:13 2016


Good grief - I assumed that 'parent' was irrelevant since this is for a standalone script. Restore that, et voila, c'est magnifique!

I assume the last node isn't checked due to an index/count issue..?


Opening database: test3.flt


p3206_37 :

Layer 0 is defined

p3206_38 :

Layer 0 is defined

p3206_75 :

Layer 0 is defined

p3206_76 :

Layer 0 is defined

p3206_77 :

Layer 0 is defined

Layer 1 is defined

p3206_78 :

Layer 0 is defined

p3206_79 :

Layer 0 is defined

p11345_14 :

p3206_88 :

Layer 0 is defined

p11345_16 :

p3206_89 :

Layer 0 is defined

p11345_17 :


Forgot the logical explanation: said node has no texture.

Original Post by: SteveThompson Tue Jul 19 16:44:57 2016


Not sure if there was a question in your last post Shawn but using the script snippet I sent you a polygon node name will print with no info after it if it is NOT textured on any layer.


And maybe you figured it out but in the script snippet you posted, your indents are all whacked. Python is very picky about indents. They are used to define code blocks/scope. The indents in the scipt you posted should look like this:


# initialize the OpenFlight API

# always call mgInit BEFORE any other OpenFlight API calls

#

mgInit (None, None)


# open database

print “\nOpening database: “, sys.argv[1], “\n”

db = mgOpenDb (sys.argv[1])

if db == None:

msgbuf = mgGetLastError ()

print msgbuf, “\n”

mgExit ()

return

print ‘Db file open.\n’


mgWalk (db, CheckPolygonForTexture, None, None, MWALK_ON)


# close the database

ok = mgCloseDb (db)

if ok == MG_FALSE:

print “Error closing database\n”


# always call mgExit() AFTER all OpenFlight API calls

mgExit()


main()

Original Post by: shawnallen Tue Jul 19 16:56:01 2016


Thanks Steve,


No question, just 'rounding things out' for posterity, thinking out loud.


My code works, so the indent whack must happen pasting it in. I've been able to use the script to process 121 files and check on image files used on layers 0 and 1. The problem I'm trying to address is figuring out if there is a naming convention issue on these two layers.


Thanks a ton for the code - I have much to digest.

Original Post by: SteveThompson Tue Jul 19 17:38:20 2016


Roger that Shawn, let us know if you have any questions along the way.


Here's a tip when posting "code" on this forum.

To get it looking "nice" and formatted on your post, you can delimit the block of script code with the "BEGIN CODE" and "END CODE" tags. It's hard to write these tokens here as plain text because the forum "gobbles" them up but


BEGIN CODE is left (square bracket) "[" followed by the word "code" followed by right (square) bracket "]"

END CODE is left (square bracket) "[" followed by foward slash "/", followed by the the word "code" followed by right (square) bracket "]"


An easy way to do this on the forum is:

1) Paste your code in the post

2) Select it all

3) Click the "code" button on the top of the post editor. This automatically pastes the BEGIN CODE and END CODE tags around what you have selected.


Attached is a picture of that.

Original Post by: shawnallen Tue Jul 19 17:41:58 2016


OK, thanks!


So it turns out I do have a (python) problem. I have a function to format the texture name string, which I thought was working, but it only works for Layer 0:


def get_tex_name(tex_name):

return (tex_name.rsplit('/',2)[-1])


For layer 1, it looks like I get a copy of layer 0. If I in-line the code that formats the string, it works fine:

            if (index1 > -1):

# print " Layer 1 is defined"

tex_name = mgGetTextureName(db, index1)

# get_tex_name(tex_name)

tex_name_str = (tex_name.rsplit('/',2)[-1])


print 'Node:', node_name, 'Tx_Layer_1:', tex_name_str


In case the full context would help, here is the thing entire:

##

##

## Sample file: egwalk1.py

##

##

## Program functions:

## Open a database from command line.

##

## API functions used:

## mgInit(), mgExit(), mgGetLastError(),

## mgGetPrevious(), mgGetName(), mgFree(),

## mgWalk(), mgWalkEx(), mgWalkGetMatrix(),

## mgMeshGetVtxCoord(), mgMeshPrimitiveGetNumVtx(),

## mgMeshPrimitiveGetType(), mgMeshPrimitiveGetVtxIndexArray(),

## mgMoreDetail(), mgOpenDb(), mgCloseDb()

##

##


import sys


# import OpenFlight API module

from mgapilib import *


def get_tex_name(tex_name):

return (tex_name.rsplit('/',2)[-1])


def CheckPolygonForTexture (db, parent, rec, i):

code = mgGetCode(rec)


# print 'Inside function'


if (code == fltPolygon or code == fltMesh):

numAttr, \

code0, index0, \

code1, index1, \

code2, index2, \

code3, index3, \

code4, index4, \

code5, index5, \

code6, index6, \

code7, index7 = \

mgGetAttList(rec, \

fltPolyTexture, \

fltLayerTexture1, \

fltLayerTexture2, \

fltLayerTexture3, \

fltLayerTexture4, \

fltLayerTexture5, \

fltLayerTexture6, \

fltLayerTexture7)

if (numAttr is 8):

node_name = mgGetName(rec)


if (index0 > -1):

# print " Layer 0 is defined"

tex_name = mgGetTextureName(db, index0)

tex_name_str = get_tex_name(tex_name)

print 'Node:', node_name, 'Tx_Layer_0:', tex_name_str


if (index1 > -1):

# print " Layer 1 is defined"

tex_name = mgGetTextureName(db, index1)

# get_tex_name(tex_name)

tex_name_str = (tex_name.rsplit('/',2)[-1])


print 'Node:', node_name, 'Tx_Layer_1:', tex_name_str


if (index2 > -1):

# print " Layer 2 is defined"

tex_name = mgGetTextureName(db, index2)

get_tex_name(tex_name)

print 'Node:', node_name, 'Tx_Layer_2:', tex_name_str


if (index3 > -1):

# print " Layer 3 is defined"

tex_name = mgGetTextureName(db, index3)

get_tex_name(tex_name)

print 'Node:', node_name, 'Tx_Layer_3:', tex_name_str


if (index4 > -1):

# print " Layer 4 is defined"

tex_name = mgGetTextureName(db, index4)

get_tex_name(tex_name)

print 'Node:', node_name, 'Tx_Layer_4:', tex_name_str


if (index5 > -1):

# print " Layer 5 is defined"

tex_name = mgGetTextureName(db, index5)

get_tex_name(tex_name)

print 'Node:', node_name, 'Tx_Layer_5:', tex_name_str


if (index6 > -1):

# print " Layer 6 is defined"

tex_name = mgGetTextureName(db, index6)

get_tex_name(tex_name)

print 'Node:', node_name, 'Tx_Layer_6:', tex_name_str


if (index7 > -1):

# print " Layer 7 is defined"

tex_name = mgGetTextureName(db, index7)

get_tex_name(tex_name)

print 'Node:', node_name, 'Tx_Layer_7:', tex_name_str


return MG_TRUE


def main():


id = "id"

# check for correct number of arguments

if len(sys.argv) < 2:

print "\nUsage: ", sys.argv[0], " <input_db_filename>\n"

print " Reads database: <input_db_filename>\n"

print " Traverse the database in different ways printing\n"

print " out the node names as they are traversed\n"

print " Traverse the database to print out polygon/mesh vertices\n"

print "\n"

return


# initialize the OpenFlight API

# always call mgInit BEFORE any other OpenFlight API calls

#

mgInit (None, None)


# open database

print "\nOpening database: ", sys.argv[1], "\n"

db = mgOpenDb (sys.argv[1])

if db == None:

msgbuf = mgGetLastError ()

print msgbuf, "\n"

mgExit ()

return


print sys.argv[1]

mgWalk (db, CheckPolygonForTexture, None, None, MWALK_ON)


# close the database

ok = mgCloseDb (db)

if ok == MG_FALSE:

print "Error closing database\n"


# always call mgExit() AFTER all OpenFlight API calls

mgExit()


main()

Original Post by: shawnallen Tue Jul 19 17:45:04 2016


working output:

Node: p17726_18445 Tx_Layer_1: veg_trees_hmr_TM.rgba

Node: p17726_18448 Tx_Layer_1: veg_trees_hmr_TM.rgba

Node: p17726_18451 Tx_Layer_1: veg_trees_hmr_TM.rgba

Node: p41266_656 Tx_Layer_1: veg_trees_hmr_TM.rgba

Node: p17726_18490 Tx_Layer_1: veg_trees_hmr_TM.rgba

Node: p41265_657 Tx_Layer_1: veg_trees_hmr_TM.rgba


Not working output:

Node: p17726_18445 Tx_Layer_1: veg_trees_hmr_TM.rgb

Node: p17726_18448 Tx_Layer_1: veg_trees_hmr_TM.rgb

Node: p17726_18451 Tx_Layer_1: veg_trees_hmr_TM.rgb

Node: p41266_656 Tx_Layer_1: veg_trees_hmr_TM.rgb

Node: p17726_18490 Tx_Layer_1: veg_trees_hmr_TM.rgb

Node: p41265_657 Tx_Layer_1: veg_trees_hmr_TM.rgb

Node: p41266_665 Tx_Layer_1: veg_trees_hmr_TM.rgb

Node: p17726_18586 Tx_Layer_1: veg_trees_hmr_TM.rgb

Original Post by: SteveThompson Tue Jul 19 17:46:09 2016


You need to assign the string that is returned by your nifty function into a variable.


Where you write

get_tex_name(tex_name)


you need to write

tex_name_str = get_tex_name(tex_name)

Without assigning the return value into something, calling the function really does nothing. The value returned just slips into the ether.

Original Post by: shawnallen Tue Jul 19 18:11:42 2016


ah, of course! Thanks!!!!!

Login to post a comment