// Manage the selection list when there is a new current point selected void imodSelectionNewCurPoint(ImodView *vi, Imod *imod, Iindex indSave, int controlDown) { Iindex *indp; bool contourless; // If ctrl-select, then manage selection list if (controlDown) { contourless = indSave.object >= 0 && !vi->imod->obj[indSave.object].contsize && vi->imod->obj[indSave.object].meshsize; // First add previous point if list is empty if (!ilistSize(vi->selectionList) && (indSave.contour >= 0 || contourless)) imodSelectionListAdd(vi, indSave); // If point not on list, add it. If point is on list, then remove // it and pop current point back to last item on list if (imodSelectionListQuery(vi, imod->cindex.object, imod->cindex.contour) < -1) { imodSelectionListAdd(vi, imod->cindex); } else { imodSelectionListRemove(vi, imod->cindex.object, imod->cindex.contour); if (ilistSize(vi->selectionList)) { indp = (Iindex *)ilistItem(vi->selectionList, ilistSize(vi->selectionList) - 1); imod->cindex = *indp; } } } else // But if Ctrl not down, clear out the list imodSelectionListClear(vi); }
// Remove the given obj, cont from the selection list if it is on it void imodSelectionListRemove(ImodView *vi, int ob, int co) { Iindex *index; int i; for (i = 0; i < ilistSize(vi->selectionList); i++) { index = (Iindex *)ilistItem(vi->selectionList, i); if (index->object == ob && index->contour == co) { ilistRemove(vi->selectionList, i); imodTrace('S', "Removing item %d, leaves %d", i, ilistSize(vi->selectionList)); return; } } }
// Clear the selection list: returns the number previously on the list int imodSelectionListClear(ImodView *vi) { int retval = ilistSize(vi->selectionList); ilistDelete(vi->selectionList); vi->selectionList = NULL; imodTrace('S', "List cleared"); return retval; }
/*! * Insert the given function into the list of functions that iiOpen will * call to check a file at position [index] in the list. The format of the * function is * ^ int iiFormatCheck(ImodImageFile *inFile) */ void iiInsertCheckFunction(IIFileCheckFunction func, int index) { if (initCheckList()) return; if (index < ilistSize(sCheckList)) ilistInsert(sCheckList, &func, index); else ilistAppend(sCheckList, &func); }
/* * Delete Row clicked for table */ void AngleDialog::deleteClicked() { int row = mTable->currentRow(); Ilist *saved = mApp->getSavedList(); if (row < 0 || row >= ilistSize(saved)) return; ilistRemove(saved, row); updateTable(); mApp->setSaveModified(); }
static void dumpSelectionList(ImodView *vi) { if (!imodDebug('S')) return; imodPrintStderr("%d on list:\n", ilistSize(vi->selectionList)); Iindex *index = (Iindex *)ilistFirst(vi->selectionList); while (index) { imodPrintStderr("%d %d %d\n", index->object, index->contour, index->point); index = (Iindex *)ilistNext(vi->selectionList); } }
/* * Find a file either by its iiFile or its fp entry */ static int findFileInList(ImodImageFile *iiFile, FILE *fp) { int i; ImodImageFile **listPtr; for (i = 0; i < ilistSize(sOpenedFiles); i++) { listPtr = (ImodImageFile **)ilistItem(sOpenedFiles, i); if ((iiFile && *listPtr == iiFile) || (fp && (*listPtr)->fp == fp)) { return i; } } return -1; }
/* * Returns 1 if all contours in the remnant list are on selection list */ int VertBufManager::checkSelectedAreRemnants(VertBufData *vbd, int obNum) { Iindex *index; if (Imodv->imod->cindex.object == obNum && Imodv->imod->cindex.contour >= 0 && !numberInList(Imodv->imod->cindex.contour, vbd->remnantIndList, vbd->numRemnant, 0)) return 0; for (int i = 0; i < ilistSize(Imodv->vi->selectionList); i++) { index = (Iindex *)ilistItem(Imodv->vi->selectionList, i); if (index->object == obNum && index->contour >= 0 && !numberInList(index->contour, vbd->remnantIndList, vbd->numRemnant, 0)) return 0; } return 1; }
// If object-contour is on selection list, return point number; otherwise -2 // If co < 0, simply tests whether object is on selection list int imodSelectionListQuery(ImodView *vi, int ob, int co) { Iindex *index; int i; for (i = 0; i < ilistSize(vi->selectionList); i++) { index = (Iindex *)ilistItem(vi->selectionList, i); if (index->object == ob && (index->contour == co || co < 0)) { imodTrace('S', "Query returns %d", index->point); return index->point; } } return -2; }
// Add an item to the selection list void imodSelectionListAdd(ImodView *vi, Iindex newIndex) { int multiObject = 1; // Placekeeper for possible argument/preference Iindex *index; int i; // Clear list if a different object is given and multiobject not allowed if (ilistSize(vi->selectionList) && !multiObject) { index = (Iindex *)ilistFirst(vi->selectionList); if (index->object != newIndex.object) imodSelectionListClear(vi); } // create list if it does not exist if (!vi->selectionList) { vi->selectionList = ilistNew(sizeof(Iindex), 4); if (!vi->selectionList) return; // ERROR } // Look through list to see if contour is already there and update point for (i = 0; i < ilistSize(vi->selectionList); i++) { index = (Iindex *)ilistItem(vi->selectionList, i); if (index->object == newIndex.object && index->contour == newIndex.contour) { index->point = newIndex.point; imodTrace('S', "update %d %d %d", newIndex.object, newIndex.contour, newIndex.point); return; } } // Add index to list imodTrace('S', "adding %d %d %d", newIndex.object, newIndex.contour, newIndex.point); ilistAppend(vi->selectionList, &newIndex); dumpSelectionList(vi); }
/* * Set Angles clicked for table, set the angles from the current row */ void AngleDialog::setAnglesClicked() { int row = mTable->currentRow(); Ilist *saved = mApp->getSavedList(); SavedDefocus *item; QString str; if (row < 0 || row >= ilistSize(saved)) return; item = (SavedDefocus *)ilistItem(saved, row); str.sprintf("%.2f",item->lAngle); mLowAngleEdit->setText(str); str.sprintf("%.2f",item->hAngle); mHighAngleEdit->setText(str); qApp->processEvents(); anglesSet(0); }
/* This is meant to be called sequentially for all indexes in the entity, not for random access */ static int istoreFindValue(Ilist *list, int index, int type, float *value, int *listInd) { Istore *store; while (*listInd < ilistSize(list)) { store = istoreItem(list, *listInd); if ((store->flags & GEN_STORE_NOINDEX) || store->index.i > index) break; (*listInd)++; if (store->index.i == index && store->type == type) { *value = store->value.f; return 1; } } return 0; }
/*! * Reopen a file that has already been opened and analyzed. Returns 1 if the file is * already open or 2 for other errors. */ int iiReopen(ImodImageFile *inFile) { IIFileCheckFunction *checkFunc; int i; if (!inFile) return -1; if (inFile->fp) return 1; if (!inFile->fmode[0]) strncpy(inFile->fmode, "rb+", 3); if (inFile->reopen) { if ((*inFile->reopen)(inFile)) return 2; inFile->state = IISTATE_READY; addToOpenedList(inFile); return 0; } inFile->fp = fopen(inFile->filename, inFile->fmode); if (!inFile->fp) return 2; /* Add back to opened list: failure is not an error because FP-based programs don't use iiReopen */ addToOpenedList(inFile); if (inFile->state != IISTATE_NOTINIT) { inFile->state = IISTATE_READY; return 0; } /* If the file is not initted yet, treat it as unknown and deal with from scratch */ inFile->format = IIFILE_UNKNOWN; for (i = 0; i < ilistSize(sCheckList); i++) { checkFunc = (IIFileCheckFunction *)ilistItem(sCheckList, i); if (!(*checkFunc)(inFile)) { inFile->state = IISTATE_READY; return 0; } } return -1; }
// Move all contours in current object to new object void imodMoveAllContours(ImodView *vi, int obNew) { int co; Imod *imod = vi->imod; Iobj *obj = imodObjectGet(imod); // Just record an object property change since there may be max surface number changes // as well as the store info vi->undo->objectPropChg(); vi->undo->objectPropChg(obNew); // If object has mesh but no contours, transfers the meshes if (!obj->contsize && obj->meshsize) { for (co = 0; co < obj->meshsize; co++) imod->obj[obNew].mesh = imodel_mesh_add(&obj->mesh[co], imod->obj[obNew].mesh, &imod->obj[obNew].meshsize); return; } // Move all the fine grain information over then delete the store if (ilistSize(obj->store)) { for (co = 0; co <= obj->surfsize; co++) istoreCopyContSurfItems(obj->store, &imod->obj[obNew].store, co, co, 1); for (co = 0; co < obj->contsize; co++) istoreCopyContSurfItems(obj->store, &imod->obj[obNew].store, co, imod->obj[obNew].contsize + co, 0); ilistDelete(obj->store); obj->store = NULL; } // Record all contours as moving vi->undo->allContourMove(imod->cindex.object, obNew); /* DNM: need to set contour inside loop because each deletion sets it to -1; and need to not increment counter! */ for (co = 0; co < (int)obj->contsize; ) { imod->cindex.contour = 0; imodObjectAddContour(&imod->obj[obNew], &obj->cont[co]); imodObjectRemoveContour(obj, co); } }
/* * Update all the entries in the table */ void AngleDialog::updateTable() { Ilist *saved = mApp->getSavedList(); SavedDefocus *item; QString str; int row, j; for (row = 0; row < ilistSize(saved); row++) { // Add a row if needed if (row + 1 > mTable->rowCount()) { mTable->insertRow(row); mTable->setRowHeight(row, mTable->fontMetrics().height() + 3); for (j = 0; j < 4; j++) { QTableWidgetItem *witem = new QTableWidgetItem(); witem->setTextAlignment(Qt::AlignRight); mTable->setItem(row, j, witem); } } // Load the data item = (SavedDefocus *)ilistItem(saved, row); str.sprintf("%.2f", item->lAngle); mTable->item(row,0)->setText(str); str.sprintf("%.2f", item->hAngle); mTable->item(row,1)->setText(str); str.sprintf("%.2f", (item->lAngle + item->hAngle) / 2.); mTable->item(row,2)->setText(str); str.sprintf("%.2f", item->defocus); mTable->item(row,3)->setText(str); } // Get rid of extra rows (hope it deletes the items) for (j = mTable->rowCount() - 1; j >= row; j--) mTable->removeRow(j); mDeleteButton->setEnabled(row > 0); mReturnButton->setEnabled(row > 0); mToFileButton->setEnabled(row > 0); if (mTable->currentRow() < 0 && mTable->rowCount()) mTable->setCurrentCell(0, 0); }
/* * Adds one item to the defocus list, keeping the list in order and * and avoiding duplicate starting and ending view numbers */ void addItemToDefocusList(Ilist *lstSaved, SavedDefocus toSave) { SavedDefocus *item; int i, matchInd = -1, insertInd = 0; // Look for match or place to insert for (i = 0; i < ilistSize(lstSaved); i++) { item = (SavedDefocus *)ilistItem(lstSaved, i); if (item->startingSlice == toSave.startingSlice && item->endingSlice == toSave.endingSlice) { matchInd = i; *item = toSave; break; } if (item->lAngle + item->hAngle <= toSave.lAngle + toSave.hAngle) insertInd = i + 1; } // If no match, now insert if (matchInd < 0 && ilistInsert(lstSaved, &toSave, insertInd)) exitError("Failed to add item to list of angles and defocuses"); }
/* * Reads a defocus file whose name is in fnDefocus and stores the values * in an Ilist of SavedDefocus structures, eliminating duplications if any. * The return value is the Ilist, which may be empty if the file does not * exist. */ Ilist *readDefocusFile(const char *fnDefocus, int &defVersion) { FILE *fp; SavedDefocus saved; char line[MAX_LINE]; int nchar, versTmp; float langtmp, hangtmp, defoctmp; Ilist *lstSaved = ilistNew(sizeof(SavedDefocus), 10); if (!lstSaved) exitError("Allocating list for angles and defocuses"); fp = fopen(fnDefocus, "r"); defVersion = 0; versTmp = 0; if (fp) { while (1) { nchar = fgetline(fp, line, MAX_LINE); if (nchar == -2) break; if (nchar == -1) exitError("Error reading defocus file %s", fnDefocus); if (nchar) { sscanf(line, "%d %d %f %f %f %d", &saved.startingSlice, &saved.endingSlice , &langtmp, &hangtmp, &defoctmp, &versTmp); if (!ilistSize(lstSaved)) defVersion = versTmp; saved.lAngle = langtmp; saved.hAngle = hangtmp; saved.defocus = defoctmp / 1000.; saved.startingSlice--; saved.endingSlice--; addItemToDefocusList(lstSaved, saved); } if (nchar < 0) break; } fclose(fp); } return lstSaved; }
void ImodvOlist::actionButtonClicked(int which) { Imod *imod = Imodv->imod; IobjGroup *group, *ogroup; int ob, index, changed = 1; if (which != OBJGRP_NEW && which != OBJGRP_DELETE) { group = (IobjGroup *)ilistItem(imod->groupList, imod->curObjGroup); if (!group) return; } switch (which) { case OBJGRP_NEW: imodvRegisterModelChg(); group = objGroupListExpand(&imod->groupList); if (!group) break; ogroup = (IobjGroup *)ilistItem(imod->groupList, imod->curObjGroup); if (ogroup) group->objList = ilistDup(ogroup->objList); imod->curObjGroup = ilistSize(imod->groupList) - 1; updateGroups(Imodv); break; case OBJGRP_DELETE: if (imod->curObjGroup < 0) return; imodvRegisterModelChg(); if (objGroupListRemove(imod->groupList, imod->curObjGroup)) break; imod->curObjGroup = B3DMIN(B3DMAX(0, imod->curObjGroup - 1), ilistSize(imod->groupList) - 1); updateGroups(Imodv); break; case OBJGRP_CLEAR: imodvRegisterModelChg(); ilistTruncate(group->objList, 0); updateGroups(Imodv); break; case OBJGRP_ADDALL: imodvRegisterModelChg(); if (group->objList) ilistTruncate(group->objList, 0); for (ob = 0; ob < imod->objsize; ob++) if (objGroupAppend(group, ob)) return; updateGroups(Imodv); break; case OBJGRP_SWAP: imodvRegisterModelChg(); for (ob = 0; ob < imod->objsize; ob++) { index = objGroupLookup(group, ob); if (index >= 0) ilistRemove(group->objList, index); else if (objGroupAppend(group, ob)) return; } updateGroups(Imodv); break; case OBJGRP_TURNON: case OBJGRP_TURNOFF: case OBJGRP_OTHERSON: case OBJGRP_OTHERSOFF: changed = 0; for (ob = 0; ob < imod->objsize; ob++) { index = objGroupLookup(group, ob); if (((index >= 0 && which == OBJGRP_TURNON) || (index < 0 && which == OBJGRP_OTHERSON)) && iobjOff(imod->obj[ob].flags)) { imodvRegisterObjectChg(ob); imod->obj[ob].flags &= ~IMOD_OBJFLAG_OFF; changed = 1; } else if (((index >= 0 && which == OBJGRP_TURNOFF) || (index < 0 && which == OBJGRP_OTHERSOFF)) && !iobjOff(imod->obj[ob].flags)) { imodvRegisterObjectChg(ob); imod->obj[ob].flags |= IMOD_OBJFLAG_OFF; changed = 1; } } imodvDraw(Imodv); imodvDrawImodImages(); imodvObjedNewView(); break; } if (changed) imodvFinishChgUnit(); }
/* * Analyze a mesh and pack it into VBOs if it qualifies */ int VertBufManager::analyzeMesh(Imesh *mesh, float zscale, int fillType, int useFillColor, DrawProps *defProps) { bool valid = true; RGBTmap colors; pair<RGBTmap::iterator,bool> mapret; RGBTmap::iterator mapit; VertBufData *vbd = mesh->vertBuf; RGBTindices rInd; Istore *stp; Istore store; int *mlist = mesh->list; DrawProps curProps; int i, j, cumInd, defInd, nextItemIndex, stateFlags, vertDflt, changeFlags, firstDflt; b3dUInt32 vertRGBT, firstRGBT; int remInd, curSave, curNext; int numDefaultTri = 0, numMixedTri = 0; int handleFlags, nonVboFlags = 0; if (fillType) handleFlags = (useFillColor ? CHANGED_FCOLOR : CHANGED_COLOR) | CHANGED_TRANS; else { handleFlags = CHANGED_COLOR | CHANGED_TRANS; nonVboFlags = CHANGED_3DWIDTH; } rInd.numFanInds = 0; // Check if there is a current VBO and it is all still valid packRGBT(defProps, useFillColor, firstRGBT); if (vbd && vbd->vbObj && fillType == vbd->fillType && (!ilistSize(mesh->store) || (vbd->useFillColor == useFillColor && vbd->defaultRGBT == firstRGBT)) && vbd->checksum == istoreChecksum(mesh->store)) { // If Z-scale still valid, return a -1; if have to fix the Z-scale, do it, return -2 if (fabs((double)(zscale - vbd->zscale)) < 1.e-4) return -1; b3dBindBuffer(GL_ARRAY_BUFFER, vbd->vbObj); if (loadVertexNormalArray(mesh, zscale, fillType)) { vbCleanupVBD(mesh); return 1; } vbd->zscale = zscale; return -2; } // Now proceed to full analysis nextItemIndex = istoreFirstChangeIndex(mesh->store); for (i = 0; i < mesh->lsize && valid; i++) { switch (mlist[i]) { case IMOD_MESH_BGNTRI: case IMOD_MESH_ENDTRI: case IMOD_MESH_BGNPOLY: case IMOD_MESH_NORMAL: case IMOD_MESH_BGNBIGPOLY: case IMOD_MESH_SWAP: valid = false; break; case IMOD_MESH_BGNPOLYNORM: i++; while (mlist[i] != IMOD_MESH_ENDPOLY && valid) { valid = (mlist[i] == mlist[i+1] + 1) && (mlist[i+2] == mlist[i+3] + 1) && (mlist[i+4] == mlist[i+5] + 1); i += 6; numDefaultTri++; } break; case IMOD_MESH_BGNPOLYNORM2: i++; while (mlist[i] != IMOD_MESH_ENDPOLY) { if (nextItemIndex < i || nextItemIndex > i + 2) { // Count a default triangle if no changes in this range numDefaultTri++; i += 3; } else { // Otherwise look at each vertex and get its properties if it is changed for (j = 0; j < 3; j++) { vertDflt = 1; if (i == nextItemIndex) { curProps = *defProps; stateFlags = 0; nextItemIndex = istoreNextChange(mesh->store, defProps, &curProps, &stateFlags, &changeFlags); if (stateFlags & handleFlags) { vertDflt = 0; packRGBT(&curProps, useFillColor, vertRGBT); } // Take triangle as mixed if it has unhandleable flags if (stateFlags & nonVboFlags) { firstDflt = -1; i++; continue; } } // For first vertex record the triangle properties, for later one record if // there is a mismatch from the first if (!j) { firstDflt = vertDflt; firstRGBT = vertRGBT; } else if (vertDflt != firstDflt || (!vertDflt && vertRGBT != firstRGBT)) { firstDflt = -1; } i++; } // Count whether it is a default or mixed triangle if (firstDflt < 0) { numMixedTri++; } else if (firstDflt > 0) { numDefaultTri++; } else { // For a special triangle, add to list of RGBT values with a count of 1 if it // is not on the list; if it is already on the list increment its count; rInd.firstElement = i; rInd.numInds = 1; mapret = colors.insert(pair<b3dUInt32,RGBTindices>(firstRGBT, rInd)); if (mapret.second == false) mapret.first->second.numInds++; } } } break; case IMOD_MESH_END: break; } } if (!valid) { vbCleanupVBD(mesh); return 3; } if (!colors.size() && !numDefaultTri) { vbCleanupVBD(mesh); return 2; } vbd = allocateVBDIfNeeded(&mesh->vertBuf); if (!vbd) return 1; // Now allocate whatever pieces are needed in there. Set remnant value in vbd first // Add up the special set sizes and re-initialize the counts to be starting indexes cumInd = numDefaultTri * 3; vbd->numRemnant = 0; if (numMixedTri) vbd->numRemnant = numMixedTri * 3 + 3; i = -1; if (allocateSpecialSets(vbd, colors.size(), cumInd, 0) || processMap(vbd, &colors, cumInd, 3, i)) { vbCleanupVBD(mesh); return 1; } imodTrace('b',"dfltInd %d spec sets %d cumind %d remnant %d", vbd->numIndDefault, vbd->numSpecialSets, cumInd, numMixedTri); // Create the store for remnants if (numMixedTri) { ilistDelete(vbd->remnantStore); vbd->remnantStore = ilistNew(sizeof(Istore), vbd->numRemnant / 8); if (!vbd->remnantStore) { vbCleanupVBD(mesh); return 1; } vbd->remnantStore->quantum = B3DMAX(vbd->remnantStore->quantum, vbd->numRemnant / 8); vbd->remnantIndList[0] = IMOD_MESH_BGNPOLYNORM2; } // Now get the vertex buffers themselves if (genAndBindBuffers(vbd, mesh->vsize, cumInd)) { vbCleanupVBD(mesh); return 1; } imodTrace('b',"vbObj %d ebObj %d", vbd->vbObj, vbd->ebObj); // Load the vertices and finish with buffer for now if (loadVertexNormalArray(mesh, zscale, fillType)) { vbCleanupVBD(mesh); return 1; } b3dBindBuffer(GL_ARRAY_BUFFER, 0); // Set the identifiers of this vb data vbd->zscale = zscale; vbd->fillType = fillType; vbd->useFillColor = useFillColor; packRGBT(defProps, useFillColor, vbd->defaultRGBT); vbd->checksum = istoreChecksum(mesh->store); // Get or use temporary array for indexes if (allocateTempInds(cumInd)) { vbCleanupVBD(mesh); return 1; } // No fine grain: copy all the indices into index array defInd = 0; if (!mesh->store) { i = 0; while (mlist[i] != IMOD_MESH_END) { if (mlist[i] == IMOD_MESH_BGNPOLYNORM) { i++; while (mlist[i] != IMOD_MESH_ENDPOLY) { i++; mInds[defInd++] = mlist[i++] / 2; } } else if (mlist[i] == IMOD_MESH_BGNPOLYNORM2) { i++; while (mlist[i] != IMOD_MESH_ENDPOLY) { mInds[defInd++] = mlist[i++] / 2; } } i++; } } else { // Otherwise process all triangles into index array or remnant arrays nextItemIndex = istoreFirstChangeIndex(mesh->store); remInd = 1; for (i = 0; i < mesh->lsize; i++) { switch (mlist[i]) { case IMOD_MESH_BGNPOLYNORM2: i++; while (mlist[i] != IMOD_MESH_ENDPOLY) { // Repeat the analysis to determine default, special, or mixed triangle curSave = mesh->store->current; if (nextItemIndex < i || nextItemIndex > i + 2) { firstDflt = 1; } else { // Otherwise look at each vertex and get its properties if it is changed for (j = 0; j < 3; j++) { vertDflt = 1; if (i + j == nextItemIndex) { curProps = *defProps; stateFlags = 0; nextItemIndex = istoreNextChange(mesh->store, defProps, &curProps, &stateFlags, &changeFlags); if (stateFlags & handleFlags) { vertDflt = 0; packRGBT(&curProps, useFillColor, vertRGBT); } if (stateFlags & nonVboFlags) { firstDflt = -1; continue; } } // For first vertex record the triangle properties, for later one stop if // there is a mismatch from the first if (!j) { firstDflt = vertDflt; firstRGBT = vertRGBT; } else if (vertDflt != firstDflt || (!vertDflt && vertRGBT != firstRGBT)) { firstDflt = -1; } } } // Save indexes for default or special triangles if (firstDflt > 0) { mInds[defInd++] = mlist[i++] / 2; mInds[defInd++] = mlist[i++] / 2; mInds[defInd++] = mlist[i++] / 2; } else if (firstDflt == 0) { mapit = colors.find(firstRGBT); mInds[mapit->second.numInds++] = mlist[i++] / 2; mInds[mapit->second.numInds++] = mlist[i++] / 2; mInds[mapit->second.numInds++] = mlist[i++] / 2; } else { // For mixed triangle, save the current pointer, copy the index for each // vertex to the remnant index array, and copy all stores for that vertex // to the remnant store, changing the index to the new value curNext = mesh->store->current; for (j = 0; j < 3; j++) { vbd->remnantIndList[remInd] = mlist[i]; while (curSave < curNext) { stp = istoreItem(mesh->store, curSave); if (stp->index.i == i) { store = *stp; store.index.i = remInd; if (istoreInsert(&vbd->remnantStore, &store)) { vbCleanupVBD(mesh); return 1; } curSave++; } else break; } i++; remInd++; } mesh->store->current = curNext; } } break; case IMOD_MESH_END: break; } } } if (vbd->numRemnant) { vbd->remnantIndList[remInd++] = IMOD_MESH_ENDPOLY; vbd->remnantIndList[remInd++] = IMOD_MESH_END; } b3dBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, cumInd * sizeof(GLuint), mInds); b3dBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); return 0; }
/* * Analyzes the list of angular ranges and defocuses to see if the view * numbers are correct, using the nz tilt angles in angles (which can be NULL * if there are no tilt angles). If it detects that the views are low by one, * it will adjust them. If there are other inconsistencies, it returns 1. */ int checkAndFixDefocusList(Ilist *list, float *angles, int nz, int defVersion) { SavedDefocus *item; int allEqual = 1, allOffByOne = 1, numEmpty = 0; int minStart = 10000, maxEnd = -100; int i, k, start, end, startAmbig, endAmbig; float tol = 0.02f; for (k = 0; k < ilistSize(list); k++) { item = (SavedDefocus *)ilistItem(list, k); minStart = B3DMIN(minStart, item->startingSlice); maxEnd = B3DMAX(maxEnd, item->endingSlice); startAmbig = 0; endAmbig = 0; if (nz == 1 || !angles) { start = 0; end = 0; /*printf("item %d start %d end %d low %f high %f has to start %d " "end %d\n", k, item->startingSlice, item->endingSlice, item->lAngle, item->hAngle, start, end);*/ } else { start = -1; end = -1; // Find first and last slice whose angle is within the range for (i = 0; i < nz; i++) { if (item->lAngle - tol < angles[i] && angles[i] < item->hAngle + tol) { if (start < 0) start = i; end = i; } // But also see if there could be ambiguity about an angle near one // end of the range, provided this is not a single-image range if (!fabs(item->hAngle - item->lAngle) < tol) { if (fabs((double)(item->lAngle - angles[i])) < 1.01 * tol) { if (angles[0] <= angles[nz - 1]) startAmbig = 1; else endAmbig = 1; /*printf("Angle %d, %f ambiguous to low angle %f, start %d end %d\n" ,i, angles[i], item->lAngle, startAmbig, endAmbig);*/ } if (fabs((double)(item->hAngle - angles[i])) < 1.01 * tol) { if (angles[0] <= angles[nz - 1]) endAmbig = 1; else startAmbig = 1; /*printf("Angle %d, %f ambiguous to high angle %f, start %d end %d\n" ,i, angles[i], item->hAngle, startAmbig, endAmbig);*/ } } } /*printf("item %d start %d end %d low %f high %f implied start %d " "end %d\n", k, item->startingSlice, item->endingSlice, item->lAngle, item->hAngle, start, end);*/ // If can't find, skip this one, count how many times this happens // This used to guarantee it thought they were off by 1! if (start < 0 || end < 0) { numEmpty++; continue; } } if ((start != item->startingSlice && !startAmbig) || (end != item->endingSlice && !endAmbig)) allEqual = 0; if ((start != item->startingSlice + 1 && !startAmbig) || (end != item->endingSlice + 1 && !endAmbig)) allOffByOne = 0; } // If we didn't find out anything, see if min and max are at least // consistent with the bug, and go ahead and adjust if (allEqual && allOffByOne && minStart == -1 && maxEnd < nz - 1) allEqual = 0; // Adjust them all if all off by one as far as we can tell, for old data if ((!allEqual || allOffByOne) && defVersion < 2) { printf("View numbers in defocus file appear to be low by 1;\n" " adding 1 to correct for old Ctfplotter bug\n"); for (k = 0; k < ilistSize(list); k++) { item = (SavedDefocus *)ilistItem(list, k); item->startingSlice++; item->endingSlice++; } } if ((!allEqual && allOffByOne && defVersion < 2) || (allEqual && !allOffByOne)) return 0; return 1; }
void ImodvOlist::updateGroups(ImodvApp *a) { IobjGroup *group; int i, ob, numGroups = ilistSize(a->imod->groupList); int curGrp = a->imod->curObjGroup; int *objs; bool *states; bool showChgd = false; QString str; diaSetSpinMMVal(mGroupSpin, 0, numGroups, curGrp + 1); str.sprintf("/%d", numGroups); mNumberLabel->setText(str); mNameEdit->setEnabled(curGrp >= 0); for (i = 1; i < OBJLIST_NUMBUTTONS; i++) mButtons[i]->setEnabled(curGrp >= 0); if (curGrp < 0) { if (grouping) { mFrame->hide(); for (ob = 0; ob < numOolistButtons; ob++) groupButtons[ob]->hide(); mFrame->show(); adjustFrameSize(); } grouping = false; return; } if (!grouping) { mFrame->hide(); for (ob = 0; ob < numOolistButtons; ob++) groupButtons[ob]->show(); mFrame->show(); adjustFrameSize(); } grouping = true; group = (IobjGroup *)ilistItem(a->imod->groupList, curGrp); if (!group) return; mNameEdit->setText(group->name); states = (bool *)malloc(sizeof(bool) * numOolistButtons); if (!states) return; for (ob = 0; ob < numOolistButtons; ob++) states[ob] = false; objs = (int *)ilistFirst(group->objList); if (objs) { for (i = 0; i < ilistSize(group->objList); i++) if (objs[i] >= 0 && objs[i] < numOolistButtons) states[objs[i]] = true; } for (ob = 0; ob < numOolistButtons; ob++) { if (ob < a->imod->objsize) { diaSetChecked(groupButtons[ob], states[ob]); if (groupButtons[ob]->isHidden()) { groupButtons[ob]->show(); showChgd = true; } } else if (!groupButtons[ob]->isHidden()) { groupButtons[ob]->hide(); showChgd = true; } } free(states); if (showChgd) adjustFrameSize(); }
/*! * Tries to open an image file with name [filename] and with the fopen mode * [mode] (e.g. "rb"), using the file format check functions on the list. * If [filename] is NULL or an empty string, then it assigns stdin to the file * pointer. Returns NULL for error; it and all checking routines should call * b3dError with their error strings. */ ImodImageFile *iiOpen(const char *filename, const char *mode) { ImodImageFile *ofile; IIFileCheckFunction *checkFunc; int i, err = 0; /* If the mode contains w for a new file, call the open routine for a default file */ if (strstr(mode, "w")) return iiOpenNew(filename, mode, IIFILE_DEFAULT); if ((ofile = iiNew()) == NULL) return NULL; if (filename && filename[0]) ofile->fp = fopen(filename, mode); else ofile->fp = stdin; if (ofile->fp == NULL || initCheckList()) { b3dError(stderr, "ERROR: iiOpen - Opening file %s\n", filename); iiDelete(ofile); return(NULL); } ofile->format = IIFILE_UNKNOWN; ofile->filename = strdup(filename); strncpy(ofile->fmode, mode, 3); /* Try to open the file with each of the check functions in turn * until one succeeds */ for (i = 0; i < ilistSize(sCheckList); i++) { checkFunc = (IIFileCheckFunction *)ilistItem(sCheckList, i); /* If file was closed and couldn't reopen, bail out */ if (ofile->fp == NULL) { b3dError(stderr, "ERROR: iiOpen - %s could not be reopened\n", filename); break; } if (!(err = (*checkFunc)(ofile))) { if (ofile->numVolumes > 1 && !sAllowMultiVolume) { b3dError(stderr, "ERROR: iiOpen - %s is an HDF file with multiple volumes and " "cannot be opened by this program or with current options to the " "program\n", filename); } else { ofile->state = IISTATE_READY; if (!addToOpenedList(ofile)) return ofile; } iiDelete(ofile); return NULL; } if (err != IIERR_NOT_FORMAT) break; } if (err == IIERR_NOT_FORMAT) b3dError(stderr, "ERROR: iiOpen - %s has unknown format.\n", filename); iiDelete(ofile); return NULL; }