mirror of
https://github.com/schrodinger/pymol-open-source.git
synced 2026-06-04 20:04:21 +08:00
3285 lines
94 KiB
C++
3285 lines
94 KiB
C++
|
|
/*
|
|
A* -------------------------------------------------------------------
|
|
B* This file contains source code for the PyMOL computer program
|
|
C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific.
|
|
D* -------------------------------------------------------------------
|
|
E* It is unlawful to modify or remove this copyright notice.
|
|
F* -------------------------------------------------------------------
|
|
G* Please see the accompanying LICENSE file for further information.
|
|
H* -------------------------------------------------------------------
|
|
I* Additional authors of this source file include:
|
|
-*
|
|
-*
|
|
-*
|
|
Z* -------------------------------------------------------------------
|
|
*/
|
|
#include"os_python.h"
|
|
|
|
#include"os_proprietary.h"
|
|
|
|
#include"os_predef.h"
|
|
#include"os_std.h"
|
|
|
|
#include"Base.h"
|
|
#include"Err.h"
|
|
#include"MemoryDebug.h"
|
|
#include"Ortho.h"
|
|
#include"Setting.h"
|
|
#include"Scene.h"
|
|
#include"ButMode.h"
|
|
#include"CGO.h"
|
|
#include"Executive.h"
|
|
#include"Editor.h"
|
|
#include"P.h"
|
|
#include"Util.h"
|
|
#include"main.h"
|
|
#include"PConv.h"
|
|
#include"Wizard.h"
|
|
#include"Seq.h"
|
|
#include"PyMOLOptions.h"
|
|
#include"ShaderMgr.h"
|
|
#include"Sphere.h"
|
|
#include"Selector.h"
|
|
#include"Parse.h"
|
|
#include "Feedback.h"
|
|
#include "Util2.h"
|
|
|
|
#ifdef _PYMOL_OPENVR
|
|
#include"OpenVRMode.h"
|
|
#endif
|
|
|
|
#include <thread>
|
|
|
|
/**
|
|
* Setting level info table
|
|
*
|
|
* Levels are not hierarchical at the atom/bond level, that's why a simple
|
|
* sorted enumeration is not sufficient.
|
|
*
|
|
* global < object < object-state
|
|
* object-state < atom < atom-state
|
|
* object-state < bond < bond-state
|
|
*/
|
|
const SettingLevelInfoType SettingLevelInfo[] = {
|
|
{"unused" , 0x00}, // 0b00000000
|
|
{"global" , 0x00}, // 0b00000000
|
|
{"object" , 0x01}, // 0b00000001
|
|
{"object-state" , 0x03}, // 0b00000011
|
|
{"atom" , 0x07}, // 0b00000111
|
|
{"atom-state" , 0x0F}, // 0b00001111
|
|
{"bond" , 0x13}, // 0b00010011
|
|
{"bond-state" , 0x33}, // 0b00110011
|
|
{NULL, 0}
|
|
};
|
|
|
|
// The following defines the static SettingInfo table
|
|
#define SETTINGINFO_IMPLEMENTATION
|
|
#include "SettingInfo.h"
|
|
|
|
template <> const char * _SettingGet<const char *>(int index, const CSetting * I);
|
|
|
|
// get level name for setting index (for feedback)
|
|
const char * SettingLevelGetName(unsigned index) {
|
|
return SettingLevelInfo[SettingInfo[index].level].name;
|
|
}
|
|
|
|
// check if setting index is valid in given level-mask
|
|
bool SettingLevelCheckMask(PyMOLGlobals * G, int index, unsigned char mask) {
|
|
unsigned char validmask = SettingLevelInfo[SettingInfo[index].level].mask;
|
|
return (0 == (mask & ~validmask));
|
|
}
|
|
|
|
// check if setting index is valid in given level
|
|
bool SettingLevelCheck(PyMOLGlobals * G, int index, unsigned char level) {
|
|
return SettingLevelCheckMask(G, index, SettingLevelInfo[level].mask);
|
|
}
|
|
|
|
/* ================================================================== */
|
|
|
|
static void SettingRecCopy(
|
|
int const index, SettingRec const& src, SettingRec& dst)
|
|
{
|
|
switch (SettingInfo[index].type) {
|
|
case cSetting_string:
|
|
dst.set_s(src.str_ ? src.str_->c_str() : nullptr);
|
|
break;
|
|
case cSetting_float3:
|
|
dst.set_3f(src.float3_);
|
|
break;
|
|
default:
|
|
dst.set_i(src.int_);
|
|
break;
|
|
}
|
|
dst.defined = src.defined;
|
|
}
|
|
|
|
CSetting *SettingCopyAll(PyMOLGlobals * G, const CSetting * src, CSetting * dst)
|
|
{
|
|
if (!src) {
|
|
delete dst;
|
|
return nullptr;
|
|
}
|
|
|
|
if (!dst) {
|
|
dst = SettingNew(G);
|
|
}
|
|
|
|
for (int index = 0; index < cSetting_INIT; ++index) {
|
|
SettingRecCopy(index, src->info[index], dst->info[index]);
|
|
}
|
|
|
|
return dst;
|
|
}
|
|
|
|
void SettingStoreDefault(PyMOLGlobals * G)
|
|
{
|
|
G->Default = SettingCopyAll(G, G->Setting, G->Default);
|
|
}
|
|
|
|
void SettingPurgeDefault(PyMOLGlobals * G)
|
|
{
|
|
DeleteP(G->Default);
|
|
}
|
|
|
|
void SettingUniqueDetachChain(PyMOLGlobals* G, int unique_id)
|
|
{
|
|
CSettingUnique* I = G->SettingUnique;
|
|
auto offsetIt = I->id2offset.find(unique_id);
|
|
if (offsetIt == I->id2offset.end()) {
|
|
return;
|
|
}
|
|
int offset = offsetIt->second;
|
|
I->id2offset.erase(offsetIt);
|
|
|
|
while (offset) {
|
|
auto entry = &I->entry[offset];
|
|
auto next = entry->next;
|
|
entry->next = I->next_free;
|
|
I->next_free = offset;
|
|
offset = next;
|
|
}
|
|
}
|
|
|
|
static void SettingUniqueExpand(PyMOLGlobals * G)
|
|
{
|
|
CSettingUnique *I = G->SettingUnique;
|
|
|
|
if(!I->next_free) {
|
|
int new_n_alloc = (I->entry.size() * 3) / 2;
|
|
auto sizeBefore = I->entry.size();
|
|
I->entry.resize(sizeBefore + new_n_alloc, SettingUniqueEntry{});
|
|
for(int a = sizeBefore; a < new_n_alloc; a++) {
|
|
I->entry[a].next = I->next_free;
|
|
I->next_free = a;
|
|
}
|
|
}
|
|
}
|
|
|
|
static
|
|
SettingUniqueEntry *SettingFindSettingUniqueEntry(PyMOLGlobals * G, int unique_id, int setting_id)
|
|
{
|
|
CSettingUnique *I = G->SettingUnique;
|
|
auto offsetIt = I->id2offset.find(unique_id);
|
|
if (offsetIt != I->id2offset.end()) {
|
|
SettingUniqueEntry* entry;
|
|
for (int offset = offsetIt->second; offset; offset = entry->next) {
|
|
entry = &I->entry[offset];
|
|
if(entry->setting_id == setting_id) {
|
|
return entry;
|
|
}
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
int SettingUniqueCheck(PyMOLGlobals * G, int unique_id, int setting_id)
|
|
{
|
|
return SettingFindSettingUniqueEntry(G, unique_id, setting_id) != nullptr;
|
|
}
|
|
|
|
/**
|
|
* Return true for convertible types and set int-compatible types to int
|
|
*/
|
|
inline bool type_upcast(int &type) {
|
|
switch (type) {
|
|
case cSetting_int:
|
|
case cSetting_color:
|
|
case cSetting_boolean:
|
|
type = cSetting_int;
|
|
case cSetting_float:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool SettingUniqueGetTypedValuePtr(PyMOLGlobals * G, int unique_id, int setting_id,
|
|
int setting_type, void * value)
|
|
{
|
|
auto entry = SettingFindSettingUniqueEntry(G, unique_id, setting_id);
|
|
if (!entry)
|
|
return false;
|
|
|
|
int type_from = SettingInfo[setting_id].type;
|
|
|
|
if (type_from != setting_type) {
|
|
if (!type_upcast(type_from) ||
|
|
!type_upcast(setting_type)) {
|
|
PRINTFB(G, FB_Setting, FB_Errors)
|
|
" Setting-Error: type mismatch\n" ENDFB(G);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (setting_type == cSetting_float3){
|
|
*(const float **) value = entry->value.float3_;
|
|
} else if (setting_type == type_from) {
|
|
*(int *) value = entry->value.int_;
|
|
} else if (setting_type == cSetting_int) {
|
|
*(int *) value = (int) entry->value.float_;
|
|
} else { // setting_type == cSetting_float
|
|
*(float *) value = (float) entry->value.int_;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Warning: Returns colors as (fff) tuple instead of color index
|
|
*
|
|
* @pre GIL
|
|
*/
|
|
PyObject *SettingUniqueGetPyObject(PyMOLGlobals * G, int unique_id, int index)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
int type = SettingGetType(G, index);
|
|
|
|
union {
|
|
int val_i;
|
|
float val_f;
|
|
const float * ptr_3f;
|
|
};
|
|
|
|
if (SettingUniqueGetTypedValuePtr(G, unique_id, index, type, &ptr_3f)) {
|
|
switch (type) {
|
|
case cSetting_boolean:
|
|
return CPythonVal_New_Boolean(val_i);
|
|
case cSetting_int:
|
|
return CPythonVal_New_Integer(val_i);
|
|
case cSetting_float:
|
|
return CPythonVal_New_Float(val_f);
|
|
case cSetting_color:
|
|
#ifdef _PYMOL_NOPY
|
|
return CPythonVal_New_Integer(val_i);
|
|
#else
|
|
return PYOBJECT_CALLFUNCTION(G->P_inst->colortype, "i", val_i);
|
|
#endif
|
|
case cSetting_float3:
|
|
{
|
|
PyObject *result = PyTuple_New(3);
|
|
PyTuple_SET_ITEM(result, 0, CPythonVal_New_Float(ptr_3f[0]));
|
|
PyTuple_SET_ITEM(result, 1, CPythonVal_New_Float(ptr_3f[1]));
|
|
PyTuple_SET_ITEM(result, 2, CPythonVal_New_Float(ptr_3f[2]));
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
static int SettingUniqueEntry_IsSame(SettingUniqueEntry *entry, int setting_type, const void *value){
|
|
if (SettingInfo[entry->setting_id].type != setting_type){
|
|
return 0;
|
|
}
|
|
if (setting_type == cSetting_float3){
|
|
const float *v = (float*)value, *ev = entry->value.float3_;
|
|
return v[0]==ev[0] && v[1]==ev[1] && v[2]==ev[2];
|
|
} else {
|
|
return (entry->value.int_ == *(int *) value);
|
|
}
|
|
}
|
|
|
|
static void SettingUniqueEntry_Set(SettingUniqueEntry *entry, int value_type, const void *value){
|
|
int setting_type = SettingGetType(entry->setting_id);
|
|
switch (value_type) {
|
|
case cSetting_boolean:
|
|
case cSetting_int:
|
|
case cSetting_color:
|
|
if (setting_type == cSetting_float) {
|
|
entry->value.float_ = *(int*) value;
|
|
} else {
|
|
entry->value.int_ = *(int *) value;
|
|
}
|
|
break;
|
|
case cSetting_float:
|
|
if (setting_type != cSetting_float) {
|
|
entry->value.int_ = *(float *) value;
|
|
} else {
|
|
entry->value.float_ = *(float *) value;
|
|
}
|
|
break;
|
|
case cSetting_float3:
|
|
memcpy(entry->value.float3_, *(const float **) value, sizeof(float) * 3);
|
|
break;
|
|
default:
|
|
printf("SettingUniqueEntry_Set-Error: unsupported type %d\n", value_type);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return false if setting was not set (nothing changed)
|
|
*/
|
|
bool SettingUniqueUnset(PyMOLGlobals * G, int unique_id, int setting_id)
|
|
{
|
|
auto I = G->SettingUnique;
|
|
auto offsetIt = I->id2offset.find(unique_id);
|
|
|
|
if (offsetIt != I->id2offset.end()) {
|
|
for (int prev = 0, offset = offsetIt->second; offset;
|
|
prev = offset, offset = I->entry[offset].next) {
|
|
if (I->entry[offset].setting_id != setting_id)
|
|
continue;
|
|
|
|
if(!prev) { /* if first entry in list */
|
|
I->id2offset.erase(offsetIt);
|
|
if(I->entry[offset].next) { /* set new list start */
|
|
I->id2offset[unique_id] = I->entry[offset].next;
|
|
}
|
|
} else { /* otherwise excise from middle or end */
|
|
I->entry[prev].next = I->entry[offset].next;
|
|
}
|
|
I->entry[offset].next = I->next_free;
|
|
I->next_free = offset;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int SettingUniqueSetTypedValue(PyMOLGlobals * G, int unique_id, int setting_id,
|
|
int setting_type, const void *value)
|
|
|
|
/* set value to nullptr in order to delete setting */
|
|
{
|
|
CSettingUnique *I = G->SettingUnique;
|
|
int isset = false;
|
|
|
|
if (!value) {
|
|
return SettingUniqueUnset(G, unique_id, setting_id);
|
|
}
|
|
|
|
auto offsetIt = I->id2offset.find(unique_id);
|
|
if (offsetIt != I->id2offset.end()) { /* setting list exists for atom */
|
|
int offset = offsetIt->second;
|
|
int prev = 0;
|
|
int found = false;
|
|
while(offset) {
|
|
auto entry = &I->entry[offset];
|
|
if(entry->setting_id == setting_id) {
|
|
found = true; /* this setting is already defined */
|
|
if (!SettingUniqueEntry_IsSame(entry, setting_type, value)){
|
|
SettingUniqueEntry_Set(entry, setting_type, value);
|
|
isset = true;
|
|
}
|
|
break;
|
|
}
|
|
prev = offset;
|
|
offset = entry->next;
|
|
}
|
|
if((!found) && value) { /* setting not found in existing list, so append new value */
|
|
if(!I->next_free)
|
|
SettingUniqueExpand(G);
|
|
if(I->next_free) {
|
|
offset = I->next_free;
|
|
{
|
|
auto entry = &I->entry[offset];
|
|
I->next_free = entry->next;
|
|
entry->next = 0;
|
|
|
|
if(prev) { /* append onto existing list */
|
|
I->entry[prev].next = offset;
|
|
entry->setting_id = setting_id;
|
|
SettingUniqueEntry_Set(entry, setting_type, value);
|
|
isset = true;
|
|
} else {
|
|
I->id2offset[unique_id] = offset;
|
|
/* create new list */
|
|
entry->setting_id = setting_id;
|
|
SettingUniqueEntry_Set(entry, setting_type, value);
|
|
isset = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if(value && offsetIt == I->id2offset.end()) { /* new setting list for atom */
|
|
if(!I->next_free)
|
|
SettingUniqueExpand(G);
|
|
if(I->next_free) {
|
|
int offset = I->next_free;
|
|
auto entry = &I->entry[offset];
|
|
|
|
I->id2offset[unique_id] = offset;
|
|
I->next_free = entry->next;
|
|
entry->setting_id = setting_id;
|
|
entry->next = 0;
|
|
SettingUniqueEntry_Set(entry, setting_type, value);
|
|
isset = true;
|
|
}
|
|
} else {
|
|
/* unhandled error */
|
|
}
|
|
return isset;
|
|
}
|
|
|
|
#ifndef _PYMOL_NOPY
|
|
/**
|
|
* @pre GIL
|
|
*/
|
|
bool SettingUniqueSetPyObject(PyMOLGlobals * G, int unique_id, int index, PyObject *value)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
if (!value)
|
|
return SettingUniqueUnset(G, unique_id, index);
|
|
|
|
int type = SettingGetType(G, index);
|
|
|
|
float val_3f[3];
|
|
union {
|
|
int val_i;
|
|
float val_f;
|
|
float * ptr_3f;
|
|
};
|
|
|
|
switch (type) {
|
|
case cSetting_boolean:
|
|
case cSetting_int:
|
|
ok_assert(1, PConvPyObjectToInt(value, &val_i));
|
|
break;
|
|
case cSetting_float:
|
|
ok_assert(1, PConvPyObjectToFloat(value, &val_f));
|
|
break;
|
|
case cSetting_color:
|
|
if (!PConvPyIntToInt(value, &val_i)) {
|
|
OrthoLineType sval;
|
|
ok_assert(1, PConvPyStrToStr(value, sval, OrthoLineLength));
|
|
val_i = ColorGetIndex(G, sval);
|
|
}
|
|
break;
|
|
case cSetting_float3:
|
|
if (!PConvPyListOrTupleToFloatArrayInPlace(value, val_3f, 3)) {
|
|
OrthoLineType sval;
|
|
ok_assert(1, PConvPyStrToStr(value, sval, OrthoLineLength) &&
|
|
sscanf(sval, "%f%f%f", &val_3f[0], &val_3f[1], &val_3f[2]) == 3);
|
|
}
|
|
ptr_3f = val_3f;
|
|
break;
|
|
default:
|
|
PRINTFB(G, FB_Python, FB_Errors)
|
|
" Python-Error: atom-state-level setting unsupported type=%d\n", type ENDFB(G);
|
|
return false;
|
|
}
|
|
|
|
return SettingUniqueSetTypedValue(G, unique_id, index, type, &val_i);
|
|
|
|
ok_except1:
|
|
PRINTFB(G, FB_Setting, FB_Errors)
|
|
" Setting-Error: type mismatch\n" ENDFB(G);
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
void SettingUniqueResetAll(PyMOLGlobals * G)
|
|
{
|
|
CSettingUnique *I = G->SettingUnique;
|
|
I->id2offset.clear();
|
|
I->entry.clear();
|
|
I->entry.resize(CSettingUnique::numInitEntries, SettingUniqueEntry{});
|
|
/* note: intentially skip index 0 */
|
|
for (int a = 2; a < I->entry.size(); a++) {
|
|
I->entry[a].next = a - 1; /* 1-based linked list with 0 as sentinel */
|
|
}
|
|
I->next_free = I->entry.size() - 1;
|
|
}
|
|
|
|
int SettingUniquePrintAll(PyMOLGlobals * G, int src_unique_id)
|
|
{
|
|
int ok = true;
|
|
CSettingUnique *I = G->SettingUnique;
|
|
printf("SettingUniquePrintAll: ");
|
|
auto offsetIt = I->id2offset.find(src_unique_id);
|
|
if (offsetIt != I->id2offset.end()) {
|
|
int src_offset = offsetIt->second;
|
|
SettingUniqueEntry *src_entry;
|
|
while(ok && src_offset) {
|
|
{
|
|
src_entry = &I->entry[src_offset];
|
|
{
|
|
int setting_id = src_entry->setting_id;
|
|
int setting_type = SettingInfo[setting_id].type;
|
|
const char * setting_name = SettingInfo[setting_id].name;
|
|
switch (setting_type) {
|
|
case cSetting_int:
|
|
case cSetting_color:
|
|
case cSetting_boolean:
|
|
printf("%s:%d:%d:%d ", setting_name, setting_id, setting_type, src_entry->value.int_);
|
|
break;
|
|
case cSetting_float:
|
|
printf("%s:%d:%d:%f ", setting_name, setting_id, setting_type, src_entry->value.float_);
|
|
break;
|
|
case cSetting_float3:
|
|
printf("%s:%d:%d:%f,%f,%f ", setting_name, setting_id, setting_type, src_entry->value.float3_[0],
|
|
src_entry->value.float3_[1],
|
|
src_entry->value.float3_[2]);
|
|
break;
|
|
case cSetting_string:
|
|
printf("%s:%d:%d:s%d ", setting_name, setting_id, setting_type, src_entry->value.int_);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
src_offset = I->entry[src_offset].next; /* src_entry invalid, since I->entry may have changed */
|
|
}
|
|
}
|
|
printf("\n");
|
|
return ok;
|
|
}
|
|
|
|
int SettingUniqueCopyAll(PyMOLGlobals * G, int src_unique_id, int dst_unique_id)
|
|
{
|
|
int ok = true;
|
|
CSettingUnique *I = G->SettingUnique;
|
|
|
|
auto dstOffsetIt = I->id2offset.find(dst_unique_id);
|
|
if (dstOffsetIt != I->id2offset.end()) { /* setting list exists for atom */
|
|
PRINTFB(G, FB_Setting, FB_Errors)
|
|
" SettingUniqueCopyAll-Bug: merging settings not implemented\n"
|
|
ENDFB(G);
|
|
ok = false;
|
|
} else if (dstOffsetIt == I->id2offset.end()) { /* new setting list for atom */
|
|
auto srcOffsetIt = I->id2offset.find(src_unique_id);
|
|
if (srcOffsetIt != I->id2offset.end()) {
|
|
int dst_offset = 0;
|
|
for (int src_offset = srcOffsetIt->second; src_offset;
|
|
src_offset = I->entry[src_offset].next) {
|
|
SettingUniqueExpand(G); // this may reallocate I->entry
|
|
|
|
if (!dst_offset) {
|
|
I->id2offset[dst_unique_id] = I->next_free;
|
|
} else {
|
|
I->entry[dst_offset].next = I->next_free;
|
|
}
|
|
|
|
dst_offset = I->next_free;
|
|
I->next_free = I->entry[dst_offset].next;
|
|
I->entry[dst_offset] = I->entry[src_offset];
|
|
I->entry[dst_offset].next = 0;
|
|
}
|
|
}
|
|
} else {
|
|
ok = false;
|
|
/* unhandled error */
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
static void SettingUniqueInit(PyMOLGlobals * G)
|
|
{
|
|
G->SettingUnique = new CSettingUnique();
|
|
SettingUniqueResetAll(G);
|
|
}
|
|
|
|
static void SettingUniqueFree(PyMOLGlobals * G)
|
|
{
|
|
DeleteP(G->SettingUnique);
|
|
}
|
|
|
|
/**
|
|
* For unique_id remapping during partial session loading
|
|
*/
|
|
int SettingUniqueConvertOldSessionID(PyMOLGlobals * G, int old_unique_id)
|
|
{
|
|
CSettingUnique *I = G->SettingUnique;
|
|
int unique_id = old_unique_id;
|
|
if (I->old2new) {
|
|
auto oldIdIt = I->old2new->find(old_unique_id);
|
|
if (oldIdIt != I->old2new->end()) {
|
|
unique_id = oldIdIt->second;
|
|
} else {
|
|
unique_id = AtomInfoGetNewUniqueID(G);
|
|
I->old2new->emplace(old_unique_id, unique_id);
|
|
}
|
|
} else {
|
|
AtomInfoReserveUniqueID(G, unique_id);
|
|
}
|
|
return unique_id;
|
|
}
|
|
|
|
/**
|
|
* Return true if the given setting index should not be stored to PSE.
|
|
*
|
|
* Blacklisted are unused and system-dependent settings.
|
|
*/
|
|
static bool is_session_blacklisted(int index) {
|
|
if (index >= cSetting_INIT ||
|
|
SettingInfo[index].level == cSettingLevel_unused) {
|
|
return true;
|
|
}
|
|
|
|
switch (index) {
|
|
case cSetting_antialias_shader:
|
|
case cSetting_ati_bugs:
|
|
case cSetting_cache_max:
|
|
case cSetting_cgo_shader_ub_color:
|
|
case cSetting_cgo_shader_ub_flags:
|
|
case cSetting_cgo_shader_ub_normal:
|
|
case cSetting_colored_feedback:
|
|
case cSetting_cylinder_shader_ff_workaround:
|
|
case cSetting_defer_updates:
|
|
case cSetting_fast_idle:
|
|
case cSetting_fetch_path:
|
|
case cSetting_internal_feedback:
|
|
case cSetting_internal_gui:
|
|
case cSetting_internal_prompt:
|
|
case cSetting_logging:
|
|
case cSetting_max_threads:
|
|
case cSetting_mouse_grid:
|
|
case cSetting_mouse_scale:
|
|
case cSetting_nb_spheres_use_shader:
|
|
case cSetting_no_idle:
|
|
case cSetting_nvidia_bugs:
|
|
case cSetting_presentation:
|
|
case cSetting_precomputed_lighting:
|
|
case cSetting_render_as_cylinders:
|
|
case cSetting_security:
|
|
case cSetting_session_changed:
|
|
case cSetting_session_file:
|
|
case cSetting_session_migration:
|
|
case cSetting_session_version_check:
|
|
case cSetting_shaders_from_disk:
|
|
case cSetting_show_progress:
|
|
case cSetting_slow_idle:
|
|
case cSetting_stereo:
|
|
case cSetting_stereo_double_pump_mono:
|
|
case cSetting_stereo_mode:
|
|
case cSetting_suspend_deferred:
|
|
case cSetting_suspend_undo:
|
|
case cSetting_suspend_undo_atom_count:
|
|
case cSetting_suspend_updates:
|
|
case cSetting_text:
|
|
case cSetting_trilines:
|
|
case cSetting_use_geometry_shaders:
|
|
case cSetting_use_shaders:
|
|
case cSetting_pick32bit:
|
|
case cSetting_display_scale_factor:
|
|
#if defined(_PYMOL_ACTIVEX)
|
|
case cSetting_async_builds:
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @pre GIL
|
|
*/
|
|
int SettingUniqueFromPyList(PyMOLGlobals * G, PyObject * list, int partial_restore)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
int ok = true;
|
|
if(!partial_restore) {
|
|
SettingUniqueResetAll(G);
|
|
}
|
|
if(list)
|
|
if(PyList_Check(list)) {
|
|
ov_size n_id = PyList_Size(list);
|
|
ov_size a;
|
|
for(a = 0; a < n_id; a++) {
|
|
PyObject *id_list = PyList_GetItem(list, a);
|
|
int unique_id;
|
|
if(ok)
|
|
ok = PyList_Check(id_list);
|
|
if(ok)
|
|
ok = (PyList_Size(id_list) > 1);
|
|
if(ok)
|
|
ok = PConvPyIntToInt(PyList_GetItem(id_list, 0), &unique_id);
|
|
if(ok && partial_restore) {
|
|
unique_id = SettingUniqueConvertOldSessionID(G, unique_id);
|
|
}
|
|
if(ok) {
|
|
ov_size n_set = 0;
|
|
|
|
PyObject *setting_list = PyList_GetItem(id_list, 1);
|
|
if(ok)
|
|
ok = PyList_Check(setting_list);
|
|
if(ok)
|
|
n_set = PyList_Size(setting_list);
|
|
if(ok) {
|
|
ov_size b;
|
|
for(b = 0; b < n_set; b++) {
|
|
PyObject *entry_list = PyList_GetItem(setting_list, b);
|
|
if(ok)
|
|
ok = PyList_Check(entry_list);
|
|
if(ok)
|
|
ok = (PyList_Size(entry_list) > 2);
|
|
if(ok) {
|
|
int setting_id;
|
|
int setting_type;
|
|
float val_3f[3];
|
|
union {
|
|
int int_;
|
|
float float_;
|
|
float * float3_;
|
|
} value_store;
|
|
if(ok)
|
|
ok = PConvPyIntToInt(PyList_GetItem(entry_list, 0), &setting_id);
|
|
if(ok)
|
|
ok = PConvPyIntToInt(PyList_GetItem(entry_list, 1), &setting_type);
|
|
if(ok)
|
|
switch (setting_type) {
|
|
|
|
case cSetting_int:
|
|
case cSetting_color:
|
|
case cSetting_boolean:
|
|
ok = PConvPyIntToInt(PyList_GetItem(entry_list, 2),
|
|
&value_store.int_);
|
|
if (setting_type == cSetting_color) {
|
|
value_store.int_ =
|
|
ColorConvertOldSessionIndex(G, value_store.int_);
|
|
}
|
|
break;
|
|
case cSetting_float:
|
|
ok = PConvPyFloatToFloat(PyList_GetItem(entry_list, 2),
|
|
&value_store.float_);
|
|
break;
|
|
case cSetting_float3:
|
|
{
|
|
CPythonVal *el = CPythonVal_PyList_GetItem(G, entry_list, 2);
|
|
value_store.float3_ = val_3f;
|
|
ok = PConvPyListToFloatArrayInPlace(el, value_store.float3_, 3);
|
|
CPythonVal_Free(el);
|
|
}
|
|
break;
|
|
}
|
|
if(ok) {
|
|
SettingUniqueSetTypedValue(G, unique_id, setting_id,
|
|
setting_type, &value_store);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
/**
|
|
* @pre GIL
|
|
*/
|
|
PyObject *SettingUniqueAsPyList(PyMOLGlobals * G)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
PyObject *result = nullptr;
|
|
CSettingUnique *I = G->SettingUnique;
|
|
{
|
|
auto n_entry = I->id2offset.size();
|
|
result = PyList_New(n_entry);
|
|
if(result) {
|
|
n_entry = 0;
|
|
for (auto id2offset : I->id2offset) {
|
|
PyObject *setting_list = nullptr;
|
|
auto unique_id = id2offset.first;
|
|
auto offset = id2offset.second;
|
|
{
|
|
int n_set = 0;
|
|
|
|
/* count number of settings for this unique_id */
|
|
|
|
auto save_offset = offset;
|
|
while(offset) {
|
|
auto entry = &I->entry[offset];
|
|
n_set++;
|
|
offset = entry->next;
|
|
}
|
|
|
|
/* create and insert list for each setting */
|
|
|
|
setting_list = PyList_New(n_set);
|
|
n_set = 0;
|
|
offset = save_offset;
|
|
while(offset) {
|
|
PyObject *setting_entry = PyList_New(3);
|
|
auto entry = &I->entry[offset];
|
|
int type = SettingInfo[entry->setting_id].type;
|
|
PyList_SetItem(setting_entry, 0, PyInt_FromLong(entry->setting_id));
|
|
PyList_SetItem(setting_entry, 1, PyInt_FromLong(type));
|
|
switch (type) {
|
|
case cSetting_int:
|
|
case cSetting_color:
|
|
case cSetting_boolean:
|
|
PyList_SetItem(setting_entry, 2, PyInt_FromLong(entry->value.int_));
|
|
break;
|
|
case cSetting_float:
|
|
PyList_SetItem(setting_entry, 2,
|
|
PyFloat_FromDouble(*(float *) &entry->value.float_));
|
|
break;
|
|
case cSetting_float3:
|
|
PyList_SetItem(setting_entry, 2,
|
|
PConvFloatArrayToPyList((float *) &entry->value.float3_, 3));
|
|
break;
|
|
}
|
|
PyList_SetItem(setting_list, n_set, setting_entry);
|
|
n_set++;
|
|
offset = entry->next;
|
|
}
|
|
}
|
|
|
|
/* add this unique_id set into the overall list */
|
|
|
|
{
|
|
PyObject *unique_list = PyList_New(2);
|
|
PyList_SetItem(unique_list, 0, PyInt_FromLong(unique_id));
|
|
PyList_SetItem(unique_list, 1, setting_list);
|
|
PyList_SetItem(result, n_entry, unique_list);
|
|
}
|
|
n_entry++;
|
|
}
|
|
}
|
|
}
|
|
return (PConvAutoNone(result));
|
|
}
|
|
|
|
int SettingSetSmart_i(PyMOLGlobals * G, CSetting * set1, CSetting * set2, int index,
|
|
int value)
|
|
{
|
|
int dummy;
|
|
if(set1 && SettingGetIfDefined_i(G, set1, index, &dummy)) {
|
|
return SettingSet_i(set1, index, value);
|
|
}
|
|
if(set2 && SettingGetIfDefined_i(G, set2, index, &dummy)) {
|
|
return SettingSet_i(set2, index, value);
|
|
}
|
|
return SettingSetGlobal_i(G, index, value);
|
|
}
|
|
|
|
/**
|
|
* @pre GIL
|
|
*/
|
|
int SettingSetGlobalsFromPyList(PyMOLGlobals * G, PyObject * list)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
int ok = true;
|
|
|
|
CSetting *I = G->Setting;
|
|
|
|
if(list)
|
|
if(PyList_Check(list))
|
|
ok = SettingFromPyList(I, list);
|
|
|
|
/* restore the following settings */
|
|
|
|
if(G->Option->no_quit) {
|
|
SettingSet_b(I, cSetting_presentation_auto_quit, 0);
|
|
}
|
|
|
|
ColorUpdateFrontFromSettings(G);
|
|
return (ok);
|
|
}
|
|
|
|
/**
|
|
* @pre GIL
|
|
*/
|
|
PyObject *SettingGetGlobalsAsPyList(PyMOLGlobals * G)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
PyObject *result = nullptr;
|
|
CSetting *I = G->Setting;
|
|
result = SettingAsPyList(I);
|
|
return (PConvAutoNone(result));
|
|
}
|
|
|
|
/**
|
|
* @pre GIL
|
|
*/
|
|
static PyObject *get_list(CSetting * I, int index, bool incl_blacklisted)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
PyObject *result = nullptr, *value = nullptr;
|
|
int setting_type = SettingInfo[index].type;
|
|
|
|
if (!incl_blacklisted && is_session_blacklisted(index)) {
|
|
return nullptr;
|
|
}
|
|
|
|
switch (setting_type) {
|
|
|
|
case cSetting_boolean:
|
|
case cSetting_int:
|
|
case cSetting_color:
|
|
value = PyInt_FromLong(I->info[index].int_);
|
|
break;
|
|
case cSetting_float:
|
|
value = PyFloat_FromDouble(I->info[index].float_);
|
|
break;
|
|
case cSetting_float3:
|
|
value = PConvFloatArrayToPyList(I->info[index].float3_, 3);
|
|
break;
|
|
case cSetting_string:
|
|
value = PyString_FromString(SettingGet<const char *>(index, I));
|
|
break;
|
|
}
|
|
|
|
if (value) {
|
|
result = PyList_New(3);
|
|
PyList_SetItem(result, 0, PyInt_FromLong(index));
|
|
PyList_SetItem(result, 1, PyInt_FromLong(setting_type));
|
|
PyList_SetItem(result, 2, value);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @pre GIL
|
|
*/
|
|
PyObject *SettingAsPyList(CSetting * I, bool incl_blacklisted)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
PyObject *result = nullptr;
|
|
int a;
|
|
|
|
if(I) {
|
|
std::vector<PyObject*> list;
|
|
list.reserve(cSetting_INIT);
|
|
|
|
for(a = 0; a < cSetting_INIT; a++) {
|
|
if(I->info[a].defined) {
|
|
PyObject * item = get_list(I, a, incl_blacklisted);
|
|
if (item != nullptr) {
|
|
list.push_back(item);
|
|
}
|
|
}
|
|
}
|
|
|
|
result = PConvToPyObject(list);
|
|
}
|
|
return (PConvAutoNone(result));
|
|
}
|
|
|
|
/*========================================================================*/
|
|
static int SettingCheckUseShaders(CSetting * I, int quiet)
|
|
{
|
|
PyMOLGlobals * G = I->G;
|
|
if (SettingGetGlobal_i(G, cSetting_use_shaders)){
|
|
if (G->ShaderMgr->IsConfigured() && !G->ShaderMgr->ShadersPresent()){
|
|
SettingSet_b(I, cSetting_use_shaders, 0);
|
|
if (!quiet){
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
"Setting-Error: use_shaders cannot be set when Shaders are not available, setting use_shaders back to false\n"
|
|
ENDFB(G);
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*========================================================================*/
|
|
/**
|
|
* @pre GIL
|
|
*/
|
|
static int set_list(CSetting * I, PyObject * list)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
int index = -1;
|
|
int setting_type = -1;
|
|
|
|
union {
|
|
int val_i;
|
|
float val_f;
|
|
float val_3f[3];
|
|
const char * val_s;
|
|
};
|
|
|
|
if (list == nullptr || CPythonVal_IsNone(list))
|
|
return true;
|
|
|
|
ok_assert(1, PyList_Check(list));
|
|
ok_assert(1, CPythonVal_PConvPyIntToInt_From_List(I->G, list, 0, &index));
|
|
ok_assert(1, CPythonVal_PConvPyIntToInt_From_List(I->G, list, 1, &setting_type));
|
|
|
|
if (is_session_blacklisted(index))
|
|
return true;
|
|
|
|
switch (setting_type) {
|
|
case cSetting_boolean:
|
|
case cSetting_int:
|
|
case cSetting_color:
|
|
ok_assert(1, CPythonVal_PConvPyIntToInt_From_List(I->G, list, 2, &val_i));
|
|
if (setting_type == cSetting_color)
|
|
val_i = ColorConvertOldSessionIndex(I->G, val_i);
|
|
SettingSet_i(I, index, val_i);
|
|
break;
|
|
case cSetting_float:
|
|
ok_assert(1, CPythonVal_PConvPyFloatToFloat_From_List(I->G, list, 2, &val_f));
|
|
SettingSet_f(I, index, val_f);
|
|
break;
|
|
case cSetting_float3:
|
|
ok_assert(1, CPythonVal_PConvPyListToFloatArrayInPlaceAutoZero_From_List(I->G, list, 2, val_3f, 3));
|
|
SettingSet_3fv(I, index, val_3f);
|
|
break;
|
|
case cSetting_string:
|
|
ok_assert(1, val_s = PyString_AsString(PyList_GetItem(list, 2)));
|
|
SettingSet_s(I, index, val_s);
|
|
break;
|
|
default:
|
|
ok_raise(1);
|
|
}
|
|
|
|
return true;
|
|
ok_except1:
|
|
printf(" set_list-Error: i=%d, t=%d\n", index, setting_type);
|
|
return false;
|
|
}
|
|
|
|
/*========================================================================*/
|
|
/**
|
|
* Used to set object and object-state level settings from PSEs
|
|
*
|
|
* @pre GIL
|
|
*/
|
|
CSetting *SettingNewFromPyList(PyMOLGlobals * G, PyObject * list)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
int ok = true;
|
|
ov_size size;
|
|
ov_size a;
|
|
CSetting *I = nullptr;
|
|
if(ok)
|
|
ok = (list != nullptr);
|
|
if(ok)
|
|
ok = PyList_Check(list);
|
|
if(ok) {
|
|
I = SettingNew(G);
|
|
size = PyList_Size(list);
|
|
for(a = 0; a < size; a++) {
|
|
if(ok)
|
|
ok = set_list(I, PyList_GetItem(list, a));
|
|
}
|
|
}
|
|
return (I);
|
|
}
|
|
|
|
/*========================================================================*/
|
|
/**
|
|
* @pre GIL
|
|
*/
|
|
int SettingFromPyList(CSetting * I, PyObject * list)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
int ok = true;
|
|
ov_size size;
|
|
ov_size a;
|
|
|
|
if(ok)
|
|
ok = (I != nullptr);
|
|
if(ok)
|
|
ok = PyList_Check(list);
|
|
if(ok) {
|
|
size = PyList_Size(list);
|
|
for(a = 0; a < size; a++) {
|
|
if(!set_list(I, PyList_GetItem(list, a)))
|
|
ok = false;
|
|
}
|
|
}
|
|
return (ok);
|
|
}
|
|
|
|
/*========================================================================*/
|
|
/**
|
|
* Get the indices of all settings that have changed since last calling
|
|
* this function. Resets the "changed" flag.
|
|
*
|
|
* @param name object name or nullptr/"" for global settings
|
|
* @param state object state
|
|
*/
|
|
std::vector<int> SettingGetUpdateList(PyMOLGlobals * G, const char * name, int state)
|
|
{
|
|
CSetting* I = G->Setting;
|
|
pymol::copyable_ptr<CSetting>* handle;
|
|
std::vector<int> result;
|
|
|
|
if (name && name[0]) {
|
|
// object-state settings
|
|
|
|
pymol::CObject *obj = ExecutiveFindObjectByName(G, name);
|
|
|
|
if (!obj ||
|
|
!(handle = obj->getSettingHandle(state)) ||
|
|
!(I = handle->get()))
|
|
// not found -> empty list
|
|
return result;
|
|
}
|
|
|
|
for (int a = 0; a < cSetting_INIT; ++a) {
|
|
if(I->info[a].changed) {
|
|
I->info[a].changed = false;
|
|
result.push_back(a);
|
|
}
|
|
}
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
void SettingCheckHandle(PyMOLGlobals * G, pymol::copyable_ptr<CSetting>& handle)
|
|
{
|
|
if(!handle)
|
|
handle.reset(SettingNew(G));
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
int SettingGetTextValue(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2, int index,
|
|
char *buffer)
|
|
{
|
|
const char * sptr = SettingGetTextPtr(G, set1, set2, index, buffer);
|
|
if(!sptr)
|
|
return 0;
|
|
|
|
if (sptr != buffer) {
|
|
if(strlen(sptr) > OrthoLineLength) {
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
"Setting-Warning: text longer than OrthoLineLength" ENDFB(G);
|
|
}
|
|
|
|
strncpy(buffer, sptr, OrthoLineLength);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*========================================================================*/
|
|
/**
|
|
* Returns a pointer to the internal string representation if available,
|
|
* or it formats the value into buffer and returns a pointer to buffer.
|
|
*/
|
|
const char * SettingGetTextPtr(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2,
|
|
int index, char *buffer)
|
|
{
|
|
int type;
|
|
const char *sptr = nullptr;
|
|
const float *ptr;
|
|
type = SettingGetType(G, index);
|
|
switch (type) {
|
|
case cSetting_boolean:
|
|
sprintf(buffer, SettingGet_b(G, set1, set2, index) ? "on" : "off");
|
|
break;
|
|
case cSetting_int:
|
|
sprintf(buffer, "%d", SettingGet_i(G, set1, set2, index));
|
|
break;
|
|
case cSetting_float:
|
|
sprintf(buffer, "%1.5f", SettingGet_f(G, set1, set2, index));
|
|
break;
|
|
case cSetting_float3:
|
|
ptr = SettingGet_3fv(G, set1, set2, index);
|
|
sprintf(buffer, "[ %1.5f, %1.5f, %1.5f ]", ptr[0], ptr[1], ptr[2]);
|
|
break;
|
|
case cSetting_color:
|
|
{
|
|
int color = SettingGet_color(G, set1, set2, index);
|
|
switch (color) {
|
|
case cColorAtomic:
|
|
strcpy(buffer, "atomic");
|
|
break;
|
|
case cColorObject:
|
|
strcpy(buffer, "object");
|
|
break;
|
|
case cColorFront:
|
|
strcpy(buffer, "front");
|
|
break;
|
|
case cColorBack:
|
|
strcpy(buffer, "back");
|
|
break;
|
|
case cColorDefault:
|
|
strcpy(buffer, "default");
|
|
break;
|
|
default:
|
|
sptr = ColorGetName(G, color);
|
|
if(sptr)
|
|
return sptr;
|
|
strcpy(buffer, "invalid");
|
|
}
|
|
}
|
|
break;
|
|
case cSetting_string:
|
|
return SettingGet_s(G, set1, set2, index);
|
|
default:
|
|
return nullptr;
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
|
|
#ifndef _PYMOL_NOPY
|
|
/*========================================================================*/
|
|
/**
|
|
* @pre GIL
|
|
*/
|
|
int SettingSetFromTuple(PyMOLGlobals * G, CSetting * I, int index, PyObject * tuple)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
PyObject *value;
|
|
int type;
|
|
int ok = true;
|
|
if(!I)
|
|
I = G->Setting; /* fall back on global settings */
|
|
|
|
/* this data structure has been pre-checked at the python level... */
|
|
|
|
type = PyInt_AsLong(PyTuple_GetItem(tuple, 0));
|
|
value = PyTuple_GetItem(tuple, 1);
|
|
switch (type) {
|
|
case cSetting_boolean:
|
|
case cSetting_int:
|
|
SettingSet_i(I, index, PyInt_AsLong(value));
|
|
break;
|
|
case cSetting_float:
|
|
SettingSet_f(I, index, (float) PyFloat_AsDouble(value));
|
|
break;
|
|
case cSetting_float3:
|
|
float tmp[3];
|
|
PyArg_ParseTuple(value, "fff", tmp, tmp + 1, tmp + 2);
|
|
SettingSet_3fv(I, index, tmp);
|
|
break;
|
|
case cSetting_color:
|
|
SettingSet_color(I, index, PyString_AsString(value));
|
|
break;
|
|
case cSetting_string:
|
|
SettingSet_s(I, index, PyString_AsString(value));
|
|
break;
|
|
default:
|
|
ok = false;
|
|
break;
|
|
}
|
|
return (ok);
|
|
}
|
|
#endif
|
|
|
|
/*========================================================================*/
|
|
int SettingStringToTypedValue(PyMOLGlobals * G, int index, const char *st, int *type,
|
|
int *value)
|
|
{
|
|
int ok = true;
|
|
int newvalue ;
|
|
float newfvalue;
|
|
/* this data structure has been pre-checked at the python level... */
|
|
|
|
*type = SettingGetType(G, index);
|
|
|
|
switch (*type) {
|
|
case cSetting_boolean:
|
|
if((!*st) || (*st == '0') || (*st == 'F') || WordMatchExact(G, st, "on", true)
|
|
|| WordMatchExact(G, st, "false", true)){
|
|
newvalue = 0;
|
|
} else {
|
|
newvalue = 1;
|
|
}
|
|
if (newvalue != *value){
|
|
*value = newvalue;
|
|
}
|
|
break;
|
|
case cSetting_int:
|
|
if(sscanf(st, "%d", &newvalue) != 1){
|
|
ok = false;
|
|
} else if (newvalue!=*value){
|
|
*value = newvalue;
|
|
}
|
|
break;
|
|
case cSetting_float:
|
|
if(sscanf(st, "%f", &newfvalue) != 1){
|
|
ok = false;
|
|
} else if (newfvalue != *((float *) value)){
|
|
*(float*)value = newfvalue;
|
|
}
|
|
break;
|
|
case cSetting_color:
|
|
{
|
|
int color_index = ColorGetIndex(G, st);
|
|
if (*(value) != color_index){
|
|
*(value) = color_index;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
ok = false;
|
|
break;
|
|
}
|
|
return (ok);
|
|
}
|
|
|
|
int SettingSetFromString(PyMOLGlobals * G, CSetting * I, int index, const char *st)
|
|
{
|
|
int type;
|
|
int ok = true;
|
|
if(!I)
|
|
I = G->Setting; /* fall back on global settings */
|
|
|
|
/* this data structure has been pre-checked at the python level... */
|
|
|
|
type = SettingGetType(G, index);
|
|
|
|
switch (type) {
|
|
case cSetting_boolean:
|
|
if((!*st) || (*st == '0') || (*st == 'F') || WordMatchExact(G, st, "on", true)
|
|
|| WordMatchExact(G, st, "false", true))
|
|
SettingSet_b(I, index, 0);
|
|
else
|
|
SettingSet_b(I, index, 1);
|
|
break;
|
|
case cSetting_int:
|
|
{
|
|
int tmp;
|
|
if(sscanf(st, "%d", &tmp) == 1)
|
|
SettingSet_i(I, index, tmp);
|
|
else
|
|
ok = false;
|
|
}
|
|
break;
|
|
case cSetting_float:
|
|
{
|
|
float tmp;
|
|
if(sscanf(st, "%f", &tmp) == 1)
|
|
SettingSet_f(I, index, tmp);
|
|
else
|
|
ok = false;
|
|
}
|
|
break;
|
|
case cSetting_float3:
|
|
{
|
|
float tmp[3];
|
|
if(sscanf(st, "%f%f%f", tmp, tmp + 1, tmp + 2) == 3)
|
|
SettingSet_3fv(I, index, tmp);
|
|
else
|
|
ok = false;
|
|
}
|
|
break;
|
|
case cSetting_color:
|
|
SettingSet_color(I, index, st);
|
|
break;
|
|
case cSetting_string:
|
|
SettingSet_s(I, index, st);
|
|
break;
|
|
default:
|
|
ok = false;
|
|
break;
|
|
}
|
|
return (ok);
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
#ifndef _PYMOL_NOPY
|
|
/**
|
|
* Warning: Returns colors as (fff) tuple instead of color index
|
|
*
|
|
* @pre GIL
|
|
*/
|
|
PyObject *SettingGetPyObject(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2, int index)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
PyObject *result = nullptr;
|
|
const float *ptr;
|
|
int type = SettingGetType(G, index);
|
|
|
|
switch (type) {
|
|
case cSetting_boolean:
|
|
result = CPythonVal_New_Boolean(SettingGet_b(G, set1, set2, index));
|
|
break;
|
|
case cSetting_int:
|
|
result = CPythonVal_New_Integer(SettingGet_i(G, set1, set2, index));
|
|
break;
|
|
case cSetting_float:
|
|
result = CPythonVal_New_Float(SettingGet_f(G, set1, set2, index));
|
|
break;
|
|
case cSetting_float3:
|
|
ptr = SettingGet_3fv(G, set1, set2, index);
|
|
result = Py_BuildValue("(fff)", pymol::pretty_f2d(ptr[0]),
|
|
pymol::pretty_f2d(ptr[1]), pymol::pretty_f2d(ptr[2]));
|
|
break;
|
|
case cSetting_color:
|
|
{
|
|
int retcol = SettingGet_color(G, set1, set2, index);
|
|
if (retcol > 0){
|
|
const float *col;
|
|
col = ColorGet(G, retcol);
|
|
result = Py_BuildValue("(fff)", col[0], col[1], col[2]);
|
|
}
|
|
}
|
|
break;
|
|
case cSetting_string:
|
|
result = PyString_FromString(SettingGet_s(G, set1, set2, index));
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @pre GIL
|
|
*/
|
|
PyObject *SettingGetTuple(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2, int index)
|
|
{
|
|
assert(PyGILState_Check());
|
|
|
|
PyObject *result = nullptr;
|
|
const float *ptr;
|
|
int type = SettingGetType(G, index);
|
|
|
|
switch (type) {
|
|
case cSetting_boolean:
|
|
case cSetting_int:
|
|
case cSetting_color:
|
|
result = Py_BuildValue("ii", type, SettingGet_i(G, set1, set2, index));
|
|
break;
|
|
case cSetting_float:
|
|
result = Py_BuildValue(
|
|
"if", type, pymol::pretty_f2d(SettingGet_f(G, set1, set2, index)));
|
|
break;
|
|
case cSetting_float3:
|
|
ptr = SettingGet_3fv(G, set1, set2, index);
|
|
result = Py_BuildValue("i(fff)", type, pymol::pretty_f2d(ptr[0]),
|
|
pymol::pretty_f2d(ptr[1]), pymol::pretty_f2d(ptr[2]));
|
|
break;
|
|
case cSetting_string:
|
|
result = Py_BuildValue("is", type, SettingGet_s(G, set1, set2, index));
|
|
break;
|
|
default:
|
|
result = PConvAutoNone(Py_None);
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
|
|
/*========================================================================*/
|
|
CSetting *SettingNew(PyMOLGlobals * G)
|
|
{
|
|
return new CSetting(G);
|
|
}
|
|
|
|
CSetting::CSetting(const CSetting& other)
|
|
{
|
|
*this = other;
|
|
}
|
|
|
|
CSetting& CSetting::operator=(const CSetting& other)
|
|
{
|
|
for (int index = 0; index < cSetting_INIT; ++index) {
|
|
SettingRecCopy(index, other.info[index], this->info[index]);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
/*========================================================================*/
|
|
CSetting::~CSetting()
|
|
{
|
|
// need to free strings
|
|
for (int index = 0; index < cSetting_INIT; ++index) {
|
|
if (SettingInfo[index].type == cSetting_string) {
|
|
info[index].delete_s();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
void SettingFreeP(CSetting * I)
|
|
{
|
|
delete I;
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
CSetting::CSetting(PyMOLGlobals* G)
|
|
: G(G)
|
|
{
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
/**
|
|
* Restore the default value from `src` or `SettingInfo`
|
|
*/
|
|
void SettingRestoreDefault(CSetting * I, int index, const CSetting * src)
|
|
{
|
|
// 1) from stored default if provided
|
|
if (src) {
|
|
SettingRecCopy(index, src->info[index], I->info[index]);
|
|
return;
|
|
}
|
|
|
|
// 2) from SettingInfo
|
|
auto &rec = SettingInfo[index];
|
|
|
|
switch (rec.type) {
|
|
case cSetting_blank:
|
|
break;
|
|
case cSetting_boolean:
|
|
case cSetting_int:
|
|
I->info[index].set_i(rec.value.i[0]);
|
|
break;
|
|
case cSetting_float:
|
|
I->info[index].set_f(rec.value.f[0]);
|
|
break;
|
|
case cSetting_float3:
|
|
I->info[index].set_3f(rec.value.f);
|
|
break;
|
|
case cSetting_string:
|
|
I->info[index].delete_s();
|
|
break;
|
|
case cSetting_color:
|
|
SettingSet_color(I, index, rec.value.s);
|
|
break;
|
|
default:
|
|
// coding error
|
|
printf(" ERROR: unkown type\n");
|
|
};
|
|
|
|
I->info[index].defined = false;
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
int SettingUnset(CSetting * I, int index)
|
|
{
|
|
if(I) {
|
|
SettingRec& sr = I->info[index];
|
|
if (!sr.defined) {
|
|
return false;
|
|
}
|
|
sr.defined = false;
|
|
sr.changed = true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
int SettingGetType(int index)
|
|
{
|
|
return (SettingInfo[index].type);
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
template <>
|
|
int _SettingGet<int>(int index, const CSetting * I)
|
|
{
|
|
PyMOLGlobals *G = I->G;
|
|
int result;
|
|
switch (SettingInfo[index].type) {
|
|
case cSetting_boolean:
|
|
case cSetting_int:
|
|
case cSetting_color:
|
|
result = I->info[index].int_;
|
|
break;
|
|
case cSetting_float:
|
|
result = (int) I->info[index].float_;
|
|
break;
|
|
default:
|
|
PRINTFB(G, FB_Setting, FB_Errors)
|
|
"Setting-Error: type read mismatch (int) %d\n", index ENDFB(G);
|
|
result = 0;
|
|
break;
|
|
}
|
|
return (result);
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
template <>
|
|
bool _SettingGet<bool>(int index, const CSetting * I)
|
|
{
|
|
PyMOLGlobals *G = I->G;
|
|
switch (SettingInfo[index].type) {
|
|
case cSetting_boolean:
|
|
case cSetting_int:
|
|
case cSetting_float:
|
|
return I->info[index].int_ != 0;
|
|
default:
|
|
PRINTFB(G, FB_Setting, FB_Errors)
|
|
"Setting-Error: type read mismatch (boolean) %d\n", index ENDFB(G);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
template <>
|
|
float _SettingGet<float>(int index, const CSetting * I)
|
|
{
|
|
float result;
|
|
PyMOLGlobals *G = I->G;
|
|
switch (SettingInfo[index].type) {
|
|
case cSetting_color:
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
" Setting-Warning: type read mismatch (float/color) %d\n", index ENDFB(G);
|
|
case cSetting_boolean:
|
|
case cSetting_int:
|
|
result = (float) I->info[index].int_;
|
|
break;
|
|
case cSetting_float:
|
|
result = I->info[index].float_;
|
|
break;
|
|
default:
|
|
PRINTFB(G, FB_Setting, FB_Errors)
|
|
"Setting-Error: type read mismatch (float) %d\n", index ENDFB(G);
|
|
result = 0.0F;
|
|
}
|
|
return (result);
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
template <>
|
|
const char * _SettingGet<const char *>(int index, const CSetting * I)
|
|
{
|
|
const char *result;
|
|
PyMOLGlobals *G = I->G;
|
|
switch (SettingInfo[index].type) {
|
|
case cSetting_string:
|
|
if(I->info[index].str_) {
|
|
result = I->info[index].str_->c_str();
|
|
} else {
|
|
result = SettingInfo[index].value.s;
|
|
}
|
|
break;
|
|
default:
|
|
PRINTFB(G, FB_Setting, FB_Errors)
|
|
"Setting-Error: type read mismatch (string) %d\n", index ENDFB(G);
|
|
result = nullptr;
|
|
}
|
|
return (char*) result;
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
template <>
|
|
const float * _SettingGet<const float *>(int index, const CSetting * I)
|
|
{
|
|
if (SettingInfo[index].type != cSetting_float3) {
|
|
PyMOLGlobals *G = I->G;
|
|
PRINTFB(G, FB_Setting, FB_Errors)
|
|
" Setting-Error: type read mismatch (float3) %d\n", index ENDFB(G);
|
|
return nullptr;
|
|
}
|
|
return I->info[index].float3_;
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
int SettingSet_i(CSetting * I, int index, int value)
|
|
{
|
|
int ok = true;
|
|
if(I) {
|
|
PyMOLGlobals *G = I->G;
|
|
{
|
|
int setting_type = SettingInfo[index].type;
|
|
switch (setting_type) {
|
|
case cSetting_boolean:
|
|
case cSetting_int:
|
|
case cSetting_color:
|
|
I->info[index].set_i(value);
|
|
break;
|
|
case cSetting_float:
|
|
I->info[index].set_f((float) value);
|
|
break;
|
|
default:
|
|
PRINTFB(G, FB_Setting, FB_Errors)
|
|
"Setting-Error: type set mismatch (integer) %d\n", index ENDFB(G);
|
|
ok = false;
|
|
}
|
|
}
|
|
} else {
|
|
ok = false;
|
|
}
|
|
return (ok);
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
static int SettingSet_color_from_3f(CSetting * I, int index, const float * vector)
|
|
{
|
|
int color_index;
|
|
float vals[3];
|
|
copy3f(vector, vals);
|
|
clamp3f(vals);
|
|
color_index = Color3fToInt(I->G, vals);
|
|
return SettingSet_i(I, index, color_index);
|
|
}
|
|
|
|
int SettingSet_color(CSetting * I, int index, const char *value)
|
|
{
|
|
int ok = true;
|
|
int color_index;
|
|
if(I) {
|
|
PyMOLGlobals *G = I->G;
|
|
color_index = ColorGetIndex(G, value);
|
|
if((color_index == -1) && (strcmp(value, "-1") &&
|
|
strcmp(value, "-2") &&
|
|
strcmp(value, "-3") &&
|
|
strcmp(value, "-4") &&
|
|
strcmp(value, "-5") && strcmp(value, "default"))) {
|
|
float vals[3];
|
|
ok = ParseFloat3List(value, vals);
|
|
if (ok){
|
|
clamp3f(vals);
|
|
color_index = cColor_TRGB_Bits |
|
|
((int) (255 * vals[0] + 0.49999F)) << 16 |
|
|
((int) (255 * vals[1] + 0.49999F)) << 8 |
|
|
((int) (255 * vals[2] + 0.49999F));
|
|
} else {
|
|
PRINTFB(G, FB_Setting, FB_Errors)
|
|
"Setting-Error: unknown color '%s'\n", value ENDFB(G);
|
|
}
|
|
}
|
|
if (ok){
|
|
SettingSet_i(I, index, color_index);
|
|
}
|
|
}
|
|
return (ok);
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
int SettingSet_f(CSetting * I, int index, float value)
|
|
{
|
|
int ok = true;
|
|
if(I) {
|
|
PyMOLGlobals *G = I->G;
|
|
{
|
|
int setting_type = SettingInfo[index].type;
|
|
switch (setting_type) {
|
|
case cSetting_boolean:
|
|
case cSetting_int:
|
|
case cSetting_color:
|
|
I->info[index].set_i((int) value);
|
|
break;
|
|
case cSetting_float:
|
|
I->info[index].set_f(value);
|
|
break;
|
|
default:
|
|
PRINTFB(G, FB_Setting, FB_Errors)
|
|
"Setting-Error: type set mismatch (float) %d\n", index ENDFB(G);
|
|
ok = false;
|
|
}
|
|
}
|
|
} else {
|
|
ok = false;
|
|
}
|
|
return (ok);
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
int SettingSet_s(CSetting * I, int index, const char *value)
|
|
{
|
|
int ok = true;
|
|
if(I) {
|
|
PyMOLGlobals *G = I->G;
|
|
{
|
|
int setting_type = SettingInfo[index].type;
|
|
switch (setting_type) {
|
|
case cSetting_string:
|
|
I->info[index].set_s(value);
|
|
break;
|
|
case cSetting_color:
|
|
return SettingSet_color(I, index, value);
|
|
default:
|
|
PRINTFB(G, FB_Setting, FB_Errors)
|
|
"Setting-Error: type set mismatch (string) %d\n", index ENDFB(G);
|
|
ok = false;
|
|
}
|
|
}
|
|
} else {
|
|
ok = false;
|
|
}
|
|
return (ok);
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
int SettingSet_3fv(CSetting * I, int index, const float *vector)
|
|
{
|
|
switch (SettingInfo[index].type) {
|
|
case cSetting_float3:
|
|
I->info[index].set_3f(vector);
|
|
return true;
|
|
case cSetting_color:
|
|
return SettingSet_color_from_3f(I, index, vector);
|
|
default:
|
|
PyMOLGlobals *G = I->G;
|
|
PRINTFB(G, FB_Setting, FB_Errors)
|
|
"Setting-Error: type set mismatch (float3) %d\n", index ENDFB(G);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
int SettingGetIndex(PyMOLGlobals * G, const char *name)
|
|
{
|
|
if (auto result = get_setting_id(G->PyMOL, name)) {
|
|
return *result;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
int SettingGetName(PyMOLGlobals * G, int index, SettingName name)
|
|
{
|
|
UtilNCopy(name, SettingInfo[index].name, sizeof(SettingName));
|
|
return (name[0] != 0);
|
|
}
|
|
|
|
/*========================================================================*/
|
|
const char * SettingGetName(int index)
|
|
{
|
|
return SettingInfo[index].name;
|
|
}
|
|
|
|
/*========================================================================*/
|
|
void SettingGenerateSideEffects(PyMOLGlobals * G, int index, const char *sele, int state, int quiet)
|
|
{
|
|
const char *inv_sele = (sele && sele[0]) ? sele : cKeywordAll;
|
|
auto &rec = SettingInfo[index];
|
|
|
|
if (rec.level == cSettingLevel_unused) {
|
|
const char * name = rec.name;
|
|
|
|
if (!quiet && name && name[0]){
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
" Setting-Warning: '%s' is no longer used\n", name
|
|
ENDFB(G);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// range check for int (global only)
|
|
if (rec.type == cSetting_int && rec.hasMinMax() && !(sele && sele[0])) {
|
|
int value = SettingGetGlobal_i(G, index);
|
|
bool clamped = true;
|
|
|
|
if (value < rec.value.i[1]) {
|
|
value = rec.value.i[1];
|
|
} else if (value > rec.value.i[2]) {
|
|
value = rec.value.i[2];
|
|
} else {
|
|
clamped = false;
|
|
}
|
|
|
|
if (clamped) {
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
" Setting-Warning: %s range = [%d,%d]; setting to %d.\n",
|
|
rec.name, rec.value.i[1], rec.value.i[2], value ENDFB(G);
|
|
SettingSetGlobal_i(G, index, value);
|
|
}
|
|
}
|
|
|
|
switch (index) {
|
|
case cSetting_stereo:
|
|
SceneUpdateStereo(G);
|
|
G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
|
|
break;
|
|
case cSetting_pick_surface:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders)){
|
|
SceneInvalidatePicking(G); // right now, when pick_surface is off, wipes each CGO's pickColor array
|
|
}
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvColor);
|
|
break;
|
|
case cSetting_pickable:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepAll, cRepInvAll);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_grid_mode:
|
|
if (!SettingGetGlobal_i(G, cSetting_grid_mode))
|
|
G->ShaderMgr->ResetUniformSet();
|
|
ExecutiveUpdateSceneMembers(G);
|
|
case cSetting_grid_slot:
|
|
ExecutiveInvalidateGroups(G, false);
|
|
ExecutiveUpdateSceneMembers(G);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_grid_max:
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_defer_builds_mode:
|
|
ExecutiveRebuildAll(G);
|
|
break;
|
|
case cSetting_seq_view:
|
|
case cSetting_seq_view_label_spacing:
|
|
case cSetting_seq_view_label_mode:
|
|
case cSetting_seq_view_label_start:
|
|
case cSetting_seq_view_format:
|
|
case cSetting_seq_view_color:
|
|
case cSetting_seq_view_unaligned_mode:
|
|
case cSetting_seq_view_gap_mode:
|
|
SeqChanged(G);
|
|
break;
|
|
case cSetting_seq_view_fill_color:
|
|
case cSetting_seq_view_fill_char:
|
|
case cSetting_seq_view_label_color:
|
|
OrthoDirty(G);
|
|
break;
|
|
case cSetting_show_frame_rate:
|
|
OrthoDirty(G);
|
|
break;
|
|
case cSetting_group_full_member_names:
|
|
case cSetting_group_arrow_prefix:
|
|
OrthoDirty(G);
|
|
break;
|
|
case cSetting_static_singletons:
|
|
SeqChanged(G);
|
|
break;
|
|
case cSetting_seq_view_location:
|
|
PParse(G, "cmd.viewport(-1,-1)");
|
|
SeqChanged(G);
|
|
break;
|
|
case cSetting_seq_view_overlay:
|
|
PParse(G, "cmd.viewport(-1,-1)");
|
|
break;
|
|
case cSetting_stereo_mode:
|
|
case cSetting_anaglyph_mode:
|
|
G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
|
|
SceneUpdateStereoMode(G);
|
|
OrthoInvalidateDoDraw(G);
|
|
OrthoDirty(G);
|
|
PyMOL_NeedRedisplay(G->PyMOL);
|
|
break;
|
|
case cSetting_precomputed_lighting:
|
|
G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
|
|
case cSetting_light_count:
|
|
case cSetting_spec_count:
|
|
G->ShaderMgr->Set_Reload_Bits(RELOAD_CALLCOMPUTELIGHTING);
|
|
case cSetting_dot_lighting:
|
|
case cSetting_mesh_lighting:
|
|
case cSetting_cgo_lighting:
|
|
case cSetting_field_of_view:
|
|
case cSetting_fog_start:
|
|
case cSetting_two_sided_lighting:
|
|
case cSetting_transparency_global_sort:
|
|
case cSetting_dot_normals:
|
|
case cSetting_mesh_normals:
|
|
SceneInvalidate(G);
|
|
break;
|
|
case cSetting_spec_power:
|
|
if (!quiet){
|
|
PRINTFB(G, FB_Setting, FB_Debugging)
|
|
"Setting-Details: spec_power is depreciated in PyMOL 1.5. This option will not work in future versions. Please set shininess to set the specular exponent for movable light sources.\n"
|
|
ENDFB(G);
|
|
}
|
|
SceneInvalidate(G);
|
|
break;
|
|
case cSetting_light:
|
|
case cSetting_light2:
|
|
case cSetting_light3:
|
|
case cSetting_light4:
|
|
case cSetting_light5:
|
|
case cSetting_light6:
|
|
case cSetting_light7:
|
|
case cSetting_reflect:
|
|
case cSetting_direct:
|
|
case cSetting_ambient:
|
|
case cSetting_specular:
|
|
case cSetting_specular_intensity:
|
|
case cSetting_shininess:
|
|
case cSetting_spec_reflect:
|
|
case cSetting_spec_direct:
|
|
case cSetting_spec_direct_power:
|
|
case cSetting_power:
|
|
case cSetting_reflect_power:
|
|
if (SettingGetGlobal_b(G, cSetting_precomputed_lighting))
|
|
G->ShaderMgr->Set_Reload_Bits(RELOAD_CALLCOMPUTELIGHTING);
|
|
SceneInvalidate(G);
|
|
break;
|
|
case cSetting_use_display_lists:
|
|
case cSetting_simplify_display_lists:
|
|
case cSetting_excl_display_lists_shaders:
|
|
if (!quiet){
|
|
PRINTFB(G, FB_Setting, FB_Debugging)
|
|
"Setting-Details: display lists were depreciated in PyMOL 1.7.x. The settings use_display_lists, simplify_display_lists, and excl_display_lists_shaders no longer work.\n"
|
|
ENDFB(G);
|
|
}
|
|
case cSetting_use_geometry_shaders:
|
|
if (SettingGetGlobal_i(G, cSetting_use_geometry_shaders) &&
|
|
G->ShaderMgr->IsConfigured() && !G->ShaderMgr->GeometryShadersPresent()) {
|
|
SettingSet_b(G->Setting, cSetting_use_geometry_shaders, 0);
|
|
if (!quiet){
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
"Setting-Error: geometry shaders not available\n" ENDFB(G);
|
|
}
|
|
return;
|
|
}
|
|
|
|
G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepLabel, cRepInvRep);
|
|
{
|
|
// check if lines need to be invalidated
|
|
bool line_as_cylinders = SettingGetGlobal_b(G, cSetting_use_shaders) &&
|
|
SettingGetGlobal_b(G, cSetting_render_as_cylinders) &&
|
|
SettingGetGlobal_b(G, cSetting_line_as_cylinders);
|
|
if (!line_as_cylinders && !SettingGetGlobal_b(G, cSetting_trilines)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
|
|
}
|
|
}
|
|
break;
|
|
case cSetting_shaders_from_disk:
|
|
G->ShaderMgr->Set_Reload_Bits(RELOAD_ALL_SHADERS);
|
|
SceneInvalidate(G);
|
|
break;
|
|
case cSetting_use_shaders:
|
|
{
|
|
short changed = 0;
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders)){
|
|
if (SettingCheckUseShaders(G->Setting, quiet)){
|
|
return;
|
|
}
|
|
}
|
|
SceneInvalidate(G);
|
|
if (SettingGetGlobal_b(G, cSetting_sphere_use_shader)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
|
|
changed = 1;
|
|
}
|
|
if (SettingGetGlobal_b(G, cSetting_ribbon_use_shader)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
|
|
changed = 1;
|
|
}
|
|
if (SettingGetGlobal_b(G, cSetting_nonbonded_use_shader)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepNonbonded, cRepInvRep);
|
|
changed = 1;
|
|
}
|
|
if (SettingGetGlobal_i(G, cSetting_nb_spheres_use_shader)){
|
|
changed = 1;
|
|
}
|
|
if (SettingGetGlobal_b(G, cSetting_dash_use_shader)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepAngle, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepDihedral, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepDash, cRepInvRep);
|
|
changed = 1;
|
|
}
|
|
if (SettingGetGlobal_b(G, cSetting_line_use_shader)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
|
|
changed = 1;
|
|
}
|
|
if (SettingGetGlobal_b(G, cSetting_cartoon_use_shader)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
|
|
changed = 1;
|
|
}
|
|
if (SettingGetGlobal_b(G, cSetting_cgo_use_shader) ||
|
|
SettingGetGlobal_b(G, cSetting_stick_as_cylinders)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvRep);
|
|
changed = 1;
|
|
}
|
|
if (SettingGetGlobal_b(G, cSetting_stick_use_shader) ||
|
|
SettingGetGlobal_b(G, cSetting_stick_as_cylinders) ||
|
|
(SettingGetGlobal_b(G, cSetting_stick_ball) &&
|
|
SettingGetGlobal_b(G, cSetting_valence))){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
|
|
changed = 1;
|
|
}
|
|
if (SettingGetGlobal_b(G, cSetting_surface_use_shader) ||
|
|
SettingGetGlobal_b(G, cSetting_dot_use_shader) ||
|
|
SettingGetGlobal_b(G, cSetting_mesh_use_shader)){
|
|
changed = 1;
|
|
}
|
|
if (changed){
|
|
SceneChanged(G);
|
|
}
|
|
}
|
|
break;
|
|
case cSetting_stereo_shift:
|
|
case cSetting_stereo_angle:
|
|
case cSetting_stereo_dynamic_strength:
|
|
SceneInvalidate(G);
|
|
break;
|
|
case cSetting_scene_buttons:
|
|
case cSetting_scene_buttons_mode:
|
|
SceneInvalidate(G);
|
|
OrthoInvalidateDoDraw(G);
|
|
break;
|
|
case cSetting_dash_round_ends:
|
|
case cSetting_dash_color:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_dash_use_shader)){
|
|
ExecutiveInvalidateRep(G, "all", cRepDash, cRepInvRep);
|
|
}
|
|
SceneInvalidate(G);
|
|
break;
|
|
case cSetting_angle_color:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_dash_use_shader)){
|
|
ExecutiveInvalidateRep(G, "all", cRepAngle, cRepInvRep);
|
|
}
|
|
SceneInvalidate(G);
|
|
break;
|
|
case cSetting_dihedral_color:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_dash_use_shader)){
|
|
ExecutiveInvalidateRep(G, "all", cRepDihedral, cRepInvRep);
|
|
}
|
|
SceneInvalidate(G);
|
|
break;
|
|
case cSetting_mouse_selection_mode:
|
|
OrthoDirty(G);
|
|
break;
|
|
case cSetting_internal_gui_control_size:
|
|
WizardRefresh(G);
|
|
OrthoDirty(G);
|
|
break;
|
|
case cSetting_hide_underscore_names:
|
|
ExecutiveInvalidateGroups(G, false);
|
|
OrthoDirty(G);
|
|
break;
|
|
case cSetting_gradient_spacing:
|
|
case cSetting_gradient_max_length:
|
|
case cSetting_gradient_min_length:
|
|
case cSetting_gradient_normal_min_dot:
|
|
case cSetting_gradient_step_size:
|
|
case cSetting_gradient_min_slope:
|
|
case cSetting_gradient_symmetry:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_min_mesh_spacing:
|
|
case cSetting_mesh_grid_max:
|
|
case cSetting_mesh_cutoff:
|
|
case cSetting_mesh_carve_state:
|
|
case cSetting_mesh_carve_cutoff:
|
|
case cSetting_mesh_carve_selection:
|
|
case cSetting_mesh_clear_state:
|
|
case cSetting_mesh_clear_cutoff:
|
|
case cSetting_mesh_clear_selection:
|
|
case cSetting_mesh_mode:
|
|
case cSetting_mesh_type:
|
|
case cSetting_mesh_solvent:
|
|
case cSetting_mesh_quality:
|
|
case cSetting_mesh_skip:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_valence:
|
|
case cSetting_valence_mode:
|
|
case cSetting_valence_size:
|
|
case cSetting_valence_zero_mode:
|
|
case cSetting_valence_zero_scale:
|
|
case cSetting_half_bonds:
|
|
case cSetting_line_stick_helper:
|
|
case cSetting_hide_long_bonds:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_stick_transparency:
|
|
case cSetting_stick_debug:
|
|
case cSetting_stick_round_nub:
|
|
case cSetting_stick_as_cylinders:
|
|
case cSetting_stick_good_geometry:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_line_use_shader:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
|
|
SceneChanged(G);
|
|
}
|
|
break;
|
|
case cSetting_ribbon_use_shader:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
|
|
SceneChanged(G);
|
|
}
|
|
break;
|
|
case cSetting_dot_as_spheres:
|
|
SceneInvalidate(G);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_dot_use_shader:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepDot, cRepInvRep);
|
|
SceneChanged(G);
|
|
}
|
|
break;
|
|
case cSetting_nonbonded_use_shader:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepNonbonded, cRepInvRep);
|
|
SceneChanged(G);
|
|
}
|
|
break;
|
|
case cSetting_nb_spheres_size:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepNonbondedSphere, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_nb_spheres_use_shader:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders)){
|
|
SceneChanged(G);
|
|
}
|
|
break;
|
|
case cSetting_render_as_cylinders:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
|
|
case cSetting_mesh_as_cylinders:
|
|
case cSetting_line_as_cylinders:
|
|
case cSetting_ribbon_as_cylinders:
|
|
case cSetting_dash_as_cylinders:
|
|
if (index == cSetting_dash_as_cylinders) {
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepAngle, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepDihedral, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepDash, cRepInvRep);
|
|
}
|
|
case cSetting_nonbonded_as_cylinders:
|
|
case cSetting_alignment_as_cylinders:
|
|
case cSetting_cartoon_nucleic_acid_as_cylinders:
|
|
if (SettingGetGlobal_b(G, cSetting_render_as_cylinders)){
|
|
if (G->ShaderMgr->shaders_present && !G->ShaderMgr->ShaderPrgExists("cylinder")){
|
|
SettingSet_b(G->Setting, cSetting_render_as_cylinders, 0);
|
|
if (!quiet){
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
"Setting-Error: render_as_cylinders cannot be set when the Cylinder Shader is not available, setting render_as_cylinder back to false\n"
|
|
ENDFB(G);
|
|
}
|
|
return;
|
|
}
|
|
switch (index){
|
|
case cSetting_render_as_cylinders:
|
|
case cSetting_cartoon_nucleic_acid_as_cylinders:
|
|
case cSetting_use_shaders:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_render_as_cylinders)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
|
|
}
|
|
}
|
|
SceneChanged(G);
|
|
}
|
|
break;
|
|
case cSetting_mesh_use_shader:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders)){
|
|
SceneChanged(G);
|
|
}
|
|
break;
|
|
case cSetting_slice_height_scale:
|
|
case cSetting_slice_height_map:
|
|
case cSetting_slice_grid:
|
|
case cSetting_slice_dynamic_grid:
|
|
case cSetting_slice_dynamic_grid_resolution:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSlice, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_label_font_id:
|
|
case cSetting_label_size:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepLabel, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_retain_order:
|
|
case cSetting_pdb_hetatm_sort:
|
|
case cSetting_pdb_insertions_go_first:
|
|
ExecutiveSort(G, inv_sele);
|
|
break;
|
|
case cSetting_roving_lines:
|
|
case cSetting_roving_sticks:
|
|
case cSetting_roving_spheres:
|
|
case cSetting_roving_labels:
|
|
case cSetting_roving_selection:
|
|
case cSetting_roving_ribbon:
|
|
case cSetting_roving_cartoon:
|
|
case cSetting_roving_polar_contacts:
|
|
case cSetting_roving_polar_cutoff:
|
|
case cSetting_roving_nonbonded:
|
|
case cSetting_roving_nb_spheres:
|
|
case cSetting_roving_map1_level:
|
|
case cSetting_roving_map2_level:
|
|
case cSetting_roving_map3_level:
|
|
case cSetting_roving_map1_name:
|
|
case cSetting_roving_map2_name:
|
|
case cSetting_roving_map3_name:
|
|
case cSetting_roving_isosurface:
|
|
case cSetting_roving_isomesh:
|
|
SceneRovingChanged(G);
|
|
break;
|
|
case cSetting_roving_byres:
|
|
case cSetting_roving_detail:
|
|
SceneRovingDirty(G);
|
|
break;
|
|
case cSetting_dash_transparency:
|
|
case cSetting_dash_length:
|
|
case cSetting_dash_gap:
|
|
case cSetting_dash_radius:
|
|
case cSetting_dash_width:
|
|
case cSetting_angle_size:
|
|
case cSetting_label_digits:
|
|
case cSetting_label_distance_digits:
|
|
case cSetting_label_angle_digits:
|
|
case cSetting_label_dihedral_digits:
|
|
case cSetting_angle_label_position:
|
|
case cSetting_dihedral_size:
|
|
case cSetting_dihedral_label_position:
|
|
ExecutiveRebuildAllObjectDist(G);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_button_mode:
|
|
EditorMouseInvalid(G);
|
|
OrthoDirty(G);
|
|
break;
|
|
case cSetting_stick_radius:
|
|
case cSetting_stick_h_scale:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep); /* base width */
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_nb_spheres_quality:
|
|
{
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepNonbondedSphere, cRepInvRep);
|
|
SceneChanged(G);
|
|
}
|
|
case cSetting_cgo_sphere_quality:
|
|
case cSetting_cgo_debug:
|
|
{
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
}
|
|
case cSetting_stick_quality:
|
|
case cSetting_stick_ball:
|
|
case cSetting_stick_nub:
|
|
case cSetting_stick_ball_ratio:
|
|
case cSetting_stick_ball_color:
|
|
case cSetting_stick_fixed_radius:
|
|
case cSetting_stick_valence_scale:
|
|
case cSetting_stick_overlap:
|
|
case cSetting_stick_color:
|
|
case cSetting_stick_use_shader:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_clamp_colors:
|
|
case cSetting_ramp_blend_nearby_colors:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepAll, cRepInvColor);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_label_color:
|
|
case cSetting_label_outline_color:
|
|
case cSetting_label_position:
|
|
ExecutiveRebuildAllObjectDist(G);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepLabel, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_cartoon_color:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_ribbon_color:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_cgo_line_width:
|
|
case cSetting_line_width:
|
|
{
|
|
GLfloat *range = G->ShaderMgr->GetLineWidthRange();
|
|
float line_width = SettingGetGlobal_f(G, index);
|
|
{
|
|
if (line_width <= 0.f){
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
" Setting-Warning: %s is set incorrectly (%f), setting to 1\n",
|
|
rec.name, line_width ENDFB(G);
|
|
SettingSetGlobal_f(G, index, 1.f);
|
|
} else if (G->HaveGUI && range[1] > 0.f && line_width > range[1]) {
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
" Setting-Warning: %s is out of range of the graphics card's "
|
|
"capability (range: %f-%f), lines might not be rendered correctly\n",
|
|
rec.name, range[0], range[1] ENDFB(G);
|
|
}
|
|
}
|
|
}
|
|
case cSetting_line_color:
|
|
case cSetting_line_radius:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepNonbonded, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_scenes_changed:
|
|
{
|
|
int scene_buttons = SettingGetGlobal_i(G, cSetting_scene_buttons);
|
|
if (scene_buttons)
|
|
OrthoInvalidateDoDraw(G);
|
|
}
|
|
break;
|
|
case cSetting_button_mode_name:
|
|
{
|
|
auto internal_gui_mode = SettingGet<InternalGUIMode>(cSetting_internal_gui_mode, G->Setting);
|
|
if (internal_gui_mode != InternalGUIMode::Default){
|
|
OrthoInvalidateDoDraw(G);
|
|
}
|
|
}
|
|
break;
|
|
case cSetting_scene_current_name:
|
|
SceneRestartFrameTimer(G);
|
|
break;
|
|
case cSetting_mesh_width:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvColor);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_ellipsoid_probability:
|
|
case cSetting_ellipsoid_scale:
|
|
case cSetting_ellipsoid_color:
|
|
case cSetting_ellipsoid_transparency:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepEllipsoid, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_ellipsoid_quality:
|
|
case cSetting_cgo_ellipsoid_quality:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepEllipsoid, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_mesh_color:
|
|
case cSetting_mesh_negative_color:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvColor);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_ray_color_ramps:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepAll, cRepInvColor);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_sphere_mode:
|
|
#ifndef _PYMOL_IP_EXTRAS
|
|
if (SettingGet<int>(G, cSetting_sphere_mode) > 9) {
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
" Setting-Warning: sphere_mode > 9 is not supported in Open-Source "
|
|
"version of PyMOL\n" ENDFB(G);
|
|
}
|
|
#endif
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
|
|
SceneInvalidate(G);
|
|
break;
|
|
case cSetting_cell_color:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCell, cRepInvColor);
|
|
SceneInvalidate(G);
|
|
case cSetting_cull_spheres:
|
|
case cSetting_sphere_scale:
|
|
case cSetting_sphere_transparency:
|
|
case cSetting_sphere_solvent:
|
|
case cSetting_sphere_point_max_size:
|
|
case cSetting_sphere_point_size:
|
|
case cSetting_sphere_use_shader:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
|
|
SceneInvalidate(G);
|
|
break;
|
|
case cSetting_sphere_quality:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepNonbondedSphere, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_nonbonded_size:
|
|
case cSetting_nonbonded_transparency:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepNonbonded, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepNonbondedSphere, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_mesh_radius:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvColor);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_ambient_occlusion_scale:
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_ambient_occlusion_mode:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvColor);
|
|
switch (SettingGetGlobal_i(G, cSetting_ambient_occlusion_mode) % 4){
|
|
case 1:
|
|
SettingSetGlobal_i(G, cSetting_ambient_occlusion_smooth, 10);
|
|
SettingSetGlobal_f(G, cSetting_ambient_occlusion_scale, 25.f);
|
|
break;
|
|
case 2:
|
|
SettingSetGlobal_i(G, cSetting_ambient_occlusion_smooth, 5);
|
|
SettingSetGlobal_f(G, cSetting_ambient_occlusion_scale, .9f);
|
|
break;
|
|
case 3:
|
|
SettingSetGlobal_i(G, cSetting_ambient_occlusion_smooth, 5);
|
|
SettingSetGlobal_f(G, cSetting_ambient_occlusion_scale, 1.1f);
|
|
break;
|
|
}
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_ambient_occlusion_smooth:
|
|
case cSetting_surface_negative_color:
|
|
case cSetting_surface_color:
|
|
case cSetting_surface_ramp_above_mode:
|
|
case cSetting_transparency:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvColor);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_dot_color:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepDot, cRepInvColor);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_sphere_color:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvColor);
|
|
SceneChanged(G);
|
|
break;
|
|
|
|
case cSetting_surface_quality:
|
|
case cSetting_surface_mode:
|
|
case cSetting_surface_normal:
|
|
case cSetting_surface_type:
|
|
case cSetting_surface_carve_state:
|
|
case cSetting_surface_carve_cutoff:
|
|
case cSetting_surface_carve_selection:
|
|
case cSetting_surface_carve_normal_cutoff:
|
|
case cSetting_surface_clear_state:
|
|
case cSetting_surface_clear_cutoff:
|
|
case cSetting_surface_clear_selection:
|
|
case cSetting_surface_trim_cutoff:
|
|
case cSetting_surface_trim_factor:
|
|
case cSetting_surface_circumscribe:
|
|
case cSetting_surface_solvent:
|
|
case cSetting_surface_proximity:
|
|
case cSetting_surface_cavity_mode:
|
|
case cSetting_surface_cavity_radius:
|
|
case cSetting_surface_cavity_cutoff:
|
|
case cSetting_cavity_cull:
|
|
case cSetting_surface_smooth_edges:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_surface_use_shader:
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_isosurface_algorithm:
|
|
case cSetting_surface_negative_visible:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_mesh_negative_visible:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvAll);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_solvent_radius:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepDot, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_trace_atoms_mode:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_ribbon_smooth:
|
|
case cSetting_ribbon_power:
|
|
case cSetting_ribbon_power_b:
|
|
case cSetting_ribbon_sampling:
|
|
case cSetting_ribbon_radius:
|
|
case cSetting_ribbon_width:
|
|
case cSetting_ribbon_throw:
|
|
case cSetting_ribbon_trace_atoms:
|
|
case cSetting_ribbon_transparency:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_draw_mode:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
|
|
break;
|
|
case cSetting_cartoon_side_chain_helper:
|
|
case cSetting_cartoon_nucleic_acid_mode:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepEllipsoid, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_ribbon_side_chain_helper:
|
|
case cSetting_ribbon_nucleic_acid_mode:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepEllipsoid, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_ray_trace_mode: /* affects loop quality */
|
|
G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
|
|
case cSetting_cartoon_transparency:
|
|
case cSetting_cartoon_ring_transparency:
|
|
case cSetting_cartoon_trace_atoms:
|
|
case cSetting_cartoon_refine:
|
|
case cSetting_cartoon_nucleic_acid_color:
|
|
case cSetting_cartoon_ring_mode:
|
|
case cSetting_cartoon_ring_finder:
|
|
case cSetting_cartoon_ring_width:
|
|
case cSetting_cartoon_ring_color:
|
|
case cSetting_cartoon_ladder_mode:
|
|
case cSetting_cartoon_ladder_radius:
|
|
case cSetting_cartoon_ladder_color:
|
|
case cSetting_cartoon_sampling:
|
|
case cSetting_cartoon_loop_quality:
|
|
case cSetting_cartoon_loop_radius:
|
|
case cSetting_cartoon_loop_cap:
|
|
case cSetting_cartoon_tube_quality:
|
|
case cSetting_cartoon_tube_radius:
|
|
case cSetting_cartoon_tube_cap:
|
|
case cSetting_cartoon_putty_quality:
|
|
case cSetting_cartoon_putty_radius:
|
|
case cSetting_cartoon_putty_range:
|
|
case cSetting_cartoon_putty_scale_min:
|
|
case cSetting_cartoon_putty_scale_max:
|
|
case cSetting_cartoon_putty_scale_power:
|
|
case cSetting_cartoon_putty_transform:
|
|
case cSetting_cartoon_power:
|
|
case cSetting_cartoon_power_b:
|
|
case cSetting_cartoon_ring_radius:
|
|
case cSetting_cartoon_rect_length:
|
|
case cSetting_cartoon_rect_width:
|
|
case cSetting_cartoon_oval_length:
|
|
case cSetting_cartoon_oval_width:
|
|
case cSetting_cartoon_oval_quality:
|
|
case cSetting_cartoon_round_helices:
|
|
case cSetting_cartoon_flat_sheets:
|
|
case cSetting_cartoon_refine_normals:
|
|
case cSetting_cartoon_smooth_cylinder_cycles:
|
|
case cSetting_cartoon_smooth_cylinder_window:
|
|
case cSetting_cartoon_smooth_loops:
|
|
case cSetting_cartoon_dumbbell_width:
|
|
case cSetting_cartoon_dumbbell_length:
|
|
case cSetting_cartoon_dumbbell_radius:
|
|
case cSetting_cartoon_fancy_helices:
|
|
case cSetting_cartoon_fancy_sheets:
|
|
case cSetting_cartoon_cylindrical_helices:
|
|
case cSetting_cartoon_refine_tips:
|
|
case cSetting_cartoon_helix_radius:
|
|
case cSetting_cartoon_throw:
|
|
case cSetting_cartoon_debug:
|
|
case cSetting_cartoon_highlight_color:
|
|
case cSetting_cartoon_discrete_colors:
|
|
case cSetting_cartoon_smooth_first:
|
|
case cSetting_cartoon_smooth_last:
|
|
case cSetting_cartoon_smooth_cycles:
|
|
case cSetting_cartoon_flat_cycles:
|
|
case cSetting_cartoon_gap_cutoff:
|
|
case cSetting_cartoon_all_alt:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_cartoon_use_shader:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
|
|
SceneChanged(G);
|
|
}
|
|
break;
|
|
case cSetting_cgo_use_shader:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvRep);
|
|
SceneChanged(G);
|
|
}
|
|
break;
|
|
case cSetting_cgo_shader_ub_flags:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_cgo_use_shader)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
|
|
SceneChanged(G);
|
|
}
|
|
break;
|
|
case cSetting_cgo_shader_ub_color:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_cgo_use_shader)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
|
|
SceneChanged(G);
|
|
}
|
|
break;
|
|
case cSetting_cgo_shader_ub_normal:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_cgo_use_shader)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
|
|
// if spheres rendered with geometry, then normals are used
|
|
// this should really only invalidate spheres that use normals (sphere_mode=0, not sure about other modes)
|
|
// but invalidating all spheres for now
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
|
|
SceneChanged(G);
|
|
}
|
|
break;
|
|
case cSetting_trilines:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepDash, cRepInvRep);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepNonbonded, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_cell_centered:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCell, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_dot_width:
|
|
case cSetting_dot_radius:
|
|
case cSetting_dot_density:
|
|
case cSetting_dot_mode:
|
|
case cSetting_dot_solvent:
|
|
case cSetting_dot_hydrogens:
|
|
case cSetting_trim_dots:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepDot, cRepInvRep);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_bg_gradient:
|
|
ColorUpdateFrontFromSettings(G);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepAll, cRepInvColor);
|
|
OrthoBackgroundTextureNeedsUpdate(G);
|
|
G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_bg_image_mode:
|
|
case cSetting_bg_image_filename:
|
|
G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
|
|
case cSetting_bg_image_linear:
|
|
case cSetting_bg_image_tilesize:
|
|
OrthoBackgroundTextureNeedsUpdate(G);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_bg_rgb_top:
|
|
case cSetting_bg_rgb_bottom:
|
|
{
|
|
/* clamp this value */
|
|
const char * bg_image_filename = SettingGet_s(G, nullptr, nullptr, cSetting_bg_image_filename);
|
|
if(!(bg_image_filename && bg_image_filename[0]) &&
|
|
SettingGetGlobal_b(G, cSetting_bg_gradient) && !OrthoBackgroundDataIsSet(*G->Ortho)) {
|
|
ColorUpdateFrontFromSettings(G);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepAll, cRepInvColor);
|
|
OrthoBackgroundTextureNeedsUpdate(G);
|
|
}
|
|
}
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_bg_rgb:
|
|
{
|
|
/* clamp this value */
|
|
const float *v = ColorGet(G, SettingGet_color(G, nullptr, nullptr, cSetting_bg_rgb));
|
|
{
|
|
const char * bg_image_filename = SettingGet_s(G, nullptr, nullptr, cSetting_bg_image_filename);
|
|
if(!(bg_image_filename && bg_image_filename[0]) && !OrthoBackgroundDataIsSet(*G->Ortho)) {
|
|
ColorUpdateFront(G, v);
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepAll, cRepInvColor);
|
|
}
|
|
}
|
|
}
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_selection_width:
|
|
case cSetting_selection_width_scale:
|
|
case cSetting_selection_width_max:
|
|
case cSetting_selection_round_points:
|
|
ExecutiveInvalidateSelectionIndicatorsCGO(G);
|
|
case cSetting_line_smooth:
|
|
case cSetting_ortho:
|
|
case cSetting_chromadepth:
|
|
case cSetting_transparency_mode:
|
|
if (index == cSetting_transparency_mode)
|
|
#ifdef _WEBGL
|
|
#endif
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvAll);
|
|
case cSetting_depth_cue:
|
|
case cSetting_fog:
|
|
case cSetting_ray_transparency_oblique:
|
|
G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
|
|
case cSetting_ray_transparency_oblique_power:
|
|
SceneInvalidate(G);
|
|
break;
|
|
case cSetting_sculpting:
|
|
OrthoDirty(G);
|
|
break;
|
|
case cSetting_auto_overlay:
|
|
OrthoRemoveAutoOverlay(G); /* always start clean */
|
|
break;
|
|
case cSetting_overlay:
|
|
case cSetting_overlay_lines:
|
|
case cSetting_text:
|
|
OrthoDirty(G);
|
|
break;
|
|
case cSetting_internal_gui_mode:
|
|
case cSetting_internal_gui_width:
|
|
case cSetting_internal_gui:
|
|
case cSetting_internal_feedback:
|
|
case cSetting_mouse_grid:
|
|
case cSetting_movie_panel_row_height:
|
|
case cSetting_movie_panel:
|
|
if(!SettingGetGlobal_b(G, cSetting_suspend_updates)) {
|
|
OrthoCommandIn(G, "viewport");
|
|
}
|
|
break;
|
|
case cSetting_suspend_updates:
|
|
if(!SettingGetGlobal_b(G, cSetting_suspend_updates)) {
|
|
SceneChanged(G); /* force big update upon resumption */
|
|
OrthoDirty(G);
|
|
}
|
|
break;
|
|
case cSetting_security:
|
|
G->Security = SettingGetGlobal_i(G, cSetting_security);
|
|
break;
|
|
case cSetting_state:
|
|
if (SettingGet<int>(G, index) < 0 /* all */) {
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
" Setting-Warning: state can't be less than 0.\n" ENDFB(G);
|
|
}
|
|
case cSetting_all_states:
|
|
case cSetting_frame:
|
|
ExecutiveInvalidateSelectionIndicatorsCGO(G);
|
|
SceneInvalidatePicking(G);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_dynamic_width:
|
|
case cSetting_dynamic_width_factor:
|
|
case cSetting_dynamic_width_min:
|
|
case cSetting_dynamic_width_max:
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_rock:
|
|
case cSetting_sweep_mode:
|
|
case cSetting_sweep_phase:
|
|
case cSetting_sweep_angle:
|
|
case cSetting_sweep_speed:
|
|
SceneRestartSweepTimer(G);
|
|
break;
|
|
case cSetting_motion_power:
|
|
case cSetting_motion_bias:
|
|
case cSetting_motion_simple:
|
|
case cSetting_motion_linear:
|
|
case cSetting_motion_hand:
|
|
case cSetting_movie_loop:
|
|
if(SettingGetGlobal_b(G, cSetting_movie_auto_interpolate)) {
|
|
ExecutiveMotionReinterpolate(G);
|
|
}
|
|
break;
|
|
case cSetting_volume_bit_depth:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepVolume, cRepInvAll);
|
|
SceneInvalidate(G);
|
|
break;
|
|
case cSetting_volume_layers:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepVolume, cRepInvColor);
|
|
SceneInvalidate(G);
|
|
break;
|
|
case cSetting_cgo_transparency:
|
|
SceneInvalidate(G);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_label_connector_mode:
|
|
{
|
|
int lc_mode = SettingGetGlobal_i(G, cSetting_label_connector_mode);
|
|
if(lc_mode < 0 || lc_mode > 4){
|
|
if (!quiet){
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
"Setting-Warning: label_connector_mode range = [0,4]"
|
|
ENDFB(G);
|
|
}
|
|
}
|
|
}
|
|
case cSetting_float_labels:
|
|
case cSetting_label_z_target:
|
|
case cSetting_label_connector:
|
|
case cSetting_label_connector_color:
|
|
case cSetting_label_connector_width:
|
|
case cSetting_label_connector_ext_length:
|
|
case cSetting_label_bg_color:
|
|
case cSetting_label_placement_offset:
|
|
case cSetting_label_relative_mode:
|
|
case cSetting_label_screen_point:
|
|
case cSetting_label_multiline_spacing:
|
|
case cSetting_label_multiline_justification:
|
|
case cSetting_label_padding:
|
|
case cSetting_label_bg_transparency:
|
|
case cSetting_label_bg_outline:
|
|
case cSetting_ray_label_connector_flat:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepLabel, cRepInvAll );
|
|
break;
|
|
case cSetting_surface_color_smoothing:
|
|
case cSetting_surface_color_smoothing_threshold:
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvColor);
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_smooth_half_bonds:
|
|
SceneChanged(G);
|
|
break;
|
|
case cSetting_antialias_shader:
|
|
case cSetting_atom_type_format:
|
|
case cSetting_colored_feedback:
|
|
case cSetting_load_atom_props_default:
|
|
case cSetting_load_object_props_default:
|
|
case cSetting_suspend_undo:
|
|
case cSetting_volume_mode:
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
" Setting-Warning: %s is not supported in Open-Source version of PyMOL\n",
|
|
SettingInfo[index].name
|
|
ENDFB(G);
|
|
break;
|
|
break;
|
|
case cSetting_surface_debug:
|
|
if (SettingGetGlobal_b(G, cSetting_use_shaders)){
|
|
ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvColor);
|
|
}
|
|
break;
|
|
case cSetting_pick32bit:
|
|
SceneInvalidatePicking(G);
|
|
break;
|
|
case cSetting_display_scale_factor:
|
|
{
|
|
int scaleFactor = SettingGetGlobal_i(G, cSetting_display_scale_factor);
|
|
if (scaleFactor > 0) {
|
|
_gScaleFactor = scaleFactor;
|
|
ExecutiveInvalidateRep(G, nullptr, cRepLabel, cRepInvRep);
|
|
OrthoCommandIn(G, "viewport");
|
|
} else {
|
|
SettingSetGlobal_i(G, cSetting_display_scale_factor, 1);
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
"Setting-Error: Cannot set a display scale factor of 0\n"
|
|
ENDFB(G);
|
|
}
|
|
break;
|
|
}
|
|
#ifdef _PYMOL_OPENVR
|
|
case cSetting_openvr_gui_distance:
|
|
case cSetting_openvr_gui_fov:
|
|
// case cSetting_openvr_gui_alpha:
|
|
// case cSetting_openvr_gui_use_alpha:
|
|
case cSetting_openvr_gui_scene_color:
|
|
case cSetting_openvr_gui_scene_alpha:
|
|
case cSetting_openvr_gui_back_color:
|
|
case cSetting_openvr_gui_back_alpha:
|
|
// case cSetting_openvr_gui_use_backdrop:
|
|
// case cSetting_openvr_gui_overlay:
|
|
// case cSetting_openvr_gui_text:
|
|
OpenVRMenuSettingsChanged(G);
|
|
break;
|
|
case cSetting_openvr_disable_clipping:
|
|
OpenVRClippingChanged(G);
|
|
break;
|
|
case cSetting_openvr_laser_width:
|
|
OpenVRLaserWidthChanged(G);
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
void SettingFreeGlobal(PyMOLGlobals * G)
|
|
{
|
|
SettingUniqueFree(G);
|
|
DeleteP(G->Setting);
|
|
DeleteP(G->Default);
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
void SettingInitGlobal(PyMOLGlobals * G, int alloc, int reset_gui, int use_default)
|
|
{
|
|
CSetting *I = G->Setting;
|
|
|
|
/* use function pointers to prevent the compiler from inlining every
|
|
call in this block (a waste of RAM and time) */
|
|
|
|
int (*set_i) (CSetting * I, int index, int value) = SettingSet_i;
|
|
int (*set_b) (CSetting * I, int index, int value) = SettingSet_b;
|
|
|
|
if(alloc || !I) {
|
|
I = G->Setting = SettingNew(G);
|
|
SettingUniqueInit(G);
|
|
}
|
|
|
|
if(G->Default && use_default) {
|
|
|
|
SettingCopyAll(G, G->Default, G->Setting);
|
|
|
|
} else {
|
|
|
|
// copy defaults from SettingInfo table
|
|
for(int index = 0; index < cSetting_INIT; ++index) {
|
|
if (!reset_gui) switch (index) {
|
|
case cSetting_internal_gui_width:
|
|
case cSetting_internal_gui:
|
|
continue;
|
|
}
|
|
|
|
SettingRestoreDefault(I, index);
|
|
}
|
|
|
|
// open-source has no volume_mode=1
|
|
set_i(I, cSetting_volume_mode, 0);
|
|
|
|
// command line arguments overwrites
|
|
set_b(I, cSetting_auto_show_lines, G->Option->sphere_mode < 0);
|
|
set_i(I, cSetting_auto_zoom, G->Option->zoom_mode);
|
|
set_b(I, cSetting_auto_show_nonbonded, G->Option->sphere_mode < 0);
|
|
set_b(I, cSetting_presentation, G->Option->presentation);
|
|
set_i(I, cSetting_defer_builds_mode, G->Option->defer_builds_mode);
|
|
set_b(I, cSetting_presentation_auto_quit, !G->Option->no_quit);
|
|
set_b(I, cSetting_auto_show_spheres, G->Option->sphere_mode >= 0);
|
|
set_i(I, cSetting_internal_feedback, G->Option->internal_feedback);
|
|
|
|
if(G->Option->stereo_mode) {
|
|
set_i(I, cSetting_stereo_mode, G->Option->stereo_mode);
|
|
} else if(G->StereoCapable || G->Option->blue_line) {
|
|
set_i(I, cSetting_stereo_mode, cStereo_quadbuffer); /* quadbuffer if we can */
|
|
}
|
|
|
|
/* In order to get electrostatic potentials in kT from the Coulomb equation...
|
|
|
|
PyMOL charges: Q, in e
|
|
PyMOL distances: r, in Angstrom
|
|
Coulomb Constant: K = 8.987552e9 ((J*m)/(C^2))
|
|
Angstrom Convertor: 1 A = 1e-10 m
|
|
Coulomb Convertor: 1 e = 1.60217733e-19 C
|
|
Angstrom Convertor: 1 A = 10e-10 m
|
|
Dielectric Constant: D (unitless)
|
|
|
|
ePot = (KQ)/(Dr) =
|
|
|
|
8.987552e9 J*m 1.6021773e-19 C 1.6021773e-19 C 1 A Q
|
|
---------------- * --------------- * --------------- * ---------- * --- =
|
|
C^2 1 e 1 e 1e-10 m Dr
|
|
|
|
2.3070795237e-18 J*A Q
|
|
= ---------------------- * ---
|
|
e^2 Dr
|
|
|
|
Boltzmann Constant: k = 1.380658e-23 (J/K)
|
|
Temperature: 300 Kelvin
|
|
|
|
kT = 1.380658e-23 * 300 = 4.141974e-21 J
|
|
|
|
2.3070795237e-18 J*A 1 kT Q
|
|
ePot = --------------------- * ------------------ * ---
|
|
e^2 4.141974e-21 J Dr
|
|
|
|
557.00000 kT*A Q
|
|
ePot = -------------- * --- which will give kT/e units when applied
|
|
e^2 Dr
|
|
*/
|
|
|
|
#ifdef WIN32
|
|
/* BEGIN PROPRIETARY CODE SEGMENT (see disclaimer in "os_proprietary.h") */
|
|
set_b(I, cSetting_cache_display, 0);
|
|
|
|
// PYMOL-3143/PYMOL-3181 Intel HD Graphics
|
|
// 4.5.0 - Build *.20.100.*
|
|
// Driver update breaks lighting
|
|
set_b(I, cSetting_precomputed_lighting, 1);
|
|
|
|
#ifndef _PYMOL_ACTIVEX
|
|
if (auto count = std::thread::hardware_concurrency() > 1) {
|
|
set_i(I, cSetting_max_threads, count);
|
|
}
|
|
/* END PROPRIETARY CODE SEGMENT */
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef _PYMOL_FREETYPE
|
|
set_i(I, cSetting_label_font_id, 0);
|
|
#endif
|
|
|
|
}
|
|
G->ShaderMgr->Set_Reload_Bits(RELOAD_ALL_SHADERS);
|
|
}
|
|
|
|
int SettingCheckFontID(PyMOLGlobals * G, CSetting * set1, CSetting * set2, int font_id){
|
|
int ret = font_id;
|
|
if (font_id < 5){ // we are no longer supporting GLUT labels since they are not resizeable
|
|
PRINTFB(G, FB_Setting, FB_Warnings)
|
|
"RepLabel-Warning: GLUT labels (label_font_id 0-4) are no longer available for labelling\n the scene since they are not resizeable label_font_id=%d setting back to 5 (default) \n",
|
|
font_id ENDFB(G);
|
|
if (SettingGet_i(G, set1, nullptr, cSetting_label_font_id) == font_id && SettingSet_i(set1, cSetting_label_font_id, 5)){
|
|
} else if (SettingGet_i(G, set2, nullptr, cSetting_label_font_id) == font_id && SettingSet_i(set2, cSetting_label_font_id, 5)){
|
|
} else if (SettingGetGlobal_i(G, cSetting_label_font_id) == font_id){
|
|
SettingSetGlobal_i(G, cSetting_label_font_id, 5);
|
|
};
|
|
ret = 5;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* State index iterator constructor, see Setting.h for documentation.
|
|
*
|
|
* @param set Optional object settings (can be nullptr)
|
|
* @param nstate Maximum number of states
|
|
*/
|
|
StateIterator::StateIterator(
|
|
PyMOLGlobals* G, CSetting* set, StateIndex_t state_, int nstate)
|
|
{
|
|
if (state_ == cStateCurrent) {
|
|
state_ = SettingGet_i(G, set, nullptr, cSetting_state) - 1;
|
|
}
|
|
|
|
if (state_ == cStateAll) {
|
|
state = 0;
|
|
end = nstate;
|
|
} else {
|
|
// given state or static singleton
|
|
state = (state_ > 0 && nstate == 1
|
|
&& SettingGet_b(G, set, nullptr, cSetting_static_singletons)) ? 0 : state_;
|
|
end = state + 1;
|
|
}
|
|
|
|
if (state < 0)
|
|
state = 0;
|
|
|
|
if (end > nstate)
|
|
end = nstate;
|
|
|
|
state--;
|
|
}
|
|
|
|
/**
|
|
* Take settings and number of states from given object.
|
|
*/
|
|
StateIterator::StateIterator(pymol::CObject* obj, StateIndex_t state_)
|
|
: StateIterator(obj->G, obj->Setting.get(), state_, obj->getNFrame())
|
|
{
|
|
}
|
|
|
|
StateIteratorV2::StateIteratorV2(
|
|
pymol::CObject* obj, StateIndex_t state_)
|
|
{
|
|
auto G = obj->G;
|
|
auto set = obj->Setting.get();
|
|
auto nstate = obj->getNFrame();
|
|
if (state_ == cStateCurrent) {
|
|
state_ = SettingGet<int>(G, set, nullptr, cSetting_state) - 1;
|
|
}
|
|
|
|
if (state_ == cStateAll) {
|
|
m_cur = 0;
|
|
m_end = nstate;
|
|
} else {
|
|
// given state or static singleton
|
|
m_cur = (state_ > 0 && nstate == 1 &&
|
|
SettingGet<bool>(G, set, nullptr, cSetting_static_singletons))
|
|
? 0
|
|
: state_;
|
|
m_end = m_cur + 1;
|
|
}
|
|
m_cur = std::max(0, m_cur);
|
|
m_beg = m_cur;
|
|
m_end = std::min(m_end, nstate);
|
|
|
|
m_cur--;
|
|
}
|
|
|
|
StateIndex_t* StateIteratorV2::begin()
|
|
{
|
|
return &m_beg;
|
|
}
|
|
StateIndex_t* StateIteratorV2::end()
|
|
{
|
|
return &m_end;
|
|
}
|
|
|
|
/**
|
|
* Helper function to init CPyMOL.Setting, a (name: index) dictionary.
|
|
* Called in PyMOL_InitAPI
|
|
*/
|
|
bool CPyMOLInitSetting(OVLexicon * Lex, std::unordered_map<int, int>& Setting) {
|
|
for(int index = 0; index < cSetting_INIT; ++index) {
|
|
auto &rec = SettingInfo[index];
|
|
|
|
if (rec.level == cSettingLevel_unused)
|
|
continue;
|
|
|
|
OVreturn_word result = OVLexicon_GetFromCString(Lex, rec.name);
|
|
|
|
if (!OVreturn_IS_OK(result)) {
|
|
return false;
|
|
}
|
|
Setting[result.word] = index;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#ifndef _PYMOL_NOPY
|
|
/**
|
|
* Export the settings names to Python a as (name: index) dictionary.
|
|
* Replacement for pymol.settings.SettingIndex
|
|
*/
|
|
PyObject * SettingGetSettingIndices() {
|
|
PyObject * val;
|
|
PyObject * dict = PyDict_New();
|
|
|
|
for(int index = 0; index < cSetting_INIT; ++index) {
|
|
auto &rec = SettingInfo[index];
|
|
|
|
if (rec.level == cSettingLevel_unused)
|
|
continue;
|
|
|
|
if ((val = PyInt_FromLong(index))) {
|
|
PyDict_SetItemString(dict, rec.name, val);
|
|
Py_DECREF(val);
|
|
}
|
|
}
|
|
|
|
return dict;
|
|
}
|
|
|
|
/**
|
|
* Return a list of all setting indices for the given unique id
|
|
*/
|
|
PyObject * SettingUniqueGetIndicesAsPyList(PyMOLGlobals * G, int unique_id)
|
|
{
|
|
CSettingUnique *I = G->SettingUnique;
|
|
PyObject * list = PyList_New(0);
|
|
|
|
auto offsetIt = I->id2offset.find(unique_id);
|
|
if (unique_id && offsetIt != I->id2offset.end()) {
|
|
SettingUniqueEntry* entry;
|
|
for (int offset = offsetIt->second; offset; offset = entry->next) {
|
|
entry = &I->entry[offset];
|
|
PyObject *item = PyInt_FromLong(entry->setting_id);
|
|
PyList_Append(list, item);
|
|
Py_DECREF(item);
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Getters for templatted programming
|
|
*/
|
|
|
|
const CSetting * _SettingGetFirstDefined(int index,
|
|
PyMOLGlobals * G,
|
|
const CSetting * set1,
|
|
const CSetting * set2) {
|
|
if (set1 && set1->info[index].defined)
|
|
return set1;
|
|
if (set2 && set2->info[index].defined)
|
|
return set2;
|
|
return G->Setting;
|
|
}
|