PageRenderTime 29ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/brlcad/branches/bullet/src/libged/loadview.c

https://bitbucket.org/vrrm/brl-cad-copy-for-fast-history-browsing-in-git
C | 383 lines | 285 code | 33 blank | 65 comment | 19 complexity | fee51fcafe7e56111082fdb6dcef2b31 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, Apache-2.0, AGPL-3.0, LGPL-3.0, GPL-3.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, 0BSD, BSD-3-Clause
  1. /* L O A D V I E W . C
  2. * BRL-CAD
  3. *
  4. * Copyright (c) 2008-2012 United States Government as represented by
  5. * the U.S. Army Research Laboratory.
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public License
  9. * version 2.1 as published by the Free Software Foundation.
  10. *
  11. * This library is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this file; see the file named COPYING for more
  18. * information.
  19. */
  20. /** @file libged/loadview.c
  21. *
  22. * The loadview command.
  23. *
  24. */
  25. #include "common.h"
  26. #include <stdlib.h>
  27. #include <ctype.h>
  28. #include <string.h>
  29. #include "bio.h"
  30. #include "./ged_private.h"
  31. vect_t _ged_eye_model;
  32. mat_t _ged_viewrot;
  33. struct ged *_ged_current_gedp;
  34. /**
  35. * here we define a minimal table of commands that are supported by the
  36. * loadview command. unsupported commands are those that have no bearing on
  37. * view restoration.
  38. */
  39. struct command_tab ged_loadview_cmdtab[] = {
  40. {"viewsize", "size in mm", "set view size",
  41. _ged_cm_vsize, 2, 2},
  42. {"eye_pt", "xyz of eye", "set eye point",
  43. _ged_cm_eyept, 4, 4},
  44. {"lookat_pt", "x y z [yflip]", "set eye look direction, in X-Y plane",
  45. _ged_cm_lookat_pt, 4, 5},
  46. {"viewrot", "4x4 matrix", "set view direction from matrix",
  47. _ged_cm_vrot, 17, 17},
  48. {"orientation", "quaternion", "set view direction from quaternion",
  49. _ged_cm_orientation, 5, 5},
  50. {"set", "", "show or set parameters",
  51. _ged_cm_set, 1, 999},
  52. /* begin unsupported commands (for view loading) */
  53. {"start", "frame number", "start a new frame",
  54. _ged_cm_null, 2, 2},
  55. {"clean", "", "clean articulation from previous frame",
  56. _ged_cm_null, 1, 1},
  57. {"end", "", "end of frame setup, begin raytrace",
  58. _ged_cm_null, 1, 1},
  59. /* not output, by default in saveview */
  60. {"multiview", "", "produce stock set of views",
  61. _ged_cm_null, 1, 1},
  62. {"anim", "path type args", "specify articulation animation",
  63. _ged_cm_null, 4, 999},
  64. {"tree", "treetop(s)", "specify alternate list of tree tops",
  65. _ged_cm_null, 1, 999},
  66. {"ae", "azim elev", "specify view as azim and elev, in degrees",
  67. _ged_cm_null, 3, 3},
  68. {"opt", "-flags", "set flags, like on command line",
  69. _ged_cm_null, 2, 999},
  70. /* this is a quick hack used for quietly parsing the EOF delimiter in the
  71. * script files.
  72. */
  73. {"EOF", "", "End of file delimiter",
  74. _ged_cm_null, 1, 1},
  75. /* XXX support for the ae command is not included, though it probably should */
  76. {(char *)0, (char *)0, (char *)0,
  77. 0, 0, 0 /* END */}
  78. };
  79. int
  80. ged_loadview(struct ged *gedp, int argc, const char *argv[])
  81. {
  82. int ret;
  83. FILE *fp;
  84. char buffer[512] = {0};
  85. /* data pulled from script file */
  86. int perspective=-1;
  87. #define MAX_DBNAME 2048
  88. char dbName[MAX_DBNAME] = {0};
  89. char objects[10000] = {0};
  90. char *editArgv[3];
  91. int prevPerspective;
  92. static const char *usage = "filename";
  93. GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
  94. GED_CHECK_VIEW(gedp, GED_ERROR);
  95. GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
  96. /* initialize result */
  97. bu_vls_trunc(gedp->ged_result_str, 0);
  98. /* must be wanting help */
  99. if (argc == 1) {
  100. bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
  101. return GED_HELP;
  102. }
  103. /* make sure the file exists */
  104. if (!bu_file_exists(argv[1], NULL)) {
  105. bu_log("Error: File %s does not exist\n", argv[1]);
  106. return GED_ERROR;
  107. }
  108. /* open the file for reading */
  109. if ((fp = fopen(argv[1], "r")) == NULL) {
  110. perror(argv[1]);
  111. return GED_ERROR;
  112. }
  113. prevPerspective = gedp->ged_gvp->gv_perspective;
  114. _ged_current_gedp = gedp;
  115. /* turn perspective mode off, by default. A "-p" option in the
  116. * view script will turn it back on.
  117. */
  118. gedp->ged_gvp->gv_perspective = 0;
  119. /* iterate over the contents of the raytrace script */
  120. /* TODO: change to bu_fgets or bu_vls_fgets */
  121. while (!feof(fp)) {
  122. memset(buffer, 0, 512);
  123. ret = fscanf(fp, "%512s", buffer);
  124. if (ret != 1)
  125. bu_log("Failed to read buffer\n");
  126. if (bu_strncmp(buffer, "-p", 2)==0) {
  127. /* we found perspective */
  128. buffer[0]=' ';
  129. buffer[1]=' ';
  130. sscanf(buffer, "%d", &perspective);
  131. /* bu_log("perspective=%d\n", perspective);*/
  132. gedp->ged_gvp->gv_perspective = perspective;
  133. } else if (bu_strncmp(buffer, "$*", 2)==0) {
  134. /* the next read is the file name, the objects come
  135. * after that
  136. */
  137. memset(dbName, 0, MAX_DBNAME);
  138. ret = fscanf(fp, "%2048s", dbName); /* MAX_DBNAME */
  139. if (ret != 1)
  140. bu_log("Failed to read database name\n");
  141. /* if the last character is a line termination,
  142. * remove it (it should always be unless the user
  143. * modifies the file)
  144. */
  145. if (*(dbName + strlen(dbName) - 1)=='\\') {
  146. memset(dbName+strlen(dbName)-1, 0, 1);
  147. }
  148. /* bu_log("dbName=%s\n", dbName); */
  149. if (!bu_same_file(gedp->ged_wdbp->dbip->dbi_filename, dbName)) {
  150. /* stop here if they are not the same file,
  151. * otherwise, we may proceed as expected, and load
  152. * the objects.
  153. */
  154. bu_vls_printf(gedp->ged_result_str, "View script references a different database\nCannot load the view without closing the current database\n(i.e. run \"opendb %s\")\n", dbName);
  155. /* restore state before leaving */
  156. gedp->ged_gvp->gv_perspective = prevPerspective;
  157. fclose(fp);
  158. return GED_ERROR;
  159. }
  160. /* get rid of anything that may be displayed, since we
  161. * will load objects that are listed in the script next.
  162. */
  163. (void)ged_zap(gedp, 1, NULL);
  164. /* now get the objects listed */
  165. ret = fscanf(fp, "%10000s", objects);
  166. if (ret != 1)
  167. bu_log("Failed to read object names\n");
  168. /* bu_log("OBJECTS=%s\n", objects);*/
  169. while ((!feof(fp)) && (bu_strncmp(objects, "\\", 1)!=0)) {
  170. /* clean off the single quotes... */
  171. if (bu_strncmp(objects, "'", 1)==0) {
  172. objects[0]=' ';
  173. memset(objects+strlen(objects)-1, ' ', 1);
  174. sscanf(objects, "%10000s", objects);
  175. }
  176. editArgv[0] = "draw";
  177. editArgv[1] = objects;
  178. editArgv[2] = (char *)NULL;
  179. if (ged_draw(gedp, 2, (const char **)editArgv) != GED_OK) {
  180. bu_vls_printf(gedp->ged_result_str, "Unable to load object: %s\n", objects);
  181. }
  182. /* bu_log("objects=%s\n", objects);*/
  183. ret = fscanf(fp, "%10000s", objects);
  184. if (ret != 1)
  185. bu_log("Failed to read object names\n");
  186. }
  187. /* end iteration over reading in listed objects */
  188. } else if (bu_strncmp(buffer, "<<EOF", 5)==0) {
  189. char *cmdBuffer = NULL;
  190. /* we are almost done .. read in the view commands */
  191. while ((cmdBuffer = rt_read_cmd(fp)) != NULL) {
  192. /* even unsupported commands should return successfully as
  193. * they should be calling ged_cm_null()
  194. */
  195. if (rt_do_cmd((struct rt_i *)0, cmdBuffer, ged_loadview_cmdtab) < 0) {
  196. bu_vls_printf(gedp->ged_result_str, "command failed: %s\n", cmdBuffer);
  197. }
  198. bu_free((genptr_t)cmdBuffer, "loadview cmdBuffer");
  199. }
  200. /* end iteration over rt commands */
  201. }
  202. /* end check for non-view values (dbname, etc.) */
  203. }
  204. /* end iteration over file until eof */
  205. fclose(fp);
  206. /* now we have to finish the eye point calculations that usually get
  207. * postponed until the end command runs. Since we are at the "end"
  208. * of a commands section, we may finish the computations.
  209. */
  210. /* First step: put eye at view center (view 0, 0, 0) */
  211. MAT_COPY(gedp->ged_gvp->gv_rotation, _ged_viewrot);
  212. MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, _ged_eye_model);
  213. ged_view_update(gedp->ged_gvp);
  214. return GED_OK;
  215. }
  216. int
  217. _ged_cm_vsize(int argc, char **argv)
  218. {
  219. if (argc < 2)
  220. return -1;
  221. /* for some reason, scale is supposed to be half of size... */
  222. _ged_current_gedp->ged_gvp->gv_size = atof(argv[1]);
  223. _ged_current_gedp->ged_gvp->gv_scale = _ged_current_gedp->ged_gvp->gv_size * 0.5;
  224. _ged_current_gedp->ged_gvp->gv_isize = 1.0 / _ged_current_gedp->ged_gvp->gv_size;
  225. return 0;
  226. }
  227. int
  228. _ged_cm_eyept(int argc, char **argv)
  229. {
  230. if (argc < 4)
  231. return -1;
  232. _ged_eye_model[X] = atof(argv[1]);
  233. _ged_eye_model[Y] = atof(argv[2]);
  234. _ged_eye_model[Z] = atof(argv[3]);
  235. /* Processing is deferred until ged_cm_end() */
  236. return 0;
  237. }
  238. int
  239. _ged_cm_lookat_pt(int argc, char **argv)
  240. {
  241. point_t pt;
  242. vect_t dir;
  243. if (argc < 4)
  244. return -1;
  245. pt[X] = atof(argv[1]);
  246. pt[Y] = atof(argv[2]);
  247. pt[Z] = atof(argv[3]);
  248. VSUB2(dir, pt, _ged_eye_model);
  249. VUNITIZE(dir);
  250. #if 1
  251. /*
  252. At the moment bn_mat_lookat will return NAN's if the direction vector
  253. is aligned with the Z axis. The following is a temporary workaround.
  254. */
  255. {
  256. vect_t neg_Z_axis;
  257. VSET(neg_Z_axis, 0.0, 0.0, -1.0);
  258. bn_mat_fromto(_ged_viewrot, dir, neg_Z_axis, &_ged_current_gedp->ged_wdbp->wdb_tol);
  259. }
  260. #else
  261. bn_mat_lookat(_ged_viewrot, dir, yflip);
  262. #endif
  263. /* Final processing is deferred until ged_cm_end(), but eye_pt
  264. * must have been specified before here (for now)
  265. */
  266. return 0;
  267. }
  268. int
  269. _ged_cm_vrot(int argc, char **argv)
  270. {
  271. int i;
  272. if (argc < 17)
  273. return -1;
  274. for (i = 0; i < 16; i++)
  275. _ged_viewrot[i] = atof(argv[i+1]);
  276. /* Processing is deferred until ged_cm_end() */
  277. return 0;
  278. }
  279. int
  280. _ged_cm_orientation(int argc, char **argv)
  281. {
  282. int i;
  283. quat_t quat;
  284. if (argc < 4)
  285. return -1;
  286. for (i = 0; i < 4; i++)
  287. quat[i] = atof(argv[i+1]);
  288. quat_quat2mat(_ged_viewrot, quat);
  289. return 0;
  290. }
  291. int
  292. _ged_cm_set(int UNUSED(argc), char **UNUSED(argv))
  293. {
  294. return -1;
  295. }
  296. /**
  297. * any commands that are not supported or implemented may call this null
  298. * routine to avoid rt_do_cmd() "command not found" error reporting
  299. */
  300. int
  301. _ged_cm_null(int argc, char **argv)
  302. {
  303. if (argc < 0 || argv == NULL)
  304. return 1;
  305. return 0;
  306. }
  307. /*
  308. * Local Variables:
  309. * tab-width: 8
  310. * mode: C
  311. * indent-tabs-mode: t
  312. * c-file-style: "stroustrup"
  313. * End:
  314. * ex: shiftwidth=4 tabstop=8
  315. */