RepWireBond.cpp (pymol-v2.1.0.tar.bz2) | : | RepWireBond.cpp (pymol-open-source-2.2.0) | ||
---|---|---|---|---|
skipping to change at line 33 | skipping to change at line 33 | |||
#include"SideChainHelper.h" | #include"SideChainHelper.h" | |||
#include"Color.h" | #include"Color.h" | |||
#include"Scene.h" | #include"Scene.h" | |||
#include"main.h" | #include"main.h" | |||
#include"Setting.h" | #include"Setting.h" | |||
#include"ShaderMgr.h" | #include"ShaderMgr.h" | |||
#include"CGO.h" | #include"CGO.h" | |||
typedef struct RepWireBond { | typedef struct RepWireBond { | |||
Rep R; | Rep R; | |||
float *V, *VP; | ||||
/* Pickable *P; */ | ||||
int N, NP; | ||||
float Width, *VarWidth; | ||||
float Radius; | ||||
CGO *shaderCGO; | CGO *shaderCGO; | |||
CGO *primitiveCGO; | ||||
bool shaderCGO_has_cylinders; | ||||
} RepWireBond; | } RepWireBond; | |||
#include"ObjectMolecule.h" | #include"ObjectMolecule.h" | |||
void RepWireBondFree(RepWireBond * I); | void RepWireBondFree(RepWireBond * I); | |||
static void RepValence(float *v, float *v1, float *v2, int *other, int a1, | ||||
int a2, float *coord, float *color, int ord, | static int RepLine(CGO *cgo, bool s1, bool s2, bool isRamped, float *v1, float * | |||
float tube_size, int half_state, int fancy); | v2, float *v1color, unsigned int b1, unsigned int b2, int a, float *v2color, boo | |||
l b1masked, bool b2masked){ | ||||
static void RepAromatic(float *v1, float *v2, int *other, | int ok = true; | |||
int a1, int a2, float *coord, float *color, | if (s1 && s2){ | |||
float tube_size, int half_state, float **v_ptr, int *n_p | CGOColorv(cgo, v1color); | |||
tr) | CGOPickColor(cgo, b1, b1masked ? cPickableNoPick : a); | |||
{ | ||||
// if not ramped, then insert vertices so colors are not interpolated sinc | ||||
e 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 ? cPickable | ||||
NoPick : 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 void RepValence(CGO *cgo, bool s1, bool s2, bool isRamped, float *v1, flo | ||||
at *v2, int *other, | ||||
int a1, int a2, float *coord, float *color1, float *color | ||||
2, 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, b1 | ||||
masked, b2masked); | ||||
RepLine(cgo, s1, s2, isRamped, vv1[1], vv2[1], color1, b1, b2, a, color2, b1 | ||||
masked, b2masked); | ||||
} | ||||
} | ||||
static void RepAromatic(CGO *cgo, bool s1, bool s2, bool isRamped, float *v1, fl | ||||
oat *v2, int *other, | ||||
int a1, int a2, float *coord, float *color1, float *colo | ||||
r2, | ||||
float tube_size, int half_state, unsigned int b1, unsign | ||||
ed int b2, int a, bool b1masked, bool b2masked) | ||||
{ | { | |||
float d[3], t[3], p0[3], p1[3], p2[3], *vv; | float d[3], t[3], p0[3], p1[3], p2[3], *vv; | |||
int a3; | int a3; | |||
float *v = *v_ptr; | ||||
float f, f_1; | ||||
int n = *n_ptr; | ||||
int double_sided; | int double_sided; | |||
v[0] = color[0]; | ||||
v[1] = color[1]; | ||||
v[2] = color[2]; | ||||
v[9] = color[0]; | ||||
v[10] = color[1]; | ||||
v[11] = color[2]; | ||||
/* direction vector */ | /* direction vector */ | |||
p0[0] = (v2[0] - v1[0]); | p0[0] = (v2[0] - v1[0]); | |||
p0[1] = (v2[1] - v1[1]); | p0[1] = (v2[1] - v1[1]); | |||
p0[2] = (v2[2] - v1[2]); | p0[2] = (v2[2] - v1[2]); | |||
copy3f(p0, d); | copy3f(p0, d); | |||
normalize3f(p0); | normalize3f(p0); | |||
/* need a prioritized third atom to get planarity */ | /* need a prioritized third atom to get planarity */ | |||
a3 = ObjectMoleculeGetPrioritizedOther(other, a1, a2, &double_sided); | a3 = ObjectMoleculeGetPrioritizedOther(other, a1, a2, &double_sided); | |||
if(a3 < 0) { | if(a3 < 0) { | |||
t[0] = p0[0]; | t[0] = p0[0]; | |||
t[1] = p0[1]; | t[1] = p0[1]; | |||
t[2] = -p0[2]; | t[2] = -p0[2]; | |||
} else { | } else { | |||
vv = coord + 3 * a3; | vv = coord + 3 * a3; | |||
t[0] = *(vv++) - v1[0]; | t[0] = *(vv++) - v1[0]; | |||
t[1] = *(vv++) - v1[1]; | t[1] = *(vv++) - v1[1]; | |||
t[2] = *(vv++) - v1[2]; | t[2] = *(vv++) - v1[2]; | |||
normalize3f(t); | normalize3f(t); | |||
} | } | |||
cross_product3f(d, t, p1); | cross_product3f(d, t, p1); | |||
normalize3f(p1); | normalize3f(p1); | |||
if(length3f(p1) == 0.0) { | if(length3f(p1) == 0.0) { | |||
p1[0] = p0[1]; | p1[0] = p0[1]; | |||
p1[1] = p0[2]; | p1[1] = p0[2]; | |||
p1[2] = p0[0]; | p1[2] = p0[0]; | |||
cross_product3f(p0, p1, p2); | cross_product3f(p0, p1, p2); | |||
normalize3f(p2); | normalize3f(p2); | |||
} else { | } else { | |||
cross_product3f(d, p1, p2); | cross_product3f(d, p1, p2); | |||
normalize3f(p2); | normalize3f(p2); | |||
} | } | |||
switch (half_state) { | ||||
case 0: /* full bond */ | ||||
t[0] = p2[0] * tube_size * 2; | t[0] = p2[0] * tube_size * 2; | |||
t[1] = p2[1] * tube_size * 2; | t[1] = p2[1] * tube_size * 2; | |||
t[2] = p2[2] * tube_size * 2; | t[2] = p2[2] * tube_size * 2; | |||
RepLine(cgo, s1, s2, isRamped, v1, v2, color1, b1, b2, a, color2, b1masked, b2 | ||||
v[0] = color[0]; | masked); | |||
v[1] = color[1]; | if (s1){ | |||
v[2] = color[2]; | CGOColorv(cgo, color1); | |||
CGOPickColor(cgo, b1, b1masked ? cPickableNoPick : a); | ||||
v[3] = v1[0]; | float f[] = { 0.14F, 0.4F } ; | |||
v[4] = v1[1]; | float f_1[] = { 1.0F - f[0], 1.0F - f[1] }; | |||
v[5] = v1[2]; | float pt1[] = { (f_1[0] * v1[0] + f[0] * v2[0]), | |||
(f_1[0] * v1[1] + f[0] * v2[1]), | ||||
v[6] = v2[0]; | (f_1[0] * v1[2] + f[0] * v2[2]) }; | |||
v[7] = v2[1]; | float pt2[] = { (f_1[1] * v1[0] + f[1] * v2[0]), | |||
v[8] = v2[2]; | (f_1[1] * v1[1] + f[1] * v2[1]), | |||
(f_1[1] * v1[2] + f[1] * v2[2]) }; | ||||
v[9] = color[0]; | float p1[3], p2[3]; | |||
v[10] = color[1]; | subtract3f(pt1, t, p1); | |||
v[11] = color[2]; | subtract3f(pt2, t, p2); | |||
cgo->add<cgo::draw::line>(p1, p2); | ||||
f = 0.14F; | ||||
f_1 = 1.0F - f; | ||||
v[12] = (f_1 * v1[0] + f * v2[0]) - t[0]; | ||||
v[13] = (f_1 * v1[1] + f * v2[1]) - t[1]; | ||||
v[14] = (f_1 * v1[2] + f * v2[2]) - t[2]; | ||||
f = 0.4F; | ||||
f_1 = 1.0F - f; | ||||
v[15] = (f_1 * v1[0] + f * v2[0]) - t[0]; | ||||
v[16] = (f_1 * v1[1] + f * v2[1]) - t[1]; | ||||
v[17] = (f_1 * v1[2] + f * v2[2]) - t[2]; | ||||
v[18] = color[0]; | ||||
v[19] = color[1]; | ||||
v[20] = color[2]; | ||||
f = 0.6F; | ||||
f_1 = 1.0F - f; | ||||
v[21] = (f_1 * v1[0] + f * v2[0]) - t[0]; | ||||
v[22] = (f_1 * v1[1] + f * v2[1]) - t[1]; | ||||
v[23] = (f_1 * v1[2] + f * v2[2]) - t[2]; | ||||
f = 0.86F; | ||||
f_1 = 1.0F - f; | ||||
v[24] = (f_1 * v1[0] + f * v2[0]) - t[0]; | ||||
v[25] = (f_1 * v1[1] + f * v2[1]) - t[1]; | ||||
v[26] = (f_1 * v1[2] + f * v2[2]) - t[2]; | ||||
v += 27; | ||||
n += 3; | ||||
if(double_sided) { | if(double_sided) { | |||
add3f(pt1, t, p1); | ||||
v[0] = color[0]; | add3f(pt2, t, p2); | |||
v[1] = color[1]; | cgo->add<cgo::draw::line>(p1, p2); | |||
v[2] = color[2]; | } | |||
} | ||||
f = 0.14F; | if (s2){ | |||
f_1 = 1.0F - f; | CGOColorv(cgo, color2); | |||
CGOPickColor(cgo, b2, b2masked ? cPickableNoPick : a); | ||||
v[3] = (f_1 * v1[0] + f * v2[0]) + t[0]; | float f[] = { 0.6F, 0.86F } ; | |||
v[4] = (f_1 * v1[1] + f * v2[1]) + t[1]; | float f_1[] = { 1.0F - f[0], 1.0F - f[1] }; | |||
v[5] = (f_1 * v1[2] + f * v2[2]) + t[2]; | float pt1[] = { (f_1[0] * v1[0] + f[0] * v2[0]), | |||
(f_1[0] * v1[1] + f[0] * v2[1]), | ||||
f = 0.4F; | (f_1[0] * v1[2] + f[0] * v2[2]) }; | |||
f_1 = 1.0F - f; | float pt2[] = { (f_1[1] * v1[0] + f[1] * v2[0]), | |||
(f_1[1] * v1[1] + f[1] * v2[1]), | ||||
v[6] = (f_1 * v1[0] + f * v2[0]) + t[0]; | (f_1[1] * v1[2] + f[1] * v2[2]) }; | |||
v[7] = (f_1 * v1[1] + f * v2[1]) + t[1]; | float p1[3], p2[3]; | |||
v[8] = (f_1 * v1[2] + f * v2[2]) + t[2]; | subtract3f(pt1, t, p1); | |||
subtract3f(pt2, t, p2); | ||||
v[9] = color[0]; | cgo->add<cgo::draw::line>(p1, p2); | |||
v[10] = color[1]; | ||||
v[11] = color[2]; | ||||
f = 0.6F; | ||||
f_1 = 1.0F - f; | ||||
v[12] = (f_1 * v1[0] + f * v2[0]) + t[0]; | ||||
v[13] = (f_1 * v1[1] + f * v2[1]) + t[1]; | ||||
v[14] = (f_1 * v1[2] + f * v2[2]) + t[2]; | ||||
f = 0.86F; | ||||
f_1 = 1.0F - f; | ||||
v[15] = (f_1 * v1[0] + f * v2[0]) + t[0]; | ||||
v[16] = (f_1 * v1[1] + f * v2[1]) + t[1]; | ||||
v[17] = (f_1 * v1[2] + f * v2[2]) + t[2]; | ||||
v += 18; | ||||
n += 2; | ||||
} | ||||
break; | ||||
case 1: | ||||
t[0] = p2[0] * tube_size * 2; | ||||
t[1] = p2[1] * tube_size * 2; | ||||
t[2] = p2[2] * tube_size * 2; | ||||
v[0] = color[0]; | ||||
v[1] = color[1]; | ||||
v[2] = color[2]; | ||||
v[3] = v1[0]; | ||||
v[4] = v1[1]; | ||||
v[5] = v1[2]; | ||||
v[6] = (v2[0] + v1[0]) / 2.0F; | ||||
v[7] = (v2[1] + v1[1]) / 2.0F; | ||||
v[8] = (v2[2] + v1[2]) / 2.0F; | ||||
v[9] = color[0]; | ||||
v[10] = color[1]; | ||||
v[11] = color[2]; | ||||
f = 0.14F; | ||||
f_1 = 1.0F - f; | ||||
v[12] = (f_1 * v1[0] + f * v2[0]) - t[0]; | ||||
v[13] = (f_1 * v1[1] + f * v2[1]) - t[1]; | ||||
v[14] = (f_1 * v1[2] + f * v2[2]) - t[2]; | ||||
f = 0.4F; | ||||
f_1 = 1.0F - f; | ||||
v[15] = (f_1 * v1[0] + f * v2[0]) - t[0]; | ||||
v[16] = (f_1 * v1[1] + f * v2[1]) - t[1]; | ||||
v[17] = (f_1 * v1[2] + f * v2[2]) - t[2]; | ||||
v += 18; | ||||
n += 2; | ||||
if(double_sided) { | ||||
v[0] = color[0]; | ||||
v[1] = color[1]; | ||||
v[2] = color[2]; | ||||
f = 0.14F; | ||||
f_1 = 1.0F - f; | ||||
v[3] = (f_1 * v1[0] + f * v2[0]) + t[0]; | ||||
v[4] = (f_1 * v1[1] + f * v2[1]) + t[1]; | ||||
v[5] = (f_1 * v1[2] + f * v2[2]) + t[2]; | ||||
f = 0.4F; | ||||
f_1 = 1.0F - f; | ||||
v[6] = (f_1 * v1[0] + f * v2[0]) + t[0]; | ||||
v[7] = (f_1 * v1[1] + f * v2[1]) + t[1]; | ||||
v[8] = (f_1 * v1[2] + f * v2[2]) + t[2]; | ||||
v += 9; | ||||
n++; | ||||
} | ||||
break; | ||||
case 2: | ||||
t[0] = p2[0] * tube_size * 2; | ||||
t[1] = p2[1] * tube_size * 2; | ||||
t[2] = p2[2] * tube_size * 2; | ||||
v[0] = color[0]; | ||||
v[1] = color[1]; | ||||
v[2] = color[2]; | ||||
v[3] = (v2[0] + v1[0]) / 2.0F; | ||||
v[4] = (v2[1] + v1[1]) / 2.0F; | ||||
v[5] = (v2[2] + v1[2]) / 2.0F; | ||||
v[6] = v2[0]; | ||||
v[7] = v2[1]; | ||||
v[8] = v2[2]; | ||||
v[9] = color[0]; | ||||
v[10] = color[1]; | ||||
v[11] = color[2]; | ||||
f = 0.60F; | ||||
f_1 = 1.0F - f; | ||||
v[12] = (f_1 * v1[0] + f * v2[0]) - t[0]; | ||||
v[13] = (f_1 * v1[1] + f * v2[1]) - t[1]; | ||||
v[14] = (f_1 * v1[2] + f * v2[2]) - t[2]; | ||||
f = 0.86F; | ||||
f_1 = 1.0F - f; | ||||
v[15] = (f_1 * v1[0] + f * v2[0]) - t[0]; | ||||
v[16] = (f_1 * v1[1] + f * v2[1]) - t[1]; | ||||
v[17] = (f_1 * v1[2] + f * v2[2]) - t[2]; | ||||
v += 18; | ||||
n += 2; | ||||
if(double_sided) { | if(double_sided) { | |||
add3f(pt1, t, p1); | ||||
v[0] = color[0]; | add3f(pt2, t, p2); | |||
v[1] = color[1]; | cgo->add<cgo::draw::line>(p1, p2); | |||
v[2] = color[2]; | ||||
f = 0.60F; | ||||
f_1 = 1.0F - f; | ||||
v[3] = (f_1 * v1[0] + f * v2[0]) + t[0]; | ||||
v[4] = (f_1 * v1[1] + f * v2[1]) + t[1]; | ||||
v[5] = (f_1 * v1[2] + f * v2[2]) + t[2]; | ||||
f = 0.86F; | ||||
f_1 = 1.0F - f; | ||||
v[6] = (f_1 * v1[0] + f * v2[0]) + t[0]; | ||||
v[7] = (f_1 * v1[1] + f * v2[1]) + t[1]; | ||||
v[8] = (f_1 * v1[2] + f * v2[2]) + t[2]; | ||||
v += 9; | ||||
n++; | ||||
} | } | |||
break; | ||||
} | } | |||
*v_ptr = v; | ||||
*n_ptr = n; | ||||
} | } | |||
void RepWireBondFree(RepWireBond * I) | void RepWireBondFree(RepWireBond * I) | |||
{ | { | |||
if (I->shaderCGO){ | ||||
CGOFree(I->shaderCGO); | CGOFree(I->shaderCGO); | |||
I->shaderCGO = 0; | CGOFree(I->primitiveCGO); | |||
} | ||||
FreeP(I->VarWidth); | ||||
FreeP(I->VP); | ||||
FreeP(I->V); | ||||
RepPurge(&I->R); | RepPurge(&I->R); | |||
OOFreeP(I); | OOFreeP(I); | |||
} | } | |||
/* lower memory use and higher performance for | /* lower memory use and higher performance for | |||
display of large trajectories, etc. */ | display of large trajectories, etc. */ | |||
void RepWireBondRenderImmediate(CoordSet * cs, RenderInfo * info) | void RepWireBondRenderImmediate(CoordSet * cs, RenderInfo * info) | |||
{ | { | |||
/* performance optimized, so it does not support the following: | /* performance optimized, so it does not support the following: | |||
skipping to change at line 474 | skipping to change at line 354 | |||
} | } | |||
} | } | |||
} | } | |||
glEnd(); | glEnd(); | |||
glEnable(GL_LIGHTING); | glEnable(GL_LIGHTING); | |||
if(!active) | if(!active) | |||
cs->Active[cRepLine] = false; | cs->Active[cRepLine] = false; | |||
} | } | |||
} | } | |||
static void RepWireBondRender(RepWireBond * I, RenderInfo * info) | static int RepWireBondCGOGenerate(RepWireBond * I, RenderInfo * info) | |||
{ | { | |||
PyMOLGlobals *G = I->R.G; | PyMOLGlobals *G = I->R.G; | |||
CRay *ray = info->ray; | CGO *convertcgo = NULL; | |||
Picking **pick = info->pick; | ||||
float *v = I->V, *vw = I->VarWidth; | ||||
float last_width = -1.0F; | ||||
int c = I->N; | ||||
unsigned int i, j; | ||||
Pickable *p; | ||||
int ok = true; | int ok = true; | |||
float line_width = SceneGetDynamicLineWidth(info, I->Width); | short line_as_cylinders = 0; | |||
float line_width_setting = | line_as_cylinders = SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetG | |||
SettingGetGlobal_f(G, cSetting_line_width); | lobal_b(G, cSetting_render_as_cylinders) && SettingGetGlobal_b(G, cSetting_line_ | |||
// 0.018f is found by trial and error | as_cylinders); | |||
// TODO: this is not sufficient to solve the problem of disappearing cylinders | ||||
float scale_bound = SettingGetGlobal_f(G, cSetting_field_of_view) * cPI / 180 | ||||
.0f * 0.018f; | ||||
if(ray) { | ||||
float radius; | ||||
float pixel_radius = ray->PixelRadius; | ||||
if (pixel_radius < scale_bound) { | ||||
pixel_radius = scale_bound; | ||||
} | ||||
if(I->Radius <= 0.0F) { | ||||
radius = ray->PixelRadius * line_width / 2.0F; | ||||
} else { | ||||
vw = NULL; | ||||
radius = I->Radius; | ||||
} | ||||
v = I->V; | { | |||
c = I->N; | if (ok && I->primitiveCGO){ | |||
if (line_as_cylinders){ | ||||
while(ok && c--) { | CGO *tmpCGO = CGONew(G); | |||
if(vw) { | ||||
if(last_width != *vw) { | if (ok) ok &= CGOEnable(tmpCGO, GL_CYLINDER_SHADER); | |||
last_width = *vw; | if (ok) ok &= CGOSpecial(tmpCGO, CYLINDER_WIDTH_FOR_REPWIRE); | |||
radius = ray->PixelRadius * last_width / 2.0F; | 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); | ||||
} | } | |||
vw++; | if (ok) ok &= CGOAppendNoStop(tmpCGO, tmp2CGO); | |||
if (ok) ok &= CGODisable(tmpCGO, shader); | ||||
if (ok) ok &= CGOStop(tmpCGO); | ||||
CGOFreeWithoutVBOs(tmp2CGO); | ||||
convertcgo = tmpCGO; | ||||
} | } | |||
/* printf("%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f \n",v[3],v[4],v[5],v | convertcgo->use_shader = true; | |||
[6],v[7],v[8]); */ | ||||
ok &= ray->sausage3fv(v + 3, v + 6, radius, v, v); | ||||
v += 9; | ||||
} | } | |||
CGOFree(I->shaderCGO); | ||||
I->shaderCGO = convertcgo; | ||||
CHECKOK(ok, I->shaderCGO); | ||||
} | ||||
return ok; | ||||
} | ||||
} else if(G->HaveGUI && G->ValidContext) { | static void RepWireBondRender(RepWireBond * I, RenderInfo * info) | |||
int nvidia_bugs = SettingGetGlobal_i(G, cSetting_nvidia_bugs); | { | |||
PyMOLGlobals *G = I->R.G; | ||||
if(pick) { | CRay *ray = info->ray; | |||
Picking **pick = info->pick; | ||||
i = (*pick)->src.index; | int ok = true; | |||
v = I->VP; | ||||
c = I->NP; | ||||
p = I->R.P; | ||||
#ifdef PURE_OPENGL_ES_2 | ||||
(void) nvidia_bugs; | ||||
#else | ||||
glBegin(GL_LINES); | ||||
while(c--) { | ||||
i++; | ||||
if(!(*pick)[0].src.bond) { | ||||
/* pass 1 - low order bits */ | ||||
glColor3ub((uchar) ((i & 0xF) << 4), (uchar) ((i & 0xF0) | 0x8), (ucha | ||||
r) ((i & 0xF00) >> 4)); /* we're encoding the index into the color */ | ||||
VLACheck((*pick), Picking, i); | ||||
p++; | ||||
(*pick)[i].src = *p; /* copy object and atom info */ | ||||
(*pick)[i].context = I->R.context; | ||||
} else { | ||||
/* pass 2 - high order bits */ | ||||
j = i >> 12; | ||||
glColor3ub((uchar) ((j & 0xF) << 4), (uchar) ((j & 0xF0) | 0x8), | ||||
(uchar) ((j & 0xF00) >> 4)); | ||||
} | ||||
if(nvidia_bugs) { | ||||
glFlush(); | ||||
} | ||||
glVertex3fv(v); | ||||
v += 3; | ||||
glVertex3fv(v); | ||||
v += 3; | ||||
} | if(ray) { | |||
glEnd(); | #ifndef _PYMOL_NO_RAY | |||
CGORenderRay(I->primitiveCGO, ray, info, NULL, NULL, I->R.cs->Setting, I->R. | ||||
cs->Obj->Obj.Setting); | ||||
ray->transparentf(0.0); | ||||
#endif | #endif | |||
(*pick)[0].src.index = i; /* pass the count */ | } else if(G->HaveGUI && G->ValidContext) { | |||
bool use_shader = SettingGetGlobal_b(G, cSetting_line_use_shader) && | ||||
SettingGetGlobal_b(G, cSetting_use_shaders); | ||||
if(pick) { | ||||
CGORenderGLPicking(use_shader ? I->shaderCGO : I->primitiveCGO, info, &I-> | ||||
R.context, NULL, NULL, &I->R); | ||||
} else { /* else not pick i.e., when rendering */ | } else { /* else not pick i.e., when rendering */ | |||
short use_shader, generate_shader_cgo = 0; | ||||
short line_as_cylinders ; | short line_as_cylinders ; | |||
int nvidia_bugs = SettingGetGlobal_i(G, cSetting_nvidia_bugs); | ||||
use_shader = SettingGetGlobal_b(G, cSetting_line_use_shader) & | ||||
SettingGetGlobal_b(G, cSetting_use_shaders); | ||||
line_as_cylinders = SettingGetGlobal_b(G, cSetting_render_as_cylinders) && SettingGetGlobal_b(G, cSetting_line_as_cylinders); | line_as_cylinders = SettingGetGlobal_b(G, cSetting_render_as_cylinders) && SettingGetGlobal_b(G, cSetting_line_as_cylinders); | |||
if (!use_shader && I->shaderCGO){ | if (I->shaderCGO && (!use_shader || (line_as_cylinders ^ I->shaderCGO_has_ | |||
CGOFree(I->shaderCGO); | cylinders))){ | |||
I->shaderCGO = 0; | ||||
} | ||||
if (I->shaderCGO && (line_as_cylinders ^ I->shaderCGO->has_draw_cylinder_b | ||||
uffers)){ | ||||
CGOFree(I->shaderCGO); | ||||
I->shaderCGO = 0; | ||||
} | ||||
if (use_shader){ | ||||
if (!I->shaderCGO){ | ||||
I->shaderCGO = CGONew(G); | ||||
CHECKOK(ok, I->shaderCGO); | ||||
if (ok) | ||||
I->shaderCGO->use_shader = true; | ||||
generate_shader_cgo = 1; | ||||
} else { | ||||
CShaderPrg *shaderPrg; | ||||
if (line_as_cylinders){ | ||||
// vertex scale is bound so that cylinders cannot disappear when it g | ||||
ets too low | ||||
float pixel_scale_value = SettingGetGlobal_f(G, cSetting_ray_pixel_sc | ||||
ale); | ||||
if(pixel_scale_value < 0) | ||||
pixel_scale_value = 1.0F; | ||||
shaderPrg = CShaderPrg_Enable_CylinderShader(G); | ||||
if (!shaderPrg) return; | ||||
if (vw){ | ||||
CShaderPrg_Set1f(shaderPrg, "uni_radius", info->vertex_scale * pixe | ||||
l_scale_value * line_width_setting/ 2.f); | ||||
} else { | ||||
CShaderPrg_Set1f(shaderPrg, "uni_radius", info->vertex_scale * pixe | ||||
l_scale_value * line_width/ 2.f); | ||||
} | ||||
} else { | ||||
shaderPrg = CShaderPrg_Enable_DefaultShader(G); | ||||
if (!shaderPrg) return; | ||||
CShaderPrg_SetLightingEnabled(shaderPrg, 0); | ||||
} | ||||
CGORenderGL(I->shaderCGO, NULL, NULL, NULL, info, &I->R); | ||||
CShaderPrg_Disable(shaderPrg); | ||||
return; | ||||
} | ||||
} | ||||
v = I->V; | ||||
c = I->N; | ||||
if (ok && generate_shader_cgo){ | ||||
ok &= CGOLinewidthSpecial(I->shaderCGO, LINEWIDTH_DYNAMIC_WITH_SCALE); | ||||
if(ok && !info->line_lighting) | ||||
ok &= CGODisable(I->shaderCGO, GL_LIGHTING); | ||||
ok &= CGOResetNormal(I->shaderCGO, true); | ||||
} else { | ||||
if(info->width_scale_flag) | ||||
glLineWidth(line_width * info->width_scale); | ||||
else | ||||
glLineWidth(line_width); | ||||
if(!info->line_lighting) | ||||
glDisable(GL_LIGHTING); | ||||
SceneResetNormal(G, true); | ||||
} | ||||
if (generate_shader_cgo){ | ||||
float curColor[3]; | ||||
while(ok && c--) { | ||||
// float cylinder_width = line_width; | ||||
float cylinder_width = line_width_setting; | ||||
if(vw) { | ||||
if(last_width != *vw) { | ||||
last_width = *vw; | ||||
ok &= CGOLinewidth(I->shaderCGO, last_width); | ||||
} | ||||
cylinder_width = *vw; | ||||
vw++; | ||||
} | ||||
if (ok){ | ||||
ok &= CGOColorv(I->shaderCGO, v); | ||||
copy3f(v, curColor); | ||||
v += 3; | ||||
} | ||||
if (ok){ | ||||
if (line_as_cylinders){ | ||||
float *origin, axis[3]; | ||||
origin = v; | ||||
v += 3; | ||||
axis[0] = v[0] - origin[0]; | ||||
axis[1] = v[1] - origin[1]; | ||||
axis[2] = v[2] - origin[2]; | ||||
v += 3; | ||||
{ | ||||
if (c && equal3f(&v[-3], &v[3]) && !equal3f(curColor, v)){ | ||||
/* if successive bonds share midpoint, then draw one cylinder w | ||||
ith two colors */ | ||||
origin = &v[-6]; | ||||
axis[0] = v[6] - origin[0]; | ||||
axis[1] = v[7] - origin[1]; | ||||
axis[2] = v[8] - origin[2]; | ||||
// if next bond has same half-point, then draw one cylinder wit | ||||
h two colors | ||||
ok &= CGOShaderCylinder2ndColor(I->shaderCGO, origin, axis, cyl | ||||
inder_width/line_width_setting, 15, v); | ||||
v += 9; | ||||
c--; | ||||
} else { | ||||
/* Storing the cylinder_width divided by the current line_width | ||||
setting */ | ||||
ok &= CGOShaderCylinder(I->shaderCGO, origin, axis, cylinder_wi | ||||
dth/line_width_setting, 15); | ||||
} | ||||
} | ||||
} else { | ||||
ok &= CGOBegin(I->shaderCGO, GL_LINES); | ||||
if (ok){ | ||||
ok &= CGOVertexv(I->shaderCGO, v); | ||||
v += 3; | ||||
} | ||||
if (ok){ | ||||
ok &= CGOVertexv(I->shaderCGO, v); | ||||
v += 3; | ||||
} | ||||
if (ok) | ||||
ok &= CGOEnd(I->shaderCGO); | ||||
} | ||||
} | ||||
} | ||||
} else { | ||||
while(c--) { | ||||
if(vw) { | ||||
if(last_width != *vw) { | ||||
last_width = *vw; | ||||
glLineWidth(last_width); | ||||
} | ||||
vw++; | ||||
} | ||||
#ifdef PURE_OPENGL_ES_2 | ||||
/* TODO */ | ||||
#else | ||||
glBegin(GL_LINES); | ||||
glColor3fv(v); | ||||
v += 3; | ||||
if(nvidia_bugs) { | ||||
glFlush(); | ||||
} | ||||
glVertex3fv(v); | ||||
v += 3; | ||||
glVertex3fv(v); | ||||
v += 3; | ||||
glEnd(); | ||||
#endif | ||||
} | ||||
} | ||||
if (generate_shader_cgo){ | ||||
if (ok) | ||||
ok &= CGOEnable(I->shaderCGO, GL_LIGHTING); | ||||
} else { | ||||
glEnable(GL_LIGHTING); | ||||
} | ||||
if (use_shader) { | ||||
if (ok && generate_shader_cgo){ | ||||
CGO *convertcgo = NULL; | ||||
if (ok) | ||||
ok &= CGOStop(I->shaderCGO); | ||||
if (ok){ | ||||
convertcgo = CGOCombineBeginEnd(I->shaderCGO, 0); | ||||
CGOFree(I->shaderCGO); | ||||
I->shaderCGO = convertcgo; | ||||
CHECKOK(ok, I->shaderCGO); | ||||
convertcgo = NULL; | ||||
} | ||||
if (ok && I->shaderCGO){ | ||||
if (line_as_cylinders){ | ||||
convertcgo = CGOOptimizeGLSLCylindersToVBOIndexed(I->shaderCGO, 0) | ||||
; | ||||
} else { | ||||
convertcgo = CGOOptimizeToVBONotIndexed(I->shaderCGO, 0); | ||||
} | ||||
} | ||||
CGOFree(I->shaderCGO); | CGOFree(I->shaderCGO); | |||
I->shaderCGO = convertcgo; | I->shaderCGO_has_cylinders = 0; | |||
CHECKOK(ok, I->shaderCGO); | ||||
} | } | |||
if (ok){ | if (ok){ | |||
CShaderPrg *shaderPrg; | if (use_shader) { | |||
if (line_as_cylinders){ | if (!I->shaderCGO) | |||
// vertex scale is bound so that cylinders cannot disappear when it g | ok &= RepWireBondCGOGenerate(I, info); | |||
ets too low | CGORenderGL(I->shaderCGO, NULL, NULL, NULL, info, &I->R); | |||
float pixel_scale_value = SettingGetGlobal_f(G, cSetting_ray_pixel_sc | ||||
ale); | ||||
if(pixel_scale_value < 0) | ||||
pixel_scale_value = 1.0F; | ||||
shaderPrg = CShaderPrg_Enable_CylinderShader(G); | ||||
if (!shaderPrg) return; | ||||
if (vw){ | ||||
CShaderPrg_Set1f(shaderPrg, "uni_radius", info->vertex_scale * pixe | ||||
l_scale_value * line_width_setting/ 2.f); | ||||
} else { | } else { | |||
CShaderPrg_Set1f(shaderPrg, "uni_radius", info->vertex_scale * pixe | CGORenderGL(I->primitiveCGO, NULL, NULL, NULL, info, &I->R); | |||
l_scale_value * line_width/ 2.f); | ||||
} | ||||
} else { | ||||
shaderPrg = CShaderPrg_Enable_DefaultShader(G); | ||||
if (!shaderPrg) return; | ||||
CShaderPrg_SetLightingEnabled(shaderPrg, 0); | ||||
} | ||||
CGORenderGL(I->shaderCGO, NULL, NULL, NULL, info, &I->R); | ||||
CShaderPrg_Disable(shaderPrg); | ||||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
if (!ok){ | if (!ok){ | |||
CGOFree(I->shaderCGO); | CGOFree(I->shaderCGO); | |||
I->shaderCGO = NULL; | ||||
I->R.fInvalidate(&I->R, I->R.cs, cRepInvPurge); | I->R.fInvalidate(&I->R, I->R.cs, cRepInvPurge); | |||
I->R.cs->Active[cRepLine] = false; | I->R.cs->Active[cRepLine] = false; | |||
} | } | |||
} | } | |||
static | static | |||
bool IsBondTerminal(ObjectMolecule *obj, int b1, int b2){ | bool IsBondTerminal(ObjectMolecule *obj, int b1, int b2){ | |||
int *neighbor = obj->Neighbor; | int *neighbor = obj->Neighbor; | |||
if(neighbor) { | if(neighbor) { | |||
int mem, nbr; | int mem, nbr; | |||
skipping to change at line 821 | skipping to change at line 475 | |||
heavy2++; | heavy2++; | |||
} | } | |||
nbr += 2; | nbr += 2; | |||
} | } | |||
if((heavy1 < 2) || (heavy2 < 2)) | if((heavy1 < 2) || (heavy2 < 2)) | |||
return true; | return true; | |||
} | } | |||
return false; | return false; | |||
} | } | |||
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 d | ||||
ash_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, therefor | ||||
e 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 vect | ||||
or | ||||
mult3f(naxis, dash_length + dgap, adddtot); // adddtot - length of dash plus g | ||||
ap 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; | ||||
} | ||||
Rep *RepWireBondNew(CoordSet * cs, int state) | Rep *RepWireBondNew(CoordSet * cs, int state) | |||
{ | { | |||
PyMOLGlobals *G = cs->State.G; | PyMOLGlobals *G = cs->State.G; | |||
ObjectMolecule *obj = cs->Obj; | ObjectMolecule *obj = cs->Obj; | |||
int a1, a2, b1, b2; | int a1, a2; | |||
int a, c1, c2, s1, s2, ord; | unsigned int b1, b2; | |||
int a, c1, c2, ord; | ||||
bool s1, s2; | ||||
BondType *b; | BondType *b; | |||
int half_bonds, *other = NULL; | int half_bonds, *other = NULL; | |||
float valence; | float valence; | |||
float *v, *v0, *v1, *v2, h[3]; | float *v1, *v2; | |||
int visFlag; | int visFlag; | |||
int maxSegment = 0; | ||||
int maxBond = 0; | ||||
float tmpColor[3]; | ||||
float line_width; | float line_width; | |||
int valence_flag = false; | int valence_flag = false; | |||
Pickable *rp; | AtomInfoType *ai1; | |||
AtomInfoType *ai1, *ai2; | ||||
int cartoon_side_chain_helper = 0; | int cartoon_side_chain_helper = 0; | |||
int ribbon_side_chain_helper = 0; | int ribbon_side_chain_helper = 0; | |||
int line_stick_helper = 0; | int line_stick_helper = 0; | |||
int na_mode; | int na_mode; | |||
bool *marked = NULL; | bool *marked = NULL; | |||
int valence_found = false; | int valence_found = false; | |||
int variable_width = false; | int variable_width = false; | |||
int n_line_width = 0; | float last_line_width = -1.f; | |||
int line_color; | int line_color; | |||
int hide_long = false; | int hide_long = false; | |||
int fancy; | int fancy; | |||
const float _0p9 = 0.9F; | const float _0p9 = 0.9F; | |||
int ok = true; | int ok = true; | |||
unsigned int line_counter = 0; | ||||
OOAlloc(G, RepWireBond); | OOAlloc(G, RepWireBond); | |||
CHECKOK(ok, I); | CHECKOK(ok, I); | |||
PRINTFD(G, FB_RepWireBond) | PRINTFD(G, FB_RepWireBond) | |||
" RepWireBondNew-Debug: entered.\n" ENDFD; | " RepWireBondNew-Debug: entered.\n" ENDFD; | |||
visFlag = false; | visFlag = false; | |||
b = obj->Bond; | b = obj->Bond; | |||
ai1 = obj->AtomInfo; | ||||
if(ok && GET_BIT(obj->RepVisCache,cRepLine)){ | if(ok && GET_BIT(obj->RepVisCache,cRepLine)){ | |||
for(a = 0; a < obj->NBond; a++) { | for(a = 0; a < obj->NBond; a++) { | |||
b1 = b->index[0]; | b1 = b->index[0]; | |||
b2 = b->index[1]; | b2 = b->index[1]; | |||
b++; | if((cRepLineBit & ai1[b1].visRep & ai1[b2].visRep)) { | |||
if(GET_BIT(obj->AtomInfo[b1].visRep,cRepLine) || GET_BIT(obj->AtomInfo[b2] | ||||
.visRep,cRepLine)) { | ||||
visFlag = true; | visFlag = true; | |||
break; | break; | |||
} | } | |||
b++; | ||||
} | } | |||
} | } | |||
if(!visFlag) { | if(!visFlag) { | |||
OOFreeP(I); | OOFreeP(I); | |||
return (NULL); /* skip if no dots are visible */ | return (NULL); /* skip if no dots are visible */ | |||
} | } | |||
marked = Calloc(bool, obj->NAtom); | marked = Calloc(bool, obj->NAtom); | |||
CHECKOK(ok, marked); | CHECKOK(ok, marked); | |||
if (!ok){ | if (!ok){ | |||
OOFreeP(I); | OOFreeP(I); | |||
skipping to change at line 903 | skipping to change at line 656 | |||
if(line_stick_helper && (SettingGet_f(G, cs->Setting, obj->Obj.Setting, | if(line_stick_helper && (SettingGet_f(G, cs->Setting, obj->Obj.Setting, | |||
cSetting_stick_transparency) > R_SMALL4)) | cSetting_stick_transparency) > R_SMALL4)) | |||
line_stick_helper = false; | line_stick_helper = false; | |||
half_bonds = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_half_bond s); | half_bonds = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_half_bond s); | |||
hide_long = SettingGet_b(G, cs->Setting, obj->Obj.Setting, cSetting_hide_long_ bonds); | hide_long = SettingGet_b(G, cs->Setting, obj->Obj.Setting, cSetting_hide_long_ bonds); | |||
na_mode = | na_mode = | |||
SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_cartoon_nucleic_acid _mode); | SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_cartoon_nucleic_acid _mode); | |||
int na_mode_ribbon = | int na_mode_ribbon = | |||
SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_ribbon_nucleic_acid_ mode); | 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; | 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; | b = obj->Bond; | |||
for(a = 0; a < obj->NBond; a++) { | for(a = 0; a < obj->NBond; a++) { | |||
b1 = b->index[0]; | b1 = b->index[0]; | |||
b2 = b->index[1]; | b2 = b->index[1]; | |||
if(obj->DiscreteFlag) { | if(obj->DiscreteFlag) { | |||
if((cs == obj->DiscreteCSet[b1]) && (cs == obj->DiscreteCSet[b2])) { | if((cs == obj->DiscreteCSet[b1]) && (cs == obj->DiscreteCSet[b2])) { | |||
a1 = obj->DiscreteAtmToIdx[b1]; | a1 = obj->DiscreteAtmToIdx[b1]; | |||
a2 = obj->DiscreteAtmToIdx[b2]; | a2 = obj->DiscreteAtmToIdx[b2]; | |||
} else { | } else { | |||
a1 = -1; | a1 = -1; | |||
a2 = -1; | a2 = -1; | |||
} | } | |||
} else { | } else { | |||
a1 = cs->AtmToIdx[b1]; | a1 = cs->AtmToIdx[b1]; | |||
a2 = cs->AtmToIdx[b2]; | a2 = cs->AtmToIdx[b2]; | |||
} | } | |||
if((a1 >= 0) && (a2 >= 0)) { | if((a1 >= 0) && (a2 >= 0)) { | |||
if((!variable_width) && AtomInfoCheckBondSetting(G, b, cSetting_line_width | if(!variable_width) | |||
)) | if (AtomInfoCheckBondSetting(G, b, cSetting_line_width)){ | |||
variable_width = true; | variable_width = true; | |||
if (valence_found) break; | ||||
} | ||||
auto bd_valence_flag = BondSettingGetWD(G, b, cSetting_valence, valence_fl ag); | auto bd_valence_flag = BondSettingGetWD(G, b, cSetting_valence, valence_fl ag); | |||
if(bd_valence_flag) { | if(bd_valence_flag) { | |||
valence_found = true; | valence_found = true; | |||
if((b->order > 0) && (b->order < 4)) { | if (variable_width) break; | |||
maxSegment += 2 * b->order; | } | |||
} else if(b->order == 4) { /* aromatic */ | ||||
maxSegment += 10; | ||||
} else { | ||||
maxSegment += 2; | ||||
} | ||||
} else | ||||
maxSegment += 2; | ||||
maxBond++; | ||||
} | } | |||
b++; | b++; | |||
} | } | |||
RepInit(G, &I->R); | RepInit(G, &I->R); | |||
I->R.fRender = (void (*)(struct Rep *, RenderInfo * info)) RepWireBondRender; | I->R.fRender = (void (*)(struct Rep *, RenderInfo * info)) RepWireBondRender; | |||
I->R.fFree = (void (*)(struct Rep *)) RepWireBondFree; | I->R.fFree = (void (*)(struct Rep *)) RepWireBondFree; | |||
I->Width = line_width; | ||||
I->Radius = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_line_radiu | ||||
s); | ||||
I->shaderCGO = 0; | I->shaderCGO = 0; | |||
I->N = 0; | I->shaderCGO_has_cylinders = 0; | |||
I->NP = 0; | ||||
I->V = NULL; | ||||
I->VP = NULL; | ||||
I->VarWidth = NULL; | ||||
I->R.P = NULL; | I->R.P = NULL; | |||
I->R.fRecolor = NULL; | I->R.fRecolor = NULL; | |||
I->R.context.object = (void *) obj; | I->R.context.object = (void *) obj; | |||
I->R.context.state = state; | I->R.context.state = state; | |||
I->R.cs = cs; | 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(obj->NBond) { | |||
if(valence_found) /* build list of up to 2 connected atoms for eac h atom */ | if(valence_found) /* build list of up to 2 connected atoms for eac h atom */ | |||
other = ObjectMoleculeGetPrioritizedOtherIndexList(obj, cs); | other = ObjectMoleculeGetPrioritizedOtherIndexList(obj, cs); | |||
if(variable_width) { | ||||
I->VarWidth = Alloc(float, maxSegment); | ||||
CHECKOK(ok, I->VarWidth); | ||||
} | ||||
if (ok) | ||||
I->V = Alloc(float, maxSegment * 9); | ||||
CHECKOK(ok, I->V); | ||||
if(ok && (cartoon_side_chain_helper || ribbon_side_chain_helper)) { | if(ok && (cartoon_side_chain_helper || ribbon_side_chain_helper)) { | |||
SideChainHelperMarkNonCartoonBonded(marked, obj, cs, | SideChainHelperMarkNonCartoonBonded(marked, obj, cs, | |||
cartoon_side_chain_helper, | cartoon_side_chain_helper, | |||
ribbon_side_chain_helper); | ribbon_side_chain_helper); | |||
} | } | |||
v = I->V; | ||||
b = obj->Bond; | b = obj->Bond; | |||
for(a = 0; ok && a < obj->NBond; a++) { | for(a = 0; ok && a < obj->NBond; ++a, ++b) { | |||
b1 = b->index[0]; | b1 = b->index[0]; | |||
b2 = b->index[1]; | b2 = b->index[1]; | |||
ord = b->order; | ord = b->order; | |||
/* | if (ord == 0 && valence_zero_mode == 0) | |||
b1 = *(b++); | continue; | |||
b2 = *(b++); | ||||
ord = (*(b++)); | ||||
*/ | ||||
if(obj->DiscreteFlag) { | if(obj->DiscreteFlag) { | |||
if((cs == obj->DiscreteCSet[b1]) && (cs == obj->DiscreteCSet[b2])) { | if((cs == obj->DiscreteCSet[b1]) && (cs == obj->DiscreteCSet[b2])) { | |||
a1 = obj->DiscreteAtmToIdx[b1]; | a1 = obj->DiscreteAtmToIdx[b1]; | |||
a2 = obj->DiscreteAtmToIdx[b2]; | a2 = obj->DiscreteAtmToIdx[b2]; | |||
} else { | } else { | |||
a1 = -1; | a1 = -1; | |||
a2 = -1; | a2 = -1; | |||
} | } | |||
} else { | } else { | |||
a1 = cs->AtmToIdx[b1]; | a1 = cs->AtmToIdx[b1]; | |||
a2 = cs->AtmToIdx[b2]; | a2 = cs->AtmToIdx[b2]; | |||
} | } | |||
if((a1 >= 0) && (a2 >= 0)) { | if((a1 >= 0) && (a2 >= 0)) { | |||
AtomInfoType *ati1 = obj->AtomInfo + b1; | AtomInfoType *ati1 = obj->AtomInfo + b1; | |||
AtomInfoType *ati2 = obj->AtomInfo + b2; | AtomInfoType *ati2 = obj->AtomInfo + b2; | |||
s1 = GET_BIT(ati1->visRep,cRepLine); | s1 = (ati1->visRep & cRepLineBit); | |||
s2 = GET_BIT(ati2->visRep,cRepLine); | s2 = (ati2->visRep & cRepLineBit); | |||
if((s1 || s2) && !(s1 && s2)) | if(s1 ^ s2){ | |||
if(!half_bonds) { | if(!half_bonds) { | |||
if(line_stick_helper && | if(line_stick_helper && | |||
(((!s1) && GET_BIT(ati1->visRep,cRepCyl) && (!GET_BIT(ati2->visRe | (((!s1) && (cRepCylBit & ati1->visRep) && !(cRepCylBit & ati2->vi | |||
p,cRepCyl))) || | sRep)) || | |||
((!s2) && GET_BIT(ati2->visRep,cRepCyl) && (!GET_BIT(ati1->visRe | ((!s2) && (cRepCylBit & ati2->visRep) && !(cRepCylBit & ati1->vi | |||
p,cRepCyl))))) | sRep)))) | |||
s1 = s2 = 1; /* turn on line when both stick and line are alt ernately shown */ | s1 = s2 = 1; /* turn on line when both stick and line are alt ernately shown */ | |||
else { | else { | |||
s1 = 0; | s1 = 0; | |||
s2 = 0; | s2 = 0; | |||
} | } | |||
} | } | |||
} | ||||
if(hide_long && (s1 || s2)) { | if(hide_long && (s1 || s2)) { | |||
float cutoff = (ati1->vdw + ati2->vdw) * _0p9; | float cutoff = (ati1->vdw + ati2->vdw) * _0p9; | |||
v1 = cs->Coord + 3 * a1; | v1 = cs->Coord + 3 * a1; | |||
v2 = cs->Coord + 3 * a2; | v2 = cs->Coord + 3 * a2; | |||
ai1 = obj->AtomInfo + b1; | ai1 = obj->AtomInfo + b1; | |||
ai2 = obj->AtomInfo + b2; | ||||
if(!within3f(v1, v2, cutoff)) /* atoms separated by more than 90% of t he sum of their vdw radii */ | if(!within3f(v1, v2, cutoff)) /* atoms separated by more than 90% of t he sum of their vdw radii */ | |||
s1 = s2 = 0; | s1 = s2 = 0; | |||
} | } | |||
if(s1 || s2) { | if(s1 || s2) { | |||
float bd_line_width = line_width; | float rgb1[3], rgb2[3]; | |||
int terminal = false; | int terminal = false; | |||
auto bd_valence_flag = BondSettingGetWD(G, b, cSetting_valence, valenc e_flag); | auto bd_valence_flag = BondSettingGetWD(G, b, cSetting_valence, valenc e_flag); | |||
auto bd_line_color = BondSettingGetWD(G, b, cSetting_line_color, line_ color); | auto bd_line_color = BondSettingGetWD(G, b, cSetting_line_color, line_ color); | |||
if(fancy && bd_valence_flag && (b->order > 1)) { | if(fancy && bd_valence_flag && (b->order > 1)) { | |||
terminal = IsBondTerminal(obj, b1, b2); | terminal = IsBondTerminal(obj, b1, b2); | |||
} | } | |||
if(variable_width) { | if(variable_width) { | |||
bd_line_width = BondSettingGetWD(G, b, cSetting_line_width, line_wid | auto bd_line_width = BondSettingGetWD(G, b, cSetting_line_width, lin | |||
th); | e_width); | |||
if (last_line_width!=bd_line_width){ | ||||
CGOSpecialWithArg(I->primitiveCGO, LINEWIDTH_FOR_LINES, bd_line_wi | ||||
dth); | ||||
last_line_width = bd_line_width; | ||||
} | ||||
} | } | |||
if(bd_line_color < 0) { | if(bd_line_color < 0) { | |||
if(bd_line_color == cColorObject) { | if(bd_line_color == cColorObject) { | |||
c1 = (c2 = obj->Obj.Color); | c1 = (c2 = obj->Obj.Color); | |||
} else if(ColorCheckRamped(G, bd_line_color)) { | } else if(ColorCheckRamped(G, bd_line_color)) { | |||
c1 = (c2 = bd_line_color); | c1 = (c2 = bd_line_color); | |||
} else { | } else { | |||
c1 = ati1->color; | c1 = ati1->color; | |||
c2 = ati2->color; | c2 = ati2->color; | |||
skipping to change at line 1098 | skipping to change at line 839 | |||
if (!sc_helper) | if (!sc_helper) | |||
AtomSettingGetIfDefined(G, ati2, cSetting_ribbon_side_chain_help er, &sc_helper); | AtomSettingGetIfDefined(G, ati2, cSetting_ribbon_side_chain_help er, &sc_helper); | |||
if (sc_helper && | if (sc_helper && | |||
SideChainHelperFilterBond(G, marked, ati1, ati2, b1, b2, na_mo de_ribbon, &c1, &c2)) | SideChainHelperFilterBond(G, marked, ati1, ati2, b1, b2, na_mo de_ribbon, &c1, &c2)) | |||
s1 = s2 = 0; | s1 = s2 = 0; | |||
} | } | |||
} | } | |||
if((c1 == c2) && s1 && s2 && (!ColorCheckRamped(G, c1))) { | bool isRamped = false; | |||
isRamped = ColorGetCheckRamped(G, c1, v1, rgb1, state); | ||||
v0 = ColorGet(G, c1); | isRamped = ColorGetCheckRamped(G, c2, v2, rgb2, state) | isRamped; | |||
if (s1 || s2){ | ||||
if((bd_valence_flag) && (ord > 1) && (ord < 4)) { | if (ord == 0 && valence_zero_mode == 2) { | |||
RepValence(v, v1, v2, other, a1, a2, cs->Coord, v0, ord, valence, | ord = 1; | |||
0, fancy | ||||
&& !terminal); | ||||
v += ord * 9; | ||||
I->N += ord; | ||||
} else if(bd_valence_flag && (ord == 4)) { /* aromatic */ | ||||
RepAromatic(v1, v2, other, a1, a2, cs->Coord, v0, valence, 0, &v, | ||||
&I->N); | ||||
} else { | ||||
I->N++; | ||||
*(v++) = *(v0++); | ||||
*(v++) = *(v0++); | ||||
*(v++) = *(v0++); | ||||
*(v++) = *(v1++); | ||||
*(v++) = *(v1++); | ||||
*(v++) = *(v1++); | ||||
*(v++) = *(v2++); | ||||
*(v++) = *(v2++); | ||||
*(v++) = *(v2++); | ||||
} | } | |||
} else { | ||||
h[0] = (v1[0] + v2[0]) / 2; | ||||
h[1] = (v1[1] + v2[1]) / 2; | ||||
h[2] = (v1[2] + v2[2]) / 2; | ||||
if(s1) { | ||||
if(ColorCheckRamped(G, c1)) { | ||||
ColorGetRamped(G, c1, v1, tmpColor, state); | ||||
v0 = tmpColor; | ||||
} else { | ||||
v0 = ColorGet(G, c1); | ||||
} | ||||
if((bd_valence_flag) && (ord > 1) && (ord < 4)) { | if (!ord){ | |||
RepValence(v, v1, h, other, a1, a2, cs->Coord, v0, ord, valence, | RepWireZeroOrderBond(I->primitiveCGO, s1, s2, v1, v2, rgb1, rgb2, | |||
1, fancy | b1, b2, a, .15f, .15f, ati1->masked, ati2->masked); | |||
&& !terminal); | } else if (!bd_valence_flag || ord <= 1){ | |||
v += ord * 9; | RepLine(I->primitiveCGO, s1, s2, isRamped, v1, v2, rgb1, b1, b2, a | |||
I->N += ord; | , rgb2, ati1->masked, ati2->masked); | |||
} else if(bd_valence_flag && (ord == 4)) { | } else { | |||
RepAromatic(v1, v2, other, a1, a2, cs->Coord, v0, valence, 1, &v | if (ord == 4){ | |||
, &I->N); | RepAromatic(I->primitiveCGO, s1, s2, isRamped, v1, v2, other, a1 | |||
} else { | , a2, cs->Coord, rgb1, rgb2, valence, 0, b1, b2, a, ati1->masked, ati2->masked); | |||
I->N++; | ||||
*(v++) = *(v0++); | ||||
*(v++) = *(v0++); | ||||
*(v++) = *(v0++); | ||||
*(v++) = *(v1++); | ||||
*(v++) = *(v1++); | ||||
*(v++) = *(v1++); | ||||
*(v++) = h[0]; | ||||
*(v++) = h[1]; | ||||
*(v++) = h[2]; | ||||
} | ||||
} | ||||
if(s2) { | ||||
if(ColorCheckRamped(G, c2)) { | ||||
ColorGetRamped(G, c2, v2, tmpColor, state); | ||||
v0 = tmpColor; | ||||
} else { | ||||
v0 = ColorGet(G, c2); | ||||
} | ||||
if((bd_valence_flag) && (ord > 1) && (ord < 4)) { | ||||
RepValence(v, h, v2, other, a1, a2, cs->Coord, v0, ord, valence, | ||||
2, fancy | ||||
&& !terminal); | ||||
v += ord * 9; | ||||
I->N += ord; | ||||
} else if(bd_valence_flag && (ord == 4)) { | ||||
RepAromatic(v1, v2, other, a1, a2, cs->Coord, v0, valence, 2, &v | ||||
, &I->N); | ||||
} else { | } else { | |||
I->N++; | RepValence(I->primitiveCGO, s1, s2, isRamped, v1, v2, other, a1, | |||
*(v++) = *(v0++); | a2, cs->Coord, rgb1, rgb2, ord, valence, fancy && !terminal, b1, b2, a, ati1->m | |||
*(v++) = *(v0++); | asked, ati2->masked); | |||
*(v++) = *(v0++); | ||||
*(v++) = h[0]; | ||||
*(v++) = h[1]; | ||||
*(v++) = h[2]; | ||||
*(v++) = *(v2++); | ||||
*(v++) = *(v2++); | ||||
*(v++) = *(v2++); | ||||
} | } | |||
} | ||||
} | ||||
/* record effective line_widths for these segments */ | ||||
if(variable_width) { | ||||
while(n_line_width < I->N) { | ||||
I->VarWidth[n_line_width] = bd_line_width; | ||||
n_line_width++; | ||||
} | } | |||
line_counter++; | ||||
} | } | |||
} | } | |||
} | } | |||
b++; | ||||
ok &= !G->Interrupt; | ok &= !G->Interrupt; | |||
} | } | |||
if (ok) | ||||
I->V = ReallocForSure(I->V, float, (v - I->V)); | ||||
CHECKOK(ok, I->V); | ||||
if(ok && I->VarWidth) { | ||||
I->VarWidth = ReallocForSure(I->VarWidth, float, n_line_width); | ||||
CHECKOK(ok, I->VarWidth); | ||||
} | ||||
/* now create pickable verson */ | ||||
if(ok && SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_pickable)) | ||||
{ | ||||
I->VP = Alloc(float, maxBond * 6 * 2); | ||||
CHECKOK(ok, I->VP); | ||||
if (ok) | ||||
I->R.P = Alloc(Pickable, 2 * maxBond + 1); | ||||
CHECKOK(ok, I->R.P); | ||||
if (ok){ | ||||
rp = I->R.P + 1; /* skip first record! */ | ||||
v = I->VP; | ||||
b = obj->Bond; | ||||
} | ||||
for(a = 0; ok && a < obj->NBond; a++) { | ||||
b1 = b->index[0]; | ||||
b2 = b->index[1]; | ||||
b++; | ||||
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)) { | ||||
ai1 = obj->AtomInfo + b1; | ||||
ai2 = obj->AtomInfo + b2; | ||||
s1 = GET_BIT(ai1->visRep,cRepLine); | ||||
s2 = GET_BIT(ai2->visRep,cRepLine); | ||||
if(!(s1 && s2)) { | ||||
if(!half_bonds) { | ||||
s1 = 0; | ||||
s2 = 0; | ||||
} | ||||
} | ||||
if(hide_long && (s1 || s2)) { | ||||
float cutoff = (ai1->vdw + ai2->vdw) * _0p9; | ||||
v1 = cs->Coord + 3 * a1; | ||||
v2 = cs->Coord + 3 * a2; | ||||
ai1 = obj->AtomInfo + b1; | ||||
ai2 = obj->AtomInfo + b2; | ||||
if(!within3f(v1, v2, cutoff)) /* atoms separated by more than | ||||
90% of the sum of their vdw radii */ | ||||
s1 = s2 = 0; | ||||
} | ||||
if(s1 || s2) { | ||||
v1 = cs->Coord + 3 * a1; | ||||
v2 = cs->Coord + 3 * a2; | ||||
h[0] = (v1[0] + v2[0]) / 2; | ||||
h[1] = (v1[1] + v2[1]) / 2; | ||||
h[2] = (v1[2] + v2[2]) / 2; | ||||
if(s1 & (!ai1->masked)) { | ||||
I->NP++; | ||||
rp->index = b1; | ||||
rp->bond = a; | ||||
rp++; | ||||
*(v++) = *(v1++); | ||||
*(v++) = *(v1++); | ||||
*(v++) = *(v1++); | ||||
*(v++) = h[0]; | ||||
*(v++) = h[1]; | ||||
*(v++) = h[2]; | ||||
} | ||||
if(s2 & (!ai2->masked)) { | ||||
I->NP++; | ||||
rp->index = b2; | ||||
rp->bond = a; | ||||
rp++; | ||||
*(v++) = h[0]; | ||||
*(v++) = h[1]; | ||||
*(v++) = h[2]; | ||||
*(v++) = *(v2++); | ||||
*(v++) = *(v2++); | ||||
*(v++) = *(v2++); | ||||
} | ||||
} | ||||
} | ||||
ok &= !G->Interrupt; | ||||
} | ||||
if (ok){ | ||||
I->R.P = Realloc(I->R.P, Pickable, I->NP + 1); | ||||
CHECKOK(ok, I->R.P); | ||||
if (ok) | ||||
I->R.P[0].index = I->NP; | ||||
} | ||||
if (ok) | ||||
I->VP = ReallocForSure(I->VP, float, (v - I->VP)); | ||||
CHECKOK(ok, I->VP); | ||||
} | ||||
} | } | |||
CGOEnd(I->primitiveCGO); | ||||
CGOSpecialWithArg(I->primitiveCGO, LINE_LIGHTING, 1.f); | ||||
CGOStop(I->primitiveCGO); | ||||
FreeP(marked); | FreeP(marked); | |||
FreeP(other); | FreeP(other); | |||
if (!ok){ | if (!ok || !line_counter){ | |||
RepWireBondFree(I); | RepWireBondFree(I); | |||
I = NULL; | I = NULL; | |||
} | } | |||
return (Rep *) I; | return (Rep *) I; | |||
} | } | |||
static void RepValence(float *v, float *v1, float *v2, int *other, | ||||
int a1, int a2, float *coord, float *color, int ord, | ||||
float tube_size, int half_state, int fancy) | ||||
{ | ||||
float d[3], t[3], p0[3], p1[3], p2[3], *vv; | ||||
int a3; | ||||
const float indent = tube_size; | ||||
v[0] = color[0]; | ||||
v[1] = color[1]; | ||||
v[2] = color[2]; | ||||
v[9] = color[0]; | ||||
v[10] = color[1]; | ||||
v[11] = color[2]; | ||||
/* 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, NULL); | ||||
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); | ||||
} | ||||
/* now we have a coordinate system */ | ||||
t[0] = p2[0] * tube_size; | ||||
t[1] = p2[1] * tube_size; | ||||
t[2] = p2[2] * tube_size; | ||||
switch (ord) { | ||||
case 2: | ||||
v[0] = color[0]; | ||||
v[1] = color[1]; | ||||
v[2] = color[2]; | ||||
v[9] = color[0]; | ||||
v[10] = color[1]; | ||||
v[11] = color[2]; | ||||
if(fancy) { | ||||
float f, f_1; | ||||
v[3] = v1[0]; | ||||
v[4] = v1[1]; | ||||
v[5] = v1[2]; | ||||
v[6] = v2[0]; | ||||
v[7] = v2[1]; | ||||
v[8] = v2[2]; | ||||
if(half_state == 2) { | ||||
v[12] = v1[0] - 2 * t[0]; | ||||
v[13] = v1[1] - 2 * t[1]; | ||||
v[14] = v1[2] - 2 * t[2]; | ||||
} else { | ||||
if(half_state == 1) | ||||
f = indent * 2; | ||||
else | ||||
f = indent; | ||||
f_1 = 1.0F - f; | ||||
v[12] = (f_1 * v1[0] + f * v2[0]) - 2 * t[0]; | ||||
v[13] = (f_1 * v1[1] + f * v2[1]) - 2 * t[1]; | ||||
v[14] = (f_1 * v1[2] + f * v2[2]) - 2 * t[2]; | ||||
} | ||||
if(half_state == 1) { | ||||
v[15] = v2[0] - 2 * t[0]; | ||||
v[16] = v2[1] - 2 * t[1]; | ||||
v[17] = v2[2] - 2 * t[2]; | ||||
} else { | ||||
if(half_state == 2) | ||||
f = 1.0 - 2 * indent; | ||||
else | ||||
f = 1.0 - indent; | ||||
f_1 = 1.0F - f; | ||||
v[15] = (f_1 * v1[0] + f * v2[0]) - 2 * t[0]; | ||||
v[16] = (f_1 * v1[1] + f * v2[1]) - 2 * t[1]; | ||||
v[17] = (f_1 * v1[2] + f * v2[2]) - 2 * t[2]; | ||||
} | ||||
} else { | ||||
v[3] = v1[0] - t[0]; | ||||
v[4] = v1[1] - t[1]; | ||||
v[5] = v1[2] - t[2]; | ||||
v[6] = v2[0] - t[0]; | ||||
v[7] = v2[1] - t[1]; | ||||
v[8] = v2[2] - t[2]; | ||||
v[12] = v1[0] + t[0]; | ||||
v[13] = v1[1] + t[1]; | ||||
v[14] = v1[2] + t[2]; | ||||
v[15] = v2[0] + t[0]; | ||||
v[16] = v2[1] + t[1]; | ||||
v[17] = v2[2] + t[2]; | ||||
} | ||||
break; | ||||
case 3: | ||||
t[0] = t[0] * 2; | ||||
t[1] = t[1] * 2; | ||||
t[2] = t[2] * 2; | ||||
v[0] = color[0]; | ||||
v[1] = color[1]; | ||||
v[2] = color[2]; | ||||
if(fancy) { | ||||
float f, f_1; | ||||
if(half_state == 2) { | ||||
v[3] = v1[0] - t[0]; | ||||
v[4] = v1[1] - t[1]; | ||||
v[5] = v1[2] - t[2]; | ||||
} else { | ||||
if(half_state == 1) | ||||
f = indent * 2; | ||||
else | ||||
f = indent; | ||||
f_1 = 1.0F - f; | ||||
v[3] = (f_1 * v1[0] + f * v2[0]) - t[0]; | ||||
v[4] = (f_1 * v1[1] + f * v2[1]) - t[1]; | ||||
v[5] = (f_1 * v1[2] + f * v2[2]) - t[2]; | ||||
} | ||||
if(half_state == 1) { | ||||
v[6] = v2[0] - t[0]; | ||||
v[7] = v2[1] - t[1]; | ||||
v[8] = v2[2] - t[2]; | ||||
} else { | ||||
if(half_state == 2) | ||||
f = 1.0 - 2 * indent; | ||||
else | ||||
f = 1.0 - indent; | ||||
f_1 = 1.0F - f; | ||||
v[6] = (f_1 * v1[0] + f * v2[0]) - t[0]; | ||||
v[7] = (f_1 * v1[1] + f * v2[1]) - t[1]; | ||||
v[8] = (f_1 * v1[2] + f * v2[2]) - t[2]; | ||||
} | ||||
if(half_state == 2) { | ||||
v[12] = v1[0] + t[0]; | ||||
v[13] = v1[1] + t[1]; | ||||
v[14] = v1[2] + t[2]; | ||||
} else { | ||||
if(half_state == 1) | ||||
f = indent * 2; | ||||
else | ||||
f = indent; | ||||
f_1 = 1.0F - f; | ||||
v[12] = (f_1 * v1[0] + f * v2[0]) + t[0]; | ||||
v[13] = (f_1 * v1[1] + f * v2[1]) + t[1]; | ||||
v[14] = (f_1 * v1[2] + f * v2[2]) + t[2]; | ||||
} | ||||
if(half_state == 1) { | ||||
v[15] = v2[0] + t[0]; | ||||
v[16] = v2[1] + t[1]; | ||||
v[17] = v2[2] + t[2]; | ||||
} else { | ||||
if(half_state == 2) | ||||
f = 1.0 - 2 * indent; | ||||
else | ||||
f = 1.0 - indent; | ||||
f_1 = 1.0F - f; | ||||
v[15] = (f_1 * v1[0] + f * v2[0]) + t[0]; | ||||
v[16] = (f_1 * v1[1] + f * v2[1]) + t[1]; | ||||
v[17] = (f_1 * v1[2] + f * v2[2]) + t[2]; | ||||
} | ||||
} else { | ||||
v[3] = v1[0] - t[0]; | ||||
v[4] = v1[1] - t[1]; | ||||
v[5] = v1[2] - t[2]; | ||||
v[6] = v2[0] - t[0]; | ||||
v[7] = v2[1] - t[1]; | ||||
v[8] = v2[2] - t[2]; | ||||
v[12] = v1[0] + t[0]; | ||||
v[13] = v1[1] + t[1]; | ||||
v[14] = v1[2] + t[2]; | ||||
v[15] = v2[0] + t[0]; | ||||
v[16] = v2[1] + t[1]; | ||||
v[17] = v2[2] + t[2]; | ||||
} | ||||
v[9] = color[0]; | ||||
v[10] = color[1]; | ||||
v[11] = color[2]; | ||||
v[18] = color[0]; | ||||
v[19] = color[1]; | ||||
v[20] = color[2]; | ||||
v[21] = v1[0]; | ||||
v[22] = v1[1]; | ||||
v[23] = v1[2]; | ||||
v[24] = v2[0]; | ||||
v[25] = v2[1]; | ||||
v[26] = v2[2]; | ||||
break; | ||||
} | ||||
} | ||||
End of changes. 78 change blocks. | ||||
863 lines changed or deleted | 409 lines changed or added |