/*! rectangular rgb picking. The picked color will be an average of pixels in * specified rectangle */ void ImageViewer::rectPickColor(bool putValueToStyleEditor) { if (!m_isHistogramEnable) return; if (!m_histogramPopup->isVisible()) return; StylePicker picker(m_image); TPoint startPos = TPoint(m_pressedMousePos.x, height() - 1 - m_pressedMousePos.y); TPoint endPos = TPoint(m_pos.x(), height() - 1 - m_pos.y()); TRectD area = TRectD(convert(startPos), convert(endPos)); area = area.enlarge(-1, -1); if (area.getLx() < 2 || area.getLy() < 2) { m_histogramPopup->updateAverageColor(TPixel32::Transparent); return; } if (m_lutCalibrator && m_lutCalibrator->isValid() && m_fbo) m_fbo->bind(); const TPixel32 pix = picker.pickColor(area.enlarge(-1, -1)); if (m_lutCalibrator && m_lutCalibrator->isValid() && m_fbo) m_fbo->release(); // throw the picked color to the histogram m_histogramPopup->updateAverageColor(pix); // throw it to the style editor as well if (putValueToStyleEditor) setPickedColorToStyleEditor(pix); }
TRectD SandorFxRenderData::getBBoxEnlargement(const TRectD &bbox) { switch (m_type) { case BlendTz: { //Nothing happen, unless we have color 0 among the blended ones. In such case, //we have to enlarge the bbox proportionally to the amount param. std::vector<std::string> items; std::string indexes = std::string(m_argv[0]); parseIndexes(indexes, items); PaletteFilterFxRenderData paletteFilterData; insertIndexes(items, &paletteFilterData); if (paletteFilterData.m_colors.size() > 0 && *paletteFilterData.m_colors.begin() == 0) return bbox.enlarge(m_blendParams.m_amount); return bbox; } case Calligraphic: case OutBorder: return bbox.enlarge(m_callParams.m_thickness); case ArtAtContour: return bbox.enlarge( tmax(tceil(m_controllerBBox.getLx()), tceil(m_controllerBBox.getLy())) * m_contourParams.m_maxSize); default: assert(false); return bbox; } }
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 RGBPickerTool::pickRect() { TImageP image = TImageP(getImage(false)); TTool::Application *app = TTool::getApplication(); TPaletteHandle *ph = app->getPaletteController()->getCurrentPalette(); int styleId = ph->getStyleIndex(); TPalette *palette = ph->getPalette(); TRectD area = m_selectingRect; if (!palette) return; if (m_selectingRect.x0 > m_selectingRect.x1) { area.x1 = m_selectingRect.x0; area.x0 = m_selectingRect.x1; } if (m_selectingRect.y0 > m_selectingRect.y1) { area.y1 = m_selectingRect.y0; area.y0 = m_selectingRect.y1; } m_selectingRect.empty(); if (area.getLx() <= 1 || area.getLy() <= 1) return; StylePicker picker(image, palette); // iwsw commented out temporarily // if (m_viewer->get3DLutUtil() && // Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled()) // m_viewer->get3DLutUtil()->bindFBO(); m_currentValue = picker.pickColor(area); // iwsw commented out temporarily // if (m_viewer->get3DLutUtil() && // Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled()) // m_viewer->get3DLutUtil()->releaseFBO(); }
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(); }
void FullColorBrushTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) { m_brushPos = m_mousePos = pos; TRasterImageP ri = (TRasterImageP)getImage(true); if (!ri) return; double maxThickness = m_thickness.getValue().second; double thickness = m_pressure.getValue() ? computeThickness(e.m_pressure, m_thickness) : maxThickness; double opacity = (m_pressure.getValue() ? computeThickness(e.m_pressure, m_opacity) : m_opacity.getValue().second) * 0.01; TDimension size = m_workRaster->getSize(); TPointD rasCenter = TPointD(size.lx * 0.5, size.ly * 0.5); TThickPoint point(pos + rasCenter, thickness); TThickPoint old = m_points.back(); if (norm2(point - old) < 4) return; TThickPoint mid((old + point) * 0.5, (point.thick + old.thick) * 0.5); m_points.push_back(mid); m_points.push_back(point); TRect bbox; int m = m_points.size(); TRectD invalidateRect; if (m == 3) { // ho appena cominciato. devo disegnare un segmento TThickPoint pa = m_points.front(); vector<TThickPoint> points; points.push_back(pa); points.push_back(mid); invalidateRect = ToolUtils::getBounds(points, maxThickness); bbox = m_brush->getBoundFromPoints(points); updateWorkAndBackupRasters(bbox + m_lastRect); m_tileSaver->save(bbox); m_brush->addArc(pa, (pa + mid) * 0.5, mid, m_oldOpacity, opacity); m_lastRect += bbox; } else { // caso generale: disegno un arco vector<TThickPoint> points; points.push_back(m_points[m - 4]); points.push_back(old); points.push_back(mid); invalidateRect = ToolUtils::getBounds(points, maxThickness); bbox = m_brush->getBoundFromPoints(points); updateWorkAndBackupRasters(bbox + m_lastRect); m_tileSaver->save(bbox); m_brush->addArc(m_points[m - 4], old, mid, m_oldOpacity, opacity); m_lastRect += bbox; } m_oldOpacity = opacity; m_brush->updateDrawing(ri->getRaster(), m_backUpRas, m_currentColor, bbox, m_opacity.getValue().second * 0.01); invalidate(invalidateRect.enlarge(2) - rasCenter); m_strokeRect += bbox; }
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(); }
void FullColorBrushTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e) { m_brushPos = m_mousePos = pos; TRasterImageP ri = (TRasterImageP)getImage(true); if (!ri) return; if (m_points.size() != 1) { double maxThickness = m_thickness.getValue().second; double thickness = m_pressure.getValue() ? computeThickness(e.m_pressure, m_thickness) : maxThickness; double opacity = (m_pressure.getValue() ? computeThickness(e.m_pressure, m_opacity) : m_opacity.getValue().second) * 0.01; TPointD rasCenter = ri->getRaster()->getCenterD(); TThickPoint point(pos + rasCenter, thickness); m_points.push_back(point); int m = m_points.size(); vector<TThickPoint> points; points.push_back(m_points[m - 3]); points.push_back(m_points[m - 2]); points.push_back(m_points[m - 1]); TRect bbox = m_brush->getBoundFromPoints(points); updateWorkAndBackupRasters(bbox); m_tileSaver->save(bbox); m_brush->addArc(points[0], points[1], points[2], m_oldOpacity, opacity); m_brush->updateDrawing(ri->getRaster(), m_backUpRas, m_currentColor, bbox, m_opacity.getValue().second * 0.01); TRectD invalidateRect = ToolUtils::getBounds(points, maxThickness); invalidate(invalidateRect.enlarge(2) - rasCenter); m_strokeRect += bbox; m_lastRect.empty(); } if (m_brush) { delete m_brush; m_brush = 0; } m_workRaster->unlock(); if (m_tileSet->getTileCount() > 0) { delete m_tileSaver; TTool::Application *app = TTool::getApplication(); TXshLevel *level = app->getCurrentLevel()->getLevel(); TXshSimpleLevelP simLevel = level->getSimpleLevel(); TFrameId frameId = getCurrentFid(); TRasterP ras = ri->getRaster()->extract(m_strokeRect)->clone(); TUndoManager::manager()->add(new FullColorBrushUndo(m_tileSet, simLevel.getPointer(), frameId, m_isFrameCreated, ras, m_strokeRect.getP00())); } notifyImageChanged(); m_strokeRect.empty(); }
int getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info) override { double scale = sqrt(fabs(info.m_affine.det())); double blur = m_value->getValue(frame) * scale; return TRasterFx::memorySize(rect.enlarge(blur), info.m_bpp); }
void get_render_enlarge( const double frame, const TAffine affine, TRectD &bBox) { const int margin = this->get_render_margin(frame, affine); if (0 < margin) { bBox = bBox.enlarge(static_cast<double>(margin)); } }
void get_render_enlarge(const double frame, const TAffine affine, TRectD &bBox) { const int margin = igs::gaussian_blur_hv::int_radius( this->get_render_real_radius(frame, affine)); if (0 < margin) { bBox = bBox.enlarge(static_cast<double>(margin)); } }
bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info) { if (m_warped.isConnected()) { int ret = m_warped->doGetBBox(frame, bBox, info); if (ret && !bBox.isEmpty()) { if (bBox != TConsts::infiniteRectD) { WarpParams params; params.m_intensity = m_intensity->getValue(frame); bBox = bBox.enlarge(getWarpRadius(params)); } return true; } } bBox = TRectD(); return false; }
TRect TRasterImageUtils::convertWorldToRaster(const TRectD &area, const TRasterImageP ri) { if (area.isEmpty()) return TRect(); if (!ri || !ri->getRaster()) return TRect(tfloor(area.x0), tfloor(area.y0), tfloor(area.x1) - 1, tfloor(area.y1) - 1); TRasterP ras = ri->getRaster(); TRectD rect(area + ras->getCenterD()); return TRect(tfloor(rect.x0), tfloor(rect.y0), tceil(rect.x1) - 1, tceil(rect.y1) - 1); }
/*-- 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(); }
int get_render_int_margin(const double frame, const TRectD &bBox, const TAffine affine, TPointD center) { /*--- 単位変換(mm-->render用pixel)と長さ(scale)変換 ---*/ const double scale = ino::pixel_per_mm() * sqrt(fabs(affine.det())); /*--- margin計算...Twist時正確でない ---*/ return igs::radial_blur::reference_margin( static_cast<int>(ceil(bBox.getLy())), static_cast<int>(ceil(bBox.getLx())), center.x, center.y, this->m_twist->getValue(frame) * 3.14159265358979 / 180.0, 0.0 // this->m_twist_radius->getValue(frame) * scale , this->m_blur->getValue(frame) / ino_param_range //,this->m_radius->getValue(frame) * scale , 0 /* debug:2012-02-01:ゼロ以上だとmarginが小さすぎになり画像が切れてしまう */ , (this->m_anti_alias->getValue() ? 4 : 1)); }
void Iwa_GradientWarpFx::get_render_enlarge(const double frame, const TAffine affine, TRectD &bBox) { double h_maxlen = 0.0; double v_maxlen = 0.0; this->get_render_real_hv(frame, affine, h_maxlen, v_maxlen); const int margin = static_cast<int>(ceil( (h_maxlen < v_maxlen) ? v_maxlen : h_maxlen)); if (0 < margin) { bBox = bBox.enlarge(static_cast<double>(margin)); } }
void rect_autofill_learn(const TVectorImageP &imgToLearn, const TRectD &rect) { if (rect.getLx() * rect.getLy() < MIN_SIZE) return; double pbx, pby; double totalArea = 0; pbx = pby = 0; if (!regionsReference.isEmpty()) regionsReference.clear(); int i, index = 0, regionCount = imgToLearn->getRegionCount(); for (i = 0; i < regionCount; i++) { TRegion *region = imgToLearn->getRegion(i); if (rect.contains(region->getBBox())) { scanRegion(region, index, regionsReference, rect); index++; } int j, subRegionCount = region->getSubregionCount(); for (j = 0; j < subRegionCount; j++) { TRegion *subRegion = region->getSubregion(j); if (rect.contains(subRegion->getBBox())) scanSubRegion(subRegion, index, regionsReference, rect); } } QMap<int, Region>::Iterator it; for (it = regionsReference.begin(); it != regionsReference.end(); it++) { pbx += it.value().m_barycentre.x; pby += it.value().m_barycentre.y; totalArea += it.value().m_area; } if (totalArea > 0) referenceB = TPointD(pbx / totalArea, pby / totalArea); else referenceB = TPointD(0.0, 0.0); }
void TTool::invalidate(const TRectD &rect) { if (m_viewer) { if (rect.isEmpty()) m_viewer->GLInvalidateAll(); else { TPointD dpiScale(1, 1); TXshSimpleLevel *sl = getApplication()->getCurrentLevel()->getSimpleLevel(); if (sl) dpiScale = getCurrentDpiScale(sl, getCurrentFid()); m_viewer->GLInvalidateRect(getCurrentColumnMatrix() * TScale(dpiScale.x, dpiScale.y) * rect); } } }
bool TRegion::selectFill(const TRectD &selArea, int styleId) { bool hitSomeRegions = false; if (selArea.contains(getBBox())) { hitSomeRegions = true; setStyle(styleId); } int regNum = m_imp->m_includedRegionArray.size(); for (int i = 0; i < regNum; i++) hitSomeRegions |= m_imp->m_includedRegionArray[i]->selectFill(selArea, styleId); return hitSomeRegions; }
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); }
bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &rs) { TRectD up_bx; const bool up_sw = (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false); TRectD dn_bx; const bool dn_sw = (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false); if (up_sw && dn_sw) { bBox = up_bx + dn_bx; return !bBox.isEmpty(); } else if (up_sw) { bBox = up_bx; return true; } else if (dn_sw) { bBox = dn_bx; return true; } else { bBox = TRectD(); return false; } }
bool TExternalProgramFx::doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info) { // bBox = TRectD(-30,-30,30,30); // return true; std::map<std::string, Port>::const_iterator portIt; for (portIt = m_ports.begin(); portIt != m_ports.end(); ++portIt) { if (portIt->second.m_port != 0) { TRasterFxPort *tmp; tmp = portIt->second.m_port; if (tmp->isConnected()) { TRectD tmpbBox; (*tmp)->doGetBBox(frame, tmpbBox, info); bBox += tmpbBox; } } } if (bBox.isEmpty()) { bBox = TRectD(); return false; } else return true; /* if(m_input1.isConnected() || m_input2.isConnected()) { bool ret = m_input1->doGetBBox(frame, bBox) || m_input1->doGetBBox(frame, bBox); return ret; } else { bBox = TRectD(); return false; } */ }
/*-- AutoCloseが実行されたらtrue,実行されなければfalseを返す --*/ bool applyAutoclose(const TToonzImageP &ti, const TRectD &selRect = TRectD(), TStroke *stroke = 0) { if (!ti) return false; // inizializzo gli AutocloseParameters AutocloseParameters params; params.m_closingDistance = (int)(m_distance.getValue()); params.m_spotAngle = (int)(m_angle.getValue()); params.m_opacity = m_opacity.getValue(); std::string inkString = ::to_string(m_inkIndex.getValue()); int inkIndex = TTool::getApplication() ->getCurrentLevelStyleIndex(); // TApp::instance()->getCurrentPalette()->getStyleIndex(); if (isInt(inkString)) inkIndex = std::stoi(inkString); params.m_inkIndex = inkIndex; TPoint delta; TRasterCM32P ras, raux = ti->getRaster(); if (m_closeType.getValue() == RECT_CLOSE && raux && !selRect.isEmpty()) { TRectD selArea = selRect; if (selRect.x0 > selRect.x1) { selArea.x1 = selRect.x0; selArea.x0 = selRect.x1; } if (selRect.y0 > selRect.y1) { selArea.y1 = selRect.y0; selArea.y0 = selRect.y1; } TRect myRect(ToonzImageUtils::convertWorldToRaster(selArea, ti)); ras = raux->extract(myRect); delta = myRect.getP00(); } else if ((m_closeType.getValue() == FREEHAND_CLOSE || m_closeType.getValue() == POLYLINE_CLOSE) && stroke) { TRectD selArea = stroke->getBBox(); TRect myRect(ToonzImageUtils::convertWorldToRaster(selArea, ti)); ras = raux->extract(myRect); delta = myRect.getP00(); } else ras = raux; if (!ras) return false; TAutocloser ac(ras, params.m_closingDistance, params.m_spotAngle, params.m_inkIndex, params.m_opacity); std::vector<TAutocloser::Segment> segments; ac.compute(segments); if ((m_closeType.getValue() == FREEHAND_CLOSE || m_closeType.getValue() == POLYLINE_CLOSE) && stroke) checkSegments(segments, stroke, raux, delta); std::vector<TAutocloser::Segment> segments2(segments); /*-- segmentが取得できなければfalseを返す --*/ if (segments2.empty()) return false; int i; if (delta != TPoint(0, 0)) for (i = 0; i < (int)segments2.size(); i++) { segments2[i].first += delta; segments2[i].second += delta; } TTileSetCM32 *tileSet = new TTileSetCM32(raux->getSize()); for (i = 0; i < (int)segments2.size(); i++) { TRect bbox(segments2[i].first, segments2[i].second); bbox = bbox.enlarge(2); tileSet->add(raux, bbox); } TXshSimpleLevel *sl = TTool::getApplication()->getCurrentLevel()->getSimpleLevel(); TFrameId id = getCurrentFid(); TUndoManager::manager()->add( new RasterAutocloseUndo(tileSet, params, segments2, sl, id)); ac.draw(segments); ToolUtils::updateSaveBox(); return true; }
void Iwa_TiledParticlesFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri) { std::vector<int> lastframe; std::vector<TLevelP> partLevel; TPointD p_offset; TDimension p_size(0, 0); /*- 参照画像ポートの取得 -*/ std::vector<TRasterFxPort *> part_ports; /*- テクスチャ素材画像のポート -*/ std::map<int, TRasterFxPort *> ctrl_ports; /*- コントロール画像のポート番号/ポート -*/ int portsCount = this->getInputPortCount(); for (int i = 0; i < portsCount; ++i) { std::string tmpName = this->getInputPortName(i); QString portName = QString::fromStdString(tmpName); if (portName.startsWith("T")) { TRasterFxPort *tmpPart = (TRasterFxPort *)this->getInputPort(tmpName); if (tmpPart->isConnected()) part_ports.push_back((TRasterFxPort *)this->getInputPort(tmpName)); } else { portName.replace(QString("Control"), QString("")); TRasterFxPort *tmpCtrl = (TRasterFxPort *)this->getInputPort(tmpName); if (tmpCtrl->isConnected()) ctrl_ports[portName.toInt()] = (TRasterFxPort *)this->getInputPort(tmpName); } } /*- テクスチャ素材のバウンディングボックスを足し合わせる ←この工程、いらないかも?-*/ if (!part_ports.empty()) { TRectD outTileBBox(tile.m_pos, TDimensionD(tile.getRaster()->getLx(), tile.getRaster()->getLy())); TRectD bbox; for (unsigned int i = 0; i < (int)part_ports.size(); ++i) { const TFxTimeRegion &tr = (*part_ports[i])->getTimeRegion(); lastframe.push_back(tr.getLastFrame() + 1); partLevel.push_back(new TLevel()); partLevel[i]->setName((*part_ports[i])->getAlias(0, ri)); // The particles offset must be calculated without considering the affine's translational // component TRenderSettings riZero(ri); riZero.m_affine.a13 = riZero.m_affine.a23 = 0; // Calculate the bboxes union for (int t = 0; t <= tr.getLastFrame(); ++t) { TRectD inputBox; (*part_ports[i])->getBBox(t, inputBox, riZero); bbox += inputBox; } } if (bbox == TConsts::infiniteRectD) bbox *= outTileBBox; p_size.lx = (int)bbox.getLx() + 1; p_size.ly = (int)bbox.getLy() + 1; p_offset = TPointD(0.5 * (bbox.x0 + bbox.x1), 0.5 * (bbox.y0 + bbox.y1)); } else { partLevel.push_back(new TLevel()); partLevel[0]->setName("particles"); TDimension vecsize(10, 10); TOfflineGL *offlineGlContext = new TOfflineGL(vecsize); offlineGlContext->clear(TPixel32(0, 0, 0, 0)); TStroke *stroke; stroke = makeEllipticStroke(0.07, TPointD((vecsize.lx - 1) * .5, (vecsize.ly - 1) * .5), 2.0, 2.0); TVectorImageP vectmp = new TVectorImage(); TPalette *plt = new TPalette(); vectmp->setPalette(plt); vectmp->addStroke(stroke); TVectorRenderData rd(AffI, TRect(vecsize), plt, 0, true, true); offlineGlContext->makeCurrent(); offlineGlContext->draw(vectmp, rd); partLevel[0]->setFrame(0, TRasterImageP(offlineGlContext->getRaster()->clone())); p_size.lx = vecsize.lx + 1; p_size.ly = vecsize.ly + 1; lastframe.push_back(1); delete offlineGlContext; } Iwa_Particles_Engine myEngine(this, frame); // Retrieving the dpi multiplier from the accumulated affine (which is isotropic). That is, // the affine will be applied *before* this effect - and we'll multiply geometrical parameters // by this dpi mult. in order to compensate. float dpi = sqrt(fabs(ri.m_affine.det())) * 100; TTile tileIn; if (TRaster32P raster32 = tile.getRaster()) { TFlash *flash = 0; myEngine.render_particles(flash, &tile, part_ports, ri, p_size, p_offset, ctrl_ports, partLevel, 1, (int)frame, 1, 0, 0, 0, 0, lastframe, getIdentifier()); } else if (TRaster64P raster64 = tile.getRaster()) { TFlash *flash = 0; myEngine.render_particles(flash, &tile, part_ports, ri, p_size, p_offset, ctrl_ports, partLevel, 1, (int)frame, 1, 0, 0, 0, 0, lastframe, getIdentifier()); } else throw TException("ParticlesFx: unsupported Pixel Type"); }
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)); } }