Skip to content

Commit 0bfdad6

Browse files
authored
Merge pull request #50 from charlesangus/add-DeepConstant-node
Add deep constant node fixes #48
2 parents d7d2d6b + 5c372f6 commit 0bfdad6

File tree

4 files changed

+178
-1
lines changed

4 files changed

+178
-1
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ $(PLUGIN_DIR)/DeepCSaturation.so: $(OBJ_DIR)/DeepCSaturation.o $(OBJ_DIR)/DeepCW
9393
$(LINK) $(STD) $(LINK_FLAGS) -o $$@ $$^ $(LIBS)
9494
$(PLUGIN_DIR)/DeepCCopyBbox.so: $(OBJ_DIR)/DeepCCopyBbox.o $(OBJ_DIR)/DeepCWrapper.o | $(PLUGIN_DIR)
9595
$(LINK) $(STD) $(LINK_FLAGS) -o $$@ $$^ $(LIBS)
96+
$(PLUGIN_DIR)/DeepCConstant.so: $(OBJ_DIR)/DeepCConstant.o $(OBJ_DIR)/DeepCWrapper.o | $(PLUGIN_DIR)
97+
$(LINK) $(STD) $(LINK_FLAGS) -o $$@ $$^ $(LIBS)
9698
$(PLUGIN_DIR)/DeepCPNoise.so: $(OBJ_DIR)/DeepCPNoise.o $(OBJ_DIR)/DeepCMWrapper.o $(OBJ_DIR)/DeepCWrapper.o | $(PLUGIN_DIR)
9799
$(LINK) $(STD) $(LINK_FLAGS) -L$(FASTNOISEDIR)/build -o $$@ $$^ $(LIBS) -lFastNoise
98100
$(PLUGIN_DIR):

