BRL-CAD
joint.c
Go to the documentation of this file.
1 /* J O I N T . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1985-2014 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 /** @addtogroup primitives */
21 /** @{ */
22 /** @file primitives/grip/grip.c
23  *
24  * Intersect a ray with a "joint" and return nothing.
25  *
26  * A JOINT is defined by a point location, two vectors and a
27  * joint value. The location is the point at which the vectors
28  * are constrained. The value is currently the angle between
29  * the vectors.
30  *
31  * All Ray intersections return "missed"
32  *
33  * The bounding box for a grip is empty.
34  *
35  */
36 
37 #include "common.h"
38 
39 #include <stddef.h>
40 #include <math.h>
41 #include "bio.h"
42 
43 #include "bu/cv.h"
44 #include "vmath.h"
45 #include "bn.h"
46 #include "rtgeom.h"
47 #include "raytrace.h"
48 #include "nmg.h"
49 #include "db.h"
50 #include "brep.h"
51 
52 #include "../../librt_private.h"
53 
54 
56  uint32_t joint_magic;
57  point_t joint_location;
60  vect_t joint_vector1;
61  vect_t joint_vector2;
62  fastf_t joint_value; /* currently angle or cross product value */
63 };
64 #define JOINT_NULL ((struct joint_specific *)0)
65 #define JOINT_FLOAT_SIZE 10
66 
67 const struct bu_structparse rt_joint_parse[] = {
68  { "%f", 3, "V", bu_offsetofarray(struct rt_joint_internal, location, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
69  { "%V", 1, "RP1", bu_offsetof(struct rt_joint_internal, reference_path_1), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
70  { "%V", 1, "RP2", bu_offsetof(struct rt_joint_internal, reference_path_2), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
71  { "%f", 3, "V1", bu_offsetofarray(struct rt_joint_internal, vector1, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
72  { "%f", 3, "V2", bu_offsetofarray(struct rt_joint_internal, vector2, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
73  { "%f", 1, "A", bu_offsetof(struct rt_joint_internal, value), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
74  { {'\0', '\0', '\0', '\0'}, 0, (char *)NULL, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
75 };
76 
77 
78 int
79 rt_joint_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
80 {
81  struct rt_joint_internal *jip;
82  struct joint_specific *jointp;
83 
84  if (rtip) RT_CK_RTI(rtip);
85 
86  jip = (struct rt_joint_internal *)ip->idb_ptr;
87  RT_JOINT_CK_MAGIC(jip);
88 
89  BU_GET(jointp, struct joint_specific);
90  stp->st_specific = (void *)jointp;
91 
92  VMOVE(jointp->joint_location, jip->location);
93  VMOVE(jointp->joint_vector1, jip->vector1);
94  VMOVE(jointp->joint_vector2, jip->vector2);
95  jointp->reference_path_1 = bu_vls_addr(&jip->reference_path_1);
96  jointp->reference_path_2 = bu_vls_addr(&jip->reference_path_2);
97  jointp->joint_value = jip->value;
98 
99 
100  /* No bounding sphere or bounding RPP is possible */
101  VSETALL(stp->st_min, 0.0);
102  VSETALL(stp->st_max, 0.0);
103 
104  stp->st_aradius = 0.0;
105  stp->st_bradius = 0.0;
106  return 0; /* OK */
107 }
108 
109 
110 void
111 rt_joint_print(const struct soltab *stp)
112 {
113  const struct joint_specific *jointp = (struct joint_specific *)stp->st_specific;
114 
115  if (jointp == JOINT_NULL) {
116  bu_log("joint(%s): no data?\n", stp->st_name);
117  return;
118  }
119  VPRINT("Location", jointp->joint_location);
120  VPRINT("Vector1", jointp->joint_vector1);
121  VPRINT("Vector2", jointp->joint_vector2);
122  bu_log("reference_path_1 = %f\n", jointp->reference_path_1);
123  bu_log("reference_path_2 = %f\n", jointp->reference_path_1);
124  bu_log("Value = %f\n", jointp->joint_value);
125 }
126 
127 
128 /**
129  * Function -
130  * Shoot a ray at a joint
131  *
132  * Algorithm -
133  * The intersection distance is computed.
134  *
135  * Returns -
136  * 0 MISS
137  * >0 HIT
138  */
139 int
140 rt_joint_shot(struct soltab *stp, struct xray *rp, struct application *ap, struct seg *UNUSED(seghead))
141 {
142  if (stp) RT_CK_SOLTAB(stp);
143  if (rp) RT_CK_RAY(rp);
144  if (ap) RT_CK_APPLICATION(ap);
145 
146  return 0; /* this has got to be the easiest.. no hit, no surfno,
147  * no nada.
148  */
149 }
150 
151 
152 /**
153  * Given ONE ray distance, return the normal and entry/exit point.
154  * The normal is already filled in.
155  */
156 void
157 rt_joint_norm(struct hit *hitp, struct soltab *stp, struct xray *rp)
158 {
159  if (hitp) RT_CK_HIT(hitp);
160  if (stp) RT_CK_SOLTAB(stp);
161  if (rp) RT_CK_RAY(rp);
162 
163  bu_bomb("rt_grp_norm: joints should never be hit.\n");
164 }
165 
166 
167 /**
168  * Return the "curvature" of the joint.
169  */
170 void
171 rt_joint_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp)
172 {
173  if (!cvp) return;
174  if (hitp) RT_CK_HIT(hitp);
175  if (stp) RT_CK_SOLTAB(stp);
176 
177  bu_bomb("rt_grp_curve: nobody should be asking for curve of a joint.\n");
178 }
179 
180 
181 /**
182  * For a hit on a face of an HALF, return the (u, v) coordinates of
183  * the hit point. 0 <= u, v <= 1. u extends along the Xbase
184  * direction. v extends along the "Ybase" direction. Note that a
185  * "toroidal" map is established, varying each from 0 up to 1 and then
186  * back down to 0 again.
187  */
188 void
189 rt_joint_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
190 {
191  if (ap) RT_CK_APPLICATION(ap);
192  if (stp) RT_CK_SOLTAB(stp);
193  if (hitp) RT_CK_HIT(hitp);
194  if (!uvp) return;
195 
196  bu_bomb("rt_grp_uv: nobody should be asking for UV of a joint.\n");
197 }
198 
199 
200 void
201 rt_joint_free(struct soltab *stp)
202 {
203  struct joint_specific *jointp = (struct joint_specific *)stp->st_specific;
204 
205  BU_PUT(jointp, struct joint_specific);
206 }
207 
208 
209 /**
210  * We represent a joint as a pyramid. The center describes where the
211  * center of the base is. The normal describes which direction the
212  * tip of the pyramid is. Mag describes the distance from the center
213  * to the tip. 1/4 of the width is the length of a base side.
214  *
215  */
216 
217 /**
218  * Plot a joint by tracing out joint vectors This draws each
219  * edge only once.
220  *
221  * XXX No checking for degenerate faces is done, but probably should
222  * be.
223  */
224 #define LOCATION_RADIUS 5
225 int
226 rt_joint_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *UNUSED(tol), const struct rt_view_info *UNUSED(info))
227 {
228  struct rt_joint_internal *jip;
229  point_t a = {LOCATION_RADIUS, 0, 0};
230  point_t b = {0, LOCATION_RADIUS, 0};
231  point_t c = {0, 0, LOCATION_RADIUS};
232  fastf_t top[16*3];
233  fastf_t middle[16*3];
234  fastf_t bottom[16*3];
235  int i;
236 
237  BU_CK_LIST_HEAD(vhead);
238  RT_CK_DB_INTERNAL(ip);
239  jip = (struct rt_joint_internal *)ip->idb_ptr;
240  RT_JOINT_CK_MAGIC(jip);
241 
242  rt_ell_16pts(top, jip->location, a, b);
243  rt_ell_16pts(bottom, jip->location, b, c);
244  rt_ell_16pts(middle, jip->location, a, c);
245 
246  RT_ADD_VLIST(vhead, &top[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE);
247  for (i = 0; i < 16; i++) {
248  RT_ADD_VLIST(vhead, &top[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW);
249  }
250 
251  RT_ADD_VLIST(vhead, &bottom[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE);
252  for (i = 0; i < 16; i++) {
253  RT_ADD_VLIST(vhead, &bottom[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW);
254  }
255 
256  RT_ADD_VLIST(vhead, &middle[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE);
257  for (i = 0; i < 16; i++) {
258  RT_ADD_VLIST(vhead, &middle[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW);
259  }
260 
261 
262  return 0;
263 }
264 
265 
266 /**
267  * Returns -
268  * -1 failure
269  * 0 success
270  */
271 int
272 rt_joint_import4(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *UNUSED(mat), const struct db_i *dbip)
273 {
274  if (ip) RT_CK_DB_INTERNAL(ip);
275  if (ep) BU_CK_EXTERNAL(ep);
276  if (dbip) RT_CK_DBI(dbip);
277 
278  return -1;
279 }
280 
281 
282 /**
283  * Returns -
284  * -1 failure
285  * 0 success
286  */
287 int
288 rt_joint_export4(struct bu_external *ep, const struct rt_db_internal *ip, double UNUSED(local2mm), const struct db_i *dbip)
289 {
290  if (ep) BU_CK_EXTERNAL(ep);
291  if (ip) RT_CK_DB_INTERNAL(ip);
292  if (dbip) RT_CK_DBI(dbip);
293 
294  return -1;
295 }
296 
297 
298 int
299 rt_joint_import5(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
300 {
301  struct rt_joint_internal *jip;
302  double f, t;
303 
304  /* must be double for import and export */
305  double vec[JOINT_FLOAT_SIZE];
306 
307  if (dbip) RT_CK_DBI(dbip);
308  RT_CK_DB_INTERNAL(ip);
309  BU_CK_EXTERNAL(ep);
310 
312 
313  ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
314  ip->idb_type = ID_JOINT;
315  ip->idb_meth = &OBJ[ID_JOINT];
316  BU_ALLOC(ip->idb_ptr, struct rt_joint_internal);
317 
318  jip = (struct rt_joint_internal *)ip->idb_ptr;
319  jip->magic = RT_JOINT_INTERNAL_MAGIC;
320 
321  /* Convert from database (network) to internal (host) format */
322  bu_cv_ntohd((unsigned char *)vec, ep->ext_buf, JOINT_FLOAT_SIZE);
323 
324  /* Transform the point, and the normal */
325  if (mat == NULL) mat = bn_mat_identity;
326 
327 
328  MAT4X3PNT(jip->location, mat, &vec[0]);
329  MAT4X3VEC(jip->vector1, mat, &vec[3]);
330  MAT4X3VEC(jip->vector2, mat, &vec[6]);
331  if (NEAR_ZERO(mat[15], 0.001)) {
332  bu_bomb("rt_joint_import5, scale factor near zero.");
333  }
334  jip->value = vec[9];
335 
336  /* convert name of reference_path_1 & 2*/
337  bu_vls_init(&jip->reference_path_1);
338  bu_vls_strcpy(&jip->reference_path_1, (char *)ep->ext_buf + JOINT_FLOAT_SIZE * SIZEOF_NETWORK_DOUBLE);
339  bu_vls_init(&jip->reference_path_2);
340  bu_vls_strcpy(&jip->reference_path_2, (char *)ep->ext_buf + JOINT_FLOAT_SIZE * SIZEOF_NETWORK_DOUBLE + bu_vls_strlen(&jip->reference_path_1) + 1);
341 
342  /* Verify that vector1 has unit length */
343  f = MAGNITUDE(jip->vector1);
344  if (f <= SMALL) {
345  bu_log("rt_joint_import5: bad vector1, len=%g\n", f);
346  return -1; /* BAD */
347  }
348  t = f - 1.0;
349  if (!NEAR_ZERO(t, 0.001)) {
350  /* Restore normal to unit length */
351  f = 1/f;
352  VSCALE(jip->vector1, jip->vector1, f);
353  }
354  /* Verify that vector2 has unit length */
355  f = MAGNITUDE(jip->vector2);
356  if (f <= SMALL) {
357  bu_log("rt_joint_import5: bad vector2, len=%g\n", f);
358  return -1; /* BAD */
359  }
360  t = f - 1.0;
361  if (!NEAR_ZERO(t, 0.001)) {
362  /* Restore normal to unit length */
363  f = 1/f;
364  VSCALE(jip->vector2, jip->vector2, f);
365  }
366 
367 
368  return 0; /* OK */
369 }
370 
371 
372 int
373 rt_joint_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
374 {
375  struct rt_joint_internal *jip;
376  unsigned char *ptr;
377 
378  /* must be double for import and export */
379  double vec[JOINT_FLOAT_SIZE];
380 
381  if (dbip) RT_CK_DBI(dbip);
382 
383  RT_CK_DB_INTERNAL(ip);
384  if (ip->idb_type != ID_JOINT) return -1;
385  jip = (struct rt_joint_internal *)ip->idb_ptr;
386  RT_JOINT_CK_MAGIC(jip);
387 
388  BU_CK_EXTERNAL(ep);
390  bu_vls_strlen(&jip->reference_path_1) + 1 +
391  + bu_vls_strlen(&jip->reference_path_2) + 1;
392  ep->ext_buf = (uint8_t *)bu_malloc(ep->ext_nbytes, "joint external");
393  ptr = (unsigned char *)ep->ext_buf;
394 
395  VSCALE(&vec[0], jip->location, local2mm);
396  VMOVE(&vec[3], jip->vector1);
397  VMOVE(&vec[6], jip->vector2);
398  vec[9] = jip->value;
399 
400  /* Convert from internal (host) to database (network) format */
401  bu_cv_htond(ep->ext_buf, (unsigned char *)vec, JOINT_FLOAT_SIZE);
402 
404  bu_strlcpy((char *)ptr, bu_vls_addr(&jip->reference_path_1), bu_vls_strlen(&jip->reference_path_1) + 1);
405 
406  ptr += bu_vls_strlen(&jip->reference_path_1) + 1;
407  bu_strlcpy((char *)ptr, bu_vls_addr(&jip->reference_path_2), bu_vls_strlen(&jip->reference_path_2) + 1);
408 
409  return 0;
410 }
411 
412 
413 /**
414  * Make human-readable formatted presentation of this solid. First
415  * line describes type of solid. Additional lines are indented one
416  * tab, and give parameter values.
417  */
418 int
419 rt_joint_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
420 {
421  struct rt_joint_internal *jip = (struct rt_joint_internal *)ip->idb_ptr;
422  char buf[256];
423 
424  RT_JOINT_CK_MAGIC(jip);
425  bu_vls_strcat(str, "joint\n");
426 
427  sprintf(buf, "\tV (%g, %g, %g)\n",
428  V3INTCLAMPARGS(jip->location)); /* should have unit length */
429 
430  bu_vls_strcat(str, buf);
431 
432  if (!verbose)
433  return 0;
434 
435  sprintf(buf, "\tV1 (%g %g %g) V2 (%g %g %g) A=%g RP1=%s RP2=%s\n",
436  INTCLAMP(jip->vector1[0]*mm2local),
437  INTCLAMP(jip->vector1[1]*mm2local),
438  INTCLAMP(jip->vector1[2]*mm2local),
439  INTCLAMP(jip->vector2[0]*mm2local),
440  INTCLAMP(jip->vector2[1]*mm2local),
441  INTCLAMP(jip->vector2[2]*mm2local),
442  INTCLAMP(jip->value*mm2local),
443  bu_vls_addr(&jip->reference_path_1),
444  bu_vls_addr(&jip->reference_path_2));
445  bu_vls_strcat(str, buf);
446 
447  return 0;
448 }
449 
450 
451 /**
452  * Free the storage associated with the rt_db_internal version of this
453  * solid.
454  */
455 void
457 {
458  RT_CK_DB_INTERNAL(ip);
459 
460  bu_free(ip->idb_ptr, "joint ifree");
461  ip->idb_ptr = ((void *)0);
462 }
463 
464 
465 int
466 rt_joint_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *UNUSED(tol))
467 {
468  struct rt_joint_internal *jip;
469 
470  if (r) *r = NULL;
471  if (m) NMG_CK_MODEL(m);
472 
473  RT_CK_DB_INTERNAL(ip);
474  jip = (struct rt_joint_internal *)ip->idb_ptr;
475  RT_JOINT_CK_MAGIC(jip);
476 
477  /* XXX tess routine needed */
478  return -1;
479 }
480 
481 
482 int
483 rt_joint_params(struct pc_pc_set *UNUSED(ps), const struct rt_db_internal *ip)
484 {
485  if (ip) RT_CK_DB_INTERNAL(ip);
486 
487  return 0; /* OK */
488 }
489 
490 /* TODO: should be dynamic */
491 #define JOINT_SELECT_VMAX_DISTSQ 100.0
492 
493 enum {
499 };
500 
502  int what;
503  vect_t start;
504 };
505 
506 static void
507 joint_free_selection(struct rt_selection *s)
508 {
509  struct joint_selection *js = (struct joint_selection *)s->obj;
510  BU_PUT(js, struct joint_selection);
511  BU_FREE(s, struct rt_selection);
512 }
513 
514 struct rt_selection_set *
516  const struct rt_db_internal *ip,
517  const struct rt_selection_query *query)
518 {
519  struct rt_joint_internal *jip;
520  fastf_t dist[3];
521  point_t qline_pt;
522  vect_t qstart;
523  point_t qdir;
524  struct joint_selection *joint_selection = NULL;
525  struct rt_selection *selection = NULL;
526  struct rt_selection_set *selection_set = NULL;
527  struct bn_tol tol;
528 
529 #if 0
530  fastf_t dist_sq1, dist_sq2;
531  point_t joint_v1pt;
532 #endif
533 
534  RT_CK_DB_INTERNAL(ip);
535  jip = (struct rt_joint_internal *)ip->idb_ptr;
536  RT_JOINT_CK_MAGIC(jip);
537 
538  /* select location, or vector1, or vector2 */
539  /* vectors are plotted location to location+vector */
540  /* distinguish between close to location and close to vector */
541  /* shortest distance between query vector and vector1, 2 */
542  /* if vector 1, 2 point is within radius of location, select
543  * location, otherwise select vector with shorter distance */
544  VMOVE(qstart, query->start);
545  VMOVE(qdir, query->dir);
546 
547  BU_GET(joint_selection, struct joint_selection);
548  joint_selection->what = JOINT_SELECT_V1;
549 
550  /* closest point on query line to location (same as the
551  * intersection between the query line and the plane parallel to
552  * the view plane that intersects the location)
553  */
554  BN_TOL_INIT(&tol);
555  (void)bn_dist_pt3_line3(dist, qline_pt, qstart, qdir, jip->location, &tol);
556  VJOIN1(joint_selection->start, qline_pt, -1.0, jip->location);
557 
558 #if 0
559  ret = bn_distsq_line3_line3(dist, qstart, qdir, jip->location,
560  jip->vector1, qline_pt, joint_v1pt);
561  dist_sq1 = dist[2];
562 
563  if (ret == 1) {
564  /* query ray is parallel to vector 1 */
565  BU_GET(joint_selection, struct joint_selection);
566  joint_selection->what = JOINT_SELECT_V1;
567  } else {
568  point_t joint_v2pt;
569  fastf_t distsq_to_loc;
570  fastf_t max_vdist;
571 
572  ret = bn_distsq_line3_line3(dist, qstart, qdir, jip->location,
573  jip->vector2, qline_pt, joint_v2pt);
574  dist_sq2 = dist[2];
575 
576  if (dist_sq1 > JOINT_SELECT_VMAX_DISTSQ &&
577  dist_sq2 > JOINT_SELECT_VMAX_DISTSQ)
578  {
579  /* query isn't close enough */
580  bu_log("selected nothing.\n");
581  return NULL;
582  }
583 
584  BU_GET(joint_selection, struct joint_selection);
585  if (dist_sq1 <= dist_sq2) {
586  /* closer to v1 than v2 */
587  distsq_to_loc = DIST_PT_PT_SQ(joint_v1pt, jip->location);
588  max_vdist = .1 * MAGSQ(jip->vector1);
589  joint_selection->what = JOINT_SELECT_V1;
590  } else {
591  /* closer to v2 than v1 */
592  distsq_to_loc = DIST_PT_PT_SQ(joint_v2pt, jip->location);
593  max_vdist = .1 * MAGSQ(jip->vector2);
594  joint_selection->what = JOINT_SELECT_V2;
595  }
596 
597  if (distsq_to_loc < max_vdist) {
598  /* closer to location than v1 */
599  joint_selection->what = JOINT_SELECT_LOC;
600  }
601  }
602 
603  if (!joint_selection) {
604  bu_log("selected nothing.\n");
605  return NULL;
606  }
607 
608  switch (joint_selection->what) {
609  case JOINT_SELECT_LOC:
610  bu_log("selected location.\n");
611  break;
612  case JOINT_SELECT_V1:
613  bu_log("selected vector1.\n");
614  break;
615  case JOINT_SELECT_V2:
616  bu_log("selected vector2.\n");
617  }
618 #endif
619 
620  /* build and return list of selections */
621  BU_ALLOC(selection_set, struct rt_selection_set);
622  BU_PTBL_INIT(&selection_set->selections);
623 
624  BU_GET(selection, struct rt_selection);
625  selection->obj = (void *)joint_selection;
626  bu_ptbl_ins(&selection_set->selections, (long *)selection);
627  selection_set->free_selection = joint_free_selection;
628 
629  return selection_set;
630 }
631 
632 int
634  struct rt_db_internal *ip,
635  struct db_i *dbip,
636  const struct rt_selection *selection,
637  const struct rt_selection_operation *op)
638 {
639  struct joint_selection *js;
640  struct rt_joint_internal *jip;
641  mat_t pmat;
642  vect_t delta, end, cross;
643  fastf_t angle;
644  struct rt_db_internal path_ip;
645  struct directory *dp;
646  struct db_full_path fpath;
647  /*int ret;*/
648 
649  if (op->type == RT_SELECTION_NOP) {
650  return 0;
651  }
652 
653  if (op->type != RT_SELECTION_TRANSLATION) {
654  return -1;
655  }
656 
657  RT_CK_DB_INTERNAL(ip);
658  jip = (struct rt_joint_internal *)ip->idb_ptr;
659  RT_JOINT_CK_MAGIC(jip);
660 
661  js = (struct joint_selection *)selection->obj;
662  if (!js) {
663  return -1;
664  }
665 
666  delta[X] = op->parameters.tran.dx;
667  delta[Y] = op->parameters.tran.dy;
668  delta[Z] = op->parameters.tran.dz;
669 
670  if (VNEAR_ZERO(delta, BN_TOL_DIST)) {
671  return 0;
672  }
673 
674  VADD2(end, js->start, delta);
675 
676  angle = VDOT(js->start, end);
677  angle /= MAGNITUDE(js->start) * MAGNITUDE(end);
678  angle = acos(angle);
679 
680  VCROSS(cross, js->start, end);
681  VUNITIZE(cross);
682 
683  /* get solid or parent comb directory */
684  /*ret =*/ (void)db_string_to_path(&fpath, dbip, bu_vls_cstr(&jip->reference_path_1));
685  if (fpath.fp_len < 1) {
686  dp = NULL;
687  } else if (fpath.fp_len == 1) {
688  dp = db_lookup(dbip, bu_vls_cstr(&jip->reference_path_1), LOOKUP_QUIET);
689  } else {
690  dp = DB_FULL_PATH_GET(&fpath, fpath.fp_len - 2);
691  }
692  if (dp == RT_DIR_NULL) {
693  bu_log("lookup failed\n");
694  db_free_full_path(&fpath);
695  return 0;
696  }
697 
698  /* modify solid matrix or parent comb's member matrix */
699  if (fpath.fp_len > 1) {
700  char *member_name = DB_FULL_PATH_CUR_DIR(&fpath)->d_namep;
701  struct rt_comb_internal *comb_ip;
702  union tree *comb_tree, *member;
703  mat_t idn, path_mat, combined_mat;
704  vect_t rot_dir;
705 
706  MAT_IDN(idn);
707 
708  rt_db_get_internal(&path_ip, dp, dbip, idn, NULL);
709  comb_ip = (struct rt_comb_internal *)path_ip.idb_ptr;
710  comb_tree = comb_ip->tree;
711 
712  member = NULL;
713  member = db_find_named_leaf(comb_tree, member_name);
714 
715  if (!member) {
716  bu_log("couldn't lookup member to edit matrix\n");
717  }
718  if (!member->tr_l.tl_mat) {
719  mat_t *new_mat;
720  BU_ALLOC(new_mat, mat_t);
721  MAT_IDN(*new_mat);
722  member->tr_l.tl_mat = (matp_t)new_mat;
723  }
724  db_path_to_mat(dbip, &fpath, path_mat, 0, NULL);
725  VEC3X4MAT(rot_dir, cross, path_mat);
726  bn_mat_arb_rot(pmat, jip->location, rot_dir, angle);
727  bn_mat_mul(combined_mat, member->tr_l.tl_mat, pmat);
728  MAT_COPY(member->tr_l.tl_mat, combined_mat);
729  } else {
730  bn_mat_arb_rot(pmat, jip->location, cross, angle);
731  rt_db_get_internal(&path_ip, dp, dbip, pmat, NULL);
732  }
733 
734  /* write changes */
735  rt_db_put_internal(dp, dbip, &path_ip, NULL);
736 
737  VMOVE(js->start, end);
738  db_free_full_path(&fpath);
739 
740  return 0;
741 }
742 
743 /** @} */
744 /*
745  * Local Variables:
746  * mode: C
747  * tab-width: 8
748  * indent-tabs-mode: t
749  * c-file-style: "stroustrup"
750  * End:
751  * ex: shiftwidth=4 tabstop=8
752  */
753 
vect_t joint_vector1
Definition: joint.c:60
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
#define BN_TOL_INIT(_p)
Definition: tol.h:87
Definition: raytrace.h:800
void rt_joint_free(struct soltab *stp)
Definition: joint.c:201
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
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
#define SIZEOF_NETWORK_DOUBLE
Definition: cv.h:48
vect_t start
Definition: joint.c:503
void rt_joint_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp)
Definition: joint.c:171
int rt_joint_process_selection(struct rt_db_internal *ip, struct db_i *dbip, const struct rt_selection *selection, const struct rt_selection_operation *op)
Definition: joint.c:633
Definition: list.h:118
int rt_db_put_internal(struct directory *dp, struct db_i *dbip, struct rt_db_internal *ip, struct resource *resp)
Definition: dir.c:136
uint32_t joint_magic
Definition: joint.c:56
point_t start
start point of query ray
Definition: raytrace.h:1990
union tree * db_find_named_leaf(union tree *tp, const char *cp)
Definition: db_tree.c:393
size_t fp_len
Definition: db_fullpath.h:44
#define SMALL
Definition: defines.h:351
#define RT_CK_APPLICATION(_p)
Definition: raytrace.h:1675
#define RT_CK_RTI(_p)
Definition: raytrace.h:1833
const mat_t bn_mat_identity
Matrix and vector functionality.
Definition: mat.c:46
if lu s
Definition: nmg_mod.c:3860
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
#define VSETALL(a, s)
Definition: color.c:54
const struct bu_structparse rt_joint_parse[]
Definition: joint.c:67
Definition: raytrace.h:215
#define ID_JOINT
Pseudo Solid/Region Joint.
Definition: raytrace.h:481
Definition: pc.h:108
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
Definition: raytrace.h:368
#define BU_ASSERT_LONG(_lhs, _relation, _rhs)
Definition: defines.h:240
Definition: raytrace.h:248
struct rt_selection_set * rt_joint_find_selections(const struct rt_db_internal *ip, const struct rt_selection_query *query)
Definition: joint.c:515
fastf_t st_aradius
Radius of APPROXIMATING sphere.
Definition: raytrace.h:433
void rt_joint_print(const struct soltab *stp)
Definition: joint.c:111
point_t joint_location
Definition: joint.c:57
Header file for the BRL-CAD common definitions.
int rt_joint_params(struct pc_pc_set *ps, const struct rt_db_internal *ip)
Definition: joint.c:483
void rt_joint_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
Definition: joint.c:189
#define DB_FULL_PATH_CUR_DIR(_pp)
Definition: db_fullpath.h:51
#define RT_JOINT_INTERNAL_MAGIC
Definition: magic.h:99
#define RT_CK_RAY(_p)
Definition: raytrace.h:224
char * reference_path_1
Definition: joint.c:58
int bu_ptbl_ins(struct bu_ptbl *b, long *p)
#define JOINT_SELECT_VMAX_DISTSQ
Definition: joint.c:491
void bu_cv_htond(unsigned char *out, const unsigned char *in, size_t count)
struct bu_ptbl selections
holds struct rt_selection
Definition: raytrace.h:1959
void rt_joint_ifree(struct rt_db_internal *ip)
Definition: joint.c:456
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
int rt_joint_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol, const struct rt_view_info *info)
Definition: joint.c:226
vect_t dir
direction of query ray
Definition: raytrace.h:1991
if(share_geom)
Definition: nmg_mod.c:3829
int rt_joint_shot(struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead)
Definition: joint.c:140
int idb_major_type
Definition: raytrace.h:192
#define DB_FULL_PATH_GET(_pp, _i)
Definition: db_fullpath.h:55
Definition: color.c:49
#define RT_ADD_VLIST(hd, pnt, draw)
Definition: raytrace.h:1865
int rt_joint_export4(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
Definition: joint.c:288
#define RT_CK_DB_INTERNAL(_p)
Definition: raytrace.h:207
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
fastf_t st_bradius
Radius of BOUNDING sphere.
Definition: raytrace.h:434
int db_string_to_path(struct db_full_path *pp, const struct db_i *dbip, const char *str)
Definition: db_fullpath.c:361
#define RT_CK_HIT(_p)
Definition: raytrace.h:259
void(* free_selection)(struct rt_selection *)
Definition: raytrace.h:1964
#define LOOKUP_QUIET
Definition: raytrace.h:893
#define BN_VLIST_LINE_MOVE
Definition: vlist.h:82
const struct rt_functab * idb_meth
for ft_ifree(), etc.
Definition: raytrace.h:194
#define bu_strlcpy(dst, src, size)
Definition: str.h:60
void db_free_full_path(struct db_full_path *pp)
Definition: db_fullpath.c:473
int rt_joint_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
Definition: joint.c:373
#define NEAR_ZERO(val, epsilon)
Definition: color.c:55
uint8_t * ext_buf
Definition: parse.h:216
static void top()
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
point_t st_max
max X, Y, Z of bounding RPP
Definition: raytrace.h:438
matp_t tl_mat
xform matp, NULL ==> identity
Definition: raytrace.h:1173
#define BN_VLIST_LINE_DRAW
Definition: vlist.h:83
#define BN_TOL_DIST
Definition: tol.h:109
size_t bu_vls_strlen(const struct bu_vls *vp)
Definition: vls.c:189
#define UNUSED(parameter)
Definition: common.h:239
#define BU_PTBL_INIT(_p)
Definition: ptbl.h:80
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
void bn_mat_mul(mat_t o, const mat_t a, const mat_t b)
vect_t joint_vector2
Definition: joint.c:61
Support for uniform tolerances.
Definition: tol.h:71
const char * bu_vls_cstr(const struct bu_vls *vp)
Definition: vls.c:103
fastf_t joint_value
Definition: joint.c:62
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
#define bu_offsetofarray(_t, _a, _d, _i)
Definition: parse.h:65
#define BU_FREE(_ptr, _type)
Definition: malloc.h:229
#define BU_STRUCTPARSE_FUNC_NULL
Definition: parse.h:153
#define RT_SELECTION_TRANSLATION
Definition: raytrace.h:2018
int rt_joint_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
Definition: joint.c:419
int bn_distsq_line3_line3(fastf_t dist[3], point_t P, vect_t d, point_t Q, vect_t e, point_t pt1, point_t pt2)
Plane/line/point calculations.
#define bu_offsetof(_t, _m)
Definition: parse.h:64
#define RT_CK_DBI(_p)
Definition: raytrace.h:829
struct tree::tree_db_leaf tr_l
struct rt_selection_translation tran
Definition: raytrace.h:2021
int bn_dist_pt3_line3(fastf_t *dist, point_t pca, const point_t a, const point_t p, const vect_t dir, const struct bn_tol *tol)
void * idb_ptr
Definition: raytrace.h:195
point_t st_min
min X, Y, Z of bounding RPP
Definition: raytrace.h:437
#define JOINT_FLOAT_SIZE
Definition: joint.c:65
void bu_cv_ntohd(unsigned char *out, const unsigned char *in, size_t count)
const struct rt_functab OBJ[]
Definition: table.c:159
int rt_joint_import5(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
Definition: joint.c:299
union tree * tree
Leading to tree_db_leaf leaves.
Definition: raytrace.h:938
#define RT_CK_SOLTAB(_p)
Definition: raytrace.h:453
#define RT_DIR_NULL
Definition: raytrace.h:875
void * st_specific
-> ID-specific (private) struct
Definition: raytrace.h:435
Definition: color.c:51
void bu_vls_strcpy(struct bu_vls *vp, const char *s)
Definition: vls.c:310
#define LOCATION_RADIUS
Definition: joint.c:224
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
#define BU_CK_LIST_HEAD(_p)
Definition: list.h:142
#define BU_CK_EXTERNAL(_p)
Definition: parse.h:224
union rt_selection_operation::@10 parameters
#define RT_SELECTION_NOP
Definition: raytrace.h:2017
void rt_ell_16pts(fastf_t *ov, fastf_t *V, fastf_t *A, fastf_t *B)
Definition: ell.c:606
size_t ext_nbytes
Definition: parse.h:210
HIDDEN void verbose(struct human_data_t *dude)
Definition: human.c:2008
void rt_joint_norm(struct hit *hitp, struct soltab *stp, struct xray *rp)
Definition: joint.c:157
Definition: vls.h:56
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
HIDDEN const point_t delta
Definition: sh_prj.c:618
double fastf_t
Definition: defines.h:300
#define VPRINT(a, b)
Definition: raytrace.h:1881
void * obj
primitive-specific selection object
Definition: raytrace.h:1951
#define JOINT_NULL
Definition: joint.c:64
int rt_joint_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
Definition: joint.c:79
void bn_mat_arb_rot(mat_t m, const point_t pt, const vect_t dir, const fastf_t ang)
Definition: mat.c:987
int rt_joint_import4(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
Definition: joint.c:272
Definition: color.c:50
char * reference_path_2
Definition: joint.c:59
int db_path_to_mat(struct db_i *dbip, struct db_full_path *pathp, mat_t mat, int depth, struct resource *resp)
Definition: db_fullpath.c:630
int rt_joint_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
Definition: joint.c:466