void AssembleData(u8 *target, int nStructs, const StructDesc &targetDesc, StructDesc &desc, u8 *data) { StructDesc *srcDesc = &desc; AssembleData(target, nStructs, targetDesc, &srcDesc, &data, 1); }
vtkDataSet * Streaker::ConstructDataset(const std::string &var, const StreakInfo &s, const PDBFileObjectVector &pdb) { const char *mName = "Streaker::ConstructDataset: "; // Gather up the times so we know how wide the new mesh is. std::vector<double> times; debug4 << mName << "Times = " << endl; for(size_t i = 0; i < pdb.size(); ++i) { double *vals = 0; int nvals = 0; debug4 << " "; if(pdb[i]->GetDoubleArray(s.xvar.c_str(), &vals, &nvals)) { for(int j = 0; j < nvals; ++j) { times.push_back(vals[j]); debug4 << vals[j] << " "; } delete [] vals; } else debug4 << "** Could not read times in " << pdb[i]->GetName().c_str() << " **"; debug4 << endl; } int sdims[3]; sdims[0] = (int)times.size(); sdims[1] = s.hsize; sdims[2] = 1; int nnodes = sdims[0] * sdims[1]; debug4 << mName << "sdims = {" << sdims[0] << ","<<sdims[1] <<","<<sdims[2]<<"}"<<endl; // Let's assemble vtkDataArray for the y and "z" values. vtkFloatArray *yvar = AssembleData(s.yvar, sdims, s.slice, s.sliceIndex, pdb); vtkFloatArray *zvar = AssembleData(s.zvar, sdims, s.slice, s.sliceIndex, pdb); // Use the yvar and time to create the points. vtkPoints *points = vtkPoints::New(); points->SetNumberOfPoints(nnodes); float *coords = (float *)points->GetVoidPointer(0); float *yc = (float *)yvar->GetVoidPointer(0); if(s.integrate) { double *ysum = new double[sdims[0]]; memset(ysum, 0, sizeof(double) * sdims[0]); for(int j = 0; j < sdims[1]; ++j) for(int i = 0; i < sdims[0]; ++i) { double xval = times[i]; xval *= s.x_scale; xval += s.x_translate; ysum[i] += (double)*yc++; double yval = ysum[i]; yval *= s.y_scale; yval += s.y_translate; if(s.log == LOGTYPE_LOG) yval = log((yval > 0.) ? yval : 1.e-9); else if(s.log == LOGTYPE_LOG10) yval = log10((yval > 0.) ? yval : 1.e-9); *coords++ = (float)xval; *coords++ = (float)yval; *coords++ = 0.; } delete [] ysum; } else { for(int j = 0; j < sdims[1]; ++j) for(int i = 0; i < sdims[0]; ++i) { double xval = times[i]; xval *= s.x_scale; xval += s.x_translate; double yval = (double)*yc++; yval *= s.y_scale; yval += s.y_translate; if(s.log == LOGTYPE_LOG) yval = log((yval > 0.) ? yval : 1.e-9); else if(s.log == LOGTYPE_LOG10) yval = log10((yval > 0.) ? yval : 1.e-9); *coords++ = (float)xval; *coords++ = (float)yval; *coords++ = 0.; } } vtkStructuredGrid *sgrid = vtkStructuredGrid::New(); sgrid->SetPoints(points); points->Delete(); sgrid->SetDimensions(sdims); // Transform zvar. float *zarr = (float *)zvar->GetVoidPointer(0); for(int i = 0; i < zvar->GetNumberOfTuples(); ++i) zarr[i] = zarr[i] * s.z_scale + s.z_translate; if(s.cellCentered) { // Create a cell-centered version of zvar. We can ignore the first row of // data since it's no good. vtkFloatArray *cvar = vtkFloatArray::New(); int cx = sdims[0] - 1; int cy = sdims[1] - 1; cvar->SetNumberOfTuples(cx * cy); float *dest = (float *)cvar->GetVoidPointer(0); float *f = (float *)zvar->GetVoidPointer(0); for(int j = 0; j < cy; ++j) { float *src = f + ((j+1) * sdims[0]); for(int i = 0; i < cx; ++i) *dest++ = *src++; } zvar->Delete(); // Add the cvar array to the dataset. cvar->SetName(var.c_str()); sgrid->GetCellData()->AddArray(cvar); } else { // Add the zvar array to the dataset. zvar->SetName(var.c_str()); sgrid->GetPointData()->AddArray(zvar); } // Assemble the vtkDataArray for the matvar if this streak plot has a material. if(s.hasMaterial) { vtkFloatArray *nodecent_matvar = AssembleData(matvar, sdims, s.slice, s.sliceIndex, pdb); // Convert the node centered matvar into a cell centered var. We just convert // 1 fewer columns and rows from the node centered data to make the cell centered // data. Not ideal. vtkIntArray *cellcent_matvar = vtkIntArray::New(); int cx = sdims[0] - 1; int cy = sdims[1] - 1; cellcent_matvar->SetNumberOfTuples(cx * cy); int *dest = (int *)cellcent_matvar->GetVoidPointer(0); int ghostMat = matnos[0]; for(int j = 0; j < cy; ++j) { float *f = (float *)nodecent_matvar->GetVoidPointer(0); float *src = f + ((j+1) * sdims[0]); for(int i = 0; i < cx; ++i) { // mat==0 is a ghost zone. Safeguard against that value appearing // in the material data or VisIt will complain. int mat = (int)(*src++); if(mat <= 0) mat = ghostMat; *dest++ = mat; } } cellcent_matvar->SetName(STREAK_MATERIAL); sgrid->GetCellData()->AddArray(cellcent_matvar); nodecent_matvar->Delete(); } // cleanup yvar->Delete(); // Transpose I,J if the data should match Silo. if(s.matchSilo) { vtkStructuredGrid *ds = TransposeIJ(sgrid); sgrid->Delete(); sgrid = ds; } return sgrid; }