python/menu.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
def create_deepc_menu():
44
menus = {
55
"Draw": {"icon":"ToolbarDraw.png",
6-
"nodes": ["DeepCPMatte", "DeepCPNoise", "DeepCID"]},
6+
"nodes": ["DeepCPMatte", "DeepCPNoise", "DeepCID", "DeepCConstant"]},
77
"Channel": {"icon":"ToolbarChannel.png",
88
"nodes": ["DeepCAddChannels", "DeepCRemoveChannels", "DeepCShuffle"]},
99
"Color": {"icon":"ToolbarColor.png",

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ set(PLUGINS
77
DeepCBlink
88
DeepCClamp
99
DeepCColorLookup
10+
DeepCConstant
1011
DeepCCopyBbox
1112
DeepCGamma
1213
DeepCGrade

src/DeepCConstant.cpp

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/* Constant node for deep nodes with adjustable samples and depth range.
2+
3+
Falk Hofmann, 11/2021
4+
*/
5+
6+
#include "DDImage/Iop.h"
7+
#include "DDImage/DeepFilterOp.h"
8+
#include "DDImage/Knobs.h"
9+
10+
static const char* CLASS = "DeepCConstant";
11+
static const char* const enumAlphaTypes[] = { "unform", "additive", "multiplicative", 0 };
12+
using namespace DD::Image;
13+
14+
class DeepCConstant : public DeepFilterOp
15+
{
16+
FormatPair formats;
17+
ChannelSet channels;
18+
float color[4];
19+
double _front;
20+
double _back;
21+
int _samples;
22+
float _overallDepth;
23+
float _sampleDistance;
24+
double _values[4];
25+
int _alphaType;
26+
float _modAlpha;
27+
28+
public:
29+
30+
int minimum_inputs() const { return 0;}
31+
32+
DeepCConstant(Node* node) : DeepFilterOp(node) {
33+
34+
formats.format(nullptr);
35+
_front = 0;
36+
_back = 10;
37+
_samples = 1;
38+
_overallDepth = 1;
39+
_sampleDistance = 0.1f;
40+
color[0] = color[1] = color[2] = color[3] = 0.5;
41+
channels = Mask_RGBA;
42+
_alphaType = 2;
43+
_values[0] = _values[1] = _values[2] = _values[3] = 0.5;
44+
_modAlpha = 1.0;
45+
}
46+
void _validate(bool);
47+
bool doDeepEngine(DD::Image::Box bbox, const DD::Image::ChannelSet& requestedChannels, DeepOutputPlane& deepOutPlane);
48+
void knobs(Knob_Callback);
49+
int knob_changed(Knob* k);
50+
51+
void calcValues();
52+
53+
static const Iop::Description d;
54+
const char* Class() const { return d.name;}
55+
const char* node_help() const;
56+
virtual Op* op() { return this; }
57+
};
58+
59+
const char* DeepCConstant::node_help() const
60+
{return "A DeepConstant with defined deep range and amount of samples.\n\n"
61+
"Falk Hofmann 11/2021";}
62+
63+
void DeepCConstant::knobs(Knob_Callback f)
64+
{
65+
Input_ChannelSet_knob(f, &channels, 4, "channels");
66+
AColor_knob(f, color, "color", "color");
67+
Format_knob(f, &formats, "format", "format");
68+
Obsolete_knob(f, "full_format", "knob format $value");
69+
Obsolete_knob(f, "proxy_format", nullptr);
70+
Divider(f, "");
71+
Enumeration_knob(f, &_alphaType, enumAlphaTypes, "alpha_mode", "split alpha mode");
72+
Tooltip(f, "Select the alpha mode.\n\n"
73+
"multiplactive will match the image visually as compared to a 2d constant.\n\n"
74+
"additive does a straight division by the number of samples and therefore will not match the 2d equivalent.\n\n"
75+
"uniform applies the given color values straight to the samples, without considering and modifications due deep sample addition." );
76+
Double_knob(f, &_front, "front", "front");
77+
Tooltip(f, "Closest distance from camera.");
78+
Double_knob(f, &_back, "back", "back");
79+
Tooltip(f, "Farthest distance from camera.");
80+
Int_knob(f, &_samples, "samples", "samples");
81+
Tooltip(f, "Amount of deep samples per pixel.");
82+
SetRange(f, 2, 1000);
83+
SetFlags(f, Knob::NO_ANIMATION);
84+
85+
}
86+
87+
void DeepCConstant::calcValues(){
88+
89+
float a = knob("color")->get_value(colourIndex(Chan_Alpha));
90+
int saveSample = (_samples > 0)? _samples: 1;
91+
_modAlpha = 1.0f- pow(1.0f - a, (1.0f/saveSample));
92+
93+
94+
for (int c = 0; c < 4; c++){
95+
96+
float val = knob("color")->get_value(c);
97+
switch (_alphaType)
98+
{
99+
case 0:
100+
_values[c] = val;
101+
break;
102+
case 1:
103+
_values[c] = val/saveSample;
104+
break;
105+
case 2:
106+
_values[c] = (val/a) * _modAlpha;
107+
}
108+
}
109+
}
110+
111+
112+
int DeepCConstant::knob_changed(Knob* k){
113+
if (k->name() == "alpha_mode"){
114+
DeepCConstant::calcValues();
115+
}
116+
}
117+
118+
void DeepCConstant::_validate(bool for_real)
119+
{
120+
ChannelSet new_channelset;
121+
new_channelset += Mask_Deep;
122+
new_channelset += Mask_Z;
123+
new_channelset += Mask_Alpha;
124+
new_channelset += channels;
125+
126+
Box box(0, 0, formats.format()->width(), formats.format()->height()) ;
127+
_deepInfo = DeepInfo(formats, box, new_channelset);
128+
_overallDepth = _back - _front;
129+
_sampleDistance = _overallDepth/(_samples);
130+
DeepCConstant::calcValues();
131+
}
132+
133+
bool DeepCConstant::doDeepEngine(DD::Image::Box box, const DD::Image::ChannelSet& channels, DeepOutputPlane& plane)
134+
{
135+
int saveSample = (_samples > 0) ? _samples: 1;
136+
137+
DeepInPlaceOutputPlane outPlane(channels, box, DeepPixel::eZDescending);
138+
outPlane.reserveSamples(box.area());
139+
140+
for (Box::iterator it = box.begin();
141+
it != box.end();
142+
it++) {
143+
144+
outPlane.setSampleCount(it, saveSample);
145+
DeepOutputPixel out = outPlane.getPixel(it);
146+
for (int sampleNo = 0; sampleNo < saveSample; sampleNo++){
147+
148+
foreach (z, channels) {
149+
float& output = out.getWritableOrderedSample(sampleNo, z);
150+
int cIndex = colourIndex(z);
151+
152+
if (z == Chan_DeepFront){
153+
output = _front + (_sampleDistance * sampleNo);
154+
155+
}
156+
else if (z == Chan_DeepBack){
157+
output = _front + (_sampleDistance * sampleNo) + _sampleDistance;
158+
159+
}
160+
else{
161+
output = _values[cIndex];
162+
}
163+
}
164+
}
165+
}
166+
mFnAssert(outPlane.isComplete());
167+
plane = outPlane;
168+
169+
170+
return true;
171+
}
172+
173+
static Op* build(Node* node) { return new DeepCConstant(node); }
174+
const Op::Description DeepCConstant::d("DeepCConstant", 0, build);

0 commit comments

Comments
 (0)