Color Model HSV

Color_Model_HSV is a basic example plugin. This wiki page is intended as a walkthrough of the code in order to help you better understand the SDK.

When installed, this plugin adds a color model that enables picking colors using hue, saturation, and value color components.

../../_images/Hsv_shot1.png

The HSV color model.

Code Walkthrough

Class Declarations

This function allows the plugin to write to the log through by inheriting from the ./FAQ#Q:_How_do_I_write_to_the_log.3F class.

1
 extern const char* SERVER_HSV_COLOR_MODEL;
1
2
3
4
5
 class CHSVColorModelLog : public CLxLuxologyLogMessage
 {
    public:
                         CHSVColorModelLog ()
                                 : CLxLuxologyLogMessage (SERVER_HSV_COLOR_MODEL) { }
1
2
        const char *     GetFormat  () { return "HSV Color Model"; }
 };

These functions are ./Command:_Server_basics that perform certain actions in running/setting up the color model. They have the general functions for the basic command class(Cmd_Flags, Enable, Notifier, Execute, and Query).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
class CHueAsWheelHSVColorModelCommand : public CLxBasicCommand
{
    public:
                         CHueAsWheelHSVColorModelCommand ();
        virtual         ~CHueAsWheelHSVColorModelCommand () {}

        int              basic_CmdFlags () LXx_OVERRIDE;
        bool             basic_Notifier (int index, std::string &name, std::string &args) LXx_OVERRIDE;
        bool             basic_Enable (CLxUser_Message &msg) LXx_OVERRIDE;

        void             cmd_Execute (unsigned int flags) LXx_OVERRIDE;
        LxResult         cmd_Query (unsigned int index, ILxUnknownID vaQuery) LXx_OVERRIDE;
};

class CWheelHSVColorModelCommand : public CLxBasicCommand
{
    public:
                         CWheelHSVColorModelCommand ();
        virtual         ~CWheelHSVColorModelCommand () {}

        int              basic_CmdFlags () LXx_OVERRIDE;
        bool             basic_Notifier (int index, std::string &name, std::string &args) LXx_OVERRIDE;
        bool             basic_Enable (CLxUser_Message &msg) LXx_OVERRIDE;

        void             cmd_Execute (unsigned int flags) LXx_OVERRIDE;
        LxResult         cmd_Query (unsigned int index, ILxUnknownID vaQuery) LXx_OVERRIDE;

        void             atrui_UIHints (unsigned int index, CLxUser_UIHints &hints) LXx_OVERRIDE;
};

class CRuleHSVColorModelCommand : public CLxBasicCommand
{
    public:
                         CRuleHSVColorModelCommand ();
        virtual         ~CRuleHSVColorModelCommand () {}

        int              basic_CmdFlags () LXx_OVERRIDE;
        bool             basic_Notifier (int index, std::string &name, std::string &args) LXx_OVERRIDE;
        bool             basic_Enable (CLxUser_Message &msg) LXx_OVERRIDE;

        void             cmd_Execute (unsigned int flags) LXx_OVERRIDE;
        LxResult         cmd_Query (unsigned int index, ILxUnknownID vaQuery) LXx_OVERRIDE;

        void             atrui_UIHints (unsigned int index, CLxUser_UIHints &hints) LXx_OVERRIDE;
};

class CRuleAdjustHSVColorModelCommand : public CLxBasicCommand
{
    public:
                         CRuleAdjustHSVColorModelCommand ();
        virtual         ~CRuleAdjustHSVColorModelCommand () {}

        int              basic_CmdFlags () LXx_OVERRIDE;
        bool             basic_Notifier (int index, std::string &name, std::string &args) LXx_OVERRIDE;
        bool             basic_Enable (CLxUser_Message &msg) LXx_OVERRIDE;

        void             cmd_Execute (unsigned int flags) LXx_OVERRIDE;
        LxResult         cmd_Query (unsigned int index, ILxUnknownID vaQuery) LXx_OVERRIDE;

        void             atrui_UIHints (unsigned int index, CLxUser_UIHints &hints) LXx_OVERRIDE;
};

class CLevelsHSVColorModelCommand : public CLxBasicCommand
{
    public:
                         CLevelsHSVColorModelCommand ();
        virtual         ~CLevelsHSVColorModelCommand () {}

        int              basic_CmdFlags () LXx_OVERRIDE;
        bool             basic_Notifier (int index, std::string &name, std::string &args) LXx_OVERRIDE;
        bool             basic_Enable (CLxUser_Message &msg) LXx_OVERRIDE;

        void             cmd_Execute (unsigned int flags) LXx_OVERRIDE;
        LxResult         cmd_Query (unsigned int index, ILxUnknownID vaQuery) LXx_OVERRIDE;

        void             atrui_UIHints (unsigned int index, CLxUser_UIHints &hints) LXx_OVERRIDE;
};

