Revision: 74204
http://sourceforge.net/p/brlcad/code/74204
Author: starseeker
Date: 2019-10-21 17:41:35 +0000 (Mon, 21 Oct 2019)
Log Message:
-----------
Rework vert-near-brep-edge testing - shouldn't be face centric for this stage.
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-21 15:51:37 UTC (rev
74203)
+++ brlcad/trunk/src/libbrep/cdt_ovlps.cpp 2019-10-21 17:41:35 UTC (rev
74204)
@@ -257,6 +257,8 @@
bool t_ind;
void update();
+ ON_3dPoint vpnt();
+
void plot(FILE *plot);
private:
@@ -283,15 +285,15 @@
// uedge_t class in the rtree, store them in two maps to support both
// adding/removing them and looking them up from either triangles or
// the tree.
- std::map<cdt_mesh::uedge_t, size_t> interior_uedge_ids;
- std::map<size_t, cdt_mesh::uedge_t> interior_uedges;
- RTree<size_t, double, 3> iuetree;
-
+ std::map<cdt_mesh::uedge_t, long> interior_uedge_ids;
+ std::map<long, cdt_mesh::uedge_t> interior_uedges;
+ RTree<long, double, 3> iedge_tree;
+
// When we consider a vertex near an edge (i.e. we're going to yank
that edge
// and retessellate) all the other unassigned overts that have that
edge as
// their assigned closest edge need to find a new one. Make it easy to
find
// out which vertices need to do that work.
- std::map<size_t, std::set<long>> iue_close_overts;
+ std::map<long, std::set<long>> iedge_close_overts;
void vert_adjust(long p_id, ON_3dPoint *p, ON_3dVector *v);
@@ -305,9 +307,6 @@
// Find close vertices
std::set<long> overts_search(ON_BoundingBox &bb);
- // Find close face boundary edges
- std::set<cdt_mesh::cpolyedge_t *> boundary_edges_search(ON_BoundingBox
&bb);
-
// Find close (non-face-boundary) edges
std::set<size_t> interior_uedges_search(ON_BoundingBox &bb);
@@ -327,6 +326,7 @@
void edge_remove(cdt_mesh::uedge_t &ue, int update_verts);
void edge_tris_remove(cdt_mesh::uedge_t &ue);
+
};
double
@@ -334,6 +334,12 @@
return v_min_edge_len;
}
+ON_3dPoint
+overt_t::vpnt() {
+ ON_3dPoint vp = *(omesh->fmesh->pnts[p_id]);
+ return vp;
+}
+
void
overt_t::update() {
// 1. Get pnt's associated edges.
@@ -376,7 +382,7 @@
double mindist = DBL_MAX;
if (closest_uedge >= 0) {
- omesh->iue_close_overts[closest_uedge].erase(p_id);
+ omesh->iedge_close_overts[closest_uedge].erase(p_id);
}
closest_uedge = -1;
std::set<size_t> close_edges = omesh->interior_uedges_search(bb);
@@ -393,7 +399,7 @@
}
}
if (closest_uedge >= 0) {
- omesh->iue_close_overts[closest_uedge].insert(p_id);
+ omesh->iedge_close_overts[closest_uedge].insert(p_id);
}
}
@@ -429,6 +435,15 @@
edge_add(ue, 0);
++tree_it;
}
+
+ std::set<cdt_mesh::uedge_t>::iterator u_it;
+ for (u_it = uedges.begin(); u_it != uedges.end(); u_it++) {
+ if (fmesh->brep_edges.find(*u_it) == fmesh->brep_edges.end()) {
+ std::cout << "Interior edge\n";
+ } else {
+ std::cout << "Skip Boundary edge\n";
+ }
+ }
}
void
@@ -507,32 +522,6 @@
return near_overts;
}
-static bool NearBoundaryEdgesCallback(void *data, void *a_context) {
- std::set<cdt_mesh::cpolyedge_t *> *edges = (std::set<cdt_mesh::cpolyedge_t
*> *)a_context;
- cdt_mesh::cpolyedge_t *pe = (cdt_mesh::cpolyedge_t *)data;
- edges->insert(pe);
- return true;
-}
-std::set<cdt_mesh::cpolyedge_t *>
-omesh_t::boundary_edges_search(ON_BoundingBox &bb)
-{
- double fMin[3]; double 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;
- std::set<cdt_mesh::cpolyedge_t *> nedges;
- struct ON_Brep_CDT_State *s_cdt = (struct ON_Brep_CDT_State *)fmesh->p_cdt;
- size_t nhits = s_cdt->face_rtrees_3d[fmesh->f_id].Search(fMin, fMax,
NearBoundaryEdgesCallback, (void *)&nedges);
-
- if (!nhits) {
- return std::set<cdt_mesh::cpolyedge_t *>();
- }
- return nedges;
-}
-
static bool NearIntEdgesCallback(size_t data, void *a_context) {
std::set<size_t> *edges = (std::set<size_t> *)a_context;
edges->insert(data);
@@ -549,7 +538,7 @@
fMax[1] = bb.Max().y;
fMax[2] = bb.Max().z;
std::set<size_t> nedges;
- size_t nhits = iuetree.Search(fMin, fMax, NearIntEdgesCallback, (void
*)&nedges);
+ size_t nhits = iedge_tree.Search(fMin, fMax, NearIntEdgesCallback, (void
*)&nedges);
if (!nhits) {
// TODO - if we've got nothing, try triangles - if we're close to any
of those,
@@ -727,7 +716,7 @@
fMax[0] = ebb.Max().x;
fMax[1] = ebb.Max().y;
fMax[2] = ebb.Max().z;
- iuetree.Insert(fMin, fMax, nind);
+ iedge_tree.Insert(fMin, fMax, nind);
if (update_verts) {
overts[ue.v[0]]->update();
@@ -777,7 +766,7 @@
interior_uedge_ids.erase(ue);
interior_uedges.erase(ue_id);
- iuetree.Remove(fMin, fMax, ue_id);
+ iedge_tree.Remove(fMin, fMax, ue_id);
if (update_verts) {
overts[ue.v[0]]->update();
@@ -784,7 +773,7 @@
overts[ue.v[1]]->update();
// The verts who where referencing this as their closest edge need to
// pick a new one
- std::set<long> close_verts = iue_close_overts[ue_id];
+ std::set<long> close_verts = iedge_close_overts[ue_id];
std::set<long>::iterator c_it;
for (c_it = close_verts.begin(); c_it != close_verts.end(); c_it++) {
overts[*c_it]->update();
@@ -796,20 +785,12 @@
ON_BoundingBox
-edge_bbox(struct ON_Brep_CDT_State *s_cdt, cdt_mesh::cpolyedge_t *pe)
+edge_bbox(cdt_mesh::bedge_seg_t *eseg)
{
- ON_BrepTrim& trim = s_cdt->brep->m_T[pe->trim_ind];
- double tcparam = (pe->trim_start + pe->trim_end) / 2.0;
- ON_3dPoint trim_2d = trim.PointAt(tcparam);
- const ON_Surface *s = trim.SurfaceOf();
- ON_3dPoint trim_3d = s->PointAt(trim_2d.x, trim_2d.y);
-
- ON_3dPoint *p3d1 = pe->eseg->e_start;
- ON_3dPoint *p3d2 = pe->eseg->e_end;
+ ON_3dPoint *p3d1 = eseg->e_start;
+ ON_3dPoint *p3d2 = eseg->e_end;
ON_Line line(*p3d1, *p3d2);
- double arc_dist = 2*trim_3d.DistanceTo(line.ClosestPointTo(trim_3d));
-
ON_BoundingBox bb = line.BoundingBox();
bb.m_max.x = bb.m_max.x + ON_ZERO_TOLERANCE;
bb.m_max.y = bb.m_max.y + ON_ZERO_TOLERANCE;
@@ -819,7 +800,7 @@
bb.m_min.z = bb.m_min.z - ON_ZERO_TOLERANCE;
double dist = p3d1->DistanceTo(*p3d2);
- double bdist = (0.5*dist > arc_dist) ? 0.5*dist : arc_dist;
+ double bdist = 0.5*dist;
double xdist = bb.m_max.x - bb.m_min.x;
double ydist = bb.m_max.y - bb.m_min.y;
double zdist = bb.m_max.z - bb.m_min.z;
@@ -1423,10 +1404,10 @@
// TODO - for edge points, should really be searching edge closest
// point rather than surface closest point...
void
-adjust_mvert_pair(overt_t *v1, overt_t *v2)
+adjust_overt_pair(overt_t *v1, overt_t *v2)
{
- ON_3dPoint p1 = *v1->omesh->fmesh->pnts[v1->p_id];
- ON_3dPoint p2 = *v2->omesh->fmesh->pnts[v2->p_id];
+ ON_3dPoint p1 = v1->vpnt();
+ ON_3dPoint p2 = v2->vpnt();
double pdist = p1.DistanceTo(p2);
ON_Line l(p1,p2);
// Weight the t parameter on the line so we are closer to the vertex
@@ -1624,7 +1605,7 @@
std::pair<overt_t *, overt_t *> vpair = vq.front();
vq.pop();
- adjust_mvert_pair(vpair.first, vpair.second);
+ adjust_overt_pair(vpair.first, vpair.second);
adjusted.insert(vpair.first);
adjusted.insert(vpair.second);
}
@@ -1639,7 +1620,7 @@
vert_ovlps[l].erase(c);
vert_ovlps[c].erase(l);
//std::cout << "COMPLEX - adjusting 1 pair only:\n";
- adjust_mvert_pair(l, c);
+ adjust_overt_pair(l, c);
adjusted.insert(l);
adjusted.insert(c);
}
@@ -1797,70 +1778,67 @@
}
int
-split_brep_face_edges_near_verts(std::set<std::pair<cdt_mesh::cdt_mesh_t *,
cdt_mesh::cdt_mesh_t *>> &check_pairs)
+split_brep_face_edges_near_verts(
+ std::set<std::pair<omesh_t *, omesh_t *>> &check_pairs,
+ std::map<long, cdt_mesh::bedge_seg_t *> &b_edges,
+ RTree<long, double, 3> &bedge_tree
+ )
{
+ std::set<std::pair<omesh_t *, omesh_t *>>::iterator cp_it;
int replaced_tris = 0;
- // Get the bounding boxes of all vertices of all meshes of all breps
- // that might have possible interactions, and find close point sets
- std::vector<struct mvert_info *> all_mverts;
- std::map<std::pair<struct ON_Brep_CDT_State *, int>, RTree<void *, double,
3>> rtrees_mpnts;
- std::map<std::pair<struct ON_Brep_CDT_State *, int>, std::map<long, struct
mvert_info *>> mpnt_maps;
- vert_bboxes(&all_mverts, &rtrees_mpnts, &mpnt_maps, check_pairs);
+ std::set<omesh_t *> ameshes;
+ for (cp_it = check_pairs.begin(); cp_it != check_pairs.end(); cp_it++) {
+ ameshes.insert(cp_it->first);
+ ameshes.insert(cp_it->second);
+ }
- // Iterate over mverts, checking for nearby edges.
- std::map<cdt_mesh::bedge_seg_t *, struct mvert_info *> edge_vert;
- std::set<std::pair<cdt_mesh::cdt_mesh_t *, cdt_mesh::cdt_mesh_t
*>>::iterator cp_it;
+ // Iterate over verts, checking for nearby edges.
+ std::map<cdt_mesh::bedge_seg_t *, overt_t *> edge_vert;
struct bu_vls fname = BU_VLS_INIT_ZERO;
bu_vls_sprintf(&fname, "vert_edge_pairs.plot3");
FILE* plot_file = fopen(bu_vls_cstr(&fname), "w");
- for (cp_it = check_pairs.begin(); cp_it != check_pairs.end(); cp_it++) {
- cdt_mesh::cdt_mesh_t *fmesh1 = cp_it->first;
- cdt_mesh::cdt_mesh_t *fmesh2 = cp_it->second;
- struct ON_Brep_CDT_State *s_cdt1 = (struct ON_Brep_CDT_State
*)fmesh1->p_cdt;
- struct ON_Brep_CDT_State *s_cdt2 = (struct ON_Brep_CDT_State
*)fmesh2->p_cdt;
- if (s_cdt1 != s_cdt2) {
- std::set<std::pair<void *, void *>> vert_edge_pairs;
- size_t ovlp_cnt =
rtrees_mpnts[std::make_pair(s_cdt1,fmesh1->f_id)].Overlaps(s_cdt2->face_rtrees_3d[fmesh2->f_id],
&vert_edge_pairs);
- int used_verts = 0;
- if (ovlp_cnt && vert_edge_pairs.size()) {
- std::set<std::pair<void *, void *>>::iterator v_it;
- for (v_it = vert_edge_pairs.begin(); v_it !=
vert_edge_pairs.end(); v_it++) {
- struct mvert_info *v = (struct mvert_info *)v_it->first;
- ON_3dPoint p = *fmesh1->pnts[v->p_id];
- cdt_mesh::cpolyedge_t *pe = (cdt_mesh::cpolyedge_t
*)v_it->second;
+ std::set<omesh_t *>::iterator a_it;
+ for (a_it = ameshes.begin(); a_it != ameshes.end(); a_it++) {
+ omesh_t *omesh = *a_it;
+ std::set<std::pair<long, long>> vert_edge_pairs;
+ size_t ovlp_cnt = omesh->vtree.Overlaps(bedge_tree, &vert_edge_pairs);
+ int used_verts = 0;
+ if (ovlp_cnt && vert_edge_pairs.size()) {
+ std::set<std::pair<long, long>>::iterator v_it;
+ for (v_it = vert_edge_pairs.begin(); v_it != vert_edge_pairs.end();
v_it++) {
+ overt_t *v = omesh->overts[v_it->first];
+ ON_3dPoint p = v->vpnt();
+ cdt_mesh::bedge_seg_t *eseg = b_edges[v_it->second];
- ON_3dPoint *p3d1 = pe->eseg->e_start;
- ON_3dPoint *p3d2 = pe->eseg->e_end;
- ON_Line line(*p3d1, *p3d2);
- double d1 = p3d1->DistanceTo(p);
- double d2 = p3d2->DistanceTo(p);
- double dline = 2*p.DistanceTo(line.ClosestPointTo(p));
- if (d1 > dline && d2 > dline) {
- //std::cout << "ACCEPT: d1: " << d1 << ", d2: " << d2
<< ", dline: " << dline << "\n";
- if (edge_vert.find(pe->eseg) != edge_vert.end()) {
- struct ON_Brep_CDT_State *s_cdtv = v->s_cdt;
- cdt_mesh::cdt_mesh_t fmeshv =
s_cdtv->fmeshes[v->f_id];
- ON_3dPoint pv = *fmeshv.pnts[v->p_id];
- double dv = pv.DistanceTo(line.ClosestPointTo(pv));
- if (dv > dline) {
- edge_vert[pe->eseg] = v;
- }
- } else {
- edge_vert[pe->eseg] = v;
- used_verts++;
+ ON_3dPoint *p3d1 = eseg->e_start;
+ ON_3dPoint *p3d2 = eseg->e_end;
+ ON_Line line(*p3d1, *p3d2);
+ double d1 = p3d1->DistanceTo(p);
+ double d2 = p3d2->DistanceTo(p);
+ double dline = 2*p.DistanceTo(line.ClosestPointTo(p));
+ if (d1 > dline && d2 > dline) {
+ std::cout << "ACCEPT: d1: " << d1 << ", d2: " << d2 << ",
dline: " << dline << "\n";
+ if (edge_vert.find(eseg) != edge_vert.end()) {
+ ON_3dPoint pv = edge_vert[eseg]->vpnt();
+ double dv = pv.DistanceTo(line.ClosestPointTo(pv));
+ if (dv > dline) {
+ edge_vert[eseg] = v;
}
- pl_color(plot_file, 255, 0, 0);
- BBOX_PLOT(plot_file, v->bb);
- pl_color(plot_file, 0, 0, 255);
- ON_BoundingBox edge_bb = edge_bbox(s_cdt2, pe);
- BBOX_PLOT(plot_file, edge_bb);
} else {
- //std::cout << "REJECT: d1: " << d1 << ", d2: " << d2
<< ", dline: " << dline << "\n";
+ edge_vert[eseg] = v;
+ used_verts++;
}
+ pl_color(plot_file, 255, 0, 0);
+ BBOX_PLOT(plot_file, v->bb);
+ pl_color(plot_file, 0, 0, 255);
+ ON_BoundingBox edge_bb = edge_bbox(eseg);
+ BBOX_PLOT(plot_file, edge_bb);
+ } else {
+ std::cout << "REJECT: d1: " << d1 << ", d2: " << d2 << ",
dline: " << dline << "\n";
}
- //std::cout << "used_verts: " << used_verts << "\n";
}
+ //std::cout << "used_verts: " << used_verts << "\n";
}
}
fclose(plot_file);
@@ -1869,16 +1847,14 @@
// 2. Find the point on the edge nearest to the vert point. (TODO - need
to think about how to
// handle multiple verts associated with same edge - may want to iterate
starting with the closest
// and see if splitting clears the others...)
- std::map<cdt_mesh::bedge_seg_t *, struct mvert_info *>::iterator ev_it;
+ std::map<cdt_mesh::bedge_seg_t *, overt_t *>::iterator ev_it;
for (ev_it = edge_vert.begin(); ev_it != edge_vert.end(); ev_it++) {
cdt_mesh::bedge_seg_t *eseg = ev_it->first;
- struct mvert_info *v = ev_it->second;
+ overt_t *v = ev_it->second;
ON_NurbsCurve *nc = eseg->nc;
ON_Interval domain(eseg->edge_start, eseg->edge_end);
- struct ON_Brep_CDT_State *s_cdt = v->s_cdt;
- cdt_mesh::cdt_mesh_t &fmesh = s_cdt->fmeshes[v->f_id];
- ON_3dPoint p = *fmesh.pnts[v->p_id];
+ ON_3dPoint p = v->vpnt();
double t;
ON_NurbsCurve_GetClosestPoint(&t, nc, p, 0.0, &domain);
ON_3dPoint cep = nc->PointAt(t);
@@ -2405,7 +2381,7 @@
int
ON_Brep_CDT_Ovlp_Resolve(struct ON_Brep_CDT_State **s_a, int s_cnt)
{
- std::set<std::pair<cdt_mesh::cdt_mesh_t *, cdt_mesh::cdt_mesh_t
*>>::iterator cp_it;
+ std::set<std::pair<cdt_mesh::cdt_mesh_t *, cdt_mesh::cdt_mesh_t
*>>::iterator p_it;
if (!s_a) return -1;
if (s_cnt < 1) return 0;
@@ -2418,13 +2394,14 @@
check_faces_validity(check_pairs, 0);
- std::cout << "Initial overlap cnt: " << face_ovlps_cnt(s_a, s_cnt) << "\n";
+ int face_ov_cnt = face_ovlps_cnt(s_a, s_cnt);
+ std::cout << "Initial overlap cnt: " << face_ov_cnt << "\n";
+ if (!face_ov_cnt) return 0;
// Make omesh containers for all the cdt_meshes in play
std::set<cdt_mesh::cdt_mesh_t *> afmeshes;
std::vector<omesh_t *> omeshes;
std::map<cdt_mesh::cdt_mesh_t *, omesh_t *> f2omap;
- std::set<std::pair<cdt_mesh::cdt_mesh_t *, cdt_mesh::cdt_mesh_t
*>>::iterator p_it;
for (p_it = check_pairs.begin(); p_it != check_pairs.end(); p_it++) {
afmeshes.insert(p_it->first);
afmeshes.insert(p_it->second);
@@ -2451,14 +2428,51 @@
std::cout << "Post vert adjustment overlap cnt: " << face_ovlps_cnt(s_a,
s_cnt) << "\n";
- int sbfvtri_cnt = split_brep_face_edges_near_verts(check_pairs);
- if (sbfvtri_cnt) {
- std::cout << "Replaced " << sbfvtri_cnt << " triangles by splitting
edges near vertices\n";
- check_faces_validity(check_pairs, 2);
+
+ // Boundary edges are handled at a brep object level, not a face level -
handle
+ // them as an independent process
+ {
+ std::map<long, cdt_mesh::bedge_seg_t *> b_edges;
+ RTree<long, double, 3> bedge_tree;
+ std::set<struct ON_Brep_CDT_State *> a_cdt;
+ for (p_it = check_pairs.begin(); p_it != check_pairs.end(); p_it++) {
+ a_cdt.insert((struct ON_Brep_CDT_State *)p_it->first->p_cdt);
+ a_cdt.insert((struct ON_Brep_CDT_State *)p_it->second->p_cdt);
+ }
+ long ecnt = 0;
+ std::set<struct ON_Brep_CDT_State *>::iterator a_it;
+ for (a_it = a_cdt.begin(); a_it != a_cdt.end(); a_it++) {
+ struct ON_Brep_CDT_State *s_cdt = *a_it;
+ std::map<int, std::set<cdt_mesh::bedge_seg_t *>>::iterator ep_it;
+ for (ep_it = s_cdt->e2polysegs.begin(); ep_it !=
s_cdt->e2polysegs.end(); ep_it++) {
+ std::set<cdt_mesh::bedge_seg_t *>::iterator bs_it;
+ for (bs_it = ep_it->second.begin(); bs_it !=
ep_it->second.end(); bs_it++) {
+ cdt_mesh::bedge_seg_t *bseg = *bs_it;
+ b_edges[ecnt] = bseg;
+ ON_BoundingBox bb = edge_bbox(bseg);
+ double fMin[3];
+ fMin[0] = bb.Min().x;
+ fMin[1] = bb.Min().y;
+ fMin[2] = bb.Min().z;
+ double fMax[3];
+ fMax[0] = bb.Max().x;
+ fMax[1] = bb.Max().y;
+ fMax[2] = bb.Max().z;
+ bedge_tree.Insert(fMin, fMax, ecnt);
+ ecnt++;
+ }
+ }
+ }
+
+ int sbfvtri_cnt = split_brep_face_edges_near_verts(ocheck_pairs,
b_edges, bedge_tree);
+ if (sbfvtri_cnt) {
+ std::cout << "Replaced " << sbfvtri_cnt << " triangles by splitting
edges near vertices\n";
+ check_faces_validity(check_pairs, 2);
+ }
+
+ std::cout << "Post edges-near-verts split overlap cnt: " <<
face_ovlps_cnt(s_a, s_cnt) << "\n";
}
- std::cout << "Post edges-near-verts split overlap cnt: " <<
face_ovlps_cnt(s_a, s_cnt) << "\n";
-
#if 0
int sbfetri_cnt = split_brep_face_edges_near_edges(check_pairs);
if (sbfetri_cnt) {
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