void StructuredVolume::getVolumeFromMemory() { //! Create the equivalent ISPC volume container and allocate memory for voxel data. createEquivalentISPC(); //! Get a pointer to the source voxel data. const Data *voxelData = getParamData("voxelData", NULL); exitOnCondition(voxelData == NULL, "no voxel data specified"); const uint8 *data = (const uint8 *) voxelData->data; //! The dimensions of the source voxel data and target volume must match. exitOnCondition(size_t(volumeDimensions.x) * volumeDimensions.y * volumeDimensions.z != voxelData->numItems, "unexpected source voxel data dimensions"); //! The source and target voxel types must match. exitOnCondition(getVoxelType() != voxelData->type, "unexpected source voxel type"); //! Size of a volume slice in bytes. size_t sliceSizeInBytes = volumeDimensions.x * volumeDimensions.y * getVoxelSizeInBytes(); //! Copy voxel data into the volume in slices to avoid overflow in ISPC offset calculations. for (size_t z=0 ; z < volumeDimensions.z ; z++) setRegion(&data[z * sliceSizeInBytes], vec3i(0, 0, z), vec3i(volumeDimensions.x, volumeDimensions.y, 1)); }
void GhostBlockBrickedVolume::createEquivalentISPC() { // Get the voxel type. voxelType = getParamString("voxelType", "unspecified"); exitOnCondition(getVoxelType() == OSP_UNKNOWN, "unrecognized voxel type (must be set before calling " "ospSetRegion())"); // Get the volume dimensions. this->dimensions = getParam3i("dimensions", vec3i(0)); exitOnCondition(reduce_min(this->dimensions) <= 0, "invalid volume dimensions (must be set before calling " "ospSetRegion())"); // Create an ISPC GhostBlockBrickedVolume object and assign type-specific // function pointers. ispcEquivalent = ispc::GBBV_createInstance(this, (int)getVoxelType(), (const ispc::vec3i &)this->dimensions); }
void BlockBrickedVolume::createEquivalentISPC() { //! Get the voxel type. voxelType = getParamString("voxelType", "unspecified"); exitOnCondition(getVoxelType() == OSP_UNKNOWN, "unrecognized voxel type"); //! Create an ISPC BlockBrickedVolume object and assign type-specific function pointers. ispcEquivalent = ispc::BlockBrickedVolume_createInstance((int) getVoxelType()); //! Get the volume dimensions. volumeDimensions = getParam3i("dimensions", vec3i(0)); exitOnCondition(reduce_min(volumeDimensions) <= 0, "invalid volume dimensions"); //! Get the transfer function. transferFunction = (TransferFunction *) getParamObject("transferFunction", NULL); exitOnCondition(transferFunction == NULL, "no transfer function specified"); //! Get the value range. //! Voxel range not used for now. // vec2f voxelRange = getParam2f("voxelRange", vec2f(0.0f)); exitOnCondition(voxelRange == vec2f(0.0f), "no voxel range specified"); //! Get the gamma correction coefficient and exponent. vec2f gammaCorrection = getParam2f("gammaCorrection", vec2f(1.0f)); //! Set the volume dimensions. ispc::BlockBrickedVolume_setVolumeDimensions(ispcEquivalent, (const ispc::vec3i &) volumeDimensions); //! Set the value range (must occur before setting the transfer function). //ispc::BlockBrickedVolume_setValueRange(ispcEquivalent, (const ispc::vec2f &) voxelRange); //! Set the transfer function. ispc::BlockBrickedVolume_setTransferFunction(ispcEquivalent, transferFunction->getEquivalentISPC()); //! Set the recommended sampling rate for ray casting based renderers. ispc::BlockBrickedVolume_setSamplingRate(ispcEquivalent, getParam1f("samplingRate", 1.0f)); //! Set the gamma correction coefficient and exponent. ispc::BlockBrickedVolume_setGammaCorrection(ispcEquivalent, (const ispc::vec2f &) gammaCorrection); //! Allocate memory for the voxel data in the ISPC object. ispc::BlockBrickedVolume_allocateMemory(ispcEquivalent); }
//! Allocate storage and populate the volume. void AMRVolume::commit() { updateEditableParameters(); // Make the voxel value range visible to the application. if (findParam("voxelRange") == nullptr) setParam("voxelRange", voxelRange); else voxelRange = getParam2f("voxelRange", voxelRange); auto methodStringFromEnv = utility::getEnvVar<std::string>("OSPRAY_AMR_METHOD"); std::string methodString = methodStringFromEnv.value_or(getParamString("amrMethod","current")); if (methodString == "finest" || methodString == "finestLevel") ispc::AMR_install_finest(getIE()); else if (methodString == "current" || methodString == "currentLevel") ispc::AMR_install_current(getIE()); else if (methodString == "octant") ispc::AMR_install_octant(getIE()); if (data != nullptr) //TODO: support data updates return; brickInfoData = getParamData("brickInfo"); assert(brickInfoData); assert(brickInfoData->data); brickDataData = getParamData("brickData"); assert(brickDataData); assert(brickDataData->data); data = make_unique<amr::AMRData>(*brickInfoData,*brickDataData); accel = make_unique<amr::AMRAccel>(*data); // finding coarset cell size + finest level cell width float coarsestCellWidth = 0.f; float finestLevelCellWidth = data->brick[0].cellWidth; box3i rootLevelBox = empty; for (auto &b : data->brick) { if (b.level == 0) rootLevelBox.extend(b.box); finestLevelCellWidth = min(finestLevelCellWidth, b.cellWidth); coarsestCellWidth = max(coarsestCellWidth, b.cellWidth); } vec3i rootGridDims = rootLevelBox.size() + vec3i(1); ospLogF(1) << "found root level dimensions of " << rootGridDims; ospLogF(1) << "coarsest cell width is " << coarsestCellWidth << std::endl; auto rateFromEnv = utility::getEnvVar<float>("OSPRAY_AMR_SAMPLING_STEP"); float samplingStep = rateFromEnv.value_or(0.1f * coarsestCellWidth); box3f worldBounds = accel->worldBounds; const vec3f gridSpacing = getParam3f("gridSpacing", vec3f(1.f)); const vec3f gridOrigin = getParam3f("gridOrigin", vec3f(0.f)); voxelType = getParamString("voxelType", "unspecified"); auto voxelTypeID = getVoxelType(); switch (voxelTypeID) { case OSP_UCHAR: break; case OSP_SHORT: break; case OSP_USHORT: break; case OSP_FLOAT: break; case OSP_DOUBLE: break; default: throw std::runtime_error("amrVolume unsupported voxel type '" + voxelType + "'"); } ispc::AMRVolume_set(getIE(), (ispc::box3f&)worldBounds, samplingStep, (const ispc::vec3f&)gridOrigin, (const ispc::vec3f&)gridSpacing); ispc::AMRVolume_setAMR(getIE(), accel->node.size(), &accel->node[0], accel->leaf.size(), &accel->leaf[0], accel->level.size(), &accel->level[0], voxelTypeID, (ispc::box3f &)worldBounds); tasking::parallel_for(accel->leaf.size(),[&](size_t leafID) { ispc::AMRVolume_computeValueRangeOfLeaf(getIE(), leafID); }); }