RepCartoon.cpp (pymol-v2.1.0.tar.bz2) | : | RepCartoon.cpp (pymol-open-source-2.2.0) | ||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
F* ------------------------------------------------------------------- | F* ------------------------------------------------------------------- | |||
G* Please see the accompanying LICENSE file for further information. | G* Please see the accompanying LICENSE file for further information. | |||
H* ------------------------------------------------------------------- | H* ------------------------------------------------------------------- | |||
I* Additional authors of this source file include: | I* Additional authors of this source file include: | |||
-* Cameron Mura | -* Cameron Mura | |||
-* | -* | |||
-* | -* | |||
Z* ------------------------------------------------------------------- | Z* ------------------------------------------------------------------- | |||
*/ | */ | |||
#include <set> | ||||
#include"os_predef.h" | #include"os_predef.h" | |||
#include"os_std.h" | #include"os_std.h" | |||
#include"os_gl.h" | #include"os_gl.h" | |||
#include"Base.h" | #include"Base.h" | |||
#include"OOMac.h" | #include"OOMac.h" | |||
#include"RepCartoon.h" | #include"RepCartoon.h" | |||
#include"Color.h" | #include"Color.h" | |||
#include"Setting.h" | #include"Setting.h" | |||
#include"Word.h" | #include"Word.h" | |||
skipping to change at line 55 | skipping to change at line 57 | |||
void setCCOut(int c) { cc_out = c; } | void setCCOut(int c) { cc_out = c; } | |||
// legacy | // legacy | |||
void operator= (int c) { cc_in = c; } | void operator= (int c) { cc_in = c; } | |||
operator int() const { return cc_in; } | operator int() const { return cc_in; } | |||
bool operator== (const CCInOut &other) const { return cc_in == other.cc_in; } | bool operator== (const CCInOut &other) const { return cc_in == other.cc_in; } | |||
}; | }; | |||
typedef struct RepCartoon { | typedef struct RepCartoon { | |||
Rep R; /* must be first! */ | Rep R; /* must be first! */ | |||
CGO *ray, *std, *preshader, *pickingCGO; | CGO *ray, *std, *preshader; | |||
char *LastVisib; | char *LastVisib; | |||
unsigned char renderWithShaders, hasTransparency; | unsigned char renderWithShaders, hasTransparency; | |||
} RepCartoon; | } RepCartoon; | |||
#include"ObjectMolecule.h" | #include"ObjectMolecule.h" | |||
#define ESCAPE_MAX 500 | #define ESCAPE_MAX 500 | |||
void RepCartoonFree(RepCartoon * I); | void RepCartoonFree(RepCartoon * I); | |||
void RepCartoonFree(RepCartoon * I) | void RepCartoonFree(RepCartoon * I) | |||
{ | { | |||
if (I->ray != I->preshader) | if (I->ray != I->preshader) | |||
CGOFree(I->preshader); | CGOFree(I->preshader); | |||
CGOFree(I->ray); | CGOFree(I->ray); | |||
if(I->pickingCGO && (I->pickingCGO != I->std)) | ||||
CGOFree(I->pickingCGO); | ||||
CGOFree(I->std); | CGOFree(I->std); | |||
FreeP(I->LastVisib); | FreeP(I->LastVisib); | |||
RepPurge(&I->R); | RepPurge(&I->R); | |||
OOFreeP(I); | OOFreeP(I); | |||
} | } | |||
/* | ||||
* CGOAddTwoSidedBackfaceSpecialOps: this function takes in a CGO, | ||||
* and outputs a CGO with that CGO wrapped with the two operations: | ||||
* enabling and disabling back faces if two_sided_lighting is not set | ||||
* (i.e., the CGOSpecial operations, see below) | ||||
* | ||||
*/ | ||||
static | ||||
CGO *CGOAddTwoSidedBackfaceSpecialOps(PyMOLGlobals *G, CGO *cgo){ | ||||
CGO *tmpCGO = CGONew(G); | ||||
CGOSpecial(tmpCGO, ENABLE_BACK_FACES_IF_NOT_TWO_SIDED); | ||||
CGOAppendNoStop(tmpCGO, cgo); | ||||
CGOSpecial(tmpCGO, DISABLE_BACK_FACES_IF_NOT_TWO_SIDED); | ||||
CGOStop(tmpCGO); | ||||
tmpCGO->render_alpha = cgo->render_alpha; | ||||
CGOFreeWithoutVBOs(cgo); | ||||
return tmpCGO; | ||||
} | ||||
static int RepCartoonCGOGenerate(RepCartoon * I, RenderInfo * info) | ||||
{ | ||||
PyMOLGlobals *G = I->R.G; | ||||
int ok = true; | ||||
int use_shaders, has_cylinders_to_optimize; | ||||
float alpha = 1.0F - SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting, cSet | ||||
ting_cartoon_transparency); | ||||
use_shaders = SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_ | ||||
b(G, cSetting_cartoon_use_shader); | ||||
has_cylinders_to_optimize = G->ShaderMgr->Get_CylinderShader(info->pass, 0) && | ||||
SettingGetGlobal_i(G, cSetting_cartoon_nucleic_aci | ||||
d_as_cylinders) && | ||||
SettingGetGlobal_b(G, cSetting_render_as_cylinders | ||||
) && | ||||
CGOHasCylinderOperations(I->preshader); | ||||
if (I->std && | ||||
(use_shaders ^ I->renderWithShaders)){ | ||||
// if renderWithShaders doesn't match use_shader, clear CGO and re-generate | ||||
CGOFree(I->std); | ||||
I->std = 0; | ||||
} | ||||
I->hasTransparency = 0; | ||||
if (use_shaders){ | ||||
CGO *convertcgo = NULL, *tmpCGO = NULL, *tmp2CGO = NULL; | ||||
if ((alpha < 1.f) && (SettingGetGlobal_i(G, cSetting_transparency_mode) != 3 | ||||
)){ | ||||
// some transparency | ||||
const float *color; | ||||
float colorWithA[4]; | ||||
CGO *convertcgo2; | ||||
convertcgo2 = CGOSimplify(I->preshader, 0) ; | ||||
convertcgo = CGOCombineBeginEnd(convertcgo2, 0); | ||||
CGOFree(convertcgo2); | ||||
CHECKOK(ok, convertcgo); | ||||
color = ColorGet(G, I->R.obj->Color); | ||||
copy3f(color, colorWithA); | ||||
colorWithA[3] = alpha; | ||||
tmpCGO = CGOOptimizeToVBOIndexedWithColorEmbedTransparentInfo(convertcgo, | ||||
0, NULL, true); | ||||
CGOStop(tmpCGO); | ||||
CGOFree(convertcgo); | ||||
tmp2CGO = CGONew(G); | ||||
CGOEnable(tmp2CGO, GL_BACK_FACE_CULLING); | ||||
CGOAppendNoStop(tmp2CGO, tmpCGO); | ||||
CGODisable(tmp2CGO, GL_BACK_FACE_CULLING); | ||||
CGOStop(tmp2CGO); | ||||
CGOFreeWithoutVBOs(tmpCGO); | ||||
I->std = tmp2CGO; | ||||
I->hasTransparency = 1; | ||||
} else { | ||||
CGO *leftOverCGO = NULL; | ||||
if (has_cylinders_to_optimize && G->ShaderMgr->Get_CylinderShader(info->pa | ||||
ss, 0)){ | ||||
/* Optimize Cylinders into Shader operation */ | ||||
CGO *tmpCGO = CGONew(G); | ||||
leftOverCGO = CGONew(G); | ||||
CGOEnable(tmpCGO, GL_CYLINDER_SHADER); | ||||
CGOFilterOutCylinderOperationsInto(I->preshader, leftOverCGO); | ||||
convertcgo = CGOConvertShaderCylindersToCylinderShader(I->preshader, tmp | ||||
CGO); | ||||
CGOAppendNoStop(tmpCGO, convertcgo); | ||||
CGODisable(tmpCGO, GL_CYLINDER_SHADER); | ||||
CGOStop(tmpCGO); | ||||
CGOFreeWithoutVBOs(convertcgo); | ||||
convertcgo = tmpCGO; | ||||
convertcgo->use_shader = true; | ||||
} | ||||
if (!leftOverCGO){ | ||||
leftOverCGO = I->preshader; | ||||
convertcgo = CGONew(G); | ||||
} | ||||
bool has_spheres_to_optimize = CGOHasSphereOperations(leftOverCGO); | ||||
if (has_spheres_to_optimize){ | ||||
/* Optimize spheres and putting them into convertcgo as a shader CGO ope | ||||
ration */ | ||||
CGO *sphereVBOs = NULL, *leftOverAfterSpheresCGO = NULL; | ||||
leftOverAfterSpheresCGO = CGONew(G); | ||||
sphereVBOs = CGOOptimizeSpheresToVBONonIndexed(leftOverCGO, 0, true, lef | ||||
tOverAfterSpheresCGO); | ||||
if (sphereVBOs){ | ||||
ok &= CGOAppendNoStop(convertcgo, sphereVBOs); | ||||
CGOFreeWithoutVBOs(sphereVBOs); | ||||
} else { | ||||
CGOFree(leftOverAfterSpheresCGO); | ||||
} | ||||
if (leftOverCGO!=I->ray && leftOverCGO!=I->preshader){ | ||||
CGOFree(leftOverCGO); | ||||
} | ||||
if (leftOverAfterSpheresCGO) | ||||
leftOverCGO = leftOverAfterSpheresCGO; | ||||
} | ||||
/* For the rest of the primitives that exist, simplify them into Geometry | ||||
* (should probably be no more, but do this anyway) */ | ||||
CGO *leftOverCGOSimplified = NULL, *leftOverCGOCombined; | ||||
leftOverCGOSimplified = CGOSimplify(leftOverCGO, 0); | ||||
CHECKOK(ok, leftOverCGOSimplified); | ||||
leftOverCGOCombined = CGOCombineBeginEnd(leftOverCGOSimplified, 0); | ||||
CGOFree(leftOverCGOSimplified); | ||||
if (leftOverCGO!=I->ray && leftOverCGO!=I->preshader){ | ||||
CGOFree(leftOverCGO); | ||||
} | ||||
// Convert all DrawArrays and Geometry to VBOs | ||||
if (ok) | ||||
tmpCGO = CGOOptimizeToVBONotIndexed(leftOverCGOCombined, 0); | ||||
CHECKOK(ok, tmpCGO); | ||||
CGOFree(leftOverCGOCombined); | ||||
if (ok) | ||||
ok &= CGOAppend(convertcgo, tmpCGO); | ||||
CGOFreeWithoutVBOs(tmpCGO); | ||||
tmpCGO = NULL; | ||||
I->std = CGOAddTwoSidedBackfaceSpecialOps(G, convertcgo); | ||||
} | ||||
} else { | ||||
if (ok){ | ||||
if (alpha < 1.f){ | ||||
CGO *tmpCGO = NULL; | ||||
tmpCGO = CGOConvertTrianglesToAlpha(I->preshader); | ||||
I->std = tmpCGO; | ||||
I->std->render_alpha = 1; // CGORenderGL should call CGOSetZVector/CGORe | ||||
nderGLAlpha only | ||||
} else { | ||||
I->std = CGOSimplify(I->preshader, 0); | ||||
CHECKOK(ok, I->std); | ||||
} | ||||
I->std = CGOAddTwoSidedBackfaceSpecialOps(G, I->std); | ||||
} | ||||
} | ||||
if(I->preshader && (I->ray!=I->preshader)){ | ||||
CGOFree(I->preshader); | ||||
} | ||||
I->preshader = NULL; | ||||
I->renderWithShaders = use_shaders; | ||||
return ok; | ||||
} | ||||
static void RepCartoonRender(RepCartoon * I, RenderInfo * info) | static void RepCartoonRender(RepCartoon * I, RenderInfo * info) | |||
{ | { | |||
CRay *ray = info->ray; | CRay *ray = info->ray; | |||
Picking **pick = info->pick; | Picking **pick = info->pick; | |||
PyMOLGlobals *G = I->R.G; | PyMOLGlobals *G = I->R.G; | |||
int ok = true; | int ok = true; | |||
if (!ray && I->preshader){ | if (!ray && I->preshader) { | |||
int use_shaders, cartoon_use_shader, has_cylinders_to_optimize; | ok &= RepCartoonCGOGenerate(I, info); | |||
use_shaders = SettingGetGlobal_b(G, cSetting_use_shaders); | ||||
cartoon_use_shader = SettingGetGlobal_b(G, cSetting_cartoon_use_shader); | ||||
has_cylinders_to_optimize = CShaderPrg_Get_CylinderShader_NoSet(G) && Settin | ||||
gGetGlobal_i(G, cSetting_cartoon_nucleic_acid_as_cylinders) && SettingGetGlobal_ | ||||
b(G, cSetting_render_as_cylinders) ; | ||||
if (use_shaders && cartoon_use_shader){ | ||||
CGO *convertcgo = NULL, *tmpCGO = NULL; | ||||
if (has_cylinders_to_optimize){ | ||||
CGO *leftOverCGO = CGONew(G), *leftOverCGOSimplified = NULL, *sphereVBOs | ||||
= NULL, *leftOverAfterSpheresCGO = NULL; | ||||
CHECKOK(ok, leftOverCGO); | ||||
/* Optimize Cylinders into Shader operation */ | ||||
if (CShaderPrg_Get_CylinderShader_NoSet(G)){ | ||||
convertcgo = CGOOptimizeGLSLCylindersToVBOIndexedWithLeftOver(I->presha | ||||
der, 0, leftOverCGO); | ||||
} | ||||
if (!convertcgo){ | ||||
convertcgo = CGONew(G); | ||||
CHECKOK(ok, convertcgo); | ||||
leftOverCGO = I->preshader; | ||||
I->preshader = NULL; | ||||
} else if (ok) { | ||||
ok &= CGOStop(leftOverCGO); | ||||
} | ||||
/* Optimize spheres and putting them into convertcgo as a shader CGO oper | ||||
ation */ | ||||
if (ok) | ||||
leftOverAfterSpheresCGO = CGONew(G); | ||||
CHECKOK(ok, leftOverAfterSpheresCGO); | ||||
if (ok) | ||||
sphereVBOs = CGOOptimizeSpheresToVBONonIndexedImpl(leftOverCGO, 0, left | ||||
OverAfterSpheresCGO); | ||||
if (ok && sphereVBOs){ | ||||
ok &= CGOStop(leftOverAfterSpheresCGO); | ||||
if (leftOverCGO!=I->ray){ | ||||
CGOFree(leftOverCGO); | ||||
leftOverCGO = NULL; | ||||
} | ||||
if (ok && sphereVBOs) | ||||
ok &= CGOAppend(convertcgo, sphereVBOs); | ||||
CGOFreeWithoutVBOs(sphereVBOs); | ||||
sphereVBOs = NULL; | ||||
} else { | ||||
if (leftOverAfterSpheresCGO) | ||||
CGOFree(leftOverAfterSpheresCGO); | ||||
leftOverAfterSpheresCGO = leftOverCGO; | ||||
} | ||||
/* For the rest of the primitives that exist, simplify them into Geometry | ||||
* (should probably be no more, but do this anyway) */ | ||||
if (ok) | ||||
leftOverCGOSimplified = CGOSimplify(leftOverAfterSpheresCGO, 0); | ||||
CHECKOK(ok, leftOverCGOSimplified); | ||||
if (leftOverAfterSpheresCGO!=I->ray){ | ||||
CGOFree(leftOverAfterSpheresCGO); | ||||
leftOverAfterSpheresCGO = NULL; | ||||
} | ||||
/* Convert all DrawArrays and Geometry to VBOs */ | ||||
if (ok) | ||||
tmpCGO = CGOOptimizeToVBONotIndexed(leftOverCGOSimplified, 0); | ||||
CHECKOK(ok, tmpCGO); | ||||
CGOFree(leftOverCGOSimplified); | ||||
leftOverCGOSimplified = NULL; | ||||
if (ok) | ||||
ok &= CGOAppend(convertcgo, tmpCGO); | ||||
CGOFreeWithoutVBOs(tmpCGO); | ||||
tmpCGO = NULL; | ||||
I->std = convertcgo; | ||||
} else if (ok){ | ||||
convertcgo = CGOSimplify(I->preshader, 0); | ||||
CHECKOK(ok, convertcgo); | ||||
if (ok) | ||||
tmpCGO = CGOOptimizeToVBONotIndexed(convertcgo, 0); | ||||
CHECKOK(ok, tmpCGO); | ||||
CGOFree(convertcgo); | ||||
convertcgo = NULL; | ||||
I->std = tmpCGO; | ||||
} | ||||
} else if (ok){ | ||||
I->std = CGOSimplify(I->preshader, 0); | ||||
CHECKOK(ok, I->std); | ||||
} | ||||
if(I->preshader && (I->ray!=I->preshader)){ | ||||
CGOFree(I->preshader); | ||||
} | ||||
I->preshader = NULL; | ||||
} | } | |||
if(ray) { | if(ray) { | |||
#ifndef _PYMOL_NO_RAY | #ifndef _PYMOL_NO_RAY | |||
int try_std = false; | int try_std = false; | |||
PRINTFD(G, FB_RepCartoon) | PRINTFD(G, FB_RepCartoon) | |||
" RepCartoonRender: rendering raytracable...\n" ENDFD; | " RepCartoonRender: rendering raytracable...\n" ENDFD; | |||
if(I->ray){ | if(I->ray){ | |||
int rok = CGORenderRay(I->ray, ray, NULL, I->R.cs->Setting, I->R.obj->Sett ing); | int rok = CGORenderRay(I->ray, ray, info, NULL, NULL, I->R.cs->Setting, I- >R.obj->Setting); | |||
if (!rok){ | if (!rok){ | |||
if (I->ray == I->preshader) | if (I->ray == I->preshader) | |||
I->preshader = NULL; | I->preshader = NULL; | |||
CGOFree(I->ray); | CGOFree(I->ray); | |||
try_std = true; | try_std = true; | |||
} | } | |||
} else { | } else { | |||
try_std = true; | try_std = true; | |||
} | } | |||
if(try_std && I->std){ | if(try_std && I->std){ | |||
ok &= CGORenderRay(I->std, ray, NULL, I->R.cs->Setting, I->R.obj->Setting) ; | ok &= CGORenderRay(I->std, ray, info, NULL, NULL, I->R.cs->Setting, I->R.o bj->Setting); | |||
if (!ok){ | if (!ok){ | |||
CGOFree(I->std); | CGOFree(I->std); | |||
} | } | |||
} | } | |||
#endif | #endif | |||
} else if(G->HaveGUI && G->ValidContext) { | } else if(G->HaveGUI && G->ValidContext) { | |||
int use_shader; | int use_shader; | |||
use_shader = SettingGetGlobal_b(G, cSetting_cartoon_use_shader) && | use_shader = SettingGetGlobal_b(G, cSetting_cartoon_use_shader) && | |||
SettingGetGlobal_b(G, cSetting_use_shaders) | SettingGetGlobal_b(G, cSetting_use_shaders); | |||
&& !pick; /* should not use shaders for picking (for now) */ | ||||
if(pick) { | if(pick) { | |||
if(I->pickingCGO) { | if(I->std) { | |||
I->pickingCGO->use_shader = use_shader; | I->std->use_shader = use_shader; | |||
CGORenderGLPicking(I->pickingCGO, pick, &I->R.context, | CGORenderGLPicking(I->std, info, &I->R.context, | |||
I->R.cs->Setting, I->R.obj->Setting); | I->R.cs->Setting, I->R.obj->Setting); | |||
} | } | |||
} else { | } else { | |||
PRINTFD(G, FB_RepCartoon) | PRINTFD(G, FB_RepCartoon) | |||
" RepCartoonRender: rendering GL...\n" ENDFD; | " RepCartoonRender: rendering GL...\n" ENDFD; | |||
if(ok && I->std){ | if(ok && I->std){ | |||
I->std->use_shader = use_shader; | I->std->use_shader = use_shader; | |||
I->std->enable_shaders = true; | ||||
CGORenderGL(I->std, NULL, I->R.cs->Setting, I->R.obj->Setting, info, & I->R); | CGORenderGL(I->std, NULL, I->R.cs->Setting, I->R.obj->Setting, info, & I->R); | |||
} | } | |||
} | } | |||
} | } | |||
if (!ok || !CGOHasOperationsOfType(I->ray, 0)){ | if (!ok || !I->ray || !CGOHasOperations(I->ray)){ | |||
if (I->ray == I->preshader) | if (I->ray == I->preshader) | |||
I->preshader = NULL; | I->preshader = NULL; | |||
CGOFree(I->ray); | CGOFree(I->ray); | |||
CGOFree(I->std); | CGOFree(I->std); | |||
I->R.fInvalidate(&I->R, I->R.cs, cRepInvPurge); | I->R.fInvalidate(&I->R, I->R.cs, cRepInvPurge); | |||
I->R.cs->Active[cRepCartoon] = false; | I->R.cs->Active[cRepCartoon] = false; | |||
} | } | |||
} | } | |||
#define NUCLEIC_NORMAL0 "C2" | #define NUCLEIC_NORMAL0 "C2" | |||
skipping to change at line 277 | skipping to change at line 345 | |||
return false; | return false; | |||
if (!(ai1->visRep & (cRepLineBit | cRepCylBit | cRepSphereBit))) | if (!(ai1->visRep & (cRepLineBit | cRepCylBit | cRepSphereBit))) | |||
return true; | return true; | |||
return !( | return !( | |||
AtomSettingGetWD(G, ai1, cSetting_cartoon_side_chain_helper, sc_helper) || | AtomSettingGetWD(G, ai1, cSetting_cartoon_side_chain_helper, sc_helper) || | |||
AtomSettingGetWD(G, ai2, cSetting_cartoon_side_chain_helper, sc_helper)); | AtomSettingGetWD(G, ai2, cSetting_cartoon_side_chain_helper, sc_helper)); | |||
} | } | |||
/* | ||||
* depth-first neighbor search for nucleic acid atom | ||||
* | ||||
* nuc_flag: NAtom-length boolean nucleic acid flags array | ||||
* neighbor: Neighbor data structure | ||||
* atm: atom index | ||||
* max_depth: maximum search depth | ||||
* seen: set of visited atom indices (read/write) | ||||
* | ||||
* Return: true if any nucleic acid atom found within max_depth radius | ||||
*/ | ||||
static | ||||
bool has_nuc_neighbor( | ||||
const int * nuc_flag, | ||||
const int * neighbor, | ||||
const int atm, | ||||
const int max_depth, | ||||
std::set<int> &seen) | ||||
{ | ||||
int atm_neighbor, tmp; | ||||
ITERNEIGHBORATOMS(neighbor, atm, atm_neighbor, tmp) { | ||||
if (nuc_flag[atm_neighbor]) | ||||
return true; | ||||
if (seen.count(atm_neighbor)) | ||||
continue; | ||||
seen.insert(atm_neighbor); | ||||
if (max_depth > 1 && | ||||
has_nuc_neighbor(nuc_flag, neighbor, atm_neighbor, max_depth - 1, seen)) | ||||
return true; | ||||
} | ||||
return false; | ||||
} | ||||
/* atix must contain n_atom + 1 elements, with the first atom repeated at the en d */ | /* atix must contain n_atom + 1 elements, with the first atom repeated at the en d */ | |||
static void do_ring(PyMOLGlobals * G, nuc_acid_data *ndata, bool is_picking, int n_atom, | static void do_ring(PyMOLGlobals * G, nuc_acid_data *ndata, int n_atom, | |||
int *atix, ObjectMolecule * obj, | int *atix, ObjectMolecule * obj, | |||
CoordSet * cs, float ring_width, CGO * cgo, int ring_color, | CoordSet * cs, float ring_width, CGO * cgo, int ring_color, | |||
float ladder_radius, int ladder_color, int ladder_mode, | float ladder_radius, int ladder_color, int ladder_mode, | |||
int sc_helper, | int sc_helper, | |||
float ring_alpha, float alpha, int *marked, float *moved, | float ring_alpha, float alpha, int *marked, float *moved, | |||
float ring_radius) | float ring_radius) | |||
{ | { | |||
float *v_i[MAX_RING_ATOM]; | float *v_i[MAX_RING_ATOM]; | |||
float *col[MAX_RING_ATOM]; | const float *col[MAX_RING_ATOM]; | |||
float n_up[MAX_RING_ATOM][3]; | float n_up[MAX_RING_ATOM][3]; | |||
float n_dn[MAX_RING_ATOM][3]; | float n_dn[MAX_RING_ATOM][3]; | |||
AtomInfoType *ai_i[MAX_RING_ATOM]; | AtomInfoType *ai_i[MAX_RING_ATOM]; | |||
int have_all = true; | int have_all = true; | |||
int all_marked = true; | int all_marked = true; | |||
AtomInfoType *ai; | AtomInfoType *ai; | |||
int have_C4 = -1; | int have_C4 = -1; | |||
int have_C4_prime = -1; | int have_C4_prime = -1; | |||
int have_C_number = -1; | int have_C_number = -1; | |||
int nf = false; | int nf = false; | |||
skipping to change at line 908 | skipping to change at line 1013 | |||
/* compute average coordinate and mark atoms so that ring is only drawn once */ | /* compute average coordinate and mark atoms so that ring is only drawn once */ | |||
zero3f(avg); | zero3f(avg); | |||
for(i = 0; i < n_atom; i++) { | for(i = 0; i < n_atom; i++) { | |||
add3f(avg, v_i[i], avg); | add3f(avg, v_i[i], avg); | |||
} | } | |||
scale3f(avg, 1.0F / n_atom, avg); | scale3f(avg, 1.0F / n_atom, avg); | |||
g1p = avg; | g1p = avg; | |||
} | } | |||
{ | { | |||
float *color1, *color2; | const float *color1, *color2; | |||
if (ladder_color >= 0) { | if (ladder_color >= 0) { | |||
color1 = color2 = ColorGet(G, ladder_color); | color1 = color2 = ColorGet(G, ladder_color); | |||
} else { | } else { | |||
color1 = ColorGet(G, g1_ai->color); | color1 = ColorGet(G, g1_ai->color); | |||
color2 = ColorGet(G, g2_ai->color); | color2 = ColorGet(G, g2_ai->color); | |||
} | } | |||
if (is_picking){ /* If picking, need to split cylinder in two | CGOPickColor(cgo, g1, g1_ai->masked ? cPickableNoPick : cPic | |||
to pick atoms */ | kableAtom); | |||
float midv[3], midc[3]; | Pickable pickcolor2 = { g2, g2_ai->masked ? cPickableNoPick | |||
average3f(g1p, g2p, midv); | : cPickableAtom }; | |||
average3f(color1, color2, midc); | float axis[3]; | |||
if(!g1_ai->masked) | subtract3f(g2p, g1p, axis); | |||
CGOPickColor(cgo, g1, cPickableAtom); | CGOColorv(cgo, color1); | |||
CGOCustomCylinderv(cgo, g1p, midv, glyco_radius, | cgo->add<cgo::draw::shadercylinder2ndcolor>(cgo, g1p, axis, | |||
color1, midc, 2.0F, 0.0F); | glyco_radius, 0x1f, color2, &pickcolor2); | |||
if(!g2_ai->masked) | ||||
CGOPickColor(cgo, g2, cPickableAtom); | ||||
CGOCustomCylinderv(cgo, midv, g2p, glyco_radius, | ||||
midc, color2, 0.0F, 2.0F); | ||||
} else { | ||||
CGOCustomCylinderv(cgo, g1p, g2p, glyco_radius, | ||||
color1, color2, 2.0F, 2.0F); | ||||
} | ||||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
/* see if any of the neighbors are confirmed nucleic acids... */ | /* see if any of the neighbors are confirmed nucleic acids... */ | |||
if(sugar_at >= 0) { | if(sugar_at >= 0) { | |||
if(!nf) { | if(!nf) { | |||
mem0 = sugar_at; | auto seen = std::set<int>(); | |||
nbr[0] = neighbor[mem0] + 1; | nf = has_nuc_neighbor(nuc_flag, obj->Neighbor, sugar_at, 5, seen); | |||
while((!nf) && (mem1 = neighbor[nbr[0]]) >= 0) { | ||||
if(!nf) | ||||
nf = nuc_flag[mem1]; | ||||
nbr[1] = neighbor[mem1] + 1; | ||||
while((!nf) && (mem2 = neighbor[nbr[1]]) >= 0) { | ||||
if(mem2 != mem0) { | ||||
if(!nf) | ||||
nf = nuc_flag[mem2]; | ||||
nbr[2] = neighbor[mem2] + 1; | ||||
while((!nf) && (mem3 = neighbor[nbr[2]]) >= 0) { | ||||
if((mem3 != mem1) && (mem3 != mem0)) { | ||||
if(!nf) | ||||
nf = nuc_flag[mem3]; | ||||
nbr[3] = neighbor[mem3] + 1; | ||||
while((mem4 = neighbor[nbr[3]]) >= 0) { | ||||
if(mem4 != mem2) { | ||||
if(!nf) | ||||
nf = nuc_flag[mem4]; | ||||
nbr[4] = neighbor[mem4] + 1; | ||||
while((mem5 = neighbor[nbr[4]]) >= 0) { | ||||
if(mem5 != mem3) { | ||||
if(!nf) | ||||
nf = nuc_flag[mem5]; | ||||
} | ||||
nbr[4] += 2; | ||||
} | ||||
} | ||||
nbr[3] += 2; | ||||
} | ||||
} | ||||
nbr[2] += 2; | ||||
} | ||||
} | ||||
nbr[1] += 2; | ||||
} | ||||
nbr[0] += 2; | ||||
} | ||||
} | } | |||
if(nf) { | if(nf) { | |||
if((ring_mode) && ((finder == 1) || (finder >= 3))) { | if((ring_mode) && ((finder == 1) || (finder >= 3))) { | |||
if((c1_at >= 0) && (base_at >= 0)) { | if((c1_at >= 0) && (base_at >= 0)) { | |||
int save_at = sugar_at; | int save_at = sugar_at; | |||
sugar_at = c1_at; | sugar_at = c1_at; | |||
{ | { | |||
AtomInfoType *sug_ai = atomInfo + sugar_at; | AtomInfoType *sug_ai = atomInfo + sugar_at; | |||
AtomInfoType *bas_ai = atomInfo + base_at; | AtomInfoType *bas_ai = atomInfo + base_at; | |||
skipping to change at line 1011 | skipping to change at line 1069 | |||
sug = -1; | sug = -1; | |||
bas = -1; | bas = -1; | |||
} | } | |||
} else { | } else { | |||
sug = cs->AtmToIdx[sugar_at]; | sug = cs->AtmToIdx[sugar_at]; | |||
bas = cs->AtmToIdx[base_at]; | bas = cs->AtmToIdx[base_at]; | |||
} | } | |||
if((sug >= 0) && (bas >= 0)) { | if((sug >= 0) && (bas >= 0)) { | |||
{ | { | |||
float *color1, *color2; | const float *color1, *color2; | |||
if (ladder_color >= 0) { | if (ladder_color >= 0) { | |||
color1 = color2 = ColorGet(G, ladder_color); | color1 = color2 = ColorGet(G, ladder_color); | |||
} else { | } else { | |||
color1 = ColorGet(G, sug_ai->color); | color1 = ColorGet(G, sug_ai->color); | |||
color2 = ColorGet(G, bas_ai->color); | color2 = ColorGet(G, bas_ai->color); | |||
} | } | |||
if (is_picking){ | CGOPickColor(cgo, sugar_at, sug_ai->masked ? cPickableNoPi | |||
float midv[3], midc[3]; | ck : cPickableAtom); | |||
average3f(cs->Coord + 3 * sug, cs->Coord + 3 * bas, midv) | Pickable pickcolor2 = { base_at, bas_ai->masked ? cPickabl | |||
; | eNoPick : cPickableAtom }; | |||
average3f(color1, color2, midc); | float axis[3]; | |||
if(!sug_ai->masked) | subtract3f(cs->Coord + 3 * bas, cs->Coord + 3 * sug, axis) | |||
CGOPickColor(cgo, sugar_at, cPickableAtom); | ; | |||
CGOCustomCylinderv(cgo, cs->Coord + 3 * sug, midv, ladder | CGOColorv(cgo, color1); | |||
_radius, | cgo->add<cgo::draw::shadercylinder2ndcolor>(cgo, cs->Coord | |||
color1, midc, 2.0F, 0.0F); | + 3 * sug, axis, ladder_radius, 0x1f, color2, &pickcolor2); | |||
if(!bas_ai->masked) | ||||
CGOPickColor(cgo, base_at, cPickableAtom); | ||||
CGOCustomCylinderv(cgo, midv, cs->Coord + 3 * bas, ladder | ||||
_radius, | ||||
midc, color2, 0.0F, 2.0F); | ||||
} else { | ||||
CGOCustomCylinderv(cgo, cs->Coord + 3 * sug, | ||||
cs->Coord + 3 * bas, | ||||
ladder_radius, | ||||
color1, color2, 2.0F, 2.0F); | ||||
} | ||||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
base_at = save_at; | base_at = save_at; | |||
sugar_at = save_at; | sugar_at = save_at; | |||
} | } | |||
} | } | |||
if((base_at >= 0) && (sugar_at >= 0)) { | if((base_at >= 0) && (sugar_at >= 0)) { | |||
AtomInfoType *sug_ai = atomInfo + sugar_at; | AtomInfoType *sug_ai = atomInfo + sugar_at; | |||
skipping to change at line 1101 | skipping to change at line 1147 | |||
scale3f(cs->Coord + 3 * p3, 0.666667F, tmp); | scale3f(cs->Coord + 3 * p3, 0.666667F, tmp); | |||
} else { | } else { | |||
scale3f(cs->Coord + 3 * p3, 0.5F, outer); | scale3f(cs->Coord + 3 * p3, 0.5F, outer); | |||
scale3f(cs->Coord + 3 * p5, 0.5F, tmp); | scale3f(cs->Coord + 3 * p5, 0.5F, tmp); | |||
} | } | |||
add3f(tmp, outer, outer); | add3f(tmp, outer, outer); | |||
v_outer = outer; | v_outer = outer; | |||
} | } | |||
} | } | |||
{ | { | |||
float *color1, *color2; | const float *color1, *color2; | |||
if (ladder_color >= 0) { | if (ladder_color >= 0) { | |||
color1 = color2 = ColorGet(G, ladder_color); | color1 = color2 = ColorGet(G, ladder_color); | |||
} else { | } else { | |||
color1 = ColorGet(G, sug_ai->color); | color1 = ColorGet(G, sug_ai->color); | |||
color2 = ColorGet(G, bas_ai->color); | color2 = ColorGet(G, bas_ai->color); | |||
} | } | |||
if (is_picking){ | ||||
float midv[3], midc[3]; | CGOPickColor(cgo, sugar_at, sug_ai->masked ? cPickableNoPick : | |||
average3f(v_outer, cs->Coord + 3 * bas, midv); | cPickableAtom); | |||
average3f(color1, color2, midc); | Pickable pickcolor2 = { base_at, bas_ai->masked ? cPickableNoP | |||
if(!sug_ai->masked) | ick : cPickableAtom }; | |||
CGOPickColor(cgo, sugar_at, cPickableAtom); | float axis[3]; | |||
CGOCustomCylinderv(cgo, v_outer, midv, ladder_radius, | subtract3f(cs->Coord + 3 * bas, v_outer, axis); | |||
color1, midc, 2.0F, 0.0F); | CGOColorv(cgo, color1); | |||
if(!bas_ai->masked) | cgo->add<cgo::draw::shadercylinder2ndcolor>(cgo, v_outer, axis | |||
CGOPickColor(cgo, base_at, cPickableAtom); | , ladder_radius, 0x1f, color2, &pickcolor2); | |||
CGOCustomCylinderv(cgo, midv, cs->Coord + 3 * bas, ladder_rad | ||||
ius, | ||||
midc, color2, 0.0F, 2.0F); | ||||
} else { | ||||
CGOCustomCylinderv(cgo, v_outer, | ||||
cs->Coord + 3 * bas, | ||||
ladder_radius, | ||||
color1, color2, 2.0F, 2.0F); | ||||
} | ||||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
if((!ring_mode) || (finder == 2)) { | if((!ring_mode) || (finder == 2)) { | |||
if(ladder_mode) { /* mark sure all rings traversed are mark */ | if(ladder_mode) { /* mark sure all rings traversed are mark */ | |||
int i; | int i; | |||
for(i = 0; i <= n_atom; i++) { | for(i = 0; i <= n_atom; i++) { | |||
marked[atix[i]] = true; | marked[atix[i]] = true; | |||
} | } | |||
} | } | |||
} | } | |||
if((!nf) && ((have_C4_prime >= 0) || (have_C4 >= 0))) { | if((!nf) && ((have_C4_prime >= 0) || (have_C4 >= 0))) { | |||
int nbr[9]; | int mem0; | |||
int *neighbor = obj->Neighbor; | ||||
int mem0, mem1, mem2, mem3, mem4, mem5, mem6, mem7, mem8, mem9; | ||||
/* see if any of the neighbors are confirmed nucleic acids... */ | /* see if any of the neighbors are confirmed nucleic acids... */ | |||
if(have_C4_prime >= 0) | if(have_C4_prime >= 0) | |||
mem0 = have_C4_prime; | mem0 = have_C4_prime; | |||
else if(have_C4 >= 0) | else if(have_C4 >= 0) | |||
mem0 = have_C4; | mem0 = have_C4; | |||
else | else | |||
mem0 = -1; | mem0 = -1; | |||
if(mem0 >= 1) { | if(mem0 >= 1) { | |||
nbr[0] = neighbor[mem0] + 1; | auto seen = std::set<int>(); | |||
while((!nf) && (mem1 = neighbor[nbr[0]]) >= 0) { | nf = has_nuc_neighbor(nuc_flag, obj->Neighbor, mem0, 9, seen); | |||
if(!nf) | ||||
nf = nuc_flag[mem1]; | ||||
nbr[1] = neighbor[mem1] + 1; | ||||
while((!nf) && (mem2 = neighbor[nbr[1]]) >= 0) { | ||||
if(mem2 != mem0) { | ||||
if(!nf) | ||||
nf = nuc_flag[mem2]; | ||||
nbr[2] = neighbor[mem2] + 1; | ||||
while((!nf) && (mem3 = neighbor[nbr[2]]) >= 0) { | ||||
if((mem3 != mem1) && (mem3 != mem0)) { | ||||
if(!nf) | ||||
nf = nuc_flag[mem3]; | ||||
nbr[3] = neighbor[mem3] + 1; | ||||
while((mem4 = neighbor[nbr[3]]) >= 0) { | ||||
if(mem4 != mem2) { | ||||
if(!nf) | ||||
nf = nuc_flag[mem4]; | ||||
nbr[4] = neighbor[mem4] + 1; | ||||
while((mem5 = neighbor[nbr[4]]) >= 0) { | ||||
if(mem5 != mem3) { | ||||
if(!nf) | ||||
nf = nuc_flag[mem5]; | ||||
nbr[5] = neighbor[mem5] + 1; | ||||
while((mem6 = neighbor[nbr[5]]) >= 0) { | ||||
if(mem6 != mem4) { | ||||
if(!nf) | ||||
nf = nuc_flag[mem6]; | ||||
nbr[6] = neighbor[mem6] + 1; | ||||
while((mem7 = neighbor[nbr[6]]) >= 0) { | ||||
if(mem7 != mem5) { | ||||
if(!nf) | ||||
nf = nuc_flag[mem7]; | ||||
nbr[7] = neighbor[mem7] + 1; | ||||
while((mem8 = neighbor[nbr[7]]) >= 0) { | ||||
if(mem8 != mem6) { | ||||
if(!nf) | ||||
nf = nuc_flag[mem8]; | ||||
nbr[8] = neighbor[mem8] + 1; | ||||
while((mem9 = neighbor[nbr[8]]) >= 0) { | ||||
if(mem9 != mem7) { | ||||
if(!nf) | ||||
nf = nuc_flag[mem9]; | ||||
} | ||||
nbr[8] += 2; | ||||
} | ||||
} | ||||
nbr[7] += 2; | ||||
} | ||||
} | ||||
nbr[6] += 2; | ||||
} | ||||
} | ||||
nbr[5] += 2; | ||||
} | ||||
} | ||||
nbr[4] += 2; | ||||
} | ||||
} | ||||
nbr[3] += 2; | ||||
} | ||||
} | ||||
nbr[2] += 2; | ||||
} | ||||
} | ||||
nbr[1] += 2; | ||||
} | ||||
nbr[0] += 2; | ||||
} | ||||
} | } | |||
} | } | |||
if(n_atom) { /* store center of ring */ | if(n_atom) { /* store center of ring */ | |||
float avg[3]; | float avg[3]; | |||
float avg_col[3]; | float avg_col[3]; | |||
int i; | int i; | |||
float up[3], upi[3]; | float up[3], upi[3]; | |||
float vc0[3], vc1[3]; | float vc0[3], vc1[3]; | |||
float *color = NULL; | const float *color = NULL; | |||
/* compute average coordinate and mark atoms so that ring is only drawn on ce */ | /* compute average coordinate and mark atoms so that ring is only drawn on ce */ | |||
zero3f(avg); | zero3f(avg); | |||
zero3f(avg_col); | zero3f(avg_col); | |||
for(i = 0; i < n_atom; i++) { | for(i = 0; i < n_atom; i++) { | |||
add3f(avg, v_i[i], avg); | add3f(avg, v_i[i], avg); | |||
add3f(avg_col, col[i], avg_col); | add3f(avg_col, col[i], avg_col); | |||
marked[atix[i]] = true; | marked[atix[i]] = true; | |||
} | } | |||
skipping to change at line 1420 | skipping to change at line 1385 | |||
CGOAlpha(cgo, alpha); | CGOAlpha(cgo, alpha); | |||
{ | { | |||
float ring_width_for_mode = ring_width; | float ring_width_for_mode = ring_width; | |||
if (ring_mode == 3){ | if (ring_mode == 3){ | |||
ring_width_for_mode = 3.f * ring_width; | ring_width_for_mode = 3.f * ring_width; | |||
} | } | |||
for(i = 0; i < n_atom; i++) { | for(i = 0; i < n_atom; i++) { | |||
ii = i + 1; | ii = i + 1; | |||
{ | { | |||
float *color1, *color2; | const float *color1, *color2; | |||
if (ring_color < 0) { | if (ring_color < 0) { | |||
color1 = col[i]; | color1 = col[i]; | |||
color2 = col[ii]; | color2 = col[ii]; | |||
} else { | } else { | |||
color1 = color2 = color; | color1 = color2 = color; | |||
} | } | |||
if (is_picking){ | CGOPickColor(cgo, atix[i], ai_i[i]->masked ? cPickableNoPick : | |||
float midv[3], midc[3]; | cPickableAtom); | |||
average3f(v_i[i], v_i[ii], midv); | Pickable pickcolor2 = { atix[ii], ai_i[ii]->masked ? cPickable | |||
average3f(color1, color2, midc); | NoPick : cPickableAtom }; | |||
CGOPickColor(cgo, atix[i], cPickableAtom); | float axis[3]; | |||
CGOCustomCylinderv(cgo, v_i[i], midv, ring_width_for_mode, | subtract3f(v_i[ii], v_i[i], axis); | |||
color1, midc, 2.0F, 0.0F); | CGOColorv(cgo, color1); | |||
CGOPickColor(cgo, atix[ii], cPickableAtom); | cgo->add<cgo::draw::shadercylinder2ndcolor>(cgo, v_i[i], axis, | |||
CGOCustomCylinderv(cgo, midv, v_i[ii], ring_width_for_mode, | ring_width_for_mode, 0x1f, color2, &pickcolor2); | |||
midc, color2, 0.0F, 2.0F); | ||||
} else { | ||||
CGOSausage(cgo, v_i[i], v_i[ii], ring_width_for_mode, color1, | ||||
color2); | ||||
} | ||||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
skipping to change at line 1671 | skipping to change at line 1629 | |||
#endif | #endif | |||
return ok; | return ok; | |||
} | } | |||
static | static | |||
int GenerateRepCartoonProcessCylindricalHelices(PyMOLGlobals * G, ObjectMolecule * obj, CoordSet *cs, CGO *cgo, CExtrude *ex, int nAt, int *seg, float *pv, floa t *tv, float *pvo, | int GenerateRepCartoonProcessCylindricalHelices(PyMOLGlobals * G, ObjectMolecule * obj, CoordSet *cs, CGO *cgo, CExtrude *ex, int nAt, int *seg, float *pv, floa t *tv, float *pvo, | |||
const CCInOut *cc, | const CCInOut *cc, | |||
int *at, float *dl, int cartoon_color, int discrete_colors, float loop_radiu s){ | int *at, float *dl, int cartoon_color, int discrete_colors, float loop_radiu s){ | |||
int ok = true; | int ok = true; | |||
int n_p, n_pm1, n_pm2; | int n_p, n_pm1, n_pm2; | |||
float *v, *v0, *v1, *v2, *vo, *d; | const float *v0; | |||
float *v, *v1, *v2, *vo, *d; | ||||
float *vc = NULL; | float *vc = NULL; | |||
int atom_index1, atom_index2, *s, | int atom_index1, atom_index2, *s, | |||
*atp, a, cur_car; | *atp, a, cur_car; | |||
int *vi; | unsigned *vi; | |||
int last_color, uniform_color; | int last_color, uniform_color; | |||
int contFlag, extrudeFlag; | int contFlag, extrudeFlag; | |||
int b, c1, c2; | int b, c1, c2; | |||
float *h_start = NULL, *h_end = NULL; | float *h_start = NULL, *h_end = NULL; | |||
float t0[3], t1[3], t2[3], t3[3]; | float t0[3], t1[3], t2[3], t3[3]; | |||
float t4[3]; | float t4[3]; | |||
float helix_radius; | float helix_radius; | |||
CGOPickColor(cgo, 0, cPickableNoPick); | CGOPickColor(cgo, 0, cPickableNoPick); | |||
helix_radius = | helix_radius = | |||
SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_cartoon_helix_radius ); | SettingGet_f(G, cs->Setting, obj->Obj.Setting, cSetting_cartoon_helix_radius ); | |||
skipping to change at line 1899 | skipping to change at line 1858 | |||
vi = ex->i; | vi = ex->i; | |||
uniform_color = true; | uniform_color = true; | |||
last_color = -1; | last_color = -1; | |||
} | } | |||
} | } | |||
return ok; | return ok; | |||
} | } | |||
static | static | |||
int GenerateRepCartoonDrawRings(PyMOLGlobals * G, nuc_acid_data *ndata, ObjectMo lecule * obj, | int GenerateRepCartoonDrawRings(PyMOLGlobals * G, nuc_acid_data *ndata, ObjectMo lecule * obj, | |||
bool is_picking, | ||||
CoordSet * cs, CGO *cgo, | CoordSet * cs, CGO *cgo, | |||
float ring_width, int cartoon_color, float alpha ){ | float ring_width, int cartoon_color, float alpha ){ | |||
int ring_i; | int ring_i; | |||
int mem[8]; | int mem[8]; | |||
int nbr[7]; | int nbr[7]; | |||
int *neighbor; | int *neighbor; | |||
int *marked = Calloc(int, obj->NAtom); | int *marked = Calloc(int, obj->NAtom); | |||
float *moved = Calloc(float, obj->NAtom * 3); | float *moved = Calloc(float, obj->NAtom * 3); | |||
int ring_color; | int ring_color; | |||
int ok = true; | int ok = true; | |||
skipping to change at line 1977 | skipping to change at line 1935 | |||
if(!(escape_count--)) | if(!(escape_count--)) | |||
goto escape; | goto escape; | |||
if((mem[5] != mem[3]) && (mem[5] != mem[2]) && (mem[5] != me m[1])) { | if((mem[5] != mem[3]) && (mem[5] != mem[2]) && (mem[5] != me m[1])) { | |||
if(mem[5] == mem[0]) { /* five-cycle */ | if(mem[5] == mem[0]) { /* five-cycle */ | |||
/* printf(" 5: %s(%d) %s(%d) %s(%d) %s(%d) %s(%d)\n", | /* printf(" 5: %s(%d) %s(%d) %s(%d) %s(%d) %s(%d)\n", | |||
obj->AtomInfo[mem[0]].name,mem[0], | obj->AtomInfo[mem[0]].name,mem[0], | |||
obj->AtomInfo[mem[1]].name,mem[1], | obj->AtomInfo[mem[1]].name,mem[1], | |||
obj->AtomInfo[mem[2]].name,mem[2], | obj->AtomInfo[mem[2]].name,mem[2], | |||
obj->AtomInfo[mem[3]].name,mem[3], | obj->AtomInfo[mem[3]].name,mem[3], | |||
obj->AtomInfo[mem[4]].name,mem[4]); */ | obj->AtomInfo[mem[4]].name,mem[4]); */ | |||
do_ring(G, ndata, is_picking, 5, mem, obj, cs, ring_widt h, cgo, ring_color, | do_ring(G, ndata, 5, mem, obj, cs, ring_width, cgo, ring _color, | |||
ladder_radius, ladder_color, ladder_mode, | ladder_radius, ladder_color, ladder_mode, | |||
cartoon_side_chain_helper, | cartoon_side_chain_helper, | |||
ring_alpha, alpha, marked, moved, ring_radius); | ring_alpha, alpha, marked, moved, ring_radius); | |||
} | } | |||
nbr[5] = neighbor[mem[5]] + 1; | nbr[5] = neighbor[mem[5]] + 1; | |||
while(((mem[6] = neighbor[nbr[5]]) >= 0) && | while(((mem[6] = neighbor[nbr[5]]) >= 0) && | |||
((!atmToIdx) || (atmToIdx[mem[5]] >= 0))) { | ((!atmToIdx) || (atmToIdx[mem[5]] >= 0))) { | |||
if((mem[6] != mem[4]) && (mem[6] != mem[3]) | if((mem[6] != mem[4]) && (mem[6] != mem[3]) | |||
&& (mem[6] != mem[2]) && (mem[6] != mem[1])) { | && (mem[6] != mem[2]) && (mem[6] != mem[1])) { | |||
if(mem[6] == mem[0]) { /* six-cycle */ | if(mem[6] == mem[0]) { /* six-cycle */ | |||
/* printf(" 6: %s %s %s %s %s %s\n", | /* printf(" 6: %s %s %s %s %s %s\n", | |||
obj->AtomInfo[mem[0]].name, | obj->AtomInfo[mem[0]].name, | |||
obj->AtomInfo[mem[1]].name, | obj->AtomInfo[mem[1]].name, | |||
obj->AtomInfo[mem[2]].name, | obj->AtomInfo[mem[2]].name, | |||
obj->AtomInfo[mem[3]].name, | obj->AtomInfo[mem[3]].name, | |||
obj->AtomInfo[mem[4]].name, | obj->AtomInfo[mem[4]].name, | |||
obj->AtomInfo[mem[5]].name | obj->AtomInfo[mem[5]].name | |||
); */ | ); */ | |||
do_ring(G, ndata, is_picking, 6, mem, obj, cs, ring_ width, cgo, ring_color, | do_ring(G, ndata, 6, mem, obj, cs, ring_width, cgo, ring_color, | |||
ladder_radius, ladder_color, ladder_mode, | ladder_radius, ladder_color, ladder_mode, | |||
cartoon_side_chain_helper, | cartoon_side_chain_helper, | |||
ring_alpha, alpha, marked, moved, | ring_alpha, alpha, marked, moved, | |||
ring_radius); | ring_radius); | |||
} | } | |||
nbr[6] = neighbor[mem[6]] + 1; | nbr[6] = neighbor[mem[6]] + 1; | |||
while(((mem[7] = neighbor[nbr[6]]) >= 0) && | while(((mem[7] = neighbor[nbr[6]]) >= 0) && | |||
((!atmToIdx) || (atmToIdx[mem[6]] >= 0))) { | ((!atmToIdx) || (atmToIdx[mem[6]] >= 0))) { | |||
if((mem[7] != mem[5]) && (mem[7] != mem[4]) | if((mem[7] != mem[5]) && (mem[7] != mem[4]) | |||
&& (mem[7] != mem[3]) && (mem[7] != mem[2]) | && (mem[7] != mem[3]) && (mem[7] != mem[2]) | |||
&& (mem[7] != mem[1])) { | && (mem[7] != mem[1])) { | |||
if(mem[7] == mem[0]) { | if(mem[7] == mem[0]) { | |||
do_ring(G, ndata, is_picking, 7, mem, obj, cs, r ing_width, cgo, | do_ring(G, ndata, 7, mem, obj, cs, ring_width, c go, | |||
ring_color, ladder_radius, | ring_color, ladder_radius, | |||
ladder_color, ladder_mode, | ladder_color, ladder_mode, | |||
cartoon_side_chain_helper, | cartoon_side_chain_helper, | |||
ring_alpha, alpha, marked, moved, ring_r adius); | ring_alpha, alpha, marked, moved, ring_r adius); | |||
} | } | |||
} | } | |||
nbr[6] += 2; | nbr[6] += 2; | |||
} | } | |||
} | } | |||
nbr[5] += 2; | nbr[5] += 2; | |||
skipping to change at line 2138 | skipping to change at line 2096 | |||
} | } | |||
} | } | |||
*c1a = c1; | *c1a = c1; | |||
*c2a = c2; | *c2a = c2; | |||
} | } | |||
static | static | |||
void CartoonGenerateSample(PyMOLGlobals *G, int sampling, int *n_p, float dev, f loat *vo, | void CartoonGenerateSample(PyMOLGlobals *G, int sampling, int *n_p, float dev, f loat *vo, | |||
float *v1, | float *v1, | |||
float *v2, int c1, int c2, int atom_index1, int atom_ index2, | float *v2, int c1, int c2, int atom_index1, int atom_ index2, | |||
float power_a, float power_b, float **vc_p, | float power_a, float power_b, float **vc_p, unsigned | |||
int **vi_p, | int **vi_p, | |||
float **v_p, float **vn_p){ | float **v_p, float **vn_p){ | |||
int b, i0; | int b, i0; | |||
float f0, f1, f2, f3, f4; | float f0, f1, f2, f3, f4; | |||
float *v0; | const float *v0; | |||
int *vi = *vi_p; | unsigned int *vi = *vi_p; | |||
float *vc = *vc_p, *v = *v_p, *vn = *vn_p; | float *vc = *vc_p, *v = *v_p, *vn = *vn_p; | |||
for(b = 0; b < sampling; b++) { /* needs optimization */ | for(b = 0; b < sampling; b++) { /* needs optimization */ | |||
if(*n_p == 0) { | if(*n_p == 0) { | |||
/* provide starting point on first point in segment only... */ | /* provide starting point on first point in segment only... */ | |||
f0 = ((float) b) / sampling; /* fraction of completion */ | f0 = ((float) b) / sampling; /* fraction of completion */ | |||
if(f0 <= 0.5) { | if(f0 <= 0.5) { | |||
v0 = ColorGet(G, c1); | v0 = ColorGet(G, c1); | |||
i0 = atom_index1; | i0 = atom_index1; | |||
} else { | } else { | |||
v0 = ColorGet(G, c2); | v0 = ColorGet(G, c2); | |||
skipping to change at line 2259 | skipping to change at line 2216 | |||
for(b = 0; b < (sampling - 1); b++) { | for(b = 0; b < (sampling - 1); b++) { | |||
p3 = sampling_tmp + b * 3; | p3 = sampling_tmp + b * 3; | |||
copy3f(p3, p1); | copy3f(p3, p1); | |||
p1 += 3; | p1 += 3; | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
static | static | |||
int CartoonExtrudeTube(short use_cylinders_for_strands, CExtrude *ex, CGO *cgo, | int CartoonExtrudeTube(short use_cylinders_for_strands, CExtrude *ex, CGO *cgo, | |||
float tube_radius, int tube_quality, int tube_cap, int is_picking){ | float tube_radius, int tube_quality, int tube_cap){ | |||
int ok = true; | int ok = true; | |||
if (use_cylinders_for_strands){ | if (use_cylinders_for_strands){ | |||
ok &= ExtrudeCylindersToCGO(ex, cgo, tube_radius, is_picking); | ok &= ExtrudeCylindersToCGO(ex, cgo, tube_radius); | |||
} else { | } else { | |||
ok &= ExtrudeCircle(ex, tube_quality, tube_radius); | ok &= ExtrudeCircle(ex, tube_quality, tube_radius); | |||
if (ok) | if (ok) | |||
ExtrudeBuildNormals1f(ex); | ExtrudeBuildNormals1f(ex); | |||
if (ok) | if (ok) | |||
ok &= ExtrudeCGOSurfaceTube(ex, cgo, tube_cap, NULL, use_cylinders_for_str ands); | ok &= ExtrudeCGOSurfaceTube(ex, cgo, tube_cap, NULL, use_cylinders_for_str ands); | |||
} | } | |||
return ok; | return ok; | |||
} | } | |||
skipping to change at line 2452 | skipping to change at line 2408 | |||
(natom < 999999) ? v3 : v4; | (natom < 999999) ? v3 : v4; | |||
} else if (quality < min_) { | } else if (quality < min_) { | |||
quality = min_; | quality = min_; | |||
} | } | |||
return quality; | return quality; | |||
} | } | |||
static | static | |||
CGO *GenerateRepCartoonCGO(CoordSet *cs, ObjectMolecule *obj, nuc_acid_data *nda ta, short use_cylinders_for_strands, | CGO *GenerateRepCartoonCGO(CoordSet *cs, ObjectMolecule *obj, nuc_acid_data *nda ta, short use_cylinders_for_strands, | |||
bool is_picking, | ||||
float *pv, int nAt, float *tv, float *pvo, | float *pv, int nAt, float *tv, float *pvo, | |||
float *dl, | float *dl, | |||
const CCInOut *car, | const CCInOut *car, | |||
int *seg, int *at, int *nuc_flag, | int *seg, int *at, int *nuc_flag, | |||
float *putty_vals, float alpha){ | float *putty_vals, float alpha){ | |||
PyMOLGlobals *G = cs->State.G; | PyMOLGlobals *G = cs->State.G; | |||
int ok = true; | int ok = true; | |||
CGO *cgo; | CGO *cgo; | |||
int contigFlag, contFlag, extrudeFlag, n_p; | int contigFlag, contFlag, extrudeFlag, n_p; | |||
CExtrude *ex = NULL; | CExtrude *ex = NULL; | |||
float dev; | float dev; | |||
int *vi; | unsigned int *vi; | |||
int atom_index1, atom_index2; | int atom_index1, atom_index2; | |||
float *v, *v1, *v2, *vo; | float *v, *v1, *v2, *vo; | |||
float *d, *vc = NULL, *vn; | float *d, *vc = NULL, *vn; | |||
int *atp; | int *atp; | |||
int c1, c2; | int c1, c2; | |||
int a; | int a; | |||
int sampling; | int sampling; | |||
float *sampling_tmp; | float *sampling_tmp; | |||
int *segptr; | int *segptr; | |||
const CCInOut *cc; | const CCInOut *cc; | |||
skipping to change at line 2657 | skipping to change at line 2612 | |||
} | } | |||
if (ok){ | if (ok){ | |||
ExtrudeTruncate(ex, n_p); | ExtrudeTruncate(ex, n_p); | |||
ok &= ExtrudeComputeTangents(ex); | ok &= ExtrudeComputeTangents(ex); | |||
} | } | |||
if (ok){ | if (ok){ | |||
/* set up shape */ | /* set up shape */ | |||
switch (cur_car) { | switch (cur_car) { | |||
case cCartoon_tube: | case cCartoon_tube: | |||
ok = CartoonExtrudeTube(use_cylinders_for_strands, ex, cgo, tube_rad ius, tube_quality, tube_cap, is_picking); | ok = CartoonExtrudeTube(use_cylinders_for_strands, ex, cgo, tube_rad ius, tube_quality, tube_cap); | |||
break; | break; | |||
case cCartoon_putty: | case cCartoon_putty: | |||
ok = CartoonExtrudePutty(G, obj, cs, cgo, ex, putty_quality, putty_r adius, putty_vals, sampling); | ok = CartoonExtrudePutty(G, obj, cs, cgo, ex, putty_quality, putty_r adius, putty_vals, sampling); | |||
if (!ok) | if (!ok) | |||
contFlag = false; | contFlag = false; | |||
break; | break; | |||
case cCartoon_loop: | case cCartoon_loop: | |||
ok = CartoonExtrudeCircle(ex, cgo, use_cylinders_for_strands, loop_q uality, loop_radius, loop_cap); | ok = CartoonExtrudeCircle(ex, cgo, use_cylinders_for_strands, loop_q uality, loop_radius, loop_cap); | |||
break; | break; | |||
case cCartoon_dash: | case cCartoon_dash: | |||
skipping to change at line 2712 | skipping to change at line 2667 | |||
if(ok && nAt > 1) { | if(ok && nAt > 1) { | |||
if((cartoon_debug > 0.5) && (cartoon_debug < 2.5)) { | if((cartoon_debug > 0.5) && (cartoon_debug < 2.5)) { | |||
ok = GenerateRepCartoonDrawDebugOrient(cgo, nAt, pv, pvo, tv); | ok = GenerateRepCartoonDrawDebugOrient(cgo, nAt, pv, pvo, tv); | |||
} | } | |||
} | } | |||
if(ex) { | if(ex) { | |||
ExtrudeFree(ex); | ExtrudeFree(ex); | |||
} | } | |||
/* draw the rings */ | /* draw the rings */ | |||
if(ok && ndata->ring_anchor && ndata->n_ring) { | if(ok && ndata->ring_anchor && ndata->n_ring) { | |||
ok = GenerateRepCartoonDrawRings(G, ndata, obj, is_picking, cs, cgo, ring_wi dth, cartoon_color, alpha); | ok = GenerateRepCartoonDrawRings(G, ndata, obj, cs, cgo, ring_width, cartoon _color, alpha); | |||
} | } | |||
if (ok) | if (ok) | |||
CGOStop(cgo); | CGOStop(cgo); | |||
FreeP(sampling_tmp); | FreeP(sampling_tmp); | |||
if (!ok){ | if (!ok){ | |||
CGOFree(cgo); | CGOFree(cgo); | |||
} | } | |||
return (cgo); | return (cgo); | |||
skipping to change at line 3725 | skipping to change at line 3680 | |||
I->R.fRender = (void (*)(struct Rep *, RenderInfo *)) RepCartoonRender; | I->R.fRender = (void (*)(struct Rep *, RenderInfo *)) RepCartoonRender; | |||
I->R.fSameVis = (int (*)(struct Rep *, struct CoordSet *)) RepCartoonSameVis; | I->R.fSameVis = (int (*)(struct Rep *, struct CoordSet *)) RepCartoonSameVis; | |||
I->R.fFree = (void (*)(struct Rep *)) RepCartoonFree; | I->R.fFree = (void (*)(struct Rep *)) RepCartoonFree; | |||
I->R.fInvalidate = RepCartoonInvalidate; | I->R.fInvalidate = RepCartoonInvalidate; | |||
I->R.fRecolor = NULL; | I->R.fRecolor = NULL; | |||
I->R.obj = &obj->Obj; | I->R.obj = &obj->Obj; | |||
I->R.cs = cs; | I->R.cs = cs; | |||
I->ray = NULL; | I->ray = NULL; | |||
I->std = NULL; | I->std = NULL; | |||
I->preshader = NULL; | I->preshader = NULL; | |||
I->pickingCGO = NULL; | ||||
I->R.context.object = (void *) obj; | I->R.context.object = (void *) obj; | |||
I->R.context.state = state; | I->R.context.state = state; | |||
/* find all of the CA points */ | /* find all of the CA points */ | |||
at = Alloc(int, cs->NAtIndex); /* cs index pointers */ | at = Alloc(int, cs->NAtIndex); /* cs index pointers */ | |||
pv = Alloc(float, cs->NAtIndex * 3); | pv = Alloc(float, cs->NAtIndex * 3); | |||
tmp = Alloc(float, cs->NAtIndex * 3); | tmp = Alloc(float, cs->NAtIndex * 3); | |||
pvo = Alloc(float, cs->NAtIndex * 3); /* orientation vector */ | pvo = Alloc(float, cs->NAtIndex * 3); /* orientation vector */ | |||
pva = Alloc(float, cs->NAtIndex * 6); /* alternative orientation vectors, two per atom */ | pva = Alloc(float, cs->NAtIndex * 6); /* alternative orientation vectors, two per atom */ | |||
skipping to change at line 3839 | skipping to change at line 3793 | |||
RepCartoonComputeDifferencesAndNormals(G, nAt, seg, pv, dv, nv, dl, true ); | RepCartoonComputeDifferencesAndNormals(G, nAt, seg, pv, dv, nv, dl, true ); | |||
/* recompute tangents */ | /* recompute tangents */ | |||
RepCartoonComputeTangents(nAt, seg, nv, tv); | RepCartoonComputeTangents(nAt, seg, nv, tv); | |||
if(cartoon_flat_sheets) { | if(cartoon_flat_sheets) { | |||
RepCartoonFlattenSheetsRefineTips(G, obj, cs, nAt, seg, sstype, tv); | RepCartoonFlattenSheetsRefineTips(G, obj, cs, nAt, seg, sstype, tv); | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
I->ray = GenerateRepCartoonCGO(cs, obj, &ndata, na_strands_as_cylinders, false , pv, nAt, tv, pvo, dl, car, seg, at, nuc_flag, | I->ray = GenerateRepCartoonCGO(cs, obj, &ndata, na_strands_as_cylinders, pv, n At, tv, pvo, dl, car, seg, at, nuc_flag, | |||
putty_vals, alpha); | putty_vals, alpha); | |||
if (I->ray && I->ray->has_begin_end){ | if (I->ray && I->ray->has_begin_end){ | |||
CGOCombineBeginEnd(&I->ray); | CGOCombineBeginEnd(&I->ray); | |||
} | } | |||
if (I->preshader) { | if (I->preshader) { | |||
CGOAppend(I->preshader, I->ray); | CGOAppend(I->preshader, I->ray); | |||
CGOFree(I->ray); | CGOFree(I->ray); | |||
} else { | } else { | |||
I->preshader = I->ray; | I->preshader = I->ray; | |||
} | } | |||
} while (ndata.next_alt && cartoon_all_alt); | } while (ndata.next_alt && cartoon_all_alt); | |||
I->ray = I->preshader; | I->ray = I->preshader; | |||
CHECKOK(ok, I->ray); | CHECKOK(ok, I->ray); | |||
if (ok){ | ||||
int has_picking_cgo = 0; | ||||
CGO *convertcgo = GenerateRepCartoonCGO(cs, obj, &ndata, false, true, pv, nA | ||||
t, tv, pvo, dl, car, seg, at, nuc_flag, | ||||
putty_vals, alpha); | ||||
if (convertcgo){ | ||||
I->pickingCGO = CGOSimplify(convertcgo, 0); | ||||
if (I->pickingCGO){ | ||||
CGOFree(convertcgo); | ||||
convertcgo = CGOCombineBeginEnd(I->pickingCGO, 0); | ||||
if (convertcgo){ | ||||
CGOFree(I->pickingCGO); | ||||
I->pickingCGO = convertcgo; | ||||
has_picking_cgo = true; | ||||
} else { | ||||
CGOFree(I->pickingCGO); | ||||
I->pickingCGO = NULL; | ||||
} | ||||
} else { | ||||
CGOFree(convertcgo); | ||||
convertcgo = NULL; | ||||
} | ||||
} | ||||
ok &= has_picking_cgo; /* If picking object can't load, remove object */ | ||||
} | ||||
ok &= !G->Interrupt; | ok &= !G->Interrupt; | |||
if (!ok){ | if (!ok){ | |||
/* cannot generate RepCartoon */ | /* cannot generate RepCartoon */ | |||
RepCartoonFree(I); | RepCartoonFree(I); | |||
I = NULL; | I = NULL; | |||
} | } | |||
FreeP(dv); | FreeP(dv); | |||
FreeP(dl); | FreeP(dl); | |||
FreeP(tv); | FreeP(tv); | |||
FreeP(nv); | FreeP(nv); | |||
End of changes. 43 change blocks. | ||||
336 lines changed or deleted | 278 lines changed or added |