BRL-CAD
edpipe.c
Go to the documentation of this file.
1 /* E D P I P E . 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/edpipe.c
21  *
22  * Functions -
23  *
24  * split_pipept - split a pipe segment at a given point
25  *
26  * find_pipept_nearest_pt - find which segment of a pipe is nearest
27  * the ray from "pt" in the viewing direction (for segment selection
28  * in MGED)
29  */
30 
31 #include "common.h"
32 
33 #include <math.h>
34 #include <string.h>
35 
36 #include "vmath.h"
37 #include "nmg.h"
38 #include "rtgeom.h"
39 #include "ged.h"
40 #include "nurb.h"
41 #include "wdb.h"
42 
43 
44 /*
45  * Returns the index for the pipe segment matching ps.
46  */
47 int
48 _ged_get_pipe_i_seg(struct rt_pipe_internal *pipeip, struct wdb_pipept *ps)
49 {
50  struct wdb_pipept *curr_ps;
51  int seg_i = 0;
52 
53  for (BU_LIST_FOR(curr_ps, wdb_pipept, &pipeip->pipe_segs_head)) {
54  if (curr_ps == ps)
55  return seg_i;
56 
57  ++seg_i;
58  }
59 
60  return -1;
61 }
62 
63 
64 /*
65  * Returns segment seg_i.
66  */
67 struct wdb_pipept *
68 _ged_get_pipe_seg_i(struct rt_pipe_internal *pipeip, int seg_i)
69 {
70  int i = 0;
71  struct wdb_pipept *curr_ps;
72 
73  for (BU_LIST_FOR(curr_ps, wdb_pipept, &pipeip->pipe_segs_head)) {
74  if (i == seg_i)
75  return curr_ps;
76 
77  ++i;
78  }
79 
80  return (struct wdb_pipept *)NULL;
81 }
82 
83 
84 void
85 split_pipept(struct bu_list *UNUSED(pipe_hd), struct wdb_pipept *UNUSED(ps), fastf_t *UNUSED(new_pt))
86 {
87  bu_log("WARNING: pipe splitting unimplemented\n");
88 }
89 
90 
91 static fastf_t
92 edpipe_scale(fastf_t d, fastf_t scale)
93 {
94  if (scale < 0.0) {
95  /* negative value sets the scale */
96  return (-scale);
97  }
98 
99  /* positive value gets multiplied */
100  return (d * scale);
101 }
102 
103 
104 void
105 pipe_scale_od(struct rt_pipe_internal *pipeip, fastf_t scale)
106 {
107  struct wdb_pipept *ps;
108 
109  RT_PIPE_CK_MAGIC(pipeip);
110 
111  /* check that this can be done */
112  for (BU_LIST_FOR(ps, wdb_pipept, &pipeip->pipe_segs_head)) {
113  fastf_t tmp_od;
114 
115  tmp_od = edpipe_scale(ps->pp_od, scale);
116 
117  if (ps->pp_id > tmp_od) {
118  /* Silently ignore */
119  return;
120  }
121  if (tmp_od > 2.0*ps->pp_bendradius) {
122  /* Silently ignore */
123  return;
124  }
125  }
126 
127  for (BU_LIST_FOR(ps, wdb_pipept, &pipeip->pipe_segs_head)) {
128  ps->pp_od = edpipe_scale(ps->pp_od, scale);
129  }
130 }
131 
132 
133 void
134 pipe_scale_id(struct rt_pipe_internal *pipeip, fastf_t scale)
135 {
136  struct wdb_pipept *ps;
137 
138  RT_PIPE_CK_MAGIC(pipeip);
139 
140  /* check that this can be done */
141  for (BU_LIST_FOR(ps, wdb_pipept, &pipeip->pipe_segs_head)) {
142  fastf_t tmp_id;
143 
144  tmp_id = edpipe_scale(ps->pp_id, scale);
145 
146  if (ps->pp_od < tmp_id) {
147  /* Silently ignore */
148  return;
149  }
150  if (tmp_id > 2.0*ps->pp_bendradius) {
151  /* Silently ignore */
152  return;
153  }
154  }
155 
156  for (BU_LIST_FOR(ps, wdb_pipept, &pipeip->pipe_segs_head)) {
157  ps->pp_id = edpipe_scale(ps->pp_id, scale);
158  }
159 }
160 
161 
162 void
163 pipe_seg_scale_od(struct wdb_pipept *ps, fastf_t scale)
164 {
165  fastf_t tmp_od;
166 
167  BU_CKMAG(ps, WDB_PIPESEG_MAGIC, "pipe segment");
168 
169  tmp_od = edpipe_scale(ps->pp_od, scale);
170 
171  /* need to check that the new OD is not less than ID
172  * of any affected segment.
173  */
174  if (ps->pp_id > tmp_od) {
175  bu_log("Cannot make OD smaller than ID\n");
176  return;
177  }
178  if (tmp_od > 2.0*ps->pp_bendradius) {
179  bu_log("Cannot make outer radius greater than bend radius\n");
180  return;
181  }
182 
183  ps->pp_od = edpipe_scale(ps->pp_od, scale);
184 }
185 
186 
187 void
188 pipe_seg_scale_id(struct wdb_pipept *ps, fastf_t scale)
189 {
190  fastf_t tmp_id;
191 
192  BU_CKMAG(ps, WDB_PIPESEG_MAGIC, "pipe segment");
193 
194  tmp_id = edpipe_scale(ps->pp_id, scale);
195 
196  /* need to check that the new ID is not greater than OD */
197  if (ps->pp_od < tmp_id) {
198  bu_log( "Cannot make ID greater than OD\n");
199  return;
200  }
201  if (tmp_id > 2.0*ps->pp_bendradius) {
202  bu_log("Cannot make inner radius greater than bend radius\n");
203  return;
204  }
205 
206  ps->pp_id = edpipe_scale(ps->pp_id, scale);
207 }
208 
209 
210 void
211 pipe_seg_scale_radius(struct wdb_pipept *ps, fastf_t scale)
212 {
213  fastf_t old_radius;
214  struct wdb_pipept *head;
215 
216  BU_CKMAG(ps, WDB_PIPESEG_MAGIC, "pipe point");
217 
218  head = ps;
219  while (head->l.magic != BU_LIST_HEAD_MAGIC)
220  head = BU_LIST_NEXT(wdb_pipept, &head->l);
221 
222  /* make sure we can make this change */
223  old_radius = ps->pp_bendradius;
224 
225  ps->pp_bendradius = edpipe_scale(ps->pp_bendradius, scale);
226 
227  if (ps->pp_bendradius < ps->pp_od * 0.5) {
228  bu_log("Cannot make bend radius less than pipe outer radius\n");
229  ps->pp_bendradius = old_radius;
230  return;
231  }
232 
233  if (rt_pipe_ck(&head->l)) {
234  /* won't work, go back to original radius */
235  ps->pp_bendradius = old_radius;
236  return;
237  }
238 }
239 
240 
241 void
242 pipe_scale_radius(struct rt_pipe_internal *pipeip, fastf_t scale)
243 {
244  struct bu_list head;
245  struct wdb_pipept *old_ps, *new_ps;
246 
247  RT_PIPE_CK_MAGIC(pipeip);
248 
249  /* make a quick check for minimum bend radius */
250  for (BU_LIST_FOR(old_ps, wdb_pipept, &pipeip->pipe_segs_head)) {
251  if (scale < 0.0) {
252  if ((-scale) < old_ps->pp_od * 0.5) {
253  bu_log("Cannot make bend radius less than pipe outer radius\n");
254  return;
255  }
256  } else {
257  if (old_ps->pp_bendradius * scale < old_ps->pp_od * 0.5) {
258  bu_log("Cannot make bend radius less than pipe outer radius\n");
259  return;
260  }
261  }
262  }
263 
264  /* make temporary copy of this pipe solid */
265  BU_LIST_INIT(&head);
266  for (BU_LIST_FOR(old_ps, wdb_pipept, &pipeip->pipe_segs_head)) {
267  BU_GET(new_ps, struct wdb_pipept);
268  *new_ps = (*old_ps);
269  BU_LIST_APPEND(&head, &new_ps->l);
270  }
271 
272  /* make the desired editing changes to the copy */
273  for (BU_LIST_FOR(new_ps, wdb_pipept, &head)) {
274  new_ps->pp_bendradius = edpipe_scale(new_ps->pp_bendradius, scale);
275  }
276 
277  /* check if the copy is O.K. */
278  if (rt_pipe_ck(&head)) {
279  /* won't work, go back to original */
280  while (BU_LIST_NON_EMPTY(&head)) {
281  new_ps = BU_LIST_FIRST(wdb_pipept, &head);
282  BU_LIST_DEQUEUE(&new_ps->l);
283  BU_PUT(new_ps, struct wdb_pipept);
284  }
285  return;
286  }
287 
288  /* free temporary pipe solid */
289  while (BU_LIST_NON_EMPTY(&head)) {
290  new_ps = BU_LIST_FIRST(wdb_pipept, &head);
291  BU_LIST_DEQUEUE(&new_ps->l);
292  BU_PUT(new_ps, struct wdb_pipept);
293  }
294 
295  /* make changes to the original */
296  for (BU_LIST_FOR(old_ps, wdb_pipept, &pipeip->pipe_segs_head)) {
297  old_ps->pp_bendradius = edpipe_scale(old_ps->pp_bendradius, scale);
298  }
299 }
300 
301 
302 struct wdb_pipept *
303 find_pipept_nearest_pt(const struct bu_list *pipe_hd, const point_t model_pt, matp_t view2model)
304 {
305  struct wdb_pipept *ps;
306  struct wdb_pipept *nearest=(struct wdb_pipept *)NULL;
307  struct bn_tol tmp_tol;
308  fastf_t min_dist = MAX_FASTF;
309  vect_t dir, work;
310 
311  tmp_tol.magic = BN_TOL_MAGIC;
312  tmp_tol.dist = 0.0;
313  tmp_tol.dist_sq = tmp_tol.dist * tmp_tol.dist;
314  tmp_tol.perp = 0.0;
315  tmp_tol.para = 1.0 - tmp_tol.perp;
316 
317  /* get a direction vector in model space corresponding to z-direction in view */
318  VSET(work, 0.0, 0.0, 1.0);
319  MAT4X3VEC(dir, view2model, work);
320 
321  for (BU_LIST_FOR(ps, wdb_pipept, pipe_hd)) {
322  fastf_t dist;
323 
324  dist = bn_dist_line3_pt3(model_pt, dir, ps->pp_coord);
325  if (dist < min_dist) {
326  min_dist = dist;
327  nearest = ps;
328  }
329  }
330 
331  return nearest;
332 }
333 
334 
335 struct wdb_pipept *
336 _ged_add_pipept(struct rt_pipe_internal *pipeip, struct wdb_pipept *pp, const point_t new_pt)
337 {
338  struct wdb_pipept *last;
339  struct wdb_pipept *newpp;
340 
341  RT_PIPE_CK_MAGIC(pipeip);
342 
343  if (pp) {
344  BU_CKMAG(pp, WDB_PIPESEG_MAGIC, "pipe point");
345  last = pp;
346  } else {
347  /* add new point to end of pipe solid */
348  last = BU_LIST_LAST(wdb_pipept, &pipeip->pipe_segs_head);
349 
350  if (last->l.magic == BU_LIST_HEAD_MAGIC) {
351  BU_GET(newpp, struct wdb_pipept);
352  newpp->l.magic = WDB_PIPESEG_MAGIC;
353  newpp->pp_od = 30.0;
354  newpp->pp_id = 0.0;
355  newpp->pp_bendradius = 40.0;
356  VMOVE(newpp->pp_coord, new_pt);
357  BU_LIST_INSERT(&pipeip->pipe_segs_head, &newpp->l);
358  return newpp;
359  }
360  }
361 
362  /* build new point */
363  BU_GET(newpp, struct wdb_pipept);
364  newpp->l.magic = WDB_PIPESEG_MAGIC;
365  newpp->pp_od = last->pp_od;
366  newpp->pp_id = last->pp_id;
367  newpp->pp_bendradius = last->pp_bendradius;
368  VMOVE(newpp->pp_coord, new_pt);
369 
370  if (pp) {
371  /* append after current point */
372  BU_LIST_APPEND(&pp->l, &newpp->l);
373  } else {
374  /* add to end of pipe solid */
375  BU_LIST_INSERT(&pipeip->pipe_segs_head, &newpp->l);
376  }
377 
378  if (rt_pipe_ck(&pipeip->pipe_segs_head)) {
379  /* won't work here, so refuse to do it */
380  BU_LIST_DEQUEUE(&newpp->l);
381  BU_PUT(newpp, struct wdb_pipept);
382  return pp;
383  }
384 
385  return newpp;
386 }
387 
388 
389 struct wdb_pipept *
390 _ged_ins_pipept(struct rt_pipe_internal *pipeip, struct wdb_pipept *pp, const point_t new_pt)
391 {
392  struct wdb_pipept *first;
393  struct wdb_pipept *newpp;
394 
395  RT_PIPE_CK_MAGIC(pipeip);
396 
397  if (pp) {
398  BU_CKMAG(pp, WDB_PIPESEG_MAGIC, "pipe point");
399  first = pp;
400  } else {
401  /* insert new point at start of pipe solid */
402  first = BU_LIST_FIRST(wdb_pipept, &pipeip->pipe_segs_head);
403 
404  if (first->l.magic == BU_LIST_HEAD_MAGIC) {
405  BU_GET(newpp, struct wdb_pipept);
406  newpp->l.magic = WDB_PIPESEG_MAGIC;
407  newpp->pp_od = 30.0;
408  newpp->pp_id = 0.0;
409  newpp->pp_bendradius = 40.0;
410  VMOVE(newpp->pp_coord, new_pt);
411  BU_LIST_APPEND(&pipeip->pipe_segs_head, &newpp->l);
412  return newpp;
413  }
414  }
415 
416  /* build new point */
417  BU_GET(newpp, struct wdb_pipept);
418  newpp->l.magic = WDB_PIPESEG_MAGIC;
419  newpp->pp_od = first->pp_od;
420  newpp->pp_id = first->pp_id;
421  newpp->pp_bendradius = first->pp_bendradius;
422  VMOVE(newpp->pp_coord, new_pt);
423 
424  if (pp) {
425  /* insert before current point */
426  BU_LIST_INSERT(&pp->l, &newpp->l);
427  } else {
428  /* add to start of pipe */
429  BU_LIST_APPEND(&pipeip->pipe_segs_head, &newpp->l);
430  }
431 
432  if (rt_pipe_ck(&pipeip->pipe_segs_head)) {
433  /* won't work here, so refuse to do it */
434  BU_LIST_DEQUEUE(&newpp->l);
435  BU_PUT(newpp, struct wdb_pipept);
436  return pp;
437  }
438 
439  return newpp;
440 }
441 
442 
443 struct wdb_pipept *
444 _ged_delete_pipept(struct wdb_pipept *ps)
445 {
446  struct wdb_pipept *next;
447  struct wdb_pipept *prev;
448  struct wdb_pipept *head;
449 
450  BU_CKMAG(ps, WDB_PIPESEG_MAGIC, "pipe segment");
451 
452  head = ps;
453  while (head->l.magic != BU_LIST_HEAD_MAGIC)
454  head = BU_LIST_NEXT(wdb_pipept, &head->l);
455 
456  next = BU_LIST_NEXT(wdb_pipept, &ps->l);
457  if (next->l.magic == BU_LIST_HEAD_MAGIC)
458  next = (struct wdb_pipept *)NULL;
459 
460  prev = BU_LIST_PREV(wdb_pipept, &ps->l);
461  if (prev->l.magic == BU_LIST_HEAD_MAGIC)
462  prev = (struct wdb_pipept *)NULL;
463 
464  if (!prev && !next) {
465  bu_log("Cannot delete last point in pipe\n");
466  return ps;
467  }
468 
469  BU_LIST_DEQUEUE(&ps->l);
470 
471  if (rt_pipe_ck(&head->l)) {
472  bu_log("Cannot delete this point, it will result in an illegal pipe\n");
473  if (next) {
474  BU_LIST_INSERT(&next->l, &ps->l);
475  } else if (prev) {
476  BU_LIST_APPEND(&prev->l, &ps->l);
477  } else {
478  BU_LIST_INSERT(&head->l, &ps->l);
479  }
480 
481  return ps;
482  } else {
483  BU_PUT(ps, struct wdb_pipept);
484  }
485 
486  if (prev)
487  return prev;
488  else
489  return next;
490 
491 }
492 
493 
494 int
495 _ged_move_pipept(struct rt_pipe_internal *pipeip, struct wdb_pipept *ps, const point_t new_pt)
496 {
497  point_t old_pt;
498 
499  RT_PIPE_CK_MAGIC(pipeip);
500  BU_CKMAG(ps, WDB_PIPESEG_MAGIC, "pipe segment");
501 
502  VMOVE(old_pt, ps->pp_coord);
503 
504  VMOVE(ps->pp_coord, new_pt);
505  if (rt_pipe_ck(&pipeip->pipe_segs_head)) {
506  bu_log("Cannot move point there\n");
507  VMOVE(ps->pp_coord, old_pt);
508  return 1;
509  }
510 
511  return 0;
512 }
513 
514 
515 int
516 _ged_scale_pipe(struct ged *gedp, struct rt_pipe_internal *pipeip, const char *attribute, fastf_t sf, int rflag)
517 {
518  int seg_i;
519  struct wdb_pipept *ps;
520 
521  RT_PIPE_CK_MAGIC(pipeip);
522 
523  /* encode rflag as a negative scale so we don't have to pass it */
524  if (!rflag && sf > 0)
525  sf = -sf;
526 
527  switch (attribute[0]) {
528  case 'b':
529  case 'r':
530  if (sscanf(attribute+1, "%d", &seg_i) != 1)
531  seg_i = 0;
532 
533  if ((ps = _ged_get_pipe_seg_i(pipeip, seg_i)) == (struct wdb_pipept *)NULL)
534  return GED_ERROR;
535 
536  pipe_seg_scale_radius(ps, sf);
537  break;
538  case 'B':
539  case 'R':
540  pipe_scale_radius(pipeip, sf);
541  break;
542  case 'i':
543  if (sscanf(attribute+1, "%d", &seg_i) != 1)
544  seg_i = 0;
545 
546  if ((ps = _ged_get_pipe_seg_i(pipeip, seg_i)) == (struct wdb_pipept *)NULL)
547  return GED_ERROR;
548 
549  pipe_seg_scale_id(ps, sf);
550  break;
551  case 'I':
552  pipe_scale_id(pipeip, sf);
553  break;
554  case 'o':
555  if (sscanf(attribute+1, "%d", &seg_i) != 1)
556  seg_i = 0;
557 
558  if ((ps = _ged_get_pipe_seg_i(pipeip, seg_i)) == (struct wdb_pipept *)NULL)
559  return GED_ERROR;
560 
561  pipe_seg_scale_od(ps, sf);
562  break;
563  case 'O':
564  pipe_scale_od(pipeip, sf);
565  break;
566  default:
567  bu_vls_printf(gedp->ged_result_str, "bad pipe attribute - %s", attribute);
568  return GED_ERROR;
569  }
570 
571  return GED_OK;
572 }
573 
574 
575 int
576 _ged_append_pipept_common(struct ged *gedp, int argc, const char *argv[], struct wdb_pipept *(*func)(struct rt_pipe_internal *, struct wdb_pipept *, const point_t))
577 {
578  struct directory *dp;
579  static const char *usage = "pipe pt";
580  struct rt_db_internal intern;
581  struct rt_pipe_internal *pipeip;
582  mat_t mat;
583  point_t view_ps_pt;
584  point_t view_pp_coord;
585  point_t ps_pt;
586  struct wdb_pipept *prevpp;
587  double scan[3];
588  char *last;
589 
591  GED_CHECK_VIEW(gedp, GED_ERROR);
592  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
593 
594  /* initialize result */
595  bu_vls_trunc(gedp->ged_result_str, 0);
596 
597  /* must be wanting help */
598  if (argc == 1) {
599  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
600  return GED_HELP;
601  }
602 
603  if (argc != 3) {
604  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
605  return GED_ERROR;
606  }
607 
608  if ((last = strrchr(argv[1], '/')) == NULL)
609  last = (char *)argv[1];
610  else
611  ++last;
612 
613  if (last[0] == '\0') {
614  bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]);
615  return GED_ERROR;
616  }
617 
618  dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET);
619  if (dp == RT_DIR_NULL) {
620  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
621  return GED_ERROR;
622  }
623 
624  if (sscanf(argv[2], "%lf %lf %lf", &scan[X], &scan[Y], &scan[Z]) != 3) {
625  bu_vls_printf(gedp->ged_result_str, "%s: bad point - %s", argv[0], argv[2]);
626  return GED_ERROR;
627  }
628  /* convert from double to fastf_t */
629  VMOVE(view_ps_pt, scan);
630 
631  if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR)
632  return GED_ERROR;
633 
634  if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
635  intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_PIPE) {
636  bu_vls_printf(gedp->ged_result_str, "Object not a PIPE");
637  rt_db_free_internal(&intern);
638 
639  return GED_ERROR;
640  }
641 
642  pipeip = (struct rt_pipe_internal *)intern.idb_ptr;
643 
644  /* use the view z from the first or last pipe point, depending on whether we're appending or prepending */
645  if (func == _ged_add_pipept)
646  prevpp = BU_LIST_LAST(wdb_pipept, &pipeip->pipe_segs_head);
647  else
648  prevpp = BU_LIST_FIRST(wdb_pipept, &pipeip->pipe_segs_head);
649 
650  MAT4X3PNT(view_pp_coord, gedp->ged_gvp->gv_model2view, prevpp->pp_coord);
651  view_ps_pt[Z] = view_pp_coord[Z];
652  MAT4X3PNT(ps_pt, gedp->ged_gvp->gv_view2model, view_ps_pt);
653 
654  if ((*func)(pipeip, (struct wdb_pipept *)NULL, ps_pt) == (struct wdb_pipept *)NULL) {
655  rt_db_free_internal(&intern);
656  bu_vls_printf(gedp->ged_result_str, "%s: cannot move point there", argv[0]);
657  return GED_ERROR;
658  }
659 
660  {
661  mat_t invmat;
662  struct wdb_pipept *curr_ps;
663  point_t curr_pt;
664 
665  bn_mat_inv(invmat, mat);
666  for (BU_LIST_FOR(curr_ps, wdb_pipept, &pipeip->pipe_segs_head)) {
667  MAT4X3PNT(curr_pt, invmat, curr_ps->pp_coord);
668  VMOVE(curr_ps->pp_coord, curr_pt);
669  }
670 
671  GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
672  }
673 
674  rt_db_free_internal(&intern);
675  return GED_OK;
676 }
677 
678 
679 int
680 ged_append_pipept(struct ged *gedp, int argc, const char *argv[])
681 {
682  return _ged_append_pipept_common(gedp, argc, argv, _ged_add_pipept);
683 }
684 
685 
686 int
687 ged_delete_pipept(struct ged *gedp, int argc, const char *argv[])
688 {
689  struct directory *dp;
690  static const char *usage = "pipe seg_i";
691  struct rt_db_internal intern;
692  struct wdb_pipept *ps;
693  struct rt_pipe_internal *pipeip;
694  int seg_i;
695  char *last;
696 
698  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
699 
700  /* initialize result */
701  bu_vls_trunc(gedp->ged_result_str, 0);
702 
703  /* must be wanting help */
704  if (argc == 1) {
705  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
706  return GED_HELP;
707  }
708 
709  if (argc != 3) {
710  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
711  return GED_ERROR;
712  }
713 
714  if ((last = strrchr(argv[1], '/')) == NULL)
715  last = (char *)argv[1];
716  else
717  ++last;
718 
719  if (last[0] == '\0') {
720  bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]);
721  return GED_ERROR;
722  }
723 
724  dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET);
725  if (dp == RT_DIR_NULL) {
726  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
727  return GED_ERROR;
728  }
729 
730  if (sscanf(argv[2], "%d", &seg_i) != 1) {
731  bu_vls_printf(gedp->ged_result_str, "%s: bad pipe segment index - %s", argv[0], argv[3]);
732  return GED_ERROR;
733  }
734 
735  if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
736  bu_vls_printf(gedp->ged_result_str, "%s: failed to get internal for %s", argv[0], argv[1]);
737  return GED_ERROR;
738  }
739 
740  if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
741  intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_PIPE) {
742  bu_vls_printf(gedp->ged_result_str, "%s is not a PIPE", argv[1]);
743  rt_db_free_internal(&intern);
744 
745  return GED_ERROR;
746  }
747 
748  pipeip = (struct rt_pipe_internal *)intern.idb_ptr;
749  if ((ps = _ged_get_pipe_seg_i(pipeip, seg_i)) == (struct wdb_pipept *)NULL) {
750  rt_db_free_internal(&intern);
751  bu_vls_printf(gedp->ged_result_str, "%s: bad pipe segment index - %s", argv[0], argv[2]);
752  return GED_ERROR;
753  }
754 
755  if (_ged_delete_pipept(ps) == ps) {
756  rt_db_free_internal(&intern);
757  bu_vls_printf(gedp->ged_result_str, "%s: cannot delete pipe segment %d", argv[0], seg_i);
758  return GED_ERROR;
759  }
760 
761  GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
762 
763  rt_db_free_internal(&intern);
764  return GED_OK;
765 }
766 
767 
768 int
769 ged_find_pipept_nearest_pt(struct ged *gedp, int argc, const char *argv[])
770 {
771  struct directory *dp;
772  static const char *usage = "pipe x y z";
773  struct rt_db_internal intern;
774  struct wdb_pipept *nearest;
775  point_t model_pt;
776  double scan[3];
777  mat_t mat;
778  int seg_i;
779  char *last;
780 
782  GED_CHECK_VIEW(gedp, GED_ERROR);
783  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
784 
785  /* initialize result */
786  bu_vls_trunc(gedp->ged_result_str, 0);
787 
788  /* must be wanting help */
789  if (argc == 1) {
790  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
791  return GED_HELP;
792  }
793 
794  if (argc != 3 && argc != 5) {
795  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
796  return GED_ERROR;
797  }
798 
799  if ((last = strrchr(argv[1], '/')) == NULL)
800  last = (char *)argv[1];
801  else
802  ++last;
803 
804  if (last[0] == '\0') {
805  bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]);
806  return GED_ERROR;
807  }
808 
809  dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET);
810  if (dp == RT_DIR_NULL) {
811  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
812  return GED_ERROR;
813  }
814 
815  if (argc == 3) {
816  if (sscanf(argv[2], "%lf %lf %lf", &scan[X], &scan[Y], &scan[Z]) != 3) {
817  bu_vls_printf(gedp->ged_result_str, "%s: bad point - %s", argv[0], argv[2]);
818  return GED_ERROR;
819  }
820  } else if (sscanf(argv[2], "%lf", &scan[X]) != 1 ||
821  sscanf(argv[3], "%lf", &scan[Y]) != 1 ||
822  sscanf(argv[4], "%lf", &scan[Z]) != 1) {
823  bu_vls_printf(gedp->ged_result_str, "%s: bad X, Y or Z", argv[0]);
824  return GED_ERROR;
825  }
826  /* convert from double to fastf_t */
827  VMOVE(model_pt, scan);
828 
829  if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR)
830  return GED_ERROR;
831 
832  nearest = find_pipept_nearest_pt(&((struct rt_pipe_internal *)intern.idb_ptr)->pipe_segs_head,
833  model_pt, gedp->ged_gvp->gv_view2model);
834  seg_i = _ged_get_pipe_i_seg((struct rt_pipe_internal *)intern.idb_ptr, nearest);
835  rt_db_free_internal(&intern);
836 
837  if (seg_i < 0) {
838  bu_vls_printf(gedp->ged_result_str, "%s: failed to find segment for %s", argv[0], argv[1]);
839  return GED_ERROR;
840  }
841 
842  bu_vls_printf(gedp->ged_result_str, "%d", seg_i);
843  return GED_OK;
844 }
845 
846 
847 int
848 ged_move_pipept(struct ged *gedp, int argc, const char *argv[])
849 {
850  struct directory *dp;
851  static const char *usage = "[-r] pipe seg_i pt";
852  struct rt_db_internal intern;
853  struct wdb_pipept *ps;
854  struct rt_pipe_internal *pipeip;
855  mat_t mat;
856  point_t ps_pt;
857  double scan[3];
858  int seg_i;
859  int rflag = 0;
860  char *last;
861 
863  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
864 
865  /* initialize result */
866  bu_vls_trunc(gedp->ged_result_str, 0);
867 
868  /* must be wanting help */
869  if (argc == 1) {
870  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
871  return GED_HELP;
872  }
873 
874  if (argc < 4 || 5 < argc) {
875  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
876  return GED_ERROR;
877  }
878 
879  if (argc == 5) {
880  if (argv[1][0] != '-' || argv[1][1] != 'r' || argv[1][2] != '\0') {
881  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
882  return GED_ERROR;
883  }
884 
885  rflag = 1;
886  --argc;
887  ++argv;
888  }
889 
890  if ((last = strrchr(argv[1], '/')) == NULL)
891  last = (char *)argv[1];
892  else
893  ++last;
894 
895  if (last[0] == '\0') {
896  bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]);
897  return GED_ERROR;
898  }
899 
900  dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET);
901  if (dp == RT_DIR_NULL) {
902  bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
903  return GED_ERROR;
904  }
905 
906  if (sscanf(argv[2], "%d", &seg_i) != 1) {
907  bu_vls_printf(gedp->ged_result_str, "%s: bad pipe segment index - %s", argv[0], argv[2]);
908  return GED_ERROR;
909  }
910 
911  if (sscanf(argv[3], "%lf %lf %lf", &scan[X], &scan[Y], &scan[Z]) != 3) {
912  bu_vls_printf(gedp->ged_result_str, "%s: bad point - %s", argv[0], argv[3]);
913  return GED_ERROR;
914  }
915  VSCALE(ps_pt, scan, gedp->ged_wdbp->dbip->dbi_local2base);
916 
917  if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR)
918  return GED_ERROR;
919 
920  if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
921  intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_PIPE) {
922  bu_vls_printf(gedp->ged_result_str, "Object not a PIPE");
923  rt_db_free_internal(&intern);
924 
925  return GED_ERROR;
926  }
927 
928  pipeip = (struct rt_pipe_internal *)intern.idb_ptr;
929  if ((ps = _ged_get_pipe_seg_i(pipeip, seg_i)) == (struct wdb_pipept *)NULL) {
930  rt_db_free_internal(&intern);
931  bu_vls_printf(gedp->ged_result_str, "%s: bad pipe segment index - %s", argv[0], argv[2]);
932  return GED_ERROR;
933  }
934 
935  if (rflag) {
936  VADD2(ps_pt, ps_pt, ps->pp_coord);
937  }
938 
939  if (_ged_move_pipept(pipeip, ps, ps_pt)) {
940  rt_db_free_internal(&intern);
941  bu_vls_printf(gedp->ged_result_str, "%s: cannot move point there", argv[0]);
942  return GED_ERROR;
943  }
944 
945  {
946  mat_t invmat;
947  struct wdb_pipept *curr_ps;
948  point_t curr_pt;
949 
950  bn_mat_inv(invmat, mat);
951  for (BU_LIST_FOR(curr_ps, wdb_pipept, &pipeip->pipe_segs_head)) {
952  MAT4X3PNT(curr_pt, invmat, curr_ps->pp_coord);
953  VMOVE(curr_ps->pp_coord, curr_pt);
954  }
955 
956  GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
957  }
958 
959  rt_db_free_internal(&intern);
960  return GED_OK;
961 }
962 
963 
964 int
965 ged_prepend_pipept(struct ged *gedp, int argc, const char *argv[])
966 {
967  return _ged_append_pipept_common(gedp, argc, argv, _ged_ins_pipept);
968 }
969 
970 
971 /*
972  * Local Variables:
973  * mode: C
974  * tab-width: 8
975  * indent-tabs-mode: t
976  * c-file-style: "stroustrup"
977  * End:
978  * ex: shiftwidth=4 tabstop=8
979  */
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_OK
Definition: ged.h:55
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
#define BU_LIST_INSERT(old, new)
Definition: list.h:183
int rt_db_get_internal(struct rt_db_internal *ip, const struct directory *dp, const struct db_i *dbip, const mat_t mat, struct resource *resp)
Definition: dir.c:76
struct wdb_pipept * _ged_get_pipe_seg_i(struct rt_pipe_internal *pipeip, int seg_i)
Definition: edpipe.c:68
struct wdb_pipept * _ged_delete_pipept(struct wdb_pipept *ps)
Definition: edpipe.c:444
Definition: list.h:118
struct wdb_pipept * _ged_ins_pipept(struct rt_pipe_internal *pipeip, struct wdb_pipept *pp, const point_t new_pt)
Definition: edpipe.c:390
#define BU_LIST_LAST(structure, hp)
Definition: list.h:306
void pipe_seg_scale_id(struct wdb_pipept *ps, fastf_t scale)
Definition: edpipe.c:188
#define BU_CKMAG(_ptr, _magic, _str)
Definition: magic.h:233
void split_pipept(struct bu_list *pipe_hd, struct wdb_pipept *ps, fastf_t *new_pt)
Definition: edpipe.c:85
double dist
>= 0
Definition: tol.h:73
Definition: ged.h:338
struct db_i * dbip
Definition: raytrace.h:1266
#define VSET(a, b, c, d)
Definition: color.c:53
int rt_pipe_ck(const struct bu_list *headp)
Definition: pipe.c:4278
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
double dist_sq
dist * dist
Definition: tol.h:74
int ged_append_pipept(struct ged *gedp, int argc, const char *argv[])
Definition: edpipe.c:680
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
int ged_delete_pipept(struct ged *gedp, int argc, const char *argv[])
Definition: edpipe.c:687
#define BN_TOL_MAGIC
Definition: magic.h:74
int ged_prepend_pipept(struct ged *gedp, int argc, const char *argv[])
Definition: edpipe.c:965
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
void pipe_seg_scale_radius(struct wdb_pipept *ps, fastf_t scale)
Definition: edpipe.c:211
void pipe_seg_scale_od(struct wdb_pipept *ps, fastf_t scale)
Definition: edpipe.c:163
#define BU_LIST_APPEND(old, new)
Definition: list.h:197
#define BU_LIST_NON_EMPTY(hp)
Definition: list.h:296
#define MAX_FASTF
Definition: defines.h:340
#define GED_ERROR
Definition: ged.h:61
struct wdb_pipept * find_pipept_nearest_pt(const struct bu_list *pipe_hd, const point_t model_pt, matp_t view2model)
Definition: edpipe.c:303
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
mat_t gv_view2model
Definition: bview.h:224
int idb_major_type
Definition: raytrace.h:192
int _ged_scale_pipe(struct ged *gedp, struct rt_pipe_internal *pipeip, const char *attribute, fastf_t sf, int rflag)
Definition: edpipe.c:516
Definition: color.c:49
struct wdb_pipept * _ged_add_pipept(struct rt_pipe_internal *pipeip, struct wdb_pipept *pp, const point_t new_pt)
Definition: edpipe.c:336
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_move_pipept(struct ged *gedp, int argc, const char *argv[])
Definition: edpipe.c:848
#define LOOKUP_QUIET
Definition: raytrace.h:893
double bn_dist_line3_pt3(const point_t pt, const vect_t dir, const point_t a)
void bn_mat_inv(mat_t output, const mat_t input)
void pipe_scale_radius(struct rt_pipe_internal *pipeip, fastf_t scale)
Definition: edpipe.c:242
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
int _ged_get_pipe_i_seg(struct rt_pipe_internal *pipeip, struct wdb_pipept *ps)
Definition: edpipe.c:48
#define UNUSED(parameter)
Definition: common.h:239
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
Support for uniform tolerances.
Definition: tol.h:71
struct bu_vls * ged_result_str
Definition: ged.h:357
double perp
nearly 0
Definition: tol.h:75
#define BU_LIST_INIT(_hp)
Definition: list.h:148
void * idb_ptr
Definition: raytrace.h:195
int _ged_move_pipept(struct rt_pipe_internal *pipeip, struct wdb_pipept *ps, const point_t new_pt)
Definition: edpipe.c:495
mat_t gv_model2view
Definition: bview.h:222
uint32_t magic
Definition: tol.h:72
void pipe_scale_od(struct rt_pipe_internal *pipeip, fastf_t scale)
Definition: edpipe.c:105
#define WDB_PIPESEG_MAGIC
Definition: magic.h:214
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
void pipe_scale_id(struct rt_pipe_internal *pipeip, fastf_t scale)
Definition: edpipe.c:134
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
double dbi_local2base
local2mm
Definition: raytrace.h:807
#define BU_LIST_DEQUEUE(cur)
Definition: list.h:209
#define BU_LIST_HEAD_MAGIC
Definition: magic.h:56
double fastf_t
Definition: defines.h:300
int ged_find_pipept_nearest_pt(struct ged *gedp, int argc, const char *argv[])
Definition: edpipe.c:769
#define BU_LIST_NEXT(structure, hp)
Definition: list.h:316
double para
nearly 1
Definition: tol.h:76
#define BU_LIST_PREV(structure, hp)
Definition: list.h:310
void rt_db_free_internal(struct rt_db_internal *ip)
Definition: dir.c:216
Definition: color.c:50
#define BU_LIST_FIRST(structure, hp)
Definition: list.h:312
int _ged_append_pipept_common(struct ged *gedp, int argc, const char *argv[], struct wdb_pipept *(*func)(struct rt_pipe_internal *, struct wdb_pipept *, const point_t))
Definition: edpipe.c:576