3

openstudio python bindings

I am dabbling with using the FreeCAD BIM Workbench to generate geometry for the .OSM file. FreeCAD is very powerful and has built-in Python capability. At this point, I can generate some simple spaces. However, I'd like to check adjacent surfaces and am running into a problem transferring the boost::optional approach from Ruby to Python. In Ruby, I would do the following (more or less, I am not in Ruby right now):

model.getSurfaces().each do |surface|
  adjacent_surface = surface.adjacentSurface()
  unless adjacent_surface.empty? then
    puts surface.name
    puts adjacent_surface.get.name
  end
end

With this, I would obtain just the names (simple strings) of surface and adjacent_surface, as desired.

In Python, I am trying the following:

for surface in model.getSurfaces():
  adjacent_surface = surface.adjacentSurface()
  if adjacent_surface is not None:
    print(surface.name)
    print(adjacent_surface.get.name)

But the "get.name" part in the last line results in this error: AttributeError: 'function' object has no attribute 'name'. And if I use just "get", the following is an example output:

<bound method IdfObject.name of <openstudio.openstudiomodelgeometry.Surface; proxy of <Swig Object of type 'std::vector< openstudio::model::Surface >::value_type *' at 0x7fea7ab0f870> >>

<bound method OptionalSurface.get of <openstudio.openstudiomodelgeometry.OptionalSurface; proxy of <Swig Object of type 'openstudio::model::OptionalSurface *' at 0x7fea66d46630> >>

That is to say, not even non-boost::optional surface shows the name. Both it and boost::optional adjacent_surface just show what appears to be a type or class specification. How can I get the simple name strings here?

mattkoch's avatar
1.1k
mattkoch
asked 2022-10-29 00:47:41 -0500
Aaron Boranian's avatar
14.1k
Aaron Boranian
updated 2022-10-29 07:27:37 -0500
edit flag offensive 0 remove flag close merge delete

Comments

Actually, using surface.name() rather than surface.name at least gets me surface name. However, using adjacent_surface.get() gets me a segmentation fault (core dumped) error.

mattkoch's avatar mattkoch (2022-10-29 00:58:14 -0500) edit
add a comment see more comments

1 Answer

4

OK, so it was late last night and I was tired. A little more digging this morning led me to try the following:

for surface in model.getSurfaces():
  adjacent_surface = surface.adjacentSurface()
  if adjacent_surface.is_initialized():
    print(surface.name())
    print(adjacent_surface.get().name())

Lo and behold, this provides the right solution. The issue was not so much with "get" or "name", but rather with the "if" statement. The "not None" approach allowed even an uninitialized adjacent_surface to be subjected to "get" or "name", and that obviously had to fail. The "is_initialized" approach prevents that. I guess I was misled by the "Ruby-empty" to "Python-Null" similarity. It also makes me wonder now whether I should use a "Ruby-is_initialized" rather than "Ruby-.empty?" approach, but that's another discussion.

mattkoch's avatar
1.1k
mattkoch
answered 2022-10-29 10:38:30 -0500
edit flag offensive 0 remove flag delete link

Comments

add a comment see more comments