void TExternalProgramFx::initialize(std::string name) { TFilePath fp = getExternFxPath() + (name + ".xml"); TIStream is(fp); if (!is) return; std::string tagName; if (!is.matchTag(tagName) || tagName != "externFx") return; try { while (is.matchTag(tagName)) { if (tagName == "executable") { TFilePath executable = TFilePath(is.getTagAttribute("path")); std::string args = is.getTagAttribute("args"); if (executable == TFilePath()) throw TException("missing executable path"); if (args == "") throw TException("missing args string"); setExecutable(executable, args); } else if (tagName == "inport" || tagName == "outport") { std::string portName = is.getTagAttribute("name"); std::string ext = is.getTagAttribute("ext"); if (portName == "") throw TException("missing port name"); if (ext == "") throw TException("missing port ext"); addPort(portName, ext, tagName == "inport"); } else if (tagName == "param") { std::string paramName = is.getTagAttribute("name"); if (paramName == "") throw TException("missing param name"); std::string type = is.getTagAttribute("type"); if (type == "") throw TException("missing param type"); if (type != "double") throw TException("param type not yet implemented"); TDoubleParamP param = new TDoubleParam(); param->setName(paramName); m_params.push_back(param); } else throw TException("unexpected tag " + tagName); } is.closeChild(); for (int i = 0; i < (int)m_params.size(); i++) bindParam(this, m_params[i]->getName(), m_params[i]); } catch (...) { } }
DirectionalBlurBaseFx(bool isMotionBLur) : m_isMotionBlur(isMotionBLur), m_angle(0.0), m_intensity(10.0), m_bidirectional(false), m_spread(true) { bindParam(this, "intensity", m_intensity); bindParam(this, "bidirectional", m_bidirectional); bindParam(this, "spread", m_spread); addInputPort("Source", m_input); m_intensity->setValueRange(0, (std::numeric_limits<double>::max)()); getAttributes()->setIsSpeedAware(true); }
void FxGadget::setValue(const TDoubleParamP ¶m, double value) { param->setValue(m_controller->getCurrentFrame(), value); }
double FxGadget::getValue(const TDoubleParamP ¶m) const { return param->getValue(m_controller->getCurrentFrame()); }
void FxGadget::addParam(const TDoubleParamP ¶m) { m_params.push_back(param); param->addObserver(this); }
bool canHandle(const TRenderSettings &info, double frame) { return isAlmostIsotropic(info.m_affine) || m_intensity->getValue(frame) == 0; }
TPointD getBlurVector(double frame) const { TPointD speed = getAttributes()->getSpeed(); double value = m_intensity->getValue(frame); return value * speed; }
void TExternalProgramFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri) { TRaster32P ras = tile.getRaster(); if (!ras) return; std::string args = m_args; std::string executablePath = ::to_string(m_executablePath); std::map<std::string, TFilePath> tmpFiles; // portname --> file TFilePath outputTmpFile; std::map<std::string, Port>::const_iterator portIt; for (portIt = m_ports.begin(); portIt != m_ports.end(); ++portIt) { TFilePath fp = TSystem::getUniqueFile("externfx"); fp = fp.withType(portIt->second.m_ext); tmpFiles[portIt->first] = fp; if (portIt->second.m_port == 0) // solo una porta e' di output outputTmpFile = fp; else { TRasterFxPort *tmp; tmp = portIt->second.m_port; if (tmp->isConnected()) { (*tmp)->compute(tile, frame, ri); TImageWriter::save(fp, ras); } } } // args e' della forma "$src $ctrl -o $out -v $value" // sostituisco le variabili int i = 0; for (;;) { i = args.find('$', i); if (i == (int)std::string::npos) break; int j = i + 1; int len = args.length(); while (j < len && isalnum(args[j])) j++; // un '$' non seguito da caratteri alfanumerici va ignorato if (j == i + 1) { // la sequenza '$$' diventa '$' if (j < len && args[j] == '$') args.replace(i, 2, "$"); i++; continue; } // ho trovato una variabile int m = j - i - 1; std::string name = args.substr(i + 1, m); // calcolo il valore. std::string value; std::map<std::string, TFilePath>::const_iterator it; it = tmpFiles.find(name); if (it != tmpFiles.end()) { // e' una porta. il valore e' il nome del // file temporaneo value = "\"" + ::to_string(it->second.getWideString()) + "\""; } else { // e' un parametro // se il nome non viene riconosciuto sostituisco la stringa nulla TDoubleParamP param = TParamP(getParams()->getParam(name)); if (param) value = std::to_string(param->getValue(frame)); } args.replace(i, m + 1, value); } args = " " + args; // aggiungo uno spazio per sicurezza // ofstream os("C:\\temp\\butta.txt"); // os << args << endl; // bisognerebbe calcolare le immagini dalla/e porta/e di input // scrivere il/i valore/i nei files temporanei/o // chiamare "m_executablePath args" // e leggere l'immagine scritta in outputTmpFile // poi cancellare tutto std::string expandedargs; char buffer[1024]; #ifdef _WIN32 ExpandEnvironmentStrings(args.c_str(), buffer, 1024); STARTUPINFO si; PROCESS_INFORMATION pinfo; GetStartupInfo(&si); BOOL ret = CreateProcess( (char *)executablePath.c_str(), // name of executable module buffer, // command line string NULL, // SD NULL, // SD TRUE, // handle inheritance option CREATE_NO_WINDOW, /*CREATE_NEW_CONSOLE*/ // creation flags NULL, // new environment block NULL, // current directory name &si, // startup information &pinfo // process information ); if (!ret) DWORD err = GetLastError(); // aspetta che il processo termini WaitForSingleObject(pinfo.hProcess, INFINITE); DWORD exitCode; ret = GetExitCodeProcess(pinfo.hProcess, // handle to the process &exitCode); // termination status #else std::string cmdline = executablePath + buffer; // int exitCode = system(cmdline.c_str()); #endif /* string name = m_executablePath.getName(); TPixel32 color; if(name == "saturate") color = TPixel32::Magenta; else if(name == "over") color = TPixel32::Green; else color = TPixel32::Red; for(int iy=0;iy<ras->getLy();iy++) { TPixel32 *pix = ras->pixels(iy); TPixel32 *endPix = pix + ras->getLx(); double x = tile.m_pos.x; double y = tile.m_pos.y + iy; while(pix<endPix) { if(x*x+y*y<900) *pix = color; else *pix = TPixel32(0,0,0,0); ++pix; x+=1.0; } } */ try { TRasterP ras = tile.getRaster(); TImageReader::load(outputTmpFile, ras); } catch (...) { } // butto i file temporanei creati std::map<std::string, TFilePath>::const_iterator fileIt; for (fileIt = tmpFiles.begin(); fileIt != tmpFiles.end(); ++fileIt) { if (TFileStatus(fileIt->second).doesExist() == true) try { TSystem::deleteFile(fileIt->second); } catch (...) { } } if (TFileStatus(outputTmpFile).doesExist() == true) try { TSystem::deleteFile(outputTmpFile); } catch (...) { } }
void FreeDistortBaseFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri) { if (!m_input.isConnected()) return; //Upon deactivation, this fx does nothing. if (m_deactivate->getValue()) { m_input->compute(tile, frame, ri); return; } //Get the source quad TPointD p00_b = m_p00_b->getValue(frame); TPointD p10_b = m_p10_b->getValue(frame); TPointD p01_b = m_p01_b->getValue(frame); TPointD p11_b = m_p11_b->getValue(frame); //Get destination quad TPointD p00_a = m_p00_a->getValue(frame); TPointD p10_a = m_p10_a->getValue(frame); TPointD p01_a = m_p01_a->getValue(frame); TPointD p11_a = m_p11_a->getValue(frame); if (m_isCastShadow) { //Shadows are mirrored tswap(p00_a, p01_a); tswap(p10_a, p11_a); } //Get requested tile's geometry TRasterP tileRas(tile.getRaster()); TRectD tileRect(convert(tileRas->getBounds()) + tile.m_pos); //Call transform to get the minimal rectOnInput TRectD inRect; TRenderSettings riNew; TRectD inBBox; safeTransform(frame, 0, tileRect, ri, inRect, riNew, inBBox); //Intersect with the bbox inRect *= inBBox; if (myIsEmpty(inRect)) return; double scale = ri.m_affine.a11; double downBlur = m_downBlur->getValue(frame) * scale; double upBlur = m_upBlur->getValue(frame) * scale; int brad = tceil(tmax(downBlur, upBlur)); inRect = inRect.enlarge(brad); TDimension inRectSize(tceil(inRect.getLx()), tceil(inRect.getLy())); TTile inTile; m_input->allocateAndCompute(inTile, inRect.getP00(), inRectSize, tileRas, frame, riNew); TPointD inTilePosRi = inTile.m_pos; //Update quads by the scale factors p00_b = riNew.m_affine * p00_b; p10_b = riNew.m_affine * p10_b; p01_b = riNew.m_affine * p01_b; p11_b = riNew.m_affine * p11_b; p00_a = ri.m_affine * p00_a; p10_a = ri.m_affine * p10_a; p01_a = ri.m_affine * p01_a; p11_a = ri.m_affine * p11_a; PerspectiveDistorter perpDistorter( p00_b - inTile.m_pos, p10_b - inTile.m_pos, p01_b - inTile.m_pos, p11_b - inTile.m_pos, p00_a, p10_a, p01_a, p11_a); BilinearDistorter bilDistorter( p00_b - inTile.m_pos, p10_b - inTile.m_pos, p01_b - inTile.m_pos, p11_b - inTile.m_pos, p00_a, p10_a, p01_a, p11_a); TQuadDistorter *distorter; if (m_distortType->getValue() == PERSPECTIVE) distorter = &perpDistorter; else if (m_distortType->getValue() == BILINEAR) distorter = &bilDistorter; else assert(0); if (m_isCastShadow) { TRaster32P ras32 = inTile.getRaster(); TRaster64P ras64 = inTile.getRaster(); if (ras32) { if (m_fade->getValue(frame) > 0) doFade(ras32, m_color->getValue(frame), m_fade->getValue(frame) / 100.0); if (brad > 0) doBlur(ras32, upBlur, downBlur, m_upTransp->getValue(frame) / 100.0, m_downTransp->getValue(frame) / 100.0, inBBox.y0 - inTile.m_pos.y, inBBox.y1 - inTile.m_pos.y); else if (m_upTransp->getValue(frame) > 0 || m_downTransp->getValue(frame) > 0) doTransparency(ras32, m_upTransp->getValue(frame) / 100.0, m_downTransp->getValue(frame) / 100.0, inBBox.y0 - inTile.m_pos.y, inBBox.y1 - inTile.m_pos.y); } else if (ras64) { if (m_fade->getValue(frame) > 0) doFade(ras64, toPixel64(m_color->getValue(frame)), m_fade->getValue(frame) / 100.0); if (brad > 0) doBlur(ras64, upBlur, downBlur, m_upTransp->getValue(frame) / 100.0, m_downTransp->getValue(frame) / 100.0, inBBox.y0 - inTile.m_pos.y, inBBox.y1 - inTile.m_pos.y); else if (m_upTransp->getValue(frame) > 0 || m_downTransp->getValue(frame) > 0) doTransparency(ras64, m_upTransp->getValue(frame) / 100.0, m_downTransp->getValue(frame) / 100.0, inBBox.y0 - inTile.m_pos.y, inBBox.y1 - inTile.m_pos.y); } else assert(false); } distort(tileRas, inTile.getRaster(), *distorter, convert(tile.m_pos), TRop::Bilinear); }