Revision: 73891
http://sourceforge.net/p/brlcad/code/73891
Author: starseeker
Date: 2019-09-11 18:41:15 +0000 (Wed, 11 Sep 2019)
Log Message:
-----------
Test inserting trim points that don't fall into another trim's UV bbox into the
on_surf_points set.
Modified Paths:
--------------
brlcad/trunk/src/libbrep/cdt.cpp
brlcad/trunk/src/libbrep/cdt.h
brlcad/trunk/src/libbrep/cdt_edge.cpp
brlcad/trunk/src/libbrep/cdt_mesh.h
brlcad/trunk/src/libbrep/cdt_surf.cpp
brlcad/trunk/src/libbrep/cdt_util.cpp
Modified: brlcad/trunk/src/libbrep/cdt.cpp
===================================================================
--- brlcad/trunk/src/libbrep/cdt.cpp 2019-09-11 17:08:15 UTC (rev 73890)
+++ brlcad/trunk/src/libbrep/cdt.cpp 2019-09-11 18:41:15 UTC (rev 73891)
@@ -203,7 +203,7 @@
// Sample the surface, independent of the trimming curves, to get points
that
// will tie the mesh to the interior surface.
- //GetInteriorPoints(s_cdt, face.m_face_index);
+ GetInteriorPoints(s_cdt, face.m_face_index);
cdt_mesh::cdt_mesh_t *fmesh = &s_cdt->fmeshes[face.m_face_index];
fmesh->f_id = face.m_face_index;
Modified: brlcad/trunk/src/libbrep/cdt.h
===================================================================
--- brlcad/trunk/src/libbrep/cdt.h 2019-09-11 17:08:15 UTC (rev 73890)
+++ brlcad/trunk/src/libbrep/cdt.h 2019-09-11 18:41:15 UTC (rev 73891)
@@ -185,6 +185,10 @@
void plot_on_bbox(ON_BoundingBox &bb, const char *filename);
void plot_ce_bbox(struct ON_Brep_CDT_State *s_cdt, cdt_mesh::cpolyedge_t *pe,
const char *filename);
+
+std::vector<cdt_mesh::cpolyedge_t *>
+cdt_face_polyedges(struct ON_Brep_CDT_State *s_cdt, int face_index);
+
struct cdt_audit_info *
cdt_ainfo(int fid, int vid, int tid, int eid, fastf_t x2d, fastf_t y2d, double
px, double py, double pz);
Modified: brlcad/trunk/src/libbrep/cdt_edge.cpp
===================================================================
--- brlcad/trunk/src/libbrep/cdt_edge.cpp 2019-09-11 17:08:15 UTC (rev
73890)
+++ brlcad/trunk/src/libbrep/cdt_edge.cpp 2019-09-11 18:41:15 UTC (rev
73891)
@@ -1522,43 +1522,10 @@
for (int face_index = 0; face_index < brep->m_F.Count(); face_index++) {
ON_BrepFace &face = s_cdt->brep->m_F[face_index];
- cdt_mesh::cdt_mesh_t *fmesh = &s_cdt->fmeshes[face_index];
std::cout << "Face " << face_index << " close edge check...\n";
- std::vector<cdt_mesh::cpolyedge_t *> ws;
- std::vector<cdt_mesh::cpolyedge_t *>::iterator w_it;
+ std::vector<cdt_mesh::cpolyedge_t *> ws = cdt_face_polyedges(s_cdt,
face_index);
- int loop_cnt = face.LoopCount();
- for (int li = 0; li < loop_cnt; li++) {
- const ON_BrepLoop *loop = face.Loop(li);
- bool is_outer = (face.OuterLoop()->m_loop_index ==
loop->m_loop_index) ? true : false;
- cdt_mesh::cpolygon_t *cpoly = NULL;
- if (is_outer) {
- cpoly = &fmesh->outer_loop;
- } else {
- cpoly = fmesh->inner_loops[li];
- }
-
- size_t ecnt = 1;
- cdt_mesh::cpolyedge_t *pe = (*cpoly->poly.begin());
- cdt_mesh::cpolyedge_t *first = pe;
- cdt_mesh::cpolyedge_t *next = pe->next;
- first->split_status = 0;
- ws.push_back(first);
- // Walk the loop
- while (first != next) {
- ecnt++;
- if (!next) break;
- next->split_status = 0;
- ws.push_back(next);
- next = next->next;
- if (ecnt > cpoly->poly.size()) {
- std::cerr << "\nrefine_close_edges: ERROR! encountered
infinite loop\n";
- return;
- }
- }
- }
-
#if 0
{
struct bu_vls fname = BU_VLS_INIT_ZERO;
@@ -1588,6 +1555,7 @@
// itself, this loop should be (in principle) suitable for
bu_parallel - we're not
// doing any splitting at this point - searching is a read only
activity once
// the initial data containers are set up
+ std::vector<cdt_mesh::cpolyedge_t *>::iterator w_it;
for (w_it = ws.begin(); w_it != ws.end(); w_it++) {
cdt_mesh::cpolyedge_t *tseg = *w_it;
ON_2dPoint p2d1(tseg->polygon->pnts_2d[tseg->v[0]].first,
tseg->polygon->pnts_2d[tseg->v[0]].second);
@@ -1631,16 +1599,23 @@
s_cdt->face_rtrees_2d[face.m_face_index].Search(tMin, tMax,
MinSplit2dCallback, (void *)&a_context);
}
- // If we need to split, do so
- for (w_it = ws.begin(); w_it != ws.end(); w_it++) {
- cdt_mesh::cpolyedge_t *pe = *w_it;
+ // If we need to split, do so. We need to process as a set,
+ // because an edge split on a closed face may end up removing more
+ // than one cpolyedge_t in ws at the same time.
+ std::set<cdt_mesh::cpolyedge_t *> ws_s(ws.begin(), ws.end());
+ while (ws_s.size()) {
+ cdt_mesh::cpolyedge_t *pe = *ws_s.begin();
if (pe->eseg) {
cdt_mesh::bedge_seg_t *b = pe->eseg;
+ // Get both of them in case they're both in ws (closed face)
+ ws_s.erase(b->tseg1);
+ ws_s.erase(b->tseg2);
+ int edge_ind = b->edge_ind;
if (pe->split_status == 2) {
std::set<cdt_mesh::bedge_seg_t *> esegs_split =
split_edge_seg(s_cdt, b, 1, 1);
if (esegs_split.size()) {
split_check = true;
- std::copy(esegs_split.begin(), esegs_split.end(),
std::back_inserter(curr_edge_segs[b->edge_ind]));
+ std::copy(esegs_split.begin(), esegs_split.end(),
std::back_inserter(curr_edge_segs[edge_ind]));
// Pick up the new trim segments from the edges for
the next iteration. Only
// want the ones associated with the current face.
std::set<cdt_mesh::bedge_seg_t *>::iterator b_it;
@@ -1652,17 +1627,18 @@
} else {
// This is probably fatal...
std::cerr << "Forced edge split failed???\n";
- curr_edge_segs[b->edge_ind].push_back(b);
+ curr_edge_segs[edge_ind].push_back(b);
current_trims.push_back(pe);
}
} else if (pe->split_status == 1) {
- curr_edge_segs[b->edge_ind].push_back(b);
+ curr_edge_segs[edge_ind].push_back(b);
current_trims.push_back(pe);
} else {
- curr_edge_segs[b->edge_ind].push_back(b);
+ curr_edge_segs[edge_ind].push_back(b);
}
} else {
// Trim only, no edge.
+ ws_s.erase(pe);
if (pe->split_status == 2) {
std::set<cdt_mesh::cpolyedge_t *> ntrims =
split_singular_seg(s_cdt, pe, 1);
if (ntrims.size()) {
Modified: brlcad/trunk/src/libbrep/cdt_mesh.h
===================================================================
--- brlcad/trunk/src/libbrep/cdt_mesh.h 2019-09-11 17:08:15 UTC (rev 73890)
+++ brlcad/trunk/src/libbrep/cdt_mesh.h 2019-09-11 18:41:15 UTC (rev 73891)
@@ -284,6 +284,7 @@
prev = NULL;
next = NULL;
defines_spnt = false;
+ eseg = NULL;
};
long v[2];
@@ -295,6 +296,7 @@
prev = NULL;
next = NULL;
defines_spnt = false;
+ eseg = NULL;
};
void plot3d(const char *fname);
Modified: brlcad/trunk/src/libbrep/cdt_surf.cpp
===================================================================
--- brlcad/trunk/src/libbrep/cdt_surf.cpp 2019-09-11 17:08:15 UTC (rev
73890)
+++ brlcad/trunk/src/libbrep/cdt_surf.cpp 2019-09-11 18:41:15 UTC (rev
73891)
@@ -65,6 +65,7 @@
const ON_Surface *s;
const ON_BrepFace *f;
RTree<void *, double, 2> *rtree_2d;
+ RTree<void *, double, 2> rtree_trim_spnts_2d;
std::map<int,ON_3dPoint *> *strim_pnts;
std::map<int,ON_3dPoint *> *strim_norms;
double u1, u2, v1, v2;
@@ -422,7 +423,32 @@
return d1+d2;
}
+struct rtree_trimpnt_context {
+ struct ON_Brep_CDT_State *s_cdt;
+ cdt_mesh::cpolyedge_t *cseg;
+ bool *use;
+};
+static bool UseTrimPntCallback(void *data, void *a_context) {
+ cdt_mesh::cpolyedge_t *tseg = (cdt_mesh::cpolyedge_t *)data;
+ struct rtree_trimpnt_context *context= (struct rtree_trimpnt_context
*)a_context;
+
+ // Our own bbox isn't a problem
+ if (tseg == context->cseg) return true;
+
+ // If this is a foreign box overlap, see if spnt is inside tseg's bbox.
If it is,
+ // we can't use spnt
+ ON_BoundingBox bb(context->cseg->spnt, context->cseg->spnt);
+ if (tseg->bb.Includes(bb)) {
+ *(context->use) = false;
+ return false;
+ }
+
+ return true;
+}
+
+
+
static void
sinfo_init(struct cdt_surf_info *sinfo, struct ON_Brep_CDT_State *s_cdt, int
face_index)
{
@@ -452,6 +478,43 @@
sinfo->min_edge = (*s_cdt->min_edge_seg_len)[face_index];
sinfo->max_edge = (*s_cdt->max_edge_seg_len)[face_index];
+
+ // If the trims will be contributing points, we need to figure out which
ones
+ // and assemble an rtree for them. We can't insert points from the general
+ // build too close to them or we run the risk of duplicate points and very
small
+ // triangles.
+ std::vector<cdt_mesh::cpolyedge_t *> ws = cdt_face_polyedges(s_cdt,
face.m_face_index);
+ std::vector<cdt_mesh::cpolyedge_t *>::iterator w_it;
+ for (w_it = ws.begin(); w_it != ws.end(); w_it++) {
+ cdt_mesh::cpolyedge_t *tseg = *w_it;
+ if (!tseg->defines_spnt) continue;
+ bool include_pnt = true;
+
+ struct rtree_trimpnt_context a_context;
+ a_context.s_cdt = s_cdt;
+ a_context.cseg = tseg;
+ a_context.use = &include_pnt;
+
+ double tMin[2];
+ tMin[0] = tseg->spnt.x - ON_ZERO_TOLERANCE;
+ tMin[1] = tseg->spnt.y - ON_ZERO_TOLERANCE;
+ double tMax[2];
+ tMax[0] = tseg->spnt.x + ON_ZERO_TOLERANCE;
+ tMax[1] = tseg->spnt.y + ON_ZERO_TOLERANCE;
+
+ s_cdt->face_rtrees_2d[face.m_face_index].Search(tMin, tMax,
UseTrimPntCallback, (void *)&a_context);
+
+ if (!include_pnt) {
+ std::cout << "Reject\n";
+ } else {
+ std::cout << "Accept\n";
+ sinfo->rtree_trim_spnts_2d.Insert(tMin, tMax, (void *)tseg);
+ sinfo->on_surf_points.insert(new ON_2dPoint(tseg->spnt));
+ }
+ }
+
+
+
double dist = 0.0;
double min_dist = 0.0;
double within_dist = 0.0;
@@ -504,7 +567,7 @@
void
-filter_surface_edge_pnts_2(struct cdt_surf_info *sinfo)
+filter_surface_pnts(struct cdt_surf_info *sinfo)
{
// Points on
@@ -537,10 +600,11 @@
sinfo->on_surf_points.erase((ON_2dPoint *)p);
}
+ cdt_mesh::cdt_mesh_t *fmesh =
&sinfo->s_cdt->fmeshes[sinfo->f->m_face_index];
+#if 0
// Next check the face loops with the point in polygon test. If it's
// outside the outer loop or inside one of the interior trimming loops,
// it's out.
- cdt_mesh::cdt_mesh_t *fmesh =
&sinfo->s_cdt->fmeshes[sinfo->f->m_face_index];
fmesh->outer_loop.rm_points_in_polygon(&sinfo->on_surf_points, true);
std::map<int, cdt_mesh::cpolygon_t*>::iterator i_it;
for (i_it = fmesh->inner_loops.begin(); i_it != fmesh->inner_loops.end();
i_it++) {
@@ -555,6 +619,7 @@
// point, or a nanoflann based nearest lookup for the edge points to get
candidates
// near each edge in turn - in the latter case, look for points common to
the result
// sets for both edge points to localize on that particular segment.
+#endif
// Populate m_interior_pnts with the final set
for (osp_it = sinfo->on_surf_points.begin(); osp_it !=
sinfo->on_surf_points.end(); osp_it++) {
@@ -582,7 +647,8 @@
}
}
-static bool
+//static bool
+bool
getSurfacePoint(
struct cdt_surf_info *sinfo,
SPatch &sp,
@@ -780,7 +846,7 @@
struct cdt_surf_info sinfo;
sinfo_init(&sinfo, s_cdt, face_index);
-
+#if 0
// may be a smaller trimmed subset of surface so worth getting
// face boundary
bool bGrowBox = false;
@@ -994,13 +1060,10 @@
double py = p2d.y + (bn_rand_half(prand) * 0.3*vlen);
sinfo.on_surf_points.insert(new ON_2dPoint(px,py));
}
+#endif
+ // Strip out points from the surface that are too close to the trimming
curves.
+ filter_surface_pnts(&sinfo);
- // Strip out points from the surface that are on the trimming curves.
Trim
- // points require special handling for watertightness and introducing
them
- // from the surface also runs the risk of adding duplicate 2D points,
which
- // aren't allowed for facetization.
- filter_surface_edge_pnts_2(&sinfo);
-
}
}
Modified: brlcad/trunk/src/libbrep/cdt_util.cpp
===================================================================
--- brlcad/trunk/src/libbrep/cdt_util.cpp 2019-09-11 17:08:15 UTC (rev
73890)
+++ brlcad/trunk/src/libbrep/cdt_util.cpp 2019-09-11 18:41:15 UTC (rev
73891)
@@ -203,6 +203,48 @@
}
+std::vector<cdt_mesh::cpolyedge_t *>
+cdt_face_polyedges(struct ON_Brep_CDT_State *s_cdt, int face_index)
+{
+ std::vector<cdt_mesh::cpolyedge_t *> ws;
+
+ ON_BrepFace &face = s_cdt->brep->m_F[face_index];
+ cdt_mesh::cdt_mesh_t *fmesh = &s_cdt->fmeshes[face_index];
+ int loop_cnt = face.LoopCount();
+ for (int li = 0; li < loop_cnt; li++) {
+ const ON_BrepLoop *loop = face.Loop(li);
+ bool is_outer = (face.OuterLoop()->m_loop_index == loop->m_loop_index)
? true : false;
+ cdt_mesh::cpolygon_t *cpoly = NULL;
+ if (is_outer) {
+ cpoly = &fmesh->outer_loop;
+ } else {
+ cpoly = fmesh->inner_loops[li];
+ }
+
+ size_t ecnt = 1;
+ cdt_mesh::cpolyedge_t *pe = (*cpoly->poly.begin());
+ cdt_mesh::cpolyedge_t *first = pe;
+ cdt_mesh::cpolyedge_t *next = pe->next;
+ first->split_status = 0;
+ ws.push_back(first);
+ //Walk the loop
+ while (first != next) {
+ ecnt++;
+ if (!next) break;
+ next->split_status = 0;
+ ws.push_back(next);
+ next = next->next;
+ if (ecnt > cpoly->poly.size()) {
+ std::cerr << "\ncdt_face_polyedges: ERROR! encountered infinite
loop\n";
+ ws.clear();
+ return ws;
+ }
+ }
+ }
+
+ return ws;
+}
+
struct cdt_audit_info *
cdt_ainfo(int fid, int vid, int tid, int eid, fastf_t x2d, fastf_t y2d,
fastf_t px, fastf_t py, fastf_t pz)
{
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