void Model::commit() { useEmbreeDynamicSceneFlag = getParam<int>("dynamicScene", 0); useEmbreeCompactSceneFlag = getParam<int>("compactMode", 0); useEmbreeRobustSceneFlag = getParam<int>("robustMode", 0); postStatusMsg(2) << "=======================================================\n" << "Finalizing model, has " << geometry.size() << " geometries and " << volume.size() << " volumes"; RTCDevice embreeDevice = (RTCDevice)ospray_getEmbreeDevice(); int sceneFlags = 0; sceneFlags = sceneFlags | (useEmbreeDynamicSceneFlag ? RTC_SCENE_FLAG_DYNAMIC : 0); sceneFlags = sceneFlags | (useEmbreeCompactSceneFlag ? RTC_SCENE_FLAG_COMPACT : 0); sceneFlags = sceneFlags | (useEmbreeRobustSceneFlag ? RTC_SCENE_FLAG_ROBUST : 0); ispc::Model_init(getIE(), embreeDevice, sceneFlags, geometry.size(), volume.size()); embreeSceneHandle = (RTCScene)ispc::Model_getEmbreeSceneHandle(getIE()); bounds = empty; for (size_t i = 0; i < geometry.size(); i++) { postStatusMsg(2) << "=======================================================\n" << "Finalizing geometry " << i; geometry[i]->finalize(this); bounds.extend(geometry[i]->bounds); ispc::Model_setGeometry(getIE(), i, geometry[i]->getIE()); } for (size_t i=0; i<volume.size(); i++) ispc::Model_setVolume(getIE(), i, volume[i]->getIE()); rtcCommitScene(embreeSceneHandle); }
//! \brief commit the material's parameters virtual void commit() override { if (getIE() == nullptr) ispcEquivalent = ispc::PathTracer_OBJ_create(); Texture2D *map_d = (Texture2D*)getParamObject("map_d"); affine2f xform_d = getTextureTransform("map_d"); Texture2D *map_Kd = (Texture2D*)getParamObject("map_Kd", getParamObject("map_kd", getParamObject("colorMap"))); affine2f xform_Kd = getTextureTransform("map_Kd") * getTextureTransform("map_kd") * getTextureTransform("colorMap"); Texture2D *map_Ks = (Texture2D*)getParamObject("map_Ks", getParamObject("map_ks")); affine2f xform_Ks = getTextureTransform("map_Ks") * getTextureTransform("map_ks"); Texture2D *map_Ns = (Texture2D*)getParamObject("map_Ns", getParamObject("map_ns")); affine2f xform_Ns = getTextureTransform("map_Ns") * getTextureTransform("map_ns"); Texture2D *map_Bump = (Texture2D*)getParamObject("map_Bump", getParamObject("map_bump", getParamObject("normalMap", getParamObject("bumpMap")))); affine2f xform_Bump = getTextureTransform("map_Bump") * getTextureTransform("map_bump") * getTextureTransform("normalMap") * getTextureTransform("BumpMap"); linear2f rot_Bump = xform_Bump.l.orthogonal().transposed(); const float d = getParam1f("d", getParam1f("alpha", 1.f)); vec3f Kd = getParam3f("Kd", getParam3f("kd", getParam3f("color", vec3f(0.8f)))); vec3f Ks = getParam3f("Ks", getParam3f("ks", vec3f(0.f))); const float Ns = getParam1f("Ns", getParam1f("ns", 10.f)); vec3f Tf = getParam3f("Tf", getParam3f("tf", vec3f(0.0f))); const float color_total = reduce_max(Kd + Ks + Tf); if (color_total > 1.0) { postStatusMsg() << "#osp:PT: warning: OBJ material produces energy " << "(Kd + Ks + Tf = " << color_total << ", should be <= 1). Scaling down to 1."; Kd /= color_total; Ks /= color_total; Tf /= color_total; } ispc::PathTracer_OBJ_set(ispcEquivalent, map_d ? map_d->getIE() : nullptr, (const ispc::AffineSpace2f&)xform_d, d, map_Kd ? map_Kd->getIE() : nullptr, (const ispc::AffineSpace2f&)xform_Kd, (const ispc::vec3f&)Kd, map_Ks ? map_Ks->getIE() : nullptr, (const ispc::AffineSpace2f&)xform_Ks, (const ispc::vec3f&)Ks, map_Ns ? map_Ns->getIE() : nullptr, (const ispc::AffineSpace2f&)xform_Ns, Ns, (const ispc::vec3f&)Tf, map_Bump ? map_Bump->getIE() : nullptr, (const ispc::AffineSpace2f&)xform_Bump, (const ispc::LinearSpace2f&)rot_Bump); }
void PathTracer::generateGeometryLights(const Model *const model , const affine3f& xfm , float *const _areaPDF ) { for(size_t i = 0; i < model->geometry.size(); i++) { auto &geo = model->geometry[i]; // recurse instances Ref<Instance> inst = geo.dynamicCast<Instance>(); if (inst) { const affine3f instXfm = xfm * inst->xfm; generateGeometryLights(inst->instancedScene.ptr, instXfm, &(inst->areaPDF[0])); } else if (geo->materialList) { // check whether the geometry has any emissive materials bool hasEmissive = false; for (auto mat : geo->ispcMaterialPtrs) { if (mat && ispc::PathTraceMaterial_isEmissive(mat)) { hasEmissive = true; break; } } if (hasEmissive) { if (ispc::GeometryLight_isSupported(geo->getIE())) { const affine3f rcpXfm = rcp(xfm); void* light = ispc::GeometryLight_create(geo->getIE() , (const ispc::AffineSpace3f&)xfm , (const ispc::AffineSpace3f&)rcpXfm , _areaPDF+i); // check whether the geometry has any emissive primitives if (light) lightArray.push_back(light); } else { postStatusMsg(1) << "#osp:pt Geometry " << geo->toString() << " does not implement area sampling! " << "Cannot use importance sampling for that " << "geometry with emissive material!"; } } } } }
void MPIDistributedDevice::commit() { if (!initialized) { int _ac = 1; const char *_av[] = {"ospray_mpi_distributed_device"}; auto *setComm = static_cast<MPI_Comm*>(getParam<void*>("worldCommunicator", nullptr)); shouldFinalizeMPI = mpicommon::init(&_ac, _av, setComm == nullptr); if (setComm) { MPI_CALL(Comm_dup(*setComm, &mpicommon::world.comm)); MPI_CALL(Comm_rank(mpicommon::world.comm, &mpicommon::world.rank)); MPI_CALL(Comm_size(mpicommon::world.comm, &mpicommon::world.size)); } auto &embreeDevice = api::ISPCDevice::embreeDevice; embreeDevice = rtcNewDevice(generateEmbreeDeviceCfg(*this).c_str()); rtcSetDeviceErrorFunction(embreeDevice, embreeErrorFunc, nullptr); RTCError erc = rtcGetDeviceError(embreeDevice); if (erc != RTC_ERROR_NONE) { // why did the error function not get called !? postStatusMsg() << "#osp:init: embree internal error number " << erc; assert(erc == RTC_ERROR_NONE); } initialized = true; } Device::commit(); masterRank = getParam<int>("masterRank", 0); TiledLoadBalancer::instance = make_unique<staticLoadBalancer::Distributed>(); }
void DistributedModel::commit() { othersRegions.clear(); // TODO: We may need to override the ISPC calls made // to the Model or customize the model struct on the ISPC // side. In which case we need some ISPC side inheritence // for the model type. Currently the code is actually identical. Model::commit(); // Send my bounding boxes to other nodes, recieve theirs for a // "full picture" of what geometries live on what nodes Data *regionData = getParamData("regions"); Data *ghostRegionData = getParamData("ghostRegions"); // The box3f data is sent as data of FLOAT3 items // TODO: It's a little awkward to copy the boxes again like this, maybe // can re-thinkg the send side of the bcast call? One that takes // a ptr and a size since we know we won't be writing out to it? // TODO: For now it doesn't matter that we don't know who owns the // other boxes, just that we know they exist and their bounds, and that // they aren't ours. if (regionData) { box3f *boxes = reinterpret_cast<box3f*>(regionData->data); myRegions = std::vector<box3f>(boxes, boxes + regionData->numItems / 2); } // If the user hasn't set any regions, there's an implicit infinitely // large region box we can place around the entire world. if (myRegions.empty()) { postStatusMsg("No regions found, making implicit " "infinitely large region", 1); myRegions.push_back(box3f(vec3f(neg_inf), vec3f(pos_inf))); } // Check if we've got ghost regions set, otherwise just use the regions if (ghostRegionData) { box3f *boxes = reinterpret_cast<box3f*>(ghostRegionData->data); ghostRegions = std::vector<box3f>(boxes, boxes + ghostRegionData->numItems / 2); } else { ghostRegions = myRegions; } for (int i = 0; i < mpicommon::numGlobalRanks(); ++i) { if (i == mpicommon::globalRank()) { messaging::bcast(i, myRegions); } else { std::vector<box3f> recv; messaging::bcast(i, recv); std::copy(recv.begin(), recv.end(), std::back_inserter(othersRegions)); } } if (logLevel() >= 1) { for (int i = 0; i < mpicommon::numGlobalRanks(); ++i) { if (i == mpicommon::globalRank()) { postStatusMsg(1) << "Rank " << mpicommon::globalRank() << ": Got regions from others {"; for (const auto &b : othersRegions) { postStatusMsg(1) << "\t" << b << ","; } postStatusMsg(1) << "}"; } } } }
static void embreeErrorFunc(void *, const RTCError code, const char* str) { postStatusMsg() << "#osp: embree internal error " << code << " : " << str; throw std::runtime_error("embree internal error '" +std::string(str)+"'"); }