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; }
CGO *CrystalGetUnitCellCGO(CCrystal * I) { PyMOLGlobals *G = I->G; float v[3]; CGO *cgo = NULL; if(I) { cgo = CGONew(G); #ifndef PURE_OPENGL_ES_2 CGODisable(cgo, GL_LIGHTING); #endif #ifdef _PYMOL_CGO_DRAWARRAYS { int nverts = 10, pl = 0; float *vertexVals; vertexVals = CGODrawArrays(cgo, GL_LINE_STRIP, CGO_VERTEX_ARRAY, nverts); set3f(v, 0, 0, 0); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 1, 0, 0); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 1, 1, 0); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 0, 1, 0); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 0, 0, 0); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 0, 0, 1); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 1, 0, 1); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 1, 1, 1); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 0, 1, 1); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 0, 0, 1); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; } { int nverts = 6, pl = 0; float *vertexVals; vertexVals = CGODrawArrays(cgo, GL_LINES, CGO_VERTEX_ARRAY, nverts); set3f(v, 0, 1, 0); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 0, 1, 1); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 1, 1, 0); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 1, 1, 1); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 1, 0, 0); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; set3f(v, 1, 0, 1); transform33f3f(I->FracToReal, v, v); vertexVals[pl++] = v[0]; vertexVals[pl++] = v[1]; vertexVals[pl++] = v[2]; } #else CGOBegin(cgo, GL_LINE_STRIP); set3f(v, 0, 0, 0); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 1, 0, 0); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 1, 1, 0); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 0, 1, 0); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 0, 0, 0); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 0, 0, 1); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 1, 0, 1); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 1, 1, 1); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 0, 1, 1); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 0, 0, 1); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); CGOEnd(cgo); CGOBegin(cgo, GL_LINES); set3f(v, 0, 1, 0); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 0, 1, 1); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 1, 1, 0); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 1, 1, 1); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 1, 0, 0); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); set3f(v, 1, 0, 1); transform33f3f(I->FracToReal, v, v); CGOVertexv(cgo, v); CGOEnd(cgo); #endif #ifndef PURE_OPENGL_ES_2 CGOEnable(cgo, GL_LIGHTING); #endif CGOStop(cgo); } return (cgo); }