problem open file with error

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
Luixx
Posts: 213
Joined: Thu Jan 25, 2018 9:12 am

problem open file with error

Post by Luixx »

Open file without script receved error:

Code: Select all

22:11:13  <string>(1)<class 'AttributeError'>: Module __main__ has no class Bolt
22:11:13  <string>(1)<class 'AttributeError'>: Module __main__ has no class ViewProviderBolt
my script:

Code: Select all

import FreeCADGui
import FreeCAD
from FreeCAD import Base
import Part
import math

class Bolt:
    def __init__(self, obj):
        # Add some custom properties to the feature
        obj.addProperty("App::PropertyLength","d","Bolt","Nominal diameter").d=10.0
        obj.addProperty("App::PropertyLength","L","Bolt","Length of the bolt").L=50.0
        obj.addProperty("App::PropertyLength","K","Bolt","Height of the head of the bolt").K=6.4
        obj.addProperty("App::PropertyLength","S","Bolt","Width of the head of the nut").S=17.0
        obj.addProperty("App::PropertyLength","m","Bolt","Height of the nut").m=8.0
        obj.addProperty("App::PropertyLength","DistanceNutFromHead","Bolt","Distance of the nut from the head").DistanceNutFromHead=30.0
        obj.addProperty("App::PropertyLength","WasherDiameterExternal","Bolt","External diameter of washer").WasherDiameterExternal=22.0
        obj.addProperty("App::PropertyLength","WasherDiameterInternal","Bolt","External diameter of washer").WasherDiameterInternal=11.0
        obj.addProperty("App::PropertyLength","WasherThickness","Bolt","Thickness of the washer").WasherThickness=2.0
        obj.addProperty("App::PropertyBool","WasherUp","Bolt","Washer up").WasherUp=True
        obj.addProperty("App::PropertyBool","WasherDown","Bolt","Washer down").WasherDown=True
        obj.addProperty("App::PropertyBool","Accuracy","Bolt","Accuracy").Accuracy=False
        obj.Proxy = self

    def execute(self, fp):
        r = (fp.S/2) / math.cos( math.pi/6 )
        
        Solid = Part.makeCylinder( fp.d/2, fp.L )
        DT = fp.L
        if fp.WasherUp:
            DT -= fp.WasherThickness
        Solid.translate( Base.Vector(0,0,-DT) )
        
        if fp.K!=0:
            vertexes = []
            for i in range(0,7):
                vertexes.append(Base.Vector( r * math.cos(math.pi/6+i*math.pi/3), r * math.sin(math.pi/6+i*math.pi/3),0))
            Shape=Part.makePolygon(vertexes)
            Wire = Part.Wire(Shape.Edges)
            Face = Part.Face(Wire)
            NutSolid = Face.extrude(Base.Vector(0,0,fp.K))
            
            if fp.Accuracy:
                vertexes = []
                vertexes.append(Base.Vector(fp.S/2,0,fp.K))
                xTop = r * 1.1
                zTop = fp.K * 1.1
                vertexes.append(Base.Vector(fp.S/2,0,zTop))
                vertexes.append(Base.Vector(xTop,0,zTop))
                vertexes.append(Base.Vector(xTop,0, fp.K-(r-fp.S/2)*math.tan(math.pi/6.0)))
                vertexes.append(Base.Vector(r,0, fp.K-(r-fp.S/2)*math.tan(math.pi/6.0)))
                vertexes.append(Base.Vector(fp.S/2,0,fp.K))
                CutShape = Part.makePolygon(vertexes)
                CutWire = Part.Wire(CutShape.Edges)
                CutFace = Part.Face(CutWire)
                CutSolid = CutFace.revolve(Base.Vector(0,0,0), Base.Vector(0,0,1),360 )
                NutSolid = NutSolid.cut(CutSolid)
                vertexes = []
                vertexes.append(Base.Vector(fp.S/2,0,0))
                vertexes.append(Base.Vector(r,0,0))
                vertexes.append(Base.Vector(r,0, (r-fp.S/2)*math.tan(math.pi/6.0)))
                vertexes.append(Base.Vector(fp.S/2,0,0))
                CutShape=Part.makePolygon(vertexes)
                CutWire = Part.Wire(CutShape.Edges)
                CutFace = Part.Face(CutWire)
                CutSolid = CutFace.revolve(Base.Vector(0,0,0), Base.Vector(0,0,1),360 )
                NutSolid = NutSolid.cut(CutSolid)
            if fp.WasherUp:
                NutSolid.translate( Base.Vector(0,0,fp.WasherThickness) )    
            Solid = Solid.fuse(NutSolid)
        
        if fp.WasherUp:
            Washer = Part.makeCylinder( fp.WasherDiameterExternal/2, fp.WasherThickness )
            Washer.cut( Part.makeCylinder( fp.WasherDiameterInternal/2, fp.WasherThickness ) )
            Solid = Solid.fuse(Washer)
        
        if fp.WasherDown:
            Washer = Part.makeCylinder( fp.WasherDiameterExternal/2, fp.WasherThickness )
            Washer.cut( Part.makeCylinder( fp.WasherDiameterInternal/2, fp.WasherThickness ) )
            Washer.translate( Base.Vector(0,0,-(fp.DistanceNutFromHead+fp.WasherThickness) ) )
            Solid = Solid.fuse(Washer)
        
        if fp.m!=0:
            vertexes = []
            for i in range(0,7):
                vertexes.append(Base.Vector( r * math.cos(math.pi/6+i*math.pi/3), r * math.sin(math.pi/6+i*math.pi/3),0))
            Shape=Part.makePolygon(vertexes)
            Wire = Part.Wire(Shape.Edges)
            Face = Part.Face(Wire)
            NutSolid = Face.extrude(Base.Vector(0,0,fp.m))
            
            if fp.Accuracy:
                vertexes = []
                vertexes.append(Base.Vector(fp.S/2,0,fp.m))
                vertexes.append(Base.Vector(r,0,fp.m))
                vertexes.append(Base.Vector(r,0, fp.m-(r-fp.S/2)*math.tan(math.pi/6.0)))
                vertexes.append(Base.Vector(fp.S/2,0,fp.m))
                CutShape=Part.makePolygon(vertexes)
                CutWire = Part.Wire(CutShape.Edges)
                CutFace = Part.Face(CutWire)
                CutSolid = CutFace.revolve(Base.Vector(0,0,0), Base.Vector(0,0,1),360 )
                NutSolid = NutSolid.cut(CutSolid)
                vertexes = []
                vertexes.append(Base.Vector(fp.S/2,0,0))
                vertexes.append(Base.Vector(r,0,0))
                vertexes.append(Base.Vector(r,0, (r-fp.S/2)*math.tan(math.pi/6.0)))
                vertexes.append(Base.Vector(fp.S/2,0,0))
                CutShape=Part.makePolygon(vertexes)
                CutWire = Part.Wire(CutShape.Edges)
                CutFace = Part.Face(CutWire)
                CutSolid = CutFace.revolve(Base.Vector(0,0,0), Base.Vector(0,0,1),360 )
                NutSolid = NutSolid.cut(CutSolid)
            DT = fp.DistanceNutFromHead+fp.m
            if fp.WasherDown:
                DT += fp.WasherThickness
            NutSolid.translate( Base.Vector(0,0,-DT ) )
            Solid = Solid.fuse(NutSolid)
        
        fp.Shape = Solid

