void AdjustLevelsPopup::acquireRaster() { //Retrieve current selection TApp *app = TApp::instance(); TSelection *selection = app->getCurrentSelection()->getSelection(); TCellSelection *cellSelection = dynamic_cast<TCellSelection *>(selection); TFilmstripSelection *filmstripSelection = dynamic_cast<TFilmstripSelection *>(selection); //Retrieve the input raster m_inputRas = TRasterP(); if (cellSelection) { TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); TXshCell cell = xsh->getCell(app->getCurrentFrame()->getFrameIndex(), app->getCurrentColumn()->getColumnIndex()); TRasterImageP rasImage = cell.getImage(true); if (rasImage && rasImage->getRaster()) m_inputRas = rasImage->getRaster(); } else if (filmstripSelection) { TXshSimpleLevel *simpleLevel = app->getCurrentLevel()->getSimpleLevel(); if (simpleLevel) { TRasterImageP rasImage = (TRasterImageP)simpleLevel->getFrame(app->getCurrentFrame()->getFid(), true); if (rasImage && rasImage->getRaster()) m_inputRas = rasImage->getRaster(); } } if (m_inputRas) { m_threshold = m_inputRas->getLx() * m_inputRas->getLy() * m_thresholdD; m_okBtn->setEnabled(true); } else { m_inputRas = TRasterP(); m_okBtn->setEnabled(false); } //Build histograms m_histogram->setRaster(m_inputRas); //Update the corresponding processed image in the viewer updateProcessedImage(); }
void BinarizePopup::fetchSample() { TApp *app = TApp::instance(); TImageP img; if (app->getCurrentFrame()->isEditingLevel()) { TXshLevel *xshLevel = app->getCurrentLevel()->getLevel(); if (xshLevel && xshLevel->getSimpleLevel()) { TXshSimpleLevel *sl = xshLevel->getSimpleLevel(); img = sl->getFrame(app->getCurrentFrame()->getFid(), false); } } else { TXsheet *xsh = app->getCurrentScene()->getScene()->getXsheet(); TXshCell cell = xsh->getCell(app->getCurrentFrame()->getFrame(), app->getCurrentColumn()->getColumnIndex()); img = cell.getImage(false); } TRasterImageP ri = img; if (ri) { setSample(ri->getRaster()); } else { setSample(TRasterP()); } }
void execute() { TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); int row = TApp::instance()->getCurrentFrame()->getFrame(); int col = TApp::instance()->getCurrentColumn()->getColumnIndex(); TXshCell cell = xsh->getCell(row, col); if (cell.isEmpty()) return; for (--row; row >= 0 && xsh->getCell(row, col) == cell; --row) // Get *last* cell in previous uniform ; // cell block if (row >= 0 && !xsh->getCell(row, col).isEmpty()) { cell = xsh->getCell(row, col); while (row > 0 && xsh->getCell(row - 1, col) == cell) // Get *first* cell in current uniform --row; // cell block TApp::instance()->getCurrentFrame()->setFrame(row); } }
void BrightnessAndContrastPopup::setCurrentSampleRaster() { TRasterP sampleRas; m_startRas = TRasterP(); TSelection *selection = TApp::instance()->getCurrentSelection()->getSelection(); TCellSelection *cellSelection = dynamic_cast<TCellSelection *>(selection); TFilmstripSelection *filmstripSelection = dynamic_cast<TFilmstripSelection *>(selection); if (cellSelection) { TApp *app = TApp::instance(); TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); TXshCell cell = xsh->getCell(app->getCurrentFrame()->getFrameIndex(), app->getCurrentColumn()->getColumnIndex()); TRasterImageP rasImage = cell.getImage(true); if (rasImage && rasImage->getRaster()) sampleRas = rasImage->getRaster()->clone(); } else if (filmstripSelection) { TApp *app = TApp::instance(); TXshSimpleLevel *simpleLevel = app->getCurrentLevel()->getSimpleLevel(); if (simpleLevel) { TRasterImageP rasImage = (TRasterImageP)simpleLevel->getFrame(app->getCurrentFrame()->getFid(), true); if (rasImage && rasImage->getRaster()) sampleRas = rasImage->getRaster()->clone(); } } if (!sampleRas) { m_viewer->raster() = TRasterP(); m_viewer->update(); m_okBtn->setEnabled(false); return; } m_okBtn->setEnabled(true); m_startRas = sampleRas->clone(); onChange(m_startRas, sampleRas, m_contrastField->getValue(), m_brightnessField->getValue()); m_viewer->raster() = sampleRas; m_viewer->update(); }
void SkeletonTool::getImageBoundingBox(TRectD &bbox, TAffine &aff, int frame, int columnIndex) { TAffine columnAff = getXsheet()->getPlacement(TStageObjectId::ColumnId(columnIndex), frame); // TAffine affine = getColumnMatrix(columnIndex); TXshCell cell = getXsheet()->getCell(frame, columnIndex); TImageP image = cell.getImage(false); TToonzImageP ti = image; TVectorImageP vi = image; if (ti) { TAffine imageDpiAff; if (cell.m_level->getSimpleLevel()) imageDpiAff = getDpiAffine(cell.m_level->getSimpleLevel(), cell.m_frameId, true); aff = columnAff * imageDpiAff; bbox = ToonzImageUtils::convertRasterToWorld(convert(ti->getBBox()), ti) * ti->getSubsampling(); ToolUtils::drawRect(bbox * ti->getSubsampling(), TPixel32(200, 200, 200), 0x5555); } else if (vi) { bbox = vi->getBBox(); aff = columnAff; } else { bbox = TRectD(); aff = TAffine(); } }
void AdjustLevelsUndo::redo() const { TXsheet *xsheet = TApp::instance()->getCurrentXsheet()->getXsheet(); TXshCell cell = xsheet->getCell(m_r, m_c); TRasterImageP rasImage = (TRasterImageP)cell.getImage(true); if (!rasImage) return; TRasterP ras = rasImage->getRaster(); if (!ras) return; TRop::rgbmAdjust(ras, ras, m_in0, m_in1, m_out0, m_out1); TXshSimpleLevel *simpleLevel = cell.getSimpleLevel(); assert(simpleLevel); simpleLevel->touchFrame(cell.getFrameId()); simpleLevel->setDirtyFlag(true); IconGenerator::instance()->invalidate(simpleLevel, cell.getFrameId()); if (m_isLastInBlock) TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); }
void undo() const { TXsheet *xsheet = TApp::instance()->getCurrentXsheet()->getXsheet(); TXshCell cell = xsheet->getCell(m_r, m_c); TImageP image = cell.getImage(true); TRasterImageP rimg = (TRasterImageP)image; TToonzImageP timg = (TToonzImageP)image; if (!rimg && !timg) return; if (rimg) rimg->setRaster(((TRasterImageP)TImageCache::instance()->get(m_rasId, true))->getRaster()->clone()); else timg->setCMapped(((TToonzImageP)TImageCache::instance()->get(m_rasId, true))->getRaster()->clone()); TXshSimpleLevel *simpleLevel = cell.getSimpleLevel(); assert(simpleLevel); simpleLevel->touchFrame(cell.getFrameId()); simpleLevel->setDirtyFlag(false); IconGenerator::instance()->invalidate(simpleLevel, cell.getFrameId()); if (m_isLastInBlock) { TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); } }
bool TXshZeraryFxColumn::canSetCell(const TXshCell &cell) const { return cell.isEmpty() || cell.m_level->getZeraryFxLevel() != 0; }
void AntialiasPopup::apply() { TCellSelection *cellSelection = dynamic_cast<TCellSelection *>(TSelection::getCurrent()); int threshold = m_thresholdField->getValue(); int softness = m_softnessField->getValue(); if (cellSelection) { std::set<TImage *> images; int r0, c0, r1, c1; cellSelection->getSelectedCells(r0, c0, r1, c1); TXsheet *xsheet = TApp::instance()->getCurrentXsheet()->getXsheet(); bool oneImageChanged = false; int c, r; TUndoManager::manager()->beginBlock(); for (c = c0; c <= c1; c++) for (r = r0; r <= r1; r++) { TXshCell cell = xsheet->getCell(r, c); TImageP image = cell.getImage(true); if (!image) continue; if (images.find(image.getPointer()) != images.end()) continue; TRasterP ras = image->raster(); if (!ras) continue; images.insert(image.getPointer()); oneImageChanged = true; TUndoManager::manager()->add(new TRasterAntialiasUndo(threshold, softness, r, c, ras->clone())); onChange(ras, threshold, softness); TXshSimpleLevel *simpleLevel = cell.getSimpleLevel(); assert(simpleLevel); simpleLevel->touchFrame(cell.getFrameId()); simpleLevel->setDirtyFlag(true); IconGenerator::instance()->invalidate(simpleLevel, cell.getFrameId()); } TUndoManager::manager()->endBlock(); if (oneImageChanged) { close(); return; } } TFilmstripSelection *filmstripSelection = dynamic_cast<TFilmstripSelection *>(TSelection::getCurrent()); if (filmstripSelection) { TXshSimpleLevel *simpleLevel = TApp::instance()->getCurrentLevel()->getSimpleLevel(); if (simpleLevel) { std::set<TFrameId> fids = filmstripSelection->getSelectedFids(); std::set<TFrameId>::iterator it = fids.begin(); bool oneImageChanged = false; for (it; it != fids.end(); it++) { TImageP image = simpleLevel->getFrame(*it, true); if (!image) continue; TRasterP ras = image->raster(); if (!ras) continue; oneImageChanged = true; onChange(ras, threshold, softness); simpleLevel->touchFrame(*it); simpleLevel->setDirtyFlag(true); IconGenerator::instance()->invalidate(simpleLevel, *it); } if (oneImageChanged) { close(); return; } } } DVGui::error(QObject::tr("The current selection is invalid.")); return; }
bool LevelCreatePopup::apply() { TApp *app = TApp::instance(); int row = app->getCurrentFrame()->getFrame(); int col = app->getCurrentColumn()->getColumnIndex(); int i, j; ToonzScene *scene = app->getCurrentScene()->getScene(); TXsheet *xsh = scene->getXsheet(); bool validColumn = true; if (xsh->getColumn(col)) validColumn = xsh->getColumn(col)->getColumnType() == TXshColumn::eLevelType; int from = (int)m_fromFld->getValue(); int to = (int)m_toFld->getValue(); int inc = (int)m_incFld->getValue(); int step = (int)m_stepFld->getValue(); double w = m_widthFld->getValue(); double h = m_heightFld->getValue(); double dpi = m_dpiFld->getValue(); int xres = std::max(tround(w * dpi), 1); int yres = std::max(tround(h * dpi), 1); int lType = getLevelType(); std::wstring levelName = m_nameFld->text().toStdWString(); // tolgo i blanks prima e dopo i = levelName.find_first_not_of(L' '); if (i == (int)std::wstring::npos) levelName = L""; else { int j = levelName.find_last_not_of(L' '); assert(j != (int)std::wstring::npos); levelName = levelName.substr(i, j - i + 1); } if (levelName.empty()) { error(tr("No level name specified: please choose a valid level name")); return false; } if (from > to) { error(tr("Invalid frame range")); return false; } if (inc <= 0) { error(tr("Invalid increment value")); return false; } if (step <= 0) { error(tr("Invalid step value")); return false; } int numFrames = step * (((to - from) / inc) + 1); if (scene->getLevelSet()->getLevel(levelName)) { error( tr("The level name specified is already used: please choose a " "different level name")); m_nameFld->selectAll(); return false; } TFilePath parentDir(m_pathFld->getPath().toStdWString()); TFilePath fp = scene->getDefaultLevelPath(lType, levelName).withParentDir(parentDir); TFilePath actualFp = scene->decodeFilePath(fp); if (TSystem::doesExistFileOrLevel(actualFp)) { error( tr("The level name specified is already used: please choose a " "different level name")); m_nameFld->selectAll(); return false; } parentDir = scene->decodeFilePath(parentDir); if (!TFileStatus(parentDir).doesExist()) { QString question; /*question = "Folder " +toQString(parentDir) + " doesn't exist.\nDo you want to create it?";*/ question = tr("Folder %1 doesn't exist.\nDo you want to create it?") .arg(toQString(parentDir)); int ret = DVGui::MsgBox(question, QObject::tr("Yes"), QObject::tr("No")); if (ret == 0 || ret == 2) return false; try { TSystem::mkDir(parentDir); DvDirModel::instance()->refreshFolder(parentDir.getParentDir()); } catch (...) { error(tr("Unable to create") + toQString(parentDir)); return false; } } TXshLevel *level = scene->createNewLevel(lType, levelName, TDimension(), 0, fp); TXshSimpleLevel *sl = dynamic_cast<TXshSimpleLevel *>(level); assert(sl); sl->setPath(fp, true); if (lType == TZP_XSHLEVEL || lType == OVL_XSHLEVEL) { sl->getProperties()->setDpiPolicy(LevelProperties::DP_ImageDpi); sl->getProperties()->setDpi(dpi); sl->getProperties()->setImageDpi(TPointD(dpi, dpi)); sl->getProperties()->setImageRes(TDimension(xres, yres)); } /*-- これからLevelを配置しようとしているセルが空いているかどうかのチェック * --*/ bool areColumnsShifted = false; TXshCell cell = xsh->getCell(row, col); bool isInRange = true; for (i = row; i < row + numFrames; i++) { if (!cell.isEmpty()) { isInRange = false; break; } cell = xsh->getCell(i, col); } if (!validColumn) { isInRange = false; } /*-- 別のLevelに占有されていた場合、Columnを1つ右に移動 --*/ if (!isInRange) { col += 1; TApp::instance()->getCurrentColumn()->setColumnIndex(col); areColumnsShifted = true; xsh->insertColumn(col); } CreateLevelUndo *undo = new CreateLevelUndo(row, col, numFrames, step, areColumnsShifted); TUndoManager::manager()->add(undo); for (i = from; i <= to; i += inc) { TFrameId fid(i); TXshCell cell(sl, fid); if (lType == PLI_XSHLEVEL) sl->setFrame(fid, new TVectorImage()); else if (lType == TZP_XSHLEVEL) { TRasterCM32P raster(xres, yres); raster->fill(TPixelCM32()); TToonzImageP ti(raster, TRect()); ti->setDpi(dpi, dpi); sl->setFrame(fid, ti); ti->setSavebox(TRect(0, 0, xres - 1, yres - 1)); } else if (lType == OVL_XSHLEVEL) { TRaster32P raster(xres, yres); raster->clear(); TRasterImageP ri(raster); ri->setDpi(dpi, dpi); sl->setFrame(fid, ri); } for (j = 0; j < step; j++) xsh->setCell(row++, col, cell); } if (lType == TZP_XSHLEVEL || lType == OVL_XSHLEVEL) { sl->save(fp); DvDirModel::instance()->refreshFolder(fp.getParentDir()); } undo->onAdd(sl); app->getCurrentScene()->notifySceneChanged(); app->getCurrentScene()->notifyCastChange(); app->getCurrentXsheet()->notifyXsheetChanged(); // Cambia l'immagine corrente ma non cambiano ne' il frame ne' la colonna // corrente // (entrambi notificano il cambiamento dell'immagine al tool). // devo verfificare che sia settato il tool giusto. app->getCurrentTool()->onImageChanged( (TImage::Type)app->getCurrentImageType()); return true; }
bool VectorizerPopup::apply() { std::set<TXshLevel *> levels; ToonzScene *scene = m_sceneHandle->getScene(); if (!scene) { assert(scene); return false; } TSceneProperties *sceneProp = scene->getProperties(); if (!sceneProp) return false; VectorizerParameters *vectorizerParameters = sceneProp->getVectorizerParameters(); if (!vectorizerParameters) return false; int r0 = 0; int c0 = 0; int r1 = 0; int c1 = 0; bool isCellSelection = getSelectedLevels(levels, r0, c0, r1, c1); if (levels.empty()) { error(tr("The current selection is invalid.")); return false; } //Initialize Progress bar m_progressDialog = new DVGui::ProgressDialog("", "Cancel", 0, 1); m_progressDialog->setWindowFlags(Qt::Dialog | Qt::WindowTitleHint); //Don't show ? and X buttons m_progressDialog->setWindowTitle(QString("Convert To Vector...")); m_progressDialog->setAttribute(Qt::WA_DeleteOnClose); m_progressDialog->setWindowModality(Qt::WindowModal); //No user interaction is allowed during vectorization m_progressDialog->setFixedSize(200, 100); //Initialize vectorizer m_vectorizer = new Vectorizer; m_vectorizer->setParameters(*vectorizerParameters); connect(m_vectorizer, SIGNAL(frameName(QString)), this, SLOT(onFrameName(QString)), Qt::QueuedConnection); connect(m_vectorizer, SIGNAL(frameDone(int)), this, SLOT(onFrameDone(int)), Qt::QueuedConnection); connect(m_vectorizer, SIGNAL(partialDone(int, int)), this, SLOT(onPartialDone(int, int)), Qt::QueuedConnection); //We DON'T want the progress bar to be hidden at cancel press - since its modal //behavior prevents the user to interfere with a possibly still active vectorization. disconnect(m_progressDialog, SIGNAL(canceled()), m_progressDialog, SLOT(onCancel())); //We first inform the vectorizer of a cancel press; bool ret = connect(m_progressDialog, SIGNAL(canceled()), m_vectorizer, SLOT(cancel())); //which eventually transmits the command to vectorization core, allowing full-time cancels ret = ret && connect(m_progressDialog, SIGNAL(canceled()), m_vectorizer, SIGNAL(transmitCancel())); //Only after the vectorizer has terminated its process - or got cancelled, we are allowed //to proceed here. ret = ret && connect(m_vectorizer, SIGNAL(finished()), this, SLOT(onFinished()), Qt::QueuedConnection); assert(ret); int newIndexColumn = c1 + 1; std::set<TXshLevel *>::iterator it = levels.begin(); for (it; it != levels.end(); it++) { TXshSimpleLevel *sl = dynamic_cast<TXshSimpleLevel *>(*it); if (!sl || !sl->getSimpleLevel() || !isLevelToConvert(sl)) { QString levelName = tr(toString(sl->getName()).c_str()); QString errorMsg = tr("Cannot convert to vector the current selection.") + levelName; error(errorMsg); continue; } std::vector<TFrameId> fids; if (isCellSelection) getSelectedFids(fids, sl, r0, c0, r1, c1); else sl->getFids(fids); assert(fids.size() > 0); close(); // Re-initialize progress Bar m_progressDialog->setMaximum(fids.size() * 100); m_progressDialog->setValue(0); m_currFrame = 0; // Re-initialize vectorizer m_vectorizer->setLevel(sl); m_vectorizer->setFids(fids); // Start vectorizing m_vectorizer->start(); m_progressDialog->show(); // Wait the vectorizer... while (!l_quitLoop) QCoreApplication::processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents); l_quitLoop = false; // Assign output X-sheet cells TXshSimpleLevel *vl = m_vectorizer->getVectorizedLevel(); if (isCellSelection && vl) { TXsheet *xsheet = TApp::instance()->getCurrentXsheet()->getXsheet(); xsheet->insertColumn(newIndexColumn); int r, c; for (c = c0; c <= c1; c++) { for (r = r0; r <= r1; r++) { TXshCell cell = xsheet->getCell(r, c); TXshSimpleLevel *level = (!cell.isEmpty()) ? cell.getSimpleLevel() : 0; if (level != sl) continue; TFrameId curFid = cell.getFrameId(); std::vector<TFrameId> newFids; vl->getFids(newFids); std::vector<TFrameId>::iterator it1 = newFids.begin(); for (it1; it1 != newFids.end(); it1++) { TFrameId id = *it1; if (id.getNumber() == curFid.getNumber() || // Hanno stesso numero di frame (id.getNumber() == 1 && curFid.getNumber() == -2)) // La vecchia cella non ha numero di frame xsheet->setCell(r, newIndexColumn, TXshCell(vl, id)); } } } newIndexColumn += 1; } else if (vl) { std::vector<TFrameId> gomi; scene->getXsheet()->exposeLevel(0, scene->getXsheet()->getFirstFreeColumnIndex(), vl, gomi); } if (m_vectorizer->isCanceled()) break; } m_progressDialog->close(); delete m_vectorizer; TApp::instance()->getCurrentScene()->notifyCastChange(); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); return true; }
void ComboViewerPanel::changeWindowTitle() { TApp *app = TApp::instance(); ToonzScene *scene = app->getCurrentScene()->getScene(); if (!scene) return; int frame = app->getCurrentFrame()->getFrame(); // put the titlebar texts in this string QString name; // if the frame type is "scene editing" if (app->getCurrentFrame()->isEditingScene()) { QString sceneName = QString::fromStdWString(scene->getSceneName()); if (sceneName.isEmpty()) sceneName = tr("Untitled"); if (app->getCurrentScene()->getDirtyFlag()) sceneName += QString(" *"); name = tr("Scene: ") + sceneName; if (frame >= 0) name = name + tr(" :: Frame: ") + tr(std::to_string(frame + 1).c_str()); int col = app->getCurrentColumn()->getColumnIndex(); if (col < 0) { setWindowTitle(name); return; } TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); TXshCell cell = xsh->getCell(frame, col); if (cell.isEmpty()) { setWindowTitle(name); return; } assert(cell.m_level.getPointer()); TFilePath fp(cell.m_level->getName()); QString imageName = QString::fromStdWString(fp.withFrame(cell.m_frameId).getWideString()); name = name + tr(" :: Level: ") + imageName; if (m_sceneViewer->isPreviewEnabled()) { name = name + " :: Zoom : " + QString::number((int)(100.0 * sqrt(m_sceneViewer->getViewMatrix().det()) * m_sceneViewer->getDpiFactor())) + "%"; } // If the current level exists and some option is set in the preference, // set the zoom value to the current level's dpi else if (Preferences::instance() ->isActualPixelViewOnSceneEditingModeEnabled() && TApp::instance()->getCurrentLevel()->getSimpleLevel() && !CleanupPreviewCheck::instance() ->isEnabled() // cleanup preview must be OFF && !CameraTestCheck::instance() ->isEnabled()) // camera test mode must be OFF neither { name = name + " :: Zoom : " + QString::number((int)(100.0 * sqrt(m_sceneViewer->getViewMatrix().det()) * m_sceneViewer->getDpiFactor())) + "%"; } } // if the frame type is "level editing" else { TXshLevel *level = app->getCurrentLevel()->getLevel(); if (level) { TFilePath fp(level->getName()); QString imageName = QString::fromStdWString( fp.withFrame(app->getCurrentFrame()->getFid()).getWideString()); name = name + tr("Level: ") + imageName; name = name + " :: Zoom : " + QString::number((int)(100.0 * sqrt(m_sceneViewer->getViewMatrix().det()) * m_sceneViewer->getDpiFactor())) + "%"; } } setWindowTitle(name); }
void StylePickerTool::pick(const TPointD &pos, const TMouseEvent &e) { // Area = 0, Line = 1, All = 2 int modeValue = m_colorType.getIndex(); //------------------------------------ // MultiLayerStylePicker /*--- PickしたStyleId = 0、かつ Preference で MultiLayerStylePickerが有効、かつ Scene編集モード、かつ 下のカラムから拾った色がTransparentでない場合、 → カレントLevelを移動する。 ---*/ if (Preferences::instance()->isMultiLayerStylePickerEnabled() && getApplication()->getCurrentFrame()->isEditingScene()) { int superPickedColumnId = getViewer()->posToColumnIndex( e.m_pos, getPixelSize() * getPixelSize(), false); if (superPickedColumnId >= 0 /*-- 何かColumnに当たった場合 --*/ && getApplication()->getCurrentColumn()->getColumnIndex() != superPickedColumnId) /*-- かつ、Current Columnでない場合 --*/ { /*-- そのColumnからPickを試みる --*/ int currentFrame = getApplication()->getCurrentFrame()->getFrame(); TXshCell pickedCell = getApplication()->getCurrentXsheet()->getXsheet()->getCell( currentFrame, superPickedColumnId); TImageP pickedImage = pickedCell.getImage(false).getPointer(); TToonzImageP picked_ti = pickedImage; TVectorImageP picked_vi = pickedImage; TXshSimpleLevel *picked_level = pickedCell.getSimpleLevel(); if ((picked_ti || picked_vi) && picked_level) { TPointD tmpMousePosition = getColumnMatrix(superPickedColumnId).inv() * getViewer()->winToWorld(e.m_pos); TPointD tmpDpiScale = getCurrentDpiScale(picked_level, getCurrentFid()); tmpMousePosition.x /= tmpDpiScale.x; tmpMousePosition.y /= tmpDpiScale.y; StylePicker superPicker(pickedImage); int picked_subsampling = picked_level->getImageSubsampling(pickedCell.getFrameId()); int superPicked_StyleId = superPicker.pickStyleId( TScale(1.0 / picked_subsampling) * tmpMousePosition + TPointD(-0.5, -0.5), getPixelSize() * getPixelSize(), modeValue); /*-- 何かStyleが拾えて、Transparentでない場合 --*/ if (superPicked_StyleId > 0) { /*-- Levelの移動 --*/ getApplication()->getCurrentLevel()->setLevel(picked_level); /*-- Columnの移動 --*/ getApplication()->getCurrentColumn()->setColumnIndex( superPickedColumnId); /*-- 選択の解除 --*/ if (getApplication()->getCurrentSelection()->getSelection()) getApplication() ->getCurrentSelection() ->getSelection() ->selectNone(); /*-- StyleIdの移動 --*/ getApplication()->setCurrentLevelStyleIndex(superPicked_StyleId); return; } } } } /*-- MultiLayerStylePicker ここまで --*/ //------------------------------------ TImageP image = getImage(false); TToonzImageP ti = image; TVectorImageP vi = image; TXshSimpleLevel *level = getApplication()->getCurrentLevel()->getSimpleLevel(); if ((!ti && !vi) || !level) return; /*-- 画面外をpickしても拾えないようにする --*/ if (!m_viewer->getGeometry().contains(pos)) return; int subsampling = level->getImageSubsampling(getCurrentFid()); StylePicker picker(image); int styleId = picker.pickStyleId(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5), getPixelSize() * getPixelSize(), modeValue); if (styleId < 0) return; if (modeValue == 1) // LINES { /*-- pickLineモードのとき、取得Styleが0の場合はカレントStyleを変えない。 * --*/ if (styleId == 0) return; /*-- * pickLineモードのとき、PurePaintの部分をクリックしてもカレントStyleを変えない * --*/ if (ti && picker.pickTone(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5)) == 255) return; } /*--- Styleを選択している場合は選択を解除する ---*/ TSelection *selection = TTool::getApplication()->getCurrentSelection()->getSelection(); if (selection) { TStyleSelection *styleSelection = dynamic_cast<TStyleSelection *>(selection); if (styleSelection) styleSelection->selectNone(); } getApplication()->setCurrentLevelStyleIndex(styleId); }
TImage *TTool::touchImage() { if (!m_application) return 0; m_cellsData.clear(); m_isLevelCreated = false; m_isFrameCreated = false; Preferences *pref = Preferences::instance(); bool isAutoCreateEnabled = pref->isAutoCreateEnabled(); bool animationSheetEnabled = pref->isAnimationSheetEnabled(); bool isAutoStretchEnabled = pref->isAutoStretchEnabled(); TFrameHandle *currentFrame = m_application->getCurrentFrame(); TXshLevelHandle *currentLevel = m_application->getCurrentLevel(); if (currentFrame->isEditingLevel()) { // Editing level // no level => return 0 TXshLevel *xl = currentLevel->getLevel(); if (!xl) return 0; TXshSimpleLevel *sl = xl->getSimpleLevel(); if (!sl || sl->isEmpty()) return 0; TFrameId fid = currentFrame->getFid(); TImageP img = sl->getFrame(fid, true); if (!img) { // no drawing found if (sl->isSubsequence() || sl->isReadOnly() || !isAutoCreateEnabled) return 0; // create a new drawing img = sl->createEmptyFrame(); sl->setFrame(fid, img); currentLevel->notifyLevelChange(); m_isFrameCreated = true; } return img.getPointer(); } else { // editing xsheet if (m_application->getCurrentObject()->isSpline()) return 0; TSceneHandle *currentScene = m_application->getCurrentScene(); ToonzScene *scene = currentScene->getScene(); int row = currentFrame->getFrame(); int col = m_application->getCurrentColumn()->getColumnIndex(); if (col < 0) return 0; TXsheetHandle *currentXsheet = m_application->getCurrentXsheet(); TXsheet *xsh = currentXsheet->getXsheet(); if (!xsh) return 0; TXshCell cell = xsh->getCell(row, col); TXshSimpleLevel *sl = cell.getSimpleLevel(); if (sl != 0) { // current cell is not empty if (isAutoCreateEnabled && animationSheetEnabled && row > 0 && xsh->getCell(row - 1, col) == xsh->getCell(row, col)) { // animationSheet is enabled and the current cell is a "hold". We must // create a new drawing. // measure the hold length (starting from the current row) : r0-r1 int r0 = row, r1 = row; if (isAutoStretchEnabled) while (xsh->getCell(r1 + 1, col) == cell) r1++; // find the proper frameid (possibly addisng suffix, in order to avoid a // fid already used) TFrameId fid = getNewFrameId(sl, row); // create the new drawing TImageP img = sl->createEmptyFrame(); m_isFrameCreated = true; // insert the drawing in the level sl->setFrame(fid, img); // update the cell cell = TXshCell(sl, fid); // update the xsheet (change the current cell and possibly all the // following "hold") for (int r = r0; r <= r1; r++) xsh->setCell(r, col, cell); // notify currentXsheet->notifyXsheetChanged(); currentScene->notifyCastChange(); currentLevel->notifyLevelChange(); m_cellsData.push_back(r0); m_cellsData.push_back(r1); m_cellsData.push_back(0); } // we've found the image. return it. return cell.getImage(true).getPointer(); } // current cell is empty. if (!isAutoCreateEnabled) return 0; // get the column range int r0, r1; xsh->getCellRange(col, r0, r1); if (animationSheetEnabled && r0 <= r1) { // animation sheet enabled and not empty column. We must create a new // drawing in the column level and possibly add "holds" // find the last not-empty cell before the current one (a) and the first // after (b) int a = row - 1, b = row + 1; while (a >= r0 && xsh->getCell(a, col).isEmpty()) a--; while (b <= r1 && xsh->getCell(b, col).isEmpty()) b++; // find the level we must attach to if (a >= r0) { // there is a not-emtpy cell before the current one sl = xsh->getCell(a, col).getSimpleLevel(); } else if (b <= r1) { sl = xsh->getCell(b, col).getSimpleLevel(); } if (sl) { // note: sl should be always !=0 (the column is not empty) // if - for some reason - it is ==0 then we skip to the standard (i.e. // !animationSheetEnabled) beahviour // create the drawing // find the proper frameid (possibly addisng suffix, in order to avoid a // fid already used) TFrameId fid = getNewFrameId(sl, row); // create the new drawing TImageP img = sl->createEmptyFrame(); m_isFrameCreated = true; // insert the drawing in the level sl->setFrame(fid, img); // update the cell cell = TXshCell(sl, fid); xsh->setCell(row, col, cell); // create holds if (!isAutoStretchEnabled) { m_cellsData.push_back(row); m_cellsData.push_back(row); m_cellsData.push_back(2); // vuoto => nuovo } else { if (a >= r0) { // create a hold before : [a+1, row-1] TXshCell aCell = xsh->getCell(a, col); for (int i = a + 1; i < row; i++) xsh->setCell(i, col, aCell); m_cellsData.push_back(a + 1); m_cellsData.push_back(row - 1); m_cellsData.push_back(1); // vuoto => vecchio if (b <= r1 && xsh->getCell(b, col).getSimpleLevel() == sl) { // create also a hold after for (int i = row + 1; i < b; i++) xsh->setCell(i, col, cell); m_cellsData.push_back(row); m_cellsData.push_back(b - 1); m_cellsData.push_back(2); // vuoto => nuovo } else { m_cellsData.push_back(row); m_cellsData.push_back(row); m_cellsData.push_back(2); // vuoto => nuovo } } else if (b <= r1) { // create a hold after for (int i = row + 1; i < b; i++) xsh->setCell(i, col, cell); m_cellsData.push_back(row); m_cellsData.push_back(b - 1); m_cellsData.push_back(2); // vuoto => nuovo } } } // notify & return currentXsheet->notifyXsheetChanged(); currentScene->notifyCastChange(); currentLevel->notifyLevelChange(); return cell.getImage(true).getPointer(); } if (row > 0 && xsh->getCell(row - 1, col).getSimpleLevel() != 0 && !animationSheetEnabled) { sl = xsh->getCell(row - 1, col).getSimpleLevel(); if (sl->getType() != OVL_XSHLEVEL || sl->getPath().getFrame() != TFrameId::NO_FRAME) { // la cella precedente contiene un drawing di un livello. animationSheet // e' disabilitato // creo un nuovo frame currentLevel->setLevel(sl); if (sl->isSubsequence() || sl->isReadOnly()) return 0; TFrameId fid = sl->index2fid(sl->getFrameCount()); TImageP img = sl->createEmptyFrame(); m_isFrameCreated = true; sl->setFrame(fid, img); cell = TXshCell(sl, fid); xsh->setCell(row, col, cell); currentXsheet->notifyXsheetChanged(); currentScene->notifyCastChange(); currentLevel->notifyLevelChange(); return img.getPointer(); } } // animation sheet disabled or empty column. autoCreate is enabled: we must // create a new level int levelType = pref->getDefLevelType(); TXshLevel *xl = scene->createNewLevel(levelType); sl = xl->getSimpleLevel(); m_isLevelCreated = true; // create the drawing TFrameId fid = animationSheetEnabled ? getNewFrameId(sl, row) : TFrameId(1); TImageP img = sl->createEmptyFrame(); m_isFrameCreated = true; sl->setFrame(fid, img); cell = TXshCell(sl, fid); xsh->setCell(row, col, cell); if (animationSheetEnabled) { m_cellsData.push_back(row); m_cellsData.push_back(row); m_cellsData.push_back(2); // vuoto => nuovo } currentXsheet->notifyXsheetChanged(); currentScene->notifyCastChange(); currentLevel->notifyLevelChange(); return img.getPointer(); } }
void ColumnCmd::cloneChild(int index) { if (!canResequence(index)) return; /*-- カラムを取得 --*/ TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); TXshColumn *column = xsh->getColumn(index); assert(column); // get the subxsheet to clone (childLevel, childXsh) /*-- SubXsheetレベルを取得 --*/ TXshLevelColumn *lcolumn = column->getLevelColumn(); assert(lcolumn); int r0 = 0, r1 = -1; lcolumn->getRange(r0, r1); assert(r0 <= r1); /*-- SubXsheetの一番頭のセル --*/ TXshCell cell = lcolumn->getCell(r0); assert(!cell.isEmpty()); /*- cell内に格納されているLevelを取得 -*/ TXshChildLevel *childLevel = cell.m_level->getChildLevel(); assert(childLevel); /*- SubXsheetのXsheetを取得 -*/ TXsheet *childXsh = childLevel->getXsheet(); // insert a new empty column /*- 隣に空きColumnをInsertしてCloneに備える -*/ int newColumnIndex = index + 1; xsh->insertColumn(newColumnIndex); // create a subxsheet (newChildLevel, newChildXsh) ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene(); ChildStack *childStack = scene->getChildStack(); TXshChildLevel *newChildLevel = childStack->createChild(0, newColumnIndex); TXsheet *newChildXsh = newChildLevel->getXsheet(); // copy columns. std::set<int> indices; for (int i = 0; i < childXsh->getColumnCount(); i++) indices.insert(i); StageObjectsData *data = new StageObjectsData(); data->storeColumns(indices, childXsh, 0); data->storeColumnFxs(indices, childXsh, 0); std::list<int> restoredSplineIds; data->restoreObjects(indices, restoredSplineIds, newChildXsh, StageObjectsData::eDoClone); delete data; cloneNotColumnLinkedFxsAndOutputsFx(childXsh, newChildXsh); cloneXsheetTStageObjectTree(childXsh, newChildXsh); /*--以下は、Clone SubXsheet するときに、SubXsheet内にある子SubXsheetをクローンする関数 クローンされた中にある子SubXsheetは、同じもので良いので、スキップする --*/ // cloneSubXsheets(newChildXsh); /*-- XSheetノードのFxSchematicでのDagNodePosを再現 FxやColumnノードの位置の再現は上のsetColumnで行っている --*/ newChildXsh->getFxDag()->getXsheetFx()->getAttributes()->setDagNodePos( childXsh->getFxDag()->getXsheetFx()->getAttributes()->getDagNodePos()); newChildXsh->updateFrameCount(); /*-- TXshChildLevel作成時にsetCellした1つ目のセルを消去 --*/ xsh->removeCells(0, newColumnIndex); /*-- CloneしたColumnのセル番号順を再現 --*/ for (int r = r0; r <= r1; r++) { TXshCell cell = lcolumn->getCell(r); if (cell.isEmpty()) continue; cell.m_level = newChildLevel; xsh->setCell(r, newColumnIndex, cell); } TStageObjectId currentObjectId = TApp::instance()->getCurrentObject()->getObjectId(); xsh->getStageObject(TStageObjectId::ColumnId(newColumnIndex)) ->setParent(xsh->getStageObjectParent(currentObjectId)); xsh->updateFrameCount(); TUndoManager::manager()->add( new CloneChildUndo(newChildLevel, newColumnIndex)); // notify changes TApp::instance()->getCurrentScene()->setDirtyFlag(true); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); }
void LinesFadePopup::apply() { TCellSelection *cellSelection = dynamic_cast<TCellSelection *>(TSelection::getCurrent()); TPixel32 color = m_linesColorField->getColor(); int intensity = m_intensity->getValue(); if (cellSelection) { std::set<TRasterImage *> images; int r0, c0, r1, c1; cellSelection->getSelectedCells(r0, c0, r1, c1); TXsheet *xsheet = TApp::instance()->getCurrentXsheet()->getXsheet(); bool oneImageChanged = false; int c, r; TUndoManager::manager()->beginBlock(); for (c = c0; c <= c1; c++) for (r = r0; r <= r1; r++) { TXshCell cell = xsheet->getCell(r, c); TRasterImageP rasImage = (TRasterImageP)cell.getImage(true); if (!rasImage) continue; if (images.find(rasImage.getPointer()) != images.end()) continue; TRaster32P ras = rasImage->getRaster(); if (!ras) continue; images.insert(rasImage.getPointer()); TUndoManager::manager()->add(new TLineFadeUndo(color, intensity, r, c, ras->clone())); oneImageChanged = true; onChange(ras, ras, color, intensity); TXshSimpleLevel *simpleLevel = cell.getSimpleLevel(); assert(simpleLevel); simpleLevel->touchFrame(cell.getFrameId()); simpleLevel->setDirtyFlag(true); IconGenerator::instance()->invalidate(simpleLevel, cell.getFrameId()); } TUndoManager::manager()->endBlock(); images.clear(); if (oneImageChanged) { close(); return; } } TFilmstripSelection *filmstripSelection = dynamic_cast<TFilmstripSelection *>(TSelection::getCurrent()); if (filmstripSelection) { TXshSimpleLevel *simpleLevel = TApp::instance()->getCurrentLevel()->getSimpleLevel(); if (simpleLevel) { std::set<TFrameId> fids = filmstripSelection->getSelectedFids(); bool oneImageChanged = false; for (auto const& fid : fids) { TRasterImageP rasImage = (TRasterImageP)simpleLevel->getFrame(fid, true); ; if (!rasImage) continue; TRaster32P ras = rasImage->getRaster(); if (!ras) continue; oneImageChanged = true; onChange(ras, ras, color, intensity); simpleLevel->touchFrame(fid); simpleLevel->setDirtyFlag(true); IconGenerator::instance()->invalidate(simpleLevel, fid); } if (oneImageChanged) { close(); return; } } } DVGui::error(QObject::tr("The current selection is invalid.")); return; }
int TApp::getCurrentImageType() { /*-- 現在のセルの種類に関係無く、Splineを選択中はベクタを編集できるようにする * --*/ if (getCurrentObject()->isSpline()) return TImage::VECTOR; TXshSimpleLevel *sl = 0; if (getCurrentFrame()->isEditingScene()) { int row = getCurrentFrame()->getFrame(); int col = getCurrentColumn()->getColumnIndex(); if (col < 0) #ifdef LINETEST return TImage::RASTER; #else { int levelType = Preferences::instance()->getDefLevelType(); return (levelType == PLI_XSHLEVEL) ? TImage::VECTOR : // RASTER image type includes both TZI_XSHLEVEL (levelType == TZP_XSHLEVEL) ? TImage::TOONZ_RASTER : TImage::RASTER; // and OVL_XSHLEVEL level types } #endif TXsheet *xsh = getCurrentXsheet()->getXsheet(); TXshCell cell = xsh->getCell(row, col); if (cell.isEmpty()) { int r0, r1; xsh->getCellRange(col, r0, r1); if (0 <= r0 && r0 <= r1) { /*-- Columnに格納されている一番上のLevelのTypeに合わせる--*/ cell = xsh->getCell(r0, col); } else /*-- Columnが空の場合 --*/ { #ifdef LINETEST return TImage::RASTER; #else int levelType = Preferences::instance()->getDefLevelType(); return (levelType == PLI_XSHLEVEL) ? TImage::VECTOR : (levelType == TZP_XSHLEVEL) ? TImage::TOONZ_RASTER : TImage::RASTER; #endif } } sl = cell.getSimpleLevel(); } else if (getCurrentFrame()->isEditingLevel()) sl = getCurrentLevel()->getSimpleLevel(); if (sl) { switch (sl->getType()) { case TZP_XSHLEVEL: return TImage::TOONZ_RASTER; case OVL_XSHLEVEL: return TImage::RASTER; case PLI_XSHLEVEL: default: return TImage::VECTOR; case MESH_XSHLEVEL: return TImage::MESH; } } return TImage::VECTOR; }
void execute() override { TColumnSelection *selection = dynamic_cast<TColumnSelection *>(TSelection::getCurrent()); if (!selection) { DVGui::warning( tr("It is not possible to merge tlv columns because no column was " "selected.")); return; } std::set<int> indices = selection->getIndices(); if (indices.size() < 2) { DVGui::warning( tr("It is not possible to merge tlv columns because at least two " "columns have to be selected.")); return; } std::set<int>::iterator it = indices.begin(); int destColumn = *it; TCellSelection::Range cells; cells.m_c0 = cells.m_c1 = destColumn; TXshColumn *column = TApp::instance()->getCurrentXsheet()->getXsheet()->getColumn( destColumn); column->getRange(cells.m_r0, cells.m_r1); // column->getLevelColumn() TFilePath newLevelPath; TXshCell c = TApp::instance()->getCurrentXsheet()->getXsheet()->getCell( cells.m_r0, destColumn); if (!c.isEmpty() && c.getSimpleLevel()) newLevelPath = c.getSimpleLevel()->getPath(); if (MergeCmappedDialog(newLevelPath).exec() != QDialog::Accepted) return; it = indices.begin(); for (; it != indices.end(); ++it) if (!checkColumnValidity(*it)) return; DVGui::ProgressDialog progress(tr("Merging Tlv Levels..."), QString(), 0, indices.size() - 1, TApp::instance()->getMainWindow()); progress.setWindowModality(Qt::WindowModal); progress.setWindowTitle(tr("Merging Tlv Levels...")); progress.setValue(0); progress.show(); QCoreApplication::instance()->processEvents(); TUndoManager::manager()->beginBlock(); cloneColumn(cells, newLevelPath); it = indices.begin(); ++it; for (int count = 0; it != indices.end();) { int index = *it; it++; mergeCmapped(destColumn, index - count, it == indices.end() ? QString::fromStdWString(newLevelPath.getWideString()) : "", false); ColumnCmd::deleteColumn(index - count); progress.setValue(++count); QCoreApplication::instance()->processEvents(); } TUndoManager::manager()->endBlock(); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); }
} //----------------------------------------------------------------------------- static inline bool doStandardOnionSkin(StageBuilder *sb, TXsheet *xsh, int level, int col) { const OnionSkinMask &osm = sb->m_onionSkinMask; return level == sb->m_xsheetLevel && osm.isEnabled() && !osm.isEmpty() && (osm.isWholeScene() || col == sb->m_currentColumnIndex || locals::hasOnionSkinnedMeshParent(sb, xsh, col)); } }; // locals if (m_onionSkinMask.isShiftTraceEnabled() && col == m_currentColumnIndex) { TXshCell cell = xsh->getCell(row, col); int r = row - 1; // r,col can be a hold. find its starting point for (; r - 1 >= 0 && xsh->getCell(r - 1, col) == cell; r--) ; if (cell.isEmpty()) r--; if (r >= 0 && (cell.getSimpleLevel() == 0 || xsh->getCell(r, col).getSimpleLevel() == cell.getSimpleLevel())) { m_shiftTraceGhostId = FIRST_GHOST; addCell(players, scene, xsh, r, col, level); } TXshCell otherCell;
bool TXshMeshColumn::canSetCell(const TXshCell &cell) const { TXshSimpleLevel *sl = cell.getSimpleLevel(); return cell.isEmpty() || (sl && sl->getType() == MESH_XSHLEVEL); }