g_part.c File Reference

#include "common.h"
#include <stddef.h>
#include <stdio.h>
#include <strings.h>
#include <math.h>
#include "machine.h"
#include "vmath.h"
#include "db.h"
#include "raytrace.h"
#include "nmg.h"
#include "rtgeom.h"
#include "./debug.h"

Include dependency graph for g_part.c:

Go to the source code of this file.

Data Structures

struct  part_specific
struct  part_state
struct  part_vert_strip

Defines

#define RT_PARTICLE_SURF_VSPHERE   1
#define RT_PARTICLE_SURF_BODY   2
#define RT_PARTICLE_SURF_HSPHERE   3
#define SEG_MISS(SEG)   (SEG).seg_stp=(struct soltab *) 0;

Functions

void rt_part_ifree (struct rt_db_internal *ip)
int rt_part_prep (struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
void rt_part_print (register const struct soltab *stp)
int rt_part_shot (struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
void rt_part_vshot (struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
void rt_part_norm (register struct hit *hitp, struct soltab *stp, register struct xray *rp)
void rt_part_curve (register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
void rt_part_uv (struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
void rt_part_free (register struct soltab *stp)
int rt_part_class (void)
HIDDEN void rt_part_hemisphere (register point_t(*ov), register fastf_t *v, fastf_t *a, fastf_t *b, fastf_t *h)
int rt_part_plot (struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
int rt_part_tess (struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
int rt_part_import (struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
int rt_part_export (struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
int rt_part_import5 (struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
int rt_part_export5 (struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
int rt_part_describe (struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)

Variables

const struct bu_structparse rt_part_parse []


Detailed Description

Intersect a ray with a "particle" solid, which can have three main forms: sphere, hemisphere-tipped cylinder (lozenge), and hemisphere-tipped cone. This code draws on the examples of g_rec (Davisson) & g_sph (Dykstra).

Authors - Michael John Muuss Paul Tanenbaum

Source - SECAD/VLD Computing Consortium, Bldg 394 The U. S. Army Ballistic Research Laboratory Aberdeen Proving Ground, Maryland 21005-5066

Algorithm for the hemisphere-tipped cylinder and cone cases -

Given V, H, vrad, and hrad, there is a set of points on this cylinder

{ (x,y,z) | (x,y,z) is on cylinder }

Through a series of Affine Transformations, this set of points will be transformed into a set of points on a unit cylinder (or cone) with the transformed base (V') located at the origin with a transformed radius of 1 (vrad'). The height of the cylinder (or cone) along the +Z axis is +1 (ie, H' = (0,0,1) ), with a transformed radius of hrad/vrad.

{ (x',y',z') | (x',y',z') is on cylinder at origin }

The transformation from X to X' is accomplished by:

finding two unit vectors A and B mutually perpendicular, and perp. to H.

X' = S(R( X - V ))

where R(X) rotates H to the +Z axis, and S(X) scales vrad' to 1 and |H'| to 1.

where R(X) = ( A/(|A|) ) ( B/(|B|) ) . X ( H/(|H|) )

and S(X) = ( 1/|A| 0 0 ) ( 0 1/|B| 0 ) . X ( 0 0 1/|H| )

To find the intersection of a line with the surface of the cylinder, consider the parametric line L:

L : { P(n) | P + t(n) . D }

Call W the actual point of intersection between L and the cylinder. Let W' be the point of intersection between L' and the unit cylinder.

L' : { P'(n) | P' + t(n) . D' }

W = invR( invS( W' ) ) + V

Where W' = k D' + P'.

If Dx' and Dy' are both 0, then there is no hit on the cylinder; but the end spheres need checking.

The equation for the unit cylinder ranging along Z is

x**2 + y**2 - r**2 = 0

and the equation for a unit cone ranging along Z is

x**2 + y**2 - f(z)**2 = 0

where in this case f(z) linearly interpolates the radius of the cylinder from vrad (r1) to hrad (r2) as z ranges from 0 to 1, i.e.:

f(z) = (r2-r1)/1 * z + r1

let m = (r2-r1)/1, and substitute:

x**2 + y**2 - (m*z+r1)**2 = 0 .

For the cylinder case, r1 == r2, so m == 0, and everything simplifies.

The parametric formulation for line L' is P' + t * D', or

x = Px' + t * Dx' y = Py' + t * Dy' z = Pz' + t * Dz' .

Substituting these definitions into the formula for the unit cone gives

(Px'+t*Dx')**2 + (Py'+t*Dy')**2 + (m*(Pz'+t*Dz')+r1)**2 = 0

Expanding and regrouping terms gives a quadratic in "t" which has the form

a * t**2 + b * t + c = 0

where

a = Dx'**2 + Dy'**2 - m**2 * Dz'**2 b = 2 * (Px'*Dx' + Py'*Dy' - m**2 * Pz'*Dz' - m*r1*Dz') c = Px'**2 + Py'**2 - m**2 * Pz'**2 - 2*m*r1*Pz' - r1**2

Line L' hits the infinitely tall unit cone at point(s) W' which correspond to the roots of the quadratic. The quadratic formula yields values for "t"

t = [ -b +/- sqrt( b** - 4 * a * c ) ] / ( 2 * a )

This parameter "t" can be substituted into the formulas for either L' or L, because affine transformations preserve distances along lines.

Now, D' = S( R( D ) ) and P' = S( R( P - V ) )

Substituting,

W = V + invR( invS[ k *( S( R( D ) ) ) + S( R( P - V ) ) ] ) = V + invR( ( k * R( D ) ) + R( P - V ) ) = V + k * D + P - V = k * D + P

Note that ``t'' is constant, and is the same in the formulations for both W and W'.

The hit at ``t'' is a hit on the height=1 unit cylinder IFF 0 <= Wz' <= 1.

NORMALS. Given the point W on the surface of the cylinder, what is the vector normal to the tangent plane at that point?

Map W onto the unit cylinder, ie: W' = S( R( W - V ) ).

Plane on unit cylinder at W' has a normal vector N' of the same value as W' in x and y, with z set to zero, ie, (Wx', Wy', 0)

The plane transforms back to the tangent plane at W, and this new plane (on the original cylinder) has a normal vector of N, viz:

N = inverse[ transpose(invR o invS) ] ( N' ) = inverse[ transpose(invS) o transpose(invR) ] ( N' ) = inverse[ inverse(S) o R ] ( N' ) = invR o S ( N' )

Note that the normal vector produced above will not have unit length.

THE HEMISPHERES.

THE "EQUIVALENT CONE":

In order to have exact matching of the surface normals at the join between the conical body of the particle and the hemispherical end, it is necessary to alter the cone to form an "equivalent cone", where the end caps of the cone are both shifted away from the large hemisphere and towards the smaller one. This makes the cone end where it is tangent to the hemisphere. The calculation for theta come from a diagram drawn by PJT on 18-Nov-99.

Definition in file g_part.c.


Define Documentation

#define RT_PARTICLE_SURF_VSPHERE   1
 

Definition at line 224 of file g_part.c.

Referenced by rt_part_curve(), rt_part_norm(), and rt_part_shot().

#define RT_PARTICLE_SURF_BODY   2
 

Definition at line 225 of file g_part.c.

Referenced by rt_part_curve(), rt_part_norm(), and rt_part_shot().

#define RT_PARTICLE_SURF_HSPHERE   3
 

Definition at line 226 of file g_part.c.

Referenced by rt_part_curve(), rt_part_norm(), and rt_part_shot().

#define SEG_MISS SEG   )     (SEG).seg_stp=(struct soltab *) 0;
 

Definition at line 745 of file g_part.c.


Function Documentation

void rt_part_ifree struct rt_db_internal ip  ) 
 

R T _ P A R T _ I F R E E

Free the storage associated with the rt_db_internal version of this solid.

Definition at line 1784 of file g_part.c.

References bu_free(), GENPTR_NULL, rt_db_internal::idb_ptr, and RT_CK_DB_INTERNAL.

Here is the call graph for this function:

int rt_part_prep struct soltab stp,
struct rt_db_internal ip,
struct rt_i rtip
 

R T _ P A R T _ P R E P

Given a pointer to a GED database record, and a transformation matrix, determine if this is a valid particle, and if so, precompute various terms of the formula.

Returns - 0 particle is OK !0 Error in description

Implicit return - A struct part_specific is created, and it's address is stored in stp->st_specific for use by part_shot().

Definition at line 254 of file g_part.c.

References bn_mat_mul(), bn_mat_trn(), bn_vec_ortho(), BU_GETSTRUCT, bu_log(), directory::d_namep, rt_db_internal::idb_ptr, MAGNITUDE, MAGSQ, MAT_IDN, rt_part_internal::part_H, part_specific::part_h_erad, part_specific::part_h_hdist, rt_part_internal::part_hrad, part_specific::part_hrad_prime, part_specific::part_int, part_specific::part_invRoS, part_specific::part_SoR, rt_part_internal::part_type, rt_part_internal::part_V, part_specific::part_v_erad, part_specific::part_v_hdist, rt_part_internal::part_vrad, part_specific::part_vrad_prime, R, RT_CK_DB_INTERNAL, RT_PART_CK_MAGIC, RT_PARTICLE_TYPE_SPHERE, SMALL, soltab::st_aradius, soltab::st_bradius, soltab::st_center, soltab::st_dp, soltab::st_max, soltab::st_min, soltab::st_specific, VADD2, VCROSS, VJOIN1, VMINMAX, VMOVE, VSCALE, VSUB2SCALE, X, Y, and Z.

Here is the call graph for this function:

void rt_part_print register const struct soltab stp  ) 
 

R T _ P A R T _ P R I N T

Definition at line 413 of file g_part.c.

References bn_mat_print(), bu_log(), rt_part_internal::part_H, rt_part_internal::part_hrad, part_specific::part_int, part_specific::part_invRoS, part_specific::part_SoR, rt_part_internal::part_type, rt_part_internal::part_V, rt_part_internal::part_vrad, RT_PARTICLE_TYPE_CONE, RT_PARTICLE_TYPE_CYLINDER, RT_PARTICLE_TYPE_SPHERE, and VPRINT.

Here is the call graph for this function:

int rt_part_shot struct soltab stp,
register struct xray rp,
struct application ap,
struct seg seghead
 

R T _ P A R T _ S H O T

Intersect a ray with a part. If an intersection occurs, a struct seg will be acquired and filled in.

Returns - 0 MISS >0 HIT

VJOIN1( hitp->hit_vpriv, pprime, t1, dprime );

VJOIN1( hitp->hit_vpriv, pprime, t2, dprime );

Definition at line 455 of file g_part.c.

References application::a_resource, BU_LIST_INSERT, FAST, seg::l, LOCAL, MAGSQ, MAT4X3VEC, NEAR_ZERO, rt_part_internal::part_H, part_specific::part_h_hdist, rt_part_internal::part_hrad, part_specific::part_hrad_prime, part_specific::part_int, part_specific::part_SoR, rt_part_internal::part_type, rt_part_internal::part_V, part_specific::part_v_hdist, rt_part_internal::part_vrad, part_specific::part_vrad_prime, RT_GET_SEG, RT_HIT_MAGIC, rt_hitsort(), RT_PARTICLE_SURF_BODY, RT_PARTICLE_SURF_HSPHERE, RT_PARTICLE_SURF_VSPHERE, RT_PARTICLE_TYPE_CYLINDER, RT_PARTICLE_TYPE_SPHERE, seg::seg_in, seg::seg_out, seg::seg_stp, SMALL, soltab::st_specific, VADD2, VDOT, VSUB2, X, Y, and Z.

Here is the call graph for this function:

void rt_part_vshot struct soltab **  stp,
struct xray **  rp,
struct seg segp,
int  n,
struct application ap
 

R T _ P A R T _ V S H O T

Vectorized version.

Definition at line 753 of file g_part.c.

References rt_vstub().

Here is the call graph for this function:

void rt_part_norm register struct hit hitp,
struct soltab stp,
register struct xray rp
 

R T _ P A R T _ N O R M

Given ONE ray distance, return the normal and entry/exit point.

Definition at line 769 of file g_part.c.

References FAST, MAT4X3VEC, rt_part_internal::part_H, part_specific::part_hrad_prime, part_specific::part_int, part_specific::part_invRoS, rt_part_internal::part_type, rt_part_internal::part_V, part_specific::part_vrad_prime, RT_PARTICLE_SURF_BODY, RT_PARTICLE_SURF_HSPHERE, RT_PARTICLE_SURF_VSPHERE, RT_PARTICLE_TYPE_CYLINDER, soltab::st_specific, VJOIN1, VSUB2, VSUB3, VUNITIZE, X, Y, and Z.

void rt_part_curve register struct curvature cvp,
register struct hit hitp,
struct soltab stp
 

R T _ P A R T _ C U R V E

Return the curvature of the particle. There are two cases: hitting a hemisphere, and hitting the cylinder.

Definition at line 819 of file g_part.c.

References bn_vec_ortho(), MAT4X3VEC, rt_part_internal::part_H, part_specific::part_h_erad, rt_part_internal::part_hrad, part_specific::part_int, part_specific::part_SoR, rt_part_internal::part_V, part_specific::part_v_erad, rt_part_internal::part_vrad, RT_PARTICLE_SURF_BODY, RT_PARTICLE_SURF_HSPHERE, RT_PARTICLE_SURF_VSPHERE, soltab::st_specific, VCROSS, VSUB2, VUNITIZE, and Z.

Here is the call graph for this function:

void rt_part_uv struct application ap,
struct soltab stp,
register struct hit hitp,
register struct uvcoord uvp
 

R T _ P A R T _ U V

For a hit on the surface of a particle, return the (u,v) coordinates of the hit point, 0 <= u,v <= 1. u = azimuth v = elevation along H

The 'u' coordinate wraps around the particle, once. The 'v' coordinate covers the 'height' of the particle, from V-r1 to (V+H)+r2.

hit_point has already been computed.

Definition at line 866 of file g_part.c.

References application::a_diverge, application::a_rbeam, bn_atan2(), bn_inv2pi, MAGNITUDE, MAT4X3VEC, rt_part_internal::part_H, part_specific::part_h_erad, part_specific::part_int, rt_part_internal::part_magic, part_specific::part_SoR, rt_part_internal::part_V, part_specific::part_v_erad, RT_PART_CK_MAGIC, soltab::st_specific, V_MIN, VSUB2, X, Y, and Z.

Here is the call graph for this function:

void rt_part_free register struct soltab stp  ) 
 

R T _ P A R T _ F R E E

Definition at line 907 of file g_part.c.

References bu_free(), and GENPTR_NULL.

Here is the call graph for this function:

int rt_part_class void   ) 
 

R T _ P A R T _ C L A S S

Definition at line 920 of file g_part.c.

HIDDEN void rt_part_hemisphere register point_t ov,
register fastf_t v,
fastf_t a,
fastf_t b,
fastf_t h
 

R T _ P A R T _ H E M I S P H E R E 8

Produce a crude approximation to a hemisphere, 8 points around the rim [0]..[7], 4 points around a midway latitude [8]..[11], and 1 point at the pole [12].

For the dome, connect up: 0 8 12 10 4 2 9 12 11 6

Definition at line 938 of file g_part.c.

References VADD2, VJOIN2, and VSUB2.

int rt_part_plot struct bu_list vhead,
struct rt_db_internal ip,
const struct rt_tess_tol ttol,
const struct bn_tol tol
 

R T _ P A R T _ P L O T

Definition at line 966 of file g_part.c.

References BN_VLIST_LINE_DRAW, BN_VLIST_LINE_MOVE, rt_db_internal::idb_ptr, rt_part_internal::part_type, rt_part_internal::part_V, rt_part_internal::part_vrad, RT_ADD_VLIST, RT_CK_DB_INTERNAL, rt_ell_16pts(), RT_PART_CK_MAGIC, RT_PARTICLE_TYPE_SPHERE, tail, VSET, and X.

Here is the call graph for this function:

int rt_part_tess struct nmgregion **  r,
struct model m,
struct rt_db_internal ip,
const struct rt_tess_tol ttol,
const struct bn_tol tol
 

R T _ P A R T _ T E S S

Based upon the tesselator for the ellipsoid.

Break the particle into three parts: Upper hemisphere 0..nsegs H North middle cylinder nsegs..nsegs+1 lower hemisphere nsegs+1..nstrips-1 V South

Definition at line 1098 of file g_part.c.

References rt_tess_tol::abs, bn_halfpi, bn_mat_fromto(), bn_mat_inv(), bn_mat_mul(), bn_mat_trn(), bu_calloc(), BU_LIST_FIRST, rt_db_internal::idb_ptr, LOCAL, MAT_IDN, part_vert_strip::nfaces, nmg_mrsv(), rt_tess_tol::norm, part_vert_strip::nverts, part_vert_strip::nverts_per_strip, rt_part_internal::part_H, rt_part_internal::part_hrad, rt_part_internal::part_type, rt_part_internal::part_V, rt_part_internal::part_vrad, R, rt_tess_tol::rel, RT_CK_DB_INTERNAL, RT_PART_CK_MAGIC, RT_PARTICLE_TYPE_SPHERE, state, VADD2, and VSET.

Here is the call graph for this function:

int rt_part_import struct rt_db_internal ip,
const struct bu_external ep,
register const fastf_t mat,
const struct db_i dbip
 

R T _ P A R T _ I M P O R T

Definition at line 1481 of file g_part.c.

References BU_CK_EXTERNAL, bu_free(), bu_log(), bu_malloc(), DB5_MAJORTYPE_BRLCAD, DBID_PARTICLE, bu_external::ext_buf, ID_PARTICLE, rt_db_internal::idb_major_type, rt_db_internal::idb_meth, rt_db_internal::idb_ptr, MAGSQ, MAT4X3PNT, MAT4X3VEC, ntohd(), NULL, record::particle_rec::p_h, record::particle_rec::p_hrad, record::particle_rec::p_v, record::particle_rec::p_vrad, record::part, rt_part_internal::part_H, rt_part_internal::part_hrad, rt_part_internal::part_magic, rt_part_internal::part_type, rt_part_internal::part_V, rt_part_internal::part_vrad, RT_CK_DB_INTERNAL, RT_PART_INTERNAL_MAGIC, RT_PARTICLE_TYPE_CONE, RT_PARTICLE_TYPE_CYLINDER, RT_PARTICLE_TYPE_SPHERE, record::u_id, and VSETALL.

Here is the call graph for this function:

int rt_part_export struct bu_external ep,
const struct rt_db_internal ip,
double  local2mm,
const struct db_i dbip
 

R T _ P A R T _ E X P O R T

Definition at line 1566 of file g_part.c.

References bu_calloc(), BU_CK_EXTERNAL, DBID_PARTICLE, bu_external::ext_buf, bu_external::ext_nbytes, htond(), ID_PARTICLE, rt_db_internal::idb_ptr, record::particle_rec::p_h, record::particle_rec::p_hrad, record::particle_rec::p_id, record::particle_rec::p_v, record::particle_rec::p_vrad, record::part, rt_part_internal::part_H, rt_part_internal::part_hrad, rt_part_internal::part_V, rt_part_internal::part_vrad, RT_CK_DB_INTERNAL, RT_PART_CK_MAGIC, and VSCALE.

Here is the call graph for this function:

int rt_part_import5 struct rt_db_internal ip,
const struct bu_external ep,
register const fastf_t mat,
const struct db_i dbip
 

R T _ P A R T _ I M P O R T 5

Definition at line 1606 of file g_part.c.

References BU_ASSERT_LONG, BU_CK_EXTERNAL, bu_free(), bu_log(), bu_malloc(), DB5_MAJORTYPE_BRLCAD, bu_external::ext_buf, bu_external::ext_nbytes, ID_PARTICLE, rt_db_internal::idb_major_type, rt_db_internal::idb_meth, rt_db_internal::idb_ptr, MAGSQ, MAT4X3PNT, MAT4X3VEC, ntohd(), NULL, rt_part_internal::part_H, rt_part_internal::part_hrad, rt_part_internal::part_magic, rt_part_internal::part_type, rt_part_internal::part_V, rt_part_internal::part_vrad, RT_CK_DB_INTERNAL, RT_PART_INTERNAL_MAGIC, RT_PARTICLE_TYPE_CONE, RT_PARTICLE_TYPE_CYLINDER, RT_PARTICLE_TYPE_SPHERE, SIZEOF_NETWORK_DOUBLE, and VSETALL.

Here is the call graph for this function:

int rt_part_export5 struct bu_external ep,
const struct rt_db_internal ip,
double  local2mm,
const struct db_i dbip
 

R T _ P A R T _ E X P O R T 5

Definition at line 1681 of file g_part.c.

References BU_CK_EXTERNAL, bu_malloc(), bu_external::ext_buf, bu_external::ext_nbytes, htond(), ID_PARTICLE, rt_db_internal::idb_ptr, rt_part_internal::part_H, rt_part_internal::part_hrad, rt_part_internal::part_V, rt_part_internal::part_vrad, RT_CK_DB_INTERNAL, RT_PART_CK_MAGIC, SIZEOF_NETWORK_DOUBLE, and VSCALE.

Here is the call graph for this function:

int rt_part_describe struct bu_vls str,
const struct rt_db_internal ip,
int  verbose,
double  mm2local
 

R T _ P A R T _ D E S C R I B E

Make human-readable formatted presentation of this solid. First line describes type of solid. Additional lines are indented one tab, and give parameter values.

Definition at line 1717 of file g_part.c.

References bu_vls_strcat(), rt_db_internal::idb_ptr, INTCLAMP, RT_PART_CK_MAGIC, RT_PARTICLE_TYPE_CONE, RT_PARTICLE_TYPE_CYLINDER, RT_PARTICLE_TYPE_SPHERE, X, Y, and Z.

Here is the call graph for this function:


Variable Documentation

const struct bu_structparse rt_part_parse[]
 

Initial value:

 {
    { "%f", 3, "V",  bu_offsetof(struct rt_part_internal, part_V[X]), BU_STRUCTPARSE_FUNC_NULL },
    { "%f", 3, "H",  bu_offsetof(struct rt_part_internal, part_H[X]), BU_STRUCTPARSE_FUNC_NULL },
    { "%f", 1, "r_v",bu_offsetof(struct rt_part_internal, part_vrad), BU_STRUCTPARSE_FUNC_NULL },
    { "%f", 1, "r_h",bu_offsetof(struct rt_part_internal, part_hrad), BU_STRUCTPARSE_FUNC_NULL },
    { {'\0','\0','\0','\0'}, 0, (char *)NULL, 0, BU_STRUCTPARSE_FUNC_NULL }
 }

Definition at line 228 of file g_part.c.


Generated on Mon Sep 18 01:25:05 2006 for BRL-CAD by  doxygen 1.4.6