Revision: 74269
http://sourceforge.net/p/brlcad/code/74269
Author: starseeker
Date: 2019-10-30 21:43:03 +0000 (Wed, 30 Oct 2019)
Log Message:
-----------
Address a couple issues that resulted in invalid meshes. One was obvious in
retrospect - a surface point has no context by itself to make a sane bounding
box, so it has to come from its parent overt. The other is a little more
worrisome - getting failing RTree searches for vertex lookup unless we do a
full tree rebuild after the vertex insertion. My understanding is that we
shouldn't have to do this, but unwinding what's going on is going to need a
pretty deep dive into the RTree.h code. In the meantime, just rebuild the tree
so we can do other testing...
Modified Paths:
--------------
brlcad/trunk/src/libbrep/cdt_ovlps.cpp
Modified: brlcad/trunk/src/libbrep/cdt_ovlps.cpp
===================================================================
--- brlcad/trunk/src/libbrep/cdt_ovlps.cpp 2019-10-30 19:02:48 UTC (rev
74268)
+++ brlcad/trunk/src/libbrep/cdt_ovlps.cpp 2019-10-30 21:43:03 UTC (rev
74269)
@@ -125,14 +125,15 @@
// The fmesh pnts array may have inactive vertices - we only want the
// active verts for this portion of the processing.
- std::map<long, class overt_t *> overts;
+ std::map<long, overt_t *> overts;
RTree<long, double, 3> vtree;
+ void rebuild_vtree();
void plot_vtree(const char *fname);
void vert_adjust(long p_id, ON_3dPoint *p, ON_3dVector *v);
// Add an fmesh vertex to the overts array and tree.
- overt_t *vert_add(long);
+ overt_t *vert_add(long, ON_BoundingBox *bb = NULL);
// Find close vertices
std::set<long> overts_search(ON_BoundingBox &bb);
@@ -262,15 +263,29 @@
std::set<long>::iterator a_it;
for (a_it = averts.begin(); a_it != averts.end(); a_it++) {
overts[*a_it] = new overt_t(this, *a_it);
- double fMin[3];
- fMin[0] = overts[*a_it]->bb.Min().x;
- fMin[1] = overts[*a_it]->bb.Min().y;
- fMin[2] = overts[*a_it]->bb.Min().z;
+ }
+
+ rebuild_vtree();
+}
+void
+omesh_t::rebuild_vtree()
+{
+ std::map<long, class overt_t *>::iterator o_it;
+
+ vtree.RemoveAll();
+
+ for (o_it = overts.begin(); o_it != overts.end(); o_it++) {
+ long ind = o_it->first;
+ overt_t *ov = o_it->second;
+ double fMin[3];
+ fMin[0] = ov->bb.Min().x;
+ fMin[1] = ov->bb.Min().y;
+ fMin[2] = ov->bb.Min().z;
double fMax[3];
- fMax[0] = overts[*a_it]->bb.Max().x;
- fMax[1] = overts[*a_it]->bb.Max().y;
- fMax[2] = overts[*a_it]->bb.Max().z;
- vtree.Insert(fMin, fMax, *a_it);
+ fMax[0] = ov->bb.Max().x;
+ fMax[1] = ov->bb.Max().y;
+ fMax[2] = ov->bb.Max().z;
+ vtree.Insert(fMin, fMax, ind);
}
}
@@ -450,12 +465,12 @@
omesh_t::vert_search(ON_BoundingBox &bb)
{
double fMin[3], fMax[3];
- fMin[0] = bb.Min().x;
- fMin[1] = bb.Min().y;
- fMin[2] = bb.Min().z;
- fMax[0] = bb.Max().x;
- fMax[1] = bb.Max().y;
- fMax[2] = bb.Max().z;
+ fMin[0] = bb.Min().x - ON_ZERO_TOLERANCE;
+ fMin[1] = bb.Min().y - ON_ZERO_TOLERANCE;
+ fMin[2] = bb.Min().z - ON_ZERO_TOLERANCE;
+ fMax[0] = bb.Max().x + ON_ZERO_TOLERANCE;
+ fMax[1] = bb.Max().y + ON_ZERO_TOLERANCE;
+ fMax[2] = bb.Max().z + ON_ZERO_TOLERANCE;
std::set<long> near_verts;
size_t nhits = vtree.Search(fMin, fMax, NearVertsCallback, (void
*)&near_verts);
@@ -507,9 +522,13 @@
overt_t *
-omesh_t::vert_add(long f3ind)
+omesh_t::vert_add(long f3ind, ON_BoundingBox *bb)
{
overts[f3ind] = new overt_t(this, f3ind);
+ if (bb) {
+ overts[f3ind]->bb = *bb;
+ }
+#if 0
double fMin[3];
fMin[0] = overts[f3ind]->bb.Min().x;
fMin[1] = overts[f3ind]->bb.Min().y;
@@ -519,6 +538,12 @@
fMax[1] = overts[f3ind]->bb.Max().y;
fMax[2] = overts[f3ind]->bb.Max().z;
vtree.Insert(fMin, fMax, f3ind);
+#endif
+ // TODO Ew. Shouldn't (I don't think?) have to do a full recreation of the
+ // rtree after every point, but just doing the insertion above doesn't
+ // result in a successful vert search (see area around line 1214). Really
+ // need to dig into why.
+ rebuild_vtree();
return overts[f3ind];
}
@@ -1077,7 +1102,7 @@
std::map<cdt_mesh::uedge_t, std::vector<revt_pt_t>>::iterator es_it;
while (edge_sets->size()) {
std::map<cdt_mesh::uedge_t, std::vector<revt_pt_t>> updated_esets;
-
+
cdt_mesh::uedge_t ue = edge_sets->begin()->first;
std::vector<revt_pt_t> epnts = edge_sets->begin()->second;
edge_sets->erase(edge_sets->begin());
@@ -1148,7 +1173,7 @@
proj_2d.second = v;
polygon->pnts_2d.push_back(proj_2d);
polygon->p2o[polygon->pnts_2d.size() - 1] = pind;
- }
+ }
// Initialize the polygon edges with one of the triangles.
cdt_mesh::triangle_t tri1 = omesh->fmesh->tris_vect[*(rtris.begin())];
@@ -1182,6 +1207,31 @@
std::set<overt_t *> new_overts;
bool have_inside = false;
for (size_t i = 0; i < epnts.size(); i++) {
+ bool skip_epnt = false;
+#if 0
+ if (BU_STR_EQUAL(omesh->fmesh->name, "p.s")) {
+ ON_3dPoint
problem(3.4452740189190436,7.674473756016984,22.999999999999989);
+ if (problem.DistanceTo(epnts[i].spnt) < 0.1) {
+ std::cout << "search problem\n";
+ }
+ }
+#endif
+ std::set <overt_t *> nv = omesh->vert_search(epnts[i].ov->bb);
+ std::set<overt_t *>::iterator v_it;
+ for (v_it = nv.begin(); v_it != nv.end(); v_it++) {
+ ON_3dPoint cvpnt = (*v_it)->vpnt();
+ double cvbbdiag = (*v_it)->bb.Diagonal().Length() * 0.1;
+ if (cvpnt.DistanceTo(epnts[i].spnt) < cvbbdiag) {
+ // Too close to a vertex in the current mesh, skip
+ std::cout << "skip epnt, too close to vert\n";
+ skip_epnt = true;
+ break;
+ }
+ }
+ if (skip_epnt) {
+ continue;
+ }
+
bool inside = false;
{
ON_3dPoint ovpnt = epnts[i].ov->vpnt();
@@ -1210,12 +1260,13 @@
CDT_Add3DPnt(s_cdt, omesh->fmesh->pnts[f3ind],
omesh->fmesh->f_id, -1, -1, -1, 0, 0);
CDT_Add3DNorm(s_cdt, omesh->fmesh->normals[fnind],
omesh->fmesh->pnts[f3ind], omesh->fmesh->f_id, -1, -1, -1, 0, 0);
omesh->fmesh->nmap[f3ind] = fnind;
- new_overts.insert(omesh->vert_add(f3ind));
+ overt_t *nvrt = omesh->vert_add(f3ind, &(epnts[i].ov->bb));
+ new_overts.insert(nvrt);
polygon->p2o[p2dind] = f3ind;
polygon->interior_points.insert(p2dind);
have_inside = true;
- }
+ }
}
@@ -1988,7 +2039,9 @@
fmeshes.insert(fmesh1);
fmeshes.insert(fmesh2);
}
- std::cout << "Full face validity check results:\n";
+ if (verbosity > 0) {
+ std::cout << "Full face validity check results:\n";
+ }
std::set<cdt_mesh::cdt_mesh_t *>::iterator f_it;
for (f_it = fmeshes.begin(); f_it != fmeshes.end(); f_it++) {
cdt_mesh::cdt_mesh_t *fmesh = *f_it;
@@ -2216,6 +2269,7 @@
for (r_it = rtris.begin(); r_it != rtris.end(); r_it++) {
replace_edge_split_tri(*omesh->fmesh, *r_it, f3ind, ue);
}
+
omesh->vert_add(f3ind);
}
omesh->split_edges.clear();
@@ -2272,10 +2326,12 @@
}
#if 0
- ON_3dPoint
problem(3.40645986967497638,8.36595332610066045,23.99999898083232353);
+ if (BU_STR_EQUAL(omesh->fmesh->name, "p.s")) {
+ ON_3dPoint
problem(3.4452740189190436,7.674473756016984,22.999999999999989);
if (problem.DistanceTo(spnt) < 0.01) {
std::cout << "problem\n";
}
+ }
#endif
// Check this point against the mesh vert tree - if we're
@@ -2291,7 +2347,7 @@
// skip that point as a refinement point in this step.
if (cverts.size()) {
double spdist = ovpnt.DistanceTo(spnt);
-
+
if (spdist < ON_ZERO_TOLERANCE) {
// If we're on the vertex point, we don't need to check
// further - we're not splitting there.
@@ -2345,7 +2401,7 @@
}
if (closest_uedge.v[0] == -1) {
- std::cout << "problem\n";
+ std::cout << "uedge problem\n";
omesh->refine_pnt_remove(ov);
continue;
}
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