Logo Search packages:      
Sourcecode: pymol version File versions  Download package

ObjectGadget.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_predef.h"
#include"os_std.h"
#include"os_gl.h"

#include"OOMac.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);

void ObjectGadgetRender(ObjectGadget *I,int state,CRay *ray,Pickable **pick,int pass);

int ObjectGadgetGetVertex(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, 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);
    }
  }
  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=ObjectGadgetNew(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,0);

  /* 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;

  I->GSet[0] = gs;
  I->NGSet = 1;
  I->Obj.Context=1;
  gs->fUpdate(gs);
  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->Obj.ExtentMin);
  copy3f(minv,I->Obj.ExtentMax);
  I->Obj.ExtentFlag=false;
  for(a=0;a<I->NGSet;a++) {
    ds = I->GSet[a];
    if(ds) {
      if(GadgetSetGetExtent(ds,I->Obj.ExtentMin,I->Obj.ExtentMax))
        I->Obj.ExtentFlag=true;
    }
  }
}

#ifndef _PYMOL_NOPY
static PyObject *ObjectGadgetGSetAsPyList(ObjectGadget *I)
{
  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]));
    } else {
      PyList_SetItem(result,a,Py_None);
      Py_INCREF(Py_None);
    }
  }
  return(PConvAutoNone(result));

}
#endif
#ifndef _PYMOL_NOPY
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) ok = GadgetSetFromPyList(I->Obj.G,PyList_GetItem(list,a),&I->GSet[a],version);
      if(ok&&I->GSet[a]) I->GSet[a]->Obj = I;
    }
  }
  return(ok);
}
#endif
int ObjectGadgetInitFromPyList(PyMOLGlobals *G,PyObject *list,ObjectGadget *I,int version)
{
#ifdef _PYMOL_NOPY
  return 0;
#else

  int ok = true;
  int ll;
  if(ok) ok = (I!=NULL)&&(list!=NULL);
  if(ok) ok = PyList_Check(list);
  if(ok) ll = PyList_Size(list);
  /* TO SUPPORT BACKWARDS COMPATIBILITY...
   Always check ll when adding new PyList_GetItem's */
  if(ok) ok = ObjectFromPyList(G,PyList_GetItem(list,0),&I->Obj);
  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);
#endif
}

int ObjectGadgetNewFromPyList(PyMOLGlobals *G,PyObject *list,ObjectGadget **result,int version)
{
#ifdef _PYMOL_NOPY
  return 0;
#else

  int ok = true;
  ObjectGadget *I=NULL;
  int gadget_type = -1;
  (*result) = NULL;

  if(ok) ok=(list!=NULL);
  if(ok) ok=PyList_Check(list);

  if(ok) ok=PConvPyIntToInt(PyList_GetItem(list,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=ObjectGadgetNew(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);
#endif
}

PyObject *ObjectGadgetPlainAsPyList(ObjectGadget *I)
{
#ifdef _PYMOL_NOPY
  return NULL;
#else

  PyObject *result = NULL;

  /* first, dump the atoms */

  result = PyList_New(5);
  PyList_SetItem(result,0,ObjectAsPyList(&I->Obj));
  PyList_SetItem(result,1,PyInt_FromLong(I->GadgetType));
  PyList_SetItem(result,2,PyInt_FromLong(I->NGSet));
  PyList_SetItem(result,3,ObjectGadgetGSetAsPyList(I));
  PyList_SetItem(result,4,PyInt_FromLong(I->CurGSet));
  return(PConvAutoNone(result));  
#endif
}

PyObject *ObjectGadgetAsPyList(ObjectGadget *I)
{
#ifdef _PYMOL_NOPY
  return NULL;
#else

  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));  
#endif
}

void ObjectGadgetPurge(ObjectGadget *I)
{
  int a;

  SceneObjectDel(I->Obj.G,(CObject*)I);
  for(a=0;a<I->NGSet;a++)
       if(I->GSet[a]) {
      if(I->GSet[a]->fFree)
        I->GSet[a]->fFree(I->GSet[a]);
            I->GSet[a]=NULL;
       }
  VLAFreeP(I->GSet);
  ObjectPurge(&I->Obj);
}

void ObjectGadgetFree(ObjectGadget *I) {
  ObjectGadgetPurge(I);
  OOFreeP(I);
}

void ObjectGadgetUpdateStates(ObjectGadget *I)
{
  int a;
  OrthoBusyPrime(I->Obj.G);
  for(a=0;a<I->NGSet;a++)
    if(I->GSet[a]) {    
      OrthoBusySlow(I->Obj.G,a,I->NGSet);
      /*       printf(" ObjectGadget: updating state %d of \"%s\".\n" , a+1, I->Obj.Name);*/
      if(I->GSet[a]->fUpdate)
        I->GSet[a]->fUpdate(I->GSet[a]);
    }
}

/*========================================================================*/
void ObjectGadgetUpdate(ObjectGadget *I)
{
  if(I->Changed) {
    ObjectGadgetUpdateStates(I);
    ObjectGadgetUpdateExtents(I);
    I->Changed=false;
  }
}

/*========================================================================*/

static int ObjectGadgetGetNState(ObjectGadget *I) {
  return(I->NGSet);
}

