BRL-CAD
edbot.c
Go to the documentation of this file.
1 /* E D B O T . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1995-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This program 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 program 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/edbot.c
21  *
22  */
23 
24 #include "common.h"
25 
26 #include <math.h>
27 #include <string.h>
28 
29 #include "vmath.h"
30 #include "nmg.h"
31 #include "rtgeom.h"
32 #include "ged.h"
33 #include "nurb.h"
34 #include "wdb.h"
35 
36 
37 int
38 ged_bot_edge_split(struct ged *gedp, int argc, const char *argv[])
39 {
40  static const char *usage = "bot edge";
41  struct directory *dp;
42  struct rt_db_internal intern;
43  struct rt_bot_internal *botip;
44  mat_t mat;
45  char *last;
46  size_t v1_i;
47  size_t v2_i;
48  size_t last_fi;
49  size_t last_vi;
50  size_t save_vi;
51  size_t i;
52  point_t new_pt;
53 
55  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
56 
57  /* initialize result */
58  bu_vls_trunc(gedp->ged_result_str, 0);
59 
60  /* must be wanting help */
61  if (argc == 1) {
62  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
63  return GED_HELP;
64  }
65 
66  if (argc != 3) {
67  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
68  return GED_ERROR;
69  }
70 
71  if ((last = strrchr(argv[1], '/')) == NULL)
72  last = (char *)argv[1];
73  else
74  ++last;
75 
76  if (last[0] == '\0') {
77  bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]);
78  return GED_ERROR;
79  }
80 
81  dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET);
82  if (dp == RT_DIR_NULL) {
83  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
84  return GED_ERROR;
85  }
86 
87  if (bu_sscanf(argv[2], "%zu %zu", &v1_i, &v2_i) != 2) {
88  bu_vls_printf(gedp->ged_result_str, "%s: bad bot edge - %s", argv[0], argv[2]);
89  return GED_ERROR;
90  }
91 
92  if (wdb_import_from_path2(gedp->ged_result_str, &intern, last, gedp->ged_wdbp, mat) == GED_ERROR) {
93  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
94  return GED_ERROR;
95  }
96 
97  if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
98  intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
99  bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
100  rt_db_free_internal(&intern);
101 
102  return GED_ERROR;
103  }
104 
105  botip = (struct rt_bot_internal *)intern.idb_ptr;
106  last_fi = botip->num_faces;
107  last_vi = botip->num_vertices;
108 
109  if (v1_i >= botip->num_vertices || v2_i >= botip->num_vertices) {
110  bu_vls_printf(gedp->ged_result_str, "%s: bad bot edge - %s", argv[0], argv[2]);
111  rt_db_free_internal(&intern);
112  return GED_ERROR;
113  }
114 
115  /*
116  * Create the new point, modify all faces (should only be two)
117  * that share the specified edge and hook in the two extra faces.
118  */
119 
120  /* First, create some space */
121  botip->num_vertices++;
122  botip->num_faces += 2;
123  botip->vertices = (fastf_t *)bu_realloc((void *)botip->vertices, botip->num_vertices*3*sizeof(fastf_t), "realloc bot vertices");
124  botip->faces = (int *)bu_realloc((void *)botip->faces, botip->num_faces*3*sizeof(int), "realloc bot faces");
125 
126  /* Create the new point. We're using the average of the edge's points */
127  VADD2(new_pt, &botip->vertices[v1_i*3], &botip->vertices[v2_i*3]);
128  VSCALE(new_pt, new_pt, 0.5);
129 
130  /* Add the new point to the last position in the list of vertices. */
131  VMOVE(&botip->vertices[last_vi*3], new_pt);
132 
133  /* Update faces associated with the specified edge */
134  for (i = 0; i < last_fi; ++i) {
135  if (((size_t)botip->faces[i*3] == v1_i && (size_t)botip->faces[i*3+1] == v2_i) ||
136  ((size_t)botip->faces[i*3] == v2_i && (size_t)botip->faces[i*3+1] == v1_i)) {
137 
138  save_vi = botip->faces[i*3+1];
139  botip->faces[i*3+1] = last_vi;
140 
141  /* Initialize a new face */
142  botip->faces[last_fi*3] = last_vi;
143  botip->faces[last_fi*3+1] = save_vi;
144  botip->faces[last_fi*3+2] = botip->faces[i*3+2];
145 
146  ++last_fi;
147  } else if (((size_t)botip->faces[i*3] == v1_i && (size_t)botip->faces[i*3+2] == v2_i) ||
148  ((size_t)botip->faces[i*3] == v2_i && (size_t)botip->faces[i*3+2] == v1_i)) {
149  save_vi = botip->faces[i*3];
150  botip->faces[i*3] = last_vi;
151 
152  /* Initialize a new face */
153  botip->faces[last_fi*3] = last_vi;
154  botip->faces[last_fi*3+1] = save_vi;
155  botip->faces[last_fi*3+2] = botip->faces[i*3+1];
156 
157  ++last_fi;
158  } else if (((size_t)botip->faces[i*3+1] == v1_i && (size_t)botip->faces[i*3+2] == v2_i) ||
159  ((size_t)botip->faces[i*3+1] == v2_i && (size_t)botip->faces[i*3+2] == v1_i)) {
160  save_vi = botip->faces[i*3+2];
161  botip->faces[i*3+2] = last_vi;
162 
163  /* Initialize a new face */
164  botip->faces[last_fi*3] = botip->faces[i*3];
165  botip->faces[last_fi*3+1] = last_vi;
166  botip->faces[last_fi*3+2] = save_vi;
167 
168  ++last_fi;
169  }
170 
171  if (last_fi >= botip->num_faces)
172  break;
173  }
174 
175  GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
176  rt_db_free_internal(&intern);
177  return GED_OK;
178 }
179 
180 
181 int
182 ged_bot_face_split(struct ged *gedp, int argc, const char *argv[])
183 {
184  static const char *usage = "bot face";
185  struct directory *dp;
186  static fastf_t sf = 1.0 / 3.0;
187  struct rt_db_internal intern;
188  struct rt_bot_internal *botip;
189  mat_t mat;
190  char *last;
191  size_t face_i;
192  size_t last_vi;
193  size_t save_vi;
194  point_t new_pt;
195 
197  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
198 
199  /* initialize result */
200  bu_vls_trunc(gedp->ged_result_str, 0);
201 
202  /* must be wanting help */
203  if (argc == 1) {
204  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
205  return GED_HELP;
206  }
207 
208  if (argc != 3) {
209  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
210  return GED_ERROR;
211  }
212 
213  if ((last = strrchr(argv[1], '/')) == NULL)
214  last = (char *)argv[1];
215  else
216  ++last;
217 
218  if (last[0] == '\0') {
219  bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]);
220  return GED_ERROR;
221  }
222 
223  dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET);
224  if (dp == RT_DIR_NULL) {
225  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
226  return GED_ERROR;
227  }
228 
229  if (bu_sscanf(argv[2], "%zu", &face_i) != 1) {
230  bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s", argv[0], argv[2]);
231  return GED_ERROR;
232  }
233 
234  if (wdb_import_from_path2(gedp->ged_result_str, &intern, last, gedp->ged_wdbp, mat) == GED_ERROR) {
235  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
236  return GED_ERROR;
237  }
238 
239  if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
240  intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
241  bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
242  rt_db_free_internal(&intern);
243 
244  return GED_ERROR;
245  }
246 
247  botip = (struct rt_bot_internal *)intern.idb_ptr;
248  last_vi = botip->num_vertices;
249 
250  if (face_i >= botip->num_faces) {
251  bu_vls_printf(gedp->ged_result_str, "%s: bad bot face index - %s", argv[0], argv[2]);
252  rt_db_free_internal(&intern);
253  return GED_ERROR;
254  }
255 
256  /* Create the new point, modify face_i and hook in the two extra faces */
257  /* First, create some space */
258  botip->num_vertices++;
259  botip->num_faces += 2;
260  botip->vertices = (fastf_t *)bu_realloc((void *)botip->vertices, botip->num_vertices*3*sizeof(fastf_t), "realloc bot vertices");
261  botip->faces = (int *)bu_realloc((void *)botip->faces, botip->num_faces*3*sizeof(int), "realloc bot faces");
262 
263  /* Create the new point. For the moment, we're using the average of the face_i's points */
264  VADD3(new_pt,
265  &botip->vertices[botip->faces[face_i*3]*3],
266  &botip->vertices[botip->faces[face_i*3+1]*3],
267  &botip->vertices[botip->faces[face_i*3+2]*3]);
268  VSCALE(new_pt, new_pt, sf);
269 
270  /* Add the new point to the last position in the list of vertices. */
271  VMOVE(&botip->vertices[last_vi*3], new_pt);
272 
273  /* Update face_i */
274  save_vi = botip->faces[face_i*3+2];
275  botip->faces[face_i*3+2] = last_vi;
276 
277  /* Initialize the two new faces */
278  botip->faces[(botip->num_faces-2)*3] = botip->faces[face_i*3+1];
279  botip->faces[(botip->num_faces-2)*3+1] = save_vi;
280  botip->faces[(botip->num_faces-2)*3+2] = last_vi;
281  botip->faces[(botip->num_faces-1)*3] = save_vi;
282  botip->faces[(botip->num_faces-1)*3+1] = botip->faces[face_i*3];
283  botip->faces[(botip->num_faces-1)*3+2] = last_vi;
284 
285  bu_vls_printf(gedp->ged_result_str, "%zu", last_vi);
286 
287  GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
288  rt_db_free_internal(&intern);
289  return GED_OK;
290 }
291 
292 
293 int
294 ged_find_bot_edge_nearest_pt(struct ged *gedp, int argc, const char *argv[])
295 {
296  static const char *usage = "bot view_xyz";
297  struct rt_db_internal intern;
298  struct rt_bot_internal *botip;
299  mat_t mat;
300  int vi1, vi2;
301  vect_t view;
302 
303  /* must be double for scanf */
304  double scan[ELEMENTS_PER_VECT];
305 
307  GED_CHECK_VIEW(gedp, GED_ERROR);
308  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
309 
310  /* initialize result */
311  bu_vls_trunc(gedp->ged_result_str, 0);
312 
313  /* must be wanting help */
314  if (argc == 1) {
315  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
316  return GED_HELP;
317  }
318 
319  if (argc != 3) {
320  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
321  return GED_ERROR;
322  }
323 
324  if (bu_sscanf(argv[2], "%lf %lf %lf", &scan[X], &scan[Y], &scan[Z]) != 3) {
325  bu_vls_printf(gedp->ged_result_str, "%s: bad view location - %s", argv[0], argv[2]);
326  return GED_ERROR;
327  }
328  VMOVE(view, scan); /* convert double to fastf_t */
329 
330  if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR) {
331  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
332  return GED_ERROR;
333  }
334 
335  if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
336  intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
337  bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
338  rt_db_free_internal(&intern);
339 
340  return GED_ERROR;
341  }
342 
343  botip = (struct rt_bot_internal *)intern.idb_ptr;
344  (void)rt_bot_find_e_nearest_pt2(&vi1, &vi2, botip, view, gedp->ged_gvp->gv_model2view);
345  bu_vls_printf(gedp->ged_result_str, "%d %d", vi1, vi2);
346 
347  rt_db_free_internal(&intern);
348  return GED_OK;
349 }
350 
351 
352 int
353 ged_find_botpt_nearest_pt(struct ged *gedp, int argc, const char *argv[])
354 {
355  static const char *usage = "bot view_xyz";
356  struct rt_db_internal intern;
357  struct rt_bot_internal *botip;
358  mat_t mat;
359  int nearest_pt;
360  vect_t view;
361 
362  /* must be double for scanf */
363  double scan[ELEMENTS_PER_VECT];
364 
366  GED_CHECK_VIEW(gedp, GED_ERROR);
367  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
368 
369  /* initialize result */
370  bu_vls_trunc(gedp->ged_result_str, 0);
371 
372  /* must be wanting help */
373  if (argc == 1) {
374  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
375  return GED_HELP;
376  }
377 
378  if (argc != 3) {
379  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
380  return GED_ERROR;
381  }
382 
383  if (bu_sscanf(argv[2], "%lf %lf %lf", &scan[X], &scan[Y], &scan[Z]) != 3) {
384  bu_vls_printf(gedp->ged_result_str, "%s: bad view location - %s", argv[0], argv[2]);
385  return GED_ERROR;
386  }
387 
388  if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR) {
389  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
390  return GED_ERROR;
391  }
392 
393  if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
394  intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
395  bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
396  rt_db_free_internal(&intern);
397 
398  return GED_ERROR;
399  }
400 
401  botip = (struct rt_bot_internal *)intern.idb_ptr;
402  VMOVE(view, scan); /* convert double to fastf_t */
403 
404  nearest_pt = rt_bot_find_v_nearest_pt2(botip, view, gedp->ged_gvp->gv_model2view);
405  bu_vls_printf(gedp->ged_result_str, "%d", nearest_pt);
406 
407  rt_db_free_internal(&intern);
408  return GED_OK;
409 }
410 
411 
412 int
413 ged_get_bot_edges(struct ged *gedp, int argc, const char *argv[])
414 {
415  static const char *usage = "bot";
416  struct rt_db_internal intern;
417  struct rt_bot_internal *botip;
418  mat_t mat;
419  size_t edge_count;
420  size_t *edge_list;
421 
423  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
424 
425  /* initialize result */
426  bu_vls_trunc(gedp->ged_result_str, 0);
427 
428  /* must be wanting help */
429  if (argc == 1) {
430  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
431  return GED_HELP;
432  }
433 
434  if (argc != 2) {
435  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
436  return GED_ERROR;
437  }
438 
439  if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR) {
440  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
441  return GED_ERROR;
442  }
443 
444  if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
445  intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
446  bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
447  rt_db_free_internal(&intern);
448 
449  return GED_ERROR;
450  }
451 
452  botip = (struct rt_bot_internal *)intern.idb_ptr;
453  if ((edge_count = rt_bot_get_edge_list(botip, &edge_list)) > 0) {
454  size_t i;
455 
456  for (i = 0; i < edge_count; i++)
457  bu_vls_printf(gedp->ged_result_str, "{%zu %zu} ", edge_list[i*2], edge_list[i*2+1]);
458 
459  bu_free(edge_list, "bot edge list");
460  }
461 
462  rt_db_free_internal(&intern);
463  return GED_OK;
464 }
465 
466 
467 int
468 ged_move_botpt(struct ged *gedp, int argc, const char *argv[])
469 {
470  static const char *usage = "[-r] bot vertex_i pt";
471  struct directory *dp;
472  struct rt_db_internal intern;
473  struct rt_bot_internal *botip;
474  mat_t mat;
475  size_t vertex_i;
476  int rflag = 0;
477  char *last;
478 
479  /* must be double for scanf */
480  double pt[ELEMENTS_PER_POINT];
481 
483  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
484 
485  /* initialize result */
486  bu_vls_trunc(gedp->ged_result_str, 0);
487 
488  /* must be wanting help */
489  if (argc == 1) {
490  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
491  return GED_HELP;
492  }
493 
494  if (argc < 4 || 5 < argc) {
495  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
496  return GED_ERROR;
497  }
498 
499  if (argc == 5) {
500  if (argv[1][0] != '-' || argv[1][1] != 'r' || argv[1][2] != '\0') {
501  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
502  return GED_ERROR;
503  }
504 
505  rflag = 1;
506  --argc;
507  ++argv;
508  }
509 
510  if ((last = strrchr(argv[1], '/')) == NULL)
511  last = (char *)argv[1];
512  else
513  ++last;
514 
515  if (last[0] == '\0') {
516  bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]);
517  return GED_ERROR;
518  }
519 
520  dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET);
521  if (dp == RT_DIR_NULL) {
522  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
523  return GED_ERROR;
524  }
525 
526  if (bu_sscanf(argv[2], "%zu", &vertex_i) != 1) {
527  bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s", argv[0], argv[2]);
528  return GED_ERROR;
529  }
530 
531  if (bu_sscanf(argv[3], "%lf %lf %lf", &pt[X], &pt[Y], &pt[Z]) != 3) {
532  bu_vls_printf(gedp->ged_result_str, "%s: bad point - %s", argv[0], argv[3]);
533  return GED_ERROR;
534  }
535 
536  VSCALE(pt, pt, gedp->ged_wdbp->dbip->dbi_local2base);
537 
538  if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR) {
539  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
540  return GED_ERROR;
541  }
542 
543  if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
544  intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
545  bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
546  rt_db_free_internal(&intern);
547 
548  return GED_ERROR;
549  }
550 
551  botip = (struct rt_bot_internal *)intern.idb_ptr;
552 
553  if (vertex_i >= botip->num_vertices) {
554  bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s", argv[0], argv[2]);
555  rt_db_free_internal(&intern);
556  return GED_ERROR;
557  }
558 
559  if (rflag) {
560  VADD2(&botip->vertices[vertex_i*3], pt, &botip->vertices[vertex_i*3]);
561  } else {
562  VMOVE(&botip->vertices[vertex_i*3], pt);
563  }
564 
565  {
566  mat_t invmat;
567  point_t curr_pt;
568  size_t idx;
569 
570  bn_mat_inv(invmat, mat);
571  for (idx = 0; idx < botip->num_vertices; idx++) {
572  MAT4X3PNT(curr_pt, invmat, &botip->vertices[idx*3]);
573  VMOVE(&botip->vertices[idx*3], curr_pt);
574  }
575  }
576 
577  GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
578  rt_db_free_internal(&intern);
579 
580  return GED_OK;
581 }
582 
583 
584 int
585 ged_move_botpts(struct ged *gedp, int argc, const char *argv[])
586 {
587  static const char *usage = "bot vec vertex_1 [vertex_2 ... vertex_n]";
588  struct directory *dp;
589  struct rt_db_internal intern;
590  struct rt_bot_internal *botip;
591  mat_t mat;
592  register int i;
593  size_t vertex_i;
594  char *last;
595 
596  /* must be double for scanf */
597  double vec[ELEMENTS_PER_VECT];
598 
600  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
601 
602  /* initialize result */
603  bu_vls_trunc(gedp->ged_result_str, 0);
604 
605  /* must be wanting help */
606  if (argc == 1) {
607  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
608  return GED_HELP;
609  }
610 
611  if (argc < 4) {
612  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
613  return GED_ERROR;
614  }
615 
616  if ((last = strrchr(argv[1], '/')) == NULL)
617  last = (char *)argv[1];
618  else
619  ++last;
620 
621  if (last[0] == '\0') {
622  bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]);
623  return GED_ERROR;
624  }
625 
626  dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET);
627  if (dp == RT_DIR_NULL) {
628  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
629  return GED_ERROR;
630  }
631 
632  if (bu_sscanf(argv[2], "%lf %lf %lf", &vec[X], &vec[Y], &vec[Z]) != 3) {
633  bu_vls_printf(gedp->ged_result_str, "%s: bad vector - %s", argv[0], argv[2]);
634  return GED_ERROR;
635  }
636 
637  VSCALE(vec, vec, gedp->ged_wdbp->dbip->dbi_local2base);
638 
639  if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR) {
640  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
641  return GED_ERROR;
642  }
643 
644  if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
645  intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
646  bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
647  rt_db_free_internal(&intern);
648 
649  return GED_ERROR;
650  }
651 
652  botip = (struct rt_bot_internal *)intern.idb_ptr;
653 
654  for (i = 3; i < argc; ++i) {
655  if (bu_sscanf(argv[i], "%zu", &vertex_i) != 1) {
656  bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s\n", argv[0], argv[i]);
657  continue;
658  }
659 
660  if (vertex_i >= botip->num_vertices) {
661  bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s\n", argv[0], argv[i]);
662  continue;
663  }
664 
665  VADD2(&botip->vertices[vertex_i*3], vec, &botip->vertices[vertex_i*3]);
666  }
667 
668  {
669  mat_t invmat;
670  point_t curr_pt;
671  size_t idx;
672 
673  bn_mat_inv(invmat, mat);
674  for (idx = 0; idx < botip->num_vertices; idx++) {
675  MAT4X3PNT(curr_pt, invmat, &botip->vertices[idx*3]);
676  VMOVE(&botip->vertices[idx*3], curr_pt);
677  }
678  }
679 
680  GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
681  rt_db_free_internal(&intern);
682 
683  return GED_OK;
684 }
685 
686 
687 int
688 _ged_select_botpts(struct ged *gedp, struct rt_bot_internal *botip, double vx, double vy, double vwidth, double vheight, double vminz, int rflag)
689 {
690  size_t i;
691  fastf_t vr = 0.0;
692  fastf_t vmin_x = 0.0;
693  fastf_t vmin_y = 0.0;
694  fastf_t vmax_x = 0.0;
695  fastf_t vmax_y = 0.0;
696 
698  GED_CHECK_VIEW(gedp, GED_ERROR);
699 
700  if (rflag) {
701  vr = vwidth;
702  } else {
703  vmin_x = vx;
704  vmin_y = vy;
705 
706  if (vwidth > 0)
707  vmax_x = vx + vwidth;
708  else {
709  vmin_x = vx + vwidth;
710  vmax_x = vx;
711  }
712 
713  if (vheight > 0)
714  vmax_y = vy + vheight;
715  else {
716  vmin_y = vy + vheight;
717  vmax_y = vy;
718  }
719  }
720 
721  if (rflag) {
722  for (i = 0; i < botip->num_vertices; i++) {
723  point_t vloc;
724  point_t vpt;
725  vect_t diff;
726  fastf_t mag;
727 
728  MAT4X3PNT(vpt, gedp->ged_gvp->gv_model2view, &botip->vertices[i*3]);
729 
730  if (vpt[Z] < vminz)
731  continue;
732 
733  VSET(vloc, vx, vy, vpt[Z]);
734  VSUB2(diff, vpt, vloc);
735  mag = MAGNITUDE(diff);
736 
737  if (mag > vr)
738  continue;
739 
740  bu_vls_printf(gedp->ged_result_str, "%zu ", i);
741  }
742  } else {
743  for (i = 0; i < botip->num_vertices; i++) {
744  point_t vpt;
745 
746  MAT4X3PNT(vpt, gedp->ged_gvp->gv_model2view, &botip->vertices[i*3]);
747 
748  if (vpt[Z] < vminz)
749  continue;
750 
751  if (vmin_x <= vpt[X] && vpt[X] <= vmax_x &&
752  vmin_y <= vpt[Y] && vpt[Y] <= vmax_y) {
753  bu_vls_printf(gedp->ged_result_str, "%zu ", i);
754  }
755  }
756  }
757 
758  return GED_OK;
759 }
760 
761 
762 /*
763  * Local Variables:
764  * mode: C
765  * tab-width: 8
766  * indent-tabs-mode: t
767  * c-file-style: "stroustrup"
768  * End:
769  * ex: shiftwidth=4 tabstop=8
770  */
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_OK
Definition: ged.h:55
int ged_get_bot_edges(struct ged *gedp, int argc, const char *argv[])
Definition: edbot.c:413
Definition: ged.h:338
size_t rt_bot_get_edge_list(const struct rt_bot_internal *bot, size_t **edge_list)
Definition: bot.c:1645
struct db_i * dbip
Definition: raytrace.h:1266
#define VSET(a, b, c, d)
Definition: color.c:53
int ged_find_botpt_nearest_pt(struct ged *gedp, int argc, const char *argv[])
Definition: edbot.c:353
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
#define GED_CHECK_ARGC_GT_0(_gedp, _argc, _flags)
Definition: ged.h:202
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
int rt_bot_find_e_nearest_pt2(int *vert1, int *vert2, const struct rt_bot_internal *bot, const point_t pt2, const mat_t mat)
Definition: bot.c:1709
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
int ged_move_botpts(struct ged *gedp, int argc, const char *argv[])
Definition: edbot.c:585
int rt_bot_find_v_nearest_pt2(const struct rt_bot_internal *bot, const point_t pt2, const mat_t mat)
Definition: bot.c:1614
int ged_move_botpt(struct ged *gedp, int argc, const char *argv[])
Definition: edbot.c:468
#define GED_ERROR
Definition: ged.h:61
int ged_find_bot_edge_nearest_pt(struct ged *gedp, int argc, const char *argv[])
Definition: edbot.c:294
struct bview * ged_gvp
Definition: ged.h:361
#define GED_DB_PUT_INTERNAL(_gedp, _dp, _intern, _resource, _flags)
Definition: ged.h:243
if(share_geom)
Definition: nmg_mod.c:3829
int idb_major_type
Definition: raytrace.h:192
Definition: color.c:49
struct resource rt_uniresource
default. Defined in librt/globals.c
Definition: globals.c:41
#define GED_CHECK_VIEW(_gedp, _flags)
Definition: ged.h:140
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
int _ged_select_botpts(struct ged *gedp, struct rt_bot_internal *botip, double vx, double vy, double vwidth, double vheight, double vminz, int rflag)
Definition: edbot.c:688
#define LOOKUP_QUIET
Definition: raytrace.h:893
void bn_mat_inv(mat_t output, const mat_t input)
int bu_sscanf(const char *src, const char *fmt,...) _BU_ATTR_SCANF23
Definition: sscanf.c:676
void * bu_realloc(void *ptr, size_t siz, const char *str)
struct bu_vls * ged_result_str
Definition: ged.h:357
void * idb_ptr
Definition: raytrace.h:195
mat_t gv_model2view
Definition: bview.h:222
int ged_bot_edge_split(struct ged *gedp, int argc, const char *argv[])
Definition: edbot.c:38
int ged_bot_face_split(struct ged *gedp, int argc, const char *argv[])
Definition: edbot.c:182
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
#define RT_DIR_NULL
Definition: raytrace.h:875
#define GED_HELP
Definition: ged.h:62
int idb_minor_type
ID_xxx.
Definition: raytrace.h:193
Definition: color.c:51
int wdb_import_from_path2(struct bu_vls *logstr, struct rt_db_internal *ip, const char *path, struct rt_wdb *wdb, matp_t matp)
Definition: wdb.c:364
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
double dbi_local2base
local2mm
Definition: raytrace.h:807
double fastf_t
Definition: defines.h:300
void rt_db_free_internal(struct rt_db_internal *ip)
Definition: dir.c:216
Definition: color.c:50