Writing FEMAP Python script

Creator
Creator

Hello,

 

I was just assigned a new project to convert FEMAP VB scripts into python.  The "Writing the FEMAP API in Python" article in your Knowledge Base got me started, but now I'm hitting a roadblock.  Here's a python script that successfully opens a Nastran model and loads the results in FEMAP, but runs into an issue executing the command in green below.

 

import pythoncom
import Pyfemap
from Pyfemap import constants
import sys


try:
   existObj = pythoncom.connect(Pyfemap.model.CLSID) #Grabs active model
   app = Pyfemap.model(existObj) #Initializes object to active mode
except:
  sys.exit("femap not open") #Exits program if there is no active femap model

rc = app.feAppMessage(0,"Python API Example 1 Started")


# Read results
f1 = app.feFileNew()
app.feFileReadNastran(1,'D:\\FEMAP_python\\filename.nas')
app.feFileReadNeutral(1,'D:\\FEMAP_python\\filename.fno',True,True,True,True,0)

 

# Check element type
e1 = app.feElem
elSet = app.feSet

 

# Search for Linear Solid
SolidL = elSet.AddRule(25, FGD_ELEM_BYTYPE)  #the line item in question
SolidL = e1.GetAllArray(elSet.ID, numElem, entID, propID,elemType, topology, Lyr, color, formulation,orient,offset,release, orientSET, orientID, nodes, connectTYPE, connectSEG )
App.feSet.Reset()
App.feSet.DeleteAll()

 

Other than the python syntax, the code is similar to the VB script. I'm running Python3.6 and I get the following error...NameError: name 'FGD_ELEM_BYTYPE' is not defined

 

Any idea why I'm getting this error?  I just want to create the SolidL set with all elements type 25.

 

Your help on this matter is greatly appreciated.

 

- john

 

7 REPLIES 7

Re: Writing FEMAP Python script

Siemens Phenom Siemens Phenom
Siemens Phenom

FGD_ELEM_BYTYPE is simply a FEMAP constant.  Since you've already used "from Pyfemap import constants" at the beginning, I think you simply need to change your line to:

 

SolidL = elSet.AddRule(25, constants.FGD_ELEM_BYTYPE)

Re: Writing FEMAP Python script

Creator
Creator

Thank you.  That solved that problem and now I'm getting NameError:  name 'numElem' is not define on the next line.

 

SolidL = e1.GetAllArray(elSet.ID,numElem, entID, propID,elemType, topology, Lyr, color, formulation,orient,offset,release, orientSET, orientID, nodes, connectTYPE, connectSEG )

 

I assume a similar problem will exists for for entID, propID, elemType, etc.  In VB, I declared them as 

 

Dim numElem As Long
Dim entID As Variant
Dim propID As Variant
Dim elemType As Variant
Dim topology As Variant
Dim Lyr As Variant
Dim color As Variant
Dim formulation As Variant
Dim orient As Variant
Dim offset As Variant
Dim release As Variant
Dim orientSET As Variant
Dim orientID As Variant
Dim nodes As Variant
Dim connectTYPE As Variant
Dim connectSEG As Variant

 

Referencing Femap->Help->Programming->Contents->API, I'm figuring out the subtleties on what changes I need to make when coverting VB commands to python.

Re: Writing FEMAP Python script

Siemens Phenom Siemens Phenom
Siemens Phenom

Python does not support the pass by reference output assignment the way the native BASIC API does.  There is an easy fix, you simply have to put 'Output' to the left of the equals, making sure to include an empty variable for the Return Code (rc).  I've atttached a .docx that goes through Python information in relation to FEMAP.

 

Conveniently, Python does not require dimensioning which makes a function like GetArray with many parameters a breeze to populate.

 

I believe your script should ultimately look like this:

 

#Start Script...

import pythoncom
import Pyfemap
from Pyfemap import constants
import sys


try:
   existObj = pythoncom.connect(Pyfemap.model.CLSID) #Grabs active model
   app = Pyfemap.model(existObj) #Initializes object to active mode
except Exception as err:
  #sys.exit("femap not open") #Exits program if there is no active femap model
  print('Could not connect to FEMAP')
  raise SystemExit(0)

