1// @configure_input@ 2 3/**************************************************************************\ 4 * Copyright (c) Kongsberg Oil & Gas Technologies AS 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: 10 * 11 * Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the following disclaimer. 13 * 14 * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * Neither the name of the copyright holder nor the names of its 19 * contributors may be used to endorse or promote products derived from 20 * this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33\**************************************************************************/ 34 35#ifdef HAVE_CONFIG_H 36#include <config.h> 37#endif // HAVE_CONFIG_H 38 39#include <assert.h> 40 41#include <Inventor/nodes/SoMaterial.h> 42#include <Inventor/sensors/SoFieldSensor.h> 43#include <Inventor/sensors/SoNodeSensor.h> 44#ifdef HAVE_SOVRMLMATERIAL 45#include <Inventor/VRMLnodes/SoVRMLMaterial.h> 46#endif // HAVE_SOVRMLMATERIAL 47 48#include <Inventor/@Gui@/SoAny.h> 49#include <Inventor/@Gui@/nodes/SoGuiPane.h> 50#include <Inventor/@Gui@/nodes/SoGuiImage.h> 51#include <Inventor/@Gui@/nodes/SoGuiSceneTexture2.h> 52#include <Inventor/@Gui@/nodes/SoGuiSlider1.h> 53#include <Inventor/@Gui@/nodes/SoGuiToggleButton.h> 54#include <Inventor/@Gui@/nodes/SoGuiRadioButton.h> 55#include <Inventor/@Gui@/nodes/SoGuiColorEditor.h> 56 57#include <Inventor/@Gui@/nodes/SoGuiMaterialEditor.h> 58 59// ************************************************************************* 60 61class MaterialEditor { 62public: 63 MaterialEditor(void); 64 ~MaterialEditor(void); 65 66 SoGuiMaterialEditor * api; 67 68 SoMaterial * material; 69 SoNodeSensor * material_sensor; 70 static void material_cb(void * closure, SoSensor * sensor); 71 72 SoFieldSensor * material_field_sensor; 73 static void material_field_cb(void * closure, SoSensor * sensor); 74 75 SoGuiToggleButton * button1; 76 SoGuiToggleButton * button2; 77 SoGuiToggleButton * button3; 78 SoGuiToggleButton * button4; 79 SoFieldSensor * button1_sensor; 80 SoFieldSensor * button2_sensor; 81 SoFieldSensor * button3_sensor; 82 SoFieldSensor * button4_sensor; 83 static void button1_cb(void * closure, SoSensor * sensor); 84 static void button2_cb(void * closure, SoSensor * sensor); 85 static void button3_cb(void * closure, SoSensor * sensor); 86 static void button4_cb(void * closure, SoSensor * sensor); 87 SoGuiRadioButton * radio1; 88 SoGuiRadioButton * radio2; 89 SoGuiRadioButton * radio3; 90 SoGuiRadioButton * radio4; 91 92 SoGuiSlider1 * slider1; 93 SoGuiSlider1 * slider2; 94 SoGuiSlider1 * slider3; 95 SoGuiSlider1 * slider4; 96 SoGuiSlider1 * slider5; 97 SoGuiSlider1 * slider6; 98 SoFieldSensor * ambient_slider_sensor; 99 SoFieldSensor * diffuse_slider_sensor; 100 SoFieldSensor * specular_slider_sensor; 101 SoFieldSensor * emissive_slider_sensor; 102 SoFieldSensor * shininess_slider_sensor; 103 SoFieldSensor * transparency_slider_sensor; 104 static void ambient_slider_cb(void * closure, SoSensor * sensor); 105 static void diffuse_slider_cb(void * closure, SoSensor * sensor); 106 static void specular_slider_cb(void * closure, SoSensor * sensor); 107 static void emissive_slider_cb(void * closure, SoSensor * sensor); 108 static void shininess_slider_cb(void * closure, SoSensor * sensor); 109 static void transparency_slider_cb(void * closure, SoSensor * sensor); 110 111 SoGuiColorEditorOpenCB * openeditorcb; 112 SoGuiColorEditorCloseCB * closeeditorcb; 113 void * cbclosure; 114 115 static SoGuiColorEditor * coloreditoropen_cb(void * closure); 116 static void coloreditorclose_cb(void * closure, SoGuiColorEditor * editor); 117 118 SbBool coloreditoropen; 119 SoGuiColorEditor * coloreditor; 120 SoFieldSensor * coloreditor_sensor; 121 static void coloreditor_cb(void * closure, SoSensor * sensor); 122 123 void checkColorEditorOpenStatus(void); 124 125 static const char * texturescene[]; 126 static const char * editorscene[]; 127}; 128 129// ************************************************************************* 130 131#define PRIVATE(obj) ((MaterialEditor *) ((SoGuiMaterialEditor *) obj)->internals) 132 133void 134SoGuiMaterialEditor::initClass(void) 135{ 136 SO_KIT_INIT_CLASS(SoGuiMaterialEditor, SoBaseKit, "BaseKit"); 137} 138 139SO_KIT_SOURCE(SoGuiMaterialEditor); 140 141SoGuiMaterialEditor::SoGuiMaterialEditor(void) 142{ 143 this->internals = new MaterialEditor; 144 PRIVATE(this)->api = this; 145 146 SO_KIT_CONSTRUCTOR(SoGuiMaterialEditor); 147 148 SO_KIT_ADD_FIELD(material, (NULL)); 149 SO_KIT_ADD_FIELD(index, (0)); 150 SO_KIT_ADD_FIELD(update, (CONTINUOUS)); 151 152 SO_KIT_DEFINE_ENUM_VALUE(Update, CONTINUOUS); 153 SO_KIT_DEFINE_ENUM_VALUE(Update, AFTER_ACCEPT); 154 155 SO_KIT_SET_SF_ENUM_TYPE(update, Update); 156 157 SO_KIT_ADD_CATALOG_ENTRY(root, SoGuiPane, TRUE, this, "", FALSE); 158 159 SO_KIT_INIT_INSTANCE(); 160 161 SoNode * scene = SoAny::loadSceneGraph(MaterialEditor::editorscene); 162 assert(scene != NULL); 163 assert(scene->isOfType(SoGuiPane::getClassTypeId())); 164 scene->ref(); 165 166 SoGuiImage * sphereimage = 167 (SoGuiImage *) SoAny::scanSceneForName(scene, "image"); 168 assert(sphereimage != NULL); 169 scene->unrefNoDelete(); 170 SbBool ok = this->setAnyPart("root", scene); 171 assert(ok); 172 173 PRIVATE(this)->button1 = (SoGuiToggleButton *) SoAny::scanSceneForName(scene, "tbutton1"); 174 PRIVATE(this)->button2 = (SoGuiToggleButton *) SoAny::scanSceneForName(scene, "tbutton2"); 175 PRIVATE(this)->button3 = (SoGuiToggleButton *) SoAny::scanSceneForName(scene, "tbutton3"); 176 PRIVATE(this)->button4 = (SoGuiToggleButton *) SoAny::scanSceneForName(scene, "tbutton4"); 177 assert(PRIVATE(this)->button1); 178 assert(PRIVATE(this)->button2); 179 assert(PRIVATE(this)->button3); 180 assert(PRIVATE(this)->button4); 181 PRIVATE(this)->radio1 = (SoGuiRadioButton *) SoAny::scanSceneForName(scene, "rbutton1"); 182 PRIVATE(this)->radio2 = (SoGuiRadioButton *) SoAny::scanSceneForName(scene, "rbutton2"); 183 PRIVATE(this)->radio3 = (SoGuiRadioButton *) SoAny::scanSceneForName(scene, "rbutton3"); 184 PRIVATE(this)->radio4 = (SoGuiRadioButton *) SoAny::scanSceneForName(scene, "rbutton4"); 185 assert(PRIVATE(this)->radio1); 186 assert(PRIVATE(this)->radio2); 187 assert(PRIVATE(this)->radio3); 188 assert(PRIVATE(this)->radio4); 189 190 PRIVATE(this)->slider1 = (SoGuiSlider1 *) SoAny::scanSceneForName(scene, "slider1"); 191 PRIVATE(this)->slider2 = (SoGuiSlider1 *) SoAny::scanSceneForName(scene, "slider2"); 192 PRIVATE(this)->slider3 = (SoGuiSlider1 *) SoAny::scanSceneForName(scene, "slider3"); 193 PRIVATE(this)->slider4 = (SoGuiSlider1 *) SoAny::scanSceneForName(scene, "slider4"); 194 PRIVATE(this)->slider5 = (SoGuiSlider1 *) SoAny::scanSceneForName(scene, "slider5"); 195 PRIVATE(this)->slider6 = (SoGuiSlider1 *) SoAny::scanSceneForName(scene, "slider6"); 196 assert(PRIVATE(this)->slider1); 197 assert(PRIVATE(this)->slider2); 198 assert(PRIVATE(this)->slider3); 199 assert(PRIVATE(this)->slider4); 200 assert(PRIVATE(this)->slider5); 201 assert(PRIVATE(this)->slider6); 202 PRIVATE(this)->slider1->setSurfaceColor(SbColor(0,0,0), SbColor(1,1,1)); 203 PRIVATE(this)->slider2->setSurfaceColor(SbColor(0,0,0), SbColor(1,1,1)); 204 PRIVATE(this)->slider3->setSurfaceColor(SbColor(0,0,0), SbColor(1,1,1)); 205 PRIVATE(this)->slider4->setSurfaceColor(SbColor(0,0,0), SbColor(1,1,1)); 206 PRIVATE(this)->slider5->setSurfaceColor(SbColor(0,0,0), SbColor(1,1,1)); 207 PRIVATE(this)->slider6->setSurfaceColor(SbColor(0,0,0), SbColor(1,1,1)); 208 209 SoNode * textureroot = SoAny::loadSceneGraph(MaterialEditor::texturescene); 210 assert(textureroot != NULL); 211 assert(textureroot->isOfType(SoSeparator::getClassTypeId())); 212 SoNode * texture = ((SoSeparator *) textureroot)->getChild(0); 213 assert(texture != NULL); 214 assert(texture->isOfType(SoGuiSceneTexture2::getClassTypeId())); 215 216 SoNode * subscene = ((SoGuiSceneTexture2 *) texture)->scene.getValue(); 217 assert(subscene); 218 subscene->ref(); 219 PRIVATE(this)->material = (SoMaterial *) SoAny::scanSceneForName(subscene, "material"); 220 subscene->unrefNoDelete(); 221 assert(PRIVATE(this)->material); 222 223 ok = sphereimage->setPart("texture", texture); 224 assert(ok); 225 226 PRIVATE(this)->ambient_slider_sensor = new SoFieldSensor(MaterialEditor::ambient_slider_cb, PRIVATE(this)); 227 PRIVATE(this)->diffuse_slider_sensor = new SoFieldSensor(MaterialEditor::diffuse_slider_cb, PRIVATE(this)); 228 PRIVATE(this)->specular_slider_sensor = new SoFieldSensor(MaterialEditor::specular_slider_cb, PRIVATE(this)); 229 PRIVATE(this)->emissive_slider_sensor = new SoFieldSensor(MaterialEditor::emissive_slider_cb, PRIVATE(this)); 230 PRIVATE(this)->shininess_slider_sensor = new SoFieldSensor(MaterialEditor::shininess_slider_cb, PRIVATE(this)); 231 PRIVATE(this)->transparency_slider_sensor = new SoFieldSensor(MaterialEditor::transparency_slider_cb, PRIVATE(this)); 232 PRIVATE(this)->ambient_slider_sensor->attach(&(PRIVATE(this)->slider1->value)); 233 PRIVATE(this)->diffuse_slider_sensor->attach(&(PRIVATE(this)->slider2->value)); 234 PRIVATE(this)->specular_slider_sensor->attach(&(PRIVATE(this)->slider3->value)); 235 PRIVATE(this)->emissive_slider_sensor->attach(&(PRIVATE(this)->slider4->value)); 236 PRIVATE(this)->shininess_slider_sensor->attach(&(PRIVATE(this)->slider5->value)); 237 PRIVATE(this)->transparency_slider_sensor->attach(&(PRIVATE(this)->slider6->value)); 238 239 PRIVATE(this)->button1_sensor = new SoFieldSensor(MaterialEditor::button1_cb, PRIVATE(this)); 240 PRIVATE(this)->button2_sensor = new SoFieldSensor(MaterialEditor::button2_cb, PRIVATE(this)); 241 PRIVATE(this)->button3_sensor = new SoFieldSensor(MaterialEditor::button3_cb, PRIVATE(this)); 242 PRIVATE(this)->button4_sensor = new SoFieldSensor(MaterialEditor::button4_cb, PRIVATE(this)); 243 PRIVATE(this)->button1_sensor->attach(&(PRIVATE(this)->button1->on)); 244 PRIVATE(this)->button2_sensor->attach(&(PRIVATE(this)->button2->on)); 245 PRIVATE(this)->button3_sensor->attach(&(PRIVATE(this)->button3->on)); 246 PRIVATE(this)->button4_sensor->attach(&(PRIVATE(this)->button4->on)); 247 248 PRIVATE(this)->material_sensor = new SoNodeSensor(MaterialEditor::material_cb, PRIVATE(this)); 249 PRIVATE(this)->material_sensor->attach(PRIVATE(this)->material); 250 PRIVATE(this)->material->touch(); 251 252 PRIVATE(this)->material_field_sensor = new SoFieldSensor(MaterialEditor::material_field_cb, PRIVATE(this)); 253 PRIVATE(this)->material_field_sensor->attach(&(this->material)); 254 255 this->setColorEditorCallbacks(MaterialEditor::coloreditoropen_cb, MaterialEditor::coloreditorclose_cb, PRIVATE(this)); 256} 257 258SoGuiMaterialEditor::~SoGuiMaterialEditor(void) 259{ 260 MaterialEditor * obj = PRIVATE(this); 261 delete obj; 262} 263 264void 265SoGuiMaterialEditor::setColorEditorCallbacks( 266 SoGuiColorEditorOpenCB * open, 267 SoGuiColorEditorCloseCB * close, 268 void * closure) 269{ 270 PRIVATE(this)->openeditorcb = open; 271 PRIVATE(this)->closeeditorcb = close; 272 PRIVATE(this)->cbclosure = closure; 273} 274 275SoMaterial * 276SoGuiMaterialEditor::getSphereMaterialNode(void) const 277{ 278 return PRIVATE(this)->material; 279} 280 281// ************************************************************************* 282// MaterialEditor 283// ************************************************************************* 284 285#define PUBLIC(obj) (((MaterialEditor *) obj)->api) 286 287// +--------------------------------------------------------------------+ 288// | | o x Ambient |======================| 0.00 | 289// | | o x Diffuse |======================| 0.00 | 290// | | o x Specular |======================| 0.00 | 291// | | o x Emissive |======================| 0.00 | 292// | | | 293// | | Shininess |======================| 0.00 | 294// | | Transp |======================| 0.00 | 295// +--------------------------------------------------------------------+ 296// [nice - Ed] 297 298const char * 299MaterialEditor::texturescene[] = 300{ 301 "#Inventor V2.1 ascii", 302 "", 303 "SoGuiSceneTexture2 {", 304 " scene", 305 " Separator {", 306 " OrthographicCamera {", 307 " position 0 0 2", 308 " nearDistance 1", 309 " farDistance 3", 310 " height 2", 311 " }", 312 " LightModel { model BASE_COLOR }", 313 " BaseColor {", 314 " rgb [ 0.3 0.3 0.3, 0.6 0.6 0.6, 0.6 0.6 0.6, 0.3 0.3 0.3 ]", 315 " }", 316 " MaterialBinding { value PER_FACE }", 317 " Coordinate3 {", 318 " point [", 319 " -3 3 0, 0 3 0, 3 3 0,", 320 " -3 0 0, 0 0 0, 3 0 0,", 321 " -3 -3 0, 0 -3 0, 3 -3 0", 322 " ]", 323 " }", 324 " QuadMesh {", 325 " verticesPerColumn 3", 326 " verticesPerRow 3", 327 " }", 328 " LightModel { model PHONG }", 329 " DirectionalLight { direction 0.556 -0.623 -0.551 }", 330 " DirectionalLight { direction -0.556 -0.623 -0.551 }", 331 " DEF material Material { }", 332 " Complexity { value 0.8 }", 333 " ShapeHints { vertexOrdering COUNTERCLOCKWISE shapeType SOLID }", 334 " Sphere { radius 0.85 }", 335 " }", 336 "}", 337 NULL 338}; 339 340// FIXME: add labels 341// FIXME: adjust geometry 342 343const char * 344MaterialEditor::editorscene[] = 345{ 346 "#Inventor V2.1 ascii", 347 "", 348 "DEF pane SoGuiPane {", 349 " worldSize 1 1 0", 350 " objectSize 550 300 0", 351 " SoGuiPosition {", 352 " position = DEF wm Calculator {", 353 " A = USE pane.objectSize", 354 " expression [", 355 " \"ta = (A[0] / 2 < A[1]) ? (A[0]/2)-20 : A[1]-20\"", 356 " \"tb = (A[1] - ta) / 2\"", 357 " \"oA = vec3f(10, tb, 0)\"", // image position 358 " \"oB = vec3f(ta, ta, 0)\"", // image size 359 " \"oC = vec3f(ta + 30, A[1] - 25, 0)\"", // radio1 position 360 " \"oD = vec3f(0, -30, 0)\"", // ratio translation 361 " ]", 362 " } . oA", 363 " }", 364 " DEF image SoGuiImage { size = USE wm.oB }", 365 " SoGuiFrame {", 366 " size = USE image.size", 367 " design EMBOSS", 368 " width 2", 369 " complement TRUE", 370 " }", 371 " SoGuiPosition { position = USE wm.oC }", 372 " DEF rbutton1 SoGuiRadioButton {", 373 " size 10 10 0", 374 " on = DEF rbuttons SoGuiRadioGroup {", 375 " in0 = USE rbutton1.on", 376 " in1 = DEF rbutton2 SoGuiRadioButton { size 10 10 0 on = USE rbuttons.out1 } . on", 377 " in2 = DEF rbutton3 SoGuiRadioButton { size 10 10 0 on = USE rbuttons.out2 } . on", 378 " in3 = DEF rbutton4 SoGuiRadioButton { size 10 10 0 on = USE rbuttons.out3 } . on", 379 " } . out0", 380 " }", 381 " SoGuiFrame {", 382 " size = USE rbutton1.size", 383 " width 2", 384 " complement = USE rbutton1.on", 385 " }", 386 " SoGuiTranslation { translation = USE wm.oD }", 387 " USE rbutton2", 388 " SoGuiFrame {", 389 " size = USE rbutton2.size", 390 " width 2", 391 " complement = USE rbutton2.on", 392 " }", 393 " SoGuiTranslation { translation = USE wm.oD }", 394 " USE rbutton3", 395 " SoGuiFrame {", 396 " size = USE rbutton3.size", 397 " width 2", 398 " complement = USE rbutton3.on", 399 " }", 400 " SoGuiTranslation { translation = USE wm.oD }", 401 " USE rbutton4", 402 " SoGuiFrame {", 403 " size = USE rbutton4.size", 404 " width 2", 405 " complement = USE rbutton4.on", 406 " }", 407 " SoGuiPosition {", 408 " position = DEF wm2 Calculator {", 409 " A = USE pane.objectSize", 410 " expression [", 411 " \"ta = (A[0] / 2 < A[1]) ? (A[0]/2)-20 : A[1]-20\"", 412 " \"oA = vec3f(ta + 60, A[1] - 25, 0)\"", 413 " \"oB = vec3f(ta + 90, A[1] - 25, 0)\"", 414 " \"oC = vec3f(ta - 100, 15, 0)\"", 415 " ]", 416 " } . oA", 417 " }", 418 " DEF tbutton1 SoGuiToggleButton {", 419 " size 10 10 0" 420 " on = USE rbuttons.out0", 421 " }", 422 " SoGuiFrame {", 423 " size = USE tbutton1.size", 424 " width 2", 425 " complement = USE tbutton1.on", 426 " design EMBOSS", 427 " }", 428 " SoGuiTranslation { translation = USE wm.oD }", 429 " DEF tbutton2 SoGuiToggleButton {", 430 " size 10 10 0" 431 " on = USE rbuttons.out1", 432 " }", 433 " SoGuiFrame {", 434 " size = USE tbutton2.size", 435 " width 2", 436 " complement = USE tbutton2.on", 437 " design EMBOSS", 438 " }", 439 " SoGuiTranslation { translation = USE wm.oD }", 440 " DEF tbutton3 SoGuiToggleButton {", 441 " size 10 10 0" 442 " on = USE rbuttons.out2", 443 " }", 444 " SoGuiFrame {", 445 " size = USE tbutton3.size", 446 " width 2", 447 " complement = USE tbutton3.on", 448 " design EMBOSS", 449 " }", 450 " SoGuiTranslation { translation = USE wm.oD }", 451 " DEF tbutton4 SoGuiToggleButton {", 452 " size 10 10 0" 453 " on = USE rbuttons.out3", 454 " }", 455 " SoGuiFrame {", 456 " size = USE tbutton4.size", 457 " width 2", 458 " complement = USE tbutton4.on", 459 " design EMBOSS", 460 " }", 461 462 " SoGuiPosition { position = USE wm2.oB }", 463 " DEF sliderframe SoGuiFrame {", 464 " size = USE wm2.oC", 465 " width 2", 466 " complement TRUE", 467 " design EMBOSS", 468 " }", 469 " DEF slider1 SoGuiSlider1 { size = USE sliderframe.size }", 470 " SoGuiTranslation { translation = USE wm.oD }", 471 " USE sliderframe", 472 " DEF slider2 SoGuiSlider1 { size = USE sliderframe.size }", 473 " SoGuiTranslation { translation = USE wm.oD }", 474 " USE sliderframe", 475 " DEF slider3 SoGuiSlider1 { size = USE sliderframe.size }", 476 " SoGuiTranslation { translation = USE wm.oD }", 477 " USE sliderframe", 478 " DEF slider4 SoGuiSlider1 { size = USE sliderframe.size }", 479 " SoGuiTranslation { translation = USE wm.oD }", 480 " SoGuiTranslation { translation = USE wm.oD }", 481 " USE sliderframe", 482 " DEF slider5 SoGuiSlider1 { size = USE sliderframe.size }", 483 " SoGuiTranslation { translation = USE wm.oD }", 484 " USE sliderframe", 485 " DEF slider6 SoGuiSlider1 { size = USE sliderframe.size }", 486 487 " SoGuiPosition { position = USE pane.objectSize }", 488 " SoGuiTranslation { translation -35 -25 0 }", 489 " DEF labelframe SoGuiFrame { size 25 15 0 width 2 design EMBOSS complement TRUE }", 490 " SoGuiLabel { text = SoGuiFormat { format \"%4.2f\" float1 = USE slider1.value } . output }", 491 " SoGuiTranslation { translation = USE wm.oD }", 492 " USE labelframe", 493 " SoGuiLabel { text = SoGuiFormat { format \"%4.2f\" float1 = USE slider2.value } . output }", 494 " SoGuiTranslation { translation = USE wm.oD }", 495 " USE labelframe", 496 " SoGuiLabel { text = SoGuiFormat { format \"%4.2f\" float1 = USE slider3.value } . output }", 497 " SoGuiTranslation { translation = USE wm.oD }", 498 " USE labelframe", 499 " SoGuiLabel { text = SoGuiFormat { format \"%4.2f\" float1 = USE slider4.value } . output }", 500 " SoGuiTranslation { translation = USE wm.oD }", 501 " SoGuiTranslation { translation = USE wm.oD }", 502 " USE labelframe", 503 " SoGuiLabel { text = SoGuiFormat { format \"%4.2f\" float1 = USE slider5.value } . output }", 504 " SoGuiTranslation { translation = USE wm.oD }", 505 " USE labelframe", 506 " SoGuiLabel { text = SoGuiFormat { format \"%4.2f\" float1 = USE slider6.value } . output }", 507 "}", 508 NULL 509}; 510 511MaterialEditor::MaterialEditor(void) 512{ 513 this->api = NULL; 514 this->material = NULL; 515 this->button1 = NULL; 516 this->button2 = NULL; 517 this->button3 = NULL; 518 this->button4 = NULL; 519 this->radio1 = NULL; 520 this->radio2 = NULL; 521 this->radio3 = NULL; 522 this->radio4 = NULL; 523 this->slider1 = NULL; 524 this->slider2 = NULL; 525 this->slider3 = NULL; 526 this->slider4 = NULL; 527 this->slider5 = NULL; 528 this->slider6 = NULL; 529 this->ambient_slider_sensor = NULL; 530 this->diffuse_slider_sensor = NULL; 531 this->specular_slider_sensor = NULL; 532 this->emissive_slider_sensor = NULL; 533 this->shininess_slider_sensor = NULL; 534 this->transparency_slider_sensor = NULL; 535 this->coloreditoropen = FALSE; 536 this->coloreditor = NULL; 537 this->coloreditor_sensor = NULL; 538} 539 540MaterialEditor::~MaterialEditor(void) 541{ 542 if ( this->coloreditor_sensor ) delete this->coloreditor_sensor; 543} 544 545void 546MaterialEditor::ambient_slider_cb(void * closure, SoSensor * sensor) 547{ 548 assert(closure); 549 MaterialEditor * me = (MaterialEditor *) closure; 550 assert(me->material); 551 assert(me->slider1); 552 SbColor ambient = me->material->ambientColor[0]; 553 float h, s, v; 554 ambient.getHSVValue(h, s, v); 555 v = me->slider1->value.getValue(); 556 ambient.setHSVValue(h, s, v); 557 if ( ambient != me->material->ambientColor[0] ) 558 me->material->ambientColor.set1Value(0, ambient); 559} 560 561void 562MaterialEditor::diffuse_slider_cb(void * closure, SoSensor * sensor) 563{ 564 assert(closure); 565 MaterialEditor * me = (MaterialEditor *) closure; 566 assert(me->material); 567 assert(me->slider2); 568 SbColor diffuse = me->material->diffuseColor[0]; 569 float h, s, v; 570 diffuse.getHSVValue(h, s, v); 571 v = me->slider2->value.getValue(); 572 diffuse.setHSVValue(h, s, v); 573 if ( diffuse != me->material->diffuseColor[0] ) 574 me->material->diffuseColor.set1Value(0, diffuse); 575} 576 577void 578MaterialEditor::specular_slider_cb(void * closure, SoSensor * sensor) 579{ 580 assert(closure); 581 MaterialEditor * me = (MaterialEditor *) closure; 582 assert(me->material); 583 assert(me->slider3); 584 SbColor specular = me->material->specularColor[0]; 585 float h, s, v; 586 specular.getHSVValue(h, s, v); 587 v = me->slider3->value.getValue(); 588 specular.setHSVValue(h, s, v); 589 if ( specular != me->material->specularColor[0] ) 590 me->material->specularColor.set1Value(0, specular); 591} 592 593void 594MaterialEditor::emissive_slider_cb(void * closure, SoSensor * sensor) 595{ 596 assert(closure); 597 MaterialEditor * me = (MaterialEditor *) closure; 598 assert(me->material); 599 assert(me->slider4); 600 SbColor emissive = me->material->emissiveColor[0]; 601 float h, s, v; 602 emissive.getHSVValue(h, s, v); 603 v = me->slider4->value.getValue(); 604 emissive.setHSVValue(h, s, v); 605 if ( emissive != me->material->emissiveColor[0] ) 606 me->material->emissiveColor.set1Value(0, emissive); 607} 608 609void 610MaterialEditor::shininess_slider_cb(void * closure, SoSensor * sensor) 611{ 612 assert(closure); 613 MaterialEditor * me = (MaterialEditor *) closure; 614 assert(me->material); 615 assert(me->slider5); 616 float shininess = me->slider5->value.getValue(); 617 if ( shininess != me->material->shininess[0] ) 618 me->material->shininess.set1Value(0, shininess); 619} 620 621void 622MaterialEditor::transparency_slider_cb(void * closure, SoSensor * sensor) 623{ 624 assert(closure); 625 MaterialEditor * me = (MaterialEditor *) closure; 626 assert(me->material); 627 assert(me->slider6); 628 float transparency = me->slider6->value.getValue(); 629 if ( transparency != me->material->transparency[0] ) 630 me->material->transparency.set1Value(0, transparency); 631} 632 633void 634MaterialEditor::checkColorEditorOpenStatus(void) 635{ 636 if ( this->button1->on.getValue() || 637 this->button2->on.getValue() || 638 this->button3->on.getValue() || 639 this->button4->on.getValue() ) { 640 if ( !this->coloreditoropen && this->openeditorcb ) { 641 this->coloreditor = this->openeditorcb(this->cbclosure); 642 this->coloreditoropen = TRUE; 643 if ( this->coloreditor_sensor == NULL ) 644 this->coloreditor_sensor = new SoFieldSensor(MaterialEditor::coloreditor_cb, this); 645 if ( this->coloreditor ) 646 this->coloreditor_sensor->attach(&(this->coloreditor->color)); 647 } 648 } else { 649 if ( this->coloreditoropen && this->closeeditorcb ) { 650 if ( this->coloreditor_sensor ) this->coloreditor_sensor->detach(); 651 this->closeeditorcb(this->cbclosure, this->coloreditor); 652 this->coloreditor = NULL; 653 this->coloreditoropen = FALSE; 654 } 655 } 656} 657 658void 659MaterialEditor::button1_cb(void * closure, SoSensor * sensor) 660{ 661 assert(closure); 662 MaterialEditor * me = (MaterialEditor *) closure; 663 SbBool down = me->button1->on.getValue(); 664 if ( !down ) { 665 if ( me->radio1->on.getValue() ) me->radio1->on.setValue(FALSE); 666 667 if ( me->button2->on.getValue() && 668 !me->button3->on.getValue() && 669 !me->button4->on.getValue() && 670 !me->radio2->on.getValue() ) me->radio2->on.setValue(TRUE); 671 if ( !me->button2->on.getValue() && 672 me->button3->on.getValue() && 673 !me->button4->on.getValue() && 674 !me->radio3->on.getValue() ) me->radio3->on.setValue(TRUE); 675 if ( !me->button2->on.getValue() && 676 !me->button3->on.getValue() && 677 me->button4->on.getValue() && 678 !me->radio4->on.getValue() ) me->radio4->on.setValue(TRUE); 679 } else { 680 if ( me->radio2->on.getValue() ) me->radio2->on.setValue(FALSE); 681 if ( me->radio3->on.getValue() ) me->radio3->on.setValue(FALSE); 682 if ( me->radio4->on.getValue() ) me->radio4->on.setValue(FALSE); 683 if ( !me->button2->on.getValue() && 684 !me->button3->on.getValue() && 685 !me->button4->on.getValue() && 686 !me->radio1->on.getValue() ) me->radio1->on.setValue(TRUE); 687 } 688 me->checkColorEditorOpenStatus(); 689} 690 691void 692MaterialEditor::button2_cb(void * closure, SoSensor * sensor) 693{ 694 assert(closure); 695 MaterialEditor * me = (MaterialEditor *) closure; 696 SbBool down = me->button2->on.getValue(); 697 if ( !down ) { 698 if ( me->radio2->on.getValue() ) me->radio2->on.setValue(FALSE); 699 if ( me->button1->on.getValue() && 700 !me->button3->on.getValue() && 701 !me->button4->on.getValue() && 702 !me->radio1->on.getValue() ) me->radio1->on.setValue(TRUE); 703 if ( !me->button1->on.getValue() && 704 me->button3->on.getValue() && 705 !me->button4->on.getValue() && 706 !me->radio3->on.getValue() ) me->radio3->on.setValue(TRUE); 707 if ( !me->button1->on.getValue() && 708 !me->button3->on.getValue() && 709 me->button4->on.getValue() && 710 !me->radio4->on.getValue() ) me->radio4->on.setValue(TRUE); 711 } else { 712 if ( me->radio1->on.getValue() ) me->radio1->on.setValue(FALSE); 713 if ( me->radio3->on.getValue() ) me->radio3->on.setValue(FALSE); 714 if ( me->radio4->on.getValue() ) me->radio4->on.setValue(FALSE); 715 if ( !me->button1->on.getValue() && 716 !me->button3->on.getValue() && 717 !me->button4->on.getValue() && 718 !me->radio2->on.getValue() ) me->radio2->on.setValue(TRUE); 719 } 720 me->checkColorEditorOpenStatus(); 721} 722 723void 724MaterialEditor::button3_cb(void * closure, SoSensor * sensor) 725{ 726 assert(closure); 727 assert(closure); 728 MaterialEditor * me = (MaterialEditor *) closure; 729 SbBool down = me->button3->on.getValue(); 730 if ( !down ) { 731 if ( me->radio3->on.getValue() ) me->radio3->on.setValue(FALSE); 732 if ( me->button1->on.getValue() && 733 !me->button2->on.getValue() && 734 !me->button4->on.getValue() && 735 !me->radio1->on.getValue() ) me->radio1->on.setValue(TRUE); 736 if ( !me->button1->on.getValue() && 737 me->button2->on.getValue() && 738 !me->button4->on.getValue() && 739 !me->radio2->on.getValue() ) me->radio2->on.setValue(TRUE); 740 if ( !me->button1->on.getValue() && 741 !me->button2->on.getValue() && 742 me->button4->on.getValue() && 743 !me->radio4->on.getValue() ) me->radio4->on.setValue(TRUE); 744 } else { 745 if ( me->radio1->on.getValue() ) me->radio1->on.setValue(FALSE); 746 if ( me->radio2->on.getValue() ) me->radio2->on.setValue(FALSE); 747 if ( me->radio4->on.getValue() ) me->radio4->on.setValue(FALSE); 748 if ( !me->button1->on.getValue() && 749 !me->button2->on.getValue() && 750 !me->button4->on.getValue() && 751 !me->radio3->on.getValue() ) me->radio3->on.setValue(TRUE); 752 } 753 me->checkColorEditorOpenStatus(); 754} 755 756void 757MaterialEditor::button4_cb(void * closure, SoSensor * sensor) 758{ 759 assert(closure); 760 MaterialEditor * me = (MaterialEditor *) closure; 761 SbBool down = me->button4->on.getValue(); 762 if ( !down ) { 763 if ( me->radio4->on.getValue() ) me->radio4->on.setValue(FALSE); 764 if ( me->button1->on.getValue() && 765 !me->button2->on.getValue() && 766 !me->button3->on.getValue() && 767 !me->radio1->on.getValue() ) me->radio1->on.setValue(TRUE); 768 if ( !me->button1->on.getValue() && 769 me->button2->on.getValue() && 770 !me->button3->on.getValue() && 771 !me->radio2->on.getValue() ) me->radio2->on.setValue(TRUE); 772 if ( !me->button1->on.getValue() && 773 !me->button2->on.getValue() && 774 me->button3->on.getValue() && 775 !me->radio3->on.getValue() ) me->radio3->on.setValue(TRUE); 776 } else { 777 if ( me->radio1->on.getValue() ) me->radio1->on.setValue(FALSE); 778 if ( me->radio2->on.getValue() ) me->radio2->on.setValue(FALSE); 779 if ( me->radio3->on.getValue() ) me->radio3->on.setValue(FALSE); 780 if ( !me->button1->on.getValue() && 781 !me->button2->on.getValue() && 782 !me->button3->on.getValue() && 783 !me->radio4->on.getValue() ) me->radio4->on.setValue(TRUE); 784 } 785 me->checkColorEditorOpenStatus(); 786} 787 788void 789MaterialEditor::coloreditor_cb(void * closure, SoSensor * sensor) 790{ 791 // coloreditor is being interacted with - so update material editor sliders 792 assert(closure); 793 MaterialEditor * me = (MaterialEditor *) closure; 794 if ( me->button1->on.getValue() ) 795 me->material->ambientColor.setValue(me->coloreditor->color.getValue()); 796 if ( me->button2->on.getValue() ) 797 me->material->diffuseColor.setValue(me->coloreditor->color.getValue()); 798 if ( me->button3->on.getValue() ) 799 me->material->specularColor.setValue(me->coloreditor->color.getValue()); 800 if ( me->button4->on.getValue() ) 801 me->material->emissiveColor.setValue(me->coloreditor->color.getValue()); 802} 803 804void 805MaterialEditor::material_cb(void * closure, SoSensor * sensor) 806{ 807 assert(closure); 808 MaterialEditor * me = (MaterialEditor *) closure; 809 SoMaterial * mat = me->material; 810 if ( !mat ) return; 811 float h, s, v; 812 SbColor color = mat->ambientColor[0]; 813 color.getHSVValue(h, s, v); 814 if ( v != me->slider1->value.getValue() ) me->slider1->value.setValue(v); 815 color = mat->diffuseColor[0]; 816 color.getHSVValue(h, s, v); 817 if ( v != me->slider2->value.getValue() ) me->slider2->value.setValue(v); 818 color = mat->specularColor[0]; 819 color.getHSVValue(h, s, v); 820 if ( v != me->slider3->value.getValue() ) me->slider3->value.setValue(v); 821 color = mat->emissiveColor[0]; 822 color.getHSVValue(h, s, v); 823 if ( v != me->slider4->value.getValue() ) me->slider4->value.setValue(v); 824 v = mat->shininess[0]; 825 if ( v != me->slider5->value.getValue() ) me->slider5->value.setValue(v); 826 v = mat->transparency[0]; 827 if ( v != me->slider6->value.getValue() ) me->slider6->value.setValue(v); 828 SoNode * attachment = PUBLIC(me)->material.getValue(); 829 if ( attachment ) { 830 if ( attachment->isOfType(SoMaterial::getClassTypeId()) ) { 831 SoMaterial * material = (SoMaterial *) attachment; 832 int index = PUBLIC(me)->index.getValue(); 833 material->ambientColor.set1Value(index, mat->ambientColor[0]); 834 material->diffuseColor.set1Value(index, mat->diffuseColor[0]); 835 material->specularColor.set1Value(index, mat->specularColor[0]); 836 material->emissiveColor.set1Value(index, mat->emissiveColor[0]); 837 material->shininess.set1Value(index, mat->shininess[0]); 838 material->transparency.set1Value(index, mat->transparency[0]); 839#ifdef HAVE_SOVRMLMATERIAL 840 } else if ( attachment->isOfType(SoVRMLMaterial::getClassTypeId()) ) { 841 SoVRMLMaterial * material = (SoVRMLMaterial *) attachment; 842 SbColor ambient = mat->ambientColor[0]; 843 float h, s, v; 844 ambient.getHSVValue(h, s, v); 845 material->ambientIntensity.setValue(v); 846 material->diffuseColor.setValue(mat->diffuseColor[0]); 847 material->specularColor.setValue(mat->specularColor[0]); 848 material->emissiveColor.setValue(mat->emissiveColor[0]); 849 material->shininess.setValue(mat->shininess[0]); 850 material->transparency.setValue(mat->transparency[0]); 851#endif // HAVE_SOVRMLMATERIAL 852 } else { 853 } 854 } 855} 856 857void 858MaterialEditor::material_field_cb(void * closure, SoSensor * sensor) 859{ 860 assert(closure); 861 MaterialEditor * me = (MaterialEditor *) closure; 862 SoNode * node = PUBLIC(me)->material.getValue(); 863 if ( !node ) return; 864 SoMaterial * mat1 = (SoMaterial *) node; 865 SoMaterial * mat2 = me->material; 866 867 if ( mat1->ambientColor[0] != mat2->ambientColor[0] ) 868 mat2->ambientColor.set1Value(0, mat1->ambientColor[0]); 869 if ( mat1->diffuseColor[0] != mat2->diffuseColor[0] ) 870 mat2->diffuseColor.set1Value(0, mat1->diffuseColor[0]); 871 if ( mat1->specularColor[0] != mat2->specularColor[0] ) 872 mat2->specularColor.set1Value(0, mat1->specularColor[0]); 873 if ( mat1->emissiveColor[0] != mat2->emissiveColor[0] ) 874 mat2->emissiveColor.set1Value(0, mat1->emissiveColor[0]); 875 if ( mat1->shininess[0] != mat2->shininess[0] ) 876 mat2->shininess.set1Value(0, mat1->shininess[0]); 877 if ( mat1->transparency[0] != mat2->transparency[0] ) 878 mat2->transparency.set1Value(0, mat1->transparency[0]); 879} 880 881SoGuiColorEditor * 882MaterialEditor::coloreditoropen_cb(void * closure) 883{ 884 SoDebugError::postInfo("MaterialEditor::coloreditoropen_cb", "default callback invoked - not implemented yet"); 885 return NULL; 886} 887 888void 889MaterialEditor::coloreditorclose_cb(void * closure, SoGuiColorEditor * editor) 890{ 891 SoDebugError::postInfo("MaterialEditor::coloreditorclose_cb", "default callback invoked - not implemented yet"); 892} 893 894#undef PRIVATE 895#undef PUBLIC 896 897// ************************************************************************* 898