BRL-CAD
xxx.c
Go to the documentation of this file.
1 /* X X X . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1990-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/xxx/xxx.c
23  *
24  * Intersect a ray with an 'xxx' primitive object.
25  *
26  * Adding a new solid type:
27  *
28  * Design disk record
29  *
30  * define rt_xxx_internal --- parameters for solid
31  * define xxx_specific --- raytracing form, possibly w/precomputed terms
32  * define rt_xxx_parse --- struct bu_structparse for "db get", "db adjust", ...
33  *
34  * code import/export4/describe/print/ifree/plot/prep/shot/curve/uv/tess
35  *
36  * edit db.h add solidrec s_type define
37  * edit rtgeom.h to add rt_xxx_internal
38  * edit bu/magic.h to add RT_XXX_INTERNAL_MAGIC
39  * edit table.c:
40  * RT_DECLARE_INTERFACE()
41  * struct rt_functab entry
42  * rt_id_solid()
43  * edit raytrace.h to make ID_XXX, increment ID_MAXIMUM
44  * edit db_scan.c to add the new solid to db_scan()
45  * edit CMakeLists.txt to add g_xxx.c to compile
46  *
47  * go to src/libwdb and create mk_xxx() routine
48  * go to src/conv and edit g2asc.c and asc2g.c to support the new solid
49  * go to src/librt and edit tcl.c to add the new solid to
50  * rt_solid_type_lookup[]
51  * also add the interface table and to rt_id_solid() in table.c;
52  * you MUST add the appropriate RTFUNCTAB_FUNC_X_CAST macro
53  * for each function rt_xxx_X you add (see entire list in raytrace.h)
54  * go to src/mged and create the edit support
55  *
56  */
57 /** @} */
58 
59 #include "common.h"
60 
61 #include <stdio.h>
62 #include <math.h>
63 
64 #include "vmath.h"
65 #include "db.h"
66 #include "nmg.h"
67 #include "rtgeom.h"
68 #include "raytrace.h"
69 
70 /* local interface header */
71 #include "./xxx.h"
72 
73 
74 /**
75  * Given a pointer to a GED database record, and a transformation
76  * matrix, determine if this is a valid XXX, and if so, precompute
77  * various terms of the formula.
78  *
79  * Returns -
80  * 0 XXX is OK
81  * !0 Error in description
82  *
83  * Implicit return -
84  * A struct xxx_specific is created, and its address is stored in
85  * stp->st_specific for use by xxx_shot().
86  */
87 int
88 rt_xxx_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
89 {
90  struct rt_xxx_internal *xxx_ip;
91 
92  if (stp) RT_CK_SOLTAB(stp);
94  if (rtip) RT_CK_RTI(rtip);
95 
96  xxx_ip = (struct rt_xxx_internal *)ip->idb_ptr;
97  RT_XXX_CK_MAGIC(xxx_ip);
98 
99  return 0;
100 }
101 
102 
103 void
104 rt_xxx_print(const struct soltab *stp)
105 {
106  const struct xxx_specific *xxx;
107 
108  if (!stp) return;
109  xxx = (struct xxx_specific *)stp->st_specific;
110  if (!xxx) return;
111  RT_CK_SOLTAB(stp);
112 }
113 
114 
115 /**
116  * Intersect a ray with a xxx. If an intersection occurs, a struct
117  * seg will be acquired and filled in.
118  *
119  * Returns -
120  * 0 MISS
121  * >0 HIT
122  */
123 int
124 rt_xxx_shot(struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead)
125 {
126  struct xxx_specific *xxx;
127 
128  if (!stp) return -1;
129  RT_CK_SOLTAB(stp);
130  xxx = (struct xxx_specific *)stp->st_specific;
131  if (!xxx) return -1;
132  if (rp) RT_CK_RAY(rp);
133  if (ap) RT_CK_APPLICATION(ap);
134  if (!seghead) return -1;
135 
136 /* the EXAMPLE_NEW_SEGMENT block shows how one might add a new result
137  * if the ray did hit the primitive. the segment values would need to
138  * be adjusted accordingly to match real values instead of -1.
139  */
140 #ifdef EXAMPLE_NEW_SEGMENT
141  /* allocate a segment */
142  RT_GET_SEG(segp, ap->a_resource);
143  segp->seg_stp = stp; /* stash a pointer to the primitive */
144 
145  segp->seg_in.hit_dist = -1; /* XXX set to real distance to entry point */
146  segp->seg_out.hit_dist = -1; /* XXX set to real distance to exit point */
147  segp->seg_in.hit_surfno = -1; /* XXX set to a non-negative ID for entry surface */
148  segp->seg_out.hit_surfno = -1; /* XXX set to a non-negative ID for exit surface */
149 
150  /* add segment to list of those encountered for this primitive */
151  BU_LIST_INSERT(&(seghead->l), &(segp->l));
152 
153  return 2; /* num surface intersections == in + out == 2 */
154 #endif
155 
156  return 0; /* MISS */
157 }
158 
159 
160 /**
161  * Given ONE ray distance, return the normal and entry/exit point.
162  */
163 void
164 rt_xxx_norm(struct hit *hitp, struct soltab *stp, struct xray *rp)
165 {
166  struct xxx_specific *xxx;
167 
168  if (!stp) return;
169  xxx = (struct xxx_specific *)stp->st_specific;
170  if (!xxx) return;
171  RT_CK_SOLTAB(stp);
172 
173  VJOIN1(hitp->hit_point, rp->r_pt, hitp->hit_dist, rp->r_dir);
174 }
175 
176 
177 /**
178  * Return the curvature of the xxx.
179  */
180 void
181 rt_xxx_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp)
182 {
183  struct xxx_specific *xxx;
184 
185  if (!stp) return;
186  xxx = (struct xxx_specific *)stp->st_specific;
187  if (!xxx) return;
188  RT_CK_SOLTAB(stp);
189 
190  cvp->crv_c1 = cvp->crv_c2 = 0;
191 
192  /* any tangent direction */
193  bn_vec_ortho(cvp->crv_pdir, hitp->hit_normal);
194 }
195 
196 
197 /**
198  * For a hit on the surface of an xxx, return the (u, v) coordinates
199  * of the hit point, 0 <= u, v <= 1.
200 
201  * u = azimuth, v = elevation
202  */
203 void
204 rt_xxx_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
205 {
206  struct xxx_specific *xxx;
207 
208  if (ap) RT_CK_APPLICATION(ap);
209  if (!stp || !uvp) return;
210  RT_CK_SOLTAB(stp);
211  if (hitp) RT_CK_HIT(hitp);
212 
213  xxx = (struct xxx_specific *)stp->st_specific;
214  if (!xxx) return;
215 }
216 
217 
218 void
219 rt_xxx_free(struct soltab *stp)
220 {
221  struct xxx_specific *xxx;
222 
223  if (!stp) return;
224  RT_CK_SOLTAB(stp);
225  xxx = (struct xxx_specific *)stp->st_specific;
226  if (!xxx) return;
227 
228  bu_free((char *)xxx, "xxx_specific");
229 }
230 
231 
232 int
233 rt_xxx_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))
234 {
235  struct rt_xxx_internal *xxx_ip;
236 
237  BU_CK_LIST_HEAD(vhead);
238  RT_CK_DB_INTERNAL(ip);
239  xxx_ip = (struct rt_xxx_internal *)ip->idb_ptr;
240  RT_XXX_CK_MAGIC(xxx_ip);
241 
242  return -1;
243 }
244 
245 
246 /**
247  * Returns -
248  * -1 failure
249  * 0 OK. *r points to nmgregion that holds this tessellation.
250  */
251 int
252 rt_xxx_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))
253 {
254  struct rt_xxx_internal *xxx_ip;
255 
256  if (r) NMG_CK_REGION(*r);
257  if (m) NMG_CK_MODEL(m);
258  RT_CK_DB_INTERNAL(ip);
259  xxx_ip = (struct rt_xxx_internal *)ip->idb_ptr;
260  RT_XXX_CK_MAGIC(xxx_ip);
261 
262  return -1;
263 }
264 
265 
266 /**
267  * Import an XXX from the database format to the internal format.
268  * Note that the data read will be in network order. This means
269  * Big-Endian integers and IEEE doubles for floating point.
270  *
271  * Apply modeling transformations as well.
272  */
273 int
274 rt_xxx_import5(struct rt_db_internal *ip, const struct bu_external *ep, const mat_t mat, const struct db_i *dbip)
275 {
276  struct rt_xxx_internal *xxx_ip;
277 
278  /* must be double for import and export */
279  double vv[ELEMENTS_PER_VECT*1];
280 
281  RT_CK_DB_INTERNAL(ip);
282  BU_CK_EXTERNAL(ep);
283  if (dbip) RT_CK_DBI(dbip);
284 
286 
287  /* set up the internal structure */
288  ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
289  ip->idb_type = ID_XXX;
290  ip->idb_meth = &OBJ[ID_XXX];
291  BU_ALLOC(ip->idb_ptr, struct rt_xxx_internal);
292 
293  xxx_ip = (struct rt_xxx_internal *)ip->idb_ptr;
294  xxx_ip->magic = RT_XXX_INTERNAL_MAGIC;
295 
296  /* Convert the data in ep->ext_buf into internal format. Note the
297  * conversion from network data (Big Endian ints, IEEE double
298  * floating point) to host local data representations.
299  */
300  bu_cv_ntohd((unsigned char *)&vv, (unsigned char *)ep->ext_buf, ELEMENTS_PER_VECT*1);
301 
302  /* Apply the modeling transformation */
303  if (mat == NULL) mat = bn_mat_identity;
304  MAT4X3PNT(xxx_ip->v, mat, vv);
305 
306  return 0; /* OK */
307 }
308 
309 
310 /**
311  * Export an XXX from internal form to external format. Note that
312  * this means converting all integers to Big-Endian format and
313  * floating point data to IEEE double.
314  *
315  * Apply the transformation to mm units as well.
316  */
317 int
318 rt_xxx_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
319 {
320  struct rt_xxx_internal *xxx_ip;
321 
322  /* must be double for import and export */
323  double vec[ELEMENTS_PER_VECT];
324 
325  RT_CK_DB_INTERNAL(ip);
326  if (ip->idb_type != ID_XXX) return -1;
327  xxx_ip = (struct rt_xxx_internal *)ip->idb_ptr;
328  RT_XXX_CK_MAGIC(xxx_ip);
329  if (dbip) RT_CK_DBI(dbip);
330 
331  BU_CK_EXTERNAL(ep);
332  ep->ext_nbytes = SIZEOF_NETWORK_DOUBLE * ELEMENTS_PER_VECT;
333  ep->ext_buf = (void *)bu_calloc(1, ep->ext_nbytes, "xxx external");
334 
335  /* Since libwdb users may want to operate in units other than mm,
336  * we offer the opportunity to scale the solid (to get it into mm)
337  * on the way out.
338  */
339  VSCALE(vec, xxx_ip->v, local2mm);
340 
341  /* Convert from internal (host) to database (network) format */
342  bu_cv_htond(ep->ext_buf, (unsigned char *)vec, ELEMENTS_PER_VECT);
343 
344  return 0;
345 }
346 
347 
348 /**
349  * Make human-readable formatted presentation of this solid. First
350  * line describes type of solid. Additional lines are indented one
351  * tab, and give parameter values.
352  */
353 int
354 rt_xxx_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
355 {
356  struct rt_xxx_internal *xxx_ip =
357  (struct rt_xxx_internal *)ip->idb_ptr;
358  char buf[256];
359 
360  RT_XXX_CK_MAGIC(xxx_ip);
361  bu_vls_strcat(str, "truncated general xxx (XXX)\n");
362 
363  if (!verbose)
364  return 0;
365 
366  sprintf(buf, "\tV (%g, %g, %g)\n",
367  INTCLAMP(xxx_ip->v[X] * mm2local),
368  INTCLAMP(xxx_ip->v[Y] * mm2local),
369  INTCLAMP(xxx_ip->v[Z] * mm2local));
370  bu_vls_strcat(str, buf);
371 
372  return 0;
373 }
374 
375 
376 /**
377  * Free the storage associated with the rt_db_internal version of this
378  * solid.
379  */
380 void
382 {
383  struct rt_xxx_internal *xxx_ip;
384 
385  RT_CK_DB_INTERNAL(ip);
386 
387  xxx_ip = (struct rt_xxx_internal *)ip->idb_ptr;
388  RT_XXX_CK_MAGIC(xxx_ip);
389  xxx_ip->magic = 0; /* sanity */
390 
391  bu_free((char *)xxx_ip, "xxx ifree");
392  ip->idb_ptr = ((void *)0); /* sanity */
393 }
394 
395 
396 /*
397  * Local Variables:
398  * mode: C
399  * tab-width: 8
400  * indent-tabs-mode: t
401  * c-file-style: "stroustrup"
402  * End:
403  * ex: shiftwidth=4 tabstop=8
404  */
int rt_xxx_import5(struct rt_db_internal *ip, const struct bu_external *ep, const mat_t mat, const struct db_i *dbip)
Definition: xxx.c:274
int rt_xxx_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
Definition: xxx.c:252
Definition: raytrace.h:800
#define BU_LIST_INSERT(old, new)
Definition: list.h:183
void rt_xxx_ifree(struct rt_db_internal *ip)
Definition: xxx.c:381
#define SIZEOF_NETWORK_DOUBLE
Definition: cv.h:48
uint32_t magic
Definition: xxx.h:71
void rt_xxx_print(const struct soltab *stp)
Definition: xxx.c:104
Definition: list.h:118
#define RT_CK_APPLICATION(_p)
Definition: raytrace.h:1675
#define RT_CK_RTI(_p)
Definition: raytrace.h:1833
vect_t crv_pdir
Principle direction.
Definition: raytrace.h:307
const mat_t bn_mat_identity
Matrix and vector functionality.
Definition: mat.c:46
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
Definition: raytrace.h:215
int rt_xxx_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
Definition: xxx.c:88
Definition: raytrace.h:368
#define BU_ASSERT_LONG(_lhs, _relation, _rhs)
Definition: defines.h:240
Definition: raytrace.h:248
int rt_xxx_shot(struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead)
Definition: xxx.c:124
Header file for the BRL-CAD common definitions.
#define ID_XXX
Definition: xxx.h:80
#define RT_CK_RAY(_p)
Definition: raytrace.h:224
struct resource * a_resource
dynamic memory resources
Definition: raytrace.h:1591
#define RT_XXX_CK_MAGIC(_p)
Definition: xxx.h:77
void bu_cv_htond(unsigned char *out, const unsigned char *in, size_t count)
struct bu_list l
Definition: raytrace.h:369
vect_t v
Definition: xxx.h:72
if(share_geom)
Definition: nmg_mod.c:3829
int idb_major_type
Definition: raytrace.h:192
Definition: color.c:49
#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 crv_c2
curvature in other direction
Definition: raytrace.h:309
#define RT_CK_HIT(_p)
Definition: raytrace.h:259
const struct rt_functab * idb_meth
for ft_ifree(), etc.
Definition: raytrace.h:194
uint8_t * ext_buf
Definition: parse.h:216
point_t hit_point
DEPRECATED: Intersection point, use VJOIN1 hit_dist.
Definition: raytrace.h:251
int rt_xxx_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
Definition: xxx.c:354
#define UNUSED(parameter)
Definition: common.h:239
void rt_xxx_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
Definition: xxx.c:204
Support for uniform tolerances.
Definition: tol.h:71
void rt_xxx_free(struct soltab *stp)
Definition: xxx.c:219
vect_t r_dir
Direction of ray (UNIT Length)
Definition: raytrace.h:219
#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
void bu_cv_ntohd(unsigned char *out, const unsigned char *in, size_t count)
const struct rt_functab OBJ[]
Definition: table.c:159
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
void rt_xxx_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp)
Definition: xxx.c:181
fastf_t crv_c1
curvature in principle dir
Definition: raytrace.h:308
#define RT_XXX_INTERNAL_MAGIC
Definition: xxx.h:76
Definition: color.c:51
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
int rt_xxx_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
Definition: xxx.c:318
vect_t hit_normal
DEPRECATED: Surface Normal at hit_point, use RT_HIT_NORMAL.
Definition: raytrace.h:252
#define BU_CK_LIST_HEAD(_p)
Definition: list.h:142
#define BU_CK_EXTERNAL(_p)
Definition: parse.h:224
size_t ext_nbytes
Definition: parse.h:210
int rt_xxx_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: xxx.c:233
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_xxx_norm(struct hit *hitp, struct soltab *stp, struct xray *rp)
Definition: xxx.c:164
Definition: color.c:50