Scripted object doesn't reopens after document closure

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
RafaelRS
Posts: 7
Joined: Tue Sep 17, 2019 7:30 am

Scripted object doesn't reopens after document closure

Post by RafaelRS »

I have following macro:

Code: Select all

class LProfile:

	def __init__(self,obj):
		obj.Proxy = self
		obj.addProperty("App::PropertyLength","Length","Profile")
		obj.addProperty("App::PropertyLength","Side1Width","Profile")
		obj.addProperty("App::PropertyLength","Side2Width","Profile")
		obj.addProperty("App::PropertyLength","Depth","Profile")
		obj.addProperty("App::PropertyLength","Side1HolesOffset","Profile")
		obj.addProperty("App::PropertyLength","Side2HolesOffset","Profile")
		obj.addProperty("App::PropertyLength","Side1HolesRadius","Profile")
		obj.addProperty("App::PropertyLength","Side2HolesRadius","Profile")
		obj.addProperty("App::PropertyInteger","Side1HolesQty","Profile")
		obj.addProperty("App::PropertyInteger","Side2HolesQty","Profile")

	def execute(self,obj):

		import Part,FreeCAD
		
		# Safety check
		if (obj.Length == 0) or (obj.Side1Width == 0) or (obj.Side2Width == 0) or (obj.Depth == 0):
			return
		 
		# Create profile points for edges
		v1 = FreeCAD.Vector(0,0,0)
		v2 = FreeCAD.Vector(0,obj.Side1Width,0)
		v3 = FreeCAD.Vector(0,obj.Side1Width,obj.Depth)
		v4 = FreeCAD.Vector(0,obj.Depth,obj.Depth)
		v5 = FreeCAD.Vector(0,obj.Depth,obj.Side2Width)
		v6 = FreeCAD.Vector(0,0,obj.Side2Width)
		
		# Create profile edges
		e1 = Part.LineSegment(v1,v2).toShape()
		e2 = Part.LineSegment(v2,v3).toShape()
		e3 = Part.LineSegment(v3,v4).toShape()
		e4 = Part.LineSegment(v4,v5).toShape()
		e5 = Part.LineSegment(v5,v6).toShape()
		e6 = Part.LineSegment(v6,v1).toShape()
		
		# Create profile shape and extrude
		wire = Part.Wire([e1,e2,e3,e4,e5,e6])
		profileFace = Part.Face(wire)
		profile = profileFace.extrude(FreeCAD.Vector(obj.Length,0,0))

		# Make holes on side 1
		if (obj.Side1HolesQty == 1):
			position = FreeCAD.Vector(obj.Length / 2,obj.Side1Width / 2,0)
			cylinder = Part.makeCylinder(obj.Side1HolesRadius,obj.Depth,position,FreeCAD.Vector(0,0,1))
			profile = profile.cut(cylinder)
		elif  (obj.Side1HolesQty > 1):
			side1HolesDistance = (obj.Length - 2 * obj.Side1HolesOffset) / (obj.Side1HolesQty - 1)
			for i in range(obj.Side1HolesQty):
				position = FreeCAD.Vector(obj.Side1HolesOffset + i * side1HolesDistance,obj.Side1Width / 2,0)
				cylinder = Part.makeCylinder(obj.Side1HolesRadius,obj.Depth,position,FreeCAD.Vector(0,0,1))
				profile = profile.cut(cylinder)
		
		# Make holes on side 2
		if (obj.Side2HolesQty == 1):
			position = FreeCAD.Vector(obj.Length / 2,0,obj.Side2Width / 2)
			cylinder = Part.makeCylinder(obj.Side2HolesRadius,obj.Depth,position,FreeCAD.Vector(0,1,0))
			profile = profile.cut(cylinder)
		elif  (obj.Side2HolesQty > 1):
			side2HolesDistance = (obj.Length - 2 * obj.Side2HolesOffset) / (obj.Side2HolesQty - 1)
			for i in range(obj.Side2HolesQty):
				position = FreeCAD.Vector(obj.Side2HolesOffset + i * side2HolesDistance,0,obj.Side2Width / 2)
				cylinder = Part.makeCylinder(obj.Side2HolesRadius,obj.Depth,position,FreeCAD.Vector(0,1,0))
				profile = profile.cut(cylinder)

		# All shapes have a Placement too. We give our shape the value of the placement
		# set by the user. This will move/rotate the face automatically.
		profile.Placement = obj.Placement
		
		# all done, we can attribute our shape to the object!
		obj.Shape = profile

