"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "layer2/RepWireBond.cpp" between
pymol-v2.1.0.tar.bz2 and pymol-open-source-2.2.0.tar.gz

About: PyMOL is a Python-enhanced molecular graphics tool. It excels at 3D visualization of proteins, small molecules, density, surfaces, and trajectories. It also includes molecular editing, ray tracing, and movies. Open Source version.

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

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)