Skip to content

Commit

Permalink
Merge pull request #166 from rewbs/extra-functions-info
Browse files Browse the repository at this point in the history
Reverse generation, last_frame, prompt lock, recompute_if(), dangerous(), common prompt start/end,  maths on value edit
  • Loading branch information
rewbs authored Jul 8, 2023
2 parents 4310a9d + fb94b34 commit 67552b5
Show file tree
Hide file tree
Showing 15 changed files with 1,489 additions and 153 deletions.
281 changes: 277 additions & 4 deletions src/Deforum.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ TimeAgo.addDefaultLocale(en);
jest.mock('react-chartjs-2', () => ({
Line: () => null
}));
// jest.mock('chartjs-plugin-crosshair', () => ({
// CrosshairPlugin: () => null
// }));
// jest.mock('chartjs-plugin-dragdata', () => null);
jest.mock('chartjs-plugin-annotation', () => ({
annotationPlugin: () => null
}));
Expand Down Expand Up @@ -9058,3 +9054,280 @@ test('info_match_gap, info_match_progress and bez offset', async () => {
expect(screen.getByTestId("output")).toMatchSnapshot();
});


test('common_prompt_append', async () => {
const fixture = {
"prompts": {
"format": "v2",
"enabled": true,
"commonPrompt": {
"name": "Common",
"positive": "common.pos",
"negative": "common.neg",
"allFrames": true,
"from": 0,
"to": 119,
"overlap": {
"inFrames": 0,
"outFrames": 0,
"type": "none",
"custom": "prompt_weight_1"
}
},
"commonPromptPos": "append",
"promptList": [
{
"name": "Prompt 1",
"positive": "my prompt1",
"negative": "my negprompt1",
"allFrames": false,
"from": 0,
"to": 6,
"overlap": {
"inFrames": 0,
"outFrames": 2,
"type": "linear",
"custom": "prompt_weight_1"
}
},
{
"positive": "my prompt2",
"negative": "my negprompt2",
"from": 5,
"to": 10,
"allFrames": false,
"name": "Prompt 2",
"overlap": {
"inFrames": 2,
"outFrames": 0,
"type": "linear",
"custom": "prompt_weight_2"
}
}
]
},
"managedFields": [],
"displayedFields": [],
"keyframes": [
{
"frame": 0,
},
{
"frame": 10,
}
],
"timeSeries": [],
"keyframeLock": "frames",
}
await loadAndRender(fixture);
expect(screen.getByTestId("output")).toMatchSnapshot();
});


test('common_prompt_prepend', async () => {
const fixture = {
"prompts": {
"format": "v2",
"enabled": true,
"commonPrompt": {
"name": "Common",
"positive": "common.pos",
"negative": "common.neg",
"allFrames": true,
"from": 0,
"to": 119,
"overlap": {
"inFrames": 0,
"outFrames": 0,
"type": "none",
"custom": "prompt_weight_1"
}
},
"commonPromptPos": "prepend",
"promptList": [
{
"name": "Prompt 1",
"positive": "my prompt1",
"negative": "my negprompt1",
"allFrames": false,
"from": 0,
"to": 6,
"overlap": {
"inFrames": 0,
"outFrames": 2,
"type": "linear",
"custom": "prompt_weight_1"
}
},
{
"positive": "my prompt2",
"negative": "my negprompt2",
"from": 5,
"to": 10,
"allFrames": false,
"name": "Prompt 2",
"overlap": {
"inFrames": 2,
"outFrames": 0,
"type": "linear",
"custom": "prompt_weight_2"
}
}
]
},
"managedFields": [],
"displayedFields": [],
"keyframes": [
{
"frame": 0,
},
{
"frame": 10,
}
],
"timeSeries": [],
"keyframeLock": "frames",
}
await loadAndRender(fixture);
expect(screen.getByTestId("output")).toMatchSnapshot();
});

test('reverse_render_standard', async () => {
const fixture = {
"prompts": {
"format": "v2",
"enabled": true,
"commonPrompt": {
"name": "Common",
"positive": "",
"negative": "",
"allFrames": true,
"from": 0,
"to": 119,
"overlap": {
"inFrames": 0,
"outFrames": 0,
"type": "none",
"custom": "prompt_weight_1"
}
},
"commonPromptPos": "append",
"promptList": [
{
"name": "Prompt 1",
"positive": "Test ${prompt_weight_1}",
"negative": "",
"allFrames": false,
"from": 0,
"to": 10,
"overlap": {
"inFrames": 0,
"outFrames": 0,
"type": "none",
"custom": "prompt_weight_1"
}
}
]
},
"managedFields": [
"zoom",
"angle",
"prompt_weight_1"
],
"keyframes": [
{
"frame": 0,
"zoom": 1,
"seed": -1,
"prompt_weight_1": 0,
"angle": 0
},
{
"frame": 5,
"zoom": 0.5,
"angle": 5
},
{
"frame": 10,
"zoom": 1.5,
"prompt_weight_1": 1,
"angle": -5
}
],
"timeSeries": [],
"keyframeLock": "frames",
"reverseRender": false,
}
await loadAndRender(fixture);
expect(screen.getByTestId("output")).toMatchSnapshot();
});

