def process(self):
            if not any(socket.is_linked for socket in self.outputs):
                return

            vertices_s = self.inputs['Vertices'].sv_get()
            degree_s = self.inputs['Degree'].sv_get()
            points_cnt_s = self.inputs['PointsCnt'].sv_get()

            curves_out = []
            points_out = []
            knots_out = []
            for vertices, degree, points_cnt in zip_long_repeat(
                    vertices_s, degree_s, points_cnt_s):
                if isinstance(degree, (tuple, list)):
                    degree = degree[0]
                if isinstance(points_cnt, (tuple, list)):
                    points_cnt = points_cnt[0]

                kwargs = dict(centripetal=self.centripetal)
                if self.has_points_cnt:
                    kwargs['ctrlpts_size'] = points_cnt

                curve = fitting.approximate_curve(vertices, degree, **kwargs)

                points_out.append(curve.ctrlpts)
                knots_out.append(curve.knotvector)

                curve = SvExGeomdlCurve(curve)
                curves_out.append(curve)

            self.outputs['Curve'].sv_set(curves_out)
            self.outputs['ControlPoints'].sv_set(points_out)
            self.outputs['Knots'].sv_set(knots_out)
        def process(self):
            if not any(socket.is_linked for socket in self.outputs):
                return

            vertices_s = self.inputs['Vertices'].sv_get()
            degree_s = self.inputs['Degree'].sv_get()
            points_cnt_s = self.inputs['PointsCnt'].sv_get()

            input_level = get_data_nesting_level(vertices_s)
            vertices_s = ensure_nesting_level(vertices_s, 4)
            degree_s = ensure_nesting_level(degree_s, 2)
            points_cnt_s = ensure_nesting_level(points_cnt_s, 2)

            nested_output = input_level > 3

            curves_out = []
            points_out = []
            knots_out = []
            for params in zip_long_repeat(vertices_s, degree_s, points_cnt_s):
                new_curves = []
                new_points = []
                new_knots = []
                for vertices, degree, points_cnt in zip_long_repeat(*params):

                    kwargs = dict(centripetal=self.centripetal)
                    if self.has_points_cnt:
                        kwargs['ctrlpts_size'] = points_cnt

                    curve = fitting.approximate_curve(vertices, degree,
                                                      **kwargs)

                    new_points.append(curve.ctrlpts)
                    new_knots.append(curve.knotvector)

                    curve = SvGeomdlCurve(curve)
                    new_curves.append(curve)

                if nested_output:
                    curves_out.append(new_curves)
                    points_out.append(new_points)
                    knots_out.append(new_knots)
                else:
                    curves_out.extend(new_curves)
                    points_out.extend(new_points)
                    knots_out.extend(new_knots)

            self.outputs['Curve'].sv_set(curves_out)
            self.outputs['ControlPoints'].sv_set(points_out)
            self.outputs['Knots'].sv_set(knots_out)
Exemple #3
0
    def curveFit(self, sketch, gL):
        #print('Curve Fit : points : '+str(len(gL)))
        if len(gL) < 2:
            for i in gL:
                sketch.addGeometry(i, False)
        else:
            print('Curve Fit : ' + str(len(gL)))
            #print(dir(gL[0]))
            #print(gL[0].StartPoint)
            #print(gL[0].EndPoint)
            #sketch.addGeometry(Part.LineSegment(gL[0].StartPoint,gL[-1].EndPoint))
            #try :
            from geomdl import fitting

            points = []
            for i in gL:
                points.append([i.StartPoint.x, i.StartPoint.y])
            points.append([i.EndPoint.x, i.EndPoint.y])
            points = tuple(points)
            degree = 3
            #curveI = fitting.interpolate_curve(points, degree)
            curve = fitting.approximate_curve(points, degree, \
                    centripetal=True, ctrlpts_size = 4)
            #print(dir(curve))
            #print(curve._control_points)
            fcCp = []
            for cp in curve._control_points:
                fcCp.append(FreeCAD.Vector(cp[0], cp[1], 0))
            print(curve.degree)
            print(curve._geometry_type)
            print('Number of Control points : ' +
                  str(len(curve._control_points)))
            #print('Number of Control points : '+str(len(curveI._control_points)))
            print('Knot Vector : ' + str(curve.knotvector))
            sketch.addGeometry(Part.BSplineCurve(fcCp,None,None,False, \
                              curve.degree,None,False))
