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; }
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); }
static void RepLabelRender(RepLabel * I, RenderInfo * info) { CRay *ray = info->ray; Picking **pick = info->pick; PyMOLGlobals *G = I->R.G; float *v = I->V; int c = I->N; int *l = I->L; int font_id = SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_label_font_id); float font_size = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_label_size); if(ray) { if(c) { char *st; TextSetOutlineColor(G, I->OutlineColor); while(c--) { if(*l) { st = OVLexicon_FetchCString(G->Lexicon, *l); TextSetPosNColor(G, v + 3, v); TextRenderRay(G, ray, font_id, st, font_size, v + 6); } v += 9; l++; } } } else if(G->HaveGUI && G->ValidContext) { if(pick) { Pickable *p = I->R.P; int i; if (I->shaderCGO){ CGORenderGLPicking(I->shaderCGO, pick, &I->R.context, I->R.cs->Setting, I->R.obj->Setting); return; } SceneSetupGLPicking(G); if(c) { char *st; int float_text = SettingGetGlobal_i(G, cSetting_float_labels); if(float_text) glDisable(GL_DEPTH_TEST); i = (*pick)->src.index; while(c--) { if(*l) { int first_pass = (!(*pick)[0].src.bond); i++; TextSetPosNColor(G, v + 3, v); TextSetPickColor(G, first_pass, i); if(first_pass) { VLACheck((*pick), Picking, i); p++; (*pick)[i].src = *p; /* copy object and atom info */ (*pick)[i].context = I->R.context; } st = OVLexicon_FetchCString(G->Lexicon, *l); TextRenderOpenGL(G, info, font_id, st, font_size, v + 6, SHADERCGO); } l++; v += 9; } if(float_text) glEnable(GL_DEPTH_TEST); (*pick)[0].src.index = i; /* pass the count */ } } else { if(c) { char *st; int float_text = SettingGetGlobal_i(G, cSetting_float_labels); short use_shader; Pickable *p = I->R.P; use_shader = SettingGetGlobal_b(G, cSetting_use_shaders); if(float_text) glDisable(GL_DEPTH_TEST); if (use_shader){ if (!I->shaderCGO){ I->shaderCGO = CGONew(G); if (use_shader){ I->shaderCGO->use_shader = true; I->shaderCGO->enable_shaders = true; } } else { CGORenderGL(I->shaderCGO, NULL, NULL, NULL, info, &I->R); if(float_text) glEnable(GL_DEPTH_TEST); return; } } else if (I->shaderCGO) { CGOFree(I->shaderCGO); I->shaderCGO = NULL; } TextSetOutlineColor(G, I->OutlineColor); while(c--) { if(*l) { p++; if (I->shaderCGO) CGOPickColor(I->shaderCGO, p->index, p->bond); TextSetPosNColor(G, v + 3, v); st = OVLexicon_FetchCString(G->Lexicon, *l); TextRenderOpenGL(G, info, font_id, st, font_size, v + 6, SHADERCGO); } l++; v += 9; } if (I->shaderCGO){ CGO *convertcgo; CGOStop(I->shaderCGO); convertcgo = CGOOptimizeLabels(I->shaderCGO, 0); CGOFree(I->shaderCGO); I->shaderCGO = convertcgo; convertcgo = NULL; if (I->shaderCGO){ I->shaderCGO->use_shader = true; I->shaderCGO->enable_shaders = true; CGORenderGL(I->shaderCGO, NULL, NULL, NULL, info, &I->R); } } if(float_text) glEnable(GL_DEPTH_TEST); } } } }