void ObjectCallbackRecomputeExtent(ObjectCallback * I) { int extent_flag = false; #ifndef _PYMOL_NOPY float mx[3], mn[3]; int a; PyObject *py_ext; for(a = 0; a < I->NState; a++) if(I->State[a].PObj) { if(PyObject_HasAttrString(I->State[a].PObj, "get_extent")) { py_ext = PYOBJECT_CALLMETHOD(I->State[a].PObj, "get_extent", ""); if(PyErr_Occurred()) PyErr_Print(); if(py_ext) { if(PConvPyListToExtent(py_ext, mn, mx)) { if(!extent_flag) { extent_flag = true; copy3f(mx, I->Obj.ExtentMax); copy3f(mn, I->Obj.ExtentMin); } else { max3f(mx, I->Obj.ExtentMax, I->Obj.ExtentMax); min3f(mn, I->Obj.ExtentMin, I->Obj.ExtentMin); } } Py_DECREF(py_ext); } } } #endif I->Obj.ExtentFlag = extent_flag; }
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); 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_i(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 {
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 RepValence(CGO *cgo, bool s1, bool s2, bool isRamped, float *v1, float *v2, int *other, int a1, int a2, float *coord, float *color1, float *color2, int ord, float tube_size, int fancy, unsigned int b1, unsigned int b2, int a, bool b1masked, bool b2masked) { float d[3], t[3], p0[3], p1[3], p2[3]; int a3; const float indent = tube_size; /* direction vector */ subtract3f(v2, v1, p0); copy3f(p0, d); normalize3f(p0); /* need a prioritized third atom to get planarity */ a3 = ObjectMoleculeGetPrioritizedOther(other, a1, a2, NULL); if(a3 < 0) { t[0] = p0[0]; t[1] = p0[1]; t[2] = -p0[2]; } else { subtract3f(coord + 3 * a3, v1, t); 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); } /* now we have a coordinate system */ mult3f(p2, tube_size, t); bool ord3 = (ord == 3); if (ord3) mult3f(t, 2.f, t); if (fancy || ord3){ RepLine(cgo, s1, s2, isRamped, v1, v2, color1, b1, b2, a, color2, b1masked, b2masked); } if(fancy) { float f[] = { indent, 1.f - indent }; float f_1[] = { 1.f - f[0], 1.f - f[1] }; float vv1[] = { (f_1[0] * v1[0] + f[0] * v2[0]) - 2 * t[0], (f_1[0] * v1[1] + f[0] * v2[1]) - 2 * t[1], (f_1[0] * v1[2] + f[0] * v2[2]) - 2 * t[2] }; float vv2[] = { (f_1[1] * v1[0] + f[1] * v2[0]) - 2 * t[0], (f_1[1] * v1[1] + f[1] * v2[1]) - 2 * t[1], (f_1[1] * v1[2] + f[1] * v2[2]) - 2 * t[2] }; RepLine(cgo, s1, s2, isRamped, vv1, vv2, color1, b1, b2, a, color2, b1masked, b2masked); } else { float vv1[][3] = { { v1[0] - t[0], v1[1] - t[1], v1[2] - t[2] }, { v1[0] + t[0], v1[1] + t[1], v1[2] + t[2] } }; float vv2[][3] = { { v2[0] - t[0], v2[1] - t[1], v2[2] - t[2] }, { v2[0] + t[0], v2[1] + t[1], v2[2] + t[2] } }; RepLine(cgo, s1, s2, isRamped, vv1[0], vv2[0], color1, b1, b2, a, color2, b1masked, b2masked); RepLine(cgo, s1, s2, isRamped, vv1[1], vv2[1], color1, b1, b2, a, color2, b1masked, b2masked); } }
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); } } }