int main(void) { int option; point *start=NULL; do { //Display user menu printf("0 - quit\n"); printf("1 - add\n"); printf("2 - remove\n"); printf("3 - display all\n"); printf("Enter option: "); fflush(stdout); scanf("%2d", &option); //Process option switch (option) { case 1: start = add_point(start); break; case 2: start = remove_point(start); break; case 3: display_all(start); break; } }while (option != 0); return 0; }
void PST_Edge::set_point( PST_Point* pt, PST_Point*& ptr, PST_Edge*& next ) { if( ptr ) remove_point( ptr, next ); if( pt->edge_ ) { if( pt->edge()->start_point() == pt ) { next = pt->edge()->start_next_; pt->edge()->start_next_ = this; } else { assert( pt->edge()->end_point() == pt ); next = pt->edge()->end_next_; pt->edge()->end_next_ = this; } } else { next = this; pt->edge_ = this; } ptr = pt; }
/* intercept mouse input */ void mouse_input(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { int point_found = update_point(x, SCREEN_HEIGHT - y); if (point_found) left_button_down = 1; if (!point_found && num_points < MAX_POINTS) { points[num_points].x = x; points[num_points].y = SCREEN_HEIGHT - y; current_point = num_points; num_points++; } } else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { remove_point(x, SCREEN_HEIGHT - y); } else if (button==GLUT_LEFT_BUTTON && state == GLUT_UP) { left_button_down = 0; } draw_screen(); }
int main(void) { int option, i = 0; FILE *fp1; point *start =NULL; // root node do // do while loop { //Display user menu printf("\n\n0 - quit\n"); printf("1 - ADD A Record\n"); printf("2 - Remove A Record\n"); printf("3 - Display All Records\n"); printf("4 - Save\n"); printf("5 - Load Saved Data\n"); printf("Enter Option: "); fflush(stdout); scanf("%2d", &option); getchar(); //Process option switch (option) // switch statement to decide next action { case 1: start = add_point(start); break; case 2: display_all(start); start = remove_point(start); break; case 3: display_all(start); break; case 4: write_to_disk(fp1, start); break; case 5: start = NULL; start = read_from_disk(fp1,start); printf("\nSAVED DATA:\n"); break; } }while (option != 0); return 0; }
void CurveEditor::on_context_menu_item_selected(int action_id) { switch (action_id) { case CONTEXT_ADD_POINT: add_point(_context_click_pos); break; case CONTEXT_REMOVE_POINT: remove_point(_selected_point); break; case CONTEXT_LINEAR: toggle_linear(); break; case CONTEXT_LEFT_LINEAR: toggle_linear(TANGENT_LEFT); break; case CONTEXT_RIGHT_LINEAR: toggle_linear(TANGENT_RIGHT); break; } }
/************************************************************** * * CGC Coarsening routine * **************************************************************/ HYPRE_Int hypre_BoomerAMGCoarsenCGCb( hypre_ParCSRMatrix *S, hypre_ParCSRMatrix *A, HYPRE_Int measure_type, HYPRE_Int coarsen_type, HYPRE_Int cgc_its, HYPRE_Int debug_flag, HYPRE_Int **CF_marker_ptr) { MPI_Comm comm = hypre_ParCSRMatrixComm(S); hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRMatrixCommPkg(S); hypre_ParCSRCommHandle *comm_handle; hypre_CSRMatrix *S_diag = hypre_ParCSRMatrixDiag(S); hypre_CSRMatrix *S_offd = hypre_ParCSRMatrixOffd(S); HYPRE_Int *S_i = hypre_CSRMatrixI(S_diag); HYPRE_Int *S_j = hypre_CSRMatrixJ(S_diag); HYPRE_Int *S_offd_i = hypre_CSRMatrixI(S_offd); HYPRE_Int *S_offd_j; HYPRE_Int num_variables = hypre_CSRMatrixNumRows(S_diag); HYPRE_Int num_cols_offd = hypre_CSRMatrixNumCols(S_offd); hypre_CSRMatrix *S_ext; HYPRE_Int *S_ext_i; HYPRE_Int *S_ext_j; hypre_CSRMatrix *ST; HYPRE_Int *ST_i; HYPRE_Int *ST_j; HYPRE_Int *CF_marker; HYPRE_Int *CF_marker_offd=NULL; HYPRE_Int ci_tilde = -1; HYPRE_Int ci_tilde_mark = -1; HYPRE_Int *measure_array; HYPRE_Int *measure_array_master; HYPRE_Int *graph_array; HYPRE_Int *int_buf_data=NULL; /*HYPRE_Int *ci_array=NULL;*/ HYPRE_Int i, j, k, l, jS; HYPRE_Int ji, jj, index; HYPRE_Int set_empty = 1; HYPRE_Int C_i_nonempty = 0; HYPRE_Int num_nonzeros; HYPRE_Int num_procs, my_id; HYPRE_Int num_sends = 0; HYPRE_Int first_col, start; HYPRE_Int col_0, col_n; hypre_LinkList LoL_head; hypre_LinkList LoL_tail; HYPRE_Int *lists, *where; HYPRE_Int measure, new_meas; HYPRE_Int num_left; HYPRE_Int nabor, nabor_two; HYPRE_Int ierr = 0; HYPRE_Int use_commpkg_A = 0; HYPRE_Real wall_time; HYPRE_Int measure_max; /* BM Aug 30, 2006: maximal measure, needed for CGC */ if (coarsen_type < 0) coarsen_type = -coarsen_type; /*------------------------------------------------------- * Initialize the C/F marker, LoL_head, LoL_tail arrays *-------------------------------------------------------*/ LoL_head = NULL; LoL_tail = NULL; lists = hypre_CTAlloc(HYPRE_Int, num_variables); where = hypre_CTAlloc(HYPRE_Int, num_variables); #if 0 /* debugging */ char filename[256]; FILE *fp; HYPRE_Int iter = 0; #endif /*-------------------------------------------------------------- * Compute a CSR strength matrix, S. * * For now, the "strength" of dependence/influence is defined in * the following way: i depends on j if * aij > hypre_max (k != i) aik, aii < 0 * or * aij < hypre_min (k != i) aik, aii >= 0 * Then S_ij = 1, else S_ij = 0. * * NOTE: the entries are negative initially, corresponding * to "unaccounted-for" dependence. *----------------------------------------------------------------*/ if (debug_flag == 3) wall_time = time_getWallclockSeconds(); hypre_MPI_Comm_size(comm,&num_procs); hypre_MPI_Comm_rank(comm,&my_id); if (!comm_pkg) { use_commpkg_A = 1; comm_pkg = hypre_ParCSRMatrixCommPkg(A); } if (!comm_pkg) { hypre_MatvecCommPkgCreate(A); comm_pkg = hypre_ParCSRMatrixCommPkg(A); } num_sends = hypre_ParCSRCommPkgNumSends(comm_pkg); if (num_cols_offd) S_offd_j = hypre_CSRMatrixJ(S_offd); jS = S_i[num_variables]; ST = hypre_CSRMatrixCreate(num_variables, num_variables, jS); ST_i = hypre_CTAlloc(HYPRE_Int,num_variables+1); ST_j = hypre_CTAlloc(HYPRE_Int,jS); hypre_CSRMatrixI(ST) = ST_i; hypre_CSRMatrixJ(ST) = ST_j; /*---------------------------------------------------------- * generate transpose of S, ST *----------------------------------------------------------*/ for (i=0; i <= num_variables; i++) ST_i[i] = 0; for (i=0; i < jS; i++) { ST_i[S_j[i]+1]++; } for (i=0; i < num_variables; i++) { ST_i[i+1] += ST_i[i]; } for (i=0; i < num_variables; i++) { for (j=S_i[i]; j < S_i[i+1]; j++) { index = S_j[j]; ST_j[ST_i[index]] = i; ST_i[index]++; } } for (i = num_variables; i > 0; i--) { ST_i[i] = ST_i[i-1]; } ST_i[0] = 0; /*---------------------------------------------------------- * Compute the measures * * The measures are given by the row sums of ST. * Hence, measure_array[i] is the number of influences * of variable i. * correct actual measures through adding influences from * neighbor processors *----------------------------------------------------------*/ measure_array_master = hypre_CTAlloc(HYPRE_Int, num_variables); measure_array = hypre_CTAlloc(HYPRE_Int, num_variables); for (i = 0; i < num_variables; i++) { measure_array_master[i] = ST_i[i+1]-ST_i[i]; } if ((measure_type || (coarsen_type != 1 && coarsen_type != 11)) && num_procs > 1) { if (use_commpkg_A) S_ext = hypre_ParCSRMatrixExtractBExt(S,A,0); else S_ext = hypre_ParCSRMatrixExtractBExt(S,S,0); S_ext_i = hypre_CSRMatrixI(S_ext); S_ext_j = hypre_CSRMatrixJ(S_ext); num_nonzeros = S_ext_i[num_cols_offd]; first_col = hypre_ParCSRMatrixFirstColDiag(S); col_0 = first_col-1; col_n = col_0+num_variables; if (measure_type) { for (i=0; i < num_nonzeros; i++) { index = S_ext_j[i] - first_col; if (index > -1 && index < num_variables) measure_array_master[index]++; } } } /*--------------------------------------------------- * Loop until all points are either fine or coarse. *---------------------------------------------------*/ if (debug_flag == 3) wall_time = time_getWallclockSeconds(); /* first coarsening phase */ /************************************************************* * * Initialize the lists * *************************************************************/ CF_marker = hypre_CTAlloc(HYPRE_Int, num_variables); num_left = 0; for (j = 0; j < num_variables; j++) { if ((S_i[j+1]-S_i[j])== 0 && (S_offd_i[j+1]-S_offd_i[j]) == 0) { CF_marker[j] = SF_PT; measure_array_master[j] = 0; } else { CF_marker[j] = UNDECIDED; /* num_left++; */ /* BM May 19, 2006: see below*/ } } if (coarsen_type==22) { /* BM Sep 8, 2006: allow_emptygrids only if the following holds for all points j: (a) the point has no strong connections at all, OR (b) the point has a strong connection across a boundary */ for (j=0;j<num_variables;j++) if (S_i[j+1]>S_i[j] && S_offd_i[j+1] == S_offd_i[j]) {coarsen_type=21;break;} } for (l = 1; l <= cgc_its; l++) { LoL_head = NULL; LoL_tail = NULL; num_left = 0; /* compute num_left before each RS coarsening loop */ memcpy (measure_array,measure_array_master,num_variables*sizeof(HYPRE_Int)); memset (lists,0,sizeof(HYPRE_Int)*num_variables); memset (where,0,sizeof(HYPRE_Int)*num_variables); for (j = 0; j < num_variables; j++) { measure = measure_array[j]; if (CF_marker[j] != SF_PT) { if (measure > 0) { enter_on_lists(&LoL_head, &LoL_tail, measure, j, lists, where); num_left++; /* compute num_left before each RS coarsening loop */ } else if (CF_marker[j] == 0) /* increase weight of strongly coupled neighbors only if j is not conained in a previously constructed coarse grid. Reason: these neighbors should start with the same initial weight in each CGC iteration. BM Aug 30, 2006 */ { if (measure < 0) hypre_printf("negative measure!\n"); /* CF_marker[j] = f_pnt; */ for (k = S_i[j]; k < S_i[j+1]; k++) { nabor = S_j[k]; /* if (CF_marker[nabor] != SF_PT) */ if (CF_marker[nabor] == 0) /* BM Aug 30, 2006: don't alter weights of points contained in other candidate coarse grids */ { if (nabor < j) { new_meas = measure_array[nabor]; if (new_meas > 0) remove_point(&LoL_head, &LoL_tail, new_meas, nabor, lists, where); else num_left++; /* BM Aug 29, 2006 */ new_meas = ++(measure_array[nabor]); enter_on_lists(&LoL_head, &LoL_tail, new_meas, nabor, lists, where); } else { new_meas = ++(measure_array[nabor]); } } } /* --num_left; */ /* BM May 19, 2006 */ } } } /* BM Aug 30, 2006: first iteration: determine maximal weight */ if (num_left && l==1) measure_max = measure_array[LoL_head->head]; /* BM Aug 30, 2006: break CGC iteration if no suitable starting point is available any more */ if (!num_left || measure_array[LoL_head->head]<measure_max) { while (LoL_head) { hypre_LinkList list_ptr = LoL_head; LoL_head = LoL_head->next_elt; dispose_elt (list_ptr); } break; } /**************************************************************** * * Main loop of Ruge-Stueben first coloring pass. * * WHILE there are still points to classify DO: * 1) find first point, i, on list with max_measure * make i a C-point, remove it from the lists * 2) For each point, j, in S_i^T, * a) Set j to be an F-point * b) For each point, k, in S_j * move k to the list in LoL with measure one * greater than it occupies (creating new LoL * entry if necessary) * 3) For each point, j, in S_i, * move j to the list in LoL with measure one * smaller than it occupies (creating new LoL * entry if necessary) * ****************************************************************/ while (num_left > 0) { index = LoL_head -> head; /* index = LoL_head -> tail; */ /* CF_marker[index] = C_PT; */ CF_marker[index] = l; /* BM Aug 18, 2006 */ measure = measure_array[index]; measure_array[index] = 0; measure_array_master[index] = 0; /* BM May 19: for CGC */ --num_left; remove_point(&LoL_head, &LoL_tail, measure, index, lists, where); for (j = ST_i[index]; j < ST_i[index+1]; j++) { nabor = ST_j[j]; /* if (CF_marker[nabor] == UNDECIDED) */ if (measure_array[nabor]>0) /* undecided point */ { /* CF_marker[nabor] = F_PT; */ /* BM Aug 18, 2006 */ measure = measure_array[nabor]; measure_array[nabor]=0; remove_point(&LoL_head, &LoL_tail, measure, nabor, lists, where); --num_left; for (k = S_i[nabor]; k < S_i[nabor+1]; k++) { nabor_two = S_j[k]; /* if (CF_marker[nabor_two] == UNDECIDED) */ if (measure_array[nabor_two]>0) /* undecided point */ { measure = measure_array[nabor_two]; remove_point(&LoL_head, &LoL_tail, measure, nabor_two, lists, where); new_meas = ++(measure_array[nabor_two]); enter_on_lists(&LoL_head, &LoL_tail, new_meas, nabor_two, lists, where); } } } } for (j = S_i[index]; j < S_i[index+1]; j++) { nabor = S_j[j]; /* if (CF_marker[nabor] == UNDECIDED) */ if (measure_array[nabor]>0) /* undecided point */ { measure = measure_array[nabor]; remove_point(&LoL_head, &LoL_tail, measure, nabor, lists, where); measure_array[nabor] = --measure; if (measure > 0) enter_on_lists(&LoL_head, &LoL_tail, measure, nabor, lists, where); else { /* CF_marker[nabor] = F_PT; */ /* BM Aug 18, 2006 */ --num_left; for (k = S_i[nabor]; k < S_i[nabor+1]; k++) { nabor_two = S_j[k]; /* if (CF_marker[nabor_two] == UNDECIDED) */ if (measure_array[nabor_two]>0) { new_meas = measure_array[nabor_two]; remove_point(&LoL_head, &LoL_tail, new_meas, nabor_two, lists, where); new_meas = ++(measure_array[nabor_two]); enter_on_lists(&LoL_head, &LoL_tail, new_meas, nabor_two, lists, where); } } } } } } if (LoL_head) hypre_printf ("Linked list not empty! head: %d\n",LoL_head->head); } l--; /* BM Aug 15, 2006 */ hypre_TFree(measure_array); hypre_TFree(measure_array_master); hypre_CSRMatrixDestroy(ST); if (debug_flag == 3) { wall_time = time_getWallclockSeconds() - wall_time; hypre_printf("Proc = %d Coarsen 1st pass = %f\n", my_id, wall_time); } hypre_TFree(lists); hypre_TFree(where); if (num_procs>1) { if (debug_flag == 3) wall_time = time_getWallclockSeconds(); hypre_BoomerAMGCoarsenCGC (S,l,coarsen_type,CF_marker); if (debug_flag == 3) { wall_time = time_getWallclockSeconds() - wall_time; hypre_printf("Proc = %d Coarsen CGC = %f\n", my_id, wall_time); } } else { /* the first candiate coarse grid is the coarse grid */ for (j=0;j<num_variables;j++) { if (CF_marker[j]==1) CF_marker[j]=C_PT; else CF_marker[j]=F_PT; } } /* BM May 19, 2006: Set all undecided points to be fine grid points. */ for (j=0;j<num_variables;j++) if (!CF_marker[j]) CF_marker[j]=F_PT; /*--------------------------------------------------- * Initialize the graph array *---------------------------------------------------*/ graph_array = hypre_CTAlloc(HYPRE_Int, num_variables); for (i = 0; i < num_variables; i++) { graph_array[i] = -1; } if (debug_flag == 3) wall_time = time_getWallclockSeconds(); for (i=0; i < num_variables; i++) { if (ci_tilde_mark != i) ci_tilde = -1; if (CF_marker[i] == -1) { for (ji = S_i[i]; ji < S_i[i+1]; ji++) { j = S_j[ji]; if (CF_marker[j] > 0) graph_array[j] = i; } for (ji = S_i[i]; ji < S_i[i+1]; ji++) { j = S_j[ji]; if (CF_marker[j] == -1) { set_empty = 1; for (jj = S_i[j]; jj < S_i[j+1]; jj++) { index = S_j[jj]; if (graph_array[index] == i) { set_empty = 0; break; } } if (set_empty) { if (C_i_nonempty) { CF_marker[i] = 1; if (ci_tilde > -1) { CF_marker[ci_tilde] = -1; ci_tilde = -1; } C_i_nonempty = 0; break; } else { ci_tilde = j; ci_tilde_mark = i; CF_marker[j] = 1; C_i_nonempty = 1; i--; break; } } } } } } if (debug_flag == 3 && coarsen_type != 2) { wall_time = time_getWallclockSeconds() - wall_time; hypre_printf("Proc = %d Coarsen 2nd pass = %f\n", my_id, wall_time); } /* third pass, check boundary fine points for coarse neighbors */ /*------------------------------------------------ * Exchange boundary data for CF_marker *------------------------------------------------*/ if (debug_flag == 3) wall_time = time_getWallclockSeconds(); CF_marker_offd = hypre_CTAlloc(HYPRE_Int, num_cols_offd); int_buf_data = hypre_CTAlloc(HYPRE_Int, hypre_ParCSRCommPkgSendMapStart(comm_pkg, num_sends)); index = 0; for (i = 0; i < num_sends; i++) { start = hypre_ParCSRCommPkgSendMapStart(comm_pkg, i); for (j = start; j < hypre_ParCSRCommPkgSendMapStart(comm_pkg, i+1); j++) int_buf_data[index++] = CF_marker[hypre_ParCSRCommPkgSendMapElmt(comm_pkg,j)]; } if (num_procs > 1) { comm_handle = hypre_ParCSRCommHandleCreate(11, comm_pkg, int_buf_data, CF_marker_offd); hypre_ParCSRCommHandleDestroy(comm_handle); } AmgCGCBoundaryFix (S,CF_marker,CF_marker_offd); if (debug_flag == 3) { wall_time = time_getWallclockSeconds() - wall_time; hypre_printf("Proc = %d CGC boundary fix = %f\n", my_id, wall_time); } /*--------------------------------------------------- * Clean up and return *---------------------------------------------------*/ /*if (coarsen_type != 1) { */ if (CF_marker_offd) hypre_TFree(CF_marker_offd); /* BM Aug 21, 2006 */ if (int_buf_data) hypre_TFree(int_buf_data); /* BM Aug 21, 2006 */ /*if (ci_array) hypre_TFree(ci_array);*/ /* BM Aug 21, 2006 */ /*} */ hypre_TFree(graph_array); if ((measure_type || (coarsen_type != 1 && coarsen_type != 11)) && num_procs > 1) hypre_CSRMatrixDestroy(S_ext); *CF_marker_ptr = CF_marker; return (ierr); }
HYPRE_Int AmgCGCChoose (hypre_CSRMatrix *G,HYPRE_Int *vertexrange,HYPRE_Int mpisize,HYPRE_Int **coarse) /* chooses one grid for every processor * ============================================================ * G : the connectivity graph * map : the parallel layout * mpisize : number of procs * coarse : the chosen coarse grids * ===========================================================*/ { HYPRE_Int i,j,jj,p,choice,*processor,ierr=0; HYPRE_Int measure,new_measure; /* MPI_Comm comm = hypre_ParCSRMatrixComm(G); */ /* hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRMatrixCommPkg (G); */ /* hypre_ParCSRCommHandle *comm_handle; */ HYPRE_Real *G_data = hypre_CSRMatrixData (G); HYPRE_Real max; HYPRE_Int *G_i = hypre_CSRMatrixI(G); HYPRE_Int *G_j = hypre_CSRMatrixJ(G); hypre_CSRMatrix *H,*HT; HYPRE_Int *H_i,*H_j,*HT_i,*HT_j; HYPRE_Int jG,jH; HYPRE_Int num_vertices = hypre_CSRMatrixNumRows (G); HYPRE_Int *measure_array; HYPRE_Int *lists,*where; hypre_LinkList LoL_head = NULL; hypre_LinkList LoL_tail = NULL; processor = hypre_CTAlloc (HYPRE_Int,num_vertices); *coarse = hypre_CTAlloc (HYPRE_Int,mpisize); memset (*coarse,0,sizeof(HYPRE_Int)*mpisize); measure_array = hypre_CTAlloc (HYPRE_Int,num_vertices); lists = hypre_CTAlloc (HYPRE_Int,num_vertices); where = hypre_CTAlloc (HYPRE_Int,num_vertices); /* for (p=0;p<mpisize;p++) hypre_printf ("%d: %d-%d\n",p,range[p]+1,range[p+1]); */ /****************************************************************** * determine heavy edges ******************************************************************/ jG = G_i[num_vertices]; H = hypre_CSRMatrixCreate (num_vertices,num_vertices,jG); H_i = hypre_CTAlloc (HYPRE_Int,num_vertices+1); H_j = hypre_CTAlloc (HYPRE_Int,jG); hypre_CSRMatrixI(H) = H_i; hypre_CSRMatrixJ(H) = H_j; for (i=0,p=0;i<num_vertices;i++) { while (vertexrange[p+1]<=i) p++; processor[i]=p; } H_i[0]=0; for (i=0,jj=0;i<num_vertices;i++) { #if 0 hypre_printf ("neighbors of grid %d:",i); #endif H_i[i+1]=H_i[i]; for (j=G_i[i],choice=-1,max=0;j<G_i[i+1];j++) { #if 0 if (G_data[j]>=0.0) hypre_printf ("G[%d,%d]=0. G_j(j)=%d, G_data(j)=%f.\n",i,G_j[j],j,G_data[j]); #endif /* G_data is always negative, so this test is sufficient */ if (choice==-1 || G_data[j]>max) { choice = G_j[j]; max = G_data[j]; } if (j==G_i[i+1]-1 || processor[G_j[j+1]] > processor[choice]) { /* we are done for this processor boundary */ H_j[jj++]=choice; H_i[i+1]++; #if 0 hypre_printf (" %d",choice); #endif choice = -1; max=0; } } #if 0 hypre_printf("\n"); #endif } /****************************************************************** * compute H^T, the transpose of H ******************************************************************/ jH = H_i[num_vertices]; HT = hypre_CSRMatrixCreate (num_vertices,num_vertices,jH); HT_i = hypre_CTAlloc (HYPRE_Int,num_vertices+1); HT_j = hypre_CTAlloc (HYPRE_Int,jH); hypre_CSRMatrixI(HT) = HT_i; hypre_CSRMatrixJ(HT) = HT_j; for (i=0; i <= num_vertices; i++) HT_i[i] = 0; for (i=0; i < jH; i++) { HT_i[H_j[i]+1]++; } for (i=0; i < num_vertices; i++) { HT_i[i+1] += HT_i[i]; } for (i=0; i < num_vertices; i++) { for (j=H_i[i]; j < H_i[i+1]; j++) { HYPRE_Int myindex = H_j[j]; HT_j[HT_i[myindex]] = i; HT_i[myindex]++; } } for (i = num_vertices; i > 0; i--) { HT_i[i] = HT_i[i-1]; } HT_i[0] = 0; /***************************************************************** * set initial vertex weights *****************************************************************/ for (i=0;i<num_vertices;i++) { measure_array[i] = H_i[i+1] - H_i[i] + HT_i[i+1] - HT_i[i]; enter_on_lists (&LoL_head,&LoL_tail,measure_array[i],i,lists,where); } /****************************************************************** * apply CGC iteration ******************************************************************/ while (LoL_head && measure_array[LoL_head->head]) { choice = LoL_head->head; measure = measure_array[choice]; #if 0 hypre_printf ("Choice: %d, measure %d, processor %d\n",choice, measure,processor[choice]); fflush(stdout); #endif (*coarse)[processor[choice]] = choice+1; /* add one because coarsegrid indexing starts with 1, not 0 */ /* new maximal weight */ new_measure = measure+1; for (i=vertexrange[processor[choice]];i<vertexrange[processor[choice]+1];i++) { /* set weights for all remaining vertices on this processor to zero */ measure = measure_array[i]; remove_point (&LoL_head,&LoL_tail,measure,i,lists,where); measure_array[i]=0; } for (j=H_i[choice];j<H_i[choice+1];j++){ jj = H_j[j]; /* if no vertex is chosen on this proc, set weights of all heavily coupled vertices to max1 */ if (!(*coarse)[processor[jj]]) { measure = measure_array[jj]; remove_point (&LoL_head,&LoL_tail,measure,jj,lists,where); enter_on_lists (&LoL_head,&LoL_tail,new_measure,jj,lists,where); measure_array[jj]=new_measure; } } for (j=HT_i[choice];j<HT_i[choice+1];j++) { jj = HT_j[j]; /* if no vertex is chosen on this proc, set weights of all heavily coupled vertices to max1 */ if (!(*coarse)[processor[jj]]) { measure = measure_array[jj]; remove_point (&LoL_head,&LoL_tail,measure,jj,lists,where); enter_on_lists (&LoL_head,&LoL_tail,new_measure,jj,lists,where); measure_array[jj]=new_measure; } } } /* remove remaining list elements, if they exist. They all should have measure 0 */ while (LoL_head) { i = LoL_head->head; measure = measure_array[i]; #if 0 hypre_assert (measure==0); #endif remove_point (&LoL_head,&LoL_tail,measure,i,lists,where); } for (p=0;p<mpisize;p++) /* if the algorithm has not determined a coarse vertex for this proc, simply take the last one Do not take the first one, it might by empty! */ if (!(*coarse)[p]) { (*coarse)[p] = vertexrange[p+1]; /* hypre_printf ("choice for processor %d: %d\n",p,range[p]+1); */ } /******************************************** * clean up ********************************************/ hypre_CSRMatrixDestroy (H); hypre_CSRMatrixDestroy (HT); hypre_TFree (processor); hypre_TFree (measure_array); hypre_TFree (lists); hypre_TFree (where); return(ierr); }
/** the algorithm that computes the visibility graph */ void construct_visibility(struct Point *points, int num_points, struct Line *lines, int num_lines, struct Map_info *out) { struct Point *p, *p_r, *q, *z; struct Point *p_infinity, *p_ninfinity; int i; p_ninfinity = (struct Point *)malloc(sizeof(struct Point)); p_infinity = (struct Point *)malloc(sizeof(struct Point)); p_ninfinity->x = PORT_DOUBLE_MAX; p_ninfinity->y = -PORT_DOUBLE_MAX; p_ninfinity->father = NULL; p_ninfinity->left_brother = NULL; p_ninfinity->right_brother = NULL; p_ninfinity->rightmost_son = NULL; p_infinity->x = PORT_DOUBLE_MAX; p_infinity->y = PORT_DOUBLE_MAX; p_infinity->father = NULL; p_infinity->left_brother = NULL; p_infinity->right_brother = NULL; p_infinity->rightmost_son = NULL; init_stack(num_points); /* sort points in decreasing x order */ quickSort(points, 0, num_points - 1); /* initialize the vis pointer of the vertices */ init_vis(points, num_points, lines, num_lines); add_rightmost(p_ninfinity, p_infinity); for (i = 0; i < num_points; i++) { add_rightmost(&points[i], p_ninfinity); } push(&points[0]); /* main loop */ while (!empty_stack()) { p = pop(); p_r = right_brother(p); q = father(p); /* if the father is not -infinity, handle p and q */ if (q != p_ninfinity) { handle(p, q, out); } z = left_brother(q); remove_point(p); /* remove and reattach p to the tree */ if (z == NULL || !left_turn(p, z, father(z))) { add_leftof(p, q); } else { while (rightmost_son(z) != NULL && left_turn(p, rightmost_son(z), z)) z = rightmost_son(z); add_rightmost(p, z); if (z == top()) z = pop(); } /* if p not attached to infinity, then p has more points to visit */ if (left_brother(p) == NULL && father(p) != p_infinity) { push(p); } /* and continue with the next one ( from left to right ) */ if (p_r != NULL) { push(p_r); } } G_free(p_infinity); G_free(p_ninfinity); }
void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb_ref = p_event; if (mb_ref.is_valid()) { const InputEventMouseButton &mb = **mb_ref; if (mb.is_pressed() && !_dragging) { Vector2 mpos = mb.get_position(); _selected_tangent = get_tangent_at(mpos); if (_selected_tangent == TANGENT_NONE) set_selected_point(get_point_at(mpos)); switch (mb.get_button_index()) { case BUTTON_RIGHT: _context_click_pos = mpos; open_context_menu(get_global_transform().xform(mpos)); break; case BUTTON_MIDDLE: remove_point(_hover_point); break; case BUTTON_LEFT: _dragging = true; break; } } if (!mb.is_pressed() && _dragging && mb.get_button_index() == BUTTON_LEFT) { _dragging = false; if (_has_undo_data) { UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo(); ur.create_action(_selected_tangent == TANGENT_NONE ? TTR("Modify Curve Point") : TTR("Modify Curve Tangent")); ur.add_do_method(*_curve_ref, "_set_data", _curve_ref->get_data()); ur.add_undo_method(*_curve_ref, "_set_data", _undo_data); // Note: this will trigger one more "changed" signal even if nothing changes, // but it's ok since it would have fired every frame during the drag anyways ur.commit_action(); _has_undo_data = false; } } } Ref<InputEventMouseMotion> mm_ref = p_event; if (mm_ref.is_valid()) { const InputEventMouseMotion &mm = **mm_ref; Vector2 mpos = mm.get_position(); if (_dragging && _curve_ref.is_valid()) { Curve &curve = **_curve_ref; if (_selected_point != -1) { if (!_has_undo_data) { // Save full curve state before dragging points, // because this operation can modify their order _undo_data = curve.get_data(); _has_undo_data = true; } if (_selected_tangent == TANGENT_NONE) { // Drag point Vector2 point_pos = get_world_pos(mpos); int i = curve.set_point_offset(_selected_point, point_pos.x); // The index may change if the point is dragged across another one set_hover_point_index(i); set_selected_point(i); // This is to prevent the user from losing a point out of view. if (point_pos.y < curve.get_min_value()) point_pos.y = curve.get_min_value(); else if (point_pos.y > curve.get_max_value()) point_pos.y = curve.get_max_value(); curve.set_point_value(_selected_point, point_pos.y); } else { // Drag tangent Vector2 point_pos = curve.get_point_position(_selected_point); Vector2 control_pos = get_world_pos(mpos); Vector2 dir = (control_pos - point_pos).normalized(); real_t tangent; if (Math::abs(dir.x) > CMP_EPSILON) tangent = dir.y / dir.x; else tangent = 9999 * (dir.y >= 0 ? 1 : -1); bool link = !Input::get_singleton()->is_key_pressed(KEY_SHIFT); if (_selected_tangent == TANGENT_LEFT) { curve.set_point_left_tangent(_selected_point, tangent); // Note: if a tangent is set to linear, it shouldn't be linked to the other if (link && _selected_point != curve.get_point_count() - 1 && !curve.get_point_right_mode(_selected_point) != Curve::TANGENT_FREE) curve.set_point_right_tangent(_selected_point, tangent); } else { curve.set_point_right_tangent(_selected_point, tangent); if (link && _selected_point != 0 && !curve.get_point_left_mode(_selected_point) != Curve::TANGENT_FREE) curve.set_point_left_tangent(_selected_point, tangent); } } } } else { set_hover_point_index(get_point_at(mpos)); } } Ref<InputEventKey> key_ref = p_event; if (key_ref.is_valid()) { const InputEventKey &key = **key_ref; if (key.is_pressed() && _selected_point != -1) { if (key.get_scancode() == KEY_DELETE) remove_point(_selected_point); } } }