void SimulationAnimationPatch::update(set<Device *> devices, IsUpdateRequiredFunction isUpdateRequired, InterruptFunction interruptRender, ClearUpdateFlagsFunction clearUpdateFlags) { // Doesn't respond if it's stopped. if (m_mode == SimulationAnimationMode::STOPPED) return ; FrameDeviceInfo frame; // Fulls time and mode for frame info. createFrameInfoHeader(frame); // Checks if an update is needed. bool rerender_req = isUpdateRequired(devices); // There's no need to send this frame if (!rerender_req) return ; createFrameInfoBody(devices, frame); std::stringstream ss; ss << "Sent new frame: " << frame.time << "(" << frame.mode << ")"; Logger::log(LDEBUG, ss.str()); // Interrupts the current rendering if in the interactive mode. if (m_mode == SimulationAnimationMode::INTERACTIVE || m_mode == SimulationAnimationMode::RECORDING) { interruptRender(); } // Enqueues. enqueueFrameInfo(frame); // A flag cleared means the task has been indeed inserted clearUpdateFlags(); }
void ArnoldAnimationPatch::renderSingleFrameToBuffer(const set<Device*>& devices, unsigned char* buff, int w, int h) { if (m_mode != SimulationAnimationMode::STOPPED) disableContinuousRenderMode(); FrameDeviceInfo frame; // Fulls time and mode for frame info. createFrameInfoHeader(frame); createFrameInfoBody(devices, frame, true); std::stringstream ss; ss << "Rendering single frame: " << frame.time; Logger::log(LDEBUG, ss.str()); // Interrupts the current rendering if in the interactive mode. if (m_mode == SimulationAnimationMode::INTERACTIVE || m_mode == SimulationAnimationMode::RECORDING) { interruptRender(); } // Render immediately. if (!m_interface->isDistributedOpen()) { m_interface->init(this->toJSON()); // Check if we were able to open a connection if (!m_interface->isDistributedOpen()) { std::cerr << "Connection could not be established. " << "Check to make sure your host and port " << "parameters are correct and that nobody " << "else is currently using the remote renderer" << std::endl; return; } } bool success = false; float* bp = nullptr; int cid; if (CachingArnoldInterface* ci = dynamic_cast<CachingArnoldInterface*>(m_interface)) { #ifdef USE_ARNOLD success = ci->render(devices, w, h, cid) == AI_SUCCESS; #else success = ci->render(devices, w, h, cid) == 0; #endif // we need to pull the proper buffer from the right context bp = ci->getBufferForContext(cid); frame.clear(); } else { updateLight(devices); success = ArnoldPatch::renderLoop(devices); frame.clear(); bp = getBufferPointer(); } if (success) { for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { int offset = (j * w + i) * 4; // convert to bytes buff[offset] = static_cast<unsigned char>(bp[offset + 2] * 0xff); buff[offset + 1] = static_cast<unsigned char>(bp[offset + 1] * 0xff); buff[offset + 2] = static_cast<unsigned char>(bp[offset + 0] * 0xff); buff[offset + 3] = static_cast<unsigned char>(bp[offset + 3] * 0xff); } } } if (CachingArnoldInterface* ci = dynamic_cast<CachingArnoldInterface*>(m_interface)) { ci->closeContext(cid); } }
void ArnoldAnimationPatch::renderSingleFrame(const set<Device*>& devices, string basepath, string filename) { if (m_mode != SimulationAnimationMode::STOPPED) disableContinuousRenderMode(); FrameDeviceInfo frame; // Fulls time and mode for frame info. createFrameInfoHeader(frame); createFrameInfoBody(devices, frame); std::stringstream ss; ss << "Rendering single frame: " << frame.time; Logger::log(LDEBUG, ss.str()); // Interrupts the current rendering if in the interactive mode. if (m_mode == SimulationAnimationMode::INTERACTIVE || m_mode == SimulationAnimationMode::RECORDING) { interruptRender(); } // Render immediately. if (!m_interface->isDistributedOpen()) { m_interface->init(this->toJSON()); // Check if we were able to open a connection if (!m_interface->isDistributedOpen()) { std::cerr << "Connection could not be established. " << "Check to make sure your host and port " << "parameters are correct and that nobody " << "else is currently using the remote renderer" << std::endl; return; } } bool success = false; float* bp = nullptr; int cid; int w = getWidth(); int h = getHeight(); if (CachingArnoldInterface* ci = dynamic_cast<CachingArnoldInterface*>(m_interface)) { #ifdef USE_ARNOLD success = ci->render(devices, w, h, cid) == AI_SUCCESS; #else success = ci->render(devices, w, h, cid) == 0; #endif // we need to pull the proper buffer from the right context bp = ci->getBufferForContext(cid); frame.clear(); } else { updateLight(devices); success = ArnoldPatch::renderLoop(devices); frame.clear(); bp = getBufferPointer(); } if (success) { unsigned char *bytes = new unsigned char[w * h * 4]; floats_to_bytes(bytes, bp, w, h); string file = basepath + "/" + filename + ".png"; if (!imageio_save_image(file.c_str(), bytes, getWidth(), getHeight())) { std::stringstream err_ss; err_ss << "Error to write png: " << filename; Logger::log(ERR, err_ss.str()); } } if (CachingArnoldInterface* ci = dynamic_cast<CachingArnoldInterface*>(m_interface)) { ci->closeContext(cid); } }