Start a new topic

Light Point Palette Load Issue

Original Post by: brianpow Thu Aug 21 19:51:01 2014


I am trying to load a color and a light palette with a single script in python. Here is my code:


import sys


from mgapilib import *


COLORPALETTEFILE = "E:\srcdata\models\ICAO-Airport\palettes\RSI.color"

LIGHTPALETTEFILE = "E:\srcdata\models\ICAO-Airport\palettes\flt1.lightpoints"


def main ():

mgInit (None, None)


mgReadColorPalette(mgGetCurrentDb(), COLORPALETTEFILE)

mgReadLightPointFile(mgGetCurrentDb(), LIGHTPALETTEFILE)

mgExit ()


main()



The color palette loads just fine, but the light point palette does not load. When I load the palette manually it works, what am I missing?


Original Post by: SteveThompson Fri Sep 26 18:42:29 2014


Yes, you can do a bit more with plugin tools that are built using the OpenFlight C API. For example, you can put them in a toolbox or a menu and the user can assign keyboard shortcuts. In addition you can build dialogs for them if you need to. Creator, admittedly, more fully supports "plugins" in this way versus OpenFlight Scripts.


Hopefully we can add more support for OpenFlight Scripts on the Creator desktop in future releases (like being able to assign icons, adding to menus or toolboxes and supporting keyboard shortcuts). Some customers have built their own dialogs using 3rd party Python GUI toolkits like wxPython.


Let us know if you have any other questions.

Original Post by: atl4ntis Fri Sep 26 18:36:26 2014


Thank you so much for all the help. Could I accomplish creating this as an actual tool using the C++ api?

Original Post by: SteveThompson Fri Sep 26 18:18:28 2014


The code actually works just fine and it does update the database as is.

I guess that depends on what you mean by "update the database". Yes the color palette (in memory) is updated. But as you originally noted, the color palette (in the GUI) is not "redrawn" automatically to reflect the in-memory changes. That is a bug and as I noted, it has been fixed for our upcoming release (thanks to you).

Original Post by: SteveThompson Fri Sep 26 18:11:59 2014


That's simple. In the OpenFlight Script Editor, load the script and do File>Publish to Creator. This will save the file in a special folder (PRESAGIS_CREATOR/config/scripts) that Creator uses to add items to the Script>Run Script menu. Now when you want to run your script simply select the Script>Run Script><your_script.py>. This is all explained in the Help context of the OpenFlight Script Editor (the section titled "Adding scripts to Creator user interface") in much more detail.


Unfortunately you cannot assign a shortcut key but you can run without launching the Script editor.

Original Post by: atl4ntis Fri Sep 26 17:45:11 2014


The code actually works just fine and it does update the database as is. The problem is how to I access this without specifically having to go to scripts -> run scripts and then selecting the script. I want it at a stand alone tool that I can hotkey or set up a button for.


The code I speak of looks like this:


#!/usr/local/bin/python


def RSiColorPalette():

toolName = "Load RSi Color Palette"

editorContext = mgNewEditorContext (toolName)


if (not editorContext):

mgSendMessage (MMSG_ERROR, "Failed creating Editor Context")

return


mgSendMessage (MMSG_STATUS, "Editor Context Created");


db = mgEditorGetDbRec (editorContext)

COLORPALETTEFILE = "E:/srcData/models/ICAO-Airport/palettes/RSI.color"

mgReadColorPalette(db, COLORPALETTEFILE)

RSiColorPalette ()


Original Post by: SteveThompson Fri Sep 26 16:40:24 2014


Oh, ok, thanks for the clarification. You want to run this in Creator from a menu. I get it now.


First, since you are running this inside Creator... you do not need to call mgInit. Creator calls mgInit on behalf of all the Plugins and Scripts so you don't have to. In fact you SHOULD NOT call mgInit. Similarly you absolutely SHOULD NOT call mgExit. You only call these two functions in the stand-alone environment. To better understand stand-alone environment vs Creator environment wrt Scripting and Plugins, see the OpenFlight API Developer Guide.


Second, when specifying "slash separators" for file names in OpenFlight script you should use either:

Two back slashes

or

One single forward slash


You need two backslashes because a single backslash is the line continuation character in Python (on which OpenFlight Script is based) and nearly every other programming language as well. If you want a single backslash in the string, you need to "escape" it with another one to tell the language that you really want that character in the string and that you are not continuing the line on the next line.


