def getExtraOrdCornerIndexMask(quad_list, AVertexList, B1VertexList, B2VertexList, CVertexList, quad_control_point_indices, quad_index, whichCorner): # TODO: Understand and change code mod_index = lambda i, modul: (i) % modul shifted_indices = lambda ind, modul: mod_index( np.array(range(modul)) + ind, modul) reverse_shifted_indices = lambda ind, modul: mod_index( np.arange(modul, 0, -1) + ind, modul) cornerVertexIndex = quad_list[quad_index, whichCorner] numberOfEdges = get_num_edges_meeting( AVertexList, cornerVertexIndex ) # todo Juan Carlos: with the objects this is very nice. quadLocalIndex = np.where(AVertexList[cornerVertexIndex, :, 1] == quad_index) if checkB1B2Reversal_opt(B1VertexList, quad_list, quad_index, cornerVertexIndex, quad_control_point_indices): if checkB1B2OrientationReversal(B2VertexList, B1VertexList, quad_list, quad_index, cornerVertexIndex): aroundcorner_indices = reverse_shifted_indices( quadLocalIndex, numberOfEdges) else: aroundcorner_indices = shifted_indices(quadLocalIndex, numberOfEdges) B1Indices = B2VertexList[cornerVertexIndex, aroundcorner_indices, 0] B2Indices = B1VertexList[cornerVertexIndex, aroundcorner_indices, 0] else: if checkB1B2OrientationReversal(B1VertexList, B2VertexList, quad_list, quad_index, cornerVertexIndex): aroundcorner_indices = reverse_shifted_indices( quadLocalIndex, numberOfEdges) else: aroundcorner_indices = shifted_indices(quadLocalIndex, numberOfEdges) B1Indices = B1VertexList[cornerVertexIndex, aroundcorner_indices, 0] B2Indices = B2VertexList[cornerVertexIndex, aroundcorner_indices, 0] AIndices = AVertexList[cornerVertexIndex, aroundcorner_indices, 0] CIndices = CVertexList[cornerVertexIndex, aroundcorner_indices, 0] indexMask = np.array([ AIndices[:].reshape([1, numberOfEdges]), B1Indices[:].reshape( [1, numberOfEdges]), B2Indices[:].reshape([1, numberOfEdges]), CIndices[:].reshape([1, numberOfEdges]) ], dtype=int) return np.squeeze(indexMask)
def getExtraOrdCornerIndexMask(quad_list,AVertexList,B1VertexList,B2VertexList,CVertexList,quad_control_point_indices,quad_index,whichCorner): # TODO: Understand and change code mod_index = lambda i, modul: (i)%modul shifted_indices = lambda ind, modul: mod_index(np.array(range(modul)) + ind,modul) reverse_shifted_indices = lambda ind, modul: mod_index(np.arange(modul,0,-1) + ind,modul) cornerVertexIndex = quad_list[quad_index,whichCorner] numberOfEdges = get_num_edges_meeting(AVertexList, cornerVertexIndex) # todo Juan Carlos: with the objects this is very nice. quadLocalIndex = np.where(AVertexList[cornerVertexIndex,:,1] == quad_index) if checkB1B2Reversal_opt(B1VertexList,quad_list,quad_index,cornerVertexIndex,quad_control_point_indices): if checkB1B2OrientationReversal(B2VertexList,B1VertexList,quad_list,quad_index,cornerVertexIndex): aroundcorner_indices = reverse_shifted_indices(quadLocalIndex,numberOfEdges) else: aroundcorner_indices = shifted_indices(quadLocalIndex,numberOfEdges) B1Indices = B2VertexList[cornerVertexIndex,aroundcorner_indices,0] B2Indices = B1VertexList[cornerVertexIndex,aroundcorner_indices,0] else: if checkB1B2OrientationReversal(B1VertexList,B2VertexList,quad_list,quad_index,cornerVertexIndex): aroundcorner_indices = reverse_shifted_indices(quadLocalIndex,numberOfEdges) else: aroundcorner_indices = shifted_indices(quadLocalIndex,numberOfEdges) B1Indices = B1VertexList[cornerVertexIndex,aroundcorner_indices,0] B2Indices = B2VertexList[cornerVertexIndex,aroundcorner_indices,0] AIndices = AVertexList[cornerVertexIndex,aroundcorner_indices,0] CIndices = CVertexList[cornerVertexIndex,aroundcorner_indices,0] indexMask = np.array([AIndices[:].reshape([1, numberOfEdges]), B1Indices[:].reshape([1, numberOfEdges]), B2Indices[:].reshape([1, numberOfEdges]), CIndices[:].reshape([1, numberOfEdges])], dtype=int) return np.squeeze(indexMask)
def checkB1B2OrientationReversal(B1,B2,quad_list,quad_index,vertex_index): """ check if the B1 in the quad to the right lies along the same edge as the B2 in the current quad. :param B1: :param B2: :param quad_list: :param quad_index: :param vertex_index: :return: a Bool? """ vertex_index = int(vertex_index) numberOfEdges = get_num_edges_meeting(B1, vertex_index) quadNumberLocal = np.where(B1[vertex_index,:,1] == quad_index)[0][0] B1EdgeFromB1 = np.reshape(B1[vertex_index,quadNumberLocal,2:4],2) shouldBeSameAsB1Edge = np.reshape(B2[vertex_index,(quadNumberLocal - 1)%numberOfEdges,2:4], 2) isB1IfReversed = np.reshape(B2[vertex_index,(quadNumberLocal + 1)%numberOfEdges,2:4],2) B2EdgeFromB2 = np.reshape(B2[vertex_index,quadNumberLocal,2:4],2) shouldBeSameAsB2Edge = np.reshape(B1[vertex_index,(quadNumberLocal + 1)%numberOfEdges,2:4],2) isB2IfReversed = np.reshape(B1[vertex_index,(quadNumberLocal - 1)%numberOfEdges,2:4],2) thisQuad_cornerVertices = quad_list[quad_index,:] whichQuadCorner = np.where(thisQuad_cornerVertices == vertex_index)[0][0] """ in peter's scheme, and therefore in the parameters, B1 is the left one if looking into the quad corner. Since the quad corners go clockwise, that means the relevant quad corner and the one after should be """ shouldBeB1Edge = thisQuad_cornerVertices[[whichQuadCorner,(whichQuadCorner+1)%4]] shouldBeB2Edge = thisQuad_cornerVertices[[whichQuadCorner, (whichQuadCorner-1)%4]] if len(np.intersect1d(B1EdgeFromB1,shouldBeB1Edge)) == 2 and \ len(np.intersect1d(B2EdgeFromB2,shouldBeB2Edge)) == 2: if len(np.intersect1d(B1EdgeFromB1,shouldBeSameAsB1Edge)) == 2 and \ len(np.intersect1d(B2EdgeFromB2,shouldBeSameAsB2Edge)) == 2: isNotCounterClockwise = False elif len(np.intersect1d(B1EdgeFromB1,isB1IfReversed)) == 2 and \ len(np.intersect1d(B2EdgeFromB2,isB2IfReversed)) == 2: isNotCounterClockwise = True else: raise Exception('something is seriously wrong because the edges don`t add upp. ' 'in checkB1B2OrientationReversal') elif len(np.intersect1d(B1EdgeFromB1,shouldBeB2Edge)) == 2: raise Exception('I didn`t write this function and the other one for you to be lazy ' 'and not use the other to check for reversed b1b2') else: print 'quad_index: ' print quad_index print 'vertex_index' print vertex_index raise Exception('ERROR! Something wrong with the edges around the quads! ' 'Function checkB1B2OrientationReversal') return isNotCounterClockwise
def createGlobalControlMeshCoefs(parameterCoordinates, quad_list, AVertexList, B1VertexList, B2VertexList, CVertexList, quad_control_point_indices): ''' Takes, for N datapoints, an array parameterCoordinates[Nx3](for every datapoint: first entry the quad index, second and third parameters on a patch that spans over [0,1]x[0,1] for the quad. The function computes the coefficient matrix for between each datapoint and the array of M/16 quads x [4x4] vertex control points, outputting the coefficients as an N x M scipy.sparse COO-type sparse matrix @param parameterCoordinates: Nx3 numpy.ndarray of datapoint parameters @param quad_list: @param AVertexList: @param B1VertexList: @param B2VertexList: @param CVertexList: @param quad_control_point_indices: (M/16)x16 numpy.ndarray of control points on each quad @return: NxM scipy.sparse COO-type sparse matrix of coefficients, maximum 22 nonzero entries per row ''' N = parameterCoordinates.shape[0] M = quad_control_point_indices.shape[0] * quad_control_point_indices.shape[1] max_size = N*28 #4 types of vertices times maximum 7 quads around an extraordinary vertex (large estimate) rows = np.zeros(max_size, dtype=int) cols = np.zeros(max_size, dtype=int) data = np.zeros(max_size) """ Precalculate the coefficients between all the vertex control points and the bezier control points for 7 different number of intersecting edges as a start (number of incoming edges(between 3 an 7 hardcoded), [A,B1,B2,C], [in which quad 1-7], bezier point first coord, bezier point second coord) """ ACoefsRaw = np.zeros((7,7,4,4)) B1CoefsRaw = np.zeros((7,7,4,4)) B2CoefsRaw = np.zeros((7,7,4,4)) CCoefsRaw = np.zeros((7,7,4,4)) for num_quads in range(3,8): [ACoefsRaw[num_quads-1, 0:num_quads, :, :], B1CoefsRaw[num_quads-1, 0:num_quads, :, :], B2CoefsRaw[num_quads-1, 0:num_quads, :, :], CCoefsRaw[num_quads-1, 0:num_quads, :, :]] = createBicubicCoefMatrices(num_quads) # compared to matlab by Saumi & Benni -> VALID coefsRawTemp = np.zeros((4,7,4,4)) indexCounter = 0 print "Main Loop Coefs" for p in range(N): if p%100 == 0: print "processing point %d of %d..." % (p, N) #check if on a corner patch : if both coords are outside [0.25,0.75] quadParameters = parameterCoordinates[p, 1:3] quad_index = int(parameterCoordinates[p, 0]) [localCoords, whichCorner, whichPatch] = createLocalParamsExtraordinary(global_quad_params=quadParameters) #print "p=%d"%p # todo for p=1 get3x3... fails! -> Resolved(?). #print "whichPatch="+str(whichPatch) # if there is a specified corner set if whichCorner != -1: cornerVertexIndex = quad_list[quad_index, whichCorner] numberOfEdges = get_num_edges_meeting(AVertexList, cornerVertexIndex) #TODO: Check output PROBLEM! indexMask = getExtraOrdCornerIndexMask(quad_list, AVertexList, B1VertexList, B2VertexList, CVertexList, quad_control_point_indices, quad_index, whichCorner) coefsRawTemp[0, 0:numberOfEdges, :, :] = ACoefsRaw[numberOfEdges-1, 0:numberOfEdges, :, :] coefsRawTemp[1, 0:numberOfEdges, :, :] = B1CoefsRaw[numberOfEdges-1, 0:numberOfEdges, :, :] coefsRawTemp[2, 0:numberOfEdges, :, :] = B2CoefsRaw[numberOfEdges-1, 0:numberOfEdges, :, :] coefsRawTemp[3, 0:numberOfEdges, :, :] = CCoefsRaw[numberOfEdges-1, 0:numberOfEdges, :, :] patchCoefsMatrix = getBicubicBezierPointCoefs(localCoords, coefsRawTemp[:, 0:numberOfEdges, :, :]) numberOfEntries = numberOfEdges*4 rows[indexCounter:(indexCounter + numberOfEntries)] = p cols[indexCounter:(indexCounter + numberOfEntries)] = indexMask.flatten()[:] data[indexCounter:(indexCounter + numberOfEntries)] = patchCoefsMatrix.flatten()[:] indexCounter += numberOfEntries else: neighbourMask = get3x3ControlPointIndexMask(quad_list=quad_list, quad_control_point_indices=quad_control_point_indices, quad_index=quad_index, localIndexXY=whichPatch) neighbourCoefs = getBezierPointCoefs(localCoords) numberOfEntries = 9 rows[indexCounter:(indexCounter + numberOfEntries)] = p cols[indexCounter:(indexCounter + numberOfEntries)] = neighbourMask.flatten()[:] data[indexCounter:(indexCounter + numberOfEntries)] = neighbourCoefs.flatten()[:] indexCounter += numberOfEntries print "Main Loop Coeffs Done." return ssp.coo_matrix((data, (rows, cols)), shape=(N, M))
def sortAB1B2VIndices(oldA,oldB1,oldB2,oldC): def mimic_matlab_row_intersect(M1, M2): M1_dict = {tuple(M1[i,:]):i for i in range(M1.shape[0])} M2_dict = {tuple(M2[i,:]):i for i in range(M2.shape[0])} keys = M1_dict.viewkeys() & M2_dict.viewkeys() MM = [] for key in keys: MM.append(list(key)) MM = np.array(MM) i = np.lexsort((MM[:,1],MM[:,0])) MM=MM[i] M1_ids = [] M2_ids = [] for key in MM: M1_ids.append(M1_dict[tuple(key)]) M2_ids.append(M2_dict[tuple(key)]) return MM, M1_ids, M2_ids assert type(oldA) is np.ndarray assert type(oldB1) is np.ndarray assert type(oldB2) is np.ndarray assert type(oldC) is np.ndarray newB1 = -1*np.ones(oldB1.shape) newB2 = -1*np.ones(oldB2.shape) newA = -1*np.ones(oldA.shape) newC = -1*np.ones(oldC.shape) for i in range(oldB2.shape[0]): m = get_num_edges_meeting(oldB2, i) indicesLocB1 = np.zeros(m,dtype=int) indicesLocB2 = np.zeros(m,dtype=int) indicesLocA = np.zeros(m,dtype=int) indicesLocC = np.zeros(m,dtype=int) BB1 = np.reshape(oldB1[i,0:m,2:4],[m,2]) BB2 = np.reshape(oldB2[i,0:m,2:4],[m,2]) idontcare,B1Indices,B2Indices = mimic_matlab_row_intersect(BB1,BB2) #todo hopefully this is right... nextIndex = 0 for local_quad_index in range(m): current_quad = B2Indices[nextIndex] neighbour = B1Indices[nextIndex] neighbourQuad = oldB1[i,neighbour,1] neighbourAIndex = np.where(oldA[i,0:m,1] == neighbourQuad)[0][0] neighbourB2Index = np.where(oldB2[i,0:m,1] == neighbourQuad)[0][0] neighbourCIndex = np.where(oldC[i,0:m,1] == neighbourQuad)[0][0] nextIndex = np.where(B2Indices == neighbourB2Index)[0][0] indicesLocA[(local_quad_index+1)%m] = int(neighbourAIndex) indicesLocB1[(local_quad_index+1)%m] = int(neighbour) indicesLocC[(local_quad_index+1)%m]= int(neighbourCIndex) indicesLocB2[local_quad_index] = current_quad newA[i,0:m,:] = oldA[i,indicesLocA,:] newB1[i,0:m,:] = oldB1[i,indicesLocB1,:] newB2[i,0:m,:] = oldB2[i,indicesLocB2,:] newC[i,0:m,:] = oldC[i,indicesLocC,:] return newA,newB1,newB2,newC
def createGlobalControlMeshCoefs(parameterCoordinates, quad_list, AVertexList, B1VertexList, B2VertexList, CVertexList, quad_control_point_indices): """ Takes, for N datapoints, an array parameterCoordinates[Nx3](for every datapoint: first entry the quad index, second and third parameterson a patch that spans over [0,1]x[0,1] for the quad. The function computes the coefficient matrix for between each datapoint and the array of M/16 quads x [4x4] vertex control points, outputting the coefficients as an N x M matrix. """ N = parameterCoordinates.shape[0] M = quad_control_point_indices.shape[0] * quad_control_point_indices.shape[1] coefsMatrix = np.zeros((N,M)) """ Precalculate the coefficients between all the vertex control points and the bezier control points for 7 different number of intersecting edges as a start (number of incoming edges(between 3 an 7 hardcoded), [A,B1,B2,C], [in which quad 1-7], bezier point first coord, bezier point second coord) """ ACoefsRaw = np.zeros((7,7,4,4)) B1CoefsRaw = np.zeros((7,7,4,4)) B2CoefsRaw = np.zeros((7,7,4,4)) CCoefsRaw = np.zeros((7,7,4,4)) for num_quads in range(3,8): [ACoefsRaw[num_quads-1, 0:num_quads, :, :], B1CoefsRaw[num_quads-1, 0:num_quads, :, :], B2CoefsRaw[num_quads-1, 0:num_quads, :, :], CCoefsRaw[num_quads-1, 0:num_quads, :, :]] = createBicubicCoefMatrices(num_quads) # compared to matlab by Saumi & Benni -> VALID coefsRawTemp = np.zeros((4,7,4,4)) print "Main Loop Coeffs" for p in range(N): if p%100 == 0: print "processing point %d of %d..." % (p, N) #check if on a corner patch : if both coords are outside [0.25,0.75] quadParameters = parameterCoordinates[p, 1:3] quad_index = int(parameterCoordinates[p, 0]) [localCoords, whichCorner, whichPatch] = createLocalParamsExtraordinary(global_quad_params=quadParameters) #print "p=%d"%p # todo for p=1 get3x3... fails! -> Resolved(?). #print "whichPatch="+str(whichPatch) # if there is a specified corner set if whichCorner != -1: cornerVertexIndex = quad_list[quad_index, whichCorner] numberOfEdges = get_num_edges_meeting(AVertexList, cornerVertexIndex) #TODO: Check output PROBLEM! indexMask = getExtraOrdCornerIndexMask(quad_list, AVertexList, B1VertexList, B2VertexList, CVertexList, quad_control_point_indices, quad_index, whichCorner) coefsRawTemp[0, 0:numberOfEdges, :, :] = ACoefsRaw[numberOfEdges-1, 0:numberOfEdges, :, :] coefsRawTemp[1, 0:numberOfEdges, :, :] = B1CoefsRaw[numberOfEdges-1, 0:numberOfEdges, :, :] coefsRawTemp[2, 0:numberOfEdges, :, :] = B2CoefsRaw[numberOfEdges-1, 0:numberOfEdges, :, :] coefsRawTemp[3, 0:numberOfEdges, :, :] = CCoefsRaw[numberOfEdges-1, 0:numberOfEdges, :, :] patchCoefsMatrix = getBicubicBezierPointCoefs(localCoords, coefsRawTemp[:, 0:numberOfEdges, :, :]) coefsMatrix[p][indexMask[:]] = patchCoefsMatrix[:] else: neighbourMask = get3x3ControlPointIndexMask(quad_list=quad_list, quad_control_point_indices=quad_control_point_indices, quad_index=quad_index, localIndexXY=whichPatch) neighbourCoefs = getBezierPointCoefs(localCoords) for j in range(3): for i in range(3): coefsMatrix[p, neighbourMask[i, j]] = neighbourCoefs[i, j] print "Main Loop Coeffs Done." return coefsMatrix
def createGlobalControlMeshCoefs(parameterCoordinates, quad_list, AVertexList, B1VertexList, B2VertexList, CVertexList, quad_control_point_indices): ''' Takes, for N datapoints, an array parameterCoordinates[Nx3](for every datapoint: first entry the quad index, second and third parameters on a patch that spans over [0,1]x[0,1] for the quad. The function computes the coefficient matrix for between each datapoint and the array of M/16 quads x [4x4] vertex control points, outputting the coefficients as an N x M scipy.sparse COO-type sparse matrix @param parameterCoordinates: Nx3 numpy.ndarray of datapoint parameters @param quad_list: @param AVertexList: @param B1VertexList: @param B2VertexList: @param CVertexList: @param quad_control_point_indices: (M/16)x16 numpy.ndarray of control points on each quad @return: NxM scipy.sparse COO-type sparse matrix of coefficients, maximum 22 nonzero entries per row ''' N = parameterCoordinates.shape[0] M = quad_control_point_indices.shape[0] * quad_control_point_indices.shape[ 1] max_size = N * 28 #4 types of vertices times maximum 7 quads around an extraordinary vertex (large estimate) rows = np.zeros(max_size, dtype=int) cols = np.zeros(max_size, dtype=int) data = np.zeros(max_size) """ Precalculate the coefficients between all the vertex control points and the bezier control points for 7 different number of intersecting edges as a start (number of incoming edges(between 3 an 7 hardcoded), [A,B1,B2,C], [in which quad 1-7], bezier point first coord, bezier point second coord) """ ACoefsRaw = np.zeros((7, 7, 4, 4)) B1CoefsRaw = np.zeros((7, 7, 4, 4)) B2CoefsRaw = np.zeros((7, 7, 4, 4)) CCoefsRaw = np.zeros((7, 7, 4, 4)) for num_quads in range(3, 8): [ ACoefsRaw[num_quads - 1, 0:num_quads, :, :], B1CoefsRaw[num_quads - 1, 0:num_quads, :, :], B2CoefsRaw[num_quads - 1, 0:num_quads, :, :], CCoefsRaw[num_quads - 1, 0:num_quads, :, :] ] = createBicubicCoefMatrices( num_quads) # compared to matlab by Saumi & Benni -> VALID coefsRawTemp = np.zeros((4, 7, 4, 4)) indexCounter = 0 print "Main Loop Coefs" for p in range(N): if p % 100 == 0: print "processing point %d of %d..." % (p, N) #check if on a corner patch : if both coords are outside [0.25,0.75] quadParameters = parameterCoordinates[p, 1:3] quad_index = int(parameterCoordinates[p, 0]) [localCoords, whichCorner, whichPatch ] = createLocalParamsExtraordinary(global_quad_params=quadParameters) #print "p=%d"%p # todo for p=1 get3x3... fails! -> Resolved(?). #print "whichPatch="+str(whichPatch) # if there is a specified corner set if whichCorner != -1: cornerVertexIndex = quad_list[quad_index, whichCorner] numberOfEdges = get_num_edges_meeting(AVertexList, cornerVertexIndex) #TODO: Check output PROBLEM! indexMask = getExtraOrdCornerIndexMask(quad_list, AVertexList, B1VertexList, B2VertexList, CVertexList, quad_control_point_indices, quad_index, whichCorner) coefsRawTemp[0, 0:numberOfEdges, :, :] = ACoefsRaw[ numberOfEdges - 1, 0:numberOfEdges, :, :] coefsRawTemp[1, 0:numberOfEdges, :, :] = B1CoefsRaw[ numberOfEdges - 1, 0:numberOfEdges, :, :] coefsRawTemp[2, 0:numberOfEdges, :, :] = B2CoefsRaw[ numberOfEdges - 1, 0:numberOfEdges, :, :] coefsRawTemp[3, 0:numberOfEdges, :, :] = CCoefsRaw[ numberOfEdges - 1, 0:numberOfEdges, :, :] patchCoefsMatrix = getBicubicBezierPointCoefs( localCoords, coefsRawTemp[:, 0:numberOfEdges, :, :]) numberOfEntries = numberOfEdges * 4 rows[indexCounter:(indexCounter + numberOfEntries)] = p cols[indexCounter:(indexCounter + numberOfEntries)] = indexMask.flatten()[:] data[indexCounter:( indexCounter + numberOfEntries)] = patchCoefsMatrix.flatten()[:] indexCounter += numberOfEntries else: neighbourMask = get3x3ControlPointIndexMask( quad_list=quad_list, quad_control_point_indices=quad_control_point_indices, quad_index=quad_index, localIndexXY=whichPatch) neighbourCoefs = getBezierPointCoefs(localCoords) numberOfEntries = 9 rows[indexCounter:(indexCounter + numberOfEntries)] = p cols[indexCounter:(indexCounter + numberOfEntries)] = neighbourMask.flatten()[:] data[indexCounter:(indexCounter + numberOfEntries)] = neighbourCoefs.flatten()[:] indexCounter += numberOfEntries print "Main Loop Coeffs Done." return ssp.coo_matrix((data, (rows, cols)), shape=(N, M))