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;
}
Exemple #2
0
Rep *RepLabelNew(CoordSet * cs, int state)
{
  PyMOLGlobals *G = cs->State.G;
  ObjectMolecule *obj;
  int a, a1, vFlag, c1;
  float *v, *v0, *vc;
  float *lab_pos;
  int *l;
  int label_color;
  LabPosType *lp = NULL;
  Pickable *rp = NULL;
  AtomInfoType *ai;
  OOAlloc(G, RepLabel);
  RepLabelInit(I);
  obj = cs->Obj;
  vFlag = false;
  if(obj->RepVisCache[cRepLabel])
    for(a = 0; a < cs->NIndex; a++) {
      if(obj->AtomInfo[cs->IdxToAtm[a]].visRep[cRepLabel]) {
        vFlag = true;
        break;
      }
    }
  if(!vFlag) {
    OOFreeP(I);
    return (NULL);              /* skip if no label are visible */
  }

  label_color = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_label_color);
  RepInit(G, &I->R);

  obj = cs->Obj;
  I->R.fRender = (void (*)(struct Rep *, RenderInfo *)) RepLabelRender;
  I->R.fFree = (void (*)(struct Rep *)) RepLabelFree;
  I->R.fRecolor = NULL;
  I->R.obj = (CObject *) obj;
  I->R.cs = cs;
  I->R.context.object = (void *) obj;
  I->R.context.state = state;

  /* raytracing primitives */

  I->L = Alloc(int, cs->NIndex);
  ErrChkPtr(G, I->L);
  I->V = (float *) mmalloc(sizeof(float) * cs->NIndex * 9);
  ErrChkPtr(G, I->V);

  I->OutlineColor =
    SettingGet_color(G, cs->Setting, obj->Obj.Setting, cSetting_label_outline_color);

  lab_pos = SettingGet_3fv(G, cs->Setting, obj->Obj.Setting, cSetting_label_position);

  if(SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_pickable)) {
    I->R.P = Alloc(Pickable, cs->NIndex + 1);
    ErrChkPtr(G, I->R.P);
    rp = I->R.P + 1;            /* skip first record! */
  }

  I->N = 0;

  v = I->V;
  l = I->L;
  for(a = 0; a < cs->NIndex; a++) {
    a1 = cs->IdxToAtm[a];
    ai = obj->AtomInfo + a1;
    if(cs->LabPos) {
      lp = cs->LabPos + a;
    }
    if(ai->visRep[cRepLabel] && (ai->label)) {
      int at_label_color;
      AtomInfoGetSetting_color(G, ai, cSetting_label_color, label_color, &at_label_color);

      /*
         float at_label_pos = lab_pos;

         AtomInfoGetSetting_3fv(G, ai, cSetting_label_position, 
         label_pos, &at_label_pos);
       */

      I->N++;
      if((at_label_color >= 0) ||
         (at_label_color == cColorFront) ||
	 (at_label_color == cColorBack))
        c1 = at_label_color;
      else
        c1 = *(cs->Color + a);
      vc = ColorGet(G, c1);     /* save new color */
      *(v++) = *(vc++);
      *(v++) = *(vc++);
      *(v++) = *(vc++);
      v0 = cs->Coord + 3 * a;
      *(v++) = *(v0++);
      *(v++) = *(v0++);
      *(v++) = *(v0++);
      if(lp) {
        switch (lp->mode) {
        case 1:                /* local absolute positioning, global relative */
          add3f(lp->offset, v - 3, v - 3);
          copy3f(lab_pos, v);
          break;
        default:
          copy3f(lab_pos, v);
          break;
        }
      } else {
        copy3f(lab_pos, v);
      }

      v += 3;
      if(rp) {
        rp->index = a1;
        rp->bond = cPickableLabel;      /* label indicator */
        rp++;
      }
      *(l++) = ai->label;
    }
  }

  if(I->N) {
    I->V = ReallocForSure(I->V, float, (v - I->V));
    I->L = ReallocForSure(I->L, int, (l - I->L));
    if(rp) {
      I->R.P = ReallocForSure(I->R.P, Pickable, (rp - I->R.P));
      I->R.P[0].index = I->N;   /* unnec? */
    }
  } else {