Cancel
Showing results for 
Search instead for 
Did you mean: 

workPart attribute has 'NoneType' after loading existing part

Creator
Creator

I'm in the process of converting a C++ journal to Python journal for NX and as I'm getting started on debugging I've run into a problem I haven't been able to figure out yet. 

 

 

# nx:threaded
import pydevd
import math
import sys
import NXOpen
import NXOpen.Assemblies
from ImportComponents import importComp

pydevd.settrace()
def main( ) : 
	# collect input arguments, 1st arg = file name
	odString = sys.argv[0]
	ggiString = sys.argv[1] 
	offsetVal = sys.argv[2]
	partPath = sys.argv[3]
		
	try:
		theSession  = NXOpen.Session.GetSession() 
		fileNew1 = theSession.Parts.FileNew()	
		fileNew1.TemplateFileName = "Blank"	
		fileNew1.UseBlankTemplate = True	
		fileNew1.ApplicationName = "GatewayTemplate"	
		fileNew1.Units = NXOpen.Part.Units.Millimeters	
		fileNew1.RelationType = ""	
		fileNew1.UsesMasterModel = "No"	
		fileNew1.TemplateType = NXOpen.FileNewTemplateType.Item	
		fileNew1.TemplatePresentationName = ""	
		fileNew1.ItemType = ""	
		fileNew1.Specialization = ""	
		fileNew1.SetCanCreateAltrep(False)	
		fileNew1.NewFileName = partPath	
		fileNew1.MasterFileName = ""	
		fileNew1.MakeDisplayedPart = True
		workPart = theSession.Parts.Work # set work part

		# Importing assembly components
		print('Importing assembly components...\n')
		odComp = importComp.getComponent(odString, "MODEL", "DOMAIN")

which leads to

 

 

# nx:threaded
import pydevd
import math
import NXOpen
import NXOpen.Assemblies

pydevd.settrace()
class importComp:
	def __init__(self, name):
		self.name = name
	@staticmethod
	def getComponent( compPath, refSet, compName ):
		theSession  = NXOpen.Session.GetSession()
		workPart = theSession.Parts.Work
		part1, partLoadStatus1 = theSession.Parts.OpenBaseDisplay(compPath)
		partLoadStatus1.Dispose()
		
		basePoint1 = NXOpen.Point3d(0.0, 0.0, 0.0)
		orientation1 = NXOpen.Matrix3x3()
		
		orientation1.Xx = 1.0
		orientation1.Xy = 0.0
		orientation1.Xz = 0.0
		orientation1.Yx = 0.0
		orientation1.Yy = 1.0
		orientation1.Yz = 0.0
		orientation1.Zx = 0.0
		orientation1.Zy = 0.0
		orientation1.Zz = 1.0
		
		component1, partLoadStatus2 = workPart.ComponentAssembly.AddComponent(compPath, refSet, compName, basePoint1, orientation1, -1, True)
		
		partLoadStatus2.Dispose()
		
		return component1

 

which returns the error:

Traceback (most recent call last):
  File "C:\path\MeshOuterAssembly.py", line 41, in main
    odComp = importComp.getComponent(odString, "MODEL", "DOMAIN")
  File "C:\path\ImportComponents.py", line 46, in getComponent
    component1, partLoadStatus2 = workPart.ComponentAssembly.AddComponent(compPath, refSet, compName, basePoint1, orientation1, -1, True)
AttributeError: 'NoneType' object has no attribute 'ComponentAssembly'

now I'm not sure what's going on here exactly. I found this thread https://community.plm.automation.siemens.com/t5/NX-Programming-Customization-Forum/run-NxOpen-Python... and tried the various ways of opening a part and being explicit about workParts but so far no impacts on the workpart itself. 

 

I've been running this through Eclipse Photon with PyDev on NX 11.0.1

 

When I run it with OpenBaseDisplay() I can see the part being loaded, so I would imagine the loading went succesful but then workPart is still 'NoneType'. This is then an issue for the ComponentAssembly. 

 

I appreciate any feedback you may have. 

8 REPLIES

Re: workPart attribute has 'NoneType' after loading existing part

Switch the lines for assigning workPart =  and OpenBaseDisplay, that should do it.

Nikolas Losse | Developer | Siemens PG PR R&D TEC
NX12 | CentOS7 | Python

Re: workPart attribute has 'NoneType' after loading existing part

Creator
Creator

That worked to solve this issue, thank you for the quick reply!

 

It did pop up a new one immediately at the same point sadly

Traceback (most recent call last):
  File "C:\path\MeshOuterAssembly.py", line 41, in main
    odComp = importComp.getComponent(odString, "MODEL", "DOMAIN")
  File "C:\path\ImportComponents.py", line 45, in getComponent
    component1, partLoadStatus2 = workPart.ComponentAssembly.AddComponent(compPath, refSet, compName, basePoint1, orientation1, -1, True)
NXOpen.NXException: Attempt to load a cyclic assembly structure

I can open the part without any issues and the line itself is copied from a Python journal where I did those actions with that part. The variables just prior to executing that line 45 seemed in order. 

