bool swc2eswc(NeuronTree input, vector<V3DLONG> & segment_id, vector<V3DLONG> & segment_layer) { V3DLONG pntNum = input.listNeuron.size(); if (pntNum<=0) { fprintf(stderr,"Illegal input neuronTree.\n"); return false; } segment_id = vector<V3DLONG>(pntNum, -1); segment_layer = vector<V3DLONG>(pntNum, -1); vector<V3DLONG> nchild(pntNum,0); for (V3DLONG i=0;i<pntNum;i++) { NeuronSWC S = input.listNeuron[i]; if (S.pn<0) continue; V3DLONG pid = input.hashNeuron.value(S.pn); nchild[pid] ++; } V3DLONG segNum = 0; V3DLONG layerNum = 0; vector<V3DLONG> to_prune; do { layerNum++; to_prune.clear(); for (V3DLONG i=0;i<pntNum;i++) { if (nchild[i]==0 && segment_id[i]==-1) //current point is an unvisited tip { segNum++; V3DLONG cur = i; V3DLONG pid; do { segment_id[cur] = segNum; segment_layer[cur] = layerNum; pid = input.listNeuron[cur].pn; if (pid<0) break; pid = input.hashNeuron.value(pid); cur = pid; } while (nchild[pid]==1); if (pid>=0) to_prune.push_back(pid); } } for (V3DLONG i=0;i<to_prune.size();i++) nchild[to_prune[i]]--; } while (!to_prune.empty()); return true; }
/*================================= * trav_pre_print_nod -- traverse node tree, * printing nodes in preorder * Created: 2001/01/27, Perry Rapp *===============================*/ static void trav_pre_print_nod (NODE node, INT * row, INT gen, INT indent, CANVASDATA canvas, INT gdvw) { NODE child; struct node_print_param_s npp; npp.node = node; npp.gdvw = gdvw; /* all display printing passes thru generic print_to_screen, which handles scrolling */ print_to_screen(gen, indent, row, &node_lineprint, &npp, canvas); for (child=nchild(node); child; child=nsibling(child)) trav_pre_print_nod(child, row, gen+1, indent, canvas, gdvw); }
/*================================================================= * expand_tree -- Create copy of node tree with additional link info *===============================================================*/ static NODE expand_tree (NODE root0) { NODE copy, node, sub; STRING key; static NODE root; /* root of record being edited */ LIST subs; /* list of contained records */ NODE expd; /* expanded main record - copy - our retval */ root = root0; expd = copy_nodes(root, TRUE, TRUE); subs = create_list(); traverse_nodes(expd, advedit_expand_traverse, subs); /* expand the list of records into the copied record */ FORLIST(subs, el) node = (NODE) el; #ifdef DEBUG llwprintf("in list: %s %s\n", ntag(node), nval(node)); #endif key = rmvat(nval(node)); if ((sub = nztop(key_possible_to_record(key, *key)))) { copy = copy_node_subtree(sub); nxref(node) = nxref(copy); ntag(node) = ntag(copy); nchild(node) = nchild(copy); nparent(node) = nparent(copy); /*MEMORY LEAK; MEMORY LEAK; MEMORY LEAK: node not removed (because its value and possibly xref [probably not] are still being referred to */ } ENDLIST /* Shouldn't we free subs now ? Perry 2001/06/22 */ #ifdef DEBUG show_node(expd); #endif return expd; }
/*========================================== * write_nodes -- Write NODEs to GEDCOM file *========================================*/ void write_nodes (INT levl, /* level */ FILE *fp, /* file */ XLAT ttm, /* char map */ NODE node, /* root */ BOOLEAN indent, /* indent? */ BOOLEAN kids, /* output kids? */ BOOLEAN sibs) /* output sibs? */ { if (!node) return; write_node(levl, fp, ttm, node, indent); if (kids) write_nodes(levl+1, fp, ttm, nchild(node), indent, TRUE, TRUE); if (sibs) write_nodes(levl, fp, ttm, nsibling(node), indent, kids, TRUE); }
void GeoTreeModel::addChildren(GeoObjectListItem* sfcList, const GeoLib::SurfaceVec* surface_vec, size_t start_index, size_t end_index) { const std::vector<GeoLib::Surface*>* surfaces = surface_vec->getVector(); const std::vector<GeoLib::Point*> &nodesVec(*((*surfaces)[start_index]->getPointVec())); for (size_t i = start_index; i < end_index; i++) { QList<QVariant> surface; std::string sfc_name(""); surface_vec->getNameOfElementByID(i, sfc_name); surface << "Surface " + QString::number(i) << QString::fromStdString(sfc_name) << "" << ""; const GeoLib::Surface &sfc(*(*surfaces)[i]); GeoTreeItem* surfaceItem(new GeoTreeItem(surface, sfcList, &sfc)); sfcList->appendChild(surfaceItem); int nElems = static_cast<int>((*surfaces)[i]->getNTriangles()); for (int j = 0; j < nElems; j++) { QList<QVariant> elem; const GeoLib::Triangle &triangle(*sfc[j]); elem << j << static_cast<int>(triangle[0]) << static_cast<int>(triangle[1]) << static_cast<int>(triangle[2]); TreeItem* child(new TreeItem(elem, surfaceItem)); surfaceItem->appendChild(child); for (int k = 0; k < 3; k++) { QList<QVariant> node; const GeoLib::Point &pnt(*(nodesVec[triangle[k]])); node << static_cast<int>(triangle[k]) << QString::number(pnt[0], 'f') << QString::number(pnt[1], 'f') << QString::number(pnt[2], 'f'); TreeItem* nchild(new TreeItem(node, child)); child->appendChild(nchild); } } } std::cout << end_index - start_index << " surfaces added." << std::endl; }
/*=================================== * find_xref -- Search node for a cross-reference key * 2001/01/21, Perry Rapp *=================================*/ static BOOLEAN find_xref (CNSTRING key, NODE node, CNSTRING tag1, CNSTRING tag2) { NODE node2; CACHEEL ncel2; BOOLEAN found=FALSE; ncel2 = node_to_cacheel_old(node); lock_cache(ncel2); for (node2 = nchild(node); node2; node2 = nsibling(node2)) { if (eqstr(tag1, ntag(node2)) || (tag2 && eqstr(tag2, ntag(node2)))) { STRING key2 = rmvat(nval(node2)); if (key2 && eqstr(key, key2)) { found = TRUE; goto exit_find; } } } exit_find: unlock_cache(ncel2); return found; }
/*============================================================== * next_fp_to_node -- Convert next GEDCOM record in file to tree * * fp: [IN] file that holds GEDCOM record/s * list: [IN] can be list at level 0? * ttm: [IN] character translation table * pmsg: [OUT] possible error message * peof: [OUT] set true if file is at end of file * callers should probably be converted to calling next_fp_to_record *============================================================*/ NODE next_fp_to_node (FILE *fp, BOOLEAN list, XLAT ttm, STRING *pmsg, BOOLEAN *peof) { INT curlev, bcode, rc; NODE root, node, curnode; static char scratch[100]; /*we return errors with this, keep it around*/ *pmsg = NULL; *peof = FALSE; if (ateof) { ateof = *peof = TRUE; lahead = FALSE; return NULL; } if (!lahead) { rc = file_to_line(fp, ttm, &lev, &xref, &tag, &val, pmsg); if (rc == DONE) { ateof = *peof = TRUE; return NULL; } else if (rc == ERROR) return NULL; lahead = TRUE; } curlev = lev; if (curlev != lev0) { *pmsg = _(qSrerwlv); return NULL; } root = curnode = create_node(xref, tag, val, NULL); bcode = OKAY; rc = file_to_line(fp, ttm, &lev, &xref, &tag, &val, pmsg); while (rc == OKAY) { if (lev == curlev) { if (lev == lev0 && !list) { bcode = DONE; break; } node = create_node(xref, tag, val, nparent(curnode)); nsibling(curnode) = node; curnode = node; } else if (lev == curlev + 1) { node = create_node(xref, tag, val, curnode); nchild(curnode) = node; curnode = node; curlev = lev; } else if (lev < curlev) { if (lev < lev0) { sprintf(scratch, _(qSrerilv), flineno); *pmsg = scratch; bcode = ERROR; break; } if (lev == lev0 && !list) { bcode = DONE; break; } while (lev < curlev) { curnode = nparent(curnode); curlev--; } node = create_node(xref, tag, val, nparent(curnode)); nsibling(curnode) = node; curnode = node; } else { sprintf(scratch, _(qSrerilv), flineno); *pmsg = scratch; bcode = ERROR; break; } rc = file_to_line(fp, ttm, &lev, &xref, &tag, &val, pmsg); } if (bcode == DONE) return root; if (bcode == ERROR || rc == ERROR) { free_nodes(root); return NULL; } lahead = FALSE; ateof = *peof = TRUE; return root; }
/*======================================= * llrpt_addnode -- Add a node to a GEDCOM tree * usage: addnode(NODE, NODE, NODE) -> VOID * args: (node being added, parent, previous child) *=====================================*/ PVALUE llrpt_addnode (PNODE node, SYMTAB stab, BOOLEAN *eflg) { PNODE arg = iargs(node); NODE newchild, next, prnt, prev; /* first argument, node (must be nonnull) */ PVALUE val = eval_and_coerce(PGNODE, arg, stab, eflg); if (*eflg) { prog_var_error(node, stab, arg, val, nonnodx, "addnode", "1"); delete_pvalue(val); return NULL; } newchild = remove_node_and_delete_pvalue(&val); if (!newchild) { prog_var_error(node, stab, arg, val, nonnodx, "addnode", "1"); return NULL; } /* second argument, parent (must be nonnull) */ val = eval_and_coerce(PGNODE, arg=inext(arg), stab, eflg); if (*eflg) { prog_var_error(node, stab, arg, val, nonnodx, "addnode", "2"); return NULL; } prnt = remove_node_and_delete_pvalue(&val); if (!prnt) { prog_var_error(node, stab, arg, val, nonnodx, "addnode", "2"); return NULL; } /* third argument, prior sibling (may be null) */ val = eval_and_coerce(PGNODE, arg=inext(arg), stab, eflg); if (*eflg) { prog_var_error(node, stab, arg, val, nonnodx, "addnode", "3"); delete_pvalue(val); return NULL; } prev = remove_node_and_delete_pvalue(&val); if (prev) { /* Check that previous sibling actually is child of new parent */ if (prnt != nparent(prev)) { prog_error(node, "2nd arg to addnode must be parent of 3rd arg"); *eflg = 1; return NULL; } } /* reparent node, but ensure its locking is only relative to new parent */ dolock_node_in_cache(newchild, FALSE); nparent(newchild) = prnt; newchild->n_cel = prnt->n_cel; set_temp_node(newchild, is_temp_node(prnt)); dolock_node_in_cache(newchild, TRUE); if (prev == NULL) { next = nchild(prnt); nchild(prnt) = newchild; } else { next = nsibling(prev); nsibling(prev) = newchild; } nsibling(newchild) = next; return NULL; }
/*================================================= * add_dnodes -- add dnodes to dnode tree * recursively, traversing NODE tree & building corresponding * dnode tree * if a line overflows, give it succeeding sibling dnodes * also, check for subordinate CONT & CONC dnodes to be assimilated *===============================================*/ static DISPNODE add_dnodes (NODE node, INT gen, INT indent, INT maxgen, INT * count, CANVASDATA canvas) { DISPNODE tn; DISPNODE tn0, tn1, tn2; NODE child, anode; INT width = (canvas->rect->right - canvas->rect->left) - 2 - gen*indent; static char line[MAXLINELEN], output[MAXLINELEN]; /* must be same size */ STRING ptr=output; INT leader; LIST list=NULL; INT mylen=sizeof(output), mylenorig; if (mylen>width) mylen = width; mylenorig = mylen; /* build xref & tag into line */ line[0] = 0; ptr = line; mylen = sizeof(line); if (nxref(node)) { llstrcatn(&ptr, nxref(node), &mylen); llstrcatn(&ptr, " ", &mylen); } if (ntag(node)) { llstrcatn(&ptr, ntag(node), &mylen); llstrcatn(&ptr, " ", &mylen); } leader = ptr-line; width -= leader; if (width < 10) { /* insufficient space */ return NULL; } /* output is available as scratch */ list = text_to_list("", width, LISTDOFREE); if (nval(node)) { STRING valtxt = nval(node); append_to_text_list(list, valtxt, width, FALSE); } /* anode is first child */ anode = nchild(node); /* check for text continuation nodes to assimilate */ if (nchild(node)) { for ( ; anode && !nchild(anode); anode = nsibling(anode)) { BOOLEAN newline=FALSE; STRING valtxt=NULL; if (eqstr(ntag(anode), "CONC")) { append_to_text_list(list, " ", width, FALSE); newline = FALSE; } else if (eqstr(ntag(anode), "CONT")) { newline = TRUE; } else { break; } valtxt = nval(anode); append_to_text_list(list, valtxt, width, newline); } } /* anode is now first non-assimilated child */ /* now add all list elements to tree as siblings first one will be tn, which we return as our result tn0 refers to previous one, for the nsibling links */ tn = tn0 = tn1 = 0; FORLIST(list, el) tn1 = alloc_displaynode(); if (!tn) { INT i; tn = tn1; /* ptr & mylen still point after leader */ llstrcatn(&ptr, el, &mylen); /* put original line */ tn1->str = strsave(line); /* now build leader we will keep reusing */ for (i=0; i<leader; i++) line[i] = '.'; line[leader-1] = ' '; } else { llstrcatn(&ptr, el, &mylen); tn1->str = strsave(line); } /* now we keep resetting ptr & mylen to after blank leader */ /* so we keep reusing that leader we built in line earlier */ ptr=line+leader; mylen=mylenorig-leader; tn1->firstchild = 0; tn1->nextsib = 0; if (tn0) tn0->nextsib = tn1; tn0 = tn1; (*count)++; ENDLIST /* special handling for empty list, which didn't get its leader */ if (is_empty_list(list)) { tn1 = alloc_displaynode(); tn = tn1; tn1->str = strsave(line); tn1->firstchild = 0; tn1->nextsib = 0; tn0 = tn1; (*count)++; } destroy_list(list); list=0; if (gen < maxgen) { /* our children hang off of tn2, which is last node of our sibling tree; tn0 is previously added child */ tn2 = tn1; tn0 = 0; /* anode was last unassimilated child */ for (child = anode; child; child = nsibling(child)) { tn1 = add_dnodes(child, gen+1, indent, maxgen, count, canvas); if (!tn1) continue; /* child was skipped */ /* link new displaynode into tree we're building */ if (tn0) tn0 = tn0->nextsib = tn1; else /* first child - first time thru loop */ tn0 = tn2->firstchild = tn1; /* child displaynode might have (overflow or assimilated) siblings */ while (tn0->nextsib) tn0 = tn0->nextsib; } } return tn; }
/*================================================ * edit_add_record -- Add record to database by editing * recstr: [IN] default record * redt: [IN] re-edit message * ntype, [IN] S, E, or X * cfrm: [IN] confirm message *==============================================*/ static RECORD edit_add_record (STRING recstr, STRING redt, STRING redtopt, char ntype, STRING cfrm) { FILE *fp; NODE node=0, refn; STRING msg, key; BOOLEAN emp; XLAT ttmi = transl_get_predefined_xlat(MEDIN); STRING (*getreffnc)(void) = NULL; /* get next internal key */ void (*todbasefnc)(NODE) = NULL; /* write record to dbase */ void (*tocachefnc)(NODE) = NULL; /* write record to cache */ /* set up functions according to type */ if (ntype == 'S') { getreffnc = getsxref; todbasefnc = sour_to_dbase; tocachefnc = sour_to_cache; } else if (ntype == 'E') { getreffnc = getexref; todbasefnc = even_to_dbase; tocachefnc = even_to_cache; } else { /* X */ getreffnc = getxxref; todbasefnc = othr_to_dbase; tocachefnc = othr_to_cache; } /* Create template for user to edit */ if (!(fp = fopen(editfile, LLWRITETEXT))) { msg_error(_(qSnofopn), editfile); return FALSE; } prefix_file_for_edit(fp); fprintf(fp, "%s\n", recstr); /* Have user edit new record */ fclose(fp); do_edit(); while (TRUE) { INT cnt; node = file_to_node(editfile, ttmi, &msg, &emp); if (!node) { if (ask_yes_or_no_msg(msg, redt)) { /* yes, edit again */ do_edit(); continue; } break; } cnt = resolve_refn_links(node); /* check validation & allow user to reedit if invalid */ /* this is a showstopper, so alternative is to abort */ if (!valid_node_type(node, ntype, &msg, NULL)) { if (ask_yes_or_no_msg(msg, redt)) { do_edit(); continue; } free_nodes(node); node = NULL; /* fail out */ break; } /* Allow user to reedit if desired if any refn links unresolved */ /* this is not a showstopper, so alternative is to continue */ if (cnt > 0) { char msgb[120]; snprintf(msgb, sizeof(msgb) , get_unresolved_ref_error_string(cnt), cnt); if (ask_yes_or_no_msg(msgb, redtopt)) { write_node_to_editfile(node); do_edit(); continue; } } break; } if (!node || !ask_yes_or_no(cfrm)) { if (node) free_nodes(node); return NULL; } nxref(node) = strsave((STRING)(*getreffnc)()); key = rmvat(nxref(node)); for (refn = nchild(node); refn; refn = nsibling(refn)) { if (eqstr("REFN", ntag(refn)) && nval(refn)) add_refn(nval(refn), key); } (*todbasefnc)(node); (*tocachefnc)(node); return key_to_record(key); }