/** * \param dim Dimension of adjacent entity being requested * \param i Parametric coordinates of cell being evaluated * \param j Parametric coordinates of cell being evaluated * \param k Parametric coordinates of cell being evaluated * \param dir Direction (0, 1, or 2), for getting adjacent edges (2d, 3d) or faces (3d) * \param ent EntityHandle of adjacent entity * \param create_if_missing If true, creates the entity if it doesn't already exist */ ErrorCode ScdBox::get_adj_edge_or_face(int dim, int i, int j, int k, int dir, EntityHandle &ent, bool create_if_missing) const { // describe connectivity of sub-element in static array // subconnect[dim-1][dir][numv][ijk] where dimensions are: // [dim-1]: dim=1 or 2, so this is 0 or 1 // [dir]: one of 0..2, for ijk directions in a hex // [numv]: number of vertices describing sub entity = 2*dim <= 4 // [ijk]: 3 values for i, j, k int subconnect[2][3][4][3] = { {{{0, 0, 0}, {1, 0, 0}, {-1, -1, -1}, {-1, -1, -1}}, // i edge {{0, 0, 0}, {0, 1, 0}, {-1, -1, -1}, {-1, -1, -1}}, // j edge {{0, 0, 0}, {0, 0, 1}, {-1, -1, -1}, {-1, -1, -1}}}, // k edge {{{0, 0, 0}, {0, 1, 0}, {0, 1, 1}, {0, 0, 1}}, // i face {{0, 0, 0}, {1, 0, 0}, {1, 0, 1}, {0, 0, 1}}, // j face {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}}}}; // k face // check proper input dimensions and lower bound if (dim < 1 || dim > 2 || i < boxDims[0] || j < boxDims[1] || k < boxDims[2]) return MB_FAILURE; // now check upper bound; parameters must be <= upper corner, since edges/faces // follow element parameterization, not vertex parameterization else if ((boxDims[3] != boxDims[0] && i > (locallyPeriodic[0] ? boxDims[3]+1 : boxDims[3])) || (boxDims[4] != boxDims[1] && j > (locallyPeriodic[1] ? boxDims[4]+1 : boxDims[4])) || (boxDims[5] != boxDims[2] && k > boxDims[5])) return MB_FAILURE; // get the vertices making up this entity EntityHandle verts[4]; for (int ind = 0; ind < 2*dim; ind++) { int i1=i+subconnect[dim-1][dir][ind][0]; int j1=j+subconnect[dim-1][dir][ind][1]; // if periodic in i and i1 is boxDims[3]+1, wrap around if (locallyPeriodic[0] && i1==boxDims[3]+1) i1=boxDims[0]; // if periodic in j and j1 is boxDims[4]+1, wrap around if (locallyPeriodic[1] && j1==boxDims[4]+1) j1=boxDims[1]; verts[ind] = get_vertex(i1, j1, k+subconnect[dim-1][dir][ind][2]); if (!verts[ind]) return MB_FAILURE; } Range ents; ErrorCode rval = scImpl->impl()->get_adjacencies(verts, 2*dim, dim, false, ents); if (MB_SUCCESS != rval) return rval; if (ents.size() > 1) return MB_FAILURE; else if (ents.size() == 1) { ent = *ents.begin(); } else if (create_if_missing) rval = scImpl->impl()->create_element((1 == dim ? MBEDGE : MBQUAD), verts, 2*dim, ent); return rval; }
void CDG::get_cd_succs(UINT id, OUT LIST<VERTEX*> & lst) { VERTEX * v = get_vertex(id); IS_TRUE0(v != NULL); EDGE_C * out = VERTEX_out_list(v); while (out != NULL) { VERTEX * succ = EDGE_to(EC_edge(out)); lst.append_tail(succ); out = EC_next(out); } }
void CDG::get_cd_preds(UINT id, OUT LIST<VERTEX*> & lst) { VERTEX * v = get_vertex(id); IS_TRUE0(v != NULL); EDGE_C * in = VERTEX_in_list(v); while (in != NULL) { VERTEX * pred = EDGE_from(EC_edge(in)); lst.append_tail(pred); in = EC_next(in); } }
void compute_normal(struct rt_bot_internal *bot, int p1, int p2, int p3, float *dest) { float v1[3]; float v2[3]; float v3[3]; float vec1[3]; float vec2[3]; float fnorm[3]; float temp[3]; float *np1, *np2, *np3; /* get face normal */ get_vertex(bot, p1, v1); if (flip_normals) { get_vertex(bot, p3, v2); get_vertex(bot, p2, v3); } else { get_vertex(bot, p2, v2); get_vertex(bot, p3, v3); } VSUB2(vec1, v1, v2); VSUB2(vec2, v1, v3); VCROSS(fnorm, vec1, vec2); VUNITIZE(fnorm); /* average existing normal with face normal per vertex */ np1 = dest + 3*p1; np2 = dest + 3*p2; np3 = dest + 3*p3; VADD2(temp, fnorm, np1); VUNITIZE(temp); VMOVE(np1, temp); VADD2(temp, fnorm, np2); VUNITIZE(temp); VMOVE(np2, temp); VADD2(temp, fnorm, np3); VUNITIZE(temp); VMOVE(np3, temp); }
MeshBuilder::MeshNode* MeshBuilder::add_vertex(const Math::Vector3<float>& pt) { MeshNode* node = get_vertex(pt); if (node == nullptr) { float q = quantize(pt); node = new MeshNode(pt); _vertex_map[q].push_back(node); } return node; }
//-------------------------------------------------------------------------------------------- int cartman_mpd_t::add_pfan(cartman_mpd_tile_t *pfan, float x, float y) { // Check the fan. if (!pfan) { log_warning("%s - tried to add null fan pointer\n", __FUNCTION__); return -1; } tile_definition_t *pdef = TILE_DICT_PTR(tile_dict, pfan->type); if (!pdef) { log_warning("%s - invalid fan type %d\n", __FUNCTION__, pfan->type); return -1; } int vert_count = pdef->numvertices; if (0 == vert_count) { log_warning("%s - undefined fan type %d\n", __FUNCTION__, pfan->type); return -1; } else if (vert_count > MAP_FAN_VERTICES_MAX) { log_warning("%s - too many vertices in fan type %d\n", __FUNCTION__, pfan->type); return -1; } // allocate the verts for this fan int start_vertex = cartman_mpd_add_fan_verts(this, pfan); if (start_vertex < 0) { log_warning("%s - could not allocate vertices for fan\n", __FUNCTION__); return -1; } // Initialize the vertices. Cartman::mpd_vertex_t *pvrt = nullptr; int cnt; Uint32 vertex; for ( cnt = 0, vertex = pfan->vrtstart; cnt < vert_count && CHAINEND != vertex; cnt++, vertex = pvrt->next ) { pvrt = get_vertex(vertex); pvrt->x = x + GRID_TO_POS( pdef->grid_ix[cnt] ); pvrt->y = y + GRID_TO_POS( pdef->grid_iy[cnt] ); pvrt->z = 0.0f; } return pfan->vrtstart; }
bool CDG::is_only_cd_self(UINT id) { VERTEX * v = get_vertex(id); IS_TRUE0(v != NULL); EDGE_C * out = VERTEX_out_list(v); while (out != NULL) { VERTEX * succ = EDGE_to(EC_edge(out)); if (succ != v) return false; out = EC_next(out); } return true; }
void DGRAPH::_remove_unreach_node(UINT id, BITSET & visited) { visited.bunion(id); VERTEX * vex = get_vertex(id); EDGE_C * el = VERTEX_out_list(vex); while (el != NULL) { UINT succ = VERTEX_id(EDGE_to(EC_edge(el))); if (!visited.is_contain(succ)) { _remove_unreach_node(succ, visited); } el = EC_next(el); } }
//Add Edge void GraphAddEdge(struct vertex** start,int from,int to,int wt){ struct vertex* head = *start; struct vertex* from_node = get_vertex(head,from); struct vertex* to_node = get_vertex(head,to); struct edge* edge_head = to_node->edges; struct edge* newEdge = malloc(sizeof(struct edge)); newEdge->wt = wt; newEdge->connect = to_node; newEdge->next = NULL; if(!edge_head){ to_node->edges = newEdge; }else{ while(edge_head->next){ edge_head = edge_head->next; } edge_head->next = newEdge; } }
VALUE rb_shape_new(struct Shape * shape) { VALUE r = rb_hash_new(); rb_hash_aset(r, ENCODED_STR_NEW2("unique_set_id", "ASCII-8BIT"), INT2NUM(shape->unique_set_id)); rb_hash_aset(r, ENCODED_STR_NEW2("version", "ASCII-8BIT"), INT2NUM(shape->version)); rb_hash_aset(r, ENCODED_STR_NEW2("gl_type", "ASCII-8BIT"), INT2NUM(shape->gl_type)); if (shape->num_attributes > 0) { VALUE attrs = rb_ary_new(); uint32_t i; for (i = 0 ; i < shape->num_attributes ; i++) { VALUE row = rb_ary_new(); rb_ary_push(row, ENCODED_STR_NEW2(shape->attributes[i].name, "ASCII-8BIT")); rb_ary_push(row, ENCODED_STR_NEW2(shape->attributes[i].value, "ASCII-8BIT")); rb_ary_push(attrs, row); } rb_hash_aset(r, ENCODED_STR_NEW2("attributes", "ASCII-8BIT"), attrs); } if (shape->num_vertexs > 0 && shape->num_vertex_arrays > 0) { VALUE arrays = rb_hash_new(); uint32_t i; for (i = 0 ; i < shape->num_vertex_arrays ; i++) { VALUE array = rb_hash_new(); VALUE vertexs = rb_ary_new(); uint32_t j; for (j = 0 ; j < shape->num_vertexs ; j++) { VALUE vertex = rb_ary_new(); float * v = get_vertex(shape, i, j); uint32_t k; for (k = 0 ; k < shape->vertex_arrays[i].num_dimensions ; k++) rb_ary_push(vertex, rb_float_new(*(v+k))); rb_ary_push(vertexs, vertex); } rb_hash_aset(array, ENCODED_STR_NEW2("vertexs", "ASCII-8BIT"), vertexs); rb_hash_aset(array, ENCODED_STR_NEW2("num_dimensions", "ASCII-8BIT"), INT2NUM(shape->vertex_arrays[i].num_dimensions)); rb_hash_aset(arrays, INT2NUM(shape->vertex_arrays[i].array_type), array); } rb_hash_aset(r, ENCODED_STR_NEW2("vertex_arrays", "ASCII-8BIT"), arrays); } return r; }
extern "C" void kdtree_insert_shape(void * v_kdtree, struct Shape * shape) { if (v_kdtree == NULL) return; duplet_tree_type * kdtree = (duplet_tree_type *)v_kdtree; int i = 0; for (i = 0 ; i < shape->num_vertexs ; i++) { float * v = get_vertex(shape, 0, i); duplet d = { {v[0], v[1]}, i, shape }; kdtree->insert(d); } kdtree_optimise(kdtree); }
rtz_vtx_t rotz_rem_vertex(rotz_t ctx, const char *v) { size_t z = strlen(v); rtz_vtx_t res; /* first check if V is really there, if not get an id and add that */ if (UNLIKELY(!(res = get_vertex(ctx, v, z)))) { ; } else if (UNLIKELY(rem_vertex(ctx, res, v, z) < 0)) { res = 0U; } return res; }
inline ErrorCode SweptElementData::get_params_connectivity(const int i, const int j, const int k, std::vector<EntityHandle>& connectivity) const { if (contains(HomCoord(i, j, k)) == false) return MB_FAILURE; connectivity.push_back(get_vertex(i, j, k)); connectivity.push_back(get_vertex(i+1, j, k)); if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 2) return MB_SUCCESS; connectivity.push_back(get_vertex(i+1, j+1, k)); connectivity.push_back(get_vertex(i, j+1, k)); if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 3) return MB_SUCCESS; connectivity.push_back(get_vertex(i, j, k+1)); connectivity.push_back(get_vertex(i+1, j, k+1)); connectivity.push_back(get_vertex(i+1, j+1, k+1)); connectivity.push_back(get_vertex(i, j+1, k+1)); return MB_SUCCESS; }
void graph_engine::activate_vertices(vertex_id_t vertices[], int num) { vertex_id_t to_add[num]; int num_to_add = 0; for (int i = 0; i < num; i++) { compute_vertex &v = get_vertex(vertices[i]); // When a vertex is added to the queue, we mark it as visited. // Therefore, a vertex can only be added to the queue once and // can only be visited once. if (v.activate_in(level.get())) to_add[num_to_add++] = vertices[i]; } activated_vertex_buf->add(to_add, num_to_add); }
safe_ptr<shader> get_image_shader(ogl_device& ogl, bool& blend_modes) { tbb::mutex::scoped_lock lock(g_shader_mutex); if(g_shader) { blend_modes = g_blend_modes; return make_safe_ptr(g_shader); } try { g_blend_modes = glTextureBarrierNV ? env::properties().get(L"configuration.blend-modes", false) : false; g_shader.reset(new shader(get_vertex(), get_fragment(g_blend_modes))); } catch(...) { CASPAR_LOG_CURRENT_EXCEPTION(); CASPAR_LOG(warning) << "Failed to compile shader. Trying to compile without blend-modes."; g_blend_modes = false; g_shader.reset(new shader(get_vertex(), get_fragment(g_blend_modes))); } ogl.enable(GL_TEXTURE_2D); if(!g_blend_modes) { ogl.enable(GL_BLEND); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); CASPAR_LOG(info) << L"[shader] Blend-modes are disabled."; } blend_modes = g_blend_modes; return make_safe_ptr(g_shader); }
rtz_vtx_t rotz_add_vertex(rotz_t ctx, const char *v) { size_t z = strlen(v); rtz_vtx_t res; /* first check if V is already there, if not get an id and add that */ if ((res = get_vertex(ctx, v, z))) { ; } else if (UNLIKELY(!(res = next_id(ctx)))) { ; } else if (UNLIKELY(add_vertex(ctx, v, z, res) < 0)) { res = 0U; } return res; }
void GL_quad::display() const { glPushMatrix(); GL_object::display(); glBegin(GL_QUADS); // vector3 normal = get_normal(); for (int i=0; i<4; i++) { vector3 vertex = get_vertex(i); vector2 tex_coord = tex_coords[i]; vector3 normal = normals[i]; glTexCoord2f(tex_coord.x, tex_coord.y); glNormal3f(normal.x, normal.y, normal.z); glVertex3f(vertex.x, vertex.y, vertex.z); } glEnd(); glPopMatrix(); }
bool DGRAPH::clone_bs(DGRAPH & src) { IS_TRUE0(m_bs_mgr != NULL); INT c; for (VERTEX * srcv = src.m_vertexs.get_first(c); srcv != NULL; srcv = src.m_vertexs.get_next(c)) { INT src_vid = VERTEX_id(srcv); VERTEX * tgtv = get_vertex(src_vid); IS_TRUE0(tgtv != NULL); get_dom_set(tgtv)->copy(*src.get_dom_set(srcv)); get_pdom_set(tgtv)->copy(*src.get_pdom_set(srcv)); } //end for each vertexs m_idom_set.copy(src.m_idom_set); m_ipdom_set.copy(src.m_ipdom_set); return true; }
inline ErrorCode ScdElementData::get_params_connectivity(const int i, const int j, const int k, std::vector<EntityHandle>& connectivity) const { if (contains(HomCoord(i, j, k)) == false) return MB_FAILURE; int ip1 = (isPeriodic[0] ? (i+1)%dIJKm1[0] : i+1), jp1 = (isPeriodic[1] ? (j+1)%dIJKm1[1] : j+1); connectivity.push_back(get_vertex(i, j, k)); connectivity.push_back(get_vertex(ip1, j, k)); if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 2) return MB_SUCCESS; connectivity.push_back(get_vertex(ip1, jp1, k)); connectivity.push_back(get_vertex(i, jp1, k)); if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 3) return MB_SUCCESS; connectivity.push_back(get_vertex(i, j, k+1)); connectivity.push_back(get_vertex(ip1, j, k+1)); connectivity.push_back(get_vertex(ip1, jp1, k+1)); connectivity.push_back(get_vertex(i, jp1, k+1)); return MB_SUCCESS; }
void get_cycle(GraphFrame *gf, int cycle_len) { int i; struct pt *v; if(cycle_len > gf->count_vertex) return; for(i = 1 ; i <= gf->count_vertex; i++) { v = get_vertex(i,gf); /*printf("first node %s \n", v->label);*/ if(!v->mark) find_cycle(gf, v, 0, cycle_len); if(!is_empty_list(gf->the_cycle)) break; } }
void reach_client::on_mouse_down(int x, int y, int button) { boost::optional<my_graph::vertex_id> hover = get_vertex(*pgraph_, coord<int>(x, y)); if (button == 0) selected_ = hover; /*if (button == 1 && hover.is_initialized()) { if (marked_.count(*hover) == 0) marked_.insert(*hover); else marked_.erase(*hover); }*/ if (button == 1 && selected_.is_initialized()&& hover.is_initialized()) { run_astar(*selected_, *hover); } base_visualizer_client::on_mouse_down(x, y, button); }
/*! Evaluates the centroid of the specified element. \param element is the element \result The centroid of the specified element. */ std::array<double, 3> Patch::eval_element_centroid(const Element &element) { const int nDimensions = 3; const long *elementConnect = element.get_connect(); const ElementInfo &elementInfo = element.get_info(); std::array<double, nDimensions> centroid = {{0., 0., 0.}}; for (int i = 0; i < elementInfo.nVertices; ++i) { Vertex &vertex = get_vertex(elementConnect[i]); const std::array<double, nDimensions> &vertexCoords = vertex.get_coords(); for (int k = 0; k < nDimensions; ++k) { centroid[k] += vertexCoords[k]; } } for (int k = 0; k < nDimensions; ++k) { centroid[k] /= elementInfo.nVertices; } return centroid; }
static float get_bounds(int i, float b[6], float x, float y, float a) { float u[8][3]; int j; int cx = (int) (x + a / 2); int cy = (int) (y + a / 2); short min = terrain[i].min[360 * cy + cx]; short max = terrain[i].max[360 * cy + cx]; get_vertex(u[0], x, y, terrain[i].o + min * terrain[i].magn); get_vertex(u[1], x + a, y, terrain[i].o + min * terrain[i].magn); get_vertex(u[2], x + a, y + a, terrain[i].o + min * terrain[i].magn); get_vertex(u[3], x, y + a, terrain[i].o + min * terrain[i].magn); get_vertex(u[4], x, y, terrain[i].o + max * terrain[i].magn); get_vertex(u[5], x + a, y, terrain[i].o + max * terrain[i].magn); get_vertex(u[6], x + a, y + a, terrain[i].o + max * terrain[i].magn); get_vertex(u[7], x, y + a, terrain[i].o + max * terrain[i].magn); b[0] = b[3] = u[0][0]; b[1] = b[4] = u[0][1]; b[2] = b[5] = u[0][2]; for (j = 1; j < 8; ++j) { b[0] = MIN(b[0], u[j][0]); b[1] = MIN(b[1], u[j][1]); b[2] = MIN(b[2], u[j][2]); b[3] = MAX(b[3], u[j][0]); b[4] = MAX(b[4], u[j][1]); b[5] = MAX(b[5], u[j][2]); } return (float) sin(RAD(cy)); }
int read_walk_distance_via_osm_to_bus_stop_from_iroquois(int argc, char ** argv, FILE * pipe_in, FILE * pipe_out, FILE * pipe_err) { //char filename[300] = ""; //int num_attributes = -1; //int c; //while ((c = getopt(argc, argv, "f:a:")) != -1) //switch (c) //{ // case 'f': // strncpy(filename, optarg, 300); // break; // case 'a': // num_attributes = atoi(optarg); // break; // default: // abort(); //} CURL *curl = NULL; CURLcode res; struct MemoryStruct chunk; char url[400]; curl = curl_easy_init(); struct Shape * shape = NULL; while ((shape = read_shape(pipe_in))) // address points { if (shape->num_vertexs > 1) { fprintf(stderr, "This is likely not the data this script was expecting. (was expecting addres points, single vertex shapes)\n"); break; } float * v = get_vertex(shape, 0, 0); chunk.memory = NULL; chunk.size = 0; sprintf(url, "http://localhost:3333/walk_distance_to_a_bus_stop?from=%f,%f", v[1], v[0]); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); res = curl_easy_perform(curl); if (chunk.size == 0) { set_attribute(shape, "route_error", "can not find a bus stop"); } else { char * walk_distance = strtok(chunk.memory, ","); char * myttc_stop_id = strtok(NULL, ","); char * myttc_stop_name = strtok(NULL, ","); if (walk_distance != NULL) set_attribute(shape, "walk_distance", walk_distance); if (myttc_stop_id != NULL) set_attribute(shape, "myttc_stop_id", myttc_stop_id); if (myttc_stop_name != NULL) set_attribute(shape, "myttc_stop_name", myttc_stop_name); } free(chunk.memory); // manipulate data here if you like write_shape(pipe_out, shape); free_shape(shape); } }
inline EntityHandle get_vertex(int i, int j, int k) const { return get_vertex(HomCoord(i,j,k)); }
/////////////////////////////////////////////////////////////////////////////// /// public _import_from_file /// Construct the graph by importing the edges from the input file. /// /// @param [in] file_name const std::string & The input graph file /// /// This function doesn't return a value /// /// @remarks The format of the file is as follows: /// 1. The first line has an integer as the number of vertices of the graph /// 2. Each line afterwards contains a directed edge in the graph: /// starting point, ending point and the weight of the edge. /// These values are separated by 'white space'. /// /// @see <TODO: insert text here> /// /// @author Yan Qi @date 5/29/2010 /////////////////////////////////////////////////////////////////////////////// void Graph::_import_from_file( const string& input_file_name ) { const char* file_name = input_file_name.c_str(); //1. Check the validity of the file ifstream ifs(file_name); if (!ifs) { cerr << "The file " << file_name << " can not be opened!" << endl; exit(1); } //2. Reset the members of the class clear(); //3. Start to read information from the input file. /// Note the format of the data in the graph file. //3.1 The first line has an integer as the number of vertices of the graph ifs >> m_nVertexNum; //3.2 In the following lines, each line contains a directed edge in the graph: /// the id of starting point, the id of ending point, the weight of the edge. /// These values are separated by 'white space'. int start_vertex, end_vertex; double edge_weight; int vertex_id = 0; while(ifs >> start_vertex) { if (start_vertex == -1) { break; } ifs >> end_vertex; ifs >> edge_weight; ///3.2.1 construct the vertices BaseVertex* start_vertex_pt = get_vertex(start_vertex); BaseVertex* end_vertex_pt = get_vertex(end_vertex); ///3.2.2 add the edge weight //// note that the duplicate edge would overwrite the one occurring before. m_mpEdgeCodeWeight[get_edge_code(start_vertex_pt, end_vertex_pt)] = edge_weight; ///3.2.3 update the fan-in or fan-out variables //// Fan-in get_vertex_set_pt(end_vertex_pt, m_mpFaninVertices)->insert(start_vertex_pt); //// Fan-out get_vertex_set_pt(start_vertex_pt, m_mpFanoutVertices)->insert(end_vertex_pt); } if(m_nVertexNum != m_vtVertices.size()) { cerr << "The number of nodes in the graph is "<< m_vtVertices.size() << " instead of " << m_nVertexNum << endl; exit(1); } m_nVertexNum = m_vtVertices.size(); m_nEdgeNum = m_mpEdgeCodeWeight.size(); ifs.close(); }
void operator()(MeshType const & input_mesh, MeshType const & output_mesh, viennagrid_plc plc_output_mesh, PointType const & N) { typedef viennagrid::result_of::const_element_range<MeshType>::type ConstElementRangeType; typedef viennagrid::result_of::iterator<ConstElementRangeType>::type ConstElementRangeIterator; viennagrid::result_of::element_copy_map<>::type copy_map(output_mesh, false); ConstElementRangeType triangles( input_mesh, 2 ); for (ConstElementRangeIterator tit = triangles.begin(); tit != triangles.end(); ++tit) { ElementType v[3]; PointType p[3]; double dp[3]; for (int pi = 0; pi != 3; ++pi) { v[pi] = viennagrid::vertices(*tit)[pi]; p[pi] = viennagrid::get_point( v[pi] ); dp[pi] = viennagrid::inner_prod( p[pi], N ); } if ( !inside(dp[0]) && !inside(dp[1]) && !inside(dp[2]) ) { // all points outside -> ignore continue; } int on_plane_count = 0; for (int pi = 0; pi != 3; ++pi) if ( on_plane(dp[pi]) ) ++on_plane_count; if (on_plane_count == 3) continue; if (on_plane_count == 2) { // std::cout << "!!!!!!!!!!!!!!!!!!!!!!!! on_plane_count = 2" << std::endl; int not_on_plane_index = !on_plane(dp[0]) ? 0 : !on_plane(dp[1]) ? 1 : 2; if ( inside(dp[not_on_plane_index]) ) { copy_map(*tit); int oi0 = (not_on_plane_index == 0) ? 1 : 0; int oi1 = (not_on_plane_index == 2) ? 1 : 2; add_line(copy_map(v[oi0]), copy_map(v[oi1])); } // else // std::cout << " outside -> skipping" << std::endl; continue; } if (on_plane_count == 1) { // std::cout << "!!!!!!!!!!!!!!!!!!!!!!!! on_plane_count = 1" << std::endl; int on_plane_index = on_plane(dp[0]) ? 0 : on_plane(dp[1]) ? 1 : 2; int oi0 = (on_plane_index == 0) ? 1 : 0; int oi1 = (on_plane_index == 2) ? 1 : 2; if ( !inside(dp[oi0]) && !inside(dp[oi1]) ) continue; if ( inside(dp[oi0]) && inside(dp[oi1]) ) { copy_map(*tit); continue; } // oi0 is inside if ( !inside(dp[oi0]) ) std::swap(oi0, oi1); ElementType v_ = get_vertex(output_mesh, N, v[oi0], v[oi1]); viennagrid::make_triangle( output_mesh, copy_map(v[on_plane_index]), copy_map(v[oi0]), v_); add_line(v_, copy_map(v[on_plane_index])); continue; } if ( inside(dp[0]) && inside(dp[1]) && inside(dp[2]) ) { // all points inside -> copy copy_map(*tit); continue; } int pos_count = 0; for (int pi = 0; pi != 3; ++pi) if ( inside(dp[pi]) ) ++pos_count; int pi = (dp[0]*dp[1] > 0) ? 2 : (dp[1]*dp[2] > 0) ? 0 : 1; int oi0 = (pi == 0) ? 1 : 0; int oi1 = (pi == 2) ? 1 : 2; ElementType v1_ = get_vertex(output_mesh, N, v[pi], v[oi0]); ElementType v2_ = get_vertex(output_mesh, N, v[pi], v[oi1]); add_line(v1_, v2_); if (pos_count == 1) { viennagrid::make_triangle( output_mesh, copy_map(v[pi]), v1_, v2_); } else { viennagrid::make_triangle( output_mesh, copy_map(v[oi0]), copy_map(v[oi1]), v1_); viennagrid::make_triangle( output_mesh, copy_map(v[oi1]), v1_, v2_); } } std::vector<viennagrid_int> line_ids; std::map<ElementType, viennagrid_int> vertices_on_hyperplane; for (LinesOnHyperplaneType::iterator it = lines_on_hyperplane.begin(); it != lines_on_hyperplane.end(); ++it) { vertices_on_hyperplane.insert( std::make_pair((*it).first, -1) ); vertices_on_hyperplane.insert( std::make_pair((*it).second, -1) ); } for (std::map<ElementType, viennagrid_int>::iterator vit = vertices_on_hyperplane.begin(); vit != vertices_on_hyperplane.end(); ++vit) { PointType p = viennagrid::get_point( (*vit).first ); viennagrid_plc_vertex_create(plc_output_mesh, &p[0], &vit->second); } for (LinesOnHyperplaneType::iterator it = lines_on_hyperplane.begin(); it != lines_on_hyperplane.end(); ++it) { viennagrid_int line_id; viennagrid_plc_line_create(plc_output_mesh, vertices_on_hyperplane[(*it).first], vertices_on_hyperplane[(*it).second], &line_id); line_ids.push_back(line_id); } viennagrid_plc_facet_create(plc_output_mesh, line_ids.size(), &line_ids[0], NULL); }
// std::sorting bool operator() (WorkSpacesGraph::vertex_t const & lhs, WorkSpacesGraph::vertex_t const & rhs) const { return get_vertex(lhs) < get_vertex(rhs); }
void Linearizer::process_quad(MeshFunction<double>** fns, int iv0, int iv1, int iv2, int iv3, int level, double* val, double* phx, double* phy, int* idx, bool curved) { double midval[3][5]; // try not to split through the vertex with the largest value int a = (verts[iv0][2] > verts[iv1][2]) ? iv0 : iv1; int b = (verts[iv2][2] > verts[iv3][2]) ? iv2 : iv3; a = (verts[a][2] > verts[b][2]) ? a : b; int flip = (a == iv1 || a == iv3) ? 1 : 0; if(level < LinearizerBase::get_max_level(fns[0]->get_active_element(), fns[0]->get_fn_order(), fns[0]->get_mesh())) { int i; if(!(level & 1)) // this is an optimization: do the following only every other time { // obtain solution values fns[0]->set_quad_order(1, item); val = fns[0]->get_values(component, value_type); if(auto_max) for (i = 0; i < lin_np_quad[1]; i++) { double v = val[i]; if(finite(v) && fabs(v) > max) #pragma omp critical(max) if(finite(v) && fabs(v) > max) max = fabs(v); } // This is just to make some sense. if(fabs(max) < Hermes::HermesSqrtEpsilon) max = Hermes::HermesSqrtEpsilon; idx = quad_indices[0]; if(curved) { RefMap* refmap = fns[0]->get_refmap(); phx = refmap->get_phys_x(1); phy = refmap->get_phys_y(1); double* dx = nullptr; double* dy = nullptr; if(this->xdisp != nullptr) fns[1]->set_quad_order(1, H2D_FN_VAL); if(this->ydisp != nullptr) fns[this->xdisp == nullptr ? 1 : 2]->set_quad_order(1, H2D_FN_VAL); if(this->xdisp != nullptr) dx = fns[1]->get_fn_values(); if(this->ydisp != nullptr) dy = fns[this->xdisp == nullptr ? 1 : 2]->get_fn_values(); for (i = 0; i < lin_np_quad[1]; i++) { if(this->xdisp != nullptr) phx[i] += dmult*dx[i]; if(this->ydisp != nullptr) phy[i] += dmult*dy[i]; } } } // obtain linearized values and coordinates at the midpoints for (i = 0; i < 3; i++) { midval[i][0] = (verts[iv0][i] + verts[iv1][i]) * 0.5; midval[i][1] = (verts[iv1][i] + verts[iv2][i]) * 0.5; midval[i][2] = (verts[iv2][i] + verts[iv3][i]) * 0.5; midval[i][3] = (verts[iv3][i] + verts[iv0][i]) * 0.5; midval[i][4] = (midval[i][0] + midval[i][2]) * 0.5; }; // the value of the middle point is not the average of the four vertex values, since quad == 2 triangles midval[2][4] = flip ? (verts[iv0][2] + verts[iv2][2]) * 0.5 : (verts[iv1][2] + verts[iv3][2]) * 0.5; // determine whether or not to split the element int split; if(eps >= 1.0) { // if eps > 1, the user wants a fixed number of refinements (no adaptivity) split = (level < eps) ? 3 : 0; } else { if(!auto_max && fabs(verts[iv0][2]) > max && fabs(verts[iv1][2]) > max && fabs(verts[iv2][2]) > max && fabs(verts[iv3][2]) > max) { // do not split if the whole quad is above the specified maximum value split = 0; } else { // calculate the approximate error of linearizing the normalized solution double herr = fabs(val[idx[1]] - midval[2][1]) + fabs(val[idx[3]] - midval[2][3]); double verr = fabs(val[idx[0]] - midval[2][0]) + fabs(val[idx[2]] - midval[2][2]); double err = fabs(val[idx[4]] - midval[2][4]) + herr + verr; split = (!finite(err) || err > max*4*eps) ? 3 : 0; // decide whether to split horizontally or vertically only if(level > 0 && split) { if(herr > 5*verr) split = 1; // h-split else if(verr > 5*herr) split = 2; // v-split } } // also decide whether to split because of the curvature if(split != 3 && curved) { double cm2 = sqr(fns[0]->get_active_element()->get_diameter()*this->get_curvature_epsilon()); if(sqr(phx[idx[1]] - midval[0][1]) + sqr(phy[idx[1]] - midval[1][1]) > cm2 || sqr(phx[idx[3]] - midval[0][3]) + sqr(phy[idx[3]] - midval[1][3]) > cm2) split |= 1; if(sqr(phx[idx[0]] - midval[0][0]) + sqr(phy[idx[0]] - midval[1][0]) > cm2 || sqr(phx[idx[2]] - midval[0][2]) + sqr(phy[idx[2]] - midval[1][2]) > cm2) split |= 2; } // do extra tests at level 0, so as not to miss some functions with zero error at edge midpoints if(level == 0 && !split) { split = ((fabs(val[13] - 0.5*(midval[2][0] + midval[2][1])) + fabs(val[17] - 0.5*(midval[2][1] + midval[2][2])) + fabs(val[20] - 0.5*(midval[2][2] + midval[2][3])) + fabs(val[9] - 0.5*(midval[2][3] + midval[2][0]))) > max*4*eps) ? 3 : 0; } } // split the quad if the error is too large, otherwise produce two linear triangles if(split) { if(curved) for (i = 0; i < 5; i++) { midval[0][i] = phx[idx[i]]; midval[1][i] = phy[idx[i]]; } // obtain mid-edge and mid-element vertices int mid0, mid1, mid2, mid3, mid4; if(split != 1) mid0 = get_vertex(iv0, iv1, midval[0][0], midval[1][0], val[idx[0]]); if(split != 2) mid1 = get_vertex(iv1, iv2, midval[0][1], midval[1][1], val[idx[1]]); if(split != 1) mid2 = get_vertex(iv2, iv3, midval[0][2], midval[1][2], val[idx[2]]); if(split != 2) mid3 = get_vertex(iv3, iv0, midval[0][3], midval[1][3], val[idx[3]]); if(split == 3) mid4 = get_vertex(mid0, mid2, midval[0][4], midval[1][4], val[idx[4]]); if(!this->exceptionMessageCaughtInParallelBlock.empty()) return; // recur to sub-elements if(split == 3) { this->push_transforms(fns, 0); process_quad(fns, iv0, mid0, mid4, mid3, level + 1, val, phx, phy, quad_indices[1], curved); this->pop_transforms(fns); this->push_transforms(fns, 1); process_quad(fns, mid0, iv1, mid1, mid4, level + 1, val, phx, phy, quad_indices[2], curved); this->pop_transforms(fns); this->push_transforms(fns, 2); process_quad(fns, mid4, mid1, iv2, mid2, level + 1, val, phx, phy, quad_indices[3], curved); this->pop_transforms(fns); this->push_transforms(fns, 3); process_quad(fns, mid3, mid4, mid2, iv3, level + 1, val, phx, phy, quad_indices[4], curved); this->pop_transforms(fns); } else if(split == 1) // h-split { this->push_transforms(fns, 4); process_quad(fns, iv0, iv1, mid1, mid3, level + 1, val, phx, phy, quad_indices[5], curved); this->pop_transforms(fns); this->push_transforms(fns, 5); process_quad(fns, mid3, mid1, iv2, iv3, level + 1, val, phx, phy, quad_indices[6], curved); this->pop_transforms(fns); } else // v-split { this->push_transforms(fns, 6); process_quad(fns, iv0, mid0, mid2, iv3, level + 1, val, phx, phy, quad_indices[7], curved); this->pop_transforms(fns); this->push_transforms(fns, 7); process_quad(fns, mid0, iv1, iv2, mid2, level + 1, val, phx, phy, quad_indices[8], curved); this->pop_transforms(fns); } return; } } // output two linear triangles, if(!flip) { add_triangle(iv3, iv0, iv1, fns[0]->get_active_element()->marker); add_triangle(iv1, iv2, iv3, fns[0]->get_active_element()->marker); } else { add_triangle(iv0, iv1, iv2, fns[0]->get_active_element()->marker); add_triangle(iv2, iv3, iv0, fns[0]->get_active_element()->marker); } }
bool operator() (WorkSpacesGraph::edge_t const & lhs, WorkSpacesGraph::edge_t const & rhs) const { csr::vertex_pair_t v0(get_vertex(std::get<0>(lhs)), get_vertex(std::get<2>(lhs))); csr::vertex_pair_t v1(get_vertex(std::get<0>(rhs)), get_vertex(std::get<2>(rhs))); return v0 < v1; }