PageRenderTime 69ms CodeModel.GetById 40ms RepoModel.GetById 1ms app.codeStats 0ms

/pymol-1.5.0.2/layer2/RepDistLabel.c

#
C | 469 lines | 382 code | 70 blank | 17 comment | 75 complexity | bb98e866cd6604de266eafd7be10bdbe MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. A* -------------------------------------------------------------------
  3. B* This file contains source code for the PyMOL computer program
  4. C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific.
  5. D* -------------------------------------------------------------------
  6. E* It is unlawful to modify or remove this copyright notice.
  7. F* -------------------------------------------------------------------
  8. G* Please see the accompanying LICENSE file for further information.
  9. H* -------------------------------------------------------------------
  10. I* Additional authors of this source file include:
  11. -*
  12. -*
  13. -*
  14. Z* -------------------------------------------------------------------
  15. */
  16. #include"os_python.h"
  17. #include"os_predef.h"
  18. #include"os_std.h"
  19. #include"os_gl.h"
  20. #include"OOMac.h"
  21. #include"RepDistLabel.h"
  22. #include"Color.h"
  23. #include"Scene.h"
  24. #include"main.h"
  25. #include"Vector.h"
  26. #include"Setting.h"
  27. #include"PyMOLObject.h"
  28. #include"Text.h"
  29. #include"Word.h"
  30. typedef char DistLabel[8];
  31. typedef struct RepDistLabel {
  32. Rep R;
  33. float *V;
  34. int N;
  35. DistLabel *L;
  36. CObject *Obj;
  37. DistSet *ds;
  38. int OutlineColor;
  39. } RepDistLabel;
  40. #include"ObjectDist.h"
  41. void RepDistLabelFree(RepDistLabel * I);
  42. void RepDistLabelFree(RepDistLabel * I)
  43. {
  44. VLAFreeP(I->V);
  45. VLAFreeP(I->L);
  46. RepPurge(&I->R);
  47. OOFreeP(I);
  48. }
  49. static void RepDistLabelRender(RepDistLabel * I, RenderInfo * info)
  50. {
  51. CRay *ray = info->ray;
  52. Picking **pick = info->pick;
  53. PyMOLGlobals *G = I->R.G;
  54. float *v = I->V;
  55. int c = I->N;
  56. DistLabel *l = I->L;
  57. int n = 0;
  58. int color;
  59. int font_id = SettingGet_i(G, I->ds->Setting, I->Obj->Setting, cSetting_label_font_id);
  60. float font_size = SettingGet_f(G, I->ds->Setting, I->Obj->Setting, cSetting_label_size);
  61. if(ray) {
  62. TextSetOutlineColor(G, I->OutlineColor);
  63. color = SettingGet_color(G, I->ds->Setting, I->Obj->Setting, cSetting_label_color);
  64. if((color >= 0) || (color == cColorFront) || (color == cColorBack))
  65. TextSetColor(G, ColorGet(G, color));
  66. else
  67. TextSetColor(G, ColorGet(G, I->Obj->Color));
  68. while(c--) {
  69. TextSetPos(G, v);
  70. TextRenderRay(G, ray, font_id, l[n], font_size, v + 3);
  71. v += 6;
  72. n++;
  73. }
  74. } else if(G->HaveGUI && G->ValidContext) {
  75. if(pick) {
  76. Pickable *p = I->R.P;
  77. int i;
  78. if(c) {
  79. int float_text = (int) SettingGet(G, cSetting_float_labels);
  80. if(float_text)
  81. glDisable(GL_DEPTH_TEST);
  82. i = (*pick)->src.index;
  83. while(c--) {
  84. if(*l) {
  85. int first_pass = (!(*pick)[0].src.bond);
  86. i++;
  87. TextSetPos(G, v);
  88. TextSetPickColor(G, first_pass, i);
  89. if(first_pass) {
  90. VLACheck((*pick), Picking, i);
  91. p++;
  92. (*pick)[i].src = *p; /* copy object and atom info */
  93. (*pick)[i].context = I->R.context;
  94. }
  95. TextRenderOpenGL(G, info, font_id, l[n], font_size, v + 3);
  96. n++;
  97. }
  98. v += 6;
  99. }
  100. if(float_text)
  101. glEnable(GL_DEPTH_TEST);
  102. (*pick)[0].src.index = i; /* pass the count */
  103. }
  104. } else {
  105. int float_text = SettingGet_i(G, I->ds->Setting,
  106. I->Obj->Setting,
  107. cSetting_float_labels);
  108. if(float_text)
  109. glDisable(GL_DEPTH_TEST);
  110. #ifdef PURE_OPENGL_ES_2
  111. /* TODO */
  112. #else
  113. if(!info->line_lighting)
  114. glDisable(GL_LIGHTING);
  115. #endif
  116. TextSetOutlineColor(G, I->OutlineColor);
  117. color = SettingGet_color(G, I->ds->Setting, I->Obj->Setting, cSetting_label_color);
  118. if((color >= 0) || (color == cColorFront) || (color == cColorBack))
  119. TextSetColor(G, ColorGet(G, color));
  120. else
  121. TextSetColor(G, ColorGet(G, I->Obj->Color));
  122. while(c--) {
  123. TextSetPos(G, v);
  124. TextRenderOpenGL(G, info, font_id, l[n], font_size, v + 3);
  125. v += 6;
  126. n++;
  127. }
  128. #ifdef PURE_OPENGL_ES_2
  129. /* TODO */
  130. #else
  131. glEnable(GL_LIGHTING);
  132. #endif
  133. if(float_text)
  134. glEnable(GL_DEPTH_TEST);
  135. }
  136. }
  137. }
  138. Rep *RepDistLabelNew(DistSet * ds, int state)
  139. {
  140. PyMOLGlobals *G = ds->State.G;
  141. int a;
  142. int n = 0;
  143. float *v, *v1, *v2, *v3, d[3], di;
  144. char buffer[255];
  145. float *lab_pos =
  146. SettingGet_3fv(G, ds->Setting, ds->Obj->Obj.Setting, cSetting_label_position);
  147. int default_digits =
  148. SettingGet_i(G, ds->Setting, ds->Obj->Obj.Setting, cSetting_label_digits);
  149. Pickable *rp = NULL;
  150. OOAlloc(G, RepDistLabel);
  151. if(!(ds->NIndex || ds->NAngleIndex || ds->NDihedralIndex)) {
  152. ds->NLabel = 0;
  153. VLAFreeP(ds->LabCoord);
  154. VLAFreeP(ds->LabPos);
  155. OOFreeP(I);
  156. return (NULL);
  157. }
  158. if(default_digits < 0)
  159. default_digits = 0;
  160. if(default_digits > 10)
  161. default_digits = 10;
  162. RepInit(G, &I->R);
  163. I->R.fRender = (void (*)(struct Rep *, RenderInfo *)) RepDistLabelRender;
  164. I->R.fFree = (void (*)(struct Rep *)) RepDistLabelFree;
  165. I->R.fRecolor = NULL;
  166. I->N = 0;
  167. I->V = NULL;
  168. I->R.P = NULL;
  169. I->Obj = (CObject *) ds->Obj;
  170. I->ds = ds;
  171. I->R.context.object = (void *) ds->Obj;
  172. I->R.context.state = state;
  173. I->OutlineColor =
  174. SettingGet_i(G, ds->Setting, I->Obj->Setting, cSetting_label_outline_color);
  175. if(ds->NIndex || ds->NAngleIndex || ds->NDihedralIndex) {
  176. float *lc;
  177. ds->NLabel = (ds->NIndex / 2 + ds->NAngleIndex / 5 + ds->NDihedralIndex / 6);
  178. if(!ds->LabCoord) { /* store label coordinates */
  179. ds->LabCoord = VLAlloc(float, 3 * ds->NLabel);
  180. } else {
  181. VLACheck(ds->LabCoord, float, 3 * ds->NLabel);
  182. }
  183. if(ds->LabPos) { /* make sure this VLA covers all labels */
  184. VLACheck(ds->LabPos, LabPosType, ds->NLabel);
  185. }
  186. if(SettingGet_f(G, ds->Setting, ds->Obj->Obj.Setting, cSetting_pickable)) {
  187. I->R.P = Alloc(Pickable, ds->NLabel + 1);
  188. ErrChkPtr(G, I->R.P);
  189. rp = I->R.P + 1; /* skip first record! */
  190. }
  191. I->V = VLAlloc(float, 3 * (ds->NIndex / 2 + ds->NAngleIndex / 5) + 1);
  192. I->L = VLAlloc(DistLabel, (ds->NIndex / 2 + ds->NAngleIndex / 5) + 1);
  193. n = 0;
  194. lc = ds->LabCoord;
  195. if(ds->NIndex) {
  196. int digits = SettingGet_i(G, ds->Setting, ds->Obj->Obj.Setting,
  197. cSetting_label_distance_digits);
  198. WordType format;
  199. if(digits < 0)
  200. digits = default_digits;
  201. if(digits > 10)
  202. digits = 10;
  203. sprintf(format, "%c0.%df", '%', digits);
  204. for(a = 0; a < ds->NIndex; a = a + 2) {
  205. v1 = ds->Coord + 3 * a;
  206. v2 = ds->Coord + 3 * (a + 1);
  207. average3f(v2, v1, d);
  208. di = (float) diff3f(v1, v2);
  209. sprintf(buffer, format, di);
  210. VLACheck(I->V, float, 6 * n + 5);
  211. VLACheck(I->L, DistLabel, n);
  212. v = I->V + 6 * n;
  213. strcpy(I->L[n], buffer);
  214. copy3f(d, v);
  215. *(lc++) = v[0];
  216. *(lc++) = v[1];
  217. *(lc++) = v[2];
  218. if(ds->LabPos) {
  219. LabPosType *lp = ds->LabPos + n;
  220. switch (lp->mode) {
  221. case 1:
  222. add3f(lp->offset, v, v);
  223. copy3f(lab_pos, v + 3);
  224. break;
  225. default:
  226. copy3f(lab_pos, v + 3);
  227. break;
  228. }
  229. } else {
  230. copy3f(lab_pos, v + 3);
  231. }
  232. if(rp) {
  233. rp->index = n; /* label index */
  234. rp->bond = cPickableLabel; /* label indicator */
  235. rp++;
  236. }
  237. n++;
  238. }
  239. }
  240. if(ds->NAngleIndex) {
  241. float d1[3], d2[3], n1[3], n2[3];
  242. float avg[3];
  243. float l1, l2;
  244. float radius;
  245. int digits = SettingGet_i(G, ds->Setting, ds->Obj->Obj.Setting,
  246. cSetting_label_angle_digits);
  247. WordType format;
  248. if(digits < 0)
  249. digits = default_digits;
  250. if(digits > 10)
  251. digits = 10;
  252. sprintf(format, "%c0.%df", '%', digits);
  253. for(a = 0; a < ds->NAngleIndex; a = a + 5) {
  254. v1 = ds->AngleCoord + 3 * a;
  255. v2 = ds->AngleCoord + 3 * (a + 1);
  256. v3 = ds->AngleCoord + 3 * (a + 2);
  257. subtract3f(v1, v2, d1);
  258. subtract3f(v3, v2, d2);
  259. normalize23f(d1, n1);
  260. normalize23f(d2, n2);
  261. average3f(n1, n2, avg);
  262. l1 = (float) length3f(d1);
  263. l2 = (float) length3f(d2);
  264. if(l1 > l2)
  265. radius = l2;
  266. else
  267. radius = l1;
  268. radius *=
  269. SettingGet_f(G, ds->Setting, ds->Obj->Obj.Setting,
  270. cSetting_angle_size) * SettingGet_f(G, ds->Setting,
  271. ds->Obj->Obj.Setting,
  272. cSetting_angle_label_position);
  273. normalize3f(avg);
  274. if((avg[0] == 0.0F) && (avg[1] == 0.0F) && (avg[2] == 0.0F))
  275. avg[0] = 1.0F;
  276. scale3f(avg, radius, avg);
  277. add3f(v2, avg, avg);
  278. di = (float) (180.0F * get_angle3f(d1, d2) / PI);
  279. sprintf(buffer, format, di);
  280. VLACheck(I->V, float, 6 * n + 5);
  281. VLACheck(I->L, DistLabel, n);
  282. v = I->V + 6 * n;
  283. strcpy(I->L[n], buffer);
  284. copy3f(avg, v);
  285. *(lc++) = v[0];
  286. *(lc++) = v[1];
  287. *(lc++) = v[2];
  288. if(ds->LabPos) {
  289. LabPosType *lp = ds->LabPos + n;
  290. switch (lp->mode) {
  291. case 1:
  292. add3f(lp->offset, v, v);
  293. copy3f(lab_pos, v + 3);
  294. break;
  295. default:
  296. copy3f(lab_pos, v + 3);
  297. break;
  298. }
  299. } else {
  300. copy3f(lab_pos, v + 3);
  301. }
  302. if(rp) {
  303. rp->index = n; /* label index */
  304. rp->bond = cPickableLabel; /* label indicator */
  305. rp++;
  306. }
  307. n++;
  308. }
  309. }
  310. if(ds->NDihedralIndex) {
  311. float d12[3], d32[3], d43[3], n32[3];
  312. float p12[3], p43[3], np12[3], np43[3];
  313. float a32[3];
  314. float l1, l2;
  315. float radius;
  316. float dihedral_size =
  317. SettingGet_f(G, ds->Setting, ds->Obj->Obj.Setting, cSetting_dihedral_size);
  318. float dihedral_label_position = SettingGet_f(G, ds->Setting, ds->Obj->Obj.Setting,
  319. cSetting_dihedral_label_position);
  320. float *v4, *v5, *v6;
  321. float avg[3];
  322. int digits = SettingGet_i(G, ds->Setting, ds->Obj->Obj.Setting,
  323. cSetting_label_dihedral_digits);
  324. WordType format;
  325. if(digits < 0)
  326. digits = default_digits;
  327. if(digits > 10)
  328. digits = 10;
  329. sprintf(format, "%c0.%df", '%', digits);
  330. for(a = 0; a < ds->NDihedralIndex; a = a + 6) {
  331. v1 = ds->DihedralCoord + 3 * a;
  332. v2 = v1 + 3;
  333. v3 = v1 + 6;
  334. v4 = v1 + 9;
  335. v5 = v1 + 12;
  336. v6 = v1 + 15;
  337. subtract3f(v1, v2, d12);
  338. subtract3f(v3, v2, d32);
  339. subtract3f(v4, v3, d43);
  340. normalize23f(d32, n32);
  341. remove_component3f(d12, n32, p12);
  342. remove_component3f(d43, n32, p43);
  343. average3f(v2, v3, a32);
  344. l1 = (float) length3f(p12);
  345. l2 = (float) length3f(p43);
  346. if(l1 > l2)
  347. radius = l2;
  348. else
  349. radius = l1;
  350. radius *= dihedral_size * dihedral_label_position;
  351. normalize23f(p12, np12);
  352. normalize23f(p43, np43);
  353. average3f(np12, np43, avg);
  354. normalize3f(avg);
  355. if((avg[0] == 0.0F) && (avg[1] == 0.0F) && (avg[2] == 0.0F))
  356. copy3f(np12, avg);
  357. scale3f(avg, radius, avg);
  358. add3f(a32, avg, avg);
  359. di = (float) (180.0F * get_dihedral3f(v1, v2, v3, v4) / PI);
  360. sprintf(buffer, format, di);
  361. VLACheck(I->V, float, 6 * n + 5);
  362. VLACheck(I->L, DistLabel, n);
  363. v = I->V + 6 * n;
  364. strcpy(I->L[n], buffer);
  365. copy3f(avg, v);
  366. *(lc++) = v[0];
  367. *(lc++) = v[1];
  368. *(lc++) = v[2];
  369. if(ds->LabPos) {
  370. LabPosType *lp = ds->LabPos + n;
  371. switch (lp->mode) {
  372. case 1:
  373. add3f(lp->offset, v, v);
  374. copy3f(lab_pos, v + 3);
  375. break;
  376. default:
  377. copy3f(lab_pos, v + 3);
  378. break;
  379. }
  380. } else {
  381. copy3f(lab_pos, v + 3);
  382. }
  383. copy3f(lab_pos, v + 3);
  384. if(rp) {
  385. rp->index = n; /* label index */
  386. rp->bond = cPickableLabel; /* label indicator */
  387. rp++;
  388. }
  389. n++;
  390. }
  391. }
  392. }
  393. I->N = n;
  394. if(rp) {
  395. I->R.P = ReallocForSure(I->R.P, Pickable, (rp - I->R.P));
  396. I->R.P[0].index = I->N; /* unnec? */
  397. }
  398. return ((void *) (struct Rep *) I);
  399. }