//----------------------------------------------------------------------- void MaterialService::loadFlowTextures(const FileGroupPtr& db) { // Load the TXLIST chunk from the resource mission file. Opde::FilePtr flow_tex; try { flow_tex = db->getFile("FLOW_TEX"); } catch (FileException) { LOG_ERROR("Flow chunk does not exist. Water materials may not be correctly displayed", "MaterialService::loadFlowTextures"); return; } // TODO: Exception handling on the chunk readout! // Okay, we are ready to map the arrays DarkDBChunkFLOW_TEX flows; int flow_count = flow_tex->size() / 32; // The record is 32 bytes long, this way we do not fail if the chunk is shorter try { // load flow_tex->read(&flows, flow_tex->size()); // To be sure we do not overlap } catch (Ogre::Exception& e) { // Connect the original exception to the printout: OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, String("Could not load flow textures : ") + e.getFullDescription(), "MaterialService::loadFlowTextures"); } // now try to load non-zero flow textures as materials for (int fnum = 0; fnum < flow_count; fnum++) { if (strlen(flows.flow[fnum].name) > 0) { // nonzero name, try to load // Construct the basic name of the material std::string matname("water/"); matname += flows.flow[fnum].name; LOG_INFO("MaterialService::loadFlowTextures: Loading flow %d : %d/%d '%s'", fnum, flows.flow[fnum].in_texture, flows.flow[fnum].out_texture, matname.c_str()); // try to find the texture definition. If found, clone to the @template + the in_texture/out_texture number if (MaterialManager::getSingleton().resourceExists(matname + "_in")) { MaterialPtr origMat = MaterialManager::getSingleton().getByName(matname + "_in"); StringUtil::StrStreamType strb; strb << "@template" << flows.flow[fnum].in_texture; std::string templn(strb.str()); if (MaterialManager::getSingleton().resourceExists(templn)) { MaterialManager::getSingleton().remove(templn); } MaterialPtr shadMat = origMat->clone(templn); shadMat->load(); addWorldMaterialTemplate(flows.flow[fnum].in_texture, shadMat); LOG_INFO("Flow now defined : %s (template %s_in)", templn.c_str(), matname.c_str()); } else { LOG_ERROR("Material not found : %s_in", matname.c_str()); } // OUT if (MaterialManager::getSingleton().resourceExists(matname + "_out")) { MaterialPtr origMat = MaterialManager::getSingleton().getByName(matname + "_out"); StringUtil::StrStreamType strb; strb << "@template" << flows.flow[fnum].in_texture; std::string templn(strb.str()); if (MaterialManager::getSingleton().resourceExists(templn)) { MaterialManager::getSingleton().remove(templn); } MaterialPtr shadMat = origMat->clone(templn); shadMat->load(); addWorldMaterialTemplate(flows.flow[fnum].out_texture, shadMat); LOG_INFO("Flow now defined : %s (template %s_in)", templn.c_str(), matname.c_str()); } else { LOG_ERROR("Material not found : %s_out", matname.c_str()); } } } }
vtkDataArray * avtMatvfExpression::DeriveVariable(vtkDataSet *in_ds, int currentDomainsIndex) { int i, j; int ncells = in_ds->GetNumberOfCells(); // // The 'currentDomainsIndex' is a data member of the base class that is // set to be the id of the current domain right before DeriveVariable is // called. We need that index to make sure we are getting the right mat. // // The 'currentTimeState' is a data member of the base class that is // set to be the current timestep during ExamineContract. // We need that timestep to make sure we are getting the right mat. // // doPostGhost allows us to request ghost corrected material data // if necessary. // // only ask for post ghost Material info if the dataset actually // has ghost zones and VisIt created them. avtDataAttributes &datts = GetInput()->GetInfo().GetAttributes(); bool created_ghosts = datts.GetContainsGhostZones() == AVT_CREATED_GHOSTS; // check bitmask to make sure we actually have bondary ghost zones // (in some cases we may only have nesting ghosts zones, and post ghost // is not the proper path) if(created_ghosts) created_ghosts = datts.GetGhostZoneTypesPresent() & AVT_BOUNDARY_GHOST_ZONES; doPostGhost = doPostGhost && in_ds->GetCellData()->GetArray("avtGhostZones") && created_ghosts; debug5 << "avtMatvfExpression: GetGhostZoneTypesPresent() = " << datts.GetGhostZoneTypesPresent() << endl; debug5 << "avtMatvfExpression: Using post ghost material object ? " << doPostGhost << endl; avtMaterial *mat = GetMetaData()->GetMaterial(currentDomainsIndex, currentTimeState, doPostGhost); if (mat == NULL) { debug1 << "Could not find a material object." << endl; vtkDoubleArray *dummy = vtkDoubleArray::New(); dummy->SetNumberOfTuples(ncells); for (i = 0 ; i < ncells ; i++) dummy->SetTuple1(i, 0.); return dummy; } // // Note that we are setting up vf_for_orig_cells based on the number of // zones in the original dataset -- this may or may not be the number // of cells in the input, depending on whether or not we did MIR. // vtkDoubleArray *vf_for_orig_cells = vtkDoubleArray::New(); int norigcells = mat->GetNZones(); vf_for_orig_cells->SetNumberOfTuples(norigcells); // // Try to match up the materials in the avtMaterial object with the // materials requested by the users. // int nmats = mat->GetNMaterials(); std::vector<bool> useMat(nmats, false); std::vector<bool> matchedMatName(matNames.size(), false); std::vector<bool> matchedMatIndex(matIndices.size(), false); for (i = 0 ; i < nmats ; i++) { std::string currentMat = mat->GetMaterials()[i]; for (j = 0 ; j < matNames.size() ; j++) { if (currentMat == matNames[j]) { useMat[i] = true; matchedMatName[j] = true; } } for (j = 0 ; j < matIndices.size() ; j++) { char tmp[256]; sprintf(tmp, "%d", matIndices[j]); std::string matname(tmp); if (currentMat == matname || (currentMat.length() > matname.length() && currentMat.substr(0,matname.length() + 1) == (matname + " "))) { useMat[i] = true; matchedMatIndex[j] = true; } } } // // Make sure that we found every material requested. If not, issue // a warning. // for (i = 0 ; i < matNames.size() ; i++) { if (!matchedMatName[i]) { const std::vector<std::string> &all_mats = mat->GetCompleteMaterialList(); bool matched = false; for (j = 0 ; j < all_mats.size() ; j++) { if (matNames[i] == all_mats[j]) { matched = true; break; } } if (!matched) { if (!issuedWarning) { char warningString[100000]; sprintf(warningString, "Could not match up \"%s\" with " "any materials when doing the matvf expression." "\nList of valid materials is: ", matNames[i].c_str()); char *tmp = warningString + strlen(warningString); for (j = 0 ; j < all_mats.size() ; j++) { if (j < (all_mats.size()-1)) sprintf(tmp, "\"%s\", ", all_mats[j].c_str()); else sprintf(tmp, "\"%s\".", all_mats[j].c_str()); tmp += strlen(tmp); } avtCallback::IssueWarning(warningString); issuedWarning = true; } } } } for (i = 0 ; i < matIndices.size() ; i++) { char tmp[256]; sprintf(tmp, "%d", matIndices[i]); std::string matname(tmp); if (!matchedMatIndex[i]) { const std::vector<std::string> &all_mats = mat->GetCompleteMaterialList(); bool matched = false; for (j = 0 ; j < all_mats.size() ; j++) { if (matname == all_mats[j]) { matched = true; break; } } if (!matched) { if (!issuedWarning) { char warningString[100000]; sprintf(warningString, "Could not match up \"%s\" with " "any materials when doing the matvf expression." "\nList of valid materials is: ", matname.c_str()); char *tmp = warningString + strlen(warningString); for (j = 0 ; j < all_mats.size() ; j++) { if (j < (all_mats.size()-1)) sprintf(tmp, "\"%s\", ", all_mats[j].c_str()); else sprintf(tmp, "\"%s\".", all_mats[j].c_str()); tmp += strlen(tmp); } avtCallback::IssueWarning(warningString); issuedWarning = true; } } } } // // Walk through the material data structure and calculate the volume // fraction for each cell. // const int *matlist = mat->GetMatlist(); const int *mixmat = mat->GetMixMat(); const float *mixvf = mat->GetMixVF(); const int *mix_next = mat->GetMixNext(); for (i = 0 ; i < norigcells ; i++) { double vf = 0.; if (matlist[i] >= 0) { vf = (useMat[matlist[i]] ? 1. : 0.); } else { vf = 0.; int current = -matlist[i]-1; // iterations < 1000 just to prevent infinite loops if someone // set this structure up wrong. int iterations = 0; bool stillMoreMats = true; while (stillMoreMats && (iterations < 1000)) { if (useMat[mixmat[current]]) { vf += mixvf[current]; } if (mix_next[current] == 0) stillMoreMats = false; else current = mix_next[current]-1; iterations++; } } vf_for_orig_cells->SetTuple1(i, vf); } bool zonesMatchMaterialObject = GetInput()->GetInfo().GetValidity(). GetZonesPreserved(); vtkDoubleArray *rv = NULL; if (zonesMatchMaterialObject) { // // We have the volume fractions for the original cells and we are // operating on the original cells -- we're done. // rv = vf_for_orig_cells; rv->Register(NULL); // Because vf_for_orig_cells will be deleted later. // Sanity check. if (norigcells != ncells) EXCEPTION0(ImproperUseException); } else { // // We have the volume fractions for the original cells, but the // original cells have been modified -- most likely by MIR. Use // their original indexing to determine the volume fractions. // rv = vtkDoubleArray::New(); rv->SetNumberOfTuples(ncells); vtkUnsignedIntArray *ids = (vtkUnsignedIntArray *) in_ds->GetCellData()->GetArray("avtOriginalCellNumbers"); if (ids == NULL) { EXCEPTION0(ImproperUseException); } int ncomps = ids->GetNumberOfComponents(); unsigned int *ptr = ids->GetPointer(0); for (i = 0 ; i < ncells ; i++) { // // The id's are poorly arranged. There may be one or two // components -- always with zones, sometimes with domains. // The zones are always the last --> ncomps-1 st component. // unsigned int id = ptr[ncomps*i + (ncomps-1)]; rv->SetTuple1(i, vf_for_orig_cells->GetTuple1(id)); } } // This was essentially a temporary for us. vf_for_orig_cells->Delete(); return rv; }