00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef debug
00018 #undef debug
00019 #endif
00020
00021
00022 static const char* const CLASS = "Cellnoise";
00023 static const char* const HELP = "Generates cell noise";
00024
00025 #include "DDImage/PixelIop.h"
00026 #include "DDImage/Row.h"
00027 #include "DDImage/Knobs.h"
00028 #include "DDImage/Knob.h"
00029 #include "DDImage/DDMath.h"
00030 #include "DDImage/NukeWrapper.h"
00031
00032 using namespace DD::Image;
00033 #include "Voronoi.h"
00034
00035 const char* const _modeList[] =
00036 {
00037 "Random",
00038 "Grid",
00039 "Hexagon",
00040 NULL
00041 };
00042
00043 inline float remap(float min, float max, float value)
00044 {
00045 return (min +(max-min)*value);
00046 }
00047
00048
00049
00050
00051
00052 class Cellnoise : public PixelIop
00053 {
00054 Voronoi m_diagram;
00055
00056 public:
00057 Channel m_channel;
00058 int m_Nmode, m_numc;
00059 int m_size, m_w, m_h;
00060 float m_min, m_max;
00061
00062 Cellnoise(Node* node) : PixelIop(node)
00063 {
00064
00065 m_min=0.f;
00066 m_max=1.f;
00067 m_numc=64;
00068 m_Nmode=2;
00069 m_size=format().width();
00070 }
00071
00072 void knobs(Knob_Callback f)
00073 {
00074 Obsolete_knob(f, "proxy_format", 0);
00075 Input_Channel_knob(f, &m_channel, 1, 0, "m_channel");
00076
00077 Knob* e =Enumeration_knob(f, &m_Nmode, _modeList, "mode_selector");
00078 Int_knob(f, &m_numc, "cells" );
00079 Float_knob(f, &m_max, "range max" );
00080 Float_knob(f, &m_min, "range min" );
00081 }
00082
00083 void _validate(bool for_real)
00084 {
00085 PixelIop::_validate(for_real);
00086 info_.set( format() );
00087 info_.channels(Mask_RGBA);
00088 set_out_channels(Mask_RGBA);
00089 }
00090
00091 void in_channels(int input, ChannelSet& mask) const
00092 {
00093
00094 }
00095
00096 void pixel_engine(const Row& in, int y, int xx, int r,
00097 ChannelMask channels, Row& row)
00098 {
00099 Color resultColor;
00100 resultColor.zero();
00101 float curColor[4];
00102 curColor[0]=curColor[1]=curColor[2]=curColor[3]=1.f;
00103 float* outptr=0;
00104
00105 foreach (z, channels)
00106 {
00107 if (z < 1 || z > 3)
00108 row.copy(in, z, xx, r);
00109 else
00110 {
00111 for ( int i = xx; i < r; i++)
00112 {
00113 if (curColor[z-1]==-1.f)
00114 {
00115 m_diagram.doVoronoiXY(resultColor, m_Nmode, m_numc, info_.format().width(), info_.format().height(), i, y);
00116 curColor[0]=remap( m_min, m_max, resultColor.m_r);
00117 curColor[1]=remap( m_min, m_max, resultColor.m_g);
00118 curColor[2]=remap( m_min, m_max, resultColor.m_b);
00119 }
00120 outptr = row.writable(z) + i;
00121 *outptr++ = curColor[z-1];
00122 curColor[z-1]=-1.f;
00123 }
00124 }
00125 }
00126 };
00127
00128 const char* Class() const { return CLASS; }
00129 const char* displayName() const { return "CellNoise"; }
00130 const char* node_help() const { return HELP; }
00131 static const Description desc;
00132 };
00133
00134 static Iop* constructor(Node* node) { return new NukeWrapper(new Cellnoise(node)); }
00135
00136
00137 const Iop::Description Cellnoise::desc(CLASS, "Image/CellNoise", constructor);