class ViewProviderLProfile:

	def __init__(self, obj):
		''' Set this object to the proxy object of the actual view provider '''
		obj.Proxy = self

	def attach(self, obj):
		''' Setup the scene sub-graph of the view provider, this method is mandatory '''
		return

	def updateData(self, fp, prop):
		''' If a property of the handled feature has changed we have the chance to handle this here '''
		return

	def getDisplayModes(self,obj):
		''' Return a list of display modes. '''
		modes=[]
		return modes

	def getDefaultDisplayMode(self):
		''' Return the name of the default display mode. It must be defined in getDisplayModes. '''
		return "Shaded"

	def setDisplayMode(self,mode):
		''' Map the display mode defined in attach with those defined in getDisplayModes.
		Since they have the same names nothing needs to be done. This method is optional.
		'''
		return mode

	def onChanged(self, vp, prop):
		''' Print the name of the property that has changed '''
		FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")

	def getIcon(self):
		return """
		/* XPM */
		static char * LProfile_xpm[] = {
		"32 32 180 2",
		"  	c None",
		". 	c #000000",
		"+ 	c #555570",
		"@ 	c #6A6A8B",
		"# 	c #2C2C34",
		"$ 	c #3B2D17",
		"% 	c #453209",
		"& 	c #382A10",
		"* 	c #44310A",
		"= 	c #463209",
		"- 	c #565670",
		"; 	c #60607D",
		"> 	c #2D2A2D",
		", 	c #403016",
		"' 	c #3A2B0F",
		") 	c #3F2E0D",
		"! 	c #515168",
		"~ 	c #312D2F",
		"{ 	c #3E2E13",
		"] 	c #392A10",
		"^ 	c #412F0C",
		"/ 	c #322E30",
		"( 	c #392C16",
		"_ 	c #3C2C0D",
		": 	c #3F2E0C",
		"< 	c #3C2C0E",
		"[ 	c #42300B",
		"} 	c #9B7733",
		"| 	c #E3AB34",
		"1 	c #DDA733",
		"2 	c #A77E29",
		"3 	c #43310A",
		"4 	c #9D7833",
		"5 	c #E8AF35",
		"6 	c #B68A2B",
		"7 	c #45310A",
		"8 	c #443209",
		"9 	c #9E7933",
		"0 	c #43300B",
		"a 	c #4F3A13",
		"b 	c #402E0D",
		"c 	c #392B0F",
		"d 	c #533D12",
		"e 	c #976D15",
		"f 	c #563F12",
		"g 	c #3B2C0F",
		"h 	c #8B661A",
		"i 	c #BC891E",
		"j 	c #795817",
		"k 	c #9F7933",
		"l 	c #BA9432",
		"m 	c #E0B038",
		"n 	c #927124",
		"o 	c #3D2D0D",
		"p 	c #44300B",
		"q 	c #E0C350",
		"r 	c #FCDC5A",
		"s 	c #A38D38",
		"t 	c #3D2D0E",
		"u 	c #402E0B",
		"v 	c #E5BC47",
		"w 	c #FACF4F",
		"x 	c #947A2E",
		"y 	c #3E2D0D",
		"z 	c #402F0C",
		"A 	c #9F7A33",
		"B 	c #402E0C",
		"C 	c #BF9028",
		"D 	c #D39F2C",
		"E 	c #654C18",
		"F 	c #3F2F0C",
		"G 	c #44310B",
		"H 	c #986E19",
		"I 	c #A6781A",
		"J 	c #664A14",
		"K 	c #6A4D14",
		"L 	c #A07A33",
		"M 	c #42300D",
		"N 	c #3B2B0F",
		"O 	c #372910",
		"P 	c #A17B32",
		"Q 	c #3E2D0C",
		"R 	c #3D2C0C",
		"S 	c #3E2D0E",
		"T 	c #6E5014",
		"U 	c #AE8020",
		"V 	c #E5C44C",
		"W 	c #EDC64C",
		"X 	c #B18322",
		"Y 	c #735315",
		"Z 	c #402F0D",
		"` 	c #3E2E0D",
		" .	c #563F11",
		"..	c #88641B",
		"+.	c #B2973B",
		"@.	c #B6973A",
		"#.	c #8A671C",
		"$.	c #574012",
		"%.	c #3C2C0F",
		"&.	c #C9982F",
		"*.	c #896721",
		"=.	c #7C5D1D",
		"-.	c #6E5219",
		";.	c #543F15",
		">.	c #382A0F",
		",.	c #3A2A0D",
		"'.	c #A27C32",
		").	c #DEA733",
		"!.	c #D6A131",
		"~.	c #CD9B30",
		"{.	c #C4942E",
		"].	c #BB8D2C",
		"^.	c #B3872A",
		"/.	c #A77E27",
		"(.	c #9D7624",
		"_.	c #8C6921",
		":.	c #7E5F1D",
		"<.	c #674D19",
		"[.	c #554015",
		"}.	c #443311",
		"|.	c #3A2B0E",
		"1.	c #3C2D0E",
		"2.	c #422F0B",
		"3.	c #3A2F23",
		"4.	c #E9B035",
		"5.	c #E5AD34",
		"6.	c #E2AA34",
		"7.	c #D9A432",
		"8.	c #D19E31",
		"9.	c #C6962F",
		"0.	c #44310D",
		"a.	c #322A22",
		"b.	c #FFFFFF",
		"c.	c #755A2C",
		"d.	c #AC8231",
		"e.	c #B5882C",
		"f.	c #BA8D31",
		"g.	c #C3932E",
		"h.	c #C39432",
		"i.	c #CB992F",
		"j.	c #DCA633",
		"k.	c #E1AA34",
		"l.	c #3A2A0F",
		"m.	c #412F0E",
		"n.	c #372E26",
		"o.	c #83839C",
		"p.	c #6A6A7F",
		"q.	c #84849D",
		"r.	c #43434D",
		"s.	c #3B3B44",
		"t.	c #3A3A43",
		"u.	c #1B1D21",
		"v.	c #312D2C",
		"w.	c #3A2E1F",
		"x.	c #745A2C",
		"y.	c #9C7528",
		"z.	c #A77F30",
		"A.	c #B4882D",
		"B.	c #B78B31",
		"C.	c #BB8D2E",
		"D.	c #BB8E31",
		"E.	c #C0912E",
		"F.	c #C79630",
		"G.	c #D29F31",
		"H.	c #DAA433",
		"I.	c #E6AE35",
		"J.	c #EAB035",
		"K.	c #342715",
		"L.	c #2F2925",
		"M.	c #505061",
		"N.	c #656578",
		"O.	c #3C3C45",
		"P.	c #212328",
		"Q.	c #00192D",
		"R.	c #000922",
		"S.	c #56452A",
		"T.	c #7B5E25",
		"U.	c #906E2E",
		"V.	c #222328",
		"W.	c #565666",
		". + @ @ # $ % % & * = = = = = = = = = = = = = = = = = = = = = = ",
		". - ; > , % * ' % = = = = = = = = = = = = = = = = = = = = = = ) ",
		". ! ~ { % * ] % = = = = = = = = = = = = = = = = = = = = = = ' ^ ",
		". / ( _ : ' = = = = = = = = = = = = = = = = = = = = = = = < [ % ",
		". } | 1 2 = = = = = = = = = = = = = = = = = = = = = = = & 3 % % ",
		". 4 5 5 6 = = = = = = = = = = = = = = = = = = = = = 7 ' 8 % % % ",
		". 9 5 5 6 = = = = = = = = = = = = = = = = = = = = 7 ] 8 % % % % ",
		". 9 5 5 6 = = = = 0 a b = = = = = = = = = = = = 0 c % % % % % % ",
		". 9 5 5 6 = = = = d e f = = = = = = = = = = = * g % % % % % % % ",
		". 9 5 5 6 = = = = h i j = = = = = = = = = = ^ g % % % % % % % % ",
		". k 5 5 6 = = = = l m n = = = = = = = = = ^ o % % % % % % % % % ",
		". k 5 5 6 = = = p q r s = = = = = = = = ) t % % % % % % % % % % ",
		". k 5 5 6 = = = u v w x = = = = = = = y z % % % % % % % % % % % ",
		". A 5 5 6 = = = B C D E = = = = = = t F % % % % % % % % % % % % ",
		". A 5 5 6 = = = G H I y = = = = = g [ % % % % % % % % % % % % % ",
		". A 5 5 6 = = = = J K = = = = = g [ % % % % % % % % % % % % % % ",
		". L 5 5 6 = = = = M b = = = = & 3 % % % % % % % % % % % % % % % ",
		". L 5 5 6 = = = = = = = = = N * % % % % % % % % % % % % % % % % ",
		". L 5 5 6 = = = = = = = * O % % % % % % % % % % % % % % % % % % ",
		". L 5 5 6 = = = = = = 0 < % % % % % % % % % % % % % % % % % % % ",
		". P 5 5 6 = = = = = 0 ] % % % % % % % % % % % % % % % % % % % % ",
		". P 5 5 6 = = = = z y % % % % % % % % % % % % % % % % % % % % % ",
		". P 5 5 6 = = = ^ < % % % % % % [ Q R [ % % % % % % % % % % % % ",
		". P 5 5 6 = = S : % % % % % ) T U V W X Y Z % % % % % % % % % [ ",
		". P 5 5 6 = ) ` % % % % % % [  ...+.@.#.$.[ % % % % % % % % ) %.",
		". P 5 5 6 g ^ % % % % % % % % % % % % % % % % % % % % % % F ) = ",
		". P 5 5 &.*.=.-.;.>.,.B [ % % % % % % % % % % % % % % % t ) = * ",
		". '.5 5 5 5 5 5 5 5 ).!.~.{.].^./.(._.:.<.[.}.|.Q [ * 1.2.= 0 3.",
		". '.5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4.5.6.7.8.9.] = 0.a.b.",
		". c.d.e.f.g.h.i.8.j.k.4.4.5 5 5 5 5 5 5 5 5 5 5 5 5 4.l.m.n.. o.",
		". p.q.. . . r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.5.I.5 J.K.L.. q.q.",
		". M.N.N.N.N.N.N.N.N.N.N.N.N.N.N.N.. . . O.P.Q.R.S.T.U.V.W.N.N.N."};
			"""

	def __getstate__(self):
		'''When saving the document this object gets stored using Python's json module.\
		        Since we have some un-serializable parts here -- the Coin stuff -- we must define this method\
		        to return a tuple of all serializable objects or None.'''
		return None
		
	def __setstate__(self,state):
		'''When restoring the serialized object from document we have the chance to set some internals here.\
		        Since no data were serialized nothing needs to be done here.'''
		return None


