Push the primitive specific point spacing logic down to the per-primitive adaptive plotting routines.
This commit is contained in:
1 parent
055994d780
commit
59dbc14461
18 files changed
+151
-199
No files matched your search
+7
-17
@@ -54,11 +54,14 @@ struct rt_view_info {
|
||||
const struct bn_tol *tol;
|
||||
|
||||
/**
|
||||
* The average distance between the segment points of plotted
|
||||
* curves. Smaller spacing means more points per curve, and thus
|
||||
* smoother (more accurate) plot curves.
|
||||
* Inputs and settings to calculate point spacing - the average distance
|
||||
* between the segment points of plotted curves. Smaller spacing means
|
||||
* more points per curve, and thus smoother (more accurate) plot curves.
|
||||
*
|
||||
* Individual primitives may need to use primitive specific information
|
||||
* to calculate the final spacing, hence these inputs are passed to the
|
||||
* adaptive plot routines.
|
||||
*/
|
||||
fastf_t point_spacing;
|
||||
struct bview *v;
|
||||
fastf_t s_size;
|
||||
fastf_t point_scale;
|
||||
@@ -157,19 +160,6 @@ struct rt_selection_operation {
|
||||
} parameters;
|
||||
};
|
||||
|
||||
/* Choose a point spacing for the given solid (sp, ip) s.t. solid
|
||||
* curves plotted with that spacing will look smooth when rasterized
|
||||
* in the given view (gvp).
|
||||
*
|
||||
* TODO: view_avg_sample_spacing() might be sufficient if we can
|
||||
* develop a general decimation routine for the resulting plots, in
|
||||
* which case, this function could be removed. */
|
||||
RT_EXPORT extern fastf_t
|
||||
rt_solid_point_spacing_for_view(
|
||||
struct rt_db_internal *ip,
|
||||
struct rt_view_info *vi);
|
||||
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* RT_VIEW_H */
|
||||
|
||||
@@ -766,12 +766,7 @@ draw_solid_wireframe(struct bview_scene_obj *sp, struct bview *gvp, struct db_i
|
||||
info.v = gvp;
|
||||
info.s_size = sp->s_size;
|
||||
info.point_scale = gvp->gvs.point_scale;
|
||||
|
||||
info.point_spacing = rt_solid_point_spacing_for_view(ip, &info);
|
||||
|
||||
info.curve_spacing = sp->s_size / 2.0;
|
||||
|
||||
info.point_spacing /= gvp->gvs.point_scale;
|
||||
info.curve_spacing /= gvp->gvs.curve_scale;
|
||||
|
||||
ret = ip->idb_meth->ft_adaptive_plot(ip, &info);
|
||||
|
||||
@@ -99,10 +99,6 @@ _wireframe_plot(struct bview_scene_obj *s, struct rt_db_internal *ip)
|
||||
info.vhead = &s->s_vlist;
|
||||
info.tol = d->tol;
|
||||
info.point_scale = s->s_os.point_scale;
|
||||
|
||||
info.point_spacing = rt_solid_point_spacing_for_view(ip, &info);
|
||||
info.point_spacing /= s->s_os.point_scale;
|
||||
|
||||
info.curve_spacing = s->s_size / 2.0;
|
||||
info.curve_spacing /= s->s_os.curve_scale;
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ set(LIBRT_SOURCES
|
||||
uv.c
|
||||
vds/vds.c
|
||||
vers.c
|
||||
view.cpp
|
||||
view.c
|
||||
vlist.c
|
||||
vshoot.c
|
||||
wdb.c
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "vmath.h"
|
||||
#include "bview.h"
|
||||
#include "rt/db4.h"
|
||||
#include "raytrace.h"
|
||||
|
||||
@@ -209,6 +210,10 @@ extern void plot_ellipse(
|
||||
extern int _rt_tcl_list_to_int_array(const char *list, int **array, int *array_len);
|
||||
extern int _rt_tcl_list_to_fastf_array(const char *list, fastf_t **array, int *array_len);
|
||||
|
||||
/* view.c */
|
||||
extern fastf_t solid_point_spacing(struct bview *gvp, fastf_t solid_width);
|
||||
extern fastf_t view_avg_sample_spacing(struct bview *gvp);
|
||||
|
||||
#ifdef USE_OPENCL
|
||||
extern cl_device_id clt_get_cl_device(void);
|
||||
extern cl_program clt_get_program(cl_context context, cl_device_id device, cl_uint count, const char *filename[], const char *options);
|
||||
|
||||
@@ -875,7 +875,7 @@ rt_bot_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
vertex_tree = build_vertex_tree(bot);
|
||||
|
||||
fold_data.root = vertex_tree;
|
||||
fold_data.point_spacing = info->point_spacing;
|
||||
fold_data.point_spacing = view_avg_sample_spacing(info->v);
|
||||
(void)rt_bot_bbox(ip, &min, &max, NULL);
|
||||
d1 = max[0] - min[0];
|
||||
d2 = max[1] - min[1];
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
|
||||
#include "raytrace.h"
|
||||
#include "rt/geom.h"
|
||||
#include "../../librt_private.h"
|
||||
|
||||
#include "./brep_local.h"
|
||||
#include "./brep_debug.h"
|
||||
@@ -1848,6 +1849,39 @@ plot_face_from_surface_tree(struct bu_list *vhead, SurfaceTree* st, int isocurve
|
||||
plot_BBNode(vhead, st, root, isocurveres, gridres);
|
||||
}
|
||||
|
||||
static fastf_t
|
||||
brep_avg_curve_bbox_diagonal_len(ON_Brep *brep)
|
||||
{
|
||||
fastf_t avg_curve_len = 0.0;
|
||||
int i, num_curves = 0;
|
||||
|
||||
for (i = 0; i < brep->m_E.Count(); ++i) {
|
||||
ON_BrepEdge &e = brep->m_E[i];
|
||||
const ON_Curve *crv = e.EdgeCurveOf();
|
||||
|
||||
if (!crv->IsLinear()) {
|
||||
++num_curves;
|
||||
|
||||
ON_BoundingBox bbox;
|
||||
if (crv->GetTightBoundingBox(bbox)) {
|
||||
avg_curve_len += bbox.Diagonal().Length();
|
||||
} else {
|
||||
ON_3dVector linear_approx =
|
||||
crv->PointAtEnd() - crv->PointAtStart();
|
||||
avg_curve_len += linear_approx.Length();
|
||||
}
|
||||
}
|
||||
}
|
||||
avg_curve_len /= num_curves;
|
||||
|
||||
return avg_curve_len;
|
||||
}
|
||||
|
||||
static fastf_t
|
||||
brep_est_avg_curve_len(struct rt_brep_internal *bi)
|
||||
{
|
||||
return brep_avg_curve_bbox_diagonal_len(bi->brep) * 2.0;
|
||||
}
|
||||
|
||||
int
|
||||
rt_brep_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
@@ -1862,6 +1896,8 @@ rt_brep_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info
|
||||
bi = (struct rt_brep_internal*)ip->idb_ptr;
|
||||
RT_BREP_CK_MAGIC(bi);
|
||||
|
||||
fastf_t point_spacing = solid_point_spacing(info->v, brep_est_avg_curve_len(bi) * M_2_PI * 2.0);
|
||||
|
||||
ON_Brep* brep = bi->brep;
|
||||
int gridres = 10;
|
||||
int isocurveres = 100;
|
||||
@@ -1918,14 +1954,14 @@ rt_brep_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info
|
||||
// achieved and the distance between the end of the last
|
||||
// segment and the endpoint is within point spacing
|
||||
for (int nsegs = 0; (nsegs < min_linear_seg_count) ||
|
||||
(DIST_PNT_PNT(pt1, endpt) > info->point_spacing); ++nsegs) {
|
||||
(DIST_PNT_PNT(pt1, endpt) > point_spacing); ++nsegs) {
|
||||
p = crv->PointAt(dom.ParameterAt(t2));
|
||||
VMOVE(pt2, p);
|
||||
|
||||
// bring t2 increasingly closer to t1 until target
|
||||
// point spacing is achieved
|
||||
double step = t2 - t1;
|
||||
while (DIST_PNT_PNT(pt1, pt2) > info->point_spacing) {
|
||||
while (DIST_PNT_PNT(pt1, pt2) > point_spacing) {
|
||||
step /= 2.0;
|
||||
t2 = t1 + step;
|
||||
p = crv->PointAt(dom.ParameterAt(t2));
|
||||
|
||||
@@ -833,7 +833,7 @@ ehy_plot_hyperbola(
|
||||
static int
|
||||
ehy_curve_points(
|
||||
const struct rt_ehy_internal *ehy,
|
||||
const struct rt_view_info *info)
|
||||
fastf_t point_spacing)
|
||||
{
|
||||
fastf_t avg_r, approx_curve_len;
|
||||
point_t p1, p2;
|
||||
@@ -845,21 +845,21 @@ ehy_curve_points(
|
||||
|
||||
approx_curve_len = 2.0 * DIST_PNT_PNT(p1, p2);
|
||||
|
||||
return approx_curve_len / info->point_spacing;
|
||||
return approx_curve_len / point_spacing;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ehy_ellipse_points(
|
||||
const struct rt_ehy_internal *ehy,
|
||||
const struct rt_view_info *info)
|
||||
fastf_t point_spacing)
|
||||
{
|
||||
fastf_t avg_radius, avg_circumference;
|
||||
|
||||
avg_radius = (ehy->ehy_r1 + ehy->ehy_r2) / 2.0;
|
||||
avg_circumference = M_2PI * avg_radius;
|
||||
|
||||
return avg_circumference / info->point_spacing;
|
||||
return avg_circumference / point_spacing;
|
||||
}
|
||||
|
||||
|
||||
@@ -872,18 +872,20 @@ rt_ehy_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
struct rt_ehy_internal *ehy;
|
||||
struct rt_pnt_node *pts_r1, *pts_r2, *node, *node1, *node2;
|
||||
|
||||
fastf_t point_spacing = solid_point_spacing(info->v, info->s_size);
|
||||
|
||||
BU_CK_LIST_HEAD(info->vhead);
|
||||
RT_CK_DB_INTERNAL(ip);
|
||||
ehy = (struct rt_ehy_internal *)ip->idb_ptr;
|
||||
RT_EHY_CK_MAGIC(ehy);
|
||||
|
||||
num_curve_points = ehy_curve_points(ehy, info);
|
||||
num_curve_points = ehy_curve_points(ehy, point_spacing);
|
||||
|
||||
if (num_curve_points < 3) {
|
||||
num_curve_points = 3;
|
||||
}
|
||||
|
||||
num_ellipse_points = ehy_ellipse_points(ehy, info);
|
||||
num_ellipse_points = ehy_ellipse_points(ehy, point_spacing);
|
||||
|
||||
if (num_ellipse_points < 6) {
|
||||
num_ellipse_points = 6;
|
||||
|
||||
@@ -757,7 +757,7 @@ draw_cross_sections_along_ell_vector(struct ell_draw_configuration config)
|
||||
static int
|
||||
ell_ellipse_points(
|
||||
const struct rt_ell_internal *ell,
|
||||
const struct rt_view_info *info)
|
||||
fastf_t point_spacing)
|
||||
{
|
||||
fastf_t avg_radius, avg_circumference;
|
||||
fastf_t ell_mag_a, ell_mag_b, ell_mag_c;
|
||||
@@ -769,7 +769,7 @@ ell_ellipse_points(
|
||||
avg_radius = (ell_mag_a + ell_mag_b + ell_mag_c) / 3.0;
|
||||
avg_circumference = M_2PI * avg_radius;
|
||||
|
||||
return avg_circumference / info->point_spacing;
|
||||
return avg_circumference / point_spacing;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -783,10 +783,12 @@ rt_ell_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
eip = (struct rt_ell_internal *)ip->idb_ptr;
|
||||
RT_ELL_CK_MAGIC(eip);
|
||||
|
||||
fastf_t point_spacing = solid_point_spacing(info->v, info->s_size);
|
||||
|
||||
config.vhead = info->vhead;
|
||||
VMOVE(config.ell_center, eip->v);
|
||||
|
||||
config.points_per_section = ell_ellipse_points(eip, info);
|
||||
config.points_per_section = ell_ellipse_points(eip, point_spacing);
|
||||
|
||||
if (config.points_per_section < 4) {
|
||||
RT_ADD_VLIST(info->vhead, eip->v, BN_VLIST_POINT_DRAW);
|
||||
|
||||
@@ -795,7 +795,7 @@ epa_plot_parabola(
|
||||
static int
|
||||
epa_curve_points(
|
||||
const struct rt_epa_internal *epa,
|
||||
const struct rt_view_info *info)
|
||||
fastf_t point_spacing)
|
||||
{
|
||||
fastf_t avg_r, approx_curve_len;
|
||||
point_t p1, p2;
|
||||
@@ -807,20 +807,20 @@ epa_curve_points(
|
||||
|
||||
approx_curve_len = 2.0 * DIST_PNT_PNT(p1, p2);
|
||||
|
||||
return approx_curve_len / info->point_spacing;
|
||||
return approx_curve_len / point_spacing;
|
||||
}
|
||||
|
||||
static int
|
||||
epa_ellipse_points(
|
||||
struct rt_epa_internal *epa,
|
||||
const struct rt_view_info *info)
|
||||
fastf_t point_spacing)
|
||||
{
|
||||
fastf_t avg_radius, avg_circumference;
|
||||
|
||||
avg_radius = (epa->epa_r1 + epa->epa_r2) / 2.0;
|
||||
avg_circumference = M_2PI * avg_radius;
|
||||
|
||||
return avg_circumference / info->point_spacing;
|
||||
return avg_circumference / point_spacing;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -840,13 +840,15 @@ rt_epa_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
return -2;
|
||||
}
|
||||
|
||||
num_curve_points = epa_curve_points(epa, info);
|
||||
fastf_t point_spacing = solid_point_spacing(info->v, info->s_size);
|
||||
|
||||
num_curve_points = epa_curve_points(epa, point_spacing);
|
||||
|
||||
if (num_curve_points < 3) {
|
||||
num_curve_points = 3;
|
||||
}
|
||||
|
||||
num_ellipse_points = epa_ellipse_points(epa, info);
|
||||
num_ellipse_points = epa_ellipse_points(epa, point_spacing);
|
||||
|
||||
if (num_ellipse_points < 6) {
|
||||
num_ellipse_points = 6;
|
||||
|
||||
@@ -895,14 +895,14 @@ static int
|
||||
eto_ellipse_points(
|
||||
vect_t ellipse_A,
|
||||
vect_t ellipse_B,
|
||||
const struct rt_view_info *info)
|
||||
fastf_t point_spacing)
|
||||
{
|
||||
fastf_t avg_radius, circumference;
|
||||
|
||||
avg_radius = (MAGNITUDE(ellipse_A) + MAGNITUDE(ellipse_B)) / 2.0;
|
||||
circumference = M_2PI * avg_radius;
|
||||
|
||||
return circumference / info->point_spacing;
|
||||
return circumference / point_spacing;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -923,6 +923,8 @@ rt_eto_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fastf_t point_spacing = solid_point_spacing(info->v, info->s_size);
|
||||
|
||||
VMOVE(eto_V, eto->eto_V);
|
||||
|
||||
VMOVE(eto_N, eto->eto_N);
|
||||
@@ -973,7 +975,7 @@ rt_eto_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
/* plot elliptical contour showing extent of ellipse +A/-A */
|
||||
eto_contour_axes(contour_A, contour_B, eto_A, eto_B, mag_ai);
|
||||
|
||||
points_per_ellipse = eto_ellipse_points(contour_A, contour_B, info);
|
||||
points_per_ellipse = eto_ellipse_points(contour_A, contour_B, point_spacing);
|
||||
|
||||
if (points_per_ellipse < 6) {
|
||||
points_per_ellipse = 6;
|
||||
@@ -989,7 +991,7 @@ rt_eto_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
/* plot elliptical contour showing extent of ellipse +B/-B */
|
||||
eto_contour_axes(contour_A, contour_B, eto_A, eto_B, mag_bi);
|
||||
|
||||
points_per_ellipse = eto_ellipse_points(contour_A, contour_B, info);
|
||||
points_per_ellipse = eto_ellipse_points(contour_A, contour_B, point_spacing);
|
||||
|
||||
if (points_per_ellipse < 6) {
|
||||
points_per_ellipse = 6;
|
||||
@@ -1009,7 +1011,7 @@ rt_eto_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
num_cross_sections = 3;
|
||||
}
|
||||
|
||||
points_per_ellipse = eto_ellipse_points(eto_A, eto_B, info);
|
||||
points_per_ellipse = eto_ellipse_points(eto_A, eto_B, point_spacing);
|
||||
|
||||
if (points_per_ellipse < 6) {
|
||||
points_per_ellipse = 6;
|
||||
|
||||
@@ -1822,11 +1822,11 @@ rt_pipe_free(struct soltab *stp)
|
||||
|
||||
|
||||
static int
|
||||
pipe_circle_segments(const struct rt_view_info *info, fastf_t radius)
|
||||
pipe_circle_segments(fastf_t point_spacing, fastf_t radius)
|
||||
{
|
||||
int num_segments;
|
||||
|
||||
num_segments = M_2PI * radius / info->point_spacing;
|
||||
num_segments = M_2PI * radius / point_spacing;
|
||||
|
||||
if (num_segments < 5) {
|
||||
num_segments = 5;
|
||||
@@ -1838,14 +1838,14 @@ pipe_circle_segments(const struct rt_view_info *info, fastf_t radius)
|
||||
|
||||
static int
|
||||
pipe_bend_segments(
|
||||
const struct rt_view_info *info,
|
||||
fastf_t point_spacing,
|
||||
const struct pipe_bend *bend)
|
||||
{
|
||||
int num_segments;
|
||||
fastf_t arc_length;
|
||||
|
||||
arc_length = (bend->bend_angle * M_1_2PI) * bend->bend_circle.radius;
|
||||
num_segments = arc_length / info->point_spacing;
|
||||
num_segments = arc_length / point_spacing;
|
||||
|
||||
if (num_segments < 3) {
|
||||
num_segments = 3;
|
||||
@@ -2206,7 +2206,7 @@ static void
|
||||
draw_pipe_circular_seg_adaptive(
|
||||
struct bu_list *vhead,
|
||||
struct pipe_segment *seg,
|
||||
const struct rt_view_info *info)
|
||||
fastf_t point_spacing)
|
||||
{
|
||||
int num_segments;
|
||||
struct pipe_bend bend;
|
||||
@@ -2230,13 +2230,13 @@ draw_pipe_circular_seg_adaptive(
|
||||
|
||||
/* draw circular bend */
|
||||
bend.pipe_circle.radius = curpt->pp_od / 2.0;
|
||||
num_segments = pipe_bend_segments(info, &bend);
|
||||
num_segments = pipe_bend_segments(point_spacing, &bend);
|
||||
seg->orient = draw_pipe_connect_circular_segs(vhead, &bend,
|
||||
seg->connecting_arcs, num_segments);
|
||||
|
||||
if (prevpt->pp_id > 0.0 && curpt->pp_id > 0.0) {
|
||||
bend.pipe_circle.radius = curpt->pp_id / 2.0;
|
||||
num_segments = pipe_bend_segments(info, &bend);
|
||||
num_segments = pipe_bend_segments(point_spacing, &bend);
|
||||
seg->orient = draw_pipe_connect_circular_segs(vhead, &bend,
|
||||
seg->connecting_arcs, num_segments);
|
||||
}
|
||||
@@ -2274,7 +2274,7 @@ static void
|
||||
draw_pipe_end_adaptive(
|
||||
struct bu_list *vhead,
|
||||
struct pipe_segment *seg,
|
||||
const struct rt_view_info *info)
|
||||
fastf_t point_spacing)
|
||||
{
|
||||
int num_segments;
|
||||
struct wdb_pipe_pnt *endpt;
|
||||
@@ -2287,13 +2287,13 @@ draw_pipe_end_adaptive(
|
||||
|
||||
/* draw outer circle */
|
||||
pipe_circle.radius = endpt->pp_od / 2.0;
|
||||
num_segments = pipe_circle_segments(info, pipe_circle.radius);
|
||||
num_segments = pipe_circle_segments(point_spacing, pipe_circle.radius);
|
||||
draw_pipe_circle(vhead, &pipe_circle, num_segments);
|
||||
|
||||
/* draw inner circle */
|
||||
if (endpt->pp_id > 0.0) {
|
||||
pipe_circle.radius = endpt->pp_id / 2.0;
|
||||
num_segments = pipe_circle_segments(info, pipe_circle.radius);
|
||||
num_segments = pipe_circle_segments(point_spacing, pipe_circle.radius);
|
||||
draw_pipe_circle(vhead, &pipe_circle, num_segments);
|
||||
}
|
||||
|
||||
@@ -2319,14 +2319,16 @@ rt_pipe_adaptive_plot(
|
||||
return 0;
|
||||
}
|
||||
|
||||
fastf_t point_spacing = solid_point_spacing(info->v, info->s_size);
|
||||
|
||||
cur_seg->connecting_arcs = pipe_connecting_arcs(pipeobj, info);
|
||||
|
||||
draw_pipe_end_adaptive(info->vhead, cur_seg, info);
|
||||
draw_pipe_end_adaptive(info->vhead, cur_seg, point_spacing);
|
||||
pipe_seg_advance(cur_seg);
|
||||
|
||||
while (!pipe_seg_is_last(cur_seg)) {
|
||||
if (pipe_seg_is_bend(cur_seg)) {
|
||||
draw_pipe_circular_seg_adaptive(info->vhead, cur_seg, info);
|
||||
draw_pipe_circular_seg_adaptive(info->vhead, cur_seg, point_spacing);
|
||||
} else {
|
||||
draw_pipe_linear_seg(info->vhead, cur_seg);
|
||||
}
|
||||
@@ -2335,7 +2337,7 @@ rt_pipe_adaptive_plot(
|
||||
}
|
||||
|
||||
draw_pipe_linear_seg(info->vhead, cur_seg);
|
||||
draw_pipe_end_adaptive(info->vhead, cur_seg, info);
|
||||
draw_pipe_end_adaptive(info->vhead, cur_seg, point_spacing);
|
||||
|
||||
BU_PUT(cur_seg, struct pipe_segment);
|
||||
|
||||
|
||||
@@ -111,7 +111,8 @@ primitive_diagonal_samples(
|
||||
ip->idb_meth->ft_bbox(ip, &bbox_min, &bbox_max, info->tol);
|
||||
primitive_diagonal_mm = DIST_PNT_PNT(bbox_min, bbox_max);
|
||||
|
||||
samples_per_mm = 1.0 / info->point_spacing;
|
||||
fastf_t point_spacing = solid_point_spacing(info->v, info->s_size);
|
||||
samples_per_mm = 1.0 / point_spacing;
|
||||
diagonal_samples = samples_per_mm * primitive_diagonal_mm;
|
||||
|
||||
return diagonal_samples;
|
||||
|
||||
@@ -926,7 +926,7 @@ rhc_plot_curve_connections(
|
||||
static int
|
||||
rhc_curve_points(
|
||||
struct rt_rhc_internal *rhc,
|
||||
const struct rt_view_info *info)
|
||||
fastf_t point_spacing)
|
||||
{
|
||||
fastf_t height, halfwidth, est_curve_length;
|
||||
point_t p0, p1;
|
||||
@@ -939,7 +939,7 @@ rhc_curve_points(
|
||||
|
||||
est_curve_length = 2.0 * DIST_PNT_PNT(p0, p1);
|
||||
|
||||
return est_curve_length / info->point_spacing;
|
||||
return est_curve_length / point_spacing;
|
||||
}
|
||||
|
||||
|
||||
@@ -960,7 +960,9 @@ rt_rhc_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
return -2;
|
||||
}
|
||||
|
||||
num_curve_points = rhc_curve_points(rhc, info);
|
||||
fastf_t point_spacing = solid_point_spacing(info->v, info->s_size);
|
||||
|
||||
num_curve_points = rhc_curve_points(rhc, point_spacing);
|
||||
|
||||
if (num_curve_points < 3) {
|
||||
num_curve_points = 3;
|
||||
|
||||
@@ -845,7 +845,7 @@ rpc_plot_curve_connections(
|
||||
static int
|
||||
rpc_curve_points(
|
||||
struct rt_rpc_internal *rpc,
|
||||
const struct rt_view_info *info)
|
||||
fastf_t point_spacing)
|
||||
{
|
||||
fastf_t height, halfwidth, est_curve_length;
|
||||
point_t p0, p1;
|
||||
@@ -858,7 +858,7 @@ rpc_curve_points(
|
||||
|
||||
est_curve_length = 2.0 * DIST_PNT_PNT(p0, p1);
|
||||
|
||||
return est_curve_length / info->point_spacing;
|
||||
return est_curve_length / point_spacing;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -878,7 +878,8 @@ rt_rpc_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
return -2;
|
||||
}
|
||||
|
||||
num_curve_points = rpc_curve_points(rpc, info);
|
||||
fastf_t point_spacing = solid_point_spacing(info->v, info->s_size);
|
||||
num_curve_points = rpc_curve_points(rpc, point_spacing);
|
||||
|
||||
if (num_curve_points < 3) {
|
||||
num_curve_points = 3;
|
||||
|
||||
@@ -1931,7 +1931,7 @@ draw_lines_between_ellipses(
|
||||
|
||||
|
||||
static int
|
||||
tgc_points_per_ellipse(const struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
tgc_points_per_ellipse(const struct rt_db_internal *ip, fastf_t point_spacing)
|
||||
{
|
||||
struct rt_tgc_internal *tgc;
|
||||
fastf_t avg_radius, avg_circumference;
|
||||
@@ -1949,7 +1949,7 @@ tgc_points_per_ellipse(const struct rt_db_internal *ip, const struct rt_view_inf
|
||||
avg_radius = (tgc_mag_a + tgc_mag_b + tgc_mag_c + tgc_mag_d) / 4.0;
|
||||
avg_circumference = M_2PI * avg_radius;
|
||||
|
||||
return avg_circumference / info->point_spacing;
|
||||
return avg_circumference / point_spacing;
|
||||
}
|
||||
|
||||
|
||||
@@ -1988,13 +1988,24 @@ rt_tgc_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
int points_per_ellipse, connecting_lines;
|
||||
struct rt_tgc_internal *tip;
|
||||
struct ellipse ellipse1, ellipse2;
|
||||
fastf_t point_spacing;
|
||||
fastf_t avg_diameter;
|
||||
fastf_t tgc_mag_a, tgc_mag_b, tgc_mag_c, tgc_mag_d;
|
||||
|
||||
BU_CK_LIST_HEAD(info->vhead);
|
||||
RT_CK_DB_INTERNAL(ip);
|
||||
tip = (struct rt_tgc_internal *)ip->idb_ptr;
|
||||
RT_TGC_CK_MAGIC(tip);
|
||||
|
||||
points_per_ellipse = tgc_points_per_ellipse(ip, info);
|
||||
tgc_mag_a = MAGNITUDE(tip->a);
|
||||
tgc_mag_b = MAGNITUDE(tip->b);
|
||||
tgc_mag_c = MAGNITUDE(tip->c);
|
||||
tgc_mag_d = MAGNITUDE(tip->d);
|
||||
avg_diameter = tgc_mag_a + tgc_mag_b + tgc_mag_c + tgc_mag_d;
|
||||
avg_diameter /= 2.0;
|
||||
point_spacing = solid_point_spacing(info->v, avg_diameter);
|
||||
|
||||
points_per_ellipse = tgc_points_per_ellipse(ip, point_spacing);
|
||||
|
||||
if (points_per_ellipse < 6) {
|
||||
point_t p;
|
||||
|
||||
@@ -1009,14 +1009,14 @@ static int
|
||||
tor_ellipse_points(
|
||||
vect_t ellipse_A,
|
||||
vect_t ellipse_B,
|
||||
const struct rt_view_info *info)
|
||||
fastf_t point_spacing)
|
||||
{
|
||||
fastf_t avg_radius, circumference;
|
||||
|
||||
avg_radius = (MAGNITUDE(ellipse_A) + MAGNITUDE(ellipse_B)) / 2.0;
|
||||
circumference = M_2PI * avg_radius;
|
||||
|
||||
return circumference / info->point_spacing;
|
||||
return circumference / point_spacing;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1033,6 +1033,8 @@ rt_tor_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
tor = (struct rt_tor_internal *)ip->idb_ptr;
|
||||
RT_TOR_CK_MAGIC(tor);
|
||||
|
||||
fastf_t point_spacing = solid_point_spacing(info->v, info->s_size);
|
||||
|
||||
VMOVE(tor_a, tor->a);
|
||||
mag_a = tor->r_a;
|
||||
|
||||
@@ -1048,7 +1050,7 @@ rt_tor_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
VJOIN1(a, tor_a, mag_h / mag_a, tor_a);
|
||||
VJOIN1(b, tor_b, mag_h / mag_b, tor_b);
|
||||
|
||||
points_per_ellipse = tor_ellipse_points(a, b, info);
|
||||
points_per_ellipse = tor_ellipse_points(a, b, point_spacing);
|
||||
if (points_per_ellipse < 6) {
|
||||
points_per_ellipse = 6;
|
||||
}
|
||||
@@ -1059,7 +1061,7 @@ rt_tor_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
VJOIN1(a, tor_a, -1.0 * mag_h / mag_a, tor_a);
|
||||
VJOIN1(b, tor_b, -1.0 * mag_h / mag_b, tor_b);
|
||||
|
||||
points_per_ellipse = tor_ellipse_points(a, b, info);
|
||||
points_per_ellipse = tor_ellipse_points(a, b, point_spacing);
|
||||
if (points_per_ellipse < 6) {
|
||||
points_per_ellipse = 6;
|
||||
}
|
||||
@@ -1069,7 +1071,7 @@ rt_tor_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info)
|
||||
/* Draw parallel circles to show the primitive's most extreme points along
|
||||
* +h/-h.
|
||||
*/
|
||||
points_per_ellipse = tor_ellipse_points(tor_a, tor_b, info);
|
||||
points_per_ellipse = tor_ellipse_points(tor_a, tor_b, point_spacing);
|
||||
if (points_per_ellipse < 6) {
|
||||
points_per_ellipse = 6;
|
||||
}
|
||||
|
||||
@@ -28,47 +28,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "brep.h"
|
||||
#include "bview.h"
|
||||
|
||||
#include "rt/db5.h"
|
||||
#include "rt/db_internal.h"
|
||||
#include "rt/geom.h"
|
||||
#include "rt/view.h"
|
||||
|
||||
static fastf_t
|
||||
brep_avg_curve_bbox_diagonal_len(ON_Brep *brep)
|
||||
{
|
||||
fastf_t avg_curve_len = 0.0;
|
||||
int i, num_curves = 0;
|
||||
|
||||
for (i = 0; i < brep->m_E.Count(); ++i) {
|
||||
ON_BrepEdge &e = brep->m_E[i];
|
||||
const ON_Curve *crv = e.EdgeCurveOf();
|
||||
|
||||
if (!crv->IsLinear()) {
|
||||
++num_curves;
|
||||
|
||||
ON_BoundingBox bbox;
|
||||
if (crv->GetTightBoundingBox(bbox)) {
|
||||
avg_curve_len += bbox.Diagonal().Length();
|
||||
} else {
|
||||
ON_3dVector linear_approx =
|
||||
crv->PointAtEnd() - crv->PointAtStart();
|
||||
avg_curve_len += linear_approx.Length();
|
||||
}
|
||||
}
|
||||
}
|
||||
avg_curve_len /= num_curves;
|
||||
|
||||
return avg_curve_len;
|
||||
}
|
||||
|
||||
static fastf_t
|
||||
brep_est_avg_curve_len(struct rt_brep_internal *bi)
|
||||
{
|
||||
return brep_avg_curve_bbox_diagonal_len(bi->brep) * 2.0;
|
||||
}
|
||||
#include "librt_private.h"
|
||||
|
||||
static fastf_t
|
||||
view_avg_size(struct bview *gvp)
|
||||
@@ -82,7 +43,7 @@ view_avg_size(struct bview *gvp)
|
||||
return (x_size + y_size) / 2.0;
|
||||
}
|
||||
|
||||
static fastf_t
|
||||
fastf_t
|
||||
view_avg_sample_spacing(struct bview *gvp)
|
||||
{
|
||||
fastf_t avg_view_size, avg_view_samples;
|
||||
@@ -93,14 +54,14 @@ view_avg_sample_spacing(struct bview *gvp)
|
||||
return avg_view_size / avg_view_samples;
|
||||
}
|
||||
|
||||
static fastf_t
|
||||
fastf_t
|
||||
solid_point_spacing(struct bview *gvp, fastf_t solid_width)
|
||||
{
|
||||
fastf_t radius, avg_view_size, avg_sample_spacing;
|
||||
point2d_t p1, p2;
|
||||
|
||||
if (solid_width < SQRT_SMALL_FASTF)
|
||||
solid_width = SQRT_SMALL_FASTF;
|
||||
solid_width = SQRT_SMALL_FASTF;
|
||||
|
||||
avg_view_size = view_avg_size(gvp);
|
||||
|
||||
@@ -112,12 +73,12 @@ solid_point_spacing(struct bview *gvp, fastf_t solid_width)
|
||||
*/
|
||||
radius = solid_width / 4.0;
|
||||
if (avg_view_size < solid_width) {
|
||||
/* If the solid is larger than the view, it is
|
||||
* probably only partly visible and likely isn't the
|
||||
* primary focus of the user. We'll cap the point
|
||||
* spacing and avoid wasting effort.
|
||||
*/
|
||||
radius = avg_view_size / 4.0;
|
||||
/* If the solid is larger than the view, it is
|
||||
* probably only partly visible and likely isn't the
|
||||
* primary focus of the user. We'll cap the point
|
||||
* spacing and avoid wasting effort.
|
||||
*/
|
||||
radius = avg_view_size / 4.0;
|
||||
}
|
||||
|
||||
/* We imagine our representative circular curve lying in
|
||||
@@ -145,18 +106,18 @@ solid_point_spacing(struct bview *gvp, fastf_t solid_width)
|
||||
* curve which will give a perfect rasterization, i.e.
|
||||
* the same rasterization as if we chose a point distance
|
||||
* of 0.
|
||||
*/
|
||||
*/
|
||||
p1[Y] = radius;
|
||||
p1[X] = 0.0;
|
||||
|
||||
avg_sample_spacing = view_avg_sample_spacing(gvp);
|
||||
if (avg_sample_spacing < radius) {
|
||||
p2[Y] = radius - (avg_sample_spacing);
|
||||
p2[Y] = radius - (avg_sample_spacing);
|
||||
} else {
|
||||
/* no particular reason other than symmetry, just need
|
||||
* to prevent sqrt(negative).
|
||||
*/
|
||||
p2[Y] = radius;
|
||||
/* no particular reason other than symmetry, just need
|
||||
* to prevent sqrt(negative).
|
||||
*/
|
||||
p2[Y] = radius;
|
||||
}
|
||||
p2[X] = sqrt((radius * radius) - (p2[Y] * p2[Y]));
|
||||
|
||||
@@ -164,70 +125,12 @@ solid_point_spacing(struct bview *gvp, fastf_t solid_width)
|
||||
}
|
||||
|
||||
|
||||
/* TODO: view_avg_sample_spacing() might be sufficient if we can
|
||||
* develop a general decimation routine for the resulting plots, in
|
||||
* which case, this function could be removed.
|
||||
/*
|
||||
* Local Variables:
|
||||
* tab-width: 8
|
||||
* mode: C
|
||||
* indent-tabs-mode: t
|
||||
* c-file-style: "stroustrup"
|
||||
* End:
|
||||
* ex: shiftwidth=4 tabstop=8
|
||||
*/
|
||||
extern "C" fastf_t
|
||||
rt_solid_point_spacing_for_view(
|
||||
struct rt_db_internal *ip,
|
||||
struct rt_view_info *vi
|
||||
)
|
||||
{
|
||||
fastf_t point_spacing = 0.0;
|
||||
|
||||
if (ip->idb_major_type == DB5_MAJORTYPE_BRLCAD) {
|
||||
switch (ip->idb_minor_type) {
|
||||
case DB5_MINORTYPE_BRLCAD_TGC: {
|
||||
struct rt_tgc_internal *tgc;
|
||||
fastf_t avg_diameter;
|
||||
fastf_t tgc_mag_a, tgc_mag_b, tgc_mag_c, tgc_mag_d;
|
||||
|
||||
RT_CK_DB_INTERNAL(ip);
|
||||
tgc = (struct rt_tgc_internal *)ip->idb_ptr;
|
||||
RT_TGC_CK_MAGIC(tgc);
|
||||
|
||||
tgc_mag_a = MAGNITUDE(tgc->a);
|
||||
tgc_mag_b = MAGNITUDE(tgc->b);
|
||||
tgc_mag_c = MAGNITUDE(tgc->c);
|
||||
tgc_mag_d = MAGNITUDE(tgc->d);
|
||||
|
||||
avg_diameter = tgc_mag_a + tgc_mag_b + tgc_mag_c + tgc_mag_d;
|
||||
avg_diameter /= 2.0;
|
||||
point_spacing = solid_point_spacing(vi->v, avg_diameter);
|
||||
}
|
||||
break;
|
||||
case DB5_MINORTYPE_BRLCAD_BOT:
|
||||
point_spacing = view_avg_sample_spacing(vi->v);
|
||||
break;
|
||||
case DB5_MINORTYPE_BRLCAD_BREP: {
|
||||
struct rt_brep_internal *bi;
|
||||
|
||||
RT_CK_DB_INTERNAL(ip);
|
||||
bi = (struct rt_brep_internal *)ip->idb_ptr;
|
||||
RT_BREP_CK_MAGIC(bi);
|
||||
|
||||
point_spacing = solid_point_spacing(vi->v,
|
||||
brep_est_avg_curve_len(bi) * M_2_PI * 2.0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
point_spacing = solid_point_spacing(vi->v, vi->s_size);
|
||||
}
|
||||
} else {
|
||||
point_spacing = solid_point_spacing(vi->v, vi->s_size);
|
||||
}
|
||||
|
||||
return point_spacing;
|
||||
}
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// tab-width: 8
|
||||
// mode: C++
|
||||
// c-basic-offset: 4
|
||||
// indent-tabs-mode: t
|
||||
// c-file-style: "stroustrup"
|
||||
// End:
|
||||
// ex: shiftwidth=4 tabstop=8
|
||||
|
||||
Reference in new issue
Block a user