class ViewProviderBolt:
    def __init__(self, obj):
        # Set this object to the proxy object of the actual view provider
        obj.Proxy = self
    
    def getDefaultDisplayMode(self):
        # Return the name of the default display mode. It must be defined in getDisplayModes.
        return "Flat Lines"

def makeBolt():
    a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Bolt")
    Bolt(a)
    ViewProviderBolt(a.ViewObject)
    FreeCAD.ActiveDocument.recompute()

makeBolt()
idea?. Thanks.
User avatar
onekk
Veteran
Posts: 6208
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: problem open file with error

Post by onekk »

idea for what?

File what is?

1) the script file you have posted
2) some other file that refer to the script


script file is working as expected, a part from the lack of a check of an open document.

referring to:

Code: Select all

a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Bolt")
without having done a check that there is an "open document" and this document is active (sadly it is not same thing), lead to an error running scripts.

But the script is working and after having created some document with Gui, this image is shown and there are no errors emitted:
luix_bolt.png
luix_bolt.png (3.57 KiB) Viewed 408 times
At least in FreeCAD 0.19.24291 AppImage on Linux.

If you are trying to make it a standalone program and then you want use it with:

Code: Select all

import Bolt
you lack at least two things:

to run it standalone, you have to write:

Code: Select all

def makeBolt():
    a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Bolt")
    Bolt(a)
    ViewProviderBolt(a.ViewObject)
    FreeCAD.ActiveDocument.recompute()

if __name__ == "__main__":
	makeBolt()
and it could run as a standalone script, and importing it correctly, i.e adding the directory where it reside to the python path (or the freecad path in this case) and putting:

Code: Select all

import sys

MODULE_PATH = "path_to_the_library.py"

# don't forget to point to the file, if not you have to costruct a proper directory like you do when creating a python library.

if not MODULE_PATH in sys.path:
    print("no module path")
    sys.path.insert(1,MODULE_PATH)
else:
    print("module path is present")
    print(sys.path)

import libraryname
...

And probably freecad will find the library and import it correctly.

Probably because I have tested it only on Linux and some windows version expose some strange behaviour, this is less frequent for python 3.8 onward, as something has been done with path management in non posix environment, but having not a mean to test it on Windows, I could not guarantee.


Note that for some strange "persistence" it is not guaranteed that if you modify the source file of the library it is correctly imported with the modified lines, sometimes it reuse the "cached" version and it could appear that modified lines are not taken in account, expecially if the "library" is split in multiple files.

Generally if this behaviour appears, a FreeCAD restart is needed, I have already asked for some solutions, but still no answers.

Hope it helps

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Post Reply