Re: workPart attribute has 'NoneType' after loading existing part

You are opening compPath, so that is workPart. Then you are adding compPath as new part to its own assembly. Is that intended? Seems like that could cause the "cyclic structure" complaint.

 

 

    AddComponent(partToAdd, referenceSetName, componentName, basePoint, orientation, layer)

 

 

Nikolas Losse | Developer | Siemens PG PR R&D TEC
NX12 | CentOS7 | Python

Re: workPart attribute has 'NoneType' after loading existing part

Creator
Creator

I'm creating a new part in which i'm adding the part located at compPath as a new component. When I recorded that as a journal it used the same path input for opening and adding a component. The same logic is present in the C++

 

Maybe the AddComponent part is just used to place it in a variable here so it can be refered to. 

 

Session *theSession = Session::GetSession();
	Part *workPart(theSession->Parts()->Work());
	PartLoadStatus *partLoadStatus1;
	Part *part1;
	part1 = theSession->Parts()->Open(compPath, &partLoadStatus1);
	delete partLoadStatus1;
	Point3d basePoint1(0.0, 0.0, 0.0);
	Matrix3x3 orientation1;
	orientation1.Xx = 1.0;
	orientation1.Xy = 0.0;
	orientation1.Xz = 0.0;
	orientation1.Yx = 0.0;
	orientation1.Yy = 1.0;
	orientation1.Yz = 0.0;
	orientation1.Zx = 0.0;
	orientation1.Zy = 0.0;
	orientation1.Zz = 1.0;
	PartLoadStatus *partLoadStatus2;
	Assemblies::Component *component1;
	component1 = workPart->ComponentAssembly()->AddComponent(compPath.GetText(), refSet.GetText(), compName.GetText(), basePoint1, orientation1, -1, &partLoadStatus2, true);
	delete partLoadStatus2;
	vector<Assemblies::Component *> compVect;
	compVect.push_back(component1);

Recorded Python journal

    basePart1, partLoadStatus1 = theSession.Parts.OpenBase("C:\Users\part.prt")    
    partLoadStatus1.Dispose()  
    part1 = theSession.Parts.Display    
    fullPath1 = workPart.FullPath    
    historyList1 = workPart.GetHistoryInformation()     
    basePoint1 = NXOpen.Point3d(0.0, 0.0, 0.0)
    orientation1 = NXOpen.Matrix3x3()    
    orientation1.Xx = 1.0
    orientation1.Xy = 0.0
    orientation1.Xz = 0.0
    orientation1.Yx = 0.0
    orientation1.Yy = 1.0
    orientation1.Yz = 0.0
    orientation1.Zx = 0.0
    orientation1.Zy = 0.0
    orientation1.Zz = 1.0
    component1, partLoadStatus2 = workPart.ComponentAssembly.AddComponent("C:\Users\part.prt", "refSet", "compName", basePoint1, orientation1, -1, True)    
    partLoadStatus2.Dispose()
    objects1 = []  

Re: workPart attribute has 'NoneType' after loading existing part

But in you c++ file you have workPart, which I assume is the newly created part, and part1, which is the existing part that is to be added as a component.

 

So you basically do workPart.addComponent(part1)

 

In your python script, you only have one part file, workPart.

 

So I think what is missing in you python script is the new file. Something like

 

newFile = createNewPart(...)

componentFile = openBase(path)

newFile.addComponent(componentFile)

 

For understanding:

The workPart is a special thing in NX, yes. But when you ask for Session.Parts.BaseWork, you just get a basePart reference. Nothing special about that other than that is currently is set as work part. But not changing when you then later switch the workPart.

When you call some file's addComponent method, you add the given component to that file. It doesn't have to be the current workPart.

Nikolas Losse | Developer | Siemens PG PR R&D TEC
NX12 | CentOS7 | Python

Re: workPart attribute has 'NoneType' after loading existing part

Creator
Creator
Your explanation makes a lot of sense. Considering I'm doing the file creation in the main.py (first code snippet) and the add component in a separate foo.py, should I add the newFile from main.py as an argument to foo.py?
Highlighted

Re: workPart attribute has 'NoneType' after loading existing part

That would be one option, and a good one too. Normally when I write functions like that I keep the part argument optional (with default part=None) and then have a block

 

 

    theSession = NXOpen.Session.GetSession()
    if part is None:
        workPart = theSession.Parts.BaseWork

in there.

 

 

Also I just figured out the real problem with your original code I think:

You never called

 

fileNew1.Commit()

so the new file didn't get created. That's why you had no workPart!

 

if you add that before your

 

workPart = theSession.Parts.Work # set work part

in the first snippet and switch the workPart and open part back in the second one it should work too.

 

 

 

Nikolas Losse | Developer | Siemens PG PR R&D TEC
NX12 | CentOS7 | Python

Re: workPart attribute has 'NoneType' after loading existing part

Creator
Creator
That definitely did the job! Thanks a lot for the helpful tips, much appreciated.