#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 [] |
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.
|
Definition at line 224 of file g_part.c. Referenced by rt_part_curve(), rt_part_norm(), and rt_part_shot(). |
|
Definition at line 225 of file g_part.c. Referenced by rt_part_curve(), rt_part_norm(), and rt_part_shot(). |
|
Definition at line 226 of file g_part.c. Referenced by rt_part_curve(), rt_part_norm(), and rt_part_shot(). |
|
|
|
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: ![]() |
|
|
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: ![]() |
|
|
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: ![]() |
|
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. |
|
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: ![]() |
|
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: ![]() |
|
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: ![]() |
|
R T _ P A R T _ C L A S S |
|
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 |
|
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: ![]() |
|
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: ![]() |
|
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: ![]() |
|
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: ![]() |
|
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: ![]() |
|
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: ![]() |
|
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: ![]() |
|
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 } } |