test('reverse_render_reversed', async () => {
const fixture = {
"prompts": {
"format": "v2",
"enabled": true,
"commonPrompt": {
"name": "Common",
"positive": "",
"negative": "",
"allFrames": true,
"from": 0,
"to": 119,
"overlap": {
"inFrames": 0,
"outFrames": 0,
"type": "none",
"custom": "prompt_weight_1"
}
},
"commonPromptPos": "append",
"promptList": [
{
"name": "Prompt 1",
"positive": "Test ${prompt_weight_1}",
"negative": "",
"allFrames": false,
"from": 0,
"to": 10,
"overlap": {
"inFrames": 0,
"outFrames": 0,
"type": "none",
"custom": "prompt_weight_1"
}
}
]
},
"managedFields": [
"zoom",
"angle",
"prompt_weight_1"
],
"keyframes": [
{
"frame": 0,
"zoom": 1,
"seed": -1,
"prompt_weight_1": 0,
"angle": 0
},
{
"frame": 5,
"zoom": 0.5,
"angle": 5
},
{
"frame": 10,
"zoom": 1.5,
"prompt_weight_1": 1,
"angle": -5
}
],
"timeSeries": [],
"keyframeLock": "frames",
"reverseRender": true,
}
await loadAndRender(fixture);
expect(screen.getByTestId("output")).toMatchSnapshot();
});
56 changes: 53 additions & 3 deletions src/FunctionDoc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ const MiniParseq = ({ keyframes, fields }: MiniParseqProps) => {
enabled: false,
promptList: [],
format: "v2",
commonPromptPos: 'append',
commonPrompt: {
name: 'Common',
positive: "",
Expand Down Expand Up @@ -187,6 +188,7 @@ type DocEntry = {
function_ref?: ParseqFunction
examples: {
description?: string,
fields?: string[],
keyframeOverrides: ParseqKeyframes,
}[]
};
Expand Down Expand Up @@ -861,10 +863,55 @@ const FunctionDoc = () => {
]
}
]
},
{
category: "Meta",
name: "**recompute_if()**: compute a value only if a condition is true, else re-use precomputed value.",
function_ref: functionLibrary.recompute_if,
examples: [
{
description: "Use a new random value on every 'snare' keyframe.",
keyframeOverrides: [
{ frame: 0, translation_z_i: 'recompute_if(f==info_match_prev("snare"), rand(0, 100))' },
{ frame: 15, info: "snare 0", },
{ frame: 30, },
{ frame: 45, info: "snare 1", },
{ frame: 60, info: "snare 2", },
{ frame: 75, },
{ frame: 90, info: "snare 3", },
{ frame: 99, info: "snare 4", },
]
},
{
description: "Bezier to a new random value on every 'snare' keyframe.",
keyframeOverrides: [
{ frame: 0, translation_z_i: 'bez(start=computed_at(info_match_prev("snare")-1,0), delta=recompute_if(f==info_match_prev("snare"), rand(-20,20)), os=info_match_progress("snare"), curve="easeOut3")' },
{ frame: 15, info: "snare 0", },
{ frame: 30, },
{ frame: 45, info: "snare 1", },
{ frame: 60, info: "snare 2", },
{ frame: 75, },
{ frame: 90, info: "snare 3", },
{ frame: 99, info: "snare 4", },
]
}
]
},
{
category: "Meta",
name: "**dangerous()**: access values of other fields",
description: "**This is an experimental function with no guarantees.** If you use it, be prepared for errors and backwards compatibility issues.",
function_ref: functionLibrary.dangerous,
examples: [
{
description: "Make x translation depend on y rotation.",
fields: ["rotation_3d_y", "translation_x"],
keyframeOverrides: [
{ frame: 0, rotation_3d_y_i: 'sin(p=50, a=10)', translation_x_i: '-dangerous("rotation_3d_y")*512/90'},
]
}
]
}



]

const renderDocEntries = () => {
Expand Down Expand Up @@ -898,6 +945,9 @@ const FunctionDoc = () => {
entry.examples.map((example) => {
const miniParseqConfig = _.cloneDeep(miniParseqDefaults);
miniParseqConfig.keyframes = _.defaultsDeep(example.keyframeOverrides, miniParseqDefaults.keyframes);
if (example.fields) {
miniParseqConfig.fields = example.fields;
}
return <>
<Typography><ReactMarkdown children={example.description || ""} /></Typography>
<MiniParseq {...miniParseqConfig} />
Expand Down
Loading

0 comments on commit 67552b5

Please sign in to comment.