myObj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","LProfile")
LProfile(myObj)
myObj.ViewObject.Proxy = 0 # this is mandatory unless we code the ViewProvider too
myObj.Length = 500
myObj.Side1Width = 40
myObj.Side2Width = 40
myObj.Depth = 3
myObj.Side1HolesOffset = 50
myObj.Side2HolesOffset = 50
myObj.Side1HolesRadius = 4
myObj.Side2HolesRadius = 2
myObj.Side1HolesQty = 3
myObj.Side2HolesQty = 4
ViewProviderLProfile(myObj.ViewObject)

FreeCAD.ActiveDocument.recompute()
I saved macro as LProfile.py

It creates object, and it looks normal, as expected, acts as expected, haves icon.
ksnip_20191024-122234.png
ksnip_20191024-122234.png (68.01 KiB) Viewed 992 times

Now if i save such document, close, and reopen, then:
FreeCAD 0.18.3 crashes
FreeCAD_0.19-18589-Linux-Conda_Py3Qt5_glibc2.12-x86_64.AppImage says:

Code: Select all

created object
<string>(2)<class 'AttributeError'>: Module __main__ has no class LProfile
<string>(2)<class 'AttributeError'>: Module __main__ has no class ViewProviderLProfile
container changed from None to _
And in document tree object icon flip to default (Part box)
ksnip_20191024-122416.png
ksnip_20191024-122416.png (68.01 KiB) Viewed 992 times