class CSaveAsPresetsHSVColorModelCommand : public CLxBasicCommand
{
    public:
                         CSaveAsPresetsHSVColorModelCommand ();
        virtual         ~CSaveAsPresetsHSVColorModelCommand () {}

        int              basic_CmdFlags () LXx_OVERRIDE;
        bool             basic_Notifier (int index, std::string &name, std::string &args) LXx_OVERRIDE;
        bool             basic_Enable (CLxUser_Message &msg) LXx_OVERRIDE;

        void             cmd_Execute (unsigned int flags) LXx_OVERRIDE;
        LxResult         cmd_Query (unsigned int index, ILxUnknownID vaQuery) LXx_OVERRIDE;

        void             atrui_UIHints (unsigned int index, CLxUser_UIHints &hints) LXx_OVERRIDE;

};

This function is a ./Notifier_Object which goes off when changes to the color model occur.

1
2
3
4
5
 class CHSVColorModelNotifier : public CLxCommandNotifier
 {
    public:
                         CHSVColorModelNotifier ();
        virtual         ~CHSVColorModelNotifier () {}
1
2
3
        virtual void            cn_Parse (std::string &args);
        virtual unsigned int    cn_Flags (int code);
 };

This code block is an enumerated type that set the values corresponding to the different type of wheels.

1
2
3
4
 enum {
        HSV_WHEEL_RGB,                  // Red, green, and blue is triadic.
        HSV_WHEEL_RYB                   // Red, yellow, and blue is triadic.
 };

This code black is an enumerated type that set the values corresponding to the rules related to building swatches.

enum {

1
2
3
4
5
6
7
8
        HSV_RULE_SOLO,                  // Just the selected color.
        HSV_RULE_COMPLEMENTARY,         // Selected color and its opposite.
        HSV_RULE_ANALOGOUS,             // Adjacent colors.
        HSV_RULE_TRIADIC,               // Three colors at 120 degree stops.
        HSV_RULE_TETRADIC,              // Four colors at 45 degree stops.
        HSV_RULE_COMPOUND,              // Five colors at 30 and 45 degree stops.
        HSV_RULE_TINTS,                 // Tinted variations.
        HSV_RULE_SHADES                 // Shaded variations.

};

This is the main function from which the color model will be built. It inherits from ./Color_(lx-color.hpp)#.282.29_SDK:_ILxColorModel_interface because it has the functions we need in order to create our color model, which we want the CHSVColorModel to create. Inside the class the functions with the colm prefix perform changes on the color model(the change is usually explained by the rest of the name. The functions without any special prefix either create the name of their function or query a value with its name. The rest of the functions have the Build prefix and build a certain type of swatch made obvious by the rest of the name.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
class CHSVColorModel :
        public CLxImpl_ColorModel
{
        CHSVColorModelLog        m_log;
        ILxUnknownID             rangeWorker;

    public:
        static LXtTagInfoDesc    descInfo[];
        CLxPolymorph<CHSVColorModelThreadRangeWorker>    range_factory;

                                 CHSVColorModel ();
        virtual                 ~CHSVColorModel ();

        virtual int              colm_NumComponents (void) LXx_OVERRIDE;

        virtual LxResult         colm_ComponentType (
                                        unsigned         componentIndex,
                                        const char      **type) LXx_OVERRIDE;

        virtual LxResult         colm_ComponentRange (
                                        unsigned         componentIndex,
                                        float           *minValue,
                                        float           *maxValue) LXx_OVERRIDE;

        virtual LxResult         colm_ToRGB (
                                        const float     *hsv,
                                        float           *rgb) LXx_OVERRIDE;

        virtual LxResult         colm_FromRGB (
                                        const float     *rgb,
                                        float           *hsv) LXx_OVERRIDE;

        virtual LxResult         colm_DrawSlice (
                                        ILxUnknownID     image,
                                        unsigned         xAxis,
                                        unsigned         yAxis,
                                        const float     *vec) LXx_OVERRIDE;

        virtual LxResult         colm_DrawSliceMarker (
                                        ILxUnknownID     image,
                                        unsigned         xAxis,
                                        unsigned         yAxis,
                                        const float     *downVec,
                                        const float     *hsv) LXx_OVERRIDE;

        virtual LxResult         colm_CanSliceBeReused (
                                        unsigned          xAxis,
                                        unsigned          yAxis,
                                        const float      *oldVec,
                                        const float      *newVec) LXx_OVERRIDE;

        virtual LxResult         colm_ToSlicePos (
                                        unsigned         xAxis,
                                        unsigned         yAxis,
                                        unsigned         imgW,
                                        unsigned         imgH,
                                        const float     *hsv,
                                        unsigned        *imgX,
                                        unsigned        *imgY) LXx_OVERRIDE;

        virtual LxResult         colm_FromSlicePos (
                                        unsigned         xAxis,
                                        unsigned         yAxis,
                                        unsigned         imgW,
                                        unsigned         imgH,
                                        unsigned         imgX,
                                        unsigned         imgY,
                                        float           *downVec,
                                        float           *hsv) LXx_OVERRIDE;

        virtual LxResult         colm_StripBaseVector (
                                        unsigned         axis,
                                        int              dynamic,
                                        float           *hsv) LXx_OVERRIDE;

        static bool              HueAxisOnStrip ();
        static bool              HueAsWheel ();
        static unsigned          Wheel ();

        static unsigned          Rule ();
        static float             RuleAdjust ();
        static float             PresetRuleAdjust ();

        static unsigned          Levels ();

        static unsigned          SwatchCount ();

        static void              BuildSwatches (
                                        const HSVColor          &baseColor,
                                        std::vector<HSVColor>   &swatchColors,
                                        unsigned                &baseColorIndex);

    private:
        static void              BuildComplementarySwatches (
                                        const HSVColor          &baseColor,
                                        std::vector<HSVColor>   &swatchColors,
                                        unsigned                &baseColorIndex);

        static void              BuildAnalogousSwatches (
                                        const HSVColor          &baseColor,
                                        std::vector<HSVColor>   &swatchColors,
                                        unsigned                &baseColorIndex);

        static void              BuildTriadicSwatches (
                                        const HSVColor          &baseColor,
                                        std::vector<HSVColor>   &swatchColors,
                                        unsigned                &baseColorIndex);

        static void              BuildTetradicSwatches (
                                        const HSVColor          &baseColor,
                                        std::vector<HSVColor>   &swatchColors,
                                        unsigned                &baseColorIndex);

        static void              BuildCompoundSwatches (
                                        const HSVColor          &baseColor,
                                        std::vector<HSVColor>   &swatchColors,
                                        unsigned                &baseColorIndex);

        static void              BuildTintsSwatches (
                                        const HSVColor          &baseColor,
                                        std::vector<HSVColor>   &swatchColors,
                                        unsigned                &baseColorIndex);

        static void              BuildShadesSwatches (
                                        const HSVColor          &baseColor,
                                        std::vector<HSVColor>   &swatchColors,
                                        unsigned                &baseColorIndex);

        CLxUser_Image            primary_marker;
        CLxUser_Image            secondary_marker;

};

