4
4
// SPDX-License-Identifier: Apache-2.0
5
5
//
6
6
#include < IPBaseNodes/PaintIPNode.h>
7
+ #include < IPCore/PaintCommand.h>
7
8
#include < IPCore/Exception.h>
8
9
#include < IPCore/IPGraph.h>
9
10
#include < TwkGLText/TwkGLText.h>
10
11
#include < mutex>
11
12
#include < stl_ext/string_algo.h>
12
13
#include < cstdlib>
13
14
#include < IPCore/ShaderCommon.h>
15
+ #include < tuple>
14
16
15
17
namespace
16
18
{
17
19
using namespace IPCore ;
20
+ using PerFramePaintCommands = std::map<int , PaintIPNode::LocalCommands>;
18
21
19
22
// Calculates the opacity based on the distance from the annotated frame to
20
23
// make the ghosted annotation more visible closer to the frame and less
@@ -42,17 +45,12 @@ namespace
42
45
return ghostOpacity;
43
46
}
44
47
45
- PaintIPNode::LocalCommands
46
- generateVisibleCommands (const PaintIPNode::LocalCommands& commands,
47
- const int frame, const size_t eye)
48
+ auto
49
+ separateCommandsByFrameGroup (const PaintIPNode::LocalCommands& commands,
50
+ const int frame, const size_t eye)
48
51
{
49
52
PaintIPNode::LocalCommands
50
- allCommands; // visible commands, including hold and ghost
51
- PaintIPNode::LocalCommands
52
- CurrentFrameCommands; // visible commands, excluding hold and ghost
53
-
54
- using PerFramePaintCommands = std::map<int , PaintIPNode::LocalCommands>;
55
-
53
+ currentFrameCommands; // visible commands, excluding hold and ghost
56
54
PerFramePaintCommands beforeCommands;
57
55
PerFramePaintCommands afterCommands;
58
56
@@ -80,7 +78,7 @@ namespace
80
78
if (frame >= startFrame
81
79
&& frame <= endFrame) // Command is visible on the current frame
82
80
{
83
- CurrentFrameCommands .push_back (localCommand);
81
+ currentFrameCommands .push_back (localCommand);
84
82
}
85
83
else
86
84
{
@@ -97,86 +95,114 @@ namespace
97
95
}
98
96
}
99
97
100
- bool noCurrentFrameCommands = CurrentFrameCommands.empty ();
98
+ return std::make_tuple (currentFrameCommands, beforeCommands,
99
+ afterCommands);
100
+ }
101
+
102
+ void addBeforeCommands (PaintIPNode::LocalCommands* allCommands,
103
+ PaintIPNode::LocalCommands* currentFrameCommands,
104
+ const PerFramePaintCommands& beforeCommands,
105
+ const int frame)
106
+ {
107
+ int levelIndex = 1 ;
108
+ bool isHoldedCommandsInFirstLevel = false ;
101
109
110
+ for (const auto & beforeCommand : beforeCommands)
102
111
{
103
- int levelIndex = 1 ;
104
- bool isHoldedCommandsInFirstLevel = false ;
112
+ int ghostLevel =
113
+ levelIndex - ( isHoldedCommandsInFirstLevel ? 1 : 0 ) ;
105
114
106
- for (const auto & beforeCommand : beforeCommands )
115
+ for (auto * command : beforeCommand. second )
107
116
{
108
- int ghostLevel =
109
- levelIndex - (isHoldedCommandsInFirstLevel ? 1 : 0 );
110
-
111
- for (auto * command : beforeCommand.second )
117
+ if (levelIndex == 1 && currentFrameCommands->empty ()
118
+ && command->hold != 0 )
112
119
{
113
- if (levelIndex == 1 && noCurrentFrameCommands
114
- && command->hold != 0 )
115
- {
116
- isHoldedCommandsInFirstLevel = true ;
117
- command->ghostOn = true ;
120
+ isHoldedCommandsInFirstLevel = true ;
121
+ command->ghostOn = true ;
118
122
119
- if (auto * polyLine =
120
- dynamic_cast <PaintIPNode::LocalPolyLine*>(
121
- command))
122
- {
123
- command->ghostColor = polyLine->color ;
124
- }
125
- else if (auto * text =
126
- dynamic_cast <PaintIPNode::LocalText*>(
127
- command))
128
- {
129
- command->ghostColor = text->color ;
130
- }
131
-
132
- CurrentFrameCommands.push_back (command);
123
+ if (auto * polyLine =
124
+ dynamic_cast <PaintIPNode::LocalPolyLine*>(command))
125
+ {
126
+ command->ghostColor = polyLine->color ;
133
127
}
134
- else if (command-> ghost != 0
135
- && command-> ghostBefore >= ghostLevel )
128
+ else if (auto * text =
129
+ dynamic_cast <PaintIPNode::LocalText*>(command) )
136
130
{
137
- command->ghostOn = true ;
138
- command->ghostColor = PaintIPNode::Color (
139
- 1.0 , 0.0 , 0.0 , 1.0 ); // Ghosted "Before" commands
140
- // are drawn in green
141
- command->ghostColor [3 ] = getGhostOpacity (
142
- frame, command->startFrame , command->duration );
143
- allCommands.push_back (command);
131
+ command->ghostColor = text->color ;
144
132
}
133
+
134
+ currentFrameCommands->push_back (command);
135
+ }
136
+ else if (command->ghost != 0
137
+ && command->ghostBefore >= ghostLevel)
138
+ {
139
+ command->ghostOn = true ;
140
+ command->ghostColor = PaintIPNode::Color (
141
+ 1.0 , 0.0 , 0.0 , 1.0 ); // Ghosted "Before" commands
142
+ // are drawn in green
143
+ command->ghostColor [3 ] = getGhostOpacity (
144
+ frame, command->startFrame , command->duration );
145
+ allCommands->push_back (command);
145
146
}
146
- levelIndex++;
147
147
}
148
+ levelIndex++;
148
149
}
150
+ }
149
151
150
- {
151
- int levelIndex = 1 ;
152
+ void addAfterCommands (PaintIPNode::LocalCommands* allCommands,
153
+ const PerFramePaintCommands& afterCommands,
154
+ const int frame)
155
+ {
156
+ int levelIndex = 1 ;
152
157
153
- for (const auto & afterCommand : afterCommands)
158
+ for (const auto & afterCommand : afterCommands)
159
+ {
160
+ for (auto * command : afterCommand.second )
154
161
{
155
- for ( auto * command : afterCommand. second )
162
+ if (command-> ghost != 0 && command-> ghostAfter >= levelIndex )
156
163
{
157
- if (command->ghost != 0
158
- && command->ghostAfter >= levelIndex)
159
- {
160
- command->ghostOn = true ;
161
- command->ghostColor = PaintIPNode::Color (
162
- 0.0 , 1.0 , 0.0 ,
163
- 1.0 ); // Ghosted "After" commands are drawn in red
164
- command->ghostColor [3 ] = getGhostOpacity (
165
- frame, command->startFrame , command->duration );
166
- allCommands.push_back (command);
167
- }
164
+ command->ghostOn = true ;
165
+ command->ghostColor = PaintIPNode::Color (
166
+ 0.0 , 1.0 , 0.0 ,
167
+ 1.0 ); // Ghosted "After" commands are drawn in red
168
+ command->ghostColor [3 ] = getGhostOpacity (
169
+ frame, command->startFrame , command->duration );
170
+ allCommands->push_back (command);
168
171
}
169
- levelIndex++;
170
172
}
173
+ levelIndex++;
171
174
}
175
+ }
172
176
177
+ void
178
+ addVisibleCommands (PaintIPNode::LocalCommands* allCommands,
179
+ const PaintIPNode::LocalCommands& currentFrameCommands)
180
+ {
181
+ for (auto * command : currentFrameCommands)
173
182
{
174
- for (auto * command : CurrentFrameCommands)
175
- {
176
- command->ghostOn = false ;
177
- allCommands.push_back (command);
178
- }
183
+ command->ghostOn = false ;
184
+ allCommands->push_back (command);
179
185
}
186
+ }
187
+
188
+ PaintIPNode::LocalCommands
189
+ generateVisibleCommands (const PaintIPNode::LocalCommands& commands,
190
+ const int frame, const size_t eye)
191
+ {
192
+ PaintIPNode::LocalCommands
193
+ allCommands; // visible commands, including hold and ghost
194
+ PaintIPNode::LocalCommands
195
+ currentFrameCommands; // visible commands, excluding hold and ghost
196
+ PerFramePaintCommands beforeCommands;
197
+ PerFramePaintCommands afterCommands;
198
+
199
+ std::tie (currentFrameCommands, beforeCommands, afterCommands) =
200
+ separateCommandsByFrameGroup (commands, frame, eye);
201
+
202
+ addBeforeCommands (&allCommands, ¤tFrameCommands, beforeCommands,
203
+ frame);
204
+ addAfterCommands (&allCommands, afterCommands, frame);
205
+ addVisibleCommands (&allCommands, currentFrameCommands);
180
206
181
207
return allCommands;
182
208
}
@@ -305,17 +331,21 @@ namespace IPCore
305
331
if (widthP && pointsP && widthP->size () == pointsP->size ()
306
332
&& widthP->size () > 1 )
307
333
{
308
- p.widths = (const float *)widthP->rawData ();
334
+ p.widths .assign (static_cast <const float *>(widthP->rawData ()),
335
+ static_cast <const float *>(widthP->rawData ())
336
+ + widthP->size ());
309
337
}
310
338
311
339
if (pointsP && pointsP->size ())
312
340
{
313
- p.points = (const Vec2f*)pointsP->rawData ();
341
+ p.points .assign (static_cast <const Vec2f*>(pointsP->rawData ()),
342
+ static_cast <const Vec2f*>(pointsP->rawData ())
343
+ + pointsP->size ());
314
344
p.npoints = pointsP->size ();
315
345
}
316
346
else
317
347
{
318
- p.points = 0 ;
348
+ p.points . clear () ;
319
349
p.npoints = 0 ;
320
350
}
321
351
@@ -327,8 +357,8 @@ namespace IPCore
327
357
const size_t prevNumTexts = m_texts.size ();
328
358
LocalText& p = m_texts[c];
329
359
330
- // Add newly created strokes to the commands vector
331
- if (prevNumTexts != m_penStrokes .size ())
360
+ // Add newly created text boxes to the commands vector
361
+ if (prevNumTexts != m_texts .size ())
332
362
{
333
363
m_commands.push_back (&p);
334
364
}
@@ -409,14 +439,6 @@ namespace IPCore
409
439
p.ghostAfter = ghostAfter;
410
440
}
411
441
412
- void PaintIPNode::clearAll ()
413
- {
414
- std::lock_guard<std::mutex> commandsGuard{m_commandsMutex};
415
- m_texts.clear ();
416
- m_penStrokes.clear ();
417
- m_commands.clear ();
418
- }
419
-
420
442
void PaintIPNode::compileFrame (Component* comp)
421
443
{
422
444
const StringProperty* orderP = comp->property <StringProperty>(" order" );
@@ -703,16 +725,12 @@ namespace IPCore
703
725
if (auto * polyLine = dynamic_cast <PaintIPNode::LocalPolyLine*>(
704
726
visibleCommand))
705
727
{
706
- polyLine->ghostOn = visibleCommand->ghostOn ;
707
- polyLine->ghostColor = visibleCommand->ghostColor ;
708
728
head->commands .push_back (polyLine);
709
729
}
710
730
else if (auto * localText =
711
731
dynamic_cast <PaintIPNode::LocalText*>(
712
732
visibleCommand))
713
733
{
714
- localText->ghostOn = visibleCommand->ghostOn ;
715
- localText->ghostColor = visibleCommand->ghostColor ;
716
734
head->commands .push_back (localText);
717
735
}
718
736
}
0 commit comments