Why is that? What i am doing wrong?
Last edited by RafaelRS on Thu Oct 24, 2019 9:27 am, edited 2 times in total.
RafaelRS
Posts: 7
Joined: Tue Sep 17, 2019 7:30 am

Re: Scripted object doesn't reopens after document closure

Post by RafaelRS »

I tested same on newly installed FreeCAD 0.16 on Centos 7, same result:

Code: Select all

<unknown exception traceback><type 'exceptions.AttributeError'>: 'module' object has no attribute 'LProfile'
<unknown exception traceback><type 'exceptions.AttributeError'>: 'module' object has no attribute 'ViewProviderLProfile'
RafaelRS
Posts: 7
Joined: Tue Sep 17, 2019 7:30 am

Re: Scripted object doesn't reopens after document closure

Post by RafaelRS »

I solved issue by typing in console:

Code: Select all

>>> from LProfile import LProfile
>>> from LProfile import ViewProviderLProfile
That thing wasn't mentioned in documentation:
https://www.freecadweb.org/wiki/Manual: ... ic_objects

Stills feeling, that this action shouldn't be required and i missed some things?
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Scripted object doesn't reopens after document closure

Post by microelly2 »

The macro file must exists in a directory which is coverd by the sys.path list.
only in this case the classes can be loaded on demand and applied to the object.
RafaelRS
Posts: 7
Joined: Tue Sep 17, 2019 7:30 am

