(self, path: List["OpenSCADObject"] = None)
return hole_kids
Because we don't force a copy every time we re-use a node
        (e.g a = cylinder(2, 6);  b = right(10) (a)
         the identical 'a' object appears in the tree twice),
        we can't count on an object's 'parent' field to trace its
        path to the root.  Instead, keep track explicitly
Because we don't force a copy every time we re-use a node
        (e.g a = cylinder(2, 6);  b = right(10) (a)
         the identical 'a' object appears in the tree twice),
        we can't count on an object's 'parent' field to trace its
        path to the root.  Instead, keep track explicitly
Because we don t force a copy every time we re - use a node ( e . g a = cylinder ( 2 6 ) ; b = right ( 10 ) ( a ) the identical a object appears in the tree twice ) we can t count on an object s parent field to trace its path to the root . Instead keep track explicitly
def find_hole_children(self, path: List["OpenSCADObject"] = None) -> List["OpenSCADObject"]:
        """
        Because we don't force a copy every time we re-use a node
        (e.g a = cylinder(2, 6);  b = right(10) (a)
         the identical 'a' object appears in the tree twice),
        we can't count on an object's 'parent' field to trace its
        path to the root.  Instead, keep track explicitly
        """
        path = path if path else [self]
        hole_kids = []

        for child in self.children:
            path.append(child)
            if child.is_hole:
                hole_kids.append(child)
                # Mark all parents as having a hole child
                for p in path:
                    p.has_hole_children = True
            # Don't append holes from separate parts below us
            elif child.is_part_root:
                continue
            # Otherwise, look below us for children
            else:
                hole_kids += child.find_hole_children(path)
            path.pop()

        return hole_kids
def find_hole_children ( self , path : List [ "OpenSCADObject" ] = None ) -> List [ "OpenSCADObject" ] : path = path if path else [ self ] hole_kids = [ ] for child in self . children : path . append ( child ) if child . is_hole : hole_kids . append ( child ) # Mark all parents as having a hole child for p in path : p . has_hole_children = True # Don't append holes from separate parts below us elif child . is_part_root : continue # Otherwise, look below us for children else : hole_kids += child . find_hole_children ( path ) path . pop ( ) return hole_kids