""" import os from geomdl import NURBS # Try to load the visualization module try: render_curve = True from geomdl.visualization import VisMPL except ImportError: render_curve = False # Fix file path os.chdir(os.path.dirname(os.path.realpath(__file__))) # Create a NURBS curve instance (full circle) curve = NURBS.Curve() # Set evaluation delta curve.delta = 0.01 # Set up curve curve.read_ctrlpts_from_txt("ex_curve04.cptw") curve.degree = 2 # Use a specialized knot vector curve.knotvector = [0, 0, 0, 0.25, 0.25, 0.5, 0.5, 0.75, 0.75, 1, 1, 1] # Evaluate curve curve.evaluate() # Draw the control point polygon and the evaluated curve if render_curve:
def process(self): if not any(socket.is_linked for socket in self.outputs): return vertices_s = self.inputs['ControlPoints'].sv_get() has_weights = self.inputs['Weights'].is_linked weights_s = self.inputs['Weights'].sv_get(default = [[1.0]]) knots_s = self.inputs['Knots'].sv_get(default = [[]]) degree_s = self.inputs['Degree'].sv_get() curves_out = [] knots_out = [] for vertices, weights, knots, degree in zip_long_repeat(vertices_s, weights_s, knots_s, degree_s): if isinstance(degree, (tuple, list)): degree = degree[0] n_source = len(vertices) fullList(weights, n_source) if self.knot_mode == 'AUTO' and self.is_cyclic: vertices = vertices + vertices[:degree+1] weights = weights + weights[:degree+1] n_total = len(vertices) # Create a 3-dimensional B-spline Curve if self.surface_mode == 'NURBS': curve = NURBS.Curve(normalize_kv = self.normalize_knots) else: curve = BSpline.Curve(normalize_kv = self.normalize_knots) # Set degree curve.degree = degree # Set control points (weights vector will be 1 by default) # Use curve.ctrlptsw is if you are using homogeneous points as Pw curve.ctrlpts = vertices if has_weights and self.surface_mode == 'NURBS': curve.weights = weights # Set knot vector if self.knot_mode == 'AUTO': if self.is_cyclic: self.debug("N: %s, degree: %s", n_total, degree) knots = list(range(n_total + degree + 1)) else: knots = knotvector.generate(curve.degree, n_total) self.debug('Auto knots: %s', knots) curve.knotvector = knots else: self.debug('Manual knots: %s', knots) #if not knotvector.check(curve.degree, knots, len(curve.ctrlpts)): # raise Exception("Explicitly provided knot vector is incorrect!") curve.knotvector = knots new_curve = SvExGeomdlCurve(curve) if self.is_cyclic: u_min = curve.knotvector[degree] u_max = curve.knotvector[-degree-2] new_curve.u_bounds = u_min, u_max else: u_min = min(curve.knotvector) u_max = max(curve.knotvector) new_curve.u_bounds = (u_min, u_max) curves_out.append(new_curve) knots_out.append(curve.knotvector) self.outputs['Curve'].sv_set(curves_out) self.outputs['Knots'].sv_set(knots_out)
def NURBS_PrePros (points, weights, knots, A, J, E, F, T): crv = NURBS.Curve() #задание кривой crv.degree = 3 #степень crv.ctrlpts = points #контрольные точки crv.weights = weights #весы опорных точек crv.knotvector = knots #узловой вектор MAXcurve = [] curve = [] #список точек кривой curvature_list = [] #список значений кривизны kThres_list = [] #список значений порога кривизны t_list = [] #список значений параметра t candPC_sublist = [] #список временный candP_sublist = [] #список временный candT_sublist = [] #список временный candPC_list = [] #список значений кривизны кандидатных точек candP_list = [] #список кандидатных точек candT_list = [] #список параметров t кандидатных точек subCurve_list = [] #Список точек подкривой subCurve = [] #Список точек всех подкривых t_out = [] #Список начальных и конечных параметров t для подкривых #начало расчета t = knots[0] #начальное значение параметра M = 100 #число итераций curve = crv.evalpts while round(t, 3) <= knots[-1]: ders = crv.derivatives(t, order=2) #расчет производных кривой (исходной точки кривой, 1 и 2 производной) der_1 = ders[1] der_2 = ders[2] #кривизна curvature = fabs((der_1[0]*der_2[1]-der_1[1]*der_2[0]))/pow((sqrt(der_1[0]*der_1[0]+ der_1[1]*der_1[1])), 3) curvature_list.append(curvature) #порог кривизны kThres = min(8*E/(pow(F*T, 2)+4*E*E), A/(F*F), sqrt(J/(pow(F, 3)))) kThres_list.append(kThres) #параметр t t_list.append(t) #проверка на кандидатную точку if curvature > kThres: candPC_sublist.append(curvature) #сохранение кандидатной точки candP_sublist.append(ders[0]) #сохранение кандидатной точки candT_sublist.append(t) #сохранение кандидатной точки elif curvature <= kThres and candPC_sublist != []: candPC_list.append(candPC_sublist) candP_list.append(candP_sublist) candT_list.append(candT_sublist) candPC_sublist = [] candP_sublist = [] candT_sublist = [] #инкремент параметра t t += 1/M t = round(t, 3) if candPC_sublist != []: candPC_list.append(candPC_sublist) candP_list.append(candP_sublist) candT_list.append(candT_sublist) candPC_sublist = [] candP_sublist = [] candT_sublist = [] #график кривизны и порога кривизны Graphs.Graph_02 (t_list, curvature_list, t_list, kThres_list, "Параметр u", "Кривизна к", "График кривизны NURBS", "Кривизна", "Порог кривизны", "Кривизна") #график #нахождение критических точек и разбиение кривой на подкривые tl = 0 t_out.append(t_list[tl]) for i in range (len(candPC_list)): critP = max(candPC_list[i]) #локальный максимум кривизны MAXcurve.append(critP) tc = curvature_list.index(critP) t_out.append(t_list[tc]) print("Локальный максимум кривизны " + str(i+1) + " = " + str(critP)) print("Точка кривой = " + str(candP_list[i][candPC_list[i].index(critP)])) print("Параметр t = " + str(candT_list[i][candPC_list[i].index(critP)])) subCurve += (curve[tl:tc+1]) tl = tc subCurve_list.append(subCurve) #график подкривой x = [] y = [] for j in range (len(subCurve)): x.append(subCurve[j][0]) y.append(subCurve[j][1]) subCurve = [] Graphs.Graph_01 (x, y, "X, мм", "Y, мм", "Подкривая " + str(len(subCurve_list)), "Траектория", "Подкривая " + str(len(subCurve_list))) #график MAXcurve.append(curvature_list[-1]) tc = t_list.index(t_list[-1]) t_out.append(t_list[tc]) subCurve += (curve[tl:tc+1]) subCurve_list.append(subCurve) #график последней подкривой x = [] y = [] for i in range (len(subCurve)): x.append(subCurve[i][0]) y.append(subCurve[i][1]) subCurve = [] Graphs.Graph_01 (x, y, "X, мм", "Y, мм", "Подкривая " + str(len(subCurve_list)), "Траектория", "Подкривая " + str(len(subCurve_list))) #график #график кривой (всех подкривых) x = [] y = [] for i in range (len(subCurve_list)): for j in range (len(subCurve_list[i])): x.append(subCurve_list[i][j][0]) y.append(subCurve_list[i][j][1]) Graphs.Graph_01 (x, y, "X, мм", "Y, мм", "Кривая", "Траектория", "Кривая") #график #Цветной график подкривых """ x1 = [] y1 = [] x2 = [] y2 = [] x3 = [] y3 = [] x4 = [] y4 = [] for i in range(len(subCurve_list[0])): x1.append(subCurve_list[0][i][0]) y1.append(subCurve_list[0][i][1]) for i in range(len(subCurve_list[1])): x2.append(subCurve_list[1][i][0]) y2.append(subCurve_list[1][i][1]) for i in range(len(subCurve_list[2])): x3.append(subCurve_list[2][i][0]) y3.append(subCurve_list[2][i][1]) for i in range(len(subCurve_list[3])): x4.append(subCurve_list[3][i][0]) y4.append(subCurve_list[3][i][1]) Graphs.Graph_04(x1, y1, x2, y2, x3, y3, x4, y4, "X, мм", "Y, мм", "Кривая после анализа геометрии", "Подкривая 1", "Подкривая 2", "Подкривая 3", "Подкривая 4", "Кривая цветная") """ #график кривой и исходного полигона x = [] y = [] for i in range(len(points)): x.append(points[i][0]) y.append(points[i][1]) x_1 = [] y_1 = [] for i in range (len(curve)): x_1.append(curve[i][0]) y_1.append(curve[i][1]) Graphs.Graph_02 (x, y, x_1, y_1, "X, мм", "Y, мм", "Кривая и опорный многоугольник", "Опорный многоугольник", "Кривая", "Кривая и полигон") #график #подсчет длины подкривой и формирования блоков подкривых out_list = [] #выходной список for i in range (len(subCurve_list)): subC_len = NURBSLength(subCurve_list[i]) #подсчет длины пути на подкривой out_list.append([subC_len, t_out[i], t_out[i+1], MAXcurve[i]]) #формирование выходного списка длин и парамтеров подкривых return out_list
def createnurbsopening(idd_filename, idf_filename, base_surface, opening_str, ctrl_points, evaluated_points=50): ########################################## # 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.createopening: unable to find the base surface', base_surface, 'in', idf_filename) return ################################# # calculating NURBS curve points ################################# from geomdl import NURBS from geomdl import utilities # one has to exclude checks for leading zeros and trailing ones in geomdl.utilities.check_knot_vector # in order for this knotvector to be allowed! utilities.check_knot_vector = new_check_knot_vector curve = NURBS.Curve() # 1/delta corresponds to the number of evaluated points of a NURBS curve that defines the opening curve.delta = 1/evaluated_points curve.degree = 3 # add weight 1 to each control point for cpt in ctrl_points: if len(cpt)<4: cpt.append(1.0) # add copy of the first degree control points in order to close NURBS curve extra_points = ctrl_points[:curve.degree] ctrl_points.extend(extra_points) # sets curve control points curve.set_ctrlpts(ctrl_points) # sets knot vector for closed NURBS curve # note that the length of ctrl_points has increased for curve.degree due to extend operation knotstep = 1/(len(ctrl_points) + curve.degree) curve.knotvector = [i*knotstep for i in range(len(ctrl_points)+curve.degree+1)] # note that for the closed NURBS curve # we have to use only the domain [knotvector[curve.degree], knotvector[len(ctrl_points)]]!!! # evaluates curve points curve.evaluate(curve.degree*knotstep, len(ctrl_points)*knotstep) # make a local copy of evaluated curve points crv_points = curve.curvepts ######################################################################### # feet of perpendiculars from the NURBS curve points to the base surface, # just to make sure we are not getting out of its plane ######################################################################### # 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 u = [ blc[0]-ulc[0], blc[1]-ulc[1], blc[2]-ulc[2] ] v = [ brc[0]-blc[0], brc[1]-blc[1], brc[2]-blc[2] ] N = crossproduct(u,v) N = normalize(N) # calculate feet of perpendiculars feet_points = [foot(crv_points[i], ulc, N) for i in range(len(crv_points))] ####################################################################################### # create a list of 0.1m squares that partition the whole wall surface # !!! it is assumed that the wall surface is a rectangle # !!! three of whose vertices are ulc, blc and brc (and the fourth one is ulc+brc-blc) ####################################################################################### # a new orthonormal system for the wall surface u = normalize(u) v = crossproduct(N,u) v = normalize(v) # transform feet_point coordinates to the uv system # since N, u, v is an orthonormal system we have that # for each vector X = <X,N>N + <X,u>u + <X,v>v # this will be applied to vectors feet_points-ulc which belong to the wall surface plane feet_points_uv = [ [dotproduct(subtract(fp, ulc), u), dotproduct(subtract(fp, ulc), v)] for fp in feet_points] # form a list of squares and a list of their centers in uv coordinates squaresize = 0.1 maxi = int(length(subtract(blc, ulc))/squaresize)-1 maxj = int(length(subtract(brc, blc))/squaresize)-1 squarelist = [ [ [ ((i+0.5)*squaresize, (j+0.5)*squaresize), ((i+1.5)*squaresize, (j+0.5)*squaresize), ((i+1.5)*squaresize, (j+1.5)*squaresize), ((i+0.5)*squaresize, (j+1.5)*squaresize) ] for j in range(maxj) ] for i in range(maxi)] squarecenters = [ ( (i+1)*squaresize, (j+1)*squaresize ) for i in range(maxi) for j in range(maxj) ] # for each square check whether its center belongs to the polygon defined by NURBS curve points import matplotlib.path as mplPath path = mplPath.Path(feet_points_uv) inside = path.contains_points(squarecenters) # select only those squares whose centers are inside the NURBS curve insideindices = [ [ j for j in range(maxj) if inside[i*maxj+j] ] for i in range(maxi) ] # now insideindices[i] contains all j such that squarelist[i][j] is inside a NURBS curve ################################################################################# # create string of idf definitions for rectangles that approximate NURBS opening ################################################################################# idf_total_opening_def = "" for i in range(maxi): # go through all inside squares within i-th column, if there are any if len(insideindices[i])>0: # pn and kn contain the beginning and the end of # subsequences of consecutive numbers within the insideindices[i] list pn = insideindices[i][0] kn = insideindices[i][0] for k in range(1, len(insideindices[i])+1): if k<len(insideindices[i]) and insideindices[i][k]==insideindices[i][k-1]+1: # consecutive subsequence goes on kn = insideindices[i][k] else: # consecutive subsequence had ended, so create an opening element # squarelist[i][pn][0],[1] contain its first two vertices in uv system, # squarelist[i][kn][2],[3] contain its last two vertices in uv system # recalculate vertices in xyz system first vertex1 = [ ulc[0] + squarelist[i][pn][0][0] * u[0] + squarelist[i][pn][0][1] * v[0], ulc[1] + squarelist[i][pn][0][0] * u[1] + squarelist[i][pn][0][1] * v[1], ulc[2] + squarelist[i][pn][0][0] * u[2] + squarelist[i][pn][0][1] * v[2] ] vertex2 = [ ulc[0] + squarelist[i][pn][1][0] * u[0] + squarelist[i][pn][1][1] * v[0], ulc[1] + squarelist[i][pn][1][0] * u[1] + squarelist[i][pn][1][1] * v[1], ulc[2] + squarelist[i][pn][1][0] * u[2] + squarelist[i][pn][1][1] * v[2] ] vertex3 = [ ulc[0] + squarelist[i][kn][2][0] * u[0] + squarelist[i][kn][2][1] * v[0], ulc[1] + squarelist[i][kn][2][0] * u[1] + squarelist[i][kn][2][1] * v[1], ulc[2] + squarelist[i][kn][2][0] * u[2] + squarelist[i][kn][2][1] * v[2] ] vertex4 = [ ulc[0] + squarelist[i][kn][3][0] * u[0] + squarelist[i][kn][3][1] * v[0], ulc[1] + squarelist[i][kn][3][0] * u[1] + squarelist[i][kn][3][1] * v[1], ulc[2] + squarelist[i][kn][3][0] * u[2] + squarelist[i][kn][3][1] * v[2] ] vert_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format( vertex1[0], vertex1[1], vertex1[2], vertex2[0], vertex2[1], vertex2[2], vertex3[0], vertex3[1], vertex3[2], vertex4[0], vertex4[1], vertex4[2]) countervert_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format( vertex1[0], vertex1[1], vertex1[2], vertex4[0], vertex4[1], vertex4[2], vertex3[0], vertex3[1], vertex3[2], vertex2[0], vertex2[1], vertex2[2]) # fill out the entries in the opening string definition single_opening_def = opening_str.replace('<IDX>', str(i)+'_'+str(pn)).replace('<BASESURFACE>', base_surface).replace('<VERTICES>', vert_str).replace('<COUNTERVERTICES>', countervert_str) idf_total_opening_def = idf_total_opening_def + single_opening_def # a new consecutive subsequence has just begun provided that k<len(insideindices[i]) if k<len(insideindices[i]): pn = insideindices[i][k] kn = insideindices[i][k] # create idf opening objects from the string containing opening definitions from io import StringIO idf_opening = IDF(StringIO(idf_total_opening_def)) # copy idf shading objects to the existing idf file openings = idf_opening.idfobjects["FENESTRATIONSURFACE:DETAILED"] for opening in openings: idf_collection.copyidfobject(opening) ############################### # at the end, save the changes ############################### idf_collection.save()