Exemple #4
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        vertices_s = self.inputs['Vertices'].sv_get()
        weights_s = self.inputs['Weights'].sv_get(default=[[[None]]])
        degree_s = self.inputs['Degree'].sv_get()
        points_cnt_s = self.inputs['PointsCnt'].sv_get()
        smoothing_s = self.inputs['Smoothing'].sv_get()

        input_level = get_data_nesting_level(vertices_s)
        vertices_s = ensure_nesting_level(vertices_s, 4)
        degree_s = ensure_nesting_level(degree_s, 2)
        points_cnt_s = ensure_nesting_level(points_cnt_s, 2)
        smoothing_s = ensure_nesting_level(smoothing_s, 2)
        has_weights = self.inputs['Weights'].is_linked
        if has_weights:
            weights_s = ensure_nesting_level(weights_s, 3)

        nested_output = input_level > 3

        curves_out = []
        points_out = []
        knots_out = []
        for params in zip_long_repeat(vertices_s, weights_s, degree_s,
                                      points_cnt_s, smoothing_s):
            new_curves = []
            new_points = []
            new_knots = []
            for vertices, weights, degree, points_cnt, smoothing in zip_long_repeat(
                    *params):

                if self.implementation == 'GEOMDL':
                    kwargs = dict(centripetal=self.centripetal)
                    if self.has_points_cnt:
                        kwargs['ctrlpts_size'] = points_cnt

                    curve = fitting.approximate_curve(vertices, degree,
                                                      **kwargs)
                    control_points = curve.ctrlpts
                    knotvector = curve.knotvector
                    curve = SvGeomdlCurve(curve)
                else:  # SCIPY:
                    points = np.array(vertices)
                    if has_weights:
                        weights = repeat_last_for_length(
                            weights, len(vertices))
                    else:
                        weights = None
                    if not self.has_smoothing:
                        smoothing = None

                    if self.is_cyclic:
                        if self.auto_cyclic:
                            dv = np.linalg.norm(points[0] - points[-1])
                            is_cyclic = dv <= self.cyclic_threshold
                            self.info("Dv %s, threshold %s => is_cyclic %s",
                                      dv, self.cyclic_threshold, is_cyclic)
                        else:
                            is_cyclic = True
                    else:
                        is_cyclic = False

                    curve = scipy_nurbs_approximate(
                        points,
                        weights=weights,
                        metric=self.metric,
                        degree=degree,
                        filter_doubles=None
                        if not self.remove_doubles else self.threshold,
                        smoothing=smoothing,
                        is_cyclic=is_cyclic)

                    control_points = curve.get_control_points().tolist()
                    knotvector = curve.get_knotvector().tolist()

                new_curves.append(curve)
                new_points.append(control_points)
                new_knots.append(knotvector)

            if nested_output:
                curves_out.append(new_curves)
                points_out.append(new_points)
                knots_out.append(new_knots)
            else:
                curves_out.extend(new_curves)
                points_out.extend(new_points)
                knots_out.extend(new_knots)

        self.outputs['Curve'].sv_set(curves_out)
        self.outputs['ControlPoints'].sv_set(points_out)
        self.outputs['Knots'].sv_set(knots_out)
