void CameraTestTool::drawCleanupCamera(double pixelSize) { CleanupParameters *cp = CleanupSettingsModel::instance()->getCurrentParameters(); TRectD rect = cp->m_camera.getStageRect(); glColor3d(1.0, 0.0, 0.0); glLineStipple(1, 0xFFFF); glEnable(GL_LINE_STIPPLE); // box glBegin(GL_LINE_STRIP); glVertex2d(rect.x0, rect.y0); glVertex2d(rect.x0, rect.y1 - pixelSize); glVertex2d(rect.x1 - pixelSize, rect.y1 - pixelSize); glVertex2d(rect.x1 - pixelSize, rect.y0); glVertex2d(rect.x0, rect.y0); glEnd(); // central cross double dx = 0.05 * rect.getP00().x; double dy = 0.05 * rect.getP00().y; tglDrawSegment(TPointD(-dx, -dy), TPointD(dx, dy)); tglDrawSegment(TPointD(-dx, dy), TPointD(dx, -dy)); glDisable(GL_LINE_STIPPLE); // camera name TPointD pos = rect.getP01() + TPointD(0, 4); glPushMatrix(); glTranslated(pos.x, pos.y, 0); glScaled(2, 2, 2); tglDrawText(TPointD(), "Cleanup Camera"); glPopMatrix(); }
void tglFillRect(const TRectD &rect) { glBegin(GL_POLYGON); tglVertex(rect.getP00()); tglVertex(rect.getP10()); tglVertex(rect.getP11()); tglVertex(rect.getP01()); glEnd(); }
void tglDrawRect(const TRectD &rect) { glBegin(GL_LINE_LOOP); tglVertex(rect.getP00()); tglVertex(rect.getP10()); tglVertex(rect.getP11()); tglVertex(rect.getP01()); glEnd(); }
TRectD TAffine::operator*(const TRectD &rect) const { if (rect != TConsts::infiniteRectD) { TPointD p1 = *this * rect.getP00(), p2 = *this * rect.getP01(), p3 = *this * rect.getP10(), p4 = *this * rect.getP11(); return TRectD(tmin(p1.x, p2.x, p3.x, p4.x), tmin(p1.y, p2.y, p3.y, p4.y), tmax(p1.x, p2.x, p3.x, p4.x), tmax(p1.y, p2.y, p3.y, p4.y)); } else return TConsts::infiniteRectD; }
void get_render_enlarge(const double frame, const TAffine affine, TRectD &bBox) { TPointD center(this->get_render_center(frame, bBox.getP00(), affine)); int margin = this->get_render_int_margin(frame, bBox, affine, center); if (0 < margin) { /* 拡大のしすぎを防ぐテキトーな制限 */ if (4096 < margin) { margin = 4096; } bBox = bBox.enlarge(margin); } }
void ShiftTraceTool::drawControlRect() { if (m_ghostIndex < 0 || m_ghostIndex > 1) return; int row = m_row[m_ghostIndex]; if (row < 0) return; int col = TApp::instance()->getCurrentColumn()->getColumnIndex(); TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); TXshCell cell = xsh->getCell(row, col); if (cell.isEmpty()) return; TImageP img = cell.getImage(false); if (!img) return; TRectD box; if (TRasterImageP ri = img) { TRasterP ras = ri->getRaster(); box = (convert(ras->getBounds()) - ras->getCenterD()) * ri->getSubsampling(); } else if (TToonzImageP ti = img) { TRasterP ras = ti->getRaster(); box = (convert(ras->getBounds()) - ras->getCenterD()) * ti->getSubsampling(); } else if (TVectorImageP vi = img) { box = vi->getBBox(); } else { return; } glPushMatrix(); tglMultMatrix(getGhostAff()); TPixel32 color; color = m_highlightedGadget == TranslateGadget ? TPixel32(200, 100, 100) : TPixel32(120, 120, 120); tglColor(color); glBegin(GL_LINE_STRIP); glVertex2d(box.x0, box.y0); glVertex2d(box.x1, box.y0); glVertex2d(box.x1, box.y1); glVertex2d(box.x0, box.y1); glVertex2d(box.x0, box.y0); glEnd(); color = m_highlightedGadget == 2000 ? TPixel32(200, 100, 100) : TPixel32::White; double r = 4 * sqrt(tglGetPixelSize2()); drawDot(box.getP00(), r, color); drawDot(box.getP01(), r, color); drawDot(box.getP10(), r, color); drawDot(box.getP11(), r, color); if (m_curveStatus == NoCurve) { color = m_highlightedGadget == 2001 ? TPixel32(200, 100, 100) : TPixel32::White; TPointD c = m_center[m_ghostIndex]; drawDot(c, r, color); } glPopMatrix(); }
inline void buildLightRects(const TRectD &tileRect, TRectD &inRect, TRectD &outRect, double blur) { if (inRect != TConsts::infiniteRectD) // Could be, if the input light is a zerary Fx makeRectCoherent(inRect, tileRect.getP00()); int blurI = tceil(blur); // It seems that the TRop::blur does wrong with these (cuts at the borders). // I don't know why - they would be best... // TRectD blurOutRect((lightRect).enlarge(blurI) * tileRect); // lightRect = ((tileRect).enlarge(blurI) * lightRect); // So we revert to the sum of the two outRect = inRect = ((tileRect).enlarge(blurI) * inRect) + ((inRect).enlarge(blurI) * tileRect); }
/*-- Paste後のフローティング状態の画像の描画 --*/ void RasterSelectionTool::drawFloatingSelection() { double pixelSize = TTool::getApplication()->getCurrentTool()->getTool()->getPixelSize(); TAffine aff = m_rasterSelection.getTransformation(); glPushMatrix(); tglMultMatrix(aff); //draw m_floatingSelection if (isFloating()) { TRasterP floatingSelection = m_rasterSelection.getFloatingSelection(); TImageP app; if (TRasterCM32P toonzRas = (TRasterCM32P)(floatingSelection)) app = TToonzImageP(toonzRas, toonzRas->getBounds()); if (TRaster32P fullColorRas = (TRaster32P)(floatingSelection)) app = TRasterImageP(fullColorRas); if (TRasterGR8P grRas = (TRasterGR8P)(floatingSelection)) app = TRasterImageP(grRas); app->setPalette(m_rasterSelection.getCurrentImage()->getPalette()); FourPoints points = getBBox() * aff.inv(); TRectD bbox = points.getBox(); TPointD center((bbox.getP00() + bbox.getP11()) * 0.5); if (TToonzImageP ti = (TToonzImageP)app) GLRasterPainter::drawRaster(TTranslation(center), ti, false); if (TRasterImageP ri = (TRasterImageP)app) GLRasterPainter::drawRaster(TTranslation(center), ri, true); } std::vector<TStroke> strokes = m_rasterSelection.getStrokes(); int i; for (i = 0; i < (int)strokes.size(); i++) { TStroke stroke = strokes[i]; glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0xF0F0); tglColor(TPixel32::Black); drawStrokeCenterline(stroke, pixelSize); glDisable(GL_LINE_STIPPLE); } glPopMatrix(); }
void Particles_Engine::render_particles( TFlash *flash, TTile *tile, std::vector<TRasterFxPort *> part_ports, const TRenderSettings &ri, TDimension &p_size, TPointD &p_offset, std::map<int, TRasterFxPort *> ctrl_ports, std::vector<TLevelP> partLevel, float dpi, int curr_frame, int shrink, double startx, double starty, double endx, double endy, std::vector<int> last_frame, unsigned long fxId) { int frame, startframe, intpart = 0, level_n = 0; struct particles_values values; double dpicorr = dpi * 0.01, fractpart = 0, dpicorr_shrinked = 0, opacity_range = 0; bool random_level = false; level_n = part_ports.size(); bool isPrecomputingEnabled = false; { TRenderer renderer(TRenderer::instance()); isPrecomputingEnabled = (renderer && renderer.isPrecomputingEnabled()) ? true : false; } memset(&values, 0, sizeof(values)); /*- 現在のフレームでの各種パラメータを得る -*/ fill_value_struct(values, m_frame); /*- 不透明度の範囲(透明〜不透明を 0〜1 に正規化)-*/ opacity_range = (values.opacity_val.second - values.opacity_val.first) * 0.01; /*- 開始フレーム -*/ startframe = (int)values.startpos_val; if (values.unit_val == ParticlesFx::UNIT_SMALL_INCH) dpicorr_shrinked = dpicorr / shrink; else dpicorr_shrinked = dpi / shrink; std::map<std::pair<int, int>, double> partScales; curr_frame = curr_frame / values.step_val; ParticlesManager *pc = ParticlesManager::instance(); // Retrieve the last rolled frame ParticlesManager::FrameData *particlesData = pc->data(fxId); std::list<Particle> myParticles; TRandom myRandom; values.random_val = &myRandom; myRandom = m_parent->randseed_val->getValue(); int totalparticles = 0; int pcFrame = particlesData->m_frame; if (pcFrame > curr_frame) { // Clear stored particlesData particlesData->clear(); pcFrame = particlesData->m_frame; } else if (pcFrame >= startframe - 1) { myParticles = particlesData->m_particles; myRandom = particlesData->m_random; totalparticles = particlesData->m_totalParticles; } /*- スタートからカレントフレームまでループ -*/ for (frame = startframe - 1; frame <= curr_frame; ++frame) { int dist_frame = curr_frame - frame; /*- * ループ内の現在のフレームでのパラメータを取得。スタートが負ならフレーム=0のときの値を格納 * -*/ fill_value_struct(values, frame < 0 ? 0 : frame * values.step_val); /*- パラメータの正規化 -*/ normalize_values(values, ri); /*- maxnum_valは"birth_rate"のパラメータ -*/ intpart = (int)values.maxnum_val; /*- * /birth_rateが小数だったとき、各フレームの小数部分を足しこんだ結果の整数部分をintpartに渡す。 * -*/ fractpart = fractpart + values.maxnum_val - intpart; if ((int)fractpart) { values.maxnum_val += (int)fractpart; fractpart = fractpart - (int)fractpart; } std::map<int, TTile *> porttiles; // Perform the roll /*- RenderSettingsを複製して現在のフレームの計算用にする -*/ TRenderSettings riAux(ri); riAux.m_affine = TAffine(); riAux.m_bpp = 32; int r_frame; // Useful in case of negative roll frames if (frame < 0) r_frame = 0; else r_frame = frame; /*- 出力画像のバウンディングボックス -*/ TRectD outTileBBox(tile->m_pos, TDimensionD(tile->getRaster()->getLx(), tile->getRaster()->getLy())); /*- Controlに刺さっている各ポートについて -*/ for (std::map<int, TRasterFxPort *>::iterator it = ctrl_ports.begin(); it != ctrl_ports.end(); ++it) { TTile *tmp; /*- ポートが接続されていて、Fx内で実際に使用されていたら -*/ if ((it->second)->isConnected() && port_is_used(it->first, values)) { TRectD bbox; (*(it->second))->getBBox(r_frame, bbox, riAux); /*- 素材が存在する場合、portTilesにコントロール画像タイルを格納 -*/ if (!bbox.isEmpty()) { if (bbox == TConsts::infiniteRectD) // There could be an infinite // bbox - deal with it bbox = ri.m_affine.inv() * outTileBBox; if (frame <= pcFrame) { // This frame will not actually be rolled. However, it was // dryComputed - so, declare the same here. (*it->second)->dryCompute(bbox, r_frame, riAux); } else { tmp = new TTile; if (isPrecomputingEnabled) (*it->second) ->allocateAndCompute(*tmp, bbox.getP00(), convert(bbox).getSize(), 0, r_frame, riAux); else { std::string alias = "CTRL: " + (*(it->second))->getAlias(r_frame, riAux); TRasterImageP rimg = TImageCache::instance()->get(alias, false); if (rimg) { tmp->m_pos = bbox.getP00(); tmp->setRaster(rimg->getRaster()); } else { (*it->second) ->allocateAndCompute(*tmp, bbox.getP00(), convert(bbox).getSize(), 0, r_frame, riAux); addRenderCache(alias, TRasterImageP(tmp->getRaster())); } } porttiles[it->first] = tmp; } } } } if (frame > pcFrame) { // Invoke the actual rolling procedure roll_particles(tile, porttiles, riAux, myParticles, values, 0, 0, frame, curr_frame, level_n, &random_level, 1, last_frame, totalparticles); // Store the rolled data in the particles manager if (!particlesData->m_calculated || particlesData->m_frame + particlesData->m_maxTrail < frame) { particlesData->m_frame = frame; particlesData->m_particles = myParticles; particlesData->m_random = myRandom; particlesData->buildMaxTrail(); particlesData->m_calculated = true; particlesData->m_totalParticles = totalparticles; } } // Render the particles if the distance from current frame is a trail // multiple if (frame >= startframe - 1 && !(dist_frame % (values.trailstep_val > 1.0 ? (int)values.trailstep_val : 1))) { // Store the maximum particle size before the do_render cycle std::list<Particle>::iterator pt; for (pt = myParticles.begin(); pt != myParticles.end(); ++pt) { Particle &part = *pt; int ndx = part.frame % last_frame[part.level]; std::pair<int, int> ndxPair(part.level, ndx); std::map<std::pair<int, int>, double>::iterator it = partScales.find(ndxPair); if (it != partScales.end()) it->second = std::max(part.scale, it->second); else partScales[ndxPair] = part.scale; } if (values.toplayer_val == ParticlesFx::TOP_SMALLER || values.toplayer_val == ParticlesFx::TOP_BIGGER) myParticles.sort(ComparebySize()); if (values.toplayer_val == ParticlesFx::TOP_SMALLER) { std::list<Particle>::iterator pt; for (pt = myParticles.begin(); pt != myParticles.end(); ++pt) { Particle &part = *pt; if (dist_frame <= part.trail && part.scale && part.lifetime > 0 && part.lifetime <= part.genlifetime) // This last... shouldn't always be? { do_render(flash, &part, tile, part_ports, porttiles, ri, p_size, p_offset, last_frame[part.level], partLevel, values, opacity_range, dist_frame, partScales); } } } else { std::list<Particle>::reverse_iterator pt; for (pt = myParticles.rbegin(); pt != myParticles.rend(); ++pt) { Particle &part = *pt; if (dist_frame <= part.trail && part.scale && part.lifetime > 0 && part.lifetime <= part.genlifetime) // Same here..? { do_render(flash, &part, tile, part_ports, porttiles, ri, p_size, p_offset, last_frame[part.level], partLevel, values, opacity_range, dist_frame, partScales); } } } } std::map<int, TTile *>::iterator it; for (it = porttiles.begin(); it != porttiles.end(); ++it) delete it->second; } }
void doCompute(TTile &tile, double frame, const TRenderSettings &info) override { bool isWarped = m_warped.isConnected(); if (!isWarped) return; if (fabs(m_intensity->getValue(frame)) < 0.01) { m_warped->compute(tile, frame, info); return; } int shrink = (info.m_shrinkX + info.m_shrinkY) / 2; double scale = sqrt(fabs(info.m_affine.det())); double gridStep = 1.5 * m_gridStep->getValue(frame); WarpParams params; params.m_intensity = m_intensity->getValue(frame) / gridStep; params.m_warperScale = scale * gridStep; params.m_sharpen = m_sharpen->getValue(); params.m_shrink = shrink; double period = m_period->getValue(frame) / info.m_shrinkX; double count = m_count->getValue(frame); double cycle = m_cycle->getValue(frame) / info.m_shrinkX; double scaleX = m_scaleX->getValue(frame) / 100.0; double scaleY = m_scaleY->getValue(frame) / 100.0; double angle = -m_angle->getValue(frame); TPointD center = m_center->getValue(frame) * (1.0 / info.m_shrinkX); // The warper is calculated on a standard reference, with fixed dpi. This // makes sure // that the lattice created for the warp does not depend on camera // transforms and resolution. TRenderSettings warperInfo(info); double warperScaleFactor = 1.0 / params.m_warperScale; warperInfo.m_affine = TScale(warperScaleFactor) * info.m_affine; // Retrieve tile's geometry TRectD tileRect; { TRasterP tileRas = tile.getRaster(); tileRect = TRectD(tile.m_pos, TDimensionD(tileRas->getLx(), tileRas->getLy())); } // Build the compute rect TRectD warpedBox, warpedComputeRect, tileComputeRect; m_warped->getBBox(frame, warpedBox, info); getWarpComputeRects(tileComputeRect, warpedComputeRect, warpedBox, tileRect, params); if (tileComputeRect.getLx() <= 0 || tileComputeRect.getLy() <= 0) return; if (warpedComputeRect.getLx() <= 0 || warpedComputeRect.getLy() <= 0) return; TRectD warperComputeRect(TScale(warperScaleFactor) * tileComputeRect); double warperEnlargement = getWarperEnlargement(params); warperComputeRect = warperComputeRect.enlarge(warperEnlargement); warperComputeRect.x0 = tfloor(warperComputeRect.x0); warperComputeRect.y0 = tfloor(warperComputeRect.y0); warperComputeRect.x1 = tceil(warperComputeRect.x1); warperComputeRect.y1 = tceil(warperComputeRect.y1); // Compute the warped tile TTile tileIn; m_warped->allocateAndCompute( tileIn, warpedComputeRect.getP00(), TDimension(warpedComputeRect.getLx(), warpedComputeRect.getLy()), tile.getRaster(), frame, info); TRasterP rasIn = tileIn.getRaster(); // Compute the warper tile TSpectrum::ColorKey colors[] = {TSpectrum::ColorKey(0, TPixel32::White), TSpectrum::ColorKey(0.5, TPixel32::Black), TSpectrum::ColorKey(1, TPixel32::White)}; TSpectrumParamP ripplecolors = TSpectrumParamP(tArrayCount(colors), colors); // Build the multiradial warperInfo.m_affine = warperInfo.m_affine * TTranslation(center) * TRotation(angle) * TScale(scaleX, scaleY); TAffine aff = warperInfo.m_affine.inv(); TPointD posTrasf = aff * (warperComputeRect.getP00()); TRasterP rasWarper = rasIn->create(warperComputeRect.getLx(), warperComputeRect.getLy()); multiRadial(rasWarper, posTrasf, ripplecolors, period, count, cycle, aff, frame); // TImageWriter::save(TFilePath("C:\\ripple.tif"), rasWarper); // Warp TPointD db; TRect rasComputeRectI(convert(tileComputeRect - tileRect.getP00(), db)); TRasterP tileRas = tile.getRaster()->extract(rasComputeRectI); TPointD rasInPos(warpedComputeRect.getP00() - tileComputeRect.getP00()); TPointD warperPos( (TScale(params.m_warperScale) * warperComputeRect.getP00()) - tileComputeRect.getP00()); warp(tileRas, rasIn, rasWarper, rasInPos, warperPos, params); }
void TColorStyle::makeIcon(const TDimension &d) { checkErrorsByGL; TColorStyle *style = this->clone(); checkErrorsByGL; TPaletteP tmpPalette = new TPalette(); checkErrorsByGL; int id = tmpPalette->addStyle(style); checkErrorsByGL; int contextLx = pow(2.0, tceil(log((double)d.lx) / log(2.0))); int contextLy = pow(2.0, tceil(log((double)d.ly) / log(2.0))); TDimension dim(contextLx, contextLy); TOfflineGL *glContext = TOfflineGL::getStock(dim); checkErrorsByGL; glContext->clear(TPixel32::White); checkErrorsByGL; TVectorImageP img = new TVectorImage; checkErrorsByGL; img->setPalette(tmpPalette.getPointer()); checkErrorsByGL; std::vector<TThickPoint> points(3); if (isRegionStyle() && !isStrokeStyle()) { points[0] = TThickPoint(-55, -50, 1); points[1] = TThickPoint(0, -60, 1); points[2] = TThickPoint(55, -50, 1); TStroke *stroke1 = new TStroke(points); img->addStroke(stroke1); points[0] = TThickPoint(50, -55, 1); points[1] = TThickPoint(60, 0, 1); points[2] = TThickPoint(50, 55, 1); TStroke *stroke2 = new TStroke(points); img->addStroke(stroke2); points[0] = TThickPoint(55, 50, 1); points[1] = TThickPoint(0, 60, 1); points[2] = TThickPoint(-55, 50, 1); TStroke *stroke3 = new TStroke(points); img->addStroke(stroke3); points[0] = TThickPoint(-50, 55, 1); points[1] = TThickPoint(-60, 0, 1); points[2] = TThickPoint(-50, -55, 1); TStroke *stroke4 = new TStroke(points); img->addStroke(stroke4); img->fill(TPointD(0, 0), id); } else if (isStrokeStyle() && !isRegionStyle()) { double rasX05 = d.lx * 0.5; double rasY05 = d.ly * 0.5; points[0] = TThickPoint(-rasX05, -rasY05, 7); points[1] = TThickPoint(0, -rasY05, 9); points[2] = TThickPoint(rasX05, rasY05, 12); TStroke *stroke1 = new TStroke(points); stroke1->setStyle(id); img->addStroke(stroke1); points.clear(); } else if (!isRasterStyle()) { assert(isStrokeStyle() && isRegionStyle()); points[0] = TThickPoint(-60, -30, 0.5); points[1] = TThickPoint(0, -30, 0.5); points[2] = TThickPoint(60, -30, 0.5); TStroke *stroke1 = new TStroke(points); stroke1->setStyle(id); img->addStroke(stroke1); points[0] = TThickPoint(60, -30, 0.5); points[1] = TThickPoint(60, 0, 0.5); points[2] = TThickPoint(60, 30, 0.5); TStroke *stroke2 = new TStroke(points); stroke2->setStyle(id); img->addStroke(stroke2); points[0] = TThickPoint(60, 30, 0.5); points[1] = TThickPoint(0, 30, 0.5); points[2] = TThickPoint(-60, 30, 0.5); TStroke *stroke3 = new TStroke(points); stroke3->setStyle(id); img->addStroke(stroke3); points[0] = TThickPoint(-60, 30, 0.5); points[1] = TThickPoint(-60, 0, 0.5); points[2] = TThickPoint(-60, -30, 0.5); TStroke *stroke4 = new TStroke(points); stroke4->setStyle(id); img->addStroke(stroke4); img->fill(TPointD(0, 0), id); } TRectD bbox = img->getBBox(); checkErrorsByGL; bbox = bbox.enlarge(TDimensionD(-10, -10)); checkErrorsByGL; double scx = 0.9 * d.lx / bbox.getLx(); double scy = 0.9 * d.ly / bbox.getLy(); double sc = std::min(scx, scy); double dx = (d.lx - bbox.getLx() * sc) * 0.5; double dy = (d.ly - bbox.getLy() * sc) * 0.5; TAffine aff = TScale(scx, scy) * TTranslation(-bbox.getP00() + TPointD(dx, dy)); checkErrorsByGL; if (isRegionStyle() && !isStrokeStyle()) aff = aff * TTranslation(-10, -10); checkErrorsByGL; const TVectorRenderData rd(aff, TRect(), tmpPalette.getPointer(), 0, true); checkErrorsByGL; glContext->draw(img, rd); checkErrorsByGL; TRect rect(d); if (!m_icon || m_icon->getSize() != d) { checkErrorsByGL; m_icon = glContext->getRaster()->extract(rect)->clone(); } else { checkErrorsByGL; m_icon->copy(glContext->getRaster()->extract(rect)); } }
ShiftTraceTool::GadgetId ShiftTraceTool::getGadget(const TPointD &p) { std::vector<std::pair<TPointD, GadgetId>> gadgets; gadgets.push_back(std::make_pair(m_p0, CurveP0Gadget)); gadgets.push_back(std::make_pair(m_p1, CurveP1Gadget)); gadgets.push_back(std::make_pair(m_p2, CurvePmGadget)); TAffine aff = getGhostAff(); if (0 <= m_ghostIndex && m_ghostIndex < 2) { gadgets.push_back(std::make_pair(aff * m_box.getP00(), RotateGadget)); gadgets.push_back(std::make_pair(aff * m_box.getP01(), RotateGadget)); gadgets.push_back(std::make_pair(aff * m_box.getP10(), RotateGadget)); gadgets.push_back(std::make_pair(aff * m_box.getP11(), RotateGadget)); gadgets.push_back( std::make_pair(aff * m_center[m_ghostIndex], MoveCenterGadget)); } int k = -1; double minDist2 = pow(10 * getPixelSize(), 2); for (int i = 0; i < (int)gadgets.size(); i++) { double d2 = norm2(gadgets[i].first - p); if (d2 < minDist2) { minDist2 = d2; k = i; } } if (k >= 0) return gadgets[k].second; // rect-point if (0 <= m_ghostIndex && m_ghostIndex < 2) { TPointD q = aff.inv() * p; double big = 1.0e6; double d = big, x = 0, y = 0; if (m_box.x0 < q.x && q.x < m_box.x1) { x = q.x; double d0 = fabs(m_box.y0 - q.y); double d1 = fabs(m_box.y1 - q.y); if (d0 < d1) { d = d0; y = m_box.y0; } else { d = d1; y = m_box.y1; } } if (m_box.y0 < q.y && q.y < m_box.y1) { double d0 = fabs(m_box.x0 - q.y); double d1 = fabs(m_box.x1 - q.y); if (d0 < d) { d = d0; y = q.y; x = m_box.x0; } if (d1 < d) { d = d1; y = q.y; x = m_box.x1; } } if (d < big) { TPointD pp = aff * TPointD(x, y); double d = norm(p - pp); if (d < 10 * getPixelSize()) { return TranslateGadget; } } } return NoGadget; }
void Iwa_GradientWarpFx::doCompute(TTile &tile, double frame, const TRenderSettings &settings) { /*- ソース画像が刺さっていなければreturn -*/ if (!m_source.isConnected()) { tile.getRaster()->clear(); return; } /*- 参照画像が刺さっていなければ、ソース画像をそのまま返す -*/ if (!m_warper.isConnected()) { m_source->compute(tile, frame, settings); return; } /*- 計算パラメータを得る -*/ /*- 移動距離のピクセルサイズ -*/ /*--- 拡大縮小(移動回転しないで)のGeometryを反映させる ---*/ double k = sqrt(fabs(settings.m_affine.det())); double hLength = m_h_maxlen->getValue(frame) * k; double vLength = m_v_maxlen->getValue(frame) * k; double scale = m_scale->getValue(frame); /*- ワープ距離が0なら、ソース画像をそのまま返す -*/ if (hLength == 0.0 && vLength == 0.0) { m_source->compute(tile, frame, settings); return; } int margin = static_cast<int>(ceil((abs(hLength) < abs(vLength)) ? abs(vLength) : abs(hLength))); /*- 素材計算範囲を計算 -*/ /*- 出力範囲 -*/ TRectD rectOut(tile.m_pos, TDimensionD( tile.getRaster()->getLx(), tile.getRaster()->getLy())); TRectD enlargedRect = rectOut.enlarge((double)margin); TDimensionI enlargedDim((int)enlargedRect.getLx(), (int)enlargedRect.getLy()); /*- ソース画像を正規化して格納 -*/ float4 *source_host; TRasterGR8P source_host_ras(enlargedDim.lx * sizeof(float4), enlargedDim.ly); source_host_ras->lock(); source_host = (float4 *)source_host_ras->getRawData(); { /*- タイルはこのフォーカス内だけ使用。正規化してsource_hostに取り込んだらもう使わない。 -*/ TTile sourceTile; m_source->allocateAndCompute( sourceTile, enlargedRect.getP00(), enlargedDim, tile.getRaster(), frame, settings); /*- タイルの画像を0〜1に正規化してホストメモリに読み込む -*/ TRaster32P ras32 = (TRaster32P)sourceTile.getRaster(); TRaster64P ras64 = (TRaster64P)sourceTile.getRaster(); if (ras32) setSourceRaster<TRaster32P, TPixel32>(ras32, source_host, enlargedDim); else if (ras64) setSourceRaster<TRaster64P, TPixel64>(ras64, source_host, enlargedDim); } /*- 参照画像を正規化して格納 -*/ float *warper_host; TRasterGR8P warper_host_ras(enlargedDim.lx * sizeof(float), enlargedDim.ly); warper_host_ras->lock(); warper_host = (float *)warper_host_ras->getRawData(); { /*- タイルはこのフォーカス内だけ使用。正規化してwarper_hostに取り込んだらもう使わない -*/ TTile warperTile; m_warper->allocateAndCompute( warperTile, enlargedRect.getP00(), enlargedDim, tile.getRaster(), frame, settings); /*- タイルの画像の輝度値を0〜1に正規化してホストメモリに読み込む -*/ TRaster32P ras32 = (TRaster32P)warperTile.getRaster(); TRaster64P ras64 = (TRaster64P)warperTile.getRaster(); if (ras32) setWarperRaster<TRaster32P, TPixel32>(ras32, warper_host, enlargedDim); else if (ras64) setWarperRaster<TRaster64P, TPixel64>(ras64, warper_host, enlargedDim); } /*- 変位値をScale倍して増やす -*/ hLength *= scale; vLength *= scale; TRasterGR8P result_host_ras; result_host_ras = TRasterGR8P(enlargedDim.lx * sizeof(float4), enlargedDim.ly); /*- 結果を収めるメモリ -*/ float4 *result_host; result_host_ras->lock(); result_host = (float4 *)result_host_ras->getRawData(); doCompute_CPU(tile, frame, settings, hLength, vLength, margin, enlargedDim, source_host, warper_host, result_host); /*- ポインタ入れ替え -*/ source_host = result_host; int2 yohaku = {(enlargedDim.lx - tile.getRaster()->getSize().lx) / 2, (enlargedDim.ly - tile.getRaster()->getSize().ly) / 2}; /*- ラスタのクリア -*/ tile.getRaster()->clear(); TRaster32P outRas32 = (TRaster32P)tile.getRaster(); TRaster64P outRas64 = (TRaster64P)tile.getRaster(); if (outRas32) setOutputRaster<TRaster32P, TPixel32>(source_host, outRas32, enlargedDim, yohaku); else if (outRas64) setOutputRaster<TRaster64P, TPixel64>(source_host, outRas64, enlargedDim, yohaku); /*- ソース画像のメモリ解放 -*/ source_host_ras->unlock(); /*- 参照画像のメモリ解放 -*/ warper_host_ras->unlock(); result_host_ras->unlock(); }
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); }
void doCompute(TTile &tile, double frame, const TRenderSettings &info) { bool isWarped = m_warped.isConnected(); if (!isWarped) return; if (fabs(m_intensity->getValue(frame)) < 0.01) { m_warped->compute(tile, frame, info); return; } int shrink = (info.m_shrinkX + info.m_shrinkY) / 2; double scale = sqrt(fabs(info.m_affine.det())); double gridStep = 1.5 * m_gridStep->getValue(frame); WarpParams params; params.m_intensity = m_intensity->getValue(frame) / gridStep; params.m_warperScale = scale * gridStep; params.m_sharpen = m_sharpen->getValue(); params.m_shrink = shrink; double evolution = m_evol->getValue(frame); double size = 100.0 / info.m_shrinkX; TPointD pos(m_posx->getValue(frame), m_posy->getValue(frame)); //The warper is calculated on a standard reference, with fixed dpi. This makes sure //that the lattice created for the warp does not depend on camera transforms and resolution. TRenderSettings warperInfo(info); double warperScaleFactor = 1.0 / params.m_warperScale; warperInfo.m_affine = TScale(warperScaleFactor) * info.m_affine; //Retrieve tile's geometry TRectD tileRect; { TRasterP tileRas = tile.getRaster(); tileRect = TRectD(tile.m_pos, TDimensionD(tileRas->getLx(), tileRas->getLy())); } //Build the compute rect TRectD warpedBox, warpedComputeRect, tileComputeRect; m_warped->getBBox(frame, warpedBox, info); getWarpComputeRects(tileComputeRect, warpedComputeRect, warpedBox, tileRect, params); if (tileComputeRect.getLx() <= 0 || tileComputeRect.getLy() <= 0) return; if (warpedComputeRect.getLx() <= 0 || warpedComputeRect.getLy() <= 0) return; TRectD warperComputeRect(TScale(warperScaleFactor) * tileComputeRect); double warperEnlargement = getWarperEnlargement(params); warperComputeRect = warperComputeRect.enlarge(warperEnlargement); warperComputeRect.x0 = tfloor(warperComputeRect.x0); warperComputeRect.y0 = tfloor(warperComputeRect.y0); warperComputeRect.x1 = tceil(warperComputeRect.x1); warperComputeRect.y1 = tceil(warperComputeRect.y1); //Compute the warped tile TTile tileIn; m_warped->allocateAndCompute(tileIn, warpedComputeRect.getP00(), TDimension(warpedComputeRect.getLx(), warpedComputeRect.getLy()), tile.getRaster(), frame, info); TRasterP rasIn = tileIn.getRaster(); //Compute the warper tile TSpectrum::ColorKey colors[] = { TSpectrum::ColorKey(0, TPixel32::White), TSpectrum::ColorKey(1, TPixel32::Black)}; TSpectrumParamP cloudscolors = TSpectrumParamP(tArrayCount(colors), colors); //Build the warper warperInfo.m_affine = warperInfo.m_affine; TAffine aff = warperInfo.m_affine.inv(); TTile warperTile; TRasterP rasWarper = rasIn->create(warperComputeRect.getLx(), warperComputeRect.getLy()); warperTile.m_pos = warperComputeRect.getP00(); warperTile.setRaster(rasWarper); { TRenderSettings info2(warperInfo); //Now, separate the part of the affine the Fx can handle from the rest. TAffine fxHandledAffine = handledAffine(warperInfo, frame); info2.m_affine = fxHandledAffine; TAffine aff = warperInfo.m_affine * fxHandledAffine.inv(); aff.a13 /= warperInfo.m_shrinkX; aff.a23 /= warperInfo.m_shrinkY; TRectD rectIn = aff.inv() * warperComputeRect; //rectIn = rectIn.enlarge(getResampleFilterRadius(info)); //Needed to counter the resample filter TRect rectInI(tfloor(rectIn.x0), tfloor(rectIn.y0), tceil(rectIn.x1) - 1, tceil(rectIn.y1) - 1); // rasIn e' un raster dello stesso tipo di tile.getRaster() TTile auxtile(warperTile.getRaster()->create(rectInI.getLx(), rectInI.getLy()), convert(rectInI.getP00())); TPointD mypos(auxtile.m_pos - pos); double scale2 = sqrt(fabs(info2.m_affine.det())); doClouds(auxtile.getRaster(), cloudscolors, mypos, evolution, size, 0.0, 1.0, PNOISE_CLOUDS, scale2, frame); info2.m_affine = aff; TRasterFx::applyAffine(warperTile, auxtile, info2); } //Warp TPointD db; TRect rasComputeRectI(convert(tileComputeRect - tileRect.getP00(), db)); TRasterP tileRas = tile.getRaster()->extract(rasComputeRectI); TPointD rasInPos(warpedComputeRect.getP00() - tileComputeRect.getP00()); TPointD warperPos((TScale(params.m_warperScale) * warperComputeRect.getP00()) - tileComputeRect.getP00()); warp(tileRas, rasIn, rasWarper, rasInPos, warperPos, params); }
// Preliminary initializations //---------------------------------------------------------------------- // Calculate the overall render area - sum of all render ports' areas TRectD renderArea; { QReadLocker sl(&m_portsLock); for (PortContainerIterator it = m_ports.begin(); it != m_ports.end(); ++it) renderArea += (*it)->getRenderArea(); } const TRenderSettings &info(renderDatas[0].m_info); // Extract the render geometry TPointD pos(renderArea.getP00()); TDimension frameSize(tceil(renderArea.getLx()), tceil(renderArea.getLy())); TRectD camBox(TPointD(pos.x / info.m_shrinkX, pos.y / info.m_shrinkY), TDimensionD(frameSize.lx, frameSize.ly)); // Refresh the raster pool specs m_rasterPool.setRasterSpecs(frameSize, info.m_bpp); // Set a temporary active instance count - so that hasToDie(renderId) returns // false RenderInstanceInfos *renderInfos; { QMutexLocker locker(&m_renderInstancesMutex); renderInfos = &m_activeInstances[renderId]; renderInfos->m_activeTasks = 1;