Exemplo n.º 1
0
"""
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:
Exemplo n.º 2
0
        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)
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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()