/*========================================================================*/
void ObjectGadgetRender(ObjectGadget *I,int state,CRay *ray,Pickable **pick,int pass)
{
  int a;
  if(!pass) {

    ObjectPrepareContext(&I->Obj,ray);
    if(state<0) {
      for(a=0;a<I->NGSet;a++)
        if(I->GSet[a])
          if(I->GSet[a]->fRender)
            I->GSet[a]->fRender(I->GSet[a],ray,pick,pass);        
    } else if(state<I->NGSet) {
      I->CurGSet=state;
      if(I->GSet[I->CurGSet]) {
        if(I->GSet[I->CurGSet]->fRender)
          I->GSet[I->CurGSet]->fRender(I->GSet[I->CurGSet],ray,pick,pass);
      }
    } else if(I->NGSet==1) { /* if only one coordinate set, assume static */
      if(I->GSet[0]->fRender)
        I->GSet[0]->fRender(I->GSet[0],ray,pick,pass);    
      I->CurGSet=0;
    }
  }
}

/*========================================================================*/
void ObjectGadgetInit(PyMOLGlobals *G,ObjectGadget *I)
{
  ObjectInit(G,(CObject*)I);

  I->Obj.type=cObjectGadget;
  I->GSet=VLAMalloc(10,sizeof(GadgetSet*),5,true); /* auto-zero */
  I->NGSet=0;
  I->Changed=true;

  I->Obj.fFree = (void (*)(struct CObject *))ObjectGadgetFree;
  I->Obj.fUpdate =(void (*)(struct CObject *)) ObjectGadgetUpdate;
  I->Obj.fRender =(void (*)(struct CObject *, int, CRay *, Pickable **,int))ObjectGadgetRender;
  I->Obj.fGetNFrame = (int (*)(struct CObject *)) ObjectGadgetGetNState;
  I->Obj.fDescribeElement = NULL;
  I->CurGSet=0;
}

/*========================================================================*/
ObjectGadget *ObjectGadgetNew(PyMOLGlobals *G)
{
  OOAlloc(G,ObjectGadget);

  ObjectGadgetInit(G,I);
  return(I);
}

#if 0

/*========================================================================*/
CGO *ObjectGadgetPyListFloatToCGO(PyObject *list)
{
#ifdef _PYMOL_NOPY
  return NULL;
#else

  CGO *cgo=NULL;
  int len;
  int ok = true;
  int result;
  float *raw=NULL;
  if(PyList_Check(list)) {
    len = PConvPyListToFloatArray(list,&raw);
    if(len<0) len = 0;
    if(raw) {
      if(ok) {
        cgo=CGONewSized(G,len);
        if(cgo) {
          result = CGOFromFloatArray(cgo,raw,len);
          if(result) {
            PRINTF " FloatToCGO: error encountered on element %d\n", result ENDF(G);
          }
          CGOStop(cgo);
        }
      }
      FreeP(raw);
    }
  }
  return(cgo);
#endif
}


ObjectGadget *ObjectGadgetFromCGO(PyMOLGlobals *G,ObjectGadget *obj,CGO *cgo,int state)
{
  ObjectGadget *I = NULL;
  int est;

  if(obj) {
    if(obj->Obj.type!=cObjectGadget) /* TODO: handle this */
      obj=NULL;
  }
  if(!obj) {
    I=ObjectGadgetNew(G);
  } else {
    I=obj;
  }
  if(state<0) state=I->NState;
  if(I->NState<=state) {
    VLACheck(I->State,ObjectGadgetState,state);
    I->NState=state+1;
  }

  if(I->State[state].std) {
    CGOFree(I->State[state].std);
  }
  if(I->State[state].ray) {
    CGOFree(I->State[state].ray);
  }
  est=CGOCheckComplex(cgo);
  if(est) {
    I->State[state].ray=cgo;
    I->State[state].std=CGOSimplify(cgo,est);
  } else 
    I->State[state].std=cgo;
  if(I) {
    ObjectGadgetRecomputeExtent(I);
  }
  SceneChanged(G);
  SceneCountFrames(G);
  return(I);
}


/*========================================================================*/
ObjectGadget *ObjectGadgetDefine(PyMOLGlobals *G,ObjectGadget *obj,PyObject *pycgo,int state)
{ /* assumes blocked interpreter */
#ifdef _PYMOL_NOPY
  return NULL;
#else
  ObjectGadget *I = NULL;

  CGO *cgo,*font_cgo;
  int est;

  if(obj) {
    if(obj->Obj.type!=cObjectGadget) /* TODO: handle this */
      obj=NULL;
  }
  if(!obj) {
    I=ObjectGadgetNew(G);
  } else {
    I=obj;
  }
  I->GadgetType = cGadgetPlain;

  if(state<0) state=I->NState;
  if(I->NState<=state) {
    VLACheck(I->State,ObjectGadgetState,state);
    I->NState=state+1;
  }

  if(I->State[state].std) {
    CGOFree(I->State[state].std);
  }
  if(I->State[state].ray) {
    CGOFree(I->State[state].ray);
  }
  if(PyList_Check(pycgo)) {
    if(PyList_Size(pycgo)) {
      if(PyFloat_Check(PyList_GetItem(pycgo,0))) {
        cgo=ObjectGadgetPyListFloatToCGO(pycgo);
        if(cgo) {
          est=CGOCheckForText(cgo);
          if(est) {
            font_cgo = CGODrawText(cgo,est,NULL);
            CGOFree(cgo);
            cgo=font_cgo;
          }
          est=CGOCheckComplex(cgo);
          if(est) {
            I->State[state].ray=cgo;
            I->State[state].std=CGOSimplify(cgo,est);
          } else 
            I->State[state].std=cgo;
          
        } else {
          ErrMessage(G,"ObjectGadget","could not parse CGO List.");
        }
      }
    }
  }
  if(I) {
    ObjectGadgetRecomputeExtent(I);
  }
  SceneChanged(G);
  SceneCountFrames(G);
  return(I);
#endif

}
#endif

Generated by  Doxygen 1.6.0   Back to index