static int RepLine(CGO *cgo, bool s1, bool s2, bool isRamped, float *v1, float *v2, float *v1color, unsigned int b1, unsigned int b2, int a, float *v2color, bool b1masked, bool b2masked){ int ok = true; if (s1 && s2){ CGOColorv(cgo, v1color); CGOPickColor(cgo, b1, b1masked ? cPickableNoPick : a); { // if not ramped, then insert vertices so colors are not interpolated since lines interpolate by default bool eq = equal3f(v1color, v2color); bool split = !eq || b1 != b2; if (split){ cgo->add<cgo::draw::splitline>(v1, v2, v2color, b2, b2masked ? cPickableNoPick : a, isRamped, b1==b2, eq); cgo->current_pick_color_index = b2; cgo->current_pick_color_bond = b2masked ? cPickableNoPick : a; } else { cgo->add<cgo::draw::line>(v1, v2); } } } else { // if half bond, then split for either s1 or s2 float h[3]; average3f(v1, v2, h); if (s1){ CGOColorv(cgo, v1color); CGOPickColor(cgo, b1, b1masked ? cPickableNoPick : a); cgo->add<cgo::draw::line>(v1, h); } else { if (v2color) CGOColorv(cgo, v2color); if (b2) CGOPickColor(cgo, b2, b2masked ? cPickableNoPick : a); cgo->add<cgo::draw::line>(h, v2); } } return ok; }
static int RepWireZeroOrderBond(CGO *cgo, bool s1, bool s2, float *v1, float *v2, float *rgb1, float *rgb2, unsigned int b1, unsigned int b2, int a, float dash_gap, float dash_length, bool b1masked, bool b2masked) { int ok = true; float axis[3], naxis[3]; subtract3f(v2, v1, axis); copy3f(axis, naxis); normalize3f(naxis); float blen = length3f(axis); float dash_tot = dash_gap + dash_length; int ndashes = blen / dash_tot; // only do even number of dashes if (ndashes < 2) { ndashes = 2; } else if (ndashes % 2) { --ndashes; } float remspace = blen - (ndashes * dash_length); // remaining space for first gaps float dgap = remspace / (ndashes - 1.f); // endpoints at each vertex, therefore only account for ndashes-1 spaces float placep[3], placep2[3], adddlen[3], adddtot[3]; float dplace; int ndashes_drawn = 0; bool color2_set = false; mult3f(naxis, dash_length, adddlen); // adddlen - length of dash as x/y/z vector mult3f(naxis, dash_length + dgap, adddtot); // adddtot - length of dash plus gap as x/y/z vector copy3f(v1, placep); if (s1){ ok &= CGOColorv(cgo, rgb1); ok &= CGOPickColor(cgo, b1, b1masked ? cPickableNoPick : a); for (dplace = 0.f; (dplace+dash_length) < blen / 2.f; ){ add3f(placep, adddlen, placep2); cgo->add<cgo::draw::line>(placep, placep2); add3f(placep, adddtot, placep); dplace += dash_length + dgap; ++ndashes_drawn; } if (!s2){ if (dplace < blen / 2.f){ // if we are behind the mid-point, only s1, so draw a half-bond add3f(placep, adddlen, placep2); cgo->add<cgo::draw::line>(placep, placep2); add3f(placep, adddtot, placep); dplace += dash_length + dgap; ++ndashes_drawn; } } } else { float tmpp[3]; dplace = (ndashes/2) * (dash_length + dgap); mult3f(naxis, dplace, tmpp); add3f(v1, tmpp, placep); ndashes_drawn = ndashes/2; // if !s1, then definitely s2, so draw half-bond if (dplace <= blen / 2.f){ // if no s1, and we are behind the mid-point, draw half-bond with only s2 add3f(placep, adddlen, placep2); ok &= CGOColorv(cgo, rgb2); ok &= CGOPickColor(cgo, b2, b2masked ? cPickableNoPick : a); color2_set = true; cgo->add<cgo::draw::line>(placep, placep2); add3f(placep, adddtot, placep); dplace += dash_length + dgap; ++ndashes_drawn; } } if (s2){ if (dplace < blen / 2.f){ // if we are behind the mid-point, draw a split cylinder with both colors float tmpp[3]; mult3f(axis, .5f, tmpp); add3f(v1, tmpp, tmpp); cgo->add<cgo::draw::line>(placep, tmpp); add3f(placep, adddlen, placep2); if (!color2_set){ ok &= CGOColorv(cgo, rgb2); ok &= CGOPickColor(cgo, b2, b2masked ? cPickableNoPick : a); } cgo->add<cgo::draw::line>(tmpp, placep2); add3f(placep, adddtot, placep); dplace += dash_length + dgap; ++ndashes_drawn; } else if (!color2_set){ ok &= CGOColorv(cgo, rgb2); ok &= CGOPickColor(cgo, b2, b2masked ? cPickableNoPick : a); } while (ndashes_drawn < ndashes){ add3f(placep, adddlen, placep2); cgo->add<cgo::draw::line>(placep, placep2); add3f(placep, adddtot, placep); dplace += dash_length + dgap; ++ndashes_drawn; } } return ok; }
static void RepAromatic(CGO *cgo, bool s1, bool s2, bool isRamped, float *v1, float *v2, int *other, int a1, int a2, float *coord, float *color1, float *color2, float tube_size, int half_state, unsigned int b1, unsigned int b2, int a, bool b1masked, bool b2masked) { float d[3], t[3], p0[3], p1[3], p2[3], *vv; int a3; int double_sided; /* direction vector */ p0[0] = (v2[0] - v1[0]); p0[1] = (v2[1] - v1[1]); p0[2] = (v2[2] - v1[2]); copy3f(p0, d); normalize3f(p0); /* need a prioritized third atom to get planarity */ a3 = ObjectMoleculeGetPrioritizedOther(other, a1, a2, &double_sided); if(a3 < 0) { t[0] = p0[0]; t[1] = p0[1]; t[2] = -p0[2]; } else { vv = coord + 3 * a3; t[0] = *(vv++) - v1[0]; t[1] = *(vv++) - v1[1]; t[2] = *(vv++) - v1[2]; normalize3f(t); } cross_product3f(d, t, p1); normalize3f(p1); if(length3f(p1) == 0.0) { p1[0] = p0[1]; p1[1] = p0[2]; p1[2] = p0[0]; cross_product3f(p0, p1, p2); normalize3f(p2); } else { cross_product3f(d, p1, p2); normalize3f(p2); } t[0] = p2[0] * tube_size * 2; t[1] = p2[1] * tube_size * 2; t[2] = p2[2] * tube_size * 2; RepLine(cgo, s1, s2, isRamped, v1, v2, color1, b1, b2, a, color2, b1masked, b2masked); if (s1){ CGOColorv(cgo, color1); CGOPickColor(cgo, b1, b1masked ? cPickableNoPick : a); float f[] = { 0.14F, 0.4F } ; float f_1[] = { 1.0F - f[0], 1.0F - f[1] }; float pt1[] = { (f_1[0] * v1[0] + f[0] * v2[0]), (f_1[0] * v1[1] + f[0] * v2[1]), (f_1[0] * v1[2] + f[0] * v2[2]) }; float pt2[] = { (f_1[1] * v1[0] + f[1] * v2[0]), (f_1[1] * v1[1] + f[1] * v2[1]), (f_1[1] * v1[2] + f[1] * v2[2]) }; float p1[3], p2[3]; subtract3f(pt1, t, p1); subtract3f(pt2, t, p2); cgo->add<cgo::draw::line>(p1, p2); if(double_sided) { add3f(pt1, t, p1); add3f(pt2, t, p2); cgo->add<cgo::draw::line>(p1, p2); } } if (s2){ CGOColorv(cgo, color2); CGOPickColor(cgo, b2, b2masked ? cPickableNoPick : a); float f[] = { 0.6F, 0.86F } ; float f_1[] = { 1.0F - f[0], 1.0F - f[1] }; float pt1[] = { (f_1[0] * v1[0] + f[0] * v2[0]), (f_1[0] * v1[1] + f[0] * v2[1]), (f_1[0] * v1[2] + f[0] * v2[2]) }; float pt2[] = { (f_1[1] * v1[0] + f[1] * v2[0]), (f_1[1] * v1[1] + f[1] * v2[1]), (f_1[1] * v1[2] + f[1] * v2[2]) }; float p1[3], p2[3]; subtract3f(pt1, t, p1); subtract3f(pt2, t, p2); cgo->add<cgo::draw::line>(p1, p2); if(double_sided) { add3f(pt1, t, p1); add3f(pt2, t, p2); cgo->add<cgo::draw::line>(p1, p2); } } }
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); } } } }