./Initialize_(index)

This function initializes each ./Overview#nexus_Servers, or in other words tells Modo that this plugin will be adding certain features.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
        void
initialize ()
{
        // Color Model server.
        LXx_ADD_SERVER (ColorModel, CHSVColorModel, SERVER_HSV_COLOR_MODEL);

        CLxGenericPolymorph     *srv;

        // Hue As Wheel command.
        srv = new CLxPolymorph<CHueAsWheelHSVColorModelCommand>;
        srv->AddInterface (new CLxIfc_Command   <CHueAsWheelHSVColorModelCommand>);
        srv->AddInterface (new CLxIfc_Attributes<CHueAsWheelHSVColorModelCommand>);
        thisModule.AddServer ("color.hsvHueAsWheel", srv);

        // Wheel command.
        srv = new CLxPolymorph<CWheelHSVColorModelCommand>;
        srv->AddInterface (new CLxIfc_Command   <CWheelHSVColorModelCommand>);
        srv->AddInterface (new CLxIfc_Attributes<CWheelHSVColorModelCommand>);
        srv->AddInterface (new CLxIfc_AttributesUI<CWheelHSVColorModelCommand>);
        thisModule.AddServer ("color.hsvWheel", srv);

        // Rule command.
        srv = new CLxPolymorph<CRuleHSVColorModelCommand>;
        srv->AddInterface (new CLxIfc_Command   <CRuleHSVColorModelCommand>);
        srv->AddInterface (new CLxIfc_Attributes<CRuleHSVColorModelCommand>);
        srv->AddInterface (new CLxIfc_AttributesUI<CRuleHSVColorModelCommand>);
        thisModule.AddServer ("color.hsvRule", srv);

        // Rule Adjust command.
        srv = new CLxPolymorph<CRuleAdjustHSVColorModelCommand>;
        srv->AddInterface (new CLxIfc_Command   <CRuleAdjustHSVColorModelCommand>);
        srv->AddInterface (new CLxIfc_Attributes<CRuleAdjustHSVColorModelCommand>);
        srv->AddInterface (new CLxIfc_AttributesUI<CRuleAdjustHSVColorModelCommand>);
        thisModule.AddServer ("color.hsvRuleAdjust", srv);

        // Levels command.
        srv = new CLxPolymorph<CLevelsHSVColorModelCommand>;
        srv->AddInterface (new CLxIfc_Command   <CLevelsHSVColorModelCommand>);
        srv->AddInterface (new CLxIfc_Attributes<CLevelsHSVColorModelCommand>);
        srv->AddInterface (new CLxIfc_AttributesUI<CLevelsHSVColorModelCommand>);
        thisModule.AddServer ("color.hsvLevels", srv);

        // Save as Presets command.
        srv = new CLxPolymorph<CSaveAsPresetsHSVColorModelCommand>;
        srv->AddInterface (new CLxIfc_Command   <CSaveAsPresetsHSVColorModelCommand>);
        srv->AddInterface (new CLxIfc_Attributes<CSaveAsPresetsHSVColorModelCommand>);
        srv->AddInterface (new CLxIfc_AttributesUI<CSaveAsPresetsHSVColorModelCommand>);
        thisModule.AddServer ("color.hsvSaveAsPresets", srv);

        // Notifier.
        srv = new CLxPolymorph<CHSVColorModelNotifier>;
        srv->AddInterface (new CLxIfc_Notifier<CHSVColorModelNotifier>);
        thisModule.AddServer (HSV_COLOR_MODEL_NOTIFIER, srv);

}

