BRL-CAD
half.c
Go to the documentation of this file.
1 /* H A L F . 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/half/half.c
23  *
24  * Intersect a ray with a Halfspace.
25  *
26  * A HALFSPACE is defined by an outward pointing normal vector, and
27  * the distance from the origin to the plane, which is defined by N
28  * and d.
29  *
30  * With outward pointing normal vectors, the ray enters the half-space
31  * defined by a plane when D dot N < 0, is parallel to the plane when
32  * D dot N = 0, and exits otherwise.
33  *
34  * The inside of the halfspace bounded by the plane consists of all
35  * points P such that VDOT(P, N) - N[W] <= 0, where N[W] stores the
36  * value d.
37  *
38  */
39 
40 #include "common.h"
41 
42 #include <stddef.h>
43 #include <math.h>
44 #include "bio.h"
45 
46 #include "bu/cv.h"
47 #include "vmath.h"
48 #include "rtgeom.h"
49 #include "raytrace.h"
50 #include "nmg.h"
51 #include "db.h"
52 
53 #include "../../librt_private.h"
54 
55 
56 struct half_specific {
57  plane_t half_eqn; /* Plane equation, outward normal */
58  vect_t half_Xbase; /* "X" basis direction */
59  vect_t half_Ybase; /* "Y" basis direction */
60 };
61 #define HALF_NULL ((struct half_specific *)0)
62 
63 const struct bu_structparse rt_hlf_parse[] = {
64  { "%f", 3, "N", bu_offsetofarray(struct rt_half_internal, eqn, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
65  { "%f", 1, "d", bu_offsetofarray(struct rt_half_internal, eqn, fastf_t, W), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
66  { {'\0', '\0', '\0', '\0'}, 0, (char *)NULL, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
67 };
68 
69 
70 int
71 rt_hlf_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
72 {
73  struct rt_half_internal *hip;
74  register struct half_specific *halfp;
75 
76  if (rtip) RT_CK_RTI(rtip);
77 
78  hip = (struct rt_half_internal *)ip->idb_ptr;
79  RT_HALF_CK_MAGIC(hip);
80 
81  /* Process a HALFSPACE, which is represented as a normal vector,
82  * and a distance.
83  */
84  BU_GET(halfp, struct half_specific);
85  stp->st_specific = (void *)halfp;
86 
87  VMOVE(halfp->half_eqn, hip->eqn);
88  halfp->half_eqn[W] = hip->eqn[W];
89 
90  /* Select one point on the halfspace as the "center" */
91  VSCALE(stp->st_center, halfp->half_eqn, halfp->half_eqn[W]);
92 
93  /* X and Y basis for uv map */
94  bn_vec_perp(halfp->half_Xbase, halfp->half_eqn);
95  VCROSS(halfp->half_Ybase, halfp->half_Xbase, halfp->half_eqn);
96  VUNITIZE(halfp->half_Xbase);
97  VUNITIZE(halfp->half_Ybase);
98 
99  /* No bounding sphere or bounding RPP is possible */
100  VSETALL(stp->st_min, -INFINITY);
101  VSETALL(stp->st_max, INFINITY);
102 
103  stp->st_aradius = INFINITY;
104  stp->st_bradius = INFINITY;
105  return 0; /* OK */
106 }
107 
108 
109 void
110 rt_hlf_print(register const struct soltab *stp)
111 {
112  register const struct half_specific *halfp =
113  (struct half_specific *)stp->st_specific;
114 
115  if (halfp == HALF_NULL) {
116  bu_log("half(%s): no data?\n", stp->st_name);
117  return;
118  }
119  VPRINT("Normal", halfp->half_eqn);
120  bu_log("d = %f\n", halfp->half_eqn[W]);
121  VPRINT("Xbase", halfp->half_Xbase);
122  VPRINT("Ybase", halfp->half_Ybase);
123 }
124 
125 
126 /**
127  * Function -
128  * Shoot a ray at a HALFSPACE
129  *
130  * Algorithm -
131  * The intersection distance is computed.
132  *
133  * Returns -
134  * 0 MISS
135  * >0 HIT
136  */
137 int
138 rt_hlf_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
139 {
140  register struct half_specific *halfp =
141  (struct half_specific *)stp->st_specific;
142  fastf_t in, out; /* ray in/out distances */
143 
144  in = -INFINITY;
145  out = INFINITY;
146 
147  {
148  fastf_t slant_factor; /* Direction dot Normal */
149  fastf_t norm_dist;
150 
151  norm_dist = VDOT(halfp->half_eqn, rp->r_pt) - halfp->half_eqn[W];
152  if ((slant_factor = -VDOT(halfp->half_eqn, rp->r_dir)) < -1.0e-10) {
153  /* exit point, when dir.N < 0. out = min(out, s) */
154  out = norm_dist/slant_factor;
155 
156  /* ensure a legal distance between +inf/-inf */
157  if (!NEAR_ZERO(out, INFINITY))
158  return 0; /* MISS */
159  } else if (slant_factor > 1.0e-10) {
160  /* entry point, when dir.N > 0. in = max(in, s) */
161  in = norm_dist/slant_factor;
162 
163  /* ensure a legal distance between +inf/-inf */
164  if (!NEAR_ZERO(in, INFINITY))
165  return 0; /* MISS */
166  } else {
167  /* ray is parallel to plane when dir.N == 0. If it is
168  * outside the solid, stop now
169  */
170  if (norm_dist > 0.0)
171  return 0; /* MISS */
172  }
173  }
174  if (RT_G_DEBUG & DEBUG_ARB8)
175  bu_log("half: in=%f, out=%f\n", in, out);
176 
177  {
178  register struct seg *segp;
179 
180  RT_GET_SEG(segp, ap->a_resource);
181  segp->seg_stp = stp;
182  segp->seg_in.hit_dist = in;
183  segp->seg_out.hit_dist = out;
184  segp->seg_in.hit_surfno = 0;
185  segp->seg_out.hit_surfno = 0;
186  BU_LIST_INSERT(&(seghead->l), &(segp->l));
187  }
188  return 2; /* HIT */
189 }
190 
191 
192 #define RT_HALF_SEG_MISS(SEG) (SEG).seg_stp=RT_SOLTAB_NULL
193 
194 /**
195  * This is the Becker vector version
196  */
197 void
198 rt_hlf_vshot(struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
199  /* An array of solid pointers */
200  /* An array of ray pointers */
201  /* array of segs (results returned) */
202  /* Number of ray/object pairs */
203 
204 {
205  register int i;
206  register struct half_specific *halfp;
207 
208  fastf_t in, out; /* ray in/out distances */
209  fastf_t slant_factor; /* Direction dot Normal */
210  fastf_t norm_dist;
211 
212  if (ap) RT_CK_APPLICATION(ap);
213 
214  /* for each ray/halfspace pair */
215  for (i = 0; i < n; i++) {
216  if (stp[i] == 0) continue; /* indicates "skip this pair" */
217 
218  halfp = (struct half_specific *)stp[i]->st_specific;
219 
220  in = -INFINITY;
221  out = INFINITY;
222 
223  norm_dist = VDOT(halfp->half_eqn, rp[i]->r_pt) - halfp->half_eqn[W];
224 
225  if ((slant_factor = -VDOT(halfp->half_eqn, rp[i]->r_dir)) <
226  -1.0e-10) {
227  /* exit point, when dir.N < 0. out = min(out, s) */
228  out = norm_dist/slant_factor;
229  } else if (slant_factor > 1.0e-10) {
230  /* entry point, when dir.N > 0. in = max(in, s) */
231  in = norm_dist/slant_factor;
232  } else {
233  /* ray is parallel to plane when dir.N == 0.
234  * If it is outside the solid, stop now */
235  if (norm_dist > 0.0) {
236  RT_HALF_SEG_MISS(segp[i]); /* No hit */
237  continue;
238  }
239  }
240 
241  /* HIT */
242  segp[i].seg_stp = stp[i];
243  segp[i].seg_in.hit_dist = in;
244  segp[i].seg_out.hit_dist = out;
245  segp[i].seg_in.hit_surfno = 0;
246  segp[i].seg_out.hit_surfno = 0;
247  }
248 }
249 
250 
251 /**
252  * Given ONE ray distance, return the normal and entry/exit point.
253  * The normal is already filled in.
254  */
255 void
256 rt_hlf_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
257 {
258  struct half_specific *halfp = (struct half_specific *)stp->st_specific;
259  fastf_t f;
260 
261  RT_CK_SOLTAB(stp);
262  RT_CK_RAY(rp);
263 
264  /*
265  * At most one normal is really defined, but whichever one it is,
266  * it has value half_eqn.
267  */
268  VMOVE(hitp->hit_normal, halfp->half_eqn);
269 
270  /* We are expected to compute hit_point here. May be infinite. */
271  f = hitp->hit_dist;
272  if (f <= -INFINITY) {
273  bu_log("rt_hlf_norm: hit_dist = -INFINITY, unable to compute pt.\n");
274  VSETALL(hitp->hit_point, -INFINITY);
275  } else if (f >= INFINITY) {
276  bu_log("rt_hlf_norm: hit_dist = +INFINITY, unable to compute pt.\n");
277  VSETALL(hitp->hit_point, INFINITY);
278  } else {
279  VJOIN1(hitp->hit_point, rp->r_pt, f, rp->r_dir);
280  }
281 }
282 
283 
284 /**
285  * Return the "curvature" of the halfspace. Pick a principle
286  * direction orthogonal to normal, and indicate no curvature.
287  */
288 void
289 rt_hlf_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp)
290 {
291  struct half_specific *halfp = (struct half_specific *)stp->st_specific;
292 
293  if (hitp) RT_CK_HIT(hitp);
294 
295  bn_vec_ortho(cvp->crv_pdir, halfp->half_eqn);
296  cvp->crv_c1 = cvp->crv_c2 = 0;
297 }
298 
299 
300 /**
301  * For a hit on a face of an HALF, return the (u, v) coordinates of
302  * the hit point. 0 <= u, v <= 1. u extends along the Xbase
303  * direction. v extends along the "Ybase" direction. Note that a
304  * "toroidal" map is established, varying each from 0 up to 1 and then
305  * back down to 0 again.
306  */
307 void
308 rt_hlf_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
309 {
310  struct half_specific *halfp = (struct half_specific *)stp->st_specific;
311 
312  vect_t P_A;
313  fastf_t f;
314  double ival;
315 
316  f = hitp->hit_dist;
317  if (f <= -INFINITY || f >= INFINITY) {
318  bu_log("rt_hlf_uv: infinite dist\n");
319  rt_pr_hit("rt_hlf_uv", hitp);
320  uvp->uv_u = uvp->uv_v = 0;
321  uvp->uv_du = uvp->uv_dv = 0;
322  return;
323  }
324  VSUB2(P_A, hitp->hit_point, stp->st_center);
325 
326  f = VDOT(P_A, halfp->half_Xbase)/10000;
327  if (f <= -INFINITY || f >= INFINITY) {
328  bu_log("rt_hlf_uv: bad X vdot\n");
329  VPRINT("Xbase", halfp->half_Xbase);
330  rt_pr_hit("rt_hlf_uv", hitp);
331  VPRINT("st_center", stp->st_center);
332  f = 0;
333  }
334  if (f < 0) f = -f;
335  f = modf(f, &ival);
336  if (f < 0.5)
337  uvp->uv_u = 2 * f; /* 0..1 */
338  else
339  uvp->uv_u = 2 * (1 - f); /* 1..0 */
340 
341  f = VDOT(P_A, halfp->half_Ybase)/10000;
342  if (f <= -INFINITY || f >= INFINITY) {
343  bu_log("rt_hlf_uv: bad Y vdot\n");
344  VPRINT("Xbase", halfp->half_Ybase);
345  rt_pr_hit("rt_hlf_uv", hitp);
346  VPRINT("st_center", stp->st_center);
347  f = 0;
348  }
349  if (f < 0) f = -f;
350  f = modf(f, &ival);
351  if (f < 0.5)
352  uvp->uv_v = 2 * f; /* 0..1 */
353  else
354  uvp->uv_v = 2 * (1 - f); /* 1..0 */
355 
356  if (uvp->uv_u < 0 || uvp->uv_v < 0) {
357  if (RT_G_DEBUG)
358  bu_log("half_uv: bad uv=%f, %f\n", uvp->uv_u, uvp->uv_v);
359  /* Fix it up */
360  if (uvp->uv_u < 0) uvp->uv_u = (-uvp->uv_u);
361  if (uvp->uv_v < 0) uvp->uv_v = (-uvp->uv_v);
362  }
363 
364  uvp->uv_du = uvp->uv_dv =
365  (ap->a_rbeam + ap->a_diverge * hitp->hit_dist) / (10000/2);
366  if (uvp->uv_du < 0 || uvp->uv_dv < 0) {
367  rt_pr_hit("rt_hlf_uv", hitp);
368  uvp->uv_du = uvp->uv_dv = 0;
369  }
370 }
371 
372 
373 void
374 rt_hlf_free(struct soltab *stp)
375 {
376  register struct half_specific *halfp =
377  (struct half_specific *)stp->st_specific;
378 
379  BU_PUT(halfp, struct half_specific);
380 }
381 
382 
383 /**
384  * Classify this halfspace against a bounding RPP. Since this is an
385  * infinite solid, it is very important that this function properly.
386  *
387  */
388 int
389 rt_hlf_class(const struct soltab *stp, const fastf_t *min, const fastf_t *max, const struct bn_tol *tol)
390 {
391  if (stp) RT_CK_SOLTAB(stp);
392  if (tol) BN_CK_TOL(tol);
393  if (!min) return 0;
394  if (!max) return 0;
395 
396  return 0;
397 }
398 
399 
400 /**
401  * The representation of a halfspace is an OUTWARD pointing normal
402  * vector, and the distance of the plane from the origin.
403  *
404  * Drawing a halfspace is difficult when using a finite display.
405  * Drawing the boundary plane is hard enough. We just make a cross in
406  * the plane, with the outward normal drawn shorter.
407  */
408 int
409 rt_hlf_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))
410 {
411  struct rt_half_internal *hip;
412  vect_t cent; /* some point on the plane */
413  vect_t xbase, ybase; /* perpendiculars to normal */
414  vect_t x_1, x_2;
415  vect_t y_1, y_2;
416  vect_t tip;
417 
418  BU_CK_LIST_HEAD(vhead);
419  RT_CK_DB_INTERNAL(ip);
420  hip = (struct rt_half_internal *)ip->idb_ptr;
421  RT_HALF_CK_MAGIC(hip);
422 
423  /* Invent a "center" point on the plane -- point closets to origin */
424  VSCALE(cent, hip->eqn, hip->eqn[W]);
425 
426  /* The use of "x" and "y" here is not related to the axis */
427  bn_vec_perp(xbase, &hip->eqn[0]);
428  VCROSS(ybase, xbase, hip->eqn);
429 
430  /* Arrange for the cross to be 2 meters across */
431  VUNITIZE(xbase);
432  VUNITIZE(ybase);
433  VSCALE(xbase, xbase, 1000);
434  VSCALE(ybase, ybase, 1000);
435 
436  VADD2(x_1, cent, xbase);
437  VSUB2(x_2, cent, xbase);
438  VADD2(y_1, cent, ybase);
439  VSUB2(y_2, cent, ybase);
440 
441  RT_ADD_VLIST(vhead, x_1, BN_VLIST_LINE_MOVE); /* the cross */
442  RT_ADD_VLIST(vhead, x_2, BN_VLIST_LINE_DRAW);
443  RT_ADD_VLIST(vhead, y_1, BN_VLIST_LINE_MOVE);
444  RT_ADD_VLIST(vhead, y_2, BN_VLIST_LINE_DRAW);
445  RT_ADD_VLIST(vhead, x_2, BN_VLIST_LINE_DRAW); /* the box */
446  RT_ADD_VLIST(vhead, y_1, BN_VLIST_LINE_DRAW);
447  RT_ADD_VLIST(vhead, x_1, BN_VLIST_LINE_DRAW);
448  RT_ADD_VLIST(vhead, y_2, BN_VLIST_LINE_DRAW);
449 
450  VSCALE(tip, hip->eqn, 500);
451  VADD2(tip, cent, tip);
452  RT_ADD_VLIST(vhead, cent, BN_VLIST_LINE_MOVE);
453  RT_ADD_VLIST(vhead, tip, BN_VLIST_LINE_DRAW);
454  return 0;
455 }
456 
457 
458 /**
459  * Returns -
460  * -1 failure
461  * 0 success
462  */
463 int
465  struct rt_db_internal *op,
466  const mat_t mat,
467  struct rt_db_internal *ip,
468  int release,
469  struct db_i *dbip,
470  struct resource *resp)
471 {
472  struct rt_half_internal *hip, *hop;
473  point_t orig_pt, pt;
474  register double f, t;
475 
476  if (dbip) RT_CK_DBI(dbip);
477 
478  RT_CK_DB_INTERNAL(ip);
479  RT_CK_RESOURCE(resp);
480  hip = (struct rt_half_internal *)ip->idb_ptr;
481  RT_HALF_CK_MAGIC(hip);
482  RT_CK_DB_INTERNAL(op);
483 
484  if (op != ip) {
486  BU_ALLOC(hop, struct rt_half_internal);
487  hop->magic = RT_HALF_INTERNAL_MAGIC;
488  op->idb_ptr = (void *)hop;
489  op->idb_meth = &OBJ[ID_HALF];
490  op->idb_major_type = DB5_MAJORTYPE_BRLCAD;
491  op->idb_type = ID_HALF;
492  if (ip->idb_avs.magic == BU_AVS_MAGIC) {
493  bu_avs_init(&op->idb_avs, ip->idb_avs.count, "avs");
494  bu_avs_merge(&op->idb_avs, &ip->idb_avs);
495  }
496  } else {
497  hop = (struct rt_half_internal *)ip->idb_ptr;
498  }
499  RT_HALF_CK_MAGIC(hop);
500 
501  /* Pick a point on the original halfspace */
502  VSCALE(orig_pt, hip->eqn, hip->eqn[1*ELEMENTS_PER_VECT]);
503 
504  /* Transform the picked point and the normal */
505  MAT4X3VEC(hop->eqn, mat, hip->eqn);
506  MAT4X3PNT(pt, mat, orig_pt);
507 
508  /*
509  * We are done with the input solid so free it if required.
510  */
511  if (release && ip != op)
513 
514  /*
515  * The transformed normal is all that is required.
516  * The new distance is found from the transformed point on the plane.
517  */
518  hop->eqn[W] = VDOT(pt, hop->eqn);
519 
520  /* Now some safety. Verify that the normal has unit length */
521  f = MAGNITUDE(hop->eqn);
522  if (f <= SMALL) {
523  bu_log("rt_half_xform: bad normal, len = %g\n", f);
524  return -1;
525  }
526  t = f - 1.0;
527  if (!NEAR_ZERO(t, 0.001)) {
528  /* Restore normal to unit length */
529  f = 1/f;
530  VSCALE(hop->eqn, hop->eqn, f);
531  hip->eqn[W] *= f;
532  }
533  return 0;
534 }
535 
536 
537 /**
538  * Returns -
539  * -1 failure
540  * 0 success
541  */
542 int
543 rt_hlf_import4(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
544 {
545  struct rt_half_internal *hip;
546  union record *rp;
547  point_t orig_pt;
548  point_t pt;
549  fastf_t orig_eqn[3*2];
550  register double f, t;
551 
552  if (dbip) RT_CK_DBI(dbip);
553 
554  BU_CK_EXTERNAL(ep);
555  rp = (union record *)ep->ext_buf;
556  if (rp->u_id != ID_SOLID) {
557  bu_log("rt_hlf_import4: defective record, id=x%x\n", rp->u_id);
558  return -1;
559  }
560 
561  RT_CK_DB_INTERNAL(ip);
562  ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
563  ip->idb_type = ID_HALF;
564  ip->idb_meth = &OBJ[ID_HALF];
565  BU_ALLOC(ip->idb_ptr, struct rt_half_internal);
566 
567  hip = (struct rt_half_internal *)ip->idb_ptr;
568  hip->magic = RT_HALF_INTERNAL_MAGIC;
569 
570  flip_fastf_float(orig_eqn, rp->s.s_values, 2, dbip->dbi_version < 0 ? 1 : 0); /* 2 floats too many */
571 
572  /* Pick a point on the original halfspace */
573  VSCALE(orig_pt, orig_eqn, orig_eqn[1*ELEMENTS_PER_VECT]);
574 
575  /* Transform the point, and the normal */
576  if (mat == NULL) mat = bn_mat_identity;
577  MAT4X3VEC(hip->eqn, mat, orig_eqn);
578  MAT4X3PNT(pt, mat, orig_pt);
579 
580  /* The transformed normal is all that is required. The new
581  * distance is found from the transformed point on the plane.
582  */
583  hip->eqn[W] = VDOT(pt, hip->eqn);
584 
585  /* Verify that normal has unit length */
586  f = MAGNITUDE(hip->eqn);
587  if (f <= SMALL) {
588  bu_log("rt_hlf_import4: bad normal, len=%g\n", f);
589  return -1; /* BAD */
590  }
591  t = f - 1.0;
592  if (!NEAR_ZERO(t, 0.001)) {
593  /* Restore normal to unit length */
594  f = 1/f;
595  VSCALE(hip->eqn, hip->eqn, f);
596  hip->eqn[W] *= f;
597  }
598  return 0; /* OK */
599 }
600 
601 
602 int
603 rt_hlf_export4(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
604 {
605  struct rt_half_internal *hip;
606  union record *rec;
607 
608  if (dbip) RT_CK_DBI(dbip);
609 
610  RT_CK_DB_INTERNAL(ip);
611  if (ip->idb_type != ID_HALF) return -1;
612  hip = (struct rt_half_internal *)ip->idb_ptr;
613  RT_HALF_CK_MAGIC(hip);
614 
615  BU_CK_EXTERNAL(ep);
616  ep->ext_nbytes = sizeof(union record);
617  ep->ext_buf = (uint8_t *)bu_calloc(1, ep->ext_nbytes, "half external");
618  rec = (union record *)ep->ext_buf;
619 
620  rec->s.s_id = ID_SOLID;
621  rec->s.s_type = HALFSPACE;
622  VMOVE(rec->s.s_values, hip->eqn);
623  rec->s.s_values[W] = hip->eqn[W] * local2mm;
624 
625  return 0;
626 }
627 
628 
629 int
630 rt_hlf_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
631 {
632  register double f, t;
633  struct rt_half_internal *hip;
634  point_t tmp_pt, new_pt;
635 
636  /* must be double for import and export */
637  double tmp_plane[ELEMENTS_PER_PLANE];
638 
639  if (dbip) RT_CK_DBI(dbip);
640 
641  BU_CK_EXTERNAL(ep);
642 
643  BU_ASSERT_LONG(ep->ext_nbytes, ==, SIZEOF_NETWORK_DOUBLE * ELEMENTS_PER_PLANE);
644 
645  RT_CK_DB_INTERNAL(ip);
646  ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
647  ip->idb_type = ID_HALF;
648  ip->idb_meth = &OBJ[ID_HALF];
649  BU_ALLOC(ip->idb_ptr, struct rt_half_internal);
650 
651  hip = (struct rt_half_internal *)ip->idb_ptr;
652  hip->magic = RT_HALF_INTERNAL_MAGIC;
653 
654  /* Convert from database (network) to internal (host) format */
655  bu_cv_ntohd((unsigned char *)tmp_plane, ep->ext_buf, ELEMENTS_PER_PLANE);
656 
657  /* to apply modeling transformations, create a temporary normal
658  * vector and point on the plane
659  */
660  VSCALE(tmp_pt, tmp_plane, tmp_plane[W]);
661 
662  /* transform both the point and the vector */
663  if (mat == NULL) mat = bn_mat_identity;
664  MAT4X3VEC(hip->eqn, mat, tmp_plane);
665  MAT4X3PNT(new_pt, mat, tmp_pt);
666 
667  /* and calculate the new distance */
668  hip->eqn[W] = VDOT(hip->eqn, new_pt);
669 
670  /* Verify that normal has unit length */
671  f = MAGNITUDE(hip->eqn);
672  if (f <= SMALL) {
673  bu_log("rt_hlf_import4: bad normal, len=%g\n", f);
674  return -1; /* BAD */
675  }
676  t = f - 1.0;
677  if (!NEAR_ZERO(t, 0.001)) {
678  /* Restore normal to unit length */
679  f = 1/f;
680  VSCALE(hip->eqn, hip->eqn, f);
681  hip->eqn[W] *= f;
682  }
683 
684  return 0; /* OK */
685 }
686 
687 
688 int
689 rt_hlf_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
690 {
691  struct rt_half_internal *hip;
692 
693  /* must be double for import and export */
694  double scaled_dist;
695  double eqn[ELEMENTS_PER_VECT];
696 
697  if (dbip) RT_CK_DBI(dbip);
698 
699  RT_CK_DB_INTERNAL(ip);
700  if (ip->idb_type != ID_HALF) return -1;
701  hip = (struct rt_half_internal *)ip->idb_ptr;
702  RT_HALF_CK_MAGIC(hip);
703 
704  BU_CK_EXTERNAL(ep);
706  ep->ext_buf = (uint8_t *)bu_malloc(ep->ext_nbytes, "half external");
707 
708  /* only the distance needs to be scaled */
709  scaled_dist = hip->eqn[W] * local2mm;
710 
711  /* Convert from internal (host) to database (network) format */
712 
713  /* the normal */
714  VMOVE(eqn, hip->eqn); /* convert fastf_t to double */
715  bu_cv_htond((unsigned char *)ep->ext_buf, (unsigned char *)eqn, ELEMENTS_PER_VECT);
716 
717  /* the distance */
718  bu_cv_htond(((unsigned char *)(ep->ext_buf)) + SIZEOF_NETWORK_DOUBLE*ELEMENTS_PER_VECT,
719  (unsigned char *)&scaled_dist, 1);
720 
721  return 0;
722 }
723 
724 
725 /**
726  * Make human-readable formatted presentation of this solid. First
727  * line describes type of solid. Additional lines are indented one
728  * tab, and give parameter values.
729  */
730 int
731 rt_hlf_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
732 {
733  struct rt_half_internal *hip;
734  char buf[256];
735 
736  hip = (struct rt_half_internal *)ip->idb_ptr;
737  RT_HALF_CK_MAGIC(hip);
738  bu_vls_strcat(str, "halfspace\n");
739 
740  if (!verbose)
741  return 0;
742 
743  sprintf(buf, "\tN (%g, %g, %g) d=%g\n",
744  V3INTCLAMPARGS(hip->eqn), /* should have unit length */
745  INTCLAMP(hip->eqn[W] * mm2local));
746  bu_vls_strcat(str, buf);
747 
748  return 0;
749 }
750 
751 
752 /**
753  * Free the storage associated with the rt_db_internal version of this
754  * solid.
755  */
756 void
758 {
759  RT_CK_DB_INTERNAL(ip);
760 
761  bu_free(ip->idb_ptr, "hlf ifree");
762  ip->idb_ptr = ((void *)0);
763 }
764 
765 
766 int
767 rt_hlf_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))
768 {
769  struct rt_half_internal *vip;
770 
771  RT_CK_DB_INTERNAL(ip);
772  vip = (struct rt_half_internal *)ip->idb_ptr;
773  RT_HALF_CK_MAGIC(vip);
774 
775  if (r) *r = NULL;
776  if (m) NMG_CK_MODEL(m);
777 
778  /* XXX tess routine needed */
779  return -1;
780 }
781 
782 
783 int
784 rt_hlf_params(struct pc_pc_set *UNUSED(ps), const struct rt_db_internal *ip)
785 {
786  if (ip) RT_CK_DB_INTERNAL(ip);
787 
788  return 0; /* OK */
789 }
790 
791 
792 /** @} */
793 /*
794  * Local Variables:
795  * mode: C
796  * tab-width: 8
797  * indent-tabs-mode: t
798  * c-file-style: "stroustrup"
799  * End:
800  * ex: shiftwidth=4 tabstop=8
801  */
Definition: raytrace.h:800
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
#define BU_LIST_INSERT(old, new)
Definition: list.h:183
#define SIZEOF_NETWORK_DOUBLE
Definition: cv.h:48
int rt_hlf_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
Definition: half.c:731
#define BU_AVS_MAGIC
Definition: magic.h:46
struct hit seg_in
IN information.
Definition: raytrace.h:370
void rt_hlf_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
Definition: half.c:308
int rt_hlf_params(struct pc_pc_set *ps, const struct rt_db_internal *ip)
Definition: half.c:784
Definition: list.h:118
int rt_hlf_import4(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
Definition: half.c:543
#define SMALL
Definition: defines.h:351
#define RT_CK_APPLICATION(_p)
Definition: raytrace.h:1675
#define RT_CK_RTI(_p)
Definition: raytrace.h:1833
vect_t half_Xbase
Definition: half.c:58
vect_t crv_pdir
Principle direction.
Definition: raytrace.h:307
const mat_t bn_mat_identity
Matrix and vector functionality.
Definition: mat.c:46
fastf_t uv_u
Range 0..1.
Definition: raytrace.h:341
struct soltab * seg_stp
pointer back to soltab
Definition: raytrace.h:372
int rt_hlf_export4(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
Definition: half.c:603
int rt_hlf_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
Definition: half.c:630
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
#define VSETALL(a, s)
Definition: color.c:54
Definition: raytrace.h:215
void bu_avs_merge(struct bu_attribute_value_set *dest, const struct bu_attribute_value_set *src)
Definition: avs.c:154
Definition: pc.h:108
Definition: raytrace.h:368
#define BU_ASSERT_LONG(_lhs, _relation, _rhs)
Definition: defines.h:240
Definition: raytrace.h:248
fastf_t st_aradius
Radius of APPROXIMATING sphere.
Definition: raytrace.h:433
vect_t half_Ybase
Definition: half.c:59
Header file for the BRL-CAD common definitions.
#define RT_CK_RAY(_p)
Definition: raytrace.h:224
void flip_fastf_float(fastf_t *ff, const dbfloat_t *fp, int n, int flip)
Definition: db_flip.c:74
void bu_cv_htond(unsigned char *out, const unsigned char *in, size_t count)
int rt_hlf_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
Definition: half.c:767
struct bu_list l
Definition: raytrace.h:369
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
const struct bu_structparse rt_hlf_parse[]
Definition: half.c:63
if(share_geom)
Definition: nmg_mod.c:3829
#define HALF_NULL
Definition: half.c:61
int idb_major_type
Definition: raytrace.h:192
Definition: color.c:49
void rt_hlf_vshot(struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
Definition: half.c:198
#define RT_G_DEBUG
Definition: raytrace.h:1718
#define RT_ADD_VLIST(hd, pnt, draw)
Definition: raytrace.h:1865
#define RT_CK_DB_INTERNAL(_p)
Definition: raytrace.h:207
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
fastf_t st_bradius
Radius of BOUNDING sphere.
Definition: raytrace.h:434
fastf_t crv_c2
curvature in other direction
Definition: raytrace.h:309
#define RT_CK_HIT(_p)
Definition: raytrace.h:259
#define RT_DB_INTERNAL_INIT(_p)
Definition: raytrace.h:199
#define BN_VLIST_LINE_MOVE
Definition: vlist.h:82
fastf_t a_diverge
slope of beam divergence/mm
Definition: raytrace.h:1600
const struct rt_functab * idb_meth
for ft_ifree(), etc.
Definition: raytrace.h:194
fastf_t uv_dv
delta in v
Definition: raytrace.h:344
#define RT_HALF_INTERNAL_MAGIC
Definition: magic.h:96
#define NEAR_ZERO(val, epsilon)
Definition: color.c:55
uint8_t * ext_buf
Definition: parse.h:216
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
point_t hit_point
DEPRECATED: Intersection point, use VJOIN1 hit_dist.
Definition: raytrace.h:251
point_t st_max
max X, Y, Z of bounding RPP
Definition: raytrace.h:438
struct hit seg_out
OUT information.
Definition: raytrace.h:371
#define BN_VLIST_LINE_DRAW
Definition: vlist.h:83
plane_t half_eqn
Definition: half.c:57
struct bu_attribute_value_set idb_avs
Definition: raytrace.h:196
#define UNUSED(parameter)
Definition: common.h:239
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
uint32_t magic
Definition: avs.h:84
goto out
Definition: nmg_mod.c:3846
void rt_hlf_free(struct soltab *stp)
Definition: half.c:374
Support for uniform tolerances.
Definition: tol.h:71
void bu_avs_init(struct bu_attribute_value_set *avp, size_t len, const char *str)
Definition: avs.c:47
#define BN_CK_TOL(_p)
Definition: tol.h:82
#define ID_HALF
Half-space.
Definition: raytrace.h:464
int rt_hlf_class(const struct soltab *stp, const fastf_t *min, const fastf_t *max, const struct bn_tol *tol)
Definition: half.c:389
void rt_pr_hit(const char *str, const struct hit *hitp)
#define bu_offsetofarray(_t, _a, _d, _i)
Definition: parse.h:65
#define BU_STRUCTPARSE_FUNC_NULL
Definition: parse.h:153
vect_t r_dir
Direction of ray (UNIT Length)
Definition: raytrace.h:219
void rt_hlf_print(register const struct soltab *stp)
Definition: half.c:110
int rt_hlf_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
Definition: half.c:138
#define RT_CK_DBI(_p)
Definition: raytrace.h:829
#define RT_GET_SEG(p, res)
Definition: raytrace.h:379
void * idb_ptr
Definition: raytrace.h:195
point_t r_pt
Point at which ray starts.
Definition: raytrace.h:218
point_t st_min
min X, Y, Z of bounding RPP
Definition: raytrace.h:437
int rt_hlf_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: half.c:409
void bu_cv_ntohd(unsigned char *out, const unsigned char *in, size_t count)
const struct rt_functab OBJ[]
Definition: table.c:159
void rt_hlf_ifree(struct rt_db_internal *ip)
Definition: half.c:757
int rt_hlf_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
Definition: half.c:689
#define RT_CK_RESOURCE(_p)
Definition: raytrace.h:1490
void bn_vec_ortho(vect_t out, const vect_t in)
#define RT_CK_SOLTAB(_p)
Definition: raytrace.h:453
void * st_specific
-> ID-specific (private) struct
Definition: raytrace.h:435
fastf_t uv_du
delta in u
Definition: raytrace.h:343
fastf_t crv_c1
curvature in principle dir
Definition: raytrace.h:308
int dbi_version
PRIVATE: use db_version()
Definition: raytrace.h:824
int hit_surfno
solid-specific surface indicator
Definition: raytrace.h:255
void bn_vec_perp(vect_t new_vec, const vect_t old_vec)
Definition: mat.c:616
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
vect_t hit_normal
DEPRECATED: Surface Normal at hit_point, use RT_HIT_NORMAL.
Definition: raytrace.h:252
fastf_t a_rbeam
initial beam radius (mm)
Definition: raytrace.h:1599
#define BU_CK_LIST_HEAD(_p)
Definition: list.h:142
#define BU_CK_EXTERNAL(_p)
Definition: parse.h:224
int rt_hlf_xform(struct rt_db_internal *op, const mat_t mat, struct rt_db_internal *ip, int release, struct db_i *dbip, struct resource *resp)
Definition: half.c:464
size_t ext_nbytes
Definition: parse.h:210
#define RT_HALF_SEG_MISS(SEG)
Definition: half.c:192
int rt_hlf_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
Definition: half.c:71
fastf_t hit_dist
dist from r_pt to hit_point
Definition: raytrace.h:250
HIDDEN void verbose(struct human_data_t *dude)
Definition: human.c:2008
Definition: vls.h:56
void rt_hlf_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
Definition: half.c:256
double fastf_t
Definition: defines.h:300
#define VPRINT(a, b)
Definition: raytrace.h:1881
void rt_db_free_internal(struct rt_db_internal *ip)
Definition: dir.c:216
void rt_hlf_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp)
Definition: half.c:289
fastf_t uv_v
Range 0..1.
Definition: raytrace.h:342
point_t st_center
Centroid of solid.
Definition: raytrace.h:432
#define DEBUG_ARB8
8 Print voluminous ARB8 details
Definition: raytrace.h:91