delConstraint() behavior

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
drmacro
Veteran
Posts: 8984
Joined: Sun Mar 02, 2014 4:35 pm

delConstraint() behavior

Post by drmacro »

Scenario:

create several constraints thusly:

Code: Select all

lock_x = DocSke.addConstraint(Sketcher.Constraint('DistanceX',Vert_ID,Pos_ID, sel_vec.x))
lock_y = DocSke.addConstraint(Sketcher.Constraint('DistanceY',Vert_ID,Pos_ID, sel_vec.y))
...and a bunch more...
later in code:

Code: Select all

DocSke.delConstraint(lock_x)
DocSke.delConstraint(lock_y)


Only constraint lock_x goes away, it appears lock_y does not because the list has changed.

Reverse order and both go.

Code: Select all

DocSke.delConstraint(lock_y)
DocSke.delConstraint(lock_x)


Noted while watching in debugger:
The constraint list doesn't seem to be orderly, i.e. constraints don't appear to be stored in the order created.

What is the correct way to delete specific constraints programmatically? (I.e. if other operations have reordered the list then the return ID (like lock_x/lock_y above) aren't reliable. for use later in removing constraints.

:?:
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
Syres
Veteran
Posts: 2900
Joined: Thu Aug 09, 2018 11:14 am

Re: delConstraint() behavior

Post by Syres »

drmacro wrote: Tue May 18, 2021 12:33 pm What is the correct way to delete specific constraints programmatically?
I can't say that this is example is the correct way to do it but I needed a way to delete all horizontal and vertical constraints on a ridiculously complex sketch and this is the way I got it work as best as I could:

Code: Select all

import FreeCAD
import Sketcher
try:
    # Get the Sketch that the user has selected
    s = FreeCADGui.Selection.getSelection()[0]
except:
    print('Nothing selected')

# Error check just incase silly user has selected a Part, Mesh etc
for selection in FreeCADGui.Selection.getSelectionEx():
    # Need to accommodate Python 3+ and Python 2_7 so check for both type names
    if str(type(selection.Object)) == "<class 'Sketcher.SketchObject'>" or str(type(selection.Object)) == "<type 'Sketcher.SketchObject'>":
        # print(s.Constraints)
        # Start the Constraint counter at Zero
        nextNumber = 0
        # Loop through all the Constraints to get the index
        for eachConstraint in s.Constraints:
            nextNumber = nextNumber + 1
        # In Reverse we need the total minus one as we are heading for Zero
        startNumberRev = nextNumber - 1
        # Loop from the highest Constraint Number to Zero, minus One each time
        for n in range(startNumberRev,-1,-1):
            # Loop within a Loop needs to start at Zero
            nextNumber = 0
            for eachConstraint in s.Constraints:
                # If the Outer Loop number matches the Inner Loop number then we have a matching Constraint
                if nextNumber == n:
                    # If the Constraint is either a Horizontal or Vertical type then we need to delete them
                    if eachConstraint.Type == 'Horizontal':
                        s.delConstraint(n)
                        print('Deleted Horizontal Constraint No. '+str(n))
                    if eachConstraint.Type == 'Vertical':
                        s.delConstraint(n)
                        print('Deleted Vertical Constraint No. '+str(n))
                    # No point in looping round if we've found a match so jump out of inner loop
                    break
                nextNumber = nextNumber + 1
    else:
        print('This does not work with anything other than a sketch')
print('Finished')
edi
Posts: 482
Joined: Fri Jan 17, 2020 1:32 pm

Re: delConstraint() behavior

Post by edi »

drmacro wrote: Tue May 18, 2021 12:33 pm The constraint list doesn't seem to be orderly, i.e. constraints don't appear to be stored in the order created.
The Constraint list is orderly. It is a Python list, which is organised as a stack. (The Geometry list is organised the same way)
Assume you have 10 constraints. If you delete number 6, the numbers of all constraints behind decrease by one. Old number 7 becomes new number 6 etc.

If you want to delete all constraints of a given type, e.g horizontal, you have to run through the list from end to start. Delete first the horizontal constraint having the highest number (you created last), and at last the horizontal constraint having the smalles number (you created first)
drmacro
Veteran
Posts: 8984
Joined: Sun Mar 02, 2014 4:35 pm

Re: delConstraint() behavior

Post by drmacro »

In this particular case, I was adding some constraints during the execution of the script, then after I was done with them, removing them.

I solved it by adding unique names to the ones I added.

Then when it came to removing them, I run through the list one time for each name, removing the constraint with the name when found.
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
Post Reply