Beispiel #1
0
def interpolate_points_to_spline(list_of_points,
                                 start_tangent,
                                 end_tangent,
                                 filter_pts=True,
                                 tolerance=TOLERANCE):
    '''
    GeomAPI_Interpolate is buggy: need to use `fix` in order
    to get the right points in...
    '''
    def fix(li, _type):
        '''function factory for 1-dimensional TCol* types'''
        pts = _type(1, len(li))
        for n, i in enumerate(li):
            pts.SetValue(n + 1, i)
        pts.thisown = False
        return pts

    if filter_pts:
        list_of_points = filter_points_by_distance(list_of_points, 0.1)

    fixed_points = fix(list_of_points, TColgp_HArray1OfPnt)
    try:
        interp = GeomAPI_Interpolate(fixed_points.GetHandle(), False,
                                     tolerance)
        interp.Load(start_tangent, end_tangent, False)
        interp.Perform()
        if interp.IsDone():
            return interp.Curve()
    except RuntimeError:
        print("Failed to interpolate the shown points")
Beispiel #2
0
def interpolate_points_vectors_to_spline(list_of_points,
                                         list_of_vectors,
                                         vector_mask=None,
                                         tolerance=TOLERANCE):
    '''
    build a curve from a set of points and vectors
    the vectors describe the tangent vector at the corresponding point
    '''
    # GeomAPI_Interpolate is buggy: need to use `fix` in order to
    # get the right points in...
    assert len(list_of_points) == len(
        list_of_vectors), 'vector and point list not of same length'

    def fix(li, _type):
        '''function factory for 1-dimensional TCol* types'''
        pts = _type(1, len(li))
        for n, i in enumerate(li):
            pts.SetValue(n + 1, i)
        pts.thisown = False
        return pts

    if vector_mask is not None:
        assert len(vector_mask) == len(
            list_of_points
        ), 'length vector mask is not of length points list nor []'
    else:
        vector_mask = [True for i in range(len(list_of_points))]

    fixed_mask = fix(vector_mask, TColStd_HArray1OfBoolean)
    fixed_points = fix(list_of_points, TColgp_HArray1OfPnt)
    fixed_vectors = fix(list_of_vectors, TColgp_Array1OfVec)

    try:
        interp = GeomAPI_Interpolate(fixed_points.GetHandle(), False,
                                     tolerance)
        interp.Load(fixed_vectors, fixed_mask.GetHandle(), False)
        interp.Perform()
        if interp.IsDone():
            return interp.Curve()
    except RuntimeError:
        # the exception was unclear
        raise RuntimeError('FAILED TO INTERPOLATE THE POINTS')
def points_to_bspline(pnts, deg=3, periodic=False, tangents=None,
                      scale=False, continuity=GeomAbs_C2):
    """
    Points to bspline: originally from pythonocc-utils, changed to allow numpy
    arrays as input
    Paramters
    ---------
    pnts : list or numpy array
        array of x, y, z points
    deg : integer
        degree of the fitted bspline
    periodic : Bool (default=False)
        If true, OCC.GeomAPI_Interpolate will be used instead of the
        GeomAPI_PointsToBspline. Curve tangent vectors can then be
        enforced at the interpolation pnts
    tangents : array (default=None)
        list of [x,y,z] tangent vectors to be specificied at points:
        if only 2 tangents are specified, these will be enforced at the
        start and end points, otherwise tangents should have the same length
        as pnts and will be enforced at each point.
    Scale : Bool (default=False)
        Will scale the tangents (gives a smoother Periodic curve if False)
    continuity : OCC.GeomAbs.GeomAbs_XX type (default C2)
        The order of continuity (C^0, C^1, C^2, G^0, ....)

    Returns
    -------
    crv : OCC.Geom.BSplineCurve

    Notes
    -----
    """
    if not periodic and (tangents is None):
        _type = TColgp_Array1OfPnt
        pnts = point_array_to_TColgp_PntArrayType(pnts, _type)
        # Fit the curve to the point array
        deg_min = deg
        deg_max = deg
        crv = GeomAPI_PointsToBSpline(pnts, deg_min, deg_max, continuity).Curve()
    else:
        _type = TColgp_HArray1OfPnt
        pnts = point_array_to_TColgp_PntArrayType(pnts, _type)
        tol = 0.001
        interp = GeomAPI_Interpolate(pnts.GetHandle(), periodic, tol)
        if tangents is not None:
            N = tangents.shape[0]
            if N == 2:
                try:
                    interp.Load(gp_Vec(*tangents[0, :]), gp_Vec(*tangents[1, :]),
                                scale)
                except:
                    # Python 3 issue: using * on numpy array breaks gp_Vec
                    interp.Load(gp_Vec(*tangents[0, :].tolist()),
                                gp_Vec(*tangents[1, :].tolist()),
                                scale)
            else:
                tan_array = TColgp_Array1OfVec(1, N)
                for i in range(1, N + 1):
                    try:
                        tan_array.SetValue(i, gp_Vec(*tangents[i - 1, :]))
                    except TypeError:
                        # Python 3 issue: using * on numpy array breaks gp_Vec
                        tan_array.SetValue(i, gp_Vec(*tangents[i - 1, :].tolist()))

                tan_flags = TColStd_HArray1OfBoolean(1, N)
                tan_flags.Init(True)  # Set all true i.e. enforce all tangents
                interp.Load(tan_array, tan_flags.GetHandle(), scale)
        interp.Perform()
        crv = interp.Curve()
    return crv