Peer-to-Peer Forum

1 of 2
1

Login Register    
scripting a -1
Posted: 26 May 2011 09:21 AM  
Sr. Member
RankRankRankRank
Total Posts:  550
Joined  2009-03-17

I haven’t tried with the texturing, but with the materials ...

I was requested by my customer to deliver all models with NO material.  An empty palette, and a material index of -1.  The 273 models in the library all have a single default material of 0, with ambient and diffuse set to 1 1 1, specular at .35 .35 .35

I tried to script it to load an empty material file (i deleted all materials and saved the palette) and set the index to -1.  the result was that it created a default material, completely transparent, and set the material indeces to 0.

If -1 is a valid value for the record, why can I not set it?  If i do it by hand in creator, it sorks as intended, but I don’t really feel like doing it by hand to 273 models (running it to set everything to zero takes approximately 1.8 seconds)

 
Posted: 26 May 2011 09:48 AM   [ # 1 ]  
Moderator
RankRankRankRank
Total Posts:  386
Joined  2008-07-03

The problem is when you delete a material in Creator, it doesn’t just remove the material from the palette, it also searches the database to find all geometry that uses that material, and sets its index to -1. The OpenFlight API is more low level than that. It is more concerned about performance. If every time you deleted a single material using the API, it had to search the entire db for that material index and clear it, deleting several materials would cause several searches. This would be slow.  The way it is now, you can delete any number of materials and only search once.  However this means you have to explicitly clear your material indices on the geometry when using the API. 

Here is a script that will erase all your materials and set all polygon’s to material index -1. You should extend this to set mesh nodes material index to -1 as well to be complete. Then you can run this in the batch run script tool to fix all your models before delivery.

db mgGetCurrentDb()

print 
"Clearing Material Palette:"
rec,index mgGetFirstMaterial (db)
while (
rec):
    
mgDeleteMaterial (dbindex)
    
rec,index mgGetNextMaterial (rec)
    
print 
"Clearing Polygon Materials:"
def ClearMaterialIndex (dbparentreci):
    if (
mgGetCode(rec) == fltPolygon):
        
mgSetAttList (recfltPolyMaterial, -1)    
    return 
MG_TRUE

db 
mgGetCurrentDb ()
mgWalk (dbNoneClearMaterialIndexNoneMWALK_NOREADONLY
 
Posted: 26 May 2011 09:51 AM   [ # 2 ]  
Sr. Member
RankRankRankRank
Total Posts:  550
Joined  2009-03-17

ACh - I was using
mgSetCurrentMaterial
to try to set the current material to -1, then
mgSetPolyCurrentMaterial or whatever - my machine died so I can’t get the exact syntax.

I’ll try using the AttList fuction on the poly

There are multiple methodologies by which to defur the feline!

 
Posted: 26 May 2011 10:00 AM   [ # 3 ]  
Sr. Member
RankRankRankRank
Total Posts:  550
Joined  2009-03-17

Works like a Champ!

 
Posted: 26 May 2011 10:19 AM   [ # 4 ]  
Moderator
RankRankRankRank
Total Posts:  604
Joined  2008-07-02

Kent ,
After looking at this a bit, there seems to be an inconsistency in OpenFlight Script (and OpenFlight C API) wrt current material when there is an empty material palette.  I noticed the following when the db has NO materials in its palette:

Sometimes mgGetCurrentMaterial returns (TRUE,0) sometimes it returns (FALSE,None).  It seems to depend on how the material palette became empty.  If you delete all the materials explicitly, you get (TRUE,0).  If you remove unused (in Creator) to empty the palette, you get (FALSE, None).  It never returns (TRUE,-1) as (from your post) you might have been thinking.

I suggest that mgGetCurrentMaterial should return (FALSE,None) when the palette is empty to indicate that there is NO current material.

Also, note that mgSetCurrentMatrial (db, -1) will always return FALSE.  I believe this is correct in either case of an empty or non-empty material palette.  When the palette is non-empty, there is ALWAYS a current material, there is no way to tell Creator that there is NO current material.

Finally…I don’t think Creator/API likes an “empty” material palette.  I would suggest (if your customer can tolerate it) that you create a material palette that has just the default material index 0 with no polygons (or meshes) referencing it.

 
Posted: 26 May 2011 10:22 AM   [ # 5 ]  
Sr. Member
RankRankRankRank
Total Posts:  550
Joined  2009-03-17

Thanks - I now have scripting modules in my library to either empty a palette or load one with a single material, and two fuctions to either wer the index to -1 using the AttList or set the index to 0 using mgSetPolyCurrentMaterial.

So if it doesn’t work out it is pretty fast to fix it, it will take longer to copy the data to my share drive than to fix the materials 8*)

 
Posted: 26 May 2011 11:58 AM   [ # 6 ]  
Sr. Member
RankRankRankRank
Total Posts:  156
Joined  2007-09-27

sooooo

by deleting the
print “Clearing Material Palette:”
rec,index = mgGetFirstMaterial (db)
while (rec):
  mgDeleteMaterial (db, index)
  rec,index = mgGetNextMaterial (rec)

this script will force the seleted polys to -1 or whatever entry I insert in the “-1” code

So to then do this also for

Feature ID
SMC
RoofLine
and a comments entry
...

The attributes for all selected polys could be forced to a default set.  Kind of what we were looking for in the PolyType thread….

If   fltPolyMaterial is for the material attribute

are
fltPolySMC
fltPolyFeatureID
fltPolyRoofLine
fltPolyComments

valid attributes pointers to change in a similar script to modify those attributes?

 
Posted: 26 May 2011 12:05 PM   [ # 7 ]  
Sr. Member
RankRankRankRank
Total Posts:  550
Joined  2009-03-17

the trouble isnt forcing a set of attributes on a selected set, it’s being able to select a set in multiple files.  I can always (and I do) traverse the driectory after the fact, open every OpenFlight, look for any rec whose
mgGetType(rec) = fltPolygon
“footprint” in mgGetName (parent)
since we make every footprint in an object called footprint (but sometimes they may be footprint_1 or something).

Just to simplify, though, it would be nice to have sets of attributes available by named list to apply while creating polygons (or whatever)

 
Posted: 26 May 2011 12:08 PM   [ # 8 ]  
Sr. Member
RankRankRankRank
Total Posts:  156
Joined  2007-09-27

Two attributes are

fltPolySmc

fltPolyFid


how do you get to the comments field?

 
Posted: 26 May 2011 12:33 PM   [ # 9 ]  
Sr. Member
RankRankRankRank
Total Posts:  156
Joined  2007-09-27

db = mgGetCurrentDb()
print “Clearing Polygon Materials:”
def ClearMaterialIndex (db, parent, rec, i):
  if (mgGetCode(rec) == fltPolygon):
      mgSetAttList (rec, fltPolyMaterial, 0) 
  return MG_TRUE

print “Clearing Polygon Feature ID:”
def ClearFIDIndex (db, parent, rec, i):
  if (mgGetCode(rec) == fltPolygon):
      mgSetAttList (rec, fltPolyFid, 100) 
  return MG_TRUE
   
print “Clearing Polygon SMC:”
def ClearSMCIndex (db, parent, rec, i):
  if (mgGetCode(rec) == fltPolygon):
      mgSetAttList (rec, fltPolySmc, 1) 
  return MG_TRUE
   
print “Clearing Polygon RoofLine:”
def ClearRoofLineIndex (db, parent, rec, i):
  if (mgGetCode(rec) == fltPolygon):
      mgSetAttList (rec, fltPolyRoofline, 1) 
  return MG_TRUE
   
print “Clearing Polygon Comments:”
def ClearComments (db, parent, rec, i):
  if (mgGetCode(rec) == fltPolygon):
      mgSetAttList (rec, fltImgComment, ALRIGHT) 
  return MG_TRUE


   
db = mgGetCurrentDb ()
mgWalk (db, None, ClearMaterialIndex, None, MWALK_NOREADONLY)
db = mgGetCurrentDb ()
mgWalk (db, None, ClearFIDIndex, None, MWALK_NOREADONLY)
db = mgGetCurrentDb ()
mgWalk (db, None, ClearSMCIndex, None, MWALK_NOREADONLY)
db = mgGetCurrentDb ()
mgWalk (db, None, ClearRoofLineIndex, None, MWALK_NOREADONLY)
db = mgGetCurrentDb ()
mgWalk (db, None, ClearComments, None, MWALK_NOREADONLY)


Well the comments field doesn’t work,
but otherwise this could be saved out as a mulit-attribute index group that gets flushed across the appropriate seleected polygons in one swipe ...! Duplicate for other sets and modify the appropriate values wanted in the next set (color 5, SMC 770 or whatever)

Any ideas on how to change the comments—think there was a script somewhere for that already


thanks this is cool

 
Posted: 26 May 2011 04:52 PM   [ # 10 ]  
Member
RankRankRank
Total Posts:  59
Joined  2009-05-18

Kent

For the comment field you should be using

mgSetComment (rec, comment)

not

mgSetAttList (rec, fltImgComment, ALRIGHT)

 
Posted: 26 May 2011 11:50 PM   [ # 11 ]  
Moderator
RankRankRankRank
Total Posts:  604
Joined  2008-07-02

For the comment field you should be using

mgSetComment (rec, comment)

not

mgSetAttList (rec, fltImgComment, ALRIGHT)

Thanks John-

Note that the OpenFlight Data Dictionary tells you that fltImgComment is NOT an attribute of fltPolygon.  Remember to use the Data Dictionary for this kind of information wink

Note that you can use mgSetAttList to set a node’s comment also using the fltComment attribute.

 
Posted: 27 May 2011 04:59 AM   [ # 12 ]  
Sr. Member
RankRankRankRank
Total Posts:  156
Joined  2007-09-27

I got a copy of the openflightdd yesterday afternoon.  Its so much better then inserting a letter into the code to see what the suggestions turn up!  ( Nothing in there about mgSetComment though.)

Thanks for the comment pointer!    I’ll poke at that.  I Can’t figure out how/where to define what the comment is to insert.   Somewhere in   argument 2 of type ‘char const *’  the openflightdd has not on that though.

Any ideas of why I need to run this twice for it to work?  The first time it always gets a
E: Traceback (most recent call last):
E:  File “<string>”, line 3, in <module>

Am I inserting a space or something I shouldn’t have.  Not sure how to poet the actual coding here.
The Primary Color Index was a douzie! Works for what I need now.

(I do know this is backwards instead of verifying masses of flt files as Kent does, but it is useful for some modeling procedures.  its like having a spoon instead of a stir stick for your coffee - there is a difference to the user)

 
Posted: 27 May 2011 06:45 AM   [ # 13 ]  
Member
RankRankRank
Total Posts:  59
Joined  2009-05-18

How about this. A bit simpler with only one mgWalk


db = mgGetCurrentDb()
print “Clearing Polygon Material and Attributes:”
def ClearMaterialandAttributes (db, parent, rec, i):
  if (mgGetCode(rec) == fltPolygon):
      ok = mgSetAttList (rec, fltPolyMaterial, 0,fltPolyFid, 100,fltPolySmc, 1,fltPolyRoofline, 1)
      ok = mgSetComment(rec,“change this to your comment”)
  return MG_TRUE

mgWalk (db, None, ClearMaterialandAttributes, None, MWALK_NOREADONLY)

 
Posted: 27 May 2011 06:55 AM   [ # 14 ]  
Sr. Member
RankRankRankRank
Total Posts:  156
Joined  2007-09-27

really beautiful.

I amy not be programming/coding savvy but it’s obviously really nice.

Thanks John, you’ve impressed me again


cheers

 
Posted: 27 May 2011 07:07 AM   [ # 15 ]  
Sr. Member
RankRankRankRank
Total Posts:  156
Joined  2007-09-27

added in the Primary Color Index and shading and now Ive got a default Residential Wall attribute set!  (roof set to 0)

One more question/request.

Is there a way to have quotations within the comments? 


really spiffy


thanks

 



1 of 2
1