예제 #1
0
static int RepWireBondCGOGenerate(RepWireBond * I, RenderInfo * info)
{
  PyMOLGlobals *G = I->R.G;
  CGO *convertcgo = NULL;
  int ok = true;
  short line_as_cylinders = 0;
  line_as_cylinders = SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_render_as_cylinders) && SettingGetGlobal_b(G, cSetting_line_as_cylinders);

  {
    if (ok && I->primitiveCGO){
      if (line_as_cylinders){
        CGO *tmpCGO = CGONew(G);

        if (ok) ok &= CGOEnable(tmpCGO, GL_CYLINDER_SHADER);
        if (ok) ok &= CGOSpecial(tmpCGO, CYLINDER_WIDTH_FOR_REPWIRE);
        convertcgo = CGOConvertLinesToCylinderShader(I->primitiveCGO, tmpCGO);
        I->shaderCGO_has_cylinders = true;

        if (ok) ok &= CGOAppendNoStop(tmpCGO, convertcgo);

        if (ok) ok &= CGODisable(tmpCGO, GL_CYLINDER_SHADER);
        if (ok) ok &= CGOStop(tmpCGO);
        CGOFreeWithoutVBOs(convertcgo);
        convertcgo = tmpCGO;
      } else {
        bool trilines = SettingGetGlobal_b(G, cSetting_trilines);
        CGO *tmpCGO = CGONew(G), *tmp2CGO;
        int shader = trilines ? GL_TRILINES_SHADER : GL_LINE_SHADER;

        if (ok) ok &= CGOEnable(tmpCGO, shader);
        if (ok) ok &= CGODisable(tmpCGO, CGO_GL_LIGHTING);
        if (trilines) {
          if (ok) ok &= CGOSpecial(tmpCGO, LINEWIDTH_DYNAMIC_WITH_SCALE);
          tmp2CGO = CGOConvertToTrilinesShader(I->primitiveCGO, tmpCGO);
        } else {
          tmp2CGO = CGOConvertToLinesShader(I->primitiveCGO, tmpCGO);
        }
        if (ok) ok &= CGOAppendNoStop(tmpCGO, tmp2CGO);
        if (ok) ok &= CGODisable(tmpCGO, shader);
        if (ok) ok &= CGOStop(tmpCGO);
        CGOFreeWithoutVBOs(tmp2CGO);
        convertcgo = tmpCGO;
      }
      convertcgo->use_shader = true;
    }
    CGOFree(I->shaderCGO);
    I->shaderCGO = convertcgo;
    CHECKOK(ok, I->shaderCGO);
  }
  return ok;
}
예제 #2
0
static int do_test_fdtdec(cmd_tbl_t *cmdtp, int flag, int argc,
			  char * const argv[])
{
	/* basic tests */
	CHECKOK(run_test("", "", ""));
	CHECKOK(run_test("1e 3d", "", ""));

	/*
	 * 'a' represents 0, 'b' represents 1, etc.
	 * The first character is the alias number, the second is the node
	 * number. So the params mean:
	 * 0a 1b	: point alias 0 to node 0 (a), alias 1 to node 1(b)
	 * ab		: to create nodes 0 and 1 (a and b)
	 * ab		: we expect the function to return two nodes, in
	 *		  the order 0, 1
	 */
	CHECKOK(run_test("0a 1b", "ab", "ab"));

	CHECKOK(run_test("0a 1c", "ab", "ab"));
	CHECKOK(run_test("1c", "ab", "ab"));
	CHECKOK(run_test("1b", "ab", "ab"));
	CHECKOK(run_test("0b", "ab", "ba"));
	CHECKOK(run_test("0b 2d", "dbc", "bcd"));
	CHECKOK(run_test("0d 3a 1c 2b", "dbac", "dcba"));

	/* things with holes */
	CHECKOK(run_test("1b 3d", "dbc", "cb d"));
	CHECKOK(run_test("1e 3d", "dbc", "bc d"));

	/* no aliases */
	CHECKOK(run_test("", "dbac", "dbac"));

	/* disabled nodes */
	CHECKOK(run_test("0d 3a 1c 2b", "dBac", "dc a"));
	CHECKOK(run_test("0b 2d", "DBc", "c"));
	CHECKOK(run_test("0b 4d 2c", "DBc", "  c"));

	/* conflicting aliases - first one gets it */
	CHECKOK(run_test("2a 1a 0a", "a", "  a"));
	CHECKOK(run_test("0a 1a 2a", "a", "a"));

	printf("Test passed\n");
	return 0;
}
예제 #3
0
Rep *RepWireBondNew(CoordSet * cs, int state)
{
  PyMOLGlobals *G = cs->State.G;
  ObjectMolecule *obj = cs->Obj;
  int a1, a2;
  unsigned int b1, b2;
  int a, c1, c2, ord;
  bool s1, s2;
  BondType *b;
  int half_bonds, *other = NULL;
  float valence;
  float *v1, *v2;
  int visFlag;
  float line_width;
  int valence_flag = false;
  AtomInfoType *ai1;
  int cartoon_side_chain_helper = 0;
  int ribbon_side_chain_helper = 0;
  int line_stick_helper = 0;
  int na_mode;
  bool *marked = NULL;
  int valence_found = false;
  int variable_width = false;
  float last_line_width = -1.f;
  int line_color;
  int hide_long = false;
  int fancy;
  const float _0p9 = 0.9F;
  int ok = true;
  unsigned int line_counter = 0;
  OOAlloc(G, RepWireBond);
  CHECKOK(ok, I);
  PRINTFD(G, FB_RepWireBond)
    " RepWireBondNew-Debug: entered.\n" ENDFD;

  visFlag = false;
  b = obj->Bond;
  ai1 = obj->AtomInfo;
  if(ok && GET_BIT(obj->RepVisCache,cRepLine)){
    for(a = 0; a < obj->NBond; a++) {
      b1 = b->index[0];
      b2 = b->index[1];
      if((cRepLineBit & ai1[b1].visRep & ai1[b2].visRep)) {
        visFlag = true;
        break;
      }
      b++;
    }
  }
  if(!visFlag) {
    OOFreeP(I);
    return (NULL);              /* skip if no dots are visible */
  }
  marked = pymol::calloc<bool>(obj->NAtom);
  CHECKOK(ok, marked);
  if (!ok){
    OOFreeP(I);
    return (NULL);
  }
  
  valence_flag = SettingGet_b(G, cs->Setting, obj->Obj.Setting, cSetting_valence);
  valence = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_valence_size);
  cartoon_side_chain_helper = SettingGet_b(G, cs->Setting, obj->Obj.Setting,
					   cSetting_cartoon_side_chain_helper);
  ribbon_side_chain_helper = SettingGet_b(G, cs->Setting, obj->Obj.Setting,
					  cSetting_ribbon_side_chain_helper);
  line_stick_helper = SettingGet_b(G, cs->Setting, obj->Obj.Setting,
				   cSetting_line_stick_helper);
  line_color = SettingGet_color(G, cs->Setting, obj->Obj.Setting, cSetting_line_color);
  line_width = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_line_width);
  
  if(line_stick_helper && (SettingGet_f(G, cs->Setting, obj->Obj.Setting,
					cSetting_stick_transparency) > R_SMALL4))
    line_stick_helper = false;
  half_bonds = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_half_bonds);
  hide_long = SettingGet_b(G, cs->Setting, obj->Obj.Setting, cSetting_hide_long_bonds);
  na_mode =
    SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_cartoon_nucleic_acid_mode);
  int na_mode_ribbon =
    SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_ribbon_nucleic_acid_mode);
  fancy = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_valence_mode) == 1;
  auto valence_zero_mode =
    SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_valence_zero_mode);
  
  b = obj->Bond;
  
  for(a = 0; a < obj->NBond; a++) {
    b1 = b->index[0];
    b2 = b->index[1];

    if(obj->DiscreteFlag) {
      if((cs == obj->DiscreteCSet[b1]) && (cs == obj->DiscreteCSet[b2])) {
        a1 = obj->DiscreteAtmToIdx[b1];
        a2 = obj->DiscreteAtmToIdx[b2];
      } else {
        a1 = -1;
        a2 = -1;
      }
    } else {
      a1 = cs->AtmToIdx[b1];
      a2 = cs->AtmToIdx[b2];
    }
    if((a1 >= 0) && (a2 >= 0)) {
      if(!variable_width)
        if (AtomInfoCheckBondSetting(G, b, cSetting_line_width)){
          variable_width = true;
          if (valence_found) break;
        }
      auto bd_valence_flag = BondSettingGetWD(G, b, cSetting_valence, valence_flag);
      if(bd_valence_flag) {
        valence_found = true;
        if (variable_width) break;
      }
    }
    b++;
  }

  RepInit(G, &I->R);

  I->R.fRender = (void (*)(struct Rep *, RenderInfo * info)) RepWireBondRender;
  I->R.fFree = (void (*)(struct Rep *)) RepWireBondFree;

  I->shaderCGO = 0;
  I->shaderCGO_has_cylinders = 0;
  I->R.P = NULL;
  I->R.fRecolor = NULL;
  I->R.context.object = (void *) obj;
  I->R.context.state = state;
  I->R.cs = cs;

  I->primitiveCGO = CGONew(G);

  CGOSpecialWithArg(I->primitiveCGO, LINE_LIGHTING, 0.f);

  CGOSpecial(I->primitiveCGO, LINEWIDTH_FOR_LINES);
  CGOBegin(I->primitiveCGO, GL_LINES);

  if(obj->NBond) {

    if(valence_found)           /* build list of up to 2 connected atoms for each atom */
      other = ObjectMoleculeGetPrioritizedOtherIndexList(obj, cs);

    if(ok && (cartoon_side_chain_helper || ribbon_side_chain_helper)) {
      SideChainHelperMarkNonCartoonBonded(marked, obj, cs,
          cartoon_side_chain_helper,
          ribbon_side_chain_helper);
    }


    b = obj->Bond;

    for(a = 0; ok && a < obj->NBond; ++a, ++b) {
      b1 = b->index[0];
      b2 = b->index[1];
      ord = b->order;

      if (ord == 0 && valence_zero_mode == 0)
        continue;

      if(obj->DiscreteFlag) {
        if((cs == obj->DiscreteCSet[b1]) && (cs == obj->DiscreteCSet[b2])) {
          a1 = obj->DiscreteAtmToIdx[b1];
          a2 = obj->DiscreteAtmToIdx[b2];
        } else {
          a1 = -1;
          a2 = -1;
        }
      } else {
        a1 = cs->AtmToIdx[b1];
        a2 = cs->AtmToIdx[b2];
      }
      if((a1 >= 0) && (a2 >= 0)) {

        AtomInfoType *ati1 = obj->AtomInfo + b1;
        AtomInfoType *ati2 = obj->AtomInfo + b2;

        s1 = (ati1->visRep & cRepLineBit);
        s2 = (ati2->visRep & cRepLineBit);

        if(s1 ^ s2){
          if(!half_bonds) {
            if(line_stick_helper &&
               (((!s1) && (cRepCylBit & ati1->visRep) && !(cRepCylBit & ati2->visRep)) ||
                ((!s2) && (cRepCylBit & ati2->visRep) && !(cRepCylBit & ati1->visRep))))
              s1 = s2 = 1;      /* turn on line when both stick and line are alternately shown */
            else {
              s1 = 0;
              s2 = 0;
            }
          }
        }

        if(hide_long && (s1 || s2)) {
          float cutoff = (ati1->vdw + ati2->vdw) * _0p9;
          v1 = cs->Coord + 3 * a1;
          v2 = cs->Coord + 3 * a2;
          ai1 = obj->AtomInfo + b1;
          if(!within3f(v1, v2, cutoff)) /* atoms separated by more than 90% of the sum of their vdw radii */
            s1 = s2 = 0;
        }

        if(s1 || s2) {
          float rgb1[3], rgb2[3];
          int terminal = false;

          auto bd_valence_flag = BondSettingGetWD(G, b, cSetting_valence, valence_flag);
          auto bd_line_color = BondSettingGetWD(G, b, cSetting_line_color, line_color);

          if(fancy && bd_valence_flag && (b->order > 1)) {
            terminal = IsBondTerminal(obj, b1, b2);
          }

          if(variable_width) {
            auto bd_line_width = BondSettingGetWD(G, b, cSetting_line_width, line_width);
            if (last_line_width!=bd_line_width){
              CGOSpecialWithArg(I->primitiveCGO, LINEWIDTH_FOR_LINES, bd_line_width);
              last_line_width = bd_line_width;
            }
          }

          if(bd_line_color < 0) {
            if(bd_line_color == cColorObject) {
              c1 = (c2 = obj->Obj.Color);
            } else if(ColorCheckRamped(G, bd_line_color)) {
              c1 = (c2 = bd_line_color);
            } else {
              c1 = ati1->color;
              c2 = ati2->color;
            }
          } else {
            c1 = (c2 = bd_line_color);
          }

          v1 = cs->Coord + 3 * a1;
          v2 = cs->Coord + 3 * a2;

          if (line_stick_helper && (ati1->visRep & ati2->visRep & cRepCylBit)) {
            s1 = s2 = 0;
          } else if ((ati1->flags & ati2->flags & cAtomFlag_polymer)) {
            // side chain helpers
            if ((cRepCartoonBit & ati1->visRep & ati2->visRep)) {
              bool sc_helper = AtomSettingGetWD(G, ati1,
                  cSetting_cartoon_side_chain_helper, cartoon_side_chain_helper);

              if (!sc_helper)
                AtomSettingGetIfDefined(G, ati2, cSetting_cartoon_side_chain_helper, &sc_helper);

              if (sc_helper &&
                  SideChainHelperFilterBond(G, marked, ati1, ati2, b1, b2, na_mode, &c1, &c2))
                s1 = s2 = 0;
            }

            if ((s1 || s2) && (cRepRibbonBit & ati1->visRep & ati2->visRep)) {
              bool sc_helper = AtomSettingGetWD(G, ati1,
                  cSetting_ribbon_side_chain_helper, ribbon_side_chain_helper);

              if (!sc_helper)
                AtomSettingGetIfDefined(G, ati2, cSetting_ribbon_side_chain_helper, &sc_helper);

              if (sc_helper &&
                  SideChainHelperFilterBond(G, marked, ati1, ati2, b1, b2, na_mode_ribbon, &c1, &c2))
                s1 = s2 = 0;
            }
          }

          bool isRamped = false;
          isRamped = ColorGetCheckRamped(G, c1, v1, rgb1, state);
          isRamped = ColorGetCheckRamped(G, c2, v2, rgb2, state) | isRamped;
          if (s1 || s2){
            if (ord == 0 && valence_zero_mode == 2) {
              ord = 1;
            }

            if (!ord){
              RepWireZeroOrderBond(I->primitiveCGO, s1, s2, v1, v2, rgb1, rgb2, b1, b2, a, .15f, .15f, ati1->masked, ati2->masked);
            } else if (!bd_valence_flag || ord <= 1){
              RepLine(I->primitiveCGO, s1, s2, isRamped, v1, v2, rgb1, b1, b2, a, rgb2, ati1->masked, ati2->masked);
            } else {
              if (ord == 4){
                RepAromatic(I->primitiveCGO, s1, s2, isRamped, v1, v2, other, a1, a2, cs->Coord, rgb1, rgb2, valence, 0, b1, b2, a, ati1->masked, ati2->masked);
              } else {
                RepValence(I->primitiveCGO, s1, s2, isRamped, v1, v2, other, a1, a2, cs->Coord, rgb1, rgb2, ord, valence, fancy && !terminal, b1, b2, a, ati1->masked, ati2->masked);
              }
            }
            line_counter++;
          }
        }
      }
      ok &= !G->Interrupt;
    }
  }
  CGOEnd(I->primitiveCGO);
  CGOSpecialWithArg(I->primitiveCGO, LINE_LIGHTING, 1.f);
  CGOStop(I->primitiveCGO);
  FreeP(marked);
  FreeP(other);
  if (!ok || !line_counter){
    RepWireBondFree(I);
    I = NULL;
  }
  return (Rep *) I;
}
예제 #4
0
파일: Util.c 프로젝트: baoboa/pymol
int UtilSemiSortFloatIndex(int n,float *array,int *x, int forward)
{
  /* approximate sort, for quick handling of transparency values */
  /* this sort uses 2 arrays start1 and next1 to keep track of */
  /* the indexes.  The values in start1 are set to the index */
  /* relative to the array value within the min/max values.  If */
  /* there is a collision, the value in next1 is set to the value */
  /* that is collided, and start1[idx] is set to the index plus 1 (a+1) */
  /* This makes it easy to go through the 2 arrays and write into the */
  /* x array the approximate order of the floating point values in array */
  /* by indexes. */
  /* Since there are two arrays of n length, this guarentees that there */
  /* will be enough memory to hold all indexes.  If there are many collisions, */
  /* the next1 array will hold a link to most of the indexes, which are traversed */
  /* when the first index is found in start1.  If there are few collisions, then */
  /* the majority of the start1 array is used. The total number of items used in */
  /* both arrays will always be the number of values, i.e., n. */
  int ok = true;
  if(n>0) {
    register float min,max,*f,v;
    register float range, scale;
    register int a;
    register int *start1;
    register int *next1;
    register int idx1;
    register int n_minus_one;

    start1 = Calloc(int,n*2);
    CHECKOK(ok, start1);
    if (!ok){
      return false;
    }

    next1 = start1 + n;
    max = (min = array[0]);
    f = array + 1;
    for(a=1;a<n;a++) {
      v = *(f++);
      if(max<v) max=v;
      if(min>v) min=v;
    }
    range = (max-min)*1.0001F; /* for boundary conditions */
    if(range<R_SMALL8) { 
      for(a=0;a<n;a++)
        x[a] = a;
    } else {
      scale = n/range;
      f = array;
      /* hash by value (actually binning) */
      if(forward) {
        for(a=0;a<n;a++) {
          idx1 = (int)((*(f++)-min)*scale);
          next1[a] = start1[idx1];
          start1[idx1] = a+1;
        }
      } else {
        n_minus_one = n-1;
        for(a=0;a<n;a++) {
          idx1 = n_minus_one-(int)((*(f++)-min)*scale);
          next1[a] = start1[idx1];
          start1[idx1] = a+1;
        }
      }
      /* now read out */
      {
        register int c=0;
        register int cur1;        
        a=0;
        while(a<n) {
          if( (cur1 = start1[a]) ) {
            idx1 = cur1 - 1;
            while(1) {
              x[c++] = idx1;
              if(! (cur1 = next1[idx1]))
                break;
              idx1 = cur1 - 1;
            }
          }
          a++;
        }
      }
    }
    mfree(start1);
  }
  return true;
}
예제 #5
0
int UtilSemiSortFloatIndexWithNBinsImpl(int *start1, int n, int nbins, float *array, int *destx, int forward)
{
  /* approximate sort, for quick handling of transparency values */
  /* this sort uses 2 arrays start1 and next1 to keep track of */
  /* the indexes.  The values in start1 are set to the index */
  /* relative to the array value within the min/max values.  If */
  /* there is a collision, the value in next1 is set to the value */
  /* that is collided, and start1[idx] is set to the index plus 1 (a+1) */
  /* This makes it easy to go through the 2 arrays and write into the */
  /* x array the approximate order of the floating point values in array */
  /* by indexes. */
  /* Since there are two arrays, this guarentees that there */
  /* will be enough memory to hold all indexes.  If there are many collisions, */
  /* the next1 array will hold a link to most of the indexes, which are traversed */
  /* when the first index is found in start1.  If there are few collisions, then */
  /* the majority of the start1 array is used. The total number of items used in */
  /* both arrays will always be the number of values, i.e., n. */
  /* 9/9/14: BB - added start1 and nbins argument
     start1 - pre-allocated memory
     nbins - allows the first array to be controled as the number of bins, 
             to match how CGORenderGLAlpha() sorts its triangles.
  */
  int ok = true;
  if(n>0) {
    float min,max,*f,v;
    float range, scale;
    int a;
    int *next1;
    int idx1;

    CHECKOK(ok, start1);
    if (!ok){
      return false;
    }

    next1 = start1 + nbins;
    max = (min = array[0]);
    f = array + 1;
    for(a=1;a<n;a++) {
      v = *(f++);
      if(max<v) max=v;
      if(min>v) min=v;
    }
    range = (max-min)/.9999F; /* for boundary conditions */
    if(range<R_SMALL8) { 
      for(a=0;a<n;a++)
        destx[a] = a;
    } else {
      scale = nbins/range;
      f = array;
      /* hash by value (actually binning) */
      if(forward) {
        for(a=0;a<n;a++) {
          idx1 = (int)((*(f++)-min)*scale);
          next1[a] = start1[idx1];
          start1[idx1] = a+1;
        }
      } else {
        for(a=0;a<n;a++) {
          idx1 = (nbins-1) - (int)((*(f++)-min)*scale);
          next1[a] = start1[idx1];
          start1[idx1] = a+1;
        }
      }
      /* now read out */
      {
        int c=0;
        int cur1;        
        a=0;
        while(a<nbins) {
          if( (cur1 = start1[a]) ) {
            idx1 = cur1 - 1;
            while(1) {
              destx[c++] = idx1;
              if(! (cur1 = next1[idx1]))
                break;
              idx1 = cur1 - 1;
            }
          }
          a++;
        }
      }
    }
  }
  return true;
}