mirror of
https://github.com/schrodinger/pymol-open-source.git
synced 2026-06-04 20:04:21 +08:00
238 lines
5.3 KiB
C++
Executable File
238 lines
5.3 KiB
C++
Executable File
/*
|
|
* MAE format export helper functions
|
|
*
|
|
* (c) 2018 Schrodinger, Inc.
|
|
*/
|
|
|
|
#include <string>
|
|
|
|
#include "os_std.h"
|
|
|
|
#include "AtomInfo.h"
|
|
#include "AtomIterators.h"
|
|
#include "MaeExportHelpers.h"
|
|
#include "Color.h"
|
|
#include "Lex.h"
|
|
#include "Setting.h"
|
|
#include "Executive.h"
|
|
#include "SpecRec.h"
|
|
|
|
/**
|
|
* Setting getter
|
|
*/
|
|
template <typename V>
|
|
V SettingGet(PyMOLGlobals * G, const SeleCoordIterator& iter, int index) {
|
|
V value = SettingGet<V>(G, iter.cs->Setting.get(), iter.obj->Setting.get(), index);
|
|
return AtomSettingGetWD(G, iter.getAtomInfo(), index, value);
|
|
}
|
|
|
|
/*
|
|
* enums from
|
|
* mmshare/include/mmct.h
|
|
* mmshare/include/mmctg.h
|
|
*/
|
|
|
|
enum MM_CTAtomStyle {
|
|
MMCT_ATOM_NOSTYLE = 0,
|
|
MMCT_ATOM_CIRCLE,
|
|
MMCT_ATOM_CPK,
|
|
MMCT_ATOM_BALLNSTICK
|
|
};
|
|
|
|
enum MM_CTBondStyle {
|
|
MMCT_BOND_NOSTYLE = 0,
|
|
MMCT_BOND_WIRE,
|
|
MMCT_BOND_TUBE,
|
|
MMCT_BOND_BALLNSTICK
|
|
};
|
|
|
|
enum MM_CTRibbonStyle {
|
|
MMCT_RIBBON_STYLE_NONE = 0, //
|
|
MMCT_RIBBON_STYLE_CARTOON = 1, // auto
|
|
MMCT_RIBBON_STYLE_RIBBON = 2, // auto
|
|
MMCT_RIBBON_STYLE_TUBE = 3, // tube, cartoon_tube_radius=0.30
|
|
MMCT_RIBBON_STYLE_THINTUBE = 4, // tube, cartoon_tube_radius=0.15
|
|
MMCT_RIBBON_STYLE_CURVELINE = 5, // ribbon, ribbon_sampling=5
|
|
MMCT_RIBBON_STYLE_CALINE = 6, // ribbon, ribbon_as_cylinders=0
|
|
MMCT_RIBBON_STYLE_CATUBE = 7, // ribbon, ribbon_as_cylinders=1
|
|
};
|
|
|
|
/**
|
|
* Get the MM_CTAtomStyle for the current atom of the iterator
|
|
*/
|
|
int MaeExportGetAtomStyle(PyMOLGlobals * G,
|
|
const SeleCoordIterator& iter)
|
|
{
|
|
auto ai = iter.getAtomInfo();
|
|
|
|
if (ai->visRep & cRepSphereBit)
|
|
return MMCT_ATOM_CPK;
|
|
|
|
if ((ai->visRep & cRepNonbondedSphereBit) && !ai->bonded)
|
|
return MMCT_ATOM_BALLNSTICK;
|
|
|
|
if ((ai->visRep & cRepCylBit) && ai->bonded
|
|
&& SettingGet<bool>(G, iter, cSetting_stick_ball)
|
|
&& SettingGet<float>(G, iter, cSetting_stick_ball_ratio) > 1.0f)
|
|
return MMCT_ATOM_BALLNSTICK;
|
|
|
|
return MMCT_ATOM_NOSTYLE;
|
|
}
|
|
|
|
/**
|
|
* Get the MM_CTBondStyle for the bond between two atoms
|
|
*/
|
|
int MaeExportGetBondStyle(const AtomInfoType * ai1, const AtomInfoType * ai2) {
|
|
if (ai1->visRep & ai2->visRep & cRepCylBit)
|
|
return MMCT_BOND_TUBE;
|
|
|
|
// assuming line_stick_helper=on
|
|
if ((ai1->visRep & (cRepLineBit | cRepCylBit)) &&
|
|
(ai2->visRep & (cRepLineBit | cRepCylBit)))
|
|
return MMCT_BOND_WIRE;
|
|
|
|
return MMCT_BOND_NOSTYLE;
|
|
}
|
|
|
|
/**
|
|
* Get the MM_CTRibbonStyle for an atom
|
|
*/
|
|
int MaeExportGetRibbonStyle(const AtomInfoType * ai) {
|
|
if (ai->visRep & cRepCartoonBit) {
|
|
switch (ai->cartoon) {
|
|
case cCartoon_skip:
|
|
return MMCT_RIBBON_STYLE_NONE;
|
|
case cCartoon_loop:
|
|
case cCartoon_tube:
|
|
case cCartoon_putty:
|
|
return MMCT_RIBBON_STYLE_TUBE;
|
|
}
|
|
return MMCT_RIBBON_STYLE_CARTOON;
|
|
}
|
|
|
|
if (ai->visRep & cRepRibbonBit) {
|
|
return MMCT_RIBBON_STYLE_CALINE;
|
|
}
|
|
|
|
return MMCT_RIBBON_STYLE_NONE;
|
|
}
|
|
|
|
/**
|
|
* Get the MAE ribbon color index and the hex formatted RGB ribbon color for
|
|
* the current atom of the iterator
|
|
*/
|
|
void MaeExportGetRibbonColor(PyMOLGlobals * G,
|
|
const SeleCoordIterator& iter,
|
|
char * ribbon_color_rgb)
|
|
{
|
|
const auto ai = iter.getAtomInfo();
|
|
|
|
if (!(ai->flags & cAtomFlag_guide))
|
|
return;
|
|
|
|
int setting_index;
|
|
if (ai->visRep & cRepCartoonBit) {
|
|
setting_index = cSetting_cartoon_color;
|
|
} else if (ai->visRep & cRepRibbonBit) {
|
|
setting_index = cSetting_ribbon_color;
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
int color = SettingGet<int>(G, iter, setting_index);
|
|
|
|
if (color > 0) {
|
|
const float * rgb = ColorGet(G, color);
|
|
sprintf(ribbon_color_rgb, "%02X%02X%02X",
|
|
int(rgb[0] * 255),
|
|
int(rgb[1] * 255),
|
|
int(rgb[2] * 255));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the MAE label user text for an atom.
|
|
*
|
|
* Quotes and backslashes are escaped.
|
|
*/
|
|
std::string MaeExportGetLabelUserText(PyMOLGlobals * G,
|
|
const AtomInfoType * ai)
|
|
{
|
|
std::string label_user_text;
|
|
|
|
if (ai->label) {
|
|
const char * label = LexStr(G, ai->label);
|
|
for (const char * p = label; *p; ++p) {
|
|
if (*p == '"' || *p == '\\')
|
|
label_user_text += '\\';
|
|
label_user_text += *p;
|
|
}
|
|
}
|
|
|
|
return label_user_text;
|
|
}
|
|
|
|
/**
|
|
* Get the MAE group title/id
|
|
*/
|
|
std::string MaeExportGetSubGroupId(PyMOLGlobals * G,
|
|
const pymol::CObject * obj)
|
|
{
|
|
std::string subgroupid;
|
|
const SpecRec * rec = nullptr;
|
|
|
|
// obj -> spec rec
|
|
for (ObjectIterator iter(G); iter.next();) {
|
|
if (iter.getObject() == obj) {
|
|
rec = iter.getSpecRec();
|
|
break;
|
|
}
|
|
}
|
|
|
|
// "->".join(grouphierarchy)
|
|
for (; rec && rec->group_name[0]; rec = rec->group) {
|
|
if (!subgroupid.empty()) {
|
|
subgroupid.insert(0, "->");
|
|
}
|
|
subgroupid.insert(0, rec->group_name);
|
|
}
|
|
|
|
return subgroupid;
|
|
}
|
|
|
|
/**
|
|
* Get parsable string representation, with quotes and escaped
|
|
* quotes/backslashes if needed.
|
|
*/
|
|
std::string MaeExportStrRepr(const char * text)
|
|
{
|
|
if (text[0] /* not empty string */) {
|
|
bool needquotes = false;
|
|
|
|
// check accepted ascii characters
|
|
for (const char * p = text; *p; ++p) {
|
|
if (*p < '$' || *p > 'z' || *p == '\\') {
|
|
needquotes = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!needquotes) {
|
|
return text;
|
|
}
|
|
}
|
|
|
|
std::string quoted_text;
|
|
quoted_text.reserve(strlen(text) + 2);
|
|
quoted_text += '"';
|
|
|
|
for (const char * p = text; *p; ++p) {
|
|
if (*p == '"' || *p == '\\')
|
|
quoted_text += '\\';
|
|
quoted_text += *p;
|
|
}
|
|
|
|
quoted_text += '"';
|
|
return quoted_text;
|
|
}
|