Re: Scripted object doesn't reopens after document closure

Post by RafaelRS »

microelly2 wrote: Thu Oct 24, 2019 10:29 am The macro file must exists in a directory which is coverd by the sys.path list.
only in this case the classes can be loaded on demand and applied to the object.
Well, print(sys.path) gives me:
['/tmp/.mount_FreeCAWmqUwV/usr/lib/python3.7/site-packages/git/ext/gitdb'
'/home/rafaelrs/.FreeCAD/Mod/BIM'
'/home/rafaelrs/.FreeCAD/Mod/lattice2'
'/home/rafaelrs/.FreeCAD/Mod/fasteners'
'/home/rafaelrs/.FreeCAD/Mod/BOLTSFC'
'/home/rafaelrs/.FreeCAD/Mod/pcb'
'/home/rafaelrs/.FreeCAD/Mod/sheetmetal'
'/home/rafaelrs/.FreeCAD/Mod/CfdOF'
'/home/rafaelrs/.FreeCAD/Mod/Cfd'
'/home/rafaelrs/.FreeCAD/Mod/Render'
'/home/rafaelrs/.FreeCAD/Mod/Part-o-magic'
'/home/rafaelrs/.FreeCAD/Mod/parts_library'
'/home/rafaelrs/.FreeCAD/Mod/FCGear'
'/home/rafaelrs/.FreeCAD/Mod/DesignSPHysics'
'/home/rafaelrs/.FreeCAD/Mod/3D_Printing_Tools'
'/home/rafaelrs/.FreeCAD/Mod/dxf-library'
'/home/rafaelrs/.FreeCAD/Mod/Curves'
'/home/rafaelrs/.FreeCAD/Mod/dodo'
'/home/rafaelrs/.FreeCAD/Mod/CurvedShapes'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Web'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Tux'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Test'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/TechDraw'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Surface'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Start'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Spreadsheet'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Sketcher'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Show'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Robot'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/ReverseEngineering'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Raytracing'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Points'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Path'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/PartDesign'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Part'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/OpenSCAD'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/MeshPart'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Mesh'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Measure'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Material'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Inspection'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Import'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Image'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Idf'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Fem'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Drawing'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Draft'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Complete'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/Arch'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod/AddonManager'
'/tmp/.mount_FreeCAWmqUwV/usr/Mod'
'/tmp/.mount_FreeCAWmqUwV/usr/lib'
'/tmp/.mount_FreeCAWmqUwV/usr/Ext'
'/tmp/.mount_FreeCAWmqUwV/usr/bin'
'/tmp/.mount_FreeCAWmqUwV/usr/lib/python37.zip'
'/tmp/.mount_FreeCAWmqUwV/usr/lib/python3.7'
'/tmp/.mount_FreeCAWmqUwV/usr/lib/python3.7/lib-dynload'
'/home/rafaelrs/.local/lib/python3.7/site-packages'
'/tmp/.mount_FreeCAWmqUwV/usr/lib/python3.7/site-packages'
'/home/rafaelrs/.FreeCAD/Macro'
'/tmp/.mount_FreeCAWmqUwV/usr/Macro'
'/home/rafaelrs/.FreeCAD/Mod/Curves/Gui'
'/tmp/.mount_FreeCAWmqUwV/usr/lib/python3.7/site-packages/gitdb/ext/smmap']
And:
 ~ ls -l /home/rafaelrs/.FreeCAD/Macro/
