TheHubbit / PyInventor

3D Graphics in Python with Open Inventor
http://thehubbit.github.io/PyInventor
BSD 3-Clause "New" or "Revised" License
16 stars 8 forks source link

Engines don't provide any outputs #6

Closed InventorMentor closed 7 years ago

InventorMentor commented 7 years ago

Hi Thomas,

Thank you very much indeed for contributing and sharing PyInventor! I really do enjoy experimenting with it and would appreciate it very much if you could please make a design proposal how to extend PyInventor in order to support Inventor engines for animated / interactive scenes.

As of PyInventor-1.0, engines don't seem to provide any outputs (fields to connect to). For animation purposes, it would also be helpful to have access and make field connections to the global realtime field and set/get its temporal resolution. Would addding the global realtime field to PyInventor be a "low hanging fruit"?

Otherwise, I would also be grateful if you could please make a proposal how I can add the global realtime field to PyInventor.

Many thanks indeed in advance!

Best, Peter.

TheHubbit commented 7 years ago

Hi Peter, Thank you for your message! I really appreciate your feedback. It is a funny coincidence that a few weeks ago was wondering about the same issue but ended up getting caught up in a lot of work related things. There are two areas that need work. First, the C++ binding must be extended to better support engine inputs and outputs. Second, the scene editor should also display engines (as children of nodes?). The first thing being a prerequisite for the latter. Let me check the code again to refresh my memory. I appreciate you offering to help with that too. Are you familiar with both C and Python, or mostly Python? Let me take a look at the code and refresh my memory. Then I can give some more detailed pointers.

Best, Thomas

InventorMentor commented 7 years ago

Hi Thomas,

 

Many thanks, I do appreciate your swift reply. To this end, my programming experience has mostly been using APIs, not providing them. Nevertheless, I could contribute to debugging, testing and eventually to its implementation itself in both C and Python, if I knew the direction to take or where to technically deep dive. Maybe you could point me to a reference where I can learn about your chosen approach for interfacing C with Python.

 

On the C++ side of Open Inventor, class SoEngineOutput seems to encapsulate the output fields of an engine instance providing methods such as

 

void addConnection (SoField f) void removeConnection (SoField f) SoFieldContainer getFieldContainer (void) SoField operator[] (int i) const

 

that would presumably have to be called from within PyInventor's implementation to support engine outputs and to enable a Python programmer to make field connections to them. A general solution requires presumably a decent understanding of Open Inventor engines and also decent technical expertise interfacing C with Python.

 

Best, Peter

 

Gesendet: Montag, 20. März 2017 um 06:22 Uhr Von: Thomas notifications@github.com An: TheHubbit/PyInventor PyInventor@noreply.github.com Cc: InventorMentor inventor_mentor@gmx.de, Author author@noreply.github.com Betreff: Re: [TheHubbit/PyInventor] Engines don't provide any outputs (#6)

Hi Peter, Thank you for your message! I really appreciate your feedback. It is a funny coincidence that a few weeks ago was wondering about the same issue but ended up getting caught up in a lot of work related things. There are two areas that need work. First, the C++ binding must be extended to better support engine inputs and outputs. Second, the scene editor should also display engines (as children of nodes?). The first thing being a prerequisite for the latter. Let me check the code again to refresh my memory. I appreciate you offering to help with that too. Are you familiar with both C and Python, or mostly Python? Let me take a look at the code and refresh my memory. Then I can give some more detailed pointers.

Best, Thomas

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

 

TheHubbit commented 7 years ago

I verified today that connecting engine outputs to fields is already supported, for example:

import inventor as iv
s = iv.Sphere()
s.connect("radius", iv.Calculator("expression \"oa = 1.234\""), "oa")
s.radius

Furthermore I added the getoutputs() method to the Python wrapper. Peter, please see at the last commit to see how methods are added to a Python class.

>>> c = iv.Calculator()
>>> c.getoutputs()
[('oa', 'MFFloat'), ('ob', 'MFFloat'), ('oc', 'MFFloat'), ('od', 'MFFloat'), ('oA', 'MFVec3f'), ('oB', 'MFVec3f'), ('oC', 'MFVec3f'), ('oD', 'MFVec3f')]

Next the QInspectorWidget.py needs to be enhanced to show connected engines. This follows a model view design for Qt as described here: http://www.yasinuludag.com/blog/?p=98 This is all a bit complicated as the Qt model just redirects to the inventor scenegraph. I can't really give more directions right now as I'm not sure myself yet what the best approach for engines in the model is.

InventorMentor commented 7 years ago

Hi Thomas,

Many thanks indeed for your swift clarification. Now I can also confirm your verfication and I can see where I was wrong. My apologies, there was a misunderstanding on my part, interpreting PyInventor's "connect" method for making field connections wrongly as "connect object's A field x >to< object's B field y" rather than the correct semantic "connect object's A field x >from< an other object's B field y".

 

objectA.connect("x", objectB, "y")   # connect(...) now understood as connectFrom(...) rather than connectTo(...)

 

Now I'm happy again. Next, I'm going to examine how to implement callbacks using PyInventor. Many thanks again!

Best, Peter

 

TheHubbit commented 7 years ago

I added Python types for fields and engine outputs for better connection handling. Use get_field() and get_output() to access those objects. For example:

import inventor as iv

sphere = iv.Sphere()
calculator = iv.Calculator('a 1.234 expression "oa = a * 2"')
sphere.get_field('radius').connect_from(calculator.get_output('oa'))
print(sphere.radius)