LIBWDB(3)

πŸ“¦
version 7.44.0 Β· 2 versions
, in nixpkgs unstable

πŸ’– LIBWDB(3) β€” the BRL-CAD libwdb glow-up πŸ’–

okay so this is libwdb, bestie. it's the library for procedural generation of MGED databases β€” meaning you get to build MGED databases from your own code instead of clicking around in a GUI like it's 1998. part of the BRL-CAD fam. let's go πŸŽ€


✨ SYNOPSIS ✨

#include "vmath.h"
#include "wdb.h"

mk_id(FILE * fp, char * title);
mk_half(FILE * fp, char * name, double d, point_t norm);
mk_rpp(FILE * fp, char * name, point_t min , max, mk_wedge ( fp , name , vert , xdir , zdir , xlen , ylen , zlen , x_top_len ) );

FILE        *fp;
char        *name;
point_t        vert;
vect_t        xdir;
vect_t        zdir;
fastf_t        xlen;
fastf_t        ylen;
fastf_t        zlen;
fastf_t        x_top_len;

mk_arb4(FILE * fp, char * name, point_t pts[]);
mk_arb5(FILE * fp, char * name, point_t pts[]);
mk_arb6(FILE * fp, char * name, point_t pts[]);
mk_arb7(FILE * fp, char * name, point_t pts[]);
mk_arb8(FILE * fp, char * name, point_t pts[]);
mk_sph(FILE * fp, char * name, point_t center, fastf_t radius);
mk_ell(FILE * fp, char * name, point_t center, vect_t a , b , c, mk_tgc ( fp , name , center , a , b , c , d ) FILE * fp, char * name);

point_t        center;
vect_t        a, b, c, d;

mk_tor(FILE * fp, char * name, point_t center, vect_t n, double r1 , r2, mk_cone ( fp , name , base , dir , height , rad1 , rad2 ) FILE * fp);

char        *name;
point_t        base;
vect_t        dir;
fastf_t        height;
fastf_t        rad1;
fastf_t        rad2;

mk_rcc(FILE * fp, char * name, point_t base, vect_t height, fastf_t radius);
mk_pipe(FILE * fp, char * name);

struct wdb_pipept *headp;

mk_pipe_free(struct wdb_pipept * headp);
mk_pipe_init(struct wdb_pipept * headp, point_t coord, fastf_t od , id , bendradius, mk_add_pipe_pt ( headp , coord , od , id , bendradius ) struct wdb_pipept * headp, point_t coord);

fastf_t od, id, bendradius;

mk_comb(FILE * fp, char * name, char * matname, char * matparm, char * rgb, mk_fcomb ( fp , name , len , region ) FILE * fp, char * name, mk_memb ( fp , name , mat , op ) FILE * fp);

char        *name;
mat_t        mat;
int        op;

mk_addmember(char * name, struct wmember * headp, mat_t mat, int op);
mk_lcomb(FILE * fp, char * name, struct wmember * headp, char * matname, char * matparm, char * rgb, mk_lfcomb ( fp , name , headp , region ) FILE * fp, char * name);

struct        wmember *headp;

mk_bsolid(FILE * fp, char * name, int nsurf, double res);
mk_bsurf(FILE * filep, struct b_spline * bp);
🫢 yes, the synopsis is a whole little chaos goblin in places β€” that's exactly how it's printed here, so we're keeping it character for character. no cap, don't @ me.

🌸 DESCRIPTION 🌸

okay so the whole point of this library: it exists so you can write MGED databases from arbitrary procedures. like, your program spits out a database. iconic. ✨

but there's some structure you gotta respect, and rn it's implicit in the calling routines β€” not enforced for you:

  • databases start with an ID record
  • COMB records must be followed immediately by MEMBER records

also, real talk: this library is by no means complete, and routines for writing every type of solid don't exist yet. it's expected to grow and change as experience is gained, but honestly nobody's sure what direction that evolution will take. so be prepared for changes in the interface to some of these routines in future releases. πŸ’€ (we love a library with main character energy and an unpredictable future.)

every routine takes as its first argument the stdio FILE pointer (e.g., stdout) on which the generated MGED database record(s) will be written with fwrite(). periodt.


πŸ¦‹ mk_id

mk_id fwrites an IDENT record on the indicated stdio file, with the string title associated.

⭐ heads up bestie: to have a valid database, the first record written must have been an IDENT record such as written by this routine. no IDENT first = no valid db. that's the vibe check.

πŸ¦‹ mk_half

makes a halfspace with name name. it's specified by the distance d from the origin, and the outward pointing normal vector norm.

πŸ¦‹ mk_rpp

makes an ARB8 called name, specified as a right rectangular parallelepiped in terms of a minimum point min and a maximum point max.

πŸ¦‹ mk_wedge

makes a right angular wedge called name, specified by:

  • a starting vertex located in the lower left corner of the solid
  • an x-direction vector
  • a z-direction vector
  • an x-length
  • a y-length
  • a z-length
  • a top x-length

the y-direction vector is the result of x-direction vector cross z-direction vector. all vertices are make in the counterclockwise direction, bottom face first. the top face is made by extruding the bottom face in the z direction. πŸ’…

πŸ¦‹ mk_arb4

makes an ARB8 called name described as an ARB4, i.e., by 4 points β€” the first 3 of which lie on a plane, and the fourth is the "peak".

πŸ¦‹ mk_arb8

makes an ARB8 called name described by an array of 8 points in pts.

πŸ”₯ important: all plates with 4 points must be co-planar. if there are degeneracies (i.e., all 8 vertices are not distinct), then certain requirements must be met. if we think of the ARB8 as having a top and a bottom plate, the first four points listed must lie on one plate, and the second four points listed must lie on the other plate.

πŸ¦‹ mk_sph and mk_ell

mk_sph makes a spherical ellipsoid called name centered at point center with radius radius.

mk_ell makes an ellipsoid called name centered at point center with three perpendicular radius vectors. the eccentricity of the ellipsoid is controlled by the relative lengths of the three radius vectors. cute AND mathematical πŸŽ€

πŸ¦‹ mk_tgc

makes a truncated general cone called name with:

  • the base plate centered at center
  • a height vector height, which is perpendicular to the two end plates β€” the length of the height vector defines the location of the top plate
  • vectors a and b β€” the base radius vectors
  • vectors c and d β€” the nose vectors

πŸ¦‹ mk_tor

makes a torus called name centered at point center, with the torus lying in a plane with normal n. radius r1 is the distance from the center point of the torus to the center of the solid part, and radius f2 is the radius of the solid part. 🍩

πŸ¦‹ mk_cone

makes a right circular cone called name, specified by the center point of the base, a direction or height vector, a height scalar, and a radius for each end of the cone.

the way this actually goes down: the direction vector is unitized and serves to derive a vector a, which is orthogonal to the direction vector and itself. this vector is scaled by both radii to obtain two of four vectors required to make a cone. it's then crossed with the unitized direction vector, and the result thereof is scaled by both radii as well to obtain the last of four vectors needed to make a cone. ✨ geometry slay ✨

πŸ¦‹ mk_rcc

makes a truncated general cone (TGC) with name name, specified as a right circular cylinder. the base plate of the cylinder is centered at base, with height vector height which is perpendicular to the two end plates β€” the length of which defines the location of the top plate. the radius given as radius defines the size of the end plates.

πŸ¦‹ mk_pipe()

creates a "pipe" solid with the specified name and writes it to the file fp.

you (yes, you) must provide a linked list of "pipe" segments headed by headp. each pipe segment includes fields indicating a "control" point for the pipe, an inner diameter, an outer diameter and a bend radius.

πŸ’€ the rules, and they are strict: - the inner diameter must be less than the outer diameter - a zero inner diameter creates a solid wire rather than a hollow pipe - the bend radius must be greater than the outer radius

the pipe is constructed along straight lines through successive points, with circular bends (of the indicated radius) connecting the straight sections.

and you're responsible for freeing the memory used by the list of pipe segments (see mk_pipe_free() below.

πŸ¦‹ mk_pipe_free()

will free the memory used by a linked list of pipe segments. this does not free the list head. πŸ™ˆ

πŸ¦‹ mk_pipe_init()

initializes a linked list of pipe segments with the initial point, inside diameter, outside diameter, and bend radius.

πŸ¦‹ mk_add_pipe_pt

adds another pipe segment to the list with the indicated point, outside radius, inside radius, and bend radius.

πŸ¦‹ mk_comb

defines a combination of name name, with material properties information included.

  • "len" indicated the number of mk_memb calls (MEMB records) that will immediately follow.
  • "region" is a boolean that is set to mark this combination as a region.
  • "matname" is either a NULL pointer, or a pointer to a string containing the material property name.
  • "matparm" is either a NULL pointer, or a pointer to a string containing the material property parameter information specific to that material.
  • Color is passed as an array of three unsigned chars in "rgb".
  • Color "inherit" is a boolean, and if true, the color and material properties will be passed from upper-level objects to lower-level objects.

πŸ¦‹ mk_fcomb

makes a simple combination header, with name name, length len, and the boolean region. it functions just like mk_comb.

"len" mk_memb calls must immediately follow the call to mk_comb or mk_fcomb. each call to mk_memb adds a reference to object name to the combination. it is transformed by the 4x4 matrix mat, and is combined by boolean operation op, chosen from the list of: UNION, INTERSECT, SUBTRACT, from <brlcad/db.h>.

πŸ¦‹ mk_addmember / mk_lcomb / mk_lfcomb

mk_addmember is used to obtain dynamic storage for a new wmember structure (see wdb.h). then mk_lcomb can be used in the same way as mk_comb to make a combination of a linked list of wmember structures.

πŸ‘‘ this is the only recommended way to create combinations, because it collects up the details in memory, and produces the combination and member records all at once, rather than in multiple calls, as in mk_comb and mk_memb. the glow-up fr fr.

the "op" argument must be one of WMOP_UNION, WMOP_SUBTRACT, or WMOP_INTERSECT.

⚠️ in the future, mk_comb and mk_memb will no longer be supported. consider yourself warned, bestie.

mk_lfcomb is the linked list equivalent of mk_fcomb.

🌟 note that the linked list heads must be initialized by an invocation of BU_LIST_INIT( &head.l );

πŸ¦‹ mk_bsolid / mk_bsurf

the routine mk_bsolid writes the header for a b-spline solid "name", with "nsurf" surfaces, at "res" resolution. this call must be followed by "nsurf" calls to mk_bsurf which enters the respective surfaces into the combination. this pair work much like the mk_comb and mk_memb pair. 🧚

πŸ¦‹ the mk_version global

the global variable mk_version may be set to 4 or 5, depending on which format BRL-CAD database you wish to write. by default, the most recent version is always created. ⭐


🌈 EXAMPLE(S) 🌈

several examples of how to use this library can be found in the proc-db directory of the BRL-CAD source distribution. go peek, they're lowkey the best tutorial πŸ’–


πŸ’œ SEE ALSO πŸ’œ

brlcad(1B), mged(1B), rt(1B)


πŸ’… DIAGNOSTICS πŸ’…

None

(yeah. that's it. that's the diagnostics section. πŸ’€)


😭 BUGS 😭

the library is incomplete. the need for the application to know higher-level details is unfortunate, but necessary to keep the library simple. we may pay for this later. πŸ™ˆ


🫢 AUTHOR 🫢

BRL-CAD Team


this software is Copyright (c) 1987-2026 United States Government as represented by the U.S. Army Research Laboratory.

πŸ› BUG REPORTS πŸ›

ok so if you find a bug or literally any problem at all, don't just suffer in silence bestie 😭 β€” report it! The way you do that is by sending electronic mail to:

devs@brlcad.org

That's it, that's the whole vibe. Spill the tea to the devs, they wanna know 🫢


and that's a wrap on LIBWDB(3)! πŸ’… this iconic little page comes from the BRL-CAD fam and lives in manual section 3 β€” go build something gorgeous with it, mwah πŸŽ€βœ¨

πŸ“¦ where this page comes from