Skip to content

Add hold and ghost #781

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,12 @@ Paint nodes are used primarily to store per frame annotations. Below *id* is the
| pen: *id* : *frame* : *user* .cap | int | 1 | The cap style of the stroke:NoCap = 0; SquareCap = 1; RoundCap = 2; |
| pen: *id* : *frame* : *user* .splat | int | 1 | |
| pen: *id* : *frame* : *user* .mode | int | 1 | Drawing mode of the stroke (Default if missing is 0):RenderOverMode = 0; RenderEraseMode = 1; |
| pen: *id* : *frame* : *user* .startFrame | int | 1 | The first frame on which the pen stroke should be displayed |
| pen: *id* : *frame* : *user* .duration | int | 1 | The number of frames on which the pen stroke should be displayed |
| pen: *id* : *frame* : *user* .hold | int | 1 | Enable holding strokes based on their duration and startFrame properties |
| pen: *id* : *frame* : *user* .ghost | int | 1 | Enable ghosting strokes based on their duration, startFrame, ghostBefore and ghostAfter properties |
| pen: *id* : *frame* : *user* .ghostBefore | int | 1 | The number of frames on which to display the ghosted stroke before the actual stroke |
| pen: *id* : *frame* : *user* .ghostAfter | int | 1 | The number of frames on which to display the ghosted stroke after the actual stroke |
| text: *id* : *frame* : *user* .position | float[2] | 1 | Location of the text in the normalized coordinate system |
| text: *id* : *frame* : *user* .color | float[4] | 1 | The color of the text |
| text: *id* : *frame* : *user* .spacing | float | 1 | The spacing of the text |
Expand All @@ -451,6 +457,12 @@ Paint nodes are used primarily to store per frame annotations. Below *id* is the
| text: *id* : *frame* : *user* .text | string | 1 | Content of the text |
| text: *id* : *frame* : *user* .origin | string | 1 | The origin of the text box. The position property will store the location of the origin, but the origin can be on any corner of the text box or centered in between. The valid possible values for origin are top-left, top-center, top-right, center-left, center-center, center-right, bottom-left, bottom-center, bottom-right, and the empty string (which is the default for backwards compatibility). |
| text: *id* : *frame* : *user* .debug | int | 1 | (unused) |
| text: *id* : *frame* : *user* .startFrame | int | 1 | The first frame on which the text box should be displayed |
| text: *id* : *frame* : *user* .duration | int | 1 | The number of frames on which the text box should be displayed |
| text: *id* : *frame* : *user* .hold | int | 1 | Enable holding text boxes based on their duration and startFrame properties |
| text: *id* : *frame* : *user* .ghost | int | 1 | Enable ghosting strokes based on their duration, startFrame, ghostBefore and ghostAfter properties |
| text: *id* : *frame* : *user* .ghostBefore | int | 1 | The number of frames on which to display the ghosted stroke before the actual stroke |
| text: *id* : *frame* : *user* .ghostAfter | int | 1 | The number of frames on which to display the ghosted stroke after the actual stroke |

## RVPrimaryConvert

Expand Down
73 changes: 50 additions & 23 deletions src/lib/ip/IPBaseNodes/IPBaseNodes/PaintIPNode.h
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
//
// Copyright (c) 2009 Tweak Software.
// All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2025 Autodesk, Inc. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef __IPGraph__PaintIPNode__h__
#define __IPGraph__PaintIPNode__h__
#include <iostream>
#include <IPCore/IPNode.h>
#include <IPCore/PaintCommand.h>
#include <TwkMath/Color.h>
#include <map>
#include <vector>

namespace IPCore
{
Expand Down Expand Up @@ -39,36 +38,62 @@ namespace IPCore
// Paint:: commands + per-command state local to this node.
//

struct LocalPolyLine : public Paint::PolyLine
class LocalCommand
{
public:
LocalCommand() = default;
virtual ~LocalCommand() = default;

int startFrame{};
int duration{};
int ghost{};
int hold{};
int ghostAfter{};
int ghostBefore{};
int eye{-1};

bool ghostOn{};
TwkMath::Col4f ghostColor{Color(0.0)};
};

class LocalPolyLine
: public Paint::PolyLine
, public LocalCommand
{
int eye;
public:
LocalPolyLine() = default;
};

struct LocalText : public Paint::Text
class LocalText
: public Paint::Text
, public LocalCommand
{
int eye;
public:
LocalText() = default;
};

typedef TwkMath::Vec4f Vec4;
typedef TwkMath::Vec3f Vec3;
typedef TwkMath::Vec2f Vec2;
typedef TwkMath::Box2f Box2;
typedef TwkMath::Mat44f Matrix;
typedef TwkMath::Col4f Color;
typedef std::vector<Vec2> PointVector;
typedef std::vector<std::string> FrameVector;
typedef std::map<Component*, LocalPolyLine> PenMap;
typedef std::map<Component*, LocalText> TextMap;
typedef std::map<int, Components> FrameMap;
using Vec4 = TwkMath::Vec4f;
using Vec3 = TwkMath::Vec3f;
using Vec2 = TwkMath::Vec2f;
using Box2 = TwkMath::Box2f;
using Matrix = TwkMath::Mat44f;
using Color = TwkMath::Col4f;
using PointVector = std::vector<Vec2>;
using FrameVector = std::vector<std::string>;
using LocalCommands = std::vector<LocalCommand*>;
using PenMap = std::map<Component*, LocalPolyLine>;
using TextMap = std::map<Component*, LocalText>;
using FrameMap = std::map<int, Components>;

PaintIPNode(const std::string& name, const NodeDefinition* def,
IPGraph* graph, GroupIPNode* group);
virtual ~PaintIPNode();

virtual IPImage* evaluate(const Context&);
IPImage* evaluate(const Context& context) override;

virtual void propertyChanged(const Property*);
virtual void readCompleted(const std::string&, unsigned int);
void propertyChanged(const Property* proprety) override;
void readCompleted(const std::string& typeName,
unsigned int version) override;

protected:
void compilePenComponent(Component*);
Expand All @@ -78,10 +103,12 @@ namespace IPCore
private:
PenMap m_penStrokes;
TextMap m_texts;
LocalCommands m_commands;
Paint::PushFrameBuffer m_pushFBO;
Paint::PopFrameBuffer m_popFBO;
FrameMap m_frameMap;
Component* m_tag;
std::mutex m_commandsMutex;
};

} // namespace IPCore
Expand Down
11 changes: 4 additions & 7 deletions src/lib/ip/IPBaseNodes/OverlayIPNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,12 @@ namespace IPCore
namespace
{

static void initializeOutline(Paint::PolyLine& outline,
const Vec2f* points, size_t npoints,
TwkPaint::Color oc, float outlineWidth,
const string& brush)
void initializeOutline(Paint::PolyLine& outline, const Vec2f* points,
size_t npoints, TwkPaint::Color oc,
float outlineWidth, const string& brush)
{
// these polyline owns the memory of their own points
outline.points = new Vec2f[npoints];
memcpy((void*)outline.points, (void*)points,
npoints * sizeof(Vec2f));
outline.points.assign(points->begin(), points->end());
outline.ownPoints = true;

outline.npoints = npoints;
Expand Down
Loading
Loading