Revision: 73176
http://sourceforge.net/p/brlcad/code/73176
Author: starseeker
Date: 2019-05-24 18:44:16 +0000 (Fri, 24 May 2019)
Log Message:
-----------
Start experimenting with a more 'edge aware' surface point generation. Not
ready for primetime yet, but looking promising.
Modified Paths:
--------------
brlcad/trunk/src/libbrep/cdt.cpp
brlcad/trunk/src/libbrep/cdt.h
brlcad/trunk/src/libbrep/cdt_surf.cpp
Modified: brlcad/trunk/src/libbrep/cdt.cpp
===================================================================
--- brlcad/trunk/src/libbrep/cdt.cpp 2019-05-24 17:17:17 UTC (rev 73175)
+++ brlcad/trunk/src/libbrep/cdt.cpp 2019-05-24 18:44:16 UTC (rev 73176)
@@ -278,7 +278,7 @@
// Sample the surface, independent of the trimming curves, to get points
that
// will tie the mesh to the interior surface.
- getSurfacePoints(s_cdt, face, on_surf_points);
+ getSurfacePoints(s_cdt, face, on_surf_points, &rt_trims);
// Strip out points from the surface that are on the trimming curves. Trim
// points require special handling for watertightness and introducing them
Modified: brlcad/trunk/src/libbrep/cdt.h
===================================================================
--- brlcad/trunk/src/libbrep/cdt.h 2019-05-24 17:17:17 UTC (rev 73175)
+++ brlcad/trunk/src/libbrep/cdt.h 2019-05-24 18:44:16 UTC (rev 73176)
@@ -139,6 +139,7 @@
struct cdt_surf_info {
const ON_Surface *s;
const ON_BrepFace *f;
+ ON_RTree *rt_trims;
std::map<int, std::map<int,ON_3dPoint *>> *strim_pnts;
std::map<int, std::map<int,ON_3dPoint *>> *strim_norms;
double u1, u2, v1, v2;
@@ -174,7 +175,8 @@
void
getSurfacePoints(struct ON_Brep_CDT_State *s_cdt,
const ON_BrepFace &face,
- ON_2dPointArray &on_surf_points);
+ ON_2dPointArray &on_surf_points,
+ ON_RTree *rt_trims);
void
plot_polyline(std::vector<p2t::Point *> *pnts, const char *filename);
Modified: brlcad/trunk/src/libbrep/cdt_surf.cpp
===================================================================
--- brlcad/trunk/src/libbrep/cdt_surf.cpp 2019-05-24 17:17:17 UTC (rev
73175)
+++ brlcad/trunk/src/libbrep/cdt_surf.cpp 2019-05-24 18:44:16 UTC (rev
73176)
@@ -125,6 +125,26 @@
return NULL;
}
+/* If we've got trimming curves involved, we need to be more careful about
respecting
+ * the min edge distance.
+ *
+ * TODO - rather than blanket assuming the min edge distance, we should go one
+ * better and find the min edge segment length for the involved edge segments.
+ * This approach generates too many unnecessary triangles and is actually a
+ * problem when a globally fine edge seg forces the surface to be fine at a
+ * course edge. */
+bool involves_trims(struct cdt_surf_info *sinfo, fastf_t u1, fastf_t u2,
fastf_t v1, fastf_t v2)
+{
+ ON_SimpleArray<void*> results;
+ ON_2dPoint pmin(u1, v1);
+ ON_2dPoint pmax(u2, v2);
+ sinfo->rt_trims->Search2d((const double *) &pmin, (const double *) &pmax,
results);
+ return (results.Count() > 0);
+}
+
+/* The "left" and "below" parameters tell this particular iteration of the
subdivision
+ * which UV points should be stored. This bookkeeping is done to avoid
introducing
+ * duplicated points at shared subdivision edges. */
static void
getSurfacePoints(
struct ON_Brep_CDT_State *s_cdt,
@@ -141,11 +161,9 @@
bool below)
{
double ldfactor = 2.0;
+ int split_u = 0;
+ int split_v = 0;
ON_2dPoint p2d(0.0, 0.0);
- ON_3dPoint p[4] = {ON_3dPoint(), ON_3dPoint(), ON_3dPoint(), ON_3dPoint()};
- ON_3dVector norm[4] = {ON_3dVector(), ON_3dVector(), ON_3dVector(),
ON_3dVector()};
- ON_3dPoint mid(0.0, 0.0, 0.0);
- ON_3dVector norm_mid(0.0, 0.0, 0.0);
fastf_t u = (u1 + u2) / 2.0;
fastf_t v = (v1 + v2) / 2.0;
fastf_t udist = u2 - u1;
@@ -156,131 +174,6 @@
return;
}
- if (udist > ldfactor * vdist) {
- int isteps = (int)(udist / vdist);
- isteps = (int)(udist / vdist / ldfactor * 2.0);
- fastf_t step = udist / (fastf_t) isteps;
-
- //bu_log("split: udist > ldfactor * vdist\n");
-
- fastf_t step_u;
- for (int i = 1; i <= isteps; i++) {
- step_u = u1 + i * step;
- if ((below) && (i < isteps)) {
- p2d.Set(step_u, v1);
- on_surf_points.Append(p2d);
- }
- if (i == 1) {
-
- // Check the distance between v1 and v2 at u1 && u1+step.
- // If they're both less than threshold, skip
- double est1 = vline_len_est(sinfo, u1, v1, v2);
- double est2 = vline_len_est(sinfo, u1+step, v1, v2);
- if (est1 < min_dist && est2 < min_dist) {
- //bu_log("Small estimates: %f, %f\n", est1, est2);
- continue;
- }
-
- getSurfacePoints(s_cdt, sinfo, u1, u1 + step, v1, v2, min_dist,
- within_dist, cos_within_ang, on_surf_points, left,
- below);
- } else if (i == isteps) {
-
- // Check the distance between v1 and v2 at u2-step && u2
- // If they're both less than threshold, skip
- double est1 = vline_len_est(sinfo, u2-step, v1, v2);
- double est2 = vline_len_est(sinfo, u2, v1, v2);
- if (est1 < min_dist && est2 < min_dist) {
- //bu_log("Small estimates: %f, %f\n", est1, est2);
- continue;
- }
-
- getSurfacePoints(s_cdt, sinfo, u2 - step, u2, v1, v2, min_dist,
- within_dist, cos_within_ang, on_surf_points, left,
- below);
- } else {
- // Check the distance between v1 and v2 at step_u - step and
step_u
- // If they're both less than threshold, skip
- double est1 = vline_len_est(sinfo, step_u - step, v1, v2);
- double est2 = vline_len_est(sinfo, step_u, v1, v2);
- if (est1 < min_dist && est2 < min_dist) {
- //bu_log("Small estimates: %f, %f\n", est1, est2);
- continue;
- }
-
- getSurfacePoints(s_cdt, sinfo, step_u - step, step_u, v1, v2,
min_dist, within_dist,
- cos_within_ang, on_surf_points, left, below);
- }
- left = false;
-
- if (i < isteps) {
- //top
- p2d.Set(step_u, v2);
- on_surf_points.Append(p2d);
- }
- }
- return;
- }
- if (vdist > ldfactor * udist) {
- int isteps = (int)(vdist / udist);
- isteps = (int)(vdist / udist / ldfactor * 2.0);
- fastf_t step = vdist / (fastf_t) isteps;
- fastf_t step_v;
-
- //bu_log("split: vdist > ldfactor * udist\n");
-
- for (int i = 1; i <= isteps; i++) {
- step_v = v1 + i * step;
- if ((left) && (i < isteps)) {
- p2d.Set(u1, step_v);
- on_surf_points.Append(p2d);
- }
-
- if (i == 1) {
- double est1 = uline_len_est(sinfo, u1, u2, v1);
- double est2 = uline_len_est(sinfo, u1, u2, v1 + step);
- if (est1 < min_dist && est2 < min_dist) {
- //bu_log("Small estimates: %f, %f\n", est1, est2);
- continue;
- }
-
- getSurfacePoints(s_cdt, sinfo, u1, u2, v1, v1 + step, min_dist,
- within_dist, cos_within_ang, on_surf_points, left,
- below);
- } else if (i == isteps) {
- double est1 = uline_len_est(sinfo, u1, u2, v2 - step);
- double est2 = uline_len_est(sinfo, u1, u2, v2);
- if (est1 < min_dist && est2 < min_dist) {
- //bu_log("Small estimates: %f, %f\n", est1, est2);
- continue;
- }
-
- getSurfacePoints(s_cdt, sinfo, u1, u2, v2 - step, v2, min_dist,
- within_dist, cos_within_ang, on_surf_points, left,
- below);
- } else {
- double est1 = uline_len_est(sinfo, u1, u2, step_v - step);
- double est2 = uline_len_est(sinfo, u1, u2, step_v);
- if (est1 < min_dist && est2 < min_dist) {
- //bu_log("Small estimates: %f, %f\n", est1, est2);
- continue;
- }
-
- getSurfacePoints(s_cdt, sinfo, u1, u2, step_v - step, step_v,
min_dist, within_dist,
- cos_within_ang, on_surf_points, left, below);
- }
-
- below = false;
-
- if (i < isteps) {
- //right
- p2d.Set(u2, step_v);
- on_surf_points.Append(p2d);
- }
- }
- return;
- }
-
double est1 = uline_len_est(sinfo, u1, u2, v1);
double est2 = uline_len_est(sinfo, u1, u2, v2);
double est3 = vline_len_est(sinfo, u1, v1, v2);
@@ -296,115 +189,76 @@
return;
}
- if ((surface_EvNormal(sinfo->s, u1, v1, p[0], norm[0]))
- && (surface_EvNormal(sinfo->s, u2, v1, p[1], norm[1])) // for u
- && (surface_EvNormal(sinfo->s, u2, v2, p[2], norm[2]))
- && (surface_EvNormal(sinfo->s, u1, v2, p[3], norm[3]))
- && (surface_EvNormal(sinfo->s, u, v, mid, norm_mid))) {
- double udot;
- double vdot;
- ON_Line line1(p[0], p[2]);
- ON_Line line2(p[1], p[3]);
- double dist = mid.DistanceTo(line1.ClosestPointTo(mid));
- V_MAX(dist, mid.DistanceTo(line2.ClosestPointTo(mid)));
+ if (udist > ldfactor * vdist) {
+ split_u = 1;
+ }
+ if (vdist > ldfactor * udist) {
+ split_v = 1;
+ }
- for (int i = 0; i < 4; i++) {
- fastf_t uc = (i == 0 || i == 3) ? u1 : u2;
- fastf_t vc = (i == 0 || i == 1) ? v1 : v2;
- ON_3dPoint *vnorm = singular_trim_norm(sinfo, uc, vc);
- if (vnorm && ON_DotProduct(*vnorm, norm_mid) > 0) {
- //bu_log("vert norm %f %f %f works\n", vnorm->x, vnorm->y,
vnorm->z);
- norm[i] = *vnorm;
+ if (!split_u || !split_v) {
+ // Don't know if we're splitting in at least one direction - check if
we're close
+ // enough to trims to need to worry about edges
+ if (involves_trims(sinfo, u1, u2, v1, v2)) {
+ if (est1 > 2*(*s_cdt->min_edge_seg_len)[sinfo->f->m_face_index] ||
est2 > 2*(*s_cdt->min_edge_seg_len)[sinfo->f->m_face_index]) {
+ split_u = 1;
}
+
+ if (est3 > 2*(*s_cdt->min_edge_seg_len)[sinfo->f->m_face_index] ||
est4 > 2*(*s_cdt->min_edge_seg_len)[sinfo->f->m_face_index]) {
+ split_v = 1;
+ }
}
-#if 0
- for (int i = 0; i < 4; i++) {
- double nnm_dot = ON_DotProduct(norm[i], norm_mid);
- if ((nnm_dot < ON_ZERO_TOLERANCE) && (fabs(nnm_dot) >
ON_ZERO_TOLERANCE)) {
+ }
+
+
+ if (!split_u || !split_v) {
+ // Don't know if we're splitting in at least one direction - check dot
products
+ ON_3dPoint mid(0.0, 0.0, 0.0);
+ ON_3dVector norm_mid(0.0, 0.0, 0.0);
+ ON_3dPoint p[4] = {ON_3dPoint(), ON_3dPoint(), ON_3dPoint(),
ON_3dPoint()};
+ ON_3dVector norm[4] = {ON_3dVector(), ON_3dVector(), ON_3dVector(),
ON_3dVector()};
+ if ((surface_EvNormal(sinfo->s, u1, v1, p[0], norm[0]))
+ && (surface_EvNormal(sinfo->s, u2, v1, p[1], norm[1])) // for u
+ && (surface_EvNormal(sinfo->s, u2, v2, p[2], norm[2]))
+ && (surface_EvNormal(sinfo->s, u1, v2, p[3], norm[3]))
+ && (surface_EvNormal(sinfo->s, u, v, mid, norm_mid))) {
+ double udot;
+ double vdot;
+ ON_Line line1(p[0], p[2]);
+ ON_Line line2(p[1], p[3]);
+ double dist = mid.DistanceTo(line1.ClosestPointTo(mid));
+ V_MAX(dist, mid.DistanceTo(line2.ClosestPointTo(mid)));
+
+
+ for (int i = 0; i < 4; i++) {
fastf_t uc = (i == 0 || i == 3) ? u1 : u2;
fastf_t vc = (i == 0 || i == 1) ? v1 : v2;
- bu_log("norm[%d](%f %f %f) backwards at %d point %f,%f (%f %f
%f)\n", i, norm[i].x, norm[i].y, norm[i].z, i, uc, vc, p[i].x, p[i].y, p[i].z);
ON_3dPoint *vnorm = singular_trim_norm(sinfo, uc, vc);
if (vnorm && ON_DotProduct(*vnorm, norm_mid) > 0) {
- bu_log("vert norm %f %f %f works\n", vnorm->x, vnorm->y,
vnorm->z);
+ //bu_log("vert norm %f %f %f works\n", vnorm->x, vnorm->y,
vnorm->z);
norm[i] = *vnorm;
- } else {
- bu_log("no matching vert normal, problem...\n");
}
}
- }
-#endif
- if (dist < min_dist + ON_ZERO_TOLERANCE) {
- return;
- }
- udot = (VNEAR_EQUAL(norm[0], norm[1], ON_ZERO_TOLERANCE)) ? 1.0 :
norm[0] * norm[1];
- vdot = (VNEAR_EQUAL(norm[0], norm[3], ON_ZERO_TOLERANCE)) ? 1.0 :
norm[0] * norm[3];
-
- if ((udot < cos_within_ang - ON_ZERO_TOLERANCE) && (vdot <
cos_within_ang - ON_ZERO_TOLERANCE)) {
- //bu_log("split: both cos_within_ang\n");
- if (left) {
- p2d.Set(u1, v);
- on_surf_points.Append(p2d);
+ if (dist < min_dist + ON_ZERO_TOLERANCE) {
+ return;
}
- if (below) {
- p2d.Set(u, v1);
- on_surf_points.Append(p2d);
- }
- //center
- p2d.Set(u, v);
- on_surf_points.Append(p2d);
- //right
- p2d.Set(u2, v);
- on_surf_points.Append(p2d);
- //top
- p2d.Set(u, v2);
- on_surf_points.Append(p2d);
- getSurfacePoints(s_cdt, sinfo, u1, u, v1, v, min_dist, within_dist,
- cos_within_ang, on_surf_points, left, below);
- getSurfacePoints(s_cdt, sinfo, u1, u, v, v2, min_dist, within_dist,
- cos_within_ang, on_surf_points, left, false);
- getSurfacePoints(s_cdt, sinfo, u, u2, v1, v, min_dist, within_dist,
- cos_within_ang, on_surf_points, false, below);
- getSurfacePoints(s_cdt, sinfo, u, u2, v, v2, min_dist, within_dist,
- cos_within_ang, on_surf_points, false, false);
- return;
- }
- if (udot < cos_within_ang - ON_ZERO_TOLERANCE) {
- //bu_log("split: udot cos_within_ang\n");
- if (below) {
- p2d.Set(u, v1);
- on_surf_points.Append(p2d);
+ udot = (VNEAR_EQUAL(norm[0], norm[1], ON_ZERO_TOLERANCE)) ? 1.0 :
norm[0] * norm[1];
+ vdot = (VNEAR_EQUAL(norm[0], norm[3], ON_ZERO_TOLERANCE)) ? 1.0 :
norm[0] * norm[3];
+ if (udot < cos_within_ang - ON_ZERO_TOLERANCE) {
+ split_u = 1;
}
- //top
- p2d.Set(u, v2);
- on_surf_points.Append(p2d);
- getSurfacePoints(s_cdt, sinfo, u1, u, v1, v2, min_dist, within_dist,
- cos_within_ang, on_surf_points, left, below);
- getSurfacePoints(s_cdt, sinfo, u, u2, v1, v2, min_dist, within_dist,
- cos_within_ang, on_surf_points, false, below);
- return;
- }
- if (vdot < cos_within_ang - ON_ZERO_TOLERANCE) {
- //bu_log("split: vdot cos_within_ang\n");
- if (left) {
- p2d.Set(u1, v);
- on_surf_points.Append(p2d);
+ if (vdot < cos_within_ang - ON_ZERO_TOLERANCE) {
+ split_v = 1;
}
- //right
- p2d.Set(u2, v);
- on_surf_points.Append(p2d);
-
- getSurfacePoints(s_cdt, sinfo, u1, u2, v1, v, min_dist, within_dist,
- cos_within_ang, on_surf_points, left, below);
- getSurfacePoints(s_cdt, sinfo, u1, u2, v, v2, min_dist, within_dist,
- cos_within_ang, on_surf_points, left, false);
- return;
}
+ }
+ if (split_u && split_v) {
+ //bu_log("split: both cos_within_ang\n");
if (left) {
p2d.Set(u1, v);
on_surf_points.Append(p2d);
@@ -423,19 +277,65 @@
p2d.Set(u, v2);
on_surf_points.Append(p2d);
- if (dist > within_dist + ON_ZERO_TOLERANCE) {
- //bu_log("split: dist(%f) > within_dist(%f)\n", dist, within_dist);
-
- getSurfacePoints(s_cdt, sinfo, u1, u, v1, v, min_dist, within_dist,
- cos_within_ang, on_surf_points, left, below);
- getSurfacePoints(s_cdt, sinfo, u1, u, v, v2, min_dist, within_dist,
- cos_within_ang, on_surf_points, left, false);
- getSurfacePoints(s_cdt, sinfo, u, u2, v1, v, min_dist, within_dist,
- cos_within_ang, on_surf_points, false, below);
- getSurfacePoints(s_cdt, sinfo, u, u2, v, v2, min_dist, within_dist,
- cos_within_ang, on_surf_points, false, false);
+ getSurfacePoints(s_cdt, sinfo, u1, u, v1, v, min_dist, within_dist,
+ cos_within_ang, on_surf_points, left, below);
+ getSurfacePoints(s_cdt, sinfo, u1, u, v, v2, min_dist, within_dist,
+ cos_within_ang, on_surf_points, left, false);
+ getSurfacePoints(s_cdt, sinfo, u, u2, v1, v, min_dist, within_dist,
+ cos_within_ang, on_surf_points, false, below);
+ getSurfacePoints(s_cdt, sinfo, u, u2, v, v2, min_dist, within_dist,
+ cos_within_ang, on_surf_points, false, false);
+ return;
+ }
+ if (split_u) {
+ //bu_log("split: udot cos_within_ang\n");
+ if (below) {
+ p2d.Set(u, v1);
+ on_surf_points.Append(p2d);
}
+ //top
+ p2d.Set(u, v2);
+ on_surf_points.Append(p2d);
+ getSurfacePoints(s_cdt, sinfo, u1, u, v1, v2, min_dist, within_dist,
+ cos_within_ang, on_surf_points, left, below);
+ getSurfacePoints(s_cdt, sinfo, u, u2, v1, v2, min_dist, within_dist,
+ cos_within_ang, on_surf_points, false, below);
+ return;
}
+ if (split_v) {
+ //bu_log("split: vdot cos_within_ang\n");
+ if (left) {
+ p2d.Set(u1, v);
+ on_surf_points.Append(p2d);
+ }
+ //right
+ p2d.Set(u2, v);
+ on_surf_points.Append(p2d);
+
+ getSurfacePoints(s_cdt, sinfo, u1, u2, v1, v, min_dist, within_dist,
+ cos_within_ang, on_surf_points, left, below);
+ getSurfacePoints(s_cdt, sinfo, u1, u2, v, v2, min_dist, within_dist,
+ cos_within_ang, on_surf_points, left, false);
+ return;
+ }
+
+ if (left) {
+ p2d.Set(u1, v);
+ on_surf_points.Append(p2d);
+ }
+ if (below) {
+ p2d.Set(u, v1);
+ on_surf_points.Append(p2d);
+ }
+ //center
+ p2d.Set(u, v);
+ on_surf_points.Append(p2d);
+ //right
+ p2d.Set(u2, v);
+ on_surf_points.Append(p2d);
+ //top
+ p2d.Set(u, v2);
+ on_surf_points.Append(p2d);
}
@@ -554,7 +454,9 @@
void
getSurfacePoints(struct ON_Brep_CDT_State *s_cdt,
const ON_BrepFace &face,
- ON_2dPointArray &on_surf_points)
+ ON_2dPointArray &on_surf_points,
+ ON_RTree *rt_trims
+ )
{
double surface_width, surface_height;
@@ -579,6 +481,7 @@
struct cdt_surf_info sinfo;
sinfo.s = s;
sinfo.f = &face;
+ sinfo.rt_trims = rt_trims;
sinfo.strim_pnts = s_cdt->strim_pnts;
sinfo.strim_norms = s_cdt->strim_norms;
double t1, t2;
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits