def Matrix_Basis_Foot_Point(BSPLINES_FOOT_POINT, CONTROL, BSPLINES, KNOT, degree, t): """ Fonction retournant la matrice de base associé au Foot_Point.""" nb_control = np.shape(CONTROL)[0] nb_foot_point = np.shape(BSPLINES_FOOT_POINT)[0] BASIS = np.zeros((nb_foot_point, nb_control)) BASIS_DER1 = 0 * BASIS BASIS_DER2 = 0 * BASIS #ON PARCOURT LES FOOTPOINTS for i in range(nb_foot_point): #ELEMENT A CHERCHER DANS LA MATRICE DES BSPLINES search = BSPLINES_FOOT_POINT[i, :] #ON CHERCHE L'INDICE DANS BSPLINES DE search. CELA NOUS DONNERA UNE #INDICATION SUR LE 't' CORRESPONDANT DANS NEW_BSPLINES index = int((np.where(np.all(BSPLINES == search, axis=1)))[0]) for j in range(nb_control): BASIS[i, j] = bs.Basis_Function_Der(degree, KNOT, j, t[index], 0) BASIS_DER1[i, j] = bs.Basis_Function_Der(degree, KNOT, j, t[index], 1) BASIS_DER2[i, j] = bs.Basis_Function_Der(degree, KNOT, j, t[index], 2) return BASIS, BASIS_DER1, BASIS_DER2
def Point_de_reference(t, CONTROL, knot, degree): """Extraction des coordonnées ainsi que du repère de Frenet associé au point 't' de la BSpline définie par les points CONTROL, le vecteur de noeud knot et son degré.""" COORD = bs.BSplines_BasisFunction(CONTROL, knot, degree, t, 0) DER1 = bs.BSplines_BasisFunction(CONTROL, knot, degree, t, 1) DER2 = bs.BSplines_BasisFunction(CONTROL, knot, degree, t, 2) TAN = stats.tangente(DER1) BI = stats.binormale(DER1, DER2) NOR = stats.normale(BI, TAN) return COORD, TAN, NOR, BI
def Extraction(PCL, degree=5, max_iter=100, tol=1.e-8, rig=0): print(" ---> Initial construction of the Bspline curve") CONTROL = BSpline_Initiale(PCL) nbcontrol = len(CONTROL) t = np.linspace(0, 1, 200) print(" ------> Number of point in centerline : ", len(t)) print(" ------> Degree of the BSpline : ", degree) KNOT = bs.Knotvector(CONTROL, degree) BSPLINE, DER1, DER2, DER3 = bs.BSplines_RoutinePython(CONTROL, KNOT, degree, t, dimension=3) BASIS_DER2 = bs.Matrix_Basis_Function(degree, KNOT, nbcontrol, t, 2) print(" ---> Start of the BSpline fitting inside the Point Cloud") print(" ------> Max_iterations = ", max_iter) print(" ------> error_tolerance = ", tol) print(" ------> rigidity = ", rig) tab_it = [] tab_err = [0, 1] it = 0 start_time = time.time() while it < max_iter and np.abs(tab_err[-1] - tab_err[-2]) > tol: #FITTING SIMPLE NEW_CONTROL, NEW_BSPLINES, erreur = Fitting(PCL, CONTROL, BSPLINE, KNOT, BASIS_DER2, degree, t, rig) tab_err.append(erreur) #MISE A JOUR CONTROL = NEW_CONTROL BSPLINE = NEW_BSPLINES #INCREMENTATION it += 1 print(" ------> Final number of iterations = ", it) print(" ------> Final error = ", erreur) CENTERLINE = BSPLINE end_time = time.time() print(" ------> Total time of fitting : ", round(end_time - start_time, 2)) return CENTERLINE
def Parametrization_section(CONTROL, aorte, liste_t, liste_theta, degree, coeff_fourier): knot = bs.Knotvector(CONTROL, degree) coordonnees = [] r_theta = [] contour = [] tan = [] nor = [] bi = [] coeff_determination = [] ############### BOUCLE POUR CHAQUE COUPURE ################# for i in range(len(liste_t)): print(" ------> PARAMETRIZATION RUNNING : {}%".format(round((i/len(liste_t))*100),2), end = "\r") start_ite = time.time() #EXTRAIT LES COORDONNEES DU POINT ET LE REPERE DE FRENET COORD, TAN, NOR, BI = Point_de_reference(liste_t[i], CONTROL, knot, degree) X_t = COORD[:,0] Y_t = COORD[:,1] Z_t = COORD[:,2] #SAVE COORDONNATES AND FRENET FRAME coordonnees.append(COORD) tan.append(TAN) nor.append(NOR) bi.append(BI) #CALCUL DE LA MATRICE DE PASSAGE DE LA BASE CANONIQUE A LA BASE DEFINIE PAR #LE REPERE DE FRENET PASSAGE = Matrice_de_passage(TAN, NOR, BI) #COUPURE DE L'AORTE PAR LE PLAN (N/B). POUR TOUT POINT DE LA COUPURE, RESSORT #SON ANGLE / NORMALE (COLONNE 0) ET SA DISTANCE / COORD (COLONNE 2). #PERMET D'EXPRIMER UN MODELE VIA UNE SERIE DE FOURIER. THETA_R_EXP, COORD_PLAN, COUPURE_PLAN = Modelisation_contour(PASSAGE, COORD, TAN, aorte) #EFFECTUE LE FITTING DU MODELE D'ORDRE n VIA UNE SERIE DE FOURIER fit = Modele_Fourier(THETA_R_EXP, ordre = coeff_fourier) #ON CALCUL LES R CORRESPONDANTS AUX THETA GRACE AU MODELE ET ON RESSORT #L'ERREUR DU MODELE THETA_R_APPROX, erreur = Theta_R_Approx(fit, THETA_R_EXP, liste_theta) r_theta.append(THETA_R_APPROX[:,1]) coeff_determination.append(erreur) #ON RECONSTRUIT LES POINTS RECONSTRUIT DANS LA BASE CANONIQUE CONTOUR = Reconstruction_contour(COORD_PLAN, THETA_R_APPROX, PASSAGE, COUPURE_PLAN) contour.append(CONTOUR) end_ite = time.time() ############### FIN BOUCLE ################################# return coordonnees, r_theta, contour, tan, nor, bi, coeff_determination
def Centerline_BSpline(path_reader, nb_control=10, nb_points=200, degree=5): CENTERLINE = VTPCenterline_To_Numpy(path_reader) NEW = CENTERLINE[20:np.shape(CENTERLINE)[0] - 20, :] N = np.shape(NEW)[0] indices = np.linspace(0, N - 1, nb_control, dtype='int') CONTROL = NEW[indices, :] t = np.linspace(0, 1, nb_points) KNOT = bs.Knotvector(CONTROL, degree) BSPLINE, DER1, DER2, DER3 = bs.BSplines_RoutinePython(CONTROL, KNOT, degree, t, dimension=3) return CONTROL, BSPLINE
def frenet_frame(POINTS): #NUMBER OF POINTS n = len(POINTS) t = np.linspace(0, 1, n) degree = 3 knot = bs.Knotvector(POINTS, degree) BSPLINE, DER1, DER2, DER3 = bs.BSplines_RoutinePython(POINTS, knot, degree, t, dimension=3) T = tangente(DER1) B = binormale(DER1, DER2) N = normale(B, T) return BSPLINE, T, N, B
def Construction_bsplines(procrust_control, nb_points, degree): procrust_bsplines = [] t = np.linspace(0, 1, nb_points) for i in range(len(procrust_control)): CONTROL = procrust_control[i] KNOT = bs.Knotvector(CONTROL, degree) BSPLINES, DER1, DER2, DER3 = bs.BSplines_RoutinePython(CONTROL, KNOT, degree, t, dimension=3) BSPLINES = np.insert(BSPLINES, 3, i, axis=1) procrust_bsplines.append(BSPLINES) #gf.Write_csv("PROCRUST_BSPLINES.csv", np.vstack(procrust_bsplines), "x, y, z, num") return procrust_bsplines
def arc_length(tfinal, CTRL): degree = 3 knotvector = bs.Knotvector(CTRL, degree) length = integrate.fixed_quad(func_to_integrate, 0.0, tfinal, args=(CTRL, degree, knotvector), n=10) return length[0]
def BSplines_Update_3D(D, CONTROL, KNOT, degree, t): """ Ressort les nouveaux points de controles ainsi que les nouvelles bsplines apres Update par le vecteur D""" nb_control = np.shape(CONTROL)[0] DD = Vector_to_matrix(D, dimension=3) #ON CREE LA NOUVELLE BSPLINES NEW_CONTROL = CONTROL + DD NEW_CONTROL[0, :] = CONTROL[0, :] NEW_CONTROL[-1, :] = CONTROL[-1, :] NEW_BSPLINES, DER1, DER2, DER3 = bs.BSplines_RoutinePython(NEW_CONTROL, KNOT, degree, t, dimension=3) return NEW_CONTROL, NEW_BSPLINES
def func_to_integrate(t, CTRL, degree, knotvector): DER = bs.BSplines_BasisFunction(CTRL, knotvector, degree, t, 1) function = np.sqrt(DER[:, 0]**2 + DER[:, 1]**2 + DER[:, 2]**2) return function