Light Table
This commit is contained in:
parent
580fc67bdc
commit
24ae8225fa
|
@ -46,7 +46,8 @@ public:
|
|||
};
|
||||
|
||||
public:
|
||||
OnionSkinMask() : m_enabled(false), m_wholeScene(false) {}
|
||||
OnionSkinMask()
|
||||
: m_enabled(false), m_wholeScene(false), m_LightTableStatus(false) {}
|
||||
|
||||
void clear();
|
||||
|
||||
|
@ -106,6 +107,10 @@ since underlying onion-skinned drawings must be visible.
|
|||
|
||||
bool isShiftTraceEnabled() const { return m_shiftTraceStatus != DISABLED; }
|
||||
|
||||
bool getLightTableStatus() const { return m_LightTableStatus; }
|
||||
void setLightTableStatus(bool status) { m_LightTableStatus = status; }
|
||||
bool isLightTableEnabled() const { return m_LightTableStatus; }
|
||||
|
||||
const TAffine getShiftTraceGhostAff(int index) const {
|
||||
return m_ghostAff[index];
|
||||
}
|
||||
|
@ -144,6 +149,8 @@ private:
|
|||
int m_ghostFrame[2]; // relative frame position of the ghosts
|
||||
QList<int> m_ghostFlipKeys; // If F1, F2 or F3 key is pressed, then only
|
||||
// display the corresponding ghost
|
||||
|
||||
bool m_LightTableStatus;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
|
|
|
@ -114,6 +114,8 @@ public:
|
|||
|
||||
TPixel32 m_filterColor;
|
||||
|
||||
static bool m_isLightTableEnabled;
|
||||
|
||||
public:
|
||||
Player();
|
||||
|
||||
|
|
53
toonz/sources/toonz/icons/dark/actions/16/light_table.svg
Normal file
53
toonz/sources/toonz/icons/dark/actions/16/light_table.svg
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
xml:space="preserve"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"
|
||||
id="svg5"
|
||||
sodipodi:docname="light_table.svg"
|
||||
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs9" /><sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="true"
|
||||
inkscape:snap-grids="false"
|
||||
inkscape:zoom="44.9375"
|
||||
inkscape:cx="6.6870654"
|
||||
inkscape:cy="7.8553547"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1141"
|
||||
inkscape:window-x="-7"
|
||||
inkscape:window-y="-7"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="shift_and_trace"><inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid925" /></sodipodi:namedview>
|
||||
<g
|
||||
id="shift_and_trace"
|
||||
transform="matrix(0.70097357,0,0,0.70097357,4.7970567,4.7844228)">
|
||||
<rect
|
||||
id="bg"
|
||||
x="0"
|
||||
y="0"
|
||||
width="16"
|
||||
height="16"
|
||||
style="fill:#878787;fill-opacity:0" />
|
||||
<path
|
||||
id="shift"
|
||||
d="M 6.7356647,15.103979 C 6.7366076,14.708023 6.4077051,14.386477 6.0017421,14.386474 l -2.9357132,-2.1e-5 c -0.4059627,-3e-6 -0.7339308,0.320617 -0.7339339,0.717493 -3.2e-6,0.396874 0.3288994,0.718419 0.7339226,0.717504 l 2.935713,2.2e-5 c 0.4059629,3e-6 0.7348705,-0.321536 0.7339341,-0.717493 z m 1.5323108,-2.458773 c 3.9e-6,-0.395036 -0.3288994,-0.716582 -0.7339224,-0.717503 l -5.8723656,8.74e-4 c -0.4050232,-9.23e-4 -0.73393072,0.320616 -0.73393388,0.717493 -9.4291e-4,0.395956 0.32795958,0.717501 0.73392248,0.717505 l 5.8714266,4.4e-5 c 0.4059627,3e-6 0.7348701,-0.321537 0.7348728,-0.718413 z M 3.1243079,5.7720927 C 3.4229159,4.0536703 -1.7838071,0.85467468 4.9496525,-3.9481261 6.3818544,-5.9935125 3.0365196,-4.9663296 3.2084716,-4.9709792 0.83890767,-3.6812481 -1.6710515,-1.6572026 -1.0966028,2.5446016 1.371745,6.9013165 2.5293574,6.5043151 3.1243079,5.7720927 Z m -6.6009662,-3.8644872 9.454e-4,-0.7174986 c -9.049e-4,-4.357358 3.61613962,-7.8933773 8.0742136,-7.8933432 4.4561948,3.39e-5 8.0731833,3.5361084 8.0740863,7.8934664 -9.48e-4,1.0868129 -0.361813,2.1433065 -1.028085,3.0133031 L 8.2670796,8.6058816 8.2670651,9.5761849 C 8.267998,10.369017 7.6101835,11.012097 6.7991968,11.011172 l -4.4035696,-3.4e-5 C 1.5855809,11.011132 0.92776981,10.368042 0.92778222,9.5761299 L 0.92779742,8.6058258 -2.8893415,3.6301583 C -3.2708676,3.1340615 -3.4766633,2.5286417 -3.4766583,1.9076055 c 0.6810244,5.2e-6 0.6810244,0 0,0 z"
|
||||
style="stroke-width:1.31402"
|
||||
sodipodi:nodetypes="ccsscscscccccscccccccscccccsscccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
|
@ -2332,6 +2332,8 @@ void MainWindow::defineActions() {
|
|||
"view_vector_as_raster");
|
||||
else
|
||||
RasterizePliToggleAction = 0;
|
||||
createToggle(MI_ToggleLightTable, QT_TR_NOOP("Light Table"), "", false,
|
||||
MenuViewCommandType, "light_table");
|
||||
|
||||
// Menu - Panes
|
||||
|
||||
|
|
|
@ -613,6 +613,7 @@ void TopBar::loadMenubar() {
|
|||
addMenuItem(viewMenu, MI_GCheck);
|
||||
addMenuItem(viewMenu, MI_ACheck);
|
||||
viewMenu->addSeparator();
|
||||
addMenuItem(viewMenu, MI_ToggleLightTable);
|
||||
addMenuItem(viewMenu, MI_ShiftTrace);
|
||||
addMenuItem(viewMenu, MI_EditShift);
|
||||
addMenuItem(viewMenu, MI_NoShift);
|
||||
|
|
|
@ -511,4 +511,6 @@
|
|||
#define MI_PrevTaggedFrame "MI_PrevTaggedFrame"
|
||||
#define MI_ClearTags "MI_ClearTags"
|
||||
|
||||
#define MI_ToggleLightTable "MI_ToggleLightTable"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -766,6 +766,25 @@ public:
|
|||
}
|
||||
} flipPrevStrokeDirectionCommand;
|
||||
|
||||
class TLightTableToggleCommand final : public MenuItemHandler {
|
||||
public:
|
||||
TLightTableToggleCommand() : MenuItemHandler(MI_ToggleLightTable) {}
|
||||
void execute() override {
|
||||
CommandManager *cm = CommandManager::instance();
|
||||
QAction *action = cm->getAction(MI_ToggleLightTable);
|
||||
OnionSkinMask osm =
|
||||
TApp::instance()->getCurrentOnionSkin()->getOnionSkinMask();
|
||||
osm.setLightTableStatus(action->isChecked());
|
||||
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
|
||||
TApp::instance()->getCurrentOnionSkin()->setOnionSkinMask(osm);
|
||||
}
|
||||
|
||||
bool isChecked(CommandId id) const {
|
||||
QAction *action = CommandManager::instance()->getAction(id);
|
||||
return action != 0 && action->isChecked();
|
||||
}
|
||||
} TLightTableToggleCommand;
|
||||
|
||||
//=============================================================================
|
||||
// SceneViewer
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -474,6 +474,8 @@
|
|||
<file>icons/dark/actions/16/shift_and_trace_no_shift.svg</file>
|
||||
<file>icons/dark/actions/16/shift_and_trace_reset.svg</file>
|
||||
|
||||
<file>icons/dark/actions/16/light_table.svg</file>
|
||||
|
||||
<!-- Folders -->
|
||||
<file>icons/dark/actions/18/folder.svg</file>
|
||||
<file>icons/dark/actions/18/folder_on.svg</file>
|
||||
|
|
|
@ -1408,6 +1408,7 @@ void RowArea::contextMenuEvent(QContextMenuEvent *event) {
|
|||
menu->addAction(cmdManager->getAction(MI_DrawingSubForward));
|
||||
menu->addAction(cmdManager->getAction(MI_DrawingSubBackward));
|
||||
menu->addSeparator();
|
||||
menu->addAction(cmdManager->getAction(MI_ToggleLightTable));
|
||||
menu->addAction(cmdManager->getAction(MI_ShiftTrace));
|
||||
menu->addAction(cmdManager->getAction(MI_EditShift));
|
||||
menu->addAction(cmdManager->getAction(MI_NoShift));
|
||||
|
|
|
@ -936,6 +936,7 @@ void Stage::visit(Visitor &visitor, const VisitArgs &args) {
|
|||
Player::m_firstBackOnionSkin = 0;
|
||||
Player::m_lastBackVisibleSkin = 0;
|
||||
Player::m_isShiftAndTraceEnabled = osm->isShiftTraceEnabled();
|
||||
Player::m_isLightTableEnabled = osm->isLightTableEnabled();
|
||||
sb.addFrame(sb.m_players, scene, xsh, row, 0, args.m_onlyVisible,
|
||||
args.m_checkPreviewVisibility);
|
||||
|
||||
|
@ -980,6 +981,7 @@ void Stage::visit(Visitor &visitor, TXshSimpleLevel *level, const TFrameId &fid,
|
|||
Player::m_firstBackOnionSkin = 0;
|
||||
Player::m_lastBackVisibleSkin = 0;
|
||||
Player::m_isShiftAndTraceEnabled = osm.isShiftTraceEnabled();
|
||||
Player::m_isLightTableEnabled = osm.isLightTableEnabled();
|
||||
sb.addSimpleLevelFrame(sb.m_players, level, fid);
|
||||
updateOnionSkinSize(sb.m_players);
|
||||
sb.visit(sb.m_players, visitor, isPlaying);
|
||||
|
|
|
@ -25,6 +25,7 @@ double Player::m_firstFrontOnionSkin = 0;
|
|||
double Player::m_firstBackOnionSkin = 0;
|
||||
double Player::m_lastBackVisibleSkin = 0;
|
||||
bool Player::m_isShiftAndTraceEnabled = false;
|
||||
bool Player::m_isLightTableEnabled = false;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -857,6 +857,10 @@ void RasterPainter::onVectorImage(TVectorImage *vi,
|
|||
int oldFrame = vPalette->getFrame();
|
||||
vPalette->setFrame(player.m_frame);
|
||||
|
||||
UCHAR useOpacity = player.m_opacity;
|
||||
if (player.m_isLightTableEnabled && !player.m_isCurrentColumn)
|
||||
useOpacity *= 0.30;
|
||||
|
||||
if (player.m_onionSkinDistance != c_noOnionSkin) {
|
||||
TPixel32 frontOnionColor, backOnionColor;
|
||||
|
||||
|
@ -875,6 +879,8 @@ void RasterPainter::onVectorImage(TVectorImage *vi,
|
|||
((player.m_onionSkinDistance == 0)
|
||||
? 0.1
|
||||
: OnionSkinMask::getOnionSkinFade(player.m_onionSkinDistance));
|
||||
if (player.m_isLightTableEnabled && !player.m_isCurrentColumn) m[3] *= 0.30;
|
||||
|
||||
c[0] = (1.0 - m[3]) * bgColor.r, c[1] = (1.0 - m[3]) * bgColor.g,
|
||||
c[2] = (1.0 - m[3]) * bgColor.b;
|
||||
c[3] = 0.0;
|
||||
|
@ -882,10 +888,10 @@ void RasterPainter::onVectorImage(TVectorImage *vi,
|
|||
cf = new TGenericColorFunction(m, c);
|
||||
} else if (player.m_filterColor != TPixel::Black) {
|
||||
TPixel32 colorScale = player.m_filterColor;
|
||||
colorScale.m = player.m_opacity;
|
||||
colorScale.m = useOpacity;
|
||||
cf = new TColumnColorFilterFunction(colorScale);
|
||||
} else if (player.m_opacity < 255)
|
||||
cf = new TTranspFader(player.m_opacity / 255.0);
|
||||
} else if (useOpacity < 255)
|
||||
cf = new TTranspFader(useOpacity / 255.0);
|
||||
|
||||
TVectorRenderData rd(m_viewAff * player.m_placement, TRect(), vPalette, cf,
|
||||
true // alpha enabled
|
||||
|
@ -1011,6 +1017,10 @@ void RasterPainter::onRasterImage(TRasterImage *ri,
|
|||
bbox *= convert(m_clipRect);
|
||||
if (bbox.isEmpty()) return;
|
||||
|
||||
UCHAR useOpacity = player.m_opacity;
|
||||
if (player.m_isLightTableEnabled && !player.m_isCurrentColumn)
|
||||
useOpacity *= 0.30;
|
||||
|
||||
int alpha = 255;
|
||||
Node::OnionMode onionMode = Node::eOnionSkinNone;
|
||||
if (player.m_onionSkinDistance != c_noOnionSkin) {
|
||||
|
@ -1023,6 +1033,8 @@ void RasterPainter::onRasterImage(TRasterImage *ri,
|
|||
? 0.9
|
||||
: (1.0 - OnionSkinMask::getOnionSkinFade(
|
||||
player.m_onionSkinDistance));
|
||||
if (player.m_isLightTableEnabled && !player.m_isCurrentColumn)
|
||||
onionSkiFade *= 0.30;
|
||||
alpha = tcrop(tround(onionSkiFade * 255.0), 0, 255);
|
||||
if (player.m_isShiftAndTraceEnabled &&
|
||||
!Preferences::instance()->areOnionColorsUsedForShiftAndTraceGhosts())
|
||||
|
@ -1034,8 +1046,8 @@ void RasterPainter::onRasterImage(TRasterImage *ri,
|
|||
: ((player.m_onionSkinDistance < 0) ? Node::eOnionSkinBack
|
||||
: Node::eOnionSkinNone);
|
||||
}
|
||||
} else if (player.m_opacity < 255)
|
||||
alpha = player.m_opacity;
|
||||
} else if (useOpacity < 255)
|
||||
alpha = useOpacity;
|
||||
TXshSimpleLevel *sl = player.m_sl;
|
||||
bool doPremultiply = false;
|
||||
bool whiteTransp = false;
|
||||
|
@ -1074,6 +1086,10 @@ void RasterPainter::onToonzImage(TToonzImage *ti, const Stage::Player &player) {
|
|||
bbox *= convert(m_clipRect);
|
||||
if (bbox.isEmpty()) return;
|
||||
|
||||
UCHAR useOpacity = player.m_opacity;
|
||||
if (player.m_isLightTableEnabled && !player.m_isCurrentColumn)
|
||||
useOpacity *= 0.30;
|
||||
|
||||
int alpha = 255;
|
||||
Node::OnionMode onionMode = Node::eOnionSkinNone;
|
||||
if (player.m_onionSkinDistance != c_noOnionSkin) {
|
||||
|
@ -1086,6 +1102,8 @@ void RasterPainter::onToonzImage(TToonzImage *ti, const Stage::Player &player) {
|
|||
? 0.9
|
||||
: (1.0 - OnionSkinMask::getOnionSkinFade(
|
||||
player.m_onionSkinDistance));
|
||||
if (player.m_isLightTableEnabled && !player.m_isCurrentColumn)
|
||||
onionSkiFade *= 0.30;
|
||||
alpha = tcrop(tround(onionSkiFade * 255.0), 0, 255);
|
||||
|
||||
if (player.m_isShiftAndTraceEnabled &&
|
||||
|
@ -1099,8 +1117,8 @@ void RasterPainter::onToonzImage(TToonzImage *ti, const Stage::Player &player) {
|
|||
: Node::eOnionSkinNone);
|
||||
}
|
||||
|
||||
} else if (player.m_opacity < 255)
|
||||
alpha = player.m_opacity;
|
||||
} else if (useOpacity < 255)
|
||||
alpha = useOpacity;
|
||||
|
||||
m_nodes.push_back(Node(r, ti->getPalette(), alpha, aff, ti->getSavebox(),
|
||||
bbox, player.m_frame, player.m_isCurrentColumn,
|
||||
|
@ -1436,6 +1454,10 @@ void onMeshImage(TMeshImage *mi, const Stage::Player &player,
|
|||
}
|
||||
}
|
||||
|
||||
UCHAR useOpacity = player.m_opacity;
|
||||
if (player.m_isLightTableEnabled && !player.m_isCurrentColumn)
|
||||
useOpacity *= 0.30;
|
||||
|
||||
if (deformation) {
|
||||
// Retrieve the associated plastic deformers data (this may eventually
|
||||
// update the deforms)
|
||||
|
@ -1455,7 +1477,7 @@ void onMeshImage(TMeshImage *mi, const Stage::Player &player,
|
|||
|
||||
// Draw edges next
|
||||
if (drawMeshes) {
|
||||
glColor4d(0.0, 1.0, 0.0, 0.7 * player.m_opacity / 255.0); // Green
|
||||
glColor4d(0.0, 1.0, 0.0, 0.7 * useOpacity / 255.0); // Green
|
||||
tglDrawEdges(*mi, dataGroup); // The mesh must be deformed
|
||||
}
|
||||
} else {
|
||||
|
@ -1469,7 +1491,7 @@ void onMeshImage(TMeshImage *mi, const Stage::Player &player,
|
|||
|
||||
// Just draw the mesh image next
|
||||
if (drawMeshes) {
|
||||
glColor4d(0.0, 1.0, 0.0, 0.7 * player.m_opacity / 255.0); // Green
|
||||
glColor4d(0.0, 1.0, 0.0, 0.7 * useOpacity / 255.0); // Green
|
||||
tglDrawEdges(*mi);
|
||||
}
|
||||
}
|
||||
|
@ -1494,6 +1516,10 @@ void onPlasticDeformedImage(TStageObject *playerObj,
|
|||
// Deal with color scaling due to transparency / onion skin
|
||||
double pixScale[4] = {1.0, 1.0, 1.0, 1.0};
|
||||
|
||||
UCHAR useOpacity = player.m_opacity;
|
||||
if (player.m_isLightTableEnabled && !player.m_isCurrentColumn)
|
||||
useOpacity *= 0.30;
|
||||
|
||||
if (doOnionSkin) {
|
||||
if (onionSkinImage) {
|
||||
TPixel32 frontOnionColor, backOnionColor;
|
||||
|
@ -1512,8 +1538,8 @@ void onPlasticDeformedImage(TStageObject *playerObj,
|
|||
pixScale[1] = (refColor.g / 255.0) * pixScale[3];
|
||||
pixScale[2] = (refColor.b / 255.0) * pixScale[3];
|
||||
}
|
||||
} else if (player.m_opacity < 255) {
|
||||
pixScale[3] = player.m_opacity / 255.0;
|
||||
} else if (useOpacity < 255) {
|
||||
pixScale[3] = useOpacity / 255.0;
|
||||
pixScale[0] = pixScale[1] = pixScale[2] = 0.0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue