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++) = α | *(tb++) = α | |||
*(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++) = α | *(tb++) = α | |||
*(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++) = α | ||||
*(tb++) = vc + (*t) * 3; | ||||
*(tb++) = vn + (*t) * 3; | ||||
*(tb++) = v + (*t) * 3; | ||||
if(va) | ||||
*(tb++) = va + (*(t + 1)); | ||||
else | ||||
*(tb++) = α | ||||
*(tb++) = vc + (*(t + 1)) * 3; | ||||
*(tb++) = vn + (*(t + 1)) * 3; | ||||
*(tb++) = v + (*(t + 1)) * 3; | ||||
if(va) | ||||
*(tb++) = va + (*(t + 2)); | ||||
else | ||||
*(tb++) = α | ||||
*(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 |