mirror of
https://github.com/schrodinger/pymol-open-source.git
synced 2026-06-04 20:04:21 +08:00
211 lines
4.8 KiB
C++
211 lines
4.8 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_predef.h"
|
|
#include"os_std.h"
|
|
#include"os_gl.h"
|
|
|
|
#include"main.h"
|
|
#include"Feedback.h"
|
|
#include"Rep.h"
|
|
#include"MemoryDebug.h"
|
|
#include"CoordSet.h"
|
|
#include"P.h"
|
|
#include"Util.h"
|
|
#include"Scene.h"
|
|
|
|
/*========================================================================*/
|
|
/**
|
|
* Delete this instance and return a newly created instance.
|
|
*
|
|
* If creating the new instance fails (e.g. empty rep):
|
|
* - Don't delete this instance
|
|
* - Set cs->Active[rep] to false
|
|
*
|
|
* @todo Use move semantics instead? Return false on failure?
|
|
*/
|
|
Rep* Rep::rebuild()
|
|
{
|
|
assert(cs);
|
|
assert(fNew);
|
|
Rep* tmp = fNew(cs, getState());
|
|
if (tmp) {
|
|
tmp->fNew = fNew;
|
|
delete this;
|
|
return tmp;
|
|
}
|
|
|
|
// nothing returned -- visibility is zero...
|
|
// keep the old object around, but inactive (TODO why?)
|
|
cs->Active[type()] = false;
|
|
return this;
|
|
}
|
|
|
|
/*========================================================================*/
|
|
/**
|
|
* Rebuild if necessary (according to invalidation status). Returns either this
|
|
* instance, or deletes this instance and returns a new one, or nullptr if the rep
|
|
* became empty/inactive.
|
|
*/
|
|
Rep* Rep::update()
|
|
{
|
|
assert(cs);
|
|
|
|
if (MaxInvalid == cRepInvNone) {
|
|
return this;
|
|
}
|
|
|
|
auto I = this;
|
|
auto const rep = type();
|
|
auto const* cs_ = cs;
|
|
|
|
assert(cs_->Active[rep]);
|
|
|
|
if (MaxInvalid == cRepInvPick) {
|
|
switch (rep) {
|
|
case cRepLine:
|
|
case cRepCyl:
|
|
case cRepRibbon:
|
|
case cRepNonbonded:
|
|
// TODO Is this needed? How about other pickable reps, like:
|
|
// - cartoon
|
|
// - spheres
|
|
// - surface with pick_surface=on
|
|
MaxInvalid = cRepInvRep;
|
|
}
|
|
}
|
|
|
|
if (MaxInvalid < cRepInvColor) {
|
|
// nothing to do
|
|
} else if (MaxInvalid == cRepInvColor) {
|
|
I = recolor();
|
|
} else if (MaxInvalid > cRepInvVisib || !sameVis()) {
|
|
I = rebuild();
|
|
} else if (!sameColor()) {
|
|
I = recolor();
|
|
}
|
|
|
|
if (!cs_->Active[rep]) {
|
|
delete I;
|
|
return nullptr;
|
|
}
|
|
|
|
if (I) {
|
|
I->MaxInvalid = cRepInvNone;
|
|
}
|
|
|
|
return I;
|
|
}
|
|
|
|
/*========================================================================*/
|
|
/**
|
|
* Request that the rep gets updated. Update happens on next scene redraw.
|
|
*
|
|
* @param level Invalidate to at least this level
|
|
*/
|
|
void Rep::invalidate(cRepInv_t level)
|
|
{
|
|
auto I = this;
|
|
SceneInvalidatePicking(I->G); // for now, if anything invalidated, then invalidate picking
|
|
if(level > I->MaxInvalid)
|
|
I->MaxInvalid = level;
|
|
}
|
|
|
|
/**
|
|
* Get the visRep mask according to auto_show_* settings
|
|
*/
|
|
cRepBitmask_t RepGetAutoShowMask(PyMOLGlobals * G)
|
|
{
|
|
cRepBitmask_t mask = 0;
|
|
if (SettingGetGlobal_b(G, cSetting_auto_show_lines)) mask |= cRepLineBit;
|
|
if (SettingGetGlobal_b(G, cSetting_auto_show_spheres)) mask |= cRepSphereBit;
|
|
if (SettingGetGlobal_b(G, cSetting_auto_show_nonbonded)) mask |= cRepNonbondedBit;
|
|
return mask;
|
|
}
|
|
|
|
/*========================================================================*/
|
|
/**
|
|
* Derived classes should overrride this method.
|
|
*
|
|
* TODO: What is this default implementation useful for? Debugging?
|
|
*/
|
|
void Rep::render(RenderInfo* info)
|
|
{
|
|
if(G->HaveGUI && G->ValidContext) {
|
|
#ifdef PURE_OPENGL_ES_2
|
|
/* TODO */
|
|
#else
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex3f(-0.5F, -0.5F, -0.5F);
|
|
glVertex3f(-0.5F, -0.5F, 0.5F);
|
|
glVertex3f(-0.5F, 0.5F, 0.5F);
|
|
glVertex3f(-0.5F, 0.5F, -0.5F);
|
|
|
|
glVertex3f(0.5F, 0.5F, -0.5F);
|
|
glVertex3f(0.5F, 0.5F, 0.5F);
|
|
glVertex3f(0.5F, -0.5F, 0.5F);
|
|
glVertex3f(0.5F, -0.5F, -0.5F);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINES);
|
|
glVertex3i(0, 0, 0);
|
|
glVertex3i(1, 0, 0);
|
|
|
|
glVertex3i(0, 0, 0);
|
|
glVertex3i(0, 2, 0);
|
|
|
|
glVertex3i(0, 0, 0);
|
|
glVertex3i(0, 0, 3);
|
|
|
|
glEnd();
|
|
#endif
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/*========================================================================*/
|
|
Rep::Rep(pymol::CObject* obj_, int state)
|
|
: G(obj_->G)
|
|
, obj(obj_)
|
|
{
|
|
context.object = obj_;
|
|
context.state = state;
|
|
}
|
|
|
|
Rep::Rep(CoordSet* cs_, int state)
|
|
: Rep(cs_->Obj, state)
|
|
{
|
|
cs = cs_;
|
|
}
|
|
|
|
Rep::~Rep()
|
|
{
|
|
FreeP(P);
|
|
}
|
|
|
|
RepIterator::RepIterator(PyMOLGlobals * G, int rep_) {
|
|
if (rep_ < 0){
|
|
end = cRepCnt;
|
|
rep = -1;
|
|
} else {
|
|
end = rep_ + 1;
|
|
rep = rep_ - 1;
|
|
}
|
|
}
|