Exemple #5
0
def fit2mask(target, maxnum=4, distance=3, threshold=5, maxlen=150):
    contours = measure.find_contours(target, .8)
    # choose contour with highest point count
    c = contours[np.argmax([len(c) for c in contours])]
    # convert to directions and remove unnecessary points
    direction = []
    last = c[0]
    del_inds = []
    for i in range(-1, len(c)):
        number = dir2num(last - c[i])
        if number == 4:
            del_inds.append(i % len(c))
            continue
        direction.append(number)
        last = c[i]
    c = np.delete(c, del_inds, axis=0)
    direction = np.array(direction)
    # split curve into segments
    breaks = [0]
    count, i = 0, 0
    max_pixel = len(direction)
    while count < max_pixel:
        i = count % len(direction)
        if i >= breaks[-1]:
            dirs = direction[breaks[-1]:i]
        else:
            dirs = direction[np.concatenate(
                [np.arange(breaks[-1], len(direction)),
                 np.arange(i)])]
        bindirs = np.bincount(dirs)
        difdir = np.diff(dirs)
        if (np.diff(np.where(difdir != 0)[0]) > threshold).sum() > (
                maxnum - 2) or (len(np.unique(bindirs)) > maxnum
                                and sorted(bindirs)[-maxnum - 1] >= threshold):
            delta = (difdir[-threshold - 1:] != 0).sum()
            new_break = (i - 1 - delta) % len(direction)
            i -= delta
            if breaks[0] == 0:
                breaks[0] = new_break
                max_pixel += new_break
            else:
                breaks.append(new_break)
        elif i - breaks[-1] >= maxlen and breaks[0] != 0:
            breaks.append((i - 1) % len(direction))
        count += 1
    # refine break points to alway have 4 or more points for fitting reasons
    perm = np.argsort(breaks)
    diffs = np.diff([*sorted(breaks), len(direction) + min(breaks)])
    if np.count_nonzero(diffs < 4):
        bad_inds = np.where(diffs < 4)[0]
        for j in bad_inds:
            breaks[perm[(j + 1) % len(perm)]] -= int(round(diffs[j] / 2))
        for j in sorted(perm[bad_inds])[::-1]:
            del breaks[j]
    # sort points into found segements
    segments = []
    split_ind = np.split(np.arange(len(direction)), sorted(breaks))
    split_ind[0] = np.concatenate((split_ind[-1], split_ind[0]))
    del split_ind[-1]
    for ind in split_ind:
        segments.append(c[ind % len(c)])
    succ = True
    crl = None
    try:
        # check that we have all points
        assert sum([len(s) for s in segments
                    ]) >= len(c), '%i points were given instead of %i' % (sum(
                        [len(s) for s in segments]), len(c))
        # fit bspline curves to the segments
        final_cps = []
        for i in range(len(segments)):
            points = segments[i].tolist()
            if len(points) == 0:
                continue
            assert len(
                points
            ) >= 4, "%i Points to fit were given. At least 4 points are needed." % len(
                points)
            curve = fitting.approximate_curve(points, 3, ctrlpts_size=4)
            final_cps.append(curve.ctrlpts)

        crl = make_cirular(final_cps, distance).tolist()
    except AssertionError as e:
        succ = False
        logger.info(
            'No approximation to the mask could be found. Try again with other parameters. %s'
            % e)
    return succ, crl
Exemple #6
0
import numpy as np
import matplotlib.pyplot as plt
from geomdl import fitting
from geomdl import exchange
from geomdl.visualization import VisMPL as vis
'''
todo: fit 3d curves to central axes of the toroid experiments
'''

con_toroid = exchange.import_csv("con_toroid_caxis.csv",delimiter = ',')
print(len(con_toroid))
toroid = exchange.import_csv("toroid_caxis.csv",delimiter = ',')
print(toroid)

curve = fitting.approximate_curve(toroid,degree = 2,ctrlpts_size = 10)
curve1 = fitting.approximate_curve(con_toroid,degree = 2,ctrlpts_size = 10-)
# Plot the interpolated curve
curve.delta = 0.005
curve.vis = vis.VisCurve3D(vis.VisConfig(ctrlpts=False))
curve.render()

# Plot the interpolated curve
curve1.delta = 0.005
curve1.vis = vis.VisCurve3D(vis.VisConfig(ctrlpts=False))
curve1.render()
Exemple #7
0
    Examples for the NURBS-Python Package
    Released under MIT License
    Developed by Onur Rauf Bingol (c) 2018

    2-dimensional curve fitting by global approximation
"""

from geomdl import fitting
from geomdl.visualization import VisMPL as vis

# The NURBS Book Ex9.1
points = ((0, 0), (3, 4), (-1, 4), (-4, 0), (-4, -3))
degree = 3  # cubic curve

# Do global curve approximation
curve = fitting.approximate_curve(points, degree)

# Plot the interpolated curve
curve.delta = 0.01
curve.vis = vis.VisCurve2D()
curve.render()

# # Visualize data and evaluated points together
# import numpy as np
# import matplotlib.pyplot as plt
# evalpts = np.array(curve.evalpts)
# pts = np.array(points)
# plt.plot(evalpts[:, 0], evalpts[:, 1])
# plt.scatter(pts[:, 0], pts[:, 1], color="red")
# plt.show()
Exemple #8
0
from geomdl import BSpline
from geomdl.knotvector import generate
from geomdl.fitting import approximate_curve
import geomdl.visualization.VisMPL as VisMPL
import math
import numpy as np
import matplotlib.pyplot as plt

points = np.array([[math.cos(i), math.sin(i)]
                   for i in np.linspace(0, 2 * math.pi, num=100)])

# print(points)
# plt.plot(points[:,0],points[:,1])
# plt.show()

curve = approximate_curve(points.tolist(), 3, ctrlpts_size=6)

curve.delta = 0.01
curve.vis = VisMPL.VisCurve2D()
curve.render()