static inline bool are_holes_inside(RingIterator first, RingIterator beyond, ExteriorRing const& exterior_ring, IndexSet const& rings_with_turns) { int idx = 0; for (RingIterator it = first; it != beyond; ++it, ++idx) { // check only rings whose index is not associated to any turn if ( rings_with_turns.find(idx) == rings_with_turns.end() && !geometry::within(range::front(*it), exterior_ring) ) { return false; } } // for those rings that do not have any associated turns, // check if they lie inside another ring idx = 0; for (RingIterator it1 = first; it1 != beyond; ++it1, ++idx) { if ( rings_with_turns.find(idx) == rings_with_turns.end() ) { for (RingIterator it2 = first; it2 != beyond; ++it2) { if ( it1 != it2 && geometry::within(range::front(*it1), *it2) ) { return false; } } } } return true; }
bool isDup(const IndexSet& data, const BSONObj& key, RecordId loc) { const IndexSet::const_iterator it = data.find(IndexKeyEntry(key, RecordId())); if (it == data.end()) return false; // Not a dup if the entry is for the same loc. return it->loc != loc; }
bool isDup(const IndexSet& data, const BSONObj& key) { IndexSet::const_iterator it = data.find(IndexKeyEntry(key, RecordId())); if (it == data.end()) return false; ++it; if (it == data.end()) return false; return it->key.woCompare(key, BSONObj(), false) == 0; }
//----------------------------------------------------------------------------- void RegularCutRefinement::refine_marked(Mesh& refined_mesh, const Mesh& mesh, const std::vector<int>& refinement_markers, const IndexSet& marked_edges) { // Count the number of cells in refined mesh std::size_t num_cells = 0; // Data structure to hold a cell std::vector<std::size_t> cell_data(3); for (CellIterator cell(mesh); !cell.end(); ++cell) { const int marker = refinement_markers[cell->index()]; switch (marker) { case no_refinement: num_cells += 1; break; case regular_refinement: num_cells += 4; break; case backtrack_bisection: num_cells += 2; break; case backtrack_bisection_refine: num_cells += 3; break; default: num_cells += 2; } } // Initialize mesh editor const std::size_t num_vertices = mesh.num_vertices() + marked_edges.size(); MeshEditor editor; editor.open(refined_mesh, mesh.topology().dim(), mesh.geometry().dim()); editor.init_vertices(num_vertices); editor.init_cells(num_cells); // Set vertex coordinates std::size_t current_vertex = 0; for (VertexIterator vertex(mesh); !vertex.end(); ++vertex) { editor.add_vertex(current_vertex, vertex->point()); current_vertex++; } for (std::size_t i = 0; i < marked_edges.size(); i++) { Edge edge(mesh, marked_edges[i]); editor.add_vertex(current_vertex, edge.midpoint()); current_vertex++; } // Get bisection data for old mesh const std::size_t D = mesh.topology().dim(); const std::vector<std::size_t>* bisection_twins = NULL; if (mesh.data().exists("bisection_twins", D)) bisection_twins = &(mesh.data().array("bisection_twins", D)); // Markers for bisected cells pointing to their bisection twins in // refined mesh std::vector<std::size_t>& refined_bisection_twins = refined_mesh.data().create_array("bisection_twins", D); refined_bisection_twins.resize(num_cells); for (std::size_t i = 0; i < num_cells; i++) refined_bisection_twins[i] = i; // Mapping from old to new unrefined cells (-1 means refined or not // yet processed) std::vector<int> unrefined_cells(mesh.num_cells()); std::fill(unrefined_cells.begin(), unrefined_cells.end(), -1); // Iterate over all cells and add new cells std::size_t current_cell = 0; std::vector<std::vector<std::size_t> > cells(4, std::vector<std::size_t>(3)); for (CellIterator cell(mesh); !cell.end(); ++cell) { // Get marker const int marker = refinement_markers[cell->index()]; if (marker == no_refinement) { // No refinement: just copy cell to new mesh std::vector<std::size_t> vertices; for (VertexIterator vertex(*cell); !vertex.end(); ++vertex) vertices.push_back(vertex->index()); editor.add_cell(current_cell++, vertices); // Store mapping to new cell index unrefined_cells[cell->index()] = current_cell - 1; // Remember unrefined bisection twins if (bisection_twins) { const std::size_t bisection_twin = (*bisection_twins)[cell->index()]; const int twin_marker = refinement_markers[bisection_twin]; dolfin_assert(twin_marker == no_refinement); if (unrefined_cells[bisection_twin] >= 0) { const std::size_t i = current_cell - 1; const std::size_t j = unrefined_cells[bisection_twin]; refined_bisection_twins[i] = j; refined_bisection_twins[j] = i; } } } else if (marker == regular_refinement) { // Regular refinement: divide into subsimplicies dolfin_assert(unrefined_cells[cell->index()] == -1); // Get vertices and edges const unsigned int* v = cell->entities(0); const unsigned int* e = cell->entities(1); dolfin_assert(v); dolfin_assert(e); // Get offset for new vertex indices const std::size_t offset = mesh.num_vertices(); // Compute indices for the six new vertices const std::size_t v0 = v[0]; const std::size_t v1 = v[1]; const std::size_t v2 = v[2]; const std::size_t e0 = offset + marked_edges.find(e[0]); const std::size_t e1 = offset + marked_edges.find(e[1]); const std::size_t e2 = offset + marked_edges.find(e[2]); // Create four new cells cells[0][0] = v0; cells[0][1] = e2; cells[0][2] = e1; cells[1][0] = v1; cells[1][1] = e0; cells[1][2] = e2; cells[2][0] = v2; cells[2][1] = e1; cells[2][2] = e0; cells[3][0] = e0; cells[3][1] = e1; cells[3][2] = e2; // Add cells std::vector<std::vector<std::size_t> >::const_iterator _cell; for (_cell = cells.begin(); _cell != cells.end(); ++_cell) editor.add_cell(current_cell++, *_cell); } else if (marker == backtrack_bisection || marker == backtrack_bisection_refine) { // Special case: backtrack bisected cells dolfin_assert(unrefined_cells[cell->index()] == -1); // Get index for bisection twin dolfin_assert(bisection_twins); const std::size_t bisection_twin = (*bisection_twins)[cell->index()]; dolfin_assert(bisection_twin != cell->index()); // Let lowest number twin handle refinement if (bisection_twin < cell->index()) continue; // Get marker for twin const int twin_marker = refinement_markers[bisection_twin]; // Find common edge(s) and bisected edge(s) const std::pair<std::size_t, std::size_t> common_edges = find_common_edges(*cell, mesh, bisection_twin); const std::pair<std::size_t, std::size_t> bisection_edges = find_bisection_edges(*cell, mesh, bisection_twin); const std::pair<std::size_t, std::size_t> bisection_vertices = find_bisection_vertices(*cell, mesh, bisection_twin, bisection_edges); // Get list of vertices and edges for both cells const Cell twin(mesh, bisection_twin); const unsigned int* vertices_0 = cell->entities(0); const unsigned int* vertices_1 = twin.entities(0); const unsigned int* edges_0 = cell->entities(1); const unsigned int* edges_1 = twin.entities(1); dolfin_assert(vertices_0); dolfin_assert(vertices_1); dolfin_assert(edges_0); dolfin_assert(edges_1); // Get offset for new vertex indices const std::size_t offset = mesh.num_vertices(); // Locate vertices such that v_i is the vertex opposite to // the edge e_i on the parent triangle const std::size_t v0 = vertices_0[common_edges.first]; const std::size_t v1 = vertices_1[common_edges.second]; const std::size_t v2 = vertices_0[bisection_edges.first]; const std::size_t e0 = offset + marked_edges.find(edges_1[bisection_vertices.second]); const std::size_t e1 = offset + marked_edges.find(edges_0[bisection_vertices.first]); const std::size_t e2 = vertices_0[bisection_vertices.first]; // Locate new vertices on bisected edge (if any) std::size_t E0 = 0; std::size_t E1 = 0; if (marker == backtrack_bisection_refine) E0 = offset + marked_edges.find(edges_0[bisection_edges.first]); if (twin_marker == backtrack_bisection_refine) E1 = offset + marked_edges.find(edges_1[bisection_edges.second]); // Add middle two cells (always) dolfin_assert(cell_data.size() == 3); cell_data[0] = e0; cell_data[1] = e1; cell_data[2] = e2; editor.add_cell(current_cell++, cell_data); cell_data[0] = v2; cell_data[1] = e1; cell_data[2] = e0; editor.add_cell(current_cell++, cell_data); // Add one or two remaining cells in current cell (left) if (marker == backtrack_bisection) { cell_data[0] = v0; cell_data[1] = e2; cell_data[2] = e1; editor.add_cell(current_cell++, cell_data); } else { // Add the two cells cell_data[0] = v0; cell_data[1] = E0; cell_data[2] = e1; editor.add_cell(current_cell++, cell_data); cell_data[0] = E0; cell_data[1] = e2; cell_data[2] = e1; editor.add_cell(current_cell++, cell_data); // Set bisection twins refined_bisection_twins[current_cell - 2] = current_cell - 1; refined_bisection_twins[current_cell - 1] = current_cell - 2; } // Add one or two remaining cells in twin cell (right) if (twin_marker == backtrack_bisection) { cell_data[0] = v1; cell_data[1] = e0; cell_data[2] = e2; editor.add_cell(current_cell++, cell_data); } else { // Add the two cells cell_data[0] = v1; cell_data[1] = e0; cell_data[2] = E1; editor.add_cell(current_cell++, cell_data); cell_data[0] = e0; cell_data[1] = e2; cell_data[2] = E1; editor.add_cell(current_cell++, cell_data); // Set bisection twins refined_bisection_twins[current_cell - 2] = current_cell - 1; refined_bisection_twins[current_cell - 1] = current_cell - 2; } } else { // One edge marked for refinement: do bisection dolfin_assert(unrefined_cells[cell->index()] == -1); // Get vertices and edges const unsigned int* v = cell->entities(0); const unsigned int* e = cell->entities(1); dolfin_assert(v); dolfin_assert(e); // Get edge number (equal to marker) dolfin_assert(marker >= 0); const std::size_t local_edge_index = static_cast<std::size_t>(marker); const std::size_t global_edge_index = e[local_edge_index]; const std::size_t ee = mesh.num_vertices() + marked_edges.find(global_edge_index); // Add the two new cells if (local_edge_index == 0) { cell_data[0] = v[0]; cell_data[1] = ee; cell_data[2] = v[1]; editor.add_cell(current_cell++, cell_data); cell_data[0] = v[0]; cell_data[1] = ee; cell_data[2] = v[2]; editor.add_cell(current_cell++, cell_data); } else if (local_edge_index == 1) { cell_data[0] = v[1]; cell_data[1] = ee; cell_data[2] = v[0]; editor.add_cell(current_cell++, cell_data); cell_data[0] = v[1]; cell_data[1] = ee; cell_data[2] = v[2]; editor.add_cell(current_cell++, cell_data); } else { cell_data[0] = v[2]; cell_data[1] = ee; cell_data[2] = v[0]; editor.add_cell(current_cell++, cell_data); cell_data[0] = v[2]; cell_data[1] = ee; cell_data[2] = v[1]; editor.add_cell(current_cell++, cell_data); } // Set bisection twins refined_bisection_twins[current_cell - 2] = current_cell - 1; refined_bisection_twins[current_cell - 1] = current_cell - 2; } } // Close mesh editor dolfin_assert(num_cells == current_cell); editor.close(); }
bool keyExists(const IndexSet& data, const BSONObj& key) { IndexSet::const_iterator it = data.find(IndexKeyEntry(key, RecordId())); return it != data.end(); }
void TopologyGraph::createBoundary(unsigned graphNum, TopologyGraph::IndexVector& output) const { // nothing to do - bail if (_verts.empty() || graphNum+1 > _maxGraphID) return; // graph ID is one more than the graph number passed in: unsigned graphID = graphNum + 1u; // Find the starting point (vertex with minimum Y) for this graph ID. // By the nature of disconnected graphs, that start point is all we need // to ensure we are walking a single connected mesh. Index vstart = _verts.end(); for (VertexSet::const_iterator vert = _verts.begin(); vert != _verts.end(); ++vert) { if (vert->_graphID == graphID) { if (vstart == _verts.end() || vert->y() < vstart->y()) { vstart = vert; } } } // couldn't find a start point - bail (should never happen) if (vstart == _verts.end()) return; // starting with the minimum-Y vertex (which is guaranteed to be in the boundary) // traverse the outside of the point set. Do this by sorting all the edges by // their angle relative to the vector from the previous point. The "leftest" turn // represents the edge connecting the current point to the next boundary point. // Thusly we walk the boundary counterclockwise until we return to the start point. Index vptr = vstart; Index vptr_prev = _verts.end(); IndexSet visited; while( true ) { // store this vertex in the result set: output.push_back( vptr ); // pull up the next 2D vertex (XY plane): osg::Vec2d vert ( vptr->x(), vptr->y() ); // construct the "base" vector that points from the previous // point to the current point; or to +X in the initial case osg::Vec2d base; if ( vptr_prev == _verts.end() ) { base.set(1, 0); } else { base = vert - osg::Vec2d( vptr_prev->x(), vptr_prev->y() ); base.normalize(); } // pull up the edge set for this vertex: EdgeMap::const_iterator ei = _edgeMap.find(vptr); if (ei == _edgeMap.end()) continue; // should be impossible const IndexSet& edges = ei->second; // find the edge with the minimum delta angle to the base vector double bestScore = -DBL_MAX; Index bestEdge = _verts.end(); //OE_NOTICE << "VERTEX (" << // vptr->x() << ", " << vptr->y() << ", " // << ") has " << edges.size() << " edges..." // << std::endl; unsigned possibleEdges = 0u; for( IndexSet::iterator e = edges.begin(); e != edges.end(); ++e ) { // don't go back from whence we just came if ( *e == vptr_prev ) continue; // never return to a vert we've already visited if ( visited.find(*e) != visited.end() ) continue; ++possibleEdges; // calculate the angle between the base vector and the current edge: osg::Vec2d edgeVert( (*e)->x(), (*e)->y() ); osg::Vec2d edge = edgeVert - vert; edge.normalize(); double cross = base.x()*edge.y() - base.y()*edge.x(); double dot = base * edge; double score; if (cross <= 0.0) score = 1.0-dot; // [0..2] else score = dot-1.0; // [-2..0] //OE_NOTICE << " check: " << (*e)->x() << ", " << (*e)->y() << std::endl; //OE_NOTICE << " base = " << base.x() << ", " << base.y() << std::endl; //OE_NOTICE << " edge = " << edge.x() << ", " << edge.y() << std::endl; //OE_NOTICE << " crs = " << cross << ", dot = " << dot << ", score = " << score << std::endl; if (score > bestScore) { bestScore = score; bestEdge = *e; } } if ( bestEdge == _verts.end() ) { // this should never happen // but sometimes does anyway OE_WARN << LC << getName() << " - Illegal state - reached a dead end during boundary detection. Vertex (" << vptr->x() << ", " << vptr->y() << ") has " << possibleEdges << " possible edges.\n" << std::endl; break; } // store the previous: vptr_prev = vptr; // follow the chosen edge around the outside of the geometry: //OE_DEBUG << " BEST SCORE = " << bestScore << std::endl; vptr = bestEdge; // record this vert so we don't visit it again. visited.insert( vptr ); // once we make it all the way around, we're done: if ( vptr == vstart ) break; } }