00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <math.h>
00024 #include "FL/forms.H"
00025 #include "FL/Fl_Counter.H"
00026 #include "FL/Fl_Value_Slider.H"
00027 #include "FL/Fl_Float_Input.H"
00028 #include "FL/Fl_Tabs.H"
00029 #include "AtomRep.h"
00030 #include "Molecule.h"
00031 #include "VMDApp.h"
00032 #include "MoleculeList.h"
00033
00034
00038 class GraphicsFltkRep : public Fl_Group {
00039 protected:
00040 GraphicsFltkRep()
00041 : Fl_Group(10, 380, 295, 235) {}
00042 virtual void do_reset() {}
00043
00044 char cmdbuf[256];
00045
00046 public:
00047 virtual int is_volumetric() { return 0; }
00048 virtual int is_orbital() { return 0; }
00049 virtual const char *repcmd() = 0;
00050 virtual void set_values(AtomRep *) = 0;
00051 void reset() { do_reset(); }
00052 };
00053
00054
00055 #define CTRWIDTH 120
00056 #define CTRWIDTHSM 80
00057 #define CTRHEIGHT 25
00058
00060 class RadiusCounter : public Fl_Counter {
00061 public:
00062 RadiusCounter(int x, int y, const char *nm)
00063 : Fl_Counter(x, y, CTRWIDTH, CTRHEIGHT, nm) {
00064 minimum(0);
00065 precision(1);
00066 step(.1);
00067 lstep(1);
00068 align(FL_ALIGN_LEFT);
00069 when(FL_WHEN_RELEASE);
00070 }
00071 };
00072
00073
00075 class GridResCounter : public Fl_Counter {
00076 public:
00077 GridResCounter(int x, int y, const char *nm)
00078 : Fl_Counter(x, y, CTRWIDTH, CTRHEIGHT, nm) {
00079 minimum(0.05);
00080 precision(3);
00081 step(0.005);
00082 lstep(0.025);
00083 align(FL_ALIGN_LEFT);
00084 when(FL_WHEN_RELEASE);
00085 }
00086 };
00087
00088
00090 class ResolutionCounter : public Fl_Counter {
00091 public:
00092 ResolutionCounter(int x, int y, const char *nm)
00093 : Fl_Counter(x, y, CTRWIDTH, CTRHEIGHT, nm) {
00094 minimum(1);
00095 precision(0);
00096 step(1);
00097 lstep(5);
00098 align(FL_ALIGN_LEFT);
00099 when(FL_WHEN_RELEASE);
00100 }
00101 };
00102
00103
00105 class StepCounter : public Fl_Counter {
00106 public:
00107 StepCounter(int x, int y, const char *nm)
00108 : Fl_Counter(x, y, 90, CTRHEIGHT, nm) {
00109 minimum(1);
00110 precision(0);
00111 step(1);
00112 lstep(4);
00113 align(FL_ALIGN_LEFT);
00114 when(FL_WHEN_RELEASE);
00115 }
00116 };
00117
00118
00120 class RepChoice : public Fl_Choice {
00121 public:
00122 RepChoice(int x, int y, const char *nm)
00123 : Fl_Choice(x, y, CTRWIDTH, CTRHEIGHT, nm) {
00124 color(VMDMENU_CHOOSER_BG);
00125 selection_color(VMDMENU_CHOOSER_SEL);
00126 align(FL_ALIGN_LEFT);
00127 }
00128 int setvalue(int newvalue) {
00129 if (newvalue >= 0 && newvalue < size())
00130 return Fl_Choice::value(newvalue);
00131 return value();
00132 }
00133 };
00134
00136 class RepChoiceSmall : public Fl_Choice {
00137 public:
00138 RepChoiceSmall(int x, int y, const char *nm)
00139 : Fl_Choice(x, y, CTRWIDTHSM, CTRHEIGHT, nm) {
00140 color(VMDMENU_CHOOSER_BG);
00141 selection_color(VMDMENU_CHOOSER_SEL);
00142 align(FL_ALIGN_LEFT);
00143 }
00144 int setvalue(int newvalue) {
00145 if (newvalue >= 0 && newvalue < size())
00146 return Fl_Choice::value(newvalue);
00147 return value();
00148 }
00149 };
00150
00151
00153 class IsoSlider : public Fl_Value_Slider {
00154 public:
00155 IsoSlider(int x, int y, const char *nm)
00156 : Fl_Value_Slider(x, y, CTRWIDTH+90, CTRHEIGHT, nm) {
00157 color(VMDMENU_SLIDER_BG);
00158 align(FL_ALIGN_LEFT);
00159 type(FL_HOR_SLIDER);
00160 }
00161 };
00162
00164 class ShortSlider : public Fl_Value_Slider {
00165 public:
00166 ShortSlider(int x, int y, const char *nm)
00167 : Fl_Value_Slider(x, y, CTRWIDTH+50, CTRHEIGHT, nm) {
00168 color(VMDMENU_SLIDER_BG);
00169 align(FL_ALIGN_LEFT);
00170 type(FL_HOR_SLIDER);
00171 }
00172 };
00173
00175 class GraphicsFltkRepLines : public GraphicsFltkRep {
00176 public:
00177 GraphicsFltkRepLines(Fl_Callback *cb, void *v) {
00178 thickness = new ResolutionCounter(x()+170, y()+120, "Thickness");
00179 thickness->callback(cb, v);
00180 Fl_Group::end();
00181 }
00182 const char *repcmd() {
00183 sprintf(cmdbuf, "Lines %f", thickness->value());
00184 return cmdbuf;
00185 }
00186 void set_values(AtomRep *rep) {
00187 thickness->value(rep->get_data(AtomRep::LINETHICKNESS));
00188 }
00189
00190 protected:
00191 void do_reset() {
00192 thickness->value(1);
00193 }
00194
00195 private:
00196 Fl_Counter *thickness;
00197 };
00198
00199
00201 class GraphicsFltkRepBonds : public GraphicsFltkRep {
00202 public:
00203 GraphicsFltkRepBonds(Fl_Callback *cb, void *v) {
00204 radius = new RadiusCounter(x()+170, y()+90, "Bond Radius");
00205 resolution= new ResolutionCounter(x()+170,y()+120,"Bond Resolution");
00206 radius->callback(cb, v);
00207 resolution->callback(cb, v);
00208 Fl_Group::end();
00209 }
00210 const char *repcmd() {
00211 sprintf(cmdbuf, "Bonds %f %f", radius->value(), resolution->value());
00212 return cmdbuf;
00213 }
00214 void set_values(AtomRep *rep) {
00215 radius->value(rep->get_data(AtomRep::BONDRAD));
00216 resolution->value(rep->get_data(AtomRep::BONDRES));
00217 }
00218
00219 protected:
00220 void do_reset() {
00221 radius->value(0.3);
00222 resolution->value(12);
00223 }
00224
00225 protected:
00226 Fl_Counter *radius;
00227 Fl_Counter *resolution;
00228 };
00229
00230
00232 class GraphicsFltkRepDynamicBonds : public GraphicsFltkRep {
00233 private:
00234 Fl_Counter *distance;
00235 Fl_Counter *radius;
00236 Fl_Counter *resolution;
00237 public:
00238 GraphicsFltkRepDynamicBonds(Fl_Callback *cb, void *v) {
00239 distance = new RadiusCounter(x()+170,y()+60,"Distance Cutoff");
00240 distance->callback(cb, v);
00241 radius = new RadiusCounter(x()+170, y()+90, "Bond Radius");
00242 radius->callback(cb, v);
00243 resolution= new ResolutionCounter(x()+170,y()+120,"Bond Resolution");
00244 resolution->callback(cb, v);
00245 Fl_Group::end();
00246 }
00247 protected:
00248 void do_reset() {
00249 distance->value(1.6);
00250 radius->value(0.3);
00251 resolution->value(12.0);
00252 }
00253 public:
00254 const char *repcmd() {
00255 sprintf(cmdbuf, "DynamicBonds %f %f %f", distance->value(), radius->value(),
00256 resolution->value());
00257 return cmdbuf;
00258 }
00259 void set_values(AtomRep *rep) {
00260 distance->value(rep->get_data(AtomRep::SPHERERAD));
00261 radius->value(rep->get_data(AtomRep::BONDRAD));
00262 resolution->value(rep->get_data(AtomRep::BONDRES));
00263 }
00264 };
00265
00266
00268 class GraphicsFltkRepCPK : public GraphicsFltkRep {
00269 public:
00270 GraphicsFltkRepCPK(Fl_Callback *cb, void *v) {
00271 bradius = new RadiusCounter(x()+170,y()+90,"Bond Radius");
00272 bresolution= new ResolutionCounter(x()+170,y()+120,"Bond Resolution");
00273 bradius->callback(cb, v);
00274 bresolution->callback(cb, v);
00275
00276 sradius = new RadiusCounter(x()+170,y()+30,"Sphere Scale");
00277 sresolution= new ResolutionCounter(x()+170,y()+60,"Sphere Resolution");
00278 sradius->callback(cb, v);
00279 sresolution->callback(cb, v);
00280
00281 Fl_Group::end();
00282 }
00283
00284 const char *repcmd() {
00285 sprintf(cmdbuf, "CPK %f %f %f %f", sradius->value(), bradius->value(),
00286 sresolution->value(), bresolution->value());
00287 return cmdbuf;
00288 }
00289 void set_values(AtomRep *rep) {
00290 bradius->value(rep->get_data(AtomRep::BONDRAD));
00291 bresolution->value(rep->get_data(AtomRep::BONDRES));
00292 sradius->value(rep->get_data(AtomRep::SPHERERAD));
00293 sresolution->value(rep->get_data(AtomRep::SPHERERES));
00294 }
00295
00296 protected:
00297 void do_reset() {
00298 bradius->value(0.3);
00299 bresolution->value(12);
00300 sradius->value(1.0);
00301 sresolution->value(12);
00302 }
00303
00304 private:
00305 Fl_Counter *bradius;
00306 Fl_Counter *bresolution;
00307 Fl_Counter *sradius;
00308 Fl_Counter *sresolution;
00309 };
00310
00311
00313 class GraphicsFltkRepPoints : public GraphicsFltkRep {
00314 public:
00315 GraphicsFltkRepPoints(Fl_Callback *cb, void *v) {
00316 size = new ResolutionCounter(x()+170, y()+120, "Size");
00317 size->callback(cb, v);
00318 Fl_Group::end();
00319 }
00320 const char *repcmd() {
00321 sprintf(cmdbuf, "Points %f", size->value());
00322 return cmdbuf;
00323 }
00324 void set_values(AtomRep *rep) {
00325 size->value(rep->get_data(AtomRep::LINETHICKNESS));
00326 }
00327
00328 protected:
00329 void do_reset() {
00330 size->value(1);
00331 }
00332
00333 private:
00334 Fl_Counter *size;
00335 };
00336
00337
00338
00340 class GraphicsFltkRepVDW : public GraphicsFltkRep {
00341 public:
00342 GraphicsFltkRepVDW(Fl_Callback *cb, void *v) {
00343 radius = new RadiusCounter(x()+170,y()+90,"Sphere Scale");
00344 resolution= new ResolutionCounter(x()+170,y()+120,"Sphere Resolution");
00345 radius->callback(cb, v);
00346 resolution->callback(cb, v);
00347 Fl_Group::end();
00348 }
00349
00350 const char *repcmd() {
00351 sprintf(cmdbuf, "VDW %f %f", radius->value(), resolution->value());
00352 return cmdbuf;
00353 }
00354 void set_values(AtomRep *rep) {
00355 radius->value(rep->get_data(AtomRep::SPHERERAD));
00356 resolution->value(rep->get_data(AtomRep::SPHERERES));
00357 }
00358
00359 protected:
00360 void do_reset() {
00361 radius->value(1.0);
00362 resolution->value(12);
00363 }
00364
00365 protected:
00366 Fl_Counter *radius;
00367 Fl_Counter *resolution;
00368 };
00369
00370
00372 class GraphicsFltkRepBeads : public GraphicsFltkRepVDW {
00373 public:
00374 GraphicsFltkRepBeads(Fl_Callback *cb, void *v)
00375 : GraphicsFltkRepVDW(cb, v) {}
00376 const char *repcmd() {
00377 sprintf(cmdbuf, "Beads %f %f", radius->value(), resolution->value());
00378 return cmdbuf;
00379 }
00380 };
00381
00382
00384 class GraphicsFltkRepDotted : public GraphicsFltkRepVDW {
00385 public:
00386 GraphicsFltkRepDotted(Fl_Callback *cb, void *v)
00387 : GraphicsFltkRepVDW(cb, v) {}
00388 const char *repcmd() {
00389 sprintf(cmdbuf, "Dotted %f %f", radius->value(), resolution->value());
00390 return cmdbuf;
00391 }
00392 };
00393
00394
00396 class GraphicsFltkRepTrace : public GraphicsFltkRepBonds {
00397 public:
00398 GraphicsFltkRepTrace(Fl_Callback *cb, void *v)
00399 : GraphicsFltkRepBonds(cb, v) {}
00400 const char *repcmd() {
00401 sprintf(cmdbuf, "Trace %f %f", radius->value(), resolution->value());
00402 return cmdbuf;
00403 }
00404 };
00405
00406
00408 class GraphicsFltkRepLicorice : public GraphicsFltkRepBonds {
00409 private:
00410 Fl_Counter *sresolution;
00411 public:
00412 GraphicsFltkRepLicorice(Fl_Callback *cb, void *v)
00413 : GraphicsFltkRepBonds(cb, v) {
00414 Fl_Group::begin();
00415 sresolution= new ResolutionCounter(x()+170,y()+60,"Sphere Resolution");
00416 sresolution->callback(cb, v);
00417
00418 Fl_Group::end();
00419 }
00420 protected:
00421 void do_reset() {
00422 GraphicsFltkRepBonds::do_reset();
00423 resolution->value(12);
00424 sresolution->value(12);
00425 }
00426 public:
00427 const char *repcmd() {
00428 sprintf(cmdbuf, "Licorice %f %f %f", radius->value(), sresolution->value(),
00429 resolution->value());
00430 return cmdbuf;
00431 }
00432 void set_values(AtomRep *rep) {
00433 GraphicsFltkRepBonds::set_values(rep);
00434 sresolution->value(rep->get_data(AtomRep::SPHERERES));
00435 }
00436 };
00437
00438
00439 #ifdef VMDPOLYHEDRA
00440
00441 class GraphicsFltkRepPolyhedra : public GraphicsFltkRep {
00442 private:
00443 Fl_Counter *distance;
00444 public:
00445 GraphicsFltkRepPolyhedra(Fl_Callback *cb, void *v) {
00446 distance = new RadiusCounter(x()+170,y()+60,"Distance Cutoff");
00447 distance->callback(cb, v);
00448 Fl_Group::end();
00449 }
00450 protected:
00451 void do_reset() {
00452 distance->value(1.6);
00453 }
00454 public:
00455 const char *repcmd() {
00456 sprintf(cmdbuf, "Polyhedra %f", distance->value());
00457 return cmdbuf;
00458 }
00459 void set_values(AtomRep *rep) {
00460 distance->value(rep->get_data(AtomRep::SPHERERAD));
00461 }
00462 };
00463 #endif
00464
00466 class GraphicsFltkRepTube : public GraphicsFltkRepBonds {
00467 public:
00468 GraphicsFltkRepTube(Fl_Callback *cb, void *v)
00469 : GraphicsFltkRepBonds(cb, v) {
00470 radius->label("Radius");
00471 resolution->label("Resolution");
00472 }
00473 const char *repcmd() {
00474 sprintf(cmdbuf, "Tube %f %f", radius->value(), resolution->value());
00475 return cmdbuf;
00476 }
00477 };
00478
00479
00481 class GraphicsFltkRepRibbons : public GraphicsFltkRepBonds {
00482 protected:
00483 Fl_Counter *thickness;
00484 public:
00485 GraphicsFltkRepRibbons(Fl_Callback *cb, void *v)
00486 : GraphicsFltkRepBonds(cb, v) {
00487 radius->label("Radius");
00488 resolution->label("Resolution");
00489 Fl_Group::begin();
00490 thickness = new ResolutionCounter(x()+170,y()+60,"Width");
00491 thickness->callback(cb, v);
00492 Fl_Group::end();
00493 }
00494 protected:
00495 void do_reset() {
00496 GraphicsFltkRepBonds::do_reset();
00497 thickness->value(2);
00498 }
00499 public:
00500 const char *repcmd() {
00501 sprintf(cmdbuf, "Ribbons %f %f %f", radius->value(), resolution->value(),
00502 thickness->value());
00503 return cmdbuf;
00504 }
00505 void set_values(AtomRep *rep) {
00506 GraphicsFltkRepBonds::set_values(rep);
00507 thickness->value(rep->get_data(AtomRep::LINETHICKNESS));
00508 }
00509 };
00510
00511
00513 class GraphicsFltkRepNewRibbons : public GraphicsFltkRep {
00514 private:
00515 RepChoice *basis;
00516 IsoSlider *thickness, *ratio;
00517 ResolutionCounter *resolution;
00518 public:
00519 GraphicsFltkRepNewRibbons(Fl_Callback *cb, void *v) {
00520
00521 Fl_Group::begin();
00522 thickness = new IsoSlider(x()+80, y()+90, "Thickness");
00523 thickness->callback(cb, v);
00524 thickness->minimum(0.1);
00525 thickness->maximum(10.0);
00526
00527 resolution= new ResolutionCounter(x()+170,y()+120,"Resolution");
00528 resolution->callback(cb, v);
00529 resolution->maximum(50.0);
00530
00531 ratio= new IsoSlider(x()+80, y()+60, "Aspect Ratio");
00532 ratio->callback(cb, v);
00533 ratio->minimum(1.0);
00534 ratio->maximum(10.0);
00535
00536 basis = new RepChoice(x()+170,y()+30,"Spline Style");
00537 basis->add("Catmull-Rom");
00538 basis->add("B-Spline");
00539 basis->callback(cb, v);
00540 Fl_Group::end();
00541 }
00542 protected:
00543 void do_reset() {
00544 thickness->value(0.3);
00545 resolution->value(12);
00546 ratio->value(3);
00547 basis->value(0);
00548 }
00549 public:
00550 const char *repcmd() {
00551 sprintf(cmdbuf, "NewRibbons %f %f %f %d", thickness->value(),
00552 resolution->value(), ratio->value(), basis->value());
00553 return cmdbuf;
00554 }
00555 void set_values(AtomRep *rep) {
00556 ratio->value(rep->get_data(AtomRep::LINETHICKNESS));
00557 basis->value((int)rep->get_data(AtomRep::SPHERERAD));
00558 thickness->value(rep->get_data(AtomRep::BONDRAD));
00559 resolution->value(rep->get_data(AtomRep::BONDRES));
00560 }
00561 };
00562
00563
00565 class GraphicsFltkRepCartoon : public GraphicsFltkRepRibbons {
00566 public:
00567 GraphicsFltkRepCartoon(Fl_Callback *cb, void *v)
00568 : GraphicsFltkRepRibbons(cb, v) {
00569 radius->label("Helix/Coil Radius");
00570 resolution->label("Helix/Coil Resolution");
00571 thickness->label("Beta Sheet Thickness");
00572 }
00573 const char *repcmd() {
00574 sprintf(cmdbuf, "Cartoon %f %f %f", radius->value(), resolution->value(),
00575 thickness->value());
00576 return cmdbuf;
00577 }
00578 protected:
00579 void do_reset() {
00580 radius->value(2.1);
00581 resolution->value(24.0);
00582 thickness->value(5.0);
00583 }
00584 };
00585
00586
00588 class GraphicsFltkRepNewCartoon : public GraphicsFltkRep {
00589 private:
00590 RepChoice *basis;
00591 IsoSlider *thickness, *ratio;
00592 ResolutionCounter *resolution;
00593 public:
00594 GraphicsFltkRepNewCartoon(Fl_Callback *cb, void *v) {
00595
00596 Fl_Group::begin();
00597 thickness = new IsoSlider(x()+80, y()+90, "Thickness");
00598 thickness->callback(cb, v);
00599 thickness->minimum(0.1);
00600 thickness->maximum(10.0);
00601
00602 resolution= new ResolutionCounter(x()+170,y()+120,"Resolution");
00603 resolution->callback(cb, v);
00604 resolution->maximum(50.0);
00605
00606 ratio= new IsoSlider(x()+80, y()+60, "Aspect Ratio");
00607 ratio->callback(cb, v);
00608 ratio->minimum(1.0);
00609 ratio->maximum(10.0);
00610
00611 basis = new RepChoice(x()+170,y()+30,"Spline Style");
00612 basis->add("Catmull-Rom");
00613 basis->add("B-Spline");
00614 basis->callback(cb, v);
00615 Fl_Group::end();
00616 }
00617 protected:
00618 void do_reset() {
00619 thickness->value(0.3);
00620 resolution->value(10);
00621 ratio->value(4.1);
00622 basis->value(0);
00623 }
00624 public:
00625 const char *repcmd() {
00626 sprintf(cmdbuf, "NewCartoon %f %f %f %d", thickness->value(),
00627 resolution->value(), ratio->value(), basis->value());
00628 return cmdbuf;
00629 }
00630 void set_values(AtomRep *rep) {
00631 ratio->value(rep->get_data(AtomRep::LINETHICKNESS));
00632 basis->value((int)rep->get_data(AtomRep::SPHERERAD));
00633 thickness->value(rep->get_data(AtomRep::BONDRAD));
00634 resolution->value(rep->get_data(AtomRep::BONDRES));
00635 }
00636 };
00637
00638 #ifdef VMDWITHCARBS
00639
00641 class GraphicsFltkRepWithRingSize : public GraphicsFltkRep {
00642 protected:
00643 ResolutionCounter *max_ring_size;
00644 Fl_Callback *parentcb;
00645 void *parentdata;
00646
00647 static void sync_cb(Fl_Widget *, void *v) {
00648 GraphicsFltkRepWithRingSize *self = (GraphicsFltkRepWithRingSize *)v;
00649 GraphicsFltkMenu *menu = (GraphicsFltkMenu *) self->parentdata;
00650
00651 int max_ring_size = (int)self->max_ring_size->value();
00652
00653 Molecule *m = menu->app->moleculeList->molecule(menu->molindex);
00654
00655 for (int i=0; i<m->components(); i++) {
00656 DrawMolItem *d = m->component(i);
00657 AtomRep *ar = d->atomRep;
00658
00659 if (ar->method() == AtomRep::RINGS_PAPERCHAIN || ar->method() == AtomRep::RINGS_TWISTER) {
00660 GraphicsFltkRepWithRingSize *rep;
00661
00662 if (ar->method() == AtomRep::RINGS_PAPERCHAIN)
00663 rep = (GraphicsFltkRepWithRingSize *) menu->repcontrols.data("PaperChain");
00664 else
00665 rep = (GraphicsFltkRepWithRingSize *) menu->repcontrols.data("Twister");
00666
00667 rep->set_values(ar);
00668 rep->max_ring_size->value(max_ring_size);
00669 ar->change(rep->repcmd());
00670 d->force_recalc(d->MOL_REGEN);
00671 }
00672 }
00673
00674
00675
00676 }
00677 };
00678
00680 class GraphicsFltkRepPaperChain : public GraphicsFltkRepWithRingSize {
00681 private:
00682 ShortSlider *bipyramid_height;
00683 public:
00684 GraphicsFltkRepPaperChain(Fl_Callback *cb, void *v) {
00685 parentcb = cb;
00686 parentdata = v;
00687
00688 Fl_Group::begin();
00689
00690 bipyramid_height = new ShortSlider(x()+120, y()+30, "Bipyramid Height");
00691 bipyramid_height->callback(cb, v);
00692 bipyramid_height->minimum(0.1);
00693 bipyramid_height->maximum(10.0);
00694
00695 max_ring_size = new ResolutionCounter(x()+150, y()+60, "Max. Ring Size");
00696 max_ring_size->callback(sync_cb,this);
00697 max_ring_size->minimum(2);
00698 max_ring_size->maximum(500);
00699
00700 Fl_Group::end();
00701 }
00702 protected:
00703 void do_reset() {
00704 bipyramid_height->value(1.0);
00705 max_ring_size->value(10);
00706 }
00707 public:
00708 const char *repcmd() {
00709 sprintf(cmdbuf, "PaperChain %f %f", bipyramid_height->value(),
00710 max_ring_size->value());
00711 return cmdbuf;
00712 }
00713 void set_values(AtomRep *rep) {
00714 bipyramid_height->value(rep->get_data(AtomRep::LINETHICKNESS));
00715 max_ring_size->value((int)rep->get_data(AtomRep::ISOSTEPSIZE));
00716 }
00717 };
00718
00720 class GraphicsFltkRepTwister : public GraphicsFltkRepWithRingSize {
00721 private:
00722 RepChoice *start_end_centroid;
00723 RepChoice *hide_shared_links;
00724 ResolutionCounter *rib_steps;
00725 ShortSlider *rib_width;
00726 ShortSlider *rib_height;
00727 ResolutionCounter *max_path_length;
00728
00729 public:
00730 GraphicsFltkRepTwister(Fl_Callback *cb, void *v) {
00731 parentcb = cb;
00732 parentdata = v;
00733
00734 Fl_Group::begin();
00735
00736 start_end_centroid = new RepChoice(x()+150, y()+30, "Start Ribbons At");
00737 start_end_centroid->callback(cb,v);
00738 start_end_centroid->add("Ring Edge");
00739 start_end_centroid->add("Ring Centroid");
00740
00741 hide_shared_links = new RepChoice(x()+150, y()+60,"Hide Shared Links");
00742 hide_shared_links->callback(cb,v);
00743 hide_shared_links->add("No");
00744 hide_shared_links->add("Yes");
00745
00746 rib_steps = new ResolutionCounter(x()+150, y()+90, "Steps in Ribbon");
00747 rib_steps->callback(cb,v);
00748 rib_steps->minimum(5);
00749 rib_steps->maximum(500);
00750
00751 max_ring_size = new ResolutionCounter(x()+150, y()+120, "Max. Ring Size");
00752 max_ring_size->callback(sync_cb,this);
00753 max_ring_size->minimum(2);
00754 max_ring_size->maximum(500);
00755
00756 max_path_length = new ResolutionCounter(x()+150, y()+150, "Max. Linking Distance");
00757 max_path_length->callback(cb,v);
00758 max_path_length->minimum(1);
00759 max_path_length->maximum(500);
00760
00761 rib_width = new ShortSlider(x()+110, y()+180, "Ribbon Width");
00762 rib_width->callback(cb,v);
00763 rib_width->minimum(0.01);
00764 rib_width->maximum(10.0);
00765
00766 rib_height = new ShortSlider(x()+110, y()+210, "Ribbon Height");
00767 rib_height->callback(cb,v);
00768 rib_height->minimum(0.01);
00769 rib_height->maximum(10.0);
00770
00771 Fl_Group::end();
00772 }
00773 protected:
00774 void do_reset() {
00775 start_end_centroid->value(1);
00776 hide_shared_links->value(0);
00777 rib_steps->value(10);
00778 rib_width->value(0.3);
00779 rib_height->value(0.05);
00780 max_ring_size->value(10);
00781 max_path_length->value(5);
00782 }
00783 public:
00784 const char *repcmd() {
00785 sprintf(cmdbuf, "Twister %f %f %f %f %f %f %f", (float) start_end_centroid->value(),
00786 (float) hide_shared_links->value(),
00787 (float) rib_steps->value(),
00788 rib_width->value(), rib_height->value(),
00789 max_ring_size->value(), max_path_length->value());
00790 return cmdbuf;
00791 }
00792 void set_values(AtomRep *rep) {
00793 start_end_centroid->value((int)rep->get_data(AtomRep::LINETHICKNESS));
00794 hide_shared_links->value((int)rep->get_data(AtomRep::BONDRES));
00795 rib_steps->value((int)rep->get_data(AtomRep::SPHERERAD));
00796 rib_width->value(rep->get_data(AtomRep::BONDRAD));
00797 rib_height->value(rep->get_data(AtomRep::SPHERERES));
00798 max_ring_size->value((int)rep->get_data(AtomRep::ISOSTEPSIZE));
00799 max_path_length->value((int)rep->get_data(AtomRep::ISOLINETHICKNESS));
00800 }
00801 };
00802
00803 #endif
00804
00806 class GraphicsFltkRepSolvent : public GraphicsFltkRep {
00807 private:
00808 RepChoice *method;
00809 Fl_Counter *detail;
00810 Fl_Counter *probe;
00811 public:
00812 GraphicsFltkRepSolvent(Fl_Callback *cb, void *v) {
00813 method = new RepChoice(x()+170,y()+60,"Representation Method");
00814 method->add("Points");
00815 method->add("Crosses");
00816 method->add("Mesh");
00817 detail = new ResolutionCounter(x()+170,y()+90,"Detail Level");
00818 detail->maximum(13);
00819 probe = new RadiusCounter(x()+170,y()+120,"Probe Radius");
00820 method->callback(cb, v);
00821 detail->callback(cb, v);
00822 probe->callback(cb, v);
00823 Fl_Group::end();
00824 }
00825 protected:
00826 void do_reset() {
00827 method->value(0);
00828 detail->value(7.0);
00829 probe->value(0);
00830 }
00831 public:
00832 const char *repcmd() {
00833 sprintf(cmdbuf, "Solvent %f %f %f", probe->value(), detail->value(),
00834 (float)(method->value()+1));
00835 return cmdbuf;
00836 }
00837 void set_values(AtomRep *rep) {
00838 method->setvalue((int)rep->get_data(AtomRep::LINETHICKNESS)-1);
00839 detail->value(rep->get_data(AtomRep::SPHERERES));
00840 probe->value(rep->get_data(AtomRep::SPHERERAD));
00841 }
00842 };
00843
00844
00846 class GraphicsFltkRepMSMS : public GraphicsFltkRep {
00847 private:
00848 Fl_Counter *density;
00849 Fl_Counter *probe;
00850 RepChoice *method;
00851 RepChoice *whichatoms;
00852 public:
00853 GraphicsFltkRepMSMS(Fl_Callback *cb, void *v) {
00854 density = new RadiusCounter(x()+170,y()+90,"Sample Density");
00855 density->minimum(0.1);
00856 density->maximum(30.0);
00857 density->callback(cb, v);
00858 probe = new RadiusCounter(x()+170,y()+120, "Probe Radius");
00859 probe->minimum(0.1);
00860 probe->maximum(8.0);
00861 probe->callback(cb, v);
00862 method = new RepChoice(x()+170,y()+60,"Representation Method");
00863 method->add("Solid Surface");
00864 method->add("Wireframe");
00865 method->callback(cb, v);
00866 whichatoms = new RepChoice(x()+170,y()+30, "Which Atoms");
00867 whichatoms->add("Selected");
00868 whichatoms->add("All");
00869 whichatoms->callback(cb, v);
00870 Fl_Group::end();
00871 }
00872 protected:
00873 void do_reset() {
00874 density->value(1.5);
00875 probe->value(1.5);
00876 method->value(0);
00877 whichatoms->value(0);
00878 }
00879 public:
00880 const char *repcmd() {
00881 sprintf(cmdbuf, "MSMS %f %f %f %f", probe->value(), density->value(),
00882 (float)whichatoms->value(), (float)method->value());
00883 return cmdbuf;
00884 }
00885 void set_values(AtomRep *rep) {
00886 density->value(rep->get_data(AtomRep::SPHERERES));
00887 probe->value(rep->get_data(AtomRep::SPHERERAD));
00888 method->setvalue((int)rep->get_data(AtomRep::BONDRES));
00889 whichatoms->setvalue((int)rep->get_data(AtomRep::LINETHICKNESS));
00890 }
00891 };
00892
00893
00895 class GraphicsFltkRepHBonds : public GraphicsFltkRep {
00896 private:
00897 Fl_Counter *distance;
00898 Fl_Counter *angle;
00899 Fl_Counter *thickness;
00900 public:
00901 GraphicsFltkRepHBonds(Fl_Callback *cb, void *v) {
00902 distance = new RadiusCounter(x()+170,y()+60,"Distance Cutoff");
00903 distance->callback(cb, v);
00904 angle = new RadiusCounter(x()+170,y()+90,"Angle Cutoff");
00905 angle->precision(0);
00906 angle->step(1);
00907 angle->lstep(10);
00908 angle->callback(cb, v);
00909 thickness = new ResolutionCounter(x()+170,y()+120, "Line Thickness");
00910 thickness->callback(cb, v);
00911 Fl_Group::end();
00912 }
00913 protected:
00914 void do_reset() {
00915 distance->value(3.0);
00916 angle->value(20.0);
00917 thickness->value(1.0);
00918 }
00919 public:
00920 const char *repcmd() {
00921 sprintf(cmdbuf, "HBonds %f %f %f", distance->value(), angle->value(),
00922 thickness->value());
00923 return cmdbuf;
00924 }
00925 void set_values(AtomRep *rep) {
00926 distance->value(rep->get_data(AtomRep::BONDRAD));
00927 angle->value(rep->get_data(AtomRep::SPHERERAD));
00928 thickness->value(rep->get_data(AtomRep::LINETHICKNESS));
00929 }
00930 };
00931
00932
00933
00934
00935 class GraphicsFltkRepQuickSurf;
00936
00937 class quicksurf_cbdata {
00938 public:
00939 GraphicsFltkMenu *self;
00940 GraphicsFltkRepQuickSurf *qsurfrep;
00941 };
00942
00944 class GraphicsFltkRepQuickSurf : public GraphicsFltkRep {
00945 private:
00946 Fl_Value_Slider *resolution;
00947 RepChoice *quality;
00948 Fl_Counter *radscale;
00949 Fl_Counter *gridspacing;
00950 Fl_Counter *isovalue;
00951 float gridspacingmult;
00952
00953 public:
00954 GraphicsFltkRepQuickSurf(Fl_Callback *cb, void *v) {
00955 gridspacingmult = 1.0f;
00956 resolution = new IsoSlider(x()+80, y()+60, "Resolution");
00957 resolution->minimum(0.5);
00958 resolution->maximum(8);
00959 resolution->callback(cb, v);
00960 resolution->when(FL_WHEN_CHANGED | FL_WHEN_RELEASE_ALWAYS);
00961 radscale = new RadiusCounter(x()+170,y()+90,"Radius Scale");
00962 radscale->minimum(0.1);
00963 radscale->callback(cb, v);
00964 isovalue = new RadiusCounter(x()+170,y()+120,"Density Isovalue");
00965 isovalue->minimum(0.1);
00966 isovalue->maximum(20);
00967 isovalue->callback(cb, v);
00968 gridspacing = new RadiusCounter(x()+170,y()+150,"Grid Spacing");
00969 gridspacing->minimum(0.5);
00970 gridspacing->callback(cb, v);
00971 quality = new RepChoice(x()+170,y()+180, "Surface Quality");
00972 quality->add("Low");
00973 quality->add("Medium");
00974 quality->add("High");
00975 quality->add("Max");
00976 quality->callback(cb, v);
00977 Fl_Group::end();
00978 }
00979
00980 void set_gridspacing_multiplier(float mult) {
00981 gridspacingmult = mult;
00982 }
00983
00984 void resolution_changed() {
00985 float val = (float) resolution->value();
00986 float res = val;
00987
00988 int qual = quality->value();
00989 switch (qual) {
00990 case 0: res *= 2.0f; break;
00991
00992 case 1: res *= 1.0f; break;
00993
00994 case 2:
00995 case 3:
00996 default: res /= 2.0f; break;
00997 }
00998
00999 float density = 0.5f;
01000 if (val > 3.0f) {
01001 density = 30.0f*(val-3.0f)+6.0f*powf((val-3.0f),2.0f)+10.0f*powf(val-3.0f,0.5f)+23.0f;
01002 } else if (val > 1) {
01003 density = 254.83f * expf(-1.018f * val) -
01004 5071.0f * powf(val, -0.0189f) + 4980.0f;
01005 } else {
01006 density = val;
01007 }
01008
01009 radscale->value(val);
01010 isovalue->value(density);
01011 gridspacing->value(res * gridspacingmult);
01012 }
01013
01014 protected:
01015 void do_reset() {
01016 resolution->value(1.0);
01017 radscale->value(1.0);
01018 gridspacing->value(1.0);
01019 isovalue->value(0.5);
01020 quality->value(1);
01021 }
01022 public:
01023 const char *repcmd() {
01024 sprintf(cmdbuf, "QuickSurf %f %f %f %f",
01025 radscale->value(), isovalue->value(), gridspacing->value(),
01026 (float)quality->value());
01027 return cmdbuf;
01028 }
01029 void set_values(AtomRep *rep) {
01030 radscale->value(rep->get_data(AtomRep::SPHERERAD));
01031 isovalue->value(rep->get_data(AtomRep::BONDRAD));
01032 gridspacing->value(rep->get_data(AtomRep::GRIDSPACING));
01033 quality->setvalue((int)rep->get_data(AtomRep::BONDRES));
01034 }
01035 };
01036
01037
01039 class GraphicsFltkRepSurf : public GraphicsFltkRep {
01040 private:
01041 Fl_Counter *probe;
01042 RepChoice *method;
01043 public:
01044 GraphicsFltkRepSurf(Fl_Callback *cb, void *v) {
01045 probe = new RadiusCounter(x()+170,y()+120,"Probe Radius");
01046 probe->minimum(0.1);
01047 probe->callback(cb, v);
01048 method = new RepChoice(x()+170,y()+90, "Representation Method");
01049 method->add("Solid Surface");
01050 method->add("Wireframe");
01051 method->callback(cb, v);
01052 Fl_Group::end();
01053 }
01054 protected:
01055 void do_reset() {
01056 probe->value(1.4);
01057 method->value(0);
01058 }
01059 public:
01060 const char *repcmd() {
01061 sprintf(cmdbuf, "Surf %f %f", probe->value(), (float)method->value());
01062 return cmdbuf;
01063 }
01064 void set_values(AtomRep *rep) {
01065 probe->value(rep->get_data(AtomRep::SPHERERAD));
01066 method->setvalue((int)rep->get_data(AtomRep::BONDRES));
01067 }
01068 };
01069
01070
01075 class GraphicsFltkRepVolumetric: public GraphicsFltkRep {
01076 protected:
01077 RepChoice *dataset;
01078
01080 struct minmax {
01081 double minval, maxval;
01082 minmax(double themin=0, double themax=0) : minval(themin), maxval(themax) {}
01083 int operator==(const minmax &v) {
01084 return (minval == v.minval && maxval == v.maxval);
01085 }
01086 };
01087 ResizeArray<minmax> minmaxlist;
01088
01089 GraphicsFltkRepVolumetric(Fl_Callback *cb, void *v) {
01090 dataset = new RepChoice(x()+170, y()+30, "Vol");
01091 dataset->callback(cb, v);
01092 }
01093 virtual void do_dataset_clear() {}
01094 virtual void do_dataset_append(const char *, double, double) {}
01095
01096 public:
01097 int is_volumetric() { return 1; }
01098 void dataset_clear() {
01099 dataset->clear();
01100 dataset->deactivate();
01101 minmaxlist.clear();
01102 do_dataset_clear();
01103 }
01104 void dataset_append(const char *nm, double newmin, double newmax) {
01105
01106
01107
01108 int ind = dataset->add("foobar");
01109 char *datalabel = new char[strlen(nm)+32];
01110 sprintf(datalabel, "vol%d: %s", ind, nm);
01111 dataset->replace(ind, datalabel);
01112 delete[] datalabel;
01113
01114 minmaxlist.append(minmax(newmin, newmax));
01115 dataset->value(minmaxlist.num()-1);
01116 do_dataset_append(nm, newmin, newmax);
01117 dataset->activate();
01118 }
01119 };
01120
01121
01122
01123
01124 class GraphicsFltkRepIsosurface;
01125
01126 class isosurface_cbdata {
01127 public:
01128 GraphicsFltkMenu *self;
01129 GraphicsFltkRepIsosurface *isorep;
01130 };
01131
01133 class GraphicsFltkRepIsosurface : public GraphicsFltkRepVolumetric {
01134 private:
01135 Fl_Slider *isovalue;
01136 Fl_Float_Input *isoinput;
01137 Fl_Float_Input *isomininput, *isomaxinput;
01138 Fl_Counter *resolution;
01139 Fl_Counter *thickness;
01140 RepChoice *method;
01141 RepChoice *boundary;
01142 Fl_Callback *parentcb;
01143 void *parentdata;
01144 int gridstepsize;
01145
01146 static void datasetchanged_cb(Fl_Widget *w, void *v) {
01147 GraphicsFltkRepIsosurface *self = (GraphicsFltkRepIsosurface *)v;
01148 if (self->minmaxlist.num() > 0) {
01149 minmax &m = self->minmaxlist[self->dataset->value()];
01150 self->isovalue->range(m.minval, m.maxval);
01151 } else {
01152 self->isovalue->range(0, 1);
01153 }
01154 (self->parentcb)(w, self->parentdata);
01155 }
01156
01157 static void inputcb(Fl_Widget *, void *v) {
01158 GraphicsFltkRepIsosurface *self = (GraphicsFltkRepIsosurface *)v;
01159 char *endptr = NULL;
01160 const char *strval = self->isoinput->value();
01161 double val = strtod(strval, &endptr);
01162 if (endptr != strval) {
01163
01164 self->isovalue->value(val);
01165 (self->parentcb)(self->isovalue, self->parentdata);
01166 }
01167 }
01168
01169 static void minmaxinputcb(Fl_Widget *, void *v) {
01170 GraphicsFltkRepIsosurface *self = (GraphicsFltkRepIsosurface *)v;
01171
01172 char *endptr = NULL;
01173 const char *minstrval = self->isomininput->value();
01174 double minval = strtod(minstrval, &endptr);
01175 if (endptr == minstrval) return;
01176 const char *maxstrval = self->isomaxinput->value();
01177 double maxval = strtod(maxstrval, &endptr);
01178 if (endptr == maxstrval) return;
01179
01180
01181 if (self->minmaxlist.num() > 0) {
01182 minmax &m = self->minmaxlist[self->dataset->value()];
01183 m.minval = minval;
01184 m.maxval = maxval;
01185 }
01186
01187
01188
01189 self->isovalue->range(minval, maxval);
01190 if (self->isovalue->value() < minval) {
01191 self->isovalue->value(minval);
01192 slidercb(NULL, v);
01193 } else if (self->isovalue->value() > maxval) {
01194 self->isovalue->value(maxval);
01195 slidercb(NULL, v);
01196 } else {
01197 self->setInputFromSlider();
01198 }
01199 }
01200
01201 void setInputFromSlider() {
01202 char buf[128];
01203 sprintf(buf, "%8g", (float)isovalue->value());
01204 isoinput->value(buf);
01205 sprintf(buf, "%8g", (float)isovalue->minimum());
01206 isomininput->value(buf);
01207 sprintf(buf, "%8g", (float)isovalue->maximum());
01208 isomaxinput->value(buf);
01209 }
01210
01211 static void slidercb(Fl_Widget *, void *v) {
01212 GraphicsFltkRepIsosurface *self = (GraphicsFltkRepIsosurface *)v;
01213 self->setInputFromSlider();
01214 (self->parentcb)(self->isovalue, self->parentdata);
01215 }
01216
01217 protected:
01218 void do_dataset_clear() {
01219 isovalue->deactivate();
01220 isoinput->deactivate();
01221 boundary->deactivate();
01222 method->deactivate();
01223 resolution->deactivate();
01224 thickness->deactivate();
01225 }
01226 void do_dataset_append(const char *, double min, double max) {
01227 isovalue->activate();
01228 isoinput->activate();
01229 boundary->activate();
01230 method->activate();
01231 resolution->activate();
01232 thickness->activate();
01233 isovalue->range(min,max);
01234 setInputFromSlider();
01235 }
01236 void do_reset() {
01237 set_grid_stepsize(1);
01238 resolution->value(1);
01239 thickness->value(1);
01240 method->value(2);
01241 boundary->value(2);
01242 dataset->value(0);
01243 }
01244
01245 public:
01246 GraphicsFltkRepIsosurface(Fl_Callback *cb, void *v)
01247 : GraphicsFltkRepVolumetric(datasetchanged_cb, this) {
01248 parentcb = cb;
01249 parentdata = v;
01250
01251 resolution= new StepCounter(x()+35,y()+90, "Step");
01252 resolution->callback(cb, v);
01253 thickness= new StepCounter(x()+35,y()+120, "Size");
01254 thickness->callback(cb, v);
01255 method = new RepChoice(x()+170,y()+90,"Draw");
01256 method->add("Solid Surface");
01257 method->add("Wireframe");
01258 method->add("Points");
01259 method->add("Shaded Points");
01260 method->callback(cb, v);
01261 boundary = new RepChoice(x()+170, y()+120, "Show");
01262 boundary->add("Isosurface");
01263 boundary->add("Box");
01264 boundary->add("Box+Isosurface");
01265 boundary->callback(cb, v);
01266 isovalue = new Fl_Slider(x()+135,y()+60, 155, CTRHEIGHT, "");
01267 isovalue->type(FL_HOR_SLIDER);
01268 isovalue->color(VMDMENU_SLIDER_BG);
01269 isovalue->when(FL_WHEN_CHANGED);
01270 isovalue->callback(slidercb, this);
01271 isoinput = new Fl_Float_Input(x()+60, y()+60, 70, CTRHEIGHT, "Isovalue");
01272 isoinput->when(FL_WHEN_ENTER_KEY);
01273 isoinput->selection_color(VMDMENU_VALUE_SEL);
01274 isoinput->callback(inputcb, this);
01275 isovalue->when(FL_WHEN_CHANGED | FL_WHEN_RELEASE_ALWAYS);
01276
01277 isomininput = new Fl_Float_Input(x()+45, y()+30, 45, CTRHEIGHT, "Range");
01278 isomininput->when(FL_WHEN_ENTER_KEY);
01279 isomininput->selection_color(VMDMENU_VALUE_SEL);
01280 isomininput->callback(minmaxinputcb, this);
01281 isomaxinput = new Fl_Float_Input(x()+90, y()+30, 45, CTRHEIGHT);
01282 isomaxinput->when(FL_WHEN_ENTER_KEY);
01283 isomaxinput->selection_color(VMDMENU_VALUE_SEL);
01284 isomaxinput->callback(minmaxinputcb, this);
01285
01286 Fl_Group::end();
01287 }
01288 const char *repcmd() {
01289 if (dataset->size() > 0) {
01290 sprintf(cmdbuf, "Isosurface %f %d %d %d %d %d",
01291 (float) isovalue->value(),
01292 (int) dataset->value(),
01293 (int) boundary->value(),
01294 (int) method->value(),
01295 gridstepsize + (int) resolution->value() - 1,
01296 (int) thickness->value());
01297 } else {
01298 sprintf(cmdbuf, "Isosurface");
01299 }
01300 return cmdbuf;
01301 }
01302 void set_values(AtomRep *rep) {
01303 dataset->setvalue((int)rep->get_data(AtomRep::SPHERERES));
01304
01305
01306 if (minmaxlist.num() > 0) {
01307 minmax &m = minmaxlist[dataset->value()];
01308 isovalue->range(m.minval, m.maxval);
01309 } else {
01310 isovalue->range(0, 1);
01311 }
01312 isovalue->value(rep->get_data(AtomRep::SPHERERAD));
01313 method->setvalue((int)rep->get_data(AtomRep::BONDRES));
01314 boundary->setvalue((int)rep->get_data(AtomRep::LINETHICKNESS));
01315 resolution->value(rep->get_data(AtomRep::ISOSTEPSIZE) - gridstepsize + 1);
01316 thickness->value(rep->get_data(AtomRep::ISOLINETHICKNESS));
01317 setInputFromSlider();
01318 }
01319 void set_grid_stepsize(int step) {
01320 gridstepsize = step;
01321 }
01322 };
01323
01324
01326 class GraphicsFltkRepVolumeSlice : public GraphicsFltkRepVolumetric {
01327 private:
01328 Fl_Value_Slider *slice;
01329 RepChoice *axis;
01330 RepChoice *quality;
01331
01332 protected:
01333 void do_dataset_clear() {
01334 slice->deactivate();
01335 axis->deactivate();
01336 quality->deactivate();
01337 }
01338 void do_dataset_append(const char *, double, double) {
01339 slice->activate();
01340 axis->activate();
01341 quality->activate();
01342 }
01343 void do_reset() {
01344 slice->value(0.5);
01345 axis->value(0);
01346 quality->value(2);
01347 }
01348 public:
01349 GraphicsFltkRepVolumeSlice(Fl_Callback *cb, void *v)
01350 : GraphicsFltkRepVolumetric(cb, v) {
01351 slice = new IsoSlider(x()+80, y()+60, "Slice Offset");
01352 slice->callback(cb, v);
01353 axis = new RepChoice(x()+170, y()+90, "Slice Axis");
01354 axis->add("X");
01355 axis->add("Y");
01356 axis->add("Z");
01357 axis->callback(cb, v);
01358 quality = new RepChoice(x()+170,y()+120, "Render Quality");
01359 quality->add("Low");
01360 quality->add("Medium");
01361 quality->add("High");
01362 quality->callback(cb, v);
01363 Fl_Group::end();
01364 }
01365 const char *repcmd() {
01366 if (dataset->size() > 0) {
01367 sprintf(cmdbuf, "VolumeSlice %f %f %f %f", slice->value(),
01368 (float)dataset->value(), (float)axis->value(),
01369 (float)quality->value());
01370 } else {
01371 sprintf(cmdbuf, "VolumeSlice");
01372 }
01373 return cmdbuf;
01374 }
01375 void set_values(AtomRep *rep) {
01376 dataset->setvalue((int)rep->get_data(AtomRep::SPHERERES));
01377 slice->value(rep->get_data(AtomRep::SPHERERAD));
01378 axis->setvalue((int)rep->get_data(AtomRep::LINETHICKNESS));
01379 quality->setvalue((int)rep->get_data(AtomRep::BONDRES));
01380 }
01381 };
01382
01383
01384
01385
01386 class GraphicsFltkRepOrbital;
01387
01388 class orbital_cbdata {
01389 public:
01390 GraphicsFltkMenu *self;
01391 GraphicsFltkRepOrbital *orbrep;
01392 };
01393
01394
01396 class GraphicsFltkRepOrbital : public GraphicsFltkRep {
01397 protected:
01398 RepChoice *wavefnctype;
01399 RepChoiceSmall *wavefncspin;
01400 RepChoiceSmall *wavefncexcitation;
01401 RepChoiceSmall *orbitalindex;
01402
01404 struct minmax {
01405 double minval, maxval;
01406 minmax(double themin=0, double themax=0) : minval(themin), maxval(themax) {}
01407 int operator==(const minmax &v) {
01408 return (minval == v.minval && maxval == v.maxval);
01409 }
01410 };
01411 ResizeArray<minmax> minmaxlist;
01412
01413
01414 public:
01415 int is_orbital() { return 1; }
01416 void dataset_clear() {
01417 orbitalindex->clear();
01418 orbitalindex->deactivate();
01419 minmaxlist.clear();
01420 do_dataset_clear();
01421 }
01422 void dataset_append(const char *nm, double newmin, double newmax) {
01423
01424
01425
01426 int ind = orbitalindex->add("foobar");
01427 char *datalabel = new char[strlen(nm)+32];
01428 sprintf(datalabel, "%s", nm);
01429 orbitalindex->replace(ind, datalabel);
01430 delete[] datalabel;
01431
01432 minmaxlist.append(minmax(newmin, newmax));
01433 orbitalindex->value(minmaxlist.num()-1);
01434 do_dataset_append(nm, newmin, newmax);
01435 orbitalindex->activate();
01436 }
01437
01438 void regen_wavefunctypes() {
01439 int i;
01440 orbital_cbdata *cbdata = (orbital_cbdata *) parentdata;
01441 GraphicsFltkMenu *menu = (GraphicsFltkMenu *) cbdata->self;
01442 Molecule *m = menu->app->moleculeList->molecule(menu->molindex);
01443 int firstvalidwaveftype=-1;
01444 int firstvalidwavefspin=-1;
01445
01446 if (m != NULL && m->qm_data != NULL) {
01447
01448
01449 for (i=0; i<7; i++) {
01450 if (m->qm_data->has_wavef_guitype(i)) {
01451 wavefnctype->mode(i, 0);
01452 if (firstvalidwaveftype < 0)
01453 firstvalidwaveftype=i;
01454 } else {
01455 wavefnctype->mode(i, FL_MENU_INACTIVE);
01456 }
01457 }
01458
01459
01460
01461 for (i=0; i<2; i++) {
01462 if (m->qm_data->has_wavef_spin(i)) {
01463 wavefncspin->mode(i, 0);
01464 if (firstvalidwavefspin < 0)
01465 firstvalidwavefspin=i;
01466 } else {
01467 wavefncspin->mode(i, FL_MENU_INACTIVE);
01468 }
01469 }
01470 } else {
01471
01472 for (i=0; i<7; i++)
01473 wavefnctype->mode(i, FL_MENU_INACTIVE);
01474 for (i=0; i<2; i++)
01475 wavefncspin->mode(i, FL_MENU_INACTIVE);
01476 }
01477
01478
01479 if (firstvalidwaveftype >= 0)
01480 wavefnctype->value(firstvalidwaveftype);
01481
01482
01483 if (firstvalidwavefspin >= 0)
01484 wavefncspin->value(firstvalidwavefspin);
01485
01486
01487 regen_excitationlist();
01488 }
01489
01490 void regen_excitationlist() {
01491 orbital_cbdata *cbdata = (orbital_cbdata *) parentdata;
01492 GraphicsFltkMenu *menu = (GraphicsFltkMenu *) cbdata->self;
01493 Molecule *m = menu->app->moleculeList->molecule(menu->molindex);
01494
01495 int wftype = (int) wavefnctype->value();
01496 if (m != NULL && m->qm_data != NULL &&
01497 m->qm_data->has_wavef_guitype(wftype)) {
01498 int maxexcitations = m->qm_data->get_highest_excitation(wftype);
01499 wavefncexcitation->clear();
01500 wavefncexcitation->deactivate();
01501
01502
01503
01504 int i;
01505 for (i=0; i<=maxexcitations; i++) {
01506 char excitationstr[64];
01507 sprintf(excitationstr, "%d", i);
01508 wavefncexcitation->add(excitationstr);
01509 }
01510
01511
01512 int firstvalidexcitation=-1;
01513 for (i=0; i<=maxexcitations; i++) {
01514 if (m->qm_data->find_wavef_id_from_gui_specs(wftype, GUI_WAVEF_SPIN_ALPHA, i)>=0 ||
01515 m->qm_data->find_wavef_id_from_gui_specs(wftype, GUI_WAVEF_SPIN_BETA, i)>=0) {
01516
01517 if (firstvalidexcitation < 0)
01518 firstvalidexcitation=i;
01519 wavefncexcitation->mode(i, 0);
01520 } else {
01521 wavefncexcitation->mode(i, FL_MENU_INACTIVE);
01522 }
01523 }
01524
01525
01526
01527 if (firstvalidexcitation >= 0)
01528 wavefncexcitation->value(firstvalidexcitation);
01529 wavefncexcitation->activate();
01530 }
01531 }
01532
01533 void regen_orbitallist(int orblistcenter=10) {
01534 dataset_clear();
01535 orbital_cbdata *cbdata = (orbital_cbdata *) parentdata;
01536 GraphicsFltkMenu *menu = (GraphicsFltkMenu *) cbdata->self;
01537 Molecule *m = menu->app->moleculeList->molecule(menu->molindex);
01538 if (m != NULL && m->qm_data != NULL) {
01539 char namestr[80];
01540
01541 int waveid = 0;
01542 int wftype = (int) wavefnctype->value();
01543 int wfspin = (int) wavefncspin->value();
01544 int wfexcitation = (int) wavefncexcitation->value();
01545
01546
01547
01548 waveid = m->qm_data->find_wavef_id_from_gui_specs(wftype, wfspin, wfexcitation);
01549
01550 if (waveid < 0) {
01551 orbitalindex->activate();
01552 return;
01553 }
01554
01555
01556 int molmaxorb = m->qm_data->get_max_avail_orbitals(waveid);
01557
01558
01559
01560 orbitallistcounter->maximum(molmaxorb);
01561
01562
01563 if (orblistcenter == -1)
01564 orblistcenter = (int) orbitallistcounter->value();
01565 else
01566 orbitallistcounter->value(orblistcenter);
01567
01568
01569 if (orblistcenter > (molmaxorb-10))
01570 orblistcenter = molmaxorb-10;
01571 if (orblistcenter < 10)
01572 orblistcenter = 10;
01573
01574 int maxorb = orblistcenter+10;
01575 int minorb = orblistcenter-10;
01576
01577
01578 if (minorb < 1)
01579 minorb=1;
01580 if (maxorb > molmaxorb)
01581 maxorb=molmaxorb;
01582
01583
01584 orbitalminindex = minorb - 1;
01585
01586 #if 0
01587
01588
01589
01590
01591
01592 int HOMO = -1;
01593 Timestep *ts = m->get_frame(0);
01594 if (ts != NULL && ts->qm_timestep != NULL &&
01595 ts->qm_timestep->get_num_wavef()) {
01596 int tmp = ts->qm_timestep->get_homo(waveid);
01597 HOMO = ts->qm_timestep->get_orbital_id_from_index(waveid, tmp);
01598 printf("HOMO: %d\n", HOMO);
01599 } else {
01600 printf("HOMO not set: %d\n", HOMO);
01601 }
01602 #endif
01603
01604
01605
01606 int j;
01607 for (j=minorb; j<=maxorb; j++) {
01608 #if 1
01609 sprintf(namestr, "%3d", j);
01610 #else
01611 if (HOMO == j)
01612 sprintf(namestr, "%3d (HOMO)", j);
01613 else
01614 sprintf(namestr, "%3d", j);
01615 #endif
01616
01617 dataset_append(namestr, -0.1, 0.1);
01618 }
01619 for (j=minorb; j<=maxorb; j++) {
01620
01621
01622 if (m->qm_data->has_orbital(waveid, j))
01623 orbitalindex->mode(j-1, 0);
01624 else
01625 orbitalindex->mode(j-1, FL_MENU_INACTIVE);
01626 }
01627
01628 orbitalindex->value(0);
01629 orbitalindex->activate();
01630 } else {
01631 orbitalindex->value(0);
01632 orbitalindex->activate();
01633 }
01634 }
01635
01636
01637 private:
01638 Fl_Slider *isovalue;
01639 Fl_Float_Input *isoinput;
01640 Fl_Float_Input *isomininput, *isomaxinput;
01641 Fl_Counter *resolution;
01642 Fl_Counter *thickness;
01643 RepChoice *method;
01644 Fl_Callback *parentcb;
01645 void *parentdata;
01646 RepChoice *boundary;
01647 int gridstepsize;
01648 Fl_Counter *orbitallistcounter;
01649 int orbitalminindex;
01650
01651 static void datasetchanged_cb(Fl_Widget *w, void *v) {
01652 GraphicsFltkRepOrbital *self = (GraphicsFltkRepOrbital *)v;
01653 if (self->minmaxlist.num() > 0) {
01654 minmax &m = self->minmaxlist[self->orbitalindex->value()];
01655 self->isovalue->range(m.minval, m.maxval);
01656 } else {
01657 self->isovalue->range(0, 1);
01658 }
01659 (self->parentcb)(w, self->parentdata);
01660 }
01661
01662 static void inputcb(Fl_Widget *, void *v) {
01663 GraphicsFltkRepOrbital *self = (GraphicsFltkRepOrbital *)v;
01664 char *endptr = NULL;
01665 const char *strval = self->isoinput->value();
01666 double val = strtod(strval, &endptr);
01667 if (endptr != strval) {
01668
01669 self->isovalue->value(val);
01670 (self->parentcb)(self->isovalue, self->parentdata);
01671 }
01672 }
01673
01674 static void minmaxinputcb(Fl_Widget *, void *v) {
01675 GraphicsFltkRepOrbital *self = (GraphicsFltkRepOrbital *)v;
01676
01677 char *endptr = NULL;
01678 const char *minstrval = self->isomininput->value();
01679 double minval = strtod(minstrval, &endptr);
01680 if (endptr == minstrval) return;
01681 const char *maxstrval = self->isomaxinput->value();
01682 double maxval = strtod(maxstrval, &endptr);
01683 if (endptr == maxstrval) return;
01684
01685
01686 if (self->minmaxlist.num() > 0) {
01687 minmax &m = self->minmaxlist[self->orbitalindex->value()];
01688 m.minval = minval;
01689 m.maxval = maxval;
01690 }
01691
01692
01693
01694 self->isovalue->range(minval, maxval);
01695 if (self->isovalue->value() < minval) {
01696 self->isovalue->value(minval);
01697 slidercb(NULL, v);
01698 } else if (self->isovalue->value() > maxval) {
01699 self->isovalue->value(maxval);
01700 slidercb(NULL, v);
01701 } else {
01702 self->setInputFromSlider();
01703 }
01704 }
01705
01706 void setInputFromSlider() {
01707 char buf[128];
01708 sprintf(buf, "%8g", (float)isovalue->value());
01709 isoinput->value(buf);
01710 sprintf(buf, "%8g", (float)isovalue->minimum());
01711 isomininput->value(buf);
01712 sprintf(buf, "%8g", (float)isovalue->maximum());
01713 isomaxinput->value(buf);
01714 }
01715
01716 static void slidercb(Fl_Widget *, void *v) {
01717 GraphicsFltkRepOrbital *self = (GraphicsFltkRepOrbital *)v;
01718 self->setInputFromSlider();
01719 (self->parentcb)(self->isovalue, self->parentdata);
01720 }
01721
01722 protected:
01723 void do_dataset_clear() {
01724 isovalue->deactivate();
01725 isoinput->deactivate();
01726 boundary->deactivate();
01727 method->deactivate();
01728 resolution->deactivate();
01729 thickness->deactivate();
01730 orbitallistcounter->deactivate();
01731 }
01732 void do_dataset_append(const char *, double min, double max) {
01733 isovalue->activate();
01734 isoinput->activate();
01735 boundary->activate();
01736 method->activate();
01737 resolution->activate();
01738 thickness->activate();
01739 orbitallistcounter->activate();
01740 isovalue->range(min,max);
01741 setInputFromSlider();
01742 }
01743 void do_reset() {
01744 set_grid_stepsize(1);
01745 resolution->value(0.075);
01746 thickness->value(1);
01747 orbitallistcounter->minimum(1);
01748 orbitallistcounter->value(10);
01749 orbitallistcounter->step(10);
01750 orbitallistcounter->lstep(50);
01751 method->value(0);
01752 boundary->value(0);
01753 wavefnctype->value(0);
01754 wavefncspin->value(0);
01755 wavefncexcitation->value(0);
01756 orbitalindex->value(0);
01757 isovalue->value(0.05);
01758
01759
01760 regen_wavefunctypes();
01761 regen_orbitallist();
01762 }
01763
01764 public:
01765 GraphicsFltkRepOrbital(Fl_Callback *cb, void *v) {
01766 parentcb = cb;
01767 parentdata = v;
01768 gridstepsize = 1;
01769 orbitalminindex = 0;
01770
01771 int gx = x();
01772 int gy = y();
01773
01774
01775
01776 wavefnctype = new RepChoice(gx+170, gy+30, "Wavefunction Type");
01777 wavefnctype->add("Canonical");
01778 wavefnctype->add("GVB geminal pairs");
01779 wavefnctype->add("MCSCF natural");
01780 wavefnctype->add("MCSCF optimized");
01781 wavefnctype->add("CI natural");
01782 wavefnctype->add("Localized");
01783 wavefnctype->add("Other");
01784 wavefnctype->callback(cb, v);
01785
01786 wavefncspin = new RepChoiceSmall(gx+65, gy+60, "Spin");
01787 wavefncspin->add("Alpha");
01788 wavefncspin->add("Beta");
01789 wavefncspin->callback(cb, v);
01790
01791 wavefncexcitation = new RepChoiceSmall(gx+65, gy+90, "Excitation");
01792 int i;
01793 for (i=0; i<11; i++) {
01794 char excitationstr[64];
01795 sprintf(excitationstr, "%d", i);
01796 wavefncexcitation->add(excitationstr);
01797 }
01798 wavefncexcitation->callback(cb, v);
01799
01800 gy+=60;
01801
01802 orbitallistcounter= new StepCounter(gx+200,gy, "OrbList");
01803 orbitallistcounter->callback(cb, v);
01804 orbitalindex = new RepChoiceSmall(gx+210, gy+30, "Orbital");
01805 orbitalindex->callback(cb, v);
01806
01807 resolution= new GridResCounter(gx+170,gy+150, "Grid Spacing");
01808 resolution->callback(cb, v);
01809 thickness= new StepCounter(gx+40,gy+120, "Size");
01810 thickness->callback(cb, v);
01811 method = new RepChoice(gx+170,gy+90,"Draw");
01812 method->add("Solid Surface");
01813 method->add("Wireframe");
01814 method->add("Points");
01815 method->add("Shaded Points");
01816 method->callback(cb, v);
01817 boundary = new RepChoice(gx+170, gy+120, "Show");
01818 boundary->add("Isosurface");
01819 boundary->add("Box");
01820 boundary->add("Box+Isosurface");
01821 boundary->callback(cb, v);
01822 isovalue = new Fl_Slider(gx+150,gy+60, 140, CTRHEIGHT, "");
01823 isovalue->type(FL_HOR_SLIDER);
01824 isovalue->color(VMDMENU_SLIDER_BG);
01825 isovalue->when(FL_WHEN_CHANGED);
01826 isovalue->callback(slidercb, this);
01827 isoinput = new Fl_Float_Input(gx+80, gy+60, 70, CTRHEIGHT, "Isovalue");
01828 isoinput->when(FL_WHEN_ENTER_KEY);
01829 isoinput->selection_color(VMDMENU_SLIDER_SEL);
01830 isoinput->callback(inputcb, this);
01831 isovalue->when(FL_WHEN_CHANGED | FL_WHEN_RELEASE_ALWAYS);
01832
01833 isomininput = new Fl_Float_Input(gx+40, gy+90, 45, CTRHEIGHT, "Range");
01834 isomininput->when(FL_WHEN_ENTER_KEY);
01835 isomininput->selection_color(VMDMENU_VALUE_SEL);
01836 isomininput->callback(minmaxinputcb, this);
01837 isomaxinput = new Fl_Float_Input(gx+85, gy+90, 45, CTRHEIGHT);
01838 isomaxinput->when(FL_WHEN_ENTER_KEY);
01839 isomaxinput->selection_color(VMDMENU_VALUE_SEL);
01840 isomaxinput->callback(minmaxinputcb, this);
01841
01842 Fl_Group::end();
01843 }
01844 const char *repcmd() {
01845 sprintf(cmdbuf, "Orbital %f %d %d %d %.3f %d %d %d %d %d",
01846 (float) isovalue->value(),
01847 (int) (orbitalindex->value() + orbitalminindex + 1),
01848 (int) boundary->value(),
01849 (int) method->value(),
01850 (float) resolution->value(),
01851 (int) thickness->value(),
01852 (int) wavefnctype->value(),
01853 (int) wavefncspin->value(),
01854 (int) wavefncexcitation->value(),
01855 gridstepsize);
01856 return cmdbuf;
01857 }
01858 void set_values(AtomRep *rep) {
01859 int oldtype = wavefnctype->value();
01860 int oldspin = wavefncspin->value();
01861 int oldexcitation = wavefncexcitation->value();
01862
01863 int newtype = (int) rep->get_data(AtomRep::WAVEFNCTYPE);
01864 int newspin = (int) rep->get_data(AtomRep::WAVEFNCSPIN);
01865 int newexcitation = (int) rep->get_data(AtomRep::WAVEFNCEXCITATION);
01866
01867
01868
01869 if (oldtype != newtype || oldspin != newspin ||
01870 oldexcitation != newexcitation) {
01871 wavefnctype->setvalue(newtype);
01872 wavefncspin->setvalue(newspin);
01873
01874 if (oldtype != newtype) {
01875
01876
01877 regen_excitationlist();
01878 }
01879 wavefncexcitation->setvalue(newexcitation);
01880 }
01881
01882
01883
01884
01885 int oldorbidx = orbitalindex->value() + orbitalminindex + 1;
01886 int neworbidx = (int)rep->get_data(AtomRep::SPHERERES);
01887 if (oldtype != newtype || oldspin != newspin ||
01888 oldexcitation != newexcitation ||
01889 abs(neworbidx-oldorbidx) > 10) {
01890
01891
01892 regen_orbitallist(neworbidx);
01893 }
01894 orbitalindex->setvalue(neworbidx - orbitalminindex - 1);
01895
01896
01897
01898 if (minmaxlist.num() > 0) {
01899 minmax &m = minmaxlist[orbitalindex->value()];
01900 isovalue->range(m.minval, m.maxval);
01901 } else {
01902 isovalue->range(0, 1);
01903 }
01904 isovalue->value(rep->get_data(AtomRep::SPHERERAD));
01905 method->setvalue((int)rep->get_data(AtomRep::BONDRES));
01906 boundary->setvalue((int)rep->get_data(AtomRep::LINETHICKNESS));
01907 resolution->value(rep->get_data(AtomRep::GRIDSPACING));
01908 thickness->value(rep->get_data(AtomRep::ISOLINETHICKNESS));
01909 set_grid_stepsize((int) rep->get_data(AtomRep::ISOSTEPSIZE));
01910 setInputFromSlider();
01911 }
01912 void set_grid_stepsize(int step) {
01913 if (step < 1)
01914 step=1;
01915
01916 gridstepsize = step;
01917 }
01918 };
01919
01920
01921
01922
01924 class GraphicsFltkRepFieldLines : public GraphicsFltkRepVolumetric {
01925 private:
01926 Fl_Counter *thickness;
01927 Fl_Value_Slider *gradmag;
01928 Fl_Value_Slider *minlen;
01929 Fl_Value_Slider *maxlen;
01930
01931 protected:
01932 void do_dataset_clear() {
01933 gradmag->deactivate();
01934 minlen->deactivate();
01935 maxlen->deactivate();
01936 thickness->deactivate();
01937 }
01938 void do_dataset_append(const char *, double, double) {
01939 gradmag->activate();
01940 minlen->activate();
01941 maxlen->activate();
01942 thickness->activate();
01943 }
01944 void do_reset() {
01945 gradmag->value(1.8);
01946 minlen->value(10);
01947 maxlen->value(50);
01948 thickness->value(1);
01949 }
01950
01951 public:
01952 GraphicsFltkRepFieldLines(Fl_Callback *cb, void *v)
01953 : GraphicsFltkRepVolumetric(cb, v) {
01954 thickness = new ResolutionCounter(x()+20, y()+30, "Size");
01955 thickness->callback(cb, v);
01956 gradmag = new IsoSlider(x()+80, y()+60, "GradientMag");
01957 gradmag->callback(cb, v);
01958 minlen = new IsoSlider(x()+80, y()+90, "Min Length");
01959 minlen->callback(cb, v);
01960 maxlen = new IsoSlider(x()+80, y()+120, "Max Length");
01961 maxlen->callback(cb, v);
01962 Fl_Group::end();
01963 }
01964 const char *repcmd() {
01965 if (dataset->size() > 0) {
01966 sprintf(cmdbuf, "FieldLines %f %f %f %f %f",
01967 (float)dataset->value(), gradmag->value(), minlen->value(), maxlen->value(), thickness->value());
01968 } else {
01969 sprintf(cmdbuf, "FieldLines");
01970 }
01971 return cmdbuf;
01972 }
01973 void set_values(AtomRep *rep) {
01974 dataset->setvalue((int)rep->get_data(AtomRep::SPHERERES));
01975 gradmag->range(0.05, 25.0);
01976 gradmag->value(rep->get_data(AtomRep::SPHERERAD));
01977 minlen->range(1, 500.0);
01978 minlen->value(rep->get_data(AtomRep::BONDRAD));
01979 maxlen->range(1, 500.0);
01980 maxlen->value(rep->get_data(AtomRep::BONDRES));
01981 thickness->range(1, 10);
01982 thickness->value(rep->get_data(AtomRep::LINETHICKNESS));
01983 }
01984 };
01985
01986