def bspline2mask(cps, width, height, delta=0.05, scaling=5): connecs = [] for i in range(len(cps)): curve = BSpline.Curve() curve.degree = 3 curve.ctrlpts = cps[i] curve.knotvector = utilities.generate_knot_vector( curve.degree, len(curve.ctrlpts)) # print('delta',delta) curve.delta = delta curve.evaluate() connecs.append(curve.evalpts) polygon = np.array(connecs).flatten().tolist() img = Image.new('L', (width, height), 255) ImageDraw.Draw(img).polygon(polygon, outline=0, fill=0) mask = np.array( img.resize((width // scaling, height // scaling), Image.NEAREST)) return mask == False
def get_b_spline(ctrl_pts): ######### ctrl_pts = mvpuai.reshape_coords_to_tuples(ctrl_pts) def get_degree_of_b_spline(num_of_ctrl_pts: int): if num_of_ctrl_pts >= 5: degree = 4 elif num_of_ctrl_pts >= 1: degree = num_of_ctrl_pts - 1 else: degree = 0 return degree degree = get_degree_of_b_spline(len(ctrl_pts)) knot_vector = utilities.generate_knot_vector(degree, len(ctrl_pts)) start = knot_vector[degree] stop = knot_vector[-(degree + 1)] return utilities.linspace(start, stop, 101, decimals=6)
def generateBSpline(self, curve_pts, degree): # Create a B-Spline curve instance curve = BSpline.Curve() # Set evaluation delta curve.delta = 0.001 # Set control points controlpts = curve_pts curve.ctrlpts = controlpts # Set curve degree curve.degree = degree # Auto-generate knot vector curve.knotvector =\ utils.generate_knot_vector(curve.degree, len(curve.ctrlpts)) return curve, curve.knotvector
def spline2polyline(degree, control_points, closed): epsilon = 1e-1 spline = BSpline.Curve() spline.degree = degree spline.ctrlpts = control_points if closed: spline.ctrlpts += spline.ctrlpts[:spline.degree] m = spline.degree + len(spline.ctrlpts) spline.knotvector = [i / m for i in range(m + 1)] curve_range = (spline.knotvector[spline.degree], spline.knotvector[len(spline.ctrlpts)]) nb_seg_init = len(spline.ctrlpts) else: spline.knotvector = utilities.generate_knot_vector( spline.degree, len(spline.ctrlpts)) curve_range = (0, 1) nb_seg_init = len(spline.ctrlpts) - 1 t = np.linspace(curve_range[0], curve_range[1], num=nb_seg_init) curve_data = np.hstack((t.reshape(nb_seg_init, 1), np.array(spline.evaluate_list(t)))) curve_data = np.transpose(curve_data) i = 1 while i < np.size(curve_data, 1): t_mid = (curve_data[0][i] + curve_data[0][i - 1]) / 2 a = curve_data[1:, i - 1] b = curve_data[1:, i] c = spline.evaluate_single(t_mid) ab = b - a ac = c - a ac_proj_in_ab = np.sum(ab * ac, axis=0) / np.sum(np.square(ab), axis=0) dist_to_curve = np.linalg.norm(ac_proj_in_ab * ab - ac, axis=0) if dist_to_curve > epsilon: curve_data = np.insert(curve_data, i, [t_mid, c[0], c[1]], axis=1) else: i += 1 vertices = np.insert(curve_data[1:], 2, 0., axis=0) if closed: return Polyline(vertices[:, :-1], True) else: return Polyline(vertices, False)
def nurbs_test(): curve = BSpline.Curve() curve.ctrlpts = ((3.0, ), (1.0, ), (3.0, ), (2.0, ), (5.0, )) # 控制点 curve.delta = 0.01 # 数据间隔 curve.degree = 4 # degree应该小于控制点数量 # 自动计算knot point curve.knotvector = utilities.generate_knot_vector(curve.degree, len(curve.ctrlpts)) curve.evaluate() # 计算曲线 pt_y = [] # y值 pt_x = np.linspace(0, 1, 101) dpt_y = [] # y一阶导数 ddpt_y = [] # y二阶导数 for pt in pt_x: tmp = curve.derivatives(pt, order=2) # 0,1,2阶导数全部计算 pt_y.append(tmp[0][0]) dpt_y.append(tmp[1][0]) ddpt_y.append(tmp[2][0]) ctrl_x = np.linspace(0, 1, 5) # 控制点 ctrl_y = [] for item in curve.ctrlpts: # ctrl_y.append(item[0]) plt.plot(pt_x, pt_y, 'b-') plt.plot(ctrl_x, ctrl_y, 'r*') plt.grid() plt.show() # 验证一阶求导的正确性 pt_y = np.array(pt_y) dpt_y = np.array(dpt_y) dpt_y_dis = (pt_y[1:] - pt_y[:-1]) / (pt_x[1] - pt_x[0]) ddpt_y_dis = (dpt_y[1:] - dpt_y[:-1]) / (pt_x[1] - pt_x[0]) pt_x_dis = pt_x[:-1] + (pt_x[1] - pt_x[0]) / 2 # 绘制一阶的 plt.plot(pt_x_dis, dpt_y_dis, '+r') plt.plot(pt_x, dpt_y, '-b') plt.show() # 绘制二阶的 plt.plot(pt_x_dis, ddpt_y_dis, '+r') plt.plot(pt_x, ddpt_y, '-b') plt.show()
def generate_heart(scale=1): # Create a B-Spline curve heart = BSpline.Curve() # Set up the control points heart.degree = 3 heart.ctrlpts = [[0, -20], [25, 5], [17, 20], [5, 19], [0.2, 13], [0, 8], [-0.2, 13], [-5, 19], [-17, 20], [-25, 5], [0, -20]] # Scale the heart up/down according to the input scale heart.ctrlpts = [[scale * x, scale * y] for x, y in heart.ctrlpts] # Auto-generate knot vector heart.knotvector = utilities.generate_knot_vector(heart.degree, len(heart.ctrlpts)) # Set the evaluation delta heart.delta = 0.001 # Evaluate the curve heart.evaluate() # Return the heart curve return heart
def test_generate_knot_vector3(): with pytest.raises(ValueError): degree = 0 num_ctrlpts = 0 utilities.generate_knot_vector(degree, num_ctrlpts)
render_surf = False # Fix file path os.chdir(os.path.dirname(os.path.realpath(__file__))) # Create a BSpline surface instance surf = BSpline.Surface() # Set evaluation delta surf.delta = 0.025 # Set up surface surf.read_ctrlpts_from_txt("ex_surface02.cpt") surf.degree_u = 3 surf.degree_v = 3 surf.knotvector_u = utilities.generate_knot_vector(surf.degree_u, 6) surf.knotvector_v = utilities.generate_knot_vector(surf.degree_v, 6) # Evaluate surface surf.evaluate() # Draw the control point grid and the evaluated surface if render_surf: vis_comp = VisMPL.VisSurfScatter() surf.vis = vis_comp surf.render() # Save control points and evaluated curve points surf.save_surfpts_to_csv("surfpts02_orig.csv", mode='linear') surf.save_ctrlpts_to_csv("ctrlpts02_orig.csv", mode='wireframe')
# Generate control points grid for Surface #1 sg01 = CPGen.Grid(15, 10, z_value=0.0) sg01.generate(8, 8) # Create a BSpline surface instance surf01 = BSpline.Surface() # Set degrees surf01.degree_u = 1 surf01.degree_v = 1 # Get the control points from the generated grid surf01.ctrlpts2d = sg01.grid # Set knot vectors surf01.knotvector_u = utilities.generate_knot_vector( surf01.degree_u, surf01.ctrlpts_size_u) surf01.knotvector_v = utilities.generate_knot_vector( surf01.degree_v, surf01.ctrlpts_size_v) # Generate control points grid for Surface #2 sg02 = CPGen.Grid(15, 10, z_value=1.0) sg02.generate(8, 8) # Create a BSpline surface instance surf02 = BSpline.Surface() # Set degrees surf02.degree_u = 1 surf02.degree_v = 1 # Get the control points from the generated grid
def createnurbsshading(idd_filename, idf_filename, base_surface, shading_str, ctrl_points, evaluated_points=20): ########################################## # loading base surface data from idf file ########################################## # check if IDD has been already set try: IDF.setiddname(idd_filename) except modeleditor.IDDAlreadySetError as e: pass # load idf file into idf collection idf_collection = IDF(idf_filename) # find the named base_surface in idf collection walls = idf_collection.idfobjects['BuildingSurface:Detailed'.upper()] for wall in walls: if wall.Name == base_surface: # named base_surface is now contained in wall break else: # named base_surface was not found in idf file print('epnurbs.createshading: unable to find the base surface', base_surface, 'in', idf_filename) return ################################# # calculating NURBS curve points ################################# from geomdl import NURBS from geomdl import utilities curve = NURBS.Curve() # 1/delta corresponds to the number of trapezoids used in approximation of NURBS shading curve.delta = 1/evaluated_points curve.degree = 3 # add weight 1 to each control point # unless it has been already weighted for cpt in ctrl_points: if len(cpt)<4: cpt.append(1.0) # sets curve control points curve.set_ctrlpts(ctrl_points) # sets curve knot vector curve.knotvector = utilities.generate_knot_vector(curve.degree, len(curve.ctrlpts)) # evaluates curve points curve.evaluate() # make a local copy of evaluated curve points crv_points = curve.curvepts ################################################################################### # feet of perpendiculars from the remaining NURBS curve points to the base surface ################################################################################### # getting the found base_surface's coordinates coord = wall.coords ulc = coord[0] blc = coord[1] brc = coord[2] # find the base_surface's plane normal and normalize it N = crossproduct( (blc[0]-ulc[0], blc[1]-ulc[1], blc[2]-ulc[2]), \ (brc[0]-ulc[0], brc[1]-ulc[1], brc[2]-ulc[2]) ) N = normalize(N) # calculate feet of perpendiculars feet_points = [foot(crv_points[i], ulc, N) for i in range(len(crv_points))] ################################################################################# # create string of idf definitions for trapezoids that approximate NURBS shading ################################################################################# idf_total_shading_def = "" for i in range(1, len(crv_points)): # the width of a trapezoid must be at least 0.01 if distance(crv_points[i-1], crv_points[i])>=0.01 and \ distance(feet_points[i-1], feet_points[i])>=0.01: # are trapezoid arms at least 0.01 or do we have a triangle? if distance(crv_points[i-1], feet_points[i-1])>=0.01: if distance(crv_points[i], feet_points[i])>=0.01: # both arms are at least 0.01, so we have a trapezoid vertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format( feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2], crv_points[i-1][0], crv_points[i-1][1], crv_points[i-1][2], crv_points[i][0], crv_points[i][1], crv_points[i][2], feet_points[i][0], feet_points[i][1], feet_points[i][2]) countervertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format( feet_points[i][0], feet_points[i][1], feet_points[i][2], crv_points[i][0], crv_points[i][1], crv_points[i][2], crv_points[i-1][0], crv_points[i-1][1], crv_points[i-1][2], feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2]) single_shading_def = shading_str.replace('<IDX>', str(i)).replace('<BASESURFACE>', base_surface).replace('<VERTICES>', vertices_str).replace('<COUNTERVERTICES>', countervertices_str) idf_total_shading_def = idf_total_shading_def + single_shading_def else: # arm i is less than 0.01, so we have a triangle vertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format( feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2], crv_points[i-1][0], crv_points[i-1][1], crv_points[i-1][2], feet_points[i][0], feet_points[i][1], feet_points[i][2]) countervertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format( feet_points[i][0], feet_points[i][1], feet_points[i][2], crv_points[i-1][0], crv_points[i-1][1], crv_points[i-1][2], feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2]) single_shading_def = shading_str.replace('<IDX>', str(i)).replace('<BASESURFACE>', base_surface).replace('<VERTICES>', vertices_str).replace('<COUNTERVERTICES>', countervertices_str) idf_total_shading_def = idf_total_shading_def + single_shading_def else: # arm i-1 is less than 0.01, but do we still have a triangle? if distance(crv_points[i], feet_points[i])>=0.01: # we have a triangle vertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format( feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2], crv_points[i][0], crv_points[i][1], crv_points[i][2], feet_points[i][0], feet_points[i][1], feet_points[i][2]) countervertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format( feet_points[i][0], feet_points[i][1], feet_points[i][2], crv_points[i][0], crv_points[i][1], crv_points[i][2], feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2]) single_shading_def = shading_str.replace('<IDX>', str(i)).replace('<BASESURFACE>', base_surface).replace('<VERTICES>', vertices_str).replace('<COUNTERVERTICES>', countervertices_str) idf_total_shading_def = idf_total_shading_def + single_shading_def else: # we do not have a shading element in this case pass # create idf shading objects from the string containing shading definitions from io import StringIO idf_shading = IDF(StringIO(idf_total_shading_def)) # copy idf shading objects to the existing idf file shadings = idf_shading.idfobjects["SHADING:ZONE:DETAILED"] for shading in shadings: idf_collection.copyidfobject(shading) ############################### # at the end, save the changes ############################### idf_collection.save()
def plot_base(ctrlpts_size_u, Bspl): type = ['closed', 'open', 'nonlinear', 'special', 'special2', 'special3'] # fig = plt.figure() # ax = fig.gca() color = ['r', 'b', 'k', 'g', 'c', 'm', 'y', 'r', 'b', 'k', 'g', 'c', 'm', 'y', 'r', 'b', 'k', 'g', 'c', 'm', 'y'] for ind, setup in enumerate(type): if setup == 'open': Bspl.knotvector_u = tuple(np.linspace(0, 1, num=Bspl.degree_u + ctrlpts_size_u + 1).tolist()) # span_u = helpers.find_span_linear(Bspl.degree_u, Bspl.knotvector_u, ctrlpts_size_u, 1) # # span_u = self._span_func(Bspl.degree_u, Bspl.knotvector_u, ctrlpts_size_u, 1) # bfunsders_u = helpers.basis_function_ders(Bspl.degree_u, Bspl.knotvector_u, span_u, 1, 0) elif setup == 'closed': Bspl.knotvector_u = geom_util.generate_knot_vector(Bspl.degree_u, ctrlpts_size_u) elif setup == 'nonlinear': pdb.set_trace() numb = Bspl.degree_u + ctrlpts_size_u + 1 vec = np.linspace(0.1, 1, num=np.floor(numb / 2)).tolist() k = 0.5 vec = [elem ** k for elem in vec] # vec = np.exp(vec) # Normalize vec = vec / (2 * np.max(vec)) if numb % 2 == 0: # Do not append mid number if uneven number of points! lst = np.sort(np.append(vec, -vec)) + 0.5 else: lst = np.sort(np.append(np.append(vec, 0), -vec)) + 0.5 Bspl.knotvector_u = tuple(lst) elif setup == 'special': # closed knotvector pdb.set_trace() c_kn = np.linspace(0, 1, num=Bspl.degree_u + ctrlpts_size_u + 1).tolist() c_kn[0] = c_kn[1] c_kn[-1] = c_kn[-2] Bspl.knotvector_u = c_kn elif setup == 'special2': c_kn = np.linspace(0, 1, num=Bspl.degree_u + ctrlpts_size_u + 1).tolist() # Closed. nothing fishy c_kn[0] = c_kn[2] c_kn[1] = c_kn[2] c_kn[-1] = c_kn[-3] c_kn[-2] = c_kn[-3] Bspl.knotvector_u = c_kn elif setup == 'special3': c_kn = np.linspace(0, 1, num=Bspl.degree_u + ctrlpts_size_u + 1).tolist() pdb.set_trace() # Closed. nothing fishy c_kn[0] = c_kn[2] c_kn[1] = c_kn[2] c_kn[-1] = c_kn[-3] c_kn[-2] = c_kn[-3] Bspl.knotvector_u = c_kn else: raise NotImplementedError start_u = Bspl._knot_vector_u[Bspl._degree_u] stop_u = Bspl._knot_vector_u[-(Bspl._degree_u + 1)] # Map variables to valid knot space knots_u = start_u + (stop_u - start_u) * np.linspace(0, 1, 100) spans_p = helpers.find_spans(Bspl.degree_u, Bspl.knotvector_u, ctrlpts_size_u, knots_u, Bspl._span_func) basis_p = helpers.basis_functions(Bspl.degree_u, Bspl.knotvector_u, spans_p, knots_u) basis_p_full = np.array(basis_full(Bspl, basis_p, Bspl.degree_u, spans_p)) # Plot the curve fig = plt.figure() ax = fig.gca() i = 0 # Bspl.derivatives(1, 1, 0) # plot derivative bfun_der = [] basis_p_full = np.array(basis_full(Bspl, basis_p, Bspl.degree_u, spans_p)) for knot in knots_u: span_u = helpers.find_span_linear(Bspl.degree_u, Bspl.knotvector_u, ctrlpts_size_u, knot) row = helpers.basis_function_ders(Bspl.degree_u, Bspl.knotvector_u, span_u, knot, 2)[-1] # pdb.set_trace() bfun_der.append(row) der_plot = np.array(basis_full(Bspl, bfun_der, Bspl.degree_u, spans_p)) # plot the value of the function for ind, dummy in enumerate(basis_p_full[0]): max_val = np.max(np.abs(der_plot[:, i])) ax.plot(knots_u, np.ravel(basis_p_full[:, i]), color[ind]) ax.plot(knots_u, np.ravel(der_plot[:, i]) * (stop_u - start_u), '--o' + color[ind]) # / np.max(der_plot[:, i]) i += 1 ax.set_title(setup) plt.show()
render_curve = False r = 3.0 Cx = lambda t: r + r * math.cos(0.5 * math.pi * t + math.pi) Cy = lambda t: r + r * math.sin(0.5 * math.pi * t + math.pi) # choose curve parameter degree = 2 nCtrlpts = 3 # gauss quadrature xi = [-0.90618, -0.538469, 0, 0.538469, 0.90618] wi = [0.236927, 0.478629, 0.568889, 0.478629, 0.236927] # solve knotvector = utils.generate_knot_vector(degree, nCtrlpts) span = lambda xi: utils.find_span(degree, tuple(knotvector), nCtrlpts, xi * 0.5 + 0.5) bfuns = lambda xi: utils.basis_functions(2, tuple(knotvector), span(xi), xi * 0.5 + 0.5) t = -0.5 print knotvector print span(t) print bfuns(t) A = np.zeros((nCtrlpts, nCtrlpts)) A_temp = np.zeros((nCtrlpts, nCtrlpts)) B = np.zeros(3) for g in range(0, len(xi)):
coords_disp[i, 0], coords_disp[i, 1])) f.close() # Visualize results (displacement only) # Visualize minimization results # Set up new surface disp_surf = bs.Surface() disp_surf.degree_u = 3 disp_surf.degree_v = 3 disp_surf.set_ctrlpts(coords_disp.tolist(), num_ctrlpts, num_ctrlpts) disp_surf.knotvector_u = gutil.generate_knot_vector(disp_surf.degree_u, num_ctrlpts) disp_surf.knotvector_v = gutil.generate_knot_vector(disp_surf.degree_v, num_ctrlpts) disp_surf.delta = 0.01 fname = 'sinusoidalxmindispl' visualize.viz_displacement(def_image, disp_surf, indices[0], indices[1], indices[2], indices[3], fname) # Compute differences between proscribed and actual displacement measurements # Fill x and y displacement arrays U_diff = np.zeros(def_image.shape) * np.nan V_diff = np.zeros(def_image.shape) * np.nan rowmin_index = indices[0] rowmax_index = indices[1] colmin_index = indices[2]
def main(): points = np.loadtxt("N2_RV_P0.txt") zmin_loc_temp = np.where(points[:, 1] == 0)[0] zmin_loc = zmin_loc_temp # points = remove_3dpoint(points,zmin_loc) N = 5 slice(N, points) slice0 = slice.slices[0] x0 = slice0[:, 0] y0 = slice0[:, 1] z0 = slice0[:, 2] slice1 = slice.slices[1] x1 = slice1[:, 0] y1 = slice1[:, 1] z1 = slice1[:, 2] slice2 = slice.slices[2] x2 = slice2[:, 0] y2 = slice2[:, 1] z2 = slice2[:, 2] slice3 = slice.slices[3] x3 = slice3[:, 0] y3 = slice3[:, 1] z3 = slice3[:, 2] slice4 = slice.slices[4] x4 = slice4[:, 0] y4 = slice4[:, 1] z4 = slice4[:, 2] print(np.shape(points)) ranges = slice.bins diameter = x0.max() - x0.min() radius = diameter height = z0.max() diameter1 = x1.max() - x1.min() radius1 = diameter1 height1 = z1.max() diameter2 = x2.max() - x2.min() radius2 = diameter2 height2 = z2.max() diameter3 = x3.max() - x3.min() radius3 = diameter3 height3 = z3.max() diameter4 = x4.max() - x4.min() radius4 = diameter4 / 2 height4 = x4.max() # Generate a cylindrical surface using the shapes component cylinder = surface.cylinder(radius, height) # vis_config = VisMPL.VisConfig(ctrlpts=True) # vis_comp = VisMPL.VisSurface(config=vis_config) # cylinder.vis = vis_comp # cylinder.render() cyl_points = cylinder.evalpts print("*****************") # print(len(cyl_points)) print("*****************") cylinder1 = surface.cylinder(radius1, height1) cyl_points1 = cylinder1.evalpts # vis_config = VisMPL.VisConfig(ctrlpts=True) # vis_comp = VisMPL.VisSurface(config=vis_config) # cylinder1.vis = vis_comp # cylinder1.render() cylinder2 = surface.cylinder(radius2, height2) cyl_points2 = cylinder2.evalpts # vis_config = VisMPL.VisConfig(ctrlpts=True) # vis_comp = VisMPL.VisSurface(config=vis_config) # cylinder2.vis = vis_comp # cylinder2.render() cylinder3 = surface.cylinder(radius3, height3) cyl_points3 = cylinder3.evalpts # vis_config = VisMPL.VisConfig(ctrlpts=True) # vis_comp = VisMPL.VisSurface(config=vis_config) # cylinder2.vis = vis_comp # cylinder2.render() cylinder4 = surface.cylinder(radius4, height4) cyl_points4 = cylinder4.evalpts # vis_config = VisMPL.VisConfig(ctrlpts=True) # vis_comp = VisMPL.VisSurface(config=vis_config) # cylinder4.vis = vis_comp # cylinder4.render() #try using points from the surface not the control points cylinder_cpts = np.array(cylinder.ctrlpts) cylinder_cpts1 = np.array(cylinder1.ctrlpts) cylinder_cpts2 = np.array(cylinder2.ctrlpts) cylinder_cpts3 = np.array(cylinder3.ctrlpts) cylinder_cpts4 = np.array(cylinder4.ctrlpts) a = np.array(cdist(np.array(cyl_points), slice0)).min(axis=0) b = np.array(cdist(np.array(cyl_points1), slice1)).min(axis=0) c = np.array(cdist(np.array(cyl_points2), slice2)).min(axis=0) d = np.array(cdist(np.array(cyl_points3), slice3)).min(axis=0) e = np.array(cdist(np.array(cyl_points4), slice4)).min(axis=0) test = np.zeros((len(cylinder_cpts), 3)) test1 = np.zeros((len(cylinder_cpts1), 3)) test2 = np.zeros((len(cylinder_cpts2), 3)) test3 = np.zeros((len(cylinder_cpts3), 3)) test4 = np.zeros((len(cylinder_cpts4), 3)) for i in range(0, len(cylinder_cpts)): test[i] = (cylinder_cpts[i] / np.linalg.norm(cylinder_cpts[i])) * a[i] test1[i] = (cylinder_cpts1[i] / np.linalg.norm(cylinder_cpts1[i])) * b[i] test2[i] = (cylinder_cpts2[i] / np.linalg.norm(cylinder_cpts2[i])) * c[i] test3[i] = (cylinder_cpts3[i] / np.linalg.norm(cylinder_cpts3[i])) * d[i] test4[i] = (cylinder_cpts4[i] / np.linalg.norm(cylinder_cpts4[i])) * e[i] test_zeros_loc = np.where(test[:, 2] == 0)[0] test1_zeros_loc = np.where(test1[:, 2] == 0)[0] test2_zeros_loc = np.where(test2[:, 2] == 0)[0] test3_zeros_loc = np.where(test3[:, 2] == 0)[0] test4_zeros_loc = np.where(test4[:, 2] == 0)[0] test = remove_3dpoint(test, test_zeros_loc) test1 = remove_3dpoint(test1, test1_zeros_loc) test2 = remove_3dpoint(test2, test2_zeros_loc) test3 = remove_3dpoint(test3, test3_zeros_loc) test4 = remove_3dpoint(test4, test4_zeros_loc) test = np.array( [test[:, 0], test[:, 1], np.ones(len(test[:, 2])) * ranges[0]]).T test1 = np.array( [test1[:, 0], test1[:, 1], np.ones(len(test1[:, 2])) * ranges[1]]).T test2 = np.array( [test2[:, 0], test2[:, 1], np.ones(len(test2[:, 2])) * ranges[2]]).T test3 = np.array( [test3[:, 0], test3[:, 1], np.ones(len(test3[:, 2])) * ranges[3]]).T test4 = np.array( [test4[:, 0], test4[:, 1], np.ones(len(test4[:, 2])) * ranges[4]]).T # for i in range(0,len(test1)): # test1[i] = test1[i] + [0,0,height] # test2[i] = test2[i]+[0,0,height1] # test3[i] = test3[i]+[0,0,height2] test = remove_3dpoint(test, len(test) - 1) test1 = remove_3dpoint(test1, len(test1) - 1) test2 = remove_3dpoint(test2, len(test2) - 1) test3 = remove_3dpoint(test3, len(test3) - 1) test4 = remove_3dpoint(test4, len(test4) - 1) # test = np.insert(test,[0,len(test)],[[0,0,-5],[0,0,ranges[0]]],axis=0) # test1 = np.insert(test1,[0,len(test1)],[0,0,ranges[1]],axis=0) # test2 = np.insert(test2,[0,len(test2)],[0,0,ranges[2]],axis=0) test = np.insert( test, [len(test) - 2, len(test) - 1, len(test)], [test[0], test[1], test[2]], axis=0) test1 = np.insert( test1, [len(test1) - 2, len(test1) - 1, len(test1)], [test1[0], test1[1], test1[2]], axis=0) test2 = np.insert( test2, [len(test2) - 2, len(test2) - 1, len(test2)], [test2[0], test2[1], test2[2]], axis=0) test3 = np.insert( test3, [len(test3) - 2, len(test3) - 1, len(test3)], [test3[0], test3[1], test3[2]], axis=0) test = np.insert( test4, [len(test4) - 2, len(test4) - 1, len(test4)], [test4[0], test4[1], test4[2]], axis=0) # print(test) # print(test1) # print(test2) # print(test3) X = np.row_stack((test, test1, test2, test3, test4)) print(X) # np.random.shuffle(X) np.savetxt("cpts_test.csv", X, delimiter=",") # np.savetxt("cpts_test1.csv", test1, delimiter=",") fig = plt.figure() ax = plt.axes(projection="3d") ax.scatter3D(test[:, 0], test[:, 1], np.ones(len(test[:, 2])) * ranges[0], color='red') ax.scatter3D(test1[:, 0], test1[:, 1], test1[:, 2], color='blue') ax.scatter3D(test2[:, 0], test2[:, 1], test2[:, 2], color='green') ax.scatter3D(test3[:, 0], test3[:, 1], test3[:, 2], color='yellow') ax.scatter3D(test4[:, 0], test4[:, 1], test4[:, 2], color='purple') # ax.scatter3D(cylinder_cpts[:,0],cylinder_cpts[:,1],cylinder_cpts[:,2]) # ax.scatter3D(cylinder_cpts1[:,0],cylinder_cpts1[:,1],cylinder_cpts1[:,2]) # try fitting a NURBS Surface surf = NURBS.Surface() surf.delta = 0.03 p_ctrlpts = exchange.import_csv("cpts_test.csv") print(len(p_ctrlpts)) p_weights = np.ones((len(p_ctrlpts))) p_size_u = 9 p_size_v = 5 p_degree_u = 3 p_degree_v = 3 t_ctrlptsw = compat.combine_ctrlpts_weights(p_ctrlpts, p_weights) n_ctrlptsw = compat.flip_ctrlpts_u(t_ctrlptsw, p_size_u, p_size_v) n_knotvector_u = utils.generate_knot_vector(p_degree_u, p_size_u) n_knotvector_v = utils.generate_knot_vector(p_degree_v, p_size_v) surf.degree_u = p_degree_u surf.degree_v = p_degree_v surf.set_ctrlpts(n_ctrlptsw, p_size_u, p_size_v) surf.knotvector_u = n_knotvector_u surf.knotvector_v = n_knotvector_v vis_config = vis.VisConfig(ctrlpts=True, axes=True, legend=True) surf.vis = vis.VisSurface(vis_config) surf.evaluate() surf.render()
def swing_curve_planning(self, leg_down): # 1. 现在是哪条腿落下 if leg_down is 'left': coe = -1 else: coe = 1 # --------------------------------- # 2. 首先处理当前准备触地的腿 p_end, a_end = self.p_end, self.a_end a_begin = np.array([a_end[0], a_end[1], -a_end[2]]) # 这是重规划的起始点 p_begin = np.array([-p_end[0], p_end[1], p_end[2]]) # 2.1 直角坐标空间下的关键点位置 p1 = tuple(p_begin) p2 = tuple(p_begin + 0.1 * a_begin) p4 = tuple(p_end - 0.05 * a_end) p5 = tuple(p_end) p3 = (0., (p1[1]+p5[1])/2, p_begin[2] + 0.3) # 2.2 关节坐标空间下的关键点位置转化 jp1 = self.coord_fake_world2joint(np.array(p1).reshape((3, 1)), leg_down) jp2 = self.coord_fake_world2joint(np.array(p2).reshape((3, 1)), leg_down) jp3 = self.coord_fake_world2joint(np.array(p3).reshape((3, 1)), leg_down) jp4 = self.coord_fake_world2joint(np.array(p4).reshape((3, 1)), leg_down) jp5 = self.coord_fake_world2joint(np.array(p5).reshape((3, 1)), leg_down) # 2.3 构造曲线对象 tmp_curve = BSpline.Curve() tmp_curve.ctrlpts = (jp1, jp2, jp3, jp4, jp5) tmp_curve.delta = 0.01 tmp_curve.degree = 4 tmp_curve.knotvector = utilities.generate_knot_vector(4, len(tmp_curve.ctrlpts)) tmp_curve.evaluate() if leg_down is 'left': self.this_curve_l = tmp_curve else: self.this_curve_r = tmp_curve # ---------------------------- # 3. 让我们来处理另一条腿吧 p_end = np.array([p_end[0], coe*0.12, p_end[2]]) # a_end = np.array([a_end[0], 0.0, a_end[2]]) # 方向向前 if self.cycle_cnt == 1: p_begin = np.array([-p_end[0], p_end[1], p_end[2]]) # x位置反向 a_begin = np.array([a_end[0], a_end[1], -a_end[2]]) # z方向相反 else: p_begin = self.p_begin a_begin = self.a_begin # 3.1 直角坐标系下的关键点位置 p1 = tuple(p_begin) p2 = tuple(p_begin + 0.1 * a_begin) p4 = tuple(p_end - 0.05 * a_end) p5 = tuple(p_end) p3 = (0., (p1[1] + p5[1]) / 2, p_begin[2] + 0.3) # 3.2 关节坐标空间下的关键点位置转化 jp1 = self.coord_fake_world2joint(np.array(p1).reshape((3, 1)), leg_down) jp2 = self.coord_fake_world2joint(np.array(p2).reshape((3, 1)), leg_down) jp3 = self.coord_fake_world2joint(np.array(p3).reshape((3, 1)), leg_down) jp4 = self.coord_fake_world2joint(np.array(p4).reshape((3, 1)), leg_down) jp5 = self.coord_fake_world2joint(np.array(p5).reshape((3, 1)), leg_down) # 3.3 构造曲线对象 tmp_curve = BSpline.Curve() tmp_curve.ctrlpts = (jp1, jp2, jp3, jp4, jp5) tmp_curve.delta = 0.01 tmp_curve.degree = 4 tmp_curve.knotvector = utilities.generate_knot_vector(4, len(tmp_curve.ctrlpts)) tmp_curve.evaluate() if leg_down is 'left': self.this_curve_r = tmp_curve else: self.this_curve_l = tmp_curve
def test_check_knot_vector4(): degree = 4 num_ctrlpts = 12 autogen_kv = utilities.generate_knot_vector(degree, num_ctrlpts) check_result = utilities.check_knot_vector(degree=degree, num_ctrlpts=num_ctrlpts, knot_vector=autogen_kv) assert check_result
def test_generate_knot_vector4(): degree = 4 num_ctrlpts = 12 autogen_kv = utilities.generate_knot_vector(degree, num_ctrlpts) result = [0.0, 0.0, 0.0, 0.0, 0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.0, 1.0, 1.0, 1.0] assert autogen_kv == result
# # 2D CURVE 1 # # Create a B-Spline curve instance (Bezier Curve) curve1 = BSpline.Curve() # Set evaluation delta curve1.delta = 0.01 # Set up the Bezier curve curve1.ctrlpts = [[10, 0], [15, 15], [20, 0]] curve1.degree = 2 # Auto-generate knot vector curve1.knotvector = utilities.generate_knot_vector(curve1.degree, len(curve1.ctrlpts)) # Evaluate curve curve1.evaluate() # Draw the control point polygon and the evaluated curve if render_curve: vis_comp1 = VisMPL.VisCurve2D() curve1.vis = vis_comp1 curve1.render() # # 2D CURVE 2 # # Create another B-Spline curve instance (Bezier Curve)
from geomdl import utilities import numpy as np degree = 4 Ncpts = 9 ti = utilities.generate_knot_vector(degree,Ncpts+1) P = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,20,21,22,23,24,25,26,51,52,53,54,55,56,57,58,59,60] def getABsis(cpt,ti,t): if t>=ti[cpt] and t<ti[cpt+1]: return 1 else: return 0 Nij=np.zeros([len(P),Ncpts+2+degree,degree+1]) for deg in range(degree+1): if deg == 0: for cpt in range(Ncpts+degree+1): for pt,t in enumerate(P): Nij[pt][cpt][deg] = getABsis(cpt,ti,t/P[-1]) else: for cpt in range(Ncpts+degree+2-deg): for pt,t in enumerate(P): try: LEFT = (t/P[-1] - ti[cpt]) / (ti[cpt+deg]-ti[cpt]) RIGHT = (ti[cpt+deg+1] - t/P[-1]) / (ti[cpt+deg+1]-ti[cpt+1])
# Weights of the control points p_weights = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] # Degrees p_degree_u = 3 p_degree_v = 2 # # Prepare data for import # t_ctrlptsw = compat.combine_ctrlpts_weights(p_ctrlpts, p_weights) n_ctrlptsw = compat.flip_ctrlpts_u(t_ctrlptsw, p_size_u, p_size_v) # Since we have no information on knot vectors, let's auto-generate them n_knotvector_u = utils.generate_knot_vector(p_degree_u, p_size_u) n_knotvector_v = utils.generate_knot_vector(p_degree_v, p_size_v) # # Import surface to NURBS-Python # surf = NURBS.Surface() surf.degree_u = p_degree_u surf.degree_v = p_degree_v surf.ctrlpts_size_u = p_size_u surf.ctrlpts_size_v = p_size_v surf.ctrlptsw = n_ctrlptsw surf.knotvector_u = n_knotvector_u surf.knotvector_v = n_knotvector_v
def smooth_bspline(self, filename): """ Smooth respiratory function using B-spline curve Parameters ---------- filname: string Name of 2DST file to smooth the respiratory function Returns ------- snake: list Optimised B-spline curve (respiratory function smoothed) """ # Recover respiratory function extracted from 2DST images using masks ldiaphragm_pts = [list(item) for item in self.respiratory_pattern(filename)] # print("Original diaphragm points: {}".format(ldiaphragm_pts)) # img = cv2.imread('{}/{}/{}/{}'.format(DIR_2DST_DICOM, self.patient, self.plan, filename), 1) # diaphragm_mask = np.zeros((256, 50, 3), np.uint8) # img_mask = img.copy() # i = 0 # while(i < len(ldiaphragm_pts) - 1): # cv2.line( # img_mask, # ldiaphragm_pts[i], ldiaphragm_pts[i + 1], # (255, 0, 0), 1) # i = i + 1 # cv2.imshow('Diaphragmatic level', img_mask) # cv2.waitKey(0) # cv2.destroyAllWindows() # cv2.imwrite('name.png', img_mask) # Try to load the visualization module try: render_curve = True from geomdl.visualization import VisMPL except ImportError: render_curve = False # Create a B-Spline curve instance curve = BSpline.Curve() # Set evaluation delta curve.delta = 0.0002 """ Set up curve """ # Set control points controlpts = ldiaphragm_pts convert_controlpts = map(lambda x: 255 - x[1], controlpts) for i in range(len(controlpts)): controlpts[i][1] = convert_controlpts[i] curve.ctrlpts = controlpts # Set curve degree curve.degree = 3 # Auto-generate knot vector curve.knotvector =\ utilities.generate_knot_vector( curve.degree, len(curve.ctrlpts)) # Evaluate curve curve.evaluate() # Draw the control point polygon and the evaluated curve if render_curve: vis_comp = VisMPL.VisCurve2D() curve.vis = vis_comp curve.render()
bump_height=45, base_extent=4, base_adjust=1) # Create a BSpline surface instance surf = BSpline.Surface() # Set degrees surf.degree_u = 3 surf.degree_v = 3 # Get the control points from the generated grid surf.ctrlpts2d = surfgrid.grid() # Set knot vectors surf.knotvector_u = utilities.generate_knot_vector(surf.degree_u, surf.ctrlpts_size_u) surf.knotvector_v = utilities.generate_knot_vector(surf.degree_v, surf.ctrlpts_size_v) # Split the surface at v = 0.35 split_surf = surf.split_v(0.35) # Set sample size of the split surface split_surf.sample_size = 25 # Generate the visualization component and its configuration vis_config = VisPlotly.VisConfig(ctrlpts=False, legend=False) vis_comp = VisPlotly.VisSurface(vis_config) # Set visualization component of the split surface split_surf.vis = vis_comp
def draw_graph(self, output_file, style, size=1.0, scale_correction=900, curved=False, symbology=True, label_correction=1.0, node_scale=5, offset=(0, 0)): """ output_file: path to an svg file style: a python dictionary defining the styles for nodes and edges size: default size is 2000 * 2000 multiplied by the size value scale_correction: change this value to alter the size of the graph relative to the total size of the svg canvas curved: whether edge connections are curved or not symbology: whether or not to use symbology when drawing the graph or a colour scheme label_correction: adjusts the position of the labels relative to the centre of the nodes node_scale: the size of the nodes relative to canvas offset: x y coordinates to offset the centre of the graph - useful when using a background image (as defined in the style) """ dwg_size = (2000 * size, 2000 * size) dwg = svgwrite.Drawing(filename=output_file, size=dwg_size, profile='full', debug=True) rect = dwg.rect(insert=(0, 0), size=dwg_size, fill=style['background']['color']) dwg.add(rect) if style['background'].get('image') is not None: path = style['background'].get('image') img = Image(filename=path) img_data = img.make_blob(format='png') encoded = base64.b64encode(img_data).decode() png_data = 'data:image/png;base64,{}'.format(encoded) image = dwg.add( dwg.image(href=(png_data), insert=(0, 0), size=dwg_size, opacity=style['background']['opacity'])) ## Scale the graph to fit the svg canvas # First, find the bounds of the graph maxX = 0 maxY = 0 minX = 0 minY = 0 for node, data in self.nodes.items(): x = float(data['x']) y = float(data['y']) if (maxX == 0 and maxY == 0 and minX == 0 and minY == 0): maxX = x maxY = y minX = x minY = y if x > maxX: maxX = x if y > maxY: maxY = y if x < minX: minX = x if y < minY: minY = y scale = (max(scale_correction / maxX, scale_correction / maxY)) * size # Then calculate the transformation to fit the nodes on the canvas for node, data in self.nodes.items(): # Translate and scale nodes x = float(data['x']) y = float(data['y']) x -= (maxX + minX) / 2 y -= (maxY + minY) / 2 x *= scale y *= scale x += 1050 * size y += 1050 * size y = (2050 * size) - y # Store translated coordinates, with x,y offset data['x'] = x + offset[0] data['y'] = y + offset[1] ## Draw the edges edges_group = dwg.add(dwg.g()) for edge, data in self.edges.items(): # Pull out the sources and targets source = data['source'] target = data['target'] # Find the coordinates of each source and target start = (self.nodes[source]['x'], self.nodes[source]['y']) end = (self.nodes[target]['x'], self.nodes[target]['y']) # Shorten the line so it doesn't overlap the symbol source_size = ((float(self.nodes[source]['size']) * 5) / 2) * size target_size = ((float(self.nodes[target]['size']) * 5) / 2) * size edge_style = None # First set the edge style to the default of 'None', so if there isn't a connection type a line is still drawn for es in style['edges']: if es['label'] == None: edge_style = es # Then go over the connections again and if there is a matching connection type, set that as the edge_style for es in style['edges']: for v in data.values(): if es['label'] == v: edge_style = es break if curved == False: if edge_style['stroke-case'] > 0: if edge_style['stroke-dasharray'] is None: edges_group.add( dwg.line(start=start, end=end, stroke=edge_style['stroke-case-color'], stroke_width=edge_style['stroke-case'])) else: edges_group.add( dwg.line( start=start, end=end, stroke=edge_style['stroke-case-color'], stroke_width=edge_style['stroke-case'], stroke_dasharray=edge_style['stroke-dasharray'] )) if edge_style['stroke-dasharray'] is None: edges_group.add( dwg.line(start=start, end=end, stroke=edge_style['stroke'], stroke_width=edge_style['stroke-width'])) else: edges_group.add( dwg.line( start=start, end=end, stroke=edge_style['stroke'], stroke_width=edge_style['stroke-width'], stroke_dasharray=edge_style['stroke-dasharray'])) arrowhead_size = 5 * size offset = calculate_edge_offset(start, end, target_size) arrowhead_geom = arrowhead(start[0], start[1], offset[0], offset[1], r=arrowhead_size) if edge_style['stroke-case'] > 0: fill = edge_style['stroke-case-color'] else: fill = edge_style['stroke'] edges_group.add(dwg.polygon(arrowhead_geom, fill=fill)) else: path = draw_curved_path(dwg, start, end, edge_style) if edge_style['stroke-case'] > 0: edges_group.add(path[1]) edges_group.add(path[0]) else: edges_group.add(path) # Calculate arrowhead angle angle = angle_between_points(start, end) control_points = calculate_control_points(start, end) arrowhead_size = 5 * size crv = BSpline.Curve() crv.degree = 2 if (start[0] > end[0]): crv.ctrlpts = [start, control_points[0], end] else: crv.ctrlpts = [start, control_points[1], end] crv.knotvector = utilities.generate_knot_vector( crv.degree, len(crv.ctrlpts)) crv.delta = 0.05 curve_points = crv.evalpts l = LineString(curve_points) p = Point(end[0], end[1]) c = p.buffer(target_size).boundary i = c.intersection(l) # If the nodes are too close together, i sometimes returns empty, therefore don't draw the arrowhead try: if (start[0] > end[0]): arrowhead_geom = arrowhead(control_points[0][0], control_points[0][1], i.coords[0][0], i.coords[0][1], r=arrowhead_size) else: arrowhead_geom = arrowhead(control_points[1][0], control_points[1][1], i.coords[0][0], i.coords[0][1], r=arrowhead_size) except: pass #offset = calculate_edge_offset(start, end, target_size) #if (start[0] > end[0]): # arrowhead_geom = arrowhead(control_points[0][0], control_points[0][1], offset[0], offset[1], r=arrowhead_size) #else: # arrowhead_geom = arrowhead(control_points[1][0], control_points[1][1], offset[0], offset[1], r=arrowhead_size) if edge_style['stroke-case'] > 0: fill = edge_style['stroke-case-color'] else: fill = edge_style['stroke'] edges_group.add(dwg.polygon(arrowhead_geom, fill=fill)) ## Now draw the nodes nodes_group = dwg.add(dwg.g()) for node, data in self.nodes.items(): x = data['x'] y = data['y'] node_size = (node_scale * (float(data['size']) * size), node_scale * (float(data['size'])) * size) circle = nodes_group.add( dwg.circle(stroke='none', fill=style['background']['color'], center=(x, y), r=node_size[0] / 2)) # Get the symbology or colour scheme for node_style in style['nodes']: for v in data.values(): if node_style['label'] == v: with open(node_style['symbol'], 'rb') as file: img = file.read() encoded = base64.b64encode(img).decode() svgdata = 'data:image/svg+xml;base64,{}'.format( encoded) image = nodes_group.add( dwg.image(href=svgdata, insert=(x - (node_size[0] / 2), y - (node_size[0] / 2)), size=node_size)) # Add the labels for node, data in self.nodes.items(): x = data['x'] y = data['y'] node_size = (node_scale * (float(data['size']) * size), node_scale * (float(data['size'])) * size) font_size = (node_size[0] * size) * label_correction label = nodes_group.add( dwg.text(text=node, insert=(x, y + (node_size[0] * 0.2)), font_size=font_size, text_anchor='middle', font_family=style['label']['font-family'], fill=style['label']['fill'])) dwg.save()
# # Draw the control points polygon, the 3D curve and the vectors # fig = plt.figure('figure X', figsize=(10.67, 8), dpi= 96) # ax = Axes3D(fig) for j in range(curve_geometry.NbPoles): data = model_part.GetNode(j + 1).X, model_part.GetNode( j + 1).Y, model_part.GetNode(j + 1).Z ctlpts_list.write( str(model_part.GetNode(j + 1).X) + ',' + str(model_part.GetNode(j + 1).Y) + ',' + str(model_part.GetNode(j + 1).Z) + '\n') ctlpts_list.close() plot_curve.ctrlpts = exchange.import_txt( "C:\_Masterarbeit\BeamValidation\python_base\Balken\ctlpts_list.txt") plot_curve.knotvector = utilities.generate_knot_vector( plot_curve.degree, len(plot_curve.ctrlpts)) # Set evaluation delta # plot_curve.delta = 0.001 # plot_curve.evaluate # add to mulit_curve multi_curve.add(plot_curve) # Set evaluation delta multi_curve.delta = 0.001 # multi_curve.evaluate # plot the controlpoint polygon and the evaluated curve vis_comp = VisMPL.VisCurve3D() multi_curve.vis = vis_comp multi_curve multi_curve.render(cpcolor='black', evalcolor='red')
[274, 438], [193, 436], [150, 525], [204, 604]] pts_c = [[204, 604], [284, 612], [387, 577], [485, 475], [430, 366], [325, 231], [274, 438], [193, 436], [150, 525], [204, 604], [284, 612], [387, 577]] #pts = [[204, 604], [284, 612], [430, 366], [274, 438], [193, 436], [204, 604]] #pts_c = [[204, 604], [284, 612], [430, 366], [274, 438], [193, 436], [204, 604], [284, 612], [430, 366]] #radius = max([functions.euclid_dist(center, p) for p in pts]) curves_1 = [] curves_0 = [] curve.degree = 3 # order = degree + 1 curve.ctrlpts = pts_c curve.knotvector = utilities.generate_knot_vector(curve.degree, len(curve.ctrlpts), clamped=False) curve_list = operations.decompose_curve(curve) knot_vectors = [] radius = 0 for c in curve_list: knot_vectors.append(c.knotvector) curves_0.append(c) radius = max(radius, max([functions.euclid_dist(center, p) for p in c.ctrlpts])) base_pts = [(p[0], p[1]) for c in curve_list for p in c.ctrlpts] x, y, r = make_circle(base_pts) # O(n) center = (x, y) radius = r