Rebuilding a Loft shape...

Need help, or want to share a macro? Post here!
User avatar
Joel_graff
Posts: 1499
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Rebuilding a Loft shape...

Postby Joel_graff » Wed Jan 23, 2019 3:43 pm

I'm trying to sort out how to rebuild a loft using makeLoft().

Specifically, I am creating a technique which auto-generates several (10-1000 or more) wire sections that are derived from a master sketch. I then use Part.makeLoft() to generate a loft from a list of wire sections.

This works very well. However, if I change the master sketch and regenerate the wire sections, I now have the dilemma of figuring out how to recreate the Loft object in-place. Ideally, it would be best if I could just use:

Code: Select all

my_existing_loft_object.sections = section_list
But that doesn't work because the loft object requires the section list to be made up of document objects, which I don't have (and don't want) given there may be over 1,000 individual wire sections auto-generated from a single master sketch.

The other idea would be to reassign the loft shape using:

Code: Select all

my_existing_loft_object.Shape = Part.makeLoft(section_list, ...)
That seems to work. However, it creates an error in the GUI on the loft object telling me that the section list is empty (even though the loft regenerates).

From what I can tell, the loft section list is empty whenever you use makeLoft(), but it doesn't complain when I create it the first time - only when I attempt to reassign an existing loft's Shape.

Any thoughts on how I can sort this out? Maybe a way to generate a loft without using Part.makeLoft() but also without having to create each section as a DocumentObject?
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
User avatar
Chris_G
Posts: 1107
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Rebuilding a Loft shape...

Postby Chris_G » Wed Jan 23, 2019 4:31 pm

Are you trying to modify a Loft object created by the Gui of the Part WB ?
Then, I am afraid it won't be possible : this is a parametric object, that uses its Properties to generate its Shape.
Maybe you can reassign its Shape property but it will be temporary, and your modification will be overwritten at the next recompute of the Loft.
However, it will work on an simple Part::Feature :

Code: Select all

obj = FreeCAD.ActiveDocument.addObject("Part::Feature","My_Mega_Sweep")
obj.Shape = Part.makeLoft(list_of_wires)
User avatar
Joel_graff
Posts: 1499
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: Rebuilding a Loft shape...

Postby Joel_graff » Wed Jan 23, 2019 4:57 pm

Chris_G wrote:
Wed Jan 23, 2019 4:31 pm
Are you trying to modify a Loft object created by the Gui of the Part WB ?
Then, I am afraid it won't be possible : this is a parametric object, that uses its Properties to generate its Shape.
Maybe you can reassign its Shape property but it will be temporary, and your modification will be overwritten at the next recompute of the Loft.
However, it will work on an simple Part::Feature :
I'm creating a Part::Loft object in code. It's not generated from the WB.

In fact, here's some test code that describes what I'm really doing:

Code: Select all

    def buildLoft(self, loft, size):

        boxes = []

        for i in range(0, 10):

            y = float(i) * 100.0

            box = [
                App.Vector(0.0, y, 0.0),
                App.Vector(0.0, y, size),
                App.Vector(size, y, size),
                App.Vector(size, y, 0.0),
                App.Vector(0.0, y, 0.0)
            ]

            boxes += [Part.makePolygon(box)]

        if loft is None:
            loft = App.ActiveDocument.addObject('Part::Loft', 'Loft')

        loft.Shape = Part.makeLoft(boxes, False, True, False)

    def testLoftRebuild(self):

        loft = App.ActiveDocument.getObject('Loft')
        size = 10.0

        if loft:
            size = 20.0

        self.buildLoft(loft, size)
        
        App.ActiveDocument.recompute()
        
The loft object shows an error, specifying that there are no sections linked. That makes sense, since the sections are generated directly from polygons using makeLoft(), but it creates an unresolvable error, nonetheless.

Reassigning the shape works just fine, and has no effect on the error. I had initially assumed the error resulted from my effort to reassign a new loft to the existing Feature shape.

To address the immediate issue, I think either makeLoft() needs to provide a way to eliminate this error (which might end up polluting the document heirarchy with a lot of unwanted section polygons) or the loft object just has to accept lists of polygons in addition to lists of document objects as valid sections.
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
User avatar
Chris_G
Posts: 1107
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Rebuilding a Loft shape...

Postby Chris_G » Wed Jan 23, 2019 5:38 pm

IMHO, trying to modify a Part::Loft object this way is a non-sense.
I think you need to create your own FeaturePython object :

Code: Select all

class myLoft(object):
    def __init__(self, obj):
        obj.Proxy = self
        # obj.addProperty("App::PropertyLink", "MasterSketch") <- to build your boxes
        obj.addProperty("App::PropertyFloat","Size")
        obj.Size = 10
    def execute(self,fp):
        size = fp.Size
        boxes = []
        for i in range(0, 10):
            y = float(i) * 100.0
            box = [
                App.Vector(0.0, y, 0.0),
                App.Vector(0.0, y, size),
                App.Vector(size, y, size),
                App.Vector(size, y, 0.0),
                App.Vector(0.0, y, 0.0)
            ]
            boxes += [Part.makePolygon(box)]
        fp.Shape = Part.makeLoft(boxes, False, True, False)

obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","MyLoft")
myLoft(obj)
obj.ViewObject.Proxy = 0
        
User avatar
Joel_graff
Posts: 1499
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: Rebuilding a Loft shape...

Postby Joel_graff » Wed Jan 23, 2019 9:15 pm

Chris_G wrote:
Wed Jan 23, 2019 5:38 pm
IMHO, trying to modify a Part::Loft object this way is a non-sense.
I think you need to create your own FeaturePython object :
That's a possibility. I initially implemented the custom object as a DocumentObjectGroupPython class rather than an FPO to achieve the same result. The sketch and loft objects lived in the document group, and the group managed the loft reconstruction, much like you did with the FPO. I didn't want to show that here for the sake of clarity. I don't know that the custom group approach is paying off, though... Mostly, this has been a big exercise in organization. :/

Still, when I tested your FPO, the error (which was my reason for this post) went away. :)
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers