BRL-CAD
#include "common.h"
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <math.h>
#include "bio.h"
#include "bu/cv.h"
#include "vmath.h"
#include "db.h"
#include "nmg.h"
#include "rtgeom.h"
#include "raytrace.h"
#include "../../librt_private.h"
Include dependency graph for rpc.c:

Go to the source code of this file.

Data Structures

struct  rpc_specific
 

Macros

#define RPC_NORM_BODY   (1) /* compute normal */
 
#define RPC_NORM_TOP   (2) /* copy tgc_N */
 
#define RPC_NORM_FRT   (3) /* copy reverse tgc_N */
 
#define RPC_NORM_BACK   (4)
 
#define RPC_TOL   .0001
 

Functions

int rt_rpc_bbox (struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *tol)
 
int rt_rpc_prep (struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
 
void rt_rpc_print (const struct soltab *stp)
 
int rt_rpc_shot (struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead)
 
void rt_rpc_norm (struct hit *hitp, struct soltab *stp, struct xray *rp)
 
void rt_rpc_curve (struct curvature *cvp, struct hit *hitp, struct soltab *stp)
 
void rt_rpc_uv (struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
 
void rt_rpc_free (struct soltab *stp)
 
int rt_rpc_adaptive_plot (struct rt_db_internal *ip, const struct rt_view_info *info)
 
int rt_rpc_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)
 
int rt_mk_parabola (struct rt_pt_node *pts, fastf_t r, fastf_t b, fastf_t dtol, fastf_t ntol)
 
int rt_rpc_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_rpc_import4 (struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
 
int rt_rpc_export4 (struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
 
int rt_rpc_import5 (struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
 
int rt_rpc_export5 (struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
 
int rt_rpc_describe (struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
 
void rt_rpc_ifree (struct rt_db_internal *ip)
 
int rt_rpc_params (struct pc_pc_set *ps, const struct rt_db_internal *ip)
 
void rt_rpc_volume (fastf_t *vol, const struct rt_db_internal *ip)
 
void rt_rpc_centroid (point_t *cent, const struct rt_db_internal *ip)
 
void rt_rpc_surf_area (fastf_t *area, const struct rt_db_internal *ip)
 

Variables

const struct bu_structparse rt_rpc_parse []
 

Detailed Description

Intersect a ray with a Right Parabolic Cylinder.

Algorithm -

Given V, H, R, and B, there is a set of points on this rpc

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

Through a series of Affine Transformations, this set of points will be transformed into a set of points on an rpc located at the origin with a rectangular halfwidth R of 1 along the Y axis, a height H of +1 along the -X axis, a distance B of 1 along the -Z axis between the vertex V and the tip of the parabola.

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

The transformation from X to X' is accomplished by:

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

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

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

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

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

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

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

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

Where W' = k D' + P'.

If Dy' and Dz' are both 0, then there is no hit on the rpc; but the end plates need checking. If there is now only 1 hit point, the top plate needs to be checked as well.

Line L' hits the infinitely long canonical rpc at W' when

 A * k**2 + B * k + C = 0

where

A = Dy'**2 B = (2 * Dy' * Py') - Dz' C = Py'**2 - Pz' - 1 b = |Breadth| = 1.0 h = |Height| = 1.0 r = 1.0

The quadratic formula yields k (which is constant):

k = [ -B +/- sqrt(B**2 - 4*A*C)] / (2*A)

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 ``k'' is constant, and is the same in the formulations for both W and W'.

The hit at ``k'' is a hit on the canonical rpc IFF -1 <= Wx' <= 0 and -1 <= Wz' <= 0.

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

Map W onto the unit rpc, i.e.: W' = S(R(W - V)).

Plane on unit rpc at W' has a normal vector N' where

N' = <0, Wy', -.5>.

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

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

because if H is perpendicular to plane Q, and matrix M maps from Q to Q', then inverse[ transpose(M) ] (H) is perpendicular to Q'. Here, H and Q are in "prime space" with the unit sphere. [Somehow, the notation here is backwards]. So, the mapping matrix M = inverse(S o R), because S o R maps from normal space to the unit sphere.

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

because inverse(R) = transpose(R), so R = transpose(invR), and S = transpose(S).

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

THE TOP AND END PLATES.

If Dz' == 0, line L' is parallel to the top plate, so there is no hit on the top plate. Otherwise, rays intersect the top plate with k = (0 - Pz')/Dz'. The solution is within the top plate IFF -1 <= Wx' <= 0 and -1 <= Wy' <= 1

If Dx' == 0, line L' is parallel to the end plates, so there is no hit on the end plates. Otherwise, rays intersect the front plate with k = (0 - Px') / Dx' and the back plate with k = (-1 - Px') / Dx'.

The solution W' is within an end plate IFF

 Wy'**2 + Wz' <= 1.0 and Wz' <= 1.0

The normal for a hit on the top plate is -Bunit. The normal for a hit on the front plate is -Hunit, and the normal for a hit on the back plate is +Hunit.

Definition in file rpc.c.

Macro Definition Documentation

#define RPC_NORM_BODY   (1) /* compute normal */

Definition at line 354 of file rpc.c.

Referenced by rt_rpc_curve(), rt_rpc_norm(), rt_rpc_shot(), and rt_rpc_uv().

#define RPC_NORM_TOP   (2) /* copy tgc_N */

Definition at line 355 of file rpc.c.

Referenced by rt_rpc_curve(), rt_rpc_norm(), rt_rpc_shot(), and rt_rpc_uv().

#define RPC_NORM_FRT   (3) /* copy reverse tgc_N */

Definition at line 356 of file rpc.c.

Referenced by rt_rpc_curve(), rt_rpc_norm(), rt_rpc_shot(), and rt_rpc_uv().

#define RPC_NORM_BACK   (4)

Definition at line 357 of file rpc.c.

Referenced by rt_rpc_curve(), rt_rpc_norm(), rt_rpc_shot(), and rt_rpc_uv().

#define RPC_TOL   .0001

Referenced by rt_mk_parabola().

Function Documentation

int rt_rpc_bbox ( struct rt_db_internal ip,
point_t *  min,
point_t *  max,
const struct bn_tol tol 
)

Calculate the RPP for an RPC

Definition at line 202 of file rpc.c.

References rt_db_internal::idb_ptr, RT_CK_DB_INTERNAL, and VSETALL.

Referenced by rt_rpc_prep().

int rt_rpc_prep ( struct soltab stp,
struct rt_db_internal ip,
struct rt_i rtip 
)

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

Returns - 0 RPC is OK !0 Error in description

Implicit return - A struct rpc_specific is created, and its address is stored in stp->st_specific for use by rpc_shot().

Definition at line 263 of file rpc.c.

References bn_mat_mul(), bn_mat_trn(), BU_GET, ID_RPC, rt_db_internal::idb_ptr, if(), OBJ, R, rpc_specific::rpc_b, rpc_specific::rpc_Bunit, rpc_specific::rpc_Hunit, rpc_specific::rpc_inv_rsq, rpc_specific::rpc_invRoS, rpc_specific::rpc_Runit, rpc_specific::rpc_SoR, rpc_specific::rpc_V, RT_CK_DB_INTERNAL, rt_rpc_bbox(), rt_i::rti_tol, soltab::st_aradius, soltab::st_bradius, soltab::st_center, soltab::st_id, soltab::st_max, soltab::st_meth, soltab::st_min, soltab::st_specific, and VSET.

Here is the call graph for this function:

void rt_rpc_print ( const struct soltab stp)

Definition at line 339 of file rpc.c.

References bn_mat_print(), rpc_specific::rpc_Bunit, rpc_specific::rpc_Hunit, rpc_specific::rpc_invRoS, rpc_specific::rpc_Runit, rpc_specific::rpc_SoR, rpc_specific::rpc_V, soltab::st_specific, and VPRINT.

Here is the call graph for this function:

int rt_rpc_shot ( struct soltab stp,
struct xray rp,
struct application ap,
struct seg seghead 
)

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

Returns - 0 MISS >0 HIT

Definition at line 369 of file rpc.c.

References application::a_resource, BU_LIST_INSERT, seg::l, NEAR_ZERO, xray::r_dir, xray::r_pt, RPC_NORM_BACK, RPC_NORM_BODY, RPC_NORM_FRT, RPC_NORM_TOP, rpc_specific::rpc_SoR, rpc_specific::rpc_V, RT_GET_SEG, RT_HIT_MAGIC, RT_PCOEF_TOL, seg::seg_in, seg::seg_out, seg::seg_stp, soltab::st_specific, X, Y, and Z.

void rt_rpc_norm ( struct hit hitp,
struct soltab stp,
struct xray rp 
)

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

Definition at line 514 of file rpc.c.

References bu_log(), hit::hit_dist, hit::hit_normal, hit::hit_point, hit::hit_surfno, hit::hit_vpriv, xray::r_dir, xray::r_pt, rpc_specific::rpc_Bunit, rpc_specific::rpc_Hunit, rpc_specific::rpc_invRoS, RPC_NORM_BACK, RPC_NORM_BODY, RPC_NORM_FRT, RPC_NORM_TOP, soltab::st_specific, VSET, and Y.

Here is the call graph for this function:

void rt_rpc_curve ( struct curvature cvp,
struct hit hitp,
struct soltab stp 
)

Return the curvature of the rpc.

Definition at line 547 of file rpc.c.

References bn_vec_ortho(), curvature::crv_c1, curvature::crv_c2, curvature::crv_pdir, hit::hit_normal, hit::hit_point, hit::hit_surfno, rpc_specific::rpc_b, rpc_specific::rpc_Hunit, rpc_specific::rpc_inv_rsq, RPC_NORM_BACK, RPC_NORM_BODY, RPC_NORM_FRT, RPC_NORM_TOP, soltab::st_specific, and Y.

Here is the call graph for this function:

void rt_rpc_uv ( struct application ap,
struct soltab stp,
struct hit hitp,
struct uvcoord uvp 
)

For a hit on the surface of an rpc, return the (u, v) coordinates of the hit point, 0 <= u, v <= 1 u = azimuth v = elevation

Definition at line 581 of file rpc.c.

References hit::hit_point, hit::hit_surfno, if(), RPC_NORM_BACK, RPC_NORM_BODY, RPC_NORM_FRT, RPC_NORM_TOP, rpc_specific::rpc_SoR, rpc_specific::rpc_V, RT_CK_APPLICATION, soltab::st_specific, uvcoord::uv_du, uvcoord::uv_dv, uvcoord::uv_u, uvcoord::uv_v, X, Y, and Z.

Here is the call graph for this function:

void rt_rpc_free ( struct soltab stp)

Definition at line 626 of file rpc.c.

References BU_PUT, and soltab::st_specific.

int rt_rpc_adaptive_plot ( struct rt_db_internal ip,
const struct rt_view_info info 
)

Definition at line 829 of file rpc.c.

References BN_VLIST_LINE_DRAW, BN_VLIST_LINE_MOVE, BU_CK_LIST_HEAD, bu_free(), rt_db_internal::idb_ptr, if(), rt_pt_node::next, primitive_curve_count(), RT_ADD_VLIST, RT_CK_DB_INTERNAL, and rt_view_info::vhead.

Here is the call graph for this function:

int rt_rpc_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 at line 894 of file rpc.c.

References OSL::Strings::back, BN_VLIST_LINE_DRAW, BN_VLIST_LINE_MOVE, BU_ALLOC, BU_CK_LIST_HEAD, bu_free(), bu_malloc(), OSL::Strings::front, rt_db_internal::idb_ptr, if(), M_PI, rt_pt_node::next, rt_tess_tol::norm, rt_pt_node::p, primitive_get_absolute_tolerance(), R, RT_ADD_VLIST, RT_CK_DB_INTERNAL, rt_mk_parabola(), VSET, Y, and Z.

Here is the call graph for this function:

int rt_rpc_tess ( struct nmgregion **  r,
struct model *  m,
struct rt_db_internal ip,
const struct rt_tess_tol ttol,
const struct bn_tol tol 
)

Returns - -1 failure 0 OK. *r points to nmgregion that holds this tessellation.

Definition at line 1068 of file rpc.c.

References OSL::Strings::back, BN_CK_TOL, bn_mat_trn(), BU_ALLOC, bu_calloc(), bu_free(), BU_LIST_FIRST, BU_LIST_FOR, bu_malloc(), OSL::Strings::front, rt_db_internal::idb_ptr, if(), M_PI, rt_pt_node::next, nmg_cface(), nmg_find_fu_of_vu(), nmg_fu_planeeqn(), nmg_gluefaces(), nmg_mark_edges_real(), nmg_mrsv(), nmg_region_a(), nmg_vertex_gv(), nmg_vertexuse_nv(), rt_tess_tol::norm, rt_pt_node::p, primitive_get_absolute_tolerance(), R, RT_CK_DB_INTERNAL, RT_CK_TESS_TOL, rt_mk_parabola(), s, VSET, and Y.

Here is the call graph for this function:

int rt_rpc_import4 ( struct rt_db_internal ip,
const struct bu_external ep,
const fastf_t mat,
const struct db_i dbip 
)

Import an RPC from the database format to the internal format. Apply modeling transformations as well.

Definition at line 1302 of file rpc.c.

References bn_mat_identity, BU_ALLOC, BU_CK_EXTERNAL, bu_free(), bu_log(), db_i::dbi_version, bu_external::ext_buf, flip_dbfloat(), flip_fastf_float(), ID_RPC, rt_db_internal::idb_major_type, rt_db_internal::idb_meth, rt_db_internal::idb_ptr, if(), OBJ, RT_CK_DB_INTERNAL, RT_CK_DBI, RT_RPC_INTERNAL_MAGIC, SMALL_FASTF, and X.

Here is the call graph for this function:

int rt_rpc_export4 ( struct bu_external ep,
const struct rt_db_internal ip,
double  local2mm,
const struct db_i dbip 
)

The name is added by the caller, in the usual place.

Definition at line 1366 of file rpc.c.

References bu_calloc(), BU_CK_EXTERNAL, bu_log(), bu_external::ext_buf, bu_external::ext_nbytes, ID_RPC, rt_db_internal::idb_ptr, NEAR_ZERO, RT_CK_DB_INTERNAL, RT_CK_DBI, RT_DOT_TOL, and RT_LEN_TOL.

Here is the call graph for this function:

int rt_rpc_import5 ( struct rt_db_internal ip,
const struct bu_external ep,
const fastf_t mat,
const struct db_i dbip 
)

Import an RPC from the database format to the internal format. Apply modeling transformations as well.

Definition at line 1416 of file rpc.c.

References bn_mat_identity, BU_ALLOC, BU_ASSERT_LONG, BU_CK_EXTERNAL, bu_cv_ntohd(), bu_free(), bu_log(), bu_external::ext_buf, bu_external::ext_nbytes, ID_RPC, rt_db_internal::idb_major_type, rt_db_internal::idb_meth, rt_db_internal::idb_ptr, OBJ, RT_CK_DB_INTERNAL, RT_CK_DBI, RT_RPC_INTERNAL_MAGIC, SIZEOF_NETWORK_DOUBLE, and SMALL_FASTF.

Here is the call graph for this function:

int rt_rpc_export5 ( struct bu_external ep,
const struct rt_db_internal ip,
double  local2mm,
const struct db_i dbip 
)

The name is added by the caller, in the usual place.

Definition at line 1461 of file rpc.c.

References BU_CK_EXTERNAL, bu_cv_htond(), bu_log(), bu_malloc(), bu_external::ext_buf, bu_external::ext_nbytes, ID_RPC, rt_db_internal::idb_ptr, NEAR_ZERO, RT_CK_DB_INTERNAL, RT_CK_DBI, RT_DOT_TOL, RT_LEN_TOL, and SIZEOF_NETWORK_DOUBLE.

Here is the call graph for this function:

int rt_rpc_describe ( struct bu_vls str,
const struct rt_db_internal ip,
int  verbose,
double  mm2local 
)

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 1513 of file rpc.c.

References bu_vls_strcat(), rt_db_internal::idb_ptr, X, Y, and Z.

Here is the call graph for this function:

void rt_rpc_ifree ( struct rt_db_internal ip)

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

Definition at line 1556 of file rpc.c.

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

Here is the call graph for this function:

int rt_rpc_params ( struct pc_pc_set ps,
const struct rt_db_internal ip 
)

Definition at line 1572 of file rpc.c.

References RT_CK_DB_INTERNAL.

void rt_rpc_volume ( fastf_t vol,
const struct rt_db_internal ip 
)

Definition at line 1581 of file rpc.c.

References rt_db_internal::idb_ptr.

void rt_rpc_centroid ( point_t *  cent,
const struct rt_db_internal ip 
)

Definition at line 1596 of file rpc.c.

References rt_db_internal::idb_ptr.

void rt_rpc_surf_area ( fastf_t area,
const struct rt_db_internal ip 
)

Definition at line 1614 of file rpc.c.

References rt_db_internal::idb_ptr.

Variable Documentation

const struct bu_structparse rt_rpc_parse[]
Initial value:
= {
{ "%f", 3, "V", bu_offsetofarray(struct rt_rpc_internal, rpc_V, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
{ "%f", 3, "H", bu_offsetofarray(struct rt_rpc_internal, rpc_H, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
{ "%f", 3, "B", bu_offsetofarray(struct rt_rpc_internal, rpc_B, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
{ "%f", 1, "r", bu_offsetof(struct rt_rpc_internal, rpc_r), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
{ {'\0', '\0', '\0', '\0'}, 0, (char *)NULL, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
}
Definition: color.c:49
#define bu_offsetofarray(_t, _a, _d, _i)
Definition: parse.h:65
#define BU_STRUCTPARSE_FUNC_NULL
Definition: parse.h:153
#define bu_offsetof(_t, _m)
Definition: parse.h:64
double fastf_t
Definition: defines.h:300

Definition at line 190 of file rpc.c.