rc = app.feAppMessage(0,"Python API Example 1 Started")


# Read results
f1 = app.feFileNew()
app.feFileReadNastran(1,'D:\\FEMAP_python\\filename.nas')
app.feFileReadNeutral(1,'D:\\FEMAP_python\\filename.fno',True,True,True,True,0)
 

# Check element type
e1 = app.feElem
elSet = app.feSet
         

# Search for Linear Solid
SolidL = elSet.AddRule(25, constants.FGD_ELEM_BYTYPE)  #the line item in question
#SolidL = e1.GetAllArray(elSet.ID, numElem, entID, propID,elemType, topology, Lyr, color, formulation,orient,offset,release, orientSET, orientID, nodes, connectTYPE, connectSEG )
[rc, numElem, entID, propID,elemType, topology, Lyr, color, formulation,orient,offset,release, orientSET, orientID, nodes, connectTYPE, connectSEG] = e1.GetAllArray(elSet.ID)

#App.feSet.Reset()
#App.feSet.DeleteAll()
elSet.Reset()
elSet.DeleteAll()

Re: Writing FEMAP Python script

Creator
Creator

Thank you for the document and providing more insight from VB to python.  Going to review the document and make the appropriate adjustments.  

Re: Writing FEMAP Python script

Creator
Creator

Hello again.

 

Reading the Using the FEMAP API was really helpful.  I specifically read the Working with Views section to prepare for the Postprocessing portion of the VB script.   

 

The VB code sets the following values:  Elements that Pass = 0 (No Labels) and Criteria Limits to 3 (Between). 

 

Dim fview As femap.View
Set fview = fApp.feView

 

fview.Contour = 2 # turn on criteria
fview.Label(FVI_CRITERIA_PASS)=0
fview.Label(FVI_CRITERIA_LIMITS)=3

fview.CriteriaMax=1.1
fview.CriteriaMin=0.5

 

Seems straight forward in python, but I get a SyntaxError: can't assign to function call for the two fview.Label.  No problems assigning valueus to Contour, CriteriaMax/Min.

 

Once I get past this, I'll start working on other fview APIs: Rotate, Put, Regenerate, AutoscaleAll.

Re: Writing FEMAP Python script

Siemens Phenom Siemens Phenom
Siemens Phenom

Ah yes, this is due to Python not liking values assigned to properties.  Fortunately, Pyfemap has a work around using .Set[propertyName].

 

You should end up with something like this...

 

 

import pythoncom
import Pyfemap
from Pyfemap import constants
import sys


try:
   existObj = pythoncom.connect(Pyfemap.model.CLSID) #Grabs active model
   app = Pyfemap.model(existObj) #Initializes object to active mode
except Exception as err:
  print(err)
  print('Could not connect to FEMAP')
  raise SystemExit(0)

rc = app.feAppMessage(0,"Python API Example 1 Started")

[rc, viewID] = app.feAppGetActiveView() #Get active view

fview = app.feView

# **********************************************************************************************************
#   In Pyfemap...
#    # The method Label is actually a property, but must be used as a method to correctly pass the arguments
#    def Label(self, nVectorIndex=defaultNamedNotOptArg):
#        return self._oleobj_.InvokeTypes(18014, LCID, 2, (3, 0), ((3, 1),),nVectorIndex
#            )
    
    # The method SetLabel is actually a property, but must be used as a method to correctly pass the arguments
#    def SetLabel(self, nVectorIndex=defaultNamedNotOptArg, arg1=defaultUnnamedArg):
#        return self._oleobj_.InvokeTypes(18014, LCID, 4, (24, 0), ((3, 1), (3, 1)),nVectorIndex
#            , arg1)

# **********************************************************************************************************

fview.Get(viewID) #Grab the view from FEMAP
fview.Contour = 2
fview.SetLabel(constants.FVI_CRITERIA_PASS,0)   #Use Set[propertyName] when writing values to Properties
fview.SetLabel(constants.FVI_CRITERIA_LIMITS,1)
fview.Put(viewID)

app.feViewRegenerate(viewID)
raise SystemExit(0)

Re: Writing FEMAP Python script

Creator
Creator

Thank you again.  Applied your answer to fview.SetDraw(constants.FVI_Node, False)