So your first post is correct:

COLORPALETTEFILE = "E:\\srcdata\\models\\ICAO-Airport\\palettes\\RSI.color"

but your most recent post is not:

COLORPALETTEFILE = "E://srcData//models//ICAO-Airport//palettes//RSI.color"


Two forward slashes will work as a quirk of some underlying functions but one single forward slash is the correct usage, not two.


Third, the first parameter to mgReadColorPalette is an mgrec*. So your first post is correct:

mgReadColorPalette(mgGetCurrentDb(), COLORPALETTEFILE)


but (as you discovered yourself) your most recent post is not:

DBN = mgGetCurrentDb()

DBFN = mgRec2Filename(DBN)

mgReadColorPalette(DBFN, COLORPALETTEFILE)


This would be correct:

DBN = mgGetCurrentDb()

mgReadColorPalette(DBN, COLORPALETTEFILE)


Finally, now that I finally understand the context of your problem, I do see that Creator does not automatically update (redraw the Color Palette or affected nodes in the Graphics view) when you call mgReadColorPalette. Nor does it mark the database as "modified". If you force a "redraw" in the Color Palette or the Graphics view you will see your changes. In other words, the function is working but Creator is not "redrawing automatically" to show you the changes. I hope that makes sense. Not a show stopper certainly since the function is working. We'll fix Creator to automatically update the scene and all will be good.


So to wrap this up, here is the correct script you should use:

COLORPALETTEFILE = "E:/srcdata/models/ICAO-Airport/palettes/RSI.color"

db = mgGetCurrentDb()

mgReadColorPalette(db, COLORPALETTEFILE)


