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)
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))
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)
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
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()
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()
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()