This function cleans up the persistent data

1
2
3
4
5
6
 void cleanup ()
 {
        if (persist) {
                delete persist;
        }
 }

Helper Functions

These are conversion utilities that will be used later on in implementing the class functions.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
        string
IntegerToString (
        unsigned value,
        unsigned padding = 0,
        bool asHexadecimal = false,
        bool withHexPrefix = false)
{
       ...
}

const float PI                  = 3.1415926535897932384626433832795f;
const float TWO_PI              = PI * 2.0f;     // 360 degrees
const float TWO_PI_OVER_THREE   = TWO_PI / 3.0f; // 120 degrees
const float HALF_PI             = PI * 0.5f;     // 90 degrees
const float THIRD_PI            = PI / 3.0f;     // 60 degrees
const float SIXTH_PI            = PI / 6.0f;     // 30 degrees
const float QUARTER_PI          = PI * 0.25f;    // 45 degrees

#define _R              rgb[0]
#define _G              rgb[1]
#define _B              rgb[2]
#define _H              hsv[0]
#define _S              hsv[1]
#define _V              hsv[2]

/*
 * rgb in [0, 1]; h in [0, TWO_PI], s and v in [0, 1]
 */
        static void
RGB2HSV (
        const float     *rgb,
        float           *hsv)
{
        ...
}

/*
 * rgb in [0, 1]; h in [0, TWO_PI], s and v in [0, 1]
 */
        static void
HSV2RGB (
        const float     *hsv,
        float           *rgb)
{
       ...
}

These are utilities that retrieve the values in certain argument indeces.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
const unsigned MAX_COMMAND_VALUE_LEN = 256;

        static string
QueryCommandString (const char *cmdName, const char *argName)
{
       ...
}

        static int