total 32
lrwxrwxrwx. 1 rafaelrs rafaelrs 66 Sep 19 13:06 DesignSPHysics.FCMacro -> /home/rafaelrs/.FreeCAD//Mod/DesignSPHysics/DesignSPHysics.FCMacro
-rw-rw-r--. 1 rafaelrs rafaelrs 10764 Oct 24 12:52 LProfile.py
-rw-------. 1 rafaelrs rafaelrs 5112 Oct 24 01:24 LProfile.xpm
lrwxrwxrwx. 1 rafaelrs rafaelrs 63 Sep 19 22:13 PartsLibrary.FCMacro -> /home/rafaelrs/.FreeCAD//Mod/parts_library/PartsLibrary.FCMacro
drwxrwsr-x. 2 rafaelrs rafaelrs 4096 Oct 24 12:52 __pycache__
lrwxrwxrwx. 1 rafaelrs rafaelrs 56 Sep 19 12:51 start_bolts.FCMacro -> /home/rafaelrs/.FreeCAD//Mod/BOLTSFC/start_bolts.FCMacro
RafaelRS
Posts: 7
Joined: Tue Sep 17, 2019 7:30 am

Re: Scripted object doesn't reopens after document closure

Post by RafaelRS »

Ok, i found reason.

Executable bit should be set for LProfile.py.

Now i see another problem. When i start FreeCAD and then open my file, addtional LProfile object was created and there some errors:
ksnip_20191024-141448.png
ksnip_20191024-141448.png (25.94 KiB) Viewed 972 times
Now, if i close document and open it again it will be OK. I think that during first open were import performing which caused code of object creating in end of LProfile.py was executed (and must be some errors happened and we see recompute errors).

What i should do in this case? My first thought is split code to two files:
LProfile.py - only classes
LProfileBuilder.py - code to create LProfile object.

Is that it's how should be done, or there another more proper way?
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Scripted object doesn't reopens after document closure

Post by microelly2 »

RafaelRS wrote: Thu Oct 24, 2019 11:19 am
Now i see another problem. When i start FreeCAD and then open my file, addtional LProfile object was created and there some errors:
ksnip_20191024-141448.png
you should put the creation code into a function.
with your code the creation is started when the macro files is loaded

here an example
https://github.com/microelly2/NodeEdito ... owGraph.py

how I create my object:
I import the moduel and than I call the creator

Code: Select all

from nodeeditor.PyFlowGraph import PyFlowGraph
def saveGraph():
	instance=pfwrap.getInstance()
	saveData = instance.graphManager.get().serialize()
	a=PyFlowGraph()
	a.graph=str(saveData)
RafaelRS
Posts: 7
Joined: Tue Sep 17, 2019 7:30 am

Re: Scripted object doesn't reopens after document closure

Post by RafaelRS »

Thanks, microelly2, for your answers, but i didn't fully understood what you said.

However, i've found good fast solution.
1. As you said, move creation inside function
2. Call function only following 'if' passed:

Code: Select all

if __name__ == "__main__":
It took idea from https://github.com/ncsaba/freecad-scrip ... ew.FCMacro
Finally tail of my script looks like following:

Code: Select all

def makeLProfile():
	myObj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","LProfile")
	LProfile(myObj)
	myObj.Length = 500
	myObj.Side1Width = 40
	myObj.Side2Width = 40
	myObj.Depth = 3
	myObj.Side1HolesOffset = 50
	myObj.Side2HolesOffset = 50
	myObj.Side1HolesRadius = 4
	myObj.Side2HolesRadius = 2
	myObj.Side1HolesQty = 3
	myObj.Side2HolesQty = 4
	ViewProviderLProfile(myObj.ViewObject)
	
	FreeCAD.ActiveDocument.recompute()

if __name__ == "__main__":
	makeLProfile()
Everything works good now!

I think will be good to fix executable bit in FreeCAD for macros. Also do correction to article:
https://www.freecadweb.org/wiki/Manual: ... ic_objects
Post Reply