This will load this color palette file into the current db on the Creator desktop but (as you've discovered) won't update the scene automatically or mark the db as modified. But, again, that does not mean the function is not working. The changes are there and can be saved the next time the user saves the file - you just won't see them until you force a redraw in Creator. I've already fixed these problems for our next version.


Note that you can encapsulate this in a "def" function but strictly speaking you don't have to. This is personal preference for you to decide.


Thanks for bringing this to our attention.

Original Post by: atl4ntis Fri Sep 26 16:05:15 2014


I'm trying to automate it as a tool so I have a hotkey set to call the script. I want to run it on the database I currently have open without using the script editor. The idea is to have a tool for our engineers to quickly load our official light palette.


I also tried something like this but from what you're saying it may not be possible with the method I'm using.


# -*- coding: utf-8 -*-

import sys

from mgapilib import *


def main ():


mgInit(None, None)

COLORPALETTEFILE = "E://srcData//models//ICAO-Airport//palettes//RSI.color"

DBN = mgGetCurrentDb()

DBFN = mgRec2Filename(DBN)

mgReadColorPalette(DBFN, COLORPALETTEFILE)

mgExit()

main()


Edit:


I think I'm approaching this all wrong. I wrote this:


#!/usr/local/bin/python


def RSiColorPalette():

toolName = "Load RSi Color Palette"

editorContext = mgNewEditorContext (toolName)


if (not editorContext):

mgSendMessage (MMSG_ERROR, "Failed creating Editor Context")

return


mgSendMessage (MMSG_STATUS, "Editor Context Created");


db = mgEditorGetDbRec (editorContext)

COLORPALETTEFILE = "E://srcData//models//ICAO-Airport//palettes//RSI.color"

mgReadColorPalette(db, COLORPALETTEFILE)

RSiColorPalette ()



This code works fine in the script editor but I need to call it as a tool. I'm still trying to figure out how to get this into the creator environment through a hotkey or button.

Original Post by: SteveThompson Fri Sep 26 15:25:51 2014


You say you are not using the Script Editor and by the looks of your code (you're calling mgInit, etc) I assume you are running this in a stand-alone environment.


If that is the case, your script (as written) won't do anything. In a stand-alone environment. mgGetCurrentDb() will be MG_NULL unless you explicitly open a database file using mgOpenDb. mgReadColorPalette, in turn, called with an MG_NULL database won't do anything.


If your intention is to load a color palette into a specific database file, you need to first open the file using mgOpenDb. then pass that db to mgReadColorPalette, and finally save and close the file. Then the next time you open this file in Creator, that file will have that color palette.


A script like this is maybe what you really meant to write?


mgInit(None, None)

COLORPALETTEFILE = "E:\\srcdata\\models\\ICAO-Airport\\palettes\\RSI.color"

db = mgOpenDb("myfile.flt")

mgReadColorPalette(db, COLORPALETTEFILE)

mgWriteDb(db)

mgClose(db)

mgExit()


Perhaps I missed the intention of your original script. Let us know what you wanted it to do and we can help you write the correct script.

Original Post by: atl4ntis Fri Sep 26 01:48:53 2014


I'm having the same issue but I'm not using the script editor. My code looks like this


# -*- coding: utf-8 -*-

import sys

from mgapilib import *


COLORPALETTEFILE = "E:\\srcdata\\models\\ICAO-Airport\\palettes\\RSI.color"



def main ():


mgInit(None, None)


mgReadColorPalette(mgGetCurrentDb(), COLORPALETTEFILE)


MgExit ()


sys.exit ("0")


main()


It runs just fine and returns a 0 but nothing happens in creator. Any suggestions?


a quick edit the code now looks like this:


# -*- coding: utf-8 -*-

import sys

from mgapilib import *


def main ():


mgInit(None, None)

COLORPALETTEFILE = "E:\\srcdata\\models\\ICAO-Airport\\palettes\\RSI.color"

mgReadColorPalette(mgGetCurrentDb(), COLORPALETTEFILE)

mgExit ()

main()


It runs without giving me any errors but it's not having any effect in creator.

Original Post by: brianpow Thu Aug 21 20:28:17 2014


Absolutely, thank you guys so much for your help!

Original Post by: ChrisRogers Thu Aug 21 20:26:00 2014


I stopped Creator and restarted, turns out I probably switched something off when I was using the other code. Thanks guys, problem solved!


I'm glad you are getting something working. However, make sure you double those backslashes. It shouldn't work at all the way it is now.

Original Post by: ChrisRogers Thu Aug 21 20:18:36 2014


Ok, that makes sense. I didn't think my changes were going to fix anything, I was just pointing out that your script contained some un-needed calls.


Your script is not working because your strings are not what you think they are. In python, you can place non-printable characters inside of strings. (think new line, or tab) Since these do not correspond to a button on the keyboard, or a letter in the alphabet, python uses something called an escape character followed by a letter to represent a single non-printable character. The backslash '\' is this escape character. For instance, "\n" is new line. "\t" is tab.


Your first string gets lucky and does not use any known escaped characters. Python was very nice and assumed that you meant to add real backslashes. However your second string contains a form feed. (\f). So you are asking creator to load something that looks more like:


"E:\srcdata\models\ICAO-Airport\palettes

lt1.lightpoints"


To be correct, you need to use double backslashes wherever you use a backslash that is not meant to be an escape character.


Try this instead:

COLORPALETTEFILE = “E:\\srcdata\\models\\ICAO-Airport\\palettes\\RSI.color”

LIGHTPALETTEFILE = “E:\\srcdata\\models\\ICAO-Airport\\palettes\\flt1.lightpoints”

mgReadColorPalette(mgGetCurrentDb(), COLORPALETTEFILE)

mgReadLightPointFile(mgGetCurrentDb(), LIGHTPALETTEFILE)

Original Post by: brianpow Thu Aug 21 20:08:52 2014


I stopped Creator and restarted, turns out I probably switched something off when I was using the other code. Thanks guys, problem solved!

Original Post by: brianpow Thu Aug 21 20:05:20 2014


Yes, sorry! I'm running this from the Creator script editor.


I tried the shortened version you provided and still nothing appears in the light point palette.

Original Post by: ChrisRogers Thu Aug 21 19:59:05 2014


Or perhaps are you running this inside of Creator's script editor?

If so, you can simplify the script to something like:


COLORPALETTEFILE = “E:\srcdata\models\ICAO-Airport\palettes\RSI.color”

LIGHTPALETTEFILE = “E:\srcdata\models\ICAO-Airport\palettes\flt1.lightpoints”

mgReadColorPalette(mgGetCurrentDb(), COLORPALETTEFILE)

mgReadLightPointFile(mgGetCurrentDb(), LIGHTPALETTEFILE)


I say this because I see you are not reading a db in the script. This makes me think you might be running inside of Creator where mgGetCurrentDb() will give you a db. You also don't need to import mgapi when inside of Creator.


If you are running inside of Creator then the call to mgInit is bad form. Creator already called this and the API has already been initialized. You only call this from stand alone scripts, and only once.

Login to post a comment