QueryCommandInt (const char *cmdName, int defaultValue = 0)
{
        ...

        static double
QueryCommandFloat (const char *cmdName, double defaultValue = 0.0)
{
        ...

}

This function takes a string and executes a command with a name that matches that string.

1
2
3
4
 ExecuteCommand (const char *cmdName)
 {
       ...
 }

This code block is a set of helper functions that Query a series of color.value commands, to retrieve the selected base color’s component values, from which the rule-based color swatches will be built and Execute the color.presetSaveWithModel commmand, to generate a preset for the given swatch. These are then used for the cmd_Execute of CSaveAsPresetsHSVColorModelCommand

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
        static bool
QueryColorValueCmd (
        HSVColor                &baseColor)
{
        ...
}

        static bool
QueryPBViewPathCmd (
        string          &path)
{
       ...
}

/*
 * Execute the color.presetSaveWithModel commmand,
 * to generate a preset for the given swatch.
 */
        static void
ExecuteHSVPresetSaveWithModelCmd (
        const HSVColor          &hsvColor,
        unsigned                 swatchIndex,
        string                  &swatchPath)
{
       ...

}

This function resizes wheel and rule swatches.

1
2
3
4
5
6
7
        static void
ResizeWheelAndRuleSwatches (
        unsigned         sliceWidth,
        unsigned         sliceHeight,
        Metrics         &metrics)
{
       ...

}

This function returns whether or not the given image (X, Y) coordinates are tracking within a swatch.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
TrackSwatch (
        Metrics         &metrics,
        unsigned         xAxis,
        unsigned         yAxis,
        unsigned         imageWidth,
        unsigned         imageHeight,
        unsigned         imageX,
        unsigned         imageY,
        LXtFVector       downVec,
        LXtFVector       hsv)
{
        ...

}

These are helper functions that Remap an HSV hue such that red, yellow, and blue are triadic, instead of red, green, and blue and perform the reverse.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
HueRGBtoRYB (float hue)
{
        ...
}

/*
 * The inverse of HueRGBtoRYB.
 */
        static inline float
HueRYBtoRGB (float hue)
{
       ...

}

Persistent Data

This is a struct that holds the persistent data of the color model

1
2
3
4
 struct CHSVColorModelPersist
 {
        ...
 };

This is a function that visits every ./Common_Datatypes#Complex_Datatypes in the struct above and sets its value to that of the matching persistent data object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class CHSVColorModelPersistVisitor : public CLxImpl_AbstractVisitor
{
    ...
};

static const char* ATOM_TAG_HUE_AS_WHEEL                = "hsv.hue.as.wheel";
static const char* ATOM_TAG_WHEEL                       = "hsv.wheel";
static const char* ATOM_TAG_RULE                        = "hsv.rule";
static const char* ATOM_TAG_RULE_ADJUST_COMPLEMENTARY   = "hsv.rule.adjust_complementary";
static const char* ATOM_TAG_RULE_ADJUST_ANALOGOUS       = "hsv.rule.adjust_analogous";
static const char* ATOM_TAG_RULE_ADJUST_TRIADIC         = "hsv.rule.adjust_triadic";
static const char* ATOM_TAG_RULE_ADJUST_TETRADIC        = "hsv.rule.adjust_tetradic";
static const char* ATOM_TAG_RULE_ADJUST_COMPOUND        = "hsv.rule.adjust_compound";
static const char* ATOM_TAG_LEVELS                      = "hsv.levels";

        LxResult
CHSVColorModelPersistVisitor::Evaluate ()
{
       ...

}

This function is a ./Notifier_Object with flags that have it go off whenever a value changes or if the command is not working.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
static const char *HSV_COLOR_MODEL_NOTIFIER = "hsv.color.model.notifier";

CHSVColorModelNotifier::CHSVColorModelNotifier ()
        :
        CLxCommandNotifier (HSV_COLOR_MODEL_NOTIFIER)
{
}

        void
CHSVColorModelNotifier::cn_Parse (string &args)
{
}

        unsigned int
CHSVColorModelNotifier::cn_Flags (int code)
{
        ...

}

This section implements the functions of the CHueAsWheelColorModelCommand class. Its constructor sets it so that it takes a boolean value. The CmdFlags function indicates that the command affects the command ui. The notifier goes off whenever the notifier(http://modo.sdk.thefoundry.co.uk/wiki/Notifier_Object) in 407-424 goes off or the selected color has changed. The enables command enables the command if the strip is not set to the hue axis. The cmd_execute portion is the actual command. Cmd_Query asks for the value of a relevant argument index.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#define LXsCOMMAND_COLOR_UPDATE_VIEW    "color.updateView"
#define LXsCOMMAND_COLOR_MODEL_AXIS     "color.modelAxis"

enum
{
       ...
};

const bool PRESET_HSV_HUE_AS_WHEEL = true;

CHueAsWheelHSVColorModelCommand::CHueAsWheelHSVColorModelCommand ()
{
        ...
}

        int
CHueAsWheelHSVColorModelCommand::basic_CmdFlags ()
{
        ...
}

        bool
CHueAsWheelHSVColorModelCommand::basic_Notifier (
        int                      index,
        string                  &name,
        string                  &args)
{
        ...
}

        bool
CHueAsWheelHSVColorModelCommand::basic_Enable (CLxUser_Message &msg)
{
        ...
}

enum
{
       ...
};

        void
CHueAsWheelHSVColorModelCommand::cmd_Execute (unsigned int flags)
{
        ...
}

        LxResult
CHueAsWheelHSVColorModelCommand::cmd_Query (unsigned int index, ILxUnknownID vaQuery)
{
       ...

}

This code block implements the same basic set of functions for the rest of the basic commands plus the atrui_UIHints function, which creates some relevant ui hints.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
enum
{
       ...
};

const int PRESET_HSV_WHEEL      = 0;

static LXtTextValueHint hint_hsvWheel[] = {
        ...
        };

CWheelHSVColorModelCommand::CWheelHSVColorModelCommand ()
{
        ...
}

        int
CWheelHSVColorModelCommand::basic_CmdFlags ()
{
       ...
}

        bool
CWheelHSVColorModelCommand::basic_Notifier (
        int                      index,
        string                  &name,
        string                  &args)
{
       ...
}

        bool
CWheelHSVColorModelCommand::basic_Enable (CLxUser_Message &msg)
{
       ...
}

        void
CWheelHSVColorModelCommand::cmd_Execute (unsigned int flags)
{
        ...
}

        LxResult
CWheelHSVColorModelCommand::cmd_Query (unsigned int index, ILxUnknownID vaQuery)
{
       ...
}

        void
CWheelHSVColorModelCommand::atrui_UIHints (
        unsigned int             index,
        CLxUser_UIHints         &hints)
{
}

/*
 * ---------------------------------------------------------------------------
 * CRuleHSVColorModelCommand
 */

enum
{
        ...
};

const int PRESET_HSV_RULE               = 0;

static LXtTextValueHint hint_hsvRule[] = {
        ...
        };

CRuleHSVColorModelCommand::CRuleHSVColorModelCommand ()
{
        ...
}

        int
CRuleHSVColorModelCommand::basic_CmdFlags ()
{
        ...
}

        bool
CRuleHSVColorModelCommand::basic_Notifier (
        int                      index,
        string                  &name,
        string                  &args)
{
       ...
}

        bool
CRuleHSVColorModelCommand::basic_Enable (CLxUser_Message &msg)
{
       ...
}

        void
CRuleHSVColorModelCommand::cmd_Execute (unsigned int flags)
{
        ...
}

        LxResult
CRuleHSVColorModelCommand::cmd_Query (
        unsigned int     index,
        ILxUnknownID     vaQuery)
{
        ...
}

        void
CRuleHSVColorModelCommand::atrui_UIHints (
        unsigned int             index,
        CLxUser_UIHints         &hints)
{
}


/*
 * ---------------------------------------------------------------------------
 * CRuleAdjustHSVColorModelCommand
 */

enum
{
       ...
};

/*
 * Preset rule adjust values vary by rule.
 */
const double DEG2RAD = 0.017453292519943295769236907684886;

const double PRESET_HSV_RULE_ADJUST_COMPLEMENTARY       = 180.0 * DEG2RAD;
const double PRESET_HSV_RULE_ADJUST_ANALOGOUS           = 30.0 * DEG2RAD;
const double PRESET_HSV_RULE_ADJUST_TRIADIC             = 120.0 * DEG2RAD;
const double PRESET_HSV_RULE_ADJUST_TETRADIC            = 45.0 * DEG2RAD;
const double PRESET_HSV_RULE_ADJUST_COMPOUND            = 30.0 * DEG2RAD;

CRuleAdjustHSVColorModelCommand::CRuleAdjustHSVColorModelCommand ()
{
        ...
}

        int
CRuleAdjustHSVColorModelCommand::basic_CmdFlags ()
{
        ...
}

        bool
CRuleAdjustHSVColorModelCommand::basic_Notifier (
        int                      index,
        string                  &name,
        string                  &args)
{
       ...
}

        bool
CRuleAdjustHSVColorModelCommand::basic_Enable (CLxUser_Message &msg)
{
        ...
}

        void
CRuleAdjustHSVColorModelCommand::cmd_Execute (unsigned int flags)
{
       ...
}

        LxResult
CRuleAdjustHSVColorModelCommand::cmd_Query (
        unsigned int     index,
        ILxUnknownID     vaQuery)
{
        ...
}

        void
CRuleAdjustHSVColorModelCommand::atrui_UIHints (
        unsigned int             index,
        CLxUser_UIHints         &hints)
{
        ...
}


/*
 * ---------------------------------------------------------------------------
 * CLevelsHSVColorModelCommand
 */

enum
{
       ...
};

const int PRESET_HSV_LEVELS             = 11;

CLevelsHSVColorModelCommand::CLevelsHSVColorModelCommand ()
{
        ...
}

        int
CLevelsHSVColorModelCommand::basic_CmdFlags ()
{
        ...
}

        bool
CLevelsHSVColorModelCommand::basic_Notifier (
        int                      index,
        string                  &name,
        string                  &args)
{
        ...
}

        bool
CLevelsHSVColorModelCommand::basic_Enable (CLxUser_Message &msg)
{
       ...
}

        void
CLevelsHSVColorModelCommand::cmd_Execute (unsigned int flags)
{
       ...
}

        LxResult
CLevelsHSVColorModelCommand::cmd_Query (unsigned int index, ILxUnknownID vaQuery)
{
       ...
}

        void
CLevelsHSVColorModelCommand::atrui_UIHints (
        unsigned int             index,
        CLxUser_UIHints         &hints)
{
       ...
}


/*
 * ---------------------------------------------------------------------------
 * CSaveAsPresetsHSVColorModelCommand
 */

enum
{
        ...
};

CSaveAsPresetsHSVColorModelCommand::CSaveAsPresetsHSVColorModelCommand ()
{
        ...
}

        int
CSaveAsPresetsHSVColorModelCommand::basic_CmdFlags ()
{
       ...
}

        bool
CSaveAsPresetsHSVColorModelCommand::basic_Notifier (
        int                      index,
        string                  &name,
        string                  &args)
{
       ...
}

        bool
CSaveAsPresetsHSVColorModelCommand::basic_Enable (CLxUser_Message &msg)
{
       ...
}

/*
 * Query a series of color.value commands, to retrieve the selected
 * base color's component values, from which the rule-based color
 * swatches will be built.
 */
        static bool
QueryColorValueCmd (
        HSVColor                &baseColor)
{
        ...
}

        static bool
QueryPBViewPathCmd (
        string          &path)
{
       ...
}

/*
 * Execute the color.presetSaveWithModel commmand,
 * to generate a preset for the given swatch.
 */
        static void
ExecuteHSVPresetSaveWithModelCmd (
        const HSVColor          &hsvColor,
        unsigned                 swatchIndex,
        string                  &swatchPath)
{
       ...
}

        void
CSaveAsPresetsHSVColorModelCommand::cmd_Execute (unsigned int flags)
{
       ...
}

        LxResult
CSaveAsPresetsHSVColorModelCommand::cmd_Query (unsigned int index, ILxUnknownID vaQuery)
{
        ...
}

        void
CSaveAsPresetsHSVColorModelCommand::atrui_UIHints (
        unsigned int             index,
        CLxUser_UIHints         &hints)
{
       ...

}

This code block implements all the functions for the CHSVColorModel ./ColorModel_Object class. The utility of each specific function I described above in documenting their declaration.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
LXtTagInfoDesc   CHSVColorModel::descInfo[] = {
        { LXsLOD_CLASSLIST,     LXa_COLORMODEL          },
        { LXsSRV_USERNAME,      "HSV"                   },
        { LXsSRV_LOGSUBSYSTEM,  SERVER_HSV_COLOR_MODEL  },
        { 0 }
};

/*
 * The minimum margin in pixels on all sides.
 */
const float HUE_WHEEL_MARGIN            = 5.0f;

/*
 * The percentage of the major dimension to use for rule-based swatches.
 */
const float MINIMUM_SWATCH_SIZE = 0.15f;

/*
 * Aspect ratio.
 */
enum {
        WHEEL_ASPECT_HORIZONTAL,
        WHEEL_ASPECT_VERTICAL
};

struct Metrics
{
       ...
};

        static void
ResizeWheelAndRuleSwatches (
        unsigned         sliceWidth,
        unsigned         sliceHeight,
        Metrics         &metrics)
{
       ...
}

/*
 * Return whether or not the given image (X, Y) coordinates are
 * tracking within a swatch.
 */
        static bool
TrackSwatch (
        Metrics         &metrics,
        unsigned         xAxis,
        unsigned         yAxis,
        unsigned         imageWidth,
        unsigned         imageHeight,
        unsigned         imageX,
        unsigned         imageY,
        LXtFVector       downVec,
        LXtFVector       hsv)
{
       ...
}

CHSVColorModel::CHSVColorModel ()
        :
        rangeWorker(NULL)
{
       ...
}

CHSVColorModel::~CHSVColorModel ()
{
}

        int
CHSVColorModel::colm_NumComponents (void)
{
        return 3; // H, S, and V
}

        LxResult
CHSVColorModel::colm_ComponentType (
        unsigned         componentIndex,
        const char      **type)
{
        ...
}

        LxResult
CHSVColorModel::colm_ComponentRange (
        unsigned         componentIndex,
        float           *minValue,
        float           *maxValue)
{
       ...
}

        LxResult
CHSVColorModel::colm_ToRGB (
        const float     *hsv,
        float           *rgb)
{
       ...
}

        LxResult
CHSVColorModel::colm_FromRGB (
        const float     *rgb,
        float           *hsv)
{
        ...
}

#define LERP(a,l,h)  ((l) + (((h) - (l)) * (a)))
const float DEG2RADF = static_cast<float>(DEG2RAD);

/*
 * Remap an HSV hue such that red, yellow, and blue are triadic,
 * instead of red, green, and blue.
 */
        static inline float
HueRGBtoRYB (float hue)
{
       ...
}

/*
 * The inverse of HueRGBtoRYB.
 */
        static inline float
HueRYBtoRGB (float hue)
{
        ...
}

CHSVColorModelThreadRangeWorker::CHSVColorModelThreadRangeWorker ()
{
}

CHSVColorModelThreadRangeWorker::~CHSVColorModelThreadRangeWorker ()
{
}

typedef struct st_HSVColorModelDrawSlice_env
{
        ...
} HSVColorModelDrawSlice_env;

        LxResult
CHSVColorModelThreadRangeWorker::rngw_Execute (
        int              index,
        void            *sharedData)
{
        ...
}

        LxResult
CHSVColorModel::colm_DrawSlice (
        ILxUnknownID     image,
        unsigned         xAxis,
        unsigned         yAxis,
        const float     *vec)
{
        ...
}

class RGBColor
{
    ...
};

class Point2D
{
    ...
};

        LxResult
CHSVColorModel::colm_DrawSliceMarker (
        ILxUnknownID     image,
        unsigned         xAxis,
        unsigned         yAxis,
        const float     *downVec,
        const float     *hsv)
{
        ...
}

        LxResult
CHSVColorModel::colm_CanSliceBeReused (
        unsigned          xAxis,
        unsigned          yAxis,
        const float      *oldVec,
        const float      *newVec)
{
        ...
}

/*
 * Calculate imgX and imgY in [0, imgW], [0, imgH], from hsv color
 * components on the plane specified by xAxis, yAxis.
 */
        LxResult
CHSVColorModel::colm_ToSlicePos (
        unsigned         xAxis,
        unsigned         yAxis,
        unsigned         imgW,
        unsigned         imgH,
        const float     *hsv,
        unsigned        *imgX,
        unsigned        *imgY)
{
        ...
}

/*
 * Calculate color model components hsv using imgX and imgY in [0, 1],
 * on the plane specified by xAxis, yAxis.
 *
 * NOTE: The other axis (the one that is neither x nor y) component value
 *       should already be set by the last bar selection or the initial
 *       color load.
 */
        LxResult
CHSVColorModel::colm_FromSlicePos (
        unsigned         xAxis,
        unsigned         yAxis,
        unsigned         imgW,
        unsigned         imgH,
        unsigned         imgX,
        unsigned         imgY,
        float           *downVec,
        float           *hsv)
{
        ...
}

/*
 * Return a clean vector so the color picker can drawn the horizontal
 * strip properly.  For hue, this is 0, 1, 1, for saturation we set the
 * value to 1 but leave the rest alone, and for value we set the hue to zero.
 */
        LxResult
CHSVColorModel::colm_StripBaseVector (
        unsigned         axis,
        int              dynamic,
        float           *hsv)
{
       ...
}

        bool
CHSVColorModel::HueAxisOnStrip ()
{
        ...
}

        bool
CHSVColorModel::HueAsWheel ()
{
        ...
}

        unsigned
CHSVColorModel::Wheel ()
{
        ...
}

        unsigned
CHSVColorModel::Rule ()
{
        ...
}

        float
CHSVColorModel::RuleAdjust ()
{
        ...
}

        float
CHSVColorModel::PresetRuleAdjust ()
{
        ...
}

        unsigned
CHSVColorModel::Levels ()
{
        ...
}

        unsigned
CHSVColorModel::SwatchCount ()
{
        ...
}

        void
CHSVColorModel::BuildSwatches (
        const HSVColor          &baseColor,
        vector<HSVColor>        &swatchColors,
        unsigned                &baseColorIndex)
{
        ...
}

/*
 * Selected color and its opposite.
 */
        void
CHSVColorModel::BuildComplementarySwatches (
        const HSVColor          &baseColor,
        vector<HSVColor>        &swatchColors,
        unsigned                &baseColorIndex)
{
       ...
}

/*
 * Adjacent colors.
 */
        void
CHSVColorModel::BuildAnalogousSwatches (
        const HSVColor          &baseColor,
        vector<HSVColor>        &swatchColors,
        unsigned                &baseColorIndex)
{
        ...
}

/*
 * Three colors at 120 degree stops.
 */
        void
CHSVColorModel::BuildTriadicSwatches (
        const HSVColor          &baseColor,
        vector<HSVColor>        &swatchColors,
        unsigned                &baseColorIndex)
{
       ...
}

/*
 * Four colors at 45 degree stops.
 */
        void
CHSVColorModel::BuildTetradicSwatches (
        const HSVColor          &baseColor,
        vector<HSVColor>        &swatchColors,
        unsigned                &baseColorIndex)
{
        ...
}

/*
 * Five colors at 30 and 45 degree stops.
 */
        void
CHSVColorModel::BuildCompoundSwatches (
        const HSVColor          &baseColor,
        vector<HSVColor>        &swatchColors,
        unsigned                &baseColorIndex)
{
        ...
}

/*
 * Variations by tint.
 */
        void
CHSVColorModel::BuildTintsSwatches (
        const HSVColor          &baseColor,
        vector<HSVColor>        &swatchColors,
        unsigned                &baseColorIndex)
{
     ...
}

/*
 * Variations by shade.
 */
        void
CHSVColorModel::BuildShadesSwatches (
        const HSVColor          &baseColor,
        vector<HSVColor>        &swatchColors,
        unsigned                &baseColorIndex)
{
     ...

}

This code block implements the functions of the CHSVColorModelThreadRangeWorker class

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
CHSVColorModelThreadRangeWorker::~CHSVColorModelThreadRangeWorker ()
{
}

typedef struct st_HSVColorModelDrawSlice_env
{
        ...
} HSVColorModelDrawSlice_env;

        LxResult
CHSVColorModelThreadRangeWorker::rngw_Execute (
        int              index,
        void            *sharedData)
{
      ...
}