[solved problem] Script crash freecad 0.20

Need help, or want to share a macro? Post here!
Luixx
Posts: 207
Joined: Thu Jan 25, 2018 9:12 am

[solved problem] Script crash freecad 0.20

Post by Luixx »

Hi, my code experimental bolt .. my hobby prorgramming. My code:

Code: Select all

# -*- coding: utf-8 -*-

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

class Bolt:
    def __init__(self, name):
        self.name = name
        self.obj = None

    def makeBolt(self):
        bolt=FreeCAD.ActiveDocument.addObject("Part::FeaturePython", self.name)
        bolt.addProperty("App::PropertyLength","d","Bolt","Nominal diameter").d=10.0
        bolt.addProperty("App::PropertyLength","L","Bolt","Length of the bolt").L=50.0
        bolt.addProperty("App::PropertyLength","K","Bolt","Height of the head of the bolt").K=6.4
        bolt.addProperty("App::PropertyLength","S","Bolt","Width of the head of the nut").S=17.0
        bolt.addProperty("App::PropertyLength","m","Bolt","Height of the nut").m=8.0
        bolt.addProperty("App::PropertyLength","DistanceNutFromHead","Bolt","Distance of the nut from the head").DistanceNutFromHead=30.0
        bolt.addProperty("App::PropertyLength","WasherDiameterExternal","Bolt","External diameter of washer").WasherDiameterExternal=22.0
        bolt.addProperty("App::PropertyLength","WasherDiameterInternal","Bolt","External diameter of washer").WasherDiameterInternal=11.0
        bolt.addProperty("App::PropertyLength","WasherThickness","Bolt","Thickness of the washer").WasherThickness=2.0
        bolt.addProperty("App::PropertyBool","WasherUp","Bolt","Washer up").WasherUp=True
        bolt.addProperty("App::PropertyBool","WasherDown","Bolt","Washer down").WasherDown=True
        bolt.addProperty("App::PropertyBool","Accuracy","Bolt","Accuracy").Accuracy=False
        self.obj = bolt

        ViewProviderBolt(bolt.ViewObject)
        FreeCAD.ActiveDocument.recompute()


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 updateData(self, fp, prop):

        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
        return
Crash freecad

Code: Select all

OS: Windows 10 Version 2009
Word size of FreeCAD: 64-bit
Version: 0.20.29177 (Git)
Build type: Release
Branch: releases/FreeCAD-0-20
Hash: 68e337670e227889217652ddac593c93b5e8dc94
Python 3.8.10, Qt 5.15.2, Coin 4.0.1, Vtk 8.2.0, OCC 7.6.2
Locale: Italian/Italy (it_IT)
Installed mods: 
  * A2plus 0.4.56a
  * Curves 0.5.0
  * Fasteners 0.3.46
  * gears 1.0.0
  * la_freecad
  * Pyramids-and-Polyhedrons
  * SheetMetal 0.2.49
Idea ?

How to solid part create function ?

thanks.
My elementary english from italy.
Last edited by Luixx on Wed Jul 06, 2022 4:15 pm, edited 1 time in total.
User avatar
onekk
Veteran
Posts: 2759
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Script crash freecad 0.20

Post by onekk »

My English and Italian Scripting Guide https://github.com/onekk/freecad-doc.
My Blog: https://onekk-maker.blogspot.com/

To help development see on GitHub Page

For enquiry about customized FC Scripting job PM me.
User avatar
dprojects
Posts: 430
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: Script crash freecad 0.20

Post by dprojects »

I am not sure if I correctly use your library but I run at mu slow laptop Asus X55U something like that:

Code: Select all

b = Bolt("boldtest")
b.makeBolt()
and the FreeCAD remains in dead wood ;-) I had to kill the FreeCAD window manually ;-)

Maybe there is somewhere infinite loop, if the FreeCAD reach "out of memory" finally it crash. I observed crashing 0.20 several times because of "out of memory". I hope 0.20 is not last lightweight FreeCAD version and it will not remain into heavy piece of junk like other paid CAD software ;-)

But regarding you bolt library, it is interesting to me because I have at woodworking workbench magicDowels tool and it can add Cylinders in right place very quickly. Next step will be replace all the referencing mounting points made by Cylinders with realistic looking screws, dowels and other mounting pins.

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking

I don't want to kill anyone LOL, is it still OK to be for total free?
User avatar
onekk
Veteran
Posts: 2759
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Script crash freecad 0.20

Post by onekk »

dprojects wrote: Tue Jul 05, 2022 9:36 am Maybe there is somewhere infinite loop, if the FreeCAD reach "out of memory" finally it crash. I observed crashing 0.20 several times because of "out of memory".
In fact it seems that OP code is not properly created as in the code examples I linked.

I've experimented with FPO (FeaturePython Object) and they seem the most correct way to add new "types" of Objects.

Even the OP ViewProvider Object code seems not respect what I've been told to create.

