"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "layer2/RepSurface.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.

RepSurface.cpp  (pymol-v2.1.0.tar.bz2):RepSurface.cpp  (pymol-open-source-2.2.0)
skipping to change at line 64 skipping to change at line 64
int *Vis; int *Vis;
int *T, *S, *AT; /* T=vertices, S=strips, AT=closest atom fo r vertices */ int *T, *S, *AT; /* T=vertices, S=strips, AT=closest atom fo r vertices */
int solidFlag; int solidFlag;
int oneColorFlag, oneColor; int oneColorFlag, oneColor;
int allVisibleFlag; int allVisibleFlag;
char *LastVisib; char *LastVisib;
int *LastColor; int *LastColor;
int ColorInvalidated; int ColorInvalidated;
int Type; int Type;
float max_vdw; float max_vdw;
CGO *debug;
/* These variables are for using the shader. All of them */ /* These variables are for using the shader. All of them */
/* are allocated/set when generate_shader_cgo to minimize */ /* are allocated/set when generate_shader_cgo to minimize */
/* allocation during the rendering loop. */ /* allocation during the rendering loop. */
CGO *shaderCGO, *pickingCGO; CGO *shaderCGO, *pickingCGO;
short dot_as_spheres; short dot_as_spheres;
uint *vertexIndices; /* the vertex index order for transparency, computed each #ifdef _PYMOL_IOS
frame and passed to VBO */ #endif
float *sum; /* the sum of the x,y,z for each triangle. used to compute zvalue
. */
float *z_value; /* the z value for each triangle, computed each frame. */
int n_tri; /* the number of triangles in the transparent surface */
int *ix; /* the triangle index order for transparency, computed each frame. */
} RepSurface; } RepSurface;
void RepSurfaceFree(RepSurface * I); void RepSurfaceFree(RepSurface * I);
int RepSurfaceSameVis(RepSurface * I, CoordSet * cs); int RepSurfaceSameVis(RepSurface * I, CoordSet * cs);
void RepSurfaceColor(RepSurface * I, CoordSet * cs); void RepSurfaceColor(RepSurface * I, CoordSet * cs);
void RepSurfaceSmoothEdges(RepSurface * I);
static void setShaderCGO(RepSurface * I, CGO * cgo) {
if (I->shaderCGO != I->pickingCGO) {
CGOFree(I->shaderCGO);
}
I->shaderCGO = cgo;
}
static void setPickingCGO(RepSurface * I, CGO * cgo) {
if (I->shaderCGO != I->pickingCGO) {
CGOFree(I->pickingCGO);
}
I->pickingCGO = cgo;
}
void RepSurfaceFree(RepSurface * I) void RepSurfaceFree(RepSurface * I)
{ {
VLAFreeP(I->V); VLAFreeP(I->V);
VLAFreeP(I->VN); VLAFreeP(I->VN);
if (I->pickingCGO && I->pickingCGO!=I->shaderCGO){ setPickingCGO(I, NULL);
CGOFree(I->pickingCGO); setShaderCGO(I, NULL);
I->pickingCGO = NULL; #ifdef _PYMOL_IOS
} #endif
if (I->shaderCGO){
CGOFree(I->shaderCGO);
I->shaderCGO = NULL;
}
if (I->vertexIndices){
FreeP(I->vertexIndices);
}
if (I->sum){
FreeP(I->sum);
}
if (I->z_value){
FreeP(I->z_value);
}
if (I->ix){
FreeP(I->ix);
}
FreeP(I->VC); FreeP(I->VC);
FreeP(I->VA); FreeP(I->VA);
if (I->VAO){ if (I->VAO){
VLAFreeP(I->VAO); VLAFreeP(I->VAO);
I->VAO = 0; I->VAO = 0;
} }
FreeP(I->RC); FreeP(I->RC);
FreeP(I->Vis); FreeP(I->Vis);
FreeP(I->LastColor); FreeP(I->LastColor);
FreeP(I->LastVisib); FreeP(I->LastVisib);
CGOFree(I->debug);
VLAFreeP(I->T); VLAFreeP(I->T);
VLAFreeP(I->S); VLAFreeP(I->S);
VLAFreeP(I->AT); VLAFreeP(I->AT);
RepPurge(&I->R); /* unnecessary, but a good idea */ RepPurge(&I->R); /* unnecessary, but a good idea */
OOFreeP(I); OOFreeP(I);
} }
typedef struct { typedef struct {
int nDot; int nDot;
float *dot; float *dot;
skipping to change at line 157 skipping to change at line 151
static void SolventDotFree(SolventDot * I) static void SolventDotFree(SolventDot * I)
{ {
if(I) { if(I) {
VLAFreeP(I->dot); VLAFreeP(I->dot);
VLAFreeP(I->dotNormal); VLAFreeP(I->dotNormal);
VLAFreeP(I->dotCode); VLAFreeP(I->dotCode);
} }
OOFreeP(I); OOFreeP(I);
} }
#ifndef PURE_OPENGL_ES_2
static
void immediate_draw_masked_vertices(
const float * vc, // colors
const float * vn, // normals
const float * v, // vertices
const int * mask, // mask
int count)
{
for (int i = 0; i < count; ++i) {
if (!mask[i])
continue;
int i3 = i * 3;
if (vc) glColor3fv(vc + i3);
if (vn) glNormal3fv(vn + i3);
glVertex3fv(v + i3);
}
}
static
void immediate_draw_indexed_vertices(
const float * vc, // colors
const float * vn, // normals
const float * v, // vertices
const int * indices, // indices
int count)
{
for (int i = 0; i < count; ++i) {
int i3 = indices[i] * 3;
if (vc) glColor3fv(vc + i3);
if (vn) glNormal3fv(vn + i3);
glVertex3fv(v + i3);
}
}
static
void immediate_draw_indexed_vertices_alpha(
const float * vc, // colors
const float * va, // alpha array
float alpha, // alpha value if va is NULL
const float * vn, // normals
const float * v, // vertices
const int * indices, // indices
int count)
{
for (int i = 0; i < count; ++i) {
int i3 = indices[i] * 3;
if (vc)
glColor4f(vc[i3], vc[i3 + 1], vc[i3 + 2],
va ? va[indices[i]] : alpha);
if (vn) glNormal3fv(vn + i3);
glVertex3fv(v + i3);
}
}
#endif
static
bool visibility_test(
bool proximityFlag,
const int * vi, // visibility array
const int * t) // indices
{
if (proximityFlag)
return (vi[t[0]] || vi[t[1]] || vi[t[2]]);
return (vi[t[0]] && vi[t[1]] && vi[t[2]]);
}
static int check_and_add(int *cache, int spacing, int t0, int t1) static int check_and_add(int *cache, int spacing, int t0, int t1)
{ {
int *rec; int *rec;
int cnt; int cnt;
t0++; t0++;
t1++; t1++;
rec = cache + spacing * t0; rec = cache + spacing * t0;
cnt = spacing; cnt = spacing;
while(cnt > 0) { while(cnt > 0) {
skipping to change at line 193 skipping to change at line 254
break; break;
} }
rec++; rec++;
cnt--; cnt--;
} }
return 0; return 0;
} }
#define CLAMP_VALUE(v) ((v>1.f) ? 1.f : (v < 0.f) ? 0.f : v) #define CLAMP_VALUE(v) ((v>1.f) ? 1.f : (v < 0.f) ? 0.f : v)
void RepSurfaceSortIX(PyMOLGlobals * G, RepSurface *I, int t_mode){
float *z_value = NULL, *zv;
float *sum, *sv;
float matrix[16];
int idx;
int *ix = NULL;
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
sum = I->sum;
z_value = I->z_value;
ix = I->ix;
zv = z_value;
sv = sum;
/* for each triangle, computes the z */
for (idx = 0; idx<I->n_tri; idx++){
*(zv++) = matrix[2] * sv[0] + matrix[6] * sv[1] + matrix[10] * sv[2];
sv += 3;
}
switch (t_mode) {
case 1:
UtilSemiSortFloatIndex(I->n_tri, z_value, ix, true);
/* UtilSortIndex(n_tri,z_value,ix,(UtilOrderFn*)ZOrderFn); */
break;
default:
UtilSemiSortFloatIndex(I->n_tri, z_value, ix, false);
/* UtilSortIndex(n_tri,z_value,ix,(UtilOrderFn*)ZRevOrderFn); */
break;
}
}
static int AtomInfoIsMasked(ObjectMolecule *obj, int atm){ static int AtomInfoIsMasked(ObjectMolecule *obj, int atm){
AtomInfoType *ait; AtomInfoType *ait;
if (atm < 0) if (atm < 0)
return cPickableNoPick; return cPickableNoPick;
ait = &obj->AtomInfo[atm]; ait = &obj->AtomInfo[atm];
return (ait->masked ? cPickableNoPick : cPickableAtom); return (ait->masked ? cPickableNoPick : cPickableAtom);
} }
static void RepSurfaceRender(RepSurface * I, RenderInfo * info) static int RepSurfaceCGOGenerate(RepSurface * I, RenderInfo * info)
{ {
CRay *ray = info->ray;
Picking **pick = info->pick;
PyMOLGlobals *G = I->R.G; PyMOLGlobals *G = I->R.G;
float *v = I->V; float *v = I->V;
float *vn = I->VN; float *vn = I->VN;
float *vc = I->VC; float *vc = I->VC;
float *va = I->VA; float *va = I->VA;
int *rc = I->RC;
int *t = I->T; int *t = I->T;
int *s = I->S; int *s = I->S;
int c = I->N; int c = I->N;
int *vi = I->Vis; int *vi = I->Vis;
int *at = I->AT; int *at = I->AT;
int ok = true; int ok = true;
float alpha; float alpha;
int t_mode; int t_mode;
CGO *convertcgo = NULL;
bool pick_surface = SettingGet_b(G, I->R.cs->Setting, I->R.obj->Setting, cSett
ing_pick_surface);
short dot_as_spheres = SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cS etting_dot_as_spheres); short dot_as_spheres = SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cS etting_dot_as_spheres);
float ambient_occlusion_scale = 0.f;
int ambient_occlusion_mode = SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setti
ng, cSetting_ambient_occlusion_mode);
int ambient_occlusion_mode_div_4 = 0;
if (ambient_occlusion_mode){
ambient_occlusion_scale = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Settin
g, cSetting_ambient_occlusion_scale);
ambient_occlusion_mode_div_4 = ambient_occlusion_mode / 4;
}
if((I->Type != 1) && (!s)) {
return;
}
alpha = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_transpar ency); alpha = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_transpar ency);
alpha = 1.0F - alpha; alpha = 1.0F - alpha;
if(fabs(alpha - 1.0) < R_SMALL4) if(fabs(alpha - 1.0) < R_SMALL4)
alpha = 1.0F; alpha = 1.0F;
if(ray) {
ray->transparentf(1.0F - alpha);
if(I->Type == 1) {
/* dot surface */
float radius;
radius = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_dot
_radius);
if(radius == 0.0F) {
radius = ray->PixelRadius * SettingGet_f(G, I->R.cs->Setting,
I->R.obj->Setting,
cSetting_dot_width) / 1.4142F;
}
if(I->oneColorFlag) {
float col[3];
ColorGetEncoded(G, I->oneColor, col);
ray->color3fv(col);
}
if(c)
while(ok && c--) {
if(*vi) {
if(!I->oneColorFlag) {
ray->color3fv(vc);
}
ok &= ray->sphere3fv(v, radius);
}
vi++;
vc += 3;
v += 3;
}
} else if((I->Type == 0) || (I->Type == 3) || (I->Type == 4) || (I->Type ==
5)) { /* solid surface */
c = I->NT;
if(I->oneColorFlag) {
float col[3], col1[3], col2[3], col3[3];
ColorGetEncoded(G, I->oneColor, col);
while(ok && c--) {
if((I->proximity
&& ((*(vi + (*t))) || (*(vi + (*(t + 1)))) || (*(vi + (*(t + 2))))
))
|| ((*(vi + (*t))) && (*(vi + (*(t + 1)))) && (*(vi + (*(t + 2)))))
){
copy3f(col, col1);
copy3f(col, col2);
copy3f(col, col3);
if (I->VAO){
float ao1, ao2, ao3;
switch (ambient_occlusion_mode_div_4){
case 1:
ao1 = 1.f-ambient_occlusion_scale*(*(I->VAO + *t));
ao2 = 1.f-ambient_occlusion_scale*(*(I->VAO + *(t+1)));
ao3 = 1.f-ambient_occlusion_scale*(*(I->VAO + *(t+2)));
break;
case 2:
ao1 = cos(.5f * PI * CLAMP_VALUE(ambient_occlusion_scale*(*(I->VA
O + *t))));
ao2 = cos(.5f * PI * CLAMP_VALUE(ambient_occlusion_scale*(*(I->VA
O + *(t+1)))));
ao3 = cos(.5f * PI * CLAMP_VALUE(ambient_occlusion_scale*(*(I->VA
O + *(t+2)))));
break;
default:
ao1 = CLAMP_VALUE(1.f / (1.f + exp(.5f*((ambient_occlusion_scale*
(*(I->VAO + *t))) - 10.f))));
ao2 = CLAMP_VALUE(1.f / (1.f + exp(.5f*((ambient_occlusion_scale*
(*(I->VAO + *(t+1)))) - 10.f))));
ao3 = CLAMP_VALUE(1.f / (1.f + exp(.5f*((ambient_occlusion_scale*
(*(I->VAO + *(t+2)))) - 10.f))));
}
mult3f(col1, ao1, col1);
mult3f(col2, ao2, col2);
mult3f(col3, ao3, col3);
}
ok &= ray->triangle3fv(v + (*t) * 3, v + (*(t + 1)) * 3, v + (*(t + 2
)) * 3,
vn + (*t) * 3, vn + (*(t + 1)) * 3, vn + (*(t
+ 2)) * 3,
col1, col2, col3);
}
t += 3;
}
} else {
while(ok && c--) {
int ttA = *t, ttB = *(t + 1), ttC = *(t + 2);
if((I->proximity && ((*(vi + ttA)) || (*(vi + ttB)) || (*(vi + ttC))))
||
((*(vi + ttA)) && (*(vi + ttB)) && (*(vi + ttC)))) {
int ttA3 = ttA * 3, ttB3 = ttB * 3, ttC3 = ttC * 3;
float cA[3], cB[3], cC[3];
copy3f(vc + ttA3, cA);
copy3f(vc + ttB3, cB);
copy3f(vc + ttC3, cC);
// register float *cA = vc + ttA3, *cB = vc + ttB3, *cC =
vc + ttC3;
if(rc) {
if(rc[ttA] < -1)
ColorGetEncoded(G, rc[ttA], cA);
// ColorGetEncoded(G, rc[ttA], (cA = colA));
if(rc[ttB] < -1)
ColorGetEncoded(G, rc[ttB], cB);
// ColorGetEncoded(G, rc[ttB], (cB = colB));
if(rc[ttC] < -1)
ColorGetEncoded(G, rc[ttC], cC);
// ColorGetEncoded(G, rc[ttC], (cC = colC));
}
if((*(vi + ttA)) || (*(vi + ttB)) || (*(vi + ttC))) {
if (I->VAO){
float ao1, ao2, ao3;
switch (ambient_occlusion_mode_div_4){
case 1:
ao1 = 1.f-ambient_occlusion_scale*(*(I->VAO + *t));
ao2 = 1.f-ambient_occlusion_scale*(*(I->VAO + *(t+1)));
ao3 = 1.f-ambient_occlusion_scale*(*(I->VAO + *(t+2)));
break;
case 2:
ao1 = cos(.5f * PI * CLAMP_VALUE(ambient_occlusion_scale*(*(I->
VAO + *t))));
ao2 = cos(.5f * PI * CLAMP_VALUE(ambient_occlusion_scale*(*(I->
VAO + *(t+1)))));
ao3 = cos(.5f * PI * CLAMP_VALUE(ambient_occlusion_scale*(*(I->
VAO + *(t+2)))));
break;
default:
ao1 = CLAMP_VALUE(1.f / (1.f + exp(.5f*((ambient_occlusion_scal
e*(*(I->VAO + *t))) - 10.f))));
ao2 = CLAMP_VALUE(1.f / (1.f + exp(.5f*((ambient_occlusion_scal
e*(*(I->VAO + *(t+1)))) - 10.f))));
ao3 = CLAMP_VALUE(1.f / (1.f + exp(.5f*((ambient_occlusion_scal
e*(*(I->VAO + *(t+2)))) - 10.f))));
}
mult3f(cA, ao1, cA);
mult3f(cB, ao2, cB);
mult3f(cC, ao3, cC);
}
if(va) {
ok &= ray->triangleTrans3fv(v + ttA3, v + ttB3, v + ttC3,
vn + ttA3, vn + ttB3, vn + ttC3,
cA, cB, cC,
1.0F - va[ttA], 1.0F - va[ttB], 1.0F
- va[ttC]);
} else {
ok &= ray->triangle3fv(v + ttA3, v + ttB3, v + ttC3,
vn + ttA3, vn + ttB3, vn + ttC3, cA, cB,
cC);
}
}
}
t += 3;
}
}
} else if(I->Type == 2) { /* triangle mesh surface */
float radius; setShaderCGO(I, CGONew(G));
int t0, t1, t2;
int spacing = 10;
int *cache = Calloc(int, spacing * (I->N + 1));
CHECKOK(ok, cache);
radius = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_mes if (!I->shaderCGO)
h_radius); return false;
if(ok && radius == 0.0F) { I->shaderCGO->use_shader = true;
float line_width = I->dot_as_spheres = dot_as_spheres;
SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_mesh_wid
th);
line_width = SceneGetDynamicLineWidth(info, line_width);
radius = ray->PixelRadius * line_width / 2.0F; if (I->Type == 1) {
/* no triangle information, so we're rendering dots only */
int normals =
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_dot_normals)
;
if(!normals){
CGOResetNormal(I->shaderCGO, true);
}
if((alpha != 1.0)) {
CGOAlpha(I->shaderCGO, alpha);
} }
if (ok){ if (dot_as_spheres){
c = I->NT; if(c) {
if(I->oneColorFlag) { ok &= CGOColor(I->shaderCGO, 1.0, 0.0, 0.0);
float col[3]; if(ok && I->oneColorFlag) {
ColorGetEncoded(G, I->oneColor, col); ok &= CGOColorv(I->shaderCGO, ColorGet(G, I->oneColor));
while(ok && c--) {
t0 = (*t);
t1 = (*(t + 1));
t2 = (*(t + 2));
if((I->proximity && ((*(vi + t0)) || (*(vi + t1)) || (*(vi + t2)))) |
|
((*(vi + t0)) && (*(vi + t1)) && (*(vi + t2)))) {
if(!check_and_add(cache, spacing, t0, t1))
ok &= ray->sausage3fv(v + t0 * 3, v + t1 * 3, radius, col, col);
if(!check_and_add(cache, spacing, t1, t2))
ok &= ray->sausage3fv(v + t1 * 3, v + t2 * 3, radius, col, col);
if(!check_and_add(cache, spacing, t2, t0))
ok &= ray->sausage3fv(v + t2 * 3, v + t0 * 3, radius, col, col);
}
t += 3;
} }
} else {
while(ok && c--) { while(ok && c--) {
t0 = (*t); if(*vi) {
t1 = (*(t + 1)); if(!I->oneColorFlag) {
t2 = (*(t + 2)); ok &= CGOColorv(I->shaderCGO, vc);
if((I->proximity && ((*(vi + t0)) || (*(vi + t1)) || (*(vi + t2)))) |
|
((*(vi + t0)) && (*(vi + t1)) && (*(vi + t2))))
if((*(vi + t0)) || (*(vi + t1)) || (*(vi + t2))) {
if(!check_and_add(cache, spacing, t0, t1))
ok &= ray->sausage3fv(v + t0 * 3, v + t1 * 3, radius, vc + t0 *
3,
vc + t1 * 3);
if(!check_and_add(cache, spacing, t1, t2))
ok &= ray->sausage3fv(v + t1 * 3, v + t2 * 3, radius, vc + t1 *
3,
vc + t2 * 3);
if(!check_and_add(cache, spacing, t2, t0))
ok &= ray->sausage3fv(v + t2 * 3, v + t0 * 3, radius, vc + t2 *
3,
vc + t0 * 3);
} }
t += 3; if(ok && normals)
ok &= CGONormalv(I->shaderCGO, vn);
if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, *at, AtomInfoIsMasked((ObjectMol
ecule*)I->R.obj, *at));
if (ok)
ok &= CGOSphere(I->shaderCGO, v, 1.f);
}
vi++;
vc += 3;
vn += 3;
v += 3;
at++;
} }
} }
FreeP(cache); } else {
} ok &= CGODotwidth(I->shaderCGO, SettingGet_f
} (G, I->R.cs->Setting, I->R.obj->Setting, cSetting_dot_w
if (ok){ idth));
ray->transparentf(0.0); if(ok && c) {
} else { ok &= CGOColor(I->shaderCGO, 1.0, 0.0, 0.0);
/* If not ok, then Clear Entire RepSurface, not just the ray object */ ok &= CGOBegin(I->shaderCGO, GL_POINTS);
if(ok && I->oneColorFlag) {
} ok &= CGOColorv(I->shaderCGO, ColorGet(G, I->oneColor));
} else if(G->HaveGUI && G->ValidContext) {
/* Not ray tracing, but rendering */
if(pick) {
int pick_surface = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cS
etting_pick_surface);
int no_pick_but_write_to_depth_buffer = (!pick_surface && (alpha == 1.0));
if (I->pickingCGO && (pick_surface || no_pick_but_write_to_depth_buffer)){
I->pickingCGO->use_shader = false;
I->pickingCGO->no_pick = no_pick_but_write_to_depth_buffer;
CGORenderGLPicking(I->pickingCGO, pick, &I->R.context, I->R.cs->Setting,
I->R.obj->Setting);
}
} else {
short use_shader, generate_shader_cgo = 0;
use_shader = SettingGetGlobal_b(G, cSetting_surface_use_shader) &
SettingGetGlobal_b(G, cSetting_use_shaders);
if (I->shaderCGO && (!use_shader || CGOCheckWhetherToFree(G, I->shaderCGO)
||
(I->Type == 1 && I->dot_as_spheres != dot_as_spheres))
){
CGOFree(I->shaderCGO);
I->shaderCGO = NULL;
}
if (use_shader){
if (!I->shaderCGO){
I->shaderCGO = CGONew(G);
CHECKOK(ok, I->shaderCGO);
if (ok){
I->shaderCGO->use_shader = true;
I->dot_as_spheres = dot_as_spheres;
generate_shader_cgo = 1;
} }
} else {
CShaderPrg * shaderPrg = 0; while(ok && c--) {
if (I->Type == 1){ if(*vi) {
if (dot_as_spheres){ if(!I->oneColorFlag) {
float radius = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, ok &= CGOColorv(I->shaderCGO, vc);
cSetting_dot_width)
* info->vertex_scale;
shaderPrg = CShaderPrg_Enable_DefaultSphereShader(G);
CShaderPrg_Set1f(shaderPrg, "sphere_size_scale", fabs(radius));
} else {
shaderPrg = CShaderPrg_Enable_DefaultShader(G);
SceneResetNormalUseShaderAttribute(G, 0, true, CShaderPrg_GetAttrib
Location(shaderPrg, "a_Normal"));
}
} else if (I->Type == 2) {
float mesh_width = SettingGet_f(G, I->R.obj->Setting, NULL, cSetting_
mesh_width);
shaderPrg = CShaderPrg_Enable_CylinderShader(G);
CShaderPrg_Set1f(shaderPrg, "uni_radius", SceneGetLineWidthForCylinde
rs(G, info, mesh_width));
} else {
shaderPrg = CShaderPrg_Enable_DefaultShader(G);
CShaderPrg_SetLightingEnabled(shaderPrg, 1);
CShaderPrg_Set1f(shaderPrg, "ambient_occlusion_scale", ambient_occlus
ion_scale);
CShaderPrg_Set1i(shaderPrg, "use_interior_color_threshold", 1);
if((alpha != 1.0) || va) {
/* Updating indices if alpha */
t_mode =
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting,
cSetting_transparency_mode);
if(info && info->alpha_cgo) {
t_mode = 0;
} }
if(t_mode) { if(normals){
RepSurfaceSortIX(G, I, t_mode); CGONormalv(I->shaderCGO, vn);
/* Now once we have ix, we can update the vertexIndices that are
stored
as VBOs */
if (I->ix){
float *pc = CGOGetNextDrawBufferedIndex(I->shaderCGO->op);
int *ix = I->ix;
if (pc){
int nindices = CGO_get_int(pc+3), c, pl, idx;
uint vbuf = CGO_get_int(pc+8);
uint *vertexIndices;
vertexIndices = I->vertexIndices;
// vertexIndices = Alloc(uint, nindices);
if (!vertexIndices){
PRINTFB(I->R.G, FB_RepSurface, FB_Errors) "ERROR: RepSurfac
eRender() vertexIndices is not set, nindices=%d\n", nindices ENDFB(I->R.G);
}
/* updates the vertexIndices from the ix array */
for(c = 0, pl=0; c < I->n_tri; c++) {
idx = ix[c] * 3;
vertexIndices[pl++] = idx;
vertexIndices[pl++] = idx + 1;
vertexIndices[pl++] = idx + 2;
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbuf);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint)*nindices,
vertexIndices, GL_STATIC_DRAW);
}
}
} }
if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, *at, AtomInfoIsMasked((ObjectMol
ecule*)I->R.obj, *at));
if (ok)
ok &= CGOVertexv(I->shaderCGO, v);
} }
vi++;
vc += 3;
vn += 3;
v += 3;
at++;
} }
{ if (ok)
float *color; ok &= CGOEnd(I->shaderCGO);
color = ColorGet(G, I->R.obj->Color);
I->shaderCGO->enable_shaders = shaderPrg ? 0 : 1;
CGORenderGL(I->shaderCGO, color, NULL, NULL, info, &I->R);
}
if (shaderPrg)
CShaderPrg_Disable(shaderPrg);
return;
} }
} }
} else if(I->Type == 2) { /* rendering triangle mesh */
if(I->debug)
CGORenderGL(I->debug, NULL, NULL, NULL, info, &I->R);
if(I->Type == 1) {
/* no triangle information, so we're rendering dots only */
int normals = int normals =
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_dot_norm SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_mesh_nor
als); mals);
int lighting = if(ok && !normals){
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_dot_ligh ok &= CGOResetNormal(I->shaderCGO, true);
ting);
if(!normals){
if (generate_shader_cgo){
CGOResetNormal(I->shaderCGO, true);
} else {
SceneResetNormal(G, true);
}
} }
if(!lighting)
if(!info->line_lighting)
glDisable(GL_LIGHTING);
if (generate_shader_cgo){
if((alpha != 1.0)) {
CGOAlpha(I->shaderCGO, alpha);
}
if (dot_as_spheres){
if(c) {
ok &= CGOColor(I->shaderCGO, 1.0, 0.0, 0.0);
if(ok && I->oneColorFlag) {
ok &= CGOColorv(I->shaderCGO, ColorGet(G, I->oneColor));
}
while(ok && c--) {
if(*vi) {
if(!I->oneColorFlag) {
ok &= CGOColorv(I->shaderCGO, vc);
}
if(ok && normals)
ok &= CGONormalv(I->shaderCGO, vn);
if (ok)
ok &= CGOPickColor(I->shaderCGO, *at, AtomInfoIsMasked((Objec
tMolecule*)I->R.obj, *at));
if (ok)
ok &= CGOSphere(I->shaderCGO, v, 1.f);
}
vi++;
vc += 3;
vn += 3;
v += 3;
at++;
}
}
} else {
ok &= CGODotwidth(I->shaderCGO, SettingGet_f
(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_d
ot_width));
if(ok && c) {
ok &= CGOColor(I->shaderCGO, 1.0, 0.0, 0.0);
ok &= CGOBegin(I->shaderCGO, GL_POINTS);
if(ok && I->oneColorFlag) {
ok &= CGOColorv(I->shaderCGO, ColorGet(G, I->oneColor));
}
while(ok && c--) {
if(*vi) {
if(!I->oneColorFlag) {
ok &= CGOColorv(I->shaderCGO, vc);
}
/* if(normals){
CGONormalv(I->shaderCGO, vn);
}*/
if (ok)
ok &= CGOPickColor(I->shaderCGO, *at, AtomInfoIsMasked((Objec
tMolecule*)I->R.obj, *at));
if (ok)
ok &= CGOVertexv(I->shaderCGO, v);
}
vi++;
vc += 3;
vn += 3;
v += 3;
at++;
}
if (ok)
ok &= CGOEnd(I->shaderCGO);
}
}
} else {
glPointSize(SettingGet_f
(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_dot_widt
h));
if(c) {
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POINTS);
if(I->oneColorFlag) {
glColor3fv(ColorGet(G, I->oneColor));
}
while(c--) {
if(*vi) {
if(!I->oneColorFlag) {
glColor3fv(vc);
}
if(normals)
glNormal3fv(vn);
glVertex3fv(v);
}
vi++;
vc += 3;
vn += 3;
v += 3;
}
glEnd();
}
} /* else use shader */
if(!lighting)
glEnable(GL_LIGHTING);
} else if(I->Type == 2) { /* rendering triangle mesh */
int normals =
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_mesh_nor
mals);
if(ok && !normals){
if (generate_shader_cgo){
ok &= CGOResetNormal(I->shaderCGO, true);
} else {
SceneResetNormal(G, true);
}
}
int lighting =
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_mesh_lig
hting);
if(!lighting)
if(!info->line_lighting)
glDisable(GL_LIGHTING);
if (ok) { if (ok) {
float line_width = float line_width =
SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_mesh_w idth); SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_mesh_w idth);
line_width = SceneGetDynamicLineWidth(info, line_width); line_width = SceneGetDynamicLineWidth(info, line_width);
if (generate_shader_cgo){ ok &= CGOSpecial(I->shaderCGO, LINEWIDTH_DYNAMIC_MESH);
ok &= CGOLinewidthSpecial(I->shaderCGO, LINEWIDTH_DYNAMIC_MESH);
} else {
glLineWidth(line_width);
}
c = I->NT; c = I->NT;
if(ok && c) { if(ok && c) {
if(I->oneColorFlag) { if(I->oneColorFlag) {
if (generate_shader_cgo){
ok &= CGOColorv(I->shaderCGO, ColorGet(G, I->oneColor)); ok &= CGOColorv(I->shaderCGO, ColorGet(G, I->oneColor));
while(ok && c--) { while(ok && c--) {
if((I->proximity if (visibility_test(I->proximity, vi, t)) {
&& ((*(vi + (*t))) || (*(vi + (*(t + 1)))) || (*(vi + (*(
t + 2))))))
|| ((*(vi + (*t))) && (*(vi + (*(t + 1)))) && (*(vi + (*(t
+ 2)))))) {
if(normals) { if(normals) {
int idx; int idx;
ok &= CGOBegin(I->shaderCGO, GL_LINE_STRIP); ok &= CGOBegin(I->shaderCGO, GL_LINE_STRIP);
idx = (*(t + 2)); idx = (*(t + 2));
if (ok) if (ok)
ok &= CGONormalv(I->shaderCGO, vn + idx * 3); ok &= CGONormalv(I->shaderCGO, vn + idx * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
idx = (*t); idx = (*t);
if (ok) if (ok)
ok &= CGONormalv(I->shaderCGO, vn + idx * 3); ok &= CGONormalv(I->shaderCGO, vn + idx * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
t++; t++;
idx = (*t); idx = (*t);
if (ok) if (ok)
ok &= CGONormalv(I->shaderCGO, vn + idx * 3); ok &= CGONormalv(I->shaderCGO, vn + idx * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
t++; t++;
idx = (*t); idx = (*t);
if (ok) if (ok)
ok &= CGONormalv(I->shaderCGO, vn + idx * 3); ok &= CGONormalv(I->shaderCGO, vn + idx * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
t++; t++;
if (ok) if (ok)
ok &= CGOEnd(I->shaderCGO); ok &= CGOEnd(I->shaderCGO);
} else { } else {
int idx; int idx;
ok &= CGOBegin(I->shaderCGO, GL_LINE_STRIP); ok &= CGOBegin(I->shaderCGO, GL_LINE_STRIP);
idx = (*(t + 2)); idx = (*(t + 2));
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
idx = *t; idx = *t;
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
t++; t++;
idx = *t; idx = *t;
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
t++; t++;
idx = *t; idx = *t;
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
t++; t++;
if (ok) if (ok)
ok &= CGOEnd(I->shaderCGO); ok &= CGOEnd(I->shaderCGO);
} }
} else
t += 3;
}
} else {
glColor3fv(ColorGet(G, I->oneColor));
while(c--) {
if((I->proximity
&& ((*(vi + (*t))) || (*(vi + (*(t + 1)))) || (*(vi + (*(t +
2))))))
|| ((*(vi + (*t))) && (*(vi + (*(t + 1)))) && (*(vi + (*(t +
2)))))) {
if(normals) {
#ifdef PURE_OPENGL_ES_2
/* TODO */
#else
glBegin(GL_LINE_STRIP);
glNormal3fv(vn + (*(t + 2)) * 3);
glVertex3fv(v + (*(t + 2)) * 3);
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glEnd();
#endif
} else {
#ifdef PURE_OPENGL_ES_2
/* TODO */
#else
glBegin(GL_LINE_STRIP);
glVertex3fv(v + (*(t + 2)) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glVertex3fv(v + (*t) * 3);
t++;
glVertex3fv(v + (*t) * 3);
t++;
glEnd();
#endif
}
} else } else
t += 3; t += 3;
} }
} /* end else use_shader */
} else { /* not oneColorFlag */ } else { /* not oneColorFlag */
if (generate_shader_cgo){
while(ok && c--) { while(ok && c--) {
if((I->proximity if (visibility_test(I->proximity, vi, t)) {
&& ((*(vi + (*t))) || (*(vi + (*(t + 1)))) || (*(vi + (*(
t + 2))))))
|| ((*(vi + (*t))) && (*(vi + (*(t + 1)))) && (*(vi + (*(t
+ 2)))))) {
if(normals) { if(normals) {
int idx; int idx;
ok &= CGOBegin(I->shaderCGO, GL_LINE_STRIP); ok &= CGOBegin(I->shaderCGO, GL_LINE_STRIP);
idx = (*(t + 2)); idx = (*(t + 2));
if (ok) if (ok)
ok &= CGOColorv(I->shaderCGO, vc + idx * 3); ok &= CGOColorv(I->shaderCGO, vc + idx * 3);
if (ok) if (ok)
ok &= CGONormalv(I->shaderCGO, vn + idx * 3); ok &= CGONormalv(I->shaderCGO, vn + idx * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
idx = (*t); idx = (*t);
if (ok) if (ok)
ok &= CGOColorv(I->shaderCGO, vc + idx * 3); ok &= CGOColorv(I->shaderCGO, vc + idx * 3);
if (ok) if (ok)
ok &= CGONormalv(I->shaderCGO, vn + idx * 3); ok &= CGONormalv(I->shaderCGO, vn + idx * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
t++; t++;
idx = (*t); idx = (*t);
if (ok) if (ok)
ok &= CGOColorv(I->shaderCGO, vc + idx * 3); ok &= CGOColorv(I->shaderCGO, vc + idx * 3);
if (ok) if (ok)
ok &= CGONormalv(I->shaderCGO, vn + idx * 3); ok &= CGONormalv(I->shaderCGO, vn + idx * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
t++; t++;
idx = (*t); idx = (*t);
if (ok) if (ok)
ok &= CGOColorv(I->shaderCGO, vc + idx * 3); ok &= CGOColorv(I->shaderCGO, vc + idx * 3);
if (ok) if (ok)
ok &= CGONormalv(I->shaderCGO, vn + idx * 3); ok &= CGONormalv(I->shaderCGO, vn + idx * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
t++; t++;
if (ok) if (ok)
ok &= CGOEnd(I->shaderCGO); ok &= CGOEnd(I->shaderCGO);
} else { } else {
int idx; int idx;
ok &= CGOBegin(I->shaderCGO, GL_LINE_STRIP); ok &= CGOBegin(I->shaderCGO, GL_LINE_STRIP);
idx = (*(t + 2)); idx = (*(t + 2));
if (ok) if (ok)
ok &= CGOColorv(I->shaderCGO, vc + idx * 3); ok &= CGOColorv(I->shaderCGO, vc + idx * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
idx = (*t); idx = (*t);
if (ok) if (ok)
ok &= CGOColorv(I->shaderCGO, vc + idx * 3); ok &= CGOColorv(I->shaderCGO, vc + idx * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
t++; t++;
idx = (*t); idx = (*t);
if (ok) if (ok)
ok &= CGOColorv(I->shaderCGO, vc + idx * 3); ok &= CGOColorv(I->shaderCGO, vc + idx * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
t++; t++;
idx = (*t); idx = (*t);
if (ok) if (ok)
ok &= CGOColorv(I->shaderCGO, vc + idx * 3); ok &= CGOColorv(I->shaderCGO, vc + idx * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIs Masked((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, v + idx * 3); ok &= CGOVertexv(I->shaderCGO, v + idx * 3);
t++; t++;
if (ok) if (ok)
ok &= CGOEnd(I->shaderCGO); ok &= CGOEnd(I->shaderCGO);
} }
} else } else
t += 3; t += 3;
} }
} else {
while(c--) {
if((I->proximity
&& ((*(vi + (*t))) || (*(vi + (*(t + 1)))) || (*(vi + (*(t +
2))))))
|| ((*(vi + (*t))) && (*(vi + (*(t + 1)))) && (*(vi + (*(t +
2)))))) {
if(normals) {
#ifdef PURE_OPENGL_ES_2
/* TODO */
#else
glBegin(GL_LINE_STRIP);
glColor3fv(vc + (*(t + 2)) * 3);
glNormal3fv(vn + (*(t + 2)) * 3);
glVertex3fv(v + (*(t + 2)) * 3);
glColor3fv(vc + (*t) * 3);
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glColor3fv(vc + (*t) * 3);
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glColor3fv(vc + (*t) * 3);
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glEnd();
#endif
} else {
#ifdef PURE_OPENGL_ES_2
/* TODO */
#else
glBegin(GL_LINE_STRIP);
glColor3fv(vc + (*(t + 2)) * 3);
glVertex3fv(v + (*(t + 2)) * 3);
glColor3fv(vc + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glColor3fv(vc + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glColor3fv(vc + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glEnd();
#endif
}
} else
t += 3;
}
}
} /* end else use_shader */
} }
} }
if(!lighting) }
glEnable(GL_LIGHTING);
} else { } else {
/* we're rendering triangles */ /* we're rendering triangles */
if((alpha != 1.0) || va) { if((alpha != 1.0) || va) {
t_mode = t_mode =
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting,
cSetting_transparency_mode); cSetting_transparency_mode);
if(info && info->alpha_cgo) { if(info && info->alpha_cgo) {
t_mode = 0; t_mode = 0;
} }
if(t_mode) { if(t_mode) {
float **t_buf = NULL, **tb; float **t_buf = NULL, **tb;
float *z_value = NULL, *zv; float *z_value = NULL, *zv;
int *ix = NULL; int *ix = NULL;
float *sumarray = NULL; int n_tri = 0;
int n_tri = 0, sumarraypl = 0;
float sum[3]; float sum[3];
float matrix[16]; float matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrix); glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
if(I->oneColorFlag) { if(I->oneColorFlag) {
t_buf = Alloc(float *, I->NT * 6); t_buf = Alloc(float *, I->NT * 6);
} else { } else {
t_buf = Alloc(float *, I->NT * 12); t_buf = Alloc(float *, I->NT * 12);
} }
CHECKOK(ok, t_buf); CHECKOK(ok, t_buf);
if (ok){ if (ok){
z_value = Alloc(float, I->NT); z_value = Alloc(float, I->NT);
CHECKOK(ok, z_value); CHECKOK(ok, z_value);
} }
if (ok){ if (ok){
ix = Alloc(int, I->NT); ix = Alloc(int, I->NT);
CHECKOK(ok, ix); CHECKOK(ok, ix);
} }
if (ok && use_shader && generate_shader_cgo){
sumarray = Alloc(float, I->NT * 3);
CHECKOK(ok, sumarray);
}
zv = z_value; zv = z_value;
tb = t_buf; tb = t_buf;
c = I->NT; c = I->NT;
if (ok){ if (ok){
if(I->oneColorFlag) { if(I->oneColorFlag) {
while(c--) { while(c--) {
if((I->proximity if (visibility_test(I->proximity, vi, t)) {
&& ((*(vi + (*t))) || (*(vi + (*(t + 1)))) || (*(vi + (*(t
+ 2))))))
|| ((*(vi + (*t))) && (*(vi + (*(t + 1)))) && (*(vi + (*(t +
2)))))) {
*(tb++) = vn + (*t) * 3; *(tb++) = vn + (*t) * 3;
*(tb++) = v + (*t) * 3; *(tb++) = v + (*t) * 3;
*(tb++) = vn + (*(t + 1)) * 3; *(tb++) = vn + (*(t + 1)) * 3;
*(tb++) = v + (*(t + 1)) * 3; *(tb++) = v + (*(t + 1)) * 3;
*(tb++) = vn + (*(t + 2)) * 3; *(tb++) = vn + (*(t + 2)) * 3;
*(tb++) = v + (*(t + 2)) * 3; *(tb++) = v + (*(t + 2)) * 3;
add3f(tb[-1], tb[-3], sum); add3f(tb[-1], tb[-3], sum);
add3f(sum, tb[-5], sum); add3f(sum, tb[-5], sum);
if (sumarray){
sumarray[sumarraypl++] = sum[0];
sumarray[sumarraypl++] = sum[1];
sumarray[sumarraypl++] = sum[2];
}
*(zv++) = matrix[2] * sum[0] + matrix[6] * sum[1] + matrix[10 ] * sum[2]; *(zv++) = matrix[2] * sum[0] + matrix[6] * sum[1] + matrix[10 ] * sum[2];
n_tri++; n_tri++;
} }
t += 3; t += 3;
} }
} else { } else {
while(c--) { while(c--) {
if((I->proximity if (visibility_test(I->proximity, vi, t)) {
&& ((*(vi + (*t))) || (*(vi + (*(t + 1)))) || (*(vi + (*(t
+ 2))))))
|| ((*(vi + (*t))) && (*(vi + (*(t + 1)))) && (*(vi + (*(t +
2))))))
if((*(vi + (*t))) || (*(vi + (*(t + 1)))) || (*(vi + (*(t + 2
))))) {
if(va) if(va)
*(tb++) = va + (*t); *(tb++) = va + (*t);
else else
*(tb++) = &alpha; *(tb++) = &alpha;
*(tb++) = vc + (*t) * 3; *(tb++) = vc + (*t) * 3;
*(tb++) = vn + (*t) * 3; *(tb++) = vn + (*t) * 3;
*(tb++) = v + (*t) * 3; *(tb++) = v + (*t) * 3;
if(va) if(va)
skipping to change at line 1087 skipping to change at line 635
if(va) if(va)
*(tb++) = va + (*(t + 2)); *(tb++) = va + (*(t + 2));
else else
*(tb++) = &alpha; *(tb++) = &alpha;
*(tb++) = vc + (*(t + 2)) * 3; *(tb++) = vc + (*(t + 2)) * 3;
*(tb++) = vn + (*(t + 2)) * 3; *(tb++) = vn + (*(t + 2)) * 3;
*(tb++) = v + (*(t + 2)) * 3; *(tb++) = v + (*(t + 2)) * 3;
add3f(tb[-1], tb[-5], sum); add3f(tb[-1], tb[-5], sum);
add3f(sum, tb[-9], sum); add3f(sum, tb[-9], sum);
if (sumarray){
sumarray[sumarraypl++] = sum[0];
sumarray[sumarraypl++] = sum[1];
sumarray[sumarraypl++] = sum[2];
}
*(zv++) = *(zv++) =
matrix[2] * sum[0] + matrix[6] * sum[1] + matrix[10] * su m[2]; matrix[2] * sum[0] + matrix[6] * sum[1] + matrix[10] * su m[2];
n_tri++; n_tri++;
} }
t += 3; t += 3;
} }
} }
} }
switch (t_mode) { switch (t_mode) {
case 1: case 1:
skipping to change at line 1115 skipping to change at line 658
default: default:
ok &= UtilSemiSortFloatIndex(n_tri, z_value, ix, false); ok &= UtilSemiSortFloatIndex(n_tri, z_value, ix, false);
/* UtilSortIndex(n_tri,z_value,ix,(UtilOrderFn*)ZRevOrderFn); */ /* UtilSortIndex(n_tri,z_value,ix,(UtilOrderFn*)ZRevOrderFn); */
break; break;
} }
c = n_tri; c = n_tri;
if(I->oneColorFlag) { if(I->oneColorFlag) {
float col[3]; float col[3];
ColorGetEncoded(G, I->oneColor, col); ColorGetEncoded(G, I->oneColor, col);
if (ok){ if (ok){
if (generate_shader_cgo){
CGOAlpha(I->shaderCGO, alpha); CGOAlpha(I->shaderCGO, alpha);
if (ok) if (ok)
ok &= CGOColor(I->shaderCGO, col[0], col[1], col[2]); ok &= CGOColor(I->shaderCGO, col[0], col[1], col[2]);
if (ok) if (ok)
ok &= CGOBegin(I->shaderCGO, GL_TRIANGLES); ok &= CGOBegin(I->shaderCGO, GL_TRIANGLES);
for(c = 0; ok && c < n_tri; c++) { for(c = 0; ok && c < n_tri; c++) {
int idx; int idx;
tb = t_buf + 6 * c; tb = t_buf + 6 * c;
// tb = t_buf + 6 * ix[c]; // tb = t_buf + 6 * ix[c];
if (ok) if (ok)
ok &= CGONormalv(I->shaderCGO, *(tb++)); ok &= CGONormalv(I->shaderCGO, *(tb++));
idx = ((*tb - v)/3); idx = ((*tb - v)/3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIsMasked ((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIsMasked ((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + idx)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + idx));
} }
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, *(tb++)); ok &= CGOVertexv(I->shaderCGO, *(tb++));
if (ok) if (ok)
ok &= CGONormalv(I->shaderCGO, *(tb++)); ok &= CGONormalv(I->shaderCGO, *(tb++));
idx = ((*tb - v)/3); idx = ((*tb - v)/3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIsMask ed((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIsMask ed((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + idx)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + idx));
} }
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, *(tb++)); ok &= CGOVertexv(I->shaderCGO, *(tb++));
if (ok) if (ok)
ok &= CGONormalv(I->shaderCGO, *(tb++)); ok &= CGONormalv(I->shaderCGO, *(tb++));
idx = ((*tb - v)/3); idx = ((*tb - v)/3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIsMask ed((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIsMask ed((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + idx)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + idx));
} }
if (ok) if (ok)
ok &= CGOVertexv(I->shaderCGO, *(tb++)); ok &= CGOVertexv(I->shaderCGO, *(tb++));
} }
if (ok) if (ok)
ok &= CGOEnd(I->shaderCGO); ok &= CGOEnd(I->shaderCGO);
} else {
glColor4f(col[0], col[1], col[2], alpha);
glBegin(GL_TRIANGLES);
for(c = 0; c < n_tri; c++) {
tb = t_buf + 6 * ix[c];
glNormal3fv(*(tb++));
glVertex3fv(*(tb++));
glNormal3fv(*(tb++));
glVertex3fv(*(tb++));
glNormal3fv(*(tb++));
glVertex3fv(*(tb++));
}
glEnd();
} /* end if else use_shader */
} }
} else { /* else I->oneColorFlag */ } else { /* else I->oneColorFlag */
if (generate_shader_cgo){
if (ok) if (ok)
ok &= CGOBegin(I->shaderCGO, GL_TRIANGLES); ok &= CGOBegin(I->shaderCGO, GL_TRIANGLES);
for(c = 0; ok && c < n_tri; c++) { for(c = 0; ok && c < n_tri; c++) {
float *vv, *v_alpha; float *vv, *v_alpha;
int idx; int idx;
tb = t_buf + 12 * c; /* need to update index every frame */ tb = t_buf + 12 * c; /* need to update index every frame */
// tb = t_buf + 12 * ix[c]; // tb = t_buf + 12 * ix[c];
v_alpha = *(tb++); v_alpha = *(tb++);
vv = *(tb++); vv = *(tb++);
ok &= CGOAlpha(I->shaderCGO, *v_alpha); ok &= CGOAlpha(I->shaderCGO, *v_alpha);
if (ok) ok &= CGOColor(I->shaderCGO, vv[0], vv[1], vv[2]); if (ok) ok &= CGOColor(I->shaderCGO, vv[0], vv[1], vv[2]);
if (ok) ok &= CGONormalv(I->shaderCGO, *(tb++)); if (ok) ok &= CGONormalv(I->shaderCGO, *(tb++));
idx = ((*tb - v)/3); idx = ((*tb - v)/3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIsMask ed((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIsMask ed((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + idx)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + idx));
} }
if (ok) ok &= CGOVertexv(I->shaderCGO, *(tb++)); if (ok) ok &= CGOVertexv(I->shaderCGO, *(tb++));
v_alpha = *(tb++); v_alpha = *(tb++);
vv = *(tb++); vv = *(tb++);
if (ok) ok &= CGOAlpha(I->shaderCGO, *v_alpha); if (ok) ok &= CGOAlpha(I->shaderCGO, *v_alpha);
if (ok) ok &= CGOColor(I->shaderCGO, vv[0], vv[1], vv[2]); if (ok) ok &= CGOColor(I->shaderCGO, vv[0], vv[1], vv[2]);
if (ok) ok &= CGONormalv(I->shaderCGO, *(tb++)); if (ok) ok &= CGONormalv(I->shaderCGO, *(tb++));
idx = ((*tb - v)/3); idx = ((*tb - v)/3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIsMask ed((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIsMask ed((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + idx)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + idx));
} }
if (ok) ok &= CGOVertexv(I->shaderCGO, *(tb++)); if (ok) ok &= CGOVertexv(I->shaderCGO, *(tb++));
v_alpha = *(tb++); v_alpha = *(tb++);
vv = *(tb++); vv = *(tb++);
if (ok) ok &= CGOAlpha(I->shaderCGO, *v_alpha); if (ok) ok &= CGOAlpha(I->shaderCGO, *v_alpha);
if (ok) ok &= CGOColor(I->shaderCGO, vv[0], vv[1], vv[2]); if (ok) ok &= CGOColor(I->shaderCGO, vv[0], vv[1], vv[2]);
if (ok) ok &= CGONormalv(I->shaderCGO, *(tb++)); if (ok) ok &= CGONormalv(I->shaderCGO, *(tb++));
idx = ((*tb - v)/3); idx = ((*tb - v)/3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIsMask ed((ObjectMolecule*)I->R.obj, I->AT[idx])); ok &= CGOPickColor(I->shaderCGO, I->AT[idx], AtomInfoIsMask ed((ObjectMolecule*)I->R.obj, I->AT[idx]));
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + idx)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + idx));
} }
if (ok) ok &= CGOVertexv(I->shaderCGO, *(tb++)); if (ok) ok &= CGOVertexv(I->shaderCGO, *(tb++));
} }
if (ok) ok &= CGOEnd(I->shaderCGO); if (ok) ok &= CGOEnd(I->shaderCGO);
} else {
#ifdef PURE_OPENGL_ES_2
/* TODO */
#else
glBegin(GL_TRIANGLES);
for(c = 0; c < n_tri; c++) {
float *vv, *v_alpha;
tb = t_buf + 12 * ix[c];
v_alpha = *(tb++);
vv = *(tb++);
glColor4f(vv[0], vv[1], vv[2], *v_alpha);
glNormal3fv(*(tb++));
glVertex3fv(*(tb++));
v_alpha = *(tb++);
vv = *(tb++);
glColor4f(vv[0], vv[1], vv[2], *v_alpha);
glNormal3fv(*(tb++));
glVertex3fv(*(tb++));
v_alpha = *(tb++);
vv = *(tb++);
glColor4f(vv[0], vv[1], vv[2], *v_alpha);
glNormal3fv(*(tb++));
glVertex3fv(*(tb++));
} }
glEnd();
#endif
}
} /* end if else use_shader */
if (ok && use_shader && generate_shader_cgo){
I->ix = ix;
I->z_value = z_value;
I->n_tri = n_tri;
I->sum = sumarray;
} else {
FreeP(ix); FreeP(ix);
FreeP(z_value); FreeP(z_value);
FreeP(t_buf); FreeP(t_buf);
}
} else if (ok) { } else if (ok) {
if(info->alpha_cgo) { /* global transparency sort */ if(info->alpha_cgo) { /* global transparency sort */
if(I->allVisibleFlag) { if(I->allVisibleFlag) {
if(I->oneColorFlag) { if(I->oneColorFlag) {
float col[3]; float col[3];
ColorGetEncoded(G, I->oneColor, col); ColorGetEncoded(G, I->oneColor, col);
glColor4f(col[0], col[1], col[2], alpha);
c = *(s++); c = *(s++);
while(c) { while(c) {
int parity = 0; int parity = 0;
s += 2; s += 2;
while(ok && c--) { while(ok && c--) {
ok &= CGOAlphaTriangle(info->alpha_cgo, ok &= CGOAlphaTriangle(info->alpha_cgo,
v + s[-2] * 3, v + s[-1] * 3, v + (* s) * 3, v + s[-2] * 3, v + s[-1] * 3, v + (* s) * 3,
vn + s[-2] * 3, vn + s[-1] * 3, vn + (*s) * 3, vn + s[-2] * 3, vn + s[-1] * 3, vn + (*s) * 3,
col, col, col, alpha, alpha, alpha, parity); col, col, col, alpha, alpha, alpha, parity);
s++; s++;
skipping to change at line 1334 skipping to change at line 822
c = *(s++); c = *(s++);
} }
} }
} else if (ok){ /* subset s */ } else if (ok){ /* subset s */
c = I->NT; c = I->NT;
if(c) { if(c) {
if(I->oneColorFlag) { if(I->oneColorFlag) {
float color[3]; float color[3];
ColorGetEncoded(G, I->oneColor, color); ColorGetEncoded(G, I->oneColor, color);
while(ok && c--) { while(ok && c--) {
if((I->proximity && ((*(vi + (*t))) || (*(vi + (*(t + 1))) if (visibility_test(I->proximity, vi, t)) {
)
|| (*(vi + (*(t + 2)))))) || ((*(vi +
(*t)))
&&
(*
(vi +
(*(t
+ 1))))
&&
(*
(vi +
(*(t
+ 2))))))
{
ok &= CGOAlphaTriangle(info->alpha_cgo, ok &= CGOAlphaTriangle(info->alpha_cgo,
v + t[0] * 3, v + t[1] * 3, v + t[ 2] * 3, v + t[0] * 3, v + t[1] * 3, v + t[ 2] * 3,
vn + t[0] * 3, vn + t[1] * 3, vn + t[2] * 3, vn + t[0] * 3, vn + t[1] * 3, vn + t[2] * 3,
color, color, color, alpha, alpha, alpha, 0); color, color, color, alpha, alpha, alpha, 0);
} }
t += 3; t += 3;
} }
} else { } else {
while(ok && c--) { while(ok && c--) {
if((I->proximity && ((*(vi + (*t))) || (*(vi + (*(t + 1))) if (visibility_test(I->proximity, vi, t)) {
)
|| (*(vi + (*(t + 2)))))) || ((*(vi +
(*t)))
&&
(*
(vi +
(*(t
+ 1))))
&&
(*
(vi +
(*(t
+ 2))))))
{
if(va) { if(va) {
ok &= CGOAlphaTriangle(info->alpha_cgo, ok &= CGOAlphaTriangle(info->alpha_cgo,
v + t[0] * 3, v + t[1] * 3, v + t[2] * 3, v + t[0] * 3, v + t[1] * 3, v + t[2] * 3,
vn + t[0] * 3, vn + t[1] * 3, vn + t[2] * 3, vn + t[0] * 3, vn + t[1] * 3, vn + t[2] * 3,
vc + t[0] * 3, vc + t[1] * 3, vc + t[2] * 3, vc + t[0] * 3, vc + t[1] * 3, vc + t[2] * 3,
va[t[0]], va[t[1]], va[t[2]], 0) ; va[t[0]], va[t[1]], va[t[2]], 0) ;
} else { } else {
ok &= CGOAlphaTriangle(info->alpha_cgo, ok &= CGOAlphaTriangle(info->alpha_cgo,
v + t[0] * 3, v + t[1] * 3, v + t[2] * 3, v + t[0] * 3, v + t[1] * 3, v + t[2] * 3,
skipping to change at line 1399 skipping to change at line 867
/* fast and ugly */ /* fast and ugly */
/* glCullFace(GL_BACK); /* glCullFace(GL_BACK);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glDepthMask(GL_FALSE); */ glDepthMask(GL_FALSE); */
if(I->allVisibleFlag) { if(I->allVisibleFlag) {
if(I->oneColorFlag) { if(I->oneColorFlag) {
float col[3]; float col[3];
ColorGetEncoded(G, I->oneColor, col); ColorGetEncoded(G, I->oneColor, col);
if (generate_shader_cgo){
if (ok) ok &= CGOAlpha(I->shaderCGO, alpha); if (ok) ok &= CGOAlpha(I->shaderCGO, alpha);
if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], col[2] ); if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], col[2] );
c = *(s++); c = *(s++);
while(ok && c) { while(ok && c) {
if (ok) ok &= CGOBegin(I->shaderCGO, GL_TRIANGLE_STRIP); if (ok) ok &= CGOBegin(I->shaderCGO, GL_TRIANGLE_STRIP);
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s])); ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3);
s++; s++;
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s])); ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3);
s++; s++;
while(ok && c--) { while(ok && c--) {
ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3); ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*s])); ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*s]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3);
s++; s++;
} }
if (ok) ok &= CGOEnd(I->shaderCGO); if (ok) ok &= CGOEnd(I->shaderCGO);
c = *(s++); c = *(s++);
} }
} else {
glColor4f(col[0], col[1], col[2], alpha);
c = *(s++);
while(c) {
#ifdef PURE_OPENGL_ES_2
/* TODO */
#else
glBegin(GL_TRIANGLE_STRIP);
glNormal3fv(vn + (*s) * 3);
glVertex3fv(v + (*s) * 3);
s++;
glNormal3fv(vn + (*s) * 3);
glVertex3fv(v + (*s) * 3);
s++;
while(c--) {
glNormal3fv(vn + (*s) * 3);
glVertex3fv(v + (*s) * 3);
s++;
}
glEnd();
#endif
c = *(s++);
}
} /* end if else use_shader */
} else { /* I->oneColorFlag */ } else { /* I->oneColorFlag */
if (generate_shader_cgo){
c = *(s++); c = *(s++);
while(ok && c) { while(ok && c) {
float *col; float *col;
if (ok) ok &= CGOBegin(I->shaderCGO, GL_TRIANGLE_STRIP); if (ok) ok &= CGOBegin(I->shaderCGO, GL_TRIANGLE_STRIP);
col = vc + (*s) * 3; col = vc + (*s) * 3;
if(va) { if(va) {
if (ok) ok &= CGOAlpha(I->shaderCGO, va[(*s)]); if (ok) ok &= CGOAlpha(I->shaderCGO, va[(*s)]);
if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], co l[2]); if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], co l[2]);
} else { } else {
if (ok) ok &= CGOAlpha(I->shaderCGO, alpha); if (ok) ok &= CGOAlpha(I->shaderCGO, alpha);
if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], co l[2]); if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], co l[2]);
} }
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s])); ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3);
s++; s++;
col = vc + (*s) * 3; col = vc + (*s) * 3;
if(va) { if(va) {
if (ok) ok &= CGOAlpha(I->shaderCGO, va[(*s)]); if (ok) ok &= CGOAlpha(I->shaderCGO, va[(*s)]);
if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], co l[2]); if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], co l[2]);
} else { } else {
if (ok) ok &= CGOAlpha(I->shaderCGO, alpha); if (ok) ok &= CGOAlpha(I->shaderCGO, alpha);
if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], co l[2]); if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], co l[2]);
} }
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s])); ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3);
s++; s++;
while(ok && c--) { while(ok && c--) {
col = vc + (*s) * 3; col = vc + (*s) * 3;
if(va) { if(va) {
ok &= CGOAlpha(I->shaderCGO, va[(*s)]); ok &= CGOAlpha(I->shaderCGO, va[(*s)]);
if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], col[2]); if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], col[2]);
} else { } else {
ok &= CGOAlpha(I->shaderCGO, alpha); ok &= CGOAlpha(I->shaderCGO, alpha);
if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], col[2]); if (ok) ok &= CGOColor(I->shaderCGO, col[0], col[1], col[2]);
} }
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*s])); ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*s]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3);
s++; s++;
} }
if (ok) ok &= CGOEnd(I->shaderCGO); if (ok) ok &= CGOEnd(I->shaderCGO);
c = *(s++); c = *(s++);
} }
} else {
c = *(s++);
while(c) {
#ifndef PURE_OPENGL_ES_2
float *col;
glBegin(GL_TRIANGLE_STRIP);
col = vc + (*s) * 3;
if(va) {
glColor4f(col[0], col[1], col[2], va[(*s)]);
} else {
glColor4f(col[0], col[1], col[2], alpha);
}
glNormal3fv(vn + (*s) * 3);
glVertex3fv(v + (*s) * 3);
s++;
col = vc + (*s) * 3;
if(va) {
glColor4f(col[0], col[1], col[2], va[(*s)]);
} else {
glColor4f(col[0], col[1], col[2], alpha);
}
glNormal3fv(vn + (*s) * 3);
glVertex3fv(v + (*s) * 3);
s++;
while(c--) {
col = vc + (*s) * 3;
if(va) {
glColor4f(col[0], col[1], col[2], va[(*s)]);
} else {
glColor4f(col[0], col[1], col[2], alpha);
}
glNormal3fv(vn + (*s) * 3);
glVertex3fv(v + (*s) * 3);
s++;
}
glEnd();
#endif
c = *(s++);
}
} }
} /* end if else use_shader */
} else { /* subset s */ } else { /* subset s */
if (generate_shader_cgo){
c = I->NT; c = I->NT;
if(ok && c) { if(ok && c) {
if (ok) ok &= CGOBegin(I->shaderCGO, GL_TRIANGLES); if (ok) ok &= CGOBegin(I->shaderCGO, GL_TRIANGLES);
if(I->oneColorFlag) { if(I->oneColorFlag) {
float color[3]; float color[3];
float *col;
ColorGetEncoded(G, I->oneColor, color); ColorGetEncoded(G, I->oneColor, color);
if (ok) ok &= CGOAlpha(I->shaderCGO, alpha); if (ok) ok &= CGOAlpha(I->shaderCGO, alpha);
if (ok) ok &= CGOColor(I->shaderCGO, color[0], color[1], color[2]); if (ok) ok &= CGOColor(I->shaderCGO, color[0], color[1], color[2]);
while(ok && c--) { while(ok && c--) {
if((I->proximity && ((*(vi + (*t))) || (*(vi + (*(t + 1 if (visibility_test(I->proximity, vi, t))
))))
|| (*(vi + (*(t + 2)))))) || ((*(v
i + (*t)))
&&
(*
(vi
+
(*
(t + 1))))
&&
(*
(vi
+
(*
(t + 2))))))
{ {
col = vc + (*t) * 3;
CGONormalv(I->shaderCGO, vn + (*t) * 3); CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + * t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + * t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomI nfoIsMasked((ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomI nfoIsMasked((ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3 ); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3 );
t++; t++;
col = vc + (*t) * 3;
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + * t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + * t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomI nfoIsMasked((ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomI nfoIsMasked((ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3 ); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3 );
t++; t++;
col = vc + (*t) * 3;
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + * t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + * t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomI nfoIsMasked((ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomI nfoIsMasked((ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3 ); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3 );
t++; t++;
} else } else
t += 3; t += 3;
} }
} else { } else {
float *col; float *col;
while(ok && c--) { while(ok && c--) {
if((I->proximity && ((*(vi + (*t))) || (*(vi + (*(t + 1 if (visibility_test(I->proximity, vi, t))
))))
|| (*(vi + (*(t + 2)))))) || ((*(v
i + (*t)))
&&
(*
(vi
+
(*
(t + 1))))
&&
(*
(vi
+
(*
(t + 2))))))
{ {
col = vc + (*t) * 3; col = vc + (*t) * 3;
if(va) { if(va) {
ok &= CGOAlpha(I->shaderCGO, va[(*t)]); ok &= CGOAlpha(I->shaderCGO, va[(*t)]);
} else { } else {
ok &= CGOAlpha(I->shaderCGO, alpha); ok &= CGOAlpha(I->shaderCGO, alpha);
} }
if (ok) ok &= CGOColorv(I->shaderCGO, col); if (ok) ok &= CGOColorv(I->shaderCGO, col);
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + * t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + * t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomI nfoIsMasked((ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomI nfoIsMasked((ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3 ); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3 );
t++; t++;
col = vc + (*t) * 3; col = vc + (*t) * 3;
if(va) { if(va) {
if (ok) ok &= CGOAlpha(I->shaderCGO, va[(*t)]); if (ok) ok &= CGOAlpha(I->shaderCGO, va[(*t)]);
} else { } else {
if (ok) ok &= CGOAlpha(I->shaderCGO, alpha); if (ok) ok &= CGOAlpha(I->shaderCGO, alpha);
} }
if (ok) ok &= CGOColorv(I->shaderCGO, col); if (ok) ok &= CGOColorv(I->shaderCGO, col);
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + * t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + * t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomI nfoIsMasked((ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomI nfoIsMasked((ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3 ); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3 );
t++; t++;
col = vc + (*t) * 3; col = vc + (*t) * 3;
if(va) { if(va) {
if (ok) ok &= CGOAlpha(I->shaderCGO, va[(*t)]); if (ok) ok &= CGOAlpha(I->shaderCGO, va[(*t)]);
} else { } else {
if (ok) ok &= CGOAlpha(I->shaderCGO, alpha); if (ok) ok &= CGOAlpha(I->shaderCGO, alpha);
} }
if (ok) ok &= CGOColorv(I->shaderCGO, col); if (ok) ok &= CGOColorv(I->shaderCGO, col);
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + * t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + * t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomI nfoIsMasked((ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomI nfoIsMasked((ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3 ); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3 );
t++; t++;
} else } else
t += 3; t += 3;
} }
} }
if (ok) ok &= CGOEnd(I->shaderCGO); if (ok) ok &= CGOEnd(I->shaderCGO);
} }
} else { /* end generate_shader_cgo */
c = I->NT;
if(c) {
#ifdef PURE_OPENGL_ES_2
/* TODO */
#else
glBegin(GL_TRIANGLES);
if(I->oneColorFlag) {
float color[3];
float *col;
ColorGetEncoded(G, I->oneColor, color);
glColor4f(color[0], color[1], color[2], alpha);
while(c--) {
if((I->proximity && ((*(vi + (*t))) || (*(vi + (*(t + 1)))
)
|| (*(vi + (*(t + 2)))))) || ((*(vi +
(*t)))
&&
(*
(vi +
(*(t
+ 1))))
&&
(*
(vi +
(*(t
+ 2))))))
{
col = vc + (*t) * 3;
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
col = vc + (*t) * 3;
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
col = vc + (*t) * 3;
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
} else
t += 3;
}
} else {
float *col;
while(c--) {
if((I->proximity && ((*(vi + (*t))) || (*(vi + (*(t + 1)))
)
|| (*(vi + (*(t + 2)))))) || ((*(vi +
(*t)))
&&
(*
(vi +
(*(t
+ 1))))
&&
(*
(vi +
(*(t
+ 2))))))
{
col = vc + (*t) * 3;
if(va) {
glColor4f(col[0], col[1], col[2], va[(*t)]);
} else {
glColor4f(col[0], col[1], col[2], alpha);
}
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
col = vc + (*t) * 3;
if(va) {
glColor4f(col[0], col[1], col[2], va[(*t)]);
} else {
glColor4f(col[0], col[1], col[2], alpha);
}
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
col = vc + (*t) * 3;
if(va) {
glColor4f(col[0], col[1], col[2], va[(*t)]);
} else {
glColor4f(col[0], col[1], col[2], alpha);
}
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
} else
t += 3;
}
}
glEnd();
#endif
} }
}
} /* end else use_shader */
} }
/* glDisable(GL_CULL_FACE); /* glDisable(GL_CULL_FACE);
glDepthMask(GL_TRUE); */ glDepthMask(GL_TRUE); */
} }
} else if (ok) { /* opaque */ } else if (ok) { /* opaque */
if(I->allVisibleFlag) { if(I->allVisibleFlag) {
if(I->oneColorFlag) { if(I->oneColorFlag) {
if (ok) { if (ok) {
if (generate_shader_cgo){
CGOColorv(I->shaderCGO, ColorGet(G, I->oneColor)); CGOColorv(I->shaderCGO, ColorGet(G, I->oneColor));
c = *(s++); c = *(s++);
while(ok && c) { while(ok && c) {
if (ok) ok &= CGOBegin(I->shaderCGO, GL_TRIANGLE_STRIP); if (ok) ok &= CGOBegin(I->shaderCGO, GL_TRIANGLE_STRIP);
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s])); ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s]));
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s));
} }
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3);
s++; s++;
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s])); ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s]));
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s));
} }
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3);
s++; s++;
while(ok && c--) { while(ok && c--) {
ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3); ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*s])); ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*s]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3);
s++; s++;
} }
if (ok) ok &= CGOEnd(I->shaderCGO); if (ok) ok &= CGOEnd(I->shaderCGO);
c = *(s++); c = *(s++);
} }
} else {
glColor3fv(ColorGet(G, I->oneColor));
c = *(s++);
while(c) {
#ifdef PURE_OPENGL_ES_2
/* TODO */
#else
glBegin(GL_TRIANGLE_STRIP);
glNormal3fv(vn + (*s) * 3);
glVertex3fv(v + (*s) * 3);
s++;
glNormal3fv(vn + (*s) * 3);
glVertex3fv(v + (*s) * 3);
s++;
while(c--) {
glNormal3fv(vn + (*s) * 3);
glVertex3fv(v + (*s) * 3);
s++;
}
glEnd();
#endif
c = *(s++);
}
} }
} /* end if else generate_shader_cgo */
} else { /* not one color */ } else { /* not one color */
if (generate_shader_cgo){
{ {
c = *(s++); c = *(s++);
while(ok && c) { while(ok && c) {
ok &= CGOBegin(I->shaderCGO, GL_TRIANGLE_STRIP); ok &= CGOBegin(I->shaderCGO, GL_TRIANGLE_STRIP);
if (ok) ok &= CGOColorv(I->shaderCGO, vc + (*s) * 3); if (ok) ok &= CGOColorv(I->shaderCGO, vc + (*s) * 3);
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s])); ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3);
s++; s++;
if (ok) ok &= CGOColorv(I->shaderCGO, vc + (*s) * 3); if (ok) ok &= CGOColorv(I->shaderCGO, vc + (*s) * 3);
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s])); ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoIsM asked((ObjectMolecule*)I->R.obj, I->AT[*s]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3);
s++; s++;
while(ok && c--) { while(ok && c--) {
ok &= CGOColorv(I->shaderCGO, vc + (*s) * 3); ok &= CGOColorv(I->shaderCGO, vc + (*s) * 3);
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*s) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *s));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*s])); ok &= CGOPickColor(I->shaderCGO, I->AT[*s], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*s]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*s) * 3);
s++; s++;
} }
if (ok) ok &= CGOEnd(I->shaderCGO ); if (ok) ok &= CGOEnd(I->shaderCGO );
c = *(s++); c = *(s++);
} }
} }
} else {
{
c = *(s++);
while(c) {
#ifdef PURE_OPENGL_ES_2
/* TODO */
#else
glBegin(GL_TRIANGLE_STRIP);
glColor3fv(vc + (*s) * 3);
glNormal3fv(vn + (*s) * 3);
glVertex3fv(v + (*s) * 3);
s++;
glColor3fv(vc + (*s) * 3);
glNormal3fv(vn + (*s) * 3);
glVertex3fv(v + (*s) * 3);
s++;
while(c--) {
glColor3fv(vc + (*s) * 3);
glNormal3fv(vn + (*s) * 3);
glVertex3fv(v + (*s) * 3);
s++;
}
glEnd();
#endif
c = *(s++);
}
}
} /* end if else generate_shader_cgo */
} /* one color */ } /* one color */
} else if (ok) { /* subsets */ } else if (ok) { /* subsets */
if (generate_shader_cgo){
c = I->NT; c = I->NT;
if(ok && c) { if(ok && c) {
ok &= CGOBegin(I->shaderCGO, GL_TRIANGLES); ok &= CGOBegin(I->shaderCGO, GL_TRIANGLES);
if(I->oneColorFlag) { if(I->oneColorFlag) {
if (ok) ok &= CGOColorv(I->shaderCGO, ColorGet(G, I->oneCol or)); if (ok) ok &= CGOColorv(I->shaderCGO, ColorGet(G, I->oneCol or));
while(ok && c--) { while(ok && c--) {
if((I->proximity && ((*(vi + (*t))) || (*(vi + (*(t + 1)) if (visibility_test(I->proximity, vi, t)) {
))
|| (*(vi + (*(t + 2)))))) || ((*(vi
+ (*t)))
&&
(*
(vi +
(*(t + 1))))
&&
(*
(vi +
(*(t
+ 2)))))) {
ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3);
t++; t++;
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3);
t++; t++;
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3);
t++; t++;
} else } else
t += 3; t += 3;
} }
} else { } else {
while(ok && c--) { while(ok && c--) {
if((I->proximity && ((*(vi + (*t))) || (*(vi + (*(t + 1)) if (visibility_test(I->proximity, vi, t)) {
))
|| (*(vi + (*(t + 2)))))) || ((*(vi
+ (*t)))
&&
(*
(vi +
(*(t + 1))))
&&
(*
(vi +
(*(t
+ 2)))))) {
ok &= CGOColorv(I->shaderCGO, vc + (*t) * 3); ok &= CGOColorv(I->shaderCGO, vc + (*t) * 3);
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3);
t++; t++;
if (ok) ok &= CGOColorv(I->shaderCGO, vc + (*t) * 3); if (ok) ok &= CGOColorv(I->shaderCGO, vc + (*t) * 3);
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3);
t++; t++;
if (ok) ok &= CGOColorv(I->shaderCGO, vc + (*t) * 3); if (ok) ok &= CGOColorv(I->shaderCGO, vc + (*t) * 3);
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoI sMasked((ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3);
t++; t++;
} else } else
t += 3; t += 3;
} }
} }
if (ok) ok &= CGOEnd(I->shaderCGO); if (ok) ok &= CGOEnd(I->shaderCGO);
} }
} else { /* if else generate_shader_cgo */
c = I->NT;
if(c) {
#ifdef PURE_OPENGL_ES_2
/* TODO */
#else
glBegin(GL_TRIANGLES);
if(I->oneColorFlag) {
glColor3fv(ColorGet(G, I->oneColor));
while(c--) {
if((I->proximity && ((*(vi + (*t))) || (*(vi + (*(t + 1))))
|| (*(vi + (*(t + 2)))))) || ((*(vi + (
*t)))
&&
(*
(vi + (*
(t + 1))))
&&
(*
(vi +
(*(t +
2)))))) {
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
} else
t += 3;
}
} else {
while(c--) {
if((I->proximity && ((*(vi + (*t))) || (*(vi + (*(t + 1))))
|| (*(vi + (*(t + 2)))))) || ((*(vi + (
*t)))
&&
(*
(vi + (*
(t + 1))))
&&
(*
(vi +
(*(t +
2)))))) {
glColor3fv(vc + (*t) * 3);
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glColor3fv(vc + (*t) * 3);
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glColor3fv(vc + (*t) * 3);
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
} else
t += 3;
}
}
glEnd();
#endif
}
} /* end if else use_shader */
} }
/* if (use_shader) { /* if (use_shader) {
CShaderPrg_Disable(shaderPrg); CShaderPrg_Disable(shaderPrg);
}*/ }*/
} }
} }
if(ok && SettingGetGlobal_i(G, cSetting_surface_debug)) { if(ok && SettingGetGlobal_i(G, cSetting_surface_debug)) {
t = I->T; t = I->T;
c = I->NT; c = I->NT;
if (generate_shader_cgo){
if(c) { if(c) {
ok &= CGOBegin(I->shaderCGO, GL_TRIANGLES); ok &= CGOBegin(I->shaderCGO, GL_TRIANGLES);
while(ok && c--) { while(ok && c--) {
if(I->allVisibleFlag if(I->allVisibleFlag
|| || visibility_test(I->proximity, vi, t)) {
((I->proximity
&& ((*(vi + (*t))) || (*(vi + (*(t + 1)))) || (*(vi + (*(t +
2))))))
|| ((*(vi + (*t))) && (*(vi + (*(t + 1)))) && (*(vi + (*(t +
2))))))) {
ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoIsMasked( (ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoIsMasked( (ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3);
t++; t++;
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoIsMasked( (ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoIsMasked( (ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3);
t++; t++;
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok && I->VAO){ if (ok && I->VAO){
ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t)); ok &= CGOAccessibility(I->shaderCGO, *(I->VAO + *t));
} }
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoIsMasked( (ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoIsMasked( (ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3);
t++; t++;
} else { } else {
t += 3; t += 3;
} }
} }
if (ok) ok &= CGOEnd(I->shaderCGO); if (ok) ok &= CGOEnd(I->shaderCGO);
} }
} else {
if(c) {
#ifdef PURE_OPENGL_ES_2
/* TODO */
#else
glBegin(GL_TRIANGLES);
while(c--) {
if(I->allVisibleFlag
||
((I->proximity
&& ((*(vi + (*t))) || (*(vi + (*(t + 1)))) || (*(vi + (*(t + 2)
)))))
|| ((*(vi + (*t))) && (*(vi + (*(t + 1)))) && (*(vi + (*(t + 2))
))))) {
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
glNormal3fv(vn + (*t) * 3);
glVertex3fv(v + (*t) * 3);
t++;
} else {
t += 3;
}
}
glEnd();
#endif
}
} /* end else use_shader */
t = I->T; t = I->T;
c = I->NT; c = I->NT;
if (generate_shader_cgo){
if(ok && c) { if(ok && c) {
ok &= CGOColor(I->shaderCGO, 0.0, 1.0, 0.0); ok &= CGOColor(I->shaderCGO, 0.0, 1.0, 0.0);
if (ok) ok &= CGODotwidth(I->shaderCGO, 1.0F); if (ok) ok &= CGODotwidth(I->shaderCGO, 1.0F);
while(ok && c--) { while(ok && c--) {
ok &= CGOBegin(I->shaderCGO, GL_LINE_STRIP); ok &= CGOBegin(I->shaderCGO, GL_LINE_STRIP);
if(I->allVisibleFlag if(I->allVisibleFlag
|| || visibility_test(I->proximity, vi, t)) {
((I->proximity
&& ((*(vi + (*t))) || (*(vi + (*(t + 1)))) || (*(vi + (*(t +
2))))))
|| ((*(vi + (*t))) && (*(vi + (*(t + 1)))) && (*(vi + (*(t +
2))))))) {
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoIsMasked( (ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoIsMasked( (ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3);
t++; t++;
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoIsMasked( (ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoIsMasked( (ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3);
t++; t++;
if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3); if (ok) ok &= CGONormalv(I->shaderCGO, vn + (*t) * 3);
if (ok) if (ok && pick_surface)
ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoIsMasked( (ObjectMolecule*)I->R.obj, I->AT[*t])); ok &= CGOPickColor(I->shaderCGO, I->AT[*t], AtomInfoIsMasked( (ObjectMolecule*)I->R.obj, I->AT[*t]));
if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3); if (ok) ok &= CGOVertexv(I->shaderCGO, v + (*t) * 3);
t++; t++;
} else { } else {
t += 3; t += 3;
} }
if (ok) ok &= CGOEnd(I->shaderCGO); if (ok) ok &= CGOEnd(I->shaderCGO);
} }
} }
} else {/* end generate_shader_cgo */
if(c) { c = I->N;
glColor3f(0.0, 1.0, 0.0); if(ok && c) {
glLineWidth(1.0F); ok &= CGOColor(I->shaderCGO, 1.0, 0.0, 0.0);
while(c--) { if (ok) ok &= CGOResetNormal(I->shaderCGO, true);
#ifdef PURE_OPENGL_ES_2 if (ok) ok &= CGOBegin(I->shaderCGO, GL_LINES);
/* TODO */ while(ok && c--) {
#else ok &= CGOVertexv(I->shaderCGO, v);
/* glBegin/glEnd should be inside the if statement, right? - BB */ if (ok) ok &= CGOVertex(I->shaderCGO, v[0] + vn[0] / 2, v[1] + vn[1] /
glBegin(GL_LINE_STRIP); 2, v[2] + vn[2] / 2);
v += 3;
if(I->allVisibleFlag vn += 3;
|| }
((I->proximity if (ok) ok &= CGOEnd(I->shaderCGO);
&& ((*(vi + (*t))) || (*(vi + (*(t + 1)))) || (*(vi + (*(t + 2) }
))))) }
|| ((*(vi + (*t))) && (*(vi + (*(t + 1)))) && (*(vi + (*(t + 2))
))))) { if (ok) ok &= CGOStop(I->shaderCGO);
if (I->Type != 2){
glNormal3fv(vn + (*t) * 3); CGOCombineBeginEnd(&I->shaderCGO);
glVertex3fv(v + (*t) * 3); if (I->Type == 1){
t++; /* Only needed to simplify spheres in surface_type=1 */
glNormal3fv(vn + (*t) * 3); CGO *simple = CGOSimplify(I->shaderCGO, 0);
glVertex3fv(v + (*t) * 3); CGOCombineBeginEnd(&simple, 0);
t++; CHECKOK(ok, simple);
glNormal3fv(vn + (*t) * 3); setPickingCGO(I, simple);
glVertex3fv(v + (*t) * 3); } else {
t++; setPickingCGO(I, I->shaderCGO);
} else { }
t += 3; }
if(I->Type == 1){
if (dot_as_spheres) {
CGO *tmpCGO = CGONew(G);
CHECKOK(ok, tmpCGO);
ok &= CGOEnable(tmpCGO, GL_SPHERE_SHADER);
ok &= CGOEnable(tmpCGO, GL_DOT_LIGHTING); // TODO: this needs normals in
sphere shader PYMOL-1870
ok &= CGOSpecial(tmpCGO, DOTSIZE_WITH_SPHERESCALE);
convertcgo = CGOOptimizeSpheresToVBONonIndexedNoShader(I->shaderCGO,
CGO_BOUNDING_BOX_SZ + fsizeof<cgo::draw::sphere_buffers>() + 2);
ok &= CGOAppendNoStop(tmpCGO, convertcgo);
CGOFreeWithoutVBOs(convertcgo);
ok &= CGODisable(tmpCGO, GL_SPHERE_SHADER);
CGOStop(tmpCGO);
convertcgo = tmpCGO;
} else {
convertcgo = CGOOptimizeToVBONotIndexedNoShader(I->shaderCGO, 0);
}
CHECKOK(ok, convertcgo);
if (ok)
convertcgo->use_shader = true;
} else if (I->Type == 2) {
CGO *convertcgo2, *simple = NULL;
CGO *tmpCGO = CGONew(G);
CHECKOK(ok, tmpCGO);
convertcgo2 = CGOConvertLinesToShaderCylinders(I->shaderCGO, 0);
CHECKOK(ok, convertcgo2);
CGOEnable(tmpCGO, GL_CYLINDER_SHADER);
CGOSpecial(tmpCGO, MESH_WIDTH_FOR_SURFACES);
convertcgo = CGOConvertShaderCylindersToCylinderShader(convertcgo2, tmpCGO);
CGOAppendNoStop(tmpCGO, convertcgo);
CGOFreeWithoutVBOs(convertcgo);
CGODisable(tmpCGO, GL_CYLINDER_SHADER);
CGOStop(tmpCGO);
convertcgo = tmpCGO;
convertcgo->use_shader = true;
if (ok)
simple = CGOSimplify(convertcgo2, 0);
CHECKOK(ok, simple);
if (ok)
setPickingCGO(I, CGOCombineBeginEnd(simple, 0));
CHECKOK(ok, I->pickingCGO);
CGOFree(simple);
CGOFree(convertcgo2);
} else {
if((alpha != 1.0) || va) { // semi-transparent
if (ok)
convertcgo = CGOOptimizeToVBOIndexedWithColorEmbedTransparentInfo(I->shad
erCGO, 0, 0, 0);
CHECKOK(ok, convertcgo);
#ifdef _PYMOL_IOS
#endif
} else {
if (ok)
convertcgo = CGOOptimizeToVBONotIndexedWithReturnedData(I->shaderCGO, 0,
false, NULL);
CHECKOK(ok, convertcgo);
}
if (ok)
convertcgo->use_shader = true;
{
CGO *tmpCGO = NULL;
tmpCGO = CGONew(G);
CGOEnable(tmpCGO, GL_SURFACE_SHADER);
//CGOEnable(tmpCGO, CGO_GL_LIGHTING); // do we need this?
CGOSpecial(tmpCGO, SET_SURFACE_UNIFORMS);
CGOAppendNoStop(tmpCGO, convertcgo);
CGODisable(tmpCGO, GL_SURFACE_SHADER);
CGOStop(tmpCGO);
CGOFreeWithoutVBOs(convertcgo);
convertcgo = tmpCGO;
convertcgo->use_shader = true;
}
}
if(ok && I->Type == 1 && !dot_as_spheres) {
setShaderCGO(I, CGONew(G));
CHECKOK(ok, I->shaderCGO);
if (ok){
I->shaderCGO->use_shader = true;
if (ok) ok &= CGOResetNormal(I->shaderCGO, true);
if (ok) ok &= CGOEnable(I->shaderCGO, GL_SURFACE_SHADER);
if (ok) ok &= CGOSpecial(I->shaderCGO, POINTSIZE_DYNAMIC_DOT_WIDTH);
if (ok) CGOAppendNoStop(I->shaderCGO, convertcgo);
if (ok) ok &= CGODisable(I->shaderCGO, GL_SURFACE_SHADER);
if (ok) ok &= CGOStop(I->shaderCGO);
CGOFreeWithoutVBOs(convertcgo);
convertcgo = NULL;
}
} else {
setShaderCGO(I, convertcgo);
convertcgo = NULL;
}
{
CGO *simple = NULL;
if (ok)
simple = CGOOptimizeToVBONotIndexed(I->pickingCGO, 0);
CHECKOK(ok, simple);
if (ok){
CGOChangeShadersTo(simple, GL_DEFAULT_SHADER, GL_SURFACE_SHADER);
}
if (ok){
setPickingCGO(I, simple);
I->pickingCGO->use_shader = true;
I->pickingCGO->no_pick = !pick_surface;
}
}
return ok;
}
static void RepSurfaceRender(RepSurface * I, RenderInfo * info)
{
CRay *ray = info->ray;
Picking **pick = info->pick;
PyMOLGlobals *G = I->R.G;
float *v = I->V;
float *vn = I->VN;
float *vc = I->VC;
float *va = I->VA;
int *rc = I->RC;
int *t = I->T;
int *s = I->S;
int c = I->N;
int *vi = I->Vis;
int ok = true;
float alpha;
int t_mode;
float ambient_occlusion_scale = 0.f;
int ambient_occlusion_mode = SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setti
ng, cSetting_ambient_occlusion_mode);
int ambient_occlusion_mode_div_4;
if (ambient_occlusion_mode){
ambient_occlusion_scale = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Settin
g, cSetting_ambient_occlusion_scale);
ambient_occlusion_mode_div_4 = ambient_occlusion_mode / 4;
}
if((I->Type != 1) && (!s)) {
return;
}
alpha = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_transpar
ency);
alpha = 1.0F - alpha;
if(fabs(alpha - 1.0) < R_SMALL4)
alpha = 1.0F;
if(ray) {
#ifndef _PYMOL_NO_RAY
ray->transparentf(1.0F - alpha);
if(I->Type == 1) {
/* dot surface */
float radius;
radius = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_dot
_radius);
if(radius == 0.0F) {
radius = ray->PixelRadius * SettingGet_f(G, I->R.cs->Setting,
I->R.obj->Setting,
cSetting_dot_width) / 1.4142F;
}
if(I->oneColorFlag) {
float col[3];
ColorGetEncoded(G, I->oneColor, col);
ray->color3fv(col);
}
if(c)
while(ok && c--) {
if(*vi) {
if(!I->oneColorFlag) {
ray->color3fv(vc);
}
ok &= ray->sphere3fv(v, radius);
}
vi++;
vc += 3;
v += 3;
}
} else if((I->Type == 0) || (I->Type == 3) || (I->Type == 4) || (I->Type ==
5)) { /* solid surface */
c = I->NT;
if(I->oneColorFlag) {
float col[3], col1[3], col2[3], col3[3];
ColorGetEncoded(G, I->oneColor, col);
while(ok && c--) {
if (visibility_test(I->proximity, vi, t)) {
copy3f(col, col1);
copy3f(col, col2);
copy3f(col, col3);
if (I->VAO){
float ao1, ao2, ao3;
switch (ambient_occlusion_mode_div_4){
case 1:
ao1 = 1.f-ambient_occlusion_scale*(*(I->VAO + *t));
ao2 = 1.f-ambient_occlusion_scale*(*(I->VAO + *(t+1)));
ao3 = 1.f-ambient_occlusion_scale*(*(I->VAO + *(t+2)));
break;
case 2:
ao1 = cos(.5f * PI * CLAMP_VALUE(ambient_occlusion_scale*(*(I->VA
O + *t))));
ao2 = cos(.5f * PI * CLAMP_VALUE(ambient_occlusion_scale*(*(I->VA
O + *(t+1)))));
ao3 = cos(.5f * PI * CLAMP_VALUE(ambient_occlusion_scale*(*(I->VA
O + *(t+2)))));
break;
default:
ao1 = CLAMP_VALUE(1.f / (1.f + exp(.5f*((ambient_occlusion_scale*
(*(I->VAO + *t))) - 10.f))));
ao2 = CLAMP_VALUE(1.f / (1.f + exp(.5f*((ambient_occlusion_scale*
(*(I->VAO + *(t+1)))) - 10.f))));
ao3 = CLAMP_VALUE(1.f / (1.f + exp(.5f*((ambient_occlusion_scale*
(*(I->VAO + *(t+2)))) - 10.f))));
}
mult3f(col1, ao1, col1);
mult3f(col2, ao2, col2);
mult3f(col3, ao3, col3);
}
ok &= ray->triangle3fv(v + (*t) * 3, v + (*(t + 1)) * 3, v + (*(t + 2
)) * 3,
vn + (*t) * 3, vn + (*(t + 1)) * 3, vn + (*(t
+ 2)) * 3,
col1, col2, col3);
}
t += 3;
}
} else {
while(ok && c--) {
int ttA = *t, ttB = *(t + 1), ttC = *(t + 2);
if (visibility_test(I->proximity, vi, t)) {
int ttA3 = ttA * 3, ttB3 = ttB * 3, ttC3 = ttC * 3;
float cA[3], cB[3], cC[3];
copy3f(vc + ttA3, cA);
copy3f(vc + ttB3, cB);
copy3f(vc + ttC3, cC);
// register float *cA = vc + ttA3, *cB = vc + ttB3, *cC =
vc + ttC3;
if(rc) {
if(rc[ttA] < -1)
ColorGetEncoded(G, rc[ttA], cA);
// ColorGetEncoded(G, rc[ttA], (cA = colA));
if(rc[ttB] < -1)
ColorGetEncoded(G, rc[ttB], cB);
// ColorGetEncoded(G, rc[ttB], (cB = colB));
if(rc[ttC] < -1)
ColorGetEncoded(G, rc[ttC], cC);
// ColorGetEncoded(G, rc[ttC], (cC = colC));
}
if((*(vi + ttA)) || (*(vi + ttB)) || (*(vi + ttC))) {
if (I->VAO){
float ao1, ao2, ao3;
switch (ambient_occlusion_mode_div_4){
case 1:
ao1 = 1.f-ambient_occlusion_scale*(*(I->VAO + *t));
ao2 = 1.f-ambient_occlusion_scale*(*(I->VAO + *(t+1)));
ao3 = 1.f-ambient_occlusion_scale*(*(I->VAO + *(t+2)));
break;
case 2:
ao1 = cos(.5f * PI * CLAMP_VALUE(ambient_occlusion_scale*(*(I->
VAO + *t))));
ao2 = cos(.5f * PI * CLAMP_VALUE(ambient_occlusion_scale*(*(I->
VAO + *(t+1)))));
ao3 = cos(.5f * PI * CLAMP_VALUE(ambient_occlusion_scale*(*(I->
VAO + *(t+2)))));
break;
default:
ao1 = CLAMP_VALUE(1.f / (1.f + exp(.5f*((ambient_occlusion_scal
e*(*(I->VAO + *t))) - 10.f))));
ao2 = CLAMP_VALUE(1.f / (1.f + exp(.5f*((ambient_occlusion_scal
e*(*(I->VAO + *(t+1)))) - 10.f))));
ao3 = CLAMP_VALUE(1.f / (1.f + exp(.5f*((ambient_occlusion_scal
e*(*(I->VAO + *(t+2)))) - 10.f))));
}
mult3f(cA, ao1, cA);
mult3f(cB, ao2, cB);
mult3f(cC, ao3, cC);
}
if(va) {
ok &= ray->triangleTrans3fv(v + ttA3, v + ttB3, v + ttC3,
vn + ttA3, vn + ttB3, vn + ttC3,
cA, cB, cC,
1.0F - va[ttA], 1.0F - va[ttB], 1.0F
- va[ttC]);
} else {
ok &= ray->triangle3fv(v + ttA3, v + ttB3, v + ttC3,
vn + ttA3, vn + ttB3, vn + ttC3, cA, cB,
cC);
}
}
}
t += 3;
}
}
} else if(I->Type == 2) { /* triangle mesh surface */
float radius;
int t0, t1, t2;
int spacing = 10;
int *cache = Calloc(int, spacing * (I->N + 1));
CHECKOK(ok, cache);
radius = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_mes
h_radius);
if(ok && radius == 0.0F) {
float line_width =
SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_mesh_wid
th);
line_width = SceneGetDynamicLineWidth(info, line_width);
radius = ray->PixelRadius * line_width / 2.0F;
}
if (ok){
float col[3], *col0, *col1, *col2;
c = I->NT;
if(I->oneColorFlag) {
ColorGetEncoded(G, I->oneColor, col);
col0 = col1 = col2 = col;
}
while(ok && c--) {
t0 = (*t);
t1 = (*(t + 1));
t2 = (*(t + 2));
if (visibility_test(I->proximity, vi, t)) {
if (!I->oneColorFlag) {
col0 = vc + t0 * 3;
col1 = vc + t1 * 3;
col2 = vc + t2 * 3;
}
if(!check_and_add(cache, spacing, t0, t1))
ok &= ray->sausage3fv(v + t0 * 3, v + t1 * 3, radius, col0, col1)
;
if(!check_and_add(cache, spacing, t1, t2))
ok &= ray->sausage3fv(v + t1 * 3, v + t2 * 3, radius, col1, col2)
;
if(!check_and_add(cache, spacing, t2, t0))
ok &= ray->sausage3fv(v + t2 * 3, v + t0 * 3, radius, col2, col0)
;
}
t += 3;
}
FreeP(cache);
}
}
if (ok){
ray->transparentf(0.0);
} else {
/* If not ok, then Clear Entire RepSurface, not just the ray object */
}
#endif
} else if(G->HaveGUI && G->ValidContext) {
/* Not ray tracing, but rendering */
if(pick) {
// Don't render transparent unpickable surfaces. Do render solid but
// unpickable surfaces to write the depth buffer and prevent
// through-picking.
if (I->pickingCGO && !(I->pickingCGO->no_pick && alpha < 1.F)) {
CGORenderGLPicking(I->pickingCGO, info, &I->R.context, I->R.cs->Setting,
I->R.obj->Setting);
}
} else {
#ifndef PURE_OPENGL_ES_2
bool use_shader = SettingGetGlobal_b(G, cSetting_surface_use_shader) &&
SettingGetGlobal_b(G, cSetting_use_shaders);
if (use_shader && !info->alpha_cgo)
#endif
{
bool dot_as_spheres = SettingGet_b(G, I->R.cs->Setting, I->R.obj->Settin
g, cSetting_dot_as_spheres);
if (!I->shaderCGO || CGOCheckWhetherToFree(G, I->shaderCGO) ||
(I->Type == 1 && I->dot_as_spheres != dot_as_spheres)) {
ok &= RepSurfaceCGOGenerate(I, info);
}
if (ok && I->shaderCGO) {
const float *color = ColorGet(G, I->R.obj->Color);
CGORenderGL(I->shaderCGO, color, NULL, NULL, info, &I->R);
return;
}
PRINTFB(G, FB_RepSurface, FB_Errors)
" RepSurfaceCGOGenerate failed\n" ENDFB(G);
}
setShaderCGO(I, NULL);
#ifndef PURE_OPENGL_ES_2
bool two_sided_lighting =
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting,
cSetting_two_sided_lighting) > 0;
if (two_sided_lighting){
GLLIGHTMODELI(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
}
if(I->Type == 1) {
/* no triangle information, so we're rendering dots only */
{
int normals =
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_dot_no
rmals);
int lighting = info->line_lighting ||
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_dot_li
ghting);
if(!normals){
SceneResetNormal(G, true);
vn = NULL;
}
if(!lighting)
glDisable(GL_LIGHTING);
glPointSize(SettingGet_f
(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_dot_width));
if(c) {
glBegin(GL_POINTS);
if(I->oneColorFlag) {
glColor3fv(ColorGet(G, I->oneColor));
vc = NULL;
} else {
glColor3f(1.0, 0.0, 0.0);
}
immediate_draw_masked_vertices(vc, vn, v, vi, c);
glEnd();
}
if(!lighting)
glEnable(GL_LIGHTING);
} /* else use shader */
} else if(I->Type == 2) { /* rendering triangle mesh */
if (ok) {
c = I->NT;
if(ok && c) {
int normals =
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_me
sh_normals);
int lighting = info->line_lighting ||
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_me
sh_lighting);
if(!normals){
SceneResetNormal(G, true);
vn = NULL;
}
if(!lighting)
glDisable(GL_LIGHTING);
float line_width =
SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_me
sh_width);
glLineWidth(SceneGetDynamicLineWidth(info, line_width));
if(I->oneColorFlag) {
glColor3fv(ColorGet(G, I->oneColor));
vc = NULL;
}
glBegin(GL_LINES);
for (; c--; t += 3) {
if (visibility_test(I->proximity, vi, t)) {
int indices[] = {t[0], t[1], t[1], t[2], t[2], t[0]};
immediate_draw_indexed_vertices(vc, vn, v, indices, 6);
}
}
glEnd();
if(!lighting)
glEnable(GL_LIGHTING);
}
}
} else {
/* we're rendering triangles */
if((alpha != 1.0) || va) {
t_mode =
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting,
cSetting_transparency_mode);
if(info && info->alpha_cgo) {
t_mode = 0;
}
if(t_mode) {
float **t_buf = NULL, **tb;
float *z_value = NULL, *zv;
int *ix = NULL;
int n_tri = 0;
float sum[3];
float matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
if(I->oneColorFlag) {
t_buf = Alloc(float *, I->NT * 6);
} else {
t_buf = Alloc(float *, I->NT * 12);
}
CHECKOK(ok, t_buf);
if (ok){
z_value = Alloc(float, I->NT);
CHECKOK(ok, z_value);
}
if (ok){
ix = Alloc(int, I->NT);
CHECKOK(ok, ix);
}
zv = z_value;
tb = t_buf;
c = I->NT;
if (ok){
if(I->oneColorFlag) {
while(c--) {
if (visibility_test(I->proximity, vi, t)) {
*(tb++) = vn + (*t) * 3;
*(tb++) = v + (*t) * 3;
*(tb++) = vn + (*(t + 1)) * 3;
*(tb++) = v + (*(t + 1)) * 3;
*(tb++) = vn + (*(t + 2)) * 3;
*(tb++) = v + (*(t + 2)) * 3;
add3f(tb[-1], tb[-3], sum);
add3f(sum, tb[-5], sum);
*(zv++) = matrix[2] * sum[0] + matrix[6] * sum[1] + matrix[10
] * sum[2];
n_tri++;
}
t += 3;
}
} else {
while(c--) {
if (visibility_test(I->proximity, vi, t)) {
if(va)
*(tb++) = va + (*t);
else
*(tb++) = &alpha;
*(tb++) = vc + (*t) * 3;
*(tb++) = vn + (*t) * 3;
*(tb++) = v + (*t) * 3;
if(va)
*(tb++) = va + (*(t + 1));
else
*(tb++) = &alpha;
*(tb++) = vc + (*(t + 1)) * 3;
*(tb++) = vn + (*(t + 1)) * 3;
*(tb++) = v + (*(t + 1)) * 3;
if(va)
*(tb++) = va + (*(t + 2));
else
*(tb++) = &alpha;
*(tb++) = vc + (*(t + 2)) * 3;
*(tb++) = vn + (*(t + 2)) * 3;
*(tb++) = v + (*(t + 2)) * 3;
add3f(tb[-1], tb[-5], sum);
add3f(sum, tb[-9], sum);
*(zv++) =
matrix[2] * sum[0] + matrix[6] * sum[1] + matrix[10] * su
m[2];
n_tri++;
}
t += 3;
}
}
}
switch (t_mode) {
case 1:
ok &= UtilSemiSortFloatIndex(n_tri, z_value, ix, true);
/* UtilSortIndex(n_tri,z_value,ix,(UtilOrderFn*)ZOrderFn); */
break;
default:
ok &= UtilSemiSortFloatIndex(n_tri, z_value, ix, false);
/* UtilSortIndex(n_tri,z_value,ix,(UtilOrderFn*)ZRevOrderFn); */
break;
}
c = n_tri;
if(I->oneColorFlag) {
float col[3];
ColorGetEncoded(G, I->oneColor, col);
if (ok){
glColor4f(col[0], col[1], col[2], alpha);
glBegin(GL_TRIANGLES);
for(c = 0; c < n_tri; c++) {
tb = t_buf + 6 * ix[c];
glNormal3fv(*(tb++));
glVertex3fv(*(tb++));
glNormal3fv(*(tb++));
glVertex3fv(*(tb++));
glNormal3fv(*(tb++));
glVertex3fv(*(tb++));
}
glEnd();
}
} else { /* else I->oneColorFlag */
glBegin(GL_TRIANGLES);
for(c = 0; c < n_tri; c++) {
float *vv, *v_alpha;
tb = t_buf + 12 * ix[c];
v_alpha = *(tb++);
vv = *(tb++);
glColor4f(vv[0], vv[1], vv[2], *v_alpha);
glNormal3fv(*(tb++));
glVertex3fv(*(tb++));
v_alpha = *(tb++);
vv = *(tb++);
glColor4f(vv[0], vv[1], vv[2], *v_alpha);
glNormal3fv(*(tb++));
glVertex3fv(*(tb++));
v_alpha = *(tb++);
vv = *(tb++);
glColor4f(vv[0], vv[1], vv[2], *v_alpha);
glNormal3fv(*(tb++));
glVertex3fv(*(tb++));
}
glEnd();
}
{
FreeP(ix);
FreeP(z_value);
FreeP(t_buf);
}
} else if (ok) {
if(info->alpha_cgo) { /* global transparency sort */
if(I->allVisibleFlag) {
if(I->oneColorFlag) {
float col[3];
ColorGetEncoded(G, I->oneColor, col);
glColor4f(col[0], col[1], col[2], alpha);
c = *(s++);
while(c) {
int parity = 0;
s += 2;
while(ok && c--) {
ok &= CGOAlphaTriangle(info->alpha_cgo,
v + s[-2] * 3, v + s[-1] * 3, v + (*
s) * 3,
vn + s[-2] * 3, vn + s[-1] * 3, vn +
(*s) * 3,
col, col, col, alpha, alpha, alpha,
parity);
s++;
parity = !parity;
}
c = *(s++);
}
} else {
c = *(s++);
while(ok && c) {
float *col0, *col1, *col2;
int parity = 0;
float alpha0, alpha1, alpha2;
col0 = vc + (*s) * 3;
if(va) {
alpha0 = va[(*s)];
} else {
alpha0 = alpha;
}
s++;
col1 = vc + (*s) * 3;
if(va) {
alpha1 = va[(*s)];
} else {
alpha1 = alpha;
}
s++;
while(ok && c--) {
col2 = vc + (*s) * 3;
if(va) {
alpha2 = va[(*s)];
} else {
alpha2 = alpha;
}
ok &= CGOAlphaTriangle(info->alpha_cgo,
v + s[-2] * 3, v + s[-1] * 3, v + (*
s) * 3,
vn + s[-2] * 3, vn + s[-1] * 3, vn +
(*s) * 3,
col0, col1, col2, alpha0, alpha1, al
pha2, parity);
alpha0 = alpha1;
alpha1 = alpha2;
col0 = col1;
col1 = col2;
s++;
parity = !parity;
}
c = *(s++);
}
}
} else if (ok){ /* subset s */
c = I->NT;
if(c) {
if(I->oneColorFlag) {
float color[3];
ColorGetEncoded(G, I->oneColor, color);
while(ok && c--) {
if (visibility_test(I->proximity, vi, t))
{
ok &= CGOAlphaTriangle(info->alpha_cgo,
v + t[0] * 3, v + t[1] * 3, v + t[
2] * 3,
vn + t[0] * 3, vn + t[1] * 3, vn +
t[2] * 3,
color, color, color, alpha, alpha,
alpha, 0);
}
t += 3;
}
} else {
while(ok && c--) {
if (visibility_test(I->proximity, vi, t))
{
if(va) {
ok &= CGOAlphaTriangle(info->alpha_cgo,
v + t[0] * 3, v + t[1] * 3, v +
t[2] * 3,
vn + t[0] * 3, vn + t[1] * 3, vn
+ t[2] * 3,
vc + t[0] * 3, vc + t[1] * 3, vc
+ t[2] * 3,
va[t[0]], va[t[1]], va[t[2]], 0)
;
} else {
ok &= CGOAlphaTriangle(info->alpha_cgo,
v + t[0] * 3, v + t[1] * 3, v +
t[2] * 3,
vn + t[0] * 3, vn + t[1] * 3, vn
+ t[2] * 3,
vc + t[0] * 3, vc + t[1] * 3, vc
+ t[2] * 3,
alpha, alpha, alpha, 0);
}
}
t += 3;
}
}
if (ok)
CGOEnd(info->alpha_cgo);
}
}
} else if (ok){
/* fast and ugly */
if(I->oneColorFlag) {
float col[3];
ColorGetEncoded(G, I->oneColor, col);
glColor4f(col[0], col[1], col[2], alpha);
vc = NULL;
}
if(I->allVisibleFlag) {
for (; (c = *(s++)); s += c + 2) {
glBegin(GL_TRIANGLE_STRIP);
immediate_draw_indexed_vertices_alpha(vc, va, alpha, vn, v,
s, c + 2);
glEnd();
}
} else {
c = I->NT;
if(c) {
glBegin(GL_TRIANGLES);
for (; c--; t += 3) {
if (visibility_test(I->proximity, vi, t)) {
immediate_draw_indexed_vertices_alpha(vc, va, alpha, vn,
v, t, 3);
}
}
glEnd();
}
}
}
}
} else if (ok) { /* opaque */
if(I->oneColorFlag) {
glColor3fv(ColorGet(G, I->oneColor));
vc = NULL;
}
if(I->allVisibleFlag) {
for (; (c = *(s++)); s += c + 2) {
glBegin(GL_TRIANGLE_STRIP);
immediate_draw_indexed_vertices(vc, vn, v, s, c + 2);
glEnd();
}
} else {
c = I->NT;
if(c) {
glBegin(GL_TRIANGLES);
for (; c--; t += 3) {
if (visibility_test(I->proximity, vi, t)) {
immediate_draw_indexed_vertices(vc, vn, v, t, 3);
}
}
glEnd();
}
}
}
}
if(ok && SettingGetGlobal_i(G, cSetting_surface_debug)) {
t = I->T;
c = I->NT;
glLineWidth(1.0F);
// draw green triangles, either filled or as line edges,
// depending on surface_type
if(c) {
glColor3f(0.0, 1.0, 0.0);
if (I->Type == 2) {
// filled green triangles for surface as mesh
glBegin(GL_TRIANGLES);
for (; c--; t += 3) {
if(I->allVisibleFlag
|| visibility_test(I->proximity, vi, t)) {
immediate_draw_indexed_vertices(NULL, vn, v, t, 3);
}
}
glEnd();
} else {
// line edges as green lines
glBegin(GL_LINES);
for (; c--; t += 3) {
if(I->allVisibleFlag
|| visibility_test(I->proximity, vi, t)) {
int indices[] = {t[0], t[1], t[1], t[2], t[2], t[0]};
immediate_draw_indexed_vertices(NULL, vn, v, indices, 6);
}
} }
glEnd(); glEnd();
#endif
} }
} }
} /* end else use_shader */
// draw normals as red lines
c = I->N; c = I->N;
if (generate_shader_cgo){
if(ok && c) {
ok &= CGOColor(I->shaderCGO, 1.0, 0.0, 0.0);
if (ok) ok &= CGOResetNormal(I->shaderCGO, true);
if (ok) ok &= CGOBegin(I->shaderCGO, GL_LINES);
while(ok && c--) {
ok &= CGOVertexv(I->shaderCGO, v);
if (ok) ok &= CGOVertex(I->shaderCGO, v[0] + vn[0] / 2, v[1] + vn[1
] / 2, v[2] + vn[2] / 2);
v += 3;
vn += 3;
}
if (ok) ok &= CGOEnd(I->shaderCGO);
}
} else {
if(c) { if(c) {
SceneResetNormal(G, true); SceneResetNormal(G, true);
glColor3f(1.0, 0.0, 0.0); glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINES); glBegin(GL_LINES);
while(c--) { while(c--) {
glVertex3fv(v); glVertex3fv(v);
glVertex3f(v[0] + vn[0] / 2, v[1] + vn[1] / 2, v[2] + vn[2] / 2); glVertex3f(v[0] + vn[0] / 2, v[1] + vn[1] / 2, v[2] + vn[2] / 2);
v += 3; v += 3;
vn += 3; vn += 3;
} }
glEnd(); glEnd();
} }
} /* end else use_shader */
} }
/* end of rendering, if using shaders, then render CGO */
if (ok && use_shader) {
CShaderPrg * shaderPrg = 0;
if (generate_shader_cgo){
CGO *convertcgo = NULL;
if (ok) ok &= CGOStop(I->shaderCGO);
if (I->Type != 2){
if (ok)
convertcgo = CGOCombineBeginEnd(I->shaderCGO, 0);
CHECKOK(ok, convertcgo);
if (I->pickingCGO && I->pickingCGO!=I->shaderCGO){
CGOFree(I->pickingCGO);
I->pickingCGO = NULL;
}
CGOFree(I->shaderCGO);
I->shaderCGO = convertcgo;
convertcgo = NULL;
I->pickingCGO = I->shaderCGO;
if (I->Type == 1){
/* Only needed to simplify spheres in surface_type=1 */
CGO *simple = CGOSimplify(I->shaderCGO, 0);
CHECKOK(ok, simple);
if (ok)
I->pickingCGO = CGOCombineBeginEnd(simple ,0);
CHECKOK(ok, I->pickingCGO);
CGOFree(simple);
}
}
if(I->Type == 1){
if (dot_as_spheres) {
convertcgo = CGOOptimizeSpheresToVBONonIndexed(I->shaderCGO, CGO_BO
UNDING_BOX_SZ + CGO_DRAW_SPHERE_BUFFERS_SZ);
} else {
convertcgo = CGOOptimizeToVBONotIndexedWithReturnedData(I->shaderCG
O, 0, false, NULL);
}
CHECKOK(ok, convertcgo);
if (ok)
convertcgo->use_shader = true;
} else if (I->Type == 2) {
CGO *convertcgo2, *simple = NULL;
convertcgo2 = CGOConvertLinesToShaderCylinders(I->shaderCGO, 0);
CHECKOK(ok, convertcgo2);
if (ok)
convertcgo = CGOOptimizeGLSLCylindersToVBOIndexed(convertcgo2, 0);
CHECKOK(ok, convertcgo);
if (ok)
convertcgo->use_shader = true;
if (ok)
simple = CGOCombineBeginEnd(convertcgo2, 0);
CHECKOK(ok, simple);
if (ok)
I->pickingCGO = CGOSimplify(simple, 0);
CHECKOK(ok, I->pickingCGO);
CGOFree(simple);
CGOFree(convertcgo2);
} else {
if(I->Type != 1 && ((alpha != 1.0) || va)) {
if (ok)
convertcgo = CGOOptimizeToVBOIndexedNoShader(I->shaderCGO, 0);
CHECKOK(ok, convertcgo);
} else {
if (ok)
convertcgo = CGOOptimizeToVBONotIndexedWithReturnedData(I->shader
CGO, 0, false, NULL);
CHECKOK(ok, convertcgo);
}
if (ok)
convertcgo->use_shader = true;
}
if(ok && I->Type == 1 && !dot_as_spheres) {
I->shaderCGO = CGONew(G);
CHECKOK(ok, I->shaderCGO);
if (ok){
I->shaderCGO->use_shader = true;
if (ok) ok &= CGOResetNormal(I->shaderCGO, true);
if (ok) ok &= CGOLinewidthSpecial(I->shaderCGO, POINTSIZE_DYNAMIC_D
OT_WIDTH);
if (ok) ok &= CGOStop(I->shaderCGO);
if (ok) CGOAppend(I->shaderCGO, convertcgo);
CGOFreeWithoutVBOs(convertcgo);
convertcgo = NULL;
}
} else {
I->shaderCGO = convertcgo;
convertcgo = NULL;
}
}
if (I->Type == 1){ if (two_sided_lighting){
if (dot_as_spheres){ GLLIGHTMODELI(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
float radius = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, c
Setting_dot_width)
* info->vertex_scale;
shaderPrg = CShaderPrg_Enable_DefaultSphereShader(G);
CShaderPrg_Set1f(shaderPrg, "sphere_size_scale", fabs(radius));
} else {
shaderPrg = CShaderPrg_Enable_DefaultShader(G);
SceneResetNormalUseShaderAttribute(G, 0, true, CShaderPrg_GetAttribLo
cation(shaderPrg, "a_Normal"));
}
} else if (I->Type == 2) {
float mesh_width = SettingGet_f(G, I->R.obj->Setting, NULL, cSetting_me
sh_width);
shaderPrg = CShaderPrg_Enable_CylinderShader(G);
CShaderPrg_Set1f(shaderPrg, "uni_radius", SceneGetLineWidthForCylinders
(G, info, mesh_width));
} else {
shaderPrg = CShaderPrg_Enable_DefaultShader(G);
CShaderPrg_Set1f(shaderPrg, "ambient_occlusion_scale", ambient_occlusio
n_scale);
CShaderPrg_Set1i(shaderPrg, "use_interior_color_threshold", 1);
{
if((alpha != 1.0) || va) {
int t_mode =
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting,
cSetting_transparency_mode);
if(info && info->alpha_cgo) {
t_mode = 0;
}
if (t_mode){
RepSurfaceSortIX(G, I, t_mode);
if (I->ix){
float *pc = CGOGetNextDrawBufferedIndex(I->shaderCGO->op);
if (pc){
int nindices = CGO_get_int(pc+3), c, pl, idx;
uint vbuf = CGO_get_int(pc+8);
uint *vertexIndices;
vertexIndices = Alloc(uint, nindices);
if (!vertexIndices){
PRINTFB(I->R.G, FB_RepSurface, FB_Errors) "ERROR: RepSurfac
eRender() vertexIndices could not be allocated: nindices=%d\n", nindices ENDFB(I
->R.G);
}
for(c = 0, pl=0; c < I->n_tri; c++) {
idx = I->ix[c] * 3;
vertexIndices[pl++] = idx;
vertexIndices[pl++] = idx + 1;
vertexIndices[pl++] = idx + 2;
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbuf);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint)*nindices,
vertexIndices, GL_STATIC_DRAW);
I->vertexIndices = vertexIndices;
}
}
}
}
}
}
if (I->shaderCGO){
I->shaderCGO->enable_shaders = shaderPrg ? 0 : 1;
CGORenderGL(I->shaderCGO, NULL, NULL, NULL, info, &I->R);
if (shaderPrg){
CShaderPrg_Disable(shaderPrg);
}
}
} }
#endif
} }
} }
if (!ok){ if (!ok){
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[cRepSurface] = false; I->R.cs->Active[cRepSurface] = false;
} }
} }
int RepSurfaceSameVis(RepSurface * I, CoordSet * cs) int RepSurfaceSameVis(RepSurface * I, CoordSet * cs)
{ {
int same = true; int same = true;
char *lv; char *lv;
int a; int a;
skipping to change at line 2447 skipping to change at line 2192
} }
} }
return true; return true;
} }
void RepSurfaceColor(RepSurface * I, CoordSet * cs) void RepSurfaceColor(RepSurface * I, CoordSet * cs)
{ {
PyMOLGlobals *G = cs->State.G; PyMOLGlobals *G = cs->State.G;
MapType *map = NULL, *ambient_occlusion_map = NULL; MapType *map = NULL, *ambient_occlusion_map = NULL;
int a, i0, i, j, c1; int a, i0, i, j, c1;
float *v0, *vc, *c0, *va; float *v0, *vc, *va;
const float *c0;
float *n0; float *n0;
int *vi, *lc; int *vi, *lc;
char *lv; char *lv;
int first_color; int first_color;
float *v_pos, v_above[3]; float *v_pos, v_above[3];
int ramp_above; int ramp_above;
ObjectMolecule *obj; ObjectMolecule *obj;
float probe_radius; float probe_radius;
float dist; float dist;
float cutoff; float cutoff;
skipping to change at line 2669 skipping to change at line 2415
/* per atom */ /* per atom */
float *VAO = Alloc(float, cs->NIndex); float *VAO = Alloc(float, cs->NIndex);
short *nVAO = Alloc(short, cs->NIndex); short *nVAO = Alloc(short, cs->NIndex);
memset(VAO, 0, sizeof(float)*cs->NIndex); memset(VAO, 0, sizeof(float)*cs->NIndex);
memset(nVAO, 0, sizeof(short)*cs->NIndex); memset(nVAO, 0, sizeof(short)*cs->NIndex);
for(a = 0; a < I->N; a++) { for(a = 0; a < I->N; a++) {
int nbits = 0; int nbits = 0;
short level1, level2, has; short level1, level2, has;
unsigned long bits = 0L, bit; unsigned long bits = 0L, bit;
float d[3], *vn0, planew, v0mod[3]; float d[3], *vn0, v0mod[3];
int closeA = -1; int closeA = -1;
float closeDist = MAXFLOAT; float closeDist = MAXFLOAT;
has = 0; has = 0;
v0 = I->V + 3 * a; v0 = I->V + 3 * a;
vn0 = I->VN + 3 * a; vn0 = I->VN + 3 * a;
mult3f(vn0, .01f, v0mod); mult3f(vn0, .01f, v0mod);
add3f(v0, v0mod, v0mod); add3f(v0, v0mod, v0mod);
planew = -(vn0[0] * v0mod[0] + vn0[1] * v0mod[1] + vn0[2] * v0mod[2]);
i = *(MapLocusEStart(ambient_occlusion_map, v0)); i = *(MapLocusEStart(ambient_occlusion_map, v0));
if(i && map->EList) { if(i && map->EList) {
j = ambient_occlusion_map->EList[i++]; j = ambient_occlusion_map->EList[i++];
while(j >= 0) { while(j >= 0) {
subtract3f(cs->Coord + j * 3, v0, d); subtract3f(cs->Coord + j * 3, v0, d);
dist = (float) length3f(d); dist = (float) length3f(d);
if (dist < closeDist){ if (dist < closeDist){
closeA = j; closeA = j;
closeDist = dist; closeDist = dist;
skipping to change at line 2748 skipping to change at line 2493
} }
} }
FreeP(VAO); FreeP(VAO);
FreeP(nVAO); FreeP(nVAO);
} else { } else {
float natomsL = 0; float natomsL = 0;
for(a = 0; a < I->N; a++) { for(a = 0; a < I->N; a++) {
int natoms = 0, nbits = 0; int natoms = 0, nbits = 0;
short level1, level2, has; short level1, level2, has;
unsigned long bits = 0L, bit; unsigned long bits = 0L, bit;
float d[3], *vn0, pt[3], planew, v0mod[3]; float d[3], *vn0, pt[3], v0mod[3];
if (a%1000==0){ if (a%1000==0){
PRINTFB(I->R.G, FB_RepSurface, FB_Debugging) "RepSurfaceColor(): Amb ient Occlusion computing mode=%d #vertices=%d done=%d\n", ambient_occlusion_mode , I->N, a ENDFB(I->R.G); PRINTFB(I->R.G, FB_RepSurface, FB_Debugging) "RepSurfaceColor(): Amb ient Occlusion computing mode=%d #vertices=%d done=%d\n", ambient_occlusion_mode , I->N, a ENDFB(I->R.G);
} }
v0 = I->V + 3 * a; v0 = I->V + 3 * a;
vn0 = I->VN + 3 * a; vn0 = I->VN + 3 * a;
mult3f(vn0, .01f, v0mod); mult3f(vn0, .01f, v0mod);
add3f(v0, v0mod, v0mod); add3f(v0, v0mod, v0mod);
planew = -(vn0[0] * v0mod[0] + vn0[1] * v0mod[1] + vn0[2] * v0mod[2]);
i = *(MapLocusEStart(ambient_occlusion_map, v0)); i = *(MapLocusEStart(ambient_occlusion_map, v0));
if(i && ambient_occlusion_map->EList) { if(i && ambient_occlusion_map->EList) {
j = ambient_occlusion_map->EList[i++]; j = ambient_occlusion_map->EList[i++];
maxDistA = 0.f; maxDistA = 0.f;
has = 0; has = 0;
while(j >= 0) { while(j >= 0) {
natomsL++; natomsL++;
if (vertex_map && a==j){ if (vertex_map && a==j){
j = ambient_occlusion_map->EList[i++]; j = ambient_occlusion_map->EList[i++];
continue; continue;
skipping to change at line 2849 skipping to change at line 2593
float *tmpVAO = Alloc(float, I->N); float *tmpVAO = Alloc(float, I->N);
int *nVAO = Alloc(int, I->N), c, *t; int *nVAO = Alloc(int, I->N), c, *t;
for (j=0; j<ambient_occlusion_smooth; j++){ for (j=0; j<ambient_occlusion_smooth; j++){
memset(nVAO, 0, sizeof(int)*I->N); memset(nVAO, 0, sizeof(int)*I->N);
memset(tmpVAO, 0, sizeof(float)*I->N); memset(tmpVAO, 0, sizeof(float)*I->N);
t = I->T; t = I->T;
c = I->NT; c = I->NT;
while (c--){ while (c--){
if((I->proximity if (visibility_test(I->proximity, vi, t)) {
&& ((*(vi + (*t))) || (*(vi + (*(t + 1)))) || (*(vi + (*(t + 2)
)))))
|| ((*(vi + (*t))) && (*(vi + (*(t + 1)))) && (*(vi + (*(t + 2))
)))) {
pt1 = *t; pt2 = *(t+1); pt3 = *(t+2); pt1 = *t; pt2 = *(t+1); pt3 = *(t+2);
nVAO[pt1] += 1; nVAO[pt2] += 1; nVAO[pt3] += 1; nVAO[pt1] += 1; nVAO[pt2] += 1; nVAO[pt3] += 1;
ave = ave3(I->VAO[pt1], I->VAO[pt2], I->VAO[pt3]); ave = ave3(I->VAO[pt1], I->VAO[pt2], I->VAO[pt3]);
tmpVAO[pt1] += ave; tmpVAO[pt1] += ave;
tmpVAO[pt2] += ave; tmpVAO[pt2] += ave;
tmpVAO[pt3] += ave; tmpVAO[pt3] += ave;
} }
t +=3; t +=3;
skipping to change at line 2891 skipping to change at line 2633
ambient_occlusion_map = NULL; ambient_occlusion_map = NULL;
} else { } else {
if (I->VAO){ if (I->VAO){
VLAFreeP(I->VAO); VLAFreeP(I->VAO);
I->VAO = 0; I->VAO = 0;
} }
} }
/* now, assign colors to each point */ /* now, assign colors to each point */
map = MapNewFlagged(G, cutoff, cs->Coord, cs->NIndex, NULL, present); map = MapNewFlagged(G, cutoff, cs->Coord, cs->NIndex, NULL, present);
if(map) { if(map) {
short color_smoothing = SettingGetGlobal_b(G, cSetting_pick_shading) ? short color_smoothing = SettingGetGlobal_i(G, cSetting_surface_color_smoot
0 : SettingGetGlobal_i(G, cSetting_surface_color_smoothing); hing);
float color_smoothing_threshold = SettingGetGlobal_f(G, cSetting_surface_c olor_smoothing_threshold); float color_smoothing_threshold = SettingGetGlobal_f(G, cSetting_surface_c olor_smoothing_threshold);
int atm, ok = true; int atm, ok = true;
MapSetupExpress(map); MapSetupExpress(map);
ok &= !G->Interrupt; ok &= !G->Interrupt;
if (ok && !I->AT) if (ok && !I->AT)
I->AT = VLACalloc(int, I->N); I->AT = VLACalloc(int, I->N);
for(a = 0; ok && a < I->N; a++) { for(a = 0; ok && a < I->N; a++) {
float at_transp = transp; float at_transp = transp;
AtomInfoType *ai0 = NULL; AtomInfoType *ai0 = NULL;
float minDist = MAXFLOAT, minDist2 = MAXFLOAT, distDiff = MAXFLOAT; float minDist = MAXFLOAT, minDist2 = MAXFLOAT, distDiff = MAXFLOAT;
int pi = -1, pi2 = -1, catm = -1; /* variables for color smoothing */ int pi = -1, catm = -1; /* variables for color smoothing */
AtomInfoType *pai = NULL, *pai2 = NULL; /* variables for color smoothing */ AtomInfoType *pai = NULL, *pai2 = NULL; /* variables for color smoothing */
c1 = 1; c1 = 1;
i0 = -1; i0 = -1;
v0 = I->V + 3 * a; v0 = I->V + 3 * a;
n0 = I->VN + 3 * a; n0 = I->VN + 3 * a;
vi = I->Vis + a; vi = I->Vis + a;
/* colors */ /* colors */
i = *(MapLocusEStart(map, v0)); i = *(MapLocusEStart(map, v0));
if(i && map->EList) { if(i && map->EList) {
j = map->EList[i++]; j = map->EList[i++];
while(j >= 0) { while(j >= 0) {
atm = cs->IdxToAtm[j]; atm = cs->IdxToAtm[j];
ai2 = obj->AtomInfo + atm; ai2 = obj->AtomInfo + atm;
if((inclH || (!ai2->isHydrogen())) && if((inclH || (!ai2->isHydrogen())) &&
((!cullByFlag) || (!(ai2->flags & cAtomFlag_ignore)))) { ((!cullByFlag) || (!(ai2->flags & cAtomFlag_ignore)))) {
dist = (float) diff3f(v0, cs->Coord + j * 3) - ai2->vdw; dist = (float) diff3f(v0, cs->Coord + j * 3) - ai2->vdw;
if(color_smoothing){ if(color_smoothing){
if (dist < minDist){ if (dist < minDist){
/* switching closest to 2nd closest */ /* switching closest to 2nd closest */
pi2 = pi;
pai2 = pai; pai2 = pai;
minDist2 = minDist; minDist2 = minDist;
pi = j; pi = j;
catm = atm; catm = atm;
pai = ai2; pai = ai2;
minDist = dist; minDist = dist;
} else if (dist < minDist2){ } else if (dist < minDist2){
/* just setting second closest */ /* just setting second closest */
pi2 = j;
pai2 = ai2; pai2 = ai2;
minDist2 = dist; minDist2 = dist;
} }
} else if (dist < minDist) { } else if (dist < minDist) {
i0 = j; i0 = j;
catm = atm; catm = atm;
ai0 = ai2; ai0 = ai2;
minDist = dist; minDist = dist;
} }
} }
skipping to change at line 3062 skipping to change at line 2801
v_pos = v0; v_pos = v0;
rc[0] = c1; rc[0] = c1;
ramped_flag = true; ramped_flag = true;
break; break;
} }
ColorGetRamped(G, c1, v_pos, vc, state); ColorGetRamped(G, c1, v_pos, vc, state);
vc += 3; vc += 3;
rc++; rc++;
} else { } else {
if (color_smoothing && distDiff < color_smoothing_threshold){ if (color_smoothing && distDiff < color_smoothing_threshold){
float *c2; const float *c2;
float weight, weight2; float weight, weight2;
if (color_smoothing==1){ if (color_smoothing==1){
weight = 1.f + sin(.5f * PI * (distDiff / color_smoothing_threshol d)); weight = 1.f + sin(.5f * PI * (distDiff / color_smoothing_threshol d));
} else { } else {
weight = 1.f + (distDiff / color_smoothing_threshold); weight = 1.f + (distDiff / color_smoothing_threshold);
} }
weight2 = 2.f - weight; weight2 = 2.f - weight;
c0 = ColorGet(G, c1); c0 = ColorGet(G, c1);
c2 = ColorGet(G, pai2->color); c2 = ColorGet(G, pai2->color);
*(rc++) = c1; *(rc++) = c1;
skipping to change at line 3109 skipping to change at line 2848
} }
} }
/* /*
if(surface_color>=0) { if(surface_color>=0) {
I->oneColorFlag=true; I->oneColorFlag=true;
I->oneColor=surface_color; I->oneColor=surface_color;
} }
*/ */
if(G->HaveGUI) { if(G->HaveGUI) {
if (I->shaderCGO){ setShaderCGO(I, NULL);
CGOFree(I->shaderCGO);
I->shaderCGO = NULL; #ifdef _PYMOL_IOS
} #endif
if (I->vertexIndices){
FreeP(I->vertexIndices);
I->vertexIndices = 0;
}
if (I->sum){
FreeP(I->sum);
I->sum = 0;
}
if (I->z_value){
FreeP(I->z_value);
I->z_value = 0;
}
if (I->ix){
FreeP(I->ix);
I->ix = 0;
}
I->n_tri = 0;
} }
if(I->VA && (!variable_alpha)) { if(I->VA && (!variable_alpha)) {
FreeP(I->VA); FreeP(I->VA);
I->VA = NULL; I->VA = NULL;
} }
if(carve_map) if(carve_map)
MapFree(carve_map); MapFree(carve_map);
VLAFreeP(carve_vla); VLAFreeP(carve_vla);
skipping to change at line 3292 skipping to change at line 3014
{ {
PyObject *result = PyTuple_New(6); PyObject *result = PyTuple_New(6);
if(result) { if(result) {
PyTuple_SetItem(result, 0, PyInt_FromLong(I->N)); PyTuple_SetItem(result, 0, PyInt_FromLong(I->N));
PyTuple_SetItem(result, 1, PConvFloatVLAToPyTuple(I->V)); PyTuple_SetItem(result, 1, PConvFloatVLAToPyTuple(I->V));
PyTuple_SetItem(result, 2, PConvFloatVLAToPyTuple(I->VN)); PyTuple_SetItem(result, 2, PConvFloatVLAToPyTuple(I->VN));
PyTuple_SetItem(result, 3, PyInt_FromLong(I->NT)); PyTuple_SetItem(result, 3, PyInt_FromLong(I->NT));
PyTuple_SetItem(result, 4, PConvIntVLAToPyTuple(I->T)); PyTuple_SetItem(result, 4, PConvIntVLAToPyTuple(I->T));
PyTuple_SetItem(result, 5, PConvIntVLAToPyTuple(I->S)); PyTuple_SetItem(result, 5, PConvIntVLAToPyTuple(I->S));
} }
return result; return result;
}
OV_INLINE ov_status SurfaceJobResultFromTuple(PyMOLGlobals * G,
SurfaceJob * I, PyObject *
tuple)
{
ov_status status = OV_STATUS_FAILURE;
SurfaceJobPurgeResult(G, I);
if(tuple && PyTuple_Check(tuple)) {
ov_size size = PyTuple_Size(tuple);
if(size >= 6) {
status = OV_STATUS_SUCCESS;
I->N = PyInt_AsLong(PyTuple_GetItem(tuple, 0));
if(OV_OK(status))
status = PConvPyTupleToFloatVLA(&I->V, PyTuple_GetItem(tuple, 1));
if(OV_OK(status))
status = PConvPyTupleToFloatVLA(&I->VN, PyTuple_GetItem(tuple, 2));
I->NT = PyInt_AsLong(PyTuple_GetItem(tuple, 3));
if(OV_OK(status))
status = PConvPyTupleToIntVLA(&I->T, PyTuple_GetItem(tuple, 4));
if(OV_OK(status))
status = PConvPyTupleToIntVLA(&I->S, PyTuple_GetItem(tuple, 5));
}
if(OV_ERR(status))
SurfaceJobPurgeResult(G, I);
}
return status;
}
#endif
static SurfaceJob *SurfaceJobNew(PyMOLGlobals * G)
{
OOCalloc(G, SurfaceJob);
return I;
}
static void SurfaceJobFree(PyMOLGlobals * G, SurfaceJob * I)
{
SurfaceJobPurgeResult(G, I);
VLAFreeP(I->coord);
VLAFreeP(I->presentVla);
VLAFreeP(I->atomInfo);
VLAFreeP(I->carveVla);
OOFreeP(I);
}
static int SurfaceJobEliminateCloseDotsType3orMore(PyMOLGlobals * G,
SurfaceJob * I, int *repeat_flag, int *dot_flag)
{
int ok = true;
int jj;
float dist;
float nearest;
float point_sep = I->pointSep;
float min_sep2 = point_sep * point_sep;
float diff[3];
{
int a;
for(a = 0; a < I->N; a++)
dot_flag[a] = 1;
}
{
MapType *map = MapNew(G, point_sep + 0.05F, I->V, I->N, NULL);
int a;
float *v = I->V;
float *vn = I->VN;
float min_dot = 0.1F;
CHECKOK(ok, map);
if (ok)
ok &= MapSetupExpress(map);
for(a = 0; ok && a < I->N; a++) {
if(dot_flag[a]) {
int i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
jj = I->N;
nearest = point_sep + 1.0F;
while(j >= 0) {
if(j > a) {
if(dot_flag[j]) {
if(dot_product3f(I->VN + (3 * j), vn) > min_dot) {
if(within3fret
(I->V + (3 * j), v, point_sep, min_sep2, diff, &dist)) {
*repeat_flag = true;
if(dist < nearest) {
/* try to be as determinstic as possible
in terms of how we collapse points */
jj = j;
nearest = dist;
} else if((j < jj) && (fabs(dist - nearest) < R_SMALL4)) {
jj = j;
nearest = dist;
}
}
}
}
}
j = map->EList[i++];
}
if(jj < I->N) {
dot_flag[jj] = 0;
add3f(vn, I->VN + (3 * jj), vn);
average3f(I->V + (3 * jj), v, v);
*repeat_flag = true;
}
}
}
v += 3;
vn += 3;
ok &= !G->Interrupt;
}
MapFree(map);
}
return ok;
}
static int SurfaceJobEliminateCloseDotsTypeLessThan3(PyMOLGlobals * G,
SurfaceJob * I, int *repeat_flag, int *dot_flag)
{
int ok = true;
int a;
float point_sep = I->pointSep;
MapType *map = MapNew(G, -point_sep, I->V, I->N, NULL);
float *v = I->V;
float *vn = I->VN;
CHECKOK(ok, map);
if (ok){
for(a = 0; a < I->N; a++)
dot_flag[a] = 1;
ok &= MapSetupExpress(map);
}
for(a = 0; ok && a < I->N; a++) {
if(dot_flag[a]) {
int i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
while(j >= 0) {
if(j != a) {
if(dot_flag[j]) {
if(within3f(I->V + (3 * j), v, point_sep)) {
dot_flag[j] = 0;
add3f(vn, I->VN + (3 * j), vn);
average3f(I->V + (3 * j), v, v);
*repeat_flag = true;
}
}
}
j = map->EList[i++];
}
}
}
v += 3;
vn += 3;
ok &= !G->Interrupt;
}
MapFree(map);
return ok;
}
static void SurfaceJobEliminateFromVArrays(PyMOLGlobals * G, SurfaceJob * I,
int *dot_flag, short normalize)
{
float *v0 = I->V;
float *vn0 = I->VN;
int *p = dot_flag;
int c = I->N;
int a;
float *v = I->V;
float *vn = I->VN;
I->N = 0;
for(a = 0; a < c; a++) {
if(*(p++)) {
*(v0++) = *(v++);
*(v0++) = *(v++);
*(v0++) = *(v++);
if (normalize)
normalize3f(vn);
*(vn0++) = *(vn++);
*(vn0++) = *(vn++);
*(vn0++) = *(vn++);
I->N++;
} else {
v += 3;
vn += 3;
}
}
}
static int SurfaceJobEliminateCloseDots(PyMOLGlobals * G, SurfaceJob * I){
int ok = true;
if(I->N) {
int repeat_flag = true;
int *dot_flag = Alloc(int, I->N);
CHECKOK(ok, dot_flag);
while(ok && repeat_flag) {
repeat_flag = false;
if(I->surfaceType >= 3) {
ok = SurfaceJobEliminateCloseDotsType3orMore(G, I, &repeat_flag, dot_flag
);
} else { /* surface types < 3 */
ok = SurfaceJobEliminateCloseDotsTypeLessThan3(G, I, &repeat_flag, dot_fl
ag);
}
if(ok) {
SurfaceJobEliminateFromVArrays(G, I, dot_flag, true);
}
ok &= !G->Interrupt;
}
FreeP(dot_flag);
}
return ok;
}
/* For each vertex, lookup all vertices within the neighborhood, and sum the dot
_product of the normals.
If the average of the dot_products of the normals is less than the trim_cutof
f,
then the middle vertex is eliminated. */
static int SurfaceJobEliminateTroublesomeVerticesMark(PyMOLGlobals * G,
SurfaceJob * I, int *repeat_flag, MapType *map, int *dot_flag,
float neighborhood, float trim_cutoff)
{
int ok = true;
int a;
float *v = I->V;
float *vn = I->VN;
for(a = 0; ok && a < I->N; a++) {
if(dot_flag[a]) {
int i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
int n_nbr = 0;
float dot_sum = 0.0F;
while(j >= 0) {
if(j != a) {
if(dot_flag[j]) {
float *v0 = I->V + 3 * j;
if(within3f(v0, v, neighborhood)) {
float *n0 = I->VN + 3 * j;
dot_sum += dot_product3f(n0, vn);
n_nbr++;
}
}
}
j = map->EList[i++];
}
if(n_nbr) {
dot_sum /= n_nbr;
if(dot_sum < trim_cutoff) {
dot_flag[a] = false;
*repeat_flag = true;
}
}
}
}
v += 3;
vn += 3;
ok &= !G->Interrupt;
}
return ok;
}
static int SurfaceJobEliminateTroublesomeVertices(PyMOLGlobals * G, SurfaceJob *
I){
int ok = true;
if((I->surfaceType != 3) &&
I->N && (I->trimCutoff > 0.0F) && (I->trimFactor > 0.0F)) {
float trim_cutoff = I->trimCutoff;
float trim_factor = I->trimFactor;
int repeat_flag = true;
float point_sep = I->pointSep;
float neighborhood = trim_factor * point_sep;
int *dot_flag = Alloc(int, I->N);
CHECKOK(ok, dot_flag);
if(ok && I->surfaceType == 6) { /* emprical tweaks */
trim_factor *= 2.5;
trim_cutoff *= 1.5;
}
while(ok && repeat_flag) {
MapType *map = MapNew(G, neighborhood, I->V, I->N, NULL);
CHECKOK(ok, map);
if (ok){
int a;
for(a = 0; a < I->N; a++)
dot_flag[a] = 1;
ok &= MapSetupExpress(map);
}
repeat_flag = false;
ok &= SurfaceJobEliminateTroublesomeVerticesMark(G, I, &repeat_flag, map,
dot_flag, neighborhood, trim_cutoff);
if(ok) {
SurfaceJobEliminateFromVArrays(G, I, dot_flag, true);
}
MapFree(map);
ok &= !G->Interrupt;
}
FreeP(dot_flag);
}
return ok;
}
static int SurfaceJobAtomProximityCleanupPass(PyMOLGlobals * G, SurfaceJob * I,
int *dot_flag, int *present_vla, float probe_radius)
{
int ok = true;
float cutoff = 0.5 * probe_radius;
float *I_coord = I->coord;
SurfaceJobAtomInfo *I_atom_info = I->atomInfo;
int n_index = VLAGetSize(I->atomInfo);
MapType *map =
MapNewFlagged(G, I->maxVdw + probe_radius, I_coord, n_index, NULL,
present_vla);
int a;
float *v;
CHECKOK(ok, map);
if (ok)
ok &= MapSetupExpress(map);
v = I->V;
for(a = 0; ok && a < I->N; a++) {
int i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
while(j >= 0) {
SurfaceJobAtomInfo *atom_info = I_atom_info + j;
if((!present_vla) || present_vla[j]) {
if(within3f(I_coord + 3 * j, v, atom_info->vdw + cutoff)) {
dot_flag[a] = true;
}
}
j = map->EList[i++];
}
}
v += 3;
ok &= !G->Interrupt;
}
MapFree(map);
return ok;
}
static int SurfaceJobRefineCopyNewPoints(SurfaceJob * I, float *new_dot, int n_n
ew){
int ok = true;
float *n1 = new_dot + 3;
float *v1 = new_dot;
float *v, *vn;
VLASize(I->V, float, 3 * (I->N + n_new));
CHECKOK(ok, I->V);
if (ok)
VLASize(I->VN, float, 3 * (I->N + n_new));
CHECKOK(ok, I->VN);
if (ok){
v = I->V + 3 * I->N;
vn = I->VN + 3 * I->N;
I->N += n_new;
}
while(ok && n_new--) {
copy3f(v1, v);
copy3f(n1, vn);
v += 3;
vn += 3;
v1 += 6;
n1 += 6;
}
return ok;
}
static int SurfaceJobRefineAddNewVerticesCheckPoint(SurfaceJob * I, MapType *map
,
int *n_new, float **new_dot, int j, float *v, float *vn, float map_cutoff,
float neighborhood, float insert_cutoff)
{
int ok = true;
float *v0 = I->V + 3 * j;
if(within3f(v0, v, map_cutoff)) {
int add_new = false;
float *n0 = I->VN + 3 * j;
VLACheck(*new_dot, float, (*n_new) * 6 + 5);
CHECKOK(ok, *new_dot);
if (ok){
float *v1 = (*new_dot) + (*n_new) * 6;
average3f(v, v0, v1);
if((dot_product3f(n0, vn) < 0.666 /* dot_cutoff, was hardcoded as a variab
le */ )
&& (within3f(v0, v, neighborhood))){
// if the normals are further than dot_cutoff apart
// and the related points are close to each other, than add new
add_new = true;
} else {
/* if points are too far apart, insert a new one, i.e.,
search for any point within insert_cutoff, if not, add */
int ii = *(MapLocusEStart(map, v1));
if(ii) {
int found = false;
int jj = map->EList[ii++];
while(jj >= 0) {
if(jj != j) {
float *vv0 = I->V + 3 * jj;
if(within3f(vv0, v1, insert_cutoff)) {
found = true;
break;
}
}
jj = map->EList[ii++];
}
if(!found)
add_new = true;
}
}
if(add_new) {
/* highly divergent, add dot in-between v and v0
(averaged, v1 set above, compute the normal (averaged below))
and n_new incremented */
float *n1 = v1 + 3;
(*n_new)++;
average3f(vn, n0, n1);
normalize3f(n1);
}
}
}
return ok;
}
static int SurfaceJobRefineAddNewVertices(PyMOLGlobals * G, SurfaceJob * I){
int ok = true;
float point_sep = I->pointSep;
int n_new = 0;
float neighborhood = 2.6 * point_sep; /* these constants need more tuning... *
/
float insert_cutoff = 1.1 * point_sep;
float map_cutoff = neighborhood;
float *new_dot = VLAlloc(float, 1000);
float *v, *vn;
if(map_cutoff < (2.9 * point_sep)) { /* these constants need more tuning... *
/
map_cutoff = 2.9 * point_sep;
}
{
MapType *map = NULL;
int a;
map = MapNew(G, map_cutoff, I->V, I->N, NULL);
CHECKOK(ok, map);
if (ok)
ok &= MapSetupExpress(map);
v = I->V;
vn = I->VN;
for(a = 0; ok && a < I->N; a++) {
int i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
while(ok && j >= 0) {
if(j > a) {
SurfaceJobRefineAddNewVerticesCheckPoint(I, map, &n_new, &new_dot, j,
v, vn, map_cutoff, neighborhood, insert_cutoff);
}
j = map->EList[i++];
ok &= !G->Interrupt;
}
}
v += 3;
vn += 3;
ok &= !G->Interrupt;
}
MapFree(map);
}
if(ok && n_new) {
ok = SurfaceJobRefineCopyNewPoints(I, new_dot, n_new);
}
VLAFreeP(new_dot);
return ok;
}
static void SurfaceJobCheckInteriorSolventSurface(MapType *solv_map, float *v,
SolventDot *sol_dot, float probe_rad_less, float dist2, int a, int *flag){
int ii;
ii = *(MapLocusEStart(solv_map, v));
if(ii && solv_map->EList) {
float *i_dot = sol_dot->dot;
float dist = probe_rad_less;
int *elist_ii = solv_map->EList + ii;
float v_0 = v[0];
int jj_next, jj = *(elist_ii++);
float v_1 = v[1];
float *v1 = i_dot + 3 * jj;
float v_2 = v[2];
while(jj >= 0) {
/* huge bottleneck -- optimized for superscaler processors */
float dx = v1[0], dy, dz;
jj_next = *(elist_ii++);
dx -= v_0;
if(jj != a) {
dx = (dx < 0.0F) ? -dx : dx;
dy = v1[1] - v_1;
if(!(dx > dist)) {
dy = (dy < 0.0F) ? -dy : dy;
dz = v1[2] - v_2;
if(!(dy > dist)) {
dx = dx * dx;
dz = (dz < 0.0F) ? -dz : dz;
dy = dy * dy;
if(!(dz > dist)) {
dx = dx + dy;
dz = dz * dz;
if(!(dx > dist2))
if((dx + dz) <= dist2) {
*flag = false;
break;
}
}
}
}
}
v1 = i_dot + 3 * jj_next;
jj = jj_next;
}
}
} }
OV_INLINE ov_status SurfaceJobResultFromTuple(PyMOLGlobals * G, static void SurfaceJobCheckPresentAndWithin(MapType *map, SurfaceJob * I,
SurfaceJob * I, PyObject * int *present_vla, float *v, float probe_rad_more, int *flag){
tuple) SurfaceJobAtomInfo *I_atom_info = I->atomInfo;
{ float *I_coord = I->coord;
ov_status status = OV_STATUS_FAILURE;
SurfaceJobPurgeResult(G, I); int i = *(MapLocusEStart(map, v));
if(tuple && PyTuple_Check(tuple)) { if(i && map->EList) {
ov_size size = PyTuple_Size(tuple); int j = map->EList[i++];
if(size >= 6) { while(j >= 0) {
status = OV_STATUS_SUCCESS; SurfaceJobAtomInfo *atom_info = I_atom_info + j;
if((!present_vla) || present_vla[j]) {
I->N = PyInt_AsLong(PyTuple_GetItem(tuple, 0)); if(within3f
if(OV_OK(status)) (I_coord + 3 * j, v,
status = PConvPyTupleToFloatVLA(&I->V, PyTuple_GetItem(tuple, 1)); atom_info->vdw + probe_rad_more)) {
if(OV_OK(status)) *flag = false;
status = PConvPyTupleToFloatVLA(&I->VN, PyTuple_GetItem(tuple, 2)); break;
I->NT = PyInt_AsLong(PyTuple_GetItem(tuple, 3)); }
if(OV_OK(status)) }
status = PConvPyTupleToIntVLA(&I->T, PyTuple_GetItem(tuple, 4)); j = map->EList[i++];
if(OV_OK(status))
status = PConvPyTupleToIntVLA(&I->S, PyTuple_GetItem(tuple, 5));
} }
if(OV_ERR(status))
SurfaceJobPurgeResult(G, I);
} }
return status;
} }
#endif
static SurfaceJob *SurfaceJobNew(PyMOLGlobals * G) static void SurfaceJobSetProbeRadius(int surface_type, float point_sep,
float *probe_radius, float *probe_rad_more, float *probe_rad_less,
float *probe_rad_less2)
{ {
OOCalloc(G, SurfaceJob); float solv_tole = point_sep * 0.04F;
return I;
}
static void SurfaceJobFree(PyMOLGlobals * G, SurfaceJob * I) if(*probe_radius < (2.5F * point_sep)) { /* minimum probe radius allowed */
{ *probe_radius = 2.5F * point_sep;
SurfaceJobPurgeResult(G, I); }
VLAFreeP(I->coord); *probe_rad_more = *probe_radius * (1.0F + solv_tole);
VLAFreeP(I->presentVla); switch (surface_type) {
VLAFreeP(I->atomInfo); case 0: /* solid */
VLAFreeP(I->carveVla); case 3:
OOFreeP(I); case 4:
case 5:
case 6:
*probe_rad_less = *probe_radius;
break;
default:
*probe_rad_less = *probe_radius * (1.0F - solv_tole);
break;
}
*probe_rad_less2 = (*probe_rad_less) * (*probe_rad_less);
} }
static int SurfaceJobRun(PyMOLGlobals * G, SurfaceJob * I) static int SurfaceJobRun(PyMOLGlobals * G, SurfaceJob * I)
{ {
int ok = true; int ok = true;
int MaxN; int MaxN;
int n_index = VLAGetSize(I->atomInfo);
int n_present = I->nPresent; int n_present = I->nPresent;
SphereRec *sp = G->Sphere->Sphere[I->sphereIndex]; SphereRec *sp = G->Sphere->Sphere[I->sphereIndex];
SphereRec *ssp = G->Sphere->Sphere[I->solventSphereIndex]; SphereRec *ssp = G->Sphere->Sphere[I->solventSphereIndex];
SurfaceJobPurgeResult(G, I); SurfaceJobPurgeResult(G, I);
{ {
/* compute limiting storage requirements */ /* compute limiting storage requirements */
int tmp = n_present; int tmp = n_present;
if(tmp < 1) if(tmp < 1)
tmp = 1; tmp = 1;
if(sp->nDot < ssp->nDot) if(sp->nDot < ssp->nDot)
MaxN = tmp * ssp->nDot; MaxN = tmp * ssp->nDot;
else else
MaxN = tmp * sp->nDot; MaxN = tmp * sp->nDot;
} }
MaxN = n_present;
I->V = VLAlloc(float, (MaxN + 1) * 3); I->V = VLAlloc(float, (MaxN + 1) * 3);
CHECKOK(ok, I->V); CHECKOK(ok, I->V);
if (ok) if (ok)
I->VN = VLAlloc(float, (MaxN + 1) * 3); I->VN = VLAlloc(float, (MaxN + 1) * 3);
CHECKOK(ok, I->VN); CHECKOK(ok, I->VN);
ok &= !G->Interrupt; ok &= !G->Interrupt;
if(!(I->V && I->VN) || (!ok)) { /* bail out point -- try to reduce crash es */ if(!(I->V && I->VN) || (!ok)) { /* bail out point -- try to reduce crash es */
PRINTFB(G, FB_RepSurface, FB_Errors) PRINTFB(G, FB_RepSurface, FB_Errors)
skipping to change at line 3387 skipping to change at line 3615
ok = false; ok = false;
} else { } else {
SolventDot *sol_dot = NULL; SolventDot *sol_dot = NULL;
float *v = I->V; float *v = I->V;
float *vn = I->VN; float *vn = I->VN;
MapType *carve_map = NULL; MapType *carve_map = NULL;
float probe_radius = I->probeRadius; float probe_radius = I->probeRadius;
int circumscribe = I->circumscribe; int circumscribe = I->circumscribe;
int surface_type = I->surfaceType; int surface_type = I->surfaceType;
float point_sep = I->pointSep; float point_sep = I->pointSep;
float *I_coord = I->coord;
int *present_vla = I->presentVla; int *present_vla = I->presentVla;
SurfaceJobAtomInfo *I_atom_info = I->atomInfo;
I->N = 0; I->N = 0;
sol_dot = SolventDotNew(G, I->coord, I->atomInfo, probe_radius, sol_dot = SolventDotNew(G, I->coord, I->atomInfo, probe_radius,
ssp, present_vla, ssp, present_vla,
circumscribe, I->surfaceMode, I->surfaceSolvent, circumscribe, I->surfaceMode, I->surfaceSolvent,
I->cavityCull, I->allVisibleFlag, I->maxVdw, I->cavityCull, I->allVisibleFlag, I->maxVdw,
I->cavityMode, I->cavityRadius, I->cavityCutoff); I->cavityMode, I->cavityRadius, I->cavityCutoff);
CHECKOK(ok, sol_dot); CHECKOK(ok, sol_dot);
ok &= !G->Interrupt; ok &= !G->Interrupt;
if(ok && sol_dot) { if(ok) {
if(!I->surfaceSolvent) { if(!I->surfaceSolvent) {
float probe_rad_more, probe_rad_less, probe_rad_less2;
float solv_tole = point_sep * 0.04F; SurfaceJobSetProbeRadius(surface_type, point_sep, &probe_radius, &probe_r
float probe_rad_more; ad_more, &probe_rad_less, &probe_rad_less2);
float probe_rad_less;
float probe_rad_less2;
if(probe_radius < (2.5F * point_sep)) { /* minimum probe radius allowed
*/
probe_radius = 2.5F * point_sep;
}
probe_rad_more = probe_radius * (1.0F + solv_tole);
switch (surface_type) {
case 0: /* solid */
case 3:
case 4:
case 5:
case 6:
probe_rad_less = probe_radius;
break;
default:
probe_rad_less = probe_radius * (1.0F - solv_tole);
break;
}
probe_rad_less2 = probe_rad_less * probe_rad_less;
if(surface_type >= 5) { /* effectively double-weights atom points */ if(surface_type >= 5) { /* effectively double-weights atom points */
if(sol_dot->nDot) { if(sol_dot->nDot) {
int a; int a;
float *v0 = sol_dot->dot; float *v0 = sol_dot->dot;
float *n0 = sol_dot->dotNormal; float *n0 = sol_dot->dotNormal;
for(a = 0; a < sol_dot->nDot; a++) { for(a = 0; a < sol_dot->nDot; a++) {
scale3f(n0, -probe_radius, v); scale3f(n0, -probe_radius, v);
add3f(v0, v, v); add3f(v0, v, v);
copy3f(n0, vn); copy3f(n0, vn);
skipping to change at line 3461 skipping to change at line 3665
if (ok) if (ok)
solv_map = MapNew(G, probe_rad_less, sol_dot->dot, sol_dot->nDot, NUL L); solv_map = MapNew(G, probe_rad_less, sol_dot->dot, sol_dot->nDot, NUL L);
CHECKOK(ok, solv_map); CHECKOK(ok, solv_map);
if(ok) { if(ok) {
ok &= MapSetupExpress(solv_map); ok &= MapSetupExpress(solv_map);
if (ok) if (ok)
ok &= MapSetupExpress(map); ok &= MapSetupExpress(map);
ok &= !G->Interrupt; ok &= !G->Interrupt;
ok &= map->EList && solv_map->EList; ok &= map->EList && solv_map->EList;
if(sol_dot->nDot && ok) { if(sol_dot->nDot && ok) {
int *dc = sol_dot->dotCode;
Vector3f *dot = Alloc(Vector3f, sp->nDot); Vector3f *dot = Alloc(Vector3f, sp->nDot);
float *v0, *n0; float *v0, *n0;
CHECKOK(ok, dot); CHECKOK(ok, dot);
if (ok){ if (ok){
int b; int b;
for(b = 0; b < sp->nDot; b++) { for(b = 0; b < sp->nDot; b++) {
scale3f(sp->dot[b], probe_radius, dot[b]); scale3f(sp->dot[b], probe_radius, dot[b]);
} }
} }
v0 = sol_dot->dot; v0 = sol_dot->dot;
n0 = sol_dot->dotNormal; n0 = sol_dot->dotNormal;
if (ok) { if (ok) {
int a, b; int a, b;
float dist2 = probe_rad_less2;
int sp_nDot = sp->nDot; int sp_nDot = sp->nDot;
for(a = 0; ok && a < sol_dot->nDot; a++) { for(a = 0; ok && a < sol_dot->nDot; a++) {
if(dc[a] || (surface_type < 6)) { /* surface type 6 is com pletely scribed */ if(sol_dot->dotCode[a] || (surface_type < 6)) { /* surface type 6 is completely scribed */
OrthoBusyFast(G, a + sol_dot->nDot * 2, sol_dot->nDot * 5); /* 2/5 to 3/5 */ OrthoBusyFast(G, a + sol_dot->nDot * 2, sol_dot->nDot * 5); /* 2/5 to 3/5 */
for(b = 0; ok && b < sp_nDot; b++) { for(b = 0; ok && b < sp_nDot; b++) {
float *dot_b = dot[b]; float *dot_b = dot[b];
v[0] = v0[0] + dot_b[0]; v[0] = v0[0] + dot_b[0];
v[1] = v0[1] + dot_b[1]; v[1] = v0[1] + dot_b[1];
v[2] = v0[2] + dot_b[2]; v[2] = v0[2] + dot_b[2];
{ {
int flag = true; int flag = true;
int ii; SurfaceJobCheckInteriorSolventSurface(solv_map, v, sol_do
ii = *(MapLocusEStart(solv_map, v)); t, probe_rad_less, probe_rad_less2, a, &flag);
if(ii && solv_map->EList) {
float *i_dot = sol_dot->dot;
float dist = probe_rad_less;
int *elist_ii = solv_map->EList + ii;
float v_0 = v[0];
int jj_next, jj = *(elist_ii++);
float v_1 = v[1];
float *v1 = i_dot + 3 * jj;
float v_2 = v[2];
while(jj >= 0) {
/* huge bottleneck -- optimized for superscaler proc
essors */
float dx = v1[0], dy, dz;
jj_next = *(elist_ii++);
dx -= v_0;
if(jj != a) {
dx = (dx < 0.0F) ? -dx : dx;
dy = v1[1] - v_1;
if(!(dx > dist)) {
dy = (dy < 0.0F) ? -dy : dy;
dz = v1[2] - v_2;
if(!(dy > dist)) {
dx = dx * dx;
dz = (dz < 0.0F) ? -dz : dz;
dy = dy * dy;
if(!(dz > dist)) {
dx = dx + dy;
dz = dz * dz;
if(!(dx > dist2))
if((dx + dz) <= dist2) {
flag = false;
break;
}
}
}
}
}
v1 = i_dot + 3 * jj_next;
jj = jj_next;
}
}
/* at this point, we have points on the interior of the solvent surface, /* at this point, we have points on the interior of the solvent surface,
so now we need to further trim that surface to cover atoms that are present */ so now we need to further trim that surface to cover atoms that are present */
if(flag) { if(flag) {
int i = *(MapLocusEStart(map, v)); SurfaceJobCheckPresentAndWithin(map, I, present_vla, v,
if(i && map->EList) { probe_rad_more, &flag);
int j = map->EList[i++];
while(j >= 0) {
SurfaceJobAtomInfo *atom_info = I_atom_info + j;
if((!present_vla) || present_vla[j]) {
if(within3f
(I_coord + 3 * j, v,
atom_info->vdw + probe_rad_more)) {
flag = false;
break;
}
}
j = map->EList[i++];
}
}
if(!flag) { /* compute the normals */ if(!flag) { /* compute the normals */
vn[0] = -sp->dot[b][0]; vn[0] = -sp->dot[b][0];
vn[1] = -sp->dot[b][1]; vn[1] = -sp->dot[b][1];
vn[2] = -sp->dot[b][2]; vn[2] = -sp->dot[b][2];
if(I->N < MaxN) {
I->N++; I->N++;
v += 3; VLACheck(I->V, float, 3 * (I->N + 1));
vn += 3; VLACheck(I->VN, float, 3 * (I->N + 1));
} else {
int v_offset = v - I->V;
int vn_offset = vn - I->VN;
MaxN = MaxN * 2;
VLASize(I->V, float, (MaxN + 1) * 3);
CHECKOK(ok, I->V); CHECKOK(ok, I->V);
if (ok)
VLASize(I->VN, float, (MaxN + 1) * 3);
CHECKOK(ok, I->VN); CHECKOK(ok, I->VN);
if (ok){ v = I->V + I->N * 3;
v = I->V + v_offset; vn = I->VN + I->N * 3;
vn = I->VN + vn_offset;
}
}
} }
} }
} }
ok &= !G->Interrupt; ok &= !G->Interrupt;
} }
} }
v0 += 3; v0 += 3;
n0 += 3; n0 += 3;
ok &= !G->Interrupt; ok &= !G->Interrupt;
} }
skipping to change at line 3595 skipping to change at line 3728
} }
MapFree(solv_map); MapFree(solv_map);
MapFree(map); MapFree(map);
} }
} else { } else {
float *v0 = sol_dot->dot; float *v0 = sol_dot->dot;
float *n0 = sol_dot->dotNormal; float *n0 = sol_dot->dotNormal;
int a; int a;
circumscribe = 0; circumscribe = 0;
if(sol_dot->nDot) { if(sol_dot->nDot) {
VLACheck(I->V, float, 3 * (I->N + sol_dot->nDot));
VLACheck(I->VN, float, 3 * (I->N + sol_dot->nDot));
v = I->V;
vn = I->VN;
for(a = 0; a < sol_dot->nDot; a++) { for(a = 0; a < sol_dot->nDot; a++) {
*(v++) = *(v0++); *(v++) = *(v0++);
*(vn++) = *(n0++); *(vn++) = *(n0++);
*(v++) = *(v0++); *(v++) = *(v0++);
*(vn++) = *(n0++); *(vn++) = *(n0++);
*(v++) = *(v0++); *(v++) = *(v0++);
*(vn++) = *(n0++); *(vn++) = *(n0++);
I->N++; I->N++;
} }
} }
skipping to change at line 3616 skipping to change at line 3753
} }
SolventDotFree(sol_dot); SolventDotFree(sol_dot);
sol_dot = NULL; sol_dot = NULL;
ok &= !G->Interrupt; ok &= !G->Interrupt;
if(ok) { if(ok) {
int refine, ref_count = 1; int refine, ref_count = 1;
if((surface_type == 0) && (circumscribe)) { if((surface_type == 0) && (circumscribe)) {
ref_count = 2; /* these constants need more tuning... */ ref_count = 2; /* these constants need more tuning... */
} }
for(refine = 0; ok && refine < ref_count; refine++) { for(refine = 0; ok && refine < ref_count; refine++) {
/* add new vertices in regions where curvature is very high /* add new vertices in regions where curvature is very high
or where there are gaps with no points */ or where there are gaps with no points */
if(I->N && (surface_type == 0) && (circumscribe)) { if(I->N && (surface_type == 0) && (circumscribe)) {
int n_new = 0; ok = SurfaceJobRefineAddNewVertices(G, I);
float neighborhood = 2.6 * point_sep; /* these constants need more tun
ing... */
float dot_cutoff = 0.666;
float insert_cutoff = 1.1 * point_sep;
float map_cutoff = neighborhood;
float *new_dot = VLAlloc(float, 1000);
if(map_cutoff < (2.9 * point_sep)) { /* these constants need more tun
ing... */
map_cutoff = 2.9 * point_sep;
}
{
MapType *map = NULL;
int a;
map = MapNew(G, map_cutoff, I->V, I->N, NULL);
CHECKOK(ok, map);
if (ok)
ok &= MapSetupExpress(map);
v = I->V;
vn = I->VN;
for(a = 0; ok && a < I->N; a++) {
int i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
while(ok && j >= 0) {
if(j > a) {
float *v0 = I->V + 3 * j;
if(within3f(v0, v, map_cutoff)) {
int add_new = false;
float *n0 = I->VN + 3 * j;
VLACheck(new_dot, float, n_new * 6 + 5);
CHECKOK(ok, new_dot);
if (ok){
float *v1 = new_dot + n_new * 6;
average3f(v, v0, v1);
if((dot_product3f(n0, vn) < dot_cutoff)
&& (within3f(v0, v, neighborhood)))
add_new = true;
else {
/* if points are too far apart, insert a new one */
int ii = *(MapLocusEStart(map, v1));
if(ii) {
int found = false;
int jj = map->EList[ii++];
while(jj >= 0) {
if(jj != j) {
float *vv0 = I->V + 3 * jj;
if(within3f(vv0, v1, insert_cutoff)) {
found = true;
break;
}
}
jj = map->EList[ii++];
}
if(!found)
add_new = true;
}
}
if(add_new) {
/* highly divergent */
float *n1 = v1 + 3;
n_new++;
average3f(vn, n0, n1);
normalize3f(n1);
}
}
}
}
j = map->EList[i++];
ok &= !G->Interrupt;
}
}
v += 3;
vn += 3;
ok &= !G->Interrupt;
}
MapFree(map);
}
if(ok && n_new) {
float *n1 = new_dot + 3;
float *v1 = new_dot;
VLASize(I->V, float, 3 * (I->N + n_new));
CHECKOK(ok, I->V);
if (ok)
VLASize(I->VN, float, 3 * (I->N + n_new));
CHECKOK(ok, I->VN);
if (ok){
v = I->V + 3 * I->N;
vn = I->VN + 3 * I->N;
I->N += n_new;
}
while(ok && n_new--) {
copy3f(v1, v);
copy3f(n1, vn);
v += 3;
vn += 3;
v1 += 6;
n1 += 6;
}
}
VLAFreeP(new_dot);
} }
if(ok && I->N && (surface_type == 0) && (circumscribe)) { if(ok && I->N && (surface_type == 0) && (circumscribe)) {
float cutoff = 0.5 * probe_radius;
/* combine scribing with an atom proximity cleanup pass */ /* combine scribing with an atom proximity cleanup pass */
int *dot_flag = Calloc(int, I->N); int *dot_flag = Calloc(int, I->N);
MapType *map = CHECKOK(ok, dot_flag);
MapNewFlagged(G, I->maxVdw + probe_radius, I_coord, n_index, NULL, ok &= SurfaceJobAtomProximityCleanupPass(G, I, dot_flag, present_vla, p
present_vla); robe_radius);
int a; /* purge unused dots */
CHECKOK(ok, map); if (ok)
if (ok) SurfaceJobEliminateFromVArrays(G, I, dot_flag, false); // not normali
ok &= MapSetupExpress(map); ze?
v = I->V;
for(a = 0; ok && a < I->N; a++) {
int i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
while(j >= 0) {
SurfaceJobAtomInfo *atom_info = I_atom_info + j;
if((!present_vla) || present_vla[j]) {
if(within3f(I_coord + 3 * j, v, atom_info->vdw + cutoff)) {
dot_flag[a] = true;
}
}
j = map->EList[i++];
}
}
v += 3;
ok &= !G->Interrupt;
}
MapFree(map);
map = NULL;
if(ok) {
/* purge unused dots */
float *v0 = I->V;
float *vn0 = I->VN;
int *p = dot_flag;
int c = I->N;
int a;
v = I->V;
vn = I->VN;
I->N = 0;
for(a = 0; a < c; a++) {
if(*(p++)) {
*(v0++) = *(v++);
*(v0++) = *(v++);
*(v0++) = *(v++);
*(vn0++) = *(vn++);
*(vn0++) = *(vn++);
*(vn0++) = *(vn++);
I->N++;
} else {
v += 3;
vn += 3;
}
}
}
FreeP(dot_flag); FreeP(dot_flag);
} }
/* now, eliminate dots that are too close to each other */ /* now, eliminate dots that are too close to each other */
ok &= SurfaceJobEliminateCloseDots(G, I);
/* CGOColor(I->debug,0.0,1.0,0.0);
CGOBegin(I->debug,GL_POINTS);
for(a=0;a<I->N;a++)
CGOVertexv(I->debug,I->V+3*a);
CGOEnd(I->debug);
*/
if(ok && I->N) {
int repeat_flag = true;
float min_dot = 0.1F;
int *dot_flag = Alloc(int, I->N);
CHECKOK(ok, dot_flag);
while(ok && repeat_flag) {
repeat_flag = false;
if(surface_type >= 3) {
int jj;
float dist;
float nearest;
float min_sep2 = point_sep * point_sep;
float diff[3];
{
int a;
for(a = 0; a < I->N; a++)
dot_flag[a] = 1;
}
{
MapType *map = MapNew(G, point_sep + 0.05F, I->V, I->N, NULL);
int a;
CHECKOK(ok, map);
if (ok)
ok &= MapSetupExpress(map);
v = I->V;
vn = I->VN;
for(a = 0; ok && a < I->N; a++) {
if(dot_flag[a]) {
int i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
jj = I->N;
nearest = point_sep + 1.0F;
while(j >= 0) {
if(j > a) {
if(dot_flag[j]) {
if(dot_product3f(I->VN + (3 * j), vn) > min_dot) {
if(within3fret
(I->V + (3 * j), v, point_sep, min_sep2, diff,
&dist)) {
repeat_flag = true;
if(dist < nearest) {
/* try to be as determinstic as possible
in terms of how we collapse points */
jj = j;
nearest = dist;
} else if((j < jj) && (fabs(dist - nearest) < R_
SMALL4)) {
jj = j;
nearest = dist;
}
}
}
}
}
j = map->EList[i++];
}
if(jj < I->N) {
dot_flag[jj] = 0;
add3f(vn, I->VN + (3 * jj), vn);
average3f(I->V + (3 * jj), v, v);
repeat_flag = true;
}
}
}
v += 3;
vn += 3;
ok &= !G->Interrupt;
}
MapFree(map);
}
} else { /* surface types < 3 */
int a;
MapType *map = MapNew(G, -point_sep, I->V, I->N, NULL);
CHECKOK(ok, map);
if (ok){
for(a = 0; a < I->N; a++)
dot_flag[a] = 1;
ok &= MapSetupExpress(map);
}
v = I->V;
vn = I->VN;
for(a = 0; ok && a < I->N; a++) {
if(dot_flag[a]) {
int i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
while(j >= 0) {
if(j != a) {
if(dot_flag[j]) {
if(within3f(I->V + (3 * j), v, point_sep)) {
dot_flag[j] = 0;
add3f(vn, I->VN + (3 * j), vn);
average3f(I->V + (3 * j), v, v);
repeat_flag = true;
}
}
}
j = map->EList[i++];
}
}
}
v += 3;
vn += 3;
ok &= !G->Interrupt;
}
MapFree(map);
}
if(ok) {
float *v0 = I->V;
float *vn0 = I->VN;
int *p = dot_flag;
int c = I->N;
int a;
v = I->V;
vn = I->VN;
I->N = 0;
for(a = 0; a < c; a++) {
if(*(p++)) {
*(v0++) = *(v++);
*(v0++) = *(v++);
*(v0++) = *(v++);
normalize3f(vn);
*(vn0++) = *(vn++);
*(vn0++) = *(vn++);
*(vn0++) = *(vn++);
I->N++;
} else {
v += 3;
vn += 3;
}
}
}
ok &= !G->Interrupt;
}
FreeP(dot_flag);
}
/* now eliminate troublesome vertices in regions of extremely high curva ture */ /* now eliminate troublesome vertices in regions of extremely high curva ture */
ok &= SurfaceJobEliminateTroublesomeVertices(G, I);
if(ok && (surface_type != 3) &&
I->N && (I->trimCutoff > 0.0F) && (I->trimFactor > 0.0F)) {
float trim_cutoff = I->trimCutoff;
float trim_factor = I->trimFactor;
int repeat_flag = true;
float neighborhood = trim_factor * point_sep;
float dot_sum;
int n_nbr;
int *dot_flag = Alloc(int, I->N);
CHECKOK(ok, dot_flag);
if(ok && surface_type == 6) { /* emprical tweaks */
trim_factor *= 2.5;
trim_cutoff *= 1.5;
}
while(ok && repeat_flag) {
int a;
MapType *map = MapNew(G, neighborhood, I->V, I->N, NULL);
CHECKOK(ok, map);
if (ok){
repeat_flag = false;
for(a = 0; a < I->N; a++)
dot_flag[a] = 1;
ok &= MapSetupExpress(map);
}
v = I->V;
vn = I->VN;
for(a = 0; ok && a < I->N; a++) {
if(dot_flag[a]) {
int i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
n_nbr = 0;
dot_sum = 0.0F;
while(j >= 0) {
if(j != a) {
if(dot_flag[j]) {
float *v0 = I->V + 3 * j;
if(within3f(v0, v, neighborhood)) {
float *n0 = I->VN + 3 * j;
dot_sum += dot_product3f(n0, vn);
n_nbr++;
}
}
}
j = map->EList[i++];
}
if(n_nbr) {
dot_sum /= n_nbr;
if(dot_sum < trim_cutoff) {
dot_flag[a] = false;
repeat_flag = true;
}
}
}
}
v += 3;
vn += 3;
ok &= !G->Interrupt;
}
if(ok) {
float *v0 = I->V;
float *vn0 = I->VN;
int *p = dot_flag;
int c = I->N;
v = I->V;
vn = I->VN;
I->N = 0;
for(a = 0; a < c; a++) {
if(*(p++)) {
*(v0++) = *(v++);
*(v0++) = *(v++);
*(v0++) = *(v++);
normalize3f(vn);
*(vn0++) = *(vn++);
*(vn0++) = *(vn++);
*(vn0++) = *(vn++);
I->N++;
} else {
v += 3;
vn += 3;
}
}
}
MapFree(map);
ok &= !G->Interrupt;
}
FreeP(dot_flag);
}
ok &= !G->Interrupt; ok &= !G->Interrupt;
} }
} }
if(ok && I->N && I->V && I->VN) { if(ok && I->N && I->V && I->VN) {
VLASizeForSure(I->V, float, 3 * I->N); VLASizeForSure(I->V, float, 3 * I->N);
CHECKOK(ok, I->V); CHECKOK(ok, I->V);
if (ok) if (ok)
VLASizeForSure(I->VN, float, 3 * I->N); VLASizeForSure(I->VN, float, 3 * I->N);
CHECKOK(ok, I->VN); CHECKOK(ok, I->VN);
skipping to change at line 4076 skipping to change at line 3819
if (ok) if (ok)
VLASizeForSure(I->VN, float, 1); VLASizeForSure(I->VN, float, 1);
CHECKOK(ok, I->VN); CHECKOK(ok, I->VN);
} }
if(carve_map) if(carve_map)
MapFree(carve_map); MapFree(carve_map);
} }
return ok; return ok;
} }
static void RepSurfaceSetSettings(PyMOLGlobals * G, CoordSet * cs,
ObjectMolecule *obj, int surface_quality, int surface_type, float *point_sep
,
int *sphere_idx, int *solv_sph_idx, int *circumscribe)
{
if(surface_quality >= 4) { /* totally impractical */
*point_sep = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surface
_best) / 4.f;
*sphere_idx = 4;
*solv_sph_idx = 4;
if(*circumscribe < 0)
*circumscribe = 91;
} else {
switch (surface_quality) {
case 3: /* nearly impractical */
*point_sep = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surfa
ce_best) / 3.f;
*sphere_idx = 4;
*solv_sph_idx = 3;
if(*circumscribe < 0)
*circumscribe = 71;
break;
case 2:
/* nearly perfect */
*point_sep = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surfa
ce_best) / 2.f;
*sphere_idx = 3;
*solv_sph_idx = 3;
if(*circumscribe < 0)
*circumscribe = 41;
break;
case 1:
/* good */
*point_sep = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surfa
ce_best);
*sphere_idx = 2;
*solv_sph_idx = 3;
if((*circumscribe < 0) && (surface_type == 6))
*circumscribe = 40;
break;
case 0:
/* 0 - normal */
*point_sep = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surfa
ce_normal);
*sphere_idx = 1;
*solv_sph_idx = 2;
if((*circumscribe < 0) && (surface_type == 6))
*circumscribe = 30;
break;
case -1:
/* -1 */
*point_sep = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surfa
ce_poor);
*sphere_idx = 1;
*solv_sph_idx = 2;
if((*circumscribe < 0) && (surface_type == 6))
*circumscribe = 10;
break;
case -2:
/* -2 god awful */
*point_sep = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surfa
ce_poor) * 1.5F;
*sphere_idx = 1;
*solv_sph_idx = 1;
break;
case -3:
/* -3 miserable */
*point_sep = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surfa
ce_miserable);
*sphere_idx = 1;
*solv_sph_idx = 1;
break;
default:
*point_sep = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surfa
ce_miserable) * 1.18F;
*sphere_idx = 0;
*solv_sph_idx = 1;
}
}
/* Fixed problem with surface holes when surface_quality>2, it seems like circ
umscribe can only be
used with surface_solvent */
if((*circumscribe < 0) || (!SettingGet_b(G, cs->Setting, obj->Obj.Setting, cSe
tting_surface_solvent)))
*circumscribe = 0;
}
static int RepSurfacePrepareSurfaceJob(PyMOLGlobals * G, SurfaceJob *surf_job,
RepSurface *I, CoordSet *cs, ObjectMolecule *obj, SurfaceJobAtomInfo **atom_
info,
float *carve_vla, int n_present, int *present_vla, int optimize, int sphere_
idx,
int solv_sph_idx, int surface_type, int circumscribe, float probe_radius,
float point_sep, float carve_cutoff)
{
int ok = true;
surf_job->maxVdw = I->max_vdw;
surf_job->allVisibleFlag = I->allVisibleFlag;
surf_job->atomInfo = *atom_info;
(*atom_info) = NULL;
surf_job->nPresent = n_present;
if(present_vla && optimize) {
/* implies that n_present < cs->NIndex, so eliminate
irrelevant atoms & coordinates if we are optimizing subsets */
surf_job->coord = VLAlloc(float, n_present * 3);
CHECKOK(ok, surf_job->coord);
if (ok) {
int *p = present_vla;
SurfaceJobAtomInfo *ai_src = surf_job->atomInfo;
SurfaceJobAtomInfo *ai_dst = surf_job->atomInfo;
float *v_src = cs->Coord;
float *v_dst = surf_job->coord;
int a;
for(a = 0; a < cs->NIndex; a++) {
if(*(p++)) {
copy3f(v_src, v_dst);
v_dst += 3;
if(ai_dst != ai_src)
*ai_dst = *ai_src;
ai_dst++;
}
v_src += 3;
ai_src++;
}
}
VLASize(surf_job->atomInfo, SurfaceJobAtomInfo, n_present);
CHECKOK(ok, surf_job->atomInfo);
} else {
surf_job->presentVla = present_vla;
present_vla = NULL;
surf_job->coord = VLAlloc(float, cs->NIndex * 3);
CHECKOK(ok, surf_job->coord);
if(ok)
UtilCopyMem(surf_job->coord, cs->Coord, sizeof(float) * 3 * cs->NIndex);
}
if (ok){
surf_job->sphereIndex = sphere_idx;
surf_job->solventSphereIndex = solv_sph_idx;
surf_job->surfaceType = surface_type;
surf_job->circumscribe = circumscribe;
surf_job->probeRadius = probe_radius;
surf_job->pointSep = point_sep;
surf_job->trimCutoff = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetti
ng_surface_trim_cutoff);
surf_job->trimFactor = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetti
ng_surface_trim_factor);
surf_job->cavityMode = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetti
ng_surface_cavity_mode);
surf_job->cavityRadius = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSet
ting_surface_cavity_radius);
surf_job->cavityCutoff = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSet
ting_surface_cavity_cutoff);
if(carve_vla)
surf_job->carveVla = VLACopy(carve_vla, float);
surf_job->carveCutoff = carve_cutoff;
surf_job->surfaceMode = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSett
ing_surface_mode);
surf_job->surfaceSolvent = SettingGet_b(G, cs->Setting, obj->Obj.Setting, cS
etting_surface_solvent);
surf_job->cavityCull = SettingGet_i(G, cs->Setting,
obj->Obj.Setting, cSetting_cavity_cull);
}
return ok;
}
#ifndef _PYMOL_NOPY
void RepSurfaceConvertSurfaceJobToPyObject(PyMOLGlobals *G, SurfaceJob *surf_job
, CoordSet *cs, ObjectMolecule *obj, PyObject **entry, PyObject **input, PyObjec
t **output, int *found){
int cache_mode = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_cache
_mode);
if(cache_mode > 0) {
int blocked = PAutoBlock(G);
*input = SurfaceJobInputAsTuple(G, surf_job);
if(PCacheGet(G, output, entry, *input) == OV_STATUS_YES) {
if(OV_OK(SurfaceJobResultFromTuple(G, surf_job, *output))) {
*found = true;
PXDecRef(*input);
*input = NULL;
PXDecRef(*entry);
*entry = NULL;
}
PXDecRef(*output);
*output = NULL;
}
if(PyErr_Occurred())
PyErr_Print();
PAutoUnblock(G, blocked);
}
}
#endif
static void RepSurfaceFindAllPresentAtoms(ObjectMolecule *obj, CoordSet *cs, int
*present_vla, int inclH, int cullByFlag){
int *ap = present_vla;
int *idx_to_atm = cs->IdxToAtm;
AtomInfoType *obj_AtomInfo = obj->AtomInfo;
int a, cs_NIndex = cs->NIndex;
for(a = 0; a < cs_NIndex; a++) {
AtomInfoType *ai1 = obj_AtomInfo + *(idx_to_atm++);
if((ai1->visRep & cRepSurfaceBit) &&
(inclH || (!ai1->isHydrogen())) &&
((!cullByFlag) || (!(ai1->flags &
(cAtomFlag_ignore | cAtomFlag_exfoliate)))))
*ap = 2;
else
*ap = 0;
ap++;
}
}
static int RepSurfaceAddNearByAtomsIfNotSurfaced(PyMOLGlobals *G, MapType *map,
ObjectMolecule *obj, CoordSet *cs, int *present_vla, int inclH,
int cullByFlag, float probe_radius, int optimize)
{
int ok = true;
float probe_radiusX2 = probe_radius * 2;
int a;
for(a = 0; ok && a < cs->NIndex; a++){
if(!present_vla[a]) {
AtomInfoType *ai1 = obj->AtomInfo + cs->IdxToAtm[a];
if((inclH || (!ai1->isHydrogen())) &&
((!cullByFlag) ||
!(ai1->flags & cAtomFlag_ignore))) {
float *v0 = cs->Coord + 3 * a;
int i = *(MapLocusEStart(map, v0));
if(optimize) {
if(i && map->EList) {
int j = map->EList[i++];
while(j >= 0) {
if(present_vla[j] > 1) {
AtomInfoType *ai2 = obj->AtomInfo + cs->IdxToAtm[j];
if(within3f
(cs->Coord + 3 * j, v0,
ai1->vdw + ai2->vdw + probe_radiusX2)) {
present_vla[a] = 1;
break;
}
}
j = map->EList[i++];
}
}
} else
present_vla[a] = 1;
}
}
ok &= !G->Interrupt;
}
return ok;
}
static int RepSurfaceRemoveAtomsNotWithinCutoff(PyMOLGlobals *G,
MapType *carve_map, float *carve_vla, CoordSet *cs, int *present_vla,
float carve_cutoff)
{
int ok = true;
int a;
for(a = 0; ok && a < cs->NIndex; a++) {
int include_flag = false;
if(carve_map) {
float *v0 = cs->Coord + 3 * a;
int i = *(MapLocusEStart(carve_map, v0));
if(i && carve_map->EList) {
int j = carve_map->EList[i++];
while(j >= 0) {
if(within3f(carve_vla + 3 * j, v0, carve_cutoff)) {
include_flag = true;
break;
}
j = carve_map->EList[i++];
}
}
}
if(!include_flag)
present_vla[a] = 0;
ok &= !G->Interrupt;
}
return ok;
}
Rep *RepSurfaceNew(CoordSet * cs, int state) Rep *RepSurfaceNew(CoordSet * cs, int state)
{ {
int ok = true; int ok = true;
PyMOLGlobals *G = cs->State.G; PyMOLGlobals *G = cs->State.G;
ObjectMolecule *obj = cs->Obj; ObjectMolecule *obj = cs->Obj;
OOCalloc(G, RepSurface); OOCalloc(G, RepSurface);
CHECKOK(ok, I); CHECKOK(ok, I);
if (!ok) if (!ok)
return NULL; return NULL;
I->pickingCGO = I->shaderCGO = 0; I->pickingCGO = I->shaderCGO = 0;
I->vertexIndices = 0; #ifdef _PYMOL_IOS
I->sum = 0; #endif
I->z_value = 0;
I->ix = 0;
I->n_tri = 0;
I->AT = 0; I->AT = 0;
I->ColorInvalidated = false; I->ColorInvalidated = false;
{ {
int surface_mode = int surface_mode =
SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_surface_mode); SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_surface_mode);
int cullByFlag = (surface_mode == cRepSurface_by_flags); int cullByFlag = (surface_mode == cRepSurface_by_flags);
int inclH = !((surface_mode == cRepSurface_heavy_atoms) int inclH = !((surface_mode == cRepSurface_heavy_atoms)
|| (surface_mode == cRepSurface_vis_heavy_only)); || (surface_mode == cRepSurface_vis_heavy_only));
int inclInvis = !((surface_mode == cRepSurface_vis_only) int inclInvis = !((surface_mode == cRepSurface_vis_only)
|| (surface_mode == cRepSurface_vis_heavy_only)); || (surface_mode == cRepSurface_vis_heavy_only));
skipping to change at line 4124 skipping to change at line 4127
} }
} }
} }
if(!visFlag) { if(!visFlag) {
OOFreeP(I); OOFreeP(I);
return (NULL); /* skip if no thing visible */ return (NULL); /* skip if no thing visible */
} }
{ {
int surface_flag = false; int surface_flag = false;
int surface_type = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting
int surface_type = _surface_type);
SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_surface_type); int surface_quality = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSett
int surface_solvent = ing_surface_quality);
SettingGet_b(G, cs->Setting, obj->Obj.Setting, cSetting_surface_solvent) float probe_radius = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetti
; ng_solvent_radius);
int surface_quality = int optimize = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_sur
SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_surface_quality) face_optimize_subsets);
; int circumscribe = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting
float probe_radius = _surface_circumscribe);
SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_solvent_radius);
int optimize =
SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_surface_optimize
_subsets);
int circumscribe =
SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_surface_circumsc
ribe);
float trim_cutoff =
SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surface_trim_cut
off);
float trim_factor =
SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surface_trim_fac
tor);
int sphere_idx = 0, solv_sph_idx = 0; int sphere_idx = 0, solv_sph_idx = 0;
MapType *map = NULL; MapType *map = NULL;
float point_sep; float point_sep;
int *present_vla = NULL; int *present_vla = NULL;
int n_present = 0; int n_present = 0;
int carve_state = 0; int carve_state = 0;
int carve_flag = false; int carve_flag = false;
float carve_cutoff; float carve_cutoff;
const char *carve_selection = NULL; const char *carve_selection = NULL;
float *carve_vla = NULL; float *carve_vla = NULL;
MapType *carve_map = NULL; MapType *carve_map = NULL;
bool smooth_edges = SettingGet_b(G, cs->Setting, obj->Obj.Setting, cSettin
int cavity_mode = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_ g_surface_smooth_edges);
surface_cavity_mode);
float cavity_radius = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSett
ing_surface_cavity_radius);
float cavity_cutoff = SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSett
ing_surface_cavity_cutoff);
I->Type = surface_type; I->Type = surface_type;
I->max_vdw = ObjectMoleculeGetMaxVDW(obj); I->max_vdw = ObjectMoleculeGetMaxVDW(obj);
if(surface_quality >= 4) { /* totally impractical */ RepSurfaceSetSettings(G, cs, obj, surface_quality, surface_type, &point_se
point_sep = p, &sphere_idx, &solv_sph_idx, &circumscribe);
SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surface_best)
/ 4;
sphere_idx = 4;
solv_sph_idx = 4;
if(circumscribe < 0)
circumscribe = 91;
} else {
switch (surface_quality) {
case 3: /* nearly impractical */
point_sep =
SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surface_best
) / 3;
sphere_idx = 4;
solv_sph_idx = 3;
if(circumscribe < 0)
circumscribe = 71;
break;
case 2:
/* nearly perfect */
point_sep =
SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surface_best
) / 2;
sphere_idx = 3;
solv_sph_idx = 3;
if(circumscribe < 0)
circumscribe = 41;
break;
case 1:
/* good */
point_sep =
SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surface_best
);
sphere_idx = 2;
solv_sph_idx = 3;
if((circumscribe < 0) && (surface_type == 6))
circumscribe = 40;
break;
case 0:
/* 0 - normal */
point_sep =
SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surface_norm
al);
sphere_idx = 1;
solv_sph_idx = 2;
if((circumscribe < 0) && (surface_type == 6))
circumscribe = 30;
break;
case -1:
/* -1 */
point_sep =
SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surface_poor
);
sphere_idx = 1;
solv_sph_idx = 2;
if((circumscribe < 0) && (surface_type == 6))
circumscribe = 10;
break;
case -2:
/* -2 god awful */
point_sep =
SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surface_poor
) * 1.5F;
sphere_idx = 1;
solv_sph_idx = 1;
break;
case -3:
/* -3 miserable */
point_sep =
SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surface_mise
rable);
sphere_idx = 1;
solv_sph_idx = 1;
break;
default:
point_sep =
SettingGet_f(G, cs->Setting, obj->Obj.Setting,
cSetting_surface_miserable) * 1.18F;
sphere_idx = 0;
solv_sph_idx = 1;
}
}
if((circumscribe < 0) || (!surface_solvent))
circumscribe = 0;
RepInit(G, &I->R); RepInit(G, &I->R);
I->R.context.object = (void *) obj; I->R.context.object = (void *) obj;
I->R.context.state = state; I->R.context.state = state;
I->R.fRender = (void (*)(struct Rep *, RenderInfo * info)) RepSurfaceRende r; I->R.fRender = (void (*)(struct Rep *, RenderInfo * info)) RepSurfaceRende r;
I->R.fFree = (void (*)(struct Rep *)) RepSurfaceFree; I->R.fFree = (void (*)(struct Rep *)) RepSurfaceFree;
I->R.fRecolor = (void (*)(struct Rep *, struct CoordSet *)) RepSurfaceColo r; I->R.fRecolor = (void (*)(struct Rep *, struct CoordSet *)) RepSurfaceColo r;
I->R.fSameVis = (int (*)(struct Rep *, struct CoordSet *)) RepSurfaceSameV is; I->R.fSameVis = (int (*)(struct Rep *, struct CoordSet *)) RepSurfaceSameV is;
I->R.fSameColor = (int (*)(struct Rep *, struct CoordSet *)) RepSurfaceSam eColor; I->R.fSameColor = (int (*)(struct Rep *, struct CoordSet *)) RepSurfaceSam eColor;
I->R.fInvalidate = (void (*)(struct Rep *, struct CoordSet *, int)) RepSur faceInvalidate; I->R.fInvalidate = (void (*)(struct Rep *, struct CoordSet *, int)) RepSur faceInvalidate;
skipping to change at line 4284 skipping to change at line 4193
} }
if(surface_flag) { if(surface_flag) {
SurfaceJobAtomInfo *atom_info = VLACalloc(SurfaceJobAtomInfo, cs->NIndex ); SurfaceJobAtomInfo *atom_info = VLACalloc(SurfaceJobAtomInfo, cs->NIndex );
CHECKOK(ok, atom_info); CHECKOK(ok, atom_info);
if(ok && atom_info) { if(ok && atom_info) {
AtomInfoType *i_ai, *obj_atom_info = obj->AtomInfo; AtomInfoType *i_ai, *obj_atom_info = obj->AtomInfo;
int *idx_to_atm = cs->IdxToAtm; int *idx_to_atm = cs->IdxToAtm;
int n_index = cs->NIndex; int n_index = cs->NIndex;
SurfaceJobAtomInfo *i_atom_info = atom_info; SurfaceJobAtomInfo *i_atom_info = atom_info;
int i; int i;
/* fill in surfacing flags into SurfaceJobAtomInfo array */
for(i = 0; i < n_index; i++) { for(i = 0; i < n_index; i++) {
i_ai = obj_atom_info + idx_to_atm[i]; i_ai = obj_atom_info + idx_to_atm[i];
/* just surfacing flags */
i_atom_info->flags = i_ai->flags & (cAtomFlag_ignore | cAtomFlag_exf oliate); i_atom_info->flags = i_ai->flags & (cAtomFlag_ignore | cAtomFlag_exf oliate);
i_atom_info->vdw = i_ai->vdw; i_atom_info->vdw = i_ai->vdw;
i_atom_info++; i_atom_info++;
} }
} }
OrthoBusyFast(G, 0, 1); OrthoBusyFast(G, 0, 1);
if (ok){ if (ok){
n_present = cs->NIndex; n_present = cs->NIndex;
carve_selection = carve_selection =
SettingGet_s(G, cs->Setting, obj->Obj.Setting, SettingGet_s(G, cs->Setting, obj->Obj.Setting,
cSetting_surface_carve_selection); cSetting_surface_carve_selection);
carve_cutoff = carve_cutoff =
SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surface_carve _cutoff); SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_surface_carve _cutoff);
if((!carve_selection) || (!carve_selection[0])) if((!carve_selection) || (!carve_selection[0]))
carve_cutoff = 0.0F; carve_cutoff = 0.0F;
if(carve_cutoff > 0.0F) { if(carve_cutoff > 0.0F) {
carve_state = carve_state =
SettingGet_i(G, cs->Setting, obj->Obj.Setting, SettingGet_i(G, cs->Setting, obj->Obj.Setting,
skipping to change at line 4325 skipping to change at line 4233
carve_state, carve_c utoff, carve_state, carve_c utoff,
&carve_vla); &carve_vla);
if(carve_map) if(carve_map)
ok &= MapSetupExpress(carve_map); ok &= MapSetupExpress(carve_map);
carve_flag = true; carve_flag = true;
I->allVisibleFlag = false; I->allVisibleFlag = false;
} }
} }
if(ok && !I->allVisibleFlag) { if(ok && !I->allVisibleFlag) {
/* optimize the space over which we calculate a surface */ /* optimize the space over which we calculate a surface */
/* first find out which atoms are actually to be surfaced */ /* first find out which atoms are actually to be surfaced */
present_vla = VLAlloc(int, cs->NIndex); present_vla = VLAlloc(int, cs->NIndex);
CHECKOK(ok, present_vla); CHECKOK(ok, present_vla);
if (ok){ if (ok){
int *ap = present_vla; RepSurfaceFindAllPresentAtoms(obj, cs, present_vla, inclH, cullByFlag
int *idx_to_atm = cs->IdxToAtm; );
AtomInfoType *obj_AtomInfo = obj->AtomInfo;
int a, cs_NIndex = cs->NIndex;
for(a = 0; a < cs_NIndex; a++) {
AtomInfoType *ai1 = obj_AtomInfo + *(idx_to_atm++);
if((ai1->visRep & cRepSurfaceBit) &&
(inclH || (!ai1->isHydrogen())) &&
((!cullByFlag) || (!(ai1->flags &
(cAtomFlag_ignore | cAtomFlag_exfoliate)))
))
*ap = 2;
else
*ap = 0;
ap++;
}
} }
if (ok) if (ok)
map = map =
MapNewFlagged(G, 2 * I->max_vdw + probe_radius, cs->Coord, cs->NInd ex, NULL, MapNewFlagged(G, 2 * I->max_vdw + probe_radius, cs->Coord, cs->NInd ex, NULL,
present_vla); present_vla);
CHECKOK(ok, map); CHECKOK(ok, map);
if (ok) if (ok)
ok &= MapSetupExpress(map); ok &= MapSetupExpress(map);
if(ok && inclInvis) { if(ok && inclInvis) {
/* then add in the nearby atoms which are not surfaced and not ignor ed */ /* then add in the nearby atoms which are not surfaced and not ignor ed */
float probe_radiusX2 = probe_radius * 2; ok &= RepSurfaceAddNearByAtomsIfNotSurfaced(G, map, obj, cs, present_
int a; vla, inclH, cullByFlag, probe_radius, optimize);
for(a = 0; ok && a < cs->NIndex; a++){
if(!present_vla[a]) {
AtomInfoType *ai1 = obj->AtomInfo + cs->IdxToAtm[a];
if((inclH || (!ai1->isHydrogen())) &&
((!cullByFlag) ||
!(ai1->flags & cAtomFlag_ignore))) {
float *v0 = cs->Coord + 3 * a;
int i = *(MapLocusEStart(map, v0));
if(optimize) {
if(i && map->EList) {
int j = map->EList[i++];
while(j >= 0) {
if(present_vla[j] > 1) {
AtomInfoType *ai2 = obj->AtomInfo + cs->IdxToAtm[j];
if(within3f
(cs->Coord + 3 * j, v0,
ai1->vdw + ai2->vdw + probe_radiusX2)) {
present_vla[a] = 1;
break;
}
}
j = map->EList[i++];
}
}
} else
present_vla[a] = 1;
}
}
ok &= !G->Interrupt;
}
} }
if(ok && carve_flag && (!optimize)) { if(ok && carve_flag && (!optimize)) {
/* and optimize for carved region */ /* and optimize for carved region */
int a; ok &= RepSurfaceRemoveAtomsNotWithinCutoff(G, carve_map, carve_vla, c
for(a = 0; ok && a < cs->NIndex; a++) { s, present_vla, carve_cutoff);
int include_flag = false;
if(carve_map) {
float *v0 = cs->Coord + 3 * a;
int i = *(MapLocusEStart(carve_map, v0));
if(i && carve_map->EList) {
int j = carve_map->EList[i++];
while(j >= 0) {
if(within3f(carve_vla + 3 * j, v0, carve_cutoff)) {
include_flag = true;
break;
}
j = carve_map->EList[i++];
}
}
}
if(!include_flag)
present_vla[a] = 0;
ok &= !G->Interrupt;
}
} }
MapFree(map); MapFree(map);
map = NULL; map = NULL;
/* now count how many atoms we actually need to think about */ /* now count how many atoms we actually need to think about */
n_present = 0; n_present = 0;
if (ok) { if (ok) {
int a; int a;
for(a = 0; a < cs->NIndex; a++) { for(a = 0; a < cs->NIndex; a++) {
if(present_vla[a]) { if(present_vla[a]) {
n_present++; n_present++;
} }
} }
} }
} }
if (ok) { if (ok) {
SurfaceJob *surf_job = SurfaceJobNew(G); SurfaceJob *surf_job = SurfaceJobNew(G);
CHECKOK(ok, surf_job); CHECKOK(ok, surf_job);
if(ok && surf_job) { ok &= RepSurfacePrepareSurfaceJob(G, surf_job, I, cs, obj, &atom_info,
carve_vla, n_present, present_vla, optimize, sphere_idx, solv_sph_idx, surface_t
surf_job->maxVdw = I->max_vdw; ype, circumscribe, probe_radius, point_sep, carve_cutoff);
surf_job->allVisibleFlag = I->allVisibleFlag;
surf_job->atomInfo = atom_info;
atom_info = NULL;
surf_job->nPresent = n_present;
if(present_vla && optimize) {
/* implies that n_present < cs->NIndex, so eliminate
irrelevant atoms & coordinates if we are optimizing subsets */
surf_job->coord = VLAlloc(float, n_present * 3);
CHECKOK(ok, surf_job->coord);
if (ok) {
int *p = present_vla;
SurfaceJobAtomInfo *ai_src = surf_job->atomInfo;
SurfaceJobAtomInfo *ai_dst = surf_job->atomInfo;
float *v_src = cs->Coord;
float *v_dst = surf_job->coord;
int a;
for(a = 0; a < cs->NIndex; a++) {
if(*(p++)) {
copy3f(v_src, v_dst);
v_dst += 3;
if(ai_dst != ai_src)
*ai_dst = *ai_src;
ai_dst++;
}
v_src += 3;
ai_src++;
}
}
VLASize(surf_job->atomInfo, SurfaceJobAtomInfo, n_present);
CHECKOK(ok, surf_job->atomInfo);
} else {
surf_job->presentVla = present_vla;
present_vla = NULL;
surf_job->coord = VLAlloc(float, cs->NIndex * 3);
CHECKOK(ok, surf_job->coord);
if(ok)
UtilCopyMem(surf_job->coord, cs->Coord, sizeof(float) * 3 * cs->
NIndex);
}
if (ok){
surf_job->sphereIndex = sphere_idx;
surf_job->solventSphereIndex = solv_sph_idx;
surf_job->surfaceType = surface_type;
surf_job->circumscribe = circumscribe;
surf_job->probeRadius = probe_radius;
surf_job->pointSep = point_sep;
surf_job->trimCutoff = trim_cutoff;
surf_job->trimFactor = trim_factor;
surf_job->cavityMode = cavity_mode;
surf_job->cavityRadius = cavity_radius;
surf_job->cavityCutoff = cavity_cutoff;
if(carve_vla)
surf_job->carveVla = VLACopy(carve_vla, float);
surf_job->carveCutoff = carve_cutoff;
surf_job->surfaceMode = surface_mode;
surf_job->surfaceSolvent = surface_solvent;
surf_job->cavityCull = SettingGet_i(G, cs->Setting,
obj->Obj.Setting, cSetting_cavi
ty_cull);
}
}
ok &= !G->Interrupt; ok &= !G->Interrupt;
if(ok) { if(ok) {
int found = false; int found = false;
#ifndef _PYMOL_NOPY #ifndef _PYMOL_NOPY
PyObject *entry = NULL; PyObject *entry = NULL;
PyObject *output = NULL; PyObject *output = NULL;
PyObject *input = NULL; PyObject *input = NULL;
int cache_mode = int cache_mode = SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSett
SettingGet_i(G, cs->Setting, obj->Obj.Setting, cSetting_cache_mode ing_cache_mode);
); RepSurfaceConvertSurfaceJobToPyObject(G, surf_job, cs, obj, &entry, &
input, &output, &found);
if(cache_mode > 0) {
int blocked = PAutoBlock(G);
input = SurfaceJobInputAsTuple(G, surf_job);
if(PCacheGet(G, &output, &entry, input) == OV_STATUS_YES) {
if(OV_OK(SurfaceJobResultFromTuple(G, surf_job, output))) {
found = true;
PXDecRef(input);
input = NULL;
PXDecRef(entry);
entry = NULL;
}
PXDecRef(output);
output = NULL;
}
if(PyErr_Occurred())
PyErr_Print();
PAutoUnblock(G, blocked);
}
#endif #endif
if(ok && !found) { if(ok && !found) {
ok &= SurfaceJobRun(G, surf_job); ok &= SurfaceJobRun(G, surf_job);
#ifndef _PYMOL_NOPY #ifndef _PYMOL_NOPY
if(cache_mode > 1) { if(cache_mode > 1) {
int blocked = PAutoBlock(G); int blocked = PAutoBlock(G);
output = SurfaceJobResultAsTuple(G, surf_job); output = SurfaceJobResultAsTuple(G, surf_job);
PCacheSet(G, entry, output); PCacheSet(G, entry, output);
PXDecRef(entry); PXDecRef(entry); entry = NULL;
entry = NULL; PXDecRef(output); output = NULL;
PXDecRef(output); PXDecRef(input); input = NULL;
output = NULL;
PXDecRef(input);
input = NULL;
PAutoUnblock(G, blocked); PAutoUnblock(G, blocked);
} }
#endif #endif
} }
#ifndef _PYMOL_NOPY #ifndef _PYMOL_NOPY
if(entry || input || output) { if(entry || input || output) {
int blocked = PAutoBlock(G); int blocked = PAutoBlock(G);
PXDecRef(entry); PXDecRef(entry);
PXDecRef(input); PXDecRef(input);
PXDecRef(output); PXDecRef(output);
skipping to change at line 4582 skipping to change at line 4329
surf_job->V = NULL; surf_job->V = NULL;
I->VN = surf_job->VN; I->VN = surf_job->VN;
surf_job->VN = NULL; surf_job->VN = NULL;
I->NT = surf_job->NT; I->NT = surf_job->NT;
surf_job->NT = 0; surf_job->NT = 0;
I->T = surf_job->T; I->T = surf_job->T;
surf_job->T = NULL; surf_job->T = NULL;
I->S = surf_job->S; I->S = surf_job->S;
surf_job->S = NULL; surf_job->S = NULL;
} }
SurfaceJobPurgeResult(G, surf_job); SurfaceJobPurgeResult(G, surf_job);
SurfaceJobFree(G, surf_job); SurfaceJobFree(G, surf_job);
} }
VLAFreeP(atom_info); VLAFreeP(atom_info);
ok &= !G->Interrupt; ok &= !G->Interrupt;
if(ok) if(ok)
RepSurfaceColor(I, cs); RepSurfaceColor(I, cs);
if (ok && smooth_edges)
RepSurfaceSmoothEdges(I);
} }
if(carve_map) if(carve_map)
MapFree(carve_map); MapFree(carve_map);
VLAFreeP(carve_vla); VLAFreeP(carve_vla);
VLAFreeP(present_vla); VLAFreeP(present_vla);
if(ok && I->debug)
ok &= CGOStop(I->debug);
OrthoBusyFast(G, 4, 4); OrthoBusyFast(G, 4, 4);
} }
} }
if(!ok) { if(!ok) {
RepSurfaceFree(I); RepSurfaceFree(I);
I = NULL; I = NULL;
} }
return (Rep *) I; return (Rep *) I;
} }
void RepSurfaceSmoothEdges(RepSurface * I)
{
std::vector<std::vector<int>> edges(I->N);
// Find all edges.
// Uses the following edge structure:
// edge[v0] -> { v1, t0, t1 }
// where (v0, v1) defines an edge and (t0, t1)
// are triangles the edge belongs to.
// The edge is unique when t0 == t1.
int *t = I->T;
int *vi = I->Vis;
for (auto i = 0; i < I->NT; i++) {
if (visibility_test(I->proximity, vi, t)) {
int v0 = t[0];
int v1 = t[1];
int v2 = t[2];
if (v0 < v1) {
edges[v0].push_back(v1);
edges[v0].push_back(i);
edges[v0].push_back(i);
} else {
edges[v1].push_back(v0);
edges[v1].push_back(i);
edges[v1].push_back(i);
}
if (v1 < v2) {
edges[v1].push_back(v2);
edges[v1].push_back(i);
edges[v1].push_back(i);
} else {
edges[v2].push_back(v1);
edges[v2].push_back(i);
edges[v2].push_back(i);
}
if (v2 < v0) {
edges[v2].push_back(v0);
edges[v2].push_back(i);
edges[v2].push_back(i);
} else {
edges[v0].push_back(v2);
edges[v0].push_back(i);
edges[v0].push_back(i);
}
}
t += 3;
}
// Assign triangles to every edge
for (auto i = 0; i < I->N; i++) {
for (auto j = 0; j < edges[i].size(); j += 3) {
for (auto k = 0; k < j; k += 3) {
if ((j != k) && (edges[i][j] == edges[i][k])) {
edges[i][j + 2] = edges[i][k + 1];
edges[i][k + 2] = edges[i][j + 1];
}
}
}
}
std::vector<int> unique_edges;
// Build a list of unique edges
for (auto i = 0; i < I->N; i++) {
for (auto j = 0; j < edges[i].size(); j += 3) {
if (edges[i][j + 1] == edges[i][j + 2]) {
unique_edges.push_back(i);
unique_edges.push_back(edges[i][j]);
}
}
}
if (unique_edges.size() > 0) {
std::vector<float> new_vertices(3 * I->N);
UtilCopyMem(&new_vertices[0], I->V, sizeof(float) * 3 * I->N);
// Average positions of vertices shared by consecutive unique edges
for (auto i = 0; i < unique_edges.size(); i += 2) {
for (auto j = 0; j < i; j += 2) {
auto v0 = -1, v1 = -1, v2 = -1;
if (unique_edges[i] == unique_edges[j]) {
v0 = unique_edges[i];
v1 = unique_edges[i + 1];
v2 = unique_edges[j + 1];
} else if (unique_edges[i + 1] == unique_edges[j]) {
v0 = unique_edges[i + 1];
v1 = unique_edges[i];
v2 = unique_edges[j + 1];
} else if (unique_edges[i] == unique_edges[j + 1]) {
v0 = unique_edges[i];
v1 = unique_edges[i + 1];
v2 = unique_edges[j];
} else if (unique_edges[i + 1] == unique_edges[j + 1]) {
v0 = unique_edges[i + 1];
v1 = unique_edges[i];
v2 = unique_edges[j];
}
if (v0 >= 0) {
for (auto k = 0; k < 3; k++) {
new_vertices[3 * v0 + k] =
(1. / 3.) * (I->V[3 * v0 + k] +
I->V[3 * v1 + k] +
I->V[3 * v2 + k]);
}
}
}
}
UtilCopyMem(I->V, &new_vertices[0], sizeof(float) * 3 * I->N);
}
}
static int SolventDotFilterOutSameXYZ(PyMOLGlobals * G, MapType *map,
SurfaceJobAtomInfo * atom_info, SurfaceJobAtomInfo *a_atom_info,
float *coord, int a, int *present, int *skip_flag)
{
int ok = true;
float *v0 = coord + 3 * a;
int i = *(MapLocusEStart(map, v0));
if(i && map->EList) {
int j = map->EList[i++];
while(ok && j >= 0) {
SurfaceJobAtomInfo *j_atom_info = atom_info + j;
if(j > a) /* only check if this is atom trails */
if((!present) || present[j]) {
if(j_atom_info->vdw == a_atom_info->vdw) { /* handle singulariti
es */
float *v1 = coord + 3 * j;
if((v0[0] == v1[0]) && (v0[1] == v1[1]) && (v0[2] == v1[2])){
// is this necessary? if some different atoms have exact same x/y/z
*skip_flag = true;
}
}
}
j = map->EList[i++];
ok &= !G->Interrupt;
}
}
return ok;
}
static int SolventDotGetDotsAroundVertexInSphere(PyMOLGlobals * G, SolventDot *I
,
MapType *map, SurfaceJobAtomInfo * atom_info, SurfaceJobAtomInfo *a_atom_inf
o,
float *coord, int a, int *present, SphereRec * sp, float radius, int *dotCnt
,
int stopDot, float *dotPtr, float *dotNormal, int *nDot)
{
float vdw = a_atom_info->vdw + radius;
float *v0 = coord + 3 * a;
int b, ok = true;
float *v = dotPtr + (*nDot) * 3;
float *n = NULL;
Vector3f *sp_dot = sp->dot;
if (dotNormal){
n = dotNormal + (*nDot) * 3;
}
for(b = 0; ok && b < sp->nDot; b++) {
float *sp_dot_b = (float*)(sp_dot + b);
int i;
int flag = true;
if (n){
n[0] = sp_dot_b[0]; n[1] = sp_dot_b[1]; n[2] = sp_dot_b[2];
}
v[0] = v0[0] + vdw * sp_dot_b[0];
v[1] = v0[1] + vdw * sp_dot_b[1];
v[2] = v0[2] + vdw * sp_dot_b[2];
i = *(MapLocusEStart(map, v));
if(i) {
int j = map->EList[i++];
while(ok && j >= 0) {
SurfaceJobAtomInfo *j_atom_info = atom_info + j;
if((!present) || present[j]) {
if(j != a) {
int skip_flag = false;
if(j_atom_info->vdw == a_atom_info->vdw) { /* handle singulariti
es */
float *v1 = coord + 3 * j;
if((v0[0] == v1[0]) && (v0[1] == v1[1]) && (v0[2] == v1[2])){
skip_flag = true;
}
}
if(!skip_flag)
if(within3f(coord + 3 * j, v, j_atom_info->vdw + radius)) {
flag = false;
break;
}
}
}
j = map->EList[i++];
ok &= !G->Interrupt;
}
}
if(ok && flag && (*dotCnt < stopDot)) {
(*dotCnt)++;
v += 3;
if (n)
n += 3;
(*nDot)++;
}
}
return ok;
}
static int SolventDotCircumscribeAroundVertex(PyMOLGlobals * G, SolventDot *I,
MapType *map, float *vdw, float dist, float *v0, float *v2, int circumscribe
,
SurfaceJobAtomInfo * atom_info, SurfaceJobAtomInfo *a_atom_info,
SurfaceJobAtomInfo *jj_atom_info, int *present, int a, int jj, float *coord,
float probe_radius, int *dotCnt, int stopDot)
{
int ok = true;
float vz[3], vx[3], vy[3], vp[3];
float tri_a = vdw[0], tri_b = vdw[2], tri_c = dist;
float tri_s = (tri_a + tri_b + tri_c) * 0.5F;
float area = (float) sqrt1f(tri_s * (tri_s - tri_a) *
(tri_s - tri_b) * (tri_s - tri_c));
float radius = (2 * area) / dist;
float adj = (float) sqrt1f(vdw[1] - radius * radius);
int b;
float *v = I->dot + I->nDot * 3;
float *n = I->dotNormal + I->nDot * 3;
subtract3f(v2, v0, vz);
get_system1f3f(vz, vx, vy);
copy3f(vz, vp);
scale3f(vp, adj, vp);
add3f(v0, vp, vp);
for(b = 0; ok && b <= circumscribe; b++) {
float xcos = (float) cos((b * 2 * cPI) / circumscribe);
float ysin = (float) sin((b * 2 * cPI) / circumscribe);
float xcosr = xcos * radius;
float ysinr = ysin * radius;
int flag = true, i;
v[0] = vp[0] + vx[0] * xcosr + vy[0] * ysinr;
v[1] = vp[1] + vx[1] * xcosr + vy[1] * ysinr;
v[2] = vp[2] + vx[2] * xcosr + vy[2] * ysinr;
i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
while(ok && j >= 0) {
SurfaceJobAtomInfo *j_atom_info = atom_info + j;
if((!present) || present[j])
if((j != a) && (j != jj)) {
int skip_flag = false;
if(a_atom_info->vdw == j_atom_info->vdw) { /* handle singularities *
/
float *v1 = coord + 3 * j;
if((v0[0] == v1[0]) && (v0[1] == v1[1]) && (v0[2] == v1[2]))
skip_flag = true;
}
if(jj_atom_info->vdw == j_atom_info->vdw) { /* handle singularities *
/
float *v1 = coord + 3 * j;
if((v2[0] == v1[0]) && (v2[1] == v1[1]) && (v2[2] == v1[2]))
skip_flag = true;
}
if(!skip_flag)
if(within3f(coord + 3 * j, v,j_atom_info->vdw + probe_radius)) {
flag = false;
break;
}
}
j = map->EList[i++];
ok &= !G->Interrupt;
}
}
if(ok && flag && (*dotCnt < stopDot)) {
float vt0[3], vt2[3];
subtract3f(v0, v, vt0);
subtract3f(v2, v, vt2);
normalize3f(vt0);
normalize3f(vt2);
add3f(vt0, vt2, n);
invert3f(n);
normalize3f(n);
/*
n[0] = vx[0] * xcos + vy[0] * ysin;
n[1] = vx[1] * xcos + vy[1] * ysin;
n[2] = vx[2] * xcos + vy[2] * ysin;
*/
I->dotCode[I->nDot] = 1; /* mark as exempt */
(*dotCnt)++;
v += 3;
n += 3;
I->nDot++;
}
}
return ok;
}
static int SolventDotMarkDotsWithinCutoff(PyMOLGlobals * G, SolventDot *I,
MapType *map, float *I_dot, int nDot, float *cavityDot, int *dot_flag, float
cutoff){
int ok = true, *p = dot_flag;
float *v = I->dot;
int a;
for(a = 0; ok && a < I->nDot; a++) {
int i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
while(j >= 0) {
if(within3f(cavityDot + (3 * j), v, cutoff)) {
*p = true;
break;
}
j = map->EList[i++];
}
}
v += 3;
p++;
if(G->Interrupt) {
ok = false;
}
}
return ok;
}
static void SolventDotSlideDotsAndInfo(PyMOLGlobals * G, SolventDot *I, int *dot
_flag, int flag_value){
float *v0 = I->dot;
float *n0 = I->dotNormal;
int *dc0 = I->dotCode;
int *p = dot_flag;
int c = I->nDot;
float *n = n0;
float *v = v0;
int *dc = dc0;
int a;
I->nDot = 0;
for(a = 0; a < c; a++) {
if(flag_value ? *(p++) : !*(p++)) {
*(v0++) = *(v++);
*(n0++) = *(n++);
*(v0++) = *(v++);
*(n0++) = *(n++);
*(v0++) = *(v++);
*(n0++) = *(n++);
*(dc0++) = *(dc++);
I->nDot++;
} else {
v += 3;
n += 3;
}
}
PRINTFD(G, FB_RepSurface)
" SolventDotNew-DEBUG: %d->%d\n", c, I->nDot ENDFD;
}
static int SolventDotMarkDotsWithinProbeRadius(PyMOLGlobals * G, SolventDot *I,
MapType *map, int cavity_cull, float probe_radius_plus, int *dot_flag, int *
flag){
int ok = true;
int *p = dot_flag;
float *v = I->dot;
int a;
for(a = 0; ok && a < I->nDot; a++) {
if(!dot_flag[a]) {
int i = *(MapLocusEStart(map, v));
int cnt = 0;
if(i && map->EList) {
int j = map->EList[i++];
while(j >= 0) {
if(j != a) {
if(within3f(I->dot + (3 * j), v, probe_radius_plus)) {
if(dot_flag[j]) {
*p = true;
(*flag) = true;
break;
}
cnt++;
if(cnt > cavity_cull) {
*p = true;
(*flag) = true;
break;
}
}
}
j = map->EList[i++];
}
}
}
v += 3;
p++;
ok &= !G->Interrupt;
}
ok &= !G->Interrupt;
return ok;
}
static SolventDot *SolventDotNew(PyMOLGlobals * G, static SolventDot *SolventDotNew(PyMOLGlobals * G,
float *coord, float *coord,
SurfaceJobAtomInfo * atom_info, SurfaceJobAtomInfo * atom_info,
float probe_radius, SphereRec * sp, float probe_radius, SphereRec * sp,
int *present, int *present,
int circumscribe, int surface_mode, int circumscribe, int surface_mode,
int surface_solvent, int cavity_cull, int surface_solvent, int cavity_cull,
int all_visible_flag, float max_vdw, int all_visible_flag, float max_vdw,
int cavity_mode, float cavity_radius, int cavity_mode, float cavity_radius,
float cavity_cutoff) float cavity_cutoff)
{ {
int ok = true; int ok = true;
int b;
float vdw;
float probe_radius_plus;
int maxDot = 0;
int stopDot; int stopDot;
int n_coord = VLAGetSize(atom_info); int n_coord = VLAGetSize(atom_info);
Vector3f *sp_dot = sp->dot;
OOCalloc(G, SolventDot); OOCalloc(G, SolventDot);
CHECKOK(ok, I); CHECKOK(ok, I);
/* printf("%p %p %p %f %p %p %p %d %d %d %d %d %f\n", /* printf("%p %p %p %f %p %p %p %d %d %d %d %d %f\n",
G, G,
coord, coord,
atom_info, atom_info,
probe_radius,sp, probe_radius,sp,
extent,present, extent,present,
circumscribe, surface_mode, circumscribe, surface_mode,
surface_solvent, cavity_cull, surface_solvent, cavity_cull,
skipping to change at line 4653 skipping to change at line 4770
I->dot = VLAlloc(float, (stopDot + 1) * 3); I->dot = VLAlloc(float, (stopDot + 1) * 3);
CHECKOK(ok, I->dot); CHECKOK(ok, I->dot);
if (ok){ if (ok){
I->dotNormal = VLAlloc(float, (stopDot + 1) * 3); I->dotNormal = VLAlloc(float, (stopDot + 1) * 3);
CHECKOK(ok, I->dotNormal); CHECKOK(ok, I->dotNormal);
} }
if (ok){ if (ok){
I->dotCode = VLACalloc(int, stopDot + 1); I->dotCode = VLACalloc(int, stopDot + 1);
CHECKOK(ok, I->dotCode); CHECKOK(ok, I->dotCode);
} }
probe_radius_plus = probe_radius * 1.5F;
I->nDot = 0; I->nDot = 0;
if (ok) { if (ok) {
int dotCnt = 0; int dotCnt = 0;
MapType *map = MapNewFlagged(G, max_vdw + probe_radius, coord, n_coord, NULL , present); MapType *map = MapNewFlagged(G, max_vdw + probe_radius, coord, n_coord, NULL , present);
CHECKOK(ok, map); CHECKOK(ok, map);
ok &= !G->Interrupt; ok &= !G->Interrupt;
if(map && ok) { if(map && ok) {
float *v = I->dot;
float *n = I->dotNormal;
int *dc = I->dotCode;
int maxCnt = 0;
ok &= MapSetupExpress(map); ok &= MapSetupExpress(map);
if (ok) { if (ok) {
int a; int a;
int skip_flag; int skip_flag;
SurfaceJobAtomInfo *a_atom_info = atom_info; SurfaceJobAtomInfo *a_atom_info = atom_info;
for(a = 0; ok && a < n_coord; a++) { for(a = 0; ok && a < n_coord; a++) {
OrthoBusyFast(G, a, n_coord * 5); OrthoBusyFast(G, a, n_coord * 5);
if((!present) || (present[a])) { if((!present) || (present[a])) {
int i;
float *v0 = coord + 3 * a;
vdw = a_atom_info->vdw + probe_radius;
skip_flag = false; skip_flag = false;
ok = SolventDotFilterOutSameXYZ(G, map, atom_info, a_atom_info, coord
i = *(MapLocusEStart(map, v0)); , a, present, &skip_flag);
if(i && map->EList) {
int j = map->EList[i++];
while(ok && j >= 0) {
SurfaceJobAtomInfo *j_atom_info = atom_info + j;
if(j > a) /* only check if this is atom trails */
if((!present) || present[j]) {
if(j_atom_info->vdw == a_atom_info->vdw) { /* handle
singularities */
float *v1 = coord + 3 * j;
if((v0[0] == v1[0]) && (v0[1] == v1[1]) && (v0[2] == v1[2]
))
skip_flag = true;
}
}
j = map->EList[i++];
ok &= !G->Interrupt;
}
}
if(ok && !skip_flag) { if(ok && !skip_flag) {
for(b = 0; ok && b < sp->nDot; b++) { ok = SolventDotGetDotsAroundVertexInSphere(G, I, map, atom_info, a_
float *sp_dot_b = (float*)(sp_dot + b); atom_info, coord, a, present, sp, probe_radius, &dotCnt, stopDot, I->dot, I->dot
int i; Normal, &I->nDot);
int flag = true;
v[0] = v0[0] + vdw * (n[0] = sp_dot_b[0]);
v[1] = v0[1] + vdw * (n[1] = sp_dot_b[1]);
v[2] = v0[2] + vdw * (n[2] = sp_dot_b[2]);
i = *(MapLocusEStart(map, v));
if(i) {
int j = map->EList[i++];
while(ok && j >= 0) {
SurfaceJobAtomInfo *j_atom_info = atom_info + j;
if((!present) || present[j]) {
if(j != a) {
skip_flag = false;
if(j_atom_info->vdw == a_atom_info->vdw) { /* handl
e singularities */
float *v1 = coord + 3 * j;
if((v0[0] == v1[0]) && (v0[1] == v1[1]) && (v0[2] == v
1[2]))
skip_flag = true;
}
if(!skip_flag)
if(within3f(coord + 3 * j, v, j_atom_info->vdw + probe
_radius)) {
flag = false;
break;
}
}
}
j = map->EList[i++];
ok &= !G->Interrupt;
}
}
if(ok && flag && (dotCnt < stopDot)) {
dotCnt++;
v += 3;
n += 3;
dc++;
I->nDot++;
}
}
}
if(dotCnt > maxCnt) {
maxCnt = dotCnt;
maxDot = I->nDot - 1;
} }
} }
a_atom_info++; a_atom_info++;
} }
} }
/* for each pair of proximal atoms, circumscribe a circle for their inters ection */ /* for each pair of proximal atoms, circumscribe a circle for their inters ection */
/* CGOReset(G->DebugCGO); */
if (ok) { if (ok) {
MapType *map2 = NULL; MapType *map2 = NULL;
if(circumscribe && (!surface_solvent)){ if(circumscribe && (!surface_solvent)){
map2 = MapNewFlagged(G, 2 * (max_vdw + probe_radius), coord, n_coord, NULL, present); map2 = MapNewFlagged(G, 2 * (max_vdw + probe_radius), coord, n_coord, NULL, present);
CHECKOK(ok, map2); CHECKOK(ok, map2);
} }
ok &= !G->Interrupt; ok &= !G->Interrupt;
if(ok && map2) { if(ok && map2) {
/* CGOBegin(G->DebugCGO,GL_LINES); */
int a; int a;
int skip_flag; int skip_flag;
SurfaceJobAtomInfo *a_atom_info = atom_info; SurfaceJobAtomInfo *a_atom_info = atom_info;
ok &= MapSetupExpress(map2); ok &= MapSetupExpress(map2);
for(a = 0; ok && a < n_coord; a++) { for(a = 0; ok && a < n_coord; a++) {
if((!present) || present[a]) { if((!present) || present[a]) {
int i;
float vdw2;
float *v0 = coord + 3 * a; float *v0 = coord + 3 * a;
vdw = a_atom_info->vdw + probe_radius;
vdw2 = vdw * vdw;
skip_flag = false; skip_flag = false;
i = *(MapLocusEStart(map2, v0)); ok = SolventDotFilterOutSameXYZ(G, map2, atom_info, a_atom_info, co
if(i) { ord, a, present, &skip_flag);
int j = map2->EList[i++];
while(ok && j >= 0) {
SurfaceJobAtomInfo *j_atom_info = atom_info + j;
if(j > a) /* only check if this is atom trails */
if((!present) || present[j]) {
if(j_atom_info->vdw == a_atom_info->vdw) { /* handle
singularities */
float *v2 = coord + 3 * j;
if((v0[0] == v2[0]) && (v0[1] == v2[1]) && (v0[2] == v2[
2]))
skip_flag = true;
}
}
j = map2->EList[i++];
ok &= !G->Interrupt;
}
}
if(ok && !skip_flag) { if(ok && !skip_flag) {
int ii = *(MapLocusEStart(map2, v0)); int ii = *(MapLocusEStart(map2, v0));
if(ii) { if(ii) {
int jj = map2->EList[ii++]; int jj = map2->EList[ii++];
while(jj >= 0) { float vdw[3];
vdw[0] = a_atom_info->vdw + probe_radius;
vdw[1] = vdw[0] * vdw[0];
while(ok && jj >= 0) {
SurfaceJobAtomInfo *jj_atom_info = atom_info + jj; SurfaceJobAtomInfo *jj_atom_info = atom_info + jj;
float dist; float dist;
if(jj > a) /* only check if this is atom trails */ if(jj > a) /* only check if this is atom trails */
if((!present) || present[jj]) { if((!present) || present[jj]) {
float vdw3 = jj_atom_info->vdw + probe_radius;
float *v2 = coord + 3 * jj; float *v2 = coord + 3 * jj;
vdw[2] = jj_atom_info->vdw + probe_radius;
dist = (float) diff3f(v0, v2); dist = (float) diff3f(v0, v2);
if((dist > R_SMALL4) && (dist < (vdw + vdw3))) { if((dist > R_SMALL4) && (dist < (vdw[0] + vdw[2]))) {
float vz[3], vx[3], vy[3], vp[3]; ok = SolventDotCircumscribeAroundVertex(G, I, map, vdw,
float tri_a = vdw, tri_b = vdw3, tri_c = dist; dist, v0, v2, circumscribe,
float tri_s = (tri_a + tri_b + tri_c) * 0.5F; atom_info, a_at
float area = (float) sqrt1f(tri_s * (tri_s - tri_a) * om_info, jj_atom_info,
(tri_s - tri_b) * (tri_s - present, a, jj,
tri_c)); coord, probe_radius, &dotCnt, stopDot);
float radius = (2 * area) / dist;
float adj = (float) sqrt1f(vdw2 - radius * radius);
subtract3f(v2, v0, vz);
get_system1f3f(vz, vx, vy);
copy3f(vz, vp);
scale3f(vp, adj, vp);
add3f(v0, vp, vp);
for(b = 0; ok && b <= circumscribe; b++) {
float xcos = (float) cos((b * 2 * cPI) / circumscrib
e);
float ysin = (float) sin((b * 2 * cPI) / circumscrib
e);
float xcosr = xcos * radius;
float ysinr = ysin * radius;
int flag = true;
v[0] = vp[0] + vx[0] * xcosr + vy[0] * ysinr;
v[1] = vp[1] + vx[1] * xcosr + vy[1] * ysinr;
v[2] = vp[2] + vx[2] * xcosr + vy[2] * ysinr;
i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
while(ok && j >= 0) {
SurfaceJobAtomInfo *j_atom_info = atom_info + j;
if((!present) || present[j])
if((j != a) && (j != jj)) {
skip_flag = false;
if(a_atom_info->vdw == j_atom_info->vdw) {
/* handle singularities */
float *v1 = coord + 3 * j;
if((v0[0] == v1[0]) &&
(v0[1] == v1[1]) && (v0[2] == v1[2]))
skip_flag = true;
}
if(jj_atom_info->vdw == j_atom_info->vdw) {
/* handle singularities */
float *v1 = coord + 3 * j;
if((v2[0] == v1[0]) &&
(v2[1] == v1[1]) && (v2[2] == v1[2]))
skip_flag = true;
}
if(!skip_flag)
if(within3f
(coord + 3 * j, v,
j_atom_info->vdw + probe_radius)) {
flag = false;
break;
}
}
j = map->EList[i++];
ok &= !G->Interrupt;
}
}
if(ok && flag && (dotCnt < stopDot)) {
float vt0[3], vt2[3];
subtract3f(v0, v, vt0);
subtract3f(v2, v, vt2);
normalize3f(vt0);
normalize3f(vt2);
add3f(vt0, vt2, n);
invert3f(n);
normalize3f(n);
/*
n[0] = vx[0] * xcos + vy[0] * ysin;
n[1] = vx[1] * xcos + vy[1] * ysin;
n[2] = vx[2] * xcos + vy[2] * ysin;
*/
*dc = 1; /* mark as exempt */
dotCnt++;
v += 3;
n += 3;
dc++;
I->nDot++;
}
}
} }
} }
jj = map2->EList[ii++]; jj = map2->EList[ii++];
} }
} }
} }
} }
a_atom_info++; a_atom_info++;
ok &= !G->Interrupt; ok &= !G->Interrupt;
} }
} }
MapFree(map2); MapFree(map2);
} }
} }
MapFree(map); MapFree(map);
/* CGOEnd(G->DebugCGO); */
} }
if(ok && cavity_mode) { if(ok && cavity_mode) {
int nCavityDot = 0; int nCavityDot = 0;
int dotCnt = 0; int dotCnt = 0;
float *cavityDot = VLAlloc(float, (stopDot + 1) * 3); float *cavityDot = VLAlloc(float, (stopDot + 1) * 3);
CHECKOK(ok, cavityDot); CHECKOK(ok, cavityDot);
if(cavity_radius<0.0F) { if(cavity_radius<0.0F) {
cavity_radius = - probe_radius * cavity_radius; cavity_radius = - probe_radius * cavity_radius;
} }
if(cavity_cutoff<0.0F) { if(cavity_cutoff<0.0F) {
cavity_cutoff = cavity_radius - cavity_cutoff * probe_radius; cavity_cutoff = cavity_radius - cavity_cutoff * probe_radius;
} }
{ {
MapType *map = MapNewFlagged(G, max_vdw + cavity_radius, coord, n_coord, N ULL, present); MapType *map = MapNewFlagged(G, max_vdw + cavity_radius, coord, n_coord, N ULL, present);
CHECKOK(ok, map); CHECKOK(ok, map);
if(G->Interrupt) if(G->Interrupt)
ok = false; ok = false;
if(ok && map) { if(ok && map) {
float *v = cavityDot;
ok &= MapSetupExpress(map); ok &= MapSetupExpress(map);
if (ok) { if (ok) {
int a; int a;
int skip_flag; int skip_flag;
SurfaceJobAtomInfo *a_atom_info = atom_info; SurfaceJobAtomInfo *a_atom_info = atom_info;
for(a = 0; a < n_coord; a++) { for(a = 0; a < n_coord; a++) {
if((!present) || (present[a])) { if((!present) || (present[a])) {
int i;
float *v0 = coord + 3 * a;
vdw = a_atom_info->vdw + cavity_radius;
skip_flag = false; skip_flag = false;
i = *(MapLocusEStart(map, v0)); ok = SolventDotFilterOutSameXYZ(G, map, atom_info, a_atom_info, coo
if(i && map->EList) { rd, a, present, &skip_flag);
int j = map->EList[i++]; if(ok && !skip_flag) {
while(j >= 0) { ok = SolventDotGetDotsAroundVertexInSphere(G, I, map, atom_info,
SurfaceJobAtomInfo *j_atom_info = atom_info + j; a_atom_info, coord, a, present, sp, cavity_radius, &dotCnt, stopDot, cavityDot,
if(j > a) /* only check if this is atom trails */ NULL, &nCavityDot);
if((!present) || present[j]) {
if(j_atom_info->vdw == a_atom_info->vdw) { /* handl
e singularities */
float *v1 = coord + 3 * j;
if((v0[0] == v1[0]) && (v0[1] == v1[1]) && (v0[2] == v1[
2]))
skip_flag = true;
}
}
j = map->EList[i++];
}
}
if(!skip_flag) {
for(b = 0; b < sp->nDot; b++) {
float *sp_dot_b = (float*)(sp_dot + b);
int i;
int flag = true;
v[0] = v0[0] + vdw * (sp_dot_b[0]);
v[1] = v0[1] + vdw * (sp_dot_b[1]);
v[2] = v0[2] + vdw * (sp_dot_b[2]);
i = *(MapLocusEStart(map, v));
if(i) {
int j = map->EList[i++];
while(j >= 0) {
SurfaceJobAtomInfo *j_atom_info = atom_info + j;
if((!present) || present[j]) {
if(j != a) {
skip_flag = false;
if(j_atom_info->vdw == a_atom_info->vdw) {
/* handle singularities */
float *v1 = coord + 3 * j;
if((v0[0] == v1[0]) && (v0[1] == v1[1]) && (v0[2] ==
v1[2]))
skip_flag = true;
}
if(!skip_flag) {
if(within3f(coord + 3 * j, v, j_atom_info->vdw + cav
ity_radius)) {
flag = false;
break;
}
}
}
}
j = map->EList[i++];
}
}
if(flag && (dotCnt < stopDot)) {
v += 3;
nCavityDot++;
dotCnt++;
}
}
} }
} }
a_atom_info++; a_atom_info++;
} }
} }
} }
MapFree(map); MapFree(map);
} }
{ {
int *dot_flag = Calloc(int, I->nDot); int *dot_flag = Calloc(int, I->nDot);
ErrChkPtr(G, dot_flag); ErrChkPtr(G, dot_flag);
{ {
MapType *map = MapNew(G, cavity_cutoff, cavityDot, nCavityDot, NULL); MapType *map = MapNew(G, cavity_cutoff, cavityDot, nCavityDot, NULL);
if(map) { if(map) {
MapSetupExpress(map); MapSetupExpress(map);
{ ok = SolventDotMarkDotsWithinCutoff(G, I, map, I->dot, I->nDot, cavityD
int *p = dot_flag; ot, dot_flag, cavity_cutoff);
float *v = I->dot;
int a;
for(a = 0; a < I->nDot; a++) {
int i = *(MapLocusEStart(map, v));
if(i && map->EList) {
int j = map->EList[i++];
while(j >= 0) {
if(within3f(cavityDot + (3 * j), v, cavity_cutoff)) {
*p = true;
break;
}
j = map->EList[i++];
}
}
v += 3;
p++;
if(G->Interrupt) {
ok = false;
break;
}
}
}
} }
MapFree(map); MapFree(map);
} }
SolventDotSlideDotsAndInfo(G, I, dot_flag, false);
{
float *v0 = I->dot;
float *n0 = I->dotNormal;
int *dc0 = I->dotCode;
int *p = dot_flag;
int c = I->nDot;
float *n = n0;
float *v = v0;
int *dc = dc0;
int a;
I->nDot = 0;
for(a = 0; a < c; a++) {
if(!*(p++)) {
*(v0++) = *(v++);
*(n0++) = *(n++);
*(v0++) = *(v++);
*(n0++) = *(n++);
*(v0++) = *(v++);
*(n0++) = *(n++);
*(dc0++) = *(dc++);
I->nDot++;
} else {
v += 3;
n += 3;
}
}
PRINTFD(G, FB_RepSurface)
" SolventDotNew-DEBUG: %d->%d\n", c, I->nDot ENDFD;
}
FreeP(dot_flag); FreeP(dot_flag);
} }
VLAFreeP(cavityDot); VLAFreeP(cavityDot);
} }
if(ok && (cavity_mode != 1) && (cavity_cull > 0) && if(ok && (cavity_mode != 1) && (cavity_cull > 0) &&
(probe_radius > 0.75F) && (!surface_solvent)) { (probe_radius > 0.75F) && (!surface_solvent)) {
int *dot_flag = Calloc(int, I->nDot); int *dot_flag = Calloc(int, I->nDot);
float probe_radius_plus;
probe_radius_plus = probe_radius * 1.5F;
ErrChkPtr(G, dot_flag); ErrChkPtr(G, dot_flag);
{ {
MapType *map = MapNew(G, probe_radius_plus, I->dot, I->nDot, NULL); MapType *map = MapNew(G, probe_radius_plus, I->dot, I->nDot, NULL);
if(map) { if(map) {
int flag = true; int flag = true;
MapSetupExpress(map); MapSetupExpress(map);
while(ok && flag) { while(ok && flag) {
int *p = dot_flag;
float *v = I->dot;
int a;
flag = false; flag = false;
for(a = 0; ok && a < I->nDot; a++) { ok = SolventDotMarkDotsWithinProbeRadius(G, I, map, cavity_cull, probe_
if(!dot_flag[a]) { radius_plus, dot_flag, &flag);
int i = *(MapLocusEStart(map, v));
int cnt = 0;
if(i && map->EList) {
int j = map->EList[i++];
while(j >= 0) {
if(j != a) {
if(within3f(I->dot + (3 * j), v, probe_radius_plus)) {
if(dot_flag[j]) {
*p = true;
flag = true;
break;
}
cnt++;
if(cnt > cavity_cull) {
*p = true;
flag = true;
break;
}
}
}
j = map->EList[i++];
}
}
}
v += 3;
p++;
ok &= !G->Interrupt;
}
ok &= !G->Interrupt;
} }
} }
MapFree(map); MapFree(map);
} }
if (ok) { if (ok) {
float *v0 = I->dot; SolventDotSlideDotsAndInfo(G, I, dot_flag, true);
float *n0 = I->dotNormal;
int *dc0 = I->dotCode;
int *p = dot_flag;
int c = I->nDot;
float *n = n0;
float *v = v0;
int *dc = dc0;
int a;
I->nDot = 0;
for(a = 0; a < c; a++) {
if(*(p++)) {
*(v0++) = *(v++);
*(n0++) = *(n++);
*(v0++) = *(v++);
*(n0++) = *(n++);
*(v0++) = *(v++);
*(n0++) = *(n++);
*(dc0++) = *(dc++);
I->nDot++;
} else {
v += 3;
n += 3;
}
}
PRINTFD(G, FB_RepSurface)
" SolventDotNew-DEBUG: %d->%d\n", c, I->nDot ENDFD;
} }
FreeP(dot_flag); FreeP(dot_flag);
} }
if(!ok) { if(!ok) {
SolventDotFree(I); SolventDotFree(I);
I = NULL; I = NULL;
} }
return I; return I;
} }
 End of changes. 241 change blocks. 
2711 lines changed or deleted 2459 lines changed or added

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