Scripted parts properties

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
JohanL
Posts: 7
Joined: Tue Jul 01, 2014 1:57 pm

Scripted parts properties

Post by JohanL »

Hi all,

I have scripted some parts with properties everything works fine except when I reopen a file containing scripted parts.
When I reopen the file and want to change a property of the script these are not executed and I get the following error message:

<unknown exception traceback><type 'exceptions.AttributeError'>: 'module' object has no attribute 'ScripedPartModuleName'
<unknown exception traceback><type 'exceptions.AttributeError'>: 'NoneType' object has no attribute 'execute'


Is there anything that describes where to locate your scripts and what the necessary steps are to prevent these errors?

Any help would be appreciated

Johan
User avatar
shoogen
Veteran
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Scripted parts properties

Post by shoogen »

For example In your PYTHONPATH or in the FreeCAD /Mod directory.
JohanL
Posts: 7
Joined: Tue Jul 01, 2014 1:57 pm

Re: Scripted parts properties

Post by JohanL »

I've done this but still doesn't work. If I check he path from the python console it is correct but still the same error.
wmayer
Founder
Posts: 20309
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Scripted parts properties

Post by wmayer »

For serialization of scripted objects we use JSON which doesn't support any kind of objects. For instance, objects from extension modules can't be serialized this way. So, when saving your project the first time do you see any error messages in the output window?
JohanL
Posts: 7
Joined: Tue Jul 01, 2014 1:57 pm

Re: Scripted parts properties

Post by JohanL »

No error are displayed when saving the file
wmayer
Founder
Posts: 20309
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Scripted parts properties

Post by wmayer »

Can you maybe upload your script or a demo of it which shows the problem?
JohanL
Posts: 7
Joined: Tue Jul 01, 2014 1:57 pm

Re: Scripted parts properties

Post by JohanL »

I have attached a cut down version of the script, same problem with this or more complicated script. This one creates a simple cube (not with the cube version) but problem is the same. When executed all is fine and the properties can be changed, this is not possible if the file is closed and reopened. Maybe there is something missing ???

Thx in advance
Test.FCStd
The Script
(2.89 KiB) Downloaded 57 times
User avatar
shoogen
Veteran
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Scripted parts properties

Post by shoogen »

You uploaded a FreeCAD file which can't, by design, contain any python code.

Code: Select all

<Property name="Proxy" type="App::PropertyPythonObject"><Python value="{}"  module="__main__" class="EasiAccessFront"/>
<Property name="Proxy" type="App::PropertyPythonObject"><Python value="0"  json="yes"/>
i already did the base64 decoding. The ViewProvider Proxy is 0. Which should work perfectly.
But the module for the Object Proxy should not be __main__
JohanL
Posts: 7
Joined: Tue Jul 01, 2014 1:57 pm

Re: Scripted parts properties

Post by JohanL »

Sorry uploaded the result file, hereby the script.

This means I have to remove the part

Code: Select all

if __name__ == "__main__":
	MakeEasiAccessFront()
from the script?

Attachment of .py file is not allowed, hereby the source code

Code: Select all

import sys
import os
import math
import FreeCAD
import FreeCADGui
import Part


from FreeCAD import Base

FreeCADPath = ''

if "FREECADPATH" in os.environ:
	FreeCADPath = os.environ.get("FREECADPATH")

IsFreeCADGui = True
if not(FreeCADPath in sys.path):
	IsFreeCADGui = False

if not(IsFreeCADGui):
	sys.path.append(FreeCADPath)
	

class EasiAccessFront:

	def __init__(self, obj):
		obj.addProperty("App::PropertyFloat","CoverWidth","Parameters","Cover Width").CoverWidth = 400.0
		obj.addProperty("App::PropertyFloat","CoverHeight","Parameters","Cover Height").CoverHeight = 400.0

		obj.Proxy = self
	def onChanged(self, fp, prop):
 		"'''Do something when a property has changed (eg. Check bounderies)'''"

 
 	def execute(self, fp):
 		"'''Do something when doing a recomputation, this method is mandatory'''"
		Front = self.CreateFront(fp)
		
		Fused3D = Front
	
		fp.Shape = Fused3D
		FreeCAD.Console.PrintMessage("============================================================================================================================\n")

	def CreateFront(self, fp):
		FreeCAD.Console.PrintMessage("\tEassiAccessFront.CreateFront()\n")

		X0Y0 = Base.Vector(0.0, 0.0, 0.0)
		X1Y0 = X0Y0 + Base.Vector(fp.CoverWidth, 0.0)
		X1Y1 = X1Y0 + Base.Vector(0.0, fp.CoverHeight)
		X0Y1 = X0Y0 + Base.Vector(0.0, fp.CoverHeight)

		L1 = Part.Line(X0Y0, X1Y0)
		L2 = Part.Line(X1Y0, X1Y1)
		L3 = Part.Line(X1Y1, X0Y1)
		L4 = Part.Line(X0Y1, X0Y0)


		FreeCAD.Console.PrintMessage("\t\tL1[X0Y0, X1Y0]={0}\n".format(L1))
		FreeCAD.Console.PrintMessage("\t\tL2[X1Y0, X1Y1]={0}\n".format(L2))
		FreeCAD.Console.PrintMessage("\t\tL3[X1Y1, X0Y1]={0}\n".format(L3))
		FreeCAD.Console.PrintMessage("\t\tL4[X0Y1, X0Y0]={0}\n".format(L4))

		Front2D = Part.Shape([L1, L2, L3, L4])
		WireFrame = Part.Wire(Front2D.Edges)
		Face = Part.Face(WireFrame)
		Front3D = Face.extrude(Base.Vector(0.0,0.0,2.5))
		return Front3D

def MakeEasiAccessFront(Name = None):
	doc = FreeCAD.activeDocument()
	if doc == None:
		doc = FreeCAD.newDocument()
	Cover=doc.addObject("Part::FeaturePython","EasiAccessFront") #add object to document
	if Name is None:
		Cover.Label = "Easi Access Front"
	else:
		Cover.Label = Name
	EasiAccessFront(Cover)
	Cover.ViewObject.Proxy=0
	doc.recompute()
	return Cover

if __name__ == "__main__":
	MakeEasiAccessFront()

User avatar
shoogen
Veteran
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Scripted parts properties

Post by shoogen »

No, that aspect is fine.
The Problem is that actually run the module in which you define your classes. This way your module gains the __main__ namespace. And FreeCAD can't determine the name of the module which has to be imported when loading back your FCStd files.
I would suggest to split your code into two modules. One with the main program, which has an import statement for the module containing the classes.
Maybe we can fix freecad to extract the module name form the __file__ of the script you are running, in future versions.
Post Reply