From what I was told there are some methods (functions) that has to be implemented eventually leaving them void so probably it is some glitch somewhere.

The only suggestion I could give is to add some print() statement to have some idea about the order of execution and maybe if some action is executed when other actions are triggered.

I've had some problem as some actions were "re-executed" because when some properties were changed a recompute() was forced, only with the print() trick I have pointed out the problem and asked for advices on how to avoid it.

Regards

Carlo D.
My English and Italian Scripting Guide https://github.com/onekk/freecad-doc.
My Blog: https://onekk-maker.blogspot.com/

To help development see on GitHub Page

For enquiry about customized FC Scripting job PM me.
User avatar
dprojects
Posts: 430
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: Script crash freecad 0.20

Post by dprojects »

onekk wrote: Tue Jul 05, 2022 11:09 am In fact it seems that OP code is not properly created as in the code examples I linked.
The problem with FreeCAD crashes via script is little more deeper. It is strongly connected with FreeCAD code approach. This is observed also with library Qt dependencies many years ago. Script should never crash FreeCAD, it should work like in the sandbox, like a rock, never crash or hang. But world is not perfect so the code never be perfect too, there is no perfect code anywhere.

So, my unpopular opinion, that for sure badly will hurt lovers of C++, is that features should never be coded in C++ (period !). C++ should be banned for features in serious, reliable, code, it should be allowed only for extremely well described and extremely well managed memory management place by C++ masters, not by anyone. Constructors and destructors should be rethinked very deeply in one place, not everywhere in every occasion on your own ;-)

The war of C ++ lovers will begin in a 3, 2, 1 .... ;-) LOL

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking

I don't want to kill anyone LOL, is it still OK to be for total free?
User avatar
onekk
Veteran
Posts: 2759
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Script crash freecad 0.20

Post by onekk »

dprojects wrote: Tue Jul 05, 2022 12:49 pm ...
I think that sanboxing the scripting engine, at least in FC is not very easy, as you have to make a sort of "virtual machine", some things could be done activating some flags in preferences, where a local environment is set for a running script.

But this will not work as example if the things not working is a WB.

And I think that also "crash" is not correct, as the problem seems to be an "hang" probably caused by some "programming loop".

It is like you made some mistake when setting something in an OS and you have to use a "recovery install" or similar workaround, forcing the OS to run with only his "minimal working set of libraries" to permit a diagnose and a recovery.

But as usual, it depends on what the base code is and on other things, even some speed considerations.

But this is clearly OT and without an OP intervention, further discussions are not useful.

Regards

Carlo D.
My English and Italian Scripting Guide https://github.com/onekk/freecad-doc.
My Blog: https://onekk-maker.blogspot.com/

To help development see on GitHub Page

For enquiry about customized FC Scripting job PM me.
User avatar
dprojects
Posts: 430
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: Script crash freecad 0.20

Post by dprojects »

I rewrite your code using this page here: Create_a_FeaturePython_object_part_II but there was infinite loop too. Looks like this line below make the problem. The Solid object is probably not created correctly so the FreeCAD is not able to parse it.

Code: Select all

        fp.Shape = Solid

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking

I don't want to kill anyone LOL, is it still OK to be for total free?
Luixx
Posts: 207
Joined: Thu Jan 25, 2018 9:12 am

Re: Script crash freecad 0.20

Post by Luixx »

ok, my solution:

Code: Select all

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

class Bolt:
    def __init__(self, obj, name):
        self.name = name
        # Add some custom properties to the feature
        obj.addProperty("App::PropertyString","name","Bolt","Nome").name=name
        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(name):
    a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython", name)
    Bolt(a, name)
    ViewProviderBolt(a.ViewObject)
    FreeCAD.ActiveDocument.recompute()

Code: Select all

import la_freecad.bolt as bolt
bolt.makeBolt("vite")
My writing library parametric .. problem solved bolt classs.
thanks.
User avatar
dprojects
Posts: 430
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: Script crash freecad 0.20

Post by dprojects »

Luixx wrote: Wed Jul 06, 2022 12:49 pm My writing library parametric ..
What do you mean by "library parametric" ? sounds like some kind of rocket science ;-) is it differ from normal library? what makes the library parametric?

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking

I don't want to kill anyone LOL, is it still OK to be for total free?
Luixx
Posts: 207
Joined: Thu Jan 25, 2018 9:12 am

Re: Script crash freecad 0.20

Post by Luixx »

Upload github experimental - my studing github.
Link:
https://github.com/luigi-amorfini/la_freecad

installed %AppData%/FreeCAD/Mod/

use macro test experiment.

Code: Select all

from la_freecad import *

length,  width, height = 250, 80, 40

box1 = Cube("cubo1")
print("init box")
box1.create(length,  width, height)
print("create box")
box1.placement(FreeCAD.Placement(App.Vector(0,0,0), App.Rotation(App.Vector(0,0,0),45), App.Vector(0,0,0)))
print("place box")

in new document adding other object on document.

thanks.
Post Reply