<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:#954F72;
text-decoration:underline;}
.MsoChpDefault
{mso-style-type:export-only;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style></head><body lang=EN-US link=blue vlink="#954F72"><div class=WordSection1><p class=MsoNormal>This is a more broad problem than pyjnius, and is likely a Java problem that is letting things past the interface contract. Okay, I will try to explain what the bug is:</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>setDEF in X3DViewpointNode returns an X3DViewpointNode (interface)</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>public X3DViewpointNode setDEF(String newValue);</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>In HelloWorld.future.py, I import the concrete class:</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>from org.web3d.x3d.jsail.Navigation.ViewpointObject import ViewpointObject as Viewpoint</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>setDEF is implemented in the imported package as the following:</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>public ViewpointObject setDEF(SFStringObject newValue)</p><p class=MsoNormal>public final ViewpointObject setDEF(String newValue)</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Note that they return a concrete class instead of the interface. So</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal> .setCenterOfRotation([0,-1,0])</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>bombs, because the interface returns an interface (the contract and not the concrete class)<b><o:p></o:p></b></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>If we used the first way of doing setDEF in HelloWorld.future.py, it would likely work, but I haven’t tested it. It should be easy to test with our current infrastructure.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Programmer would be required to use non-SAI methods in many, many cases. This is undesirable, I think, but possible. They can always fallback to the other style of coding in an emergency. I do not know if there’s a backup for every SAI method. We can perhaps add them.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>My concern is that Java is allowing an interface contract violation in the compiler apparently.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>I do not know the formal definition of interface. My guess is we could change pyjnius.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>So what do we do next? The following code seems to work OK:</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>from org.web3d.x3d.jsail.fields.SFStringObject import SFStringObject as SFString</p><p class=MsoNormal>from org.web3d.x3d.jsail.fields.SFVec3fObject import SFVec3fObject as SFVec3f</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal> .addChild(Viewpoint() \</p><p class=MsoNormal> .setDEF(SFString("ViewUpClose")) \</p><p class=MsoNormal> .setCenterOfRotation(SFVec3f([0,-1,0])) \</p><p class=MsoNormal> .setDescription(SFString("Hello world!")) \</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>This is essentially what X_ITE does for scripts. X3DOM prefers using language-native types.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>We could try an intermediate set of interfaces which provided both the interface return and the concrete class return. A “future” interface standard.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>I can do what works, but that’s not in agreement with the Java SAI standard that I know of (but I’ve never read it).</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>It is an overall problem, because I will need to put parameter “objectifiers” to make the setters work, so SAI methods aren’t called.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>$ python HelloWorld.future.py</p><p class=MsoNormal>Warning: toFileX3D() is overwriting prior file /x3d-code/www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter01TechnicalOverview/HelloWorld_RoundTrip.x3d</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Done, checked in. You will have to rerun the generation of python. There are a few errors left, maybe you can take a crack at analyzing the issue with this one:</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>processSingleScene.pythonValidation:</p><p class=MsoNormal> [echo] processSingleScene.python C:\x3d-code\www.web3d.org\x3d\content\examples\X3dForWebAuthors\Chapter07EventAnimationInterpolation\CircleFishPTPrototype.future.py</p><p class=MsoNormal> [echo] Loading X3D model as .py program, if successful then saving as round-trip .x3d version:</p><p class=MsoNormal> [exec] Traceback (most recent call last):</p><p class=MsoNormal> [exec] File "C:\x3d-code\www.web3d.org\x3d\content\examples\X3dForWebAuthors\Chapter07EventAnimationInterpolation\CircleFishPTPrototype.future.py", line 157, in <module></p><p class=MsoNormal> [exec] .setProtoField(SFString("fishScale")) \</p><p class=MsoNormal> [exec] AttributeError: 'org.web3d.x3d.jsail.X3DConcreteNode' object has no attribute 'addChild'</p><p class=MsoNormal> [exec] Result: 1</p><p class=MsoNormal> [echo] =====================</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>I think we should make our code as flexible as possible, yet enforce interface contracts in some way.</p><p class=MsoNormal>Right now, it’s like we don’t have a workable Java SAI.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Sent from <a href="https://go.microsoft.com/fwlink/?LinkId=550986">Mail</a> for Windows 10</p><p class=MsoNormal><o:p> </o:p></p><div style='mso-element:para-border-div;border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in'><p class=MsoNormal style='border:none;padding:0in'><b>From: </b><a href="mailto:brutzman@nps.edu">Brutzman, Donald (Don) (CIV)</a><br><b>Sent: </b>Monday, April 22, 2019 9:25 PM<br><b>To: </b><a href="mailto:yottzumm@gmail.com">John Carlson</a><br><b>Cc: </b><a href="mailto:x3d-public@web3d.org">X3D Graphics public mailing list</a><br><b>Subject: </b>Re: [x3d-public] Sample X3D Python API; examples publishedforcontinuing improvement</p></div><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Everything I've seen so far indicates that no major redesign is needed, rather more likely is that</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>a. we are not invoking pyjnius correctly, or</p><p class=MsoNormal>b. pyjnius is not behaving as expected.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Could we focus on HelloWorld.x3d and .java working for the two python versions? Let's consider this simple example in depth, rather than everything + everything.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>http://x3dgraphics.com/examples/X3dForWebAuthors/Chapter01TechnicalOverview/HelloWorldIndex.html</p><p class=MsoNormal>http://x3dgraphics.com/examples/X3dForWebAuthors/Chapter01TechnicalOverview/HelloWorld</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>build outputs excerpt:</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>http://www.web3d.org/x3d/content/examples/build.python.all.log.txt</p><p class=MsoNormal>==================================================================</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>=====================</p><p class=MsoNormal>create python:</p><p class=MsoNormal>node xml2all.js C:\x3d-code\www.web3d.org\x3d\content\examples\X3dForWebAuthors/Chapter01TechnicalOverview//HelloWorld.x3d</p><p class=MsoNormal>HelloWorld.x3d converted to HelloWorld.py</p><p class=MsoNormal>- - - - - - - - - - -</p><p class=MsoNormal>validate python:</p><p class=MsoNormal>Loading HelloWorld.py with X3DJSAIL, if successful then saving as round-trip HelloWorld_RoundTrip1.x3d version:</p><p class=MsoNormal>Moving 1 file to C:\x3d-code\www.web3d.org\x3d\content\examples\X3dForWebAuthors\Chapter01TechnicalOverview</p><p class=MsoNormal>HelloWorld.py round-trip load test #1 complete</p><p class=MsoNormal>- - - - - -</p><p class=MsoNormal>Loading HelloWorld.future.py with X3DJSAIL, if successful then saving as round-trip HelloWorld_RoundTrip2.x3d version:</p><p class=MsoNormal>Traceback (most recent call last):</p><p class=MsoNormal> File "C:\x3d-code\www.web3d.org\x3d\content\examples\X3dForWebAuthors/Chapter01TechnicalOverview//HelloWorld.future.py", line 104, in <module></p><p class=MsoNormal> .setDEF("ViewUpClose") \</p><p class=MsoNormal>AttributeError: 'org.web3d.x3d.sai.Navigation.X3DViewpointNode' object has no attribute 'setCenterOfRotation'</p><p class=MsoNormal>Result: 1</p><p class=MsoNormal>HelloWorld.future.py round-trip load test #2 complete</p><p class=MsoNormal>==================================================================</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>I think if we get that one to work for v2, we can get them all to work.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Nope, more work beyond that example. There’s also work with coordIndexes, which I will probably fix another day.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>John</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>On 4/17/2019 12:29 PM, John Carlson wrote:</p><p class=MsoNormal>> Removing the getSuperclass and adding reflect package failed to fix anything.</p><p class=MsoNormal>> </p><p class=MsoNormal>> Hmm.</p><p class=MsoNormal>> </p><p class=MsoNormal>> Back to drawing board. I am starting to work on XML output from the other API, looking at possible packages. Will probably gen up my own, and then validate it.</p><p class=MsoNormal>> </p><p class=MsoNormal>> What are the XML aspects of SAI? Is there a standard API for exporting scenegraph?</p><p class=MsoNormal>> </p><p class=MsoNormal>> Thanks,</p><p class=MsoNormal>> </p><p class=MsoNormal>> John</p><p class=MsoNormal>> </p><p class=MsoNormal>> Sent from Mail <https://go.microsoft.com/fwlink/?LinkId=550986> for Windows 10</p><p class=MsoNormal>> </p><p class=MsoNormal>> *From: *John Carlson <mailto:yottzumm@gmail.com></p><p class=MsoNormal>> *Sent: *Tuesday, April 16, 2019 10:20 AM</p><p class=MsoNormal>> *To: *Brutzman, Donald (Don) (CIV) <mailto:brutzman@nps.edu></p><p class=MsoNormal>> *Cc: *X3D Graphics public mailing list <mailto:x3d-public@web3d.org></p><p class=MsoNormal>> *Subject: *Re: [x3d-public] Sample X3D Python API; examples published forcontinuing improvement</p><p class=MsoNormal>> </p><p class=MsoNormal>> One idea is to edit reflect.py and remove getSuperclass call.</p><p class=MsoNormal>> </p><p class=MsoNormal>> On Tue, Apr 16, 2019 at 10:08 AM John Carlson <yottzumm@gmail.com <mailto:yottzumm@gmail.com>> wrote:</p><p class=MsoNormal>> </p><p class=MsoNormal>> I think what we must try to do is duplicate autoclass functionality without abstract classes. I suggest a separate version of X3DJSAIL???? Any other suggestions? Please review/modify my generated code for any other suggestion?</p><p class=MsoNormal>> </p><p class=MsoNormal>> A prior suggestion was to add casting? Should we create a third serializer for this?</p><p class=MsoNormal>> </p><p class=MsoNormal>> John</p><p class=MsoNormal>> </p><p class=MsoNormal>> John</p><p class=MsoNormal>> </p><p class=MsoNormal>> On Mon, Apr 15, 2019 at 8:32 PM Brutzman, Donald (Don) (CIV) <brutzman@nps.edu <mailto:brutzman@nps.edu>> wrote:</p><p class=MsoNormal>> </p><p class=MsoNormal>> OK thanks for feedback John.</p><p class=MsoNormal>> </p><p class=MsoNormal>> Sorry but no tossing in the towel yet, please! Not ready for a reset on this end yet. Am optimistic that close scrutiny of your pyjnius code - which has gotten so far - will continue to inform progress. We're not far from an initial implementation. More study of python will help (at least for me).</p><p class=MsoNormal>> </p><p class=MsoNormal>> ... and in any case, we now have a nice build harness to test and improve language-binding progress against all available example scenes.</p><p class=MsoNormal>> </p><p class=MsoNormal>> </p><p class=MsoNormal>> On 4/15/2019 12:19 PM, John Carlson wrote:</p><p class=MsoNormal>> > You are welcome to produce an X3dToPy.xslt or otherwise manipulate the python files to eliminate any abstract classes. I am not aware of using abstract classes in the *.future.py files, and would have to be shown an example, thanks. You may also move the org/Web3d/X3D/sai pyjnius folder out of the way for a test.</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > I do know ignoring the return value from the setters seems to work for pyjnius, so perhaps we should explore why that works in the context of abstract classes.</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > Also, please explore what I am doing with declaring abstract classes under the pyjnius folder and how that might be improved.</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > I need an example before I can move forward.</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > Thanks,</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > John</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > On Mon, Apr 15, 2019 at 11:23 AM Brutzman, Donald (Don) (CIV) <brutzman@nps.edu <mailto:brutzman@nps.edu> <mailto:brutzman@nps.edu <mailto:brutzman@nps.edu>>> wrote:</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > Am happy to report that both versions of your .py programs are now being produced and published for all models in X3D Examples Archives.</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > BLUF: these should greatly help us in continued improvement of X3D Python language-binding syntax.</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > Build log (now 10MB) includes X3D validation of RoundTrip scenes and remains updated at</p><p class=MsoNormal>> > https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/content/examples/</p><p class=MsoNormal>> > https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/content/examples/build.python.all.log.txt</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > A zip of all autogenerated python models is at</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > http://www.web3d.org/x3d/content/examples/X3dExampleArchivesPythonScenes.zip</p><p class=MsoNormal>> > http://www.web3d.org/x3d/content/examples/X3dExampleArchivesPythonScenes.zip.MD5</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > Example links to python source _.pyv1_ and _.pyv2_ are provided for each scene, for example</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > http://x3dgraphics.com/examples/X3dForAdvancedModeling/HelloWorldScenes/</p><p class=MsoNormal>> > http://x3dgraphics.com/examples/X3dForAdvancedModeling/HelloWorldScenes/HelloWorldIndex.html</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > As before the .future.py versions fail pyjnius because of use of abstract classes.</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > On 4/11/2019 6:35 PM, John Carlson wrote:</p><p class=MsoNormal>> > > This versions is much cleaner than the previous version. Attached zip.</p><p class=MsoNormal>> > ></p><p class=MsoNormal>> > > Please review. We will get comments soon I hope.</p><p class=MsoNormal>> > ></p><p class=MsoNormal>> > > John</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > John, do you think we should pursue changes to pyJNIus to support abstract classes?</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > Or... we could instead eliminate them and fully elaborate each node. Not convinced that Python programmers might want or need abstract classes in the first place. Certainly we don't need to implement them in this initial-design phase.</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > This is kind of configuration preparation is automatable using X3DUOM, of course. Excerpts from your zip follows. You appear to be there already, fully elaborating methods for all fields in all nodes? Perhaps we should simply test with abstract classes omitted, or defined second?</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > [...]</p><p class=MsoNormal>> > class X3DAppearanceChildNode(X3DNode):</p><p class=MsoNormal>> > def __init__(self, **kwargs):</p><p class=MsoNormal>> > def metadata(self):</p><p class=MsoNormal>> > def metadata(self, value = None):</p><p class=MsoNormal>> > def setMetadata(self, metadata = None):</p><p class=MsoNormal>> > def addMetadata(self, metadata = None):</p><p class=MsoNormal>> > def removeMetadata(self, metadata):</p><p class=MsoNormal>> > def getMetadata(self, metadata = None):</p><p class=MsoNormal>> > def metadata_changed(self, metadata = None):</p><p class=MsoNormal>> > def DEF(self):</p><p class=MsoNormal>> > def DEF(self, value = None):</p><p class=MsoNormal>> > def setDEF(self, DEF = None):</p><p class=MsoNormal>> > def addDEF(self, DEF = None):</p><p class=MsoNormal>> > def removeDEF(self, DEF):</p><p class=MsoNormal>> > def getDEF(self, DEF = None):</p><p class=MsoNormal>> > def DEF_changed(self, DEF = None):</p><p class=MsoNormal>> > def USE(self):</p><p class=MsoNormal>> > def USE(self, value = None):</p><p class=MsoNormal>> > def setUSE(self, USE = None):</p><p class=MsoNormal>> > def addUSE(self, USE = None):</p><p class=MsoNormal>> > def removeUSE(self, USE):</p><p class=MsoNormal>> > def getUSE(self, USE = None):</p><p class=MsoNormal>> > def USE_changed(self, USE = None):</p><p class=MsoNormal>> > def class_(self):</p><p class=MsoNormal>> > def class_(self, value = None):</p><p class=MsoNormal>> > def setClass(self, class_ = None):</p><p class=MsoNormal>> > def addClass(self, class_ = None):</p><p class=MsoNormal>> > def removeClass(self, class_):</p><p class=MsoNormal>> > def getClass(self, class_ = None):</p><p class=MsoNormal>> > def class_changed(self, class_ = None):</p><p class=MsoNormal>> > def comments(self):</p><p class=MsoNormal>> > def comments(self, value = None):</p><p class=MsoNormal>> > def setComments(self, comments = None):</p><p class=MsoNormal>> > def addComments(self, comments = None):</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > [...]</p><p class=MsoNormal>> > class StringSensor(X3DKeyDeviceSensorNode):</p><p class=MsoNormal>> > def __init__(self, **kwargs):</p><p class=MsoNormal>> > def deletionAllowed(self):</p><p class=MsoNormal>> > def deletionAllowed(self, value = True):</p><p class=MsoNormal>> > def setDeletionAllowed(self, deletionAllowed = True):</p><p class=MsoNormal>> > def addDeletionAllowed(self, deletionAllowed = True):</p><p class=MsoNormal>> > def removeDeletionAllowed(self, deletionAllowed):</p><p class=MsoNormal>> > def isDeletionAllowed(self, deletionAllowed = True):</p><p class=MsoNormal>> > def enabled(self):</p><p class=MsoNormal>> > def enabled(self, value = True):</p><p class=MsoNormal>> > def setEnabled(self, enabled = True):</p><p class=MsoNormal>> > def addEnabled(self, enabled = True):</p><p class=MsoNormal>> > def removeEnabled(self, enabled):</p><p class=MsoNormal>> > def isEnabled(self, enabled = True):</p><p class=MsoNormal>> > def removeEnteredText(self, enteredText):</p><p class=MsoNormal>> > def getEnteredText(self, enteredText = None):</p><p class=MsoNormal>> > def enteredText_changed(self, enteredText = None):</p><p class=MsoNormal>> > def removeFinalText(self, finalText):</p><p class=MsoNormal>> > def getFinalText(self, finalText = None):</p><p class=MsoNormal>> > def finalText_changed(self, finalText = None):</p><p class=MsoNormal>> > def isActive(self, Active = None):</p><p class=MsoNormal>> > def metadata(self):</p><p class=MsoNormal>> > def metadata(self, value = None):</p><p class=MsoNormal>> > def setMetadata(self, metadata = None):</p><p class=MsoNormal>> > def addMetadata(self, metadata = None):</p><p class=MsoNormal>> > def removeMetadata(self, metadata):</p><p class=MsoNormal>> > def getMetadata(self, metadata = None):</p><p class=MsoNormal>> > def metadata_changed(self, metadata = None):</p><p class=MsoNormal>> > def DEF(self):</p><p class=MsoNormal>> > def DEF(self, value = None):</p><p class=MsoNormal>> > def setDEF(self, DEF = None):</p><p class=MsoNormal>> > def addDEF(self, DEF = None):</p><p class=MsoNormal>> > def removeDEF(self, DEF):</p><p class=MsoNormal>> > def getDEF(self, DEF = None):</p><p class=MsoNormal>> > def DEF_changed(self, DEF = None):</p><p class=MsoNormal>> > def USE(self):</p><p class=MsoNormal>> > def USE(self, value = None):</p><p class=MsoNormal>> > def setUSE(self, USE = None):</p><p class=MsoNormal>> > def addUSE(self, USE = None):</p><p class=MsoNormal>> > def removeUSE(self, USE):</p><p class=MsoNormal>> > def getUSE(self, USE = None):</p><p class=MsoNormal>> > def USE_changed(self, USE = None):</p><p class=MsoNormal>> > def class_(self):</p><p class=MsoNormal>> > def class_(self, value = None):</p><p class=MsoNormal>> > def setClass(self, class_ = None):</p><p class=MsoNormal>> > def addClass(self, class_ = None):</p><p class=MsoNormal>> > def removeClass(self, class_):</p><p class=MsoNormal>> > def getClass(self, class_ = None):</p><p class=MsoNormal>> > def class_changed(self, class_ = None):</p><p class=MsoNormal>> > def comments(self):</p><p class=MsoNormal>> > def comments(self, value = None):</p><p class=MsoNormal>> > def setComments(self, comments = None):</p><p class=MsoNormal>> > def addComments(self, comments = None):</p><p class=MsoNormal>> ></p><p class=MsoNormal>> > all the best, Don</p><p class=MsoNormal>> > --</p><p class=MsoNormal>> > Don Brutzman Naval Postgraduate School, Code USW/Br brutzman@nps.edu <mailto:brutzman@nps.edu> <mailto:brutzman@nps.edu <mailto:brutzman@nps.edu>></p><p class=MsoNormal>> > Watkins 270, MOVES Institute, Monterey CA 93943-5000 USA +1.831.656.2149</p><p class=MsoNormal>> > X3D graphics, virtual worlds, navy robotics http://faculty.nps.edu/brutzman</p><p class=MsoNormal>> ></p><p class=MsoNormal>> </p><p class=MsoNormal>> </p><p class=MsoNormal>> all the best, Don</p><p class=MsoNormal>> -- </p><p class=MsoNormal>> Don Brutzman Naval Postgraduate School, Code USW/Br brutzman@nps.edu <mailto:brutzman@nps.edu></p><p class=MsoNormal>> Watkins 270, MOVES Institute, Monterey CA 93943-5000 USA +1.831.656.2149</p><p class=MsoNormal>> X3D graphics, virtual worlds, navy robotics http://faculty.nps.edu/brutzman</p><p class=MsoNormal>> </p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>all the best, Don</p><p class=MsoNormal>-- </p><p class=MsoNormal>Don Brutzman Naval Postgraduate School, Code USW/Br brutzman@nps.edu</p><p class=MsoNormal>Watkins 270, MOVES Institute, Monterey CA 93943-5000 USA +1.831.656.2149</p><p class=MsoNormal>X3D graphics, virtual worlds, navy robotics http://faculty.nps.edu/brutzman</p><p class=MsoNormal><o:p> </o:p></p></div></body></html>