(curve, parbox, **kwargs)
Checks if the trim curve was closed and sense was set.

    :param curve: trim curve
    :param parbox: parameter space bounding box of the underlying surface
    :return: a tuple containing the status of the operation and list of extra trim curves generated
    :rtype: tuple
Checks if the trim curve was closed and sense was set.
Checks if the trim curve was closed and sense was set .
def check_trim_curve(curve, parbox, **kwargs):
    """ Checks if the trim curve was closed and sense was set.

    :param curve: trim curve
    :param parbox: parameter space bounding box of the underlying surface
    :return: a tuple containing the status of the operation and list of extra trim curves generated
    :rtype: tuple
    """
    def next_idx(edge_idx, direction):
        tmp = edge_idx + direction
        if tmp < 0:
            return 3
        if tmp > 3:
            return 0
        return tmp

    # Keyword arguments
    tol = kwargs.get('tol', 10e-8)

    # First, check if the curve is closed
    dist = linalg.point_distance(curve.evalpts[0], curve.evalpts[-1])
    if dist <= tol:
        # Curve is closed
        return detect_sense(curve, tol), []
    else:
        # Define start and end points of the trim curve
        pt_start = curve.evalpts[0]
        pt_end = curve.evalpts[-1]

        # Search for intersections
        idx_spt = -1
        idx_ept = -1
        for idx in range(len(parbox) - 1):
            if detect_intersection(parbox[idx], parbox[idx + 1], pt_start, tol):
                idx_spt = idx
            if detect_intersection(parbox[idx], parbox[idx + 1], pt_end, tol):
                idx_ept = idx

        # Check result of the intersection
        if idx_spt < 0 or idx_ept < 0:
            # Curve does not intersect any edges of the parametric space
            # TODO: Extrapolate the curve using the tangent vector and find intersections
            return False, []
        else:
            # Get sense of the original curve
            c_sense = curve.opt_get('reversed')

            # If sense is None, then detect sense
            if c_sense is None:
                # Get evaluated points
                pts = curve.evalpts
                num_pts = len(pts)

                # Find sense
                tmp_sense = 0
                for pti in range(1, num_pts - 1):
                    tmp_sense = detect_ccw(pts[pti - 1], pts[pti], pts[pti + 1], tol)
                    if tmp_sense != 0:
                        break
                if tmp_sense == 0:
                    tmp_sense2 = detect_ccw(pts[int(num_pts/3)], pts[int(2*num_pts/3)], pts[-int(num_pts/3)], tol)
                    if tmp_sense2 != 0:
                        tmp_sense = -tmp_sense2
                    else:
                        # We cannot decide which region to trim. Therefore, ignore this curve.
                        return False, []

                c_sense = 0 if tmp_sense > 0 else 1

                # Update sense of the original curve
                curve.opt = ['reversed', c_sense]

            # Generate a curve container and add the original curve
            cont = [curve]

            move_dir = -1 if c_sense == 0 else 1

            # Curve intersects with the edges of the parametric space
            counter = 0
            while counter < 4:
                if idx_ept == idx_spt:
                    counter = 5
                    pt_start = curve.evalpts[0]
                else:
                    # Find next index
                    idx_ept = next_idx(idx_ept, move_dir)
                    # Update tracked last point
                    pt_start = parbox[idx_ept + 1 - c_sense]
                    # Increment counter
                    counter += 1

                # Generate the curve segment
                crv = shortcuts.generate_curve()
                crv.degree = 1
                crv.ctrlpts = [pt_end, pt_start]
                crv.knotvector = [0, 0, 1, 1]
                crv.opt = ['reversed', c_sense]

                pt_end = pt_start

                # Add it to the container
                cont.append(crv)

            # Update curve
            return True, cont
def check_trim_curve ( curve , parbox , * * kwargs ) : def next_idx ( edge_idx , direction ) : tmp = edge_idx + direction if tmp < 0 : return 3 if tmp > 3 : return 0 return tmp # Keyword arguments tol = kwargs . get ( 'tol' , 10e-8 ) # First, check if the curve is closed dist = linalg . point_distance ( curve . evalpts [ 0 ] , curve . evalpts [ - 1 ] ) if dist <= tol : # Curve is closed return detect_sense ( curve , tol ) , [ ] else : # Define start and end points of the trim curve pt_start = curve . evalpts [ 0 ] pt_end = curve . evalpts [ - 1 ] # Search for intersections idx_spt = - 1 idx_ept = - 1 for idx in range ( len ( parbox ) - 1 ) : if detect_intersection ( parbox [ idx ] , parbox [ idx + 1 ] , pt_start , tol ) : idx_spt = idx if detect_intersection ( parbox [ idx ] , parbox [ idx + 1 ] , pt_end , tol ) : idx_ept = idx # Check result of the intersection if idx_spt < 0 or idx_ept < 0 : # Curve does not intersect any edges of the parametric space # TODO: Extrapolate the curve using the tangent vector and find intersections return False , [ ] else : # Get sense of the original curve c_sense = curve . opt_get ( 'reversed' ) # If sense is None, then detect sense if c_sense is None : # Get evaluated points pts = curve . evalpts num_pts = len ( pts ) # Find sense tmp_sense = 0 for pti in range ( 1 , num_pts - 1 ) : tmp_sense = detect_ccw ( pts [ pti - 1 ] , pts [ pti ] , pts [ pti + 1 ] , tol ) if tmp_sense != 0 : break if tmp_sense == 0 : tmp_sense2 = detect_ccw ( pts [ int ( num_pts / 3 ) ] , pts [ int ( 2 * num_pts / 3 ) ] , pts [ - int ( num_pts / 3 ) ] , tol ) if tmp_sense2 != 0 : tmp_sense = - tmp_sense2 else : # We cannot decide which region to trim. Therefore, ignore this curve. return False , [ ] c_sense = 0 if tmp_sense > 0 else 1 # Update sense of the original curve curve . opt = [ 'reversed' , c_sense ] # Generate a curve container and add the original curve cont = [ curve ] move_dir = - 1 if c_sense == 0 else 1 # Curve intersects with the edges of the parametric space counter = 0 while counter < 4 : if idx_ept == idx_spt : counter = 5 pt_start = curve . evalpts [ 0 ] else : # Find next index idx_ept = next_idx ( idx_ept , move_dir ) # Update tracked last point pt_start = parbox [ idx_ept + 1 - c_sense ] # Increment counter counter += 1 # Generate the curve segment crv = shortcuts . generate_curve ( ) crv . degree = 1 crv . ctrlpts = [ pt_end , pt_start ] crv . knotvector = [ 0 , 0 , 1 , 1 ] crv . opt = [ 'reversed' , c_sense ] pt_end = pt_start # Add it to the container cont . append ( crv ) # Update curve return True , cont