Files
pymol-open-source/layer2/ObjectGadget.cpp
Jarrett Johnson 65835f9991 Remove OOMac
2021-07-07 12:03:25 -04:00

476 lines
11 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"ObjectGadget.h"
#include"ObjectGadgetRamp.h"
#include"GadgetSet.h"
#include"Base.h"
#include"MemoryDebug.h"
#include"CGO.h"
#include"Scene.h"
#include"Setting.h"
#include"PConv.h"
#include"main.h"
#include"Color.h"
#include"VFont.h"
CGO *ObjectGadgetPyListFloatToCGO(PyObject * list);
int ObjectGadgetGetVertex(const ObjectGadget * I, int index, int base, float *v)
{
GadgetSet *gs;
int ok = false;
if(I->CurGSet < I->NGSet) {
gs = I->GSet[I->CurGSet];
if(gs) {
ok = GadgetSetGetVertex(gs, index, base, v);
}
}
return (ok);
}
int ObjectGadgetSetVertex(ObjectGadget * I, int index, int base, const float *v)
{
GadgetSet *gs;
int ok = false;
if(I->CurGSet < I->NGSet) {
gs = I->GSet[I->CurGSet];
if(gs) {
ok = GadgetSetSetVertex(gs, index, base, v);
}
}
if (index) // if 0 - xyz doesn't change, 1 - mouse position when changing colors
I->Changed = true;
return (ok);
}
/* in current state */
ObjectGadget *ObjectGadgetTest(PyMOLGlobals * G)
{
ObjectGadget *I = NULL;
GadgetSet *gs = NULL;
CGO *cgo = NULL;
int a;
float coord[] = {
0.5F, 0.5F, 0.0F,
0.0F, 0.0F, 0.0F,
0.3F, 0.0F, 0.0F,
0.0F, -0.3F, 0.0F,
0.3F, -0.3F, 0.0F,
0.03F, -0.03F, 0.03F,
0.27F, -0.03F, 0.03F,
0.03F, -0.27F, 0.03F,
0.27F, -0.27F, 0.03F,
0.02F, -0.02F, 0.01F,
0.28F, -0.02F, 0.01F,
0.02F, -0.28F, 0.01F,
0.28F, -0.28F, 0.01F,
};
float normal[] = {
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
-1.0, 0.0, 0.0,
0.0, -1.0, 0.0,
};
I = new ObjectGadget(G);
gs = GadgetSetNew(G);
gs->NCoord = 13;
gs->Coord = VLAlloc(float, gs->NCoord * 3);
for(a = 0; a < gs->NCoord * 3; a++) {
gs->Coord[a] = coord[a];
}
gs->NNormal = 5;
gs->Normal = VLAlloc(float, gs->NNormal * 3);
for(a = 0; a < gs->NNormal * 3; a++) {
gs->Normal[a] = normal[a];
}
cgo = CGONewSized(G, 100);
CGOColor(cgo, 1.0, 1.0, 1.0);
/* top */
CGOBegin(cgo, GL_TRIANGLE_STRIP);
CGONormal(cgo, 2.0, 2.0, 0.0);
CGOVertex(cgo, 1.0, 5.0, 0.0);
CGOVertex(cgo, 1.0, 6.0, 0.0);
CGONormal(cgo, 2.0, 1.0, 0.0);
CGOVertex(cgo, 1.0, 1.0, 0.0);
CGOVertex(cgo, 1.0, 2.0, 0.0);
CGOEnd(cgo);
/* bottom */
CGOBegin(cgo, GL_TRIANGLE_STRIP);
CGONormal(cgo, 2.0, 4.0, 0.0);
CGOVertex(cgo, 1.0, 3.0, 0.0);
CGOVertex(cgo, 1.0, 4.0, 0.0);
CGONormal(cgo, 2.0, 2.0, 0.0);
CGOVertex(cgo, 1.0, 7.0, 0.0);
CGOVertex(cgo, 1.0, 8.0, 0.0);
CGOEnd(cgo);
/* left */
CGOBegin(cgo, GL_TRIANGLE_STRIP);
CGONormal(cgo, 2.0, 3.0, 0.0);
CGOVertex(cgo, 1.0, 1.0, 0.0);
CGOVertex(cgo, 1.0, 3.0, 0.0);
CGONormal(cgo, 2.0, 2.0, 0.0);
CGOVertex(cgo, 1.0, 5.0, 0.0);
CGOVertex(cgo, 1.0, 7.0, 0.0);
CGOEnd(cgo);
/* right */
CGOBegin(cgo, GL_TRIANGLE_STRIP);
CGONormal(cgo, 2.0, 2.0, 0.0);
CGOVertex(cgo, 1.0, 6.0, 0.0);
CGOVertex(cgo, 1.0, 8.0, 0.0);
CGONormal(cgo, 2.0, 0.0, 0.0);
CGOVertex(cgo, 1.0, 2.0, 0.0);
CGOVertex(cgo, 1.0, 4.0, 0.0);
CGOEnd(cgo);
CGOColor(cgo, 1.0, 0.0, 0.0);
/* center */
CGOBegin(cgo, GL_TRIANGLE_STRIP);
CGONormal(cgo, 2.0, 2.0, 0.0);
CGOVertex(cgo, 1.0, 5.0, 0.0);
CGOVertex(cgo, 1.0, 7.0, 0.0);
CGOVertex(cgo, 1.0, 6.0, 0.0);
CGOVertex(cgo, 1.0, 8.0, 0.0);
CGOEnd(cgo);
CGOColor(cgo, 0.0, 1.0, 0.0);
/* backr */
CGOBegin(cgo, GL_TRIANGLE_STRIP);
CGONormal(cgo, 2.0, 2.0, 0.0);
CGOVertex(cgo, 1.0, 9.0, 0.0);
CGOVertex(cgo, 1.0, 10.0, 0.0);
CGOVertex(cgo, 1.0, 11.0, 0.0);
CGOVertex(cgo, 1.0, 12.0, 0.0);
CGOEnd(cgo);
CGOStop(cgo);
gs->ShapeCGO = cgo;
cgo = CGONewSized(G, 100);
CGODotwidth(cgo, 5);
CGOPickColor(cgo, 0, cPickableGadget);
/* top */
CGOBegin(cgo, GL_TRIANGLE_STRIP);
CGOVertex(cgo, 1.0, 1.0, 0.0);
CGOVertex(cgo, 1.0, 2.0, 0.0);
CGOVertex(cgo, 1.0, 5.0, 0.0);
CGOVertex(cgo, 1.0, 6.0, 0.0);
CGOEnd(cgo);
/* bottom */
CGOBegin(cgo, GL_TRIANGLE_STRIP);
CGOVertex(cgo, 1.0, 3.0, 0.0);
CGOVertex(cgo, 1.0, 4.0, 0.0);
CGOVertex(cgo, 1.0, 7.0, 0.0);
CGOVertex(cgo, 1.0, 8.0, 0.0);
CGOEnd(cgo);
/* left */
CGOBegin(cgo, GL_TRIANGLE_STRIP);
CGOVertex(cgo, 1.0, 1.0, 0.0);
CGOVertex(cgo, 1.0, 3.0, 0.0);
CGOVertex(cgo, 1.0, 5.0, 0.0);
CGOVertex(cgo, 1.0, 7.0, 0.0);
CGOEnd(cgo);
/* right */
CGOBegin(cgo, GL_TRIANGLE_STRIP);
CGOVertex(cgo, 1.0, 6.0, 0.0);
CGOVertex(cgo, 1.0, 8.0, 0.0);
CGOVertex(cgo, 1.0, 2.0, 0.0);
CGOVertex(cgo, 1.0, 4.0, 0.0);
CGOEnd(cgo);
CGOEnd(cgo);
CGOStop(cgo);
gs->PickShapeCGO = cgo;
gs->Obj = I;
gs->State = 0;
I->GSet[0] = gs;
I->NGSet = 1;
gs->update();
ObjectGadgetUpdateExtents(I);
return (I);
}
void ObjectGadgetUpdateExtents(ObjectGadget * I)
{
float maxv[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
float minv[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX };
int a;
GadgetSet *ds;
/* update extents */
copy3f(maxv, I->ExtentMin);
copy3f(minv, I->ExtentMax);
I->ExtentFlag = false;
for(a = 0; a < I->NGSet; a++) {
ds = I->GSet[a];
if(ds) {
if(GadgetSetGetExtent(ds, I->ExtentMin, I->ExtentMax))
I->ExtentFlag = true;
}
}
}
static PyObject *ObjectGadgetGSetAsPyList(ObjectGadget * I, bool incl_cgos)
{
PyObject *result = NULL;
int a;
result = PyList_New(I->NGSet);
for(a = 0; a < I->NGSet; a++) {
if(I->GSet[a]) {
PyList_SetItem(result, a, GadgetSetAsPyList(I->GSet[a], incl_cgos));
} else {
PyList_SetItem(result, a, PConvAutoNone(Py_None));
}
}
return (PConvAutoNone(result));
}
static int ObjectGadgetGSetFromPyList(ObjectGadget * I, PyObject * list, int version)
{
int ok = true;
int a;
if(ok)
ok = PyList_Check(list);
if(ok) {
VLACheck(I->GSet, GadgetSet *, I->NGSet);
for(a = 0; a < I->NGSet; a++) {
if(ok){
auto *val = PyList_GetItem(list, a);
ok = GadgetSetFromPyList(I->G, val, &I->GSet[a], version);
}
if(ok && I->GSet[a]) {
I->GSet[a]->Obj = I;
I->GSet[a]->State = a;
}
}
}
return (ok);
}
int ObjectGadgetInitFromPyList(PyMOLGlobals * G, PyObject * list, ObjectGadget * I,
int version)
{
int ok = true;
if(ok)
ok = (I != NULL) && (list != NULL);
if(ok)
ok = PyList_Check(list);
/* TO SUPPORT BACKWARDS COMPATIBILITY...
Always check ll when adding new PyList_GetItem's */
if(ok){
auto *val = PyList_GetItem(list, 0);
ok = ObjectFromPyList(G, val, I);
}
if(ok)
ok = PConvPyIntToInt(PyList_GetItem(list, 1), &I->GadgetType);
if(ok)
ok = PConvPyIntToInt(PyList_GetItem(list, 2), &I->NGSet);
if(ok)
ok = ObjectGadgetGSetFromPyList(I, PyList_GetItem(list, 3), version);
if(ok)
ok = PConvPyIntToInt(PyList_GetItem(list, 4), &I->CurGSet);
/* ObjectGadgetInvalidateRep(I,cRepAll); */
if(ok) {
ObjectGadgetUpdateExtents(I);
} else {
/* cleanup? */
}
return (ok);
}
int ObjectGadgetNewFromPyList(PyMOLGlobals * G, PyObject * list, ObjectGadget ** result,
int version)
{
int ok = true;
ObjectGadget *I = NULL;
int gadget_type = -1;
PyObject *plain;
(*result) = NULL;
if(ok)
ok = (list != NULL);
if(ok)
ok = PyList_Check(list);
/* NOTE there is a serious screw-up here...ramp gadgets aren't saved right, but
we've got to maintain backward compat...ugh */
if(ok)
ok = ((plain = PyList_GetItem(list, 0)) != NULL);
if(ok)
ok = PyList_Check(plain);
if(ok)
ok = PConvPyIntToInt(PyList_GetItem(plain, 1), &gadget_type);
if(ok)
switch (gadget_type) { /* call the right routine to restore the gadget! */
case cGadgetRamp:
ok = ObjectGadgetRampNewFromPyList(G, list, (ObjectGadgetRamp **) result, version);
break;
case cGadgetPlain:
I = new ObjectGadget(G);
if(ok)
ok = (I != NULL);
if(ok)
ok = ObjectGadgetInitFromPyList(G, list, I, version);
if(ok)
(*result) = I;
break;
default:
ok = false;
break;
}
return (ok);
}
PyObject *ObjectGadgetPlainAsPyList(ObjectGadget * I, bool incl_cgos)
{
PyObject *result = NULL;
/* first, dump the atoms */
result = PyList_New(5);
PyList_SetItem(result, 0, ObjectAsPyList(I));
PyList_SetItem(result, 1, PyInt_FromLong(I->GadgetType));
PyList_SetItem(result, 2, PyInt_FromLong(I->NGSet));
PyList_SetItem(result, 3, ObjectGadgetGSetAsPyList(I, incl_cgos));
PyList_SetItem(result, 4, PyInt_FromLong(I->CurGSet));
return (PConvAutoNone(result));
}
PyObject *ObjectGadgetAsPyList(ObjectGadget * I)
{
PyObject *result = NULL;
/* first, dump the atoms */
switch (I->GadgetType) {
case cGadgetRamp:
result = ObjectGadgetRampAsPyList((ObjectGadgetRamp *) I);
break;
case cGadgetPlain:
result = ObjectGadgetPlainAsPyList(I);
break;
}
return (PConvAutoNone(result));
}
ObjectGadget::~ObjectGadget()
{
auto I = this;
for(int a = 0; a < I->NGSet; a++)
if(I->GSet[a]) {
delete I->GSet[a];
I->GSet[a] = NULL;
}
}
void ObjectGadgetUpdateStates(ObjectGadget * I)
{
int a;
OrthoBusyPrime(I->G);
for(a = 0; a < I->NGSet; a++)
if(I->GSet[a]) {
OrthoBusySlow(I->G, a, I->NGSet);
/* printf(" ObjectGadget: updating state %d of \"%s\".\n" , a+1, I->Name); */
I->GSet[a]->update();
}
}
/*========================================================================*/
void ObjectGadget::update()
{
auto I = this;
if(I->Changed) {
ObjectGadgetUpdateStates(I);
ObjectGadgetUpdateExtents(I);
I->Changed = false;
}
}
/*========================================================================*/
int ObjectGadget::getNFrame() const
{
return NGSet;
}
/*========================================================================*/
void ObjectGadget::render(RenderInfo * info)
{
auto I = this;
int state = info->state;
const RenderPass pass = info->pass;
if(pass == RenderPass::Transparent || info->ray || info->pick) {
ObjectPrepareContext(I, info);
for(StateIterator iter(I->G, I->Setting.get(), state, I->NGSet);
iter.next();) {
GadgetSet * gs = I->GSet[iter.state];
gs->render(info);
}
}
}
/*========================================================================*/
ObjectGadget::ObjectGadget(PyMOLGlobals * G) : pymol::CObject(G)
{
type = cObjectGadget;
GSet = pymol::vla<GadgetSet*>(10); /* auto-zero */
}
pymol::RenderContext ObjectGadget::getRenderContext() const
{
return pymol::RenderContext::UnitWindow;
}