1
/**************************************************************************\
3
* This file is part of the Coin 3D visualization library.
4
* Copyright (C) 1998-2005 by Systems in Motion. All rights reserved.
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* ("GPL") version 2 as published by the Free Software Foundation.
9
* See the file LICENSE.GPL at the root directory of this source
10
* distribution for additional information about the GNU GPL.
12
* For using Coin with software that can not be combined with the GNU
13
* GPL, and for taking advantage of the additional benefits of our
14
* support services, please contact Systems in Motion about acquiring
15
* a Coin Professional Edition License.
17
* See <URL:http://www.coin3d.org/> for more information.
19
* Systems in Motion, Postboks 1283, Pirsenteret, 7462 Trondheim, NORWAY.
20
* <URL:http://www.sim.no/>.
22
\**************************************************************************/
24
#include <Inventor/SbPList.h>
25
#include <Inventor/SoSceneManager.h>
26
#include <Inventor/fields/SoSFColor.h>
27
#include <Inventor/fields/SoMFColor.h>
28
#include <Inventor/fields/SoMFUInt32.h>
29
#include <Inventor/nodes/SoSwitch.h>
30
#include <Inventor/nodes/SoSeparator.h>
31
#include <Inventor/nodes/SoTexture2.h>
32
#include <Inventor/sensors/SoFieldSensor.h>
33
#include <Inventor/actions/SoGLRenderAction.h>
35
#include <Inventor/Qt/SoAny.h>
37
#include <Inventor/Qt/nodes/SoGuiViewportFix.h>
38
#include <Inventor/Qt/nodes/SoGuiPane.h>
39
#include <Inventor/Qt/nodes/SoGuiClickCounter.h>
40
#include <Inventor/Qt/nodes/SoGuiSlider1.h>
41
#include <Inventor/Qt/nodes/SoGuiSlider2.h>
43
#include <Inventor/Qt/nodes/SoGuiColorEditor.h>
47
\class SoGuiColorEditor Inventor/Qt/editors/SoGuiColorEditor.h
48
\brief The SoGuiColorEditor class is a GUI component for interactively
53
\enum SoGuiColorEditor::Sliders
57
\val SoGuiColorEditor::NONE
61
\val SoGuiColorEditor::INTENSITY
65
\val SoGuiColorEditor::RGB
69
\val SoGuiColorEditor::HSV
73
\val SoGuiColorEditor::RGB_V
77
\val SoGuiColorEditor::RGB_HSV
81
\enum SoGuiColorEditor::Update
85
\val SoGuiColorEditor::CONTINUOUS
89
\val SoGuiColorEditor::AFTER_ACCEPT
92
// *************************************************************************
96
SoGuiColorEditor * api;
98
void colorChange(void);
100
SoFieldSensor * color_sensor;
101
static void color_update_cb(void * closure, SoSensor * sensor);
104
SoGuiClickCounter * switcher;
105
SoGuiSlider1 * slider_r; // red
106
SoGuiSlider1 * slider_g; // green
107
SoGuiSlider1 * slider_b; // blue
108
SoGuiSlider1 * slider_h; // hue
109
SoGuiSlider1 * slider_s; // saturation
110
SoGuiSlider1 * slider_v; // value
111
SoGuiSlider2 * slider_wheel;
113
SoFieldSensor * sensor_r;
114
SoFieldSensor * sensor_g;
115
SoFieldSensor * sensor_b;
116
SoFieldSensor * sensor_h;
117
SoFieldSensor * sensor_s;
118
SoFieldSensor * sensor_v;
119
SoFieldSensor * sensor_wheel;
121
static void update_r_cb(void * closure, SoSensor * sensor);
122
static void update_g_cb(void * closure, SoSensor * sensor);
123
static void update_b_cb(void * closure, SoSensor * sensor);
124
static void update_h_cb(void * closure, SoSensor * sensor);
125
static void update_s_cb(void * closure, SoSensor * sensor);
126
static void update_v_cb(void * closure, SoSensor * sensor);
127
static void update_wheel_cb(void * closure, SoSensor * sensor);
129
static const char * editorscene[];
131
static float calculateHue(float x, float y);
132
static SbVec2f calculateFromHue(float h, float s, float v);
134
void generateSliderTextureR(const SbColor & current, SbBool wysiwyg);
135
void generateSliderTextureG(const SbColor & current, SbBool wysiwyg);
136
void generateSliderTextureB(const SbColor & current, SbBool wysiwyg);
137
void generateSliderTextureH(const SbColor & current, SbBool wysiwyg);
138
void generateSliderTextureS(const SbColor & current, SbBool wysiwyg);
139
void generateSliderTextureV(const SbColor & current, SbBool wysiwyg);
140
void generateSliderTextureHSV(const SbColor & current, SbBool wysiwyg);
143
// *************************************************************************
145
#define PRIVATE(obj) ((ColorEditor *) ((SoGuiColorEditor *) obj)->internals)
146
#define PUBLIC(obj) (((ColorEditor *) obj)->api)
149
SoGuiColorEditor::initClass(void)
151
SO_KIT_INIT_CLASS(SoGuiColorEditor, SoBaseKit, "BaseKit");
154
SO_KIT_SOURCE(SoGuiColorEditor);
156
SoGuiColorEditor::SoGuiColorEditor(void)
158
this->internals = (void *) new ColorEditor;
159
PRIVATE(this)->api = this;
161
SO_KIT_CONSTRUCTOR(SoGuiColorEditor);
163
SO_KIT_ADD_FIELD(wysiwyg, (FALSE));
164
SO_KIT_ADD_FIELD(color, (SbColor(0.0f, 0.0f, 0.0f)));
165
SO_KIT_ADD_FIELD(sliders, (SoGuiColorEditor::RGB_V));
166
SO_KIT_ADD_FIELD(update, (SoGuiColorEditor::AFTER_ACCEPT));
168
SO_KIT_DEFINE_ENUM_VALUE(Sliders, NONE);
169
SO_KIT_DEFINE_ENUM_VALUE(Sliders, INTENSITY);
170
SO_KIT_DEFINE_ENUM_VALUE(Sliders, RGB);
171
SO_KIT_DEFINE_ENUM_VALUE(Sliders, HSV);
172
SO_KIT_DEFINE_ENUM_VALUE(Sliders, RGB_V);
173
SO_KIT_DEFINE_ENUM_VALUE(Sliders, RGB_HSV);
175
SO_KIT_DEFINE_ENUM_VALUE(Update, CONTINUOUS);
176
SO_KIT_DEFINE_ENUM_VALUE(Update, AFTER_ACCEPT);
178
SO_KIT_SET_SF_ENUM_TYPE(sliders, Sliders);
179
SO_KIT_SET_SF_ENUM_TYPE(update, Update);
181
SO_KIT_ADD_CATALOG_ENTRY(root, SoGuiPane, TRUE, this, "", FALSE);
183
SO_KIT_INIT_INSTANCE();
185
PRIVATE(this)->switcher = NULL;
186
PRIVATE(this)->sensor_r = NULL;
187
PRIVATE(this)->sensor_g = NULL;
188
PRIVATE(this)->sensor_b = NULL;
189
PRIVATE(this)->sensor_h = NULL;
190
PRIVATE(this)->sensor_s = NULL;
191
PRIVATE(this)->sensor_v = NULL;
192
PRIVATE(this)->sensor_wheel = NULL;
194
PRIVATE(this)->editor = NULL;
196
SoNode * scene = SoAny::loadSceneGraph(ColorEditor::editorscene);
197
assert(scene != NULL);
198
assert(scene->isOfType(SoGuiPane::getClassTypeId()));
200
PRIVATE(this)->editor = (SoGuiPane *) scene;
201
PRIVATE(this)->editor->ref();
202
PRIVATE(this)->switcher = (SoGuiClickCounter *) SoAny::scanSceneForName(PRIVATE(this)->editor, "switcher");
203
PRIVATE(this)->slider_r = (SoGuiSlider1 *) SoAny::scanSceneForName(PRIVATE(this)->editor, "slider_r", TRUE);
204
PRIVATE(this)->slider_g = (SoGuiSlider1 *) SoAny::scanSceneForName(PRIVATE(this)->editor, "slider_g", TRUE);
205
PRIVATE(this)->slider_b = (SoGuiSlider1 *) SoAny::scanSceneForName(PRIVATE(this)->editor, "slider_b", TRUE);
206
PRIVATE(this)->slider_h = (SoGuiSlider1 *) SoAny::scanSceneForName(PRIVATE(this)->editor, "slider_h", TRUE);
207
PRIVATE(this)->slider_s = (SoGuiSlider1 *) SoAny::scanSceneForName(PRIVATE(this)->editor, "slider_s", TRUE);
208
PRIVATE(this)->slider_v = (SoGuiSlider1 *) SoAny::scanSceneForName(PRIVATE(this)->editor, "slider_v", TRUE);
209
PRIVATE(this)->slider_wheel = (SoGuiSlider2 *) SoAny::scanSceneForName(PRIVATE(this)->editor, "colorwheel", TRUE);
210
if ( PRIVATE(this)->slider_r ) {
211
PRIVATE(this)->slider_r->ref();
212
PRIVATE(this)->sensor_r = new SoFieldSensor(ColorEditor::update_r_cb, PRIVATE(this));
213
PRIVATE(this)->sensor_r->attach(&(PRIVATE(this)->slider_r->value));
214
PRIVATE(this)->generateSliderTextureR(this->color.getValue(), FALSE);
216
if ( PRIVATE(this)->slider_g ) {
217
PRIVATE(this)->slider_g->ref();
218
PRIVATE(this)->sensor_g = new SoFieldSensor(ColorEditor::update_g_cb, PRIVATE(this));
219
PRIVATE(this)->sensor_g->attach(&(PRIVATE(this)->slider_g->value));
220
PRIVATE(this)->generateSliderTextureG(this->color.getValue(), FALSE);
222
if ( PRIVATE(this)->slider_b ) {
223
PRIVATE(this)->slider_b->ref();
224
PRIVATE(this)->sensor_b = new SoFieldSensor(ColorEditor::update_b_cb, PRIVATE(this));
225
PRIVATE(this)->sensor_b->attach(&(PRIVATE(this)->slider_b->value));
226
PRIVATE(this)->generateSliderTextureB(this->color.getValue(), FALSE);
228
if ( PRIVATE(this)->slider_h ) {
229
PRIVATE(this)->slider_h->ref();
230
PRIVATE(this)->sensor_h = new SoFieldSensor(ColorEditor::update_h_cb, PRIVATE(this));
231
PRIVATE(this)->sensor_h->attach(&(PRIVATE(this)->slider_h->value));
232
PRIVATE(this)->generateSliderTextureH(this->color.getValue(), FALSE);
234
if ( PRIVATE(this)->slider_s ) {
235
PRIVATE(this)->slider_s->ref();
236
PRIVATE(this)->sensor_s = new SoFieldSensor(ColorEditor::update_s_cb, PRIVATE(this));
237
PRIVATE(this)->sensor_s->attach(&(PRIVATE(this)->slider_s->value));
238
PRIVATE(this)->generateSliderTextureS(this->color.getValue(), FALSE);
241
if ( PRIVATE(this)->slider_v ) {
242
PRIVATE(this)->slider_v->ref();
243
PRIVATE(this)->sensor_v = new SoFieldSensor(ColorEditor::update_v_cb, PRIVATE(this));
244
PRIVATE(this)->sensor_v->attach(&(PRIVATE(this)->slider_v->value));
245
PRIVATE(this)->generateSliderTextureV(this->color.getValue(), FALSE);
247
if ( PRIVATE(this)->slider_wheel ) {
248
PRIVATE(this)->slider_wheel->ref();
249
PRIVATE(this)->sensor_wheel = new SoFieldSensor(ColorEditor::update_wheel_cb, PRIVATE(this));
250
PRIVATE(this)->sensor_wheel->attach(&(PRIVATE(this)->slider_wheel->value));
251
PRIVATE(this)->generateSliderTextureHSV(this->color.getValue(), FALSE);
254
PRIVATE(this)->editor->unrefNoDelete();
255
this->setAnyPart("root", scene);
257
PRIVATE(this)->color_sensor = new SoFieldSensor(ColorEditor::color_update_cb, PRIVATE(this));
258
PRIVATE(this)->color_sensor->attach(&(this->color));
260
// SoGuiViewportFix * viewportfix = (SoGuiViewportFix *) SoAny::scanSceneForName(inherited::getSceneGraph(), "viewportfix", FALSE);
261
// assert(viewportfix != NULL);
262
// PRIVATE(this)->editor->objectSize.connectFrom(&(viewportfix->viewportSize));
265
SoGuiColorEditor::~SoGuiColorEditor(void)
267
ColorEditor * instance = PRIVATE(this);
271
// *************************************************************************
275
ColorEditor::editorscene[] = {
276
"#Inventor V2.1 ascii",
277
"DEF pane SoGuiPane {",
279
" objectSize 400 340 0",
280
// Calculate positions
282
" position = DEF windowgeometry Calculator {",
283
" A = USE pane.objectSize",
284
" B 120 120 0", // colorwheel size
285
" C 140 30 0", // clickcounter size
286
" a 2", // width of frame
288
" \"oA = vec3f(a, A[1] - C[1] - a, 0)\"", // clickcounter pos
289
" \"oB = vec3f(A[0] - B[0] - a, A[1] - B[1] - a, 0)\"", // colorwheel pos
293
// Create a click counter
294
" DEF switcher SoGuiClickCounter {",
295
" size = USE windowgeometry.C",
296
" first 2 # the INTENSITY sliders",
297
" last 6 # the RGB_HSV sliders",
298
" value 5 # start with the RGB_V group",
300
// Create a frame around the click counter area
302
" size = USE windowgeometry.C",
306
// Create labels for the click counter
309
" scaleFactor 2 2 2",
311
" DEF sliderlabel SoGuiLabel {",
312
" which = USE switcher.value",
324
// Create a frame around the color wheel
325
" SoGuiPosition { position = USE windowgeometry.oB }",
327
" size = USE windowgeometry.B",
332
// Create the color wheel
333
" DEF colorwheel SoGuiSlider2 {",
334
" size = USE windowgeometry.B",
336
// Position the sliders
338
" position = DEF slidergeometry Calculator {",
339
" A = USE pane.objectSize",
340
" B = USE windowgeometry.B", // color wheel size
341
" a = USE windowgeometry.a", // width of frame
343
" c 30", // width of text
345
" \"ta = (A[1] - (2*a + B[1]) - 7*b) / 6\"", // slider height
346
" \"tb = A[0] - 2*b - c\"", // slider width
347
" \"oA = vec3f(tb, ta, 0)\"", // slider size
348
" \"oB = vec3f(c+b , b, 0)\"", // slider pos
349
" \"oC = vec3f(0, ta + b, 0)\"", // slider translation
350
" \"oD = vec3f(-c, 0, 0)\"", // slider label translation
354
// Create the sliders depending on the click count value
356
" whichChild = USE switcher.value",
357
" Group {", // never to be rendered...
358
" DEF slider_r SoGuiSlider1 { size = USE slidergeometry.oA }",
359
" DEF slider_g SoGuiSlider1 { size = USE slidergeometry.oA }",
360
" DEF slider_b SoGuiSlider1 { size = USE slidergeometry.oA }",
361
" DEF slider_h SoGuiSlider1 { size = USE slidergeometry.oA }",
362
" DEF slider_s SoGuiSlider1 { size = USE slidergeometry.oA }",
363
" DEF slider_v SoGuiSlider1 { size = USE slidergeometry.oA }",
364
" DEF slider_translation SoGuiTranslation { translation = USE slidergeometry.oC }",
365
" DEF slider_frame SoGuiFrame {",
366
" size = USE slidergeometry.oA ",
371
" DEF label_translation SoGuiTranslation { translation = USE slidergeometry.oD }",
372
" DEF label_scale Scale { scaleFactor 2 2 2 }",
373
" DEF label_r Separator {",
374
" USE label_translation",
376
" SoGuiLabel { text \"R\" }",
378
" DEF label_g Separator {",
379
" USE label_translation",
381
" SoGuiLabel { text \"G\" }",
383
" DEF label_b Separator {",
384
" USE label_translation",
386
" SoGuiLabel { text \"B\" }",
388
" DEF label_h Separator {",
389
" USE label_translation",
391
" SoGuiLabel { text \"H\" }",
393
" DEF label_s Separator {",
394
" USE label_translation",
396
" SoGuiLabel { text \"S\" }",
398
" DEF label_v Separator {",
399
" USE label_translation",
401
" SoGuiLabel { text \"V\" }",
404
" DEF sliders_NONE Group {", // in case we search for names once, instead of indexing
405
" }", // children directly inside setCurrentSliders()
406
" DEF sliders_INTENSITY Group {",
407
" USE slider_frame", // frames before sliders - the knobs must paint over frames
411
" DEF sliders_RGB Group {",
415
" USE slider_translation",
419
" USE slider_translation",
424
" DEF sliders_HSV Group {",
428
" USE slider_translation",
432
" USE slider_translation",
437
" DEF sliders_RGB_V Group {",
438
" USE sliders_INTENSITY",
439
" USE slider_translation",
442
" DEF sliders_RGB_HSV Group {",
444
" USE slider_translation",
453
// *************************************************************************
456
ColorEditor::colorChange(void)
458
float r = 0.0f, g = 0.0f, b = 0.0f, h = 0.0f, s = 0.0f, v = 0.0f;
459
SbColor color(PUBLIC(this)->color.getValue());
460
color.getValue(r, g, b);
461
color.getHSVValue(h, s, v);
463
SbVec2f wheel(this->calculateFromHue(h, s, v));
465
this->sensor_r->detach();
466
this->sensor_g->detach();
467
this->sensor_b->detach();
468
this->sensor_h->detach();
469
this->sensor_s->detach();
470
this->sensor_v->detach();
471
this->sensor_wheel->detach();
473
if ( r != this->slider_r->value.getValue() ) this->slider_r->value.setValue(r);
474
if ( g != this->slider_g->value.getValue() ) this->slider_g->value.setValue(g);
475
if ( b != this->slider_b->value.getValue() ) this->slider_b->value.setValue(b);
476
if ( h != this->slider_h->value.getValue() ) this->slider_h->value.setValue(h);
477
if ( s != this->slider_s->value.getValue() ) this->slider_s->value.setValue(s);
478
if ( v != this->slider_v->value.getValue() ) this->slider_v->value.setValue(v);
479
if ( wheel != this->slider_wheel->value.getValue() ) this->slider_wheel->value.setValue(wheel);
481
assert(PUBLIC(this) != NULL);
482
if ( PUBLIC(this)->wysiwyg.getValue() ) {
483
this->generateSliderTextureR(color, TRUE);
484
this->generateSliderTextureG(color, TRUE);
485
this->generateSliderTextureB(color, TRUE);
486
this->generateSliderTextureH(color, TRUE);
487
this->generateSliderTextureS(color, TRUE);
488
this->generateSliderTextureV(color, TRUE);
489
this->generateSliderTextureHSV(color, TRUE);
492
this->sensor_r->attach(&(this->slider_r->value));
493
this->sensor_g->attach(&(this->slider_g->value));
494
this->sensor_b->attach(&(this->slider_b->value));
495
this->sensor_h->attach(&(this->slider_h->value));
496
this->sensor_s->attach(&(this->slider_s->value));
497
this->sensor_v->attach(&(this->slider_v->value));
498
this->sensor_wheel->attach(&(this->slider_wheel->value));
502
ColorEditor::color_update_cb(void * closure, SoSensor * sensor)
504
assert(closure != NULL);
505
ColorEditor * me = (ColorEditor *) closure;
509
// *************************************************************************
512
ColorEditor::update_r_cb(void * closure, SoSensor * sensor)
514
ColorEditor * me = (ColorEditor *) closure;
516
SbColor color = PUBLIC(me)->color.getValue();
517
color.getValue(r, g, b);
518
r = me->slider_r->value.getValue();
519
color.setValue(r, g, b);
520
PUBLIC(me)->color.setValue(color);
524
ColorEditor::update_g_cb(void * closure, SoSensor * sensor)
526
ColorEditor * me = (ColorEditor *) closure;
528
SbColor color = PUBLIC(me)->color.getValue();
529
color.getValue(r, g, b);
530
g = me->slider_g->value.getValue();
531
color.setValue(r, g, b);
532
PUBLIC(me)->color.setValue(color);
536
ColorEditor::update_b_cb(void * closure, SoSensor * sensor)
538
ColorEditor * me = (ColorEditor *) closure;
540
SbColor color = PUBLIC(me)->color.getValue();
541
color.getValue(r, g, b);
542
b = me->slider_b->value.getValue();
543
color.setValue(r, g, b);
544
PUBLIC(me)->color.setValue(color);
548
ColorEditor::update_h_cb(void * closure, SoSensor * sensor)
550
ColorEditor * me = (ColorEditor *) closure;
552
SbColor color = PUBLIC(me)->color.getValue();
553
color.getHSVValue(h, s, v);
554
h = me->slider_h->value.getValue();
555
color.setHSVValue(h, s, v);
556
PUBLIC(me)->color.setValue(color);
560
ColorEditor::update_s_cb(void * closure, SoSensor * sensor)
562
ColorEditor * me = (ColorEditor *) closure;
564
SbColor color = PUBLIC(me)->color.getValue();
565
color.getHSVValue(h, s, v);
566
s = me->slider_s->value.getValue();
567
color.setHSVValue(h, s, v);
568
PUBLIC(me)->color.setValue(color);
572
ColorEditor::update_v_cb(void * closure, SoSensor * sensor)
574
ColorEditor * me = (ColorEditor *) closure;
576
SbColor color = PUBLIC(me)->color.getValue();
577
color.getHSVValue(h, s, v);
578
v = me->slider_v->value.getValue();
579
color.setHSVValue(h, s, v);
580
PUBLIC(me)->color.setValue(color);
584
ColorEditor::update_wheel_cb(void * closure, SoSensor * sensor)
586
ColorEditor * me = (ColorEditor *) closure;
587
SbVec2f value = me->slider_wheel->value.getValue();
588
value = value * 2.0f - SbVec2f(1.0f, 1.0f);
589
if ( value.length() > 1.0f ) {
591
SbVec2f reverse = (value + SbVec2f(1.0f, 1.0f)) / 2.0f;
592
me->slider_wheel->value.setValue(reverse);
595
if ( value[0] == 0.0f ) h = ((value[1] < 0.0f) ? 3.0f : 1.0f) * float(M_PI) / 2.0f;
596
else h = (float) atan(value[1] / value[0]);
597
if ( value[0] < 0.0f ) h += float(M_PI);
598
if ( h < 0.0f ) h += (2.0f * float(M_PI));
599
h /= 2.0f * float(M_PI);
600
float s = SoQtMin(value.length(), 1.0f); // float precision bugfix
602
float a = 0.0f, b = 0.0f, v = 1.0f;
603
SbColor existing = PUBLIC(me)->color.getValue();
604
existing.getHSVValue(a, b, v);
607
color.setHSVValue(h, s, v);
608
PUBLIC(me)->color.setValue(color);
611
// *************************************************************************
614
ColorEditor::calculateHue(float x, float y)
617
if ( x == 0.0f ) hue = ((y < 0.0f) ? 3.0f : 1.0f) * float(M_PI) / 2.0f;
618
else hue = (float) atan(y / x);
619
if ( x < 0.0f ) hue += float(M_PI);
620
if ( hue < 0.0f ) hue += (2.0f * float(M_PI));
621
return hue / (2.0f * float(M_PI));
625
ColorEditor::calculateFromHue(float h, float s, float v)
627
float hue = h * 2.0f * float(M_PI);
628
return SbVec2f(((float) cos(hue) * s + 1.0f) / 2.0f, ((float) sin(hue) * s + 1.0f) / 2.0f);
631
// *************************************************************************
634
ColorEditor::generateSliderTextureR(const SbColor & current, SbBool wysiwyg)
636
assert(this->slider_r != NULL);
637
float red, green, blue;
638
current.getValue(red, green, blue);
642
SoTexture2 * texture = SO_GET_PART(this->slider_r, "surfaceTexture", SoTexture2);
644
texture->wrapS.setValue(SoTexture2::CLAMP);
645
texture->wrapT.setValue(SoTexture2::CLAMP);
646
SbVec2s size(256, 1);
648
texture->image.setValue(size, nc, NULL);
649
texture->model.setValue(SoTexture2::DECAL);
650
unsigned char * bytes = texture->image.startEditing(size, nc);
652
for ( x = 0; x < size[0]; x++ ) {
653
red = (float) x / (float) (size[0] - 1);
654
for ( y = 0; y < size[1]; y++ ) {
655
bytes[(size[0]*y+x)*nc+0] = (unsigned char) (red * 255.0f);
656
bytes[(size[0]*y+x)*nc+1] = (unsigned char) (green * 255.0f);
657
bytes[(size[0]*y+x)*nc+2] = (unsigned char) (blue * 255.0f);
658
// if ( nc > 3 ) bytes[(size[0]*y+x)*nc+4] = 255;
661
texture->image.finishEditing();
665
ColorEditor::generateSliderTextureG(const SbColor & current, SbBool wysiwyg)
667
assert(this->slider_g != NULL);
668
float red, green, blue;
669
current.getValue(red, green, blue);
673
SoTexture2 * texture = SO_GET_PART(this->slider_g, "surfaceTexture", SoTexture2);
675
texture->wrapS.setValue(SoTexture2::CLAMP);
676
texture->wrapT.setValue(SoTexture2::CLAMP);
677
SbVec2s size(256, 1);
679
texture->image.setValue(size, nc, NULL);
680
texture->model.setValue(SoTexture2::DECAL);
681
unsigned char * bytes = texture->image.startEditing(size, nc);
683
for ( x = 0; x < size[0]; x++ ) {
684
green = (float) x / (float) (size[0] - 1);
685
for ( y = 0; y < size[1]; y++ ) {
686
bytes[(size[0]*y+x)*nc+0] = (unsigned char) (red * 255.0f);
687
bytes[(size[0]*y+x)*nc+1] = (unsigned char) (green * 255.0f);
688
bytes[(size[0]*y+x)*nc+2] = (unsigned char) (blue * 255.0f);
689
// if ( nc > 3 ) bytes[(size[0]*y+x)*nc+4] = 255;
692
texture->image.finishEditing();
696
ColorEditor::generateSliderTextureB(const SbColor & current, SbBool wysiwyg)
698
assert(this->slider_b != NULL);
699
float red, green, blue;
700
current.getValue(red, green, blue);
704
SoTexture2 * texture = SO_GET_PART(this->slider_b, "surfaceTexture", SoTexture2);
706
texture->wrapS.setValue(SoTexture2::CLAMP);
707
texture->wrapT.setValue(SoTexture2::CLAMP);
708
SbVec2s size(256, 1);
710
texture->image.setValue(size, nc, NULL);
711
texture->model.setValue(SoTexture2::DECAL);
712
unsigned char * bytes = texture->image.startEditing(size, nc);
714
for ( x = 0; x < size[0]; x++ ) {
715
blue = (float) x / (float) (size[0] - 1);
716
for ( y = 0; y < size[1]; y++ ) {
717
bytes[(size[0]*y+x)*nc+0] = (unsigned char) (red * 255.0f);
718
bytes[(size[0]*y+x)*nc+1] = (unsigned char) (green * 255.0f);
719
bytes[(size[0]*y+x)*nc+2] = (unsigned char) (blue * 255.0f);
720
// if ( nc > 3 ) bytes[(size[0]*y+x)*nc+4] = 255;
723
texture->image.finishEditing();
727
ColorEditor::generateSliderTextureH(const SbColor & current, SbBool wysiwyg)
729
assert(this->slider_h != NULL);
730
float hue, saturation, value;
731
current.getHSVValue(hue, saturation, value);
736
SoTexture2 * texture = SO_GET_PART(this->slider_h, "surfaceTexture", SoTexture2);
738
texture->wrapS.setValue(SoTexture2::CLAMP);
739
texture->wrapT.setValue(SoTexture2::CLAMP);
740
SbVec2s size(256, 1);
742
texture->image.setValue(size, nc, NULL);
743
texture->model.setValue(SoTexture2::DECAL);
744
unsigned char * bytes = texture->image.startEditing(size, nc);
746
for ( x = 0; x < size[0]; x++ ) {
747
const float hue = (float) x / (float) (size[0] - 1);
748
for ( y = 0; y < size[1]; y++ ) {
749
float r = 0.0f, g = 0.0f, b = 0.0f;
750
SbColor color(r, g, b);
751
color.setHSVValue(hue, saturation, value);
752
color.getValue(r, g, b);
753
bytes[(size[0]*y+x)*nc+0] = (unsigned char) (r * 255.0f);
754
bytes[(size[0]*y+x)*nc+1] = (unsigned char) (g * 255.0f);
755
bytes[(size[0]*y+x)*nc+2] = (unsigned char) (b * 255.0f);
756
// if ( nc > 3 ) bytes[(size[0]*y+x)*nc+4] = 255;
759
texture->image.finishEditing();
763
ColorEditor::generateSliderTextureS(const SbColor & current, SbBool wysiwyg)
765
assert(this->slider_s != NULL);
766
float hue, saturation, value;
767
current.getHSVValue(hue, saturation, value);
772
SoTexture2 * texture = SO_GET_PART(this->slider_s, "surfaceTexture", SoTexture2);
774
texture->wrapS.setValue(SoTexture2::CLAMP);
775
texture->wrapT.setValue(SoTexture2::CLAMP);
776
SbVec2s size(256, 1);
778
texture->image.setValue(size, nc, NULL);
779
texture->model.setValue(SoTexture2::DECAL);
780
unsigned char * bytes = texture->image.startEditing(size, nc);
782
for ( x = 0; x < size[0]; x++ ) {
783
const float saturation = (float) x / (float) (size[0] - 1);
784
for ( y = 0; y < size[1]; y++ ) {
785
float r = 0.0f, g = 0.0f, b = 0.0f;
786
SbColor color(r, g, b);
787
color.setHSVValue(hue, saturation, value);
788
color.getValue(r, g, b);
789
bytes[(size[0]*y+x)*nc+0] = (unsigned char) (r * 255.0f);
790
bytes[(size[0]*y+x)*nc+1] = (unsigned char) (g * 255.0f);
791
bytes[(size[0]*y+x)*nc+2] = (unsigned char) (b * 255.0f);
792
// if ( nc > 3 ) bytes[(size[0]*y+x)*nc+4] = 255;
795
texture->image.finishEditing();
799
ColorEditor::generateSliderTextureV(const SbColor & current, SbBool wysiwyg)
801
assert(this->slider_v != NULL);
802
float hue, saturation, value;
803
current.getHSVValue(hue, saturation, value);
808
SoTexture2 * texture = SO_GET_PART(this->slider_v, "surfaceTexture", SoTexture2);
810
texture->wrapS.setValue(SoTexture2::CLAMP);
811
texture->wrapT.setValue(SoTexture2::CLAMP);
812
SbVec2s size(256, 1);
814
texture->image.setValue(size, nc, NULL);
815
texture->model.setValue(SoTexture2::DECAL);
816
unsigned char * bytes = texture->image.startEditing(size, nc);
818
for ( x = 0; x < size[0]; x++ ) {
819
const float value = (float) x / (float) (size[0] - 1);
820
for ( y = 0; y < size[1]; y++ ) {
821
float r = 0.0f, g = 0.0f, b = 0.0f;
822
SbColor color(r, g, b);
823
color.setHSVValue(hue, saturation, value);
824
color.getValue(r, g, b);
825
bytes[(size[0]*y+x)*nc+0] = (unsigned char) (r * 255.0f);
826
bytes[(size[0]*y+x)*nc+1] = (unsigned char) (g * 255.0f);
827
bytes[(size[0]*y+x)*nc+2] = (unsigned char) (b * 255.0f);
828
// if ( nc > 3 ) bytes[(size[0]*y+x)*nc+4] = 255;
831
texture->image.finishEditing();
835
ColorEditor::generateSliderTextureHSV(const SbColor & current, SbBool wysiwyg)
837
assert(this->slider_wheel != NULL);
838
float hue, saturation, value;
839
current.getHSVValue(hue, saturation, value);
844
SoTexture2 * texture = SO_GET_PART(this->slider_wheel, "surfaceTexture", SoTexture2);
846
texture->wrapS.setValue(SoTexture2::CLAMP);
847
texture->wrapT.setValue(SoTexture2::CLAMP);
848
SbVec2s size(256, 256);
850
texture->image.setValue(size, nc, NULL);
851
texture->model.setValue(SoTexture2::DECAL);
852
unsigned char * bytes = texture->image.startEditing(size, nc);
854
const float halfx = (float) size[0] / 2.0f;
855
const float halfy = (float) size[1] / 2.0f;
856
for ( y = 0; y < size[1]; y++ ) {
857
const float ypos = ((float) y - halfy) / halfy;
858
for ( x = 0; x < size[0]; x++ ) {
859
const float xpos = ((float) x - halfx) / halfx;
860
const float saturation = (float) sqrt(xpos * xpos + ypos * ypos);
861
float hue = ColorEditor::calculateHue(xpos, ypos);
862
float red = 0.0f, green = 0.0f, blue = 0.0f;
863
SbColor color(red, green, blue);
864
if ( saturation <= 1.0f ) color.setHSVValue(hue, saturation, value);
865
color.getValue(red, green, blue);
866
bytes[(size[0]*y+x)*nc+0] = (unsigned char) (red * 255.0f);
867
bytes[(size[0]*y+x)*nc+1] = (unsigned char) (green * 255.0f);
868
bytes[(size[0]*y+x)*nc+2] = (unsigned char) (blue * 255.0f);
869
// if ( nc > 3 ) bytes[(size[0]*y+x)*nc+4] = 255;
872
texture->image.finishEditing();
875
// *************************************************************************